710ba82c56a39caebe627bdd8acb2f5a8068f97f
[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         int z;
516
517         ast_localtime(&w, &t, NULL);
518 #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined( __NetBSD__ ) || defined(__APPLE__)
519         z = -t.tm_gmtoff / 60 / 15;
520 #else
521         z = timezone / 60 / 15;
522 #endif
523         *o++ = ((t.tm_year % 10) << 4) + (t.tm_year % 100) / 10;
524         *o++ = (((t.tm_mon + 1) % 10) << 4) + (t.tm_mon + 1) / 10;
525         *o++ = ((t.tm_mday % 10) << 4) + t.tm_mday / 10;
526         *o++ = ((t.tm_hour % 10) << 4) + t.tm_hour / 10;
527         *o++ = ((t.tm_min % 10) << 4) + t.tm_min / 10;
528         *o++ = ((t.tm_sec % 10) << 4) + t.tm_sec / 10;
529         if (z < 0)
530                 *o++ = (((-z) % 10) << 4) + (-z) / 10 + 0x08;
531         else
532                 *o++ = ((z % 10) << 4) + z / 10;
533 }
534
535 /*! \brief unpack a date and return */
536 static time_t unpackdate(unsigned char *i)
537 {
538         struct tm t;
539         t.tm_year = 100 + (i[0] & 0xF) * 10 + (i[0] >> 4);
540         t.tm_mon = (i[1] & 0xF) * 10 + (i[1] >> 4) - 1;
541         t.tm_mday = (i[2] & 0xF) * 10 + (i[2] >> 4);
542         t.tm_hour = (i[3] & 0xF) * 10 + (i[3] >> 4);
543         t.tm_min = (i[4] & 0xF) * 10 + (i[4] >> 4);
544         t.tm_sec = (i[5] & 0xF) * 10 + (i[5] >> 4);
545         t.tm_isdst = 0;
546         if (i[6] & 0x08)
547                 t.tm_min += 15 * ((i[6] & 0x7) * 10 + (i[6] >> 4));
548         else
549                 t.tm_min -= 15 * ((i[6] & 0x7) * 10 + (i[6] >> 4));
550         return mktime(&t);
551 }
552
553 /*! \brief unpacks bytes (7 bit encoding) at i, len l septets, 
554         and places in udh and ud setting udhl and udl. udh not used 
555         if udhi not set */
556 static void unpacksms7(unsigned char *i, unsigned char l, unsigned char *udh, int *udhl, unsigned short *ud, int *udl, char udhi)
557 {
558         unsigned char b = 0, p = 0;
559         unsigned short *o = ud;
560         *udhl = 0;
561         if (udhi && l) {                 /* header */
562                 int h = i[p];
563                 *udhl = h;
564                 if (h) {
565                         b = 1;
566                         p++;
567                         l--;
568                         while (h-- && l) {
569                                 *udh++ = i[p++];
570                                 b += 8;
571                                 while (b >= 7) {
572                                         b -= 7;
573                                         l--;
574                                         if (!l)
575                                                 break;
576                                 }
577                         }
578                         /* adjust for fill, septets */
579                         if (b) {
580                                 b = 7 - b;
581                                 l--;
582                         }
583                 }
584         }
585         while (l--) {
586                 unsigned char v;
587                 if (b < 2)
588                         v = ((i[p] >> b) & 0x7F);       /* everything in one byte */
589                 else
590                         v = ((((i[p] >> b) + (i[p + 1] << (8 - b)))) & 0x7F);
591                 b += 7;
592                 if (b >= 8) {
593                         b -= 8;
594                         p++;
595                 }
596                 /* 0x00A0 is the encoding of ESC (27) in defaultalphabet */
597                 if (o > ud && o[-1] == 0x00A0 && escapes[v])
598                         o[-1] = escapes[v];
599                 else
600                         *o++ = defaultalphabet[v];
601         }
602         *udl = (o - ud);
603 }
604
605 /*! \brief unpacks bytes (8 bit encoding) at i, len l septets, 
606       and places in udh and ud setting udhl and udl. udh not used 
607       if udhi not set */
608 static void unpacksms8(unsigned char *i, unsigned char l, unsigned char *udh, int *udhl, unsigned short *ud, int *udl, char udhi)
609 {
610         unsigned short *o = ud;
611         *udhl = 0;
612         if (udhi) {
613                 int n = *i;
614                 *udhl = n;
615                 if (n) {
616                         i++;
617                         l--;
618                         while (l && n) {
619                                 l--;
620                                 n--;
621                                 *udh++ = *i++;
622                         }
623                 }
624         }
625         while (l--)
626                 *o++ = *i++;      /* not to UTF-8 as explicitly 8 bit coding in DCS */
627         *udl = (o - ud);
628 }
629
630 /*! \brief unpacks bytes (16 bit encoding) at i, len l septets,
631          and places in udh and ud setting udhl and udl. 
632         udh not used if udhi not set */
633 static void unpacksms16(unsigned char *i, unsigned char l, unsigned char *udh, int *udhl, unsigned short *ud, int *udl, char udhi)
634 {
635         unsigned short *o = ud;
636         *udhl = 0;
637         if (udhi) {
638                 int n = *i;
639                 *udhl = n;
640                 if (n) {
641                         i++;
642                         l--;
643                         while (l && n) {
644                                 l--;
645                                 n--;
646                                 *udh++ = *i++;
647                         }
648                 }
649         }
650         while (l--) {
651                 int v = *i++;
652                 if (l--)
653                         v = (v << 8) + *i++;
654                 *o++ = v;
655         }
656         *udl = (o - ud);
657 }
658
659 /*! \brief general unpack - starts with length byte (octet or septet) and returns number of bytes used, inc length */
660 static int unpacksms(unsigned char dcs, unsigned char *i, unsigned char *udh, int *udhl, unsigned short *ud, int *udl, char udhi)
661 {
662         int l = *i++;
663         if (is7bit(dcs)) {
664                 unpacksms7(i, l, udh, udhl, ud, udl, udhi);
665                 l = (l * 7 + 7) / 8;            /* adjust length to return */
666         } else if (is8bit(dcs))
667                 unpacksms8(i, l, udh, udhl, ud, udl, udhi);
668         else
669                 unpacksms16(i, l, udh, udhl, ud, udl, udhi);
670         return l + 1;
671 }
672
673 /*! \brief unpack an address from i, return byte length, unpack to o */
674 static unsigned char unpackaddress(char *o, unsigned char *i)
675 {
676         unsigned char l = i[0],
677                 p;
678         if (i[1] == 0x91)
679                 *o++ = '+';
680         for (p = 0; p < l; p++) {
681                 if (p & 1)
682                         *o++ = (i[2 + p / 2] >> 4) + '0';
683                 else
684                         *o++ = (i[2 + p / 2] & 0xF) + '0';
685         }
686         *o = 0;
687         return (l + 5) / 2;
688 }
689
690 /*! \brief store an address at o, and return number of bytes used */
691 static unsigned char packaddress(unsigned char *o, char *i)
692 {
693         unsigned char p = 2;
694         o[0] = 0;               /* number of bytes */
695         if (*i == '+') {        /* record as bit 0 in byte 1 */
696                 i++;
697                 o[1] = 0x91;
698         } else
699                 o[1] = 0x81;
700         for ( ; *i ; i++) {
701                 if (!isdigit(*i))       /* ignore non-digits */
702                         continue;
703                 if (o[0] & 1)
704                         o[p++] |= ((*i & 0xF) << 4);
705                 else
706                         o[p] = (*i & 0xF);
707                 o[0]++;
708         }
709         if (o[0] & 1)
710                 o[p++] |= 0xF0;                   /* pad */
711         return p;
712 }
713
714 /*! \brief Log the output, and remove file */
715 static void sms_log(sms_t * h, char status)
716 {
717         int o;
718
719         if (*h->oa == '\0' && *h->da == '\0')
720                 return;
721         o = open(log_file, O_CREAT | O_APPEND | O_WRONLY, AST_FILE_MODE);
722         if (o >= 0) {
723                 char line[1000], mrs[3] = "", *p;
724                 char buf[30];
725                 unsigned char n;
726
727                 if (h->mr >= 0)
728                         snprintf(mrs, sizeof(mrs), "%02X", h->mr);
729                 snprintf(line, sizeof(line), "%s %c%c%c%s %s %s %s ",
730                         isodate(time(NULL), buf, sizeof(buf)),
731                         status, h->rx ? 'I' : 'O', h->smsc ? 'S' : 'M', mrs, h->queue,
732                         S_OR(h->oa, "-"), S_OR(h->da, "-") );
733                 p = line + strlen(line);
734                 for (n = 0; n < h->udl; n++) {
735                         if (h->ud[n] == '\\') {
736                                 *p++ = '\\';
737                                 *p++ = '\\';
738                         } else if (h->ud[n] == '\n') {
739                                 *p++ = '\\';
740                                 *p++ = 'n';
741                         } else if (h->ud[n] == '\r') {
742                                 *p++ = '\\';
743                                 *p++ = 'r';
744                         } else if (h->ud[n] < 32 || h->ud[n] == 127)
745                                 *p++ = 191;
746                         else
747                                 *p++ = h->ud[n];
748                 }
749                 *p++ = '\n';
750                 *p = 0;
751                 write(o, line, strlen(line));
752                 close(o);
753         }
754         *h->oa = *h->da = h->udl = 0;
755 }
756
757 /*! \brief parse and delete a file */
758 static void sms_readfile(sms_t * h, char *fn)
759 {
760         char line[1000];
761         FILE *s;
762         char dcsset = 0;                /* if DSC set */
763         ast_log(LOG_EVENT, "Sending %s\n", fn);
764         h->rx = h->udl = *h->oa = *h->da = h->pid = h->srr = h->udhi = h->rp = h->vp = h->udhl = 0;
765         h->mr = -1;
766         h->dcs = 0xF1;                  /* normal messages class 1 */
767         h->scts = time(NULL);
768         s = fopen(fn, "r");
769         if (s) {
770                 if (unlink(fn)) {       /* concurrent access, we lost */
771                         fclose(s);
772                         return;
773                 }
774                 while (fgets (line, sizeof(line), s)) { /* process line in file */
775                         char *p;
776                         void *pp = &p;
777                         for (p = line; *p && *p != '\n' && *p != '\r'; p++);
778                         *p = 0;                                  /* strip eoln */
779                         p = line;
780                         if (!*p || *p == ';')
781                                 continue;                         /* blank line or comment, ignore */
782                         while (isalnum(*p)) {
783                                 *p = tolower (*p);
784                                 p++;
785                         }
786                         while (isspace (*p))
787                                 *p++ = 0;
788                         if (*p == '=') {
789                                 *p++ = 0;
790                                 if (!strcmp(line, "ud")) {       /* parse message (UTF-8) */
791                                         unsigned char o = 0;
792                                         memcpy(h->udtxt, p, SMSLEN);    /* for protocol 2 */
793                                         while (*p && o < SMSLEN)
794                                                 h->ud[o++] = utf8decode(pp);
795                                         h->udl = o;
796                                         if (*p)
797                                                 ast_log(LOG_WARNING, "UD too long in %s\n", fn);
798                                 } else {
799                                         while (isspace (*p))
800                                                 p++;
801                                         if (!strcmp(line, "oa") && strlen(p) < sizeof(h->oa))
802                                                 numcpy (h->oa, p);
803                                         else if (!strcmp(line, "da") && strlen(p) < sizeof(h->oa))
804                                                 numcpy (h->da, p);
805                                         else if (!strcmp(line, "pid"))
806                                                 h->pid = atoi(p);
807                                         else if (!strcmp(line, "dcs")) {
808                                                 h->dcs = atoi(p);
809                                                 dcsset = 1;
810                                         } else if (!strcmp(line, "mr"))
811                                                 h->mr = atoi(p);
812                                         else if (!strcmp(line, "srr"))
813                                                 h->srr = (atoi(p) ? 1 : 0);
814                                         else if (!strcmp(line, "vp"))
815                                                 h->vp = atoi(p);
816                                         else if (!strcmp(line, "rp"))
817                                                 h->rp = (atoi(p) ? 1 : 0);
818                                         else if (!strcmp(line, "scts")) {       /* get date/time */
819                                                 int Y,
820                                                   m,
821                                                   d,
822                                                   H,
823                                                   M,
824                                                   S;
825                                                 if (sscanf (p, "%d-%d-%dT%d:%d:%d", &Y, &m, &d, &H, &M, &S) == 6) {
826                                                         struct tm t;
827                                                         t.tm_year = Y - 1900;
828                                                         t.tm_mon = m - 1;
829                                                         t.tm_mday = d;
830                                                         t.tm_hour = H;
831                                                         t.tm_min = M;
832                                                         t.tm_sec = S;
833                                                         t.tm_isdst = -1;
834                                                         h->scts = mktime(&t);
835                                                         if (h->scts == (time_t) - 1)
836                                                                 ast_log(LOG_WARNING, "Bad date/timein %s: %s", fn, p);
837                                                 }
838                                         } else
839                                                 ast_log(LOG_WARNING, "Cannot parse in %s: %s=%si\n", fn, line, p);
840                                 }
841                         } else if (*p == '#') {         /* raw hex format */
842                                 *p++ = 0;
843                                 if (*p == '#') {
844                                         p++;
845                                         if (!strcmp(line, "ud")) {      /* user data */
846                                                 int o = 0;
847                                                 while (*p && o < SMSLEN) {
848                                                         if (isxdigit(*p) && isxdigit(p[1]) && isxdigit(p[2]) && isxdigit(p[3])) {
849                                                                 h->ud[o++] =
850                                                                         (((isalpha(*p) ? 9 : 0) + (*p & 0xF)) << 12) +
851                                                                         (((isalpha(p[1]) ? 9 : 0) + (p[1] & 0xF)) << 8) +
852                                                                         (((isalpha(p[2]) ? 9 : 0) + (p[2] & 0xF)) << 4) + ((isalpha(p[3]) ? 9 : 0) + (p[3] & 0xF));
853                                                                 p += 4;
854                                                         } else
855                                                                 break;
856                                                 }
857                                                 h->udl = o;
858                                                 if (*p)
859                                                         ast_log(LOG_WARNING, "UD too long / invalid UCS-2 hex in %s\n", fn);
860                                         } else
861                                                 ast_log(LOG_WARNING, "Only ud can use ## format, %s\n", fn);
862                                 } else if (!strcmp(line, "ud")) {       /* user data */
863                                         int o = 0;
864                                         while (*p && o < SMSLEN) {
865                                                 if (isxdigit(*p) && isxdigit(p[1])) {
866                                                         h->ud[o++] = (((isalpha(*p) ? 9 : 0) + (*p & 0xF)) << 4) + ((isalpha(p[1]) ? 9 : 0) + (p[1] & 0xF));
867                                                         p += 2;
868                                                 } else
869                                                         break;
870                                         }
871                                         h->udl = o;
872                                         if (*p)
873                                                 ast_log(LOG_WARNING, "UD too long / invalid UCS-1 hex in %s\n", fn);
874                                 } else if (!strcmp(line, "udh")) {      /* user data header */
875                                         unsigned char o = 0;
876                                         h->udhi = 1;
877                                         while (*p && o < SMSLEN) {
878                                                 if (isxdigit(*p) && isxdigit(p[1])) {
879                                                         h->udh[o] = (((isalpha(*p) ? 9 : 0) + (*p & 0xF)) << 4) + ((isalpha(p[1]) ? 9 : 0) + (p[1] & 0xF));
880                                                         o++;
881                                                         p += 2;
882                                                 } else
883                                                         break;
884                                         }
885                                         h->udhl = o;
886                                         if (*p)
887                                                 ast_log(LOG_WARNING, "UDH too long / invalid hex in %s\n", fn);
888                                 } else
889                                         ast_log(LOG_WARNING, "Only ud and udh can use # format, %s\n", fn);
890                         } else
891                                 ast_log(LOG_WARNING, "Cannot parse in %s: %s\n", fn, line);
892                 }
893                 fclose(s);
894                 if (!dcsset && packsms7(0, h->udhl, h->udh, h->udl, h->ud) < 0) {
895                         if (packsms8(0, h->udhl, h->udh, h->udl, h->ud) < 0) {
896                                 if (packsms16(0, h->udhl, h->udh, h->udl, h->ud) < 0)
897                                         ast_log(LOG_WARNING, "Invalid UTF-8 message even for UCS-2 (%s)\n", fn);
898                                 else {
899                                         h->dcs = 0x08;  /* default to 16 bit */
900                                         ast_log(LOG_WARNING, "Sending in 16 bit format(%s)\n", fn);
901                                 }
902                         } else {
903                                 h->dcs = 0xF5;          /* default to 8 bit */
904                                 ast_log(LOG_WARNING, "Sending in 8 bit format(%s)\n", fn);
905                         }
906                 }
907                 if (is7bit(h->dcs) && packsms7(0, h->udhl, h->udh, h->udl, h->ud) < 0)
908                         ast_log(LOG_WARNING, "Invalid 7 bit GSM data %s\n", fn);
909                 if (is8bit(h->dcs) && packsms8(0, h->udhl, h->udh, h->udl, h->ud) < 0)
910                         ast_log(LOG_WARNING, "Invalid 8 bit data %s\n", fn);
911                 if (is16bit(h->dcs) && packsms16(0, h->udhl, h->udh, h->udl, h->ud) < 0)
912                         ast_log(LOG_WARNING, "Invalid 16 bit data %s\n", fn);
913         }
914 }
915
916 /*! \brief white a received text message to a file */
917 static void sms_writefile(sms_t * h)
918 {
919         char fn[200] = "", fn2[200] = "";
920         char buf[30];
921         FILE *o;
922
923         snprintf(fn, sizeof(fn), "%s/sms/%s", ast_config_AST_SPOOL_DIR, h->smsc ? h->rx ? "morx" : "mttx" : h->rx ? "mtrx" : "motx");
924         ast_mkdir(fn, 0777);                    /* ensure it exists */
925         ast_copy_string(fn2, fn, sizeof(fn2));
926         snprintf(fn2 + strlen(fn2), sizeof(fn2) - strlen(fn2), "/%s.%s-%d", h->queue, isodate(h->scts, buf, sizeof(buf)), seq++);
927         snprintf(fn + strlen(fn), sizeof(fn) - strlen(fn), "/.%s", fn2 + strlen(fn) + 1);
928         o = fopen(fn, "w");
929         if (o == NULL)
930                 return;
931
932         if (*h->oa)
933                 fprintf(o, "oa=%s\n", h->oa);
934         if (*h->da)
935                 fprintf(o, "da=%s\n", h->da);
936         if (h->udhi) {
937                 unsigned int p;
938                 fprintf(o, "udh#");
939                 for (p = 0; p < h->udhl; p++)
940                         fprintf(o, "%02X", h->udh[p]);
941                 fprintf(o, "\n");
942         }
943         if (h->udl) {
944                 unsigned int p;
945                 for (p = 0; p < h->udl && h->ud[p] >= ' '; p++);
946                 if (p < h->udl)
947                         fputc(';', o);    /* cannot use ud=, but include as a comment for human readable */
948                 fprintf(o, "ud=");
949                 for (p = 0; p < h->udl; p++) {
950                         unsigned short v = h->ud[p];
951                         if (v < 32)
952                                 fputc(191, o);
953                         else if (v < 0x80)
954                                 fputc(v, o);
955                         else if (v < 0x800)
956                         {
957                                 fputc(0xC0 + (v >> 6), o);
958                                 fputc(0x80 + (v & 0x3F), o);
959                         } else
960                         {
961                                 fputc(0xE0 + (v >> 12), o);
962                                 fputc(0x80 + ((v >> 6) & 0x3F), o);
963                                 fputc(0x80 + (v & 0x3F), o);
964                         }
965                 }
966                 fprintf(o, "\n");
967                 for (p = 0; p < h->udl && h->ud[p] >= ' '; p++);
968                 if (p < h->udl) {
969                         for (p = 0; p < h->udl && h->ud[p] < 0x100; p++);
970                         if (p == h->udl) {                                               /* can write in ucs-1 hex */
971                                 fprintf(o, "ud#");
972                                 for (p = 0; p < h->udl; p++)
973                                         fprintf(o, "%02X", h->ud[p]);
974                                 fprintf(o, "\n");
975                         } else {                                                 /* write in UCS-2 */
976                                 fprintf(o, "ud##");
977                                 for (p = 0; p < h->udl; p++)
978                                         fprintf(o, "%04X", h->ud[p]);
979                                 fprintf(o, "\n");
980                         }
981                 }
982         }
983         if (h->scts) {
984                 char buf[30];
985                 fprintf(o, "scts=%s\n", isodate(h->scts, buf, sizeof(buf)));
986         }
987         if (h->pid)
988                 fprintf(o, "pid=%d\n", h->pid);
989         if (h->dcs != 0xF1)
990                 fprintf(o, "dcs=%d\n", h->dcs);
991         if (h->vp)
992                 fprintf(o, "vp=%d\n", h->vp);
993         if (h->srr)
994                 fprintf(o, "srr=1\n");
995         if (h->mr >= 0)
996                 fprintf(o, "mr=%d\n", h->mr);
997         if (h->rp)
998                 fprintf(o, "rp=1\n");
999         fclose(o);
1000         if (rename(fn, fn2))
1001                 unlink(fn);
1002         else
1003                 ast_log(LOG_EVENT, "Received to %s\n", fn2);
1004 }
1005
1006 /*! \brief read dir skipping dot files... */
1007 static struct dirent *readdirqueue(DIR *d, char *queue)
1008 {
1009         struct dirent *f;
1010         do {
1011                 f = readdir(d);
1012         } while (f && (*f->d_name == '.' || strncmp(f->d_name, queue, strlen(queue)) || f->d_name[strlen(queue)] != '.'));
1013         return f;
1014 }
1015
1016 /*! \brief handle the incoming message */
1017 static unsigned char sms_handleincoming (sms_t * h)
1018 {
1019         unsigned char p = 3;
1020         if (h->smsc) {                                                                   /* SMSC */
1021                 if ((h->imsg[2] & 3) == 1) {                            /* SMS-SUBMIT */
1022                         h->udhl = h->udl = 0;
1023                         h->vp = 0;
1024                         h->srr = ((h->imsg[2] & 0x20) ? 1 : 0);
1025                         h->udhi = ((h->imsg[2] & 0x40) ? 1 : 0);
1026                         h->rp = ((h->imsg[2] & 0x80) ? 1 : 0);
1027                         ast_copy_string(h->oa, h->cli, sizeof(h->oa));
1028                         h->scts = time(NULL);
1029                         h->mr = h->imsg[p++];
1030                         p += unpackaddress(h->da, h->imsg + p);
1031                         h->pid = h->imsg[p++];
1032                         h->dcs = h->imsg[p++];
1033                         if ((h->imsg[2] & 0x18) == 0x10) {                                                       /* relative VP */
1034                                 if (h->imsg[p] < 144)
1035                                         h->vp = (h->imsg[p] + 1) * 5;
1036                                 else if (h->imsg[p] < 168)
1037                                         h->vp = 720 + (h->imsg[p] - 143) * 30;
1038                                 else if (h->imsg[p] < 197)
1039                                         h->vp = (h->imsg[p] - 166) * 1440;
1040                                 else
1041                                         h->vp = (h->imsg[p] - 192) * 10080;
1042                                 p++;
1043                         } else if (h->imsg[2] & 0x18)
1044                                 p += 7;                          /* ignore enhanced / absolute VP */
1045                         p += unpacksms(h->dcs, h->imsg + p, h->udh, &h->udhl, h->ud, &h->udl, h->udhi);
1046                         h->rx = 1;                               /* received message */
1047                         sms_writefile(h);         /* write the file */
1048                         if (p != h->imsg[1] + 2) {
1049                                 ast_log(LOG_WARNING, "Mismatch receive unpacking %d/%d\n", p, h->imsg[1] + 2);
1050                                 return 0xFF;              /* duh! */
1051                         }
1052                 } else {
1053                         ast_log(LOG_WARNING, "Unknown message type %02X\n", h->imsg[2]);
1054                         return 0xFF;
1055                 }
1056         } else {                                                                         /* client */
1057                 if (!(h->imsg[2] & 3)) {                                                                 /* SMS-DELIVER */
1058                         *h->da = h->srr = h->rp = h->vp = h->udhi = h->udhl = h->udl = 0;
1059                         h->srr = ((h->imsg[2] & 0x20) ? 1 : 0);
1060                         h->udhi = ((h->imsg[2] & 0x40) ? 1 : 0);
1061                         h->rp = ((h->imsg[2] & 0x80) ? 1 : 0);
1062                         h->mr = -1;
1063                         p += unpackaddress(h->oa, h->imsg + p);
1064                         h->pid = h->imsg[p++];
1065                         h->dcs = h->imsg[p++];
1066                         h->scts = unpackdate(h->imsg + p);
1067                         p += 7;
1068                         p += unpacksms(h->dcs, h->imsg + p, h->udh, &h->udhl, h->ud, &h->udl, h->udhi);
1069                         h->rx = 1;                               /* received message */
1070                         sms_writefile(h);         /* write the file */
1071                         if (p != h->imsg[1] + 2) {
1072                                 ast_log(LOG_WARNING, "Mismatch receive unpacking %d/%d\n", p, h->imsg[1] + 2);
1073                                 return 0xFF;              /* duh! */
1074                         }
1075                 } else {
1076                         ast_log(LOG_WARNING, "Unknown message type %02X\n", h->imsg[2]);
1077                         return 0xFF;
1078                 }
1079         }
1080         return 0;                                                 /* no error */
1081 }
1082
1083 #ifdef SOLARIS
1084 #define NAME_MAX 1024
1085 #endif
1086
1087 /*!
1088  * Add data to a protocol 2 message.
1089  * Use the length field (h->omsg[1]) as a pointer to the next free position.
1090  */
1091 static void adddata_proto2(sms_t *h, unsigned char msg, char *data, int size)
1092 {
1093         int x = h->omsg[1]+2;   /* Get current position */
1094         if (x == 2)
1095                 x += 2;         /* First: skip Payload length (set later) */
1096         h->omsg[x++] = msg;     /* Message code */
1097         h->omsg[x++] = (unsigned char)size;       /* Data size Low */
1098         h->omsg[x++] = 0;        /* Data size Hi */
1099         for (; size > 0 ; size--)
1100                 h->omsg[x++] = *data++;
1101         h->omsg[1] = x - 2;     /* Frame size */
1102         h->omsg[2] = x - 4;     /* Payload length (Lo) */
1103         h->omsg[3] = 0;         /* Payload length (Hi) */
1104 }
1105
1106 static void putdummydata_proto2(sms_t *h)
1107 {
1108         adddata_proto2(h, 0x10, "\0", 1);             /* Media Identifier > SMS */
1109         adddata_proto2(h, 0x11, "\0\0\0\0\0\0", 6);    /* Firmware version */
1110         adddata_proto2(h, 0x12, "\2\0\4", 3);     /* SMS provider ID */
1111         adddata_proto2(h, 0x13, h->udtxt, h->udl);     /* Body */
1112 }
1113
1114 static void sms_compose2(sms_t *h, int more)
1115 {
1116         struct tm tm;
1117         char stm[9];
1118
1119         h->omsg[0] = 0x00;       /* set later... */
1120         h->omsg[1] = 0;
1121         putdummydata_proto2(h);
1122         if (h->smsc) {            /* deliver */
1123                 h->omsg[0] = 0x11;      /* SMS_DELIVERY */
1124                 /* Required: 10 11 12 13 14 15 17 (seems they must be ordered!) */
1125                 ast_localtime(&h->scts, &tm, NULL);
1126                 sprintf(stm, "%02d%02d%02d%02d", tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min);     /* Date mmddHHMM */
1127                 adddata_proto2(h, 0x14, stm, 8);               /* Date */
1128                 if (*h->oa == 0)
1129                         strcpy(h->oa, "00000000");
1130                 adddata_proto2(h, 0x15, h->oa, strlen(h->oa)); /* Originator */
1131                 adddata_proto2(h, 0x17, "\1", 1);             /* Calling Terminal ID */
1132         } else {                        /* submit */
1133                 h->omsg[0] = 0x10;      /* SMS_SUBMIT */
1134                 /* Required: 10 11 12 13 17 18 1B 1C (seems they must be ordered!) */
1135                 adddata_proto2(h, 0x17, "\1", 1);             /* Calling Terminal ID */
1136                 if (*h->da == 0)
1137                         strcpy(h->da, "00000000");
1138                 adddata_proto2(h, 0x18, h->da, strlen(h->da)); /* Originator */
1139                 adddata_proto2(h, 0x1B, "\1", 1);             /* Called Terminal ID */
1140                 adddata_proto2(h, 0x1C, "\0\0\0", 3);     /* Notification */
1141         }
1142 }
1143
1144 static void putdummydata_proto2(sms_t *h);
1145
1146 #define MAX_DEBUG_LEN   300
1147 static char *sms_hexdump(unsigned char buf[], int size, char *s /* destination */)
1148 {
1149         char *p;
1150         int f;
1151
1152         for (p = s, f = 0; f < size && f < MAX_DEBUG_LEN; f++, p += 3) 
1153                 sprintf(p, "%02X ", (unsigned char)buf[f]);
1154         return(s);
1155 }
1156
1157
1158 /*! \brief sms_handleincoming_proto2: handle the incoming message */
1159 static int sms_handleincoming_proto2(sms_t *h)
1160 {
1161         int f, i, sz = 0;
1162         int msg, msgsz;
1163         struct tm tm;
1164         char debug_buf[MAX_DEBUG_LEN * 3 + 1];
1165
1166         sz = h->imsg[1] + 2;
1167         /* ast_verbose(VERBOSE_PREFIX_3 "SMS-P2 Frame: %s\n", sms_hexdump(h->imsg, sz, debug_buf)); */
1168
1169         /* Parse message body (called payload) */
1170         h->scts = time(NULL);
1171         for (f = 4; f < sz; ) {
1172                 msg = h->imsg[f++];
1173                 msgsz = h->imsg[f++];
1174                 msgsz += (h->imsg[f++] * 256);
1175                 switch (msg) {
1176                 case 0x13:      /* Body */
1177                         if (option_verbose > 2)
1178                                 ast_verbose(VERBOSE_PREFIX_3 "SMS-P2 Body#%02X=[%.*s]\n", msg, msgsz, &h->imsg[f]);
1179                         if (msgsz >= sizeof(h->imsg))
1180                                 msgsz = sizeof(h->imsg) - 1;
1181                         for (i = 0; i < msgsz; i++)
1182                                 h->ud[i] = h->imsg[f + i];
1183                         h->udl = msgsz;
1184                         break;
1185                 case 0x14:      /* Date SCTS */
1186                         h->scts = time(NULL);
1187                         ast_localtime(&h->scts, &tm, NULL);
1188                         tm.tm_mon = ( (h->imsg[f] * 10) + h->imsg[f + 1] ) - 1;
1189                         tm.tm_mday = ( (h->imsg[f + 2] * 10) + h->imsg[f + 3] );
1190                         tm.tm_hour = ( (h->imsg[f + 4] * 10) + h->imsg[f + 5] );
1191                         tm.tm_min = ( (h->imsg[f + 6] * 10) + h->imsg[f + 7] );
1192                         tm.tm_sec = 0;
1193                         h->scts = mktime(&tm);
1194                         if (option_verbose > 2)
1195                                 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);
1196                         break;
1197                 case 0x15:      /* Calling line (from SMSC) */
1198                         if (msgsz >= 20)
1199                                 msgsz = 20 - 1;
1200                         if (option_verbose > 2)
1201                                 ast_verbose(VERBOSE_PREFIX_3 "SMS-P2 Origin#%02X=[%.*s]\n", msg, msgsz, &h->imsg[f]);
1202                         ast_copy_string(h->oa, (char *)(&h->imsg[f]), msgsz + 1);
1203                         break;
1204                 case 0x18:      /* Destination(from TE/phone) */
1205                         if (msgsz >= 20)
1206                                 msgsz = 20 - 1;
1207                         if (option_verbose > 2)
1208                                 ast_verbose(VERBOSE_PREFIX_3 "SMS-P2 Destination#%02X=[%.*s]\n", msg, msgsz, &h->imsg[f]);
1209                         ast_copy_string(h->da, (char *)(&h->imsg[f]), msgsz + 1);
1210                         break;
1211                 case 0x1C:      /* Notify */
1212                         if (option_verbose > 2)
1213                                 ast_verbose(VERBOSE_PREFIX_3 "SMS-P2 Notify#%02X=%s\n", msg, sms_hexdump(&h->imsg[f], 3, debug_buf));
1214                         break;
1215                 default:
1216                         if (option_verbose > 2)
1217                                 ast_verbose(VERBOSE_PREFIX_3 "SMS-P2 Par#%02X [%d]: %s\n", msg, msgsz, sms_hexdump(&h->imsg[f], msgsz, debug_buf));
1218                         break;
1219                 }
1220                 f+=msgsz;       /* Skip to next */
1221         }
1222         h->rx = 1;            /* received message */
1223         sms_writefile(h);      /* write the file */
1224         return 0;              /* no error */
1225 }
1226
1227 #if 0
1228 static void smssend(sms_t *h, char *c)
1229 {
1230         int f, x;
1231         for (f = 0; f < strlen(c); f++) {
1232                 sscanf(&c[f*3], "%x", &x);
1233                 h->omsg[f] = x;
1234         }
1235         sms_messagetx(h);
1236 }
1237 #endif
1238
1239 static void sms_nextoutgoing (sms_t *h);
1240
1241 static void sms_messagerx2(sms_t * h)
1242 {
1243         int p = h->imsg[0] & DLL_SMS_MASK ; /* mask the high bit */
1244         int cause;
1245
1246 #define DLL2_ACK(h) ((h->framenumber & 1) ? DLL2_SMS_ACK1: DLL2_SMS_ACK1)
1247         switch (p) {
1248         case DLL2_SMS_EST:      /* Protocol 2: Connection ready (fake): send message  */
1249                 sms_nextoutgoing (h);
1250                 /* 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 "); */
1251                 break;
1252
1253         case DLL2_SMS_INFO_MO:  /* transport SMS_SUBMIT */
1254         case DLL2_SMS_INFO_MT:  /* transport SMS_DELIVERY */
1255                 cause = sms_handleincoming_proto2(h);
1256                 if (!cause)     /* ACK */
1257                         sms_log(h, 'Y');
1258                 h->omsg[0] = DLL2_ACK(h);
1259                 h->omsg[1] = 0x06;  /* msg len */
1260                 h->omsg[2] = 0x04;  /* payload len */
1261                 h->omsg[3] = 0x00;  /* payload len */
1262                 h->omsg[4] = 0x1f;  /* Response type */
1263                 h->omsg[5] = 0x01;  /* parameter len */
1264                 h->omsg[6] = 0x00;  /* parameter len */
1265                 h->omsg[7] = cause;  /* CONFIRM or error */
1266                 sms_messagetx(h);
1267                 break;
1268
1269         case DLL2_SMS_NACK:     /* Protocol 2: SMS_NAK */
1270                 h->omsg[0] = DLL2_SMS_REL;  /* SMS_REL */
1271                 h->omsg[1] = 0x00;  /* msg len */
1272                 sms_messagetx(h);
1273                 break;
1274
1275         case DLL2_SMS_ACK0:
1276         case DLL2_SMS_ACK1:
1277                 /* SMS_ACK also transport SMS_SUBMIT or SMS_DELIVERY */
1278                 if ( (h->omsg[0] & DLL_SMS_MASK) == DLL2_SMS_REL) {
1279                         /* a response to our Release, just hangup */
1280                         h->hangup = 1;    /* hangup */
1281                 } else {
1282                         /* XXX depending on what we are.. */
1283                         ast_log(LOG_NOTICE, "SMS_SUBMIT or SMS_DELIVERY");
1284                         sms_nextoutgoing (h);
1285                 }
1286                 break;
1287
1288         case DLL2_SMS_REL:      /* Protocol 2: SMS_REL (hangup req) */
1289                 h->omsg[0] = DLL2_ACK(h);
1290                 h->omsg[1] = 0;
1291                 sms_messagetx(h);
1292                 break;
1293         }
1294 }
1295
1296 /*! \brief compose a message for protocol 1 */
1297 static void sms_compose1(sms_t *h, int more)
1298 {
1299         unsigned int p = 2;     /* next byte to write. Skip type and len */
1300
1301         h->omsg[0] = 0x91;                /* SMS_DATA */
1302         if (h->smsc) {                   /* deliver */
1303                 h->omsg[p++] = (more ? 4 : 0) + ((h->udhl > 0) ? 0x40 : 0);
1304                 p += packaddress(h->omsg + p, h->oa);
1305                 h->omsg[p++] = h->pid;
1306                 h->omsg[p++] = h->dcs;
1307                 packdate(h->omsg + p, h->scts);
1308                 p += 7;
1309                 p += packsms(h->dcs, h->omsg + p, h->udhl, h->udh, h->udl, h->ud);
1310         } else {                         /* submit */
1311                 h->omsg[p++] =
1312                         0x01 + (more ? 4 : 0) + (h->srr ? 0x20 : 0) + (h->rp ? 0x80 : 0) + (h->vp ? 0x10 : 0) + (h->udhi ? 0x40 : 0);
1313                 if (h->mr < 0)
1314                         h->mr = message_ref++;
1315                 h->omsg[p++] = h->mr;
1316                 p += packaddress(h->omsg + p, h->da);
1317                 h->omsg[p++] = h->pid;
1318                 h->omsg[p++] = h->dcs;
1319                 if (h->vp) {             /* relative VP */
1320                         if (h->vp < 720)
1321                                 h->omsg[p++] = (h->vp + 4) / 5 - 1;
1322                         else if (h->vp < 1440)
1323                                 h->omsg[p++] = (h->vp - 720 + 29) / 30 + 143;
1324                         else if (h->vp < 43200)
1325                                 h->omsg[p++] = (h->vp + 1439) / 1440 + 166;
1326                         else if (h->vp < 635040)
1327                                 h->omsg[p++] = (h->vp + 10079) / 10080 + 192;
1328                         else
1329                                 h->omsg[p++] = 255;             /* max */
1330                 }
1331                 p += packsms(h->dcs, h->omsg + p, h->udhl, h->udh, h->udl, h->ud);
1332         }
1333         h->omsg[1] = p - 2;
1334 }
1335
1336 /*! \brief find and fill in next message, or send a REL if none waiting */
1337 static void sms_nextoutgoing (sms_t * h)
1338 {         
1339         char fn[100 + NAME_MAX] = "";
1340         DIR *d;
1341         char more = 0;
1342
1343         *h->da = *h->oa = '\0';                 /* clear destinations */
1344         h->rx = 0;                              /* outgoing message */
1345         snprintf(fn, sizeof(fn), "%s/sms/%s", ast_config_AST_SPOOL_DIR, h->smsc ? "mttx" : "motx");
1346         ast_mkdir(fn, 0777);                    /* ensure it exists */
1347         d = opendir(fn);
1348         if (d) {
1349                 struct dirent *f = readdirqueue(d, h->queue);
1350                 if (f) {
1351                         snprintf(fn + strlen(fn), sizeof(fn) - strlen(fn), "/%s", f->d_name);
1352                         sms_readfile(h, fn);
1353                         if (readdirqueue(d, h->queue))
1354                                 more = 1;                         /* more to send */
1355                 }
1356                 closedir(d);
1357         }
1358         if (*h->da || *h->oa) {                                                                  /* message to send */
1359                 if (h->protocol == 2)
1360                         sms_compose2(h, more);
1361                 else
1362                         sms_compose1(h, more);
1363         } else {                                /* no message */
1364                 if (h->protocol == 2) {
1365                         h->omsg[0] = 0x17;      /* SMS_REL */
1366                         h->omsg[1] = 0;
1367                 } else {
1368                         h->omsg[0] = 0x94;      /* SMS_REL */
1369                         h->omsg[1] = 0;
1370                 }
1371         }
1372         sms_messagetx(h);
1373 }
1374
1375 #define DIR_RX 1
1376 #define DIR_TX 2
1377 static void sms_debug (int dir, sms_t *h)
1378 {
1379         char txt[259 * 3 + 1];
1380         char *p = txt;                                           /* always long enough */
1381         unsigned char *msg = (dir == DIR_RX) ? h->imsg : h->omsg;
1382         int n = (dir == DIR_RX) ? h->ibytep : msg[1] + 2;
1383         int q = 0;
1384         while (q < n && q < 30) {
1385                 sprintf(p, " %02X", msg[q++]);
1386                 p += 3;
1387         }
1388         if (q < n)
1389                 sprintf(p, "...");
1390         if (option_verbose > 2)
1391                 ast_verbose(VERBOSE_PREFIX_3 "SMS %s%s\n", dir == DIR_RX ? "RX" : "TX", txt);
1392 }
1393
1394
1395 static void sms_messagerx(sms_t * h)
1396 {
1397         int cause;
1398
1399         sms_debug (DIR_RX, h);
1400         if (h->protocol == 2) {
1401                 sms_messagerx2(h);
1402                 return;
1403         }
1404         /* parse incoming message for Protocol 1 */
1405         switch (h->imsg[0]) {
1406         case 0x91:                                              /* SMS_DATA */
1407                 cause = sms_handleincoming (h);
1408                 if (!cause) {
1409                         sms_log(h, 'Y');
1410                         h->omsg[0] = 0x95;  /* SMS_ACK */
1411                         h->omsg[1] = 0x02;
1412                         h->omsg[2] = 0x00;  /* deliver report */
1413                         h->omsg[3] = 0x00;  /* no parameters */
1414                 } else {                                                         /* NACK */
1415                         sms_log(h, 'N');
1416                         h->omsg[0] = 0x96;  /* SMS_NACK */
1417                         h->omsg[1] = 3;
1418                         h->omsg[2] = 0;   /* delivery report */
1419                         h->omsg[3] = cause; /* cause */
1420                         h->omsg[4] = 0;   /* no parameters */
1421                 }
1422                 sms_messagetx(h);
1423                 break;
1424
1425         case 0x92:                                              /* SMS_ERROR */
1426                 h->err = 1;
1427                 sms_messagetx(h);                 /* send whatever we sent again */
1428                 break;
1429         case 0x93:                                              /* SMS_EST */
1430                 sms_nextoutgoing (h);
1431                 break;
1432         case 0x94:                                              /* SMS_REL */
1433                 h->hangup = 1;                          /* hangup */
1434                 break;
1435         case 0x95:                                              /* SMS_ACK */
1436                 sms_log(h, 'Y');
1437                 sms_nextoutgoing (h);
1438                 break;
1439         case 0x96:                                              /* SMS_NACK */
1440                 h->err = 1;
1441                 sms_log(h, 'N');
1442                 sms_nextoutgoing (h);
1443                 break;
1444         default:                                                  /* Unknown */
1445                 h->omsg[0] = 0x92;                /* SMS_ERROR */
1446                 h->omsg[1] = 1;
1447                 h->omsg[2] = 3;                   /* unknown message type; */
1448                 sms_messagetx(h);
1449                 break;
1450         }
1451 }
1452
1453 static void sms_messagetx(sms_t * h)
1454 {
1455         unsigned char c = 0, p;
1456         int len = h->omsg[1] + 2;       /* total message length excluding checksum */
1457
1458         for (p = 0; p < len; p++)       /* compute checksum */
1459                 c += h->omsg[p];
1460         h->omsg[len] = 0 - c;           /* actually, (256 - (c & 0fxx)) & 0xff) */
1461         sms_debug(DIR_TX, h);
1462         h->framenumber++;       /* Proto 2 */
1463         h->obyte = 1;           /* send mark ('1') at the beginning */
1464         h->opause = 200;
1465         /* Change the initial message delay. BT requires 300ms,
1466          * but for others this might be way too much and the phone
1467          * could time out. XXX make it configurable.
1468          */
1469         if (h->omsg[0] == 0x93)
1470                 h->opause = 8 * h->opause_0;    /* initial message delay */
1471         h->obytep = 0;
1472         h->obitp = 0;
1473         if (h->protocol == 2) {
1474                 h->oseizure = 300;      /* Proto 2: 300bits (or more ?) */
1475                 h->obyte = 0;      /* Seizure starts with  space (0) */
1476                 h->opause = 400;
1477         } else {
1478                 h->oseizure = 0;        /* Proto 1: No seizure */
1479         }
1480         /* Note - setting osync triggers the generator */
1481         h->osync = OSYNC_BITS;                  /* 80 sync bits */
1482         h->obyten = len + 1;            /* bytes to send (including checksum) */
1483 }
1484
1485 /*!
1486  * outgoing data are produced by this generator function, that reads from
1487  * the descriptor whether it has data to send and which ones.
1488  */
1489 static int sms_generate(struct ast_channel *chan, void *data, int len, int samples)
1490 {
1491         struct ast_frame f = { 0 };
1492 #define MAXSAMPLES (800)
1493         output_t *buf;
1494         sms_t *h = data;
1495         int i;
1496
1497         if (samples > MAXSAMPLES) {
1498                 ast_log(LOG_WARNING, "Only doing %d samples (%d requested)\n",
1499                          MAXSAMPLES, samples);
1500                 samples = MAXSAMPLES;
1501         }
1502         len = samples * sizeof(*buf) + AST_FRIENDLY_OFFSET;
1503         buf = alloca(len);
1504
1505         f.frametype = AST_FRAME_VOICE;
1506         f.subclass = __OUT_FMT;
1507         f.datalen = samples * sizeof(*buf);
1508         f.offset = AST_FRIENDLY_OFFSET;
1509         f.mallocd = 0;
1510         f.data = buf;
1511         f.samples = samples;
1512         f.src = "app_sms";
1513         /* create a buffer containing the digital sms pattern */
1514         for (i = 0; i < samples; i++) {
1515                 buf[i] = wave_out[0];   /* default is silence */
1516
1517                 if (h->opause)
1518                         h->opause--;
1519                 else if (h->obyten || h->osync) {       /* sending data */
1520                         buf[i] = wave_out[h->ophase];
1521                         h->ophase += (h->obyte & 1) ? 13 : 21;  /* compute next phase */
1522                         if (h->ophase >= 80)
1523                                 h->ophase -= 80;
1524                         if ((h->ophasep += 12) >= 80) {         /* time to send the next bit */
1525                                 h->ophasep -= 80;
1526                                 if (h->oseizure > 0) {     /* sending channel seizure (proto 2) */
1527                                         h->oseizure--;
1528                                         h->obyte ^= 1;  /* toggle low bit */
1529                                 } else if (h->osync) {
1530                                         h->obyte = 1;   /* send mark as sync bit */
1531                                         h->osync--;             /* sending sync bits */
1532                                         if (h->osync == 0 && h->protocol == 2 && h->omsg[0] == DLL2_SMS_EST) {
1533                                                 h->obytep = h->obyten = 0;      /* we are done */
1534                                         }
1535                                 } else {
1536                                         h->obitp++;
1537                                         if (h->obitp == 1)
1538                                                 h->obyte = 0; /* start bit; */
1539                                         else if (h->obitp == 2)
1540                                                 h->obyte = h->omsg[h->obytep];
1541                                         else if (h->obitp == 10) {
1542                                                 h->obyte = 1; /* stop bit */
1543                                                 h->obitp = 0;
1544                                                 h->obytep++;
1545                                                 if (h->obytep == h->obyten) {
1546                                                         h->obytep = h->obyten = 0; /* sent */
1547                                                         h->osync = 10;    /* trailing marks */
1548                                                 }
1549                                         } else
1550                                                 h->obyte >>= 1;
1551                                 }
1552                         }
1553                 }
1554         }
1555         if (ast_write(chan, &f) < 0) {
1556                 ast_log(LOG_WARNING, "Failed to write frame to '%s': %s\n", chan->name, strerror(errno));
1557                 return -1;
1558         }
1559         return 0;
1560 #undef MAXSAMPLES
1561 }
1562
1563 /*!
1564  * Just return the pointer to the descriptor that we received.
1565  */
1566 static void *sms_alloc(struct ast_channel *chan, void *sms_t_ptr)
1567 {
1568         return sms_t_ptr;
1569 }
1570
1571 static void sms_release(struct ast_channel *chan, void *data)
1572 {
1573         return; /* nothing to do here. */
1574 }
1575
1576 static struct ast_generator smsgen = {
1577         .alloc = sms_alloc,
1578         .release = sms_release,
1579         .generate = sms_generate,
1580 };
1581
1582 /*!
1583  * Process an incoming frame, trying to detect the carrier and
1584  * decode the message. The two frequencies are 1300 and 2100 Hz.
1585  * The decoder detects the amplitude of the signal over the last
1586  * few samples, filtering the absolute values with a lowpass filter.
1587  * If the magnitude (h->imag) is large enough, multiply the signal
1588  * by the two carriers, and compute the amplitudes m0 and m1.
1589  * Record the current sample as '0' or '1' depending on which one is greater.
1590  * The last 3 bits are stored in h->ibith, with the count of '1'
1591  * bits in h->ibitt.
1592  * XXX the rest is to be determined.
1593  */
1594 static void sms_process(sms_t * h, int samples, signed short *data)
1595 {
1596         int bit;
1597
1598         /*
1599          * Ignore incoming audio while a packet is being transmitted,
1600          * the protocol is half-duplex.
1601          * Unfortunately this means that if the outbound and incoming
1602          * transmission overlap (which is an error condition anyways),
1603          * we may miss some data and this makes debugging harder.
1604          */
1605         if (h->obyten || h->osync)
1606                 return;
1607         for ( ; samples-- ; data++) {
1608                 unsigned long long m0, m1;
1609                 if (abs(*data) > h->imag)
1610                         h->imag = abs(*data);
1611                 else
1612                         h->imag = h->imag * 7 / 8;
1613                 if (h->imag <= 500) {           /* below [arbitrary] threahold: lost carrier */
1614                         if (h->idle++ == 80000) {                /* nothing happening */
1615                                 ast_log(LOG_NOTICE, "No data, hanging up\n");
1616                                 h->hangup = 1;
1617                                 h->err = 1;
1618                         }
1619                         if (h->ierr) {          /* error */
1620                                 ast_log(LOG_NOTICE, "Error %d, hanging up\n", h->ierr);
1621                                 /* Protocol 1 */
1622                                 h->err = 1;
1623                                 h->omsg[0] = 0x92;  /* error */
1624                                 h->omsg[1] = 1;
1625                                 h->omsg[2] = h->ierr;
1626                                 sms_messagetx(h);  /* send error */
1627                         }
1628                         h->ierr = h->ibitn = h->ibytep = h->ibytec = 0;
1629                         continue;
1630                 }
1631                 h->idle = 0;
1632
1633                 /* multiply signal by the two carriers. */
1634                 h->ims0 = (h->ims0 * 6 + *data * wave[h->ips0]) / 7;
1635                 h->imc0 = (h->imc0 * 6 + *data * wave[h->ipc0]) / 7;
1636                 h->ims1 = (h->ims1 * 6 + *data * wave[h->ips1]) / 7;
1637                 h->imc1 = (h->imc1 * 6 + *data * wave[h->ipc1]) / 7;
1638                 /* compute the amplitudes */
1639                 m0 = h->ims0 * h->ims0 + h->imc0 * h->imc0;
1640                 m1 = h->ims1 * h->ims1 + h->imc1 * h->imc1;
1641
1642                 /* advance the sin/cos pointers */
1643                 if ((h->ips0 += 21) >= 80)
1644                         h->ips0 -= 80;
1645                 if ((h->ipc0 += 21) >= 80)
1646                         h->ipc0 -= 80;
1647                 if ((h->ips1 += 13) >= 80)
1648                         h->ips1 -= 80;
1649                 if ((h->ipc1 += 13) >= 80)
1650                         h->ipc1 -= 80;
1651
1652                 /* set new bit to 1 or 0 depending on which value is stronger */
1653                 h->ibith <<= 1;
1654                 if (m1 > m0)
1655                         h->ibith |= 1;
1656                 if (h->ibith & 8)
1657                         h->ibitt--;
1658                 if (h->ibith & 1)
1659                         h->ibitt++;
1660                 bit = ((h->ibitt > 1) ? 1 : 0);
1661                 if (bit != h->ibitl)
1662                         h->ibitc = 1;
1663                 else
1664                         h->ibitc++;
1665                 h->ibitl = bit;
1666                 if (!h->ibitn && h->ibitc == 4 && !bit) {
1667                         h->ibitn = 1;
1668                         h->iphasep = 0;
1669                 }
1670                 if (bit && h->ibitc == 200) {                                            /* sync, restart message */
1671                         /* Protocol 2: empty connnection ready (I am master) */
1672                         if (h->framenumber < 0 && h->ibytec >= 160 && !memcmp(h->imsg, "UUUUUUUUUUUUUUUUUUUU", 20)) {
1673                                 h->framenumber = 1;
1674                                 if (option_verbose > 2)
1675                                         ast_verbose(VERBOSE_PREFIX_3 "SMS protocol 2 detected\n");
1676                                 h->protocol = 2;
1677                                 h->imsg[0] = 0xff;      /* special message (fake) */
1678                                 h->imsg[1] = h->imsg[2] = 0x00;
1679                                 h->ierr = h->ibitn = h->ibytep = h->ibytec = 0;
1680                                 sms_messagerx(h);
1681                         }
1682                         h->ierr = h->ibitn = h->ibytep = h->ibytec = 0;
1683                 }
1684                 if (h->ibitn) {
1685                         h->iphasep += 12;
1686                         if (h->iphasep >= 80) {                                 /* next bit */
1687                                 h->iphasep -= 80;
1688                                 if (h->ibitn++ == 9) {                          /* end of byte */
1689                                         if (!bit) { /* bad stop bit */
1690                                                 ast_log(LOG_NOTICE, "bad stop bit");
1691                                                 h->ierr = 0xFF; /* unknown error */
1692                                         } else {
1693                                                 if (h->ibytep < sizeof(h->imsg)) {
1694                                                         h->imsg[h->ibytep] = h->ibytev;
1695                                                         h->ibytec += h->ibytev;
1696                                                         h->ibytep++;
1697                                                 } else if (h->ibytep == sizeof(h->imsg)) {
1698                                                         ast_log(LOG_NOTICE, "msg too large");
1699                                                         h->ierr = 2; /* bad message length */
1700                                                 }
1701                                                 if (h->ibytep > 1 && h->ibytep == 3 + h->imsg[1] && !h->ierr) {
1702                                                         if (!h->ibytec)
1703                                                                 sms_messagerx(h);
1704                                                         else {
1705                                                                 ast_log(LOG_NOTICE, "bad checksum");
1706                                                                 h->ierr = 1;            /* bad checksum */
1707                                                         }
1708                                                 }
1709                                         }
1710                                         h->ibitn = 0;
1711                                 }
1712                                 h->ibytev = (h->ibytev >> 1) + (bit ? 0x80 : 0);
1713                         }
1714                 }
1715         }
1716 }
1717
1718 /*
1719  * Standard argument parsing:
1720  *      - one enum for the flags we recognise,
1721  *      - one enum for argument indexes
1722  *      - AST_APP_OPTIONS() to drive the parsing routine
1723  *      - in the function, AST_DECLARE_APP_ARGS(...) for the arguments.
1724  */
1725 enum {
1726         OPTION_BE_SMSC  = (1 << 0),     /* act as sms center */
1727         OPTION_ANSWER   = (1 << 1),     /* answer on incoming calls */
1728         OPTION_TWO      = (1 << 2),     /* Use Protocol Two */
1729         OPTION_PAUSE    = (1 << 3),     /* pause before sending data, in ms */
1730         OPTION_SRR      = (1 << 4),     /* set srr */
1731         OPTION_DCS      = (1 << 5),     /* set dcs */
1732 } sms_flags;
1733
1734 enum {
1735         OPTION_ARG_PAUSE = 0,
1736         OPTION_ARG_ARRAY_SIZE
1737 } sms_opt_args;
1738
1739 AST_APP_OPTIONS(sms_options, {
1740         AST_APP_OPTION('s', OPTION_BE_SMSC),
1741         AST_APP_OPTION('a', OPTION_ANSWER),
1742         AST_APP_OPTION('t', OPTION_TWO),
1743         AST_APP_OPTION('r', OPTION_SRR),
1744         AST_APP_OPTION('o', OPTION_DCS),
1745         AST_APP_OPTION_ARG('p', OPTION_PAUSE, OPTION_ARG_PAUSE),
1746         } );
1747
1748 static int sms_exec(struct ast_channel *chan, void *data)
1749 {
1750         int res = -1;
1751         struct ast_module_user *u;
1752         sms_t h = { 0 };
1753         /* argument parsing support */
1754         struct ast_flags sms_flags;
1755         char *parse, *sms_opts[OPTION_ARG_ARRAY_SIZE];
1756         char *p;
1757         AST_DECLARE_APP_ARGS(sms_args,
1758                 AST_APP_ARG(queue);
1759                 AST_APP_ARG(options);
1760                 AST_APP_ARG(addr);
1761                 AST_APP_ARG(body);
1762         );
1763
1764         if (!data) {
1765                 ast_log(LOG_ERROR, "Requires queue name at least\n");
1766                 return -1;
1767         }
1768
1769         parse = ast_strdupa(data);      /* create a local copy */
1770         AST_STANDARD_APP_ARGS(sms_args, parse);
1771         if (sms_args.argc > 1)
1772                 ast_app_parse_options(sms_options, &sms_flags, sms_opts, sms_args.options);
1773
1774         ast_verbose("sms argc %d queue <%s> opts <%s> addr <%s> body <%s>\n",
1775                 sms_args.argc, S_OR(sms_args.queue, ""),
1776                 S_OR(sms_args.options, ""),
1777                 S_OR(sms_args.addr, ""),
1778                 S_OR(sms_args.body, "") );
1779
1780         u = ast_module_user_add(chan);
1781         h.ipc0 = h.ipc1 = 20;           /* phase for cosine */
1782         h.dcs = 0xF1;                   /* default */
1783
1784         if (chan->cid.cid_num)
1785                 ast_copy_string(h.cli, chan->cid.cid_num, sizeof(h.cli));
1786
1787         if (ast_strlen_zero(sms_args.queue)) {
1788                 ast_log(LOG_ERROR, "Requires queue name\n");
1789                 goto done;
1790         }
1791         if (strlen(sms_args.queue) >= sizeof(h.queue)) {
1792                 ast_log(LOG_ERROR, "Queue name too long\n");
1793                 goto done;
1794         }
1795         ast_copy_string(h.queue, sms_args.queue, sizeof(h.queue));
1796
1797         for (p = h.queue; *p; p++)
1798                 if (!isalnum(*p))
1799                         *p = '-';                         /* make very safe for filenames */
1800
1801         h.smsc = ast_test_flag(&sms_flags, OPTION_BE_SMSC);
1802         h.protocol = ast_test_flag(&sms_flags, OPTION_TWO) ? 2 : 1;
1803         if (!ast_strlen_zero(sms_opts[OPTION_ARG_PAUSE]))
1804                 h.opause_0 = atoi(sms_opts[OPTION_ARG_PAUSE]);
1805         if (h.opause_0 < 25 || h.opause_0 > 2000)
1806                 h.opause_0 = 300;       /* default 300ms */
1807         ast_verbose("initial delay %dms\n", h.opause_0);
1808
1809
1810         /* the following apply if there is an arg3/4 and apply to the created message file */
1811         if (ast_test_flag(&sms_flags, OPTION_SRR))
1812                 h.srr = 1;
1813         if (ast_test_flag(&sms_flags, OPTION_DCS))
1814                 h.dcs = 1;
1815 #if 0   
1816                 case '1':
1817                 case '2':
1818                 case '3':
1819                 case '4':
1820                 case '5':
1821                 case '6':
1822                 case '7':                                /* set the pid for saved local message */
1823                         h.pid = 0x40 + (*d & 0xF);
1824                         break;
1825                 }
1826 #endif
1827         if (sms_args.argc > 2) {
1828                 unsigned char *up;
1829
1830                 /* submitting a message, not taking call. */
1831                 /* deprecated, use smsq instead */
1832                 h.scts = time(NULL);
1833                 if (ast_strlen_zero(sms_args.addr) || strlen(sms_args.addr) >= sizeof(h.oa)) {
1834                         ast_log(LOG_ERROR, "Address too long %s\n", sms_args.addr);
1835                         goto done;
1836                 }
1837                 if (h.smsc)
1838                         ast_copy_string(h.oa, sms_args.addr, sizeof(h.oa));
1839                 else {
1840                         ast_copy_string(h.da, sms_args.addr, sizeof(h.da));
1841                         ast_copy_string(h.oa, h.cli, sizeof(h.oa));
1842                 }
1843                 h.udl = 0;
1844                 if (ast_strlen_zero(sms_args.body)) {
1845                         ast_log(LOG_ERROR, "Missing body for %s\n", sms_args.addr);
1846                         goto done;
1847                 }
1848                 up = (unsigned char *)sms_args.body;
1849                 while (*up && h.udl < SMSLEN)
1850                         h.ud[h.udl++] = utf8decode(&up);
1851                 if (is7bit(h.dcs) && packsms7(0, h.udhl, h.udh, h.udl, h.ud) < 0) {
1852                         ast_log(LOG_WARNING, "Invalid 7 bit GSM data\n");
1853                         goto done;
1854                 }
1855                 if (is8bit(h.dcs) && packsms8(0, h.udhl, h.udh, h.udl, h.ud) < 0) {
1856                         ast_log(LOG_WARNING, "Invalid 8 bit data\n");
1857                         goto done;
1858                 }
1859                 if (is16bit(h.dcs) && packsms16(0, h.udhl, h.udh, h.udl, h.ud) < 0) {
1860                         ast_log(LOG_WARNING, "Invalid 16 bit data\n");
1861                         goto done;
1862                 }
1863                 h.rx = 0;                                 /* sent message */
1864                 h.mr = -1;
1865                 sms_writefile(&h);
1866                 res = h.err;
1867                 goto done;
1868         }
1869
1870         if (ast_test_flag(&sms_flags, OPTION_ANSWER)) {
1871                 h.framenumber = 1;           /* Proto 2 */
1872                 /* set up SMS_EST initial message */
1873                 if (h.protocol == 2) {
1874                         h.omsg[0] = DLL2_SMS_EST;
1875                         h.omsg[1] = 0;
1876                 } else {
1877                         h.omsg[0] = DLL1_SMS_EST | DLL1_SMS_COMPLETE;
1878                         h.omsg[1] = 0;
1879                 }
1880                 sms_messagetx(&h);
1881         }
1882
1883         if (chan->_state != AST_STATE_UP)
1884                 ast_answer(chan);
1885
1886         res = ast_set_write_format(chan, __OUT_FMT);
1887         if (res >= 0)
1888                 res = ast_set_read_format(chan, AST_FORMAT_SLINEAR);
1889         if (res < 0) {
1890                 ast_log(LOG_ERROR, "Unable to set to linear mode, giving up\n");
1891                 goto done;
1892         }
1893
1894         if ( (res = ast_activate_generator(chan, &smsgen, &h)) < 0) {
1895                 ast_log(LOG_ERROR, "Failed to activate generator on '%s'\n", chan->name);
1896                 goto done;
1897         }
1898
1899         /* Do our thing here */
1900         for (;;) {
1901                 struct ast_frame *f;
1902                 int i = ast_waitfor(chan, -1);
1903                 if (i < 0) {
1904                         ast_log(LOG_NOTICE, "waitfor failed\n");
1905                         break;
1906                 }
1907                 if (h.hangup) {
1908                         ast_log(LOG_NOTICE, "channel hangup\n");
1909                         break;
1910                 }
1911                 f = ast_read(chan);
1912                 if (!f) {
1913                         ast_log(LOG_NOTICE, "ast_read failed\n");
1914                         break;
1915                 }
1916                 if (f->frametype == AST_FRAME_VOICE) {
1917                         sms_process(&h, f->samples, f->data);
1918                 }
1919
1920                 ast_frfree(f);
1921         }
1922         res = h.err;    /* XXX */
1923
1924         sms_log(&h, '?');                         /* log incomplete message */
1925 done:
1926         ast_module_user_remove(u);
1927         return (res);
1928 }
1929
1930 static int unload_module(void)
1931 {
1932         return ast_unregister_application(app);
1933 }
1934
1935 static int load_module(void)
1936 {
1937 #ifdef OUTALAW
1938         int p;
1939         for (p = 0; p < 80; p++)
1940                 wavea[p] = AST_LIN2A (wave[p]);
1941 #endif
1942         snprintf(log_file, sizeof(log_file), "%s/sms", ast_config_AST_LOG_DIR);
1943         return ast_register_application(app, sms_exec, synopsis, descrip);
1944 }
1945
1946 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "SMS/PSTN handler");