[asterisk-commits] rmudgett: trunk r416830 - in /trunk: apps/ include/asterisk/ main/

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Fri Jun 20 12:06:53 CDT 2014


Author: rmudgett
Date: Fri Jun 20 12:06:42 2014
New Revision: 416830

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=416830
Log:
voicemail API callbacks: Extract the sayname API call to its own registerd callback.

* Extract the sayname API call to its own registerd callback.  This allows
the app_directory and app_chanspy applications to say a mailbox owner's
name using an alternate provider when app_voicemail is not available
because you are using res_mwi_external.  app_directory still uses the
voicemail.conf file.

AFS-64 #close
Reported by: Mark Michelson

Modified:
    trunk/apps/app_chanspy.c
    trunk/apps/app_directory.c
    trunk/apps/app_voicemail.c
    trunk/include/asterisk/app.h
    trunk/main/app.c

Modified: trunk/apps/app_chanspy.c
URL: http://svnview.digium.com/svn/asterisk/trunk/apps/app_chanspy.c?view=diff&rev=416830&r1=416829&r2=416830
==============================================================================
--- trunk/apps/app_chanspy.c (original)
+++ trunk/apps/app_chanspy.c Fri Jun 20 12:06:42 2014
@@ -864,6 +864,15 @@
 	return NULL;
 }
 
+static int spy_sayname(struct ast_channel *chan, const char *mailbox, const char *context)
+{
+	char *mailbox_id;
+
+	mailbox_id = ast_alloca(strlen(mailbox) + strlen(context) + 2);
+	sprintf(mailbox_id, "%s@%s", mailbox, context); /* Safe */
+	return ast_app_sayname(chan, mailbox_id);
+}
+
 static int common_exec(struct ast_channel *chan, struct ast_flags *flags,
 	int volfactor, const int fd, struct spy_dtmf_options *user_options,
 	const char *mygroup, const char *myenforced, const char *spec, const char *exten,
@@ -1078,8 +1087,9 @@
 				if (ast_test_flag(flags, OPTION_NAME)) {
 					const char *local_context = S_OR(name_context, "default");
 					const char *local_mailbox = S_OR(mailbox, ptr);
+
 					if (local_mailbox) {
-						res = ast_app_sayname(chan, local_mailbox, local_context);
+						res = spy_sayname(chan, local_mailbox, local_context);
 					} else {
 						res = -1;
 					}

Modified: trunk/apps/app_directory.c
URL: http://svnview.digium.com/svn/asterisk/trunk/apps/app_directory.c?view=diff&rev=416830&r1=416829&r2=416830
==============================================================================
--- trunk/apps/app_directory.c (original)
+++ trunk/apps/app_directory.c Fri Jun 20 12:06:42 2014
@@ -26,7 +26,6 @@
  */
 
 /*** MODULEINFO
-	<depend>app_voicemail</depend>
 	<support_level>core</support_level>
  ***/
 #include "asterisk.h"
@@ -290,7 +289,13 @@
 	const char *ext, const char *name, struct ast_flags *flags)
 {
 	int res = 0;
-	if ((res = ast_app_sayname(chan, ext, context)) >= 0) {
+	char *mailbox_id;
+
+	mailbox_id = ast_alloca(strlen(ext) + strlen(context) + 2);
+	sprintf(mailbox_id, "%s@%s", ext, context); /* Safe */
+
+	res = ast_app_sayname(chan, mailbox_id);
+	if (res >= 0) {
 		ast_stopstream(chan);
 		/* If Option 'e' was specified, also read the extension number with the name */
 		if (ast_test_flag(flags, OPT_SAYEXTENSION)) {

Modified: trunk/apps/app_voicemail.c
URL: http://svnview.digium.com/svn/asterisk/trunk/apps/app_voicemail.c?view=diff&rev=416830&r1=416829&r2=416830
==============================================================================
--- trunk/apps/app_voicemail.c (original)
+++ trunk/apps/app_voicemail.c Fri Jun 20 12:06:42 2014
@@ -13669,6 +13669,29 @@
 	return res;
 }
 
+/*!
+ * \internal
+ * \brief Play a recorded user name for the mailbox to the specified channel.
+ *
+ * \param chan Where to play the recorded name file.
+ * \param mailbox_id The mailbox name.
+ *
+ * \retval 0 Name played without interruption
+ * \retval dtmf ASCII value of the DTMF which interrupted playback.
+ * \retval -1 Unable to locate mailbox or hangup occurred.
+ */
+static int vm_sayname(struct ast_channel *chan, const char *mailbox_id)
+{
+	char *context;
+	char *mailbox;
+
+	if (ast_strlen_zero(mailbox_id)
+		|| separate_mailbox(ast_strdupa(mailbox_id), &mailbox, &context)) {
+		return -1;
+	}
+	return sayname(chan, mailbox, context);
+}
+
 static void read_password_from_file(const char *secretfn, char *password, int passwordlen) {
 	struct ast_config *pwconf;
 	struct ast_flags config_flags = { 0 };
@@ -14286,7 +14309,6 @@
 	.inboxcount = inboxcount,
 	.inboxcount2 = inboxcount2,
 	.messagecount = messagecount,
-	.sayname = sayname,
 	.copy_recording_to_vm = msg_create_from_file,
 	.index_to_foldername = vm_index_to_foldername,
 	.mailbox_snapshot_create = vm_mailbox_snapshot_create,
@@ -14295,6 +14317,13 @@
 	.msg_remove = vm_msg_remove,
 	.msg_forward = vm_msg_forward,
 	.msg_play = vm_msg_play,
+};
+
+static const struct ast_vm_greeter_functions vm_greeter_table = {
+	.module_version = VM_GREETER_MODULE_VERSION,
+	.module_name = AST_MODULE,
+
+	.sayname = vm_sayname,
 };
 
 static int reload(void)
@@ -14327,6 +14356,7 @@
 #endif
 	ast_cli_unregister_multiple(cli_voicemail, ARRAY_LEN(cli_voicemail));
 	ast_vm_unregister(vm_table.module_name);
+	ast_vm_greeter_unregister(vm_greeter_table.module_name);
 #ifdef TEST_FRAMEWORK
 	ast_uninstall_vm_test_functions();
 #endif
@@ -14394,8 +14424,10 @@
 #endif
 
 	res |= ast_vm_register(&vm_table);
-	if (res)
+	res |= ast_vm_greeter_register(&vm_greeter_table);
+	if (res) {
 		return res;
+	}
 
 	ast_cli_register_multiple(cli_voicemail, ARRAY_LEN(cli_voicemail));
 	ast_data_register_multiple(vm_data_providers, ARRAY_LEN(vm_data_providers));

Modified: trunk/include/asterisk/app.h
URL: http://svnview.digium.com/svn/asterisk/trunk/include/asterisk/app.h?view=diff&rev=416830&r1=416829&r2=416830
==============================================================================
--- trunk/include/asterisk/app.h (original)
+++ trunk/include/asterisk/app.h Fri Jun 20 12:06:42 2014
@@ -392,17 +392,16 @@
 typedef int (ast_messagecount_fn)(const char *mailbox_id, const char *folder);
 
 /*!
- * \brief Play a recorded user name for the mailbox.
+ * \brief Play a recorded user name for the mailbox to the specified channel.
  *
  * \param chan Where to play the recorded name file.
- * \param user The user part of user at context.
- * \param context The context part of user at context.  Must be explicit.
+ * \param mailbox_id The mailbox name.
  *
  * \retval 0 Name played without interruption
- * \retval dtmf ASCII value of the DTMF which interrupted playback
- * \retval -1 on failure
- */
-typedef int (ast_sayname_fn)(struct ast_channel *chan, const char *user, const char *context);
+ * \retval dtmf ASCII value of the DTMF which interrupted playback.
+ * \retval -1 Unable to locate mailbox or hangup occurred.
+ */
+typedef int (ast_sayname_fn)(struct ast_channel *chan, const char *mailbox_id);
 
 /*!
  * \brief Creates a voicemail based on a specified file to a mailbox.
@@ -534,7 +533,7 @@
 typedef int (ast_vm_msg_play_fn)(struct ast_channel *chan, const char *mailbox,
 	const char *context, const char *folder, const char *msg_num, ast_vm_msg_play_cb *cb);
 
-#define VM_MODULE_VERSION 1
+#define VM_MODULE_VERSION 2
 
 /*! \brief Voicemail function table definition. */
 struct ast_vm_functions {
@@ -554,7 +553,6 @@
 	ast_inboxcount_fn *inboxcount;
 	ast_inboxcount2_fn *inboxcount2;
 	ast_messagecount_fn *messagecount;
-	ast_sayname_fn *sayname;
 	ast_copy_recording_to_vm_fn *copy_recording_to_vm;
 	ast_vm_index_to_foldername_fn *index_to_foldername;
 	ast_vm_mailbox_snapshot_create_fn *mailbox_snapshot_create;
@@ -569,8 +567,8 @@
  * \brief Determine if a voicemail provider is registered.
  * \since 12.0.0
  *
- * \retval 0 if no privider registered.
- * \retval 1 if a privider is registered.
+ * \retval 0 if no provider registered.
+ * \retval 1 if a provider is registered.
  */
 int ast_vm_is_registered(void);
 
@@ -596,6 +594,59 @@
  * \return Nothing
  */
 void ast_vm_unregister(const char *module_name);
+
+#define VM_GREETER_MODULE_VERSION 1
+
+/*! \brief Voicemail greeter function table definition. */
+struct ast_vm_greeter_functions {
+	/*!
+	 * \brief The version of this function table.
+	 *
+	 * \note If the ABI for this table changes, the module version
+	 * (\ref VM_GREETER_MODULE_VERSION) should be incremented.
+	 */
+	unsigned int module_version;
+	/*! \brief The name of the module that provides the voicemail greeter functionality */
+	const char *module_name;
+	/*! \brief The module for the voicemail greeter provider */
+	struct ast_module *module;
+
+	ast_sayname_fn *sayname;
+};
+
+/*!
+ * \brief Determine if a voicemail greeter provider is registered.
+ * \since 13.0.0
+ *
+ * \retval 0 if no provider registered.
+ * \retval 1 if a provider is registered.
+ */
+int ast_vm_greeter_is_registered(void);
+
+/*!
+ * \brief Set voicemail greeter function callbacks
+ * \since 13.0.0
+ *
+ * \param vm_table Voicemail greeter function table to install.
+ * \param module Pointer to the module implementing the interface
+ *
+ * \retval 0 on success.
+ * \retval -1 on error.
+ */
+int __ast_vm_greeter_register(const struct ast_vm_greeter_functions *vm_table, struct ast_module *module);
+
+/*! \brief See \ref __ast_vm_greeter_register() */
+#define ast_vm_greeter_register(vm_table) __ast_vm_greeter_register(vm_table, ast_module_info ? ast_module_info->self : NULL)
+
+/*!
+ * \brief Unregister the specified voicemail greeter provider
+ * \since 13.0.0
+ *
+ * \param The module name of the provider to unregister
+ *
+ * \return Nothing
+ */
+void ast_vm_greeter_unregister(const char *module_name);
 
 #ifdef TEST_FRAMEWORK
 typedef int (ast_vm_test_create_user_fn)(const char *context, const char *user);
@@ -652,16 +703,16 @@
 int ast_app_inboxcount2(const char *mailboxes, int *urgentmsgs, int *newmsgs, int *oldmsgs);
 
 /*!
- * \brief Given a mailbox and context, play that mailbox owner's name to the channel specified
- * \param[in] chan Channel on which to play the name
- * \param[in] mailbox Mailbox number from which to retrieve the recording
- * \param[in] context Mailbox context from which to locate the mailbox number
+ * \brief Play a recorded user name for the mailbox to the specified channel.
+ *
+ * \param chan Where to play the recorded name file.
+ * \param mailbox_id The mailbox name.
+ *
  * \retval 0 Name played without interruption
  * \retval dtmf ASCII value of the DTMF which interrupted playback.
  * \retval -1 Unable to locate mailbox or hangup occurred.
- * \since 1.6.1
- */
-int ast_app_sayname(struct ast_channel *chan, const char *mailbox, const char *context);
+ */
+int ast_app_sayname(struct ast_channel *chan, const char *mailbox_id);
 
 /*!
  * \brief Get the number of messages in a given mailbox folder

Modified: trunk/main/app.c
URL: http://svnview.digium.com/svn/asterisk/trunk/main/app.c?view=diff&rev=416830&r1=416829&r2=416830
==============================================================================
--- trunk/main/app.c (original)
+++ trunk/main/app.c Fri Jun 20 12:06:42 2014
@@ -519,6 +519,66 @@
 	ao2_cleanup(table);
 }
 
+/*! \brief The container for the voicemail greeter provider */
+static AO2_GLOBAL_OBJ_STATIC(vm_greeter_provider);
+
+/*! Voicemail greeter not registered warning */
+static int vm_greeter_warnings;
+
+int ast_vm_greeter_is_registered(void)
+{
+	struct ast_vm_greeter_functions *table;
+	int is_registered;
+
+	table = ao2_global_obj_ref(vm_greeter_provider);
+	is_registered = table ? 1 : 0;
+	ao2_cleanup(table);
+	return is_registered;
+}
+
+int __ast_vm_greeter_register(const struct ast_vm_greeter_functions *vm_table, struct ast_module *module)
+{
+	RAII_VAR(struct ast_vm_greeter_functions *, table, NULL, ao2_cleanup);
+
+	if (!vm_table->module_name) {
+		ast_log(LOG_ERROR, "Voicemail greeter provider missing required information.\n");
+		return -1;
+	}
+	if (vm_table->module_version != VM_GREETER_MODULE_VERSION) {
+		ast_log(LOG_ERROR, "Voicemail greeter provider '%s' has incorrect version\n",
+			vm_table->module_name);
+		return -1;
+	}
+
+	table = ao2_global_obj_ref(vm_greeter_provider);
+	if (table) {
+		ast_log(LOG_WARNING, "Voicemail greeter provider already registered by %s.\n",
+			table->module_name);
+		return -1;
+	}
+
+	table = ao2_alloc_options(sizeof(*table), NULL, AO2_ALLOC_OPT_LOCK_NOLOCK);
+	if (!table) {
+		return -1;
+	}
+	*table = *vm_table;
+	table->module = module;
+
+	ao2_global_obj_replace_unref(vm_greeter_provider, table);
+	return 0;
+}
+
+void ast_vm_greeter_unregister(const char *module_name)
+{
+	struct ast_vm_greeter_functions *table;
+
+	table = ao2_global_obj_ref(vm_greeter_provider);
+	if (table && !strcmp(table->module_name, module_name)) {
+		ao2_global_obj_release(vm_greeter_provider);
+	}
+	ao2_cleanup(table);
+}
+
 #ifdef TEST_FRAMEWORK
 static ast_vm_test_create_user_fn *ast_vm_test_create_user_func = NULL;
 static ast_vm_test_destroy_user_fn *ast_vm_test_destroy_user_func = NULL;
@@ -546,7 +606,8 @@
 
 #define VM_API_CALL(res, api_call, api_parms)								\
 	do {																	\
-		struct ast_vm_functions *table = ao2_global_obj_ref(vm_provider);	\
+		struct ast_vm_functions *table;										\
+		table = ao2_global_obj_ref(vm_provider);							\
 		if (!table) {														\
 			vm_warn_no_provider();											\
 		} else if (table->api_call) {										\
@@ -557,6 +618,27 @@
 		ao2_cleanup(table);													\
 	} while (0)
 
+static void vm_greeter_warn_no_provider(void)
+{
+	if (vm_greeter_warnings++ % 10 == 0) {
+		ast_verb(3, "No voicemail greeter provider registered.\n");
+	}
+}
+
+#define VM_GREETER_API_CALL(res, api_call, api_parms)						\
+	do {																	\
+		struct ast_vm_greeter_functions *table;								\
+		table = ao2_global_obj_ref(vm_greeter_provider);					\
+		if (!table) {														\
+			vm_greeter_warn_no_provider();									\
+		} else if (table->api_call) {										\
+			ast_module_ref(table->module);									\
+			(res) = table->api_call api_parms;								\
+			ast_module_unref(table->module);								\
+		}																	\
+		ao2_cleanup(table);													\
+	} while (0)
+
 int ast_app_has_voicemail(const char *mailboxes, const char *folder)
 {
 	int res = 0;
@@ -612,11 +694,11 @@
 	return res;
 }
 
-int ast_app_sayname(struct ast_channel *chan, const char *mailbox, const char *context)
+int ast_app_sayname(struct ast_channel *chan, const char *mailbox_id)
 {
 	int res = -1;
 
-	VM_API_CALL(res, sayname, (chan, mailbox, context));
+	VM_GREETER_API_CALL(res, sayname, (chan, mailbox_id));
 	return res;
 }
 




More information about the asterisk-commits mailing list