aboutsummaryrefslogtreecommitdiffstats
path: root/channels
diff options
context:
space:
mode:
Diffstat (limited to 'channels')
-rw-r--r--channels/chan_iax2.c23
-rw-r--r--channels/chan_local.c25
-rw-r--r--channels/chan_misdn.c99
-rw-r--r--channels/chan_phone.c3
-rw-r--r--channels/chan_sip.c162
-rw-r--r--channels/chan_zap.c15
-rw-r--r--channels/misdn/chan_misdn_config.h2
-rw-r--r--channels/misdn/isdn_lib.c34
-rw-r--r--channels/misdn/isdn_msg_parser.c4
-rw-r--r--channels/misdn_config.c8
10 files changed, 225 insertions, 150 deletions
diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c
index 5e4648f37..e896abeb3 100644
--- a/channels/chan_iax2.c
+++ b/channels/chan_iax2.c
@@ -410,6 +410,7 @@ struct iax2_registry {
};
static struct iax2_registry *registrations;
+AST_MUTEX_DEFINE_STATIC(reg_lock);
/* Don't retry more frequently than every 10 ms, or less frequently than every 5 seconds */
#define MIN_RETRY_TIME 100
@@ -4399,8 +4400,8 @@ static int iax2_show_registry(int fd, int argc, char *argv[])
char iabuf[INET_ADDRSTRLEN];
if (argc != 3)
return RESULT_SHOWUSAGE;
- ast_mutex_lock(&peerl.lock);
ast_cli(fd, FORMAT2, "Host", "Username", "Perceived", "Refresh", "State");
+ ast_mutex_lock(&reg_lock);
for (reg = registrations;reg;reg = reg->next) {
snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(iabuf, sizeof(iabuf), reg->addr.sin_addr), ntohs(reg->addr.sin_port));
if (reg->us.sin_addr.s_addr)
@@ -4410,7 +4411,7 @@ static int iax2_show_registry(int fd, int argc, char *argv[])
ast_cli(fd, FORMAT, host,
reg->username, perceived, reg->refresh, regstate2str(reg->regstate));
}
- ast_mutex_unlock(&peerl.lock);
+ ast_mutex_unlock(&reg_lock);
return RESULT_SUCCESS;
#undef FORMAT
#undef FORMAT2
@@ -5624,9 +5625,11 @@ static int iax2_register(char *value, int lineno)
reg->addr.sin_family = AF_INET;
memcpy(&reg->addr.sin_addr, hp->h_addr, sizeof(&reg->addr.sin_addr));
reg->addr.sin_port = porta ? htons(atoi(porta)) : htons(IAX_DEFAULT_PORTNO);
+ ast_mutex_lock(&reg_lock);
reg->next = registrations;
reg->callno = 0;
registrations = reg;
+ ast_mutex_unlock(&reg_lock);
} else {
ast_log(LOG_ERROR, "Out of memory\n");
return -1;
@@ -7110,7 +7113,7 @@ retryowner:
if (!strcmp(ies.called_number, ast_parking_ext())) {
if (iax_park(ast_bridged_channel(iaxs[fr->callno]->owner), iaxs[fr->callno]->owner)) {
ast_log(LOG_WARNING, "Failed to park call on '%s'\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name);
- } else
+ } else if (ast_bridged_channel(iaxs[fr->callno]->owner))
ast_log(LOG_DEBUG, "Parked call on '%s'\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name);
} else {
if (ast_async_goto(ast_bridged_channel(iaxs[fr->callno]->owner), iaxs[fr->callno]->context, ies.called_number, 1))
@@ -8582,6 +8585,7 @@ static void delete_users(void)
user = user->next;
}
ast_mutex_unlock(&userl.lock);
+ ast_mutex_lock(&reg_lock);
for (reg = registrations;reg;) {
regl = reg;
reg = reg->next;
@@ -8600,6 +8604,7 @@ static void delete_users(void)
free(regl);
}
registrations = NULL;
+ ast_mutex_unlock(&reg_lock);
ast_mutex_lock(&peerl.lock);
for (peer=peerl.peers;peer;) {
/* Assume all will be deleted, and we'll find out for sure later */
@@ -8976,8 +8981,10 @@ static int reload_config(void)
set_config(config,1);
prune_peers();
prune_users();
+ ast_mutex_lock(&reg_lock);
for (reg = registrations; reg; reg = reg->next)
iax2_do_register(reg);
+ ast_mutex_unlock(&reg_lock);
/* Qualify hosts, too */
ast_mutex_lock(&peerl.lock);
for (peer = peerl.peers; peer; peer = peer->next)
@@ -9347,9 +9354,6 @@ static char *function_iaxpeer(struct ast_channel *chan, char *cmd, char *data, c
buf[0] = '\0';
- if (chan->tech != &iax2_tech)
- return buf;
-
if (!(peername = ast_strdupa(data))) {
ast_log(LOG_ERROR, "Memory Error!\n");
return ret;
@@ -9357,7 +9361,10 @@ static char *function_iaxpeer(struct ast_channel *chan, char *cmd, char *data, c
/* if our channel, return the IP address of the endpoint of current channel */
if (!strcmp(peername,"CURRENTCHANNEL")) {
- unsigned short callno = PTR_TO_CALLNO(chan->tech_pvt);
+ unsigned short callno;
+ if (chan->tech != &iax2_tech)
+ return buf;
+ callno = PTR_TO_CALLNO(chan->tech_pvt);
ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[callno]->addr.sin_addr) : "", len);
return buf;
}
@@ -9742,8 +9749,10 @@ int load_module(void)
ast_netsock_release(netsock);
}
+ ast_mutex_lock(&reg_lock);
for (reg = registrations; reg; reg = reg->next)
iax2_do_register(reg);
+ ast_mutex_unlock(&reg_lock);
ast_mutex_lock(&peerl.lock);
for (peer = peerl.peers; peer; peer = peer->next) {
if (peer->sockfd < 0)
diff --git a/channels/chan_local.c b/channels/chan_local.c
index 84fd9d220..b3bf3b24c 100644
--- a/channels/chan_local.c
+++ b/channels/chan_local.c
@@ -168,6 +168,9 @@ static int local_answer(struct ast_channel *ast)
int isoutbound;
int res = -1;
+ if (!p)
+ return -1;
+
ast_mutex_lock(&p->lock);
isoutbound = IS_OUTBOUND(ast, p);
if (isoutbound) {
@@ -245,6 +248,9 @@ static int local_write(struct ast_channel *ast, struct ast_frame *f)
int res = -1;
int isoutbound;
+ if (!p)
+ return -1;
+
/* Just queue for delivery to the other side */
ast_mutex_lock(&p->lock);
isoutbound = IS_OUTBOUND(ast, p);
@@ -263,6 +269,10 @@ static int local_write(struct ast_channel *ast, struct ast_frame *f)
static int local_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
{
struct local_pvt *p = newchan->tech_pvt;
+
+ if (!p)
+ return -1;
+
ast_mutex_lock(&p->lock);
if ((p->owner != oldchan) && (p->chan != oldchan)) {
@@ -285,6 +295,9 @@ static int local_indicate(struct ast_channel *ast, int condition)
struct ast_frame f = { AST_FRAME_CONTROL, };
int isoutbound;
+ if (!p)
+ return -1;
+
/* Queue up a frame representing the indication as a control frame */
ast_mutex_lock(&p->lock);
isoutbound = IS_OUTBOUND(ast, p);
@@ -301,6 +314,9 @@ static int local_digit(struct ast_channel *ast, char digit)
struct ast_frame f = { AST_FRAME_DTMF, };
int isoutbound;
+ if (!p)
+ return -1;
+
ast_mutex_lock(&p->lock);
isoutbound = IS_OUTBOUND(ast, p);
f.subclass = digit;
@@ -316,6 +332,9 @@ static int local_sendhtml(struct ast_channel *ast, int subclass, const char *dat
struct ast_frame f = { AST_FRAME_HTML, };
int isoutbound;
+ if (!p)
+ return -1;
+
ast_mutex_lock(&p->lock);
isoutbound = IS_OUTBOUND(ast, p);
f.subclass = subclass;
@@ -334,6 +353,9 @@ static int local_call(struct ast_channel *ast, char *dest, int timeout)
int res;
struct ast_var_t *varptr = NULL, *new;
size_t len, namelen;
+
+ if (!p)
+ return -1;
ast_mutex_lock(&p->lock);
@@ -410,6 +432,9 @@ static int local_hangup(struct ast_channel *ast)
struct ast_channel *ochan = NULL;
int glaredetect;
+ if (!p)
+ return -1;
+
ast_mutex_lock(&p->lock);
isoutbound = IS_OUTBOUND(ast, p);
if (isoutbound) {
diff --git a/channels/chan_misdn.c b/channels/chan_misdn.c
index 4f2fac442..9049ba753 100644
--- a/channels/chan_misdn.c
+++ b/channels/chan_misdn.c
@@ -796,8 +796,8 @@ static int misdn_show_cls (int fd, int argc, char *argv[])
print_bc_info(fd, help, bc);
} else {
if (help->state == MISDN_HOLDED) {
- chan_misdn_log(0, 0, "ITS A HOLDED BC:\n");
- chan_misdn_log(0,0," --> l3_id: %x\n"
+ chan_misdn_log(2, 0, "ITS A HOLDED BC:\n");
+ chan_misdn_log(2,0," --> l3_id: %x\n"
" --> dad:%s oad:%s\n"
,help->l3id
@@ -1220,8 +1220,7 @@ static int update_config (struct chan_list *ch, int orig)
int port=bc->port;
- chan_misdn_log(1,port,"update_config: Getting Config\n");
-
+ chan_misdn_log(7,port,"update_config: Getting Config\n");
int hdlc=0;
misdn_cfg_get( port, MISDN_CFG_HDLC, &hdlc, sizeof(int));
@@ -1635,7 +1634,7 @@ static int misdn_call(struct ast_channel *ast, char *dest, int timeout)
chan_misdn_log(1, port, "* CALL: %s\n",dest);
- chan_misdn_log(1, port, " --> * dad:%s tech:%s ctx:%s\n",ast->exten,ast->name, ast->context);
+ chan_misdn_log(2, port, " --> * dad:%s tech:%s ctx:%s\n",ast->exten,ast->name, ast->context);
chan_misdn_log(3, port, " --> * adding2newbc ext %s\n",ast->exten);
if (ast->exten) {
@@ -1691,7 +1690,7 @@ static int misdn_call(struct ast_channel *ast, char *dest, int timeout)
return -1;
}
- chan_misdn_log(1, port, " --> * SEND: State Dialing pid:%d\n",newbc?newbc->pid:1);
+ chan_misdn_log(2, port, " --> * SEND: State Dialing pid:%d\n",newbc?newbc->pid:1);
ast_setstate(ast, AST_STATE_DIALING);
ast->hangupcause=16;
@@ -1855,12 +1854,11 @@ static int misdn_indication(struct ast_channel *ast, int cond)
return -1;
}
- chan_misdn_log(1, p->bc->port, "* IND : Indication [%d] from %s\n",cond, ast->exten);
+ chan_misdn_log(5, p->bc->port, "* IND : Indication [%d] from %s\n",cond, ast->exten);
switch (cond) {
case AST_CONTROL_BUSY:
- chan_misdn_log(1, p->bc->port, "* IND :\tbusy\n");
- chan_misdn_log(1, p->bc->port, " --> * SEND: State Busy pid:%d\n",p->bc?p->bc->pid:-1);
+ chan_misdn_log(1, p->bc->port, "* IND :\tbusy pid:%d\n",p->bc?p->bc->pid:-1);
ast_setstate(ast,AST_STATE_BUSY);
p->bc->out_cause=17;
@@ -1873,41 +1871,42 @@ static int misdn_indication(struct ast_channel *ast, int cond)
return -1;
break;
case AST_CONTROL_RING:
- chan_misdn_log(1, p->bc->port, " --> * IND :\tring pid:%d\n",p->bc?p->bc->pid:-1);
+ chan_misdn_log(1, p->bc->port, "* IND :\tring pid:%d\n",p->bc?p->bc->pid:-1);
return -1;
break;
case AST_CONTROL_RINGING:
+ chan_misdn_log(1, p->bc->port, "* IND :\tringing pid:%d\n",p->bc?p->bc->pid:-1);
switch (p->state) {
case MISDN_ALERTING:
- chan_misdn_log(1, p->bc->port, " --> * IND :\tringing pid:%d but I was Ringing before, so ignoreing it\n",p->bc?p->bc->pid:-1);
+ chan_misdn_log(2, p->bc->port, " --> * IND :\tringing pid:%d but I was Ringing before, so ignoreing it\n",p->bc?p->bc->pid:-1);
break;
case MISDN_CONNECTED:
- chan_misdn_log(1, p->bc->port, " --> * IND :\tringing pid:%d but Connected, so just send TONE_ALERTING without state changes \n",p->bc?p->bc->pid:-1);
+ chan_misdn_log(2, p->bc->port, " --> * IND :\tringing pid:%d but Connected, so just send TONE_ALERTING without state changes \n",p->bc?p->bc->pid:-1);
return -1;
break;
default:
p->state=MISDN_ALERTING;
- chan_misdn_log(1, p->bc->port, " --> * IND :\tringing pid:%d\n",p->bc?p->bc->pid:-1);
+ chan_misdn_log(2, p->bc->port, " --> * IND :\tringing pid:%d\n",p->bc?p->bc->pid:-1);
misdn_lib_send_event( p->bc, EVENT_ALERTING);
if (p->other_ch && p->other_ch->bc) {
if (misdn_inband_avail(p->other_ch->bc)) {
- chan_misdn_log(1,p->bc->port, " --> other End is mISDN and has inband info available\n");
+ chan_misdn_log(2,p->bc->port, " --> other End is mISDN and has inband info available\n");
break;
}
if (!p->other_ch->bc->nt) {
- chan_misdn_log(1,p->bc->port, " --> other End is mISDN TE so it has inband info for sure (?)\n");
+ chan_misdn_log(2,p->bc->port, " --> other End is mISDN TE so it has inband info for sure (?)\n");
break;
}
}
- chan_misdn_log(1, p->bc->port, " --> * SEND: State Ring pid:%d\n",p->bc?p->bc->pid:-1);
+ chan_misdn_log(3, p->bc->port, " --> * SEND: State Ring pid:%d\n",p->bc?p->bc->pid:-1);
ast_setstate(ast,AST_STATE_RINGING);
if ( !p->bc->nt && (p->orginator==ORG_MISDN) && !p->incoming_early_audio )
- chan_misdn_log(1,p->bc->port, " --> incoming_early_audio off\n");
+ chan_misdn_log(2,p->bc->port, " --> incoming_early_audio off\n");
else
return -1;
}
@@ -1967,7 +1966,7 @@ static int misdn_indication(struct ast_channel *ast, int cond)
chan_misdn_log(1, p->bc->port, " --> *\tUNHOLD pid:%d\n",p->bc?p->bc->pid:-1);
break;
default:
- ast_log(LOG_NOTICE, " --> * Unknown Indication:%d pid:%d\n",cond,p->bc?p->bc->pid:-1);
+ chan_misdn_log(1, p->bc->port, " --> * Unknown Indication:%d pid:%d\n",cond,p->bc?p->bc->pid:-1);
}
return 0;
@@ -2044,10 +2043,10 @@ static int misdn_hangup(struct ast_channel *ast)
}
chan_misdn_log(1, bc->port, "* IND : HANGUP\tpid:%d ctx:%s dad:%s oad:%s State:%s\n",p->bc?p->bc->pid:-1, ast->context, ast->exten, AST_CID_P(ast), misdn_get_ch_state(p));
- chan_misdn_log(2, bc->port, " --> l3id:%x\n",p->l3id);
- chan_misdn_log(1, bc->port, " --> cause:%d\n",bc->cause);
- chan_misdn_log(1, bc->port, " --> out_cause:%d\n",bc->out_cause);
- chan_misdn_log(1, bc->port, " --> state:%s\n", misdn_get_ch_state(p));
+ chan_misdn_log(3, bc->port, " --> l3id:%x\n",p->l3id);
+ chan_misdn_log(3, bc->port, " --> cause:%d\n",bc->cause);
+ chan_misdn_log(2, bc->port, " --> out_cause:%d\n",bc->out_cause);
+ chan_misdn_log(2, bc->port, " --> state:%s\n", misdn_get_ch_state(p));
switch (p->state) {
case MISDN_CALLING:
@@ -2132,7 +2131,7 @@ static int misdn_hangup(struct ast_channel *ast)
}
- chan_misdn_log(1, bc->port, "Channel: %s hanguped new state:%s\n",ast->name,misdn_get_ch_state(p));
+ chan_misdn_log(3, bc->port, " --> Channel: %s hanguped new state:%s\n",ast->name,misdn_get_ch_state(p));
return 0;
}
@@ -2348,9 +2347,9 @@ enum ast_bridge_result misdn_bridge (struct ast_channel *c0,
/* got hangup .. */
if (!f)
- chan_misdn_log(1,ch1->bc->port,"Read Null Frame\n");
+ chan_misdn_log(4,ch1->bc->port,"Read Null Frame\n");
else
- chan_misdn_log(1,ch1->bc->port,"Read Frame Controll class:%d\n",f->subclass);
+ chan_misdn_log(4,ch1->bc->port,"Read Frame Controll class:%d\n",f->subclass);
*fo=f;
*rc=who;
@@ -2955,11 +2954,11 @@ static void hangup_chan(struct chan_list *ch)
return;
}
- cb_log(1,port,"hangup_chan\n");
+ cb_log(5,port,"hangup_chan called\n");
if (ch->need_hangup)
{
- cb_log(1,port,"-> hangup\n");
+ cb_log(2,port," --> hangup\n");
send_cause2ast(ch->ast,ch->bc,ch);
ch->need_hangup=0;
ch->need_queue_hangup=0;
@@ -2969,7 +2968,7 @@ static void hangup_chan(struct chan_list *ch)
}
if (!ch->need_queue_hangup) {
- cb_log(1,port,"No need to queue hangup\n");
+ cb_log(2,port," --> No need to queue hangup\n");
}
ch->need_queue_hangup=0;
@@ -2978,7 +2977,7 @@ static void hangup_chan(struct chan_list *ch)
if (ch->ast)
ast_queue_hangup(ch->ast);
- cb_log(1,port,"-> queue_hangup\n");
+ cb_log(2,port," --> queue_hangup\n");
} else {
cb_log(1,port,"Cannot hangup chan, no ast\n");
}
@@ -2998,7 +2997,7 @@ static void release_chan(struct misdn_bchannel *bc) {
ast=ch->ast;
}
- chan_misdn_log(1, bc->port, "release_chan: bc with l3id: %x\n",bc->l3_id);
+ chan_misdn_log(5, bc->port, "release_chan: bc with l3id: %x\n",bc->l3_id);
/*releaseing jitterbuffer*/
if (ch->jb ) {
@@ -3177,22 +3176,32 @@ void import_ch(struct ast_channel *chan, struct misdn_bchannel *bc, struct chan_
tmp=pbx_builtin_getvar_helper(chan,"MISDN_PID");
if (tmp) {
ch->other_pid=atoi(tmp);
- chan_misdn_log(1,bc->port,"IMPORT_PID: importing pid:%s\n",tmp);
+ chan_misdn_log(3,bc->port," --> IMPORT_PID: importing pid:%s\n",tmp);
if (ch->other_pid >0) {
ch->other_ch=find_chan_by_pid(cl_te,ch->other_pid);
if (ch->other_ch) ch->other_ch->other_ch=ch;
}
}
+
+ tmp=pbx_builtin_getvar_helper(chan,"MISDN_ADDRESS_COMPLETE");
+ if (tmp && (atoi(tmp) == 1)) {
+ bc->sending_complete=1;
+ }
}
void export_ch(struct ast_channel *chan, struct misdn_bchannel *bc, struct chan_list *ch)
{
char tmp[32];
- chan_misdn_log(1,bc->port,"EXPORT_PID: pid:%d\n",bc->pid);
+ chan_misdn_log(3,bc->port," --> EXPORT_PID: pid:%d\n",bc->pid);
sprintf(tmp,"%d",bc->pid);
pbx_builtin_setvar_helper(chan,"_MISDN_PID",tmp);
+
+ if (bc->sending_complete) {
+ sprintf(tmp,"%d",bc->sending_complete);
+ pbx_builtin_setvar_helper(chan,"MISDN_ADDRESS_COMPLETE",tmp);
+ }
}
@@ -3730,15 +3739,15 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
ast_queue_control(ch->ast, AST_CONTROL_RINGING);
ast_setstate(ch->ast, AST_STATE_RINGING);
- cb_log(1,bc->port,"Set State Ringing\n");
+ cb_log(7,bc->port," --> Set State Ringing\n");
if ( misdn_cap_is_speech(bc->capability) && misdn_inband_avail(bc)) {
cb_log(1,bc->port,"Starting Tones, we have inband Data\n");
start_bc_tones(ch);
} else {
- cb_log(1,bc->port,"We have no inband Data, the other end must create ringing\n");
+ cb_log(3,bc->port," --> We have no inband Data, the other end must create ringing\n");
if (ch->far_alerting) {
- cb_log(1,bc->port,"The other end can not do ringing eh ?.. we must do all ourself..");
+ cb_log(1,bc->port," --> The other end can not do ringing eh ?.. we must do all ourself..");
start_bc_tones(ch);
/*tone_indicate(ch, TONE_FAR_ALERTING);*/
}
@@ -3937,7 +3946,11 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
int ret=write(ch->pipe[1], bc->bframe, bc->bframe_len);
if (ret<=0) {
- chan_misdn_log(-1, bc->port, "Write returned <=0 (err=%s)\n",strerror(errno));
+ chan_misdn_log(-1, bc->port, "Write returned <=0 (err=%s) --> hanging up channel\n",strerror(errno));
+
+ stop_bc_tones(ch);
+ hangup_chan(ch);
+ release_chan(bc);
}
} else {
chan_misdn_log(1, bc->port, "Wripe Pipe full!\n");
@@ -4009,6 +4022,9 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
ch->bc=bc;
ch->state = MISDN_CONNECTED;
+ ch->hold_info.port=0;
+ ch->hold_info.channel=0;
+
struct ast_channel *hold_ast=AST_BRIDGED_P(ch->ast);
if (hold_ast) {
@@ -4090,7 +4106,7 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
break;
default:
- ast_log(LOG_NOTICE, "Got Unknown Event\n");
+ chan_misdn_log(1,0, "Got Unknown Event\n");
break;
}
@@ -4121,8 +4137,11 @@ int load_module(void)
return 0;
}
-
- misdn_cfg_init(max_ports);
+ if (misdn_cfg_init(max_ports)<0) {
+ ast_log(LOG_ERROR, "Unable to initialize mISDN Config System\n");
+ return 0;
+ }
+
g_config_initialized=1;
misdn_debug = (int *)malloc(sizeof(int) * (max_ports+1));
@@ -4345,7 +4364,7 @@ static int misdn_facility_exec(struct ast_channel *chan, void *data)
misdn_lib_send_facility(ch->bc, FACILITY_CALLDEFLECT, tok);
} else {
- ast_log(LOG_WARNING, "Unknown Facility: %s\n",tok);
+ chan_misdn_log(1, ch->bc->port, "Unknown Facility: %s\n",tok);
}
return 0;
diff --git a/channels/chan_phone.c b/channels/chan_phone.c
index 65257d507..ad7b87013 100644
--- a/channels/chan_phone.c
+++ b/channels/chan_phone.c
@@ -37,9 +37,6 @@
#include <linux/telephony.h>
/* Still use some IXJ specific stuff */
#include <linux/version.h>
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-# include <linux/compiler.h>
-#endif
#include <linux/ixjuser.h>
#include "asterisk.h"
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index 892ec86fc..67005f690 100644
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -1273,7 +1273,9 @@ static int retrans_pkt(void *data)
ast_mutex_unlock(&pkt->owner->owner->lock);
} else {
/* If no channel owner, destroy now */
- ast_set_flag(pkt->owner, SIP_NEEDDESTROY);
+ /* Let the peerpoke system expire packets when the timer expires for poke_noanswer */
+ if (pkt->method != SIP_OPTIONS)
+ ast_set_flag(pkt->owner, SIP_NEEDDESTROY);
}
}
/* In any case, go ahead and remove the packet */
@@ -1426,6 +1428,7 @@ static int __sip_ack(struct sip_pvt *p, int seqno, int resp, int sipmethod)
if (sipdebug && option_debug > 3)
ast_log(LOG_DEBUG, "** SIP TIMER: Cancelling retransmit of packet (reply received) Retransid #%d\n", cur->retransid);
ast_sched_del(sched, cur->retransid);
+ cur->retransid = -1;
}
free(cur);
res = 0;
@@ -1481,8 +1484,8 @@ static int __sip_semi_ack(struct sip_pvt *p, int seqno, int resp, int sipmethod)
if (option_debug > 3 && sipdebug)
ast_log(LOG_DEBUG, "*** SIP TIMER: Cancelling retransmission #%d - %s (got response)\n", cur->retransid, msg);
ast_sched_del(sched, cur->retransid);
+ cur->retransid = -1;
}
- cur->retransid = -1;
res = 0;
break;
}
@@ -1681,6 +1684,7 @@ static void sip_destroy_peer(struct sip_peer *peer)
}
if (peer->expire > -1)
ast_sched_del(sched, peer->expire);
+
if (peer->pokeexpire > -1)
ast_sched_del(sched, peer->pokeexpire);
register_peer_exten(peer, 0);
@@ -2289,7 +2293,7 @@ static int update_call_counter(struct sip_pvt *fup, int event)
case INC_CALL_LIMIT:
if (*call_limit > 0 ) {
if (*inuse >= *call_limit) {
- ast_log(LOG_ERROR, "Call %s %s '%s' rejected due to usage limit of %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *call_limit);
+ ast_log(LOG_NOTICE, "Call %s %s '%s' rejected due to usage limit of %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *call_limit);
if (u)
ASTOBJ_UNREF(u,sip_destroy_user);
else
@@ -2518,7 +2522,7 @@ static int sip_hangup(struct ast_channel *ast)
/* Do we need a timer here if we don't hear from them at all? */
} else {
/* Send a new request: CANCEL */
- transmit_request_with_auth(p, SIP_CANCEL, p->ocseq, 1, 0);
+ transmit_request(p, SIP_CANCEL, p->ocseq, 1, 0);
/* Actually don't destroy us yet, wait for the 487 on our original
INVITE, but do set an autodestruct just in case we never get it. */
}
@@ -2592,7 +2596,7 @@ static int sip_answer(struct ast_channel *ast)
ast_setstate(ast, AST_STATE_UP);
if (option_debug)
ast_log(LOG_DEBUG, "sip_answer(%s)\n", ast->name);
- res = transmit_response_with_sdp(p, "200 OK", &p->initreq, 1);
+ res = transmit_response_with_sdp(p, "200 OK", &p->initreq, 2);
}
ast_mutex_unlock(&p->lock);
return res;
@@ -2655,6 +2659,11 @@ static int sip_write(struct ast_channel *ast, struct ast_frame *frame)
static int sip_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
{
struct sip_pvt *p = newchan->tech_pvt;
+ if (!p) {
+ ast_log(LOG_WARNING, "No pvt after masquerade. Strange things may happen\n");
+ return -1;
+ }
+
ast_mutex_lock(&p->lock);
if (p->owner != oldchan) {
ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, p->owner);
@@ -3278,9 +3287,10 @@ static struct sip_pvt *find_call(struct sip_request *req, struct sockaddr_in *si
ast_mutex_unlock(&iflock);
/* If this is a response and we have ignoring of out of dialog responses turned on, then drop it */
+ /* ...and never respond to a SIP ACK message */
if (!sip_methods[intended_method].can_create) {
/* Can't create dialog */
- if (intended_method != SIP_RESPONSE)
+ if (intended_method != SIP_RESPONSE && intended_method != SIP_ACK)
transmit_response_using_temp(callid, sin, 1, intended_method, req, "481 Call leg/transaction does not exist");
} else if (sip_methods[intended_method].can_create == 2) {
char *response = "481 Call leg/transaction does not exist";
@@ -3298,6 +3308,19 @@ static struct sip_pvt *find_call(struct sip_request *req, struct sockaddr_in *si
p = sip_alloc(callid, sin, 1, intended_method);
if (p)
ast_mutex_lock(&p->lock);
+ else {
+ /* We have a memory or file/socket error (can't allocate RTP sockets or something) so we're not
+ getting a dialog from sip_alloc.
+
+ Without a dialog we can't retransmit and handle ACKs and all that, but at least
+ send an error message.
+
+ Sorry, we apologize for the inconvienience
+ */
+ transmit_response_using_temp(callid, sin, 1, intended_method, req, "500 Server internal error");
+ if (option_debug > 3)
+ ast_log(LOG_DEBUG, "Failed allocating SIP dialog, sending 500 Server internal error and giving up\n");
+ }
}
return p;
@@ -3541,7 +3564,9 @@ static int find_sdp(struct sip_request *req)
for (x = 0; x < (req->lines - 2); x++) {
if (!strncasecmp(req->line[x], boundary, strlen(boundary)) &&
!strcasecmp(req->line[x + 1], "Content-Type: application/sdp")) {
- req->sdp_start = x + 2;
+ x += 2;
+ req->sdp_start = x;
+
/* search for the end of the body part */
for ( ; x < req->lines; x++) {
if (!strncasecmp(req->line[x], boundary, strlen(boundary)))
@@ -4272,7 +4297,8 @@ static int reqprep(struct sip_request *req, struct sip_pvt *p, int sipmethod, in
add_header(req, "From", ot);
add_header(req, "To", of);
}
- add_header(req, "Contact", p->our_contact);
+ if (sipmethod != SIP_BYE && sipmethod != SIP_CANCEL && sipmethod != SIP_MESSAGE)
+ add_header(req, "Contact", p->our_contact);
copy_header(req, orig, "Call-ID");
add_header(req, "CSeq", tmp);
@@ -4310,6 +4336,7 @@ static int __transmit_response(struct sip_pvt *p, char *msg, struct sip_request
static int transmit_response_using_temp(char *callid, struct sockaddr_in *sin, int useglobal_nat, const int intended_method, struct sip_request *req, char *msg)
{
struct sip_pvt *p = alloca(sizeof(*p));
+ struct sip_history *hist = NULL;
memset(p, 0, sizeof(*p));
@@ -4335,6 +4362,11 @@ static int transmit_response_using_temp(char *callid, struct sockaddr_in *sin, i
__transmit_response(p, msg, req, 0);
+ while ((hist = p->history)) {
+ p->history = p->history->next;
+ free(hist);
+ }
+
return 0;
}
@@ -5717,7 +5749,8 @@ static int transmit_register(struct sip_registry *r, int sipmethod, char *auth,
ast_copy_string(p->domain, r->domain, sizeof(p->domain));
ast_copy_string(p->opaque, r->opaque, sizeof(p->opaque));
ast_copy_string(p->qop, r->qop, sizeof(p->qop));
- p->noncecount = r->noncecount++;
+ r->noncecount++;
+ p->noncecount = r->noncecount;
memset(digest,0,sizeof(digest));
if(!build_reply_digest(p, sipmethod, digest, sizeof(digest)))
@@ -6165,8 +6198,10 @@ static enum parse_register_result parse_register_contact(struct sip_pvt *pvt, st
else
p->username[0] = '\0';
- if (p->expire > -1)
+ if (p->expire > -1) {
ast_sched_del(sched, p->expire);
+ p->expire = -1;
+ }
if ((expiry < 1) || (expiry > max_expiry))
expiry = max_expiry;
if (!ast_test_flag(p, SIP_REALTIME))
@@ -8217,7 +8252,7 @@ static int _sip_show_peer(int type, int fd, struct mansession *s, struct message
print_group(fd, peer->pickupgroup, 0);
ast_cli(fd, " Mailbox : %s\n", peer->mailbox);
ast_cli(fd, " VM Extension : %s\n", peer->vmexten);
- ast_cli(fd, " LastMsgsSent : %d\n", peer->lastmsgssent);
+ ast_cli(fd, " LastMsgsSent : %d/%d\n", (peer->lastmsgssent & 0x7fff0000) >> 16, peer->lastmsgssent & 0xffff);
ast_cli(fd, " Call limit : %d\n", peer->call_limit);
ast_cli(fd, " Dynamic : %s\n", (ast_test_flag(&peer->flags_page2, SIP_PAGE2_DYNAMIC)?"Yes":"No"));
ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>"));
@@ -9718,7 +9753,7 @@ static void check_pendings(struct sip_pvt *p)
if (ast_test_flag(p, SIP_PENDINGBYE)) {
/* if we can't BYE, then this is really a pending CANCEL */
if (!ast_test_flag(p, SIP_CAN_BYE))
- transmit_request_with_auth(p, SIP_CANCEL, p->ocseq, 1, 0);
+ transmit_request(p, SIP_CANCEL, p->ocseq, 1, 0);
/* Actually don't destroy us yet, wait for the 487 on our original
INVITE, but do set an autodestruct just in case we never get it. */
else
@@ -9889,12 +9924,23 @@ static void handle_response_invite(struct sip_pvt *p, int resp, char *rest, stru
ast_log(LOG_WARNING, "Re-invite to non-existing call leg on other UA. SIP dialog '%s'. Giving up.\n", p->callid);
transmit_request(p, SIP_ACK, seqno, 0, 0);
break;
+ case 487: /* Cancelled transaction */
+ /* We have sent CANCEL on an outbound INVITE
+ This transaction is already scheduled to be killed by sip_hangup().
+ */
+ transmit_request(p, SIP_ACK, seqno, 0, 0);
+ if (p->owner && !ignore)
+ ast_queue_hangup(p->owner);
+ else if (!ignore)
+ update_call_counter(p, DEC_CALL_LIMIT);
+ break;
case 491: /* Pending */
/* we have to wait a while, then retransmit */
/* Transmission is rescheduled, so everything should be taken care of.
We should support the retry-after at some point */
break;
case 501: /* Not implemented */
+ transmit_request(p, SIP_ACK, seqno, 0, 0);
if (p->owner)
ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
break;
@@ -9920,6 +9966,7 @@ static int handle_response_register(struct sip_pvt *p, int resp, char *rest, str
if (global_regattempts_max)
p->registry->regattempts = global_regattempts_max+1;
ast_sched_del(sched, r->timeout);
+ r->timeout = -1;
ast_set_flag(p, SIP_NEEDDESTROY);
break;
case 404: /* Not found */
@@ -9929,6 +9976,7 @@ static int handle_response_register(struct sip_pvt *p, int resp, char *rest, str
ast_set_flag(p, SIP_NEEDDESTROY);
r->call = NULL;
ast_sched_del(sched, r->timeout);
+ r->timeout = -1;
break;
case 407: /* Proxy auth */
if ((p->authtries == MAX_AUTHTRIES) || do_register_auth(p, req, "Proxy-Authenticate", "Proxy-Authorization")) {
@@ -9943,6 +9991,7 @@ static int handle_response_register(struct sip_pvt *p, int resp, char *rest, str
ast_set_flag(p, SIP_NEEDDESTROY);
r->call = NULL;
ast_sched_del(sched, r->timeout);
+ r->timeout = -1;
break;
case 200: /* 200 OK */
if (!r) {
@@ -10062,7 +10111,7 @@ static int handle_response_peerpoke(struct sip_pvt *p, int resp, char *rest, str
ast_sched_del(sched, peer->pokeexpire);
if (sipmethod == SIP_INVITE) /* Does this really happen? */
transmit_request(p, SIP_ACK, seqno, 0, 0);
- ast_set_flag(p, SIP_NEEDDESTROY);
+ ast_set_flag(p, SIP_NEEDDESTROY);
/* Try again eventually */
if ((peer->lastms < 0) || (peer->lastms > peer->maxms))
@@ -10199,6 +10248,10 @@ static void handle_response(struct sip_pvt *p, int resp, char *rest, struct sip_
ast_set_flag(p, SIP_NEEDDESTROY);
break;
+ case 487:
+ if (sipmethod == SIP_INVITE)
+ handle_response_invite(p, resp, rest, req, ignore, seqno);
+ break;
case 491: /* Pending */
if (sipmethod == SIP_INVITE) {
handle_response_invite(p, resp, rest, req, ignore, seqno);
@@ -10213,7 +10266,6 @@ static void handle_response(struct sip_pvt *p, int resp, char *rest, struct sip_
if ((resp >= 300) && (resp < 700)) {
if ((option_verbose > 2) && (resp != 487))
ast_verbose(VERBOSE_PREFIX_3 "Got SIP response %d \"%s\" back from %s\n", resp, rest, ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr));
- ast_set_flag(p, SIP_ALREADYGONE);
if (p->rtp) {
/* Immediately stop RTP */
ast_rtp_stop(p->rtp);
@@ -10236,12 +10288,6 @@ static void handle_response(struct sip_pvt *p, int resp, char *rest, struct sip_
if (p->owner)
ast_queue_control(p->owner, AST_CONTROL_BUSY);
break;
- case 487:
- /* channel now destroyed - dec the inUse counter */
- if (owner)
- ast_queue_hangup(p->owner);
- update_call_counter(p, DEC_CALL_LIMIT);
- break;
case 482: /* SIP is incapable of performing a hairpin call, which
is yet another failure of not having a layer 2 (again, YAY
IETF for thinking ahead). So we treat this as a call
@@ -10612,8 +10658,9 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int
/* This is a call to ourself. Send ourselves an error code and stop
processing immediately, as SIP really has no good mechanism for
being able to call yourself */
- transmit_response(p, "482 Loop Detected", req);
- /* We do NOT destroy p here, so that our response will be accepted */
+ transmit_response_reliable(p, "482 Loop Detected", req, 1);
+ if (!p->lastinvite)
+ ast_set_flag(p, SIP_NEEDDESTROY);
return 0;
}
if (!ignore) {
@@ -10655,10 +10702,7 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int
transmit_fake_auth_response(p, req, p->randdata, sizeof(p->randdata), 1);
} else {
ast_log(LOG_NOTICE, "Failed to authenticate user %s\n", get_header(req, "From"));
- if (ignore)
- transmit_response(p, "403 Forbidden", req);
- else
- transmit_response_reliable(p, "403 Forbidden", req, 1);
+ transmit_response_reliable(p, "403 Forbidden", req, 1);
}
ast_set_flag(p, SIP_NEEDDESTROY);
p->theirtag[0] = '\0'; /* Forget their to-tag, we'll get a new one */
@@ -10700,10 +10744,7 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int
if (res) {
if (res < 0) {
ast_log(LOG_NOTICE, "Failed to place call for user %s, too many calls\n", p->username);
- if (ignore)
- transmit_response(p, "480 Temporarily Unavailable (Call limit)", req);
- else
- transmit_response_reliable(p, "480 Temporarily Unavailable (Call limit) ", req, 1);
+ transmit_response_reliable(p, "480 Temporarily Unavailable (Call limit) ", req, 1);
ast_set_flag(p, SIP_NEEDDESTROY);
}
return 0;
@@ -10716,20 +10757,13 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int
build_contact(p);
if (gotdest) {
- if (gotdest < 0) {
- if (ignore)
- transmit_response(p, "404 Not Found", req);
- else
- transmit_response_reliable(p, "404 Not Found", req, 1);
- update_call_counter(p, DEC_CALL_LIMIT);
- } else {
- if (ignore)
- transmit_response(p, "484 Address Incomplete", req);
- else
- transmit_response_reliable(p, "484 Address Incomplete", req, 1);
- update_call_counter(p, DEC_CALL_LIMIT);
- }
+ if (gotdest < 0)
+ transmit_response_reliable(p, "404 Not Found", req, 1);
+ else
+ transmit_response_reliable(p, "484 Address Incomplete", req, 1);
+ update_call_counter(p, DEC_CALL_LIMIT);
ast_set_flag(p, SIP_NEEDDESTROY);
+ return 0;
} else {
/* If no extension was specified, use the s one */
if (ast_strlen_zero(p->exten))
@@ -10835,19 +10869,12 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int
} else {
if (p && !ast_test_flag(p, SIP_NEEDDESTROY) && !ignore) {
if (!p->jointcapability) {
- if (ignore)
- transmit_response(p, "488 Not Acceptable Here (codec error)", req);
- else
- transmit_response_reliable(p, "488 Not Acceptable Here (codec error)", req, 1);
- ast_set_flag(p, SIP_NEEDDESTROY);
+ transmit_response_reliable(p, "488 Not Acceptable Here (codec error)", req, 1);
} else {
ast_log(LOG_NOTICE, "Unable to create/find channel\n");
- if (ignore)
- transmit_response(p, "503 Unavailable", req);
- else
- transmit_response_reliable(p, "503 Unavailable", req, 1);
- ast_set_flag(p, SIP_NEEDDESTROY);
+ transmit_response_reliable(p, "503 Unavailable", req, 1);
}
+ ast_set_flag(p, SIP_NEEDDESTROY);
}
}
return res;
@@ -10961,7 +10988,8 @@ static int handle_request_bye(struct sip_pvt *p, struct sip_request *req, int de
struct ast_channel *bridged_to;
char iabuf[INET_ADDRSTRLEN];
- if (p->pendinginvite && !ast_test_flag(p, SIP_OUTGOING) && !ignore)
+ /* If we have an INCOMING invite that we haven't answered, terminate that transaction */
+ if (p->pendinginvite && !ast_test_flag(p, SIP_OUTGOING) && !ignore && !p->owner)
transmit_response_reliable(p, "487 Request Terminated", &p->initreq, 1);
copy_request(&p->initreq, req);
@@ -11202,7 +11230,7 @@ static int handle_request_subscribe(struct sip_pvt *p, struct sip_request *req,
if ((firststate = ast_extension_state(NULL, p->context, p->exten)) < 0) {
char iabuf[INET_ADDRSTRLEN];
- ast_log(LOG_ERROR, "Got SUBSCRIBE for extension %s@%s from %s, but there is no hint for that extension\n", p->exten, p->context, ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr));
+ ast_log(LOG_NOTICE, "Got SUBSCRIBE for extension %s@%s from %s, but there is no hint for that extension\n", p->exten, p->context, ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr));
transmit_response(p, "404 Not found", req);
ast_set_flag(p, SIP_NEEDDESTROY);
return 0;
@@ -11272,7 +11300,6 @@ static int handle_request(struct sip_pvt *p, struct sip_request *req, struct soc
{
/* Called with p->lock held, as well as p->owner->lock if appropriate, keeping things
relatively static */
- struct sip_request resp;
char *cmd;
char *cseq;
char *useragent;
@@ -11286,9 +11313,6 @@ static int handle_request(struct sip_pvt *p, struct sip_request *req, struct soc
char *e;
int error = 0;
- /* Clear out potential response */
- memset(&resp, 0, sizeof(resp));
-
/* Get Method and Cseq */
cseq = get_header(req, "Cseq");
cmd = req->header[0];
@@ -11303,7 +11327,7 @@ static int handle_request(struct sip_pvt *p, struct sip_request *req, struct soc
error = 1;
}
if (error) {
- if (!p->initreq.header) /* New call */
+ if (!p->initreq.headers) /* New call */
ast_set_flag(p, SIP_NEEDDESTROY); /* Make sure we destroy this dialog */
return -1;
}
@@ -11534,7 +11558,7 @@ retrylock:
goto retrylock;
}
if (!lockretry) {
- ast_log(LOG_ERROR, "We could NOT get the channel lock for %s! \n", p->owner->name);
+ ast_log(LOG_ERROR, "We could NOT get the channel lock for %s - Call ID %s! \n", p->owner->name, p->callid);
ast_log(LOG_ERROR, "SIP MESSAGE JUST IGNORED: %s \n", req.data);
ast_log(LOG_ERROR, "BAD! BAD! BAD!\n");
return 1;
@@ -11576,7 +11600,7 @@ static int sip_send_mwi_to_peer(struct sip_peer *peer)
time(&peer->lastmsgcheck);
/* Return now if it's the same thing we told them last time */
- if (((newmsgs << 8) | (oldmsgs)) == peer->lastmsgssent) {
+ if (((newmsgs > 0x7fff ? 0x7fff0000 : (newmsgs << 16)) | (oldmsgs > 0xffff ? 0xffff : oldmsgs)) == peer->lastmsgssent) {
return 0;
}
@@ -11585,7 +11609,7 @@ static int sip_send_mwi_to_peer(struct sip_peer *peer)
ast_log(LOG_WARNING, "Unable to build sip pvt data for MWI\n");
return -1;
}
- peer->lastmsgssent = ((newmsgs << 8) | (oldmsgs));
+ peer->lastmsgssent = ((newmsgs > 0x7fff ? 0x7fff0000 : (newmsgs << 16)) | (oldmsgs > 0xffff ? 0xffff : oldmsgs));
if (create_addr_from_peer(p, peer)) {
/* Maybe they're not registered, etc. */
sip_destroy(p);
@@ -11816,7 +11840,7 @@ static int sip_poke_peer(struct sip_peer *peer)
peer->call = NULL;
return 0;
}
- if (peer->call > 0) {
+ if (peer->call) {
if (sipdebug)
ast_log(LOG_NOTICE, "Still have a QUALIFY dialog active, deleting\n");
sip_destroy(peer->call);
@@ -13520,8 +13544,10 @@ static int sip_do_reload(void)
sip_destroy(iterator->call);
}
ASTOBJ_UNLOCK(iterator);
+
} while(0));
+
ASTOBJ_CONTAINER_DESTROYALL(&userl, sip_destroy_user);
ASTOBJ_CONTAINER_DESTROYALL(&regl, sip_registry_destroy);
ASTOBJ_CONTAINER_MARKALL(&peerl);
@@ -13713,13 +13739,7 @@ int unload_module()
while (p) {
pl = p;
p = p->next;
- /* Free associated memory */
- ast_mutex_destroy(&pl->lock);
- if (pl->chanvars) {
- ast_variables_destroy(pl->chanvars);
- pl->chanvars = NULL;
- }
- free(pl);
+ __sip_destroy(pl, 1);
}
iflist = NULL;
ast_mutex_unlock(&iflock);
diff --git a/channels/chan_zap.c b/channels/chan_zap.c
index 69177a981..277a152c1 100644
--- a/channels/chan_zap.c
+++ b/channels/chan_zap.c
@@ -3339,7 +3339,7 @@ static int attempt_transfer(struct zt_pvt *p)
stop if now if appropriate */
if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner))
ast_moh_stop(ast_bridged_channel(p->subs[SUB_THREEWAY].owner));
- if (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_RINGING) {
+ if (p->subs[SUB_REAL].owner->_state == AST_STATE_RINGING) {
ast_indicate(ast_bridged_channel(p->subs[SUB_REAL].owner), AST_CONTROL_RINGING);
}
if (p->subs[SUB_REAL].owner->cdr) {
@@ -3363,7 +3363,7 @@ static int attempt_transfer(struct zt_pvt *p)
ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
unalloc_sub(p, SUB_THREEWAY);
} else if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) {
- if (p->subs[SUB_REAL].owner->_state == AST_STATE_RINGING) {
+ if (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_RINGING) {
ast_indicate(ast_bridged_channel(p->subs[SUB_THREEWAY].owner), AST_CONTROL_RINGING);
}
ast_moh_stop(ast_bridged_channel(p->subs[SUB_THREEWAY].owner));
@@ -4853,11 +4853,10 @@ static int zt_indicate(struct ast_channel *chan, int condition)
}
#endif
res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_RINGTONE);
- if (chan->_state != AST_STATE_UP) {
- if ((chan->_state != AST_STATE_RING) ||
- ((p->sig != SIG_FXSKS) &&
+ if (chan->_state != AST_STATE_UP && chan->_state != AST_STATE_RING) {
+ if ((p->sig != SIG_FXSKS) &&
(p->sig != SIG_FXSLS) &&
- (p->sig != SIG_FXSGS)))
+ (p->sig != SIG_FXSGS))
ast_setstate(chan, AST_STATE_RINGING);
}
break;
@@ -6268,7 +6267,9 @@ static int handle_init_event(struct zt_pvt *i, int event)
case SIG_FXOLS:
case SIG_FXOGS:
case SIG_FXOKS:
- zt_set_hook(i->subs[SUB_REAL].zfd, ZT_OFFHOOK);
+ res = zt_set_hook(i->subs[SUB_REAL].zfd, ZT_OFFHOOK);
+ if (res && (errno == EBUSY))
+ break;
if (i->cidspill) {
/* Cancel VMWI spill */
free(i->cidspill);
diff --git a/channels/misdn/chan_misdn_config.h b/channels/misdn/chan_misdn_config.h
index db007f57d..d36686cc0 100644
--- a/channels/misdn/chan_misdn_config.h
+++ b/channels/misdn/chan_misdn_config.h
@@ -85,7 +85,7 @@ enum misdn_cfg_method {
};
/* you must call misdn_cfg_init before any other function of this header file */
-void misdn_cfg_init(int max_ports);
+int misdn_cfg_init(int max_ports);
void misdn_cfg_reload(void);
void misdn_cfg_destroy(void);
diff --git a/channels/misdn/isdn_lib.c b/channels/misdn/isdn_lib.c
index f07951c57..72b7d8243 100644
--- a/channels/misdn/isdn_lib.c
+++ b/channels/misdn/isdn_lib.c
@@ -420,10 +420,10 @@ static int find_free_chan_in_stack(struct misdn_stack *stack, int channel)
{
int i;
- cb_log(1,stack->port,"find_free_chan: req_chan:%d\n",channel);
+ cb_log(5,stack->port,"find_free_chan: req_chan:%d\n",channel);
if (channel < 0 || channel > MAX_BCHANS) {
- cb_log(4, stack->port, " !! out of bound call to find_free_chan_in_stack! (ch:%d)\n", channel);
+ cb_log(0, stack->port, " !! out of bound call to find_free_chan_in_stack! (ch:%d)\n", channel);
return 0;
}
@@ -432,14 +432,14 @@ static int find_free_chan_in_stack(struct misdn_stack *stack, int channel)
for (i = 0; i < stack->b_num; i++) {
if (i != 15 && (channel < 0 || i == channel)) { /* skip E1 Dchannel ;) and work with chan preselection */
if (!stack->channels[i]) {
- cb_log (1, stack->port, " --> found chan%s: %d\n", channel>=0?" (preselected)":"", i+1);
+ cb_log (3, stack->port, " --> found chan%s: %d\n", channel>=0?" (preselected)":"", i+1);
stack->channels[i] = 1;
return i+1;
}
}
}
- cb_log (4, stack->port, " !! NO FREE CHAN IN STACK\n");
+ cb_log (1, stack->port, " !! NO FREE CHAN IN STACK\n");
dump_chan_list(stack);
return 0;
@@ -1671,8 +1671,6 @@ int misdn_lib_port_up(int port, int check)
stack;
stack=stack->next) {
- if ( !stack->ptp && !check) return 1;
-
if (stack->port == port) {
if (stack->blocked) {
@@ -1690,7 +1688,7 @@ int misdn_lib_port_up(int port, int check)
return 0;
}
} else {
- if ( stack->l1link)
+ if ( !check || stack->l1link )
return 1;
else {
cb_log(0,port, "Port down PMP\n");
@@ -2030,7 +2028,7 @@ handle_event_nt(void *dat, void *arg)
if (stack->ptp)
set_chan_in_stack(stack, bc->channel);
else
- cb_log(0,stack->port," --> PTMP but channel requested\n");
+ cb_log(3,stack->port," --> PTMP but channel requested\n");
} else {
@@ -3173,7 +3171,7 @@ int misdn_lib_send_event(struct misdn_bchannel *bc, enum event_e event )
}
cb_log(1, stack->port, "I SEND:%s oad:%s dad:%s pid:%d\n", isdn_get_info(msgs_g, event, 0), bc->oad, bc->dad, bc->pid);
- cb_log(1, stack->port, " --> bc_state:%s\n",bc_state2str(bc->bc_state));
+ cb_log(4, stack->port, " --> bc_state:%s\n",bc_state2str(bc->bc_state));
misdn_lib_log_ies(bc);
switch (event) {
@@ -4182,7 +4180,7 @@ void manager_ec_enable(struct misdn_bchannel *bc)
struct misdn_stack *stack=get_stack_by_bc(bc);
- cb_log(1, stack?stack->port:0,"ec_enable\n");
+ cb_log(4, stack?stack->port:0,"ec_enable\n");
if (!misdn_cap_is_speech(bc->capability)) {
cb_log(1, stack?stack->port:0, " --> no speech? cannot enable EC\n");
@@ -4190,7 +4188,7 @@ void manager_ec_enable(struct misdn_bchannel *bc)
}
if (bc->ec_enable) {
- cb_log(1, stack?stack->port:0,"Sending Control ECHOCAN_ON taps:%d training:%d\n",bc->ec_deftaps, bc->ec_training);
+ cb_log(3, stack?stack->port:0,"Sending Control ECHOCAN_ON taps:%d training:%d\n",bc->ec_deftaps, bc->ec_training);
switch (bc->ec_deftaps) {
case 4:
@@ -4222,7 +4220,7 @@ void manager_ec_disable(struct misdn_bchannel *bc)
{
struct misdn_stack *stack=get_stack_by_bc(bc);
- cb_log(1, stack?stack->port:0,"ec_disable\n");
+ cb_log(4, stack?stack->port:0," --> ec_disable\n");
if (!misdn_cap_is_speech(bc->capability)) {
cb_log(1, stack?stack->port:0, " --> no speech? cannot disable EC\n");
@@ -4230,7 +4228,7 @@ void manager_ec_disable(struct misdn_bchannel *bc)
}
if ( ! bc->ec_enable) {
- cb_log(1, stack?stack->port:0, "Sending Control ECHOCAN_OFF\n");
+ cb_log(3, stack?stack->port:0, "Sending Control ECHOCAN_OFF\n");
manager_ph_control(bc, ECHOCAN_OFF, 0);
}
}
@@ -4247,7 +4245,7 @@ void misdn_join_conf(struct misdn_bchannel *bc, int conf_id)
manager_ph_control(bc, CMX_RECEIVE_OFF, 0);
manager_ph_control(bc, CMX_CONF_JOIN, conf_id);
- cb_log(1,bc->port, "Joining bc:%x in conf:%d\n",bc->addr,conf_id);
+ cb_log(3,bc->port, "Joining bc:%x in conf:%d\n",bc->addr,conf_id);
char data[16];
int len=15;
@@ -4265,13 +4263,13 @@ void misdn_split_conf(struct misdn_bchannel *bc, int conf_id)
manager_ph_control(bc, CMX_RECEIVE_ON, 0);
manager_ph_control(bc, CMX_CONF_SPLIT, conf_id);
- cb_log(1,bc->port, "Splitting bc:%x in conf:%d\n",bc->addr,conf_id);
+ cb_log(4,bc->port, "Splitting bc:%x in conf:%d\n",bc->addr,conf_id);
}
void misdn_lib_bridge( struct misdn_bchannel * bc1, struct misdn_bchannel *bc2) {
int conf_id=bc1->pid +1;
- cb_log(1, bc1->port, "I Send: BRIDGE from:%d to:%d\n",bc1->port,bc2->port);
+ cb_log(4, bc1->port, "I Send: BRIDGE from:%d to:%d\n",bc1->port,bc2->port);
struct misdn_bchannel *bc_list[]={
bc1,bc2,NULL
@@ -4280,7 +4278,7 @@ void misdn_lib_bridge( struct misdn_bchannel * bc1, struct misdn_bchannel *bc2)
for (bc=bc_list; *bc; *bc++) {
(*bc)->conf_id=conf_id;
- cb_log(1, (*bc)->port, " --> bc_addr:%x\n",(*bc)->addr);
+ cb_log(4, (*bc)->port, " --> bc_addr:%x\n",(*bc)->addr);
switch((*bc)->bc_state) {
case BCHAN_ACTIVATED:
@@ -4315,7 +4313,7 @@ void misdn_lib_split_bridge( struct misdn_bchannel * bc1, struct misdn_bchannel
void misdn_lib_echo(struct misdn_bchannel *bc, int onoff)
{
- cb_log(1,bc->port, " --> ECHO %s\n", onoff?"ON":"OFF");
+ cb_log(3,bc->port, " --> ECHO %s\n", onoff?"ON":"OFF");
manager_ph_control(bc, onoff?CMX_ECHO_ON:CMX_ECHO_OFF, 0);
}
diff --git a/channels/misdn/isdn_msg_parser.c b/channels/misdn/isdn_msg_parser.c
index 136c9a62d..3d841d893 100644
--- a/channels/misdn/isdn_msg_parser.c
+++ b/channels/misdn/isdn_msg_parser.c
@@ -323,6 +323,10 @@ msg_t *build_setup (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
enc_ie_bearer(&setup->BEARER, msg, coding, capability, mode, rate, -1, user, nt,bc);
}
+
+ if (bc->sending_complete) {
+ enc_ie_complete(&setup->BEARER,msg, bc->sending_complete, nt, bc);
+ }
#if DEBUG
printf("Building SETUP Msg\n");
diff --git a/channels/misdn_config.c b/channels/misdn_config.c
index 689c8c7c7..1d33ac15d 100644
--- a/channels/misdn_config.c
+++ b/channels/misdn_config.c
@@ -91,7 +91,7 @@ static const struct misdn_cfg_spec port_spec[] = {
{ "far_alerting", MISDN_CFG_FAR_ALERTING, MISDN_CTYPE_BOOL, "no", NONE },
{ "pmp_l1_check", MISDN_CFG_PMP_L1_CHECK, MISDN_CTYPE_BOOL, "yes", NONE },
{ "reject_cause", MISDN_CFG_REJECT_CAUSE, MISDN_CTYPE_INT, "21", NONE },
- { "block_on_alarm", MISDN_CFG_ALARM_BLOCK, MISDN_CTYPE_BOOL, "yes", NONE },
+ { "block_on_alarm", MISDN_CFG_ALARM_BLOCK, MISDN_CTYPE_BOOL, "no", NONE },
{ "hdlc", MISDN_CFG_HDLC, MISDN_CTYPE_BOOL, "no", NONE },
{ "context", MISDN_CFG_CONTEXT, MISDN_CTYPE_STR, "default", NONE },
{ "language", MISDN_CFG_LANGUAGE, MISDN_CTYPE_STR, "en", NONE },
@@ -727,7 +727,7 @@ void misdn_cfg_destroy (void)
ast_mutex_destroy(&config_mutex);
}
-void misdn_cfg_init (int this_max_ports)
+int misdn_cfg_init (int this_max_ports)
{
char config[] = "misdn.conf";
char *cat, *p;
@@ -737,7 +737,7 @@ void misdn_cfg_init (int this_max_ports)
if (!(cfg = AST_LOAD_CFG(config))) {
ast_log(LOG_WARNING,"no misdn.conf ?\n");
- return;
+ return -1;
}
misdn_cfg_lock();
@@ -783,4 +783,6 @@ void misdn_cfg_init (int this_max_ports)
misdn_cfg_unlock();
AST_DESTROY_CFG(cfg);
+
+ return 0;
}