include "logger.h" and errno.h from asterisk.h - usage shows that they
[asterisk/asterisk.git] / res / res_smdi.c
index 334f640..376ccc0 100644 (file)
  * \author Matthew A. Nicholson <mnicholson@digium.com>
  */
 
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
+#include "asterisk.h"
+
+ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
+
 #include <termios.h>
 #include <sys/time.h>
 #include <time.h>
 #include <ctype.h>
 
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision: $")
-
 #include "asterisk/module.h"
 #include "asterisk/lock.h"
 #include "asterisk/utils.h"
@@ -41,14 +38,11 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision: $")
 #include "asterisk/config.h"
 #include "asterisk/astobj.h"
 #include "asterisk/io.h"
-#include "asterisk/logger.h"
-#include "asterisk/utils.h"
 #include "asterisk/options.h"
 
 /* Message expiry time in milliseconds */
 #define SMDI_MSG_EXPIRY_TIME   30000 /* 30 seconds */
 
-static const char tdesc[] = "Asterisk Simplified Message Desk Interface (SMDI) Module";
 static const char config_file[] = "smdi.conf";
 
 static void ast_smdi_md_message_push(struct ast_smdi_interface *iface, struct ast_smdi_md_message *msg);
@@ -57,10 +51,7 @@ static void ast_smdi_mwi_message_push(struct ast_smdi_interface *iface, struct a
 static void *smdi_read(void *iface_p);
 static int smdi_load(int reload);
 
-/* Use count stuff */
-
-AST_MUTEX_DEFINE_STATIC(localuser_lock);
-static int localusecnt = 0;
+struct module_symbols *me;     /* initialized in load_module() */
 
 /*! \brief SMDI interface container. */
 struct ast_smdi_interface_container {
@@ -99,24 +90,23 @@ int ast_smdi_mwi_set(struct ast_smdi_interface *iface, const char *mailbox)
        FILE *file;
        int i;
        
-       file = fopen(iface->name, "w");
-       if(!file) {
+       if (!(file = fopen(iface->name, "w"))) {
                ast_log(LOG_ERROR, "Error opening SMDI interface %s (%s) for writing\n", iface->name, strerror(errno));
                return 1;
        }       
-
+       
        ASTOBJ_WRLOCK(iface);
-
+       
        fprintf(file, "OP:MWI ");
-
-       for(i = 0; i < iface->msdstrip; i++)
-          fprintf(file, "0");
+       
+       for (i = 0; i < iface->msdstrip; i++)
+               fprintf(file, "0");
 
        fprintf(file, "%s!\x04", mailbox);
        fclose(file);
 
        ASTOBJ_UNLOCK(iface);
-       ast_log(LOG_DEBUG, "Sent MWI set message for %s on %s\n", mailbox, iface->name);
+       ast_debug(1, "Sent MWI set message for %s on %s\n", mailbox, iface->name);
        return 0;
 }
 
@@ -129,32 +119,31 @@ int ast_smdi_mwi_unset(struct ast_smdi_interface *iface, const char *mailbox)
 {
        FILE *file;
        int i;
-       
-       file = fopen(iface->name, "w");
-       if(!file) {
+
+       if (!(file = fopen(iface->name, "w"))) {
                ast_log(LOG_ERROR, "Error opening SMDI interface %s (%s) for writing\n", iface->name, strerror(errno));
                return 1;
        }       
-
+       
        ASTOBJ_WRLOCK(iface);
-
+       
        fprintf(file, "RMV:MWI ");
-
-       for(i = 0; i < iface->msdstrip; i++)
-          fprintf(file, "0");
+       
+       for (i = 0; i < iface->msdstrip; i++)
+               fprintf(file, "0");
 
        fprintf(file, "%s!\x04", mailbox);
        fclose(file);
 
        ASTOBJ_UNLOCK(iface);
-       ast_log(LOG_DEBUG, "Sent MWI unset message for %s on %s", mailbox, iface->name);
+       ast_debug(1, "Sent MWI unset message for %s on %s\n", mailbox, iface->name);
        return 0;
 }
 
 /*!
  * \brief Put an SMDI message back in the front of the queue.
  * \param iface a pointer to the interface to use.
- * \param msg a pointer to the message to use.
+ * \param md_msg a pointer to the message to use.
  *
  * This function puts a message back in the front of the specified queue.  It
  * should be used if a message was popped but is not going to be processed for
@@ -168,7 +157,7 @@ void ast_smdi_md_message_putback(struct ast_smdi_interface *iface, struct ast_sm
 /*!
  * \brief Put an SMDI message back in the front of the queue.
  * \param iface a pointer to the interface to use.
- * \param msg a pointer to the message to use.
+ * \param mwi_msg a pointer to the message to use.
  *
  * This function puts a message back in the front of the specified queue.  It
  * should be used if a message was popped but is not going to be processed for
@@ -203,7 +192,7 @@ struct ast_smdi_md_message *ast_smdi_md_message_pop(struct ast_smdi_interface *i
                if (elapsed > iface->msg_expiry) {
                        /* found an expired message */
                        ASTOBJ_UNREF(md_msg, ast_smdi_md_message_destroy);
-                       ast_log(LOG_NOTICE, "Purged expired message from %s SMDI MD message queue.  Message was %ld milliseconds too old.",
+                       ast_log(LOG_NOTICE, "Purged expired message from %s SMDI MD message queue.  Message was %ld milliseconds too old.\n",
                                iface->name, elapsed - iface->msg_expiry);
                        md_msg = ASTOBJ_CONTAINER_UNLINK_START(&iface->md_q);
                }
@@ -230,11 +219,10 @@ struct ast_smdi_md_message *ast_smdi_md_message_pop(struct ast_smdi_interface *i
  */
 extern struct ast_smdi_md_message *ast_smdi_md_message_wait(struct ast_smdi_interface *iface, int timeout)
 {
-       struct timeval start;
+       struct timeval start = ast_tvnow();
        long diff = 0;
        struct ast_smdi_md_message *msg;
 
-       start = ast_tvnow();
        while (diff < timeout) {
 
                if ((msg = ast_smdi_md_message_pop(iface)))
@@ -260,18 +248,17 @@ extern struct ast_smdi_md_message *ast_smdi_md_message_wait(struct ast_smdi_inte
 extern struct ast_smdi_mwi_message *ast_smdi_mwi_message_pop(struct ast_smdi_interface *iface)
 {
        struct ast_smdi_mwi_message *mwi_msg = ASTOBJ_CONTAINER_UNLINK_START(&iface->mwi_q);
-       struct timeval now;
+       struct timeval now = ast_tvnow();
        long elapsed = 0;
 
        /* purge old messages */
-       now = ast_tvnow();
        while (mwi_msg) {
                elapsed = ast_tvdiff_ms(now, mwi_msg->timestamp);
 
                if (elapsed > iface->msg_expiry) {
                        /* found an expired message */
                        ASTOBJ_UNREF(mwi_msg, ast_smdi_mwi_message_destroy);
-                       ast_log(LOG_NOTICE, "Purged expired message from %s SMDI MWI message queue.  Message was %ld milliseconds too old.",
+                       ast_log(LOG_NOTICE, "Purged expired message from %s SMDI MWI message queue.  Message was %ld milliseconds too old.\n",
                                iface->name, elapsed - iface->msg_expiry);
                        mwi_msg = ASTOBJ_CONTAINER_UNLINK_START(&iface->mwi_q);
                }
@@ -298,11 +285,10 @@ extern struct ast_smdi_mwi_message *ast_smdi_mwi_message_pop(struct ast_smdi_int
  */
 extern struct ast_smdi_mwi_message *ast_smdi_mwi_message_wait(struct ast_smdi_interface *iface, int timeout)
 {
-       struct timeval start;
+       struct timeval start = ast_tvnow();
        long diff = 0;
        struct ast_smdi_mwi_message *msg;
 
-       start = ast_tvnow();
        while (diff < timeout) {
 
                if ((msg = ast_smdi_mwi_message_pop(iface)))
@@ -330,7 +316,7 @@ extern struct ast_smdi_interface *ast_smdi_interface_find(const char *iface_name
 
 /*! \brief Read an SMDI message.
  *
- * \param iface the SMDI interface to read from.
+ * \param iface_p the SMDI interface to read from.
  *
  * This function loops and reads from and SMDI interface.  It must be stopped
  * using pthread_cancel().
@@ -416,7 +402,7 @@ static void *smdi_read(void *iface_p)
                                /* add the message to the message queue */
                                md_msg->timestamp = ast_tvnow();
                                ast_smdi_md_message_push(iface, md_msg);
-                               ast_log(LOG_DEBUG, "Recieved SMDI MD message on %s\n", iface->name);
+                               ast_debug(1, "Recieved SMDI MD message on %s\n", iface->name);
                                
                                ASTOBJ_UNREF(md_msg, ast_smdi_md_message_destroy);
 
@@ -459,7 +445,7 @@ static void *smdi_read(void *iface_p)
                                /* add the message to the message queue */
                                mwi_msg->timestamp = ast_tvnow();
                                ast_smdi_mwi_message_push(iface, mwi_msg);
-                               ast_log(LOG_DEBUG, "Recieved SMDI MWI message on %s\n", iface->name);
+                               ast_debug(1, "Recieved SMDI MWI message on %s\n", iface->name);
                                
                                ASTOBJ_UNREF(mwi_msg, ast_smdi_mwi_message_destroy);
                        } else {
@@ -477,13 +463,13 @@ static void *smdi_read(void *iface_p)
 /*! \brief ast_smdi_md_message destructor. */
 void ast_smdi_md_message_destroy(struct ast_smdi_md_message *msg)
 {
-       free(msg);
+       ast_free(msg);
 }
 
 /*! \brief ast_smdi_mwi_message destructor. */
 void ast_smdi_mwi_message_destroy(struct ast_smdi_mwi_message *msg)
 {
-       free(msg);
+       ast_free(msg);
 }
 
 /*! \brief ast_smdi_interface destructor. */
@@ -503,12 +489,9 @@ void ast_smdi_interface_destroy(struct ast_smdi_interface *iface)
        ASTOBJ_CONTAINER_DESTROYALL(&iface->mwi_q, ast_smdi_mwi_message_destroy);
        ASTOBJ_CONTAINER_DESTROY(&iface->md_q);
        ASTOBJ_CONTAINER_DESTROY(&iface->mwi_q);
-       free(iface);
+       ast_free(iface);
 
-       ast_mutex_lock(&localuser_lock);
-       localusecnt--;
-       ast_mutex_unlock(&localuser_lock);
-       ast_update_use_count();
+       ast_module_unref(ast_module_info->self);
 }
 
 /*!
@@ -526,6 +509,7 @@ static int smdi_load(int reload)
        struct ast_config *conf;
        struct ast_variable *v;
        struct ast_smdi_interface *iface = NULL;
+       struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
        int res = 0;
 
        /* Config options */
@@ -536,13 +520,15 @@ static int smdi_load(int reload)
        
        int msdstrip = 0;              /* strip zero digits */
        long msg_expiry = SMDI_MSG_EXPIRY_TIME;
-       
-       conf = ast_config_load(config_file);
 
-       if (!conf) {
-               ast_log(LOG_ERROR, "Unable to load config %s\n", config_file);
-               return -1;
-       }
+       if (!(conf = ast_config_load(config_file, config_flags))) {
+               if (reload)
+                       ast_log(LOG_NOTICE, "Unable to reload config %s: SMDI untouched\n", config_file);
+               else
+                       ast_log(LOG_NOTICE, "Unable to load config %s: SMDI disabled\n", config_file);
+               return 1;
+       } else if (conf == CONFIG_STATUS_FILEUNCHANGED)
+               return 0;
 
        /* Mark all interfaces that we are listening on.  We will unmark them
         * as we find them in the config file, this way we know any interfaces
@@ -621,7 +607,8 @@ static int smdi_load(int reload)
                                }
                        }
                                                        
-                       iface = ast_calloc(1, sizeof(*iface));
+                       if (!(iface = ast_calloc(1, sizeof(*iface))))
+                               continue;
 
                        ASTOBJ_INIT(iface);
                        ASTOBJ_CONTAINER_INIT(&iface->md_q);
@@ -655,13 +642,13 @@ static int smdi_load(int reload)
                        
                        /* set the stop bits */
                        if (stopbits)
-                          iface->mode.c_cflag = iface->mode.c_cflag | CSTOPB;   /* set two stop bits */
+                               iface->mode.c_cflag = iface->mode.c_cflag | CSTOPB;   /* set two stop bits */
                        else
-                          iface->mode.c_cflag = iface->mode.c_cflag & ~CSTOPB;  /* set one stop bit */
-
+                               iface->mode.c_cflag = iface->mode.c_cflag & ~CSTOPB;  /* set one stop bit */
+                       
                        /* set the parity */
                        iface->mode.c_cflag = (iface->mode.c_cflag & ~PARENB & ~PARODD) | paritybit;
-
+                       
                        /* set the character size */
                        iface->mode.c_cflag = (iface->mode.c_cflag & ~CSIZE) | charsize;
                        
@@ -679,9 +666,8 @@ static int smdi_load(int reload)
                        iface->msg_expiry = msg_expiry;
 
                         /* start the listner thread */
-                       if (option_verbose > 2)
-                               ast_verbose(VERBOSE_PREFIX_3 "Starting SMDI monitor thread for %s\n", iface->name);
-                       if (ast_pthread_create(&iface->thread, NULL, smdi_read, iface)) {
+                       ast_verb(3, "Starting SMDI monitor thread for %s\n", iface->name);
+                       if (ast_pthread_create_background(&iface->thread, NULL, smdi_read, iface)) {
                                ast_log(LOG_ERROR, "Error starting SMDI monitor thread for %s\n", iface->name);
                                ASTOBJ_UNREF(iface, ast_smdi_interface_destroy);
                                continue;
@@ -689,17 +675,13 @@ static int smdi_load(int reload)
 
                        ASTOBJ_CONTAINER_LINK(&smdi_ifaces, iface);
                        ASTOBJ_UNREF(iface, ast_smdi_interface_destroy);
-                       ast_mutex_lock(&localuser_lock);
-                       localusecnt++;
-                       ast_mutex_unlock(&localuser_lock);
-                       ast_update_use_count();
+                       ast_module_ref(ast_module_info->self);
                } else {
                        ast_log(LOG_NOTICE, "Ignoring unknown option %s in %s\n", v->name, config_file);
                }
-               v = v->next;
        }
        ast_config_destroy(conf);
-
+       
        /* Prune any interfaces we should no longer monitor. */
        if (reload)
                ASTOBJ_CONTAINER_PRUNE_MARKED(&smdi_ifaces, ast_smdi_interface_destroy);
@@ -709,36 +691,30 @@ static int smdi_load(int reload)
        if (!smdi_ifaces.head)
                res = 1;
        ASTOBJ_CONTAINER_UNLOCK(&smdi_ifaces);
-                       
+       
        return res;
 }
 
-
-char *description(void)
-{
-       return (char *) tdesc;
-}
-
-int load_module(void)
+static int load_module(void)
 {
        int res;
-
+       
        /* initialize our containers */
        memset(&smdi_ifaces, 0, sizeof(smdi_ifaces));
        ASTOBJ_CONTAINER_INIT(&smdi_ifaces);
-
+       
        /* load the config and start the listener threads*/
        res = smdi_load(0);
        if (res < 0) {
                return res;
        } else if (res == 1) {
-               ast_log(LOG_WARNING, "No SMDI interfaces are available to listen on, not starting SDMI listener.\n");
-               return 0;
+               ast_log(LOG_NOTICE, "No SMDI interfaces are available to listen on, not starting SMDI listener.\n");
+               return AST_MODULE_LOAD_DECLINE;
        } else
-               return 0;
+               return AST_MODULE_LOAD_SUCCESS;
 }
 
-int unload_module(void)
+static int unload_module(void)
 {
        /* this destructor stops any running smdi_read threads */
        ASTOBJ_CONTAINER_DESTROYALL(&smdi_ifaces, ast_smdi_interface_destroy);
@@ -747,7 +723,7 @@ int unload_module(void)
        return 0;
 }
 
-int reload(void)
+static int reload(void)
 {
        int res;
 
@@ -762,16 +738,8 @@ int reload(void)
                return 0;
 }
 
-int usecount(void)
-{
-       int res;
-
-       STANDARD_USECOUNT(res);
-
-       return res;
-}
-
-char *key()
-{
-       return ASTERISK_GPL_KEY;
-}
+AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS, "Simplified Message Desk Interface (SMDI) Resource",
+               .load = load_module,
+               .unload = unload_module,
+               .reload = reload,
+              );