Add revk's SMS application (bug #1437). Thanks!
[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/callerid.h>
20 #include <stdlib.h>
21 #include <unistd.h>
22 #include <string.h>
23 #include <stdlib.h>
24 #include <errno.h>
25 #include <sys/types.h>
26 #include <dirent.h>
27 #include <ctype.h>
28
29 #include <pthread.h>
30
31 /* ToDo */
32 /* When acting as SC and answering, should check for messages and send instead of sending EST as first packet */
33 /* Add full VP support */
34 /* Handle status report messages (generation and reception) */
35 /* Log to show oa and da with no spaces to allow parsing */
36 /* USC2 coding */
37
38 static unsigned char message_ref;       /* arbitary message ref */
39
40 static char *tdesc = "SMS/PSTN handler";
41
42 static char *app = "SMS";
43
44 static char *synopsis = "Communicates with SMS service centres and SMS capable analogue phones";
45
46 static char *descrip =
47   "  SMS(name|[a][s]):  SMS handles exchange of SMS data with a call to/from SMS capabale\n"
48   "phone or SMS PSTN service centre. Can send and/or receive SMS messages.\n"
49   "Returns 0 if call handled correctly, or -1 if there were any problems.\n"
50   "Works to ETSI ES 201 912 compatible with BT SMS PSTN service in UK\n"
51   "Typical usage is to use to handle called from the SMS service centre CLI,\n"
52   "or to set up a call using 'outgoing' or manager interface to connect service centre to SMS()\n"
53   "name is the name of the queue used in /var/spool/asterisk/sms\n"
54   "Argument 'a' means answer, i.e. send initial FSK packet.\n"
55   "Argument 's' means act as service centre talking to a phone.\n"
56   "Messages are processed as per text file message queues.\n"
57   "Can also call as SMS(name|[s]|number|message) to queue a message.\n";
58
59 static signed short wave[] =
60   { 0, 392, 782, 1167, 1545, 1913, 2270, 2612, 2939, 3247, 3536, 3802, 4045, 4263, 4455, 4619, 4755, 4862, 4938, 4985,
61   5000, 4985, 4938, 4862, 4755, 4619, 4455, 4263, 4045, 3802, 3536, 3247, 2939, 2612, 2270, 1913, 1545, 1167, 782, 392,
62   0, -392, -782, -1167,
63   -1545, -1913, -2270, -2612, -2939, -3247, -3536, -3802, -4045, -4263, -4455, -4619, -4755, -4862, -4938, -4985, -5000,
64   -4985, -4938, -4862,
65   -4755, -4619, -4455, -4263, -4045, -3802, -3536, -3247, -2939, -2612, -2270, -1913, -1545, -1167, -782, -392
66 };
67
68 STANDARD_LOCAL_USER;
69
70 LOCAL_USER_DECL;
71
72 /* SMS 7 bit character mapping */
73 /* Note that some greek characters are simply coded as 191 (inverted question mark) as ISO-8859-1 does not do greek */
74 /* Note 27 (escape) is to be displayed as a space as per GSM 03.38 */
75 static unsigned char sms7to8[] = {
76   '@', 163, '$', 165, 232, 233, 249, 236, 242, 199, 10, 216, 248, 13, 197, 229,
77   191, '_', 191, 191, 191, 191, 191, 191, 191, 191, 191, ' ', 198, 230, 223, 201,
78   ' ', '!', '"', '#', 164, '%', '&', 39, '(', ')', '*', '+', ',', '-', '.', '/',
79   '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?',
80   161, 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
81   'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 196, 214, 209, 220, 167,
82   191, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
83   'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 228, 246, 241, 252, 224,
84 };
85 unsigned char sms8to7[256];
86
87 typedef struct sms_s
88 {
89   unsigned char hangup;         /* we are done... */
90   unsigned char smsc;           /* we are SMSC */
91   char queue[30];               /* queue name */
92   char oa[20];                  /* originating address */
93   char da[20];                  /* destination address */
94   time_t scts;                  /* time stamp */
95   unsigned char pid;            /* protocol ID */
96   unsigned char dcs;            /* data coding scheme */
97   unsigned char mr;             /* message reference */
98   unsigned char udl;            /* user date length */
99   unsigned char srr:1;          /* Status Report request */
100   unsigned char rp:1;           /* Reply Path */
101   unsigned int vp;              /* validity period in minutes, 0 for not set */
102   unsigned char ud[160];        /* user data (message) */
103   unsigned char cli[20];        /* caller ID */
104   unsigned char ophase;         /* phase (0-79) for 0 and 1 frequencies (1300Hz and 2100Hz) */
105   unsigned char ophasep;        /* phase (0-79) for 1200 bps */
106   unsigned char obyte;          /* byte being sent */
107   unsigned int opause;          /* silent pause before sending (in sample periods) */
108   unsigned char obitp;          /* bit in byte */
109   unsigned char osync;          /* sync bits to send */
110   unsigned char obytep;         /* byte in data */
111   unsigned char obyten;         /* bytes in data */
112   unsigned char omsg[256];      /* data buffer (out) */
113   unsigned char imsg[200];      /* data buffer (in) */
114   signed long long ims0, imc0, ims1, imc1;      /* magnitude averages sin/cos 0/1 */
115   unsigned int idle;
116   unsigned short imag;          /* signal level */
117   unsigned char ips0, ips1, ipc0, ipc1; /* phase sin/cos 0/1 */
118   unsigned char ibitl;          /* last bit */
119   unsigned char ibitc;          /* bit run length count */
120   unsigned char iphasep;        /* bit phase (0-79) for 1200 bps */
121   unsigned char ibitn;          /* bit number in byte being received */
122   unsigned char ibytev;         /* byte value being received */
123   unsigned char ibytep;         /* byte pointer in messafe */
124   unsigned char ibytec;         /* byte checksum for message */
125   unsigned char ierr;           /* error flag */
126   unsigned char ibith;          /* history of last bits */
127   unsigned char ibitt;          /* total of 1's in last 3 bites */
128   /* more to go here */
129 } sms_t;
130
131 static void *
132 sms_alloc (struct ast_channel *chan, void *params)
133 {
134   return params;
135 }
136
137 static void
138 sms_release (struct ast_channel *chan, void *data)
139 {
140   return;
141 }
142
143 static void sms_messagetx (sms_t * h);
144
145 /* copy number, skipping non digits apart from leading + */
146 static void
147 numcpy (char *d, char *s)
148 {
149   if (*s == '+')
150     *d++ = *s++;
151   while (*s)
152     {
153       if (isdigit (*s))
154         *d++ = *s;
155       s++;
156     }
157   *d = 0;
158 }
159
160 static char *
161 isodate (time_t t)
162 {                               /* static, return a date/time in ISO format */
163   static char date[20];
164   strftime (date, sizeof (date), "%Y-%m-%d %H:%M:%S", localtime (&t));
165   return date;
166 }
167
168 /* pack n bytes from i to o and return number of bytes */
169 static unsigned char
170 pack7 (unsigned char *o, unsigned char *i, unsigned char n)
171 {
172   unsigned char p = 0, b = 0;
173   /* fixup - map character set perhaps... */
174   o[0] = 0;
175   while (n--)
176     {
177       o[p] |= ((sms8to7[*i] & 0x7F) << b);
178       b += 7;
179       if (b >= 8)
180         {
181           b -= 8;
182           p++;
183           o[p] = ((sms8to7[*i] & 0x7F) >> (7 - b));
184         }
185       i++;
186     }
187   if (b)
188     p++;
189   return p;
190 }
191
192 /* check if all characters are valid 7 bit coding characters */
193 static unsigned char
194 check7 (unsigned char l, unsigned char *p)
195 {
196   while (l--)
197     if (sms8to7[*p++] & 0x80)
198       return 1;
199   return 0;
200 }
201
202 /* pack a date and return */
203 static void
204 packdate (unsigned char *o, time_t w)
205 {
206   struct tm *t = localtime (&w);
207   int z = timezone / 3600 / 15;
208   *o++ = ((t->tm_year % 10) << 4) + (t->tm_year % 100) / 10;
209   *o++ = (((t->tm_mon + 1) % 10) << 4) + (t->tm_mon + 1) / 10;
210   *o++ = ((t->tm_mday % 10) << 4) + t->tm_mday / 10;
211   *o++ = ((t->tm_hour % 10) << 4) + t->tm_hour / 10;
212   *o++ = ((t->tm_min % 10) << 4) + t->tm_min / 10;
213   *o++ = ((t->tm_sec % 10) << 4) + t->tm_sec / 10;
214   if (z < 0)
215     *o++ = (((-z) % 10) << 4) + (-z) / 10 + 0x08;
216   else
217     *o++ = ((z % 10) << 4) + z / 10;
218 }
219
220 /* unpack a date and return */
221 static time_t
222 unpackdate (unsigned char *i)
223 {
224   struct tm t;
225   t.tm_year = 100 + (i[0] & 0xF) * 10 + (i[0] >> 4);
226   t.tm_mon = (i[1] & 0xF) * 10 + (i[1] >> 4) - 1;
227   t.tm_mday = (i[2] & 0xF) * 10 + (i[2] >> 4);
228   t.tm_hour = (i[3] & 0xF) * 10 + (i[3] >> 4);
229   t.tm_min = (i[4] & 0xF) * 10 + (i[4] >> 4);
230   t.tm_sec = (i[5] & 0xF) * 10 + (i[5] >> 4);
231   t.tm_isdst = 0;
232   if (i[6] & 0x08)
233     t.tm_min += 15 * ((i[6] & 0x7) * 10 + (i[6] >> 4));
234   else
235     t.tm_min -= 15 * ((i[6] & 0x7) * 10 + (i[6] >> 4));
236   return mktime (&t);
237 }
238
239 /* unpack bytes from i to o and return number of source bytes. */
240 static unsigned char
241 unpack7 (unsigned char *o, unsigned char *i, unsigned char l)
242 {
243   unsigned char b = 0, p = 0;
244   while (l--)
245     {
246       if (b < 2)
247         *o++ = sms7to8[((i[p] >> b) & 0x7F)];
248       else
249         *o++ = sms7to8[((((i[p] >> b) + (i[p + 1] << (8 - b)))) & 0x7F)];
250       b += 7;
251       if (b >= 8)
252         {
253           b -= 8;
254           p++;
255         }
256     }
257   if (b)
258     p++;
259   return p;
260 }
261
262 /* unpack an address from i, return byte length, unpack to o */
263 static unsigned char
264 unpackaddress (char *o, unsigned char *i)
265 {
266   unsigned char l = i[0], p;
267   if (i[1] == 0x91)
268     *o++ = '+';
269   for (p = 0; p < l; p++)
270     {
271       if (p & 1)
272         *o++ = (i[2 + p / 2] >> 4) + '0';
273       else
274         *o++ = (i[2 + p / 2] & 0xF) + '0';
275     }
276   *o = 0;
277   return (l + 5) / 2;
278 }
279
280 /* store an address at o, and return number of bytes used */
281 static unsigned char
282 packaddress (unsigned char *o, char *i)
283 {
284   unsigned char p = 2;
285   o[0] = 0;
286   if (*i == '+')
287     {
288       i++;
289       o[1] = 0x91;
290     }
291   else
292     o[1] = 0x81;
293   while (*i)
294     if (isdigit (*i))
295       {
296         if (o[0] & 1)
297           o[p++] |= ((*i & 0xF) << 4);
298         else
299           o[p] = (*i & 0xF);
300         o[0]++;
301         i++;
302       }
303     else
304       i++;
305   if (o[0] & 1)
306     o[p++] |= 0xF0;             /* pad */
307   return p;
308 }
309
310 static void
311 sms_log (sms_t * h, char status)
312 {                               /* log the output, and remove file */
313   if (*h->oa || *h->da)
314     {
315       int o = open ("/var/log/asterisk/sms", O_CREAT | O_APPEND | O_WRONLY, 0666);
316       if (o >= 0)
317         {
318           char line[1000], *p;
319           unsigned char n;
320           sprintf (line, "%s %c %s %s %s ", isodate (time (0)), status, h->queue, *h->oa ? h->oa : "-",
321                    *h->da ? h->da : "-");
322           p = line + strlen (line);
323           for (n = 0; n < h->udl; n++)
324             if (h->ud[n] == '\\')
325               {
326                 *p++ = '\\';
327                 *p++ = '\\';
328               }
329             else if (h->ud[n] == '\n')
330               {
331                 *p++ = '\\';
332                 *p++ = 'n';
333               }
334             else if (h->ud[n] == '\r')
335               {
336                 *p++ = '\\';
337                 *p++ = 'r';
338               }
339             else if (h->ud[n] < 32 || h->ud[n] == 127)
340               *p++ = 191;
341             else
342               *p++ = h->ud[n];
343           *p++ = '\n';
344           *p = 0;
345           write (o, line, strlen (line));
346           close (o);
347         }
348       *h->oa = *h->da = h->udl = 0;
349     }
350 }
351
352 /* parse and delete a file */
353 static void
354 sms_readfile (sms_t * h, char *fn)
355 {
356   char line[1000];
357   FILE *s;
358   char dcsset = 0;              /* if DSC set */
359   ast_log (LOG_EVENT, "Sending %s\n", fn);
360   h->udl = *h->oa = *h->da = h->pid = h->srr = h->rp = h->vp = 0;
361   h->dcs = 0xF1;                /* normal messages class 1 */
362   h->scts = time (0);
363   h->mr = message_ref++;
364   s = fopen (fn, "r");
365   if (s)
366     {
367       if (unlink (fn))
368         {                       /* concurrent access, we lost */
369           fclose (s);
370           return;
371         }
372       while (fgets (line, sizeof (line), s))
373         {                       /* process line in file */
374           char *p;
375           for (p = line; *p && *p != '\n' && *p != '\r'; p++);
376           *p = 0;               /* strip eoln */
377           //ast_log (LOG_EVENT, "Line %s\n", line);
378           p = line;
379           if (!*p || *p == ';')
380             continue;           /* blank line or comment, ignore */
381           while (isalnum (*p))
382             {
383               *p = tolower (*p);
384               p++;
385             }
386           while (isspace (*p))
387             *p++ = 0;
388           if (*p == '=')
389             {
390               *p++ = 0;
391               if (!strcmp (line, "ud"))
392                 {               /* parse message */
393                   unsigned char o = 0;
394                   while (*p && o < 160)
395                     {
396                       if (*p == '\\')
397                         {
398                           p++;
399                           if (*p == '\\')
400                             h->ud[o++] = *p++;
401                           else if (*p == 'n')
402                             {
403                               h->ud[o++] = '\n';
404                               p++;
405                             }
406                           else if (*p == 'r')
407                             {
408                               h->ud[o++] = '\r';
409                               p++;
410                             }
411                         }
412                       else
413                         h->ud[o++] = *p++;
414                     }
415                   h->udl = o;
416                   if (*p)
417                     ast_log (LOG_WARNING, "UD too long in %s\n", fn);
418                 }
419               else
420                 {
421                   while (isspace (*p))
422                     p++;
423                   if (!strcmp (line, "oa") && strlen (p) < sizeof (h->oa))
424                     numcpy (h->oa, p);
425                   else if (!strcmp (line, "da") && strlen (p) < sizeof (h->oa))
426                     numcpy (h->da, p);
427                   else if (!strcmp (line, "pid"))
428                     h->pid = atoi (p);
429                   else if (!strcmp (line, "dcs"))
430                     {
431                       h->dcs = atoi (p);
432                       dcsset = 1;
433                     }
434                   else if (!strcmp (line, "mr"))
435                     h->mr = atoi (p);
436                   else if (!strcmp (line, "srr"))
437                     h->srr = (atoi (p) ? 1 : 0);
438                   else if (!strcmp (line, "vp"))
439                     h->vp = atoi (p);
440                   else if (!strcmp (line, "rp"))
441                     h->rp = (atoi (p) ? 1 : 0);
442                   else if (!strcmp (line, "scts"))
443                     {           /* get date/time */
444                       int Y, m, d, H, M, S;
445                       if (sscanf (p, "%d-%d-%d %d:%d:%d", &Y, &m, &d, &H, &M, &S) == 6)
446                         {
447                           struct tm t;
448                           t.tm_year = Y - 1900;
449                           t.tm_mon = m - 1;
450                           t.tm_mday = d;
451                           t.tm_hour = H;
452                           t.tm_min = M;
453                           t.tm_sec = S;
454                           t.tm_isdst = -1;
455                           h->scts = mktime (&t);
456                           if (h->scts == (time_t) - 1)
457                             ast_log (LOG_WARNING, "Bad date/timein %s: %s", fn, p);
458                         }
459                     }
460                   else
461                     ast_log (LOG_WARNING, "Cannot parse in %s: %s=%si\n", fn, line, p);
462                 }
463             }
464           else if (*p == '#')
465             {                   /* raw hex format */
466               *p++ = 0;
467               if (!strcmp (line, "ud"))
468                 {
469                   unsigned char o = 0;
470                   while (*p && o < 160)
471                     {
472                       if (isxdigit (*p) && isxdigit (p[1]))
473                         {
474                           h->ud[o] =
475                             (((isalpha (*p) ? 9 : 0) + (*p & 0xF)) << 4) + ((isalpha (p[1]) ? 9 : 0) + (p[1] & 0xF));
476                           o++;
477                           p += 2;
478                         }
479                       else
480                         break;
481                     }
482                   h->udl = o;
483                   if (*p)
484                     ast_log (LOG_WARNING, "UD too long / invalid hex in %s\n", fn);
485                 }
486               else
487                 ast_log (LOG_WARNING, "Only ud can use 8 bit key format with # instead of =\n");
488             }
489           else
490             ast_log (LOG_WARNING, "Cannot parse in %s: %s\n", fn, line);
491         }
492       fclose (s);
493       if (!dcsset && h->udl <= 140 && check7 (h->udl, h->ud))
494         {
495           h->dcs = 0xF5;        // default to 8 bit
496           ast_log (LOG_WARNING, "Sending in 8 bit format because of illegal characters %s\n", fn);
497         }
498       if ((h->dcs & 4) && h->udl > 140)
499         {
500           ast_log (LOG_WARNING, "8 bit data too long, truncated %s\n", fn);
501           h->udl = 140;
502         }
503       else if (!(h->dcs & 4) && check7 (h->udl, h->ud))
504         ast_log (LOG_WARNING, "Invalid 7 bit GSM data %s\n", fn);
505     }
506   //ast_log (LOG_EVENT, "Loaded %s\n", fn);
507 }
508
509 /* white a received text message to a file */
510 static void
511 sms_writefile (sms_t * h)
512 {
513   char fn[200], fn2[200];
514   FILE *o;
515   strcpy (fn, "/var/spool/asterisk/sms");
516   mkdir (fn, 0777);             /* ensure it exists */
517   sprintf (fn + strlen (fn), "/%s.%s", h->smsc ? "me-sc" : "sc-me", h->queue);
518   mkdir (fn, 0777);             /* ensure it exists */
519   strcpy (fn2, fn);
520   strftime (fn2 + strlen (fn2), 30, "/%Y-%m-%d_%H:%M:%S", localtime (&h->scts));
521   sprintf (fn2 + strlen (fn2), "-%02X", h->mr);
522   sprintf (fn + strlen (fn), "/.%s", fn2 + strlen (fn) + 1);
523   o = fopen (fn, "w");
524   if (o)
525     {
526       fprintf (o, "mr=%d\n", h->mr);
527       if (*h->oa)
528         fprintf (o, "oa=%s\n", h->oa);
529       if (*h->da)
530         fprintf (o, "da=%s\n", h->da);
531       if (h->pid)
532         fprintf (o, "pid=%d\n", h->pid);
533       if (h->dcs != 0xF1)
534         fprintf (o, "dcs=%d\n", h->dcs);
535       if (h->vp)
536         fprintf (o, "srr=%d\n", h->vp);
537       if (h->srr)
538         fprintf (o, "srr=1\n");
539       if (h->rp)
540         fprintf (o, "rp=1\n");
541       if (h->scts)
542         fprintf (o, "scts=%s\n", isodate (h->scts));
543       if (h->udl)
544         {
545           unsigned int p;
546           for (p = 0; p < h->udl && ((h->ud[p] >= 32 && h->ud[p] != 127) || h->ud[p] == '\n' || h->ud[p] == '\r'); p++);
547           if (p < h->udl)
548             {                   // use a hex format as unprintable characters
549               fprintf (o, "ud#");
550               for (p = 0; p < h->udl; p++)
551                 fprintf (o, "%02X", h->ud[p]);
552               fprintf (o, "\n;");
553               /* followed by commented line using printable characters */
554             }
555           fprintf (o, "ud=");
556           for (p = 0; p < h->udl; p++)
557             {
558               if (h->ud[p] == '\\')
559                 fprintf (o, "\\\\");
560               else if (h->ud[p] == '\r')
561                 fprintf (o, "\\r");
562               else if (h->ud[p] == '\n')
563                 fprintf (o, "\\n");
564               else if (h->ud[p] < 32 || h->ud[p] == 127)
565                 fputc (191, o);
566               else
567                 fputc (h->ud[p], o);
568             }
569           fprintf (o, "\n");
570         }
571       fclose (o);
572       if (rename (fn, fn2))
573         unlink (fn);
574       else
575         ast_log (LOG_EVENT, "Received to %s\n", fn2);
576     }
577 }
578
579 /* read dir skipping dot files... */
580 static struct dirent *
581 readdirdot (DIR * d)
582 {
583   struct dirent *f;
584   do
585     {
586       f = readdir (d);
587     }
588   while (f && *f->d_name == '.');
589   return f;
590 }
591
592 /* handle the incoming message */
593 static unsigned char
594 sms_handleincoming (sms_t * h)
595 {
596   unsigned char p = 3;
597   if (h->smsc)
598     {                           /* SMSC */
599       if ((h->imsg[2] & 3) == 1)
600         {                       /* SMS-SUBMIT */
601           h->vp = 0;
602           h->srr = ((h->imsg[2] & 0x20) ? 1 : 0);
603           h->rp = ((h->imsg[2] & 0x80) ? 1 : 0);
604           strcpy (h->oa, h->cli);
605           h->scts = time (0);
606           h->mr = h->imsg[p++];
607           p += unpackaddress (h->da, h->imsg + p);
608           h->pid = h->imsg[p++];
609           h->dcs = h->imsg[p++];
610           if ((h->imsg[2] & 0x18) == 0x10)
611             {                   /* relative VP */
612               if (h->imsg[p] < 144)
613                 h->vp = (h->imsg[p] + 1) * 5;
614               else if (h->imsg[p] < 168)
615                 h->vp = 720 + (h->imsg[p] - 143) * 30;
616               else if (h->imsg[p] < 197)
617                 h->vp = (h->imsg[p] - 166) * 1440;
618               else
619                 h->vp = (h->imsg[p] - 192) * 10080;
620               p++;
621             }
622           else if (h->imsg[2] & 0x18)
623             p += 7;             /* ignore enhanced / absolute VP */
624           h->udl = h->imsg[p++];
625           if (h->udl)
626             {
627               if (h->dcs & 4)
628                 {
629                   memcpy (h->ud, h->imsg + p, h->udl);
630                   p += h->udl;
631                 }
632               else
633                 p += unpack7 (h->ud, h->imsg + p, h->udl);
634             }
635           sms_writefile (h);    /* write the file */
636           if (p != h->imsg[1] + 2)
637             return 0xFF;        /* duh! */
638         }
639       else
640         {
641           ast_log (LOG_WARNING, "Unknown message type %02X\n", h->imsg[2]);
642           return 0xFF;
643         }
644     }
645   else
646     {                           /* client */
647       if (!(h->imsg[2] & 3))
648         {                       /* SMS-DELIVER */
649           *h->da = h->srr = h->rp = h->vp = 0;
650           h->mr = message_ref++;
651           p += unpackaddress (h->oa, h->imsg + p);
652           h->pid = h->imsg[p++];
653           h->dcs = h->imsg[p++];
654           h->scts = unpackdate (h->imsg + p);
655           p += 7;
656           h->udl = h->imsg[p++];
657           if (h->udl)
658             {
659               if (h->dcs & 4)
660                 {
661                   memcpy (h->ud, h->imsg + p, h->udl);
662                   p += h->udl;
663                 }
664               else
665                 p += unpack7 (h->ud, h->imsg + p, h->udl);
666             }
667           sms_writefile (h);    /* write the file */
668           if (p != h->imsg[1] + 2)
669             return 0xFF;        /* duh! */
670         }
671       else
672         {
673           ast_log (LOG_WARNING, "Unknown message type %02X\n", h->imsg[2]);
674           return 0xFF;
675         }
676     }
677   return 0;                     /* no error */
678 }
679
680 static void
681 sms_nextoutgoing (sms_t * h)
682 {                               /* find and fill in next message, or send a REL if none waiting */
683   char fn[100 + NAME_MAX];
684   DIR *d;
685   char more = 0;
686   strcpy (fn, "/var/spool/asterisk/sms");
687   mkdir (fn, 0777);             /* ensure it exists */
688   sprintf (fn + strlen (fn), "/%s.%s", h->smsc ? "sc-me" : "me-sc", h->queue);
689   mkdir (fn, 0777);             /* ensure it exists */
690   d = opendir (fn);
691   if (d)
692     {
693       struct dirent *f = readdirdot (d);
694       if (f)
695         {
696           sprintf (fn + strlen (fn), "/%s", f->d_name);
697           sms_readfile (h, fn);
698           if (readdirdot (d))
699             more = 1;           /* more to send */
700         }
701       closedir (d);
702     }
703   if (*h->da || *h->oa)
704     {                           /* message to send */
705       unsigned char p = 2;
706       h->omsg[0] = 0x91;        /* SMS_DATA */
707       if (h->smsc)
708         {                       /* deliver */
709           h->omsg[p++] = (more ? 4 : 0);
710           p += packaddress (h->omsg + p, h->oa);
711           h->omsg[p++] = h->pid;
712           h->omsg[p++] = h->dcs;
713           packdate (h->omsg + p, h->scts);
714           p += 7;
715           h->omsg[p++] = h->udl;
716           if (h->udl)
717             {
718               if (h->dcs & 4)
719                 {
720                   memcpy (h->omsg + p, h->ud, h->udl);
721                   p += h->udl;
722                 }
723               else
724                 p += pack7 (h->omsg + p, h->ud, h->udl);
725             }
726         }
727       else
728         {                       /* submit */
729           h->omsg[p++] = 0x01 + (more ? 4 : 0) + (h->srr ? 0x20 : 0) + (h->rp ? 0x80 : 0) + (h->vp ? 0x10 : 0);
730           h->omsg[p++] = h->mr;
731           p += packaddress (h->omsg + p, h->da);
732           h->omsg[p++] = h->pid;
733           h->omsg[p++] = h->dcs;
734           if (h->vp)
735             {                   /* relative VP */
736               if (h->vp < 720)
737                 h->omsg[p++] = (h->vp + 4) / 5 - 1;
738               else if (h->vp < 1440)
739                 h->omsg[p++] = (h->vp - 720 + 29) / 30 + 143;
740               else if (h->vp < 43200)
741                 h->omsg[p++] = (h->vp + 1439) / 1440 + 166;
742               else if (h->vp < 635040)
743                 h->omsg[p++] = (h->vp + 10079) / 10080 + 192;
744               else
745                 h->omsg[p++] = 255;     /* max */
746             }
747           h->omsg[p++] = h->udl;
748           if (h->udl)
749             {
750               if (h->dcs & 4)
751                 {
752                   memcpy (h->omsg + p, h->ud, h->udl);
753                   p += h->udl;
754                 }
755               else
756                 p += pack7 (h->omsg + p, h->ud, h->udl);
757             }
758         }
759       h->omsg[1] = p - 2;
760       sms_messagetx (h);
761     }
762   else
763     {                           /* no message */
764       h->omsg[0] = 0x94;        /* SMS_REL */
765       h->omsg[1] = 0;
766       sms_messagetx (h);
767     }
768 }
769
770 static void
771 sms_messagerx (sms_t * h)
772 {
773   ast_verbose (VERBOSE_PREFIX_3 "SMS RX %02X %02X %02X %02X %02X %02X...\n", h->imsg[0], h->imsg[1], h->imsg[2],
774                h->imsg[3], h->imsg[4], h->imsg[5]);
775   /* testing */
776   switch (h->imsg[0])
777     {
778     case 0x91:                  /* SMS_DATA */
779       {
780         unsigned char cause = sms_handleincoming (h);
781         if (!cause)
782           {
783             sms_log (h, 'Y');
784             h->omsg[0] = 0x95;  /* SMS_ACK */
785             h->omsg[1] = 0x02;
786             h->omsg[2] = 0x00;  /* deliver report */
787             h->omsg[3] = 0x00;  /* no parameters */
788           }
789         else
790           {                     /* NACK */
791             sms_log (h, 'N');
792             h->omsg[0] = 0x96;  /* SMS_NACK */
793             h->omsg[1] = 3;
794             h->omsg[2] = 0;     /* delivery report */
795             h->omsg[3] = cause; /* cause */
796             h->omsg[4] = 0;     /* no parameters */
797           }
798         sms_messagetx (h);
799       }
800       break;
801     case 0x92:                  /* SMS_ERROR */
802       sms_messagetx (h);        /* send whatever we sent again */
803       break;
804     case 0x93:                  /* SMS_EST */
805       sms_nextoutgoing (h);
806       break;
807     case 0x94:                  /* SMS_REL */
808       h->hangup = 1;            /* hangup */
809       break;
810     case 0x95:                  /* SMS_ACK */
811       sms_log (h, 'Y');
812       sms_nextoutgoing (h);
813       break;
814     case 0x96:                  /* SMS_NACK */
815       sms_log (h, 'N');
816       sms_nextoutgoing (h);
817       break;
818     default:                    /* Unknown */
819       h->omsg[0] = 0x92;        /* SMS_ERROR */
820       h->omsg[1] = 1;
821       h->omsg[2] = 3;           /* unknown message type; */
822       sms_messagetx (h);
823       break;
824     }
825 }
826
827 static void
828 sms_messagetx (sms_t * h)
829 {
830   unsigned char c = 0, p;
831   for (p = 0; p < h->omsg[1] + 2; p++)
832     c += h->omsg[p];
833   h->omsg[h->omsg[1] + 2] = 0 - c;
834   ast_verbose (VERBOSE_PREFIX_3 "SMS TX %02X %02X %02X %02X %02X %02X...\n", h->omsg[0], h->omsg[1], h->omsg[2],
835                h->omsg[3], h->omsg[4], h->omsg[5]);
836   h->obyte = 1;
837   h->opause = 200;
838   if (h->omsg[0] == 0x93)
839     h->opause = 2400;           /* initial message delay 300ms (for BT) */
840   h->obytep = 0;
841   h->obitp = 0;
842   h->osync = 80;
843   h->obyten = h->omsg[1] + 3;
844 }
845
846
847 static int
848 sms_generate (struct ast_channel *chan, void *data, int len, int samples)
849 {
850   struct ast_frame f;
851   unsigned char waste[AST_FRIENDLY_OFFSET];
852   signed short buf[800];
853   sms_t *h = data;
854   int i;
855
856   if (len > sizeof (buf))
857     {
858       ast_log (LOG_WARNING, "Only doing %d bytes (%d bytes requested)\n", sizeof (buf) / sizeof (signed short), len);
859       len = sizeof (buf);
860       samples = len / 2;
861     }
862   waste[0] = 0;                 /* make compiler happy */
863   f.frametype = AST_FRAME_VOICE;
864   f.subclass = AST_FORMAT_SLINEAR;
865   f.offset = AST_FRIENDLY_OFFSET;
866   f.mallocd = 0;
867   f.data = buf;
868   f.datalen = samples * 2;
869   f.samples = samples;
870   f.src = "app_sms";
871   /* create a buffer containing the digital sms pattern */
872   for (i = 0; i < samples; i++)
873     {
874       buf[i] = 0;
875       if (h->opause)
876         h->opause--;
877       else if (h->obyten || h->osync)
878         {                       /* sending data */
879           buf[i] = wave[h->ophase];
880           if ((h->ophase += ((h->obyte & 1) ? 13 : 21)) >= 80)
881             h->ophase -= 80;
882           if ((h->ophasep += 12) >= 80)
883             {                   /* next bit */
884               h->ophasep -= 80;
885               if (h->osync)
886                 h->osync--;     /* sending sync bits */
887               else
888                 {
889                   h->obyte >>= 1;
890                   h->obitp++;
891                   if (h->obitp == 1)
892                     h->obyte = 0;       /* start bit; */
893                   else if (h->obitp == 2)
894                     h->obyte = h->omsg[h->obytep];
895                   else if (h->obitp == 10)
896                     {
897                       h->obyte = 1;     /* stop bit */
898                       h->obitp = 0;
899                       h->obytep++;
900                       if (h->obytep == h->obyten)
901                         {
902                           h->obytep = h->obyten = 0;    /* sent */
903                           h->osync = 10;        /* trailing marks */
904                         }
905                     }
906                 }
907             }
908         }
909     }
910   if (ast_write (chan, &f) < 0)
911     {
912       ast_log (LOG_WARNING, "Failed to write frame to '%s': %s\n", chan->name, strerror (errno));
913       return -1;
914     }
915   return 0;
916 }
917
918 static void
919 sms_process (sms_t * h, int samples, signed short *data)
920 {
921   if (h->obyten || h->osync)
922     return;                     /* sending */
923   while (samples--)
924     {
925       unsigned long long m0, m1;
926       if (abs (*data) > h->imag)
927         h->imag = abs (*data);
928       else
929         h->imag = h->imag * 7 / 8;
930       if (h->imag > 500)
931         {
932           h->ims0 = (h->ims0 * 6 + *data * wave[h->ips0]) / 7;
933           h->idle = 0;
934           h->imc0 = (h->imc0 * 6 + *data * wave[h->ipc0]) / 7;
935           h->ims1 = (h->ims1 * 6 + *data * wave[h->ips1]) / 7;
936           h->imc1 = (h->imc1 * 6 + *data * wave[h->ipc1]) / 7;
937           m0 = h->ims0 * h->ims0 + h->imc0 * h->imc0;
938           m1 = h->ims1 * h->ims1 + h->imc1 * h->imc1;
939           if ((h->ips0 += 21) >= 80)
940             h->ips0 -= 80;
941           if ((h->ipc0 += 21) >= 80)
942             h->ipc0 -= 80;
943           if ((h->ips1 += 13) >= 80)
944             h->ips1 -= 80;
945           if ((h->ipc1 += 13) >= 80)
946             h->ipc1 -= 80;
947           {
948             char bit;
949             h->ibith <<= 1;
950             if (m1 > m0)
951               h->ibith |= 1;
952             if (h->ibith & 8)
953               h->ibitt--;
954             if (h->ibith & 1)
955               h->ibitt++;
956             bit = ((h->ibitt > 1) ? 1 : 0);
957             if (bit != h->ibitl)
958               h->ibitc = 1;
959             else
960               h->ibitc++;
961             h->ibitl = bit;
962             if (!h->ibitn && h->ibitc == 4 && !bit)
963               {
964                 h->ibitn = 1;
965                 h->iphasep = 0;
966               }
967             if (bit && h->ibitc == 200)
968               {                 /* sync, restart message */
969                 h->ierr = h->ibitn = h->ibytep = h->ibytec = 0;
970               }
971             if (h->ibitn)
972               {
973                 h->iphasep += 12;
974                 if (h->iphasep >= 80)
975                   {             /* next bit */
976                     h->iphasep -= 80;
977                     if (h->ibitn++ == 9)
978                       {         /* end of byte */
979                         if (!bit)       /* bad stop bit */
980                           h->ierr = 0xFF;       /* unknown error */
981                         else
982                           {
983                             if (h->ibytep < sizeof (h->imsg))
984                               {
985                                 h->imsg[h->ibytep] = h->ibytev;
986                                 h->ibytec += h->ibytev;
987                                 h->ibytep++;
988                               }
989                             else if (h->ibytep == sizeof (h->imsg))
990                               h->ierr = 2;      /* bad message length */
991                             if (h->ibytep > 1 && h->ibytep == 3 + h->imsg[1] && !h->ierr)
992                               {
993                                 if (!h->ibytec)
994                                   sms_messagerx (h);
995                                 else
996                                   h->ierr = 1;  /* bad checksum */
997                               }
998                           }
999                         h->ibitn = 0;
1000                       }
1001                     h->ibytev = (h->ibytev >> 1) + (bit ? 0x80 : 0);
1002                   }
1003               }
1004           }
1005         }
1006       else
1007         {                       /* lost carrier */
1008           if (h->idle++ == 80000)
1009             {                   /* nothing happening */
1010               ast_log (LOG_EVENT, "No data, hanging up\n");
1011               h->hangup = 1;
1012             }
1013           if (h->ierr)
1014             {                   /* error */
1015               h->omsg[0] = 0x92;        /* error */
1016               h->omsg[1] = 1;
1017               h->omsg[2] = h->ierr;
1018               sms_messagetx (h);        /* send error */
1019             }
1020           h->ierr = h->ibitn = h->ibytep = h->ibytec = 0;
1021         }
1022       data++;
1023     }
1024 }
1025
1026 static struct ast_generator smsgen = {
1027 alloc:sms_alloc,
1028 release:sms_release,
1029 generate:sms_generate,
1030 };
1031
1032 static int
1033 sms_exec (struct ast_channel *chan, void *data)
1034 {
1035   int res = -1;
1036   struct localuser *u;
1037   struct ast_frame *f;
1038   sms_t h = { 0 };
1039   h.ipc0 = h.ipc1 = 20;         /* phase for cosine */
1040   h.dcs = 0xF1;                 /* default */
1041   if (!data)
1042     {
1043       ast_log (LOG_ERROR, "Requires queue name at least\n");
1044       return -1;
1045     }
1046
1047   if (chan->callerid)
1048     {                           /* get caller ID. Used as originating address on sc side receives */
1049       char temp[256], *name, *num;
1050       strncpy (temp, chan->callerid, sizeof (temp));
1051       ast_callerid_parse (temp, &name, &num);
1052       if (!num)
1053         num = temp;
1054       ast_shrink_phone_number (num);
1055       if (strlen (num) < sizeof (h.cli))
1056         strcpy (h.cli, num);
1057     }
1058
1059   {
1060     char *d = data, *p, answer = 0;
1061     if (!*d || *d == '|')
1062       {
1063         ast_log (LOG_ERROR, "Requires queue name\n");
1064         return -1;
1065       }
1066     for (p = d; *p && *p != '|'; p++);
1067     if (p - d >= sizeof (h.queue))
1068       {
1069         ast_log (LOG_ERROR, "Queue name too long\n");
1070         return -1;
1071       }
1072     strncpy (h.queue, d, p - d);
1073     if (*p == '|')
1074       p++;
1075     d = p;
1076     for (p = h.queue; *p; p++)
1077       if (!isalnum (*p))
1078         *p = '-';               /* make very safe for filenames */
1079     while (*d && *d != '|')
1080       {
1081         switch (*d)
1082           {
1083           case 'a':             /* we have to send the initial FSK sequence */
1084             answer = 1;
1085             break;
1086           case 's':             /* we are acting as a service centre talking to a phone */
1087             h.smsc = 1;
1088             break;
1089             /* the following apply if there is an arg3/4 and apply to the created message file */
1090           case 'r':
1091             h.srr = 1;
1092             break;
1093           case 'o':
1094             h.dcs |= 4;         /* octets */
1095             break;
1096           case '1':
1097           case '2':
1098           case '3':
1099           case '4':
1100           case '5':
1101           case '6':
1102           case '7':             /* set the pid for saved local message */
1103             h.pid = 0x40 + (*d & 0xF);
1104             break;
1105           }
1106         d++;
1107       }
1108     if (*d == '|')
1109       {                         /* submitting a message, not taking call. */
1110         d++;
1111         h.scts = time (0);
1112         for (p = d; *p && *p != '|'; p++);
1113         if (*p)
1114           *p++ = 0;
1115         if (strlen (d) >= sizeof (h.oa))
1116           {
1117             ast_log (LOG_ERROR, "Address too long %s\n", d);
1118             return 0;
1119           }
1120         strcpy (h.smsc ? h.oa : h.da, d);
1121         if (!h.smsc)
1122           strcpy (h.oa, h.cli);
1123         d = p;
1124         if (!(h.dcs & 4) && check7 (h.udl, h.ud))
1125           ast_log (LOG_WARNING, "Invalid GSM characters in %.*s\n", h.udl, h.ud);
1126         if (strlen (d) > ((h.dcs & 4) ? 140 : 160))
1127           {
1128             ast_log (LOG_ERROR, "Message too long %s\n", d);
1129             h.udl = ((h.dcs & 4) ? 140 : 160);
1130           }
1131         else
1132           h.udl = strlen (d);
1133         if (h.udl)
1134           memcpy (h.ud, d, h.udl);
1135         h.smsc = !h.smsc;       /* file woul go in wrong directory otherwise... */
1136         sms_writefile (&h);
1137         return 0;
1138       }
1139
1140     if (answer)
1141       {                         /* set up SMS_EST initial message */
1142         h.omsg[0] = 0x93;
1143         h.omsg[1] = 0;
1144         sms_messagetx (&h);
1145       }
1146   }
1147
1148   LOCAL_USER_ADD (u);
1149   if (chan->_state != AST_STATE_UP)
1150     ast_answer (chan);
1151
1152   res = ast_set_write_format (chan, AST_FORMAT_SLINEAR);
1153   if (res >= 0)
1154     res = ast_set_read_format (chan, AST_FORMAT_SLINEAR);
1155   if (res < 0)
1156     {
1157       LOCAL_USER_REMOVE (u);
1158       ast_log (LOG_ERROR, "Unable to set to linear mode, giving up\n");
1159       return -1;
1160     }
1161
1162   if (ast_activate_generator (chan, &smsgen, &h) < 0)
1163     {
1164       LOCAL_USER_REMOVE (u);
1165       ast_log (LOG_ERROR, "Failed to activate generator on '%s'\n", chan->name);
1166       return -1;
1167     }
1168
1169   /* Do our thing here */
1170   while (ast_waitfor (chan, -1) > -1 && !h.hangup)
1171     {
1172       f = ast_read (chan);
1173       if (!f)
1174         break;
1175       if (f->frametype == AST_FRAME_VOICE)
1176         {
1177           sms_process (&h, f->samples, f->data);
1178         }
1179
1180       ast_frfree (f);
1181     }
1182
1183   sms_log (&h, '?');            /* log incomplete message */
1184
1185   LOCAL_USER_REMOVE (u);
1186   return h.hangup;
1187 }
1188
1189 int
1190 unload_module (void)
1191 {
1192   STANDARD_HANGUP_LOCALUSERS;
1193   return ast_unregister_application (app);
1194 }
1195
1196 int
1197 load_module (void)
1198 {
1199   {                             /* fill in sms8to7 from sms7to8 */
1200     int p;
1201     for (p = 0; p < 256; p++)
1202       sms8to7[p] = 0xE0;        /* inverted question mark and invalid */
1203     for (p = 0; p < 128; p++)
1204       sms8to7[sms7to8[p]] = p;
1205   }
1206   return ast_register_application (app, sms_exec, synopsis, descrip);
1207 }
1208
1209 char *
1210 description (void)
1211 {
1212   return tdesc;
1213 }
1214
1215 int
1216 usecount (void)
1217 {
1218   int res;
1219   STANDARD_USECOUNT (res);
1220   return res;
1221 }
1222
1223 char *
1224 key ()
1225 {
1226   return ASTERISK_GPL_KEY;
1227 }