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
#include <asterisk/utils.h>
00030
00031 struct callerid_state {
00032 fsk_data fskd;
00033 char rawdata[256];
00034 short oldstuff[160];
00035 int oldlen;
00036 int pos;
00037 int type;
00038 int cksum;
00039 char name[64];
00040 char number[64];
00041 int flags;
00042 int sawflag;
00043 int len;
00044 };
00045
00046
00047 float cid_dr[4],
cid_di[4];
00048 float clidsb = 8000.0 / 1200.0;
00049 float sasdr,
sasdi;
00050 float casdr1,
casdi1,
casdr2,
casdi2;
00051
00052 #define CALLERID_SPACE 2200.0
00053 #define CALLERID_MARK 1200.0
00054 #define SAS_FREQ 440.0
00055 #define CAS_FREQ1 2130.0
00056 #define CAS_FREQ2 2750.0
00057
00058
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)
00059 {
00060
int x;
00061
float t;
00062
for (x=0;x<len;x++) {
00063 t = *cr1 * ddr1 - *ci1 * ddi1;
00064 *ci1 = *cr1 * ddi1 + *ci1 * ddr1;
00065 *cr1 = t;
00066 t = 2.0 - (*cr1 * *cr1 + *ci1 * *ci1);
00067 *cr1 *= t;
00068 *ci1 *= t;
00069
00070 t = *cr2 * ddr2 - *ci2 * ddi2;
00071 *ci2 = *cr2 * ddi2 + *ci2 * ddr2;
00072 *cr2 = t;
00073 t = 2.0 - (*cr2 * *cr2 + *ci2 * *ci2);
00074 *cr2 *= t;
00075 *ci2 *= t;
00076 buf[x] =
AST_LIN2X((*cr1 + *cr2) * 8192.0);
00077 }
00078 }
00079
00080
static inline void gen_tone(
unsigned char *buf,
int len,
int codec,
float ddr1,
float ddi1,
float *cr1,
float *ci1)
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 buf[x] =
AST_LIN2X(*cr1 * 8192.0);
00092 }
00093 }
00094
00095 void callerid_init(
void)
00096 {
00097
00098
cid_dr[0] = cos(
CALLERID_SPACE * 2.0 * M_PI / 8000.0);
00099
cid_di[0] = sin(
CALLERID_SPACE * 2.0 * M_PI / 8000.0);
00100
cid_dr[1] = cos(
CALLERID_MARK * 2.0 * M_PI / 8000.0);
00101
cid_di[1] = sin(
CALLERID_MARK * 2.0 * M_PI / 8000.0);
00102
sasdr = cos(
SAS_FREQ * 2.0 * M_PI / 8000.0);
00103
sasdi = sin(
SAS_FREQ * 2.0 * M_PI / 8000.0);
00104
casdr1 = cos(
CAS_FREQ1 * 2.0 * M_PI / 8000.0);
00105
casdi1 = sin(
CAS_FREQ1 * 2.0 * M_PI / 8000.0);
00106
casdr2 = cos(
CAS_FREQ2 * 2.0 * M_PI / 8000.0);
00107
casdi2 = sin(
CAS_FREQ2 * 2.0 * M_PI / 8000.0);
00108 }
00109
00110 struct callerid_state *
callerid_new(
void)
00111 {
00112
struct callerid_state *cid;
00113 cid =
malloc(
sizeof(
struct callerid_state));
00114
if (cid) {
00115 memset(cid, 0,
sizeof(
struct callerid_state));
00116 cid->fskd.spb = 7;
00117 cid->fskd.hdlc = 0;
00118 cid->fskd.nbit = 8;
00119 cid->fskd.nstop = 1;
00120 cid->fskd.paridad = 0;
00121 cid->fskd.bw=1;
00122 cid->fskd.f_mark_idx = 2;
00123 cid->fskd.f_space_idx = 3;
00124 cid->fskd.pcola = 0;
00125 cid->fskd.cont = 0;
00126 cid->fskd.x0 = 0.0;
00127 cid->fskd.state = 0;
00128 memset(cid->name, 0,
sizeof(cid->name));
00129 memset(cid->number, 0,
sizeof(cid->number));
00130 cid->flags =
CID_UNKNOWN_NAME |
CID_UNKNOWN_NUMBER;
00131 cid->pos = 0;
00132 }
else
00133
ast_log(
LOG_WARNING,
"Out of memory\n");
00134
return cid;
00135 }
00136
00137 void callerid_get(
struct callerid_state *cid,
char **name,
char **number,
int *flags)
00138 {
00139 *flags = cid->
flags;
00140
if (cid->
flags & (
CID_UNKNOWN_NAME |
CID_PRIVATE_NUMBER))
00141 *name = NULL;
00142
else
00143 *name = cid->
name;
00144
if (cid->
flags & (
CID_UNKNOWN_NUMBER |
CID_PRIVATE_NUMBER))
00145 *number = NULL;
00146
else
00147 *number = cid->
number;
00148 }
00149
00150 int ast_gen_cas(
unsigned char *outbuf,
int sendsas,
int len,
int codec)
00151 {
00152
int pos = 0;
00153
int saslen=2400;
00154
float cr1 = 1.0;
00155
float ci1 = 0.0;
00156
float cr2 = 1.0;
00157
float ci2 = 0.0;
00158
if (sendsas) {
00159
if (len < saslen)
00160
return -1;
00161 gen_tone(outbuf, saslen, codec,
sasdr,
sasdi, &cr1, &ci1);
00162 len -= saslen;
00163 pos += saslen;
00164 cr2 = cr1;
00165 ci2 = ci1;
00166 }
00167 gen_tones(outbuf + pos, len, codec,
casdr1,
casdi1,
casdr2,
casdi2, &cr1, &ci1, &cr2, &ci2);
00168
return 0;
00169 }
00170
00171 int callerid_feed(
struct callerid_state *cid,
unsigned char *ubuf,
int len,
int codec)
00172 {
00173
int mylen = len;
00174
int olen;
00175
int b =
'X';
00176
int res;
00177
int x;
00178
short *buf =
malloc(2 * len + cid->
oldlen);
00179
short *obuf = buf;
00180
if (!buf) {
00181
ast_log(
LOG_WARNING,
"Out of memory\n");
00182
return -1;
00183 }
00184 memset(buf, 0, 2 * len + cid->
oldlen);
00185 memcpy(buf, cid->
oldstuff, cid->
oldlen);
00186 mylen += cid->
oldlen/2;
00187
for (x=0;x<len;x++)
00188 buf[x+cid->
oldlen/2] =
AST_XLAW(ubuf[x]);
00189
while(mylen >= 80) {
00190 olen = mylen;
00191 res =
fsk_serie(&cid->
fskd, buf, &mylen, &b);
00192
if (mylen < 0) {
00193
ast_log(
LOG_ERROR,
"fsk_serie made mylen < 0 (%d)\n", mylen);
00194
return -1;
00195 }
00196 buf += (olen - mylen);
00197
if (res < 0) {
00198
ast_log(
LOG_NOTICE,
"fsk_serie failed\n");
00199
return -1;
00200 }
00201
if (res == 1) {
00202
00203
if (b > 0xff)
00204
continue;
00205
switch(cid->
sawflag) {
00206
case 0:
00207
if (b ==
'U')
00208 cid->
sawflag = 2;
00209
break;
00210
case 2:
00211
if ((b == 0x04) || (b == 0x80)) {
00212 cid->
type = b;
00213 cid->
sawflag = 3;
00214 cid->
cksum = b;
00215 }
00216
break;
00217
case 3:
00218
00219 cid->
sawflag = 4;
00220 cid->
len = b;
00221 cid->
pos = 0;
00222 cid->
cksum += b;
00223
break;
00224
case 4:
00225
if (cid->
pos >= 128) {
00226
ast_log(
LOG_WARNING,
"Caller ID too long???\n");
00227
return -1;
00228 }
00229 cid->
rawdata[cid->
pos++] = b;
00230 cid->
len--;
00231 cid->
cksum += b;
00232
if (!cid->
len) {
00233 cid->
rawdata[cid->
pos] =
'\0';
00234 cid->
sawflag = 5;
00235 }
00236
break;
00237
case 5:
00238
if (b != (256 - (cid->
cksum & 0xff))) {
00239
ast_log(
LOG_NOTICE,
"Caller*ID failed checksum\n");
00240
00241 cid->
sawflag = 0;
00242
break;
00243 }
00244
00245 strcpy(cid->
number,
"");
00246 strcpy(cid->
name,
"");
00247
00248
if (cid->
type == 0x80) {
00249
00250
00251
for (x=0;x< cid->
pos;) {
00252
switch(cid->
rawdata[x++]) {
00253
case 1:
00254
00255
break;
00256
case 2:
00257
case 3:
00258
case 4:
00259 res = cid->
rawdata[x];
00260
if (res > 32) {
00261
ast_log(
LOG_NOTICE,
"Truncating long caller ID number from %d bytes to 32\n", cid->
rawdata[x]);
00262 res = 32;
00263 }
00264 memcpy(cid->
number, cid->
rawdata + x + 1, res);
00265
00266 cid->
number[res] =
'\0';
00267
break;
00268
case 7:
00269
case 8:
00270 res = cid->
rawdata[x];
00271
if (res > 32) {
00272
ast_log(
LOG_NOTICE,
"Truncating long caller ID name from %d bytes to 32\n", cid->
rawdata[x]);
00273 res = 32;
00274 }
00275 memcpy(cid->
name, cid->
rawdata + x + 1, res);
00276 cid->
name[res] =
'\0';
00277
break;
00278
case 22:
00279
break;
00280
default:
00281
ast_log(
LOG_NOTICE,
"Unknown IE %d\n", cid->
rawdata[x-1]);
00282 }
00283 x += cid->
rawdata[x];
00284 x++;
00285 }
00286 }
else {
00287
00288 strncpy(cid->
number, cid->
rawdata + 8,
sizeof(cid->
number)-1);
00289 }
00290
00291 cid->
flags = 0;
00292
if (!strcmp(cid->
number,
"P")) {
00293 strcpy(cid->
number,
"");
00294 cid->
flags |=
CID_PRIVATE_NUMBER;
00295 }
else if (!strcmp(cid->
number,
"O") || ast_strlen_zero(cid->
number)) {
00296 strcpy(cid->
number,
"");
00297 cid->
flags |=
CID_UNKNOWN_NUMBER;
00298 }
00299
if (!strcmp(cid->
name,
"P")) {
00300 strcpy(cid->
name,
"");
00301 cid->
flags |=
CID_PRIVATE_NAME;
00302 }
else if (!strcmp(cid->
name,
"O") || ast_strlen_zero(cid->
name)) {
00303 strcpy(cid->
name,
"");
00304 cid->
flags |=
CID_UNKNOWN_NAME;
00305 }
00306
return 1;
00307
break;
00308
default:
00309
ast_log(
LOG_ERROR,
"Dunno what to do with a digit in sawflag %d\n", cid->
sawflag);
00310 }
00311 }
00312 }
00313
if (mylen) {
00314 memcpy(cid->
oldstuff, buf, mylen * 2);
00315 cid->
oldlen = mylen * 2;
00316 }
else
00317 cid->
oldlen = 0;
00318
free(obuf);
00319
return 0;
00320 }
00321
00322 void callerid_free(
struct callerid_state *cid)
00323 {
00324
free(cid);
00325 }
00326
00327
static int callerid_genmsg(
char *msg,
int size,
char *number,
char *name,
int flags)
00328 {
00329 time_t t;
00330
struct tm tm;
00331
char *ptr;
00332
int res;
00333
int i,x;
00334
00335 time(&t);
00336 localtime_r(&t,&tm);
00337
00338 ptr = msg;
00339
00340
00341 res = snprintf(ptr, size,
"\001\010%02d%02d%02d%02d", tm.tm_mon + 1,
00342 tm.tm_mday, tm.tm_hour, tm.tm_min);
00343 size -= res;
00344 ptr += res;
00345
if (!number || ast_strlen_zero(number) || (flags &
CID_UNKNOWN_NUMBER)) {
00346
00347 res = snprintf(ptr, size,
"\004\001O");
00348 size -= res;
00349 ptr += res;
00350 }
else if (flags &
CID_PRIVATE_NUMBER) {
00351
00352 res = snprintf(ptr, size,
"\004\001P");
00353 size -= res;
00354 ptr += res;
00355 }
else {
00356
00357 i = strlen(number);
00358
if (i > 16) i = 16;
00359 res = snprintf(ptr, size,
"\002%c", i);
00360 size -= res;
00361 ptr += res;
00362
for (x=0;x<i;x++)
00363 ptr[x] = number[x];
00364 ptr[i] =
'\0';
00365 ptr += i;
00366 size -= i;
00367 }
00368
00369
if (!name || ast_strlen_zero(name) || (flags &
CID_UNKNOWN_NAME)) {
00370
00371 res = snprintf(ptr, size,
"\010\001O");
00372 size -= res;
00373 ptr += res;
00374 }
else if (flags &
CID_PRIVATE_NAME) {
00375
00376 res = snprintf(ptr, size,
"\010\001P");
00377 size -= res;
00378 ptr += res;
00379 }
else {
00380
00381 i = strlen(name);
00382
if (i > 16) i = 16;
00383 res = snprintf(ptr, size,
"\007%c", i);
00384 size -= res;
00385 ptr += res;
00386
for (x=0;x<i;x++)
00387 ptr[x] = name[x];
00388 ptr[i] =
'\0';
00389 ptr += i;
00390 size -= i;
00391 }
00392
return (ptr - msg);
00393
00394 }
00395
00396 int vmwi_generate(
unsigned char *buf,
int active,
int mdmf,
int codec)
00397 {
00398
unsigned char msg[256];
00399
int len=0;
00400
int sum;
00401
int x;
00402
int bytes = 0;
00403
float cr = 1.0;
00404
float ci = 0.0;
00405
float scont = 0.0;
00406
if (mdmf) {
00407
00408 msg[len++] = 0x82;
00409
00410 msg[len++] = 3;
00411
00412 msg[len++] = 0xb;
00413
00414 msg[len++] = 1;
00415
00416
if (active)
00417 msg[len++] = 0xff;
00418
else
00419 msg[len++] = 0x00;
00420 }
else {
00421
00422 msg[len++] = 0x6;
00423
00424 msg[len++] = 3;
00425
if (active) {
00426 msg[len++] = 0x42;
00427 msg[len++] = 0x42;
00428 msg[len++] = 0x42;
00429 }
else {
00430 msg[len++] = 0x6f;
00431 msg[len++] = 0x6f;
00432 msg[len++] = 0x6f;
00433 }
00434 }
00435 sum = 0;
00436
for (x=0;x<len;x++)
00437 sum += msg[x];
00438 sum = (256 - (sum & 255));
00439 msg[len++] = sum;
00440
00441
for (x=0;x<4000;x++)
00442
PUT_BYTE(0x7f);
00443
00444
for (x=0;x<30;x++)
00445
PUT_CLID(0x55);
00446
00447
for (x=0;x<170;x++)
00448
PUT_CLID_MARKMS;
00449
for (x=0;x<len;x++) {
00450
PUT_CLID(msg[x]);
00451 }
00452
00453
for (x=0;x<50;x++)
00454
PUT_CLID_MARKMS;
00455
return bytes;
00456 }
00457
00458 int callerid_generate(
unsigned char *buf,
char *number,
char *name,
int flags,
int callwaiting,
int codec)
00459 {
00460
int bytes=0;
00461
int x, sum;
00462
int len;
00463
00464
float cr = 1.0;
00465
float ci = 0.0;
00466
float scont = 0.0;
00467
unsigned char msg[256];
00468 len = callerid_genmsg(msg,
sizeof(msg), number, name, flags);
00469
if (!callwaiting) {
00470
00471
for (x=0;x<4000;x++)
00472
PUT_BYTE(0x7f);
00473
00474
for (x=0;x<30;x++)
00475
PUT_CLID(0x55);
00476 }
00477
00478
for (x=0;x<150;x++)
00479
PUT_CLID_MARKMS;
00480
00481
PUT_CLID(0x80);
00482
00483
PUT_CLID(len);
00484 sum = 0x80 + strlen(msg);
00485
00486
for (x=0;x<len; x++) {
00487
PUT_CLID(msg[x]);
00488 sum += msg[x];
00489 }
00490
00491
PUT_CLID(256 - (sum & 255));
00492
00493
00494
for (x=0;x<50;x++)
00495
PUT_CLID_MARKMS;
00496
00497
return bytes;
00498 }
00499
00500 void ast_shrink_phone_number(
char *n)
00501 {
00502
int x,y=0;
00503
for (x=0;n[x];x++)
00504
if (!strchr(
"( )-.", n[x]))
00505 n[y++] = n[x];
00506 n[y] =
'\0';
00507 }
00508
00509 int ast_isphonenumber(
char *n)
00510 {
00511
int x;
00512
if (!n || ast_strlen_zero(n))
00513
return 0;
00514
for (x=0;n[x];x++)
00515
if (!strchr(
"0123456789*#+", n[x]))
00516
return 0;
00517
return 1;
00518 }
00519
00520 int ast_callerid_parse(
char *instr,
char **name,
char **location)
00521 {
00522
char *ns, *ne;
00523
char *ls, *le;
00524
char tmp[256];
00525
00526
00527
if ((ls = strchr(instr,
'<')) && (le = strchr(ls,
'>'))) {
00528
00529 *le =
'\0';
00530 *ls =
'\0';
00531 *location = ls + 1;
00532
if ((ns = strchr(instr,
'\"')) && (ne = strchr(ns + 1,
'\"'))) {
00533
00534 *ns =
'\0';
00535 *ne =
'\0';
00536 *name = ns + 1;
00537
return 0;
00538 }
else {
00539
00540 *name = instr;
00541
while(!ast_strlen_zero(instr) && (instr[strlen(instr) - 1] < 33))
00542 instr[strlen(instr) - 1] =
'\0';
00543
00544
while(**name && (**name < 33))
00545 (*name)++;
00546
return 0;
00547 }
00548 }
else {
00549 strncpy(tmp, instr,
sizeof(tmp)-1);
00550
ast_shrink_phone_number(tmp);
00551
if (
ast_isphonenumber(tmp)) {
00552
00553 *name = NULL;
00554 *location = instr;
00555 }
else {
00556
00557 *name = instr;
00558
while(*(*name) && ((*(*name) < 33) || (*(*name) ==
'\"'))) (*name)++;
00559 ne = *name + strlen(*name) - 1;
00560
while((ne > *name) && ((*ne < 33) || (*ne ==
'\"'))) { *ne =
'\0'; ne--; }
00561 *location = NULL;
00562 }
00563
return 0;
00564 }
00565
return -1;
00566 }
00567
00568
static int __ast_callerid_generate(
unsigned char *buf,
char *callerid,
int callwaiting,
int codec)
00569 {
00570
char tmp[256];
00571
char *n, *l;
00572
if (!callerid)
00573
return callerid_generate(buf, NULL, NULL, 0, callwaiting, codec);
00574 strncpy(tmp, callerid,
sizeof(tmp)-1);
00575
if (
ast_callerid_parse(tmp, &n, &l)) {
00576
ast_log(LOG_WARNING,
"Unable to parse '%s' into CallerID name & number\n", callerid);
00577
return callerid_generate(buf, NULL, NULL, 0, callwaiting, codec);
00578 }
00579
if (l)
00580
ast_shrink_phone_number(l);
00581
if (!
ast_isphonenumber(l))
00582
return callerid_generate(buf, NULL, n, 0, callwaiting, codec);
00583
return callerid_generate(buf, l, n, 0, callwaiting, codec);
00584 }
00585
00586 int ast_callerid_generate(
unsigned char *buf,
char *callerid,
int codec)
00587 {
00588
return __ast_callerid_generate(buf, callerid, 0, codec);
00589 }
00590
00591 int ast_callerid_callwaiting_generate(
unsigned char *buf,
char *callerid,
int codec)
00592 {
00593
return __ast_callerid_generate(buf, callerid, 1, codec);
00594 }