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. |
1.3.4