Merge "Revert "AGI: Only defer frames when in an interception routine.""
[asterisk/asterisk.git] / apps / app_alarmreceiver.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C)  2004 - 2005 Steve Rodgers
5  *
6  * Steve Rodgers <hwstar@rodgers.sdcoxmail.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18
19 /*! \file
20  *
21  * \brief Central Station Alarm receiver for Ademco Contact ID
22  * \author Steve Rodgers <hwstar@rodgers.sdcoxmail.com>
23  *
24  * *** WARNING *** WARNING *** WARNING *** WARNING *** WARNING *** WARNING *** WARNING *** WARNING ***
25  *
26  * Use at your own risk. Please consult the GNU GPL license document included with Asterisk.         *
27  *
28  * *** WARNING *** WARNING *** WARNING *** WARNING *** WARNING *** WARNING *** WARNING *** WARNING ***
29  *
30  * \ingroup applications
31  */
32
33 /*! \li \ref app_alarmreceiver.c uses the configuration file \ref alarmreceiver.conf
34  * \addtogroup configuration_file Configuration Files
35  */
36
37 /*!
38  * \page alarmreceiver.conf alarmreceiver.conf
39  * \verbinclude alarmreceiver.conf.sample
40  */
41
42 /*** MODULEINFO
43         <support_level>extended</support_level>
44  ***/
45
46 #include "asterisk.h"
47
48 #include <math.h>
49 #include <sys/wait.h>
50 #include <sys/time.h>
51
52 #include "asterisk/lock.h"
53 #include "asterisk/file.h"
54 #include "asterisk/channel.h"
55 #include "asterisk/pbx.h"
56 #include "asterisk/module.h"
57 #include "asterisk/translate.h"
58 #include "asterisk/app.h"
59 #include "asterisk/dsp.h"
60 #include "asterisk/config.h"
61 #include "asterisk/localtime.h"
62 #include "asterisk/callerid.h"
63 #include "asterisk/astdb.h"
64 #include "asterisk/utils.h"
65 #include "asterisk/indications.h"
66 #include "asterisk/format_cache.h"
67
68 #define ALMRCV_CONFIG "alarmreceiver.conf"
69 #define UNKNOWN_FORMAT "UNKNOWN_FORMAT"
70
71 #define ADEMCO_CONTACT_ID "ADEMCO_CONTACT_ID"
72 /*
73         AAAA _ID_ P CCC XX ZZZ S
74
75 where AAAA is the account number, _ID_ is 18 or 98, P is the pin status (alarm or restore), CCC
76 is the alarm code which is pre-defined by Ademco (but you may be able to reprogram it in the panel), XX
77 is the dialer group, partition or area number, ZZZ is the zone or user number and S is the checksum
78 */
79
80 #define ADEMCO_EXPRESS_4_1 "ADEMCO_EXPRESS_4_1"
81 /*
82         AAAA _ID_ C S
83
84 where AAAA is the account number, _ID_ is 17, C is the alarm code and S is the checksum.
85 */
86
87 #define ADEMCO_EXPRESS_4_2 "ADEMCO_EXPRESS_4_2"
88 /*
89         AAAA _ID_ C Z S
90
91 where AAAA is the account number, _ID_ is 27, C is the alarm code, Z is the zone or user number and S is the checksum.
92 */
93
94 #define ADEMCO_HIGH_SPEED "ADEMCO_HIGH_SPEED"
95 /*
96         AAAA _ID_ PPPP PPPP X S
97
98 where AAAA is the account number, _ID_ is 55, PPPP PPPP is the status of each zone, X
99 is a special digit which describes the type of information in the PPPP PPPP fields and S is checksum.
100 Each P field contains one of the following values:
101         1  new alarm           3  new restore           5  normal
102         2  new opening         4  new closing           6  outstanding
103 The X field contains one of the following values:
104         0  AlarmNet messages
105         1  ambush or duress
106         2  opening by user (the first P field contains the user number)
107         3  bypass (the P fields indicate which zones are bypassed)
108         4  closing by user (the first P field contain the user number)
109         5  trouble (the P fields contain which zones are in trouble)
110         6  system trouble
111         7  normal message (the P fields indicate zone status)
112         8  low battery (the P fields indicate zone status)
113         9  test (the P fields indicate zone status)
114 */
115 #define ADEMCO_SUPER_FAST "ADEMCO_SUPER_FAST"
116 /*
117         AAAA _ID_ PPPP PPPP X
118 where AAA is the account number, _ID_ is 56
119 */
120
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"
127
128 #define ADEMCO_AUDIO_CALL_NEXT "606"
129
130 struct {
131   char digit;
132   char weight;
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} };
136
137 struct event_node{
138         char data[17];
139         struct event_node *next;
140 };
141
142 typedef struct event_node event_node_t;
143
144 struct timeval call_start_time;
145
146 static const char app[] = "AlarmReceiver";
147 /*** DOCUMENTATION
148         <application name="AlarmReceiver" language="en_US">
149                 <synopsis>
150                         Provide support for receiving alarm reports from a burglar or fire alarm panel.
151                 </synopsis>
152                 <syntax />
153                 <description>
154                         <para>This application should be called whenever there is an alarm panel calling in to dump its events.
155                         The application will handshake with the alarm panel, and receive events, validate them, handshake them,
156                         and store them until the panel hangs up. Once the panel hangs up, the application will run the system
157                         command specified by the eventcmd setting in <filename>alarmreceiver.conf</filename> and pipe the
158                         events to the standard input of the application.
159                         The configuration file also contains settings for DTMF timing, and for the loudness of the
160                         acknowledgement tones.</para>
161                         <note><para>Few Ademco DTMF signalling formats are detected automaticaly: Contact ID, Express 4+1,
162                         Express 4+2, High Speed and Super Fast.</para></note>
163                         <para>The application is affected by the following variables:</para>
164                         <variablelist>
165                                 <variable name="ALARMRECEIVER_CALL_LIMIT">
166                                         <para>Maximum call time, in milliseconds.</para>
167                                         <para>If set, this variable causes application to exit after the specified time.</para>
168                                 </variable>
169                                 <variable name="ALARMRECEIVER_RETRIES_LIMIT">
170                                         <para>Maximum number of retries per call.</para>
171                                         <para>If set, this variable causes application to exit after the specified number of messages.</para>
172                                 </variable>
173                         </variablelist>
174                 </description>
175                 <see-also>
176                         <ref type="filename">alarmreceiver.conf</ref>
177                 </see-also>
178         </application>
179  ***/
180
181 /* Config Variables */
182 static int fdtimeout = 2000;
183 static int sdtimeout = 200;
184 static int answait = 1250;
185 static int toneloudness = 4096;
186 static int log_individual_events = 0;
187 static int no_group_meta = 0;
188 static char event_spool_dir[128] = {'\0'};
189 static char event_app[128] = {'\0'};
190 static char db_family[128] = {'\0'};
191 static char time_stamp_format[128] = {"%a %b %d, %Y @ %H:%M:%S %Z"};
192
193 /* Misc variables */
194 static char event_file[14] = "/event-XXXXXX";
195
196 /*!
197  * \brief Attempt to access a database variable and increment it
198  *
199  * \note Only if the user defined db-family in alarmreceiver.conf
200  *
201  * The alarmreceiver app will write statistics to a few variables
202  * in this family if it is defined. If the new key doesn't exist in the
203  * family, then create it and set its value to 1.
204  *
205  * \param key A database key to increment
206  * \return Nothing
207  */
208 static void database_increment(char *key)
209 {
210         unsigned v;
211         char value[16];
212
213         if (ast_strlen_zero(db_family)) {
214                 return; /* If not defined, don't do anything */
215         }
216
217         if (ast_db_get(db_family, key, value, sizeof(value) - 1)) {
218                 ast_verb(4, "AlarmReceiver: Creating database entry %s and setting to 1\n", key);
219                 /* Guess we have to create it */
220                 ast_db_put(db_family, key, "1");
221                 return;
222         }
223
224         sscanf(value, "%30u", &v);
225         v++;
226
227         ast_verb(4, "AlarmReceiver: New value for %s: %u\n", key, v);
228         snprintf(value, sizeof(value), "%u", v);
229
230         if (ast_db_put(db_family, key, value)) {
231                 ast_verb(4, "AlarmReceiver: database_increment write error\n");
232         }
233
234         return;
235 }
236
237 /*!
238  * \brief Receive a fixed length DTMF string.
239  *
240  * \note Doesn't give preferential treatment to any digit,
241  * \note allow different timeout values for the first and all subsequent digits
242  *
243  * \param chan Asterisk Channel
244  * \param digit_string Digits String
245  * \param buf_size The size of the Digits String buffer
246  * \param expected Digits expected for this message type
247  * \param received Pointer to number of digits received so far
248  *
249  * \retval 0 if all digits were successfully received
250  * \retval 1 if a timeout occurred
251  * \retval -1 if the caller hung up or on channel errors
252  */
253 static int receive_dtmf_digits(struct ast_channel *chan, char *digit_string, int buf_size, int expected, int *received)
254 {
255         int rtn = 0;
256         int r;
257         struct ast_frame *f;
258         struct timeval lastdigittime;
259
260         lastdigittime = ast_tvnow();
261         while (*received < expected && *received < buf_size - 1) {
262                 /* If timed out, leave */
263                 if (ast_tvdiff_ms(ast_tvnow(), lastdigittime) > ((*received > 0) ? sdtimeout : fdtimeout)) {
264                         ast_verb(4, "AlarmReceiver: DTMF Digit Timeout on %s\n", ast_channel_name(chan));
265                         ast_debug(1, "AlarmReceiver: DTMF timeout on chan %s\n", ast_channel_name(chan));
266                         rtn = 1;
267                         break;
268                 }
269
270                 if ((r = ast_waitfor(chan, -1)) < 0) {
271                         ast_debug(1, "Waitfor returned %d\n", r);
272                         continue;
273                 }
274
275                 if ((f = ast_read(chan)) == NULL) {
276                         rtn = -1;
277                         break;
278                 }
279
280                 /* If they hung up, leave */
281                 if ((f->frametype == AST_FRAME_CONTROL)
282                         && (f->subclass.integer == AST_CONTROL_HANGUP)) {
283                         if (f->data.uint32) {
284                                 ast_channel_hangupcause_set(chan, f->data.uint32);
285                         }
286                         ast_frfree(f);
287                         rtn = -1;
288                         break;
289                 }
290
291                 /* If not DTMF, just do it again */
292                 if (f->frametype != AST_FRAME_DTMF) {
293                         ast_frfree(f);
294                         continue;
295                 }
296
297                 /* Save digit */
298                 digit_string[(*received)++] = f->subclass.integer;
299                 ast_frfree(f);
300
301                 lastdigittime = ast_tvnow();
302         }
303
304         /* Null terminate the end of the digit_string */
305         digit_string[*received] = '\0';
306
307         return rtn;
308 }
309
310 /*!
311  * \brief Write metadata to log file
312  *
313  * \param logfile Log File Pointer
314  * \param signalling_type Signaling Type
315  * \param chan Asterisk Channel
316  * \param no_checksum Expecting messages without checksum
317  *
318  * \retval 0 success
319  * \retval -1 failure
320  */
321 static int write_metadata(FILE *logfile, char *signalling_type, struct ast_channel *chan, int no_checksum)
322 {
323         struct timeval t;
324         struct ast_tm now;
325         char *cl;
326         char *cn;
327         char workstring[80];
328         char timestamp[80];
329
330         /* Extract the caller ID location */
331         ast_copy_string(workstring,
332                 S_COR(ast_channel_caller(chan)->id.number.valid,
333                 ast_channel_caller(chan)->id.number.str, ""), sizeof(workstring));
334         ast_shrink_phone_number(workstring);
335         if (ast_strlen_zero(workstring)) {
336                 cl = "<unknown>";
337         } else {
338                 cl = workstring;
339         }
340         cn = S_COR(ast_channel_caller(chan)->id.name.valid,
341                 ast_channel_caller(chan)->id.name.str, "<unknown>");
342
343         /* Get the current time */
344         t = ast_tvnow();
345         ast_localtime(&t, &now, NULL);
346
347         /* Format the time */
348         ast_strftime(timestamp, sizeof(timestamp), time_stamp_format, &now);
349
350         if (no_group_meta && fprintf(logfile, "PROTOCOL=%s\n"
351                         "CHECKSUM=%s\n"
352                         "CALLINGFROM=%s\n"
353                         "CALLERNAME=%s\n"
354                         "TIMESTAMP=%s\n\n",
355                         signalling_type, (!no_checksum) ? "yes" : "no", cl, cn, timestamp) > -1) {
356                 return 0;
357         } else if (fprintf(logfile, "\n\n[metadata]\n\n"
358                         "PROTOCOL=%s\n"
359                         "CHECKSUM=%s\n"
360                         "CALLINGFROM=%s\n"
361                         "CALLERNAME=%s\n"
362                         "TIMESTAMP=%s\n\n"
363                         "[events]\n\n",
364                         signalling_type, (!no_checksum) ? "yes" : "no", cl, cn, timestamp) > -1) {
365                 return 0;
366         }
367
368         ast_verb(3, "AlarmReceiver: can't write metadata\n");
369         ast_debug(1, "AlarmReceiver: can't write metadata\n");
370         return -1;
371 }
372
373 /*!
374  * \brief Log a single event
375  *
376  * \param logfile Log File Pointer
377  * \param event Event Structure
378  *
379  * \retval 0 success
380  * \retval -1 failure
381  */
382 static int write_event(FILE *logfile, event_node_t *event)
383 {
384         if (fprintf(logfile, "%s%s\n", no_group_meta ? "event=" : "", event->data) < 0) {
385                 return -1;
386         }
387
388         return 0;
389 }
390
391 /*!
392  * \brief Log events if configuration key logindividualevents is enabled or on exit
393  *
394  * \param chan Asterisk Channel
395  * \param signalling_type Signaling Type
396  * \param event Event Structure
397  * \param no_checksum Expecting messages without checksum
398  *
399  * \retval 0 success
400  * \retval -1 failure
401  */
402 static int log_events(struct ast_channel *chan, char *signalling_type, event_node_t *event, int no_checksum)
403 {
404         char workstring[sizeof(event_spool_dir) + sizeof(event_file)] = "";
405         int fd;
406         FILE *logfile;
407         event_node_t *elp = event;
408
409         if (!ast_strlen_zero(event_spool_dir)) {
410
411                 /* Make a template */
412                 ast_copy_string(workstring, event_spool_dir, sizeof(workstring));
413                 strncat(workstring, event_file, sizeof(workstring) - strlen(workstring) - 1);
414
415                 /* Make the temporary file */
416                 fd = mkstemp(workstring);
417
418                 if (fd == -1) {
419                         ast_verb(3, "AlarmReceiver: can't make temporary file\n");
420                         ast_debug(1, "AlarmReceiver: can't make temporary file\n");
421                         return -1;
422                 }
423
424                 if ((logfile = fdopen(fd, "w")) == NULL) {
425                         return -1;
426                 }
427
428                 /* Write the file */
429                 if (write_metadata(logfile, signalling_type, chan, no_checksum)) {
430                         fflush(logfile);
431                         fclose(logfile);
432                         return -1;
433                 }
434
435                 while ((elp != NULL) && (write_event(logfile, elp) == 0)) {
436                         elp = elp->next;
437                 }
438
439                 fflush(logfile);
440                 fclose(logfile);
441         }
442
443         return 0;
444 }
445
446 /*!
447  * \brief Verify Ademco checksum
448  * \since 11.0
449  *
450  * \param event Received DTMF String
451  * \param expected Number of Digits expected
452  *
453  * \retval 0 success
454  * \retval -1 failure
455  */
456 static int ademco_verify_checksum(char *event, int expected)
457 {
458         int checksum = 0;
459         int i, j;
460
461         for (j = 0; j < expected; j++) {
462                 for (i = 0; i < ARRAY_LEN(digits_mapping); i++) {
463                         if (digits_mapping[i].digit == event[j]) {
464                                 break;
465                         }
466                 }
467
468                 if (i >= ARRAY_LEN(digits_mapping)) {
469                         ast_verb(2, "AlarmReceiver: Bad DTMF character %c, trying again\n", event[j]);
470                         return -1;
471                 }
472
473                 checksum += digits_mapping[i].weight;
474         }
475
476         /* Checksum is mod(15) of the total */
477         if (!(checksum % 15)) {
478                 return 0;
479         }
480
481         return -1;
482 }
483
484 /*!
485  * \brief Send a single tone burst for a specified duration and frequency.
486  * \since 11.0
487  *
488  * \param chan Asterisk Channel
489  * \param tone_freq Frequency of the tone to send
490  * \param tone_duration Tone duration in ms
491  * \param delay Delay before sending the tone
492  *
493  * \retval 0 success
494  * \retval -1 failure
495  */
496 static int send_tone_burst(struct ast_channel *chan, const char *tone_freq, int tone_duration, int delay)
497 {
498         if (delay && ast_safe_sleep(chan, delay)) {
499                 return -1;
500         }
501
502         if (ast_playtones_start(chan, toneloudness, tone_freq, 0)) {
503                 return -1;
504         }
505
506         if (ast_safe_sleep(chan, tone_duration)) {
507                 return -1;
508         }
509
510         ast_playtones_stop(chan);
511         return 0;
512 }
513
514 /*!
515  * \brief Check if the message is in known and valid Ademco format
516  *
517  * \param signalling_type Expected signalling type for the message
518  * \param event event received
519  *
520  * \retval 0 The event is valid
521  * \retval -1 The event is not valid
522  */
523 static int ademco_check_valid(char *signalling_type, char *event)
524 {
525         if (!strcmp(signalling_type, UNKNOWN_FORMAT)) {
526                 return 1;
527         }
528
529         if (!strcmp(signalling_type, ADEMCO_CONTACT_ID)
530                 && strncmp(event + 4, ADEMCO_MSG_TYPE_1, 2)
531                 && strncmp(event + 4, ADEMCO_MSG_TYPE_2, 2)) {
532                 return -1;
533         }
534
535         if (!strcmp(signalling_type, ADEMCO_EXPRESS_4_1) && strncmp(event + 4, ADEMCO_MSG_TYPE_3, 2)) {
536                 return -1;
537         }
538
539         if (!strcmp(signalling_type, ADEMCO_EXPRESS_4_2) && strncmp(event + 4, ADEMCO_MSG_TYPE_4, 2)) {
540                 return -1;
541         }
542
543         if (!strcmp(signalling_type, ADEMCO_HIGH_SPEED) && strncmp(event + 4, ADEMCO_MSG_TYPE_5, 2)) {
544                 return -1;
545         }
546
547         if (!strcmp(signalling_type, ADEMCO_SUPER_FAST) && strncmp(event + 4, ADEMCO_MSG_TYPE_6, 2)) {
548                 return -1;
549         }
550
551         return 0;
552 }
553
554 /*!
555  * \brief Detect the message format of an event
556  *
557  * \param signalling_type Expected signalling type for the message
558  * \param event event received
559  * \param no_checksum Should we calculate checksum for the message
560  *
561  * \returns The expected digits for the detected event type
562  */
563 static int ademco_detect_format(char *signalling_type, char *event, int *no_checksum)
564 {
565         int res = 16;
566
567         if (!strncmp(event + 4, ADEMCO_MSG_TYPE_1, 2)
568                 || !strncmp(event + 4, ADEMCO_MSG_TYPE_2, 2)) {
569                 sprintf(signalling_type, "%s", ADEMCO_CONTACT_ID);
570         }
571
572         if (!strncmp(event + 4, ADEMCO_MSG_TYPE_3, 2)) {
573                 sprintf(signalling_type, "%s", ADEMCO_EXPRESS_4_1);
574                 res = 8;
575         }
576
577         if (!strncmp(event + 4, ADEMCO_MSG_TYPE_4, 2)) {
578                 sprintf(signalling_type, "%s", ADEMCO_EXPRESS_4_2);
579                 res = 9;
580         }
581
582         if (!strncmp(event + 4, ADEMCO_MSG_TYPE_5, 2)) {
583                 sprintf(signalling_type, "%s", ADEMCO_HIGH_SPEED);
584         }
585
586         if (!strncmp(event + 4, ADEMCO_MSG_TYPE_6, 2)) {
587                 sprintf(signalling_type, "%s", ADEMCO_SUPER_FAST);
588                 *no_checksum = 1;
589                 res = 15;
590         }
591
592         if (strcmp(signalling_type, UNKNOWN_FORMAT)) {
593                 ast_verb(4, "AlarmMonitoring: Detected format %s.\n", signalling_type);
594                 ast_debug(1, "AlarmMonitoring: Autodetected format %s.\n", signalling_type);
595         }
596
597         return res;
598 }
599
600 /*!
601  * \brief Receive Ademco ContactID or other format Data String
602  *
603  * \param chan Asterisk Channel
604  * \param ehead Pointer to events list
605  * \param signalling_type Expected signalling type for the message
606  * \param no_checksum Should we calculate checksum for the message
607  *
608  * \retval 0 success
609  * \retval -1 failure
610  */
611 static int receive_ademco_event(struct ast_channel *chan, event_node_t **ehead, char *signalling_type, int *no_checksum)
612 {
613         int res = 0;
614         const char *limit;
615         char event[17];
616         event_node_t *enew, *elp;
617         int got_some_digits = 0;
618         int events_received = 0;
619         int ack_retries = 0;
620         int limit_retries = 0;
621         int expected_length = sizeof(event) - 1;
622
623         database_increment("calls-received");
624
625         /* Wait for first event */
626         ast_verb(4, "AlarmReceiver: Waiting for first event from panel...\n");
627
628         while (res >= 0) {
629                 int digits_received = 0;
630
631                 res = 0;
632
633                 if (log_individual_events) {
634                         sprintf(signalling_type, "%s", UNKNOWN_FORMAT);
635                         expected_length = 16;
636                         *no_checksum = 0;
637                 }
638
639                 if (got_some_digits == 0) {
640                         /* Send ACK tone sequence */
641                         ast_verb(4, "AlarmReceiver: Sending 1400Hz 100ms burst (ACK)\n");
642                         res = send_tone_burst(chan, "1400", 100, 0);
643                         if (!res) {
644                                 ast_verb(4, "AlarmReceiver: Sending 2300Hz 100ms burst (ACK)\n");
645                                 res = send_tone_burst(chan, "2300", 100, 100);
646                         }
647                 }
648                 if (res) {
649                         return -1;
650                 }
651
652                 res = receive_dtmf_digits(chan, event, sizeof(event), expected_length, &digits_received);
653                 if (res < 0) {
654                         if (events_received == 0) {
655                                 /* Hangup with no events received should be logged in the DB */
656                                 database_increment("no-events-received");
657                                 ast_verb(4, "AlarmReceiver: No events received!\n");
658                         } else {
659                                 if (ack_retries) {
660                                         database_increment("ack-retries");
661                                         ast_verb(4, "AlarmReceiver: ACK retries during this call: %d\n", ack_retries);
662                                 }
663                         }
664                         ast_verb(4, "AlarmReceiver: App exiting...\n");
665                         break;
666                 }
667
668                 if (!strcmp(signalling_type, UNKNOWN_FORMAT) && digits_received > 5) {
669                         expected_length = ademco_detect_format(signalling_type, event, no_checksum);
670
671                         if (res > 0) {
672                                 if (digits_received == expected_length) {
673                                         res = limit_retries = 0;
674                                 } else if (digits_received == expected_length - 1
675                                         && (!strcmp(signalling_type, ADEMCO_EXPRESS_4_2)
676                                         || !strcmp(signalling_type, ADEMCO_EXPRESS_4_1))) {
677                                         /* ADEMCO EXPRESS without checksum */
678                                         res = limit_retries = 0;
679                                         expected_length--;
680                                         *no_checksum = 1;
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);
683                                 }
684                         }
685                 }
686
687                 ast_channel_lock(chan);
688                 limit = pbx_builtin_getvar_helper(chan, "ALARMRECEIVER_CALL_LIMIT");
689                 if (!ast_strlen_zero(limit)) {
690                         if (ast_tvdiff_ms(ast_tvnow(), call_start_time) > atoi(limit)) {
691                                 ast_channel_unlock(chan);
692                                 return -1;
693                         }
694                 }
695                 limit = pbx_builtin_getvar_helper(chan, "ALARMRECEIVER_RETRIES_LIMIT");
696                 ast_channel_unlock(chan);
697                 if (!ast_strlen_zero(limit)) {
698                         if (limit_retries + 1 >= atoi(limit)) {
699                                 return -1;
700                         }
701                 }
702
703                 if (res) {
704                         /* Didn't get all of the digits */
705                         ast_verb(2, "AlarmReceiver: Incomplete string: %s, trying again...\n", event);
706                         limit_retries++;
707
708                         if (!events_received && strcmp(signalling_type, UNKNOWN_FORMAT))
709                         {
710                                 sprintf(signalling_type, "%s", UNKNOWN_FORMAT);
711                                 expected_length = sizeof(event) - 1;
712                         }
713
714                         if (!got_some_digits) {
715                                 got_some_digits = (!ast_strlen_zero(event)) ? 1 : 0;
716                                 ack_retries++;
717                         }
718                         continue;
719                 }
720
721                 got_some_digits = 1;
722
723                 ast_verb(2, "AlarmReceiver: Received Event %s\n", event);
724                 ast_debug(1, "AlarmReceiver: Received event: %s\n", event);
725
726                 /* Calculate checksum */
727                 if (!(*no_checksum) && ademco_verify_checksum(event, expected_length)) {
728                         database_increment("checksum-errors");
729                         ast_verb(2, "AlarmReceiver: Nonzero checksum\n");
730                         ast_debug(1, "AlarmReceiver: Nonzero checksum\n");
731                         continue;
732                 }
733
734                 /* Check the message type for correctness */
735                 if (ademco_check_valid(signalling_type, event)) {
736                         database_increment("format-errors");
737                         ast_verb(2, "AlarmReceiver: Wrong message type\n");
738                         ast_debug(1, "AlarmReceiver: Wrong message type\n");
739                         continue;
740                 }
741
742                 events_received++;
743
744                 /* Queue the Event */
745                 if (!(enew = ast_calloc(1, sizeof(*enew)))) {
746                         return -1;
747                 }
748
749                 enew->next = NULL;
750                 ast_copy_string(enew->data, event, sizeof(enew->data));
751
752                 /* Insert event onto end of list */
753                 if (*ehead == NULL) {
754                         *ehead = enew;
755                 } else {
756                         for (elp = *ehead; elp->next != NULL; elp = elp->next) {
757                                 ;
758                         }
759                         elp->next = enew;
760                 }
761
762                 /* Let the user have the option of logging the single event before sending the kissoff tone */
763                 if (log_individual_events && log_events(chan, signalling_type, enew, *no_checksum)) {
764                         return -1;
765                 }
766
767                 /* Send the kissoff tone (1400 Hz, 900 ms, after 200ms delay) */
768                 if (send_tone_burst(chan, "1400", 900, 200)) {
769                         return -1;
770                 }
771
772                 /* If audio call follows, exit alarm receiver app */
773                 if (!strcmp(signalling_type, ADEMCO_CONTACT_ID)
774                         && !strncmp(event + 7, ADEMCO_AUDIO_CALL_NEXT, 3)) {
775                         ast_verb(4, "AlarmReceiver: App exiting... Audio call next!\n");
776                         return 0;
777                 }
778         }
779
780         return res;
781 }
782
783 /*!
784  * \brief This is the main function called by Asterisk Core whenever the App is invoked in the extension logic.
785  *
786  * \param chan Asterisk Channel
787  * \param data Application data
788  *
789  * \retval 0 success
790  * \retval -1 failure
791  */
792 static int alarmreceiver_exec(struct ast_channel *chan, const char *data)
793 {
794         int res = 0;
795         int no_checksum = 0;
796         event_node_t *elp, *efree;
797         char signalling_type[64] = "";
798         event_node_t *event_head = NULL;
799
800         if ((ast_format_cmp(ast_channel_writeformat(chan), ast_format_ulaw) == AST_FORMAT_CMP_NOT_EQUAL) &&
801                 (ast_format_cmp(ast_channel_writeformat(chan), ast_format_alaw) == AST_FORMAT_CMP_NOT_EQUAL)) {
802                 ast_verb(4, "AlarmReceiver: Setting write format to Mu-law\n");
803                 if (ast_set_write_format(chan, ast_format_ulaw)) {
804                         ast_log(LOG_WARNING, "AlarmReceiver: Unable to set write format to Mu-law on %s\n",ast_channel_name(chan));
805                         return -1;
806                 }
807         }
808
809         if ((ast_format_cmp(ast_channel_readformat(chan), ast_format_ulaw) == AST_FORMAT_CMP_NOT_EQUAL) &&
810                 (ast_format_cmp(ast_channel_readformat(chan), ast_format_alaw) == AST_FORMAT_CMP_NOT_EQUAL)) {
811                 ast_verb(4, "AlarmReceiver: Setting read format to Mu-law\n");
812                 if (ast_set_read_format(chan, ast_format_ulaw)) {
813                         ast_log(LOG_WARNING, "AlarmReceiver: Unable to set read format to Mu-law on %s\n",ast_channel_name(chan));
814                         return -1;
815                 }
816         }
817
818         /* Set default values for this invocation of the application */
819         ast_copy_string(signalling_type, UNKNOWN_FORMAT, sizeof(signalling_type));
820         call_start_time = ast_tvnow();
821
822         /* Answer the channel if it is not already */
823         if (ast_channel_state(chan) != AST_STATE_UP) {
824                 ast_verb(4, "AlarmReceiver: Answering channel\n");
825                 if (ast_answer(chan)) {
826                         return -1;
827                 }
828         }
829
830         /* Wait for the connection to settle post-answer */
831         ast_verb(4, "AlarmReceiver: Waiting for connection to stabilize\n");
832         if (ast_safe_sleep(chan, answait)) {
833                 return -1;
834         }
835
836         /* Attempt to receive the events */
837         receive_ademco_event(chan, &event_head, signalling_type, &no_checksum);
838
839         /* Events queued by receiver, write them all out here if so configured */
840         if (!log_individual_events) {
841                 res = log_events(chan, signalling_type, event_head, no_checksum);
842         }
843
844         /* Do we exec a command line at the end? */
845         if ((!res) && (!ast_strlen_zero(event_app)) && (event_head)) {
846                 ast_debug(1,"Alarmreceiver: executing: %s\n", event_app);
847                 ast_safe_system(event_app);
848         }
849
850         /* Free up the data allocated in our linked list */
851         for (elp = event_head; (elp != NULL);) {
852                 efree = elp;
853                 elp = elp->next;
854                 ast_free(efree);
855         }
856
857         return 0;
858 }
859
860 /*!
861  * \brief Load the configuration from the configuration file
862  *
863  * \param reload True on reload
864  *
865  * \retval 1 success
866  * \retval 0 failure
867  */
868 static int load_config(int reload)
869 {
870         struct ast_config *cfg;
871         const char *value;
872         struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
873
874         /* Read in the config file */
875         cfg = ast_config_load(ALMRCV_CONFIG, config_flags);
876
877         if (!cfg) {
878                 ast_verb(4, "AlarmReceiver: No config file\n");
879                 return 0;
880         } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
881                 return 1;
882         } else if (cfg == CONFIG_STATUS_FILEINVALID) {
883                 ast_log(LOG_ERROR, "Config file %s is in an invalid format.  Aborting.\n",
884                         ALMRCV_CONFIG);
885                 return 0;
886         }
887
888         if ((value = ast_variable_retrieve(cfg, "general", "eventcmd")) != NULL) {
889                 ast_copy_string(event_app, value, sizeof(event_app));
890         }
891
892         if ((value = ast_variable_retrieve(cfg, "general", "loudness")) != NULL) {
893                 toneloudness = atoi(value);
894                 if (toneloudness < 100) {
895                         toneloudness = 100;
896                 } else if (toneloudness > 8192) {
897                         toneloudness = 8192;
898                 }
899         }
900
901         if ((value = ast_variable_retrieve(cfg, "general", "fdtimeout")) != NULL) {
902                 fdtimeout = atoi(value);
903                 if (fdtimeout < 1000) {
904                         fdtimeout = 1000;
905                 } else if (fdtimeout > 10000) {
906                         fdtimeout = 10000;
907                 }
908         }
909
910         if ((value = ast_variable_retrieve(cfg, "general", "sdtimeout")) != NULL) {
911                 sdtimeout = atoi(value);
912                 if (sdtimeout < 110) {
913                         sdtimeout = 110;
914                 } else if (sdtimeout > 4000) {
915                         sdtimeout = 4000;
916                 }
917         }
918
919         if ((value = ast_variable_retrieve(cfg, "general", "answait")) != NULL) {
920                 answait = atoi(value);
921                 if (answait < 500) {
922                         answait = 500;
923                 } else if (answait > 10000) {
924                         answait = 10000;
925                 }
926         }
927
928         if ((value = ast_variable_retrieve(cfg, "general", "no_group_meta")) != NULL) {
929                 no_group_meta = ast_true(value);
930         }
931
932         if ((value = ast_variable_retrieve(cfg, "general", "logindividualevents")) != NULL) {
933                 log_individual_events = ast_true(value);
934         }
935
936         if ((value = ast_variable_retrieve(cfg, "general", "eventspooldir")) != NULL) {
937                 ast_copy_string(event_spool_dir, value, sizeof(event_spool_dir));
938         }
939
940         if ((value = ast_variable_retrieve(cfg, "general", "timestampformat")) != NULL) {
941                 ast_copy_string(time_stamp_format, value, sizeof(time_stamp_format));
942         }
943
944         if ((value = ast_variable_retrieve(cfg, "general", "db-family")) != NULL) {
945                 ast_copy_string(db_family, value, sizeof(db_family));
946         }
947
948         ast_config_destroy(cfg);
949
950         return 1;
951 }
952
953 /*!
954  * \brief Unregister Alarm Receiver App
955  *
956  * \retval 0 success
957  * \retval -1 failure
958  */
959 static int unload_module(void)
960 {
961         return ast_unregister_application(app);
962 }
963
964 /*!
965  * \brief Load the module
966  *
967  * Module loading including tests for configuration or dependencies.
968  * This function can return AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_DECLINE,
969  * or AST_MODULE_LOAD_SUCCESS. If a dependency or environment variable fails
970  * tests return AST_MODULE_LOAD_FAILURE. If the module can not load the
971  * configuration file or other non-critical problem return
972  * AST_MODULE_LOAD_DECLINE. On success return AST_MODULE_LOAD_SUCCESS.
973  */
974 static int load_module(void)
975 {
976         if (load_config(0)) {
977                 if (ast_register_application_xml(app, alarmreceiver_exec)) {
978                         return AST_MODULE_LOAD_FAILURE;
979                 }
980                 return AST_MODULE_LOAD_SUCCESS;
981         }
982
983         return AST_MODULE_LOAD_DECLINE;
984 }
985
986 static int reload(void)
987 {
988         if (load_config(1)) {
989                 return AST_MODULE_LOAD_SUCCESS;
990         }
991
992         return AST_MODULE_LOAD_DECLINE;
993 }
994
995 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Alarm Receiver for Asterisk",
996         .support_level = AST_MODULE_SUPPORT_EXTENDED,
997         .load = load_module,
998         .unload = unload_module,
999         .reload = reload,
1000 );