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} };
146static const char app[] =
"AlarmReceiver";
220 ast_verb(4,
"AlarmReceiver: Creating database entry %s and setting to 1\n", key);
226 sscanf(
value,
"%30u", &v);
229 ast_verb(4,
"AlarmReceiver: New value for %s: %u\n", key, v);
233 ast_verb(4,
"AlarmReceiver: database_increment write error\n");
260 struct timeval lastdigittime;
263 while (*received < expected && *received < buf_size - 1) {
273 ast_debug(1,
"Waitfor returned %d\n", r);
307 digit_string[*received] =
'\0';
357 signalling_type, (!no_checksum) ?
"yes" :
"no", cl, cn, timestamp) > -1) {
359 }
else if (fprintf(logfile,
"\n\n[metadata]\n\n"
366 signalling_type, (!no_checksum) ?
"yes" :
"no", cl, cn, timestamp) > -1) {
370 ast_verb(3,
"AlarmReceiver: can't write metadata\n");
371 ast_debug(1,
"AlarmReceiver: can't write metadata\n");
415 strncat(workstring,
event_file,
sizeof(workstring) - strlen(workstring) - 1);
418 fd = mkstemp(workstring);
421 ast_verb(3,
"AlarmReceiver: can't make temporary file\n");
422 ast_debug(1,
"AlarmReceiver: can't make temporary file\n");
426 if ((logfile = fdopen(fd,
"w")) ==
NULL) {
431 if (
write_metadata(logfile, signalling_type, chan, no_checksum)) {
463 for (j = 0; j < expected; j++) {
471 ast_verb(2,
"AlarmReceiver: Bad DTMF character %c, trying again\n",
event[j]);
479 if (!(checksum % 15)) {
595 ast_verb(4,
"AlarmMonitoring: Detected format %s.\n", signalling_type);
596 ast_debug(1,
"AlarmMonitoring: Autodetected format %s.\n", signalling_type);
619 int got_some_digits = 0;
620 int events_received = 0;
622 int limit_retries = 0;
623 int expected_length =
sizeof(
event) - 1;
628 ast_verb(4,
"AlarmReceiver: Waiting for first event from panel...\n");
631 int digits_received = 0;
637 expected_length = 16;
641 if (got_some_digits == 0) {
643 ast_verb(4,
"AlarmReceiver: Sending 1400Hz 100ms burst (ACK)\n");
646 ast_verb(4,
"AlarmReceiver: Sending 2300Hz 100ms burst (ACK)\n");
656 if (events_received == 0) {
659 ast_verb(4,
"AlarmReceiver: No events received!\n");
663 ast_verb(4,
"AlarmReceiver: ACK retries during this call: %d\n", ack_retries);
666 ast_verb(4,
"AlarmReceiver: App exiting...\n");
670 if (!strcmp(signalling_type,
UNKNOWN_FORMAT) && digits_received > 5) {
674 if (digits_received == expected_length) {
675 res = limit_retries = 0;
676 }
else if (digits_received == expected_length - 1
680 res = limit_retries = 0;
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);
700 if (limit_retries + 1 >= atoi(limit)) {
707 ast_verb(2,
"AlarmReceiver: Incomplete string: %s, trying again...\n",
event);
713 expected_length =
sizeof(
event) - 1;
716 if (!got_some_digits) {
731 ast_verb(2,
"AlarmReceiver: Nonzero checksum\n");
732 ast_debug(1,
"AlarmReceiver: Nonzero checksum\n");
739 ast_verb(2,
"AlarmReceiver: Wrong message type\n");
740 ast_debug(1,
"AlarmReceiver: Wrong message type\n");
755 if (*ehead ==
NULL) {
758 for (elp = *ehead; elp->
next !=
NULL; elp = elp->
next) {
777 ast_verb(4,
"AlarmReceiver: App exiting... Audio call next!\n");
799 char signalling_type[64] =
"";
804 ast_verb(4,
"AlarmReceiver: Setting write format to Mu-law\n");
813 ast_verb(4,
"AlarmReceiver: Setting read format to Mu-law\n");
826 ast_verb(4,
"AlarmReceiver: Answering channel\n");
833 ast_verb(4,
"AlarmReceiver: Waiting for connection to stabilize\n");
843 res =
log_events(chan, signalling_type, event_head, no_checksum);
853 for (elp = event_head; (elp !=
NULL);) {
880 ast_verb(4,
"AlarmReceiver: No config file\n");
#define ADEMCO_MSG_TYPE_4
static int ademco_verify_checksum(char *event, int expected)
Verify Ademco checksum.
static char time_stamp_format[128]
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_EXPRESS_4_2
struct timeval call_start_time
#define ADEMCO_MSG_TYPE_2
#define ADEMCO_CONTACT_ID
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 ADEMCO_HIGH_SPEED
static char db_family[128]
#define ADEMCO_AUDIO_CALL_NEXT
struct @6 digits_mapping[]
#define ADEMCO_MSG_TYPE_3
static int write_metadata(FILE *logfile, char *signalling_type, struct ast_channel *chan, int no_checksum)
Write metadata to log file.
#define ADEMCO_EXPRESS_4_1
static char event_spool_dir[128]
#define ADEMCO_MSG_TYPE_6
static int log_individual_events
static char event_file[14]
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.
#define ADEMCO_MSG_TYPE_5
static char event_app[128]
#define ADEMCO_SUPER_FAST
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_module(void)
Load the module.
static int unload_module(void)
Unregister Alarm Receiver App.
static int load_config(int reload)
Load the configuration from the configuration file.
static int ademco_detect_format(char *signalling_type, char *event, int *no_checksum)
Detect the message format of an event.
#define ADEMCO_MSG_TYPE_1
static int ademco_check_valid(char *signalling_type, char *event)
Check if the message is in known and valid Ademco format.
static int write_event(FILE *logfile, event_node_t *event)
Log a single event.
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.
Persistent data storage (akin to *doze registry)
int ast_db_put(const char *family, const char *key, const char *value)
Store value addressed by family/key.
int ast_db_get(const char *family, const char *key, char *value, int valuelen)
Get key value specified by family/key.
Asterisk main include file. File version handling, generic pbx functions.
#define ast_calloc(num, len)
A wrapper for calloc()
CallerID (and other GR30) management and generation Includes code and algorithms from the Zapata libr...
void ast_shrink_phone_number(char *n)
Shrink a phone number in place to just digits (more accurately it just removes ()'s,...
General Asterisk PBX channel definitions.
const char * ast_channel_name(const struct ast_channel *chan)
#define ast_channel_lock(chan)
int ast_waitfor(struct ast_channel *chan, int ms)
Wait for input on a channel.
struct ast_frame * ast_read(struct ast_channel *chan)
Reads a frame.
int ast_set_read_format(struct ast_channel *chan, struct ast_format *format)
Sets read format on channel chan.
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.
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
void ast_channel_hangupcause_set(struct ast_channel *chan, int value)
int ast_answer(struct ast_channel *chan)
Answer a channel.
int ast_safe_sleep(struct ast_channel *chan, int ms)
Wait for a specified amount of time, looking for hangups.
#define ast_channel_unlock(chan)
struct ast_format * ast_channel_readformat(struct ast_channel *chan)
ast_channel_state
ast_channel states
Convenient Signal Processing routines.
Generic File Format Support. Should be included by clients of the file handling routines....
Application convenience functions, designed to give consistent look and feel to Asterisk apps.
int ast_safe_system(const char *s)
Safely spawn an OS shell command while closing file descriptors.
Configuration File Parser.
#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.
const char * ast_variable_retrieve(struct ast_config *config, const char *category, const char *variable)
#define ast_debug(level,...)
Log a DEBUG message.
#define ast_verb(level,...)
int ast_playtones_start(struct ast_channel *chan, int vol, const char *tonelist, int interruptible)
Start playing a list of tones on a channel.
void ast_playtones_stop(struct ast_channel *chan)
Stop playing tones on a channel.
Custom localtime functions for multiple timezones.
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
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...
Asterisk locking-related definitions:
Asterisk module definitions.
#define AST_MODULE_INFO(keystr, flags_to_set, desc, fields...)
@ AST_MODULE_SUPPORT_EXTENDED
#define ASTERISK_GPL_KEY
The text the key() function should return.
int ast_unregister_application(const char *app)
Unregister an application.
@ AST_MODULE_LOAD_SUCCESS
@ AST_MODULE_LOAD_DECLINE
Module has failed to load, may be in an inconsistent state.
#define ast_register_application_xml(app, execute)
Register an application using XML documentation.
Core PBX routines and definitions.
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true"....
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
static force_inline int attribute_pure ast_strlen_zero(const char *s)
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Main Channel structure associated with a channel.
Structure used to handle boolean flags.
Data structure associated with a single frame of data.
union ast_frame::@228 data
struct ast_frame_subclass subclass
enum ast_frame_type frametype
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Support for translation of data formats. translate.c.