diff options
Diffstat (limited to 'send+dump')
-rw-r--r-- | send+dump/Makefile.in | 30 | ||||
-rw-r--r-- | send+dump/dumpOSC.c | 723 | ||||
-rw-r--r-- | send+dump/dumpUDP.c | 190 | ||||
-rw-r--r-- | send+dump/htmsocket.c | 313 | ||||
-rw-r--r-- | send+dump/htmsocket.h | 48 | ||||
-rw-r--r-- | send+dump/sendOSC.c | 602 |
6 files changed, 0 insertions, 1906 deletions
diff --git a/send+dump/Makefile.in b/send+dump/Makefile.in deleted file mode 100644 index 8bf6b69..0000000 --- a/send+dump/Makefile.in +++ /dev/null @@ -1,30 +0,0 @@ -LIBS = @LIBS@ -LIBOSCDIR = ../libOSC -LIBOSC = ${LIBOSCDIR}/libOSC.a - -# strange bug requires this... -CFLAGS= @CFLAGS@ @INCLUDES@ -# INCLUDES= @INCLUDES@ - -DUMPOBJS=dumpOSC.o - - -both: sendOSC dumpOSC - -sendOSC: sendOSC.o htmsocket.o ${LIBOSC} - ${CC} ${CFLAGS} $(INCLUDES) -o sendOSC sendOSC.o htmsocket.o $(LIBS) ${LIBOSC} - -dumpOSC: ${DUMPOBJS} - ${CC} ${CFLAGS} $(INCLUDES) -o $@ ${DUMPOBJS} $(LIBS) - -dumpUDP: dumpUDP.o - ${CC} ${CFLAGS} $(INCLUDES) -o dumpUDP dumpUDP.o $(LIBS) - -${LIBOSC}: - echo "You need to go to " ${LIBOSCDIR} " and do a make." - (cd ../libOSC ; make) - -clean: - rm -f sendOSC dumpOSC *.o - - diff --git a/send+dump/dumpOSC.c b/send+dump/dumpOSC.c deleted file mode 100644 index 7603fca..0000000 --- a/send+dump/dumpOSC.c +++ /dev/null @@ -1,723 +0,0 @@ -/* -Written by Matt Wright and Adrian Freed, The Center for New Music and -Audio Technologies, University of California, Berkeley. Copyright (c) -1992,93,94,95,96,97,98,99,2000,01,02,03,04 The Regents of the University of -California (Regents). - -Permission to use, copy, modify, distribute, and distribute modified versions -of this software and its documentation without fee and without a signed -licensing agreement, is hereby granted, provided that the above copyright -notice, this paragraph and the following two paragraphs appear in all copies, -modifications, and distributions. - -IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, -SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING -OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS -BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED -HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE -MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - - -The OSC webpage is http://cnmat.cnmat.berkeley.edu/OpenSoundControl -*/ - - - /* - - dumpOSC.c - server that displays OpenSoundControl messages sent to it - for debugging client udp and UNIX protocol - - by Matt Wright, 6/3/97 - modified from dumpSC.c, by Matt Wright and Adrian Freed - - version 0.2: Added "-silent" option a.k.a. "-quiet" - - version 0.3: Incorporated patches from Nicola Bernardini to make - things Linux-friendly. Also added ntohl() in the right places - to support little-endian architectures. - - CNMAT OSX compile changes not included (20040820) jdl - - compile: - cc -o dumpOSC dumpOSC.c - - to-do: - - More robustness in saying exactly what's wrong with ill-formed - messages. (If they don't make sense, show exactly what was - received.) - - Time-based features: print time-received for each packet - - Clean up to separate OSC parsing code from socket/select stuff - -*/ - - -#ifdef UNIX -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#include <unistd.h> -#include <fcntl.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <netinet/in.h> -#include <rpc/rpc.h> -#include <sys/socket.h> -#include <sys/un.h> -#include <sys/times.h> -#include <sys/param.h> -#include <sys/time.h> -#include <sys/ioctl.h> -#include <ctype.h> -#include <arpa/inet.h> -#include <netdb.h> -#include <pwd.h> -#include <signal.h> -#include <grp.h> -#include <sys/file.h> -#ifndef __APPLE__ - #include <sys/prctl.h> - #include <bits/sigset.h> -#endif - -#ifdef NEED_SCHEDCTL_AND_LOCK -#include <sys/schedctl.h> -#include <sys/lock.h> -#endif - - -char *htm_error_string; -typedef int Boolean; -typedef void *OBJ; - -typedef struct ClientAddressStruct { - struct sockaddr_in cl_addr; - int clilen; - int sockfd; -} *ClientAddr; - -Boolean ShowBytes = FALSE; -Boolean Silent = FALSE; - -/* Declarations */ -static int unixinitudp(int chan); -static int initudp(int chan); -static void closeudp(int sockfd); -Boolean ClientReply(int packetsize, void *packet, int socketfd, - void *clientaddresspointer, int clientaddressbufferlength); -void sgi_CleanExit(void); -Boolean sgi_HaveToQuit(void); -int RegisterPollingDevice(int fd, void (*callbackfunction)(int , void *), void *dummy); -#ifndef __APPLE__ -static void catch_sigint(); -#endif -static int Synthmessage(char *m, int n, void *clientdesc, int clientdesclength, int fd) ; -void ParseOSCPacket(char *buf, int n, ClientAddr returnAddr); -static void Smessage(char *address, void *v, int n, ClientAddr returnAddr); -static void PrintTypeTaggedArgs(void *v, int n); -static void PrintHeuristicallyTypeGuessedArgs(void *v, int n, int skipComma); -char *DataAfterAlignedString(char *string, char *boundary) ; -Boolean IsNiceString(char *string, char *boundary) ; -void complain(char *s, ...); - - -#define UNIXDG_PATH "/tmp/htm" -#define UNIXDG_TMP "/tmp/htm.XXXXXX" -static int unixinitudp(int chan) -{ - struct sockaddr_un serv_addr; - int sockfd; - - if((sockfd = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0) - return sockfd; - - bzero((char *)&serv_addr, sizeof(serv_addr)); - serv_addr.sun_family = AF_UNIX; - strcpy(serv_addr.sun_path, UNIXDG_PATH); - sprintf(serv_addr.sun_path+strlen(serv_addr.sun_path), "%d", chan); - unlink(serv_addr.sun_path); - if(bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr.sun_family)+strlen(serv_addr.sun_path)) < 0) - { - perror("unable to bind\n"); - return -1; - } - - fcntl(sockfd, F_SETFL, FNDELAY); - return sockfd; -} - -static int initudp(int chan) -{ - struct sockaddr_in serv_addr; - int sockfd; - - if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) - return sockfd; - bzero((char *)&serv_addr, sizeof(serv_addr)); - serv_addr.sin_family = AF_INET; - serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); - serv_addr.sin_port = htons(chan); - - if(bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) - { - perror("unable to bind\n"); - return -1; - } - - fcntl(sockfd, F_SETFL, FNDELAY); - return sockfd; -} - -static void closeudp(int sockfd) { - close(sockfd); -} - -static Boolean catchupflag=FALSE; -Boolean ClientReply(int packetsize, void *packet, int socketfd, - void *clientaddresspointer, int clientaddressbufferlength) -{ - if(!clientaddresspointer) return FALSE; - catchupflag= TRUE; - return packetsize==sendto(socketfd, packet, packetsize, 0, clientaddresspointer, clientaddressbufferlength); -} - -static Boolean exitflag= FALSE; -void sgi_CleanExit(void) { - exitflag = TRUE; -} - -Boolean sgi_HaveToQuit(void) { - return exitflag; -} - - -/* file descriptor poll table */ -static int npolldevs =0; -typedef struct polldev -{ - int fd; - void (*callbackfunction)(int , void *); - void *dummy; -} polldev; -#define TABMAX 8 -static polldev polldevs[TABMAX]; - - -/* Register a device (referred to by a file descriptor that the caller - should have already successfully obtained from a system call) to be - polled as real-time constraints allowed. - - When a select(2) call indicates activity on the file descriptor, the - callback function is called with the file descripter as first - argument and the given dummy argument (presumably a pointer to the - instance variables associated with the device). -*/ -int RegisterPollingDevice(int fd, void (*callbackfunction)(int , void *), void *dummy) -{ - if(npolldevs<TABMAX) - { - polldevs[npolldevs].fd = fd; - polldevs[npolldevs].callbackfunction = callbackfunction; - polldevs[npolldevs].dummy = dummy; - } - else return -1; - return npolldevs++; -} - -static int caught_sigint; - -#ifndef __APPLE__ -static void catch_sigint() { - caught_sigint = 1; -} -#endif -static int sockfd, usockfd; - - - -static int Synthmessage(char *m, int n, void *clientdesc, int clientdesclength, int fd) { - struct ClientAddressStruct ras; - ClientAddr ra = &ras; - - catchupflag= FALSE; - - ras.cl_addr = *((struct sockaddr_in *) clientdesc); - ras.clilen = clientdesclength; - ras.sockfd = fd; - - if (ShowBytes) { - int i; - printf("%d byte message:\n", n); - for (i = 0; i < n; ++i) { - printf(" %x (%c)\t", m[i], m[i]); - if (i%4 == 3) printf("\n"); - } - printf("\n"); - } - - ParseOSCPacket(m, n, ra); - return catchupflag; -} - -void PrintClientAddr(ClientAddr CA) { - unsigned long addr = CA->cl_addr.sin_addr.s_addr; - printf("Client address %p:\n", CA); - printf(" clilen %d, sockfd %d\n", CA->clilen, CA->sockfd); - printf(" sin_family %d, sin_port %d\n", CA->cl_addr.sin_family, - CA->cl_addr.sin_port); - printf(" address: (%x) %s\n", addr, inet_ntoa(CA->cl_addr.sin_addr)); - - printf(" sin_zero = \"%c%c%c%c%c%c%c%c\"\n", - CA->cl_addr.sin_zero[0], - CA->cl_addr.sin_zero[1], - CA->cl_addr.sin_zero[2], - CA->cl_addr.sin_zero[3], - CA->cl_addr.sin_zero[4], - CA->cl_addr.sin_zero[5], - CA->cl_addr.sin_zero[6], - CA->cl_addr.sin_zero[7]); - - printf("\n"); -} - - -void ParseOSCPacket(char *buf, int n, ClientAddr returnAddr) { - int size, messageLen, i; - char *messageName; - char *args; - -#ifdef PRINTADDRS - PrintClientAddr(returnAddr); -#endif - - - if ((n%4) != 0) { - complain("SynthControl packet size (%d) not a multiple of 4 bytes: dropping", - n); - return; - } - - if ((n >= 8) && (strncmp(buf, "#bundle", 8) == 0)) { - /* This is a bundle message. */ - - if (n < 16) { - complain("Bundle message too small (%d bytes) for time tag", n); - return; - } - - /* Print the time tag */ - printf("[ %lx%08lx\n", ntohl(*((unsigned long *)(buf+8))), - ntohl(*((unsigned long *)(buf+12)))); - /* Note: if we wanted to actually use the time tag as a little-endian - 64-bit int, we'd have to word-swap the two 32-bit halves of it */ - - i = 16; /* Skip "#group\0" and time tag */ - while(i<n) { - size = ntohl(*((int *) (buf + i))); - if ((size % 4) != 0) { - complain("Bad size count %d in bundle (not a multiple of 4)", size); - return; - } - if ((size + i + 4) > n) { - complain("Bad size count %d in bundle (only %d bytes left in entire bundle)", - size, n-i-4); - return; - } - - /* Recursively handle element of bundle */ - ParseOSCPacket(buf+i+4, size, returnAddr); - i += 4 + size; - } - if (i != n) { - complain("This can't happen"); - } - printf("]\n"); - } else { - /* This is not a bundle message */ - - messageName = buf; - args = DataAfterAlignedString(messageName, buf+n); - if (args == 0) { - complain("Bad message name string: %s\nDropping entire message.\n", - htm_error_string); - return; - } - messageLen = args-messageName; - Smessage(messageName, (void *)args, n-messageLen, returnAddr); - } -} - -#define SMALLEST_POSITIVE_FLOAT 0.000001f - -static void Smessage(char *address, void *v, int n, ClientAddr returnAddr) { - char *chars = v; - - printf("%s ", address); - - if (n != 0) { - if (chars[0] == ',') { - if (chars[1] != ',') { - /* This message begins with a type-tag string */ - PrintTypeTaggedArgs(v, n); - } else { - /* Double comma means an escaped real comma, not a type string */ - PrintHeuristicallyTypeGuessedArgs(v, n, 1); - } - } else { - PrintHeuristicallyTypeGuessedArgs(v, n, 0); - } - } - - printf("\n"); - fflush(stdout); /* Added for Sami 5/21/98 */ -} - -static void PrintTypeTaggedArgs(void *v, int n) { - char *typeTags, *thisType; - char *p; - - typeTags = v; - - if (!IsNiceString(typeTags, typeTags+n)) { - /* No null-termination, so maybe it wasn't a type tag - string after all */ - PrintHeuristicallyTypeGuessedArgs(v, n, 0); - return; - } - - p = DataAfterAlignedString(typeTags, typeTags+n); - - - for (thisType = typeTags + 1; *thisType != 0; ++thisType) { - switch (*thisType) { - case 'i': case 'r': case 'm': case 'c': - printf("%d ", ntohl(*((int *) p))); - p += 4; - break; - - case 'f': { - int i = ntohl(*((int *) p)); - float *floatp = ((float *) (&i)); - printf("%f ", *floatp); - p += 4; - } - break; - - case 'h': case 't': - printf("[A 64-bit int] "); - p += 8; - break; - - case 'd': - printf("[A 64-bit float] "); - p += 8; - break; - - case 's': case 'S': - if (!IsNiceString(p, typeTags+n)) { - printf("Type tag said this arg is a string but it's not!\n"); - return; - } else { - printf("\"%s\" ", p); - p = DataAfterAlignedString(p, typeTags+n); - } - break; - - case 'T': printf("[True] "); break; - case 'F': printf("[False] "); break; - case 'N': printf("[Nil]"); break; - case 'I': printf("[Infinitum]"); break; - - default: - printf("[Unrecognized type tag %c]", *thisType); - return; - } - } -} - -static void PrintHeuristicallyTypeGuessedArgs(void *v, int n, int skipComma) { - int i, thisi; - float thisf; - int *ints; - char *chars; - char *string, *nextString; - - - /* Go through the arguments 32 bits at a time */ - ints = v; - chars = v; - - for (i = 0; i<n/4; ) { - string = &chars[i*4]; - thisi = ntohl(ints[i]); - /* Reinterpret the (potentially byte-reversed) thisi as a float */ - thisf = *(((float *) (&thisi))); - - if (thisi >= -1000 && thisi <= 1000000) { - printf("%d ", thisi); - i++; - } else if (thisf >= -1000.f && thisf <= 1000000.f && - (thisf <=0.0f || thisf >= SMALLEST_POSITIVE_FLOAT)) { - printf("%f ", thisf); - i++; - } else if (IsNiceString(string, chars+n)) { - nextString = DataAfterAlignedString(string, chars+n); - printf("\"%s\" ", (i == 0 && skipComma) ? string +1 : string); - i += (nextString-string) / 4; - } else { - printf("0x%x ", ints[i]); - i++; - } - } -} - - -#define STRING_ALIGN_PAD 4 - -char *DataAfterAlignedString(char *string, char *boundary) -{ - /* The argument is a block of data beginning with a string. The - string has (presumably) been padded with extra null characters - so that the overall length is a multiple of STRING_ALIGN_PAD - bytes. Return a pointer to the next byte after the null - byte(s). The boundary argument points to the character after - the last valid character in the buffer---if the string hasn't - ended by there, something's wrong. - - If the data looks wrong, return 0, and set htm_error_string */ - - int i; - - if ((boundary - string) %4 != 0) { - fprintf(stderr, "Internal error: DataAfterAlignedString: bad boundary\n"); - return 0; - } - - for (i = 0; string[i] != '\0'; i++) { - if (string + i >= boundary) { - htm_error_string = "DataAfterAlignedString: Unreasonably long string"; - return 0; - } - } - - /* Now string[i] is the first null character */ - i++; - - for (; (i % STRING_ALIGN_PAD) != 0; i++) { - if (string + i >= boundary) { - htm_error_string = "DataAfterAlignedString: Unreasonably long string"; - return 0; - } - if (string[i] != '\0') { - htm_error_string = "DataAfterAlignedString: Incorrectly padded string."; - return 0; - } - } - - return string+i; -} - -Boolean IsNiceString(char *string, char *boundary) -{ - /* Arguments same as DataAfterAlignedString(). Is the given "string" - really a string? I.e., is it a sequence of isprint() characters - terminated with 1-4 null characters to align on a 4-byte boundary? */ - - int i; - - if ((boundary - string) %4 != 0) { - fprintf(stderr, "Internal error: IsNiceString: bad boundary\n"); - return 0; - } - - for (i = 0; string[i] != '\0'; i++) { - if (!isprint(string[i])) return FALSE; - if (string + i >= boundary) return FALSE; - } - - /* If we made it this far, it's a null-terminated sequence of printing characters - in the given boundary. Now we just make sure it's null padded... */ - - /* Now string[i] is the first null character */ - i++; - for (; (i % STRING_ALIGN_PAD) != 0; i++) { - if (string[i] != '\0') return FALSE; - } - - return TRUE; -} - - - - - - - -#define MAXMESG 32768 -static char mbuf[MAXMESG]; - -int main(int argc, char **argv) { - int udp_port; /* port to receive parameter updates from */ - - struct sockaddr_in cl_addr; - int clilen,maxclilen=sizeof(cl_addr); - struct sockaddr_un ucl_addr; - int uclilen,umaxclilen=sizeof(ucl_addr); - int i,n; - - - clilen = maxclilen; - uclilen = umaxclilen; - - udp_port = -1; - for (i=1; i < argc; ++i) { - if (strcmp(argv[i], "-showbytes") == 0) { - ShowBytes = TRUE; - } else if (strcmp(argv[i], "-silent") == 0 || - strcmp(argv[i], "-quiet") == 0) { - Silent = TRUE; - } else if (udp_port != -1) { - goto usageError; - } else { - udp_port = atoi(argv[i]); - if (udp_port == 0) { - goto usageError; - } - } - } - - if (udp_port == -1) { - usageError: - fprintf(stderr, "Usage\n\tdumpOSC portno [-showbytes] [-quiet]\n\t(responds to udp and UNIX packets on that port no)\n"); - exit(1); - } - - - n = recvfrom(0, mbuf, MAXMESG, 0, &cl_addr, &clilen); - if(n>0) - { - sockfd = 0; - udp_port = -1; - Synthmessage(mbuf, n, &cl_addr, clilen,sockfd) ; - } - else - { sockfd=initudp(udp_port); - usockfd=unixinitudp(udp_port); - } - - if (!Silent) { - printf("dumpOSC version 0.2 (6/18/97 Matt Wright). Unix/UDP Port %d \n", udp_port); - printf("Copyright (c) 1992,1996,1997 Regents of the University of California.\n"); - } - if(sockfd>=0 && usockfd>=0) - { - fd_set read_fds, write_fds; - int nfds; -#define max(a,b) (((a) > (b)) ? (a) : (b)) - nfds = max(sockfd, usockfd)+ 1; - { - int j; - for(j=0;j<npolldevs;++j) - if(polldevs[j].fd>=nfds) - { - nfds = polldevs[j].fd+1; -/* -printf("polldev %d\n", polldevs[j].fd); -*/ - } - } -/* - printf("nfds %d\n", nfds); -*/ - caught_sigint = 0; -#ifndef __APPLE__ - sigset(SIGINT, catch_sigint); /* set sig handler */ -#endif - while(!caught_sigint) - { - - int r; - - back: - - FD_ZERO(&read_fds); /* clear read_fds */ - FD_ZERO(&write_fds); /* clear write_fds */ - FD_SET(sockfd, &read_fds); - FD_SET(usockfd, &read_fds); - { - int j; - - for(j=0;j<npolldevs;++j) - FD_SET(polldevs[j].fd, &read_fds); - } - - r = select(nfds, &read_fds, &write_fds, (fd_set *)0, - (struct timeval *)0); - if (r < 0) /* select reported an error */ - goto out; - { - int j; - - for(j=0;j<npolldevs;++j) - if(FD_ISSET(polldevs[j].fd, &read_fds)) - (*(polldevs[j].callbackfunction))(polldevs[j].fd,polldevs[j].dummy ); - } - if(FD_ISSET(sockfd, &read_fds)) - { - clilen = maxclilen; - while( (n = recvfrom(sockfd, mbuf, MAXMESG, 0, &cl_addr, &clilen)) >0) - { - int r; - /* printf("received UDP packet of length %d\n", n); */ - r = Synthmessage(mbuf, n, &cl_addr, clilen, sockfd) ; - - if( sgi_HaveToQuit()) goto out; - if(r>0) goto back; - clilen = maxclilen; - } - } - if(FD_ISSET(usockfd, &read_fds)) - { - uclilen = umaxclilen; - while( (n = recvfrom(usockfd, mbuf, MAXMESG, 0, &ucl_addr, &uclilen)) >0) - { - int r; - /* printf("received UNIX packet of length %d\n", n); */ - - r=Synthmessage(mbuf, n, &ucl_addr, uclilen,usockfd) ; - - if( sgi_HaveToQuit()) goto out; - if(r>0) goto back; - uclilen = umaxclilen; - } - } - } /* End of while(!caught_sigint) */ - closeudp(sockfd); - -out: ; - } - else - perror("initudp"); - - return 0; -} - - -#include <stdarg.h> -void complain(char *s, ...) { - va_list ap; - va_start(ap, s); - fprintf(stderr, "*** ERROR: "); - vfprintf(stderr, s, ap); - fprintf(stderr, "\n"); - va_end(ap); -} - -#endif /* __sgi or LINUX */ diff --git a/send+dump/dumpUDP.c b/send+dump/dumpUDP.c deleted file mode 100644 index 494a6e3..0000000 --- a/send+dump/dumpUDP.c +++ /dev/null @@ -1,190 +0,0 @@ -/* -Written by Matt Wright, The Center for New Music and -Audio Technologies, University of California, Berkeley. Copyright (c) -1998,99,2000,01,02,03,04 The Regents of the University of -California (Regents). - -Permission to use, copy, modify, distribute, and distribute modified versions -of this software and its documentation without fee and without a signed -licensing agreement, is hereby granted, provided that the above copyright -notice, this paragraph and the following two paragraphs appear in all copies, -modifications, and distributions. - -IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, -SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING -OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS -BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED -HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE -MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - - -The OSC webpage is http://cnmat.cnmat.berkeley.edu/OpenSoundControl - -dumpUDP.c: smallest UDP receiving application -by Matt Wright, 9/9/98 - -*/ - - -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#include <unistd.h> -#include <fcntl.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <netinet/in.h> -#include <rpc/rpc.h> -#include <sys/socket.h> -#include <sys/un.h> -#include <sys/times.h> -#include <sys/param.h> -#include <sys/time.h> -#include <sys/ioctl.h> -#include <ctype.h> -#include <arpa/inet.h> -#include <netdb.h> -#include <pwd.h> -#include <signal.h> -#include <grp.h> -#include <sys/file.h> -#include <bstring.h> -#include <sys/prctl.h> -#include <sys/schedctl.h> -#include <sys/lock.h> - - -typedef struct ClientAddressStruct { - struct sockaddr_in cl_addr; - int clilen; - int sockfd; -} *ClientAddr; - -void PrintClientAddr(ClientAddr CA) { - unsigned long addr = CA->cl_addr.sin_addr.s_addr; - printf("Client address %p:\n", CA); - printf(" clilen %d, sockfd %d\n", CA->clilen, CA->sockfd); - printf(" sin_family %d, sin_port %d\n", CA->cl_addr.sin_family, - CA->cl_addr.sin_port); - printf(" address: (%x) %s\n", addr, inet_ntoa(CA->cl_addr.sin_addr)); - - printf(" sin_zero = \"%c%c%c%c%c%c%c%c\"\n", - CA->cl_addr.sin_zero[0], - CA->cl_addr.sin_zero[1], - CA->cl_addr.sin_zero[2], - CA->cl_addr.sin_zero[3], - CA->cl_addr.sin_zero[4], - CA->cl_addr.sin_zero[5], - CA->cl_addr.sin_zero[6], - CA->cl_addr.sin_zero[7]); - - printf("\n"); -} - - -static int initudp(int port) { - struct sockaddr_in serv_addr; - int n, sockfd; - - if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) - return sockfd; - bzero((char *)&serv_addr, sizeof(serv_addr)); - serv_addr.sin_family = AF_INET; - serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); - serv_addr.sin_port = htons(port); - - if(bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) - { - perror("unable to bind\n"); - return -1; - } - - fcntl(sockfd, F_SETFL, FNDELAY); - return sockfd; -} - - -static void closeudp(int sockfd) { - close(sockfd); -} - - -static int time_to_quit; - -static void catch_sigint() { - time_to_quit = 1; -} - -void GotAPacket(char *buf, int n, ClientAddr returnAddr) { - printf("received UDP packet of length %d\n", n); - PrintClientAddr(returnAddr); -} - -#define MAXMESG 32768 -static char mbuf[MAXMESG]; - -void ReceivePacket(int sockfd) { - struct ClientAddressStruct returnAddress; - int maxclilen=sizeof(returnAddress.cl_addr); - int n; - - returnAddress.clilen = maxclilen; - while( (n = recvfrom(sockfd, mbuf, MAXMESG, 0, &(returnAddress.cl_addr), - &(returnAddress.clilen))) >0) { - GotAPacket(mbuf, n, &returnAddress); - - if (time_to_quit) return; - returnAddress.clilen = maxclilen; - } -} - -void main(int argc, char **argv) { - int udp_port; /* port to receive parameter updates from */ - int sockfd; - int i; - - fd_set read_fds, write_fds; - int nfds; - - udp_port = 7000; - - sockfd=initudp(udp_port); - - if(sockfd<0) { - perror("initudp"); - return; - } - - nfds = sockfd + 1; - - time_to_quit = 0; - sigset(SIGINT, catch_sigint); /* set sig handler */ - - while(!time_to_quit) - { - - int c,r; - - back: - - FD_ZERO(&read_fds); /* clear read_fds */ - FD_ZERO(&write_fds); /* clear write_fds */ - FD_SET(sockfd, &read_fds); - - - r = select(nfds, &read_fds, &write_fds, (fd_set *)0, - (struct timeval *)0); - if (r < 0) /* select reported an error */ - goto out; - - if(FD_ISSET(sockfd, &read_fds)) { - ReceivePacket(sockfd); - } - - } /* End of while(!time_to_quit) */ -out: ; -} diff --git a/send+dump/htmsocket.c b/send+dump/htmsocket.c deleted file mode 100644 index 1cc17cd..0000000 --- a/send+dump/htmsocket.c +++ /dev/null @@ -1,313 +0,0 @@ -/*
-Written by Adrian Freed, The Center for New Music and Audio Technologies,
-University of California, Berkeley. Copyright (c) 1992,93,94,95,96,97,98,99,2000,01,02,03,04
-The Regents of the University of California (Regents).
-
-Permission to use, copy, modify, distribute, and distribute modified versions
-of this software and its documentation without fee and without a signed
-licensing agreement, is hereby granted, provided that the above copyright
-notice, this paragraph and the following two paragraphs appear in all copies,
-modifications, and distributions.
-
-IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
-SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING
-OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS
-BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
-THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED
-HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE
-MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
-
-
-The OSC webpage is http://cnmat.cnmat.berkeley.edu/OpenSoundControl
-*/
-
- /* htmsocket.c
-
- Adrian Freed
- send parameters to htm servers by udp or UNIX protocol
-
- Modified 6/6/96 by Matt Wright to understand symbolic host names
- in addition to X.X.X.X addresses.
-
- pd: branched jdl
- -- win additions raf 2002
- -- enabled broadcast jdl 2003
- */
-
-#if HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#ifdef __APPLE__
- #include <string.h>
-#endif
-
-#ifdef _WIN32
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <winsock2.h>
- #include <ctype.h>
- #include <signal.h>
- #include <sys/types.h>
- #include <stdlib.h>
- #include "OSC-common.h"
- #include <stdio.h>
-#else
- #include <stdio.h>
- #include <unistd.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <netinet/in.h>
-
-// #include <rpc/rpc.h>
- #include <sys/socket.h>
- #include <sys/un.h>
- #include <sys/times.h>
- #include <sys/param.h>
- #include <sys/time.h>
- #include <sys/ioctl.h>
-
- #include <ctype.h>
- #include <arpa/inet.h>
- #include <netdb.h>
- #include <pwd.h>
- #include <signal.h>
- #include <grp.h>
- #include <sys/fcntl.h>
- #include <sys/file.h>
- #include <sys/time.h>
- #include <sys/types.h>
-// #include <sys/prctl.h>
-
- #include <stdlib.h>
-#endif
-
-#define UNIXDG_PATH "/tmp/htm"
-#define UNIXDG_TMP "/tmp/htm.XXXXXX"
-#include "htmsocket.h"
-typedef struct
-{
- float srate;
-
- struct sockaddr_in serv_addr; /* udp socket */
- #ifndef WIN32
- struct sockaddr_un userv_addr; /* UNIX socket */
- #endif
- int sockfd; /* socket file descriptor */
- int index, len,uservlen;
- void *addr;
- int id;
-} desc;
-
-/* 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)
-{
- struct sockaddr_in cl_addr;
- #ifndef WIN32
- int sockfd;
- struct sockaddr_un ucl_addr;
- #else
- unsigned int sockfd;
- #endif
-
- char oval = 1;
-
- desc *o;
- o = malloc(sizeof(*o));
- if(!o)
- return 0;
-
- #ifndef WIN32
-
- if(!host)
- {
- char *mktemp(char *);
- int clilen;
- o->len = sizeof(ucl_addr);
- /*
- * Fill in the structure "userv_addr" with the address of the
- * server that we want to send to.
- */
-
- bzero((char *) &o->userv_addr, sizeof(o->userv_addr));
- o->userv_addr.sun_family = AF_UNIX;
- strcpy(o->userv_addr.sun_path, UNIXDG_PATH);
- sprintf(o->userv_addr.sun_path+strlen(o->userv_addr.sun_path), "%d", portnumber);
- o->uservlen = sizeof(o->userv_addr.sun_family) + strlen(o->userv_addr.sun_path);
- o->addr = &(o->userv_addr);
- /*
- * Open a socket (a UNIX domain datagram socket).
- */
-
- if ( (sockfd = socket(AF_UNIX, SOCK_DGRAM, 0)) >= 0)
- {
- /*
- * Bind a local address for us.
- * In the UNIX domain we have to choose our own name (that
- * should be unique). We'll use mktemp() to create a unique
- * pathname, based on our process id.
- */
-
- bzero((char *) &ucl_addr, sizeof(ucl_addr)); /* zero out */
- ucl_addr.sun_family = AF_UNIX;
- strcpy(ucl_addr.sun_path, UNIXDG_TMP);
-
- mktemp(ucl_addr.sun_path);
- clilen = sizeof(ucl_addr.sun_family) + strlen(ucl_addr.sun_path);
-
- if (bind(sockfd, (struct sockaddr *) &ucl_addr, clilen) < 0)
- {
- perror("client: can't bind local address");
- close(sockfd);
- sockfd = -1;
- }
- }
- else
- perror("unable to make socket\n");
-
- }else
-
- #endif
-
- {
- /*
- * Fill in the structure "serv_addr" with the address of the
- * server that we want to send to.
- */
- o->len = sizeof(cl_addr);
-
- #ifdef WIN32
- ZeroMemory((char *)&o->serv_addr, sizeof(o->serv_addr));
- #else
- bzero((char *)&o->serv_addr, sizeof(o->serv_addr));
- #endif
-
- o->serv_addr.sin_family = AF_INET;
-
- /* MW 6/6/96: Call gethostbyname() instead of inet_addr(),
- so that host can be either an Internet host name (e.g.,
- "les") or an Internet address in standard dot notation
- (e.g., "128.32.122.13") */
- {
- struct hostent *hostsEntry;
- unsigned long address;
-
- hostsEntry = gethostbyname(host);
- if (hostsEntry == NULL) {
- fprintf(stderr, "Couldn't decipher host name \"%s\"\n", host);
- #ifndef WIN32
- herror(NULL);
- #endif
- return 0;
- }
-
- address = *((unsigned long *) hostsEntry->h_addr_list[0]);
- o->serv_addr.sin_addr.s_addr = address;
- }
-
- /* was: o->serv_addr.sin_addr.s_addr = inet_addr(host); */
-
- /* End MW changes */
-
- /*
- * Open a socket (a UDP domain datagram socket).
- */
-
-
- #ifdef WIN32
- o->serv_addr.sin_port = htons((USHORT)portnumber);
- o->addr = &(o->serv_addr);
- if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) != INVALID_SOCKET) {
- ZeroMemory((char *)&cl_addr, sizeof(cl_addr));
- cl_addr.sin_family = AF_INET;
- cl_addr.sin_addr.s_addr = htonl(INADDR_ANY);
- cl_addr.sin_port = htons(0);
-
- // enable broadcast: jdl ~2003
- if(setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &oval, sizeof(int)) == -1) {
- perror("setsockopt");
- }
-
- if(bind(sockfd, (struct sockaddr *) &cl_addr, sizeof(cl_addr)) < 0) {
- perror("could not bind\n");
- closesocket(sockfd);
- sockfd = -1;
- }
- }
- else { perror("unable to make socket\n");}
- #else
- o->serv_addr.sin_port = htons(portnumber);
- o->addr = &(o->serv_addr);
- if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) >= 0) {
- bzero((char *)&cl_addr, sizeof(cl_addr));
- cl_addr.sin_family = AF_INET;
- cl_addr.sin_addr.s_addr = htonl(INADDR_ANY);
- cl_addr.sin_port = htons(0);
-
- // enable broadcast: jdl ~2003
- if(setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &oval, sizeof(int)) == -1) {
- perror("setsockopt");
- }
-
- if(bind(sockfd, (struct sockaddr *) &cl_addr, sizeof(cl_addr)) < 0) {
- perror("could not bind\n");
- close(sockfd);
- sockfd = -1;
- }
- }
- else { perror("unable to make socket\n");}
- #endif
- }
- #ifdef WIN32
- if(sockfd == INVALID_SOCKET) {
- #else
- if(sockfd < 0) {
- #endif
- free(o);
- o = 0;
- }
- else
- o->sockfd = sockfd;
- return o;
-}
-
-
-#include <errno.h>
-
-static bool sendudp(const struct sockaddr *sp, int sockfd,int length, int count, void *b)
-{
- int rcount;
- if((rcount=sendto(sockfd, b, count, 0, sp, length)) != count)
- {
- printf("sockfd %d count %d rcount %dlength %d errno %d\n", sockfd,count,rcount,length, errno);
- return FALSE;
- }
- return TRUE;
-}
-bool SendHTMSocket(void *htmsendhandle, int length_in_bytes, void *buffer)
-{
- desc *o = (desc *)htmsendhandle;
- return sendudp(o->addr, o->sockfd, o->len, length_in_bytes, buffer);
-}
-void CloseHTMSocket(void *htmsendhandle)
-{
- desc *o = (desc *)htmsendhandle;
- #ifdef WIN32
- if(SOCKET_ERROR == closesocket(o->sockfd)) {
- perror("CloseHTMSocket::closesocket failed\n");
- return;
- }
- #else
- if(close(o->sockfd) == -1)
- {
- perror("CloseHTMSocket::closesocket failed");
- return;
- }
- #endif
-
- free(o);
-}
diff --git a/send+dump/htmsocket.h b/send+dump/htmsocket.h deleted file mode 100644 index 07bea93..0000000 --- a/send+dump/htmsocket.h +++ /dev/null @@ -1,48 +0,0 @@ -/* -Written by Adrian Freed, The Center for New Music and Audio Technologies, -University of California, Berkeley. Copyright (c) 1992,93,94,95,96,97,98,99,2000,01,02,03,04 -The Regents of the University of California (Regents). - -Permission to use, copy, modify, distribute, and distribute modified versions -of this software and its documentation without fee and without a signed -licensing agreement, is hereby granted, provided that the above copyright -notice, this paragraph and the following two paragraphs appear in all copies, -modifications, and distributions. - -IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, -SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING -OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS -BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED -HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE -MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - - -The OSC webpage is http://cnmat.cnmat.berkeley.edu/OpenSoundControl -*/ - - - /* htmparam.h - - Adrian Freed - send parameters to htm servers by udp or UNIX protocol - */ -#ifndef TRUE -#define TRUE 1 -#define FALSE 0 -#endif -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); - -/* 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 */ -bool SendHTMSocket(void *htmsendhandle, int length_in_bytes, void *buffer); - -/* close the socket(2) and release memory associated with it */ -void CloseHTMSocket(void *htmsendhandle); diff --git a/send+dump/sendOSC.c b/send+dump/sendOSC.c deleted file mode 100644 index bde4f8d..0000000 --- a/send+dump/sendOSC.c +++ /dev/null @@ -1,602 +0,0 @@ -/* -Written by Matt Wright, The Center for New Music and Audio Technologies, -University of California, Berkeley. Copyright (c) 1996,97,98,99,2000,01,02,03 -The Regents of the University of California (Regents). - -Permission to use, copy, modify, distribute, and distribute modified versions -of this software and its documentation without fee and without a signed -licensing agreement, is hereby granted, provided that the above copyright -notice, this paragraph and the following two paragraphs appear in all copies, -modifications, and distributions. - -IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, -SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING -OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS -BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED -HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE -MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - - -The OSC webpage is http://cnmat.cnmat.berkeley.edu/OpenSoundControl -*/ - -/* sendOSC.c - - Matt Wright, 6/3/97 - based on sendSC.c, which was based on a version by Adrian Freed - - Text-based OpenSoundControl client. User can enter messages via command - line arguments or standard input. - - Version 0.1: "play" feature - Version 0.2: Message type tags. - -*/ - -#define VERSION "http://cnmat.berkeley.edu/OpenSoundControl/sendOSC-0.1.html" - -/* -compiling: - cc -o sendOSC sendOSC.c htmsocket.c OpenSoundControl.c OSC_timeTag.c -*/ - - -#include "OSC-client.h" -#include "htmsocket.h" - -#include <stdio.h> -#include <stdlib.h> -/* #include <bstring.h> */ -#include <string.h> - -#ifdef UNIX - #include <ctype.h> - #include <netinet/in.h> -#endif - -typedef struct { - enum {INT, FLOAT, STRING} type; - union { - int i; - float f; - char *s; - } datum; -} typedArg; - -void CommandLineMode(int argc, char *argv[], void *htmsocket); -void InteractiveMode(void *htmsocket); -OSCTimeTag ParseTimeTag(char *s); -void ParseInteractiveLine(OSCbuf *buf, char *mesg); -typedArg ParseToken(char *token); -int WriteMessage(OSCbuf *buf, char *messageName, int numArgs, typedArg *args); -void SendBuffer(void *htmsocket, OSCbuf *buf); -void SendData(void *htmsocket, int size, char *data); -void fatal_error(char *s); -void complain(char *s, ...); - -/* Exit status codes: - 0: successful - 2: Message(s) dropped because of buffer overflow - 3: Socket error - 4: Usage error - 5: Internal error -*/ -static int exitStatus = 0; - - -static int useTypeTags = 1; - -int main(int argc, char *argv[]) { - int portnumber; - char *hostname = 0; - void *htmsocket; - - argc--; - argv++; - - if (argc == 0) { - goto usageerror; - } - - if (argc >= 1 && (strncmp(*argv, "-notypetags", 2) == 0)) { - useTypeTags = 0; - argv++; - argc--; - } - - if (argc >= 2 && (strncmp(*argv, "-r", 2) == 0)) { - hostname = getenv("REMOTE_ADDR"); - if (hostname == NULL) { - complain("sendSC -r: REMOTE_ADDR not in environment\n"); - exit(4); - } - argv++; - argc--; - } - - if (argc >= 3 && (strncmp(*argv, "-h", 2) == 0)) { - hostname = argv[1]; - argv += 2; - argc -= 2; - } - portnumber = atoi(*argv); - argv++; - argc--; - - htmsocket = OpenHTMSocket(hostname, portnumber); - if (!htmsocket) { - perror("Couldn't open socket: "); - exit(3); - } - - if (argc > 0) { - printf("host %s, port %d, %s\n", hostname, portnumber, - useTypeTags ? "use type tags" : "don't use type tags"); - CommandLineMode(argc, argv, htmsocket); - } else { - printf("sendOSC version " VERSION "\n"); - printf("by Matt Wright. Copyright (c) 1996, 1997 Regents of the University of California.\n"); - printf("host %s, port %d, %s\n", hostname, portnumber, - useTypeTags ? "use type tags" : "don't use type tags"); - InteractiveMode(htmsocket); - } - CloseHTMSocket(htmsocket); - exit(exitStatus); - - - usageerror: - complain("usage: %s [-notypetags] [-r] [-h target_host_name] port_number [message...]\n", - argv[-1]); - exit(4); - -} - - -#define MAX_ARGS 2000 -#define SC_BUFFER_SIZE 32000 -static char bufferForOSCbuf[SC_BUFFER_SIZE]; - -void CommandLineMode(int argc, char *argv[], void *htmsocket) { - char *messageName; - char *token; - typedArg args[MAX_ARGS]; - int i,j, numArgs; - OSCbuf buf[1]; - - OSC_initBuffer(buf, SC_BUFFER_SIZE, bufferForOSCbuf); - - if (argc > 1) { - if (OSC_openBundle(buf, OSCTT_Immediately())) { - complain("Problem opening bundle: %s\n", OSC_errorMessage); - return; - } - } - - for (i = 0; i < argc; i++) { - messageName = strtok(argv[i], ","); - if (messageName == NULL) { - break; - } - - j = 0; - while ((token = strtok(NULL, ",")) != NULL) { - args[j] = ParseToken(token); - j++; - if (j >= MAX_ARGS) { - complain("Sorry; your message has more than MAX_ARGS (%d) arguments; ignoring the rest.\n", - MAX_ARGS); - break; - } - } - numArgs = j; - - WriteMessage(buf, messageName, numArgs, args); - } - - if (argc > 1) { - if (OSC_closeBundle(buf)) { - complain("Problem closing bundle: %s\n", OSC_errorMessage); - return; - } - } - - SendBuffer(htmsocket, buf); -} - -#define MAXMESG 2048 - -void InteractiveMode(void *htmsocket) { - char mesg[MAXMESG]; - OSCbuf buf[1]; - int bundleDepth = 0; /* At first, we haven't seen "[". */ - - OSC_initBuffer(buf, SC_BUFFER_SIZE, bufferForOSCbuf); - - while (fgets(mesg, MAXMESG, stdin) != NULL) { - if (mesg[0] == '\n') { - if (bundleDepth > 0) { - /* Ignore blank lines inside a group. */ - } else { - /* blank line => repeat previous send */ - SendBuffer(htmsocket, buf); - } - continue; - } - - if (bundleDepth == 0) { - OSC_resetBuffer(buf); - } - - if (mesg[0] == '[') { - OSCTimeTag tt = ParseTimeTag(mesg+1); - if (OSC_openBundle(buf, tt)) { - complain("Problem opening bundle: %s\n", OSC_errorMessage); - OSC_resetBuffer(buf); - bundleDepth = 0; - continue; - } - bundleDepth++; - } else if (mesg[0] == ']' && mesg[1] == '\n' && mesg[2] == '\0') { - if (bundleDepth == 0) { - complain("Unexpected ']': not currently in a bundle.\n"); - } else { - if (OSC_closeBundle(buf)) { - complain("Problem closing bundle: %s\n", OSC_errorMessage); - OSC_resetBuffer(buf); - bundleDepth = 0; - continue; - } - - bundleDepth--; - if (bundleDepth == 0) { - SendBuffer(htmsocket, buf); - } - } - } else { - ParseInteractiveLine(buf, mesg); - if (bundleDepth != 0) { - /* Don't send anything until we close all bundles */ - } else { - SendBuffer(htmsocket, buf); - } - } - } -} - -OSCTimeTag ParseTimeTag(char *s) { - char *p, *newline; - typedArg arg; - - p = s; - while (isspace(*p)) p++; - if (*p == '\0') return OSCTT_Immediately(); - - if (*p == '+') { - /* Time tag is for some time in the future. It should be a - number of seconds as an int or float */ - - newline = strchr(s, '\n'); - if (newline != NULL) *newline = '\0'; - - p++; /* Skip '+' */ - while (isspace(*p)) p++; - - arg = ParseToken(p); - if (arg.type == STRING) { - complain("warning: inscrutable time tag request: %s\n", s); - return OSCTT_Immediately(); - } else if (arg.type == INT) { - return OSCTT_PlusSeconds(OSCTT_CurrentTime(), - (float) arg.datum.i); - } else if (arg.type == FLOAT) { - return OSCTT_PlusSeconds(OSCTT_CurrentTime(), arg.datum.f); - } else { - fatal_error("This can't happen!"); - } - } - - if (isdigit(*p) || (*p >= 'a' && *p <='f') || (*p >= 'A' && *p <='F')) { - /* They specified the 8-byte tag in hex */ - OSCTimeTag tt; - if (sscanf(p, "%llx", &tt) != 1) { - complain("warning: couldn't parse time tag %s\n", s); - return OSCTT_Immediately(); - } -#ifndef HAS8BYTEINT - if (ntohl(1) != 1) { - /* tt is a struct of seconds and fractional part, - and this machine is little-endian, so sscanf - wrote each half of the time tag in the wrong half - of the struct. */ - uint4 temp; - temp = tt.seconds; - tt.seconds = tt.fraction ; - tt.fraction = temp; - } -#endif - return tt; - } - - complain("warning: invalid time tag: %s\n", s); - return OSCTT_Immediately(); -} - - -void ParseInteractiveLine(OSCbuf *buf, char *mesg) { - char *messageName, *token, *p; - typedArg args[MAX_ARGS]; - int thisArg; - - p = mesg; - while (isspace(*p)) p++; - if (*p == '\0') return; - - messageName = p; - - if (strcmp(messageName, "play\n") == 0) { - /* Special kludge feature to save typing */ - typedArg arg; - - if (OSC_openBundle(buf, OSCTT_Immediately())) { - complain("Problem opening bundle: %s\n", OSC_errorMessage); - return; - } - - arg.type = INT; - arg.datum.i = 0; - WriteMessage(buf, "/voices/0/tp/timbre_index", 1, &arg); - - arg.type = FLOAT; - arg.datum.i = 0.0f; - WriteMessage(buf, "/voices/0/tm/goto", 1, &arg); - - if (OSC_closeBundle(buf)) { - complain("Problem closing bundle: %s\n", OSC_errorMessage); - } - - return; - } - - while (!isspace(*p) && *p != '\0') p++; - if (isspace(*p)) { - *p = '\0'; - p++; - } - - thisArg = 0; - while (*p != '\0') { - /* flush leading whitespace */ - while (isspace(*p)) p++; - if (*p == '\0') break; - - if (*p == '"') { - /* A string argument: scan for close quotes */ - p++; - args[thisArg].type = STRING; - args[thisArg].datum.s = p; - - while (*p != '"') { - if (*p == '\0') { - complain("Unterminated quote mark: ignoring line\n"); - return; - } - p++; - } - *p = '\0'; - p++; - } else { - token = p; - while (!isspace(*p) && (*p != '\0')) p++; - if (isspace(*p)) { - *p = '\0'; - p++; - } - args[thisArg] = ParseToken(token); - } - thisArg++; - if (thisArg >= MAX_ARGS) { - complain("Sorry, your message has more than MAX_ARGS (%d) arguments; ignoring the rest.\n", - MAX_ARGS); - break; - } - } - - if (WriteMessage(buf, messageName, thisArg, args) != 0) { - complain("Problem sending message: %s\n", OSC_errorMessage); - } -} - -typedArg ParseToken(char *token) { - char *p = token; - typedArg returnVal; - - /* It might be an int, a float, or a string */ - - if (*p == '-') p++; - - if (isdigit(*p) || *p == '.') { - while (isdigit(*p)) p++; - if (*p == '\0') { - returnVal.type = INT; - returnVal.datum.i = atoi(token); - return returnVal; - } - if (*p == '.') { - p++; - while (isdigit(*p)) p++; - if (*p == '\0') { - returnVal.type = FLOAT; - returnVal.datum.f = atof(token); - return returnVal; - } - } - } - - returnVal.type = STRING; - returnVal.datum.s = token; - return returnVal; -} - -int WriteMessage(OSCbuf *buf, char *messageName, int numArgs, typedArg *args) { - int j, returnVal; - - returnVal = 0; - -#ifdef DEBUG - printf("WriteMessage: %s ", messageName); - - for (j = 0; j < numArgs; j++) { - switch (args[j].type) { - case INT: - printf("%d ", args[j].datum.i); - break; - - case FLOAT: - printf("%f ", args[j].datum.f); - break; - - case STRING: - printf("%s ", args[j].datum.s); - break; - - default: - fatal_error("Unrecognized arg type"); - exit(5); - } - } - printf("\n"); -#endif - - if (!useTypeTags) { - returnVal = OSC_writeAddress(buf, messageName); - if (returnVal) { - complain("Problem writing address: %s\n", OSC_errorMessage); - } - } else { - /* First figure out the type tags */ - char typeTags[MAX_ARGS+2]; - int i; - - typeTags[0] = ','; - - for (i = 0; i < numArgs; ++i) { - switch (args[i].type) { - case INT: - typeTags[i+1] = 'i'; - break; - - case FLOAT: - typeTags[i+1] = 'f'; - break; - - case STRING: - typeTags[i+1] = 's'; - break; - - default: - fatal_error("Unrecognized arg type"); - exit(5); - } - } - typeTags[i+1] = '\0'; - - returnVal = OSC_writeAddressAndTypes(buf, messageName, typeTags); - if (returnVal) { - complain("Problem writing address: %s\n", OSC_errorMessage); - } - } - - for (j = 0; j < numArgs; j++) { - switch (args[j].type) { - case INT: - if ((returnVal = OSC_writeIntArg(buf, args[j].datum.i)) != 0) { - return returnVal; - } - break; - - case FLOAT: - if ((returnVal = OSC_writeFloatArg(buf, args[j].datum.f)) != 0) { - return returnVal; - } - break; - - case STRING: - if ((returnVal = OSC_writeStringArg(buf, args[j].datum.s)) != 0) { - return returnVal; - } - break; - - default: - fatal_error("Unrecognized arg type"); - exit(5); - } - } - - return returnVal; -} - -void SendBuffer(void *htmsocket, OSCbuf *buf) { -#ifdef DEBUG - printf("Sending buffer...\n"); -#endif - if (OSC_isBufferEmpty(buf)) return; - if (!OSC_isBufferDone(buf)) { - fatal_error("SendBuffer() called but buffer not ready!"); - exit(5); - } - SendData(htmsocket, OSC_packetSize(buf), OSC_getPacket(buf)); -} - -void SendData(void *htmsocket, int size, char *data) { - if (!SendHTMSocket(htmsocket, size, data)) { - perror("Couldn't send out socket: "); - CloseHTMSocket(htmsocket); - exit(3); - } -} - -void fatal_error(char *s) { - fprintf(stderr, "%s\n", s); - exit(4); -} - -#include <stdarg.h> -void complain(char *s, ...) { - va_list ap; - va_start(ap, s); - vfprintf(stderr, s, ap); - va_end(ap); -} - - -#ifdef COMPUTE_MESSAGE_SIZE - /* Unused code to find the size of a message */ - - /* Compute size */ - size = SynthControl_effectiveStringLength(messageName); - - for (j = 0; j < numArgs; j++) { - switch (args[j].type) { - case INT: case FLOAT: - size += 4; - break; - - case STRING: - size += SynthControl_effectiveStringLength(args[j].datum.s); - break; - - default: - fatal_error("Unrecognized token type"); - exit(4); - } - } - - if (!SynthControl_willMessageFit(buf, size)) { - complain("Message \"%s\" won't fit in buffer: dropping.", messageName); - return; - } -#endif |