Merge sms stuff and move to "utils" subdir (bug #2973)
[asterisk/asterisk.git] / apps / app_sms.c
1 /*
2  * Asterisk -- A telephony toolkit for Linux.
3  *
4  * SMS application - ETSI ES 201 912 protocol 1 implimentation
5  * 
6  * Copyright (C) 2004, Adrian Kennard, rights assigned to Digium
7  *
8  * This program is free software, distributed under the terms of
9  * the GNU General Public License
10  */
11
12 #include <asterisk/lock.h>
13 #include <asterisk/file.h>
14 #include <asterisk/logger.h>
15 #include <asterisk/options.h>
16 #include <asterisk/channel.h>
17 #include <asterisk/pbx.h>
18 #include <asterisk/module.h>
19 #include <asterisk/alaw.h>
20 #include <asterisk/callerid.h>
21 #include <stdlib.h>
22 #include <unistd.h>
23 #include <string.h>
24 #include <stdlib.h>
25 #include <errno.h>
26 #include <sys/types.h>
27 #include <dirent.h>
28 #include <ctype.h>
29 #include "../astconf.h"
30
31 /* output using Alaw rather than linear */
32 /*#define OUTALAW */
33
34 /* ToDo */
35 /* Add full VP support */
36 /* Handle status report messages (generation and reception) */
37 /* Time zones on time stamps */
38 /* user ref field */
39
40 static volatile unsigned char message_ref;      /* arbitary message ref */
41 static volatile unsigned int seq;      /* arbitrary message sequence number for unqiue files */
42
43 static char log_file[255];
44 static char spool_dir[255];
45
46 static char *tdesc = "SMS/PSTN handler";
47
48 static char *app = "SMS";
49
50 static char *synopsis = "Communicates with SMS service centres and SMS capable analogue phones";
51
52 static char *descrip =
53    "  SMS(name|[a][s]):  SMS handles exchange of SMS data with a call to/from SMS capabale\n"
54    "phone or SMS PSTN service centre. Can send and/or receive SMS messages.\n"
55    "Returns 0 if call handled correctly, or -1 if there were any problems.\n"
56    "Works to ETSI ES 201 912 compatible with BT SMS PSTN service in UK\n"
57    "Typical usage is to use to handle called from the SMS service centre CLI,\n"
58    "or to set up a call using 'outgoing' or manager interface to connect service centre to SMS()\n"
59    "name is the name of the queue used in /var/spool/asterisk/sms\n"
60    "Argument 'a' means answer, i.e. send initial FSK packet.\n"
61    "Argument 's' means act as service centre talking to a phone.\n"
62    "Messages are processed as per text file message queues.\n" "smsq is a command to generate message queues and send messages.\n";
63
64 static signed short wave[] =
65    { 0, 392, 782, 1167, 1545, 1913, 2270, 2612, 2939, 3247, 3536, 3802, 4045, 4263, 4455, 4619, 4755, 4862, 4938, 4985,
66    5000, 4985, 4938, 4862, 4755, 4619, 4455, 4263, 4045, 3802, 3536, 3247, 2939, 2612, 2270, 1913, 1545, 1167, 782, 392,
67    0, -392, -782, -1167,
68    -1545, -1913, -2270, -2612, -2939, -3247, -3536, -3802, -4045, -4263, -4455, -4619, -4755, -4862, -4938, -4985, -5000,
69    -4985, -4938, -4862,
70    -4755, -4619, -4455, -4263, -4045, -3802, -3536, -3247, -2939, -2612, -2270, -1913, -1545, -1167, -782, -392
71 };
72
73 #ifdef OUTALAW
74 static unsigned char wavea[80];
75 #endif
76
77 STANDARD_LOCAL_USER;
78
79 LOCAL_USER_DECL;
80
81 /* SMS 7 bit character mapping to UCS-2 */
82 static const unsigned short defaultalphabet[] = {
83    0x0040, 0x00A3, 0x0024, 0x00A5, 0x00E8, 0x00E9, 0x00F9, 0x00EC,
84    0x00F2, 0x00E7, 0x000A, 0x00D8, 0x00F8, 0x000D, 0x00C5, 0x00E5,
85    0x0394, 0x005F, 0x03A6, 0x0393, 0x039B, 0x03A9, 0x03A0, 0x03A8,
86    0x03A3, 0x0398, 0x039E, 0x00A0, 0x00C6, 0x00E6, 0x00DF, 0x00C9,
87    ' ', '!', '"', '#', 164, '%', '&', 39, '(', ')', '*', '+', ',', '-', '.', '/',
88    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?',
89    161, 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
90    'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 196, 214, 209, 220, 167,
91    191, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
92    'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 228, 246, 241, 252, 224,
93 };
94
95 static const unsigned short escapes[] = {
96    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x000C, 0, 0, 0, 0, 0,
97    0, 0, 0, 0, 0x005E, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
98    0, 0, 0, 0, 0, 0, 0, 0, 0x007B, 0x007D, 0, 0, 0, 0, 0, 0x005C,
99    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x005B, 0x007E, 0x005D, 0,
100    0x007C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
101    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
102    0, 0, 0, 0, 0, 0x20AC, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
103    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
104 };
105
106 #define SMSLEN 160              /* max SMS length */
107
108 typedef struct sms_s
109 {
110    unsigned char hangup;        /* we are done... */
111    unsigned char smsc:1;        /* we are SMSC */
112    unsigned char rx:1;          /* this is a received message */
113    char queue[30];              /* queue name */
114    char oa[20];                 /* originating address */
115    char da[20];                 /* destination address */
116    time_t scts;                 /* time stamp, UTC */
117    unsigned char pid;           /* protocol ID */
118    unsigned char dcs;           /* data coding scheme */
119    short mr;                    /* message reference - actually a byte, but usde -1 for not set */
120    int udl;                     /* user data length */
121    int udhl;                    /* user data header length */
122    unsigned char srr:1;         /* Status Report request */
123    unsigned char udhi:1;        /* User Data Header required, even if length 0 */
124    unsigned char rp:1;          /* Reply Path */
125    unsigned int vp;             /* validity period in minutes, 0 for not set */
126    unsigned short ud[SMSLEN];   /* user data (message), UCS-2 coded */
127    unsigned char udh[SMSLEN];   /* user data header */
128    unsigned char cli[20];       /* caller ID */
129    unsigned char ophase;        /* phase (0-79) for 0 and 1 frequencies (1300Hz and 2100Hz) */
130    unsigned char ophasep;       /* phase (0-79) for 1200 bps */
131    unsigned char obyte;         /* byte being sent */
132    unsigned int opause;         /* silent pause before sending (in sample periods) */
133    unsigned char obitp;         /* bit in byte */
134    unsigned char osync;         /* sync bits to send */
135    unsigned char obytep;        /* byte in data */
136    unsigned char obyten;        /* bytes in data */
137    unsigned char omsg[256];     /* data buffer (out) */
138    unsigned char imsg[200];     /* data buffer (in) */
139    signed long long ims0,
140      imc0,
141      ims1,
142      imc1;                      /* magnitude averages sin/cos 0/1 */
143    unsigned int idle;
144    unsigned short imag;         /* signal level */
145    unsigned char ips0,
146      ips1,
147      ipc0,
148      ipc1;                      /* phase sin/cos 0/1 */
149    unsigned char ibitl;         /* last bit */
150    unsigned char ibitc;         /* bit run length count */
151    unsigned char iphasep;       /* bit phase (0-79) for 1200 bps */
152    unsigned char ibitn;         /* bit number in byte being received */
153    unsigned char ibytev;        /* byte value being received */
154    unsigned char ibytep;        /* byte pointer in messafe */
155    unsigned char ibytec;        /* byte checksum for message */
156    unsigned char ierr;          /* error flag */
157    unsigned char ibith;         /* history of last bits */
158    unsigned char ibitt;         /* total of 1's in last 3 bites */
159    /* more to go here */
160 } sms_t;
161
162 /* different types of encoding */
163 #define is7bit(dcs) (((dcs)&0xC0)?(!((dcs)&4)):(!((dcs)&12)))
164 #define is8bit(dcs) (((dcs)&0xC0)?(((dcs)&4)):(((dcs)&12)==4))
165 #define is16bit(dcs) (((dcs)&0xC0)?0:(((dcs)&12)==8))
166
167 static void *
168 sms_alloc (struct ast_channel *chan, void *params)
169 {
170    return params;
171 }
172
173 static void
174 sms_release (struct ast_channel *chan, void *data)
175 {
176    return;
177 }
178
179 static void sms_messagetx (sms_t * h);
180
181 /* copy number, skipping non digits apart from leading + */
182 static void
183 numcpy (char *d, char *s)
184 {
185    if (*s == '+')
186       *d++ = *s++;
187    while (*s)
188    {
189       if (isdigit (*s))
190          *d++ = *s;
191       s++;
192    }
193    *d = 0;
194 }
195
196 static char *
197 isodate (time_t t)
198 {                               /* static, return a date/time in ISO format */
199    static char date[20];
200    strftime (date, sizeof (date), "%Y-%m-%dT%H:%M:%S", localtime (&t));
201    return date;
202 }
203
204 /* reads next UCS character from null terminated UTF-8 string and advanced pointer */
205 /* for non valid UTF-8 sequences, returns character as is */
206 /* Does not advance pointer for null termination */
207 static long
208 utf8decode (unsigned char **pp)
209 {
210    unsigned char *p = *pp;
211    if (!*p)
212       return 0;                 /* null termination of string */
213    (*pp)++;
214    if (*p < 0xC0)
215       return *p;                /* ascii or continuation character */
216    if (*p < 0xE0)
217    {
218       if (*p < 0xC2 || (p[1] & 0xC0) != 0x80)
219          return *p;             /* not valid UTF-8 */
220       (*pp)++;
221       return ((*p & 0x1F) << 6) + (p[1] & 0x3F);
222    }
223    if (*p < 0xF0)
224    {
225       if ((*p == 0xE0 && p[1] < 0xA0) || (p[1] & 0xC0) != 0x80 || (p[2] & 0xC0) != 0x80)
226          return *p;             /* not valid UTF-8 */
227       (*pp) += 2;
228       return ((*p & 0x0F) << 12) + ((p[1] & 0x3F) << 6) + (p[2] & 0x3F);
229    }
230    if (*p < 0xF8)
231    {
232       if ((*p == 0xF0 && p[1] < 0x90) || (p[1] & 0xC0) != 0x80 || (p[2] & 0xC0) != 0x80 || (p[3] & 0xC0) != 0x80)
233          return *p;             /* not valid UTF-8 */
234       (*pp) += 3;
235       return ((*p & 0x07) << 18) + ((p[1] & 0x3F) << 12) + ((p[2] & 0x3F) << 6) + (p[3] & 0x3F);
236    }
237    if (*p < 0xFC)
238    {
239       if ((*p == 0xF8 && p[1] < 0x88) || (p[1] & 0xC0) != 0x80 || (p[2] & 0xC0) != 0x80 || (p[3] & 0xC0) != 0x80
240           || (p[4] & 0xC0) != 0x80)
241          return *p;             /* not valid UTF-8 */
242       (*pp) += 4;
243       return ((*p & 0x03) << 24) + ((p[1] & 0x3F) << 18) + ((p[2] & 0x3F) << 12) + ((p[3] & 0x3F) << 6) + (p[4] & 0x3F);
244    }
245    if (*p < 0xFE)
246    {
247       if ((*p == 0xFC && p[1] < 0x84) || (p[1] & 0xC0) != 0x80 || (p[2] & 0xC0) != 0x80 || (p[3] & 0xC0) != 0x80
248           || (p[4] & 0xC0) != 0x80 || (p[5] & 0xC0) != 0x80)
249          return *p;             /* not valid UTF-8 */
250       (*pp) += 5;
251       return ((*p & 0x01) << 30) + ((p[1] & 0x3F) << 24) + ((p[2] & 0x3F) << 18) + ((p[3] & 0x3F) << 12) + ((p[4] & 0x3F) << 6) +
252          (p[5] & 0x3F);
253    }
254    return *p;                   /* not sensible */
255 }
256
257 /* This 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 */
258 /* The return value is the number of septets packed in to o, which is internally limited to SMSLEN */
259 /* o can be null, in which case this is used to validate or count only */
260 /* if the input contains invalid characters then the return value is -1 */
261 static int
262 packsms7 (unsigned char *o, int udhl, unsigned char *udh, int udl, unsigned short *ud)
263 {
264    unsigned char p = 0,
265       b = 0,
266       n = 0;
267    if (udhl)
268    {                            /* header */
269       if (o)
270          o[p++] = udhl;
271       b = 1;
272       n = 1;
273       while (udhl--)
274       {
275          if (o)
276             o[p++] = *udh++;
277          b += 8;
278          while (b >= 7)
279          {
280             b -= 7;
281             n++;
282          }
283          if (n >= SMSLEN)
284             return n;
285       }
286       if (b)
287       {
288          b = 7 - b;
289          if (++n >= SMSLEN)
290             return n;
291       };                        /* filling to septet boundary */
292    }
293    if (o)
294       o[p] = 0;
295    /* message */
296    while (udl--)
297    {
298       long u;
299       unsigned char v;
300       u = *ud++;
301       for (v = 0; v < 128 && defaultalphabet[v] != u; v++);
302       if (v == 128 && u && n + 1 < SMSLEN)
303       {
304          for (v = 0; v < 128 && escapes[v] != u; v++);
305          if (v < 128)
306          {                      /* escaped sequence */
307             if (o)
308                o[p] |= (27 << b);
309             b += 7;
310             if (b >= 8)
311             {
312                b -= 8;
313                p++;
314                if (o)
315                   o[p] = (27 >> (7 - b));
316             }
317             n++;
318          }
319       }
320       if (v == 128)
321          return -1;             /* invalid character */
322       if (o)
323          o[p] |= (v << b);
324       b += 7;
325       if (b >= 8)
326       {
327          b -= 8;
328          p++;
329          if (o)
330             o[p] = (v >> (7 - b));
331       }
332       if (++n >= SMSLEN)
333          return n;
334    }
335    return n;
336 }
337
338 /* This 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 */
339 /* The return value is the number of bytes packed in to o, which is internally limited to 140 */
340 /* o can be null, in which case this is used to validate or count only */
341 /* if the input contains invalid characters then the return value is -1 */
342 static int
343 packsms8 (unsigned char *o, int udhl, unsigned char *udh, int udl, unsigned short *ud)
344 {
345    unsigned char p = 0;
346    /* header - no encoding */
347    if (udhl)
348    {
349       if (o)
350          o[p++] = udhl;
351       while (udhl--)
352       {
353          if (o)
354             o[p++] = *udh++;
355          if (p >= 140)
356             return p;
357       }
358    }
359    while (udl--)
360    {
361       long u;
362       u = *ud++;
363       if (u < 0 || u > 0xFF)
364          return -1;             /* not valid */
365       if (o)
366          o[p++] = u;
367       if (p >= 140)
368          return p;
369    }
370    return p;
371 }
372
373 /* This takes a binary header (udhl bytes at udh) and UCS-2 message (udl characters at ud) and packs in to o using 16 bit UCS-2 character codes */
374 /* The return value is the number of bytes packed in to o, which is internally limited to 140 */
375 /* o can be null, in which case this is used to validate or count only */
376 /* if the input contains invalid characters then the return value is -1 */
377 static int
378 packsms16 (unsigned char *o, int udhl, unsigned char *udh, int udl, unsigned short *ud)
379 {
380    unsigned char p = 0;
381    /* header - no encoding */
382    if (udhl)
383    {
384       if (o)
385          o[p++] = udhl;
386       while (udhl--)
387       {
388          if (o)
389             o[p++] = *udh++;
390          if (p >= 140)
391             return p;
392       }
393    }
394    while (udl--)
395    {
396       long u;
397       u = *ud++;
398       if (o)
399          o[p++] = (u >> 8);
400       if (p >= 140)
401          return p - 1;          /* could not fit last character */
402       if (o)
403          o[p++] = u;
404       if (p >= 140)
405          return p;
406    }
407    return p;
408 }
409
410 /* general pack, with length and data, returns number of bytes of target used */
411 static int
412 packsms (unsigned char dcs, unsigned char *base, unsigned int udhl, unsigned char *udh, int udl, unsigned short *ud)
413 {
414    unsigned char *p = base;
415    if (udl)
416    {
417       int l = 0;
418       if (is7bit (dcs))
419       {                         /* 7 bit */
420          l = packsms7 (p + 1, udhl, udh, udl, ud);
421          if (l < 0)
422             l = 0;
423          *p++ = l;
424          p += (l * 7 + 7) / 8;
425       } else if (is8bit (dcs))
426       {                         /* 8 bit */
427          l = packsms8 (p + 1, udhl, udh, udl, ud);
428          if (l < 0)
429             l = 0;
430          *p++ = l;
431          p += l;
432       } else
433       {                         /* UCS-2 */
434          l = packsms16 (p + 1, udhl, udh, udl, ud);
435          if (l < 0)
436             l = 0;
437          *p++ = l;
438          p += l;
439       }
440    } else
441       *p++ = 0;                 /* no user data */
442    return p - base;
443 }
444
445
446 /* pack a date and return */
447 static void
448 packdate (unsigned char *o, time_t w)
449 {
450    struct tm *t = localtime (&w);
451 #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined( __NetBSD__ ) || defined(__APPLE__)
452    int z = -t->tm_gmtoff / 60 / 15;
453 #else
454    int z = timezone / 60 / 15;
455 #endif
456    *o++ = ((t->tm_year % 10) << 4) + (t->tm_year % 100) / 10;
457    *o++ = (((t->tm_mon + 1) % 10) << 4) + (t->tm_mon + 1) / 10;
458    *o++ = ((t->tm_mday % 10) << 4) + t->tm_mday / 10;
459    *o++ = ((t->tm_hour % 10) << 4) + t->tm_hour / 10;
460    *o++ = ((t->tm_min % 10) << 4) + t->tm_min / 10;
461    *o++ = ((t->tm_sec % 10) << 4) + t->tm_sec / 10;
462    if (z < 0)
463       *o++ = (((-z) % 10) << 4) + (-z) / 10 + 0x08;
464    else
465       *o++ = ((z % 10) << 4) + z / 10;
466 }
467
468 /* unpack a date and return */
469 static time_t
470 unpackdate (unsigned char *i)
471 {
472    struct tm t;
473    t.tm_year = 100 + (i[0] & 0xF) * 10 + (i[0] >> 4);
474    t.tm_mon = (i[1] & 0xF) * 10 + (i[1] >> 4) - 1;
475    t.tm_mday = (i[2] & 0xF) * 10 + (i[2] >> 4);
476    t.tm_hour = (i[3] & 0xF) * 10 + (i[3] >> 4);
477    t.tm_min = (i[4] & 0xF) * 10 + (i[4] >> 4);
478    t.tm_sec = (i[5] & 0xF) * 10 + (i[5] >> 4);
479    t.tm_isdst = 0;
480    if (i[6] & 0x08)
481       t.tm_min += 15 * ((i[6] & 0x7) * 10 + (i[6] >> 4));
482    else
483       t.tm_min -= 15 * ((i[6] & 0x7) * 10 + (i[6] >> 4));
484    return mktime (&t);
485 }
486
487 /* unpacks bytes (7 bit encoding) at i, len l septets, and places in udh and ud setting udhl and udl. udh not used if udhi not set */
488 static void
489 unpacksms7 (unsigned char *i, unsigned char l, unsigned char *udh, int *udhl, unsigned short *ud, int *udl, char udhi)
490 {
491    unsigned char b = 0,
492       p = 0;
493    unsigned short *o = ud;
494    *udhl = 0;
495    if (udhi && l)
496    {                            /* header */
497       int h = i[p];
498       *udhl = h;
499       if (h)
500       {
501          b = 1;
502          p++;
503          l--;
504          while (h-- && l)
505          {
506             *udh++ = i[p++];
507             b += 8;
508             while (b >= 7)
509             {
510                b -= 7;
511                l--;
512                if (!l)
513                   break;
514             }
515          }
516          /* adjust for fill, septets */
517          if (b)
518          {
519             b = 7 - b;
520             l--;
521          }
522       }
523    }
524    while (l--)
525    {
526       unsigned char v;
527       if (b < 2)
528          v = ((i[p] >> b) & 0x7F);
529       else
530          v = ((((i[p] >> b) + (i[p + 1] << (8 - b)))) & 0x7F);
531       b += 7;
532       if (b >= 8)
533       {
534          b -= 8;
535          p++;
536       }
537       if (o > ud && o[-1] == 0x00A0 && escapes[v])
538          o[-1] = escapes[v];
539       else
540          *o++ = defaultalphabet[v];
541    }
542    *udl = (o - ud);
543 }
544
545 /* unpacks bytes (8 bit encoding) at i, len l septets, and places in udh and ud setting udhl and udl. udh not used if udhi not set */
546 static void
547 unpacksms8 (unsigned char *i, unsigned char l, unsigned char *udh, int *udhl, unsigned short *ud, int *udl, char udhi)
548 {
549    unsigned short *o = ud;
550    *udhl = 0;
551    if (udhi)
552    {
553       int n = *i;
554       *udhl = n;
555       if (n)
556       {
557          i++;
558          l--;
559          while (l && n)
560          {
561             l--;
562             n--;
563             *udh++ = *i++;
564          }
565       }
566    }
567    while (l--)
568       *o++ = *i++;              /* not to UTF-8 as explicitely 8 bit coding in DCS */
569    *udl = (o - ud);
570 }
571
572 /* unpacks bytes (16 bit encoding) at i, len l septets, and places in udh and ud setting udhl and udl. udh not used if udhi not set */
573 static void
574 unpacksms16 (unsigned char *i, unsigned char l, unsigned char *udh, int *udhl, unsigned short *ud, int *udl, char udhi)
575 {
576    unsigned short *o = ud;
577    *udhl = 0;
578    if (udhi)
579    {
580       int n = *i;
581       *udhl = n;
582       if (n)
583       {
584          i++;
585          l--;
586          while (l && n)
587          {
588             l--;
589             n--;
590             *udh++ = *i++;
591          }
592       }
593    }
594    while (l--)
595    {
596       int v = *i++;
597       if (l--)
598          v = (v << 8) + *i++;
599       *o++ = v;
600    }
601    *udl = (o - ud);
602 }
603
604 /* general unpack - starts with length byte (octet or septet) and returns number of bytes used, inc length */
605 static int
606 unpacksms (unsigned char dcs, unsigned char *i, unsigned char *udh, int *udhl, unsigned short *ud, int *udl, char udhi)
607 {
608    int l = *i++;
609    if (is7bit (dcs))
610    {
611       unpacksms7 (i, l, udh, udhl, ud, udl, udhi);
612       l = (l * 7 + 7) / 8;      /* adjust length to return */
613    } else if (is8bit (dcs))
614       unpacksms8 (i, l, udh, udhl, ud, udl, udhi);
615    else
616       unpacksms16 (i, l, udh, udhl, ud, udl, udhi);
617    return l + 1;
618 }
619
620 /* unpack an address from i, return byte length, unpack to o */
621 static unsigned char
622 unpackaddress (char *o, unsigned char *i)
623 {
624    unsigned char l = i[0],
625       p;
626    if (i[1] == 0x91)
627       *o++ = '+';
628    for (p = 0; p < l; p++)
629    {
630       if (p & 1)
631          *o++ = (i[2 + p / 2] >> 4) + '0';
632       else
633          *o++ = (i[2 + p / 2] & 0xF) + '0';
634    }
635    *o = 0;
636    return (l + 5) / 2;
637 }
638
639 /* store an address at o, and return number of bytes used */
640 static unsigned char
641 packaddress (unsigned char *o, char *i)
642 {
643    unsigned char p = 2;
644    o[0] = 0;
645    if (*i == '+')
646    {
647       i++;
648       o[1] = 0x91;
649    } else
650       o[1] = 0x81;
651    while (*i)
652       if (isdigit (*i))
653       {
654          if (o[0] & 1)
655             o[p++] |= ((*i & 0xF) << 4);
656          else
657             o[p] = (*i & 0xF);
658          o[0]++;
659          i++;
660       } else
661          i++;
662    if (o[0] & 1)
663       o[p++] |= 0xF0;           /* pad */
664    return p;
665 }
666
667 static void
668 sms_log (sms_t * h, char status)
669 {                               /* log the output, and remove file */
670    if (*h->oa || *h->da)
671    {
672       int o = open (log_file, O_CREAT | O_APPEND | O_WRONLY, 0666);
673       if (o >= 0)
674       {
675          char line[1000],
676            mrs[3] = "",
677             *p;
678          unsigned char n;
679          if (h->mr >= 0)
680             snprintf (mrs, sizeof (mrs), "%02X", h->mr);
681          snprintf (line, sizeof (line), "%s %c%c%c%s %s %s %s ",
682                    isodate (time (0)), status, h->rx ? 'I' : 'O', h->smsc ? 'S' : 'M', mrs, h->queue, *h->oa ? h->oa : "-",
683                    *h->da ? h->da : "-");
684          p = line + strlen (line);
685          for (n = 0; n < h->udl; n++)
686             if (h->ud[n] == '\\')
687             {
688                *p++ = '\\';
689                *p++ = '\\';
690             } else if (h->ud[n] == '\n')
691             {
692                *p++ = '\\';
693                *p++ = 'n';
694             } else if (h->ud[n] == '\r')
695             {
696                *p++ = '\\';
697                *p++ = 'r';
698             } else if (h->ud[n] < 32 || h->ud[n] == 127)
699                *p++ = 191;
700             else
701                *p++ = h->ud[n];
702          *p++ = '\n';
703          *p = 0;
704          write (o, line, strlen (line));
705          close (o);
706       }
707       *h->oa = *h->da = h->udl = 0;
708    }
709 }
710
711 /* parse and delete a file */
712 static void
713 sms_readfile (sms_t * h, char *fn)
714 {
715    char line[1000];
716    FILE *s;
717    char dcsset = 0;             /* if DSC set */
718    ast_log (LOG_EVENT, "Sending %s\n", fn);
719    h->rx = h->udl = *h->oa = *h->da = h->pid = h->srr = h->udhi = h->rp = h->vp = h->udhl = 0;
720    h->mr = -1;
721    h->dcs = 0xF1;               /* normal messages class 1 */
722    h->scts = time (0);
723    s = fopen (fn, "r");
724    if (s)
725    {
726       if (unlink (fn))
727       {                         /* concurrent access, we lost */
728          fclose (s);
729          return;
730       }
731       while (fgets (line, sizeof (line), s))
732       {                         /* process line in file */
733          unsigned char *p;
734          for (p = line; *p && *p != '\n' && *p != '\r'; p++);
735          *p = 0;                /* strip eoln */
736          p = line;
737          if (!*p || *p == ';')
738             continue;           /* blank line or comment, ignore */
739          while (isalnum (*p))
740          {
741             *p = tolower (*p);
742             p++;
743          }
744          while (isspace (*p))
745             *p++ = 0;
746          if (*p == '=')
747          {
748             *p++ = 0;
749             if (!strcmp (line, "ud"))
750             {                   /* parse message (UTF-8) */
751                unsigned char o = 0;
752                while (*p && o < SMSLEN)
753                   h->ud[o++] = utf8decode (&p);
754                h->udl = o;
755                if (*p)
756                   ast_log (LOG_WARNING, "UD too long in %s\n", fn);
757             } else
758             {
759                while (isspace (*p))
760                   p++;
761                if (!strcmp (line, "oa") && strlen (p) < sizeof (h->oa))
762                   numcpy (h->oa, p);
763                else if (!strcmp (line, "da") && strlen (p) < sizeof (h->oa))
764                   numcpy (h->da, p);
765                else if (!strcmp (line, "pid"))
766                   h->pid = atoi (p);
767                else if (!strcmp (line, "dcs"))
768                {
769                   h->dcs = atoi (p);
770                   dcsset = 1;
771                } else if (!strcmp (line, "mr"))
772                   h->mr = atoi (p);
773                else if (!strcmp (line, "srr"))
774                   h->srr = (atoi (p) ? 1 : 0);
775                else if (!strcmp (line, "vp"))
776                   h->vp = atoi (p);
777                else if (!strcmp (line, "rp"))
778                   h->rp = (atoi (p) ? 1 : 0);
779                else if (!strcmp (line, "scts"))
780                {                /* get date/time */
781                   int Y,
782                     m,
783                     d,
784                     H,
785                     M,
786                     S;
787                   if (sscanf (p, "%d-%d-%dT%d:%d:%d", &Y, &m, &d, &H, &M, &S) == 6)
788                   {
789                      struct tm t;
790                      t.tm_year = Y - 1900;
791                      t.tm_mon = m - 1;
792                      t.tm_mday = d;
793                      t.tm_hour = H;
794                      t.tm_min = M;
795                      t.tm_sec = S;
796                      t.tm_isdst = -1;
797                      h->scts = mktime (&t);
798                      if (h->scts == (time_t) - 1)
799                         ast_log (LOG_WARNING, "Bad date/timein %s: %s", fn, p);
800                   }
801                } else
802                   ast_log (LOG_WARNING, "Cannot parse in %s: %s=%si\n", fn, line, p);
803             }
804          } else if (*p == '#')
805          {                      /* raw hex format */
806             *p++ = 0;
807             if (*p == '#')
808             {
809                p++;
810                if (!strcmp (line, "ud"))
811                {                /* user data */
812                   int o = 0;
813                   while (*p && o < SMSLEN)
814                   {
815                      if (isxdigit (*p) && isxdigit (p[1]) && isxdigit (p[2]) && isxdigit (p[3]))
816                      {
817                         h->ud[o++] =
818                            (((isalpha (*p) ? 9 : 0) + (*p & 0xF)) << 12) +
819                            (((isalpha (p[1]) ? 9 : 0) + (p[1] & 0xF)) << 8) +
820                            (((isalpha (p[2]) ? 9 : 0) + (p[2] & 0xF)) << 4) + ((isalpha (p[3]) ? 9 : 0) + (p[3] & 0xF));
821                         p += 4;
822                      } else
823                         break;
824                   }
825                   h->udl = o;
826                   if (*p)
827                      ast_log (LOG_WARNING, "UD too long / invalid UCS-2 hex in %s\n", fn);
828                } else
829                   ast_log (LOG_WARNING, "Only ud can use ## format, %s\n", fn);
830             } else if (!strcmp (line, "ud"))
831             {                   /* user data */
832                int o = 0;
833                while (*p && o < SMSLEN)
834                {
835                   if (isxdigit (*p) && isxdigit (p[1]))
836                   {
837                      h->ud[o++] = (((isalpha (*p) ? 9 : 0) + (*p & 0xF)) << 4) + ((isalpha (p[1]) ? 9 : 0) + (p[1] & 0xF));
838                      p += 2;
839                   } else
840                      break;
841                }
842                h->udl = o;
843                if (*p)
844                   ast_log (LOG_WARNING, "UD too long / invalid UCS-1 hex in %s\n", fn);
845             } else if (!strcmp (line, "udh"))
846             {                   /* user data header */
847                unsigned char o = 0;
848                h->udhi = 1;
849                while (*p && o < SMSLEN)
850                {
851                   if (isxdigit (*p) && isxdigit (p[1]))
852                   {
853                      h->udh[o] = (((isalpha (*p) ? 9 : 0) + (*p & 0xF)) << 4) + ((isalpha (p[1]) ? 9 : 0) + (p[1] & 0xF));
854                      o++;
855                      p += 2;
856                   } else
857                      break;
858                }
859                h->udhl = o;
860                if (*p)
861                   ast_log (LOG_WARNING, "UDH too long / invalid hex in %s\n", fn);
862             } else
863                ast_log (LOG_WARNING, "Only ud and udh can use # format, %s\n", fn);
864          } else
865             ast_log (LOG_WARNING, "Cannot parse in %s: %s\n", fn, line);
866       }
867       fclose (s);
868       if (!dcsset && packsms7 (0, h->udhl, h->udh, h->udl, h->ud) < 0)
869       {
870          if (packsms8 (0, h->udhl, h->udh, h->udl, h->ud) < 0)
871          {
872             if (packsms16 (0, h->udhl, h->udh, h->udl, h->ud) < 0)
873                ast_log (LOG_WARNING, "Invalid UTF-8 message even for UCS-2 (%s)\n", fn);
874             else
875             {
876                h->dcs = 0x08;   /* default to 16 bit */
877                ast_log (LOG_WARNING, "Sending in 16 bit format (%s)\n", fn);
878             }
879          } else
880          {
881             h->dcs = 0xF5;      /* default to 8 bit */
882             ast_log (LOG_WARNING, "Sending in 8 bit format (%s)\n", fn);
883          }
884       }
885       if (is7bit (h->dcs) && packsms7 (0, h->udhl, h->udh, h->udl, h->ud) < 0)
886          ast_log (LOG_WARNING, "Invalid 7 bit GSM data %s\n", fn);
887       if (is8bit (h->dcs) && packsms8 (0, h->udhl, h->udh, h->udl, h->ud) < 0)
888          ast_log (LOG_WARNING, "Invalid 8 bit data %s\n", fn);
889       if (is16bit (h->dcs) && packsms16 (0, h->udhl, h->udh, h->udl, h->ud) < 0)
890          ast_log (LOG_WARNING, "Invalid 16 bit data %s\n", fn);
891    }
892 }
893
894 /* white a received text message to a file */
895 static void
896 sms_writefile (sms_t * h)
897 {
898    char fn[200] = "",
899       fn2[200] = "";
900    FILE *o;
901    strncpy (fn, spool_dir, sizeof (fn) - 1);
902    mkdir (fn, 0777);            /* ensure it exists */
903    snprintf (fn + strlen (fn), sizeof (fn) - strlen (fn), "/%s", h->smsc ? h->rx ? "morx" : "mttx" : h->rx ? "mtrx" : "motx");
904    mkdir (fn, 0777);            /* ensure it exists */
905    strncpy (fn2, fn, sizeof (fn2) - 1);
906    snprintf (fn2 + strlen (fn2), sizeof (fn2) - strlen (fn2), "/%s.%s-%d", h->queue, isodate (h->scts), seq++);
907    snprintf (fn + strlen (fn), sizeof (fn) - strlen (fn), "/.%s", fn2 + strlen (fn) + 1);
908    o = fopen (fn, "w");
909    if (o)
910    {
911       if (*h->oa)
912          fprintf (o, "oa=%s\n", h->oa);
913       if (*h->da)
914          fprintf (o, "da=%s\n", h->da);
915       if (h->udhi)
916       {
917          unsigned int p;
918          fprintf (o, "udh#");
919          for (p = 0; p < h->udhl; p++)
920             fprintf (o, "%02X", h->udh[p]);
921          fprintf (o, "\n");
922       }
923       if (h->udl)
924       {
925          unsigned int p;
926          for (p = 0; p < h->udl && h->ud[p] >= ' '; p++);
927          if (p < h->udl)
928             fputc (';', o);     /* cannot use ud=, but include as a comment for human readable */
929          fprintf (o, "ud=");
930          for (p = 0; p < h->udl; p++)
931          {
932             unsigned short v = h->ud[p];
933             if (v < 32)
934                fputc (191, o);
935             else if (v < 0x80)
936                fputc (v, o);
937             else if (v < 0x800)
938             {
939                fputc (0xC0 + (v >> 6), o);
940                fputc (0x80 + (v & 0x3F), o);
941             } else
942             {
943                fputc (0xE0 + (v >> 12), o);
944                fputc (0x80 + ((v >> 6) & 0x3F), o);
945                fputc (0x80 + (v & 0x3F), o);
946             }
947          }
948          fprintf (o, "\n");
949          for (p = 0; p < h->udl && h->ud[p] >= ' '; p++);
950          if (p < h->udl)
951          {
952             for (p = 0; p < h->udl && h->ud[p] < 0x100; p++);
953             if (p == h->udl)
954             {                   /* can write in ucs-1 hex */
955                fprintf (o, "ud#");
956                for (p = 0; p < h->udl; p++)
957                   fprintf (o, "%02X", h->ud[p]);
958                fprintf (o, "\n");
959             } else
960             {                   /* 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 /* read dir skipping dot files... */
991 static struct dirent *
992 readdirqueue (DIR * d, char *queue)
993 {
994    struct dirent *f;
995    do
996    {
997       f = readdir (d);
998    }
999    while (f && (*f->d_name == '.' || strncmp (f->d_name, queue, strlen (queue)) || f->d_name[strlen (queue)] != '.'));
1000    return f;
1001 }
1002
1003 /* handle the incoming message */
1004 static unsigned char
1005 sms_handleincoming (sms_t * h)
1006 {
1007    unsigned char p = 3;
1008    if (h->smsc)
1009    {                            /* SMSC */
1010       if ((h->imsg[2] & 3) == 1)
1011       {                         /* SMS-SUBMIT */
1012          h->udhl = h->udl = 0;
1013          h->vp = 0;
1014          h->srr = ((h->imsg[2] & 0x20) ? 1 : 0);
1015          h->udhi = ((h->imsg[2] & 0x40) ? 1 : 0);
1016          h->rp = ((h->imsg[2] & 0x80) ? 1 : 0);
1017          strncpy (h->oa, h->cli, sizeof (h->oa) - 1);
1018          h->scts = time (0);
1019          h->mr = h->imsg[p++];
1020          p += unpackaddress (h->da, h->imsg + p);
1021          h->pid = h->imsg[p++];
1022          h->dcs = h->imsg[p++];
1023          if ((h->imsg[2] & 0x18) == 0x10)
1024          {                      /* relative VP */
1025             if (h->imsg[p] < 144)
1026                h->vp = (h->imsg[p] + 1) * 5;
1027             else if (h->imsg[p] < 168)
1028                h->vp = 720 + (h->imsg[p] - 143) * 30;
1029             else if (h->imsg[p] < 197)
1030                h->vp = (h->imsg[p] - 166) * 1440;
1031             else
1032                h->vp = (h->imsg[p] - 192) * 10080;
1033             p++;
1034          } else if (h->imsg[2] & 0x18)
1035             p += 7;             /* ignore enhanced / absolute VP */
1036          p += unpacksms (h->dcs, h->imsg + p, h->udh, &h->udhl, h->ud, &h->udl, h->udhi);
1037          h->rx = 1;             /* received message */
1038          sms_writefile (h);     /* write the file */
1039          if (p != h->imsg[1] + 2)
1040          {
1041             ast_log (LOG_WARNING, "Mismatch receive unpacking %d/%d\n", p, h->imsg[1] + 2);
1042             return 0xFF;        /* duh! */
1043          }
1044       } else
1045       {
1046          ast_log (LOG_WARNING, "Unknown message type %02X\n", h->imsg[2]);
1047          return 0xFF;
1048       }
1049    } else
1050    {                            /* client */
1051       if (!(h->imsg[2] & 3))
1052       {                         /* SMS-DELIVER */
1053          *h->da = h->srr = h->rp = h->vp = h->udhi = h->udhl = h->udl = 0;
1054          h->srr = ((h->imsg[2] & 0x20) ? 1 : 0);
1055          h->udhi = ((h->imsg[2] & 0x40) ? 1 : 0);
1056          h->rp = ((h->imsg[2] & 0x80) ? 1 : 0);
1057          h->mr = -1;
1058          p += unpackaddress (h->oa, h->imsg + p);
1059          h->pid = h->imsg[p++];
1060          h->dcs = h->imsg[p++];
1061          h->scts = unpackdate (h->imsg + p);
1062          p += 7;
1063          p += unpacksms (h->dcs, h->imsg + p, h->udh, &h->udhl, h->ud, &h->udl, h->udhi);
1064          h->rx = 1;             /* received message */
1065          sms_writefile (h);     /* write the file */
1066          if (p != h->imsg[1] + 2)
1067          {
1068             ast_log (LOG_WARNING, "Mismatch receive unpacking %d/%d\n", p, h->imsg[1] + 2);
1069             return 0xFF;        /* duh! */
1070          }
1071       } else
1072       {
1073          ast_log (LOG_WARNING, "Unknown message type %02X\n", h->imsg[2]);
1074          return 0xFF;
1075       }
1076    }
1077    return 0;                    /* no error */
1078 }
1079
1080 static void
1081 sms_nextoutgoing (sms_t * h)
1082 {                               /* find and fill in next message, or send a REL if none waiting */
1083    char fn[100 + NAME_MAX] = "";
1084    DIR *d;
1085    char more = 0;
1086    strncpy (fn, spool_dir, sizeof (fn) - 1);
1087    mkdir (fn, 0777);            /* ensure it exists */
1088    h->rx = 0;                   /* outgoing message */
1089    snprintf (fn + strlen (fn), sizeof (fn) - strlen (fn), "/%s", h->smsc ? "mttx" : "motx");
1090    mkdir (fn, 0777);            /* ensure it exists */
1091    d = opendir (fn);
1092    if (d)
1093    {
1094       struct dirent *f = readdirqueue (d, h->queue);
1095       if (f)
1096       {
1097          snprintf (fn + strlen (fn), sizeof (fn) - strlen (fn), "/%s", f->d_name);
1098          sms_readfile (h, fn);
1099          if (readdirqueue (d, h->queue))
1100             more = 1;           /* more to send */
1101       }
1102       closedir (d);
1103    }
1104    if (*h->da || *h->oa)
1105    {                            /* message to send */
1106       unsigned char p = 2;
1107       h->omsg[0] = 0x91;        /* SMS_DATA */
1108       if (h->smsc)
1109       {                         /* deliver */
1110          h->omsg[p++] = (more ? 4 : 0);
1111          p += packaddress (h->omsg + p, h->oa);
1112          h->omsg[p++] = h->pid;
1113          h->omsg[p++] = h->dcs;
1114          packdate (h->omsg + p, h->scts);
1115          p += 7;
1116          p += packsms (h->dcs, h->omsg + p, h->udhl, h->udh, h->udl, h->ud);
1117       } else
1118       {                         /* submit */
1119          h->omsg[p++] =
1120             0x01 + (more ? 4 : 0) + (h->srr ? 0x20 : 0) + (h->rp ? 0x80 : 0) + (h->vp ? 0x10 : 0) + (h->udhi ? 0x40 : 0);
1121          if (h->mr < 0)
1122             h->mr = message_ref++;
1123          h->omsg[p++] = h->mr;
1124          p += packaddress (h->omsg + p, h->da);
1125          h->omsg[p++] = h->pid;
1126          h->omsg[p++] = h->dcs;
1127          if (h->vp)
1128          {                      /* relative VP */
1129             if (h->vp < 720)
1130                h->omsg[p++] = (h->vp + 4) / 5 - 1;
1131             else if (h->vp < 1440)
1132                h->omsg[p++] = (h->vp - 720 + 29) / 30 + 143;
1133             else if (h->vp < 43200)
1134                h->omsg[p++] = (h->vp + 1439) / 1440 + 166;
1135             else if (h->vp < 635040)
1136                h->omsg[p++] = (h->vp + 10079) / 10080 + 192;
1137             else
1138                h->omsg[p++] = 255;      /* max */
1139          }
1140          p += packsms (h->dcs, h->omsg + p, h->udhl, h->udh, h->udl, h->ud);
1141       }
1142       h->omsg[1] = p - 2;
1143       sms_messagetx (h);
1144    } else
1145    {                            /* no message */
1146       h->omsg[0] = 0x94;        /* SMS_REL */
1147       h->omsg[1] = 0;
1148       sms_messagetx (h);
1149    }
1150 }
1151
1152 static void
1153 sms_debug (char *dir, unsigned char *msg)
1154 {
1155    char txt[259 * 3 + 1],
1156     *p = txt;                   /* always long enough */
1157    int n = msg[1] + 3,
1158       q = 0;
1159    while (q < n && q < 30)
1160    {
1161       sprintf (p, " %02X", msg[q++]);
1162       p += 3;
1163    }
1164    if (q < n)
1165       sprintf (p, "...");
1166    ast_verbose (VERBOSE_PREFIX_3 "SMS %s%s\n", dir, txt);
1167 }
1168
1169 static void
1170 sms_messagerx (sms_t * h)
1171 {
1172    sms_debug ("RX", h->imsg);
1173    /* testing */
1174    switch (h->imsg[0])
1175    {
1176    case 0x91:                  /* SMS_DATA */
1177       {
1178          unsigned char cause = sms_handleincoming (h);
1179          if (!cause)
1180          {
1181             sms_log (h, 'Y');
1182             h->omsg[0] = 0x95;  /* SMS_ACK */
1183             h->omsg[1] = 0x02;
1184             h->omsg[2] = 0x00;  /* deliver report */
1185             h->omsg[3] = 0x00;  /* no parameters */
1186          } else
1187          {                      /* NACK */
1188             sms_log (h, 'N');
1189             h->omsg[0] = 0x96;  /* SMS_NACK */
1190             h->omsg[1] = 3;
1191             h->omsg[2] = 0;     /* delivery report */
1192             h->omsg[3] = cause; /* cause */
1193             h->omsg[4] = 0;     /* no parameters */
1194          }
1195          sms_messagetx (h);
1196       }
1197       break;
1198    case 0x92:                  /* SMS_ERROR */
1199       sms_messagetx (h);        /* send whatever we sent again */
1200       break;
1201    case 0x93:                  /* SMS_EST */
1202       sms_nextoutgoing (h);
1203       break;
1204    case 0x94:                  /* SMS_REL */
1205       h->hangup = 1;            /* hangup */
1206       break;
1207    case 0x95:                  /* SMS_ACK */
1208       sms_log (h, 'Y');
1209       sms_nextoutgoing (h);
1210       break;
1211    case 0x96:                  /* SMS_NACK */
1212       sms_log (h, 'N');
1213       sms_nextoutgoing (h);
1214       break;
1215    default:                    /* Unknown */
1216       h->omsg[0] = 0x92;        /* SMS_ERROR */
1217       h->omsg[1] = 1;
1218       h->omsg[2] = 3;           /* unknown message type; */
1219       sms_messagetx (h);
1220       break;
1221    }
1222 }
1223
1224 static void
1225 sms_messagetx (sms_t * h)
1226 {
1227    unsigned char c = 0,
1228       p;
1229    for (p = 0; p < h->omsg[1] + 2; p++)
1230       c += h->omsg[p];
1231    h->omsg[h->omsg[1] + 2] = 0 - c;
1232    sms_debug ("TX", h->omsg);
1233    h->obyte = 1;
1234    h->opause = 200;
1235    if (h->omsg[0] == 0x93)
1236       h->opause = 2400;         /* initial message delay 300ms (for BT) */
1237    h->obytep = 0;
1238    h->obitp = 0;
1239    h->osync = 80;
1240    h->obyten = h->omsg[1] + 3;
1241 }
1242
1243 static int
1244 sms_generate (struct ast_channel *chan, void *data, int len, int samples)
1245 {
1246    struct ast_frame f = { 0 };
1247    unsigned char waste[AST_FRIENDLY_OFFSET];
1248 #ifdef OUTALAW
1249    unsigned char buf[800];
1250 #else
1251    signed short buf[800];
1252 #endif
1253    sms_t *h = data;
1254    int i;
1255
1256    if (len > sizeof (buf))
1257    {
1258       ast_log (LOG_WARNING, "Only doing %d bytes (%d bytes requested)\n", sizeof (buf) / sizeof (signed short), len);
1259       len = sizeof (buf);
1260 #ifdef OUTALAW
1261       samples = len;
1262 #else
1263       samples = len / 2;
1264 #endif
1265    }
1266    waste[0] = 0;                /* make compiler happy */
1267    f.frametype = AST_FRAME_VOICE;
1268 #ifdef OUTALAW
1269    f.subclass = AST_FORMAT_ALAW;
1270    f.datalen = samples;
1271 #else
1272    f.subclass = AST_FORMAT_SLINEAR;
1273    f.datalen = samples * 2;
1274 #endif
1275    f.offset = AST_FRIENDLY_OFFSET;
1276    f.mallocd = 0;
1277    f.data = buf;
1278    f.samples = samples;
1279    f.src = "app_sms";
1280    /* create a buffer containing the digital sms pattern */
1281    for (i = 0; i < samples; i++)
1282    {
1283 #ifdef OUTALAW
1284       buf[i] = wavea[0];
1285 #else
1286       buf[i] = wave[0];
1287 #endif
1288       if (h->opause)
1289          h->opause--;
1290       else if (h->obyten || h->osync)
1291       {                         /* sending data */
1292 #ifdef OUTALAW
1293          buf[i] = wavea[h->ophase];
1294 #else
1295          buf[i] = wave[h->ophase];
1296 #endif
1297          if ((h->ophase += ((h->obyte & 1) ? 13 : 21)) >= 80)
1298             h->ophase -= 80;
1299          if ((h->ophasep += 12) >= 80)
1300          {                      /* next bit */
1301             h->ophasep -= 80;
1302             if (h->osync)
1303                h->osync--;      /* sending sync bits */
1304             else
1305             {
1306                h->obyte >>= 1;
1307                h->obitp++;
1308                if (h->obitp == 1)
1309                   h->obyte = 0; /* start bit; */
1310                else if (h->obitp == 2)
1311                   h->obyte = h->omsg[h->obytep];
1312                else if (h->obitp == 10)
1313                {
1314                   h->obyte = 1; /* stop bit */
1315                   h->obitp = 0;
1316                   h->obytep++;
1317                   if (h->obytep == h->obyten)
1318                   {
1319                      h->obytep = h->obyten = 0; /* sent */
1320                      h->osync = 10;     /* trailing marks */
1321                   }
1322                }
1323             }
1324          }
1325       }
1326    }
1327    if (ast_write (chan, &f) < 0)
1328    {
1329       ast_log (LOG_WARNING, "Failed to write frame to '%s': %s\n", chan->name, strerror (errno));
1330       return -1;
1331    }
1332    return 0;
1333 }
1334
1335 static void
1336 sms_process (sms_t * h, int samples, signed short *data)
1337 {
1338    if (h->obyten || h->osync)
1339       return;                   /* sending */
1340    while (samples--)
1341    {
1342       unsigned long long m0,
1343         m1;
1344       if (abs (*data) > h->imag)
1345          h->imag = abs (*data);
1346       else
1347          h->imag = h->imag * 7 / 8;
1348       if (h->imag > 500)
1349       {
1350          h->idle = 0;
1351          h->ims0 = (h->ims0 * 6 + *data * wave[h->ips0]) / 7;
1352          h->imc0 = (h->imc0 * 6 + *data * wave[h->ipc0]) / 7;
1353          h->ims1 = (h->ims1 * 6 + *data * wave[h->ips1]) / 7;
1354          h->imc1 = (h->imc1 * 6 + *data * wave[h->ipc1]) / 7;
1355          m0 = h->ims0 * h->ims0 + h->imc0 * h->imc0;
1356          m1 = h->ims1 * h->ims1 + h->imc1 * h->imc1;
1357          if ((h->ips0 += 21) >= 80)
1358             h->ips0 -= 80;
1359          if ((h->ipc0 += 21) >= 80)
1360             h->ipc0 -= 80;
1361          if ((h->ips1 += 13) >= 80)
1362             h->ips1 -= 80;
1363          if ((h->ipc1 += 13) >= 80)
1364             h->ipc1 -= 80;
1365          {
1366             char bit;
1367             h->ibith <<= 1;
1368             if (m1 > m0)
1369                h->ibith |= 1;
1370             if (h->ibith & 8)
1371                h->ibitt--;
1372             if (h->ibith & 1)
1373                h->ibitt++;
1374             bit = ((h->ibitt > 1) ? 1 : 0);
1375             if (bit != h->ibitl)
1376                h->ibitc = 1;
1377             else
1378                h->ibitc++;
1379             h->ibitl = bit;
1380             if (!h->ibitn && h->ibitc == 4 && !bit)
1381             {
1382                h->ibitn = 1;
1383                h->iphasep = 0;
1384             }
1385             if (bit && h->ibitc == 200)
1386             {                   /* sync, restart message */
1387                h->ierr = h->ibitn = h->ibytep = h->ibytec = 0;
1388             }
1389             if (h->ibitn)
1390             {
1391                h->iphasep += 12;
1392                if (h->iphasep >= 80)
1393                {                /* next bit */
1394                   h->iphasep -= 80;
1395                   if (h->ibitn++ == 9)
1396                   {             /* end of byte */
1397                      if (!bit)  /* bad stop bit */
1398                         h->ierr = 0xFF; /* unknown error */
1399                      else
1400                      {
1401                         if (h->ibytep < sizeof (h->imsg))
1402                         {
1403                            h->imsg[h->ibytep] = h->ibytev;
1404                            h->ibytec += h->ibytev;
1405                            h->ibytep++;
1406                         } else if (h->ibytep == sizeof (h->imsg))
1407                            h->ierr = 2; /* bad message length */
1408                         if (h->ibytep > 1 && h->ibytep == 3 + h->imsg[1] && !h->ierr)
1409                         {
1410                            if (!h->ibytec)
1411                               sms_messagerx (h);
1412                            else
1413                               h->ierr = 1;      /* bad checksum */
1414                         }
1415                      }
1416                      h->ibitn = 0;
1417                   }
1418                   h->ibytev = (h->ibytev >> 1) + (bit ? 0x80 : 0);
1419                }
1420             }
1421          }
1422       } else
1423       {                         /* lost carrier */
1424          if (h->idle++ == 80000)
1425          {                      /* nothing happening */
1426             ast_log (LOG_EVENT, "No data, hanging up\n");
1427             h->hangup = 1;
1428          }
1429          if (h->ierr)
1430          {                      /* error */
1431             h->omsg[0] = 0x92;  /* error */
1432             h->omsg[1] = 1;
1433             h->omsg[2] = h->ierr;
1434             sms_messagetx (h);  /* send error */
1435          }
1436          h->ierr = h->ibitn = h->ibytep = h->ibytec = 0;
1437       }
1438       data++;
1439    }
1440 }
1441
1442 static struct ast_generator smsgen = {
1443  alloc:sms_alloc,
1444  release:sms_release,
1445  generate:sms_generate,
1446 };
1447
1448 static int
1449 sms_exec (struct ast_channel *chan, void *data)
1450 {
1451    int res = -1;
1452    struct localuser *u;
1453    struct ast_frame *f;
1454    sms_t h = { 0 };
1455    h.ipc0 = h.ipc1 = 20;        /* phase for cosine */
1456    h.dcs = 0xF1;                /* default */
1457    if (!data)
1458    {
1459       ast_log (LOG_ERROR, "Requires queue name at least\n");
1460       return -1;
1461    }
1462
1463    if (chan->cid.cid_num)
1464       strncpy (h.cli, chan->cid.cid_num, sizeof (h.cli) - 1);
1465
1466    {
1467       unsigned char *d = data,
1468          *p,
1469          answer = 0;
1470       if (!*d || *d == '|')
1471       {
1472          ast_log (LOG_ERROR, "Requires queue name\n");
1473          return -1;
1474       }
1475       for (p = d; *p && *p != '|'; p++);
1476       if (p - d >= sizeof (h.queue))
1477       {
1478          ast_log (LOG_ERROR, "Queue name too long\n");
1479          return -1;
1480       }
1481       strncpy (h.queue, d, p - d);
1482       if (*p == '|')
1483          p++;
1484       d = p;
1485       for (p = h.queue; *p; p++)
1486          if (!isalnum (*p))
1487             *p = '-';           /* make very safe for filenames */
1488       while (*d && *d != '|')
1489       {
1490          switch (*d)
1491          {
1492          case 'a':             /* we have to send the initial FSK sequence */
1493             answer = 1;
1494             break;
1495          case 's':             /* we are acting as a service centre talking to a phone */
1496             h.smsc = 1;
1497             break;
1498             /* the following apply if there is an arg3/4 and apply to the created message file */
1499          case 'r':
1500             h.srr = 1;
1501             break;
1502          case 'o':
1503             h.dcs |= 4;         /* octets */
1504             break;
1505          case '1':
1506          case '2':
1507          case '3':
1508          case '4':
1509          case '5':
1510          case '6':
1511          case '7':             /* set the pid for saved local message */
1512             h.pid = 0x40 + (*d & 0xF);
1513             break;
1514          }
1515          d++;
1516       }
1517       if (*d == '|')
1518       {
1519          /* submitting a message, not taking call. */
1520          /* depricated, use smsq instead */
1521          d++;
1522          h.scts = time (0);
1523          for (p = d; *p && *p != '|'; p++);
1524          if (*p)
1525             *p++ = 0;
1526          if (strlen (d) >= sizeof (h.oa))
1527          {
1528             ast_log (LOG_ERROR, "Address too long %s\n", d);
1529             return 0;
1530          }
1531          if (h.smsc)
1532          {
1533             strncpy (h.oa, d, sizeof (h.oa) - 1);
1534          } else
1535          {
1536             strncpy (h.da, d, sizeof (h.da) - 1);
1537          }
1538          if (!h.smsc)
1539             strncpy (h.oa, h.cli, sizeof (h.oa) - 1);
1540          d = p;
1541          h.udl = 0;
1542          while (*p && h.udl < SMSLEN)
1543             h.ud[h.udl++] = utf8decode (&p);
1544          if (is7bit (h.dcs) && packsms7 (0, h.udhl, h.udh, h.udl, h.ud) < 0)
1545             ast_log (LOG_WARNING, "Invalid 7 bit GSM data\n");
1546          if (is8bit (h.dcs) && packsms8 (0, h.udhl, h.udh, h.udl, h.ud) < 0)
1547             ast_log (LOG_WARNING, "Invalid 8 bit data\n");
1548          if (is16bit (h.dcs) && packsms16 (0, h.udhl, h.udh, h.udl, h.ud) < 0)
1549             ast_log (LOG_WARNING, "Invalid 16 bit data\n");
1550          h.rx = 0;              /* sent message */
1551          h.mr = -1;
1552          sms_writefile (&h);
1553          return 0;
1554       }
1555
1556       if (answer)
1557       {
1558          /* set up SMS_EST initial message */
1559          h.omsg[0] = 0x93;
1560          h.omsg[1] = 0;
1561          sms_messagetx (&h);
1562       }
1563    }
1564
1565    LOCAL_USER_ADD (u);
1566    if (chan->_state != AST_STATE_UP)
1567       ast_answer (chan);
1568
1569 #ifdef OUTALAW
1570    res = ast_set_write_format (chan, AST_FORMAT_ALAW);
1571 #else
1572    res = ast_set_write_format (chan, AST_FORMAT_SLINEAR);
1573 #endif
1574    if (res >= 0)
1575       res = ast_set_read_format (chan, AST_FORMAT_SLINEAR);
1576    if (res < 0)
1577    {
1578       LOCAL_USER_REMOVE (u);
1579       ast_log (LOG_ERROR, "Unable to set to linear mode, giving up\n");
1580       return -1;
1581    }
1582
1583    if (ast_activate_generator (chan, &smsgen, &h) < 0)
1584    {
1585       LOCAL_USER_REMOVE (u);
1586       ast_log (LOG_ERROR, "Failed to activate generator on '%s'\n", chan->name);
1587       return -1;
1588    }
1589
1590    /* Do our thing here */
1591    while (ast_waitfor (chan, -1) > -1 && !h.hangup)
1592    {
1593       f = ast_read (chan);
1594       if (!f)
1595          break;
1596       if (f->frametype == AST_FRAME_VOICE)
1597       {
1598          sms_process (&h, f->samples, f->data);
1599       }
1600
1601       ast_frfree (f);
1602    }
1603
1604    sms_log (&h, '?');           /* log incomplete message */
1605
1606    LOCAL_USER_REMOVE (u);
1607    return (h.hangup);
1608 }
1609
1610 int
1611 unload_module (void)
1612 {
1613    STANDARD_HANGUP_LOCALUSERS;
1614    return ast_unregister_application (app);
1615 }
1616
1617 int
1618 load_module (void)
1619 {
1620 #ifdef OUTALAW
1621    {
1622       int p;
1623       for (p = 0; p < 80; p++)
1624          wavea[p] = AST_LIN2A (wave[p]);
1625    }
1626 #endif
1627    snprintf (log_file, sizeof (log_file), "%s/sms", ast_config_AST_LOG_DIR);
1628    snprintf (spool_dir, sizeof (spool_dir), "%s/sms", ast_config_AST_SPOOL_DIR);
1629    return ast_register_application (app, sms_exec, synopsis, descrip);
1630 }
1631
1632 char *
1633 description (void)
1634 {
1635    return tdesc;
1636 }
1637
1638 int
1639 usecount (void)
1640 {
1641    int res;
1642    STANDARD_USECOUNT (res);
1643    return res;
1644 }
1645
1646 char *
1647 key ()
1648 {
1649    return ASTERISK_GPL_KEY;
1650 }