[asterisk-commits] rmudgett: branch rmudgett/external_mwi r403430 - in /team/rmudgett/external_m...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Fri Dec 6 13:57:58 CST 2013


Author: rmudgett
Date: Fri Dec  6 13:57:55 2013
New Revision: 403430

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=403430
Log:
Nearly complete work so far before simplifying the API.

Added:
    team/rmudgett/external_mwi/include/asterisk/res_mwi_external.h   (with props)
    team/rmudgett/external_mwi/res/res_mwi_external.c   (with props)
    team/rmudgett/external_mwi/res/res_mwi_external.exports.in   (with props)
    team/rmudgett/external_mwi/res/res_mwi_external_ami.c   (with props)
Modified:
    team/rmudgett/external_mwi/apps/app_voicemail.c
    team/rmudgett/external_mwi/configs/sorcery.conf.sample
    team/rmudgett/external_mwi/include/asterisk/app.h
    team/rmudgett/external_mwi/include/asterisk/doxyref.h
    team/rmudgett/external_mwi/main/app.c
    team/rmudgett/external_mwi/main/sorcery.c
    team/rmudgett/external_mwi/res/res_sorcery_astdb.c

Modified: team/rmudgett/external_mwi/apps/app_voicemail.c
URL: http://svnview.digium.com/svn/asterisk/team/rmudgett/external_mwi/apps/app_voicemail.c?view=diff&rev=403430&r1=403429&r2=403430
==============================================================================
--- team/rmudgett/external_mwi/apps/app_voicemail.c (original)
+++ team/rmudgett/external_mwi/apps/app_voicemail.c Fri Dec  6 13:57:55 2013
@@ -47,6 +47,7 @@
  */
 
 /*** MODULEINFO
+	<conflict>res_mwi_external</conflict>
 	<use type="module">res_adsi</use>
 	<use type="module">res_smdi</use>
 	<support_level>core</support_level>
@@ -14225,6 +14226,25 @@
 }
 #endif /* defined(TEST_FRAMEWORK) */
 
+static const struct ast_vm_functions vm_table = {
+	.module_version = VM_MODULE_VERSION,
+	.module_name = AST_MODULE,
+
+	.has_voicemail = has_voicemail,
+	.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,
+	.mailbox_snapshot_destroy = vm_mailbox_snapshot_destroy,
+	.msg_move = vm_msg_move,
+	.msg_remove = vm_msg_remove,
+	.msg_forward = vm_msg_forward,
+	.msg_play = vm_msg_play,
+};
+
 static int reload(void)
 {
 	return load_config(1);
@@ -14254,7 +14274,7 @@
 	res |= AST_TEST_UNREGISTER(test_voicemail_vm_info);
 #endif
 	ast_cli_unregister_multiple(cli_voicemail, ARRAY_LEN(cli_voicemail));
-	ast_uninstall_vm_functions();
+	ast_vm_unregister(vm_table.module_name);
 #ifdef TEST_FRAMEWORK
 	ast_uninstall_vm_test_functions();
 #endif
@@ -14321,16 +14341,12 @@
 	res |= AST_TEST_REGISTER(test_voicemail_vm_info);
 #endif
 
+	res |= ast_vm_register(&vm_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));
-
-	ast_install_vm_functions(has_voicemail, inboxcount, inboxcount2, messagecount, sayname, msg_create_from_file,
-				 vm_index_to_foldername,
-				 vm_mailbox_snapshot_create, vm_mailbox_snapshot_destroy,
-				 vm_msg_move, vm_msg_remove, vm_msg_forward, vm_msg_play);
 
 #ifdef TEST_FRAMEWORK
 	ast_install_vm_test_functions(vm_test_create_user, vm_test_destroy_user);

Modified: team/rmudgett/external_mwi/configs/sorcery.conf.sample
URL: http://svnview.digium.com/svn/asterisk/team/rmudgett/external_mwi/configs/sorcery.conf.sample?view=diff&rev=403430&r1=403429&r2=403430
==============================================================================
--- team/rmudgett/external_mwi/configs/sorcery.conf.sample (original)
+++ team/rmudgett/external_mwi/configs/sorcery.conf.sample Fri Dec  6 13:57:55 2013
@@ -49,6 +49,13 @@
 test=memory
 
 ;
+; The following object mapping is the default mapping of external MWI mailbox
+; objects to give persistence to the message counts.
+;
+;[res_mwi_external]
+;mailboxes=astdb,mwi_external
+
+;
 ; The following object mappings set PJSIP objects to use realtime database mappings from extconfig
 ; with the table names used when automatically generating configuration from the alembic script.
 ;

Modified: team/rmudgett/external_mwi/include/asterisk/app.h
URL: http://svnview.digium.com/svn/asterisk/team/rmudgett/external_mwi/include/asterisk/app.h?view=diff&rev=403430&r1=403429&r2=403430
==============================================================================
--- team/rmudgett/external_mwi/include/asterisk/app.h (original)
+++ team/rmudgett/external_mwi/include/asterisk/app.h Fri Dec  6 13:57:55 2013
@@ -334,19 +334,19 @@
 /*!
  * \brief Determines if the given folder has messages.
  *
- * \param mailbox Comma or & delimited list of mailboxes (user at context).
+ * \param mailboxes Comma or & delimited list of mailboxes (user at context).
  *          If no context is found, uses 'default' for the context.
  * \param folder The folder to look in.  Default is INBOX if not provided.
  *
  * \retval 1 if the folder has one or more messages.
  * \retval 0 otherwise.
  */
-typedef int (ast_has_voicemail_fn)(const char *mailbox, const char *folder);
+typedef int (ast_has_voicemail_fn)(const char *mailboxes, const char *folder);
 
 /*!
  * \brief Gets the number of messages that exist for the mailbox list.
  *
- * \param mailbox Comma or space delimited list of mailboxes (user at context).
+ * \param mailboxes Comma or space delimited list of mailboxes (user at context).
  *          If no context is found, uses 'default' for the context.
  * \param newmsgs Where to put the count of new messages. (Can be NULL)
  * \param oldmsgs Where to put the count of old messages. (Can be NULL)
@@ -358,12 +358,12 @@
  * \retval 0 on success
  * \retval -1 on failure
  */
-typedef int (ast_inboxcount_fn)(const char *mailbox, int *newmsgs, int *oldmsgs);
+typedef int (ast_inboxcount_fn)(const char *mailboxes, int *newmsgs, int *oldmsgs);
 
 /*!
  * \brief Gets the number of messages that exist for the mailbox list.
  *
- * \param mailbox Comma or space delimited list of mailboxes (user at context).
+ * \param mailboxes Comma or space delimited list of mailboxes (user at context).
  *          If no context is found, uses 'default' for the context.
  * \param urgentmsgs Where to put the count of urgent messages. (Can be NULL)
  * \param newmsgs Where to put the count of new messages. (Can be NULL)
@@ -377,13 +377,13 @@
  * \retval 0 on success
  * \retval -1 on failure
  */
-typedef int (ast_inboxcount2_fn)(const char *mailbox, int *urgentmsgs, int *newmsgs, int *oldmsgs);
+typedef int (ast_inboxcount2_fn)(const char *mailboxes, int *urgentmsgs, int *newmsgs, int *oldmsgs);
 
 /*!
  * \brief Gets the number of messages that exist in a mailbox folder.
  *
  * \param context The context part of user at context.  Uses 'default' if not provided.
- * \param mailbox The user part of user at context.
+ * \param user The user part of user at context.
  * \param folder The folder to look in.  Default is INBOX if not provided.
  *
  * \note If requesting INBOX then the returned count is INBOX +
@@ -391,20 +391,20 @@
  *
  * \return The number of messages in this mailbox folder (zero or more).
  */
-typedef int (ast_messagecount_fn)(const char *context, const char *mailbox, const char *folder);
+typedef int (ast_messagecount_fn)(const char *context, const char *user, const char *folder);
 
 /*!
  * \brief Play a recorded user name for the mailbox.
  *
  * \param chan Where to play the recorded name file.
- * \param mailbox The user part of user at context.
+ * \param user The user part of user at context.
  * \param context The context part of user at context.  Must be explicit.
  *
  * \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 *mailbox, const char *context);
+typedef int (ast_sayname_fn)(struct ast_channel *chan, const char *user, const char *context);
 
 /*!
  * \brief Creates a voicemail based on a specified file to a mailbox.
@@ -430,7 +430,7 @@
 /*!
  * \brief Create a snapshot of a mailbox which contains information about every msg.
  *
- * \param mailbox The user part of user at context.
+ * \param user The user part of user at context.
  * \param context The context part of user at context.  Must be explicit.
  * \param folder When not NULL only msgs from the specified folder will be included.
  * \param descending list the msgs in descending order rather than ascending order.
@@ -444,7 +444,7 @@
  * \retval snapshot on success
  * \retval NULL on failure
  */
-typedef struct ast_vm_mailbox_snapshot *(ast_vm_mailbox_snapshot_create_fn)(const char *mailbox,
+typedef struct ast_vm_mailbox_snapshot *(ast_vm_mailbox_snapshot_create_fn)(const char *user,
 	const char *context, const char *folder, int descending,
 	enum ast_vm_snapshot_sort_val sort_val, int combine_INBOX_and_OLD);
 
@@ -536,45 +536,63 @@
 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
+
+/*! \brief Voicemail function table definition. */
+struct ast_vm_functions {
+	/*!
+	 * \brief The version of this function table.
+	 *
+	 * \note If the ABI for this table changes, the module version
+	 * (\ref VM_MODULE_VERSION) should be incremented.
+	 */
+	unsigned int module_version;
+	/*! \brief The name of the module that provides the voicemail functionality */
+	const char *module_name;
+	/*! \brief The module for the voicemail provider */
+	struct ast_module *module;
+
+	ast_has_voicemail_fn *has_voicemail;
+	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;
+	ast_vm_mailbox_snapshot_destroy_fn *mailbox_snapshot_destroy;
+	ast_vm_msg_move_fn *msg_move;
+	ast_vm_msg_remove_fn *msg_remove;
+	ast_vm_msg_forward_fn *msg_forward;
+	ast_vm_msg_play_fn *msg_play;
+};
+
 /*!
  * \brief Set voicemail function callbacks
  *
- * \param has_voicemail_func set function pointer
- * \param inboxcount_func set function pointer
- * \param inboxcount2_func set function pointer
- * \param messagecount_func set function pointer
- * \param sayname_func set function pointer
- * \param copy_recording_to_vm_func set function pointer
- * \param vm_index_to_foldername_func set function pointer
- * \param vm_mailbox_snapshot_create_func set function pointer
- * \param vm_mailbox_snapshot_destroy_func set function pointer
- * \param vm_msg_move_func set function pointer
- * \param vm_msg_remove_func set function pointer
- * \param vm_msg_forward_func set function pointer
- * \param vm_msg_play_func set function pointer
- *
- * \version 1.6.1 Added inboxcount2_func, sayname_func
- */
-void ast_install_vm_functions(ast_has_voicemail_fn *has_voicemail_func,
-	ast_inboxcount_fn *inboxcount_func,
-	ast_inboxcount2_fn *inboxcount2_func,
-	ast_messagecount_fn *messagecount_func,
-	ast_sayname_fn *sayname_func,
-	ast_copy_recording_to_vm_fn *copy_recording_to_vm_func,
-	ast_vm_index_to_foldername_fn *vm_index_to_foldername_func,
-	ast_vm_mailbox_snapshot_create_fn *vm_mailbox_snapshot_create_func,
-	ast_vm_mailbox_snapshot_destroy_fn *vm_mailbox_snapshot_destroy_func,
-	ast_vm_msg_move_fn *vm_msg_move_func,
-	ast_vm_msg_remove_fn *vm_msg_remove_func,
-	ast_vm_msg_forward_fn *vm_msg_forward_func,
-	ast_vm_msg_play_fn *vm_msg_play_func);
-
-
-void ast_uninstall_vm_functions(void);
+ * \param vm_table Voicemail function table to install.
+ * \param module Pointer to the module implementing the interface
+ *
+ * \retval 0 on success.
+ * \retval -1 on error.
+ */
+int __ast_vm_register(const struct ast_vm_functions *vm_table, struct ast_module *module);
+
+/*! \brief See \ref __ast_vm_register() */
+#define ast_vm_register(vm_table) __ast_vm_register(vm_table, ast_module_info ? ast_module_info->self : NULL)
+
+/*!
+ * \brief Unregister the specified voicemail provider
+ *
+ * \param The module name of the provider to unregister
+ *
+ * \return Nothing
+ */
+void ast_vm_unregister(const char *module_name);
 
 #ifdef TEST_FRAMEWORK
-typedef int (ast_vm_test_create_user_fn)(const char *context, const char *mailbox);
-typedef int (ast_vm_test_destroy_user_fn)(const char *context, const char *mailbox);
+typedef int (ast_vm_test_create_user_fn)(const char *context, const char *user);
+typedef int (ast_vm_test_destroy_user_fn)(const char *context, const char *user);
 
 void ast_install_vm_test_functions(ast_vm_test_create_user_fn *vm_test_create_user_func,
 	ast_vm_test_destroy_user_fn *vm_test_destroy_user_func);
@@ -599,12 +617,12 @@
  * \retval -1 Failure
  * \since 1.0
  */
-int ast_app_has_voicemail(const char *mailbox, const char *folder);
+int ast_app_has_voicemail(const char *mailboxes, const char *folder);
 
 /*!
  * \brief Determine number of new/old messages in a mailbox
  * \since 1.0
- * \param[in] mailbox Mailbox specification in the format
+ * \param[in] mailboxes Mailbox specification in the format
  * 	/code
  *	 mbox[\@context][&mbox2[\@context2]][...]
  *	/code
@@ -613,18 +631,18 @@
  * \retval 0 Success
  * \retval -1 Failure
  */
-int ast_app_inboxcount(const char *mailbox, int *newmsgs, int *oldmsgs);
+int ast_app_inboxcount(const char *mailboxes, int *newmsgs, int *oldmsgs);
 
 /*!
  * \brief Determine number of urgent/new/old messages in a mailbox
- * \param[in] mailbox the mailbox context to use
+ * \param[in] mailboxes the mailbox context to use
  * \param[out] urgentmsgs the urgent message count
  * \param[out] newmsgs the new message count
  * \param[out] oldmsgs the old message count
  * \return Returns 0 for success, negative upon error
  * \since 1.6.1
  */
-int ast_app_inboxcount2(const char *mailbox, int *urgentmsgs, int *newmsgs, int *oldmsgs);
+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

Modified: team/rmudgett/external_mwi/include/asterisk/doxyref.h
URL: http://svnview.digium.com/svn/asterisk/team/rmudgett/external_mwi/include/asterisk/doxyref.h?view=diff&rev=403430&r1=403429&r2=403430
==============================================================================
--- team/rmudgett/external_mwi/include/asterisk/doxyref.h (original)
+++ team/rmudgett/external_mwi/include/asterisk/doxyref.h Fri Dec  6 13:57:55 2013
@@ -99,7 +99,6 @@
  * \page AstAPIChanges Asterisk API Changes
  *
  * \section Changes161 Version 1.6.1
- * \li ast_install_vm_functions()
  * \li vmwi_generate()
  * \li ast_channel_datastore_alloc()
  * \li ast_channel_datastore_free()

Added: team/rmudgett/external_mwi/include/asterisk/res_mwi_external.h
URL: http://svnview.digium.com/svn/asterisk/team/rmudgett/external_mwi/include/asterisk/res_mwi_external.h?view=auto&rev=403430
==============================================================================
--- team/rmudgett/external_mwi/include/asterisk/res_mwi_external.h (added)
+++ team/rmudgett/external_mwi/include/asterisk/res_mwi_external.h Fri Dec  6 13:57:55 2013
@@ -1,0 +1,227 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2013, Digium, Inc.
+ *
+ * Richard Mudgett <rmudgett at digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*!
+ * \file
+ * \brief Core external MWI support.
+ *
+ * \author Richard Mudgett <rmudgett at digium.com>
+ *
+ * See Also:
+ * \arg \ref AstCREDITS
+ */
+
+#ifndef _ASTERISK_RES_MWI_EXTERNAL_H
+#define _ASTERISK_RES_MWI_EXTERNAL_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C"
+{
+#endif
+
+/* ------------------------------------------------------------------- */
+
+/*!
+ * \brief Increase the external MWI resource module reference count.
+ * \since 13.0.0
+ *
+ * \return Nothing
+ */
+void ast_mwi_external_ref(void);
+
+/*!
+ * \brief Decrease the external MWI resource module reference count.
+ * \since 13.0.0
+ *
+ * \return Nothing
+ */
+void ast_mwi_external_unref(void);
+
+struct ast_mwi_mailbox_object;
+
+/*! \brief Convienience unref function for mailbox object. */
+#define ast_mwi_mailbox_unref(mailbox) ao2_ref((struct ast_mwi_mailbox_object *) mailbox, -1)
+
+/*!
+ * \brief Allocate an external MWI object.
+ * \since 13.0.0
+ *
+ * \param user Part of user at context.
+ * \param context Part of user at context.  Defaults to 'default' if empty.
+ *
+ * \retval object on success.  The object is an ao2 object.
+ * \retval NULL on error.
+ */
+struct ast_mwi_mailbox_object *ast_mwi_mailbox_alloc(const char *user, const char *context);
+
+/*!
+ * \brief Get user part of user at context.
+ * \since 13.0.0
+ *
+ * \param mailbox Object to get user part of user at context.
+ *
+ * \retval user Part of user at context on success.  Use ast_free() to destroy.
+ * \retval NULL on error.
+ */
+char *ast_mwi_mailbox_get_user(const struct ast_mwi_mailbox_object *mailbox);
+
+/*!
+ * \brief Get context part of user at context.
+ * \since 13.0.0
+ *
+ * \param mailbox Object to get context part of user at context.
+ *
+ * \retval context Part of user at context on success.  Use ast_free() to destroy.
+ * \retval NULL on error.
+ */
+char *ast_mwi_mailbox_get_context(const struct ast_mwi_mailbox_object *mailbox);
+
+/*!
+ * \brief Get the number of new messages.
+ * \since 13.0.0
+ *
+ * \param mailbox Object to get number of new messages.
+ *
+ * \return Number of new messages.
+ */
+unsigned int ast_mwi_mailbox_get_msgs_new(const struct ast_mwi_mailbox_object *mailbox);
+
+/*!
+ * \brief Get the number of old messages.
+ * \since 13.0.0
+ *
+ * \param mailbox Object to get number of old messages.
+ *
+ * \return Number of old messages.
+ */
+unsigned int ast_mwi_mailbox_get_msgs_old(const struct ast_mwi_mailbox_object *mailbox);
+
+/*!
+ * \brief Copy the external MWI counts object.
+ * \since 13.0.0
+ *
+ * \param mailbox What to copy.
+ *
+ * \retval copy on success.  The object is an ao2 object.
+ * \retval NULL on error.
+ */
+struct ast_mwi_mailbox_object *ast_mwi_mailbox_copy(const struct ast_mwi_mailbox_object *mailbox);
+
+/*!
+ * \brief Set the number of new messages.
+ * \since 13.0.0
+ *
+ * \param mailbox Object to set number of new messages.
+ * \param num_msgs Number of messages to set.
+ *
+ * \return Nothing
+ */
+void ast_mwi_mailbox_set_msgs_new(struct ast_mwi_mailbox_object *mailbox, unsigned int num_msgs);
+
+/*!
+ * \brief Set the number of old messages.
+ * \since 13.0.0
+ *
+ * \param mailbox Object to set number of old messages.
+ * \param num_msgs Number of messages to set.
+ *
+ * \return Nothing
+ */
+void ast_mwi_mailbox_set_msgs_old(struct ast_mwi_mailbox_object *mailbox, unsigned int num_msgs);
+
+/*!
+ * \brief Update the external MWI counts with the given object.
+ * \since 13.0.0
+ *
+ * \param mailbox What to update.
+ *
+ * \retval 0 on success.
+ * \retval -1 on error.
+ */
+int ast_mwi_mailbox_update(struct ast_mwi_mailbox_object *mailbox);
+
+/*!
+ * \brief Delete external MWI object(s).
+ * \since 13.0.0
+ *
+ * \param user Part of user at context.
+ * \param context Part of user at context.  Defaults to 'default' if empty.
+ *
+ * \note If user is empty then deletes all mailboxes in the
+ * specified context.
+ *
+ * \retval 0 on success.
+ * \retval -1 on error.
+ */
+int ast_mwi_mailbox_delete(const char *user, const char *context);
+
+/*!
+ * \brief Delete all external MWI objects.
+ * \since 13.0.0
+ *
+ * \retval 0 on success.
+ * \retval -1 on error.
+ */
+int ast_mwi_mailbox_delete_all(void);
+
+/*!
+ * \brief Get matching external MWI object.
+ * \since 13.0.0
+ *
+ * \param user Part of user at context.
+ * \param context Part of user at context.  Defaults to 'default' if empty.
+ *
+ * \retval requested mailbox on success.  The object is an ao2 object.
+ * \retval NULL on error or no mailbox.
+ *
+ * \note The object must be treated as read-only.
+ */
+const struct ast_mwi_mailbox_object *ast_mwi_mailbox_get(const char *user, const char *context);
+
+/*!
+ * \brief Get all external MWI objects in the specified context.
+ * \since 13.0.0
+ *
+ * \param context Part of user at context.  Defaults to 'default' if empty.
+ *
+ * \retval container of struct ast_mwi_mailbox_object on success.
+ * \retval NULL on error.
+ *
+ * \note The objects in the container must be treated as read-only.
+ */
+struct ao2_container *ast_mwi_mailbox_get_by_context(const char *context);
+
+/*!
+ * \brief Get all external MWI objects.
+ * \since 13.0.0
+ *
+ * \retval container of struct ast_mwi_mailbox_object on success.
+ * \retval NULL on error.
+ *
+ * \note The objects in the container must be treated as read-only.
+ */
+struct ao2_container *ast_mwi_mailbox_get_all(void);
+
+
+/* ------------------------------------------------------------------- */
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif	/* _ASTERISK_RES_MWI_EXTERNAL_H */

Propchange: team/rmudgett/external_mwi/include/asterisk/res_mwi_external.h
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: team/rmudgett/external_mwi/include/asterisk/res_mwi_external.h
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Propchange: team/rmudgett/external_mwi/include/asterisk/res_mwi_external.h
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: team/rmudgett/external_mwi/main/app.c
URL: http://svnview.digium.com/svn/asterisk/team/rmudgett/external_mwi/main/app.c?view=diff&rev=403430&r1=403429&r2=403430
==============================================================================
--- team/rmudgett/external_mwi/main/app.c (original)
+++ team/rmudgett/external_mwi/main/app.c Fri Dec  6 13:57:55 2013
@@ -426,64 +426,53 @@
 	return res;
 }
 
-static ast_has_voicemail_fn *ast_has_voicemail_func = NULL;
-static ast_inboxcount_fn *ast_inboxcount_func = NULL;
-static ast_inboxcount2_fn *ast_inboxcount2_func = NULL;
-static ast_sayname_fn *ast_sayname_func = NULL;
-static ast_messagecount_fn *ast_messagecount_func = NULL;
-static ast_copy_recording_to_vm_fn *ast_copy_recording_to_vm_func = NULL;
-static ast_vm_index_to_foldername_fn *ast_vm_index_to_foldername_func = NULL;
-static ast_vm_mailbox_snapshot_create_fn *ast_vm_mailbox_snapshot_create_func = NULL;
-static ast_vm_mailbox_snapshot_destroy_fn *ast_vm_mailbox_snapshot_destroy_func = NULL;
-static ast_vm_msg_move_fn *ast_vm_msg_move_func = NULL;
-static ast_vm_msg_remove_fn *ast_vm_msg_remove_func = NULL;
-static ast_vm_msg_forward_fn *ast_vm_msg_forward_func = NULL;
-static ast_vm_msg_play_fn *ast_vm_msg_play_func = NULL;
-
-void ast_install_vm_functions(ast_has_voicemail_fn *has_voicemail_func,
-	ast_inboxcount_fn *inboxcount_func,
-	ast_inboxcount2_fn *inboxcount2_func,
-	ast_messagecount_fn *messagecount_func,
-	ast_sayname_fn *sayname_func,
-	ast_copy_recording_to_vm_fn *copy_recording_to_vm_func,
-	ast_vm_index_to_foldername_fn *vm_index_to_foldername_func,
-	ast_vm_mailbox_snapshot_create_fn *vm_mailbox_snapshot_create_func,
-	ast_vm_mailbox_snapshot_destroy_fn *vm_mailbox_snapshot_destroy_func,
-	ast_vm_msg_move_fn *vm_msg_move_func,
-	ast_vm_msg_remove_fn *vm_msg_remove_func,
-	ast_vm_msg_forward_fn *vm_msg_forward_func,
-	ast_vm_msg_play_fn *vm_msg_play_func)
-{
-	ast_has_voicemail_func = has_voicemail_func;
-	ast_inboxcount_func = inboxcount_func;
-	ast_inboxcount2_func = inboxcount2_func;
-	ast_messagecount_func = messagecount_func;
-	ast_sayname_func = sayname_func;
-	ast_copy_recording_to_vm_func = copy_recording_to_vm_func;
-	ast_vm_index_to_foldername_func = vm_index_to_foldername_func;
-	ast_vm_mailbox_snapshot_create_func = vm_mailbox_snapshot_create_func;
-	ast_vm_mailbox_snapshot_destroy_func = vm_mailbox_snapshot_destroy_func;
-	ast_vm_msg_move_func = vm_msg_move_func;
-	ast_vm_msg_remove_func = vm_msg_remove_func;
-	ast_vm_msg_forward_func = vm_msg_forward_func;
-	ast_vm_msg_play_func = vm_msg_play_func;
-}
-
-void ast_uninstall_vm_functions(void)
-{
-	ast_has_voicemail_func = NULL;
-	ast_inboxcount_func = NULL;
-	ast_inboxcount2_func = NULL;
-	ast_messagecount_func = NULL;
-	ast_sayname_func = NULL;
-	ast_copy_recording_to_vm_func = NULL;
-	ast_vm_index_to_foldername_func = NULL;
-	ast_vm_mailbox_snapshot_create_func = NULL;
-	ast_vm_mailbox_snapshot_destroy_func = NULL;
-	ast_vm_msg_move_func = NULL;
-	ast_vm_msg_remove_func = NULL;
-	ast_vm_msg_forward_func = NULL;
-	ast_vm_msg_play_func = NULL;
+/*! \brief The container for the voicemail provider */
+static AO2_GLOBAL_OBJ_STATIC(vm_provider);
+
+/*! Voicemail not registered warning */
+static int vm_warnings;
+
+int __ast_vm_register(const struct ast_vm_functions *vm_table, struct ast_module *module)
+{
+	RAII_VAR(struct ast_vm_functions *, table, NULL, ao2_cleanup);
+
+	if (!vm_table->module_name) {
+		ast_log(LOG_ERROR, "Voicemail provider missing required information.\n");
+		return -1;
+	}
+	if (vm_table->module_version != VM_MODULE_VERSION) {
+		ast_log(LOG_ERROR, "Voicemail provider '%s' has incorrect version\n",
+			vm_table->module_name);
+		return -1;
+	}
+
+	table = ao2_global_obj_ref(vm_provider);
+	if (table) {
+		ast_log(LOG_WARNING, "Voicemail 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_provider, table);
+	return 0;
+}
+
+void ast_vm_unregister(const char *module_name)
+{
+	struct ast_vm_functions *table;
+
+	table = ao2_global_obj_ref(vm_provider);
+	if (table && !strcmp(table->module_name, module_name)) {
+		ao2_global_obj_release(vm_provider);
+	}
+	ao2_cleanup(table);
 }
 
 #ifdef TEST_FRAMEWORK
@@ -504,17 +493,32 @@
 }
 #endif
 
-int ast_app_has_voicemail(const char *mailbox, const char *folder)
-{
-	static int warned = 0;
-	if (ast_has_voicemail_func) {
-		return ast_has_voicemail_func(mailbox, folder);
-	}
-
-	if (warned++ % 10 == 0) {
-		ast_verb(3, "Message check requested for mailbox %s/folder %s but voicemail not loaded.\n", mailbox, folder ? folder : "INBOX");
-	}
-	return 0;
+static void vm_warn_no_provider(void)
+{
+	if (vm_warnings++ % 10 == 0) {
+		ast_verb(3, "No voicemail provider registered.\n");
+	}
+}
+
+#define VM_API_CALL(res, api_call, api_parms)								\
+	do {																	\
+		struct ast_vm_functions *table = ao2_global_obj_ref(vm_provider);	\
+		if (!table) {														\
+			vm_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;
+
+	VM_API_CALL(res, has_voicemail, (mailboxes, folder));
+	return res;
 }
 
 /*!
@@ -525,44 +529,31 @@
  */
 int ast_app_copy_recording_to_vm(struct ast_vm_recording_data *vm_rec_data)
 {
-	static int warned = 0;
-
-	if (ast_copy_recording_to_vm_func) {
-		return ast_copy_recording_to_vm_func(vm_rec_data);
-	}
-
-	if (warned++ % 10 == 0) {
-		ast_verb(3, "copy recording to voicemail called to copy %s.%s to %s@%s, but voicemail not loaded.\n",
-			vm_rec_data->recording_file, vm_rec_data->recording_ext,
-			vm_rec_data->mailbox, vm_rec_data->context);
-	}
-
-	return -1;
-}
-
-int ast_app_inboxcount(const char *mailbox, int *newmsgs, int *oldmsgs)
-{
-	static int warned = 0;
+	int res = -1;
+
+	VM_API_CALL(res, copy_recording_to_vm, (vm_rec_data));
+	return res;
+}
+
+int ast_app_inboxcount(const char *mailboxes, int *newmsgs, int *oldmsgs)
+{
+	int res = 0;
+
 	if (newmsgs) {
 		*newmsgs = 0;
 	}
 	if (oldmsgs) {
 		*oldmsgs = 0;
 	}
-	if (ast_inboxcount_func) {
-		return ast_inboxcount_func(mailbox, newmsgs, oldmsgs);
-	}
-
-	if (warned++ % 10 == 0) {
-		ast_verb(3, "Message count requested for mailbox %s but voicemail not loaded.\n", mailbox);
-	}
-
-	return 0;
-}
-
-int ast_app_inboxcount2(const char *mailbox, int *urgentmsgs, int *newmsgs, int *oldmsgs)
-{
-	static int warned = 0;
+
+	VM_API_CALL(res, inboxcount, (mailboxes, newmsgs, oldmsgs));
+	return res;
+}
+
+int ast_app_inboxcount2(const char *mailboxes, int *urgentmsgs, int *newmsgs, int *oldmsgs)
+{
+	int res = 0;
+
 	if (newmsgs) {
 		*newmsgs = 0;
 	}
@@ -572,46 +563,33 @@
 	if (urgentmsgs) {
 		*urgentmsgs = 0;
 	}
-	if (ast_inboxcount2_func) {
-		return ast_inboxcount2_func(mailbox, urgentmsgs, newmsgs, oldmsgs);
-	}
-
-	if (warned++ % 10 == 0) {
-		ast_verb(3, "Message count requested for mailbox %s but voicemail not loaded.\n", mailbox);
-	}
-
-	return 0;
+
+	VM_API_CALL(res, inboxcount2, (mailboxes, urgentmsgs, newmsgs, oldmsgs));
+	return res;
 }
 
 int ast_app_sayname(struct ast_channel *chan, const char *mailbox, const char *context)
 {
-	if (ast_sayname_func) {
-		return ast_sayname_func(chan, mailbox, context);
-	}
-	return -1;
+	int res = -1;
+
+	VM_API_CALL(res, sayname, (chan, mailbox, context));
+	return res;
 }
 
 int ast_app_messagecount(const char *context, const char *mailbox, const char *folder)
 {
-	static int warned = 0;
-	if (ast_messagecount_func) {
-		return ast_messagecount_func(context, mailbox, folder);
-	}
-
-	if (!warned) {
-		warned++;
-		ast_verb(3, "Message count requested for mailbox %s@%s/%s but voicemail not loaded.\n", mailbox, context, folder);
-	}
-
-	return 0;
+	int res = 0;
+
+	VM_API_CALL(res, messagecount, (context, mailbox, folder));
+	return res;
 }
 
 const char *ast_vm_index_to_foldername(int id)
 {
-	if (ast_vm_index_to_foldername_func) {
-		return ast_vm_index_to_foldername_func(id);
-	}
-	return NULL;
+	const char *res = NULL;
+
+	VM_API_CALL(res, index_to_foldername, (id));
+	return res;
 }
 
 struct ast_vm_mailbox_snapshot *ast_vm_mailbox_snapshot_create(const char *mailbox,
@@ -621,18 +599,19 @@
 	enum ast_vm_snapshot_sort_val sort_val,
 	int combine_INBOX_and_OLD)
 {
-	if (ast_vm_mailbox_snapshot_create_func) {
-		return ast_vm_mailbox_snapshot_create_func(mailbox, context, folder, descending, sort_val, combine_INBOX_and_OLD);
-	}
-	return NULL;
+	struct ast_vm_mailbox_snapshot *res = NULL;
+
+	VM_API_CALL(res, mailbox_snapshot_create, (mailbox, context, folder, descending,
+		sort_val, combine_INBOX_and_OLD));
+	return res;
 }
 
 struct ast_vm_mailbox_snapshot *ast_vm_mailbox_snapshot_destroy(struct ast_vm_mailbox_snapshot *mailbox_snapshot)
 {
-	if (ast_vm_mailbox_snapshot_destroy_func) {
-		return ast_vm_mailbox_snapshot_destroy_func(mailbox_snapshot);
-	}
-	return NULL;
+	struct ast_vm_mailbox_snapshot *res = NULL;
+
+	VM_API_CALL(res, mailbox_snapshot_destroy, (mailbox_snapshot));
+	return res;
 }
 
 int ast_vm_msg_move(const char *mailbox,
@@ -642,10 +621,11 @@
 	const char *old_msg_ids[],
 	const char *newfolder)
 {
-	if (ast_vm_msg_move_func) {
-		return ast_vm_msg_move_func(mailbox, context, num_msgs, oldfolder, old_msg_ids, newfolder);
-	}
-	return 0;
+	int res = 0;
+
+	VM_API_CALL(res, msg_move, (mailbox, context, num_msgs, oldfolder, old_msg_ids,
+		newfolder));
+	return res;
 }
 
 int ast_vm_msg_remove(const char *mailbox,
@@ -654,10 +634,10 @@
 	const char *folder,
 	const char *msgs[])
 {
-	if (ast_vm_msg_remove_func) {
-		return ast_vm_msg_remove_func(mailbox, context, num_msgs, folder, msgs);
-	}
-	return 0;
+	int res = 0;
+
+	VM_API_CALL(res, msg_remove, (mailbox, context, num_msgs, folder, msgs));
+	return res;
 }
 
 int ast_vm_msg_forward(const char *from_mailbox,
@@ -670,10 +650,11 @@
 	const char *msg_ids[],
 	int delete_old)
 {
-	if (ast_vm_msg_forward_func) {
-		return ast_vm_msg_forward_func(from_mailbox, from_context, from_folder, to_mailbox, to_context, to_folder, num_msgs, msg_ids, delete_old);
-	}
-	return 0;
+	int res = 0;
+
+	VM_API_CALL(res, msg_forward, (from_mailbox, from_context, from_folder, to_mailbox,
+		to_context, to_folder, num_msgs, msg_ids, delete_old));
+	return res;
 }
 
 int ast_vm_msg_play(struct ast_channel *chan,
@@ -683,10 +664,10 @@
 	const char *msg_num,
 	ast_vm_msg_play_cb *cb)
 {
-	if (ast_vm_msg_play_func) {
-		return ast_vm_msg_play_func(chan, mailbox, context, folder, msg_num, cb);
-	}
-	return 0;
+	int res = 0;
+
+	VM_API_CALL(res, msg_play, (chan, mailbox, context, folder, msg_num, cb));
+	return res;
 }
 
 #ifdef TEST_FRAMEWORK

Modified: team/rmudgett/external_mwi/main/sorcery.c
URL: http://svnview.digium.com/svn/asterisk/team/rmudgett/external_mwi/main/sorcery.c?view=diff&rev=403430&r1=403429&r2=403430
==============================================================================
--- team/rmudgett/external_mwi/main/sorcery.c (original)
+++ team/rmudgett/external_mwi/main/sorcery.c Fri Dec  6 13:57:55 2013
@@ -472,7 +472,7 @@
 /*! \brief Internal function which creates an object type and adds a wizard mapping */
 static int sorcery_apply_wizard_mapping(struct ast_sorcery *sorcery, const char *type, const char *module, const char *name, const char *data, unsigned int caching)
 {
-	RAII_VAR(struct ast_sorcery_object_type *, object_type,  ao2_find(sorcery->types, type, OBJ_KEY), ao2_cleanup);
+	RAII_VAR(struct ast_sorcery_object_type *, object_type, ao2_find(sorcery->types, type, OBJ_KEY), ao2_cleanup);
 	RAII_VAR(struct ast_sorcery_wizard *, wizard, ao2_find(wizards, name, OBJ_KEY), ao2_cleanup);
 	RAII_VAR(struct ast_sorcery_object_wizard *, object_wizard, ao2_alloc(sizeof(*object_wizard), sorcery_object_wizard_destructor), ao2_cleanup);
 	int created = 0;
@@ -513,19 +513,21 @@
 	struct ast_variable *mapping;
 	int res = 0;
 
-	if (!config || (config == CONFIG_STATUS_FILEMISSING) || (config == CONFIG_STATUS_FILEINVALID)) {
+	if (!config || config == CONFIG_STATUS_FILEINVALID) {
 		return -1;
 	}
 
 	for (mapping = ast_variable_browse(config, name); mapping; mapping = mapping->next) {
 		RAII_VAR(char *, mapping_name, ast_strdup(mapping->name), ast_free);
 		RAII_VAR(char *, mapping_value, ast_strdup(mapping->value), ast_free);
-		char *options = mapping_name, *name = strsep(&options, "/");
-		char *data = mapping_value, *wizard = strsep(&data, ",");
+		char *options = mapping_name;
+		char *type = strsep(&options, "/");
+		char *data = mapping_value;
+		char *wizard = strsep(&data, ",");
 		unsigned int caching = 0;
 
-		/* If no wizard exists just skip, nothing we can do */
-		if (ast_strlen_zero(wizard)) {
+		/* If no object type or wizard exists just skip, nothing we can do */
+		if (ast_strlen_zero(type) || ast_strlen_zero(wizard)) {
 			continue;
 		}
 
@@ -535,7 +537,8 @@
 		}
 
 		/* Any error immediately causes us to stop */
-		if ((res = sorcery_apply_wizard_mapping(sorcery, name, module, wizard, data, caching))) {
+		if (sorcery_apply_wizard_mapping(sorcery, type, module, wizard, data, caching)) {
+			res = -1;
 			break;
 		}
 	}
@@ -547,7 +550,7 @@
 
 int __ast_sorcery_apply_default(struct ast_sorcery *sorcery, const char *type, const char *module, const char *name, const char *data)
 {
-	RAII_VAR(struct ast_sorcery_object_type *, object_type,  ao2_find(sorcery->types, type, OBJ_KEY), ao2_cleanup);
+	RAII_VAR(struct ast_sorcery_object_type *, object_type, ao2_find(sorcery->types, type, OBJ_KEY), ao2_cleanup);
 
 	/* Defaults can not be added if any existing mapping exists */
 	if (object_type) {
@@ -682,13 +685,13 @@
 		__aco_option_register(object_type->info, name, ACO_EXACT, object_type->file->types, default_val, opt_type, config_handler, flags, no_doc, argc);
 	} else if (argc == 1) {
 		__aco_option_register(object_type->info, name, ACO_EXACT, object_type->file->types, default_val, opt_type, config_handler, flags, no_doc, argc,
-				      object_field->args[0]);
+			object_field->args[0]);
 	} else if (argc == 2) {
 		__aco_option_register(object_type->info, name, ACO_EXACT, object_type->file->types, default_val, opt_type, config_handler, flags, no_doc, argc,
-				      object_field->args[0], object_field->args[1]);
+			object_field->args[0], object_field->args[1]);
 	} else if (argc == 3) {
 		__aco_option_register(object_type->info, name, ACO_EXACT, object_type->file->types, default_val, opt_type, config_handler, flags, no_doc, argc,
-				      object_field->args[0], object_field->args[1], object_field->args[2]);
+			object_field->args[0], object_field->args[1], object_field->args[2]);
 	} else {
 		ast_assert(0); /* The hack... she does us no good for this */
 	}
@@ -1081,7 +1084,7 @@
 	struct ast_sorcery_object_details *details;
 
 	if (!object_type || !object_type->type.item_alloc ||
-	    !(details = object_type->type.item_alloc(id))) {
+		!(details = object_type->type.item_alloc(id))) {
 		return NULL;
 	}
 
@@ -1194,7 +1197,7 @@
 	i = ao2_iterator_init(object_type->wizards, 0);
 	for (; (wizard = ao2_iterator_next(&i)); ao2_ref(wizard, -1)) {
 		if (wizard->wizard->retrieve_id &&
-		    !(object = wizard->wizard->retrieve_id(sorcery, wizard->data, object_type->name, id))) {
+			!(object = wizard->wizard->retrieve_id(sorcery, wizard->data, object_type->name, id))) {
 			continue;
 		}
 
@@ -1203,7 +1206,7 @@
 		ao2_ref(wizard, -1);
 		break;
 	}
-        ao2_iterator_destroy(&i);
+	ao2_iterator_destroy(&i);
 
 	if (!cached && object) {
 		ao2_callback(object_type->wizards, 0, sorcery_cache_create, object);

Added: team/rmudgett/external_mwi/res/res_mwi_external.c
URL: http://svnview.digium.com/svn/asterisk/team/rmudgett/external_mwi/res/res_mwi_external.c?view=auto&rev=403430
==============================================================================
--- team/rmudgett/external_mwi/res/res_mwi_external.c (added)
+++ team/rmudgett/external_mwi/res/res_mwi_external.c Fri Dec  6 13:57:55 2013
@@ -1,0 +1,1027 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2013, Digium, Inc.
+ *
+ * Richard Mudgett <rmudgett at digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*!
+ * \file
+ * \brief Core external MWI support.
+ *
+ * \details
+ * The module manages the persistent message counts cache and supplies
+ * an API to allow the protocol specific modules to control the counts
+ * or a subset.
+ *
+ * \author Richard Mudgett <rmudgett at digium.com>
+ *
+ * See Also:
+ * \arg \ref AstCREDITS
+ */
+
+/*** MODULEINFO
+	<defaultenabled>no</defaultenabled>
+	<conflict>app_voicemail</conflict>
+	<support_level>core</support_level>
+ ***/
+
+/*** DOCUMENTATION
+	<configInfo name="res_mwi_external" language="en_US">
+		<synopsis>Core external MWI support</synopsis>
+		<configFile name="sorcery.conf">
+			<configObject name="mailboxes">
+				<synopsis>Persistent cache of external MWI Mailboxs.</synopsis>
+				<description>
+					<para>Allows the alteration of sorcery backend mapping for
+					the persistent cache of external MWI mailboxes.</para>
+				</description>
+			</configObject>
+		</configFile>
+	</configInfo>
+ ***/
+
+
+#include "asterisk.h"
+
+ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
+
+#include "asterisk/app.h"

[... 1441 lines stripped ...]



More information about the asterisk-commits mailing list