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