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