[libpri-commits] rmudgett: branch group/ccss r1056 - in /team/group/ccss: pri_q931.h q931.c

SVN commits to the libpri project libpri-commits at lists.digium.com
Mon Aug 31 18:28:17 CDT 2009


Author: rmudgett
Date: Mon Aug 31 18:28:14 2009
New Revision: 1056

URL: http://svn.asterisk.org/svn-view/libpri?view=rev&rev=1056
Log:
Add REGISTER message support.

Modified:
    team/group/ccss/pri_q931.h
    team/group/ccss/q931.c

Modified: team/group/ccss/pri_q931.h
URL: http://svn.asterisk.org/svn-view/libpri/team/group/ccss/pri_q931.h?view=diff&rev=1056&r1=1055&r2=1056
==============================================================================
--- team/group/ccss/pri_q931.h (original)
+++ team/group/ccss/pri_q931.h Mon Aug 31 18:28:14 2009
@@ -104,6 +104,7 @@
 #define Q931_CONGESTION_CONTROL		0x79
 #define Q931_INFORMATION			0x7b
 #define Q931_FACILITY				0x62
+#define Q931_REGISTER				0x64	/* Q.932 */
 #define Q931_NOTIFY					0x6e
 
 /* Call Management Messages */
@@ -458,6 +459,9 @@
 extern q931_call *q931_new_call(struct pri *pri);
 
 extern int q931_setup(struct pri *pri, q931_call *c, struct pri_sr *req);
+
+int q931_register(struct pri *ctrl, q931_call *call);
+
 extern void q931_dump(struct pri *pri, q931_h *h, int len, int txrx);
 
 extern void __q931_destroycall(struct pri *pri, q931_call *c);

Modified: team/group/ccss/q931.c
URL: http://svn.asterisk.org/svn-view/libpri/team/group/ccss/q931.c?view=diff&rev=1056&r1=1055&r2=1056
==============================================================================
--- team/group/ccss/q931.c (original)
+++ team/group/ccss/q931.c Mon Aug 31 18:28:14 2009
@@ -75,6 +75,7 @@
 	{ Q931_CONGESTION_CONTROL, "CONGESTION CONTROL" },
 	{ Q931_INFORMATION, "INFORMATION" },
 	{ Q931_FACILITY, "FACILITY" },
+	{ Q931_REGISTER, "REGISTER" },
 	{ Q931_NOTIFY, "NOTIFY", { Q931_IE_NOTIFY_IND } },
 
 	/* Call Management */
@@ -3628,6 +3629,10 @@
 
 int q931_call_progress(struct pri *ctrl, q931_call *c, int channel, int info)
 {
+	if (c->ourcallstate == Q931_CALL_STATE_CALL_INDEPENDENT_SERVICE) {
+		/* Cannot send this message when in this state */
+		return 0;
+	}
 	if (channel) { 
 		c->ds1no = (channel & 0xff00) >> 8;
 		c->ds1explicit = (channel & 0x10000) >> 16;
@@ -3650,6 +3655,10 @@
 
 int q931_call_progress_with_cause(struct pri *ctrl, q931_call *c, int channel, int info, int cause)
 {
+	if (c->ourcallstate == Q931_CALL_STATE_CALL_INDEPENDENT_SERVICE) {
+		/* Cannot send this message when in this state */
+		return 0;
+	}
 	if (channel) { 
 		c->ds1no = (channel & 0xff00) >> 8;
 		c->ds1explicit = (channel & 0x10000) >> 16;
@@ -3682,6 +3691,10 @@
 
 int q931_call_proceeding(struct pri *ctrl, q931_call *c, int channel, int info)
 {
+	if (c->ourcallstate == Q931_CALL_STATE_CALL_INDEPENDENT_SERVICE) {
+		/* Cannot send this message when in this state */
+		return 0;
+	}
 	if (channel) { 
 		c->ds1no = (channel & 0xff00) >> 8;
 		c->ds1explicit = (channel & 0x10000) >> 16;
@@ -3709,6 +3722,10 @@
 
 int q931_alerting(struct pri *ctrl, q931_call *c, int channel, int info)
 {
+	if (c->ourcallstate == Q931_CALL_STATE_CALL_INDEPENDENT_SERVICE) {
+		/* Cannot send this message when in this state */
+		return 0;
+	}
 	if (!c->proc) 
 		q931_call_proceeding(ctrl, c, channel, 0);
 	if (info) {
@@ -3739,6 +3756,10 @@
  
 int q931_setup_ack(struct pri *ctrl, q931_call *c, int channel, int nonisdn)
 {
+	if (c->ourcallstate == Q931_CALL_STATE_CALL_INDEPENDENT_SERVICE) {
+		/* Cannot send this message when in this state */
+		return 0;
+	}
 	if (channel) { 
 		c->ds1no = (channel & 0xff00) >> 8;
 		c->ds1explicit = (channel & 0x10000) >> 16;
@@ -3833,6 +3854,10 @@
 
 int q931_connect(struct pri *ctrl, q931_call *c, int channel, int nonisdn)
 {
+	if (c->ourcallstate == Q931_CALL_STATE_CALL_INDEPENDENT_SERVICE) {
+		/* Cannot send this message when in this state */
+		return 0;
+	}
 	if (channel) { 
 		c->ds1no = (channel & 0xff00) >> 8;
 		c->ds1explicit = (channel & 0x10000) >> 16;
@@ -4046,6 +4071,38 @@
 	}
 	return res;
 	
+}
+
+static int register_ies[] = { Q931_IE_FACILITY, -1 };
+
+/*!
+ * \brief Build and send the REGISTER message.
+ *
+ * \param ctrl D channel controller.
+ * \param call Q.931 call leg
+ *
+ * \retval 0 on success.
+ * \retval -1 on error.
+ */
+int q931_register(struct pri *ctrl, q931_call *call)
+{
+	int res;
+
+	call->newcall = 0;
+
+	call->cis_call = 1;
+	call->cis_auto_disconnect = 0;
+	call->chanflags = FLAG_EXCLUSIVE;/* For safety mark this channel as exclusive. */
+	call->channelno = 0;
+
+	res = send_message(ctrl, call, Q931_REGISTER, register_ies);
+	if (!res) {
+		call->alive = 1;
+
+		UPDATE_OURCALLSTATE(ctrl, call, Q931_CALL_STATE_CALL_INDEPENDENT_SERVICE);
+		call->peercallstate = Q931_CALL_STATE_CALL_INDEPENDENT_SERVICE;
+	}
+	return res;
 }
 
 static int release_complete_ies[] = { Q931_IE_FACILITY, Q931_IE_USER_USER, -1 };
@@ -4203,6 +4260,10 @@
 		/* sent RELEASE */
 		/* don't do anything, waiting for RELEASE_COMPLETE */
 		break;
+	case Q931_CALL_STATE_CALL_INDEPENDENT_SERVICE:
+		/* we sent or received REGISTER */
+		q931_release_complete(ctrl, c, cause);
+		break;
 	case Q931_CALL_STATE_RESTART:
 	case Q931_CALL_STATE_RESTART_REQUEST:
 		/* sent RESTART */
@@ -4287,6 +4348,8 @@
 	case Q931_SETUP:
 		if (ctrl->debug & PRI_DEBUG_Q931_STATE)
 			pri_message(ctrl, "-- Processing Q.931 Call Setup\n");
+		/* Fall through */
+	case Q931_REGISTER:
 		c->channelno = -1;
 		c->slotmap = -1;
 		c->chanflags = 0;
@@ -4314,6 +4377,7 @@
 		/* Fall through */
 	case Q931_CONNECT:
 		c->ccrequestresult = 0;
+		/* Fall through */
 	case Q931_ALERTING:
 	case Q931_PROGRESS:
 		c->useruserinfo[0] = '\0';
@@ -4602,6 +4666,122 @@
 
 /*!
  * \internal
+ * \brief Fill in the RING event fields.
+ *
+ * \param ctrl D channel controller.
+ * \param call Q.931 call leg
+ *
+ * \return Nothing
+ */
+static void q931_fill_ring_event(struct pri *ctrl, struct q931_call *call)
+{
+	struct pri_subcommand *subcmd;
+
+	if (call->redirecting.from.number.valid && !call->redirecting.count) {
+		/*
+		 * This is most likely because the redirecting number came in
+		 * with the redirecting ie only and not a DivertingLegInformation2.
+		 */
+		call->redirecting.count = 1;
+	}
+	if (call->redirecting.state == Q931_REDIRECTING_STATE_PENDING_TX_DIV_LEG_3) {
+		/*
+		 * Valid for Q.SIG and ETSI PRI/BRI-PTP modes:
+		 * Setup the redirecting.to informtion so we can identify
+		 * if the user wants to manually supply the COLR for this
+		 * redirected to number if further redirects could happen.
+		 *
+		 * All the user needs to do is set the REDIRECTING(to-pres)
+		 * to the COLR and REDIRECTING(to-num) = complete-dialed-number
+		 * (i.e. CALLERID(dnid)) to be safe after determining that the
+		 * incoming call was redirected by checking if the
+		 * REDIRECTING(count) is nonzero.
+		 */
+		call->redirecting.to.number = call->called.number;
+		call->redirecting.to.number.presentation =
+			PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_UNSCREENED;
+	}
+
+	ctrl->ev.e = PRI_EVENT_RING;
+	ctrl->ev.ring.subcmds = &ctrl->subcmds;
+	ctrl->ev.ring.channel = q931_encode_channel(call);
+
+	/* Calling party information */
+	ctrl->ev.ring.callingpres = q931_party_id_presentation(&call->remote_id);
+	ctrl->ev.ring.callingplan = call->remote_id.number.plan;
+	if (call->remote_id.number.valid
+		&& (call->remote_id.number.presentation == PRES_ALLOWED_NETWORK_NUMBER
+			|| call->remote_id.number.presentation == PRES_PROHIB_NETWORK_NUMBER)) {
+		ctrl->ev.ring.callingplanani = call->remote_id.number.plan;
+		libpri_copy_string(ctrl->ev.ring.callingani, call->remote_id.number.str,
+			sizeof(ctrl->ev.ring.callingani));
+	} else {
+		ctrl->ev.ring.callingplanani = -1;
+		ctrl->ev.ring.callingani[0] = '\0';
+	}
+	libpri_copy_string(ctrl->ev.ring.callingnum, call->remote_id.number.str,
+		sizeof(ctrl->ev.ring.callingnum));
+	libpri_copy_string(ctrl->ev.ring.callingname, call->remote_id.name.str,
+		sizeof(ctrl->ev.ring.callingname));
+	libpri_copy_string(ctrl->ev.ring.callingsubaddr, call->callingsubaddr,
+		sizeof(ctrl->ev.ring.callingsubaddr));
+
+	ctrl->ev.ring.ani2 = call->ani2;
+
+	/* Called party information */
+	ctrl->ev.ring.calledplan = call->called.number.plan;
+	libpri_copy_string(ctrl->ev.ring.callednum, call->called.number.str,
+		sizeof(ctrl->ev.ring.callednum));
+
+	/* Original called party information (For backward compatibility) */
+	libpri_copy_string(ctrl->ev.ring.origcalledname,
+		call->redirecting.orig_called.name.str, sizeof(ctrl->ev.ring.origcalledname));
+	libpri_copy_string(ctrl->ev.ring.origcallednum,
+		call->redirecting.orig_called.number.str, sizeof(ctrl->ev.ring.origcallednum));
+	ctrl->ev.ring.callingplanorigcalled = call->redirecting.orig_called.number.plan;
+	if (call->redirecting.orig_called.number.valid
+		|| call->redirecting.orig_called.name.valid) {
+		ctrl->ev.ring.origredirectingreason = call->redirecting.orig_reason;
+	} else {
+		ctrl->ev.ring.origredirectingreason = -1;
+	}
+
+	/* Redirecting from party information (For backward compatibility) */
+	ctrl->ev.ring.callingplanrdnis = call->redirecting.from.number.plan;
+	libpri_copy_string(ctrl->ev.ring.redirectingnum, call->redirecting.from.number.str,
+		sizeof(ctrl->ev.ring.redirectingnum));
+	libpri_copy_string(ctrl->ev.ring.redirectingname, call->redirecting.from.name.str,
+		sizeof(ctrl->ev.ring.redirectingname));
+
+	ctrl->ev.ring.redirectingreason = call->redirecting.reason;
+
+	libpri_copy_string(ctrl->ev.ring.useruserinfo, call->useruserinfo,
+		sizeof(ctrl->ev.ring.useruserinfo));
+	call->useruserinfo[0] = '\0';
+
+	ctrl->ev.ring.flexible = !(call->chanflags & FLAG_EXCLUSIVE);
+	ctrl->ev.ring.cref = call->cr;
+	ctrl->ev.ring.call = call;
+	ctrl->ev.ring.layer1 = call->userl1;
+	ctrl->ev.ring.complete = call->complete;
+	ctrl->ev.ring.ctype = call->transcapability;
+	ctrl->ev.ring.progress = call->progress;
+	ctrl->ev.ring.progressmask = call->progressmask;
+	ctrl->ev.ring.reversecharge = call->reversecharge;
+
+	if (call->redirecting.count) {
+		subcmd = q931_alloc_subcommand(ctrl);
+		if (subcmd) {
+			/* Setup redirecting subcommand */
+			subcmd->cmd = PRI_SUBCMD_REDIRECTING;
+			q931_party_redirecting_copy_to_pri(&subcmd->u.redirecting,
+				&call->redirecting);
+		}
+	}
+}
+
+/*!
+ * \internal
  * \brief Fill in the FACILITY event fields.
  *
  * \param ctrl D channel controller.
@@ -4659,6 +4839,24 @@
 		/* Notify user of restart event */
 		ctrl->ev.e = PRI_EVENT_RESTART;
 		ctrl->ev.restart.channel = q931_encode_channel(c);
+		return Q931_RES_HAVEEVENT;
+	case Q931_REGISTER:
+		/* Must be new call */
+		if (!c->newcall) {
+			q931_status(ctrl, c, PRI_CAUSE_WRONG_CALL_STATE);
+			break;
+		}
+		c->newcall = 0;
+		c->alive = 1;
+
+		c->cis_call = 1;
+		c->chanflags = FLAG_EXCLUSIVE;/* For safety mark this channel as exclusive. */
+		c->channelno = 0;
+
+		UPDATE_OURCALLSTATE(ctrl, c, Q931_CALL_STATE_CALL_INDEPENDENT_SERVICE);
+		c->peercallstate = Q931_CALL_STATE_CALL_INDEPENDENT_SERVICE;
+
+		q931_fill_ring_event(ctrl, c);
 		return Q931_RES_HAVEEVENT;
 	case Q931_SETUP:
 		if (missingmand) {
@@ -4681,98 +4879,7 @@
 			break;
 		}
 
-		if (c->redirecting.from.number.valid && !c->redirecting.count) {
-			/*
-			 * This is most likely because the redirecting number came in
-			 * with the redirecting ie only and not a DivertingLegInformation2.
-			 */
-			c->redirecting.count = 1;
-		}
-		if (c->redirecting.state == Q931_REDIRECTING_STATE_PENDING_TX_DIV_LEG_3) {
-			/*
-			 * Valid for Q.SIG and ETSI PRI/BRI-PTP modes:
-			 * Setup the redirecting.to informtion so we can identify
-			 * if the user wants to manually supply the COLR for this
-			 * redirected to number if further redirects could happen.
-			 *
-			 * All the user needs to do is set the REDIRECTING(to-pres)
-			 * to the COLR and REDIRECTING(to-num) = complete-dialed-number
-			 * (i.e. CALLERID(dnid)) to be safe after determining that the
-			 * incoming call was redirected by checking if the
-			 * REDIRECTING(count) is nonzero.
-			 */
-			c->redirecting.to.number = c->called.number;
-			c->redirecting.to.number.presentation =
-				PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_UNSCREENED;
-		}
-
-		ctrl->ev.e = PRI_EVENT_RING;
-		ctrl->ev.ring.subcmds = &ctrl->subcmds;
-		ctrl->ev.ring.channel = q931_encode_channel(c);
-
-		/* Calling party information */
-		ctrl->ev.ring.callingpres = q931_party_id_presentation(&c->remote_id);
-		ctrl->ev.ring.callingplan = c->remote_id.number.plan;
-		if (c->remote_id.number.valid
-			&& (c->remote_id.number.presentation == PRES_ALLOWED_NETWORK_NUMBER
-				|| c->remote_id.number.presentation == PRES_PROHIB_NETWORK_NUMBER)) {
-			ctrl->ev.ring.callingplanani = c->remote_id.number.plan;
-			libpri_copy_string(ctrl->ev.ring.callingani, c->remote_id.number.str, sizeof(ctrl->ev.ring.callingani));
-		} else {
-			ctrl->ev.ring.callingplanani = -1;
-			ctrl->ev.ring.callingani[0] = '\0';
-		}
-		libpri_copy_string(ctrl->ev.ring.callingnum, c->remote_id.number.str, sizeof(ctrl->ev.ring.callingnum));
-		libpri_copy_string(ctrl->ev.ring.callingname, c->remote_id.name.str, sizeof(ctrl->ev.ring.callingname));
-		libpri_copy_string(ctrl->ev.ring.callingsubaddr, c->callingsubaddr, sizeof(ctrl->ev.ring.callingsubaddr));
-
-		ctrl->ev.ring.ani2 = c->ani2;
-
-		/* Called party information */
-		ctrl->ev.ring.calledplan = c->called.number.plan;
-		libpri_copy_string(ctrl->ev.ring.callednum, c->called.number.str, sizeof(ctrl->ev.ring.callednum));
-
-		/* Original called party information (For backward compatibility) */
-		libpri_copy_string(ctrl->ev.ring.origcalledname, c->redirecting.orig_called.name.str, sizeof(ctrl->ev.ring.origcalledname));
-		libpri_copy_string(ctrl->ev.ring.origcallednum, c->redirecting.orig_called.number.str, sizeof(ctrl->ev.ring.origcallednum));
-		ctrl->ev.ring.callingplanorigcalled = c->redirecting.orig_called.number.plan;
-		if (c->redirecting.orig_called.number.valid
-			|| c->redirecting.orig_called.name.valid) {
-			ctrl->ev.ring.origredirectingreason = c->redirecting.orig_reason;
-		} else {
-			ctrl->ev.ring.origredirectingreason = -1;
-		}
-
-		/* Redirecting from party information (For backward compatibility) */
-		ctrl->ev.ring.callingplanrdnis = c->redirecting.from.number.plan;
-		libpri_copy_string(ctrl->ev.ring.redirectingnum, c->redirecting.from.number.str, sizeof(ctrl->ev.ring.redirectingnum));
-		libpri_copy_string(ctrl->ev.ring.redirectingname, c->redirecting.from.name.str, sizeof(ctrl->ev.ring.redirectingname));
-
-		ctrl->ev.ring.redirectingreason = c->redirecting.reason;
-
-		libpri_copy_string(ctrl->ev.ring.useruserinfo, c->useruserinfo, sizeof(ctrl->ev.ring.useruserinfo));
-		c->useruserinfo[0] = '\0';
-
-		ctrl->ev.ring.flexible = ! (c->chanflags & FLAG_EXCLUSIVE);
-		ctrl->ev.ring.cref = c->cr;
-		ctrl->ev.ring.call = c;
-		ctrl->ev.ring.layer1 = c->userl1;
-		ctrl->ev.ring.complete = c->complete; 
-		ctrl->ev.ring.ctype = c->transcapability;
-		ctrl->ev.ring.progress = c->progress;
-		ctrl->ev.ring.progressmask = c->progressmask;
-		ctrl->ev.ring.reversecharge = c->reversecharge;
-
-		if (c->redirecting.count) {
-			subcmd = q931_alloc_subcommand(ctrl);
-			if (subcmd) {
-				/* Setup redirecting subcommand */
-				subcmd->cmd = PRI_SUBCMD_REDIRECTING;
-				q931_party_redirecting_copy_to_pri(&subcmd->u.redirecting,
-					&c->redirecting);
-			}
-		}
-
+		q931_fill_ring_event(ctrl, c);
 		return Q931_RES_HAVEEVENT;
 	case Q931_ALERTING:
 		if (c->newcall) {




More information about the libpri-commits mailing list