mirror of
https://github.com/asterisk/asterisk.git
synced 2025-11-01 11:32:25 +00:00
IAX2 updates, dial fix
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@873 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -241,7 +241,7 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in, struct localu
|
|||||||
case AST_CONTROL_RINGING:
|
case AST_CONTROL_RINGING:
|
||||||
if (option_verbose > 2)
|
if (option_verbose > 2)
|
||||||
ast_verbose( VERBOSE_PREFIX_3 "%s is ringing\n", o->chan->name);
|
ast_verbose( VERBOSE_PREFIX_3 "%s is ringing\n", o->chan->name);
|
||||||
if (!sentringing) {
|
if (!sentringing && !moh) {
|
||||||
ast_indicate(in, AST_CONTROL_RINGING);
|
ast_indicate(in, AST_CONTROL_RINGING);
|
||||||
sentringing++;
|
sentringing++;
|
||||||
ringind++;
|
ringind++;
|
||||||
|
|||||||
@@ -379,8 +379,8 @@ struct chan_iax2_pvt {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static struct ast_iax2_queue {
|
static struct ast_iax2_queue {
|
||||||
struct ast_iax2_frame *head;
|
struct iax_frame *head;
|
||||||
struct ast_iax2_frame *tail;
|
struct iax_frame *tail;
|
||||||
int count;
|
int count;
|
||||||
pthread_mutex_t lock;
|
pthread_mutex_t lock;
|
||||||
} iaxq;
|
} iaxq;
|
||||||
@@ -569,65 +569,13 @@ static int get_samples(struct ast_frame *f)
|
|||||||
return samples;
|
return samples;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int frames = 0;
|
static struct iax_frame *iaxfrdup2(struct iax_frame *fr)
|
||||||
static int iframes = 0;
|
|
||||||
static int oframes = 0;
|
|
||||||
|
|
||||||
static void ast_iax2_frame_wrap(struct ast_iax2_frame *fr, struct ast_frame *f)
|
|
||||||
{
|
|
||||||
fr->af.frametype = f->frametype;
|
|
||||||
fr->af.subclass = f->subclass;
|
|
||||||
fr->af.mallocd = 0; /* Our frame is static relative to the container */
|
|
||||||
fr->af.datalen = f->datalen;
|
|
||||||
fr->af.samples = f->samples;
|
|
||||||
fr->af.offset = AST_FRIENDLY_OFFSET;
|
|
||||||
fr->af.src = f->src;
|
|
||||||
fr->af.data = fr->afdata;
|
|
||||||
if (fr->af.datalen)
|
|
||||||
memcpy(fr->af.data, f->data, fr->af.datalen);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct ast_iax2_frame *ast_iax2_frame_new(int direction, int datalen)
|
|
||||||
{
|
|
||||||
struct ast_iax2_frame *fr;
|
|
||||||
fr = malloc(sizeof(struct ast_iax2_frame) + datalen);
|
|
||||||
if (fr) {
|
|
||||||
fr->direction = direction;
|
|
||||||
fr->retrans = -1;
|
|
||||||
frames++;
|
|
||||||
if (fr->direction == DIRECTION_INGRESS)
|
|
||||||
iframes++;
|
|
||||||
else
|
|
||||||
oframes++;
|
|
||||||
}
|
|
||||||
return fr;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ast_iax2_frame_free(struct ast_iax2_frame *fr)
|
|
||||||
{
|
|
||||||
if (fr->retrans > -1)
|
|
||||||
ast_sched_del(sched, fr->retrans);
|
|
||||||
if (fr->direction == DIRECTION_INGRESS)
|
|
||||||
iframes--;
|
|
||||||
else if (fr->direction == DIRECTION_OUTGRESS)
|
|
||||||
oframes--;
|
|
||||||
else {
|
|
||||||
ast_log(LOG_WARNING, "Attempt to double free frame detected\n");
|
|
||||||
CRASH;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
fr->direction = 0;
|
|
||||||
free(fr);
|
|
||||||
frames--;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct ast_iax2_frame *iaxfrdup2(struct ast_iax2_frame *fr)
|
|
||||||
{
|
{
|
||||||
/* Malloc() a copy of a frame */
|
/* Malloc() a copy of a frame */
|
||||||
struct ast_iax2_frame *new = ast_iax2_frame_new(DIRECTION_INGRESS, fr->af.datalen);
|
struct iax_frame *new = iax_frame_new(DIRECTION_INGRESS, fr->af.datalen);
|
||||||
if (new) {
|
if (new) {
|
||||||
memcpy(new, fr, sizeof(struct ast_iax2_frame));
|
memcpy(new, fr, sizeof(struct iax_frame));
|
||||||
ast_iax2_frame_wrap(new, &fr->af);
|
iax_frame_wrap(new, &fr->af);
|
||||||
new->data = NULL;
|
new->data = NULL;
|
||||||
new->datalen = 0;
|
new->datalen = 0;
|
||||||
new->direction = DIRECTION_INGRESS;
|
new->direction = DIRECTION_INGRESS;
|
||||||
@@ -802,6 +750,13 @@ static int find_callno(unsigned short callno, unsigned short dcallno, struct soc
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void iax2_frame_free(struct iax_frame *fr)
|
||||||
|
{
|
||||||
|
if (fr->retrans > -1)
|
||||||
|
ast_sched_del(sched, fr->retrans);
|
||||||
|
iax_frame_free(fr);
|
||||||
|
}
|
||||||
|
|
||||||
static int iax2_queue_frame(int callno, struct ast_frame *f)
|
static int iax2_queue_frame(int callno, struct ast_frame *f)
|
||||||
{
|
{
|
||||||
int pass =0;
|
int pass =0;
|
||||||
@@ -835,7 +790,7 @@ static int __do_deliver(void *data)
|
|||||||
{
|
{
|
||||||
/* Just deliver the packet by using queueing. This is called by
|
/* Just deliver the packet by using queueing. This is called by
|
||||||
the IAX thread with the iaxsl lock held. */
|
the IAX thread with the iaxsl lock held. */
|
||||||
struct ast_iax2_frame *fr = data;
|
struct iax_frame *fr = data;
|
||||||
unsigned int ts;
|
unsigned int ts;
|
||||||
fr->retrans = -1;
|
fr->retrans = -1;
|
||||||
if (iaxs[fr->callno] && !iaxs[fr->callno]->alreadygone) {
|
if (iaxs[fr->callno] && !iaxs[fr->callno]->alreadygone) {
|
||||||
@@ -856,7 +811,7 @@ static int __do_deliver(void *data)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Free our iax frame */
|
/* Free our iax frame */
|
||||||
ast_iax2_frame_free(fr);
|
iax2_frame_free(fr);
|
||||||
/* And don't run again */
|
/* And don't run again */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -864,7 +819,7 @@ static int __do_deliver(void *data)
|
|||||||
static int do_deliver(void *data)
|
static int do_deliver(void *data)
|
||||||
{
|
{
|
||||||
/* Locking version of __do_deliver */
|
/* Locking version of __do_deliver */
|
||||||
struct ast_iax2_frame *fr = data;
|
struct iax_frame *fr = data;
|
||||||
int callno = fr->callno;
|
int callno = fr->callno;
|
||||||
int res;
|
int res;
|
||||||
ast_pthread_mutex_lock(&iaxsl[callno]);
|
ast_pthread_mutex_lock(&iaxsl[callno]);
|
||||||
@@ -907,7 +862,7 @@ static int handle_error(void)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int send_packet(struct ast_iax2_frame *f)
|
static int send_packet(struct iax_frame *f)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
/* Called with iaxsl held */
|
/* Called with iaxsl held */
|
||||||
@@ -998,7 +953,7 @@ static int iax2_predestroy_nolock(int callno)
|
|||||||
static void iax2_destroy(int callno)
|
static void iax2_destroy(int callno)
|
||||||
{
|
{
|
||||||
struct chan_iax2_pvt *pvt;
|
struct chan_iax2_pvt *pvt;
|
||||||
struct ast_iax2_frame *cur;
|
struct iax_frame *cur;
|
||||||
struct ast_channel *owner;
|
struct ast_channel *owner;
|
||||||
|
|
||||||
retry:
|
retry:
|
||||||
@@ -1070,7 +1025,7 @@ static void iax2_destroy_nolock(int callno)
|
|||||||
ast_pthread_mutex_lock(&iaxsl[callno]);
|
ast_pthread_mutex_lock(&iaxsl[callno]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int update_packet(struct ast_iax2_frame *f)
|
static int update_packet(struct iax_frame *f)
|
||||||
{
|
{
|
||||||
/* Called with iaxsl lock held, and iaxs[callno] non-NULL */
|
/* Called with iaxsl lock held, and iaxs[callno] non-NULL */
|
||||||
struct ast_iax2_full_hdr *fh = f->data;
|
struct ast_iax2_full_hdr *fh = f->data;
|
||||||
@@ -1086,7 +1041,7 @@ static int attempt_transmit(void *data)
|
|||||||
{
|
{
|
||||||
/* Attempt to transmit the frame to the remote peer...
|
/* Attempt to transmit the frame to the remote peer...
|
||||||
Called without iaxsl held. */
|
Called without iaxsl held. */
|
||||||
struct ast_iax2_frame *f = data;
|
struct iax_frame *f = data;
|
||||||
int freeme=0;
|
int freeme=0;
|
||||||
int callno = f->callno;
|
int callno = f->callno;
|
||||||
/* Make sure this call is still active */
|
/* Make sure this call is still active */
|
||||||
@@ -1163,7 +1118,7 @@ static int attempt_transmit(void *data)
|
|||||||
ast_pthread_mutex_unlock(&iaxq.lock);
|
ast_pthread_mutex_unlock(&iaxq.lock);
|
||||||
f->retrans = -1;
|
f->retrans = -1;
|
||||||
/* Free the IAX frame */
|
/* Free the IAX frame */
|
||||||
ast_iax2_frame_free(f);
|
iax2_frame_free(f);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -1201,7 +1156,7 @@ static char jitter_usage[] =
|
|||||||
|
|
||||||
static int iax2_show_stats(int fd, int argc, char *argv[])
|
static int iax2_show_stats(int fd, int argc, char *argv[])
|
||||||
{
|
{
|
||||||
struct ast_iax2_frame *cur;
|
struct iax_frame *cur;
|
||||||
int cnt = 0, dead=0, final=0;
|
int cnt = 0, dead=0, final=0;
|
||||||
if (argc != 3)
|
if (argc != 3)
|
||||||
return RESULT_SHOWUSAGE;
|
return RESULT_SHOWUSAGE;
|
||||||
@@ -1214,7 +1169,7 @@ static int iax2_show_stats(int fd, int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
ast_cli(fd, " IAX Statistics\n");
|
ast_cli(fd, " IAX Statistics\n");
|
||||||
ast_cli(fd, "---------------------\n");
|
ast_cli(fd, "---------------------\n");
|
||||||
ast_cli(fd, "Outstanding frames: %d (%d ingress, %d outgress)\n", frames, iframes, oframes);
|
ast_cli(fd, "Outstanding frames: %d (%d ingress, %d outgress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes());
|
||||||
ast_cli(fd, "Packets in transmit queue: %d dead, %d final, %d total\n", dead, final, cnt);
|
ast_cli(fd, "Packets in transmit queue: %d dead, %d final, %d total\n", dead, final, cnt);
|
||||||
return RESULT_SUCCESS;
|
return RESULT_SUCCESS;
|
||||||
}
|
}
|
||||||
@@ -1296,7 +1251,7 @@ static unsigned int calc_rxstamp(struct chan_iax2_pvt *p);
|
|||||||
#ifdef BRIDGE_OPTIMIZATION
|
#ifdef BRIDGE_OPTIMIZATION
|
||||||
static unsigned int calc_fakestamp(struct chan_iax2_pvt *from, struct chan_iax2_pvt *to, unsigned int ts);
|
static unsigned int calc_fakestamp(struct chan_iax2_pvt *from, struct chan_iax2_pvt *to, unsigned int ts);
|
||||||
|
|
||||||
static int forward_delivery(struct ast_iax2_frame *fr)
|
static int forward_delivery(struct iax_frame *fr)
|
||||||
{
|
{
|
||||||
struct chan_iax2_pvt *p1, *p2;
|
struct chan_iax2_pvt *p1, *p2;
|
||||||
p1 = iaxs[fr->callno];
|
p1 = iaxs[fr->callno];
|
||||||
@@ -1313,7 +1268,7 @@ static int forward_delivery(struct ast_iax2_frame *fr)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int schedule_delivery(struct ast_iax2_frame *fr, int reallydeliver, int updatehistory)
|
static int schedule_delivery(struct iax_frame *fr, int reallydeliver, int updatehistory)
|
||||||
{
|
{
|
||||||
int ms,x;
|
int ms,x;
|
||||||
int drops[MEMORY_SIZE];
|
int drops[MEMORY_SIZE];
|
||||||
@@ -1434,7 +1389,7 @@ static int schedule_delivery(struct ast_iax2_frame *fr, int reallydeliver, int u
|
|||||||
if (option_debug)
|
if (option_debug)
|
||||||
ast_log(LOG_DEBUG, "Dropping voice packet since %d ms is, too old\n", ms);
|
ast_log(LOG_DEBUG, "Dropping voice packet since %d ms is, too old\n", ms);
|
||||||
/* Free our iax frame */
|
/* Free our iax frame */
|
||||||
ast_iax2_frame_free(fr);
|
iax2_frame_free(fr);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (option_debug)
|
if (option_debug)
|
||||||
@@ -1444,7 +1399,7 @@ static int schedule_delivery(struct ast_iax2_frame *fr, int reallydeliver, int u
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int iax2_transmit(struct ast_iax2_frame *fr)
|
static int iax2_transmit(struct iax_frame *fr)
|
||||||
{
|
{
|
||||||
/* Lock the queue and place this packet at the end */
|
/* Lock the queue and place this packet at the end */
|
||||||
fr->next = NULL;
|
fr->next = NULL;
|
||||||
@@ -2136,8 +2091,8 @@ static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned in
|
|||||||
struct ast_iax2_full_hdr *fh;
|
struct ast_iax2_full_hdr *fh;
|
||||||
struct ast_iax2_mini_hdr *mh;
|
struct ast_iax2_mini_hdr *mh;
|
||||||
unsigned char buffer[4096]; /* Buffer -- must preceed fr2 */
|
unsigned char buffer[4096]; /* Buffer -- must preceed fr2 */
|
||||||
struct ast_iax2_frame fr2;
|
struct iax_frame fr2;
|
||||||
struct ast_iax2_frame *fr;
|
struct iax_frame *fr;
|
||||||
int res;
|
int res;
|
||||||
int sendmini=0;
|
int sendmini=0;
|
||||||
unsigned int lastsent;
|
unsigned int lastsent;
|
||||||
@@ -2166,23 +2121,23 @@ static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned in
|
|||||||
/* Mark that mini-style frame is appropriate */
|
/* Mark that mini-style frame is appropriate */
|
||||||
sendmini = 1;
|
sendmini = 1;
|
||||||
}
|
}
|
||||||
/* Allocate an ast_iax2_frame */
|
/* Allocate an iax_frame */
|
||||||
if (now) {
|
if (now) {
|
||||||
fr = &fr2;
|
fr = &fr2;
|
||||||
} else
|
} else
|
||||||
fr = ast_iax2_frame_new(DIRECTION_OUTGRESS, f->datalen);
|
fr = iax_frame_new(DIRECTION_OUTGRESS, f->datalen);
|
||||||
if (!fr) {
|
if (!fr) {
|
||||||
ast_log(LOG_WARNING, "Out of memory\n");
|
ast_log(LOG_WARNING, "Out of memory\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
/* Copy our prospective frame into our immediate or retransmitted wrapper */
|
/* Copy our prospective frame into our immediate or retransmitted wrapper */
|
||||||
ast_iax2_frame_wrap(fr, f);
|
iax_frame_wrap(fr, f);
|
||||||
|
|
||||||
fr->ts = fts;
|
fr->ts = fts;
|
||||||
if (!fr->ts) {
|
if (!fr->ts) {
|
||||||
ast_log(LOG_WARNING, "timestamp is 0?\n");
|
ast_log(LOG_WARNING, "timestamp is 0?\n");
|
||||||
if (!now)
|
if (!now)
|
||||||
ast_iax2_frame_free(fr);
|
iax2_frame_free(fr);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
fr->callno = pvt->callno;
|
fr->callno = pvt->callno;
|
||||||
@@ -2704,7 +2659,6 @@ static int authenticate_verify(struct chan_iax2_pvt *p, struct iax_ies *ies)
|
|||||||
strncpy(md5secret, ies->md5_result, sizeof(md5secret)-1);
|
strncpy(md5secret, ies->md5_result, sizeof(md5secret)-1);
|
||||||
if (ies->rsa_result)
|
if (ies->rsa_result)
|
||||||
strncpy(rsasecret, ies->rsa_result, sizeof(rsasecret)-1);
|
strncpy(rsasecret, ies->rsa_result, sizeof(rsasecret)-1);
|
||||||
printf("Auth methods: %d, rsasecret: %s, inkeys: %s\n", p->authmethods, rsasecret, p->inkeys);
|
|
||||||
if ((p->authmethods & IAX_AUTH_RSA) && strlen(rsasecret) && strlen(p->inkeys)) {
|
if ((p->authmethods & IAX_AUTH_RSA) && strlen(rsasecret) && strlen(p->inkeys)) {
|
||||||
struct ast_key *key;
|
struct ast_key *key;
|
||||||
char *keyn;
|
char *keyn;
|
||||||
@@ -3046,7 +3000,7 @@ static int complete_transfer(int callno, struct iax_ies *ies)
|
|||||||
{
|
{
|
||||||
int peercallno = 0;
|
int peercallno = 0;
|
||||||
struct chan_iax2_pvt *pvt = iaxs[callno];
|
struct chan_iax2_pvt *pvt = iaxs[callno];
|
||||||
struct ast_iax2_frame *cur;
|
struct iax_frame *cur;
|
||||||
|
|
||||||
if (ies->callno)
|
if (ies->callno)
|
||||||
peercallno = ies->callno;
|
peercallno = ies->callno;
|
||||||
@@ -3378,7 +3332,7 @@ static int iax2_vnak(int callno)
|
|||||||
|
|
||||||
static void vnak_retransmit(int callno, int last)
|
static void vnak_retransmit(int callno, int last)
|
||||||
{
|
{
|
||||||
struct ast_iax2_frame *f;
|
struct iax_frame *f;
|
||||||
ast_pthread_mutex_lock(&iaxq.lock);
|
ast_pthread_mutex_lock(&iaxq.lock);
|
||||||
f = iaxq.head;
|
f = iaxq.head;
|
||||||
while(f) {
|
while(f) {
|
||||||
@@ -3406,15 +3360,15 @@ static int send_trunk(struct iax2_peer *peer)
|
|||||||
int calls = 0;
|
int calls = 0;
|
||||||
int res = 0;
|
int res = 0;
|
||||||
int firstcall = 0;
|
int firstcall = 0;
|
||||||
unsigned char buf[65536 + sizeof(struct ast_iax2_frame)], *ptr;
|
unsigned char buf[65536 + sizeof(struct iax_frame)], *ptr;
|
||||||
int len = 65536;
|
int len = 65536;
|
||||||
struct ast_iax2_frame *fr;
|
struct iax_frame *fr;
|
||||||
struct ast_iax2_meta_hdr *meta;
|
struct ast_iax2_meta_hdr *meta;
|
||||||
struct ast_iax2_meta_trunk_hdr *mth;
|
struct ast_iax2_meta_trunk_hdr *mth;
|
||||||
struct ast_iax2_meta_trunk_entry *met;
|
struct ast_iax2_meta_trunk_entry *met;
|
||||||
|
|
||||||
/* Point to frame */
|
/* Point to frame */
|
||||||
fr = (struct ast_iax2_frame *)buf;
|
fr = (struct iax_frame *)buf;
|
||||||
/* Point to meta data */
|
/* Point to meta data */
|
||||||
meta = (struct ast_iax2_meta_hdr *)fr->afdata;
|
meta = (struct ast_iax2_meta_hdr *)fr->afdata;
|
||||||
mth = (struct ast_iax2_meta_trunk_hdr *)meta->data;
|
mth = (struct ast_iax2_meta_trunk_hdr *)meta->data;
|
||||||
@@ -3540,8 +3494,8 @@ static int socket_read(int *id, int fd, short events, void *cbdata)
|
|||||||
struct ast_iax2_meta_trunk_hdr *mth;
|
struct ast_iax2_meta_trunk_hdr *mth;
|
||||||
struct ast_iax2_meta_trunk_entry *mte;
|
struct ast_iax2_meta_trunk_entry *mte;
|
||||||
char dblbuf[4096]; /* Declaration of dblbuf must immediately *preceed* fr on the stack */
|
char dblbuf[4096]; /* Declaration of dblbuf must immediately *preceed* fr on the stack */
|
||||||
struct ast_iax2_frame fr;
|
struct iax_frame fr;
|
||||||
struct ast_iax2_frame *cur;
|
struct iax_frame *cur;
|
||||||
struct ast_frame f;
|
struct ast_frame f;
|
||||||
struct ast_channel *c;
|
struct ast_channel *c;
|
||||||
struct iax2_dpcache *dp;
|
struct iax2_dpcache *dp;
|
||||||
@@ -3628,7 +3582,7 @@ static int socket_read(int *id, int fd, short events, void *cbdata)
|
|||||||
else
|
else
|
||||||
f.samples = 0;
|
f.samples = 0;
|
||||||
fr.outoforder = 0;
|
fr.outoforder = 0;
|
||||||
ast_iax2_frame_wrap(&fr, &f);
|
iax_frame_wrap(&fr, &f);
|
||||||
#ifdef BRIDGE_OPTIMIZATION
|
#ifdef BRIDGE_OPTIMIZATION
|
||||||
if (iaxs[fr.callno]->bridgecallno) {
|
if (iaxs[fr.callno]->bridgecallno) {
|
||||||
forward_delivery(&fr);
|
forward_delivery(&fr);
|
||||||
@@ -4113,7 +4067,7 @@ static int socket_read(int *id, int fd, short events, void *cbdata)
|
|||||||
f.mallocd = 0;
|
f.mallocd = 0;
|
||||||
f.offset = 0;
|
f.offset = 0;
|
||||||
f.samples = 0;
|
f.samples = 0;
|
||||||
ast_iax2_frame_wrap(&fr, &f);
|
iax_frame_wrap(&fr, &f);
|
||||||
schedule_delivery(iaxfrdup2(&fr), 1, updatehistory);
|
schedule_delivery(iaxfrdup2(&fr), 1, updatehistory);
|
||||||
#ifdef BRIDGE_OPTIMIZATION
|
#ifdef BRIDGE_OPTIMIZATION
|
||||||
}
|
}
|
||||||
@@ -4383,7 +4337,7 @@ static int socket_read(int *id, int fd, short events, void *cbdata)
|
|||||||
f.samples = get_samples(&f);
|
f.samples = get_samples(&f);
|
||||||
else
|
else
|
||||||
f.samples = 0;
|
f.samples = 0;
|
||||||
ast_iax2_frame_wrap(&fr, &f);
|
iax_frame_wrap(&fr, &f);
|
||||||
|
|
||||||
/* If this is our most recent packet, use it as our basis for timestamping */
|
/* If this is our most recent packet, use it as our basis for timestamping */
|
||||||
if (iaxs[fr.callno]->last < fr.ts) {
|
if (iaxs[fr.callno]->last < fr.ts) {
|
||||||
@@ -4560,7 +4514,7 @@ static void *network_thread(void *ignore)
|
|||||||
/* Our job is simple: Send queued messages, retrying if necessary. Read frames
|
/* Our job is simple: Send queued messages, retrying if necessary. Read frames
|
||||||
from the network, and queue them for delivery to the channels */
|
from the network, and queue them for delivery to the channels */
|
||||||
int res;
|
int res;
|
||||||
struct ast_iax2_frame *f, *freeme;
|
struct iax_frame *f, *freeme;
|
||||||
/* Establish I/O callback for socket read */
|
/* Establish I/O callback for socket read */
|
||||||
ast_io_add(io, netsocket, socket_read, AST_IO_IN, NULL);
|
ast_io_add(io, netsocket, socket_read, AST_IO_IN, NULL);
|
||||||
if (timingfd > -1)
|
if (timingfd > -1)
|
||||||
@@ -4599,7 +4553,7 @@ static void *network_thread(void *ignore)
|
|||||||
}
|
}
|
||||||
f = f->next;
|
f = f->next;
|
||||||
if (freeme)
|
if (freeme)
|
||||||
ast_iax2_frame_free(freeme);
|
iax_frame_free(freeme);
|
||||||
}
|
}
|
||||||
ast_pthread_mutex_unlock(&iaxq.lock);
|
ast_pthread_mutex_unlock(&iaxq.lock);
|
||||||
res = ast_sched_wait(sched);
|
res = ast_sched_wait(sched);
|
||||||
|
|||||||
@@ -23,6 +23,10 @@
|
|||||||
#include "iax2-parser.h"
|
#include "iax2-parser.h"
|
||||||
|
|
||||||
|
|
||||||
|
static int frames = 0;
|
||||||
|
static int iframes = 0;
|
||||||
|
static int oframes = 0;
|
||||||
|
|
||||||
static void internaloutput(const char *str)
|
static void internaloutput(const char *str)
|
||||||
{
|
{
|
||||||
printf(str);
|
printf(str);
|
||||||
@@ -165,7 +169,7 @@ static void dump_ies(unsigned char *iedata, int len)
|
|||||||
outputf("\n");
|
outputf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void iax_showframe(struct ast_iax2_frame *f, struct ast_iax2_full_hdr *fhi, int rx, struct sockaddr_in *sin, int datalen)
|
void iax_showframe(struct iax_frame *f, struct ast_iax2_full_hdr *fhi, int rx, struct sockaddr_in *sin, int datalen)
|
||||||
{
|
{
|
||||||
char *frames[] = {
|
char *frames[] = {
|
||||||
"(0?)",
|
"(0?)",
|
||||||
@@ -504,3 +508,52 @@ int iax_parse_ies(struct iax_ies *ies, unsigned char *data, int datalen)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void iax_frame_wrap(struct iax_frame *fr, struct ast_frame *f)
|
||||||
|
{
|
||||||
|
fr->af.frametype = f->frametype;
|
||||||
|
fr->af.subclass = f->subclass;
|
||||||
|
fr->af.mallocd = 0; /* Our frame is static relative to the container */
|
||||||
|
fr->af.datalen = f->datalen;
|
||||||
|
fr->af.samples = f->samples;
|
||||||
|
fr->af.offset = AST_FRIENDLY_OFFSET;
|
||||||
|
fr->af.src = f->src;
|
||||||
|
fr->af.data = fr->afdata;
|
||||||
|
if (fr->af.datalen)
|
||||||
|
memcpy(fr->af.data, f->data, fr->af.datalen);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct iax_frame *iax_frame_new(int direction, int datalen)
|
||||||
|
{
|
||||||
|
struct iax_frame *fr;
|
||||||
|
fr = malloc(sizeof(struct iax_frame) + datalen);
|
||||||
|
if (fr) {
|
||||||
|
fr->direction = direction;
|
||||||
|
fr->retrans = -1;
|
||||||
|
frames++;
|
||||||
|
if (fr->direction == DIRECTION_INGRESS)
|
||||||
|
iframes++;
|
||||||
|
else
|
||||||
|
oframes++;
|
||||||
|
}
|
||||||
|
return fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void iax_frame_free(struct iax_frame *fr)
|
||||||
|
{
|
||||||
|
/* Note: does not remove from scheduler! */
|
||||||
|
if (fr->direction == DIRECTION_INGRESS)
|
||||||
|
iframes--;
|
||||||
|
else if (fr->direction == DIRECTION_OUTGRESS)
|
||||||
|
oframes--;
|
||||||
|
else {
|
||||||
|
errorf("Attempt to double free frame detected\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fr->direction = 0;
|
||||||
|
free(fr);
|
||||||
|
frames--;
|
||||||
|
}
|
||||||
|
|
||||||
|
int iax_get_frames(void) { return frames; }
|
||||||
|
int iax_get_iframes(void) { return iframes; }
|
||||||
|
int iax_get_oframes(void) { return oframes; }
|
||||||
|
|||||||
@@ -47,7 +47,12 @@ struct iax_ies {
|
|||||||
#define DIRECTION_INGRESS 1
|
#define DIRECTION_INGRESS 1
|
||||||
#define DIRECTION_OUTGRESS 2
|
#define DIRECTION_OUTGRESS 2
|
||||||
|
|
||||||
struct ast_iax2_frame {
|
struct iax_frame {
|
||||||
|
#ifdef LIBIAX
|
||||||
|
struct iax_session *session;
|
||||||
|
struct iax_event *event;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* /Our/ call number */
|
/* /Our/ call number */
|
||||||
unsigned short callno;
|
unsigned short callno;
|
||||||
/* /Their/ call number */
|
/* /Their/ call number */
|
||||||
@@ -79,8 +84,8 @@ struct ast_iax2_frame {
|
|||||||
/* Retransmission ID */
|
/* Retransmission ID */
|
||||||
int retrans;
|
int retrans;
|
||||||
/* Easy linking */
|
/* Easy linking */
|
||||||
struct ast_iax2_frame *next;
|
struct iax_frame *next;
|
||||||
struct ast_iax2_frame *prev;
|
struct iax_frame *prev;
|
||||||
/* Actual, isolated frame header */
|
/* Actual, isolated frame header */
|
||||||
struct ast_frame af;
|
struct ast_frame af;
|
||||||
unsigned char unused[AST_FRIENDLY_OFFSET];
|
unsigned char unused[AST_FRIENDLY_OFFSET];
|
||||||
@@ -96,7 +101,7 @@ struct iax_ie_data {
|
|||||||
extern void iax_set_output(void (*output)(const char *data));
|
extern void iax_set_output(void (*output)(const char *data));
|
||||||
/* Choose a different function for errors */
|
/* Choose a different function for errors */
|
||||||
extern void iax_set_error(void (*output)(const char *data));
|
extern void iax_set_error(void (*output)(const char *data));
|
||||||
extern void iax_showframe(struct ast_iax2_frame *f, struct ast_iax2_full_hdr *fhi, int rx, struct sockaddr_in *sin, int datalen);
|
extern void iax_showframe(struct iax_frame *f, struct ast_iax2_full_hdr *fhi, int rx, struct sockaddr_in *sin, int datalen);
|
||||||
|
|
||||||
extern const char *iax_ie2str(int ie);
|
extern const char *iax_ie2str(int ie);
|
||||||
|
|
||||||
@@ -109,4 +114,11 @@ extern int iax_ie_append_byte(struct iax_ie_data *ied, unsigned char ie, unsigne
|
|||||||
extern int iax_ie_append(struct iax_ie_data *ied, unsigned char ie);
|
extern int iax_ie_append(struct iax_ie_data *ied, unsigned char ie);
|
||||||
extern int iax_parse_ies(struct iax_ies *ies, unsigned char *data, int datalen);
|
extern int iax_parse_ies(struct iax_ies *ies, unsigned char *data, int datalen);
|
||||||
|
|
||||||
|
extern int iax_get_frames(void);
|
||||||
|
extern int iax_get_iframes(void);
|
||||||
|
extern int iax_get_oframes(void);
|
||||||
|
|
||||||
|
extern void iax_frame_wrap(struct iax_frame *fr, struct ast_frame *f);
|
||||||
|
extern struct iax_frame *iax_frame_new(int direction, int datalen);
|
||||||
|
extern void iax_frame_free(struct iax_frame *fr);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user