[svn-commits] kharwell: branch kharwell/stasis_aoc_event r392515 - /team/kharwell/stasis_ao...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Fri Jun 21 17:49:17 CDT 2013


Author: kharwell
Date: Fri Jun 21 17:49:15 2013
New Revision: 392515

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=392515
Log:
most of the codes in - testing and cleanup left.

Added:
    team/kharwell/stasis_aoc_event/main/aoc.c
      - copied, changed from r392270, trunk/main/aoc.c
Modified:
    team/kharwell/stasis_aoc_event/main/manager.c

Copied: team/kharwell/stasis_aoc_event/main/aoc.c (from r392270, trunk/main/aoc.c)
URL: http://svnview.digium.com/svn/asterisk/team/kharwell/stasis_aoc_event/main/aoc.c?view=diff&rev=392515&p1=trunk/main/aoc.c&r1=392270&p2=team/kharwell/stasis_aoc_event/main/aoc.c&r2=392515
==============================================================================
--- trunk/main/aoc.c (original)
+++ team/kharwell/stasis_aoc_event/main/aoc.c Fri Jun 21 17:49:15 2013
@@ -36,6 +36,8 @@
 #include "asterisk/_private.h"
 #include "asterisk/cli.h"
 #include "asterisk/manager.h"
+#include "asterisk/stasis_channels.h"
+#include "asterisk/stasis_message_router.h"
 
 /* Encoded Payload Flags */
 #define AST_AOC_ENCODED_TYPE_REQUEST    (0 << 0)
@@ -1289,13 +1291,8 @@
 		aoc_multiplier_str(mult));
 }
 
-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", ast_channel_name(chan));
-		ast_str_append(msg, 0, "UniqueID: %s\r\n", ast_channel_uniqueid(chan));
-	}
-
+static void aoc_request_event(const struct ast_aoc_decoded *decoded, struct ast_str **msg)
+{
 	if (decoded->request_flag) {
 		ast_str_append(msg, 0, "AOCRequest:");
 		if (decoded->request_flag & AST_AOC_REQUEST_S) {
@@ -1314,16 +1311,11 @@
 	}
 }
 
-static void aoc_s_event(const struct ast_aoc_decoded *decoded, struct ast_channel *owner, struct ast_str **msg)
+static void aoc_s_event(const struct ast_aoc_decoded *decoded, struct ast_str **msg)
 {
 	const char *rate_str;
 	char prefix[32];
 	int idx;
-
-	if (owner) {
-		ast_str_append(msg, 0, "Channel: %s\r\n", ast_channel_name(owner));
-		ast_str_append(msg, 0, "UniqueID: %s\r\n", ast_channel_uniqueid(owner));
-	}
 
 	ast_str_append(msg, 0, "NumberRates: %d\r\n", decoded->aoc_s_count);
 	for (idx = 0; idx < decoded->aoc_s_count; ++idx) {
@@ -1387,16 +1379,11 @@
 	}
 }
 
-static void aoc_d_event(const struct ast_aoc_decoded *decoded, struct ast_channel *chan, struct ast_str **msg)
+static void aoc_d_event(const struct ast_aoc_decoded *decoded, struct ast_str **msg)
 {
 	const char *charge_str;
 	int idx;
 	char prefix[32];
-
-	if (chan) {
-		ast_str_append(msg, 0, "Channel: %s\r\n", ast_channel_name(chan));
-		ast_str_append(msg, 0, "UniqueID: %s\r\n", ast_channel_uniqueid(chan));
-	}
 
 	charge_str = aoc_charge_type_str(decoded->charge_type);
 	ast_str_append(msg, 0, "Type: %s\r\n", charge_str);
@@ -1441,16 +1428,11 @@
 	}
 }
 
-static void aoc_e_event(const struct ast_aoc_decoded *decoded, struct ast_channel *chan, struct ast_str **msg)
+static void aoc_e_event(const struct ast_aoc_decoded *decoded, struct ast_str **msg)
 {
 	const char *charge_str;
 	int idx;
 	char prefix[32];
-
-	if (chan) {
-		ast_str_append(msg, 0, "Channel: %s\r\n", ast_channel_name(chan));
-		ast_str_append(msg, 0, "UniqueID: %s\r\n", ast_channel_uniqueid(chan));
-	}
 
 	charge_str = "ChargingAssociation";
 
@@ -1509,41 +1491,360 @@
 	}
 }
 
+static struct ast_json *units_to_json(const struct ast_aoc_decoded *decoded)
+{
+	int i;
+	struct ast_json *units = ast_json_array_create();
+
+	if (!units) {
+		return ast_json_null();
+	}
+
+	for (i = 0; i < decoded->unit_count; ++i) {
+		struct ast_json *unit = ast_json_object_create();
+
+		if (decoded->unit_list[i].valid_amount) {
+			ast_json_object_set(
+				unit, "NumberOf", ast_json_stringf(
+					"%u", decoded->unit_list[i].amount));
+			}
+
+		if (decoded->unit_list[i].valid_type) {
+			ast_json_object_set(
+				unit, "TypeOf", ast_json_stringf(
+					"%d", decoded->unit_list[i].type));
+		}
+
+		if (ast_json_array_append(units, unit)) {
+			break;
+		}
+	}
+
+	return units;
+}
+
+static struct ast_json *currency_to_json(const char *name, int cost,
+					 enum ast_aoc_currency_multiplier mult)
+{
+	return ast_json_pack("{s:s, s:i, s:s}",	"Name", name,
+			     "Cost", cost, "Multiplier", aoc_multiplier_str(mult));
+}
+
+static struct ast_json *charge_to_json(const struct ast_aoc_decoded *decoded)
+{
+	RAII_VAR(struct ast_json *, obj, NULL, ast_json_unref);
+	const char *obj_type;
+
+	if (decoded->charge_type != AST_AOC_CHARGE_CURRENCY &&
+	    decoded->charge_type != AST_AOC_CHARGE_UNIT) {
+		return ast_json_pack("{s:s}", "Type",
+				     aoc_charge_type_str(decoded->charge_type));
+	}
+
+	if (decoded->charge_type == AST_AOC_CHARGE_CURRENCY) {
+		obj_type = "Currency";
+		obj = currency_to_json(decoded->currency_name, decoded->currency_amount,
+				       decoded->multiplier);
+	} else { /* decoded->charge_type == AST_AOC_CHARGE_UNIT */
+		obj_type = "Units";
+		obj = units_to_json(decoded);
+	}
+
+	return ast_json_pack(
+		"{s:s, s:s, s:s, s:O}",
+		"Type", aoc_charge_type_str(decoded->charge_type),
+		"BillingID", aoc_billingid_str(decoded->billing_id),
+		"TotalType", aoc_type_of_totaling_str(decoded->total_type),
+		obj_type, obj);
+}
+
+static struct ast_json *association_to_json(const struct ast_aoc_decoded *decoded)
+{
+	switch (decoded->charging_association.charging_type) {
+	case AST_AOC_CHARGING_ASSOCIATION_NUMBER:
+		return ast_json_pack(
+			"{s:s, s:i}",
+			"Number", decoded->charging_association.charge.number.number,
+			"Plan", decoded->charging_association.charge.number.plan);
+	case AST_AOC_CHARGING_ASSOCIATION_ID:
+		return ast_json_pack(
+			"{s:i}", "ID", decoded->charging_association.charge.id);
+	case AST_AOC_CHARGING_ASSOCIATION_NA:
+	default:
+		return ast_json_null();
+	}
+}
+
+static struct ast_json *s_to_json(const struct ast_aoc_decoded *decoded)
+{
+	int i;
+	struct ast_json *rates = ast_json_array_create();
+
+	if (!rates) {
+		return ast_json_null();
+	}
+
+	for (i = 0; i < decoded->aoc_s_count; ++i) {
+		struct ast_json *rate = ast_json_object_create();
+		RAII_VAR(struct ast_json *, type, NULL, ast_json_unref);
+		RAII_VAR(struct ast_json *, currency, NULL, ast_json_unref);
+		const char *charge_item = aoc_charged_item_str(
+			decoded->aoc_s_entries[i].charged_item);
+
+		if (decoded->aoc_s_entries[i].charged_item == AST_AOC_CHARGED_ITEM_NA) {
+			rate = ast_json_pack("{s:s}", "Chargeable", charge_item);
+			if (ast_json_array_append(rates, rate)) {
+				break;
+			}
+			continue;
+		}
+
+		switch (decoded->aoc_s_entries[i].rate_type) {
+		case AST_AOC_RATE_TYPE_DURATION:
+		{
+			RAII_VAR(struct ast_json *, time, NULL, ast_json_unref);
+			RAII_VAR(struct ast_json *, granularity, NULL, ast_json_unref);
+
+			currency = currency_to_json(
+				decoded->aoc_s_entries[i].rate.duration.currency_name,
+				decoded->aoc_s_entries[i].rate.duration.amount,
+				decoded->aoc_s_entries[i].rate.duration.multiplier);
+
+			time = ast_json_pack(
+				"{s:i, s:s}",
+				"Length", decoded->aoc_s_entries[i].rate.duration.time,
+				"Scale", decoded->aoc_s_entries[i].rate.duration.time_scale);
+
+			if (decoded->aoc_s_entries[i].rate.duration.granularity_time) {
+				granularity = ast_json_pack(
+					"{s:i, s:s}",
+					"Length", decoded->aoc_s_entries[i].rate.duration.granularity_time,
+					"Scale", decoded->aoc_s_entries[i].rate.duration.granularity_time_scale);
+			}
+
+			type = ast_json_pack("{s:O, s:s, s:O, s:O}", "Currency", currency, "ChargingType",
+					     decoded->aoc_s_entries[i].rate.duration.charging_type ?
+					     "StepFunction" : "ContinuousCharging", "Time", time,
+					     "Granularity", granularity ? granularity : ast_json_null());
+
+			break;
+		}
+		case AST_AOC_RATE_TYPE_FLAT:
+			currency = currency_to_json(
+				decoded->aoc_s_entries[i].rate.flat.currency_name,
+				decoded->aoc_s_entries[i].rate.flat.amount,
+				decoded->aoc_s_entries[i].rate.flat.multiplier);
+
+			type = ast_json_pack("{s:O}", "Currency", currency);
+			break;
+		case AST_AOC_RATE_TYPE_VOLUME:
+			currency = currency_to_json(
+				decoded->aoc_s_entries[i].rate.volume.currency_name,
+				decoded->aoc_s_entries[i].rate.volume.amount,
+				decoded->aoc_s_entries[i].rate.volume.multiplier);
+
+			type = ast_json_pack(
+				"{s:s, s:O}", "Unit", aoc_volume_unit_str(
+					decoded->aoc_s_entries[i].rate.volume.volume_unit),
+				"Currency", currency);
+			break;
+		case AST_AOC_RATE_TYPE_SPECIAL_CODE:
+			type = ast_json_pack("{s:i}", "SpecialCode",
+					    decoded->aoc_s_entries[i].rate.special_code);
+			break;
+		default:
+			break;
+		}
+
+		rate = ast_json_pack("{s:s, s:O}", "Chargeable", charge_item,
+				     aoc_rate_type_str(decoded->aoc_s_entries[i].rate_type), type);
+		if (ast_json_array_append(rates, rate)) {
+			break;
+		}
+	}
+	return rates;
+}
+
+static struct ast_json *d_to_json(const struct ast_aoc_decoded *decoded)
+{
+	return ast_json_pack("{s:o}", "Charge", charge_to_json(decoded));
+}
+
+static struct ast_json *e_to_json(const struct ast_aoc_decoded *decoded)
+{
+	return ast_json_pack("{s:o, s:o}",
+			     "ChargingAssociation", association_to_json(decoded),
+			     "Charge", charge_to_json(decoded));
+}
+
+static void json_value_str_append(struct ast_json *value, const char *key,
+				  struct ast_str **res)
+{
+	switch (ast_json_typeof(value)) {
+	case AST_JSON_STRING:
+		ast_str_append(res, 0, "%s: %s\r\n", key, ast_json_string_get(value));
+		break;
+	case AST_JSON_INTEGER:
+		ast_str_append(res, 0, "%s: %jd\r\n", key, ast_json_integer_get(value));
+		break;
+	case AST_JSON_TRUE:
+		ast_str_append(res, 0, "%s: True\r\n", key);
+		break;
+	case AST_JSON_FALSE:
+		ast_str_append(res, 0, "%s: False\r\n", key);
+		break;
+	default:
+		ast_str_append(res, 0, "%s: \r\n", key);
+		break;
+	}
+}
+
+static void json_to_ast_str(struct ast_json *obj, const char *key,
+				struct ast_str **res);
+
+static void json_to_ast_str_key(struct ast_json *obj, const char* key,
+				      const char *parent_key, struct ast_str **res)
+{
+	if (parent_key) {
+		struct ast_str *key_str = ast_str_alloca(64);
+		ast_str_set(&key_str, 0, "%s/%s", parent_key, key);
+		json_to_ast_str(obj, ast_str_buffer(key_str), res);
+		return;
+	}
+
+	json_to_ast_str(obj, key, res);
+}
+
+static void json_to_ast_str(struct ast_json *obj, const char *key,
+			    struct ast_str **res)
+{
+	struct ast_json_iter *i;
+
+	if (!obj || (!res && !(*res) && (!(*res = ast_str_create(1024))))) {
+		return;
+	}
+
+	if (ast_json_typeof(obj) != AST_JSON_OBJECT &&
+	    ast_json_typeof(obj) != AST_JSON_ARRAY) {
+		json_value_str_append(obj, key, res);
+		return;
+	}
+
+	if (ast_json_typeof(obj) != AST_JSON_ARRAY) {
+		size_t j;
+		for (j = 0; j < ast_json_array_size(obj); ++j) {
+			json_to_ast_str_key(ast_json_array_get(obj, j),
+					    key, NULL, res);
+		}
+		return;
+	}
+
+	for (i = ast_json_object_iter(obj); i;
+	     i = ast_json_object_iter_next(obj, i)) {
+		json_to_ast_str_key(ast_json_object_iter_value(i),
+				    ast_json_object_iter_key(i), key, res);
+	}
+}
+
+static struct ast_str *json_obj_to_ast_str(struct ast_json *obj)
+{
+	struct ast_str *res = ast_str_create(1024);
+	json_to_ast_str(obj, NULL, &res);
+	return res;
+}
+
+static struct ast_manager_event_blob *aoc_to_ami(struct stasis_message *message)
+{
+	struct ast_channel_blob *obj = stasis_message_data(message);
+	RAII_VAR(struct ast_str *, channel, NULL, ast_free);
+	RAII_VAR(struct ast_str *, aoc, NULL, ast_free);
+	const char *name;
+
+	ast_log(LOG_VERBOSE, "ast_stasis_event - START\n");
+	if (!(channel = ast_manager_build_channel_state_string(
+		      obj->snapshot))) {
+		return NULL;
+	}
+
+	if (!(aoc = json_obj_to_ast_str(obj->blob))) {
+		return NULL;
+	}
+
+	name = stasis_message_type_name(stasis_message_type(message));
+	ast_log(LOG_VERBOSE, "ast_stasis_event - name = %s, channel = %s, \n\naoc = %s\n", name, ast_str_buffer(channel), ast_str_buffer(aoc));
+	return ast_manager_event_blob_create(EVENT_FLAG_AOC, name, "%s%s",
+					     AS_OR(channel, ""), ast_str_buffer(aoc));
+}
+
+struct stasis_message_type *aoc_s_type(void);
+struct stasis_message_type *aoc_d_type(void);
+struct stasis_message_type *aoc_e_type(void);
+
+STASIS_MESSAGE_TYPE_DEFN(
+	aoc_s_type,
+	.to_ami = aoc_to_ami);
+
+STASIS_MESSAGE_TYPE_DEFN(
+	aoc_d_type,
+	.to_ami = aoc_to_ami);
+
+STASIS_MESSAGE_TYPE_DEFN(
+	aoc_e_type,
+	.to_ami = aoc_to_ami);
+
 int ast_aoc_manager_event(const struct ast_aoc_decoded *decoded, struct ast_channel *chan)
 {
-	struct ast_str *msg;
-
-	if (!decoded || !(msg = ast_str_create(1024))) {
+	RAII_VAR(struct ast_json *, blob, NULL, ast_json_unref);
+	struct stasis_message_type *msg_type;
+
+	RAII_VAR(struct ast_str *, aoc, NULL, ast_free);
+	const char *blob_str;
+	ast_log(LOG_VERBOSE, "ast_aoc_manager_event - START type = %d\n", decoded->msg_type);
+/*
+action: login
+username: kharwell
+secret: pass
+
+Action: AOCMessage
+Channel: SIP/102-00000000
+MsgType: e
+ChargeType: Currency
+CurrencyAmount: 16
+CurrencyName: USD
+CurrencyMultiplier: OneThousandth
+AOCBillingId: Normal
+ActionID: 1234
+*/
+
+	if (!decoded) {
 		return -1;
 	}
 
 	switch (decoded->msg_type) {
 	case AST_AOC_S:
-		if (chan) {
-			aoc_s_event(decoded, chan, &msg);
-			ast_manager_event(chan, EVENT_FLAG_AOC, "AOC-S", "%s", ast_str_buffer(msg));
-		}
+		blob = s_to_json(decoded);
+		msg_type = aoc_s_type();
 		break;
 	case AST_AOC_D:
-		if (chan) {
-			aoc_d_event(decoded, chan, &msg);
-			ast_manager_event(chan, EVENT_FLAG_AOC, "AOC-D", "%s", ast_str_buffer(msg));
-		}
+		blob = d_to_json(decoded);
+		msg_type = aoc_d_type();
 		break;
 	case AST_AOC_E:
-		{
-			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));
-		}
+		blob = e_to_json(decoded);
+		msg_type = aoc_e_type();
 		break;
 	default:
 		/* events for AST_AOC_REQUEST are not generated here */
-		break;
-	}
-
-	ast_free(msg);
+		return 0;
+	}
+
+	if (!blob) {
+		ast_log(LOG_VERBOSE, "Why is BLOB NULL??..oh noes!\n");
+	}
+	aoc = json_obj_to_ast_str(blob); /* ast_manager_str_from_json_object(blob, NULL); */
+	blob_str = ast_json_dump_string(blob/* , AST_JSON_PRETTY */);
+	ast_log(LOG_VERBOSE, "ast_aoc_manager_event - bob the blob = %s\n\n AOCstuff = %s\n", blob_str, ast_str_buffer(aoc));
+	ast_channel_publish_blob(chan, msg_type, blob);
 	return 0;
 }
 
@@ -1556,19 +1857,19 @@
 	switch (decoded->msg_type) {
 	case AST_AOC_S:
 		ast_str_append(msg, 0, "AOC-S\r\n");
-		aoc_s_event(decoded, NULL, msg);
+		aoc_s_event(decoded, msg);
 		break;
 	case AST_AOC_D:
 		ast_str_append(msg, 0, "AOC-D\r\n");
-		aoc_d_event(decoded, NULL, msg);
+		aoc_d_event(decoded, msg);
 		break;
 	case AST_AOC_E:
 		ast_str_append(msg, 0, "AOC-E\r\n");
-		aoc_e_event(decoded, NULL, msg);
+		aoc_e_event(decoded, msg);
 		break;
 	case AST_AOC_REQUEST:
 		ast_str_append(msg, 0, "AOC-Request\r\n");
-		aoc_request_event(decoded, NULL, msg);
+		aoc_request_event(decoded, msg);
 		break;
 	}
 
@@ -1607,10 +1908,27 @@
 
 static void aoc_shutdown(void)
 {
+	STASIS_MESSAGE_TYPE_CLEANUP(aoc_s_type);
+	STASIS_MESSAGE_TYPE_CLEANUP(aoc_d_type);
+	STASIS_MESSAGE_TYPE_CLEANUP(aoc_e_type);
+
 	ast_cli_unregister_multiple(aoc_cli, ARRAY_LEN(aoc_cli));
 }
 int ast_aoc_cli_init(void)
 {
+	STASIS_MESSAGE_TYPE_INIT(aoc_s_type);
+	STASIS_MESSAGE_TYPE_INIT(aoc_d_type);
+	STASIS_MESSAGE_TYPE_INIT(aoc_e_type);
+
+	/* stasis_message_router_add(message_router, aoc_s_type(), */
+	/* 			  aoc_stasis_event, "AOC-S"); */
+
+	/* stasis_message_router_add(message_router, aoc_d_type(), */
+	/* 			  aoc_stasis_event, "AOC-D"); */
+
+	/* stasis_message_router_add(message_router, aoc_e_type(), */
+	/* 			  aoc_stasis_event, "AOC-E"); */
+
 	ast_register_atexit(aoc_shutdown);
 	return ast_cli_register_multiple(aoc_cli, ARRAY_LEN(aoc_cli));
 }

Modified: team/kharwell/stasis_aoc_event/main/manager.c
URL: http://svnview.digium.com/svn/asterisk/team/kharwell/stasis_aoc_event/main/manager.c?view=diff&rev=392515&r1=392514&r2=392515
==============================================================================
--- team/kharwell/stasis_aoc_event/main/manager.c (original)
+++ team/kharwell/stasis_aoc_event/main/manager.c Fri Jun 21 17:49:15 2013
@@ -4549,6 +4549,9 @@
 	ast_aoc_set_billing_id(decoded, _billingid);
 	ast_aoc_set_total_type(decoded, _totaltype);
 
+	/* TODO: remove below used for tmp testing */
+	ast_aoc_manager_event(decoded, chan);
+	/* TODO: remove code before this */
 
 	if ((encoded = ast_aoc_encode(decoded, &encoded_size, NULL)) && !ast_indicate_data(chan, AST_CONTROL_AOC, encoded, encoded_size)) {
 		astman_send_ack(s, m, "AOC Message successfully queued on channel");




More information about the svn-commits mailing list