efl debug - clean up debugd and debug cli tool code proto handling
authorCarsten Haitzler (Rasterman) <raster@rasterman.com>
Fri, 8 May 2015 10:48:26 +0000 (19:48 +0900)
committerCarsten Haitzler (Rasterman) <raster@rasterman.com>
Fri, 8 May 2015 10:48:26 +0000 (19:48 +0900)
this clenas up protocol handling to share common code and have more
compact and easier to maintain code on both sides here.

src/bin/efl/efl_debug.c
src/bin/efl/efl_debug_common.c
src/bin/efl/efl_debug_common.h
src/bin/efl/efl_debugd.c

index b9800988cec8b25b2a5655e60ea6cc926025792e..c8df269bf96c730813fc5dee771bf52d18fa94f4 100644 (file)
@@ -10,21 +10,19 @@ static const char *expect = NULL;
 static Ecore_Con_Server *svr;
 
 static void
-_proto(unsigned char *d, unsigned int size)
+_do(char *op, unsigned char *d, int size)
 {
-   if (size >= 4)
+   if (!strcmp(op, "CLST"))
      {
-        char *cmd = (char *)d;
+        int i, n;
 
-        if (!strncmp(cmd, "CLST", 4))
+        n = (size) / sizeof(int);
+        if (n < 10000)
           {
-             int i, n;
-
-             n = (size - 4) / sizeof(int);
-             if (n < 10000)
+             int *pids = malloc(n * sizeof(int));
+             if (pids)
                {
-                  int *pids = malloc(n * sizeof(int));
-                  memcpy(pids, d + 4, n * sizeof(int));
+                  memcpy(pids, d, n * sizeof(int));
                   for (i = 0; i < n; i++)
                     {
                        if (pids[i] > 0) printf("%i\n", pids[i]);
@@ -32,78 +30,42 @@ _proto(unsigned char *d, unsigned int size)
                   free(pids);
                }
           }
-        if ((expect) && (!strncmp(cmd, expect, 4)))
-          ecore_main_loop_quit();
-     }
-}
-
-
-static Eina_Bool
-_server_proto(void)
-{
-   unsigned int size, newsize;
-   unsigned char *b;
-   if (!buf) return EINA_FALSE;
-   if (buf_size < 4) return EINA_FALSE;
-   memcpy(&size, buf, 4);
-   if (buf_size < (size + 4)) return EINA_FALSE;
-   _proto(buf + 4, size);
-   newsize = buf_size - (size + 4);
-   if (buf_size == newsize)
-     {
-        free(buf);
-        buf = NULL;
-        buf_size = 0;
-     }
-   else
-     {
-        b = malloc(newsize);
-        memcpy(b, buf + size + 4, newsize);
-        free(buf);
-        buf = b;
-        buf_size = newsize;
      }
-   return EINA_TRUE;
+   if ((expect) && (!strcmp(op, expect))) ecore_main_loop_quit();
 }
 
 Eina_Bool
-_server_add(void *data EINA_UNUSED, int type EINA_UNUSED, Ecore_Con_Event_Server_Add *ev)
+_server_add(void *data EINA_UNUSED, int type EINA_UNUSED, Ecore_Con_Event_Server_Add *ev EINA_UNUSED)
 {
    int i;
    for (i = 1; i < my_argc; i++)
      {
         if (!strcmp(my_argv[i], "list"))
           {
-             unsigned int size = 4;
-             char *head = "LIST";
+             send_svr(svr, "LIST", NULL, 0);
              expect = "CLST";
-             ecore_con_server_send(svr, &size, 4);
-             ecore_con_server_send(svr, head, 4);
+             printf("send... expect %s\n", expect);
           }
         else if ((!strcmp(my_argv[i], "pon")) &&
                  (i < (my_argc - 2)))
           {
-             unsigned int size = 12;
-             char *head = "PLON";
+             unsigned char buf[8];
              int pid = atoi(my_argv[i + 1]);
              unsigned int freq = atoi(my_argv[i + 2]);
-             i++;
-             ecore_con_server_send(svr, &size, 4);
-             ecore_con_server_send(svr, head, 4);
-             ecore_con_server_send(svr, &pid, 4);
-             ecore_con_server_send(svr, &freq, 4);
+             i += 2;
+             store_val(buf, 0, pid);
+             store_val(buf, 4, freq);
+             send_svr(svr, "PLON", buf, sizeof(buf));
              ecore_main_loop_quit();
           }
         else if ((!strcmp(my_argv[i], "poff")) &&
                  (i < (my_argc - 1)))
           {
-             unsigned int size = 8;
-             char *head = "PLOFF";
+             unsigned char buf[4];
              int pid = atoi(my_argv[i + 1]);
              i++;
-             ecore_con_server_send(svr, &size, 4);
-             ecore_con_server_send(svr, head, 4);
-             ecore_con_server_send(svr, &pid, 4);
+             store_val(buf, 0, pid);
+             send_svr(svr, "PLOF", buf, sizeof(buf));
              ecore_main_loop_quit();
           }
      }
@@ -111,7 +73,7 @@ _server_add(void *data EINA_UNUSED, int type EINA_UNUSED, Ecore_Con_Event_Server
 }
 
 Eina_Bool
-_server_del(void *data EINA_UNUSED, int type EINA_UNUSED, Ecore_Con_Event_Server_Del *ev)
+_server_del(void *data EINA_UNUSED, int type EINA_UNUSED, Ecore_Con_Event_Server_Del *ev EINA_UNUSED)
 {
    ecore_main_loop_quit();
    return ECORE_CALLBACK_RENEW;
@@ -120,26 +82,17 @@ _server_del(void *data EINA_UNUSED, int type EINA_UNUSED, Ecore_Con_Event_Server
 static Eina_Bool
 _server_data(void *data EINA_UNUSED, int type EINA_UNUSED, Ecore_Con_Event_Server_Data *ev)
 {
-   if (!buf)
-     {
-        buf = malloc(ev->size);
-        if (buf)
-          {
-             buf_size = ev->size;
-             memcpy(buf, ev->data, ev->size);
-          }
-     }
-   else
+   char op[5];
+   unsigned char *d = NULL;
+   int size;
+
+   _protocol_collect(&(buf), &(buf_size), ev->data, ev->size);
+   while ((size = _proto_read(&(buf), &(buf_size), op, &d)) >= 0)
      {
-        unsigned char *b = realloc(buf, buf_size + ev->size);
-        if (b)
-          {
-             buf = b;
-             memcpy(buf + buf_size, ev->data, ev->size);
-             buf_size += ev->size;
-          }
+        _do(op, d, size);
+        free(d);
+        d = NULL;
      }
-   while (_server_proto());
    return ECORE_CALLBACK_RENEW;
 }
 
@@ -156,7 +109,7 @@ main(int argc, char **argv)
    svr = ecore_con_server_connect(ECORE_CON_LOCAL_USER, "efl_debug", 0, NULL);
    if (!svr)
      {
-        fprintf(stderr, "ERROR: Cannot connetc to debug daemon.\n");
+        fprintf(stderr, "ERROR: Cannot connect to debug daemon.\n");
         return -1;
      }
 
index 5b8c6f8f50076c46c5884bf7b308ac4dd8332afb..82587d2a5503ce2473e841f29f3af8f30e39cc79 100644 (file)
@@ -1 +1,95 @@
 #include "efl_debug_common.h"
+
+void
+_protocol_collect(unsigned char **buf, unsigned int *buf_size,
+                  void *data, int size)
+{
+   // no buffer yet - duplicate it as out only data
+   if (!*buf)
+     {
+        *buf = malloc(size);
+        if (*buf)
+          {
+             *buf_size = size;
+             memcpy(*buf, data, size);
+          }
+     }
+   // we have data - append to the buffer and reallocate it as needed
+   else
+     {
+        unsigned char *b = realloc(*buf, *buf_size + size);
+        if (b)
+          {
+             *buf = b;
+             memcpy(*buf + *buf_size, data, size);
+             *buf_size += size;
+          }
+     }
+}
+
+int
+_proto_read(unsigned char **buf, unsigned int *buf_size,
+            char *op, unsigned char **data)
+{
+   unsigned int size, new_buf_size;
+   unsigned char *b;
+
+   // we have no data yet, or not enough - minimum 8 bytes
+   if (!*buf) return -1;
+   if (*buf_size < 8) return -1;
+   // get size of total message
+   memcpy(&size, *buf, 4);
+   // if size is invalid < 4 bytes - no message there
+   if (size < 4) return -1;
+   // if our total message buffer size is not big enough yet - no message
+   if (*buf_size < (size + 4)) return -1;
+
+   // copy out 4 byte opcode and nul byet terminate it
+   memcpy(op, *buf + 4, 4);
+   op[4] = 0;
+
+   // take off opcode header of 4 bytes
+   size -= 4;
+   // the new buffer size once we remove header+payload is...
+   new_buf_size = *buf_size - (size + 8);
+   if (size == 0)
+     {
+        *data = NULL;
+        size = 0;
+     }
+   else
+     {
+        // allocate new space for payload
+        *data = malloc(size);
+        if (!*data)
+          {
+             // allocation faild - no message
+             return -1;
+          }
+        memcpy(*data, *buf + 8, size);
+     }
+   // if new shrunk buffer size is empty -= just simply free buffer
+   if (new_buf_size == 0)
+     {
+        free(*buf);
+        *buf = NULL;
+     }
+   else
+     {
+        // allocate newly shrunk buffer
+        b = malloc(new_buf_size);
+        if (!b)
+          {
+             // alloc failure - bad. fail proto read then
+             free(*data);
+             return -1;
+          }
+        // copy data to new smaller buffer and free old, storing new buffer
+        memcpy(b, *buf + size + 8, new_buf_size);
+        free(*buf);
+        *buf = b;
+     }
+   // store new buffer size
+   *buf_size = new_buf_size;
+   return (int)size;
+}
index 435ddc092330b954fdd1ae824a432e17735e2982..46f859c6516e6956e7b16047061968bbb413c169 100644 (file)
@@ -9,4 +9,34 @@
 #include <unistd.h>
 #include <string.h>
 
+void _protocol_collect(unsigned char **buf, unsigned int *buf_size,
+                       void *data, int size);
+int _proto_read(unsigned char **buf, unsigned int *buf_size,
+                char *op, unsigned char **data);
+
+#define fetch_val(dst, buf, off) \
+   memcpy(&dst, ((unsigned char *)buf) + off, sizeof(dst))
+#define store_val(buf, off, src) \
+   memcpy(buf + off, &src, sizeof(src))
+#define send_svr(svr, op, data, size) \
+   do { \
+      unsigned char head[8]; \
+      char *op2 = op; \
+      int size2 = size + 4; \
+      memcpy(head + 0, &size2, 4); \
+      memcpy(head + 4, op2, 4); \
+      ecore_con_server_send(svr, head, 8); \
+      if (size > 0) ecore_con_server_send(svr, data, size); \
+   } while (0)
+#define send_cli(cli, op, data, size) \
+   do { \
+      unsigned char head[8]; \
+      char *op2 = op; \
+      int size2 = size + 4; \
+      memcpy(head + 0, &size2, 4); \
+      memcpy(head + 4, op2, 4); \
+      ecore_con_client_send(cli, head, 8); \
+      if (size > 0) ecore_con_client_send(cli, data, size); \
+   } while (0)
+
 #endif
index c102ed4a9bf2c2827be3f4865d9fd4821e91dfc7..b64747f63d3eb98aafb649726bc60ff490b7a62e 100644 (file)
@@ -5,129 +5,85 @@ typedef struct _Client Client;
 struct _Client
 {
    Ecore_Con_Client *client;
-   int version;
-   pid_t pid;
-   unsigned char *buf;
-   unsigned int   buf_size;
+   unsigned char    *buf;
+   unsigned int      buf_size;
+
+   int               version;
+   pid_t             pid;
 };
 
 static Ecore_Con_Server *svr = NULL;
 static Eina_List *clients = NULL;
 
+static Client *
+_client_pid_find(int pid)
+{
+   Client *c;
+   Eina_List *l;
+
+   if (pid <= 0) return NULL;
+   EINA_LIST_FOREACH(clients, l, c)
+     {
+        if (c->pid == pid) return c;
+     }
+   return NULL;
+}
+
 static void
-_proto(Client *c, unsigned char *d, unsigned int size)
+_do(Client *c, char *op, unsigned char *d, int size)
 {
-   if (size >= 4)
+   Client *c2;
+   Eina_List *l;
+
+   if ((!strcmp(op, "HELO")) && (size >= 8))
      {
-        char *cmd = (char *)d;
+        int version;
+        int pid;
 
-        if (!strncmp(cmd, "HELO", 4))
+        fetch_val(version, d, 0);
+        fetch_val(pid, d, 4);
+        c->version = version;
+        c->pid = pid;
+     }
+   else if (!strcmp(op, "LIST"))
+     {
+        int n = eina_list_count(clients);
+        unsigned int *pids = malloc(n * sizeof(int));
+        if (pids)
           {
-             int version;
-             int pid;
+             int i = 0;
 
-             memcpy(&version, d + 4, 4);
-             memcpy(&pid, d + 8, 4);
-             c->version = version;
-             c->pid = pid;
-          }
-        else if (!strncmp(cmd, "LIST", 4))
-          {
-             int n = eina_list_count(clients), i;
-             unsigned int *pids, size2;
-             Client *c2;
-             Eina_List *l;
-             char *head = "CLST";
-
-             pids = malloc(n * sizeof(int));
-             i = 0;
-             size2 = 4 + (n * sizeof(int));
              EINA_LIST_FOREACH(clients, l, c2)
                {
                   pids[i] = c2->pid;
                   i++;
                }
-             ecore_con_client_send(c->client, &size2, 4);
-             ecore_con_client_send(c->client, head, 4);
-             ecore_con_client_send(c->client, pids, n * sizeof(int));
+             send_cli(c->client, "CLST", pids, n * sizeof(int));
              free(pids);
           }
-        else if (!strncmp(cmd, "PLON", 4))
-          {
-             int pid;
-             unsigned int freq = 1000;
-             Client *c2;
-             Eina_List *l;
-
-             memcpy(&pid, d + 4, 4);
-             memcpy(&freq, d + 8, 4);
-             if (pid > 0)
-               {
-                  EINA_LIST_FOREACH(clients, l, c2)
-                    {
-                       if (c2->pid == pid)
-                         {
-                            unsigned int size2 = 8;
-
-                            ecore_con_client_send(c2->client, &size2, 4);
-                            ecore_con_client_send(c2->client, d, 4);
-                            ecore_con_client_send(c2->client, &freq, 4);
-                            break;
-                         }
-                    }
-               }
-          }
-        else if (!strncmp(cmd, "PLOF", 4))
-          {
-             int pid;
-             Client *c2;
-             Eina_List *l;
-
-             memcpy(&pid, d + 4, 4);
-             if (pid > 0)
-               {
-                  EINA_LIST_FOREACH(clients, l, c2)
-                    {
-                       if (c2->pid == pid)
-                         {
-                            unsigned int size2 = 4;
-
-                            ecore_con_client_send(c2->client, &size2, 4);
-                            ecore_con_client_send(c2->client, d, 4);
-                            break;
-                         }
-                    }
-               }
-          }
      }
-}
-
-static Eina_Bool
-_client_proto(Client *c)
-{
-   unsigned int size, newsize;
-   unsigned char *b;
-   if (!c->buf) return EINA_FALSE;
-   if (c->buf_size < 4) return EINA_FALSE;
-   memcpy(&size, c->buf, 4);
-   if (c->buf_size < (size + 4)) return EINA_FALSE;
-   _proto(c, c->buf + 4, size);
-   newsize = c->buf_size - (size + 4);
-   if (c->buf_size == newsize)
+   else if ((!strcmp(op, "PLON")) && (size >= 8))
      {
-        free(c->buf);
-        c->buf = NULL;
-        c->buf_size = 0;
+        int pid;
+        unsigned int freq = 1000;
+        fetch_val(pid, d, 0);
+        fetch_val(freq, d, 4);
+        if ((c2 = _client_pid_find(pid)))
+          {
+             unsigned char buf[4];
+             store_val(buf, 0, freq);
+             send_cli(c2->client, "PLON", buf, sizeof(buf));
+          }
      }
-   else
+   else if (!strcmp(op, "PLOF"))
      {
-        b = malloc(newsize);
-        memcpy(b, c->buf + size + 4, newsize);
-        free(c->buf);
-        c->buf = b;
-        c->buf_size = newsize;
+        int pid;
+        fetch_val(pid, d, 0);
+        if ((c2 = _client_pid_find(pid)))
+          {
+             send_cli(c2->client, "PLOF", NULL, 0);
+          }
      }
-   return EINA_TRUE;
 }
 
 static Eina_Bool
@@ -161,26 +117,17 @@ _client_data(void *data EINA_UNUSED, int type EINA_UNUSED, Ecore_Con_Event_Clien
    Client *c = ecore_con_client_data_get(ev->client);
    if (c)
      {
-        if (!c->buf)
-          {
-             c->buf = malloc(ev->size);
-             if (c->buf)
-               {
-                  c->buf_size = ev->size;
-                  memcpy(c->buf, ev->data, ev->size);
-               }
-          }
-        else
+        char op[5];
+        unsigned char *d = NULL;
+        int size;
+
+        _protocol_collect(&(c->buf), &(c->buf_size), ev->data, ev->size);
+        while ((size = _proto_read(&(c->buf), &(c->buf_size), op, &d)) >= 0)
           {
-             unsigned char *b = realloc(c->buf, c->buf_size + ev->size);
-             if (b)
-               {
-                  c->buf = b;
-                  memcpy(c->buf + c->buf_size, ev->data, ev->size);
-                  c->buf_size += ev->size;
-               }
+             _do(c, op, d, size);
+             free(d);
+             d = NULL;
           }
-        while (_client_proto(c));
      }
    return ECORE_CALLBACK_RENEW;
 }