summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Hirt <daniel.hirt@samsung.com>2015-09-10 17:17:19 +0300
committerDaniel Hirt <daniel.hirt@samsung.com>2015-09-10 17:17:19 +0300
commit1f188e95cc12e7ef33d34a7baac82a9c540aae67 (patch)
tree98c10c900a5ebda8160e4826efe72e728560392f
Add initial commit
-rw-r--r--README0
-rw-r--r--src/Makefile14
-rw-r--r--src/client.c167
-rw-r--r--src/debugd.c388
4 files changed, 569 insertions, 0 deletions
diff --git a/README b/README
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/README
diff --git a/src/Makefile b/src/Makefile
new file mode 100644
index 0000000..94a83f4
--- /dev/null
+++ b/src/Makefile
@@ -0,0 +1,14 @@
1CC = gcc -ggdb3 -O0
2
3targets = client debugd
4
5all: $(targets)
6
7client: client.c
8 $(CC) -o client client.c `pkg-config --cflags --libs efl ecore ecore-ipc`
9
10debugd: debugd.c
11 $(CC) -o debugd debugd.c `pkg-config --cflags --libs efl ecore ecore-file ecore-ipc`
12
13clean:
14 rm client debugd
diff --git a/src/client.c b/src/client.c
new file mode 100644
index 0000000..510c982
--- /dev/null
+++ b/src/client.c
@@ -0,0 +1,167 @@
1#include <stdio.h>
2#include <stdlib.h>
3#include <unistd.h>
4#include <string.h>
5
6#include <sys/socket.h>
7#include <Ecore.h>
8/* We will create a socket in a specific port defined by TCP_SERVER_PORT */
9
10#define BUFFER_SIZE 1024
11
12Ecore_Exe *g_child = NULL;
13char *g_bridge_file = NULL;
14Eina_Bool test_mode = EINA_FALSE;
15
16static Eina_Bool
17_send_message_test(char *msg)
18{
19 if (!ecore_exe_send(g_child, msg, strlen(msg)))
20 {
21 fprintf(stderr, "Could not send message to child\n");
22 return EINA_FALSE;
23 }
24 else
25 {
26 fprintf(stderr, "Father: I've sent this message: %s\n", msg);
27 return EINA_TRUE;
28 }
29}
30
31static Eina_Bool
32_send_message(char *msg)
33{
34 char tmp[1024];
35 char msg2[1024];
36 static char seq = 1;
37
38 if (!g_bridge_file) return EINA_FALSE;
39
40 sprintf(tmp, "sdb push msg %s &> /dev/null", g_bridge_file);
41
42 msg2[0] = seq++;
43
44 strcpy(msg2 + 1, msg);
45
46 FILE *f = fopen("msg", "w+");
47 fprintf(f, "%s\n", msg2);
48 fclose(f);
49
50 ecore_exe_run(tmp, NULL);
51
52 return EINA_TRUE;
53}
54
55static Eina_Bool
56_fd_handler_cb(void *data, Ecore_Fd_Handler *fd_handler EINA_UNUSED)
57{
58 char msg[BUFFER_SIZE];
59
60 if (!fgets(msg, BUFFER_SIZE, stdin))
61 {
62 fprintf(stderr, "nothing\n");
63 return ECORE_CALLBACK_RENEW;
64 }
65
66 fprintf(stdout, "Father: User entered: %s\n", msg);
67 if (test_mode)
68 {
69 _send_message_test(msg);
70 }
71 else
72 {
73 _send_message(msg);
74 }
75 return ECORE_CALLBACK_RENEW;
76}
77
78static Eina_Bool
79_msg_from_child_handler(void *data EINA_UNUSED, int type EINA_UNUSED,
80 void *event)
81{
82 Ecore_Exe_Event_Data *cdata = event;
83 char msg[BUFFER_SIZE];
84 strncpy(msg, cdata->data, cdata->size);
85 msg[cdata->size] = 0;
86 fprintf(stdout, "Father: my child sent me: %s\n", msg);
87
88 /* First message initializes the file path to push */
89 if (!g_bridge_file)
90 {
91 int len = strlen(msg);
92 msg[len - 1] = 0; /* removing the newline */
93 g_bridge_file = strdup(msg);
94 fprintf(stdout, "Dest file set to %s\n", g_bridge_file);
95 }
96
97 return ECORE_CALLBACK_DONE;
98}
99
100static int count = 0;
101
102static Ecore_Exe *
103_init_bridge(void)
104{
105 /* Listen to port and after connect start receiving.
106 * Recieved messages should contain ASCII text. Send back UPPERCASE
107 * conversion of these messages */
108
109 const char *cmd_bridge = "sdb shell /home/developer/bridge";
110 const char *cmd_test = "./debugd bridge test";
111
112 const char *cmd;
113 const char *profile = getenv("DBG_PROFILE");
114
115 if (profile && !strcmp(profile, "test"))
116 {
117 printf ("Starting test profile\n");
118 cmd = cmd_test;
119 test_mode = EINA_TRUE;
120 }
121 else
122 {
123 cmd = cmd_bridge;
124 }
125
126 printf ("Starting bridge with command: %s\n", cmd);
127
128 return ecore_exe_pipe_run(cmd,
129 ECORE_EXE_PIPE_WRITE |
130 ECORE_EXE_PIPE_READ_LINE_BUFFERED |
131 ECORE_EXE_PIPE_READ,
132 NULL);
133}
134
135int main (int argc, char **argv)
136{
137 if (!ecore_init())
138 goto exit;
139
140 Ecore_Exe *bridge = _init_bridge();
141
142 if (!bridge)
143 {
144 fprintf(stderr, "Could not initialize bridge\n");
145 goto error;
146 }
147
148 g_child = bridge;
149
150 ecore_main_fd_handler_add(STDIN_FILENO,
151 ECORE_FD_READ,
152 _fd_handler_cb,
153 NULL, NULL, NULL);
154 ecore_event_handler_add(ECORE_EXE_EVENT_DATA, _msg_from_child_handler, NULL);
155
156 ecore_main_loop_begin();
157
158 ecore_exe_free(bridge); /* Does not affect the child process */
159 ecore_shutdown();
160
161 return EXIT_SUCCESS;
162
163error:
164 ecore_shutdown();
165exit:
166 return EXIT_FAILURE;
167}
diff --git a/src/debugd.c b/src/debugd.c
new file mode 100644
index 0000000..1a535f2
--- /dev/null
+++ b/src/debugd.c
@@ -0,0 +1,388 @@
1#include <stdio.h>
2#include <stdlib.h>
3#include <unistd.h>
4#include <Ecore.h>
5#include <Ecore_Ipc.h>
6#include <ctype.h>
7
8#define BUFFER_SIZE 1024
9//////////////////////////////////////////////////////////////////////////
10/////////////////// Daemon (Server) //////////////////////////////////////
11/////////////////////////////////////////////////////////////////////////
12
13static Ecore_Ipc_Server *ipc = NULL;
14/* Client-to-server cb's */
15static Ecore_Event_Handler *hnd_add = NULL;
16static Ecore_Event_Handler *hnd_del = NULL;
17static Ecore_Event_Handler *hnd_data = NULL;
18
19static Eina_Bool
20_cb_client_add(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
21{
22 return ECORE_CALLBACK_DONE;
23}
24
25static Eina_Bool
26_cb_client_del(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
27{
28 return ECORE_CALLBACK_DONE;
29}
30
31#define IPC_HEAD(_type) \
32 Ecore_Ipc_Event_Client_##_type *e = event; \
33 if (ecore_ipc_client_server_get(e->client) != ipc) \
34 return ECORE_CALLBACK_PASS_ON
35
36static Eina_Bool
37_cb_client_data(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
38{
39 IPC_HEAD(Data);
40 if (e->major == 1)
41 {
42 ecore_ipc_client_send(e->client, 1, 0, 0, 0, 0, NULL, 0);
43 }
44 return ECORE_CALLBACK_DONE;
45}
46
47////// Server ////////////////////
48static void
49_broadcast(Ecore_Ipc_Server *svr, int major, int minor, void *data, int size)
50{
51 Eina_List *ipc_clients = ecore_ipc_server_clients_get(svr);
52 Eina_List *l;
53 Ecore_Ipc_Client *cl;
54
55 EINA_LIST_FOREACH(ipc_clients, l, cl)
56 {
57 ecore_ipc_client_send(cl, major, minor, 0, 0, 0, data, size);
58 }
59}
60
61static Eina_Bool
62_server_shutdown(void)
63{
64 if (!ipc) return EINA_TRUE;
65
66 ecore_ipc_server_del(ipc);
67 ecore_event_handler_del(hnd_add);
68 ecore_event_handler_del(hnd_del);
69 ecore_event_handler_del(hnd_data);
70 ipc = NULL;
71 hnd_add = NULL;
72 hnd_del = NULL;
73 hnd_data = NULL;
74 ecore_ipc_shutdown();
75 return EINA_TRUE;
76}
77
78static Eina_Bool
79_server_init(void)
80{
81 fprintf(stdout, "Initializing server\n");
82 if (ipc) return EINA_TRUE;
83
84 ipc = ecore_ipc_server_add(ECORE_IPC_LOCAL_USER, "debugd", 0, NULL);
85 if (!ipc)
86 {
87 fprintf(stdout, "Failed raising server");
88 _server_shutdown();
89 return EINA_FALSE;
90 }
91 fprintf(stdout, "Server initialized successfully on 0 port\n");
92
93 hnd_add = ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_ADD,
94 _cb_client_add, NULL);
95 hnd_del = ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_DEL,
96 _cb_client_del, NULL);
97 hnd_data = ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_DATA,
98 _cb_client_data, NULL);
99 return EINA_TRUE;
100}
101
102typedef enum
103{
104 DAEMON_MODE_NORMAL,
105 DAEMON_MODE_TEST,
106 DAEMON_MODE_BRIDGE_NORMAL,
107 DAEMON_MODE_BRIDGE_TEST
108} Daemon_Mode;
109
110Eina_Bool
111_daemon(Daemon_Mode mode)
112{
113 fprintf(stdout, "Daemon Mode!!!\n");
114#if 1
115 if (!_server_init())
116 {
117 return EINA_FALSE;
118 }
119#endif
120 ecore_main_loop_begin();
121#if 1
122 _server_shutdown();
123#endif
124
125 return EINA_TRUE;
126}
127
128//////////////////////////////////////////////////////////////////////////
129/////////////////// Bridge (Client) //////////////////////////////////////
130/////////////////////////////////////////////////////////////////////////
131
132/////// Bridge-Daemon Comm. /////////
133#include <Ecore_File.h>
134static Ecore_Ipc_Server *srv_ipc = NULL;
135/* Server-to-client cb's */
136static Ecore_Event_Handler *svr_hnd_add = NULL;
137static Ecore_Event_Handler *svr_hnd_del = NULL;
138static Ecore_Event_Handler *svr_hnd_data = NULL;
139
140const char *debug_prefix = ".";
141
142/* Send a message from bridge to daemon */
143static void
144_bridge_send(char *msg, int size)
145{
146 ecore_ipc_server_send(srv_ipc, 1, 0, 0, 0, 0, msg, size);
147}
148
149static Eina_Bool
150_cb_server_add(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
151{
152 return ECORE_CALLBACK_DONE;
153}
154
155static Eina_Bool
156_cb_server_del(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
157{
158 return ECORE_CALLBACK_DONE;
159}
160
161#define SVR_IPC_HEAD(_type) \
162 Ecore_Ipc_Event_Server_##_type *e = event; \
163 if (e->server != srv_ipc) \
164 return ECORE_CALLBACK_PASS_ON
165
166static Eina_Bool
167_cb_server_data(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
168{
169 SVR_IPC_HEAD(Data);
170 if (e->major == 1) // registration
171 {
172 fprintf(stdout, "Server responded!\n");
173 }
174 return ECORE_CALLBACK_DONE;
175}
176
177static void
178_ipc_launch(void)
179{
180 char buf[PATH_MAX];
181 int num = 0; /* retries counter */
182
183 snprintf(buf, sizeof(buf), "%s/debugd", debug_prefix);
184 ecore_exe_run(buf, NULL);
185 while ((!srv_ipc) && (num < 500))
186 {
187 num++;
188 usleep(1000);
189 srv_ipc = ecore_ipc_server_connect(ECORE_IPC_LOCAL_USER, "debugd", 0, NULL);
190 }
191
192 if (!srv_ipc)
193 {
194 perror("Launched server but could not connect after 500 tries\n");
195 }
196}
197
198static Eina_Bool
199debug_daemon_init(void)
200{
201 srv_ipc = ecore_ipc_server_connect(ECORE_IPC_LOCAL_USER, "debugd", 0, NULL);
202 if (!srv_ipc) _ipc_launch();
203
204 if (!srv_ipc)
205 {
206 perror ("Could not connect to ipc server");
207 ecore_ipc_shutdown();
208 return EINA_FALSE;
209 }
210 svr_hnd_add = ecore_event_handler_add(ECORE_IPC_EVENT_SERVER_ADD,
211 _cb_server_add, NULL);
212 svr_hnd_del = ecore_event_handler_add(ECORE_IPC_EVENT_SERVER_DEL,
213 _cb_server_del, NULL);
214 svr_hnd_data = ecore_event_handler_add(ECORE_IPC_EVENT_SERVER_DATA,
215 _cb_server_data, NULL);
216
217 return EINA_TRUE;;
218}
219
220/////// Bridge-CLI Comm /////////
221
222///////// ADB MODE /////////////
223const char *tmp_dir = "/home/developer/tmp";
224int tmpcount = 0;
225
226static char *
227_check_strip_cmd(char* cmd)
228{
229 static char seq = 1;
230 char tmp = *cmd;
231
232 if (tmp != seq)
233 {
234 return NULL;
235 }
236
237 seq++; /* all ok. increment seq */
238 return cmd + 1;
239}
240
241static void
242_tmp_file_monitor_cb(void *data, Ecore_File_Monitor *em,
243 Ecore_File_Event event, const char *path)
244{
245 if (event == ECORE_FILE_EVENT_MODIFIED)
246 {
247 char line[BUFFER_SIZE];
248 char arg1[256], arg2[256];
249 char *cmd;
250 FILE *f = fopen(path, "r");
251
252 fgets(line, BUFFER_SIZE, f);
253 fclose(f);
254 cmd = _check_strip_cmd(line);
255
256 if (cmd)
257 {
258 fputs(cmd, stdout);
259 fflush(stdout);
260 }
261 }
262}
263
264static Eina_Bool
265_bridge_sdb(void)
266{
267 char tmp[1024];
268 FILE *f;
269 Ecore_File_Monitor *fm;
270
271 /* We use files here. Yeah... */
272 if (!ecore_file_init())
273 {
274 return EINA_FALSE;
275 }
276
277 /* Send first message to client with the required cmd file path to push */
278 sprintf(tmp, "%s/bridge-%d", tmp_dir, getpid());
279
280 f = fopen(tmp, "w+");
281 fprintf(stdout, "%s\n", tmp);
282 fclose(f);
283
284 fm = ecore_file_monitor_add(tmp, _tmp_file_monitor_cb, NULL);
285
286 ecore_main_loop_begin();
287 ecore_file_shutdown();
288
289 return EINA_TRUE;
290}
291
292////////// TEST MODE /////////////////
293static Eina_Bool
294_fd_handler_cb(void *data, Ecore_Fd_Handler *fd_handler EINA_UNUSED)
295{
296 char msg[BUFFER_SIZE];
297 char *c;
298
299 if (!fgets(msg, BUFFER_SIZE, stdin))
300 {
301 fprintf(stderr, "nothing\n");
302 return ECORE_CALLBACK_RENEW;
303 }
304#if 0
305 for (c = msg; *c != 0; c++)
306 *c = toupper(toupper(*c));
307
308 fprintf(stdout, "%s\n", msg);
309#endif
310 _bridge_send(msg, strlen(msg));
311 return ECORE_CALLBACK_RENEW;
312}
313
314static Eina_Bool
315_bridge_test(void)
316{
317 fprintf(stdout, "BRIDGE TEST MODE\n");
318 ecore_main_fd_handler_add(STDIN_FILENO,
319 ECORE_FD_READ,
320 _fd_handler_cb,
321 NULL, NULL, NULL);
322 ecore_main_loop_begin();
323 return EINA_TRUE;
324}
325
326static int
327_bridge(Daemon_Mode mode)
328{
329
330 /* Initialize debug daemon */
331 if (!debug_daemon_init())
332 {
333 perror("Exiting...\n");
334 return EINA_FALSE;
335 }
336
337 if (mode == DAEMON_MODE_BRIDGE_TEST)
338 return _bridge_test();
339 else //BRIDGE_NORMAL
340 return _bridge_sdb();
341}
342
343////////////////////////////////////////////////////////////
344///////////////// Main /////////////////////////////////////
345////////////////////////////////////////////////////////////
346
347/* All modes require ipc comm. */
348int main (int argc, char **argv)
349{
350 Daemon_Mode mode;
351 Eina_Bool ret;
352 Eina_Bool test = EINA_FALSE;
353 if (!ecore_init()) goto exit;
354 if (!ecore_ipc_init())
355 {
356 ecore_shutdown();
357 goto exit;
358 }
359
360 mode = DAEMON_MODE_NORMAL;
361 if (argc == 2)
362 {
363 if (!strcmp(argv[1], "test"))
364 {
365 mode = DAEMON_MODE_TEST;
366 }
367 }
368 else if ((argc == 3) && !strcmp(argv[1], "bridge"))
369 {
370 if (!strcmp(argv[2], "test"))
371 {
372 mode = DAEMON_MODE_BRIDGE_TEST;
373 }
374 else
375 {
376 mode = DAEMON_MODE_BRIDGE_NORMAL;
377 }
378 }
379
380 if (mode > DAEMON_MODE_TEST)
381 _bridge(mode);
382 else _daemon(mode);
383
384 ecore_shutdown();
385
386exit:
387 return EXIT_SUCCESS;
388}