#include "asterisk.h"
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <sys/wait.h>
#include <unistd.h>
#include <sys/time.h>
#include "asterisk/lock.h"
#include "asterisk/file.h"
#include "asterisk/logger.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/module.h"
#include "asterisk/translate.h"
#include "asterisk/ulaw.h"
#include "asterisk/options.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 int | alarmreceiver_exec (struct ast_channel *chan, void *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, 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 char * | app = "AlarmReceiver" |
static char | db_family [128] = {'\0'} |
static char * | descrip |
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 * | synopsis = "Provide support for receiving alarm reports from a burglar or fire alarm panel" |
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 62 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 69 of file app_alarmreceiver.c.
static int alarmreceiver_exec | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 626 of file app_alarmreceiver.c.
References ast_channel::_state, ADEMCO_CONTACT_ID, ast_answer(), AST_FORMAT_ULAW, ast_log(), ast_module_user_add, ast_module_user_remove, ast_safe_sleep(), ast_safe_system(), ast_set_read_format(), ast_set_write_format(), AST_STATE_UP, ast_strlen_zero(), ast_verbose(), ast_module_user::chan, free, LOG_DEBUG, log_events(), LOG_WARNING, event_node::next, option_verbose, receive_ademco_contact_id(), and VERBOSE_PREFIX_4.
Referenced by load_module().
00627 { 00628 int res = 0; 00629 struct ast_module_user *u; 00630 event_node_t *elp, *efree; 00631 char signalling_type[64] = ""; 00632 00633 event_node_t *event_head = NULL; 00634 00635 u = ast_module_user_add(chan); 00636 00637 /* Set write and read formats to ULAW */ 00638 00639 if(option_verbose >= 4) 00640 ast_verbose(VERBOSE_PREFIX_4 "AlarmReceiver: Setting read and write formats to ULAW\n"); 00641 00642 if (ast_set_write_format(chan,AST_FORMAT_ULAW)){ 00643 ast_log(LOG_WARNING, "AlarmReceiver: Unable to set write format to Mu-law on %s\n",chan->name); 00644 ast_module_user_remove(u); 00645 return -1; 00646 } 00647 00648 if (ast_set_read_format(chan,AST_FORMAT_ULAW)){ 00649 ast_log(LOG_WARNING, "AlarmReceiver: Unable to set read format to Mu-law on %s\n",chan->name); 00650 ast_module_user_remove(u); 00651 return -1; 00652 } 00653 00654 /* Set default values for this invokation of the application */ 00655 00656 ast_copy_string(signalling_type, ADEMCO_CONTACT_ID, sizeof(signalling_type)); 00657 00658 00659 /* Answer the channel if it is not already */ 00660 00661 if(option_verbose >= 4) 00662 ast_verbose(VERBOSE_PREFIX_4 "AlarmReceiver: Answering channel\n"); 00663 00664 if (chan->_state != AST_STATE_UP) { 00665 00666 res = ast_answer(chan); 00667 00668 if (res) { 00669 ast_module_user_remove(u); 00670 return -1; 00671 } 00672 } 00673 00674 /* Wait for the connection to settle post-answer */ 00675 00676 if(option_verbose >= 4) 00677 ast_verbose(VERBOSE_PREFIX_4 "AlarmReceiver: Waiting for connection to stabilize\n"); 00678 00679 res = ast_safe_sleep(chan, 1250); 00680 00681 /* Attempt to receive the events */ 00682 00683 if(!res){ 00684 00685 /* Determine the protocol to receive in advance */ 00686 /* Note: Ademco contact is the only one supported at this time */ 00687 /* Others may be added later */ 00688 00689 if(!strcmp(signalling_type, ADEMCO_CONTACT_ID)) 00690 receive_ademco_contact_id(chan, data, fdtimeout, sdtimeout, toneloudness, &event_head); 00691 else 00692 res = -1; 00693 } 00694 00695 00696 00697 /* Events queued by receiver, write them all out here if so configured */ 00698 00699 if((!res) && (log_individual_events == 0)){ 00700 res = log_events(chan, signalling_type, event_head); 00701 00702 } 00703 00704 /* 00705 * Do we exec a command line at the end? 00706 */ 00707 00708 if((!res) && (!ast_strlen_zero(event_app)) && (event_head)){ 00709 ast_log(LOG_DEBUG,"Alarmreceiver: executing: %s\n", event_app); 00710 ast_safe_system(event_app); 00711 } 00712 00713 /* 00714 * Free up the data allocated in our linked list 00715 */ 00716 00717 for(elp = event_head; (elp != NULL);){ 00718 efree = elp; 00719 elp = elp->next; 00720 free(efree); 00721 } 00722 00723 00724 ast_module_user_remove(u); 00725 00726 return 0; 00727 }
AST_MODULE_INFO_STANDARD | ( | ASTERISK_GPL_KEY | , | |
"Alarm Receiver for Asterisk" | ||||
) |
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_verbose(), option_verbose, and VERBOSE_PREFIX_4.
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 if(option_verbose >= 4) 00122 ast_verbose(VERBOSE_PREFIX_4 "AlarmReceiver: Creating database entry %s and setting to 1\n", key); 00123 /* Guess we have to create it */ 00124 res = ast_db_put(db_family, key, "1"); 00125 return; 00126 } 00127 00128 sscanf(value, "%u", &v); 00129 v++; 00130 00131 if(option_verbose >= 4) 00132 ast_verbose(VERBOSE_PREFIX_4 "AlarmReceiver: New value for %s: %u\n", key, v); 00133 00134 snprintf(value, sizeof(value), "%u", v); 00135 00136 res = ast_db_put(db_family, key, value); 00137 00138 if((res)&&(option_verbose >= 4)) 00139 ast_verbose(VERBOSE_PREFIX_4 "AlarmReceiver: database_increment write error\n"); 00140 00141 return; 00142 }
static int load_config | ( | void | ) | [static] |
Definition at line 733 of file app_alarmreceiver.c.
References ALMRCV_CONFIG, ast_config_destroy(), ast_config_load(), ast_true(), ast_variable_retrieve(), ast_verbose(), option_verbose, and VERBOSE_PREFIX_4.
Referenced by load_module(), and reload().
00734 { 00735 struct ast_config *cfg; 00736 const char *p; 00737 00738 /* Read in the config file */ 00739 00740 cfg = ast_config_load(ALMRCV_CONFIG); 00741 00742 if(!cfg){ 00743 00744 if(option_verbose >= 4) 00745 ast_verbose(VERBOSE_PREFIX_4 "AlarmReceiver: No config file\n"); 00746 return 0; 00747 } 00748 else{ 00749 00750 00751 p = ast_variable_retrieve(cfg, "general", "eventcmd"); 00752 00753 if(p){ 00754 ast_copy_string(event_app, p, sizeof(event_app)); 00755 event_app[sizeof(event_app) - 1] = '\0'; 00756 } 00757 00758 p = ast_variable_retrieve(cfg, "general", "loudness"); 00759 if(p){ 00760 toneloudness = atoi(p); 00761 if(toneloudness < 100) 00762 toneloudness = 100; 00763 if(toneloudness > 8192) 00764 toneloudness = 8192; 00765 } 00766 p = ast_variable_retrieve(cfg, "general", "fdtimeout"); 00767 if(p){ 00768 fdtimeout = atoi(p); 00769 if(fdtimeout < 1000) 00770 fdtimeout = 1000; 00771 if(fdtimeout > 10000) 00772 fdtimeout = 10000; 00773 } 00774 00775 p = ast_variable_retrieve(cfg, "general", "sdtimeout"); 00776 if(p){ 00777 sdtimeout = atoi(p); 00778 if(sdtimeout < 110) 00779 sdtimeout = 110; 00780 if(sdtimeout > 4000) 00781 sdtimeout = 4000; 00782 00783 } 00784 00785 p = ast_variable_retrieve(cfg, "general", "logindividualevents"); 00786 if(p){ 00787 log_individual_events = ast_true(p); 00788 00789 } 00790 00791 p = ast_variable_retrieve(cfg, "general", "eventspooldir"); 00792 00793 if(p){ 00794 ast_copy_string(event_spool_dir, p, sizeof(event_spool_dir)); 00795 event_spool_dir[sizeof(event_spool_dir) - 1] = '\0'; 00796 } 00797 00798 p = ast_variable_retrieve(cfg, "general", "timestampformat"); 00799 00800 if(p){ 00801 ast_copy_string(time_stamp_format, p, sizeof(time_stamp_format)); 00802 time_stamp_format[sizeof(time_stamp_format) - 1] = '\0'; 00803 } 00804 00805 p = ast_variable_retrieve(cfg, "general", "db-family"); 00806 00807 if(p){ 00808 ast_copy_string(db_family, p, sizeof(db_family)); 00809 db_family[sizeof(db_family) - 1] = '\0'; 00810 } 00811 ast_config_destroy(cfg); 00812 } 00813 return 1; 00814 00815 }
static int load_module | ( | void | ) | [static] |
Definition at line 833 of file app_alarmreceiver.c.
References alarmreceiver_exec(), AST_MODULE_LOAD_DECLINE, ast_register_application(), and load_config().
00834 { 00835 if(load_config()) 00836 return ast_register_application(app, alarmreceiver_exec, synopsis, descrip); 00837 else 00838 return AST_MODULE_LOAD_DECLINE; 00839 }
static int log_events | ( | struct ast_channel * | chan, | |
char * | signalling_type, | |||
event_node_t * | event | |||
) | [static] |
Definition at line 383 of file app_alarmreceiver.c.
References ast_log(), ast_strlen_zero(), ast_verbose(), event, LOG_DEBUG, event_node::next, VERBOSE_PREFIX_4, write_event(), and write_metadata().
Referenced by alarmreceiver_exec(), and receive_ademco_contact_id().
00384 { 00385 00386 int res = 0; 00387 char workstring[sizeof(event_spool_dir)+sizeof(event_file)] = ""; 00388 int fd; 00389 FILE *logfile; 00390 event_node_t *elp = event; 00391 00392 if (!ast_strlen_zero(event_spool_dir)) { 00393 00394 /* Make a template */ 00395 00396 ast_copy_string(workstring, event_spool_dir, sizeof(workstring)); 00397 strncat(workstring, event_file, sizeof(workstring) - strlen(workstring) - 1); 00398 00399 /* Make the temporary file */ 00400 00401 fd = mkstemp(workstring); 00402 00403 if(fd == -1){ 00404 ast_verbose(VERBOSE_PREFIX_4 "AlarmReceiver: can't make temporary file\n"); 00405 ast_log(LOG_DEBUG,"AlarmReceiver: can't make temporary file\n"); 00406 res = -1; 00407 } 00408 00409 if(!res){ 00410 logfile = fdopen(fd, "w"); 00411 if(logfile){ 00412 /* Write the file */ 00413 res = write_metadata(logfile, signalling_type, chan); 00414 if(!res) 00415 while((!res) && (elp != NULL)){ 00416 res = write_event(logfile, elp); 00417 elp = elp->next; 00418 } 00419 if(!res){ 00420 if(fflush(logfile) == EOF) 00421 res = -1; 00422 if(!res){ 00423 if(fclose(logfile) == EOF) 00424 res = -1; 00425 } 00426 } 00427 } 00428 else 00429 res = -1; 00430 } 00431 } 00432 00433 return res; 00434 }
static void make_tone_burst | ( | unsigned char * | data, | |
float | freq, | |||
float | loudness, | |||
int | len, | |||
int * | x | |||
) | [static] |
Definition at line 149 of file app_alarmreceiver.c.
References AST_LIN2MU.
Referenced by send_tone_burst().
00150 { 00151 int i; 00152 float val; 00153 00154 for(i = 0; i < len; i++){ 00155 val = loudness * sin((freq * 2.0 * M_PI * (*x)++)/8000.0); 00156 data[i] = AST_LIN2MU((int)val); 00157 } 00158 00159 /* wrap back around from 8000 */ 00160 00161 if (*x >= 8000) *x = 0; 00162 return; 00163 }
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 442 of file app_alarmreceiver.c.
References ADEMCO_CONTACT_ID, ast_calloc, ast_log(), ast_safe_sleep(), ast_strlen_zero(), ast_verbose(), database_increment(), event, LOG_DEBUG, log_events(), event_node::next, option_verbose, receive_dtmf_digits(), send_tone_burst(), VERBOSE_PREFIX_2, and VERBOSE_PREFIX_4.
Referenced by alarmreceiver_exec().
00443 { 00444 int i,j; 00445 int res = 0; 00446 int checksum; 00447 char event[17]; 00448 event_node_t *enew, *elp; 00449 int got_some_digits = 0; 00450 int events_received = 0; 00451 int ack_retries = 0; 00452 00453 static char digit_map[15] = "0123456789*#ABC"; 00454 static unsigned char digit_weights[15] = {10,1,2,3,4,5,6,7,8,9,11,12,13,14,15}; 00455 00456 database_increment("calls-received"); 00457 00458 /* Wait for first event */ 00459 00460 if(option_verbose >= 4) 00461 ast_verbose(VERBOSE_PREFIX_4 "AlarmReceiver: Waiting for first event from panel\n"); 00462 00463 while(res >= 0){ 00464 00465 if(got_some_digits == 0){ 00466 00467 /* Send ACK tone sequence */ 00468 00469 00470 if(option_verbose >= 4) 00471 ast_verbose(VERBOSE_PREFIX_4 "AlarmReceiver: Sending 1400Hz 100ms burst (ACK)\n"); 00472 00473 00474 res = send_tone_burst(chan, 1400.0, 100, tldn); 00475 00476 if(!res) 00477 res = ast_safe_sleep(chan, 100); 00478 00479 if(!res){ 00480 if(option_verbose >= 4) 00481 ast_verbose(VERBOSE_PREFIX_4 "AlarmReceiver: Sending 2300Hz 100ms burst (ACK)\n"); 00482 00483 res = send_tone_burst(chan, 2300.0, 100, tldn); 00484 } 00485 00486 } 00487 00488 if( res >= 0) 00489 res = receive_dtmf_digits(chan, event, sizeof(event) - 1, fdto, sdto); 00490 00491 if (res < 0){ 00492 00493 if(events_received == 0) 00494 /* Hangup with no events received should be logged in the DB */ 00495 database_increment("no-events-received"); 00496 else{ 00497 if(ack_retries){ 00498 if(option_verbose >= 4) 00499 ast_verbose(VERBOSE_PREFIX_2 "AlarmReceiver: ACK retries during this call: %d\n", ack_retries); 00500 00501 database_increment("ack-retries"); 00502 } 00503 } 00504 if(option_verbose >= 4) 00505 ast_verbose(VERBOSE_PREFIX_4 "AlarmReceiver: App exiting...\n"); 00506 res = -1; 00507 break; 00508 } 00509 00510 if(res != 0){ 00511 /* Didn't get all of the digits */ 00512 if(option_verbose >= 2) 00513 ast_verbose(VERBOSE_PREFIX_2 "AlarmReceiver: Incomplete string: %s, trying again...\n", event); 00514 00515 if(!got_some_digits){ 00516 got_some_digits = (!ast_strlen_zero(event)) ? 1 : 0; 00517 ack_retries++; 00518 } 00519 continue; 00520 } 00521 00522 got_some_digits = 1; 00523 00524 if(option_verbose >= 2) 00525 ast_verbose(VERBOSE_PREFIX_2 "AlarmReceiver: Received Event %s\n", event); 00526 ast_log(LOG_DEBUG, "AlarmReceiver: Received event: %s\n", event); 00527 00528 /* Calculate checksum */ 00529 00530 for(j = 0, checksum = 0; j < 16; j++){ 00531 for(i = 0 ; i < sizeof(digit_map) ; i++){ 00532 if(digit_map[i] == event[j]) 00533 break; 00534 } 00535 00536 if(i == 16) 00537 break; 00538 00539 checksum += digit_weights[i]; 00540 } 00541 00542 if(i == 16){ 00543 if(option_verbose >= 2) 00544 ast_verbose(VERBOSE_PREFIX_2 "AlarmReceiver: Bad DTMF character %c, trying again\n", event[j]); 00545 continue; /* Bad character */ 00546 } 00547 00548 /* Checksum is mod(15) of the total */ 00549 00550 checksum = checksum % 15; 00551 00552 if (checksum) { 00553 database_increment("checksum-errors"); 00554 if (option_verbose >= 2) 00555 ast_verbose(VERBOSE_PREFIX_2 "AlarmReceiver: Nonzero checksum\n"); 00556 ast_log(LOG_DEBUG, "AlarmReceiver: Nonzero checksum\n"); 00557 continue; 00558 } 00559 00560 /* Check the message type for correctness */ 00561 00562 if(strncmp(event + 4, "18", 2)){ 00563 if(strncmp(event + 4, "98", 2)){ 00564 database_increment("format-errors"); 00565 if(option_verbose >= 2) 00566 ast_verbose(VERBOSE_PREFIX_2 "AlarmReceiver: Wrong message type\n"); 00567 ast_log(LOG_DEBUG, "AlarmReceiver: Wrong message type\n"); 00568 continue; 00569 } 00570 } 00571 00572 events_received++; 00573 00574 /* Queue the Event */ 00575 if (!(enew = ast_calloc(1, sizeof(*enew)))) { 00576 res = -1; 00577 break; 00578 } 00579 00580 enew->next = NULL; 00581 ast_copy_string(enew->data, event, sizeof(enew->data)); 00582 00583 /* 00584 * Insert event onto end of list 00585 */ 00586 00587 if(*ehead == NULL){ 00588 *ehead = enew; 00589 } 00590 else{ 00591 for(elp = *ehead; elp->next != NULL; elp = elp->next) 00592 ; 00593 00594 elp->next = enew; 00595 } 00596 00597 if(res > 0) 00598 res = 0; 00599 00600 /* Let the user have the option of logging the single event before sending the kissoff tone */ 00601 00602 if((res == 0) && (log_individual_events)) 00603 res = log_events(chan, ADEMCO_CONTACT_ID, enew); 00604 00605 /* Wait 200 msec before sending kissoff */ 00606 00607 if(res == 0) 00608 res = ast_safe_sleep(chan, 200); 00609 00610 /* Send the kissoff tone */ 00611 00612 if(res == 0) 00613 res = send_tone_burst(chan, 1400.0, 900, tldn); 00614 } 00615 00616 00617 return res; 00618 }
static int receive_dtmf_digits | ( | struct ast_channel * | chan, | |
char * | digit_string, | |||
int | length, | |||
int | fdto, | |||
int | sdto | |||
) | [static] |
Definition at line 238 of file app_alarmreceiver.c.
References AST_CONTROL_HANGUP, AST_FRAME_CONTROL, AST_FRAME_DTMF, ast_frfree, ast_log(), ast_read(), ast_verbose(), ast_waitfor(), f, LOG_DEBUG, option_verbose, and VERBOSE_PREFIX_4.
Referenced by receive_ademco_contact_id().
00239 { 00240 int res = 0; 00241 int i = 0; 00242 int r; 00243 struct ast_frame *f; 00244 struct timeval lastdigittime; 00245 00246 lastdigittime = ast_tvnow(); 00247 for(;;){ 00248 /* if outa time, leave */ 00249 if (ast_tvdiff_ms(ast_tvnow(), lastdigittime) > 00250 ((i > 0) ? sdto : fdto)){ 00251 if(option_verbose >= 4) 00252 ast_verbose(VERBOSE_PREFIX_4 "AlarmReceiver: DTMF Digit Timeout on %s\n", chan->name); 00253 00254 ast_log(LOG_DEBUG,"AlarmReceiver: DTMF timeout on chan %s\n",chan->name); 00255 00256 res = 1; 00257 break; 00258 } 00259 00260 if ((r = ast_waitfor(chan, -1) < 0)) { 00261 ast_log(LOG_DEBUG, "Waitfor returned %d\n", r); 00262 continue; 00263 } 00264 00265 f = ast_read(chan); 00266 00267 if (f == NULL){ 00268 res = -1; 00269 break; 00270 } 00271 00272 /* If they hung up, leave */ 00273 if ((f->frametype == AST_FRAME_CONTROL) && 00274 (f->subclass == AST_CONTROL_HANGUP)){ 00275 ast_frfree(f); 00276 res = -1; 00277 break; 00278 } 00279 00280 /* if not DTMF, just do it again */ 00281 if (f->frametype != AST_FRAME_DTMF){ 00282 ast_frfree(f); 00283 continue; 00284 } 00285 00286 digit_string[i++] = f->subclass; /* save digit */ 00287 00288 ast_frfree(f); 00289 00290 /* If we have all the digits we expect, leave */ 00291 if(i >= length) 00292 break; 00293 00294 lastdigittime = ast_tvnow(); 00295 } 00296 00297 digit_string[i] = '\0'; /* Nul terminate the end of the digit string */ 00298 return res; 00299 00300 }
static int send_tone_burst | ( | struct ast_channel * | chan, | |
float | freq, | |||
int | duration, | |||
int | tldn | |||
) | [static] |
Definition at line 170 of file app_alarmreceiver.c.
References AST_FORMAT_ULAW, AST_FRAME_VOICE, ast_frfree, AST_FRIENDLY_OFFSET, ast_log(), ast_read(), ast_verbose(), ast_waitfor(), ast_write(), ast_frame::data, ast_frame::datalen, f, ast_frame::frametype, LOG_WARNING, make_tone_burst(), ast_frame::mallocd, ast_frame::offset, option_verbose, ast_frame::samples, ast_frame::subclass, and VERBOSE_PREFIX_4.
Referenced by receive_ademco_contact_id().
00171 { 00172 int res = 0; 00173 int i = 0; 00174 int x = 0; 00175 struct ast_frame *f, wf; 00176 00177 struct { 00178 unsigned char offset[AST_FRIENDLY_OFFSET]; 00179 unsigned char buf[640]; 00180 } tone_block; 00181 00182 for(;;) 00183 { 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 = AST_FORMAT_ULAW; 00199 wf.offset = AST_FRIENDLY_OFFSET; 00200 wf.mallocd = 0; 00201 wf.data = 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 if(option_verbose >= 4) 00214 ast_verbose(VERBOSE_PREFIX_4 "AlarmReceiver: Failed to write frame on %s\n", chan->name); 00215 ast_log(LOG_WARNING, "AlarmReceiver Failed to write frame on %s\n",chan->name); 00216 res = -1; 00217 ast_frfree(f); 00218 break; 00219 } 00220 } 00221 00222 ast_frfree(f); 00223 } 00224 return res; 00225 }
static int unload_module | ( | void | ) | [static] |
Definition at line 822 of file app_alarmreceiver.c.
References ast_module_user_hangup_all, and ast_unregister_application().
00823 { 00824 int res; 00825 00826 res = ast_unregister_application(app); 00827 00828 ast_module_user_hangup_all(); 00829 00830 return res; 00831 }
static int write_event | ( | FILE * | logfile, | |
event_node_t * | event | |||
) | [static] |
Definition at line 367 of file app_alarmreceiver.c.
References event.
Referenced by log_events().
00368 { 00369 int res = 0; 00370 00371 if( fprintf(logfile, "%s\n", event->data) < 0) 00372 res = -1; 00373 00374 return res; 00375 }
static int write_metadata | ( | FILE * | logfile, | |
char * | signalling_type, | |||
struct ast_channel * | chan | |||
) | [static] |
Definition at line 306 of file app_alarmreceiver.c.
References ast_callerid_parse(), ast_localtime(), ast_log(), ast_shrink_phone_number(), ast_verbose(), ast_channel::cid, ast_callerid::cid_num, LOG_DEBUG, t, and VERBOSE_PREFIX_4.
Referenced by log_events().
00307 { 00308 int res = 0; 00309 time_t t; 00310 struct tm now; 00311 char *cl,*cn; 00312 char workstring[80]; 00313 char timestamp[80]; 00314 00315 /* Extract the caller ID location */ 00316 if (chan->cid.cid_num) 00317 ast_copy_string(workstring, chan->cid.cid_num, sizeof(workstring)); 00318 workstring[sizeof(workstring) - 1] = '\0'; 00319 00320 ast_callerid_parse(workstring, &cn, &cl); 00321 if (cl) 00322 ast_shrink_phone_number(cl); 00323 00324 00325 /* Get the current time */ 00326 00327 time(&t); 00328 ast_localtime(&t, &now, NULL); 00329 00330 /* Format the time */ 00331 00332 strftime(timestamp, sizeof(timestamp), time_stamp_format, &now); 00333 00334 00335 res = fprintf(logfile, "\n\n[metadata]\n\n"); 00336 00337 if(res >= 0) 00338 res = fprintf(logfile, "PROTOCOL=%s\n", signalling_type); 00339 00340 if(res >= 0) 00341 res = fprintf(logfile, "CALLINGFROM=%s\n", (!cl) ? "<unknown>" : cl); 00342 00343 if(res >- 0) 00344 res = fprintf(logfile, "CALLERNAME=%s\n", (!cn) ? "<unknown>" : cn); 00345 00346 if(res >= 0) 00347 res = fprintf(logfile, "TIMESTAMP=%s\n\n", timestamp); 00348 00349 if(res >= 0) 00350 res = fprintf(logfile, "[events]\n\n"); 00351 00352 if(res < 0){ 00353 ast_verbose(VERBOSE_PREFIX_4 "AlarmReceiver: can't write metadata\n"); 00354 00355 ast_log(LOG_DEBUG,"AlarmReceiver: can't write metadata\n"); 00356 } 00357 else 00358 res = 0; 00359 00360 return res; 00361 }
char* app = "AlarmReceiver" [static] |
Definition at line 71 of file app_alarmreceiver.c.
char db_family[128] = {'\0'} [static] |
Definition at line 93 of file app_alarmreceiver.c.
char* descrip [static] |
Definition at line 74 of file app_alarmreceiver.c.
char event_app[128] = {'\0'} [static] |
Definition at line 92 of file app_alarmreceiver.c.
char event_file[14] = "/event-XXXXXX" [static] |
Definition at line 98 of file app_alarmreceiver.c.
char event_spool_dir[128] = {'\0'} [static] |
Definition at line 91 of file app_alarmreceiver.c.
int fdtimeout = 2000 [static] |
Definition at line 87 of file app_alarmreceiver.c.
int log_individual_events = 0 [static] |
Definition at line 90 of file app_alarmreceiver.c.
int sdtimeout = 200 [static] |
Definition at line 88 of file app_alarmreceiver.c.
char* synopsis = "Provide support for receiving alarm reports from a burglar or fire alarm panel" [static] |
Definition at line 73 of file app_alarmreceiver.c.
char time_stamp_format[128] = {"%a %b %d, %Y @ %H:%M:%S %Z"} [static] |
Definition at line 94 of file app_alarmreceiver.c.
int toneloudness = 4096 [static] |
Definition at line 89 of file app_alarmreceiver.c.