Fri Nov 12 11:48:07 2010

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"
Include dependency graph for app_alarmreceiver.c:

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 struct 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 = "0901e4e500243c855563a2d78b0c03e4" , .load = load_module, .unload = unload_module, }
static 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 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 730 of file app_alarmreceiver.c.

static void __unreg_module ( void   )  [static]

Definition at line 730 of file app_alarmreceiver.c.

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

Definition at line 567 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().

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

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(), and ast_verb.

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       ast_verb(4, "AlarmReceiver: Creating database entry %s and setting to 1\n", key);
00122       /* Guess we have to create it */
00123       res = ast_db_put(db_family, key, "1");
00124       return;
00125    }
00126    
00127    sscanf(value, "%30u", &v);
00128    v++;
00129 
00130    ast_verb(4, "AlarmReceiver: New value for %s: %u\n", key, v);
00131 
00132    snprintf(value, sizeof(value), "%u", v);
00133 
00134    res = ast_db_put(db_family, key, value);
00135 
00136    if (res)
00137       ast_verb(4, "AlarmReceiver: database_increment write error\n");
00138 
00139    return;
00140 }

static int load_config ( void   )  [static]

Definition at line 639 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_STATUS_FILEINVALID, and LOG_ERROR.

Referenced by load_module().

00640 {
00641    struct ast_config *cfg;
00642    const char *p;
00643    struct ast_flags config_flags = { 0 };
00644 
00645    /* Read in the config file */
00646    cfg = ast_config_load(ALMRCV_CONFIG, config_flags);
00647 
00648    if (!cfg) {
00649       ast_verb(4, "AlarmReceiver: No config file\n");
00650       return 0;
00651    } else if (cfg == CONFIG_STATUS_FILEINVALID) {
00652       ast_log(LOG_ERROR, "Config file %s is in an invalid format.  Aborting.\n", ALMRCV_CONFIG);
00653       return 0;
00654    } else {
00655       p = ast_variable_retrieve(cfg, "general", "eventcmd");
00656       if (p) {
00657          ast_copy_string(event_app, p, sizeof(event_app));
00658          event_app[sizeof(event_app) - 1] = '\0';
00659       }
00660       p = ast_variable_retrieve(cfg, "general", "loudness");
00661       if (p) {
00662          toneloudness = atoi(p);
00663          if(toneloudness < 100)
00664             toneloudness = 100;
00665          if(toneloudness > 8192)
00666             toneloudness = 8192;
00667       }
00668       p = ast_variable_retrieve(cfg, "general", "fdtimeout");
00669       if (p) {
00670          fdtimeout = atoi(p);
00671          if(fdtimeout < 1000)
00672             fdtimeout = 1000;
00673          if(fdtimeout > 10000)
00674             fdtimeout = 10000;
00675       }
00676 
00677       p = ast_variable_retrieve(cfg, "general", "sdtimeout");
00678       if (p) {
00679          sdtimeout = atoi(p);
00680          if(sdtimeout < 110)
00681             sdtimeout = 110;
00682          if(sdtimeout > 4000)
00683             sdtimeout = 4000;
00684       }
00685 
00686       p = ast_variable_retrieve(cfg, "general", "logindividualevents");
00687       if (p)
00688          log_individual_events = ast_true(p);
00689 
00690       p = ast_variable_retrieve(cfg, "general", "eventspooldir");
00691       if (p) {
00692          ast_copy_string(event_spool_dir, p, sizeof(event_spool_dir));
00693          event_spool_dir[sizeof(event_spool_dir) - 1] = '\0';
00694       }
00695 
00696       p = ast_variable_retrieve(cfg, "general", "timestampformat");
00697       if (p) {
00698          ast_copy_string(time_stamp_format, p, sizeof(time_stamp_format));
00699          time_stamp_format[sizeof(time_stamp_format) - 1] = '\0';
00700       }
00701 
00702       p = ast_variable_retrieve(cfg, "general", "db-family");
00703       if (p) {
00704          ast_copy_string(db_family, p, sizeof(db_family));
00705          db_family[sizeof(db_family) - 1] = '\0';
00706       }
00707       ast_config_destroy(cfg);
00708    }
00709    return 1;
00710 }

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

Definition at line 364 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().

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

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

Definition at line 146 of file app_alarmreceiver.c.

References AST_LIN2MU.

Referenced by send_tone_burst().

00147 {
00148    int     i;
00149    float   val;
00150 
00151    for (i = 0; i < len; i++) {
00152       val = loudness * sin((freq * 2.0 * M_PI * (*x)++)/8000.0);
00153       data[i] = AST_LIN2MU((int)val);
00154    }
00155 
00156    /* wrap back around from 8000 */
00157 
00158    if (*x >= 8000)
00159       *x = 0;
00160    return;
00161 }

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

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

Referenced by alarmreceiver_exec().

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

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

Definition at line 232 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(), ast_frame::data, f, ast_frame::frametype, ast_channel::hangupcause, ast_channel::name, ast_frame::subclass, and ast_frame::uint32.

Referenced by receive_ademco_contact_id().

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

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

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

Referenced by receive_ademco_contact_id().

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

static int unload_module ( void   )  [static]

Definition at line 715 of file app_alarmreceiver.c.

References ast_unregister_application().

00716 {
00717    return ast_unregister_application(app);
00718 }

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

Definition at line 350 of file app_alarmreceiver.c.

References event_node::data.

Referenced by log_events().

00351 {
00352    int res = 0;
00353 
00354    if (fprintf(logfile, "%s\n", event->data) < 0)
00355       res = -1;
00356 
00357    return res;
00358 }

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

Definition at line 296 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, ast_channel::cid, and ast_callerid::cid_num.

Referenced by log_events().

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


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 = "0901e4e500243c855563a2d78b0c03e4" , .load = load_module, .unload = unload_module, } [static]

Definition at line 730 of file app_alarmreceiver.c.

char* app = "AlarmReceiver" [static]

Definition at line 65 of file app_alarmreceiver.c.

Definition at line 730 of file app_alarmreceiver.c.

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

Definition at line 95 of file app_alarmreceiver.c.

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

Definition at line 94 of file app_alarmreceiver.c.

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

Definition at line 99 of file app_alarmreceiver.c.

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

Definition at line 93 of file app_alarmreceiver.c.

int fdtimeout = 2000 [static]

Definition at line 89 of file app_alarmreceiver.c.

int log_individual_events = 0 [static]

Definition at line 92 of file app_alarmreceiver.c.

int sdtimeout = 200 [static]

Definition at line 90 of file app_alarmreceiver.c.

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

Definition at line 96 of file app_alarmreceiver.c.

int toneloudness = 4096 [static]

Definition at line 91 of file app_alarmreceiver.c.


Generated by  doxygen 1.6.2