50 #define AST_API_MODULE
62 #define SMDI_MSG_EXPIRY_TIME 30000
211 #define DEFAULT_POLLING_INTERVAL 10
234 pthread_cancel(iface->
thread);
235 pthread_join(iface->
thread, NULL);
297 if (!(file = fopen(iface->
name,
"w"))) {
304 fprintf(file,
"%s:MWI ", on ?
"OP" :
"RMV");
306 for (i = 0; i < iface->
msdstrip; i++)
309 fprintf(file,
"%s!\x04", mailbox);
314 ast_debug(1,
"Sent MWI set message for %s on %s\n", mailbox, iface->
name);
433 "Message was %ld milliseconds too old.\n",
500 if (!strcasecmp(iterator->mesg_desk_term, search_key))
511 if (!strcasecmp(iterator->mesg_desk_num, search_key))
545 struct timeval start;
564 while (diff < timeout) {
565 struct timespec ts = { 0, };
570 if ((msg =
smdi_msg_find(iface, type, search_key, options))) {
576 ts.tv_sec = wait.tv_sec;
577 ts.tv_nsec = wait.tv_usec * 1000;
584 if ((msg =
smdi_msg_find(iface, type, search_key, options))) {
652 while ((c = fgetc(iface->
file))) {
668 if (!(md_msg =
ast_calloc(1,
sizeof(*md_msg)))) {
702 for (i = 0; i <
sizeof(md_msg->
fwd_st) - 1; i++) {
703 if ((c = fgetc(iface->
file)) ==
' ') {
705 ast_log(
LOG_DEBUG,
"Read a space, done looking for the forwarding station\n");
711 ast_log(
LOG_DEBUG,
"Read a '%c' and stored it in the forwarding station buffer\n", c);
714 ast_log(
LOG_DEBUG,
"Read a '%c', but didn't store it in the fwd station buffer, because of the msdstrip setting (%d < %d)\n", c, i, iface->
msdstrip);
730 for (i = 0; i <
sizeof(md_msg->
calling_st) - 1; i++) {
731 if (!isdigit((c = fgetc(iface->
file)))) {
733 ast_log(
LOG_DEBUG,
"Read a '%c', but didn't store it in the calling station buffer because it's not a digit\n", c);
745 ast_log(
LOG_DEBUG,
"Read a '%c' and stored it in the calling station buffer\n", c);
748 ast_log(
LOG_DEBUG,
"Read a '%c', but didn't store it in the calling station buffer, because of the msdstrip setting (%d < %d)\n", c, i, iface->
msdstrip);
765 }
else if (c ==
'W') {
768 ast_log(
LOG_DEBUG,
"Read a 'W', it's an MWI message. (No more debug coming for MWI messages)\n");
770 if (!(mwi_msg =
ast_calloc(1,
sizeof(*mwi_msg)))) {
782 for (i = 0; i <
sizeof(mwi_msg->
fwd_st) - 1; i++) {
783 if ((c = fgetc(iface->
file)) ==
' ') {
802 for (i = 0; i <
sizeof(mwi_msg->
cause) - 1; i++)
805 mwi_msg->
cause[
sizeof(mwi_msg->
cause) - 1] =
'\0';
819 ast_log(
LOG_ERROR,
"Error reading from SMDI interface %s, stopping listener thread\n", iface->
name);
862 mailbox =
strsep(&context,
"@");
901 struct timespec ts = { 0, };
902 struct timeval polltime;
915 ts.tv_sec = polltime.tv_sec;
916 ts.tv_nsec = polltime.tv_usec * 1000;
964 speed_t baud_rate = B9600;
965 tcflag_t paritybit = PARENB;
966 tcflag_t charsize = CS7;
974 ast_log(
LOG_NOTICE,
"Unable to reload config %s: SMDI untouched\n", config_file);
990 if (!strcasecmp(v->
name,
"baudrate")) {
991 if (!strcasecmp(v->
value,
"9600"))
993 else if (!strcasecmp(v->
value,
"4800"))
995 else if (!strcasecmp(v->
value,
"2400"))
997 else if (!strcasecmp(v->
value,
"1200"))
1003 }
else if (!strcasecmp(v->
name,
"msdstrip")) {
1004 if (!sscanf(v->
value,
"%30d", &msdstrip)) {
1007 }
else if (0 > msdstrip || msdstrip > 9) {
1011 }
else if (!strcasecmp(v->
name,
"msgexpirytime")) {
1012 if (!sscanf(v->
value,
"%30ld", &msg_expiry)) {
1016 }
else if (!strcasecmp(v->
name,
"paritybit")) {
1017 if (!strcasecmp(v->
value,
"even"))
1019 else if (!strcasecmp(v->
value,
"odd"))
1020 paritybit = PARENB | PARODD;
1021 else if (!strcasecmp(v->
value,
"none"))
1022 paritybit = ~PARENB;
1027 }
else if (!strcasecmp(v->
name,
"charsize")) {
1028 if (!strcasecmp(v->
value,
"7"))
1030 else if (!strcasecmp(v->
value,
"8"))
1033 ast_log(
LOG_NOTICE,
"Invalid character size setting in %s (line %d), using default\n", config_file, v->
lineno);
1036 }
else if (!strcasecmp(v->
name,
"twostopbits")) {
1038 }
else if (!strcasecmp(v->
name,
"smdiport")) {
1065 if (!(iface->
file = fopen(iface->
name,
"r"))) {
1071 iface->
fd = fileno(iface->
file);
1076 if (tcgetattr(iface->
fd, &iface->
mode)) {
1083 if (cfsetispeed(&iface->
mode, baud_rate) || cfsetospeed(&iface->
mode, baud_rate)) {
1091 iface->
mode.c_cflag = iface->
mode.c_cflag | CSTOPB;
1093 iface->
mode.c_cflag = iface->
mode.c_cflag & ~CSTOPB;
1096 iface->
mode.c_cflag = (iface->
mode.c_cflag & ~PARENB & ~PARODD) | paritybit;
1099 iface->
mode.c_cflag = (iface->
mode.c_cflag & ~CSIZE) | charsize;
1102 if (tcsetattr(iface->
fd, TCSAFLUSH, &iface->
mode)) {
1115 ast_verb(3,
"Starting SMDI monitor thread for %s\n", iface->
name);
1136 if (!strcasecmp(v->
name,
"smdiport")) {
1144 }
else if (!strcasecmp(v->
name,
"pollinginterval")) {
1151 ast_log(
LOG_ERROR,
"Mailbox mapping ignored, no valid SMDI interface specified in mailboxes section\n");
1165 ast_log(
LOG_ERROR,
"Failed to start MWI monitoring thread. This module will not operate.\n");
1209 #define SMDI_RETRIEVE_TIMEOUT_DEFAULT 3000
1266 if (sscanf(
args.timeout,
"%30u", &timeout) != 1) {
1274 "waiting %u ms.\n",
args.search_key, timeout);
1284 snprintf(buf, len,
"%u", smd->
id);
1289 datastore->
data = smd;
1304 if (smd && !datastore)
1361 smd = datastore->
data;
1363 if (!strcasecmp(
args.component,
"number")) {
1365 }
else if (!strcasecmp(
args.component,
"terminal")) {
1367 }
else if (!strcasecmp(
args.component,
"station")) {
1369 }
else if (!strcasecmp(
args.component,
"callerid")) {
1371 }
else if (!strcasecmp(
args.component,
"type")) {
1388 .
name =
"SMDI_MSG_RETRIEVE",
1416 }
else if (res == 1) {
1418 ast_log(
LOG_NOTICE,
"No SMDI interfaces are available to listen on, not starting SMDI listener.\n");
1471 }
else if (res == 1) {
1472 ast_log(
LOG_WARNING,
"No SMDI interfaces were specified to listen on, not starting SDMI listener.\n");
SMDI message desk message queue.
struct ast_smdi_md_queue md_q
enum sip_cc_notify_state state
#define ast_channel_lock(chan)
Main Channel structure associated with a channel.
char fwd_st[SMDI_MAX_STATION_NUM_LEN+1]
Asterisk locking-related definitions:
static int unlock_msg_q(struct ast_smdi_interface *iface, enum smdi_message_type type)
Asterisk main include file. File version handling, generic pbx functions.
#define AST_APP_OPTIONS(holder, options...)
Declares an array of options for an application.
static void * smdi_msg_pop(struct ast_smdi_interface *iface, enum smdi_message_type type)
void ast_module_unref(struct ast_module *)
#define ASTOBJ_CONTAINER_RDLOCK(container)
Lock an ASTOBJ_CONTAINER for reading.
static int smdi_load(int reload)
int ast_autoservice_start(struct ast_channel *chan)
Automatically service a channel for us...
char * strsep(char **str, const char *delims)
static struct @346 mwi_monitor
Data that gets used by the SMDI MWI monitoring thread.
#define ast_test_flag(p, flag)
unsigned int polling_interval
const ast_string_field context
Time-related functions and macros.
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.
static void purge_old_messages(struct ast_smdi_interface *iface, enum smdi_message_type type)
static void poll_mailbox(struct mailbox_mapping *mm)
static struct ast_custom_function smdi_msg_retrieve_function
char mesg_desk_num[SMDI_MESG_DESK_NUM_LEN+1]
int ast_app_has_voicemail(const char *mailbox, const char *folder)
Determine if a given mailbox has any voicemail If folder is NULL, defaults to "INBOX". If folder is "INBOX", includes the number of messages in the "Urgent" folder.
char calling_st[SMDI_MAX_STATION_NUM_LEN+1]
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category)
Goes through variables.
#define ASTOBJ_CONTAINER_UNLINK_START(container)
Remove an object from the front of a container.
static void destroy_mailbox_mapping(struct mailbox_mapping *mm)
int ast_app_parse_options(const struct ast_app_option *options, struct ast_flags *flags, char **args, char *optstr)
Parses a string containing application options and sets flags/arguments.
struct ast_smdi_interface * ast_smdi_interface_find(const char *iface_name)
Find an SMDI interface with the specified name.
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application's arguments.
#define ASTOBJ_UNMARK(object)
Unmark an ASTOBJ by subtracting the ASTOBJ_FLAG_MARKED flag from its objflags mask.
Structure for variables, used for configurations and for channel variables.
static int smdi_msg_retrieve_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
#define SMDI_MAX_FILENAME_LEN
Structure for a data store type.
Configuration File Parser.
#define ast_calloc_with_stringfields(n, type, size)
Allocate a structure with embedded stringfields in a single allocation.
#define ast_cond_init(cond, attr)
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
#define AST_DECLARE_STRING_FIELDS(field_list)
Declare the fields needed in a structure.
#define ASTOBJ_WRLOCK(object)
Lock an ASTOBJ for writing.
static void * smdi_msg_find(struct ast_smdi_interface *iface, enum smdi_message_type type, const char *search_key, struct ast_flags options)
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
#define ast_mutex_lock(a)
A mapping between an SMDI mailbox ID and an Asterisk mailbox.
#define AST_MODULE_INFO(keystr, flags_to_set, desc, fields...)
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Structure for a data store object.
struct ast_datastore * ast_channel_datastore_find(struct ast_channel *chan, const struct ast_datastore_info *info, const char *uid)
Find a datastore on a channel.
static struct ast_custom_function smdi_msg_function
I/O Management (derived from Cheops-NG)
SMDI interface container.
struct ast_smdi_interface * iface
#define ast_module_user_remove(user)
#define ast_cond_signal(cond)
#define ast_verb(level,...)
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.
void ast_config_destroy(struct ast_config *config)
Destroys a config.
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return * the previous value of *p. This can be used to handle reference co...
static void ast_smdi_interface_destroy(struct ast_smdi_interface *iface)
int ast_custom_function_unregister(struct ast_custom_function *acf)
Unregister a custom function.
String fields in structures.
pthread_cond_t ast_cond_t
char cause[SMDI_MWI_FAIL_CAUSE_LEN+1]
int ast_smdi_mwi_set(struct ast_smdi_interface *iface, const char *mailbox)
Set the MWI indicator for a mailbox.
#define ast_pthread_create_background(a, b, c, d)
static void ast_smdi_mwi_message_push(struct ast_smdi_interface *iface, struct ast_smdi_mwi_message *mwi_msg)
#define ASTOBJ_CONTAINER_INIT(container)
Initialize a container.
#define ASTOBJ_CONTAINER_LINK_START(container, newobj)
Add an object to the front of a container.
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)
struct ast_smdi_md_message * ast_smdi_md_message_pop(struct ast_smdi_interface *iface)
Get the next SMDI message from the queue.
static void destroy_all_mailbox_mappings(void)
#define SMDI_RETRIEVE_TIMEOUT_DEFAULT
void ast_smdi_interface_unref(struct ast_smdi_interface *iface)
#define ast_debug(level,...)
Log a DEBUG message.
struct ast_smdi_interface * iface
static struct timeval msg_timestamp(void *msg, enum smdi_message_type type)
General Asterisk PBX channel definitions.
#define ast_config_load(filename, flags)
Load a config file.
#define DEFAULT_POLLING_INTERVAL
#define AST_PTHREADT_NULL
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Data structure associated with a custom dialplan function.
#define AST_STRING_FIELD(name)
Declare a string field.
void ast_smdi_md_message_destroy(struct ast_smdi_md_message *msg)
ast_smdi_md_message destructor.
struct @346::@349 mailbox_mappings
#define ASTOBJ_INIT(object)
Initialize an object.
static int _unload_module(int fromload)
A set of macros to manage forward-linked lists.
static struct ast_smdi_interface_container smdi_ifaces
#define ast_cond_broadcast(cond)
struct mailbox_mapping::@348 entry
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
static int smdi_toggle_mwi(struct ast_smdi_interface *iface, const char *mailbox, int on)
An SMDI message desk message.
#define ast_module_user_add(chan)
Core PBX routines and definitions.
int ast_autoservice_stop(struct ast_channel *chan)
Stop servicing a channel for us...
#define ASTOBJ_UNREF(object, destructor)
Decrement the reference count on an object.
SMDI message waiting indicator message queue.
#define AST_LIST_HEAD_NOLOCK(name, type)
Defines a structure to be used to hold a list of specified type (with no lock).
#define ast_strdupa(s)
duplicate a string in memory from the stack
char mesg_desk_term[SMDI_MESG_DESK_TERM_LEN+1]
#define ASTOBJ_CONTAINER_DESTROY(container)
Destroy a container.
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
#define ASTOBJ_CONTAINER_DESTROYALL(container, destructor)
Empty a container.
A set of macros implementing objects and containers. Macros are used for maximum performance, to support multiple inheritance, and to be easily integrated into existing structures without additional malloc calls, etc.
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true". This function checks to see whether a string passed to it is an indication of an "true" value. It checks to see if the string is "yes", "true", "y", "t", "on" or "1".
static void * unlink_from_msg_q(struct ast_smdi_interface *iface, enum smdi_message_type type)
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.
#define ASTOBJ_CONTAINER_LINK(container, newobj)
Add an object to a container.
static struct ast_app_option smdi_msg_ret_options[128]
#define ASTOBJ_CONTAINER_LINK_END(container, newobj)
Add an object to the end of a container.
#define ASTOBJ_COMPONENTS_FULL(type, namelen, hashes)
Add ASTOBJ components to a struct (with locking support).
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
const ast_string_field mailbox
struct timeval ast_tvadd(struct timeval a, struct timeval b)
Returns the sum of two timevals a + b.
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
#define ast_cond_destroy(cond)
#define ASTOBJ_CONTAINER_TRAVERSE(container, continue, eval)
Iterate through the objects in a container.
struct ast_datastore * ast_datastore_alloc(const struct ast_datastore_info *info, const char *uid)
static void smdi_msg_datastore_destroy(void *data)
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
#define AST_LIST_ENTRY(type)
Declare a forward link structure inside a list entry.
#define ast_channel_unlock(chan)
static void parse(struct mgcp_request *req)
#define ASTOBJ_UNLOCK(object)
Unlock a locked object.
#define ASTOBJ_CONTAINER_FIND(container, namestr)
Find an object in a container.
#define ASTOBJ_CONTAINER_UNLOCK(container)
Unlock an ASTOBJ_CONTAINER.
struct ast_smdi_mwi_message * ast_smdi_mwi_message_pop(struct ast_smdi_interface *iface)
Get the next SMDI message from the queue.
SMDI support for Asterisk.
static void unref_msg(void *msg, enum smdi_message_type type)
char fwd_st[SMDI_MAX_STATION_NUM_LEN+1]
if(yyss+yystacksize-1<=yyssp)
Structure used to handle boolean flags.
static int unload_module(void)
static int lock_msg_q(struct ast_smdi_interface *iface, enum smdi_message_type type)
static int load_module(void)
static void append_mailbox_mapping(struct ast_variable *var, struct ast_smdi_interface *iface)
static int smdi_msg_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
ASTOBJ_CONTAINER_COMPONENTS(struct ast_smdi_interface)
static void * mwi_monitor_handler(void *data)
const ast_string_field smdi
ASTOBJ_CONTAINER_COMPONENTS(struct ast_smdi_mwi_message)
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
struct timeval ast_tv(ast_time_t sec, ast_suseconds_t usec)
Returns a timeval from sec, usec.
#define AST_PTHREADT_STOP
Application convenience functions, designed to give consistent look and feel to Asterisk apps...
void ast_smdi_mwi_message_destroy(struct ast_smdi_mwi_message *msg)
ast_smdi_mwi_message destructor.
#define SMDI_MSG_EXPIRY_TIME
static void * smdi_read(void *iface_p)
static struct ast_smdi_interface * alloc_smdi_interface(void)
#define ASTOBJ_CONTAINER_MARKALL(container)
Mark all the objects in a container.
struct ast_smdi_md_message * md_msg
#define AST_APP_ARG(name)
Define an application argument.
#define AST_OPTIONAL_API_NAME(name)
struct ast_variable * next
#define ast_mutex_init(pmutex)
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the 'standard' argument separation process for an application.
#define CONFIG_STATUS_FILEINVALID
int ast_smdi_mwi_unset(struct ast_smdi_interface *iface, const char *mailbox)
Unset the MWI indicator for a mailbox.
static char context[AST_MAX_CONTEXT]
static void ast_smdi_md_message_push(struct ast_smdi_interface *iface, struct ast_smdi_md_message *md_msg)
#define ast_mutex_destroy(a)
#define ASTERISK_GPL_KEY
The text the key() function should return.
#define ASTOBJ_REF(object)
Increment an object reference count.
struct ast_smdi_mwi_message * ast_smdi_mwi_message_wait_station(struct ast_smdi_interface *iface, int timeout, const char *station)
Asterisk module definitions.
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
#define ast_cond_timedwait(cond, mutex, time)
#define ast_custom_function_register(acf)
Register a custom function.
static const char config_file[]
ASTOBJ_CONTAINER_COMPONENTS(struct ast_smdi_md_message)
Structure for mutex and tracking information.
An SMDI message waiting indicator message.
static char mailbox[AST_MAX_EXTENSION]
struct ast_smdi_mwi_queue mwi_q
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.
#define ASTERISK_FILE_VERSION(file, version)
Register/unregister a source code file with the core.
#define ASTOBJ_CONTAINER_PRUNE_MARKED(container, destructor)
Prune marked objects from a container.
#define AST_APP_OPTION(option, flagno)
Declares an application option that does not accept an argument.
#define CONFIG_STATUS_FILEUNCHANGED
#define ast_mutex_unlock(a)
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
struct ast_module * ast_module_ref(struct ast_module *)
static struct ast_datastore_info smdi_msg_datastore_info