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