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