1 #ifdef HAVE_CONFIG_H
2 # include <config.h>
3 #endif
4
5 #ifdef STDC_HEADERS
6 # include <stdlib.h>
7 # include <stddef.h>
8 #else
9 # ifdef HAVE_STDLIB_H
10 # include <stdlib.h>
11 # endif
12 #endif
13
14 #include <Eina.h>
15
16 #include "Ecore.h"
17 #include "Ecore_Con.h"
18 #include "ecore_con_private.h"
19 #include "Ecore_Con_Eet.h"
20
21 #define ECORE_CON_EET_RAW_MAGIC 0xDEAD007
22 #define ECORE_CON_EET_DATA_KEY "ecore_con_eet_data_key"
23
24 typedef struct _Ecore_Con_Eet_Base_Data Ecore_Con_Eet_Base_Data;
25 typedef struct _Ecore_Con_Eet_Server_Obj_Data Ecore_Con_Eet_Server_Obj_Data;
26 typedef struct _Ecore_Con_Eet_Client_Obj_Data Ecore_Con_Eet_Client_Obj_Data;
27 typedef struct _Ecore_Con_Eet_Data Ecore_Con_Eet_Data;
28 typedef struct _Ecore_Con_Eet_Raw_Data Ecore_Con_Eet_Raw_Data;
29 typedef struct _Ecore_Con_Eet_Client Ecore_Con_Eet_Client;
30 typedef struct _Ecore_Con_Eet_Server Ecore_Con_Eet_Server;
31
32 struct _Ecore_Con_Eet_Server_Obj_Data
33 {
34 Eina_List *connections;
35 Eina_List *client_connect_callbacks;
36 Eina_List *client_disconnect_callbacks;
37
38 Ecore_Event_Handler *handler_add;
39 Ecore_Event_Handler *handler_del;
40 Ecore_Event_Handler *handler_data;
41 };
42
43 struct _Ecore_Con_Eet_Client_Obj_Data
44 {
45 Ecore_Con_Reply *r;
46 Eina_List *server_connect_callbacks;
47 Eina_List *server_disconnect_callbacks;
48
49 Ecore_Event_Handler *handler_add;
50 Ecore_Event_Handler *handler_del;
51 Ecore_Event_Handler *handler_data;
52 };
53
54 struct _Ecore_Con_Reply
55 {
56 Ecore_Con_Eet *ece;
57 Ecore_Con_Client *client;
58
59 Eet_Connection *econn;
60
61 char *buffer_section;
62 unsigned char *buffer;
63 unsigned int buffer_length;
64 unsigned int buffer_current;
65 Ecore_Con_Eet_Raw_Data *buffer_handler;
66 };
67
68 struct _Ecore_Con_Eet_Data
69 {
70 Ecore_Con_Eet_Data_Cb func;
71 const char *name;
72 const void *data;
73 };
74
75 struct _Ecore_Con_Eet_Raw_Data
76 {
77 Ecore_Con_Eet_Raw_Data_Cb func;
78 const char *name;
79 const void *data;
80 };
81
82 struct _Ecore_Con_Eet_Client
83 {
84 Ecore_Con_Eet_Client_Cb func;
85 const void *data;
86 };
87
88 struct _Ecore_Con_Eet_Server
89 {
90 Ecore_Con_Eet_Server_Cb func;
91 const void *data;
92 };
93
94 struct _Ecore_Con_Eet_Base_Data
95 {
96 Ecore_Con_Server *server;
97
98 Eet_Data_Descriptor *edd;
99 Eet_Data_Descriptor *matching;
100
101 Eina_Hash *data_callbacks;
102 Eina_Hash *raw_data_callbacks;
103 };
104
105 static void
_ecore_con_eet_data_free(void * data)106 _ecore_con_eet_data_free(void *data)
107 {
108 Ecore_Con_Eet_Data *eced = data;
109
110 eina_stringshare_del(eced->name);
111 free(eced);
112 }
113
114 static void
_ecore_con_eet_raw_data_free(void * data)115 _ecore_con_eet_raw_data_free(void *data)
116 {
117 Ecore_Con_Eet_Raw_Data *eced = data;
118
119 eina_stringshare_del(eced->name);
120 free(eced);
121 }
122
123 static void
_ecore_con_eet_reply_cleanup(Ecore_Con_Reply * n)124 _ecore_con_eet_reply_cleanup(Ecore_Con_Reply *n)
125 {
126 if (n->buffer_handler) free(n->buffer);
127 n->buffer = NULL;
128 n->buffer_handler = NULL;
129 free(n->buffer_section);
130 n->buffer_section = NULL;
131 }
132
133 typedef struct _Ecore_Con_Eet_Protocol Ecore_Con_Eet_Protocol;
134 struct _Ecore_Con_Eet_Protocol
135 {
136 const char *type;
137 void *data;
138 };
139
140 static const char *
_ecore_con_eet_data_type_get(const void * data,Eina_Bool * unknow EINA_UNUSED)141 _ecore_con_eet_data_type_get(const void *data, Eina_Bool *unknow EINA_UNUSED)
142 {
143 const Ecore_Con_Eet_Protocol *p = data;
144
145 return p->type;
146 }
147
148 static Eina_Bool
_ecore_con_eet_data_type_set(const char * type,void * data,Eina_Bool unknow EINA_UNUSED)149 _ecore_con_eet_data_type_set(const char *type, void *data, Eina_Bool unknow EINA_UNUSED)
150 {
151 Ecore_Con_Eet_Protocol *p = data;
152
153 p->type = type;
154 return EINA_TRUE;
155 }
156
157 static void
_ecore_con_eet_data_descriptor_setup(Ecore_Con_Eet_Base_Data * ece)158 _ecore_con_eet_data_descriptor_setup(Ecore_Con_Eet_Base_Data *ece)
159 {
160 Eet_Data_Descriptor_Class eddc;
161
162 EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, Ecore_Con_Eet_Protocol);
163 ece->edd = eet_data_descriptor_stream_new(&eddc);
164
165 eddc.version = EET_DATA_DESCRIPTOR_CLASS_VERSION;
166 eddc.func.type_get = _ecore_con_eet_data_type_get;
167 eddc.func.type_set = _ecore_con_eet_data_type_set;
168 ece->matching = eet_data_descriptor_stream_new(&eddc);
169
170 EET_DATA_DESCRIPTOR_ADD_VARIANT(ece->edd, Ecore_Con_Eet_Protocol, "data", data, type, ece->matching);
171 }
172
173 /* Dealing with a server listening to connection */
174 static Eina_Bool
_ecore_con_eet_read_cb(const void * eet_data,size_t size,void * user_data)175 _ecore_con_eet_read_cb(const void *eet_data, size_t size, void *user_data)
176 {
177 Ecore_Con_Reply *n = user_data;
178 Ecore_Con_Eet_Protocol *protocol;
179 Ecore_Con_Eet_Data *cb;
180 Ecore_Con_Eet_Base_Data *ece_data = efl_data_scope_get(n->ece, ECORE_CON_EET_BASE_CLASS);
181
182 protocol = eet_data_descriptor_decode(ece_data->edd, eet_data, size);
183 if (!protocol) return EINA_TRUE;
184
185 cb = eina_hash_find(ece_data->data_callbacks, protocol->type);
186 if (!cb) return EINA_TRUE; /* Should I report unknow protocol communication ? */
187
188 cb->func((void *)cb->data, n, cb->name, protocol->data);
189
190 eina_stringshare_del(protocol->type);
191 free(protocol);
192
193 return EINA_TRUE;
194 }
195
196 static Eina_Bool
_ecore_con_eet_server_write_cb(const void * data,size_t size,void * user_data)197 _ecore_con_eet_server_write_cb(const void *data, size_t size, void *user_data)
198 {
199 Ecore_Con_Reply *n = user_data;
200
201 if (ecore_con_client_send(n->client, data, size) != (int)size)
202 return EINA_FALSE;
203 return EINA_TRUE;
204 }
205
206 static Eina_Bool
_ecore_con_eet_client_write_cb(const void * data,size_t size,void * user_data)207 _ecore_con_eet_client_write_cb(const void *data, size_t size, void *user_data)
208 {
209 Ecore_Con_Reply *n = user_data;
210 Ecore_Con_Eet_Base_Data *ece_data = efl_data_scope_get(n->ece, ECORE_CON_EET_BASE_CLASS);
211
212 if (ecore_con_server_send(ece_data->server, data, size) != (int)size)
213 return EINA_FALSE;
214
215 return EINA_TRUE;
216 }
217
218 static Eina_Bool
_ecore_con_eet_server_connected(void * data,int type EINA_UNUSED,Ecore_Con_Event_Client_Add * ev)219 _ecore_con_eet_server_connected(void *data, int type EINA_UNUSED, Ecore_Con_Event_Client_Add *ev)
220 {
221 Ecore_Con_Eet_Client *ecec;
222 Eina_List *ll;
223 Ecore_Con_Reply *n;
224 Ecore_Con_Eet *ece_obj = data;
225 Ecore_Con_Eet_Base_Data *base_data = efl_data_scope_get(ece_obj, ECORE_CON_EET_BASE_CLASS);
226 Ecore_Con_Eet_Server_Obj_Data *r = efl_data_scope_get(ece_obj, ECORE_CON_EET_SERVER_OBJ_CLASS);
227
228 if (ecore_con_client_server_get(ev->client) != base_data->server)
229 return EINA_TRUE;
230
231 n = calloc(1, sizeof (Ecore_Con_Reply));
232 if (!n) return EINA_TRUE;
233
234 n->client = ev->client;
235 n->ece = ece_obj;
236 n->econn = eet_connection_new(_ecore_con_eet_read_cb, _ecore_con_eet_server_write_cb, n);
237 ecore_con_client_data_set(n->client, n);
238
239 EINA_LIST_FOREACH(r->client_connect_callbacks, ll, ecec)
240 if (!ecec->func((void *)ecec->data, n, n->client))
241 {
242 eet_connection_close(n->econn, NULL);
243 free(n);
244 return EINA_TRUE;
245 }
246
247 r->connections = eina_list_append(r->connections, n);
248
249 return EINA_TRUE;
250 }
251
252 static Eina_Bool
_ecore_con_eet_server_disconnected(void * data,int type EINA_UNUSED,Ecore_Con_Event_Client_Del * ev)253 _ecore_con_eet_server_disconnected(void *data, int type EINA_UNUSED, Ecore_Con_Event_Client_Del *ev)
254 {
255 Ecore_Con_Eet *ece_obj = data;
256 Ecore_Con_Eet_Base_Data *base_data = efl_data_scope_get(ece_obj, ECORE_CON_EET_BASE_CLASS);
257 Ecore_Con_Eet_Server_Obj_Data *r = efl_data_scope_get(ece_obj, ECORE_CON_EET_SERVER_OBJ_CLASS);
258 Ecore_Con_Reply *n;
259 Eina_List *l;
260
261 if (ecore_con_client_server_get(ev->client) != base_data->server)
262 return EINA_TRUE;
263
264 EINA_LIST_FOREACH(r->connections, l, n)
265 if (n->client == ev->client)
266 {
267 Ecore_Con_Eet_Client *ecec;
268 Eina_List *ll;
269
270 EINA_LIST_FOREACH(r->client_disconnect_callbacks, ll, ecec)
271 ecec->func((void *)ecec->data, n, n->client);
272
273 eet_connection_close(n->econn, NULL);
274 free(n);
275 r->connections = eina_list_remove_list(r->connections, l);
276 return EINA_TRUE;
277 }
278
279 return EINA_TRUE;
280 }
281
282 static void
_ecore_con_eet_raw_data_push(Ecore_Con_Reply * n,void * data,int size)283 _ecore_con_eet_raw_data_push(Ecore_Con_Reply *n, void *data, int size)
284 {
285 if (n->buffer_handler)
286 memcpy(n->buffer + n->buffer_current, data, size);
287 n->buffer_current += size;
288
289 if (n->buffer_current == n->buffer_length)
290 {
291 if (n->buffer_handler)
292 n->buffer_handler->func((void *)n->buffer_handler->data, n, n->buffer_handler->name, n->buffer_section, n->buffer, n->buffer_length);
293 _ecore_con_eet_reply_cleanup(n);
294 }
295 }
296
297 static void
_ecore_con_eet_data(Ecore_Con_Reply * n,void * data,unsigned int size)298 _ecore_con_eet_data(Ecore_Con_Reply *n, void *data, unsigned int size)
299 {
300 /* FIXME: Enforce detection of attack and kill connection on that case */
301 if (n->buffer)
302 {
303 if (n->buffer_current + size > n->buffer_length)
304 {
305 _ecore_con_eet_reply_cleanup(n);
306 return;
307 }
308
309 _ecore_con_eet_raw_data_push(n, data, size);
310 return;
311 }
312 else if (eet_connection_empty(n->econn) && size > (int)(4 * sizeof (unsigned int) + 2))
313 {
314 unsigned int *tmp = data;
315 size -= 4 * sizeof (unsigned int);
316
317 if (eina_ntohl(tmp[0]) == ECORE_CON_EET_RAW_MAGIC)
318 {
319 unsigned int protocol_length = eina_ntohl(tmp[1]);
320 unsigned int section_length = eina_ntohl(tmp[2]);
321 unsigned int data_length = eina_ntohl(tmp[3]);
322
323 if (protocol_length > 1 && section_length > 1 && protocol_length + section_length <= size && data_length < 10 * 1024 * 1024)
324 {
325 char *buffer = (char *)&tmp[4];
326 char *protocol;
327 char *section;
328 Ecore_Con_Eet_Base_Data *eceb_data = efl_data_scope_get(n->ece,ECORE_CON_EET_BASE_CLASS);
329
330 protocol = buffer;
331 section = buffer + protocol_length;
332
333 if (protocol[protocol_length - 1] == '\0' &&
334 section[section_length - 1] == '\0')
335 {
336 size -= protocol_length + section_length;
337 buffer = section + section_length;
338
339 n->buffer_handler = eina_hash_find(eceb_data->raw_data_callbacks, protocol);
340 n->buffer_section = strdup(section);
341 n->buffer_length = data_length;
342 n->buffer_current = 0;
343 if (n->buffer_handler)
344 n->buffer = malloc(sizeof (unsigned char) * data_length);
345 else
346 n->buffer = (void *)1;
347 if (n->buffer)
348 {
349 _ecore_con_eet_raw_data_push(n, buffer, size);
350 return;
351 }
352 _ecore_con_eet_reply_cleanup(n);
353
354 size += protocol_length + section_length;
355 }
356 }
357 }
358
359 size += 4 * sizeof (unsigned int);
360 }
361
362 eet_connection_received(n->econn, data, size);
363 }
364
365 static Eina_Bool
_ecore_con_eet_server_data(void * data,int type EINA_UNUSED,Ecore_Con_Event_Client_Data * ev)366 _ecore_con_eet_server_data(void *data, int type EINA_UNUSED, Ecore_Con_Event_Client_Data *ev)
367 {
368 Ecore_Con_Eet *ece_obj = data;
369 Ecore_Con_Eet_Base_Data *r = efl_data_scope_get(ece_obj, ECORE_CON_EET_BASE_CLASS);
370 Ecore_Con_Reply *n;
371
372 if (ecore_con_client_server_get(ev->client) != r->server)
373 return EINA_TRUE;
374
375 n = ecore_con_client_data_get(ev->client);
376
377 efl_ref(ece_obj);
378 _ecore_con_eet_data(n, ev->data, ev->size);
379 efl_unref(ece_obj);
380
381 return EINA_TRUE;
382 }
383
384 /* Dealing connection to a server */
385
386 static Eina_Bool
_ecore_con_eet_client_connected(void * data,int type EINA_UNUSED,Ecore_Con_Event_Server_Add * ev)387 _ecore_con_eet_client_connected(void *data, int type EINA_UNUSED, Ecore_Con_Event_Server_Add *ev)
388 {
389 Ecore_Con_Eet_Server *eces;
390 Ecore_Con_Eet *ece_obj = data;
391 Ecore_Con_Eet_Base_Data *base_data = efl_data_scope_get(ece_obj, ECORE_CON_EET_BASE_CLASS);
392 Ecore_Con_Eet_Client_Obj_Data *r = efl_data_scope_get(ece_obj, ECORE_CON_EET_CLIENT_OBJ_CLASS);
393 Ecore_Con_Reply *n;
394 Eina_List *ll;
395
396 /* Client did connect */
397 if (base_data->server != ev->server) return EINA_TRUE;
398 if (r->r) return EINA_TRUE;
399
400 n = calloc(1, sizeof (Ecore_Con_Reply));
401 if (!n) return EINA_TRUE;
402
403 n->client = NULL;
404 n->ece = ece_obj;
405 n->econn = eet_connection_new(_ecore_con_eet_read_cb, _ecore_con_eet_client_write_cb, n);
406
407 EINA_LIST_FOREACH(r->server_connect_callbacks, ll, eces)
408 {
409 Ecore_Con_Eet_Base_Data *temp = efl_data_scope_get(n->ece, ECORE_CON_EET_BASE_CLASS);
410 if (!eces->func((void *)eces->data, n, temp->server))
411 {
412 eet_connection_close(n->econn, NULL);
413 free(n);
414 return EINA_TRUE;
415 }
416 }
417
418 r->r = n;
419
420 return EINA_TRUE;
421 }
422
423 static Eina_Bool
_ecore_con_eet_client_disconnected(void * data,int type EINA_UNUSED,Ecore_Con_Event_Server_Del * ev)424 _ecore_con_eet_client_disconnected(void *data, int type EINA_UNUSED, Ecore_Con_Event_Server_Del *ev)
425 {
426 Ecore_Con_Eet *ece_obj = data;
427 Ecore_Con_Eet_Base_Data *base_data = efl_data_scope_get(ece_obj, ECORE_CON_EET_BASE_CLASS);
428 Ecore_Con_Eet_Client_Obj_Data *r = efl_data_scope_get(ece_obj, ECORE_CON_EET_CLIENT_OBJ_CLASS);
429 Ecore_Con_Eet_Server *eces;
430 Eina_List *ll;
431
432 if (base_data->server != ev->server) return EINA_TRUE;
433 if (!r->r) return EINA_TRUE;
434
435 /* Client disconnected */
436 EINA_LIST_FOREACH(r->server_disconnect_callbacks, ll, eces)
437 eces->func((void *)eces->data, r->r, base_data->server);
438
439 eet_connection_close(r->r->econn, NULL);
440 free(r->r);
441 r->r = NULL;
442
443 return EINA_TRUE;
444 }
445
446 static Eina_Bool
_ecore_con_eet_client_data(void * data,int type EINA_UNUSED,Ecore_Con_Event_Server_Data * ev)447 _ecore_con_eet_client_data(void *data, int type EINA_UNUSED, Ecore_Con_Event_Server_Data *ev)
448 {
449 Ecore_Con_Eet *ece_obj = data;
450 Ecore_Con_Eet_Base_Data *base_data = efl_data_scope_get(ece_obj, ECORE_CON_EET_BASE_CLASS);
451 Ecore_Con_Eet_Client_Obj_Data *r = efl_data_scope_get(ece_obj, ECORE_CON_EET_CLIENT_OBJ_CLASS);
452
453 if (base_data->server != ev->server) return EINA_TRUE;
454 if (!r->r) return EINA_TRUE;
455
456 /* Got some data */
457 efl_ref(ece_obj);
458 _ecore_con_eet_data(r->r, ev->data, ev->size);
459 efl_unref(ece_obj);
460
461 return EINA_TRUE;
462 }
463
464 /*************
465 * Generated API
466 */
467
468 EOLIAN static void
_ecore_con_eet_base_data_callback_set(Eo * obj EINA_UNUSED,Ecore_Con_Eet_Base_Data * pd,const char * name,Ecore_Con_Eet_Data_Cb func,const void * data)469 _ecore_con_eet_base_data_callback_set(Eo *obj EINA_UNUSED, Ecore_Con_Eet_Base_Data *pd, const char *name, Ecore_Con_Eet_Data_Cb func, const void *data)
470 {
471 Ecore_Con_Eet_Data *eced;
472
473 eced = calloc(1, sizeof (Ecore_Con_Eet_Data));
474 if (!eced) return;
475
476 eced->func = func;
477 eced->data = data;
478 eced->name = eina_stringshare_add(name);
479
480 eina_hash_direct_add(pd->data_callbacks, eced->name, eced);
481 }
482
483 EOLIAN static void
_ecore_con_eet_base_raw_data_callback_set(Eo * obj EINA_UNUSED,Ecore_Con_Eet_Base_Data * pd,const char * name,Ecore_Con_Eet_Raw_Data_Cb func,const void * data)484 _ecore_con_eet_base_raw_data_callback_set(Eo *obj EINA_UNUSED, Ecore_Con_Eet_Base_Data *pd, const char *name, Ecore_Con_Eet_Raw_Data_Cb func, const void *data)
485 {
486 Ecore_Con_Eet_Raw_Data *ecerd;
487
488 ecerd = calloc(1, sizeof (Ecore_Con_Eet_Raw_Data));
489 if (!ecerd) return;
490
491 ecerd->func = func;
492 ecerd->data = data;
493 ecerd->name = eina_stringshare_add(name);
494
495 eina_hash_direct_add(pd->raw_data_callbacks, ecerd->name, ecerd);
496 }
497
498 EOLIAN static void
_ecore_con_eet_base_data_callback_del(Eo * obj EINA_UNUSED,Ecore_Con_Eet_Base_Data * pd,const char * name)499 _ecore_con_eet_base_data_callback_del(Eo *obj EINA_UNUSED, Ecore_Con_Eet_Base_Data *pd, const char *name)
500 {
501 eina_hash_del(pd->data_callbacks, name, NULL);
502 }
503
504 EOLIAN static void
_ecore_con_eet_base_raw_data_callback_del(Eo * obj,Ecore_Con_Eet_Base_Data * pd,const char * name)505 _ecore_con_eet_base_raw_data_callback_del(Eo *obj, Ecore_Con_Eet_Base_Data *pd, const char *name)
506 {
507 Ecore_Con_Eet_Client_Obj_Data *eced = efl_data_scope_get(obj, ECORE_CON_EET_CLIENT_OBJ_CLASS);
508
509 if (efl_isa(obj, ECORE_CON_EET_CLIENT_OBJ_CLASS) &&
510 eced->r->buffer_handler &&
511 !strcmp(eced->r->buffer_handler->name, name))
512 {
513 eced->r->buffer_handler = NULL;
514 free(eced->r->buffer);
515 eced->r->buffer = (void *)1;
516 }
517 eina_hash_del(pd->raw_data_callbacks, name, NULL);
518 }
519
520 EOLIAN static void
_ecore_con_eet_base_send(Eo * obj EINA_UNUSED,Ecore_Con_Eet_Base_Data * pd,Ecore_Con_Reply * reply,const char * name,void * value)521 _ecore_con_eet_base_send(Eo *obj EINA_UNUSED, Ecore_Con_Eet_Base_Data *pd, Ecore_Con_Reply *reply, const char *name, void *value)
522 {
523 Ecore_Con_Eet_Protocol protocol;
524
525 if (!reply) return;
526
527 protocol.type = name;
528 protocol.data = value;
529
530 eet_connection_send(reply->econn, pd->edd, &protocol, NULL);
531 }
532
533 EOLIAN static void
_ecore_con_eet_base_raw_send(Eo * obj EINA_UNUSED,Ecore_Con_Eet_Base_Data * pd,Ecore_Con_Reply * reply,const char * protocol_name,const char * section,Eina_Binbuf * section_data)534 _ecore_con_eet_base_raw_send(Eo *obj EINA_UNUSED, Ecore_Con_Eet_Base_Data *pd, Ecore_Con_Reply *reply, const char *protocol_name, const char *section, Eina_Binbuf *section_data)
535 {
536 unsigned int protocol[4];
537 unsigned int protocol_length;
538 unsigned int section_length;
539 unsigned int size;
540 unsigned int length = 0;
541 const void *value = NULL;
542 char *tmp;
543
544 if (!reply) return;
545 if (!protocol_name) return;
546 if (!section) return;
547
548 if (section_data)
549 {
550 length = eina_binbuf_length_get(section_data);
551 value = eina_binbuf_string_get(section_data);
552 }
553
554 protocol_length = strlen(protocol_name) + 1;
555 if (protocol_length == 1) return;
556 section_length = strlen(section) + 1;
557
558 protocol[0] = eina_htonl(ECORE_CON_EET_RAW_MAGIC);
559 protocol[1] = eina_htonl(protocol_length);
560 protocol[2] = eina_htonl(section_length);
561 protocol[3] = eina_htonl(length);
562
563 size = sizeof (protocol) + protocol_length + section_length;
564 tmp = alloca(size);
565 memcpy(tmp, protocol, sizeof (protocol));
566 memcpy(tmp + sizeof (protocol), protocol_name, protocol_length);
567 memcpy(tmp + sizeof (protocol) + protocol_length, section, section_length);
568
569 if (reply->client)
570 {
571 ecore_con_client_send(reply->client, tmp, size);
572 ecore_con_client_send(reply->client, value, length);
573 }
574 else
575 {
576 ecore_con_server_send(pd->server, tmp, size);
577 ecore_con_server_send(pd->server, value, length);
578 }
579 }
580
581 EOLIAN static void
_ecore_con_eet_base_register(Eo * obj EINA_UNUSED,Ecore_Con_Eet_Base_Data * pd,const char * name,Eet_Data_Descriptor * edd)582 _ecore_con_eet_base_register(Eo *obj EINA_UNUSED, Ecore_Con_Eet_Base_Data *pd, const char *name, Eet_Data_Descriptor *edd)
583 {
584 EET_DATA_DESCRIPTOR_ADD_MAPPING(pd->matching, name, edd);
585 }
586
587 EOLIAN static Efl_Object *
_ecore_con_eet_server_obj_efl_object_constructor(Eo * obj,Ecore_Con_Eet_Server_Obj_Data * pd EINA_UNUSED)588 _ecore_con_eet_server_obj_efl_object_constructor(Eo *obj, Ecore_Con_Eet_Server_Obj_Data *pd EINA_UNUSED)
589 {
590 obj = efl_constructor(efl_super(obj, ECORE_CON_EET_SERVER_OBJ_CLASS));
591
592 if (!obj) return NULL;
593
594 pd->handler_add = ecore_event_handler_add(ECORE_CON_EVENT_CLIENT_ADD,
595 (Ecore_Event_Handler_Cb)_ecore_con_eet_server_connected, obj);
596 pd->handler_del = ecore_event_handler_add(ECORE_CON_EVENT_CLIENT_DEL,
597 (Ecore_Event_Handler_Cb)_ecore_con_eet_server_disconnected, obj);
598 pd->handler_data = ecore_event_handler_add(ECORE_CON_EVENT_CLIENT_DATA,
599 (Ecore_Event_Handler_Cb)_ecore_con_eet_server_data, obj);
600
601 return obj;
602 }
603
604 EOLIAN static void
_ecore_con_eet_server_obj_efl_object_destructor(Eo * obj,Ecore_Con_Eet_Server_Obj_Data * pd EINA_UNUSED)605 _ecore_con_eet_server_obj_efl_object_destructor(Eo *obj, Ecore_Con_Eet_Server_Obj_Data *pd EINA_UNUSED)
606 {
607 Ecore_Con_Reply *n;
608 Ecore_Con_Eet_Client *c;
609
610 EINA_LIST_FREE(pd->connections, n)
611 {
612 _ecore_con_eet_reply_cleanup(n);
613 eet_connection_close(n->econn, NULL);
614 free(n);
615 }
616 EINA_LIST_FREE(pd->client_connect_callbacks, c)
617 free(c);
618 EINA_LIST_FREE(pd->client_disconnect_callbacks, c)
619 free(c);
620
621 ecore_event_handler_del(pd->handler_add);
622 ecore_event_handler_del(pd->handler_del);
623 ecore_event_handler_del(pd->handler_data);
624
625 efl_destructor(efl_super(obj, ECORE_CON_EET_SERVER_OBJ_CLASS));
626 }
627
628 EOLIAN static Efl_Object *
_ecore_con_eet_client_obj_efl_object_constructor(Eo * obj,Ecore_Con_Eet_Client_Obj_Data * pd EINA_UNUSED)629 _ecore_con_eet_client_obj_efl_object_constructor(Eo *obj, Ecore_Con_Eet_Client_Obj_Data *pd EINA_UNUSED)
630 {
631 obj = efl_constructor(efl_super(obj, ECORE_CON_EET_CLIENT_OBJ_CLASS));
632
633 if (!obj) return NULL;
634
635 pd->handler_add = ecore_event_handler_add(ECORE_CON_EVENT_SERVER_ADD,
636 (Ecore_Event_Handler_Cb)_ecore_con_eet_client_connected, obj);
637 pd->handler_del = ecore_event_handler_add(ECORE_CON_EVENT_SERVER_DEL,
638 (Ecore_Event_Handler_Cb)_ecore_con_eet_client_disconnected, obj);
639 pd->handler_data = ecore_event_handler_add(ECORE_CON_EVENT_SERVER_DATA,
640 (Ecore_Event_Handler_Cb)_ecore_con_eet_client_data, obj);
641
642 return obj;
643 }
644
645 EOLIAN static void
_ecore_con_eet_client_obj_efl_object_destructor(Eo * obj,Ecore_Con_Eet_Client_Obj_Data * pd EINA_UNUSED)646 _ecore_con_eet_client_obj_efl_object_destructor(Eo *obj, Ecore_Con_Eet_Client_Obj_Data *pd EINA_UNUSED)
647 {
648 Ecore_Con_Eet_Server *s;
649
650 if (pd->r)
651 {
652 _ecore_con_eet_reply_cleanup(pd->r);
653 eet_connection_close(pd->r->econn, NULL);
654 }
655 EINA_LIST_FREE(pd->server_connect_callbacks, s)
656 free(s);
657 EINA_LIST_FREE(pd->server_disconnect_callbacks, s)
658 free(s);
659
660 ecore_event_handler_del(pd->handler_add);
661 ecore_event_handler_del(pd->handler_del);
662 ecore_event_handler_del(pd->handler_data);
663
664 efl_destructor(efl_super(obj, ECORE_CON_EET_CLIENT_OBJ_CLASS));
665 }
666
667 EOLIAN static Efl_Object *
_ecore_con_eet_base_efl_object_constructor(Eo * obj,Ecore_Con_Eet_Base_Data * pd)668 _ecore_con_eet_base_efl_object_constructor(Eo *obj, Ecore_Con_Eet_Base_Data *pd)
669 {
670 obj = efl_constructor(efl_super(obj, ECORE_CON_EET_BASE_CLASS));
671
672 if (!obj) return NULL;
673
674 pd->data_callbacks = eina_hash_stringshared_new(_ecore_con_eet_data_free);
675 pd->raw_data_callbacks = eina_hash_string_superfast_new(_ecore_con_eet_raw_data_free);
676
677 _ecore_con_eet_data_descriptor_setup(pd);
678
679 return obj;
680 }
681
682 EOLIAN static void
_ecore_con_eet_base_efl_object_destructor(Eo * obj,Ecore_Con_Eet_Base_Data * pd)683 _ecore_con_eet_base_efl_object_destructor(Eo *obj, Ecore_Con_Eet_Base_Data *pd)
684 {
685 eet_data_descriptor_free(pd->edd);
686 eet_data_descriptor_free(pd->matching);
687 eina_hash_free(pd->data_callbacks);
688 eina_hash_free(pd->raw_data_callbacks);
689
690 efl_destructor(efl_super(obj, ECORE_CON_EET_BASE_CLASS));
691 }
692
693 EOLIAN static Efl_Object *
_ecore_con_eet_base_efl_object_finalize(Eo * obj,Ecore_Con_Eet_Base_Data * pd)694 _ecore_con_eet_base_efl_object_finalize(Eo *obj, Ecore_Con_Eet_Base_Data *pd)
695 {
696 if (!pd->server) return NULL;
697
698 return efl_finalize(efl_super(obj, ECORE_CON_EET_BASE_CLASS));
699 }
700
701 EOLIAN static void
_ecore_con_eet_base_server_set(Eo * obj EINA_UNUSED,Ecore_Con_Eet_Base_Data * pd,Ecore_Con_Server * data)702 _ecore_con_eet_base_server_set(Eo *obj EINA_UNUSED, Ecore_Con_Eet_Base_Data *pd, Ecore_Con_Server *data)
703 {
704 if (!ecore_con_server_check(data))
705 return;
706
707 pd->server = data;
708 }
709
710 EOLIAN static Ecore_Con_Server *
_ecore_con_eet_base_server_get(const Eo * obj EINA_UNUSED,Ecore_Con_Eet_Base_Data * pd)711 _ecore_con_eet_base_server_get(const Eo *obj EINA_UNUSED, Ecore_Con_Eet_Base_Data *pd)
712 {
713 return pd->server;
714 }
715
716 /**************
717 * Global API *
718 **************/
719
720 EAPI Ecore_Con_Eet *
ecore_con_eet_server_new(Ecore_Con_Server * server)721 ecore_con_eet_server_new(Ecore_Con_Server *server)
722 {
723 Ecore_Con_Eet *ece_obj;
724
725 if (!server) return NULL;
726
727 ece_obj = efl_add_ref(ECORE_CON_EET_SERVER_OBJ_CLASS, NULL, ecore_con_eet_base_server_set(efl_added, server));
728
729 return ece_obj;
730 }
731
732 EAPI Ecore_Con_Eet *
ecore_con_eet_client_new(Ecore_Con_Server * server)733 ecore_con_eet_client_new(Ecore_Con_Server *server)
734 {
735 Ecore_Con_Eet *ece_obj;
736
737 if (!server) return NULL;
738
739 ece_obj = efl_add_ref(ECORE_CON_EET_CLIENT_OBJ_CLASS, NULL, ecore_con_eet_base_server_set(efl_added, server));
740
741 return ece_obj;
742 }
743
744 EAPI void
ecore_con_eet_server_free(Ecore_Con_Eet * server)745 ecore_con_eet_server_free(Ecore_Con_Eet *server)
746 {
747 efl_unref(server);
748 }
749
750 EAPI void
ecore_con_eet_register(Ecore_Con_Eet * ece,const char * name,Eet_Data_Descriptor * edd)751 ecore_con_eet_register(Ecore_Con_Eet *ece, const char *name, Eet_Data_Descriptor *edd)
752 {
753 ecore_con_eet_base_register(ece, name, edd);
754 }
755
756 EAPI void
ecore_con_eet_data_callback_add(Ecore_Con_Eet * ece,const char * name,Ecore_Con_Eet_Data_Cb func,const void * data)757 ecore_con_eet_data_callback_add(Ecore_Con_Eet *ece, const char *name, Ecore_Con_Eet_Data_Cb func, const void *data)
758 {
759 ecore_con_eet_base_data_callback_set(ece, name, func, data);
760 }
761
762 EAPI void
ecore_con_eet_data_callback_del(Ecore_Con_Eet * ece,const char * name)763 ecore_con_eet_data_callback_del(Ecore_Con_Eet *ece, const char *name)
764 {
765 ecore_con_eet_base_data_callback_del(ece, name);
766 }
767
768 EAPI void
ecore_con_eet_raw_data_callback_add(Ecore_Con_Eet * ece,const char * name,Ecore_Con_Eet_Raw_Data_Cb func,const void * data)769 ecore_con_eet_raw_data_callback_add(Ecore_Con_Eet *ece, const char *name, Ecore_Con_Eet_Raw_Data_Cb func, const void *data)
770 {
771 ecore_con_eet_base_raw_data_callback_set(ece, name, func, data);
772 }
773
774 EAPI void
ecore_con_eet_raw_data_callback_del(Ecore_Con_Eet * ece,const char * name)775 ecore_con_eet_raw_data_callback_del(Ecore_Con_Eet *ece, const char *name)
776 {
777 ecore_con_eet_base_raw_data_callback_del(ece, name);
778 }
779
780 EAPI void
ecore_con_eet_client_connect_callback_add(Ecore_Con_Eet * ece,Ecore_Con_Eet_Client_Cb func,const void * data)781 ecore_con_eet_client_connect_callback_add(Ecore_Con_Eet *ece, Ecore_Con_Eet_Client_Cb func, const void *data)
782 {
783 Ecore_Con_Eet_Server_Obj_Data *eces = efl_data_scope_get(ece, ECORE_CON_EET_SERVER_OBJ_CLASS);
784 Ecore_Con_Eet_Client *c;
785
786 if (!eces || !func) return;
787
788 c = calloc(1, sizeof (Ecore_Con_Eet_Client));
789 if (!c) return;
790
791 c->func = func;
792 c->data = data;
793
794 eces->client_connect_callbacks = eina_list_append(eces->client_connect_callbacks, c);
795 }
796
797 EAPI void
ecore_con_eet_client_connect_callback_del(Ecore_Con_Eet * ece,Ecore_Con_Eet_Client_Cb func,const void * data)798 ecore_con_eet_client_connect_callback_del(Ecore_Con_Eet *ece, Ecore_Con_Eet_Client_Cb func, const void *data)
799 {
800 Ecore_Con_Eet_Server_Obj_Data *eces = efl_data_scope_get(ece, ECORE_CON_EET_SERVER_OBJ_CLASS);
801 Ecore_Con_Eet_Client *c;
802 Eina_List *l;
803
804 if (!eces || !func) return;
805
806 EINA_LIST_FOREACH(eces->client_connect_callbacks, l, c)
807 if (c->func == func && c->data == data)
808 {
809 eces->client_connect_callbacks = eina_list_remove_list(eces->client_connect_callbacks, l);
810 free(c);
811 return;
812 }
813 }
814
815 EAPI void
ecore_con_eet_client_disconnect_callback_add(Ecore_Con_Eet * ece,Ecore_Con_Eet_Client_Cb func,const void * data)816 ecore_con_eet_client_disconnect_callback_add(Ecore_Con_Eet *ece, Ecore_Con_Eet_Client_Cb func, const void *data)
817 {
818 Ecore_Con_Eet_Server_Obj_Data *eces = efl_data_scope_get(ece, ECORE_CON_EET_SERVER_OBJ_CLASS);
819 Ecore_Con_Eet_Client *c;
820
821 if (!eces || !func) return;
822
823 c = calloc(1, sizeof (Ecore_Con_Eet_Client));
824 if (!c) return;
825
826 c->func = func;
827 c->data = data;
828
829 eces->client_disconnect_callbacks = eina_list_append(eces->client_disconnect_callbacks, c);
830 }
831
832 EAPI void
ecore_con_eet_client_disconnect_callback_del(Ecore_Con_Eet * ece,Ecore_Con_Eet_Client_Cb func,const void * data)833 ecore_con_eet_client_disconnect_callback_del(Ecore_Con_Eet *ece, Ecore_Con_Eet_Client_Cb func, const void *data)
834 {
835 Ecore_Con_Eet_Server_Obj_Data *eced = efl_data_scope_get(ece, ECORE_CON_EET_SERVER_OBJ_CLASS);
836 Ecore_Con_Eet_Client *c;
837 Eina_List *l;
838
839 if (!eced || !func) return;
840
841 EINA_LIST_FOREACH(eced->client_disconnect_callbacks, l, c)
842 if (c->func == func && c->data == data)
843 {
844 eced->client_disconnect_callbacks = eina_list_remove_list(eced->client_disconnect_callbacks, l);
845 free(c);
846 return;
847 }
848 }
849
850 EAPI void
ecore_con_eet_server_connect_callback_add(Ecore_Con_Eet * ece,Ecore_Con_Eet_Server_Cb func,const void * data)851 ecore_con_eet_server_connect_callback_add(Ecore_Con_Eet *ece, Ecore_Con_Eet_Server_Cb func, const void *data)
852 {
853 Ecore_Con_Eet_Client_Obj_Data *eced = efl_data_scope_get(ece, ECORE_CON_EET_CLIENT_OBJ_CLASS);
854 Ecore_Con_Eet_Server *s;
855
856 if (!eced || !func) return;
857
858 s = calloc(1, sizeof (Ecore_Con_Eet_Server));
859 if (!s) return;
860
861 s->func = func;
862 s->data = data;
863
864 eced->server_connect_callbacks = eina_list_append(eced->server_connect_callbacks, s);
865 }
866
867 EAPI void
ecore_con_eet_server_connect_callback_del(Ecore_Con_Eet * ece,Ecore_Con_Eet_Server_Cb func,const void * data)868 ecore_con_eet_server_connect_callback_del(Ecore_Con_Eet *ece, Ecore_Con_Eet_Server_Cb func, const void *data)
869 {
870 Ecore_Con_Eet_Client_Obj_Data *eced = efl_data_scope_get(ece, ECORE_CON_EET_CLIENT_OBJ_CLASS);
871 Ecore_Con_Eet_Server *s;
872 Eina_List *l;
873
874 if (!eced || !func) return;
875
876 EINA_LIST_FOREACH(eced->server_connect_callbacks, l, s)
877 if (s->func == func && s->data == data)
878 {
879 eced->server_connect_callbacks = eina_list_remove_list(eced->server_connect_callbacks, l);
880 free(s);
881 return;
882 }
883 }
884
885 EAPI void
ecore_con_eet_server_disconnect_callback_add(Ecore_Con_Eet * ece,Ecore_Con_Eet_Server_Cb func,const void * data)886 ecore_con_eet_server_disconnect_callback_add(Ecore_Con_Eet *ece, Ecore_Con_Eet_Server_Cb func, const void *data)
887 {
888 Ecore_Con_Eet_Client_Obj_Data *eced = efl_data_scope_get(ece, ECORE_CON_EET_CLIENT_OBJ_CLASS);
889 Ecore_Con_Eet_Server *s;
890
891 if (!eced || !func) return;
892
893 s = calloc(1, sizeof (Ecore_Con_Eet_Server));
894 if (!s) return;
895
896 s->func = func;
897 s->data = data;
898
899 eced->server_disconnect_callbacks = eina_list_append(eced->server_disconnect_callbacks, s);
900 }
901
902 EAPI void
ecore_con_eet_server_disconnect_callback_del(Ecore_Con_Eet * ece,Ecore_Con_Eet_Server_Cb func,const void * data)903 ecore_con_eet_server_disconnect_callback_del(Ecore_Con_Eet *ece, Ecore_Con_Eet_Server_Cb func, const void *data)
904 {
905 Ecore_Con_Eet_Client_Obj_Data *eced = efl_data_scope_get(ece, ECORE_CON_EET_CLIENT_OBJ_CLASS);
906 Ecore_Con_Eet_Server *s;
907 Eina_List *l;
908
909 if (!eced || !func) return;
910
911 EINA_LIST_FOREACH(eced->server_disconnect_callbacks, l, s)
912 if (s->func == func && s->data == data)
913 {
914 eced->server_disconnect_callbacks = eina_list_remove_list(eced->server_disconnect_callbacks, l);
915 free(s);
916 return;
917 }
918 }
919
920 EAPI void
ecore_con_eet_data_set(Ecore_Con_Eet * ece,const void * data)921 ecore_con_eet_data_set(Ecore_Con_Eet *ece, const void *data)
922 {
923 efl_key_data_set(ece, ECORE_CON_EET_DATA_KEY, data);
924 }
925
926 EAPI const void *
ecore_con_eet_data_get(Ecore_Con_Eet * ece)927 ecore_con_eet_data_get(Ecore_Con_Eet *ece)
928 {
929 return efl_key_data_get(ece, ECORE_CON_EET_DATA_KEY);
930 }
931
932 EAPI Ecore_Con_Eet *
ecore_con_eet_reply(Ecore_Con_Reply * reply)933 ecore_con_eet_reply(Ecore_Con_Reply *reply)
934 {
935 if (!reply) return NULL;
936 return reply->ece;
937 }
938
939 EAPI void
ecore_con_eet_send(Ecore_Con_Reply * reply,const char * name,void * value)940 ecore_con_eet_send(Ecore_Con_Reply *reply, const char *name, void *value)
941 {
942 ecore_con_eet_base_send(reply->ece, reply, name, value);
943 }
944
945 EAPI void
ecore_con_eet_raw_send(Ecore_Con_Reply * reply,const char * protocol_name,const char * section,void * value,unsigned int length)946 ecore_con_eet_raw_send(Ecore_Con_Reply *reply, const char *protocol_name, const char *section, void *value, unsigned int length)
947 {
948 Eina_Binbuf *buf = eina_binbuf_manage_new(value, length, 1);
949 ecore_con_eet_base_raw_send(reply->ece, reply, protocol_name, section, buf);
950 eina_binbuf_free(buf);
951 }
952
953 #include "ecore_con_eet_base_eo.c"
954 #include "ecore_con_eet_server_obj_eo.c"
955 #include "ecore_con_eet_client_obj_eo.c"
956