diff options
-rw-r--r-- | CHANGES | 13 | ||||
-rw-r--r-- | apps/app_dial.c | 18 | ||||
-rw-r--r-- | apps/app_queue.c | 20 | ||||
-rw-r--r-- | apps/app_voicemail.c | 45 | ||||
-rw-r--r-- | include/asterisk.h | 20 | ||||
-rw-r--r-- | include/asterisk/app.h | 2 | ||||
-rw-r--r-- | include/asterisk/module.h | 2 | ||||
-rw-r--r-- | include/asterisk/stasis_cache_pattern.h | 21 | ||||
-rw-r--r-- | main/app.c | 4 | ||||
-rw-r--r-- | main/endpoints.c | 12 | ||||
-rw-r--r-- | main/pbx_builtins.c | 2 | ||||
-rw-r--r-- | main/pbx_functions.c | 2 | ||||
-rw-r--r-- | main/stasis_cache_pattern.c | 21 | ||||
-rw-r--r-- | res/res_mwi_external.c | 13 |
14 files changed, 134 insertions, 61 deletions
@@ -33,6 +33,19 @@ res_pjsip_history information on filtering, view the current CLI help for the 'pjsip show history' command. +Voicemail +------------------ + * app_voicemail and res_mwi_external can now be built together. The default + remains to build app_voicemail and not res_mwi_external but if they are + both built, the load order will cause res_mwi_external to load first and + app_voicemail will be skipped. Use 'preload=app_voicemail.so' in + modules.conf to force app_voicemail to be the voicemail provider. + +Queue +------------------- + * Added field ReasonPause on QueueMemberStatus if set when paused, the reason + the queue member was paused. + ------------------------------------------------------------------------------ --- Functionality changes from Asterisk 13.6.0 to Asterisk 13.7.0 ------------ ------------------------------------------------------------------------------ diff --git a/apps/app_dial.c b/apps/app_dial.c index d65dcae0a..bc4f8a574 100644 --- a/apps/app_dial.c +++ b/apps/app_dial.c @@ -2151,6 +2151,24 @@ static int dial_exec_full(struct ast_channel *chan, const char *data, struct ast return -1; } + if (ast_check_hangup_locked(chan)) { + /* + * Caller hung up before we could dial. If dial is executed + * within an AGI then the AGI has likely eaten all queued + * frames before executing the dial in DeadAGI mode. With + * the caller hung up and no pending frames from the caller's + * read queue, dial would not know that the call has hung up + * until a called channel answers. It is rather annoying to + * whoever just answered the non-existent call. + * + * Dial should not continue execution in DeadAGI mode, hangup + * handlers, or the h exten. + */ + ast_verb(3, "Caller hung up before dial.\n"); + pbx_builtin_setvar_helper(chan, "DIALSTATUS", "CANCEL"); + return -1; + } + parse = ast_strdupa(data); AST_STANDARD_APP_ARGS(args, parse); diff --git a/apps/app_queue.c b/apps/app_queue.c index 45d00939c..c2450765c 100644 --- a/apps/app_queue.c +++ b/apps/app_queue.c @@ -1002,6 +1002,9 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") <enum name="1"/> </enumlist> </parameter> + <parameter name="PausedReason"> + <para>If set when paused, the reason the queue member was paused.</para> + </parameter> <parameter name="Ringinuse"> <enumlist> <enum name="0"/> @@ -1493,6 +1496,7 @@ struct member { int realtime; /*!< Is this member realtime? */ int status; /*!< Status of queue member */ int paused; /*!< Are we paused (not accepting calls)? */ + char reason_paused[80]; /*!< Reason of paused if member is paused */ int queuepos; /*!< In what order (pertains to certain strategies) should this member be called? */ time_t lastcall; /*!< When last successful call was hungup */ struct call_queue *lastqueue; /*!< Last queue we received a call */ @@ -2155,7 +2159,7 @@ static void queue_publish_member_blob(struct stasis_message_type *type, struct a static struct ast_json *queue_member_blob_create(struct call_queue *q, struct member *mem) { - return ast_json_pack("{s: s, s: s, s: s, s: s, s: s, s: i, s: i, s: i, s: i, s: i, s: i}", + return ast_json_pack("{s: s, s: s, s: s, s: s, s: s, s: i, s: i, s: i, s: i, s: i, s: s, s: i}", "Queue", q->name, "MemberName", mem->membername, "Interface", mem->interface, @@ -2166,6 +2170,7 @@ static struct ast_json *queue_member_blob_create(struct call_queue *q, struct me "LastCall", (int)mem->lastcall, "Status", mem->status, "Paused", mem->paused, + "PausedReason", mem->reason_paused, "Ringinuse", mem->ringinuse); } @@ -7055,6 +7060,14 @@ static void set_queue_member_pause(struct call_queue *q, struct member *mem, con } mem->paused = paused; + if (paused) { + if (!ast_strlen_zero(reason)) { + ast_copy_string(mem->reason_paused, reason, sizeof(mem->reason_paused)); + } + } else { + ast_copy_string(mem->reason_paused, "", sizeof(mem->reason_paused)); + } + ast_devstate_changed(mem->paused ? QUEUE_PAUSED_DEVSTATE : QUEUE_UNPAUSED_DEVSTATE, AST_DEVSTATE_CACHABLE, "Queue:%s_pause_%s", q->name, mem->interface); @@ -9513,10 +9526,11 @@ static int manager_queues_status(struct mansession *s, const struct message *m) "LastCall: %d\r\n" "Status: %d\r\n" "Paused: %d\r\n" + "PausedReason: %s\r\n" "%s" "\r\n", q->name, mem->membername, mem->interface, mem->state_interface, mem->dynamic ? "dynamic" : "static", - mem->penalty, mem->calls, (int)mem->lastcall, mem->status, mem->paused, idText); + mem->penalty, mem->calls, (int)mem->lastcall, mem->status, mem->paused, mem->reason_paused, idText); ++q_items; } ao2_ref(mem, -1); @@ -9670,7 +9684,7 @@ static int manager_pause_queue_member(struct mansession *s, const struct message interface = astman_get_header(m, "Interface"); paused_s = astman_get_header(m, "Paused"); queuename = astman_get_header(m, "Queue"); /* Optional - if not supplied, pause the given Interface in all queues */ - reason = astman_get_header(m, "Reason"); /* Optional - Only used for logging purposes */ + reason = astman_get_header(m, "Reason"); /* Optional */ if (ast_strlen_zero(interface) || ast_strlen_zero(paused_s)) { astman_send_error(s, m, "Need 'Interface' and 'Paused' parameters."); diff --git a/apps/app_voicemail.c b/apps/app_voicemail.c index 19bd896af..0755c44b0 100644 --- a/apps/app_voicemail.c +++ b/apps/app_voicemail.c @@ -48,7 +48,6 @@ /*** MODULEINFO <defaultenabled>yes</defaultenabled> - <conflict>res_mwi_external</conflict> <use type="module">res_adsi</use> <use type="module">res_smdi</use> <support_level>core</support_level> @@ -14702,10 +14701,14 @@ static int unload_module(void) * * Module loading including tests for configuration or dependencies. * This function can return AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_DECLINE, - * or AST_MODULE_LOAD_SUCCESS. If a dependency or environment variable fails - * tests return AST_MODULE_LOAD_FAILURE. If the module can not load the - * configuration file or other non-critical problem return - * AST_MODULE_LOAD_DECLINE. On success return AST_MODULE_LOAD_SUCCESS. + * or AST_MODULE_LOAD_SUCCESS. + * + * If a dependency, allocation or environment variable fails tests, return AST_MODULE_LOAD_FAILURE. + * + * If the module can't load the configuration file, can't register as a provider or + * has another issue not fatal to Asterisk itself, return AST_MODULE_LOAD_DECLINE. + * + * On success return AST_MODULE_LOAD_SUCCESS. */ static int load_module(void) { @@ -14714,7 +14717,7 @@ static int load_module(void) umask(my_umask); if (!(inprocess_container = ao2_container_alloc(573, inprocess_hash_fn, inprocess_cmp_fn))) { - return AST_MODULE_LOAD_DECLINE; + return AST_MODULE_LOAD_FAILURE; } /* compute the location of the voicemail spool directory */ @@ -14724,8 +14727,10 @@ static int load_module(void) ast_log(AST_LOG_WARNING, "failed to reference mwi subscription taskprocessor. MWI will not work\n"); } - if ((res = load_config(0))) - return res; + if ((res = load_config(0))) { + unload_module(); + return AST_MODULE_LOAD_DECLINE; + } res = ast_register_application_xml(app, vm_exec); res |= ast_register_application_xml(app2, vm_execmain); @@ -14746,10 +14751,26 @@ static int load_module(void) res |= AST_TEST_REGISTER(test_voicemail_vm_info); #endif - res |= ast_vm_register(&vm_table); - res |= ast_vm_greeter_register(&vm_greeter_table); if (res) { - return res; + ast_log(LOG_ERROR, "Failure registering applications, functions or tests\n"); + unload_module(); + return AST_MODULE_LOAD_DECLINE; + } + + /* ast_vm_register may return DECLINE if another module registered for vm */ + res = ast_vm_register(&vm_table); + if (res) { + ast_log(LOG_ERROR, "Failure registering as a voicemail provider\n"); + unload_module(); + return AST_MODULE_LOAD_DECLINE; + } + + /* ast_vm_greeter_register may return DECLINE if another module registered as a greeter */ + res = ast_vm_greeter_register(&vm_greeter_table); + if (res) { + ast_log(LOG_ERROR, "Failure registering as a greeter provider\n"); + unload_module(); + return AST_MODULE_LOAD_DECLINE; } ast_cli_register_multiple(cli_voicemail, ARRAY_LEN(cli_voicemail)); @@ -14762,7 +14783,7 @@ static int load_module(void) ast_realtime_require_field("voicemail", "uniqueid", RQ_UINTEGER3, 11, "password", RQ_CHAR, 10, SENTINEL); ast_realtime_require_field("voicemail_data", "filename", RQ_CHAR, 30, "duration", RQ_UINTEGER3, 5, SENTINEL); - return res; + return AST_MODULE_LOAD_SUCCESS; } static int dialout(struct ast_channel *chan, struct ast_vm_user *vmu, char *num, char *outgoing_context) diff --git a/include/asterisk.h b/include/asterisk.h index c501c44ce..873ed5c34 100644 --- a/include/asterisk.h +++ b/include/asterisk.h @@ -222,6 +222,9 @@ char *ast_complete_source_filename(const char *partial, int n); * SVN from modifying them in this file; under normal circumstances they would * not be present and SVN would expand the Revision keyword into the file's * revision number. + * + * \deprecated All new files should use ASTERISK_REGISTER_FILE instead. + * \version 11.22.0 deprecated */ #ifdef MTX_PROFILE #define HAVE_MTX_PROFILE /* used in lock.h */ @@ -251,6 +254,23 @@ char *ast_complete_source_filename(const char *partial, int n); #define ASTERISK_FILE_VERSION(file, x) #endif /* LOW_MEMORY */ +/*! + * \since 11.22.0 + * \brief Register/unregister a source code file with the core. + * + * This macro will place a file-scope constructor and destructor into the + * source of the module using it; this will cause the file to be + * registered with the Asterisk core (and unregistered) at the appropriate + * times. + * + * Example: + * + * \code + * ASTERISK_REGISTER_FILE() + * \endcode + */ +#define ASTERISK_REGISTER_FILE() ASTERISK_FILE_VERSION(__FILE__, NULL) + #if !defined(LOW_MEMORY) /*! * \brief support for event profiling diff --git a/include/asterisk/app.h b/include/asterisk/app.h index 6171dd4f2..86336e32b 100644 --- a/include/asterisk/app.h +++ b/include/asterisk/app.h @@ -580,6 +580,7 @@ int ast_vm_is_registered(void); * * \retval 0 on success. * \retval -1 on error. + * \retval AST_MODULE_LOAD_DECLINE if there's already another provider registered. */ int __ast_vm_register(const struct ast_vm_functions *vm_table, struct ast_module *module); @@ -648,6 +649,7 @@ int ast_vm_greeter_is_registered(void); * * \retval 0 on success. * \retval -1 on error. + * \retval AST_MODULE_LOAD_DECLINE if there's already another greeter registered. */ int __ast_vm_greeter_register(const struct ast_vm_greeter_functions *vm_table, struct ast_module *module); diff --git a/include/asterisk/module.h b/include/asterisk/module.h index d201aacc8..35ee8bbd7 100644 --- a/include/asterisk/module.h +++ b/include/asterisk/module.h @@ -68,7 +68,7 @@ enum ast_module_unload_mode { enum ast_module_load_result { AST_MODULE_LOAD_SUCCESS = 0, /*!< Module loaded and configured */ AST_MODULE_LOAD_DECLINE = 1, /*!< Module is not configured */ - AST_MODULE_LOAD_SKIP = 2, /*!< Module was skipped for some reason */ + AST_MODULE_LOAD_SKIP = 2, /*!< Module was skipped for some reason (For loader.c use only. Should never be returned by modules)*/ AST_MODULE_LOAD_PRIORITY = 3, /*!< Module is not loaded yet, but is added to prioity heap */ AST_MODULE_LOAD_FAILURE = -1, /*!< Module could not be loaded properly */ }; diff --git a/include/asterisk/stasis_cache_pattern.h b/include/asterisk/stasis_cache_pattern.h index 27761351a..e61d3e931 100644 --- a/include/asterisk/stasis_cache_pattern.h +++ b/include/asterisk/stasis_cache_pattern.h @@ -121,9 +121,12 @@ struct stasis_cp_single *stasis_cp_single_create(struct stasis_cp_all *all, const char *name); /*! - * \brief Create the 'one' side of the cache pattern. + * \brief Create a sink in the cache pattern * - * Create the 'one' but do not automatically forward. + * Create the 'one' but do not automatically forward to the all's topic. + * This is useful when aggregating other topic's messages created with + * \c stasis_cp_single_create in another caching topic without replicating + * those messages in the all's topics. * * Dispose of using stasis_cp_single_unsubscribe(). * @@ -131,22 +134,10 @@ struct stasis_cp_single *stasis_cp_single_create(struct stasis_cp_all *all, * \param name Base name for the topics. * \return One side instance */ -struct stasis_cp_single *stasis_cp_single_create_only(struct stasis_cp_all *all, +struct stasis_cp_single *stasis_cp_sink_create(struct stasis_cp_all *all, const char *name); /*! - * \brief Set up a topic and topic cache forward. - * - * Forward 'from' to 'to'. - * - * \param from Source 'one' side instance. - * \param to Destination 'one' side instance. - * \retval 0 Success - * \retval -1 Failure - */ -int stasis_cp_single_forward(struct stasis_cp_single *from, struct stasis_cp_single *to); - -/*! * \brief Stops caching and forwarding messages. * * \param one One side of the cache pattern. diff --git a/main/app.c b/main/app.c index 8c33b9146..c4143d840 100644 --- a/main/app.c +++ b/main/app.c @@ -494,7 +494,7 @@ int __ast_vm_register(const struct ast_vm_functions *vm_table, struct ast_module if (table) { ast_log(LOG_WARNING, "Voicemail provider already registered by %s.\n", table->module_name); - return -1; + return AST_MODULE_LOAD_DECLINE; } table = ao2_alloc_options(sizeof(*table), NULL, AO2_ALLOC_OPT_LOCK_NOLOCK); @@ -605,7 +605,7 @@ int __ast_vm_greeter_register(const struct ast_vm_greeter_functions *vm_table, s if (table) { ast_log(LOG_WARNING, "Voicemail greeter provider already registered by %s.\n", table->module_name); - return -1; + return AST_MODULE_LOAD_DECLINE; } table = ao2_alloc_options(sizeof(*table), NULL, AO2_ALLOC_OPT_LOCK_NOLOCK); diff --git a/main/endpoints.c b/main/endpoints.c index 8f3ae366e..80e7f87fd 100644 --- a/main/endpoints.c +++ b/main/endpoints.c @@ -74,6 +74,8 @@ struct ast_endpoint { struct stasis_message_router *router; /*! ast_str_container of channels associated with this endpoint */ struct ao2_container *channel_ids; + /*! Forwarding subscription from an endpoint to its tech endpoint */ + struct stasis_forward *tech_forward; }; static int endpoint_hash(const void *obj, int flags) @@ -303,7 +305,7 @@ static struct ast_endpoint *endpoint_internal_create(const char *tech, const cha if (!ast_strlen_zero(resource)) { - endpoint->topics = stasis_cp_single_create_only(ast_endpoint_cache_all(), + endpoint->topics = stasis_cp_single_create(ast_endpoint_cache_all(), endpoint->id); if (!endpoint->topics) { return NULL; @@ -322,14 +324,13 @@ static struct ast_endpoint *endpoint_internal_create(const char *tech, const cha return NULL; } - if (stasis_cp_single_forward(endpoint->topics, tech_endpoint->topics)) { - return NULL; - } + endpoint->tech_forward = stasis_forward_all(stasis_cp_single_topic(endpoint->topics), + stasis_cp_single_topic(tech_endpoint->topics)); endpoint_publish_snapshot(endpoint); ao2_link(endpoints, endpoint); } else { - endpoint->topics = stasis_cp_single_create(ast_endpoint_cache_all(), + endpoint->topics = stasis_cp_sink_create(ast_endpoint_cache_all(), endpoint->id); if (!endpoint->topics) { return NULL; @@ -382,6 +383,7 @@ void ast_endpoint_shutdown(struct ast_endpoint *endpoint) } ao2_unlink(endpoints, endpoint); + endpoint->tech_forward = stasis_forward_cancel(endpoint->tech_forward); clear_msg = create_endpoint_snapshot_message(endpoint); if (clear_msg) { diff --git a/main/pbx_builtins.c b/main/pbx_builtins.c index ce5a92b97..fa155888a 100644 --- a/main/pbx_builtins.c +++ b/main/pbx_builtins.c @@ -29,7 +29,7 @@ #include "asterisk.h" -ASTERISK_FILE_VERSION(__FILE__, "$Revision$") +ASTERISK_REGISTER_FILE() #include "asterisk/_private.h" #include "asterisk/pbx.h" diff --git a/main/pbx_functions.c b/main/pbx_functions.c index b8be2bc40..bc738b043 100644 --- a/main/pbx_functions.c +++ b/main/pbx_functions.c @@ -29,7 +29,7 @@ #include "asterisk.h" -ASTERISK_FILE_VERSION(__FILE__, "$Revision$") +ASTERISK_REGISTER_FILE() #include "asterisk/_private.h" #include "asterisk/cli.h" diff --git a/main/stasis_cache_pattern.c b/main/stasis_cache_pattern.c index ccc9ebf08..7ccf1c181 100644 --- a/main/stasis_cache_pattern.c +++ b/main/stasis_cache_pattern.c @@ -138,7 +138,7 @@ struct stasis_cp_single *stasis_cp_single_create(struct stasis_cp_all *all, { RAII_VAR(struct stasis_cp_single *, one, NULL, ao2_cleanup); - one = stasis_cp_single_create_only(all, name); + one = stasis_cp_sink_create(all, name); if (!one) { return NULL; } @@ -157,7 +157,7 @@ struct stasis_cp_single *stasis_cp_single_create(struct stasis_cp_all *all, return one; } -struct stasis_cp_single *stasis_cp_single_create_only(struct stasis_cp_all *all, +struct stasis_cp_single *stasis_cp_sink_create(struct stasis_cp_all *all, const char *name) { RAII_VAR(struct stasis_cp_single *, one, NULL, ao2_cleanup); @@ -180,23 +180,6 @@ struct stasis_cp_single *stasis_cp_single_create_only(struct stasis_cp_all *all, return one; } -int stasis_cp_single_forward(struct stasis_cp_single *from, struct stasis_cp_single *to) -{ - from->forward_topic_to_all = stasis_forward_all(from->topic, to->topic); - if (!from->forward_topic_to_all) { - return -1;; - } - - from->forward_cached_to_all = stasis_forward_all( - stasis_caching_get_topic(from->topic_cached), - stasis_caching_get_topic(to->topic_cached)); - if (!from->forward_cached_to_all) { - return -1; - } - - return 0; -} - void stasis_cp_single_unsubscribe(struct stasis_cp_single *one) { if (!one) { diff --git a/res/res_mwi_external.c b/res/res_mwi_external.c index e5d8a3d32..9ded0d959 100644 --- a/res/res_mwi_external.c +++ b/res/res_mwi_external.c @@ -33,7 +33,6 @@ /*** MODULEINFO <defaultenabled>no</defaultenabled> - <conflict>app_voicemail</conflict> <support_level>core</support_level> ***/ @@ -935,12 +934,22 @@ static int unload_module(void) static int load_module(void) { + int res; + if (mwi_sorcery_init() || ast_sorcery_observer_add(mwi_sorcery, MWI_MAILBOX_TYPE, &mwi_observers) #if defined(MWI_DEBUG_CLI) || ast_cli_register_multiple(mwi_cli, ARRAY_LEN(mwi_cli)) #endif /* defined(MWI_DEBUG_CLI) */ - || ast_vm_register(&vm_table)) { + ) { + unload_module(); + return AST_MODULE_LOAD_DECLINE; + } + + /* ast_vm_register may return DECLINE if another module registered for vm */ + res = ast_vm_register(&vm_table); + if (res) { + ast_log(LOG_ERROR, "Failure registering as a voicemail provider\n"); unload_module(); return AST_MODULE_LOAD_DECLINE; } |