Hello, I am working on adding multicast support to ecore. This code let's you set up a multicast listener using the call:
mcast_svr = ecore_con_server_add(ECORE_CON_REMOTE_MCAST, "239.255.2.1", 1201, NULL); The only thing new about the ecore_con_server_add() call is that the "name" parameter is the multicast address. Previously, this parameter was ignored for REMOTE_SYSTEM connections. The multicast handler callback below emits an ECORE_CON_EVENT_CLIENT_DATA signal for each multicast packet that is received. If this is not desired, the _ecore_svr_cl_handler() callback could be used instead. Handle the multicast client data as usual by registering the callback: ecore_event_handler_add(ECORE_CON_EVENT_CLIENT_DATA, (Handler_Func)client_data, NULL); I am going to work on UDP client and multicast support next. Regards, Matt Index: Ecore_Con.h =================================================================== RCS file: /var/cvs/e/e17/libs/ecore/src/lib/ecore_con/Ecore_Con.h,v retrieving revision 1.42 diff -u -r1.42 Ecore_Con.h --- Ecore_Con.h 8 Jul 2008 04:08:52 -0000 1.42 +++ Ecore_Con.h 5 Sep 2008 03:42:09 -0000 @@ -79,6 +79,7 @@ ECORE_CON_LOCAL_SYSTEM, ECORE_CON_LOCAL_ABSTRACT, ECORE_CON_REMOTE_SYSTEM, + ECORE_CON_REMOTE_MCAST, ECORE_CON_USE_SSL2 = (1 << 4), ECORE_CON_USE_SSL3 = (1 << 5), ECORE_CON_USE_TLS = (1 << 6) Index: ecore_con.c =================================================================== RCS file: /var/cvs/e/e17/libs/ecore/src/lib/ecore_con/ecore_con.c,v retrieving revision 1.95 diff -u -r1.95 ecore_con.c --- ecore_con.c 26 May 2008 05:16:33 -0000 1.95 +++ ecore_con.c 5 Sep 2008 03:42:09 -0000 @@ -31,6 +31,7 @@ static void _ecore_con_client_free(Ecore_Con_Client *cl); static int _ecore_con_svr_handler(void *data, Ecore_Fd_Handler *fd_handler); static int _ecore_con_cl_handler(void *data, Ecore_Fd_Handler *fd_handler); +static int _ecore_con_mcast_handler(void *data, Ecore_Fd_Handler *fd_handler); static int _ecore_con_svr_cl_handler(void *data, Ecore_Fd_Handler *fd_handler); static void _ecore_con_server_flush(Ecore_Con_Server *svr); static void _ecore_con_client_flush(Ecore_Con_Client *cl); @@ -154,8 +155,10 @@ Ecore_Con_Type type; struct sockaddr_in socket_addr; struct sockaddr_un socket_unix; + struct ip_mreq mreq; struct linger lin; char buf[4096]; + const int on=1; if (port < 0) return NULL; /* local user socket: FILE: ~/.ecore/[name]/[port] */ @@ -318,6 +321,25 @@ _ecore_con_svr_handler, svr, NULL, NULL); if (!svr->fd_handler) goto error; } + else if (type == ECORE_CON_REMOTE_MCAST) + { + svr->fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); + if(svr->fd < 0) goto error; + mreq.imr_multiaddr.s_addr = inet_addr(name); + mreq.imr_interface.s_addr = htonl(INADDR_ANY); + if (setsockopt(svr->fd, SOL_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) != 0) goto error; + if (setsockopt(svr->fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) != 0) goto error; + if (fcntl(svr->fd, F_SETFL, O_NONBLOCK) < 0) goto error; + if (fcntl(svr->fd, F_SETFD, FD_CLOEXEC) < 0) goto error; + socket_addr.sin_family = AF_INET; + socket_addr.sin_port = htons(port); + socket_addr.sin_addr.s_addr = inet_addr(name); + if (bind(svr->fd, (struct sockaddr *)&socket_addr, sizeof(struct sockaddr_in)) < 0) goto error; + svr->fd_handler = + ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ, + _ecore_con_mcast_handler, svr, NULL, NULL); + if (!svr->fd_handler) goto error; + } #if USE_OPENSSL if (compl_type & ECORE_CON_SSL) @@ -1411,6 +1433,76 @@ } static int +_ecore_con_mcast_handler(void *data, Ecore_Fd_Handler *fd_handler) +{ + Ecore_Con_Client *cl; + + cl = data; + if (cl->dead) return 1; + if (cl->delete_me) return 1; + if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ)) + { + unsigned char buf[65536]; + int num; + + errno = 0; + num = read(cl->fd, buf, 65536); + if (num > 0) + { + if (!cl->delete_me) + { + Ecore_Con_Event_Client_Data *e; + unsigned char *inbuf; + + inbuf = malloc(num); + if(inbuf == NULL) + return 1; + memcpy(inbuf, buf, num); + + e = calloc(1, sizeof(Ecore_Con_Event_Client_Data)); + if (e) + { + cl->event_count++; + e->client = cl; + e->data = inbuf; + e->size = num; + ecore_event_add(ECORE_CON_EVENT_CLIENT_DATA, e, + _ecore_con_event_client_data_free, + NULL); + } + } + if ((errno == EIO) || (errno == EBADF) || + (errno == EPIPE) || (errno == EINVAL) || + (errno == ENOSPC) || (num == 0)/* is num == 0 right? */) + { + if (!cl->delete_me) + { + /* we lost our client! */ + Ecore_Con_Event_Client_Del *e; + + e = calloc(1, sizeof(Ecore_Con_Event_Client_Del)); + if (e) + { + cl->event_count++; + e->client = cl; + ecore_event_add(ECORE_CON_EVENT_CLIENT_DEL, e, + _ecore_con_event_client_del_free, + NULL); + } + } + cl->dead = 1; + if (cl->fd_handler) + ecore_main_fd_handler_del(cl->fd_handler); + cl->fd_handler = NULL; + } + } + } + else if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_WRITE)) + _ecore_con_client_flush(cl); + return 1; +} + +static int _ecore_con_svr_cl_handler(void *data, Ecore_Fd_Handler *fd_handler) { Ecore_Con_Client *cl; ------------------------------------------------------------------------- This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK & win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100&url=/ _______________________________________________ enlightenment-devel mailing list enlightenment-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/enlightenment-devel