Initial commit
[jamendo] / branches / nota-show-app / src / service_nb.c
1 /***************************************************************************
2  *            service_nb.c
3  *
4  *  Thu Nov 19 14:23:57 2009
5  *  Copyright  2009  Marcin Miklas
6  *  <marcin.miklas@teleca.com>
7  ****************************************************************************/
8
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <netinet/in.h> 
13
14 #include "service.h"
15
16 static void shut_down(void);
17 static int disconnect(int socket, ServiceCallbacks* cb);
18
19 #ifdef SERVICE_MAIN
20
21 unsigned char* last_image=NULL;
22 int last_image_size = 0;
23
24 void put_image(unsigned char* img_buf, int img_size) {
25         printf("Image received: size = %d\n",img_size);
26         if(last_image) {
27                 free(last_image);
28                 last_image = NULL;
29                 last_image_size = 0;
30         }
31         last_image = malloc(img_size);
32         memcpy(last_image,img_buf,img_size);
33         last_image_size = img_size;     
34 }
35
36 unsigned char* get_image(int* size) {
37         if(size)
38                 *size = last_image_size;
39
40         unsigned char* img = malloc(last_image_size);
41         memcpy(img,last_image,last_image_size);
42         return img;
43 }               
44
45 void face_found() {
46         printf("face found!\n");
47 }
48
49 int main(int args, char** argv)
50 {
51         ServiceCallbacks cb = {0};
52         cb.log = (void (*)(const char*)) &puts;
53         cb.put_image = &put_image;
54         cb.get_image = &get_image;
55         cb.face_found = &face_found;
56         service(&cb);
57         return 0;
58 }
59 #endif
60
61 static int listener = 0;
62 int fdmax = 0;
63 fd_set all;             // all active sockets
64
65 void* service(ServiceCallbacks* cb)
66 {
67         LOG1("Activating service with SID '%d'\n", DEFAULT_SID);
68         
69         /* Activating a service means registering it with the Resource Manager,
70          * so that it is visible to applications. The return value is the initial
71          * listener socket (h_in3).
72          */
73         listener = n_activate(DEFAULT_SID, NULL, NULL);
74         if (listener < 0) {
75                 return NULL;
76         }
77         else
78                 LOG("\tdone.\n");
79         atexit(shut_down);
80         
81         fd_set read;    // sockets ready for reading
82         fd_set errors;  
83         FD_ZERO(&all);
84         FD_SET(listener, &all);
85         FD_ZERO(&read);
86         fdmax = listener;       //biggest socket number (right now,
87                                                 //'listener' is the only open socket)
88         int quit = 0;
89         while (!quit && (!cb->run_check || *(cb->run_check)))
90         {
91                 read = all;             //make a copy of the master set
92                 errors = all;   //will contain sockets with error conditions set
93                 if (Hselect(Hgetinstance(), fdmax+1, &read, NULL, &errors, NULL) == -1) 
94                 {
95                         LOG("Error on select\n");
96                 }
97                 /* Select modifies read so that it includes the sockets
98                  * that are ready for reading. Let's check which ones they were:
99                  */
100                 int i;
101                 for (i = 0; i <= fdmax; i++)
102                 {
103                         if (FD_ISSET(i, &read)) {       // found a socket ready to be read
104                                 if (i == listener)      //service socket
105                                 {
106                                         LOG("Accepting new connection.\n");
107                                         int socket = n_accept(i, NULL, 0);
108                                         if (socket < 0) {
109                                                 LOG1("\terror: %d\n", socket);
110                                                 continue;
111                                         }
112                                         LOG1("\tdone - socket %d connected.\n", socket);
113                                         FD_SET(socket, &all);   //add to master set
114                                         if (socket > fdmax) 
115                                                 fdmax = socket;
116                                 }       //service socket handler
117                                 else    //data on an existing socket
118                                 {
119                                         int err = read_smsg(&i, HSReceiveBlocking, cb); 
120                                         if (err < 0)    //error reading service message
121                                         {
122                                                 n_disconnect(i);
123                                                 FD_CLR(i, &all);
124                                         }
125                                         else {
126                                                 switch(err) {
127                                                         case DISCONNECT:
128                                                                 disconnect(i,cb);
129                                                                 break;
130                                                         case QUIT:
131                                                                 disconnect(i,cb);
132                                                                 quit = 1;
133                                                                 break;
134                                                 }
135                                         }
136                                 }       //incoming data handler
137                         }       // Handle sockets in the read set
138                         // check for errors:
139                         if (FD_ISSET(i, &errors)) {
140                                 if (i == listener)      //error on service socket
141                                 {
142                                         LOG("Error in service socket; quitting.\n");
143                                         exit(-1);
144                                 }
145                                 FD_CLR(i, &all);
146                                 n_disconnect(i);
147                                 continue;
148                         }
149                 }       // Read socket loop
150         }       // Main loop
151
152         exit(0);
153 }
154
155 static int disconnect(int socket, ServiceCallbacks* cb)
156 {
157         FD_CLR(socket, &all);
158         return n_disconnect(socket);
159 }
160
161 static void shut_down()
162 {
163         printf("Shutting down...\n");
164         printf("Deactivating service...\n");
165         HErrorCode err = n_deactivate(listener, NULL);
166         if(err >= 0) {
167                 printf("Deactivated.\n");
168                 FD_CLR(listener, &all);
169         }
170         int i;
171         // Close all open sockets:
172         for (i = 0; i <= fdmax; i++)
173                 if (FD_ISSET(i, &all))
174                         n_disconnect(i);
175 }
176