]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
Stasis: Allow message types to be blocked
authorKinsey Moore <kmoore@digium.com>
Wed, 6 Aug 2014 12:55:28 +0000 (12:55 +0000)
committerKinsey Moore <kmoore@digium.com>
Wed, 6 Aug 2014 12:55:28 +0000 (12:55 +0000)
This introduces stasis.conf and a mechanism to prevent certain message
types from being published. Internally, this works by preventing the
chosen message types from being created which ensures that those
message types can never be published. This patch also adjusts message
publishers such that message payloads are not created if the related
message type is not available.

ASTERISK-23943 #close
Review: https://reviewboard.asterisk.org/r/3823/

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@420124 65c4cc65-6c06-0410-ace0-fbb531ad65f3

39 files changed:
apps/app_chanspy.c
apps/app_forkcdr.c
apps/app_queue.c
configs/samples/stasis.conf.sample [new file with mode: 0644]
funcs/func_cdr.c
include/asterisk/stasis.h
main/app.c
main/bridge.c
main/ccss.c
main/cdr.c
main/channel.c
main/core_local.c
main/devicestate.c
main/endpoints.c
main/file.c
main/loader.c
main/manager.c
main/named_acl.c
main/pickup.c
main/presencestate.c
main/rtp_engine.c
main/security_events.c
main/stasis.c
main/stasis_bridges.c
main/stasis_cache.c
main/stasis_channels.c
main/stasis_endpoints.c
main/stasis_message.c
main/stasis_system.c
main/test.c
pbx/pbx_realtime.c
res/parking/parking_manager.c
res/res_corosync.c
res/res_stasis.c
res/res_stasis_snoop.c
res/res_stasis_test.c
res/res_stun_monitor.c
tests/test_stasis.c
tests/test_stasis_channels.c

index af69be30334a4139acef676f4112b64594cea51a..5806b997d7e68fc13131a7cb4bf2f47508bcd27f 100644 (file)
@@ -557,13 +557,14 @@ static void publish_chanspy_message(struct ast_channel *spyer,
        RAII_VAR(struct ast_json *, blob, NULL, ast_json_unref);
        RAII_VAR(struct ast_multi_channel_blob *, payload, NULL, ao2_cleanup);
        RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup);
+       struct stasis_message_type *type = start ? ast_channel_chanspy_start_type(): ast_channel_chanspy_stop_type();
 
        if (!spyer) {
                ast_log(AST_LOG_WARNING, "Attempt to publish ChanSpy message for NULL spyer channel\n");
                return;
        }
        blob = ast_json_null();
-       if (!blob) {
+       if (!blob || !type) {
                return;
        }
 
@@ -582,9 +583,7 @@ static void publish_chanspy_message(struct ast_channel *spyer,
                }
        }
 
-       message = stasis_message_create(
-                       start ? ast_channel_chanspy_start_type(): ast_channel_chanspy_stop_type(),
-                                       payload);
+       message = stasis_message_create(type, payload);
        if (!message) {
                return;
        }
index 932e862e1ad3c2b6aa9319052ce6c02a6c13d088..bbd15881a5e0147d0ab7def527aec12b615ac70d 100644 (file)
@@ -136,7 +136,7 @@ static void forkcdr_callback(void *data, struct stasis_subscription *sub, struct
 static int forkcdr_exec(struct ast_channel *chan, const char *data)
 {
        RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup);
-       RAII_VAR(struct fork_cdr_message_payload *, payload, ao2_alloc(sizeof(*payload), NULL), ao2_cleanup);
+       RAII_VAR(struct fork_cdr_message_payload *, payload, NULL, ao2_cleanup);
        RAII_VAR(struct stasis_message_router *, router, ast_cdr_message_router(), ao2_cleanup);
 
        char *parse;
@@ -153,6 +153,13 @@ static int forkcdr_exec(struct ast_channel *chan, const char *data)
                ast_app_parse_options(forkcdr_exec_options, &flags, NULL, args.options);
        }
 
+       if (!forkcdr_message_type()) {
+               ast_log(AST_LOG_WARNING, "Failed to manipulate CDR for channel %s: no message type\n",
+                       ast_channel_name(chan));
+               return -1;
+       }
+
+       payload = ao2_alloc(sizeof(*payload), NULL);
        if (!payload) {
                return -1;
        }
index b0c81df38ab5ff024d7ab4a5a64045b92fc28335..012f04a710032d3758223607ce08493c223e88c8 100644 (file)
@@ -2066,6 +2066,10 @@ static void queue_publish_multi_channel_snapshot_blob(struct stasis_topic *topic
        RAII_VAR(struct ast_multi_channel_blob *, payload, NULL, ao2_cleanup);
        RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
 
+       if (!type) {
+               return;
+       }
+
        payload = ast_multi_channel_blob_create(blob);
        if (!payload) {
                return;
@@ -2122,7 +2126,7 @@ static void queue_publish_member_blob(struct stasis_message_type *type, struct a
        RAII_VAR(struct ast_json_payload *, payload, NULL, ao2_cleanup);
        RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
 
-       if (!blob) {
+       if (!blob || !type) {
                return;
        }
 
diff --git a/configs/samples/stasis.conf.sample b/configs/samples/stasis.conf.sample
new file mode 100644 (file)
index 0000000..3aac230
--- /dev/null
@@ -0,0 +1,122 @@
+[declined_message_types]
+; This config section contains the names of message types that should be prevented
+; from being created. By default, all message types are allowed to be created.
+;
+; Using this functionality requires knowledge of the names of internal stasis
+; message types which is generally the same as the name of the accessor function.
+;
+; Use of this functionality may break more complex functionality in Asterisk
+; such as CEL, CDR, transfers, etc. and will likely cause related messages in ARI
+; and AMI to go missing.
+; decline=stasis_app_recording_snapshot_type
+; decline=stasis_app_playback_snapshot_type
+; decline=stasis_test_message_type
+; decline=confbridge_start_type
+; decline=confbridge_end_type
+; decline=confbridge_join_type
+; decline=confbridge_leave_type
+; decline=confbridge_start_record_type
+; decline=confbridge_stop_record_type
+; decline=confbridge_mute_type
+; decline=confbridge_unmute_type
+; decline=confbridge_talking_type
+; decline=cel_generic_type
+; decline=ast_bridge_snapshot_type
+; decline=ast_bridge_merge_message_type
+; decline=ast_channel_entered_bridge_type
+; decline=ast_channel_left_bridge_type
+; decline=ast_blind_transfer_type
+; decline=ast_attended_transfer_type
+; decline=ast_endpoint_snapshot_type
+; decline=ast_endpoint_state_type
+; decline=ast_device_state_message_type
+; decline=ast_test_suite_message_type
+; decline=ast_mwi_state_type
+; decline=ast_mwi_vm_app_type
+; decline=ast_format_register_type
+; decline=ast_format_unregister_type
+; decline=ast_manager_get_generic_type
+; decline=ast_parked_call_type
+; decline=ast_channel_snapshot_type
+; decline=ast_channel_dial_type
+; decline=ast_channel_varset_type
+; decline=ast_channel_hangup_request_type
+; decline=ast_channel_dtmf_begin_type
+; decline=ast_channel_dtmf_end_type
+; decline=ast_channel_hold_type
+; decline=ast_channel_unhold_type
+; decline=ast_channel_chanspy_start_type
+; decline=ast_channel_chanspy_stop_type
+; decline=ast_channel_fax_type
+; decline=ast_channel_hangup_handler_type
+; decline=ast_channel_moh_start_type
+; decline=ast_channel_moh_stop_type
+; decline=ast_channel_monitor_start_type
+; decline=ast_channel_monitor_stop_type
+; decline=ast_channel_agent_login_type
+; decline=ast_channel_agent_logoff_type
+; decline=ast_channel_talking_start
+; decline=ast_channel_talking_stop
+; decline=ast_security_event_type
+; decline=ast_named_acl_change_type
+; decline=ast_local_bridge_type
+; decline=ast_local_optimization_begin_type
+; decline=ast_local_optimization_end_type
+; decline=stasis_subscription_change_type
+; decline=ast_multi_user_event_type
+; decline=stasis_cache_clear_type
+; decline=stasis_cache_update_type
+; decline=ast_network_change_type
+; decline=ast_system_registry_type
+; decline=ast_cc_available_type
+; decline=ast_cc_offertimerstart_type
+; decline=ast_cc_requested_type
+; decline=ast_cc_requestacknowledged_type
+; decline=ast_cc_callerstopmonitoring_type
+; decline=ast_cc_callerstartmonitoring_type
+; decline=ast_cc_callerrecalling_type
+; decline=ast_cc_recallcomplete_type
+; decline=ast_cc_failure_type
+; decline=ast_cc_monitorfailed_type
+; decline=ast_presence_state_message_type
+; decline=ast_rtp_rtcp_sent_type
+; decline=ast_rtp_rtcp_received_type
+; decline=ast_call_pickup_type
+; decline=aoc_s_type
+; decline=aoc_d_type
+; decline=aoc_e_type
+; decline=dahdichannel_type
+; decline=mcid_type
+; decline=session_timeout_type
+; decline=cdr_read_message_type
+; decline=cdr_write_message_type
+; decline=cdr_prop_write_message_type
+; decline=corosync_ping_message_type
+; decline=agi_exec_start_type
+; decline=agi_exec_end_type
+; decline=agi_async_start_type
+; decline=agi_async_exec_type
+; decline=agi_async_end_type
+; decline=queue_caller_join_type
+; decline=queue_caller_leave_type
+; decline=queue_caller_abandon_type
+; decline=queue_member_status_type
+; decline=queue_member_added_type
+; decline=queue_member_removed_type
+; decline=queue_member_pause_type
+; decline=queue_member_penalty_type
+; decline=queue_member_ringinuse_type
+; decline=queue_agent_called_type
+; decline=queue_agent_connect_type
+; decline=queue_agent_complete_type
+; decline=queue_agent_dump_type
+; decline=queue_agent_ringnoanswer_type
+; decline=meetme_join_type
+; decline=meetme_leave_type
+; decline=meetme_end_type
+; decline=meetme_mute_type
+; decline=meetme_talking_type
+; decline=meetme_talk_request_type
+; decline=appcdr_message_type
+; decline=forkcdr_message_type
+; decline=cdr_sync_message_type
index 44ecf4d6b4106a2d553d6c9f2d15ce3725d958a7..c9fce23d2d0b629d0626a4ac947daf2019555c73 100644 (file)
@@ -437,8 +437,7 @@ static int cdr_read(struct ast_channel *chan, const char *cmd, char *parse,
                    char *buf, size_t len)
 {
        RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup);
-       RAII_VAR(struct cdr_func_payload *, payload,
-               ao2_alloc(sizeof(*payload), NULL), ao2_cleanup);
+       RAII_VAR(struct cdr_func_payload *, payload, NULL, ao2_cleanup);
        struct cdr_func_data output = { 0, };
 
        if (!chan) {
@@ -446,6 +445,13 @@ static int cdr_read(struct ast_channel *chan, const char *cmd, char *parse,
                return -1;
        }
 
+       if (!cdr_read_message_type()) {
+               ast_log(AST_LOG_WARNING, "Failed to manipulate CDR for channel %s: message type not available\n",
+                       ast_channel_name(chan));
+               return -1;
+       }
+
+       payload = ao2_alloc(sizeof(*payload), NULL);
        if (!payload) {
                return -1;
        }
@@ -489,8 +495,7 @@ static int cdr_write(struct ast_channel *chan, const char *cmd, char *parse,
                     const char *value)
 {
        RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup);
-       RAII_VAR(struct cdr_func_payload *, payload,
-                    ao2_alloc(sizeof(*payload), NULL), ao2_cleanup);
+       RAII_VAR(struct cdr_func_payload *, payload, NULL, ao2_cleanup);
        RAII_VAR(struct stasis_message_router *, router,
                     ast_cdr_message_router(), ao2_cleanup);
 
@@ -505,6 +510,13 @@ static int cdr_write(struct ast_channel *chan, const char *cmd, char *parse,
                return -1;
        }
 
+       if (!cdr_write_message_type()) {
+               ast_log(AST_LOG_WARNING, "Failed to manipulate CDR for channel %s: message type not available\n",
+                       ast_channel_name(chan));
+               return -1;
+       }
+
+       payload = ao2_alloc(sizeof(*payload), NULL);
        if (!payload) {
                return -1;
        }
@@ -543,6 +555,13 @@ static int cdr_prop_write(struct ast_channel *chan, const char *cmd, char *parse
                return -1;
        }
 
+       if (!cdr_write_message_type()) {
+               ast_log(AST_LOG_WARNING, "Failed to manipulate CDR for channel %s: message type not available\n",
+                       ast_channel_name(chan));
+               return -1;
+       }
+
+       payload = ao2_alloc(sizeof(*payload), NULL);
        if (!payload) {
                return -1;
        }
index 4c4052c144f80b1e512578f0384f897ed5891266..b8dc4c84576475b2005e7e6f7e3b09a56d099f4f 100644 (file)
@@ -273,6 +273,15 @@ struct stasis_message_vtable {
                struct stasis_message *message);
 };
 
+/*!
+ * \brief Return code for Stasis message type creation attempts
+ */
+enum stasis_message_type_result {
+       STASIS_MESSAGE_TYPE_ERROR = -1, /*!< Message type was not created due to allocation failure */
+       STASIS_MESSAGE_TYPE_SUCCESS,    /*!< Message type was created successfully */
+       STASIS_MESSAGE_TYPE_DECLINED,   /*!< Message type was not created due to configuration */
+};
+
 /*!
  * \brief Create a new message type.
  *
@@ -281,12 +290,15 @@ struct stasis_message_vtable {
  *
  * \param name Name of the new type.
  * \param vtable Virtual table of message methods. May be \c NULL.
- * \return Pointer to the new type.
- * \return \c NULL on error.
+ * \param[out] result The location where the new message type will be placed
+ *
+ * \note Stasis message type creation may be declined if the message type is disabled
+ *
+ * \returns A stasis_message_type_result enum
  * \since 12
  */
-struct stasis_message_type *stasis_message_type_create(const char *name,
-       struct stasis_message_vtable *vtable);
+enum stasis_message_type_result stasis_message_type_create(const char *name,
+       struct stasis_message_vtable *vtable, struct stasis_message_type **result);
 
 /*!
  * \brief Gets the name of a given message type
@@ -297,6 +309,16 @@ struct stasis_message_type *stasis_message_type_create(const char *name,
  */
 const char *stasis_message_type_name(const struct stasis_message_type *type);
 
+/*!
+ * \brief Check whether a message type is declined
+ *
+ * \param name The name of the message type to check
+ *
+ * \retval zero The message type is not declined
+ * \retval non-zero The message type is declined
+ */
+int stasis_message_type_declined(const char *name);
+
 /*!
  * \brief Create a new message.
  *
@@ -1184,9 +1206,8 @@ void stasis_log_bad_type_access(const char *name);
 #define STASIS_MESSAGE_TYPE_INIT(name)                                 \
        ({                                                              \
                ast_assert(_priv_ ## name == NULL);                     \
-               _priv_ ## name = stasis_message_type_create(#name,      \
-                       &_priv_ ## name ## _v);                         \
-               _priv_ ## name ? 0 : -1;                                \
+               stasis_message_type_create(#name,       \
+                       &_priv_ ## name ## _v, &_priv_ ## name) == STASIS_MESSAGE_TYPE_ERROR ? 1 : 0;   \
        })
 
 /*!
index fa7c3ece138a4f04d1407463179d1a49d6592943..89889c65f21617cdce61e780384b9d9d5839a18d 100644 (file)
@@ -3104,6 +3104,10 @@ static struct stasis_message *mwi_state_create_message(
        struct ast_mwi_state *mwi_state;
        struct stasis_message *message;
 
+       if (!ast_mwi_state_type()) {
+               return NULL;
+       }
+
        mwi_state = ast_mwi_create(mailbox, context);
        if (!mwi_state) {
                return NULL;
@@ -3247,6 +3251,10 @@ struct stasis_message *ast_mwi_blob_create(struct ast_mwi_state *mwi_state,
 
        ast_assert(blob != NULL);
 
+       if (!message_type) {
+               return NULL;
+       }
+
        obj = ao2_alloc(sizeof(*obj), mwi_blob_dtor);
        if (!obj) {
                return NULL;
index 63086e16ee022a2efffb25d66d0588abf259dfdd..462676ca844e437a430a116ff65c5c25e72cd7bb 100644 (file)
@@ -615,6 +615,10 @@ static struct stasis_message *create_bridge_snapshot_message(struct ast_bridge *
 {
        RAII_VAR(struct ast_bridge_snapshot *, snapshot, NULL, ao2_cleanup);
 
+       if (!ast_bridge_snapshot_type()) {
+               return NULL;
+       }
+
        ast_bridge_lock(bridge);
        snapshot = ast_bridge_snapshot_create(bridge);
        ast_bridge_unlock(bridge);
index 9fcabfefd6fbc5c528de1cb50b278f179f0d8750..3626f3d38b9cb21bacd6a3f0d5823cf5792773d3 100644 (file)
@@ -1032,8 +1032,15 @@ static int cc_publish(struct stasis_message_type *message_type, int core_id, str
        RAII_VAR(struct ast_json_payload *, payload, NULL, ao2_cleanup);
        RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup);
 
+       if (!message_type) {
+               return -1;
+       }
+
        blob = ast_json_pack("{s: i}",
                "core_id", core_id);
+       if (!blob) {
+               return -1;
+       }
 
        if (extras) {
                ast_json_object_update(blob, extras);
index 17fa8a25fafb00e3a7ae1d2cb492e56c01ecf40d..2aaef88626c753d48442fc7d602d919f79f7e647 100644 (file)
@@ -4198,7 +4198,7 @@ int ast_cdr_engine_init(void)
 void ast_cdr_engine_term(void)
 {
        RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
-       RAII_VAR(void *, payload, ao2_alloc(sizeof(*payload), NULL), ao2_cleanup);
+       RAII_VAR(void *, payload, NULL, ao2_cleanup);
        RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup);
 
        /* Since this is called explicitly during process shutdown, we might not have ever
@@ -4208,16 +4208,19 @@ void ast_cdr_engine_term(void)
                return;
        }
 
-       /* Make sure we have the needed items */
-       if (!stasis_router || !payload) {
-               return;
-       }
+       if (cdr_sync_message_type()) {
+               /* Make sure we have the needed items */
+               payload = ao2_alloc(sizeof(*payload), NULL);
+               if (!stasis_router || !payload) {
+                       return;
+               }
 
-       ast_debug(1, "CDR Engine termination request received; waiting on messages...\n");
+               ast_debug(1, "CDR Engine termination request received; waiting on messages...\n");
 
-       message = stasis_message_create(cdr_sync_message_type(), payload);
-       if (message) {
-               stasis_message_router_publish_sync(stasis_router, message);
+               message = stasis_message_create(cdr_sync_message_type(), payload);
+               if (message) {
+                       stasis_message_router_publish_sync(stasis_router, message);
+               }
        }
 
        if (ast_test_flag(&mod_cfg->general->settings, CDR_BATCHMODE)) {
index 6a252a6991cab4899de431459e74d3048cd35c26..23799d9be810a62e7db622d950a9b144440935d9 100644 (file)
@@ -678,6 +678,11 @@ int ast_str2cause(const char *name)
 static struct stasis_message *create_channel_snapshot_message(struct ast_channel *channel)
 {
        RAII_VAR(struct ast_channel_snapshot *, snapshot, NULL, ao2_cleanup);
+
+       if (!ast_channel_snapshot_type()) {
+               return NULL;
+       }
+
        ast_channel_lock(channel);
        snapshot = ast_channel_snapshot_create(channel);
        ast_channel_unlock(channel);
index e1b66d0a736d04c277927dccd9f49a5df70e2aa9..54915ecfe2fecd0437bb1a2c7e1db5d6382633a3 100644 (file)
@@ -357,6 +357,10 @@ static void local_optimization_started_cb(struct ast_unreal_pvt *base, struct as
        RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
        struct local_pvt *p = (struct local_pvt *)base;
 
+       if (!ast_local_optimization_begin_type()) {
+               return;
+       }
+
        json_object = ast_json_pack("{s: i, s: i}",
                        "dest", dest, "id", id);
 
@@ -395,6 +399,10 @@ static void local_optimization_finished_cb(struct ast_unreal_pvt *base, int succ
        RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
        struct local_pvt *p = (struct local_pvt *)base;
 
+       if (!ast_local_optimization_end_type()) {
+               return;
+       }
+
        json_object = ast_json_pack("{s: i, s: i}", "success", success, "id", id);
 
        if (!json_object) {
@@ -501,6 +509,10 @@ static void publish_local_bridge_message(struct local_pvt *p)
        struct ast_channel *owner;
        struct ast_channel *chan;
 
+       if (!ast_local_bridge_type()) {
+               return;
+       }
+
        ast_unreal_lock_all(&p->base, &chan, &owner);
 
        blob = ast_json_pack("{s: s, s: s, s: b}",
index c4a57dd685788fcf3a677aa75aeda8b1a9aed07e..7f9136da39a63ca4d0cc1e48e5ce1131a4fc9791 100644 (file)
@@ -721,6 +721,10 @@ int ast_publish_device_state_full(
 
        ast_assert(!ast_strlen_zero(device));
 
+       if (!ast_device_state_message_type()) {
+               return -1;
+       }
+
        device_state = device_state_alloc(device, state, cachable, eid);
        if (!device_state) {
                return -1;
@@ -807,6 +811,10 @@ static struct stasis_message *device_state_aggregate_calc(struct stasis_cache_en
        struct ast_devstate_aggregate aggregate;
        int idx;
 
+       if (!ast_device_state_message_type()) {
+               return NULL;
+       }
+
        /* Determine the new aggregate device state. */
        ast_devstate_aggregate_init(&aggregate);
        snapshot = stasis_cache_entry_get_local(entry);
index 07687eecc5066f515f6b1fe009870aa3d54b2968..cc2eccc705ee6b1eff3e3d8cc78b269b1d90b2dc 100644 (file)
@@ -174,6 +174,10 @@ static void endpoint_publish_snapshot(struct ast_endpoint *endpoint)
        ast_assert(endpoint != NULL);
        ast_assert(endpoint->topics != NULL);
 
+       if (!ast_endpoint_snapshot_type()) {
+               return;
+       }
+
        snapshot = ast_endpoint_snapshot_create(endpoint);
        if (!snapshot) {
                return;
@@ -349,6 +353,11 @@ struct ast_endpoint *ast_endpoint_create(const char *tech, const char *resource)
 static struct stasis_message *create_endpoint_snapshot_message(struct ast_endpoint *endpoint)
 {
        RAII_VAR(struct ast_endpoint_snapshot *, snapshot, NULL, ao2_cleanup);
+
+       if (!ast_endpoint_snapshot_type()) {
+               return NULL;
+       }
+
        snapshot = ast_endpoint_snapshot_create(endpoint);
        if (!snapshot) {
                return NULL;
index fa4c63bd95a624f3d2dae306d91884c83f81c3dc..59d39df8fd598bcc8e7e652a6716a455d51e0d2e 100644 (file)
@@ -97,6 +97,10 @@ static int publish_format_update(const struct ast_format_def *f, struct stasis_m
        RAII_VAR(struct ast_json_payload *, json_payload, NULL, ao2_cleanup);
        RAII_VAR(struct ast_json *, json_object, NULL, ast_json_unref);
 
+       if (!type) {
+               return -1;
+       }
+
        json_object = ast_json_pack("{s: s, s: o}",
                "format", f->name,
                "extensions", json_array_from_list(f->exts, "|"));
index b4eef13c284eba8b7064960ed1a50e29c8dd04a6..ac17ddc9e78a4d946de8e586512234e60f09b793 100644 (file)
@@ -803,6 +803,10 @@ static void publish_reload_message(const char *name, enum ast_module_reload_resu
        RAII_VAR(struct ast_json *, event_object, NULL, ast_json_unref);
        char res_buffer[8];
 
+       if (!ast_manager_get_generic_type()) {
+               return;
+       }
+
        snprintf(res_buffer, sizeof(res_buffer), "%u", result);
        event_object = ast_json_pack("{s: s, s: s}",
                        "Module", S_OR(name, "All"),
index 7fa083ca9bf7d4022d1e52904de0aee9ec01f8fc..b4e927ffb8e20166a878898f72d30a3f4ef42675 100644 (file)
@@ -1519,7 +1519,7 @@ void ast_manager_publish_event(const char *type, int class_type, struct ast_json
        RAII_VAR(struct ast_json_payload *, payload, NULL, ao2_cleanup);
        RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup);
 
-       if (!obj) {
+       if (!obj || !ast_manager_get_generic_type()) {
                return;
        }
 
index f0b5c2894703b5dfaabbef2f58795da2327f9e62..deda260b7dbb2560476a99ccef0cca2224e00cc1 100644 (file)
@@ -380,7 +380,7 @@ static int publish_acl_change(const char *name)
        RAII_VAR(struct ast_json_payload *, json_payload, NULL, ao2_cleanup);
        RAII_VAR(struct ast_json *, json_object, ast_json_object_create(), ast_json_unref);
 
-       if (!json_object) {
+       if (!json_object || !ast_named_acl_change_type()) {
                goto publish_failure;
        }
 
index 5be0c03abecfc29112a1966879d3ac74884ec575..125ec9359cfcea9311380d3ce2fb633a617a84c4 100644 (file)
@@ -282,6 +282,10 @@ static int send_call_pickup_stasis_message(struct ast_channel *picking_up, struc
        RAII_VAR(struct ast_multi_channel_blob *, pickup_payload, NULL, ao2_cleanup);
        RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
 
+       if (!ast_call_pickup_type()) {
+               return -1;
+       }
+
        if (!(pickup_payload = ast_multi_channel_blob_create(ast_json_null()))) {
                return -1;
        }
index db947df3414ca8c0321114da6c1c530e18329923..07df7429d9510208e2a27704d01add3227ed8e1e 100644 (file)
@@ -263,8 +263,13 @@ static void presence_state_event(const char *provider,
                const char *message)
 {
        RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
-       RAII_VAR(struct ast_presence_state_message *, presence_state, presence_state_alloc(provider, state, subtype, message), ao2_cleanup);
+       RAII_VAR(struct ast_presence_state_message *, presence_state, NULL, ao2_cleanup);
 
+       if (!ast_presence_state_message_type()) {
+               return;
+       }
+
+       presence_state = presence_state_alloc(provider, state, subtype, message);
        if (!presence_state) {
                return;
        }
index 52be8b90e28549d3c2a1cbe9dea6a4c7a19e92cf..0c624ab61627f2111a3b7236705e7fab687208ea 100644 (file)
@@ -1996,6 +1996,10 @@ void ast_rtp_publish_rtcp_message(struct ast_rtp_instance *rtp,
        RAII_VAR(struct rtcp_message_payload *, payload, NULL, ao2_cleanup);
        RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup);
 
+       if (!message_type) {
+               return;
+       }
+
        payload = ao2_alloc(sizeof(*payload), rtcp_message_payload_dtor);
        if (!payload || !report) {
                return;
index f4dc6fc6d8a6aef26312503e7c0f0dc6f988cb0f..00a70fbec541b9f74ad05febc375a5088493ad7d 100644 (file)
@@ -1127,8 +1127,11 @@ static int handle_security_event(const struct ast_security_event_common *sec)
        const struct ast_security_event_ie_type *ies;
        unsigned int i;
 
-       json_object = alloc_security_event_json_object(sec);
+       if (!ast_security_event_type()) {
+               return -1;
+       }
 
+       json_object = alloc_security_event_json_object(sec);
        if (!json_object) {
                return -1;
        }
index 594ec5e99c9641ea0e29269f4ea419219cf3a5a7..d8e0e5afc8762efc30604e28f02d8bc6bffc266e 100644 (file)
@@ -41,6 +41,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$");
 #include "asterisk/stasis_channels.h"
 #include "asterisk/stasis_bridges.h"
 #include "asterisk/stasis_endpoints.h"
+#include "asterisk/config_options.h"
 
 /*** DOCUMENTATION
        <managerEvent language="en_US" name="UserEvent">
@@ -60,6 +61,135 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$");
                        </see-also>
                </managerEventInstance>
        </managerEvent>
+       <configInfo name="stasis" language="en_US">
+               <configFile name="stasis.conf">
+                       <configObject name="declined_message_types">
+                               <synopsis>Stasis message types for which to decline creation.</synopsis>
+                               <configOption name="decline">
+                                       <synopsis>The message type to decline.</synopsis>
+                                       <description>
+                                               <para>This configuration option defines the name of the Stasis
+                                               message type that Asterisk is forbidden from creating and can be
+                                               specified as many times as necessary to achieve the desired result.</para>
+                                               <enumlist>
+                                                       <enum name="stasis_app_recording_snapshot_type" />
+                                                       <enum name="stasis_app_playback_snapshot_type" />
+                                                       <enum name="stasis_test_message_type" />
+                                                       <enum name="confbridge_start_type" />
+                                                       <enum name="confbridge_end_type" />
+                                                       <enum name="confbridge_join_type" />
+                                                       <enum name="confbridge_leave_type" />
+                                                       <enum name="confbridge_start_record_type" />
+                                                       <enum name="confbridge_stop_record_type" />
+                                                       <enum name="confbridge_mute_type" />
+                                                       <enum name="confbridge_unmute_type" />
+                                                       <enum name="confbridge_talking_type" />
+                                                       <enum name="cel_generic_type" />
+                                                       <enum name="ast_bridge_snapshot_type" />
+                                                       <enum name="ast_bridge_merge_message_type" />
+                                                       <enum name="ast_channel_entered_bridge_type" />
+                                                       <enum name="ast_channel_left_bridge_type" />
+                                                       <enum name="ast_blind_transfer_type" />
+                                                       <enum name="ast_attended_transfer_type" />
+                                                       <enum name="ast_endpoint_snapshot_type" />
+                                                       <enum name="ast_endpoint_state_type" />
+                                                       <enum name="ast_device_state_message_type" />
+                                                       <enum name="ast_test_suite_message_type" />
+                                                       <enum name="ast_mwi_state_type" />
+                                                       <enum name="ast_mwi_vm_app_type" />
+                                                       <enum name="ast_format_register_type" />
+                                                       <enum name="ast_format_unregister_type" />
+                                                       <enum name="ast_manager_get_generic_type" />
+                                                       <enum name="ast_parked_call_type" />
+                                                       <enum name="ast_channel_snapshot_type" />
+                                                       <enum name="ast_channel_dial_type" />
+                                                       <enum name="ast_channel_varset_type" />
+                                                       <enum name="ast_channel_hangup_request_type" />
+                                                       <enum name="ast_channel_dtmf_begin_type" />
+                                                       <enum name="ast_channel_dtmf_end_type" />
+                                                       <enum name="ast_channel_hold_type" />
+                                                       <enum name="ast_channel_unhold_type" />
+                                                       <enum name="ast_channel_chanspy_start_type" />
+                                                       <enum name="ast_channel_chanspy_stop_type" />
+                                                       <enum name="ast_channel_fax_type" />
+                                                       <enum name="ast_channel_hangup_handler_type" />
+                                                       <enum name="ast_channel_moh_start_type" />
+                                                       <enum name="ast_channel_moh_stop_type" />
+                                                       <enum name="ast_channel_monitor_start_type" />
+                                                       <enum name="ast_channel_monitor_stop_type" />
+                                                       <enum name="ast_channel_agent_login_type" />
+                                                       <enum name="ast_channel_agent_logoff_type" />
+                                                       <enum name="ast_channel_talking_start" />
+                                                       <enum name="ast_channel_talking_stop" />
+                                                       <enum name="ast_security_event_type" />
+                                                       <enum name="ast_named_acl_change_type" />
+                                                       <enum name="ast_local_bridge_type" />
+                                                       <enum name="ast_local_optimization_begin_type" />
+                                                       <enum name="ast_local_optimization_end_type" />
+                                                       <enum name="stasis_subscription_change_type" />
+                                                       <enum name="ast_multi_user_event_type" />
+                                                       <enum name="stasis_cache_clear_type" />
+                                                       <enum name="stasis_cache_update_type" />
+                                                       <enum name="ast_network_change_type" />
+                                                       <enum name="ast_system_registry_type" />
+                                                       <enum name="ast_cc_available_type" />
+                                                       <enum name="ast_cc_offertimerstart_type" />
+                                                       <enum name="ast_cc_requested_type" />
+                                                       <enum name="ast_cc_requestacknowledged_type" />
+                                                       <enum name="ast_cc_callerstopmonitoring_type" />
+                                                       <enum name="ast_cc_callerstartmonitoring_type" />
+                                                       <enum name="ast_cc_callerrecalling_type" />
+                                                       <enum name="ast_cc_recallcomplete_type" />
+                                                       <enum name="ast_cc_failure_type" />
+                                                       <enum name="ast_cc_monitorfailed_type" />
+                                                       <enum name="ast_presence_state_message_type" />
+                                                       <enum name="ast_rtp_rtcp_sent_type" />
+                                                       <enum name="ast_rtp_rtcp_received_type" />
+                                                       <enum name="ast_call_pickup_type" />
+                                                       <enum name="aoc_s_type" />
+                                                       <enum name="aoc_d_type" />
+                                                       <enum name="aoc_e_type" />
+                                                       <enum name="dahdichannel_type" />
+                                                       <enum name="mcid_type" />
+                                                       <enum name="session_timeout_type" />
+                                                       <enum name="cdr_read_message_type" />
+                                                       <enum name="cdr_write_message_type" />
+                                                       <enum name="cdr_prop_write_message_type" />
+                                                       <enum name="corosync_ping_message_type" />
+                                                       <enum name="agi_exec_start_type" />
+                                                       <enum name="agi_exec_end_type" />
+                                                       <enum name="agi_async_start_type" />
+                                                       <enum name="agi_async_exec_type" />
+                                                       <enum name="agi_async_end_type" />
+                                                       <enum name="queue_caller_join_type" />
+                                                       <enum name="queue_caller_leave_type" />
+                                                       <enum name="queue_caller_abandon_type" />
+                                                       <enum name="queue_member_status_type" />
+                                                       <enum name="queue_member_added_type" />
+                                                       <enum name="queue_member_removed_type" />
+                                                       <enum name="queue_member_pause_type" />
+                                                       <enum name="queue_member_penalty_type" />
+                                                       <enum name="queue_member_ringinuse_type" />
+                                                       <enum name="queue_agent_called_type" />
+                                                       <enum name="queue_agent_connect_type" />
+                                                       <enum name="queue_agent_complete_type" />
+                                                       <enum name="queue_agent_dump_type" />
+                                                       <enum name="queue_agent_ringnoanswer_type" />
+                                                       <enum name="meetme_join_type" />
+                                                       <enum name="meetme_leave_type" />
+                                                       <enum name="meetme_end_type" />
+                                                       <enum name="meetme_mute_type" />
+                                                       <enum name="meetme_talking_type" />
+                                                       <enum name="meetme_talk_request_type" />
+                                                       <enum name="appcdr_message_type" />
+                                                       <enum name="forkcdr_message_type" />
+                                                       <enum name="cdr_sync_message_type" />
+                                               </enumlist>
+                                       </description>
+                               </configOption>
+                       </configObject>
+               </configFile>
+       </configInfo>
 ***/
 
 /*!
@@ -801,6 +931,10 @@ static void send_subscription_subscribe(struct stasis_topic *topic, struct stasi
        /* This assumes that we have already unsubscribed */
        ast_assert(stasis_subscription_is_subscribed(sub));
 
+       if (!stasis_subscription_change_type()) {
+               return;
+       }
+
        change = subscription_change_alloc(topic, sub->uniqueid, "Subscribe");
        if (!change) {
                return;
@@ -826,6 +960,10 @@ static void send_subscription_unsubscribe(struct stasis_topic *topic,
        /* This assumes that we have already unsubscribed */
        ast_assert(!stasis_subscription_is_subscribed(sub));
 
+       if (!stasis_subscription_change_type()) {
+               return;
+       }
+
        change = subscription_change_alloc(topic, sub->uniqueid, "Unsubscribe");
        if (!change) {
                return;
@@ -1066,6 +1204,10 @@ void ast_multi_object_blob_single_channel_publish(struct ast_channel *chan,
        RAII_VAR(struct ast_channel_snapshot *, channel_snapshot, NULL, ao2_cleanup);
        RAII_VAR(struct ast_multi_object_blob *, multi, NULL, ao2_cleanup);
 
+       if (!type) {
+               return;
+       }
+
        multi = ast_multi_object_blob_create(blob);
        if (!multi) {
                return;
@@ -1215,6 +1357,113 @@ static struct ast_manager_event_blob *multi_user_event_to_ami(
                ast_str_buffer(body));
 }
 
+/*! \brief A structure to hold global configuration-related options */
+struct stasis_declined_config {
+       /*! The list of message types to decline */
+       struct ao2_container *declined;
+};
+
+
+struct stasis_config {
+       struct stasis_declined_config *declined_message_types;
+};
+
+/*! \brief An aco_type structure to link the "declined_message_types" category to the stasis_declined_config type */
+static struct aco_type declined_option = {
+       .type = ACO_GLOBAL,
+       .name = "declined_message_types",
+       .item_offset = offsetof(struct stasis_config, declined_message_types),
+       .category_match = ACO_WHITELIST,
+       .category = "^declined_message_types$",
+};
+
+struct aco_type *declined_options[] = ACO_TYPES(&declined_option);
+
+struct aco_file stasis_conf = {
+        .filename = "stasis.conf",
+       .types = ACO_TYPES(&declined_option),
+};
+
+/*! \brief A global object container that will contain the stasis_config that gets swapped out on reloads */
+static AO2_GLOBAL_OBJ_STATIC(globals);
+
+static void *stasis_config_alloc(void);
+
+/*! \brief Register information about the configs being processed by this module */
+CONFIG_INFO_CORE("stasis", cfg_info, globals, stasis_config_alloc,
+        .files = ACO_FILES(&stasis_conf),
+);
+
+static void stasis_declined_config_destructor(void *obj)
+{
+       struct stasis_declined_config *declined = obj;
+       ao2_cleanup(declined->declined);
+}
+
+static void stasis_config_destructor(void *obj)
+{
+       struct stasis_config *cfg = obj;
+       ao2_cleanup(cfg->declined_message_types);
+}
+
+static void *stasis_config_alloc(void)
+{
+       struct stasis_config *cfg;
+
+       if (!(cfg = ao2_alloc(sizeof(*cfg), stasis_config_destructor))) {
+               return NULL;
+       }
+
+       /* Allocate/initialize memory */
+       cfg->declined_message_types = ao2_alloc(sizeof(*cfg->declined_message_types), stasis_declined_config_destructor);
+       if (!cfg->declined_message_types) {
+               goto error;
+       }
+
+       cfg->declined_message_types->declined = ast_str_container_alloc(13);
+       if (!cfg->declined_message_types->declined) {
+               goto error;
+       }
+
+       return cfg;
+error:
+       ao2_ref(cfg, -1);
+       return NULL;
+}
+
+int stasis_message_type_declined(const char *name)
+{
+       RAII_VAR(struct stasis_config *, cfg, ao2_global_obj_ref(globals), ao2_cleanup);
+       char *name_in_declined;
+       int res;
+
+       if (!cfg || !cfg->declined_message_types) {
+               return 0;
+       }
+
+       name_in_declined = ao2_find(cfg->declined_message_types->declined, name, OBJ_SEARCH_KEY);
+       res = name_in_declined ? 1 : 0;
+       ao2_cleanup(name_in_declined);
+       if (res) {
+               ast_log(LOG_NOTICE, "Declining to allocate Stasis message type '%s' due to configuration\n", name);
+       }
+       return res;
+}
+
+static int declined_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
+{
+       struct stasis_declined_config *declined = obj;
+
+       if (ast_strlen_zero(var->value)) {
+               return 0;
+       }
+
+       if (ast_str_container_add(declined->declined, var->value)) {
+               return -1;
+       }
+
+       return 0;
+}
 
 /*!
  * @{ \brief Define multi user event message type(s).
@@ -1232,6 +1481,8 @@ static void stasis_cleanup(void)
 {
        STASIS_MESSAGE_TYPE_CLEANUP(stasis_subscription_change_type);
        STASIS_MESSAGE_TYPE_CLEANUP(ast_multi_user_event_type);
+       aco_info_destroy(&cfg_info);
+       ao2_global_obj_release(globals);
 }
 
 int stasis_init(void)
@@ -1241,6 +1492,24 @@ int stasis_init(void)
        /* Be sure the types are cleaned up after the message bus */
        ast_register_cleanup(stasis_cleanup);
 
+       if (aco_info_init(&cfg_info)) {
+               return -1;
+       }
+
+       aco_option_register_custom(&cfg_info, "decline", ACO_EXACT, declined_options, "", declined_handler, 0);
+
+       if (aco_process_config(&cfg_info, 0) == ACO_PROCESS_ERROR) {
+               RAII_VAR(struct stasis_config *, stasis_cfg, stasis_config_alloc(), ao2_cleanup);
+
+               if (aco_set_defaults(&declined_option, "declined_message_types", stasis_cfg->declined_message_types)) {
+                       ast_log(LOG_ERROR, "Failed to load stasis.conf and failed to initialize defaults.\n");
+                       return -1;
+               }
+
+               ast_log(LOG_NOTICE, "Could not load stasis config; using defaults\n");
+               ao2_global_obj_replace_unref(globals, stasis_cfg);
+       }
+
        cache_init = stasis_cache_init();
        if (cache_init != 0) {
                return -1;
index c5df5f4f9300a98dd31ac7ec5eb62e4287759340..56f7605f7580c1ea2e62791a0ee1cbe8e63a589f 100644 (file)
@@ -267,6 +267,10 @@ void ast_bridge_publish_state(struct ast_bridge *bridge)
        RAII_VAR(struct ast_bridge_snapshot *, snapshot, NULL, ao2_cleanup);
        RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
 
+       if (!ast_bridge_snapshot_type()) {
+               return;
+       }
+
        ast_assert(bridge != NULL);
 
        snapshot = ast_bridge_snapshot_create(bridge);
@@ -358,6 +362,10 @@ void ast_bridge_publish_merge(struct ast_bridge *to, struct ast_bridge *from)
        RAII_VAR(struct ast_bridge_merge_message *, merge_msg, NULL, ao2_cleanup);
        RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
 
+       if (!ast_bridge_merge_message_type()) {
+               return;
+       }
+
        ast_assert(to != NULL);
        ast_assert(from != NULL);
 
@@ -394,6 +402,10 @@ struct stasis_message *ast_bridge_blob_create(
        RAII_VAR(struct ast_bridge_blob *, obj, NULL, ao2_cleanup);
        RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
 
+       if (!message_type) {
+               return NULL;
+       }
+
        obj = ao2_alloc(sizeof(*obj), bridge_blob_dtor);
        if (!obj) {
                return NULL;
@@ -958,6 +970,10 @@ void ast_bridge_publish_attended_transfer_fail(int is_external, enum ast_transfe
        RAII_VAR(struct ast_attended_transfer_message *, transfer_msg, NULL, ao2_cleanup);
        RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
 
+       if (!ast_attended_transfer_type()) {
+               return;
+       }
+
        transfer_msg = attended_transfer_message_create(is_external, result, transferee, target);
        if (!transfer_msg) {
                return;
@@ -980,6 +996,10 @@ void ast_bridge_publish_attended_transfer_bridge_merge(int is_external, enum ast
        RAII_VAR(struct ast_attended_transfer_message *, transfer_msg, NULL, ao2_cleanup);
        RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
 
+       if (!ast_attended_transfer_type()) {
+               return;
+       }
+
        transfer_msg = attended_transfer_message_create(is_external, result, transferee, target);
        if (!transfer_msg) {
                return;
@@ -1004,6 +1024,10 @@ void ast_bridge_publish_attended_transfer_threeway(int is_external, enum ast_tra
        RAII_VAR(struct ast_attended_transfer_message *, transfer_msg, NULL, ao2_cleanup);
        RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
 
+       if (!ast_attended_transfer_type()) {
+               return;
+       }
+
        transfer_msg = attended_transfer_message_create(is_external, result, transferee, target);
        if (!transfer_msg) {
                return;
@@ -1037,6 +1061,10 @@ void ast_bridge_publish_attended_transfer_app(int is_external, enum ast_transfer
        RAII_VAR(struct ast_attended_transfer_message *, transfer_msg, NULL, ao2_cleanup);
        RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
 
+       if (!ast_attended_transfer_type()) {
+               return;
+       }
+
        transfer_msg = attended_transfer_message_create(is_external, result, transferee, target);
        if (!transfer_msg) {
                return;
@@ -1061,6 +1089,10 @@ void ast_bridge_publish_attended_transfer_link(int is_external, enum ast_transfe
        RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
        int i;
 
+       if (!ast_attended_transfer_type()) {
+               return;
+       }
+
        transfer_msg = attended_transfer_message_create(is_external, result, transferee, target);
        if (!transfer_msg) {
                return;
index 8b4304e5f4f3f1a8b61627820c09e161750db198..c492307d63aef631cf15ca299b31e177f5fa0e39 100644 (file)
@@ -185,10 +185,13 @@ static struct stasis_cache_entry *cache_entry_create(struct stasis_message_type
        struct stasis_cache_entry *entry;
        int is_remote;
 
-       ast_assert(type != NULL);
        ast_assert(id != NULL);
        ast_assert(snapshot != NULL);
 
+       if (!type) {
+               return NULL;
+       }
+
        entry = ao2_alloc_options(sizeof(*entry), cache_entry_dtor,
                AO2_ALLOC_OPT_LOCK_NOLOCK);
        if (!entry) {
@@ -550,9 +553,12 @@ struct ao2_container *stasis_cache_get_all(struct stasis_cache *cache, struct st
 
        ast_assert(cache != NULL);
        ast_assert(cache->entries != NULL);
-       ast_assert(type != NULL);
        ast_assert(id != NULL);
 
+       if (!type) {
+               return NULL;
+       }
+
        found = ao2_container_alloc_list(AO2_ALLOC_OPT_LOCK_NOLOCK, 0, NULL, NULL);
        if (!found) {
                return NULL;
@@ -619,9 +625,12 @@ struct stasis_message *stasis_cache_get_by_eid(struct stasis_cache *cache, struc
 
        ast_assert(cache != NULL);
        ast_assert(cache->entries != NULL);
-       ast_assert(type != NULL);
        ast_assert(id != NULL);
 
+       if (!type) {
+               return NULL;
+       }
+
        ao2_rdlock(cache->entries);
 
        cached_entry = cache_find(cache->entries, type, id);
@@ -752,6 +761,10 @@ static struct stasis_message *update_create(struct stasis_message *old_snapshot,
 
        ast_assert(old_snapshot != NULL || new_snapshot != NULL);
 
+       if (!stasis_cache_update_type()) {
+               return NULL;
+       }
+
        update = ao2_alloc_options(sizeof(*update), stasis_cache_update_dtor,
                AO2_ALLOC_OPT_LOCK_NOLOCK);
        if (!update) {
index a1e7ad20949d638f8b40e51373aada48901990b5..d7fbc98ab94f7adf3fcc2a5c1b19b2b8d4210d0d 100644 (file)
@@ -304,6 +304,10 @@ void ast_channel_publish_dial_forward(struct ast_channel *caller, struct ast_cha
        RAII_VAR(struct ast_channel_snapshot *, peer_snapshot, NULL, ao2_cleanup);
        RAII_VAR(struct ast_channel_snapshot *, forwarded_snapshot, NULL, ao2_cleanup);
 
+       if (!ast_channel_dial_type()) {
+               return;
+       }
+
        ast_assert(peer != NULL);
        blob = ast_json_pack("{s: s, s: s, s: s}",
                             "dialstatus", S_OR(dialstatus, ""),
@@ -405,9 +409,15 @@ struct stasis_message *ast_channel_blob_create_from_cache(const char *channel_id
                                               struct ast_json *blob)
 {
        RAII_VAR(struct ast_channel_snapshot *, snapshot,
-                       ast_channel_snapshot_get_latest(channel_id),
+                       NULL,
                        ao2_cleanup);
 
+       if (!type) {
+               return NULL;
+       }
+
+       snapshot = ast_channel_snapshot_get_latest(channel_id);
+
        return create_channel_blob_message(snapshot, type, blob);
 }
 
@@ -416,6 +426,10 @@ struct stasis_message *ast_channel_blob_create(struct ast_channel *chan,
 {
        RAII_VAR(struct ast_channel_snapshot *, snapshot, NULL, ao2_cleanup);
 
+       if (!type) {
+               return NULL;
+       }
+
        if (chan) {
                snapshot = ast_channel_snapshot_create(chan);
        }
@@ -644,6 +658,10 @@ void ast_channel_publish_snapshot(struct ast_channel *chan)
        RAII_VAR(struct ast_channel_snapshot *, snapshot, NULL, ao2_cleanup);
        RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup);
 
+       if (!ast_channel_snapshot_type()) {
+               return;
+       }
+
        if (ast_test_flag(ast_channel_flags(chan), AST_FLAG_SNAPSHOT_STAGE)) {
                return;
        }
@@ -793,6 +811,10 @@ void ast_publish_channel_state(struct ast_channel *chan)
        RAII_VAR(struct ast_channel_snapshot *, snapshot, NULL, ao2_cleanup);
        RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup);
 
+       if (!ast_channel_snapshot_type()) {
+               return;
+       }
+
        ast_assert(chan != NULL);
        if (!chan) {
                return;
index e3f5a3f15e57b8ade9ecb921f57ed7300951c6cb..73746817725cdbd19911dd0ffadb05b94d1710cc 100644 (file)
@@ -150,6 +150,9 @@ struct stasis_message *ast_endpoint_blob_create(struct ast_endpoint *endpoint,
        RAII_VAR(struct ast_endpoint_blob *, obj, NULL, ao2_cleanup);
        RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
 
+       if (!type) {
+               return NULL;
+       }
        if (!blob) {
                blob = ast_json_null();
        }
index 70c4085390cfa49b347e7a9ddcf4aaafb3802d1d..c797cdfa0509e6cf6c2b1201d695e2f8124cc502 100644 (file)
@@ -50,14 +50,20 @@ static void message_type_dtor(void *obj)
        type->name = NULL;
 }
 
-struct stasis_message_type *stasis_message_type_create(const char *name,
-       struct stasis_message_vtable *vtable)
+int stasis_message_type_create(const char *name,
+       struct stasis_message_vtable *vtable,
+       struct stasis_message_type **result)
 {
        struct stasis_message_type *type;
 
+       /* Check for declination */
+       if (name && stasis_message_type_declined(name)) {
+               return STASIS_MESSAGE_TYPE_DECLINED;
+       }
+
        type = ao2_t_alloc(sizeof(*type), message_type_dtor, name);
        if (!type) {
-               return NULL;
+               return STASIS_MESSAGE_TYPE_ERROR;
        }
        if (!vtable) {
                /* Null object pattern, FTW! */
@@ -67,11 +73,12 @@ struct stasis_message_type *stasis_message_type_create(const char *name,
        type->name = ast_strdup(name);
        if (!type->name) {
                ao2_cleanup(type);
-               return NULL;
+               return STASIS_MESSAGE_TYPE_ERROR;
        }
        type->vtable = vtable;
+       *result = type;
 
-       return type;
+       return STASIS_MESSAGE_TYPE_SUCCESS;
 }
 
 const char *stasis_message_type_name(const struct stasis_message_type *type)
index 2428a96c0767f37b53685dd93d933d6bfd67b0ec..e232b8e8a3d1cb4d53dad18da0ecde808c730ab0 100644 (file)
@@ -122,6 +122,10 @@ void ast_system_publish_registry(const char *channeltype, const char *username,
        RAII_VAR(struct ast_json_payload *, payload, NULL, ao2_cleanup);
        RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup);
 
+       if (!ast_system_registry_type()) {
+               return;
+       }
+
        registry = ast_json_pack("{s: s, s: s, s: s, s: s, s: s, s: s}",
                "type", "registry",
                "channeltype", channeltype,
index fe8fe153205ed30b07f732ac4157cb2a54f227e4..c144d3eb405242ab0dc0d5bfe57569c78b393959 100644 (file)
@@ -1015,15 +1015,22 @@ struct ast_json *ast_test_suite_get_blob(struct ast_test_suite_message_payload *
 void __ast_test_suite_event_notify(const char *file, const char *func, int line, const char *state, const char *fmt, ...)
 {
        RAII_VAR(struct ast_test_suite_message_payload *, payload,
-                       ao2_alloc(sizeof(*payload), test_suite_message_payload_dtor),
+                       NULL,
                        ao2_cleanup);
        RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
-       RAII_VAR(struct ast_str *, buf, ast_str_create(128), ast_free);
+       RAII_VAR(struct ast_str *, buf, NULL, ast_free);
        va_list ap;
 
+       if (!ast_test_suite_message_type()) {
+               return;
+       }
+
+       buf = ast_str_create(128);
        if (!buf) {
                return;
        }
+
+       payload = ao2_alloc(sizeof(*payload), test_suite_message_payload_dtor);
        if (!payload) {
                return;
        }
index 641e30d95efd1a8ddd6c9832012ea1dd2c65c7f4..de62851e0feed250b3d945573827b0651343dea6 100644 (file)
@@ -333,9 +333,11 @@ static int realtime_exec(struct ast_channel *chan, const char *context, const ch
                                                 term_color(tmp1, app, COLOR_BRCYAN, 0, sizeof(tmp1)),
                                                 term_color(tmp2, ast_channel_name(chan), COLOR_BRMAGENTA, 0, sizeof(tmp2)),
                                                 term_color(tmp3, S_OR(appdata, ""), COLOR_BRMAGENTA, 0, sizeof(tmp3)));
-                               ast_channel_lock(chan);
-                               snapshot = ast_channel_snapshot_create(chan);
-                               ast_channel_unlock(chan);
+                               if (ast_channel_snapshot_type()) {
+                                       ast_channel_lock(chan);
+                                       snapshot = ast_channel_snapshot_create(chan);
+                                       ast_channel_unlock(chan);
+                               }
                                if (snapshot) {
                                        /* pbx_exec sets application name and data, but we don't want to log
                                         * every exec. Just update the snapshot here instead.
index 20f8c4e1c80ad89d66fb58ebe7c48f69f701f86a..73b5ff49546fbacef04d1db6ba6696547d9fe99e 100644 (file)
@@ -579,6 +579,10 @@ void publish_parked_call_failure(struct ast_channel *parkee)
        RAII_VAR(struct ast_parked_call_payload *, payload, NULL, ao2_cleanup);
        RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
 
+       if (!ast_parked_call_type()) {
+               return;
+       }
+
        payload = parked_call_payload_from_failure(parkee);
        if (!payload) {
                return;
@@ -597,6 +601,10 @@ void publish_parked_call(struct parked_user *pu, enum ast_parked_call_event_type
        RAII_VAR(struct ast_parked_call_payload *, payload, NULL, ao2_cleanup);
        RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
 
+       if (!ast_parked_call_type()) {
+               return;
+       }
+
        payload = parked_call_payload_from_parked_user(pu, event_type);
        if (!payload) {
                return;
index 1df9ed841165835993ffbbea630277e1d5f93458..58290c7ccf3d00cbe2ec11b79c9c9f9692a1376b 100644 (file)
@@ -117,6 +117,10 @@ static void publish_corosync_ping_to_stasis(struct ast_event *event)
        ast_assert(ast_event_get_type(event) == AST_EVENT_PING);
        ast_assert(event != NULL);
 
+       if (!corosync_ping_message_type()) {
+               return;
+       }
+
        payload = ao2_t_alloc(sizeof(*payload), corosync_ping_payload_dtor, "Create ping payload");
        if (!payload) {
                return;
index 7d5373153f2edef6662d94ac48d856a0f83cae16..7b5d16f1abd789683aa85539a84511314a313c5a 100644 (file)
@@ -1357,6 +1357,10 @@ enum stasis_app_user_event_res stasis_app_user_event(const char *app_name,
                return STASIS_APP_USER_APP_NOT_FOUND;
        }
 
+       if (!ast_multi_user_event_type()) {
+               return res;
+       }
+
        blob = json_variables;
        if (!blob) {
                blob = ast_json_pack("{}");
index af31046fca25f9231c51c6d922ab1f923418f4ad..72f8519230670ecee4abba5b2fe466ea5db2e9cd 100644 (file)
@@ -111,9 +111,10 @@ static void publish_chanspy_message(struct stasis_app_snoop *snoop, int start)
        RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup);
        RAII_VAR(struct ast_channel_snapshot *, snoop_snapshot, NULL, ao2_cleanup);
        RAII_VAR(struct ast_channel_snapshot *, spyee_snapshot, NULL, ao2_cleanup);
+       struct stasis_message_type *type = start ? ast_channel_chanspy_start_type(): ast_channel_chanspy_stop_type();
 
        blob = ast_json_null();
-       if (!blob) {
+       if (!blob || !type) {
                return;
        }
 
@@ -133,9 +134,7 @@ static void publish_chanspy_message(struct stasis_app_snoop *snoop, int start)
                ast_multi_channel_blob_add_channel(payload, "spyee_channel", spyee_snapshot);
        }
 
-       message = stasis_message_create(
-                       start ? ast_channel_chanspy_start_type(): ast_channel_chanspy_stop_type(),
-                                       payload);
+       message = stasis_message_create(type, payload);
        if (!message) {
                return;
        }
index cec8e20c639bfcf30c0b6bf28bfed3aff3d1720f..9860b0ebd7f39dc2319628cacb0ea4d653becc6c 100644 (file)
@@ -251,6 +251,10 @@ struct stasis_message *stasis_test_message_create(void)
 {
        RAII_VAR(void *, data, NULL, ao2_cleanup);
 
+       if (!stasis_test_message_type()) {
+               return NULL;
+       }
+
        /* We just need the unique pointer; don't care what's in it */
        data = ao2_alloc(1, NULL);
        if (!data) {
index 1bda4b9ff9ff657de077e1b5f29400ee4d54c1d8..4cdc2fdca79292f4ca2e926649a39bc57b2c4829 100644 (file)
@@ -157,10 +157,15 @@ static int stun_monitor_request(const void *blarg)
                        if (args.external_addr_known) {
                                RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
                                RAII_VAR(struct ast_json_payload *, json_payload, NULL, ao2_cleanup);
-                               RAII_VAR(struct ast_json *, json_object, ast_json_object_create(), ast_json_unref);
+                               RAII_VAR(struct ast_json *, json_object, NULL, ast_json_unref);
+
+                               if (!ast_network_change_type()) {
+                                       goto publish_failure;
+                               }
 
                                /* This json_object doesn't actually contain anything yet. We have to reference something
                                 * for stasis, and this is useful for if we want to ever add data for any reason. */
+                               json_object = ast_json_object_create();
                                if (!json_object) {
                                        goto publish_failure;
                                }
index 4c042c05be47df4cf0064fb03498910a14a2f80b..ba82e83adb06aa625d949bbb9834071d252f8ceb 100644 (file)
@@ -84,8 +84,8 @@ AST_TEST_DEFINE(message_type)
                break;
        }
 
-       ast_test_validate(test, NULL == stasis_message_type_create(NULL, NULL));
-       uut = stasis_message_type_create("SomeMessage", NULL);
+       ast_test_validate(test, stasis_message_type_create(NULL, NULL, NULL) == STASIS_MESSAGE_TYPE_ERROR);
+       ast_test_validate(test, stasis_message_type_create("SomeMessage", NULL, &uut) == STASIS_MESSAGE_TYPE_SUCCESS);
        ast_test_validate(test, 0 == strcmp(stasis_message_type_name(uut), "SomeMessage"));
 
        return AST_TEST_PASS;
@@ -116,7 +116,7 @@ AST_TEST_DEFINE(message)
 
        memset(&foreign_eid, 0xFF, sizeof(foreign_eid));
 
-       type = stasis_message_type_create("SomeMessage", NULL);
+       ast_test_validate(test, stasis_message_type_create("SomeMessage", NULL, &type) == STASIS_MESSAGE_TYPE_SUCCESS);
 
        ast_test_validate(test, NULL == stasis_message_create_full(NULL, NULL, NULL));
        ast_test_validate(test, NULL == stasis_message_create_full(type, NULL, NULL));
@@ -395,7 +395,7 @@ AST_TEST_DEFINE(publish)
 
        test_data = ao2_alloc(1, NULL);
        ast_test_validate(test, NULL != test_data);
-       test_message_type = stasis_message_type_create("TestMessage", NULL);
+       ast_test_validate(test, stasis_message_type_create("TestMessage", NULL, &test_message_type) == STASIS_MESSAGE_TYPE_SUCCESS);
        test_message = stasis_message_create(test_message_type, test_data);
 
        stasis_publish(topic, test_message);
@@ -442,7 +442,7 @@ AST_TEST_DEFINE(publish_sync)
 
        test_data = ao2_alloc(1, NULL);
        ast_test_validate(test, NULL != test_data);
-       test_message_type = stasis_message_type_create("TestMessage", NULL);
+       ast_test_validate(test, stasis_message_type_create("TestMessage", NULL, &test_message_type) == STASIS_MESSAGE_TYPE_SUCCESS);
        test_message = stasis_message_create(test_message_type, test_data);
 
        stasis_publish_sync(uut, test_message);
@@ -490,7 +490,7 @@ AST_TEST_DEFINE(unsubscribe_stops_messages)
 
        test_data = ao2_alloc(1, NULL);
        ast_test_validate(test, NULL != test_data);
-       test_message_type = stasis_message_type_create("TestMessage", NULL);
+       ast_test_validate(test, stasis_message_type_create("TestMessage", NULL, &test_message_type) == STASIS_MESSAGE_TYPE_SUCCESS);
        test_message = stasis_message_create(test_message_type, test_data);
 
        stasis_publish(topic, test_message);
@@ -554,7 +554,7 @@ AST_TEST_DEFINE(forward)
 
        test_data = ao2_alloc(1, NULL);
        ast_test_validate(test, NULL != test_data);
-       test_message_type = stasis_message_type_create("TestMessage", NULL);
+       ast_test_validate(test, stasis_message_type_create("TestMessage", NULL, &test_message_type) == STASIS_MESSAGE_TYPE_SUCCESS);
        test_message = stasis_message_create(test_message_type, test_data);
 
        stasis_publish(topic, test_message);
@@ -604,7 +604,7 @@ AST_TEST_DEFINE(interleaving)
                break;
        }
 
-       test_message_type = stasis_message_type_create("test", NULL);
+       ast_test_validate(test, stasis_message_type_create("test", NULL, &test_message_type) == STASIS_MESSAGE_TYPE_SUCCESS);
        ast_test_validate(test, NULL != test_message_type);
 
        test_data = ao2_alloc(1, NULL);
@@ -796,7 +796,7 @@ AST_TEST_DEFINE(cache_filter)
                break;
        }
 
-       non_cache_type = stasis_message_type_create("NonCacheable", NULL);
+       ast_test_validate(test, stasis_message_type_create("NonCacheable", NULL, &non_cache_type) == STASIS_MESSAGE_TYPE_SUCCESS);
        ast_test_validate(test, NULL != non_cache_type);
        topic = stasis_topic_create("SomeTopic");
        ast_test_validate(test, NULL != topic);
@@ -847,7 +847,7 @@ AST_TEST_DEFINE(cache)
                break;
        }
 
-       cache_type = stasis_message_type_create("Cacheable", NULL);
+       ast_test_validate(test, stasis_message_type_create("Cacheable", NULL, &cache_type) == STASIS_MESSAGE_TYPE_SUCCESS);
        ast_test_validate(test, NULL != cache_type);
        topic = stasis_topic_create("SomeTopic");
        ast_test_validate(test, NULL != topic);
@@ -948,7 +948,7 @@ AST_TEST_DEFINE(cache_dump)
                break;
        }
 
-       cache_type = stasis_message_type_create("Cacheable", NULL);
+       ast_test_validate(test, stasis_message_type_create("Cacheable", NULL, &cache_type) == STASIS_MESSAGE_TYPE_SUCCESS);
        ast_test_validate(test, NULL != cache_type);
        topic = stasis_topic_create("SomeTopic");
        ast_test_validate(test, NULL != topic);
@@ -1071,7 +1071,7 @@ AST_TEST_DEFINE(cache_eid_aggregate)
        memset(&foreign_eid1, 0xAA, sizeof(foreign_eid1));
        memset(&foreign_eid2, 0xBB, sizeof(foreign_eid2));
 
-       cache_type = stasis_message_type_create("Cacheable", NULL);
+       ast_test_validate(test, stasis_message_type_create("Cacheable", NULL, &cache_type) == STASIS_MESSAGE_TYPE_SUCCESS);
        ast_test_validate(test, NULL != cache_type);
 
        topic = stasis_topic_create("SomeTopic");
@@ -1331,11 +1331,11 @@ AST_TEST_DEFINE(router)
        consumer3 = consumer_create(1);
        ast_test_validate(test, NULL != consumer3);
 
-       test_message_type1 = stasis_message_type_create("TestMessage1", NULL);
+       ast_test_validate(test, stasis_message_type_create("TestMessage1", NULL, &test_message_type1) == STASIS_MESSAGE_TYPE_SUCCESS);
        ast_test_validate(test, NULL != test_message_type1);
-       test_message_type2 = stasis_message_type_create("TestMessage2", NULL);
+       ast_test_validate(test, stasis_message_type_create("TestMessage2", NULL, &test_message_type2) == STASIS_MESSAGE_TYPE_SUCCESS);
        ast_test_validate(test, NULL != test_message_type2);
-       test_message_type3 = stasis_message_type_create("TestMessage3", NULL);
+       ast_test_validate(test, stasis_message_type_create("TestMessage3", NULL, &test_message_type3) == STASIS_MESSAGE_TYPE_SUCCESS);
        ast_test_validate(test, NULL != test_message_type3);
 
        uut = stasis_message_router_create(topic);
@@ -1448,11 +1448,11 @@ AST_TEST_DEFINE(router_cache_updates)
        consumer3 = consumer_create(1);
        ast_test_validate(test, NULL != consumer3);
 
-       test_message_type1 = stasis_message_type_create("Cache1", NULL);
+       ast_test_validate(test, stasis_message_type_create("Cache1", NULL, &test_message_type1) == STASIS_MESSAGE_TYPE_SUCCESS);
        ast_test_validate(test, NULL != test_message_type1);
-       test_message_type2 = stasis_message_type_create("Cache2", NULL);
+       ast_test_validate(test, stasis_message_type_create("Cache2", NULL, &test_message_type2) == STASIS_MESSAGE_TYPE_SUCCESS);
        ast_test_validate(test, NULL != test_message_type2);
-       test_message_type3 = stasis_message_type_create("NonCache", NULL);
+       ast_test_validate(test, stasis_message_type_create("NonCache", NULL, &test_message_type3) == STASIS_MESSAGE_TYPE_SUCCESS);
        ast_test_validate(test, NULL != test_message_type3);
 
        uut = stasis_message_router_create(
@@ -1535,7 +1535,7 @@ AST_TEST_DEFINE(no_to_json)
        ast_test_validate(test, NULL == actual);
 
        /* Test message with NULL to_json function */
-       type = stasis_message_type_create("SomeMessage", NULL);
+       ast_test_validate(test, stasis_message_type_create("SomeMessage", NULL, &type) == STASIS_MESSAGE_TYPE_SUCCESS);
 
        data = ao2_alloc(strlen(expected) + 1, NULL);
        strcpy(data, expected);
@@ -1568,7 +1568,7 @@ AST_TEST_DEFINE(to_json)
                break;
        }
 
-       type = stasis_message_type_create("SomeMessage", &fake_vtable);
+       ast_test_validate(test, stasis_message_type_create("SomeMessage", &fake_vtable, &type) == STASIS_MESSAGE_TYPE_SUCCESS);
 
        data = ao2_alloc(strlen(expected_text) + 1, NULL);
        strcpy(data, expected_text);
@@ -1606,7 +1606,7 @@ AST_TEST_DEFINE(no_to_ami)
        ast_test_validate(test, NULL == actual);
 
        /* Test message with NULL to_ami function */
-       type = stasis_message_type_create("SomeMessage", NULL);
+       ast_test_validate(test, stasis_message_type_create("SomeMessage", NULL, &type) == STASIS_MESSAGE_TYPE_SUCCESS);
 
        data = ao2_alloc(strlen(expected) + 1, NULL);
        strcpy(data, expected);
@@ -1639,7 +1639,7 @@ AST_TEST_DEFINE(to_ami)
                break;
        }
 
-       type = stasis_message_type_create("SomeMessage", &fake_vtable);
+       ast_test_validate(test, stasis_message_type_create("SomeMessage", &fake_vtable, &type) == STASIS_MESSAGE_TYPE_SUCCESS);
 
        data = ao2_alloc(strlen(expected_text) + 1, NULL);
        strcpy(data, expected_text);
index 89240130ce8a8bbc528467ad3ce67d20e0961a58..4c4bc665e202e64b16426aef9e51cfdc88323b88 100644 (file)
@@ -71,7 +71,7 @@ AST_TEST_DEFINE(channel_blob_create)
                break;
        }
 
-       type = stasis_message_type_create("test-type", NULL);
+       ast_test_validate(test, stasis_message_type_create("test-type", NULL, &type) == STASIS_MESSAGE_TYPE_SUCCESS);
        chan = ast_channel_alloc(0, AST_STATE_DOWN, "100", "Alice", "100", "100", "default", NULL, NULL, 0, "TEST/Alice");
        ast_channel_unlock(chan);
        json = ast_json_pack("{s: s}",
@@ -126,7 +126,7 @@ AST_TEST_DEFINE(null_blob)
                break;
        }
 
-       type = stasis_message_type_create("test-type", NULL);
+       ast_test_validate(test, stasis_message_type_create("test-type", NULL, &type) == STASIS_MESSAGE_TYPE_SUCCESS);
        chan = ast_channel_alloc(0, AST_STATE_DOWN, "100", "Alice", "100", "100", "default", NULL, NULL, 0, "TEST/Alice");
        ast_channel_unlock(chan);
        json = ast_json_pack("{s: s}",