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";
217 ast_verb(4,
"AlarmReceiver: Creating database entry %s and setting to 1\n", key);
223 sscanf(
value,
"%30u", &v);
226 ast_verb(4,
"AlarmReceiver: New value for %s: %u\n", key, v);
230 ast_verb(4,
"AlarmReceiver: database_increment write error\n");
257 struct timeval lastdigittime;
260 while (*received < expected && *received < buf_size - 1) {
270 ast_debug(1,
"Waitfor returned %d\n", r);
304 digit_string[*received] =
'\0';
354 signalling_type, (!no_checksum) ?
"yes" :
"no", cl, cn, timestamp) > -1) {
356 }
else if (fprintf(logfile,
"\n\n[metadata]\n\n"
363 signalling_type, (!no_checksum) ?
"yes" :
"no", cl, cn, timestamp) > -1) {
367 ast_verb(3,
"AlarmReceiver: can't write metadata\n");
368 ast_debug(1,
"AlarmReceiver: can't write metadata\n");
412 strncat(workstring,
event_file,
sizeof(workstring) - strlen(workstring) - 1);
415 fd = mkstemp(workstring);
418 ast_verb(3,
"AlarmReceiver: can't make temporary file\n");
419 ast_debug(1,
"AlarmReceiver: can't make temporary file\n");
423 if ((logfile = fdopen(fd,
"w")) ==
NULL) {
428 if (
write_metadata(logfile, signalling_type, chan, no_checksum)) {
460 for (j = 0; j < expected; j++) {
468 ast_verb(2,
"AlarmReceiver: Bad DTMF character %c, trying again\n",
event[j]);
476 if (!(checksum % 15)) {
592 ast_verb(4,
"AlarmMonitoring: Detected format %s.\n", signalling_type);
593 ast_debug(1,
"AlarmMonitoring: Autodetected format %s.\n", signalling_type);
616 int got_some_digits = 0;
617 int events_received = 0;
619 int limit_retries = 0;
620 int expected_length =
sizeof(
event) - 1;
625 ast_verb(4,
"AlarmReceiver: Waiting for first event from panel...\n");
628 int digits_received = 0;
634 expected_length = 16;
638 if (got_some_digits == 0) {
640 ast_verb(4,
"AlarmReceiver: Sending 1400Hz 100ms burst (ACK)\n");
643 ast_verb(4,
"AlarmReceiver: Sending 2300Hz 100ms burst (ACK)\n");
653 if (events_received == 0) {
656 ast_verb(4,
"AlarmReceiver: No events received!\n");
660 ast_verb(4,
"AlarmReceiver: ACK retries during this call: %d\n", ack_retries);
663 ast_verb(4,
"AlarmReceiver: App exiting...\n");
667 if (!strcmp(signalling_type,
UNKNOWN_FORMAT) && digits_received > 5) {
671 if (digits_received == expected_length) {
672 res = limit_retries = 0;
673 }
else if (digits_received == expected_length - 1
677 res = limit_retries = 0;
680 ast_verb(4,
"AlarmMonitoring: Skipping checksum for format %s.\n", signalling_type);
681 ast_debug(1,
"AlarmMonitoring: Skipping checksum for format %s.\n", signalling_type);
697 if (limit_retries + 1 >= atoi(limit)) {
704 ast_verb(2,
"AlarmReceiver: Incomplete string: %s, trying again...\n",
event);
710 expected_length =
sizeof(
event) - 1;
713 if (!got_some_digits) {
728 ast_verb(2,
"AlarmReceiver: Nonzero checksum\n");
729 ast_debug(1,
"AlarmReceiver: Nonzero checksum\n");
736 ast_verb(2,
"AlarmReceiver: Wrong message type\n");
737 ast_debug(1,
"AlarmReceiver: Wrong message type\n");
752 if (*ehead ==
NULL) {
755 for (elp = *ehead; elp->
next !=
NULL; elp = elp->
next) {
774 ast_verb(4,
"AlarmReceiver: App exiting... Audio call next!\n");
796 char signalling_type[64] =
"";
801 ast_verb(4,
"AlarmReceiver: Setting write format to Mu-law\n");
810 ast_verb(4,
"AlarmReceiver: Setting read format to Mu-law\n");
823 ast_verb(4,
"AlarmReceiver: Answering channel\n");
830 ast_verb(4,
"AlarmReceiver: Waiting for connection to stabilize\n");
840 res =
log_events(chan, signalling_type, event_head, no_checksum);
850 for (elp = event_head; (elp !=
NULL);) {
877 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.
#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)
@ CONFIG_FLAG_FILEUNCHANGED
#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.
struct ast_frame_subclass subclass
union ast_frame::@226 data
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.