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