[libpri-commits] rmudgett: branch group/issue14068 r873 - /team/group/issue14068/
SVN commits to the libpri project
libpri-commits at lists.digium.com
Fri Jun 12 13:44:53 CDT 2009
Author: rmudgett
Date: Fri Jun 12 13:44:49 2009
New Revision: 873
URL: http://svn.asterisk.org/svn-view/libpri?view=rev&rev=873
Log:
ETSI COLP feature completed.
Modified:
team/group/issue14068/libpri.h
team/group/issue14068/pri.c
team/group/issue14068/pri_facility.c
team/group/issue14068/pri_facility.h
team/group/issue14068/pri_internal.h
team/group/issue14068/q931.c
Modified: team/group/issue14068/libpri.h
URL: http://svn.asterisk.org/svn-view/libpri/team/group/issue14068/libpri.h?view=diff&rev=873&r1=872&r2=873
==============================================================================
--- team/group/issue14068/libpri.h (original)
+++ team/group/issue14068/libpri.h Fri Jun 12 13:44:49 2009
@@ -298,8 +298,8 @@
#define PRI_RATE_ADAPT_ASYNC 0x40
/* Notifications */
-#define PRI_NOTIFY_USER_SUSPENDED 0x00 /* User suspended */
-#define PRI_NOTIFY_USER_RESUMED 0x01 /* User resumed */
+#define PRI_NOTIFY_USER_SUSPENDED 0x00 /* User suspended (Q.931) (Call is placed on hold) */
+#define PRI_NOTIFY_USER_RESUMED 0x01 /* User resumed (Q.931) (Call is taken off hold) */
#define PRI_NOTIFY_BEARER_CHANGE 0x02 /* Bearer service change (DSS1) */
#define PRI_NOTIFY_ASN1_COMPONENT 0x03 /* ASN.1 encoded component (DSS1) */
#define PRI_NOTIFY_COMPLETION_DELAY 0x04 /* Call completion delay */
@@ -314,12 +314,12 @@
#define PRI_NOTIFY_CONF_OTHER_DISCONNECTED 0x4a /* Other party disconnected */
#define PRI_NOTIFY_CONF_FLOATING 0x4b /* Conference floating */
#define PRI_NOTIFY_WAITING_CALL 0x60 /* Call is waiting call */
-#define PRI_NOTIFY_DIVERSION_ACTIVATED 0x68 /* Diversion activated (DSS1) */
-#define PRI_NOTIFY_TRANSFER_ALERTING 0x69 /* Call transfer, alerting */
-#define PRI_NOTIFY_TRANSFER_ACTIVE 0x6a /* Call transfer, active */
+#define PRI_NOTIFY_DIVERSION_ACTIVATED 0x68 /* Diversion activated (DSS1) (cfu, cfb, cfnr) (EN 300 207-1 Section 7.2.1) */
+#define PRI_NOTIFY_TRANSFER_ALERTING 0x69 /* Call transfer, alerting (EN 300 369-1 Section 7.2) */
+#define PRI_NOTIFY_TRANSFER_ACTIVE 0x6a /* Call transfer, active(answered) (EN 300 369-1 Section 7.2) */
#define PRI_NOTIFY_REMOTE_HOLD 0x79 /* Remote hold */
#define PRI_NOTIFY_REMOTE_RETRIEVAL 0x7a /* Remote retrieval */
-#define PRI_NOTIFY_CALL_DIVERTING 0x7b /* Call is diverting */
+#define PRI_NOTIFY_CALL_DIVERTING 0x7b /* Call is diverting (EN 300 207-1 Section 7.2.1) */
#define PRI_COPY_DIGITS_CALLED_NUMBER
Modified: team/group/issue14068/pri.c
URL: http://svn.asterisk.org/svn-view/libpri/team/group/issue14068/pri.c?view=diff&rev=873&r1=872&r2=873
==============================================================================
--- team/group/issue14068/pri.c (original)
+++ team/group/issue14068/pri.c Fri Jun 12 13:44:49 2009
@@ -643,27 +643,39 @@
}
call->local_id = party_id;
- switch (ctrl->switchtype) {
- case PRI_SWITCH_QSIG:
- switch (call->ourcallstate) {
- case Q931_CALL_STATE_CALL_INITIATED:
- case Q931_CALL_STATE_OVERLAP_SENDING:
- case Q931_CALL_STATE_OUTGOING_CALL_PROCEEDING:
- case Q931_CALL_STATE_CALL_DELIVERED:
- /*
- * The local party transferred to someone else before
- * the remote end answered.
- */
- case Q931_CALL_STATE_ACTIVE:
+ switch (call->ourcallstate) {
+ case Q931_CALL_STATE_CALL_INITIATED:
+ case Q931_CALL_STATE_OVERLAP_SENDING:
+ case Q931_CALL_STATE_OUTGOING_CALL_PROCEEDING:
+ case Q931_CALL_STATE_CALL_DELIVERED:
+ /*
+ * The local party transferred to someone else before
+ * the remote end answered.
+ */
+ case Q931_CALL_STATE_ACTIVE:
+ switch (ctrl->switchtype) {
+ case PRI_SWITCH_EUROISDN_E1:
+ case PRI_SWITCH_EUROISDN_T1:
+ if (q931_is_ptmp(ctrl)) {
+ /* PTMP mode */
+ q931_notify_redirection(ctrl, call, PRI_NOTIFY_TRANSFER_ACTIVE,
+ &call->local_id.number);
+ } else {
+ /* PTP mode */
+ /* Immediately send EctInform APDU, callStatus=answered(0) */
+ send_call_transfer_complete(ctrl, call, 0);
+ }
+ break;
+ case PRI_SWITCH_QSIG:
/* Immediately send CallTransferComplete APDU, callStatus=answered(0) */
- qsig_initiate_call_transfer_complete(ctrl, call, 0);
+ send_call_transfer_complete(ctrl, call, 0);
break;
default:
- /* Just save the data for further developments. */
break;
}
break;
default:
+ /* Just save the data for further developments. */
break;
}
@@ -688,6 +700,10 @@
call->redirecting.orig_reason = redirecting->orig_reason;
if (redirecting->count <= 0) {
if (call->redirecting.from.number.valid) {
+ /*
+ * We are redirecting with an unknown count
+ * so assume the count is one.
+ */
call->redirecting.count = 1;
} else {
call->redirecting.count = 0;
@@ -708,6 +724,16 @@
}
switch (ctrl->switchtype) {
+ case PRI_SWITCH_EUROISDN_E1:
+ case PRI_SWITCH_EUROISDN_T1:
+ if (q931_is_ptmp(ctrl)) {
+ /* PTMP mode */
+ q931_notify_redirection(ctrl, call, PRI_NOTIFY_CALL_DIVERTING,
+ &call->redirecting.to.number);
+ break;
+ }
+ /* PTP mode - same behaviour as Q.SIG */
+ /* fall through */
case PRI_SWITCH_QSIG:
if (call->redirecting.state != Q931_REDIRECTING_STATE_PENDING_TX_DIV_LEG_3
|| strcmp(call->redirecting.to.number.str, call->called_number.str) != 0) {
Modified: team/group/issue14068/pri_facility.c
URL: http://svn.asterisk.org/svn-view/libpri/team/group/issue14068/pri_facility.c?view=diff&rev=873&r1=872&r2=873
==============================================================================
--- team/group/issue14068/pri_facility.c (original)
+++ team/group/issue14068/pri_facility.c Fri Jun 12 13:44:49 2009
@@ -791,6 +791,49 @@
/*!
* \internal
+ * \brief Encode the ETSI DivertingLegInformation1 invoke 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 call Call leg from which to encode diversion leg 1.
+ *
+ * \retval Start of the next ASN.1 component to encode on success.
+ * \retval NULL on error.
+ */
+static unsigned char *enc_etsi_diverting_leg_information1(struct pri *ctrl,
+ unsigned char *pos, unsigned char *end, q931_call *call)
+{
+ struct rose_msg_invoke msg;
+
+ pos = facility_encode_header(ctrl, pos, end, NULL);
+ if (!pos) {
+ return NULL;
+ }
+
+ memset(&msg, 0, sizeof(msg));
+ msg.operation = ROSE_ETSI_DivertingLegInformation1;
+ msg.invoke_id = get_invokeid(ctrl);
+ msg.args.etsi.DivertingLegInformation1.diversion_reason =
+ redirectingreason_from_q931(ctrl, call->redirecting.reason);
+
+ if (call->redirecting.to.number.valid) {
+ msg.args.etsi.DivertingLegInformation1.subscription_option = 2;
+
+ /* divertedToNumber is the redirecting.to.number */
+ msg.args.etsi.DivertingLegInformation1.diverted_to_present = 1;
+ q931_copy_presented_number_unscreened_to_rose(ctrl,
+ &msg.args.etsi.DivertingLegInformation1.diverted_to,
+ &call->redirecting.to.number);
+ } else {
+ msg.args.etsi.DivertingLegInformation1.subscription_option = 1;
+ }
+ pos = rose_encode_invoke(ctrl, pos, end, &msg);
+
+ return pos;
+}
+
+/*!
* \brief Encode and queue the DivertingLegInformation1 invoke message.
*
* \param ctrl D channel controller for diagnostic messages or global options.
@@ -805,6 +848,11 @@
unsigned char *end;
switch (ctrl->switchtype) {
+ case PRI_SWITCH_EUROISDN_E1:
+ case PRI_SWITCH_EUROISDN_T1:
+ end = enc_etsi_diverting_leg_information1(ctrl, buffer, buffer + sizeof(buffer),
+ call);
+ break;
case PRI_SWITCH_QSIG:
end = enc_qsig_diverting_leg_information1(ctrl, buffer, buffer + sizeof(buffer),
call);
@@ -904,6 +952,57 @@
/*!
* \internal
+ * \brief Encode the ETSI DivertingLegInformation2 invoke 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 call Call leg from which to encode diversion leg 2.
+ *
+ * \retval Start of the next ASN.1 component to encode on success.
+ * \retval NULL on error.
+ */
+static unsigned char *enc_etsi_diverting_leg_information2(struct pri *ctrl,
+ unsigned char *pos, unsigned char *end, q931_call *call)
+{
+ struct rose_msg_invoke msg;
+
+ pos = facility_encode_header(ctrl, pos, end, NULL);
+ if (!pos) {
+ return NULL;
+ }
+
+ memset(&msg, 0, sizeof(msg));
+ msg.operation = ROSE_ETSI_DivertingLegInformation2;
+ msg.invoke_id = get_invokeid(ctrl);
+
+ /* diversionCounter is the redirecting.count */
+ msg.args.etsi.DivertingLegInformation2.diversion_counter = call->redirecting.count;
+
+ msg.args.etsi.DivertingLegInformation2.diversion_reason =
+ redirectingreason_from_q931(ctrl, call->redirecting.reason);
+
+ /* divertingNr is the redirecting.from.number */
+ msg.args.etsi.DivertingLegInformation2.diverting_present = 1;
+ q931_copy_presented_number_unscreened_to_rose(ctrl,
+ &msg.args.etsi.DivertingLegInformation2.diverting,
+ &call->redirecting.from.number);
+
+ if (1 < call->redirecting.count) {
+ /* originalCalledNr is the redirecting.orig_called.number */
+ msg.args.etsi.DivertingLegInformation2.original_called_present = 1;
+ q931_copy_presented_number_unscreened_to_rose(ctrl,
+ &msg.args.etsi.DivertingLegInformation2.original_called,
+ &call->redirecting.orig_called.number);
+ }
+
+ pos = rose_encode_invoke(ctrl, pos, end, &msg);
+
+ return pos;
+}
+
+/*!
+ * \internal
* \brief Encode and queue the DivertingLegInformation2 invoke message.
*
* \param ctrl D channel controller for diagnostic messages or global options.
@@ -918,6 +1017,11 @@
unsigned char *end;
switch (ctrl->switchtype) {
+ case PRI_SWITCH_EUROISDN_E1:
+ case PRI_SWITCH_EUROISDN_T1:
+ end = enc_etsi_diverting_leg_information2(ctrl, buffer, buffer + sizeof(buffer),
+ call);
+ break;
case PRI_SWITCH_QSIG:
end = enc_qsig_diverting_leg_information2(ctrl, buffer, buffer + sizeof(buffer),
call);
@@ -984,6 +1088,41 @@
}
/*!
+ * \internal
+ * \brief Encode the ETSI DivertingLegInformation3 invoke 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 call Call leg from which to encode diversion leg 3.
+ *
+ * \retval Start of the next ASN.1 component to encode on success.
+ * \retval NULL on error.
+ */
+static unsigned char *enc_etsi_diverting_leg_information3(struct pri *ctrl,
+ unsigned char *pos, unsigned char *end, q931_call *call)
+{
+ struct rose_msg_invoke msg;
+
+ pos = facility_encode_header(ctrl, pos, end, NULL);
+ if (!pos) {
+ return NULL;
+ }
+
+ memset(&msg, 0, sizeof(msg));
+ msg.operation = ROSE_ETSI_DivertingLegInformation3;
+ msg.invoke_id = get_invokeid(ctrl);
+
+ if ((call->redirecting.to.number.presentation & PRI_PRES_RESTRICTION) == PRI_PRES_ALLOWED) {
+ msg.args.etsi.DivertingLegInformation3.presentation_allowed_indicator = 1; /* TRUE */
+ }
+
+ pos = rose_encode_invoke(ctrl, pos, end, &msg);
+
+ return pos;
+}
+
+/*!
* \brief Encode and queue the DivertingLegInformation3 invoke message.
*
* \param ctrl D channel controller for diagnostic messages or global options.
@@ -1000,6 +1139,11 @@
unsigned char *end;
switch (ctrl->switchtype) {
+ case PRI_SWITCH_EUROISDN_E1:
+ case PRI_SWITCH_EUROISDN_T1:
+ end = enc_etsi_diverting_leg_information3(ctrl, buffer, buffer + sizeof(buffer),
+ call);
+ break;
case PRI_SWITCH_QSIG:
end = enc_qsig_diverting_leg_information3(ctrl, buffer, buffer + sizeof(buffer),
call);
@@ -1914,7 +2058,51 @@
/*!
* \internal
- * \brief Encode and queue the Q.SIG CallTransferComplete invoke message.
+ * \brief Encode the ETSI EctInform invoke 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 call Call leg from which to encode inform message.
+ * \param call_status TRUE if call is alerting.
+ *
+ * \retval Start of the next ASN.1 component to encode on success.
+ * \retval NULL on error.
+ */
+static unsigned char *enc_etsi_ect_inform(struct pri *ctrl, unsigned char *pos,
+ unsigned char *end, q931_call *call, int call_status)
+{
+ struct rose_msg_invoke msg;
+
+ pos = facility_encode_header(ctrl, pos, end, NULL);
+ if (!pos) {
+ return NULL;
+ }
+
+ memset(&msg, 0, sizeof(msg));
+ msg.operation = ROSE_ETSI_EctInform;
+ msg.invoke_id = get_invokeid(ctrl);
+
+ if (!call_status) {
+ msg.args.etsi.EctInform.status = 1;/* active */
+
+ /*
+ * EctInform(active) contains the redirectionNumber
+ * redirectionNumber is the local_id.number
+ */
+ msg.args.etsi.EctInform.redirection_present = 1;
+ q931_copy_presented_number_unscreened_to_rose(ctrl,
+ &msg.args.etsi.EctInform.redirection, &call->local_id.number);
+ }
+
+ pos = rose_encode_invoke(ctrl, pos, end, &msg);
+
+ return pos;
+}
+
+/*!
+ * \internal
+ * \brief Encode and queue the CallTransferComplete/EctInform invoke message.
*
* \param ctrl D channel controller for diagnostic messages or global options.
* \param call Call leg from which to encode call transfer.
@@ -1930,6 +2118,11 @@
unsigned char *end;
switch (ctrl->switchtype) {
+ case PRI_SWITCH_EUROISDN_E1:
+ case PRI_SWITCH_EUROISDN_T1:
+ end =
+ enc_etsi_ect_inform(ctrl, buffer, buffer + sizeof(buffer), call, call_status);
+ break;
case PRI_SWITCH_QSIG:
end =
enc_qsig_call_transfer_complete(ctrl, buffer, buffer + sizeof(buffer), call,
@@ -2150,8 +2343,13 @@
}
switch (ctrl->switchtype) {
- case PRI_SWITCH_QSIG:
- /* For Q.SIG it does network and cpe operations */
+ case PRI_SWITCH_EUROISDN_E1:
+ case PRI_SWITCH_EUROISDN_T1:
+ if (q931_is_ptmp(ctrl)) {
+ /* PTMP mode */
+ break;
+ }
+ /* PTP mode */
if (call->redirecting.count) {
rose_diverting_leg_information2_encode(ctrl, call);
@@ -2161,6 +2359,18 @@
*/
call->redirecting.state = Q931_REDIRECTING_STATE_EXPECTING_RX_DIV_LEG_3;
}
+ break;
+ case PRI_SWITCH_QSIG:
+ /* For Q.SIG it does network and cpe operations */
+ if (call->redirecting.count) {
+ rose_diverting_leg_information2_encode(ctrl, call);
+
+ /*
+ * Expect a DivertingLegInformation3 to update the COLR of the
+ * redirecting-to party we are attempting to call now.
+ */
+ call->redirecting.state = Q931_REDIRECTING_STATE_EXPECTING_RX_DIV_LEG_3;
+ }
add_callername_facility_ies(ctrl, call, 1);
break;
case PRI_SWITCH_NI2:
@@ -2178,24 +2388,22 @@
return 0;
}
-int qsig_initiate_diverting_leg_information1(struct pri *ctrl, q931_call *call)
-{
- if (rose_diverting_leg_information1_encode(ctrl, call)
- || q931_facility(ctrl, call)) {
- pri_message(ctrl, "Could not schedule facility message for divertingLegInfo1\n");
- return -1;
- }
-
- return 0;
-}
-
-int qsig_initiate_call_transfer_complete(struct pri *ctrl, q931_call *call,
- int call_status)
+/*!
+ * \brief Send the CallTransferComplete/EctInform invoke message.
+ *
+ * \param ctrl D channel controller for diagnostic messages or global options.
+ * \param call Call leg from which to encode call transfer.
+ * \param call_status TRUE if call is alerting.
+ *
+ * \retval 0 on success.
+ * \retval -1 on error.
+ */
+int send_call_transfer_complete(struct pri *ctrl, q931_call *call, int call_status)
{
if (rose_call_transfer_complete_encode(ctrl, call, call_status)
|| q931_facility(ctrl, call)) {
pri_message(ctrl,
- "Could not schedule facility message for callTransferComplete\n");
+ "Could not schedule facility message for call transfer completed.\n");
return -1;
}
@@ -2428,297 +2636,73 @@
break;
case ROSE_ETSI_InterrogateServedUserNumbers:
break;
+#endif /* Not handled yet */
case ROSE_ETSI_DivertingLegInformation1:
- break;
- case ROSE_ETSI_DivertingLegInformation2:
- break;
- case ROSE_ETSI_DivertingLegInformation3:
- break;
-#endif /* Not handled yet */
- case ROSE_ETSI_ChargingRequest:
- /* Ignore messsage */
- break;
-#if 0 /* Not handled yet */
- case ROSE_ETSI_AOCSCurrency:
- break;
- case ROSE_ETSI_AOCSSpecialArr:
- break;
- case ROSE_ETSI_AOCDCurrency:
- break;
- case ROSE_ETSI_AOCDChargingUnit:
- break;
- case ROSE_ETSI_AOCECurrency:
- break;
-#endif /* Not handled yet */
- case ROSE_ETSI_AOCEChargingUnit:
- call->aoc_units = 0;
- if (invoke->args.etsi.AOCEChargingUnit.type == 1
- && !invoke->args.etsi.AOCEChargingUnit.charging_unit.free_of_charge) {
- unsigned index;
-
- for (index =
- invoke->args.etsi.AOCEChargingUnit.charging_unit.specific.recorded.
- num_records; index--;) {
- if (!invoke->args.etsi.AOCEChargingUnit.charging_unit.specific.recorded.
- list[index].not_available) {
- call->aoc_units +=
- invoke->args.etsi.AOCEChargingUnit.charging_unit.specific.
- recorded.list[index].number_of_units;
- }
- }
- }
- /* the following function is currently not used - just to make the compiler happy */
- if (0) {
- /* use this function to forward the aoc-e on a bridged channel */
- aoc_aoce_charging_unit_encode(ctrl, call, call->aoc_units);
- }
- break;
-#if 0 /* Not handled yet */
- case ROSE_ITU_IdentificationOfCharge:
- break;
-#endif /* Not handled yet */
-#if 0 /* Not handled yet */
- case ROSE_ETSI_EctExecute:
- break;
- case ROSE_ETSI_ExplicitEctExecute:
- break;
- case ROSE_ETSI_RequestSubaddress:
- break;
- case ROSE_ETSI_SubaddressTransfer:
- break;
- case ROSE_ETSI_EctLinkIdRequest:
- break;
- case ROSE_ETSI_EctInform:
- break;
- case ROSE_ETSI_EctLoopTest:
- break;
-#endif /* Not handled yet */
- case ROSE_QSIG_CallingName:
- /* CallingName is put in remote_id.name */
- rose_copy_name_to_q931(ctrl, &call->remote_id.name,
- &invoke->args.qsig.CallingName.name);
- break;
- case ROSE_QSIG_CalledName:
- /* CalledName is put in remote_id.name */
- rose_copy_name_to_q931(ctrl, &call->remote_id.name,
- &invoke->args.qsig.CalledName.name);
-
- /* Setup connected line subcommand */
- subcmd = q931_alloc_subcommand(ctrl);
- if (!subcmd) {
- pri_error(ctrl, "ERROR: Too many facility subcommands\n");
- break;
- }
- subcmd->cmd = PRI_SUBCMD_CONNECTED_LINE;
- q931_party_id_copy_to_pri(&subcmd->u.connected_line.id, &call->remote_id);
- break;
- case ROSE_QSIG_ConnectedName:
- /* ConnectedName is put in remote_id.name */
- rose_copy_name_to_q931(ctrl, &call->remote_id.name,
- &invoke->args.qsig.ConnectedName.name);
- break;
-#if 0 /* Not handled yet */
- case ROSE_QSIG_BusyName:
- break;
-#endif /* Not handled yet */
-#if 0 /* Not handled yet */
- case ROSE_QSIG_ChargeRequest:
- break;
- case ROSE_QSIG_GetFinalCharge:
- break;
- case ROSE_QSIG_AocFinal:
- break;
- case ROSE_QSIG_AocInterim:
- break;
- case ROSE_QSIG_AocRate:
- break;
- case ROSE_QSIG_AocComplete:
- break;
- case ROSE_QSIG_AocDivChargeReq:
- break;
-#endif /* Not handled yet */
-#if 0 /* Not handled yet */
- case ROSE_QSIG_CallTransferIdentify:
- break;
- case ROSE_QSIG_CallTransferAbandon:
- break;
- case ROSE_QSIG_CallTransferInitiate:
- break;
- case ROSE_QSIG_CallTransferSetup:
- break;
-#endif /* Not handled yet */
- case ROSE_QSIG_CallTransferActive:
- call->incoming_ct_state = INCOMING_CT_STATE_POST_CONNECTED_LINE;
-
- /* connectedAddress is put in remote_id.number */
- rose_copy_presented_address_screened_to_q931(ctrl, &call->remote_id.number,
- &invoke->args.qsig.CallTransferActive.connected);
-
- /* connectedName is put in remote_id.name */
- if (invoke->args.qsig.CallTransferActive.connected_name_present) {
- rose_copy_name_to_q931(ctrl, &call->remote_id.name,
- &invoke->args.qsig.CallTransferActive.connected_name);
- }
- break;
- case ROSE_QSIG_CallTransferComplete:
- /* redirectionNumber is put in remote_id.number */
- rose_copy_presented_number_screened_to_q931(ctrl, &call->remote_id.number,
- &invoke->args.qsig.CallTransferComplete.redirection);
-
- /* redirectionName is put in remote_id.name */
- if (invoke->args.qsig.CallTransferComplete.redirection_name_present) {
- rose_copy_name_to_q931(ctrl, &call->remote_id.name,
- &invoke->args.qsig.CallTransferComplete.redirection_name);
- }
-
- if (invoke->args.qsig.CallTransferComplete.call_status == 1) {
- /* The remote party for the transfer has not answered yet. */
- call->incoming_ct_state = INCOMING_CT_STATE_EXPECT_CT_ACTIVE;
- } else {
- call->incoming_ct_state = INCOMING_CT_STATE_POST_CONNECTED_LINE;
- }
- break;
- case ROSE_QSIG_CallTransferUpdate:
- party_id = call->remote_id;
-
- /* redirectionNumber is put in party_id.number */
- rose_copy_presented_number_screened_to_q931(ctrl, &party_id.number,
- &invoke->args.qsig.CallTransferUpdate.redirection);
-
- /* redirectionName is put in party_id.name */
- if (invoke->args.qsig.CallTransferUpdate.redirection_name_present) {
- rose_copy_name_to_q931(ctrl, &party_id.name,
- &invoke->args.qsig.CallTransferUpdate.redirection_name);
- }
-
- if (q931_party_id_cmp(&party_id, &call->remote_id)) {
- /* The remote_id data has changed. */
- call->remote_id = party_id;
- switch (call->incoming_ct_state) {
- case INCOMING_CT_STATE_IDLE:
- call->incoming_ct_state = INCOMING_CT_STATE_POST_CONNECTED_LINE;
- break;
- default:
- break;
- }
- }
- break;
-#if 0 /* Not handled yet */
- case ROSE_QSIG_SubaddressTransfer:
- break;
-#endif /* Not handled yet */
- case ROSE_QSIG_PathReplacement:
- anfpr_pathreplacement_respond(ctrl, call, ie);
- break;
-#if 0 /* Not handled yet */
- case ROSE_QSIG_ActivateDiversionQ:
- break;
- case ROSE_QSIG_DeactivateDiversionQ:
- break;
- case ROSE_QSIG_InterrogateDiversionQ:
- break;
- case ROSE_QSIG_CheckRestriction:
- break;
- case ROSE_QSIG_CallRerouting:
- break;
-#endif /* Not handled yet */
- case ROSE_QSIG_DivertingLegInformation1:
- /* nominatedNr is put in redirecting.to.number */
- switch (invoke->args.qsig.DivertingLegInformation1.subscription_option) {
+ /* divertedToNumber is put in redirecting.to.number */
+ switch (invoke->args.etsi.DivertingLegInformation1.subscription_option) {
default:
- case QSIG_NO_NOTIFICATION:
- case QSIG_NOTIFICATION_WITHOUT_DIVERTED_TO_NR:
+ case 0: /* noNotification */
+ case 1: /* notificationWithoutDivertedToNr */
q931_party_number_init(&call->redirecting.to.number);
call->redirecting.to.number.valid = 1;
call->redirecting.to.number.presentation =
PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_UNSCREENED;
break;
- case QSIG_NOTIFICATION_WITH_DIVERTED_TO_NR:
- q931_party_number_init(&call->redirecting.to.number);
- call->redirecting.to.number.valid = 1;
- rose_copy_number_to_q931(ctrl, &call->redirecting.to.number,
- &invoke->args.qsig.DivertingLegInformation1.nominated_number);
- if (call->redirecting.to.number.str[0]) {
- call->redirecting.to.number.presentation =
- PRI_PRES_ALLOWED | PRI_PRES_USER_NUMBER_UNSCREENED;
+ case 2: /* notificationWithDivertedToNr */
+ if (invoke->args.etsi.DivertingLegInformation1.diverted_to_present) {
+ rose_copy_presented_number_unscreened_to_q931(ctrl,
+ &call->redirecting.to.number,
+ &invoke->args.etsi.DivertingLegInformation1.diverted_to);
+ } else {
+ q931_party_number_init(&call->redirecting.to.number);
+ call->redirecting.to.number.valid = 1;
}
break;
}
call->redirecting.reason = redirectingreason_for_q931(ctrl,
- invoke->args.qsig.DivertingLegInformation1.diversion_reason);
+ invoke->args.etsi.DivertingLegInformation1.diversion_reason);
if (call->redirecting.count < PRI_MAX_REDIRECTS) {
++call->redirecting.count;
}
call->redirecting.state = Q931_REDIRECTING_STATE_EXPECTING_RX_DIV_LEG_3;
break;
- case ROSE_QSIG_DivertingLegInformation2:
+ case ROSE_ETSI_DivertingLegInformation2:
call->redirecting.state = Q931_REDIRECTING_STATE_PENDING_TX_DIV_LEG_3;
call->redirecting.count =
- invoke->args.qsig.DivertingLegInformation2.diversion_counter;
+ invoke->args.etsi.DivertingLegInformation2.diversion_counter;
if (!call->redirecting.count) {
/* To be safe, make sure that the count is non-zero. */
call->redirecting.count = 1;
}
call->redirecting.reason = redirectingreason_for_q931(ctrl,
- invoke->args.qsig.DivertingLegInformation2.diversion_reason);
+ invoke->args.etsi.DivertingLegInformation2.diversion_reason);
/* divertingNr is put in redirecting.from.number */
- if (invoke->args.qsig.DivertingLegInformation2.diverting_present) {
+ if (invoke->args.etsi.DivertingLegInformation2.diverting_present) {
rose_copy_presented_number_unscreened_to_q931(ctrl,
&call->redirecting.from.number,
- &invoke->args.qsig.DivertingLegInformation2.diverting);
+ &invoke->args.etsi.DivertingLegInformation2.diverting);
} else {
q931_party_number_init(&call->redirecting.from.number);
call->redirecting.from.number.valid = 1;
}
- /* redirectingName is put in redirecting.from.name */
- if (invoke->args.qsig.DivertingLegInformation2.redirecting_name_present) {
- rose_copy_name_to_q931(ctrl, &call->redirecting.from.name,
- &invoke->args.qsig.DivertingLegInformation2.redirecting_name);
- } else {
- q931_party_name_init(&call->redirecting.from.name);
- }
-
call->redirecting.orig_reason = PRI_REDIR_UNKNOWN;
- if (invoke->args.qsig.DivertingLegInformation2.original_diversion_reason_present) {
- call->redirecting.orig_reason = redirectingreason_for_q931(ctrl,
- invoke->args.qsig.DivertingLegInformation2.original_diversion_reason);
- }
/* originalCalledNr is put in redirecting.orig_called.number */
- if (invoke->args.qsig.DivertingLegInformation2.original_called_present) {
+ if (invoke->args.etsi.DivertingLegInformation2.original_called_present) {
rose_copy_presented_number_unscreened_to_q931(ctrl,
&call->redirecting.orig_called.number,
- &invoke->args.qsig.DivertingLegInformation2.original_called);
+ &invoke->args.etsi.DivertingLegInformation2.original_called);
} else {
q931_party_number_init(&call->redirecting.orig_called.number);
}
-
- /* originalCalledName is put in redirecting.orig_called.name */
- if (invoke->args.qsig.DivertingLegInformation2.original_called_name_present) {
- rose_copy_name_to_q931(ctrl, &call->redirecting.orig_called.name,
- &invoke->args.qsig.DivertingLegInformation2.original_called_name);
- } else {
- q931_party_name_init(&call->redirecting.orig_called.name);
- }
- break;
- case ROSE_QSIG_DivertingLegInformation3:
- if (!invoke->args.qsig.DivertingLegInformation3.presentation_allowed_indicator) {
+ break;
+ case ROSE_ETSI_DivertingLegInformation3:
+ if (!invoke->args.etsi.DivertingLegInformation3.presentation_allowed_indicator) {
call->redirecting.to.number.presentation =
PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_UNSCREENED;
- }
-
- /* redirectionName is put in redirecting.to.name */
- if (invoke->args.qsig.DivertingLegInformation3.redirection_name_present) {
- rose_copy_name_to_q931(ctrl, &call->redirecting.to.name,
- &invoke->args.qsig.DivertingLegInformation3.redirection_name);
- if (!invoke->args.qsig.DivertingLegInformation3.presentation_allowed_indicator) {
- call->redirecting.to.name.presentation = PRI_PRES_RESTRICTED;
- }
- } else {
- q931_party_name_init(&call->redirecting.to.name);
}
switch (call->redirecting.state) {
@@ -2738,6 +2722,325 @@
break;
}
break;
+ case ROSE_ETSI_ChargingRequest:
+ /* Ignore messsage */
+ break;
+#if 0 /* Not handled yet */
+ case ROSE_ETSI_AOCSCurrency:
+ break;
+ case ROSE_ETSI_AOCSSpecialArr:
+ break;
+ case ROSE_ETSI_AOCDCurrency:
+ break;
+ case ROSE_ETSI_AOCDChargingUnit:
+ break;
+ case ROSE_ETSI_AOCECurrency:
+ break;
+#endif /* Not handled yet */
+ case ROSE_ETSI_AOCEChargingUnit:
+ call->aoc_units = 0;
+ if (invoke->args.etsi.AOCEChargingUnit.type == 1
+ && !invoke->args.etsi.AOCEChargingUnit.charging_unit.free_of_charge) {
+ unsigned index;
+
+ for (index =
+ invoke->args.etsi.AOCEChargingUnit.charging_unit.specific.recorded.
+ num_records; index--;) {
+ if (!invoke->args.etsi.AOCEChargingUnit.charging_unit.specific.recorded.
+ list[index].not_available) {
+ call->aoc_units +=
+ invoke->args.etsi.AOCEChargingUnit.charging_unit.specific.
+ recorded.list[index].number_of_units;
+ }
+ }
+ }
+ /* the following function is currently not used - just to make the compiler happy */
+ if (0) {
+ /* use this function to forward the aoc-e on a bridged channel */
+ aoc_aoce_charging_unit_encode(ctrl, call, call->aoc_units);
+ }
+ break;
+#if 0 /* Not handled yet */
+ case ROSE_ITU_IdentificationOfCharge:
+ break;
+#endif /* Not handled yet */
+#if 0 /* Not handled yet */
+ case ROSE_ETSI_EctExecute:
+ break;
+ case ROSE_ETSI_ExplicitEctExecute:
+ break;
+#endif /* Not handled yet */
+ case ROSE_ETSI_RequestSubaddress:
+ /* Ignore since we are not handling subaddresses yet. */
+ break;
+#if 0 /* Not handled yet */
+ case ROSE_ETSI_SubaddressTransfer:
+ break;
+ case ROSE_ETSI_EctLinkIdRequest:
+ break;
+#endif /* Not handled yet */
+ case ROSE_ETSI_EctInform:
+ /* redirectionNumber is put in remote_id.number */
+ if (invoke->args.etsi.EctInform.redirection_present) {
+ rose_copy_presented_number_unscreened_to_q931(ctrl,
+ &call->remote_id.number, &invoke->args.etsi.EctInform.redirection);
+ }
+ if (!invoke->args.etsi.EctInform.status) {
+ /* The remote party for the transfer has not answered yet. */
+ call->incoming_ct_state = INCOMING_CT_STATE_EXPECT_CT_ACTIVE;
+ } else {
+ call->incoming_ct_state = INCOMING_CT_STATE_POST_CONNECTED_LINE;
+ }
+ break;
+#if 0 /* Not handled yet */
+ case ROSE_ETSI_EctLoopTest:
+ break;
+#endif /* Not handled yet */
+ case ROSE_QSIG_CallingName:
+ /* CallingName is put in remote_id.name */
+ rose_copy_name_to_q931(ctrl, &call->remote_id.name,
+ &invoke->args.qsig.CallingName.name);
+ break;
+ case ROSE_QSIG_CalledName:
+ /* CalledName is put in remote_id.name */
+ rose_copy_name_to_q931(ctrl, &call->remote_id.name,
+ &invoke->args.qsig.CalledName.name);
+
+ /* Setup connected line subcommand */
+ subcmd = q931_alloc_subcommand(ctrl);
+ if (!subcmd) {
+ pri_error(ctrl, "ERROR: Too many facility subcommands\n");
+ break;
+ }
+ subcmd->cmd = PRI_SUBCMD_CONNECTED_LINE;
+ q931_party_id_copy_to_pri(&subcmd->u.connected_line.id, &call->remote_id);
+ break;
+ case ROSE_QSIG_ConnectedName:
+ /* ConnectedName is put in remote_id.name */
+ rose_copy_name_to_q931(ctrl, &call->remote_id.name,
+ &invoke->args.qsig.ConnectedName.name);
+ break;
+#if 0 /* Not handled yet */
+ case ROSE_QSIG_BusyName:
+ break;
+#endif /* Not handled yet */
+#if 0 /* Not handled yet */
+ case ROSE_QSIG_ChargeRequest:
+ break;
+ case ROSE_QSIG_GetFinalCharge:
+ break;
+ case ROSE_QSIG_AocFinal:
+ break;
+ case ROSE_QSIG_AocInterim:
+ break;
+ case ROSE_QSIG_AocRate:
+ break;
+ case ROSE_QSIG_AocComplete:
+ break;
+ case ROSE_QSIG_AocDivChargeReq:
+ break;
+#endif /* Not handled yet */
+#if 0 /* Not handled yet */
+ case ROSE_QSIG_CallTransferIdentify:
+ break;
+ case ROSE_QSIG_CallTransferAbandon:
+ break;
+ case ROSE_QSIG_CallTransferInitiate:
+ break;
+ case ROSE_QSIG_CallTransferSetup:
+ break;
+#endif /* Not handled yet */
+ case ROSE_QSIG_CallTransferActive:
+ call->incoming_ct_state = INCOMING_CT_STATE_POST_CONNECTED_LINE;
+
+ /* connectedAddress is put in remote_id.number */
+ rose_copy_presented_address_screened_to_q931(ctrl, &call->remote_id.number,
+ &invoke->args.qsig.CallTransferActive.connected);
+
+ /* connectedName is put in remote_id.name */
+ if (invoke->args.qsig.CallTransferActive.connected_name_present) {
+ rose_copy_name_to_q931(ctrl, &call->remote_id.name,
+ &invoke->args.qsig.CallTransferActive.connected_name);
+ }
+ break;
+ case ROSE_QSIG_CallTransferComplete:
+ /* redirectionNumber is put in remote_id.number */
+ rose_copy_presented_number_screened_to_q931(ctrl, &call->remote_id.number,
+ &invoke->args.qsig.CallTransferComplete.redirection);
+
+ /* redirectionName is put in remote_id.name */
+ if (invoke->args.qsig.CallTransferComplete.redirection_name_present) {
+ rose_copy_name_to_q931(ctrl, &call->remote_id.name,
+ &invoke->args.qsig.CallTransferComplete.redirection_name);
+ }
+
+ if (invoke->args.qsig.CallTransferComplete.call_status == 1) {
+ /* The remote party for the transfer has not answered yet. */
+ call->incoming_ct_state = INCOMING_CT_STATE_EXPECT_CT_ACTIVE;
+ } else {
+ call->incoming_ct_state = INCOMING_CT_STATE_POST_CONNECTED_LINE;
+ }
+ break;
+ case ROSE_QSIG_CallTransferUpdate:
+ party_id = call->remote_id;
+
+ /* redirectionNumber is put in party_id.number */
+ rose_copy_presented_number_screened_to_q931(ctrl, &party_id.number,
+ &invoke->args.qsig.CallTransferUpdate.redirection);
+
+ /* redirectionName is put in party_id.name */
+ if (invoke->args.qsig.CallTransferUpdate.redirection_name_present) {
+ rose_copy_name_to_q931(ctrl, &party_id.name,
+ &invoke->args.qsig.CallTransferUpdate.redirection_name);
+ }
+
+ if (q931_party_id_cmp(&party_id, &call->remote_id)) {
+ /* The remote_id data has changed. */
+ call->remote_id = party_id;
+ switch (call->incoming_ct_state) {
+ case INCOMING_CT_STATE_IDLE:
+ call->incoming_ct_state = INCOMING_CT_STATE_POST_CONNECTED_LINE;
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+#if 0 /* Not handled yet */
+ case ROSE_QSIG_SubaddressTransfer:
+ break;
+#endif /* Not handled yet */
+ case ROSE_QSIG_PathReplacement:
+ anfpr_pathreplacement_respond(ctrl, call, ie);
+ break;
+#if 0 /* Not handled yet */
+ case ROSE_QSIG_ActivateDiversionQ:
+ break;
+ case ROSE_QSIG_DeactivateDiversionQ:
+ break;
+ case ROSE_QSIG_InterrogateDiversionQ:
+ break;
+ case ROSE_QSIG_CheckRestriction:
+ break;
+ case ROSE_QSIG_CallRerouting:
+ break;
+#endif /* Not handled yet */
+ case ROSE_QSIG_DivertingLegInformation1:
+ /* nominatedNr is put in redirecting.to.number */
+ switch (invoke->args.qsig.DivertingLegInformation1.subscription_option) {
+ default:
+ case QSIG_NO_NOTIFICATION:
+ case QSIG_NOTIFICATION_WITHOUT_DIVERTED_TO_NR:
+ q931_party_number_init(&call->redirecting.to.number);
+ call->redirecting.to.number.valid = 1;
+ call->redirecting.to.number.presentation =
+ PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_UNSCREENED;
+ break;
+ case QSIG_NOTIFICATION_WITH_DIVERTED_TO_NR:
+ q931_party_number_init(&call->redirecting.to.number);
+ call->redirecting.to.number.valid = 1;
+ rose_copy_number_to_q931(ctrl, &call->redirecting.to.number,
+ &invoke->args.qsig.DivertingLegInformation1.nominated_number);
+ if (call->redirecting.to.number.str[0]) {
+ call->redirecting.to.number.presentation =
+ PRI_PRES_ALLOWED | PRI_PRES_USER_NUMBER_UNSCREENED;
+ }
+ break;
+ }
+
+ call->redirecting.reason = redirectingreason_for_q931(ctrl,
+ invoke->args.qsig.DivertingLegInformation1.diversion_reason);
+ if (call->redirecting.count < PRI_MAX_REDIRECTS) {
+ ++call->redirecting.count;
+ }
+ call->redirecting.state = Q931_REDIRECTING_STATE_EXPECTING_RX_DIV_LEG_3;
+ break;
+ case ROSE_QSIG_DivertingLegInformation2:
+ call->redirecting.state = Q931_REDIRECTING_STATE_PENDING_TX_DIV_LEG_3;
+ call->redirecting.count =
+ invoke->args.qsig.DivertingLegInformation2.diversion_counter;
+ if (!call->redirecting.count) {
+ /* To be safe, make sure that the count is non-zero. */
+ call->redirecting.count = 1;
+ }
+ call->redirecting.reason = redirectingreason_for_q931(ctrl,
+ invoke->args.qsig.DivertingLegInformation2.diversion_reason);
+
+ /* divertingNr is put in redirecting.from.number */
+ if (invoke->args.qsig.DivertingLegInformation2.diverting_present) {
+ rose_copy_presented_number_unscreened_to_q931(ctrl,
+ &call->redirecting.from.number,
+ &invoke->args.qsig.DivertingLegInformation2.diverting);
+ } else {
+ q931_party_number_init(&call->redirecting.from.number);
+ call->redirecting.from.number.valid = 1;
+ }
+
+ /* redirectingName is put in redirecting.from.name */
+ if (invoke->args.qsig.DivertingLegInformation2.redirecting_name_present) {
+ rose_copy_name_to_q931(ctrl, &call->redirecting.from.name,
+ &invoke->args.qsig.DivertingLegInformation2.redirecting_name);
+ } else {
+ q931_party_name_init(&call->redirecting.from.name);
+ }
+
+ call->redirecting.orig_reason = PRI_REDIR_UNKNOWN;
+ if (invoke->args.qsig.DivertingLegInformation2.original_diversion_reason_present) {
+ call->redirecting.orig_reason = redirectingreason_for_q931(ctrl,
+ invoke->args.qsig.DivertingLegInformation2.original_diversion_reason);
+ }
+
+ /* originalCalledNr is put in redirecting.orig_called.number */
+ if (invoke->args.qsig.DivertingLegInformation2.original_called_present) {
+ rose_copy_presented_number_unscreened_to_q931(ctrl,
+ &call->redirecting.orig_called.number,
+ &invoke->args.qsig.DivertingLegInformation2.original_called);
+ } else {
+ q931_party_number_init(&call->redirecting.orig_called.number);
+ }
+
+ /* originalCalledName is put in redirecting.orig_called.name */
+ if (invoke->args.qsig.DivertingLegInformation2.original_called_name_present) {
+ rose_copy_name_to_q931(ctrl, &call->redirecting.orig_called.name,
+ &invoke->args.qsig.DivertingLegInformation2.original_called_name);
+ } else {
+ q931_party_name_init(&call->redirecting.orig_called.name);
+ }
+ break;
+ case ROSE_QSIG_DivertingLegInformation3:
+ if (!invoke->args.qsig.DivertingLegInformation3.presentation_allowed_indicator) {
+ call->redirecting.to.number.presentation =
+ PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_UNSCREENED;
+ }
+
+ /* redirectionName is put in redirecting.to.name */
+ if (invoke->args.qsig.DivertingLegInformation3.redirection_name_present) {
+ rose_copy_name_to_q931(ctrl, &call->redirecting.to.name,
+ &invoke->args.qsig.DivertingLegInformation3.redirection_name);
+ if (!invoke->args.qsig.DivertingLegInformation3.presentation_allowed_indicator) {
+ call->redirecting.to.name.presentation = PRI_PRES_RESTRICTED;
+ }
+ } else {
+ q931_party_name_init(&call->redirecting.to.name);
+ }
+
+ switch (call->redirecting.state) {
+ case Q931_REDIRECTING_STATE_EXPECTING_RX_DIV_LEG_3:
+ call->redirecting.state = Q931_REDIRECTING_STATE_IDLE;
+ subcmd = q931_alloc_subcommand(ctrl);
+ if (!subcmd) {
+ pri_error(ctrl, "ERROR: Too many facility subcommands\n");
+ break;
+ }
+ /* Setup redirecting subcommand */
+ subcmd->cmd = PRI_SUBCMD_REDIRECTING;
+ q931_party_redirecting_copy_to_pri(&subcmd->u.redirecting,
+ &call->redirecting);
+ break;
+ default:
+ break;
+ }
+ break;
#if 0 /* Not handled yet */
case ROSE_QSIG_CfnrDivertedLegFailed:
break;
Modified: team/group/issue14068/pri_facility.h
URL: http://svn.asterisk.org/svn-view/libpri/team/group/issue14068/pri_facility.h?view=diff&rev=873&r1=872&r2=873
==============================================================================
--- team/group/issue14068/pri_facility.h (original)
+++ team/group/issue14068/pri_facility.h Fri Jun 12 13:44:49 2009
@@ -78,16 +78,12 @@
/* starts a QSIG Path Replacement */
int anfpr_initiate_transfer(struct pri *pri, q931_call *c1, q931_call *c2);
-int qsig_initiate_diverting_leg_information1(struct pri *pri, q931_call *call);
-
-int qsig_initiate_call_transfer_complete(struct pri *pri, q931_call *call, int call_status);
+int send_call_transfer_complete(struct pri *pri, q931_call *call, int call_status);
int rose_diverting_leg_information1_encode(struct pri *pri, q931_call *call);
-
int rose_diverting_leg_information3_encode(struct pri *pri, q931_call *call, int messagetype);
[... 426 lines stripped ...]
More information about the libpri-commits
mailing list