Initial commit
[jamendo] / branches / nota-show-app / src / service_nb.c
diff --git a/branches/nota-show-app/src/service_nb.c b/branches/nota-show-app/src/service_nb.c
new file mode 100644 (file)
index 0000000..cd4c752
--- /dev/null
@@ -0,0 +1,176 @@
+/***************************************************************************
+ *            service_nb.c
+ *
+ *  Thu Nov 19 14:23:57 2009
+ *  Copyright  2009  Marcin Miklas
+ *  <marcin.miklas@teleca.com>
+ ****************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <netinet/in.h> 
+
+#include "service.h"
+
+static void shut_down(void);
+static int disconnect(int socket, ServiceCallbacks* cb);
+
+#ifdef SERVICE_MAIN
+
+unsigned char* last_image=NULL;
+int last_image_size = 0;
+
+void put_image(unsigned char* img_buf, int img_size) {
+       printf("Image received: size = %d\n",img_size);
+       if(last_image) {
+               free(last_image);
+               last_image = NULL;
+               last_image_size = 0;
+       }
+       last_image = malloc(img_size);
+       memcpy(last_image,img_buf,img_size);
+       last_image_size = img_size;     
+}
+
+unsigned char* get_image(int* size) {
+       if(size)
+               *size = last_image_size;
+
+       unsigned char* img = malloc(last_image_size);
+       memcpy(img,last_image,last_image_size);
+       return img;
+}              
+
+void face_found() {
+       printf("face found!\n");
+}
+
+int main(int args, char** argv)
+{
+       ServiceCallbacks cb = {0};
+       cb.log = (void (*)(const char*)) &puts;
+       cb.put_image = &put_image;
+       cb.get_image = &get_image;
+       cb.face_found = &face_found;
+       service(&cb);
+       return 0;
+}
+#endif
+
+static int listener = 0;
+int fdmax = 0;
+fd_set all;            // all active sockets
+
+void* service(ServiceCallbacks* cb)
+{
+       LOG1("Activating service with SID '%d'\n", DEFAULT_SID);
+       
+       /* Activating a service means registering it with the Resource Manager,
+        * so that it is visible to applications. The return value is the initial
+        * listener socket (h_in3).
+        */
+       listener = n_activate(DEFAULT_SID, NULL, NULL);
+       if (listener < 0) {
+               return NULL;
+       }
+       else
+               LOG("\tdone.\n");
+       atexit(shut_down);
+       
+       fd_set read;    // sockets ready for reading
+       fd_set errors;  
+       FD_ZERO(&all);
+       FD_SET(listener, &all);
+       FD_ZERO(&read);
+       fdmax = listener;       //biggest socket number (right now,
+                                               //'listener' is the only open socket)
+       int quit = 0;
+       while (!quit && (!cb->run_check || *(cb->run_check)))
+       {
+               read = all;             //make a copy of the master set
+               errors = all;   //will contain sockets with error conditions set
+               if (Hselect(Hgetinstance(), fdmax+1, &read, NULL, &errors, NULL) == -1) 
+               {
+                       LOG("Error on select\n");
+               }
+               /* Select modifies read so that it includes the sockets
+                * that are ready for reading. Let's check which ones they were:
+                */
+               int i;
+               for (i = 0; i <= fdmax; i++)
+               {
+                       if (FD_ISSET(i, &read)) {       // found a socket ready to be read
+                               if (i == listener)      //service socket
+                               {
+                                       LOG("Accepting new connection.\n");
+                                       int socket = n_accept(i, NULL, 0);
+                                       if (socket < 0) {
+                                               LOG1("\terror: %d\n", socket);
+                                               continue;
+                                       }
+                                       LOG1("\tdone - socket %d connected.\n", socket);
+                                       FD_SET(socket, &all);   //add to master set
+                                       if (socket > fdmax) 
+                                               fdmax = socket;
+                               }       //service socket handler
+                               else    //data on an existing socket
+                               {
+                                       int err = read_smsg(&i, HSReceiveBlocking, cb); 
+                                       if (err < 0)    //error reading service message
+                                       {
+                                               n_disconnect(i);
+                                               FD_CLR(i, &all);
+                                       }
+                                       else {
+                                               switch(err) {
+                                                       case DISCONNECT:
+                                                               disconnect(i,cb);
+                                                               break;
+                                                       case QUIT:
+                                                               disconnect(i,cb);
+                                                               quit = 1;
+                                                               break;
+                                               }
+                                       }
+                               }       //incoming data handler
+                       }       // Handle sockets in the read set
+                       // check for errors:
+                       if (FD_ISSET(i, &errors)) {
+                               if (i == listener)      //error on service socket
+                               {
+                                       LOG("Error in service socket; quitting.\n");
+                                       exit(-1);
+                               }
+                               FD_CLR(i, &all);
+                               n_disconnect(i);
+                               continue;
+                       }
+               }       // Read socket loop
+       }       // Main loop
+
+       exit(0);
+}
+
+static int disconnect(int socket, ServiceCallbacks* cb)
+{
+       FD_CLR(socket, &all);
+       return n_disconnect(socket);
+}
+
+static void shut_down()
+{
+       printf("Shutting down...\n");
+       printf("Deactivating service...\n");
+       HErrorCode err = n_deactivate(listener, NULL);
+       if(err >= 0) {
+               printf("Deactivated.\n");
+               FD_CLR(listener, &all);
+       }
+       int i;
+       // Close all open sockets:
+       for (i = 0; i <= fdmax; i++)
+               if (FD_ISSET(i, &all))
+                       n_disconnect(i);
+}
+