diff options
-rw-r--r-- | channels/chan_misdn.c | 14 | ||||
-rw-r--r-- | channels/misdn/chan_misdn_config.h | 1 | ||||
-rw-r--r-- | channels/misdn/isdn_lib.c | 80 | ||||
-rw-r--r-- | channels/misdn/isdn_lib.h | 12 | ||||
-rw-r--r-- | channels/misdn_config.c | 4 | ||||
-rw-r--r-- | configs/misdn.conf.sample | 11 |
6 files changed, 97 insertions, 25 deletions
diff --git a/channels/chan_misdn.c b/channels/chan_misdn.c index a048e70fb..151b6a51b 100644 --- a/channels/chan_misdn.c +++ b/channels/chan_misdn.c @@ -2935,7 +2935,7 @@ static struct ast_channel *misdn_request(const char *type, int format, void *dat if ( port_up>0 ) { - newbc = misdn_lib_get_free_bc(port, robin_channel); + newbc = misdn_lib_get_free_bc(port, robin_channel,0); if (newbc) { chan_misdn_log(4, port, " Success! Found port:%d channel:%d\n", newbc->port, newbc->channel); if (port_up) @@ -2969,7 +2969,7 @@ static struct ast_channel *misdn_request(const char *type, int format, void *dat chan_misdn_log(4, port, "portup:%d\n", port_up); if ( port_up>0 ) { - newbc = misdn_lib_get_free_bc(port, 0); + newbc = misdn_lib_get_free_bc(port, 0, 0); if (newbc) break; } @@ -2980,7 +2980,7 @@ static struct ast_channel *misdn_request(const char *type, int format, void *dat } else { if (channel) chan_misdn_log(1, port," --> preselected_channel: %d\n",channel); - newbc = misdn_lib_get_free_bc(port, channel); + newbc = misdn_lib_get_free_bc(port, channel, 0); } if (!newbc) { @@ -3830,6 +3830,14 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data) } + if (bc->cw) { + chan_misdn_log(0, bc->port, " --> Call Waiting on PMP sending RELEASE_COMPLETE\n"); + int cause; + misdn_cfg_get( bc->port, MISDN_CFG_REJECT_CAUSE, &cause, sizeof(cause)); + bc->out_cause=cause?cause:16; + return RESPONSE_RELEASE_SETUP; + } + print_bearer(bc); { diff --git a/channels/misdn/chan_misdn_config.h b/channels/misdn/chan_misdn_config.h index 04376c3cd..f43f3447c 100644 --- a/channels/misdn/chan_misdn_config.h +++ b/channels/misdn/chan_misdn_config.h @@ -29,6 +29,7 @@ enum misdn_cfg_elements { MISDN_CFG_TXGAIN, /* int */ MISDN_CFG_TE_CHOOSE_CHANNEL, /* int (bool) */ MISDN_CFG_PMP_L1_CHECK, /* int (bool) */ + MISDN_CFG_REJECT_CAUSE, /* int */ MISDN_CFG_ALARM_BLOCK, /* int (bool) */ MISDN_CFG_HDLC, /* int (bool) */ MISDN_CFG_CONTEXT, /* char[] */ diff --git a/channels/misdn/isdn_lib.c b/channels/misdn/isdn_lib.c index 2f69d1759..b22e4d61e 100644 --- a/channels/misdn/isdn_lib.c +++ b/channels/misdn/isdn_lib.c @@ -109,7 +109,7 @@ struct misdn_stack* get_stack_by_bc(struct misdn_bchannel *bc) for ( ; stack; stack=stack->next) { int i; - for (i=0; i <stack->b_num; i++) { + for (i=0; i <=stack->b_num; i++) { if ( bc->port == stack->port) return stack; } } @@ -418,7 +418,7 @@ static void dump_chan_list(struct misdn_stack *stack) { int i; - for (i=0; i <stack->b_num; i++) { + for (i=0; i <= stack->b_num; i++) { cb_log(6, stack->port, "Idx:%d stack->cchan:%d Chan:%d\n",i,stack->channels[i], i+1); } } @@ -535,6 +535,7 @@ static void empty_bc(struct misdn_bchannel *bc) bc->in_use= 0; + bc->cw= 0; bc->channel = 0; @@ -667,7 +668,7 @@ static void clear_l3(struct misdn_stack *stack) { int i; - for (i=0; i<stack->b_num; i++) { + for (i=0; i<=stack->b_num; i++) { if (global_state == MISDN_INITIALIZED) { cb_event(EVENT_CLEANUP, &stack->bc[i], NULL); empty_chan_in_stack(stack,i+1); @@ -1163,7 +1164,7 @@ struct misdn_stack* stack_init( int midev, int port, int ptp ) stack->d_stid = stinf->id; stack->b_num = stinf->childcnt; - for (i=0; i<stinf->childcnt; i++) + for (i=0; i<=stinf->childcnt; i++) stack->b_stids[i] = stinf->child[i]; switch(stinf->pid.protocol[0] & ~ISDN_PID_FEATURE_MASK) { @@ -1376,7 +1377,7 @@ static struct misdn_stack * find_stack_by_mgr(manager_t* mgr_nt) static struct misdn_bchannel *find_bc_by_masked_l3id(struct misdn_stack *stack, unsigned long l3id, unsigned long mask) { int i; - for (i=0; i<stack->b_num; i++) { + for (i=0; i<=stack->b_num; i++) { if ( (stack->bc[i].l3_id & mask) == (l3id & mask)) return &stack->bc[i] ; } return stack_holder_find(stack,l3id); @@ -1386,7 +1387,7 @@ static struct misdn_bchannel *find_bc_by_masked_l3id(struct misdn_stack *stack, struct misdn_bchannel *find_bc_by_l3id(struct misdn_stack *stack, unsigned long l3id) { int i; - for (i=0; i<stack->b_num; i++) { + for (i=0; i<=stack->b_num; i++) { if (stack->bc[i].l3_id == l3id) return &stack->bc[i] ; } return stack_holder_find(stack,l3id); @@ -1395,7 +1396,7 @@ struct misdn_bchannel *find_bc_by_l3id(struct misdn_stack *stack, unsigned long static struct misdn_bchannel *find_bc_holded(struct misdn_stack *stack) { int i; - for (i=0; i<stack->b_num; i++) { + for (i=0; i<=stack->b_num; i++) { if (stack->bc[i].holded ) return &stack->bc[i] ; } return NULL; @@ -1410,7 +1411,7 @@ static struct misdn_bchannel *find_bc_by_addr(unsigned long addr) for (stack=glob_mgr->stack_list; stack; stack=stack->next) { - for (i=0; i< stack->b_num; i++) { + for (i=0; i<=stack->b_num; i++) { if ( (stack->bc[i].addr&STACK_ID_MASK)==(addr&STACK_ID_MASK) || stack->bc[i].layer_id== addr ) { return &stack->bc[i]; } @@ -1428,7 +1429,7 @@ struct misdn_bchannel *find_bc_by_confid(unsigned long confid) for (stack=glob_mgr->stack_list; stack; stack=stack->next) { - for (i=0; i< stack->b_num; i++) { + for (i=0; i<=stack->b_num; i++) { if ( stack->bc[i].conf_id==confid ) { return &stack->bc[i]; } @@ -1445,7 +1446,7 @@ static struct misdn_bchannel *find_bc_by_channel(int port, int channel) if (!stack) return NULL; - for (i=0; i< stack->b_num; i++) { + for (i=0; i<=stack->b_num; i++) { if ( stack->bc[i].channel== channel ) { return &stack->bc[i]; } @@ -1535,7 +1536,7 @@ static int handle_event ( struct misdn_bchannel *bc, enum event_e event, iframe_ static int handle_new_process(struct misdn_stack *stack, iframe_t *frm) { - struct misdn_bchannel* bc=misdn_lib_get_free_bc(stack->port, 0); + struct misdn_bchannel* bc=misdn_lib_get_free_bc(stack->port, 0, 1); if (!bc) { @@ -1555,8 +1556,9 @@ static int handle_cr ( struct misdn_stack *stack, iframe_t *frm) switch (frm->prim) { case CC_NEW_CR|INDICATION: cb_log(7, stack->port, " --> lib: NEW_CR Ind with l3id:%x on this port.\n",frm->dinfo); - if (handle_new_process(stack, frm) <0) + if (handle_new_process(stack, frm) <0) { return -1; + } return 1; case CC_NEW_CR|CONFIRM: return 1; @@ -2182,6 +2184,30 @@ static int do_tone(struct misdn_bchannel *bc, int len) } +#ifdef MISDN_SAVE_DATA +static void misdn_save_data(int id, char *p1, int l1, char *p2, int l2) +{ + char n1[32],n2[32]; + + sprintf(n1,"/tmp/misdn-rx-%d.raw",id); + sprintf(n2,"/tmp/misdn-tx-%d.raw",id); + + FILE *rx=fopen(n1,"a+"); + FILE *tx=fopen(n2,"a+"); + + if (!rx || !tx) { + cb_log(0,0,"Couldn't open files: %s\n",strerror(errno)); + return ; + } + + fwrite(p1,1,l1,rx); + fwrite(p2,1,l2,tx); + + fclose(rx); + fclose(tx); + +} +#endif void misdn_tx_jitter(struct misdn_bchannel *bc, int len) { @@ -2193,6 +2219,9 @@ void misdn_tx_jitter(struct misdn_bchannel *bc, int len) jlen=cb_jb_empty(bc,data,len); if (jlen) { +#ifdef MISDN_SAVE_DATA + misdn_save_data((bc->port*100+bc->channel), data, jlen, bc->bframe, bc->bframe_len); +#endif flip_buf_bits( data, jlen); if (jlen < len) { @@ -2207,7 +2236,7 @@ void misdn_tx_jitter(struct misdn_bchannel *bc, int len) txfrm->len =jlen; cb_log(9, bc->port, "Transmitting %d samples 2 misdn\n", txfrm->len); - + r=mISDN_write( glob_mgr->midev, buf, txfrm->len + mISDN_HEADER_LEN, 8000 ); } else { #define MISDN_GEN_SILENCE @@ -2554,6 +2583,8 @@ static int handle_frm(msg_t *msg) if (ret<0) { cb_log(3,stack?stack->port:0,"handle_frm: handle_cr <0 prim:%x addr:%x\n", frm->prim, frm->addr); + + } if(ret) { @@ -2589,8 +2620,9 @@ handle_frm_bc: break; case RESPONSE_IGNORE_SETUP: /* I think we should send CC_RELEASE_CR, but am not sure*/ - bc->out_cause=16; + + case RESPONSE_RELEASE_SETUP: misdn_lib_send_event(bc,EVENT_RELEASE_COMPLETE); if (bc->channel>0) empty_chan_in_stack(stack, bc->channel); @@ -2659,7 +2691,7 @@ static int handle_l1(msg_t *msg) free_msg(msg); } - for (i=0;i<stack->b_num; i++) { + for (i=0;i<=stack->b_num; i++) { if (stack->bc[i].evq != EVENT_NOTHING) { cb_log(4, stack->port, "Fireing Queued Event %s because L1 got up\n", isdn_get_info(msgs_g, stack->bc[i].evq, 0)); misdn_lib_send_event(&stack->bc[i],stack->bc[i].evq); @@ -2683,7 +2715,7 @@ static int handle_l1(msg_t *msg) case PH_DEACTIVATE | INDICATION: cb_log (3, stack->port, "L1: PH L1Link Down! \n"); - for (i=0; i<stack->b_num; i++) { + for (i=0; i<=stack->b_num; i++) { if (global_state == MISDN_INITIALIZED) { cb_event(EVENT_CLEANUP, &stack->bc[i], glob_mgr->user_data); } @@ -3001,7 +3033,7 @@ struct misdn_bchannel *manager_find_bc_by_pid(int pid) for (stack=glob_mgr->stack_list; stack; stack=stack->next) { - for (i=0; i<stack->b_num; i++) + for (i=0; i<=stack->b_num; i++) if (stack->bc[i].pid == pid) return &stack->bc[i]; } @@ -3036,7 +3068,7 @@ static void prepare_bc(struct misdn_bchannel*bc, int channel) #endif } -struct misdn_bchannel* misdn_lib_get_free_bc(int port, int channel) +struct misdn_bchannel* misdn_lib_get_free_bc(int port, int channel, int inout) { struct misdn_stack *stack; int i; @@ -3067,8 +3099,14 @@ struct misdn_bchannel* misdn_lib_get_free_bc(int port, int channel) return NULL; } } - for (i = 0; i < stack->b_num; i++) { + + int maxnum=inout&&!stack->pri&&!stack->ptp?stack->b_num+1:stack->b_num; + for (i = 0; i <maxnum; i++) { if (!stack->bc[i].in_use) { + /* 3. channel on bri means CW*/ + if (!stack->pri && i==stack->b_num) + stack->bc[i].cw=1; + prepare_bc(&stack->bc[i], channel); return &stack->bc[i]; } @@ -3774,7 +3812,7 @@ int misdn_lib_init(char *portlist, struct misdn_lib_iface *iface, void *user_dat { int i; - for(i=0;i<stack->b_num; i++) { + for(i=0;i<=stack->b_num; i++) { int r; if ((r=init_bc(stack, &stack->bc[i], stack->midev,port,i, "", 1))<0) { cb_log(0, port, "Got Err @ init_bc :%d\n",r); @@ -3821,7 +3859,7 @@ void misdn_lib_destroy() int i; for ( help=glob_mgr->stack_list; help; help=help->next ) { - for(i=0;i<help->b_num; i++) { + for(i=0;i<=help->b_num; i++) { char buf[1024]; mISDN_write_frame(help->midev, buf, help->bc[i].addr, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC); help->bc[i].addr = 0; diff --git a/channels/misdn/isdn_lib.h b/channels/misdn/isdn_lib.h index 4eda56cbf..7b9c88dda 100644 --- a/channels/misdn/isdn_lib.h +++ b/channels/misdn/isdn_lib.h @@ -20,6 +20,14 @@ /* typedef int ie_nothing_t ;*/ /** end of init usage **/ + +/* + * uncomment the following to make chan_misdn create + * record files in /tmp/misdn-{rx|tx}-PortChannel format + * */ + +/*#define MISDN_SAVE_DATA*/ + #ifdef WITH_BEROEC typedef int beroec_t; @@ -95,6 +103,7 @@ enum mISDN_NUMBER_PLAN { enum event_response_e { RESPONSE_IGNORE_SETUP_WITHOUT_CLOSE, RESPONSE_IGNORE_SETUP, + RESPONSE_RELEASE_SETUP, RESPONSE_ERR, RESPONSE_OK }; @@ -214,6 +223,7 @@ struct misdn_bchannel { int channel_preselected; int in_use; + int cw; int addr; char * bframe; @@ -382,7 +392,7 @@ char *manager_isdn_get_info(enum event_e event); void misdn_lib_transfer(struct misdn_bchannel* holded_bc); -struct misdn_bchannel* misdn_lib_get_free_bc(int port, int channel); +struct misdn_bchannel* misdn_lib_get_free_bc(int port, int channel, int inout); void manager_bchannel_activate(struct misdn_bchannel *bc); void manager_bchannel_deactivate(struct misdn_bchannel * bc); diff --git a/channels/misdn_config.c b/channels/misdn_config.c index c8f70166a..c7131b0e4 100644 --- a/channels/misdn_config.c +++ b/channels/misdn_config.c @@ -271,6 +271,9 @@ static const struct misdn_cfg_spec port_spec[] = { { "max_outgoing", MISDN_CFG_MAX_OUT, MISDN_CTYPE_INT, "-1", NONE, "Defines the maximum amount of outgoing calls per port for this group\n" "\texceeding calls will be rejected" }, + + { "reject_cause", MISDN_CFG_REJECT_CAUSE, MISDN_CTYPE_INT, "21", NONE, + "Defines the cause with which a 3. call is rejected on PTMP BRI."}, { "faxdetect", MISDN_CFG_FAXDETECT, MISDN_CTYPE_STR, "no", NONE, "Setup fax detection:\n" "\t no - no fax detection\n" @@ -302,6 +305,7 @@ static const struct misdn_cfg_spec port_spec[] = { "MSN's for TE ports, listen on those numbers on the above ports, and\n" "\tindicate the incoming calls to Asterisk.\n" "\tHere you can give a comma seperated list, or simply an '*' for any msn." }, + }; static const struct misdn_cfg_spec gen_spec[] = { diff --git a/configs/misdn.conf.sample b/configs/misdn.conf.sample index e077e9089..d2fbfa64f 100644 --- a/configs/misdn.conf.sample +++ b/configs/misdn.conf.sample @@ -203,6 +203,17 @@ te_choose_channel=no pmp_l1_check=yes pp_l2_check=no + + +; +; in PMP this option defines which cause should be sent out to +; the 3. caller. chan_misdn does not support callwaiting on TE +; PMP side. This allows to modify the RELEASE_COMPLETE cause +; at least. +; +reject_cause=16 + + ; ; Send Setup_Acknowledge on incoming calls anyway (instead of PROCEEDING), ; this requests additional Infos, so we can waitfordigits |