summaryrefslogtreecommitdiff
path: root/main
diff options
context:
space:
mode:
Diffstat (limited to 'main')
-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
24 files changed, 461 insertions, 24 deletions
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;
}