fix liax
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@5147 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
parent
ebb56a9eba
commit
8c918602d9
|
@ -40,16 +40,12 @@ void gettimeofday(struct timeval *tv, void /*struct timezone*/ *tz);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
#define _BSD_SOURCE 1
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#ifdef __GNUC__
|
|
||||||
#ifndef __USE_SVID
|
|
||||||
#define __USE_SVID
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
@ -60,7 +56,7 @@ void gettimeofday(struct timeval *tv, void /*struct timezone*/ *tz);
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "iax2.h"
|
#include "iax2.h"
|
||||||
|
@ -70,7 +66,7 @@ void gettimeofday(struct timeval *tv, void /*struct timezone*/ *tz);
|
||||||
#ifdef NEWJB
|
#ifdef NEWJB
|
||||||
#include "jitterbuf.h"
|
#include "jitterbuf.h"
|
||||||
#endif
|
#endif
|
||||||
|
#include "iax-mutex.h"
|
||||||
/*
|
/*
|
||||||
work around jitter-buffer shrinking in asterisk:
|
work around jitter-buffer shrinking in asterisk:
|
||||||
channels/chan_iax2.c:schedule_delivery() shrinks jitter buffer by 2.
|
channels/chan_iax2.c:schedule_delivery() shrinks jitter buffer by 2.
|
||||||
|
@ -330,6 +326,8 @@ struct iax_sched {
|
||||||
struct iax_sched *next;
|
struct iax_sched *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static mutex_t *sched_mutex = NULL;
|
||||||
|
static mutex_t *session_mutex = NULL;
|
||||||
static struct iax_sched *schedq = NULL;
|
static struct iax_sched *schedq = NULL;
|
||||||
static struct iax_session *sessions = NULL;
|
static struct iax_session *sessions = NULL;
|
||||||
static int callnums = 1;
|
static int callnums = 1;
|
||||||
|
@ -412,6 +410,7 @@ static int iax_sched_add(struct iax_event *event, struct iax_frame *frame, sched
|
||||||
sched->func = func;
|
sched->func = func;
|
||||||
sched->arg = arg;
|
sched->arg = arg;
|
||||||
/* Put it in the list, in order */
|
/* Put it in the list, in order */
|
||||||
|
iax_mutex_lock(sched_mutex);
|
||||||
cur = schedq;
|
cur = schedq;
|
||||||
while(cur && cur->when <= sched->when) {
|
while(cur && cur->when <= sched->when) {
|
||||||
prev = cur;
|
prev = cur;
|
||||||
|
@ -423,6 +422,7 @@ static int iax_sched_add(struct iax_event *event, struct iax_frame *frame, sched
|
||||||
} else {
|
} else {
|
||||||
schedq = sched;
|
schedq = sched;
|
||||||
}
|
}
|
||||||
|
iax_mutex_unlock(sched_mutex);
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
DEBU(G "Out of memory!\n");
|
DEBU(G "Out of memory!\n");
|
||||||
|
@ -433,7 +433,9 @@ static int iax_sched_add(struct iax_event *event, struct iax_frame *frame, sched
|
||||||
static int iax_sched_del(struct iax_event *event, struct iax_frame *frame, sched_func func, void *arg, int all)
|
static int iax_sched_del(struct iax_event *event, struct iax_frame *frame, sched_func func, void *arg, int all)
|
||||||
{
|
{
|
||||||
struct iax_sched *cur, *tmp, *prev = NULL;
|
struct iax_sched *cur, *tmp, *prev = NULL;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
iax_mutex_lock(sched_mutex);
|
||||||
cur = schedq;
|
cur = schedq;
|
||||||
while (cur) {
|
while (cur) {
|
||||||
if (cur->event == event && cur->frame == frame && cur->func == func && cur->arg == arg) {
|
if (cur->event == event && cur->frame == frame && cur->func == func && cur->arg == arg) {
|
||||||
|
@ -444,13 +446,18 @@ static int iax_sched_del(struct iax_event *event, struct iax_frame *frame, sched
|
||||||
tmp = cur;
|
tmp = cur;
|
||||||
cur = cur->next;
|
cur = cur->next;
|
||||||
free(tmp);
|
free(tmp);
|
||||||
if (!all)
|
if (!all) {
|
||||||
return -1;
|
ret = -1;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
prev = cur;
|
prev = cur;
|
||||||
cur = cur->next;
|
cur = cur->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
done:
|
||||||
|
iax_mutex_unlock(sched_mutex);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -458,24 +465,31 @@ static int iax_sched_del(struct iax_event *event, struct iax_frame *frame, sched
|
||||||
|
|
||||||
time_in_ms_t iax_time_to_next_event(void)
|
time_in_ms_t iax_time_to_next_event(void)
|
||||||
{
|
{
|
||||||
struct iax_sched *cur = schedq;
|
struct iax_sched *cur = NULL;
|
||||||
time_in_ms_t minimum = 999999999;
|
time_in_ms_t minimum = 999999999;
|
||||||
|
|
||||||
/* If there are no pending events, we don't need to timeout */
|
iax_mutex_lock(sched_mutex);
|
||||||
if (!cur)
|
cur = schedq;
|
||||||
return -1;
|
|
||||||
|
|
||||||
|
/* If there are no pending events, we don't need to timeout */
|
||||||
|
if (!cur) {
|
||||||
|
iax_mutex_unlock(sched_mutex);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
while(cur) {
|
while(cur) {
|
||||||
if (cur->when < minimum) {
|
if (cur->when < minimum) {
|
||||||
minimum = cur->when;
|
minimum = cur->when;
|
||||||
}
|
}
|
||||||
cur = cur->next;
|
cur = cur->next;
|
||||||
}
|
}
|
||||||
|
iax_mutex_unlock(sched_mutex);
|
||||||
|
|
||||||
if (minimum <= 0) {
|
if (minimum <= 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return minimum - current_time_in_ms();
|
return minimum - current_time_in_ms();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -497,7 +511,7 @@ struct iax_session *iax_session_new(void)
|
||||||
callnums = 1;
|
callnums = 1;
|
||||||
s->peercallno = 0;
|
s->peercallno = 0;
|
||||||
s->transferpeer = 0; /* for attended transfer */
|
s->transferpeer = 0; /* for attended transfer */
|
||||||
s->next = sessions;
|
|
||||||
s->sendto = iax_sendto;
|
s->sendto = iax_sendto;
|
||||||
s->pingid = -1;
|
s->pingid = -1;
|
||||||
#ifdef NEWJB
|
#ifdef NEWJB
|
||||||
|
@ -510,7 +524,10 @@ struct iax_session *iax_session_new(void)
|
||||||
jb_setconf(s->jb, &jbconf);
|
jb_setconf(s->jb, &jbconf);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
iax_mutex_lock(session_mutex);
|
||||||
|
s->next = sessions;
|
||||||
sessions = s;
|
sessions = s;
|
||||||
|
iax_mutex_unlock(session_mutex);
|
||||||
}
|
}
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
@ -518,12 +535,19 @@ struct iax_session *iax_session_new(void)
|
||||||
static int iax_session_valid(struct iax_session *session)
|
static int iax_session_valid(struct iax_session *session)
|
||||||
{
|
{
|
||||||
/* Return -1 on a valid iax session pointer, 0 on a failure */
|
/* Return -1 on a valid iax session pointer, 0 on a failure */
|
||||||
struct iax_session *cur = sessions;
|
struct iax_session *cur;
|
||||||
|
|
||||||
|
iax_mutex_lock(session_mutex);
|
||||||
|
cur = sessions;
|
||||||
while(cur) {
|
while(cur) {
|
||||||
if (session == cur)
|
if (session == cur) {
|
||||||
|
iax_mutex_unlock(session_mutex);
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
cur = cur->next;
|
cur = cur->next;
|
||||||
}
|
}
|
||||||
|
iax_mutex_unlock(session_mutex);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -865,26 +889,29 @@ void iax_set_networking(sendto_t st, recvfrom_t rf)
|
||||||
|
|
||||||
int __iax_shutdown(void)
|
int __iax_shutdown(void)
|
||||||
{
|
{
|
||||||
|
struct iax_sched *sp, *fp;
|
||||||
|
|
||||||
/* Hangup Calls */
|
/* Hangup Calls */
|
||||||
if (sessions) {
|
if (sessions) {
|
||||||
struct iax_session *sp = NULL, *fp = NULL;
|
struct iax_session *sp = NULL, *fp = NULL;
|
||||||
|
iax_mutex_lock(session_mutex);
|
||||||
for(sp = sessions; sp ;) {
|
for(sp = sessions; sp ;) {
|
||||||
iax_hangup(sp, "System Shutdown");
|
iax_hangup(sp, "System Shutdown");
|
||||||
fp = sp;
|
fp = sp;
|
||||||
sp = sp->next;
|
sp = sp->next;
|
||||||
destroy_session(fp);
|
destroy_session(fp);
|
||||||
}
|
}
|
||||||
|
iax_mutex_unlock(session_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Clear Scheduler */
|
/* Clear Scheduler */
|
||||||
if(schedq) {
|
iax_mutex_lock(sched_mutex);
|
||||||
struct iax_sched *sp, *fp;
|
for(sp = schedq; sp ;) {
|
||||||
for(sp = schedq; sp ;) {
|
fp = sp;
|
||||||
fp = sp;
|
sp = sp->next;
|
||||||
sp = sp->next;
|
free(fp);
|
||||||
free(fp);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
iax_mutex_unlock(sched_mutex);
|
||||||
|
|
||||||
if (netfd > -1) {
|
if (netfd > -1) {
|
||||||
shutdown(netfd, 2);
|
shutdown(netfd, 2);
|
||||||
|
@ -893,6 +920,9 @@ int __iax_shutdown(void)
|
||||||
|
|
||||||
time_end();
|
time_end();
|
||||||
|
|
||||||
|
iax_mutex_destroy(sched_mutex);
|
||||||
|
iax_mutex_destroy(session_mutex);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -910,6 +940,9 @@ int iax_init(char *ip, int preferredportno)
|
||||||
|
|
||||||
init_time();
|
init_time();
|
||||||
|
|
||||||
|
iax_mutex_create(&sched_mutex);
|
||||||
|
iax_mutex_create(&session_mutex);
|
||||||
|
|
||||||
if(iax_recvfrom == (recvfrom_t) recvfrom) {
|
if(iax_recvfrom == (recvfrom_t) recvfrom) {
|
||||||
if (netfd > -1) {
|
if (netfd > -1) {
|
||||||
/* Sokay, just don't do anything */
|
/* Sokay, just don't do anything */
|
||||||
|
@ -1229,12 +1262,14 @@ static void stop_transfer(struct iax_session *session)
|
||||||
{
|
{
|
||||||
struct iax_sched *sch;
|
struct iax_sched *sch;
|
||||||
|
|
||||||
|
iax_mutex_lock(sched_mutex);
|
||||||
sch = schedq;
|
sch = schedq;
|
||||||
while(sch) {
|
while(sch) {
|
||||||
if (sch->frame && (sch->frame->session == session))
|
if (sch->frame && (sch->frame->session == session))
|
||||||
sch->frame->retries = -1;
|
sch->frame->retries = -1;
|
||||||
sch = sch->next;
|
sch = sch->next;
|
||||||
}
|
}
|
||||||
|
iax_mutex_unlock(sched_mutex);
|
||||||
} /* stop_transfer */
|
} /* stop_transfer */
|
||||||
|
|
||||||
static void complete_transfer(struct iax_session *session, int peercallno, int xfr2peer, int preserveSeq)
|
static void complete_transfer(struct iax_session *session, int peercallno, int xfr2peer, int preserveSeq)
|
||||||
|
@ -1356,14 +1391,18 @@ static int iax_finish_transfer(struct iax_session *s, short new_peer)
|
||||||
|
|
||||||
static struct iax_session *iax_find_session2(short callno)
|
static struct iax_session *iax_find_session2(short callno)
|
||||||
{
|
{
|
||||||
struct iax_session *cur = sessions;
|
struct iax_session *cur;
|
||||||
|
|
||||||
|
iax_mutex_lock(session_mutex);
|
||||||
|
cur = sessions;
|
||||||
while(cur) {
|
while(cur) {
|
||||||
if (callno == cur->callno && callno != 0) {
|
if (callno == cur->callno && callno != 0) {
|
||||||
|
iax_mutex_unlock(session_mutex);
|
||||||
return cur;
|
return cur;
|
||||||
}
|
}
|
||||||
cur = cur->next;
|
cur = cur->next;
|
||||||
}
|
}
|
||||||
|
iax_mutex_unlock(session_mutex);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -1431,6 +1470,8 @@ static void destroy_session(struct iax_session *session)
|
||||||
struct iax_session *cur, *prev=NULL;
|
struct iax_session *cur, *prev=NULL;
|
||||||
struct iax_sched *curs, *prevs=NULL, *nexts=NULL;
|
struct iax_sched *curs, *prevs=NULL, *nexts=NULL;
|
||||||
int loop_cnt=0;
|
int loop_cnt=0;
|
||||||
|
|
||||||
|
iax_mutex_lock(sched_mutex);
|
||||||
curs = schedq;
|
curs = schedq;
|
||||||
while(curs) {
|
while(curs) {
|
||||||
nexts = curs->next;
|
nexts = curs->next;
|
||||||
|
@ -1451,7 +1492,9 @@ static void destroy_session(struct iax_session *session)
|
||||||
curs = nexts;
|
curs = nexts;
|
||||||
loop_cnt++;
|
loop_cnt++;
|
||||||
}
|
}
|
||||||
|
iax_mutex_unlock(sched_mutex);
|
||||||
|
|
||||||
|
|
||||||
cur = sessions;
|
cur = sessions;
|
||||||
while(cur) {
|
while(cur) {
|
||||||
if (cur == session) {
|
if (cur == session) {
|
||||||
|
@ -2081,9 +2124,13 @@ static struct iax_session *iax_find_session(struct sockaddr_in *sin,
|
||||||
short dcallno,
|
short dcallno,
|
||||||
int makenew)
|
int makenew)
|
||||||
{
|
{
|
||||||
struct iax_session *cur = sessions;
|
struct iax_session *cur;
|
||||||
|
|
||||||
|
iax_mutex_lock(session_mutex);
|
||||||
|
cur = sessions;
|
||||||
while(cur) {
|
while(cur) {
|
||||||
if (forward_match(sin, callno, dcallno, cur)) {
|
if (forward_match(sin, callno, dcallno, cur)) {
|
||||||
|
iax_mutex_unlock(session_mutex);
|
||||||
return cur;
|
return cur;
|
||||||
}
|
}
|
||||||
cur = cur->next;
|
cur = cur->next;
|
||||||
|
@ -2092,11 +2139,14 @@ static struct iax_session *iax_find_session(struct sockaddr_in *sin,
|
||||||
cur = sessions;
|
cur = sessions;
|
||||||
while(cur) {
|
while(cur) {
|
||||||
if (reverse_match(sin, callno, cur)) {
|
if (reverse_match(sin, callno, cur)) {
|
||||||
|
iax_mutex_unlock(session_mutex);
|
||||||
return cur;
|
return cur;
|
||||||
}
|
}
|
||||||
cur = cur->next;
|
cur = cur->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
iax_mutex_unlock(session_mutex);
|
||||||
|
|
||||||
if (makenew && !dcallno) {
|
if (makenew && !dcallno) {
|
||||||
cur = iax_session_new();
|
cur = iax_session_new();
|
||||||
cur->peercallno = callno;
|
cur->peercallno = callno;
|
||||||
|
@ -2108,6 +2158,7 @@ static struct iax_session *iax_find_session(struct sockaddr_in *sin,
|
||||||
} else {
|
} else {
|
||||||
DEBU(G "No session, peer = %d, us = %d\n", callno, dcallno);
|
DEBU(G "No session, peer = %d, us = %d\n", callno, dcallno);
|
||||||
}
|
}
|
||||||
|
|
||||||
return cur;
|
return cur;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2428,6 +2479,7 @@ static struct iax_event *iax_header_to_event(struct iax_session *session,
|
||||||
for (x=session->rseqno; x != fh->iseqno; x++) {
|
for (x=session->rseqno; x != fh->iseqno; x++) {
|
||||||
/* Ack the packet with the given timestamp */
|
/* Ack the packet with the given timestamp */
|
||||||
DEBU(G "Cancelling transmission of packet %d\n", x);
|
DEBU(G "Cancelling transmission of packet %d\n", x);
|
||||||
|
iax_mutex_lock(sched_mutex);
|
||||||
sch = schedq;
|
sch = schedq;
|
||||||
while(sch) {
|
while(sch) {
|
||||||
if (sch->frame && (sch->frame->session == session) &&
|
if (sch->frame && (sch->frame->session == session) &&
|
||||||
|
@ -2435,6 +2487,7 @@ static struct iax_event *iax_header_to_event(struct iax_session *session,
|
||||||
sch->frame->retries = -1;
|
sch->frame->retries = -1;
|
||||||
sch = sch->next;
|
sch = sch->next;
|
||||||
}
|
}
|
||||||
|
iax_mutex_unlock(sched_mutex);
|
||||||
}
|
}
|
||||||
/* Note how much we've received acknowledgement for */
|
/* Note how much we've received acknowledgement for */
|
||||||
session->rseqno = fh->iseqno;
|
session->rseqno = fh->iseqno;
|
||||||
|
@ -2846,15 +2899,17 @@ static struct iax_event *iax_miniheader_to_event(struct iax_session *session,
|
||||||
|
|
||||||
void iax_destroy(struct iax_session *session)
|
void iax_destroy(struct iax_session *session)
|
||||||
{
|
{
|
||||||
|
iax_mutex_lock(session_mutex);
|
||||||
destroy_session(session);
|
destroy_session(session);
|
||||||
|
iax_mutex_unlock(session_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct iax_event *iax_net_read(void)
|
static struct iax_event *iax_net_read(void)
|
||||||
{
|
{
|
||||||
unsigned char buf[65536];
|
unsigned char buf[65536];
|
||||||
int res;
|
int res, sinlen;
|
||||||
struct sockaddr_in sin;
|
struct sockaddr_in sin;
|
||||||
unsigned int sinlen;
|
|
||||||
sinlen = sizeof(sin);
|
sinlen = sizeof(sin);
|
||||||
res = iax_recvfrom(netfd, buf, sizeof(buf), 0, (struct sockaddr *) &sin, &sinlen);
|
res = iax_recvfrom(netfd, buf, sizeof(buf), 0, (struct sockaddr *) &sin, &sinlen);
|
||||||
|
|
||||||
|
@ -2894,6 +2949,7 @@ static struct iax_session *iax_txcnt_session(struct ast_iax2_full_hdr *fh, int d
|
||||||
if (!ies.transferid) {
|
if (!ies.transferid) {
|
||||||
return NULL; /* TXCNT without proper IAX_IE_TRANSFERID */
|
return NULL; /* TXCNT without proper IAX_IE_TRANSFERID */
|
||||||
}
|
}
|
||||||
|
iax_mutex_lock(session_mutex);
|
||||||
for( cur=sessions; cur; cur=cur->next ) {
|
for( cur=sessions; cur; cur=cur->next ) {
|
||||||
if ((cur->transferring) && (cur->transferid == ies.transferid) &&
|
if ((cur->transferring) && (cur->transferid == ies.transferid) &&
|
||||||
(cur->callno == dcallno) && (cur->transfercallno == callno)) {
|
(cur->callno == dcallno) && (cur->transfercallno == callno)) {
|
||||||
|
@ -2906,6 +2962,7 @@ static struct iax_session *iax_txcnt_session(struct ast_iax2_full_hdr *fh, int d
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
iax_mutex_unlock(session_mutex);
|
||||||
return cur;
|
return cur;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2958,6 +3015,7 @@ struct iax_event *iax_net_process(unsigned char *buf, int len, struct sockaddr_i
|
||||||
static struct iax_sched *iax_get_sched(time_in_ms_t time_in_ms)
|
static struct iax_sched *iax_get_sched(time_in_ms_t time_in_ms)
|
||||||
{
|
{
|
||||||
struct iax_sched *cur, *prev=NULL;
|
struct iax_sched *cur, *prev=NULL;
|
||||||
|
iax_mutex_lock(sched_mutex);
|
||||||
cur = schedq;
|
cur = schedq;
|
||||||
/* Check the event schedule first. */
|
/* Check the event schedule first. */
|
||||||
while(cur) {
|
while(cur) {
|
||||||
|
@ -2968,10 +3026,12 @@ static struct iax_sched *iax_get_sched(time_in_ms_t time_in_ms)
|
||||||
} else {
|
} else {
|
||||||
schedq = cur->next;
|
schedq = cur->next;
|
||||||
}
|
}
|
||||||
|
iax_mutex_unlock(sched_mutex);
|
||||||
return cur;
|
return cur;
|
||||||
}
|
}
|
||||||
cur = cur->next;
|
cur = cur->next;
|
||||||
}
|
}
|
||||||
|
iax_mutex_unlock(sched_mutex);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3005,8 +3065,11 @@ struct iax_event *iax_get_event(int blocking)
|
||||||
if (frame->retries < 0) {
|
if (frame->retries < 0) {
|
||||||
/* It's been acked. No need to send it. Destroy the old
|
/* It's been acked. No need to send it. Destroy the old
|
||||||
frame. If final, destroy the session. */
|
frame. If final, destroy the session. */
|
||||||
if (frame->final)
|
if (frame->final) {
|
||||||
|
iax_mutex_lock(session_mutex);
|
||||||
destroy_session(frame->session);
|
destroy_session(frame->session);
|
||||||
|
iax_mutex_unlock(session_mutex);
|
||||||
|
}
|
||||||
if (frame->data)
|
if (frame->data)
|
||||||
free(frame->data);
|
free(frame->data);
|
||||||
free(frame);
|
free(frame);
|
||||||
|
@ -3023,7 +3086,9 @@ struct iax_event *iax_get_event(int blocking)
|
||||||
/* We haven't been able to get an ACK on this packet. If a
|
/* We haven't been able to get an ACK on this packet. If a
|
||||||
final frame, destroy the session, otherwise, pass up timeout */
|
final frame, destroy the session, otherwise, pass up timeout */
|
||||||
if (frame->final) {
|
if (frame->final) {
|
||||||
|
iax_mutex_lock(session_mutex);
|
||||||
destroy_session(frame->session);
|
destroy_session(frame->session);
|
||||||
|
iax_mutex_unlock(session_mutex);
|
||||||
if (frame->data)
|
if (frame->data)
|
||||||
free(frame->data);
|
free(frame->data);
|
||||||
free(frame);
|
free(frame);
|
||||||
|
@ -3070,54 +3135,59 @@ struct iax_event *iax_get_event(int blocking)
|
||||||
{
|
{
|
||||||
struct iax_session *cur;
|
struct iax_session *cur;
|
||||||
jb_frame frame;
|
jb_frame frame;
|
||||||
|
iax_mutex_lock(session_mutex);
|
||||||
for(cur=sessions; cur; cur=cur->next) {
|
for(cur=sessions; cur; cur=cur->next) {
|
||||||
int ret;
|
int ret;
|
||||||
time_in_ms_t now;
|
time_in_ms_t now;
|
||||||
time_in_ms_t next;
|
time_in_ms_t next;
|
||||||
|
|
||||||
now = time_in_ms - cur->rxcore;
|
now = time_in_ms - cur->rxcore;
|
||||||
if(now > (next = jb_next(cur->jb))) {
|
if(now > (next = jb_next(cur->jb))) {
|
||||||
/* FIXME don't hardcode interpolation frame length in jb_get */
|
/* FIXME don't hardcode interpolation frame length in jb_get */
|
||||||
ret = jb_get(cur->jb,&frame,now,20);
|
ret = jb_get(cur->jb,&frame,now,20);
|
||||||
switch(ret) {
|
switch(ret) {
|
||||||
case JB_OK:
|
case JB_OK:
|
||||||
// if(frame.type == JB_TYPE_VOICE && next + 20 != jb_next(cur->jb)) fprintf(stderr, "NEXT %ld is not %ld+20!\n", jb_next(cur->jb), next);
|
// if(frame.type == JB_TYPE_VOICE && next + 20 != jb_next(cur->jb)) fprintf(stderr, "NEXT %ld is not %ld+20!\n", jb_next(cur->jb), next);
|
||||||
event = frame.data;
|
event = frame.data;
|
||||||
event = handle_event(event);
|
event = handle_event(event);
|
||||||
if (event) {
|
if (event) {
|
||||||
return event;
|
iax_mutex_unlock(session_mutex);
|
||||||
}
|
return event;
|
||||||
break;
|
}
|
||||||
case JB_INTERP:
|
break;
|
||||||
// if(next + 20 != jb_next(cur->jb)) fprintf(stderr, "NEXT %ld is not %ld+20!\n", jb_next(cur->jb), next);
|
case JB_INTERP:
|
||||||
/* create an interpolation frame */
|
// if(next + 20 != jb_next(cur->jb)) fprintf(stderr, "NEXT %ld is not %ld+20!\n", jb_next(cur->jb), next);
|
||||||
//fprintf(stderr, "Making Interpolation frame\n");
|
/* create an interpolation frame */
|
||||||
event = (struct iax_event *)malloc(sizeof(struct iax_event));
|
//fprintf(stderr, "Making Interpolation frame\n");
|
||||||
if (event) {
|
event = (struct iax_event *)malloc(sizeof(struct iax_event));
|
||||||
event->etype = IAX_EVENT_VOICE;
|
if (event) {
|
||||||
event->subclass = cur->voiceformat;
|
event->etype = IAX_EVENT_VOICE;
|
||||||
event->ts = now; /* XXX: ??? applications probably ignore this anyway */
|
event->subclass = cur->voiceformat;
|
||||||
event->session = cur;
|
event->ts = now; /* XXX: ??? applications probably ignore this anyway */
|
||||||
event->datalen = 0;
|
event->session = cur;
|
||||||
event = handle_event(event);
|
event->datalen = 0;
|
||||||
if(event)
|
event = handle_event(event);
|
||||||
return event;
|
if(event) {
|
||||||
}
|
iax_mutex_unlock(session_mutex);
|
||||||
break;
|
return event;
|
||||||
case JB_DROP:
|
}
|
||||||
// if(next != jb_next(cur->jb)) fprintf(stderr, "NEXT %ld is not next %ld!\n", jb_next(cur->jb), next);
|
}
|
||||||
iax_event_free(frame.data);
|
break;
|
||||||
break;
|
case JB_DROP:
|
||||||
case JB_NOFRAME:
|
// if(next != jb_next(cur->jb)) fprintf(stderr, "NEXT %ld is not next %ld!\n", jb_next(cur->jb), next);
|
||||||
case JB_EMPTY:
|
iax_event_free(frame.data);
|
||||||
/* do nothing */
|
break;
|
||||||
break;
|
case JB_NOFRAME:
|
||||||
default:
|
case JB_EMPTY:
|
||||||
/* shouldn't happen */
|
/* do nothing */
|
||||||
break;
|
break;
|
||||||
}
|
default:
|
||||||
}
|
/* shouldn't happen */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
iax_mutex_unlock(session_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -3169,8 +3239,10 @@ char *iax_event_get_apparent_ip(struct iax_event *event)
|
||||||
|
|
||||||
void iax_session_destroy(struct iax_session **session)
|
void iax_session_destroy(struct iax_session **session)
|
||||||
{
|
{
|
||||||
|
iax_mutex_lock(session_mutex);
|
||||||
destroy_session(*session);
|
destroy_session(*session);
|
||||||
*session = NULL;
|
*session = NULL;
|
||||||
|
iax_mutex_unlock(session_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void iax_event_free(struct iax_event *event)
|
void iax_event_free(struct iax_event *event)
|
||||||
|
@ -3185,7 +3257,9 @@ void iax_event_free(struct iax_event *event)
|
||||||
case IAX_EVENT_HANGUP:
|
case IAX_EVENT_HANGUP:
|
||||||
/* Destroy this session -- it's no longer valid */
|
/* Destroy this session -- it's no longer valid */
|
||||||
if (event->session) { /* maybe the user did it already */
|
if (event->session) { /* maybe the user did it already */
|
||||||
|
iax_mutex_lock(session_mutex);
|
||||||
destroy_session(event->session);
|
destroy_session(event->session);
|
||||||
|
iax_mutex_unlock(session_mutex);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue