Beispiel #1
0
void ReceivePacket(int sockfd) {
    OSCPacketBuffer pb;
    struct NetworkReturnAddressStruct *ra;
    int maxclilen=sizeof(struct sockaddr_in);
    int n;
    int capacity = OSCGetReceiveBufferSize();
    int morePackets = 1;
    char *buf;


    while(morePackets) {
	pb = OSCAllocPacketBuffer();
	if (!pb) {
	    OSCWarning("Out of memory for packet buffers---had to drop a packet!");
	    /* How do I actually gobble down the packet? */
	    return;
	}
	buf = OSCPacketBufferGetBuffer(pb);

	/* The type NetworkReturnAddressPtr is const in two ways, so that
	   callback procedures that are passed the pointer can neither change
	   the pointer itself or the data the pointer points to.  But here's
	   where we fill in the return address, so we do a cast to a non-const
	   type. */

	ra = (struct NetworkReturnAddressStruct *) OSCPacketBufferGetClientAddr(pb);
	ra->clilen = maxclilen;
	ra->sockfd = sockfd;

/*	printf("* recvfrom(sockfd %d, buf %p, capacity %d)\n", sockfd, buf, capacity); */
	n = recvfrom(sockfd, buf, capacity, 0, &(ra->cl_addr), &(ra->clilen));

	if (n > 0) {
	    int *sizep = OSCPacketBufferGetSize(pb);
	    *sizep = n;
	    OSCAcceptPacket(pb);
	    if (time_to_quit) return;
	} else {
	    OSCFreePacket(pb);
	    morePackets = 0;
	}
    }
}
Boolean OSCScheduleInternalMessages(OSCTimeTag when, int numMessages, 
				    char **addresses, int *arglens, void **args) {
    int i, bufSizeNeeded, paddedStrLen;
    OSCPacketBuffer p;
    queuedData *qd, *scan;
    char *bufPtr;
    char *oldBufPtr;
    

    /* Figure out how big of a buffer we'll need to hold this huge bundle.
       We don't store the "#bundle" string or the time tag, just the 4-byte
       size counts, the addresses, possible extra null padding for the
       addresses, and the arguments. */

    bufSizeNeeded = 0;
    for (i = 0; i < numMessages; ++i) {
	bufSizeNeeded += 4 + OSCPaddedStrlen(addresses[i]) + arglens[i];
    }

    if (bufSizeNeeded > OSCGetReceiveBufferSize()) {
	return FALSE;
    }
	

    /* Now try to allocate the data objects to hold these messages */
    qd = AllocQD();
    if (qd == 0) return FALSE;

    p = OSCAllocPacketBuffer();
    if (p == 0) {
	FreeQD(qd);
	return FALSE;
    }

    /* Now fill in the buffer with a fake #bundle message.   This is almost like
       putting a real #bundle message in the buffer and then calling OSCAcceptPacket,
       except that we save a little time and memory by not writing "#bundle" or the time tag,
       and by pre-parsing the messages a little.   Thus, this code duplicates a lot
       of what's in InsertBundleOrMessage() */

    bufPtr = p->buf;

    for (i = 0; i < numMessages; ++i) {
	/* First the size count of this bundle element */
	*((int4 *) bufPtr) = OSCPaddedStrlen(addresses[i]) + arglens[i];
	bufPtr += sizeof(int4);

	/* Then the address */
	bufPtr = OSCPaddedStrcpy(bufPtr, addresses[i]);

	/* Then the arguments */
	memcpy(bufPtr, args[i], arglens[i]);
	bufPtr += arglens[i];
    }

#ifdef PARANOID
    if (bufPtr != p->buf+bufSizeNeeded) {
	fatal_error("OSCScheduleInternalMessages: internal error");
    }
#endif

    /* Fill in the rest of the packet fields */
    p->n = bufSizeNeeded;
    p->returnAddrOK = FALSE;
    PacketAddRef(p);

    /* Now fill in the queuedData object */
    qd->timetag = when;
    qd->myPacket = p;
    qd->type = BUNDLE;
    qd->data.bundle.length = bufSizeNeeded;
    qd->data.bundle.bytes = p->buf;

    /* Now we can put it into the scheduling queue. */
    OSCQueueInsert(globals.TheQueue, (OSCSchedulableObject) qd);

    return TRUE;
}