#include "asterisk.h"
#include <math.h>
#include <sys/wait.h>
#include <sys/time.h>
#include "asterisk/lock.h"
#include "asterisk/file.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/module.h"
#include "asterisk/translate.h"
#include "asterisk/ulaw.h"
#include "asterisk/app.h"
#include "asterisk/dsp.h"
#include "asterisk/config.h"
#include "asterisk/localtime.h"
#include "asterisk/callerid.h"
#include "asterisk/astdb.h"
#include "asterisk/utils.h"
Go to the source code of this file.
Data Structures | |
struct | event_node |
Defines | |
#define | ADEMCO_CONTACT_ID "ADEMCO_CONTACT_ID" |
#define | ALMRCV_CONFIG "alarmreceiver.conf" |
Typedefs | |
typedef event_node | event_node_t |
Functions | |
static void | __reg_module (void) |
static void | __unreg_module (void) |
static int | alarmreceiver_exec (struct ast_channel *chan, const char *data) |
static void | database_increment (char *key) |
static int | load_config (void) |
static int | load_module (void) |
static int | log_events (struct ast_channel *chan, char *signalling_type, event_node_t *event) |
static void | make_tone_burst (unsigned char *data, float freq, float loudness, int len, int *x) |
static int | receive_ademco_contact_id (struct ast_channel *chan, const void *data, int fdto, int sdto, int tldn, event_node_t **ehead) |
static int | receive_dtmf_digits (struct ast_channel *chan, char *digit_string, int length, int fdto, int sdto) |
static int | send_tone_burst (struct ast_channel *chan, float freq, int duration, int tldn) |
static int | unload_module (void) |
static int | write_event (FILE *logfile, event_node_t *event) |
static int | write_metadata (FILE *logfile, char *signalling_type, struct ast_channel *chan) |
Variables | |
static struct ast_module_info | __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Alarm Receiver for Asterisk" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "8586c2a7d357cb591cc3a6607a8f62d1" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, } |
static const char | app [] = "AlarmReceiver" |
static struct ast_module_info * | ast_module_info = &__mod_info |
static char | db_family [128] = {'\0'} |
static char | event_app [128] = {'\0'} |
static char | event_file [14] = "/event-XXXXXX" |
static char | event_spool_dir [128] = {'\0'} |
static int | fdtimeout = 2000 |
static int | log_individual_events = 0 |
static int | sdtimeout = 200 |
static char | time_stamp_format [128] = {"%a %b %d, %Y @ %H:%M:%S %Z"} |
static int | toneloudness = 4096 |
Use at your own risk. Please consult the GNU GPL license document included with Asterisk. *
*** WARNING *** WARNING *** WARNING *** WARNING *** WARNING *** WARNING *** WARNING *** WARNING ***
Definition in file app_alarmreceiver.c.
#define ADEMCO_CONTACT_ID "ADEMCO_CONTACT_ID" |
Definition at line 56 of file app_alarmreceiver.c.
Referenced by alarmreceiver_exec(), and receive_ademco_contact_id().
#define ALMRCV_CONFIG "alarmreceiver.conf" |
typedef struct event_node event_node_t |
Definition at line 63 of file app_alarmreceiver.c.
static void __reg_module | ( | void | ) | [static] |
Definition at line 734 of file app_alarmreceiver.c.
static void __unreg_module | ( | void | ) | [static] |
Definition at line 734 of file app_alarmreceiver.c.
static int alarmreceiver_exec | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 571 of file app_alarmreceiver.c.
References ast_channel::_state, ADEMCO_CONTACT_ID, ast_answer(), ast_copy_string(), ast_debug, AST_FORMAT_ULAW, ast_free, ast_log(), ast_safe_sleep(), ast_safe_system(), ast_set_read_format(), ast_set_write_format(), AST_STATE_UP, ast_strlen_zero(), ast_verb, log_events(), LOG_WARNING, ast_channel::name, event_node::next, and receive_ademco_contact_id().
Referenced by load_module().
00572 { 00573 int res = 0; 00574 event_node_t *elp, *efree; 00575 char signalling_type[64] = ""; 00576 event_node_t *event_head = NULL; 00577 00578 /* Set write and read formats to ULAW */ 00579 ast_verb(4, "AlarmReceiver: Setting read and write formats to ULAW\n"); 00580 00581 if (ast_set_write_format(chan,AST_FORMAT_ULAW)) { 00582 ast_log(LOG_WARNING, "AlarmReceiver: Unable to set write format to Mu-law on %s\n",chan->name); 00583 return -1; 00584 } 00585 00586 if (ast_set_read_format(chan,AST_FORMAT_ULAW)) { 00587 ast_log(LOG_WARNING, "AlarmReceiver: Unable to set read format to Mu-law on %s\n",chan->name); 00588 return -1; 00589 } 00590 00591 /* Set default values for this invocation of the application */ 00592 ast_copy_string(signalling_type, ADEMCO_CONTACT_ID, sizeof(signalling_type)); 00593 00594 /* Answer the channel if it is not already */ 00595 ast_verb(4, "AlarmReceiver: Answering channel\n"); 00596 if (chan->_state != AST_STATE_UP) { 00597 if ((res = ast_answer(chan))) 00598 return -1; 00599 } 00600 00601 /* Wait for the connection to settle post-answer */ 00602 ast_verb(4, "AlarmReceiver: Waiting for connection to stabilize\n"); 00603 res = ast_safe_sleep(chan, 1250); 00604 00605 /* Attempt to receive the events */ 00606 if (!res) { 00607 /* Determine the protocol to receive in advance */ 00608 /* Note: Ademco contact is the only one supported at this time */ 00609 /* Others may be added later */ 00610 if(!strcmp(signalling_type, ADEMCO_CONTACT_ID)) 00611 receive_ademco_contact_id(chan, data, fdtimeout, sdtimeout, toneloudness, &event_head); 00612 else 00613 res = -1; 00614 } 00615 00616 /* Events queued by receiver, write them all out here if so configured */ 00617 if ((!res) && (log_individual_events == 0)) 00618 res = log_events(chan, signalling_type, event_head); 00619 00620 /* 00621 * Do we exec a command line at the end? 00622 */ 00623 if ((!res) && (!ast_strlen_zero(event_app)) && (event_head)) { 00624 ast_debug(1,"Alarmreceiver: executing: %s\n", event_app); 00625 ast_safe_system(event_app); 00626 } 00627 00628 /* 00629 * Free up the data allocated in our linked list 00630 */ 00631 for (elp = event_head; (elp != NULL);) { 00632 efree = elp; 00633 elp = elp->next; 00634 ast_free(efree); 00635 } 00636 00637 return 0; 00638 }
static void database_increment | ( | char * | key | ) | [static] |
Definition at line 108 of file app_alarmreceiver.c.
References ast_db_get(), ast_db_put(), ast_strlen_zero(), ast_verb, and value.
Referenced by receive_ademco_contact_id().
00109 { 00110 int res = 0; 00111 unsigned v; 00112 char value[16]; 00113 00114 00115 if (ast_strlen_zero(db_family)) 00116 return; /* If not defined, don't do anything */ 00117 00118 res = ast_db_get(db_family, key, value, sizeof(value) - 1); 00119 00120 if (res) { 00121 ast_verb(4, "AlarmReceiver: Creating database entry %s and setting to 1\n", key); 00122 /* Guess we have to create it */ 00123 res = ast_db_put(db_family, key, "1"); 00124 return; 00125 } 00126 00127 sscanf(value, "%30u", &v); 00128 v++; 00129 00130 ast_verb(4, "AlarmReceiver: New value for %s: %u\n", key, v); 00131 00132 snprintf(value, sizeof(value), "%u", v); 00133 00134 res = ast_db_put(db_family, key, value); 00135 00136 if (res) 00137 ast_verb(4, "AlarmReceiver: database_increment write error\n"); 00138 00139 return; 00140 }
static int load_config | ( | void | ) | [static] |
Definition at line 643 of file app_alarmreceiver.c.
References ALMRCV_CONFIG, ast_config_destroy(), ast_config_load, ast_copy_string(), ast_log(), ast_true(), ast_variable_retrieve(), ast_verb, config_flags, CONFIG_STATUS_FILEINVALID, and LOG_ERROR.
Referenced by __reload(), ast_ais_evt_load_module(), ast_features_init(), ast_features_reload(), handle_voicemail_reload(), load_module(), reload(), and reload_module().
00644 { 00645 struct ast_config *cfg; 00646 const char *p; 00647 struct ast_flags config_flags = { 0 }; 00648 00649 /* Read in the config file */ 00650 cfg = ast_config_load(ALMRCV_CONFIG, config_flags); 00651 00652 if (!cfg) { 00653 ast_verb(4, "AlarmReceiver: No config file\n"); 00654 return 0; 00655 } else if (cfg == CONFIG_STATUS_FILEINVALID) { 00656 ast_log(LOG_ERROR, "Config file %s is in an invalid format. Aborting.\n", ALMRCV_CONFIG); 00657 return 0; 00658 } else { 00659 p = ast_variable_retrieve(cfg, "general", "eventcmd"); 00660 if (p) { 00661 ast_copy_string(event_app, p, sizeof(event_app)); 00662 event_app[sizeof(event_app) - 1] = '\0'; 00663 } 00664 p = ast_variable_retrieve(cfg, "general", "loudness"); 00665 if (p) { 00666 toneloudness = atoi(p); 00667 if(toneloudness < 100) 00668 toneloudness = 100; 00669 if(toneloudness > 8192) 00670 toneloudness = 8192; 00671 } 00672 p = ast_variable_retrieve(cfg, "general", "fdtimeout"); 00673 if (p) { 00674 fdtimeout = atoi(p); 00675 if(fdtimeout < 1000) 00676 fdtimeout = 1000; 00677 if(fdtimeout > 10000) 00678 fdtimeout = 10000; 00679 } 00680 00681 p = ast_variable_retrieve(cfg, "general", "sdtimeout"); 00682 if (p) { 00683 sdtimeout = atoi(p); 00684 if(sdtimeout < 110) 00685 sdtimeout = 110; 00686 if(sdtimeout > 4000) 00687 sdtimeout = 4000; 00688 } 00689 00690 p = ast_variable_retrieve(cfg, "general", "logindividualevents"); 00691 if (p) 00692 log_individual_events = ast_true(p); 00693 00694 p = ast_variable_retrieve(cfg, "general", "eventspooldir"); 00695 if (p) { 00696 ast_copy_string(event_spool_dir, p, sizeof(event_spool_dir)); 00697 event_spool_dir[sizeof(event_spool_dir) - 1] = '\0'; 00698 } 00699 00700 p = ast_variable_retrieve(cfg, "general", "timestampformat"); 00701 if (p) { 00702 ast_copy_string(time_stamp_format, p, sizeof(time_stamp_format)); 00703 time_stamp_format[sizeof(time_stamp_format) - 1] = '\0'; 00704 } 00705 00706 p = ast_variable_retrieve(cfg, "general", "db-family"); 00707 if (p) { 00708 ast_copy_string(db_family, p, sizeof(db_family)); 00709 db_family[sizeof(db_family) - 1] = '\0'; 00710 } 00711 ast_config_destroy(cfg); 00712 } 00713 return 1; 00714 }
static int load_module | ( | void | ) | [static] |
Definition at line 724 of file app_alarmreceiver.c.
References alarmreceiver_exec(), AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_SUCCESS, ast_register_application_xml, and load_config().
00725 { 00726 if (load_config()) { 00727 if (ast_register_application_xml(app, alarmreceiver_exec)) 00728 return AST_MODULE_LOAD_FAILURE; 00729 return AST_MODULE_LOAD_SUCCESS; 00730 } else 00731 return AST_MODULE_LOAD_DECLINE; 00732 }
static int log_events | ( | struct ast_channel * | chan, | |
char * | signalling_type, | |||
event_node_t * | event | |||
) | [static] |
Definition at line 368 of file app_alarmreceiver.c.
References ast_copy_string(), ast_debug, ast_strlen_zero(), ast_verb, event_node::next, write_event(), and write_metadata().
Referenced by alarmreceiver_exec(), and receive_ademco_contact_id().
00369 { 00370 00371 int res = 0; 00372 char workstring[sizeof(event_spool_dir)+sizeof(event_file)] = ""; 00373 int fd; 00374 FILE *logfile; 00375 event_node_t *elp = event; 00376 00377 if (!ast_strlen_zero(event_spool_dir)) { 00378 00379 /* Make a template */ 00380 ast_copy_string(workstring, event_spool_dir, sizeof(workstring)); 00381 strncat(workstring, event_file, sizeof(workstring) - strlen(workstring) - 1); 00382 00383 /* Make the temporary file */ 00384 fd = mkstemp(workstring); 00385 00386 if (fd == -1) { 00387 ast_verb(3, "AlarmReceiver: can't make temporary file\n"); 00388 ast_debug(1,"AlarmReceiver: can't make temporary file\n"); 00389 res = -1; 00390 } 00391 00392 if (!res) { 00393 logfile = fdopen(fd, "w"); 00394 if (logfile) { 00395 /* Write the file */ 00396 res = write_metadata(logfile, signalling_type, chan); 00397 if (!res) 00398 while ((!res) && (elp != NULL)) { 00399 res = write_event(logfile, elp); 00400 elp = elp->next; 00401 } 00402 if (!res) { 00403 if (fflush(logfile) == EOF) 00404 res = -1; 00405 if (!res) { 00406 if (fclose(logfile) == EOF) 00407 res = -1; 00408 } 00409 } 00410 } else 00411 res = -1; 00412 } 00413 } 00414 00415 return res; 00416 }
static void make_tone_burst | ( | unsigned char * | data, | |
float | freq, | |||
float | loudness, | |||
int | len, | |||
int * | x | |||
) | [static] |
Definition at line 146 of file app_alarmreceiver.c.
References AST_LIN2MU, and M_PI.
Referenced by send_tone_burst().
00147 { 00148 int i; 00149 float val; 00150 00151 for (i = 0; i < len; i++) { 00152 val = loudness * sin((freq * 2.0 * M_PI * (*x)++)/8000.0); 00153 data[i] = AST_LIN2MU((int)val); 00154 } 00155 00156 /* wrap back around from 8000 */ 00157 00158 if (*x >= 8000) 00159 *x = 0; 00160 return; 00161 }
static int receive_ademco_contact_id | ( | struct ast_channel * | chan, | |
const void * | data, | |||
int | fdto, | |||
int | sdto, | |||
int | tldn, | |||
event_node_t ** | ehead | |||
) | [static] |
Definition at line 423 of file app_alarmreceiver.c.
References ADEMCO_CONTACT_ID, ast_calloc, ast_copy_string(), ast_debug, ast_safe_sleep(), ast_strlen_zero(), ast_verb, database_increment(), log_events(), event_node::next, receive_dtmf_digits(), and send_tone_burst().
Referenced by alarmreceiver_exec().
00424 { 00425 int i, j; 00426 int res = 0; 00427 int checksum; 00428 char event[17]; 00429 event_node_t *enew, *elp; 00430 int got_some_digits = 0; 00431 int events_received = 0; 00432 int ack_retries = 0; 00433 00434 static char digit_map[15] = "0123456789*#ABC"; 00435 static unsigned char digit_weights[15] = {10,1,2,3,4,5,6,7,8,9,11,12,13,14,15}; 00436 00437 database_increment("calls-received"); 00438 00439 /* Wait for first event */ 00440 ast_verb(4, "AlarmReceiver: Waiting for first event from panel\n"); 00441 00442 while (res >= 0) { 00443 if (got_some_digits == 0) { 00444 /* Send ACK tone sequence */ 00445 ast_verb(4, "AlarmReceiver: Sending 1400Hz 100ms burst (ACK)\n"); 00446 res = send_tone_burst(chan, 1400.0, 100, tldn); 00447 if (!res) 00448 res = ast_safe_sleep(chan, 100); 00449 if (!res) { 00450 ast_verb(4, "AlarmReceiver: Sending 2300Hz 100ms burst (ACK)\n"); 00451 res = send_tone_burst(chan, 2300.0, 100, tldn); 00452 } 00453 } 00454 if ( res >= 0) 00455 res = receive_dtmf_digits(chan, event, sizeof(event) - 1, fdto, sdto); 00456 if (res < 0) { 00457 if (events_received == 0) { 00458 /* Hangup with no events received should be logged in the DB */ 00459 database_increment("no-events-received"); 00460 } else { 00461 if (ack_retries) { 00462 ast_verb(4, "AlarmReceiver: ACK retries during this call: %d\n", ack_retries); 00463 database_increment("ack-retries"); 00464 } 00465 } 00466 ast_verb(4, "AlarmReceiver: App exiting...\n"); 00467 res = -1; 00468 break; 00469 } 00470 00471 if (res != 0) { 00472 /* Didn't get all of the digits */ 00473 ast_verb(2, "AlarmReceiver: Incomplete string: %s, trying again...\n", event); 00474 00475 if (!got_some_digits) { 00476 got_some_digits = (!ast_strlen_zero(event)) ? 1 : 0; 00477 ack_retries++; 00478 } 00479 continue; 00480 } 00481 00482 got_some_digits = 1; 00483 00484 ast_verb(2, "AlarmReceiver: Received Event %s\n", event); 00485 ast_debug(1, "AlarmReceiver: Received event: %s\n", event); 00486 00487 /* Calculate checksum */ 00488 00489 for (j = 0, checksum = 0; j < 16; j++) { 00490 for (i = 0; i < sizeof(digit_map); i++) { 00491 if (digit_map[i] == event[j]) 00492 break; 00493 } 00494 00495 if (i == 16) 00496 break; 00497 00498 checksum += digit_weights[i]; 00499 } 00500 if (i == 16) { 00501 ast_verb(2, "AlarmReceiver: Bad DTMF character %c, trying again\n", event[j]); 00502 continue; /* Bad character */ 00503 } 00504 00505 /* Checksum is mod(15) of the total */ 00506 00507 checksum = checksum % 15; 00508 00509 if (checksum) { 00510 database_increment("checksum-errors"); 00511 ast_verb(2, "AlarmReceiver: Nonzero checksum\n"); 00512 ast_debug(1, "AlarmReceiver: Nonzero checksum\n"); 00513 continue; 00514 } 00515 00516 /* Check the message type for correctness */ 00517 00518 if (strncmp(event + 4, "18", 2)) { 00519 if (strncmp(event + 4, "98", 2)) { 00520 database_increment("format-errors"); 00521 ast_verb(2, "AlarmReceiver: Wrong message type\n"); 00522 ast_debug(1, "AlarmReceiver: Wrong message type\n"); 00523 continue; 00524 } 00525 } 00526 00527 events_received++; 00528 00529 /* Queue the Event */ 00530 if (!(enew = ast_calloc(1, sizeof(*enew)))) { 00531 res = -1; 00532 break; 00533 } 00534 00535 enew->next = NULL; 00536 ast_copy_string(enew->data, event, sizeof(enew->data)); 00537 00538 /* 00539 * Insert event onto end of list 00540 */ 00541 if (*ehead == NULL) 00542 *ehead = enew; 00543 else { 00544 for(elp = *ehead; elp->next != NULL; elp = elp->next) 00545 ; 00546 elp->next = enew; 00547 } 00548 00549 if (res > 0) 00550 res = 0; 00551 00552 /* Let the user have the option of logging the single event before sending the kissoff tone */ 00553 if ((res == 0) && (log_individual_events)) 00554 res = log_events(chan, ADEMCO_CONTACT_ID, enew); 00555 /* Wait 200 msec before sending kissoff */ 00556 if (res == 0) 00557 res = ast_safe_sleep(chan, 200); 00558 00559 /* Send the kissoff tone */ 00560 if (res == 0) 00561 res = send_tone_burst(chan, 1400.0, 900, tldn); 00562 } 00563 00564 return res; 00565 }
static int receive_dtmf_digits | ( | struct ast_channel * | chan, | |
char * | digit_string, | |||
int | length, | |||
int | fdto, | |||
int | sdto | |||
) | [static] |
Definition at line 232 of file app_alarmreceiver.c.
References AST_CONTROL_HANGUP, ast_debug, AST_FRAME_CONTROL, AST_FRAME_DTMF, ast_frfree, ast_read(), ast_tvdiff_ms(), ast_tvnow(), ast_verb, ast_waitfor(), f, ast_channel::hangupcause, and ast_channel::name.
Referenced by receive_ademco_contact_id().
00233 { 00234 int res = 0; 00235 int i = 0; 00236 int r; 00237 struct ast_frame *f; 00238 struct timeval lastdigittime; 00239 00240 lastdigittime = ast_tvnow(); 00241 for (;;) { 00242 /* if outa time, leave */ 00243 if (ast_tvdiff_ms(ast_tvnow(), lastdigittime) > ((i > 0) ? sdto : fdto)) { 00244 ast_verb(4, "AlarmReceiver: DTMF Digit Timeout on %s\n", chan->name); 00245 ast_debug(1,"AlarmReceiver: DTMF timeout on chan %s\n",chan->name); 00246 res = 1; 00247 break; 00248 } 00249 00250 if ((r = ast_waitfor(chan, -1) < 0)) { 00251 ast_debug(1, "Waitfor returned %d\n", r); 00252 continue; 00253 } 00254 00255 f = ast_read(chan); 00256 00257 if (f == NULL) { 00258 res = -1; 00259 break; 00260 } 00261 00262 /* If they hung up, leave */ 00263 if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass.integer == AST_CONTROL_HANGUP)) { 00264 if (f->data.uint32) { 00265 chan->hangupcause = f->data.uint32; 00266 } 00267 ast_frfree(f); 00268 res = -1; 00269 break; 00270 } 00271 00272 /* if not DTMF, just do it again */ 00273 if (f->frametype != AST_FRAME_DTMF) { 00274 ast_frfree(f); 00275 continue; 00276 } 00277 00278 digit_string[i++] = f->subclass.integer; /* save digit */ 00279 00280 ast_frfree(f); 00281 00282 /* If we have all the digits we expect, leave */ 00283 if(i >= length) 00284 break; 00285 00286 lastdigittime = ast_tvnow(); 00287 } 00288 00289 digit_string[i] = '\0'; /* Nul terminate the end of the digit string */ 00290 return res; 00291 }
static int send_tone_burst | ( | struct ast_channel * | chan, | |
float | freq, | |||
int | duration, | |||
int | tldn | |||
) | [static] |
Definition at line 167 of file app_alarmreceiver.c.
References AST_FORMAT_ULAW, AST_FRAME_VOICE, ast_frfree, AST_FRIENDLY_OFFSET, ast_log(), ast_read(), ast_verb, ast_waitfor(), ast_write(), ast_frame_subclass::codec, ast_frame::data, ast_frame::datalen, f, ast_frame::frametype, LOG_WARNING, make_tone_burst(), ast_frame::mallocd, ast_frame::offset, ast_frame::ptr, ast_frame::samples, and ast_frame::subclass.
Referenced by receive_ademco_contact_id().
00168 { 00169 int res = 0; 00170 int i = 0; 00171 int x = 0; 00172 struct ast_frame *f, wf; 00173 00174 struct { 00175 unsigned char offset[AST_FRIENDLY_OFFSET]; 00176 unsigned char buf[640]; 00177 } tone_block; 00178 00179 for (;;) { 00180 00181 if (ast_waitfor(chan, -1) < 0) { 00182 res = -1; 00183 break; 00184 } 00185 00186 f = ast_read(chan); 00187 if (!f) { 00188 res = -1; 00189 break; 00190 } 00191 00192 if (f->frametype == AST_FRAME_VOICE) { 00193 wf.frametype = AST_FRAME_VOICE; 00194 wf.subclass.codec = AST_FORMAT_ULAW; 00195 wf.offset = AST_FRIENDLY_OFFSET; 00196 wf.mallocd = 0; 00197 wf.data.ptr = tone_block.buf; 00198 wf.datalen = f->datalen; 00199 wf.samples = wf.datalen; 00200 00201 make_tone_burst(tone_block.buf, freq, (float) tldn, wf.datalen, &x); 00202 00203 i += wf.datalen / 8; 00204 if (i > duration) { 00205 ast_frfree(f); 00206 break; 00207 } 00208 if (ast_write(chan, &wf)) { 00209 ast_verb(4, "AlarmReceiver: Failed to write frame on %s\n", chan->name); 00210 ast_log(LOG_WARNING, "AlarmReceiver Failed to write frame on %s\n",chan->name); 00211 res = -1; 00212 ast_frfree(f); 00213 break; 00214 } 00215 } 00216 00217 ast_frfree(f); 00218 } 00219 return res; 00220 }
static int unload_module | ( | void | ) | [static] |
Definition at line 719 of file app_alarmreceiver.c.
References ast_unregister_application().
00720 { 00721 return ast_unregister_application(app); 00722 }
static int write_event | ( | FILE * | logfile, | |
event_node_t * | event | |||
) | [static] |
Definition at line 354 of file app_alarmreceiver.c.
References event_node::data.
Referenced by log_events().
00355 { 00356 int res = 0; 00357 00358 if (fprintf(logfile, "%s\n", event->data) < 0) 00359 res = -1; 00360 00361 return res; 00362 }
static int write_metadata | ( | FILE * | logfile, | |
char * | signalling_type, | |||
struct ast_channel * | chan | |||
) | [static] |
Definition at line 296 of file app_alarmreceiver.c.
References ast_copy_string(), ast_debug, ast_localtime(), ast_shrink_phone_number(), ast_strftime(), ast_strlen_zero(), ast_tvnow(), ast_verb, ast_channel::caller, ast_party_caller::id, ast_party_id::name, ast_party_id::number, S_COR, ast_party_name::str, ast_party_number::str, ast_party_name::valid, and ast_party_number::valid.
Referenced by log_events().
00297 { 00298 int res = 0; 00299 struct timeval t; 00300 struct ast_tm now; 00301 char *cl; 00302 char *cn; 00303 char workstring[80]; 00304 char timestamp[80]; 00305 00306 /* Extract the caller ID location */ 00307 ast_copy_string(workstring, 00308 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, ""), 00309 sizeof(workstring)); 00310 ast_shrink_phone_number(workstring); 00311 if (ast_strlen_zero(workstring)) { 00312 cl = "<unknown>"; 00313 } else { 00314 cl = workstring; 00315 } 00316 cn = S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, "<unknown>"); 00317 00318 /* Get the current time */ 00319 t = ast_tvnow(); 00320 ast_localtime(&t, &now, NULL); 00321 00322 /* Format the time */ 00323 ast_strftime(timestamp, sizeof(timestamp), time_stamp_format, &now); 00324 00325 res = fprintf(logfile, "\n\n[metadata]\n\n"); 00326 if (res >= 0) { 00327 res = fprintf(logfile, "PROTOCOL=%s\n", signalling_type); 00328 } 00329 if (res >= 0) { 00330 res = fprintf(logfile, "CALLINGFROM=%s\n", cl); 00331 } 00332 if (res >= 0) { 00333 res = fprintf(logfile, "CALLERNAME=%s\n", cn); 00334 } 00335 if (res >= 0) { 00336 res = fprintf(logfile, "TIMESTAMP=%s\n\n", timestamp); 00337 } 00338 if (res >= 0) { 00339 res = fprintf(logfile, "[events]\n\n"); 00340 } 00341 if (res < 0) { 00342 ast_verb(3, "AlarmReceiver: can't write metadata\n"); 00343 ast_debug(1,"AlarmReceiver: can't write metadata\n"); 00344 } else { 00345 res = 0; 00346 } 00347 00348 return res; 00349 }
struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Alarm Receiver for Asterisk" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "8586c2a7d357cb591cc3a6607a8f62d1" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, } [static] |
Definition at line 734 of file app_alarmreceiver.c.
const char app[] = "AlarmReceiver" [static] |
Definition at line 65 of file app_alarmreceiver.c.
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 734 of file app_alarmreceiver.c.
char db_family[128] = {'\0'} [static] |
Definition at line 95 of file app_alarmreceiver.c.
char event_app[128] = {'\0'} [static] |
Definition at line 94 of file app_alarmreceiver.c.
char event_file[14] = "/event-XXXXXX" [static] |
Definition at line 99 of file app_alarmreceiver.c.
char event_spool_dir[128] = {'\0'} [static] |
Definition at line 93 of file app_alarmreceiver.c.
int fdtimeout = 2000 [static] |
Definition at line 89 of file app_alarmreceiver.c.
int log_individual_events = 0 [static] |
Definition at line 92 of file app_alarmreceiver.c.
int sdtimeout = 200 [static] |
Definition at line 90 of file app_alarmreceiver.c.
char time_stamp_format[128] = {"%a %b %d, %Y @ %H:%M:%S %Z"} [static] |
Definition at line 96 of file app_alarmreceiver.c.
int toneloudness = 4096 [static] |
Definition at line 91 of file app_alarmreceiver.c.