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