* added possibility to change echocancel settings during calls
authorChristian Richter <christian.richter@beronet.com>
Tue, 8 Aug 2006 09:19:06 +0000 (09:19 +0000)
committerChristian Richter <christian.richter@beronet.com>
Tue, 8 Aug 2006 09:19:06 +0000 (09:19 +0000)
* removed the holded element from the chan_list struct, we know this from the
  state already
* added a few tweaks to make HOLD/RETRIEVE work again (TRANSFER does not work
  yet)
* added possibility to debug mISDN frames via syslog
* added misdn_lib_port_is_blocked function to check if a port is blocked
* removed ec_training=1 from empty_bc, we don't use ec_training anymore
* removed unused misdn_lib_get_l2_status function
* added the nt bit to dummy misdn_bchannel objects
* setting bc->out_fac_type to FACILITY_NONE defaultly
* removed HANDLER_DEBUG stuff for better readability

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@39295 65c4cc65-6c06-0410-ace0-fbb531ad65f3

channels/chan_misdn.c
channels/misdn/fac.c
channels/misdn/isdn_lib.c
channels/misdn/isdn_lib.h
channels/misdn/isdn_msg_parser.c

index 21edb0d..72a26c8 100644 (file)
@@ -142,11 +142,12 @@ struct chan_list {
        int need_hangup;
        int need_busy;
        
-       int holded; 
        int orginator;
 
        int norxtone;
        int notxtone; 
+
+       int toggle_ec;
        
        int incoming_early_audio;
 
@@ -337,6 +338,8 @@ int add_out_calls(int port);
 int add_in_calls(int port);
 
 
+static int update_ec_config(struct misdn_bchannel *bc);
+
 /*************** Helpers *****************/
 
 static struct chan_list * get_chan_by_ast(struct ast_channel *ast)
@@ -987,6 +990,13 @@ static void print_bc_info (int fd, struct chan_list* help, struct misdn_bchannel
                        "  --> state: %s\n"
                        "  --> capability: %s\n"
                        "  --> echo_cancel: %d\n"
+#ifdef WITH_BEROEC
+                       "  --> bnec_tail: %d\n"
+                       "  --> bnec_nlp: %d\n"
+                       "  --> bnec_ah: %d\n"
+                       "  --> bnec_td: %d\n"
+                       "  --> bnec_zerocoeff: %d\n"
+#endif
                        "  --> notone : rx %d tx:%d\n"
                        "  --> bc_hold: %d holded_bc :%d\n",
                        help->ast->name,
@@ -1000,6 +1010,14 @@ static void print_bc_info (int fd, struct chan_list* help, struct misdn_bchannel
                        bc_state2str(bc->bc_state),
                        bearer2str(bc->capability),
                        bc->ec_enable,
+
+#ifdef WITH_BEROEC
+                       bc->bnec_tail,
+                       bc->bnec_nlp,
+                       bc->bnec_ah,
+                       bc->bnec_td,
+                       bc->bnec_zero,
+#endif
                        help->norxtone,help->notxtone,
                        bc->holded, help->holded_bc?1:0
                        );
@@ -1205,9 +1223,11 @@ static int misdn_toggle_echocancel (int fd, int argc, char *argv[])
                        ast_cli(fd, "Toggling EchoCancel %s failed Channel does not exist\n", channame);
                        return 0; 
                } else {
-                       tmp->bc->ec_enable=tmp->bc->ec_enable?0:1;
+                       
+                       tmp->toggle_ec=tmp->toggle_ec?0:1;
 
-                       if (tmp->bc->ec_enable) {
+                       if (tmp->toggle_ec) {
+                               update_ec_config(tmp->bc);
                                manager_ec_enable(tmp->bc);
                        } else {
                                manager_ec_disable(tmp->bc);
@@ -1649,6 +1669,44 @@ void debug_numplan(int port, int numplan, char *type)
 
 
 
+static int update_ec_config(struct misdn_bchannel *bc)
+{
+       int ec;
+       int port=bc->port;
+               
+       misdn_cfg_get( port, MISDN_CFG_ECHOCANCEL, &ec, 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
+       return 0;
+}
+
 
 static int read_config(struct chan_list *ch, int orig) {
 
@@ -1718,41 +1776,9 @@ static int read_config(struct chan_list *ch, int orig) {
        misdn_cfg_get( bc->port, MISDN_CFG_CONTEXT, ch->context, sizeof(ch->context));
        
        ast_copy_string (ast->context,ch->context,sizeof(ast->context));        
-       {
-               int ec;
-               
-               misdn_cfg_get( port, MISDN_CFG_ECHOCANCEL, &ec, 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
-       }
-       
+       update_ec_config(bc);
+
        {
                int eb3;
                
@@ -2141,7 +2167,7 @@ static int misdn_fixup(struct ast_channel *oldast, struct ast_channel *ast)
        
        if (!ast || ! (p=MISDN_ASTERISK_TECH_PVT(ast) )) return -1;
        
-       chan_misdn_log(1, p->bc?p->bc->port:0, "* IND: Got Fixup State:%s Holded:%d L3id:%x\n", misdn_get_ch_state(p), p->holded, p->l3id);
+       chan_misdn_log(1, p->bc?p->bc->port:0, "* IND: Got Fixup State:%s L3id:%x\n", misdn_get_ch_state(p), p->l3id);
        
        p->ast = ast ;
        p->state=MISDN_CONNECTED;
@@ -2539,7 +2565,7 @@ static int misdn_write(struct ast_channel *ast, struct ast_frame *frame)
                return -1;
        }
        
-       if (ch->holded ) {
+       if (ch->state == MISDN_HOLDED) {
                chan_misdn_log(7, ch->bc->port, "misdn_write: Returning because holded\n");
                return 0;
        }
@@ -3349,7 +3375,6 @@ static void misdn_transfer_bc(struct chan_list *tmp_ch, struct chan_list *holded
        ast_moh_stop(AST_BRIDGED_P(holded_chan->ast));
 
        holded_chan->state=MISDN_CONNECTED;
-       holded_chan->holded=0;
        misdn_lib_transfer(holded_chan->bc?holded_chan->bc:holded_chan->holded_bc);
        ast_channel_masquerade(holded_chan->ast, AST_BRIDGED_P(tmp_ch->ast));
 }
@@ -3559,6 +3584,8 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
                        case EVENT_SETUP:
                        case EVENT_DISCONNECT:
                        case EVENT_PORT_ALARM:
+                       case EVENT_RETRIEVE:
+                       case EVENT_NEW_BC:
                                break;
                        case EVENT_RELEASE_COMPLETE:
                                chan_misdn_log(1, bc->port, " --> no Ch, so we've already released.\n");
@@ -3620,6 +3647,15 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
                break;
 
        case EVENT_NEW_BC:
+               if (!ch) {
+                       ch=find_holded(cl_te,bc);
+               }
+               
+               if (!ch) {
+                       ast_log(LOG_WARNING,"NEW_BC without chan_list?\n");
+                       break;
+               }
+
                if (bc)
                        ch->bc=(struct misdn_bchannel*)user_data;
                break;
@@ -4147,7 +4183,8 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
                        if  (ch->state == MISDN_CONNECTED ) {
                                misdn_transfer_bc(ch, holded_ch) ;
                        }
-                       misdn_lib_send_event(bc,EVENT_RELEASE_COMPLETE);
+                       hangup_chan(ch);
+                       release_chan(bc);
                        break;
                }
                
@@ -4333,6 +4370,12 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
        /***************************/
        case EVENT_RETRIEVE:
        {
+               ch=find_holded(cl_te, bc);
+               if (!ch) {
+                       ast_log(LOG_WARNING, "Found no Holded channel, cannot Retrieve\n");
+                       misdn_lib_send_event(bc, EVENT_RETRIEVE_REJECT);
+                       break;
+               }
                struct ast_channel *hold_ast=AST_BRIDGED_P(ch->ast);
                ch->state = MISDN_CONNECTED;
                
index 994d8cf..383a60f 100644 (file)
@@ -264,8 +264,8 @@ void fac_dec( unsigned char *p, Q931_info_t *qi, enum facility_type *type,  unio
 {
        int i, fac_len=0;
        unsigned char facility[256];
-       
-       if (! (bc->nt) )
+
+       if (!bc->nt)
        {
                p = NULL;
                if (qi->QI_ELEMENT(facility))
@@ -274,10 +274,10 @@ void fac_dec( unsigned char *p, Q931_info_t *qi, enum facility_type *type,  unio
        if (!p)
                return;
        
-       fac_len = p[0];
+       fac_len = p[0] & 0xff;
+
        memcpy(facility, p+1, fac_len);
        
-       
        switch(facility[0]) {
        case FACILITY_CENTREX:
        {
index eb26cd9..8209df9 100644 (file)
@@ -11,6 +11,8 @@
  * the GNU General Public License
  */
 
+
+#include <syslog.h>
 #include "isdn_lib_intern.h"
 #include <mISDNuser/isdn_debug.h>
 
@@ -66,6 +68,17 @@ int misdn_lib_port_unblock(int port)
 
 }
 
+int misdn_lib_is_port_blocked(int port)
+{      
+       struct misdn_stack *stack=get_misdn_stack();
+       for ( ; stack; stack=stack->next) {
+               if (stack->port == port) {
+                       return stack->blocked;
+               }
+       }
+       return -1;
+}
+
 int misdn_lib_is_ptp(int port)
 {
        struct misdn_stack *stack=get_misdn_stack();
@@ -367,14 +380,12 @@ int send_msg (int midev, struct misdn_bchannel *bc, msg_t *dmsg)
        }
        
        frm->addr = (stack->upper_id | FLG_MSG_DOWN);
-
-       
        frm->dinfo = bc->l3_id;
-  
        frm->len = (dmsg->len) - mISDN_HEADER_LEN;
-       
+                               
+       cb_log(4,stack->port,"Sending msg, prim:%x addr:%x dinfo:%x\n",frm->prim,frm->addr,frm->dinfo);
+
        mISDN_write(midev, dmsg->data, dmsg->len, TIMEOUT_1SEC);
-  
        free_msg(dmsg);
 
        return 0;
@@ -528,8 +539,10 @@ void empty_bc(struct misdn_bchannel *bc)
 {
        bc->bframe_len=0;
        
+
+       bc->in_use= 0;
+
        bc->channel = 0;
-       bc->in_use = 0;
 
        bc->sending_complete = 0;
 
@@ -569,8 +582,10 @@ void empty_bc(struct misdn_bchannel *bc)
        bc->ec_enable = 0;
        bc->ec_deftaps = 128;
        bc->ec_whenbridged = 0;
+
+#ifdef EC_TRAIN
        bc->ec_training = 1;
-       
+#endif
        
        bc->orig=0;
   
@@ -605,6 +620,7 @@ void empty_bc(struct misdn_bchannel *bc)
        bc->orig_dad[0] = 0;
        
        bc->fac_type=FACILITY_NONE;
+       bc->out_fac_type=FACILITY_NONE;
        
        bc->te_choose_channel = 0;
 
@@ -638,22 +654,15 @@ int clean_up_bc(struct misdn_bchannel *bc)
        
        manager_bchannel_deactivate(bc);
 
-#ifdef WITH_BEROEC
-       if (bc->ec)
-               beroec_destroy(bc->ec);
-       bc->ec=NULL;
-#endif
 
-       if ( misdn_cap_is_speech(bc->capability) && bc->ec_enable) {
-               manager_ec_disable(bc);
-       }
+       manager_ec_disable(bc);
+
 
        mISDN_write_frame(stack->midev, buff, bc->layer_id|FLG_MSG_TARGET|FLG_MSG_DOWN, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
        
        /*mISDN_clear_stack(stack->midev, bc->b_stid);*/
 
        
-
        bc->b_stid = 0;
        bc_state_change(bc, BCHAN_CLEANED);
        
@@ -800,18 +809,6 @@ int misdn_lib_get_l2_te_ptp_up(struct misdn_stack *stack)
        return 0;
 }
 
-int misdn_lib_get_l2_status(struct misdn_stack *stack)
-{
-       iframe_t act;
-       
-       act.prim = DL_ESTABLISH | REQUEST;
-
-       act.addr = (stack->upper_id | FLG_MSG_DOWN)  ;
-
-       act.dinfo = 0;
-       act.len = 0;
-       return mISDN_write(stack->midev, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
-}
 
 int misdn_lib_get_short_status(struct misdn_stack *stack)
 {
@@ -1044,7 +1041,6 @@ int setup_bc(struct misdn_bchannel *bc)
                return(-EINVAL);
        }
 
-
        ret = mISDN_get_setstack_ind(midev, bc->layer_id);
 
        if (ret) {
@@ -1308,6 +1304,17 @@ struct misdn_stack* stack_init( int midev, int port, int ptp )
                         * up L1s*/
                        stack->l1link=0;
                }
+               stack->l1link=0;
+               stack->l2link=0;
+#if 0  
+               if (!stack->nt) {
+                       misdn_lib_get_short_status(stack);
+               } else {
+                       misdn_lib_get_l1_up(stack);
+                       if (!stack->ptp) misdn_lib_get_l1_up(stack);
+                       misdn_lib_get_l2_up(stack);
+               }
+#endif
 
                misdn_lib_get_short_status(stack);
                misdn_lib_get_l1_up(stack);
@@ -1570,6 +1577,7 @@ int handle_cr ( struct misdn_stack *stack, iframe_t *frm)
                                memset (&dummybc,0,sizeof(dummybc));
                                dummybc.port=stack->port;
                                dummybc.l3_id=frm->dinfo;
+                               dummybc.nt=stack->nt;
                                bc=&dummybc; 
                        }
       
@@ -1768,9 +1776,13 @@ handle_event_nt(void *dat, void *arg)
                        struct misdn_bchannel *hold_bc=stack_holder_find(stack,bc->l3_id);
 
                        if (hold_bc) {
-                               cb_event(EVENT_NEW_BC, hold_bc, bc);
+
                                cb_log(4, stack->port, "REMOVEING Holder\n");
                                stack_holder_remove(stack, hold_bc);
+
+                               memcpy(bc,hold_bc,sizeof(struct misdn_bchannel));
+                               cb_event(EVENT_NEW_BC, hold_bc, bc);
+
                                free(hold_bc);
                        }
                        
@@ -1923,6 +1935,7 @@ handle_event_nt(void *dat, void *arg)
                                memset (&dummybc,0,sizeof(dummybc));
                                dummybc.port=stack->port;
                                dummybc.l3_id=hh->dinfo;
+                               dummybc.nt=stack->nt;
                                bc=&dummybc; 
                        }
        
@@ -2025,6 +2038,7 @@ handle_event_nt(void *dat, void *arg)
                        memset (&dummybc,0,sizeof(dummybc));
                        dummybc.port=stack->port;
                        dummybc.l3_id=hh->dinfo;
+                       dummybc.nt=stack->nt;
                        bc=&dummybc; 
                }
                if (bc ) {
@@ -2554,13 +2568,11 @@ int handle_frm(msg_t *msg)
        
        struct misdn_stack *stack=find_stack_by_addr(frm->addr);
 
-       
-       cb_log(4,stack?stack->port:0,"handle_frm: frm->addr:%x frm->prim:%x\n",frm->addr,frm->prim);
-       
-  
        if (!stack || stack->nt) {
                return 0;
        }
+       
+       cb_log(4,stack?stack->port:0,"handle_frm: frm->addr:%x frm->prim:%x\n",frm->addr,frm->prim);
 
        {
                struct misdn_bchannel *bc;
@@ -2648,7 +2660,7 @@ int handle_l1(msg_t *msg)
        int i ;
        
        if (!stack) return 0 ;
-  
+
        switch (frm->prim) {
        case PH_ACTIVATE | CONFIRM:
        case PH_ACTIVATE | INDICATION:
@@ -3136,7 +3148,7 @@ void misdn_lib_log_ies(struct misdn_bchannel *bc)
        cb_log(4, stack->port, " --> screen:%d --> pres:%d\n",
                        bc->screen, bc->pres);
        
-       cb_log(4, stack->port, " --> addr:%x l3id:%x b_stid:%x layer_id:%x\n", bc->pid, bc->addr, bc->l3_id, bc->b_stid, bc->layer_id);
+       cb_log(4, stack->port, " --> addr:%x l3id:%x b_stid:%x layer_id:%x\n", bc->addr, bc->l3_id, bc->b_stid, bc->layer_id);
        
        cb_log(4, stack->port, " --> facility:%s out_facility:%s\n",fac2str(bc->fac_type),fac2str(bc->out_fac_type));
 
@@ -3200,6 +3212,9 @@ int misdn_lib_send_event(struct misdn_bchannel *bc, enum event_e event )
 
        case EVENT_CONNECT:
        case EVENT_RETRIEVE_ACKNOWLEDGE:
+
+               bc->holded=0;
+               
                if (stack->nt) {
                        if (bc->channel <=0 ) { /*  else we have the channel already */
                                bc->channel = find_free_chan_in_stack(stack, bc, 0);
@@ -3212,48 +3227,36 @@ int misdn_lib_send_event(struct misdn_bchannel *bc, enum event_e event )
                        }
                        /* Its that i generate channels */
                }
-               
+
                ret=setup_bc(bc);
                if (ret == -EINVAL) {
                        cb_log(0,bc->port,"send_event: setup_bc failed\n");
                }
-               
-               if ( (event == EVENT_CONNECT ) && misdn_cap_is_speech(bc->capability) ) {
-                       if ( *bc->crypt_key ) {
-                               cb_log(4, stack->port,  " --> ENABLING BLOWFISH channel:%d oad%d:%s dad%d:%s \n", bc->channel, bc->onumplan,bc->oad, bc->dnumplan,bc->dad);
-                               
-                               manager_ph_control_block(bc,  BF_ENABLE_KEY, bc->crypt_key, strlen(bc->crypt_key) );
-                       }
-                       
-                       if (!bc->nodsp) manager_ph_control(bc,  DTMF_TONE_START, 0);
-                       
-                       if (bc->ec_enable) manager_ec_enable(bc);
-
-#ifdef WITH_BEROEC
-                       if (!bec_initialized) bc->bnec_tail=0;
-
-                       if (bc->bnec_tail) {
-                               bc->ec=beroec_new(bc->bnec_tail, BEROEC_SUBBAND, bc->bnec_ah,
-                               bc->bnec_td, bc->bnec_zero, bc->bnec_adapt, bc->bnec_nlp);
-                       }
-#endif
 
+               cb_log(0,bc->port,"After SETUP BC\n");
 
-                       
-                       if (bc->txgain != 0) {
-                               cb_log(4, stack->port,  "--> Changing txgain to %d\n", bc->txgain);
-                               manager_ph_control(bc, VOL_CHANGE_TX, bc->txgain);
-                       }
-                       
-                       if ( bc->rxgain != 0 ) {
-                               cb_log(4, stack->port,  "--> Changing rxgain to %d\n", bc->rxgain);
-                               manager_ph_control(bc, VOL_CHANGE_RX, bc->rxgain);
-                       }
-                       
-               }
                
-               if (event == EVENT_RETRIEVE_ACKNOWLEDGE) {
-                       cb_log(0,bc->port,"DO WE NEED TO DO SOMETHING HERE WITH THE BC ?\n");
+               if (misdn_cap_is_speech(bc->capability)) {
+                       if ((event==EVENT_CONNECT)||(event==EVENT_RETRIEVE_ACKNOWLEDGE)) {
+                               if ( *bc->crypt_key ) {
+                                       cb_log(4, stack->port,  " --> ENABLING BLOWFISH channel:%d oad%d:%s dad%d:%s \n", bc->channel, bc->onumplan,bc->oad, bc->dnumplan,bc->dad);
+                                       
+                                       manager_ph_control_block(bc,  BF_ENABLE_KEY, bc->crypt_key, strlen(bc->crypt_key) );
+                               }
+                               
+                               if (!bc->nodsp) manager_ph_control(bc,  DTMF_TONE_START, 0);
+                               manager_ec_enable(bc);
+                               
+                               if (bc->txgain != 0) {
+                                       cb_log(4, stack->port,  "--> Changing txgain to %d\n", bc->txgain);
+                                       manager_ph_control(bc, VOL_CHANGE_TX, bc->txgain);
+                               }
+                               
+                               if ( bc->rxgain != 0 ) {
+                                       cb_log(4, stack->port,  "--> Changing rxgain to %d\n", bc->rxgain);
+                                       manager_ph_control(bc, VOL_CHANGE_RX, bc->rxgain);
+                               }
+                       }
                }
                break;
 
@@ -3325,16 +3328,7 @@ int misdn_lib_send_event(struct misdn_bchannel *bc, enum event_e event )
                
                if (misdn_cap_is_speech(bc->capability)) {
                        if (  !bc->nodsp) manager_ph_control(bc,  DTMF_TONE_START, 0);
-                       if (bc->ec_enable) manager_ec_enable(bc);
-#ifdef WITH_BEROEC
-                       if (!bec_initialized) bc->bnec_tail=0;
-
-                       if (bc->bnec_tail) {
-                               bc->ec=beroec_new(bc->bnec_tail, BEROEC_SUBBAND, bc->bnec_ah,
-                               bc->bnec_td, bc->bnec_zero, bc->bnec_adapt, bc->bnec_nlp);
-                       }
-#endif
-
+                       manager_ec_enable(bc);
 
                        if ( bc->txgain != 0 ) {
                                cb_log(4, stack->port, "--> Changing txgain to %d\n", bc->txgain);
@@ -3470,22 +3464,18 @@ int manager_isdn_handler(iframe_t *frm ,msg_t *msg)
        }
 
        if ( ((frm->addr | ISDN_PID_BCHANNEL_BIT )>> 28 ) == 0x5) {
-#ifdef MISDN_HANDLER_DEBUG
-               cb_log(0,0,"handle_bchan START\n");
-#endif
                if (handle_bchan(msg)) {
-#ifdef MISDN_HANDLER_DEBUG
-                       cb_log(0,0,"handle_bchan STOP\n");
-#endif
                        return 0 ;
                }
-#ifdef MISDN_HANDLER_DEBUG
-               cb_log(0,0,"handle_bchan NOTSTOP\n");
-#endif 
        }       
-       
+
+#ifdef RECV_FRM_SYSLOG_DEBUG
+       syslog(LOG_NOTICE,"mISDN recv: P(%02d): ADDR:%x PRIM:%x DINFO:%x\n",stack->port, frm->addr, frm->prim, frm->dinfo);
+#endif
+
        if (handle_timers(msg)) 
                return 0 ;
+
        
        if (handle_mgmt(msg)) 
                return 0 ; 
@@ -3497,45 +3487,18 @@ int manager_isdn_handler(iframe_t *frm ,msg_t *msg)
        if (handle_l1(msg)) 
                return 0 ;
        
-#ifdef MISDN_HANDLER_DEBUG
-       cb_log(0,0,"handle_frm_nt START\n");
-#endif
        if (handle_frm_nt(msg)) {
-#ifdef MISDN_HANDLER_DEBUG
-               cb_log(0,0,"handle_frm_nt STOP\n");
-#endif
                return 0;
        }
-#ifdef MISDN_HANDLER_DEBUG
-       cb_log(0,0,"handle_frm_nt NOTSTOP\n");
-       
-       cb_log(0,0,"handle_frm START\n");
-#endif
-       
+
        if (handle_frm(msg)) {
-#ifdef MISDN_HANDLER_DEBUG
-               cb_log(0,0,"handle_frm STOP\n");
-#endif
-               
                return 0;
        }
-#ifdef MISDN_HANDLER_DEBUG
-       cb_log(0,0,"handle_frm NOTSTOP\n");     
-       
-       cb_log(0,0,"handle_err START\n");
-#endif
-       
+
        if (handle_err(msg)) {
-#ifdef MISDN_HANDLER_DEBUG
-               cb_log(0,0,"handle_err STOP\n");
-#endif
                return 0 ;
        }
-#ifdef MISDN_HANDLER_DEBUG
-       cb_log(0,0,"handle_err NOTSTOP\n");
-#endif
 
-       
        cb_log(0, 0, "Unhandled Message: prim %x len %d from addr %x, dinfo %x on this port.\n",frm->prim, frm->len, frm->addr, frm->dinfo);            
        free_msg(msg);
        
@@ -3719,7 +3682,6 @@ void manager_event_handler(void *arg)
                                } else {
                                        iframe_t *frm = (iframe_t *)msg->data;
                                        struct misdn_bchannel *bc = find_bc_by_l3id(stack, frm->dinfo);
-                                       cb_log(4,stack->port,"Sending msg, prim:%x addr:%x dinfo:%x\n",frm->prim,frm->addr,frm->dinfo);
                                        if (bc) send_msg(glob_mgr->midev, bc, msg);
                                }
                        }
@@ -4128,6 +4090,8 @@ void stack_holder_remove(struct misdn_stack *stack, struct misdn_bchannel *holde
 
        if (!holder->stack_holder) return;
        
+       holder->stack_holder=0;
+       
        cb_log(4,stack->port, "*HOLDER: remove %x\n",holder->l3_id);
        if (!stack || ! stack->holding) return;
   
@@ -4210,29 +4174,58 @@ void manager_ec_enable(struct misdn_bchannel *bc)
 
        struct misdn_stack *stack=get_stack_by_bc(bc);
        
-       cb_log(1, 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:
-       case 8:
-       case 16:
-       case 32:
-       case 64:
-       case 128:
-       case 256:
-       case 512:
-       case 1024:
-               cb_log(4, stack->port, "Taps is %d\n",bc->ec_deftaps);
-               break;
-       default:
-               cb_log(0, stack->port, "Taps should be power of 2\n");
-               bc->ec_deftaps=128;
+       cb_log(1, 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");
+               return;
        }
 
-       ec_arr[0]=bc->ec_deftaps;
-       ec_arr[1]=bc->ec_training;
+#ifdef WITH_BEROEC
+       if (bc->ec) {
+               cb_log(1, stack?stack->port:0, " --> EC already loaded\n");
+               return;
+       }
+
+       if (!bec_initialized) bc->bnec_tail=0;
+
+       if (bc->bnec_tail) {
+               bc->ec=beroec_new(bc->bnec_tail, BEROEC_SUBBAND,
+               bc->bnec_ah,
+               bc->bnec_td, bc->bnec_zero, bc->bnec_adapt, bc->bnec_nlp);
+       }       
+       return ;
+#endif
+
+       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);
+       
+               switch (bc->ec_deftaps) {
+               case 4:
+               case 8:
+               case 16:
+               case 32:
+               case 64:
+               case 128:
+               case 256:
+               case 512:
+               case 1024:
+                       cb_log(4, stack->port, "Taps is %d\n",bc->ec_deftaps);
+                       break;
+               default:
+                       cb_log(0, stack->port, "Taps should be power of 2\n");
+                       bc->ec_deftaps=128;
+               }
        
-       manager_ph_control_block(bc,  ECHOCAN_ON,  ec_arr, sizeof(ec_arr));
+               ec_arr[0]=bc->ec_deftaps;
+#ifdef EC_TRAIN
+               ec_arr[1]=bc->ec_training;
+#else
+               ec_arr[1]=0;
+#endif
+               
+               manager_ph_control_block(bc,  ECHOCAN_ON,  ec_arr, sizeof(ec_arr));
+       }
 }
 
 
@@ -4241,8 +4234,24 @@ void manager_ec_disable(struct misdn_bchannel *bc)
 {
        struct misdn_stack *stack=get_stack_by_bc(bc);
        
-       cb_log(1, stack?stack->port:0, "Sending Control ECHOCAN_OFF\n");
-       manager_ph_control(bc,  ECHOCAN_OFF, 0);
+       cb_log(1, 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");
+               return;
+       }
+
+#ifdef WITH_BEROEC
+       if (bc->ec)
+               beroec_destroy(bc->ec);
+       bc->ec=NULL;
+       return;
+#endif
+
+       if ( bc->ec_enable) {
+               cb_log(1, stack?stack->port:0, "Sending Control ECHOCAN_OFF\n");
+               manager_ph_control(bc,  ECHOCAN_OFF, 0);
+       }
 }
 
 struct misdn_stack* get_misdn_stack() {
@@ -4367,6 +4376,10 @@ void misdn_lib_reinit_nt_stack(int port)
        
                Isdnl2Init(&stack->nst);
                Isdnl3Init(&stack->nst);
+
+               if (!stack->ptp)
+                       misdn_lib_get_l1_up(stack);
+               misdn_lib_get_l2_up(stack);
        }
 }
 
index 736a99f..3673baf 100644 (file)
@@ -410,6 +410,7 @@ void manager_ph_control(struct misdn_bchannel *bc, int c1, int c2);
 int misdn_lib_port_restart(int port);
 int misdn_lib_get_port_info(int port);
 
+int misdn_lib_is_port_blocked(int port);
 int misdn_lib_port_block(int port);
 int misdn_lib_port_unblock(int port);
 
index 875a724..ae8aa76 100644 (file)
@@ -879,7 +879,7 @@ msg_t *build_release_complete (struct isdn_msg msgs[], struct misdn_bchannel *bc
 
 void parse_facility (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt) 
 {
-
+//#define FACILITY_DECODE
 #ifdef FACILITY_DECODE
        int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
        FACILITY_t *facility=(FACILITY_t*)((unsigned long)(msg->data+HEADER_LEN));