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