Central Station Alarm receiver for Ademco Contact ID. More...
#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 struct event_node | event_node_t |
Functions | |
| static void | __reg_module (void) |
| static void | __unreg_module (void) |
| static int | alarmreceiver_exec (struct ast_channel *chan, void *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, 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_DEFAULT , .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 = "0901e4e500243c855563a2d78b0c03e4" , .load = load_module, .unload = unload_module, } |
| static 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 |
Central Station Alarm receiver for Ademco Contact ID.
*** WARNING *** WARNING *** WARNING *** WARNING *** WARNING *** WARNING *** WARNING *** WARNING ***
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" |
Definition at line 55 of file app_alarmreceiver.c.
Referenced by load_config().
| 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 730 of file app_alarmreceiver.c.
| static void __unreg_module | ( | void | ) | [static] |
Definition at line 730 of file app_alarmreceiver.c.
| static int alarmreceiver_exec | ( | struct ast_channel * | chan, | |
| void * | data | |||
| ) | [static] |
Definition at line 567 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().
00568 { 00569 int res = 0; 00570 event_node_t *elp, *efree; 00571 char signalling_type[64] = ""; 00572 event_node_t *event_head = NULL; 00573 00574 /* Set write and read formats to ULAW */ 00575 ast_verb(4, "AlarmReceiver: Setting read and write formats to ULAW\n"); 00576 00577 if (ast_set_write_format(chan,AST_FORMAT_ULAW)) { 00578 ast_log(LOG_WARNING, "AlarmReceiver: Unable to set write format to Mu-law on %s\n",chan->name); 00579 return -1; 00580 } 00581 00582 if (ast_set_read_format(chan,AST_FORMAT_ULAW)) { 00583 ast_log(LOG_WARNING, "AlarmReceiver: Unable to set read format to Mu-law on %s\n",chan->name); 00584 return -1; 00585 } 00586 00587 /* Set default values for this invocation of the application */ 00588 ast_copy_string(signalling_type, ADEMCO_CONTACT_ID, sizeof(signalling_type)); 00589 00590 /* Answer the channel if it is not already */ 00591 ast_verb(4, "AlarmReceiver: Answering channel\n"); 00592 if (chan->_state != AST_STATE_UP) { 00593 if ((res = ast_answer(chan))) 00594 return -1; 00595 } 00596 00597 /* Wait for the connection to settle post-answer */ 00598 ast_verb(4, "AlarmReceiver: Waiting for connection to stabilize\n"); 00599 res = ast_safe_sleep(chan, 1250); 00600 00601 /* Attempt to receive the events */ 00602 if (!res) { 00603 /* Determine the protocol to receive in advance */ 00604 /* Note: Ademco contact is the only one supported at this time */ 00605 /* Others may be added later */ 00606 if(!strcmp(signalling_type, ADEMCO_CONTACT_ID)) 00607 receive_ademco_contact_id(chan, data, fdtimeout, sdtimeout, toneloudness, &event_head); 00608 else 00609 res = -1; 00610 } 00611 00612 /* Events queued by receiver, write them all out here if so configured */ 00613 if ((!res) && (log_individual_events == 0)) 00614 res = log_events(chan, signalling_type, event_head); 00615 00616 /* 00617 * Do we exec a command line at the end? 00618 */ 00619 if ((!res) && (!ast_strlen_zero(event_app)) && (event_head)) { 00620 ast_debug(1,"Alarmreceiver: executing: %s\n", event_app); 00621 ast_safe_system(event_app); 00622 } 00623 00624 /* 00625 * Free up the data allocated in our linked list 00626 */ 00627 for (elp = event_head; (elp != NULL);) { 00628 efree = elp; 00629 elp = elp->next; 00630 ast_free(efree); 00631 } 00632 00633 return 0; 00634 }
| 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(), and ast_verb.
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 639 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_STATUS_FILEINVALID, and LOG_ERROR.
Referenced by load_module().
00640 { 00641 struct ast_config *cfg; 00642 const char *p; 00643 struct ast_flags config_flags = { 0 }; 00644 00645 /* Read in the config file */ 00646 cfg = ast_config_load(ALMRCV_CONFIG, config_flags); 00647 00648 if (!cfg) { 00649 ast_verb(4, "AlarmReceiver: No config file\n"); 00650 return 0; 00651 } else if (cfg == CONFIG_STATUS_FILEINVALID) { 00652 ast_log(LOG_ERROR, "Config file %s is in an invalid format. Aborting.\n", ALMRCV_CONFIG); 00653 return 0; 00654 } else { 00655 p = ast_variable_retrieve(cfg, "general", "eventcmd"); 00656 if (p) { 00657 ast_copy_string(event_app, p, sizeof(event_app)); 00658 event_app[sizeof(event_app) - 1] = '\0'; 00659 } 00660 p = ast_variable_retrieve(cfg, "general", "loudness"); 00661 if (p) { 00662 toneloudness = atoi(p); 00663 if(toneloudness < 100) 00664 toneloudness = 100; 00665 if(toneloudness > 8192) 00666 toneloudness = 8192; 00667 } 00668 p = ast_variable_retrieve(cfg, "general", "fdtimeout"); 00669 if (p) { 00670 fdtimeout = atoi(p); 00671 if(fdtimeout < 1000) 00672 fdtimeout = 1000; 00673 if(fdtimeout > 10000) 00674 fdtimeout = 10000; 00675 } 00676 00677 p = ast_variable_retrieve(cfg, "general", "sdtimeout"); 00678 if (p) { 00679 sdtimeout = atoi(p); 00680 if(sdtimeout < 110) 00681 sdtimeout = 110; 00682 if(sdtimeout > 4000) 00683 sdtimeout = 4000; 00684 } 00685 00686 p = ast_variable_retrieve(cfg, "general", "logindividualevents"); 00687 if (p) 00688 log_individual_events = ast_true(p); 00689 00690 p = ast_variable_retrieve(cfg, "general", "eventspooldir"); 00691 if (p) { 00692 ast_copy_string(event_spool_dir, p, sizeof(event_spool_dir)); 00693 event_spool_dir[sizeof(event_spool_dir) - 1] = '\0'; 00694 } 00695 00696 p = ast_variable_retrieve(cfg, "general", "timestampformat"); 00697 if (p) { 00698 ast_copy_string(time_stamp_format, p, sizeof(time_stamp_format)); 00699 time_stamp_format[sizeof(time_stamp_format) - 1] = '\0'; 00700 } 00701 00702 p = ast_variable_retrieve(cfg, "general", "db-family"); 00703 if (p) { 00704 ast_copy_string(db_family, p, sizeof(db_family)); 00705 db_family[sizeof(db_family) - 1] = '\0'; 00706 } 00707 ast_config_destroy(cfg); 00708 } 00709 return 1; 00710 }
| static int load_module | ( | void | ) | [static] |
Definition at line 720 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().
00721 { 00722 if (load_config()) { 00723 if (ast_register_application_xml(app, alarmreceiver_exec)) 00724 return AST_MODULE_LOAD_FAILURE; 00725 return AST_MODULE_LOAD_SUCCESS; 00726 } else 00727 return AST_MODULE_LOAD_DECLINE; 00728 }
| static int log_events | ( | struct ast_channel * | chan, | |
| char * | signalling_type, | |||
| event_node_t * | event | |||
| ) | [static] |
Definition at line 364 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().
00365 { 00366 00367 int res = 0; 00368 char workstring[sizeof(event_spool_dir)+sizeof(event_file)] = ""; 00369 int fd; 00370 FILE *logfile; 00371 event_node_t *elp = event; 00372 00373 if (!ast_strlen_zero(event_spool_dir)) { 00374 00375 /* Make a template */ 00376 ast_copy_string(workstring, event_spool_dir, sizeof(workstring)); 00377 strncat(workstring, event_file, sizeof(workstring) - strlen(workstring) - 1); 00378 00379 /* Make the temporary file */ 00380 fd = mkstemp(workstring); 00381 00382 if (fd == -1) { 00383 ast_verb(3, "AlarmReceiver: can't make temporary file\n"); 00384 ast_debug(1,"AlarmReceiver: can't make temporary file\n"); 00385 res = -1; 00386 } 00387 00388 if (!res) { 00389 logfile = fdopen(fd, "w"); 00390 if (logfile) { 00391 /* Write the file */ 00392 res = write_metadata(logfile, signalling_type, chan); 00393 if (!res) 00394 while ((!res) && (elp != NULL)) { 00395 res = write_event(logfile, elp); 00396 elp = elp->next; 00397 } 00398 if (!res) { 00399 if (fflush(logfile) == EOF) 00400 res = -1; 00401 if (!res) { 00402 if (fclose(logfile) == EOF) 00403 res = -1; 00404 } 00405 } 00406 } else 00407 res = -1; 00408 } 00409 } 00410 00411 return res; 00412 }
| 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.
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, | |
| void * | data, | |||
| int | fdto, | |||
| int | sdto, | |||
| int | tldn, | |||
| event_node_t ** | ehead | |||
| ) | [static] |
Definition at line 419 of file app_alarmreceiver.c.
References ADEMCO_CONTACT_ID, ast_calloc, ast_copy_string(), ast_debug, ast_safe_sleep(), ast_strlen_zero(), ast_verb, event_node::data, database_increment(), log_events(), event_node::next, receive_dtmf_digits(), and send_tone_burst().
Referenced by alarmreceiver_exec().
00420 { 00421 int i, j; 00422 int res = 0; 00423 int checksum; 00424 char event[17]; 00425 event_node_t *enew, *elp; 00426 int got_some_digits = 0; 00427 int events_received = 0; 00428 int ack_retries = 0; 00429 00430 static char digit_map[15] = "0123456789*#ABC"; 00431 static unsigned char digit_weights[15] = {10,1,2,3,4,5,6,7,8,9,11,12,13,14,15}; 00432 00433 database_increment("calls-received"); 00434 00435 /* Wait for first event */ 00436 ast_verb(4, "AlarmReceiver: Waiting for first event from panel\n"); 00437 00438 while (res >= 0) { 00439 if (got_some_digits == 0) { 00440 /* Send ACK tone sequence */ 00441 ast_verb(4, "AlarmReceiver: Sending 1400Hz 100ms burst (ACK)\n"); 00442 res = send_tone_burst(chan, 1400.0, 100, tldn); 00443 if (!res) 00444 res = ast_safe_sleep(chan, 100); 00445 if (!res) { 00446 ast_verb(4, "AlarmReceiver: Sending 2300Hz 100ms burst (ACK)\n"); 00447 res = send_tone_burst(chan, 2300.0, 100, tldn); 00448 } 00449 } 00450 if ( res >= 0) 00451 res = receive_dtmf_digits(chan, event, sizeof(event) - 1, fdto, sdto); 00452 if (res < 0) { 00453 if (events_received == 0) { 00454 /* Hangup with no events received should be logged in the DB */ 00455 database_increment("no-events-received"); 00456 } else { 00457 if (ack_retries) { 00458 ast_verb(4, "AlarmReceiver: ACK retries during this call: %d\n", ack_retries); 00459 database_increment("ack-retries"); 00460 } 00461 } 00462 ast_verb(4, "AlarmReceiver: App exiting...\n"); 00463 res = -1; 00464 break; 00465 } 00466 00467 if (res != 0) { 00468 /* Didn't get all of the digits */ 00469 ast_verb(2, "AlarmReceiver: Incomplete string: %s, trying again...\n", event); 00470 00471 if (!got_some_digits) { 00472 got_some_digits = (!ast_strlen_zero(event)) ? 1 : 0; 00473 ack_retries++; 00474 } 00475 continue; 00476 } 00477 00478 got_some_digits = 1; 00479 00480 ast_verb(2, "AlarmReceiver: Received Event %s\n", event); 00481 ast_debug(1, "AlarmReceiver: Received event: %s\n", event); 00482 00483 /* Calculate checksum */ 00484 00485 for (j = 0, checksum = 0; j < 16; j++) { 00486 for (i = 0; i < sizeof(digit_map); i++) { 00487 if (digit_map[i] == event[j]) 00488 break; 00489 } 00490 00491 if (i == 16) 00492 break; 00493 00494 checksum += digit_weights[i]; 00495 } 00496 if (i == 16) { 00497 ast_verb(2, "AlarmReceiver: Bad DTMF character %c, trying again\n", event[j]); 00498 continue; /* Bad character */ 00499 } 00500 00501 /* Checksum is mod(15) of the total */ 00502 00503 checksum = checksum % 15; 00504 00505 if (checksum) { 00506 database_increment("checksum-errors"); 00507 ast_verb(2, "AlarmReceiver: Nonzero checksum\n"); 00508 ast_debug(1, "AlarmReceiver: Nonzero checksum\n"); 00509 continue; 00510 } 00511 00512 /* Check the message type for correctness */ 00513 00514 if (strncmp(event + 4, "18", 2)) { 00515 if (strncmp(event + 4, "98", 2)) { 00516 database_increment("format-errors"); 00517 ast_verb(2, "AlarmReceiver: Wrong message type\n"); 00518 ast_debug(1, "AlarmReceiver: Wrong message type\n"); 00519 continue; 00520 } 00521 } 00522 00523 events_received++; 00524 00525 /* Queue the Event */ 00526 if (!(enew = ast_calloc(1, sizeof(*enew)))) { 00527 res = -1; 00528 break; 00529 } 00530 00531 enew->next = NULL; 00532 ast_copy_string(enew->data, event, sizeof(enew->data)); 00533 00534 /* 00535 * Insert event onto end of list 00536 */ 00537 if (*ehead == NULL) 00538 *ehead = enew; 00539 else { 00540 for(elp = *ehead; elp->next != NULL; elp = elp->next) 00541 ; 00542 elp->next = enew; 00543 } 00544 00545 if (res > 0) 00546 res = 0; 00547 00548 /* Let the user have the option of logging the single event before sending the kissoff tone */ 00549 if ((res == 0) && (log_individual_events)) 00550 res = log_events(chan, ADEMCO_CONTACT_ID, enew); 00551 /* Wait 200 msec before sending kissoff */ 00552 if (res == 0) 00553 res = ast_safe_sleep(chan, 200); 00554 00555 /* Send the kissoff tone */ 00556 if (res == 0) 00557 res = send_tone_burst(chan, 1400.0, 900, tldn); 00558 } 00559 00560 return res; 00561 }
| 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(), ast_frame::data, f, ast_frame::frametype, ast_channel::hangupcause, ast_channel::name, ast_frame::subclass, and ast_frame::uint32.
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 == 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; /* 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(), buf, ast_frame::data, ast_frame::datalen, f, ast_frame::frametype, LOG_WARNING, make_tone_burst(), ast_frame::mallocd, ast_channel::name, 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 = 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 715 of file app_alarmreceiver.c.
References ast_unregister_application().
00716 { 00717 return ast_unregister_application(app); 00718 }
| static int write_event | ( | FILE * | logfile, | |
| event_node_t * | event | |||
| ) | [static] |
Definition at line 350 of file app_alarmreceiver.c.
References event_node::data.
Referenced by log_events().
00351 { 00352 int res = 0; 00353 00354 if (fprintf(logfile, "%s\n", event->data) < 0) 00355 res = -1; 00356 00357 return res; 00358 }
| 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_callerid_parse(), ast_copy_string(), ast_debug, ast_localtime(), ast_shrink_phone_number(), ast_strftime(), ast_tvnow(), ast_verb, ast_channel::cid, and ast_callerid::cid_num.
Referenced by log_events().
00297 { 00298 int res = 0; 00299 struct timeval t; 00300 struct ast_tm now; 00301 char *cl,*cn; 00302 char workstring[80]; 00303 char timestamp[80]; 00304 00305 /* Extract the caller ID location */ 00306 if (chan->cid.cid_num) 00307 ast_copy_string(workstring, chan->cid.cid_num, sizeof(workstring)); 00308 workstring[sizeof(workstring) - 1] = '\0'; 00309 00310 ast_callerid_parse(workstring, &cn, &cl); 00311 if (cl) 00312 ast_shrink_phone_number(cl); 00313 00314 /* Get the current time */ 00315 t = ast_tvnow(); 00316 ast_localtime(&t, &now, NULL); 00317 00318 /* Format the time */ 00319 ast_strftime(timestamp, sizeof(timestamp), time_stamp_format, &now); 00320 00321 res = fprintf(logfile, "\n\n[metadata]\n\n"); 00322 00323 if (res >= 0) 00324 res = fprintf(logfile, "PROTOCOL=%s\n", signalling_type); 00325 00326 if (res >= 0) 00327 res = fprintf(logfile, "CALLINGFROM=%s\n", (!cl) ? "<unknown>" : cl); 00328 00329 if (res >- 0) 00330 res = fprintf(logfile, "CALLERNAME=%s\n", (!cn) ? "<unknown>" : cn); 00331 00332 if (res >= 0) 00333 res = fprintf(logfile, "TIMESTAMP=%s\n\n", timestamp); 00334 00335 if (res >= 0) 00336 res = fprintf(logfile, "[events]\n\n"); 00337 00338 if (res < 0) { 00339 ast_verb(3, "AlarmReceiver: can't write metadata\n"); 00340 ast_debug(1,"AlarmReceiver: can't write metadata\n"); 00341 } else 00342 res = 0; 00343 00344 return res; 00345 }
struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .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 = "0901e4e500243c855563a2d78b0c03e4" , .load = load_module, .unload = unload_module, } [static] |
Definition at line 730 of file app_alarmreceiver.c.
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 730 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.
1.6.2