The assertion that peer was not found on final event
[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 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
49
50 #include <math.h>
51 #include <sys/wait.h>
52 #include <sys/time.h>
53
54 #include "asterisk/lock.h"
55 #include "asterisk/file.h"
56 #include "asterisk/channel.h"
57 #include "asterisk/pbx.h"
58 #include "asterisk/module.h"
59 #include "asterisk/translate.h"
60 #include "asterisk/app.h"
61 #include "asterisk/dsp.h"
62 #include "asterisk/config.h"
63 #include "asterisk/localtime.h"
64 #include "asterisk/callerid.h"
65 #include "asterisk/astdb.h"
66 #include "asterisk/utils.h"
67 #include "asterisk/indications.h"
68 #include "asterisk/format_cache.h"
69
70 #define ALMRCV_CONFIG "alarmreceiver.conf"
71 #define UNKNOWN_FORMAT "UNKNOWN_FORMAT"
72
73 #define ADEMCO_CONTACT_ID "ADEMCO_CONTACT_ID"
74 /*
75         AAAA _ID_ P CCC XX ZZZ S
76
77 where AAAA is the account number, _ID_ is 18 or 98, P is the pin status (alarm or restore), CCC
78 is the alarm code which is pre-defined by Ademco (but you may be able to reprogram it in the panel), XX
79 is the dialer group, partition or area number, ZZZ is the zone or user number and S is the checksum
80 */
81
82 #define ADEMCO_EXPRESS_4_1 "ADEMCO_EXPRESS_4_1"
83 /*
84         AAAA _ID_ C S
85
86 where AAAA is the account number, _ID_ is 17, C is the alarm code and S is the checksum.
87 */
88
89 #define ADEMCO_EXPRESS_4_2 "ADEMCO_EXPRESS_4_2"
90 /*
91         AAAA _ID_ C Z S
92
93 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.
94 */
95
96 #define ADEMCO_HIGH_SPEED "ADEMCO_HIGH_SPEED"
97 /*
98         AAAA _ID_ PPPP PPPP X S
99
100 where AAAA is the account number, _ID_ is 55, PPPP PPPP is the status of each zone, X
101 is a special digit which describes the type of information in the PPPP PPPP fields and S is checksum.
102 Each P field contains one of the following values:
103         1  new alarm           3  new restore           5  normal
104         2  new opening         4  new closing           6  outstanding
105 The X field contains one of the following values:
106         0  AlarmNet messages
107         1  ambush or duress
108         2  opening by user (the first P field contains the user number)
109         3  bypass (the P fields indicate which zones are bypassed)
110         4  closing by user (the first P field contain the user number)
111         5  trouble (the P fields contain which zones are in trouble)
112         6  system trouble
113         7  normal message (the P fields indicate zone status)
114         8  low battery (the P fields indicate zone status)
115         9  test (the P fields indicate zone status)
116 */
117 #define ADEMCO_SUPER_FAST "ADEMCO_SUPER_FAST"
118 /*
119         AAAA _ID_ PPPP PPPP X
120 where AAA is the account number, _ID_ is 56
121 */
122
123 #define ADEMCO_MSG_TYPE_1 "18"
124 #define ADEMCO_MSG_TYPE_2 "98"
125 #define ADEMCO_MSG_TYPE_3 "17"
126 #define ADEMCO_MSG_TYPE_4 "27"
127 #define ADEMCO_MSG_TYPE_5 "55"
128 #define ADEMCO_MSG_TYPE_6 "56"
129
130 #define ADEMCO_AUDIO_CALL_NEXT "606"
131
132 struct {
133   char digit;
134   char weight;
135 } digits_mapping[] = { {'0', 10}, {'1', 1} , {'2', 2}, {'3', 3}, {'4', 4}, {'5', 5},
136         {'6', 6}, {'7', 7}, {'8', 8}, {'9', 9}, {'*', 11}, {'#', 12},
137         {'A', 13}, {'B', 14}, {'C', 15} };
138
139 struct event_node{
140         char data[17];
141         struct event_node *next;
142 };
143
144 typedef struct event_node event_node_t;
145
146 struct timeval call_start_time;
147
148 static const char app[] = "AlarmReceiver";
149 /*** DOCUMENTATION
150         <application name="AlarmReceiver" language="en_US">
151                 <synopsis>
152                         Provide support for receiving alarm reports from a burglar or fire alarm panel.
153                 </synopsis>
154                 <syntax />
155                 <description>
156                         <para>This application should be called whenever there is an alarm panel calling in to dump its events.
157                         The application will handshake with the alarm panel, and receive events, validate them, handshake them,
158                         and store them until the panel hangs up. Once the panel hangs up, the application will run the system
159                         command specified by the eventcmd setting in <filename>alarmreceiver.conf</filename> and pipe the
160                         events to the standard input of the application.
161                         The configuration file also contains settings for DTMF timing, and for the loudness of the
162                         acknowledgement tones.</para>
163                         <note><para>Few Ademco DTMF signalling formats are detected automaticaly: Contact ID, Express 4+1,
164                         Express 4+2, High Speed and Super Fast.</para></note>
165                         <para>The application is affected by the following variables:</para>
166                         <variablelist>
167                                 <variable name="ALARMRECEIVER_CALL_LIMIT">
168                                         <para>Maximum call time, in milliseconds.</para>
169                                         <para>If set, this variable causes application to exit after the specified time.</para>
170                                 </variable>
171                                 <variable name="ALARMRECEIVER_RETRIES_LIMIT">
172                                         <para>Maximum number of retries per call.</para>
173                                         <para>If set, this variable causes application to exit after the specified number of messages.</para>
174                                 </variable>
175                         </variablelist>
176                 </description>
177                 <see-also>
178                         <ref type="filename">alarmreceiver.conf</ref>
179                 </see-also>
180         </application>
181  ***/
182
183 /* Config Variables */
184 static int fdtimeout = 2000;
185 static int sdtimeout = 200;
186 static int answait = 1250;
187 static int toneloudness = 4096;
188 static int log_individual_events = 0;
189 static int no_group_meta = 0;
190 static char event_spool_dir[128] = {'\0'};
191 static char event_app[128] = {'\0'};
192 static char db_family[128] = {'\0'};
193 static char time_stamp_format[128] = {"%a %b %d, %Y @ %H:%M:%S %Z"};
194
195 /* Misc variables */
196 static char event_file[14] = "/event-XXXXXX";
197
198 /*!
199  * \brief Attempt to access a database variable and increment it
200  *
201  * \note Only if the user defined db-family in alarmreceiver.conf
202  *
203  * The alarmreceiver app will write statistics to a few variables
204  * in this family if it is defined. If the new key doesn't exist in the
205  * family, then create it and set its value to 1.
206  *
207  * \param key A database key to increment
208  * \return Nothing
209  */
210 static void database_increment(char *key)
211 {
212         unsigned v;
213         char value[16];
214
215         if (ast_strlen_zero(db_family)) {
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 }
238
239 /*!
240  * \brief Receive a fixed length DTMF string.
241  *
242  * \note Doesn't give preferential treatment to any digit,
243  * \note allow different timeout values for the first and all subsequent digits
244  *
245  * \param chan Asterisk Channel
246  * \param digit_string Digits String
247  * \param buf_size The size of the Digits String buffer
248  * \param expected Digits expected for this message type
249  * \param received Pointer to number of digits received so far
250  *
251  * \retval 0 if all digits were successfully received
252  * \retval 1 if a timeout occurred
253  * \retval -1 if the caller hung up or on channel errors
254  */
255 static int receive_dtmf_digits(struct ast_channel *chan, char *digit_string, int buf_size, int expected, int *received)
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)
284                         && (f->subclass.integer == AST_CONTROL_HANGUP)) {
285                         if (f->data.uint32) {
286                                 ast_channel_hangupcause_set(chan, 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 }
311
312 /*!
313  * \brief Write metadata to log file
314  *
315  * \param logfile Log File Pointer
316  * \param signalling_type Signaling Type
317  * \param chan Asterisk Channel
318  * \param no_checksum Expecting messages without checksum
319  *
320  * \retval 0 success
321  * \retval -1 failure
322  */
323 static int write_metadata(FILE *logfile, char *signalling_type, struct ast_channel *chan, int no_checksum)
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 }
374
375 /*!
376  * \brief Log a single event
377  *
378  * \param logfile Log File Pointer
379  * \param event Event Structure
380  *
381  * \retval 0 success
382  * \retval -1 failure
383  */
384 static int write_event(FILE *logfile, event_node_t *event)
385 {
386         if (fprintf(logfile, "%s%s\n", no_group_meta ? "event=" : "", event->data) < 0) {
387                 return -1;
388         }
389
390         return 0;
391 }
392
393 /*!
394  * \brief Log events if configuration key logindividualevents is enabled or on exit
395  *
396  * \param chan Asterisk Channel
397  * \param signalling_type Signaling Type
398  * \param event Event Structure
399  * \param no_checksum Expecting messages without checksum
400  *
401  * \retval 0 success
402  * \retval -1 failure
403  */
404 static int log_events(struct ast_channel *chan, char *signalling_type, event_node_t *event, int no_checksum)
405 {
406         char workstring[sizeof(event_spool_dir) + sizeof(event_file)] = "";
407         int fd;
408         FILE *logfile;
409         event_node_t *elp = event;
410
411         if (!ast_strlen_zero(event_spool_dir)) {
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 }
447
448 /*!
449  * \brief Verify Ademco checksum
450  * \since 11.0
451  *
452  * \param event Received DTMF String
453  * \param expected Number of Digits expected
454  *
455  * \retval 0 success
456  * \retval -1 failure
457  */
458 static int ademco_verify_checksum(char *event, int expected)
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 }
485
486 /*!
487  * \brief Send a single tone burst for a specifed duration and frequency.
488  * \since 11.0
489  *
490  * \param chan Asterisk Channel
491  * \param tone_freq Frequency of the tone to send
492  * \param tone_duration Tone duration in ms
493  * \param delay Delay before sending the tone
494  *
495  * \retval 0 success
496  * \retval -1 failure
497  */
498 static int send_tone_burst(struct ast_channel *chan, const char *tone_freq, int tone_duration, int delay)
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 }
515
516 /*!
517  * \brief Check if the message is in known and valid Ademco format
518  *
519  * \param signalling_type Expected signalling type for the message
520  * \param event event received
521  *
522  * \retval 0 The event is valid
523  * \retval -1 The event is not valid
524  */
525 static int ademco_check_valid(char *signalling_type, char *event)
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 }
555
556 /*!
557  * \brief Detect the message format of an event
558  *
559  * \param signalling_type Expected signalling type for the message
560  * \param event event received
561  * \param no_checksum Should we calculate checksum for the message
562  *
563  * \returns The expected digits for the detected event type
564  */
565 static int ademco_detect_format(char *signalling_type, char *event, int *no_checksum)
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 }
601
602 /*!
603  * \brief Receive Ademco ContactID or other format Data String
604  *
605  * \param chan Asterisk Channel
606  * \param ehead Pointer to events list
607  * \param signalling_type Expected signalling type for the message
608  * \param no_checksum Should we calculate checksum for the message
609  *
610  * \retval 0 success
611  * \retval -1 failure
612  */
613 static int receive_ademco_event(struct ast_channel *chan, event_node_t **ehead, char *signalling_type, int *no_checksum)
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
635                 if (log_individual_events) {
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 }
784
785 /*!
786  * \brief This is the main function called by Asterisk Core whenever the App is invoked in the extension logic.
787  *
788  * \param chan Asterisk Channel
789  * \param data Application data
790  *
791  * \retval 0 success
792  * \retval -1 failure
793  */
794 static int alarmreceiver_exec(struct ast_channel *chan, const char *data)
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
802         if ((ast_format_cmp(ast_channel_writeformat(chan), ast_format_ulaw) == AST_FORMAT_CMP_NOT_EQUAL) &&
803                 (ast_format_cmp(ast_channel_writeformat(chan), ast_format_alaw) == AST_FORMAT_CMP_NOT_EQUAL)) {
804                 ast_verb(4, "AlarmReceiver: Setting write format to Mu-law\n");
805                 if (ast_set_write_format(chan, ast_format_ulaw)) {
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
811         if ((ast_format_cmp(ast_channel_readformat(chan), ast_format_ulaw) == AST_FORMAT_CMP_NOT_EQUAL) &&
812                 (ast_format_cmp(ast_channel_readformat(chan), ast_format_alaw) == AST_FORMAT_CMP_NOT_EQUAL)) {
813                 ast_verb(4, "AlarmReceiver: Setting read format to Mu-law\n");
814                 if (ast_set_read_format(chan, ast_format_ulaw)) {
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));
822         call_start_time = ast_tvnow();
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 */
842         if (!log_individual_events) {
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);
849                 ast_safe_system(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 }
861
862 /*!
863  * \brief Load the configuration from the configuration file
864  *
865  * \param reload True on reload
866  *
867  * \retval 1 success
868  * \retval 0 failure
869  */
870 static int load_config(int reload)
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",
886                         ALMRCV_CONFIG);
887                 return 0;
888         }
889
890         if ((value = ast_variable_retrieve(cfg, "general", "eventcmd")) != NULL) {
891                 ast_copy_string(event_app, value, sizeof(event_app));
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) {
931                 no_group_meta = ast_true(value);
932         }
933
934         if ((value = ast_variable_retrieve(cfg, "general", "logindividualevents")) != NULL) {
935                 log_individual_events = ast_true(value);
936         }
937
938         if ((value = ast_variable_retrieve(cfg, "general", "eventspooldir")) != NULL) {
939                 ast_copy_string(event_spool_dir, value, sizeof(event_spool_dir));
940         }
941
942         if ((value = ast_variable_retrieve(cfg, "general", "timestampformat")) != NULL) {
943                 ast_copy_string(time_stamp_format, value, sizeof(time_stamp_format));
944         }
945
946         if ((value = ast_variable_retrieve(cfg, "general", "db-family")) != NULL) {
947                 ast_copy_string(db_family, value, sizeof(db_family));
948         }
949
950         ast_config_destroy(cfg);
951
952         return 1;
953 }
954
955 /*!
956  * \brief Unregister Alarm Receiver App
957  *
958  * \retval 0 success
959  * \retval -1 failure
960  */
961 static int unload_module(void)
962 {
963         return ast_unregister_application(app);
964 }
965
966 /*!
967  * \brief Load the module
968  *
969  * Module loading including tests for configuration or dependencies.
970  * This function can return AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_DECLINE,
971  * or AST_MODULE_LOAD_SUCCESS. If a dependency or environment variable fails
972  * tests return AST_MODULE_LOAD_FAILURE. If the module can not load the
973  * configuration file or other non-critical problem return
974  * AST_MODULE_LOAD_DECLINE. On success return AST_MODULE_LOAD_SUCCESS.
975  */
976 static int load_module(void)
977 {
978         if (load_config(0)) {
979                 if (ast_register_application_xml(app, alarmreceiver_exec)) {
980                         return AST_MODULE_LOAD_FAILURE;
981                 }
982                 return AST_MODULE_LOAD_SUCCESS;
983         }
984
985         return AST_MODULE_LOAD_DECLINE;
986 }
987
988 static int reload(void)
989 {
990         if (load_config(1)) {
991                 return AST_MODULE_LOAD_SUCCESS;
992         }
993
994         return AST_MODULE_LOAD_DECLINE;
995 }
996
997 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Alarm Receiver for Asterisk",
998                 .support_level = AST_MODULE_SUPPORT_EXTENDED,
999                 .load = load_module,
1000                 .unload = unload_module,
1001                 .reload = reload,
1002 );