[svn-commits] rmudgett: branch 1.4 r1757 - /branches/1.4/
SVN commits to the Digium repositories
svn-commits at lists.digium.com
Fri May 28 15:26:25 CDT 2010
Author: rmudgett
Date: Fri May 28 15:26:23 2010
New Revision: 1757
URL: http://svnview.digium.com/svn/libpri?view=rev&rev=1757
Log:
ETSI Malicious Call ID support.
Add the ability to report malicious callers.
Relevant specification: EN 300 180
Review: https://reviewboard.asterisk.org/r/575/
Modified:
branches/1.4/libpri.h
branches/1.4/pri_facility.c
branches/1.4/pri_internal.h
branches/1.4/rose.c
branches/1.4/rose.h
branches/1.4/rosetest.c
Modified: branches/1.4/libpri.h
URL: http://svnview.digium.com/svn/libpri/branches/1.4/libpri.h?view=diff&rev=1757&r1=1756&r2=1757
==============================================================================
--- branches/1.4/libpri.h (original)
+++ branches/1.4/libpri.h Fri May 28 15:26:23 2010
@@ -545,6 +545,8 @@
#define PRI_SUBCMD_AOC_E 20 /*!< Advice Of Charge End information */
//#define PRI_SUBCMD_AOC_CHARGING_REQ 21 /*!< Advice Of Charge Request information */
//#define PRI_SUBCMD_AOC_CHARGING_REQ_RSP 22 /*!< Advice Of Charge Request Response information */
+#define PRI_SUBCMD_MCID_REQ 23 /*!< Malicious Call ID Request */
+#define PRI_SUBCMD_MCID_RSP 24 /*!< Malicious Call ID Request response */
#if defined(STATUS_REQUEST_PLACE_HOLDER)
struct pri_subcmd_status_request {
@@ -873,6 +875,38 @@
} recorded;
/*! Charging association. */
struct pri_aoc_e_charging_association associated;
+};
+
+struct pri_subcmd_mcid_req {
+ /*!
+ * \brief Information libpri knows about the malicious caller.
+ * \note For the convenience of the upper layer. This information
+ * may be incomplete if the upper layer redacted some caller
+ * information because it was restricted.
+ */
+ struct pri_party_id originator;
+ /*! \brief Information libpri knows about the callee. */
+ struct pri_party_id answerer;
+};
+
+struct pri_subcmd_mcid_rsp {
+ /*!
+ * \brief MCID request response status.
+ * \details
+ * success(0),
+ * timeout(1),
+ * error(2),
+ * reject(3)
+ */
+ int status;
+ /*!
+ * \brief Failure code that can be converted to a string to further
+ * explain the non-timeout failure.
+ * \note Valid when status is error or reject.
+ * \note Use pri_facility_error2str() to convert the error_code.
+ * \note Use pri_facility_reject2str() to convert the reject_code.
+ */
+ int fail_code;
};
struct pri_subcommand {
@@ -903,6 +937,8 @@
struct pri_subcmd_aoc_s aoc_s;
struct pri_subcmd_aoc_d aoc_d;
struct pri_subcmd_aoc_e aoc_e;
+ struct pri_subcmd_mcid_req mcid_req;
+ struct pri_subcmd_mcid_rsp mcid_rsp;
} u;
};
@@ -1735,6 +1771,28 @@
#endif /* defined(STATUS_REQUEST_PLACE_HOLDER) */
/*!
+ * \brief Set the Malicious Call ID feature enable flag.
+ *
+ * \param ctrl D channel controller.
+ * \param enable TRUE to enable MCID feature.
+ *
+ * \return Nothing
+ */
+void pri_mcid_enable(struct pri *ctrl, int enable);
+
+/*!
+ * \brief Send the MCID request message.
+ *
+ * \param ctrl D channel controller.
+ * \param call Q.931 call leg
+ *
+ * \retval 0 on success. You should wait for a PRI_SUBCMD_MCID_RSP
+ * to continue clearing the call if it was in progress.
+ * \retval -1 on error.
+ */
+int pri_mcid_req_send(struct pri *ctrl, q931_call *call);
+
+/*!
* \brief Set the call completion feature enable flag.
*
* \param ctrl D channel controller.
Modified: branches/1.4/pri_facility.c
URL: http://svnview.digium.com/svn/libpri/branches/1.4/pri_facility.c?view=diff&rev=1757&r1=1756&r2=1757
==============================================================================
--- branches/1.4/pri_facility.c (original)
+++ branches/1.4/pri_facility.c Fri May 28 15:26:23 2010
@@ -3538,6 +3538,151 @@
return rose_result_ok_encode(ctrl, call, Q931_DISCONNECT, invoke_id);
} else {
return send_facility_error(ctrl, call, invoke_id, ROSE_ERROR_Gen_NotAvailable);
+ }
+}
+
+/*!
+ * \internal
+ * \brief MCIDRequest 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 mcid_req_response(enum APDU_CALLBACK_REASON reason, struct pri *ctrl, struct q931_call *call, struct apdu_event *apdu, const struct apdu_msg_data *msg)
+{
+ struct pri_subcommand *subcmd;
+ int status;
+ int fail_code;
+
+ switch (reason) {
+ case APDU_CALLBACK_REASON_TIMEOUT:
+ status = 1;/* timeout */
+ fail_code = 0;
+ break;
+ case APDU_CALLBACK_REASON_MSG_RESULT:
+ status = 0;/* success */
+ fail_code = 0;
+ break;
+ case APDU_CALLBACK_REASON_MSG_ERROR:
+ status = 2;/* error */
+ fail_code = msg->response.error->code;
+ break;
+ case APDU_CALLBACK_REASON_MSG_REJECT:
+ status = 3;/* reject */
+ fail_code = 0;
+ fail_code = msg->response.reject->code;
+ break;
+ default:
+ return 1;
+ }
+ subcmd = q931_alloc_subcommand(ctrl);
+ if (subcmd) {
+ /* Indicate that our MCID request has completed. */
+ subcmd->cmd = PRI_SUBCMD_MCID_RSP;
+ subcmd->u.mcid_rsp.status = status;
+ subcmd->u.mcid_rsp.fail_code = fail_code;
+ } else {
+ /* Oh, well. */
+ }
+ return 1;
+}
+
+/*!
+ * \internal
+ * \brief Encode a MCIDRequest 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_mcid_req(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_MCIDRequest;
+
+ pos = rose_encode_invoke(ctrl, pos, end, &msg);
+
+ return pos;
+}
+
+/*!
+ * \internal
+ * \brief Encode and queue a MCID request message.
+ *
+ * \param ctrl D channel controller for diagnostic messages or global options.
+ * \param call Call leg from which to encode message.
+ *
+ * \retval 0 on success.
+ * \retval -1 on error.
+ */
+static int rose_mcid_req_encode(struct pri *ctrl, q931_call *call)
+{
+ unsigned char buffer[256];
+ unsigned char *end;
+ struct apdu_callback_data response;
+
+ switch (ctrl->switchtype) {
+ case PRI_SWITCH_EUROISDN_E1:
+ case PRI_SWITCH_EUROISDN_T1:
+ end = enc_etsi_mcid_req(ctrl, buffer, buffer + sizeof(buffer), call);
+ break;
+ default:
+ return -1;
+ }
+ if (!end) {
+ return -1;
+ }
+
+ memset(&response, 0, sizeof(response));
+ response.invoke_id = ctrl->last_invoke;
+ response.timeout_time = ctrl->timers[PRI_TIMER_T_RESPONSE];
+ response.callback = mcid_req_response;
+
+ return pri_call_apdu_queue(call, Q931_FACILITY, buffer, end - buffer, &response);
+}
+
+int pri_mcid_req_send(struct pri *ctrl, q931_call *call)
+{
+ if (!ctrl || !call) {
+ return -1;
+ }
+ if (call->cc.originated) {
+ /* We can only send MCID if we answered the call. */
+ return -1;
+ }
+
+ if (rose_mcid_req_encode(ctrl, call) || q931_facility(ctrl, call)) {
+ pri_message(ctrl,
+ "Could not schedule facility message for MCID request message.\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+void pri_mcid_enable(struct pri *ctrl, int enable)
+{
+ if (ctrl) {
+ ctrl = PRI_MASTER(ctrl);
+ ctrl->mcid_support = enable ? 1 : 0;
}
}
@@ -4375,6 +4520,44 @@
call->cc.record = cc_record;
pri_cc_event(ctrl, call, cc_record, CC_EVENT_AVAILABLE);
break;
+ case ROSE_ETSI_MCIDRequest:
+ if (q931_is_dummy_call(call)) {
+ /* Don't even dignify this with a response. */
+ break;
+ }
+ if (!PRI_MASTER(ctrl)->mcid_support) {
+ send_facility_error(ctrl, call, invoke->invoke_id,
+ ROSE_ERROR_Gen_NotSubscribed);
+ break;
+ }
+ if (!call->cc.originated) {
+ send_facility_error(ctrl, call, invoke->invoke_id,
+ ROSE_ERROR_Gen_NotIncomingCall);
+ break;
+ }
+ switch (call->ourcallstate) {
+ case Q931_CALL_STATE_ACTIVE:
+ case Q931_CALL_STATE_DISCONNECT_INDICATION:
+ case Q931_CALL_STATE_DISCONNECT_REQUEST:/* XXX We are really in the wrong state for this mode. */
+ subcmd = q931_alloc_subcommand(ctrl);
+ if (!subcmd) {
+ send_facility_error(ctrl, call, invoke->invoke_id,
+ ROSE_ERROR_Gen_NotAvailable);
+ break;
+ }
+
+ subcmd->cmd = PRI_SUBCMD_MCID_REQ;
+ q931_party_id_copy_to_pri(&subcmd->u.mcid_req.originator, &call->local_id);
+ q931_party_id_copy_to_pri(&subcmd->u.mcid_req.answerer, &call->remote_id);
+
+ send_facility_result_ok(ctrl, call, invoke->invoke_id);
+ break;
+ default:
+ send_facility_error(ctrl, call, invoke->invoke_id,
+ ROSE_ERROR_Gen_InvalidCallState);
+ break;
+ }
+ break;
case ROSE_QSIG_CallingName:
/* CallingName is put in remote_id.name */
rose_copy_name_to_q931(ctrl, &call->remote_id.name,
Modified: branches/1.4/pri_internal.h
URL: http://svnview.digium.com/svn/libpri/branches/1.4/pri_internal.h?view=diff&rev=1757&r1=1756&r2=1757
==============================================================================
--- branches/1.4/pri_internal.h (original)
+++ branches/1.4/pri_internal.h Fri May 28 15:26:23 2010
@@ -109,6 +109,7 @@
unsigned int transfer_support:1;/* TRUE if the upper layer supports ECT */
unsigned int aoc_support:1;/* TRUE if can send AOC events to the upper layer. */
unsigned int manual_connect_ack:1;/* TRUE if the CONNECT_ACKNOWLEDGE is sent with API call */
+ unsigned int mcid_support:1;/* TRUE if the upper layer supports MCID */
/* MDL variables */
int mdl_error;
Modified: branches/1.4/rose.c
URL: http://svnview.digium.com/svn/libpri/branches/1.4/rose.c?view=diff&rev=1757&r1=1756&r2=1757
==============================================================================
--- branches/1.4/rose.c (original)
+++ branches/1.4/rose.c Fri May 28 15:26:23 2010
@@ -531,6 +531,16 @@
rose_enc_etsi_CCNR_T_Request_ARG, rose_enc_etsi_CCNR_T_Request_RES,
rose_dec_etsi_CCNR_T_Request_ARG, rose_dec_etsi_CCNR_T_Request_RES
},
+
+ /*
+ * localValue's from MCID-Operations
+ * {ccitt identified-organization etsi(0) 130 operations-and-errors(1)}
+ */
+ {
+ ROSE_ETSI_MCIDRequest, NULL, 3,
+ NULL, NULL,
+ NULL, NULL
+ },
/* *INDENT-ON* */
};
@@ -1390,6 +1400,8 @@
{ ROSE_ETSI_CCBS_T_Request, "ROSE_ETSI_CCBS_T_Request" },
{ ROSE_ETSI_CCNR_T_Request, "ROSE_ETSI_CCNR_T_Request" },
+
+ { ROSE_ETSI_MCIDRequest, "ROSE_ETSI_MCIDRequest" },
{ ROSE_QSIG_CallingName, "ROSE_QSIG_CallingName" },
{ ROSE_QSIG_CalledName, "ROSE_QSIG_CalledName" },
Modified: branches/1.4/rose.h
URL: http://svnview.digium.com/svn/libpri/branches/1.4/rose.h?view=diff&rev=1757&r1=1756&r2=1757
==============================================================================
--- branches/1.4/rose.h (original)
+++ branches/1.4/rose.h Fri May 28 15:26:23 2010
@@ -133,6 +133,9 @@
/* ETSI CCNR-private-networks-Operations-and-Errors */
ROSE_ETSI_CCNR_T_Request, /*!< Invoke/Result */
+
+ /* ETSI MCID-Operations */
+ ROSE_ETSI_MCIDRequest, /*!< Invoke/Result */
/* Q.SIG Name-Operations */
ROSE_QSIG_CallingName, /*!< Invoke only */
Modified: branches/1.4/rosetest.c
URL: http://svnview.digium.com/svn/libpri/branches/1.4/rosetest.c?view=diff&rev=1757&r1=1756&r2=1757
==============================================================================
--- branches/1.4/rosetest.c (original)
+++ branches/1.4/rosetest.c Fri May 28 15:26:23 2010
@@ -1388,6 +1388,13 @@
.component.result.operation = ROSE_ETSI_CCNR_T_Request,
.component.result.invoke_id = 53,
.component.result.args.etsi.CCNR_T_Request.retention_supported = 1,
+ },
+
+ /* MCID */
+ {
+ .type = ROSE_COMP_TYPE_INVOKE,
+ .component.invoke.operation = ROSE_ETSI_MCIDRequest,
+ .component.invoke.invoke_id = 54,
},
/* *INDENT-ON* */
};
More information about the svn-commits
mailing list