Thu Jul 9 13:40:43 2009

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, 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 , .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 = "068e67f60f50dd9ee86464c05884a49d" , .load = load_module, .unload = unload_module, }
static char * app = "AlarmReceiver"
static const struct ast_module_infoast_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


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 56 of file app_alarmreceiver.c.

Referenced by alarmreceiver_exec(), and receive_ademco_contact_id().

#define ALMRCV_CONFIG   "alarmreceiver.conf"

Definition at line 55 of file app_alarmreceiver.c.

Referenced by load_config().


Typedef Documentation

typedef struct event_node event_node_t

Definition at line 63 of file app_alarmreceiver.c.


Function Documentation

static void __reg_module ( void   )  [static]

Definition at line 715 of file app_alarmreceiver.c.

static void __unreg_module ( void   )  [static]

Definition at line 715 of file app_alarmreceiver.c.

static int alarmreceiver_exec ( struct ast_channel chan,
void *  data 
) [static]

Definition at line 555 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, chan, log_events(), LOG_WARNING, ast_channel::name, event_node::next, and receive_ademco_contact_id().

Referenced by load_module().

00556 {
00557    int res = 0;
00558    event_node_t *elp, *efree;
00559    char signalling_type[64] = "";
00560    event_node_t *event_head = NULL;
00561 
00562    /* Set write and read formats to ULAW */
00563    ast_verb(4, "AlarmReceiver: Setting read and write formats to ULAW\n");
00564 
00565    if (ast_set_write_format(chan,AST_FORMAT_ULAW)) {
00566       ast_log(LOG_WARNING, "AlarmReceiver: Unable to set write format to Mu-law on %s\n",chan->name);
00567       return -1;
00568    }
00569 
00570    if (ast_set_read_format(chan,AST_FORMAT_ULAW)) {
00571       ast_log(LOG_WARNING, "AlarmReceiver: Unable to set read format to Mu-law on %s\n",chan->name);
00572       return -1;
00573    }
00574 
00575    /* Set default values for this invocation of the application */
00576    ast_copy_string(signalling_type, ADEMCO_CONTACT_ID, sizeof(signalling_type));
00577 
00578    /* Answer the channel if it is not already */
00579    ast_verb(4, "AlarmReceiver: Answering channel\n");
00580    if (chan->_state != AST_STATE_UP) {
00581       if ((res = ast_answer(chan)))
00582          return -1;
00583    }
00584 
00585    /* Wait for the connection to settle post-answer */
00586    ast_verb(4, "AlarmReceiver: Waiting for connection to stabilize\n");
00587    res = ast_safe_sleep(chan, 1250);
00588 
00589    /* Attempt to receive the events */
00590    if (!res) {
00591       /* Determine the protocol to receive in advance */
00592       /* Note: Ademco contact is the only one supported at this time */
00593       /* Others may be added later */
00594       if(!strcmp(signalling_type, ADEMCO_CONTACT_ID))
00595          receive_ademco_contact_id(chan, data, fdtimeout, sdtimeout, toneloudness, &event_head);
00596       else
00597          res = -1;
00598    }
00599 
00600    /* Events queued by receiver, write them all out here if so configured */
00601    if ((!res) && (log_individual_events == 0))
00602       res = log_events(chan, signalling_type, event_head);
00603 
00604    /*
00605    * Do we exec a command line at the end?
00606    */
00607    if ((!res) && (!ast_strlen_zero(event_app)) && (event_head)) {
00608       ast_debug(1,"Alarmreceiver: executing: %s\n", event_app);
00609       ast_safe_system(event_app);
00610    }
00611 
00612    /*
00613    * Free up the data allocated in our linked list
00614    */
00615    for (elp = event_head; (elp != NULL);) {
00616       efree = elp;
00617       elp = elp->next;
00618       ast_free(efree);
00619    }
00620 
00621    return 0;
00622 }

static void database_increment ( char *  key  )  [static]

Definition at line 99 of file app_alarmreceiver.c.

References ast_db_get(), ast_db_put(), ast_strlen_zero(), and ast_verb.

Referenced by receive_ademco_contact_id().

00100 {
00101    int res = 0;
00102    unsigned v;
00103    char value[16];
00104    
00105    
00106    if (ast_strlen_zero(db_family))
00107       return; /* If not defined, don't do anything */
00108    
00109    res = ast_db_get(db_family, key, value, sizeof(value) - 1);
00110    
00111    if (res) {
00112       ast_verb(4, "AlarmReceiver: Creating database entry %s and setting to 1\n", key);
00113       /* Guess we have to create it */
00114       res = ast_db_put(db_family, key, "1");
00115       return;
00116    }
00117    
00118    sscanf(value, "%u", &v);
00119    v++;
00120 
00121    ast_verb(4, "AlarmReceiver: New value for %s: %u\n", key, v);
00122 
00123    snprintf(value, sizeof(value), "%u", v);
00124 
00125    res = ast_db_put(db_family, key, value);
00126 
00127    if (res)
00128       ast_verb(4, "AlarmReceiver: database_increment write error\n");
00129 
00130    return;
00131 }

static int load_config ( void   )  [static]

Definition at line 627 of file app_alarmreceiver.c.

References ALMRCV_CONFIG, ast_config_destroy(), ast_config_load, ast_copy_string(), ast_true(), ast_variable_retrieve(), and ast_verb.

00628 {
00629    struct ast_config *cfg;
00630    const char *p;
00631    struct ast_flags config_flags = { 0 };
00632 
00633    /* Read in the config file */
00634    cfg = ast_config_load(ALMRCV_CONFIG, config_flags);
00635 
00636    if (!cfg) {
00637       ast_verb(4, "AlarmReceiver: No config file\n");
00638       return 0;
00639    } else {
00640       p = ast_variable_retrieve(cfg, "general", "eventcmd");
00641       if (p) {
00642          ast_copy_string(event_app, p, sizeof(event_app));
00643          event_app[sizeof(event_app) - 1] = '\0';
00644       }
00645       p = ast_variable_retrieve(cfg, "general", "loudness");
00646       if (p) {
00647          toneloudness = atoi(p);
00648          if(toneloudness < 100)
00649             toneloudness = 100;
00650          if(toneloudness > 8192)
00651             toneloudness = 8192;
00652       }
00653       p = ast_variable_retrieve(cfg, "general", "fdtimeout");
00654       if (p) {
00655          fdtimeout = atoi(p);
00656          if(fdtimeout < 1000)
00657             fdtimeout = 1000;
00658          if(fdtimeout > 10000)
00659             fdtimeout = 10000;
00660       }
00661 
00662       p = ast_variable_retrieve(cfg, "general", "sdtimeout");
00663       if (p) {
00664          sdtimeout = atoi(p);
00665          if(sdtimeout < 110)
00666             sdtimeout = 110;
00667          if(sdtimeout > 4000)
00668             sdtimeout = 4000;
00669       }
00670 
00671       p = ast_variable_retrieve(cfg, "general", "logindividualevents");
00672       if (p)
00673          log_individual_events = ast_true(p);
00674 
00675       p = ast_variable_retrieve(cfg, "general", "eventspooldir");
00676       if (p) {
00677          ast_copy_string(event_spool_dir, p, sizeof(event_spool_dir));
00678          event_spool_dir[sizeof(event_spool_dir) - 1] = '\0';
00679       }
00680 
00681       p = ast_variable_retrieve(cfg, "general", "timestampformat");
00682       if (p) {
00683          ast_copy_string(time_stamp_format, p, sizeof(time_stamp_format));
00684          time_stamp_format[sizeof(time_stamp_format) - 1] = '\0';
00685       }
00686 
00687       p = ast_variable_retrieve(cfg, "general", "db-family");
00688       if (p) {
00689          ast_copy_string(db_family, p, sizeof(db_family));
00690          db_family[sizeof(db_family) - 1] = '\0';
00691       }
00692       ast_config_destroy(cfg);
00693    }
00694    return 1;
00695 }

static int load_module ( void   )  [static]

Definition at line 705 of file app_alarmreceiver.c.

References alarmreceiver_exec(), AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_SUCCESS, ast_register_application, and load_config().

00706 {
00707    if (load_config()) {
00708       if (ast_register_application(app, alarmreceiver_exec, synopsis, descrip))
00709          return AST_MODULE_LOAD_FAILURE;
00710       return AST_MODULE_LOAD_SUCCESS;
00711    } else
00712       return AST_MODULE_LOAD_DECLINE;
00713 }

static int log_events ( struct ast_channel chan,
char *  signalling_type,
event_node_t event 
) [static]

Definition at line 352 of file app_alarmreceiver.c.

References ast_copy_string(), ast_debug, ast_strlen_zero(), ast_verb, chan, event_node::next, write_event(), and write_metadata().

Referenced by alarmreceiver_exec(), and receive_ademco_contact_id().

00353 {
00354 
00355    int res = 0;
00356    char workstring[sizeof(event_spool_dir)+sizeof(event_file)] = "";
00357    int fd;
00358    FILE *logfile;
00359    event_node_t *elp = event;
00360    
00361    if (!ast_strlen_zero(event_spool_dir)) {
00362       
00363       /* Make a template */
00364       ast_copy_string(workstring, event_spool_dir, sizeof(workstring));
00365       strncat(workstring, event_file, sizeof(workstring) - strlen(workstring) - 1);
00366       
00367       /* Make the temporary file */
00368       fd = mkstemp(workstring);
00369       
00370       if (fd == -1) {
00371          ast_verb(3, "AlarmReceiver: can't make temporary file\n");
00372          ast_debug(1,"AlarmReceiver: can't make temporary file\n");
00373          res = -1;
00374       }
00375 
00376       if (!res) {
00377          logfile = fdopen(fd, "w");
00378          if (logfile) {
00379             /* Write the file */
00380             res = write_metadata(logfile, signalling_type, chan);
00381             if (!res)
00382                while ((!res) && (elp != NULL)) {
00383                   res = write_event(logfile, elp);
00384                   elp = elp->next;
00385                }
00386             if (!res) {
00387                if (fflush(logfile) == EOF)
00388                   res = -1;
00389                if (!res) {
00390                   if (fclose(logfile) == EOF)
00391                      res = -1;
00392                }
00393             }
00394          } else
00395             res = -1;
00396       }
00397    }
00398 
00399    return res;
00400 }

static void make_tone_burst ( unsigned char *  data,
float  freq,
float  loudness,
int  len,
int *  x 
) [static]

Definition at line 137 of file app_alarmreceiver.c.

References AST_LIN2MU.

Referenced by send_tone_burst().

00138 {
00139    int     i;
00140    float   val;
00141 
00142    for (i = 0; i < len; i++) {
00143       val = loudness * sin((freq * 2.0 * M_PI * (*x)++)/8000.0);
00144       data[i] = AST_LIN2MU((int)val);
00145    }
00146 
00147    /* wrap back around from 8000 */
00148 
00149    if (*x >= 8000)
00150       *x = 0;
00151    return;
00152 }

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 407 of file app_alarmreceiver.c.

References ADEMCO_CONTACT_ID, ast_calloc, ast_copy_string(), ast_debug, ast_safe_sleep(), ast_strlen_zero(), ast_verb, chan, database_increment(), log_events(), event_node::next, receive_dtmf_digits(), and send_tone_burst().

Referenced by alarmreceiver_exec().

00408 {
00409    int i, j;
00410    int res = 0;
00411    int checksum;
00412    char event[17];
00413    event_node_t *enew, *elp;
00414    int got_some_digits = 0;
00415    int events_received = 0;
00416    int ack_retries = 0;
00417    
00418    static char digit_map[15] = "0123456789*#ABC";
00419    static unsigned char digit_weights[15] = {10,1,2,3,4,5,6,7,8,9,11,12,13,14,15};
00420 
00421    database_increment("calls-received");
00422 
00423    /* Wait for first event */
00424    ast_verb(4, "AlarmReceiver: Waiting for first event from panel\n");
00425 
00426    while (res >= 0) {
00427       if (got_some_digits == 0) {
00428          /* Send ACK tone sequence */
00429          ast_verb(4, "AlarmReceiver: Sending 1400Hz 100ms burst (ACK)\n");
00430          res = send_tone_burst(chan, 1400.0, 100, tldn);
00431          if (!res)
00432             res = ast_safe_sleep(chan, 100);
00433          if (!res) {
00434             ast_verb(4, "AlarmReceiver: Sending 2300Hz 100ms burst (ACK)\n");
00435             res = send_tone_burst(chan, 2300.0, 100, tldn);
00436          }
00437       }
00438       if ( res >= 0)
00439          res = receive_dtmf_digits(chan, event, sizeof(event) - 1, fdto, sdto);
00440       if (res < 0) {
00441          if (events_received == 0) {
00442             /* Hangup with no events received should be logged in the DB */
00443             database_increment("no-events-received");
00444          } else {
00445             if (ack_retries) {
00446                ast_verb(4, "AlarmReceiver: ACK retries during this call: %d\n", ack_retries);
00447                database_increment("ack-retries");
00448             }
00449          }
00450          ast_verb(4, "AlarmReceiver: App exiting...\n");
00451          res = -1;
00452          break;
00453       }
00454 
00455       if (res != 0) {
00456          /* Didn't get all of the digits */
00457          ast_verb(2, "AlarmReceiver: Incomplete string: %s, trying again...\n", event);
00458 
00459          if (!got_some_digits) {
00460             got_some_digits = (!ast_strlen_zero(event)) ? 1 : 0;
00461             ack_retries++;
00462          }
00463          continue;
00464       }
00465 
00466       got_some_digits = 1;
00467 
00468       ast_verb(2, "AlarmReceiver: Received Event %s\n", event);
00469       ast_debug(1, "AlarmReceiver: Received event: %s\n", event);
00470 
00471       /* Calculate checksum */
00472 
00473       for (j = 0, checksum = 0; j < 16; j++) {
00474          for (i = 0; i < sizeof(digit_map); i++) {
00475             if (digit_map[i] == event[j])
00476                break;
00477          }
00478 
00479          if (i == 16)
00480             break;
00481 
00482          checksum += digit_weights[i];
00483       }
00484       if (i == 16) {
00485          ast_verb(2, "AlarmReceiver: Bad DTMF character %c, trying again\n", event[j]);
00486          continue; /* Bad character */
00487       }
00488 
00489       /* Checksum is mod(15) of the total */
00490 
00491       checksum = checksum % 15;
00492 
00493       if (checksum) {
00494          database_increment("checksum-errors");
00495          ast_verb(2, "AlarmReceiver: Nonzero checksum\n");
00496          ast_debug(1, "AlarmReceiver: Nonzero checksum\n");
00497          continue;
00498       }
00499 
00500       /* Check the message type for correctness */
00501 
00502       if (strncmp(event + 4, "18", 2)) {
00503          if (strncmp(event + 4, "98", 2)) {
00504             database_increment("format-errors");
00505             ast_verb(2, "AlarmReceiver: Wrong message type\n");
00506             ast_debug(1, "AlarmReceiver: Wrong message type\n");
00507          continue;
00508          }
00509       }
00510 
00511       events_received++;
00512 
00513       /* Queue the Event */
00514       if (!(enew = ast_calloc(1, sizeof(*enew)))) {
00515          res = -1;
00516          break;
00517       }
00518 
00519       enew->next = NULL;
00520       ast_copy_string(enew->data, event, sizeof(enew->data));
00521 
00522       /*
00523       * Insert event onto end of list
00524       */
00525       if (*ehead == NULL)
00526          *ehead = enew;
00527       else {
00528          for(elp = *ehead; elp->next != NULL; elp = elp->next)
00529          ;
00530          elp->next = enew;
00531       }
00532 
00533       if (res > 0)
00534          res = 0;
00535 
00536       /* Let the user have the option of logging the single event before sending the kissoff tone */
00537       if ((res == 0) && (log_individual_events))
00538          res = log_events(chan, ADEMCO_CONTACT_ID, enew);
00539       /* Wait 200 msec before sending kissoff */
00540       if (res == 0)
00541          res = ast_safe_sleep(chan, 200);
00542 
00543       /* Send the kissoff tone */
00544       if (res == 0)
00545          res = send_tone_burst(chan, 1400.0, 900, tldn);
00546    }
00547 
00548    return res;
00549 }

static int receive_dtmf_digits ( struct ast_channel chan,
char *  digit_string,
int  length,
int  fdto,
int  sdto 
) [static]

Definition at line 223 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(), chan, f, and ast_channel::name.

Referenced by receive_ademco_contact_id().

00224 {
00225    int res = 0;
00226    int i = 0;
00227    int r;
00228    struct ast_frame *f;
00229    struct timeval lastdigittime;
00230 
00231    lastdigittime = ast_tvnow();
00232    for (;;) {
00233       /* if outa time, leave */
00234       if (ast_tvdiff_ms(ast_tvnow(), lastdigittime) > ((i > 0) ? sdto : fdto)) {
00235          ast_verb(4, "AlarmReceiver: DTMF Digit Timeout on %s\n", chan->name);
00236          ast_debug(1,"AlarmReceiver: DTMF timeout on chan %s\n",chan->name);
00237          res = 1;
00238          break;
00239       }
00240 
00241       if ((r = ast_waitfor(chan, -1) < 0)) {
00242          ast_debug(1, "Waitfor returned %d\n", r);
00243          continue;
00244       }
00245 
00246       f = ast_read(chan);
00247 
00248       if (f == NULL) {
00249          res = -1;
00250          break;
00251       }
00252 
00253       /* If they hung up, leave */
00254       if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_HANGUP)) {
00255          ast_frfree(f);
00256          res = -1;
00257          break;
00258       }
00259 
00260       /* if not DTMF, just do it again */
00261       if (f->frametype != AST_FRAME_DTMF) {
00262          ast_frfree(f);
00263          continue;
00264       }
00265 
00266       digit_string[i++] = f->subclass;  /* save digit */
00267 
00268       ast_frfree(f);
00269 
00270       /* If we have all the digits we expect, leave */
00271       if(i >= length)
00272          break;
00273 
00274       lastdigittime = ast_tvnow();
00275    }
00276 
00277    digit_string[i] = '\0'; /* Nul terminate the end of the digit string */
00278    return res;
00279 }

static int send_tone_burst ( struct ast_channel chan,
float  freq,
int  duration,
int  tldn 
) [static]

Definition at line 158 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(), buf, chan, ast_frame::data, ast_frame::datalen, f, ast_frame::frametype, LOG_WARNING, make_tone_burst(), ast_frame::mallocd, ast_frame::offset, ast_frame::samples, and ast_frame::subclass.

Referenced by receive_ademco_contact_id().

00159 {
00160    int res = 0;
00161    int i = 0;
00162    int x = 0;
00163    struct ast_frame *f, wf;
00164    
00165    struct {
00166       unsigned char offset[AST_FRIENDLY_OFFSET];
00167       unsigned char buf[640];
00168    } tone_block;
00169 
00170    for (;;) {
00171 
00172       if (ast_waitfor(chan, -1) < 0) {
00173          res = -1;
00174          break;
00175       }
00176 
00177       f = ast_read(chan);
00178       if (!f) {
00179          res = -1;
00180          break;
00181       }
00182 
00183       if (f->frametype == AST_FRAME_VOICE) {
00184          wf.frametype = AST_FRAME_VOICE;
00185          wf.subclass = AST_FORMAT_ULAW;
00186          wf.offset = AST_FRIENDLY_OFFSET;
00187          wf.mallocd = 0;
00188          wf.data = tone_block.buf;
00189          wf.datalen = f->datalen;
00190          wf.samples = wf.datalen;
00191          
00192          make_tone_burst(tone_block.buf, freq, (float) tldn, wf.datalen, &x);
00193 
00194          i += wf.datalen / 8;
00195          if (i > duration) {
00196             ast_frfree(f);
00197             break;
00198          }
00199          if (ast_write(chan, &wf)) {
00200             ast_verb(4, "AlarmReceiver: Failed to write frame on %s\n", chan->name);
00201             ast_log(LOG_WARNING, "AlarmReceiver Failed to write frame on %s\n",chan->name);
00202             res = -1;
00203             ast_frfree(f);
00204             break;
00205          }
00206       }
00207 
00208       ast_frfree(f);
00209    }
00210    return res;
00211 }

static int unload_module ( void   )  [static]

Definition at line 700 of file app_alarmreceiver.c.

References ast_unregister_application().

00701 {
00702    return ast_unregister_application(app);
00703 }

static int write_event ( FILE *  logfile,
event_node_t event 
) [static]

Definition at line 338 of file app_alarmreceiver.c.

References event_node::data.

Referenced by log_events().

00339 {
00340    int res = 0;
00341 
00342    if (fprintf(logfile, "%s\n", event->data) < 0)
00343       res = -1;
00344 
00345    return res;
00346 }

static int write_metadata ( FILE *  logfile,
char *  signalling_type,
struct ast_channel chan 
) [static]

Definition at line 284 of file app_alarmreceiver.c.

References ast_callerid_parse(), ast_copy_string(), ast_debug, ast_localtime(), ast_shrink_phone_number(), ast_strftime(), ast_tvnow(), ast_verb, chan, ast_channel::cid, and ast_callerid::cid_num.

Referenced by log_events().

00285 {
00286    int res = 0;
00287    struct timeval t;
00288    struct ast_tm now;
00289    char *cl,*cn;
00290    char workstring[80];
00291    char timestamp[80];
00292    
00293    /* Extract the caller ID location */
00294    if (chan->cid.cid_num)
00295       ast_copy_string(workstring, chan->cid.cid_num, sizeof(workstring));
00296    workstring[sizeof(workstring) - 1] = '\0';
00297 
00298    ast_callerid_parse(workstring, &cn, &cl);
00299    if (cl)
00300       ast_shrink_phone_number(cl);
00301 
00302    /* Get the current time */
00303    t = ast_tvnow();
00304    ast_localtime(&t, &now, NULL);
00305 
00306    /* Format the time */
00307    ast_strftime(timestamp, sizeof(timestamp), time_stamp_format, &now);
00308 
00309    res = fprintf(logfile, "\n\n[metadata]\n\n");
00310 
00311    if (res >= 0)
00312       res = fprintf(logfile, "PROTOCOL=%s\n", signalling_type);
00313 
00314    if (res >= 0)
00315       res = fprintf(logfile, "CALLINGFROM=%s\n", (!cl) ? "<unknown>" : cl);
00316 
00317    if (res >- 0)
00318       res = fprintf(logfile, "CALLERNAME=%s\n", (!cn) ? "<unknown>" : cn);
00319 
00320    if (res >= 0)
00321       res = fprintf(logfile, "TIMESTAMP=%s\n\n", timestamp);
00322 
00323    if (res >= 0)
00324       res = fprintf(logfile, "[events]\n\n");
00325 
00326    if (res < 0) {
00327       ast_verb(3, "AlarmReceiver: can't write metadata\n");
00328       ast_debug(1,"AlarmReceiver: can't write metadata\n");
00329    } else
00330       res = 0;
00331 
00332    return res;
00333 }


Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .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 = "068e67f60f50dd9ee86464c05884a49d" , .load = load_module, .unload = unload_module, } [static]

Definition at line 715 of file app_alarmreceiver.c.

char* app = "AlarmReceiver" [static]

Definition at line 65 of file app_alarmreceiver.c.

const struct ast_module_info* ast_module_info = &__mod_info [static]

Definition at line 715 of file app_alarmreceiver.c.

char db_family[128] = {'\0'} [static]

Definition at line 86 of file app_alarmreceiver.c.

char* descrip [static]

Definition at line 68 of file app_alarmreceiver.c.

char event_app[128] = {'\0'} [static]

Definition at line 85 of file app_alarmreceiver.c.

char event_file[14] = "/event-XXXXXX" [static]

Definition at line 90 of file app_alarmreceiver.c.

char event_spool_dir[128] = {'\0'} [static]

Definition at line 84 of file app_alarmreceiver.c.

int fdtimeout = 2000 [static]

Definition at line 80 of file app_alarmreceiver.c.

int log_individual_events = 0 [static]

Definition at line 83 of file app_alarmreceiver.c.

int sdtimeout = 200 [static]

Definition at line 81 of file app_alarmreceiver.c.

char* synopsis = "Provide support for receiving alarm reports from a burglar or fire alarm panel" [static]

Definition at line 67 of file app_alarmreceiver.c.

char time_stamp_format[128] = {"%a %b %d, %Y @ %H:%M:%S %Z"} [static]

Definition at line 87 of file app_alarmreceiver.c.

int toneloudness = 4096 [static]

Definition at line 82 of file app_alarmreceiver.c.


Generated on Thu Jul 9 13:40:43 2009 for Asterisk - the Open Source PBX by  doxygen 1.4.7