Go to the source code of this file.
Defines | |
#define | MAX_CALLERID_SIZE 32000 |
#define | CID_PRIVATE_NAME (1 << 0) |
#define | CID_PRIVATE_NUMBER (1 << 1) |
#define | CID_UNKNOWN_NAME (1 << 2) |
#define | CID_UNKNOWN_NUMBER (1 << 3) |
#define | AST_LIN2X(a) ((codec == AST_FORMAT_ALAW) ? (AST_LIN2A(a)) : (AST_LIN2MU(a))) |
#define | AST_XLAW(a) ((codec == AST_FORMAT_ALAW) ? (AST_ALAW(a)) : (AST_MULAW(a))) |
#define | PUT_BYTE(a) |
#define | PUT_AUDIO_SAMPLE(y) |
#define | PUT_CLID_MARKMS |
#define | PUT_CLID_BAUD(bit) |
#define | PUT_CLID(byte) |
Typedefs | |
typedef callerid_state | CIDSTATE |
Functions | |
void | callerid_init (void) |
CallerID Initialization. | |
int | callerid_generate (unsigned char *buf, char *number, char *name, int flags, int callwaiting, int codec) |
Generates a CallerID FSK stream in ulaw format suitable for transmission. | |
callerid_state * | callerid_new (void) |
Create a callerID state machine. | |
int | callerid_feed (struct callerid_state *cid, unsigned char *ubuf, int samples, int codec) |
Read samples into the state machine. | |
void | callerid_get (struct callerid_state *cid, char **number, char **name, int *flags) |
Extract info out of callerID state machine. Flags are listed above. | |
void | callerid_free (struct callerid_state *cid) |
Free a callerID state. | |
int | ast_callerid_generate (unsigned char *buf, char *astcid, int codec) |
Generate Caller-ID spill from the "callerid" field of asterisk (in e-mail address like format). | |
int | vmwi_generate (unsigned char *buf, int active, int mdmf, int codec) |
Generate message waiting indicator. | |
int | ast_callerid_callwaiting_generate (unsigned char *buf, char *astcid, int codec) |
Generate Caller-ID spill from the "callerid" field of asterisk (in e-mail address like format) but in a format suitable for Call Waiting(tm)'s Caller*ID(tm). | |
int | ast_callerid_parse (char *instr, char **name, char **location) |
Destructively parse inbuf into name and location (or number). | |
int | ast_gen_cas (unsigned char *outbuf, int sas, int len, int codec) |
Generate a CAS (CPE Alert Signal) tone for 'n' samples. | |
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... | |
int | ast_isphonenumber (char *n) |
Check if a string consists only of digits. Returns non-zero if so. | |
Variables | |
float | cid_dr [4] |
float | cid_di [4] |
float | clidsb |
|
Definition at line 27 of file callerid.h. |
|
Definition at line 28 of file callerid.h. Referenced by callerid_feed(). |
|
Definition at line 22 of file callerid.h. Referenced by callerid_feed(). |
|
Definition at line 23 of file callerid.h. Referenced by callerid_feed(), and callerid_get(). |
|
Definition at line 24 of file callerid.h. Referenced by callerid_feed(), callerid_get(), and callerid_new(). |
|
Definition at line 25 of file callerid.h. Referenced by callerid_feed(), callerid_get(), and callerid_new(). |
|
Definition at line 20 of file callerid.h. |
|
Value: do { \ int index = (short)(rint(8192.0 * (y))); \ *(buf++) = AST_LIN2X(index); \ bytes++; \ } while(0) Definition at line 176 of file callerid.h. |
|
Value: do { \ *(buf++) = (a); \ bytes++; \ } while(0) Definition at line 171 of file callerid.h. |
|
Definition at line 197 of file callerid.h. Referenced by callerid_generate(), and vmwi_generate(). |
|
Definition at line 188 of file callerid.h. |
|
Value: do { \ int x; \ for (x=0;x<8;x++) \ PUT_AUDIO_SAMPLE(callerid_getcarrier(&cr, &ci, 1)); \ } while(0) Definition at line 182 of file callerid.h. Referenced by callerid_generate(), and vmwi_generate(). |
|
Definition at line 32 of file callerid.h. |
|
Generate Caller-ID spill from the "callerid" field of asterisk (in e-mail address like format) but in a format suitable for Call Waiting(tm)'s Caller*ID(tm). See ast_callerid_generate for other details Definition at line 587 of file callerid.c.
00588 {
00589 return __ast_callerid_generate(buf, callerid, 1, codec);
00590 }
|
|
Generate Caller-ID spill from the "callerid" field of asterisk (in e-mail address like format).
Definition at line 582 of file callerid.c.
00583 {
00584 return __ast_callerid_generate(buf, callerid, 0, codec);
00585 }
|
|
Destructively parse inbuf into name and location (or number).
Definition at line 516 of file callerid.c. References ast_isphonenumber(), and ast_shrink_phone_number(). Referenced by ast_cdr_init(), ast_cdr_setcid(), ast_cdr_update(), ast_privacy_check(), and ast_privacy_set().
00517 { 00518 char *ns, *ne; 00519 char *ls, *le; 00520 char tmp[256]; 00521 /* Try for "name" <location> format or 00522 name <location> format */ 00523 if ((ls = strchr(instr, '<')) && (le = strchr(ls, '>'))) { 00524 /* Found the location */ 00525 *le = '\0'; 00526 *ls = '\0'; 00527 *location = ls + 1; 00528 if ((ns = strchr(instr, '\"')) && (ne = strchr(ns + 1, '\"'))) { 00529 /* Get name out of quotes */ 00530 *ns = '\0'; 00531 *ne = '\0'; 00532 *name = ns + 1; 00533 return 0; 00534 } else { 00535 /* Just trim off any trailing spaces */ 00536 *name = instr; 00537 while(strlen(instr) && (instr[strlen(instr) - 1] < 33)) 00538 instr[strlen(instr) - 1] = '\0'; 00539 /* And leading spaces */ 00540 while(**name && (**name < 33)) 00541 name++; 00542 return 0; 00543 } 00544 } else { 00545 strncpy(tmp, instr, sizeof(tmp)-1); 00546 ast_shrink_phone_number(tmp); 00547 if (ast_isphonenumber(tmp)) { 00548 /* Assume it's just a location */ 00549 *name = NULL; 00550 *location = instr; 00551 } else { 00552 /* Assume it's just a name. Make sure it's not quoted though */ 00553 *name = instr; 00554 while(*(*name) && ((*(*name) < 33) || (*(*name) == '\"'))) (*name)++; 00555 ne = *name + strlen(*name) - 1; 00556 while((ne > *name) && ((*ne < 33) || (*ne == '\"'))) { *ne = '\0'; ne--; } 00557 *location = NULL; 00558 } 00559 return 0; 00560 } 00561 return -1; 00562 } |
|
Generate a CAS (CPE Alert Signal) tone for 'n' samples.
Definition at line 149 of file callerid.c. References casdi1, casdi2, casdr1, casdr2, sasdi, and sasdr.
00150 { 00151 int pos = 0; 00152 int saslen=2400; 00153 float cr1 = 1.0; 00154 float ci1 = 0.0; 00155 float cr2 = 1.0; 00156 float ci2 = 0.0; 00157 if (sendsas) { 00158 if (len < saslen) 00159 return -1; 00160 gen_tone(outbuf, saslen, codec, sasdr, sasdi, &cr1, &ci1); 00161 len -= saslen; 00162 pos += saslen; 00163 cr2 = cr1; 00164 ci2 = ci1; 00165 } 00166 gen_tones(outbuf + pos, len, codec, casdr1, casdi1, casdr2, casdi2, &cr1, &ci1, &cr2, &ci2); 00167 return 0; 00168 } |
|
Check if a string consists only of digits. Returns non-zero if so.
Definition at line 505 of file callerid.c. Referenced by ast_callerid_parse().
00506 { 00507 int x; 00508 if (!n || !strlen(n)) 00509 return 0; 00510 for (x=0;n[x];x++) 00511 if (!strchr("0123456789*#", n[x])) 00512 return 0; 00513 return 1; 00514 } |
|
Shrink a phone number in place to just digits (more accurately it just removes ()'s, .'s, and -'s...
Definition at line 496 of file callerid.c. Referenced by ast_callerid_parse(), ast_cdr_init(), ast_cdr_setcid(), ast_cdr_update(), ast_privacy_check(), and ast_privacy_set().
00497 { 00498 int x,y=0; 00499 for (x=0;n[x];x++) 00500 if (!strchr("( )-.", n[x])) 00501 n[y++] = n[x]; 00502 n[y] = '\0'; 00503 } |
|
Read samples into the state machine.
Definition at line 170 of file callerid.c. References ast_log(), AST_XLAW, b, CID_PRIVATE_NAME, CID_PRIVATE_NUMBER, CID_UNKNOWN_NAME, CID_UNKNOWN_NUMBER, callerid_state::cksum, callerid_state::flags, free, fsk_serie(), callerid_state::fskd, callerid_state::len, LOG_ERROR, LOG_NOTICE, LOG_WARNING, malloc, 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.
00171 { 00172 int mylen = len; 00173 int olen; 00174 int b = 'X'; 00175 int res; 00176 int x; 00177 short *buf = malloc(2 * len + cid->oldlen); 00178 short *obuf = buf; 00179 if (!buf) { 00180 ast_log(LOG_WARNING, "Out of memory\n"); 00181 return -1; 00182 } 00183 memset(buf, 0, 2 * len + cid->oldlen); 00184 memcpy(buf, cid->oldstuff, cid->oldlen); 00185 mylen += cid->oldlen/2; 00186 for (x=0;x<len;x++) 00187 buf[x+cid->oldlen/2] = AST_XLAW(ubuf[x]); 00188 while(mylen >= 80) { 00189 olen = mylen; 00190 res = fsk_serie(&cid->fskd, buf, &mylen, &b); 00191 if (mylen < 0) { 00192 ast_log(LOG_ERROR, "fsk_serie made mylen < 0 (%d)\n", mylen); 00193 return -1; 00194 } 00195 buf += (olen - mylen); 00196 if (res < 0) { 00197 ast_log(LOG_NOTICE, "fsk_serie failed\n"); 00198 return -1; 00199 } 00200 if (res == 1) { 00201 /* Ignore invalid bytes */ 00202 if (b > 0xff) 00203 continue; 00204 switch(cid->sawflag) { 00205 case 0: /* Look for flag */ 00206 if (b == 'U') 00207 cid->sawflag = 2; 00208 break; 00209 case 2: /* Get lead-in */ 00210 if ((b == 0x04) || (b == 0x80)) { 00211 cid->type = b; 00212 cid->sawflag = 3; 00213 cid->cksum = b; 00214 } 00215 break; 00216 case 3: /* Get length */ 00217 /* Not a lead in. We're ready */ 00218 cid->sawflag = 4; 00219 cid->len = b; 00220 cid->pos = 0; 00221 cid->cksum += b; 00222 break; 00223 case 4: /* Retrieve message */ 00224 if (cid->pos >= 128) { 00225 ast_log(LOG_WARNING, "Caller ID too long???\n"); 00226 return -1; 00227 } 00228 cid->rawdata[cid->pos++] = b; 00229 cid->len--; 00230 cid->cksum += b; 00231 if (!cid->len) { 00232 cid->rawdata[cid->pos] = '\0'; 00233 cid->sawflag = 5; 00234 } 00235 break; 00236 case 5: /* Check checksum */ 00237 if (b != (256 - (cid->cksum & 0xff))) { 00238 ast_log(LOG_NOTICE, "Caller*ID failed checksum\n"); 00239 /* Try again */ 00240 cid->sawflag = 0; 00241 break; 00242 } 00243 00244 strcpy(cid->number, ""); 00245 strcpy(cid->name, ""); 00246 /* If we get this far we're fine. */ 00247 if (cid->type == 0x80) { 00248 /* MDMF */ 00249 /* Go through each element and process */ 00250 for (x=0;x< cid->pos;) { 00251 switch(cid->rawdata[x++]) { 00252 case 1: 00253 /* Date */ 00254 break; 00255 case 2: /* Number */ 00256 case 3: /* Number (for Zebble) */ 00257 case 4: /* Number */ 00258 res = cid->rawdata[x]; 00259 if (res > 32) { 00260 ast_log(LOG_NOTICE, "Truncating long caller ID number from %d bytes to 32\n", cid->rawdata[x]); 00261 res = 32; 00262 } 00263 memcpy(cid->number, cid->rawdata + x + 1, res); 00264 /* Null terminate */ 00265 cid->number[res] = '\0'; 00266 break; 00267 case 7: /* Name */ 00268 case 8: /* Name */ 00269 res = cid->rawdata[x]; 00270 if (res > 32) { 00271 ast_log(LOG_NOTICE, "Truncating long caller ID name from %d bytes to 32\n", cid->rawdata[x]); 00272 res = 32; 00273 } 00274 memcpy(cid->name, cid->rawdata + x + 1, res); 00275 cid->name[res] = '\0'; 00276 break; 00277 case 22: /* Something French */ 00278 break; 00279 default: 00280 ast_log(LOG_NOTICE, "Unknown IE %d\n", cid->rawdata[x-1]); 00281 } 00282 x += cid->rawdata[x]; 00283 x++; 00284 } 00285 } else { 00286 /* SDMF */ 00287 strncpy(cid->number, cid->rawdata + 8, sizeof(cid->number)-1); 00288 } 00289 /* Update flags */ 00290 cid->flags = 0; 00291 if (!strcmp(cid->number, "P")) { 00292 strcpy(cid->number, ""); 00293 cid->flags |= CID_PRIVATE_NUMBER; 00294 } else if (!strcmp(cid->number, "O") || !strlen(cid->number)) { 00295 strcpy(cid->number, ""); 00296 cid->flags |= CID_UNKNOWN_NUMBER; 00297 } 00298 if (!strcmp(cid->name, "P")) { 00299 strcpy(cid->name, ""); 00300 cid->flags |= CID_PRIVATE_NAME; 00301 } else if (!strcmp(cid->name, "O") || !strlen(cid->name)) { 00302 strcpy(cid->name, ""); 00303 cid->flags |= CID_UNKNOWN_NAME; 00304 } 00305 return 1; 00306 break; 00307 default: 00308 ast_log(LOG_ERROR, "Dunno what to do with a digit in sawflag %d\n", cid->sawflag); 00309 } 00310 } 00311 } 00312 if (mylen) { 00313 memcpy(cid->oldstuff, buf, mylen * 2); 00314 cid->oldlen = mylen * 2; 00315 } else 00316 cid->oldlen = 0; 00317 free(obuf); 00318 return 0; 00319 } |
|
Free a callerID state.
Definition at line 321 of file callerid.c. References free.
00322 { 00323 free(cid); 00324 } |
|
Generates a CallerID FSK stream in ulaw format suitable for transmission.
Definition at line 454 of file callerid.c. References PUT_BYTE, PUT_CLID, and PUT_CLID_MARKMS.
00455 { 00456 int bytes=0; 00457 int x, sum; 00458 int len; 00459 /* Initial carriers (real/imaginary) */ 00460 float cr = 1.0; 00461 float ci = 0.0; 00462 float scont = 0.0; 00463 unsigned char msg[256]; 00464 len = callerid_genmsg(msg, sizeof(msg), number, name, flags); 00465 if (!callwaiting) { 00466 /* Wait a half a second */ 00467 for (x=0;x<4000;x++) 00468 PUT_BYTE(0x7f); 00469 /* Transmit 30 0x55's (looks like a square wave) for channel seizure */ 00470 for (x=0;x<30;x++) 00471 PUT_CLID(0x55); 00472 } 00473 /* Send 150ms of callerid marks */ 00474 for (x=0;x<150;x++) 00475 PUT_CLID_MARKMS; 00476 /* Send 0x80 indicating MDMF format */ 00477 PUT_CLID(0x80); 00478 /* Put length of whole message */ 00479 PUT_CLID(len); 00480 sum = 0x80 + strlen(msg); 00481 /* Put each character of message and update checksum */ 00482 for (x=0;x<len; x++) { 00483 PUT_CLID(msg[x]); 00484 sum += msg[x]; 00485 } 00486 /* Send 2's compliment of sum */ 00487 PUT_CLID(256 - (sum & 255)); 00488 00489 /* Send 50 more ms of marks */ 00490 for (x=0;x<50;x++) 00491 PUT_CLID_MARKMS; 00492 00493 return bytes; 00494 } |
|
Extract info out of callerID state machine. Flags are listed above.
Returns nothing. Definition at line 136 of file callerid.c. References CID_PRIVATE_NUMBER, CID_UNKNOWN_NAME, CID_UNKNOWN_NUMBER, callerid_state::flags, callerid_state::name, and callerid_state::number.
00137 { 00138 *flags = cid->flags; 00139 if (cid->flags & (CID_UNKNOWN_NAME | CID_PRIVATE_NUMBER)) 00140 *name = NULL; 00141 else 00142 *name = cid->name; 00143 if (cid->flags & (CID_UNKNOWN_NUMBER | CID_PRIVATE_NUMBER)) 00144 *number = NULL; 00145 else 00146 *number = cid->number; 00147 } |
|
CallerID Initialization. Initializes the callerid system. Mostly stuff for inverse FFT Definition at line 94 of file callerid.c. References CALLERID_MARK, CALLERID_SPACE, CAS_FREQ1, CAS_FREQ2, casdi1, casdi2, casdr1, casdr2, cid_di, cid_dr, SAS_FREQ, sasdi, and sasdr. Referenced by main().
00095 { 00096 /* Initialize stuff for inverse FFT */ 00097 cid_dr[0] = cos(CALLERID_SPACE * 2.0 * M_PI / 8000.0); 00098 cid_di[0] = sin(CALLERID_SPACE * 2.0 * M_PI / 8000.0); 00099 cid_dr[1] = cos(CALLERID_MARK * 2.0 * M_PI / 8000.0); 00100 cid_di[1] = sin(CALLERID_MARK * 2.0 * M_PI / 8000.0); 00101 sasdr = cos(SAS_FREQ * 2.0 * M_PI / 8000.0); 00102 sasdi = sin(SAS_FREQ * 2.0 * M_PI / 8000.0); 00103 casdr1 = cos(CAS_FREQ1 * 2.0 * M_PI / 8000.0); 00104 casdi1 = sin(CAS_FREQ1 * 2.0 * M_PI / 8000.0); 00105 casdr2 = cos(CAS_FREQ2 * 2.0 * M_PI / 8000.0); 00106 casdi2 = sin(CAS_FREQ2 * 2.0 * M_PI / 8000.0); 00107 } |
|
Create a callerID state machine. This function returns a malloc'd instance of the callerid_state data structure. Returns a pointer to a malloc'd callerid_state structure, or NULL on error. Definition at line 109 of file callerid.c. References ast_log(), CID_UNKNOWN_NAME, CID_UNKNOWN_NUMBER, LOG_WARNING, and malloc.
00110 { 00111 struct callerid_state *cid; 00112 cid = malloc(sizeof(struct callerid_state)); 00113 memset(cid, 0, sizeof(struct callerid_state)); 00114 if (cid) { 00115 cid->fskd.spb = 7; /* 1200 baud */ 00116 cid->fskd.hdlc = 0; /* Async */ 00117 cid->fskd.nbit = 8; /* 8 bits */ 00118 cid->fskd.nstop = 1; /* 1 stop bit */ 00119 cid->fskd.paridad = 0; /* No parity */ 00120 cid->fskd.bw=1; /* Filter 800 Hz */ 00121 cid->fskd.f_mark_idx = 2; /* 1200 Hz */ 00122 cid->fskd.f_space_idx = 3; /* 2200 Hz */ 00123 cid->fskd.pcola = 0; /* No clue */ 00124 cid->fskd.cont = 0; /* Digital PLL reset */ 00125 cid->fskd.x0 = 0.0; 00126 cid->fskd.state = 0; 00127 memset(cid->name, 0, sizeof(cid->name)); 00128 memset(cid->number, 0, sizeof(cid->number)); 00129 cid->flags = CID_UNKNOWN_NAME | CID_UNKNOWN_NUMBER; 00130 cid->pos = 0; 00131 } else 00132 ast_log(LOG_WARNING, "Out of memory\n"); 00133 return cid; 00134 } |
|
Generate message waiting indicator.
Definition at line 395 of file callerid.c. References PUT_CLID, and PUT_CLID_MARKMS.
00396 { 00397 unsigned char msg[256]; 00398 int len=0; 00399 int sum; 00400 int x; 00401 int bytes = 0; 00402 float cr = 1.0; 00403 float ci = 0.0; 00404 float scont = 0.0; 00405 if (mdmf) { 00406 /* MDMF Message waiting */ 00407 msg[len++] = 0x82; 00408 /* Length is 3 */ 00409 msg[len++] = 3; 00410 /* IE is "Message Waiting Parameter" */ 00411 msg[len++] = 0xb; 00412 /* Length of IE is one */ 00413 msg[len++] = 1; 00414 /* Active or not */ 00415 if (active) 00416 msg[len++] = 0xff; 00417 else 00418 msg[len++] = 0x00; 00419 } else { 00420 /* SDMF Message waiting */ 00421 msg[len++] = 0x6; 00422 /* Length is 3 */ 00423 msg[len++] = 3; 00424 if (active) { 00425 msg[len++] = 0x42; 00426 msg[len++] = 0x42; 00427 msg[len++] = 0x42; 00428 } else { 00429 msg[len++] = 0x6f; 00430 msg[len++] = 0x6f; 00431 msg[len++] = 0x6f; 00432 } 00433 } 00434 sum = 0; 00435 for (x=0;x<len;x++) 00436 sum += msg[x]; 00437 sum = (256 - (sum & 255)); 00438 msg[len++] = sum; 00439 /* Transmit 30 0x55's (looks like a square wave) for channel seizure */ 00440 for (x=0;x<30;x++) 00441 PUT_CLID(0x55); 00442 /* Send 170ms of callerid marks */ 00443 for (x=0;x<170;x++) 00444 PUT_CLID_MARKMS; 00445 for (x=0;x<len;x++) { 00446 PUT_CLID(msg[x]); 00447 } 00448 /* Send 50 more ms of marks */ 00449 for (x=0;x<50;x++) 00450 PUT_CLID_MARKMS; 00451 return bytes; 00452 } |
|
Definition at line 154 of file callerid.h. Referenced by callerid_init(). |
|
Definition at line 153 of file callerid.h. Referenced by callerid_init(). |
|
Definition at line 155 of file callerid.h. |