#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_interface * | alloc_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_interface * | ast_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_message * | ast_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_message * | ast_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_message * | ast_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_message * | ast_smdi_mwi_message_wait (struct ast_smdi_interface *iface, int timeout) |
| Get the next SMDI message from the queue. | |
| ast_smdi_mwi_message * | ast_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 |
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 DEFAULT_POLLING_INTERVAL 10 |
10 seconds
Definition at line 112 of file res_smdi.c.
| #define SMDI_MSG_EXPIRY_TIME 30000 |
| #define SMDI_RETRIEVE_TIMEOUT_DEFAULT 3000 |
| anonymous enum |
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 |
| 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.
| iface_name | the name/port of the interface to search for. |
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().
00161 { 00162 ASTOBJ_UNREF(iface, ast_smdi_interface_destroy); 00163 }
| 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.
| iface | a pointer to the interface to use. |
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().
00172 { 00173 ast_mutex_lock(&iface->md_q_lock); 00174 ASTOBJ_CONTAINER_LINK_END(&iface->md_q, md_msg); 00175 ast_cond_broadcast(&iface->md_q_cond); 00176 ast_mutex_unlock(&iface->md_q_lock); 00177 }
| 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.
| iface | a pointer to the interface to use. | |
| md_msg | a pointer to the message to use. |
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.
00233 { 00234 ast_mutex_lock(&iface->md_q_lock); 00235 ASTOBJ_CONTAINER_LINK_START(&iface->md_q, md_msg); 00236 ast_cond_broadcast(&iface->md_q_cond); 00237 ast_mutex_unlock(&iface->md_q_lock); 00238 }
| 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.
| iface | a pointer to the interface to use. | |
| timeout | the time to wait before returning in milliseconds. |
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.
| iface | a pointer to the interface to use. |
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.
| iface | a pointer to the interface to use. | |
| mwi_msg | a pointer to the message to use. |
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.
| iface | a pointer to the interface to use. | |
| timeout | the time to wait before returning in milliseconds. |
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.
| 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.
| 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] |
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