various whitespace changes to reduce indentation and to better conform to
[asterisk/asterisk.git] / main / 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
290         buf = alloca(2 * len + cid->oldlen);
291
292         memcpy(buf, cid->oldstuff, cid->oldlen);
293         mylen += cid->oldlen/2;
294
295         for (x = 0; x < len; x++) 
296                 buf[x+cid->oldlen/2] = AST_XLAW(ubuf[x]);
297
298         while (mylen >= 160) {
299                 b = b2 = 0;
300                 olen = mylen;
301                 res = fsk_serie(&cid->fskd, buf, &mylen, &b);
302
303                 if (mylen < 0) {
304                         ast_log(LOG_ERROR, "fsk_serie made mylen < 0 (%d)\n", mylen);
305                         return -1;
306                 }
307
308                 buf += (olen - mylen);
309
310                 if (res < 0) {
311                         ast_log(LOG_NOTICE, "fsk_serie failed\n");
312                         return -1;
313                 }
314
315                 if (res == 1) {
316                         b2 = b;
317                         b  &= 0x7f;
318
319                         /* crc checksum calculation */
320                         if (cid->sawflag > 1)
321                                 cid->crc = calc_crc(cid->crc, (unsigned char) b2);
322
323                         /* Ignore invalid bytes */
324                         if (b > 0xff)
325                                 continue;
326
327                         /* skip DLE if needed */
328                         if (cid->sawflag > 0) {
329                                 if (cid->sawflag != 5 && cid->skipflag == 0 && b == 0x10) {
330                                         cid->skipflag = 1 ;
331                                         continue ;
332                                 }
333                         }
334                         if (cid->skipflag == 1)
335                                 cid->skipflag = 0 ;
336
337                         /* caller id retrieval */
338                         switch(cid->sawflag) {
339                         case 0: /* DLE */
340                                 if (b == 0x10) {
341                                         cid->sawflag = 1;
342                                         cid->skipflag = 0;
343                                         cid->crc = 0;
344                                 }
345                                 break;
346                         case 1: /* SOH */
347                                 if (b == 0x01) {
348                                         cid->sawflag = 2;
349                                 }
350                                 break ;
351                         case 2: /* HEADER */
352                                 if (b == 0x07) {
353                                         cid->sawflag = 3;
354                                 }
355                                 break;
356                         case 3: /* STX */
357                                 if (b == 0x02) {
358                                         cid->sawflag = 4;
359                                 }
360                                 break;
361                         case 4: /* SERVICE TYPE */
362                                 if (b == 0x40) {
363                                         cid->sawflag = 5;
364                                 }
365                                 break;
366                         case 5: /* Frame Length */
367                                 cid->sawflag = 6;
368                                 break;  
369                         case 6: /* NUMBER TYPE */
370                                 cid->sawflag = 7;
371                                 cid->pos = 0;
372                                 cid->rawdata[cid->pos++] = b;
373                                 break;
374                         case 7: /* NUMBER LENGTH */
375                                 cid->sawflag = 8;
376                                 cid->len = b;
377                                 if ((cid->len+2) >= sizeof(cid->rawdata)) {
378                                         ast_log(LOG_WARNING, "too long caller id string\n") ;
379                                         return -1;
380                                 }
381                                 cid->rawdata[cid->pos++] = b;
382                                 break;
383                         case 8: /* Retrieve message */
384                                 cid->rawdata[cid->pos++] = b;
385                                 cid->len--;
386                                 if (cid->len<=0) {
387                                         cid->rawdata[cid->pos] = '\0';
388                                         cid->sawflag = 9;
389                                 }
390                                 break;
391                         case 9: /* ETX */
392                                 cid->sawflag = 10;
393                                 break;
394                         case 10: /* CRC Checksum 1 */
395                                 cid->sawflag = 11;
396                                 break;
397                         case 11: /* CRC Checksum 2 */
398                                 cid->sawflag = 12;
399                                 if (cid->crc != 0) {
400                                         ast_log(LOG_WARNING, "crc checksum error\n") ;
401                                         return -1;
402                                 } 
403                                 /* extract caller id data */
404                                 for (x=0; x<cid->pos;) {
405                                         switch (cid->rawdata[x++]) {
406                                         case 0x02: /* caller id  number */
407                                                 cid->number[0] = '\0';
408                                                 cid->name[0] = '\0';
409                                                 cid->flags = 0;
410                                                 res = cid->rawdata[x++];
411                                                 ast_copy_string(cid->number, &cid->rawdata[x], res+1);
412                                                 x += res;
413                                                 break;
414                                         case 0x21: /* additional information */
415                                                 /* length */
416                                                 x++; 
417                                                 /* number type */
418                                                 switch (cid->rawdata[x]) { 
419                                                 case 0x00: /* unknown */
420                                                 case 0x01: /* international number */
421                                                 case 0x02: /* domestic number */
422                                                 case 0x03: /* network */
423                                                 case 0x04: /* local call */
424                                                 case 0x06: /* short dial number */
425                                                 case 0x07: /* reserved */
426                                                 default:   /* reserved */
427                                                         if (option_debug > 1)
428                                                                 ast_log(LOG_DEBUG, "cid info:#1=%X\n", cid->rawdata[x]);
429                                                         break ;
430                                                 }
431                                                 x++; 
432                                                 /* numbering plan octed 4 */
433                                                 x++; 
434                                                 /* numbering plan octed 5 */
435                                                 switch (cid->rawdata[x]) { 
436                                                 case 0x00: /* unknown */
437                                                 case 0x01: /* recommendation E.164 ISDN */
438                                                 case 0x03: /* recommendation X.121 */
439                                                 case 0x04: /* telex dial plan */
440                                                 case 0x08: /* domestic dial plan */
441                                                 case 0x09: /* private dial plan */
442                                                 case 0x05: /* reserved */
443                                                 default:   /* reserved */
444                                                         if (option_debug > 1)
445                                                                 ast_log(LOG_DEBUG, "cid info:#2=%X\n", cid->rawdata[x]);
446                                                         break ;
447                                                 }
448                                                 x++; 
449                                                 break ;
450                                         case 0x04: /* no callerid reason */
451                                                 /* length */
452                                                 x++; 
453                                                 /* no callerid reason code */
454                                                 switch (cid->rawdata[x]) {
455                                                 case 'P': /* caller id denied by user */
456                                                 case 'O': /* service not available */
457                                                 case 'C': /* pay phone */
458                                                 case 'S': /* service congested */
459                                                                 cid->flags |= CID_UNKNOWN_NUMBER;
460                                                         if (option_debug > 1)
461                                                                 ast_log(LOG_DEBUG, "no cid reason:%c\n",cid->rawdata[x]);
462                                                         break ;
463                                                 }
464                                                 x++; 
465                                                 break ;
466                                         case 0x09: /* dialed number */
467                                                 /* length */
468                                                 res = cid->rawdata[x++];
469                                                 /* dialed number */
470                                                 x += res;
471                                                 break ;
472                                         case 0x22: /* dialed number additional information */
473                                                 /* length */
474                                                 x++;
475                                                 /* number type */
476                                                 switch (cid->rawdata[x]) {
477                                                 case 0x00: /* unknown */
478                                                 case 0x01: /* international number */
479                                                 case 0x02: /* domestic number */
480                                                 case 0x03: /* network */
481                                                 case 0x04: /* local call */
482                                                 case 0x06: /* short dial number */
483                                                 case 0x07: /* reserved */
484                                                 default:   /* reserved */
485                                                         if (option_debug > 1)
486                                                                 ast_log(LOG_NOTICE, "did info:#1=%X\n", cid->rawdata[x]);
487                                                         break ;
488                                                 }
489                                                 x++;
490                                                 /* numbering plan octed 4 */
491                                                 x++;
492                                                 /* numbering plan octed 5 */
493                                                 switch (cid->rawdata[x]) {
494                                                 case 0x00: /* unknown */
495                                                 case 0x01: /* recommendation E.164 ISDN */
496                                                 case 0x03: /* recommendation X.121 */
497                                                 case 0x04: /* telex dial plan */
498                                                 case 0x08: /* domestic dial plan */
499                                                 case 0x09: /* private dial plan */
500                                                 case 0x05: /* reserved */
501                                                 default:   /* reserved */
502                                                         if (option_debug > 1)
503                                                                 ast_log(LOG_DEBUG, "did info:#2=%X\n", cid->rawdata[x]);
504                                                         break ;
505                                                 }
506                                                 x++;
507                                                 break ;
508                                         }
509                                 }
510                                 return 1;
511                                 break;
512                         default:
513                                 ast_log(LOG_ERROR, "invalid value in sawflag %d\n", cid->sawflag);
514                         }
515                 }
516         }
517         if (mylen) {
518                 memcpy(cid->oldstuff, buf, mylen * 2);
519                 cid->oldlen = mylen * 2;
520         } else
521                 cid->oldlen = 0;
522         
523         return 0;
524 }
525
526
527 int callerid_feed(struct callerid_state *cid, unsigned char *ubuf, int len, int codec)
528 {
529         int mylen = len;
530         int olen;
531         int b = 'X';
532         int res;
533         int x;
534         short *buf;
535
536         buf = alloca(2 * len + cid->oldlen);
537
538         memcpy(buf, cid->oldstuff, cid->oldlen);
539         mylen += cid->oldlen/2;
540
541         for (x = 0; x < len; x++) 
542                 buf[x+cid->oldlen/2] = AST_XLAW(ubuf[x]);
543         while (mylen >= 160) {
544                 olen = mylen;
545                 res = fsk_serie(&cid->fskd, buf, &mylen, &b);
546                 if (mylen < 0) {
547                         ast_log(LOG_ERROR, "fsk_serie made mylen < 0 (%d)\n", mylen);
548                         return -1;
549                 }
550                 buf += (olen - mylen);
551                 if (res < 0) {
552                         ast_log(LOG_NOTICE, "fsk_serie failed\n");
553                         return -1;
554                 }
555                 if (res == 1) {
556                         /* Ignore invalid bytes */
557                         if (b > 0xff)
558                                 continue;
559                         switch(cid->sawflag) {
560                         case 0: /* Look for flag */
561                                 if (b == 'U')
562                                         cid->sawflag = 2;
563                                 break;
564                         case 2: /* Get lead-in */
565                                 if ((b == 0x04) || (b == 0x80)) {
566                                         cid->type = b;
567                                         cid->sawflag = 3;
568                                         cid->cksum = b;
569                                 }
570                                 break;
571                         case 3: /* Get length */
572                                 /* Not a lead in.  We're ready  */
573                                 cid->sawflag = 4;
574                                 cid->len = b;
575                                 cid->pos = 0;
576                                 cid->cksum += b;
577                                 break;
578                         case 4: /* Retrieve message */
579                                 if (cid->pos >= 128) {
580                                         ast_log(LOG_WARNING, "Caller ID too long???\n");
581                                         return -1;
582                                 }
583                                 cid->rawdata[cid->pos++] = b;
584                                 cid->len--;
585                                 cid->cksum += b;
586                                 if (!cid->len) {
587                                         cid->rawdata[cid->pos] = '\0';
588                                         cid->sawflag = 5;
589                                 }
590                                 break;
591                         case 5: /* Check checksum */
592                                 if (b != (256 - (cid->cksum & 0xff))) {
593                                         ast_log(LOG_NOTICE, "Caller*ID failed checksum\n");
594                                         /* Try again */
595                                         cid->sawflag = 0;
596                                         break;
597                                 }
598                 
599                                 cid->number[0] = '\0';
600                                 cid->name[0] = '\0';
601                                 /* If we get this far we're fine.  */
602                                 if (cid->type == 0x80) {
603                                         /* MDMF */
604                                         /* Go through each element and process */
605                                         for (x = 0; x < cid->pos;) {
606                                                 switch(cid->rawdata[x++]) {
607                                                 case 1:
608                                                         /* Date */
609                                                         break;
610                                                 case 2: /* Number */
611                                                 case 3: /* Number (for Zebble) */
612                                                 case 4: /* Number */
613                                                         res = cid->rawdata[x];
614                                                         if (res > 32) {
615                                                                 ast_log(LOG_NOTICE, "Truncating long caller ID number from %d bytes to 32\n", cid->rawdata[x]);
616                                                                 res = 32; 
617                                                         }
618                                                         if (ast_strlen_zero(cid->number)) {
619                                                                 memcpy(cid->number, cid->rawdata + x + 1, res);
620                                                                 /* Null terminate */
621                                                                 cid->number[res] = '\0';
622                                                         }
623                                                         break;
624                                                 case 6: /* Stentor Call Qualifier (ie. Long Distance call) */
625                                                         break;
626                                                 case 7: /* Name */
627                                                 case 8: /* Name */
628                                                         res = cid->rawdata[x];
629                                                         if (res > 32) {
630                                                                 ast_log(LOG_NOTICE, "Truncating long caller ID name from %d bytes to 32\n", cid->rawdata[x]);
631                                                                 res = 32; 
632                                                         }
633                                                         memcpy(cid->name, cid->rawdata + x + 1, res);
634                                                         cid->name[res] = '\0';
635                                                         break;
636                                                 case 17: /* UK: Call type, 1=Voice Call, 2=Ringback when free, 129=Message waiting  */
637                                                 case 19: /* UK: Network message system status (Number of messages waiting) */
638                                                 case 22: /* Something French */
639                                                         break;
640                                                 default:
641                                                         ast_log(LOG_NOTICE, "Unknown IE %d\n", cid->rawdata[x - 1]);
642                                                 }
643                                                 x += cid->rawdata[x];
644                                                 x++;
645                                         }
646                                 } else {
647                                         /* SDMF */
648                                         ast_copy_string(cid->number, cid->rawdata + 8, sizeof(cid->number));
649                                 }
650                                 /* Update flags */
651                                 cid->flags = 0;
652                                 if (!strcmp(cid->number, "P")) {
653                                         strcpy(cid->number, "");
654                                         cid->flags |= CID_PRIVATE_NUMBER;
655                                 } else if (!strcmp(cid->number, "O") || ast_strlen_zero(cid->number)) {
656                                         strcpy(cid->number, "");
657                                         cid->flags |= CID_UNKNOWN_NUMBER;
658                                 }
659                                 if (!strcmp(cid->name, "P")) {
660                                         strcpy(cid->name, "");
661                                         cid->flags |= CID_PRIVATE_NAME;
662                                 } else if (!strcmp(cid->name, "O") || ast_strlen_zero(cid->name)) {
663                                         strcpy(cid->name, "");
664                                         cid->flags |= CID_UNKNOWN_NAME;
665                                 }
666                                 return 1;
667                                 break;
668                         default:
669                                 ast_log(LOG_ERROR, "Dunno what to do with a digit in sawflag %d\n", cid->sawflag);
670                         }
671                 }
672         }
673         if (mylen) {
674                 memcpy(cid->oldstuff, buf, mylen * 2);
675                 cid->oldlen = mylen * 2;
676         } else
677                 cid->oldlen = 0;
678
679         return 0;
680 }
681
682 void callerid_free(struct callerid_state *cid)
683 {
684         free(cid);
685 }
686
687 static int callerid_genmsg(char *msg, int size, const char *number, const char *name, int flags)
688 {
689         time_t t;
690         struct tm tm;
691         char *ptr;
692         int res;
693         int i,x;
694         /* Get the time */
695         time(&t);
696         localtime_r(&t,&tm);
697         
698         ptr = msg;
699         
700         /* Format time and message header */
701         res = snprintf(ptr, size, "\001\010%02d%02d%02d%02d", tm.tm_mon + 1,
702                                 tm.tm_mday, tm.tm_hour, tm.tm_min);
703         size -= res;
704         ptr += res;
705         if (ast_strlen_zero(number) || (flags & CID_UNKNOWN_NUMBER)) {
706                 /* Indicate number not known */
707                 res = snprintf(ptr, size, "\004\001O");
708                 size -= res;
709                 ptr += res;
710         } else if (flags & CID_PRIVATE_NUMBER) {
711                 /* Indicate number is private */
712                 res = snprintf(ptr, size, "\004\001P");
713                 size -= res;
714                 ptr += res;
715         } else {
716                 /* Send up to 16 digits of number MAX */
717                 i = strlen(number);
718                 if (i > 16) i = 16;
719                 res = snprintf(ptr, size, "\002%c", i);
720                 size -= res;
721                 ptr += res;
722                 for (x = 0; x < i; x++)
723                         ptr[x] = number[x];
724                 ptr[i] = '\0';
725                 ptr += i;
726                 size -= i;
727         }
728
729         if (ast_strlen_zero(name) || (flags & CID_UNKNOWN_NAME)) {
730                 /* Indicate name not known */
731                 res = snprintf(ptr, size, "\010\001O");
732                 size -= res;
733                 ptr += res;
734         } else if (flags & CID_PRIVATE_NAME) {
735                 /* Indicate name is private */
736                 res = snprintf(ptr, size, "\010\001P");
737                 size -= res;
738                 ptr += res;
739         } else {
740                 /* Send up to 16 digits of name MAX */
741                 i = strlen(name);
742                 if (i > 16) i = 16;
743                 res = snprintf(ptr, size, "\007%c", i);
744                 size -= res;
745                 ptr += res;
746                 for (x=0;x<i;x++)
747                         ptr[x] = name[x];
748                 ptr[i] = '\0';
749                 ptr += i;
750                 size -= i;
751         }
752         return (ptr - msg);
753         
754 }
755
756 int vmwi_generate(unsigned char *buf, int active, int mdmf, int codec)
757 {
758         unsigned char msg[256];
759         int len=0;
760         int sum;
761         int x;
762         int bytes = 0;
763         float cr = 1.0;
764         float ci = 0.0;
765         float scont = 0.0;
766         if (mdmf) {
767                 /* MDMF Message waiting */
768                 msg[len++] = 0x82;
769                 /* Length is 3 */
770                 msg[len++] = 3;
771                 /* IE is "Message Waiting Parameter" */
772                 msg[len++] = 0xb;
773                 /* Length of IE is one */
774                 msg[len++] = 1;
775                 /* Active or not */
776                 if (active)
777                         msg[len++] = 0xff;
778                 else
779                         msg[len++] = 0x00;
780         } else {
781                 /* SDMF Message waiting */
782                 msg[len++] = 0x6;
783                 /* Length is 3 */
784                 msg[len++] = 3;
785                 if (active) {
786                         msg[len++] = 0x42;
787                         msg[len++] = 0x42;
788                         msg[len++] = 0x42;
789                 } else {
790                         msg[len++] = 0x6f;
791                         msg[len++] = 0x6f;
792                         msg[len++] = 0x6f;
793                 }
794         }
795         sum = 0;
796         for (x=0; x<len; x++)
797                 sum += msg[x];
798         sum = (256 - (sum & 255));
799         msg[len++] = sum;
800         /* Wait a half a second */
801         for (x=0; x<4000; x++)
802                 PUT_BYTE(0x7f);
803         /* Transmit 30 0x55's (looks like a square wave) for channel seizure */
804         for (x=0; x<30; x++)
805                 PUT_CLID(0x55);
806         /* Send 170ms of callerid marks */
807         for (x=0; x<170; x++)
808                 PUT_CLID_MARKMS;
809         for (x=0; x<len; x++) {
810                 PUT_CLID(msg[x]);
811         }
812         /* Send 50 more ms of marks */
813         for (x=0; x<50; x++)
814                 PUT_CLID_MARKMS;
815         return bytes;
816 }
817
818 int callerid_generate(unsigned char *buf, const char *number, const char *name, int flags, int callwaiting, int codec)
819 {
820         int bytes=0;
821         int x, sum;
822         int len;
823
824         /* Initial carriers (real/imaginary) */
825         float cr = 1.0;
826         float ci = 0.0;
827         float scont = 0.0;
828         char msg[256];
829         len = callerid_genmsg(msg, sizeof(msg), number, name, flags);
830         if (!callwaiting) {
831                 /* Wait a half a second */
832                 for (x=0; x<4000; x++)
833                         PUT_BYTE(0x7f);
834                 /* Transmit 30 0x55's (looks like a square wave) for channel seizure */
835                 for (x=0; x<30; x++)
836                         PUT_CLID(0x55);
837         }
838         /* Send 150ms of callerid marks */
839         for (x=0; x<150; x++)
840                 PUT_CLID_MARKMS;
841         /* Send 0x80 indicating MDMF format */
842         PUT_CLID(0x80);
843         /* Put length of whole message */
844         PUT_CLID(len);
845         sum = 0x80 + strlen(msg);
846         /* Put each character of message and update checksum */
847         for (x=0; x<len; x++) {
848                 PUT_CLID(msg[x]);
849                 sum += msg[x];
850         }
851         /* Send 2's compliment of sum */
852         PUT_CLID(256 - (sum & 255));
853
854         /* Send 50 more ms of marks */
855         for (x=0; x<50; x++)
856                 PUT_CLID_MARKMS;
857         
858         return bytes;
859 }
860
861 /*! \brief Clean up phone string
862  * remove '(', ' ', ')', non-trailing '.', and '-' not in square brackets.
863  * Basically, remove anything that could be invalid in a pattern.
864  */
865 void ast_shrink_phone_number(char *n)
866 {
867         int x, y=0;
868         int bracketed = 0;
869
870         for (x=0; n[x]; x++) {
871                 switch(n[x]) {
872                 case '[':
873                         bracketed++;
874                         n[y++] = n[x];
875                         break;
876                 case ']':
877                         bracketed--;
878                         n[y++] = n[x];
879                         break;
880                 case '-':
881                         if (bracketed)
882                                 n[y++] = n[x];
883                         break;
884                 case '.':
885                         if (!n[x+1])
886                                 n[y++] = n[x];
887                         break;
888                 default:
889                         if (!strchr("()", n[x]))
890                                 n[y++] = n[x];
891                 }
892         }
893         n[y] = '\0';
894 }
895
896 /*! \brief Checks if phone number consists of valid characters 
897         \param exten    String that needs to be checked
898         \param valid    Valid characters in string
899         \return 1 if valid string, 0 if string contains invalid characters
900 */
901 static int ast_is_valid_string(const char *exten, const char *valid)
902 {
903         int x;
904
905         if (ast_strlen_zero(exten))
906                 return 0;
907         for (x=0; exten[x]; x++)
908                 if (!strchr(valid, exten[x]))
909                         return 0;
910         return 1;
911 }
912
913 /*! \brief checks if string consists only of digits and * \# and + 
914         \return 1 if string is valid AST phone number
915         \return 0 if not
916 */
917 int ast_isphonenumber(const char *n)
918 {
919         return ast_is_valid_string(n, "0123456789*#+");
920 }
921
922 /*! \brief checks if string consists only of digits and ( ) - * \# and + 
923         Pre-qualifies the string for ast_shrink_phone_number()
924         \return 1 if string is valid AST shrinkable phone number
925         \return 0 if not
926 */
927 int ast_is_shrinkable_phonenumber(const char *exten)
928 {
929         return ast_is_valid_string(exten, "0123456789*#+()-.");
930 }
931
932 /*! \brief parse string for caller id information 
933         \return always returns 0, as the code always returns something.
934   XXX note that 'name' is not parsed consistently e.g. we have
935
936         input                   location        name
937         " foo bar " <123>       123             ' foo bar ' (with spaces around)
938         " foo bar "             NULL            'foo bar' (without spaces around)
939         " foo bar  <123>"       123             '" foo bar'
940   The parsing of leading and trailing space/quotes should be more consistent.
941 */
942 int ast_callerid_parse(char *instr, char **name, char **location)
943 {
944         char *ns, *ne, *ls, *le;
945
946         /* Try "name" <location> format or name <location> format */
947         if ((ls = strchr(instr, '<')) && (le = strchr(ls, '>'))) {
948                 *ls = *le = '\0';       /* location found, trim off the brackets */
949                 *location = ls + 1;     /* and this is the result */
950                 if ((ns = strchr(instr, '"')) && (ne = strchr(ns + 1, '"'))) {
951                         *ns = *ne = '\0';       /* trim off the quotes */
952                         *name = ns + 1;         /* and this is the name */
953                 } else { /* no quotes, trim off leading and trailing spaces */
954                         *name = ast_skip_blanks(instr);
955                         ast_trim_blanks(*name);
956                 }
957         } else {        /* no valid brackets */
958                 char tmp[256];
959
960                 ast_copy_string(tmp, instr, sizeof(tmp));
961                 ast_shrink_phone_number(tmp);
962                 if (ast_isphonenumber(tmp)) {   /* Assume it's just a location */
963                         *name = NULL;
964                         strcpy(instr, tmp); /* safe, because tmp will always be the same size or smaller than instr */
965                         *location = instr;
966                 } else { /* Assume it's just a name. */
967                         *location = NULL;
968                         if ((ns = strchr(instr, '"')) && (ne = strchr(ns + 1, '"'))) {
969                                 *ns = *ne = '\0';       /* trim off the quotes */
970                                 *name = ns + 1;         /* and this is the name */
971                         } else { /* no quotes, trim off leading and trailing spaces */
972                                 *name = ast_skip_blanks(instr);
973                                 ast_trim_blanks(*name);
974                         }
975                 }
976         }
977         return 0;
978 }
979
980 static int __ast_callerid_generate(unsigned char *buf, const char *name, const char *number, int callwaiting, int codec)
981 {
982         if (ast_strlen_zero(name))
983                 name = NULL;
984         if (ast_strlen_zero(number))
985                 number = NULL;
986         return callerid_generate(buf, number, name, 0, callwaiting, codec);
987 }
988
989 int ast_callerid_generate(unsigned char *buf, const char *name, const char *number, int codec)
990 {
991         return __ast_callerid_generate(buf, name, number, 0, codec);
992 }
993
994 int ast_callerid_callwaiting_generate(unsigned char *buf, const char *name, const char *number, int codec)
995 {
996         return __ast_callerid_generate(buf, name, number, 1, codec);
997 }
998
999 char *ast_callerid_merge(char *buf, int bufsiz, const char *name, const char *num, const char *unknown)
1000 {
1001         if (!unknown)
1002                 unknown = "<unknown>";
1003         if (name && num)
1004                 snprintf(buf, bufsiz, "\"%s\" <%s>", name, num);
1005         else if (name) 
1006                 ast_copy_string(buf, name, bufsiz);
1007         else if (num)
1008                 ast_copy_string(buf, num, bufsiz);
1009         else
1010                 ast_copy_string(buf, unknown, bufsiz);
1011         return buf;
1012 }
1013
1014 int ast_callerid_split(const char *buf, char *name, int namelen, char *num, int numlen)
1015 {
1016         char *tmp;
1017         char *l = NULL, *n = NULL;
1018
1019         tmp = ast_strdupa(buf);
1020         ast_callerid_parse(tmp, &n, &l);
1021         if (n)
1022                 ast_copy_string(name, n, namelen);
1023         else
1024                 name[0] = '\0';
1025         if (l) {
1026                 ast_shrink_phone_number(l);
1027                 ast_copy_string(num, l, numlen);
1028         } else
1029                 num[0] = '\0';
1030         return 0;
1031 }
1032
1033 /*! \brief Translation table for Caller ID Presentation settings */
1034 static struct {
1035         int val;
1036         const char *name;
1037         const char *description;
1038 } pres_types[] = {
1039         {  AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED, "allowed_not_screened", "Presentation Allowed, Not Screened"},
1040         {  AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, "allowed_passed_screen", "Presentation Allowed, Passed Screen"},
1041         {  AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN, "allowed_failed_screen", "Presentation Allowed, Failed Screen"},
1042         {  AST_PRES_ALLOWED_NETWORK_NUMBER, "allowed", "Presentation Allowed, Network Number"},
1043         {  AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED, "prohib_not_screened", "Presentation Prohibited, Not Screened"},
1044         {  AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN, "prohib_passed_screen", "Presentation Prohibited, Passed Screen"},
1045         {  AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN, "prohib_failed_screen", "Presentation Prohibited, Failed Screen"},
1046         {  AST_PRES_PROHIB_NETWORK_NUMBER, "prohib", "Presentation Prohibited, Network Number"},
1047         {  AST_PRES_NUMBER_NOT_AVAILABLE, "unavailable", "Number Unavailable"},
1048 };
1049
1050 /*! \brief Convert caller ID text code to value 
1051         used in config file parsing
1052         \param data text string
1053         \return value AST_PRES_ from callerid.h 
1054 */
1055 int ast_parse_caller_presentation(const char *data)
1056 {
1057         int i;
1058
1059         for (i = 0; i < ((sizeof(pres_types) / sizeof(pres_types[0]))); i++) {
1060                 if (!strcasecmp(pres_types[i].name, data))
1061                         return pres_types[i].val;
1062         }
1063
1064         return -1;
1065 }
1066
1067 /*! \brief Convert caller ID pres value to explanatory string 
1068         \param data value (see callerid.h AST_PRES_ ) 
1069         \return string for human presentation
1070 */
1071 const char *ast_describe_caller_presentation(int data)
1072 {
1073         int i;
1074
1075         for (i = 0; i < ((sizeof(pres_types) / sizeof(pres_types[0]))); i++) {
1076                 if (pres_types[i].val == data)
1077                         return pres_types[i].description;
1078         }
1079
1080         return "unknown";
1081 }
1082
1083 /*! \brief Convert caller ID pres value to text code
1084         \param data text string
1085         \return string for config file
1086 */
1087 const char *ast_named_caller_presentation(int data)
1088 {
1089         int i;
1090
1091         for (i = 0; i < ((sizeof(pres_types) / sizeof(pres_types[0]))); i++) {
1092                 if (pres_types[i].val == data)
1093                         return pres_types[i].name;
1094         }
1095
1096         return "unknown";
1097 }