Asterisk - The Open Source Telephony Project GIT-master-8f1982c
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros Modules Pages
Data Structures | Macros | Typedefs | Functions | Variables
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/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 "asterisk/indications.h"
#include "asterisk/format_cache.h"
Include dependency graph for app_alarmreceiver.c:

Go to the source code of this file.

Data Structures

struct  event_node
 

Macros

#define ADEMCO_AUDIO_CALL_NEXT   "606"
 
#define ADEMCO_CONTACT_ID   "ADEMCO_CONTACT_ID"
 
#define ADEMCO_EXPRESS_4_1   "ADEMCO_EXPRESS_4_1"
 
#define ADEMCO_EXPRESS_4_2   "ADEMCO_EXPRESS_4_2"
 
#define ADEMCO_HIGH_SPEED   "ADEMCO_HIGH_SPEED"
 
#define ADEMCO_MSG_TYPE_1   "18"
 
#define ADEMCO_MSG_TYPE_2   "98"
 
#define ADEMCO_MSG_TYPE_3   "17"
 
#define ADEMCO_MSG_TYPE_4   "27"
 
#define ADEMCO_MSG_TYPE_5   "55"
 
#define ADEMCO_MSG_TYPE_6   "56"
 
#define ADEMCO_SUPER_FAST   "ADEMCO_SUPER_FAST"
 
#define ALMRCV_CONFIG   "alarmreceiver.conf"
 
#define UNKNOWN_FORMAT   "UNKNOWN_FORMAT"
 

Typedefs

typedef struct event_node event_node_t
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
static int ademco_check_valid (char *signalling_type, char *event)
 Check if the message is in known and valid Ademco format. More...
 
static int ademco_detect_format (char *signalling_type, char *event, int *no_checksum)
 Detect the message format of an event. More...
 
static int ademco_verify_checksum (char *event, int expected)
 Verify Ademco checksum. More...
 
static int alarmreceiver_exec (struct ast_channel *chan, const char *data)
 This is the main function called by Asterisk Core whenever the App is invoked in the extension logic. More...
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
static void database_increment (char *key)
 Attempt to access a database variable and increment it. More...
 
static int load_config (int reload)
 Load the configuration from the configuration file. More...
 
static int load_module (void)
 Load the module. More...
 
static int log_events (struct ast_channel *chan, char *signalling_type, event_node_t *event, int no_checksum)
 Log events if configuration key logindividualevents is enabled or on exit. More...
 
static int receive_ademco_event (struct ast_channel *chan, event_node_t **ehead, char *signalling_type, int *no_checksum)
 Receive Ademco ContactID or other format Data String. More...
 
static int receive_dtmf_digits (struct ast_channel *chan, char *digit_string, int buf_size, int expected, int *received)
 Receive a fixed length DTMF string. More...
 
static int reload (void)
 
static int send_tone_burst (struct ast_channel *chan, const char *tone_freq, int tone_duration, int delay)
 Send a single tone burst for a specified duration and frequency. More...
 
static int unload_module (void)
 Unregister Alarm Receiver App. More...
 
static int write_event (FILE *logfile, event_node_t *event)
 Log a single event. More...
 
static int write_metadata (FILE *logfile, char *signalling_type, struct ast_channel *chan, int no_checksum)
 Write metadata to log file. More...
 

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 = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_EXTENDED, .load = load_module, .unload = unload_module, .reload = reload, }
 
static int answait = 1250
 
static const char app [] = "AlarmReceiver"
 
static const struct ast_module_infoast_module_info = &__mod_info
 
struct timeval call_start_time
 
static char db_family [128] = {'\0'}
 
struct {
   char   digit
 
   char   weight
 
digits_mapping []
 
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 no_group_meta = 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 hwsta.nosp@m.r@ro.nosp@m.dgers.nosp@m..sdc.nosp@m.oxmai.nosp@m.l.co.nosp@m.m

*** 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.

Macro Definition Documentation

◆ ADEMCO_AUDIO_CALL_NEXT

#define ADEMCO_AUDIO_CALL_NEXT   "606"

Definition at line 128 of file app_alarmreceiver.c.

◆ ADEMCO_CONTACT_ID

#define ADEMCO_CONTACT_ID   "ADEMCO_CONTACT_ID"

Definition at line 71 of file app_alarmreceiver.c.

◆ ADEMCO_EXPRESS_4_1

#define ADEMCO_EXPRESS_4_1   "ADEMCO_EXPRESS_4_1"

Definition at line 80 of file app_alarmreceiver.c.

◆ ADEMCO_EXPRESS_4_2

#define ADEMCO_EXPRESS_4_2   "ADEMCO_EXPRESS_4_2"

Definition at line 87 of file app_alarmreceiver.c.

◆ ADEMCO_HIGH_SPEED

#define ADEMCO_HIGH_SPEED   "ADEMCO_HIGH_SPEED"

Definition at line 94 of file app_alarmreceiver.c.

◆ ADEMCO_MSG_TYPE_1

#define ADEMCO_MSG_TYPE_1   "18"

Definition at line 121 of file app_alarmreceiver.c.

◆ ADEMCO_MSG_TYPE_2

#define ADEMCO_MSG_TYPE_2   "98"

Definition at line 122 of file app_alarmreceiver.c.

◆ ADEMCO_MSG_TYPE_3

#define ADEMCO_MSG_TYPE_3   "17"

Definition at line 123 of file app_alarmreceiver.c.

◆ ADEMCO_MSG_TYPE_4

#define ADEMCO_MSG_TYPE_4   "27"

Definition at line 124 of file app_alarmreceiver.c.

◆ ADEMCO_MSG_TYPE_5

#define ADEMCO_MSG_TYPE_5   "55"

Definition at line 125 of file app_alarmreceiver.c.

◆ ADEMCO_MSG_TYPE_6

#define ADEMCO_MSG_TYPE_6   "56"

Definition at line 126 of file app_alarmreceiver.c.

◆ ADEMCO_SUPER_FAST

#define ADEMCO_SUPER_FAST   "ADEMCO_SUPER_FAST"

Definition at line 115 of file app_alarmreceiver.c.

◆ ALMRCV_CONFIG

#define ALMRCV_CONFIG   "alarmreceiver.conf"

Definition at line 68 of file app_alarmreceiver.c.

◆ UNKNOWN_FORMAT

#define UNKNOWN_FORMAT   "UNKNOWN_FORMAT"

Definition at line 69 of file app_alarmreceiver.c.

Typedef Documentation

◆ event_node_t

typedef struct event_node event_node_t

Definition at line 142 of file app_alarmreceiver.c.

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 1002 of file app_alarmreceiver.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 1002 of file app_alarmreceiver.c.

◆ ademco_check_valid()

static int ademco_check_valid ( char *  signalling_type,
char *  event 
)
static

Check if the message is in known and valid Ademco format.

Parameters
signalling_typeExpected signalling type for the message
eventevent received
Return values
0The event is valid
-1The event is not valid

Definition at line 525 of file app_alarmreceiver.c.

526{
527 if (!strcmp(signalling_type, UNKNOWN_FORMAT)) {
528 return 1;
529 }
530
531 if (!strcmp(signalling_type, ADEMCO_CONTACT_ID)
532 && strncmp(event + 4, ADEMCO_MSG_TYPE_1, 2)
533 && strncmp(event + 4, ADEMCO_MSG_TYPE_2, 2)) {
534 return -1;
535 }
536
537 if (!strcmp(signalling_type, ADEMCO_EXPRESS_4_1) && strncmp(event + 4, ADEMCO_MSG_TYPE_3, 2)) {
538 return -1;
539 }
540
541 if (!strcmp(signalling_type, ADEMCO_EXPRESS_4_2) && strncmp(event + 4, ADEMCO_MSG_TYPE_4, 2)) {
542 return -1;
543 }
544
545 if (!strcmp(signalling_type, ADEMCO_HIGH_SPEED) && strncmp(event + 4, ADEMCO_MSG_TYPE_5, 2)) {
546 return -1;
547 }
548
549 if (!strcmp(signalling_type, ADEMCO_SUPER_FAST) && strncmp(event + 4, ADEMCO_MSG_TYPE_6, 2)) {
550 return -1;
551 }
552
553 return 0;
554}
#define ADEMCO_MSG_TYPE_4
#define ADEMCO_EXPRESS_4_2
#define ADEMCO_MSG_TYPE_2
#define ADEMCO_CONTACT_ID
#define ADEMCO_HIGH_SPEED
#define ADEMCO_MSG_TYPE_3
#define ADEMCO_EXPRESS_4_1
#define ADEMCO_MSG_TYPE_6
#define ADEMCO_MSG_TYPE_5
#define UNKNOWN_FORMAT
#define ADEMCO_SUPER_FAST
#define ADEMCO_MSG_TYPE_1
Definition: astman.c:222

References ADEMCO_CONTACT_ID, ADEMCO_EXPRESS_4_1, ADEMCO_EXPRESS_4_2, ADEMCO_HIGH_SPEED, ADEMCO_MSG_TYPE_1, ADEMCO_MSG_TYPE_2, ADEMCO_MSG_TYPE_3, ADEMCO_MSG_TYPE_4, ADEMCO_MSG_TYPE_5, ADEMCO_MSG_TYPE_6, ADEMCO_SUPER_FAST, and UNKNOWN_FORMAT.

Referenced by receive_ademco_event().

◆ ademco_detect_format()

static int ademco_detect_format ( char *  signalling_type,
char *  event,
int *  no_checksum 
)
static

Detect the message format of an event.

Parameters
signalling_typeExpected signalling type for the message
eventevent received
no_checksumShould we calculate checksum for the message
Returns
The expected digits for the detected event type

Definition at line 565 of file app_alarmreceiver.c.

566{
567 int res = 16;
568
569 if (!strncmp(event + 4, ADEMCO_MSG_TYPE_1, 2)
570 || !strncmp(event + 4, ADEMCO_MSG_TYPE_2, 2)) {
571 sprintf(signalling_type, "%s", ADEMCO_CONTACT_ID);
572 }
573
574 if (!strncmp(event + 4, ADEMCO_MSG_TYPE_3, 2)) {
575 sprintf(signalling_type, "%s", ADEMCO_EXPRESS_4_1);
576 res = 8;
577 }
578
579 if (!strncmp(event + 4, ADEMCO_MSG_TYPE_4, 2)) {
580 sprintf(signalling_type, "%s", ADEMCO_EXPRESS_4_2);
581 res = 9;
582 }
583
584 if (!strncmp(event + 4, ADEMCO_MSG_TYPE_5, 2)) {
585 sprintf(signalling_type, "%s", ADEMCO_HIGH_SPEED);
586 }
587
588 if (!strncmp(event + 4, ADEMCO_MSG_TYPE_6, 2)) {
589 sprintf(signalling_type, "%s", ADEMCO_SUPER_FAST);
590 *no_checksum = 1;
591 res = 15;
592 }
593
594 if (strcmp(signalling_type, UNKNOWN_FORMAT)) {
595 ast_verb(4, "AlarmMonitoring: Detected format %s.\n", signalling_type);
596 ast_debug(1, "AlarmMonitoring: Autodetected format %s.\n", signalling_type);
597 }
598
599 return res;
600}
#define ast_debug(level,...)
Log a DEBUG message.
#define ast_verb(level,...)

References ADEMCO_CONTACT_ID, ADEMCO_EXPRESS_4_1, ADEMCO_EXPRESS_4_2, ADEMCO_HIGH_SPEED, ADEMCO_MSG_TYPE_1, ADEMCO_MSG_TYPE_2, ADEMCO_MSG_TYPE_3, ADEMCO_MSG_TYPE_4, ADEMCO_MSG_TYPE_5, ADEMCO_MSG_TYPE_6, ADEMCO_SUPER_FAST, ast_debug, ast_verb, and UNKNOWN_FORMAT.

Referenced by receive_ademco_event().

◆ ademco_verify_checksum()

static int ademco_verify_checksum ( char *  event,
int  expected 
)
static

Verify Ademco checksum.

Since
11.0
Parameters
eventReceived DTMF String
expectedNumber of Digits expected
Return values
0success
-1failure

Definition at line 458 of file app_alarmreceiver.c.

459{
460 int checksum = 0;
461 int i, j;
462
463 for (j = 0; j < expected; j++) {
464 for (i = 0; i < ARRAY_LEN(digits_mapping); i++) {
465 if (digits_mapping[i].digit == event[j]) {
466 break;
467 }
468 }
469
470 if (i >= ARRAY_LEN(digits_mapping)) {
471 ast_verb(2, "AlarmReceiver: Bad DTMF character %c, trying again\n", event[j]);
472 return -1;
473 }
474
475 checksum += digits_mapping[i].weight;
476 }
477
478 /* Checksum is mod(15) of the total */
479 if (!(checksum % 15)) {
480 return 0;
481 }
482
483 return -1;
484}
struct @6 digits_mapping[]
char digit
#define ARRAY_LEN(a)
Definition: utils.h:666

References ARRAY_LEN, ast_verb, digit, and digits_mapping.

Referenced by receive_ademco_event().

◆ alarmreceiver_exec()

static int alarmreceiver_exec ( struct ast_channel chan,
const char *  data 
)
static

This is the main function called by Asterisk Core whenever the App is invoked in the extension logic.

Parameters
chanAsterisk Channel
dataApplication data
Return values
0success
-1failure

Definition at line 794 of file app_alarmreceiver.c.

795{
796 int res = 0;
797 int no_checksum = 0;
798 event_node_t *elp, *efree;
799 char signalling_type[64] = "";
800 event_node_t *event_head = NULL;
801
804 ast_verb(4, "AlarmReceiver: Setting write format to Mu-law\n");
806 ast_log(LOG_WARNING, "AlarmReceiver: Unable to set write format to Mu-law on %s\n",ast_channel_name(chan));
807 return -1;
808 }
809 }
810
813 ast_verb(4, "AlarmReceiver: Setting read format to Mu-law\n");
815 ast_log(LOG_WARNING, "AlarmReceiver: Unable to set read format to Mu-law on %s\n",ast_channel_name(chan));
816 return -1;
817 }
818 }
819
820 /* Set default values for this invocation of the application */
821 ast_copy_string(signalling_type, UNKNOWN_FORMAT, sizeof(signalling_type));
823
824 /* Answer the channel if it is not already */
825 if (ast_channel_state(chan) != AST_STATE_UP) {
826 ast_verb(4, "AlarmReceiver: Answering channel\n");
827 if (ast_answer(chan)) {
828 return -1;
829 }
830 }
831
832 /* Wait for the connection to settle post-answer */
833 ast_verb(4, "AlarmReceiver: Waiting for connection to stabilize\n");
834 if (ast_safe_sleep(chan, answait)) {
835 return -1;
836 }
837
838 /* Attempt to receive the events */
839 receive_ademco_event(chan, &event_head, signalling_type, &no_checksum);
840
841 /* Events queued by receiver, write them all out here if so configured */
843 res = log_events(chan, signalling_type, event_head, no_checksum);
844 }
845
846 /* Do we exec a command line at the end? */
847 if ((!res) && (!ast_strlen_zero(event_app)) && (event_head)) {
848 ast_debug(1,"Alarmreceiver: executing: %s\n", event_app);
850 }
851
852 /* Free up the data allocated in our linked list */
853 for (elp = event_head; (elp != NULL);) {
854 efree = elp;
855 elp = elp->next;
856 ast_free(efree);
857 }
858
859 return 0;
860}
struct timeval call_start_time
static int log_events(struct ast_channel *chan, char *signalling_type, event_node_t *event, int no_checksum)
Log events if configuration key logindividualevents is enabled or on exit.
static int log_individual_events
static int receive_ademco_event(struct ast_channel *chan, event_node_t **ehead, char *signalling_type, int *no_checksum)
Receive Ademco ContactID or other format Data String.
static char event_app[128]
static int answait
#define ast_free(a)
Definition: astmm.h:180
#define ast_log
Definition: astobj2.c:42
const char * ast_channel_name(const struct ast_channel *chan)
int ast_set_read_format(struct ast_channel *chan, struct ast_format *format)
Sets read format on channel chan.
Definition: channel.c:5721
struct ast_format * ast_channel_writeformat(struct ast_channel *chan)
int ast_set_write_format(struct ast_channel *chan, struct ast_format *format)
Sets write format on channel chan.
Definition: channel.c:5762
int ast_answer(struct ast_channel *chan)
Answer a channel.
Definition: channel.c:2774
int ast_safe_sleep(struct ast_channel *chan, int ms)
Wait for a specified amount of time, looking for hangups.
Definition: channel.c:1541
struct ast_format * ast_channel_readformat(struct ast_channel *chan)
ast_channel_state
ast_channel states
Definition: channelstate.h:35
@ AST_STATE_UP
Definition: channelstate.h:42
enum ast_format_cmp_res ast_format_cmp(const struct ast_format *format1, const struct ast_format *format2)
Compare two formats.
Definition: format.c:201
@ AST_FORMAT_CMP_NOT_EQUAL
Definition: format.h:38
struct ast_format * ast_format_ulaw
Built-in cached ulaw format.
Definition: format_cache.c:86
struct ast_format * ast_format_alaw
Built-in cached alaw format.
Definition: format_cache.c:91
int ast_safe_system(const char *s)
Safely spawn an OS shell command while closing file descriptors.
Definition: extconf.c:829
#define LOG_WARNING
#define NULL
Definition: resample.c:96
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:425
struct event_node * next
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:159

References answait, ast_answer(), ast_channel_name(), ast_channel_readformat(), ast_channel_writeformat(), ast_copy_string(), ast_debug, ast_format_alaw, ast_format_cmp(), AST_FORMAT_CMP_NOT_EQUAL, 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_tvnow(), ast_verb, call_start_time, event_app, log_events(), log_individual_events, LOG_WARNING, event_node::next, NULL, receive_ademco_event(), and UNKNOWN_FORMAT.

Referenced by load_module().

◆ AST_MODULE_SELF_SYM()

struct ast_module * AST_MODULE_SELF_SYM ( void  )

Definition at line 1002 of file app_alarmreceiver.c.

◆ database_increment()

static void database_increment ( char *  key)
static

Attempt to access a database variable and increment it.

Note
Only if the user defined db-family in alarmreceiver.conf

The alarmreceiver app will write statistics to a few variables in this family if it is defined. If the new key doesn't exist in the family, then create it and set its value to 1.

Parameters
keyA database key to increment

Definition at line 210 of file app_alarmreceiver.c.

211{
212 unsigned v;
213 char value[16];
214
216 return; /* If not defined, don't do anything */
217 }
218
219 if (ast_db_get(db_family, key, value, sizeof(value) - 1)) {
220 ast_verb(4, "AlarmReceiver: Creating database entry %s and setting to 1\n", key);
221 /* Guess we have to create it */
222 ast_db_put(db_family, key, "1");
223 return;
224 }
225
226 sscanf(value, "%30u", &v);
227 v++;
228
229 ast_verb(4, "AlarmReceiver: New value for %s: %u\n", key, v);
230 snprintf(value, sizeof(value), "%u", v);
231
232 if (ast_db_put(db_family, key, value)) {
233 ast_verb(4, "AlarmReceiver: database_increment write error\n");
234 }
235
236 return;
237}
static char db_family[128]
int ast_db_put(const char *family, const char *key, const char *value)
Store value addressed by family/key.
Definition: db.c:335
int ast_db_get(const char *family, const char *key, char *value, int valuelen)
Get key value specified by family/key.
Definition: db.c:421
int value
Definition: syslog.c:37

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

Referenced by receive_ademco_event().

◆ load_config()

static int load_config ( int  reload)
static

Load the configuration from the configuration file.

Parameters
reloadTrue on reload
Return values
1success
0failure

Definition at line 870 of file app_alarmreceiver.c.

871{
872 struct ast_config *cfg;
873 const char *value;
874 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
875
876 /* Read in the config file */
877 cfg = ast_config_load(ALMRCV_CONFIG, config_flags);
878
879 if (!cfg) {
880 ast_verb(4, "AlarmReceiver: No config file\n");
881 return 0;
882 } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
883 return 1;
884 } else if (cfg == CONFIG_STATUS_FILEINVALID) {
885 ast_log(LOG_ERROR, "Config file %s is in an invalid format. Aborting.\n",
887 return 0;
888 }
889
890 if ((value = ast_variable_retrieve(cfg, "general", "eventcmd")) != NULL) {
892 }
893
894 if ((value = ast_variable_retrieve(cfg, "general", "loudness")) != NULL) {
895 toneloudness = atoi(value);
896 if (toneloudness < 100) {
897 toneloudness = 100;
898 } else if (toneloudness > 8192) {
899 toneloudness = 8192;
900 }
901 }
902
903 if ((value = ast_variable_retrieve(cfg, "general", "fdtimeout")) != NULL) {
904 fdtimeout = atoi(value);
905 if (fdtimeout < 1000) {
906 fdtimeout = 1000;
907 } else if (fdtimeout > 10000) {
908 fdtimeout = 10000;
909 }
910 }
911
912 if ((value = ast_variable_retrieve(cfg, "general", "sdtimeout")) != NULL) {
913 sdtimeout = atoi(value);
914 if (sdtimeout < 110) {
915 sdtimeout = 110;
916 } else if (sdtimeout > 4000) {
917 sdtimeout = 4000;
918 }
919 }
920
921 if ((value = ast_variable_retrieve(cfg, "general", "answait")) != NULL) {
922 answait = atoi(value);
923 if (answait < 500) {
924 answait = 500;
925 } else if (answait > 10000) {
926 answait = 10000;
927 }
928 }
929
930 if ((value = ast_variable_retrieve(cfg, "general", "no_group_meta")) != NULL) {
932 }
933
934 if ((value = ast_variable_retrieve(cfg, "general", "logindividualevents")) != NULL) {
936 }
937
938 if ((value = ast_variable_retrieve(cfg, "general", "eventspooldir")) != NULL) {
940 }
941
942 if ((value = ast_variable_retrieve(cfg, "general", "timestampformat")) != NULL) {
944 }
945
946 if ((value = ast_variable_retrieve(cfg, "general", "db-family")) != NULL) {
948 }
949
951
952 return 1;
953}
static char time_stamp_format[128]
#define ALMRCV_CONFIG
static int fdtimeout
static int toneloudness
static int sdtimeout
static char event_spool_dir[128]
static int no_group_meta
static int reload(void)
#define ast_config_load(filename, flags)
Load a config file.
@ CONFIG_FLAG_FILEUNCHANGED
#define CONFIG_STATUS_FILEUNCHANGED
#define CONFIG_STATUS_FILEINVALID
void ast_config_destroy(struct ast_config *cfg)
Destroys a config.
Definition: extconf.c:1289
const char * ast_variable_retrieve(struct ast_config *config, const char *category, const char *variable)
Definition: main/config.c:869
#define LOG_ERROR
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true"....
Definition: utils.c:2199
Structure used to handle boolean flags.
Definition: utils.h:199

References ALMRCV_CONFIG, answait, ast_config_destroy(), ast_config_load, ast_copy_string(), ast_log, ast_true(), ast_variable_retrieve(), ast_verb, CONFIG_FLAG_FILEUNCHANGED, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEUNCHANGED, db_family, event_app, event_spool_dir, fdtimeout, LOG_ERROR, log_individual_events, no_group_meta, NULL, reload(), sdtimeout, time_stamp_format, toneloudness, and value.

Referenced by load_module(), and reload().

◆ load_module()

static int load_module ( void  )
static

Load the module.

Module loading including tests for configuration or dependencies. This function can return AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_DECLINE, or AST_MODULE_LOAD_SUCCESS. If a dependency or environment variable fails tests return AST_MODULE_LOAD_FAILURE. If the module can not load the configuration file or other non-critical problem return AST_MODULE_LOAD_DECLINE. On success return AST_MODULE_LOAD_SUCCESS.

Definition at line 976 of file app_alarmreceiver.c.

977{
978 if (load_config(0)) {
981 }
983 }
984
986}
static const char app[]
static int alarmreceiver_exec(struct ast_channel *chan, const char *data)
This is the main function called by Asterisk Core whenever the App is invoked in the extension logic.
static int load_config(int reload)
Load the configuration from the configuration file.
@ AST_MODULE_LOAD_SUCCESS
Definition: module.h:70
@ AST_MODULE_LOAD_DECLINE
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
#define ast_register_application_xml(app, execute)
Register an application using XML documentation.
Definition: module.h:640

References alarmreceiver_exec(), app, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, ast_register_application_xml, and load_config().

◆ log_events()

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

Log events if configuration key logindividualevents is enabled or on exit.

Parameters
chanAsterisk Channel
signalling_typeSignaling Type
eventEvent Structure
no_checksumExpecting messages without checksum
Return values
0success
-1failure

Definition at line 404 of file app_alarmreceiver.c.

405{
406 char workstring[sizeof(event_spool_dir) + sizeof(event_file)] = "";
407 int fd;
408 FILE *logfile;
409 event_node_t *elp = event;
410
412
413 /* Make a template */
414 ast_copy_string(workstring, event_spool_dir, sizeof(workstring));
415 strncat(workstring, event_file, sizeof(workstring) - strlen(workstring) - 1);
416
417 /* Make the temporary file */
418 fd = mkstemp(workstring);
419
420 if (fd == -1) {
421 ast_verb(3, "AlarmReceiver: can't make temporary file\n");
422 ast_debug(1, "AlarmReceiver: can't make temporary file\n");
423 return -1;
424 }
425
426 if ((logfile = fdopen(fd, "w")) == NULL) {
427 return -1;
428 }
429
430 /* Write the file */
431 if (write_metadata(logfile, signalling_type, chan, no_checksum)) {
432 fflush(logfile);
433 fclose(logfile);
434 return -1;
435 }
436
437 while ((elp != NULL) && (write_event(logfile, elp) == 0)) {
438 elp = elp->next;
439 }
440
441 fflush(logfile);
442 fclose(logfile);
443 }
444
445 return 0;
446}
static int write_metadata(FILE *logfile, char *signalling_type, struct ast_channel *chan, int no_checksum)
Write metadata to log file.
static char event_file[14]
static int write_event(FILE *logfile, event_node_t *event)
Log a single event.

References ast_copy_string(), ast_debug, ast_strlen_zero(), ast_verb, event_file, event_spool_dir, event_node::next, NULL, write_event(), and write_metadata().

Referenced by alarmreceiver_exec(), and receive_ademco_event().

◆ receive_ademco_event()

static int receive_ademco_event ( struct ast_channel chan,
event_node_t **  ehead,
char *  signalling_type,
int *  no_checksum 
)
static

Receive Ademco ContactID or other format Data String.

Parameters
chanAsterisk Channel
eheadPointer to events list
signalling_typeExpected signalling type for the message
no_checksumShould we calculate checksum for the message
Return values
0success
-1failure

Definition at line 613 of file app_alarmreceiver.c.

614{
615 int res = 0;
616 const char *limit;
617 char event[17];
618 event_node_t *enew, *elp;
619 int got_some_digits = 0;
620 int events_received = 0;
621 int ack_retries = 0;
622 int limit_retries = 0;
623 int expected_length = sizeof(event) - 1;
624
625 database_increment("calls-received");
626
627 /* Wait for first event */
628 ast_verb(4, "AlarmReceiver: Waiting for first event from panel...\n");
629
630 while (res >= 0) {
631 int digits_received = 0;
632
633 res = 0;
634
636 sprintf(signalling_type, "%s", UNKNOWN_FORMAT);
637 expected_length = 16;
638 *no_checksum = 0;
639 }
640
641 if (got_some_digits == 0) {
642 /* Send ACK tone sequence */
643 ast_verb(4, "AlarmReceiver: Sending 1400Hz 100ms burst (ACK)\n");
644 res = send_tone_burst(chan, "1400", 100, 0);
645 if (!res) {
646 ast_verb(4, "AlarmReceiver: Sending 2300Hz 100ms burst (ACK)\n");
647 res = send_tone_burst(chan, "2300", 100, 100);
648 }
649 }
650 if (res) {
651 return -1;
652 }
653
654 res = receive_dtmf_digits(chan, event, sizeof(event), expected_length, &digits_received);
655 if (res < 0) {
656 if (events_received == 0) {
657 /* Hangup with no events received should be logged in the DB */
658 database_increment("no-events-received");
659 ast_verb(4, "AlarmReceiver: No events received!\n");
660 } else {
661 if (ack_retries) {
662 database_increment("ack-retries");
663 ast_verb(4, "AlarmReceiver: ACK retries during this call: %d\n", ack_retries);
664 }
665 }
666 ast_verb(4, "AlarmReceiver: App exiting...\n");
667 break;
668 }
669
670 if (!strcmp(signalling_type, UNKNOWN_FORMAT) && digits_received > 5) {
671 expected_length = ademco_detect_format(signalling_type, event, no_checksum);
672
673 if (res > 0) {
674 if (digits_received == expected_length) {
675 res = limit_retries = 0;
676 } else if (digits_received == expected_length - 1
677 && (!strcmp(signalling_type, ADEMCO_EXPRESS_4_2)
678 || !strcmp(signalling_type, ADEMCO_EXPRESS_4_1))) {
679 /* ADEMCO EXPRESS without checksum */
680 res = limit_retries = 0;
681 expected_length--;
682 *no_checksum = 1;
683 ast_verb(4, "AlarmMonitoring: Skipping checksum for format %s.\n", signalling_type);
684 ast_debug(1, "AlarmMonitoring: Skipping checksum for format %s.\n", signalling_type);
685 }
686 }
687 }
688
689 ast_channel_lock(chan);
690 limit = pbx_builtin_getvar_helper(chan, "ALARMRECEIVER_CALL_LIMIT");
691 if (!ast_strlen_zero(limit)) {
692 if (ast_tvdiff_ms(ast_tvnow(), call_start_time) > atoi(limit)) {
693 ast_channel_unlock(chan);
694 return -1;
695 }
696 }
697 limit = pbx_builtin_getvar_helper(chan, "ALARMRECEIVER_RETRIES_LIMIT");
698 ast_channel_unlock(chan);
699 if (!ast_strlen_zero(limit)) {
700 if (limit_retries + 1 >= atoi(limit)) {
701 return -1;
702 }
703 }
704
705 if (res) {
706 /* Didn't get all of the digits */
707 ast_verb(2, "AlarmReceiver: Incomplete string: %s, trying again...\n", event);
708 limit_retries++;
709
710 if (!events_received && strcmp(signalling_type, UNKNOWN_FORMAT))
711 {
712 sprintf(signalling_type, "%s", UNKNOWN_FORMAT);
713 expected_length = sizeof(event) - 1;
714 }
715
716 if (!got_some_digits) {
717 got_some_digits = (!ast_strlen_zero(event)) ? 1 : 0;
718 ack_retries++;
719 }
720 continue;
721 }
722
723 got_some_digits = 1;
724
725 ast_verb(2, "AlarmReceiver: Received Event %s\n", event);
726 ast_debug(1, "AlarmReceiver: Received event: %s\n", event);
727
728 /* Calculate checksum */
729 if (!(*no_checksum) && ademco_verify_checksum(event, expected_length)) {
730 database_increment("checksum-errors");
731 ast_verb(2, "AlarmReceiver: Nonzero checksum\n");
732 ast_debug(1, "AlarmReceiver: Nonzero checksum\n");
733 continue;
734 }
735
736 /* Check the message type for correctness */
737 if (ademco_check_valid(signalling_type, event)) {
738 database_increment("format-errors");
739 ast_verb(2, "AlarmReceiver: Wrong message type\n");
740 ast_debug(1, "AlarmReceiver: Wrong message type\n");
741 continue;
742 }
743
744 events_received++;
745
746 /* Queue the Event */
747 if (!(enew = ast_calloc(1, sizeof(*enew)))) {
748 return -1;
749 }
750
751 enew->next = NULL;
752 ast_copy_string(enew->data, event, sizeof(enew->data));
753
754 /* Insert event onto end of list */
755 if (*ehead == NULL) {
756 *ehead = enew;
757 } else {
758 for (elp = *ehead; elp->next != NULL; elp = elp->next) {
759 ;
760 }
761 elp->next = enew;
762 }
763
764 /* Let the user have the option of logging the single event before sending the kissoff tone */
765 if (log_individual_events && log_events(chan, signalling_type, enew, *no_checksum)) {
766 return -1;
767 }
768
769 /* Send the kissoff tone (1400 Hz, 900 ms, after 200ms delay) */
770 if (send_tone_burst(chan, "1400", 900, 200)) {
771 return -1;
772 }
773
774 /* If audio call follows, exit alarm receiver app */
775 if (!strcmp(signalling_type, ADEMCO_CONTACT_ID)
776 && !strncmp(event + 7, ADEMCO_AUDIO_CALL_NEXT, 3)) {
777 ast_verb(4, "AlarmReceiver: App exiting... Audio call next!\n");
778 return 0;
779 }
780 }
781
782 return res;
783}
static int ademco_verify_checksum(char *event, int expected)
Verify Ademco checksum.
static int receive_dtmf_digits(struct ast_channel *chan, char *digit_string, int buf_size, int expected, int *received)
Receive a fixed length DTMF string.
#define ADEMCO_AUDIO_CALL_NEXT
static int ademco_detect_format(char *signalling_type, char *event, int *no_checksum)
Detect the message format of an event.
static int ademco_check_valid(char *signalling_type, char *event)
Check if the message is in known and valid Ademco format.
static int send_tone_burst(struct ast_channel *chan, const char *tone_freq, int tone_duration, int delay)
Send a single tone burst for a specified duration and frequency.
static void database_increment(char *key)
Attempt to access a database variable and increment it.
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
#define ast_channel_lock(chan)
Definition: channel.h:2972
#define ast_channel_unlock(chan)
Definition: channel.h:2973
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:107

References ADEMCO_AUDIO_CALL_NEXT, ademco_check_valid(), ADEMCO_CONTACT_ID, ademco_detect_format(), ADEMCO_EXPRESS_4_1, ADEMCO_EXPRESS_4_2, ademco_verify_checksum(), ast_calloc, ast_channel_lock, ast_channel_unlock, ast_copy_string(), ast_debug, ast_strlen_zero(), ast_tvdiff_ms(), ast_tvnow(), ast_verb, call_start_time, event_node::data, database_increment(), log_events(), log_individual_events, event_node::next, NULL, pbx_builtin_getvar_helper(), receive_dtmf_digits(), send_tone_burst(), and UNKNOWN_FORMAT.

Referenced by alarmreceiver_exec().

◆ receive_dtmf_digits()

static int receive_dtmf_digits ( struct ast_channel chan,
char *  digit_string,
int  buf_size,
int  expected,
int *  received 
)
static

Receive a fixed length DTMF string.

Note
Doesn't give preferential treatment to any digit,
allow different timeout values for the first and all subsequent digits
Parameters
chanAsterisk Channel
digit_stringDigits String
buf_sizeThe size of the Digits String buffer
expectedDigits expected for this message type
receivedPointer to number of digits received so far
Return values
0if all digits were successfully received
1if a timeout occurred
-1if the caller hung up or on channel errors

Definition at line 255 of file app_alarmreceiver.c.

256{
257 int rtn = 0;
258 int r;
259 struct ast_frame *f;
260 struct timeval lastdigittime;
261
262 lastdigittime = ast_tvnow();
263 while (*received < expected && *received < buf_size - 1) {
264 /* If timed out, leave */
265 if (ast_tvdiff_ms(ast_tvnow(), lastdigittime) > ((*received > 0) ? sdtimeout : fdtimeout)) {
266 ast_verb(4, "AlarmReceiver: DTMF Digit Timeout on %s\n", ast_channel_name(chan));
267 ast_debug(1, "AlarmReceiver: DTMF timeout on chan %s\n", ast_channel_name(chan));
268 rtn = 1;
269 break;
270 }
271
272 if ((r = ast_waitfor(chan, -1)) < 0) {
273 ast_debug(1, "Waitfor returned %d\n", r);
274 continue;
275 }
276
277 if ((f = ast_read(chan)) == NULL) {
278 rtn = -1;
279 break;
280 }
281
282 /* If they hung up, leave */
283 if ((f->frametype == AST_FRAME_CONTROL)
285 if (f->data.uint32) {
287 }
288 ast_frfree(f);
289 rtn = -1;
290 break;
291 }
292
293 /* If not DTMF, just do it again */
294 if (f->frametype != AST_FRAME_DTMF) {
295 ast_frfree(f);
296 continue;
297 }
298
299 /* Save digit */
300 digit_string[(*received)++] = f->subclass.integer;
301 ast_frfree(f);
302
303 lastdigittime = ast_tvnow();
304 }
305
306 /* Null terminate the end of the digit_string */
307 digit_string[*received] = '\0';
308
309 return rtn;
310}
int ast_waitfor(struct ast_channel *chan, int ms)
Wait for input on a channel.
Definition: channel.c:3130
struct ast_frame * ast_read(struct ast_channel *chan)
Reads a frame.
Definition: channel.c:4214
void ast_channel_hangupcause_set(struct ast_channel *chan, int value)
#define AST_FRAME_DTMF
#define ast_frfree(fr)
@ AST_FRAME_CONTROL
@ AST_CONTROL_HANGUP
Data structure associated with a single frame of data.
union ast_frame::@228 data
struct ast_frame_subclass subclass
enum ast_frame_type frametype

References ast_channel_hangupcause_set(), ast_channel_name(), 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, fdtimeout, ast_frame::frametype, ast_frame_subclass::integer, NULL, sdtimeout, ast_frame::subclass, and ast_frame::uint32.

Referenced by receive_ademco_event().

◆ reload()

static int reload ( void  )
static

Definition at line 988 of file app_alarmreceiver.c.

989{
990 if (load_config(1)) {
992 }
993
995}

References AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, and load_config().

Referenced by load_config().

◆ send_tone_burst()

static int send_tone_burst ( struct ast_channel chan,
const char *  tone_freq,
int  tone_duration,
int  delay 
)
static

Send a single tone burst for a specified duration and frequency.

Since
11.0
Parameters
chanAsterisk Channel
tone_freqFrequency of the tone to send
tone_durationTone duration in ms
delayDelay before sending the tone
Return values
0success
-1failure

Definition at line 498 of file app_alarmreceiver.c.

499{
500 if (delay && ast_safe_sleep(chan, delay)) {
501 return -1;
502 }
503
504 if (ast_playtones_start(chan, toneloudness, tone_freq, 0)) {
505 return -1;
506 }
507
508 if (ast_safe_sleep(chan, tone_duration)) {
509 return -1;
510 }
511
512 ast_playtones_stop(chan);
513 return 0;
514}
int ast_playtones_start(struct ast_channel *chan, int vol, const char *tonelist, int interruptible)
Start playing a list of tones on a channel.
Definition: indications.c:302
void ast_playtones_stop(struct ast_channel *chan)
Stop playing tones on a channel.
Definition: indications.c:393

References ast_playtones_start(), ast_playtones_stop(), ast_safe_sleep(), and toneloudness.

Referenced by receive_ademco_event().

◆ unload_module()

static int unload_module ( void  )
static

Unregister Alarm Receiver App.

Return values
0success
-1failure

Definition at line 961 of file app_alarmreceiver.c.

962{
964}
int ast_unregister_application(const char *app)
Unregister an application.
Definition: pbx_app.c:392

References app, and ast_unregister_application().

◆ write_event()

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

Log a single event.

Parameters
logfileLog File Pointer
eventEvent Structure
Return values
0success
-1failure

Definition at line 384 of file app_alarmreceiver.c.

385{
386 if (fprintf(logfile, "%s%s\n", no_group_meta ? "event=" : "", event->data) < 0) {
387 return -1;
388 }
389
390 return 0;
391}

References no_group_meta.

Referenced by log_events().

◆ write_metadata()

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

Write metadata to log file.

Parameters
logfileLog File Pointer
signalling_typeSignaling Type
chanAsterisk Channel
no_checksumExpecting messages without checksum
Return values
0success
-1failure

Definition at line 323 of file app_alarmreceiver.c.

324{
325 struct timeval t;
326 struct ast_tm now;
327 char *cl;
328 char *cn;
329 char workstring[80];
330 char timestamp[80];
331
332 /* Extract the caller ID location */
333 ast_copy_string(workstring,
334 S_COR(ast_channel_caller(chan)->id.number.valid,
335 ast_channel_caller(chan)->id.number.str, ""), sizeof(workstring));
336 ast_shrink_phone_number(workstring);
337 if (ast_strlen_zero(workstring)) {
338 cl = "<unknown>";
339 } else {
340 cl = workstring;
341 }
342 cn = S_COR(ast_channel_caller(chan)->id.name.valid,
343 ast_channel_caller(chan)->id.name.str, "<unknown>");
344
345 /* Get the current time */
346 t = ast_tvnow();
347 ast_localtime(&t, &now, NULL);
348
349 /* Format the time */
350 ast_strftime(timestamp, sizeof(timestamp), time_stamp_format, &now);
351
352 if (no_group_meta && fprintf(logfile, "PROTOCOL=%s\n"
353 "CHECKSUM=%s\n"
354 "CALLINGFROM=%s\n"
355 "CALLERNAME=%s\n"
356 "TIMESTAMP=%s\n\n",
357 signalling_type, (!no_checksum) ? "yes" : "no", cl, cn, timestamp) > -1) {
358 return 0;
359 } else if (fprintf(logfile, "\n\n[metadata]\n\n"
360 "PROTOCOL=%s\n"
361 "CHECKSUM=%s\n"
362 "CALLINGFROM=%s\n"
363 "CALLERNAME=%s\n"
364 "TIMESTAMP=%s\n\n"
365 "[events]\n\n",
366 signalling_type, (!no_checksum) ? "yes" : "no", cl, cn, timestamp) > -1) {
367 return 0;
368 }
369
370 ast_verb(3, "AlarmReceiver: can't write metadata\n");
371 ast_debug(1, "AlarmReceiver: can't write metadata\n");
372 return -1;
373}
void ast_shrink_phone_number(char *n)
Shrink a phone number in place to just digits (more accurately it just removes ()'s,...
Definition: callerid.c:1101
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
static const char name[]
Definition: format_mp3.c:68
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
int ast_strftime(char *buf, size_t len, const char *format, const struct ast_tm *tm)
Special version of strftime(3) that handles fractions of a second. Takes the same arguments as strfti...
Definition: localtime.c:2524
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
Definition: strings.h:87
Number structure.
Definition: app_followme.c:157

References ast_channel_caller(), ast_copy_string(), ast_debug, ast_localtime(), ast_shrink_phone_number(), ast_strftime(), ast_strlen_zero(), ast_tvnow(), ast_verb, name, no_group_meta, NULL, S_COR, and time_stamp_format.

Referenced by log_events().

Variable Documentation

◆ __mod_info

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 = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_EXTENDED, .load = load_module, .unload = unload_module, .reload = reload, }
static

Definition at line 1002 of file app_alarmreceiver.c.

◆ answait

int answait = 1250
static

Definition at line 187 of file app_alarmreceiver.c.

Referenced by alarmreceiver_exec(), and load_config().

◆ app

const char app[] = "AlarmReceiver"
static

Definition at line 146 of file app_alarmreceiver.c.

Referenced by load_module(), and unload_module().

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 1002 of file app_alarmreceiver.c.

◆ call_start_time

struct timeval call_start_time

Definition at line 144 of file app_alarmreceiver.c.

Referenced by alarmreceiver_exec(), and receive_ademco_event().

◆ db_family

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

Definition at line 193 of file app_alarmreceiver.c.

Referenced by database_increment(), and load_config().

◆ digit

char digit

Definition at line 131 of file app_alarmreceiver.c.

Referenced by __ast_pbx_run(), __ast_read(), action_atxfer(), action_cancel_atxfer(), action_playback_and_continue(), ademco_verify_checksum(), agent_alert(), ast_bridge_channel_feature_digit(), ast_bridge_channel_feature_digit_add(), ast_channel_end_dtmf(), ast_dsp_process(), ast_rtp_dtmf_begin(), ast_rtp_dtmf_end(), ast_rtp_dtmf_end_with_duration(), ast_rtp_instance_dtmf_begin(), ast_rtp_instance_dtmf_end(), ast_rtp_instance_dtmf_end_with_duration(), ast_senddigit(), ast_senddigit_begin(), ast_senddigit_end(), ast_senddigit_external(), ast_senddigit_mf(), ast_senddigit_mf_begin(), ast_translate_number_ka(), ast_unreal_digit_begin(), ast_unreal_digit_end(), attended_transfer_exec(), audiosocket_send_dtmf(), bridge_channel_feature_digit_add(), chan_pjsip_digit_begin(), chan_pjsip_digit_end(), chan_pjsip_indicate(), change_spy_mode(), channel_dtmf_begin_cb(), channel_dtmf_end_cb(), collect_digits(), compare(), console_digit_begin(), console_digit_end(), controlplayback_exec(), dahdi_digit_begin(), dahdi_digit_end(), dial_exec_full(), dictate_exec(), digit_to_dtmfindex(), directory_exec(), do_directory(), dtmf_end_to_json(), dtmf_stream(), get_mohbydigit(), handle_incoming_request(), hfp_send_dtmf(), iax2_digit_begin(), iax2_digit_end(), info_dtmf_data_alloc(), jingle_digit_begin(), jingle_digit_end(), manager_play_dtmf(), manager_play_mf(), mbl_digit_end(), moh_digit_match(), moh_handle_digit(), morsecode_exec(), ooh323_digit_begin(), ooh323_digit_end(), ooh323_onReceivedDigit(), play_file(), send_dtmf_begin_event(), send_dtmf_end_event(), send_dtmf_tone(), store_digit(), try_calling(), unistim_do_senddigit(), unistim_senddigit_begin(), unistim_senddigit_end(), valid_exit(), and wait_for_answer().

◆ 

struct { ... } digits_mapping[]
Initial value:
= { {'0', 10}, {'1', 1} , {'2', 2}, {'3', 3}, {'4', 4}, {'5', 5},
{'6', 6}, {'7', 7}, {'8', 8}, {'9', 9}, {'*', 11}, {'#', 12},
{'A', 13}, {'B', 14}, {'C', 15} }

Referenced by ademco_verify_checksum().

◆ event_app

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

Definition at line 192 of file app_alarmreceiver.c.

Referenced by alarmreceiver_exec(), and load_config().

◆ event_file

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

Definition at line 197 of file app_alarmreceiver.c.

Referenced by log_events().

◆ event_spool_dir

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

Definition at line 191 of file app_alarmreceiver.c.

Referenced by load_config(), and log_events().

◆ fdtimeout

int fdtimeout = 2000
static

Definition at line 185 of file app_alarmreceiver.c.

Referenced by acf_faxopt_write(), load_config(), and receive_dtmf_digits().

◆ log_individual_events

int log_individual_events = 0
static

Definition at line 189 of file app_alarmreceiver.c.

Referenced by alarmreceiver_exec(), load_config(), and receive_ademco_event().

◆ no_group_meta

int no_group_meta = 0
static

Definition at line 190 of file app_alarmreceiver.c.

Referenced by load_config(), write_event(), and write_metadata().

◆ sdtimeout

int sdtimeout = 200
static

Definition at line 186 of file app_alarmreceiver.c.

Referenced by load_config(), and receive_dtmf_digits().

◆ time_stamp_format

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

Definition at line 194 of file app_alarmreceiver.c.

Referenced by load_config(), and write_metadata().

◆ toneloudness

int toneloudness = 4096
static

Definition at line 188 of file app_alarmreceiver.c.

Referenced by load_config(), and send_tone_burst().

◆ weight

char weight