Merged revisions 44561 via svnmerge from

https://origsvn.digium.com/svn/asterisk/branches/1.4

................
r44561 | crichter | 2006-10-06 14:50:25 +0200 (Fr, 06 Okt 2006) | 9 lines

Merged revisions 44334 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.2

........
r44334 | crichter | 2006-10-04 17:13:58 +0200 (Mi, 04 Okt 2006) | 1 line

added the option 'reject_cause' to make it possible to set the RELEASE_COMPLETE - cause on the 3. incoming PMP channel, which is automatically rejected because chan_misdn does not support that kind of callwaiting. Therefore chan_misdn supports now 3 incoming channels on a PMP BRI Port. misdn_lib_get_free_bc now gets the info if the requested channel is incoming or outgoing to make the 3. channel possible
........

................


git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@44841 65c4cc65-6c06-0410-ace0-fbb531ad65f3
1.6.0
Christian Richter 19 years ago
parent 05c4624d9b
commit e09ad744af

@ -2941,7 +2941,7 @@ static struct ast_channel *misdn_request(const char *type, int format, void *dat
if ( port_up>0 ) { 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) { if (newbc) {
chan_misdn_log(4, port, " Success! Found port:%d channel:%d\n", newbc->port, newbc->channel); chan_misdn_log(4, port, " Success! Found port:%d channel:%d\n", newbc->port, newbc->channel);
if (port_up) if (port_up)
@ -2975,7 +2975,7 @@ static struct ast_channel *misdn_request(const char *type, int format, void *dat
chan_misdn_log(4, port, "portup:%d\n", port_up); chan_misdn_log(4, port, "portup:%d\n", port_up);
if ( port_up>0 ) { if ( port_up>0 ) {
newbc = misdn_lib_get_free_bc(port, 0); newbc = misdn_lib_get_free_bc(port, 0, 0);
if (newbc) if (newbc)
break; break;
} }
@ -2986,7 +2986,7 @@ static struct ast_channel *misdn_request(const char *type, int format, void *dat
} else { } else {
if (channel) if (channel)
chan_misdn_log(1, port," --> preselected_channel: %d\n",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) { if (!newbc) {
@ -3836,6 +3836,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); print_bearer(bc);
{ {

@ -29,6 +29,7 @@ enum misdn_cfg_elements {
MISDN_CFG_TXGAIN, /* int */ MISDN_CFG_TXGAIN, /* int */
MISDN_CFG_TE_CHOOSE_CHANNEL, /* int (bool) */ MISDN_CFG_TE_CHOOSE_CHANNEL, /* int (bool) */
MISDN_CFG_PMP_L1_CHECK, /* int (bool) */ MISDN_CFG_PMP_L1_CHECK, /* int (bool) */
MISDN_CFG_REJECT_CAUSE, /* int */
MISDN_CFG_ALARM_BLOCK, /* int (bool) */ MISDN_CFG_ALARM_BLOCK, /* int (bool) */
MISDN_CFG_HDLC, /* int (bool) */ MISDN_CFG_HDLC, /* int (bool) */
MISDN_CFG_CONTEXT, /* char[] */ MISDN_CFG_CONTEXT, /* char[] */

@ -109,7 +109,7 @@ struct misdn_stack* get_stack_by_bc(struct misdn_bchannel *bc)
for ( ; stack; stack=stack->next) { for ( ; stack; stack=stack->next) {
int i; 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; if ( bc->port == stack->port) return stack;
} }
} }
@ -184,6 +184,10 @@ void misdn_tx_jitter(struct misdn_bchannel *bc, int len);
struct misdn_bchannel *find_bc_by_l3id(struct misdn_stack *stack, unsigned long l3id); struct misdn_bchannel *find_bc_by_l3id(struct misdn_stack *stack, unsigned long l3id);
struct misdn_bchannel *find_bc_by_confid(unsigned long confid);
struct misdn_bchannel *stack_holder_find_bychan(struct misdn_stack *stack, int chan);
int setup_bc(struct misdn_bchannel *bc); int setup_bc(struct misdn_bchannel *bc);
int manager_isdn_handler(iframe_t *frm ,msg_t *msg); int manager_isdn_handler(iframe_t *frm ,msg_t *msg);
@ -418,7 +422,7 @@ static void dump_chan_list(struct misdn_stack *stack)
{ {
int i; 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); cb_log(6, stack->port, "Idx:%d stack->cchan:%d Chan:%d\n",i,stack->channels[i], i+1);
} }
} }
@ -535,6 +539,7 @@ static void empty_bc(struct misdn_bchannel *bc)
bc->in_use= 0; bc->in_use= 0;
bc->cw= 0;
bc->channel = 0; bc->channel = 0;
@ -667,7 +672,7 @@ static void clear_l3(struct misdn_stack *stack)
{ {
int i; int i;
for (i=0; i<stack->b_num; i++) { for (i=0; i<=stack->b_num; i++) {
if (global_state == MISDN_INITIALIZED) { if (global_state == MISDN_INITIALIZED) {
cb_event(EVENT_CLEANUP, &stack->bc[i], NULL); cb_event(EVENT_CLEANUP, &stack->bc[i], NULL);
empty_chan_in_stack(stack,i+1); empty_chan_in_stack(stack,i+1);
@ -1164,7 +1169,7 @@ struct misdn_stack* stack_init( int midev, int port, int ptp )
stack->d_stid = stinf->id; stack->d_stid = stinf->id;
stack->b_num = stinf->childcnt; 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]; stack->b_stids[i] = stinf->child[i];
switch(stinf->pid.protocol[0] & ~ISDN_PID_FEATURE_MASK) { switch(stinf->pid.protocol[0] & ~ISDN_PID_FEATURE_MASK) {
@ -1377,7 +1382,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) static struct misdn_bchannel *find_bc_by_masked_l3id(struct misdn_stack *stack, unsigned long l3id, unsigned long mask)
{ {
int i; 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] ; if ( (stack->bc[i].l3_id & mask) == (l3id & mask)) return &stack->bc[i] ;
} }
return stack_holder_find(stack,l3id); return stack_holder_find(stack,l3id);
@ -1387,7 +1392,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) struct misdn_bchannel *find_bc_by_l3id(struct misdn_stack *stack, unsigned long l3id)
{ {
int i; 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] ; if (stack->bc[i].l3_id == l3id) return &stack->bc[i] ;
} }
return stack_holder_find(stack,l3id); return stack_holder_find(stack,l3id);
@ -1396,7 +1401,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) static struct misdn_bchannel *find_bc_holded(struct misdn_stack *stack)
{ {
int i; 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] ; if (stack->bc[i].holded ) return &stack->bc[i] ;
} }
return NULL; return NULL;
@ -1411,7 +1416,7 @@ static struct misdn_bchannel *find_bc_by_addr(unsigned long addr)
for (stack=glob_mgr->stack_list; for (stack=glob_mgr->stack_list;
stack; stack;
stack=stack->next) { 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 ) { if ( (stack->bc[i].addr&STACK_ID_MASK)==(addr&STACK_ID_MASK) || stack->bc[i].layer_id== addr ) {
return &stack->bc[i]; return &stack->bc[i];
} }
@ -1429,7 +1434,7 @@ struct misdn_bchannel *find_bc_by_confid(unsigned long confid)
for (stack=glob_mgr->stack_list; for (stack=glob_mgr->stack_list;
stack; stack;
stack=stack->next) { 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 ) { if ( stack->bc[i].conf_id==confid ) {
return &stack->bc[i]; return &stack->bc[i];
} }
@ -1446,7 +1451,7 @@ static struct misdn_bchannel *find_bc_by_channel(int port, int channel)
if (!stack) return NULL; 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 ) { if ( stack->bc[i].channel== channel ) {
return &stack->bc[i]; return &stack->bc[i];
} }
@ -1536,7 +1541,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) 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) { if (!bc) {
@ -1556,8 +1561,9 @@ static int handle_cr ( struct misdn_stack *stack, iframe_t *frm)
switch (frm->prim) { switch (frm->prim) {
case CC_NEW_CR|INDICATION: case CC_NEW_CR|INDICATION:
cb_log(7, stack->port, " --> lib: NEW_CR Ind with l3id:%x on this port.\n",frm->dinfo); 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;
}
return 1; return 1;
case CC_NEW_CR|CONFIRM: case CC_NEW_CR|CONFIRM:
return 1; return 1;
@ -2183,6 +2189,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) void misdn_tx_jitter(struct misdn_bchannel *bc, int len)
{ {
@ -2194,6 +2224,9 @@ void misdn_tx_jitter(struct misdn_bchannel *bc, int len)
jlen=cb_jb_empty(bc,data,len); jlen=cb_jb_empty(bc,data,len);
if (jlen) { 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); flip_buf_bits( data, jlen);
if (jlen < len) { if (jlen < len) {
@ -2208,7 +2241,7 @@ void misdn_tx_jitter(struct misdn_bchannel *bc, int len)
txfrm->len =jlen; txfrm->len =jlen;
cb_log(9, bc->port, "Transmitting %d samples 2 misdn\n", txfrm->len); 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 ); r=mISDN_write( glob_mgr->midev, buf, txfrm->len + mISDN_HEADER_LEN, 8000 );
} else { } else {
#define MISDN_GEN_SILENCE #define MISDN_GEN_SILENCE
@ -2555,6 +2588,8 @@ static int handle_frm(msg_t *msg)
if (ret<0) { if (ret<0) {
cb_log(3,stack?stack->port:0,"handle_frm: handle_cr <0 prim:%x addr:%x\n", frm->prim, frm->addr); cb_log(3,stack?stack->port:0,"handle_frm: handle_cr <0 prim:%x addr:%x\n", frm->prim, frm->addr);
} }
if(ret) { if(ret) {
@ -2590,8 +2625,9 @@ handle_frm_bc:
break; break;
case RESPONSE_IGNORE_SETUP: case RESPONSE_IGNORE_SETUP:
/* I think we should send CC_RELEASE_CR, but am not sure*/ /* I think we should send CC_RELEASE_CR, but am not sure*/
bc->out_cause=16; bc->out_cause=16;
case RESPONSE_RELEASE_SETUP:
misdn_lib_send_event(bc,EVENT_RELEASE_COMPLETE); misdn_lib_send_event(bc,EVENT_RELEASE_COMPLETE);
if (bc->channel>0) if (bc->channel>0)
empty_chan_in_stack(stack, bc->channel); empty_chan_in_stack(stack, bc->channel);
@ -2660,7 +2696,7 @@ static int handle_l1(msg_t *msg)
free_msg(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) { 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)); 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); misdn_lib_send_event(&stack->bc[i],stack->bc[i].evq);
@ -2684,7 +2720,7 @@ static int handle_l1(msg_t *msg)
case PH_DEACTIVATE | INDICATION: case PH_DEACTIVATE | INDICATION:
cb_log (3, stack->port, "L1: PH L1Link Down! \n"); 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) { if (global_state == MISDN_INITIALIZED) {
cb_event(EVENT_CLEANUP, &stack->bc[i], glob_mgr->user_data); cb_event(EVENT_CLEANUP, &stack->bc[i], glob_mgr->user_data);
} }
@ -3002,7 +3038,7 @@ struct misdn_bchannel *manager_find_bc_by_pid(int pid)
for (stack=glob_mgr->stack_list; for (stack=glob_mgr->stack_list;
stack; stack;
stack=stack->next) { 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]; if (stack->bc[i].pid == pid) return &stack->bc[i];
} }
@ -3037,7 +3073,7 @@ static void prepare_bc(struct misdn_bchannel*bc, int channel)
#endif #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; struct misdn_stack *stack;
int i; int i;
@ -3068,8 +3104,14 @@ struct misdn_bchannel* misdn_lib_get_free_bc(int port, int channel)
return NULL; 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) { 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); prepare_bc(&stack->bc[i], channel);
return &stack->bc[i]; return &stack->bc[i];
} }
@ -3775,7 +3817,7 @@ int misdn_lib_init(char *portlist, struct misdn_lib_iface *iface, void *user_dat
{ {
int i; int i;
for(i=0;i<stack->b_num; i++) { for(i=0;i<=stack->b_num; i++) {
int r; int r;
if ((r=init_bc(stack, &stack->bc[i], stack->midev,port,i, "", 1))<0) { 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); cb_log(0, port, "Got Err @ init_bc :%d\n",r);
@ -3822,7 +3864,7 @@ void misdn_lib_destroy()
int i; int i;
for ( help=glob_mgr->stack_list; help; help=help->next ) { 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]; char buf[1024];
mISDN_write_frame(help->midev, buf, help->bc[i].addr, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC); mISDN_write_frame(help->midev, buf, help->bc[i].addr, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
help->bc[i].addr = 0; help->bc[i].addr = 0;

@ -20,6 +20,14 @@
/* typedef int ie_nothing_t ;*/ /* typedef int ie_nothing_t ;*/
/** end of init usage **/ /** 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 #ifdef WITH_BEROEC
typedef int beroec_t; typedef int beroec_t;
@ -95,6 +103,7 @@ enum mISDN_NUMBER_PLAN {
enum event_response_e { enum event_response_e {
RESPONSE_IGNORE_SETUP_WITHOUT_CLOSE, RESPONSE_IGNORE_SETUP_WITHOUT_CLOSE,
RESPONSE_IGNORE_SETUP, RESPONSE_IGNORE_SETUP,
RESPONSE_RELEASE_SETUP,
RESPONSE_ERR, RESPONSE_ERR,
RESPONSE_OK RESPONSE_OK
}; };
@ -214,6 +223,7 @@ struct misdn_bchannel {
int channel_preselected; int channel_preselected;
int in_use; int in_use;
int cw;
int addr; int addr;
char * bframe; char * bframe;
@ -382,7 +392,7 @@ char *manager_isdn_get_info(enum event_e event);
void misdn_lib_transfer(struct misdn_bchannel* holded_bc); 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_activate(struct misdn_bchannel *bc);
void manager_bchannel_deactivate(struct misdn_bchannel * bc); void manager_bchannel_deactivate(struct misdn_bchannel * bc);

@ -271,6 +271,9 @@ static const struct misdn_cfg_spec port_spec[] = {
{ "max_outgoing", MISDN_CFG_MAX_OUT, MISDN_CTYPE_INT, "-1", NONE, { "max_outgoing", MISDN_CFG_MAX_OUT, MISDN_CTYPE_INT, "-1", NONE,
"Defines the maximum amount of outgoing calls per port for this group\n" "Defines the maximum amount of outgoing calls per port for this group\n"
"\texceeding calls will be rejected" }, "\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, { "faxdetect", MISDN_CFG_FAXDETECT, MISDN_CTYPE_STR, "no", NONE,
"Setup fax detection:\n" "Setup fax detection:\n"
"\t no - no 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" "MSN's for TE ports, listen on those numbers on the above ports, and\n"
"\tindicate the incoming calls to Asterisk.\n" "\tindicate the incoming calls to Asterisk.\n"
"\tHere you can give a comma seperated list, or simply an '*' for any msn." }, "\tHere you can give a comma seperated list, or simply an '*' for any msn." },
}; };
static const struct misdn_cfg_spec gen_spec[] = { static const struct misdn_cfg_spec gen_spec[] = {

@ -203,6 +203,17 @@ te_choose_channel=no
pmp_l1_check=yes pmp_l1_check=yes
pp_l2_check=no 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), ; Send Setup_Acknowledge on incoming calls anyway (instead of PROCEEDING),
; this requests additional Infos, so we can waitfordigits ; this requests additional Infos, so we can waitfordigits

Loading…
Cancel
Save