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
[email protected]
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel