BuildSystem: Remove unused variables.
[asterisk/asterisk.git] / main / aoc.c
index 7dd888e..253c745 100644 (file)
@@ -28,7 +28,6 @@
  ***/
 
 #include "asterisk.h"
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$");
 
 #include "asterisk/aoc.h"
 #include "asterisk/utils.h"
@@ -85,6 +84,10 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$");
                                </parameter>
                                <parameter name="SpecialCode" />
                        </syntax>
+                       <see-also>
+                               <ref type="managerEvent">AOC-D</ref>
+                               <ref type="managerEvent">AOC-E</ref>
+                       </see-also>
                </managerEventInstance>
        </managerEvent>
        <managerEvent language="en_US" name="AOC-D">
@@ -138,6 +141,11 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$");
                                <parameter name="NumberOf" />
                                <parameter name="TypeOf" />
                        </syntax>
+                       <see-also>
+                               <ref type="manager">AOCMessage</ref>
+                               <ref type="managerEvent">AOC-S</ref>
+                               <ref type="managerEvent">AOC-E</ref>
+                       </see-also>
                </managerEventInstance>
        </managerEvent>
        <managerEvent language="en_US" name="AOC-E">
@@ -151,6 +159,11 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$");
                                <parameter name="ID" />
                                <xi:include xpointer="xpointer(/docs/managerEvent[@name='AOC-D']/managerEventInstance/syntax/parameter)" />
                        </syntax>
+                       <see-also>
+                               <ref type="manager">AOCMessage</ref>
+                               <ref type="managerEvent">AOC-S</ref>
+                               <ref type="managerEvent">AOC-D</ref>
+                       </see-also>
                </managerEventInstance>
        </managerEvent>
 ***/
@@ -1642,19 +1655,21 @@ static struct ast_json *units_to_json(const struct ast_aoc_decoded *decoded)
 static struct ast_json *currency_to_json(const char *name, int cost,
                                         enum ast_aoc_currency_multiplier mult)
 {
-       return ast_json_pack("{s:s, s:i, s:s}", "Name", name,
-                            "Cost", cost, "Multiplier", aoc_multiplier_str(mult));
+       return ast_json_pack("{s:s, s:i, s:s}",
+               "Name", AST_JSON_UTF8_VALIDATE(name),
+               "Cost", cost,
+               "Multiplier", aoc_multiplier_str(mult));
 }
 
 static struct ast_json *charge_to_json(const struct ast_aoc_decoded *decoded)
 {
-       RAII_VAR(struct ast_json *, obj, NULL, ast_json_unref);
+       struct ast_json *obj;
        const char *obj_type;
 
        if (decoded->charge_type != AST_AOC_CHARGE_CURRENCY &&
            decoded->charge_type != AST_AOC_CHARGE_UNIT) {
-               return ast_json_pack("{s:s}", "Type",
-                                    aoc_charge_type_str(decoded->charge_type));
+               return ast_json_pack("{s:s}",
+                       "Type", aoc_charge_type_str(decoded->charge_type));
        }
 
        if (decoded->charge_type == AST_AOC_CHARGE_CURRENCY) {
@@ -1666,8 +1681,7 @@ static struct ast_json *charge_to_json(const struct ast_aoc_decoded *decoded)
                obj = units_to_json(decoded);
        }
 
-       return ast_json_pack(
-               "{s:s, s:s, s:s, s:O}",
+       return ast_json_pack("{s:s, s:s, s:s, s:o}",
                "Type", aoc_charge_type_str(decoded->charge_type),
                "BillingID", aoc_billingid_str(decoded->billing_id),
                "TotalType", aoc_type_of_totaling_str(decoded->total_type),
@@ -1678,13 +1692,11 @@ static struct ast_json *association_to_json(const struct ast_aoc_decoded *decode
 {
        switch (decoded->charging_association.charging_type) {
        case AST_AOC_CHARGING_ASSOCIATION_NUMBER:
-               return ast_json_pack(
-                       "{s:s, s:i}",
-                       "Number", decoded->charging_association.charge.number.number,
+               return ast_json_pack("{s:s, s:i}",
+                       "Number", AST_JSON_UTF8_VALIDATE(decoded->charging_association.charge.number.number),
                        "Plan", decoded->charging_association.charge.number.plan);
        case AST_AOC_CHARGING_ASSOCIATION_ID:
-               return ast_json_pack(
-                       "{s:i}", "ID", decoded->charging_association.charge.id);
+               return ast_json_pack("{s:i}", "ID", decoded->charging_association.charge.id);
        case AST_AOC_CHARGING_ASSOCIATION_NA:
        default:
                return ast_json_null();
@@ -1701,9 +1713,9 @@ static struct ast_json *s_to_json(const struct ast_aoc_decoded *decoded)
        }
 
        for (i = 0; i < decoded->aoc_s_count; ++i) {
-               struct ast_json *rate = ast_json_object_create();
-               RAII_VAR(struct ast_json *, type, NULL, ast_json_unref);
-               RAII_VAR(struct ast_json *, currency, NULL, ast_json_unref);
+               struct ast_json *rate;
+               struct ast_json *type = NULL;
+               struct ast_json *currency;
                const char *charge_item = aoc_charged_item_str(
                        decoded->aoc_s_entries[i].charged_item);
 
@@ -1718,30 +1730,30 @@ static struct ast_json *s_to_json(const struct ast_aoc_decoded *decoded)
                switch (decoded->aoc_s_entries[i].rate_type) {
                case AST_AOC_RATE_TYPE_DURATION:
                {
-                       RAII_VAR(struct ast_json *, time, NULL, ast_json_unref);
-                       RAII_VAR(struct ast_json *, granularity, NULL, ast_json_unref);
+                       struct ast_json *time;
+                       struct ast_json *granularity = NULL;
 
                        currency = currency_to_json(
                                decoded->aoc_s_entries[i].rate.duration.currency_name,
                                decoded->aoc_s_entries[i].rate.duration.amount,
                                decoded->aoc_s_entries[i].rate.duration.multiplier);
 
-                       time = ast_json_pack(
-                               "{s:i, s:s}",
+                       time = ast_json_pack("{s:i, s:i}",
                                "Length", decoded->aoc_s_entries[i].rate.duration.time,
                                "Scale", decoded->aoc_s_entries[i].rate.duration.time_scale);
 
                        if (decoded->aoc_s_entries[i].rate.duration.granularity_time) {
-                               granularity = ast_json_pack(
-                                       "{s:i, s:s}",
+                               granularity = ast_json_pack("{s:i, s:i}",
                                        "Length", decoded->aoc_s_entries[i].rate.duration.granularity_time,
                                        "Scale", decoded->aoc_s_entries[i].rate.duration.granularity_time_scale);
                        }
 
-                       type = ast_json_pack("{s:O, s:s, s:O, s:O}", "Currency", currency, "ChargingType",
-                                            decoded->aoc_s_entries[i].rate.duration.charging_type ?
-                                            "StepFunction" : "ContinuousCharging", "Time", time,
-                                            "Granularity", granularity ? granularity : ast_json_null());
+                       type = ast_json_pack("{s:o, s:s, s:o, s:o}",
+                               "Currency", currency,
+                               "ChargingType", decoded->aoc_s_entries[i].rate.duration.charging_type
+                                       ? "StepFunction" : "ContinuousCharging",
+                               "Time", time,
+                               "Granularity", granularity ?: ast_json_null());
 
                        break;
                }
@@ -1751,7 +1763,7 @@ static struct ast_json *s_to_json(const struct ast_aoc_decoded *decoded)
                                decoded->aoc_s_entries[i].rate.flat.amount,
                                decoded->aoc_s_entries[i].rate.flat.multiplier);
 
-                       type = ast_json_pack("{s:O}", "Currency", currency);
+                       type = ast_json_pack("{s:o}", "Currency", currency);
                        break;
                case AST_AOC_RATE_TYPE_VOLUME:
                        currency = currency_to_json(
@@ -1759,21 +1771,22 @@ static struct ast_json *s_to_json(const struct ast_aoc_decoded *decoded)
                                decoded->aoc_s_entries[i].rate.volume.amount,
                                decoded->aoc_s_entries[i].rate.volume.multiplier);
 
-                       type = ast_json_pack(
-                               "{s:s, s:O}", "Unit", aoc_volume_unit_str(
+                       type = ast_json_pack("{s:s, s:o}",
+                               "Unit", aoc_volume_unit_str(
                                        decoded->aoc_s_entries[i].rate.volume.volume_unit),
                                "Currency", currency);
                        break;
                case AST_AOC_RATE_TYPE_SPECIAL_CODE:
-                       type = ast_json_pack("{s:i}", "SpecialCode",
-                                           decoded->aoc_s_entries[i].rate.special_code);
+                       type = ast_json_pack("{s:i}",
+                               "SpecialCode", decoded->aoc_s_entries[i].rate.special_code);
                        break;
                default:
                        break;
                }
 
-               rate = ast_json_pack("{s:s, s:O}", "Chargeable", charge_item,
-                                    aoc_rate_type_str(decoded->aoc_s_entries[i].rate_type), type);
+               rate = ast_json_pack("{s:s, s:o}",
+                       "Chargeable", charge_item,
+                       aoc_rate_type_str(decoded->aoc_s_entries[i].rate_type), type);
                if (ast_json_array_append(rates, rate)) {
                        break;
                }
@@ -1793,24 +1806,90 @@ static struct ast_json *e_to_json(const struct ast_aoc_decoded *decoded)
                             "Charge", charge_to_json(decoded));
 }
 
+struct aoc_event_blob {
+       /*! Channel AOC event is associated with (NULL for unassociated) */
+       struct ast_channel_snapshot *snapshot;
+       /*! AOC JSON blob of data */
+       struct ast_json *blob;
+};
+
+static void aoc_event_blob_dtor(void *obj)
+{
+       struct aoc_event_blob *aoc_event = obj;
+
+       ao2_cleanup(aoc_event->snapshot);
+       ast_json_unref(aoc_event->blob);
+}
+
+/*!
+ * \internal
+ * \brief Publish an AOC event.
+ * \since 13.3.0
+ *
+ * \param chan Channel associated with the AOC event. (May be NULL if no channel)
+ * \param msg_type What kind of AOC event.
+ * \param blob AOC data blob to publish.
+ *
+ * \return Nothing
+ */
+static void aoc_publish_blob(struct ast_channel *chan, struct stasis_message_type *msg_type, struct ast_json *blob)
+{
+       struct stasis_message *msg;
+       struct aoc_event_blob *aoc_event;
+
+       if (!blob || ast_json_is_null(blob)) {
+               /* No AOC blob information?  Nothing to send an event about. */
+               return;
+       }
+
+       aoc_event = ao2_alloc_options(sizeof(*aoc_event), aoc_event_blob_dtor,
+               AO2_ALLOC_OPT_LOCK_NOLOCK);
+       if (!aoc_event) {
+               return;
+       }
+
+       if (chan) {
+               aoc_event->snapshot = ast_channel_snapshot_get_latest(ast_channel_uniqueid(chan));
+               if (!aoc_event->snapshot) {
+                       ao2_ref(aoc_event, -1);
+                       return;
+               }
+       }
+       aoc_event->blob = ast_json_ref(blob);
+
+       msg = stasis_message_create(msg_type, aoc_event);
+       ao2_ref(aoc_event, -1);
+
+       if (msg) {
+               stasis_publish(ast_manager_get_topic(), msg);
+               ao2_ref(msg, -1);
+       }
+}
+
 static struct ast_manager_event_blob *aoc_to_ami(struct stasis_message *message,
                                                 const char *event_name)
 {
-       struct ast_channel_blob *obj = stasis_message_data(message);
-       RAII_VAR(struct ast_str *, channel, NULL, ast_free);
-       RAII_VAR(struct ast_str *, aoc, NULL, ast_free);
+       struct aoc_event_blob *aoc_event = stasis_message_data(message);
+       struct ast_str *channel = NULL;
+       struct ast_str *aoc;
+       struct ast_manager_event_blob *ev = NULL;
 
-       if (!(channel = ast_manager_build_channel_state_string(
-                     obj->snapshot))) {
-               return NULL;
+       if (aoc_event->snapshot) {
+               channel = ast_manager_build_channel_state_string(aoc_event->snapshot);
+               if (!channel) {
+                       return NULL;
+               }
        }
 
-       if (!(aoc = ast_manager_str_from_json_object(obj->blob, NULL))) {
-               return NULL;
+       aoc = ast_manager_str_from_json_object(aoc_event->blob, NULL);
+       if (aoc && !ast_strlen_zero(ast_str_buffer(aoc))) {
+               ev = ast_manager_event_blob_create(EVENT_FLAG_AOC, event_name, "%s%s",
+                       AS_OR(channel, ""), ast_str_buffer(aoc));
        }
 
-       return ast_manager_event_blob_create(EVENT_FLAG_AOC, event_name, "%s%s",
-                                            AS_OR(channel, ""), ast_str_buffer(aoc));
+       ast_free(aoc);
+       ast_free(channel);
+       return ev;
 }
 
 static struct ast_manager_event_blob *aoc_s_to_ami(struct stasis_message *message)
@@ -1846,7 +1925,7 @@ STASIS_MESSAGE_TYPE_DEFN(
 
 int ast_aoc_manager_event(const struct ast_aoc_decoded *decoded, struct ast_channel *chan)
 {
-       RAII_VAR(struct ast_json *, blob, NULL, ast_json_unref);
+       struct ast_json *blob;
        struct stasis_message_type *msg_type;
 
        if (!decoded) {
@@ -1871,7 +1950,8 @@ int ast_aoc_manager_event(const struct ast_aoc_decoded *decoded, struct ast_chan
                return 0;
        }
 
-       ast_channel_publish_blob(chan, msg_type, blob);
+       aoc_publish_blob(chan, msg_type, blob);
+       ast_json_unref(blob);
        return 0;
 }
 
@@ -1947,6 +2027,6 @@ int ast_aoc_cli_init(void)
        STASIS_MESSAGE_TYPE_INIT(aoc_d_type);
        STASIS_MESSAGE_TYPE_INIT(aoc_e_type);
 
-       ast_register_atexit(aoc_shutdown);
+       ast_register_cleanup(aoc_shutdown);
        return ast_cli_register_multiple(aoc_cli, ARRAY_LEN(aoc_cli));
 }