[libpri-commits] rmudgett: branch 1.4 r1737 - /branches/1.4/
SVN commits to the libpri project
libpri-commits at lists.digium.com
Fri May 28 13:03:41 CDT 2010
Author: rmudgett
Date: Fri May 28 13:03:38 2010
New Revision: 1737
URL: http://svnview.digium.com/svn/libpri?view=rev&rev=1737
Log:
ETSI Advice Of Charge (AOC) event reporting.
This feature passes ETSI AOC-S, AOC-D, and AOC-E message information to
the upper layer (i.e. Asterisk) for processing.
Relevant specification: EN 300 182
Consideration was made for the possible future addition of Q.SIG AOC
support (ECMA-212) with the events passed to the upper layer.
Review: https://reviewboard.asterisk.org/r/538/
Added:
branches/1.4/pri_aoc.c
- copied unchanged from r1736, team/rmudgett/aoc_event/pri_aoc.c
Modified:
branches/1.4/Makefile
branches/1.4/libpri.h
branches/1.4/pri_facility.c
branches/1.4/pri_facility.h
branches/1.4/pri_internal.h
branches/1.4/rose_etsi_aoc.c
Modified: branches/1.4/Makefile
URL: http://svnview.digium.com/svn/libpri/branches/1.4/Makefile?view=diff&rev=1737&r1=1736&r2=1737
==============================================================================
--- branches/1.4/Makefile (original)
+++ branches/1.4/Makefile Fri May 28 13:03:38 2010
@@ -47,6 +47,7 @@
q921.o \
prisched.o \
q931.o \
+ pri_aoc.o \
pri_cc.o \
pri_facility.o \
asn1_primitive.o \
@@ -71,6 +72,7 @@
q921.lo \
prisched.lo \
q931.lo \
+ pri_aoc.lo \
pri_cc.lo \
pri_facility.lo \
asn1_primitive.lo \
Modified: branches/1.4/libpri.h
URL: http://svnview.digium.com/svn/libpri/branches/1.4/libpri.h?view=diff&rev=1737&r1=1736&r2=1737
==============================================================================
--- branches/1.4/libpri.h (original)
+++ branches/1.4/libpri.h Fri May 28 13:03:38 2010
@@ -539,6 +539,11 @@
#define PRI_SUBCMD_CC_CANCEL 15 /*!< Unsolicited indication that CC is canceled */
#define PRI_SUBCMD_CC_STOP_ALERTING 16 /*!< Indicate that someone else has responed to remote user free */
#define PRI_SUBCMD_TRANSFER_CALL 17 /*!< Request to transfer the specified calls together. */
+#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_AOC_CHARGING_REQ 21 /*!< Advice Of Charge Request information */
+//#define PRI_SUBCMD_AOC_CHARGING_REQ_RSP 22 /*!< Advice Of Charge Request Response information */
#if defined(STATUS_REQUEST_PLACE_HOLDER)
struct pri_subcmd_status_request {
@@ -646,6 +651,227 @@
int is_call_2_held;
/*! Invocation ID to use when sending a reply to the transfer request. */
int invoke_id;
+};
+
+/*! \brief What is being charged. */
+enum PRI_AOC_CHARGED_ITEM {
+ PRI_AOC_CHARGED_ITEM_NOT_AVAILABLE,
+ PRI_AOC_CHARGED_ITEM_SPECIAL_ARRANGEMENT,
+ PRI_AOC_CHARGED_ITEM_BASIC_COMMUNICATION,
+ PRI_AOC_CHARGED_ITEM_CALL_ATTEMPT,
+ PRI_AOC_CHARGED_ITEM_CALL_SETUP,
+ 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,
+ PRI_AOC_RATE_TYPE_FREE,
+ PRI_AOC_RATE_TYPE_FREE_FROM_BEGINNING,
+ PRI_AOC_RATE_TYPE_DURATION,
+ PRI_AOC_RATE_TYPE_FLAT,
+ 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,
+ PRI_AOC_TIME_SCALE_SECOND,
+ PRI_AOC_TIME_SCALE_TEN_SECOND,
+ PRI_AOC_TIME_SCALE_MINUTE,
+ 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,
+ PRI_AOC_MULTIPLIER_TENTH,
+ PRI_AOC_MULTIPLIER_ONE,
+ PRI_AOC_MULTIPLIER_TEN,
+ 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;
+ /*! Not present if the granularity time is zero. */
+ struct pri_aoc_time granularity;
+ /*!
+ * \brief Charging interval type
+ * \details
+ * continuousCharging(0),
+ * stepFunction(1)
+ */
+ int charging_type;
+ /*! 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 */
+ int unit;
+ /*! Name of currency involved. Null terminated. */
+ char currency[10 + 1];
+};
+
+struct pri_aoc_s_element {
+ /*!
+ * \brief What is being charged.
+ * \see enum PRI_AOC_CHARGED_ITEM
+ */
+ int chargeable;
+ /*!
+ * \brief Rate method being used.
+ * \see enum PRI_AOC_RATE_TYPE
+ */
+ int rate_type;
+ /*! \brief Charge rate being applied. */
+ union {
+ struct pri_aoc_duration duration;
+ struct pri_aoc_flat flat;
+ struct pri_aoc_volume volume;
+ int special;
+ } rate;
+};
+
+struct pri_subcmd_aoc_s {
+ /*!
+ * \brief Number of items in the rate list.
+ * \note If the list is empty then the charging information is not available.
+ */
+ int num_items;
+ struct pri_aoc_s_element item[10];
+};
+
+enum PRI_AOC_DE_CHARGE {
+ PRI_AOC_DE_CHARGE_NOT_AVAILABLE,
+ PRI_AOC_DE_CHARGE_FREE,
+ 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];
+};
+
+enum PRI_AOC_D_BILLING_ID {
+ PRI_AOC_D_BILLING_ID_NOT_AVAILABLE,
+ PRI_AOC_D_BILLING_ID_NORMAL,
+ PRI_AOC_D_BILLING_ID_REVERSE,
+ PRI_AOC_D_BILLING_ID_CREDIT_CARD,
+};
+struct pri_subcmd_aoc_d {
+ /*!
+ * \brief What is being charged.
+ * \see enum PRI_AOC_DE_CHARGE
+ */
+ int charge;
+ /*!
+ * \brief Billing accumulation
+ * \details
+ * subTotal(0),
+ * total(1)
+ */
+ int billing_accumulation;
+ /*! \see enum PRI_AOC_D_BILLING_ID */
+ int billing_id;
+ union {
+ /*! Recorded currency */
+ struct pri_aoc_recorded_currency money;
+ /*! Recorded units list */
+ struct pri_aoc_recorded_units unit;
+ } recorded;
+};
+
+enum PRI_AOC_E_BILLING_ID {
+ PRI_AOC_E_BILLING_ID_NOT_AVAILABLE,
+ PRI_AOC_E_BILLING_ID_NORMAL,
+ PRI_AOC_E_BILLING_ID_REVERSE,
+ PRI_AOC_E_BILLING_ID_CREDIT_CARD,
+ PRI_AOC_E_BILLING_ID_CALL_FORWARDING_UNCONDITIONAL,
+ PRI_AOC_E_BILLING_ID_CALL_FORWARDING_BUSY,
+ PRI_AOC_E_BILLING_ID_CALL_FORWARDING_NO_REPLY,
+ 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 */
+ struct pri_party_number number;
+ /*! Charge identifier */
+ int id;
+ } charge;
+ /*! \see enum PRI_AOC_E_CHARGING_ASSOCIATION */
+ int charging_type;
+};
+
+struct pri_subcmd_aoc_e {
+ /*!
+ * \brief What is being charged.
+ * \see enum PRI_AOC_DE_CHARGE
+ */
+ int charge;
+ /*! \see enum PRI_AOC_E_BILLING_ID */
+ int billing_id;
+ union {
+ /*! Recorded currency */
+ struct pri_aoc_recorded_currency money;
+ /*! Recorded units list */
+ struct pri_aoc_recorded_units unit;
+ } recorded;
+ /*! Charging association. */
+ struct pri_aoc_e_charging_association associated;
};
struct pri_subcommand {
@@ -673,6 +899,9 @@
struct pri_subcmd_cc_id cc_call;
struct pri_subcmd_cc_cancel cc_cancel;
struct pri_subcmd_transfer transfer;
+ struct pri_subcmd_aoc_s aoc_s;
+ struct pri_subcmd_aoc_d aoc_d;
+ struct pri_subcmd_aoc_e aoc_e;
} u;
};
@@ -817,7 +1046,7 @@
int cause;
int cref;
q931_call *call; /* Opaque call pointer of call hanging up. */
- long aoc_units; /* Advise of Charge number of charged units */
+ long aoc_units; /* Advice of Charge number of charged units */
char useruserinfo[260]; /* User->User info */
struct pri_subcommands *subcmds;
/*!
@@ -1379,6 +1608,16 @@
int pri_transfer_rsp(struct pri *ctrl, q931_call *call, int invoke_id, int is_successful);
/*!
+ * \brief Set the advice of charge events feature enable flag.
+ *
+ * \param ctrl D channel controller.
+ * \param enable TRUE to enable AOC events feature.
+ *
+ * \return Nothing
+ */
+void pri_aoc_events_enable(struct pri *ctrl, int enable);
+
+/*!
* \brief Set the call hold 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=1737&r1=1736&r2=1737
==============================================================================
--- branches/1.4/pri_facility.c (original)
+++ branches/1.4/pri_facility.c Fri May 28 13:03:38 2010
@@ -2699,82 +2699,6 @@
return error_code;
}
-
-/* AOC */
-/*!
- * \internal
- * \brief Encode the ETSI AOCEChargingUnit 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 chargedunits Number of units charged to encode.
- *
- * \retval Start of the next ASN.1 component to encode on success.
- * \retval NULL on error.
- */
-static unsigned char *enc_etsi_aoce_charging_unit(struct pri *ctrl, unsigned char *pos,
- unsigned char *end, long chargedunits)
-{
- 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_AOCEChargingUnit;
- msg.invoke_id = get_invokeid(ctrl);
- msg.args.etsi.AOCEChargingUnit.type = 1; /* charging_unit */
- if (chargedunits <= 0) {
- msg.args.etsi.AOCEChargingUnit.charging_unit.free_of_charge = 1;
- } else {
- msg.args.etsi.AOCEChargingUnit.charging_unit.specific.recorded.num_records = 1;
- msg.args.etsi.AOCEChargingUnit.charging_unit.specific.recorded.list[0].
- number_of_units = chargedunits;
- }
- pos = rose_encode_invoke(ctrl, pos, end, &msg);
-
- return pos;
-}
-
-/*!
- * \internal
- * \brief Send the ETSI AOCEChargingUnit invoke message.
- *
- * \param ctrl D channel controller for diagnostic messages or global options.
- * \param call Call leg from which to encode AOC.
- * \param chargedunits Number of units charged to encode.
- *
- * \retval 0 on success.
- * \retval -1 on error.
- */
-static int aoc_aoce_charging_unit_encode(struct pri *ctrl, q931_call *call,
- long chargedunits)
-{
- unsigned char buffer[255];
- unsigned char *end;
-
- /* sample data: [ 91 a1 12 02 02 3a 78 02 01 24 30 09 30 07 a1 05 30 03 02 01 01 ] */
-
- end =
- enc_etsi_aoce_charging_unit(ctrl, buffer, buffer + sizeof(buffer), chargedunits);
- 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 facility message for call %d\n", call->cr);
- return -1;
- }
-
- return 0;
-}
-/* End AOC */
/* ===== Call Transfer Supplementary Service (ECMA-178) ===== */
@@ -4129,40 +4053,23 @@
case ROSE_ETSI_ChargingRequest:
/* Ignore messsage */
break;
-#if 0 /* Not handled yet */
case ROSE_ETSI_AOCSCurrency:
+ aoc_etsi_aoc_s_currency(ctrl, invoke);
break;
case ROSE_ETSI_AOCSSpecialArr:
+ aoc_etsi_aoc_s_special_arrangement(ctrl, invoke);
break;
case ROSE_ETSI_AOCDCurrency:
+ aoc_etsi_aoc_d_currency(ctrl, invoke);
break;
case ROSE_ETSI_AOCDChargingUnit:
+ aoc_etsi_aoc_d_charging_unit(ctrl, invoke);
break;
case ROSE_ETSI_AOCECurrency:
- break;
-#endif /* Not handled yet */
+ aoc_etsi_aoc_e_currency(ctrl, call, invoke);
+ break;
case ROSE_ETSI_AOCEChargingUnit:
- call->aoc_units = 0;
- if (invoke->args.etsi.AOCEChargingUnit.type == 1
- && !invoke->args.etsi.AOCEChargingUnit.charging_unit.free_of_charge) {
- unsigned index;
-
- for (index =
- invoke->args.etsi.AOCEChargingUnit.charging_unit.specific.recorded.
- num_records; index--;) {
- if (!invoke->args.etsi.AOCEChargingUnit.charging_unit.specific.recorded.
- list[index].not_available) {
- call->aoc_units +=
- invoke->args.etsi.AOCEChargingUnit.charging_unit.specific.
- recorded.list[index].number_of_units;
- }
- }
- }
- /* the following function is currently not used - just to make the compiler happy */
- if (0) {
- /* use this function to forward the aoc-e on a bridged channel */
- aoc_aoce_charging_unit_encode(ctrl, call, call->aoc_units);
- }
+ aoc_etsi_aoc_e_charging_unit(ctrl, call, invoke);
break;
#if 0 /* Not handled yet */
case ROSE_ITU_IdentificationOfCharge:
Modified: branches/1.4/pri_facility.h
URL: http://svnview.digium.com/svn/libpri/branches/1.4/pri_facility.h?view=diff&rev=1737&r1=1736&r2=1737
==============================================================================
--- branches/1.4/pri_facility.h (original)
+++ branches/1.4/pri_facility.h Fri May 28 13:03:38 2010
@@ -245,4 +245,11 @@
void pri_cc_qsig_cancel(struct pri *ctrl, q931_call *call, int msgtype, const struct rose_msg_invoke *invoke);
void pri_cc_qsig_exec_possible(struct pri *ctrl, q931_call *call, int msgtype, const struct rose_msg_invoke *invoke);
+void aoc_etsi_aoc_s_currency(struct pri *ctrl, const struct rose_msg_invoke *invoke);
+void aoc_etsi_aoc_s_special_arrangement(struct pri *ctrl, const struct rose_msg_invoke *invoke);
+void aoc_etsi_aoc_d_currency(struct pri *ctrl, const struct rose_msg_invoke *invoke);
+void aoc_etsi_aoc_d_charging_unit(struct pri *ctrl, const struct rose_msg_invoke *invoke);
+void aoc_etsi_aoc_e_currency(struct pri *ctrl, q931_call *call, const struct rose_msg_invoke *invoke);
+void aoc_etsi_aoc_e_charging_unit(struct pri *ctrl, q931_call *call, const struct rose_msg_invoke *invoke);
+
#endif /* _PRI_FACILITY_H */
Modified: branches/1.4/pri_internal.h
URL: http://svnview.digium.com/svn/libpri/branches/1.4/pri_internal.h?view=diff&rev=1737&r1=1736&r2=1737
==============================================================================
--- branches/1.4/pri_internal.h (original)
+++ branches/1.4/pri_internal.h Fri May 28 13:03:38 2010
@@ -107,6 +107,7 @@
unsigned int hangup_fix_enabled:1;/* TRUE if should follow Q.931 Section 5.3.2 instead of blindly sending RELEASE_COMPLETE for certain causes */
unsigned int cc_support:1;/* TRUE if upper layer supports call completion. */
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. */
/* MDL variables */
int mdl_error;
Modified: branches/1.4/rose_etsi_aoc.c
URL: http://svnview.digium.com/svn/libpri/branches/1.4/rose_etsi_aoc.c?view=diff&rev=1737&r1=1736&r2=1737
==============================================================================
--- branches/1.4/rose_etsi_aoc.c (original)
+++ branches/1.4/rose_etsi_aoc.c Fri May 28 13:03:38 2010
@@ -623,8 +623,13 @@
ASN1_CALL(pos, asn1_enc_null(pos, end, ASN1_TYPE_NULL));
break;
case 1: /* currency_info_list */
- ASN1_CALL(pos, rose_enc_etsi_AOCSCurrencyInfoList(ctrl, pos, end,
- ASN1_TAG_SEQUENCE, &args->etsi.AOCSCurrency.currency_info));
+ if (args->etsi.AOCSCurrency.currency_info.num_records) {
+ ASN1_CALL(pos, rose_enc_etsi_AOCSCurrencyInfoList(ctrl, pos, end,
+ ASN1_TAG_SEQUENCE, &args->etsi.AOCSCurrency.currency_info));
+ } else {
+ /* There were no records so encode as charge_not_available */
+ ASN1_CALL(pos, asn1_enc_null(pos, end, ASN1_TYPE_NULL));
+ }
break;
default:
ASN1_ENC_ERROR(ctrl, "Unknown AOCSCurrency type");
More information about the libpri-commits
mailing list