Allow Asterisk to compile under GCC 4.10
[asterisk/asterisk.git] / main / callerid.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 1999 - 2005, Digium, Inc.
5  *
6  * Mark Spencer <markster@digium.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18
19 /*! \file
20  *
21  * \brief CallerID Generation support
22  *
23  * \author Mark Spencer <markster@digium.com>
24  */
25
26 /*** MODULEINFO
27         <support_level>core</support_level>
28  ***/
29
30 #include "asterisk.h"
31
32 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
33
34 #include <time.h>
35 #include <math.h>
36 #include <ctype.h>
37
38 #include "asterisk/ulaw.h"
39 #include "asterisk/alaw.h"
40 #include "asterisk/frame.h"
41 #include "asterisk/channel.h"
42 #include "asterisk/callerid.h"
43 #include "asterisk/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         int skipflag;
61         unsigned short crc;
62 };
63
64
65 float cid_dr[4], cid_di[4];
66 float clidsb = 8000.0 / 1200.0;
67 float sasdr, sasdi;
68 float casdr1, casdi1, casdr2, casdi2;
69
70 #define CALLERID_SPACE  2200.0          /*!< 2200 hz for "0" */
71 #define CALLERID_MARK   1200.0          /*!< 1200 hz for "1" */
72 #define SAS_FREQ                 440.0
73 #define CAS_FREQ1               2130.0
74 #define CAS_FREQ2               2750.0
75
76 #define AST_CALLERID_UNKNOWN    "<unknown>"
77
78 static inline void gen_tones(unsigned char *buf, int len, struct ast_format *codec, float ddr1, float ddi1, float ddr2, float ddi2, float *cr1, float *ci1, float *cr2, float *ci2)
79 {
80         int x;
81         float t;
82         for (x = 0; x < len; x++) {
83                 t = *cr1 * ddr1 - *ci1 * ddi1;
84                 *ci1 = *cr1 * ddi1 + *ci1 * ddr1;
85                 *cr1 = t;
86                 t = 2.0 - (*cr1 * *cr1 + *ci1 * *ci1);
87                 *cr1 *= t;
88                 *ci1 *= t;
89
90                 t = *cr2 * ddr2 - *ci2 * ddi2;
91                 *ci2 = *cr2 * ddi2 + *ci2 * ddr2;
92                 *cr2 = t;
93                 t = 2.0 - (*cr2 * *cr2 + *ci2 * *ci2);
94                 *cr2 *= t;
95                 *ci2 *= t;
96                 buf[x] = AST_LIN2X((*cr1 + *cr2) * 2048.0);
97         }
98 }
99
100 static inline void gen_tone(unsigned char *buf, int len, struct ast_format *codec, float ddr1, float ddi1, float *cr1, float *ci1)
101 {
102         int x;
103         float t;
104         for (x = 0; x < len; x++) {
105                 t = *cr1 * ddr1 - *ci1 * ddi1;
106                 *ci1 = *cr1 * ddi1 + *ci1 * ddr1;
107                 *cr1 = t;
108                 t = 2.0 - (*cr1 * *cr1 + *ci1 * *ci1);
109                 *cr1 *= t;
110                 *ci1 *= t;
111                 buf[x] = AST_LIN2X(*cr1 * 8192.0);
112         }
113 }
114
115 /*! \brief Initialize stuff for inverse FFT */
116 void callerid_init(void)
117 {
118         cid_dr[0] = cos(CALLERID_SPACE * 2.0 * M_PI / 8000.0);
119         cid_di[0] = sin(CALLERID_SPACE * 2.0 * M_PI / 8000.0);
120         cid_dr[1] = cos(CALLERID_MARK * 2.0 * M_PI / 8000.0);
121         cid_di[1] = sin(CALLERID_MARK * 2.0 * M_PI / 8000.0);
122         sasdr = cos(SAS_FREQ * 2.0 * M_PI / 8000.0);
123         sasdi = sin(SAS_FREQ * 2.0 * M_PI / 8000.0);
124         casdr1 = cos(CAS_FREQ1 * 2.0 * M_PI / 8000.0);
125         casdi1 = sin(CAS_FREQ1 * 2.0 * M_PI / 8000.0);
126         casdr2 = cos(CAS_FREQ2 * 2.0 * M_PI / 8000.0);
127         casdi2 = sin(CAS_FREQ2 * 2.0 * M_PI / 8000.0);
128 }
129
130 struct callerid_state *callerid_new(int cid_signalling)
131 {
132         struct callerid_state *cid;
133
134         if ((cid = ast_calloc(1, sizeof(*cid)))) {
135 #ifdef INTEGER_CALLERID
136                 cid->fskd.ispb = 7;             /* 1200 baud */
137                 /* Set up for 1200 / 8000 freq *32 to allow ints */
138                 cid->fskd.pllispb  = (int)(8000 * 32  / 1200);
139                 cid->fskd.pllids   = cid->fskd.pllispb/32;
140                 cid->fskd.pllispb2 = cid->fskd.pllispb/2;
141
142                 cid->fskd.icont = 0;           /* PLL REset */
143                 /* cid->fskd.hdlc = 0; */       /* Async */
144                 cid->fskd.nbit = 8;             /* 8 bits */
145                 cid->fskd.instop = 1;           /* 1 stop bit */
146                 /* cid->fskd.paridad = 0; */    /* No parity */
147                 cid->fskd.bw = 1;               /* Filter 800 Hz */
148                 if (cid_signalling == 2) {      /* v23 signalling */
149                         cid->fskd.f_mark_idx  = 4;      /* 1300 Hz */
150                         cid->fskd.f_space_idx = 5;      /* 2100 Hz */
151                 } else {                        /* Bell 202 signalling as default */
152                         cid->fskd.f_mark_idx  = 2;      /* 1200 Hz */
153                         cid->fskd.f_space_idx = 3;      /* 2200 Hz */
154                 }
155                 /* cid->fskd.pcola = 0; */      /* No clue */
156                 /* cid->fskd.cont = 0.0; */     /* Digital PLL reset */
157                 /* cid->fskd.x0 = 0.0; */
158                 /* cid->fskd.state = 0; */
159                 cid->flags = CID_UNKNOWN_NAME | CID_UNKNOWN_NUMBER;
160                 /* cid->pos = 0; */
161
162                 fskmodem_init(&cid->fskd);
163 #else
164                 cid->fskd.spb = 7.0;            /* 1200 baud */
165                 /* cid->fskd.hdlc = 0; */       /* Async */
166                 cid->fskd.nbit = 8;             /* 8 bits */
167                 cid->fskd.nstop = 1.0;          /* 1 stop bit */
168                 /* cid->fskd.paridad = 0; */    /* No parity */
169                 cid->fskd.bw = 1;               /* Filter 800 Hz */
170                 if (cid_signalling == 2) {      /* v23 signalling */
171                         cid->fskd.f_mark_idx =  4;      /* 1300 Hz */
172                         cid->fskd.f_space_idx = 5;      /* 2100 Hz */
173                 } else {                        /* Bell 202 signalling as default */
174                         cid->fskd.f_mark_idx =  2;      /* 1200 Hz */
175                         cid->fskd.f_space_idx = 3;      /* 2200 Hz */
176                 }
177                 /* cid->fskd.pcola = 0; */      /* No clue */
178                 /* cid->fskd.cont = 0.0; */     /* Digital PLL reset */
179                 /* cid->fskd.x0 = 0.0; */
180                 /* cid->fskd.state = 0; */
181                 cid->flags = CID_UNKNOWN_NAME | CID_UNKNOWN_NUMBER;
182                 /* cid->pos = 0; */
183 #endif
184         }
185
186         return cid;
187 }
188
189 void callerid_get(struct callerid_state *cid, char **name, char **number, int *flags)
190 {
191         *flags = cid->flags;
192         if (cid->flags & (CID_UNKNOWN_NAME | CID_PRIVATE_NAME))
193                 *name = NULL;
194         else
195                 *name = cid->name;
196         if (cid->flags & (CID_UNKNOWN_NUMBER | CID_PRIVATE_NUMBER))
197                 *number = NULL;
198         else
199                 *number = cid->number;
200 }
201
202 void callerid_get_dtmf(char *cidstring, char *number, int *flags)
203 {
204         int i;
205         int code;
206
207         /* "Clear" the number-buffer. */
208         number[0] = 0;
209
210         if (strlen(cidstring) < 2) {
211                 ast_debug(1, "No cid detected\n");
212                 *flags = CID_UNKNOWN_NUMBER;
213                 return;
214         }
215
216         /* Detect protocol and special types */
217         if (cidstring[0] == 'B') {
218                 /* Handle special codes */
219                 code = atoi(&cidstring[1]);
220                 if (code == 0)
221                         *flags = CID_UNKNOWN_NUMBER;
222                 else if (code == 10)
223                         *flags = CID_PRIVATE_NUMBER;
224                 else
225                         ast_debug(1, "Unknown DTMF code %d\n", code);
226         } else if (cidstring[0] == 'D' && cidstring[2] == '#') {
227                 /* .DK special code */
228                 if (cidstring[1] == '1')
229                         *flags = CID_PRIVATE_NUMBER;
230                 if (cidstring[1] == '2' || cidstring[1] == '3')
231                         *flags = CID_UNKNOWN_NUMBER;
232         } else if (cidstring[0] == 'D' || cidstring[0] == 'A') {
233                 /* "Standard" callerid */
234                 for (i = 1; i < strlen(cidstring); i++) {
235                         if (cidstring[i] == 'C' || cidstring[i] == '#')
236                                 break;
237                         if (isdigit(cidstring[i]))
238                                 number[i-1] = cidstring[i];
239                         else
240                                 ast_debug(1, "Unknown CID digit '%c'\n",
241                                         cidstring[i]);
242                 }
243                 number[i-1] = 0;
244         } else if (isdigit(cidstring[0])) {
245                 /* It begins with a digit, so we parse it as a number and hope
246                  * for the best */
247                 ast_log(LOG_WARNING, "Couldn't detect start-character. CID "
248                         "parsing might be unreliable\n");
249                 for (i = 0; i < strlen(cidstring); i++) {
250                         if (isdigit(cidstring[i]))
251                                 number[i] = cidstring[i];
252                         else
253                                 break;
254                 }
255                 number[i] = 0;
256         } else {
257                 ast_debug(1, "Unknown CID protocol, start digit '%c'\n", cidstring[0]);
258                 *flags = CID_UNKNOWN_NUMBER;
259         }
260 }
261
262 int ast_gen_cas(unsigned char *outbuf, int sendsas, int len, struct ast_format *codec)
263 {
264         int pos = 0;
265         int saslen = 2400;
266         float cr1 = 1.0;
267         float ci1 = 0.0;
268         float cr2 = 1.0;
269         float ci2 = 0.0;
270
271         if (sendsas) {
272                 if (len < saslen)
273                         return -1;
274                 gen_tone(outbuf, saslen, codec, sasdr, sasdi, &cr1, &ci1);
275                 len -= saslen;
276                 pos += saslen;
277                 cr2 = cr1;
278                 ci2 = ci1;
279         }
280         gen_tones(outbuf + pos, len, codec, casdr1, casdi1, casdr2, casdi2, &cr1, &ci1, &cr2, &ci2);
281         return 0;
282 }
283
284 static unsigned short calc_crc(unsigned short crc, unsigned char data)
285 {
286         unsigned int i, j, org, dst;
287         org = data;
288         dst = 0;
289
290         for (i = 0; i < CHAR_BIT; i++) {
291                 org <<= 1;
292                 dst >>= 1;
293                 if (org & 0x100)
294                         dst |= 0x80;
295         }
296         data = (unsigned char) dst;
297         crc ^= (unsigned int) data << (16 - CHAR_BIT);
298         for (j = 0; j < CHAR_BIT; j++) {
299                 if (crc & 0x8000U)
300                         crc = (crc << 1) ^ 0x1021U ;
301                 else
302                         crc <<= 1 ;
303         }
304         return crc;
305 }
306
307 int callerid_feed_jp(struct callerid_state *cid, unsigned char *ubuf, int len, struct ast_format *codec)
308 {
309         int mylen = len;
310         int olen;
311         int b = 'X';
312         int b2;
313         int res;
314         int x;
315         short *buf;
316
317         buf = ast_alloca(2 * len + cid->oldlen);
318
319         memcpy(buf, cid->oldstuff, cid->oldlen);
320         mylen += cid->oldlen / 2;
321
322         for (x = 0; x < len; x++)
323                 buf[x+cid->oldlen/2] = AST_XLAW(ubuf[x]);
324
325         while (mylen >= 160) {
326                 b = b2 = 0;
327                 olen = mylen;
328                 res = fsk_serial(&cid->fskd, buf, &mylen, &b);
329
330                 if (mylen < 0) {
331                         ast_log(LOG_ERROR, "No start bit found in fsk data.\n");
332                         return -1;
333                 }
334
335                 buf += (olen - mylen);
336
337                 if (res < 0) {
338                         ast_log(LOG_NOTICE, "fsk_serial failed\n");
339                         return -1;
340                 }
341
342                 if (res == 1) {
343                         b2 = b;
344                         b  &= 0x7f;
345
346                         /* crc checksum calculation */
347                         if (cid->sawflag > 1)
348                                 cid->crc = calc_crc(cid->crc, (unsigned char) b2);
349
350                         /* Ignore invalid bytes */
351                         if (b > 0xff)
352                                 continue;
353
354                         /* skip DLE if needed */
355                         if (cid->sawflag > 0) {
356                                 if (cid->sawflag != 5 && cid->skipflag == 0 && b == 0x10) {
357                                         cid->skipflag = 1 ;
358                                         continue ;
359                                 }
360                         }
361                         if (cid->skipflag == 1)
362                                 cid->skipflag = 0 ;
363
364                         /* caller id retrieval */
365                         switch (cid->sawflag) {
366                         case 0: /* DLE */
367                                 if (b == 0x10) {
368                                         cid->sawflag = 1;
369                                         cid->skipflag = 0;
370                                         cid->crc = 0;
371                                 }
372                                 break;
373                         case 1: /* SOH */
374                                 if (b == 0x01)
375                                         cid->sawflag = 2;
376                                 break ;
377                         case 2: /* HEADER */
378                                 if (b == 0x07)
379                                         cid->sawflag = 3;
380                                 break;
381                         case 3: /* STX */
382                                 if (b == 0x02)
383                                         cid->sawflag = 4;
384                                 break;
385                         case 4: /* SERVICE TYPE */
386                                 if (b == 0x40)
387                                         cid->sawflag = 5;
388                                 break;
389                         case 5: /* Frame Length */
390                                 cid->sawflag = 6;
391                                 break;
392                         case 6: /* NUMBER TYPE */
393                                 cid->sawflag = 7;
394                                 cid->pos = 0;
395                                 cid->rawdata[cid->pos++] = b;
396                                 break;
397                         case 7: /* NUMBER LENGTH */
398                                 cid->sawflag = 8;
399                                 cid->len = b;
400                                 if ((cid->len+2) >= sizeof(cid->rawdata)) {
401                                         ast_log(LOG_WARNING, "too long caller id string\n") ;
402                                         return -1;
403                                 }
404                                 cid->rawdata[cid->pos++] = b;
405                                 break;
406                         case 8: /* Retrieve message */
407                                 cid->rawdata[cid->pos++] = b;
408                                 cid->len--;
409                                 if (cid->len<=0) {
410                                         cid->rawdata[cid->pos] = '\0';
411                                         cid->sawflag = 9;
412                                 }
413                                 break;
414                         case 9: /* ETX */
415                                 cid->sawflag = 10;
416                                 break;
417                         case 10: /* CRC Checksum 1 */
418                                 cid->sawflag = 11;
419                                 break;
420                         case 11: /* CRC Checksum 2 */
421                                 cid->sawflag = 12;
422                                 if (cid->crc != 0) {
423                                         ast_log(LOG_WARNING, "crc checksum error\n") ;
424                                         return -1;
425                                 }
426                                 /* extract caller id data */
427                                 for (x = 0; x < cid->pos;) {
428                                         switch (cid->rawdata[x++]) {
429                                         case 0x02: /* caller id  number */
430                                                 cid->number[0] = '\0';
431                                                 cid->name[0] = '\0';
432                                                 cid->flags = 0;
433                                                 res = cid->rawdata[x++];
434                                                 ast_copy_string(cid->number, &cid->rawdata[x], res+1);
435                                                 x += res;
436                                                 break;
437                                         case 0x21: /* additional information */
438                                                 /* length */
439                                                 x++;
440                                                 /* number type */
441                                                 switch (cid->rawdata[x]) {
442                                                 case 0x00: /* unknown */
443                                                 case 0x01: /* international number */
444                                                 case 0x02: /* domestic number */
445                                                 case 0x03: /* network */
446                                                 case 0x04: /* local call */
447                                                 case 0x06: /* short dial number */
448                                                 case 0x07: /* reserved */
449                                                 default:   /* reserved */
450                                                         ast_debug(2, "cid info:#1=%X\n", (unsigned)cid->rawdata[x]);
451                                                         break ;
452                                                 }
453                                                 x++;
454                                                 /* numbering plan octed 4 */
455                                                 x++;
456                                                 /* numbering plan octed 5 */
457                                                 switch (cid->rawdata[x]) {
458                                                 case 0x00: /* unknown */
459                                                 case 0x01: /* recommendation E.164 ISDN */
460                                                 case 0x03: /* recommendation X.121 */
461                                                 case 0x04: /* telex dial plan */
462                                                 case 0x08: /* domestic dial plan */
463                                                 case 0x09: /* private dial plan */
464                                                 case 0x05: /* reserved */
465                                                 default:   /* reserved */
466                                                         ast_debug(2, "cid info:#2=%X\n", (unsigned)cid->rawdata[x]);
467                                                         break ;
468                                                 }
469                                                 x++;
470                                                 break ;
471                                         case 0x04: /* no callerid reason */
472                                                 /* length */
473                                                 x++;
474                                                 /* no callerid reason code */
475                                                 switch (cid->rawdata[x]) {
476                                                 case 'P': /* caller id denied by user */
477                                                 case 'O': /* service not available */
478                                                 case 'C': /* pay phone */
479                                                 case 'S': /* service congested */
480                                                         cid->flags |= CID_UNKNOWN_NUMBER;
481                                                         ast_debug(2, "no cid reason:%c\n", cid->rawdata[x]);
482                                                         break ;
483                                                 }
484                                                 x++;
485                                                 break ;
486                                         case 0x09: /* dialed number */
487                                                 /* length */
488                                                 res = cid->rawdata[x++];
489                                                 /* dialed number */
490                                                 x += res;
491                                                 break ;
492                                         case 0x22: /* dialed number additional information */
493                                                 /* length */
494                                                 x++;
495                                                 /* number type */
496                                                 switch (cid->rawdata[x]) {
497                                                 case 0x00: /* unknown */
498                                                 case 0x01: /* international number */
499                                                 case 0x02: /* domestic number */
500                                                 case 0x03: /* network */
501                                                 case 0x04: /* local call */
502                                                 case 0x06: /* short dial number */
503                                                 case 0x07: /* reserved */
504                                                 default:   /* reserved */
505                                                         if (option_debug > 1)
506                                                                 ast_log(LOG_NOTICE, "did info:#1=%X\n", (unsigned)cid->rawdata[x]);
507                                                         break ;
508                                                 }
509                                                 x++;
510                                                 /* numbering plan octed 4 */
511                                                 x++;
512                                                 /* numbering plan octed 5 */
513                                                 switch (cid->rawdata[x]) {
514                                                 case 0x00: /* unknown */
515                                                 case 0x01: /* recommendation E.164 ISDN */
516                                                 case 0x03: /* recommendation X.121 */
517                                                 case 0x04: /* telex dial plan */
518                                                 case 0x08: /* domestic dial plan */
519                                                 case 0x09: /* private dial plan */
520                                                 case 0x05: /* reserved */
521                                                 default:   /* reserved */
522                                                         ast_debug(2, "did info:#2=%X\n", (unsigned)cid->rawdata[x]);
523                                                         break ;
524                                                 }
525                                                 x++;
526                                                 break ;
527                                         }
528                                 }
529                                 return 1;
530                                 break;
531                         default:
532                                 ast_log(LOG_ERROR, "invalid value in sawflag %d\n", cid->sawflag);
533                         }
534                 }
535         }
536         if (mylen) {
537                 memcpy(cid->oldstuff, buf, mylen * 2);
538                 cid->oldlen = mylen * 2;
539         } else
540                 cid->oldlen = 0;
541
542         return 0;
543 }
544
545
546 int callerid_feed(struct callerid_state *cid, unsigned char *ubuf, int len, struct ast_format *codec)
547 {
548         int mylen = len;
549         int olen;
550         int b = 'X';
551         int res;
552         int x;
553         short *buf;
554
555         buf = ast_alloca(2 * len + cid->oldlen);
556
557         memcpy(buf, cid->oldstuff, cid->oldlen);
558         mylen += cid->oldlen/2;
559
560         for (x = 0; x < len; x++)
561                 buf[x+cid->oldlen/2] = AST_XLAW(ubuf[x]);
562         while (mylen >= 160) {
563                 olen = mylen;
564                 res = fsk_serial(&cid->fskd, buf, &mylen, &b);
565                 if (mylen < 0) {
566                         ast_log(LOG_ERROR, "No start bit found in fsk data.\n");
567                         return -1;
568                 }
569                 buf += (olen - mylen);
570                 if (res < 0) {
571                         ast_log(LOG_NOTICE, "fsk_serial failed\n");
572                         return -1;
573                 }
574                 if (res == 1) {
575                         if (b > 0xff) {
576                                 if (cid->sawflag != 5) {
577                                         /* Ignore invalid bytes */
578                                         continue;
579                                 }
580                                 /*
581                                  * We can tollerate an error on the checksum character since the
582                                  * checksum character is the last character in the message and
583                                  * it validates the message.
584                                  *
585                                  * Remove character error flags.
586                                  * Bit 8 : Parity error
587                                  * Bit 9 : Framing error
588                                  */
589                                 b &= 0xff;
590                         }
591                         switch (cid->sawflag) {
592                         case 0: /* Look for flag */
593                                 if (b == 'U')
594                                         cid->sawflag = 2;
595                                 break;
596                         case 2: /* Get lead-in */
597                                 if ((b == 0x04) || (b == 0x80) || (b == 0x06) || (b == 0x82)) {
598                                         cid->type = b;
599                                         cid->sawflag = 3;
600                                         cid->cksum = b;
601                                 }
602                                 break;
603                         case 3: /* Get length */
604                                 /* Not a lead in.  We're ready  */
605                                 cid->sawflag = 4;
606                                 cid->len = b;
607                                 cid->pos = 0;
608                                 cid->cksum += b;
609                                 break;
610                         case 4: /* Retrieve message */
611                                 if (cid->pos >= 128) {
612                                         ast_log(LOG_WARNING, "Caller ID too long???\n");
613                                         return -1;
614                                 }
615                                 cid->rawdata[cid->pos++] = b;
616                                 cid->len--;
617                                 cid->cksum += b;
618                                 if (!cid->len) {
619                                         cid->rawdata[cid->pos] = '\0';
620                                         cid->sawflag = 5;
621                                 }
622                                 break;
623                         case 5: /* Check checksum */
624                                 if ((b + cid->cksum) & 0xff) {
625                                         ast_log(LOG_NOTICE, "Caller*ID failed checksum\n");
626                                         /* Try again */
627                                         cid->sawflag = 0;
628                                         break;
629                                 }
630
631                                 cid->number[0] = '\0';
632                                 cid->name[0] = '\0';
633                                 /* Update flags */
634                                 cid->flags = 0;
635                                 /* If we get this far we're fine.  */
636                                 if ((cid->type == 0x80) || (cid->type == 0x82)) {
637                                         /* MDMF */
638                                         /* Go through each element and process */
639                                         for (x = 0; x < cid->pos;) {
640                                                 switch (cid->rawdata[x++]) {
641                                                 case 1:
642                                                         /* Date */
643                                                         break;
644                                                 case 2: /* Number */
645                                                 case 3: /* Number (for Zebble) */
646                                                 case 4: /* Number */
647                                                         res = cid->rawdata[x];
648                                                         if (res > 32) {
649                                                                 ast_log(LOG_NOTICE, "Truncating long caller ID number from %d bytes to 32\n", cid->rawdata[x]);
650                                                                 res = 32;
651                                                         }
652                                                         if (ast_strlen_zero(cid->number)) {
653                                                                 memcpy(cid->number, cid->rawdata + x + 1, res);
654                                                                 /* Null terminate */
655                                                                 cid->number[res] = '\0';
656                                                         }
657                                                         break;
658                                                 case 6: /* Stentor Call Qualifier (ie. Long Distance call) */
659                                                         break;
660                                                 case 7: /* Name */
661                                                 case 8: /* Name */
662                                                         res = cid->rawdata[x];
663                                                         if (res > 32) {
664                                                                 ast_log(LOG_NOTICE, "Truncating long caller ID name from %d bytes to 32\n", cid->rawdata[x]);
665                                                                 res = 32;
666                                                         }
667                                                         memcpy(cid->name, cid->rawdata + x + 1, res);
668                                                         cid->name[res] = '\0';
669                                                         break;
670                                                 case 11: /* Message Waiting */
671                                                         res = cid->rawdata[x + 1];
672                                                         if (res)
673                                                                 cid->flags |= CID_MSGWAITING;
674                                                         else
675                                                                 cid->flags |= CID_NOMSGWAITING;
676                                                         break;
677                                                 case 17: /* UK: Call type, 1=Voice Call, 2=Ringback when free, 129=Message waiting  */
678                                                 case 19: /* UK: Network message system status (Number of messages waiting) */
679                                                 case 22: /* Something French */
680                                                         break;
681                                                 default:
682                                                         ast_log(LOG_NOTICE, "Unknown IE %d\n", cid->rawdata[x - 1]);
683                                                 }
684                                                 res = cid->rawdata[x];
685                                                 if (0 > res){   /* Negative offset in the CID Spill */
686                                                         ast_log(LOG_NOTICE, "IE %d has bad field length of %d at offset %d\n", cid->rawdata[x-1], cid->rawdata[x], x);
687                                                         /* Try again */
688                                                         cid->sawflag = 0;
689                                                         break;  /* Exit the loop */
690                                                 }
691                                                 x += cid->rawdata[x];
692                                                 x++;
693                                         }
694                                 } else if (cid->type == 0x6) {
695                                         /* VMWI SDMF */
696                                         if (cid->rawdata[2] == 0x42) {
697                                                 cid->flags |= CID_MSGWAITING;
698                                         } else if (cid->rawdata[2] == 0x6f) {
699                                                 cid->flags |= CID_NOMSGWAITING;
700                                         }
701                                 } else {
702                                         /* SDMF */
703                                         ast_copy_string(cid->number, cid->rawdata + 8, sizeof(cid->number));
704                                 }
705                                 if (!strcmp(cid->number, "P")) {
706                                         strcpy(cid->number, "");
707                                         cid->flags |= CID_PRIVATE_NUMBER;
708                                 } else if (!strcmp(cid->number, "O") || ast_strlen_zero(cid->number)) {
709                                         strcpy(cid->number, "");
710                                         cid->flags |= CID_UNKNOWN_NUMBER;
711                                 }
712                                 if (!strcmp(cid->name, "P")) {
713                                         strcpy(cid->name, "");
714                                         cid->flags |= CID_PRIVATE_NAME;
715                                 } else if (!strcmp(cid->name, "O") || ast_strlen_zero(cid->name)) {
716                                         strcpy(cid->name, "");
717                                         cid->flags |= CID_UNKNOWN_NAME;
718                                 }
719                                 return 1;
720                                 break;
721                         default:
722                                 ast_log(LOG_ERROR, "Dunno what to do with a digit in sawflag %d\n", cid->sawflag);
723                         }
724                 }
725         }
726         if (mylen) {
727                 memcpy(cid->oldstuff, buf, mylen * 2);
728                 cid->oldlen = mylen * 2;
729         } else
730                 cid->oldlen = 0;
731
732         return 0;
733 }
734
735 void callerid_free(struct callerid_state *cid)
736 {
737         ast_free(cid);
738 }
739
740 static int callerid_genmsg(char *msg, int size, const char *number, const char *name, int flags)
741 {
742         struct timeval now = ast_tvnow();
743         struct ast_tm tm;
744         char *ptr;
745         int res;
746         int i, x;
747
748         /* Get the time */
749         ast_localtime(&now, &tm, NULL);
750
751         ptr = msg;
752
753         /* Format time and message header */
754         res = snprintf(ptr, size, "\001\010%02d%02d%02d%02d", tm.tm_mon + 1,
755                                 tm.tm_mday, tm.tm_hour, tm.tm_min);
756         size -= res;
757         ptr += res;
758         if (ast_strlen_zero(number) || (flags & CID_UNKNOWN_NUMBER)) {
759                 /* Indicate number not known */
760                 res = snprintf(ptr, size, "\004\001O");
761                 size -= res;
762                 ptr += res;
763         } else if (flags & CID_PRIVATE_NUMBER) {
764                 /* Indicate number is private */
765                 res = snprintf(ptr, size, "\004\001P");
766                 size -= res;
767                 ptr += res;
768         } else {
769                 /* Send up to 16 digits of number MAX */
770                 i = strlen(number);
771                 if (i > 16)
772                         i = 16;
773                 res = snprintf(ptr, size, "\002%c", i);
774                 size -= res;
775                 ptr += res;
776                 for (x = 0; x < i; x++)
777                         ptr[x] = number[x];
778                 ptr[i] = '\0';
779                 ptr += i;
780                 size -= i;
781         }
782
783         if (ast_strlen_zero(name) || (flags & CID_UNKNOWN_NAME)) {
784                 /* Indicate name not known */
785                 res = snprintf(ptr, size, "\010\001O");
786                 size -= res;
787                 ptr += res;
788         } else if (flags & CID_PRIVATE_NAME) {
789                 /* Indicate name is private */
790                 res = snprintf(ptr, size, "\010\001P");
791                 size -= res;
792                 ptr += res;
793         } else {
794                 /* Send up to 16 digits of name MAX */
795                 i = strlen(name);
796                 if (i > 16)
797                         i = 16;
798                 res = snprintf(ptr, size, "\007%c", i);
799                 size -= res;
800                 ptr += res;
801                 for (x = 0; x < i; x++)
802                         ptr[x] = name[x];
803                 ptr[i] = '\0';
804                 ptr += i;
805                 size -= i;
806         }
807         return (ptr - msg);
808
809 }
810
811 int ast_callerid_vmwi_generate(unsigned char *buf, int active, int type, struct ast_format *codec,
812                                const char* name, const char* number, int flags)
813 {
814         char msg[256];
815         int len = 0;
816         int sum;
817         int x;
818         int bytes = 0;
819         float cr = 1.0;
820         float ci = 0.0;
821         float scont = 0.0;
822
823         if (type == CID_MWI_TYPE_MDMF_FULL) {
824                 /* MDMF Message waiting with date, number, name and MWI parameter */
825                 msg[0] = 0x82;
826
827                 /* put date, number info at the right place */
828                 len = callerid_genmsg(msg+2, sizeof(msg)-2, number, name, flags);
829
830                 /* length of MDMF CLI plus Message Waiting Structure */
831                 msg[1] = len+3;
832
833                 /* Go to the position to write to */
834                 len = len+2;
835
836                 /* "Message Waiting Parameter" */
837                 msg[len++] = 0x0b;
838                 /* Length of IE is one */
839                 msg[len++] = 1;
840                 /* Active or not */
841                 if (active)
842                         msg[len++] = 0xff;
843                 else
844                         msg[len++] = 0x00;
845
846         } else if (type == CID_MWI_TYPE_MDMF) {
847                 /* MDMF Message waiting only */
848                 /* same as above except that the we only put MWI parameter */
849                 msg[len++] = 0x82;
850                 /* Length is 3 */
851                 msg[len++] = 3;
852                 /* IE is "Message Waiting Parameter" */
853                 msg[len++] = 0x0b;
854                 /* Length of IE is one */
855                 msg[len++] = 1;
856                 /* Active or not */
857                 if (active)
858                         msg[len++] = 0xff;
859                 else
860                         msg[len++] = 0x00;
861         } else {
862                 /* SDMF Message waiting */
863                 msg[len++] = 0x6;
864                 /* Length is 3 */
865                 msg[len++] = 3;
866                 if (active) {
867                         msg[len++] = 0x42;
868                         msg[len++] = 0x42;
869                         msg[len++] = 0x42;
870                 } else {
871                         msg[len++] = 0x6f;
872                         msg[len++] = 0x6f;
873                         msg[len++] = 0x6f;
874                 }
875         }
876         sum = 0;
877         for (x = 0; x < len; x++)
878                 sum += msg[x];
879         sum = (256 - (sum & 255));
880         msg[len++] = sum;
881         /* Wait a half a second */
882         for (x = 0; x < 4000; x++)
883                 PUT_BYTE(0x7f);
884         /* Transmit 30 0x55's (looks like a square wave) for channel seizure */
885         for (x = 0; x < 30; x++)
886                 PUT_CLID(0x55);
887         /* Send 170ms of callerid marks */
888         for (x = 0; x < 170; x++)
889                 PUT_CLID_MARKMS;
890         for (x = 0; x < len; x++) {
891                 PUT_CLID(msg[x]);
892         }
893         /* Send 50 more ms of marks */
894         for (x = 0; x < 50; x++)
895                 PUT_CLID_MARKMS;
896         return bytes;
897 }
898
899 int callerid_generate(unsigned char *buf, const char *number, const char *name, int flags, int callwaiting, struct ast_format *codec)
900 {
901         int bytes = 0;
902         int x, sum;
903         int len;
904
905         /* Initial carriers (real/imaginary) */
906         float cr = 1.0;
907         float ci = 0.0;
908         float scont = 0.0;
909         char msg[256];
910         len = callerid_genmsg(msg, sizeof(msg), number, name, flags);
911         if (!callwaiting) {
912                 /* Wait a half a second */
913                 for (x = 0; x < 4000; x++)
914                         PUT_BYTE(0x7f);
915                 /* Transmit 30 0x55's (looks like a square wave) for channel seizure */
916                 for (x = 0; x < 30; x++)
917                         PUT_CLID(0x55);
918         }
919         /* Send 150ms of callerid marks */
920         for (x = 0; x < 150; x++)
921                 PUT_CLID_MARKMS;
922         /* Send 0x80 indicating MDMF format */
923         PUT_CLID(0x80);
924         /* Put length of whole message */
925         PUT_CLID(len);
926         sum = 0x80 + strlen(msg);
927         /* Put each character of message and update checksum */
928         for (x = 0; x < len; x++) {
929                 PUT_CLID(msg[x]);
930                 sum += msg[x];
931         }
932         /* Send 2's compliment of sum */
933         PUT_CLID(256 - (sum & 255));
934
935         /* Send 50 more ms of marks */
936         for (x = 0; x < 50; x++)
937                 PUT_CLID_MARKMS;
938
939         return bytes;
940 }
941
942 /*!
943  * \brief Clean up phone string
944  * \details
945  * Remove '(', ' ', ')', non-trailing '.', and '-' not in square brackets.
946  * Basically, remove anything that could be invalid in a pattern.
947  */
948 void ast_shrink_phone_number(char *n)
949 {
950         int x, y = 0;
951         int bracketed = 0;
952
953         for (x = 0; n[x]; x++) {
954                 switch (n[x]) {
955                 case '[':
956                         bracketed++;
957                         n[y++] = n[x];
958                         break;
959                 case ']':
960                         bracketed--;
961                         n[y++] = n[x];
962                         break;
963                 case '-':
964                         if (bracketed)
965                                 n[y++] = n[x];
966                         break;
967                 case '.':
968                         if (!n[x+1])
969                                 n[y++] = n[x];
970                         break;
971                 default:
972                         /* ignore parenthesis and whitespace */
973                         if (!strchr("( )", n[x]))
974                                 n[y++] = n[x];
975                 }
976         }
977         n[y] = '\0';
978 }
979
980 /*!
981  * \brief Checks if phone number consists of valid characters
982  * \param exten String that needs to be checked
983  * \param valid Valid characters in string
984  * \retval 1 if valid string
985  * \retval 0 if string contains invalid characters
986  */
987 static int ast_is_valid_string(const char *exten, const char *valid)
988 {
989         int x;
990
991         if (ast_strlen_zero(exten))
992                 return 0;
993         for (x = 0; exten[x]; x++)
994                 if (!strchr(valid, exten[x]))
995                         return 0;
996         return 1;
997 }
998
999 int ast_isphonenumber(const char *n)
1000 {
1001         return ast_is_valid_string(n, "0123456789*#+");
1002 }
1003
1004 int ast_is_shrinkable_phonenumber(const char *exten)
1005 {
1006         return ast_is_valid_string(exten, "0123456789*#+()-.");
1007 }
1008
1009 int ast_callerid_parse(char *instr, char **name, char **location)
1010 {
1011         char *ns, *ne, *ls, *le;
1012
1013         /* Try "name" <location> format or name <location> format */
1014         if ((ls = strrchr(instr, '<')) && (le = strrchr(ls, '>'))) {
1015                 *ls = *le = '\0';       /* location found, trim off the brackets */
1016                 *location = ls + 1;     /* and this is the result */
1017                 if ((ns = strchr(instr, '"')) && (ne = strchr(ns + 1, '"'))) {
1018                         *ns = *ne = '\0';       /* trim off the quotes */
1019                         *name = ns + 1;         /* and this is the name */
1020                 } else if (ns) {
1021                         /* An opening quote was found but no closing quote was. The closing
1022                          * quote may actually be after the end of the bracketed number
1023                          */
1024                         if (strchr(le + 1, '\"')) {
1025                                 *ns = '\0';
1026                                 *name = ns + 1;
1027                                 ast_trim_blanks(*name);
1028                         } else {
1029                                 *name = NULL;
1030                         }
1031                 } else { /* no quotes, trim off leading and trailing spaces */
1032                         *name = ast_skip_blanks(instr);
1033                         ast_trim_blanks(*name);
1034                 }
1035         } else {        /* no valid brackets */
1036                 char tmp[256];
1037
1038                 ast_copy_string(tmp, instr, sizeof(tmp));
1039                 ast_shrink_phone_number(tmp);
1040                 if (ast_isphonenumber(tmp)) {   /* Assume it's just a location */
1041                         *name = NULL;
1042                         strcpy(instr, tmp); /* safe, because tmp will always be the same size or smaller than instr */
1043                         *location = instr;
1044                 } else { /* Assume it's just a name. */
1045                         *location = NULL;
1046                         if ((ns = strchr(instr, '"')) && (ne = strchr(ns + 1, '"'))) {
1047                                 *ns = *ne = '\0';       /* trim off the quotes */
1048                                 *name = ns + 1;         /* and this is the name */
1049                         } else { /* no quotes, trim off leading and trailing spaces */
1050                                 *name = ast_skip_blanks(instr);
1051                                 ast_trim_blanks(*name);
1052                         }
1053                 }
1054         }
1055         return 0;
1056 }
1057
1058 static int __ast_callerid_generate(unsigned char *buf, const char *name, const char *number, int callwaiting, struct ast_format *codec)
1059 {
1060         if (ast_strlen_zero(name))
1061                 name = NULL;
1062         if (ast_strlen_zero(number))
1063                 number = NULL;
1064         return callerid_generate(buf, number, name, 0, callwaiting, codec);
1065 }
1066
1067 int ast_callerid_generate(unsigned char *buf, const char *name, const char *number, struct ast_format *codec)
1068 {
1069         return __ast_callerid_generate(buf, name, number, 0, codec);
1070 }
1071
1072 int ast_callerid_callwaiting_generate(unsigned char *buf, const char *name, const char *number, struct ast_format *codec)
1073 {
1074         return __ast_callerid_generate(buf, name, number, 1, codec);
1075 }
1076
1077 char *ast_callerid_merge(char *buf, int bufsiz, const char *name, const char *num, const char *unknown)
1078 {
1079         if (!unknown)
1080                 unknown = "<unknown>";
1081         if (name && num)
1082                 snprintf(buf, bufsiz, "\"%s\" <%s>", name, num);
1083         else if (name)
1084                 ast_copy_string(buf, name, bufsiz);
1085         else if (num)
1086                 ast_copy_string(buf, num, bufsiz);
1087         else
1088                 ast_copy_string(buf, unknown, bufsiz);
1089         return buf;
1090 }
1091
1092 int ast_callerid_split(const char *buf, char *name, int namelen, char *num, int numlen)
1093 {
1094         char *tmp;
1095         char *l = NULL, *n = NULL;
1096
1097         tmp = ast_strdupa(buf);
1098         ast_callerid_parse(tmp, &n, &l);
1099         if (n)
1100                 ast_copy_string(name, n, namelen);
1101         else
1102                 name[0] = '\0';
1103         if (l) {
1104                 ast_shrink_phone_number(l);
1105                 ast_copy_string(num, l, numlen);
1106         } else
1107                 num[0] = '\0';
1108         return 0;
1109 }
1110
1111 struct ast_value_translation {
1112         int value;
1113         const char *name;
1114         const char *description;
1115 };
1116
1117 /*! \brief Translation table for Caller ID Presentation settings */
1118 static const struct ast_value_translation pres_types[] = {
1119 /* *INDENT-OFF* */
1120         { AST_PRES_ALLOWED | AST_PRES_USER_NUMBER_UNSCREENED,        "allowed_not_screened",  "Presentation Allowed, Not Screened" },
1121         { AST_PRES_ALLOWED | AST_PRES_USER_NUMBER_PASSED_SCREEN,     "allowed_passed_screen", "Presentation Allowed, Passed Screen" },
1122         { AST_PRES_ALLOWED | AST_PRES_USER_NUMBER_FAILED_SCREEN,     "allowed_failed_screen", "Presentation Allowed, Failed Screen" },
1123         { AST_PRES_ALLOWED | AST_PRES_NETWORK_NUMBER,                "allowed",               "Presentation Allowed, Network Number" },
1124
1125         { AST_PRES_RESTRICTED | AST_PRES_USER_NUMBER_UNSCREENED,     "prohib_not_screened",   "Presentation Prohibited, Not Screened" },
1126         { AST_PRES_RESTRICTED | AST_PRES_USER_NUMBER_PASSED_SCREEN,  "prohib_passed_screen",  "Presentation Prohibited, Passed Screen" },
1127         { AST_PRES_RESTRICTED | AST_PRES_USER_NUMBER_FAILED_SCREEN,  "prohib_failed_screen",  "Presentation Prohibited, Failed Screen" },
1128         { AST_PRES_RESTRICTED | AST_PRES_NETWORK_NUMBER,             "prohib",                "Presentation Prohibited, Network Number" },
1129
1130         { AST_PRES_UNAVAILABLE | AST_PRES_NETWORK_NUMBER,            "unavailable",           "Number Unavailable" }, /* Default name to value conversion. */
1131         { AST_PRES_UNAVAILABLE | AST_PRES_USER_NUMBER_UNSCREENED,    "unavailable",           "Number Unavailable" },
1132         { AST_PRES_UNAVAILABLE | AST_PRES_USER_NUMBER_FAILED_SCREEN, "unavailable",           "Number Unavailable" },
1133         { AST_PRES_UNAVAILABLE | AST_PRES_USER_NUMBER_PASSED_SCREEN, "unavailable",           "Number Unavailable" },
1134 /* *INDENT-ON* */
1135 };
1136
1137 /*!
1138  * \brief Convert caller ID text code to value (used in config file parsing)
1139  * \param data text string from config file
1140  * \retval value AST_PRES_ from callerid.h
1141  * \retval -1 if not in table
1142  */
1143 int ast_parse_caller_presentation(const char *data)
1144 {
1145         int index;
1146         if (!data) {
1147                 return -1;
1148         }
1149
1150         for (index = 0; index < ARRAY_LEN(pres_types); ++index) {
1151                 if (!strcasecmp(pres_types[index].name, data)) {
1152                         return pres_types[index].value;
1153                 }
1154         }
1155
1156         return -1;
1157 }
1158
1159 /*!
1160  * \brief Convert caller ID pres value to explanatory string
1161  * \param data AST_PRES_ value from callerid.h
1162  * \return string for human presentation
1163  */
1164 const char *ast_describe_caller_presentation(int data)
1165 {
1166         int index;
1167
1168         for (index = 0; index < ARRAY_LEN(pres_types); ++index) {
1169                 if (pres_types[index].value == data) {
1170                         return pres_types[index].description;
1171                 }
1172         }
1173
1174         return "unknown";
1175 }
1176
1177 /*!
1178  * \brief Convert caller ID pres value to text code
1179  * \param data AST_PRES_ value from callerid.h
1180  * \return string for config file
1181  */
1182 const char *ast_named_caller_presentation(int data)
1183 {
1184         int index;
1185
1186         for (index = 0; index < ARRAY_LEN(pres_types); ++index) {
1187                 if (pres_types[index].value == data) {
1188                         return pres_types[index].name;
1189                 }
1190         }
1191
1192         return "unknown";
1193 }
1194
1195 /*! \brief Translation table for redirecting reason settings */
1196 static const struct ast_value_translation redirecting_reason_types[] = {
1197 /* *INDENT-OFF* */
1198         { AST_REDIRECTING_REASON_UNKNOWN,        "unknown",      "Unknown" },
1199         { AST_REDIRECTING_REASON_USER_BUSY,      "cfb",          "Call Forwarding Busy" },
1200         { AST_REDIRECTING_REASON_NO_ANSWER,      "cfnr",         "Call Forwarding No Reply" },
1201         { AST_REDIRECTING_REASON_UNAVAILABLE,    "unavailable",  "Callee is Unavailable" },
1202         { AST_REDIRECTING_REASON_UNCONDITIONAL,  "cfu",          "Call Forwarding Unconditional" },
1203         { AST_REDIRECTING_REASON_TIME_OF_DAY,    "time_of_day",  "Time of Day" },
1204         { AST_REDIRECTING_REASON_DO_NOT_DISTURB, "dnd",          "Do Not Disturb" },
1205         { AST_REDIRECTING_REASON_DEFLECTION,     "deflection",   "Call Deflection" },
1206         { AST_REDIRECTING_REASON_FOLLOW_ME,      "follow_me",    "Follow Me" },
1207         { AST_REDIRECTING_REASON_OUT_OF_ORDER,   "out_of_order", "Called DTE Out-Of-Order" },
1208         { AST_REDIRECTING_REASON_AWAY,           "away",         "Callee is Away" },
1209         { AST_REDIRECTING_REASON_CALL_FWD_DTE,   "cf_dte",       "Call Forwarding By The Called DTE" },
1210         { AST_REDIRECTING_REASON_SEND_TO_VM,     "send_to_vm",   "Call is being redirected to user's voicemail"},
1211 /* *INDENT-ON* */
1212 };
1213
1214 int ast_redirecting_reason_parse(const char *data)
1215 {
1216         int index;
1217
1218         for (index = 0; index < ARRAY_LEN(redirecting_reason_types); ++index) {
1219                 if (!strcasecmp(redirecting_reason_types[index].name, data)) {
1220                         return redirecting_reason_types[index].value;
1221                 }
1222         }
1223
1224         return -1;
1225 }
1226
1227 const char *ast_redirecting_reason_describe(int data)
1228 {
1229         int index;
1230
1231         for (index = 0; index < ARRAY_LEN(redirecting_reason_types); ++index) {
1232                 if (redirecting_reason_types[index].value == data) {
1233                         return redirecting_reason_types[index].description;
1234                 }
1235         }
1236
1237         return "not-known";
1238 }
1239
1240 const char *ast_redirecting_reason_name(const struct ast_party_redirecting_reason *data)
1241 {
1242         int index;
1243
1244         if (!ast_strlen_zero(data->str)) {
1245                 /* Use this string if it has been set. Otherwise, use the table. */
1246                 return data->str;
1247         }
1248
1249         for (index = 0; index < ARRAY_LEN(redirecting_reason_types); ++index) {
1250                 if (redirecting_reason_types[index].value == data->code) {
1251                         return redirecting_reason_types[index].name;
1252                 }
1253         }
1254
1255         return "not-known";
1256 }
1257
1258 /*! \brief Translation table for connected line update source settings */
1259 static const struct ast_value_translation connected_line_source_types[] = {
1260 /* *INDENT-OFF* */
1261         { AST_CONNECTED_LINE_UPDATE_SOURCE_UNKNOWN,           "unknown",           "Unknown" },
1262         { AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER,            "answer",            "Normal Call Answering" },
1263         { AST_CONNECTED_LINE_UPDATE_SOURCE_DIVERSION,         "diversion",         "Call Diversion (Deprecated, use REDIRECTING)" },
1264         { AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER,          "transfer_active",   "Call Transfer(Active)" },
1265         { AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER,          "transfer",          "Call Transfer(Active)" },/* Old name must come after new name. */
1266         { AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER_ALERTING, "transfer_alerting", "Call Transfer(Alerting)" }
1267 /* *INDENT-ON* */
1268 };
1269
1270 int ast_connected_line_source_parse(const char *data)
1271 {
1272         int index;
1273
1274         for (index = 0; index < ARRAY_LEN(connected_line_source_types); ++index) {
1275                 if (!strcasecmp(connected_line_source_types[index].name, data)) {
1276                         return connected_line_source_types[index].value;
1277                 }
1278         }
1279
1280         return -1;
1281 }
1282
1283 const char *ast_connected_line_source_describe(int data)
1284 {
1285         int index;
1286
1287         for (index = 0; index < ARRAY_LEN(connected_line_source_types); ++index) {
1288                 if (connected_line_source_types[index].value == data) {
1289                         return connected_line_source_types[index].description;
1290                 }
1291         }
1292
1293         return "not-known";
1294 }
1295
1296 const char *ast_connected_line_source_name(int data)
1297 {
1298         int index;
1299
1300         for (index = 0; index < ARRAY_LEN(connected_line_source_types); ++index) {
1301                 if (connected_line_source_types[index].value == data) {
1302                         return connected_line_source_types[index].name;
1303                 }
1304         }
1305
1306         return "not-known";
1307 }
1308
1309 /*! \brief Translation table for ast_party_name char-set settings */
1310 static const struct ast_value_translation party_name_charset_tbl[] = {
1311 /* *INDENT-OFF* */
1312         { AST_PARTY_CHAR_SET_UNKNOWN,               "unknown",      "Unknown" },
1313         { AST_PARTY_CHAR_SET_ISO8859_1,             "iso8859-1",    "ISO8859-1" },
1314         { AST_PARTY_CHAR_SET_WITHDRAWN,             "withdrawn",    "Withdrawn" },
1315         { AST_PARTY_CHAR_SET_ISO8859_2,             "iso8859-2",    "ISO8859-2" },
1316         { AST_PARTY_CHAR_SET_ISO8859_3,             "iso8859-3",    "ISO8859-3" },
1317         { AST_PARTY_CHAR_SET_ISO8859_4,             "iso8859-4",    "ISO8859-4" },
1318         { AST_PARTY_CHAR_SET_ISO8859_5,             "iso8859-5",    "ISO8859-5" },
1319         { AST_PARTY_CHAR_SET_ISO8859_7,             "iso8859-7",    "ISO8859-7" },
1320         { AST_PARTY_CHAR_SET_ISO10646_BMPSTRING,    "bmp",          "ISO10646 Bmp String" },
1321         { AST_PARTY_CHAR_SET_ISO10646_UTF_8STRING,  "utf8",         "ISO10646 UTF-8 String" },
1322 /* *INDENT-ON* */
1323 };
1324
1325 int ast_party_name_charset_parse(const char *data)
1326 {
1327         int index;
1328
1329         for (index = 0; index < ARRAY_LEN(party_name_charset_tbl); ++index) {
1330                 if (!strcasecmp(party_name_charset_tbl[index].name, data)) {
1331                         return party_name_charset_tbl[index].value;
1332                 }
1333         }
1334
1335         return -1;
1336 }
1337
1338 const char *ast_party_name_charset_describe(int data)
1339 {
1340         int index;
1341
1342         for (index = 0; index < ARRAY_LEN(party_name_charset_tbl); ++index) {
1343                 if (party_name_charset_tbl[index].value == data) {
1344                         return party_name_charset_tbl[index].description;
1345                 }
1346         }
1347
1348         return "not-known";
1349 }
1350
1351 const char *ast_party_name_charset_str(int data)
1352 {
1353         int index;
1354
1355         for (index = 0; index < ARRAY_LEN(party_name_charset_tbl); ++index) {
1356                 if (party_name_charset_tbl[index].value == data) {
1357                         return party_name_charset_tbl[index].name;
1358                 }
1359         }
1360
1361         return "not-known";
1362 }