remove some useless checks after calls to ast_strdupa
[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 <time.h>
27 #include <string.h>
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <unistd.h>
31 #include <math.h>
32 #include <ctype.h>
33
34 #include "asterisk.h"
35
36 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
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/utils.h"
46
47 struct callerid_state {
48         fsk_data fskd;
49         char rawdata[256];
50         short oldstuff[160];
51         int oldlen;
52         int pos;
53         int type;
54         int cksum;
55         char name[64];
56         char number[64];
57         int flags;
58         int sawflag;
59         int len;
60
61         int skipflag; 
62         unsigned short crc;
63 };
64
65
66 float cid_dr[4], cid_di[4];
67 float clidsb = 8000.0 / 1200.0;
68 float sasdr, sasdi;
69 float casdr1, casdi1, casdr2, casdi2;
70
71 #define CALLERID_SPACE  2200.0          /*!< 2200 hz for "0" */
72 #define CALLERID_MARK   1200.0          /*!< 1200 hz for "1" */
73 #define SAS_FREQ                 440.0
74 #define CAS_FREQ1               2130.0
75 #define CAS_FREQ2               2750.0
76
77 #define AST_CALLERID_UNKNOWN    "<unknown>"
78
79 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)
80 {
81         int x;
82         float t;
83         for (x=0;x<len;x++) {
84                 t = *cr1 * ddr1 - *ci1 * ddi1;
85                 *ci1 = *cr1 * ddi1 + *ci1 * ddr1;
86                 *cr1 = t;
87                 t = 2.0 - (*cr1 * *cr1 + *ci1 * *ci1);
88                 *cr1 *= t;
89                 *ci1 *= t;      
90
91                 t = *cr2 * ddr2 - *ci2 * ddi2;
92                 *ci2 = *cr2 * ddi2 + *ci2 * ddr2;
93                 *cr2 = t;
94                 t = 2.0 - (*cr2 * *cr2 + *ci2 * *ci2);
95                 *cr2 *= t;
96                 *ci2 *= t;      
97                 buf[x] = AST_LIN2X((*cr1 + *cr2) * 2048.0);
98         }
99 }
100
101 static inline void gen_tone(unsigned char *buf, int len, int codec, float ddr1, float ddi1, float *cr1, float *ci1)
102 {
103         int x;
104         float t;
105         for (x=0;x<len;x++) {
106                 t = *cr1 * ddr1 - *ci1 * ddi1;
107                 *ci1 = *cr1 * ddi1 + *ci1 * ddr1;
108                 *cr1 = t;
109                 t = 2.0 - (*cr1 * *cr1 + *ci1 * *ci1);
110                 *cr1 *= t;
111                 *ci1 *= t;      
112                 buf[x] = AST_LIN2X(*cr1 * 8192.0);
113         }
114 }
115
116 /*! \brief Initialize stuff for inverse FFT */
117 void callerid_init(void)
118 {
119         cid_dr[0] = cos(CALLERID_SPACE * 2.0 * M_PI / 8000.0);
120         cid_di[0] = sin(CALLERID_SPACE * 2.0 * M_PI / 8000.0);
121         cid_dr[1] = cos(CALLERID_MARK * 2.0 * M_PI / 8000.0);
122         cid_di[1] = sin(CALLERID_MARK * 2.0 * M_PI / 8000.0);
123         sasdr = cos(SAS_FREQ * 2.0 * M_PI / 8000.0);
124         sasdi = sin(SAS_FREQ * 2.0 * M_PI / 8000.0);
125         casdr1 = cos(CAS_FREQ1 * 2.0 * M_PI / 8000.0);
126         casdi1 = sin(CAS_FREQ1 * 2.0 * M_PI / 8000.0);
127         casdr2 = cos(CAS_FREQ2 * 2.0 * M_PI / 8000.0);
128         casdi2 = sin(CAS_FREQ2 * 2.0 * M_PI / 8000.0);
129 }
130
131 struct callerid_state *callerid_new(int cid_signalling)
132 {
133         struct callerid_state *cid;
134         cid = malloc(sizeof(struct callerid_state));
135         if (cid) {
136                 memset(cid, 0, sizeof(struct callerid_state));
137                 cid->fskd.spb = 7;              /* 1200 baud */
138                 cid->fskd.hdlc = 0;             /* Async */
139                 cid->fskd.nbit = 8;             /* 8 bits */
140                 cid->fskd.nstop = 1;    /* 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;                     /* Digital PLL reset */
152                 cid->fskd.x0 = 0.0;
153                 cid->fskd.state = 0;
154                 memset(cid->name, 0, sizeof(cid->name));
155                 memset(cid->number, 0, sizeof(cid->number));
156                 cid->flags = CID_UNKNOWN_NAME | CID_UNKNOWN_NUMBER;
157                 cid->pos = 0;
158         } else
159                 ast_log(LOG_WARNING, "Out of memory\n");
160         return cid;
161 }
162
163 void callerid_get(struct callerid_state *cid, char **name, char **number, int *flags)
164 {
165         *flags = cid->flags;
166         if (cid->flags & (CID_UNKNOWN_NAME | CID_PRIVATE_NUMBER))
167                 *name = NULL;
168         else
169                 *name = cid->name;
170         if (cid->flags & (CID_UNKNOWN_NUMBER | CID_PRIVATE_NUMBER))
171                 *number = NULL;
172         else
173                 *number = cid->number;
174 }
175
176 void callerid_get_dtmf(char *cidstring, char *number, int *flags)
177 {
178         int i;
179         int code;
180
181         /* "Clear" the number-buffer. */
182         number[0] = 0;
183
184         if (strlen(cidstring) < 2) {
185                 ast_log(LOG_DEBUG, "No cid detected\n");
186                 *flags = CID_UNKNOWN_NUMBER;
187                 return;
188         }
189         
190         /* Detect protocol and special types */
191         if (cidstring[0] == 'B') {
192                 /* Handle special codes */
193                 code = atoi(&cidstring[1]);
194                 if (code == 0)
195                         *flags = CID_UNKNOWN_NUMBER;
196                 else if (code == 10) 
197                         *flags = CID_PRIVATE_NUMBER;
198                 else
199                         ast_log(LOG_DEBUG, "Unknown DTMF code %d\n", code);
200         } else if (cidstring[0] == 'D' && cidstring[2] == '#') {
201                 /* .DK special code */
202                 if (cidstring[1] == '1')
203                         *flags = CID_PRIVATE_NUMBER;
204                 if (cidstring[1] == '2' || cidstring[1] == '3')
205                         *flags = CID_UNKNOWN_NUMBER;
206         } else if (cidstring[0] == 'D' || cidstring[0] == 'A') {
207                 /* "Standard" callerid */
208                 for (i = 1; i < strlen(cidstring); i++ ) {
209                         if (cidstring[i] == 'C' || cidstring[i] == '#')
210                                 break;
211                         if (isdigit(cidstring[i]))
212                                 number[i-1] = cidstring[i];
213                         else
214                                 ast_log(LOG_DEBUG, "Unknown CID digit '%c'\n",
215                                         cidstring[i]);
216                 }
217                 number[i-1] = 0;
218         } else if (isdigit(cidstring[0])) {
219                 /* It begins with a digit, so we parse it as a number and hope
220                  * for the best */
221                 ast_log(LOG_WARNING, "Couldn't detect start-character. CID "
222                         "parsing might be unreliable\n");
223                 for (i = 0; i < strlen(cidstring); i++) {
224                         if (isdigit(cidstring[i]))
225                                 number[i] = cidstring[i];
226                         else
227                                 break;
228                 }
229                 number[i] = 0;
230         } else {
231                 ast_log(LOG_DEBUG, "Unknown CID protocol, start digit '%c'\n", 
232                         cidstring[0]);
233                 *flags = CID_UNKNOWN_NUMBER;
234         }
235 }
236
237 int ast_gen_cas(unsigned char *outbuf, int sendsas, int len, int codec)
238 {
239         int pos = 0;
240         int saslen=2400;
241         float cr1 = 1.0;
242         float ci1 = 0.0;
243         float cr2 = 1.0;
244         float ci2 = 0.0;
245         if (sendsas) {
246                 if (len < saslen)
247                         return -1;
248                 gen_tone(outbuf, saslen, codec, sasdr, sasdi, &cr1, &ci1);
249                 len -= saslen;
250                 pos += saslen;
251                 cr2 = cr1;
252                 ci2 = ci1;
253         }
254         gen_tones(outbuf + pos, len, codec, casdr1, casdi1, casdr2, casdi2, &cr1, &ci1, &cr2, &ci2);
255         return 0;
256 }
257
258 static unsigned short calc_crc(unsigned short crc, unsigned char data)
259 {
260         unsigned int i, j, org, dst;
261         org = data;
262         dst = 0;
263         for (i=0; i<CHAR_BIT; i++) {
264         org <<= 1;
265         dst >>= 1;
266         if (org & 0x100) {
267                 dst |= 0x80;
268         }
269         }
270         data = (unsigned char)dst;
271         crc ^= (unsigned int)data << (16 - CHAR_BIT);
272         for ( j=0; j<CHAR_BIT; j++ ) {
273                 if ( crc & 0x8000U ) crc = (crc << 1) ^ 0x1021U ;
274                 else crc <<= 1 ;
275         }
276         return crc;
277 }
278
279 int callerid_feed_jp(struct callerid_state *cid, unsigned char *ubuf, int len, int codec)
280 {
281         int mylen = len;
282         int olen;
283         int b = 'X';
284         int b2 ;
285         int res;
286         int x;
287         short *buf = malloc(2 * len + cid->oldlen);
288         short *obuf = buf;
289
290         if (!buf) {
291                 ast_log(LOG_WARNING, "Out of memory\n");
292                 return -1;
293         }
294
295         memset(buf, 0, 2 * len + cid->oldlen);
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                                                                                 ast_log(LOG_NOTICE, "cid info:#1=%X\n", cid->rawdata[x]);
436                                                                                 break ;
437                                                                 }
438                                 x++; 
439                                                                 /* numbering plan octed 4 */
440                                 x++; 
441                                                                 /* numbering plan octed 5 */
442                                         switch (cid->rawdata[x]) { 
443                                                                         case 0x00: /* unknown */
444                                                                         case 0x01: /* recommendation E.164 ISDN */
445                                                                         case 0x03: /* recommendation X.121 */
446                                                                         case 0x04: /* telex dial plan */
447                                                                         case 0x08: /* domestic dial plan */
448                                                                         case 0x09: /* private dial plan */
449                                                                         case 0x05: /* reserved */
450                                                                         default:   /* reserved */
451                                                                                 ast_log(LOG_NOTICE, "cid info:#2=%X\n", cid->rawdata[x]);
452                                                                                 break ;
453                                                                 }
454                                 x++; 
455                                                                 break ;
456                                                         case 0x04: /* no callerid reason */
457                                                                 /* length */
458                                 x++; 
459                                                                 /* no callerid reason code */
460                                 switch (cid->rawdata[x]) {
461                                                                         case 'P': /* caller id denied by user */
462                                                                         case 'O': /* service not available */
463                                                                         case 'C': /* pay phone */
464                                                                         case 'S': /* service congested */
465                                                         cid->flags |= CID_UNKNOWN_NUMBER;
466                                                                                 ast_log(LOG_NOTICE, "no cid reason:%c\n",cid->rawdata[x]);
467                                                                                 break ;
468                                                                 }
469                                 x++; 
470                                                                 break ;
471                                                         case 0x09: /* dialed number */
472                                                                 /* length */
473                                                                 res = cid->rawdata[x++];
474                                                                 /* dialed number */
475                                                                 x += res;
476                                                                 break ;
477                                                         case 0x22: /* dialed number additional information */
478                                 /* length */
479                                 x++;
480                                 /* number type */
481                                 switch (cid->rawdata[x]) {
482                                     case 0x00: /* unknown */
483                                     case 0x01: /* international number */
484                                     case 0x02: /* domestic number */
485                                     case 0x03: /* network */
486                                     case 0x04: /* local call */
487                                     case 0x06: /* short dial number */
488                                     case 0x07: /* reserved */
489                                     default:   /* reserved */
490                                         ast_log(LOG_NOTICE, "did info:#1=%X\n", cid->rawdata[x]);
491                                         break ;
492                                 }
493                                 x++;
494                                 /* numbering plan octed 4 */
495                                 x++;
496                                 /* numbering plan octed 5 */
497                                 switch (cid->rawdata[x]) {
498                                     case 0x00: /* unknown */
499                                     case 0x01: /* recommendation E.164 ISDN */
500                                     case 0x03: /* recommendation X.121 */
501                                     case 0x04: /* telex dial plan */
502                                     case 0x08: /* domestic dial plan */
503                                     case 0x09: /* private dial plan */
504                                     case 0x05: /* reserved */
505                                     default:   /* reserved */
506                                         ast_log(LOG_NOTICE, "did info:#2=%X\n", cid->rawdata[x]);
507                                         break ;
508                                 }
509                                 x++;
510                                 break ;
511                                                 }
512                                         }
513                                         return 1;
514                                         break;
515                                 default:
516                                         ast_log(LOG_ERROR, "invalid value in sawflag %d\n", cid->sawflag);
517                         }
518                 }
519         }
520         if (mylen) {
521                 memcpy(cid->oldstuff, buf, mylen * 2);
522                 cid->oldlen = mylen * 2;
523         } else
524                 cid->oldlen = 0;
525         free(obuf);
526         return 0;
527 }
528
529
530 int callerid_feed(struct callerid_state *cid, unsigned char *ubuf, int len, int codec)
531 {
532         int mylen = len;
533         int olen;
534         int b = 'X';
535         int res;
536         int x;
537         short *buf = malloc(2 * len + cid->oldlen);
538         short *obuf = buf;
539         if (!buf) {
540                 ast_log(LOG_WARNING, "Out of memory\n");
541                 return -1;
542         }
543         memset(buf, 0, 2 * len + cid->oldlen);
544         memcpy(buf, cid->oldstuff, cid->oldlen);
545         mylen += cid->oldlen/2;
546         for (x=0;x<len;x++) 
547                 buf[x+cid->oldlen/2] = AST_XLAW(ubuf[x]);
548         while(mylen >= 160) {
549                 olen = mylen;
550                 res = fsk_serie(&cid->fskd, buf, &mylen, &b);
551                 if (mylen < 0) {
552                         ast_log(LOG_ERROR, "fsk_serie made mylen < 0 (%d)\n", mylen);
553                         return -1;
554                 }
555                 buf += (olen - mylen);
556                 if (res < 0) {
557                         ast_log(LOG_NOTICE, "fsk_serie failed\n");
558                         return -1;
559                 }
560                 if (res == 1) {
561                         /* Ignore invalid bytes */
562                         if (b > 0xff)
563                                 continue;
564                         switch(cid->sawflag) {
565                         case 0: /* Look for flag */
566                                 if (b == 'U')
567                                         cid->sawflag = 2;
568                                 break;
569                         case 2: /* Get lead-in */
570                                 if ((b == 0x04) || (b == 0x80)) {
571                                         cid->type = b;
572                                         cid->sawflag = 3;
573                                         cid->cksum = b;
574                                 }
575                                 break;
576                         case 3: /* Get length */
577                                 /* Not a lead in.  We're ready  */
578                                 cid->sawflag = 4;
579                                 cid->len = b;
580                                 cid->pos = 0;
581                                 cid->cksum += b;
582                                 break;
583                         case 4: /* Retrieve message */
584                                 if (cid->pos >= 128) {
585                                         ast_log(LOG_WARNING, "Caller ID too long???\n");
586                                         return -1;
587                                 }
588                                 cid->rawdata[cid->pos++] = b;
589                                 cid->len--;
590                                 cid->cksum += b;
591                                 if (!cid->len) {
592                                         cid->rawdata[cid->pos] = '\0';
593                                         cid->sawflag = 5;
594                                 }
595                                 break;
596                         case 5: /* Check checksum */
597                                 if (b != (256 - (cid->cksum & 0xff))) {
598                                         ast_log(LOG_NOTICE, "Caller*ID failed checksum\n");
599                                         /* Try again */
600                                         cid->sawflag = 0;
601                                         break;
602                                 }
603                 
604                                 cid->number[0] = '\0';
605                                 cid->name[0] = '\0';
606                                 /* If we get this far we're fine.  */
607                                 if (cid->type == 0x80) {
608                                         /* MDMF */
609                                         /* Go through each element and process */
610                                         for (x=0;x< cid->pos;) {
611                                                 switch(cid->rawdata[x++]) {
612                                                 case 1:
613                                                         /* Date */
614                                                         break;
615                                                 case 2: /* Number */
616                                                 case 3: /* Number (for Zebble) */
617                                                 case 4: /* Number */
618                                                         res = cid->rawdata[x];
619                                                         if (res > 32) {
620                                                                 ast_log(LOG_NOTICE, "Truncating long caller ID number from %d bytes to 32\n", cid->rawdata[x]);
621                                                                 res = 32; 
622                                                         }
623                                                         if (ast_strlen_zero(cid->number)) {
624                                                                 memcpy(cid->number, cid->rawdata + x + 1, res);
625                                                                 /* Null terminate */
626                                                                 cid->number[res] = '\0';
627                                                         }
628                                                         break;
629                                                 case 6: /* Stentor Call Qualifier (ie. Long Distance call) */
630                                                         break;
631                                                 case 7: /* Name */
632                                                 case 8: /* Name */
633                                                         res = cid->rawdata[x];
634                                                         if (res > 32) {
635                                                                 ast_log(LOG_NOTICE, "Truncating long caller ID name from %d bytes to 32\n", cid->rawdata[x]);
636                                                                 res = 32; 
637                                                         }
638                                                         memcpy(cid->name, cid->rawdata + x + 1, res);
639                                                         cid->name[res] = '\0';
640                                                         break;
641                                                 case 17: /* UK: Call type, 1=Voice Call, 2=Ringback when free, 129=Message waiting  */
642                                                 case 19: /* UK: Network message system status (Number of messages waiting) */
643                                                 case 22: /* Something French */
644                                                         break;
645                                                 default:
646                                                         ast_log(LOG_NOTICE, "Unknown IE %d\n", cid->rawdata[x-1]);
647                                                 }
648                                                 x += cid->rawdata[x];
649                                                 x++;
650                                         }
651                                 } else {
652                                         /* SDMF */
653                                         ast_copy_string(cid->number, cid->rawdata + 8, sizeof(cid->number));
654                                 }
655                                 /* Update flags */
656                                 cid->flags = 0;
657                                 if (!strcmp(cid->number, "P")) {
658                                         strcpy(cid->number, "");
659                                         cid->flags |= CID_PRIVATE_NUMBER;
660                                 } else if (!strcmp(cid->number, "O") || ast_strlen_zero(cid->number)) {
661                                         strcpy(cid->number, "");
662                                         cid->flags |= CID_UNKNOWN_NUMBER;
663                                 }
664                                 if (!strcmp(cid->name, "P")) {
665                                         strcpy(cid->name, "");
666                                         cid->flags |= CID_PRIVATE_NAME;
667                                 } else if (!strcmp(cid->name, "O") || ast_strlen_zero(cid->name)) {
668                                         strcpy(cid->name, "");
669                                         cid->flags |= CID_UNKNOWN_NAME;
670                                 }
671                                 return 1;
672                                 break;
673                         default:
674                                 ast_log(LOG_ERROR, "Dunno what to do with a digit in sawflag %d\n", cid->sawflag);
675                         }
676                 }
677         }
678         if (mylen) {
679                 memcpy(cid->oldstuff, buf, mylen * 2);
680                 cid->oldlen = mylen * 2;
681         } else
682                 cid->oldlen = 0;
683         free(obuf);
684         return 0;
685 }
686
687 void callerid_free(struct callerid_state *cid)
688 {
689         free(cid);
690 }
691
692 static int callerid_genmsg(char *msg, int size, char *number, char *name, int flags)
693 {
694         time_t t;
695         struct tm tm;
696         char *ptr;
697         int res;
698         int i,x;
699         /* Get the time */
700         time(&t);
701         localtime_r(&t,&tm);
702         
703         ptr = msg;
704         
705         /* Format time and message header */
706         res = snprintf(ptr, size, "\001\010%02d%02d%02d%02d", tm.tm_mon + 1,
707                                 tm.tm_mday, tm.tm_hour, tm.tm_min);
708         size -= res;
709         ptr += res;
710         if (ast_strlen_zero(number) || (flags & CID_UNKNOWN_NUMBER)) {
711                 /* Indicate number not known */
712                 res = snprintf(ptr, size, "\004\001O");
713                 size -= res;
714                 ptr += res;
715         } else if (flags & CID_PRIVATE_NUMBER) {
716                 /* Indicate number is private */
717                 res = snprintf(ptr, size, "\004\001P");
718                 size -= res;
719                 ptr += res;
720         } else {
721                 /* Send up to 16 digits of number MAX */
722                 i = strlen(number);
723                 if (i > 16) i = 16;
724                 res = snprintf(ptr, size, "\002%c", i);
725                 size -= res;
726                 ptr += res;
727                 for (x=0;x<i;x++)
728                         ptr[x] = number[x];
729                 ptr[i] = '\0';
730                 ptr += i;
731                 size -= i;
732         }
733
734         if (ast_strlen_zero(name) || (flags & CID_UNKNOWN_NAME)) {
735                 /* Indicate name not known */
736                 res = snprintf(ptr, size, "\010\001O");
737                 size -= res;
738                 ptr += res;
739         } else if (flags & CID_PRIVATE_NAME) {
740                 /* Indicate name is private */
741                 res = snprintf(ptr, size, "\010\001P");
742                 size -= res;
743                 ptr += res;
744         } else {
745                 /* Send up to 16 digits of name MAX */
746                 i = strlen(name);
747                 if (i > 16) i = 16;
748                 res = snprintf(ptr, size, "\007%c", i);
749                 size -= res;
750                 ptr += res;
751                 for (x=0;x<i;x++)
752                         ptr[x] = name[x];
753                 ptr[i] = '\0';
754                 ptr += i;
755                 size -= i;
756         }
757         return (ptr - msg);
758         
759 }
760
761 int vmwi_generate(unsigned char *buf, int active, int mdmf, int codec)
762 {
763         unsigned char msg[256];
764         int len=0;
765         int sum;
766         int x;
767         int bytes = 0;
768         float cr = 1.0;
769         float ci = 0.0;
770         float scont = 0.0;
771         if (mdmf) {
772                 /* MDMF Message waiting */
773                 msg[len++] = 0x82;
774                 /* Length is 3 */
775                 msg[len++] = 3;
776                 /* IE is "Message Waiting Parameter" */
777                 msg[len++] = 0xb;
778                 /* Length of IE is one */
779                 msg[len++] = 1;
780                 /* Active or not */
781                 if (active)
782                         msg[len++] = 0xff;
783                 else
784                         msg[len++] = 0x00;
785         } else {
786                 /* SDMF Message waiting */
787                 msg[len++] = 0x6;
788                 /* Length is 3 */
789                 msg[len++] = 3;
790                 if (active) {
791                         msg[len++] = 0x42;
792                         msg[len++] = 0x42;
793                         msg[len++] = 0x42;
794                 } else {
795                         msg[len++] = 0x6f;
796                         msg[len++] = 0x6f;
797                         msg[len++] = 0x6f;
798                 }
799         }
800         sum = 0;
801         for (x=0;x<len;x++)
802                 sum += msg[x];
803         sum = (256 - (sum & 255));
804         msg[len++] = sum;
805         /* Wait a half a second */
806         for (x=0;x<4000;x++)
807                 PUT_BYTE(0x7f);
808         /* Transmit 30 0x55's (looks like a square wave) for channel seizure */
809         for (x=0;x<30;x++)
810                 PUT_CLID(0x55);
811         /* Send 170ms of callerid marks */
812         for (x=0;x<170;x++)
813                 PUT_CLID_MARKMS;
814         for (x=0;x<len;x++) {
815                 PUT_CLID(msg[x]);
816         }
817         /* Send 50 more ms of marks */
818         for (x=0;x<50;x++)
819                 PUT_CLID_MARKMS;
820         return bytes;
821 }
822
823 int callerid_generate(unsigned char *buf, char *number, char *name, int flags, int callwaiting, int codec)
824 {
825         int bytes=0;
826         int x, sum;
827         int len;
828         /* Initial carriers (real/imaginary) */
829         float cr = 1.0;
830         float ci = 0.0;
831         float scont = 0.0;
832         char msg[256];
833         len = callerid_genmsg(msg, sizeof(msg), number, name, flags);
834         if (!callwaiting) {
835                 /* Wait a half a second */
836                 for (x=0;x<4000;x++)
837                         PUT_BYTE(0x7f);
838                 /* Transmit 30 0x55's (looks like a square wave) for channel seizure */
839                 for (x=0;x<30;x++)
840                         PUT_CLID(0x55);
841         }
842         /* Send 150ms of callerid marks */
843         for (x=0;x<150;x++)
844                 PUT_CLID_MARKMS;
845         /* Send 0x80 indicating MDMF format */
846         PUT_CLID(0x80);
847         /* Put length of whole message */
848         PUT_CLID(len);
849         sum = 0x80 + strlen(msg);
850         /* Put each character of message and update checksum */
851         for (x=0;x<len; x++) {
852                 PUT_CLID(msg[x]);
853                 sum += msg[x];
854         }
855         /* Send 2's compliment of sum */
856         PUT_CLID(256 - (sum & 255));
857
858         /* Send 50 more ms of marks */
859         for (x=0;x<50;x++)
860                 PUT_CLID_MARKMS;
861         
862         return bytes;
863 }
864
865 void ast_shrink_phone_number(char *n)
866 {
867         int x,y=0;
868         int bracketed=0;
869         for (x=0;n[x];x++) {
870                 switch(n[x]) {
871                 case '[':
872                         bracketed++;
873                         n[y++] = n[x];
874                         break;
875                 case ']':
876                         bracketed--;
877                         n[y++] = n[x];
878                         break;
879                 case '-':
880                         if (bracketed)
881                                 n[y++] = n[x];
882                         break;
883                 case '.':
884                         if (!n[x+1])
885                                 n[y++] = n[x];
886                         break;
887                 default:
888                         if (!strchr("( )", n[x]))
889                                 n[y++] = n[x];
890                 }
891         }
892         n[y] = '\0';
893 }
894
895 /*! \brief checks if string consists only of digits and * \# and + 
896         \return 1 if string is valid AST phone number
897         \return 0 if not
898 */
899 int ast_isphonenumber(char *n)
900 {
901         int x;
902         if (ast_strlen_zero(n))
903                 return 0;
904         for (x=0;n[x];x++)
905                 if (!strchr("0123456789*#+", n[x]))
906                         return 0;
907         return 1;
908 }
909
910 /*! \brief parse string for caller id information 
911         \return returns -1 on failure, otherwise 0
912 */
913 int ast_callerid_parse(char *instr, char **name, char **location)
914 {
915         char *ns, *ne;
916         char *ls, *le;
917         char tmp[256];
918         /* Try for "name" <location> format or 
919            name <location> format */
920         if ((ls = strchr(instr, '<')) && (le = strchr(ls, '>'))) {
921                 /* Found the location */
922                 *le = '\0';
923                 *ls = '\0';
924                 *location = ls + 1;
925                 if ((ns = strchr(instr, '\"')) && (ne = strchr(ns + 1, '\"'))) {
926                         /* Get name out of quotes */
927                         *ns = '\0';
928                         *ne = '\0';
929                         *name = ns + 1;
930                         return 0;
931                 } else {
932                         /* Just trim off any trailing spaces */
933                         *name = instr;
934                         while(!ast_strlen_zero(instr) && (instr[strlen(instr) - 1] < 33))
935                                 instr[strlen(instr) - 1] = '\0';
936                         /* And leading spaces */
937                         *name = ast_skip_blanks(*name);
938                         return 0;
939                 }
940         } else {
941                 ast_copy_string(tmp, instr, sizeof(tmp));
942                 ast_shrink_phone_number(tmp);
943                 if (ast_isphonenumber(tmp)) {
944                         /* Assume it's just a location */
945                         *name = NULL;
946                         *location = instr;
947                 } else {
948                         /* Assume it's just a name.  Make sure it's not quoted though */
949                         *name = instr;
950                         while(*(*name) && ((*(*name) < 33) || (*(*name) == '\"'))) (*name)++;
951                         ne = *name + strlen(*name) - 1;
952                         while((ne > *name) && ((*ne < 33) || (*ne == '\"'))) { *ne = '\0'; ne--; }
953                         *location = NULL;
954                 }
955                 return 0;
956         }
957         return -1;
958 }
959
960 static int __ast_callerid_generate(unsigned char *buf, char *name, char *number, int callwaiting, int codec)
961 {
962         if (ast_strlen_zero(name))
963                 name = NULL;
964         if (ast_strlen_zero(number))
965                 number = NULL;
966         return callerid_generate(buf, number, name, 0, callwaiting, codec);
967 }
968
969 int ast_callerid_generate(unsigned char *buf, char *name, char *number, int codec)
970 {
971         return __ast_callerid_generate(buf, name, number, 0, codec);
972 }
973
974 int ast_callerid_callwaiting_generate(unsigned char *buf, char *name, char *number, int codec)
975 {
976         return __ast_callerid_generate(buf, name, number, 1, codec);
977 }
978
979 char *ast_callerid_merge(char *buf, int bufsiz, const char *name, const char *num, const char *unknown)
980 {
981         if (!unknown)
982                 unknown = "<unknown>";
983         if (name && num)
984                 snprintf(buf, bufsiz, "\"%s\" <%s>", name, num);
985         else if (name) 
986                 ast_copy_string(buf, name, bufsiz);
987         else if (num)
988                 ast_copy_string(buf, num, bufsiz);
989         else
990                 ast_copy_string(buf, unknown, bufsiz);
991         return buf;
992 }
993
994 int ast_callerid_split(const char *buf, char *name, int namelen, char *num, int numlen)
995 {
996         char *tmp;
997         char *l = NULL, *n = NULL;
998         
999         tmp = ast_strdupa(buf);
1000         ast_callerid_parse(tmp, &n, &l);
1001         if (n)
1002                 ast_copy_string(name, n, namelen);
1003         else
1004                 name[0] = '\0';
1005         if (l) {
1006                 ast_shrink_phone_number(l);
1007                 ast_copy_string(num, l, numlen);
1008         } else
1009                 num[0] = '\0';
1010         return 0;
1011 }
1012
1013 static struct {
1014         int val;
1015         char *name;
1016         char *description;
1017 } pres_types[] = {
1018         {  AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED, "allowed_not_screened", "Presentation Allowed, Not Screened"},
1019         {  AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, "allowed_passed_screen", "Presentation Allowed, Passed Screen"},
1020         {  AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN, "allowed_failed_screen", "Presentation Allowed, Failed Screen"},
1021         {  AST_PRES_ALLOWED_NETWORK_NUMBER, "allowed", "Presentation Allowed, Network Number"},
1022         {  AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED, "prohib_not_screened", "Presentation Prohibited, Not Screened"},
1023         {  AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN, "prohib_passed_screen", "Presentation Prohibited, Passed Screen"},
1024         {  AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN, "prohib_failed_screen", "Presentation Prohibited, Failed Screen"},
1025         {  AST_PRES_PROHIB_NETWORK_NUMBER, "prohib", "Presentation Prohibited, Network Number"},
1026         {  AST_PRES_NUMBER_NOT_AVAILABLE, "unavailable", "Number Unavailable"},
1027 };
1028
1029 /*! \brief Convert caller ID text code to value 
1030         used in config file parsing
1031         \param data text string
1032         \return value AST_PRES_ from callerid.h 
1033 */
1034 int ast_parse_caller_presentation(const char *data)
1035 {
1036         int i;
1037
1038         for (i = 0; i < ((sizeof(pres_types) / sizeof(pres_types[0]))); i++) {
1039                 if (!strcasecmp(pres_types[i].name, data))
1040                         return pres_types[i].val;
1041         }
1042
1043         return -1;
1044 }
1045
1046 /*! \brief Convert caller ID pres value to explanatory string 
1047         \param data value (see callerid.h AST_PRES_ ) 
1048         \return string for human presentation
1049 */
1050 const char *ast_describe_caller_presentation(int data)
1051 {
1052         int i;
1053
1054         for (i = 0; i < ((sizeof(pres_types) / sizeof(pres_types[0]))); i++) {
1055                 if (pres_types[i].val == data)
1056                         return pres_types[i].description;
1057         }
1058
1059         return "unknown";
1060 }