00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
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 <asterisk/ulaw.h>
00024 #include <asterisk/alaw.h>
00025 #include <asterisk/frame.h>
00026 #include <asterisk/callerid.h>
00027 #include <asterisk/logger.h>
00028 #include <asterisk/fskmodem.h>
00029
00030 struct callerid_state {
00031 fsk_data fskd;
00032 char rawdata[256];
00033 short oldstuff[160];
00034 int oldlen;
00035 int pos;
00036 int type;
00037 int cksum;
00038 char name[64];
00039 char number[64];
00040 int flags;
00041 int sawflag;
00042 int len;
00043 };
00044
00045
00046 float cid_dr[4], cid_di[4];
00047 float clidsb = 8000.0 / 1200.0;
00048 float sasdr, sasdi;
00049 float casdr1, casdi1, casdr2, casdi2;
00050
00051 #define CALLERID_SPACE 2200.0
00052 #define CALLERID_MARK 1200.0
00053 #define SAS_FREQ 440.0
00054 #define CAS_FREQ1 2130.0
00055 #define CAS_FREQ2 2750.0
00056
00057 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)
00058 {
00059 int x;
00060 float t;
00061 for (x=0;x<len;x++) {
00062 t = *cr1 * ddr1 - *ci1 * ddi1;
00063 *ci1 = *cr1 * ddi1 + *ci1 * ddr1;
00064 *cr1 = t;
00065 t = 2.0 - (*cr1 * *cr1 + *ci1 * *ci1);
00066 *cr1 *= t;
00067 *ci1 *= t;
00068
00069 t = *cr2 * ddr2 - *ci2 * ddi2;
00070 *ci2 = *cr2 * ddi2 + *ci2 * ddr2;
00071 *cr2 = t;
00072 t = 2.0 - (*cr2 * *cr2 + *ci2 * *ci2);
00073 *cr2 *= t;
00074 *ci2 *= t;
00075 buf[x] = AST_LIN2X((*cr1 + *cr2) * 8192.0);
00076 }
00077 }
00078
00079 static inline void gen_tone(unsigned char *buf, int len, int codec, float ddr1, float ddi1, float *cr1, float *ci1)
00080 {
00081 int x;
00082 float t;
00083 for (x=0;x<len;x++) {
00084 t = *cr1 * ddr1 - *ci1 * ddi1;
00085 *ci1 = *cr1 * ddi1 + *ci1 * ddr1;
00086 *cr1 = t;
00087 t = 2.0 - (*cr1 * *cr1 + *ci1 * *ci1);
00088 *cr1 *= t;
00089 *ci1 *= t;
00090 buf[x] = AST_LIN2X(*cr1 * 8192.0);
00091 }
00092 }
00093
00094 void callerid_init(void)
00095 {
00096
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 }
00108
00109 struct callerid_state *callerid_new(void)
00110 {
00111 struct callerid_state *cid;
00112 cid = malloc(sizeof(struct callerid_state));
00113 if (cid) {
00114 memset(cid, 0, sizeof(struct callerid_state));
00115 cid->fskd.spb = 7;
00116 cid->fskd.hdlc = 0;
00117 cid->fskd.nbit = 8;
00118 cid->fskd.nstop = 1;
00119 cid->fskd.paridad = 0;
00120 cid->fskd.bw=1;
00121 cid->fskd.f_mark_idx = 2;
00122 cid->fskd.f_space_idx = 3;
00123 cid->fskd.pcola = 0;
00124 cid->fskd.cont = 0;
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 }
00135
00136 void callerid_get(struct callerid_state *cid, char **name, char **number, int *flags)
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 }
00148
00149 int ast_gen_cas(unsigned char *outbuf, int sendsas, int len, int codec)
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 }
00169
00170 int callerid_feed(struct callerid_state *cid, unsigned char *ubuf, int len, int codec)
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
00202 if (b > 0xff)
00203 continue;
00204 switch(cid->sawflag) {
00205 case 0:
00206 if (b == 'U')
00207 cid->sawflag = 2;
00208 break;
00209 case 2:
00210 if ((b == 0x04) || (b == 0x80)) {
00211 cid->type = b;
00212 cid->sawflag = 3;
00213 cid->cksum = b;
00214 }
00215 break;
00216 case 3:
00217
00218 cid->sawflag = 4;
00219 cid->len = b;
00220 cid->pos = 0;
00221 cid->cksum += b;
00222 break;
00223 case 4:
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:
00237 if (b != (256 - (cid->cksum & 0xff))) {
00238 ast_log(LOG_NOTICE, "Caller*ID failed checksum\n");
00239
00240 cid->sawflag = 0;
00241 break;
00242 }
00243
00244 strcpy(cid->number, "");
00245 strcpy(cid->name, "");
00246
00247 if (cid->type == 0x80) {
00248
00249
00250 for (x=0;x< cid->pos;) {
00251 switch(cid->rawdata[x++]) {
00252 case 1:
00253
00254 break;
00255 case 2:
00256 case 3:
00257 case 4:
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
00265 cid->number[res] = '\0';
00266 break;
00267 case 7:
00268 case 8:
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:
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
00287 strncpy(cid->number, cid->rawdata + 8, sizeof(cid->number)-1);
00288 }
00289
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 }
00320
00321 void callerid_free(struct callerid_state *cid)
00322 {
00323 free(cid);
00324 }
00325
00326 static int callerid_genmsg(char *msg, int size, char *number, char *name, int flags)
00327 {
00328 time_t t;
00329 struct tm tm;
00330 char *ptr;
00331 int res;
00332 int i,x;
00333
00334 time(&t);
00335 localtime_r(&t,&tm);
00336
00337 ptr = msg;
00338
00339
00340 res = snprintf(ptr, size, "\001\010%02d%02d%02d%02d", tm.tm_mon + 1,
00341 tm.tm_mday, tm.tm_hour, tm.tm_min);
00342 size -= res;
00343 ptr += res;
00344 if (!number || !strlen(number) || (flags & CID_UNKNOWN_NUMBER)) {
00345
00346 res = snprintf(ptr, size, "\004\001O");
00347 size -= res;
00348 ptr += res;
00349 } else if (flags & CID_PRIVATE_NUMBER) {
00350
00351 res = snprintf(ptr, size, "\004\001P");
00352 size -= res;
00353 ptr += res;
00354 } else {
00355
00356 i = strlen(number);
00357 if (i > 16) i = 16;
00358 res = snprintf(ptr, size, "\002%c", i);
00359 size -= res;
00360 ptr += res;
00361 for (x=0;x<i;x++)
00362 ptr[x] = number[x];
00363 ptr[i] = '\0';
00364 ptr += i;
00365 size -= i;
00366 }
00367
00368 if (!name || !strlen(name) || (flags & CID_UNKNOWN_NAME)) {
00369
00370 res = snprintf(ptr, size, "\010\001O");
00371 size -= res;
00372 ptr += res;
00373 } else if (flags & CID_PRIVATE_NAME) {
00374
00375 res = snprintf(ptr, size, "\010\001P");
00376 size -= res;
00377 ptr += res;
00378 } else {
00379
00380 i = strlen(name);
00381 if (i > 16) i = 16;
00382 res = snprintf(ptr, size, "\007%c", i);
00383 size -= res;
00384 ptr += res;
00385 for (x=0;x<i;x++)
00386 ptr[x] = name[x];
00387 ptr[i] = '\0';
00388 ptr += i;
00389 size -= i;
00390 }
00391 return (ptr - msg);
00392
00393 }
00394
00395 int vmwi_generate(unsigned char *buf, int active, int mdmf, int codec)
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
00407 msg[len++] = 0x82;
00408
00409 msg[len++] = 3;
00410
00411 msg[len++] = 0xb;
00412
00413 msg[len++] = 1;
00414
00415 if (active)
00416 msg[len++] = 0xff;
00417 else
00418 msg[len++] = 0x00;
00419 } else {
00420
00421 msg[len++] = 0x6;
00422
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
00440 for (x=0;x<30;x++)
00441 PUT_CLID(0x55);
00442
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
00449 for (x=0;x<50;x++)
00450 PUT_CLID_MARKMS;
00451 return bytes;
00452 }
00453
00454 int callerid_generate(unsigned char *buf, char *number, char *name, int flags, int callwaiting, int codec)
00455 {
00456 int bytes=0;
00457 int x, sum;
00458 int len;
00459
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
00467 for (x=0;x<4000;x++)
00468 PUT_BYTE(0x7f);
00469
00470 for (x=0;x<30;x++)
00471 PUT_CLID(0x55);
00472 }
00473
00474 for (x=0;x<150;x++)
00475 PUT_CLID_MARKMS;
00476
00477 PUT_CLID(0x80);
00478
00479 PUT_CLID(len);
00480 sum = 0x80 + strlen(msg);
00481
00482 for (x=0;x<len; x++) {
00483 PUT_CLID(msg[x]);
00484 sum += msg[x];
00485 }
00486
00487 PUT_CLID(256 - (sum & 255));
00488
00489
00490 for (x=0;x<50;x++)
00491 PUT_CLID_MARKMS;
00492
00493 return bytes;
00494 }
00495
00496 void ast_shrink_phone_number(char *n)
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 }
00504
00505 int ast_isphonenumber(char *n)
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 }
00515
00516 int ast_callerid_parse(char *instr, char **name, char **location)
00517 {
00518 char *ns, *ne;
00519 char *ls, *le;
00520 char tmp[256];
00521
00522
00523 if ((ls = strchr(instr, '<')) && (le = strchr(ls, '>'))) {
00524
00525 *le = '\0';
00526 *ls = '\0';
00527 *location = ls + 1;
00528 if ((ns = strchr(instr, '\"')) && (ne = strchr(ns + 1, '\"'))) {
00529
00530 *ns = '\0';
00531 *ne = '\0';
00532 *name = ns + 1;
00533 return 0;
00534 } else {
00535
00536 *name = instr;
00537 while(strlen(instr) && (instr[strlen(instr) - 1] < 33))
00538 instr[strlen(instr) - 1] = '\0';
00539
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
00549 *name = NULL;
00550 *location = instr;
00551 } else {
00552
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 }
00563
00564 static int __ast_callerid_generate(unsigned char *buf, char *callerid, int callwaiting, int codec)
00565 {
00566 char tmp[256];
00567 char *n, *l;
00568 if (!callerid)
00569 return callerid_generate(buf, NULL, NULL, 0, callwaiting, codec);
00570 strncpy(tmp, callerid, sizeof(tmp)-1);
00571 if (ast_callerid_parse(tmp, &n, &l)) {
00572 ast_log(LOG_WARNING, "Unable to parse '%s' into CallerID name & number\n", callerid);
00573 return callerid_generate(buf, NULL, NULL, 0, callwaiting, codec);
00574 }
00575 if (l)
00576 ast_shrink_phone_number(l);
00577 if (!ast_isphonenumber(l))
00578 return callerid_generate(buf, NULL, n, 0, callwaiting, codec);
00579 return callerid_generate(buf, l, n, 0, callwaiting, codec);
00580 }
00581
00582 int ast_callerid_generate(unsigned char *buf, char *callerid, int codec)
00583 {
00584 return __ast_callerid_generate(buf, callerid, 0, codec);
00585 }
00586
00587 int ast_callerid_callwaiting_generate(unsigned char *buf, char *callerid, int codec)
00588 {
00589 return __ast_callerid_generate(buf, callerid, 1, codec);
00590 }