[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