From 90d9f039bc67f902dcb0525354b65b58c540bd2d Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 2 Jan 2007 01:38:20 +0000 Subject: committed patch 1612910 to add multicast support to the OSCx objects. I took out the changes to configure.ac since it broke the Pd-extended build stuff. svn path=/trunk/externals/OSCx/; revision=7120 --- src/dumpOSC.c | 41 +++++++++++++++++++++++++++++++++++++---- src/htmsocket.c | 14 ++++++++++++-- src/htmsocket.h | 2 +- src/sendOSC.c | 39 +++++++++++++++++++++++++++++++-------- 4 files changed, 81 insertions(+), 15 deletions(-) diff --git a/src/dumpOSC.c b/src/dumpOSC.c index 05e117f..d495442 100644 --- a/src/dumpOSC.c +++ b/src/dumpOSC.c @@ -253,13 +253,35 @@ static void dumpOSC_read(t_dumpOSC *x, int sockfd) { } static void *dumpOSC_new(t_symbol *compatflag, - t_floatarg fportno) { + int argc, t_atom* argv) { t_dumpOSC *x; struct sockaddr_in server; int clilen=sizeof(server); int sockfd; - int portno=fportno; + int portno=0; int udp = 1; + t_symbol *castgroup=NULL; + + if (argc == 1) { + if (argv[0].a_type==A_FLOAT) + portno = (int)argv[0].a_w.w_float; + else + return NULL; + } + + else if (argc == 2) { + if (argv[0].a_type==A_SYMBOL) + castgroup = argv[0].a_w.w_symbol; + else + return NULL; + + if (argv[1].a_type==A_FLOAT) + portno = (int)argv[1].a_w.w_float; + else + return NULL; + } + + else return NULL; //x->x_b = binbuf_new(); //x->x_outat = binbuf_getvec(x->x_b); @@ -278,6 +300,18 @@ static void *dumpOSC_new(t_symbol *compatflag, server.sin_addr.s_addr = INADDR_ANY; /* assign server port number */ server.sin_port = htons((u_short)portno); + + // ss 2006 + if (castgroup) { + struct ip_mreq mreq; + mreq.imr_multiaddr.s_addr = inet_addr(castgroup->s_name); + mreq.imr_interface.s_addr = htonl(INADDR_ANY); + if (setsockopt(sockfd,IPPROTO_IP,IP_ADD_MEMBERSHIP,&mreq,sizeof(mreq)) < 0) { + sys_sockerror("setsockopt"); + } + } + + /* name the socket */ if (bind(sockfd, (struct sockaddr *)&server, sizeof(server)) < 0) { @@ -339,8 +373,7 @@ void dumpOSC_setup(void) { dumpOSC_class = class_new(gensym("dumpOSC"), (t_newmethod)dumpOSC_new, (t_method)dumpOSC_free, - sizeof(t_dumpOSC), CLASS_NOINLET, A_DEFFLOAT, A_DEFFLOAT, - A_DEFSYM, 0); + sizeof(t_dumpOSC), CLASS_NOINLET, A_GIMME, 0); class_sethelpsymbol(dumpOSC_class, gensym("dumpOSC-help.pd")); } diff --git a/src/htmsocket.c b/src/htmsocket.c index d9d9343..36b1d1a 100644 --- a/src/htmsocket.c +++ b/src/htmsocket.c @@ -104,7 +104,7 @@ typedef struct /* open a socket for HTM communication to given host on given portnumber */ /* if host is 0 then UNIX protocol is used (i.e. local communication */ -void *OpenHTMSocket(char *host, int portnumber) +void *OpenHTMSocket(char *host, int portnumber, unsigned char multicast_TTL) { struct sockaddr_in cl_addr; #ifndef WIN32 @@ -229,7 +229,12 @@ void *OpenHTMSocket(char *host, int portnumber) // enable broadcast: jdl ~2003 if(setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &oval, sizeof(int)) == -1) { - perror("setsockopt"); + perror("setsockopt broadcast"); + } + + // set multicast Time-To-Live: ss + if(setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_TTL, &multicast_TTL, sizeof(multicast_TTL)) == -1) { + perror("setsockopt TTL"); } if(bind(sockfd, (struct sockaddr *) &cl_addr, sizeof(cl_addr)) < 0) { @@ -253,6 +258,11 @@ void *OpenHTMSocket(char *host, int portnumber) perror("setsockopt"); } + // set multicast Time-To-Live: ss 2006 + if(setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_TTL, &multicast_TTL, sizeof(multicast_TTL)) == -1) { + perror("setsockopt TTL"); + } + if(bind(sockfd, (struct sockaddr *) &cl_addr, sizeof(cl_addr)) < 0) { perror("could not bind\n"); close(sockfd); diff --git a/src/htmsocket.h b/src/htmsocket.h index 07bea93..fcdeccc 100644 --- a/src/htmsocket.h +++ b/src/htmsocket.h @@ -38,7 +38,7 @@ typedef int bool; /* open a socket for HTM communication to given host on given portnumber */ /* if host is 0 then UNIX protocol is used (i.e. local communication) */ -void *OpenHTMSocket(char *host, int portnumber); +void *OpenHTMSocket(char *host, int portnumber, unsigned char multicast_TTL); /* send a buffer of data over htm socket, returns TRUE on success. Note that udp sends rarely fail. UNIX sends fail if a kernal buffer overflows */ diff --git a/src/sendOSC.c b/src/sendOSC.c index 10c22c9..3c99402 100644 --- a/src/sendOSC.c +++ b/src/sendOSC.c @@ -113,7 +113,7 @@ static void *sendOSC_new(t_floatarg udpflag); void sendOSC_openbundle(t_sendOSC *x); static void sendOSC_closebundle(t_sendOSC *x); static void sendOSC_settypetags(t_sendOSC *x, t_float *f); -static void sendOSC_connect(t_sendOSC *x, t_symbol *hostname, t_floatarg fportno); +static void sendOSC_connect(t_sendOSC *x, t_symbol *s, int argc, t_atom *argv); void sendOSC_disconnect(t_sendOSC *x); static void sendOSC_sendtyped(t_sendOSC *x, t_symbol *s, int argc, t_atom *argv); void sendOSC_send(t_sendOSC *x, t_symbol *s, int argc, t_atom *argv); @@ -187,16 +187,39 @@ static void sendOSC_settypetags(t_sendOSC *x, t_float *f) post("sendOSC.c: setting typetags %d",x->x_typetags); } -static void sendOSC_connect(t_sendOSC *x, t_symbol *hostname, t_floatarg fportno) +static void sendOSC_connect(t_sendOSC *x, t_symbol *s, int argc, t_atom *argv) // t_symbol *hostname, t_floatarg fportno, int argc, t_atom *argv) { - int portno = fportno; + float fportno=0; + t_symbol *hostname; + int portno = fportno; + unsigned char ttl=1; char *protocolStr; - /* create a socket */ + /* create a socket */ + + if (argc < 2) + return; + + if (argv[0].a_type==A_SYMBOL) + hostname = argv[0].a_w.w_symbol; + else + return; + + if (argv[1].a_type==A_FLOAT) + portno = (int)argv[1].a_w.w_float; + else + return; + + if (argc >= 3) { + if (argv[2].a_type==A_FLOAT) + ttl = (unsigned char)argv[2].a_w.w_float; + else + return; + } // make sure handle is available if(x->x_htmsocket == 0) { - x->x_htmsocket = OpenHTMSocket(hostname->s_name, portno); + x->x_htmsocket = OpenHTMSocket(hostname->s_name, portno, ttl); if (!x->x_htmsocket) post("sendOSC: Couldn't open socket: "); else @@ -213,8 +236,8 @@ static void sendOSC_connect(t_sendOSC *x, t_symbol *hostname, t_floatarg fportno protocolStr = "unknown"; break; } - post("sendOSC: connected to port %s:%d (hSock=%d) protocol = %s", - hostname->s_name, portno, x->x_htmsocket, protocolStr); + post("sendOSC: connected to port %s:%d (hSock=%d) protocol = %s ttl = %d", + hostname->s_name, portno, x->x_htmsocket, protocolStr, ttl); outlet_float(x->x_obj.ob_outlet, 1); } } @@ -337,7 +360,7 @@ void sendOSC_setup(void) (t_method)sendOSC_free, sizeof(t_sendOSC), 0, A_DEFFLOAT, 0); class_addmethod(sendOSC_class, (t_method)sendOSC_connect, - gensym("connect"), A_SYMBOL, A_FLOAT, 0); + gensym("connect"), A_GIMME, 0); class_addmethod(sendOSC_class, (t_method)sendOSC_disconnect, gensym("disconnect"), 0); class_addmethod(sendOSC_class, (t_method)sendOSC_settypetags, -- cgit v1.2.1