[libpri-commits] rmudgett: branch rmudgett/aoc_event r1505 - /team/rmudgett/aoc_event/

SVN commits to the libpri project libpri-commits at lists.digium.com
Tue Feb 23 20:56:36 CST 2010


Author: rmudgett
Date: Tue Feb 23 20:56:34 2010
New Revision: 1505

URL: http://svnview.digium.com/svn/libpri?view=rev&rev=1505
Log:
Initial AOC event support.

Added:
    team/rmudgett/aoc_event/pri_aoc.c   (with props)
Modified:
    team/rmudgett/aoc_event/Makefile
    team/rmudgett/aoc_event/libpri.h
    team/rmudgett/aoc_event/pri_facility.c
    team/rmudgett/aoc_event/pri_facility.h
    team/rmudgett/aoc_event/pri_internal.h

Modified: team/rmudgett/aoc_event/Makefile
URL: http://svnview.digium.com/svn/libpri/team/rmudgett/aoc_event/Makefile?view=diff&rev=1505&r1=1504&r2=1505
==============================================================================
--- team/rmudgett/aoc_event/Makefile (original)
+++ team/rmudgett/aoc_event/Makefile Tue Feb 23 20:56:34 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: team/rmudgett/aoc_event/libpri.h
URL: http://svnview.digium.com/svn/libpri/team/rmudgett/aoc_event/libpri.h?view=diff&rev=1505&r1=1504&r2=1505
==============================================================================
--- team/rmudgett/aoc_event/libpri.h (original)
+++ team/rmudgett/aoc_event/libpri.h Tue Feb 23 20:56:34 2010
@@ -539,6 +539,9 @@
 #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 */
 
 #if defined(STATUS_REQUEST_PLACE_HOLDER)
 struct pri_subcmd_status_request {
@@ -646,6 +649,207 @@
 	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_ARRANGEMENT,
+};
+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 {
+	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 +877,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 +1024,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;
 	/*!
@@ -1368,6 +1575,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.

Added: team/rmudgett/aoc_event/pri_aoc.c
URL: http://svnview.digium.com/svn/libpri/team/rmudgett/aoc_event/pri_aoc.c?view=auto&rev=1505
==============================================================================
--- team/rmudgett/aoc_event/pri_aoc.c (added)
+++ team/rmudgett/aoc_event/pri_aoc.c Tue Feb 23 20:56:34 2010
@@ -1,0 +1,681 @@
+/*
+ * libpri: An implementation of Primary Rate ISDN
+ *
+ * Copyright (C) 2010 Digium, Inc.
+ *
+ * Richard Mudgett <rmudgett at digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2 as published by the
+ * Free Software Foundation. See the LICENSE file included with
+ * this program for more details.
+ *
+ * In addition, when this program is distributed with Asterisk in
+ * any form that would qualify as a 'combined work' or as a
+ * 'derivative work' (but not mere aggregation), you can redistribute
+ * and/or modify the combination under the terms of the license
+ * provided with that copy of Asterisk, instead of the license
+ * terms granted here.
+ */
+
+/*!
+ * \file
+ * \brief Advice Of Charge (AOC) facility support.
+ *
+ * \author Richard Mudgett <rmudgett at digium.com>
+ */
+
+
+#include "compat.h"
+#include "libpri.h"
+#include "pri_internal.h"
+#include "pri_facility.h"
+
+
+/* ------------------------------------------------------------------- */
+
+/*!
+ * \internal
+ * \brief Fill in the AOC subcmd amount from the ETSI amount.
+ *
+ * \param subcmd_amount AOC subcmd amount.
+ * \param etsi_amount AOC ETSI amount.
+ *
+ * \return Nothing
+ */
+static void aoc_etsi_subcmd_amount(struct pri_aoc_amount *subcmd_amount, const struct roseEtsiAOCAmount *etsi_amount)
+{
+	subcmd_amount->cost = etsi_amount->currency;
+	subcmd_amount->multiplier = etsi_amount->multiplier;
+}
+
+/*!
+ * \internal
+ * \brief Fill in the AOC subcmd time from the ETSI time.
+ *
+ * \param subcmd_time AOC subcmd time.
+ * \param etsi_time AOC ETSI time.
+ *
+ * \return Nothing
+ */
+static void aoc_etsi_subcmd_time(struct pri_aoc_time *subcmd_time, const struct roseEtsiAOCTime *etsi_time)
+{
+	subcmd_time->length = etsi_time->length;
+	subcmd_time->scale = etsi_time->scale;
+}
+
+/*!
+ * \internal
+ * \brief Fill in the AOC subcmd recorded currency from the ETSI recorded currency.
+ *
+ * \param subcmd_recorded AOC subcmd recorded currency.
+ * \param etsi_recorded AOC ETSI recorded currency.
+ *
+ * \return Nothing
+ */
+static void aoc_etsi_subcmd_recorded_currency(struct pri_aoc_recorded_currency *subcmd_recorded, const struct roseEtsiAOCRecordedCurrency *etsi_recorded)
+{
+	aoc_etsi_subcmd_amount(&subcmd_recorded->amount, &etsi_recorded->amount);
+	libpri_copy_string(subcmd_recorded->currency, (char *) etsi_recorded->currency,
+		sizeof(subcmd_recorded->currency));
+}
+
+/*!
+ * \internal
+ * \brief Fill in the AOC subcmd recorded units from the ETSI recorded units.
+ *
+ * \param subcmd_recorded AOC subcmd recorded units list.
+ * \param etsi_recorded AOC ETSI recorded units list.
+ *
+ * \return Nothing
+ */
+static void aoc_etsi_subcmd_recorded_units(struct pri_aoc_recorded_units *subcmd_recorded, const struct roseEtsiAOCRecordedUnitsList *etsi_recorded)
+{
+	int idx;
+
+	/* Fill in the itemized list of recorded units. */
+	for (idx = 0; idx < etsi_recorded->num_records
+		&& idx < ARRAY_LEN(subcmd_recorded->item); ++idx) {
+		if (etsi_recorded->list[idx].not_available) {
+			subcmd_recorded->item[idx].number = -1;
+		} else {
+			subcmd_recorded->item[idx].number = etsi_recorded->list[idx].number_of_units;
+		}
+		if (etsi_recorded->list[idx].type_of_unit_present) {
+			subcmd_recorded->item[idx].type = etsi_recorded->list[idx].type_of_unit;
+		} else {
+			subcmd_recorded->item[idx].type = -1;
+		}
+	}
+	subcmd_recorded->num_items = idx;
+}
+
+/*!
+ * \internal
+ * \brief Fill in the AOC-S subcmd currency info list of chargeable items.
+ *
+ * \param aoc_s AOC-S info list of chargeable items.
+ * \param info ETSI info list of chargeable items.
+ *
+ * \return Nothing
+ */
+static void aoc_etsi_subcmd_aoc_s_currency_info(struct pri_subcmd_aoc_s *aoc_s, const struct roseEtsiAOCSCurrencyInfoList *info)
+{
+	int idx;
+
+	/* Fill in the itemized list of chargeable items. */
+	for (idx = 0; idx < info->num_records && idx < ARRAY_LEN(aoc_s->item); ++idx) {
+		/* What is being charged. */
+		switch (info->list[idx].charged_item) {
+		case 0:/* basicCommunication */
+			aoc_s->item[idx].chargeable = PRI_AOC_CHARGED_ITEM_BASIC_COMMUNICATION;
+			break;
+		case 1:/* callAttempt */
+			aoc_s->item[idx].chargeable = PRI_AOC_CHARGED_ITEM_CALL_ATTEMPT;
+			break;
+		case 2:/* callSetup */
+			aoc_s->item[idx].chargeable = PRI_AOC_CHARGED_ITEM_CALL_SETUP;
+			break;
+		case 3:/*  userToUserInfo */
+			aoc_s->item[idx].chargeable = PRI_AOC_CHARGED_ITEM_USER_USER_INFO;
+			break;
+		case 4:/* operationOfSupplementaryServ */
+			aoc_s->item[idx].chargeable = PRI_AOC_CHARGED_ITEM_SUPPLEMENTARY_SERVICE;
+			break;
+		default:
+			aoc_s->item[idx].chargeable = PRI_AOC_CHARGED_ITEM_NOT_AVAILABLE;
+			break;
+		}
+
+		/* Rate method being used. */
+		switch (info->list[idx].currency_type) {
+		case 0:/* specialChargingCode */
+			aoc_s->item[idx].rate_type = PRI_AOC_RATE_TYPE_SPECIAL_ARRANGEMENT;
+			aoc_s->item[idx].rate.special = info->list[idx].u.special_charging_code;
+			break;
+		case 1:/* durationCurrency */
+			aoc_s->item[idx].rate_type = PRI_AOC_RATE_TYPE_DURATION;
+			aoc_etsi_subcmd_amount(&aoc_s->item[idx].rate.duration.amount,
+				&info->list[idx].u.duration.amount);
+			aoc_etsi_subcmd_time(&aoc_s->item[idx].rate.duration.time,
+				&info->list[idx].u.duration.time);
+			if (info->list[idx].u.duration.granularity_present) {
+				aoc_etsi_subcmd_time(&aoc_s->item[idx].rate.duration.granularity,
+					&info->list[idx].u.duration.granularity);
+			} else {
+				aoc_s->item[idx].rate.duration.granularity.length = 0;
+				aoc_s->item[idx].rate.duration.granularity.scale =
+					PRI_AOC_TIME_SCALE_HUNDREDTH_SECOND;
+			}
+			aoc_s->item[idx].rate.duration.charging_type =
+				info->list[idx].u.duration.charging_type;
+			libpri_copy_string(aoc_s->item[idx].rate.duration.currency,
+				(char *) info->list[idx].u.duration.currency,
+				sizeof(aoc_s->item[idx].rate.duration.currency));
+			break;
+		case 2:/* flatRateCurrency */
+			aoc_s->item[idx].rate_type = PRI_AOC_RATE_TYPE_FLAT;
+			aoc_etsi_subcmd_amount(&aoc_s->item[idx].rate.flat.amount,
+				&info->list[idx].u.flat_rate.amount);
+			libpri_copy_string(aoc_s->item[idx].rate.flat.currency,
+				(char *) info->list[idx].u.flat_rate.currency,
+				sizeof(aoc_s->item[idx].rate.flat.currency));
+			break;
+		case 3:/* volumeRateCurrency */
+			aoc_s->item[idx].rate_type = PRI_AOC_RATE_TYPE_VOLUME;
+			aoc_etsi_subcmd_amount(&aoc_s->item[idx].rate.volume.amount,
+				&info->list[idx].u.volume_rate.amount);
+			aoc_s->item[idx].rate.volume.unit = info->list[idx].u.volume_rate.unit;
+			libpri_copy_string(aoc_s->item[idx].rate.volume.currency,
+				(char *) info->list[idx].u.volume_rate.currency,
+				sizeof(aoc_s->item[idx].rate.volume.currency));
+			break;
+		case 4:/* freeOfCharge */
+			aoc_s->item[idx].rate_type = PRI_AOC_RATE_TYPE_FREE;
+			break;
+		default:
+		case 5:/* currencyInfoNotAvailable */
+			aoc_s->item[idx].rate_type = PRI_AOC_RATE_TYPE_NOT_AVAILABLE;
+			break;
+		}
+	}
+	aoc_s->num_items = idx;
+}
+
+/*!
+ * \brief Handle the ETSI AOCSCurrency message.
+ *
+ * \param ctrl D channel controller for diagnostic messages or global options.
+ * \param invoke Decoded ROSE invoke message contents.
+ *
+ * \return Nothing
+ */
+void aoc_etsi_aoc_s_currency(struct pri *ctrl, const struct rose_msg_invoke *invoke)
+{
+	struct pri_subcommand *subcmd;
+
+	if (!PRI_MASTER(ctrl)->aoc_support) {
+		return;
+	}
+	subcmd = q931_alloc_subcommand(ctrl);
+	if (!subcmd) {
+		return;
+	}
+
+	subcmd->cmd = PRI_SUBCMD_AOC_S;
+	if (!invoke->args.etsi.AOCSCurrency.type) {
+		subcmd->u.aoc_s.num_items = 1;
+		subcmd->u.aoc_s.item[0].chargeable = PRI_AOC_CHARGED_ITEM_NOT_AVAILABLE;
+		subcmd->u.aoc_s.item[0].rate_type = PRI_AOC_RATE_TYPE_NOT_AVAILABLE;
+		return;
+	}
+
+	/* Fill in the itemized list of chargeable items. */
+	aoc_etsi_subcmd_aoc_s_currency_info(&subcmd->u.aoc_s,
+		&invoke->args.etsi.AOCSCurrency.currency_info);
+}
+
+/*!
+ * \brief Handle the ETSI AOCSSpecialArr message.
+ *
+ * \param ctrl D channel controller for diagnostic messages or global options.
+ * \param invoke Decoded ROSE invoke message contents.
+ *
+ * \return Nothing
+ */
+void aoc_etsi_aoc_s_special_arrangement(struct pri *ctrl, const struct rose_msg_invoke *invoke)
+{
+	struct pri_subcommand *subcmd;
+
+	if (!PRI_MASTER(ctrl)->aoc_support) {
+		return;
+	}
+	subcmd = q931_alloc_subcommand(ctrl);
+	if (!subcmd) {
+		return;
+	}
+	subcmd->cmd = PRI_SUBCMD_AOC_S;
+	subcmd->u.aoc_s.num_items = 1;
+	if (!invoke->args.etsi.AOCSSpecialArr.type) {
+		subcmd->u.aoc_s.item[0].chargeable = PRI_AOC_CHARGED_ITEM_NOT_AVAILABLE;
+		subcmd->u.aoc_s.item[0].rate_type = PRI_AOC_RATE_TYPE_NOT_AVAILABLE;
+		return;
+	}
+	subcmd->u.aoc_s.item[0].chargeable = PRI_AOC_CHARGED_ITEM_SPECIAL_ARRANGEMENT;
+	subcmd->u.aoc_s.item[0].rate_type = PRI_AOC_RATE_TYPE_SPECIAL_ARRANGEMENT;
+	subcmd->u.aoc_s.item[0].rate.special =
+		invoke->args.etsi.AOCSSpecialArr.special_arrangement;
+}
+
+/*!
+ * \internal
+ * \brief Determine the AOC-D subcmd billing_id value.
+ *
+ * \param billing_id_present TRUE if billing_id valid.
+ * \param billing_id ETSI billing id from ROSE.
+ *
+ * \return enum PRI_AOC_D_BILLING_ID value
+ */
+static enum PRI_AOC_D_BILLING_ID aoc_etsi_subcmd_aoc_d_billing_id(int billing_id_present, int billing_id)
+{
+	enum PRI_AOC_D_BILLING_ID value;
+
+	if (billing_id_present) {
+		switch (billing_id) {
+		case 0:/* normalCharging */
+			value = PRI_AOC_D_BILLING_ID_NORMAL;
+			break;
+		case 1:/* reverseCharging */
+			value = PRI_AOC_D_BILLING_ID_REVERSE;
+			break;
+		case 2:/* creditCardCharging */
+			value = PRI_AOC_D_BILLING_ID_CREDIT_CARD;
+			break;
+		default:
+			value = PRI_AOC_D_BILLING_ID_NOT_AVAILABLE;
+			break;
+		}
+	} else {
+		value = PRI_AOC_D_BILLING_ID_NOT_AVAILABLE;
+	}
+	return value;
+}
+
+/*!
+ * \brief Handle the ETSI AOCDCurrency message.
+ *
+ * \param ctrl D channel controller for diagnostic messages or global options.
+ * \param invoke Decoded ROSE invoke message contents.
+ *
+ * \return Nothing
+ */
+void aoc_etsi_aoc_d_currency(struct pri *ctrl, const struct rose_msg_invoke *invoke)
+{
+	struct pri_subcommand *subcmd;
+
+	if (!PRI_MASTER(ctrl)->aoc_support) {
+		return;
+	}
+	subcmd = q931_alloc_subcommand(ctrl);
+	if (!subcmd) {
+		return;
+	}
+
+	subcmd->cmd = PRI_SUBCMD_AOC_D;
+	switch (invoke->args.etsi.AOCDCurrency.type) {
+	default:
+	case 0:/* charge_not_available */
+		subcmd->u.aoc_d.charge = PRI_AOC_DE_CHARGE_NOT_AVAILABLE;
+		break;
+	case 1:/* free_of_charge */
+		subcmd->u.aoc_d.charge = PRI_AOC_DE_CHARGE_FREE;
+		break;
+	case 2:/* specific_currency */
+		subcmd->u.aoc_d.charge = PRI_AOC_DE_CHARGE_CURRENCY;
+		aoc_etsi_subcmd_recorded_currency(&subcmd->u.aoc_d.recorded.money,
+			&invoke->args.etsi.AOCDCurrency.specific.recorded);
+		subcmd->u.aoc_d.billing_accumulation =
+			invoke->args.etsi.AOCDCurrency.specific.type_of_charging_info;
+		subcmd->u.aoc_d.billing_id = aoc_etsi_subcmd_aoc_d_billing_id(
+			invoke->args.etsi.AOCDCurrency.specific.billing_id_present,
+			invoke->args.etsi.AOCDCurrency.specific.billing_id);
+		break;
+	}
+}
+
+/*!
+ * \brief Handle the ETSI AOCDChargingUnit message.
+ *
+ * \param ctrl D channel controller for diagnostic messages or global options.
+ * \param invoke Decoded ROSE invoke message contents.
+ *
+ * \return Nothing
+ */
+void aoc_etsi_aoc_d_charging_unit(struct pri *ctrl, const struct rose_msg_invoke *invoke)
+{
+	struct pri_subcommand *subcmd;
+
+	if (!PRI_MASTER(ctrl)->aoc_support) {
+		return;
+	}
+	subcmd = q931_alloc_subcommand(ctrl);
+	if (!subcmd) {
+		return;
+	}
+
+	subcmd->cmd = PRI_SUBCMD_AOC_D;
+	switch (invoke->args.etsi.AOCDChargingUnit.type) {
+	default:
+	case 0:/* charge_not_available */
+		subcmd->u.aoc_d.charge = PRI_AOC_DE_CHARGE_NOT_AVAILABLE;
+		break;
+	case 1:/* free_of_charge */
+		subcmd->u.aoc_d.charge = PRI_AOC_DE_CHARGE_FREE;
+		break;
+	case 2:/* specific_charging_units */
+		subcmd->u.aoc_d.charge = PRI_AOC_DE_CHARGE_UNITS;
+		aoc_etsi_subcmd_recorded_units(&subcmd->u.aoc_d.recorded.unit,
+			&invoke->args.etsi.AOCDChargingUnit.specific.recorded);
+		subcmd->u.aoc_d.billing_accumulation =
+			invoke->args.etsi.AOCDChargingUnit.specific.type_of_charging_info;
+		subcmd->u.aoc_d.billing_id = aoc_etsi_subcmd_aoc_d_billing_id(
+			invoke->args.etsi.AOCDChargingUnit.specific.billing_id_present,
+			invoke->args.etsi.AOCDChargingUnit.specific.billing_id);
+		break;
+	}
+}
+
+/*!
+ * \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;
+}
+
+/*!
+ * \internal
+ * \brief Fill in the AOC-E subcmd charging association from the ETSI charging association.
+ *
+ * \param ctrl D channel controller for diagnostic messages or global options.
+ * \param subcmd_association AOC-E subcmd charging association.
+ * \param etsi_association AOC-E ETSI charging association.
+ *
+ * \return Nothing
+ */
+static void aoc_etsi_subcmd_aoc_e_charging_association(struct pri *ctrl, struct pri_aoc_e_charging_association *subcmd_association, const struct roseEtsiAOCChargingAssociation *etsi_association)
+{
+	struct q931_party_number q931_number;
+
+	switch (etsi_association->type) {
+	case 0:/* charge_identifier */
+		subcmd_association->charging_type = PRI_AOC_E_CHARGING_ASSOCIATION_ID;
+		subcmd_association->charge.id = etsi_association->id;
+		break;
+	case 1:/* charged_number */
+		subcmd_association->charging_type = PRI_AOC_E_CHARGING_ASSOCIATION_NUMBER;
+		q931_party_number_init(&q931_number);
+		rose_copy_number_to_q931(ctrl, &q931_number, &etsi_association->number);
+		q931_party_number_copy_to_pri(&subcmd_association->charge.number, &q931_number);
+		break;
+	default:
+		subcmd_association->charging_type = PRI_AOC_E_CHARGING_ASSOCIATION_NOT_AVAILABLE;
+		break;
+	}
+}
+
+/*!
+ * \internal
+ * \brief Determine the AOC-E subcmd billing_id value.
+ *
+ * \param billing_id_present TRUE if billing_id valid.
+ * \param billing_id ETSI billing id from ROSE.
+ *
+ * \return enum PRI_AOC_E_BILLING_ID value
+ */
+static enum PRI_AOC_E_BILLING_ID aoc_etsi_subcmd_aoc_e_billing_id(int billing_id_present, int billing_id)
+{
+	enum PRI_AOC_E_BILLING_ID value;
+
+	if (billing_id_present) {
+		switch (billing_id) {
+		case 0:/* normalCharging */
+			value = PRI_AOC_E_BILLING_ID_NORMAL;
+			break;
+		case 1:/* reverseCharging */
+			value = PRI_AOC_E_BILLING_ID_REVERSE;
+			break;
+		case 2:/* creditCardCharging */
+			value = PRI_AOC_E_BILLING_ID_CREDIT_CARD;
+			break;
+		case 3:/* callForwardingUnconditional */
+			value = PRI_AOC_E_BILLING_ID_CALL_FORWARDING_UNCONDITIONAL;
+			break;
+		case 4:/* callForwardingBusy */
+			value = PRI_AOC_E_BILLING_ID_CALL_FORWARDING_BUSY;
+			break;
+		case 5:/* callForwardingNoReply */
+			value = PRI_AOC_E_BILLING_ID_CALL_FORWARDING_NO_REPLY;
+			break;
+		case 6:/* callDeflection */
+			value = PRI_AOC_E_BILLING_ID_CALL_DEFLECTION;
+			break;
+		case 7:/* callTransfer */
+			value = PRI_AOC_E_BILLING_ID_CALL_TRANSFER;
+			break;
+		default:
+			value = PRI_AOC_E_BILLING_ID_NOT_AVAILABLE;
+			break;
+		}
+	} else {
+		value = PRI_AOC_E_BILLING_ID_NOT_AVAILABLE;
+	}
+	return value;
+}
+
+/*!
+ * \brief Handle the ETSI AOCECurrency message.
+ *
+ * \param ctrl D channel controller for diagnostic messages or global options.
+ * \param call Q.931 call leg.
+ * \param invoke Decoded ROSE invoke message contents.
+ *
+ * \return Nothing
+ */
+void aoc_etsi_aoc_e_currency(struct pri *ctrl, q931_call *call, const struct rose_msg_invoke *invoke)
+{
+	struct pri_subcommand *subcmd;
+
+	if (!PRI_MASTER(ctrl)->aoc_support) {
+		return;
+	}
+	subcmd = q931_alloc_subcommand(ctrl);
+	if (!subcmd) {
+		return;
+	}
+
+	subcmd->cmd = PRI_SUBCMD_AOC_E;
+	subcmd->u.aoc_e.associated.charging_type =
+		PRI_AOC_E_CHARGING_ASSOCIATION_NOT_AVAILABLE;
+
+	if (!invoke->args.etsi.AOCECurrency.type) {
+		subcmd->u.aoc_e.charge = PRI_AOC_DE_CHARGE_NOT_AVAILABLE;
+		return;
+	}
+
+	/* Fill in charging association if present. */
+	if (invoke->args.etsi.AOCECurrency.currency_info.charging_association_present) {
+		aoc_etsi_subcmd_aoc_e_charging_association(ctrl, &subcmd->u.aoc_e.associated,
+			&invoke->args.etsi.AOCECurrency.currency_info.charging_association);
+	}
+
+	/* Call was free of charge. */
+	if (invoke->args.etsi.AOCECurrency.currency_info.free_of_charge) {
+		subcmd->u.aoc_e.charge = PRI_AOC_DE_CHARGE_FREE;
+		return;
+	}
+
+	/* Fill in currency cost of call. */
+	subcmd->u.aoc_e.charge = PRI_AOC_DE_CHARGE_CURRENCY;
+	aoc_etsi_subcmd_recorded_currency(&subcmd->u.aoc_e.recorded.money,
+		&invoke->args.etsi.AOCECurrency.currency_info.specific.recorded);
+	subcmd->u.aoc_e.billing_id = aoc_etsi_subcmd_aoc_e_billing_id(
+		invoke->args.etsi.AOCECurrency.currency_info.specific.billing_id_present,
+		invoke->args.etsi.AOCECurrency.currency_info.specific.billing_id);
+}
+
+/*!
+ * \brief Handle the ETSI AOCEChargingUnit message.
+ *
+ * \param ctrl D channel controller for diagnostic messages or global options.
+ * \param call Q.931 call leg.
+ * \param invoke Decoded ROSE invoke message contents.
+ *
+ * \return Nothing
+ */
+void aoc_etsi_aoc_e_charging_unit(struct pri *ctrl, q931_call *call, const struct rose_msg_invoke *invoke)
+{
+	struct pri_subcommand *subcmd;
+	unsigned idx;
+
+	/* Fill in legacy stuff. */
+	call->aoc_units = 0;
+	if (invoke->args.etsi.AOCEChargingUnit.type == 1
+		&& !invoke->args.etsi.AOCEChargingUnit.charging_unit.free_of_charge) {
+		for (idx =
+			invoke->args.etsi.AOCEChargingUnit.charging_unit.specific.recorded.num_records;
+			idx--;) {
+			if (!invoke->args.etsi.AOCEChargingUnit.charging_unit.specific.recorded.
+				list[idx].not_available) {
+				call->aoc_units +=
+					invoke->args.etsi.AOCEChargingUnit.charging_unit.specific.
+					recorded.list[idx].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);
+	}
+
+	if (!PRI_MASTER(ctrl)->aoc_support) {
+		return;
+	}
+	subcmd = q931_alloc_subcommand(ctrl);
+	if (!subcmd) {
+		return;
+	}
+
+	subcmd->cmd = PRI_SUBCMD_AOC_E;
+	subcmd->u.aoc_e.associated.charging_type =
+		PRI_AOC_E_CHARGING_ASSOCIATION_NOT_AVAILABLE;
+
+	if (!invoke->args.etsi.AOCEChargingUnit.type) {
+		subcmd->u.aoc_e.charge = PRI_AOC_DE_CHARGE_NOT_AVAILABLE;
+		return;
+	}
+
+	/* Fill in charging association if present. */
+	if (invoke->args.etsi.AOCEChargingUnit.charging_unit.charging_association_present) {
+		aoc_etsi_subcmd_aoc_e_charging_association(ctrl, &subcmd->u.aoc_e.associated,
+			&invoke->args.etsi.AOCEChargingUnit.charging_unit.charging_association);
+	}
+
+	/* Call was free of charge. */
+	if (invoke->args.etsi.AOCEChargingUnit.charging_unit.free_of_charge) {
+		subcmd->u.aoc_e.charge = PRI_AOC_DE_CHARGE_FREE;
+		return;
+	}
+
+	/* Fill in unit cost of call. */
+	subcmd->u.aoc_e.charge = PRI_AOC_DE_CHARGE_UNITS;
+	aoc_etsi_subcmd_recorded_units(&subcmd->u.aoc_e.recorded.unit,
+		&invoke->args.etsi.AOCEChargingUnit.charging_unit.specific.recorded);
+	subcmd->u.aoc_e.billing_id = aoc_etsi_subcmd_aoc_e_billing_id(
+		invoke->args.etsi.AOCEChargingUnit.charging_unit.specific.billing_id_present,
+		invoke->args.etsi.AOCEChargingUnit.charging_unit.specific.billing_id);
+}
+
+void pri_aoc_events_enable(struct pri *ctrl, int enable)
+{
+	if (ctrl) {
+		ctrl = PRI_MASTER(ctrl);
+		ctrl->aoc_support = enable ? 1 : 0;
+	}
+}
+
+/* ------------------------------------------------------------------- */
+/* end pri_aoc.c */

Propchange: team/rmudgett/aoc_event/pri_aoc.c
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: team/rmudgett/aoc_event/pri_aoc.c
------------------------------------------------------------------------------
    svn:keywords = 'Author Date Id Revision'

Propchange: team/rmudgett/aoc_event/pri_aoc.c
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: team/rmudgett/aoc_event/pri_facility.c
URL: http://svnview.digium.com/svn/libpri/team/rmudgett/aoc_event/pri_facility.c?view=diff&rev=1505&r1=1504&r2=1505
==============================================================================
--- team/rmudgett/aoc_event/pri_facility.c (original)
+++ team/rmudgett/aoc_event/pri_facility.c Tue Feb 23 20:56:34 2010
@@ -2700,82 +2700,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) ===== */
 
@@ -4130,40 +4054,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: team/rmudgett/aoc_event/pri_facility.h
URL: http://svnview.digium.com/svn/libpri/team/rmudgett/aoc_event/pri_facility.h?view=diff&rev=1505&r1=1504&r2=1505
==============================================================================
--- team/rmudgett/aoc_event/pri_facility.h (original)
+++ team/rmudgett/aoc_event/pri_facility.h Tue Feb 23 20:56:34 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: team/rmudgett/aoc_event/pri_internal.h
URL: http://svnview.digium.com/svn/libpri/team/rmudgett/aoc_event/pri_internal.h?view=diff&rev=1505&r1=1504&r2=1505
==============================================================================
--- team/rmudgett/aoc_event/pri_internal.h (original)
+++ team/rmudgett/aoc_event/pri_internal.h Tue Feb 23 20:56:34 2010
@@ -103,6 +103,7 @@
 	unsigned int deflection_support:1;/* TRUE if upper layer supports call deflection/rerouting. */
 	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;




More information about the libpri-commits mailing list