875071cb810a555699085e5eae8ed266dd15582f
[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  */
24
25 #include <time.h>
26 #include <string.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <unistd.h>
30 #include <math.h>
31 #include <ctype.h>
32
33 #include "asterisk.h"
34
35 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
36
37 #include "asterisk/ulaw.h"
38 #include "asterisk/alaw.h"
39 #include "asterisk/frame.h"
40 #include "asterisk/channel.h"
41 #include "asterisk/callerid.h"
42 #include "asterisk/logger.h"
43 #include "asterisk/fskmodem.h"
44 #include "asterisk/utils.h"
45
46 struct callerid_state {
47         fsk_data fskd;
48         char rawdata[256];
49         short oldstuff[160];
50         int oldlen;
51         int pos;
52         int type;
53         int cksum;
54         char name[64];
55         char number[64];
56         int flags;
57         int sawflag;
58         int len;
59 };
60
61
62 float cid_dr[4], cid_di[4];
63 float clidsb = 8000.0 / 1200.0;
64 float sasdr, sasdi;
65 float casdr1, casdi1, casdr2, casdi2;
66
67 #define CALLERID_SPACE  2200.0          /* 2200 hz for "0" */
68 #define CALLERID_MARK   1200.0          /* 1200 hz for "1" */
69 #define SAS_FREQ                 440.0
70 #define CAS_FREQ1               2130.0
71 #define CAS_FREQ2               2750.0
72
73 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)
74 {
75         int x;
76         float t;
77         for (x=0;x<len;x++) {
78                 t = *cr1 * ddr1 - *ci1 * ddi1;
79                 *ci1 = *cr1 * ddi1 + *ci1 * ddr1;
80                 *cr1 = t;
81                 t = 2.0 - (*cr1 * *cr1 + *ci1 * *ci1);
82                 *cr1 *= t;
83                 *ci1 *= t;      
84
85                 t = *cr2 * ddr2 - *ci2 * ddi2;
86                 *ci2 = *cr2 * ddi2 + *ci2 * ddr2;
87                 *cr2 = t;
88                 t = 2.0 - (*cr2 * *cr2 + *ci2 * *ci2);
89                 *cr2 *= t;
90                 *ci2 *= t;      
91                 buf[x] = AST_LIN2X((*cr1 + *cr2) * 2048.0);
92         }
93 }
94
95 static inline void gen_tone(unsigned char *buf, int len, int codec, float ddr1, float ddi1, float *cr1, float *ci1)
96 {
97         int x;
98         float t;
99         for (x=0;x<len;x++) {
100                 t = *cr1 * ddr1 - *ci1 * ddi1;
101                 *ci1 = *cr1 * ddi1 + *ci1 * ddr1;
102                 *cr1 = t;
103                 t = 2.0 - (*cr1 * *cr1 + *ci1 * *ci1);
104                 *cr1 *= t;
105                 *ci1 *= t;      
106                 buf[x] = AST_LIN2X(*cr1 * 8192.0);
107         }
108 }
109
110 void callerid_init(void)
111 {
112         /* Initialize stuff for inverse FFT */
113         cid_dr[0] = cos(CALLERID_SPACE * 2.0 * M_PI / 8000.0);
114         cid_di[0] = sin(CALLERID_SPACE * 2.0 * M_PI / 8000.0);
115         cid_dr[1] = cos(CALLERID_MARK * 2.0 * M_PI / 8000.0);
116         cid_di[1] = sin(CALLERID_MARK * 2.0 * M_PI / 8000.0);
117         sasdr = cos(SAS_FREQ * 2.0 * M_PI / 8000.0);
118         sasdi = sin(SAS_FREQ * 2.0 * M_PI / 8000.0);
119         casdr1 = cos(CAS_FREQ1 * 2.0 * M_PI / 8000.0);
120         casdi1 = sin(CAS_FREQ1 * 2.0 * M_PI / 8000.0);
121         casdr2 = cos(CAS_FREQ2 * 2.0 * M_PI / 8000.0);
122         casdi2 = sin(CAS_FREQ2 * 2.0 * M_PI / 8000.0);
123 }
124
125 struct callerid_state *callerid_new(int cid_signalling)
126 {
127         struct callerid_state *cid;
128         cid = malloc(sizeof(struct callerid_state));
129         if (cid) {
130                 memset(cid, 0, sizeof(struct callerid_state));
131                 cid->fskd.spb = 7;              /* 1200 baud */
132                 cid->fskd.hdlc = 0;             /* Async */
133                 cid->fskd.nbit = 8;             /* 8 bits */
134                 cid->fskd.nstop = 1;    /* 1 stop bit */
135                 cid->fskd.paridad = 0;  /* No parity */
136                 cid->fskd.bw=1;                 /* Filter 800 Hz */
137                 if (cid_signalling == 2) { /* v23 signalling */
138                         cid->fskd.f_mark_idx =  4;      /* 1300 Hz */
139                         cid->fskd.f_space_idx = 5;      /* 2100 Hz */
140                 } else { /* Bell 202 signalling as default */ 
141                         cid->fskd.f_mark_idx =  2;      /* 1200 Hz */
142                         cid->fskd.f_space_idx = 3;      /* 2200 Hz */
143                 }
144                 cid->fskd.pcola = 0;            /* No clue */
145                 cid->fskd.cont = 0;                     /* Digital PLL reset */
146                 cid->fskd.x0 = 0.0;
147                 cid->fskd.state = 0;
148                 memset(cid->name, 0, sizeof(cid->name));
149                 memset(cid->number, 0, sizeof(cid->number));
150                 cid->flags = CID_UNKNOWN_NAME | CID_UNKNOWN_NUMBER;
151                 cid->pos = 0;
152         } else
153                 ast_log(LOG_WARNING, "Out of memory\n");
154         return cid;
155 }
156
157 void callerid_get(struct callerid_state *cid, char **name, char **number, int *flags)
158 {
159         *flags = cid->flags;
160         if (cid->flags & (CID_UNKNOWN_NAME | CID_PRIVATE_NUMBER))
161                 *name = NULL;
162         else
163                 *name = cid->name;
164         if (cid->flags & (CID_UNKNOWN_NUMBER | CID_PRIVATE_NUMBER))
165                 *number = NULL;
166         else
167                 *number = cid->number;
168 }
169
170 void callerid_get_dtmf(char *cidstring, char *number, int *flags)
171 {
172         int i;
173         int code;
174
175         /* "Clear" the number-buffer. */
176         number[0] = 0;
177
178         if (strlen(cidstring) < 2) {
179                 ast_log(LOG_DEBUG, "No cid detected\n");
180                 *flags = CID_UNKNOWN_NUMBER;
181                 return;
182         }
183         
184         /* Detect protocol and special types */
185         if (cidstring[0] == 'B') {
186                 /* Handle special codes */
187                 code = atoi(&cidstring[1]);
188                 if (code == 0)
189                         *flags = CID_UNKNOWN_NUMBER;
190                 else if (code == 10) 
191                         *flags = CID_PRIVATE_NUMBER;
192                 else
193                         ast_log(LOG_DEBUG, "Unknown DTMF code %d\n", code);
194         } else if (cidstring[0] == 'D' && cidstring[2] == '#') {
195                 /* .DK special code */
196                 if (cidstring[1] == '1')
197                         *flags = CID_PRIVATE_NUMBER;
198                 if (cidstring[1] == '2' || cidstring[1] == '3')
199                         *flags = CID_UNKNOWN_NUMBER;
200         } else if (cidstring[0] == 'D' || cidstring[0] == 'A') {
201                 /* "Standard" callerid */
202                 for (i = 1; i < strlen(cidstring); i++ ) {
203                         if (cidstring[i] == 'C' || cidstring[i] == '#')
204                                 break;
205                         if (isdigit(cidstring[i]))
206                                 number[i-1] = cidstring[i];
207                         else
208                                 ast_log(LOG_DEBUG, "Unknown CID digit '%c'\n",
209                                         cidstring[i]);
210                 }
211                 number[i-1] = 0;
212         } else if (isdigit(cidstring[0])) {
213                 /* It begins with a digit, so we parse it as a number and hope
214                  * for the best */
215                 ast_log(LOG_WARNING, "Couldn't detect start-character. CID "
216                         "parsing might be unreliable\n");
217                 for (i = 0; i < strlen(cidstring); i++) {
218                         if (isdigit(cidstring[i]))
219                                 number[i] = cidstring[i];
220                         else
221                                 break;
222                 }
223                 number[i] = 0;
224         } else {
225                 ast_log(LOG_DEBUG, "Unknown CID protocol, start digit '%c'\n", 
226                         cidstring[0]);
227                 *flags = CID_UNKNOWN_NUMBER;
228         }
229 }
230
231 int ast_gen_cas(unsigned char *outbuf, int sendsas, int len, int codec)
232 {
233         int pos = 0;
234         int saslen=2400;
235         float cr1 = 1.0;
236         float ci1 = 0.0;
237         float cr2 = 1.0;
238         float ci2 = 0.0;
239         if (sendsas) {
240                 if (len < saslen)
241                         return -1;
242                 gen_tone(outbuf, saslen, codec, sasdr, sasdi, &cr1, &ci1);
243                 len -= saslen;
244                 pos += saslen;
245                 cr2 = cr1;
246                 ci2 = ci1;
247         }
248         gen_tones(outbuf + pos, len, codec, casdr1, casdi1, casdr2, casdi2, &cr1, &ci1, &cr2, &ci2);
249         return 0;
250 }
251
252 int callerid_feed(struct callerid_state *cid, unsigned char *ubuf, int len, int codec)
253 {
254         int mylen = len;
255         int olen;
256         int b = 'X';
257         int res;
258         int x;
259         short *buf = malloc(2 * len + cid->oldlen);
260         short *obuf = buf;
261         if (!buf) {
262                 ast_log(LOG_WARNING, "Out of memory\n");
263                 return -1;
264         }
265         memset(buf, 0, 2 * len + cid->oldlen);
266         memcpy(buf, cid->oldstuff, cid->oldlen);
267         mylen += cid->oldlen/2;
268         for (x=0;x<len;x++) 
269                 buf[x+cid->oldlen/2] = AST_XLAW(ubuf[x]);
270         while(mylen >= 160) {
271                 olen = mylen;
272                 res = fsk_serie(&cid->fskd, buf, &mylen, &b);
273                 if (mylen < 0) {
274                         ast_log(LOG_ERROR, "fsk_serie made mylen < 0 (%d)\n", mylen);
275                         return -1;
276                 }
277                 buf += (olen - mylen);
278                 if (res < 0) {
279                         ast_log(LOG_NOTICE, "fsk_serie failed\n");
280                         return -1;
281                 }
282                 if (res == 1) {
283                         /* Ignore invalid bytes */
284                         if (b > 0xff)
285                                 continue;
286                         switch(cid->sawflag) {
287                         case 0: /* Look for flag */
288                                 if (b == 'U')
289                                         cid->sawflag = 2;
290                                 break;
291                         case 2: /* Get lead-in */
292                                 if ((b == 0x04) || (b == 0x80)) {
293                                         cid->type = b;
294                                         cid->sawflag = 3;
295                                         cid->cksum = b;
296                                 }
297                                 break;
298                         case 3: /* Get length */
299                                 /* Not a lead in.  We're ready  */
300                                 cid->sawflag = 4;
301                                 cid->len = b;
302                                 cid->pos = 0;
303                                 cid->cksum += b;
304                                 break;
305                         case 4: /* Retrieve message */
306                                 if (cid->pos >= 128) {
307                                         ast_log(LOG_WARNING, "Caller ID too long???\n");
308                                         return -1;
309                                 }
310                                 cid->rawdata[cid->pos++] = b;
311                                 cid->len--;
312                                 cid->cksum += b;
313                                 if (!cid->len) {
314                                         cid->rawdata[cid->pos] = '\0';
315                                         cid->sawflag = 5;
316                                 }
317                                 break;
318                         case 5: /* Check checksum */
319                                 if (b != (256 - (cid->cksum & 0xff))) {
320                                         ast_log(LOG_NOTICE, "Caller*ID failed checksum\n");
321                                         /* Try again */
322                                         cid->sawflag = 0;
323                                         break;
324                                 }
325                 
326                                 cid->number[0] = '\0';
327                                 cid->name[0] = '\0';
328                                 /* If we get this far we're fine.  */
329                                 if (cid->type == 0x80) {
330                                         /* MDMF */
331                                         /* Go through each element and process */
332                                         for (x=0;x< cid->pos;) {
333                                                 switch(cid->rawdata[x++]) {
334                                                 case 1:
335                                                         /* Date */
336                                                         break;
337                                                 case 2: /* Number */
338                                                 case 3: /* Number (for Zebble) */
339                                                 case 4: /* Number */
340                                                         res = cid->rawdata[x];
341                                                         if (res > 32) {
342                                                                 ast_log(LOG_NOTICE, "Truncating long caller ID number from %d bytes to 32\n", cid->rawdata[x]);
343                                                                 res = 32; 
344                                                         }
345                                                         if (ast_strlen_zero(cid->number)) {
346                                                                 memcpy(cid->number, cid->rawdata + x + 1, res);
347                                                                 /* Null terminate */
348                                                                 cid->number[res] = '\0';
349                                                         }
350                                                         break;
351                                                 case 6: /* Stentor Call Qualifier (ie. Long Distance call) */
352                                                         break;
353                                                 case 7: /* Name */
354                                                 case 8: /* Name */
355                                                         res = cid->rawdata[x];
356                                                         if (res > 32) {
357                                                                 ast_log(LOG_NOTICE, "Truncating long caller ID name from %d bytes to 32\n", cid->rawdata[x]);
358                                                                 res = 32; 
359                                                         }
360                                                         memcpy(cid->name, cid->rawdata + x + 1, res);
361                                                         cid->name[res] = '\0';
362                                                         break;
363                                                 case 17: /* UK: Call type, 1=Voice Call, 2=Ringback when free, 129=Message waiting  */
364                                                 case 19: /* UK: Network message system status (Number of messages waiting) */
365                                                 case 22: /* Something French */
366                                                         break;
367                                                 default:
368                                                         ast_log(LOG_NOTICE, "Unknown IE %d\n", cid->rawdata[x-1]);
369                                                 }
370                                                 x += cid->rawdata[x];
371                                                 x++;
372                                         }
373                                 } else {
374                                         /* SDMF */
375                                         ast_copy_string(cid->number, cid->rawdata + 8, sizeof(cid->number));
376                                 }
377                                 /* Update flags */
378                                 cid->flags = 0;
379                                 if (!strcmp(cid->number, "P")) {
380                                         strcpy(cid->number, "");
381                                         cid->flags |= CID_PRIVATE_NUMBER;
382                                 } else if (!strcmp(cid->number, "O") || ast_strlen_zero(cid->number)) {
383                                         strcpy(cid->number, "");
384                                         cid->flags |= CID_UNKNOWN_NUMBER;
385                                 }
386                                 if (!strcmp(cid->name, "P")) {
387                                         strcpy(cid->name, "");
388                                         cid->flags |= CID_PRIVATE_NAME;
389                                 } else if (!strcmp(cid->name, "O") || ast_strlen_zero(cid->name)) {
390                                         strcpy(cid->name, "");
391                                         cid->flags |= CID_UNKNOWN_NAME;
392                                 }
393                                 return 1;
394                                 break;
395                         default:
396                                 ast_log(LOG_ERROR, "Dunno what to do with a digit in sawflag %d\n", cid->sawflag);
397                         }
398                 }
399         }
400         if (mylen) {
401                 memcpy(cid->oldstuff, buf, mylen * 2);
402                 cid->oldlen = mylen * 2;
403         } else
404                 cid->oldlen = 0;
405         free(obuf);
406         return 0;
407 }
408
409 void callerid_free(struct callerid_state *cid)
410 {
411         free(cid);
412 }
413
414 static int callerid_genmsg(char *msg, int size, char *number, char *name, int flags)
415 {
416         time_t t;
417         struct tm tm;
418         char *ptr;
419         int res;
420         int i,x;
421         /* Get the time */
422         time(&t);
423         localtime_r(&t,&tm);
424         
425         ptr = msg;
426         
427         /* Format time and message header */
428         res = snprintf(ptr, size, "\001\010%02d%02d%02d%02d", tm.tm_mon + 1,
429                                 tm.tm_mday, tm.tm_hour, tm.tm_min);
430         size -= res;
431         ptr += res;
432         if (ast_strlen_zero(number) || (flags & CID_UNKNOWN_NUMBER)) {
433                 /* Indicate number not known */
434                 res = snprintf(ptr, size, "\004\001O");
435                 size -= res;
436                 ptr += res;
437         } else if (flags & CID_PRIVATE_NUMBER) {
438                 /* Indicate number is private */
439                 res = snprintf(ptr, size, "\004\001P");
440                 size -= res;
441                 ptr += res;
442         } else {
443                 /* Send up to 16 digits of number MAX */
444                 i = strlen(number);
445                 if (i > 16) i = 16;
446                 res = snprintf(ptr, size, "\002%c", i);
447                 size -= res;
448                 ptr += res;
449                 for (x=0;x<i;x++)
450                         ptr[x] = number[x];
451                 ptr[i] = '\0';
452                 ptr += i;
453                 size -= i;
454         }
455
456         if (ast_strlen_zero(name) || (flags & CID_UNKNOWN_NAME)) {
457                 /* Indicate name not known */
458                 res = snprintf(ptr, size, "\010\001O");
459                 size -= res;
460                 ptr += res;
461         } else if (flags & CID_PRIVATE_NAME) {
462                 /* Indicate name is private */
463                 res = snprintf(ptr, size, "\010\001P");
464                 size -= res;
465                 ptr += res;
466         } else {
467                 /* Send up to 16 digits of name MAX */
468                 i = strlen(name);
469                 if (i > 16) i = 16;
470                 res = snprintf(ptr, size, "\007%c", i);
471                 size -= res;
472                 ptr += res;
473                 for (x=0;x<i;x++)
474                         ptr[x] = name[x];
475                 ptr[i] = '\0';
476                 ptr += i;
477                 size -= i;
478         }
479         return (ptr - msg);
480         
481 }
482
483 int vmwi_generate(unsigned char *buf, int active, int mdmf, int codec)
484 {
485         unsigned char msg[256];
486         int len=0;
487         int sum;
488         int x;
489         int bytes = 0;
490         float cr = 1.0;
491         float ci = 0.0;
492         float scont = 0.0;
493         if (mdmf) {
494                 /* MDMF Message waiting */
495                 msg[len++] = 0x82;
496                 /* Length is 3 */
497                 msg[len++] = 3;
498                 /* IE is "Message Waiting Parameter" */
499                 msg[len++] = 0xb;
500                 /* Length of IE is one */
501                 msg[len++] = 1;
502                 /* Active or not */
503                 if (active)
504                         msg[len++] = 0xff;
505                 else
506                         msg[len++] = 0x00;
507         } else {
508                 /* SDMF Message waiting */
509                 msg[len++] = 0x6;
510                 /* Length is 3 */
511                 msg[len++] = 3;
512                 if (active) {
513                         msg[len++] = 0x42;
514                         msg[len++] = 0x42;
515                         msg[len++] = 0x42;
516                 } else {
517                         msg[len++] = 0x6f;
518                         msg[len++] = 0x6f;
519                         msg[len++] = 0x6f;
520                 }
521         }
522         sum = 0;
523         for (x=0;x<len;x++)
524                 sum += msg[x];
525         sum = (256 - (sum & 255));
526         msg[len++] = sum;
527         /* Wait a half a second */
528         for (x=0;x<4000;x++)
529                 PUT_BYTE(0x7f);
530         /* Transmit 30 0x55's (looks like a square wave) for channel seizure */
531         for (x=0;x<30;x++)
532                 PUT_CLID(0x55);
533         /* Send 170ms of callerid marks */
534         for (x=0;x<170;x++)
535                 PUT_CLID_MARKMS;
536         for (x=0;x<len;x++) {
537                 PUT_CLID(msg[x]);
538         }
539         /* Send 50 more ms of marks */
540         for (x=0;x<50;x++)
541                 PUT_CLID_MARKMS;
542         return bytes;
543 }
544
545 int callerid_generate(unsigned char *buf, char *number, char *name, int flags, int callwaiting, int codec)
546 {
547         int bytes=0;
548         int x, sum;
549         int len;
550         /* Initial carriers (real/imaginary) */
551         float cr = 1.0;
552         float ci = 0.0;
553         float scont = 0.0;
554         char msg[256];
555         len = callerid_genmsg(msg, sizeof(msg), number, name, flags);
556         if (!callwaiting) {
557                 /* Wait a half a second */
558                 for (x=0;x<4000;x++)
559                         PUT_BYTE(0x7f);
560                 /* Transmit 30 0x55's (looks like a square wave) for channel seizure */
561                 for (x=0;x<30;x++)
562                         PUT_CLID(0x55);
563         }
564         /* Send 150ms of callerid marks */
565         for (x=0;x<150;x++)
566                 PUT_CLID_MARKMS;
567         /* Send 0x80 indicating MDMF format */
568         PUT_CLID(0x80);
569         /* Put length of whole message */
570         PUT_CLID(len);
571         sum = 0x80 + strlen(msg);
572         /* Put each character of message and update checksum */
573         for (x=0;x<len; x++) {
574                 PUT_CLID(msg[x]);
575                 sum += msg[x];
576         }
577         /* Send 2's compliment of sum */
578         PUT_CLID(256 - (sum & 255));
579
580         /* Send 50 more ms of marks */
581         for (x=0;x<50;x++)
582                 PUT_CLID_MARKMS;
583         
584         return bytes;
585 }
586
587 void ast_shrink_phone_number(char *n)
588 {
589         int x,y=0;
590         int bracketed=0;
591         for (x=0;n[x];x++) {
592                 switch(n[x]) {
593                 case '[':
594                         bracketed++;
595                         n[y++] = n[x];
596                         break;
597                 case ']':
598                         bracketed--;
599                         n[y++] = n[x];
600                         break;
601                 case '-':
602                         if (bracketed)
603                                 n[y++] = n[x];
604                         break;
605                 case '.':
606                         if (!n[x+1])
607                                 n[y++] = n[x];
608                         break;
609                 default:
610                         if (!strchr("( )", n[x]))
611                                 n[y++] = n[x];
612                 }
613         }
614         n[y] = '\0';
615 }
616
617 int ast_isphonenumber(char *n)
618 {
619         int x;
620         if (ast_strlen_zero(n))
621                 return 0;
622         for (x=0;n[x];x++)
623                 if (!strchr("0123456789*#+", n[x]))
624                         return 0;
625         return 1;
626 }
627
628 int ast_callerid_parse(char *instr, char **name, char **location)
629 {
630         char *ns, *ne;
631         char *ls, *le;
632         char tmp[256];
633         /* Try for "name" <location> format or 
634            name <location> format */
635         if ((ls = strchr(instr, '<')) && (le = strchr(ls, '>'))) {
636                 /* Found the location */
637                 *le = '\0';
638                 *ls = '\0';
639                 *location = ls + 1;
640                 if ((ns = strchr(instr, '\"')) && (ne = strchr(ns + 1, '\"'))) {
641                         /* Get name out of quotes */
642                         *ns = '\0';
643                         *ne = '\0';
644                         *name = ns + 1;
645                         return 0;
646                 } else {
647                         /* Just trim off any trailing spaces */
648                         *name = instr;
649                         while(!ast_strlen_zero(instr) && (instr[strlen(instr) - 1] < 33))
650                                 instr[strlen(instr) - 1] = '\0';
651                         /* And leading spaces */
652                         *name = ast_skip_blanks(*name);
653                         return 0;
654                 }
655         } else {
656                 ast_copy_string(tmp, instr, sizeof(tmp));
657                 ast_shrink_phone_number(tmp);
658                 if (ast_isphonenumber(tmp)) {
659                         /* Assume it's just a location */
660                         *name = NULL;
661                         *location = instr;
662                 } else {
663                         /* Assume it's just a name.  Make sure it's not quoted though */
664                         *name = instr;
665                         while(*(*name) && ((*(*name) < 33) || (*(*name) == '\"'))) (*name)++;
666                         ne = *name + strlen(*name) - 1;
667                         while((ne > *name) && ((*ne < 33) || (*ne == '\"'))) { *ne = '\0'; ne--; }
668                         *location = NULL;
669                 }
670                 return 0;
671         }
672         return -1;
673 }
674
675 static int __ast_callerid_generate(unsigned char *buf, char *name, char *number, int callwaiting, int codec)
676 {
677         if (ast_strlen_zero(name))
678                 name = NULL;
679         if (ast_strlen_zero(number))
680                 number = NULL;
681         return callerid_generate(buf, number, name, 0, callwaiting, codec);
682 }
683
684 int ast_callerid_generate(unsigned char *buf, char *name, char *number, int codec)
685 {
686         return __ast_callerid_generate(buf, name, number, 0, codec);
687 }
688
689 int ast_callerid_callwaiting_generate(unsigned char *buf, char *name, char *number, int codec)
690 {
691         return __ast_callerid_generate(buf, name, number, 1, codec);
692 }
693
694 char *ast_callerid_merge(char *buf, int bufsiz, const char *name, const char *num, const char *unknown)
695 {
696         if (!unknown)
697                 unknown = "<unknown>";
698         if (name && num)
699                 snprintf(buf, bufsiz, "\"%s\" <%s>", name, num);
700         else if (name) 
701                 ast_copy_string(buf, name, bufsiz);
702         else if (num)
703                 ast_copy_string(buf, num, bufsiz);
704         else
705                 ast_copy_string(buf, unknown, bufsiz);
706         return buf;
707 }
708 int ast_callerid_split(const char *buf, char *name, int namelen, char *num, int numlen)
709 {
710         char *tmp;
711         char *l = NULL, *n = NULL;
712         tmp = ast_strdupa(buf);
713         if (!tmp) {
714                 name[0] = '\0';
715                 num[0] = '\0';
716                 return -1;
717         }
718         ast_callerid_parse(tmp, &n, &l);
719         if (n)
720                 ast_copy_string(name, n, namelen);
721         else
722                 name[0] = '\0';
723         if (l) {
724                 ast_shrink_phone_number(l);
725                 ast_copy_string(num, l, numlen);
726         } else
727                 num[0] = '\0';
728         return 0;
729 }
730
731 static struct {
732         int val;
733         char *name;
734         char *description;
735 } pres_types[] = {
736         {  AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED, "allowed_not_screened", "Presentation Allowed, Not Screened"},
737         {  AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, "allowed_passed_screen", "Presentation Allowed, Passed Screen"},
738         {  AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN, "allowed_failed_screen", "Presentation Allowed, Failed Screen"},
739         {  AST_PRES_ALLOWED_NETWORK_NUMBER, "allowed", "Presentation Allowed, Network Number"},
740         {  AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED, "prohib_not_screened", "Presentation Prohibited, Not Screened"},
741         {  AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN, "prohib_passed_screen", "Presentation Prohibited, Passed Screen"},
742         {  AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN, "prohib_failed_screen", "Presentation Prohibited, Failed Screen"},
743         {  AST_PRES_PROHIB_NETWORK_NUMBER, "prohib", "Presentation Prohibited, Network Number"},
744         {  AST_PRES_NUMBER_NOT_AVAILABLE, "unavailable", "Number Unavailable"},
745 };
746
747 int ast_parse_caller_presentation(const char *data)
748 {
749         int i;
750
751         for (i = 0; i < ((sizeof(pres_types) / sizeof(pres_types[0]))); i++) {
752                 if (!strcasecmp(pres_types[i].name, data))
753                         return pres_types[i].val;
754         }
755
756         return -1;
757 }
758
759 const char *ast_describe_caller_presentation(int data)
760 {
761         int i;
762
763         for (i = 0; i < ((sizeof(pres_types) / sizeof(pres_types[0]))); i++) {
764                 if (pres_types[i].val == data)
765                         return pres_types[i].description;
766         }
767
768         return "unknown";
769 }