[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