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