[svn-commits] rmudgett: mISDNuser/trunk r33 - in /mISDNuser/trunk: i4lnet/ include/

SVN commits to the Digium repositories svn-commits at lists.digium.com
Thu Dec 18 21:29:13 CST 2008


Author: rmudgett
Date: Thu Dec 18 21:29:13 2008
New Revision: 33

URL: http://svn.digium.com/view/thirdparty?view=rev&rev=33
Log:
JIRA AST-123/ABE-1705
*  Added REGISTER message support for CCBS-T/CCNR-T.
*  Added missing NOTIFY message support for diversion and
explicit call transfer.
*  Added the ability to send FACILITY messages on the
dummy call reference (NT side).
*  Added missing parsing of DISPLAY ie to messages that can
send DISPLAY ie contents.
*  Fixed the generated ie order in l3dss1_alert_req().
*  Fixed the message type used in l3dss1_notify_req().

Modified:
    mISDNuser/trunk/i4lnet/net_l3.c
    mISDNuser/trunk/i4lnet/net_l3.h
    mISDNuser/trunk/include/l3dss1.h

Modified: mISDNuser/trunk/i4lnet/net_l3.c
URL: http://svn.digium.com/view/thirdparty/mISDNuser/trunk/i4lnet/net_l3.c?view=diff&rev=33&r1=32&r2=33
==============================================================================
--- mISDNuser/trunk/i4lnet/net_l3.c (original)
+++ mISDNuser/trunk/i4lnet/net_l3.c Thu Dec 18 21:29:13 2008
@@ -59,13 +59,13 @@
 };
 
 struct stateentry {
-	int state;
+	unsigned long state;
 	int primitive;
 	void (*rout) (layer3_proc_t *, int, void *);
 };
 
-#define SBIT(state)	(1<<state)
-#define ALL_STATES	0x03ffffff
+#define SBIT(state)	(1UL << state)
+#define ALL_STATES	0xffffffff
 
 void
 display_NR_IE(u_char *p, char *head1, char *head2)
@@ -322,8 +322,13 @@
 
 static void MsgStart(layer3_proc_t *pc, u_char mt) {
 	pc->op = &pc->obuf[0];
+
+	/* Protocol discriminator */
 	*pc->op++ = 8;
-	if (pc->callref == -1) { /* dummy cr */
+
+	/* Call Reference */
+	if (pc->callref == -1) {
+		/* dummy cr */
 		*pc->op++ = 0;
 	} else {
 		if (pc->l3->nst->feature & FEATURE_NET_CRLEN2) {
@@ -338,6 +343,8 @@
 			pc->op++;
 		}
 	}
+
+	/* Message Type */
 	*pc->op++ = mt;
 }
 
@@ -431,7 +438,7 @@
 static void
 l3dss1_msg_without_setup(layer3_proc_t *pc, u_char cause)
 {
-	/* This routine is called if here was no SETUP made (checks in dss1up and in
+	/* This routine is called if there was no SETUP made (checks in dss1up and in
 	 * l3dss1_setup) and a RELEASE_COMPLETE have to be sent with an error code
 	 * MT_STATUS_ENQUIRE in the NULL state is handled too
 	 */
@@ -631,9 +638,94 @@
 	fac = (FACILITY_t *)(umsg->data + mISDNUSER_HEAD_SIZE);
 	fac->FACILITY =
 		find_and_copy_ie(msg->data, msg->len, IE_FACILITY, 0, umsg);
+	fac->DISPLAY =
+		find_and_copy_ie(msg->data, msg->len, IE_DISPLAY, 0, umsg);
 	if (mISDN_l3up(pc, umsg))
 		free_msg(umsg);
 }
+
+
+
+
+/* ******************************************************************* */
+/*!
+ * \internal
+ * \brief Parse the register message for its ie's and pass it up.
+ *
+ * \param pc
+ * \param pr
+ * \param arg
+ *
+ * \return Nothing
+ */
+static void l3dss1_register(layer3_proc_t *pc, int pr, void *arg)
+{
+	msg_t *umsg;
+	msg_t *msg = arg;
+	REGISTER_t *reg;
+
+	umsg = prep_l3data_msg(CC_REGISTER | INDICATION,
+		pc->callref > 0 ? pc->ces | (pc->callref << 16) : -1,
+		sizeof(REGISTER_t), msg->len, NULL);
+	if (!umsg) {
+		return;
+	}
+	reg = (REGISTER_t *) (umsg->data + mISDNUSER_HEAD_SIZE);
+	reg->FACILITY =
+		find_and_copy_ie(msg->data, msg->len, IE_FACILITY, 0, umsg);
+	reg->DISPLAY =
+		find_and_copy_ie(msg->data, msg->len, IE_DISPLAY, 0, umsg);
+	if (mISDN_l3up(pc, umsg)) {
+		free_msg(umsg);
+	}
+}	/* end l3dss1_register() */
+
+
+
+
+/* ******************************************************************* */
+/*!
+ * \internal
+ * \brief Parse the notify message for its ie's and pass it up.
+ *
+ * \param pc
+ * \param pr
+ * \param arg
+ *
+ * \return Nothing
+ */
+static void l3dss1_notify(layer3_proc_t *pc, int pr, void *arg)
+{
+	msg_t *umsg;
+	msg_t *msg = arg;
+	NOTIFY_t *notify;
+
+	umsg = prep_l3data_msg(CC_NOTIFY | INDICATION,
+		pc->callref > 0 ? pc->ces | (pc->callref << 16) : -1,
+		sizeof(NOTIFY_t), msg->len, NULL);
+	if (!umsg) {
+		return;
+	}
+
+	/* Locate the ie's */
+	notify = (NOTIFY_t *) (umsg->data + mISDNUSER_HEAD_SIZE);
+	notify->BEARER =
+		find_and_copy_ie(msg->data, msg->len, IE_BEARER, 0, umsg);
+	notify->NOTIFY =
+		find_and_copy_ie(msg->data, msg->len, IE_NOTIFY, 0, umsg);
+	notify->DISPLAY =
+		find_and_copy_ie(msg->data, msg->len, IE_DISPLAY, 0, umsg);
+	notify->REDIR_DN =
+		find_and_copy_ie(msg->data, msg->len, IE_REDIR_DN, 0, umsg);
+
+	if (!notify->NOTIFY) {
+		l3dss1_status_send(pc, CAUSE_MANDATORY_IE_MISS);
+		free_msg(umsg);
+	} else if (mISDN_l3up(pc, umsg)) {
+		free_msg(umsg);
+	}
+}	/* end l3dss1_notify() */
+
 
 static void
 l3dss1_restart(layer3_proc_t *pc, int pr, void *arg)
@@ -647,6 +739,8 @@
 	if (!umsg)
 		return;
 	restart = (RESTART_t *)(umsg->data + mISDNUSER_HEAD_SIZE);
+	restart->DISPLAY =
+		find_and_copy_ie(msg->data, msg->len, IE_DISPLAY, 0, umsg);
 	restart->RESTART_IND =
 		find_and_copy_ie(msg->data, msg->len, IE_RESTART_IND, 0, umsg);
 
@@ -763,8 +857,8 @@
 		if (pc->l3->debug & L3_DEB_WARN)
 			l3_debug(pc->l3, "setup with wrong chid ret %d", pc->err);
 	}
-	/* Now we are on none mandatory IEs */
-
+
+	/* Now we are on non-mandatory IEs */
 	setup->COMPLETE =
 		find_and_copy_ie(msg->data, msg->len, IE_COMPLETE, 0, umsg);
 	setup->FACILITY =
@@ -773,6 +867,8 @@
 		find_and_copy_ie(msg->data, msg->len, IE_PROGRESS, 0, umsg);
 	setup->NET_FAC =
 		find_and_copy_ie(msg->data, msg->len, IE_NET_FAC, 0, umsg);
+	setup->DISPLAY =
+		find_and_copy_ie(msg->data, msg->len, IE_DISPLAY, 0, umsg);
 	setup->KEYPAD =
 		find_and_copy_ie(msg->data, msg->len, IE_KEYPAD, 0, umsg);
 	setup->SIGNAL =
@@ -798,7 +894,7 @@
 	L3DelTimer(&pc->timer2);
 	dprint(DBGM_L3, pc->l3->nst->cardnr, "%s: pc=%p del timer2\n", __FUNCTION__, pc);
 	L3AddTimer(&pc->timer2, T_CTRL, 0x31f);
-	if (err) /* STATUS for none mandatory IE errors after actions are taken */
+	if (err) /* STATUS for non-mandatory IE errors after actions are taken */
 		l3dss1_std_ie_err(pc, err);
 	if (mISDN_l3up(pc, umsg))
 		free_msg(umsg);
@@ -833,6 +929,8 @@
 	} 
 	disc->FACILITY =
 		find_and_copy_ie(msg->data, msg->len, IE_FACILITY, 0, umsg);
+	disc->DISPLAY =
+		find_and_copy_ie(msg->data, msg->len, IE_DISPLAY, 0, umsg);
 	disc->SIGNAL =
 		find_and_copy_ie(msg->data, msg->len, IE_SIGNAL, 0, umsg);
 	disc->USER_USER =
@@ -864,6 +962,8 @@
 	}
 	disc->FACILITY =
 		find_and_copy_ie(msg->data, msg->len, IE_FACILITY, 0, umsg);
+	disc->DISPLAY =
+		find_and_copy_ie(msg->data, msg->len, IE_DISPLAY, 0, umsg);
 	disc->SIGNAL =
 		find_and_copy_ie(msg->data, msg->len, IE_SIGNAL, 0, umsg);
 	disc->USER_USER =
@@ -891,6 +991,8 @@
 	info = (INFORMATION_t *)(umsg->data + mISDNUSER_HEAD_SIZE);
 	info->COMPLETE =
 		find_and_copy_ie(msg->data, msg->len, IE_COMPLETE, 0, umsg);
+	info->DISPLAY =
+		find_and_copy_ie(msg->data, msg->len, IE_DISPLAY, 0, umsg);
 	info->KEYPAD =
 		find_and_copy_ie(msg->data, msg->len, IE_KEYPAD, 0, umsg);
 	info->SIGNAL =
@@ -930,6 +1032,8 @@
 	}
 	rel->FACILITY =
 		find_and_copy_ie(msg->data, msg->len, IE_FACILITY, 0, umsg);
+	rel->DISPLAY =
+		find_and_copy_ie(msg->data, msg->len, IE_DISPLAY, 0, umsg);
 	rel->SIGNAL =
 		find_and_copy_ie(msg->data, msg->len, IE_SIGNAL, 0, umsg);
 	rel->USER_USER =
@@ -975,6 +1079,8 @@
 	}
 	relc->FACILITY =
 		find_and_copy_ie(msg->data, msg->len, IE_FACILITY, 0, umsg);
+	relc->DISPLAY =
+		find_and_copy_ie(msg->data, msg->len, IE_DISPLAY, 0, umsg);
 	relc->SIGNAL =
 		find_and_copy_ie(msg->data, msg->len, IE_SIGNAL, 0, umsg);
 	relc->USER_USER =
@@ -1013,6 +1119,8 @@
 		find_and_copy_ie(msg->data, msg->len, IE_CHANNEL_ID, 0, umsg);
 	sa->FACILITY =
 		find_and_copy_ie(msg->data, msg->len, IE_FACILITY, 0, umsg);
+	sa->DISPLAY =
+		find_and_copy_ie(msg->data, msg->len, IE_DISPLAY, 0, umsg);
 	sa->PROGRESS =
 		find_and_copy_ie(msg->data, msg->len, IE_PROGRESS, 0, umsg);
 	if (!mISDN_l3up(pc->master, umsg))
@@ -1047,6 +1155,8 @@
 		find_and_copy_ie(msg->data, msg->len, IE_FACILITY, 0, umsg);
 	proc->PROGRESS =
 		find_and_copy_ie(msg->data, msg->len, IE_PROGRESS, 0, umsg);
+	proc->DISPLAY =
+		find_and_copy_ie(msg->data, msg->len, IE_DISPLAY, 0, umsg);
 	proc->HLC =
 		find_and_copy_ie(msg->data, msg->len, IE_HLC, 0, umsg);
 	if (!mISDN_l3up(pc->master, umsg))
@@ -1081,6 +1191,8 @@
 		find_and_copy_ie(msg->data, msg->len, IE_FACILITY, 0, umsg);
 	al->PROGRESS =
 		find_and_copy_ie(msg->data, msg->len, IE_PROGRESS, 0, umsg);
+	al->DISPLAY =
+		find_and_copy_ie(msg->data, msg->len, IE_DISPLAY, 0, umsg);
 	al->SIGNAL =
 		find_and_copy_ie(msg->data, msg->len, IE_SIGNAL, 0, umsg);
 	al->HLC =
@@ -1129,7 +1241,7 @@
 		free_msg(umsg);
 		return;
 	}
-	/* Now we are on none mandatory IEs */
+	/* Now we are on non-mandatory IEs */
 	cp->BEARER =
 		find_and_copy_ie(msg->data, msg->len, IE_BEARER, 0, umsg);
 	cp->FACILITY =
@@ -1145,7 +1257,7 @@
 	L3DelTimer(&pc->timer1);
 	newl3state(pc, 3);
 	L3AddTimer(&pc->timer1, T310, 0x310);
-	if (ret) /* STATUS for none mandatory IE errors after actions are taken */
+	if (ret) /* STATUS for non-mandatory IE errors after actions are taken */
 		l3dss1_std_ie_err(pc, ret);
 	if (mISDN_l3up(pc, umsg))
 		free_msg(umsg);
@@ -1221,6 +1333,8 @@
 	if (!umsg)
 		return;
 	hold = (HOLD_t *)(umsg->data + mISDNUSER_HEAD_SIZE);
+	hold->DISPLAY =
+		find_and_copy_ie(msg->data, msg->len, IE_DISPLAY, 0, umsg);
 	if (mISDN_l3up(pc, umsg))
 		free_msg(umsg);
 }
@@ -1304,6 +1418,10 @@
 		MT_STATUS_ENQUIRY, l3dss1_status_enq},
 	{ALL_STATES,
 		MT_FACILITY, l3dss1_facility},
+	{SBIT(0),
+		MT_REGISTER, l3dss1_register},
+	{ALL_STATES,
+		MT_NOTIFY, l3dss1_notify},
 	{SBIT(19),
 		MT_STATUS, l3dss1_release_cmpl},
 	{SBIT(0),
@@ -1329,7 +1447,7 @@
 	{SBIT(6) | SBIT(7) | SBIT(8) | SBIT(9) | SBIT(19) | SBIT(25),
 		MT_RELEASE, l3dss1_release_i},
 	{SBIT(0) | SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(10) |
-	 SBIT(11) | SBIT(12) | SBIT(15) | SBIT(17) | SBIT(19),
+	 SBIT(11) | SBIT(12) | SBIT(15) | SBIT(17) | SBIT(19) | SBIT(31),
 		MT_RELEASE_COMPLETE, l3dss1_release_cmpl},
 	{SBIT(4) | SBIT(7) | SBIT(10),
 		MT_USER_INFORMATION, l3dss1_userinfo},
@@ -1483,7 +1601,7 @@
 		MT_RELEASE, l3dss1_release_m},
 	{SBIT(19),  MT_RELEASE, l3dss1_release_cmpl},
 	{SBIT(0) | SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(10) |
-	 SBIT(11) | SBIT(12) | SBIT(15) | SBIT(17) | SBIT(19),
+	 SBIT(11) | SBIT(12) | SBIT(15) | SBIT(17) | SBIT(19) | SBIT(31),
 		MT_RELEASE_COMPLETE, l3dss1_release_cmpl_mx},
 	{SBIT(6) | SBIT(7) | SBIT(8) | SBIT(9) | SBIT(22) | SBIT(25),
 		MT_RELEASE_COMPLETE, l3dss1_release_cmpl_m},
@@ -1571,12 +1689,12 @@
 			AddvarIE(pc, IE_PROGRESS, alert->PROGRESS);
 		if (alert->DISPLAY)
 			AddvarIE(pc, IE_DISPLAY, alert->DISPLAY);
+		if (alert->REDIR_DN)
+			AddvarIE(pc, IE_REDIR_DN, alert->REDIR_DN);
 		if (alert->HLC)
 			AddvarIE(pc, IE_HLC, alert->HLC);
 		if (alert->USER_USER)
 			AddvarIE(pc, IE_USER_USER, alert->USER_USER);
-		if (alert->REDIR_DN)
-			AddvarIE(pc, IE_REDIR_DN, alert->REDIR_DN);
 		SendMsg(pc, 4);
 	} else {
 		newl3state(pc, 4);
@@ -1786,6 +1904,36 @@
 	}
 }
 
+
+
+
+/* ******************************************************************* */
+/*!
+ * \internal
+ * \brief Build the register message and send it.
+ *
+ * \param pc 
+ * \param pr 
+ * \param arg 
+ *
+ * \return Nothing
+ */
+static void l3dss1_register_req(layer3_proc_t *pc, int pr, void *arg)
+{
+	REGISTER_t *reg = arg;
+
+	if (reg) {
+		MsgStart(pc, MT_REGISTER);
+		if (reg->FACILITY) {
+			AddvarIE(pc, IE_FACILITY, reg->FACILITY);
+		}
+		if (reg->DISPLAY) {
+			AddvarIE(pc, IE_DISPLAY, reg->DISPLAY);
+		}
+		SendMsg(pc, 31);/* call state: Call Independent Service (U31/N31) */
+	}
+}	/* end l3dss1_register_req() */
+
 static void
 l3dss1_userinfo_req(layer3_proc_t *pc, int pr, void *arg)
 {
@@ -1869,7 +2017,7 @@
 	NOTIFY_t *noti = arg;
 
 	if (noti) {
-		MsgStart(pc, MT_INFORMATION);
+		MsgStart(pc, MT_NOTIFY);
 		if (noti->BEARER)
 			AddvarIE(pc, IE_BEARER, noti->BEARER);
 		if (noti->NOTIFY)
@@ -2380,13 +2528,15 @@
 */
 	{ALL_STATES,
 	 CC_FACILITY | REQUEST, l3dss1_facility_req},
+	{SBIT(0),
+	 CC_REGISTER | REQUEST, l3dss1_register_req},
 	{SBIT(4) | SBIT(7) | SBIT(8) | SBIT(10),
 	 CC_USER_INFORMATION | REQUEST, l3dss1_userinfo_req},
 	{SBIT(2) | SBIT(3) | SBIT(4) | SBIT(10) | SBIT(11) | SBIT(12) | SBIT(25),
 	 CC_INFORMATION | REQUEST, l3dss1_information_req},
 	{SBIT(2) | SBIT(3) | SBIT(4),
 	 CC_PROGRESS | REQUEST, l3dss1_progress_req},
-	{SBIT(10) | SBIT(15),
+	{SBIT(3) | SBIT(4) | SBIT(8) | SBIT(9) | SBIT(10) | SBIT(15) | SBIT(17),
 	 CC_NOTIFY | REQUEST, l3dss1_notify_req},
 	{SBIT(2),
 	 CC_T302, l3dss1_t302},
@@ -2514,9 +2664,10 @@
 		case IMSG_L2_DATA:
 			for (i = 0; i < DATASLLEN; i++)
 				if ((l3m->mt == datastatelist[i].primitive) &&
-					((1 << proc->state) & datastatelist[i].state))
+					((1UL << proc->state) & datastatelist[i].state))
 				break;
 			if (i == DATASLLEN) {
+				/* Message type not found or not valid to receive in the current state. */
 				if (proc->l3->debug & L3_DEB_STATE) {
 					l3_debug(proc->l3, "dss1 state %d mt %#x unhandled",
 						proc->state, l3m->mt);
@@ -2535,7 +2686,7 @@
 		case IMSG_MASTER_L2_DATA:
 			for (i = 0; i < MDATASLLEN; i++)
 				if ((l3m->mt == mdatastatelist[i].primitive) &&
-					((1 << proc->state) & mdatastatelist[i].state))
+					((1UL << proc->state) & mdatastatelist[i].state))
 				break;
 			if (i == MDATASLLEN) {
 				if (proc->l3->debug & L3_DEB_STATE) {
@@ -2562,9 +2713,10 @@
 		case IMSG_L4_DATA:
 			for (i = 0; i < DOWNSLLEN; i++)
 				if ((l3m->mt == downstatelist[i].primitive) &&
-					((1 << proc->state) & downstatelist[i].state))
+					((1UL << proc->state) & downstatelist[i].state))
 				break;
 			if (i == DOWNSLLEN) {
+				/* Message type not found or not valid to send in the current state. */
 				if (proc->l3->debug & L3_DEB_STATE) {
 					l3_debug(proc->l3, "dss1 state %d L4 %#x unhandled",
 						proc->state, l3m->mt);
@@ -2603,8 +2755,8 @@
 			break;
 		case IMSG_RELEASE_CHILDS:
 			{
-				RELEASE_t	*rel;
-				char		cause[3];
+				RELEASE_t *rel;
+				u_char cause[3];
 
 				cause[0] = 2;
 				cause[1] = CAUSE_LOC_PNET_LOCUSER | 0x80;
@@ -2634,6 +2786,7 @@
 static int
 dl_data_mux(layer3_t *l3, mISDNuser_head_t *hh, msg_t *msg)
 {
+	layer3_proc_t dummy;
 	layer3_proc_t	*proc;
 	int		ret = -EINVAL;
 	int		cr;
@@ -2674,15 +2827,14 @@
 		return(0);
 	} else if (cr == -1) {  /* Dummy Callref */
 		if (l3m.mt == MT_FACILITY) {
-			layer3_proc_t dummy;
-			memset( &dummy, 0, sizeof(layer3_proc_t));
+			memset(&dummy, 0, sizeof(layer3_proc_t));
 			dummy.l3 = l3;
 			dummy.ces = 0;
 			dummy.callref = -1;
 			l3dss1_facility(&dummy, hh->prim, msg);
-		}
-		else if (l3->debug & L3_DEB_WARN)
+		} else if (l3->debug & L3_DEB_WARN) {
 			l3_debug(l3, "dss1 dummy Callref (no facility msg)");
+		}
 		free_msg(msg);
 		return(0);
 	} else if ((((msg->data[1] & 0x0f) == 1) && (0==(cr & 0x7f))) ||
@@ -2693,8 +2845,7 @@
 //		global_handler(l3, l3m.mt, msg);
 
 		if (l3m.mt == MT_RESTART)  {
-			layer3_proc_t dummy;
-			memset( &dummy, 0, sizeof(layer3_proc_t));
+			memset(&dummy, 0, sizeof(layer3_proc_t));
 			dummy.l3 = l3;
 			dummy.ces = 0;
 			dummy.callref = 0;
@@ -2707,17 +2858,22 @@
 	proc = find_proc(l3->proc, hh->dinfo, cr);
 	dprint(DBGM_L3, l3->nst->cardnr, "%s: proc(%p)\n", __FUNCTION__, proc);
 	if (!proc) {
-		if (l3m.mt == MT_SETUP || l3m.mt == MT_RESUME) {
-			/* Setup/Resume creates a new transaction process */
+		switch (l3m.mt) {
+		case MT_SETUP:
+		case MT_RESUME:
+		case MT_REGISTER:
 			if (msg->data[2] & 0x80) {
-				/* Setup/Resume with wrong CREF flag */
+				/* Wrong CREF flag */
 				if (l3->debug & L3_DEB_STATE)
 					l3_debug(l3, "dss1 wrong CRef flag");
 				free_msg(msg);
 				return(0);
 			}
-			dprint(DBGM_L3, l3->nst->cardnr, "%s: %s\n", __FUNCTION__, (l3m.mt==MT_SETUP)?"MT_SETUP":"MT_RESUME");
-			if (!(proc = create_proc(l3, hh->dinfo, cr, NULL))) {
+
+			/* Create a new transaction process */
+			dprint(DBGM_L3, l3->nst->cardnr, "%s: mt(%x) creating proc\n", __FUNCTION__, l3m.mt);
+			proc = create_proc(l3, hh->dinfo, cr, NULL);
+			if (!proc) {
 				/* May be to answer with RELEASE_COMPLETE and
 				 * CAUSE 0x2f "Resource unavailable", but this
 				 * need a new_l3_process too ... arghh
@@ -2727,13 +2883,14 @@
 			}
 			dprint(DBGM_L3, l3->nst->cardnr, "%s: proc(%p)\n", __FUNCTION__, proc);
 			APPEND_TO_LIST(proc, l3->proc);
-		} else {
+			break;
+		default:
 			dprint(DBGM_L3, l3->nst->cardnr, "%s: mt(%x) do not create proc\n", __FUNCTION__,
 				l3m.mt);
 			// TODO: it happens that a response to an outgoing setup is received after connect of another terminal. in this case we must release.
 			free_msg(msg);
 			return(0);
-		}
+		}	/* end switch */
 	}
 	if ((proc->ces & 0xffffff00) == 0xff00) {
 		dprint(DBGM_L3, l3->nst->cardnr, "%s: master state %d found\n", __FUNCTION__,
@@ -2774,6 +2931,7 @@
 	mISDNuser_head_t	*hh;
 	layer3_proc_t	*proc;
 	struct _l3_msg	l3m;
+	layer3_proc_t dummy;
 
 	hh = (mISDNuser_head_t *)msg->data;
 	dprint(DBGM_L3, nst->cardnr, "%s: msg len(%d)\n", __FUNCTION__, msg->len);
@@ -2784,40 +2942,45 @@
 		(hh->dinfo>>16)& 0xffff);
 	if (!proc) {
 		switch (hh->prim) {
-			case CC_RESTART | REQUEST:
-				{
-					layer3_proc_t dummy;
-					memset( &dummy, 0, sizeof(layer3_proc_t));
-					dummy.l3 = nst->layer3;
-					dummy.ces = 0;
-					dummy.callref = 0;
-					l3dss1_restart_req(&dummy, hh->prim, msg->data); 
-					free_msg(msg);
-					return(0);
-				}
-			break;
-			case CC_SETUP | REQUEST:
-			{
-				int l4id;
-				nst->layer3->next_cr++;
-				if (nst->feature & FEATURE_NET_CRLEN2) {
-					if (nst->layer3->next_cr>32766)
-						nst->layer3->next_cr = 1;
-				} else {
-					if (nst->layer3->next_cr>126)
-						nst->layer3->next_cr = 1;
-				}
-				proc = create_proc(nst->layer3, hh->dinfo & 0xffff,
-					nst->layer3->next_cr | 0x8000, NULL);
-				if (!proc) {
-					dprint(DBGM_L3, nst->cardnr, "%s: pr(%x) failed to create proc.\n",
-						__FUNCTION__, hh->prim);
-					free_msg(msg);
-					return(0);
-				}
-				dprint(DBGM_L3, nst->cardnr, "%s: proc(%p)\n", __FUNCTION__, proc);
+		case CC_RESTART | REQUEST:
+			memset(&dummy, 0, sizeof(layer3_proc_t));
+			dummy.l3 = nst->layer3;
+			dummy.ces = 0;
+			dummy.callref = 0;/* global call reference */
+			l3dss1_restart_req(&dummy, hh->prim, msg->data); 
+			free_msg(msg);
+			return(0);
+		case CC_FACILITY | REQUEST:
+			memset(&dummy, 0, sizeof(layer3_proc_t));
+			dummy.l3 = nst->layer3;
+			dummy.ces = 0;
+			dummy.callref = -1;/* Dummy call reference */
+			l3dss1_facility_req(&dummy, hh->prim, msg->data); 
+			free_msg(msg);
+			return(0);
+		case CC_REGISTER | REQUEST:
+		case CC_SETUP | REQUEST:
+		{
+			int l4id;
+			nst->layer3->next_cr++;
+			if (nst->feature & FEATURE_NET_CRLEN2) {
+				if (nst->layer3->next_cr>32766)
+					nst->layer3->next_cr = 1;
+			} else {
+				if (nst->layer3->next_cr>126)
+					nst->layer3->next_cr = 1;
+			}
+			proc = create_proc(nst->layer3, hh->dinfo & 0xffff,
+				nst->layer3->next_cr | 0x8000, NULL);
+			if (!proc) {
+				dprint(DBGM_L3, nst->cardnr, "%s: pr(%x) failed to create proc.\n",
+					__FUNCTION__, hh->prim);
+				free_msg(msg);
+				return(0);
+			}
+			dprint(DBGM_L3, nst->cardnr, "%s: proc(%p)\n", __FUNCTION__, proc);
+#if 0
 #warning testing
-#if 0
 printf("check for tei 0 active\n");
 		l2 = nst->layer2;
 		while(l2) {
@@ -2837,23 +3000,23 @@
 			
 		}
 #endif
-			
-
-				APPEND_TO_LIST(proc, nst->layer3->proc);
-				l4id = proc->ces | (proc->callref << 16);
-				if_link(nst->manager, (ifunc_t)nst->l3_manager, CC_SETUP | CONFIRM, hh->dinfo, sizeof(int), &l4id, 0);
-				}
+			APPEND_TO_LIST(proc, nst->layer3->proc);
+			l4id = proc->ces | (proc->callref << 16);
+			if_link(nst->manager, (ifunc_t) nst->l3_manager,
+				(hh->prim & MISDN_CMD_MASK) | CONFIRM,
+				hh->dinfo, sizeof(int), &l4id, 0);
 			break;
-			case DL_ESTABLISH | REQUEST: 
-				if (nst->feature & FEATURE_NET_PTP) {
-					l3down(nst->layer3, DL_ESTABLISH | REQUEST, 0, NULL);
-					free_msg(msg);
-					return 0;
-				}
+		}
+		case DL_ESTABLISH | REQUEST: 
+			if (nst->feature & FEATURE_NET_PTP) {
+				l3down(nst->layer3, DL_ESTABLISH | REQUEST, 0, NULL);
+				free_msg(msg);
+				return 0;
+			}
 			break;
-			default:
+		default:
 			break;
-		}
+		}	/* end switch */
 	}
 	if (!proc) {
 		dprint(DBGM_L3, nst->cardnr, "%s: pr(%x) no proc id %x found\n", __FUNCTION__,

Modified: mISDNuser/trunk/i4lnet/net_l3.h
URL: http://svn.digium.com/view/thirdparty/mISDNuser/trunk/i4lnet/net_l3.h?view=diff&rev=33&r1=32&r2=33
==============================================================================
--- mISDNuser/trunk/i4lnet/net_l3.h (original)
+++ mISDNuser/trunk/i4lnet/net_l3.h Thu Dec 18 21:29:13 2008
@@ -19,6 +19,136 @@
 	itimer_t		tl;
 	int			nr;
 };
+
+/*
+* Q.931 call states
+*
+* Call states at the user side of the interface:
+*   null state (U0):
+*     No call exists.
+*   call initiated (U1):
+*     This state exists for an outgoing call, when the user requests
+*     call establishment from the network.
+*   overlap sending (U2):
+*     This state exists for an outgoing call when the user has
+*     received acknowledgement of the call establishment request which
+*     permits the user to send additional call information to the network
+*     in overlap mode.
+*   outgoing call proceeding (U3):
+*     This state exists for an outgoing call when the user has
+*     received acknowledgement that the network has received all
+*     call information necessary to effect call establishment.
+*   call delivered (U4):
+*     This state exists for an outgoing call when the calling user has
+*     received an indication that remote user alerting has been initiated.
+*   call present (U6):
+*     This state exists for an incoming call when the user has received a
+*     call establishment request but has not yet responded.
+*   call received (U7):
+*     This state exists for an incoming call when the user has indicated
+*     alerting but has not yet answered.
+*   connect request (U8):
+*     This state exists for an incoming call when the user has answered
+*     the call and is waiting to be awarded the call.
+*   incoming call proceeding (U9):
+*     This state exists for an incoming call when the user has sent
+*     acknowledgement that the user has received all call information
+*     necessary to effect call establishment.
+*   active (U10):
+*     This state exists for an incoming call when the user has received
+*     an acknowledgement from the network that the user has been awarded
+*     the call. This state exists for an outgoing call when the user has
+*     received an indication that the remote user has answered the call.
+*   disconnect request (U11):
+*     This state exists when the user has requested the network to clear
+*     the end-to-end connection (if any) and is waiting for a response.
+*   disconnect indication (U12):
+*     This state exists when the user has received an invitation to
+*     disconnect because the network has disconnected the end-to-end
+*     connection (if any).
+*   suspend request (U15):
+*     This state exists when the user has requested the network to suspend
+*     the call and is waiting for a response.
+*   resume request (U17):
+*     This state exists when the user has requested the network to resume
+*     a previously suspended call and is waiting for a response.
+*   release request (U19):
+*     This state exists when the user has requested the network to release
+*     and is waiting for a response.
+*   overlap receiving (U25):
+*     This state exists for an incoming call when the user has acknowledged
+*     the call establishment request from the network and is prepared to
+*     receive additional call information (if any) in overlap mode.
+*   call independent service (U31): (From Q.932)
+*     This state exists when a call independent supplementary service
+*     signalling connection is established.
+*
+* Network call states
+*   null state (N0):
+*     No call exists.
+*   call initiated (N1):
+*     This state exists for an outgoing call when the network has received
+*     a call establishment request but has not yet responded.
+*   overlap sending (N2):
+*     This state exists for an outgoing call when the network has acknowledged
+*     the call establishment request and is prepared to receive additional
+*     call information (if any) in overlap mode.
+*   outgoing call proceeding (N3):
+*     This state exists for an outgoing call when the network has sent
+*     acknowledgement that the network has received all call information
+*     necessary to effect call establishment.
+*   call delivered (N4):
+*     This state exists for an outgoing call when the network has indicated
+*     that remote user alerting has been initiated.
+*   call present (N6):
+*     This state exists for an incoming call when the network has sent a
+*     call establishment request but has not yet received a satisfactory
+*     response.
+*   call received (N7):
+*     This state exists for an incoming call when the network has received
+*     an indication that the user is alerting but has not yet received an
+*     answer.
+*   connect request (N8):
+*     This state exists for an incoming call when the network has received
+*     an answer but the network has not yet awarded the call.
+*   incoming call proceeding (N9):
+*     This state exists for an incoming call when the network has received
+*     acknowledgement that the user has received all call information
+*     necessary to effect call establishment.
+*   active (N10):
+*     This state exists for an incoming call when the network has awarded
+*     the call to the called user. This state exists for an outgoing call
+*     when the network has indicated that the remote user has answered
+*     the call.
+*   disconnect request (N11):
+*     This state exists when the network has received a request from the
+*     user to clear the end-to-end connection (if any).
+*   disconnect indication (N12):
+*     This state exists when the network has disconnected the end-to-end
+*     connection (if any) and has sent an invitation to disconnect the
+*     user-network connection.
+*   suspend request (N15):
+*     This state exists when the network has received a request to suspend
+*     the call but has not yet responded.
+*   resume request (N17):
+*     This state exists when the network has received a request to resume
+*     a previously suspended call but has not yet responded.
+*   release request (N19):
+*     This state exists when the network has requested the user to release
+*     and is waiting for a response.
+*   call abort (N22):
+*     This state exists for an incoming call for the point-to-multipoint
+*     configuration when the call is being cleared before any user has been
+*     awarded the call.
+*   overlap receiving (N25):
+*     This state exists for an incoming call when the network has received
+*     acknowledgement of the call establishment request which permits the
+*     network to send additional call information (if any) in the overlap
+*     mode.
+*   call independent service (N31): (From Q.932)
+*     This state exists when a call independent supplementary service
+*     signalling connection is established.
+*/
 
 struct _layer3_proc {
 	layer3_proc_t	*prev;
@@ -29,7 +159,7 @@
 	int		callref;
 	int		ces;
 	int		selces;
-	int		state;
+	int		state;/* User/Network call state */
 	u_long		Flags;
 	L3Timer_t	timer1;
 	L3Timer_t	timer2;
@@ -259,6 +389,11 @@
 	u_char *DISPLAY;
 } FACILITY_t;
 
+typedef struct _REGISTER {
+	u_char *FACILITY;
+	u_char *DISPLAY;
+} REGISTER_t;
+
 typedef struct _HOLD {
 	u_char *DISPLAY;
 } HOLD_t;

Modified: mISDNuser/trunk/include/l3dss1.h
URL: http://svn.digium.com/view/thirdparty/mISDNuser/trunk/include/l3dss1.h?view=diff&rev=33&r1=32&r2=33
==============================================================================
--- mISDNuser/trunk/include/l3dss1.h (original)
+++ mISDNuser/trunk/include/l3dss1.h Thu Dec 18 21:29:13 2008
@@ -67,6 +67,7 @@
 #define MT_CONGESTION_CONTROL	0x79
 #define MT_INFORMATION		0x7b
 #define MT_FACILITY		0x62
+#define MT_REGISTER		0x64
 #define MT_NOTIFY		0x6e
 #define MT_STATUS		0x7d
 #define MT_STATUS_ENQUIRY	0x75




More information about the svn-commits mailing list