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