I am a bit confused with "the system paces itself to the network activity ".
First, yes I am sending packet and receiving them so there is sort of correlation in the User Agent. My point is that if the Sender if the user already has a 20ms delay from packet to packet I do not see any harm on checking the socket whether anything was received or not. So basically if i am receiving something of the same size of my payload I read if not I ignore it. Below my pseudo Code
Code:
GLOBAL VALUES
Int runcond = 1;
Int queue_position;
pthread_mutex_t token_mutex;
pthread_cond_t ReceiveData_cond;//=PTHREAD_COND_INITIALIZER;
int breceive;
pthread_cond_t SendData_cond;//=PTHREAD_COND_INITIALIZER;
int bsend;
pthread_cond_t Start_cond;//=PTHREAD_COND_INITIALIZER;
int payloadsize=160;
int rtp_hdr=12;
Main Proxy
Int sockfd;
pthread_create (&pid_rtp_sender, NULL, &send_rtp, null;
pthread_create (&pid_rtp_receiver, NULL, &receive_rtp,null);
void* send_rtp(void* unused)
{
unsigned char * pkt;
if (!(pkt=malloc(((payloadsize+rtp_hdr)+1)*sizeof(char))))printf("malloc error for pkt\n");
if ((sockfd=socket(PF_INET,SOCK_DGRAM,0))<0) {
printf("socket error");
return;
}
/*Bind the source port*/
inet_pton(AF_INET,strdup("192.168.1.2"),&ip_address.s_addr);
rem_addr.sin_family = AF_INET;
rem_addr.sin_port = htons(ndestport);
memcpy(&rem_addr.sin_addr.s_addr,&ip_address.s_addr, sizeof(rem_addr.sin_addr));
addrlen=sizeof(rem_addr);
bind (sockfd,(struct sockaddr *)&local_addr,sizeof(struct sockaddr_in));
flags = fcntl(sockfd, F_GETFL);
flags |= O_NONBLOCK;
fcntl(sockfd, F_SETFL, flags);
while (runcond)
{
pthread_mutex_lock(&token_mutex);
if (q_position > 0){
/*Get Payload from Queue*/
pkt=get_queue(queue,q_position);
snd=sendto(sockfd,pkt,payloadsize+rtp_hdr,0,(struct sockaddr *)&rem_addr,sizeof(rem_addr));
}
breceive=1;
pthread_cond_signal(&ReceiveData_cond);
bsend=0;
pthread_mutex_unlock(&token_mutex);
}
void* receive_rtp(void* unused)
{
unsigned char * pkt;
if (!(pkt=malloc(((payloadsize+rtp_hdr)+1)*sizeof(char))))printf("malloc error for pkt\n");
if ((sockfd=socket(PF_INET,SOCK_DGRAM,0))<0) {
printf("socket error");
return;
}
/*Bind the source port*/
inet_pton(AF_INET,myip,&ip_address.s_addr);
rem_addr.sin_family = AF_INET;
rem_addr.sin_port = htons(ndestport);
memcpy(&rem_addr.sin_addr.s_addr,&ip_address.s_addr, sizeof(rem_addr.sin_addr));
addrlen=sizeof(rem_addr);
bind (sockfd,(struct sockaddr *)&local_addr,sizeof(struct sockaddr_in));
flags = fcntl(sockfd, F_GETFL);
flags |= O_NONBLOCK;
fcntl(sockfd, F_SETFL, flags);
while (runcond)
{
pthread_mutex_lock(&token_mutex);
err=recvfrom(sockfd,pkt,payloadsize+rtp_hdr, 0, (struct sockaddr *)&address,&addrlen );
if (err==payloadsize){
memcpy(payload,pkt+rtp_hdr,payloadsize);
memcpy(&cseq_tmp,pkt+2,sizeof(cseq_tmp));
/*ADD PAYLOAD TO A FIFO QUEUE*/
q_position=q_add(queue,q_position,&cdnbuffer,payloadsize);
}
bsend=1;
pthread_cond_signal(&SendData_cond);
breceive=0;
while (!breceive)
pthread_cond_wait(&ReceiveData_cond,&token_mutex);
pthread_mutex_unlock(&token_mutex);
}
USER AGENT
Code:
void* send_rtp(void* unused)
{
unsigned char * pkt;
if (!(pkt=malloc(((payloadsize+rtp_hdr)+1)*sizeof(char))))printf("malloc error for pkt\n");
if ((sockfd=socket(PF_INET,SOCK_DGRAM,0))<0) {
printf("socket error");
return;
}
/*Bind the source port*/
inet_pton(AF_INET,strdup("192.168.1.2"),&ip_address.s_addr);
rem_addr.sin_family = AF_INET;
rem_addr.sin_port = htons(ndestport);
memcpy(&rem_addr.sin_addr.s_addr,&ip_address.s_addr, sizeof(rem_addr.sin_addr));
addrlen=sizeof(rem_addr);
bind (sockfd,(struct sockaddr *)&local_addr,sizeof(struct sockaddr_in));
/* Open PCM device for recording (capture). */
//rc = snd_pcm_open(&handle, "default",SND_PCM_STREAM_CAPTURE, 0);
rc = snd_pcm_open(&handle, "plughw:0,0",SND_PCM_STREAM_CAPTURE, 0);
if (rc < 0){
fprintf(stderr,"unable to open pcm device: %s\n",snd_strerror(rc));
exit(1);
}
printf("PCM opened cap\n");
snd_pcm_hw_params_alloca(¶ms);
snd_pcm_hw_params_any(handle, params);
snd_pcm_hw_params_set_access(handle, params,SND_PCM_ACCESS_RW_INTERLEAVED);
//snd_pcm_hw_params_set_format(handle, params,SND_PCM_FORMAT_MU_LAW);
if (snd_pcm_hw_params_set_format(handle, params,SND_PCM_FORMAT_S16_LE)<0)printf("pcm set format\n");
snd_pcm_hw_params_set_channels(handle, params, 1);
snd_pcm_hw_params_set_rate_near(handle, params, &val, &dir);
snd_pcm_hw_params_set_period_size(handle,params, frames, dir);
rc = snd_pcm_hw_params(handle, params);
if (rc < 0){
fprintf(stderr,"unable to set hw parameters: %s\n",snd_strerror(rc));
exit(1);
}
if (DEBUG) printf("Parameters written to the driver cap\n");
fcntl(sockfd, F_SETFL, flags);
while (runcond)
{
pthread_mutex_lock(&token_mutex);
rc = snd_pcm_readi(handle, pkt, frames);
if (rc == -EPIPE)
{
printf(" sender overrun occurred\n");fflush(stdout);
snd_pcm_prepare(handle);
}
else if (rc < 0) printf("error from read \n");
else if (rc != (int)frames) printf("short read, read %d frames\n", rc);
snd=sendto(sockfd,pkt,payloadsize+rtp_hdr,0,(struct sockaddr *)&rem_addr,sizeof(rem_addr));
breceive=1;
pthread_cond_signal(&ReceiveData_cond);
bsend=0;
pthread_mutex_unlock(&token_mutex);
}
void* receive_rtp(void* unused)
{
unsigned char * pkt;
if (!(pkt=malloc(((payloadsize+rtp_hdr)+1)*sizeof(char))))printf("malloc error for pkt\n");
if ((sockfd=socket(PF_INET,SOCK_DGRAM,0))<0) {
printf("socket error");
return;
}
/*Bind the source port*/
inet_pton(AF_INET,myip,&ip_address.s_addr);
rem_addr.sin_family = AF_INET;
rem_addr.sin_port = htons(ndestport);
memcpy(&rem_addr.sin_addr.s_addr,&ip_address.s_addr, sizeof(rem_addr.sin_addr));
addrlen=sizeof(rem_addr);
bind (sockfd,(struct sockaddr *)&local_addr,sizeof(struct sockaddr_in));
/*OPTIONAL??*/
flags = fcntl(sockfd, F_GETFL);
flags |= O_NONBLOCK;
fcntl(sockfd, F_SETFL, flags);
while (runcond)
{
pthread_mutex_lock(&token_mutex);
err=recvfrom(sockfd,pkt,payloadsize+rtp_hdr, 0, (struct sockaddr *)&address,&addrlen );
if (err==payloadsize){
memcpy(payload,pkt+rtp_hdr,payloadsize);
memcpy(&cseq_tmp,pkt+2,sizeof(cseq_tmp));
…
}
bsend=1;
pthread_cond_signal(&SendData_cond);
breceive=0;
while (!breceive)
pthread_cond_wait(&ReceiveData_cond,&token_mutex);
pthread_mutex_unlock(&token_mutex);
}
I am programming that wrongly? is there any other way to make this more efficient? It is important for me not to use blocking sockets as if one packet is lost the sender will suffer this delay too.
Any ideas are welcome