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