#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.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"
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) |
static void | database_increment (char *key) |
char * | description (void) |
Provides a description of the module. | |
char * | key () |
Returns the ASTERISK_GPL_KEY. | |
static int | load_config (void) |
int | load_module (void) |
Initialize the module. | |
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) |
int | unload_module (void) |
Cleanup all module structures, sockets, etc. | |
int | usecount (void) |
Provides a usecount. | |
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 |
LOCAL_USER_DECL | |
static int | log_individual_events = 0 |
static int | sdtimeout = 200 |
STANDARD_LOCAL_USER | |
static char * | synopsis = "Provide support for receving alarm reports from a burglar or fire alarm panel" |
static char * | tdesc = "Alarm Receiver for Asterisk" |
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 details. *
*** WARNING *** WARNING *** WARNING *** WARNING *** WARNING *** WARNING *** WARNING *** WARNING ***
Definition in file app_alarmreceiver.c.
#define ADEMCO_CONTACT_ID "ADEMCO_CONTACT_ID" |
Definition at line 61 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 68 of file app_alarmreceiver.c.
static int alarmreceiver_exec | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 641 of file app_alarmreceiver.c.
References ast_channel::_state, ADEMCO_CONTACT_ID, ast_answer(), AST_FORMAT_ULAW, ast_log(), ast_safe_sleep(), ast_safe_system(), ast_set_read_format(), ast_set_write_format(), AST_STATE_UP, ast_strlen_zero(), ast_verbose(), localuser::chan, free, LOCAL_USER_ADD, LOCAL_USER_REMOVE, 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().
00642 { 00643 int res = 0; 00644 struct localuser *u; 00645 event_node_t *elp, *efree; 00646 char signalling_type[64] = ""; 00647 00648 event_node_t *event_head = NULL; 00649 00650 LOCAL_USER_ADD(u); 00651 00652 /* Set write and read formats to ULAW */ 00653 00654 if(option_verbose >= 4) 00655 ast_verbose(VERBOSE_PREFIX_4 "AlarmReceiver: Setting read and write formats to ULAW\n"); 00656 00657 if (ast_set_write_format(chan,AST_FORMAT_ULAW)){ 00658 ast_log(LOG_WARNING, "AlarmReceiver: Unable to set write format to Mu-law on %s\n",chan->name); 00659 LOCAL_USER_REMOVE(u); 00660 return -1; 00661 } 00662 00663 if (ast_set_read_format(chan,AST_FORMAT_ULAW)){ 00664 ast_log(LOG_WARNING, "AlarmReceiver: Unable to set read format to Mu-law on %s\n",chan->name); 00665 LOCAL_USER_REMOVE(u); 00666 return -1; 00667 } 00668 00669 /* Set default values for this invokation of the application */ 00670 00671 ast_copy_string(signalling_type, ADEMCO_CONTACT_ID, sizeof(signalling_type)); 00672 00673 00674 /* Answer the channel if it is not already */ 00675 00676 if(option_verbose >= 4) 00677 ast_verbose(VERBOSE_PREFIX_4 "AlarmReceiver: Answering channel\n"); 00678 00679 if (chan->_state != AST_STATE_UP) { 00680 00681 res = ast_answer(chan); 00682 00683 if (res) { 00684 LOCAL_USER_REMOVE(u); 00685 return -1; 00686 } 00687 } 00688 00689 /* Wait for the connection to settle post-answer */ 00690 00691 if(option_verbose >= 4) 00692 ast_verbose(VERBOSE_PREFIX_4 "AlarmReceiver: Waiting for connection to stabilize\n"); 00693 00694 res = ast_safe_sleep(chan, 1250); 00695 00696 /* Attempt to receive the events */ 00697 00698 if(!res){ 00699 00700 /* Determine the protocol to receive in advance */ 00701 /* Note: Ademco contact is the only one supported at this time */ 00702 /* Others may be added later */ 00703 00704 if(!strcmp(signalling_type, ADEMCO_CONTACT_ID)) 00705 receive_ademco_contact_id(chan, data, fdtimeout, sdtimeout, toneloudness, &event_head); 00706 else 00707 res = -1; 00708 } 00709 00710 00711 00712 /* Events queued by receiver, write them all out here if so configured */ 00713 00714 if((!res) && (log_individual_events == 0)){ 00715 res = log_events(chan, signalling_type, event_head); 00716 00717 } 00718 00719 /* 00720 * Do we exec a command line at the end? 00721 */ 00722 00723 if((!res) && (!ast_strlen_zero(event_app)) && (event_head)){ 00724 ast_log(LOG_DEBUG,"Alarmreceiver: executing: %s\n", event_app); 00725 ast_safe_system(event_app); 00726 } 00727 00728 /* 00729 * Free up the data allocated in our linked list 00730 */ 00731 00732 for(elp = event_head; (elp != NULL);){ 00733 efree = elp; 00734 elp = elp->next; 00735 free(efree); 00736 } 00737 00738 00739 LOCAL_USER_REMOVE(u); 00740 00741 return 0; 00742 }
static void database_increment | ( | char * | key | ) | [static] |
Definition at line 117 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().
00118 { 00119 int res = 0; 00120 unsigned v; 00121 char value[16]; 00122 00123 00124 if (ast_strlen_zero(db_family)) 00125 return; /* If not defined, don't do anything */ 00126 00127 res = ast_db_get(db_family, key, value, sizeof(value) - 1); 00128 00129 if(res){ 00130 if(option_verbose >= 4) 00131 ast_verbose(VERBOSE_PREFIX_4 "AlarmReceiver: Creating database entry %s and setting to 1\n", key); 00132 /* Guess we have to create it */ 00133 res = ast_db_put(db_family, key, "1"); 00134 return; 00135 } 00136 00137 sscanf(value, "%u", &v); 00138 v++; 00139 00140 if(option_verbose >= 4) 00141 ast_verbose(VERBOSE_PREFIX_4 "AlarmReceiver: New value for %s: %u\n", key, v); 00142 00143 snprintf(value, sizeof(value), "%u", v); 00144 00145 res = ast_db_put(db_family, key, value); 00146 00147 if((res)&&(option_verbose >= 4)) 00148 ast_verbose(VERBOSE_PREFIX_4 "AlarmReceiver: database_increment write error"); 00149 00150 return; 00151 }
char* description | ( | void | ) |
Provides a description of the module.
Definition at line 853 of file app_alarmreceiver.c.
00854 { 00855 return tdesc; 00856 }
char* key | ( | void | ) |
Returns the ASTERISK_GPL_KEY.
This returns the ASTERISK_GPL_KEY, signifiying that you agree to the terms of the GPL stated in the ASTERISK_GPL_KEY. Your module will not load if it does not return the EXACT message:
char *key(void) { return ASTERISK_GPL_KEY; }
Definition at line 865 of file app_alarmreceiver.c.
References ASTERISK_GPL_KEY.
00866 { 00867 return ASTERISK_GPL_KEY; 00868 }
static int load_config | ( | void | ) | [static] |
Definition at line 748 of file app_alarmreceiver.c.
References ALMRCV_CONFIG, ast_config_destroy(), ast_config_load(), ast_true(), ast_variable_retrieve(), ast_verbose(), cfg, option_verbose, and VERBOSE_PREFIX_4.
00749 { 00750 struct ast_config *cfg; 00751 char *p; 00752 00753 /* Read in the config file */ 00754 00755 cfg = ast_config_load(ALMRCV_CONFIG); 00756 00757 if(!cfg){ 00758 00759 if(option_verbose >= 4) 00760 ast_verbose(VERBOSE_PREFIX_4 "AlarmReceiver: No config file\n"); 00761 } 00762 else{ 00763 00764 00765 p = ast_variable_retrieve(cfg, "general", "eventcmd"); 00766 00767 if(p){ 00768 ast_copy_string(event_app, p, sizeof(event_app)); 00769 event_app[sizeof(event_app) - 1] = '\0'; 00770 } 00771 00772 p = ast_variable_retrieve(cfg, "general", "loudness"); 00773 if(p){ 00774 toneloudness = atoi(p); 00775 if(toneloudness < 100) 00776 toneloudness = 100; 00777 if(toneloudness > 8192) 00778 toneloudness = 8192; 00779 } 00780 p = ast_variable_retrieve(cfg, "general", "fdtimeout"); 00781 if(p){ 00782 fdtimeout = atoi(p); 00783 if(fdtimeout < 1000) 00784 fdtimeout = 1000; 00785 if(fdtimeout > 10000) 00786 fdtimeout = 10000; 00787 } 00788 00789 p = ast_variable_retrieve(cfg, "general", "sdtimeout"); 00790 if(p){ 00791 sdtimeout = atoi(p); 00792 if(sdtimeout < 110) 00793 sdtimeout = 110; 00794 if(sdtimeout > 4000) 00795 sdtimeout = 4000; 00796 00797 } 00798 00799 p = ast_variable_retrieve(cfg, "general", "logindividualevents"); 00800 if(p){ 00801 log_individual_events = ast_true(p); 00802 00803 } 00804 00805 p = ast_variable_retrieve(cfg, "general", "eventspooldir"); 00806 00807 if(p){ 00808 ast_copy_string(event_spool_dir, p, sizeof(event_spool_dir)); 00809 event_spool_dir[sizeof(event_spool_dir) - 1] = '\0'; 00810 } 00811 00812 p = ast_variable_retrieve(cfg, "general", "timestampformat"); 00813 00814 if(p){ 00815 ast_copy_string(time_stamp_format, p, sizeof(time_stamp_format)); 00816 time_stamp_format[sizeof(time_stamp_format) - 1] = '\0'; 00817 } 00818 00819 p = ast_variable_retrieve(cfg, "general", "db-family"); 00820 00821 if(p){ 00822 ast_copy_string(db_family, p, sizeof(db_family)); 00823 db_family[sizeof(db_family) - 1] = '\0'; 00824 } 00825 ast_config_destroy(cfg); 00826 } 00827 return 0; 00828 00829 }
int load_module | ( | void | ) |
Initialize the module.
Initialize the Agents module. This function is being called by Asterisk when loading the module. Among other thing it registers applications, cli commands and reads the cofiguration file.
Definition at line 847 of file app_alarmreceiver.c.
References alarmreceiver_exec(), ast_register_application(), and load_config().
00848 { 00849 load_config(); 00850 return ast_register_application(app, alarmreceiver_exec, synopsis, descrip); 00851 }
static int log_events | ( | struct ast_channel * | chan, | |
char * | signalling_type, | |||
event_node_t * | event | |||
) | [static] |
Definition at line 392 of file app_alarmreceiver.c.
References 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().
00393 { 00394 00395 int res = 0; 00396 char workstring[sizeof(event_spool_dir)+sizeof(event_file)] = ""; 00397 int fd; 00398 FILE *logfile; 00399 event_node_t *elp = event; 00400 00401 if (!ast_strlen_zero(event_spool_dir)) { 00402 00403 /* Make a template */ 00404 00405 ast_copy_string(workstring, event_spool_dir, sizeof(workstring)); 00406 strncat(workstring, event_file, sizeof(workstring) - strlen(workstring) - 1); 00407 00408 /* Make the temporary file */ 00409 00410 fd = mkstemp(workstring); 00411 00412 if(fd == -1){ 00413 ast_verbose(VERBOSE_PREFIX_4 "AlarmReceiver: can't make temporary file\n"); 00414 ast_log(LOG_DEBUG,"AlarmReceiver: can't make temporary file\n"); 00415 res = -1; 00416 } 00417 00418 if(!res){ 00419 logfile = fdopen(fd, "w"); 00420 if(logfile){ 00421 /* Write the file */ 00422 res = write_metadata(logfile, signalling_type, chan); 00423 if(!res) 00424 while((!res) && (elp != NULL)){ 00425 res = write_event(logfile, elp); 00426 elp = elp->next; 00427 } 00428 if(!res){ 00429 if(fflush(logfile) == EOF) 00430 res = -1; 00431 if(!res){ 00432 if(fclose(logfile) == EOF) 00433 res = -1; 00434 } 00435 } 00436 } 00437 else 00438 res = -1; 00439 } 00440 } 00441 00442 return res; 00443 }
static void make_tone_burst | ( | unsigned char * | data, | |
float | freq, | |||
float | loudness, | |||
int | len, | |||
int * | x | |||
) | [static] |
Definition at line 158 of file app_alarmreceiver.c.
References AST_LIN2MU.
Referenced by send_tone_burst().
00159 { 00160 int i; 00161 float val; 00162 00163 for(i = 0; i < len; i++){ 00164 val = loudness * sin((freq * 2.0 * M_PI * (*x)++)/8000.0); 00165 data[i] = AST_LIN2MU((int)val); 00166 } 00167 00168 /* wrap back around from 8000 */ 00169 00170 if (*x >= 8000) *x = 0; 00171 return; 00172 }
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 451 of file app_alarmreceiver.c.
References ADEMCO_CONTACT_ID, ast_log(), ast_safe_sleep(), ast_strlen_zero(), ast_verbose(), event_node::data, database_increment(), LOG_DEBUG, log_events(), LOG_WARNING, malloc, event_node::next, option_verbose, receive_dtmf_digits(), send_tone_burst(), VERBOSE_PREFIX_1, VERBOSE_PREFIX_2, and VERBOSE_PREFIX_4.
Referenced by alarmreceiver_exec().
00452 { 00453 int i,j; 00454 int res = 0; 00455 int checksum; 00456 char event[17]; 00457 event_node_t *enew, *elp; 00458 int got_some_digits = 0; 00459 int events_received = 0; 00460 int ack_retries = 0; 00461 00462 static char digit_map[15] = "0123456789*#ABC"; 00463 static unsigned char digit_weights[15] = {10,1,2,3,4,5,6,7,8,9,11,12,13,14,15}; 00464 00465 database_increment("calls-received"); 00466 00467 /* Wait for first event */ 00468 00469 if(option_verbose >= 4) 00470 ast_verbose(VERBOSE_PREFIX_4 "AlarmReceiver: Waiting for first event from panel\n"); 00471 00472 while(res >= 0){ 00473 00474 if(got_some_digits == 0){ 00475 00476 /* Send ACK tone sequence */ 00477 00478 00479 if(option_verbose >= 4) 00480 ast_verbose(VERBOSE_PREFIX_4 "AlarmReceiver: Sending 1400Hz 100ms burst (ACK)\n"); 00481 00482 00483 res = send_tone_burst(chan, 1400.0, 100, tldn); 00484 00485 if(!res) 00486 res = ast_safe_sleep(chan, 100); 00487 00488 if(!res){ 00489 if(option_verbose >= 4) 00490 ast_verbose(VERBOSE_PREFIX_4 "AlarmReceiver: Sending 2300Hz 100ms burst (ACK)\n"); 00491 00492 res = send_tone_burst(chan, 2300.0, 100, tldn); 00493 } 00494 00495 } 00496 00497 if( res >= 0) 00498 res = receive_dtmf_digits(chan, event, sizeof(event) - 1, fdto, sdto); 00499 00500 if (res < 0){ 00501 00502 if(events_received == 0) 00503 /* Hangup with no events received should be logged in the DB */ 00504 database_increment("no-events-received"); 00505 else{ 00506 if(ack_retries){ 00507 if(option_verbose >= 4) 00508 ast_verbose(VERBOSE_PREFIX_2 "AlarmReceiver: ACK retries during this call: %d\n", ack_retries); 00509 00510 database_increment("ack-retries"); 00511 } 00512 } 00513 if(option_verbose >= 4) 00514 ast_verbose(VERBOSE_PREFIX_4 "AlarmReceiver: App exiting...\n"); 00515 res = -1; 00516 break; 00517 } 00518 00519 if(res != 0){ 00520 /* Didn't get all of the digits */ 00521 if(option_verbose >= 2) 00522 ast_verbose(VERBOSE_PREFIX_2 "AlarmReceiver: Incomplete string: %s, trying again...\n", event); 00523 00524 if(!got_some_digits){ 00525 got_some_digits = (!ast_strlen_zero(event)) ? 1 : 0; 00526 ack_retries++; 00527 } 00528 continue; 00529 } 00530 00531 got_some_digits = 1; 00532 00533 if(option_verbose >= 2) 00534 ast_verbose(VERBOSE_PREFIX_2 "AlarmReceiver: Received Event %s\n", event); 00535 ast_log(LOG_DEBUG, "AlarmReceiver: Received event: %s\n", event); 00536 00537 /* Calculate checksum */ 00538 00539 for(j = 0, checksum = 0; j < 16; j++){ 00540 for(i = 0 ; i < sizeof(digit_map) ; i++){ 00541 if(digit_map[i] == event[j]) 00542 break; 00543 } 00544 00545 if(i == 16) 00546 break; 00547 00548 checksum += digit_weights[i]; 00549 } 00550 00551 if(i == 16){ 00552 if(option_verbose >= 2) 00553 ast_verbose(VERBOSE_PREFIX_2 "AlarmReceiver: Bad DTMF character %c, trying again\n", event[j]); 00554 continue; /* Bad character */ 00555 } 00556 00557 /* Checksum is mod(15) of the total */ 00558 00559 checksum = checksum % 15; 00560 00561 if(checksum){ 00562 database_increment("checksum-errors"); 00563 if(option_verbose >= 2) 00564 ast_verbose(VERBOSE_PREFIX_2 "AlarmReceiver: Nonzero checksum\n"); 00565 ast_log(LOG_DEBUG, "AlarmReceiver: Nonzero checksum\n"); 00566 continue; 00567 } 00568 00569 /* Check the message type for correctness */ 00570 00571 if(strncmp(event + 4, "18", 2)){ 00572 if(strncmp(event + 4, "98", 2)){ 00573 database_increment("format-errors"); 00574 if(option_verbose >= 2) 00575 ast_verbose(VERBOSE_PREFIX_2 "AlarmReceiver: Wrong message type\n"); 00576 ast_log(LOG_DEBUG, "AlarmReceiver: Wrong message type\n"); 00577 continue; 00578 } 00579 } 00580 00581 events_received++; 00582 00583 /* Queue the Event */ 00584 00585 if((enew = malloc(sizeof(event_node_t))) == NULL){ 00586 if(option_verbose >= 1) 00587 ast_verbose(VERBOSE_PREFIX_1 "AlarmReceiver: Failed to allocate memory\n"); 00588 ast_log(LOG_WARNING, "AlarmReceiver Failed to allocate memory\n"); 00589 res = -1; 00590 break; 00591 } 00592 00593 memset(enew, 0, sizeof(event_node_t)); 00594 00595 enew->next = NULL; 00596 ast_copy_string(enew->data, event, sizeof(enew->data)); 00597 00598 /* 00599 * Insert event onto end of list 00600 */ 00601 00602 if(*ehead == NULL){ 00603 *ehead = enew; 00604 } 00605 else{ 00606 for(elp = *ehead; elp->next != NULL; elp = elp->next) 00607 ; 00608 00609 elp->next = enew; 00610 } 00611 00612 if(res > 0) 00613 res = 0; 00614 00615 /* Let the user have the option of logging the single event before sending the kissoff tone */ 00616 00617 if((res == 0) && (log_individual_events)) 00618 res = log_events(chan, ADEMCO_CONTACT_ID, enew); 00619 00620 /* Wait 200 msec before sending kissoff */ 00621 00622 if(res == 0) 00623 res = ast_safe_sleep(chan, 200); 00624 00625 /* Send the kissoff tone */ 00626 00627 if(res == 0) 00628 res = send_tone_burst(chan, 1400.0, 900, tldn); 00629 } 00630 00631 00632 return res; 00633 }
static int receive_dtmf_digits | ( | struct ast_channel * | chan, | |
char * | digit_string, | |||
int | length, | |||
int | fdto, | |||
int | sdto | |||
) | [static] |
Definition at line 247 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(), ast_frame::frametype, LOG_DEBUG, ast_channel::name, option_verbose, ast_frame::subclass, and VERBOSE_PREFIX_4.
Referenced by receive_ademco_contact_id().
00248 { 00249 int res = 0; 00250 int i = 0; 00251 int r; 00252 struct ast_frame *f; 00253 struct timeval lastdigittime; 00254 00255 lastdigittime = ast_tvnow(); 00256 for(;;){ 00257 /* if outa time, leave */ 00258 if (ast_tvdiff_ms(ast_tvnow(), lastdigittime) > 00259 ((i > 0) ? sdto : fdto)){ 00260 if(option_verbose >= 4) 00261 ast_verbose(VERBOSE_PREFIX_4 "AlarmReceiver: DTMF Digit Timeout on %s\n", chan->name); 00262 00263 ast_log(LOG_DEBUG,"AlarmReceiver: DTMF timeout on chan %s\n",chan->name); 00264 00265 res = 1; 00266 break; 00267 } 00268 00269 if ((r = ast_waitfor(chan, -1) < 0)) { 00270 ast_log(LOG_DEBUG, "Waitfor returned %d\n", r); 00271 continue; 00272 } 00273 00274 f = ast_read(chan); 00275 00276 if (f == NULL){ 00277 res = -1; 00278 break; 00279 } 00280 00281 /* If they hung up, leave */ 00282 if ((f->frametype == AST_FRAME_CONTROL) && 00283 (f->subclass == AST_CONTROL_HANGUP)){ 00284 ast_frfree(f); 00285 res = -1; 00286 break; 00287 } 00288 00289 /* if not DTMF, just do it again */ 00290 if (f->frametype != AST_FRAME_DTMF){ 00291 ast_frfree(f); 00292 continue; 00293 } 00294 00295 digit_string[i++] = f->subclass; /* save digit */ 00296 00297 ast_frfree(f); 00298 00299 /* If we have all the digits we expect, leave */ 00300 if(i >= length) 00301 break; 00302 00303 lastdigittime = ast_tvnow(); 00304 } 00305 00306 digit_string[i] = '\0'; /* Nul terminate the end of the digit string */ 00307 return res; 00308 00309 }
static int send_tone_burst | ( | struct ast_channel * | chan, | |
float | freq, | |||
int | duration, | |||
int | tldn | |||
) | [static] |
Definition at line 179 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, 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().
00180 { 00181 int res = 0; 00182 int i = 0; 00183 int x = 0; 00184 struct ast_frame *f, wf; 00185 00186 struct { 00187 unsigned char offset[AST_FRIENDLY_OFFSET]; 00188 unsigned char buf[640]; 00189 } tone_block; 00190 00191 for(;;) 00192 { 00193 00194 if (ast_waitfor(chan, -1) < 0){ 00195 res = -1; 00196 break; 00197 } 00198 00199 f = ast_read(chan); 00200 if (!f){ 00201 res = -1; 00202 break; 00203 } 00204 00205 if (f->frametype == AST_FRAME_VOICE) { 00206 wf.frametype = AST_FRAME_VOICE; 00207 wf.subclass = AST_FORMAT_ULAW; 00208 wf.offset = AST_FRIENDLY_OFFSET; 00209 wf.mallocd = 0; 00210 wf.data = tone_block.buf; 00211 wf.datalen = f->datalen; 00212 wf.samples = wf.datalen; 00213 00214 make_tone_burst(tone_block.buf, freq, (float) tldn, wf.datalen, &x); 00215 00216 i += wf.datalen / 8; 00217 if (i > duration) { 00218 ast_frfree(f); 00219 break; 00220 } 00221 if (ast_write(chan, &wf)){ 00222 if(option_verbose >= 4) 00223 ast_verbose(VERBOSE_PREFIX_4 "AlarmReceiver: Failed to write frame on %s\n", chan->name); 00224 ast_log(LOG_WARNING, "AlarmReceiver Failed to write frame on %s\n",chan->name); 00225 res = -1; 00226 ast_frfree(f); 00227 break; 00228 } 00229 } 00230 00231 ast_frfree(f); 00232 } 00233 return res; 00234 }
int unload_module | ( | void | ) |
Cleanup all module structures, sockets, etc.
This is called at exit. Any registrations and memory allocations need to be unregistered and free'd here. Nothing else will do these for you (until exit).
Definition at line 836 of file app_alarmreceiver.c.
References ast_unregister_application(), and STANDARD_HANGUP_LOCALUSERS.
00837 { 00838 int res; 00839 00840 res = ast_unregister_application(app); 00841 00842 STANDARD_HANGUP_LOCALUSERS; 00843 00844 return res; 00845 }
int usecount | ( | void | ) |
Provides a usecount.
This function will be called by various parts of asterisk. Basically, all it has to do is to return a usecount when called. You will need to maintain your usecount within the module somewhere. The usecount should be how many channels provided by this module are in use.
Definition at line 858 of file app_alarmreceiver.c.
References STANDARD_USECOUNT.
00859 { 00860 int res; 00861 STANDARD_USECOUNT(res); 00862 return res; 00863 }
static int write_event | ( | FILE * | logfile, | |
event_node_t * | event | |||
) | [static] |
Definition at line 376 of file app_alarmreceiver.c.
References event_node::data.
Referenced by log_events().
00377 { 00378 int res = 0; 00379 00380 if( fprintf(logfile, "%s\n", event->data) < 0) 00381 res = -1; 00382 00383 return res; 00384 }
static int write_metadata | ( | FILE * | logfile, | |
char * | signalling_type, | |||
struct ast_channel * | chan | |||
) | [static] |
Definition at line 315 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().
00316 { 00317 int res = 0; 00318 time_t t; 00319 struct tm now; 00320 char *cl,*cn; 00321 char workstring[80]; 00322 char timestamp[80]; 00323 00324 /* Extract the caller ID location */ 00325 if (chan->cid.cid_num) 00326 ast_copy_string(workstring, chan->cid.cid_num, sizeof(workstring)); 00327 workstring[sizeof(workstring) - 1] = '\0'; 00328 00329 ast_callerid_parse(workstring, &cn, &cl); 00330 if (cl) 00331 ast_shrink_phone_number(cl); 00332 00333 00334 /* Get the current time */ 00335 00336 time(&t); 00337 ast_localtime(&t, &now, NULL); 00338 00339 /* Format the time */ 00340 00341 strftime(timestamp, sizeof(timestamp), time_stamp_format, &now); 00342 00343 00344 res = fprintf(logfile, "\n\n[metadata]\n\n"); 00345 00346 if(res >= 0) 00347 res = fprintf(logfile, "PROTOCOL=%s\n", signalling_type); 00348 00349 if(res >= 0) 00350 res = fprintf(logfile, "CALLINGFROM=%s\n", (!cl) ? "<unknown>" : cl); 00351 00352 if(res >- 0) 00353 res = fprintf(logfile, "CALLERNAME=%s\n", (!cn) ? "<unknown>" : cn); 00354 00355 if(res >= 0) 00356 res = fprintf(logfile, "TIMESTAMP=%s\n\n", timestamp); 00357 00358 if(res >= 0) 00359 res = fprintf(logfile, "[events]\n\n"); 00360 00361 if(res < 0){ 00362 ast_verbose(VERBOSE_PREFIX_4 "AlarmReceiver: can't write metadata\n"); 00363 00364 ast_log(LOG_DEBUG,"AlarmReceiver: can't write metadata\n"); 00365 } 00366 else 00367 res = 0; 00368 00369 return res; 00370 }
char* app = "AlarmReceiver" [static] |
Definition at line 72 of file app_alarmreceiver.c.
char db_family[128] = {'\0'} [static] |
Definition at line 94 of file app_alarmreceiver.c.
char* descrip [static] |
Definition at line 75 of file app_alarmreceiver.c.
char event_app[128] = {'\0'} [static] |
Definition at line 93 of file app_alarmreceiver.c.
char event_file[14] = "/event-XXXXXX" [static] |
Definition at line 101 of file app_alarmreceiver.c.
char event_spool_dir[128] = {'\0'} [static] |
Definition at line 92 of file app_alarmreceiver.c.
int fdtimeout = 2000 [static] |
Definition at line 88 of file app_alarmreceiver.c.
Definition at line 107 of file app_alarmreceiver.c.
int log_individual_events = 0 [static] |
Definition at line 91 of file app_alarmreceiver.c.
int sdtimeout = 200 [static] |
Definition at line 89 of file app_alarmreceiver.c.
Definition at line 105 of file app_alarmreceiver.c.
char* synopsis = "Provide support for receving alarm reports from a burglar or fire alarm panel" [static] |
Definition at line 74 of file app_alarmreceiver.c.
char* tdesc = "Alarm Receiver for Asterisk" [static] |
Definition at line 70 of file app_alarmreceiver.c.
char time_stamp_format[128] = {"%a %b %d, %Y @ %H:%M:%S %Z"} [static] |
Definition at line 95 of file app_alarmreceiver.c.
int toneloudness = 4096 [static] |
Definition at line 90 of file app_alarmreceiver.c.