<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>