Exemple #1
0
/* 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);
}
Exemple #2
0
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
}
Exemple #3
0
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);
}