![]() |
Home page |
Mailing list |
Docs
Asterisk developer's documentation :: Codename Pineapple
res_smdi.c File Reference
Definition in file res_smdi.c.
#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 dependency graph for res_smdi.c:

Go to the source code of this file.
Data Structures | |
| struct | ast_smdi_interface_container |
| SMDI interface container. More... | |
Defines | |
| #define | SMDI_MSG_EXPIRY_TIME 30000 |
Functions | |
| AST_MODULE_INFO (ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS,"Simplified Message Desk Interface (SMDI) Resource",.load=load_module,.unload=unload_module,.reload=reload,) | |
| void | ast_smdi_interface_destroy (struct ast_smdi_interface *iface) |
| ast_smdi_interface destructor. | |
| ast_smdi_interface * | ast_smdi_interface_find (const char *iface_name) |
| Find an SMDI interface with the specified name. | |
| 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 *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 *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. | |
| 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 int | load_module (void) |
| static int | reload (void) |
| static int | smdi_load (int reload) |
| static void * | smdi_read (void *iface_p) |
| Read an SMDI message. | |
| static int | unload_module (void) |
Variables | |
| static const char | config_file [] = "smdi.conf" |
| module_symbols * | me |
| ast_smdi_interface_container | smdi_ifaces |
| SMDI interface container. | |
|
|
Definition at line 48 of file res_smdi.c. Referenced by smdi_load(). |
|
||||||||||||||||||||||||||||
|
|
|
|
|
Find an SMDI interface with the specified name.
Definition at line 323 of file res_smdi.c. References ASTOBJ_CONTAINER_FIND, and smdi_ifaces. 00324 { 00325 return (ASTOBJ_CONTAINER_FIND(&smdi_ifaces, iface_name)); 00326 }
|
|
|
ast_smdi_md_message destructor.
Definition at line 477 of file res_smdi.c. References free. Referenced by ast_smdi_interface_destroy(), and ast_smdi_md_message_pop(). 00478 { 00479 free(msg); 00480 }
|
|
|
Get the next SMDI message from the queue.
Definition at line 189 of file res_smdi.c. References ast_log(), ast_smdi_md_message_destroy(), ASTOBJ_CONTAINER_UNLINK_START, ASTOBJ_UNREF, LOG_NOTICE, ast_smdi_interface::md_q, ast_smdi_interface::msg_expiry, and ast_smdi_md_message::timestamp. Referenced by ast_smdi_md_message_wait(). 00190 { 00191 struct ast_smdi_md_message *md_msg = ASTOBJ_CONTAINER_UNLINK_START(&iface->md_q); 00192 struct timeval now; 00193 long elapsed = 0; 00194 00195 /* purge old messages */ 00196 now = ast_tvnow(); 00197 while (md_msg) { 00198 elapsed = ast_tvdiff_ms(now, md_msg->timestamp); 00199 00200 if (elapsed > iface->msg_expiry) { 00201 /* found an expired message */ 00202 ASTOBJ_UNREF(md_msg, ast_smdi_md_message_destroy); 00203 ast_log(LOG_NOTICE, "Purged expired message from %s SMDI MD message queue. Message was %ld milliseconds too old.\n", 00204 iface->name, elapsed - iface->msg_expiry); 00205 md_msg = ASTOBJ_CONTAINER_UNLINK_START(&iface->md_q); 00206 } 00207 else { 00208 /* good message, return it */ 00209 break; 00210 } 00211 } 00212 00213 return md_msg; 00214 }
|
|
||||||||||||
|
Definition at line 71 of file res_smdi.c. References ASTOBJ_CONTAINER_LINK_END, and ast_smdi_interface::md_q. 00072 { 00073 ASTOBJ_CONTAINER_LINK_END(&iface->md_q, md_msg); 00074 }
|
|
||||||||||||
|
Put an SMDI message back in the front of the queue.
Definition at line 160 of file res_smdi.c. References ASTOBJ_CONTAINER_LINK_START, and ast_smdi_interface::md_q. 00161 { 00162 ASTOBJ_CONTAINER_LINK_START(&iface->md_q, md_msg); 00163 }
|
|
||||||||||||
|
Get the next SMDI message from the queue.
Definition at line 228 of file res_smdi.c. References ast_smdi_md_message_pop(). Referenced by ss_thread(). 00229 { 00230 struct timeval start; 00231 long diff = 0; 00232 struct ast_smdi_md_message *msg; 00233 00234 start = ast_tvnow(); 00235 while (diff < timeout) { 00236 00237 if ((msg = ast_smdi_md_message_pop(iface))) 00238 return msg; 00239 00240 /* check timeout */ 00241 diff = ast_tvdiff_ms(ast_tvnow(), start); 00242 } 00243 00244 return (ast_smdi_md_message_pop(iface)); 00245 }
|
|
|
ast_smdi_mwi_message destructor.
Definition at line 483 of file res_smdi.c. References free. Referenced by ast_smdi_interface_destroy(), and ast_smdi_mwi_message_pop(). 00484 { 00485 free(msg); 00486 }
|
|
|
Get the next SMDI message from the queue.
Definition at line 257 of file res_smdi.c. References ast_log(), ast_smdi_mwi_message_destroy(), ASTOBJ_CONTAINER_UNLINK_START, ASTOBJ_UNREF, LOG_NOTICE, ast_smdi_interface::msg_expiry, ast_smdi_interface::mwi_q, and ast_smdi_mwi_message::timestamp. Referenced by ast_smdi_mwi_message_wait(). 00258 { 00259 struct ast_smdi_mwi_message *mwi_msg = ASTOBJ_CONTAINER_UNLINK_START(&iface->mwi_q); 00260 struct timeval now; 00261 long elapsed = 0; 00262 00263 /* purge old messages */ 00264 now = ast_tvnow(); 00265 while (mwi_msg) { 00266 elapsed = ast_tvdiff_ms(now, mwi_msg->timestamp); 00267 00268 if (elapsed > iface->msg_expiry) { 00269 /* found an expired message */ 00270 ASTOBJ_UNREF(mwi_msg, ast_smdi_mwi_message_destroy); 00271 ast_log(LOG_NOTICE, "Purged expired message from %s SMDI MWI message queue. Message was %ld milliseconds too old.\n", 00272 iface->name, elapsed - iface->msg_expiry); 00273 mwi_msg = ASTOBJ_CONTAINER_UNLINK_START(&iface->mwi_q); 00274 } 00275 else { 00276 /* good message, return it */ 00277 break; 00278 } 00279 } 00280 00281 return mwi_msg; 00282 }
|
|
||||||||||||
|
Definition at line 82 of file res_smdi.c. References ASTOBJ_CONTAINER_LINK_END, and ast_smdi_interface::mwi_q. 00083 { 00084 ASTOBJ_CONTAINER_LINK_END(&iface->mwi_q, mwi_msg); 00085 }
|
|
||||||||||||
|
Put an SMDI message back in the front of the queue.
Definition at line 174 of file res_smdi.c. References ASTOBJ_CONTAINER_LINK_START, and ast_smdi_interface::mwi_q. 00175 { 00176 ASTOBJ_CONTAINER_LINK_START(&iface->mwi_q, mwi_msg); 00177 }
|
|
||||||||||||
|
Get the next SMDI message from the queue.
Definition at line 296 of file res_smdi.c. References ast_smdi_mwi_message_pop(). 00297 { 00298 struct timeval start; 00299 long diff = 0; 00300 struct ast_smdi_mwi_message *msg; 00301 00302 start = ast_tvnow(); 00303 while (diff < timeout) { 00304 00305 if ((msg = ast_smdi_mwi_message_pop(iface))) 00306 return msg; 00307 00308 /* check timeout */ 00309 diff = ast_tvdiff_ms(ast_tvnow(), start); 00310 } 00311 00312 return (ast_smdi_mwi_message_pop(iface)); 00313 }
|
|
||||||||||||
|
Set the MWI indicator for a mailbox.
Definition at line 92 of file res_smdi.c. References ast_log(), ASTOBJ_UNLOCK, ASTOBJ_WRLOCK, file, LOG_DEBUG, LOG_ERROR, ast_smdi_interface::msdstrip, and option_debug. 00093 { 00094 FILE *file; 00095 int i; 00096 00097 file = fopen(iface->name, "w"); 00098 if(!file) { 00099 ast_log(LOG_ERROR, "Error opening SMDI interface %s (%s) for writing\n", iface->name, strerror(errno)); 00100 return 1; 00101 } 00102 00103 ASTOBJ_WRLOCK(iface); 00104 00105 fprintf(file, "OP:MWI "); 00106 00107 for(i = 0; i < iface->msdstrip; i++) 00108 fprintf(file, "0"); 00109 00110 fprintf(file, "%s!\x04", mailbox); 00111 fclose(file); 00112 00113 ASTOBJ_UNLOCK(iface); 00114 if (option_debug) 00115 ast_log(LOG_DEBUG, "Sent MWI set message for %s on %s\n", mailbox, iface->name); 00116 return 0; 00117 }
|
|
||||||||||||
|
Unset the MWI indicator for a mailbox.
Definition at line 124 of file res_smdi.c. References ast_log(), ASTOBJ_UNLOCK, ASTOBJ_WRLOCK, file, LOG_DEBUG, LOG_ERROR, ast_smdi_interface::msdstrip, and option_debug. 00125 { 00126 FILE *file; 00127 int i; 00128 00129 file = fopen(iface->name, "w"); 00130 if(!file) { 00131 ast_log(LOG_ERROR, "Error opening SMDI interface %s (%s) for writing\n", iface->name, strerror(errno)); 00132 return 1; 00133 } 00134 00135 ASTOBJ_WRLOCK(iface); 00136 00137 fprintf(file, "RMV:MWI "); 00138 00139 for(i = 0; i < iface->msdstrip; i++) 00140 fprintf(file, "0"); 00141 00142 fprintf(file, "%s!\x04", mailbox); 00143 fclose(file); 00144 00145 ASTOBJ_UNLOCK(iface); 00146 if (option_debug) 00147 ast_log(LOG_DEBUG, "Sent MWI unset message for %s on %s\n", mailbox, iface->name); 00148 return 0; 00149 }
|
|
|
Definition at line 712 of file res_smdi.c. References ast_log(), AST_MODULE_LOAD_DECLINE, ASTOBJ_CONTAINER_INIT, LOG_WARNING, smdi_ifaces, and smdi_load(). 00713 { 00714 int res; 00715 00716 /* initialize our containers */ 00717 memset(&smdi_ifaces, 0, sizeof(smdi_ifaces)); 00718 ASTOBJ_CONTAINER_INIT(&smdi_ifaces); 00719 00720 /* load the config and start the listener threads*/ 00721 res = smdi_load(0); 00722 if (res < 0) { 00723 return res; 00724 } else if (res == 1) { 00725 ast_log(LOG_WARNING, "No SMDI interfaces are available to listen on, not starting SDMI listener.\n"); 00726 return AST_MODULE_LOAD_DECLINE;; 00727 } else 00728 return 0; 00729 }
|
|
|
Definition at line 740 of file res_smdi.c. References ast_log(), LOG_WARNING, and smdi_load(). 00741 { 00742 int res; 00743 00744 res = smdi_load(1); 00745 00746 if (res < 0) { 00747 return res; 00748 } else if (res == 1) { 00749 ast_log(LOG_WARNING, "No SMDI interfaces were specified to listen on, not starting SDMI listener.\n"); 00750 return 0; 00751 } else 00752 return 0; 00753 }
|
|
|
Definition at line 520 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(). 00521 { 00522 struct ast_config *conf; 00523 struct ast_variable *v; 00524 struct ast_smdi_interface *iface = NULL; 00525 int res = 0; 00526 00527 /* Config options */ 00528 speed_t baud_rate = B9600; /* 9600 baud rate */ 00529 tcflag_t paritybit = PARENB; /* even parity checking */ 00530 tcflag_t charsize = CS7; /* seven bit characters */ 00531 int stopbits = 0; /* One stop bit */ 00532 00533 int msdstrip = 0; /* strip zero digits */ 00534 long msg_expiry = SMDI_MSG_EXPIRY_TIME; 00535 00536 conf = ast_config_load(config_file); 00537 00538 if (!conf) { 00539 if (reload) 00540 ast_log(LOG_NOTICE, "Unable to reload config %s: SMDI untouched\n", config_file); 00541 else 00542 ast_log(LOG_NOTICE, "Unable to load config %s: SMDI disabled\n", config_file); 00543 return 1; 00544 } 00545 00546 /* Mark all interfaces that we are listening on. We will unmark them 00547 * as we find them in the config file, this way we know any interfaces 00548 * still marked after we have finished parsing the config file should 00549 * be stopped. 00550 */ 00551 if (reload) 00552 ASTOBJ_CONTAINER_MARKALL(&smdi_ifaces); 00553 00554 for (v = ast_variable_browse(conf, "interfaces"); v; v = v->next) { 00555 if (!strcasecmp(v->name, "baudrate")) { 00556 if (!strcasecmp(v->value, "9600")) 00557 baud_rate = B9600; 00558 else if(!strcasecmp(v->value, "4800")) 00559 baud_rate = B4800; 00560 else if(!strcasecmp(v->value, "2400")) 00561 baud_rate = B2400; 00562 else if(!strcasecmp(v->value, "1200")) 00563 baud_rate = B1200; 00564 else { 00565 ast_log(LOG_NOTICE, "Invalid baud rate '%s' specified in %s (line %d), using default\n", v->value, config_file, v->lineno); 00566 baud_rate = B9600; 00567 } 00568 } else if (!strcasecmp(v->name, "msdstrip")) { 00569 if (!sscanf(v->value, "%d", &msdstrip)) { 00570 ast_log(LOG_NOTICE, "Invalid msdstrip value in %s (line %d), using default\n", config_file, v->lineno); 00571 msdstrip = 0; 00572 } else if (0 > msdstrip || msdstrip > 9) { 00573 ast_log(LOG_NOTICE, "Invalid msdstrip value in %s (line %d), using default\n", config_file, v->lineno); 00574 msdstrip = 0; 00575 } 00576 } else if (!strcasecmp(v->name, "msgexpirytime")) { 00577 if (!sscanf(v->value, "%ld", &msg_expiry)) { 00578 ast_log(LOG_NOTICE, "Invalid msgexpirytime value in %s (line %d), using default\n", config_file, v->lineno); 00579 msg_expiry = SMDI_MSG_EXPIRY_TIME; 00580 } 00581 } else if (!strcasecmp(v->name, "paritybit")) { 00582 if (!strcasecmp(v->value, "even")) 00583 paritybit = PARENB; 00584 else if (!strcasecmp(v->value, "odd")) 00585 paritybit = PARENB | PARODD; 00586 else if (!strcasecmp(v->value, "none")) 00587 paritybit = ~PARENB; 00588 else { 00589 ast_log(LOG_NOTICE, "Invalid parity bit setting in %s (line %d), using default\n", config_file, v->lineno); 00590 paritybit = PARENB; 00591 } 00592 } else if (!strcasecmp(v->name, "charsize")) { 00593 if (!strcasecmp(v->value, "7")) 00594 charsize = CS7; 00595 else if (!strcasecmp(v->value, "8")) 00596 charsize = CS8; 00597 else { 00598 ast_log(LOG_NOTICE, "Invalid character size setting in %s (line %d), using default\n", config_file, v->lineno); 00599 charsize = CS7; 00600 } 00601 } else if (!strcasecmp(v->name, "twostopbits")) { 00602 stopbits = ast_true(v->name); 00603 } else if (!strcasecmp(v->name, "smdiport")) { 00604 if (reload) { 00605 /* we are reloading, check if we are already 00606 * monitoring this interface, if we are we do 00607 * not want to start it again. This also has 00608 * the side effect of not updating different 00609 * setting for the serial port, but it should 00610 * be trivial to rewrite this section so that 00611 * options on the port are changed without 00612 * restarting the interface. Or the interface 00613 * could be restarted with out emptying the 00614 * queue. */ 00615 if ((iface = ASTOBJ_CONTAINER_FIND(&smdi_ifaces, v->value))) { 00616 ast_log(LOG_NOTICE, "SMDI interface %s already running, not restarting\n", iface->name); 00617 ASTOBJ_UNMARK(iface); 00618 ASTOBJ_UNREF(iface, ast_smdi_interface_destroy); 00619 continue; 00620 } 00621 } 00622 00623 if (!(iface = ast_calloc(1, sizeof(*iface)))) 00624 continue; 00625 00626 ASTOBJ_INIT(iface); 00627 ASTOBJ_CONTAINER_INIT(&iface->md_q); 00628 ASTOBJ_CONTAINER_INIT(&iface->mwi_q); 00629 00630 ast_copy_string(iface->name, v->value, sizeof(iface->name)); 00631 00632 if (!(iface->file = fopen(iface->name, "r"))) { 00633 ast_log(LOG_ERROR, "Error opening SMDI interface %s (%s)\n", iface->name, strerror(errno)); 00634 ASTOBJ_UNREF(iface, ast_smdi_interface_destroy); 00635 continue; 00636 } 00637 00638 iface->fd = fileno(iface->file); 00639 00640 /* Set the proper attributes for our serial port. */ 00641 00642 /* get the current attributes from the port */ 00643 if (tcgetattr(iface->fd, &iface->mode)) { 00644 ast_log(LOG_ERROR, "Error getting atributes of %s (%s)\n", iface->name, strerror(errno)); 00645 ASTOBJ_UNREF(iface, ast_smdi_interface_destroy); 00646 continue; 00647 } 00648 00649 /* set the desired speed */ 00650 if (cfsetispeed(&iface->mode, baud_rate) || cfsetospeed(&iface->mode, baud_rate)) { 00651 ast_log(LOG_ERROR, "Error setting baud rate on %s (%s)\n", iface->name, strerror(errno)); 00652 ASTOBJ_UNREF(iface, ast_smdi_interface_destroy); 00653 continue; 00654 } 00655 00656 /* set the stop bits */ 00657 if (stopbits) 00658 iface->mode.c_cflag = iface->mode.c_cflag | CSTOPB; /* set two stop bits */ 00659 else 00660 iface->mode.c_cflag = iface->mode.c_cflag & ~CSTOPB; /* set one stop bit */ 00661 00662 /* set the parity */ 00663 iface->mode.c_cflag = (iface->mode.c_cflag & ~PARENB & ~PARODD) | paritybit; 00664 00665 /* set the character size */ 00666 iface->mode.c_cflag = (iface->mode.c_cflag & ~CSIZE) | charsize; 00667 00668 /* commit the desired attributes */ 00669 if (tcsetattr(iface->fd, TCSAFLUSH, &iface->mode)) { 00670 ast_log(LOG_ERROR, "Error setting attributes on %s (%s)\n", iface->name, strerror(errno)); 00671 ASTOBJ_UNREF(iface, ast_smdi_interface_destroy); 00672 continue; 00673 } 00674 00675 /* set the msdstrip */ 00676 iface->msdstrip = msdstrip; 00677 00678 /* set the message expiry time */ 00679 iface->msg_expiry = msg_expiry; 00680 00681 /* start the listner thread */ 00682 if (option_verbose > 2) 00683 ast_verbose(VERBOSE_PREFIX_3 "Starting SMDI monitor thread for %s\n", iface->name); 00684 if (ast_pthread_create_background(&iface->thread, NULL, smdi_read, iface)) { 00685 ast_log(LOG_ERROR, "Error starting SMDI monitor thread for %s\n", iface->name); 00686 ASTOBJ_UNREF(iface, ast_smdi_interface_destroy); 00687 continue; 00688 } 00689 00690 ASTOBJ_CONTAINER_LINK(&smdi_ifaces, iface); 00691 ASTOBJ_UNREF(iface, ast_smdi_interface_destroy); 00692 ast_module_ref(ast_module_info->self); 00693 } else { 00694 ast_log(LOG_NOTICE, "Ignoring unknown option %s in %s\n", v->name, config_file); 00695 } 00696 } 00697 ast_config_destroy(conf); 00698 00699 /* Prune any interfaces we should no longer monitor. */ 00700 if (reload) 00701 ASTOBJ_CONTAINER_PRUNE_MARKED(&smdi_ifaces, ast_smdi_interface_destroy); 00702 00703 ASTOBJ_CONTAINER_RDLOCK(&smdi_ifaces); 00704 /* TODO: this is bad, we need an ASTOBJ method for this! */ 00705 if (!smdi_ifaces.head) 00706 res = 1; 00707 ASTOBJ_CONTAINER_UNLOCK(&smdi_ifaces); 00708 00709 return res; 00710 }
|
|
|
Read an SMDI message.
Definition at line 335 of file res_smdi.c. References ast_calloc, ast_smdi_interface_destroy(), ASTOBJ_INIT, ASTOBJ_UNREF, ast_smdi_md_message::calling_st, ast_smdi_interface::file, ast_smdi_md_message::fwd_st, ast_smdi_interface::msdstrip, SMDI_MAX_STATION_NUM_LEN, SMDI_MESG_DESK_NUM_LEN, and SMDI_MESG_DESK_TERM_LEN. 00336 { 00337 struct ast_smdi_interface *iface = iface_p; 00338 struct ast_smdi_md_message *md_msg; 00339 struct ast_smdi_mwi_message *mwi_msg; 00340 char c = '\0'; 00341 char *cp = NULL; 00342 int i; 00343 int start = 0; 00344 00345 /* read an smdi message */ 00346 while ((c = fgetc(iface->file))) { 00347 00348 /* check if this is the start of a message */ 00349 if (!start) { 00350 if (c == 'M') 00351 start = 1; 00352 } 00353 else { /* Determine if this is a MD or MWI message */ 00354 if(c == 'D') { /* MD message */ 00355 start = 0; 00356 00357 if (!(md_msg = ast_calloc(1, sizeof(*md_msg)))) { 00358 ASTOBJ_UNREF(iface,ast_smdi_interface_destroy); 00359 return NULL; 00360 } 00361 00362 ASTOBJ_INIT(md_msg); 00363 00364 /* read the message desk number */ 00365 for(i = 0; i < SMDI_MESG_DESK_NUM_LEN; i++) 00366 md_msg->mesg_desk_num[i] = fgetc(iface->file); 00367 00368 md_msg->mesg_desk_num[SMDI_MESG_DESK_NUM_LEN] = '\0'; 00369 00370 /* read the message desk terminal number */ 00371 for(i = 0; i < SMDI_MESG_DESK_TERM_LEN; i++) 00372 md_msg->mesg_desk_term[i] = fgetc(iface->file); 00373 00374 md_msg->mesg_desk_term[SMDI_MESG_DESK_TERM_LEN] = '\0'; 00375 00376 /* read the message type */ 00377 md_msg->type = fgetc(iface->file); 00378 00379 /* read the forwarding station number (may be blank) */ 00380 cp = &md_msg->fwd_st[0]; 00381 for (i = 0; i < SMDI_MAX_STATION_NUM_LEN + 1; i++) { 00382 if((c = fgetc(iface->file)) == ' ') { 00383 *cp = '\0'; 00384 break; 00385 } 00386 00387 /* store c in md_msg->fwd_st */ 00388 if( i >= iface->msdstrip) 00389 *cp++ = c; 00390 } 00391 00392 /* make sure the value is null terminated, even if this truncates it */ 00393 md_msg->fwd_st[SMDI_MAX_STATION_NUM_LEN] = '\0'; 00394 cp = NULL; 00395 00396 /* read the calling station number (may be blank) */ 00397 cp = &md_msg->calling_st[0]; 00398 for (i = 0; i < SMDI_MAX_STATION_NUM_LEN + 1; i++) { 00399 if (!isdigit((c = fgetc(iface->file)))) { 00400 *cp = '\0'; 00401 break; 00402 } 00403 00404 /* store c in md_msg->calling_st */ 00405 if (i >= iface->msdstrip) 00406 *cp++ = c; 00407 } 00408 00409 /* make sure the value is null terminated, even if this truncates it */ 00410 md_msg->calling_st[SMDI_MAX_STATION_NUM_LEN] = '\0'; 00411 cp = NULL; 00412 00413 /* add the message to the message queue */ 00414 md_msg->timestamp = ast_tvnow(); 00415 ast_smdi_md_message_push(iface, md_msg); 00416 if (option_debug) 00417 ast_log(LOG_DEBUG, "Recieved SMDI MD message on %s\n", iface->name); 00418 00419 ASTOBJ_UNREF(md_msg, ast_smdi_md_message_destroy); 00420 00421 } else if(c == 'W') { /* MWI message */ 00422 start = 0; 00423 00424 if (!(mwi_msg = ast_calloc(1, sizeof(*mwi_msg)))) { 00425 ASTOBJ_UNREF(iface,ast_smdi_interface_destroy); 00426 return NULL; 00427 } 00428 00429 ASTOBJ_INIT(mwi_msg); 00430 00431 /* discard the 'I' (from 'MWI') */ 00432 fgetc(iface->file); 00433 00434 /* read the forwarding station number (may be blank) */ 00435 cp = &mwi_msg->fwd_st[0]; 00436 for (i = 0; i < SMDI_MAX_STATION_NUM_LEN + 1; i++) { 00437 if ((c = fgetc(iface->file)) == ' ') { 00438 *cp = '\0'; 00439 break; 00440 } 00441 00442 /* store c in md_msg->fwd_st */ 00443 if (i >= iface->msdstrip) 00444 *cp++ = c; 00445 } 00446 00447 /* make sure the station number is null terminated, even if this will truncate it */ 00448 mwi_msg->fwd_st[SMDI_MAX_STATION_NUM_LEN] = '\0'; 00449 cp = NULL; 00450 00451 /* read the mwi failure cause */ 00452 for (i = 0; i < SMDI_MWI_FAIL_CAUSE_LEN; i++) 00453 mwi_msg->cause[i] = fgetc(iface->file); 00454 00455 mwi_msg->cause[SMDI_MWI_FAIL_CAUSE_LEN] = '\0'; 00456 00457 /* add the message to the message queue */ 00458 mwi_msg->timestamp = ast_tvnow(); 00459 ast_smdi_mwi_message_push(iface, mwi_msg); 00460 if (option_debug) 00461 ast_log(LOG_DEBUG, "Recieved SMDI MWI message on %s\n", iface->name); 00462 00463 ASTOBJ_UNREF(mwi_msg, ast_smdi_mwi_message_destroy); 00464 } else { 00465 ast_log(LOG_ERROR, "Unknown SMDI message type recieved on %s (M%c).\n", iface->name, c); 00466 start = 0; 00467 } 00468 } 00469 } 00470 00471 ast_log(LOG_ERROR, "Error reading from SMDI interface %s, stopping listener thread\n", iface->name); 00472 ASTOBJ_UNREF(iface,ast_smdi_interface_destroy); 00473 return NULL; 00474 }
|
|
|
Definition at line 731 of file res_smdi.c. References ast_smdi_interface_destroy(), ASTOBJ_CONTAINER_DESTROY, ASTOBJ_CONTAINER_DESTROYALL, and smdi_ifaces. 00732 { 00733 /* this destructor stops any running smdi_read threads */ 00734 ASTOBJ_CONTAINER_DESTROYALL(&smdi_ifaces, ast_smdi_interface_destroy); 00735 ASTOBJ_CONTAINER_DESTROY(&smdi_ifaces); 00736 00737 return 0; 00738 }
|
|
|
Definition at line 50 of file res_smdi.c. |
|
|
Definition at line 58 of file res_smdi.c. |
|
|
SMDI interface container.
Referenced by ast_smdi_interface_find(), load_module(), smdi_load(), and unload_module(). |