Sat Nov 1 06:29:17 2008

Asterisk developer's documentation


res_smdi.c File Reference

SMDI support for Asterisk. More...

#include "asterisk.h"
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <termios.h>
#include <sys/time.h>
#include <time.h>
#include <ctype.h>
#include "asterisk/module.h"
#include "asterisk/lock.h"
#include "asterisk/utils.h"
#include "asterisk/smdi.h"
#include "asterisk/config.h"
#include "asterisk/astobj.h"
#include "asterisk/io.h"
#include "asterisk/logger.h"
#include "asterisk/options.h"
#include "asterisk/stringfields.h"
#include "asterisk/linkedlists.h"
#include "asterisk/app.h"
#include "asterisk/pbx.h"

Include dependency graph for res_smdi.c:

Go to the source code of this file.

Data Structures

struct  ast_smdi_interface
struct  ast_smdi_interface_container
 SMDI interface container. More...
struct  ast_smdi_md_queue
 SMDI message desk message queue. More...
struct  ast_smdi_mwi_queue
 SMDI message waiting indicator message queue. More...
struct  mailbox_mapping
 A mapping between an SMDI mailbox ID and an Asterisk mailbox. More...
struct  smdi_msg_datastore

Defines

#define DEFAULT_POLLING_INTERVAL   10
#define SMDI_MSG_EXPIRY_TIME   30000
#define SMDI_RETRIEVE_TIMEOUT_DEFAULT   3000

Enumerations

enum  { OPT_SEARCH_TERMINAL = (1 << 0), OPT_SEARCH_NUMBER = (1 << 1) }
enum  smdi_message_type { SMDI_MWI, SMDI_MD }

Functions

static struct ast_smdi_interfacealloc_smdi_interface (void)
static void append_mailbox_mapping (struct ast_variable *var, struct ast_smdi_interface *iface)
 AST_APP_OPTIONS (smdi_msg_ret_options, BEGIN_OPTIONS AST_APP_OPTION('t', OPT_SEARCH_TERMINAL), AST_APP_OPTION('n', OPT_SEARCH_NUMBER), END_OPTIONS)
 AST_MODULE_INFO (ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS,"Simplified Message Desk Interface (SMDI) Resource",.load=load_module,.unload=unload_module,.reload=reload,)
static void ast_smdi_interface_destroy (struct ast_smdi_interface *iface)
ast_smdi_interfaceast_smdi_interface_find (const char *iface_name)
 Find an SMDI interface with the specified name.
void ast_smdi_interface_unref (struct ast_smdi_interface *iface)
void ast_smdi_md_message_destroy (struct ast_smdi_md_message *msg)
 ast_smdi_md_message destructor.
ast_smdi_md_messageast_smdi_md_message_pop (struct ast_smdi_interface *iface)
 Get the next SMDI message from the queue.
static void ast_smdi_md_message_push (struct ast_smdi_interface *iface, struct ast_smdi_md_message *md_msg)
void ast_smdi_md_message_putback (struct ast_smdi_interface *iface, struct ast_smdi_md_message *md_msg)
 Put an SMDI message back in the front of the queue.
ast_smdi_md_messageast_smdi_md_message_wait (struct ast_smdi_interface *iface, int timeout)
 Get the next SMDI message from the queue.
void ast_smdi_mwi_message_destroy (struct ast_smdi_mwi_message *msg)
 ast_smdi_mwi_message destructor.
ast_smdi_mwi_messageast_smdi_mwi_message_pop (struct ast_smdi_interface *iface)
 Get the next SMDI message from the queue.
static void ast_smdi_mwi_message_push (struct ast_smdi_interface *iface, struct ast_smdi_mwi_message *mwi_msg)
void ast_smdi_mwi_message_putback (struct ast_smdi_interface *iface, struct ast_smdi_mwi_message *mwi_msg)
 Put an SMDI message back in the front of the queue.
ast_smdi_mwi_messageast_smdi_mwi_message_wait (struct ast_smdi_interface *iface, int timeout)
 Get the next SMDI message from the queue.
ast_smdi_mwi_messageast_smdi_mwi_message_wait_station (struct ast_smdi_interface *iface, int timeout, const char *station)
int ast_smdi_mwi_set (struct ast_smdi_interface *iface, const char *mailbox)
 Set the MWI indicator for a mailbox.
int ast_smdi_mwi_unset (struct ast_smdi_interface *iface, const char *mailbox)
 Unset the MWI indicator for a mailbox.
static void destroy_all_mailbox_mappings (void)
static void destroy_mailbox_mapping (struct mailbox_mapping *mm)
static int load_module (void)
static int lock_msg_q (struct ast_smdi_interface *iface, enum smdi_message_type type)
static struct timeval msg_timestamp (void *msg, enum smdi_message_type type)
static void * mwi_monitor_handler (void *data)
static void poll_mailbox (struct mailbox_mapping *mm)
static void purge_old_messages (struct ast_smdi_interface *iface, enum smdi_message_type type)
static int reload (void)
static int smdi_load (int reload)
static void * smdi_message_wait (struct ast_smdi_interface *iface, int timeout, enum smdi_message_type type, const char *search_key, struct ast_flags options)
static void smdi_msg_datastore_destroy (void *data)
static void * smdi_msg_find (struct ast_smdi_interface *iface, enum smdi_message_type type, const char *search_key, struct ast_flags options)
static void * smdi_msg_pop (struct ast_smdi_interface *iface, enum smdi_message_type type)
static int smdi_msg_read (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
static int smdi_msg_retrieve_read (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
static void * smdi_read (void *iface_p)
static int smdi_toggle_mwi (struct ast_smdi_interface *iface, const char *mailbox, int on)
static void * unlink_from_msg_q (struct ast_smdi_interface *iface, enum smdi_message_type type)
static int unload_module (void)
static int unlock_msg_q (struct ast_smdi_interface *iface, enum smdi_message_type type)
static void unref_msg (void *msg, enum smdi_message_type type)

Variables

static const char config_file [] = "smdi.conf"
struct {
   ast_cond_t   cond
   ast_mutex_t   lock
   pthread_t   thread
mwi_monitor
 Data that gets used by the SMDI MWI monitoring thread.
ast_smdi_interface_container smdi_ifaces
 SMDI interface container.
static struct ast_datastore_info smdi_msg_datastore_info
static struct ast_custom_function smdi_msg_function
static int smdi_msg_id
static struct ast_custom_function smdi_msg_retrieve_function


Detailed Description

SMDI support for Asterisk.

Author:
Matthew A. Nicholson <mnicholson@digium.com>

Russell Bryant <russell@digium.com>

Here is a useful mailing list post that describes SMDI protocol details: http://lists.digium.com/pipermail/asterisk-dev/2003-June/000884.html

Definition in file res_smdi.c.


Define Documentation

#define DEFAULT_POLLING_INTERVAL   10

10 seconds

Definition at line 112 of file res_smdi.c.

#define SMDI_MSG_EXPIRY_TIME   30000

Definition at line 58 of file res_smdi.c.

Referenced by smdi_load().

#define SMDI_RETRIEVE_TIMEOUT_DEFAULT   3000

In milliseconds

Definition at line 1093 of file res_smdi.c.

Referenced by smdi_msg_retrieve_read().


Enumeration Type Documentation

anonymous enum

Enumerator:
OPT_SEARCH_TERMINAL 
OPT_SEARCH_NUMBER 

Definition at line 372 of file res_smdi.c.

00372      {
00373    OPT_SEARCH_TERMINAL = (1 << 0),
00374    OPT_SEARCH_NUMBER   = (1 << 1),
00375 };

enum smdi_message_type

Enumerator:
SMDI_MWI 
SMDI_MD 

Definition at line 248 of file res_smdi.c.

00248                        {
00249    SMDI_MWI,
00250    SMDI_MD,
00251 };


Function Documentation

static struct ast_smdi_interface* alloc_smdi_interface ( void   )  [static]

Definition at line 808 of file res_smdi.c.

References ast_calloc, ast_cond_init(), ast_mutex_init(), ASTOBJ_CONTAINER_INIT, and ASTOBJ_INIT.

00809 {
00810    struct ast_smdi_interface *iface;
00811 
00812    if (!(iface = ast_calloc(1, sizeof(*iface))))
00813       return NULL;
00814 
00815    ASTOBJ_INIT(iface);
00816    ASTOBJ_CONTAINER_INIT(&iface->md_q);
00817    ASTOBJ_CONTAINER_INIT(&iface->mwi_q);
00818 
00819    ast_mutex_init(&iface->md_q_lock);
00820    ast_cond_init(&iface->md_q_cond, NULL);
00821 
00822    ast_mutex_init(&iface->mwi_q_lock);
00823    ast_cond_init(&iface->mwi_q_cond, NULL);
00824 
00825    return iface;
00826 }

static void append_mailbox_mapping ( struct ast_variable var,
struct ast_smdi_interface iface 
) [static]

Definition at line 729 of file res_smdi.c.

References ast_calloc, AST_LIST_INSERT_TAIL, ast_mutex_lock(), ast_mutex_unlock(), ast_strdupa, ast_string_field_init, ast_string_field_set, ast_strlen_zero(), ASTOBJ_REF, context, free, mailbox_mapping::iface, mailbox, mwi_monitor, strsep(), and var.

00730 {
00731    struct mailbox_mapping *mm;
00732    char *mailbox, *context;
00733 
00734    if (!(mm = ast_calloc(1, sizeof(*mm))))
00735       return;
00736    
00737    if (ast_string_field_init(mm, 32)) {
00738       free(mm);
00739       return;
00740    }
00741 
00742    ast_string_field_set(mm, smdi, var->name);
00743 
00744    context = ast_strdupa(var->value);
00745    mailbox = strsep(&context, "@");
00746    if (ast_strlen_zero(context))
00747       context = "default";
00748 
00749    ast_string_field_set(mm, mailbox, mailbox);
00750    ast_string_field_set(mm, context, context);
00751 
00752    mm->iface = ASTOBJ_REF(iface);
00753 
00754    ast_mutex_lock(&mwi_monitor.lock);
00755    AST_LIST_INSERT_TAIL(&mwi_monitor.mailbox_mappings, mm, entry);
00756    ast_mutex_unlock(&mwi_monitor.lock);
00757 }

AST_APP_OPTIONS ( smdi_msg_ret_options  ,
BEGIN_OPTIONS   AST_APP_OPTION('t', OPT_SEARCH_TERMINAL),
AST_APP_OPTION('n', OPT_SEARCH_NUMBER)  ,
END_OPTIONS   
)

AST_MODULE_INFO ( ASTERISK_GPL_KEY  ,
AST_MODFLAG_GLOBAL_SYMBOLS  ,
"Simplified Message Desk Interface (SMDI) Resource"  ,
load = load_module,
unload = unload_module,
reload = reload 
)

static void ast_smdi_interface_destroy ( struct ast_smdi_interface iface  )  [static]

Definition at line 132 of file res_smdi.c.

References ast_cond_destroy(), ast_module_unref(), ast_mutex_destroy(), AST_PTHREADT_NULL, AST_PTHREADT_STOP, ast_smdi_md_message_destroy(), ast_smdi_mwi_message_destroy(), ASTOBJ_CONTAINER_DESTROY, ASTOBJ_CONTAINER_DESTROYALL, ast_smdi_interface::file, free, mailbox_mapping::iface, ast_smdi_interface::md_q, ast_smdi_interface::md_q_cond, ast_smdi_interface::md_q_lock, ast_smdi_interface::mwi_q, ast_smdi_interface::mwi_q_cond, ast_smdi_interface::mwi_q_lock, and ast_smdi_interface::thread.

Referenced by ast_smdi_interface_unref(), destroy_mailbox_mapping(), smdi_msg_datastore_destroy(), smdi_msg_retrieve_read(), smdi_read(), and unload_module().

00133 {
00134    if (iface->thread != AST_PTHREADT_NULL && iface->thread != AST_PTHREADT_STOP) {
00135       pthread_cancel(iface->thread);
00136       pthread_join(iface->thread, NULL);
00137    }
00138    
00139    iface->thread = AST_PTHREADT_STOP;
00140    
00141    if (iface->file) 
00142       fclose(iface->file);
00143    
00144    ASTOBJ_CONTAINER_DESTROYALL(&iface->md_q, ast_smdi_md_message_destroy);
00145    ASTOBJ_CONTAINER_DESTROYALL(&iface->mwi_q, ast_smdi_mwi_message_destroy);
00146    ASTOBJ_CONTAINER_DESTROY(&iface->md_q);
00147    ASTOBJ_CONTAINER_DESTROY(&iface->mwi_q);
00148 
00149    ast_mutex_destroy(&iface->md_q_lock);
00150    ast_cond_destroy(&iface->md_q_cond);
00151 
00152    ast_mutex_destroy(&iface->mwi_q_lock);
00153    ast_cond_destroy(&iface->mwi_q_cond);
00154 
00155    free(iface);
00156 
00157    ast_module_unref(ast_module_info->self);
00158 }

struct ast_smdi_interface* ast_smdi_interface_find ( const char *  iface_name  ) 

Find an SMDI interface with the specified name.

Parameters:
iface_name the name/port of the interface to search for.
Returns:
a pointer to the interface located or NULL if none was found. This actually returns an ASTOBJ reference and should be released using ASTOBJ_UNREF(iface, ast_smdi_interface_destroy).

Definition at line 505 of file res_smdi.c.

References ASTOBJ_CONTAINER_FIND, and smdi_ifaces.

Referenced by load_config(), and smdi_msg_retrieve_read().

00506 {
00507    return (ASTOBJ_CONTAINER_FIND(&smdi_ifaces, iface_name));
00508 }

void ast_smdi_interface_unref ( struct ast_smdi_interface iface  ) 

Definition at line 160 of file res_smdi.c.

References ast_smdi_interface_destroy(), ASTOBJ_UNREF, and mailbox_mapping::iface.

Referenced by destroy_dahdi_pvt().

void ast_smdi_md_message_destroy ( struct ast_smdi_md_message msg  ) 

ast_smdi_md_message destructor.

Definition at line 702 of file res_smdi.c.

References free.

Referenced by ast_smdi_interface_destroy(), smdi_msg_datastore_destroy(), smdi_msg_retrieve_read(), and unref_msg().

00703 {
00704    free(msg);
00705 }

struct ast_smdi_md_message* ast_smdi_md_message_pop ( struct ast_smdi_interface iface  ) 

Get the next SMDI message from the queue.

Parameters:
iface a pointer to the interface to use.
This function pulls the first unexpired message from the SMDI message queue on the specified interface. It will purge all expired SMDI messages before returning.

Returns:
the next SMDI message, or NULL if there were no pending messages.

Definition at line 476 of file res_smdi.c.

References SMDI_MD, and smdi_msg_pop().

00477 {
00478    return smdi_msg_pop(iface, SMDI_MD);
00479 }

static void ast_smdi_md_message_push ( struct ast_smdi_interface iface,
struct ast_smdi_md_message md_msg 
) [static]

Definition at line 171 of file res_smdi.c.

References ast_cond_broadcast(), ast_mutex_lock(), ast_mutex_unlock(), ASTOBJ_CONTAINER_LINK_END, mailbox_mapping::iface, ast_smdi_interface::md_q, ast_smdi_interface::md_q_cond, and ast_smdi_interface::md_q_lock.

Referenced by purge_old_messages().

void ast_smdi_md_message_putback ( struct ast_smdi_interface iface,
struct ast_smdi_md_message msg 
)

Put an SMDI message back in the front of the queue.

Parameters:
iface a pointer to the interface to use.
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 some reason, and the message needs to be returned to the queue.

Definition at line 232 of file res_smdi.c.

References ast_cond_broadcast(), ast_mutex_lock(), ast_mutex_unlock(), ASTOBJ_CONTAINER_LINK_START, mailbox_mapping::iface, ast_smdi_interface::md_q, ast_smdi_interface::md_q_cond, and ast_smdi_interface::md_q_lock.

struct ast_smdi_md_message* ast_smdi_md_message_wait ( struct ast_smdi_interface iface,
int  timeout 
)

Get the next SMDI message from the queue.

Parameters:
iface a pointer to the interface to use.
timeout the time to wait before returning in milliseconds.
This function pulls a message from the SMDI message queue on the specified interface. If no message is available this function will wait the specified amount of time before returning.

Returns:
the next SMDI message, or NULL if there were no pending messages and the timeout has expired.

Definition at line 481 of file res_smdi.c.

References SMDI_MD, and smdi_message_wait().

Referenced by ss_thread().

00482 {
00483    struct ast_flags options = { 0 };
00484    return smdi_message_wait(iface, timeout, SMDI_MD, NULL, options);
00485 }

void ast_smdi_mwi_message_destroy ( struct ast_smdi_mwi_message msg  ) 

ast_smdi_mwi_message destructor.

Definition at line 707 of file res_smdi.c.

References free.

Referenced by ast_smdi_interface_destroy(), run_externnotify(), and unref_msg().

00708 {
00709    free(msg);
00710 }

struct ast_smdi_mwi_message* ast_smdi_mwi_message_pop ( struct ast_smdi_interface iface  ) 

Get the next SMDI message from the queue.

Parameters:
iface a pointer to the interface to use.
This function pulls the first unexpired message from the SMDI message queue on the specified interface. It will purge all expired SMDI messages before returning.

Returns:
the next SMDI message, or NULL if there were no pending messages.

Definition at line 487 of file res_smdi.c.

References smdi_msg_pop(), and SMDI_MWI.

00488 {
00489    return smdi_msg_pop(iface, SMDI_MWI);
00490 }

static void ast_smdi_mwi_message_push ( struct ast_smdi_interface iface,
struct ast_smdi_mwi_message mwi_msg 
) [static]

Definition at line 185 of file res_smdi.c.

References ast_cond_broadcast(), ast_mutex_lock(), ast_mutex_unlock(), ASTOBJ_CONTAINER_LINK_END, mailbox_mapping::iface, ast_smdi_interface::mwi_q, ast_smdi_interface::mwi_q_cond, and ast_smdi_interface::mwi_q_lock.

Referenced by purge_old_messages().

00186 {
00187    ast_mutex_lock(&iface->mwi_q_lock);
00188    ASTOBJ_CONTAINER_LINK_END(&iface->mwi_q, mwi_msg);
00189    ast_cond_broadcast(&iface->mwi_q_cond);
00190    ast_mutex_unlock(&iface->mwi_q_lock);
00191 }

void ast_smdi_mwi_message_putback ( struct ast_smdi_interface iface,
struct ast_smdi_mwi_message msg 
)

Put an SMDI message back in the front of the queue.

Parameters:
iface a pointer to the interface to use.
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 some reason, and the message needs to be returned to the queue.

Definition at line 240 of file res_smdi.c.

References ast_cond_broadcast(), ast_mutex_lock(), ast_mutex_unlock(), ASTOBJ_CONTAINER_LINK_START, mailbox_mapping::iface, ast_smdi_interface::mwi_q, ast_smdi_interface::mwi_q_cond, and ast_smdi_interface::mwi_q_lock.

00241 {
00242    ast_mutex_lock(&iface->mwi_q_lock);
00243    ASTOBJ_CONTAINER_LINK_START(&iface->mwi_q, mwi_msg);
00244    ast_cond_broadcast(&iface->mwi_q_cond);
00245    ast_mutex_unlock(&iface->mwi_q_lock);
00246 }

struct ast_smdi_mwi_message* ast_smdi_mwi_message_wait ( struct ast_smdi_interface iface,
int  timeout 
)

Get the next SMDI message from the queue.

Parameters:
iface a pointer to the interface to use.
timeout the time to wait before returning in milliseconds.
This function pulls a message from the SMDI message queue on the specified interface. If no message is available this function will wait the specified amount of time before returning.

Returns:
the next SMDI message, or NULL if there were no pending messages and the timeout has expired.

Definition at line 492 of file res_smdi.c.

References smdi_message_wait(), and SMDI_MWI.

00493 {
00494    struct ast_flags options = { 0 };
00495    return smdi_message_wait(iface, timeout, SMDI_MWI, NULL, options);
00496 }

struct ast_smdi_mwi_message* ast_smdi_mwi_message_wait_station ( struct ast_smdi_interface iface,
int  timeout,
const char *  station 
)

Definition at line 498 of file res_smdi.c.

References smdi_message_wait(), and SMDI_MWI.

Referenced by run_externnotify().

00500 {
00501    struct ast_flags options = { 0 };
00502    return smdi_message_wait(iface, timeout, SMDI_MWI, station, options);
00503 }

int ast_smdi_mwi_set ( struct ast_smdi_interface iface,
const char *  mailbox 
)

Set the MWI indicator for a mailbox.

Parameters:
iface the interface to use.
mailbox the mailbox to use.

Definition at line 222 of file res_smdi.c.

References mailbox_mapping::iface, and smdi_toggle_mwi().

Referenced by poll_mailbox(), and run_externnotify().

00223 {
00224    return smdi_toggle_mwi(iface, mailbox, 1);
00225 }

int ast_smdi_mwi_unset ( struct ast_smdi_interface iface,
const char *  mailbox 
)

Unset the MWI indicator for a mailbox.

Parameters:
iface the interface to use.
mailbox the mailbox to use.

Definition at line 227 of file res_smdi.c.

References mailbox_mapping::iface, and smdi_toggle_mwi().

Referenced by poll_mailbox(), and run_externnotify().

00228 {
00229    return smdi_toggle_mwi(iface, mailbox, 0);
00230 }

static void destroy_all_mailbox_mappings ( void   )  [static]

Definition at line 719 of file res_smdi.c.

References AST_LIST_REMOVE_HEAD, ast_mutex_lock(), ast_mutex_unlock(), destroy_mailbox_mapping(), and mwi_monitor.

Referenced by unload_module().

00720 {
00721    struct mailbox_mapping *mm;
00722 
00723    ast_mutex_lock(&mwi_monitor.lock);
00724    while ((mm = AST_LIST_REMOVE_HEAD(&mwi_monitor.mailbox_mappings, entry)))
00725       destroy_mailbox_mapping(mm);
00726    ast_mutex_unlock(&mwi_monitor.lock);
00727 }

static void destroy_mailbox_mapping ( struct mailbox_mapping mm  )  [static]

Definition at line 712 of file res_smdi.c.

References ast_smdi_interface_destroy(), ast_string_field_free_memory, ASTOBJ_UNREF, free, and mailbox_mapping::iface.

Referenced by destroy_all_mailbox_mappings().

00713 {
00714    ast_string_field_free_memory(mm);
00715    ASTOBJ_UNREF(mm->iface, ast_smdi_interface_destroy);
00716    free(mm);
00717 }

static int load_module ( void   )  [static]

Definition at line 1316 of file res_smdi.c.

References ast_cond_init(), ast_custom_function_register(), ast_log(), AST_MODULE_LOAD_DECLINE, ast_mutex_init(), ASTOBJ_CONTAINER_INIT, LOG_WARNING, mwi_monitor, smdi_ifaces, smdi_load(), smdi_msg_function, and smdi_msg_retrieve_function.

01317 {
01318    int res;
01319 
01320    /* initialize our containers */
01321    memset(&smdi_ifaces, 0, sizeof(smdi_ifaces));
01322    ASTOBJ_CONTAINER_INIT(&smdi_ifaces);
01323 
01324    ast_mutex_init(&mwi_monitor.lock);
01325    ast_cond_init(&mwi_monitor.cond, NULL);
01326 
01327    ast_custom_function_register(&smdi_msg_retrieve_function);
01328    ast_custom_function_register(&smdi_msg_function);
01329 
01330    /* load the config and start the listener threads*/
01331    res = smdi_load(0);
01332    if (res < 0) {
01333       return res;
01334    } else if (res == 1) {
01335       ast_log(LOG_WARNING, "No SMDI interfaces are available to listen on, not starting SMDI listener.\n");
01336       return AST_MODULE_LOAD_DECLINE;
01337    }
01338 
01339    return 0;
01340 }

static int lock_msg_q ( struct ast_smdi_interface iface,
enum smdi_message_type  type 
) [inline, static]

Definition at line 253 of file res_smdi.c.

References ast_mutex_lock(), mailbox_mapping::iface, ast_smdi_interface::md_q_lock, ast_smdi_interface::mwi_q_lock, SMDI_MD, and SMDI_MWI.

Referenced by purge_old_messages(), smdi_message_wait(), and smdi_msg_pop().

00254 {
00255    switch (type) {
00256    case SMDI_MWI:
00257       return ast_mutex_lock(&iface->mwi_q_lock);
00258    case SMDI_MD:  
00259       return ast_mutex_lock(&iface->md_q_lock);
00260    }
00261    
00262    return -1;
00263 }

static struct timeval msg_timestamp ( void *  msg,
enum smdi_message_type  type 
) [inline, static]

Definition at line 289 of file res_smdi.c.

References SMDI_MD, SMDI_MWI, ast_smdi_mwi_message::timestamp, and type.

Referenced by purge_old_messages().

00290 {
00291    struct ast_smdi_md_message *md_msg = msg;
00292    struct ast_smdi_mwi_message *mwi_msg = msg;
00293 
00294    switch (type) {
00295    case SMDI_MWI:
00296       return mwi_msg->timestamp;
00297    case SMDI_MD:
00298       return md_msg->timestamp;
00299    }
00300 
00301    return ast_tv(0, 0);
00302 }

static void* mwi_monitor_handler ( void *  data  )  [static]

Definition at line 781 of file res_smdi.c.

References ast_cond_timedwait(), AST_LIST_TRAVERSE, ast_mutex_lock(), ast_mutex_unlock(), ast_tvadd(), mwi_monitor, and poll_mailbox().

00782 {
00783    while (!mwi_monitor.stop) {
00784       struct timespec ts = { 0, };
00785       struct timeval tv;
00786       struct mailbox_mapping *mm;
00787 
00788       ast_mutex_lock(&mwi_monitor.lock);
00789 
00790       mwi_monitor.last_poll = ast_tvnow();
00791 
00792       AST_LIST_TRAVERSE(&mwi_monitor.mailbox_mappings, mm, entry)
00793          poll_mailbox(mm);
00794 
00795       /* Sleep up to the configured polling interval.  Allow unload_module()
00796        * to signal us to wake up and exit. */
00797       tv = ast_tvadd(mwi_monitor.last_poll, ast_tv(mwi_monitor.polling_interval, 0));
00798       ts.tv_sec = tv.tv_sec;
00799       ts.tv_nsec = tv.tv_usec * 1000;
00800       ast_cond_timedwait(&mwi_monitor.cond, &mwi_monitor.lock, &ts);
00801 
00802       ast_mutex_unlock(&mwi_monitor.lock);
00803    }
00804 
00805    return NULL;
00806 }

static void poll_mailbox ( struct mailbox_mapping mm  )  [static]

Note:
Called with the mwi_monitor.lock locked

Definition at line 762 of file res_smdi.c.

References ast_app_has_voicemail(), ast_smdi_mwi_set(), ast_smdi_mwi_unset(), mailbox_mapping::cur_state, and mailbox_mapping::iface.

Referenced by mwi_monitor_handler().

00763 {
00764    char buf[1024];
00765    unsigned int state;
00766 
00767    snprintf(buf, sizeof(buf), "%s@%s", mm->mailbox, mm->context);
00768 
00769    state = !!ast_app_has_voicemail(mm->mailbox, NULL);
00770 
00771    if (state != mm->cur_state) {
00772       if (state)
00773          ast_smdi_mwi_set(mm->iface, mm->smdi);
00774       else
00775          ast_smdi_mwi_unset(mm->iface, mm->smdi);
00776 
00777       mm->cur_state = state;
00778    }
00779 }

static void purge_old_messages ( struct ast_smdi_interface iface,
enum smdi_message_type  type 
) [static]

Definition at line 317 of file res_smdi.c.

References ast_log(), ast_smdi_md_message_push(), ast_smdi_mwi_message_push(), mailbox_mapping::iface, lock_msg_q(), LOG_NOTICE, ast_smdi_interface::msg_expiry, msg_timestamp(), SMDI_MD, SMDI_MWI, unlink_from_msg_q(), unlock_msg_q(), and unref_msg().

Referenced by smdi_msg_find(), and smdi_msg_pop().

00318 {
00319    struct timeval now;
00320    long elapsed = 0;
00321    void *msg;
00322    
00323    lock_msg_q(iface, type);
00324    msg = unlink_from_msg_q(iface, type);
00325    unlock_msg_q(iface, type);
00326 
00327    /* purge old messages */
00328    now = ast_tvnow();
00329    while (msg) {
00330       elapsed = ast_tvdiff_ms(now, msg_timestamp(msg, type));
00331 
00332       if (elapsed > iface->msg_expiry) {
00333          /* found an expired message */
00334          unref_msg(msg, type);
00335          ast_log(LOG_NOTICE, "Purged expired message from %s SMDI %s message queue.  "
00336             "Message was %ld milliseconds too old.\n",
00337             iface->name, (type == SMDI_MD) ? "MD" : "MWI", 
00338             elapsed - iface->msg_expiry);
00339 
00340          lock_msg_q(iface, type);
00341          msg = unlink_from_msg_q(iface, type);
00342          unlock_msg_q(iface, type);
00343       } else {
00344          /* good message, put it back and return */
00345          switch (type) {
00346          case SMDI_MD:
00347             ast_smdi_md_message_push(iface, msg);
00348             break;
00349          case SMDI_MWI:
00350             ast_smdi_mwi_message_push(iface, msg);
00351             break;
00352          }
00353          unref_msg(msg, type);
00354          break;
00355       }
00356    }
00357 }

static int reload ( void   )  [static]

Definition at line 1365 of file res_smdi.c.

References ast_log(), LOG_WARNING, and smdi_load().

01366 {
01367    int res;
01368 
01369    res = smdi_load(1);
01370 
01371    if (res < 0) {
01372       return res;
01373    } else if (res == 1) {
01374       ast_log(LOG_WARNING, "No SMDI interfaces were specified to listen on, not starting SDMI listener.\n");
01375       return 0;
01376    } else
01377       return 0;
01378 }

static int smdi_load ( int  reload  )  [static]

Definition at line 838 of file res_smdi.c.

References ast_config_load(), ast_log(), ast_variable_browse(), ASTOBJ_CONTAINER_MARKALL, ast_variable::lineno, LOG_NOTICE, ast_smdi_interface::msdstrip, ast_smdi_interface::msg_expiry, ast_variable::name, ast_variable::next, smdi_ifaces, SMDI_MSG_EXPIRY_TIME, and ast_variable::value.

Referenced by load_module(), and reload().

00839 {
00840    struct ast_config *conf;
00841    struct ast_variable *v;
00842    struct ast_smdi_interface *iface = NULL;
00843    int res = 0;
00844 
00845    /* Config options */
00846    speed_t baud_rate = B9600;     /* 9600 baud rate */
00847    tcflag_t paritybit = PARENB;   /* even parity checking */
00848    tcflag_t charsize = CS7;       /* seven bit characters */
00849    int stopbits = 0;              /* One stop bit */
00850    
00851    int