Sat Mar 10 01:54:30 2012

Asterisk developer's documentation


app_alarmreceiver.c File Reference

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 event_node event_node_t

Functions

static void __reg_module (void)
static void __unreg_module (void)
static int alarmreceiver_exec (struct ast_channel *chan, const char *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, 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 struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .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 = "88eaa8f5c1bd988bedd71113385e0886" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, }
static const char app [] = "AlarmReceiver"
static struct ast_module_infoast_module_info = &__mod_info
static char db_family [128] = {'\0'}
static char event_app [128] = {'\0'}
static char event_file [14] = "/event-XXXXXX"
static char event_spool_dir [128] = {'\0'}
static int fdtimeout = 2000
static int log_individual_events = 0
static int sdtimeout = 200
static char time_stamp_format [128] = {"%a %b %d, %Y @ %H:%M:%S %Z"}
static int toneloudness = 4096


Detailed Description

Central Station Alarm receiver for Ademco Contact ID.

Author:
Steve Rodgers <hwstar@rodgers.sdcoxmail.com>
*** 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 Documentation

#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 Documentation

typedef struct event_node event_node_t

Definition at line 67 of file app_alarmreceiver.c.


Function Documentation

static void __reg_module ( void   )  [static]

Definition at line 738 of file app_alarmreceiver.c.

static void __unreg_module ( void   )  [static]

Definition at line 738 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, ast_channel::name, 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 }

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_flags, CONFIG_STATUS_FILEINVALID, and LOG_ERROR.

Referenced by __reload(), ast_ais_evt_load_module(), ast_features_init(), ast_features_reload(), handle_voicemail_reload(), load_module(), reload(), and reload_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, 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(), f, ast_channel::hangupcause, and ast_channel::name.

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 }


Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .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 = "88eaa8f5c1bd988bedd71113385e0886" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, } [static]

Definition at line 738 of file app_alarmreceiver.c.

const char app[] = "AlarmReceiver" [static]

Definition at line 69 of file app_alarmreceiver.c.

struct ast_module_info* ast_module_info = &__mod_info [static]

Definition at line 738 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.


Generated on Sat Mar 10 01:54:31 2012 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7