[libpri-commits] dvossel: branch dvossel/aoc_send r1574 - /team/dvossel/aoc_send/
SVN commits to the libpri project
libpri-commits at lists.digium.com
Tue Apr 6 13:05:16 CDT 2010
Author: dvossel
Date: Tue Apr 6 13:05:14 2010
New Revision: 1574
URL: http://svnview.digium.com/svn/libpri?view=rev&rev=1574
Log:
ETSI aoc-s send routines
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=1574&r1=1573&r2=1574
==============================================================================
--- team/dvossel/aoc_send/libpri.h (original)
+++ team/dvossel/aoc_send/libpri.h Tue Apr 6 13:05:14 2010
@@ -1530,6 +1530,9 @@
/* Send AOC-Request message */
int pri_aoc_charging_request_send(struct pri *ctrl, q931_call *c, const struct pri_subcmd_aoc_request *aoc_request);
+/* Send AOC-S message */
+int pri_aoc_s_send(struct pri *ctrl, q931_call *c, const struct pri_subcmd_aoc_s *aoc_s);
+
/* Send AOC-D message */
int pri_aoc_d_send(struct pri *ctrl, q931_call *c, const struct pri_subcmd_aoc_d *aoc_d);
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=1574&r1=1573&r2=1574
==============================================================================
--- team/dvossel/aoc_send/pri_aoc.c (original)
+++ team/dvossel/aoc_send/pri_aoc.c Tue Apr 6 13:05:14 2010
@@ -57,6 +57,21 @@
/*!
* \internal
+ * \brief Fill in the ETSI amount from the AOC subcmd amount.
+ *
+ * \param subcmd_amount AOC subcmd amount.
+ * \param etsi_amount AOC ETSI amount.
+ *
+ * \return Nothing
+ */
+static void aoc_enc_etsi_subcmd_amount(const struct pri_aoc_amount *subcmd_amount, struct roseEtsiAOCAmount *etsi_amount)
+{
+ etsi_amount->currency = subcmd_amount->cost;
+ etsi_amount->multiplier = subcmd_amount->multiplier;
+}
+
+/*!
+ * \internal
* \brief Fill in the AOC subcmd time from the ETSI time.
*
* \param subcmd_time AOC subcmd time.
@@ -68,6 +83,21 @@
{
subcmd_time->length = etsi_time->length;
subcmd_time->scale = etsi_time->scale;
+}
+
+/*!
+ * \internal
+ * \brief Fill in the ETSI Time from the AOC subcmd time.
+ *
+ * \param subcmd_time AOC subcmd time.
+ * \param etsi_time AOC ETSI time.
+ *
+ * \return Nothing
+ */
+static void aoc_enc_etsi_subcmd_time(const struct pri_aoc_time *subcmd_time, struct roseEtsiAOCTime *etsi_time)
+{
+ etsi_time->length = subcmd_time->length;
+ etsi_time->scale = subcmd_time->scale;
}
/*!
@@ -247,6 +277,94 @@
}
/*!
+ * \internal
+ * \brief Fill in the currency info list of chargeable items from a aoc_s subcmd
+ *
+ * \param aoc_s AOC-S info list of chargeable items.
+ * \param info ETSI info list of chargeable items.
+ *
+ * \return Nothing
+ */
+static void enc_etsi_subcmd_aoc_s_currency_info(const struct pri_subcmd_aoc_s *aoc_s, struct roseEtsiAOCSCurrencyInfoList *info)
+{
+ int idx;
+
+ for (idx = 0; idx < aoc_s->num_items && idx < ARRAY_LEN(info->list); ++idx) {
+ /* What is being charged. */
+ switch (aoc_s->item[idx].chargeable) {
+ default:
+ case PRI_AOC_CHARGED_ITEM_BASIC_COMMUNICATION:
+ info->list[idx].charged_item = 0;
+ break;
+ case PRI_AOC_CHARGED_ITEM_CALL_ATTEMPT:
+ info->list[idx].charged_item = 1;
+ break;
+ case PRI_AOC_CHARGED_ITEM_CALL_SETUP:
+ info->list[idx].charged_item = 2;
+ break;
+ case PRI_AOC_CHARGED_ITEM_USER_USER_INFO:
+ info->list[idx].charged_item = 3;
+ break;
+ case PRI_AOC_CHARGED_ITEM_SUPPLEMENTARY_SERVICE:
+ info->list[idx].charged_item = 4;
+ break;
+ }
+
+ /* Rate method being used. */
+ switch (aoc_s->item[idx].rate_type) {
+ case PRI_AOC_RATE_TYPE_SPECIAL_CODE:
+ info->list[idx].currency_type = 0;
+ info->list[idx].u.special_charging_code = aoc_s->item[idx].rate.special;
+ break;
+ case PRI_AOC_RATE_TYPE_DURATION:
+ info->list[idx].currency_type = 1;
+ aoc_enc_etsi_subcmd_amount(&aoc_s->item[idx].rate.duration.amount,
+ &info->list[idx].u.duration.amount);
+ aoc_enc_etsi_subcmd_time(&aoc_s->item[idx].rate.duration.time,
+ &info->list[idx].u.duration.time);
+ if (aoc_s->item[idx].rate.duration.granularity.length) {
+ info->list[idx].u.duration.granularity_present = 1;
+ aoc_enc_etsi_subcmd_time(&aoc_s->item[idx].rate.duration.granularity,
+ &info->list[idx].u.duration.granularity);
+ } else {
+ info->list[idx].u.duration.granularity_present = 0;
+ }
+ info->list[idx].u.duration.charging_type = aoc_s->item[idx].rate.duration.charging_type;
+ libpri_copy_string((char *) info->list[idx].u.duration.currency,
+ aoc_s->item[idx].rate.duration.currency,
+ sizeof((char *) info->list[idx].u.duration.currency));
+ break;
+ case PRI_AOC_RATE_TYPE_FLAT:
+ info->list[idx].currency_type = 2;
+
+ aoc_enc_etsi_subcmd_amount(&aoc_s->item[idx].rate.flat.amount,
+ &info->list[idx].u.flat_rate.amount);
+ libpri_copy_string((char *) info->list[idx].u.flat_rate.currency,
+ aoc_s->item[idx].rate.flat.currency,
+ sizeof((char *) info->list[idx].u.flat_rate.currency));
+ break;
+ case PRI_AOC_RATE_TYPE_VOLUME:
+ info->list[idx].currency_type = 3;
+ aoc_enc_etsi_subcmd_amount(&aoc_s->item[idx].rate.volume.amount,
+ &info->list[idx].u.volume_rate.amount);
+ info->list[idx].u.volume_rate.unit = aoc_s->item[idx].rate.volume.unit;
+ libpri_copy_string((char *) info->list[idx].u.volume_rate.currency,
+ aoc_s->item[idx].rate.volume.currency,
+ sizeof((char *) info->list[idx].u.volume_rate.currency));
+ break;
+ case PRI_AOC_RATE_TYPE_FREE:
+ info->list[idx].currency_type = 4;
+ break;
+ case PRI_AOC_RATE_TYPE_NOT_AVAILABLE:
+ default:
+ info->list[idx].currency_type = 5;
+ break;
+ }
+ info->num_records++;
+ }
+}
+
+/*!
* \brief Handle the ETSI AOCSCurrency message.
*
* \param ctrl D channel controller for diagnostic messages or global options.
@@ -961,6 +1079,82 @@
/*!
* \internal
+ * \brief Encode the ETSI AOCSSpecialArr invoke 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 aoc_s, the aoc-s data to encode.
+ *
+ * \retval Start of the next ASN.1 component to encode on success.
+ * \retval NULL on error.
+ */
+static unsigned char *enc_etsi_aocs_special_arrangement(struct pri *ctrl, unsigned char *pos,
+ unsigned char *end, const struct pri_subcmd_aoc_s *aoc_s)
+{
+ struct rose_msg_invoke msg;
+
+ pos = facility_encode_header(ctrl, pos, end, NULL);
+ if (!pos) {
+ return NULL;
+ }
+
+ memset(&msg, 0, sizeof(msg));
+ msg.operation = ROSE_ETSI_AOCSSpecialArr;
+ msg.invoke_id = get_invokeid(ctrl);
+
+ if (!aoc_s->num_items || (aoc_s->item[0].rate_type != PRI_AOC_RATE_TYPE_SPECIAL_CODE)) {
+ msg.args.etsi.AOCSSpecialArr.type = 0;
+ } else {
+ msg.args.etsi.AOCSSpecialArr.type = 1;
+ msg.args.etsi.AOCSSpecialArr.special_arrangement = aoc_s->item[0].rate.special;
+ }
+
+ pos = rose_encode_invoke(ctrl, pos, end, &msg);
+
+ return pos;
+}
+
+/*!
+ * \internal
+ * \brief Encode the ETSI AOCSCurrency invoke 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 aoc_s, the aoc-s data to encode.
+ *
+ * \retval Start of the next ASN.1 component to encode on success.
+ * \retval NULL on error.
+ */
+static unsigned char *enc_etsi_aocs_currency(struct pri *ctrl, unsigned char *pos,
+ unsigned char *end, const struct pri_subcmd_aoc_s *aoc_s)
+{
+ struct rose_msg_invoke msg;
+
+ pos = facility_encode_header(ctrl, pos, end, NULL);
+ if (!pos) {
+ return NULL;
+ }
+
+ memset(&msg, 0, sizeof(msg));
+ msg.operation = ROSE_ETSI_AOCSCurrency;
+ msg.invoke_id = get_invokeid(ctrl);
+
+ if (aoc_s->num_items) {
+ msg.args.etsi.AOCSCurrency.type = 1; /* charge list is present */
+ enc_etsi_subcmd_aoc_s_currency_info(aoc_s, &msg.args.etsi.AOCSCurrency.currency_info);
+ } else {
+ msg.args.etsi.AOCSCurrency.type = 0; /* charge not available */
+ }
+
+ pos = rose_encode_invoke(ctrl, pos, end, &msg);
+
+ return pos;
+}
+
+/*!
+ * \internal
* \brief Encode the ETSI ChargingRequest Response message
*
* \param ctrl D channel controller for diagnostic messages or global options.
@@ -1197,6 +1391,87 @@
return pri_call_apdu_queue(call, Q931_SETUP, buffer, end - buffer, &response);
}
+
+/*!
+ * \internal
+ * \brief Send the ETSI AOCS invoke message.
+ *
+ * \param ctrl D channel controller for diagnostic messages or global options.
+ * \param call Call leg from which to encode AOC.
+ * \param aoc_s, the AOC-S payload data to encode.
+ *
+ * \retval 0 on success.
+ * \retval -1 on error.
+ */
+static int aoc_aocs_encode(struct pri *ctrl, q931_call *call, const struct pri_subcmd_aoc_s *aoc_s)
+{
+ unsigned char buffer[255];
+ unsigned char *end = 0;
+
+ if (aoc_s->item[0].chargeable == PRI_AOC_CHARGED_ITEM_SPECIAL_ARRANGEMENT) {
+ end = enc_etsi_aocs_special_arrangement(ctrl, buffer, buffer + sizeof(buffer), aoc_s);
+ } else {
+ end = enc_etsi_aocs_currency(ctrl, buffer, buffer + sizeof(buffer), aoc_s);
+ }
+
+ 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-s facility message for call %d\n", call->cr);
+ return -1;
+ }
+
+ return 0;
+}
+
+/*!
+ * \internal
+ * \brief Send the ETSI AOCD invoke message.
+ *
+ * \param ctrl D channel controller for diagnostic messages or global options.
+ * \param call Call leg from which to encode AOC.
+ * \param aoc_d, the aoc_d payload data to encode.
+ *
+ * \retval 0 on success.
+ * \retval -1 on error.
+ */
+static int aoc_aocd_encode(struct pri *ctrl, q931_call *call, const struct pri_subcmd_aoc_d *aoc_d)
+{
+ unsigned char buffer[255];
+ unsigned char *end = 0;
+
+
+ switch (aoc_d->charge) {
+ case PRI_AOC_DE_CHARGE_NOT_AVAILABLE:
+ case PRI_AOC_DE_CHARGE_FREE:
+ case PRI_AOC_DE_CHARGE_CURRENCY:
+ end = enc_etsi_aocd_currency(ctrl, buffer, buffer + sizeof(buffer), aoc_d);
+ break;
+ case PRI_AOC_DE_CHARGE_UNITS:
+ end = enc_etsi_aocd_charging_unit(ctrl, buffer, buffer + sizeof(buffer), aoc_d);
+ break;
+ }
+
+ 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-d facility message for call %d\n", call->cr);
+ return -1;
+ }
+
+ return 0;
+}
+
/*!
* \internal
* \brief Send the ETSI AOCE invoke message.
@@ -1234,49 +1509,6 @@
if (pri_call_apdu_queue(call, Q931_FACILITY, buffer, end - buffer, NULL)
|| q931_facility(call->pri, call)) {
pri_message(ctrl, "Could not schedule aoc-e facility message for call %d\n", call->cr);
- return -1;
- }
-
- return 0;
-}
-
-/*!
- * \internal
- * \brief Send the ETSI AOCD invoke message.
- *
- * \param ctrl D channel controller for diagnostic messages or global options.
- * \param call Call leg from which to encode AOC.
- * \param aoc_d, the aoc_d payload data to encode.
- *
- * \retval 0 on success.
- * \retval -1 on error.
- */
-static int aoc_aocd_encode(struct pri *ctrl, q931_call *call, const struct pri_subcmd_aoc_d *aoc_d)
-{
- unsigned char buffer[255];
- unsigned char *end = 0;
-
-
- switch (aoc_d->charge) {
- case PRI_AOC_DE_CHARGE_NOT_AVAILABLE:
- case PRI_AOC_DE_CHARGE_FREE:
- case PRI_AOC_DE_CHARGE_CURRENCY:
- end = enc_etsi_aocd_currency(ctrl, buffer, buffer + sizeof(buffer), aoc_d);
- break;
- case PRI_AOC_DE_CHARGE_UNITS:
- end = enc_etsi_aocd_charging_unit(ctrl, buffer, buffer + sizeof(buffer), aoc_d);
- break;
- }
-
- 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-d facility message for call %d\n", call->cr);
return -1;
}
@@ -1331,6 +1563,24 @@
return 0;
}
+int pri_aoc_s_send(struct pri *ctrl, q931_call *call, 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_aocs_encode(ctrl, call, aoc_s);
+ case PRI_SWITCH_QSIG:
+ break;
+ default:
+ return -1;
+ }
+
+ return 0;
+}
+
int pri_aoc_d_send(struct pri *ctrl, q931_call *call, const struct pri_subcmd_aoc_d *aoc_d)
{
if (!ctrl || !call)
More information about the libpri-commits
mailing list