![]() |
Home page |
Mailing list |
Docs
Asterisk developer's documentation :: Codename Pineapple
callerid.c File Reference
Definition in file callerid.c.
#include "asterisk.h"
#include <time.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <math.h>
#include <ctype.h>
#include "asterisk/ulaw.h"
#include "asterisk/alaw.h"
#include "asterisk/frame.h"
#include "asterisk/channel.h"
#include "asterisk/callerid.h"
#include "asterisk/logger.h"
#include "asterisk/fskmodem.h"
#include "asterisk/options.h"
#include "asterisk/utils.h"
Include dependency graph for callerid.c:

Go to the source code of this file.
Data Structures | |
| struct | callerid_state |
Defines | |
| #define | AST_CALLERID_UNKNOWN "<unknown>" |
| #define | CALLERID_MARK 1200.0 |
| #define | CALLERID_SPACE 2200.0 |
| #define | CAS_FREQ1 2130.0 |
| #define | CAS_FREQ2 2750.0 |
| #define | SAS_FREQ 440.0 |
Functions | |
| static int | __ast_callerid_generate (unsigned char *buf, const char *name, const char *number, int callwaiting, int codec) |
| int | ast_callerid_callwaiting_generate (unsigned char *buf, const char *name, const char *number, int codec) |
| Generate Caller-ID spill but in a format suitable for Call Waiting(tm)'s Caller*ID(tm) See ast_callerid_generate() for other details. | |
| int | ast_callerid_generate (unsigned char *buf, const char *name, const char *number, int codec) |
| Generate Caller-ID spill from the "callerid" field of asterisk (in e-mail address like format). | |
| char * | ast_callerid_merge (char *buf, int bufsiz, const char *name, const char *num, const char *unknown) |
| int | ast_callerid_parse (char *instr, char **name, char **location) |
| Destructively parse inbuf into name and location (or number) Parses callerid stream from inbuf and changes into useable form, outputed in name and location. | |
| int | ast_callerid_split (const char *buf, char *name, int namelen, char *num, int numlen) |
| const char * | ast_describe_caller_presentation (int data) |
| Convert caller ID pres value to explanatory string. | |
| int | ast_gen_cas (unsigned char *outbuf, int sendsas, int len, int codec) |
| int | ast_is_shrinkable_phonenumber (const char *exten) |
| Check if a string consists only of digits and and + # ( ) - . (meaning it can be cleaned with ast_shrink_phone_number). | |
| static int | ast_is_valid_string (const char *exten, const char *valid) |
| Checks if phone number consists of valid characters. | |
| int | ast_isphonenumber (const char *n) |
| Check if a string consists only of digits and + #. | |
| const char * | ast_named_caller_presentation (int data) |
| Convert caller ID pres value to text code. | |
| int | ast_parse_caller_presentation (const char *data) |
| Convert caller ID text code to value used in config file parsing. | |
| void | ast_shrink_phone_number (char *n) |
| Shrink a phone number in place to just digits (more accurately it just removes ()'s, .'s, and -'s... | |
| static unsigned short | calc_crc (unsigned short crc, unsigned char data) |
| int | callerid_feed (struct callerid_state *cid, unsigned char *ubuf, int len, int codec) |
| Read samples into the state machine. | |
| int | callerid_feed_jp (struct callerid_state *cid, unsigned char *ubuf, int len, int codec) |
| Read samples into the state machine. | |
| void | callerid_free (struct callerid_state *cid) |
| Free a callerID state. | |
| int | callerid_generate (unsigned char *buf, const char *number, const char *name, int flags, int callwaiting, int codec) |
| Generates a CallerID FSK stream in ulaw format suitable for transmission. | |
| static int | callerid_genmsg (char *msg, int size, const char *number, const char *name, int flags) |
| void | callerid_get (struct callerid_state *cid, char **name, char **number, int *flags) |
| Extract info out of callerID state machine. Flags are listed above. | |
| void | callerid_get_dtmf (char *cidstring, char *number, int *flags) |
| void | callerid_init (void) |
| CallerID Initialization. | |
| callerid_state * | callerid_new (int cid_signalling) |
| Create a callerID state machine. | |
| static void | gen_tone (unsigned char *buf, int len, int codec, float ddr1, float ddi1, float *cr1, float *ci1) |
| static 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) |
| int | vmwi_generate (unsigned char *buf, int active, int mdmf, int codec) |
| Generate message waiting indicator (stutter tone). | |
Variables | |
| float | casdi1 |
| float | casdi2 |
| float | casdr1 |
| float | casdr2 |
| float | cid_di [4] |
| float | cid_dr [4] |
| float | clidsb = 8000.0 / 1200.0 |
| struct { | |
| int alarm | |
| const char * description | |
| unsigned int event_log:1 | |
| char * ext | |
| char * mtype | |
| char * name | |
| const char * name | |
| rtpPayloadType payloadType | |
| unsigned int queue_log:1 | |
| char * subtype | |
| char * type | |
| int val | |
| } | pres_types [] |
| Translation table for Caller ID Presentation settings. | |
| float | sasdi |
| float | sasdr |
|
|
Definition at line 78 of file callerid.c. |
|
|
1200 hz for "1" Definition at line 73 of file callerid.c. Referenced by callerid_init(). |
|
|
2200 hz for "0" Definition at line 72 of file callerid.c. Referenced by callerid_init(). |
|
|
Definition at line 75 of file callerid.c. Referenced by callerid_init(). |
|
|
Definition at line 76 of file callerid.c. Referenced by callerid_init(). |
|
|
Definition at line 74 of file callerid.c. Referenced by callerid_init(). |
|
||||||||||||||||||||||||
|
Definition at line 980 of file callerid.c. References ast_strlen_zero(), and callerid_generate(). Referenced by ast_callerid_callwaiting_generate(), and ast_callerid_generate(). 00981 { 00982 if (ast_strlen_zero(name)) 00983 name = NULL; 00984 if (ast_strlen_zero(number)) 00985 number = NULL; 00986 return callerid_generate(buf, number, name, 0, callwaiting, codec); 00987 }
|
|
||||||||||||||||||||
|
Generate Caller-ID spill but in a format suitable for Call Waiting(tm)'s Caller*ID(tm) See ast_callerid_generate() for other details.
Definition at line 994 of file callerid.c. References __ast_callerid_generate(). Referenced by send_cwcidspill(). 00995 { 00996 return __ast_callerid_generate(buf, name, number, 1, codec); 00997 }
|
|
||||||||||||||||||||
|
Generate Caller-ID spill from the "callerid" field of asterisk (in e-mail address like format).
Definition at line 989 of file callerid.c. References __ast_callerid_generate(). Referenced by zt_call(). 00990 { 00991 return __ast_callerid_generate(buf, name, number, 0, codec); 00992 }
|
|
||||||||||||||||||||||||
|
Definition at line 999 of file callerid.c. Referenced by _sip_show_device(), _sip_show_peer(), iax2_show_peer(), and sip_show_user(). 01000 { 01001 if (!unknown) 01002 unknown = "<unknown>"; 01003 if (name && num) 01004 snprintf(buf, bufsiz, "\"%s\" <%s>", name, num); 01005 else if (name) 01006 ast_copy_string(buf, name, bufsiz); 01007 else if (num) 01008 ast_copy_string(buf, num, bufsiz); 01009 else 01010 ast_copy_string(buf, unknown, bufsiz); 01011 return buf; 01012 }
|
|
||||||||||||||||
|
Destructively parse inbuf into name and location (or number) Parses callerid stream from inbuf and changes into useable form, outputed in name and location.
Definition at line 942 of file callerid.c. References ast_isphonenumber(), and ast_shrink_phone_number(). Referenced by action_originate(), ast_callerid_split(), ast_privacy_check(), ast_privacy_set(), and handle_setcallerid(). 00943 { 00944 char *ns, *ne, *ls, *le; 00945 00946 /* Try "name" <location> format or name <location> format */ 00947 if ((ls = strchr(instr, '<')) && (le = strchr(ls, '>'))) { 00948 *ls = *le = '\0'; /* location found, trim off the brackets */ 00949 *location = ls + 1; /* and this is the result */ 00950 if ((ns = strchr(instr, '"')) && (ne = strchr(ns + 1, '"'))) { 00951 *ns = *ne = '\0'; /* trim off the quotes */ 00952 *name = ns + 1; /* and this is the name */ 00953 } else { /* no quotes, trim off leading and trailing spaces */ 00954 *name = ast_skip_blanks(instr); 00955 ast_trim_blanks(*name); 00956 } 00957 } else { /* no valid brackets */ 00958 char tmp[256]; 00959 00960 ast_copy_string(tmp, instr, sizeof(tmp)); 00961 ast_shrink_phone_number(tmp); 00962 if (ast_isphonenumber(tmp)) { /* Assume it's just a location */ 00963 *name = NULL; 00964 strcpy(instr, tmp); /* safe, because tmp will always be the same size or smaller than instr */ 00965 *location = instr; 00966 } else { /* Assume it's just a name. */ 00967 *location = NULL; 00968 if ((ns = strchr(instr, '"')) && (ne = strchr(ns + 1, '"'))) { 00969 *ns = *ne = '\0'; /* trim off the quotes */ 00970 *name = ns + 1; /* and this is the name */ 00971 } else { /* no quotes, trim off leading and trailing spaces */ 00972 *name = ast_skip_blanks(instr); 00973 ast_trim_blanks(*name); 00974 } 00975 } 00976 } 00977 return 0; 00978 }
|
|
||||||||||||||||||||||||
|
Definition at line 1014 of file callerid.c. References ast_callerid_parse(), ast_shrink_phone_number(), and ast_strdupa. Referenced by apply_outgoing(), build_device(), build_gateway(), build_peer(), build_user(), load_module(), set_device_cid(), store_callerid(), and update_common_options(). 01015 { 01016 char *tmp; 01017 char *l = NULL, *n = NULL; 01018 01019 tmp = ast_strdupa(buf); 01020 ast_callerid_parse(tmp, &n, &l); 01021 if (n) 01022 ast_copy_string(name, n, namelen); 01023 else 01024 name[0] = '\0'; 01025 if (l) { 01026 ast_shrink_phone_number(l); 01027 ast_copy_string(num, l, numlen); 01028 } else 01029 num[0] = '\0'; 01030 return 0; 01031 }
|
|
|
Convert caller ID pres value to explanatory string.
Definition at line 1071 of file callerid.c. References pres_types. Referenced by _sip_show_device(), _sip_show_peer(), ast_set_callerid(), and sip_show_user(). 01072 { 01073 int i; 01074 01075 for (i = 0; i < ((sizeof(pres_types) / sizeof(pres_types[0]))); i++) { 01076 if (pres_types[i].val == data) 01077 return pres_types[i].description; 01078 } 01079 01080 return "unknown"; 01081 }
|
|
||||||||||||||||||||
|
Definition at line 235 of file callerid.c. References casdi1, casdi2, casdr1, casdr2, gen_tone(), gen_tones(), callerid_state::pos, sasdi, and sasdr. Referenced by __adsi_transmit_messages(), and zt_callwait(). 00236 { 00237 int pos = 0; 00238 int saslen = 2400; 00239 float cr1 = 1.0; 00240 float ci1 = 0.0; 00241 float cr2 = 1.0; 00242 float ci2 = 0.0; 00243 00244 if (sendsas) { 00245 if (len < saslen) 00246 return -1; 00247 gen_tone(outbuf, saslen, codec, sasdr, sasdi, &cr1, &ci1); 00248 len -= saslen; 00249 pos += saslen; 00250 cr2 = cr1; 00251 ci2 = ci1; 00252 } 00253 gen_tones(outbuf + pos, len, codec, casdr1, casdi1, casdr2, casdi2, &cr1, &ci1, &cr2, &ci2); 00254 return 0; 00255 }
|
|
|
Check if a string consists only of digits and and + # ( ) - . (meaning it can be cleaned with ast_shrink_phone_number).
Definition at line 927 of file callerid.c. References ast_is_valid_string(). Referenced by check_peer_ok(), check_user_full(), check_user_ok(), and replace_cid(). 00928 { 00929 return ast_is_valid_string(exten, "0123456789*#+()-."); 00930 }
|
|
||||||||||||
|
Checks if phone number consists of valid characters.
Definition at line 901 of file callerid.c. References ast_strlen_zero(). Referenced by ast_is_shrinkable_phonenumber(), and ast_isphonenumber(). 00902 { 00903 int x; 00904 00905 if (ast_strlen_zero(exten)) 00906 return 0; 00907 for (x = 0; exten[x]; x++) 00908 if (!strchr(valid, exten[x])) 00909 return 0; 00910 return 1; 00911 }
|
|
|
Check if a string consists only of digits and + #.
Definition at line 917 of file callerid.c. References ast_is_valid_string(). Referenced by ast_callerid_parse(). 00918 { 00919 return ast_is_valid_string(n, "0123456789*#+"); 00920 }
|
|
|
Convert caller ID pres value to text code.
Definition at line 1087 of file callerid.c. References pres_types. 01088 { 01089 int i; 01090 01091 for (i = 0; i < ((sizeof(pres_types) / sizeof(pres_types[0]))); i++) { 01092 if (pres_types[i].val == data) 01093 return pres_types[i].name; 01094 } 01095 01096 return "unknown"; 01097 }
|
|
|
Convert caller ID text code to value used in config file parsing.
Definition at line 1055 of file callerid.c. References name, and pres_types. Referenced by build_device(), and build_peer(). 01056 { 01057 int i; 01058 01059 for (i = 0; i < ((sizeof(pres_types) / sizeof(pres_types[0]))); i++) { 01060 if (!strcasecmp(pres_types[i].name, data)) 01061 return pres_types[i].val; 01062 } 01063 01064 return -1; 01065 }
|
|
|
Shrink a phone number in place to just digits (more accurately it just removes ()'s, .'s, and -'s...
Definition at line 865 of file callerid.c. Referenced by action_originate(), ast_callerid_parse(), ast_callerid_split(), ast_privacy_check(), ast_privacy_set(), check_access(), check_peer_ok(), check_user_full(), check_user_ok(), handle_setcallerid(), and replace_cid(). 00866 { 00867 int x, y=0; 00868 int bracketed = 0; 00869 00870 for (x = 0; n[x]; x++) { 00871 switch (n[x]) { 00872 case '[': 00873 bracketed++; 00874 n[y++] = n[x]; 00875 break; 00876 case ']': 00877 bracketed--; 00878 n[y++] = n[x]; 00879 break; 00880 case '-': 00881 if (bracketed) 00882 n[y++] = n[x]; 00883 break; 00884 case '.': 00885 if (!n[x+1]) 00886 n[y++] = n[x]; 00887 break; 00888 default: 00889 if (!strchr("()", n[x])) 00890 n[y++] = n[x]; 00891 } 00892 } 00893 n[y] = '\0'; 00894 }
|
|
||||||||||||
|
Definition at line 257 of file callerid.c. References org. Referenced by callerid_feed_jp(). 00258 { 00259 unsigned int i, j, org, dst; 00260 org = data; 00261 dst = 0; 00262 00263 for (i = 0; i < CHAR_BIT; i++) { 00264 org <<= 1; 00265 dst >>= 1; 00266 if (org & 0x100) 00267 dst |= 0x80; 00268 } 00269 data = (unsigned char) dst; 00270 crc ^= (unsigned int) data << (16 - CHAR_BIT); 00271 for (j = 0; j < CHAR_BIT; j++) { 00272 if (crc & 0x8000U) 00273 crc = (crc << 1) ^ 0x1021U ; 00274 else 00275 crc <<= 1 ; 00276 } 00277 return crc; 00278 }
|
|
||||||||||||||||||||
|
Read samples into the state machine.
Definition at line 523 of file callerid.c. References ast_log(), ast_strlen_zero(), AST_XLAW, callerid_state::cksum, fsk_serial(), callerid_state::fskd, callerid_state::len, LOG_ERROR, LOG_NOTICE, LOG_WARNING, callerid_state::name, callerid_state::number, callerid_state::oldlen, callerid_state::oldstuff, callerid_state::pos, callerid_state::rawdata, callerid_state::sawflag, and callerid_state::type. Referenced by ss_thread(). 00524 { 00525 int mylen = len; 00526 int olen; 00527 int b = 'X'; 00528 int res; 00529 int x; 00530 short *buf; 00531 00532 buf = alloca(2 * len + cid->oldlen); 00533 00534 memcpy(buf, cid->oldstuff, cid->oldlen); 00535 mylen += cid->oldlen/2; 00536 00537 for (x = 0; x < len; x++) 00538 buf[x+cid->oldlen/2] = AST_XLAW(ubuf[x]); 00539 while (mylen >= 160) { 00540 olen = mylen; 00541 res = fsk_serial(&cid->fskd, buf, &mylen, &b); 00542 if (mylen < 0) { 00543 ast_log(LOG_ERROR, "fsk_serial made mylen < 0 (%d)\n", mylen); 00544 return -1; 00545 } 00546 buf += (olen - mylen); 00547 if (res < 0) { 00548 ast_log(LOG_NOTICE, "fsk_serial failed\n"); 00549 return -1; 00550 } 00551 if (res == 1) { 00552 /* Ignore invalid bytes */ 00553 if (b > 0xff) 00554 continue; 00555 switch (cid->sawflag) { 00556 case 0: /* Look for flag */ 00557 if (b == 'U') 00558 cid->sawflag = 2; 00559 break; 00560 case 2: /* Get lead-in */ 00561 if ((b == 0x04) || (b == 0x80)) { 00562 cid->type = b; 00563 cid->sawflag = 3; 00564 cid->cksum = b; 00565 } 00566 break; 00567 case 3: /* Get length */ 00568 /* Not a lead in. We're ready */ 00569 cid->sawflag = 4; 00570 cid->len = b; 00571 cid->pos = 0; 00572 cid->cksum += b; 00573 break; 00574 case 4: /* Retrieve message */ 00575 if (cid->pos >= 128) { 00576 ast_log(LOG_WARNING, "Caller ID too long???\n"); 00577 return -1; 00578 } 00579 cid->rawdata[cid->pos++] = b; 00580 cid->len--; 00581 cid->cksum += b; 00582 if (!cid->len) { 00583 cid->rawdata[cid->pos] = '\0'; 00584 cid->sawflag = 5; 00585 } 00586 break; 00587 case 5: /* Check checksum */ 00588 if (b != (256 - (cid->cksum & 0xff))) { 00589 ast_log(LOG_NOTICE, "Caller*ID failed checksum\n"); 00590 /* Try again */ 00591 cid->sawflag = 0; 00592 break; 00593 } 00594 00595 cid->number[0] = '\0'; 00596 cid->name[0] = '\0'; 00597 /* If we get this far we're fine. */ 00598 if (cid->type == 0x80) { 00599 /* MDMF */ 00600 /* Go through each element and process */ 00601 for (x = 0; x < cid->pos;) { 00602 switch (cid->rawdata[x++]) { 00603 case 1: 00604 /* Date */ 00605 break; 00606 case 2: /* Number */ 00607 case 3: /* Number (for Zebble) */ 00608 case 4: /* Number */ 00609 res = cid->rawdata[x]; 00610 if (res > 32) { 00611 ast_log(LOG_NOTICE, "Truncating long caller ID number from %d bytes to 32\n", cid->rawdata[x]); 00612 res = 32; 00613 } 00614 if (ast_strlen_zero(cid->number)) { 00615 memcpy(cid->number, cid->rawdata + x + 1, res); 00616 /* Null terminate */ 00617 cid->number[res] = '\0'; 00618 } 00619 break; 00620 case 6: /* Stentor Call Qualifier (ie. Long Distance call) */ 00621 break; 00622 case 7: /* Name */ 00623 case 8: /* Name */ 00624 res = cid->rawdata[x]; 00625 if (res > 32) { 00626 ast_log(LOG_NOTICE, "Truncating long caller ID name from %d bytes to 32\n", cid->rawdata[x]); 00627 res = 32; 00628 } 00629 memcpy(cid->name, cid->rawdata + x + 1, res); 00630 cid->name[res] = '\0'; 00631 break; 00632 case 17: /* UK: Call type, 1=Voice Call, 2=Ringback when free, 129=Message waiting */ 00633 case 19: /* UK: Network message system status (Number of messages waiting) */ 00634 case 22: /* Something French */ 00635 break; 00636 default: 00637 ast_log(LOG_NOTICE, "Unknown IE %d\n", cid->rawdata[x - 1]); 00638 } 00639 x += cid->rawdata[x]; 00640 x++; 00641 } 00642 } else { 00643 /* SDMF */ 00644 ast_copy_string(cid->number, cid->rawdata + 8, sizeof(cid->number)); 00645 } 00646 /* Update flags */ 00647 cid->flags = 0; 00648 if (!strcmp(cid->number, "P")) { 00649 strcpy(cid->number, ""); 00650 cid->flags |= CID_PRIVATE_NUMBER; 00651 } else if (!strcmp(cid->number, "O") || ast_strlen_zero(cid->number)) { 00652 strcpy(cid->number, ""); 00653 cid->flags |= CID_UNKNOWN_NUMBER; 00654 } 00655 if (!strcmp(cid->name, "P")) { 00656 strcpy(cid->name, ""); 00657 cid->flags |= CID_PRIVATE_NAME; 00658 } else if (!strcmp(cid->name, "O") || ast_strlen_zero(cid->name)) { 00659 strcpy(cid->name, ""); 00660 cid->flags |= CID_UNKNOWN_NAME; 00661 } 00662 return 1; 00663 break; 00664 default: 00665 ast_log(LOG_ERROR, "Dunno what to do with a digit in sawflag %d\n", cid->sawflag); 00666 } 00667 } 00668 } 00669 if (mylen) { 00670 memcpy(cid->oldstuff, buf, mylen * 2); 00671 cid->oldlen = mylen * 2; 00672 } else 00673 cid->oldlen = 0; 00674 00675 return 0; 00676 }
|
|
||||||||||||||||||||
|
Read samples into the state machine.
Definition at line 280 of file callerid.c. References ast_log(), AST_XLAW, calc_crc(), CID_UNKNOWN_NUMBER, callerid_state::crc, callerid_state::flags, fsk_serial(), callerid_state::fskd, callerid_state::len, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, LOG_WARNING, callerid_state::name, callerid_state::number, callerid_state::oldlen, callerid_state::oldstuff, option_debug, callerid_state::pos, callerid_state::rawdata, callerid_state::sawflag, and callerid_state::skipflag. Referenced by ss_thread(). 00281 { 00282 int mylen = len; 00283 int olen; 00284 int b = 'X'; 00285 int b2; 00286 int res; 00287 int x; 00288 short *buf; 00289 00290 buf = alloca(2 * len + cid->oldlen); 00291 00292 memcpy(buf, cid->oldstuff, cid->oldlen); 00293 mylen += cid->oldlen / 2; 00294 00295 for (x = 0; x < len; x++) 00296 buf[x+cid->oldlen/2] = AST_XLAW(ubuf[x]); 00297 00298 while (mylen >= 160) { 00299 b = b2 = 0; 00300 olen = mylen; 00301 res = fsk_serial(&cid->fskd, buf, &mylen, &b); 00302 00303 if (mylen < 0) { 00304 ast_log(LOG_ERROR, "fsk_serial made mylen < 0 (%d)\n", mylen); 00305 return -1; 00306 } 00307 00308 buf += (olen - mylen); 00309 00310 if (res < 0) { 00311 ast_log(LOG_NOTICE, "fsk_serial failed\n"); 00312 return -1; 00313 } 00314 00315 if (res == 1) { 00316 b2 = b; 00317 b &= 0x7f; 00318 00319 /* crc checksum calculation */ 00320 if (cid->sawflag > 1) 00321 cid->crc = calc_crc(cid->crc, (unsigned char) b2); 00322 00323 /* Ignore invalid bytes */ 00324 if (b > 0xff) 00325 continue; 00326 00327 /* skip DLE if needed */ 00328 if (cid->sawflag > 0) { 00329 if (cid->sawflag != 5 && cid->skipflag == 0 && b == 0x10) { 00330 cid->skipflag = 1 ; 00331 continue ; 00332 } 00333 } 00334 if (cid->skipflag == 1) 00335 cid->skipflag = 0 ; 00336 00337 /* caller id retrieval */ 00338 switch (cid->sawflag) { 00339 case 0: /* DLE */ 00340 if (b == 0x10) { 00341 cid->sawflag = 1; 00342 cid->skipflag = 0; 00343 cid->crc = 0; 00344 } 00345 break; 00346 case 1: /* SOH */ 00347 if (b == 0x01) 00348 cid->sawflag = 2; 00349 break ; 00350 case 2: /* HEADER */ 00351 if (b == 0x07) 00352 cid->sawflag = 3; 00353 break; 00354 case 3: /* STX */ 00355 if (b == 0x02) 00356 cid->sawflag = 4; 00357 break; 00358 case 4: /* SERVICE TYPE */ 00359 if (b == 0x40) 00360 cid->sawflag = 5; 00361 break; 00362 case 5: /* Frame Length */ 00363 cid->sawflag = 6; 00364 break; 00365 case 6: /* NUMBER TYPE */ 00366 cid->sawflag = 7; 00367 cid->pos = 0; 00368 cid->rawdata[cid->pos++] = b; 00369 break; 00370 case 7: /* NUMBER LENGTH */ 00371 cid->sawflag = 8; 00372 cid->len = b; 00373 if ((cid->len+2) >= sizeof(cid->rawdata)) { 00374 ast_log(LOG_WARNING, "too long caller id string\n") ; 00375 return -1; 00376 } 00377 cid->rawdata[cid->pos++] = b; 00378 break; 00379 case 8: /* Retrieve message */ 00380 cid->rawdata[cid->pos++] = b; 00381 cid->len--; 00382 if (cid->len<=0) { 00383 cid->rawdata[cid->pos] = '\0'; 00384 cid->sawflag = 9; 00385 } 00386 break; 00387 case 9: /* ETX */ 00388 cid->sawflag = 10; 00389 break; 00390 case 10: /* CRC Checksum 1 */ 00391 cid->sawflag = 11; 00392 break; 00393 case 11: /* CRC Checksum 2 */ 00394 cid->sawflag = 12; 00395 if (cid->crc != 0) { 00396 ast_log(LOG_WARNING, "crc checksum error\n") ; 00397 return -1; 00398 } 00399 /* extract caller id data */ 00400 for (x = 0; x < cid->pos;) { 00401 switch (cid->rawdata[x++]) { 00402 case 0x02: /* caller id number */ 00403 cid->number[0] = '\0'; 00404 cid->name[0] = '\0'; 00405 cid->flags = 0; 00406 res = cid->rawdata[x++]; 00407 ast_copy_string(cid->number, &cid->rawdata[x], res+1); 00408 x += res; 00409 break; 00410 case 0x21: /* additional information */ 00411 /* length */ 00412 x++; 00413 /* number type */ 00414 switch (cid->rawdata[x]) { 00415 case 0x00: /* unknown */ 00416 case 0x01: /* international number */ 00417 case 0x02: /* domestic number */ 00418 case 0x03: /* network */ 00419 case 0x04: /* local call */ 00420 case 0x06: /* short dial number */ 00421 case 0x07: /* reserved */ 00422 default: /* reserved */ 00423 if (option_debug > 1) 00424 ast_log(LOG_DEBUG, "cid info:#1=%X\n", cid->rawdata[x]); 00425 break ; 00426 } 00427 x++; |