put generator functions next to each other.
[asterisk/asterisk.git] / apps / app_sms.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2004 - 2005, Adrian Kennard, rights assigned to Digium
5  *
6  * See http://www.asterisk.org for more information about
7  * the Asterisk project. Please do not directly contact
8  * any of the maintainers of this project for assistance;
9  * the project provides a web site, mailing lists and IRC
10  * channels for your use.
11  *
12  * This program is free software, distributed under the terms of
13  * the GNU General Public License Version 2. See the LICENSE file
14  * at the top of the source tree.
15  */
16
17 /*! \file
18  *
19  * \brief SMS application - ETSI ES 201 912 protocol 1 implementation
20  * 
21  * \par Development notes
22  * \note The ETSI standards are available free of charge from ETSI at
23  *      http://pda.etsi.org/pda/queryform.asp
24  *      Among the relevant documents here we have:
25  *
26  *      ES 201 912      SMS for PSTN/ISDN
27  *      TS 123 040      Technical realization of SMS
28  *
29  * \note 2006-09-19: ETSI ES 201 912 protocol 2 used in Italy and Spain
30  *                   support added by Filippo Grassilli (Hyppo)
31  *                   <http://hyppo.com> (Hyppo)
32  *                   Not fully tested, under development
33  * 
34  * \ingroup applications
35  *
36  * \author Adrian Kennard (for the original protocol 1 code)
37  */
38
39 #include "asterisk.h"
40
41 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
42
43 #include <stdlib.h>
44 #include <stdio.h>
45 #include <string.h>
46 #include <unistd.h>
47 #include <errno.h>
48 #include <dirent.h>
49 #include <ctype.h>
50 #include <sys/types.h>
51 #include <sys/stat.h>
52
53 #include "asterisk/lock.h"
54 #include "asterisk/file.h"
55 #include "asterisk/logger.h"
56 #include "asterisk/options.h"
57 #include "asterisk/channel.h"
58 #include "asterisk/pbx.h"
59 #include "asterisk/module.h"
60 #include "asterisk/alaw.h"
61 #include "asterisk/callerid.h"
62
63 /* #define OUTALAW */ /* enable this to output Alaw rather than linear */
64
65 /* ToDo */
66 /* Add full VP support */
67 /* Handle status report messages (generation and reception) */
68 /* Time zones on time stamps */
69 /* user ref field */
70
71 static volatile unsigned char message_ref;      /* arbitary message ref */
72 static volatile unsigned int seq;       /* arbitrary message sequence number for unqiue files */
73
74 static char log_file[255];
75 static char spool_dir[255];
76
77 static char *app = "SMS";
78
79 static char *synopsis = "Communicates with SMS service centres and SMS capable analogue phones";
80
81 static char *descrip =
82         "  SMS(name|[a][s][t]):  SMS handles exchange of SMS data with a call to/from SMS capable\n"
83         "phone or SMS PSTN service center. Can send and/or receive SMS messages.\n"
84         "Works to ETSI ES 201 912 compatible with BT SMS PSTN service in UK\n"
85         "and Telecom Italia in Italy.\n"
86         "Typical usage is to use to handle called from the SMS service centre CLI,\n"
87         "or to set up a call using 'outgoing' or manager interface to connect\n"
88         "service centre to SMS()\n"
89         "name is the name of the queue used in /var/spool/asterisk/sms\n"
90         "Arguments:\n"
91         " a: answer, i.e. send initial FSK packet.\n"
92         " s: act as service centre talking to a phone.\n"
93         " t: use protocol 2 (default used is protocol 1).\n"
94         "Messages are processed as per text file message queues.\n" 
95         "smsq (a separate software) is a command to generate message\n"
96         "queues and send messages.\n"
97         "NOTE: the protocol has tight delay bounds. Please use short frames\n"
98         "and disable/keep short the jitter buffer on the ATA to make sure that\n"
99         "respones (ACK etc.) are received in time.\n";
100
101 /*
102  * 80 samples of a single period of the wave. At 8000 Hz, it means these
103  * are the samples of a 100 Hz signal.
104  * To pick the two carriers (1300Hz for '1' and 2100 Hz for '0') used by
105  * the modulation, we should take one every 13 and 21 samples respectively.
106  */
107 static signed short wave[] = {
108         0, 392, 782, 1167, 1545, 1913, 2270, 2612, 2939, 3247, 3536, 3802, 4045, 4263, 4455, 4619, 4755, 4862, 4938, 4985,
109         5000, 4985, 4938, 4862, 4755, 4619, 4455, 4263, 4045, 3802, 3536, 3247, 2939, 2612, 2270, 1913, 1545, 1167, 782, 392,
110         0, -392, -782, -1167,
111          -1545, -1913, -2270, -2612, -2939, -3247, -3536, -3802, -4045, -4263, -4455, -4619, -4755, -4862, -4938, -4985, -5000,
112         -4985, -4938, -4862,
113         -4755, -4619, -4455, -4263, -4045, -3802, -3536, -3247, -2939, -2612, -2270, -1913, -1545, -1167, -782, -392
114 };
115
116 #ifdef OUTALAW
117 static unsigned char wavea[80];
118 typedef unsigned char output_t;
119 static const output_t *wave_out = wavea;        /* outgoing samples */
120 #define __OUT_FMT AST_FORMAT_ALAW;
121 #else
122 typedef signed short output_t;
123 static const output_t *wave_out = wave;         /* outgoing samples */
124 #define __OUT_FMT AST_FORMAT_SLINEAR
125 #endif
126
127 #define OSYNC_BITS      80      /* initial sync bits */
128
129 /*!
130  * The SMS spec ETSI ES 201 912 defines two protocols with different message types.
131  * Also note that the high bit is used to indicate whether the message
132  * is complete or not, but in two opposite ways:
133  * for Protocol 1, 0x80 means that the message is complete;
134  * for Protocol 2, 0x00 means that the message is complete;
135  */
136 enum message_types {
137         DLL_SMS_MASK    = 0x7f, /* mask for the valid bits */
138
139         /* Protocol 1 values */
140         DLL1_SMS_DATA           = 0x11, /* data packet */
141         DLL1_SMS_ERROR          = 0x12,
142         DLL1_SMS_EST            = 0x13, /* start the connection */
143         DLL1_SMS_REL            = 0x14, /* end the connection */
144         DLL1_SMS_ACK            = 0x15,
145         DLL1_SMS_NACK           = 0x16,
146
147         DLL1_SMS_COMPLETE       = 0x80, /* packet is complete */
148         DLL1_SMS_MORE           = 0x00, /* more data to follow */
149
150         /* Protocol 2 values */
151         DLL2_SMS_EST            = 0x7f, /* magic number. No message body */
152         DLL2_SMS_INFO_MO        = 0x10,
153         DLL2_SMS_INFO_MT        = 0x11,
154         DLL2_SMS_INFO_STA       = 0x12,
155         DLL2_SMS_NACK           = 0x13,
156         DLL2_SMS_ACK0           = 0x14, /* ack even-numbered frame */
157         DLL2_SMS_ACK1           = 0x15, /* ack odd-numbered frame */
158         DLL2_SMS_ENQ            = 0x16,
159         DLL2_SMS_REL            = 0x17, /* end the connection */
160
161         DLL2_SMS_COMPLETE       = 0x00, /* packet is complete */
162         DLL2_SMS_MORE           = 0x80, /* more data to follow */
163 };
164
165 /* SMS 7 bit character mapping to UCS-2 */
166 static const unsigned short defaultalphabet[] = {
167         0x0040, 0x00A3, 0x0024, 0x00A5, 0x00E8, 0x00E9, 0x00F9, 0x00EC,
168         0x00F2, 0x00E7, 0x000A, 0x00D8, 0x00F8, 0x000D, 0x00C5, 0x00E5,
169         0x0394, 0x005F, 0x03A6, 0x0393, 0x039B, 0x03A9, 0x03A0, 0x03A8,
170         0x03A3, 0x0398, 0x039E, 0x00A0, 0x00C6, 0x00E6, 0x00DF, 0x00C9,
171         ' ', '!', '"', '#', 164, '%', '&', 39, '(', ')', '*', '+', ',', '-', '.', '/',
172         '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?',
173         161, 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
174         'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 196, 214, 209, 220, 167,
175         191, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
176         'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 228, 246, 241, 252, 224,
177 };
178
179 static const unsigned short escapes[] = {
180         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x000C, 0, 0, 0, 0, 0,
181         0, 0, 0, 0, 0x005E, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
182         0, 0, 0, 0, 0, 0, 0, 0, 0x007B, 0x007D, 0, 0, 0, 0, 0, 0x005C,
183         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x005B, 0x007E, 0x005D, 0,
184         0x007C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
185         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
186         0, 0, 0, 0, 0, 0x20AC, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
187         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
188 };
189
190 #define SMSLEN 160              /*!< max SMS length */
191
192 typedef struct sms_s {
193         unsigned char hangup;        /*!< we are done... */
194         unsigned char err;           /*!< set for any errors */
195         unsigned char smsc:1;        /*!< we are SMSC */
196         unsigned char rx:1;          /*!< this is a received message */
197         char queue[30];              /*!< queue name */
198         char oa[20];                 /*!< originating address */
199         char da[20];                 /*!< destination address */
200         time_t scts;                 /*!< time stamp, UTC */
201         unsigned char pid;           /*!< protocol ID */
202         unsigned char dcs;           /*!< data coding scheme */
203         short mr;                    /*!< message reference - actually a byte, but usde -1 for not set */
204         int udl;                     /*!< user data length */
205         int udhl;                    /*!< user data header length */
206         unsigned char srr:1;         /*!< Status Report request */
207         unsigned char udhi:1;        /*!< User Data Header required, even if length 0 */
208         unsigned char rp:1;          /*!< Reply Path */
209         unsigned int vp;             /*!< validity period in minutes, 0 for not set */
210         unsigned short ud[SMSLEN];   /*!< user data (message), UCS-2 coded */
211         unsigned char udh[SMSLEN];   /*!< user data header */
212         char cli[20];                /*!< caller ID */
213         unsigned char ophase;        /*!< phase (0-79) for 0 and 1 frequencies (1300Hz and 2100Hz) */
214         unsigned char ophasep;       /*!< phase (0-79) for 1200 bps */
215         unsigned char obyte;         /*!< byte being sent */
216         unsigned int opause;         /*!< silent pause before sending (in sample periods) */
217         unsigned char obitp;         /*!< bit in byte */
218         unsigned char osync;         /*!< sync bits to send */
219         unsigned char obytep;        /*!< byte in data */
220         unsigned char obyten;        /*!< bytes in data */
221         unsigned char omsg[256];     /*!< data buffer (out) */
222         unsigned char imsg[250];     /*!< data buffer (in) */
223         signed long long ims0,
224                 imc0,
225                 ims1,
226                 imc1;                      /*!< magnitude averages sin/cos 0/1 */
227         unsigned int idle;
228         unsigned short imag;         /*!< signal level */
229         unsigned char ips0;          /*!< phase sin for bit 0, start at  0 inc by 21 mod 80 */
230         unsigned char ips1;          /*!< phase cos for bit 0, start at 20 inc by 21 mod 80 */
231         unsigned char ipc0;          /*!< phase sin for bit 1, start at  0 inc by 13 mod 80 */
232         unsigned char ipc1;          /*!< phase cos for bit 1, start at 20 inc by 13 mod 80 */
233         unsigned char ibitl;         /*!< last bit */
234         unsigned char ibitc;         /*!< bit run length count */
235         unsigned char iphasep;       /*!< bit phase (0-79) for 1200 bps */
236         unsigned char ibitn;         /*!< bit number in byte being received */
237         unsigned char ibytev;        /*!< byte value being received */
238         unsigned char ibytep;        /*!< byte pointer in message */
239         unsigned char ibytec;        /*!< byte checksum for message */
240         unsigned char ierr;          /*!< error flag */
241         unsigned char ibith;         /*!< history of last bits */
242         unsigned char ibitt;         /*!< total of 1's in last 3 bytes */
243         /* more to go here */
244
245         int protocol;                /*!< ETSI SMS protocol to use (passed at app call) */
246         int oseizure;                /*!< protocol 2: channel seizure bits to send */
247         int framenumber;             /*!< protocol 2: frame number (for sending ACK0 or ACK1) */
248         char udtxt[SMSLEN]; /*!< user data (message), PLAIN text */
249 } sms_t;
250
251 /* different types of encoding */
252 #define is7bit(dcs) (((dcs)&0xC0)?(!((dcs)&4)):(!((dcs)&12)))
253 #define is8bit(dcs) (((dcs)&0xC0)?(((dcs)&4)):(((dcs)&12)==4))
254 #define is16bit(dcs) (((dcs)&0xC0)?0:(((dcs)&12)==8))
255
256 static void sms_messagetx (sms_t * h);
257
258 /*! \brief copy number, skipping non digits apart from leading + */
259 static void numcpy (char *d, char *s)
260 {
261         if (*s == '+')
262                 *d++ = *s++;
263         while (*s) {
264                 if (isdigit (*s))
265                         *d++ = *s;
266                 s++;
267         }
268         *d = 0;
269 }
270
271 /*! \brief static, return a date/time in ISO format */
272 static char * isodate (time_t t)
273 {
274         static char date[20];
275         strftime (date, sizeof (date), "%Y-%m-%dT%H:%M:%S", localtime (&t));
276         return date;
277 }
278
279 /*! \brief reads next UCS character from null terminated UTF-8 string and advanced pointer */
280 /* for non valid UTF-8 sequences, returns character as is */
281 /* Does not advance pointer for null termination */
282 static long utf8decode (unsigned char **pp)
283 {
284         unsigned char *p = *pp;
285         if (!*p)
286                 return 0;                 /* null termination of string */
287         (*pp)++;
288         if (*p < 0xC0)
289                 return *p;                /* ascii or continuation character */
290         if (*p < 0xE0) {
291                 if (*p < 0xC2 || (p[1] & 0xC0) != 0x80)
292                         return *p;             /* not valid UTF-8 */
293                 (*pp)++;
294                 return ((*p & 0x1F) << 6) + (p[1] & 0x3F);
295         }
296         if (*p < 0xF0) {
297                 if ((*p == 0xE0 && p[1] < 0xA0) || (p[1] & 0xC0) != 0x80 || (p[2] & 0xC0) != 0x80)
298                          return *p;             /* not valid UTF-8 */
299                 (*pp) += 2;
300                 return ((*p & 0x0F) << 12) + ((p[1] & 0x3F) << 6) + (p[2] & 0x3F);
301         }
302         if (*p < 0xF8) {
303                 if ((*p == 0xF0 && p[1] < 0x90) || (p[1] & 0xC0) != 0x80 || (p[2] & 0xC0) != 0x80 || (p[3] & 0xC0) != 0x80)
304                         return *p;             /* not valid UTF-8 */
305                 (*pp) += 3;
306                 return ((*p & 0x07) << 18) + ((p[1] & 0x3F) << 12) + ((p[2] & 0x3F) << 6) + (p[3] & 0x3F);
307         }
308         if (*p < 0xFC) {
309                 if ((*p == 0xF8 && p[1] < 0x88) || (p[1] & 0xC0) != 0x80 || (p[2] & 0xC0) != 0x80 || (p[3] & 0xC0) != 0x80
310                         || (p[4] & 0xC0) != 0x80)
311                         return *p;             /* not valid UTF-8 */
312                 (*pp) += 4;
313                 return ((*p & 0x03) << 24) + ((p[1] & 0x3F) << 18) + ((p[2] & 0x3F) << 12) + ((p[3] & 0x3F) << 6) + (p[4] & 0x3F);
314         }
315         if (*p < 0xFE) {
316                 if ((*p == 0xFC && p[1] < 0x84) || (p[1] & 0xC0) != 0x80 || (p[2] & 0xC0) != 0x80 || (p[3] & 0xC0) != 0x80
317                         || (p[4] & 0xC0) != 0x80 || (p[5] & 0xC0) != 0x80)
318                         return *p;             /* not valid UTF-8 */
319                 (*pp) += 5;
320                 return ((*p & 0x01) << 30) + ((p[1] & 0x3F) << 24) + ((p[2] & 0x3F) << 18) + ((p[3] & 0x3F) << 12) + ((p[4] & 0x3F) << 6) + (p[5] & 0x3F);
321         }
322         return *p;                   /* not sensible */
323 }
324
325 /*! \brief takes a binary header (udhl bytes at udh) and UCS-2 message (udl characters at ud) and packs in to o using SMS 7 bit character codes */
326 /* The return value is the number of septets packed in to o, which is internally limited to SMSLEN */
327 /* o can be null, in which case this is used to validate or count only */
328 /* if the input contains invalid characters then the return value is -1 */
329 static int packsms7 (unsigned char *o, int udhl, unsigned char *udh, int udl, unsigned short *ud)
330 {
331          unsigned char p = 0, b = 0, n = 0;
332
333         if (udhl) {                            /* header */
334                 if (o)
335                         o[p++] = udhl;
336                 b = 1;
337                 n = 1;
338                 while (udhl--) {
339                         if (o)
340                                 o[p++] = *udh++;
341                         b += 8;
342                         while (b >= 7) {
343                                 b -= 7;
344                                 n++;
345                         }
346                         if (n >= SMSLEN)
347                                 return n;
348                 }
349                 if (b) {
350                         b = 7 - b;
351                         if (++n >= SMSLEN)
352                                 return n;
353                         };      /* filling to septet boundary */
354                 }
355                 if (o)
356                         o[p] = 0;
357                 /* message */
358                 while (udl--) {
359                         long u;
360                         unsigned char v;
361                         u = *ud++;
362                         for (v = 0; v < 128 && defaultalphabet[v] != u; v++);
363                         if (v == 128 && u && n + 1 < SMSLEN) {
364                                 for (v = 0; v < 128 && escapes[v] != u; v++);
365                                 if (v < 128) {  /* escaped sequence */
366                                 if (o)
367                                         o[p] |= (27 << b);
368                                 b += 7;
369                                 if (b >= 8) {
370                                         b -= 8;
371                                         p++;
372                                         if (o)
373                                                 o[p] = (27 >> (7 - b));
374                                 }
375                                 n++;
376                         }
377                 }
378                 if (v == 128)
379                         return -1;             /* invalid character */
380                 if (o)
381                         o[p] |= (v << b);
382                 b += 7;
383                 if (b >= 8) {
384                         b -= 8;
385                         p++;
386                         if (o)
387                                 o[p] = (v >> (7 - b));
388                 }
389                 if (++n >= SMSLEN)
390                         return n;
391         }
392         return n;
393 }
394
395 /*! \brief takes a binary header (udhl bytes at udh) and UCS-2 message (udl characters at ud) and packs in to o using 8 bit character codes */
396 /* The return value is the number of bytes packed in to o, which is internally limited to 140 */
397 /* o can be null, in which case this is used to validate or count only */
398 /* if the input contains invalid characters then the return value is -1 */
399 static int packsms8 (unsigned char *o, int udhl, unsigned char *udh, int udl, unsigned short *ud)
400 {
401         unsigned char p = 0;
402
403         /* header - no encoding */
404         if (udhl) {
405                 if (o)
406                         o[p++] = udhl;
407                 while (udhl--) {
408                         if (o)
409                                 o[p++] = *udh++;
410                         if (p >= 140)
411                                 return p;
412                 }
413         }
414         while (udl--) {
415                 long u;
416                 u = *ud++;
417                 if (u < 0 || u > 0xFF)
418                         return -1;             /* not valid */
419                 if (o)
420                         o[p++] = u;
421                 if (p >= 140)
422                         return p;
423         }
424         return p;
425 }
426
427 /*! \brief takes a binary header (udhl bytes at udh) and UCS-2 
428         message (udl characters at ud) and packs in to o using 16 bit 
429         UCS-2 character codes 
430         The return value is the number of bytes packed in to o, which is 
431         internally limited to 140 
432         o can be null, in which case this is used to validate or count 
433         only if the input contains invalid characters then 
434         the return value is -1 */
435 static int packsms16 (unsigned char *o, int udhl, unsigned char *udh, int udl, unsigned short *ud)
436 {
437         unsigned char p = 0;
438         /* header - no encoding */
439         if (udhl) {
440                 if (o)
441                         o[p++] = udhl;
442                 while (udhl--) {
443                         if (o)
444                                 o[p++] = *udh++;
445                         if (p >= 140)
446                                 return p;
447                 }
448         }
449         while (udl--) {
450                 long u;
451                 u = *ud++;
452                 if (o)
453                         o[p++] = (u >> 8);
454                 if (p >= 140)
455                         return p - 1;          /* could not fit last character */
456                 if (o)
457                         o[p++] = u;
458                 if (p >= 140)
459                         return p;
460         }
461         return p;
462 }
463
464 /*! \brief general pack, with length and data, 
465         returns number of bytes of target used */
466 static int packsms (unsigned char dcs, unsigned char *base, unsigned int udhl, unsigned char *udh, int udl, unsigned short *ud)
467 {
468         unsigned char *p = base;
469         if (udl) {
470                 int l = 0;
471                 if (is7bit (dcs)) {              /* 7 bit */
472                         l = packsms7 (p + 1, udhl, udh, udl, ud);
473                         if (l < 0)
474                                 l = 0;
475                         *p++ = l;
476                         p += (l * 7 + 7) / 8;
477                 } else if (is8bit (dcs)) {                                                               /* 8 bit */
478                         l = packsms8 (p + 1, udhl, udh, udl, ud);
479                         if (l < 0)
480                                 l = 0;
481                         *p++ = l;
482                         p += l;
483                 } else {                         /* UCS-2 */
484                         l = packsms16 (p + 1, udhl, udh, udl, ud);
485                         if (l < 0)
486                                 l = 0;
487                         *p++ = l;
488                         p += l;
489                 }
490         } else
491                 *p++ = 0;                         /* no user data */
492         return p - base;
493 }
494
495
496 /*! \brief pack a date and return */
497 static void packdate (unsigned char *o, time_t w)
498 {
499         struct tm *t = localtime (&w);
500 #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined( __NetBSD__ ) || defined(__APPLE__)
501         int z = -t->tm_gmtoff / 60 / 15;
502 #else
503         int z = timezone / 60 / 15;
504 #endif
505         *o++ = ((t->tm_year % 10) << 4) + (t->tm_year % 100) / 10;
506         *o++ = (((t->tm_mon + 1) % 10) << 4) + (t->tm_mon + 1) / 10;
507         *o++ = ((t->tm_mday % 10) << 4) + t->tm_mday / 10;
508         *o++ = ((t->tm_hour % 10) << 4) + t->tm_hour / 10;
509         *o++ = ((t->tm_min % 10) << 4) + t->tm_min / 10;
510         *o++ = ((t->tm_sec % 10) << 4) + t->tm_sec / 10;
511         if (z < 0)
512                 *o++ = (((-z) % 10) << 4) + (-z) / 10 + 0x08;
513         else
514                 *o++ = ((z % 10) << 4) + z / 10;
515 }
516
517 /*! \brief unpack a date and return */
518 static time_t unpackdate (unsigned char *i)
519 {
520         struct tm t;
521         t.tm_year = 100 + (i[0] & 0xF) * 10 + (i[0] >> 4);
522         t.tm_mon = (i[1] & 0xF) * 10 + (i[1] >> 4) - 1;
523         t.tm_mday = (i[2] & 0xF) * 10 + (i[2] >> 4);
524         t.tm_hour = (i[3] & 0xF) * 10 + (i[3] >> 4);
525         t.tm_min = (i[4] & 0xF) * 10 + (i[4] >> 4);
526         t.tm_sec = (i[5] & 0xF) * 10 + (i[5] >> 4);
527         t.tm_isdst = 0;
528         if (i[6] & 0x08)
529                 t.tm_min += 15 * ((i[6] & 0x7) * 10 + (i[6] >> 4));
530         else
531                 t.tm_min -= 15 * ((i[6] & 0x7) * 10 + (i[6] >> 4));
532         return mktime (&t);
533 }
534
535 /*! \brief unpacks bytes (7 bit encoding) at i, len l septets, 
536         and places in udh and ud setting udhl and udl. udh not used 
537         if udhi not set */
538 static void unpacksms7 (unsigned char *i, unsigned char l, unsigned char *udh, int *udhl, unsigned short *ud, int *udl, char udhi)
539 {
540         unsigned char b = 0, p = 0;
541         unsigned short *o = ud;
542         *udhl = 0;
543         if (udhi && l) {                 /* header */
544                 int h = i[p];
545                 *udhl = h;
546                 if (h) {
547                         b = 1;
548                         p++;
549                         l--;
550                         while (h-- && l) {
551                                 *udh++ = i[p++];
552                                 b += 8;
553                                 while (b >= 7) {
554                                         b -= 7;
555                                         l--;
556                                         if (!l)
557                                                 break;
558                                 }
559                         }
560                         /* adjust for fill, septets */
561                         if (b) {
562                                 b = 7 - b;
563                                 l--;
564                         }
565                 }
566         }
567         while (l--) {
568                 unsigned char v;
569                 if (b < 2)
570                         v = ((i[p] >> b) & 0x7F);
571                 else
572                         v = ((((i[p] >> b) + (i[p + 1] << (8 - b)))) & 0x7F);
573                 b += 7;
574                 if (b >= 8) {
575                         b -= 8;
576                         p++;
577                 }
578                 if (o > ud && o[-1] == 0x00A0 && escapes[v])
579                         o[-1] = escapes[v];
580                 else
581                         *o++ = defaultalphabet[v];
582         }
583         *udl = (o - ud);
584 }
585
586 /*! \brief unpacks bytes (8 bit encoding) at i, len l septets, 
587       and places in udh and ud setting udhl and udl. udh not used 
588       if udhi not set */
589 static void unpacksms8 (unsigned char *i, unsigned char l, unsigned char *udh, int *udhl, unsigned short *ud, int *udl, char udhi)
590 {
591         unsigned short *o = ud;
592         *udhl = 0;
593         if (udhi) {
594                 int n = *i;
595                 *udhl = n;
596                 if (n) {
597                         i++;
598                         l--;
599                         while (l && n) {
600                                 l--;
601                                 n--;
602                                 *udh++ = *i++;
603                         }
604                 }
605         }
606         while (l--)
607                 *o++ = *i++;      /* not to UTF-8 as explicitly 8 bit coding in DCS */
608         *udl = (o - ud);
609 }
610
611 /*! \brief unpacks bytes (16 bit encoding) at i, len l septets,
612          and places in udh and ud setting udhl and udl. 
613         udh not used if udhi not set */
614 static void unpacksms16 (unsigned char *i, unsigned char l, unsigned char *udh, int *udhl, unsigned short *ud, int *udl, char udhi)
615 {
616         unsigned short *o = ud;
617         *udhl = 0;
618         if (udhi) {
619                 int n = *i;
620                 *udhl = n;
621                 if (n) {
622                         i++;
623                         l--;
624                         while (l && n) {
625                                 l--;
626                                 n--;
627                                 *udh++ = *i++;
628                         }
629                 }
630         }
631         while (l--) {
632                 int v = *i++;
633                 if (l--)
634                         v = (v << 8) + *i++;
635                 *o++ = v;
636         }
637         *udl = (o - ud);
638 }
639
640 /*! \brief general unpack - starts with length byte (octet or septet) and returns number of bytes used, inc length */
641 static int unpacksms (unsigned char dcs, unsigned char *i, unsigned char *udh, int *udhl, unsigned short *ud, int *udl, char udhi)
642 {
643         int l = *i++;
644         if (is7bit (dcs)) {
645                 unpacksms7 (i, l, udh, udhl, ud, udl, udhi);
646                 l = (l * 7 + 7) / 8;            /* adjust length to return */
647         } else if (is8bit (dcs))
648                 unpacksms8 (i, l, udh, udhl, ud, udl, udhi);
649         else
650                 unpacksms16 (i, l, udh, udhl, ud, udl, udhi);
651         return l + 1;
652 }
653
654 /*! \brief unpack an address from i, return byte length, unpack to o */
655 static unsigned char unpackaddress (char *o, unsigned char *i)
656 {
657         unsigned char l = i[0],
658                 p;
659         if (i[1] == 0x91)
660                 *o++ = '+';
661         for (p = 0; p < l; p++) {
662                 if (p & 1)
663                         *o++ = (i[2 + p / 2] >> 4) + '0';
664                 else
665                         *o++ = (i[2 + p / 2] & 0xF) + '0';
666         }
667         *o = 0;
668         return (l + 5) / 2;
669 }
670
671 /*! \brief store an address at o, and return number of bytes used */
672 static unsigned char packaddress (unsigned char *o, char *i)
673 {
674         unsigned char p = 2;
675         o[0] = 0;
676         if (*i == '+') {
677                 i++;
678                 o[1] = 0x91;
679         } else
680                 o[1] = 0x81;
681         while (*i)
682                 if (isdigit (*i)) {
683                         if (o[0] & 1)
684                                 o[p++] |= ((*i & 0xF) << 4);
685                         else
686                                 o[p] = (*i & 0xF);
687                         o[0]++;
688                         i++;
689                 } else
690                         i++;
691         if (o[0] & 1)
692                 o[p++] |= 0xF0;                   /* pad */
693         return p;
694 }
695
696 /*! \brief Log the output, and remove file */
697 static void sms_log (sms_t * h, char status)
698 {
699         if (*h->oa || *h->da) {
700                 int o = open (log_file, O_CREAT | O_APPEND | O_WRONLY, AST_FILE_MODE);
701                 if (o >= 0) {
702                         char line[1000], mrs[3] = "", *p;
703                         unsigned char n;
704
705                         if (h->mr >= 0)
706                                 snprintf (mrs, sizeof (mrs), "%02X", h->mr);
707                         snprintf (line, sizeof (line), "%s %c%c%c%s %s %s %s ",
708                                  isodate (time (0)), status, h->rx ? 'I' : 'O', h->smsc ? 'S' : 'M', mrs, h->queue, *h->oa ? h->oa : "-",
709                                  *h->da ? h->da : "-");
710                         p = line + strlen (line);
711                         for (n = 0; n < h->udl; n++)
712                                 if (h->ud[n] == '\\') {
713                                         *p++ = '\\';
714                                         *p++ = '\\';
715                                 } else if (h->ud[n] == '\n') {
716                                         *p++ = '\\';
717                                         *p++ = 'n';
718                                 } else if (h->ud[n] == '\r') {
719                                         *p++ = '\\';
720                                         *p++ = 'r';
721                                 } else if (h->ud[n] < 32 || h->ud[n] == 127)
722                                         *p++ = 191;
723                                 else
724                                         *p++ = h->ud[n];
725                         *p++ = '\n';
726                         *p = 0;
727                         write (o, line, strlen (line));
728                         close (o);
729                 }
730                 *h->oa = *h->da = h->udl = 0;
731         }
732 }
733
734 /*! \brief parse and delete a file */
735 static void sms_readfile (sms_t * h, char *fn)
736 {
737         char line[1000];
738         FILE *s;
739         char dcsset = 0;                /* if DSC set */
740         ast_log (LOG_EVENT, "Sending %s\n", fn);
741         h->rx = h->udl = *h->oa = *h->da = h->pid = h->srr = h->udhi = h->rp = h->vp = h->udhl = 0;
742         h->mr = -1;
743         h->dcs = 0xF1;                  /* normal messages class 1 */
744         h->scts = time (0);
745         s = fopen (fn, "r");
746         if (s) {
747                 if (unlink (fn)) {      /* concurrent access, we lost */
748                         fclose (s);
749                         return;
750                 }
751                 while (fgets (line, sizeof (line), s)) {        /* process line in file */
752                         char *p;
753                         void *pp = &p;
754                         for (p = line; *p && *p != '\n' && *p != '\r'; p++);
755                         *p = 0;                                  /* strip eoln */
756                         p = line;
757                         if (!*p || *p == ';')
758                                 continue;                         /* blank line or comment, ignore */
759                         while (isalnum (*p)) {
760                                 *p = tolower (*p);
761                                 p++;
762                         }
763                         while (isspace (*p))
764                                 *p++ = 0;
765                         if (*p == '=') {
766                                 *p++ = 0;
767                                 if (!strcmp (line, "ud")) {      /* parse message (UTF-8) */
768                                         unsigned char o = 0;
769                                         memcpy(h->udtxt,p,SMSLEN);      /* for protocol 2 */
770                                         while (*p && o < SMSLEN)
771                                                 h->ud[o++] = utf8decode(pp);
772                                         h->udl = o;
773                                         if (*p)
774                                                 ast_log (LOG_WARNING, "UD too long in %s\n", fn);
775                                 } else {
776                                         while (isspace (*p))
777                                                 p++;
778                                         if (!strcmp (line, "oa") && strlen (p) < sizeof (h->oa))
779                                                 numcpy (h->oa, p);
780                                         else if (!strcmp (line, "da") && strlen (p) < sizeof (h->oa))
781                                                 numcpy (h->da, p);
782                                         else if (!strcmp (line, "pid"))
783                                                 h->pid = atoi (p);
784                                         else if (!strcmp (line, "dcs")) {
785                                                 h->dcs = atoi (p);
786                                                 dcsset = 1;
787                                         } else if (!strcmp (line, "mr"))
788                                                 h->mr = atoi (p);
789                                         else if (!strcmp (line, "srr"))
790                                                 h->srr = (atoi (p) ? 1 : 0);
791                                         else if (!strcmp (line, "vp"))
792                                                 h->vp = atoi (p);
793                                         else if (!strcmp (line, "rp"))
794                                                 h->rp = (atoi (p) ? 1 : 0);
795                                         else if (!strcmp (line, "scts")) {      /* get date/time */
796                                                 int Y,
797                                                   m,
798                                                   d,
799                                                   H,
800                                                   M,
801                                                   S;
802                                                 if (sscanf (p, "%d-%d-%dT%d:%d:%d", &Y, &m, &d, &H, &M, &S) == 6) {
803                                                         struct tm t;
804                                                         t.tm_year = Y - 1900;
805                                                         t.tm_mon = m - 1;
806                                                         t.tm_mday = d;
807                                                         t.tm_hour = H;
808                                                         t.tm_min = M;
809                                                         t.tm_sec = S;
810                                                         t.tm_isdst = -1;
811                                                         h->scts = mktime (&t);
812                                                         if (h->scts == (time_t) - 1)
813                                                                 ast_log (LOG_WARNING, "Bad date/timein %s: %s", fn, p);
814                                                 }
815                                         } else
816                                                 ast_log (LOG_WARNING, "Cannot parse in %s: %s=%si\n", fn, line, p);
817                                 }
818                         } else if (*p == '#') {         /* raw hex format */
819                                 *p++ = 0;
820                                 if (*p == '#') {
821                                         p++;
822                                         if (!strcmp (line, "ud")) {     /* user data */
823                                                 int o = 0;
824                                                 while (*p && o < SMSLEN) {
825                                                         if (isxdigit (*p) && isxdigit (p[1]) && isxdigit (p[2]) && isxdigit (p[3])) {
826                                                                 h->ud[o++] =
827                                                                         (((isalpha (*p) ? 9 : 0) + (*p & 0xF)) << 12) +
828                                                                         (((isalpha (p[1]) ? 9 : 0) + (p[1] & 0xF)) << 8) +
829                                                                         (((isalpha (p[2]) ? 9 : 0) + (p[2] & 0xF)) << 4) + ((isalpha (p[3]) ? 9 : 0) + (p[3] & 0xF));
830                                                                 p += 4;
831                                                         } else
832                                                                 break;
833                                                 }
834                                                 h->udl = o;
835                                                 if (*p)
836                                                         ast_log (LOG_WARNING, "UD too long / invalid UCS-2 hex in %s\n", fn);
837                                         } else
838                                                 ast_log (LOG_WARNING, "Only ud can use ## format, %s\n", fn);
839                                 } else if (!strcmp (line, "ud")) {      /* user data */
840                                         int o = 0;
841                                         while (*p && o < SMSLEN) {
842                                                 if (isxdigit (*p) && isxdigit (p[1])) {
843                                                         h->ud[o++] = (((isalpha (*p) ? 9 : 0) + (*p & 0xF)) << 4) + ((isalpha (p[1]) ? 9 : 0) + (p[1] & 0xF));
844                                                         p += 2;
845                                                 } else
846                                                         break;
847                                         }
848                                         h->udl = o;
849                                         if (*p)
850                                                 ast_log (LOG_WARNING, "UD too long / invalid UCS-1 hex in %s\n", fn);
851                                 } else if (!strcmp (line, "udh")) {     /* user data header */
852                                         unsigned char o = 0;
853                                         h->udhi = 1;
854                                         while (*p && o < SMSLEN) {
855                                                 if (isxdigit (*p) && isxdigit (p[1])) {
856                                                         h->udh[o] = (((isalpha (*p) ? 9 : 0) + (*p & 0xF)) << 4) + ((isalpha (p[1]) ? 9 : 0) + (p[1] & 0xF));
857                                                         o++;
858                                                         p += 2;
859                                                 } else
860                                                         break;
861                                         }
862                                         h->udhl = o;
863                                         if (*p)
864                                                 ast_log (LOG_WARNING, "UDH too long / invalid hex in %s\n", fn);
865                                 } else
866                                         ast_log (LOG_WARNING, "Only ud and udh can use # format, %s\n", fn);
867                         } else
868                                 ast_log (LOG_WARNING, "Cannot parse in %s: %s\n", fn, line);
869                 }
870                 fclose (s);
871                 if (!dcsset && packsms7 (0, h->udhl, h->udh, h->udl, h->ud) < 0) {
872                         if (packsms8 (0, h->udhl, h->udh, h->udl, h->ud) < 0) {
873                                 if (packsms16 (0, h->udhl, h->udh, h->udl, h->ud) < 0)
874                                         ast_log (LOG_WARNING, "Invalid UTF-8 message even for UCS-2 (%s)\n", fn);
875                                 else {
876                                         h->dcs = 0x08;  /* default to 16 bit */
877                                         ast_log (LOG_WARNING, "Sending in 16 bit format (%s)\n", fn);
878                                 }
879                         } else {
880                                 h->dcs = 0xF5;          /* default to 8 bit */
881                                 ast_log (LOG_WARNING, "Sending in 8 bit format (%s)\n", fn);
882                         }
883                 }
884                 if (is7bit (h->dcs) && packsms7 (0, h->udhl, h->udh, h->udl, h->ud) < 0)
885                         ast_log (LOG_WARNING, "Invalid 7 bit GSM data %s\n", fn);
886                 if (is8bit (h->dcs) && packsms8 (0, h->udhl, h->udh, h->udl, h->ud) < 0)
887                         ast_log (LOG_WARNING, "Invalid 8 bit data %s\n", fn);
888                 if (is16bit (h->dcs) && packsms16 (0, h->udhl, h->udh, h->udl, h->ud) < 0)
889                         ast_log (LOG_WARNING, "Invalid 16 bit data %s\n", fn);
890         }
891 }
892
893 /*! \brief white a received text message to a file */
894 static void sms_writefile (sms_t * h)
895 {
896         char fn[200] = "", fn2[200] = "";
897         FILE *o;
898         ast_copy_string (fn, spool_dir, sizeof (fn));
899         mkdir (fn, 0777);                       /* ensure it exists */
900         snprintf (fn + strlen (fn), sizeof (fn) - strlen (fn), "/%s", h->smsc ? h->rx ? "morx" : "mttx" : h->rx ? "mtrx" : "motx");
901         mkdir (fn, 0777);                       /* ensure it exists */
902         ast_copy_string (fn2, fn, sizeof (fn2));
903         snprintf (fn2 + strlen (fn2), sizeof (fn2) - strlen (fn2), "/%s.%s-%d", h->queue, isodate (h->scts), seq++);
904         snprintf (fn + strlen (fn), sizeof (fn) - strlen (fn), "/.%s", fn2 + strlen (fn) + 1);
905         o = fopen (fn, "w");
906         if (o) {
907                 if (*h->oa)
908                         fprintf (o, "oa=%s\n", h->oa);
909                 if (*h->da)
910                         fprintf (o, "da=%s\n", h->da);
911                 if (h->udhi) {
912                         unsigned int p;
913                         fprintf (o, "udh#");
914                         for (p = 0; p < h->udhl; p++)
915                                 fprintf (o, "%02X", h->udh[p]);
916                         fprintf (o, "\n");
917                 }
918                 if (h->udl) {
919                         unsigned int p;
920                         for (p = 0; p < h->udl && h->ud[p] >= ' '; p++);
921                         if (p < h->udl)
922                                 fputc (';', o);   /* cannot use ud=, but include as a comment for human readable */
923                         fprintf (o, "ud=");
924                         for (p = 0; p < h->udl; p++) {
925                                 unsigned short v = h->ud[p];
926                                 if (v < 32)
927                                         fputc (191, o);
928                                 else if (v < 0x80)
929                                         fputc (v, o);
930                                 else if (v < 0x800)
931                                 {
932                                         fputc (0xC0 + (v >> 6), o);
933                                         fputc (0x80 + (v & 0x3F), o);
934                                 } else
935                                 {
936                                         fputc (0xE0 + (v >> 12), o);
937                                         fputc (0x80 + ((v >> 6) & 0x3F), o);
938                                         fputc (0x80 + (v & 0x3F), o);
939                                 }
940                         }
941                         fprintf (o, "\n");
942                         for (p = 0; p < h->udl && h->ud[p] >= ' '; p++);
943                         if (p < h->udl) {
944                                 for (p = 0; p < h->udl && h->ud[p] < 0x100; p++);
945                                 if (p == h->udl) {                                               /* can write in ucs-1 hex */
946                                         fprintf (o, "ud#");
947                                         for (p = 0; p < h->udl; p++)
948                                                 fprintf (o, "%02X", h->ud[p]);
949                                         fprintf (o, "\n");
950                                 } else {                                                 /* write in UCS-2 */
951                                         fprintf (o, "ud##");
952                                         for (p = 0; p < h->udl; p++)
953                                                 fprintf (o, "%04X", h->ud[p]);
954                                         fprintf (o, "\n");
955                                 }
956                         }
957                 }
958                 if (h->scts)
959                         fprintf (o, "scts=%s\n", isodate (h->scts));
960                 if (h->pid)
961                         fprintf (o, "pid=%d\n", h->pid);
962                 if (h->dcs != 0xF1)
963                         fprintf (o, "dcs=%d\n", h->dcs);
964                 if (h->vp)
965                         fprintf (o, "vp=%d\n", h->vp);
966                 if (h->srr)
967                         fprintf (o, "srr=1\n");
968                 if (h->mr >= 0)
969                         fprintf (o, "mr=%d\n", h->mr);
970                 if (h->rp)
971                         fprintf (o, "rp=1\n");
972                 fclose (o);
973                 if (rename (fn, fn2))
974                         unlink (fn);
975                 else
976                         ast_log (LOG_EVENT, "Received to %s\n", fn2);
977         }
978 }
979
980 /*! \brief read dir skipping dot files... */
981 static struct dirent *readdirqueue (DIR * d, char *queue)
982 {
983    struct dirent *f;
984    do {
985       f = readdir (d);
986    } while (f && (*f->d_name == '.' || strncmp (f->d_name, queue, strlen (queue)) || f->d_name[strlen (queue)] != '.'));
987    return f;
988 }
989
990 /*! \brief handle the incoming message */
991 static unsigned char sms_handleincoming (sms_t * h)
992 {
993         unsigned char p = 3;
994         if (h->smsc) {                                                                   /* SMSC */
995                 if ((h->imsg[2] & 3) == 1) {                            /* SMS-SUBMIT */
996                         h->udhl = h->udl = 0;
997                         h->vp = 0;
998                         h->srr = ((h->imsg[2] & 0x20) ? 1 : 0);
999                         h->udhi = ((h->imsg[2] & 0x40) ? 1 : 0);
1000                         h->rp = ((h->imsg[2] & 0x80) ? 1 : 0);
1001                         ast_copy_string (h->oa, h->cli, sizeof (h->oa));
1002                         h->scts = time (0);
1003                         h->mr = h->imsg[p++];
1004                         p += unpackaddress (h->da, h->imsg + p);
1005                         h->pid = h->imsg[p++];
1006                         h->dcs = h->imsg[p++];
1007                         if ((h->imsg[2] & 0x18) == 0x10) {                                                       /* relative VP */
1008                                 if (h->imsg[p] < 144)
1009                                         h->vp = (h->imsg[p] + 1) * 5;
1010                                 else if (h->imsg[p] < 168)
1011                                         h->vp = 720 + (h->imsg[p] - 143) * 30;
1012                                 else if (h->imsg[p] < 197)
1013                                         h->vp = (h->imsg[p] - 166) * 1440;
1014                                 else
1015                                         h->vp = (h->imsg[p] - 192) * 10080;
1016                                 p++;
1017                         } else if (h->imsg[2] & 0x18)
1018                                 p += 7;                          /* ignore enhanced / absolute VP */
1019                         p += unpacksms (h->dcs, h->imsg + p, h->udh, &h->udhl, h->ud, &h->udl, h->udhi);
1020                         h->rx = 1;                               /* received message */
1021                         sms_writefile (h);        /* write the file */
1022                         if (p != h->imsg[1] + 2) {
1023                                 ast_log (LOG_WARNING, "Mismatch receive unpacking %d/%d\n", p, h->imsg[1] + 2);
1024                                 return 0xFF;              /* duh! */
1025                         }
1026                 } else {
1027                         ast_log (LOG_WARNING, "Unknown message type %02X\n", h->imsg[2]);
1028                         return 0xFF;
1029                 }
1030         } else {                                                                         /* client */
1031                 if (!(h->imsg[2] & 3)) {                                                                 /* SMS-DELIVER */
1032                         *h->da = h->srr = h->rp = h->vp = h->udhi = h->udhl = h->udl = 0;
1033                         h->srr = ((h->imsg[2] & 0x20) ? 1 : 0);
1034                         h->udhi = ((h->imsg[2] & 0x40) ? 1 : 0);
1035                         h->rp = ((h->imsg[2] & 0x80) ? 1 : 0);
1036                         h->mr = -1;
1037                         p += unpackaddress (h->oa, h->imsg + p);
1038                         h->pid = h->imsg[p++];
1039                         h->dcs = h->imsg[p++];
1040                         h->scts = unpackdate (h->imsg + p);
1041                         p += 7;
1042                         p += unpacksms (h->dcs, h->imsg + p, h->udh, &h->udhl, h->ud, &h->udl, h->udhi);
1043                         h->rx = 1;                               /* received message */
1044                         sms_writefile (h);        /* write the file */
1045                         if (p != h->imsg[1] + 2) {
1046                                 ast_log (LOG_WARNING, "Mismatch receive unpacking %d/%d\n", p, h->imsg[1] + 2);
1047                                 return 0xFF;              /* duh! */
1048                         }
1049                 } else {
1050                         ast_log (LOG_WARNING, "Unknown message type %02X\n", h->imsg[2]);
1051                         return 0xFF;
1052                 }
1053         }
1054         return 0;                                                 /* no error */
1055 }
1056
1057 #ifdef SOLARIS
1058 #define NAME_MAX 1024
1059 #endif
1060
1061 /*!
1062  * Add data to a protocol 2 message.
1063  * Use the length field (h->omsg[1]) as a pointer to the next free position.
1064  */
1065 static void adddata_proto2 (sms_t *h, unsigned char msg, char *data, int size)
1066 {
1067         int x = h->omsg[1]+2;   /* Get current position */
1068         if (x==2)
1069                 x += 2;         /* First: skip Payload length (set later) */
1070         h->omsg[x++] = msg;     /* Message code */
1071         h->omsg[x++]=(unsigned char)size;       /* Data size Low */
1072         h->omsg[x++]=0;         /* Data size Hi */
1073         for (; size>0 ; size--)
1074                 h->omsg[x++] = *data++;
1075         h->omsg[1] = x-2;       /* Frame size */
1076         h->omsg[2] = x-4;       /* Payload length (Lo) */
1077         h->omsg[3] = 0;         /* Payload length (Hi) */
1078 }
1079
1080 static void putdummydata_proto2 (sms_t *h)
1081 {
1082         adddata_proto2 (h, 0x10, "\0", 1);              /* Media Identifier > SMS */
1083         adddata_proto2 (h, 0x11, "\0\0\0\0\0\0", 6);    /* Firmware version */
1084         adddata_proto2 (h, 0x12, "\2\0\4", 3);          /* SMS provider ID */
1085         adddata_proto2 (h, 0x13, h->udtxt, h->udl);     /* Body */
1086 }
1087
1088 static void sms_compose2(sms_t *h, int more)
1089 {
1090         struct tm *tm;
1091         char stm[9];
1092
1093         h->omsg[0] = 0x00;       /* set later... */
1094         h->omsg[1] = 0;
1095         putdummydata_proto2 (h);
1096         if (h->smsc) {                  /* deliver */
1097                 h->omsg[0] = 0x11;      /* SMS_DELIVERY */
1098                 // Required: 10 11 12 13 14 15 17 (seems they must be ordered!)
1099                 tm=localtime(&h->scts);
1100                 sprintf (stm, "%02d%02d%02d%02d", tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min);     // Date mmddHHMM
1101                 adddata_proto2 (h, 0x14, stm, 8);               /* Date */
1102                 if(*h->oa==0)
1103                         strcpy(h->oa,"00000000");
1104                 adddata_proto2 (h, 0x15, h->oa, strlen(h->oa)); /* Originator */
1105                 adddata_proto2 (h, 0x17, "\1", 1);              /* Calling Terminal ID */
1106         } else {                        /* submit */
1107                 h->omsg[0] = 0x10;      /* SMS_SUBMIT */
1108                 // Required: 10 11 12 13 17 18 1B 1C (seems they must be ordered!)
1109                 adddata_proto2 (h, 0x17, "\1", 1);              /* Calling Terminal ID */
1110                 if(*h->da==0)
1111                         strcpy(h->da,"00000000");
1112                 adddata_proto2 (h, 0x18, h->da, strlen(h->da)); /* Originator */
1113                 adddata_proto2 (h, 0x1B, "\1", 1);              /* Called Terminal ID */
1114                 adddata_proto2 (h, 0x1C, "\0\0\0", 3);          /* Notification */
1115         }
1116 }
1117
1118 static void putdummydata_proto2 (sms_t *h);
1119
1120 #if 1 /* XXX debugging */
1121 static char *sms_hexdump (unsigned char buf[], int size)
1122 {
1123         static char *s=NULL;
1124         char *p;
1125         int f;
1126
1127         s=(char *)realloc(s,(size*3)+1);
1128         for(p=s,f=0; f<size && f<800/3; f++,p+=3) 
1129                 sprintf(p,"%02X ",(unsigned char)buf[f]);
1130         return(s);
1131 }
1132 #endif
1133
1134 /*! \brief sms_handleincoming_proto2: handle the incoming message */
1135 static int sms_handleincoming_proto2 (sms_t * h)
1136 {
1137         int f, i, sz=0;
1138         int msg, msgsz;
1139         struct tm *tm;
1140
1141         sz = h->imsg[1]+2;
1142         /* ast_verbose (VERBOSE_PREFIX_3 "SMS-P2 Frame: %s\n", sms_hexdump(h->imsg,sz)); */
1143
1144         /* Parse message body (called payload) */
1145         h->scts = time (0);
1146         for(f=4; f<sz; ) {
1147                 msg=h->imsg[f++];
1148                 msgsz=h->imsg[f++];
1149                 msgsz+=(h->imsg[f++]*256);
1150                 switch(msg) {
1151                 case 0x13:      /* Body */
1152                         if (option_verbose > 2)
1153                                 ast_verbose (VERBOSE_PREFIX_3 "SMS-P2 Body#%02X=[%.*s]\n",msg,msgsz,&h->imsg[f]);
1154                         if (msgsz >= sizeof(h->imsg))
1155                                 msgsz = sizeof(h->imsg)-1;
1156                         for (i=0; i<msgsz; i++)
1157                                 h->ud[i]=h->imsg[f+i];
1158                         h->udl = msgsz;
1159                         break;
1160                 case 0x14:      /* Date SCTS */
1161                         h->scts = time (0);
1162                         tm = localtime (&h->scts);
1163                         tm->tm_mon = ( (h->imsg[f]*10) + h->imsg[f+1] ) - 1;
1164                         tm->tm_mday = ( (h->imsg[f+2]*10) + h->imsg[f+3] );
1165                         tm->tm_hour = ( (h->imsg[f+4]*10) + h->imsg[f+5] );
1166                         tm->tm_min = ( (h->imsg[f+6]*10) + h->imsg[f+7] );
1167                         tm->tm_sec = 0;
1168                         h->scts = mktime (tm);
1169                         if (option_verbose > 2)
1170                                 ast_verbose (VERBOSE_PREFIX_3 "SMS-P2 Date#%02X=%02d/%02d %02d:%02d\n", msg, tm->tm_mday, tm->tm_mon+1, tm->tm_hour, tm->tm_min);
1171                         break;
1172                 case 0x15:      /* Calling line (from SMSC) */
1173                         if (msgsz>=20)
1174                                 msgsz=20-1;
1175                         if (option_verbose > 2)
1176                                 ast_verbose (VERBOSE_PREFIX_3 "SMS-P2 Origin#%02X=[%.*s]\n",msg,msgsz,&h->imsg[f]);
1177                         ast_copy_string (h->oa, (char*)(&h->imsg[f]), msgsz+1);
1178                         break;
1179                 case 0x18:      /* Destination (from TE/phone) */
1180                         if (msgsz>=20)
1181                                 msgsz=20-1;
1182                         if (option_verbose > 2)
1183                                 ast_verbose (VERBOSE_PREFIX_3 "SMS-P2 Destination#%02X=[%.*s]\n",msg,msgsz,&h->imsg[f]);
1184                         ast_copy_string (h->da, (char*)(&h->imsg[f]), msgsz+1);
1185                         break;
1186                 case 0x1C:      /* Notify */
1187                         if (option_verbose > 2)
1188                                 ast_verbose (VERBOSE_PREFIX_3 "SMS-P2 Notify#%02X=%s\n",msg,sms_hexdump(&h->imsg[f],3));
1189                         break;
1190                 default:
1191                         if (option_verbose > 2)
1192                                 ast_verbose (VERBOSE_PREFIX_3 "SMS-P2 Par#%02X [%d]: %s\n",msg,msgsz,sms_hexdump(&h->imsg[f],msgsz));
1193                         break;
1194                 }
1195                 f+=msgsz;       /* Skip to next */
1196         }
1197         h->rx = 1;              /* received message */
1198         sms_writefile (h);      /* write the file */
1199         return 0;               /* no error */
1200 }
1201
1202 #if 0
1203 static void smssend(sms_t *h, char *c)
1204 {
1205         int f, x;
1206         for(f=0; f<strlen(c); f++) {
1207                 sscanf(&c[f*3],"%x",&x);
1208                 h->omsg[f] = x;
1209         }
1210         sms_messagetx (h);
1211 }
1212 #endif
1213
1214 static void sms_nextoutgoing (sms_t *h);
1215
1216 static void sms_messagerx2(sms_t * h)
1217 {
1218         int p = h->imsg[0] & DLL_SMS_MASK ; /* mask the high bit */
1219         int cause;
1220
1221 #define DLL2_ACK(h) ((h->framenumber & 1) ? DLL2_SMS_ACK1: DLL2_SMS_ACK1)
1222         switch (p) {
1223         case DLL2_SMS_EST:      /* Protocol 2: Connection ready (fake): send message  */
1224                 sms_nextoutgoing (h);
1225                 //smssend(h,"11 29 27 00 10 01 00 00 11 06 00 00 00 00 00 00 00 12 03 00 02 00 04 13 01 00 41 14 08 00 30 39 31 35 30 02 30 02 15 02 00 39 30 ");
1226                 break;
1227
1228         case DLL2_SMS_INFO_MO:  /* transport SMS_SUBMIT */
1229         case DLL2_SMS_INFO_MT:  /* transport SMS_DELIVERY */
1230                 cause = sms_handleincoming_proto2(h);
1231                 if (!cause)     /* ACK */
1232                         sms_log (h, 'Y');
1233                 h->omsg[0] = DLL2_ACK(h);
1234                 h->omsg[1] = 0x06;  /* msg len */
1235                 h->omsg[2] = 0x04;  /* payload len */
1236                 h->omsg[3] = 0x00;  /* payload len */
1237                 h->omsg[4] = 0x1f;  /* Response type */
1238                 h->omsg[5] = 0x01;  /* parameter len */
1239                 h->omsg[6] = 0x00;  /* parameter len */
1240                 h->omsg[7] = cause;  /* CONFIRM or error */
1241                 sms_messagetx (h);
1242                 break;
1243
1244         case DLL2_SMS_NACK:     /* Protocol 2: SMS_NAK */
1245                 h->omsg[0] = DLL2_SMS_REL;  /* SMS_REL */
1246                 h->omsg[1] = 0x00;  /* msg len */
1247                 sms_messagetx (h);
1248                 break;
1249
1250         case DLL2_SMS_ACK0:
1251         case DLL2_SMS_ACK1:
1252                 /* SMS_ACK also transport SMS_SUBMIT or SMS_DELIVERY */
1253                 if( (h->omsg[0] & DLL_SMS_MASK) == DLL2_SMS_REL) {
1254                         /* a response to our Release, just hangup */
1255                         h->hangup = 1;          /* hangup */
1256                 } else {
1257                         /* XXX depending on what we are.. */
1258                         ast_log(LOG_NOTICE, "SMS_SUBMIT or SMS_DELIVERY");
1259                         sms_nextoutgoing (h);
1260                 }
1261                 break;
1262
1263         case DLL2_SMS_REL:      /* Protocol 2: SMS_REL (hangup req) */
1264                 h->omsg[0] = DLL2_ACK(h);
1265                 h->omsg[1] = 0;
1266                 sms_messagetx (h);
1267                 break;
1268         }
1269 }
1270
1271 /*! \brief compose a message for protocol 1 */
1272 static void sms_compose1(sms_t *h, int more)
1273 {
1274         unsigned int p = 2;     /* next byte to write. Skip type and len */
1275
1276         h->omsg[0] = 0x91;                /* SMS_DATA */
1277         if (h->smsc) {                   /* deliver */
1278                 h->omsg[p++] = (more ? 4 : 0) + ((h->udhl > 0) ? 0x40 : 0);
1279                 p += packaddress (h->omsg + p, h->oa);
1280                 h->omsg[p++] = h->pid;
1281                 h->omsg[p++] = h->dcs;
1282                 packdate (h->omsg + p, h->scts);
1283                 p += 7;
1284                 p += packsms (h->dcs, h->omsg + p, h->udhl, h->udh, h->udl, h->ud);
1285         } else {                         /* submit */
1286                 h->omsg[p++] =
1287                         0x01 + (more ? 4 : 0) + (h->srr ? 0x20 : 0) + (h->rp ? 0x80 : 0) + (h->vp ? 0x10 : 0) + (h->udhi ? 0x40 : 0);
1288                 if (h->mr < 0)
1289                         h->mr = message_ref++;
1290                 h->omsg[p++] = h->mr;
1291                 p += packaddress (h->omsg + p, h->da);
1292                 h->omsg[p++] = h->pid;
1293                 h->omsg[p++] = h->dcs;
1294                 if (h->vp) {             /* relative VP */
1295                         if (h->vp < 720)
1296                                 h->omsg[p++] = (h->vp + 4) / 5 - 1;
1297                         else if (h->vp < 1440)
1298                                 h->omsg[p++] = (h->vp - 720 + 29) / 30 + 143;
1299                         else if (h->vp < 43200)
1300                                 h->omsg[p++] = (h->vp + 1439) / 1440 + 166;
1301                         else if (h->vp < 635040)
1302                                 h->omsg[p++] = (h->vp + 10079) / 10080 + 192;
1303                         else
1304                                 h->omsg[p++] = 255;             /* max */
1305                 }
1306                 p += packsms (h->dcs, h->omsg + p, h->udhl, h->udh, h->udl, h->ud);
1307         }
1308         h->omsg[1] = p - 2;
1309 }
1310
1311 /*! \brief find and fill in next message, or send a REL if none waiting */
1312 static void sms_nextoutgoing (sms_t * h)
1313 {          
1314         char fn[100 + NAME_MAX] = "";
1315         DIR *d;
1316         char more = 0;
1317
1318         *h->da = *h->oa = '\0';                 /* clear destinations */
1319         ast_copy_string (fn, spool_dir, sizeof (fn));
1320         mkdir(fn, 0777);                        /* ensure it exists */
1321         h->rx = 0;                              /* outgoing message */
1322         snprintf (fn + strlen (fn), sizeof (fn) - strlen (fn), "/%s", h->smsc ? "mttx" : "motx");
1323         mkdir (fn, 0777);                       /* ensure it exists */
1324         d = opendir (fn);
1325         if (d) {
1326                 struct dirent *f = readdirqueue (d, h->queue);
1327                 if (f) {
1328                         snprintf (fn + strlen (fn), sizeof (fn) - strlen (fn), "/%s", f->d_name);
1329                         sms_readfile (h, fn);
1330                         if (readdirqueue (d, h->queue))
1331                                 more = 1;                         /* more to send */
1332                 }
1333                 closedir (d);
1334         }
1335         if (*h->da || *h->oa) {                                                                  /* message to send */
1336                 if (h->protocol==2)
1337                         sms_compose2(h, more);
1338                 else
1339                         sms_compose1(h,more);
1340         } else {                                /* no message */
1341                 if (h->protocol==2) {
1342                         h->omsg[0] = 0x17;      /* SMS_REL */
1343                         h->omsg[1] = 0;
1344                 } else {
1345                         h->omsg[0] = 0x94;      /* SMS_REL */
1346                         h->omsg[1] = 0;
1347                 }
1348         }
1349         sms_messagetx (h);
1350 }
1351
1352 #define DIR_RX 1
1353 #define DIR_TX 2
1354 static void sms_debug (int dir, sms_t *h)
1355 {
1356         char txt[259 * 3 + 1];
1357         char *p = txt;                                           /* always long enough */
1358         unsigned char *msg = (dir == DIR_RX) ? h->imsg : h->omsg;
1359         int n = (dir == DIR_RX) ? h->ibytep : msg[1] + 2;
1360         int q = 0;
1361         while (q < n && q < 30) {
1362                 sprintf (p, " %02X", msg[q++]);
1363                 p += 3;
1364         }
1365         if (q < n)
1366                 sprintf (p, "...");
1367         if (option_verbose > 2)
1368                 ast_verbose (VERBOSE_PREFIX_3 "SMS %s%s\n", dir == DIR_RX ? "RX" : "TX", txt);
1369 }
1370
1371
1372 static void sms_messagerx(sms_t * h)
1373 {
1374         int cause;
1375
1376         sms_debug (DIR_RX, h);
1377         if (h->protocol == 2) {
1378                 sms_messagerx2(h);
1379                 return;
1380         }
1381         /* parse incoming message for Protocol 1 */
1382         switch (h->imsg[0]) {
1383         case 0x91:                                              /* SMS_DATA */
1384                         cause = sms_handleincoming (h);
1385                         if (!cause) {
1386                                 sms_log (h, 'Y');
1387                                 h->omsg[0] = 0x95;  /* SMS_ACK */
1388                                 h->omsg[1] = 0x02;
1389                                 h->omsg[2] = 0x00;  /* deliver report */
1390                                 h->omsg[3] = 0x00;  /* no parameters */
1391                         } else {                                                         /* NACK */
1392                                 sms_log (h, 'N');
1393                                 h->omsg[0] = 0x96;  /* SMS_NACK */
1394                                 h->omsg[1] = 3;
1395                                 h->omsg[2] = 0;   /* delivery report */
1396                                 h->omsg[3] = cause; /* cause */
1397                                 h->omsg[4] = 0;   /* no parameters */
1398                         }
1399                         sms_messagetx (h);
1400                         break;
1401
1402         case 0x92:                                              /* SMS_ERROR */
1403                 h->err = 1;
1404                 sms_messagetx (h);                /* send whatever we sent again */
1405                 break;
1406         case 0x93:                                              /* SMS_EST */
1407                 sms_nextoutgoing (h);
1408                 break;
1409         case 0x94:                                              /* SMS_REL */
1410                 h->hangup = 1;                          /* hangup */
1411                 break;
1412         case 0x95:                                              /* SMS_ACK */
1413                 sms_log (h, 'Y');
1414                 sms_nextoutgoing (h);
1415                 break;
1416         case 0x96:                                              /* SMS_NACK */
1417                 h->err = 1;
1418                 sms_log (h, 'N');
1419                 sms_nextoutgoing (h);
1420                 break;
1421         default:                                                  /* Unknown */
1422                 h->omsg[0] = 0x92;                /* SMS_ERROR */
1423                 h->omsg[1] = 1;
1424                 h->omsg[2] = 3;                   /* unknown message type; */
1425                 sms_messagetx (h);
1426                 break;
1427         }
1428 }
1429
1430 static void sms_messagetx(sms_t * h)
1431 {
1432         unsigned char c = 0, p;
1433         int len = h->omsg[1] + 2;       /* total message length excluding checksum */
1434
1435         for (p = 0; p < len; p++)       /* compute checksum */
1436                 c += h->omsg[p];
1437         h->omsg[len] = 0 - c;           /* actually, (256 - (c & 0fxx)) & 0xff) */
1438         sms_debug(DIR_TX, h);
1439         h->framenumber++;       /* Proto 2 */
1440         h->obyte = 1;           /* send mark ('1') at the beginning */
1441         h->opause = 200;
1442         /* Change the initial message delay. BT requires 300ms,
1443          * but for others this might be way too much and the phone
1444          * could time out. XXX make it configurable.
1445          */
1446         if (h->omsg[0] == 0x93)
1447                 h->opause = 200;        /* XXX initial message delay 300ms (for BT) */
1448         h->obytep = 0;
1449         h->obitp = 0;
1450         if (h->protocol == 2) {
1451                 h->oseizure = 300;      /* Proto 2: 300bits (or more ?) */
1452                 h->obyte = 0;           /* Seizure starts with  space (0) */
1453                 h->opause = 400;
1454         } else {
1455                 h->oseizure = 0;        /* Proto 1: No seizure */
1456         }
1457         /* Note - setting osync triggers the generator */
1458         h->osync = OSYNC_BITS;                  /* 80 sync bits */
1459         h->obyten = len + 1;            /* bytes to send (including checksum) */
1460 }
1461
1462 /*!
1463  * outgoing data are produced by this generator function, that reads from
1464  * the descriptor whether it has data to send and which ones.
1465  */
1466 static int sms_generate (struct ast_channel *chan, void *data, int len, int samples)
1467 {
1468         struct ast_frame f = { 0 };
1469 #define MAXSAMPLES (800)
1470         output_t *buf;
1471         sms_t *h = data;
1472         int i;
1473
1474         if (samples > MAXSAMPLES) {
1475                 ast_log (LOG_WARNING, "Only doing %d samples (%d requested)\n",
1476                          MAXSAMPLES, samples);
1477                 samples = MAXSAMPLES;
1478         }
1479         len = samples * sizeof(*buf) + AST_FRIENDLY_OFFSET;
1480         buf = alloca(len);
1481
1482         f.frametype = AST_FRAME_VOICE;
1483         f.subclass = __OUT_FMT;
1484         f.datalen = samples * sizeof(*buf);
1485         f.offset = AST_FRIENDLY_OFFSET;
1486         f.mallocd = 0;
1487         f.data = buf;
1488         f.samples = samples;
1489         f.src = "app_sms";
1490         /* create a buffer containing the digital sms pattern */
1491         for (i = 0; i < samples; i++) {
1492                 buf[i] = wave_out[0];   /* default is silence */
1493
1494                 if (h->opause)
1495                         h->opause--;
1496                 else if (h->obyten || h->osync) {       /* sending data */
1497                         buf[i] = wave_out[h->ophase];
1498                         h->ophase += (h->obyte & 1) ? 13 : 21;  /* compute next phase */
1499                         if (h->ophase >= 80)
1500                                 h->ophase -= 80;
1501                         if ((h->ophasep += 12) >= 80) {         /* time to send the next bit */
1502                                 h->ophasep -= 80;
1503                                 if (h->oseizure > 0) {           /* sending channel seizure (proto 2) */
1504                                         h->oseizure--;
1505                                         h->obyte ^= 1;  /* toggle low bit */
1506                                 } else if (h->osync) {
1507                                         h->obyte = 1;   /* send mark as sync bit */
1508                                         h->osync--;             /* sending sync bits */
1509                                         if (h->osync == 0 && h->protocol == 2 && h->omsg[0] == DLL2_SMS_EST) {
1510                                                 h->obytep = h->obyten = 0;      /* we are done */
1511                                         }
1512                                 } else {
1513                                         h->obitp++;
1514                                         if (h->obitp == 1)
1515                                                 h->obyte = 0; /* start bit; */
1516                                         else if (h->obitp == 2)
1517                                                 h->obyte = h->omsg[h->obytep];
1518                                         else if (h->obitp == 10) {
1519                                                 h->obyte = 1; /* stop bit */
1520                                                 h->obitp = 0;
1521                                                 h->obytep++;
1522                                                 if (h->obytep == h->obyten) {
1523                                                         h->obytep = h->obyten = 0; /* sent */
1524                                                         h->osync = 10;    /* trailing marks */
1525                                                 }
1526                                         } else
1527                                                 h->obyte >>= 1;
1528                                 }
1529                         }
1530                 }
1531         }
1532         if (ast_write (chan, &f) < 0) {
1533                 ast_log (LOG_WARNING, "Failed to write frame to '%s': %s\n", chan->name, strerror (errno));
1534                 return -1;
1535         }
1536         return 0;
1537 #undef MAXSAMPLES
1538 }
1539
1540 /*!
1541  * Just return the pointer to the descriptor that we received.
1542  */
1543 static void *sms_alloc (struct ast_channel *chan, void *sms_t_ptr)
1544 {
1545         return sms_t_ptr;
1546 }
1547
1548 static void sms_release (struct ast_channel *chan, void *data)
1549 {
1550         return; /* nothing to do here. */
1551 }
1552
1553 static struct ast_generator smsgen = {
1554         .alloc = sms_alloc,
1555         .release = sms_release,
1556         .generate = sms_generate,
1557 };
1558
1559 /*!
1560  * Process an incoming frame, trying to detect the carrier and
1561  * decode the message. The two frequencies are 1300 and 2100 Hz.
1562  * The decoder detects the amplitude of the signal over the last
1563  * few samples, filtering the absolute values with a lowpass filter.
1564  * If the magnitude (h->imag) is large enough, multiply the signal
1565  * by the two carriers, and compute the amplitudes m0 and m1.
1566  * Record the current sample as '0' or '1' depending on which one is greater.
1567  * The last 3 bits are stored in h->ibith, with the count of '1'
1568  * bits in h->ibitt.
1569  * XXX the rest is to be determined.
1570  */
1571 static void sms_process(sms_t * h, int samples, signed short *data)
1572 {
1573         int bit;
1574
1575         /*
1576          * Ignore incoming audio while a packet is being transmitted,
1577          * the protocol is half-duplex.
1578          * Unfortunately this means that if the outbound and incoming
1579          * transmission overlap (which is an error condition anyways),
1580          * we may miss some data and this makes debugging harder.
1581          */
1582         if (h->obyten || h->osync)
1583                 return;
1584         for ( ; samples-- ; data++) {
1585                 unsigned long long m0, m1;
1586                 if (abs (*data) > h->imag)
1587                         h->imag = abs (*data);
1588                 else
1589                         h->imag = h->imag * 7 / 8;
1590                 if (h->imag <= 500) {           /* below [arbitrary] threahold: lost carrier */
1591                         if (h->idle++ == 80000) {                /* nothing happening */
1592                                 ast_log (LOG_NOTICE, "No data, hanging up\n");
1593                                 h->hangup = 1;
1594                                 h->err = 1;
1595                         }
1596                         if (h->ierr) {          /* error */
1597                                 ast_log (LOG_NOTICE, "Error %d, hanging up\n", h->ierr);
1598                                 /* Protocol 1 */
1599                                 h->err = 1;
1600                                 h->omsg[0] = 0x92;  /* error */
1601                                 h->omsg[1] = 1;
1602                                 h->omsg[2] = h->ierr;
1603                                 sms_messagetx (h);  /* send error */
1604                         }
1605                         h->ierr = h->ibitn = h->ibytep = h->ibytec = 0;
1606                         continue;
1607                 }
1608                 h->idle = 0;
1609
1610                 /* multiply signal by the two carriers. */
1611                 h->ims0 = (h->ims0 * 6 + *data * wave[h->ips0]) / 7;
1612                 h->imc0 = (h->imc0 * 6 + *data * wave[h->ipc0]) / 7;
1613                 h->ims1 = (h->ims1 * 6 + *data * wave[h->ips1]) / 7;
1614                 h->imc1 = (h->imc1 * 6 + *data * wave[h->ipc1]) / 7;
1615                 /* compute the amplitudes */
1616                 m0 = h->ims0 * h->ims0 + h->imc0 * h->imc0;
1617                 m1 = h->ims1 * h->ims1 + h->imc1 * h->imc1;
1618
1619                 /* advance the sin/cos pointers */
1620                 if ((h->ips0 += 21) >= 80)
1621                         h->ips0 -= 80;
1622                 if ((h->ipc0 += 21) >= 80)
1623                         h->ipc0 -= 80;
1624                 if ((h->ips1 += 13) >= 80)
1625                         h->ips1 -= 80;
1626                 if ((h->ipc1 += 13) >= 80)
1627                         h->ipc1 -= 80;
1628
1629                 /* set new bit to 1 or 0 depending on which value is stronger */
1630                 h->ibith <<= 1;
1631                 if (m1 > m0)
1632                         h->ibith |= 1;
1633                 if (h->ibith & 8)
1634                         h->ibitt--;
1635                 if (h->ibith & 1)
1636                         h->ibitt++;
1637                 bit = ((h->ibitt > 1) ? 1 : 0);
1638                 if (bit != h->ibitl)
1639                         h->ibitc = 1;
1640                 else
1641                         h->ibitc++;
1642                 h->ibitl = bit;
1643                 if (!h->ibitn && h->ibitc == 4 && !bit) {
1644                         h->ibitn = 1;
1645                         h->iphasep = 0;
1646                 }
1647                 if (bit && h->ibitc == 200) {                                            /* sync, restart message */
1648                         /* Protocol 2: empty connnection ready (I am master) */
1649                         if(h->framenumber<0 && h->ibytec>=160 && !memcmp(h->imsg,"UUUUUUUUUUUUUUUUUUUU",20)) {
1650                                 h->framenumber = 1;
1651                                 if (option_verbose > 2)
1652                                         ast_verbose (VERBOSE_PREFIX_3 "SMS protocol 2 detected\n");
1653                                 h->protocol = 2;
1654                                 h->imsg[0] = 0xff;      /* special message (fake) */
1655                                 h->imsg[1] = h->imsg[2] = 0x00;
1656                                 h->ierr = h->ibitn = h->ibytep = h->ibytec = 0;
1657                                 sms_messagerx (h);
1658                         }
1659                         h->ierr = h->ibitn = h->ibytep = h->ibytec = 0;
1660                 }
1661                 if (h->ibitn) {
1662                         h->iphasep += 12;
1663                         if (h->iphasep >= 80) {                                 /* next bit */
1664                                 h->iphasep -= 80;
1665                                 if (h->ibitn++ == 9) {                          /* end of byte */
1666                                         if (!bit) { /* bad stop bit */
1667                                                 ast_log(LOG_NOTICE, "bad stop bit");
1668                                                 h->ierr = 0xFF; /* unknown error */
1669                                         } else {
1670                                                 if (h->ibytep < sizeof (h->imsg)) {
1671                                                         h->imsg[h->ibytep] = h->ibytev;
1672                                                         h->ibytec += h->ibytev;
1673                                                         h->ibytep++;
1674                                                 } else if (h->ibytep == sizeof (h->imsg)) {
1675                                                         ast_log(LOG_NOTICE, "msg too large");
1676                                                         h->ierr = 2; /* bad message length */
1677                                                 }
1678                                                 if (h->ibytep > 1 && h->ibytep == 3 + h->imsg[1] && !h->ierr) {
1679                                                         if (!h->ibytec)
1680                                                                 sms_messagerx (h);
1681                                                         else {
1682                                                                 ast_log(LOG_NOTICE, "bad checksum");
1683                                                                 h->ierr = 1;            /* bad checksum */
1684                                                         }
1685                                                 }
1686                                         }
1687                                         h->ibitn = 0;
1688                                 }
1689                                 h->ibytev = (h->ibytev >> 1) + (bit ? 0x80 : 0);
1690                         }
1691                 }
1692         }
1693 }
1694
1695 static int sms_exec (struct ast_channel *chan, void *data)
1696 {
1697         int res = -1;
1698         struct ast_module_user *u;
1699         struct ast_frame *f;
1700         sms_t h = { 0 };
1701         unsigned char *p;
1702         unsigned char *d = data;
1703         int answer = 0;
1704         
1705         if (!data) {
1706                 ast_log (LOG_ERROR, "Requires queue name at least\n");
1707                 return -1;
1708         }
1709
1710         u = ast_module_user_add(chan);
1711         h.ipc0 = h.ipc1 = 20;           /* phase for cosine */
1712         h.dcs = 0xF1;                   /* default */
1713
1714         if (chan->cid.cid_num)
1715                 ast_copy_string (h.cli, chan->cid.cid_num, sizeof (h.cli));
1716
1717         if (!*d || *d == '|') {
1718                 ast_log (LOG_ERROR, "Requires queue name\n");
1719                 ast_module_user_remove(u);
1720                 return -1;
1721         }
1722         for (p = d; *p && *p != '|'; p++);
1723         if (p - d >= sizeof (h.queue)) {
1724                 ast_log (LOG_ERROR, "Queue name too long\n");
1725                 ast_module_user_remove(u);
1726                 return -1;
1727         }
1728         strncpy(h.queue, (char *)d, p - d);
1729         if (*p == '|')
1730                 p++;
1731         d = p;
1732         for (p = (unsigned char *)h.queue; *p; p++)
1733                 if (!isalnum (*p))
1734                         *p = '-';                         /* make very safe for filenames */
1735
1736         while (*d && *d != '|') {
1737                 switch (*d) {
1738                 case 'a':                                /* we have to send the initial FSK sequence */
1739                         answer = 1;
1740                         break;
1741                 case 's':                                /* we are acting as a service centre talking to a phone */
1742                         h.smsc = 1;
1743                         break;
1744                 case 't':                                /* use protocol 2 ([t]wo)! couldn't use numbers *!* */
1745                         h.protocol = 2;
1746                         break;
1747                         /* the following apply if there is an arg3/4 and apply to the created message file */
1748                 case 'r':
1749                         h.srr = 1;
1750                         break;
1751                 case 'o':
1752                         h.dcs |= 4;                     /* octets */
1753                         break;
1754                 case '1':
1755                 case '2':
1756                 case '3':
1757                 case '4':
1758                 case '5':
1759                 case '6':
1760                 case '7':                                /* set the pid for saved local message */
1761                         h.pid = 0x40 + (*d & 0xF);
1762                         break;
1763                 }
1764                 d++;
1765         }
1766         if (*d == '|') {
1767                 /* submitting a message, not taking call. */
1768                 /* deprecated, use smsq instead */
1769                 d++;
1770                 h.scts = time (0);
1771                 for (p = d; *p && *p != '|'; p++);
1772                 if (*p)
1773                         *p++ = 0;
1774                 if (strlen ((char *)d) >= sizeof (h.oa)) {
1775                         ast_log (LOG_ERROR, "Address too long %s\n", d);
1776                         return 0;
1777                 }
1778                 if (h.smsc) {
1779                         ast_copy_string (h.oa, (char *)d, sizeof (h.oa));
1780                 } else {
1781                         ast_copy_string (h.da, (char *)d, sizeof (h.da));
1782                 }
1783                 if (!h.smsc)
1784                         ast_copy_string (h.oa, h.cli, sizeof (h.oa));
1785                 d = p;
1786                 h.udl = 0;
1787                 while (*p && h.udl < SMSLEN)
1788                         h.ud[h.udl++] = utf8decode(&p);
1789                 if (is7bit (h.dcs) && packsms7 (0, h.udhl, h.udh, h.udl, h.ud) < 0)
1790                         ast_log (LOG_WARNING, "Invalid 7 bit GSM data\n");
1791                 if (is8bit (h.dcs) && packsms8 (0, h.udhl, h.udh, h.udl, h.ud) < 0)
1792                         ast_log (LOG_WARNING, "Invalid 8 bit data\n");
1793                 if (is16bit (h.dcs) && packsms16 (0, h.udhl, h.udh, h.udl, h.ud) < 0)
1794                         ast_log (LOG_WARNING, "Invalid 16 bit data\n");
1795                 h.rx = 0;                                 /* sent message */
1796                 h.mr = -1;
1797                 sms_writefile (&h);
1798                 ast_module_user_remove(u);
1799                 return 0;
1800         }
1801
1802         if (answer) {
1803                 h.framenumber = 1;             /* Proto 2 */
1804                 /* set up SMS_EST initial message */
1805                 if (h.protocol == 2) {
1806                         h.omsg[0] = DLL2_SMS_EST;
1807                         h.omsg[1] = 0;
1808                 } else {
1809                         h.omsg[0] = DLL1_SMS_EST | DLL1_SMS_COMPLETE;
1810                         h.omsg[1] = 0;
1811                 }
1812                 sms_messagetx (&h);
1813         }
1814
1815         if (chan->_state != AST_STATE_UP)
1816                 ast_answer (chan);
1817
1818         res = ast_set_write_format (chan, __OUT_FMT);
1819         if (res >= 0)
1820                 res = ast_set_read_format (chan, AST_FORMAT_SLINEAR);
1821         if (res < 0) {
1822                 ast_log (LOG_ERROR, "Unable to set to linear mode, giving up\n");
1823                 ast_module_user_remove(u);
1824                 return -1;
1825         }
1826
1827         if (ast_activate_generator (chan, &smsgen, &h) < 0) {
1828                 ast_log (LOG_ERROR, "Failed to activate generator on '%s'\n", chan->name);
1829                 ast_module_user_remove(u);
1830                 return -1;
1831         }
1832
1833         /* Do our thing here */
1834         for (;;) {
1835                 int i = ast_waitfor(chan, -1);
1836                 if (i < 0) {
1837                         ast_log(LOG_NOTICE, "waitfor failed\n");
1838                         break;
1839                 }
1840                 if (h.hangup) {
1841                         ast_log(LOG_NOTICE, "channel hangup\n");
1842                         break;
1843                 }
1844                 f = ast_read (chan);
1845                 if (!f) {
1846                         ast_log(LOG_NOTICE, "ast_read failed\n");
1847                         break;
1848                 }
1849                 if (f->frametype == AST_FRAME_VOICE) {
1850                         sms_process (&h, f->samples, f->data);
1851                 }
1852
1853                 ast_frfree (f);
1854         }
1855
1856         sms_log (&h, '?');                        /* log incomplete message */
1857
1858         ast_module_user_remove(u);
1859         return (h.err);
1860 }
1861
1862 static int unload_module(void)
1863 {
1864         int res;
1865
1866         res = ast_unregister_application (app);
1867         
1868         ast_module_user_hangup_all();
1869
1870         return res;     
1871 }
1872
1873 static int load_module(void)
1874 {
1875 #ifdef OUTALAW
1876         {
1877                 int p;
1878                 for (p = 0; p < 80; p++)
1879                         wavea[p] = AST_LIN2A (wave[p]);
1880         }
1881 #endif
1882         snprintf (log_file, sizeof (log_file), "%s/sms", ast_config_AST_LOG_DIR);
1883         snprintf (spool_dir, sizeof (spool_dir), "%s/sms", ast_config_AST_SPOOL_DIR);
1884         return ast_register_application (app, sms_exec, synopsis, descrip);
1885 }
1886
1887 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "SMS/PSTN handler");