summaryrefslogtreecommitdiff
path: root/channels/chan_misdn.c
diff options
context:
space:
mode:
authorChristian Richter <christian.richter@beronet.com>2006-08-03 16:38:00 +0000
committerChristian Richter <christian.richter@beronet.com>2006-08-03 16:38:00 +0000
commitfc3d27cf6fe27e5796b5def1932feb9932947244 (patch)
treee0b13b91f114361f7c52e40a5a9306ec9612ef89 /channels/chan_misdn.c
parentaac4712421516b7a0aed816fdfd0bd4f4e244a7f (diff)
* removed pp_l2_check (fixed L2 bug in mISDNuser)
* added blocking flag to stack object. A port can be blocked/unblocked from the cli * added EVENT_PORT_ALARM to send alarm infos to the chan_misdn.c layer (later we can add a manager event for that) * added block_on_alarm option, to block the port whenever a ALARM occurs * added need_busy flag to indicate if we've sended a CONTROL_BUSY already * changed a bunch of cb_log(-1,..) to cb_log(0,..) due to funny behaviour in recent asterisk ast_log messages.. * fixed a few ETSI state violations, especially when finishing calls in different seldom states * changed debug levels a lot to make the log more readable in low debuglevels * some first fixes for the HOLD/RETRIEVE stuff (doesn't work totally still) * removed the PRECONNECTED state stuff * added cause 27 when we get a CLEANUP directly after a outgoing SETUP, this creates a CHANISUNAVAIL instead of a NOANSWER * removed the addr pointer from "misdn show stacks" that's not needed anymore and makes the output more unreadable * added cause saving on RELEASE/RELEASE_COMPLETE * set cause to 16 on prepare_bc * removed stack getting from ph_control functions, we don't really need it there * added beroec api git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@38801 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'channels/chan_misdn.c')
-rw-r--r--channels/chan_misdn.c196
1 files changed, 145 insertions, 51 deletions
diff --git a/channels/chan_misdn.c b/channels/chan_misdn.c
index d862a4633..68f319cd1 100644
--- a/channels/chan_misdn.c
+++ b/channels/chan_misdn.c
@@ -140,6 +140,7 @@ struct chan_list {
enum misdn_chan_state state;
int need_queue_hangup;
int need_hangup;
+ int need_busy;
int holded;
int orginator;
@@ -715,6 +716,35 @@ static int misdn_set_crypt_debug(int fd, int argc, char *argv[])
}
+static int misdn_port_block(int fd, int argc, char *argv[])
+{
+ int port;
+
+ if (argc != 4)
+ return RESULT_SHOWUSAGE;
+
+ port = atoi(argv[3]);
+
+ misdn_lib_port_block(port);
+
+ return 0;
+}
+
+static int misdn_port_unblock(int fd, int argc, char *argv[])
+{
+ int port;
+
+ if (argc != 4)
+ return RESULT_SHOWUSAGE;
+
+ port = atoi(argv[3]);
+
+ misdn_lib_port_unblock(port);
+
+ return 0;
+}
+
+
static int misdn_restart_port (int fd, int argc, char *argv[])
{
int port;
@@ -877,6 +907,7 @@ static struct state_struct state_array[] = {
{MISDN_ALERTING,"ALERTING"}, /* when Alerting */
{MISDN_BUSY,"BUSY"}, /* when BUSY */
{MISDN_CONNECTED,"CONNECTED"}, /* when connected */
+ {MISDN_PRECONNECTED,"PRECONNECTED"}, /* when connected */
{MISDN_DISCONNECTED,"DISCONNECTED"}, /* when connected */
{MISDN_RELEASED,"RELEASED"}, /* when connected */
{MISDN_BRIDGED,"BRIDGED"}, /* when bridged */
@@ -909,7 +940,6 @@ static char *misdn_get_ch_state(struct chan_list *p)
static void reload_config(void)
{
int i, cfg_debug;
- chan_misdn_log(-1, 0, "Dynamic Crypting Activation is not support during reload at the moment\n");
free_robin_list();
misdn_cfg_reload();
@@ -1381,6 +1411,19 @@ static struct ast_cli_entry cli_show_cl =
complete_ch
};
+static struct ast_cli_entry cli_port_block=
+{ {"misdn","port","block", NULL},
+ misdn_port_block,
+ "Blocks the given port",
+ "Usage: misdn port block\n"
+};
+
+static struct ast_cli_entry cli_port_unblock=
+{ {"misdn","port","unblock", NULL},
+ misdn_port_unblock,
+ "Unblocks the given port",
+ "Usage: misdn port unblock\n"
+};
static struct ast_cli_entry cli_restart_port =
@@ -1559,12 +1602,12 @@ static void config_jitterbuffer(struct chan_list *ch)
} else {
if (len <=100 || len > 8000) {
- chan_misdn_log(-1,bc->port,"config_jb: Jitterbuffer out of Bounds, setting to 1000\n");
+ chan_misdn_log(0,bc->port,"config_jb: Jitterbuffer out of Bounds, setting to 1000\n");
len=1000;
}
if ( threshold > len ) {
- chan_misdn_log(-1,bc->port,"config_jb: Jitterbuffer Threshold > Jitterbuffer setting to Jitterbuffer -1\n");
+ chan_misdn_log(0,bc->port,"config_jb: Jitterbuffer Threshold > Jitterbuffer setting to Jitterbuffer -1\n");
}
if ( ch->jb) {
@@ -1676,21 +1719,38 @@ static int read_config(struct chan_list *ch, int orig) {
ast_copy_string (ast->context,ch->context,sizeof(ast->context));
{
- int ec, ectr;
+ int ec;
misdn_cfg_get( port, MISDN_CFG_ECHOCANCEL, &ec, sizeof(int));
- misdn_cfg_get( port, MISDN_CFG_ECHOTRAINING, &ectr, sizeof(int));
if (ec == 1 ) {
bc->ec_enable=1;
} else if ( ec > 1 ) {
bc->ec_enable=1;
bc->ec_deftaps=ec;
}
+#ifdef WITH_ECHOTRAINING
+ int ectr;
+ misdn_cfg_get( port, MISDN_CFG_ECHOTRAINING, &ectr, sizeof(int));
if ( ectr >= 0 ) {
bc->ec_training=ectr;
}
+#endif
+
+#ifdef WITH_BEROEC
+ misdn_cfg_get(port, MISDN_CFG_BNECHOCANCEL,&bc->bnec_tail, sizeof(int));
+ misdn_cfg_get(port, MISDN_CFG_BNEC_ANTIHOWL, &bc->bnec_ah, sizeof(int));
+ misdn_cfg_get(port, MISDN_CFG_BNEC_NLP, &bc->bnec_nlp, sizeof(int));
+ misdn_cfg_get(port, MISDN_CFG_BNEC_TD, &bc->bnec_td, sizeof(int));
+ misdn_cfg_get(port, MISDN_CFG_BNEC_ADAPT, &bc->bnec_adapt, sizeof(int));
+ misdn_cfg_get(port, MISDN_CFG_BNEC_ZEROCOEFF, &bc->bnec_zero, sizeof(int));
+
+ if (bc->bnec_tail && bc->ec_enable) {
+ ast_log(LOG_WARNING,"Are you sure you wan't to mix BNEC with Zapec ? This might cause bad audio quality!\n");
+ bc->ec_enable=0;
+ }
+#endif
}
{
@@ -1839,7 +1899,7 @@ static int misdn_call(struct ast_channel *ast, char *dest, int timeout)
if (ext) {
opts=strtok_r(NULL,"/",&tokb);
} else {
- chan_misdn_log(-1,0,"misdn_call: No Extension given!\n");
+ chan_misdn_log(0,0,"misdn_call: No Extension given!\n");
return -1;
}
}
@@ -2265,6 +2325,11 @@ static int misdn_hangup(struct ast_channel *ast)
return 0;
}
+ p->need_hangup=0;
+ p->need_queue_hangup=0;
+ p->need_busy=0;
+
+
if (!p->bc->nt)
stop_bc_tones(p);
@@ -2295,13 +2360,8 @@ static int misdn_hangup(struct ast_channel *ast)
start_bc_tones(p);
hanguptone_indicate(p);
- if (bc->nt) {
- if (bc->need_disconnect)
- misdn_lib_send_event( bc, EVENT_DISCONNECT);
- } else {
- misdn_lib_send_event( bc, EVENT_RELEASE_COMPLETE);
- p->state=MISDN_CLEANING;
- }
+ if (bc->need_disconnect)
+ misdn_lib_send_event( bc, EVENT_DISCONNECT);
break;
case MISDN_CALLING_ACKNOWLEDGE:
@@ -2323,6 +2383,7 @@ static int misdn_hangup(struct ast_channel *ast)
misdn_lib_send_event( bc, EVENT_DISCONNECT);
break;
case MISDN_CONNECTED:
+ case MISDN_PRECONNECTED:
/* Alerting or Disconect */
if (p->bc->nt) {
start_bc_tones(p);
@@ -2755,6 +2816,7 @@ static struct chan_list *init_chan_list(int orig)
cl->orginator=orig;
cl->need_queue_hangup=1;
cl->need_hangup=1;
+ cl->need_busy=1;
cl->overlap_dial_task=-1;
return cl;
@@ -2844,18 +2906,19 @@ static struct ast_channel *misdn_request(const char *type, int format, void *dat
if (!strcasecmp(cfg_group, group)) {
int port_up;
- int check,checkl2;
+ int check;
misdn_cfg_get(port, MISDN_CFG_PMP_L1_CHECK, &check, sizeof(int));
- misdn_cfg_get(port, MISDN_CFG_PP_L2_CHECK, &checkl2, sizeof(int));
- check=checkl2?2:check;
-
port_up = misdn_lib_port_up(port, check);
if (check && !port_up)
chan_misdn_log(1,port,"L1 is not Up on this Port\n");
+ if (check && port_up<0) {
+ ast_log(LOG_WARNING,"This port (%d) is blocked\n", port);
+ }
+
- if ( port_up ) {
+ if ( port_up>0 ) {
newbc = misdn_lib_get_free_bc(port, robin_channel);
if (newbc) {
chan_misdn_log(4, port, " Success! Found port:%d channel:%d\n", newbc->port, newbc->channel);
@@ -2871,7 +2934,7 @@ static struct ast_channel *misdn_request(const char *type, int format, void *dat
} while (!newbc && robin_channel != rr->channel);
if (!newbc)
- chan_misdn_log(4, port, " Failed! No free channel in group %d!", group);
+ chan_misdn_log(-1, port, " Failed! No free channel in group %d!", group);
}
else {
@@ -2883,15 +2946,13 @@ static struct ast_channel *misdn_request(const char *type, int format, void *dat
chan_misdn_log(3,port, "Group [%s] Port [%d]\n", group, port);
if (!strcasecmp(cfg_group, group)) {
int port_up;
- int check,checkl2;
+ int check;
misdn_cfg_get(port, MISDN_CFG_PMP_L1_CHECK, &check, sizeof(int));
- misdn_cfg_get(port, MISDN_CFG_PP_L2_CHECK, &checkl2, sizeof(int));
- check=checkl2?2:check;
port_up = misdn_lib_port_up(port, check);
chan_misdn_log(4, port, "portup:%d\n", port_up);
- if ( port_up ) {
+ if ( port_up>0 ) {
newbc = misdn_lib_get_free_bc(port, 0);
if (newbc)
break;
@@ -3178,9 +3239,11 @@ static void hangup_chan(struct chan_list *ch)
return;
}
+ cb_log(1,ch->bc?ch->bc->port:0,"hangup_chan\n");
if (ch->need_hangup)
{
+ cb_log(1,ch->bc->port,"-> hangup\n");
send_cause2ast(ch->ast,ch->bc,ch);
ch->need_hangup=0;
ch->need_queue_hangup=0;
@@ -3196,7 +3259,10 @@ static void hangup_chan(struct chan_list *ch)
ch->need_queue_hangup=0;
if (ch->ast) {
send_cause2ast(ch->ast,ch->bc,ch);
- ast_queue_hangup(ch->ast);
+
+ if (ch->ast)
+ ast_queue_hangup(ch->ast);
+ cb_log(1,ch->bc->port,"-> queue_hangup\n");
} else {
cb_log(1,ch->bc->port,"Cannot hangup chan, no ast\n");
}
@@ -3385,11 +3451,20 @@ static void send_cause2ast(struct ast_channel *ast, struct misdn_bchannel*bc, st
case 21:
case 17: /* user busy */
- chan_misdn_log(1, bc?bc->port:0, " --> * SEND: Queue Busy pid:%d\n", bc?bc->pid:-1);
ch->state=MISDN_BUSY;
+
+ if (!ch->need_busy) {
+ chan_misdn_log(1,bc?bc->port:0, "Queued busy already\n");
+ break;
+ }
+
+ chan_misdn_log(1, bc?bc->port:0, " --> * SEND: Queue Busy pid:%d\n", bc?bc->pid:-1);
+
ast_queue_control(ast, AST_CONTROL_BUSY);
+ ch->need_busy=0;
+
break;
}
}
@@ -3463,15 +3538,23 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
struct chan_list *ch=find_chan_by_bc(cl_te, bc);
if (event != EVENT_BCHAN_DATA && event != EVENT_TONE_GENERATE) { /* Debug Only Non-Bchan */
- chan_misdn_log(1, bc->port, "I IND :%s oad:%s dad:%s pid:%d state:%s\n", manager_isdn_get_info(event), bc->oad, bc->dad, bc->pid, ch?misdn_get_ch_state(ch):"none");
- misdn_lib_log_ies(bc);
- chan_misdn_log(2,bc->port," --> bc_state:%s\n",bc_state2str(bc->bc_state));
+ int debuglevel=1;
+
+ if ( event==EVENT_CLEANUP && !user_data)
+ debuglevel=5;
+
+ chan_misdn_log(debuglevel, bc->port, "I IND :%s oad:%s dad:%s pid:%d state:%s\n", manager_isdn_get_info(event), bc->oad, bc->dad, bc->pid, ch?misdn_get_ch_state(ch):"none");
+ if (debuglevel==1) {
+ misdn_lib_log_ies(bc);
+ chan_misdn_log(4,bc->port," --> bc_state:%s\n",bc_state2str(bc->bc_state));
+ }
}
if (!ch) {
switch(event) {
case EVENT_SETUP:
case EVENT_DISCONNECT:
+ case EVENT_PORT_ALARM:
break;
case EVENT_RELEASE_COMPLETE:
chan_misdn_log(1, bc->port, " --> no Ch, so we've already released.\n");
@@ -3510,7 +3593,16 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
switch (event) {
-
+ case EVENT_PORT_ALARM:
+ {
+ int boa=0;
+ misdn_cfg_get( bc->port, MISDN_CFG_ALARM_BLOCK, &boa, sizeof(int));
+ if (boa) {
+ cb_log(1,bc->port," --> blocking\n");
+ misdn_lib_port_block(bc->port);
+ }
+ }
+ break;
case EVENT_BCHAN_ACTIVATED:
break;
@@ -3521,21 +3613,11 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
case EVENT_NEW_L3ID:
ch->l3id=bc->l3_id;
ch->addr=bc->addr;
-
- if (bc->nt && ch->state == MISDN_PRECONNECTED ) {
- /* OK we've got the very new l3id so we can answer
- now */
- start_bc_tones(ch);
-
- ch->state = MISDN_CONNECTED;
- ast_queue_control(ch->ast, AST_CONTROL_ANSWER);
-
- }
break;
case EVENT_NEW_BC:
if (bc)
- ch->bc=bc;
+ ch->bc=(struct misdn_bchannel*)user_data;
break;
case EVENT_DTMF_TONE:
@@ -4002,6 +4084,7 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
break;
case EVENT_CONNECT:
{
+ /*we answer when we've got our very new L3 ID from the NT stack */
misdn_lib_send_event(bc,EVENT_CONNECT_ACKNOWLEDGE);
struct ast_channel *bridged=AST_BRIDGED_P(ch->ast);
@@ -4020,11 +4103,6 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
}
}
- /*we answer when we've got our very new L3 ID from the NT stack */
- if (bc->nt) {
- ch->state=MISDN_PRECONNECTED;
- break;
- }
/* notice that we don't break here!*/
@@ -4045,9 +4123,6 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
if (ch) {
struct chan_list *holded_ch=find_holded(cl_te, bc);
- if (ch->ast)
- send_cause2ast(ch->ast,bc,ch);
-
chan_misdn_log(3,bc->port," --> org:%d nt:%d, inbandavail:%d state:%d\n", ch->orginator, bc->nt, misdn_inband_avail(bc), ch->state);
if ( ch->orginator==ORG_AST && !bc->nt && misdn_inband_avail(bc) && ch->state != MISDN_CONNECTED) {
/* If there's inband information available (e.g. a
@@ -4064,11 +4139,12 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
/*Check for holded channel, to implement transfer*/
if (holded_ch && ch->ast ) {
+ cb_log(1,bc->port," --> found holded ch\n");
if (ch->state == MISDN_CONNECTED ) {
misdn_transfer_bc(ch, holded_ch) ;
- misdn_lib_send_event(bc,EVENT_RELEASE_COMPLETE);
- break;
}
+ misdn_lib_send_event(bc,EVENT_RELEASE_COMPLETE);
+ break;
}
stop_bc_tones(ch);
@@ -4085,7 +4161,7 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
hangup_chan(ch);
release_chan(bc);
- if (bc->cause >= 0 && bc->need_release_complete)
+ if (bc->need_release_complete)
misdn_lib_send_event(bc,EVENT_RELEASE_COMPLETE);
}
break;
@@ -4101,6 +4177,15 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
case EVENT_CLEANUP:
{
stop_bc_tones(ch);
+
+ switch(ch->state) {
+ case MISDN_CALLING:
+ bc->cause=27; /* Destination out of order */
+ break;
+ default:
+ break;
+ }
+
hangup_chan(ch);
release_chan(bc);
}
@@ -4378,6 +4463,8 @@ static int unload_module(void *mod)
ast_cli_unregister(&cli_show_port);
ast_cli_unregister(&cli_show_ports_stats);
ast_cli_unregister(&cli_show_stacks);
+ ast_cli_unregister(&cli_port_block);
+ ast_cli_unregister(&cli_port_unblock);
ast_cli_unregister(&cli_restart_port);
ast_cli_unregister(&cli_port_up);
ast_cli_unregister(&cli_port_down);
@@ -4491,6 +4578,8 @@ static int load_module(void *mod)
ast_cli_register(&cli_show_stacks);
ast_cli_register(&cli_show_ports_stats);
+ ast_cli_register(&cli_port_block);
+ ast_cli_register(&cli_port_unblock);
ast_cli_register(&cli_restart_port);
ast_cli_register(&cli_port_up);
ast_cli_register(&cli_port_down);
@@ -4722,6 +4811,10 @@ static int misdn_set_opt_exec(struct ast_channel *chan, void *data)
if (neglect) {
chan_misdn_log(1, ch->bc->port, " --> disabled\n");
ch->bc->ec_enable=0;
+
+#ifdef WITH_BEROEC
+ ch->bc->bnec_tail=0;
+#endif
} else {
ch->bc->ec_enable=1;
ch->bc->orig=ch->orginator;
@@ -5001,6 +5094,7 @@ void chan_misdn_log(int level, int port, char *tmpl, ...)
if (level == -1)
ast_log(LOG_WARNING, buf);
+
else if (misdn_debug_only[port] ?
(level==1 && misdn_debug[port]) || (level==misdn_debug[port])
: level <= misdn_debug[port]) {