[svn-commits] dvossel: branch dvossel/generic_aoc r255493 - in /team/dvossel/generic_aoc: c...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Tue Mar 30 17:33:39 CDT 2010


Author: dvossel
Date: Tue Mar 30 17:33:38 2010
New Revision: 255493

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=255493
Log:
documentation, improved AOC Event and Debug generation, and new unit test for aoc events

Modified:
    team/dvossel/generic_aoc/channels/sig_pri.c
    team/dvossel/generic_aoc/include/asterisk/aoc.h
    team/dvossel/generic_aoc/main/aoc.c
    team/dvossel/generic_aoc/tests/test_aoc.c

Modified: team/dvossel/generic_aoc/channels/sig_pri.c
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/generic_aoc/channels/sig_pri.c?view=diff&rev=255493&r1=255492&r2=255493
==============================================================================
--- team/dvossel/generic_aoc/channels/sig_pri.c (original)
+++ team/dvossel/generic_aoc/channels/sig_pri.c Tue Mar 30 17:33:38 2010
@@ -2408,7 +2408,7 @@
  *
  * \note Assumes that the PRI lock is already obtained.
  */
-static void sig_pri_aocd_from_ast(struct sig_pri_chan *pvt, struct ast_channel *ast, struct ast_aoc_decoded *decoded)
+static void sig_pri_aoc_d_from_ast(struct sig_pri_chan *pvt, struct ast_channel *ast, struct ast_aoc_decoded *decoded)
 {
 	struct pri_subcmd_aoc_d aoc_d = { 0, };
 	aoc_d.billing_accumulation = (ast_aoc_get_total_type(decoded) == AST_AOC_TOTAL) ? 1 : 0;
@@ -2481,7 +2481,7 @@
  *
  * \note Assumes that the PRI lock is already obtained.
  */
-static void sig_pri_aoce_from_ast(struct sig_pri_chan *pvt, struct ast_channel *ast, struct ast_aoc_decoded *decoded)
+static void sig_pri_aoc_e_from_ast(struct sig_pri_chan *pvt, struct ast_channel *ast, struct ast_aoc_decoded *decoded)
 {
 	struct pri_subcmd_aoc_e aoc_e = { 0, };
 
@@ -5422,10 +5422,10 @@
 			if (decoded && p->pri && !pri_grab(p, p->pri)) {
 				switch (ast_aoc_get_msg_type(decoded)) {
 				case AST_AOC_D:
-					sig_pri_aocd_from_ast(p, chan, decoded);
+					sig_pri_aoc_d_from_ast(p, chan, decoded);
 					break;
 				case AST_AOC_E:
-					sig_pri_aoce_from_ast(p, chan, decoded);
+					sig_pri_aoc_e_from_ast(p, chan, decoded);
 					break;
 				case AST_AOC_REQUEST:
 					/* TODO XXX do we pass through requests? */
@@ -6370,5 +6370,4 @@
 	}
 #endif	/* defined(HAVE_PRI_CCSS) */
 }
-
 #endif /* HAVE_PRI */

Modified: team/dvossel/generic_aoc/include/asterisk/aoc.h
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/generic_aoc/include/asterisk/aoc.h?view=diff&rev=255493&r1=255492&r2=255493
==============================================================================
--- team/dvossel/generic_aoc/include/asterisk/aoc.h (original)
+++ team/dvossel/generic_aoc/include/asterisk/aoc.h Tue Mar 30 17:33:38 2010
@@ -39,7 +39,7 @@
 	AST_AOC_MULT_TEN,
 	AST_AOC_MULT_HUNDRED,
 	AST_AOC_MULT_THOUSAND,
-	AST_AOC_MULT_NUM_ENTRIES, /* must remain the last item in enum */
+	AST_AOC_MULT_NUM_ENTRIES, /* must remain the last item in enum, this is not a valid type */
 };
 
 /*! \brief Defines the billing id options for an aoc message.
@@ -55,7 +55,7 @@
 	AST_AOC_BILLING_CALL_FWD_NO_REPLY,
 	AST_AOC_BILLING_CALL_DEFLECTION,
 	AST_AOC_BILLING_CALL_TRANSFER,
-	AST_AOC_BILLING_NUM_ENTRIES, /* must remain the last item in enum */
+	AST_AOC_BILLING_NUM_ENTRIES, /* must remain the last item in enum, not a valid billing id */
 };
 
 enum ast_aoc_type {
@@ -300,6 +300,22 @@
  */
 int ast_aoc_set_association_number(struct ast_aoc_decoded *decoded, const char *num, uint8_t plan);
 
+/*! \brief Add AOC-S duration rate entry
+ *
+ *  \param aoc decoded object to add entry to
+ *  \param ast_aoc_s_charged_item
+ *  \param currency amount 
+ *  \param currency multiplier
+ *  \param currency name, truncated after 10 characters
+ *  \param time
+ *  \param time scale from ast_aoc_time_scale enum
+ *  \param granularity_time (optional, set to 0 if not present);
+ *  \param granularity_scale (optional, set to 0 if not present);
+ *  \param step_function, set to 1 if this is to use a step function, 0 if continuious 
+ *
+ *  \retval 0 success
+ *  \retval -1 failure
+ */
 int ast_aoc_s_add_rate_duration(struct ast_aoc_decoded *decoded,
 	enum ast_aoc_s_charged_item charged_item,
 	unsigned int amount,
@@ -311,12 +327,35 @@
 	enum ast_aoc_time_scale granularity_time_scale,
 	int step_function);
 
+/*! \brief Add AOC-S flat rate entry
+ *
+ *  \param aoc decoded object to add entry to
+ *  \param ast_aoc_s_charged_item
+ *  \param currency amount 
+ *  \param currency multiplier
+ *  \param currency name, truncated after 10 characters
+ *
+ *  \retval 0 success
+ *  \retval -1 failure
+ */
 int ast_aoc_s_add_rate_flat(struct ast_aoc_decoded *decoded,
 	enum ast_aoc_s_charged_item charged_item,
 	unsigned int amount,
 	enum ast_aoc_currency_multiplier multiplier,
 	const char *currency_name);
 
+/*! \brief Add AOC-S volume rate entry
+ *
+ *  \param aoc decoded object to add entry to
+ *  \param ast_aoc_s_charged_item
+ *  \param volume unit from ast_aoc_volume_unit enum 
+ *  \param currency amount 
+ *  \param currency multiplier
+ *  \param currency name, truncated after 10 characters
+ *
+ *  \retval 0 success
+ *  \retval -1 failure
+ */
 int ast_aoc_s_add_rate_volume(struct ast_aoc_decoded *decoded,
 	enum ast_aoc_s_charged_item charged_item,
 	enum ast_aoc_volume_unit volume_unit,
@@ -324,18 +363,61 @@
 	enum ast_aoc_currency_multiplier multiplier,
 	const char *currency_name);
 
+/*! \brief Add AOC-S special rate entry
+ *
+ *  \param aoc decoded object to add entry to
+ *  \param ast_aoc_s_charged_item
+ *  \param special charging code
+ *
+ *  \retval 0 success
+ *  \retval -1 failure
+ */
 int ast_aoc_s_add_rate_special_charge_code(struct ast_aoc_decoded *decoded,
 	enum ast_aoc_s_charged_item charged_item,
 	unsigned int code);
 
+/*! \brief Add AOC-S indicating charge item is free
+ *
+ *  \param aoc decoded object to add entry to
+ *  \param ast_aoc_s_charged_item
+ *
+ *  \retval 0 success
+ *  \retval -1 failure
+ */
 int ast_aoc_s_add_rate_free(struct ast_aoc_decoded *decoded,
 	enum ast_aoc_s_charged_item charged_item);
 
+/*! \brief Add AOC-S entry indicating charge item is not available
+ *
+ *  \param aoc decoded object to add entry to
+ *  \param ast_aoc_s_charged_item
+ *
+ *  \retval 0 success
+ *  \retval -1 failure
+ */
 int ast_aoc_s_add_rate_na(struct ast_aoc_decoded *decoded,
 	enum ast_aoc_s_charged_item charged_item);
 
+/*! \brief Add AOC-S special arrangement entry
+ *
+ *  \param aoc decoded object to add entry to
+ *  \param special arrangement code
+ *
+ *  \retval 0 success
+ *  \retval -1 failure
+ */
 int ast_aoc_s_add_special_arrangement(struct ast_aoc_decoded *decoded,
 	unsigned int code);
+
+/*! \brief Convert decoded aoc msg to string representation
+ *
+ *  \param ast_aoc_decoded struct to convert to string
+ *  \param dynamic heap allocated ast_str object to store string representation in
+ *
+ *  \retval 0 success
+ *  \retval -1 failure
+ */
+int ast_aoc_decoded2str(const struct ast_aoc_decoded *decoded, struct ast_str **msg);
 
 /*! \brief generate AOC manager event */
 int ast_aoc_manager_event(const struct ast_aoc_decoded *decoded, struct ast_channel *chan);

Modified: team/dvossel/generic_aoc/main/aoc.c
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/generic_aoc/main/aoc.c?view=diff&rev=255493&r1=255492&r2=255493
==============================================================================
--- team/dvossel/generic_aoc/main/aoc.c (original)
+++ team/dvossel/generic_aoc/main/aoc.c Tue Mar 30 17:33:38 2010
@@ -37,7 +37,7 @@
 #define AST_AOC_ENCODED_TYPE_REQUEST    (0 << 0)
 #define AST_AOC_ENCODED_TYPE_D          (1 << 0)
 #define AST_AOC_ENCODED_TYPE_E          (2 << 0)
-/* #define AOC_PAYLOAD_TYPE_S (3 << 0)  This is not yet supported, but reserve this for future use */
+/* #define AOC_PAYLOAD_TYPE_S (3 << 0) encoding aoc-s is not yet supported, but reserve this for future use */
 
 #define AST_AOC_ENCODED_REQUEST_S       (1 << 2)
 #define AST_AOC_ENCODED_REQUEST_D       (1 << 3)
@@ -55,7 +55,7 @@
 
 
 static char aoc_debug_enabled = 0;
-static void aoc_display_decoded(const struct ast_aoc_decoded *decoded, int decoding);
+static void aoc_display_decoded_debug(const struct ast_aoc_decoded *decoded, int decoding);
 
 /* AOC Payload Header. Holds all the encoded AOC data to pass on the wire */
 struct ast_aoc_encoded {
@@ -88,7 +88,6 @@
 	int charging_association_id;
 	uint8_t charging_association_plan;
 	char charging_association_number[32];
-
 
 	/* AOC-S charge information */
 	int aoc_s_count;
@@ -191,7 +190,6 @@
 				decoded->currency_amount = ntohl(ie.amount);
 				decoded->multiplier = ie.multiplier; /* only one byte */
 				memcpy(decoded->currency_name, ie.name, sizeof(decoded->currency_name));
-
 			} else {
 				ast_log(LOG_WARNING, "Recieved invalid currency ie\n");
 			}
@@ -289,7 +287,7 @@
 	aoc_parse_ie(decoded, encoded->data, ntohs(encoded->datalen));
 
 	if (aoc_debug_enabled) {
-		aoc_display_decoded(decoded, 1);
+		aoc_display_decoded_debug(decoded, 1);
 	}
 
 	return decoded;
@@ -300,7 +298,9 @@
 	int pos;
 };
 
-/*! \brief append an AOC information element
+/*
+ * \internal
+ * \brief append an AOC information element
  *  \note data is expecte to already be in network byte order at this point
  */
 static int aoc_append_ie(struct aoc_ie_data *ied, unsigned short ie_id, const void *data, unsigned short datalen)
@@ -318,7 +318,6 @@
 
 static void aoc_create_ie_data(struct ast_aoc_decoded *decoded, struct aoc_ie_data *ied)
 {
-
 	ied->pos = 0;
 
 	if (decoded->currency_amount) {
@@ -450,12 +449,11 @@
 	*out_size = size;
 
 	if (aoc_debug_enabled) {
-		aoc_display_decoded(decoded, 0);
+		aoc_display_decoded_debug(decoded, 0);
 	}
 
 	return encoded;
 }
-
 
 static int aoc_s_add_entry(struct ast_aoc_decoded *decoded, struct ast_aoc_s_entry *entry)
 {
@@ -974,49 +972,6 @@
 	return "NotAvailable";
 }
 
-static void aoc_request_event(const struct ast_aoc_decoded *decoded, struct ast_channel *chan, int manager, int debug)
-{
-	struct ast_str *msg;
-
-	if (!decoded) {
-		return;
-	}
-
-	msg = ast_str_create(1024);
-	if (!msg) {
-		return;
-	}
-
-	if (chan) {
-		ast_str_append(&msg, 0, "Channel: %s\r\n", chan->name);
-		ast_str_append(&msg, 0, "UniqueID: %s\r\n", chan->uniqueid);
-	}
-
-	if (decoded->request_flag) {
-		ast_str_append(&msg, 0, "AOCRequest:");
-		if (decoded->request_flag & AST_AOC_REQUEST_S) {
-			ast_str_append(&msg, 0, "S");
-		}
-		if (decoded->request_flag & AST_AOC_REQUEST_D) {
-			ast_str_append(&msg, 0, "D");
-		}
-		if (decoded->request_flag & AST_AOC_REQUEST_E) {
-			ast_str_append(&msg, 0, "E");
-		}
-		ast_str_append(&msg, 0, "AOCRequest: \r\n");
-
-	} else {
-		ast_str_append(&msg, 0, "AOCRequest: NONE");
-	}
-
-	if (debug) {
-		ast_verb(1,"%s", ast_str_buffer(msg));
-	}
-	if (manager && chan) {
-		ast_manager_event(chan, EVENT_FLAG_AOC, "AOC-Request", "%s", ast_str_buffer(msg));
-	}
-	ast_free(msg);
-}
 
 int ast_aoc_test_encode_decode_match(struct ast_aoc_decoded *decoded)
 {
@@ -1111,51 +1066,70 @@
 		aoc_multiplier_str(mult));
 }
 
-static void aoc_s_event(const struct ast_aoc_decoded *decoded, struct ast_channel *owner, int manager, int debug)
-{
-	struct ast_str *msg;
+static void aoc_request_event(const struct ast_aoc_decoded *decoded, struct ast_channel *chan, struct ast_str **msg)
+{
+	if (chan) {
+		ast_str_append(msg, 0, "Channel: %s\r\n", chan->name);
+		ast_str_append(msg, 0, "UniqueID: %s\r\n", chan->uniqueid);
+	}
+
+	if (decoded->request_flag) {
+		ast_str_append(msg, 0, "AOCRequest:");
+		if (decoded->request_flag & AST_AOC_REQUEST_S) {
+			ast_str_append(msg, 0, "S");
+		}
+		if (decoded->request_flag & AST_AOC_REQUEST_D) {
+			ast_str_append(msg, 0, "D");
+		}
+		if (decoded->request_flag & AST_AOC_REQUEST_E) {
+			ast_str_append(msg, 0, "E");
+		}
+		ast_str_append(msg, 0, "AOCRequest: \r\n");
+
+	} else {
+		ast_str_append(msg, 0, "AOCRequest: NONE");
+	}
+}
+
+static void aoc_s_event(const struct ast_aoc_decoded *decoded, struct ast_channel *owner, struct ast_str **msg)
+{
 	const char *rate_str;
 	char prefix[32];
 	int idx;
 
-	msg = ast_str_create(1024);
-	if (!msg) {
-		return;
-	}
-
 	if (owner) {
-		ast_str_append(&msg, 0, "Channel: %s\r\n", owner->name);
-		ast_str_append(&msg, 0, "UniqueID: %s\r\n", owner->uniqueid);
-	}
-
-	ast_str_append(&msg, 0, "NumberRates: %d\r\n", decoded->aoc_s_count);
+		ast_str_append(msg, 0, "Channel: %s\r\n", owner->name);
+		ast_str_append(msg, 0, "UniqueID: %s\r\n", owner->uniqueid);
+	}
+
+	ast_str_append(msg, 0, "NumberRates: %d\r\n", decoded->aoc_s_count);
 	for (idx = 0; idx < decoded->aoc_s_count; ++idx) {
 		snprintf(prefix, sizeof(prefix), "Rate(%d)", idx);
 
-		ast_str_append(&msg, 0, "%s/Chargeable: %s\r\n", prefix,
+		ast_str_append(msg, 0, "%s/Chargeable: %s\r\n", prefix,
 			aoc_charged_item_str(decoded->aoc_s_entries[idx].charged_item));
 		if (decoded->aoc_s_entries[idx].charged_item == AST_AOC_CHARGED_ITEM_NA) {
 			continue;
 		}
 		rate_str = aoc_rate_type_str(decoded->aoc_s_entries[idx].rate_type);
-		ast_str_append(&msg, 0, "%s/Type: %s\r\n", prefix, rate_str);
+		ast_str_append(msg, 0, "%s/Type: %s\r\n", prefix, rate_str);
 		switch (decoded->aoc_s_entries[idx].rate_type) {
 		case AST_AOC_RATE_TYPE_DURATION:
 			strcat(prefix, "/");
 			strcat(prefix, rate_str);
-			ast_str_append(&msg, 0, "%s/Currency: %s\r\n", prefix,
+			ast_str_append(msg, 0, "%s/Currency: %s\r\n", prefix,
 				decoded->aoc_s_entries[idx].rate.duration.currency_name);
-			aoc_amount_str(&msg, prefix,
+			aoc_amount_str(msg, prefix,
 				decoded->aoc_s_entries[idx].rate.duration.amount,
 				decoded->aoc_s_entries[idx].rate.duration.multiplier);
-			ast_str_append(&msg, 0, "%s/ChargingType: %s\r\n", prefix,
+			ast_str_append(msg, 0, "%s/ChargingType: %s\r\n", prefix,
 				decoded->aoc_s_entries[idx].rate.duration.charging_type ?
 				"StepFunction" : "ContinuousCharging");
-			aoc_time_str(&msg, prefix, "Time",
+			aoc_time_str(msg, prefix, "Time",
 				decoded->aoc_s_entries[idx].rate.duration.time,
 				decoded->aoc_s_entries[idx].rate.duration.time_scale);
 			if (decoded->aoc_s_entries[idx].rate.duration.granularity_time) {
-				aoc_time_str(&msg, prefix, "Granularity",
+				aoc_time_str(msg, prefix, "Granularity",
 					decoded->aoc_s_entries[idx].rate.duration.granularity_time,
 					decoded->aoc_s_entries[idx].rate.duration.granularity_time_scale);
 			}
@@ -1163,65 +1137,50 @@
 		case AST_AOC_RATE_TYPE_FLAT:
 			strcat(prefix, "/");
 			strcat(prefix, rate_str);
-			ast_str_append(&msg, 0, "%s/Currency: %s\r\n", prefix,
+			ast_str_append(msg, 0, "%s/Currency: %s\r\n", prefix,
 				decoded->aoc_s_entries[idx].rate.flat.currency_name);
-			aoc_amount_str(&msg, prefix,
+			aoc_amount_str(msg, prefix,
 				decoded->aoc_s_entries[idx].rate.flat.amount,
 				decoded->aoc_s_entries[idx].rate.flat.multiplier);
 			break;
 		case AST_AOC_RATE_TYPE_VOLUME:
 			strcat(prefix, "/");
 			strcat(prefix, rate_str);
-			ast_str_append(&msg, 0, "%s/Currency: %s\r\n", prefix,
+			ast_str_append(msg, 0, "%s/Currency: %s\r\n", prefix,
 				decoded->aoc_s_entries[idx].rate.volume.currency_name);
-			aoc_amount_str(&msg, prefix,
+			aoc_amount_str(msg, prefix,
 				decoded->aoc_s_entries[idx].rate.volume.amount,
 				decoded->aoc_s_entries[idx].rate.volume.multiplier);
-			ast_str_append(&msg, 0, "%s/Unit: %s\r\n", prefix,
+			ast_str_append(msg, 0, "%s/Unit: %s\r\n", prefix,
 				aoc_volume_unit_str(decoded->aoc_s_entries[idx].rate.volume.unit));
 			break;
 		case AST_AOC_RATE_TYPE_SPECIAL_CODE:
-			ast_str_append(&msg, 0, "%s/%s: %d\r\n", prefix, rate_str,
+			ast_str_append(msg, 0, "%s/%s: %d\r\n", prefix, rate_str,
 				decoded->aoc_s_entries[idx].rate.special_code);
 			break;
 		default:
 			break;
 		}
 	}
-
-	if (debug) {
-		ast_verb(1,"%s", ast_str_buffer(msg));
-	}
-	if (manager && owner) {
-		ast_manager_event(owner, EVENT_FLAG_AOC, "AOC-S", "%s", ast_str_buffer(msg));
-	}
-	ast_free(msg);
-}
-
-static void aoc_d_event(const struct ast_aoc_decoded *decoded, struct ast_channel *chan, int manager, int debug)
-{
-	struct ast_str *msg;
+}
+
+static void aoc_d_event(const struct ast_aoc_decoded *decoded, struct ast_channel *chan, struct ast_str **msg)
+{
 	const char *charge_str;
 	int idx;
 	char prefix[32];
 
-	msg = ast_str_create(1024);
-
-	if (!msg) {
-		return;
-	}
-
 	if (chan) {
-		ast_str_append(&msg, 0, "Channel: %s\r\n", chan->name);
-		ast_str_append(&msg, 0, "UniqueID: %s\r\n", chan->uniqueid);
+		ast_str_append(msg, 0, "Channel: %s\r\n", chan->name);
+		ast_str_append(msg, 0, "UniqueID: %s\r\n", chan->uniqueid);
 	}
 
 	charge_str = aoc_charge_type_str(decoded->charge_type);
-	ast_str_append(&msg, 0, "Type: %s\r\n", charge_str);
+	ast_str_append(msg, 0, "Type: %s\r\n", charge_str);
 	switch (decoded->charge_type) {
 	case AST_AOC_CHARGE_CURRENCY:
 	case AST_AOC_CHARGE_UNIT:
-		ast_str_append(&msg, 0, "BillingID: %s\r\n",
+		ast_str_append(msg, 0, "BillingID: %s\r\n",
 			aoc_billingid_str(decoded->billing_id));
 		break;
 	default:
@@ -1229,76 +1188,56 @@
 	}
 	switch (decoded->charge_type) {
 	case AST_AOC_CHARGE_CURRENCY:
-		ast_str_append(&msg, 0, "%s: %s\r\n", charge_str,
+		ast_str_append(msg, 0, "%s: %s\r\n", charge_str,
 			decoded->currency_name);
-		aoc_amount_str(&msg, charge_str,
+		aoc_amount_str(msg, charge_str,
 			decoded->currency_amount,
 			decoded->multiplier);
 		break;
 	case AST_AOC_CHARGE_UNIT:
-		ast_str_append(&msg, 0, "%s/NumberItems: %d\r\n", charge_str,
+		ast_str_append(msg, 0, "%s/NumberItems: %d\r\n", charge_str,
 			decoded->unit_count);
 		for (idx = 0; idx < decoded->unit_count; ++idx) {
 			snprintf(prefix, sizeof(prefix), "%s/Item(%d)", charge_str, idx);
-			ast_str_append(&msg, 0, "%s/NumberOf: %u\r\n", prefix,
+			ast_str_append(msg, 0, "%s/NumberOf: %u\r\n", prefix,
 				decoded->unit_list[idx].amount);
-			ast_str_append(&msg, 0, "%s/TypeOf: %d\r\n", prefix,
+			ast_str_append(msg, 0, "%s/TypeOf: %d\r\n", prefix,
 				decoded->unit_list[idx].type);
 		}
 		break;
 	default:
 		break;
 	}
-
-	if (debug) {
-		ast_verb(1,"%s", ast_str_buffer(msg));
-	}
-
-	if (manager && chan) {
-		ast_manager_event(chan, EVENT_FLAG_AOC, "AOC-D", "%s", ast_str_buffer(msg));
-	}
-	ast_free(msg);
-}
-
-static void aoc_e_event(const struct ast_aoc_decoded *decoded, struct ast_channel *chan, int manager, int debug)
-{
-	struct ast_channel *chans[1];
-	struct ast_str *msg;
+}
+
+static void aoc_e_event(const struct ast_aoc_decoded *decoded, struct ast_channel *chan, struct ast_str **msg)
+{
 	const char *charge_str;
 	int idx;
 	char prefix[32];
 
-	if (!decoded) {
-		return;
-	}
-
-	msg = ast_str_create(1024);
-	if (!msg) {
-		return;
-	}
-
 	if (chan) {
-		ast_str_append(&msg, 0, "Channel: %s\r\n", chan->name);
-		ast_str_append(&msg, 0, "UniqueID: %s\r\n", chan->uniqueid);
+		ast_str_append(msg, 0, "Channel: %s\r\n", chan->name);
+		ast_str_append(msg, 0, "UniqueID: %s\r\n", chan->uniqueid);
 	}
 
 	charge_str = "ChargingAssociation";
 	if (!ast_strlen_zero(decoded->charging_association_number)) {
 		snprintf(prefix, sizeof(prefix), "%s/Number", charge_str);
-		ast_str_append(&msg, 0, "%s: %s\r\n", prefix,
+		ast_str_append(msg, 0, "%s: %s\r\n", prefix,
 			decoded->charging_association_number);
-		ast_str_append(&msg, 0, "%s/Plan: %d\r\n", prefix,
+		ast_str_append(msg, 0, "%s/Plan: %d\r\n", prefix,
 			decoded->charging_association_plan);
 	} else if (decoded->charging_association_id) {
-		ast_str_append(&msg, 0, "%s/ID: %d\r\n", charge_str, decoded->charging_association_id);
+		ast_str_append(msg, 0, "%s/ID: %d\r\n", charge_str, decoded->charging_association_id);
 	}
 
 	charge_str = aoc_charge_type_str(decoded->charge_type);
-	ast_str_append(&msg, 0, "Type: %s\r\n", charge_str);
+	ast_str_append(msg, 0, "Type: %s\r\n", charge_str);
 	switch (decoded->charge_type) {
 	case AST_AOC_CHARGE_CURRENCY:
 	case AST_AOC_CHARGE_UNIT:
-		ast_str_append(&msg, 0, "BillingID: %s\r\n",
+		ast_str_append(msg, 0, "BillingID: %s\r\n",
 			aoc_billingid_str(decoded->billing_id));
 		break;
 	default:
@@ -1306,90 +1245,117 @@
 	}
 	switch (decoded->charge_type) {
 	case AST_AOC_CHARGE_CURRENCY:
-		ast_str_append(&msg, 0, "%s: %s\r\n", charge_str,
+		ast_str_append(msg, 0, "%s: %s\r\n", charge_str,
 			decoded->currency_name);
-		aoc_amount_str(&msg, charge_str,
+		aoc_amount_str(msg, charge_str,
 			decoded->currency_amount,
 			decoded->multiplier);
 		break;
 	case AST_AOC_CHARGE_UNIT:
-		ast_str_append(&msg, 0, "%s/NumberItems: %d\r\n", charge_str,
+		ast_str_append(msg, 0, "%s/NumberItems: %d\r\n", charge_str,
 			decoded->unit_count);
 		for (idx = 0; idx < decoded->unit_count; ++idx) {
 			snprintf(prefix, sizeof(prefix), "%s/Item(%d)", charge_str, idx);
-			ast_str_append(&msg, 0, "%s/NumberOf: %u\r\n", prefix,
+			ast_str_append(msg, 0, "%s/NumberOf: %u\r\n", prefix,
 				decoded->unit_list[idx].amount);
-			ast_str_append(&msg, 0, "%s/TypeOf: %d\r\n", prefix,
+			ast_str_append(msg, 0, "%s/TypeOf: %d\r\n", prefix,
 				decoded->unit_list[idx].type);
 		}
 		break;
 	default:
 		break;
 	}
-
-	if (debug) {
-		ast_verb(1,"%s", ast_str_buffer(msg));
-	}
-
-	if (manager) {
-		chans[0] = chan;
-		ast_manager_event_multichan(EVENT_FLAG_AOC, "AOC-E", chan ? 1 : 0, chans, "%s",
-			ast_str_buffer(msg));
-	}
-	ast_free(msg);
 }
 
 int ast_aoc_manager_event(const struct ast_aoc_decoded *decoded, struct ast_channel *chan)
 {
-	if (!decoded) {
+	struct ast_str *msg;
+
+	if (!decoded || !(msg = ast_str_create(1024))) {
 		return -1;
 	}
 
 	switch (decoded->msg_type) {
 	case AST_AOC_S:
-		aoc_s_event(decoded, chan, 1, 0);
+		if (chan) {
+			aoc_s_event(decoded, chan, &msg);
+			ast_manager_event(chan, EVENT_FLAG_AOC, "AOC-S", "%s", ast_str_buffer(msg));
+		}
 		break;
 	case AST_AOC_D:
-		aoc_d_event(decoded, chan, 1, 0);
+		if (chan) {
+			aoc_d_event(decoded, chan, &msg);
+			ast_manager_event(chan, EVENT_FLAG_AOC, "AOC-D", "%s", ast_str_buffer(msg));
+		}
 		break;
 	case AST_AOC_E:
-		aoc_e_event(decoded, chan, 1, 0);
+		{
+			struct ast_channel *chans[1];
+			aoc_e_event(decoded, chan, &msg);
+			chans[0] = chan;
+			ast_manager_event_multichan(EVENT_FLAG_AOC, "AOC-E", chan ? 1 : 0, chans, "%s", ast_str_buffer(msg));
+		}
 		break;
 	case AST_AOC_REQUEST:
-		aoc_request_event(decoded, chan, 1, 0);
-		break;
-	}
-
+		if (chan) {
+			aoc_request_event(decoded, chan, &msg);
+			ast_manager_event(chan, EVENT_FLAG_AOC, "AOC-Request", "%s", ast_str_buffer(msg));
+		}
+		break;
+	}
+
+	ast_free(msg);
 	return 0;
 }
 
-static void aoc_display_decoded(const struct ast_aoc_decoded *decoded, int decoding)
-{
+int ast_aoc_decoded2str(const struct ast_aoc_decoded *decoded, struct ast_str **msg)
+{
+	if (!decoded || !msg) {
+		return -1;
+	}
+
+	switch (decoded->msg_type) {
+	case AST_AOC_S:
+		ast_str_append(msg, 0, "AOC-S\r\n");
+		aoc_s_event(decoded, NULL, msg);
+		break;
+	case AST_AOC_D:
+		ast_str_append(msg, 0, "AOC-D\r\n");
+		aoc_d_event(decoded, NULL, msg);
+		break;
+	case AST_AOC_E:
+		ast_str_append(msg, 0, "AOC-E\r\n");
+		aoc_e_event(decoded, NULL, msg);
+		break;
+	case AST_AOC_REQUEST:
+		ast_str_append(msg, 0, "AOC-Request\r\n");
+		aoc_request_event(decoded, NULL, msg);
+		break;
+	}
+
+	return 0;
+}
+
+static void aoc_display_decoded_debug(const struct ast_aoc_decoded *decoded, int decoding)
+{
+	struct ast_str *msg;
+
+	if (!decoded || !(msg = ast_str_create(1024))) {
+		return;
+	}
+
+	if (ast_aoc_decoded2str(decoded, &msg)) {
+		ast_free(msg);
+		return;
+	}
+
 	if (decoding) {
 		ast_verb(1, "---- DECODED AOC MSG ----\r\n");
 	} else {
 		ast_verb(1, "---- ENCODED AOC MSG ----\r\n");
 	}
-
-	switch (decoded->msg_type) {
-	case AST_AOC_S:
-		ast_verb(1, "AOC-S\r\n");
-		aoc_s_event(decoded, NULL, 0, 1);
-		break;
-	case AST_AOC_D:
-		ast_verb(1, "AOC-D\r\n");
-		aoc_d_event(decoded, NULL, 0, 1);
-		break;
-	case AST_AOC_E:
-		ast_verb(1, "AOC-E\r\n");
-		aoc_e_event(decoded, NULL, 0, 1);
-		break;
-	case AST_AOC_REQUEST:
-		ast_verb(1, "AOC-Request\r\n");
-		aoc_request_event(decoded, NULL, 1, 0);
-		break;
-	}
-	ast_verb(1, "\r\n");
+	ast_verb(1, "%s\r\n", ast_str_buffer(msg));
+	ast_free(msg);
 }
 
 static struct ast_cli_entry aoc_cli[] = {

Modified: team/dvossel/generic_aoc/tests/test_aoc.c
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/generic_aoc/tests/test_aoc.c?view=diff&rev=255493&r1=255492&r2=255493
==============================================================================
--- team/dvossel/generic_aoc/tests/test_aoc.c (original)
+++ team/dvossel/generic_aoc/tests/test_aoc.c Tue Mar 30 17:33:38 2010
@@ -37,6 +37,211 @@
 #include "asterisk/module.h"
 #include "asterisk/test.h"
 #include "asterisk/aoc.h"
+
+
+AST_TEST_DEFINE(aoc_event_generation_test)
+{
+	int res = AST_TEST_PASS;
+	struct ast_aoc_decoded *decoded = NULL;
+	struct ast_str *msg = NULL;
+
+	switch (cmd) {
+	case TEST_INIT:
+		info->name = "aoc_event_test";
+		info->category = "main/aoc/";
+		info->summary = "Advice of Charge event generation test";
+		info->description =
+			"Creates AOC messages, verify event string matches expected results";
+		return AST_TEST_NOT_RUN;
+	case TEST_EXECUTE:
+		break;
+	}
+
+	if (!(msg = ast_str_create(1024))) {
+		goto cleanup_aoc_event_test;
+	}
+
+	/* ---- TEST 1, AOC-D event generation */
+	if (!(decoded = ast_aoc_create(AST_AOC_D, AST_AOC_CHARGE_CURRENCY, 0))) {
+
+		ast_test_status_update(test, "failed to create AOC-D message for event generation.\n");
+		res = AST_TEST_FAIL;
+		goto cleanup_aoc_event_test;
+	}
+	/* Add billing id information */
+	ast_aoc_set_billing_id(decoded, AST_AOC_BILLING_CREDIT_CARD);
+
+	/* Set currency information, verify results */
+	if ((ast_aoc_set_currency_info(decoded, 100, AST_AOC_MULT_ONE, "usd")) ||
+		(ast_aoc_set_total_type(decoded, AST_AOC_SUBTOTAL))) {
+
+		ast_test_status_update(test, "failed to set currency info in AOC-D msg\n");
+		res = AST_TEST_FAIL;
+		goto cleanup_aoc_event_test;
+	}
+	if (ast_aoc_decoded2str(decoded, &msg)) {
+
+		ast_test_status_update(test, "failed to generate AOC-D msg string.\n");
+		res = AST_TEST_FAIL;
+		goto cleanup_aoc_event_test;
+	}
+	if (strncmp(ast_str_buffer(msg),
+		"AOC-D\r\nType: Currency\r\nBillingID: CreditCard\r\n"
+		"Currency: usd\r\nCurrency/Amount/Cost: 100\r\n"
+		"Currency/Amount/Multiplier: 1\r\n",
+		strlen(ast_str_buffer(msg)))) {
+
+		ast_test_status_update(test, "AOC-D msg event did not match expected results\n");
+		res = AST_TEST_FAIL;
+		goto cleanup_aoc_event_test;
+	}
+	decoded = ast_aoc_destroy_decoded(decoded);
+	ast_str_reset(msg);
+
+
+	/* ---- TEST 2, AOC-S event generation */
+	if (!(decoded = ast_aoc_create(AST_AOC_S, 0, 0))) {
+		ast_test_status_update(test, "failed to create AOC-S message for event generation.\n");
+
+		res = AST_TEST_FAIL;
+		goto cleanup_aoc_event_test;
+	}
+
+	ast_aoc_s_add_rate_flat(decoded,
+		AST_AOC_CHARGED_ITEM_BASIC_COMMUNICATION,
+		123,
+		AST_AOC_MULT_TEN,
+		"pineapple");
+
+	ast_aoc_s_add_rate_volume(decoded,
+		AST_AOC_CHARGED_ITEM_CALL_ATTEMPT,
+		AST_AOC_VOLUME_UNIT_SEGMENT,
+		937,
+		AST_AOC_MULT_ONEHUNDREDTH,
+		"oranges");
+
+	ast_aoc_s_add_rate_duration(decoded,
+		AST_AOC_CHARGED_ITEM_CALL_ATTEMPT,
+		937,
+		AST_AOC_MULT_ONETHOUSANDTH,
+		"bananas",
+		848,
+		AST_AOC_TIME_SCALE_TENTH_SECOND,
+		949,
+		AST_AOC_TIME_SCALE_HOUR,
+		1);
+
+	ast_aoc_s_add_rate_duration(decoded,
+		AST_AOC_CHARGED_ITEM_USER_USER_INFO,
+		937,
+		AST_AOC_MULT_THOUSAND,
+		"bananas",
+		1111,
+		AST_AOC_TIME_SCALE_SECOND,
+		2222,
+		AST_AOC_TIME_SCALE_DAY,
+		0);
+
+	if (ast_aoc_decoded2str(decoded, &msg)) {
+
+		ast_test_status_update(test, "failed to generate AOC-D msg string.\n");
+		res = AST_TEST_FAIL;
+		goto cleanup_aoc_event_test;
+	}
+
+
+	if (strncmp(ast_str_buffer(msg),
+		"AOC-S\r\n"
+		"NumberRates: 4\r\n"
+		"Rate(0)/Chargeable: BasicCommunication\r\n"
+		"Rate(0)/Type: Flat\r\n"
+		"Rate(0)/Flat/Currency: pineapple\r\n"
+		"Rate(0)/Flat/Amount/Cost: 123\r\n"
+		"Rate(0)/Flat/Amount/Multiplier: 10\r\n"
+		"Rate(1)/Chargeable: CallAttempt\r\n"
+		"Rate(1)/Type: Volume\r\n"
+		"Rate(1)/Volume/Currency: oranges\r\n"
+		"Rate(1)/Volume/Amount/Cost: 937\r\n"
+		"Rate(1)/Volume/Amount/Multiplier: 1/100\r\n"
+		"Rate(1)/Volume/Unit: Segment\r\n"
+		"Rate(2)/Chargeable: CallAttempt\r\n"
+		"Rate(2)/Type: Duration\r\n"
+		"Rate(2)/Duration/Currency: bananas\r\n"
+		"Rate(2)/Duration/Amount/Cost: 937\r\n"
+		"Rate(2)/Duration/Amount/Multiplier: 1/1000\r\n"
+		"Rate(2)/Duration/ChargingType: StepFunction\r\n"
+		"Rate(2)/Duration/Time/Length: 848\r\n"
+		"Rate(2)/Duration/Time/Scale: OneTenthSecond\r\n"
+		"Rate(2)/Duration/Granularity/Length: 949\r\n"
+		"Rate(2)/Duration/Granularity/Scale: Hour\r\n"
+		"Rate(3)/Chargeable: UserUserInfo\r\n"
+		"Rate(3)/Type: Duration\r\n"
+		"Rate(3)/Duration/Currency: bananas\r\n"
+		"Rate(3)/Duration/Amount/Cost: 937\r\n"
+		"Rate(3)/Duration/Amount/Multiplier: 1000\r\n"
+		"Rate(3)/Duration/ChargingType: ContinuousCharging\r\n"
+		"Rate(3)/Duration/Time/Length: 1111\r\n"
+		"Rate(3)/Duration/Time/Scale: Second\r\n"
+		"Rate(3)/Duration/Granularity/Length: 2222\r\n"
+		"Rate(3)/Duration/Granularity/Scale: Day\r\n",
+		strlen(ast_str_buffer(msg)))) {
+
+		ast_test_status_update(test, "AOC-S msg event did not match expected results\n");
+		res = AST_TEST_FAIL;
+		goto cleanup_aoc_event_test;
+	}
+	decoded = ast_aoc_destroy_decoded(decoded);
+	ast_str_reset(msg);
+
+	/* ---- TEST 3, AOC-E event generation */
+	if (!(decoded = ast_aoc_create(AST_AOC_E, AST_AOC_CHARGE_UNIT, 0))) {
+		ast_test_status_update(test, "failed to create AOC-E message for event generation.\n");
+
+		res = AST_TEST_FAIL;
+		goto cleanup_aoc_event_test;
+	}
+	if ((ast_aoc_add_unit_entry(decoded, 111, 1)) ||
+		(ast_aoc_add_unit_entry(decoded, 2222, 2)) ||
+		(ast_aoc_add_unit_entry(decoded, 3333, 3)) ||
+		(ast_aoc_add_unit_entry(decoded, 44444, 4))) {
+
+		ast_test_status_update(test, "failed to set unit info for AOC-E message\n");
+		res = AST_TEST_FAIL;
+		goto cleanup_aoc_event_test;
+	}
+	if (ast_aoc_decoded2str(decoded, &msg)) {
+
+		ast_test_status_update(test, "failed to generate AOC-E msg string.\n");
+		res = AST_TEST_FAIL;
+		goto cleanup_aoc_event_test;
+	}
+
+	if (strncmp(ast_str_buffer(msg),
+		"AOC-E\r\n"
+		"Type: Units\r\n"
+		"BillingID: NotAvailable\r\n"
+		"Units/NumberItems: 4\r\n"
+		"Units/Item(0)/NumberOf: 111\r\n"
+		"Units/Item(0)/TypeOf: 1\r\n"
+		"Units/Item(1)/NumberOf: 2222\r\n"
+		"Units/Item(1)/TypeOf: 2\r\n"
+		"Units/Item(2)/NumberOf: 3333\r\n"
+		"Units/Item(2)/TypeOf: 3\r\n"
+		"Units/Item(3)/NumberOf: 44444\r\n"
+		"Units/Item(3)/TypeOf: 4\r\n",
+		strlen(ast_str_buffer(msg)))) {
+
+		ast_test_status_update(test, "AOC-E msg event did not match expected results\n");
+		res = AST_TEST_FAIL;
+		goto cleanup_aoc_event_test;
+	}
+
+cleanup_aoc_event_test:
+
+	decoded = ast_aoc_destroy_decoded(decoded);
+	ast_free(msg);
+	return res;
+}
 
 AST_TEST_DEFINE(aoc_encode_decode_test)
 {
@@ -310,12 +515,14 @@
 static int unload_module(void)
 {
 	AST_TEST_UNREGISTER(aoc_encode_decode_test);
+	AST_TEST_UNREGISTER(aoc_event_generation_test);
 	return 0;
 }
 
 static int load_module(void)
 {
 	AST_TEST_REGISTER(aoc_encode_decode_test);
+	AST_TEST_REGISTER(aoc_event_generation_test);
 	return AST_MODULE_LOAD_SUCCESS;
 }
 




More information about the svn-commits mailing list