[asterisk-commits] dvossel: branch dvossel/generic_aoc r256218 - in /team/dvossel/generic_aoc: i...
SVN commits to the Asterisk project
asterisk-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 asterisk-commits
mailing list