#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 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 | AST_MODFLAG_BUILDSUM, .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 = "361d7bb937402d51e4658efb5b4d76e4" , .load = load_module, .unload = unload_module, } |
static char * | app = "AlarmReceiver" |
static const struct ast_module_info * | ast_module_info = &__mod_info |
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 void __reg_module | ( | void | ) | [static] |
Definition at line 841 of file app_alarmreceiver.c.
static void __unreg_module | ( | void | ) | [static] |
Definition at line 841 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_copy_string(), 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, ast_channel::name, 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 }
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, "%30u", &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_copy_string(), 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_copy_string(), ast_log(), ast_strlen_zero(), ast_verbose(), 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_copy_string(), ast_log(), ast_safe_sleep(), ast_strlen_zero(), ast_verbose(), database_increment(), 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_tvdiff_ms(), ast_tvnow(), ast_verbose(), ast_waitfor(), f, LOG_DEBUG, ast_channel::name, 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_node::data.
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_copy_string(), 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 }
struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT | AST_MODFLAG_BUILDSUM, .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 = "361d7bb937402d51e4658efb5b4d76e4" , .load = load_module, .unload = unload_module, } [static] |
Definition at line 841 of file app_alarmreceiver.c.
char* app = "AlarmReceiver" [static] |
Definition at line 71 of file app_alarmreceiver.c.
const struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 841 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.