summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/app_chanspy.c7
-rw-r--r--apps/app_forkcdr.c9
-rw-r--r--apps/app_queue.c6
-rw-r--r--configs/samples/stasis.conf.sample122
-rw-r--r--funcs/func_cdr.c27
-rw-r--r--include/asterisk/stasis.h35
-rw-r--r--main/app.c8
-rw-r--r--main/bridge.c4
-rw-r--r--main/ccss.c7
-rw-r--r--main/cdr.c21
-rw-r--r--main/channel.c5
-rw-r--r--main/core_local.c12
-rw-r--r--main/devicestate.c8
-rw-r--r--main/endpoints.c9
-rw-r--r--main/file.c4
-rw-r--r--main/loader.c4
-rw-r--r--main/manager.c2
-rw-r--r--main/named_acl.c2
-rw-r--r--main/pickup.c4
-rw-r--r--main/presencestate.c7
-rw-r--r--main/rtp_engine.c4
-rw-r--r--main/security_events.c5
-rw-r--r--main/stasis.c269
-rw-r--r--main/stasis_bridges.c32
-rw-r--r--main/stasis_cache.c19
-rw-r--r--main/stasis_channels.c24
-rw-r--r--main/stasis_endpoints.c3
-rw-r--r--main/stasis_message.c17
-rw-r--r--main/stasis_system.c4
-rw-r--r--main/test.c11
-rw-r--r--pbx/pbx_realtime.c8
-rw-r--r--res/parking/parking_manager.c8
-rw-r--r--res/res_corosync.c4
-rw-r--r--res/res_stasis.c4
-rw-r--r--res/res_stasis_snoop.c7
-rw-r--r--res/res_stasis_test.c4
-rw-r--r--res/res_stun_monitor.c7
-rw-r--r--tests/test_stasis.c44
-rw-r--r--tests/test_stasis_channels.c4
39 files changed, 708 insertions, 73 deletions
diff --git a/apps/app_chanspy.c b/apps/app_chanspy.c
index af69be303..5806b997d 100644
--- a/apps/app_chanspy.c
+++ b/apps/app_chanspy.c
@@ -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;
}
diff --git a/apps/app_forkcdr.c b/apps/app_forkcdr.c
index 932e862e1..bbd15881a 100644
--- a/apps/app_forkcdr.c
+++ b/apps/app_forkcdr.c
@@ -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;
}
diff --git a/apps/app_queue.c b/apps/app_queue.c
index b0c81df38..012f04a71 100644
--- a/apps/app_queue.c
+++ b/apps/app_queue.c
@@ -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
index 000000000..3aac230cb
--- /dev/null
+++ b/configs/samples/stasis.conf.sample
@@ -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
diff --git a/funcs/func_cdr.c b/funcs/func_cdr.c
index 44ecf4d6b..c9fce23d2 100644
--- a/funcs/func_cdr.c
+++ b/funcs/func_cdr.c
@@ -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;
}
diff --git a/include/asterisk/stasis.h b/include/asterisk/stasis.h
index 4c4052c14..b8dc4c845 100644
--- a/include/asterisk/stasis.h
+++ b/include/asterisk/stasis.h
@@ -274,6 +274,15 @@ struct stasis_message_vtable {
};
/*!
+ * \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.
*
* \ref stasis_message_type is an AO2 object, so ao2_cleanup() when you're done
@@ -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
@@ -298,6 +310,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.
*
* This message is an \c ao2 object, and must be ao2_cleanup()'ed when you are done
@@ -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; \
})
/*!
diff --git a/main/app.c b/main/app.c
index fa7c3ece1..89889c65f 100644
--- a/main/app.c
+++ b/main/app.c
@@ -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;
diff --git a/main/bridge.c b/main/bridge.c
index 63086e16e..462676ca8 100644
--- a/main/bridge.c
+++ b/main/bridge.c
@@ -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);
diff --git a/main/ccss.c b/main/ccss.c
index 9fcabfefd..3626f3d38 100644
--- a/main/ccss.c
+++ b/main/ccss.c
@@ -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);
diff --git a/main/cdr.c b/main/cdr.c
index 17fa8a25f..2aaef8862 100644
--- a/main/cdr.c
+++ b/main/cdr.c
@@ -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)) {
diff --git a/main/channel.c b/main/channel.c
index 6a252a699..23799d9be 100644
--- a/main/channel.c
+++ b/main/channel.c
@@ -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);
diff --git a/main/core_local.c b/main/core_local.c
index e1b66d0a7..54915ecfe 100644
--- a/main/core_local.c
+++ b/main/core_local.c
@@ -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}",
diff --git a/main/devicestate.c b/main/devicestate.c
index c4a57dd68..7f9136da3 100644
--- a/main/devicestate.c
+++ b/main/devicestate.c
@@ -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);
diff --git a/main/endpoints.c b/main/endpoints.c
index 07687eecc..cc2eccc70 100644
--- a/main/endpoints.c
+++ b/main/endpoints.c
@@ -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;
diff --git a/main/file.c b/main/file.c
index fa4c63bd9..59d39df8f 100644
--- a/main/file.c
+++ b/main/file.c
@@ -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, "|"));
diff --git a/main/loader.c b/main/loader.c
index b4eef13c2..ac17ddc9e 100644
--- a/main/loader.c
+++ b/main/loader.c
@@ -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"),
diff --git a/main/manager.c b/main/manager.c
index 7fa083ca9..b4e927ffb 100644
--- a/main/manager.c
+++ b/main/manager.c
@@ -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;
}
diff --git a/main/named_acl.c b/main/named_acl.c
index f0b5c2894..deda260b7 100644
--- a/main/named_acl.c
+++ b/main/named_acl.c
@@ -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;
}
diff --git a/main/pickup.c b/main/pickup.c
index 5be0c03ab..125ec9359 100644
--- a/main/pickup.c
+++ b/main/pickup.c
@@ -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;
}
diff --git a/main/presencestate.c b/main/presencestate.c
index db947df34..07df7429d 100644
--- a/main/presencestate.c
+++ b/main/presencestate.c
@@ -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;
}
diff --git a/main/rtp_engine.c b/main/rtp_engine.c
index 52be8b90e..0c624ab61 100644
--- a/main/rtp_engine.c
+++ b/main/rtp_engine.c
@@ -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;
diff --git a/main/security_events.c b/main/security_events.c
index f4dc6fc6d..00a70fbec 100644
--- a/main/security_events.c
+++ b/main/security_events.c
@@ -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;
}
diff --git a/main/stasis.c b/main/stasis.c
index 594ec5e99..d8e0e5afc 100644
--- a/main/stasis.c
+++ b/main/stasis.c
@@ -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;
diff --git a/main/stasis_bridges.c b/main/stasis_bridges.c
index c5df5f4f9..56f7605f7 100644
--- a/main/stasis_bridges.c
+++ b/main/stasis_bridges.c
@@ -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;
diff --git a/main/stasis_cache.c b/main/stasis_cache.c
index 8b4304e5f..c492307d6 100644
--- a/main/stasis_cache.c
+++ b/main/stasis_cache.c
@@ -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) {
diff --git a/main/stasis_channels.c b/main/stasis_channels.c
index a1e7ad209..d7fbc98ab 100644
--- a/main/stasis_channels.c
+++ b/main/stasis_channels.c
@@ -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;
diff --git a/main/stasis_endpoints.c b/main/stasis_endpoints.c
index e3f5a3f15..737468177 100644
--- a/main/stasis_endpoints.c
+++ b/main/stasis_endpoints.c
@@ -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();
}
diff --git a/main/stasis_message.c b/main/stasis_message.c
index 70c408539..c797cdfa0 100644
--- a/main/stasis_message.c
+++ b/main/stasis_message.c
@@ -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)
diff --git a/main/stasis_system.c b/main/stasis_system.c
index 2428a96c0..e232b8e8a 100644
--- a/main/stasis_system.c
+++ b/main/stasis_system.c
@@ -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,
diff --git a/main/test.c b/main/test.c
index fe8fe1532..c144d3eb4 100644
--- a/main/test.c
+++ b/main/test.c
@@ -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;
}
diff --git a/pbx/pbx_realtime.c b/pbx/pbx_realtime.c
index 641e30d95..de62851e0 100644
--- a/pbx/pbx_realtime.c
+++ b/pbx/pbx_realtime.c
@@ -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.
diff --git a/res/parking/parking_manager.c b/res/parking/parking_manager.c
index 20f8c4e1c..73b5ff495 100644
--- a/res/parking/parking_manager.c
+++ b/res/parking/parking_manager.c
@@ -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;
diff --git a/res/res_corosync.c b/res/res_corosync.c
index 1df9ed841..58290c7cc 100644
--- a/res/res_corosync.c
+++ b/res/res_corosync.c
@@ -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;
diff --git a/res/res_stasis.c b/res/res_stasis.c
index 7d5373153..7b5d16f1a 100644
--- a/res/res_stasis.c
+++ b/res/res_stasis.c
@@ -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("{}");
diff --git a/res/res_stasis_snoop.c b/res/res_stasis_snoop.c
index af31046fc..72f851923 100644
--- a/res/res_stasis_snoop.c
+++ b/res/res_stasis_snoop.c
@@ -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;
}
diff --git a/res/res_stasis_test.c b/res/res_stasis_test.c
index cec8e20c6..9860b0ebd 100644
--- a/res/res_stasis_test.c
+++ b/res/res_stasis_test.c
@@ -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) {
diff --git a/res/res_stun_monitor.c b/res/res_stun_monitor.c
index 1bda4b9ff..4cdc2fdca 100644
--- a/res/res_stun_monitor.c
+++ b/res/res_stun_monitor.c
@@ -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;
}
diff --git a/tests/test_stasis.c b/tests/test_stasis.c
index 4c042c05b..ba82e83ad 100644
--- a/tests/test_stasis.c
+++ b/tests/test_stasis.c
@@ -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);
diff --git a/tests/test_stasis_channels.c b/tests/test_stasis_channels.c
index 89240130c..4c4bc665e 100644
--- a/tests/test_stasis_channels.c
+++ b/tests/test_stasis_channels.c
@@ -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}",