--- /dev/null
+/***************************************************************************
+ * 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);
+}
+