Multiple revisions 375519-375524
authorRichard Mudgett <rmudgett@digium.com>
Fri, 2 Nov 2012 18:46:58 +0000 (18:46 +0000)
committerRichard Mudgett <rmudgett@digium.com>
Fri, 2 Nov 2012 18:46:58 +0000 (18:46 +0000)
........
  r375519 | rmudgett | 2012-10-30 16:06:15 -0500 (Tue, 30 Oct 2012) | 11 lines

  chan_misdn: Timer primitives must be handled first.

  The frm->addr is a different "address space" than the stack/instance
  address of other Lx primitives.  The test for B channel instance address
  could fail.

  Patches:
patch01_timers.diff (license #6372) patch uploaded by Guenther Kelleter

  JIRA ABE-2888

  ........
  r375520 | rmudgett | 2012-10-30 16:14:58 -0500 (Tue, 30 Oct 2012) | 10 lines

  chan_misdn: Free memory in error paths and other memory leaks.

  The one line commented with BUG is not easily fixable because there is no
  de-init function one can call.

  Patches:
patch02_memory.diff (license #6372) patch uploaded by Guenther Kelleter

  JIRA ABE-2888

  ........
  r375521 | rmudgett | 2012-10-30 16:38:41 -0500 (Tue, 30 Oct 2012) | 14 lines

  chan_misdn: ISDN NT L2 de-establish/establish

  * An NT-PTMP cannot de/establish L2 since it doesn't know the TEIs.
  * On NT-PTP L2 is started when L1 is finally active in handle_l1.
  * L2 deactivation logging cleanup.
  * L2 aggregate link status is unknown for NT-PTMP, show as "UNKN".
  * Removed unused functions and code for L2 handling.

  Patches:
patch03_L2estab.diff (license #6372) patch uploaded by Guenther Kelleter
Modified

  JIRA ABE-2888

  ........
  r375522 | rmudgett | 2012-10-30 16:56:14 -0500 (Tue, 30 Oct 2012) | 22 lines

  chan_misdn: Fix broken upper_id/lower_id usage.

  Sending PH prim via lower_id layer (3 or 1) simply does not work.  For TE
  (3) it returns an error (len=-6) which is not evaluated by handle_l1(), so
  the L1 layer status ends up wrong.  Instead PH must be sent via L4, only
  then does it reach L1 without an error message.

  And NT PH prims only reach L1 when they are sent to layer 2 id.
  --> use upper_id to send PH primitives.

  * Check for errors in PH_(DE)ACTIVATE | CONFIRM.
  * Debug messages are improved.

  * The lower_id is now not used for anything, except: Why is lower_id layer
  deleted when it wasn't created?  I removed this code since it looks very
  wrong.

  Patches:
patch04_l1activation.diff (license #6372) patch uploaded by Guenther Kelleter

  JIRA ABE-2888

  ........
  r375523 | rmudgett | 2012-10-30 17:29:15 -0500 (Tue, 30 Oct 2012) | 31 lines

  chan_misdn: Fix loss of B channels if L1 is down.

  If you make 2 calls out an NT PTMP port which is not connected to any
  phone, the B channel associated with that call becomes unusable until
  Asterisk is restarted.

  The problem is the EVENT_SETUP is queued when L1 is not up in
  misdn_lib_send_event().  If L1 cannot be activated the event won't be
  dequeued.  It gets even worse when the call is hung up.  The queued
  EVENT_SETUP will be overwritten by an EVENT_DISCONNECT.  The reserved B
  channel then will never be freed.  If later someone connects a phone to
  the port, L1 will eventually activate and the queued EVENT_DISCONNECT is
  sent down the stack.  However, it is ignored because it is the wrong call
  state.

  The real fix would be that activation and queueing for a new SETUP is done
  by the NT stack.  But since it doesn't, the workaround must be removed
  because it doesn't always work.

  Fix: The event is no longer queued but immediately sent to the stack.  If
  L1 cannot be activated, the L3 state machine that was started by the
  EVENT_SETUP will do its work, i.e.  a timeout will release the B channel
  properly.  The SETUP possibly cannot be sent the first time but is resent
  by T303 in case L1 could be activated.

  Patches:
patch05_bchan-loss.diff (license #6372) patch uploaded by Guenther Kelleter
Modified

  JIRA ABE-2888

........
  r375524 | rmudgett | 2012-10-30 18:26:05 -0500 (Tue, 30 Oct 2012) | 13 lines

  chan_misdn: Remove some calls to exit().

  Try proper cleanup when something goes wrong in misdn_lib_init().
  Especially do not call exit()!

  * Fix memory leak because stack_destroy() does not free the stack struct.

  Patches:
patch06_cleanup-init.diff (license #6372) patch uploaded by Guenther Kelleter
Modified

  JIRA ABE-2888
........

Merged revisions 375519-375524 from https://origsvn.digium.com/svn/asterisk/be/branches/C.3-bier
........

Merged revisions 375625 from http://svn.asterisk.org/svn/asterisk/branches/1.8
........

Merged revisions 375626 from http://svn.asterisk.org/svn/asterisk/branches/10
........

Merged revisions 375627 from http://svn.asterisk.org/svn/asterisk/branches/11

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

channels/misdn/isdn_lib.c
channels/misdn/isdn_lib.h

index 73e5309..42bbd8f 100644 (file)
@@ -180,7 +180,7 @@ void get_show_stack_details(int port, char *buf)
                        stack->port,
                        stack->nt ? "NT" : "TE",
                        stack->ptp ? "PTP" : "PMP",
-                       stack->l2link ? "UP  " : "DOWN",
+                       (stack->nt && !stack->ptp) ? "UNKN" : stack->l2link ? "UP  " : "DOWN",
                        stack->l1link ? "UP  " : "DOWN",
                        stack->blocked);
        } else {
@@ -772,8 +772,6 @@ static void empty_bc(struct misdn_bchannel *bc)
 
        bc->notify_description_code = mISDN_NOTIFY_CODE_INVALID;
 
-       bc->evq=EVENT_NOTHING;
-
        bc->progress_coding=0;
        bc->progress_location=0;
        bc->progress_indicator=0;
@@ -880,7 +878,7 @@ static int misdn_lib_get_l1_down(struct misdn_stack *stack)
        /* Pull Up L1 */
        iframe_t act;
        act.prim = PH_DEACTIVATE | REQUEST;
-       act.addr = stack->lower_id|FLG_MSG_DOWN;
+       act.addr = stack->upper_id | FLG_MSG_DOWN;
        act.dinfo = 0;
        act.len = 0;
 
@@ -892,7 +890,7 @@ static int misdn_lib_get_l1_down(struct misdn_stack *stack)
 static int misdn_lib_get_l2_down(struct misdn_stack *stack)
 {
 
-       if (stack->ptp && (stack->nt) ) {
+       if (stack->ptp && stack->nt) {
                msg_t *dmsg;
                /* L2 */
                dmsg = create_l2msg(DL_RELEASE| REQUEST, 0, 0);
@@ -901,7 +899,7 @@ static int misdn_lib_get_l2_down(struct misdn_stack *stack)
                if (stack->nst.manager_l3(&stack->nst, dmsg))
                        free_msg(dmsg);
                pthread_mutex_unlock(&stack->nstlock);
-       } else {
+       } else if (!stack->nt) {
                iframe_t act;
 
                act.prim = DL_RELEASE| REQUEST;
@@ -911,6 +909,7 @@ static int misdn_lib_get_l2_down(struct misdn_stack *stack)
                act.len = 0;
                return mISDN_write(stack->midev, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
        }
+       /* cannot deestablish L2 for NT PTMP to unknown TE TEIs */
 
        return 0;
 }
@@ -921,20 +920,19 @@ static int misdn_lib_get_l1_up(struct misdn_stack *stack)
        /* Pull Up L1 */
        iframe_t act;
        act.prim = PH_ACTIVATE | REQUEST;
-       act.addr = (stack->upper_id | FLG_MSG_DOWN)  ;
-
+       act.addr = stack->upper_id | FLG_MSG_DOWN;
 
        act.dinfo = 0;
        act.len = 0;
 
+       cb_log(1, stack->port, "SENDING PH_ACTIVATE | REQ\n");
        return mISDN_write(stack->midev, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
-
 }
 
 int misdn_lib_get_l2_up(struct misdn_stack *stack)
 {
 
-       if (stack->ptp && (stack->nt) ) {
+       if (stack->ptp && stack->nt) {
                msg_t *dmsg;
                /* L2 */
                dmsg = create_l2msg(DL_ESTABLISH | REQUEST, 0, 0);
@@ -943,7 +941,7 @@ int misdn_lib_get_l2_up(struct misdn_stack *stack)
                if (stack->nst.manager_l3(&stack->nst, dmsg))
                        free_msg(dmsg);
                pthread_mutex_unlock(&stack->nstlock);
-       } else {
+       } else if (!stack->nt) {
                iframe_t act;
 
                act.prim = DL_ESTABLISH | REQUEST;
@@ -953,25 +951,11 @@ int misdn_lib_get_l2_up(struct misdn_stack *stack)
                act.len = 0;
                return mISDN_write(stack->midev, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
        }
+       /* cannot establish L2 for NT PTMP to unknown TE TEIs */
 
        return 0;
 }
 
-#if 0
-static int misdn_lib_get_l2_te_ptp_up(struct misdn_stack *stack)
-{
-       iframe_t act;
-
-       act.prim = DL_ESTABLISH | REQUEST;
-       act.addr = (stack->upper_id  & ~LAYER_ID_MASK) | 3 | FLG_MSG_DOWN;
-
-       act.dinfo = 0;
-       act.len = 0;
-       return mISDN_write(stack->midev, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
-       return 0;
-}
-#endif
-
 static int misdn_lib_get_short_status(struct misdn_stack *stack)
 {
        iframe_t act;
@@ -1231,7 +1215,7 @@ static int init_bc(struct misdn_stack *stack, struct misdn_bchannel *bc, int mid
 
        cb_log(8, port, "Init.BC %d.\n",bidx);
 
-       bc->send_lock=malloc(sizeof(struct send_lock));
+       bc->send_lock = malloc(sizeof(struct send_lock)); /* XXX BUG! memory leak never freed */
        if (!bc->send_lock) {
                return -1;
        }
@@ -1319,6 +1303,7 @@ static struct misdn_stack *stack_init(int midev, int port, int ptp)
        ret = mISDN_get_stack_info(midev, port, buff, sizeof(buff));
        if (ret < 0) {
                cb_log(0, port, "%s: Cannot get stack info for this port. (ret=%d)\n", __FUNCTION__, ret);
+               free(stack);
                return(NULL);
        }
 
@@ -1382,27 +1367,30 @@ static struct misdn_stack *stack_init(int midev, int port, int ptp)
                ret = mISDN_new_layer(midev, &li);
                if (ret) {
                        cb_log(0, port, "%s: Cannot add layer %d to this port.\n", __FUNCTION__, nt?2:4);
+                       free(stack);
                        return(NULL);
                }
 
 
-               stack->upper_id = li.id;
-               ret = mISDN_register_layer(midev, stack->d_stid, stack->upper_id);
+               ret = mISDN_register_layer(midev, stack->d_stid, li.id);
                if (ret)
                {
                        cb_log(0,port,"Cannot register layer %d of this port.\n", nt?2:4);
+                       free(stack);
                        return(NULL);
                }
 
                stack->lower_id = mISDN_get_layerid(midev, stack->d_stid, nt?1:3);
                if (stack->lower_id < 0) {
                        cb_log(0, port, "%s: Cannot get layer(%d) id of this port.\n", __FUNCTION__, nt?1:3);
+                       free(stack);
                        return(NULL);
                }
 
                stack->upper_id = mISDN_get_layerid(midev, stack->d_stid, nt?2:4);
                if (stack->upper_id < 0) {
-                       cb_log(0, port, "%s: Cannot get layer(%d) id of this port.\n", __FUNCTION__, 2);
+                       cb_log(0, port, "%s: Cannot get layer(%d) id of this port.\n", __FUNCTION__, nt?2:4);
+                       free(stack);
                        return(NULL);
                }
 
@@ -1426,7 +1414,7 @@ static struct misdn_stack *stack_init(int midev, int port, int ptp)
                        if (stack->pri)
                                stack->nst.feature |= FEATURE_NET_CRLEN2 | FEATURE_NET_EXTCID;
 
-                       stack->nst.l1_id = stack->lower_id;
+                       stack->nst.l1_id = stack->lower_id; /* never used */
                        stack->nst.l2_id = stack->upper_id;
 
                        msg_queue_init(&stack->nst.down_queue);
@@ -1451,8 +1439,10 @@ static struct misdn_stack *stack_init(int midev, int port, int ptp)
 
                misdn_lib_get_short_status(stack);
                misdn_lib_get_l1_up(stack);
-               misdn_lib_get_l2_up(stack);
-
+               /* handle_l1 will start L2 for NT. */
+               if (!stack->nt) {
+                       misdn_lib_get_l2_up(stack);
+               }
        }
 
        cb_log(8, port, "stack_init: lowerId:%x upperId:%x\n", stack->lower_id, stack->upper_id);
@@ -1472,9 +1462,6 @@ static void stack_destroy(struct misdn_stack *stack)
                cleanup_Isdnl3(&stack->nst);
        }
 
-       if (stack->lower_id)
-               mISDN_write_frame(stack->midev, buf, stack->lower_id, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
-
        if (stack->upper_id)
                mISDN_write_frame(stack->midev, buf, stack->upper_id, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
 
@@ -1600,28 +1587,6 @@ static struct misdn_bchannel *find_bc_by_confid(unsigned long confid)
 }
 
 
-static struct misdn_bchannel *find_bc_by_channel(int port, int channel)
-{
-       struct misdn_stack *stack = find_stack_by_port(port);
-       int i;
-
-       if (!stack) {
-               return NULL;
-       }
-
-       for (i = 0; i <= stack->b_num; i++) {
-               if (stack->bc[i].in_use && stack->bc[i].channel == channel) {
-                       return &stack->bc[i];
-               }
-       }
-
-       return NULL;
-}
-
-
-
-
-
 static int handle_event_te(struct misdn_bchannel *bc, enum event_e event, iframe_t *frm)
 {
        struct misdn_stack *stack=get_stack_by_bc(bc);
@@ -1825,8 +1790,10 @@ int misdn_lib_get_port_up (int port)
 
                        if (!stack->l1link)
                                misdn_lib_get_l1_up(stack);
-                       if (!stack->l2link)
+                       /* handle_l1 will start L2 for NT. */
+                       if (!stack->l2link && !stack->nt) {
                                misdn_lib_get_l2_up(stack);
+                       }
 
                        return 0;
                }
@@ -2156,8 +2123,8 @@ static int handle_event_nt(void *dat, void *arg)
 
        case DL_RELEASE | INDICATION:
        case DL_RELEASE | CONFIRM:
+               cb_log(3, stack->port, "%% GOT L2 DeActivate Info.\n");
                if (stack->ptp) {
-                       cb_log(3 , stack->port, "%% GOT L2 DeActivate Info.\n");
 
                        if (stack->l2upcnt>3) {
                                cb_log(0 , stack->port, "!!! Could not Get the L2 up after 3 Attempts!!!\n");
@@ -2167,9 +2134,7 @@ static int handle_event_nt(void *dat, void *arg)
                                        stack->l2upcnt++;
                                }
                        }
-
-               } else
-                       cb_log(3, stack->port, "%% GOT L2 DeActivate Info.\n");
+               }
 
                stack->l2link = 0;
                free_msg(msg);
@@ -2835,12 +2800,18 @@ static int handle_l1(msg_t *msg)
 {
        iframe_t *frm = (iframe_t*) msg->data;
        struct misdn_stack *stack = find_stack_by_addr(frm->addr);
-       int i ;
 
        if (!stack) return 0 ;
 
        switch (frm->prim) {
        case PH_ACTIVATE | CONFIRM:
+               /* we have to check for errors! */
+               if (frm->len) {
+                       cb_log (3, stack->port, "L1: PH_ACTIVATE|REQUEST returned error!\n");
+                       free_msg(msg);
+                       return 1;
+               }
+               /* fall through */
        case PH_ACTIVATE | INDICATION:
                cb_log (3, stack->port, "L1: PH L1Link Up!\n");
                stack->l1link=1;
@@ -2857,15 +2828,6 @@ static int handle_l1(msg_t *msg)
                } else {
                        free_msg(msg);
                }
-
-               for (i=0;i<=stack->b_num; i++) {
-                       if (stack->bc[i].evq != EVENT_NOTHING) {
-                               cb_log(4, stack->port, "Firing 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);
-                               stack->bc[i].evq=EVENT_NOTHING;
-                       }
-
-               }
                return 1;
 
        case PH_ACTIVATE | REQUEST:
@@ -2879,6 +2841,13 @@ static int handle_l1(msg_t *msg)
                return 1;
 
        case PH_DEACTIVATE | CONFIRM:
+               /* we have to check for errors! */
+               if (frm->len) {
+                       cb_log (3, stack->port, "L1: PH_DEACTIVATE|REQUEST returned error!\n");
+                       free_msg(msg);
+                       return 1;
+               }
+               /* fall through */
        case PH_DEACTIVATE | INDICATION:
                cb_log (3, stack->port, "L1: PH L1Link Down! \n");
 
@@ -3159,7 +3128,8 @@ static int te_lib_init(void)
        entity = frm->dinfo & 0xffff;
        if (ret < mISDN_HEADER_LEN || !entity) {
                fprintf(stderr, "cannot request MGR_NEWENTITY from mISDN: %s\n", strerror(errno));
-               exit(-1);
+               mISDN_close(midev);
+               return -1;
        }
 
        return midev;
@@ -3577,11 +3547,7 @@ int misdn_lib_send_event(struct misdn_bchannel *bc, enum event_e event )
        cb_log(6,stack->port,"SENDEVENT: stack->nt:%d stack->upperid:%x\n",stack->nt, stack->upper_id);
 
        if ( stack->nt && !stack->l1link) {
-               /** Queue Event **/
-               bc->evq=event;
-               cb_log(1, stack->port, "Queueing Event %s because L1 is down (btw. Activating L1)\n", isdn_get_info(msgs_g, event, 0));
                misdn_lib_get_l1_up(stack);
-               RETURN(0,OUT);
        }
 
        cb_log(1, stack->port,
@@ -3851,7 +3817,6 @@ static int handle_err(msg_t *msg)
                {
                        int port=(frm->addr&MASTER_ID_MASK) >> 8;
                        int channel=(frm->addr&CHILD_ID_MASK) >> 16;
-                       struct misdn_bchannel *bc;
 
                        /*we flush the read buffer here*/
 
@@ -3859,31 +3824,6 @@ static int handle_err(msg_t *msg)
 
                        free_msg(msg);
                        return 1;
-
-
-                       bc = find_bc_by_channel(port, channel);
-
-                       if (!bc) {
-                               struct misdn_stack *stack = find_stack_by_port(port);
-
-                               if (!stack) {
-                                       cb_log(0,0," --> stack not found\n");
-                                       free_msg(msg);
-                                       return 1;
-                               }
-
-                               cb_log(0,0," --> bc not found by channel\n");
-                               if (stack->l2link)
-                                       misdn_lib_get_l2_down(stack);
-
-                               if (stack->l1link)
-                                       misdn_lib_get_l1_down(stack);
-
-                               free_msg(msg);
-                               return 1;
-                       }
-
-                       cb_log(3,port," --> BC in state:%s\n", bc_state2str(bc->bc_state));
                }
        }
 
@@ -3897,6 +3837,13 @@ int manager_isdn_handler(iframe_t *frm ,msg_t *msg)
                cb_log(0,0,"SERIOUS BUG, dinfo == 0xffffffff, prim == PH_DATA | CONFIRM !!!!\n");
        }
 
+       /* Timer primitives must be handled first, because the frm->addr is a different
+        * "address space" than the stack/instance address of other Lx primitives.
+        */
+       if (handle_timers(msg)) {
+               return 0;
+       }
+
        if ( ((frm->addr | ISDN_PID_BCHANNEL_BIT )>> 28 ) == 0x5) {
                static int unhandled_bmsg_count=1000;
                if (handle_bchan(msg)) {
@@ -3917,10 +3864,6 @@ int manager_isdn_handler(iframe_t *frm ,msg_t *msg)
        syslog(LOG_NOTICE,"mISDN recv: ADDR:%x PRIM:%x DINFO:%x\n", frm->addr, frm->prim, frm->dinfo);
 #endif
 
-       if (handle_timers(msg))
-               return 0 ;
-
-
        if (handle_mgmt(msg))
                return 0 ;
 
@@ -4190,7 +4133,7 @@ void misdn_lib_nt_debug_init( int flags, char *file )
 
 int misdn_lib_init(char *portlist, struct misdn_lib_iface *iface, void *user_data)
 {
-       struct misdn_lib *mgr=calloc(1, sizeof(struct misdn_lib));
+       struct misdn_lib *mgr;
        char *tok, *tokb;
        char plist[1024];
        int midev;
@@ -4200,20 +4143,24 @@ int misdn_lib_init(char *portlist, struct misdn_lib_iface *iface, void *user_dat
        cb_event = iface->cb_event;
        cb_jb_empty = iface->cb_jb_empty;
 
+       if (!portlist || (*portlist == 0)) {
+               return 1;
+       }
+
+       mgr = calloc(1, sizeof(*mgr));
+       if (!mgr) {
+               return 1;
+       }
        glob_mgr = mgr;
 
        msg_init();
 
        misdn_lib_nt_debug_init(0,NULL);
 
-       if (!portlist || (*portlist == 0) ) return 1;
-
        init_flip_bits();
 
-       {
-               strncpy(plist,portlist, 1024);
-               plist[1023] = 0;
-       }
+       strncpy(plist, portlist, 1024);
+       plist[1023] = 0;
 
        memcpy(tone_425_flip,tone_425,TONE_425_SIZE);
        flip_buf_bits(tone_425_flip,TONE_425_SIZE);
@@ -4222,6 +4169,11 @@ int misdn_lib_init(char *portlist, struct misdn_lib_iface *iface, void *user_dat
        flip_buf_bits(tone_silence_flip,TONE_SILENCE_SIZE);
 
        midev=te_lib_init();
+       if (midev <= 0) {
+               free(glob_mgr);
+               glob_mgr = NULL;
+               return 1;
+       }
        mgr->midev=midev;
 
        port_count=mISDN_get_stack_count(midev);
@@ -4246,13 +4198,13 @@ int misdn_lib_init(char *portlist, struct misdn_lib_iface *iface, void *user_dat
 
                if (port > port_count) {
                        cb_log(0, port, "Couldn't Initialize this port since we have only %d ports\n", port_count);
-                       exit(1);
+                       continue;
                }
 
                stack = stack_init(midev, port, ptp);
                if (!stack) {
-                       perror("stack_init");
-                       exit(1);
+                       cb_log(0, port, "stack_init() failed for this port\n");
+                       continue;
                }
 
                /* Initialize the B channel records for real B channels. */
@@ -4260,19 +4212,29 @@ int misdn_lib_init(char *portlist, struct misdn_lib_iface *iface, void *user_dat
                        r = init_bc(stack, &stack->bc[i], stack->midev, port, i);
                        if (r < 0) {
                                cb_log(0, port, "Got Err @ init_bc :%d\n", r);
-                               exit(1);
+                               break;
                        }
                }
+               if (i <= stack->b_num) {
+                       stack_destroy(stack);
+                       free(stack);
+                       continue;
+               }
 #if defined(AST_MISDN_ENHANCEMENTS)
                /* Initialize the B channel records for REGISTER signaling links. */
                for (i = MAX_BCHANS + 1; i < ARRAY_LEN(stack->bc); ++i) {
                        r = init_bc(stack, &stack->bc[i], stack->midev, port, i);
                        if (r < 0) {
                                cb_log(0, port, "Got Err @ init_bc :%d\n", r);
-                               exit(1);
+                               break;
                        }
                        stack->bc[i].is_register_pool = 1;
                }
+               if (i < ARRAY_LEN(stack->bc)) {
+                       stack_destroy(stack);
+                       free(stack);
+                       continue;
+               }
 #endif /* defined(AST_MISDN_ENHANCEMENTS) */
 
                /* Add the new stack to the end of the list */
@@ -4287,6 +4249,13 @@ int misdn_lib_init(char *portlist, struct misdn_lib_iface *iface, void *user_dat
                }
        }
 
+       if (!mgr->stack_list) {
+               /* no stacks were successfully initialized !? */
+               te_lib_destroy(midev);
+               free(glob_mgr);
+               glob_mgr = NULL;
+               return 1;
+       }
        if (sem_init(&handler_started, 1, 0)<0)
                sem_init(&handler_started, 0, 0);
 
@@ -4335,6 +4304,12 @@ void misdn_lib_destroy(void)
 
        cb_log(1, 0, "Closing mISDN device\n");
        te_lib_destroy(glob_mgr->midev);
+       while ((help = glob_mgr->stack_list)) {
+               glob_mgr->stack_list = help->next;
+               free(help);
+       }
+       free(glob_mgr);
+       glob_mgr = NULL;
 }
 
 char *manager_isdn_get_info(enum event_e event)
@@ -4821,7 +4796,7 @@ void misdn_lib_reinit_nt_stack(int port)
                if (stack->pri)
                        stack->nst.feature |= FEATURE_NET_CRLEN2 | FEATURE_NET_EXTCID;
 
-               stack->nst.l1_id = stack->lower_id;
+               stack->nst.l1_id = stack->lower_id; /* never used */
                stack->nst.l2_id = stack->upper_id;
 
                msg_queue_init(&stack->nst.down_queue);
@@ -4831,7 +4806,6 @@ void misdn_lib_reinit_nt_stack(int port)
 
                if (!stack->ptp)
                        misdn_lib_get_l1_up(stack);
-               misdn_lib_get_l2_up(stack);
        }
 }
 
index 3ef1376..62e80d6 100644 (file)
@@ -520,9 +520,6 @@ struct misdn_bchannel {
        /*! \brief TRUE if AOCDtype and AOCD data are ready to export to Asterisk */
        int AOCD_need_export;
 
-       /*! \brief Event waiting for Layer 1 to come up */
-       enum event_e evq;
-
        /*** CRYPTING STUFF ***/
        int crypt;              /* Initialized, Not used */
        int curprx;             /* Initialized, Not used */