68 #define ALMRCV_CONFIG "alarmreceiver.conf" 69 #define UNKNOWN_FORMAT "UNKNOWN_FORMAT" 71 #define ADEMCO_CONTACT_ID "ADEMCO_CONTACT_ID" 80 #define ADEMCO_EXPRESS_4_1 "ADEMCO_EXPRESS_4_1" 87 #define ADEMCO_EXPRESS_4_2 "ADEMCO_EXPRESS_4_2" 94 #define ADEMCO_HIGH_SPEED "ADEMCO_HIGH_SPEED" 115 #define ADEMCO_SUPER_FAST "ADEMCO_SUPER_FAST" 121 #define ADEMCO_MSG_TYPE_1 "18" 122 #define ADEMCO_MSG_TYPE_2 "98" 123 #define ADEMCO_MSG_TYPE_3 "17" 124 #define ADEMCO_MSG_TYPE_4 "27" 125 #define ADEMCO_MSG_TYPE_5 "55" 126 #define ADEMCO_MSG_TYPE_6 "56" 128 #define ADEMCO_AUDIO_CALL_NEXT "606" 133 }
digits_mapping[] = { {
'0', 10}, {
'1', 1} , {
'2', 2}, {
'3', 3}, {
'4', 4}, {
'5', 5},
134 {
'6', 6}, {
'7', 7}, {
'8', 8}, {
'9', 9}, {
'*', 11}, {
'#', 12},
135 {
'A', 13}, {
'B', 14}, {
'C', 15} };
146 static const char app[] =
"AlarmReceiver";
218 ast_verb(4,
"AlarmReceiver: Creating database entry %s and setting to 1\n", key);
224 sscanf(value,
"%30u", &v);
227 ast_verb(4,
"AlarmReceiver: New value for %s: %u\n", key, v);
228 snprintf(value,
sizeof(value),
"%u", v);
231 ast_verb(4,
"AlarmReceiver: database_increment write error\n");
258 struct timeval lastdigittime;
261 while (*received < expected && *received < buf_size - 1) {
271 ast_debug(1,
"Waitfor returned %d\n", r);
305 digit_string[*received] =
'\0';
355 signalling_type, (!no_checksum) ?
"yes" :
"no", cl, cn, timestamp) > -1) {
357 }
else if (fprintf(logfile,
"\n\n[metadata]\n\n" 364 signalling_type, (!no_checksum) ?
"yes" :
"no", cl, cn, timestamp) > -1) {
368 ast_verb(3,
"AlarmReceiver: can't write metadata\n");
369 ast_debug(1,
"AlarmReceiver: can't write metadata\n");
384 if (fprintf(logfile,
"%s%s\n",
no_group_meta ?
"event=" :
"", event->
data) < 0) {
413 strncat(workstring,
event_file,
sizeof(workstring) - strlen(workstring) - 1);
416 fd = mkstemp(workstring);
419 ast_verb(3,
"AlarmReceiver: can't make temporary file\n");
420 ast_debug(1,
"AlarmReceiver: can't make temporary file\n");
424 if ((logfile = fdopen(fd,
"w")) ==
NULL) {
429 if (
write_metadata(logfile, signalling_type, chan, no_checksum)) {
461 for (j = 0; j < expected; j++) {
469 ast_verb(2,
"AlarmReceiver: Bad DTMF character %c, trying again\n", event[j]);
477 if (!(checksum % 15)) {
593 ast_verb(4,
"AlarmMonitoring: Detected format %s.\n", signalling_type);
594 ast_debug(1,
"AlarmMonitoring: Autodetected format %s.\n", signalling_type);
617 int got_some_digits = 0;
618 int events_received = 0;
620 int limit_retries = 0;
621 int expected_length =
sizeof(
event) - 1;
626 ast_verb(4,
"AlarmReceiver: Waiting for first event from panel...\n");
629 int digits_received = 0;
635 expected_length = 16;
639 if (got_some_digits == 0) {
641 ast_verb(4,
"AlarmReceiver: Sending 1400Hz 100ms burst (ACK)\n");
644 ast_verb(4,
"AlarmReceiver: Sending 2300Hz 100ms burst (ACK)\n");
654 if (events_received == 0) {
657 ast_verb(4,
"AlarmReceiver: No events received!\n");
661 ast_verb(4,
"AlarmReceiver: ACK retries during this call: %d\n", ack_retries);
664 ast_verb(4,
"AlarmReceiver: App exiting...\n");
668 if (!strcmp(signalling_type,
UNKNOWN_FORMAT) && digits_received > 5) {
672 if (digits_received == expected_length) {
673 res = limit_retries = 0;
674 }
else if (digits_received == expected_length - 1
678 res = limit_retries = 0;
681 ast_verb(4,
"AlarmMonitoring: Skipping checksum for format %s.\n", signalling_type);
682 ast_debug(1,
"AlarmMonitoring: Skipping checksum for format %s.\n", signalling_type);
698 if (limit_retries + 1 >= atoi(limit)) {
705 ast_verb(2,
"AlarmReceiver: Incomplete string: %s, trying again...\n",
event);
711 expected_length =
sizeof(
event) - 1;
714 if (!got_some_digits) {
729 ast_verb(2,
"AlarmReceiver: Nonzero checksum\n");
730 ast_debug(1,
"AlarmReceiver: Nonzero checksum\n");
737 ast_verb(2,
"AlarmReceiver: Wrong message type\n");
738 ast_debug(1,
"AlarmReceiver: Wrong message type\n");
753 if (*ehead ==
NULL) {
756 for (elp = *ehead; elp->
next !=
NULL; elp = elp->
next) {
775 ast_verb(4,
"AlarmReceiver: App exiting... Audio call next!\n");
797 char signalling_type[64] =
"";
802 ast_verb(4,
"AlarmReceiver: Setting write format to Mu-law\n");
811 ast_verb(4,
"AlarmReceiver: Setting read format to Mu-law\n");
824 ast_verb(4,
"AlarmReceiver: Answering channel\n");
831 ast_verb(4,
"AlarmReceiver: Waiting for connection to stabilize\n");
841 res =
log_events(chan, signalling_type, event_head, no_checksum);
851 for (elp = event_head; (elp !=
NULL);) {
878 ast_verb(4,
"AlarmReceiver: No config file\n");
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
static int load_config(int reload)
Load the configuration from the configuration file.
int ast_safe_sleep(struct ast_channel *chan, int ms)
Wait for a specified amount of time, looking for hangups.
#define ast_channel_lock(chan)
Main Channel structure associated with a channel.
#define ADEMCO_EXPRESS_4_2
Asterisk locking-related definitions:
Asterisk main include file. File version handling, generic pbx functions.
static char event_file[14]
#define ADEMCO_MSG_TYPE_6
CallerID (and other GR30) management and generation Includes code and algorithms from the Zapata libr...
Support for translation of data formats. translate.c.
void ast_channel_hangupcause_set(struct ast_channel *chan, int value)
Convenient Signal Processing routines.
struct @10 digits_mapping[]
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 CONFIG_STATUS_FILEINVALID
const ast_string_field name
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
struct ast_frame * ast_read(struct ast_channel *chan)
Reads a frame.
ast_channel_state
ast_channel states
#define ADEMCO_MSG_TYPE_4
#define ADEMCO_HIGH_SPEED
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Generic File Format Support. Should be included by clients of the file handling routines. File service providers should instead include mod_format.h.
static void database_increment(char *key)
Attempt to access a database variable and increment it.
void ast_playtones_stop(struct ast_channel *chan)
Stop playing tones on a channel.
static int write_metadata(FILE *logfile, char *signalling_type, struct ast_channel *chan, int no_checksum)
Write metadata to log file.
int ast_unregister_application(const char *app)
Unregister an application.
#define ast_verb(level,...)
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
struct ast_frame_subclass subclass
#define ast_strlen_zero(foo)
struct ast_format * ast_channel_readformat(struct ast_channel *chan)
Custom localtime functions for multiple timezones.
Configuration File Parser.
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...
#define ast_debug(level,...)
Log a DEBUG message.
#define ADEMCO_SUPER_FAST
#define ast_config_load(filename, flags)
Load a config file.
General Asterisk PBX channel definitions.
int ast_set_read_format(struct ast_channel *chan, struct ast_format *format)
Sets read format on channel chan.
#define ADEMCO_MSG_TYPE_1
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
void ast_config_destroy(struct ast_config *config)
Destroys a config.
#define ADEMCO_MSG_TYPE_3
int ast_set_write_format(struct ast_channel *chan, struct ast_format *format)
Sets write format on channel chan.
#define ADEMCO_MSG_TYPE_2
static int ademco_verify_checksum(char *event, int expected)
Verify Ademco checksum.
Core PBX routines and definitions.
#define CONFIG_STATUS_FILEUNCHANGED
#define ADEMCO_EXPRESS_4_1
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 char event_app[128]
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true". This function checks to see whether a string passed to it is an indication of an "true" value. It checks to see if the string is "yes", "true", "y", "t", "on" or "1".
int ast_safe_system(const char *s)
Safely spawn an OS shell command while closing file descriptors.
#define ast_channel_unlock(chan)
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.
#define ast_calloc(num, len)
A wrapper for calloc()
Module has failed to load, may be in an inconsistent state.
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...
int ast_db_get(const char *family, const char *key, char *value, int valuelen)
Get key value specified by family/key.
Structure used to handle boolean flags.
AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS|AST_MODFLAG_LOAD_ORDER, "HTTP Phone Provisioning",.support_level=AST_MODULE_SUPPORT_EXTENDED,.load=load_module,.unload=unload_module,.reload=reload,.load_pri=AST_MODPRI_CHANNEL_DEPEND,.requires="http",)
static int load_module(void)
Load the module.
const char * ast_variable_retrieve(struct ast_config *config, const char *category, const char *variable)
static int write_event(FILE *logfile, event_node_t *event)
Log a single event.
static int log_individual_events
int ast_waitfor(struct ast_channel *chan, int ms)
Wait for input on a channel.
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
#define ADEMCO_CONTACT_ID
const char * ast_channel_name(const struct ast_channel *chan)
static char time_stamp_format[128]
#define ADEMCO_MSG_TYPE_5
int ast_answer(struct ast_channel *chan)
Answer a channel.
Data structure associated with a single frame of data.
int ast_playtones_start(struct ast_channel *chan, int vol, const char *tonelist, int interruptible)
Start playing a list of tones on a channel.
static int ademco_check_valid(char *signalling_type, char *event)
Check if the message is in known and valid Ademco format.
struct timeval call_start_time
static char event_spool_dir[128]
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.
int ast_db_put(const char *family, const char *key, const char *value)
Store value addressed by family/key.
union ast_frame::@263 data
enum ast_frame_type frametype
void ast_shrink_phone_number(char *n)
Shrink a phone number in place to just digits (more accurately it just removes ()'s, .'s, and -'s...
#define ASTERISK_GPL_KEY
The text the key() function should return.
Asterisk module definitions.
struct ast_format * ast_channel_writeformat(struct ast_channel *chan)
static char db_family[128]
Persistant data storage (akin to *doze registry)
Application convenience functions, designed to give consistent look and feel to Asterisk apps...
#define ast_register_application_xml(app, execute)
Register an application using XML documentation.
static int ademco_detect_format(char *signalling_type, char *event, int *no_checksum)
Detect the message format of an event.
static int unload_module(void)
Unregister Alarm Receiver App.
#define ADEMCO_AUDIO_CALL_NEXT