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