[asterisk-commits] mjordan: branch mjordan/voicemail_refactor_11_10_19 r348361 - in /team/mjorda...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Fri Dec 16 07:33:38 CST 2011
Author: mjordan
Date: Fri Dec 16 07:30:28 2011
New Revision: 348361
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=348361
Log:
I think I'm getting closer to how I want this to look
Modified:
team/mjordan/voicemail_refactor_11_10_19/include/asterisk/message_storage.h
team/mjordan/voicemail_refactor_11_10_19/res/res_message_imap.c
team/mjordan/voicemail_refactor_11_10_19/res/res_message_storage.c
Modified: team/mjordan/voicemail_refactor_11_10_19/include/asterisk/message_storage.h
URL: http://svnview.digium.com/svn/asterisk/team/mjordan/voicemail_refactor_11_10_19/include/asterisk/message_storage.h?view=diff&rev=348361&r1=348360&r2=348361
==============================================================================
--- team/mjordan/voicemail_refactor_11_10_19/include/asterisk/message_storage.h (original)
+++ team/mjordan/voicemail_refactor_11_10_19/include/asterisk/message_storage.h Fri Dec 16 07:30:28 2011
@@ -9,70 +9,25 @@
#define MESSAGE_STORAGE_H_
-struct vm_config {
- double volgain;
- unsigned int max_silence;
+struct ast_msg_config {
unsigned int max_deleted_messages;
unsigned int max_messages;
- unsigned int min_say_duration;
- unsigned int min_message_duration;
- unsigned int max_message_duration;
- unsigned int max_message_greeting_length;
- unsigned int skip_ms;
- unsigned int min_password_length;
- unsigned int silence_threshold;
- unsigned int poll_frequency;
- unsigned int max_logins;
enum vm_passwordlocation password_location;
- char attach_format[MAX_FORMAT_LENGTH];
char format[MAX_FORMAT_LENGTH];
- char dial_out_context[AST_MAX_CONTEXT];
- char callback_context[AST_MAX_CONTEXT];
- char op_exit_context[AST_MAX_CONTEXT];
- char default_users_context[AST_MAX_CONTEXT];
- char cid_internal_contexts[MAX_NUM_CID_CONTEXTS][AST_MAX_CONTEXT];
- char extern_notify_cmd[PATH_MAX];
- char extern_pass_cmd[PATH_MAX];
- char extern_pass_check_cmd[PATH_MAX];
- char directory_intro_path[PATH_MAX];
- struct vm_sound_config * sound_config;
- struct vm_listen_control_config * listen_control_config;
- struct vm_smdi_config * smdi_config;
- struct vm_adsi_config * adsi_config;
- struct ast_flags globalflags;
- struct ast_flags passwordflags;
+ struct ast_flags global_flags;
+ struct ast_flags password_flags;
AST_DECLARE_STRING_FIELDS(
- AST_STRING_FIELD(mail_command);
- AST_STRING_FIELD(email_from_string);
- AST_STRING_FIELD(email_server);
- AST_STRING_FIELD(email_date_format);
- AST_STRING_FIELD(email_subject);
- AST_STRING_FIELD(email_body);
- AST_STRING_FIELD(pager_from_string);
- AST_STRING_FIELD(pager_date_format);
- AST_STRING_FIELD(pager_subject);
- AST_STRING_FIELD(pager_body);
AST_STRING_FIELD(zonetag);
AST_STRING_FIELD(locale);
- AST_STRING_FIELD(charset);
);
};
-
-struct ast_msg_user {
+struct ast_msg_mailbox {
char context[AST_MAX_CONTEXT]; /*!< Mailbox context */
char mailbox[AST_MAX_EXTENSION]; /*!< Mailbox id, unique within a context */
char language[MAX_LANGUAGE]; /*!< Config: Language setting */
- char callback[AST_MAX_CONTEXT]; /*!< Callback context */
- char dialout[AST_MAX_CONTEXT]; /*!< Dialout context */
- char uniqueid[80]; /*!< Unique integer identifier TODO: make this an integer? */
- char exit[AST_MAX_CONTEXT]; /*!< Context to exit out to */
- char attachfmt[MAX_FORMAT_LENGTH]; /*!< Attachment format */
- int min_say_duration; /*!< Minimum number of seconds for say */
- int min_message_duration; /*!< Minimum number of seconds per message for this mailbox */
int max_messages; /*!< Maximum number of msgs per folder for this mailbox */
int max_deleted_messages; /*!< Maximum number of deleted msgs saved for this mailbox */
- int max_message_duration; /*!< Maximum number of seconds per message for this mailbox */
int hash_key;
enum vm_passwordlocation password_location; /*!< Storage location of the password */
double volgain; /*!< Volume gain for voicemails sent via email */
@@ -80,15 +35,7 @@
AST_DECLARE_STRING_FIELDS(
AST_STRING_FIELD(fullname);
AST_STRING_FIELD(password);
- AST_STRING_FIELD(email_address);
- AST_STRING_FIELD(email_subject);
- AST_STRING_FIELD(email_body);
- AST_STRING_FIELD(pager_address);
- AST_STRING_FIELD(pager_subject);
- AST_STRING_FIELD(pager_body);
- AST_STRING_FIELD(email_from_address);
AST_STRING_FIELD(locale);
- AST_STRING_FIELD(mail_command);
AST_STRING_FIELD(zonetag);
AST_STRING_FIELD(timezone);
);
@@ -96,16 +43,28 @@
struct ast_msg_storage_tech {
+
const char * const name;
int (* const load_config)(struct ast_config *cfg, int reload);
+ int (* const load_mailboxes)(struct ast_config *mcfg, int reload, int by_variable);
+
+ struct ast_msg_config *(* const get_config)(void);
+
+ struct ast_msg_mailbox *(* const get_mailbox)(const char * const context, const char * const mailbox);
+
/* store message */
-
/* delete message */
/* retrieve message */
};
+
+struct ast_msg_config *ast_get_message_storage_config(void);
+
+struct ast_msg_mailbox *ast_get_message_mailbox(const char * const context, const char * const mailbox);
+
+void ast_unregister_message_storage_tech(const char * const name);
void ast_register_message_storage_tech(struct ast_msg_storage_tech *ms_tech);
Modified: team/mjordan/voicemail_refactor_11_10_19/res/res_message_imap.c
URL: http://svnview.digium.com/svn/asterisk/team/mjordan/voicemail_refactor_11_10_19/res/res_message_imap.c?view=diff&rev=348361&r1=348360&r2=348361
==============================================================================
--- team/mjordan/voicemail_refactor_11_10_19/res/res_message_imap.c (original)
+++ team/mjordan/voicemail_refactor_11_10_19/res/res_message_imap.c Fri Dec 16 07:30:28 2011
@@ -7,7 +7,6 @@
#define USERS_CONFIG "users.conf"
struct imap_config {
- /* TODO: make the next two fields bit fields? */
struct ast_msg_config *msg_config;
unsigned int expunge_on_hangup;
unsigned int imap_greetings;
@@ -29,72 +28,126 @@
);
};
-struct imap_user {
- struct ast_msg_user *msg_user;
+/*! \internal \brief The IMAP mailbox definition */
+struct imap_mailbox {
+ struct ast_msg_mailbox *msg_mailbox; /*!< The inherited message mailbox information */
AST_DECLARE_STRING_FIELDS(
- AST_STRING_FIELD(user); /*!< IMAP server login */
- AST_STRING_FIELD(password); /*!< IMAP server password if authpassword not defined */
- AST_STRING_FIELD(default_folder); /*!< IMAP voicemail folder */
- AST_STRING_FIELD(shared_id); /*!< Shared mailbox ID to use rather than the dialed one */
+ AST_STRING_FIELD(user); /*!< IMAP server login */
+ AST_STRING_FIELD(password); /*!< IMAP server password if auth_password not defined */
+ AST_STRING_FIELD(default_folder); /*!< IMAP message folder */
+ AST_STRING_FIELD(shared_id); /*!< Shared mailbox ID to use rather than the dialed one */
+ AST_STRING_FIELD(server);
+ AST_STRING_FIELD(port);
+ AST_STRING_FIELD(flags);
);
};
+/*! \internal \brief Default delimiter in messages */
static const char default_delimiter = '\0';
+
+/*! \internal \brief By default, messages are deleted if a hangup is detected */
+/* TODO: not sure if this actually should be here */
static const unsigned int default_expunge_on_hangup = 1;
+
+/*! \internal \brief Default IMAP server hostname */
static const char *default_imap_server_address = "localhost";
+
+/*! \internal \brief Default port to communicate over */
static const char *default_imap_port = "143";
+
+/*! \internal \brief Default IMAP folder to store messages in */
static const char *default_imap_folder = "INBOX";
+/*! \internal \brief Context that contains default settings */
static const char *default_settings_context = "general";
+
+/*! \internal \brief Context that contains timezone information; skipped for mailboxes */
static const char *default_timezone_context = "zonemessages";
+/* \internal \brief The IMAP storage layer configuration object
+ * \note Methods should *not* reference this object directly, but instead should
+ * get a reference from it through imap_get_config
+ */
static struct imap_config *config;
-
-static struct ao2_container *imap_users;
/*! \internal \brief The mutex that protects access to the imap config object */
AST_MUTEX_DEFINE_STATIC(config_lock);
+
+/* \internal \brief The IMAP mailboxes */
+static struct ao2_container *imap_mailboxes;
+
+/*! \internal \brief The base storage technology that the IMAP tech uses as an intermediate layer */
+static struct ast_msg_storage_tech *base_tech;
static struct ast_msg_storage_tech imap_message_storage_tech = {
.name = "IMAP",
.load_config = imap_load_config,
+ .load_mailboxes = imap_load_mailboxes,
+ .get_config = ast_get_message_storage_config,
+ .get_mailbox = ast_get_message_mailbox,
};
-static struct imap_user *imap_user_new(void)
-{
- struct imap_user *imu = NULL;
-
- if ((imu = ao2_alloc(sizeof(*imu), imap_user_destroy))) {
- if (ast_string_field_init(imu, 256)) {
- ao2_ref(imu, -1);
- imu = NULL;
- }
- }
-
- return imu;
-}
-
-static void imap_user_destroy(void *obj)
-{
- struct imap_user *imu = obj;
-
- if (!imu) {
+static struct imap_mailbox *imap_mailbox_new(const char *context, const char *mailbox)
+{
+ struct imap_mailbox *imbox = NULL;
+ struct ast_msg_mailbox *mbox = NULL;
+
+ if (!base_tech) {
+ return NULL;
+ }
+
+ if (!(mbox = base_tech->get_mailbox(context, mailbox))) {
+ ast_log(AST_LOG_WARNING, "Attempted to create IMAP mailbox from unknown mailbox %s/%s\n", context, mailbox);
+ return NULL;
+ }
+
+ if ((imbox = ao2_alloc(sizeof(*imbox), imap_mailbox_destroy))) {
+ imbox->msg_mailbox = mbox;
+ if (ast_string_field_init(imbox, 256)) {
+ ao2_ref(imbox, -1);
+ imbox = NULL;
+ }
+ } else {
+ ao2_ref(mbox, -1);
+ }
+
+ return imbox;
+}
+
+static void imap_mailbox_destroy(void *obj)
+{
+ struct imap_mailbox *imbox = obj;
+
+ if (!imbox) {
return;
}
- ao2_ref(imu->msg_user, -1);
- ast_string_field_free_memory(imu);
+ ao2_ref(imbox->msg_mailbox, -1);
+ ast_string_field_free_memory(imbox);
}
static struct imap_config *imap_config_new(void)
{
struct imap_config *iconfig = NULL;
+ struct ast_msg_config *config = NULL;
+
+ if (!base_tech) {
+ return NULL;
+ }
+
+ if (!(config = base_tech->get_config())) {
+ return NULL;
+ }
if ((iconfig = ao2_alloc(sizeof(*iconfig), imap_config_destroy))) {
+ iconfig->msg_config = config;
+
if (ast_string_field_init(iconfig, 256)) {
ao2_ref(iconfig, -1);
iconfig = NULL;
}
+ } else {
+ ao2_ref(config, -1);
}
return iconfig;
@@ -108,13 +161,17 @@
return;
}
- ao2_ref(iconfig->msg_config, -1);
+ ao2_ref(&iconfig->msg_config, -1);
ast_string_field_free_memory(iconfig);
}
-static void imap_populate_default_options(struct imap_config *iconfig)
+static void populate_default_config_options(struct imap_config *iconfig)
{
iconfig->expunge_on_hangup = default_expunge_on_hangup;
+ iconfig->close_timeout = 30;
+ iconfig->open_timeout = 30;
+ iconfig->write_timeout = 30;
+ iconfig->read_timeout = 30;
strcpy(iconfig->delimiter, default_delimiter);
@@ -123,13 +180,27 @@
ast_string_field_set(iconfig, folder, default_imap_folder);
}
-static int imap_load_config(struct imap_config *iconfig, struct ast_config *cfg, int reload)
+static int imap_load_config(struct ast_config *cfg, int reload)
{
struct ast_variable *var;
struct ast_category *cat = ast_category_get(cfg, default_settings_context);
+ struct imap_config *iconfig;
if (!cat) {
ast_log(AST_LOG_ERROR, "No %s category defined in configuration\n", default_settings_context);
+ return 1;
+ }
+
+ if (!base_tech) {
+ ast_log(AST_LOG_ERROR, "No base message technology defined; cannot load configuration\n");
+ return 1;
+ } else if (base_tech->load_config(cfg, reload)) {
+ ast_log(AST_LOG_ERROR, "Base message technology %s failed to load config; cannot load IMAP configuration\n", base_tech->name);
+ return 1;
+ }
+
+ if (!(iconfig = imap_config_new())) {
+ ast_log(AST_LOG_ERROR, "Unable to allocate sufficient memory for imap_config object\n");
return 1;
}
@@ -183,6 +254,13 @@
}
}
+ ast_mutex_lock(&config_lock);
+ if (reload) {
+ ao2_ref(config, -1);
+ }
+ config = iconfig;
+ ast_mutex_unlock(&config_lock);
+
return 0;
}
@@ -192,13 +270,13 @@
* prematurely deleted in the case of a reload - methods that obtain the object should decrement the
* reference count when they are finished with it.
*/
-static struct imap_config *get_imap_config(void)
+static struct ast_msg_config *imap_get_config(void)
{
ast_mutex_lock(&config_lock);
ao2_ref(config, +1);
ast_mutex_unlock(&config_lock);
- return config;
+ return (struct ast_msg_config *)config;
}
static int valid_user(struct imap_user *imu)
@@ -206,7 +284,7 @@
return 0;
}
-static void populate_user_from_variable(const struct imap_config *iconfig, struct imap_user *imu, const char *cat_name, struct ast_variable *var)
+static void create_mailbox_from_variable(const struct imap_config *iconfig, struct imap_user *imu, const char *cat_name, struct ast_variable *var)
{
char *values;
char *options;
@@ -248,38 +326,45 @@
}
}
-static void populate_user_from_category(const struct imap_config *iconfig, struct imap_user *imu, struct ast_config *ucfg, const char *cat_name)
-{
-
-}
-
-static int imap_load_users(const struct imap_config *iconfig, struct ast_config *ucfg, int reload, int load_from_variable, struct ao2_container *user_container)
+static void create_mailbox_from_category(const struct imap_config *iconfig, struct imap_user *imu, struct ast_config *ucfg, const char *cat_name)
+{
+
+}
+
+static int imap_load_mailboxes(struct ast_config *mcfg, int reload, int by_variable)
{
const char *cat_name;
- struct imap_user *imu_tmp;
- struct imap_user *imu_old;
- struct imap_user *imu;
int res = 0;
-
- for (cat_name = ast_category_browse(ucfg, NULL); cat_name; cat_name = ast_category_browse(ucfg, cat_name)) {
+ struct imap_mailbox *imbox = NULL;
+ struct imap_config *iconfig = NULL;
+ struct ao2_container *temp_container;
+
+ if (!base_tech) {
+ ast_log(AST_LOG_ERROR, "No base message technology defined; cannot load mailboxes\n");
+ return 1;
+ } else if (base_tech->load_mailboxes(mcfg, reload, by_variable)) {
+ ast_log(AST_LOG_ERROR, "Base message technology %s failed to load mailboxes; cannot load mailboxes\n", base_tech->name);
+ return 1;
+ }
+
+ iconfig = imap_get_config();
+
+ for (cat_name = ast_category_browse(mcfg, NULL); cat_name; cat_name = ast_category_browse(mcfg, cat_name)) {
/* Anything not in the general context or timezone context is assumed to be user data */
- if (load_from_variable && (!strcasecmp(cat_name, default_general_context) || !strcasecmp(cat_name, default_timezone_context))) {
+ if (by_variable && (!strcasecmp(cat_name, default_settings_context) || !strcasecmp(cat_name, default_timezone_context))) {
continue;
}
- if (!(imu = imap_user_new())) {
- ast_log(AST_LOG_ERROR, "Failed to allocate memory for imap_user object\n");
- res = 1;
- continue;
- }
-
- if (!load_from_variable) {
- for (var = ast_variable_browse(ucfg, cat_name); var; var = var->next) {
- populate_user_from_variable(iconfig, imu, cat_name, var);
+ if (!by_variable) {
+ for (var = ast_variable_browse(mcfg, cat_name); var; var = var->next) {
+ if (imbox = create_mailbox_from_variable(iconfig, imu, cat_name, var)) {
+ ao2_link(user_container, )
+ }
}
} else {
- if (ast_true(ast_config_option(ucfg, cat_name, "hasvoicemail"))) {
- populate_user_from_category(iconfig, imu, ucfg, cat_name);
+ /* TODO: this should probably be changed to hasmailbox or something along those lines */
+ if (ast_true(ast_config_option(mcfg, cat_name, "hasvoicemail"))) {
+ imbox = create_mailbox_from_category(iconfig, imu, ucfg, cat_name);
}
}
@@ -288,94 +373,43 @@
}
ao2_ref(imu, -1);
}
+
+ ao2_ref(iconfig, -1);
+
return 0;
}
-static int load_configs(int reload)
-{
- struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
- struct ast_config *cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags);
- struct ast_config *ucfg = ast_config_load(USERS_CONFIG, config_flags);
- struct imap_config *iconfig;
-
- /* If both configs are unchanged exit; otherwise load both */
- if (cfg == CONFIG_STATUS_FILEUNCHANGED && ucfg == CONFIG_STATUS_FILEUNCHANGED) {
- return 0;
- } else if (cfg == CONFIG_STATUS_FILEUNCHANGED && ucfg != CONFIG_STATUS_FILEUNCHANGED) {
- ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
- cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags);
- } else if (cfg != CONFIG_STATUS_FILEUNCHANGED && ucfg == CONFIG_STATUS_FILEUNCHANGED) {
- ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
- ucfg = ast_config_load(USER_CONFIG, config_flags);
- }
-
- if (!cfg || cfg == CONFIG_STATUS_FILEINVALID) {
- if (ucfg && ucfg != CONFIG_STATUS_FILEINVALID) {
- ast_config_destroy(ucfg);
- }
- ast_log(AST_LOG_ERROR, "Config file " VOICEMAIL_CONFIG " is in an invalid format. Aborting.\n");
- return 1;
- }
-
- if (ucfg == CONFIG_STATUS_FILEINVALID) {
- ast_log(AST_LOG_WARNING, "Config file " USERS_CONFIG " is in an invalid format. Avoiding.\n");
- ucfg = NULL;
+static int reload(void)
+{
+ return 0;
+}
+
+static int unload_module(void)
+{
+ ast_unregister_message_storage_tech(imap_message_storage_tech.name);
+
+ ao2_ref(config, -1);
+ ao2_ref(imap_mailboxes, -1);
+
+ return 0;
+}
+
+static int load_module(void)
+{
+ /* TODO: base? */
+ if (!(base_tech = ast_get_message_storage_tech("base"))) {
+ ast_log(AST_LOG_ERROR, "Unable to obtain base message technology\n");
+ return AST_MODULE_LOAD_FAILURE;
+ }
+
+ if (!(imap_mailboxes = ao2_container_alloc())) {
+ ast_log(AST_LOG_ERROR, "Unable to allocate IMAP users container\n");
+ return AST_MODULE_LOAD_FAILURE;
}
/* Since we have good config objects, attempt to create a new IMAP config from them */
- if (!(iconfig = imap_config_new())) {
+ if (!(config = imap_config_new())) {
ast_log(AST_LOG_ERROR, "Failed to allocate memory for new IMAP config object\n");
- return 1;
- }
- if (imap_load_config(iconfig, cfg, reload)) {
- ast_log(AST_LOG_ERROR, "Failed to load and parse " VOICEMAIL_CONFIG ". Aborting.\n");
- ast_config_destroy(cfg);
- if (ucfg) {
- ast_config_destroy(ucfg);
- }
- return 1;
- }
-
- /* Load user information from both the main config and from the optional user config */
- imap_load_users(iconfig, cfg, reload, 1, imap_users);
- if (ucfg) {
- imap_load_users(iconfig, ucfg, reload, 0, imap_users);
- }
-
- /* Update and replace the current IMAP configuration object */
- ast_mutex_lock(&config_lock);
- if (reload) {
- ao2_ref(config, -1);
- }
- config = iconfig;
- ast_mutex_unlock(&config_lock);
-
- return 0;
-}
-
-static int reload(void)
-{
- int res = 0;
-
- res |= load_configs(1);
-
- return res;
-}
-
-/* If I were to allow unloading it would look something like this */
-static int unload_module(void)
-{
- return 0;
-}
-
-static int load_module(void)
-{
- if (!(imap_users = ao2_container_alloc())) {
- ast_log(LOG_ERROR, "Unable to allocate IMAP users container\n");
- return AST_MODULE_LOAD_FAILURE;
- }
-
- if (load_configs(0)) {
ao2_ref(imap_users, -1);
return AST_MODULE_LOAD_FAILURE;
}
Modified: team/mjordan/voicemail_refactor_11_10_19/res/res_message_storage.c
URL: http://svnview.digium.com/svn/asterisk/team/mjordan/voicemail_refactor_11_10_19/res/res_message_storage.c?view=diff&rev=348361&r1=348360&r2=348361
==============================================================================
--- team/mjordan/voicemail_refactor_11_10_19/res/res_message_storage.c (original)
+++ team/mjordan/voicemail_refactor_11_10_19/res/res_message_storage.c Fri Dec 16 07:30:28 2011
@@ -22,11 +22,12 @@
return;
}
- /* Don't add the tech if its already been added */
+ /* Add the tech if it hasn't already been added */
ao2_lock(msg_storage_techs);
it_techs = ao2_iterator_init(msg_storage_techs, 0);
while ((tech_current = ao2_iterator_next(&it_techs))) {
if (!strncmp(ms_tech->name, tech_current->name, sizeof(ms_tech->name))) {
+ ast_log(AST_LOG_WARNING, "Message storage technology %s already registered\n", ms_tech->name)
ao2_ref(tech_current, -1);
ao2_iterator_destroy(&it_techs);
ao2_unlock(msg_storage_techs);
@@ -38,6 +39,21 @@
ao2_unlock(msg_storage_techs);
ao2_link(msg_storage_techs, ms_tech);
+}
+
+void ast_unregister_message_storage_tech(const char * const name)
+{
+ struct ast_msg_storage_tech tech_temp = { .name = name, };
+ struct ast_msg_storage_tech *ms_tech;
+
+ if (ast_strlen_zero(name)) {
+ return;
+ }
+
+ if ((ms_tech = ao2_find(msg_storage_techs, tech_temp, OBJ_POINTER))) {
+ ao2_ref(ms_tech, -1);
+ ao2_unlink(msg_storage_techs, ms_tech);
+ }
}
struct ast_msg_storage_tech *ast_get_message_storage_tech(const char * const name)
More information about the asterisk-commits
mailing list