[svn-commits] rmudgett: branch rmudgett/mcid r1546 - /team/rmudgett/mcid/

SVN commits to the Digium repositories svn-commits at lists.digium.com
Wed Mar 17 18:12:08 CDT 2010


Author: rmudgett
Date: Wed Mar 17 18:12:05 2010
New Revision: 1546

URL: http://svnview.digium.com/svn/libpri?view=rev&rev=1546
Log:
MCID API to send and receive.

Modified:
    team/rmudgett/mcid/libpri.h
    team/rmudgett/mcid/pri_facility.c
    team/rmudgett/mcid/pri_internal.h

Modified: team/rmudgett/mcid/libpri.h
URL: http://svnview.digium.com/svn/libpri/team/rmudgett/mcid/libpri.h?view=diff&rev=1546&r1=1545&r2=1546
==============================================================================
--- team/rmudgett/mcid/libpri.h (original)
+++ team/rmudgett/mcid/libpri.h Wed Mar 17 18:12:05 2010
@@ -543,6 +543,8 @@
 #define PRI_SUBCMD_AOC_S					18	/*!< Advice Of Charge Start information (Rate list) */
 #define PRI_SUBCMD_AOC_D					19	/*!< Advice Of Charge During information */
 #define PRI_SUBCMD_AOC_E					20	/*!< Advice Of Charge End information */
+#define PRI_SUBCMD_MCID_REQ					21	/*!< Malicious Call ID Request */
+#define PRI_SUBCMD_MCID_REQ_COMPLETE		22	/*!< Malicious Call ID Request completed */
 
 #if defined(STATUS_REQUEST_PLACE_HOLDER)
 struct pri_subcmd_status_request {
@@ -851,6 +853,16 @@
 	} 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 caller;
 };
 
 struct pri_subcommand {
@@ -881,6 +893,7 @@
 		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;
 	} u;
 };
 
@@ -1702,6 +1715,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_REQ_COMPLETE
+ * 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: team/rmudgett/mcid/pri_facility.c
URL: http://svnview.digium.com/svn/libpri/team/rmudgett/mcid/pri_facility.c?view=diff&rev=1546&r1=1545&r2=1546
==============================================================================
--- team/rmudgett/mcid/pri_facility.c (original)
+++ team/rmudgett/mcid/pri_facility.c Wed Mar 17 18:12:05 2010
@@ -3539,6 +3539,136 @@
 		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;
+
+	switch (reason) {
+	case APDU_CALLBACK_REASON_TIMEOUT:
+	case APDU_CALLBACK_REASON_MSG_RESULT:
+	case APDU_CALLBACK_REASON_MSG_ERROR:
+	case APDU_CALLBACK_REASON_MSG_REJECT:
+		subcmd = q931_alloc_subcommand(ctrl);
+		if (!subcmd) {
+			/* Oh, well. */
+			break;
+		}
+
+		/* Indicate that our MCID request has completed. */
+		subcmd->cmd = PRI_SUBCMD_MCID_REQ_COMPLETE;
+		break;
+	default:
+		break;
+	}
+	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_result 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_result(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 = -1;
+	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;
 	}
 }
 
@@ -4376,6 +4506,39 @@
 		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;
+		}
+		if (call->ourcallstate != Q931_CALL_STATE_ACTIVE
+			&& call->ourcallstate != Q931_CALL_STATE_DISCONNECT_INDICATION) {
+			send_facility_error(ctrl, call, invoke->invoke_id,
+				ROSE_ERROR_Gen_InvalidCallState);
+			break;
+		}
+		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.caller, &call->local_id);
+
+		send_facility_result_ok(ctrl, call, invoke->invoke_id);
+		break;
 	case ROSE_QSIG_CallingName:
 		/* CallingName is put in remote_id.name */
 		rose_copy_name_to_q931(ctrl, &call->remote_id.name,

Modified: team/rmudgett/mcid/pri_internal.h
URL: http://svnview.digium.com/svn/libpri/team/rmudgett/mcid/pri_internal.h?view=diff&rev=1546&r1=1545&r2=1546
==============================================================================
--- team/rmudgett/mcid/pri_internal.h (original)
+++ team/rmudgett/mcid/pri_internal.h Wed Mar 17 18:12:05 2010
@@ -108,6 +108,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;




More information about the svn-commits mailing list