[asterisk-commits] rmudgett: trunk r375628 - in /trunk: ./ channels/misdn/
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Fri Nov 2 13:47:02 CDT 2012
Author: rmudgett
Date: Fri Nov 2 13:46:58 2012
New Revision: 375628
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=375628
Log:
Multiple revisions 375519-375524
........
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
Modified:
trunk/ (props changed)
trunk/channels/misdn/isdn_lib.c
trunk/channels/misdn/isdn_lib.h
Propchange: trunk/
------------------------------------------------------------------------------
Binary property 'branch-11-merged' - no diff available.
Modified: trunk/channels/misdn/isdn_lib.c
URL: http://svnview.digium.com/svn/asterisk/trunk/channels/misdn/isdn_lib.c?view=diff&rev=375628&r1=375627&r2=375628
==============================================================================
--- trunk/channels/misdn/isdn_lib.c (original)
+++ trunk/channels/misdn/isdn_lib.c Fri Nov 2 13:46:58 2012
@@ -180,7 +180,7 @@
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 @@
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 @@
/* 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_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 @@
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 @@
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 @@
/* 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 @@
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,24 +951,10 @@
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)
{
@@ -1231,7 +1215,7 @@
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 @@
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 @@
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 @@
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 @@
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);
@@ -1471,9 +1461,6 @@
cleanup_Isdnl2(&stack->nst);
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);
@@ -1598,28 +1585,6 @@
}
return NULL;
}
-
-
-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)
@@ -1825,8 +1790,10 @@
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 @@
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 @@
stack->l2upcnt++;
}
}
-
- } else
- cb_log(3, stack->port, "%% GOT L2 DeActivate Info.\n");
+ }
stack->l2link = 0;
free_msg(msg);
@@ -2835,12 +2800,18 @@
{
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 @@
} 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 @@
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 @@
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 @@
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 @@
{
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 @@
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));
}
}
@@ -3895,6 +3835,13 @@
if (frm->dinfo==0xffffffff && frm->prim==(PH_DATA|CONFIRM)) {
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) {
@@ -3916,10 +3863,6 @@
#ifdef RECV_FRM_SYSLOG_DEBUG
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 @@
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 @@
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 @@
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 @@
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,8 +4212,13 @@
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. */
@@ -4269,9 +4226,14 @@
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) */
@@ -4287,6 +4249,13 @@
}
}
+ 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 @@
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 @@
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,8 +4806,7 @@
if (!stack->ptp)
misdn_lib_get_l1_up(stack);
- misdn_lib_get_l2_up(stack);
- }
-}
-
-
+ }
+}
+
+
Modified: trunk/channels/misdn/isdn_lib.h
URL: http://svnview.digium.com/svn/asterisk/trunk/channels/misdn/isdn_lib.h?view=diff&rev=375628&r1=375627&r2=375628
==============================================================================
--- trunk/channels/misdn/isdn_lib.h (original)
+++ trunk/channels/misdn/isdn_lib.h Fri Nov 2 13:46:58 2012
@@ -520,9 +520,6 @@
/*! \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 */
More information about the asterisk-commits
mailing list