00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "asterisk.h"
00027
00028 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 310633 $")
00029
00030 #include <time.h>
00031 #include <string.h>
00032 #include <stdio.h>
00033 #include <stdlib.h>
00034 #include <unistd.h>
00035 #include <math.h>
00036 #include <ctype.h>
00037
00038 #include "asterisk/ulaw.h"
00039 #include "asterisk/alaw.h"
00040 #include "asterisk/frame.h"
00041 #include "asterisk/channel.h"
00042 #include "asterisk/callerid.h"
00043 #include "asterisk/logger.h"
00044 #include "asterisk/fskmodem.h"
00045 #include "asterisk/options.h"
00046 #include "asterisk/utils.h"
00047
00048 struct callerid_state {
00049 fsk_data fskd;
00050 char rawdata[256];
00051 short oldstuff[160];
00052 int oldlen;
00053 int pos;
00054 int type;
00055 int cksum;
00056 char name[64];
00057 char number[64];
00058 int flags;
00059 int sawflag;
00060 int len;
00061
00062 int skipflag;
00063 unsigned short crc;
00064 };
00065
00066
00067 float cid_dr[4], cid_di[4];
00068 float clidsb = 8000.0 / 1200.0;
00069 float sasdr, sasdi;
00070 float casdr1, casdi1, casdr2, casdi2;
00071
00072 #define CALLERID_SPACE 2200.0
00073 #define CALLERID_MARK 1200.0
00074 #define SAS_FREQ 440.0
00075 #define CAS_FREQ1 2130.0
00076 #define CAS_FREQ2 2750.0
00077
00078 #define AST_CALLERID_UNKNOWN "<unknown>"
00079
00080 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)
00081 {
00082 int x;
00083 float t;
00084 for (x=0;x<len;x++) {
00085 t = *cr1 * ddr1 - *ci1 * ddi1;
00086 *ci1 = *cr1 * ddi1 + *ci1 * ddr1;
00087 *cr1 = t;
00088 t = 2.0 - (*cr1 * *cr1 + *ci1 * *ci1);
00089 *cr1 *= t;
00090 *ci1 *= t;
00091
00092 t = *cr2 * ddr2 - *ci2 * ddi2;
00093 *ci2 = *cr2 * ddi2 + *ci2 * ddr2;
00094 *cr2 = t;
00095 t = 2.0 - (*cr2 * *cr2 + *ci2 * *ci2);
00096 *cr2 *= t;
00097 *ci2 *= t;
00098 buf[x] = AST_LIN2X((*cr1 + *cr2) * 2048.0);
00099 }
00100 }
00101
00102 static inline void gen_tone(unsigned char *buf, int len, int codec, float ddr1, float ddi1, float *cr1, float *ci1)
00103 {
00104 int x;
00105 float t;
00106 for (x=0;x<len;x++) {
00107 t = *cr1 * ddr1 - *ci1 * ddi1;
00108 *ci1 = *cr1 * ddi1 + *ci1 * ddr1;
00109 *cr1 = t;
00110 t = 2.0 - (*cr1 * *cr1 + *ci1 * *ci1);
00111 *cr1 *= t;
00112 *ci1 *= t;
00113 buf[x] = AST_LIN2X(*cr1 * 8192.0);
00114 }
00115 }
00116
00117
00118 void callerid_init(void)
00119 {
00120 cid_dr[0] = cos(CALLERID_SPACE * 2.0 * M_PI / 8000.0);
00121 cid_di[0] = sin(CALLERID_SPACE * 2.0 * M_PI / 8000.0);
00122 cid_dr[1] = cos(CALLERID_MARK * 2.0 * M_PI / 8000.0);
00123 cid_di[1] = sin(CALLERID_MARK * 2.0 * M_PI / 8000.0);
00124 sasdr = cos(SAS_FREQ * 2.0 * M_PI / 8000.0);
00125 sasdi = sin(SAS_FREQ * 2.0 * M_PI / 8000.0);
00126 casdr1 = cos(CAS_FREQ1 * 2.0 * M_PI / 8000.0);
00127 casdi1 = sin(CAS_FREQ1 * 2.0 * M_PI / 8000.0);
00128 casdr2 = cos(CAS_FREQ2 * 2.0 * M_PI / 8000.0);
00129 casdi2 = sin(CAS_FREQ2 * 2.0 * M_PI / 8000.0);
00130 }
00131
00132 struct callerid_state *callerid_new(int cid_signalling)
00133 {
00134 struct callerid_state *cid;
00135
00136 if ((cid = ast_calloc(1, sizeof(*cid)))) {
00137 cid->fskd.spb = 7.0;
00138
00139 cid->fskd.nbit = 8;
00140 cid->fskd.nstop = 1.0;
00141
00142 cid->fskd.bw = 1;
00143 if (cid_signalling == 2) {
00144 cid->fskd.f_mark_idx = 4;
00145 cid->fskd.f_space_idx = 5;
00146 } else {
00147 cid->fskd.f_mark_idx = 2;
00148 cid->fskd.f_space_idx = 3;
00149 }
00150
00151
00152
00153
00154 cid->flags = CID_UNKNOWN_NAME | CID_UNKNOWN_NUMBER;
00155
00156 }
00157
00158 return cid;
00159 }
00160
00161 void callerid_get(struct callerid_state *cid, char **name, char **number, int *flags)
00162 {
00163 *flags = cid->flags;
00164 if (cid->flags & (CID_UNKNOWN_NAME | CID_PRIVATE_NAME))
00165 *name = NULL;
00166 else
00167 *name = cid->name;
00168 if (cid->flags & (CID_UNKNOWN_NUMBER | CID_PRIVATE_NUMBER))
00169 *number = NULL;
00170 else
00171 *number = cid->number;
00172 }
00173
00174 void callerid_get_dtmf(char *cidstring, char *number, int *flags)
00175 {
00176 int i;
00177 int code;
00178
00179
00180 number[0] = 0;
00181
00182 if (strlen(cidstring) < 2) {
00183 ast_log(LOG_DEBUG, "No cid detected\n");
00184 *flags = CID_UNKNOWN_NUMBER;
00185 return;
00186 }
00187
00188
00189 if (cidstring[0] == 'B') {
00190
00191 code = atoi(&cidstring[1]);
00192 if (code == 0)
00193 *flags = CID_UNKNOWN_NUMBER;
00194 else if (code == 10)
00195 *flags = CID_PRIVATE_NUMBER;
00196 else
00197 ast_log(LOG_DEBUG, "Unknown DTMF code %d\n", code);
00198 } else if (cidstring[0] == 'D' && cidstring[2] == '#') {
00199
00200 if (cidstring[1] == '1')
00201 *flags = CID_PRIVATE_NUMBER;
00202 if (cidstring[1] == '2' || cidstring[1] == '3')
00203 *flags = CID_UNKNOWN_NUMBER;
00204 } else if (cidstring[0] == 'D' || cidstring[0] == 'A') {
00205
00206 for (i = 1; i < strlen(cidstring); i++ ) {
00207 if (cidstring[i] == 'C' || cidstring[i] == '#')
00208 break;
00209 if (isdigit(cidstring[i]))
00210 number[i-1] = cidstring[i];
00211 else
00212 ast_log(LOG_DEBUG, "Unknown CID digit '%c'\n",
00213 cidstring[i]);
00214 }
00215 number[i-1] = 0;
00216 } else if (isdigit(cidstring[0])) {
00217
00218
00219 ast_log(LOG_WARNING, "Couldn't detect start-character. CID "
00220 "parsing might be unreliable\n");
00221 for (i = 0; i < strlen(cidstring); i++) {
00222 if (isdigit(cidstring[i]))
00223 number[i] = cidstring[i];
00224 else
00225 break;
00226 }
00227 number[i] = 0;
00228 } else {
00229 ast_log(LOG_DEBUG, "Unknown CID protocol, start digit '%c'\n",
00230 cidstring[0]);
00231 *flags = CID_UNKNOWN_NUMBER;
00232 }
00233 }
00234
00235 int ast_gen_cas(unsigned char *outbuf, int sendsas, int len, int codec)
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 if (sendsas) {
00244 if (len < saslen)
00245 return -1;
00246 gen_tone(outbuf, saslen, codec, sasdr, sasdi, &cr1, &ci1);
00247 len -= saslen;
00248 pos += saslen;
00249 cr2 = cr1;
00250 ci2 = ci1;
00251 }
00252 gen_tones(outbuf + pos, len, codec, casdr1, casdi1, casdr2, casdi2, &cr1, &ci1, &cr2, &ci2);
00253 return 0;
00254 }
00255
00256 static unsigned short calc_crc(unsigned short crc, unsigned char data)
00257 {
00258 unsigned int i, j, org, dst;
00259 org = data;
00260 dst = 0;
00261
00262 for (i=0; i < CHAR_BIT; i++) {
00263 org <<= 1;
00264 dst >>= 1;
00265 if (org & 0x100) {
00266 dst |= 0x80;
00267 }
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 }
00279
00280 int callerid_feed_jp(struct callerid_state *cid, unsigned char *ubuf, int len, int codec)
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 short *obuf;
00290
00291 if (!(buf = ast_calloc(1, 2 * len + cid->oldlen))) {
00292 return -1;
00293 }
00294
00295 obuf = buf;
00296 memcpy(buf, cid->oldstuff, cid->oldlen);
00297 mylen += cid->oldlen/2;
00298
00299 for (x=0;x<len;x++)
00300 buf[x+cid->oldlen/2] = AST_XLAW(ubuf[x]);
00301
00302 while (mylen >= 160) {
00303 b = b2 = 0;
00304 olen = mylen;
00305 res = fsk_serie(&cid->fskd, buf, &mylen, &b);
00306
00307 if (mylen < 0) {
00308 ast_log(LOG_ERROR, "No start bit found in fsk data.\n");
00309 free(obuf);
00310 return -1;
00311 }
00312
00313 buf += (olen - mylen);
00314
00315 if (res < 0) {
00316 ast_log(LOG_NOTICE, "fsk_serie failed\n");
00317 free(obuf);
00318 return -1;
00319 }
00320
00321 if (res == 1) {
00322
00323 b2 = b ;
00324 b = b & 0x7f ;
00325
00326
00327 if ( cid->sawflag > 1 ) {
00328 cid->crc = calc_crc(cid->crc, (unsigned char)b2);
00329 }
00330
00331
00332 if (b > 0xff) {
00333 continue;
00334 }
00335
00336
00337 if ( cid->sawflag > 0 ) {
00338 if ( cid->sawflag != 5 && cid->skipflag == 0 && b == 0x10 ) {
00339 cid->skipflag = 1 ;
00340 continue ;
00341 }
00342 }
00343 if ( cid->skipflag == 1 ) {
00344 cid->skipflag = 0 ;
00345 }
00346
00347
00348 switch(cid->sawflag) {
00349 case 0:
00350 if (b == 0x10) {
00351 cid->sawflag = 1;
00352 cid->skipflag = 0;
00353 cid->crc = 0;
00354 }
00355 break;
00356 case 1:
00357 if (b == 0x01) {
00358 cid->sawflag = 2;
00359 }
00360 break ;
00361 case 2:
00362 if (b == 0x07) {
00363 cid->sawflag = 3;
00364 }
00365 break;
00366 case 3:
00367 if (b == 0x02) {
00368 cid->sawflag = 4;
00369 }
00370 break;
00371 case 4:
00372 if (b == 0x40) {
00373 cid->sawflag = 5;
00374 }
00375 break;
00376 case 5:
00377 cid->sawflag = 6;
00378 break;
00379 case 6:
00380 cid->sawflag = 7;
00381 cid->pos = 0;
00382 cid->rawdata[cid->pos++] = b;
00383 break;
00384 case 7:
00385 cid->sawflag = 8;
00386 cid->len = b;
00387 if ( (cid->len+2) >= sizeof( cid->rawdata ) ) {
00388 ast_log(LOG_WARNING, "too long caller id string\n" ) ;
00389 free(obuf);
00390 return -1;
00391 }
00392 cid->rawdata[cid->pos++] = b;
00393 break;
00394 case 8:
00395 cid->rawdata[cid->pos++] = b;
00396 cid->len--;
00397 if (cid->len<=0) {
00398 cid->rawdata[cid->pos] = '\0';
00399 cid->sawflag = 9;
00400 }
00401 break;
00402 case 9:
00403 cid->sawflag = 10;
00404 break;
00405 case 10:
00406 cid->sawflag = 11;
00407 break;
00408 case 11:
00409 cid->sawflag = 12;
00410 if ( cid->crc != 0 ) {
00411 ast_log(LOG_WARNING, "crc checksum error\n" ) ;
00412 free(obuf);
00413 return -1;
00414 }
00415
00416 for (x=0; x<cid->pos; ) {
00417 switch (cid->rawdata[x++]) {
00418 case 0x02:
00419 cid->number[0] = '\0';
00420 cid->name[0] = '\0';
00421 cid->flags = 0;
00422 res = cid->rawdata[x++];
00423 ast_copy_string(cid->number, &cid->rawdata[x], res+1 );
00424 x += res;
00425 break;
00426 case 0x21:
00427
00428 x++;
00429
00430 switch (cid->rawdata[x]) {
00431 case 0x00:
00432 case 0x01:
00433 case 0x02:
00434 case 0x03:
00435 case 0x04:
00436 case 0x06:
00437 case 0x07:
00438 default:
00439 if (option_debug > 1)
00440 ast_log(LOG_DEBUG, "cid info:#1=%X\n", cid->rawdata[x]);
00441 break ;
00442 }
00443 x++;
00444
00445 x++;
00446
00447 switch (cid->rawdata[x]) {
00448 case 0x00:
00449 case 0x01:
00450 case 0x03:
00451 case 0x04:
00452 case 0x08:
00453 case 0x09:
00454 case 0x05:
00455 default:
00456 if (option_debug > 1)
00457 ast_log(LOG_DEBUG, "cid info:#2=%X\n", cid->rawdata[x]);
00458 break ;
00459 }
00460 x++;
00461 break ;
00462 case 0x04:
00463
00464 x++;
00465
00466 switch (cid->rawdata[x]) {
00467 case 'P':
00468 case 'O':
00469 case 'C':
00470 case 'S':
00471 cid->flags |= CID_UNKNOWN_NUMBER;
00472 if (option_debug > 1)
00473 ast_log(LOG_DEBUG, "no cid reason:%c\n",cid->rawdata[x]);
00474 break ;
00475 }
00476 x++;
00477 break ;
00478 case 0x09:
00479
00480 res = cid->rawdata[x++];
00481
00482 x += res;
00483 break ;
00484 case 0x22:
00485
00486 x++;
00487
00488 switch (cid->rawdata[x]) {
00489 case 0x00:
00490 case 0x01:
00491 case 0x02:
00492 case 0x03:
00493 case 0x04:
00494 case 0x06:
00495 case 0x07:
00496 default:
00497 if (option_debug > 1)
00498 ast_log(LOG_NOTICE, "did info:#1=%X\n", cid->rawdata[x]);
00499 break ;
00500 }
00501 x++;
00502
00503 x++;
00504
00505 switch (cid->rawdata[x]) {
00506 case 0x00:
00507 case 0x01:
00508 case 0x03:
00509 case 0x04:
00510 case 0x08:
00511 case 0x09:
00512 case 0x05:
00513 default:
00514 if (option_debug > 1)
00515 ast_log(LOG_DEBUG, "did info:#2=%X\n", cid->rawdata[x]);
00516 break ;
00517 }
00518 x++;
00519 break ;
00520 }
00521 }
00522 free(obuf);
00523 return 1;
00524 break;
00525 default:
00526 ast_log(LOG_ERROR, "invalid value in sawflag %d\n", cid->sawflag);
00527 }
00528 }
00529 }
00530 if (mylen) {
00531 memcpy(cid->oldstuff, buf, mylen * 2);
00532 cid->oldlen = mylen * 2;
00533 } else
00534 cid->oldlen = 0;
00535 free(obuf);
00536 return 0;
00537 }
00538
00539
00540 int callerid_feed(struct callerid_state *cid, unsigned char *ubuf, int len, int codec)
00541 {
00542 int mylen = len;
00543 int olen;
00544 int b = 'X';
00545 int res;
00546 int x;
00547 short *buf;
00548 short *obuf;
00549
00550 if (!(buf = ast_calloc(1, 2 * len + cid->oldlen))) {
00551 return -1;
00552 }
00553
00554 obuf = buf;
00555 memcpy(buf, cid->oldstuff, cid->oldlen);
00556 mylen += cid->oldlen/2;
00557
00558 for (x=0;x<len;x++)
00559 buf[x+cid->oldlen/2] = AST_XLAW(ubuf[x]);
00560 while(mylen >= 160) {
00561 olen = mylen;
00562 res = fsk_serie(&cid->fskd, buf, &mylen, &b);
00563 if (mylen < 0) {
00564 ast_log(LOG_ERROR, "No start bit found in fsk data.\n");
00565 free(obuf);
00566 return -1;
00567 }
00568 buf += (olen - mylen);
00569 if (res < 0) {
00570 ast_log(LOG_NOTICE, "fsk_serie failed\n");
00571 free(obuf);
00572 return -1;
00573 }
00574 if (res == 1) {
00575 if (b > 0xff) {
00576 if (cid->sawflag != 5) {
00577
00578 continue;
00579 }
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589 b &= 0xff;
00590 }
00591 switch(cid->sawflag) {
00592 case 0:
00593 if (b == 'U')
00594 cid->sawflag = 2;
00595 break;
00596 case 2:
00597 if ((b == 0x04) || (b == 0x80)) {
00598 cid->type = b;
00599 cid->sawflag = 3;
00600 cid->cksum = b;
00601 }
00602 break;
00603 case 3:
00604
00605 cid->sawflag = 4;
00606 cid->len = b;
00607 cid->pos = 0;
00608 cid->cksum += b;
00609 break;
00610 case 4:
00611 if (cid->pos >= 128) {
00612 ast_log(LOG_WARNING, "Caller ID too long???\n");
00613 free(obuf);
00614 return -1;
00615 }
00616 cid->rawdata[cid->pos++] = b;
00617 cid->len--;
00618 cid->cksum += b;
00619 if (!cid->len) {
00620 cid->rawdata[cid->pos] = '\0';
00621 cid->sawflag = 5;
00622 }
00623 break;
00624 case 5:
00625 if (b != (256 - (cid->cksum & 0xff))) {
00626 ast_log(LOG_NOTICE, "Caller*ID failed checksum\n");
00627
00628 cid->sawflag = 0;
00629 break;
00630 }
00631
00632 cid->number[0] = '\0';
00633 cid->name[0] = '\0';
00634
00635 if (cid->type == 0x80) {
00636
00637
00638 for (x=0;x< cid->pos;) {
00639 switch(cid->rawdata[x++]) {
00640 case 1:
00641
00642 break;
00643 case 2:
00644 case 3:
00645 case 4:
00646 res = cid->rawdata[x];
00647 if (res > 32) {
00648 ast_log(LOG_NOTICE, "Truncating long caller ID number from %d bytes to 32\n", cid->rawdata[x]);
00649 res = 32;
00650 }
00651 if (ast_strlen_zero(cid->number)) {
00652 memcpy(cid->number, cid->rawdata + x + 1, res);
00653
00654 cid->number[res] = '\0';
00655 }
00656 break;
00657 case 6:
00658 break;
00659 case 7:
00660 case 8:
00661 res = cid->rawdata[x];
00662 if (res > 32) {
00663 ast_log(LOG_NOTICE, "Truncating long caller ID name from %d bytes to 32\n", cid->rawdata[x]);
00664 res = 32;
00665 }
00666 memcpy(cid->name, cid->rawdata + x + 1, res);
00667 cid->name[res] = '\0';
00668 break;
00669 case 17:
00670 case 19:
00671 case 22:
00672 break;
00673 default:
00674 ast_log(LOG_NOTICE, "Unknown IE %d\n", cid->rawdata[x-1]);
00675 }
00676 res = cid->rawdata[x];
00677 if (0 > res){
00678 ast_log(LOG_NOTICE, "IE %d has bad field length of %d at offset %d\n", cid->rawdata[x-1], cid->rawdata[x], x);
00679
00680 cid->sawflag = 0;
00681 break;
00682 }
00683 x += cid->rawdata[x];
00684 x++;
00685 }
00686 } else {
00687
00688 ast_copy_string(cid->number, cid->rawdata + 8, sizeof(cid->number));
00689 }
00690
00691 cid->flags = 0;
00692 if (!strcmp(cid->number, "P")) {
00693 strcpy(cid->number, "");
00694 cid->flags |= CID_PRIVATE_NUMBER;
00695 } else if (!strcmp(cid->number, "O") || ast_strlen_zero(cid->number)) {
00696 strcpy(cid->number, "");
00697 cid->flags |= CID_UNKNOWN_NUMBER;
00698 }
00699 if (!strcmp(cid->name, "P")) {
00700 strcpy(cid->name, "");
00701 cid->flags |= CID_PRIVATE_NAME;
00702 } else if (!strcmp(cid->name, "O") || ast_strlen_zero(cid->name)) {
00703 strcpy(cid->name, "");
00704 cid->flags |= CID_UNKNOWN_NAME;
00705 }
00706 free(obuf);
00707 return 1;
00708 break;
00709 default:
00710 ast_log(LOG_ERROR, "Dunno what to do with a digit in sawflag %d\n", cid->sawflag);
00711 }
00712 }
00713 }
00714 if (mylen) {
00715 memcpy(cid->oldstuff, buf, mylen * 2);
00716 cid->oldlen = mylen * 2;
00717 } else
00718 cid->oldlen = 0;
00719 free(obuf);
00720 return 0;
00721 }
00722
00723 void callerid_free(struct callerid_state *cid)
00724 {
00725 free(cid);
00726 }
00727
00728 static int callerid_genmsg(char *msg, int size, const char *number, const char *name, int flags)
00729 {
00730 time_t t;
00731 struct tm tm;
00732 char *ptr;
00733 int res;
00734 int i,x;
00735
00736 time(&t);
00737 ast_localtime(&t, &tm, NULL);
00738
00739 ptr = msg;
00740
00741
00742 res = snprintf(ptr, size, "\001\010%02d%02d%02d%02d", tm.tm_mon + 1,
00743 tm.tm_mday, tm.tm_hour, tm.tm_min);
00744 size -= res;
00745 ptr += res;
00746 if (ast_strlen_zero(number) || (flags & CID_UNKNOWN_NUMBER)) {
00747
00748 res = snprintf(ptr, size, "\004\001O");
00749 size -= res;
00750 ptr += res;
00751 } else if (flags & CID_PRIVATE_NUMBER) {
00752
00753 res = snprintf(ptr, size, "\004\001P");
00754 size -= res;
00755 ptr += res;
00756 } else {
00757
00758 i = strlen(number);
00759 if (i > 16) i = 16;
00760 res = snprintf(ptr, size, "\002%c", i);
00761 size -= res;
00762 ptr += res;
00763 for (x = 0; x < i; x++)
00764 ptr[x] = number[x];
00765 ptr[i] = '\0';
00766 ptr += i;
00767 size -= i;
00768 }
00769
00770 if (ast_strlen_zero(name) || (flags & CID_UNKNOWN_NAME)) {
00771
00772 res = snprintf(ptr, size, "\010\001O");
00773 size -= res;
00774 ptr += res;
00775 } else if (flags & CID_PRIVATE_NAME) {
00776
00777 res = snprintf(ptr, size, "\010\001P");
00778 size -= res;
00779 ptr += res;
00780 } else {
00781
00782 i = strlen(name);
00783 if (i > 16) i = 16;
00784 res = snprintf(ptr, size, "\007%c", i);
00785 size -= res;
00786 ptr += res;
00787 for (x=0;x<i;x++)
00788 ptr[x] = name[x];
00789 ptr[i] = '\0';
00790 ptr += i;
00791 size -= i;
00792 }
00793 return (ptr - msg);
00794
00795 }
00796
00797 int ast_callerid_vmwi_generate(unsigned char *buf, int active, int mdmf, int codec)
00798 {
00799 unsigned char msg[256];
00800 int len=0;
00801 int sum;
00802 int x;
00803 int bytes = 0;
00804 float cr = 1.0;
00805 float ci = 0.0;
00806 float scont = 0.0;
00807 if (mdmf) {
00808
00809 msg[len++] = 0x82;
00810
00811 msg[len++] = 3;
00812
00813 msg[len++] = 0xb;
00814
00815 msg[len++] = 1;
00816
00817 if (active)
00818 msg[len++] = 0xff;
00819 else
00820 msg[len++] = 0x00;
00821 } else {
00822
00823 msg[len++] = 0x6;
00824
00825 msg[len++] = 3;
00826 if (active) {
00827 msg[len++] = 0x42;
00828 msg[len++] = 0x42;
00829 msg[len++] = 0x42;
00830 } else {
00831 msg[len++] = 0x6f;
00832 msg[len++] = 0x6f;
00833 msg[len++] = 0x6f;
00834 }
00835 }
00836 sum = 0;
00837 for (x=0; x<len; x++)
00838 sum += msg[x];
00839 sum = (256 - (sum & 255));
00840 msg[len++] = sum;
00841
00842 for (x=0; x<4000; x++)
00843 PUT_BYTE(0x7f);
00844
00845 for (x=0; x<30; x++)
00846 PUT_CLID(0x55);
00847
00848 for (x=0; x<170; x++)
00849 PUT_CLID_MARKMS;
00850 for (x=0; x<len; x++) {
00851 PUT_CLID(msg[x]);
00852 }
00853
00854 for (x=0; x<50; x++)
00855 PUT_CLID_MARKMS;
00856 return bytes;
00857 }
00858
00859 int callerid_generate(unsigned char *buf, const char *number, const char *name, int flags, int callwaiting, int codec)
00860 {
00861 int bytes=0;
00862 int x, sum;
00863 int len;
00864
00865
00866 float cr = 1.0;
00867 float ci = 0.0;
00868 float scont = 0.0;
00869 char msg[256];
00870 len = callerid_genmsg(msg, sizeof(msg), number, name, flags);
00871 if (!callwaiting) {
00872
00873 for (x=0; x<4000; x++)
00874 PUT_BYTE(0x7f);
00875
00876 for (x=0; x<30; x++)
00877 PUT_CLID(0x55);
00878 }
00879
00880 for (x=0; x<150; x++)
00881 PUT_CLID_MARKMS;
00882
00883 PUT_CLID(0x80);
00884
00885 PUT_CLID(len);
00886 sum = 0x80 + strlen(msg);
00887
00888 for (x=0; x<len; x++) {
00889 PUT_CLID(msg[x]);
00890 sum += msg[x];
00891 }
00892
00893 PUT_CLID(256 - (sum & 255));
00894
00895
00896 for (x=0; x<50; x++)
00897 PUT_CLID_MARKMS;
00898
00899 return bytes;
00900 }
00901
00902
00903
00904
00905
00906 void ast_shrink_phone_number(char *n)
00907 {
00908 int x, y=0;
00909 int bracketed = 0;
00910
00911 for (x=0; n[x]; x++) {
00912 switch(n[x]) {
00913 case '[':
00914 bracketed++;
00915 n[y++] = n[x];
00916 break;
00917 case ']':
00918 bracketed--;
00919 n[y++] = n[x];
00920 break;
00921 case '-':
00922 if (bracketed)
00923 n[y++] = n[x];
00924 break;
00925 case '.':
00926 if (!n[x+1])
00927 n[y++] = n[x];
00928 break;
00929 default:
00930 if (!strchr("( )", n[x]))
00931 n[y++] = n[x];
00932 }
00933 }
00934 n[y] = '\0';
00935 }
00936
00937
00938
00939
00940
00941
00942 static int ast_is_valid_string(const char *exten, const char *valid)
00943 {
00944 int x;
00945
00946 if (ast_strlen_zero(exten))
00947 return 0;
00948 for (x=0; exten[x]; x++)
00949 if (!strchr(valid, exten[x]))
00950 return 0;
00951 return 1;
00952 }
00953
00954
00955
00956
00957
00958 int ast_isphonenumber(const char *n)
00959 {
00960 return ast_is_valid_string(n, "0123456789*#+");
00961 }
00962
00963
00964
00965
00966
00967
00968 int ast_is_shrinkable_phonenumber(const char *exten)
00969 {
00970 return ast_is_valid_string(exten, "0123456789*#+()-.");
00971 }
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982 int ast_callerid_parse(char *instr, char **name, char **location)
00983 {
00984 char *ns, *ne, *ls, *le;
00985
00986
00987 if ((ls = strrchr(instr, '<')) && (le = strrchr(ls, '>'))) {
00988 *ls = *le = '\0';
00989 *location = ls + 1;
00990 if ((ns = strchr(instr, '"')) && (ne = strchr(ns + 1, '"'))) {
00991 *ns = *ne = '\0';
00992 *name = ns + 1;
00993 } else if (ns) {
00994
00995
00996
00997 if (strchr(le + 1, '\"')) {
00998 *ns = '\0';
00999 *name = ns + 1;
01000 ast_trim_blanks(*name);
01001 } else {
01002 *name = NULL;
01003 }
01004 } else {
01005 *name = ast_skip_blanks(instr);
01006 ast_trim_blanks(*name);
01007 }
01008 } else {
01009 char tmp[256];
01010
01011 ast_copy_string(tmp, instr, sizeof(tmp));
01012 ast_shrink_phone_number(tmp);
01013 if (ast_isphonenumber(tmp)) {
01014 *name = NULL;
01015 strcpy(instr, tmp);
01016 *location = instr;
01017 } else {
01018 *location = NULL;
01019 if ((ns = strchr(instr, '"')) && (ne = strchr(ns + 1, '"'))) {
01020 *ns = *ne = '\0';
01021 *name = ns + 1;
01022 } else {
01023 *name = ast_skip_blanks(instr);
01024 ast_trim_blanks(*name);
01025 }
01026 }
01027 }
01028 return 0;
01029 }
01030
01031 static int __ast_callerid_generate(unsigned char *buf, const char *name, const char *number, int callwaiting, int codec)
01032 {
01033 if (ast_strlen_zero(name))
01034 name = NULL;
01035 if (ast_strlen_zero(number))
01036 number = NULL;
01037 return callerid_generate(buf, number, name, 0, callwaiting, codec);
01038 }
01039
01040 int ast_callerid_generate(unsigned char *buf, const char *name, const char *number, int codec)
01041 {
01042 return __ast_callerid_generate(buf, name, number, 0, codec);
01043 }
01044
01045 int ast_callerid_callwaiting_generate(unsigned char *buf, const char *name, const char *number, int codec)
01046 {
01047 return __ast_callerid_generate(buf, name, number, 1, codec);
01048 }
01049
01050 char *ast_callerid_merge(char *buf, int bufsiz, const char *name, const char *num, const char *unknown)
01051 {
01052 if (!unknown)
01053 unknown = "<unknown>";
01054 if (name && num)
01055 snprintf(buf, bufsiz, "\"%s\" <%s>", name, num);
01056 else if (name)
01057 ast_copy_string(buf, name, bufsiz);
01058 else if (num)
01059 ast_copy_string(buf, num, bufsiz);
01060 else
01061 ast_copy_string(buf, unknown, bufsiz);
01062 return buf;
01063 }
01064
01065 int ast_callerid_split(const char *buf, char *name, int namelen, char *num, int numlen)
01066 {
01067 char *tmp;
01068 char *l = NULL, *n = NULL;
01069
01070 tmp = ast_strdupa(buf);
01071 ast_callerid_parse(tmp, &n, &l);
01072 if (n)
01073 ast_copy_string(name, n, namelen);
01074 else
01075 name[0] = '\0';
01076 if (l) {
01077 ast_shrink_phone_number(l);
01078 ast_copy_string(num, l, numlen);
01079 } else
01080 num[0] = '\0';
01081 return 0;
01082 }
01083
01084
01085 static struct {
01086 int val;
01087 char *name;
01088 char *description;
01089 } pres_types[] = {
01090 { AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED, "allowed_not_screened", "Presentation Allowed, Not Screened"},
01091 { AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, "allowed_passed_screen", "Presentation Allowed, Passed Screen"},
01092 { AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN, "allowed_failed_screen", "Presentation Allowed, Failed Screen"},
01093 { AST_PRES_ALLOWED_NETWORK_NUMBER, "allowed", "Presentation Allowed, Network Number"},
01094 { AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED, "prohib_not_screened", "Presentation Prohibited, Not Screened"},
01095 { AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN, "prohib_passed_screen", "Presentation Prohibited, Passed Screen"},
01096 { AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN, "prohib_failed_screen", "Presentation Prohibited, Failed Screen"},
01097 { AST_PRES_PROHIB_NETWORK_NUMBER, "prohib", "Presentation Prohibited, Network Number"},
01098 { AST_PRES_NUMBER_NOT_AVAILABLE, "unavailable", "Number Unavailable"},
01099 };
01100
01101
01102
01103
01104
01105
01106 int ast_parse_caller_presentation(const char *data)
01107 {
01108 int i;
01109
01110 if (!data) {
01111 return -1;
01112 }
01113
01114 for (i = 0; i < ((sizeof(pres_types) / sizeof(pres_types[0]))); i++) {
01115 if (!strcasecmp(pres_types[i].name, data))
01116 return pres_types[i].val;
01117 }
01118
01119 return -1;
01120 }
01121
01122
01123
01124
01125
01126 const char *ast_describe_caller_presentation(int data)
01127 {
01128 int i;
01129
01130 for (i = 0; i < ((sizeof(pres_types) / sizeof(pres_types[0]))); i++) {
01131 if (pres_types[i].val == data)
01132 return pres_types[i].description;
01133 }
01134
01135 return "unknown";
01136 }