From beb2c8145358bcd7b4494a7b636e378aa2a1ea95 Mon Sep 17 00:00:00 2001 From: Martin Peach Date: Wed, 15 Sep 2010 18:52:38 +0000 Subject: Can set maximum packet length. Updated help patch. svn path=/trunk/externals/mrpeach/; revision=14147 --- slipenc/slipenc-help.pd | 220 ++++++++++++++++++++++++------------------------ slipenc/slipenc.c | 180 ++++++++++++++++++++++----------------- 2 files changed, 212 insertions(+), 188 deletions(-) diff --git a/slipenc/slipenc-help.pd b/slipenc/slipenc-help.pd index b2e4bf6..8ddc871 100644 --- a/slipenc/slipenc-help.pd +++ b/slipenc/slipenc-help.pd @@ -1,109 +1,111 @@ -#N canvas 167 357 1113 568 10; -#X obj -98 77 packOSC; -#X msg -98 52 /test 1 2 3 192 218 219 220 221 222; -#X text 193 533 Author: Martin Peach \, 2010/05/04; -#X floatatom -72 99 5 0 0 0 - - -; -#X text -100 -6 [slipenc]: Encode a list of bytes using Serial Line -Internet Protocol (SLIP); -#X text -39 228 Note that SLIP limits the maximum packet size to 1006 -; -#X obj -71 246 print encoded; -#X obj -71 163 print original; -#X obj 8 381 print decoded; -#X obj -98 141 t a a; -#X obj -98 224 t a a; -#X msg 124 60 /test/pi 3.14159; -#X msg 233 60 /test/pi \$1; -#X obj 233 40 expr 4*atan(1); -#X obj 233 22 bng 15 250 50 0 empty empty empty 17 7 0 10 -4034 -86277 --1; -#X obj -98 448 unpackOSC; -#X obj -98 364 t a a; -#X obj -98 469 routeOSC /test; -#X obj -92 492 print test; -#X obj -17 492 print other; -#X obj -98 515 routeOSC /pi; -#X floatatom -98 537 12 0 0 0 - - -; -#X text -38 191 Encodes a list of bytes for transmission through a -serial link using SLIP (RFC 1055). Useful for sending OSC through [comport]. -; -#X msg -52 124 192 192 192 192 192; -#X msg 821 312 192 192 192 192 192; -#X floatatom -35 313 5 0 0 0 - - -; -#X obj -104 322 cnv 15 60 30 empty empty empty 20 12 0 14 -4034 -66577 -0; -#X obj -98 329 slipdec; -#X obj -103 186 cnv 15 60 30 empty empty empty 20 12 0 14 -4034 -66577 -0; -#X obj -98 191 slipenc; -#X msg 27 174 1 2 3 4; -#X text 366 117 The motivation behind SLIP is the need to determine -the boundaries of a packet when it is received one byte at a time \, -as with a serial channel. Bytes are integers between 0 and 255; -#X text -100 22 [slipdec]: Decode a list of bytes using SLIP; -#X msg 79 124 1 2 3 4 5 6; -#X msg 160 124 1.1 2.22 3 4 5 6; -#X text -37 98 single floats will pass through as single packets; -#X msg 18 312 192 \, 1 \, 219 \, 220 \, 192; -#X msg 170 312 192 \, 1.33 \, 192; -#X msg -76 290 verbosity \$1; -#X obj -76 271 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 -1; -#X text 366 174 SLIP (RFC 1055) is a simple encoding that prefixes -each packet with 192 \, and replaces 192s inside the packet with 219 -followed by 220 Any 219 will be replaced with 219 and 221 The packet -ends with 192; -#X text 16 294 This should give 1 192; -#X text 168 294 Only bytes are permitted; -#X text 819 294 Null packets are invisible; -#X text 637 294 Unterminated list is invalid; -#X msg 640 312 1 219 5 6 7; -#X text 318 294 Missing 192 at start is OK \, bad escapes are invalid -; -#X msg 480 312 192 219 5 6 7 192; -#X msg 321 312 1 43 5 6 7 192; -#X text -42 329 Decodes a list of bytes from SLIP to raw. Useful for -receiving OSC via [comport].; -#X obj -71 383 list split 1; -#X obj -71 404 == 47; -#X obj -98 427 spigot; -#X text -35 403 select OSC messages based on the leading '/'; -#X obj -59 358 print valid; -#X connect 0 0 9 0; -#X connect 1 0 0 0; -#X connect 3 0 9 0; -#X connect 9 0 29 0; -#X connect 9 1 7 0; -#X connect 10 0 27 0; -#X connect 10 1 6 0; -#X connect 11 0 0 0; -#X connect 12 0 0 0; -#X connect 13 0 12 0; -#X connect 14 0 13 0; -#X connect 15 0 17 0; -#X connect 16 0 52 0; -#X connect 16 1 8 0; -#X connect 16 1 50 0; -#X connect 17 0 18 0; -#X connect 17 0 20 0; -#X connect 17 1 19 0; -#X connect 20 0 21 0; -#X connect 23 0 9 0; -#X connect 24 0 27 0; -#X connect 25 0 27 0; -#X connect 27 0 16 0; -#X connect 27 1 54 0; -#X connect 29 0 10 0; -#X connect 30 0 29 0; -#X connect 33 0 9 0; -#X connect 34 0 9 0; -#X connect 36 0 27 0; -#X connect 37 0 27 0; -#X connect 38 0 27 0; -#X connect 39 0 38 0; -#X connect 45 0 27 0; -#X connect 47 0 27 0; -#X connect 48 0 27 0; -#X connect 50 0 51 0; -#X connect 51 0 52 1; -#X connect 52 0 15 0; +#N canvas 351 316 1113 568 10; +#X obj -98 77 packOSC; +#X msg -98 52 /test 1 2 3 192 218 219 220 221 222; +#X floatatom -72 99 5 0 0 0 - - -; +#X text -100 -6 [slipenc]: Encode a list of bytes using Serial Line +Internet Protocol (SLIP); +#X obj -71 246 print encoded; +#X obj -71 163 print original; +#X obj 8 381 print decoded; +#X obj -98 141 t a a; +#X obj -98 224 t a a; +#X msg 124 60 /test/pi 3.14159; +#X msg 233 60 /test/pi \$1; +#X obj 233 40 expr 4*atan(1); +#X obj 233 22 bng 15 250 50 0 empty empty empty 17 7 0 10 -4034 -86277 +-1; +#X obj -98 448 unpackOSC; +#X obj -98 364 t a a; +#X obj -98 469 routeOSC /test; +#X obj -92 492 print test; +#X obj -17 492 print other; +#X obj -98 515 routeOSC /pi; +#X floatatom -98 537 12 0 0 0 - - -; +#X text -16 190 Encodes a list of bytes for transmission through a +serial link using SLIP (RFC 1055). Useful for sending OSC through [comport]. +; +#X msg -52 124 192 192 192 192 192; +#X msg 821 312 192 192 192 192 192; +#X floatatom -35 313 5 0 0 0 - - -; +#X obj -104 322 cnv 15 60 30 empty empty empty 20 12 0 14 -4034 -66577 +0; +#X obj -103 186 cnv 15 60 30 empty empty empty 20 12 0 14 -4034 -66577 +0; +#X msg 27 174 1 2 3 4; +#X text 340 77 The motivation behind SLIP is the need to determine +the boundaries of a packet when it is received one byte at a time \, +as with a serial channel. Bytes are integers between 0 and 255; +#X text -100 22 [slipdec]: Decode a list of bytes using SLIP; +#X msg 79 124 1 2 3 4 5 6; +#X msg 160 124 1.1 2.22 3 4 5 6; +#X text -37 98 single floats will pass through as single packets; +#X msg 18 312 192 \, 1 \, 219 \, 220 \, 192; +#X msg 170 312 192 \, 1.33 \, 192; +#X msg -76 290 verbosity \$1; +#X obj -76 271 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 +1; +#X text 340 134 SLIP (RFC 1055) is a simple encoding that prefixes +each packet with 192 \, and replaces 192s inside the packet with 219 +followed by 220 Any 219 will be replaced with 219 and 221 The packet +ends with 192; +#X text 16 294 This should give 1 192; +#X text 168 294 Only bytes are permitted; +#X text 819 294 Null packets are invisible; +#X text 637 294 Unterminated list is invalid; +#X msg 640 312 1 219 5 6 7; +#X text 318 294 Missing 192 at start is OK \, bad escapes are invalid +; +#X msg 480 312 192 219 5 6 7 192; +#X msg 321 312 1 43 5 6 7 192; +#X text -42 329 Decodes a list of bytes from SLIP to raw. Useful for +receiving OSC via [comport].; +#X obj -71 383 list split 1; +#X obj -71 404 == 47; +#X obj -98 427 spigot; +#X text -35 403 select OSC messages based on the leading '/'; +#X obj -59 358 print valid; +#X text 56 234 Note that the SLIP specification limits the maximum +packet size to 1006...; +#X text 177 529 Author: Martin Peach \, 2010/09/15; +#X obj -98 191 slipenc; +#X obj -98 329 slipdec; +#X text 57 262 ...but a float argument to slipdec or slipenc will set +another maximum packet size; +#X connect 0 0 7 0; +#X connect 1 0 0 0; +#X connect 2 0 7 0; +#X connect 7 0 53 0; +#X connect 7 1 5 0; +#X connect 8 0 54 0; +#X connect 8 1 4 0; +#X connect 9 0 0 0; +#X connect 10 0 0 0; +#X connect 11 0 10 0; +#X connect 12 0 11 0; +#X connect 13 0 15 0; +#X connect 14 0 48 0; +#X connect 14 1 6 0; +#X connect 14 1 46 0; +#X connect 15 0 16 0; +#X connect 15 0 18 0; +#X connect 15 1 17 0; +#X connect 18 0 19 0; +#X connect 21 0 7 0; +#X connect 22 0 54 0; +#X connect 23 0 54 0; +#X connect 26 0 53 0; +#X connect 29 0 7 0; +#X connect 30 0 7 0; +#X connect 32 0 54 0; +#X connect 33 0 54 0; +#X connect 34 0 54 0; +#X connect 35 0 34 0; +#X connect 41 0 54 0; +#X connect 43 0 54 0; +#X connect 44 0 54 0; +#X connect 46 0 47 0; +#X connect 47 0 48 1; +#X connect 48 0 13 0; +#X connect 53 0 8 0; +#X connect 54 0 14 0; +#X connect 54 1 50 0; diff --git a/slipenc/slipenc.c b/slipenc/slipenc.c index 814b5cd..74b1b29 100644 --- a/slipenc/slipenc.c +++ b/slipenc/slipenc.c @@ -1,38 +1,37 @@ -/* slipenc.c 20070711 Martin Peach */ -/**encode a list of bytes as SLIP / +/* slipenc.c 20100513 Martin Peach */ +/* encode a list of bytes as SLIP */ /* -/* -From RFC 1055: -PROTOCOL - - The SLIP protocol defines two special characters: SLIP_END and SLIP_ESC. SLIP_END is - octal 300 (decimal 192) and SLIP_ESC is octal 333 (decimal 219) not to be - confused with the ASCII ESCape character; for the purposes of this - discussion, SLIP_ESC will indicate the SLIP SLIP_ESC character. To send a - packet, a SLIP host simply starts sending the data in the packet. If - a data byte is the same code as SLIP_END character, a two byte sequence of - SLIP_ESC and octal 334 (decimal 220) is sent instead. If it the same as - an SLIP_ESC character, an two byte sequence of SLIP_ESC and octal 335 (decimal - 221) is sent instead. When the last byte in the packet has been - sent, an SLIP_END character is then transmitted. - - Phil Karn suggests a simple change to the algorithm, which is to - begin as well as end packets with an SLIP_END character. This will flush - any erroneous bytes which have been caused by line noise. In the - normal case, the receiver will simply see two back-to-back SLIP_END - characters, which will generate a bad IP packet. If the SLIP - implementation does not throw away the zero-length IP packet, the IP - implementation certainly will. If there was line noise, the data - received due to it will be discarded without affecting the following - packet. - - Because there is no 'standard' SLIP specification, there is no real - defined maximum packet size for SLIP. It is probably best to accept - the maximum packet size used by the Berkeley UNIX SLIP drivers: 1006 - bytes including the IP and transport protocol headers (not including - the framing characters). Therefore any new SLIP implementations - should be prepared to accept 1006 byte datagrams and should not send - more than 1006 bytes in a datagram. +* From RFC 1055: +* PROTOCOL +* +* The SLIP protocol defines two special characters: SLIP_END and SLIP_ESC. SLIP_END is +* octal 300 (decimal 192) and SLIP_ESC is octal 333 (decimal 219) not to be +* confused with the ASCII ESCape character; for the purposes of this +* discussion, SLIP_ESC will indicate the SLIP SLIP_ESC character. To send a +* packet, a SLIP host simply starts sending the data in the packet. If +* a data byte is the same code as SLIP_END character, a two byte sequence of +* SLIP_ESC and octal 334 (decimal 220) is sent instead. If it the same as +* an SLIP_ESC character, an two byte sequence of SLIP_ESC and octal 335 (decimal +* 221) is sent instead. When the last byte in the packet has been +* sent, an SLIP_END character is then transmitted. +* +* Phil Karn suggests a simple change to the algorithm, which is to +* begin as well as end packets with an SLIP_END character. This will flush +* any erroneous bytes which have been caused by line noise. In the +* normal case, the receiver will simply see two back-to-back SLIP_END +* characters, which will generate a bad IP packet. If the SLIP +* implementation does not throw away the zero-length IP packet, the IP +* implementation certainly will. If there was line noise, the data +* received due to it will be discarded without affecting the following +* packet. +* +* Because there is no 'standard' SLIP specification, there is no real +* defined maximum packet size for SLIP. It is probably best to accept +* the maximum packet size used by the Berkeley UNIX SLIP drivers: 1006 +* bytes including the IP and transport protocol headers (not including +* the framing characters). Therefore any new SLIP implementations +* should be prepared to accept 1006 byte datagrams and should not send +* more than 1006 bytes in a datagram. */ #include "m_pd.h" @@ -40,11 +39,11 @@ PROTOCOL /* -------------------------- slipenc -------------------------- */ #ifndef _SLIPCODES /* SLIP special character codes */ -#define SLIP_END 0300 /* indicates end of packet */ -#define SLIP_ESC 0333 /* indicates byte stuffing */ -#define SLIP_ESC_END 0334 /* SLIP_ESC SLIP_ESC_END means SLIP_END data byte */ -#define SLIP_ESC_ESC 0335 /* SLIP_ESC SLIP_ESC_ESC means SLIP_ESC data byte */ -#define MAX_SLIP 1006 /* maximum SLIP packet size */ +#define SLIP_END 0300 /* indicates end of packet */ +#define SLIP_ESC 0333 /* indicates byte stuffing */ +#define SLIP_ESC_END 0334 /* SLIP_ESC SLIP_ESC_END means SLIP_END data byte */ +#define SLIP_ESC_ESC 0335 /* SLIP_ESC SLIP_ESC_ESC means SLIP_ESC data byte */ +#define MAX_SLIP 1006 /* maximum SLIP packet size */ #define _SLIPCODES #endif // _SLIPCODES @@ -56,6 +55,7 @@ typedef struct _slipenc t_outlet *x_slipenc_out; t_atom *x_slip_buf; t_int x_slip_length; + t_int x_slip_max_length; } t_slipenc; static void *slipenc_new(t_symbol *s, int argc, t_atom *argv); @@ -65,17 +65,35 @@ void slipenc_setup(void); static void *slipenc_new(t_symbol *s, int argc, t_atom *argv) { - int i; + int i, max_len; t_slipenc *x = (t_slipenc *)pd_new(slipenc_class); - x->x_slip_buf = (t_atom *)getbytes(sizeof(t_atom)*MAX_SLIP); + if (x == NULL) return x; + + x->x_slip_max_length = MAX_SLIP; // default unless float argument given + for (i = 0; i < argc; ++i) + { + if (argv[i].a_type == A_FLOAT) + { + max_len = atom_getfloat(&argv[i]); + if (max_len > 3) + { + x->x_slip_max_length = max_len; + post("slipenc: maximum packet length is %d", x->x_slip_max_length); + } + else + post("slipenc: maximum packet length must be greater than 3, using %d", x->x_slip_max_length); + break; + } + } + x->x_slip_buf = (t_atom *)getbytes(sizeof(t_atom)*x->x_slip_max_length); if(x->x_slip_buf == NULL) { - error("slipenc: unable to allocate %lu bytes for x_slip_buf", (long)sizeof(t_atom)*MAX_SLIP); + error("slipenc: unable to allocate %lu bytes for x_slip_buf", (long)sizeof(t_atom)*x->x_slip_max_length); return NULL; } /* Initialize all the slip buf atoms to float type */ - for (i = 0; i < MAX_SLIP; ++i) x->x_slip_buf[i].a_type = A_FLOAT; + for (i = 0; i < x->x_slip_max_length; ++i) x->x_slip_buf[i].a_type = A_FLOAT; x->x_slipenc_out = outlet_new(&x->x_obj, &s_list); return (x); } @@ -86,51 +104,55 @@ static void slipenc_list(t_slipenc *x, t_symbol *s, int ac, t_atom *av) float f; int i, c; - i = x->x_slip_length = 0; - /* send an initial SLIP_END character to flush out any data that may */ - /* have accumulated in the receiver due to line noise */ - x->x_slip_buf[x->x_slip_length++].a_w.w_float = SLIP_END; - + i = 0; /* for each byte in the packet, send the appropriate character sequence */ - while((i < ac) && (x->x_slip_length < (MAX_SLIP-1))) + while (i < ac) { - /* check each atom for byteness */ - f = atom_getfloat(&av[i++]); - c = (((int)f) & 0x0FF); - if (c != f) - { - /* abort, bad input character */ - pd_error (x, "slipenc: input %f out of range [0..255]", f); - return; - } - if(SLIP_END == c) - { - /* If it's the same code as a SLIP_END character, replace it with a */ - /* special two-character code so as not to make the receiver think we sent SLIP_END */ - x->x_slip_buf[x->x_slip_length++].a_w.w_float = SLIP_ESC; - x->x_slip_buf[x->x_slip_length++].a_w.w_float = SLIP_ESC_END; - } - else if (SLIP_ESC == c) - { - /* If it's the same code as a SLIP_ESC character, replace it with a special two-character code */ - /* so as not to make the receiver think we sent SLIP_ESC */ - x->x_slip_buf[x->x_slip_length++].a_w.w_float = SLIP_ESC; - x->x_slip_buf[x->x_slip_length++].a_w.w_float = SLIP_ESC_ESC; - } - else + x->x_slip_length = 0; + /* send an initial SLIP_END character to flush out any data that may */ + /* have accumulated in the receiver due to line noise */ + x->x_slip_buf[x->x_slip_length++].a_w.w_float = SLIP_END; + + while((i < ac)&&(x->x_slip_length < (x->x_slip_max_length-2))) { - /* Otherwise, pass the character */ - x->x_slip_buf[x->x_slip_length++].a_w.w_float = c; + /* check each atom for byteness */ + f = atom_getfloat(&av[i++]); + c = (((int)f) & 0x0FF); + if (c != f) + { + /* abort, bad input character */ + pd_error (x, "slipenc: input %f out of range [0..255]", f); + return; + } + if(SLIP_END == c) + { + /* If it's the same code as a SLIP_END character, replace it with a */ + /* special two-character code so as not to make the receiver think we sent SLIP_END */ + x->x_slip_buf[x->x_slip_length++].a_w.w_float = SLIP_ESC; + x->x_slip_buf[x->x_slip_length++].a_w.w_float = SLIP_ESC_END; + } + else if (SLIP_ESC == c) + { + /* If it's the same code as a SLIP_ESC character, replace it with a special two-character code */ + /* so as not to make the receiver think we sent SLIP_ESC */ + x->x_slip_buf[x->x_slip_length++].a_w.w_float = SLIP_ESC; + x->x_slip_buf[x->x_slip_length++].a_w.w_float = SLIP_ESC_ESC; + } + else + { + /* Otherwise, pass the character */ + x->x_slip_buf[x->x_slip_length++].a_w.w_float = c; + } } + /* Add the SLIP_END code to tell the receiver that the packet is complete */ + x->x_slip_buf[x->x_slip_length++].a_w.w_float = SLIP_END; + outlet_list(x->x_slipenc_out, &s_list, x->x_slip_length, x->x_slip_buf); } - /* Add the SLIP_END code to tell the receiver that the packet is complete */ - x->x_slip_buf[x->x_slip_length++].a_w.w_float = SLIP_END; - outlet_list(x->x_slipenc_out, &s_list, x->x_slip_length, x->x_slip_buf); } static void slipenc_free(t_slipenc *x) { - if (x->x_slip_buf != NULL) freebytes((void *)x->x_slip_buf, sizeof(t_atom)*MAX_SLIP); + if (x->x_slip_buf != NULL) freebytes((void *)x->x_slip_buf, sizeof(t_atom)*x->x_slip_max_length); } void slipenc_setup(void) -- cgit v1.2.1