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