2 * Asterisk -- An open source telephony toolkit.
4 * Copyright (C) 1999 - 2005, Digium, Inc.
6 * Mark Spencer <markster@digium.com>
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.
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.
21 * \brief CallerID Generation support
23 * \author Mark Spencer <markster@digium.com>
28 ASTERISK_FILE_VERSION(__FILE__
, "$Revision$")
38 #include "asterisk/ulaw.h"
39 #include "asterisk/alaw.h"
40 #include "asterisk/frame.h"
41 #include "asterisk/channel.h"
42 #include "asterisk/callerid.h"
43 #include "asterisk/logger.h"
44 #include "asterisk/fskmodem.h"
45 #include "asterisk/options.h"
46 #include "asterisk/utils.h"
48 struct callerid_state
{
67 float cid_dr
[4], cid_di
[4];
68 float clidsb
= 8000.0 / 1200.0;
70 float casdr1
, casdi1
, casdr2
, casdi2
;
72 #define CALLERID_SPACE 2200.0 /*!< 2200 hz for "0" */
73 #define CALLERID_MARK 1200.0 /*!< 1200 hz for "1" */
74 #define SAS_FREQ 440.0
75 #define CAS_FREQ1 2130.0
76 #define CAS_FREQ2 2750.0
78 #define AST_CALLERID_UNKNOWN "<unknown>"
80 static inline void gen_tones(unsigned char *buf
, int len
, int codec
, float ddr1
, float ddi1
, float ddr2
, float ddi2
, float *cr1
, float *ci1
, float *cr2
, float *ci2
)
85 t
= *cr1
* ddr1
- *ci1
* ddi1
;
86 *ci1
= *cr1
* ddi1
+ *ci1
* ddr1
;
88 t
= 2.0 - (*cr1
* *cr1
+ *ci1
* *ci1
);
92 t
= *cr2
* ddr2
- *ci2
* ddi2
;
93 *ci2
= *cr2
* ddi2
+ *ci2
* ddr2
;
95 t
= 2.0 - (*cr2
* *cr2
+ *ci2
* *ci2
);
98 buf
[x
] = AST_LIN2X((*cr1
+ *cr2
) * 2048.0);
102 static inline void gen_tone(unsigned char *buf
, int len
, int codec
, float ddr1
, float ddi1
, float *cr1
, float *ci1
)
106 for (x
=0;x
<len
;x
++) {
107 t
= *cr1
* ddr1
- *ci1
* ddi1
;
108 *ci1
= *cr1
* ddi1
+ *ci1
* ddr1
;
110 t
= 2.0 - (*cr1
* *cr1
+ *ci1
* *ci1
);
113 buf
[x
] = AST_LIN2X(*cr1
* 8192.0);
117 /*! \brief Initialize stuff for inverse FFT */
118 void callerid_init(void)
120 cid_dr
[0] = cos(CALLERID_SPACE
* 2.0 * M_PI
/ 8000.0);
121 cid_di
[0] = sin(CALLERID_SPACE
* 2.0 * M_PI
/ 8000.0);
122 cid_dr
[1] = cos(CALLERID_MARK
* 2.0 * M_PI
/ 8000.0);
123 cid_di
[1] = sin(CALLERID_MARK
* 2.0 * M_PI
/ 8000.0);
124 sasdr
= cos(SAS_FREQ
* 2.0 * M_PI
/ 8000.0);
125 sasdi
= sin(SAS_FREQ
* 2.0 * M_PI
/ 8000.0);
126 casdr1
= cos(CAS_FREQ1
* 2.0 * M_PI
/ 8000.0);
127 casdi1
= sin(CAS_FREQ1
* 2.0 * M_PI
/ 8000.0);
128 casdr2
= cos(CAS_FREQ2
* 2.0 * M_PI
/ 8000.0);
129 casdi2
= sin(CAS_FREQ2
* 2.0 * M_PI
/ 8000.0);
132 struct callerid_state
*callerid_new(int cid_signalling
)
134 struct callerid_state
*cid
;
136 if ((cid
= ast_calloc(1, sizeof(*cid
)))) {
137 cid
->fskd
.spb
= 7.0; /* 1200 baud */
138 /* cid->fskd.hdlc = 0; */ /* Async */
139 cid
->fskd
.nbit
= 8; /* 8 bits */
140 cid
->fskd
.nstop
= 1.0; /* 1 stop bit */
141 /* cid->fskd.paridad = 0; */ /* No parity */
142 cid
->fskd
.bw
= 1; /* Filter 800 Hz */
143 if (cid_signalling
== 2) { /* v23 signalling */
144 cid
->fskd
.f_mark_idx
= 4; /* 1300 Hz */
145 cid
->fskd
.f_space_idx
= 5; /* 2100 Hz */
146 } else { /* Bell 202 signalling as default */
147 cid
->fskd
.f_mark_idx
= 2; /* 1200 Hz */
148 cid
->fskd
.f_space_idx
= 3; /* 2200 Hz */
150 /* cid->fskd.pcola = 0; */ /* No clue */
151 /* cid->fskd.cont = 0.0; */ /* Digital PLL reset */
152 /* cid->fskd.x0 = 0.0; */
153 /* cid->fskd.state = 0; */
154 cid
->flags
= CID_UNKNOWN_NAME
| CID_UNKNOWN_NUMBER
;
161 void callerid_get(struct callerid_state
*cid
, char **name
, char **number
, int *flags
)
164 if (cid
->flags
& (CID_UNKNOWN_NAME
| CID_PRIVATE_NAME
))
168 if (cid
->flags
& (CID_UNKNOWN_NUMBER
| CID_PRIVATE_NUMBER
))
171 *number
= cid
->number
;
174 void callerid_get_dtmf(char *cidstring
, char *number
, int *flags
)
179 /* "Clear" the number-buffer. */
182 if (strlen(cidstring
) < 2) {
183 ast_log(LOG_DEBUG
, "No cid detected\n");
184 *flags
= CID_UNKNOWN_NUMBER
;
188 /* Detect protocol and special types */
189 if (cidstring
[0] == 'B') {
190 /* Handle special codes */
191 code
= atoi(&cidstring
[1]);
193 *flags
= CID_UNKNOWN_NUMBER
;
195 *flags
= CID_PRIVATE_NUMBER
;
197 ast_log(LOG_DEBUG
, "Unknown DTMF code %d\n", code
);
198 } else if (cidstring
[0] == 'D' && cidstring
[2] == '#') {
199 /* .DK special code */
200 if (cidstring
[1] == '1')
201 *flags
= CID_PRIVATE_NUMBER
;
202 if (cidstring
[1] == '2' || cidstring
[1] == '3')
203 *flags
= CID_UNKNOWN_NUMBER
;
204 } else if (cidstring
[0] == 'D' || cidstring
[0] == 'A') {
205 /* "Standard" callerid */
206 for (i
= 1; i
< strlen(cidstring
); i
++ ) {
207 if (cidstring
[i
] == 'C' || cidstring
[i
] == '#')
209 if (isdigit(cidstring
[i
]))
210 number
[i
-1] = cidstring
[i
];
212 ast_log(LOG_DEBUG
, "Unknown CID digit '%c'\n",
216 } else if (isdigit(cidstring
[0])) {
217 /* It begins with a digit, so we parse it as a number and hope
219 ast_log(LOG_WARNING
, "Couldn't detect start-character. CID "
220 "parsing might be unreliable\n");
221 for (i
= 0; i
< strlen(cidstring
); i
++) {
222 if (isdigit(cidstring
[i
]))
223 number
[i
] = cidstring
[i
];
229 ast_log(LOG_DEBUG
, "Unknown CID protocol, start digit '%c'\n",
231 *flags
= CID_UNKNOWN_NUMBER
;
235 int ast_gen_cas(unsigned char *outbuf
, int sendsas
, int len
, int codec
)
246 gen_tone(outbuf
, saslen
, codec
, sasdr
, sasdi
, &cr1
, &ci1
);
252 gen_tones(outbuf
+ pos
, len
, codec
, casdr1
, casdi1
, casdr2
, casdi2
, &cr1
, &ci1
, &cr2
, &ci2
);
256 static unsigned short calc_crc(unsigned short crc
, unsigned char data
)
258 unsigned int i
, j
, org
, dst
;
262 for (i
=0; i
< CHAR_BIT
; i
++) {
269 data
= (unsigned char)dst
;
270 crc
^= (unsigned int)data
<< (16 - CHAR_BIT
);
271 for ( j
=0; j
<CHAR_BIT
; j
++ ) {
273 crc
= (crc
<< 1) ^ 0x1021U
;
280 int callerid_feed_jp(struct callerid_state
*cid
, unsigned char *ubuf
, int len
, int codec
)
291 if (!(buf
= ast_calloc(1, 2 * len
+ cid
->oldlen
))) {
296 memcpy(buf
, cid
->oldstuff
, cid
->oldlen
);
297 mylen
+= cid
->oldlen
/2;
300 buf
[x
+cid
->oldlen
/2] = AST_XLAW(ubuf
[x
]);
302 while (mylen
>= 160) {
305 res
= fsk_serie(&cid
->fskd
, buf
, &mylen
, &b
);
308 ast_log(LOG_ERROR
, "No start bit found in fsk data.\n");
313 buf
+= (olen
- mylen
);
316 ast_log(LOG_NOTICE
, "fsk_serie failed\n");
326 /* crc checksum calculation */
327 if ( cid
->sawflag
> 1 ) {
328 cid
->crc
= calc_crc(cid
->crc
, (unsigned char)b2
);
331 /* Ignore invalid bytes */
336 /* skip DLE if needed */
337 if ( cid
->sawflag
> 0 ) {
338 if ( cid
->sawflag
!= 5 && cid
->skipflag
== 0 && b
== 0x10 ) {
343 if ( cid
->skipflag
== 1 ) {
347 /* caller id retrieval */
348 switch(cid
->sawflag
) {
371 case 4: /* SERVICE TYPE */
376 case 5: /* Frame Length */
379 case 6: /* NUMBER TYPE */
382 cid
->rawdata
[cid
->pos
++] = b
;
384 case 7: /* NUMBER LENGTH */
387 if ( (cid
->len
+2) >= sizeof( cid
->rawdata
) ) {
388 ast_log(LOG_WARNING
, "too long caller id string\n" ) ;
392 cid
->rawdata
[cid
->pos
++] = b
;
394 case 8: /* Retrieve message */
395 cid
->rawdata
[cid
->pos
++] = b
;
398 cid
->rawdata
[cid
->pos
] = '\0';
405 case 10: /* CRC Checksum 1 */
408 case 11: /* CRC Checksum 2 */
410 if ( cid
->crc
!= 0 ) {
411 ast_log(LOG_WARNING
, "crc checksum error\n" ) ;
415 /* extract caller id data */
416 for (x
=0; x
<cid
->pos
; ) {
417 switch (cid
->rawdata
[x
++]) {
418 case 0x02: /* caller id number */
419 cid
->number
[0] = '\0';
422 res
= cid
->rawdata
[x
++];
423 ast_copy_string(cid
->number
, &cid
->rawdata
[x
], res
+1 );
426 case 0x21: /* additional information */
430 switch (cid
->rawdata
[x
]) {
431 case 0x00: /* unknown */
432 case 0x01: /* international number */
433 case 0x02: /* domestic number */
434 case 0x03: /* network */
435 case 0x04: /* local call */
436 case 0x06: /* short dial number */
437 case 0x07: /* reserved */
438 default: /* reserved */
439 if (option_debug
> 1)
440 ast_log(LOG_DEBUG
, "cid info:#1=%X\n", cid
->rawdata
[x
]);
444 /* numbering plan octed 4 */
446 /* numbering plan octed 5 */
447 switch (cid
->rawdata
[x
]) {
448 case 0x00: /* unknown */
449 case 0x01: /* recommendation E.164 ISDN */
450 case 0x03: /* recommendation X.121 */
451 case 0x04: /* telex dial plan */
452 case 0x08: /* domestic dial plan */
453 case 0x09: /* private dial plan */
454 case 0x05: /* reserved */
455 default: /* reserved */
456 if (option_debug
> 1)
457 ast_log(LOG_DEBUG
, "cid info:#2=%X\n", cid
->rawdata
[x
]);
462 case 0x04: /* no callerid reason */
465 /* no callerid reason code */
466 switch (cid
->rawdata
[x
]) {
467 case 'P': /* caller id denied by user */
468 case 'O': /* service not available */
469 case 'C': /* pay phone */
470 case 'S': /* service congested */
471 cid
->flags
|= CID_UNKNOWN_NUMBER
;
472 if (option_debug
> 1)
473 ast_log(LOG_DEBUG
, "no cid reason:%c\n",cid
->rawdata
[x
]);
478 case 0x09: /* dialed number */
480 res
= cid
->rawdata
[x
++];
484 case 0x22: /* dialed number additional information */
488 switch (cid
->rawdata
[x
]) {
489 case 0x00: /* unknown */
490 case 0x01: /* international number */
491 case 0x02: /* domestic number */
492 case 0x03: /* network */
493 case 0x04: /* local call */
494 case 0x06: /* short dial number */
495 case 0x07: /* reserved */
496 default: /* reserved */
497 if (option_debug
> 1)
498 ast_log(LOG_NOTICE
, "did info:#1=%X\n", cid
->rawdata
[x
]);
502 /* numbering plan octed 4 */
504 /* numbering plan octed 5 */
505 switch (cid
->rawdata
[x
]) {
506 case 0x00: /* unknown */
507 case 0x01: /* recommendation E.164 ISDN */
508 case 0x03: /* recommendation X.121 */
509 case 0x04: /* telex dial plan */
510 case 0x08: /* domestic dial plan */
511 case 0x09: /* private dial plan */
512 case 0x05: /* reserved */
513 default: /* reserved */
514 if (option_debug
> 1)
515 ast_log(LOG_DEBUG
, "did info:#2=%X\n", cid
->rawdata
[x
]);
526 ast_log(LOG_ERROR
, "invalid value in sawflag %d\n", cid
->sawflag
);
531 memcpy(cid
->oldstuff
, buf
, mylen
* 2);
532 cid
->oldlen
= mylen
* 2;
540 int callerid_feed(struct callerid_state
*cid
, unsigned char *ubuf
, int len
, int codec
)
550 if (!(buf
= ast_calloc(1, 2 * len
+ cid
->oldlen
))) {
555 memcpy(buf
, cid
->oldstuff
, cid
->oldlen
);
556 mylen
+= cid
->oldlen
/2;
559 buf
[x
+cid
->oldlen
/2] = AST_XLAW(ubuf
[x
]);
560 while(mylen
>= 160) {
562 res
= fsk_serie(&cid
->fskd
, buf
, &mylen
, &b
);
564 ast_log(LOG_ERROR
, "No start bit found in fsk data.\n");
568 buf
+= (olen
- mylen
);
570 ast_log(LOG_NOTICE
, "fsk_serie failed\n");
575 /* Ignore invalid bytes */
578 switch(cid
->sawflag
) {
579 case 0: /* Look for flag */
583 case 2: /* Get lead-in */
584 if ((b
== 0x04) || (b
== 0x80)) {
590 case 3: /* Get length */
591 /* Not a lead in. We're ready */
597 case 4: /* Retrieve message */
598 if (cid
->pos
>= 128) {
599 ast_log(LOG_WARNING
, "Caller ID too long???\n");
603 cid
->rawdata
[cid
->pos
++] = b
;
607 cid
->rawdata
[cid
->pos
] = '\0';
611 case 5: /* Check checksum */
612 if (b
!= (256 - (cid
->cksum
& 0xff))) {
613 ast_log(LOG_NOTICE
, "Caller*ID failed checksum\n");
619 cid
->number
[0] = '\0';
621 /* If we get this far we're fine. */
622 if (cid
->type
== 0x80) {
624 /* Go through each element and process */
625 for (x
=0;x
< cid
->pos
;) {
626 switch(cid
->rawdata
[x
++]) {
631 case 3: /* Number (for Zebble) */
633 res
= cid
->rawdata
[x
];
635 ast_log(LOG_NOTICE
, "Truncating long caller ID number from %d bytes to 32\n", cid
->rawdata
[x
]);
638 if (ast_strlen_zero(cid
->number
)) {
639 memcpy(cid
->number
, cid
->rawdata
+ x
+ 1, res
);
641 cid
->number
[res
] = '\0';
644 case 6: /* Stentor Call Qualifier (ie. Long Distance call) */
648 res
= cid
->rawdata
[x
];
650 ast_log(LOG_NOTICE
, "Truncating long caller ID name from %d bytes to 32\n", cid
->rawdata
[x
]);
653 memcpy(cid
->name
, cid
->rawdata
+ x
+ 1, res
);
654 cid
->name
[res
] = '\0';
656 case 17: /* UK: Call type, 1=Voice Call, 2=Ringback when free, 129=Message waiting */
657 case 19: /* UK: Network message system status (Number of messages waiting) */
658 case 22: /* Something French */
661 ast_log(LOG_NOTICE
, "Unknown IE %d\n", cid
->rawdata
[x
-1]);
663 res
= cid
->rawdata
[x
];
664 if (0 > res
){ /* Negative offset in the CID Spill */
665 ast_log(LOG_NOTICE
, "IE %d has bad field length of %d at offset %d\n", cid
->rawdata
[x
-1], cid
->rawdata
[x
], x
);
668 break; /* Exit the loop */
670 x
+= cid
->rawdata
[x
];
675 ast_copy_string(cid
->number
, cid
->rawdata
+ 8, sizeof(cid
->number
));
679 if (!strcmp(cid
->number
, "P")) {
680 strcpy(cid
->number
, "");
681 cid
->flags
|= CID_PRIVATE_NUMBER
;
682 } else if (!strcmp(cid
->number
, "O") || ast_strlen_zero(cid
->number
)) {
683 strcpy(cid
->number
, "");
684 cid
->flags
|= CID_UNKNOWN_NUMBER
;
686 if (!strcmp(cid
->name
, "P")) {
687 strcpy(cid
->name
, "");
688 cid
->flags
|= CID_PRIVATE_NAME
;
689 } else if (!strcmp(cid
->name
, "O") || ast_strlen_zero(cid
->name
)) {
690 strcpy(cid
->name
, "");
691 cid
->flags
|= CID_UNKNOWN_NAME
;
697 ast_log(LOG_ERROR
, "Dunno what to do with a digit in sawflag %d\n", cid
->sawflag
);
702 memcpy(cid
->oldstuff
, buf
, mylen
* 2);
703 cid
->oldlen
= mylen
* 2;
710 void callerid_free(struct callerid_state
*cid
)
715 static int callerid_genmsg(char *msg
, int size
, const char *number
, const char *name
, int flags
)
724 ast_localtime(&t
, &tm
, NULL
);
728 /* Format time and message header */
729 res
= snprintf(ptr
, size
, "\001\010%02d%02d%02d%02d", tm
.tm_mon
+ 1,
730 tm
.tm_mday
, tm
.tm_hour
, tm
.tm_min
);
733 if (ast_strlen_zero(number
) || (flags
& CID_UNKNOWN_NUMBER
)) {
734 /* Indicate number not known */
735 res
= snprintf(ptr
, size
, "\004\001O");
738 } else if (flags
& CID_PRIVATE_NUMBER
) {
739 /* Indicate number is private */
740 res
= snprintf(ptr
, size
, "\004\001P");
744 /* Send up to 16 digits of number MAX */
747 res
= snprintf(ptr
, size
, "\002%c", i
);
750 for (x
= 0; x
< i
; x
++)
757 if (ast_strlen_zero(name
) || (flags
& CID_UNKNOWN_NAME
)) {
758 /* Indicate name not known */
759 res
= snprintf(ptr
, size
, "\010\001O");
762 } else if (flags
& CID_PRIVATE_NAME
) {
763 /* Indicate name is private */
764 res
= snprintf(ptr
, size
, "\010\001P");
768 /* Send up to 16 digits of name MAX */
771 res
= snprintf(ptr
, size
, "\007%c", i
);
784 int vmwi_generate(unsigned char *buf
, int active
, int mdmf
, int codec
)
786 unsigned char msg
[256];
795 /* MDMF Message waiting */
799 /* IE is "Message Waiting Parameter" */
801 /* Length of IE is one */
809 /* SDMF Message waiting */
824 for (x
=0; x
<len
; x
++)
826 sum
= (256 - (sum
& 255));
828 /* Wait a half a second */
829 for (x
=0; x
<4000; x
++)
831 /* Transmit 30 0x55's (looks like a square wave) for channel seizure */
834 /* Send 170ms of callerid marks */
835 for (x
=0; x
<170; x
++)
837 for (x
=0; x
<len
; x
++) {
840 /* Send 50 more ms of marks */
846 int callerid_generate(unsigned char *buf
, const char *number
, const char *name
, int flags
, int callwaiting
, int codec
)
852 /* Initial carriers (real/imaginary) */
857 len
= callerid_genmsg(msg
, sizeof(msg
), number
, name
, flags
);
859 /* Wait a half a second */
860 for (x
=0; x
<4000; x
++)
862 /* Transmit 30 0x55's (looks like a square wave) for channel seizure */
866 /* Send 150ms of callerid marks */
867 for (x
=0; x
<150; x
++)
869 /* Send 0x80 indicating MDMF format */
871 /* Put length of whole message */
873 sum
= 0x80 + strlen(msg
);
874 /* Put each character of message and update checksum */
875 for (x
=0; x
<len
; x
++) {
879 /* Send 2's compliment of sum */
880 PUT_CLID(256 - (sum
& 255));
882 /* Send 50 more ms of marks */
889 /*! \brief Clean up phone string
890 * remove '(', ' ', ')', non-trailing '.', and '-' not in square brackets.
891 * Basically, remove anything that could be invalid in a pattern.
893 void ast_shrink_phone_number(char *n
)
898 for (x
=0; n
[x
]; x
++) {
917 if (!strchr("( )", n
[x
]))
924 /*! \brief Checks if phone number consists of valid characters
925 \param exten String that needs to be checked
926 \param valid Valid characters in string
927 \return 1 if valid string, 0 if string contains invalid characters
929 static int ast_is_valid_string(const char *exten
, const char *valid
)
933 if (ast_strlen_zero(exten
))
935 for (x
=0; exten
[x
]; x
++)
936 if (!strchr(valid
, exten
[x
]))
941 /*! \brief checks if string consists only of digits and * \# and +
942 \return 1 if string is valid AST phone number
945 int ast_isphonenumber(const char *n
)
947 return ast_is_valid_string(n
, "0123456789*#+");
950 /*! \brief checks if string consists only of digits and ( ) - * \# and +
951 Pre-qualifies the string for ast_shrink_phone_number()
952 \return 1 if string is valid AST shrinkable phone number
955 int ast_is_shrinkable_phonenumber(const char *exten
)
957 return ast_is_valid_string(exten
, "0123456789*#+()-.");
961 * \brief Destructively parse instr for caller id information
962 * \return always returns 0, as the code always returns something.
963 * \note XXX 'name' is not parsed consistently e.g. we have
964 * input location name
965 * " foo bar " <123> 123 ' foo bar ' (with spaces around)
966 * " foo bar " NULL 'foo bar' (without spaces around)
967 * " foo bar <123>" 123 '" foo bar'
968 * The parsing of leading and trailing space/quotes should be more consistent.
970 int ast_callerid_parse(char *instr
, char **name
, char **location
)
972 char *ns
, *ne
, *ls
, *le
;
974 /* Try "name" <location> format or name <location> format */
975 if ((ls
= strchr(instr
, '<')) && (le
= strchr(ls
, '>'))) {
976 *ls
= *le
= '\0'; /* location found, trim off the brackets */
977 *location
= ls
+ 1; /* and this is the result */
978 if ((ns
= strchr(instr
, '"')) && (ne
= strchr(ns
+ 1, '"'))) {
979 *ns
= *ne
= '\0'; /* trim off the quotes */
980 *name
= ns
+ 1; /* and this is the name */
981 } else { /* no quotes, trim off leading and trailing spaces */
982 *name
= ast_skip_blanks(instr
);
983 ast_trim_blanks(*name
);
985 } else { /* no valid brackets */
988 ast_copy_string(tmp
, instr
, sizeof(tmp
));
989 ast_shrink_phone_number(tmp
);
990 if (ast_isphonenumber(tmp
)) { /* Assume it's just a location */
992 strcpy(instr
, tmp
); /* safe, because tmp will always be the same size or smaller than instr */
994 } else { /* Assume it's just a name. */
996 if ((ns
= strchr(instr
, '"')) && (ne
= strchr(ns
+ 1, '"'))) {
997 *ns
= *ne
= '\0'; /* trim off the quotes */
998 *name
= ns
+ 1; /* and this is the name */
999 } else { /* no quotes, trim off leading and trailing spaces */
1000 *name
= ast_skip_blanks(instr
);
1001 ast_trim_blanks(*name
);
1008 static int __ast_callerid_generate(unsigned char *buf
, const char *name
, const char *number
, int callwaiting
, int codec
)
1010 if (ast_strlen_zero(name
))
1012 if (ast_strlen_zero(number
))
1014 return callerid_generate(buf
, number
, name
, 0, callwaiting
, codec
);
1017 int ast_callerid_generate(unsigned char *buf
, const char *name
, const char *number
, int codec
)
1019 return __ast_callerid_generate(buf
, name
, number
, 0, codec
);
1022 int ast_callerid_callwaiting_generate(unsigned char *buf
, const char *name
, const char *number
, int codec
)
1024 return __ast_callerid_generate(buf
, name
, number
, 1, codec
);
1027 char *ast_callerid_merge(char *buf
, int bufsiz
, const char *name
, const char *num
, const char *unknown
)
1030 unknown
= "<unknown>";
1032 snprintf(buf
, bufsiz
, "\"%s\" <%s>", name
, num
);
1034 ast_copy_string(buf
, name
, bufsiz
);
1036 ast_copy_string(buf
, num
, bufsiz
);
1038 ast_copy_string(buf
, unknown
, bufsiz
);
1042 int ast_callerid_split(const char *buf
, char *name
, int namelen
, char *num
, int numlen
)
1045 char *l
= NULL
, *n
= NULL
;
1047 tmp
= ast_strdupa(buf
);
1048 ast_callerid_parse(tmp
, &n
, &l
);
1050 ast_copy_string(name
, n
, namelen
);
1054 ast_shrink_phone_number(l
);
1055 ast_copy_string(num
, l
, numlen
);
1061 /*! \brief Translation table for Caller ID Presentation settings */
1067 { AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED
, "allowed_not_screened", "Presentation Allowed, Not Screened"},
1068 { AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN
, "allowed_passed_screen", "Presentation Allowed, Passed Screen"},
1069 { AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN
, "allowed_failed_screen", "Presentation Allowed, Failed Screen"},
1070 { AST_PRES_ALLOWED_NETWORK_NUMBER
, "allowed", "Presentation Allowed, Network Number"},
1071 { AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED
, "prohib_not_screened", "Presentation Prohibited, Not Screened"},
1072 { AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN
, "prohib_passed_screen", "Presentation Prohibited, Passed Screen"},
1073 { AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN
, "prohib_failed_screen", "Presentation Prohibited, Failed Screen"},
1074 { AST_PRES_PROHIB_NETWORK_NUMBER
, "prohib", "Presentation Prohibited, Network Number"},
1075 { AST_PRES_NUMBER_NOT_AVAILABLE
, "unavailable", "Number Unavailable"},
1078 /*! \brief Convert caller ID text code to value
1079 used in config file parsing
1080 \param data text string
1081 \return value AST_PRES_ from callerid.h
1083 int ast_parse_caller_presentation(const char *data
)
1087 for (i
= 0; i
< ((sizeof(pres_types
) / sizeof(pres_types
[0]))); i
++) {
1088 if (!strcasecmp(pres_types
[i
].name
, data
))
1089 return pres_types
[i
].val
;
1095 /*! \brief Convert caller ID pres value to explanatory string
1096 \param data value (see callerid.h AST_PRES_ )
1097 \return string for human presentation
1099 const char *ast_describe_caller_presentation(int data
)
1103 for (i
= 0; i
< ((sizeof(pres_types
) / sizeof(pres_types
[0]))); i
++) {
1104 if (pres_types
[i
].val
== data
)
1105 return pres_types
[i
].description
;