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