[libpri-commits] dvossel: branch dvossel/aoc_send r1591 - /team/dvossel/aoc_send/

SVN commits to the libpri project libpri-commits at lists.digium.com
Tue Apr 13 15:07:28 CDT 2010


Author: dvossel
Date: Tue Apr 13 15:07:26 2010
New Revision: 1591

URL: http://svnview.digium.com/svn/libpri?view=rev&rev=1591
Log:
handle AOC-S msg on request response correctly

Modified:
    team/dvossel/aoc_send/libpri.h
    team/dvossel/aoc_send/pri_aoc.c

Modified: team/dvossel/aoc_send/libpri.h
URL: http://svnview.digium.com/svn/libpri/team/dvossel/aoc_send/libpri.h?view=diff&rev=1591&r1=1590&r2=1591
==============================================================================
--- team/dvossel/aoc_send/libpri.h (original)
+++ team/dvossel/aoc_send/libpri.h Tue Apr 13 15:07:26 2010
@@ -653,55 +653,6 @@
 	int invoke_id;
 };
 
-enum PRI_AOC_REQUEST_RESPONSE {
-
-	/* Error Results */
-	PRI_AOC_REQUEST_RESPONSE_ERROR_NOT_IMPLEMENTED,
-	PRI_AOC_REQUEST_RESPONSE_ERROR_NOT_AVAILABLE,
-	PRI_AOC_REQUEST_RESPONSE_ERROR_TIMEOUT,
-	/* generic error result all other errors are lumped into */
-	PRI_AOC_REQUEST_RESPONSE_ERROR,
-
-	/* AOC Results */
-	PRI_AOC_REQUEST_RESPONSE_CURRENCY_INFO_LIST,
-	PRI_AOC_REQUEST_RESPONSE_SPECIAL_ARG,
-	PRI_AOC_REQUEST_RESPONSE_CHARGING_INFO_FOLLOWS,
-};
-
-enum PRI_AOC_REQUEST {
-	PRI_AOC_REQUEST_S = (1 << 0),
-	PRI_AOC_REQUEST_D = (1 << 1),
-	PRI_AOC_REQUEST_E = (1 << 2),
-};
-
-struct pri_subcmd_aoc_request_response {
-	/*!
-	 * \brief What type of aoc was requested.
-	 * \see enum PRI_AOC_REQUEST
-	 */
-	int charging_request;
-
-	/*!
-	 * \brief response to the charging_request
-	 * \see enum PRI_AOC_REQUEST_RESPONSE
-	 */
-	int charging_response;
-
-};
-
-struct pri_subcmd_aoc_request {
-	/*!
-	 * \brief What types of aoc are being requested.
-	 * \see enum PRI_AOC_REQUEST
-	 */
-	int charging_request;
-
-	/*!
-	 * \brief Value given by the initiating request.
-	 */
-	 int invoke_id;
-};
-
 /*! \brief What is being charged. */
 enum PRI_AOC_CHARGED_ITEM {
 	PRI_AOC_CHARGED_ITEM_NOT_AVAILABLE,
@@ -712,6 +663,7 @@
 	PRI_AOC_CHARGED_ITEM_USER_USER_INFO,
 	PRI_AOC_CHARGED_ITEM_SUPPLEMENTARY_SERVICE,
 };
+
 /*! \brief Rate method being used. */
 enum PRI_AOC_RATE_TYPE {
 	PRI_AOC_RATE_TYPE_NOT_AVAILABLE,
@@ -722,6 +674,7 @@
 	PRI_AOC_RATE_TYPE_VOLUME,
 	PRI_AOC_RATE_TYPE_SPECIAL_CODE,
 };
+
 enum PRI_AOC_TIME_SCALE {
 	PRI_AOC_TIME_SCALE_HUNDREDTH_SECOND,
 	PRI_AOC_TIME_SCALE_TENTH_SECOND,
@@ -731,12 +684,14 @@
 	PRI_AOC_TIME_SCALE_HOUR,
 	PRI_AOC_TIME_SCALE_DAY,
 };
+
 struct pri_aoc_time {
 	/*! LengthOfTimeUnit (Not valid if length is zero.) */
 	long length;
 	/*! \see enum PRI_AOC_TIME_SCALE */
 	int scale;
 };
+
 enum PRI_AOC_MULTIPLIER {
 	PRI_AOC_MULTIPLIER_THOUSANDTH,
 	PRI_AOC_MULTIPLIER_HUNDREDTH,
@@ -746,11 +701,13 @@
 	PRI_AOC_MULTIPLIER_HUNDRED,
 	PRI_AOC_MULTIPLIER_THOUSAND,
 };
+
 struct pri_aoc_amount {
 	long cost;
 	/*! \see enum PRI_AOC_MULTIPLIER */
 	int multiplier;
 };
+
 struct pri_aoc_duration {
 	struct pri_aoc_amount amount;
 	struct pri_aoc_time time;
@@ -766,16 +723,19 @@
 	/*! Name of currency involved.  Null terminated. */
 	char currency[10 + 1];
 };
+
 struct pri_aoc_flat {
 	struct pri_aoc_amount amount;
 	/*! Name of currency involved.  Null terminated. */
 	char currency[10 + 1];
 };
+
 enum PRI_AOC_VOLUME_UNIT {
 	PRI_AOC_VOLUME_UNIT_OCTET,
 	PRI_AOC_VOLUME_UNIT_SEGMENT,
 	PRI_AOC_VOLUME_UNIT_MESSAGE,
 };
+
 struct pri_aoc_volume {
 	struct pri_aoc_amount amount;
 	/*! \see enum PRI_AOC_VOLUME_UNIT */
@@ -803,6 +763,7 @@
 		int special;
 	} rate;
 };
+
 struct pri_subcmd_aoc_s {
 	int num_items;
 	struct pri_aoc_s_element item[10];
@@ -814,17 +775,20 @@
 	PRI_AOC_DE_CHARGE_CURRENCY,
 	PRI_AOC_DE_CHARGE_UNITS,
 };
+
 struct pri_aoc_recorded_currency {
 	struct pri_aoc_amount amount;
 	/*! Name of currency involved.  Null terminated. */
 	char currency[10 + 1];
 };
+
 struct pri_aoc_units_element {
 	/*! Number of units recorded. -1 if not available. */
 	long number;
 	/*! Type of unit recorded. -1 if not available. */
 	int type;
 };
+
 struct pri_aoc_recorded_units {
 	int num_items;
 	struct pri_aoc_units_element item[32];
@@ -870,11 +834,13 @@
 	PRI_AOC_E_BILLING_ID_CALL_DEFLECTION,
 	PRI_AOC_E_BILLING_ID_CALL_TRANSFER,
 };
+
 enum PRI_AOC_E_CHARGING_ASSOCIATION {
 	PRI_AOC_E_CHARGING_ASSOCIATION_NOT_AVAILABLE,
 	PRI_AOC_E_CHARGING_ASSOCIATION_NUMBER,
 	PRI_AOC_E_CHARGING_ASSOCIATION_ID,
 };
+
 struct pri_aoc_e_charging_association {
 	union {
 		/*! Charged number */
@@ -885,6 +851,7 @@
 	/*! \see enum PRI_AOC_E_CHARGING_ASSOCIATION */
 	int charging_type;
 };
+
 struct pri_subcmd_aoc_e {
 	/*!
 	 * \brief What is being charged.
@@ -901,6 +868,65 @@
 	} recorded;
 	/*! Charging association. */
 	struct pri_aoc_e_charging_association associated;
+};
+
+enum PRI_AOC_REQUEST_RESPONSE {
+
+	/* Error Results */
+	PRI_AOC_REQUEST_RESPONSE_ERROR_NOT_IMPLEMENTED,
+	PRI_AOC_REQUEST_RESPONSE_ERROR_NOT_AVAILABLE,
+	PRI_AOC_REQUEST_RESPONSE_ERROR_TIMEOUT,
+	/* generic error result all other errors are lumped into */
+	PRI_AOC_REQUEST_RESPONSE_ERROR,
+
+	/* AOC Results */
+	PRI_AOC_REQUEST_RESPONSE_CHARGING_INFO_FOLLOWS,
+	PRI_AOC_REQUEST_RESPONSE_CURRENCY_INFO_LIST,
+	PRI_AOC_REQUEST_RESPONSE_SPECIAL_ARG,
+};
+
+enum PRI_AOC_REQUEST {
+	PRI_AOC_REQUEST_S = (1 << 0),
+	PRI_AOC_REQUEST_D = (1 << 1),
+	PRI_AOC_REQUEST_E = (1 << 2),
+};
+
+struct pri_subcmd_aoc_request_response {
+
+	/*!
+	 * \brief aoc_s data from response
+	 */
+	struct pri_subcmd_aoc_s aoc_s;
+
+	/*!
+	 * \brief if the aoc_s msg is present, this will be set
+	 */
+	int valid_aoc_s;
+
+	/*!
+	 * \brief What type of aoc was requested.
+	 * \see enum PRI_AOC_REQUEST
+	 */
+	int charging_request;
+
+	/*!
+	 * \brief response to the charging_request
+	 * \see enum PRI_AOC_REQUEST_RESPONSE
+	 */
+	int charging_response;
+};
+
+struct pri_subcmd_aoc_request {
+	/*!
+	 * \brief What types of aoc are being requested.
+	 * \see enum PRI_AOC_REQUEST
+	 */
+	int charging_request;
+
+	/*!
+	 * \brief Value given by the initiating request.
+	 */
+	 int invoke_id;
 };
 
 struct pri_subcommand {
@@ -1523,9 +1549,11 @@
 /* Request AOC on call setup */
 int pri_sr_set_aoc_charging_request(struct pri_sr *sr, int charging_request);
 
-
-/* Send AOC-Request message */
-int pri_aoc_charging_request_response(struct pri *ctrl, q931_call *call, int response, const struct pri_subcmd_aoc_request *aoc_request);
+/* Send AOC Request Response to a request for AOC-S */
+int pri_aoc_s_request_response_send(struct pri *ctrl, q931_call *call, const int invoke_id, const struct pri_subcmd_aoc_s *aoc_s);
+
+/* Send AOC Request Response to a request for AOC-D or AOC-E */
+int pri_aoc_de_request_response_send(struct pri *ctrl, q931_call *call, const int response, const int invoke_id);
 
 /* Send AOC-Request message */
 int pri_aoc_charging_request_send(struct pri *ctrl, q931_call *c, const struct pri_subcmd_aoc_request *aoc_request);

Modified: team/dvossel/aoc_send/pri_aoc.c
URL: http://svnview.digium.com/svn/libpri/team/dvossel/aoc_send/pri_aoc.c?view=diff&rev=1591&r1=1590&r2=1591
==============================================================================
--- team/dvossel/aoc_send/pri_aoc.c (original)
+++ team/dvossel/aoc_send/pri_aoc.c Tue Apr 13 15:07:26 2010
@@ -170,6 +170,7 @@
 
 	subcmd->u.aoc_request.invoke_id = invoke->invoke_id;
 	switch (invoke->args.etsi.ChargingRequest.charging_case) {
+	default:
 	case 0:
 		subcmd->u.aoc_request.charging_request = PRI_AOC_REQUEST_S;
 		break;
@@ -179,8 +180,6 @@
 	case 2:
 		subcmd->u.aoc_request.charging_request = PRI_AOC_REQUEST_E;
 		break;
-	default:
-		subcmd->u.aoc_request.charging_request = PRI_AOC_REQUEST_S;
 	}
 }
 
@@ -1160,28 +1159,39 @@
  * \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 aoc_request, the aoc charging request data to encode.
+ * \param response, the response to the request
+ * \param invoke_id, the request's invoke id
+ * \param aoc_s, the rate list associated with a response to AOC-S request
  *
  * \retval Start of the next ASN.1 component to encode on success.
  * \retval NULL on error.
  */
 static unsigned char *enc_etsi_aoc_request_response(struct pri *ctrl, unsigned char *pos,
-	unsigned char *end, int response, int invoke_id)
+	unsigned char *end, int response, int invoke_id, const struct pri_subcmd_aoc_s *aoc_s)
 {
 	struct rose_msg_result msg_result = { 0, };
 	struct rose_msg_error msg_error = { 0, };
 	int is_error = 0;
 	pos = facility_encode_header(ctrl, pos, end, NULL);
+
 	if (!pos) {
 		return NULL;
 	}
 
 	switch (response) {
 	case PRI_AOC_REQUEST_RESPONSE_CURRENCY_INFO_LIST:
+		if (!aoc_s) {
+			return NULL;
+		}
+		enc_etsi_subcmd_aoc_s_currency_info(aoc_s, &msg_result.args.etsi.ChargingRequest.u.currency_info);
 		msg_result.args.etsi.ChargingRequest.type = 0;
 		break;
 	case PRI_AOC_REQUEST_RESPONSE_SPECIAL_ARG:
+		if (!aoc_s) {
+			return NULL;
+		}
 		msg_result.args.etsi.ChargingRequest.type = 1;
+		msg_result.args.etsi.ChargingRequest.u.special_arrangement = aoc_s->item[0].rate.special;
 		break;
 	case PRI_AOC_REQUEST_RESPONSE_CHARGING_INFO_FOLLOWS:
 		msg_result.args.etsi.ChargingRequest.type = 2;
@@ -1259,7 +1269,7 @@
 
 /*!
  * \internal
- * \brief Send the ETSI AOC Request Response message.
+ * \brief Send the ETSI AOC Request Response message for an AOC-S request
  *
  * \param ctrl D channel controller for diagnostic messages or global options.
  * \param call Call leg from which to encode AOC.
@@ -1269,12 +1279,19 @@
  * \retval 0 on success.
  * \retval -1 on error.
  */
-static int aoc_charging_request_response_encode(struct pri *ctrl, q931_call *call, int response, const struct pri_subcmd_aoc_request *aoc_request)
+static int aoc_s_request_response_encode(struct pri *ctrl, q931_call *call, const int invoke_id, const struct pri_subcmd_aoc_s *aoc_s)
 {
 	unsigned char buffer[255];
 	unsigned char *end = 0;
-
-	end = enc_etsi_aoc_request_response(ctrl, buffer, buffer + sizeof(buffer), response, aoc_request->invoke_id);
+	int response = PRI_AOC_REQUEST_RESPONSE_ERROR_NOT_AVAILABLE;
+
+	if (aoc_s && aoc_s->item[0].chargeable == PRI_AOC_CHARGED_ITEM_SPECIAL_ARRANGEMENT) {
+		response = PRI_AOC_REQUEST_RESPONSE_SPECIAL_ARG;
+	} else if (aoc_s) {
+		response = PRI_AOC_REQUEST_RESPONSE_CURRENCY_INFO_LIST;
+	}
+
+	end = enc_etsi_aoc_request_response(ctrl, buffer, buffer + sizeof(buffer), response, invoke_id, aoc_s);
 
 	if (!end) {
 		return -1;
@@ -1289,10 +1306,55 @@
 	}
 
 	return 0;
-
-}
-
-
+}
+
+
+/*!
+ * \internal
+ * \brief Send the ETSI AOC Request Response message for AOC-D and AOC-E requests
+ *
+ * \param ctrl D channel controller for diagnostic messages or global options.
+ * \param call Call leg from which to encode AOC.
+ * \param response code
+ * \param invoke_id
+ *
+ * \retval 0 on success.
+ * \retval -1 on error.
+ */
+static int aoc_de_request_response_encode(struct pri *ctrl, q931_call *call, const int response, const int invoke_id)
+{
+	unsigned char buffer[255];
+	unsigned char *end = 0;
+
+	end = enc_etsi_aoc_request_response(ctrl, buffer, buffer + sizeof(buffer), response, invoke_id, NULL);
+
+	if (!end) {
+		return -1;
+	}
+
+	/* Remember that if we queue a facility IE for a facility message we
+	 * have to explicitly send the facility message ourselves */
+	if (pri_call_apdu_queue(call, Q931_FACILITY, buffer, end - buffer, NULL)
+		|| q931_facility(call->pri, call)) {
+		pri_message(ctrl, "Could not schedule aoc request response facility message for call %d\n", call->cr);
+		return -1;
+	}
+
+	return 0;
+}
+
+/*!
+ * \internal
+ * \brief AOC-Request 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 pri_aoc_request_get_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;
@@ -1336,10 +1398,19 @@
 	case APDU_CALLBACK_REASON_MSG_RESULT:
 		switch (msg->response.result->args.etsi.ChargingRequest.type) {
 		case 0:
+			subcmd->u.aoc_request_response.valid_aoc_s = 1;
 			subcmd->u.aoc_request_response.charging_response = PRI_AOC_REQUEST_RESPONSE_CURRENCY_INFO_LIST;
+			aoc_etsi_subcmd_aoc_s_currency_info(&subcmd->u.aoc_request_response.aoc_s,
+				&msg->response.result->args.etsi.ChargingRequest.u.currency_info);
 			break;
 		case 1:
+			subcmd->u.aoc_request_response.valid_aoc_s = 1;
 			subcmd->u.aoc_request_response.charging_response = PRI_AOC_REQUEST_RESPONSE_SPECIAL_ARG;
+			subcmd->u.aoc_request_response.aoc_s.num_items = 1;
+			subcmd->u.aoc_request_response.aoc_s.item[0].chargeable = PRI_AOC_CHARGED_ITEM_SPECIAL_ARRANGEMENT;
+			subcmd->u.aoc_request_response.aoc_s.item[0].rate_type = PRI_AOC_RATE_TYPE_SPECIAL_CODE;
+			subcmd->u.aoc_request_response.aoc_s.item[0].rate.special =
+				msg->response.result->args.etsi.ChargingRequest.u.special_arrangement;
 			break;
 		case 2:
 			subcmd->u.aoc_request_response.charging_response = PRI_AOC_REQUEST_RESPONSE_CHARGING_INFO_FOLLOWS;
@@ -1354,7 +1425,7 @@
 		break;
 	}
 
-	return 0;
+	return 1;
 }
 
 /*!
@@ -1382,7 +1453,9 @@
 
 	memset(&response, 0, sizeof(response));
 	response.invoke_id = ctrl->last_invoke;
-	response.timeout_time = ctrl->timers[PRI_TIMER_T_CCBS1];
+	 /* Set a custom timeout period. Wait 60 seconds for AOC-S response
+	  * TODO, this may need to be configurable */
+	response.timeout_time = 60000;
 	response.callback = pri_aoc_request_get_response;
 	response.user.ptr = (void *) &request;
 
@@ -1512,7 +1585,7 @@
 	return 0;
 }
 
-int pri_aoc_charging_request_response(struct pri *ctrl, q931_call *call, int response, const struct pri_subcmd_aoc_request *aoc_request)
+int pri_aoc_de_request_response_send(struct pri *ctrl, q931_call *call, const int response, const int invoke_id)
 {
 	if (!ctrl || !call)
 		return -1;
@@ -1520,7 +1593,25 @@
 	switch (ctrl->switchtype) {
 	case PRI_SWITCH_EUROISDN_E1:
 	case PRI_SWITCH_EUROISDN_T1:
-		return aoc_charging_request_response_encode(ctrl, call, response, aoc_request);
+		return aoc_de_request_response_encode(ctrl, call, response, invoke_id);
+	case PRI_SWITCH_QSIG:
+		break;
+	default:
+		return -1;
+	}
+
+	return 0;
+}
+
+int pri_aoc_s_request_response_send(struct pri *ctrl, q931_call *call, const int invoke_id, const struct pri_subcmd_aoc_s *aoc_s)
+{
+	if (!ctrl || !call)
+		return -1;
+
+	switch (ctrl->switchtype) {
+	case PRI_SWITCH_EUROISDN_E1:
+	case PRI_SWITCH_EUROISDN_T1:
+		return aoc_s_request_response_encode(ctrl, call, invoke_id, aoc_s);
 	case PRI_SWITCH_QSIG:
 		break;
 	default:




More information about the libpri-commits mailing list