[libpri-commits] rmudgett: branch rmudgett/ect r1497 - /team/rmudgett/ect/

SVN commits to the libpri project libpri-commits at lists.digium.com
Mon Feb 15 14:50:57 CST 2010


Author: rmudgett
Date: Mon Feb 15 14:50:52 2010
New Revision: 1497

URL: http://svnview.digium.com/svn/libpri?view=rev&rev=1497
Log:
Add code to initiate ETSI ECT when Asterisk detects a tromboned call.

Modified:
    team/rmudgett/ect/libpri.h
    team/rmudgett/ect/pri.c
    team/rmudgett/ect/pri_facility.c
    team/rmudgett/ect/pri_facility.h
    team/rmudgett/ect/pri_q931.h
    team/rmudgett/ect/q931.c

Modified: team/rmudgett/ect/libpri.h
URL: http://svnview.digium.com/svn/libpri/team/rmudgett/ect/libpri.h?view=diff&rev=1497&r1=1496&r2=1497
==============================================================================
--- team/rmudgett/ect/libpri.h (original)
+++ team/rmudgett/ect/libpri.h Mon Feb 15 14:50:52 2010
@@ -1205,7 +1205,7 @@
 
 #define PRI_2BCT
 /* Attempt to pass the channels back to the NET side if compatable and
- * suscribed.  Sometimes called 2 bchannel transfer (2BCT) */
+ * subscribed.  Sometimes called 2 bchannel transfer (2BCT) */
 int pri_channel_bridge(q931_call *call1, q931_call *call2);
 
 /* Override message and error stuff */

Modified: team/rmudgett/ect/pri.c
URL: http://svnview.digium.com/svn/libpri/team/rmudgett/ect/pri.c?view=diff&rev=1497&r1=1496&r2=1497
==============================================================================
--- team/rmudgett/ect/pri.c (original)
+++ team/rmudgett/ect/pri.c Mon Feb 15 14:50:52 2010
@@ -1024,6 +1024,10 @@
 	if (!call1 || !call2)
 		return -1;
 
+	/* Check to see if we're on the same PRI */
+	if (call1->pri != call2->pri)
+		return -1;
+	
 	/* Make sure we have compatible switchtypes */
 	if (call1->pri->switchtype != call2->pri->switchtype)
 		return -1;
@@ -1032,36 +1036,36 @@
 	if (call1->bc.transcapability != call2->bc.transcapability)
 		return -1;
 
-	/* Check to see if we're on the same PRI */
-	if (call1->pri != call2->pri)
-		return -1;
-	
 	switch (call1->pri->switchtype) {
-		case PRI_SWITCH_NI2:
-		case PRI_SWITCH_LUCENT5E:
-		case PRI_SWITCH_ATT4ESS:
-			if (eect_initiate_transfer(call1->pri, call1, call2))
-				return -1;
-			else
-				return 0;
-			break;
-		case PRI_SWITCH_DMS100:
-			if (rlt_initiate_transfer(call1->pri, call1, call2))
-				return -1;
-			else
-				return 0;
-			break;
-		case PRI_SWITCH_QSIG:
-			call1->bridged_call = call2;
-			call2->bridged_call = call1;
-			if (anfpr_initiate_transfer(call1->pri, call1, call2))
-				return -1;
-			else
-				return 0;
-			break;
-		default:
+	case PRI_SWITCH_NI2:
+	case PRI_SWITCH_LUCENT5E:
+	case PRI_SWITCH_ATT4ESS:
+		if (eect_initiate_transfer(call1->pri, call1, call2)) {
 			return -1;
-	}
+		}
+		break;
+	case PRI_SWITCH_DMS100:
+		if (rlt_initiate_transfer(call1->pri, call1, call2)) {
+			return -1;
+		}
+		break;
+	case PRI_SWITCH_QSIG:
+		call1->bridged_call = call2;
+		call2->bridged_call = call1;
+		if (anfpr_initiate_transfer(call1->pri, call1, call2)) {
+			return -1;
+		}
+		break;
+	case PRI_SWITCH_EUROISDN_E1:
+	case PRI_SWITCH_EUROISDN_T1:
+		if (etsi_initiate_transfer(call1->pri, call1, call2)) {
+			return -1;
+		}
+		break;
+	default:
+		return -1;
+	}
+	return 0;
 }
 
 int pri_hangup(struct pri *pri, q931_call *call, int cause)

Modified: team/rmudgett/ect/pri_facility.c
URL: http://svnview.digium.com/svn/libpri/team/rmudgett/ect/pri_facility.c?view=diff&rev=1497&r1=1496&r2=1497
==============================================================================
--- team/rmudgett/ect/pri_facility.c (original)
+++ team/rmudgett/ect/pri_facility.c Mon Feb 15 14:50:52 2010
@@ -2361,6 +2361,155 @@
 	return 0;
 }
 /* End AFN-PR */
+
+/*!
+ * \internal
+ * \brief Encode ETSI ExplicitEctExecute message.
+ *
+ * \param ctrl D channel controller for diagnostic messages or global options.
+ * \param pos Starting position to encode the facility ie contents.
+ * \param end End of facility ie contents encoding data buffer.
+ * \param link_id Identifier of other call involved in transfer.
+ *
+ * \retval Start of the next ASN.1 component to encode on success.
+ * \retval NULL on error.
+ */
+static unsigned char *enc_etsi_ect_explicit_execute(struct pri *ctrl, unsigned char *pos,
+	unsigned char *end, int link_id)
+{
+	struct rose_msg_invoke msg;
+
+	pos = facility_encode_header(ctrl, pos, end, NULL);
+	if (!pos) {
+		return NULL;
+	}
+
+	memset(&msg, 0, sizeof(msg));
+	msg.invoke_id = get_invokeid(ctrl);
+	msg.operation = ROSE_ETSI_ExplicitEctExecute;
+
+	msg.args.etsi.ExplicitEctExecute.link_id = link_id;
+
+	pos = rose_encode_invoke(ctrl, pos, end, &msg);
+
+	return pos;
+}
+
+/*!
+ * \internal
+ * \brief ECT LinkId response callback function.
+ *
+ * \param reason Reason callback is called.
+ * \param ctrl D channel controller.
+ * \param call Q.931 call leg.
+ * \param apdu APDU queued entry.  Do not change!
+ * \param msg APDU response message data.  (NULL if was not the reason called.)
+ *
+ * \return TRUE if no more responses are expected.
+ */
+static int etsi_ect_link_id_rsp(enum APDU_CALLBACK_REASON reason, struct pri *ctrl,
+	struct q931_call *call, struct apdu_event *apdu, const struct apdu_msg_data *msg)
+{
+	unsigned char buffer[256];
+	unsigned char *end;
+	q931_call *call_2;
+
+	switch (reason) {
+	case APDU_CALLBACK_REASON_MSG_RESULT:
+		call_2 = q931_find_call(ctrl, apdu->response.user.value);
+		if (!call_2) {
+			break;
+		}
+
+		end = enc_etsi_ect_explicit_execute(ctrl, buffer, buffer + sizeof(buffer),
+			msg->response.result->args.etsi.EctLinkIdRequest.link_id);
+		if (!end) {
+			break;
+		}
+
+		/* Remember that if we queue a facility IE for a facility message we
+		 * have to explicitly send the facility message ourselves */
+		if (pri_call_apdu_queue(call_2, Q931_FACILITY, buffer, end - buffer, NULL)) {
+			break;
+		}
+		if (q931_facility(call->pri, call_2)) {
+			pri_message(ctrl, "Could not schedule facility message for call %d\n",
+				call_2->cr);
+		}
+		break;
+	default:
+		break;
+	}
+	return 0;
+}
+
+/*!
+ * \internal
+ * \brief Encode ETSI ECT LinkId request message.
+ *
+ * \param ctrl D channel controller for diagnostic messages or global options.
+ * \param pos Starting position to encode the facility ie contents.
+ * \param end End of facility ie contents encoding data buffer.
+ *
+ * \retval Start of the next ASN.1 component to encode on success.
+ * \retval NULL on error.
+ */
+static unsigned char *enc_etsi_ect_link_id_req(struct pri *ctrl, unsigned char *pos,
+	unsigned char *end)
+{
+	struct rose_msg_invoke msg;
+
+	pos = facility_encode_header(ctrl, pos, end, NULL);
+	if (!pos) {
+		return NULL;
+	}
+
+	memset(&msg, 0, sizeof(msg));
+	msg.invoke_id = get_invokeid(ctrl);
+	msg.operation = ROSE_ETSI_EctLinkIdRequest;
+
+	pos = rose_encode_invoke(ctrl, pos, end, &msg);
+
+	return pos;
+}
+
+/*!
+ * \brief Start an Explicit Call Transfer (ECT) sequence between the two calls.
+ *
+ * \param ctrl D channel controller for diagnostic messages or global options.
+ * \param call_1 Q.931 call leg 1
+ * \param call_2 Q.931 call leg 2
+ *
+ * \retval 0 on success.
+ * \retval -1 on error.
+ */
+int etsi_initiate_transfer(struct pri *ctrl, q931_call *call_1, q931_call *call_2)
+{
+	unsigned char buffer[256];
+	unsigned char *end;
+	struct apdu_callback_data response;
+
+	end = enc_etsi_ect_link_id_req(ctrl, buffer, buffer + sizeof(buffer));
+	if (!end) {
+		return -1;
+	}
+
+	memset(&response, 0, sizeof(response));
+	response.invoke_id = ctrl->last_invoke;
+	response.timeout_time = -1;
+	response.callback = etsi_ect_link_id_rsp;
+	response.user.value = call_2->cr;
+
+	/* Remember that if we queue a facility IE for a facility message we
+	 * have to explicitly send the facility message ourselves */
+	if (pri_call_apdu_queue(call_1, Q931_FACILITY, buffer, end - buffer, &response)
+		|| q931_facility(call_1->pri, call_1)) {
+		pri_message(ctrl, "Could not schedule facility message for call %d\n", call_1->cr);
+		return -1;
+	}
+
+	return 0;
+}
 
 /* AOC */
 /*!

Modified: team/rmudgett/ect/pri_facility.h
URL: http://svnview.digium.com/svn/libpri/team/rmudgett/ect/pri_facility.h?view=diff&rev=1497&r1=1496&r2=1497
==============================================================================
--- team/rmudgett/ect/pri_facility.h (original)
+++ team/rmudgett/ect/pri_facility.h Mon Feb 15 14:50:52 2010
@@ -206,11 +206,13 @@
 
 int rlt_initiate_transfer(struct pri *pri, q931_call *c1, q931_call *c2);
 
+/* starts a QSIG Path Replacement */
+int anfpr_initiate_transfer(struct pri *pri, q931_call *c1, q931_call *c2);
+
+int etsi_initiate_transfer(struct pri *ctrl, q931_call *call_1, q931_call *call_2);
+
 int qsig_cf_callrerouting(struct pri *pri, q931_call *c, const char* dest, const char* original, const char* reason);
 int send_reroute_request(struct pri *ctrl, q931_call *call, const struct q931_party_id *caller, const struct q931_party_redirecting *deflection, int subscription_option);
-
-/* starts a QSIG Path Replacement */
-int anfpr_initiate_transfer(struct pri *pri, q931_call *c1, q931_call *c2);
 
 int send_call_transfer_complete(struct pri *pri, q931_call *call, int call_status);
 

Modified: team/rmudgett/ect/pri_q931.h
URL: http://svnview.digium.com/svn/libpri/team/rmudgett/ect/pri_q931.h?view=diff&rev=1497&r1=1496&r2=1497
==============================================================================
--- team/rmudgett/ect/pri_q931.h (original)
+++ team/rmudgett/ect/pri_q931.h Mon Feb 15 14:50:52 2010
@@ -490,7 +490,8 @@
 
 extern int q931_call_setcrv(struct pri *pri, q931_call *call, int crv, int callmode);
 
-extern q931_call *q931_new_call(struct pri *pri);
+q931_call *q931_find_call(struct pri *ctrl, int cr);
+q931_call *q931_new_call(struct pri *pri);
 
 extern int q931_setup(struct pri *pri, q931_call *c, struct pri_sr *req);
 

Modified: team/rmudgett/ect/q931.c
URL: http://svnview.digium.com/svn/libpri/team/rmudgett/ect/q931.c?view=diff&rev=1497&r1=1496&r2=1497
==============================================================================
--- team/rmudgett/ect/q931.c (original)
+++ team/rmudgett/ect/q931.c Mon Feb 15 14:50:52 2010
@@ -3597,7 +3597,8 @@
  *
  * \param ctrl D channel controller.
  * \param call Q.931 call leg.
- * 
+ * \param cr Call Reference identifier.
+ *
  * \note The call record is assumed to already be memset() to zero.
  *
  * \return Nothing
@@ -3647,6 +3648,49 @@
 	} else {
 		call->pri = ctrl;
 	}
+}
+
+/*!
+ * \brief Find a call in the active call pool.
+ *
+ * \param ctrl D channel controller.
+ * \param cr Call Reference identifier.
+ *
+ * \retval call if found.
+ * \retval NULL if not found.
+ */
+q931_call *q931_find_call(struct pri *ctrl, int cr)
+{
+	q931_call *cur;
+	struct pri *master;
+
+	if (cr == Q931_DUMMY_CALL_REFERENCE) {
+		return ctrl->dummy_call;
+	}
+
+	/* Find the master  - He has the call pool */
+	master = PRI_MASTER(ctrl);
+
+	for (cur = *master->callpool; cur; cur = cur->next) {
+		if (cur->cr == cr) {
+			/* Found existing call. */
+			switch (ctrl->switchtype) {
+			case PRI_SWITCH_GR303_EOC:
+			case PRI_SWITCH_GR303_EOC_PATH:
+			case PRI_SWITCH_GR303_TMC:
+			case PRI_SWITCH_GR303_TMC_SWITCHING:
+				break;
+			default:
+				if (!ctrl->bri) {
+					/* PRI is set to whoever called us */
+					cur->pri = ctrl;
+				}
+				break;
+			}
+			break;
+		}
+	}
+	return cur;
 }
 
 static q931_call *q931_getcall(struct pri *ctrl, int cr)




More information about the libpri-commits mailing list