[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: C code to multiplex small voice packets into IP packets



> Hi everyone,
>
> I am looking for a C code to multiplex voice packets of say 20 Bytes into IP packets. I need
> to do this while keeping the timer in order to meeting delays involved in transporting voice
> traffic in the UTRAN based IP.
 
Here's something I whipped up:
=======================================================================

/*
* Multiplexing module. Call voip_init first, then
* voip_multiplex_packet with a voice packet ad nauseum.
* voip_multiplex_packet is nonblocking.
* Finally, call voip_deinit
*
*/

#include <string.h>
#include <sys/time.h>
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>

#define IPPKT_SEND_SIZELIMIT 50000
#define IPPKT_SEND_TIMELIMIT_USEC 250000
#define VOICEPKT_SIZE 20
#define MAX_FAILURES 3

static int pkt_off = 0;
static struct timeval deadline;
static unsigned char ip_buf[IPPKT_SEND_SIZELIMIT];
static unsigned char* failed_send[MAX_FAILURES]; /* ring buffer */
static int failed_send_len[MAX_FAILURES];
int fs_start = 0;
int fs_end = 0;

int voip_init()
{
 int i,j;

 for ( i = 0; i < MAX_FAILURES; i++ )
 {
   failed_send[i] = (unsigned char*) malloc(IPPKT_SEND_SIZELIMIT);
   if( !failed_send[i] )
   {
     fprintf(stderr,"voip_init: Out of memory\n");
     for ( j = 0; j < i; j++ )
       free(failed_send[j]);
     return 0;
   }
 }

 if( gettimeofday(&deadline,NULL) < 0 ){
   perror("voip_init: gettimeofday: ");
   return 0;
 }
 deadline.tv_usec += IPPKT_SEND_TIMELIMIT_USEC;

 return 1;
}

void voip_deinit()
{
 int i;

 for ( i = 0; i < MAX_FAILURES; i++ )
   free(failed_send[i]);
}

static add_to_failed(unsigned char* buf, int len)
{
 if ( fs_end = (fs_start + (MAX_FAILURES - 1)) % MAX_FAILURES ) /* -1
in mod MAX_FAILURES */
   fs_start++; /* too many failures - drop oldest voice packet (will
cause clip) */
 memcpy(failed_send[fs_end], buf, len);
 failed_send_len[fs_end] = len;
 fs_end++;
 fs_end %= MAX_FAILURES;
}

static void send_pkt(int sock, struct sockaddr* addr, int len )
{
 int queue_full = 0;

 while ( fs_start != fs_end )
 {
   if( sendto( sock, failed_send[fs_start],
failed_send_len[fs_start], MSG_DONTWAIT, addr, sizeof(struct sockaddr)
) < 0 )
   {
     queue_full = 1;
     break;
   }
   else
     fs_start++;
 }

 if ( queue_full )
   add_to_failed(ip_buf,len);
 else
 {
   if( sendto( sock, ip_buf, len, MSG_DONTWAIT, addr, sizeof(struct
sockaddr) ) < 0 )
   {
     if ( EAGAIN == errno || EWOULDBLOCK == errno )
     {
       add_to_failed(ip_buf,len);
     }
   }
 }

 gettimeofday(&deadline,NULL);
 deadline.tv_usec += IPPKT_SEND_TIMELIMIT_USEC;
}

/* Add a voice packet to our IP packet. Send when 1) full or
* 2) timeout expires.
*
*/
void voip_multiplex_packet(
 int sock,
 struct sockaddr* addr,
 unsigned char* voicepkt)
{
 struct timeval now;

 if ( timercmp((&now),(&deadline),>=) )
 {
   send_pkt(sock, addr, pkt_off+1);
   pkt_off = 0;
 }

 memcpy(ip_buf+pkt_off, voicepkt, VOICEPKT_SIZE);
 pkt_off += VOICEPKT_SIZE;

 if ( pkt_off + VOICEPKT_SIZE >= IPPKT_SEND_SIZELIMIT )
 {
   send_pkt(sock, addr, pkt_off+1);
   pkt_off = 0;
 }
}



Reply to: