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: