From coding guidelines:
[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 static char spool_dir[255];
76
77 static char *app = "SMS";
78
79 static char *synopsis = "Communicates with SMS service centres and SMS capable analogue phones";
80
81 static char *descrip =
82         "  SMS(name|[a][s][t][p(d)][r][o]|addr|body):\n"
83         "SMS handles exchange of SMS data with a call to/from SMS capable\n"
84         "phone or SMS PSTN service center. Can send and/or receive SMS messages.\n"
85         "Works to ETSI ES 201 912 compatible with BT SMS PSTN service in UK\n"
86         "and Telecom Italia in Italy.\n"
87         "Typical usage is to use to handle called from the SMS service centre CLI,\n"
88         "or to set up a call using 'outgoing' or manager interface to connect\n"
89         "service centre to SMS()\n"
90         "name is the name of the queue used in /var/spool/asterisk/sms\n"
91         "Arguments:\n"
92         " a: answer, i.e. send initial FSK packet.\n"
93         " s: act as service centre talking to a phone.\n"
94         " t: use protocol 2 (default used is protocol 1).\n"
95         " p(N): set the initial delay to N ms (default is 300).\n"
96         "addr and body are a deprecated format to send messages out.\n"
97         " s: set the Status Report Request (SRR) bit.\n"
98         " o: the body should be coded as octets not 7-bit symbols.\n"
99         "Messages are processed as per text file message queues.\n" 
100         "smsq (a separate software) is a command to generate message\n"
101         "queues and send messages.\n"
102         "NOTE: the protocol has tight delay bounds. Please use short frames\n"
103         "and disable/keep short the jitter buffer on the ATA to make sure that\n"
104         "respones (ACK etc.) are received in time.\n";
105
106 /*
107  * 80 samples of a single period of the wave. At 8000 Hz, it means these
108  * are the samples of a 100 Hz signal.
109  * To pick the two carriers (1300Hz for '1' and 2100 Hz for '0') used by
110  * the modulation, we should take one every 13 and 21 samples respectively.
111  */
112 static signed short wave[] = {
113         0, 392, 782, 1167, 1545, 1913, 2270, 2612, 2939, 3247, 3536, 3802, 4045, 4263, 4455, 4619, 4755, 4862, 4938, 4985,
114         5000, 4985, 4938, 4862, 4755, 4619, 4455, 4263, 4045, 3802, 3536, 3247, 2939, 2612, 2270, 1913, 1545, 1167, 782, 392,
115         0, -392, -782, -1167,
116          -1545, -1913, -2270, -2612, -2939, -3247, -3536, -3802, -4045, -4263, -4455, -4619, -4755, -4862, -4938, -4985, -5000,
117         -4985, -4938, -4862,
118         -4755, -4619, -4455, -4263, -4045, -3802, -3536, -3247, -2939, -2612, -2270, -1913, -1545, -1167, -782, -392
119 };
120
121 #ifdef OUTALAW
122 static unsigned char wavea[80];
123 typedef unsigned char output_t;
124 static const output_t *wave_out = wavea;        /* outgoing samples */
125 #define __OUT_FMT AST_FORMAT_ALAW;
126 #else
127 typedef signed short output_t;
128 static const output_t *wave_out = wave;         /* outgoing samples */
129 #define __OUT_FMT AST_FORMAT_SLINEAR
130 #endif
131
132 #define OSYNC_BITS      80      /* initial sync bits */
133
134 /*!
135  * The SMS spec ETSI ES 201 912 defines two protocols with different message types.
136  * Also note that the high bit is used to indicate whether the message
137  * is complete or not, but in two opposite ways:
138  * for Protocol 1, 0x80 means that the message is complete;
139  * for Protocol 2, 0x00 means that the message is complete;
140  */
141 enum message_types {
142         DLL_SMS_MASK    = 0x7f, /* mask for the valid bits */
143
144         /* Protocol 1 values */
145         DLL1_SMS_DATA           = 0x11, /* data packet */
146         DLL1_SMS_ERROR          = 0x12,
147         DLL1_SMS_EST            = 0x13, /* start the connection */
148         DLL1_SMS_REL            = 0x14, /* end the connection */
149         DLL1_SMS_ACK            = 0x15,
150         DLL1_SMS_NACK           = 0x16,
151
152         DLL1_SMS_COMPLETE       = 0x80, /* packet is complete */
153         DLL1_SMS_MORE           = 0x00, /* more data to follow */
154
155         /* Protocol 2 values */
156         DLL2_SMS_EST            = 0x7f, /* magic number. No message body */
157         DLL2_SMS_INFO_MO        = 0x10,
158         DLL2_SMS_INFO_MT        = 0x11,
159         DLL2_SMS_INFO_STA       = 0x12,
160         DLL2_SMS_NACK           = 0x13,
161         DLL2_SMS_ACK0           = 0x14, /* ack even-numbered frame */
162         DLL2_SMS_ACK1           = 0x15, /* ack odd-numbered frame */
163         DLL2_SMS_ENQ            = 0x16,
164         DLL2_SMS_REL            = 0x17, /* end the connection */
165
166         DLL2_SMS_COMPLETE       = 0x00, /* packet is complete */
167         DLL2_SMS_MORE           = 0x80, /* more data to follow */
168 };
169
170 /* SMS 7 bit character mapping to UCS-2 */
171 static const unsigned short defaultalphabet[] = {
172         0x0040, 0x00A3, 0x0024, 0x00A5, 0x00E8, 0x00E9, 0x00F9, 0x00EC,
173         0x00F2, 0x00E7, 0x000A, 0x00D8, 0x00F8, 0x000D, 0x00C5, 0x00E5,
174         0x0394, 0x005F, 0x03A6, 0x0393, 0x039B, 0x03A9, 0x03A0, 0x03A8,
175         0x03A3, 0x0398, 0x039E, 0x00A0, 0x00C6, 0x00E6, 0x00DF, 0x00C9,
176         ' ', '!', '"', '#', 164, '%', '&', 39, '(', ')', '*', '+', ',', '-', '.', '/',
177         '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?',
178         161, 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
179         'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 196, 214, 209, 220, 167,
180         191, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
181         'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 228, 246, 241, 252, 224,
182 };
183
184 static const unsigned short escapes[] = {
185         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x000C, 0, 0, 0, 0, 0,
186         0, 0, 0, 0, 0x005E, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
187         0, 0, 0, 0, 0, 0, 0, 0, 0x007B, 0x007D, 0, 0, 0, 0, 0, 0x005C,
188         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x005B, 0x007E, 0x005D, 0,
189         0x007C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
190         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
191         0, 0, 0, 0, 0, 0x20AC, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
192         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
193 };
194
195 #define SMSLEN          160              /*!< max SMS length */
196 #define SMSLEN_8        140              /*!< max SMS length for 8-bit char */
197
198 typedef struct sms_s {
199         unsigned char hangup;        /*!< we are done... */
200         unsigned char err;           /*!< set for any errors */
201         unsigned char smsc:1;        /*!< we are SMSC */
202         unsigned char rx:1;          /*!< this is a received message */
203         char queue[30];              /*!< queue name */
204         char oa[20];                 /*!< originating address */
205         char da[20];                 /*!< destination address */
206         time_t scts;                 /*!< time stamp, UTC */
207         unsigned char pid;           /*!< protocol ID */
208         unsigned char dcs;           /*!< data coding scheme */
209         short mr;                    /*!< message reference - actually a byte, but use -1 for not set */
210         int udl;                     /*!< user data length */
211         int udhl;                    /*!< user data header length */
212         unsigned char srr:1;         /*!< Status Report request */
213         unsigned char udhi:1;        /*!< User Data Header required, even if length 0 */
214         unsigned char rp:1;          /*!< Reply Path */
215         unsigned int vp;             /*!< validity period in minutes, 0 for not set */
216         unsigned short ud[SMSLEN];   /*!< user data (message), UCS-2 coded */
217         unsigned char udh[SMSLEN];   /*!< user data header */
218         char cli[20];                /*!< caller ID */
219         unsigned char ophase;        /*!< phase (0-79) for 0 and 1 frequencies (1300Hz and 2100Hz) */
220         unsigned char ophasep;       /*!< phase (0-79) for 1200 bps */
221         unsigned char obyte;         /*!< byte being sent */
222         unsigned int opause;         /*!< silent pause before sending (in sample periods) */
223         unsigned char obitp;         /*!< bit in byte */
224         unsigned char osync;         /*!< sync bits to send */
225         unsigned char obytep;        /*!< byte in data */
226         unsigned char obyten;        /*!< bytes in data */
227         unsigned char omsg[256];     /*!< data buffer (out) */
228         unsigned char imsg[250];     /*!< data buffer (in) */
229         signed long long ims0,
230                 imc0,
231                 ims1,
232                 imc1;                      /*!< magnitude averages sin/cos 0/1 */
233         unsigned int idle;
234         unsigned short imag;         /*!< signal level */
235         unsigned char ips0;          /*!< phase sin for bit 0, start at  0 inc by 21 mod 80 */
236         unsigned char ips1;          /*!< phase cos for bit 0, start at 20 inc by 21 mod 80 */
237         unsigned char ipc0;          /*!< phase sin for bit 1, start at  0 inc by 13 mod 80 */
238         unsigned char ipc1;          /*!< phase cos for bit 1, start at 20 inc by 13 mod 80 */
239         unsigned char ibitl;         /*!< last bit */
240         unsigned char ibitc;         /*!< bit run length count */
241         unsigned char iphasep;       /*!< bit phase (0-79) for 1200 bps */
242         unsigned char ibitn;         /*!< bit number in byte being received */
243         unsigned char ibytev;        /*!< byte value being received */
244         unsigned char ibytep;        /*!< byte pointer in message */
245         unsigned char ibytec;        /*!< byte checksum for message */
246         unsigned char ierr;          /*!< error flag */
247         unsigned char ibith;         /*!< history of last bits */
248         unsigned char ibitt;         /*!< total of 1's in last 3 bytes */
249         /* more to go here */
250
251         int     opause_0;               /*!< initial delay in ms, p() option */
252         int protocol;                /*!< ETSI SMS protocol to use (passed at app call) */
253         int oseizure;                /*!< protocol 2: channel seizure bits to send */
254         int framenumber;             /*!< protocol 2: frame number (for sending ACK0 or ACK1) */
255         char udtxt[SMSLEN]; /*!< user data (message), PLAIN text */
256 } sms_t;
257
258 /* different types of encoding */
259 #define is7bit(dcs)     ( ((dcs) & 0xC0) ? (!((dcs)&4) ) : (((dcs) & 0xc) == 0) )
260 #define is8bit(dcs)     ( ((dcs) & 0xC0) ? ( ((dcs)&4) ) : (((dcs) & 0xc) == 4) )
261 #define is16bit(dcs)    ( ((dcs) & 0xC0) ? 0             : (((dcs) & 0xc) == 8) )
262
263 static void sms_messagetx (sms_t * h);
264
265 /*! \brief copy number, skipping non digits apart from leading + */
266 static void numcpy(char *d, char *s)
267 {
268         if (*s == '+')
269                 *d++ = *s++;
270         while (*s) {
271                 if (isdigit (*s))
272                         *d++ = *s;
273                 s++;
274         }
275         *d = 0;
276 }
277
278 /*! \brief static, return a date/time in ISO format */
279 static char * isodate(time_t t, char *buf, int len)
280 {
281         strftime(buf, len, "%Y-%m-%dT%H:%M:%S", localtime (&t));
282         return buf;
283 }
284
285 /*! \brief Reads next UCS character from NUL terminated UTF-8 string and advance pointer */
286 /* for non valid UTF-8 sequences, returns character as is */
287 /* Does not advance pointer for null termination */
288 static long utf8decode(unsigned char **pp)
289 {
290         unsigned char *p = *pp;
291         if (!*p)
292                 return 0;                 /* null termination of string */
293         (*pp)++;
294         if (*p < 0xC0)
295                 return *p;                /* ascii or continuation character */
296         if (*p < 0xE0) {
297                 if (*p < 0xC2 || (p[1] & 0xC0) != 0x80)
298                         return *p;             /* not valid UTF-8 */
299                 (*pp)++;
300                 return ((*p & 0x1F) << 6) + (p[1] & 0x3F);
301         }
302         if (*p < 0xF0) {
303                 if ((*p == 0xE0 && p[1] < 0xA0) || (p[1] & 0xC0) != 0x80 || (p[2] & 0xC0) != 0x80)
304                          return *p;             /* not valid UTF-8 */
305                 (*pp) += 2;
306                 return ((*p & 0x0F) << 12) + ((p[1] & 0x3F) << 6) + (p[2] & 0x3F);
307         }
308         if (*p < 0xF8) {
309                 if ((*p == 0xF0 && p[1] < 0x90) || (p[1] & 0xC0) != 0x80 || (p[2] & 0xC0) != 0x80 || (p[3] & 0xC0) != 0x80)
310                         return *p;             /* not valid UTF-8 */
311                 (*pp) += 3;
312                 return ((*p & 0x07) << 18) + ((p[1] & 0x3F) << 12) + ((p[2] & 0x3F) << 6) + (p[3] & 0x3F);
313         }
314         if (*p < 0xFC) {
315                 if ((*p == 0xF8 && p[1] < 0x88) || (p[1] & 0xC0) != 0x80 || (p[2] & 0xC0) != 0x80 || (p[3] & 0xC0) != 0x80
316                         || (p[4] & 0xC0) != 0x80)
317                         return *p;             /* not valid UTF-8 */
318                 (*pp) += 4;
319                 return ((*p & 0x03) << 24) + ((p[1] & 0x3F) << 18) + ((p[2] & 0x3F) << 12) + ((p[3] & 0x3F) << 6) + (p[4] & 0x3F);
320         }
321         if (*p < 0xFE) {
322                 if ((*p == 0xFC && p[1] < 0x84) || (p[1] & 0xC0) != 0x80 || (p[2] & 0xC0) != 0x80 || (p[3] & 0xC0) != 0x80
323                         || (p[4] & 0xC0) != 0x80 || (p[5] & 0xC0) != 0x80)
324                         return *p;             /* not valid UTF-8 */
325                 (*pp) += 5;
326                 return ((*p & 0x01) << 30) + ((p[1] & 0x3F) << 24) + ((p[2] & 0x3F) << 18) + ((p[3] & 0x3F) << 12) + ((p[4] & 0x3F) << 6) + (p[5] & 0x3F);
327         }
328         return *p;                   /* not sensible */
329 }
330
331 /*! \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 */
332 /* The return value is the number of septets packed in to o, which is internally limited to SMSLEN */
333 /* o can be null, in which case this is used to validate or count only */
334 /* if the input contains invalid characters then the return value is -1 */
335 static int packsms7(unsigned char *o, int udhl, unsigned char *udh, int udl, unsigned short *ud)
336 {
337         unsigned char p = 0;    /* output pointer (bytes) */
338         unsigned char b = 0;    /* bit position */
339         unsigned char n = 0;    /* output character count */
340         unsigned char dummy[SMSLEN];
341
342         if (o == NULL)          /* output to a dummy buffer if o not set */
343                 o = dummy;
344
345         if (udhl) {                            /* header */
346                 o[p++] = udhl;
347                 b = 1;
348                 n = 1;
349                 while (udhl--) {
350                         o[p++] = *udh++;
351                         b += 8;
352                         while (b >= 7) {
353                                 b -= 7;
354                                 n++;
355                         }
356                         if (n >= SMSLEN)
357                                 return n;
358                 }
359                 if (b) {
360                         b = 7 - b;
361                         if (++n >= SMSLEN)
362                                 return n;
363                 };      /* filling to septet boundary */
364         }
365         o[p] = 0;
366         /* message */
367         while (udl--) {
368                 long u;
369                 unsigned char v;
370                 u = *ud++;
371                 /* XXX 0 is invalid ? */
372                 /* look up in defaultalphabet[]. If found, v is the 7-bit code */
373                 for (v = 0; v < 128 && defaultalphabet[v] != u; v++);
374                 if (v == 128 /* not found */ && u && n + 1 < SMSLEN) {
375                         /* if not found, look in the escapes table (we need 2 bytes) */
376                         for (v = 0; v < 128 && escapes[v] != u; v++);
377                         if (v < 128) {  /* escaped sequence, esc + v */
378                                 /* store the low (8-b) bits in o[p], the remaining bits in o[p+1] */
379                                 o[p] |= (27 << b);      /* the low bits go into o[p] */ 
380                                 b += 7;
381                                 if (b >= 8) {
382                                         b -= 8;
383                                         p++;
384                                         o[p] = (27 >> (7 - b));
385                                 }
386                                 n++;
387                         }
388                 }
389                 if (v == 128)
390                         return -1;             /* invalid character */
391                 /* store, same as above */
392                 o[p] |= (v << b);
393                 b += 7;
394                 if (b >= 8) {
395                         b -= 8;
396                         p++;
397                         o[p] = (v >> (7 - b));
398                 }
399                 if (++n >= SMSLEN)
400                         return n;
401         }
402         return n;
403 }
404
405 /*! \brief takes a binary header (udhl bytes at udh) and UCS-2 message (udl characters at ud)
406  * and packs in to o using 8 bit character codes.
407  * The return value is the number of bytes packed in to o, which is internally limited to 140.
408  * o can be null, in which case this is used to validate or count only.
409  * if the input contains invalid characters then the return value is -1
410  */
411 static int packsms8(unsigned char *o, int udhl, unsigned char *udh, int udl, unsigned short *ud)
412 {
413         unsigned char p = 0;
414         unsigned char dummy[SMSLEN_8];
415
416         if (o == NULL)
417                 o = dummy;
418         /* header - no encoding */
419         if (udhl) {
420                 o[p++] = udhl;
421                 while (udhl--) {
422                         o[p++] = *udh++;
423                         if (p >= SMSLEN_8)
424                                 return p;
425                 }
426         }
427         while (udl--) {
428                 long u;
429                 u = *ud++;
430                 if (u < 0 || u > 0xFF)
431                         return -1;             /* not valid */
432                 o[p++] = u;
433                 if (p >= SMSLEN_8)
434                         return p;
435         }
436         return p;
437 }
438
439 /*! \brief takes a binary header (udhl bytes at udh) and UCS-2 
440         message (udl characters at ud) and packs in to o using 16 bit 
441         UCS-2 character codes 
442         The return value is the number of bytes packed in to o, which is 
443         internally limited to 140 
444         o can be null, in which case this is used to validate or count 
445         only if the input contains invalid characters then 
446         the return value is -1 */
447 static int packsms16(unsigned char *o, int udhl, unsigned char *udh, int udl, unsigned short *ud)
448 {
449         unsigned char p = 0;
450         unsigned char dummy[SMSLEN_8];
451
452         if (o == NULL)
453                 o = dummy;
454         /* header - no encoding */
455         if (udhl) {
456                 o[p++] = udhl;
457                 while (udhl--) {
458                         o[p++] = *udh++;
459                         if (p >= SMSLEN_8)
460                                 return p;
461                 }
462         }
463         while (udl--) {
464                 long u;
465                 u = *ud++;
466                 o[p++] = (u >> 8);
467                 if (p >= SMSLEN_8)
468                         return p - 1;          /* could not fit last character */
469                 o[p++] = u;
470                 if (p >= SMSLEN_8)
471                         return p;
472         }
473         return p;
474 }
475
476 /*! \brief general pack, with length and data, 
477         returns number of bytes of target used */
478 static int packsms(unsigned char dcs, unsigned char *base, unsigned int udhl, unsigned char *udh, int udl, unsigned short *ud)
479 {
480         unsigned char *p = base;
481         if (udl == 0)
482                 *p++ = 0;                       /* no user data */
483         else {
484                 
485                 int l = 0;
486                 if (is7bit(dcs)) {              /* 7 bit */
487                         l = packsms7(p + 1, udhl, udh, udl, ud);
488                         if (l < 0)
489                                 l = 0;
490                         *p++ = l;
491                         p += (l * 7 + 7) / 8;
492                 } else if (is8bit(dcs)) {       /* 8 bit */
493                         l = packsms8(p + 1, udhl, udh, udl, ud);
494                         if (l < 0)
495                                 l = 0;
496                         *p++ = l;
497                         p += l;
498                 } else {                        /* UCS-2 */
499                         l = packsms16(p + 1, udhl, udh, udl, ud);
500                         if (l < 0)
501                                 l = 0;
502                         *p++ = l;
503                         p += l;
504                 }
505         }
506         return p - base;
507 }
508
509
510 /*! \brief pack a date and return */
511 static void packdate(unsigned char *o, time_t w)
512 {
513         struct tm *t = localtime (&w);
514 #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined( __NetBSD__ ) || defined(__APPLE__)
515         int z = -t->tm_gmtoff / 60 / 15;
516 #else
517         int z = timezone / 60 / 15;
518 #endif
519         *o++ = ((t->tm_year % 10) << 4) + (t->tm_year % 100) / 10;
520         *o++ = (((t->tm_mon + 1) % 10) << 4) + (t->tm_mon + 1) / 10;
521         *o++ = ((t->tm_mday % 10) << 4) + t->tm_mday / 10;
522         *o++ = ((t->tm_hour % 10) << 4) + t->tm_hour / 10;
523         *o++ = ((t->tm_min % 10) << 4) + t->tm_min / 10;
524         *o++ = ((t->tm_sec % 10) << 4) + t->tm_sec / 10;
525         if (z < 0)
526                 *o++ = (((-z) % 10) << 4) + (-z) / 10 + 0x08;
527         else
528                 *o++ = ((z % 10) << 4) + z / 10;
529 }
530
531 /*! \brief unpack a date and return */
532 static time_t unpackdate (unsigned char *i)
533 {
534         struct tm t;
535         t.tm_year = 100 + (i[0] & 0xF) * 10 + (i[0] >> 4);
536         t.tm_mon = (i[1] & 0xF) * 10 + (i[1] >> 4) - 1;
537         t.tm_mday = (i[2] & 0xF) * 10 + (i[2] >> 4);
538         t.tm_hour = (i[3] & 0xF) * 10 + (i[3] >> 4);
539         t.tm_min = (i[4] & 0xF) * 10 + (i[4] >> 4);
540         t.tm_sec = (i[5] & 0xF) * 10 + (i[5] >> 4);
541         t.tm_isdst = 0;
542         if (i[6] & 0x08)
543                 t.tm_min += 15 * ((i[6] & 0x7) * 10 + (i[6] >> 4));
544         else
545                 t.tm_min -= 15 * ((i[6] & 0x7) * 10 + (i[6] >> 4));
546         return mktime (&t);
547 }
548
549 /*! \brief unpacks bytes (7 bit encoding) at i, len l septets, 
550         and places in udh and ud setting udhl and udl. udh not used 
551         if udhi not set */
552 static void unpacksms7(unsigned char *i, unsigned char l, unsigned char *udh, int *udhl, unsigned short *ud, int *udl, char udhi)
553 {
554         unsigned char b = 0, p = 0;
555         unsigned short *o = ud;
556         *udhl = 0;
557         if (udhi && l) {                 /* header */
558                 int h = i[p];
559                 *udhl = h;
560                 if (h) {
561                         b = 1;
562                         p++;
563                         l--;
564                         while (h-- && l) {
565                                 *udh++ = i[p++];
566                                 b += 8;
567                                 while (b >= 7) {
568                                         b -= 7;
569                                         l--;
570                                         if (!l)
571                                                 break;
572                                 }
573                         }
574                         /* adjust for fill, septets */
575                         if (b) {
576                                 b = 7 - b;
577                                 l--;
578                         }
579                 }
580         }
581         while (l--) {
582                 unsigned char v;
583                 if (b < 2)
584                         v = ((i[p] >> b) & 0x7F);       /* everything in one byte */
585                 else
586                         v = ((((i[p] >> b) + (i[p + 1] << (8 - b)))) & 0x7F);
587                 b += 7;
588                 if (b >= 8) {
589                         b -= 8;
590                         p++;
591                 }
592                 /* 0x00A0 is the encoding of ESC (27) in defaultalphabet */
593                 if (o > ud && o[-1] == 0x00A0 && escapes[v])
594                         o[-1] = escapes[v];
595                 else
596                         *o++ = defaultalphabet[v];
597         }
598         *udl = (o - ud);
599 }
600
601 /*! \brief unpacks bytes (8 bit encoding) at i, len l septets, 
602       and places in udh and ud setting udhl and udl. udh not used 
603       if udhi not set */
604 static void unpacksms8(unsigned char *i, unsigned char l, unsigned char *udh, int *udhl, unsigned short *ud, int *udl, char udhi)
605 {
606         unsigned short *o = ud;
607         *udhl = 0;
608         if (udhi) {
609                 int n = *i;
610                 *udhl = n;
611                 if (n) {
612                         i++;
613                         l--;
614                         while (l && n) {
615                                 l--;
616                                 n--;
617                                 *udh++ = *i++;
618                         }
619                 }
620         }
621         while (l--)
622                 *o++ = *i++;      /* not to UTF-8 as explicitly 8 bit coding in DCS */
623         *udl = (o - ud);
624 }
625
626 /*! \brief unpacks bytes (16 bit encoding) at i, len l septets,
627          and places in udh and ud setting udhl and udl. 
628         udh not used if udhi not set */
629 static void unpacksms16(unsigned char *i, unsigned char l, unsigned char *udh, int *udhl, unsigned short *ud, int *udl, char udhi)
630 {
631         unsigned short *o = ud;
632         *udhl = 0;
633         if (udhi) {
634                 int n = *i;
635                 *udhl = n;
636                 if (n) {
637                         i++;
638                         l--;
639                         while (l && n) {
640                                 l--;
641                                 n--;
642                                 *udh++ = *i++;
643                         }
644                 }
645         }
646         while (l--) {
647                 int v = *i++;
648                 if (l--)
649                         v = (v << 8) + *i++;
650                 *o++ = v;
651         }
652         *udl = (o - ud);
653 }
654
655 /*! \brief general unpack - starts with length byte (octet or septet) and returns number of bytes used, inc length */
656 static int unpacksms(unsigned char dcs, unsigned char *i, unsigned char *udh, int *udhl, unsigned short *ud, int *udl, char udhi)
657 {
658         int l = *i++;
659         if (is7bit (dcs)) {
660                 unpacksms7 (i, l, udh, udhl, ud, udl, udhi);
661                 l = (l * 7 + 7) / 8;            /* adjust length to return */
662         } else if (is8bit (dcs))
663                 unpacksms8 (i, l, udh, udhl, ud, udl, udhi);
664         else
665                 unpacksms16 (i, l, udh, udhl, ud, udl, udhi);
666         return l + 1;
667 }
668
669 /*! \brief unpack an address from i, return byte length, unpack to o */
670 static unsigned char unpackaddress(char *o, unsigned char *i)
671 {
672         unsigned char l = i[0],
673                 p;
674         if (i[1] == 0x91)
675                 *o++ = '+';
676         for (p = 0; p < l; p++) {
677                 if (p & 1)
678                         *o++ = (i[2 + p / 2] >> 4) + '0';
679                 else
680                         *o++ = (i[2 + p / 2] & 0xF) + '0';
681         }
682         *o = 0;
683         return (l + 5) / 2;
684 }
685
686 /*! \brief store an address at o, and return number of bytes used */
687 static unsigned char packaddress(unsigned char *o, char *i)
688 {
689         unsigned char p = 2;
690         o[0] = 0;               /* number of bytes */
691         if (*i == '+') {        /* record as bit 0 in byte 1 */
692                 i++;
693                 o[1] = 0x91;
694         } else
695                 o[1] = 0x81;
696         for ( ; *i ; i++) {
697                 if (!isdigit (*i))      /* ignore non-digits */
698                         continue;
699                 if (o[0] & 1)
700                         o[p++] |= ((*i & 0xF) << 4);
701                 else
702                         o[p] = (*i & 0xF);
703                 o[0]++;
704         }
705         if (o[0] & 1)
706                 o[p++] |= 0xF0;                   /* pad */
707         return p;
708 }
709
710 /*! \brief Log the output, and remove file */
711 static void sms_log(sms_t * h, char status)
712 {
713         int o;
714
715         if (*h->oa == '\0' && *h->da == '\0')
716                 return;
717         o = open (log_file, O_CREAT | O_APPEND | O_WRONLY, AST_FILE_MODE);
718         if (o >= 0) {
719                 char line[1000], mrs[3] = "", *p;
720                 char buf[30];
721                 unsigned char n;
722
723                 if (h->mr >= 0)
724                         snprintf (mrs, sizeof (mrs), "%02X", h->mr);
725                 snprintf (line, sizeof (line), "%s %c%c%c%s %s %s %s ",
726                         isodate(time(0), buf, sizeof(buf)),
727                         status, h->rx ? 'I' : 'O', h->smsc ? 'S' : 'M', mrs, h->queue,
728                         S_OR(h->oa, "-"), S_OR(h->da, "-") );
729                 p = line + strlen (line);
730                 for (n = 0; n < h->udl; n++) {
731                         if (h->ud[n] == '\\') {
732                                 *p++ = '\\';
733                                 *p++ = '\\';
734                         } else if (h->ud[n] == '\n') {
735                                 *p++ = '\\';
736                                 *p++ = 'n';
737                         } else if (h->ud[n] == '\r') {
738                                 *p++ = '\\';
739                                 *p++ = 'r';
740                         } else if (h->ud[n] < 32 || h->ud[n] == 127)
741                                 *p++ = 191;
742                         else
743                                 *p++ = h->ud[n];
744                 }
745                 *p++ = '\n';
746                 *p = 0;
747                 write (o, line, strlen (line));
748                 close (o);
749         }
750         *h->oa = *h->da = h->udl = 0;
751 }
752
753 /*! \brief parse and delete a file */
754 static void sms_readfile(sms_t * h, char *fn)
755 {
756         char line[1000];
757         FILE *s;
758         char dcsset = 0;                /* if DSC set */
759         ast_log (LOG_EVENT, "Sending %s\n", fn);
760         h->rx = h->udl = *h->oa = *h->da = h->pid = h->srr = h->udhi = h->rp = h->vp = h->udhl = 0;
761         h->mr = -1;
762         h->dcs = 0xF1;                  /* normal messages class 1 */
763         h->scts = time (0);
764         s = fopen (fn, "r");
765         if (s) {
766                 if (unlink (fn)) {      /* concurrent access, we lost */
767                         fclose (s);
768                         return;
769                 }
770                 while (fgets (line, sizeof (line), s)) {        /* process line in file */
771                         char *p;
772                         void *pp = &p;
773                         for (p = line; *p && *p != '\n' && *p != '\r'; p++);
774                         *p = 0;                                  /* strip eoln */
775                         p = line;
776                         if (!*p || *p == ';')
777                                 continue;                         /* blank line or comment, ignore */
778                         while (isalnum (*p)) {
779                                 *p = tolower (*p);
780                                 p++;
781                         }
782                         while (isspace (*p))
783                                 *p++ = 0;
784                         if (*p == '=') {
785                                 *p++ = 0;
786                                 if (!strcmp (line, "ud")) {      /* parse message (UTF-8) */
787                                         unsigned char o = 0;
788                                         memcpy(h->udtxt,p,SMSLEN);      /* for protocol 2 */
789                                         while (*p && o < SMSLEN)
790                                                 h->ud[o++] = utf8decode(pp);
791                                         h->udl = o;
792                                         if (*p)
793                                                 ast_log (LOG_WARNING, "UD too long in %s\n", fn);
794                                 } else {
795                                         while (isspace (*p))
796                                                 p++;
797                                         if (!strcmp (line, "oa") && strlen (p) < sizeof (h->oa))
798                                                 numcpy (h->oa, p);
799                                         else if (!strcmp (line, "da") && strlen (p) < sizeof (h->oa))
800                                                 numcpy (h->da, p);
801                                         else if (!strcmp (line, "pid"))
802                                                 h->pid = atoi (p);
803                                         else if (!strcmp (line, "dcs")) {
804                                                 h->dcs = atoi (p);
805                                                 dcsset = 1;
806                                         } else if (!strcmp (line, "mr"))
807                                                 h->mr = atoi (p);
808                                         else if (!strcmp (line, "srr"))
809                                                 h->srr = (atoi (p) ? 1 : 0);
810                                         else if (!strcmp (line, "vp"))
811                                                 h->vp = atoi (p);
812                                         else if (!strcmp (line, "rp"))
813                                                 h->rp = (atoi (p) ? 1 : 0);
814                                         else if (!strcmp (line, "scts")) {      /* get date/time */
815                                                 int Y,
816                                                   m,
817                                                   d,
818                                                   H,
819                                                   M,
820                                                   S;
821                                                 if (sscanf (p, "%d-%d-%dT%d:%d:%d", &Y, &m, &d, &H, &M, &S) == 6) {
822                                                         struct tm t;
823                                                         t.tm_year = Y - 1900;
824                                                         t.tm_mon = m - 1;
825                                                         t.tm_mday = d;
826                                                         t.tm_hour = H;
827                                                         t.tm_min = M;
828                                                         t.tm_sec = S;
829                                                         t.tm_isdst = -1;
830                                                         h->scts = mktime (&t);
831                                                         if (h->scts == (time_t) - 1)
832                                                                 ast_log (LOG_WARNING, "Bad date/timein %s: %s", fn, p);
833                                                 }
834                                         } else
835                                                 ast_log (LOG_WARNING, "Cannot parse in %s: %s=%si\n", fn, line, p);
836                                 }
837                         } else if (*p == '#') {         /* raw hex format */
838                                 *p++ = 0;
839                                 if (*p == '#') {
840                                         p++;
841                                         if (!strcmp (line, "ud")) {     /* user data */
842                                                 int o = 0;
843                                                 while (*p && o < SMSLEN) {
844                                                         if (isxdigit (*p) && isxdigit (p[1]) && isxdigit (p[2]) && isxdigit (p[3])) {
845                                                                 h->ud[o++] =
846                                                                         (((isalpha (*p) ? 9 : 0) + (*p & 0xF)) << 12) +
847                                                                         (((isalpha (p[1]) ? 9 : 0) + (p[1] & 0xF)) << 8) +
848                                                                         (((isalpha (p[2]) ? 9 : 0) + (p[2] & 0xF)) << 4) + ((isalpha (p[3]) ? 9 : 0) + (p[3] & 0xF));
849                                                                 p += 4;
850                                                         } else
851                                                                 break;
852                                                 }
853                                                 h->udl = o;
854                                                 if (*p)
855                                                         ast_log (LOG_WARNING, "UD too long / invalid UCS-2 hex in %s\n", fn);
856                                         } else
857                                                 ast_log (LOG_WARNING, "Only ud can use ## format, %s\n", fn);
858                                 } else if (!strcmp (line, "ud")) {      /* user data */
859                                         int o = 0;
860                                         while (*p && o < SMSLEN) {
861                                                 if (isxdigit (*p) && isxdigit (p[1])) {
862                                                         h->ud[o++] = (((isalpha (*p) ? 9 : 0) + (*p & 0xF)) << 4) + ((isalpha (p[1]) ? 9 : 0) + (p[1] & 0xF));
863                                                         p += 2;
864                                                 } else
865                                                         break;
866                                         }
867                                         h->udl = o;
868                                         if (*p)
869                                                 ast_log (LOG_WARNING, "UD too long / invalid UCS-1 hex in %s\n", fn);
870                                 } else if (!strcmp (line, "udh")) {     /* user data header */
871                                         unsigned char o = 0;
872                                         h->udhi = 1;
873                                         while (*p && o < SMSLEN) {
874                                                 if (isxdigit (*p) && isxdigit (p[1])) {
875                                                         h->udh[o] = (((isalpha (*p) ? 9 : 0) + (*p & 0xF)) << 4) + ((isalpha (p[1]) ? 9 : 0) + (p[1] & 0xF));
876                                                         o++;
877                                                         p += 2;
878                                                 } else
879                                                         break;
880                                         }
881                                         h->udhl = o;
882                                         if (*p)
883                                                 ast_log (LOG_WARNING, "UDH too long / invalid hex in %s\n", fn);
884                                 } else
885                                         ast_log (LOG_WARNING, "Only ud and udh can use # format, %s\n", fn);
886                         } else
887                                 ast_log (LOG_WARNING, "Cannot parse in %s: %s\n", fn, line);
888                 }
889                 fclose (s);
890                 if (!dcsset && packsms7 (0, h->udhl, h->udh, h->udl, h->ud) < 0) {
891                         if (packsms8 (0, h->udhl, h->udh, h->udl, h->ud) < 0) {
892                                 if (packsms16 (0, h->udhl, h->udh, h->udl, h->ud) < 0)
893                                         ast_log (LOG_WARNING, "Invalid UTF-8 message even for UCS-2 (%s)\n", fn);
894                                 else {
895                                         h->dcs = 0x08;  /* default to 16 bit */
896                                         ast_log (LOG_WARNING, "Sending in 16 bit format (%s)\n", fn);
897                                 }
898                         } else {
899                                 h->dcs = 0xF5;          /* default to 8 bit */
900                                 ast_log (LOG_WARNING, "Sending in 8 bit format (%s)\n", fn);
901                         }
902                 }
903                 if (is7bit (h->dcs) && packsms7 (0, h->udhl, h->udh, h->udl, h->ud) < 0)
904                         ast_log (LOG_WARNING, "Invalid 7 bit GSM data %s\n", fn);
905                 if (is8bit (h->dcs) && packsms8 (0, h->udhl, h->udh, h->udl, h->ud) < 0)
906                         ast_log (LOG_WARNING, "Invalid 8 bit data %s\n", fn);
907                 if (is16bit (h->dcs) && packsms16 (0, h->udhl, h->udh, h->udl, h->ud) < 0)
908                         ast_log (LOG_WARNING, "Invalid 16 bit data %s\n", fn);
909         }
910 }
911
912 /*! \brief white a received text message to a file */
913 static void sms_writefile(sms_t * h)
914 {
915         char fn[200] = "", fn2[200] = "";
916         char buf[30];
917         FILE *o;
918
919         ast_copy_string(fn, spool_dir, sizeof (fn));
920         mkdir(fn, 0777);                        /* ensure it exists */
921         snprintf(fn + strlen (fn), sizeof (fn) - strlen (fn), "/%s", h->smsc ? h->rx ? "morx" : "mttx" : h->rx ? "mtrx" : "motx");
922         mkdir(fn, 0777);                        /* ensure it exists */
923         ast_copy_string(fn2, fn, sizeof (fn2));
924         snprintf(fn2 + strlen (fn2), sizeof (fn2) - strlen (fn2), "/%s.%s-%d", h->queue, isodate(h->scts, buf, sizeof(buf)), seq++);
925         snprintf (fn + strlen (fn), sizeof (fn) - strlen (fn), "/.%s", fn2 + strlen (fn) + 1);
926         o = fopen (fn, "w");
927         if (o == NULL)
928                 return;
929
930         if (*h->oa)
931                 fprintf (o, "oa=%s\n", h->oa);
932         if (*h->da)
933                 fprintf (o, "da=%s\n", h->da);
934         if (h->udhi) {
935                 unsigned int p;
936                 fprintf (o, "udh#");
937                 for (p = 0; p < h->udhl; p++)
938                         fprintf (o, "%02X", h->udh[p]);
939                 fprintf (o, "\n");
940         }
941         if (h->udl) {
942                 unsigned int p;
943                 for (p = 0; p < h->udl && h->ud[p] >= ' '; p++);
944                 if (p < h->udl)
945                         fputc (';', o);   /* cannot use ud=, but include as a comment for human readable */
946                 fprintf (o, "ud=");
947                 for (p = 0; p < h->udl; p++) {
948                         unsigned short v = h->ud[p];
949                         if (v < 32)
950                                 fputc (191, o);
951                         else if (v < 0x80)
952                                 fputc (v, o);
953                         else if (v < 0x800)
954                         {
955                                 fputc (0xC0 + (v >> 6), o);
956                                 fputc (0x80 + (v & 0x3F), o);
957                         } else
958                         {
959                                 fputc (0xE0 + (v >> 12), o);
960                                 fputc (0x80 + ((v >> 6) & 0x3F), o);
961                                 fputc (0x80 + (v & 0x3F), o);
962                         }
963                 }
964                 fprintf (o, "\n");
965                 for (p = 0; p < h->udl && h->ud[p] >= ' '; p++);
966                 if (p < h->udl) {
967                         for (p = 0; p < h->udl && h->ud[p] < 0x100; p++);
968                         if (p == h->udl) {                                               /* can write in ucs-1 hex */
969                                 fprintf (o, "ud#");
970                                 for (p = 0; p < h->udl; p++)
971                                         fprintf (o, "%02X", h->ud[p]);
972                                 fprintf (o, "\n");
973                         } else {                                                 /* write in UCS-2 */
974                                 fprintf (o, "ud##");
975                                 for (p = 0; p < h->udl; p++)
976                                         fprintf (o, "%04X", h->ud[p]);
977                                 fprintf (o, "\n");
978                         }
979                 }
980         }
981         if (h->scts) {
982                 char buf[30];
983                 fprintf (o, "scts=%s\n", isodate(h->scts, buf, sizeof(buf)));
984         }
985         if (h->pid)
986                 fprintf (o, "pid=%d\n", h->pid);
987         if (h->dcs != 0xF1)
988                 fprintf (o, "dcs=%d\n", h->dcs);
989         if (h->vp)
990                 fprintf (o, "vp=%d\n", h->vp);
991         if (h->srr)
992                 fprintf (o, "srr=1\n");
993         if (h->mr >= 0)
994                 fprintf (o, "mr=%d\n", h->mr);
995         if (h->rp)
996                 fprintf (o, "rp=1\n");
997         fclose (o);
998         if (rename (fn, fn2))
999                 unlink (fn);
1000         else
1001                 ast_log (LOG_EVENT, "Received to %s\n", fn2);
1002 }
1003
1004 /*! \brief read dir skipping dot files... */
1005 static struct dirent *readdirqueue (DIR * d, char *queue)
1006 {
1007         struct dirent *f;
1008         do {
1009                 f = readdir (d);
1010         } while (f && (*f->d_name == '.' || strncmp (f->d_name, queue, strlen (queue)) || f->d_name[strlen (queue)] != '.'));
1011         return f;
1012 }
1013
1014 /*! \brief handle the incoming message */
1015 static unsigned char sms_handleincoming (sms_t * h)
1016 {
1017         unsigned char p = 3;
1018         if (h->smsc) {                                                                   /* SMSC */
1019                 if ((h->imsg[2] & 3) == 1) {                            /* SMS-SUBMIT */
1020                         h->udhl = h->udl = 0;
1021                         h->vp = 0;
1022                         h->srr = ((h->imsg[2] & 0x20) ? 1 : 0);
1023                         h->udhi = ((h->imsg[2] & 0x40) ? 1 : 0);
1024                         h->rp = ((h->imsg[2] & 0x80) ? 1 : 0);
1025                         ast_copy_string (h->oa, h->cli, sizeof (h->oa));
1026                         h->scts = time (0);
1027                         h->mr = h->imsg[p++];
1028                         p += unpackaddress (h->da, h->imsg + p);
1029                         h->pid = h->imsg[p++];
1030                         h->dcs = h->imsg[p++];
1031                         if ((h->imsg[2] & 0x18) == 0x10) {                                                       /* relative VP */
1032                                 if (h->imsg[p] < 144)
1033                                         h->vp = (h->imsg[p] + 1) * 5;
1034                                 else if (h->imsg[p] < 168)
1035                                         h->vp = 720 + (h->imsg[p] - 143) * 30;
1036                                 else if (h->imsg[p] < 197)
1037                                         h->vp = (h->imsg[p] - 166) * 1440;
1038                                 else
1039                                         h->vp = (h->imsg[p] - 192) * 10080;
1040                                 p++;
1041                         } else if (h->imsg[2] & 0x18)
1042                                 p += 7;                          /* ignore enhanced / absolute VP */
1043                         p += unpacksms (h->dcs, h->imsg + p, h->udh, &h->udhl, h->ud, &h->udl, h->udhi);
1044                         h->rx = 1;                               /* received message */
1045                         sms_writefile (h);        /* write the file */
1046                         if (p != h->imsg[1] + 2) {
1047                                 ast_log (LOG_WARNING, "Mismatch receive unpacking %d/%d\n", p, h->imsg[1] + 2);
1048                                 return 0xFF;              /* duh! */
1049                         }
1050                 } else {
1051                         ast_log (LOG_WARNING, "Unknown message type %02X\n", h->imsg[2]);
1052                         return 0xFF;
1053                 }
1054         } else {                                                                         /* client */
1055                 if (!(h->imsg[2] & 3)) {                                                                 /* SMS-DELIVER */
1056                         *h->da = h->srr = h->rp = h->vp = h->udhi = h->udhl = h->udl = 0;
1057                         h->srr = ((h->imsg[2] & 0x20) ? 1 : 0);
1058                         h->udhi = ((h->imsg[2] & 0x40) ? 1 : 0);
1059                         h->rp = ((h->imsg[2] & 0x80) ? 1 : 0);
1060                         h->mr = -1;
1061                         p += unpackaddress (h->oa, h->imsg + p);
1062                         h->pid = h->imsg[p++];
1063                         h->dcs = h->imsg[p++];
1064                         h->scts = unpackdate (h->imsg + p);
1065                         p += 7;
1066                         p += unpacksms (h->dcs, h->imsg + p, h->udh, &h->udhl, h->ud, &h->udl, h->udhi);
1067                         h->rx = 1;                               /* received message */
1068                         sms_writefile (h);        /* write the file */
1069                         if (p != h->imsg[1] + 2) {
1070                                 ast_log (LOG_WARNING, "Mismatch receive unpacking %d/%d\n", p, h->imsg[1] + 2);
1071                                 return 0xFF;              /* duh! */
1072                         }
1073                 } else {
1074                         ast_log (LOG_WARNING, "Unknown message type %02X\n", h->imsg[2]);
1075                         return 0xFF;
1076                 }
1077         }
1078         return 0;                                                 /* no error */
1079 }
1080
1081 #ifdef SOLARIS
1082 #define NAME_MAX 1024
1083 #endif
1084
1085 /*!
1086  * Add data to a protocol 2 message.
1087  * Use the length field (h->omsg[1]) as a pointer to the next free position.
1088  */
1089 static void adddata_proto2 (sms_t *h, unsigned char msg, char *data, int size)
1090 {
1091         int x = h->omsg[1]+2;   /* Get current position */
1092         if (x==2)
1093                 x += 2;         /* First: skip Payload length (set later) */
1094         h->omsg[x++] = msg;     /* Message code */
1095         h->omsg[x++]=(unsigned char)size;       /* Data size Low */
1096         h->omsg[x++]=0;         /* Data size Hi */
1097         for (; size>0 ; size--)
1098                 h->omsg[x++] = *data++;
1099         h->omsg[1] = x-2;       /* Frame size */
1100         h->omsg[2] = x-4;       /* Payload length (Lo) */
1101         h->omsg[3] = 0;         /* Payload length (Hi) */
1102 }
1103
1104 static void putdummydata_proto2 (sms_t *h)
1105 {
1106         adddata_proto2 (h, 0x10, "\0", 1);              /* Media Identifier > SMS */
1107         adddata_proto2 (h, 0x11, "\0\0\0\0\0\0", 6);    /* Firmware version */
1108         adddata_proto2 (h, 0x12, "\2\0\4", 3);          /* SMS provider ID */
1109         adddata_proto2 (h, 0x13, h->udtxt, h->udl);     /* Body */
1110 }
1111
1112 static void sms_compose2(sms_t *h, int more)
1113 {
1114         struct tm *tm;
1115         char stm[9];
1116
1117         h->omsg[0] = 0x00;       /* set later... */
1118         h->omsg[1] = 0;
1119         putdummydata_proto2 (h);
1120         if (h->smsc) {                  /* deliver */
1121                 h->omsg[0] = 0x11;      /* SMS_DELIVERY */
1122                 // Required: 10 11 12 13 14 15 17 (seems they must be ordered!)
1123                 tm=localtime(&h->scts);
1124                 sprintf (stm, "%02d%02d%02d%02d", tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min);     // Date mmddHHMM
1125                 adddata_proto2 (h, 0x14, stm, 8);               /* Date */
1126                 if(*h->oa==0)
1127                         strcpy(h->oa,"00000000");
1128                 adddata_proto2 (h, 0x15, h->oa, strlen(h->oa)); /* Originator */
1129                 adddata_proto2 (h, 0x17, "\1", 1);              /* Calling Terminal ID */
1130         } else {                        /* submit */
1131                 h->omsg[0] = 0x10;      /* SMS_SUBMIT */
1132                 // Required: 10 11 12 13 17 18 1B 1C (seems they must be ordered!)
1133                 adddata_proto2 (h, 0x17, "\1", 1);              /* Calling Terminal ID */
1134                 if(*h->da==0)
1135                         strcpy(h->da,"00000000");
1136                 adddata_proto2 (h, 0x18, h->da, strlen(h->da)); /* Originator */
1137                 adddata_proto2 (h, 0x1B, "\1", 1);              /* Called Terminal ID */
1138                 adddata_proto2 (h, 0x1C, "\0\0\0", 3);          /* Notification */
1139         }
1140 }
1141
1142 static void putdummydata_proto2 (sms_t *h);
1143
1144 #define MAX_DEBUG_LEN   300
1145 static char *sms_hexdump(unsigned char buf[], int size, char *s /* destination */)
1146 {
1147         char *p;
1148         int f;
1149
1150         for (p=s,f=0; f<size && f < MAX_DEBUG_LEN; f++, p+=3) 
1151                 sprintf(p,"%02X ",(unsigned char)buf[f]);
1152         return(s);
1153 }
1154
1155
1156 /*! \brief sms_handleincoming_proto2: handle the incoming message */
1157 static int sms_handleincoming_proto2(sms_t * h)
1158 {
1159         int f, i, sz=0;
1160         int msg, msgsz;
1161         struct tm *tm;
1162         char debug_buf[MAX_DEBUG_LEN * 3 + 1];
1163
1164         sz = h->imsg[1]+2;
1165         /* ast_verbose (VERBOSE_PREFIX_3 "SMS-P2 Frame: %s\n", sms_hexdump(h->imsg,sz, debug_buf)); */
1166
1167         /* Parse message body (called payload) */
1168         h->scts = time (0);
1169         for(f=4; f<sz; ) {
1170                 msg=h->imsg[f++];
1171                 msgsz=h->imsg[f++];
1172                 msgsz+=(h->imsg[f++]*256);
1173                 switch(msg) {
1174                 case 0x13:      /* Body */
1175                         if (option_verbose > 2)
1176                                 ast_verbose (VERBOSE_PREFIX_3 "SMS-P2 Body#%02X=[%.*s]\n",msg,msgsz,&h->imsg[f]);
1177                         if (msgsz >= sizeof(h->imsg))
1178                                 msgsz = sizeof(h->imsg)-1;
1179                         for (i=0; i<msgsz; i++)
1180                                 h->ud[i]=h->imsg[f+i];
1181                         h->udl = msgsz;
1182                         break;
1183                 case 0x14:      /* Date SCTS */
1184                         h->scts = time (0);
1185                         tm = localtime (&h->scts);
1186                         tm->tm_mon = ( (h->imsg[f]*10) + h->imsg[f+1] ) - 1;
1187                         tm->tm_mday = ( (h->imsg[f+2]*10) + h->imsg[f+3] );
1188                         tm->tm_hour = ( (h->imsg[f+4]*10) + h->imsg[f+5] );
1189                         tm->tm_min = ( (h->imsg[f+6]*10) + h->imsg[f+7] );
1190                         tm->tm_sec = 0;
1191                         h->scts = mktime (tm);
1192                         if (option_verbose > 2)
1193                                 ast_verbose (VERBOSE_PREFIX_3 "SMS-P2 Date#%02X=%02d/%02d %02d:%02d\n", msg, tm->tm_mday, tm->tm_mon+1, tm->tm_hour, tm->tm_min);
1194                         break;
1195                 case 0x15:      /* Calling line (from SMSC) */
1196                         if (msgsz>=20)
1197                                 msgsz=20-1;
1198                         if (option_verbose > 2)
1199                                 ast_verbose (VERBOSE_PREFIX_3 "SMS-P2 Origin#%02X=[%.*s]\n",msg,msgsz,&h->imsg[f]);
1200                         ast_copy_string (h->oa, (char*)(&h->imsg[f]), msgsz+1);
1201                         break;
1202                 case 0x18:      /* Destination (from TE/phone) */
1203                         if (msgsz>=20)
1204                                 msgsz=20-1;
1205                         if (option_verbose > 2)
1206                                 ast_verbose (VERBOSE_PREFIX_3 "SMS-P2 Destination#%02X=[%.*s]\n",msg,msgsz,&h->imsg[f]);
1207                         ast_copy_string (h->da, (char*)(&h->imsg[f]), msgsz+1);
1208                         break;
1209                 case 0x1C:      /* Notify */
1210                         if (option_verbose > 2)
1211                                 ast_verbose (VERBOSE_PREFIX_3 "SMS-P2 Notify#%02X=%s\n",msg, sms_hexdump(&h->imsg[f],3, debug_buf));
1212                         break;
1213                 default:
1214                         if (option_verbose > 2)
1215                                 ast_verbose (VERBOSE_PREFIX_3 "SMS-P2 Par#%02X [%d]: %s\n",msg,msgsz,sms_hexdump(&h->imsg[f],msgsz, debug_buf));
1216                         break;
1217                 }
1218                 f+=msgsz;       /* Skip to next */
1219         }
1220         h->rx = 1;              /* received message */
1221         sms_writefile (h);      /* write the file */
1222         return 0;               /* no error */
1223 }
1224
1225 #if 0
1226 static void smssend(sms_t *h, char *c)
1227 {
1228         int f, x;
1229         for(f=0; f<strlen(c); f++) {
1230                 sscanf(&c[f*3],"%x",&x);
1231                 h->omsg[f] = x;
1232         }
1233         sms_messagetx (h);
1234 }
1235 #endif
1236
1237 static void sms_nextoutgoing (sms_t *h);
1238
1239 static void sms_messagerx2(sms_t * h)
1240 {
1241         int p = h->imsg[0] & DLL_SMS_MASK ; /* mask the high bit */
1242         int cause;
1243
1244 #define DLL2_ACK(h) ((h->framenumber & 1) ? DLL2_SMS_ACK1: DLL2_SMS_ACK1)
1245         switch (p) {
1246         case DLL2_SMS_EST:      /* Protocol 2: Connection ready (fake): send message  */
1247                 sms_nextoutgoing (h);
1248                 //smssend(h,"11 29 27 00 10 01 00 00 11 06 00 00 00 00 00 00 00 12 03 00 02 00 04 13 01 00 41 14 08 00 30 39 31 35 30 02 30 02 15 02 00 39 30 ");
1249                 break;
1250
1251         case DLL2_SMS_INFO_MO:  /* transport SMS_SUBMIT */
1252         case DLL2_SMS_INFO_MT:  /* transport SMS_DELIVERY */
1253                 cause = sms_handleincoming_proto2(h);
1254                 if (!cause)     /* ACK */
1255                         sms_log (h, 'Y');
1256                 h->omsg[0] = DLL2_ACK(h);
1257                 h->omsg[1] = 0x06;  /* msg len */
1258                 h->omsg[2] = 0x04;  /* payload len */
1259                 h->omsg[3] = 0x00;  /* payload len */
1260                 h->omsg[4] = 0x1f;  /* Response type */
1261                 h->omsg[5] = 0x01;  /* parameter len */
1262                 h->omsg[6] = 0x00;  /* parameter len */
1263                 h->omsg[7] = cause;  /* CONFIRM or error */
1264                 sms_messagetx (h);
1265                 break;
1266
1267         case DLL2_SMS_NACK:     /* Protocol 2: SMS_NAK */
1268                 h->omsg[0] = DLL2_SMS_REL;  /* SMS_REL */
1269                 h->omsg[1] = 0x00;  /* msg len */
1270                 sms_messagetx (h);
1271                 break;
1272
1273         case DLL2_SMS_ACK0:
1274         case DLL2_SMS_ACK1:
1275                 /* SMS_ACK also transport SMS_SUBMIT or SMS_DELIVERY */
1276                 if( (h->omsg[0] & DLL_SMS_MASK) == DLL2_SMS_REL) {
1277                         /* a response to our Release, just hangup */
1278                         h->hangup = 1;          /* hangup */
1279                 } else {
1280                         /* XXX depending on what we are.. */
1281                         ast_log(LOG_NOTICE, "SMS_SUBMIT or SMS_DELIVERY");
1282                         sms_nextoutgoing (h);
1283                 }
1284                 break;
1285
1286         case DLL2_SMS_REL:      /* Protocol 2: SMS_REL (hangup req) */
1287                 h->omsg[0] = DLL2_ACK(h);
1288                 h->omsg[1] = 0;
1289                 sms_messagetx (h);
1290                 break;
1291         }
1292 }
1293
1294 /*! \brief compose a message for protocol 1 */
1295 static void sms_compose1(sms_t *h, int more)
1296 {
1297         unsigned int p = 2;     /* next byte to write. Skip type and len */
1298
1299         h->omsg[0] = 0x91;                /* SMS_DATA */
1300         if (h->smsc) {                   /* deliver */
1301                 h->omsg[p++] = (more ? 4 : 0) + ((h->udhl > 0) ? 0x40 : 0);
1302                 p += packaddress (h->omsg + p, h->oa);
1303                 h->omsg[p++] = h->pid;
1304                 h->omsg[p++] = h->dcs;
1305                 packdate (h->omsg + p, h->scts);
1306                 p += 7;
1307                 p += packsms (h->dcs, h->omsg + p, h->udhl, h->udh, h->udl, h->ud);
1308         } else {                         /* submit */
1309                 h->omsg[p++] =
1310                         0x01 + (more ? 4 : 0) + (h->srr ? 0x20 : 0) + (h->rp ? 0x80 : 0) + (h->vp ? 0x10 : 0) + (h->udhi ? 0x40 : 0);
1311                 if (h->mr < 0)
1312                         h->mr = message_ref++;
1313                 h->omsg[p++] = h->mr;
1314                 p += packaddress (h->omsg + p, h->da);
1315                 h->omsg[p++] = h->pid;
1316                 h->omsg[p++] = h->dcs;
1317                 if (h->vp) {             /* relative VP */
1318                         if (h->vp < 720)
1319                                 h->omsg[p++] = (h->vp + 4) / 5 - 1;
1320                         else if (h->vp < 1440)
1321                                 h->omsg[p++] = (h->vp - 720 + 29) / 30 + 143;
1322                         else if (h->vp < 43200)
1323                                 h->omsg[p++] = (h->vp + 1439) / 1440 + 166;
1324                         else if (h->vp < 635040)
1325                                 h->omsg[p++] = (h->vp + 10079) / 10080 + 192;
1326                         else
1327                                 h->omsg[p++] = 255;             /* max */
1328                 }
1329                 p += packsms (h->dcs, h->omsg + p, h->udhl, h->udh, h->udl, h->ud);
1330         }
1331         h->omsg[1] = p - 2;
1332 }
1333
1334 /*! \brief find and fill in next message, or send a REL if none waiting */
1335 static void sms_nextoutgoing (sms_t * h)
1336 {          
1337         char fn[100 + NAME_MAX] = "";
1338         DIR *d;
1339         char more = 0;
1340
1341         *h->da = *h->oa = '\0';                 /* clear destinations */
1342         ast_copy_string (fn, spool_dir, sizeof (fn));
1343         mkdir(fn, 0777);                        /* ensure it exists */
1344         h->rx = 0;                              /* outgoing message */
1345         snprintf (fn + strlen (fn), sizeof (fn) - strlen (fn), "/%s", h->smsc ? "mttx" : "motx");
1346         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 (0);
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         int res;
1933
1934         res = ast_unregister_application (app);
1935         
1936         ast_module_user_hangup_all();
1937
1938         return res;     
1939 }
1940
1941 static int load_module(void)
1942 {
1943 #ifdef OUTALAW
1944         int p;
1945         for (p = 0; p < 80; p++)
1946                 wavea[p] = AST_LIN2A (wave[p]);
1947 #endif
1948         snprintf (log_file, sizeof (log_file), "%s/sms", ast_config_AST_LOG_DIR);
1949         snprintf (spool_dir, sizeof (spool_dir), "%s/sms", ast_config_AST_SPOOL_DIR);
1950         return ast_register_application (app, sms_exec, synopsis, descrip);
1951 }
1952
1953 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "SMS/PSTN handler");