[libpri-commits] rmudgett: branch group/ccss r1344 - /team/group/ccss/
SVN commits to the libpri project
libpri-commits at lists.digium.com
Fri Nov 20 11:28:19 CST 2009
Author: rmudgett
Date: Fri Nov 20 11:28:16 2009
New Revision: 1344
URL: http://svnview.digium.com/svn/libpri?view=rev&rev=1344
Log:
Commit checkpoint for work in progress.
* Rearange code to make some pri_facility.c functions available to
pri_cc.c.
* Some progress on PTMP call completion.
* Make q931_encode_channel() handle the cis_call flag like the held_call
flag. Asterisk will need to deal with PRI events coming in with the
cis_call flag set in the channel parameter. Asterisk should generally
treat subcmds from these events as coming in without a call.
* q931_fill_facility_event() now sets the PRI_EVENT_FACILITY call
parameter to NULL if the call reference is the dummy call reference.
Modified:
team/group/ccss/pri.c
team/group/ccss/pri_cc.c
team/group/ccss/pri_facility.c
team/group/ccss/pri_facility.h
team/group/ccss/pri_internal.h
team/group/ccss/q931.c
Modified: team/group/ccss/pri.c
URL: http://svnview.digium.com/svn/libpri/team/group/ccss/pri.c?view=diff&rev=1344&r1=1343&r2=1344
==============================================================================
--- team/group/ccss/pri.c (original)
+++ team/group/ccss/pri.c Fri Nov 20 11:28:16 2009
@@ -40,8 +40,6 @@
#include "libpri.h"
#include "pri_internal.h"
#include "pri_facility.h"
-#include "pri_q921.h"
-#include "pri_q931.h"
#define PRI_BIT(a_bit) (1UL << (a_bit))
#define PRI_ALL_SWITCHES 0xFFFFFFFF
Modified: team/group/ccss/pri_cc.c
URL: http://svnview.digium.com/svn/libpri/team/group/ccss/pri_cc.c?view=diff&rev=1344&r1=1343&r2=1344
==============================================================================
--- team/group/ccss/pri_cc.c (original)
+++ team/group/ccss/pri_cc.c Fri Nov 20 11:28:16 2009
@@ -35,17 +35,14 @@
#include "compat.h"
#include "libpri.h"
#include "pri_internal.h"
-#include "pri_q921.h"
-#include "pri_q931.h"
+#include "pri_facility.h"
#include <stdlib.h>
/* ------------------------------------------------------------------- */
-#if defined(BUGBUG_NOT_USED_YET)
-/*!
- * \internal
+/*!
* \brief Find a cc_record by the PTMP reference_id.
*
* \param ctrl D channel controller.
@@ -54,7 +51,7 @@
* \retval cc_record on success.
* \retval NULL on error.
*/
-static struct pri_cc_record *pri_cc_find_by_reference(struct pri *ctrl, unsigned reference_id)
+struct pri_cc_record *pri_cc_find_by_reference(struct pri *ctrl, unsigned reference_id)
{
struct pri_cc_record *cc_record;
@@ -68,10 +65,8 @@
return cc_record;
}
-#endif
-
-/*!
- * \internal
+
+/*!
* \brief Find a cc_record by the PTMP linkage_id.
*
* \param ctrl D channel controller.
@@ -80,7 +75,7 @@
* \retval cc_record on success.
* \retval NULL on error.
*/
-static struct pri_cc_record *pri_cc_find_by_linkage(struct pri *ctrl, unsigned linkage_id)
+struct pri_cc_record *pri_cc_find_by_linkage(struct pri *ctrl, unsigned linkage_id)
{
struct pri_cc_record *cc_record;
@@ -120,19 +115,17 @@
return cc_record;
}
-#if defined(BUGBUG_NOT_USED_YET)
-/*!
- * \internal
+/*!
* \brief Find a cc_record by an incoming call addressing data.
*
* \param ctrl D channel controller.
- * \param party_a Party A address.
+ * \param party_a Party A address.
* \param party_b Party B address.
*
* \retval cc_record on success.
* \retval NULL on error.
*/
-static struct pri_cc_record *pri_cc_find_by_addressing(struct pri *ctrl, const struct q931_party_address *party_a, const struct q931_party_address *party_b)
+struct pri_cc_record *pri_cc_find_by_addressing(struct pri *ctrl, const struct q931_party_address *party_a, const struct q931_party_address *party_b)
{
struct pri_cc_record *cc_record;
@@ -149,19 +142,16 @@
/*! \todo BUGBUG pri_cc_find_by_addressing() not written */
}
-#endif
-
-#if defined(BUGBUG_NOT_USED_YET)
-/*!
- * \internal
+
+/*!
* \brief Allocate a new cc_record reference id.
*
* \param ctrl D channel controller.
*
* \retval reference_id on success.
- * \retval -1 on error.
- */
-static int pri_cc_new_reference_id(struct pri *ctrl)
+ * \retval CC_PTMP_INVALID_ID on error.
+ */
+int pri_cc_new_reference_id(struct pri *ctrl)
{
long reference_id;
long first_id;
@@ -176,14 +166,13 @@
if (reference_id == first_id) {
/* We probably have a resource leak. */
pri_error(ctrl, "PTMP call completion reference id exhaustion!\n");
- reference_id = -1;
+ reference_id = CC_PTMP_INVALID_ID;
break;
}
}
return reference_id;
}
-#endif
/*!
* \internal
@@ -192,7 +181,7 @@
* \param ctrl D channel controller.
*
* \retval linkage_id on success.
- * \retval -1 on error.
+ * \retval CC_PTMP_INVALID_ID on error.
*/
static int pri_cc_new_linkage_id(struct pri *ctrl)
{
@@ -209,7 +198,7 @@
if (linkage_id == first_id) {
/* We probably have a resource leak. */
pri_error(ctrl, "PTMP call completion linkage id exhaustion!\n");
- linkage_id = -1;
+ linkage_id = CC_PTMP_INVALID_ID;
break;
}
}
@@ -318,6 +307,110 @@
}
/*!
+ * \internal
+ * \brief Encode ETSI PTP call completion event operation 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 operation PTP call completion event operation to encode.
+ *
+ * \retval Start of the next ASN.1 component to encode on success.
+ * \retval NULL on error.
+ */
+static unsigned char *enc_etsi_ptp_cc_operation(struct pri *ctrl, unsigned char *pos,
+ unsigned char *end, enum rose_operation operation)
+{
+ 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 = operation;
+
+ pos = rose_encode_invoke(ctrl, pos, end, &msg);
+
+ return pos;
+}
+
+/*!
+ * \internal
+ * \brief Encode ETSI PTMP call completion available 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 message.
+ *
+ * \retval Start of the next ASN.1 component to encode on success.
+ * \retval NULL on error.
+ */
+static unsigned char *enc_etsi_ptmp_cc_available(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.invoke_id = get_invokeid(ctrl);
+ msg.operation = ROSE_ETSI_CallInfoRetain;
+
+ msg.args.etsi.CallInfoRetain.call_linkage_id = call->cc.record->call_linkage_id;
+
+ pos = rose_encode_invoke(ctrl, pos, end, &msg);
+
+ return pos;
+}
+
+/*!
+ * \brief Encode and queue a cc-available message.
+ *
+ * \param ctrl D channel controller for diagnostic messages or global options.
+ * \param call Call leg from which to encode call completion available.
+ * \param msgtype Q.931 message type to put facility ie in.
+ *
+ * \retval 0 on success.
+ * \retval -1 on error.
+ */
+int rose_cc_available_encode(struct pri *ctrl, q931_call *call, int msgtype)
+{
+ unsigned char buffer[256];
+ unsigned char *end;
+
+ switch (ctrl->switchtype) {
+ case PRI_SWITCH_EUROISDN_E1:
+ case PRI_SWITCH_EUROISDN_T1:
+ if (q931_is_ptmp(ctrl)) {
+ end =
+ enc_etsi_ptmp_cc_available(ctrl, buffer, buffer + sizeof(buffer), call);
+ } else {
+ end =
+ enc_etsi_ptp_cc_operation(ctrl, buffer, buffer + sizeof(buffer),
+ ROSE_ETSI_CCBS_T_Available);
+ }
+ break;
+ case PRI_SWITCH_QSIG:
+ /* Q.SIG does not have a cc-available type message. */
+ return 0;
+ default:
+ return -1;
+ }
+ if (!end) {
+ return -1;
+ }
+
+ return pri_call_apdu_queue(call, msgtype, buffer, end - buffer, NULL);
+}
+
+/*!
* \brief Send an event from the upper layer to the cc state machine.
*
* \param ctrl D channel controller.
@@ -428,7 +521,7 @@
int linkage_id;
linkage_id = pri_cc_new_linkage_id(ctrl);
- if (linkage_id < 0) {
+ if (linkage_id == CC_PTMP_INVALID_ID) {
break;
}
cc_record = pri_cc_new_record(ctrl, call);
@@ -522,23 +615,171 @@
}
/*!
+ * \internal
+ * \brief Encode a PTMP cc-request reply 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 operation CCBS/CCNR operation code.
+ * \param invoke_id Invoke id to put in error message response.
+ * \param recall_mode Configured PTMP recall mode.
+ * \param reference_id Active CC reference id.
+ *
+ * \retval Start of the next ASN.1 component to encode on success.
+ * \retval NULL on error.
+ */
+static unsigned char *enc_cc_etsi_ptmp_req_rsp(struct pri *ctrl, unsigned char *pos,
+ unsigned char *end, enum rose_operation operation, int invoke_id, int recall_mode,
+ int reference_id)
+{
+ struct rose_msg_result msg;
+
+ pos = facility_encode_header(ctrl, pos, end, NULL);
+ if (!pos) {
+ return NULL;
+ }
+
+ memset(&msg, 0, sizeof(msg));
+ msg.invoke_id = invoke_id;
+ msg.operation = operation;
+
+ /* CCBS/CCNR reply */
+ msg.args.etsi.CCBSRequest.recall_mode = recall_mode;
+ msg.args.etsi.CCBSRequest.ccbs_reference = reference_id;
+
+ pos = rose_encode_result(ctrl, pos, end, &msg);
+
+ return pos;
+}
+
+/*!
+ * \internal
+ * \brief Encode and queue PTMP a cc-request reply message.
+ *
+ * \param ctrl D channel controller.
+ * \param call Q.931 call leg.
+ * \param msgtype Q.931 message type to put facility ie in.
+ * \param operation CCBS/CCNR operation code.
+ * \param invoke_id Invoke id to put in error message response.
+ * \param recall_mode Configured PTMP recall mode.
+ * \param reference_id Active CC reference id.
+ *
+ * \retval 0 on success.
+ * \retval -1 on error.
+ */
+static int rose_cc_etsi_ptmp_req_rsp_encode(struct pri *ctrl, q931_call *call, int msgtype, enum rose_operation operation, int invoke_id, int recall_mode, int reference_id)
+{
+ unsigned char buffer[256];
+ unsigned char *end;
+
+ end = enc_cc_etsi_ptmp_req_rsp(ctrl, buffer, buffer + sizeof(buffer), operation,
+ invoke_id, recall_mode, reference_id);
+ if (!end) {
+ return -1;
+ }
+
+ return pri_call_apdu_queue(call, msgtype, buffer, end - buffer, NULL);
+}
+
+/*!
+ * \internal
+ * \brief Send the CC activation request result PTMP.
+ *
+ * \param ctrl D channel controller.
+ * \param call Q.931 call leg.
+ * \param operation CCBS/CCNR operation code.
+ * \param invoke_id Invoke id to put in error message response.
+ * \param recall_mode Configured PTMP recall mode.
+ * \param reference_id Active CC reference id.
+ *
+ * \retval 0 on success.
+ * \retval -1 on error.
+ */
+static int send_cc_etsi_ptmp_req_rsp(struct pri *ctrl, q931_call *call, enum rose_operation operation, int invoke_id, int recall_mode, int reference_id)
+{
+ if (rose_cc_etsi_ptmp_req_rsp_encode(ctrl, call, Q931_FACILITY, operation, invoke_id,
+ recall_mode, reference_id)
+ || q931_facility(ctrl, call)) {
+ pri_message(ctrl,
+ "Could not schedule facility message for CC request result message.\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+/*!
+ * \internal
+ * \brief Response to an incoming CC activation request PTMP.
+ *
+ * \param ctrl D channel controller.
+ * \param cc_record Call completion record to process event.
+ * \param status success(0)/timeout(1)/
+ * short_term_denial(2)/long_term_denial(3)/not_subscribed(4)/queue_full(5)
+ *
+ * \return Nothing
+ */
+static void rose_cc_req_rsp_ptmp(struct pri *ctrl, struct pri_cc_record *cc_record, int status)
+{
+ if (status) {
+ enum rose_error_code code;
+
+ switch (status) {
+ default:
+ case 1:/* timeout */
+ case 2:/* short_term_denial */
+ code = ROSE_ERROR_CCBS_ShortTermDenial;
+ break;
+ case 3:/* long_term_denial */
+ code = ROSE_ERROR_CCBS_LongTermDenial;
+ break;
+ case 4:/* not_subscribed */
+ code = ROSE_ERROR_Gen_NotSubscribed;
+ break;
+ case 5:/* queue_full */
+ code = ROSE_ERROR_CCBS_OutgoingCCBSQueueFull;
+ break;
+ }
+ send_facility_error(ctrl, cc_record->response.signaling,
+ cc_record->response.invoke_id, code);
+ cc_record->state = CC_STATE_AVAILABLE;
+ cc_record->ccbs_reference_id = CC_PTMP_INVALID_ID;
+ } else {
+ /* Successful CC activation. */
+ send_cc_etsi_ptmp_req_rsp(ctrl, cc_record->response.signaling,
+ cc_record->response.invoke_operation, cc_record->response.invoke_id,
+ cc_record->option.recall_mode, cc_record->ccbs_reference_id);
+ cc_record->state = CC_STATE_ACTIVATED;
+ }
+}
+
+/*!
* \brief Response to an incoming CC activation request.
*
* \param ctrl D channel controller.
* \param cc_id CC record ID to activate.
* \param status success(0)/timeout(1)/
- * short_term_denial(2)/long_term_denial(3)/not_subscribed(4)
+ * short_term_denial(2)/long_term_denial(3)/not_subscribed(4)/queue_full(5)
*
* \return Nothing
*/
void pri_cc_req_rsp(struct pri *ctrl, long cc_id, int status)
{
+ struct pri_cc_record *cc_record;
+
+ cc_record = pri_cc_find_by_id(ctrl, cc_id);
+ if (!cc_record) {
+ return;
+ }
+
switch (ctrl->switchtype) {
case PRI_SWITCH_QSIG:
break;
case PRI_SWITCH_EUROISDN_E1:
case PRI_SWITCH_EUROISDN_T1:
if (q931_is_ptmp(ctrl)) {
+ rose_cc_req_rsp_ptmp(ctrl, cc_record, status);
} else {
}
break;
Modified: team/group/ccss/pri_facility.c
URL: http://svnview.digium.com/svn/libpri/team/group/ccss/pri_facility.c?view=diff&rev=1344&r1=1343&r2=1344
==============================================================================
--- team/group/ccss/pri_facility.c (original)
+++ team/group/ccss/pri_facility.c Fri Nov 20 11:28:16 2009
@@ -30,10 +30,7 @@
#include "compat.h"
#include "libpri.h"
#include "pri_internal.h"
-#include "pri_q921.h"
-#include "pri_q931.h"
#include "pri_facility.h"
-#include "rose.h"
#include <stdio.h>
#include <stdlib.h>
@@ -43,12 +40,6 @@
const char *pri_facility_error2str(int facility_error_code)
{
return rose_error2str(facility_error_code);
-}
-
-static short get_invokeid(struct pri *ctrl)
-{
- ctrl = PRI_MASTER(ctrl);
- return ++ctrl->last_invoke;
}
static int redirectingreason_from_q931(struct pri *ctrl, int redirectingreason)
@@ -503,7 +494,6 @@
}
/*!
- * \internal
* \brief Copy the given rose party number to the q931_party_number
*
* \param ctrl D channel controller for diagnostic messages or global options.
@@ -514,8 +504,8 @@
*
* \return Nothing
*/
-static void rose_copy_number_to_q931(struct pri *ctrl,
- struct q931_party_number *q931_number, const struct rosePartyNumber *rose_number)
+void rose_copy_number_to_q931(struct pri *ctrl, struct q931_party_number *q931_number,
+ const struct rosePartyNumber *rose_number)
{
//q931_party_number_init(q931_number);
libpri_copy_string(q931_number->str, (char *) rose_number->str,
@@ -526,7 +516,6 @@
}
/*!
- * \internal
* \brief Copy the given rose subaddress to the q931_party_subaddress.
*
* \param ctrl D channel controller for diagnostic messages or global options.
@@ -537,7 +526,7 @@
*
* \return Nothing
*/
-static void rose_copy_subaddress_to_q931(struct pri *ctrl,
+void rose_copy_subaddress_to_q931(struct pri *ctrl,
struct q931_party_subaddress *q931_subaddress,
const struct rosePartySubaddress *rose_subaddress)
{
@@ -577,7 +566,6 @@
}
/*!
- * \internal
* \brief Copy the given rose address to the q931_party_id address.
*
* \param ctrl D channel controller for diagnostic messages or global options.
@@ -588,8 +576,8 @@
*
* \return Nothing
*/
-static void rose_copy_address_to_q931(struct pri *ctrl,
- struct q931_party_id *q931_address, const struct roseAddress *rose_address)
+void rose_copy_address_to_q931(struct pri *ctrl, struct q931_party_id *q931_address,
+ const struct roseAddress *rose_address)
{
rose_copy_number_to_q931(ctrl, &q931_address->number, &rose_address->number);
rose_copy_subaddress_to_q931(ctrl, &q931_address->subaddress,
@@ -597,7 +585,6 @@
}
/*!
- * \internal
* \brief Copy the given rose presented screened party number to the q931_party_number
*
* \param ctrl D channel controller for diagnostic messages or global options.
@@ -606,7 +593,7 @@
*
* \return Nothing
*/
-static void rose_copy_presented_number_screened_to_q931(struct pri *ctrl,
+void rose_copy_presented_number_screened_to_q931(struct pri *ctrl,
struct q931_party_number *q931_number,
const struct rosePresentedNumberScreened *rose_presented)
{
@@ -628,7 +615,6 @@
}
/*!
- * \internal
* \brief Copy the given rose presented unscreened party number to the q931_party_number
*
* \param ctrl D channel controller for diagnostic messages or global options.
@@ -637,7 +623,7 @@
*
* \return Nothing
*/
-static void rose_copy_presented_number_unscreened_to_q931(struct pri *ctrl,
+void rose_copy_presented_number_unscreened_to_q931(struct pri *ctrl,
struct q931_party_number *q931_number,
const struct rosePresentedNumberUnscreened *rose_presented)
{
@@ -656,7 +642,6 @@
}
/*!
- * \internal
* \brief Copy the given rose presented screened party address to the q931_party_number
*
* \param ctrl D channel controller for diagnostic messages or global options.
@@ -665,7 +650,7 @@
*
* \return Nothing
*/
-static void rose_copy_presented_address_screened_to_q931(struct pri *ctrl,
+void rose_copy_presented_address_screened_to_q931(struct pri *ctrl,
struct q931_party_id *q931_address,
const struct rosePresentedAddressScreened *rose_presented)
{
@@ -691,7 +676,6 @@
}
/*!
- * \internal
* \brief Copy the given rose party name to the q931_party_name
*
* \param ctrl D channel controller for diagnostic messages or global options.
@@ -700,8 +684,8 @@
*
* \return Nothing
*/
-static void rose_copy_name_to_q931(struct pri *ctrl,
- struct q931_party_name *qsig_name, const struct roseQsigName *rose_name)
+void rose_copy_name_to_q931(struct pri *ctrl, struct q931_party_name *qsig_name,
+ const struct roseQsigName *rose_name)
{
//q931_party_name_init(qsig_name);
qsig_name->valid = 1;
@@ -712,7 +696,6 @@
}
/*!
- * \internal
* \brief Copy the given q931_party_number to the rose party number
*
* \param ctrl D channel controller for diagnostic messages or global options.
@@ -721,8 +704,8 @@
*
* \return Nothing
*/
-static void q931_copy_number_to_rose(struct pri *ctrl,
- struct rosePartyNumber *rose_number, const struct q931_party_number *q931_number)
+void q931_copy_number_to_rose(struct pri *ctrl, struct rosePartyNumber *rose_number,
+ const struct q931_party_number *q931_number)
{
rose_number->plan = numbering_plan_from_q931(ctrl, q931_number->plan);
rose_number->ton = typeofnumber_from_q931(ctrl, q931_number->plan);
@@ -733,7 +716,6 @@
}
/*!
- * \internal
* \brief Copy the given q931_party_subaddress to the rose subaddress.
*
* \param ctrl D channel controller for diagnostic messages or global options.
@@ -742,7 +724,7 @@
*
* \return Nothing
*/
-static void q931_copy_subaddress_to_rose(struct pri *ctrl,
+void q931_copy_subaddress_to_rose(struct pri *ctrl,
struct rosePartySubaddress *rose_subaddress,
const struct q931_party_subaddress *q931_subaddress)
{
@@ -784,7 +766,6 @@
}
/*!
- * \internal
* \brief Copy the given q931_party_id address to the rose address.
*
* \param ctrl D channel controller for diagnostic messages or global options.
@@ -793,7 +774,7 @@
*
* \return Nothing
*/
-static void q931_copy_address_to_rose(struct pri *ctrl, struct roseAddress *rose_address,
+void q931_copy_address_to_rose(struct pri *ctrl, struct roseAddress *rose_address,
const struct q931_party_id *q931_address)
{
q931_copy_number_to_rose(ctrl, &rose_address->number, &q931_address->number);
@@ -802,7 +783,6 @@
}
/*!
- * \internal
* \brief Copy the given q931_party_number to the rose presented screened party number
*
* \param ctrl D channel controller for diagnostic messages or global options.
@@ -811,7 +791,7 @@
*
* \return Nothing
*/
-static void q931_copy_presented_number_screened_to_rose(struct pri *ctrl,
+void q931_copy_presented_number_screened_to_rose(struct pri *ctrl,
struct rosePresentedNumberScreened *rose_presented,
const struct q931_party_number *q931_number)
{
@@ -827,7 +807,6 @@
}
/*!
- * \internal
* \brief Copy the given q931_party_number to the rose presented unscreened party number
*
* \param ctrl D channel controller for diagnostic messages or global options.
@@ -836,7 +815,7 @@
*
* \return Nothing
*/
-static void q931_copy_presented_number_unscreened_to_rose(struct pri *ctrl,
+void q931_copy_presented_number_unscreened_to_rose(struct pri *ctrl,
struct rosePresentedNumberUnscreened *rose_presented,
const struct q931_party_number *q931_number)
{
@@ -849,9 +828,7 @@
}
}
-#if 0 /* In case it is needed in the future */
-/*!
- * \internal
+/*!
* \brief Copy the given q931_party_number to the rose presented screened party address
*
* \param ctrl D channel controller for diagnostic messages or global options.
@@ -860,7 +837,7 @@
*
* \return Nothing
*/
-static void q931_copy_presented_address_screened_to_rose(struct pri *ctrl,
+void q931_copy_presented_address_screened_to_rose(struct pri *ctrl,
struct rosePresentedAddressScreened *rose_presented,
const struct q931_party_id *q931_address)
{
@@ -878,10 +855,8 @@
rose_presented->presentation = 2;/* numberNotAvailableDueToInterworking */
}
}
-#endif /* In case it is needed in the future */
-
-/*!
- * \internal
+
+/*!
* \brief Copy the given q931_party_name to the rose party name
*
* \param ctrl D channel controller for diagnostic messages or global options.
@@ -890,8 +865,8 @@
*
* \return Nothing
*/
-static void q931_copy_name_to_rose(struct pri *ctrl,
- struct roseQsigName *rose_name, const struct q931_party_name *qsig_name)
+void q931_copy_name_to_rose(struct pri *ctrl, struct roseQsigName *rose_name,
+ const struct q931_party_name *qsig_name)
{
if (qsig_name->valid) {
rose_name->presentation = qsig_name_presentation_from_q931(ctrl,
@@ -2991,18 +2966,18 @@
}
/*!
- * \internal
* \brief Encode and queue a plain facility error code.
*
* \param ctrl D channel controller for diagnostic messages or global options.
* \param call Call leg from which to encode error message response.
+ * \param msgtype Q.931 message type to put facility ie in.
* \param invoke_id Invoke id to put in error message response.
* \param code Error code to put in error message response.
*
* \retval 0 on success.
* \retval -1 on error.
*/
-static int rose_facility_error_encode(struct pri *ctrl, q931_call *call, int invoke_id,
+int rose_error_msg_encode(struct pri *ctrl, q931_call *call, int msgtype, int invoke_id,
enum rose_error_code code)
{
unsigned char buffer[256];
@@ -3025,7 +3000,7 @@
return -1;
}
- return pri_call_apdu_queue(call, Q931_FACILITY, buffer, end - buffer, NULL);
+ return pri_call_apdu_queue(call, msgtype, buffer, end - buffer, NULL);
}
/*!
@@ -3039,10 +3014,10 @@
* \retval 0 on success.
* \retval -1 on error.
*/
-static int send_facility_error(struct pri *ctrl, q931_call *call, int invoke_id,
+int send_facility_error(struct pri *ctrl, q931_call *call, int invoke_id,
enum rose_error_code code)
{
- if (rose_facility_error_encode(ctrl, call, invoke_id, code)
+ if (rose_error_msg_encode(ctrl, call, Q931_FACILITY, invoke_id, code)
|| q931_facility(ctrl, call)) {
pri_message(ctrl,
"Could not schedule facility message for error message.\n");
@@ -3124,7 +3099,6 @@
}
/*!
- * \internal
* \brief Encode and queue a plain ROSE result ok.
*
* \param ctrl D channel controller for diagnostic messages or global options.
@@ -3135,7 +3109,7 @@
* \retval 0 on success.
* \retval -1 on error.
*/
-static int rose_result_ok_encode(struct pri *ctrl, q931_call *call, int msgtype, int invoke_id)
+int rose_result_ok_encode(struct pri *ctrl, q931_call *call, int msgtype, int invoke_id)
{
unsigned char buffer[256];
unsigned char *end;
@@ -3170,7 +3144,7 @@
* \retval 0 on success.
* \retval -1 on error.
*/
-static int send_facility_result_ok(struct pri *ctrl, q931_call *call, int invoke_id)
+int send_facility_result_ok(struct pri *ctrl, q931_call *call, int invoke_id)
{
if (rose_result_ok_encode(ctrl, call, Q931_FACILITY, invoke_id)
|| q931_facility(ctrl, call)) {
@@ -3223,111 +3197,6 @@
break;
}
return send_facility_error(ctrl, call, invoke_id, rose_err);
-}
-
-/*!
- * \internal
- * \brief Encode ETSI PTP call completion event operation 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 message.
- * \param operation PTP call completion event operation to encode.
- *
- * \retval Start of the next ASN.1 component to encode on success.
- * \retval NULL on error.
- */
-static unsigned char *enc_etsi_ptp_cc_operation(struct pri *ctrl, unsigned char *pos,
- unsigned char *end, q931_call *call, enum rose_operation operation)
-{
- 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 = operation;
-
- pos = rose_encode_invoke(ctrl, pos, end, &msg);
-
- return pos;
-}
-
-/*!
- * \internal
- * \brief Encode ETSI PTMP call completion available 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 message.
- *
- * \retval Start of the next ASN.1 component to encode on success.
- * \retval NULL on error.
- */
-static unsigned char *enc_etsi_ptmp_cc_available(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.invoke_id = get_invokeid(ctrl);
- msg.operation = ROSE_ETSI_CallInfoRetain;
-
- msg.args.etsi.CallInfoRetain.call_linkage_id = call->cc.record->call_linkage_id;
-
- pos = rose_encode_invoke(ctrl, pos, end, &msg);
-
- return pos;
-}
-
-/*!
- * \brief Encode and queue a cc-available message.
- *
- * \param ctrl D channel controller for diagnostic messages or global options.
- * \param call Call leg from which to encode call completion available.
- * \param msgtype Q.931 message type to put facility ie in.
- *
- * \retval 0 on success.
- * \retval -1 on error.
- */
-int rose_cc_available_encode(struct pri *ctrl, q931_call *call, int msgtype)
-{
- unsigned char buffer[256];
- unsigned char *end;
-
- switch (ctrl->switchtype) {
- case PRI_SWITCH_EUROISDN_E1:
- case PRI_SWITCH_EUROISDN_T1:
- if (q931_is_ptmp(ctrl)) {
- end =
- enc_etsi_ptmp_cc_available(ctrl, buffer, buffer + sizeof(buffer), call);
- } else {
- end =
- enc_etsi_ptp_cc_operation(ctrl, buffer, buffer + sizeof(buffer), call,
- ROSE_ETSI_CCBS_T_Available);
- }
- break;
- case PRI_SWITCH_QSIG:
- /* Q.SIG does not have a cc-available type message. */
- return 0;
- default:
- return -1;
- }
- if (!end) {
- return -1;
- }
-
- return pri_call_apdu_queue(call, msgtype, buffer, end - buffer, NULL);
}
/*!
@@ -3891,6 +3760,39 @@
subcmd->u.cc_available.cc_id = cc_record->record_id;
break;
case ROSE_ETSI_CCBSRequest:
+ cc_record = pri_cc_find_by_linkage(ctrl,
+ invoke->args.etsi.CCBSRequest.call_linkage_id);
+ if (!cc_record) {
+ send_facility_error(ctrl, call, invoke->invoke_id,
+ ROSE_ERROR_CCBS_InvalidCallLinkageID);
+ break;
+ }
+ if (cc_record->state != CC_STATE_AVAILABLE) {
+ send_facility_error(ctrl, call, invoke->invoke_id,
+ ROSE_ERROR_CCBS_IsAlreadyActivated);
+ break;
+ }
+ cc_record->ccbs_reference_id = pri_cc_new_reference_id(ctrl);
+ if (cc_record->ccbs_reference_id == CC_PTMP_INVALID_ID) {
+ /* Could not allocate a call reference id. */
+ send_facility_error(ctrl, call, invoke->invoke_id,
+ ROSE_ERROR_CCBS_OutgoingCCBSQueueFull);
+ break;
+ }
+ cc_record->state = CC_STATE_REQUESTED;
+ cc_record->response.signaling = call;
+ cc_record->response.invoke_operation = invoke->operation;
+ cc_record->response.invoke_id = invoke->invoke_id;
+
+ subcmd = q931_alloc_subcommand(ctrl);
+ if (!subcmd) {
+ pri_error(ctrl, "ERROR: Too many facility subcommands\n");
+ break;
+ }
+
+ subcmd->cmd = PRI_SUBCMD_CC_REQ;
+ subcmd->u.cc_request.cc_id = cc_record->record_id;
+ subcmd->u.cc_request.mode = 0;/* ccbs */
break;
case ROSE_ETSI_CCBSDeactivate:
break;
@@ -3950,6 +3852,39 @@
subcmd->u.cc_available.cc_id = cc_record->record_id;
break;
case ROSE_ETSI_CCNRRequest:
+ cc_record = pri_cc_find_by_linkage(ctrl,
+ invoke->args.etsi.CCNRRequest.call_linkage_id);
+ if (!cc_record) {
+ send_facility_error(ctrl, call, invoke->invoke_id,
+ ROSE_ERROR_CCBS_InvalidCallLinkageID);
+ break;
+ }
+ if (cc_record->state != CC_STATE_AVAILABLE) {
+ send_facility_error(ctrl, call, invoke->invoke_id,
+ ROSE_ERROR_CCBS_IsAlreadyActivated);
+ break;
+ }
+ cc_record->ccbs_reference_id = pri_cc_new_reference_id(ctrl);
+ if (cc_record->ccbs_reference_id == CC_PTMP_INVALID_ID) {
+ /* Could not allocate a call reference id. */
+ send_facility_error(ctrl, call, invoke->invoke_id,
+ ROSE_ERROR_CCBS_OutgoingCCBSQueueFull);
+ break;
+ }
+ cc_record->state = CC_STATE_REQUESTED;
+ cc_record->response.signaling = call;
+ cc_record->response.invoke_operation = invoke->operation;
+ cc_record->response.invoke_id = invoke->invoke_id;
+
+ subcmd = q931_alloc_subcommand(ctrl);
+ if (!subcmd) {
+ pri_error(ctrl, "ERROR: Too many facility subcommands\n");
+ break;
+ }
+
+ subcmd->cmd = PRI_SUBCMD_CC_REQ;
+ subcmd->u.cc_request.cc_id = cc_record->record_id;
+ subcmd->u.cc_request.mode = 1;/* ccnr */
break;
case ROSE_ETSI_CCNRInterrogate:
break;
Modified: team/group/ccss/pri_facility.h
URL: http://svnview.digium.com/svn/libpri/team/group/ccss/pri_facility.h?view=diff&rev=1344&r1=1343&r2=1344
==============================================================================
--- team/group/ccss/pri_facility.h (original)
+++ team/group/ccss/pri_facility.h Fri Nov 20 11:28:16 2009
@@ -30,13 +30,7 @@
#ifndef _PRI_FACILITY_H
#define _PRI_FACILITY_H
#include "pri_q931.h"
-
-/* Forward declare some structs */
-struct fac_extension_header;
-struct rose_msg_invoke;
-struct rose_msg_result;
-struct rose_msg_error;
-struct rose_msg_reject;
+#include "rose.h"
/* Protocol Profile field */
#define Q932_PROTOCOL_MASK 0x1F
@@ -173,6 +167,27 @@
unsigned char apdu[255];
};
+void rose_copy_number_to_q931(struct pri *ctrl, struct q931_party_number *q931_number, const struct rosePartyNumber *rose_number);
+void rose_copy_subaddress_to_q931(struct pri *ctrl, struct q931_party_subaddress *q931_subaddress, const struct rosePartySubaddress *rose_subaddress);
+void rose_copy_address_to_q931(struct pri *ctrl, struct q931_party_id *q931_address, const struct roseAddress *rose_address);
+void rose_copy_presented_number_screened_to_q931(struct pri *ctrl, struct q931_party_number *q931_number, const struct rosePresentedNumberScreened *rose_presented);
+void rose_copy_presented_number_unscreened_to_q931(struct pri *ctrl, struct q931_party_number *q931_number, const struct rosePresentedNumberUnscreened *rose_presented);
+void rose_copy_presented_address_screened_to_q931(struct pri *ctrl, struct q931_party_id *q931_address, const struct rosePresentedAddressScreened *rose_presented);
+void rose_copy_name_to_q931(struct pri *ctrl, struct q931_party_name *qsig_name, const struct roseQsigName *rose_name);
+
+void q931_copy_number_to_rose(struct pri *ctrl, struct rosePartyNumber *rose_number, const struct q931_party_number *q931_number);
+void q931_copy_subaddress_to_rose(struct pri *ctrl, struct rosePartySubaddress *rose_subaddress, const struct q931_party_subaddress *q931_subaddress);
+void q931_copy_address_to_rose(struct pri *ctrl, struct roseAddress *rose_address, const struct q931_party_id *q931_address);
+void q931_copy_presented_number_screened_to_rose(struct pri *ctrl, struct rosePresentedNumberScreened *rose_presented, const struct q931_party_number *q931_number);
+void q931_copy_presented_number_unscreened_to_rose(struct pri *ctrl, struct rosePresentedNumberUnscreened *rose_presented, const struct q931_party_number *q931_number);
+void q931_copy_presented_address_screened_to_rose(struct pri *ctrl, struct rosePresentedAddressScreened *rose_presented, const struct q931_party_id *q931_address);
+void q931_copy_name_to_rose(struct pri *ctrl, struct roseQsigName *rose_name, const struct q931_party_name *qsig_name);
+
+int rose_error_msg_encode(struct pri *ctrl, q931_call *call, int msgtype, int invoke_id, enum rose_error_code code);
+int send_facility_error(struct pri *ctrl, q931_call *call, int invoke_id, enum rose_error_code code);
+int rose_result_ok_encode(struct pri *ctrl, q931_call *call, int msgtype, int invoke_id);
+int send_facility_result_ok(struct pri *ctrl, q931_call *call, int invoke_id);
+
/* Queues an MWI apdu on a the given call */
int mwi_message_send(struct pri *pri, q931_call *call, struct pri_sr *req, int activate);
Modified: team/group/ccss/pri_internal.h
URL: http://svnview.digium.com/svn/libpri/team/group/ccss/pri_internal.h?view=diff&rev=1344&r1=1343&r2=1344
==============================================================================
--- team/group/ccss/pri_internal.h (original)
+++ team/group/ccss/pri_internal.h Fri Nov 20 11:28:16 2009
@@ -583,6 +583,10 @@
CC_EVENT_CCBS_REQUEST,
/*! Requesting CCNR activation. */
CC_EVENT_CCNR_REQUEST,
+ /*! Requesting CCBS activation accepted. */
+ CC_EVENT_CCBS_REQUEST_ACCEPT,
+ /*! Requesting CCNR activation accepted. */
+ CC_EVENT_CCNR_REQUEST_ACCEPT,
/*! CC party B is available. */
CC_EVENT_REMOTE_USER_FREE,
/*! CC poll/prompt for party A status. */
@@ -632,7 +636,17 @@
struct q931_party_address party_b;
/* BUGBUG need to record BC, HLC, and LLC from initial SETUP */
- /*! TRUE if the remote party is party B. */
+ /*! Pending response information. */
+ struct {
+ /*! Send response on this signaling link. */
+ struct q931_call *signaling;
+ /*! Invoke operation code */
+ int invoke_operation;
+ /*! Invoke id to use in the pending response. */
+ short invoke_id;
+ } response;
+
+ /*! TRUE if the remote party is party B. (We are a monitor./We are the originator.) */
unsigned char party_b_is_remote;
/*! TRUE if party_a_busy status is valid. (PTMP) */
unsigned char party_a_status_valid;
@@ -727,6 +741,10 @@
int q931_notify_redirection(struct pri *ctrl, q931_call *call, int notify, const struct q931_party_number *number);
+struct pri_cc_record *pri_cc_find_by_reference(struct pri *ctrl, unsigned reference_id);
+struct pri_cc_record *pri_cc_find_by_linkage(struct pri *ctrl, unsigned linkage_id);
+struct pri_cc_record *pri_cc_find_by_addressing(struct pri *ctrl, const struct q931_party_address *party_a, const struct q931_party_address *party_b);
+int pri_cc_new_reference_id(struct pri *ctrl);
void pri_cc_delete_record(struct pri *ctrl, struct pri_cc_record *doomed);
struct pri_cc_record *pri_cc_new_record(struct pri *ctrl, q931_call *call);
int pri_cc_event_down(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_record, enum CC_EVENTS event);
@@ -785,4 +803,10 @@
return (call->cr == Q931_DUMMY_CALL_REFERENCE) ? 1 : 0;
}
+static inline short get_invokeid(struct pri *ctrl)
+{
+ ctrl = PRI_MASTER(ctrl);
+ return ++ctrl->last_invoke;
+}
+
#endif
Modified: team/group/ccss/q931.c
URL: http://svnview.digium.com/svn/libpri/team/group/ccss/q931.c?view=diff&rev=1344&r1=1343&r2=1344
==============================================================================
--- team/group/ccss/q931.c (original)
+++ team/group/ccss/q931.c Fri Nov 20 11:28:16 2009
@@ -30,10 +30,7 @@
#include "compat.h"
#include "libpri.h"
#include "pri_internal.h"
-#include "pri_q921.h"
-#include "pri_q931.h"
#include "pri_facility.h"
-#include "rose.h"
#include <unistd.h>
#include <stdlib.h>
@@ -306,16 +303,18 @@
case Q931_HOLD_STATE_RETRIEVE_REQ:
case Q931_HOLD_STATE_RETRIEVE_IND:
held_call = 1 << 18;
-
- /* So a -1 does not wipe out the held_call flag. */
+ break;
+ default:
+ held_call = 0;
+ break;
+ }
+ if (held_call || call->cis_call) {
+ /* So a -1 does not wipe out the held_call or cis_call flags. */
channelno = call->channelno & 0xFF;
ds1no = call->ds1no & 0xFF;
- break;
- default:
- held_call = 0;
+ } else {
channelno = call->channelno;
ds1no = call->ds1no;
- break;
}
return channelno | (ds1no << 8) | (call->ds1explicit << 16) | (call->cis_call << 17)
| held_call;
@@ -6088,7 +6087,6 @@
if (allow_posthandle) {
res = post_handle_q931_message(ctrl, mh, c, missingmand);
-
if (res == Q931_RES_HAVEEVENT && !allow_event) {
res = 0;
}
@@ -6564,7 +6562,11 @@
ctrl->ev.facility.subcmds = &ctrl->subcmds;
ctrl->ev.facility.channel = q931_encode_channel(call);
ctrl->ev.facility.cref = call->cr;
- ctrl->ev.facility.call = call->master_call;
+ if (q931_is_dummy_call(call)) {
+ ctrl->ev.facility.call = NULL;
+ } else {
+ ctrl->ev.facility.call = call->master_call;
+ }
ctrl->ev.facility.subcall = call;
/* Need to do this for backward compatibility with struct pri_event_facname */
More information about the libpri-commits
mailing list