diff --git a/channels/chan_misdn.c b/channels/chan_misdn.c index fefef85b7..06c04a233 100644 --- a/channels/chan_misdn.c +++ b/channels/chan_misdn.c @@ -2972,6 +2972,7 @@ static struct ast_channel *misdn_request(const char *type, int format, void *dat char *tokb=NULL, *p=NULL; int channel=0, port=0; struct misdn_bchannel *newbc = NULL; + int dec=0; struct chan_list *cl=init_chan_list(ORG_AST); @@ -3000,23 +3001,27 @@ static struct ast_channel *misdn_request(const char *type, int format, void *dat else { port = atoi(port_str); } - - } else { ast_log(LOG_WARNING, " --> ! IND : CALL dad:%s WITHOUT PORT/Group, check extension.conf\n",ext); return NULL; } + if (misdn_cfg_is_group_method(group, METHOD_STANDARD_DEC)) { + chan_misdn_log(4, port, " --> STARTING STANDARDDEC...\n"); + dec=1; + } + if (!ast_strlen_zero(group)) { char cfg_group[BUFFERSIZE+1]; struct robin_list *rr = NULL; if (misdn_cfg_is_group_method(group, METHOD_ROUND_ROBIN)) { - chan_misdn_log(4, port, " --> STARTING ROUND ROBIN..."); + chan_misdn_log(4, port, " --> STARTING ROUND ROBIN...\n"); rr = get_robin_position(group); } + if (rr) { int robin_channel = rr->channel; int port_start; @@ -3058,7 +3063,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,0); + newbc = misdn_lib_get_free_bc(port, robin_channel,0, 0); if (newbc) { chan_misdn_log(4, port, " Success! Found port:%d channel:%d\n", newbc->port, newbc->channel); if (port_up) @@ -3074,9 +3079,7 @@ static struct ast_channel *misdn_request(const char *type, int format, void *dat if (!newbc) chan_misdn_log(-1, port, " Failed! No free channel in group %d!", group); - } - - else { + } else { for (port=misdn_cfg_get_next_port(0); port > 0; port=misdn_cfg_get_next_port(port)) { @@ -3092,18 +3095,17 @@ 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, 0); + newbc = misdn_lib_get_free_bc(port, 0, 0, dec); if (newbc) break; } } } } - } else { if (channel) chan_misdn_log(1, port," --> preselected_channel: %d\n",channel); - newbc = misdn_lib_get_free_bc(port, channel, 0); + newbc = misdn_lib_get_free_bc(port, channel, 0, dec); } if (!newbc) { @@ -4397,6 +4399,8 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data) cb_log(1,bc->port," --> found holded ch\n"); misdn_transfer_bc(ch, holded_ch) ; } + + bc->need_disconnect=0; stop_bc_tones(ch); hangup_chan(ch); @@ -4413,6 +4417,9 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data) case EVENT_RELEASE: { + bc->need_disconnect=0; + bc->need_release=0; + hangup_chan(ch); release_chan(bc); @@ -4422,6 +4429,10 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data) break; case EVENT_RELEASE_COMPLETE: { + bc->need_disconnect=0; + bc->need_release=0; + bc->need_release_complete=0; + stop_bc_tones(ch); hangup_chan(ch); release_chan(bc); diff --git a/channels/misdn/chan_misdn_config.h b/channels/misdn/chan_misdn_config.h index 55c4166a7..0e0a7b9c4 100644 --- a/channels/misdn/chan_misdn_config.h +++ b/channels/misdn/chan_misdn_config.h @@ -101,7 +101,8 @@ enum misdn_cfg_elements { enum misdn_cfg_method { METHOD_STANDARD = 0, - METHOD_ROUND_ROBIN + METHOD_ROUND_ROBIN, + METHOD_STANDARD_DEC }; /* you must call misdn_cfg_init before any other function of this header file */ diff --git a/channels/misdn/isdn_lib.c b/channels/misdn/isdn_lib.c index 530731102..429242783 100644 --- a/channels/misdn/isdn_lib.c +++ b/channels/misdn/isdn_lib.c @@ -431,7 +431,7 @@ static void dump_chan_list(struct misdn_stack *stack) -static int find_free_chan_in_stack(struct misdn_stack *stack, struct misdn_bchannel *bc, int channel) +static int find_free_chan_in_stack(struct misdn_stack *stack, struct misdn_bchannel *bc, int channel, int dec) { int i; @@ -443,14 +443,25 @@ static int find_free_chan_in_stack(struct misdn_stack *stack, struct misdn_bchan } 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 (3, stack->port, " --> found chan%s: %d\n", channel>=0?" (preselected)":"", i+1); - bc->channel=i+1; - cb_event(EVENT_NEW_CHANNEL, bc, NULL); - return i+1; + + if (dec) { + for (i = stack->b_num-1; i >=0; i--) { + if (i != 15 && (channel < 0 || i == channel)) { /* skip E1 Dchannel ;) and work with chan preselection */ + if (!stack->channels[i]) { + cb_log (3, stack->port, " --> found chan%s: %d\n", channel>=0?" (preselected)":"", i+1); + bc->channel=i+1; + return i+1; + } + } + } + } else { + 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 (3, stack->port, " --> found chan%s: %d\n", channel>=0?" (preselected)":"", i+1); + bc->channel=i+1; + return i+1; + } } } } @@ -541,6 +552,7 @@ static void empty_bc(struct misdn_bchannel *bc) bc->in_use= 0; bc->cw= 0; + bc->dec=0; bc->channel = 0; bc->sending_complete = 0; @@ -690,7 +702,7 @@ static int set_chan_in_stack(struct misdn_stack *stack, int channel) if (!stack->channels[channel-1]) stack->channels[channel-1] = 1; else { - cb_log(0,stack->port,"channel already in use:%d\n", channel ); + cb_log(4,stack->port,"channel already in use:%d\n", channel ); return -1; } } else { @@ -838,7 +850,7 @@ static int create_process (int midev, struct misdn_bchannel *bc) { struct misdn_stack *stack=get_stack_by_bc(bc); if (stack->nt) { - if (!find_free_chan_in_stack(stack, bc, bc->channel_preselected ? bc->channel : 0)) + if (!find_free_chan_in_stack(stack, bc, bc->channel_preselected ? bc->channel : 0, 0)) return -1; /*bc->channel=free_chan;*/ @@ -870,10 +882,11 @@ static int create_process (int midev, struct misdn_bchannel *bc) { } else { if (stack->ptp || bc->te_choose_channel) { /* we know exactly which channels are in use */ - if (!find_free_chan_in_stack(stack, bc, bc->channel_preselected ? bc->channel : 0)) + if (!find_free_chan_in_stack(stack, bc, bc->channel_preselected ? bc->channel : 0, 0)) return -1; /*bc->channel=free_chan;*/ cb_log(2,stack->port, " --> found channel: %d\n", bc->channel); + if (set_chan_in_stack(stack ,bc->channel)<0) return -1; } else { /* other phones could have made a call also on this port (ptmp) */ @@ -1509,7 +1522,7 @@ static int handle_event ( struct misdn_bchannel *bc, enum event_e event, iframe_ case EVENT_SETUP: { if (bc->channel == 0xff) { - if (!find_free_chan_in_stack(stack, bc, 0)) { + if (!find_free_chan_in_stack(stack, bc, 0, 0)) { cb_log(0, stack->port, "Any Channel Requested, but we have no more!!\n"); bc->out_cause=34; misdn_lib_send_event(bc,EVENT_RELEASE_COMPLETE); @@ -1558,7 +1571,7 @@ static int handle_cr ( struct misdn_stack *stack, iframe_t *frm) case CC_NEW_CR|INDICATION: cb_log(7, stack->port, " --> lib: NEW_CR Ind with l3id:%x on this port.\n",frm->dinfo); - struct misdn_bchannel* bc=misdn_lib_get_free_bc(stack->port, 0, 1); + struct misdn_bchannel* bc=misdn_lib_get_free_bc(stack->port, 0, 1, 0); if (!bc) { cb_log(0, stack->port, " --> !! lib: No free channel!\n"); return -1; @@ -1796,7 +1809,7 @@ handle_event_nt(void *dat, void *arg) case CC_SETUP|INDICATION: { - struct misdn_bchannel* bc=misdn_lib_get_free_bc(stack->port, 0, 1); + struct misdn_bchannel* bc=misdn_lib_get_free_bc(stack->port, 0, 1, 0); if (!bc) ERR_NO_CHANNEL: { @@ -2038,8 +2051,7 @@ handle_event_nt(void *dat, void *arg) switch (event) { case EVENT_SETUP: if (bc->channel<=0 || bc->channel==0xff) { - bc->channel=find_free_chan_in_stack(stack,bc, 0); - + bc->channel=find_free_chan_in_stack(stack,bc, 0,0); if (bc->channel<=0) goto ERR_NO_CHANNEL; } else if (!stack->ptp) @@ -3053,7 +3065,7 @@ static void prepare_bc(struct misdn_bchannel*bc, int channel) #endif } -struct misdn_bchannel* misdn_lib_get_free_bc(int port, int channel, int inout) +struct misdn_bchannel* misdn_lib_get_free_bc(int port, int channel, int inout, int dec) { struct misdn_stack *stack; int i; @@ -3086,17 +3098,29 @@ struct misdn_bchannel* misdn_lib_get_free_bc(int port, int channel, int inout) } int maxnum=inout&&!stack->pri&&!stack->ptp?stack->b_num+1:stack->b_num; - //int maxnum=stack->b_num+1; - cb_log(0,0,"maxnum:%d",maxnum); - for (i = 0; i bc[i].in_use) { - /* 3. channel on bri means CW*/ - if (!stack->pri && i==stack->b_num) - stack->bc[i].cw=1; + if (dec) { + for (i = maxnum-1; i>=0; 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); + stack->bc[i].dec=1; + return &stack->bc[i]; + } + } + } else { + for (i = 0; i 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]; + prepare_bc(&stack->bc[i], channel); + return &stack->bc[i]; + } } } @@ -3218,7 +3242,7 @@ int misdn_lib_send_event(struct misdn_bchannel *bc, enum event_e event ) if (stack->nt) { if (bc->channel <=0 ) { /* else we have the channel already */ - if (!find_free_chan_in_stack(stack, bc, 0)) { + if (!find_free_chan_in_stack(stack, bc, 0,0)) { cb_log(0, stack->port, " No free channel at the moment\n"); /*FIXME: add disconnect*/ err=-ENOCHAN; diff --git a/channels/misdn/isdn_lib.h b/channels/misdn/isdn_lib.h index f8742f81e..8e47b1643 100644 --- a/channels/misdn/isdn_lib.h +++ b/channels/misdn/isdn_lib.h @@ -214,6 +214,7 @@ struct misdn_bchannel { int need_release; int need_release_complete; + int dec; /** var stuff**/ int l3_id; int pid; @@ -398,7 +399,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, int inout); +struct misdn_bchannel* misdn_lib_get_free_bc(int port, int channel, int inout, int dec); 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 9f6a3b767..70f1c793c 100644 --- a/channels/misdn_config.c +++ b/channels/misdn_config.c @@ -658,9 +658,12 @@ int misdn_cfg_is_port_valid (int port) int misdn_cfg_is_group_method (char *group, enum misdn_cfg_method meth) { int i, re = 0; - char *method = NULL; + char *method ; misdn_cfg_lock(); + + method = port_cfg[0][map[MISDN_CFG_METHOD]].str; + for (i = 1; i <= max_ports; i++) { if (port_cfg[i] && port_cfg[i][map[MISDN_CFG_GROUPNAME]].str) { if (!strcasecmp(port_cfg[i][map[MISDN_CFG_GROUPNAME]].str, group)) @@ -668,12 +671,15 @@ int misdn_cfg_is_group_method (char *group, enum misdn_cfg_method meth) port_cfg[i][map[MISDN_CFG_METHOD]].str : port_cfg[0][map[MISDN_CFG_METHOD]].str); } } + if (method) { switch (meth) { case METHOD_STANDARD: re = !strcasecmp(method, "standard"); break; case METHOD_ROUND_ROBIN: re = !strcasecmp(method, "round_robin"); break; + case METHOD_STANDARD_DEC: re = !strcasecmp(method, "standard_dec"); + break; } } misdn_cfg_unlock();