Main Page | Alphabetical List | Data Structures | File List | Data Fields | Globals

callerid.c

Go to the documentation of this file.
00001 /* 00002 * Asterisk -- A telephony toolkit for Linux. 00003 * 00004 * CallerID Generation support 00005 * 00006 * Copyright (C) 2001-2004, Digium, Inc. 00007 * 00008 * Mark Spencer <markster@digium.com> 00009 * 00010 * This program is free software, distributed under the terms of 00011 * the GNU General Public License. 00012 * 00013 * Includes code and algorithms from the Zapata library. 00014 * 00015 */ 00016 00017 #include <time.h> 00018 #include <string.h> 00019 #include <stdio.h> 00020 #include <stdlib.h> 00021 #include <unistd.h> 00022 #include <math.h> 00023 #include <ctype.h> 00024 #include <asterisk/ulaw.h> 00025 #include <asterisk/alaw.h> 00026 #include <asterisk/frame.h> 00027 #include <asterisk/callerid.h> 00028 #include <asterisk/logger.h> 00029 #include <asterisk/fskmodem.h> 00030 #include <asterisk/utils.h> 00031 00032 struct callerid_state { 00033 fsk_data fskd; 00034 char rawdata[256]; 00035 short oldstuff[160]; 00036 int oldlen; 00037 int pos; 00038 int type; 00039 int cksum; 00040 char name[64]; 00041 char number[64]; 00042 int flags; 00043 int sawflag; 00044 int len; 00045 }; 00046 00047 00048 float cid_dr[4], cid_di[4]; 00049 float clidsb = 8000.0 / 1200.0; 00050 float sasdr, sasdi; 00051 float casdr1, casdi1, casdr2, casdi2; 00052 00053 #define CALLERID_SPACE 2200.0 /* 2200 hz for "0" */ 00054 #define CALLERID_MARK 1200.0 /* 1200 hz for "1" */ 00055 #define SAS_FREQ 440.0 00056 #define CAS_FREQ1 2130.0 00057 #define CAS_FREQ2 2750.0 00058 00059 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) 00060 { 00061 int x; 00062 float t; 00063 for (x=0;x<len;x++) { 00064 t = *cr1 * ddr1 - *ci1 * ddi1; 00065 *ci1 = *cr1 * ddi1 + *ci1 * ddr1; 00066 *cr1 = t; 00067 t = 2.0 - (*cr1 * *cr1 + *ci1 * *ci1); 00068 *cr1 *= t; 00069 *ci1 *= t; 00070 00071 t = *cr2 * ddr2 - *ci2 * ddi2; 00072 *ci2 = *cr2 * ddi2 + *ci2 * ddr2; 00073 *cr2 = t; 00074 t = 2.0 - (*cr2 * *cr2 + *ci2 * *ci2); 00075 *cr2 *= t; 00076 *ci2 *= t; 00077 buf[x] = AST_LIN2X((*cr1 + *cr2) * 2048.0); 00078 } 00079 } 00080 00081 static inline void gen_tone(unsigned char *buf, int len, int codec, float ddr1, float ddi1, float *cr1, float *ci1) 00082 { 00083 int x; 00084 float t; 00085 for (x=0;x<len;x++) { 00086 t = *cr1 * ddr1 - *ci1 * ddi1; 00087 *ci1 = *cr1 * ddi1 + *ci1 * ddr1; 00088 *cr1 = t; 00089 t = 2.0 - (*cr1 * *cr1 + *ci1 * *ci1); 00090 *cr1 *= t; 00091 *ci1 *= t; 00092 buf[x] = AST_LIN2X(*cr1 * 8192.0); 00093 } 00094 } 00095 00096 void callerid_init(void) 00097 { 00098 /* Initialize stuff for inverse FFT */ 00099 cid_dr[0] = cos(CALLERID_SPACE * 2.0 * M_PI / 8000.0); 00100 cid_di[0] = sin(CALLERID_SPACE * 2.0 * M_PI / 8000.0); 00101 cid_dr[1] = cos(CALLERID_MARK * 2.0 * M_PI / 8000.0); 00102 cid_di[1] = sin(CALLERID_MARK * 2.0 * M_PI / 8000.0); 00103 sasdr = cos(SAS_FREQ * 2.0 * M_PI / 8000.0); 00104 sasdi = sin(SAS_FREQ * 2.0 * M_PI / 8000.0); 00105 casdr1 = cos(CAS_FREQ1 * 2.0 * M_PI / 8000.0); 00106 casdi1 = sin(CAS_FREQ1 * 2.0 * M_PI / 8000.0); 00107 casdr2 = cos(CAS_FREQ2 * 2.0 * M_PI / 8000.0); 00108 casdi2 = sin(CAS_FREQ2 * 2.0 * M_PI / 8000.0); 00109 } 00110 00111 struct callerid_state *callerid_new(int cid_signalling) 00112 { 00113 struct callerid_state *cid; 00114 cid = malloc(sizeof(struct callerid_state)); 00115 if (cid) { 00116 memset(cid, 0, sizeof(struct callerid_state)); 00117 cid->fskd.spb = 7; /* 1200 baud */ 00118 cid->fskd.hdlc = 0; /* Async */ 00119 cid->fskd.nbit = 8; /* 8 bits */ 00120 cid->fskd.nstop = 1; /* 1 stop bit */ 00121 cid->fskd.paridad = 0; /* No parity */ 00122 cid->fskd.bw=1; /* Filter 800 Hz */ 00123 if (cid_signalling == 2) { /* v23 signalling */ 00124 cid->fskd.f_mark_idx = 4; /* 1300 Hz */ 00125 cid->fskd.f_space_idx = 5; /* 2100 Hz */ 00126 } else { /* Bell 202 signalling as default */ 00127 cid->fskd.f_mark_idx = 2; /* 1200 Hz */ 00128 cid->fskd.f_space_idx = 3; /* 2200 Hz */ 00129 } 00130 cid->fskd.pcola = 0; /* No clue */ 00131 cid->fskd.cont = 0; /* Digital PLL reset */ 00132 cid->fskd.x0 = 0.0; 00133 cid->fskd.state = 0; 00134 memset(cid->name, 0, sizeof(cid->name)); 00135 memset(cid->number, 0, sizeof(cid->number)); 00136 cid->flags = CID_UNKNOWN_NAME | CID_UNKNOWN_NUMBER; 00137 cid->pos = 0; 00138 } else 00139 ast_log(LOG_WARNING, "Out of memory\n"); 00140 return cid; 00141 } 00142 00143 void callerid_get(struct callerid_state *cid, char **name, char **number, int *flags) 00144 { 00145 *flags = cid->flags; 00146 if (cid->flags & (CID_UNKNOWN_NAME | CID_PRIVATE_NUMBER)) 00147 *name = NULL; 00148 else 00149 *name = cid->name; 00150 if (cid->flags & (CID_UNKNOWN_NUMBER | CID_PRIVATE_NUMBER)) 00151 *number = NULL; 00152 else 00153 *number = cid->number; 00154 } 00155 00156 void callerid_get_dtmf(char *cidstring, char *number, int *flags) 00157 { 00158 int i; 00159 int code; 00160 00161 /* "Clear" the number-buffer. */ 00162 number[0] = 0; 00163 00164 if (strlen(cidstring) < 2) { 00165 ast_log(LOG_DEBUG, "No cid detected\n"); 00166 *flags = CID_UNKNOWN_NUMBER; 00167 return; 00168 } 00169 00170 /* Detect protocol and special types */ 00171 if (cidstring[0] == 'B') { 00172 /* Handle special codes */ 00173 code = atoi(&cidstring[1]); 00174 if (code == 0) 00175 *flags = CID_UNKNOWN_NUMBER; 00176 else if (code == 10) 00177 *flags = CID_PRIVATE_NUMBER; 00178 else 00179 ast_log(LOG_DEBUG, "Unknown DTMF code %d\n", code); 00180 } else if (cidstring[0] == 'D' && cidstring[2] == '#') { 00181 /* .DK special code */ 00182 if (cidstring[1] == '1') 00183 *flags = CID_PRIVATE_NUMBER; 00184 if (cidstring[1] == '2' || cidstring[1] == '3') 00185 *flags = CID_UNKNOWN_NUMBER; 00186 } else if (cidstring[0] == 'D' || cidstring[0] == 'A') { 00187 /* "Standard" callerid */ 00188 for (i = 1; i < strlen(cidstring); i++ ) { 00189 if (cidstring[i] == 'C' || cidstring[i] == '#') 00190 break; 00191 if (isdigit(cidstring[i])) 00192 number[i-1] = cidstring[i]; 00193 else 00194 ast_log(LOG_DEBUG, "Unknown CID digit '%c'\n", 00195 cidstring[i]); 00196 } 00197 number[i-1] = 0; 00198 } else if (isdigit(cidstring[0])) { 00199 /* It begins with a digit, so we parse it as a number and hope 00200 * for the best */ 00201 ast_log(LOG_WARNING, "Couldn't detect start-character. CID " 00202 "parsing might be unreliable\n"); 00203 for (i = 0; i < strlen(cidstring); i++) { 00204 if (isdigit(cidstring[i])) 00205 number[i] = cidstring[i]; 00206 else 00207 break; 00208 } 00209 number[i] = 0; 00210 } else { 00211 ast_log(LOG_DEBUG, "Unknown CID protocol, start digit '%c'\n", 00212 cidstring[0]); 00213 *flags = CID_UNKNOWN_NUMBER; 00214 } 00215 } 00216 00217 int ast_gen_cas(unsigned char *outbuf, int sendsas, int len, int codec) 00218 { 00219 int pos = 0; 00220 int saslen=2400; 00221 float cr1 = 1.0; 00222 float ci1 = 0.0; 00223 float cr2 = 1.0; 00224 float ci2 = 0.0; 00225 if (sendsas) { 00226 if (len < saslen) 00227 return -1; 00228 gen_tone(outbuf, saslen, codec, sasdr, sasdi, &cr1, &ci1); 00229 len -= saslen; 00230 pos += saslen; 00231 cr2 = cr1; 00232 ci2 = ci1; 00233 } 00234 gen_tones(outbuf + pos, len, codec, casdr1, casdi1, casdr2, casdi2, &cr1, &ci1, &cr2, &ci2); 00235 return 0; 00236 } 00237 00238 int callerid_feed(struct callerid_state *cid, unsigned char *ubuf, int len, int codec) 00239 { 00240 int mylen = len; 00241 int olen; 00242 int b = 'X'; 00243 int res; 00244 int x; 00245 short *buf = malloc(2 * len + cid->oldlen); 00246 short *obuf = buf; 00247 if (!buf) { 00248 ast_log(LOG_WARNING, "Out of memory\n"); 00249 return -1; 00250 } 00251 memset(buf, 0, 2 * len + cid->oldlen); 00252 memcpy(buf, cid->oldstuff, cid->oldlen); 00253 mylen += cid->oldlen/2; 00254 for (x=0;x<len;x++) 00255 buf[x+cid->oldlen/2] = AST_XLAW(ubuf[x]); 00256 while(mylen >= 160) { 00257 olen = mylen; 00258 res = fsk_serie(&cid->fskd, buf, &mylen, &b); 00259 if (mylen < 0) { 00260 ast_log(LOG_ERROR, "fsk_serie made mylen < 0 (%d)\n", mylen); 00261 return -1; 00262 } 00263 buf += (olen - mylen); 00264 if (res < 0) { 00265 ast_log(LOG_NOTICE, "fsk_serie failed\n"); 00266 return -1; 00267 } 00268 if (res == 1) { 00269 /* Ignore invalid bytes */ 00270 if (b > 0xff) 00271 continue; 00272 switch(cid->sawflag) { 00273 case 0: /* Look for flag */ 00274 if (b == 'U') 00275 cid->sawflag = 2; 00276 break; 00277 case 2: /* Get lead-in */ 00278 if ((b == 0x04) || (b == 0x80)) { 00279 cid->type = b; 00280 cid->sawflag = 3; 00281 cid->cksum = b; 00282 } 00283 break; 00284 case 3: /* Get length */ 00285 /* Not a lead in. We're ready */ 00286 cid->sawflag = 4; 00287 cid->len = b; 00288 cid->pos = 0; 00289 cid->cksum += b; 00290 break; 00291 case 4: /* Retrieve message */ 00292 if (cid->pos >= 128) { 00293 ast_log(LOG_WARNING, "Caller ID too long???\n"); 00294 return -1; 00295 } 00296 cid->rawdata[cid->pos++] = b; 00297 cid->len--; 00298 cid->cksum += b; 00299 if (!cid->len) { 00300 cid->rawdata[cid->pos] = '\0'; 00301 cid->sawflag = 5; 00302 } 00303 break; 00304 case 5: /* Check checksum */ 00305 if (b != (256 - (cid->cksum & 0xff))) { 00306 ast_log(LOG_NOTICE, "Caller*ID failed checksum\n"); 00307 /* Try again */ 00308 cid->sawflag = 0; 00309 break; 00310 } 00311 00312 cid->number[0] = '\0'; 00313 cid->name[0] = '\0'; 00314 /* If we get this far we're fine. */ 00315 if (cid->type == 0x80) { 00316 /* MDMF */ 00317 /* Go through each element and process */ 00318 for (x=0;x< cid->pos;) { 00319 switch(cid->rawdata[x++]) { 00320 case 1: 00321 /* Date */ 00322 break; 00323 case 2: /* Number */ 00324 case 3: /* Number (for Zebble) */ 00325 case 4: /* Number */ 00326 res = cid->rawdata[x]; 00327 if (res > 32) { 00328 ast_log(LOG_NOTICE, "Truncating long caller ID number from %d bytes to 32\n", cid->rawdata[x]); 00329 res = 32; 00330 } 00331 if (ast_strlen_zero(cid->number)) { 00332 memcpy(cid->number, cid->rawdata + x + 1, res); 00333 /* Null terminate */ 00334 cid->number[res] = '\0'; 00335 } 00336 break; 00337 case 7: /* Name */ 00338 case 8: /* Name */ 00339 res = cid->rawdata[x]; 00340 if (res > 32) { 00341 ast_log(LOG_NOTICE, "Truncating long caller ID name from %d bytes to 32\n", cid->rawdata[x]); 00342 res = 32; 00343 } 00344 memcpy(cid->name, cid->rawdata + x + 1, res); 00345 cid->name[res] = '\0'; 00346 break; 00347 case 17: /* UK: Call type, 1=Voice Call, 2=Ringback when free, 129=Message waiting */ 00348 case 19: /* UK: Network message system status (Number of messages waiting) */ 00349 case 22: /* Something French */ 00350 break; 00351 default: 00352 ast_log(LOG_NOTICE, "Unknown IE %d\n", cid->rawdata[x-1]); 00353 } 00354 x += cid->rawdata[x]; 00355 x++; 00356 } 00357 } else { 00358 /* SDMF */ 00359 strncpy(cid->number, cid->rawdata + 8, sizeof(cid->number)-1); 00360 } 00361 /* Update flags */ 00362 cid->flags = 0; 00363 if (!strcmp(cid->number, "P")) { 00364 strcpy(cid->number, ""); 00365 cid->flags |= CID_PRIVATE_NUMBER; 00366 } else if (!strcmp(cid->number, "O") || ast_strlen_zero(cid->number)) { 00367 strcpy(cid->number, ""); 00368 cid->flags |= CID_UNKNOWN_NUMBER; 00369 } 00370 if (!strcmp(cid->name, "P")) { 00371 strcpy(cid->name, ""); 00372 cid->flags |= CID_PRIVATE_NAME; 00373 } else if (!strcmp(cid->name, "O") || ast_strlen_zero(cid->name)) { 00374 strcpy(cid->name, ""); 00375 cid->flags |= CID_UNKNOWN_NAME; 00376 } 00377 return 1; 00378 break; 00379 default: 00380 ast_log(LOG_ERROR, "Dunno what to do with a digit in sawflag %d\n", cid->sawflag); 00381 } 00382 } 00383 } 00384 if (mylen) { 00385 memcpy(cid->oldstuff, buf, mylen * 2); 00386 cid->oldlen = mylen * 2; 00387 } else 00388 cid->oldlen = 0; 00389 free(obuf); 00390 return 0; 00391 } 00392 00393 void callerid_free(struct callerid_state *cid) 00394 { 00395 free(cid); 00396 } 00397 00398 static int callerid_genmsg(char *msg, int size, char *number, char *name, int flags) 00399 { 00400 time_t t; 00401 struct tm tm; 00402 char *ptr; 00403 int res; 00404 int i,x; 00405 /* Get the time */ 00406 time(&t); 00407 localtime_r(&t,&tm); 00408 00409 ptr = msg; 00410 00411 /* Format time and message header */ 00412 res = snprintf(ptr, size, "\001\010%02d%02d%02d%02d", tm.tm_mon + 1, 00413 tm.tm_mday, tm.tm_hour, tm.tm_min); 00414 size -= res; 00415 ptr += res; 00416 if (!number || ast_strlen_zero(number) || (flags & CID_UNKNOWN_NUMBER)) { 00417 /* Indicate number not known */ 00418 res = snprintf(ptr, size, "\004\001O"); 00419 size -= res; 00420 ptr += res; 00421 } else if (flags & CID_PRIVATE_NUMBER) { 00422 /* Indicate number is private */ 00423 res = snprintf(ptr, size, "\004\001P"); 00424 size -= res; 00425 ptr += res; 00426 } else { 00427 /* Send up to 16 digits of number MAX */ 00428 i = strlen(number); 00429 if (i > 16) i = 16; 00430 res = snprintf(ptr, size, "\002%c", i); 00431 size -= res; 00432 ptr += res; 00433 for (x=0;x<i;x++) 00434 ptr[x] = number[x]; 00435 ptr[i] = '\0'; 00436 ptr += i; 00437 size -= i; 00438 } 00439 00440 if (!name || ast_strlen_zero(name) || (flags & CID_UNKNOWN_NAME)) { 00441 /* Indicate name not known */ 00442 res = snprintf(ptr, size, "\010\001O"); 00443 size -= res; 00444 ptr += res; 00445 } else if (flags & CID_PRIVATE_NAME) { 00446 /* Indicate name is private */ 00447 res = snprintf(ptr, size, "\010\001P"); 00448 size -= res; 00449 ptr += res; 00450 } else { 00451 /* Send up to 16 digits of name MAX */ 00452 i = strlen(name); 00453 if (i > 16) i = 16; 00454 res = snprintf(ptr, size, "\007%c", i); 00455 size -= res; 00456 ptr += res; 00457 for (x=0;x<i;x++) 00458 ptr[x] = name[x]; 00459 ptr[i] = '\0'; 00460 ptr += i; 00461 size -= i; 00462 } 00463 return (ptr - msg); 00464 00465 } 00466 00467 int vmwi_generate(unsigned char *buf, int active, int mdmf, int codec) 00468 { 00469 unsigned char msg[256]; 00470 int len=0; 00471 int sum; 00472 int x; 00473 int bytes = 0; 00474 float cr = 1.0; 00475 float ci = 0.0; 00476 float scont = 0.0; 00477 if (mdmf) { 00478 /* MDMF Message waiting */ 00479 msg[len++] = 0x82; 00480 /* Length is 3 */ 00481 msg[len++] = 3; 00482 /* IE is "Message Waiting Parameter" */ 00483 msg[len++] = 0xb; 00484 /* Length of IE is one */ 00485 msg[len++] = 1; 00486 /* Active or not */ 00487 if (active) 00488 msg[len++] = 0xff; 00489 else 00490 msg[len++] = 0x00; 00491 } else { 00492 /* SDMF Message waiting */ 00493 msg[len++] = 0x6; 00494 /* Length is 3 */ 00495 msg[len++] = 3; 00496 if (active) { 00497 msg[len++] = 0x42; 00498 msg[len++] = 0x42; 00499 msg[len++] = 0x42; 00500 } else { 00501 msg[len++] = 0x6f; 00502 msg[len++] = 0x6f; 00503 msg[len++] = 0x6f; 00504 } 00505 } 00506 sum = 0; 00507 for (x=0;x<len;x++) 00508 sum += msg[x]; 00509 sum = (256 - (sum & 255)); 00510 msg[len++] = sum; 00511 /* Wait a half a second */ 00512 for (x=0;x<4000;x++) 00513 PUT_BYTE(0x7f); 00514 /* Transmit 30 0x55's (looks like a square wave) for channel seizure */ 00515 for (x=0;x<30;x++) 00516 PUT_CLID(0x55); 00517 /* Send 170ms of callerid marks */ 00518 for (x=0;x<170;x++) 00519 PUT_CLID_MARKMS; 00520 for (x=0;x<len;x++) { 00521 PUT_CLID(msg[x]); 00522 } 00523 /* Send 50 more ms of marks */ 00524 for (x=0;x<50;x++) 00525 PUT_CLID_MARKMS; 00526 return bytes; 00527 } 00528 00529 int callerid_generate(unsigned char *buf, char *number, char *name, int flags, int callwaiting, int codec) 00530 { 00531 int bytes=0; 00532 int x, sum; 00533 int len; 00534 /* Initial carriers (real/imaginary) */ 00535 float cr = 1.0; 00536 float ci = 0.0; 00537 float scont = 0.0; 00538 unsigned char msg[256]; 00539 len = callerid_genmsg(msg, sizeof(msg), number, name, flags); 00540 if (!callwaiting) { 00541 /* Wait a half a second */ 00542 for (x=0;x<4000;x++) 00543 PUT_BYTE(0x7f); 00544 /* Transmit 30 0x55's (looks like a square wave) for channel seizure */ 00545 for (x=0;x<30;x++) 00546 PUT_CLID(0x55); 00547 } 00548 /* Send 150ms of callerid marks */ 00549 for (x=0;x<150;x++) 00550 PUT_CLID_MARKMS; 00551 /* Send 0x80 indicating MDMF format */ 00552 PUT_CLID(0x80); 00553 /* Put length of whole message */ 00554 PUT_CLID(len); 00555 sum = 0x80 + strlen(msg); 00556 /* Put each character of message and update checksum */ 00557 for (x=0;x<len; x++) { 00558 PUT_CLID(msg[x]); 00559 sum += msg[x]; 00560 } 00561 /* Send 2's compliment of sum */ 00562 PUT_CLID(256 - (sum & 255)); 00563 00564 /* Send 50 more ms of marks */ 00565 for (x=0;x<50;x++) 00566 PUT_CLID_MARKMS; 00567 00568 return bytes; 00569 } 00570 00571 void ast_shrink_phone_number(char *n) 00572 { 00573 int x,y=0; 00574 for (x=0;n[x];x++) 00575 if (!strchr("( )-.", n[x])) 00576 n[y++] = n[x]; 00577 n[y] = '\0'; 00578 } 00579 00580 int ast_isphonenumber(char *n) 00581 { 00582 int x; 00583 if (!n || ast_strlen_zero(n)) 00584 return 0; 00585 for (x=0;n[x];x++) 00586 if (!strchr("0123456789*#+", n[x])) 00587 return 0; 00588 return 1; 00589 } 00590 00591 int ast_callerid_parse(char *instr, char **name, char **location) 00592 { 00593 char *ns, *ne; 00594 char *ls, *le; 00595 char tmp[256]; 00596 /* Try for "name" <location> format or 00597 name <location> format */ 00598 if ((ls = strchr(instr, '<')) && (le = strchr(ls, '>'))) { 00599 /* Found the location */ 00600 *le = '\0'; 00601 *ls = '\0'; 00602 *location = ls + 1; 00603 if ((ns = strchr(instr, '\"')) && (ne = strchr(ns + 1, '\"'))) { 00604 /* Get name out of quotes */ 00605 *ns = '\0'; 00606 *ne = '\0'; 00607 *name = ns + 1; 00608 return 0; 00609 } else { 00610 /* Just trim off any trailing spaces */ 00611 *name = instr; 00612 while(!ast_strlen_zero(instr) && (instr[strlen(instr) - 1] < 33)) 00613 instr[strlen(instr) - 1] = '\0'; 00614 /* And leading spaces */ 00615 while(**name && (**name < 33)) 00616 (*name)++; 00617 return 0; 00618 } 00619 } else { 00620 strncpy(tmp, instr, sizeof(tmp)-1); 00621 ast_shrink_phone_number(tmp); 00622 if (ast_isphonenumber(tmp)) { 00623 /* Assume it's just a location */ 00624 *name = NULL; 00625 *location = instr; 00626 } else { 00627 /* Assume it's just a name. Make sure it's not quoted though */ 00628 *name = instr; 00629 while(*(*name) && ((*(*name) < 33) || (*(*name) == '\"'))) (*name)++; 00630 ne = *name + strlen(*name) - 1; 00631 while((ne > *name) && ((*ne < 33) || (*ne == '\"'))) { *ne = '\0'; ne--; } 00632 *location = NULL; 00633 } 00634 return 0; 00635 } 00636 return -1; 00637 } 00638 00639 static int __ast_callerid_generate(unsigned char *buf, char *callerid, int callwaiting, int codec) 00640 { 00641 char tmp[256]; 00642 char *n, *l; 00643 if (!callerid) 00644 return callerid_generate(buf, NULL, NULL, 0, callwaiting, codec); 00645 strncpy(tmp, callerid, sizeof(tmp)-1); 00646 if (ast_callerid_parse(tmp, &n, &l)) { 00647 ast_log(LOG_WARNING, "Unable to parse '%s' into CallerID name & number\n", callerid); 00648 return callerid_generate(buf, NULL, NULL, 0, callwaiting, codec); 00649 } 00650 if (l) 00651 ast_shrink_phone_number(l); 00652 if (!ast_isphonenumber(l)) 00653 return callerid_generate(buf, NULL, n, 0, callwaiting, codec); 00654 return callerid_generate(buf, l, n, 0, callwaiting, codec); 00655 } 00656 00657 int ast_callerid_generate(unsigned char *buf, char *callerid, int codec) 00658 { 00659 return __ast_callerid_generate(buf, callerid, 0, codec); 00660 } 00661 00662 int ast_callerid_callwaiting_generate(unsigned char *buf, char *callerid, int codec) 00663 { 00664 return __ast_callerid_generate(buf, callerid, 1, codec); 00665 }

Generated on Fri Sep 24 21:03:46 2004 for Asterisk by doxygen 1.3.8