simplify autoconfig include mechanism (make tholo happy he can use lint again :-)
[asterisk/asterisk.git] / callerid.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 1999 - 2005, Digium, Inc.
5  *
6  * Mark Spencer <markster@digium.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18
19 /*! \file
20  *
21  * \brief CallerID Generation support 
22  *
23  * \author Mark Spencer <markster@digium.com> 
24  */
25
26 #include "asterisk.h"
27
28 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
29
30 #include <time.h>
31 #include <string.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <unistd.h>
35 #include <math.h>
36 #include <ctype.h>
37
38 #include "asterisk/ulaw.h"
39 #include "asterisk/alaw.h"
40 #include "asterisk/frame.h"
41 #include "asterisk/channel.h"
42 #include "asterisk/callerid.h"
43 #include "asterisk/logger.h"
44 #include "asterisk/fskmodem.h"
45 #include "asterisk/options.h"
46 #include "asterisk/utils.h"
47
48 struct callerid_state {
49         fsk_data fskd;
50         char rawdata[256];
51         short oldstuff[160];
52         int oldlen;
53         int pos;
54         int type;
55         int cksum;
56         char name[64];
57         char number[64];
58         int flags;
59         int sawflag;
60         int len;
61
62         int skipflag; 
63         unsigned short crc;
64 };
65
66
67 float cid_dr[4], cid_di[4];
68 float clidsb = 8000.0 / 1200.0;
69 float sasdr, sasdi;
70 float casdr1, casdi1, casdr2, casdi2;
71
72 #define CALLERID_SPACE  2200.0          /*!< 2200 hz for "0" */
73 #define CALLERID_MARK   1200.0          /*!< 1200 hz for "1" */
74 #define SAS_FREQ                 440.0
75 #define CAS_FREQ1               2130.0
76 #define CAS_FREQ2               2750.0
77
78 #define AST_CALLERID_UNKNOWN    "<unknown>"
79
80 static inline void gen_tones(unsigned char *buf, int len, int codec, float ddr1, float ddi1, float ddr2, float ddi2, float *cr1, float *ci1, float *cr2, float *ci2)
81 {
82         int x;
83         float t;
84         for (x=0;x<len;x++) {
85                 t = *cr1 * ddr1 - *ci1 * ddi1;
86                 *ci1 = *cr1 * ddi1 + *ci1 * ddr1;
87                 *cr1 = t;
88                 t = 2.0 - (*cr1 * *cr1 + *ci1 * *ci1);
89                 *cr1 *= t;
90                 *ci1 *= t;      
91
92                 t = *cr2 * ddr2 - *ci2 * ddi2;
93                 *ci2 = *cr2 * ddi2 + *ci2 * ddr2;
94                 *cr2 = t;
95                 t = 2.0 - (*cr2 * *cr2 + *ci2 * *ci2);
96                 *cr2 *= t;
97                 *ci2 *= t;      
98                 buf[x] = AST_LIN2X((*cr1 + *cr2) * 2048.0);
99         }
100 }
101
102 static inline void gen_tone(unsigned char *buf, int len, int codec, float ddr1, float ddi1, float *cr1, float *ci1)
103 {
104         int x;
105         float t;
106         for (x=0;x<len;x++) {
107                 t = *cr1 * ddr1 - *ci1 * ddi1;
108                 *ci1 = *cr1 * ddi1 + *ci1 * ddr1;
109                 *cr1 = t;
110                 t = 2.0 - (*cr1 * *cr1 + *ci1 * *ci1);
111                 *cr1 *= t;
112                 *ci1 *= t;      
113                 buf[x] = AST_LIN2X(*cr1 * 8192.0);
114         }
115 }
116
117 /*! \brief Initialize stuff for inverse FFT */
118 void callerid_init(void)
119 {
120         cid_dr[0] = cos(CALLERID_SPACE * 2.0 * M_PI / 8000.0);
121         cid_di[0] = sin(CALLERID_SPACE * 2.0 * M_PI / 8000.0);
122         cid_dr[1] = cos(CALLERID_MARK * 2.0 * M_PI / 8000.0);
123         cid_di[1] = sin(CALLERID_MARK * 2.0 * M_PI / 8000.0);
124         sasdr = cos(SAS_FREQ * 2.0 * M_PI / 8000.0);
125         sasdi = sin(SAS_FREQ * 2.0 * M_PI / 8000.0);
126         casdr1 = cos(CAS_FREQ1 * 2.0 * M_PI / 8000.0);
127         casdi1 = sin(CAS_FREQ1 * 2.0 * M_PI / 8000.0);
128         casdr2 = cos(CAS_FREQ2 * 2.0 * M_PI / 8000.0);
129         casdi2 = sin(CAS_FREQ2 * 2.0 * M_PI / 8000.0);
130 }
131
132 struct callerid_state *callerid_new(int cid_signalling)
133 {
134         struct callerid_state *cid;
135
136         if ((cid = ast_calloc(1, sizeof(*cid)))) {
137                 cid->fskd.spb = 7.0;            /* 1200 baud */
138                 /* cid->fskd.hdlc = 0; */       /* Async */
139                 cid->fskd.nbit = 8;             /* 8 bits */
140                 cid->fskd.nstop = 1.0;          /* 1 stop bit */
141                 /* cid->fskd.paridad = 0; */    /* No parity */
142                 cid->fskd.bw = 1;               /* Filter 800 Hz */
143                 if (cid_signalling == 2) {      /* v23 signalling */
144                         cid->fskd.f_mark_idx =  4;      /* 1300 Hz */
145                         cid->fskd.f_space_idx = 5;      /* 2100 Hz */
146                 } else {                        /* Bell 202 signalling as default */
147                         cid->fskd.f_mark_idx =  2;      /* 1200 Hz */
148                         cid->fskd.f_space_idx = 3;      /* 2200 Hz */
149                 }
150                 /* cid->fskd.pcola = 0; */      /* No clue */
151                 /* cid->fskd.cont = 0.0; */     /* Digital PLL reset */
152                 /* cid->fskd.x0 = 0.0; */
153                 /* cid->fskd.state = 0; */
154                 cid->flags = CID_UNKNOWN_NAME | CID_UNKNOWN_NUMBER;
155                 /* cid->pos = 0; */
156         }
157
158         return cid;
159 }
160
161 void callerid_get(struct callerid_state *cid, char **name, char **number, int *flags)
162 {
163         *flags = cid->flags;
164         if (cid->flags & (CID_UNKNOWN_NAME | CID_PRIVATE_NUMBER))
165                 *name = NULL;
166         else
167                 *name = cid->name;
168         if (cid->flags & (CID_UNKNOWN_NUMBER | CID_PRIVATE_NUMBER))
169                 *number = NULL;
170         else
171                 *number = cid->number;
172 }
173
174 void callerid_get_dtmf(char *cidstring, char *number, int *flags)
175 {
176         int i;
177         int code;
178
179         /* "Clear" the number-buffer. */
180         number[0] = 0;
181
182         if (strlen(cidstring) < 2) {
183                 ast_log(LOG_DEBUG, "No cid detected\n");
184                 *flags = CID_UNKNOWN_NUMBER;
185                 return;
186         }
187         
188         /* Detect protocol and special types */
189         if (cidstring[0] == 'B') {
190                 /* Handle special codes */
191                 code = atoi(&cidstring[1]);
192                 if (code == 0)
193                         *flags = CID_UNKNOWN_NUMBER;
194                 else if (code == 10) 
195                         *flags = CID_PRIVATE_NUMBER;
196                 else
197                         ast_log(LOG_DEBUG, "Unknown DTMF code %d\n", code);
198         } else if (cidstring[0] == 'D' && cidstring[2] == '#') {
199                 /* .DK special code */
200                 if (cidstring[1] == '1')
201                         *flags = CID_PRIVATE_NUMBER;
202                 if (cidstring[1] == '2' || cidstring[1] == '3')
203                         *flags = CID_UNKNOWN_NUMBER;
204         } else if (cidstring[0] == 'D' || cidstring[0] == 'A') {
205                 /* "Standard" callerid */
206                 for (i = 1; i < strlen(cidstring); i++ ) {
207                         if (cidstring[i] == 'C' || cidstring[i] == '#')
208                                 break;
209                         if (isdigit(cidstring[i]))
210                                 number[i-1] = cidstring[i];
211                         else
212                                 ast_log(LOG_DEBUG, "Unknown CID digit '%c'\n",
213                                         cidstring[i]);
214                 }
215                 number[i-1] = 0;
216         } else if (isdigit(cidstring[0])) {
217                 /* It begins with a digit, so we parse it as a number and hope
218                  * for the best */
219                 ast_log(LOG_WARNING, "Couldn't detect start-character. CID "
220                         "parsing might be unreliable\n");
221                 for (i = 0; i < strlen(cidstring); i++) {
222                         if (isdigit(cidstring[i]))
223                                 number[i] = cidstring[i];
224                         else
225                                 break;
226                 }
227                 number[i] = 0;
228         } else {
229                 ast_log(LOG_DEBUG, "Unknown CID protocol, start digit '%c'\n", 
230                         cidstring[0]);
231                 *flags = CID_UNKNOWN_NUMBER;
232         }
233 }
234
235 int ast_gen_cas(unsigned char *outbuf, int sendsas, int len, int codec)
236 {
237         int pos = 0;
238         int saslen=2400;
239         float cr1 = 1.0;
240         float ci1 = 0.0;
241         float cr2 = 1.0;
242         float ci2 = 0.0;
243         if (sendsas) {
244                 if (len < saslen)
245                         return -1;
246                 gen_tone(outbuf, saslen, codec, sasdr, sasdi, &cr1, &ci1);
247                 len -= saslen;
248                 pos += saslen;
249                 cr2 = cr1;
250                 ci2 = ci1;
251         }
252         gen_tones(outbuf + pos, len, codec, casdr1, casdi1, casdr2, casdi2, &cr1, &ci1, &cr2, &ci2);
253         return 0;
254 }
255
256 static unsigned short calc_crc(unsigned short crc, unsigned char data)
257 {
258         unsigned int i, j, org, dst;
259         org = data;
260         dst = 0;
261
262         for (i=0; i < CHAR_BIT; i++) {
263                 org <<= 1;
264                 dst >>= 1;
265                 if (org & 0x100) {
266                         dst |= 0x80;
267                 }
268         }
269         data = (unsigned char)dst;
270         crc ^= (unsigned int)data << (16 - CHAR_BIT);
271         for ( j=0; j<CHAR_BIT; j++ ) {
272                 if ( crc & 0x8000U )
273                         crc = (crc << 1) ^ 0x1021U ;
274                 else
275                         crc <<= 1 ;
276         }
277         return crc;
278 }
279
280 int callerid_feed_jp(struct callerid_state *cid, unsigned char *ubuf, int len, int codec)
281 {
282         int mylen = len;
283         int olen;
284         int b = 'X';
285         int b2 ;
286         int res;
287         int x;
288         short *buf;
289         short *obuf;
290
291         if (!(buf = ast_calloc(1, 2 * len + cid->oldlen))) {
292                 return -1;
293         }
294
295         obuf = buf;
296         memcpy(buf, cid->oldstuff, cid->oldlen);
297         mylen += cid->oldlen/2;
298
299         for (x=0;x<len;x++) 
300                 buf[x+cid->oldlen/2] = AST_XLAW(ubuf[x]);
301
302         while (mylen >= 160) {
303         b = b2 = 0 ;
304                 olen = mylen;
305                 res = fsk_serie(&cid->fskd, buf, &mylen, &b);
306
307                 if (mylen < 0) {
308                         ast_log(LOG_ERROR, "fsk_serie made mylen < 0 (%d)\n", mylen);
309                         return -1;
310                 }
311
312                 buf += (olen - mylen);
313
314                 if (res < 0) {
315                         ast_log(LOG_NOTICE, "fsk_serie failed\n");
316                         return -1;
317                 }
318
319                 if (res == 1) {
320
321                         b2 = b ;
322                         b  = b & 0x7f ;
323
324                         /* crc checksum calculation */
325                         if ( cid->sawflag > 1 ) {
326                                 cid->crc = calc_crc(cid->crc, (unsigned char)b2);
327                         }
328
329                         /* Ignore invalid bytes */
330                         if (b > 0xff) {
331                                 continue;
332                         }
333
334                         /* skip DLE if needed */
335                         if ( cid->sawflag > 0 ) {
336                                 if ( cid->sawflag != 5 && cid->skipflag == 0 && b == 0x10 ) {
337                                         cid->skipflag = 1 ;
338                                         continue ;
339                                 }
340                         }
341                         if ( cid->skipflag == 1 ) {
342                                 cid->skipflag = 0 ;
343                         }
344
345                         /* caller id retrieval */
346                         switch(cid->sawflag) {
347                                 case 0: /* DLE */
348                                         if (b == 0x10) {
349                                                 cid->sawflag = 1;
350                                                 cid->skipflag = 0;
351                                                 cid->crc = 0;
352                                         }
353                                         break;
354                                 case 1: /* SOH */
355                                         if (b == 0x01) {
356                                                 cid->sawflag = 2;
357                                         }
358                                         break ;
359                                 case 2: /* HEADER */
360                                         if (b == 0x07) {
361                                                 cid->sawflag = 3;
362                                         }
363                                         break;
364                                 case 3: /* STX */
365                                         if (b == 0x02) {
366                                                 cid->sawflag = 4;
367                                         }
368                                         break;
369                                 case 4: /* SERVICE TYPE */
370                                         if (b == 0x40) {
371                                                 cid->sawflag = 5;
372                                         }
373                                         break;
374                                 case 5: /* Frame Length */
375                                         cid->sawflag = 6;
376                                         break;  
377                                 case 6: /* NUMBER TYPE */
378                                         cid->sawflag = 7;
379                                         cid->pos = 0;
380                                         cid->rawdata[cid->pos++] = b;
381                                         break;
382                                 case 7: /* NUMBER LENGTH */
383                                         cid->sawflag = 8;
384                                         cid->len = b;
385                                         if ( (cid->len+2) >= sizeof( cid->rawdata ) ) {
386                                                 ast_log(LOG_WARNING, "too long caller id string\n" ) ;
387                                                 return -1;
388                                         }
389                                         cid->rawdata[cid->pos++] = b;
390                                         break;
391                                 case 8: /* Retrieve message */
392                                         cid->rawdata[cid->pos++] = b;
393                                         cid->len--;
394                                         if (cid->len<=0) {
395                                                 cid->rawdata[cid->pos] = '\0';
396                                                 cid->sawflag = 9;
397                                         }
398                                         break;
399                                 case 9: /* ETX */
400                                         cid->sawflag = 10;
401                                         break;
402                                 case 10: /* CRC Checksum 1 */
403                                         cid->sawflag = 11;
404                                         break;
405                                 case 11: /* CRC Checksum 2 */
406                                         cid->sawflag = 12;
407                                         if ( cid->crc != 0 ) {
408                                                 ast_log(LOG_WARNING, "crc checksum error\n" ) ;
409                                                 return -1;
410                                         } 
411                                         /* extract caller id data */
412                                         for (x=0; x<cid->pos; ) {
413                                                 switch (cid->rawdata[x++]) {
414                                                 case 0x02: /* caller id  number */
415                                                         cid->number[0] = '\0';
416                                                         cid->name[0] = '\0';
417                                                         cid->flags = 0;
418                                                         res = cid->rawdata[x++];
419                                                         ast_copy_string(cid->number, &cid->rawdata[x], res+1 );
420                                                         x += res;
421                                                         break;
422                                                 case 0x21: /* additional information */
423                                                         /* length */
424                                                         x++; 
425                                                         /* number type */
426                                                         switch (cid->rawdata[x]) { 
427                                                         case 0x00: /* unknown */
428                                                         case 0x01: /* international number */
429                                                         case 0x02: /* domestic number */
430                                                         case 0x03: /* network */
431                                                         case 0x04: /* local call */
432                                                         case 0x06: /* short dial number */
433                                                         case 0x07: /* reserved */
434                                                         default:   /* reserved */
435                                                                 if (option_debug > 1)
436                                                                         ast_log(LOG_DEBUG, "cid info:#1=%X\n", cid->rawdata[x]);
437                                                                 break ;
438                                                         }
439                                                         x++; 
440                                                         /* numbering plan octed 4 */
441                                                         x++; 
442                                                         /* numbering plan octed 5 */
443                                                         switch (cid->rawdata[x]) { 
444                                                         case 0x00: /* unknown */
445                                                         case 0x01: /* recommendation E.164 ISDN */
446                                                         case 0x03: /* recommendation X.121 */
447                                                         case 0x04: /* telex dial plan */
448                                                         case 0x08: /* domestic dial plan */
449                                                         case 0x09: /* private dial plan */
450                                                         case 0x05: /* reserved */
451                                                         default:   /* reserved */
452                                                                 if (option_debug > 1)
453                                                                         ast_log(LOG_DEBUG, "cid info:#2=%X\n", cid->rawdata[x]);
454                                                                 break ;
455                                                         }
456                                                         x++; 
457                                                         break ;
458                                                 case 0x04: /* no callerid reason */
459                                                         /* length */
460                                                         x++; 
461                                                         /* no callerid reason code */
462                                                         switch (cid->rawdata[x]) {
463                                                         case 'P': /* caller id denied by user */
464                                                         case 'O': /* service not available */
465                                                         case 'C': /* pay phone */
466                                                         case 'S': /* service congested */
467                                                                 cid->flags |= CID_UNKNOWN_NUMBER;
468                                                                 if (option_debug > 1)
469                                                                         ast_log(LOG_DEBUG, "no cid reason:%c\n",cid->rawdata[x]);
470                                                                 break ;
471                                                         }
472                                                         x++; 
473                                                         break ;
474                                                 case 0x09: /* dialed number */
475                                                         /* length */
476                                                         res = cid->rawdata[x++];
477                                                         /* dialed number */
478                                                         x += res;
479                                                         break ;
480                                                 case 0x22: /* dialed number additional information */
481                                                         /* length */
482                                                         x++;
483                                                         /* number type */
484                                                         switch (cid->rawdata[x]) {
485                                                         case 0x00: /* unknown */
486                                                         case 0x01: /* international number */
487                                                         case 0x02: /* domestic number */
488                                                         case 0x03: /* network */
489                                                         case 0x04: /* local call */
490                                                         case 0x06: /* short dial number */
491                                                         case 0x07: /* reserved */
492                                                         default:   /* reserved */
493                                                                 if (option_debug > 1)
494                                                                         ast_log(LOG_NOTICE, "did info:#1=%X\n", cid->rawdata[x]);
495                                                                 break ;
496                                                         }
497                                                         x++;
498                                                         /* numbering plan octed 4 */
499                                                         x++;
500                                                         /* numbering plan octed 5 */
501                                                         switch (cid->rawdata[x]) {
502                                                         case 0x00: /* unknown */
503                                                         case 0x01: /* recommendation E.164 ISDN */
504                                                         case 0x03: /* recommendation X.121 */
505                                                         case 0x04: /* telex dial plan */
506                                                         case 0x08: /* domestic dial plan */
507                                                         case 0x09: /* private dial plan */
508                                                         case 0x05: /* reserved */
509                                                         default:   /* reserved */
510                                                                 if (option_debug > 1)
511                                                                         ast_log(LOG_DEBUG, "did info:#2=%X\n", cid->rawdata[x]);
512                                                                 break ;
513                                                         }
514                                                         x++;
515                                                         break ;
516                                                 }
517                                         }
518                                         return 1;
519                                         break;
520                                 default:
521                                         ast_log(LOG_ERROR, "invalid value in sawflag %d\n", cid->sawflag);
522                         }
523                 }
524         }
525         if (mylen) {
526                 memcpy(cid->oldstuff, buf, mylen * 2);
527                 cid->oldlen = mylen * 2;
528         } else
529                 cid->oldlen = 0;
530         free(obuf);
531         return 0;
532 }
533
534
535 int callerid_feed(struct callerid_state *cid, unsigned char *ubuf, int len, int codec)
536 {
537         int mylen = len;
538         int olen;
539         int b = 'X';
540         int res;
541         int x;
542         short *buf;
543         short *obuf;
544
545         if (!(buf = ast_calloc(1, 2 * len + cid->oldlen))) {
546                 return -1;
547         }
548
549         obuf = buf;
550         memcpy(buf, cid->oldstuff, cid->oldlen);
551         mylen += cid->oldlen/2;
552
553         for (x=0;x<len;x++) 
554                 buf[x+cid->oldlen/2] = AST_XLAW(ubuf[x]);
555         while(mylen >= 160) {
556                 olen = mylen;
557                 res = fsk_serie(&cid->fskd, buf, &mylen, &b);
558                 if (mylen < 0) {
559                         ast_log(LOG_ERROR, "fsk_serie made mylen < 0 (%d)\n", mylen);
560                         free(obuf);
561                         return -1;
562                 }
563                 buf += (olen - mylen);
564                 if (res < 0) {
565                         ast_log(LOG_NOTICE, "fsk_serie failed\n");
566                         return -1;
567                 }
568                 if (res == 1) {
569                         /* Ignore invalid bytes */
570                         if (b > 0xff)
571                                 continue;
572                         switch(cid->sawflag) {
573                         case 0: /* Look for flag */
574                                 if (b == 'U')
575                                         cid->sawflag = 2;
576                                 break;
577                         case 2: /* Get lead-in */
578                                 if ((b == 0x04) || (b == 0x80)) {
579                                         cid->type = b;
580                                         cid->sawflag = 3;
581                                         cid->cksum = b;
582                                 }
583                                 break;
584                         case 3: /* Get length */
585                                 /* Not a lead in.  We're ready  */
586                                 cid->sawflag = 4;
587                                 cid->len = b;
588                                 cid->pos = 0;
589                                 cid->cksum += b;
590                                 break;
591                         case 4: /* Retrieve message */
592                                 if (cid->pos >= 128) {
593                                         ast_log(LOG_WARNING, "Caller ID too long???\n");
594                                         free(obuf);
595                                         return -1;
596                                 }
597                                 cid->rawdata[cid->pos++] = b;
598                                 cid->len--;
599                                 cid->cksum += b;
600                                 if (!cid->len) {
601                                         cid->rawdata[cid->pos] = '\0';
602                                         cid->sawflag = 5;
603                                 }
604                                 break;
605                         case 5: /* Check checksum */
606                                 if (b != (256 - (cid->cksum & 0xff))) {
607                                         ast_log(LOG_NOTICE, "Caller*ID failed checksum\n");
608                                         /* Try again */
609                                         cid->sawflag = 0;
610                                         break;
611                                 }
612                 
613                                 cid->number[0] = '\0';
614                                 cid->name[0] = '\0';
615                                 /* If we get this far we're fine.  */
616                                 if (cid->type == 0x80) {
617                                         /* MDMF */
618                                         /* Go through each element and process */
619                                         for (x=0;x< cid->pos;) {
620                                                 switch(cid->rawdata[x++]) {
621                                                 case 1:
622                                                         /* Date */
623                                                         break;
624                                                 case 2: /* Number */
625                                                 case 3: /* Number (for Zebble) */
626                                                 case 4: /* Number */
627                                                         res = cid->rawdata[x];
628                                                         if (res > 32) {
629                                                                 ast_log(LOG_NOTICE, "Truncating long caller ID number from %d bytes to 32\n", cid->rawdata[x]);
630                                                                 res = 32; 
631                                                         }
632                                                         if (ast_strlen_zero(cid->number)) {
633                                                                 memcpy(cid->number, cid->rawdata + x + 1, res);
634                                                                 /* Null terminate */
635                                                                 cid->number[res] = '\0';
636                                                         }
637                                                         break;
638                                                 case 6: /* Stentor Call Qualifier (ie. Long Distance call) */
639                                                         break;
640                                                 case 7: /* Name */
641                                                 case 8: /* Name */
642                                                         res = cid->rawdata[x];
643                                                         if (res > 32) {
644                                                                 ast_log(LOG_NOTICE, "Truncating long caller ID name from %d bytes to 32\n", cid->rawdata[x]);
645                                                                 res = 32; 
646                                                         }
647                                                         memcpy(cid->name, cid->rawdata + x + 1, res);
648                                                         cid->name[res] = '\0';
649                                                         break;
650                                                 case 17: /* UK: Call type, 1=Voice Call, 2=Ringback when free, 129=Message waiting  */
651                                                 case 19: /* UK: Network message system status (Number of messages waiting) */
652                                                 case 22: /* Something French */
653                                                         break;
654                                                 default:
655                                                         ast_log(LOG_NOTICE, "Unknown IE %d\n", cid->rawdata[x-1]);
656                                                 }
657                                                 x += cid->rawdata[x];
658                                                 x++;
659                                         }
660                                 } else {
661                                         /* SDMF */
662                                         ast_copy_string(cid->number, cid->rawdata + 8, sizeof(cid->number));
663                                 }
664                                 /* Update flags */
665                                 cid->flags = 0;
666                                 if (!strcmp(cid->number, "P")) {
667                                         strcpy(cid->number, "");
668                                         cid->flags |= CID_PRIVATE_NUMBER;
669                                 } else if (!strcmp(cid->number, "O") || ast_strlen_zero(cid->number)) {
670                                         strcpy(cid->number, "");
671                                         cid->flags |= CID_UNKNOWN_NUMBER;
672                                 }
673                                 if (!strcmp(cid->name, "P")) {
674                                         strcpy(cid->name, "");
675                                         cid->flags |= CID_PRIVATE_NAME;
676                                 } else if (!strcmp(cid->name, "O") || ast_strlen_zero(cid->name)) {
677                                         strcpy(cid->name, "");
678                                         cid->flags |= CID_UNKNOWN_NAME;
679                                 }
680                                 free(obuf);
681                                 return 1;
682                                 break;
683                         default:
684                                 ast_log(LOG_ERROR, "Dunno what to do with a digit in sawflag %d\n", cid->sawflag);
685                         }
686                 }
687         }
688         if (mylen) {
689                 memcpy(cid->oldstuff, buf, mylen * 2);
690                 cid->oldlen = mylen * 2;
691         } else
692                 cid->oldlen = 0;
693         free(obuf);
694         return 0;
695 }
696
697 void callerid_free(struct callerid_state *cid)
698 {
699         free(cid);
700 }
701
702 static int callerid_genmsg(char *msg, int size, const char *number, const char *name, int flags)
703 {
704         time_t t;
705         struct tm tm;
706         char *ptr;
707         int res;
708         int i,x;
709         /* Get the time */
710         time(&t);
711         localtime_r(&t,&tm);
712         
713         ptr = msg;
714         
715         /* Format time and message header */
716         res = snprintf(ptr, size, "\001\010%02d%02d%02d%02d", tm.tm_mon + 1,
717                                 tm.tm_mday, tm.tm_hour, tm.tm_min);
718         size -= res;
719         ptr += res;
720         if (ast_strlen_zero(number) || (flags & CID_UNKNOWN_NUMBER)) {
721                 /* Indicate number not known */
722                 res = snprintf(ptr, size, "\004\001O");
723                 size -= res;
724                 ptr += res;
725         } else if (flags & CID_PRIVATE_NUMBER) {
726                 /* Indicate number is private */
727                 res = snprintf(ptr, size, "\004\001P");
728                 size -= res;
729                 ptr += res;
730         } else {
731                 /* Send up to 16 digits of number MAX */
732                 i = strlen(number);
733                 if (i > 16) i = 16;
734                 res = snprintf(ptr, size, "\002%c", i);
735                 size -= res;
736                 ptr += res;
737                 for (x = 0; x < i; x++)
738                         ptr[x] = number[x];
739                 ptr[i] = '\0';
740                 ptr += i;
741                 size -= i;
742         }
743
744         if (ast_strlen_zero(name) || (flags & CID_UNKNOWN_NAME)) {
745                 /* Indicate name not known */
746                 res = snprintf(ptr, size, "\010\001O");
747                 size -= res;
748                 ptr += res;
749         } else if (flags & CID_PRIVATE_NAME) {
750                 /* Indicate name is private */
751                 res = snprintf(ptr, size, "\010\001P");
752                 size -= res;
753                 ptr += res;
754         } else {
755                 /* Send up to 16 digits of name MAX */
756                 i = strlen(name);
757                 if (i > 16) i = 16;
758                 res = snprintf(ptr, size, "\007%c", i);
759                 size -= res;
760                 ptr += res;
761                 for (x=0;x<i;x++)
762                         ptr[x] = name[x];
763                 ptr[i] = '\0';
764                 ptr += i;
765                 size -= i;
766         }
767         return (ptr - msg);
768         
769 }
770
771 int vmwi_generate(unsigned char *buf, int active, int mdmf, int codec)
772 {
773         unsigned char msg[256];
774         int len=0;
775         int sum;
776         int x;
777         int bytes = 0;
778         float cr = 1.0;
779         float ci = 0.0;
780         float scont = 0.0;
781         if (mdmf) {
782                 /* MDMF Message waiting */
783                 msg[len++] = 0x82;
784                 /* Length is 3 */
785                 msg[len++] = 3;
786                 /* IE is "Message Waiting Parameter" */
787                 msg[len++] = 0xb;
788                 /* Length of IE is one */
789                 msg[len++] = 1;
790                 /* Active or not */
791                 if (active)
792                         msg[len++] = 0xff;
793                 else
794                         msg[len++] = 0x00;
795         } else {
796                 /* SDMF Message waiting */
797                 msg[len++] = 0x6;
798                 /* Length is 3 */
799                 msg[len++] = 3;
800                 if (active) {
801                         msg[len++] = 0x42;
802                         msg[len++] = 0x42;
803                         msg[len++] = 0x42;
804                 } else {
805                         msg[len++] = 0x6f;
806                         msg[len++] = 0x6f;
807                         msg[len++] = 0x6f;
808                 }
809         }
810         sum = 0;
811         for (x=0; x<len; x++)
812                 sum += msg[x];
813         sum = (256 - (sum & 255));
814         msg[len++] = sum;
815         /* Wait a half a second */
816         for (x=0; x<4000; x++)
817                 PUT_BYTE(0x7f);
818         /* Transmit 30 0x55's (looks like a square wave) for channel seizure */
819         for (x=0; x<30; x++)
820                 PUT_CLID(0x55);
821         /* Send 170ms of callerid marks */
822         for (x=0; x<170; x++)
823                 PUT_CLID_MARKMS;
824         for (x=0; x<len; x++) {
825                 PUT_CLID(msg[x]);
826         }
827         /* Send 50 more ms of marks */
828         for (x=0; x<50; x++)
829                 PUT_CLID_MARKMS;
830         return bytes;
831 }
832
833 int callerid_generate(unsigned char *buf, const char *number, const char *name, int flags, int callwaiting, int codec)
834 {
835         int bytes=0;
836         int x, sum;
837         int len;
838
839         /* Initial carriers (real/imaginary) */
840         float cr = 1.0;
841         float ci = 0.0;
842         float scont = 0.0;
843         char msg[256];
844         len = callerid_genmsg(msg, sizeof(msg), number, name, flags);
845         if (!callwaiting) {
846                 /* Wait a half a second */
847                 for (x=0; x<4000; x++)
848                         PUT_BYTE(0x7f);
849                 /* Transmit 30 0x55's (looks like a square wave) for channel seizure */
850                 for (x=0; x<30; x++)
851                         PUT_CLID(0x55);
852         }
853         /* Send 150ms of callerid marks */
854         for (x=0; x<150; x++)
855                 PUT_CLID_MARKMS;
856         /* Send 0x80 indicating MDMF format */
857         PUT_CLID(0x80);
858         /* Put length of whole message */
859         PUT_CLID(len);
860         sum = 0x80 + strlen(msg);
861         /* Put each character of message and update checksum */
862         for (x=0; x<len; x++) {
863                 PUT_CLID(msg[x]);
864                 sum += msg[x];
865         }
866         /* Send 2's compliment of sum */
867         PUT_CLID(256 - (sum & 255));
868
869         /* Send 50 more ms of marks */
870         for (x=0; x<50; x++)
871                 PUT_CLID_MARKMS;
872         
873         return bytes;
874 }
875
876 /*! \brief Clean up phone string
877  * remove '(', ' ', ')', non-trailing '.', and '-' not in square brackets.
878  * Basically, remove anything that could be invalid in a pattern.
879  */
880 void ast_shrink_phone_number(char *n)
881 {
882         int x, y=0;
883         int bracketed = 0;
884
885         for (x=0; n[x]; x++) {
886                 switch(n[x]) {
887                 case '[':
888                         bracketed++;
889                         n[y++] = n[x];
890                         break;
891                 case ']':
892                         bracketed--;
893                         n[y++] = n[x];
894                         break;
895                 case '-':
896                         if (bracketed)
897                                 n[y++] = n[x];
898                         break;
899                 case '.':
900                         if (!n[x+1])
901                                 n[y++] = n[x];
902                         break;
903                 default:
904                         if (!strchr("( )", n[x]))
905                                 n[y++] = n[x];
906                 }
907         }
908         n[y] = '\0';
909 }
910
911 /*! \brief Checks if phone number consists of valid characters 
912         \param exten    String that needs to be checked
913         \param valid    Valid characters in string
914         \return 1 if valid string, 0 if string contains invalid characters
915 */
916 static int ast_is_valid_string(const char *exten, const char *valid)
917 {
918         int x;
919
920         if (ast_strlen_zero(exten))
921                 return 0;
922         for (x=0; exten[x]; x++)
923                 if (!strchr(valid, exten[x]))
924                         return 0;
925         return 1;
926 }
927
928 /*! \brief checks if string consists only of digits and * \# and + 
929         \return 1 if string is valid AST phone number
930         \return 0 if not
931 */
932 int ast_isphonenumber(const char *n)
933 {
934         return ast_is_valid_string(n, "0123456789*#+");
935 }
936
937 /*! \brief checks if string consists only of digits and ( ) - * \# and + 
938         Pre-qualifies the string for ast_shrink_phone_number()
939         \return 1 if string is valid AST shrinkable phone number
940         \return 0 if not
941 */
942 int ast_is_shrinkable_phonenumber(const char *exten)
943 {
944         return ast_is_valid_string(exten, "0123456789*#+()-.");
945 }
946
947 /*! \brief parse string for caller id information 
948         \return always returns 0, as the code always returns something.
949   XXX note that 'name' is not parsed consistently e.g. we have
950
951         input                   location        name
952         " foo bar " <123>       123             ' foo bar ' (with spaces around)
953         " foo bar "             NULL            'foo bar' (without spaces around)
954         " foo bar  <123>"       123             '" foo bar'
955   The parsing of leading and trailing space/quotes should be more consistent.
956 */
957 int ast_callerid_parse(char *instr, char **name, char **location)
958 {
959         char *ns, *ne, *ls, *le;
960
961         /* Try "name" <location> format or name <location> format */
962         if ((ls = strchr(instr, '<')) && (le = strchr(ls, '>'))) {
963                 *ls = *le = '\0';       /* location found, trim off the brackets */
964                 *location = ls + 1;     /* and this is the result */
965                 if ((ns = strchr(instr, '"')) && (ne = strchr(ns + 1, '"'))) {
966                         *ns = *ne = '\0';       /* trim off the quotes */
967                         *name = ns + 1;         /* and this is the name */
968                 } else { /* no quotes, trim off leading and trailing spaces */
969                         *name = ast_skip_blanks(instr);
970                         ast_trim_blanks(*name);
971                 }
972         } else {        /* no valid brackets */
973                 char tmp[256];
974
975                 ast_copy_string(tmp, instr, sizeof(tmp));
976                 ast_shrink_phone_number(tmp);
977                 if (ast_isphonenumber(tmp)) {   /* Assume it's just a location */
978                         *name = NULL;
979                         strcpy(instr, tmp); /* safe, because tmp will always be the same size or smaller than instr */
980                         *location = instr;
981                 } else { /* Assume it's just a name. */
982                         *location = NULL;
983                         if ((ns = strchr(instr, '"')) && (ne = strchr(ns + 1, '"'))) {
984                                 *ns = *ne = '\0';       /* trim off the quotes */
985                                 *name = ns + 1;         /* and this is the name */
986                         } else { /* no quotes, trim off leading and trailing spaces */
987                                 *name = ast_skip_blanks(instr);
988                                 ast_trim_blanks(*name);
989                         }
990                 }
991         }
992         return 0;
993 }
994
995 static int __ast_callerid_generate(unsigned char *buf, const char *name, const char *number, int callwaiting, int codec)
996 {
997         if (ast_strlen_zero(name))
998                 name = NULL;
999         if (ast_strlen_zero(number))
1000                 number = NULL;
1001         return callerid_generate(buf, number, name, 0, callwaiting, codec);
1002 }
1003
1004 int ast_callerid_generate(unsigned char *buf, const char *name, const char *number, int codec)
1005 {
1006         return __ast_callerid_generate(buf, name, number, 0, codec);
1007 }
1008
1009 int ast_callerid_callwaiting_generate(unsigned char *buf, const char *name, const char *number, int codec)
1010 {
1011         return __ast_callerid_generate(buf, name, number, 1, codec);
1012 }
1013
1014 char *ast_callerid_merge(char *buf, int bufsiz, const char *name, const char *num, const char *unknown)
1015 {
1016         if (!unknown)
1017                 unknown = "<unknown>";
1018         if (name && num)
1019                 snprintf(buf, bufsiz, "\"%s\" <%s>", name, num);
1020         else if (name) 
1021                 ast_copy_string(buf, name, bufsiz);
1022         else if (num)
1023                 ast_copy_string(buf, num, bufsiz);
1024         else
1025                 ast_copy_string(buf, unknown, bufsiz);
1026         return buf;
1027 }
1028
1029 int ast_callerid_split(const char *buf, char *name, int namelen, char *num, int numlen)
1030 {
1031         char *tmp;
1032         char *l = NULL, *n = NULL;
1033
1034         tmp = ast_strdupa(buf);
1035         ast_callerid_parse(tmp, &n, &l);
1036         if (n)
1037                 ast_copy_string(name, n, namelen);
1038         else
1039                 name[0] = '\0';
1040         if (l) {
1041                 ast_shrink_phone_number(l);
1042                 ast_copy_string(num, l, numlen);
1043         } else
1044                 num[0] = '\0';
1045         return 0;
1046 }
1047
1048 /*! \brief Translation table for Caller ID Presentation settings */
1049 static struct {
1050         int val;
1051         char *name;
1052         char *description;
1053 } pres_types[] = {
1054         {  AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED, "allowed_not_screened", "Presentation Allowed, Not Screened"},
1055         {  AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, "allowed_passed_screen", "Presentation Allowed, Passed Screen"},
1056         {  AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN, "allowed_failed_screen", "Presentation Allowed, Failed Screen"},
1057         {  AST_PRES_ALLOWED_NETWORK_NUMBER, "allowed", "Presentation Allowed, Network Number"},
1058         {  AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED, "prohib_not_screened", "Presentation Prohibited, Not Screened"},
1059         {  AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN, "prohib_passed_screen", "Presentation Prohibited, Passed Screen"},
1060         {  AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN, "prohib_failed_screen", "Presentation Prohibited, Failed Screen"},
1061         {  AST_PRES_PROHIB_NETWORK_NUMBER, "prohib", "Presentation Prohibited, Network Number"},
1062         {  AST_PRES_NUMBER_NOT_AVAILABLE, "unavailable", "Number Unavailable"},
1063 };
1064
1065 /*! \brief Convert caller ID text code to value 
1066         used in config file parsing
1067         \param data text string
1068         \return value AST_PRES_ from callerid.h 
1069 */
1070 int ast_parse_caller_presentation(const char *data)
1071 {
1072         int i;
1073
1074         for (i = 0; i < ((sizeof(pres_types) / sizeof(pres_types[0]))); i++) {
1075                 if (!strcasecmp(pres_types[i].name, data))
1076                         return pres_types[i].val;
1077         }
1078
1079         return -1;
1080 }
1081
1082 /*! \brief Convert caller ID pres value to explanatory string 
1083         \param data value (see callerid.h AST_PRES_ ) 
1084         \return string for human presentation
1085 */
1086 const char *ast_describe_caller_presentation(int data)
1087 {
1088         int i;
1089
1090         for (i = 0; i < ((sizeof(pres_types) / sizeof(pres_types[0]))); i++) {
1091                 if (pres_types[i].val == data)
1092                         return pres_types[i].description;
1093         }
1094
1095         return "unknown";
1096 }