[Asterisk-code-review] manager: AOC-S support for AOCMessage (asterisk[20])

Friendly Automation asteriskteam at digium.com
Fri Dec 9 07:59:22 CST 2022


Friendly Automation has submitted this change. ( https://gerrit.asterisk.org/c/asterisk/+/19536 )

Change subject: manager: AOC-S support for AOCMessage
......................................................................

manager: AOC-S support for AOCMessage

ASTERISK-21502

Change-Id: I051b778f8c862d3b4794d28f2f3d782316707b08
---
A doc/CHANGES-staging/manager_aoc.txt
M main/manager.c
2 files changed, 436 insertions(+), 35 deletions(-)

Approvals:
  Joshua Colp: Looks good to me, but someone else must approve
  George Joseph: Looks good to me, approved
  Friendly Automation: Approved for Submit




diff --git a/doc/CHANGES-staging/manager_aoc.txt b/doc/CHANGES-staging/manager_aoc.txt
new file mode 100644
index 0000000..ed90cf6
--- /dev/null
+++ b/doc/CHANGES-staging/manager_aoc.txt
@@ -0,0 +1,3 @@
+Subject: AMI
+
+The AOCMessage action can now be used to generate AOC-S messages.
diff --git a/main/manager.c b/main/manager.c
index fc65a33..8a198b3 100644
--- a/main/manager.c
+++ b/main/manager.c
@@ -1122,8 +1122,9 @@
 		</synopsis>
 		<syntax>
 			<xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
-			<parameter name="Channel" required="true">
-				<para>Channel name to generate the AOC message on.</para>
+			<parameter name="Channel">
+				<para>Channel name to generate the AOC message on.
+				This value is required unless ChannelPrefix is given.</para>
 			</parameter>
 			<parameter name="ChannelPrefix">
 				<para>Partial channel prefix.  By using this option one can match the beginning part
@@ -1133,14 +1134,15 @@
 				the first matched channel has the message sent on it. </para>
 			</parameter>
 			<parameter name="MsgType" required="true">
-				<para>Defines what type of AOC message to create, AOC-D or AOC-E</para>
+				<para>Defines what type of AOC message to create, AOC-S, AOC-D or AOC-E</para>
 				<enumlist>
+					<enum name="S" />
 					<enum name="D" />
 					<enum name="E" />
 				</enumlist>
 			</parameter>
-			<parameter name="ChargeType" required="true">
-				<para>Defines what kind of charge this message represents.</para>
+			<parameter name="ChargeType">
+				<para>Defines what kind of charge this message represents for AOC-D and AOC-E.</para>
 				<enumlist>
 					<enum name="NA" />
 					<enum name="FREE" />
@@ -1168,11 +1170,13 @@
 				<para>Specifies the currency's name.  Note that this value is truncated after 10 characters.</para>
 			</parameter>
 			<parameter name="CurrencyAmount">
-				<para>Specifies the charge unit amount as a positive integer.  This value is required
-				when ChargeType==Currency.</para>
+				<para>Specifies the charge unit amount as a positive integer.
+				This value is required when ChargeType==Currency (AOC-D or AOC-E) or
+				RateType==Duration/Flat/Volume (AOC-S).</para>
 			</parameter>
 			<parameter name="CurrencyMultiplier">
-				<para>Specifies the currency multiplier.  This value is required when ChargeType==Currency.</para>
+				<para>Specifies the currency multiplier.
+				This value is required when CurrencyAmount is given.</para>
 				<enumlist>
 					<enum name="OneThousandth" />
 					<enum name="OneHundredth" />
@@ -1217,11 +1221,102 @@
 				The value is bits 7 through 1 of the Q.931 octet containing the type-of-number and
 				numbering-plan-identification fields.</para>
 			</parameter>
+			<parameter name="ChargedItem">
+				<para>Defines what part of the call is charged in AOC-S. Usually this is set to
+				BasicCommunication, which refers to the time after the call is answered, but establishment
+				(CallAttempt) or successful establishment (CallSetup) of a call can also be used.
+				Other options are available, but these generally do not carry enough information to actually
+				calculate the price of a call.
+				It is possible to have multiple ChargedItem entries for a single call -- for example to
+				charge for both the establishment of the call and the actual call. In this case, each
+				ChargedItem is described by a ChargedItem: header and all other headers that follow it up to
+				the next ChargedItem: header.</para>
+				<enumlist>
+					<enum name="NA" />
+					<enum name="SpecialArrangement" />
+					<enum name="BasicCommunication" />
+					<enum name="CallAttempt" />
+					<enum name="CallSetup" />
+					<enum name="UserUserInfo" />
+					<enum name="SupplementaryService" />
+				</enumlist>
+			</parameter>
+			<parameter name="RateType">
+				<para>Defines how an AOC-S ChargedItem is charged.
+				The Duration option is only available when ChargedItem==BasicCommunication.</para>
+				<enumlist>
+					<enum name="NA" />
+					<enum name="Free" />
+					<enum name="FreeFromBeginning" />
+					<enum name="Duration" />
+					<enum name="Flat" />
+					<enum name="Volume" />
+					<enum name="SpecialCode" />
+				</enumlist>
+			</parameter>
+			<parameter name="Time">
+				<para>Specifies a positive integer which is the amount of time is paid for by one
+				CurrencyAmount.
+				This value is required when RateType==Duration.</para>
+			</parameter>
+			<parameter name="TimeScale">
+				<para>Specifies the time multiplier.
+				This value is required when Time is given.</para>
+				<enumlist>
+					<enum name="OneHundredthSecond" />
+					<enum name="OneTenthSecond" />
+					<enum name="Second" />
+					<enum name="TenSeconds" />
+					<enum name="Minute" />
+					<enum name="Hour" />
+					<enum name="Day" />
+				</enumlist>
+			</parameter>
+			<parameter name="Granularity">
+				<para>Specifies a positive integer which is the size of the charged time increments.
+				This value is optional when RateType==Duration and ChargingType==StepFunction.</para>
+			</parameter>
+			<parameter name="GranularityTimeScale">
+				<para>Specifies the granularity time multiplier.
+				This value is required when Granularity is given.</para>
+				<enumlist>
+					<enum name="OneHundredthSecond" />
+					<enum name="OneTenthSecond" />
+					<enum name="Second" />
+					<enum name="TenSeconds" />
+					<enum name="Minute" />
+					<enum name="Hour" />
+					<enum name="Day" />
+				</enumlist>
+			</parameter>
+			<parameter name="ChargingType">
+				<para>Specifies whether the charge increases continuously with time or in increments of
+				Time or, if provided, Granularity.
+				This value is required when RateType==Duration.</para>
+				<enumlist>
+					<enum name="ContinuousCharging" />
+					<enum name="StepFunction" />
+				</enumlist>
+			</parameter>
+			<parameter name="VolumeUnit">
+				<para>Specifies the quantity of which one unit is paid for by one CurrencyAmount.
+				This value is required when RateType==Volume.</para>
+				<enumlist>
+					<enum name="Octet" />
+					<enum name="Segment" />
+					<enum name="Message" />
+				</enumlist>
+			</parameter>
+			<parameter name="Code">
+				<para>Specifies the charging code, which can be set to a value between 1 and 10.
+				This value is required when ChargedItem==SpecialArrangement or RateType==SpecialCode.</para>
+			</parameter>
 		</syntax>
 		<description>
-			<para>Generates an AOC-D or AOC-E message on a channel.</para>
+			<para>Generates an AOC-S, AOC-D or AOC-E message on a channel.</para>
 		</description>
 		<see-also>
+			<ref type="managerEvent">AOC-S</ref>
 			<ref type="managerEvent">AOC-D</ref>
 			<ref type="managerEvent">AOC-E</ref>
 		</see-also>
@@ -5549,10 +5644,8 @@
 	return 0;
 }
 
-static int action_aocmessage(struct mansession *s, const struct message *m)
+static struct ast_aoc_decoded *action_aoc_de_message(struct mansession *s, const struct message *m)
 {
-	const char *channel = astman_get_header(m, "Channel");
-	const char *pchannel = astman_get_header(m, "ChannelPrefix");
 	const char *msgtype = astman_get_header(m, "MsgType");
 	const char *chargetype = astman_get_header(m, "ChargeType");
 	const char *currencyname = astman_get_header(m, "CurrencyName");
@@ -5572,30 +5665,8 @@
 	unsigned int _currencyamount = 0;
 	int _association_id = 0;
 	unsigned int _association_plan = 0;
-	struct ast_channel *chan = NULL;
 
 	struct ast_aoc_decoded *decoded = NULL;
-	struct ast_aoc_encoded *encoded = NULL;
-	size_t encoded_size = 0;
-
-	if (ast_strlen_zero(channel) && ast_strlen_zero(pchannel)) {
-		astman_send_error(s, m, "Channel and PartialChannel are not specified. Specify at least one of these.");
-		goto aocmessage_cleanup;
-	}
-
-	if (!(chan = ast_channel_get_by_name(channel)) && !ast_strlen_zero(pchannel)) {
-		chan = ast_channel_get_by_name_prefix(pchannel, strlen(pchannel));
-	}
-
-	if (!chan) {
-		astman_send_error(s, m, "No such channel");
-		goto aocmessage_cleanup;
-	}
-
-	if (ast_strlen_zero(msgtype) || (strcasecmp(msgtype, "d") && strcasecmp(msgtype, "e"))) {
-		astman_send_error(s, m, "Invalid MsgType");
-		goto aocmessage_cleanup;
-	}
 
 	if (ast_strlen_zero(chargetype)) {
 		astman_send_error(s, m, "ChargeType not specified");
@@ -5736,8 +5807,324 @@
 	ast_aoc_set_billing_id(decoded, _billingid);
 	ast_aoc_set_total_type(decoded, _totaltype);
 
+	return decoded;
 
-	if ((encoded = ast_aoc_encode(decoded, &encoded_size, NULL)) && !ast_indicate_data(chan, AST_CONTROL_AOC, encoded, encoded_size)) {
+aocmessage_cleanup:
+
+	ast_aoc_destroy_decoded(decoded);
+	return NULL;
+}
+
+static int action_aoc_s_submessage(struct mansession *s, const struct message *m,
+		struct ast_aoc_decoded *decoded)
+{
+	const char *chargeditem = __astman_get_header(m, "ChargedItem", GET_HEADER_LAST_MATCH);
+	const char *ratetype = __astman_get_header(m, "RateType", GET_HEADER_LAST_MATCH);
+	const char *currencyname = __astman_get_header(m, "CurrencyName", GET_HEADER_LAST_MATCH);
+	const char *currencyamount = __astman_get_header(m, "CurrencyAmount", GET_HEADER_LAST_MATCH);
+	const char *mult = __astman_get_header(m, "CurrencyMultiplier", GET_HEADER_LAST_MATCH);
+	const char *time = __astman_get_header(m, "Time", GET_HEADER_LAST_MATCH);
+	const char *timescale = __astman_get_header(m, "TimeScale", GET_HEADER_LAST_MATCH);
+	const char *granularity = __astman_get_header(m, "Granularity", GET_HEADER_LAST_MATCH);
+	const char *granularitytimescale = __astman_get_header(m, "GranularityTimeScale", GET_HEADER_LAST_MATCH);
+	const char *chargingtype = __astman_get_header(m, "ChargingType", GET_HEADER_LAST_MATCH);
+	const char *volumeunit = __astman_get_header(m, "VolumeUnit", GET_HEADER_LAST_MATCH);
+	const char *code = __astman_get_header(m, "Code", GET_HEADER_LAST_MATCH);
+
+	enum ast_aoc_s_charged_item _chargeditem;
+	enum ast_aoc_s_rate_type _ratetype;
+	enum ast_aoc_currency_multiplier _mult = AST_AOC_MULT_ONE;
+	unsigned int _currencyamount = 0;
+	unsigned int _code;
+	unsigned int _time = 0;
+	enum ast_aoc_time_scale _scale = 0;
+	unsigned int _granularity = 0;
+	enum ast_aoc_time_scale _granularity_time_scale = AST_AOC_TIME_SCALE_MINUTE;
+	int _step = 0;
+	enum ast_aoc_volume_unit _volumeunit = 0;
+
+	if (ast_strlen_zero(chargeditem)) {
+		astman_send_error(s, m, "ChargedItem not specified");
+		goto aocmessage_cleanup;
+	}
+
+	if (ast_strlen_zero(ratetype)) {
+		astman_send_error(s, m, "RateType not specified");
+		goto aocmessage_cleanup;
+	}
+
+	if (!strcasecmp(chargeditem, "NA")) {
+		_chargeditem = AST_AOC_CHARGED_ITEM_NA;
+	} else if (!strcasecmp(chargeditem, "SpecialArrangement")) {
+		_chargeditem = AST_AOC_CHARGED_ITEM_SPECIAL_ARRANGEMENT;
+	} else if (!strcasecmp(chargeditem, "BasicCommunication")) {
+		_chargeditem = AST_AOC_CHARGED_ITEM_BASIC_COMMUNICATION;
+	} else if (!strcasecmp(chargeditem, "CallAttempt")) {
+		_chargeditem = AST_AOC_CHARGED_ITEM_CALL_ATTEMPT;
+	} else if (!strcasecmp(chargeditem, "CallSetup")) {
+		_chargeditem = AST_AOC_CHARGED_ITEM_CALL_SETUP;
+	} else if (!strcasecmp(chargeditem, "UserUserInfo")) {
+		_chargeditem = AST_AOC_CHARGED_ITEM_USER_USER_INFO;
+	} else if (!strcasecmp(chargeditem, "SupplementaryService")) {
+		_chargeditem = AST_AOC_CHARGED_ITEM_SUPPLEMENTARY_SERVICE;
+	} else {
+		astman_send_error(s, m, "Invalid ChargedItem");
+		goto aocmessage_cleanup;
+	}
+
+	if (!strcasecmp(ratetype, "NA")) {
+		_ratetype = AST_AOC_RATE_TYPE_NA;
+	} else if (!strcasecmp(ratetype, "Free")) {
+		_ratetype = AST_AOC_RATE_TYPE_FREE;
+	} else if (!strcasecmp(ratetype, "FreeFromBeginning")) {
+		_ratetype = AST_AOC_RATE_TYPE_FREE_FROM_BEGINNING;
+	} else if (!strcasecmp(ratetype, "Duration")) {
+		_ratetype = AST_AOC_RATE_TYPE_DURATION;
+	} else if (!strcasecmp(ratetype, "Flat")) {
+		_ratetype = AST_AOC_RATE_TYPE_FLAT;
+	} else if (!strcasecmp(ratetype, "Volume")) {
+		_ratetype = AST_AOC_RATE_TYPE_VOLUME;
+	} else if (!strcasecmp(ratetype, "SpecialCode")) {
+		_ratetype = AST_AOC_RATE_TYPE_SPECIAL_CODE;
+	} else {
+		astman_send_error(s, m, "Invalid RateType");
+		goto aocmessage_cleanup;
+	}
+
+	if (_ratetype > AST_AOC_RATE_TYPE_FREE_FROM_BEGINNING) {
+		if (ast_strlen_zero(currencyamount) || (sscanf(currencyamount, "%30u",
+				&_currencyamount) != 1)) {
+			astman_send_error(s, m, "Invalid CurrencyAmount, CurrencyAmount is a required when RateType is non-free");
+			goto aocmessage_cleanup;
+		}
+
+		if (ast_strlen_zero(mult)) {
+			astman_send_error(s, m, "ChargeMultiplier unspecified, ChargeMultiplier is required when ChargeType is Currency.");
+			goto aocmessage_cleanup;
+		} else if (!strcasecmp(mult, "onethousandth")) {
+			_mult = AST_AOC_MULT_ONETHOUSANDTH;
+		} else if (!strcasecmp(mult, "onehundredth")) {
+			_mult = AST_AOC_MULT_ONEHUNDREDTH;
+		} else if (!strcasecmp(mult, "onetenth")) {
+			_mult = AST_AOC_MULT_ONETENTH;
+		} else if (!strcasecmp(mult, "one")) {
+			_mult = AST_AOC_MULT_ONE;
+		} else if (!strcasecmp(mult, "ten")) {
+			_mult = AST_AOC_MULT_TEN;
+		} else if (!strcasecmp(mult, "hundred")) {
+			_mult = AST_AOC_MULT_HUNDRED;
+		} else if (!strcasecmp(mult, "thousand")) {
+			_mult = AST_AOC_MULT_THOUSAND;
+		} else {
+			astman_send_error(s, m, "Invalid ChargeMultiplier");
+			goto aocmessage_cleanup;
+		}
+	}
+
+	if (_ratetype == AST_AOC_RATE_TYPE_DURATION) {
+		if (ast_strlen_zero(timescale)) {
+			astman_send_error(s, m, "TimeScale unspecified, TimeScale is required when RateType is Duration.");
+			goto aocmessage_cleanup;
+		} else if (!strcasecmp(timescale, "onehundredthsecond")) {
+			_scale = AST_AOC_TIME_SCALE_HUNDREDTH_SECOND;
+		} else if (!strcasecmp(timescale, "onetenthsecond")) {
+			_scale = AST_AOC_TIME_SCALE_TENTH_SECOND;
+		} else if (!strcasecmp(timescale, "second")) {
+			_scale = AST_AOC_TIME_SCALE_SECOND;
+		} else if (!strcasecmp(timescale, "tenseconds")) {
+			_scale = AST_AOC_TIME_SCALE_TEN_SECOND;
+		} else if (!strcasecmp(timescale, "minute")) {
+			_scale = AST_AOC_TIME_SCALE_MINUTE;
+		} else if (!strcasecmp(timescale, "hour")) {
+			_scale = AST_AOC_TIME_SCALE_HOUR;
+		} else if (!strcasecmp(timescale, "day")) {
+			_scale = AST_AOC_TIME_SCALE_DAY;
+		} else {
+			astman_send_error(s, m, "Invalid TimeScale");
+			goto aocmessage_cleanup;
+		}
+
+		if (ast_strlen_zero(time) || (sscanf(time, "%30u", &_time) != 1)) {
+			astman_send_error(s, m, "Invalid Time, Time is a required when RateType is Duration");
+			goto aocmessage_cleanup;
+		}
+
+		if (!ast_strlen_zero(granularity)) {
+			if ((sscanf(time, "%30u", &_granularity) != 1)) {
+				astman_send_error(s, m, "Invalid Granularity");
+				goto aocmessage_cleanup;
+			}
+
+			if (ast_strlen_zero(granularitytimescale)) {
+				astman_send_error(s, m, "Invalid GranularityTimeScale, GranularityTimeScale is a required when Granularity is specified");
+			} else if (!strcasecmp(granularitytimescale, "onehundredthsecond")) {
+				_granularity_time_scale = AST_AOC_TIME_SCALE_HUNDREDTH_SECOND;
+			} else if (!strcasecmp(granularitytimescale, "onetenthsecond")) {
+				_granularity_time_scale = AST_AOC_TIME_SCALE_TENTH_SECOND;
+			} else if (!strcasecmp(granularitytimescale, "second")) {
+				_granularity_time_scale = AST_AOC_TIME_SCALE_SECOND;
+			} else if (!strcasecmp(granularitytimescale, "tenseconds")) {
+				_granularity_time_scale = AST_AOC_TIME_SCALE_TEN_SECOND;
+			} else if (!strcasecmp(granularitytimescale, "minute")) {
+				_granularity_time_scale = AST_AOC_TIME_SCALE_MINUTE;
+			} else if (!strcasecmp(granularitytimescale, "hour")) {
+				_granularity_time_scale = AST_AOC_TIME_SCALE_HOUR;
+			} else if (!strcasecmp(granularitytimescale, "day")) {
+				_granularity_time_scale = AST_AOC_TIME_SCALE_DAY;
+			} else {
+				astman_send_error(s, m, "Invalid GranularityTimeScale");
+				goto aocmessage_cleanup;
+			}
+		}
+
+		if (ast_strlen_zero(chargingtype) || strcasecmp(chargingtype, "continuouscharging") == 0) {
+			_step = 0;
+		} else if (strcasecmp(chargingtype, "stepfunction") == 0 ) {
+			_step = 1;
+		} else {
+			astman_send_error(s, m, "Invalid ChargingType");
+			goto aocmessage_cleanup;
+		}
+	}
+
+	if (_ratetype == AST_AOC_RATE_TYPE_VOLUME) {
+		if (ast_strlen_zero(volumeunit)) {
+			astman_send_error(s, m, "VolumeUnit unspecified, VolumeUnit is required when RateType is Volume.");
+			goto aocmessage_cleanup;
+		} else if (!strcasecmp(timescale, "octet")) {
+			_volumeunit = AST_AOC_VOLUME_UNIT_OCTET;
+		} else if (!strcasecmp(timescale, "segment")) {
+			_volumeunit = AST_AOC_VOLUME_UNIT_SEGMENT;
+		} else if (!strcasecmp(timescale, "message")) {
+			_volumeunit = AST_AOC_VOLUME_UNIT_MESSAGE;
+		}else {
+			astman_send_error(s, m, "Invalid VolumeUnit");
+			goto aocmessage_cleanup;
+		}
+	}
+
+	if (_chargeditem == AST_AOC_CHARGED_ITEM_SPECIAL_ARRANGEMENT
+			|| _ratetype == AST_AOC_RATE_TYPE_SPECIAL_CODE) {
+		if (ast_strlen_zero(code) || (sscanf(code, "%30u", &_code) != 1)) {
+			astman_send_error(s, m, "Invalid Code, Code is a required when ChargedItem is SpecialArrangement and when RateType is SpecialCode");
+			goto aocmessage_cleanup;
+		}
+	}
+
+	if (_chargeditem == AST_AOC_CHARGED_ITEM_SPECIAL_ARRANGEMENT) {
+		ast_aoc_s_add_special_arrangement(decoded, _code);
+	} else if (_ratetype == AST_AOC_RATE_TYPE_DURATION) {
+		ast_aoc_s_add_rate_duration(decoded, _chargeditem, _currencyamount, _mult,
+			currencyname, _time, _scale, _granularity, _granularity_time_scale, _step);
+	} else if (_ratetype == AST_AOC_RATE_TYPE_FLAT) {
+		ast_aoc_s_add_rate_flat(decoded, _chargeditem, _currencyamount, _mult,
+				currencyname);
+	} else if (_ratetype == AST_AOC_RATE_TYPE_VOLUME) {
+		ast_aoc_s_add_rate_volume(decoded, _chargeditem, _volumeunit, _currencyamount,
+			_mult, currencyname);
+	} else if (_ratetype == AST_AOC_RATE_TYPE_SPECIAL_CODE) {
+		ast_aoc_s_add_rate_special_charge_code(decoded, _chargeditem, _code);
+	} else if (_ratetype == AST_AOC_RATE_TYPE_FREE) {
+		ast_aoc_s_add_rate_free(decoded, _chargeditem, 0);
+	} else if (_ratetype == AST_AOC_RATE_TYPE_FREE_FROM_BEGINNING) {
+		ast_aoc_s_add_rate_free(decoded, _chargeditem, 1);
+	} else if (_ratetype == AST_AOC_RATE_TYPE_NA) {
+		ast_aoc_s_add_rate_na(decoded, _chargeditem);
+	}
+
+	return 0;
+
+aocmessage_cleanup:
+
+	return -1;
+}
+
+static struct ast_aoc_decoded *action_aoc_s_message(struct mansession *s,
+		const struct message *m)
+{
+	struct ast_aoc_decoded *decoded = NULL;
+	int hdrlen;
+	int x;
+	static const char hdr[] = "ChargedItem:";
+	struct message sm = { 0 };
+	int rates = 0;
+
+	if (!(decoded = ast_aoc_create(AST_AOC_S, 0, 0))) {
+		astman_send_error(s, m, "Message Creation Failed");
+		goto aocmessage_cleanup;
+	}
+
+	hdrlen = strlen(hdr);
+	for (x = 0; x < m->hdrcount; x++) {
+		if (strncasecmp(hdr, m->headers[x], hdrlen) == 0) {
+			if (rates > ast_aoc_s_get_count(decoded)) {
+				if (action_aoc_s_submessage(s, &sm, decoded) == -1) {
+					goto aocmessage_cleanup;
+				}
+			}
+			++rates;
+		}
+
+		sm.headers[sm.hdrcount] = m->headers[x];
+		++sm.hdrcount;
+	}
+	if (rates > ast_aoc_s_get_count(decoded)) {
+		if (action_aoc_s_submessage(s, &sm, decoded) == -1) {
+			goto aocmessage_cleanup;
+		}
+	}
+
+	return decoded;
+
+aocmessage_cleanup:
+
+	ast_aoc_destroy_decoded(decoded);
+	return NULL;
+}
+
+static int action_aocmessage(struct mansession *s, const struct message *m)
+{
+	const char *msgtype = astman_get_header(m, "MsgType");
+	const char *channel = astman_get_header(m, "Channel");
+	const char *pchannel = astman_get_header(m, "ChannelPrefix");
+
+	struct ast_channel *chan = NULL;
+
+	struct ast_aoc_decoded *decoded = NULL;
+	struct ast_aoc_encoded *encoded = NULL;
+	size_t encoded_size = 0;
+
+	if (ast_strlen_zero(channel) && ast_strlen_zero(pchannel)) {
+		astman_send_error(s, m, "Channel and PartialChannel are not specified. Specify at least one of these.");
+		goto aocmessage_cleanup;
+	}
+
+	if (!(chan = ast_channel_get_by_name(channel)) && !ast_strlen_zero(pchannel)) {
+		chan = ast_channel_get_by_name_prefix(pchannel, strlen(pchannel));
+	}
+
+	if (!chan) {
+		astman_send_error(s, m, "No such channel");
+		goto aocmessage_cleanup;
+	}
+
+	if (strcasecmp(msgtype, "d") == 0 || strcasecmp(msgtype, "e") == 0) {
+		decoded = action_aoc_de_message(s, m);
+	}
+	else if (strcasecmp(msgtype, "s") == 0) {
+		decoded = action_aoc_s_message(s, m);
+	}
+	else {
+		astman_send_error(s, m, "Invalid MsgType");
+		goto aocmessage_cleanup;
+	}
+
+	if (!decoded) {
+		goto aocmessage_cleanup;
+	}
+
+	if ((encoded = ast_aoc_encode(decoded, &encoded_size, chan))
+			&& !ast_indicate_data(chan, AST_CONTROL_AOC, encoded, encoded_size)) {
 		astman_send_ack(s, m, "AOC Message successfully queued on channel");
 	} else {
 		astman_send_error(s, m, "Error encoding AOC message, could not queue onto channel");

-- 
To view, visit https://gerrit.asterisk.org/c/asterisk/+/19536
To unsubscribe, or for help writing mail filters, visit https://gerrit.asterisk.org/settings

Gerrit-Project: asterisk
Gerrit-Branch: 20
Gerrit-Change-Id: I051b778f8c862d3b4794d28f2f3d782316707b08
Gerrit-Change-Number: 19536
Gerrit-PatchSet: 3
Gerrit-Owner: Michael Kuron <m.kuron at gmx.de>
Gerrit-Reviewer: Friendly Automation
Gerrit-Reviewer: George Joseph <gjoseph at digium.com>
Gerrit-Reviewer: Joshua Colp <jcolp at sangoma.com>
Gerrit-MessageType: merged
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.digium.com/pipermail/asterisk-code-review/attachments/20221209/96c00126/attachment-0001.html>


More information about the asterisk-code-review mailing list