aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--net/udpreceive-help.pd90
-rw-r--r--net/udpreceive.c103
2 files changed, 113 insertions, 80 deletions
diff --git a/net/udpreceive-help.pd b/net/udpreceive-help.pd
index 530e503..5bded46 100644
--- a/net/udpreceive-help.pd
+++ b/net/udpreceive-help.pd
@@ -1,43 +1,47 @@
-#N canvas 238 505 742 371 12;
-#X floatatom 394 264 3 0 0 0 - - -;
-#X floatatom 421 264 3 0 0 0 - - -;
-#X floatatom 448 264 3 0 0 0 - - -;
-#X floatatom 475 264 3 0 0 0 - - -;
-#X obj 171 120 udpreceive 9997;
-#X floatatom 502 265 5 0 0 0 - - -;
-#X obj 394 238 unpack 0 0 0 0 0;
-#X msg 171 90 status;
-#X floatatom 273 185 9 0 0 0 - - -;
-#X obj 454 211 tgl 15 0 empty empty empty 17 7 0 10 -4034 -1 -1 0 1
-;
-#X floatatom 333 211 9 0 0 0 - - -;
-#X text -30 90 get status on right outlet:;
-#X text 166 185 bytes received:;
-#X text 181 209 total bytes received:;
-#X text 351 263 from:;
-#X text 299 97 Specify a multicast address (from 224.0.0.0 to 239.255.255.255)
-to use multicasting;
-#X text 162 57 Creation arguments: port number to listen on (required)
-;
-#X text 124 33 [udpreceive] receives bytes over a udp connection.;
-#X obj 171 254 spigot;
-#X obj 210 234 tgl 15 0 empty empty enable_print: -77 8 0 10 -4034
--1 -1 0 1;
-#X obj 171 279 print received;
-#X obj 273 152 route received total from multicast;
-#X text 301 75 IP address to listen on (optional);
-#X text 466 320 Martin Peach 2010/08/05;
-#X connect 4 0 18 0;
-#X connect 4 1 21 0;
-#X connect 6 0 0 0;
-#X connect 6 1 1 0;
-#X connect 6 2 2 0;
-#X connect 6 3 3 0;
-#X connect 6 4 5 0;
-#X connect 7 0 4 0;
-#X connect 18 0 20 0;
-#X connect 19 0 18 1;
-#X connect 21 0 8 0;
-#X connect 21 1 10 0;
-#X connect 21 2 6 0;
-#X connect 21 3 9 0;
+#N canvas 238 314 742 409 12;
+#X floatatom 414 304 3 0 0 0 - - -;
+#X floatatom 441 304 3 0 0 0 - - -;
+#X floatatom 468 304 3 0 0 0 - - -;
+#X floatatom 495 304 3 0 0 0 - - -;
+#X obj 191 160 udpreceive 9997;
+#X floatatom 522 305 5 0 0 0 - - -;
+#X obj 414 278 unpack 0 0 0 0 0;
+#X msg 191 90 status;
+#X floatatom 293 225 9 0 0 0 - - -;
+#X obj 474 251 tgl 15 0 empty empty empty 17 7 0 10 -4034 -1 -1 0 1
+;
+#X floatatom 353 251 9 0 0 0 - - -;
+#X text -10 90 get status on right outlet:;
+#X text 186 225 bytes received:;
+#X text 201 249 total bytes received:;
+#X text 371 303 from:;
+#X text 293 78 Specify a multicast address (from 224.0.0.0 to 239.255.255.255)
+to use multicasting;
+#X text 36 38 Creation arguments: port number to listen on (required)
+;
+#X obj 191 294 spigot;
+#X obj 230 274 tgl 15 0 empty empty enable_print: -77 8 0 10 -4034
+-1 -1 0 1;
+#X obj 191 319 print received;
+#X obj 293 192 route received total from multicast;
+#X text 175 56 IP address to listen on (optional);
+#X msg 202 129 port 9998;
+#X text 276 127 change port to listen on;
+#X text 486 360 Martin Peach 2010/10/15;
+#X text -12 3 [udpreceive] receives datagrams over a udp connection
+and outputs them as raw bytes.;
+#X connect 4 0 17 0;
+#X connect 4 1 20 0;
+#X connect 6 0 0 0;
+#X connect 6 1 1 0;
+#X connect 6 2 2 0;
+#X connect 6 3 3 0;
+#X connect 6 4 5 0;
+#X connect 7 0 4 0;
+#X connect 17 0 19 0;
+#X connect 18 0 17 1;
+#X connect 20 0 8 0;
+#X connect 20 1 10 0;
+#X connect 20 2 6 0;
+#X connect 20 3 9 0;
+#X connect 22 0 4 0;
diff --git a/net/udpreceive.c b/net/udpreceive.c
index e65d58f..09d31b8 100644
--- a/net/udpreceive.c
+++ b/net/udpreceive.c
@@ -38,14 +38,17 @@ typedef struct _udpreceive
t_atom x_addrbytes[5];
t_atom x_msgoutbuf[MAX_UDP_RECEIVE];
char x_msginbuf[MAX_UDP_RECEIVE];
+ char addr[256]; // a multicast address or 0
} t_udpreceive;
void udpreceive_setup(void);
static void udpreceive_free(t_udpreceive *x);
static void *udpreceive_new(t_symbol *s, int argc, t_atom *argv);
+static int udpreceive_new_socket(t_udpreceive *x, char *address, int port);
static void udpreceive_sock_err(t_udpreceive *x, char *err_string);
static void udpreceive_status(t_udpreceive *x);
static void udpreceive_read(t_udpreceive *x, int sockfd);
+static void udpreceive_port(t_udpreceive *x, t_float portno);
static void udpreceive_read(t_udpreceive *x, int sockfd)
{
@@ -97,42 +100,75 @@ static void udpreceive_read(t_udpreceive *x, int sockfd)
static void *udpreceive_new(t_symbol *s, int argc, t_atom *argv)
{
t_udpreceive *x;
- struct sockaddr_in server;
- struct hostent *hp;
-#if defined __APPLE__ || defined _WIN32
- struct ip_mreq mreq;
-#else
- struct ip_mreqn mreq;
-#endif
- int sockfd, portno = 0;
- int multicast_joined = 0;
- int intarg, i;
- char addr[256] = {'\0'};
+ int result = 0, portno = 0;
+ int i;
x = (t_udpreceive *)pd_new(udpreceive_class); /* if something fails we return 0 instead of x. Is this OK? */
+ if (NULL == x) return x;
+ x->addr[0] = '\0';
+ /* convert the bytes in the buffer to floats in a list */
+ for (i = 0; i < MAX_UDP_RECEIVE; ++i)
+ {
+ x->x_msgoutbuf[i].a_type = A_FLOAT;
+ x->x_msgoutbuf[i].a_w.w_float = 0;
+ }
+ for (i = 0; i < 5; ++i)
+ {
+ x->x_addrbytes[i].a_type = A_FLOAT;
+ x->x_addrbytes[i].a_w.w_float = 0;
+ }
#ifdef DEBUG
post("udpreceive_new:argc is %d s is %s", argc, s->s_name);
#endif
for (i = 0; i < argc ;++i)
{
if (argv[i].a_type == A_FLOAT)
- {
+ { // float is taken to be a port number
#ifdef DEBUG
post ("argv[%d] is a float: %f", i, argv[i].a_w.w_float);
#endif
portno = (int)argv[i].a_w.w_float;
}
else if (argv[i].a_type == A_SYMBOL)
- {
+ { // symbol is taken to be an ip address (for multicast)
#ifdef DEBUG
post ("argv[%d] is a symbol: %s", i, argv[i].a_w.w_symbol->s_name);
#endif
- atom_string(&argv[i], addr, 256);
+ atom_string(&argv[i], x->addr, 256);
}
}
#ifdef DEBUG
- post("Setting port %d, address %s", portno, addr);
+ post("Setting port %d, address %s", portno, x->addr);
+#endif
+
+ x->x_msgout = outlet_new(&x->x_obj, &s_anything);
+ x->x_addrout = outlet_new(&x->x_obj, &s_anything);
+
+ x->x_connectsocket = -1; // no socket
+ result = udpreceive_new_socket(x, x->addr, portno);
+ return (x);
+}
+
+static int udpreceive_new_socket(t_udpreceive *x, char *address, int port)
+{
+// return nonzero if successful in creating and binding a socket
+ int sockfd;
+ int intarg;
+ int multicast_joined = 0;
+ struct sockaddr_in server;
+ struct hostent *hp;
+#if defined __APPLE__ || defined _WIN32
+ struct ip_mreq mreq;
+#else
+ struct ip_mreqn mreq;
#endif
+
+ if (x->x_connectsocket >= 0)
+ {
+ // close the existing socket first
+ sys_rmpollfn(x->x_connectsocket);
+ sys_closesocket(x->x_connectsocket);
+ }
/* create a socket */
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
#ifdef DEBUG
@@ -144,10 +180,10 @@ static void *udpreceive_new(t_symbol *s, int argc, t_atom *argv)
return 0;
}
server.sin_family = AF_INET;
- if (addr[0] == 0) server.sin_addr.s_addr = INADDR_ANY;
+ if (address[0] == 0) server.sin_addr.s_addr = INADDR_ANY;
else
{
- hp = gethostbyname(addr);
+ hp = gethostbyname(address);
if (hp == 0)
{
pd_error(x, "udpreceive: bad host?\n");
@@ -163,7 +199,7 @@ static void *udpreceive_new(t_symbol *s, int argc, t_atom *argv)
udpreceive_sock_err(x, "udpreceive: setsockopt (SO_REUSEADDR) failed");
/* assign server port number */
- server.sin_port = htons((u_short)portno);
+ server.sin_port = htons((u_short)port);
/* if a multicast address was specified, join the multicast group */
/* hop count defaults to 1 so we won't leave the subnet*/
@@ -175,7 +211,7 @@ static void *udpreceive_new(t_symbol *s, int argc, t_atom *argv)
{
udpreceive_sock_err(x, "udpreceive: bind");
sys_closesocket(sockfd);
- return (0);
+ return 0;
}
/* second join the multicast group */
memcpy((char *)&server.sin_addr, (char *)hp->h_addr, hp->h_length);
@@ -204,29 +240,14 @@ static void *udpreceive_new(t_symbol *s, int argc, t_atom *argv)
{
udpreceive_sock_err(x, "udpreceive: bind");
sys_closesocket(sockfd);
- return (0);
+ return 0;
}
}
-
- x->x_msgout = outlet_new(&x->x_obj, &s_anything);
- x->x_addrout = outlet_new(&x->x_obj, &s_anything);
- x->x_connectsocket = sockfd;
-
- /* convert the bytes in the buffer to floats in a list */
- for (i = 0; i < MAX_UDP_RECEIVE; ++i)
- {
- x->x_msgoutbuf[i].a_type = A_FLOAT;
- x->x_msgoutbuf[i].a_w.w_float = 0;
- }
- for (i = 0; i < 5; ++i)
- {
- x->x_addrbytes[i].a_type = A_FLOAT;
- x->x_addrbytes[i].a_w.w_float = 0;
- }
x->x_multicast_joined = multicast_joined;
+ x->x_connectsocket = sockfd;
x->x_total_received = 0L;
sys_addpollfn(x->x_connectsocket, (t_fdpollfn)udpreceive_read, x);
- return (x);
+ return 1;
}
static void udpreceive_sock_err(t_udpreceive *x, char *err_string)
@@ -268,6 +289,12 @@ static void udpreceive_status(t_udpreceive *x)
outlet_anything( x->x_addrout, gensym("total"), 1, &output_atom);
}
+static void udpreceive_port(t_udpreceive *x, t_float portno)
+{
+ int result;
+ result = udpreceive_new_socket(x, x->addr, (int)portno);
+}
+
static void udpreceive_free(t_udpreceive *x)
{
if (x->x_connectsocket >= 0)
@@ -284,6 +311,8 @@ void udpreceive_setup(void)
sizeof(t_udpreceive), CLASS_DEFAULT, A_GIMME, 0);
class_addmethod(udpreceive_class, (t_method)udpreceive_status,
gensym("status"), 0);
+ class_addmethod(udpreceive_class, (t_method)udpreceive_port,
+ gensym("port"), A_DEFFLOAT, 0);
}
/* end udpreceive.c */