/* instance creation routine */ static void *routeOSC_new(t_symbol *s, int argc, t_atom *argv) { t_routeOSC *x = (t_routeOSC *)pd_new(routeOSC_class); // get memory for a new object & initialize int i; if (argc > MAX_NUM) { error("* routeOSC: too many arguments: %d (max %d)", argc, MAX_NUM); return 0; } x->x_num = 0; /* first verify that all arguments are symbols whose first character is '/' */ for (i = 0; i < argc; ++i) { if (argv[i].a_type == A_SYMBOL) { if (argv[i].a_w.w_symbol->s_name[0] == '/') { /* Now that's a nice prefix */ ++(x->x_num); } else { error("routeOSC: argument %d does not begin with a slash(/).", i); return(0); } } else { error("routeOSC: argument %d is not a symbol.", i); return 0; } } /* now allocate the storage for each path */ x->x_prefixes = (char **)getzbytes(x->x_num*sizeof(char *)); /* the OSC addresses to be matched */ x->x_prefix_depth = (int *)getzbytes(x->x_num*sizeof(int)); /* the number of slashes in each prefix */ x->x_outlets = (void **)getzbytes((x->x_num+1)*sizeof(void *)); /* one for each prefix plus one for everything else */ /* put the pointer to the path in x_prefixes */ /* put the number of levels in x_prefix_depth */ for (i = 0; i < x->x_num; ++i) { x->x_prefixes[i] = argv[i].a_w.w_symbol->s_name; x->x_prefix_depth[i] = routeOSC_count_slashes(x->x_prefixes[i]); } /* Have to create the outlets in reverse order */ /* well, not in pd ? */ for (i = 0; i <= x->x_num; i++) { x->x_outlets[i] = outlet_new(&x->x_obj, &s_list); } x->x_verbosity = 0; /* quiet by default */ return (x); }
static void udpsend_tilde_set_multicast_interface (t_udpsend_tilde *x, t_symbol *s, int argc, t_atom *argv) { #ifdef _WIN32 int i, n_ifaces = 32; PMIB_IPADDRTABLE pIPAddrTable; DWORD dwSize; IN_ADDR IPAddr; int if_index = -1; int found = 0; t_symbol *interfacename = gensym("none"); struct hostent *hp = 0; struct sockaddr_in server; if (x->x_fd < 0) { pd_error(x, "udpsend_tilde_set_multicast_interface: not connected"); return; } switch (argv[0].a_type) { case A_FLOAT: if_index = (int)atom_getfloat(&argv[0]); break; case A_SYMBOL: interfacename = atom_getsymbol(&argv[0]); break; default: pd_error(x, "udpsend_tilde_set_multicast_interface: argument not float or symbol"); return; } if (if_index == -1) { hp = gethostbyname(interfacename->s_name); // if interface is a dotted or named IP address (192.168.0.88) } if (hp != 0) memcpy((char *)&server.sin_addr, (char *)hp->h_addr, hp->h_length); else // maybe interface is its index (1) (names aren't available in _WIN32) { /* get the list of interfaces, IPv4 only */ dwSize = sizeof(MIB_IPADDRTABLE)*n_ifaces; if ((pIPAddrTable = (MIB_IPADDRTABLE *) getbytes(dwSize)) == NULL) { post("udpsend_tilde: unable to allocate %lu bytes for GetIpAddrTable", dwSize); return; } if (GetIpAddrTable(pIPAddrTable, &dwSize, 0)) { udpsend_tilde_sock_err(x, "udpsend_tilde_set_multicast_interface: GetIpAddrTable"); return; } n_ifaces = pIPAddrTable->dwNumEntries; post("udpsend_tilde: %d interface%s available:", n_ifaces, (n_ifaces == 1)?"":"s"); for (i = 0; i < n_ifaces; i++) { IPAddr.S_un.S_addr = (u_long) pIPAddrTable->table[i].dwAddr; post("[%d]: %s", pIPAddrTable->table[i].dwIndex, inet_ntoa(IPAddr)); if (pIPAddrTable->table[i].dwIndex == if_index) { server.sin_addr = IPAddr; found = 1; } } if (pIPAddrTable) { freebytes(pIPAddrTable, dwSize); pIPAddrTable = NULL; } if (! found) { post("udpsend_tilde_set_multicast_interface: bad host name? (%s)\n", interfacename->s_name); return; } } if (setsockopt(x->x_fd, IPPROTO_IP, IP_MULTICAST_IF, (const char *)&server.sin_addr, sizeof(struct in_addr)) == SOCKET_ERROR) udpsend_tilde_sock_err(x, "udpsend_tilde setsockopt IP_MULTICAST_IF"); else post("udpsend_tilde multicast interface is %s", inet_ntoa(server.sin_addr)); #elif defined __APPLE__ int if_index = -1; int found = 0; t_symbol *interfacename = gensym("none"); struct ifaddrs *ifap; int i = 0; int n_ifaces = 0; struct hostent *hp = 0; struct sockaddr_in server; struct sockaddr *sa; char ifname[IFNAMSIZ]; /* longest possible interface name */ if (x->x_fd < 0) { pd_error(x, "udpsend_tilde_set_multicast_interface: not connected"); return; } switch (argv[0].a_type) { case A_FLOAT: if_index = (int)atom_getfloat(&argv[0]); break; case A_SYMBOL: interfacename = atom_getsymbol(&argv[0]); break; default: pd_error(x, "udpsend_tilde_set_multicast_interface: argument not float or symbol"); return; } if (if_index == -1) { hp = gethostbyname(interfacename->s_name); // if interface is a dotted or named IP address (192.168.0.88) } if (hp != 0) memcpy((char *)&server.sin_addr, (char *)hp->h_addr, hp->h_length); else // maybe interface is its name (eth0) or index (1) { // scan all the interfaces to get the IP address of interface if (getifaddrs(&ifap)) udpsend_tilde_sock_err(x, "udpsend_tilde getifaddrs"); i = found = n_ifaces = 0; while (NULL != ifap) { sa = ifap->ifa_addr; if (AF_INET == sa->sa_family) { ++n_ifaces; strncpy (ifname, ifap->ifa_name, IFNAMSIZ); post("[%d]: %s: %s", i, ifname, inet_ntoa(((struct sockaddr_in *)sa)->sin_addr)); if((i == if_index) || ((if_index == -1) && (!strncmp(interfacename->s_name, ifname, IFNAMSIZ)))) { // either the index or the name match server.sin_addr = ((struct sockaddr_in *)sa)->sin_addr; found = 1; } } i++; ifap = ifap->ifa_next; // next record or NULL } freeifaddrs(ifap); post ("udpsend_tilde: %d interfaces", n_ifaces); if (!found) return; } if (setsockopt(x->x_fd, IPPROTO_IP, IP_MULTICAST_IF, (const char *)&server.sin_addr, sizeof(struct in_addr))) udpsend_tilde_sock_err(x, "udpsend_tilde setsockopt IP_MULTICAST_IF"); else post("udpsend_tilde multicast interface is %s", inet_ntoa(server.sin_addr)); return; #else // __linux__ struct sockaddr_in server; struct sockaddr *sa; struct hostent *hp = 0; struct ifconf ifc; int n_ifaces = 32, i, origbuflen, found = 0; char ifname[IFNAMSIZ]; /* longest possible interface name */ t_symbol *interface = gensym("none"); int if_index = -1; if (x->x_fd < 0) { pd_error(x, "udpsend_tilde_set_multicast_interface: not connected"); return; } switch (argv[0].a_type) { case A_FLOAT: if_index = (int)atom_getfloat(&argv[0]); break; case A_SYMBOL: interface = atom_getsymbol(&argv[0]); break; default: pd_error(x, "udpsend_tilde_set_multicast_interface: argument not float or symbol"); return; } if (if_index == -1) { hp = gethostbyname(interface->s_name); // if interface is a dotted or named IP address (192.168.0.88) } if (hp != 0) memcpy((char *)&server.sin_addr, (char *)hp->h_addr, hp->h_length); else // maybe interface is its name (eth0) or index (1) { // scan all the interfaces to get the IP address of interface // find the number of interfaces origbuflen = n_ifaces * sizeof (struct ifreq);// save maximum length for free() ifc.ifc_len = origbuflen; // SIOCGIFCONF changes it to valid length ifc.ifc_buf = (char*)getzbytes(origbuflen); if (ifc.ifc_buf != NULL) { // if (ioctl(x->x_fd, SIOCGIFCONF, &ifc) < 0) // get list of interfaces udpsend_tilde_sock_err(x, "udpsend_tilde_set_multicast_interface: getting list of interfaces"); else { n_ifaces = ifc.ifc_len/sizeof(struct ifreq); post("udpsend_tilde: %d interface%s available:", n_ifaces, (n_ifaces == 1)?"":"s"); for(i = 0; i < n_ifaces; i++) { sa = (struct sockaddr *)&(ifc.ifc_req[i].ifr_addr); strncpy (ifname, ifc.ifc_req[i].ifr_name, IFNAMSIZ); post("[%d]: %s: %s", i, ifname, inet_ntoa(((struct sockaddr_in *)sa)->sin_addr)); if ( (i == if_index) || ((if_index == -1) && (!strncmp(interface->s_name, ifname, IFNAMSIZ))) ) { server.sin_addr = ((struct sockaddr_in *)sa)->sin_addr; found = 1; } } } } freebytes(ifc.ifc_buf, origbuflen); if (! found) { post("udpsend_tilde_set_multicast_interface: bad host name? (%s)\n", interface->s_name); return; } } if (setsockopt(x->x_fd, IPPROTO_IP, IP_MULTICAST_IF, &server.sin_addr, sizeof(struct in_addr)) < 0) udpsend_tilde_sock_err(x, "udpsend_tilde_set_multicast_interface: setsockopt"); else post("udpsend_tilde multicast interface is %s", inet_ntoa(server.sin_addr)); #endif // _WIN32 }
static void packOSC_sendtyped(t_packOSC *x, t_symbol *s, int argc, t_atom *argv) { char messageName[MAXPDSTRING]; unsigned int nTypeTags = 0, typeStrTotalSize = 0; unsigned int argsSize = sizeof(typedArg)*argc; char* typeStr = NULL; /* might not be used */ typedArg* args = (typedArg*)getbytes(argsSize); unsigned int i, nTagsWithData, nArgs, blobCount; unsigned int m, j, k; char c; if (args == NULL) { error("packOSC: unable to allocate %lu bytes for args", (long)argsSize); return; } messageName[0] = '\0'; /* empty */ if(x->x_prefix) /* if there is a prefix, prefix it to the path */ { size_t len = strlen(x->x_prefix); if(len >= MAXPDSTRING) len = MAXPDSTRING-1; strncpy(messageName, x->x_prefix, MAXPDSTRING); atom_string(&argv[0], messageName+len, (unsigned)(MAXPDSTRING-len)); } else atom_string(&argv[0], messageName, MAXPDSTRING); /* the OSC address string */ if (x->x_typetags & 2) { /* second arg is typestring */ /* we need to find out how long the type string is before we copy it*/ nTypeTags = (unsigned int)strlen(atom_getsymbol(&argv[1])->s_name); typeStrTotalSize = nTypeTags + 2; typeStr = (char*)getzbytes(typeStrTotalSize); if (typeStr == NULL) { error("packOSC: unable to allocate %u bytes for typeStr", nTypeTags); return; } typeStr[0] = ','; atom_string(&argv[1], &typeStr[1], typeStrTotalSize); #ifdef DEBUG post("typeStr: %s, nTypeTags %lu", typeStr, nTypeTags); #endif nArgs = argc-2; for (m = nTagsWithData = blobCount = 0; m < nTypeTags; ++m) { #ifdef DEBUG post("typeStr[%d] %c", m+1, typeStr[m+1]); #endif if ((c = typeStr[m+1]) == 0) break; if (!(c == 'T' || c == 'F' || c == 'N' || c == 'I')) { ++nTagsWithData; /* anything other than these tags have at least one data byte */ /* OSC-blob An int32 size count, followed by that many 8-bit bytes of arbitrary binary data, followed by 0-3 additional zero bytes to make the total number of bits a multiple of 32. */ if (c == 'b') blobCount++; /* b probably has more than one byte, so set a flag */ } } if (((blobCount == 0)&&(nTagsWithData != nArgs)) || ((blobCount != 0)&&(nTagsWithData > nArgs))) { error("packOSC: Tags count %d doesn't match argument count %d", nTagsWithData, nArgs); goto cleanup; } if (blobCount > 1) { error("packOSC: Only one blob per packet at the moment..."); goto cleanup; } for (j = k = 0; j < m; ++j) /* m is the number of tags */ { c = typeStr[j+1]; if (c == 'b') { /* A blob has to be the last item, until we get more elaborate. */ if (j != m-1) { error("packOSC: Since I don't know how big the blob is, Blob must be the last item in the list"); goto cleanup; } /* Pack all the remaining arguments as a blob */ for (; k < nArgs; ++k) { args[k] = packOSC_blob(&argv[k+2]); } } else if (!(c == 'T' || c == 'F' || c == 'N' || c == 'I')) /* not no data */ { args[k] = packOSC_forceatom(&argv[k+2], c); ++k; } } if(packOSC_writetypedmessage(x, x->x_oscbuf, messageName, nArgs, args, typeStr)) { error("packOSC: usage error, write-msg failed."); goto cleanup; } } else { for (i = 0; i < (unsigned)(argc-1); i++) { args[i] = packOSC_parseatom(&argv[i+1]); #ifdef DEBUG switch (args[i].type) { case INT_osc: post("packOSC: cell-cont: %d\n", args[i].datum.i); break; case FLOAT_osc: post("packOSC: cell-cont: %f\n", args[i].datum.f); break; case STRING_osc: post("packOSC: cell-cont: %s\n", args[i].datum.s); break; case NOTYPE_osc: post("packOSC: unknown type\n"); break; } post("packOSC: type-id: %d\n", args[i].type); #endif } if(packOSC_writemessage(x, x->x_oscbuf, messageName, i, args)) { error("packOSC: usage error, write-msg failed."); goto cleanup; } } if(!x->x_bundle) { packOSC_sendbuffer(x); OSC_initBuffer(x->x_oscbuf, x->x_buflength, x->x_bufferForOSCbuf); } cleanup: if (typeStr != NULL) freebytes(typeStr, typeStrTotalSize); if (args != NULL) freebytes(args, argsSize); }