Mon Aug 31 12:30:14 2015

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

Functions

static int alarmreceiver_exec (struct ast_channel *chan, const char *data)
 AST_MODULE_INFO_STANDARD (ASTERISK_GPL_KEY,"Alarm Receiver for Asterisk")
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 const char app [] = "AlarmReceiver"
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 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, 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 }

AST_MODULE_INFO_STANDARD ( ASTERISK_GPL_KEY  ,
"Alarm Receiver for Asterisk"   
)
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_STATUS_FILEINVALID, and LOG_ERROR.

Referenced by load_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]
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, event_node::data, 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(), ast_frame::data, f, ast_frame::frametype, ast_channel::hangupcause, ast_frame_subclass::integer, ast_frame::subclass, and ast_frame::uint32.

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

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

Definition at line 69 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 31 Aug 2015 for Asterisk - The Open Source Telephony Project by  doxygen 1.6.1