[svn-commits] dvossel: branch dvossel/generic_aoc r256218 - in /team/dvossel/generic_aoc: i...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Mon Apr 5 14:25:08 CDT 2010


Author: dvossel
Date: Mon Apr  5 14:25:06 2010
New Revision: 256218

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=256218
Log:
aoc-s encode decode routines

Modified:
    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/include/asterisk/aoc.h
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/generic_aoc/include/asterisk/aoc.h?view=diff&rev=256218&r1=256217&r2=256218
==============================================================================
--- team/dvossel/generic_aoc/include/asterisk/aoc.h (original)
+++ team/dvossel/generic_aoc/include/asterisk/aoc.h Mon Apr  5 14:25:06 2010
@@ -95,20 +95,20 @@
 
 struct ast_aoc_time {
 	/*! LengthOfTimeUnit (Not valid if length is zero.) */
-	unsigned long length;
-	enum ast_aoc_time_scale scale;
+	uint32_t length;
+	uint16_t scale;
 };
 
 struct ast_aoc_duration_rate {
-	enum ast_aoc_currency_multiplier multiplier;
-	unsigned int amount;
-
-	unsigned long time;
-	enum ast_aoc_time_scale time_scale;
+	uint16_t multiplier;
+	uint32_t amount;
+
+	uint32_t time;
+	uint16_t time_scale;
 
 	/*! Not present if the granularity time is zero. */
-	unsigned long granularity_time;
-	enum ast_aoc_time_scale granularity_time_scale;
+	uint32_t granularity_time;
+	uint16_t granularity_time_scale;
 
 	/*!
 	 * \brief Charging interval type
@@ -128,15 +128,15 @@
 };
 
 struct ast_aoc_volume_rate {
-	enum ast_aoc_currency_multiplier multiplier;
-	unsigned int amount;
-	enum ast_aoc_volume_unit unit;
+	uint16_t multiplier;
+	uint32_t amount;
+	uint16_t volume_unit;
 	char currency_name[AOC_CURRENCY_NAME_SIZE];
 };
 
 struct ast_aoc_flat_rate {
-	enum ast_aoc_currency_multiplier multiplier;
-	unsigned int amount;
+	uint16_t multiplier;
+	uint32_t amount;
 
 	/*! Name of currency involved.  Null terminated. */
 	char currency_name[AOC_CURRENCY_NAME_SIZE];
@@ -162,16 +162,16 @@
 	AST_AOC_RATE_TYPE_SPECIAL_CODE,
 };
 struct ast_aoc_s_entry {
-	enum ast_aoc_s_charged_item charged_item;
-
-	enum ast_aoc_s_rate_type rate_type;
+	uint16_t charged_item;
+
+	uint16_t rate_type;
 
 	/*! \brief Charge rate being applied. */
 	union {
 		struct ast_aoc_duration_rate duration;
 		struct ast_aoc_flat_rate flat;
 		struct ast_aoc_volume_rate volume;
-		unsigned int special_code; /* 1...10 */
+		uint16_t special_code; /* 1...10 */
 	} rate;
 };
 

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=256218&r1=256217&r2=256218
==============================================================================
--- team/dvossel/generic_aoc/main/aoc.c (original)
+++ team/dvossel/generic_aoc/main/aoc.c Mon Apr  5 14:25:06 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) encoding aoc-s is not yet supported, but reserve this for future use */
+#define AST_AOC_ENCODED_TYPE_S          (3 << 0)
 
 #define AST_AOC_ENCODED_REQUEST_S       (1 << 2)
 #define AST_AOC_ENCODED_REQUEST_D       (1 << 3)
@@ -56,6 +56,7 @@
 
 static char aoc_debug_enabled = 0;
 static void aoc_display_decoded_debug(const struct ast_aoc_decoded *decoded, int decoding);
+static int aoc_s_add_entry(struct ast_aoc_decoded *decoded, struct ast_aoc_s_entry *entry);
 
 /* AOC Payload Header. Holds all the encoded AOC data to pass on the wire */
 struct ast_aoc_encoded {
@@ -126,6 +127,11 @@
 	char charge_number[32];
 };
 
+#define AOC_IE_RATE 5
+struct aoc_ie_charging_rate {
+	struct ast_aoc_s_entry entry;
+};
+
 struct ast_aoc_decoded *ast_aoc_create(const enum ast_aoc_type msg_type,
 		const enum ast_aoc_charge_type charge_type,
 		const enum ast_aoc_request requests)
@@ -167,6 +173,56 @@
 {
 	ast_free(encoded);
 	return NULL;
+}
+
+static void aoc_parse_ie_charging_rate(struct ast_aoc_decoded *decoded, const struct aoc_ie_charging_rate *ie)
+{
+	struct ast_aoc_s_entry entry = { 0, };
+
+	entry.charged_item = ntohs(ie->entry.charged_item);
+	entry.rate_type = ntohs(ie->entry.rate_type);
+
+	switch (entry.rate_type) {
+	case AST_AOC_RATE_TYPE_DURATION:
+		entry.rate.duration.multiplier = ntohs(ie->entry.rate.duration.multiplier);
+		entry.rate.duration.amount = ntohl(ie->entry.rate.duration.amount);
+		entry.rate.duration.time = ntohl(ie->entry.rate.duration.time);
+		entry.rate.duration.time_scale = ntohs(ie->entry.rate.duration.time_scale);
+		entry.rate.duration.granularity_time = ntohl(ie->entry.rate.duration.granularity_time);
+		entry.rate.duration.granularity_time_scale = ntohs(ie->entry.rate.duration.granularity_time_scale);
+		entry.rate.duration.charging_type = ie->entry.rate.duration.charging_type; /* only one byte */
+
+		if (!ast_strlen_zero(ie->entry.rate.duration.currency_name)) {
+			ast_copy_string(entry.rate.duration.currency_name,
+				ie->entry.rate.duration.currency_name,
+				sizeof(entry.rate.duration.currency_name));
+		}
+		break;
+	case AST_AOC_RATE_TYPE_FLAT:
+		entry.rate.flat.multiplier = ntohs(ie->entry.rate.flat.multiplier);
+		entry.rate.flat.amount = ntohl(ie->entry.rate.flat.amount);
+		if (!ast_strlen_zero(ie->entry.rate.flat.currency_name)) {
+			ast_copy_string(entry.rate.flat.currency_name,
+				ie->entry.rate.flat.currency_name,
+				sizeof(entry.rate.flat.currency_name));
+		}
+		break;
+	case AST_AOC_RATE_TYPE_VOLUME:
+		entry.rate.volume.multiplier = ntohs(ie->entry.rate.volume.multiplier);
+		entry.rate.volume.amount = ntohl(ie->entry.rate.volume.amount);
+		entry.rate.volume.volume_unit = ntohs(ie->entry.rate.volume.volume_unit);
+		if (!ast_strlen_zero(ie->entry.rate.volume.currency_name)) {
+			ast_copy_string(entry.rate.volume.currency_name,
+				ie->entry.rate.volume.currency_name,
+				sizeof(entry.rate.volume.currency_name));
+		}
+		break;
+	case AST_AOC_RATE_TYPE_SPECIAL_CODE:
+		entry.rate.special_code = ntohs(ie->entry.rate.special_code);
+		break;
+	}
+
+	aoc_s_add_entry(decoded, &entry);
 }
 
 static int aoc_parse_ie(struct ast_aoc_decoded *decoded, unsigned char *data, unsigned int datalen)
@@ -223,6 +279,15 @@
 				ast_log(LOG_WARNING, "Recieved invalid charging association ie\n");
 			}
 			break;
+		case AOC_IE_RATE:
+			if (len == sizeof(struct aoc_ie_charging_rate)) {
+				struct aoc_ie_charging_rate ie;
+				memcpy(&ie, data + 2, len);
+				aoc_parse_ie_charging_rate(decoded, &ie);
+			} else {
+				ast_log(LOG_WARNING, "Recieved invalid charging rate ie\n");
+			}
+			break;
 		default:
 			ast_log(LOG_WARNING, "Unknown AOC Information Element, ignoring.\n");
 		}
@@ -249,7 +314,10 @@
 	}
 
 	/* decode flags */
-	if (encoded->flags & AST_AOC_ENCODED_TYPE_E) {
+
+	if ((encoded->flags & AST_AOC_ENCODED_TYPE_S) == AST_AOC_ENCODED_TYPE_S) {
+		decoded->msg_type = AST_AOC_S;
+	} else if (encoded->flags & AST_AOC_ENCODED_TYPE_E) {
 		decoded->msg_type = AST_AOC_E;
 	} else if (encoded->flags & AST_AOC_ENCODED_TYPE_D) {
 		decoded->msg_type = AST_AOC_D;
@@ -267,7 +335,7 @@
 		if (encoded->flags & AST_AOC_ENCODED_REQUEST_E) {
 			decoded->request_flag |= AST_AOC_REQUEST_E;
 		}
-	} else {
+	} else if ((decoded->msg_type == AST_AOC_D) || (decoded->msg_type == AST_AOC_E)) {
 		if ((encoded->flags & AST_AOC_ENCODED_CHARGE_UNIT) == AST_AOC_ENCODED_CHARGE_UNIT) {
 			decoded->charge_type = AST_AOC_CHARGE_UNIT;
 		} else if ((encoded->flags & AST_AOC_ENCODED_CHARGE_CURRENCY) == AST_AOC_ENCODED_CHARGE_CURRENCY) {
@@ -316,6 +384,52 @@
 	return 0;
 }
 
+static void aoc_create_ie_data_charging_rate(const struct ast_aoc_s_entry *entry, struct aoc_ie_charging_rate *ie)
+{
+	ie->entry.charged_item = htons(entry->charged_item);
+	ie->entry.rate_type = htons(entry->rate_type);
+
+	switch (entry->rate_type) {
+	case AST_AOC_RATE_TYPE_DURATION:
+		ie->entry.rate.duration.multiplier = htons(entry->rate.duration.multiplier);
+		ie->entry.rate.duration.amount = htonl(entry->rate.duration.amount);
+		ie->entry.rate.duration.time = htonl(entry->rate.duration.time);
+		ie->entry.rate.duration.time_scale = htons(entry->rate.duration.time_scale);
+		ie->entry.rate.duration.granularity_time = htonl(entry->rate.duration.granularity_time);
+		ie->entry.rate.duration.granularity_time_scale = htons(entry->rate.duration.granularity_time_scale);
+		ie->entry.rate.duration.charging_type = entry->rate.duration.charging_type; /* only one byte */
+
+		if (!ast_strlen_zero(entry->rate.duration.currency_name)) {
+			ast_copy_string(ie->entry.rate.duration.currency_name,
+				entry->rate.duration.currency_name,
+				sizeof(ie->entry.rate.duration.currency_name));
+		}
+		break;
+	case AST_AOC_RATE_TYPE_FLAT:
+		ie->entry.rate.flat.multiplier = htons(entry->rate.flat.multiplier);
+		ie->entry.rate.flat.amount = htonl(entry->rate.flat.amount);
+		if (!ast_strlen_zero(entry->rate.flat.currency_name)) {
+			ast_copy_string(ie->entry.rate.flat.currency_name,
+				entry->rate.flat.currency_name,
+				sizeof(ie->entry.rate.flat.currency_name));
+		}
+		break;
+	case AST_AOC_RATE_TYPE_VOLUME:
+		ie->entry.rate.volume.multiplier = htons(entry->rate.volume.multiplier);
+		ie->entry.rate.volume.amount = htonl(entry->rate.volume.amount);
+		ie->entry.rate.volume.volume_unit = htons(entry->rate.volume.volume_unit);
+		if (!ast_strlen_zero(entry->rate.volume.currency_name)) {
+			ast_copy_string(ie->entry.rate.volume.currency_name,
+				entry->rate.volume.currency_name,
+				sizeof(ie->entry.rate.volume.currency_name));
+		}
+		break;
+	case AST_AOC_RATE_TYPE_SPECIAL_CODE:
+		ie->entry.rate.special_code = htons(entry->rate.special_code);
+		break;
+	}
+
+}
 static void aoc_create_ie_data(struct ast_aoc_decoded *decoded, struct aoc_ie_data *ied)
 {
 	ied->pos = 0;
@@ -359,6 +473,16 @@
 		}
 		aoc_append_ie(ied, AOC_IE_CHARGING_ASSOCIATION, (const void *) &ie, sizeof(ie));
 	}
+
+	if (decoded->aoc_s_count) {
+		struct aoc_ie_charging_rate ie;
+		int i;
+		for (i = 0; i < decoded->aoc_s_count; i++) {
+			memset(&ie, 0, sizeof(ie));
+			aoc_create_ie_data_charging_rate(&decoded->aoc_s_entries[i], &ie);
+			aoc_append_ie(ied, AOC_IE_RATE, (const void *) &ie, sizeof(ie));
+		}
+	}
 }
 
 struct ast_aoc_encoded *ast_aoc_encode(struct ast_aoc_decoded *decoded, size_t *out_size)
@@ -371,10 +495,6 @@
 		return NULL;
 	}
 
-	if (decoded->msg_type == AST_AOC_S) {
-		ast_log(LOG_ERROR, "Cannot encode AOC-S message, pass through of AOC-S is supported\n");
-		return NULL;
-	}
 	*out_size = 0;
 
 	/* create information element buffer before allocating the payload,
@@ -398,6 +518,9 @@
 
 	/* --- Set Flags --- */
 	switch (decoded->msg_type) {
+	case AST_AOC_S:
+		encoded->flags = AST_AOC_ENCODED_TYPE_S;
+		break;
 	case AST_AOC_D:
 		encoded->flags = AST_AOC_ENCODED_TYPE_D;
 		break;
@@ -421,7 +544,7 @@
 		if (decoded->request_flag & AST_AOC_REQUEST_E) {
 			encoded->flags |= AST_AOC_ENCODED_REQUEST_E;
 		}
-	} else {
+	} else if ((decoded->msg_type == AST_AOC_D) || (decoded->msg_type == AST_AOC_E)) {
 		switch (decoded->charge_type) {
 		case AST_AOC_CHARGE_UNIT:
 			encoded->flags |= AST_AOC_ENCODED_CHARGE_UNIT;
@@ -531,7 +654,7 @@
 	entry.rate_type = AST_AOC_RATE_TYPE_VOLUME;
 	entry.rate.volume.multiplier = multiplier;
 	entry.rate.volume.amount = amount;
-	entry.rate.volume.unit = volume_unit;
+	entry.rate.volume.volume_unit = volume_unit;
 
 	if (!ast_strlen_zero(currency_name)) {
 		ast_copy_string(entry.rate.volume.currency_name, currency_name, sizeof(entry.rate.volume.currency_name));
@@ -1152,7 +1275,7 @@
 				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,
-				aoc_volume_unit_str(decoded->aoc_s_entries[idx].rate.volume.unit));
+				aoc_volume_unit_str(decoded->aoc_s_entries[idx].rate.volume.volume_unit));
 			break;
 		case AST_AOC_RATE_TYPE_SPECIAL_CODE:
 			ast_str_append(msg, 0, "%s/%s: %d\r\n", prefix, rate_str,

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=256218&r1=256217&r2=256218
==============================================================================
--- team/dvossel/generic_aoc/tests/test_aoc.c (original)
+++ team/dvossel/generic_aoc/tests/test_aoc.c Mon Apr  5 14:25:06 2010
@@ -506,6 +506,60 @@
 	/* cleanup decoded msg */
 	decoded = ast_aoc_destroy_decoded(decoded);
 
+
+/* ---- TEST 6, AOC-S encode decode */
+	if (!(decoded = ast_aoc_create(AST_AOC_S, 0, 0))) {
+		ast_test_status_update(test, "failed to create AOC-S message for encode decode testing.\n");
+
+		res = AST_TEST_FAIL;
+		goto cleanup_aoc_test;
+	}
+
+	ast_aoc_s_add_rate_duration(decoded,
+		AST_AOC_CHARGED_ITEM_SUPPLEMENTARY_SERVICE,
+		937,
+		AST_AOC_MULT_THOUSAND,
+		"jkasdf",
+		235328,
+		AST_AOC_TIME_SCALE_SECOND,
+		905423,
+		AST_AOC_TIME_SCALE_DAY,
+		1);
+
+	ast_aoc_s_add_rate_flat(decoded,
+		AST_AOC_CHARGED_ITEM_CALL_SETUP,
+		1337,
+		AST_AOC_MULT_ONEHUNDREDTH,
+		"MONEYS");
+
+	ast_aoc_s_add_rate_volume(decoded,
+		AST_AOC_CHARGED_ITEM_CALL_ATTEMPT,
+		AST_AOC_VOLUME_UNIT_SEGMENT,
+		5555,
+		AST_AOC_MULT_ONEHUNDREDTH,
+		"pounds");
+
+	ast_aoc_s_add_rate_duration(decoded,
+		AST_AOC_CHARGED_ITEM_CALL_ATTEMPT,
+		78923,
+		AST_AOC_MULT_ONETHOUSANDTH,
+		"SNAP",
+		9354,
+		AST_AOC_TIME_SCALE_HUNDREDTH_SECOND,
+		234933,
+		AST_AOC_TIME_SCALE_SECOND,
+		0);
+
+	if (ast_aoc_test_encode_decode_match(decoded)) {
+		ast_test_status_update(test, "Test6: encode decode routine for AOC-S did not match expected results\n");
+		res = AST_TEST_FAIL;
+		goto cleanup_aoc_test;
+	}
+	/* cleanup decoded msg */
+	decoded = ast_aoc_destroy_decoded(decoded);
+
+
+
 cleanup_aoc_test:
 
 	decoded = ast_aoc_destroy_decoded(decoded);




More information about the svn-commits mailing list