[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