Version 0.3.0 from FTP
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@558 f38db490-d61c-443f-a65b-d21fe96a405b
This commit is contained in:
parent
cc270283b1
commit
909f17e6ca
185
callerid.c
185
callerid.c
|
@ -21,12 +21,11 @@
|
|||
#include <unistd.h>
|
||||
#include <math.h>
|
||||
#include <asterisk/ulaw.h>
|
||||
#include <asterisk/alaw.h>
|
||||
#include <asterisk/frame.h>
|
||||
#include <asterisk/callerid.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/fskmodem.h>
|
||||
#include "sas.h"
|
||||
#include "cas.h"
|
||||
|
||||
|
||||
struct callerid_state {
|
||||
fsk_data fskd;
|
||||
|
@ -46,9 +45,51 @@ struct callerid_state {
|
|||
|
||||
float cid_dr[4], cid_di[4];
|
||||
float clidsb = 8000.0 / 1200.0;
|
||||
float sasdr, sasdi;
|
||||
float casdr1, casdi1, casdr2, casdi2;
|
||||
|
||||
#define CALLERID_SPACE 2200.0 /* 2200 hz for "0" */
|
||||
#define CALLERID_MARK 1200.0 /* 1200 hz for "1" */
|
||||
#define SAS_FREQ 440.0
|
||||
#define CAS_FREQ1 2130.0
|
||||
#define CAS_FREQ2 2750.0
|
||||
|
||||
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)
|
||||
{
|
||||
int x;
|
||||
float t;
|
||||
for (x=0;x<len;x++) {
|
||||
t = *cr1 * ddr1 - *ci1 * ddi1;
|
||||
*ci1 = *cr1 * ddi1 + *ci1 * ddr1;
|
||||
*cr1 = t;
|
||||
t = 2.0 - (*cr1 * *cr1 + *ci1 * *ci1);
|
||||
*cr1 *= t;
|
||||
*ci1 *= t;
|
||||
|
||||
t = *cr2 * ddr2 - *ci2 * ddi2;
|
||||
*ci2 = *cr2 * ddi2 + *ci2 * ddr2;
|
||||
*cr2 = t;
|
||||
t = 2.0 - (*cr2 * *cr2 + *ci2 * *ci2);
|
||||
*cr2 *= t;
|
||||
*ci2 *= t;
|
||||
buf[x] = AST_LIN2X((*cr1 + *cr2) * 8192.0);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void gen_tone(unsigned char *buf, int len, int codec, float ddr1, float ddi1, float *cr1, float *ci1)
|
||||
{
|
||||
int x;
|
||||
float t;
|
||||
for (x=0;x<len;x++) {
|
||||
t = *cr1 * ddr1 - *ci1 * ddi1;
|
||||
*ci1 = *cr1 * ddi1 + *ci1 * ddr1;
|
||||
*cr1 = t;
|
||||
t = 2.0 - (*cr1 * *cr1 + *ci1 * *ci1);
|
||||
*cr1 *= t;
|
||||
*ci1 *= t;
|
||||
buf[x] = AST_LIN2X(*cr1 * 8192.0);
|
||||
}
|
||||
}
|
||||
|
||||
void callerid_init(void)
|
||||
{
|
||||
|
@ -57,6 +98,12 @@ void callerid_init(void)
|
|||
cid_di[0] = sin(CALLERID_SPACE * 2.0 * M_PI / 8000.0);
|
||||
cid_dr[1] = cos(CALLERID_MARK * 2.0 * M_PI / 8000.0);
|
||||
cid_di[1] = sin(CALLERID_MARK * 2.0 * M_PI / 8000.0);
|
||||
sasdr = cos(SAS_FREQ * 2.0 * M_PI / 8000.0);
|
||||
sasdi = sin(SAS_FREQ * 2.0 * M_PI / 8000.0);
|
||||
casdr1 = cos(CAS_FREQ1 * 2.0 * M_PI / 8000.0);
|
||||
casdi1 = sin(CAS_FREQ1 * 2.0 * M_PI / 8000.0);
|
||||
casdr2 = cos(CAS_FREQ2 * 2.0 * M_PI / 8000.0);
|
||||
casdi2 = sin(CAS_FREQ2 * 2.0 * M_PI / 8000.0);
|
||||
}
|
||||
|
||||
struct callerid_state *callerid_new(void)
|
||||
|
@ -99,36 +146,28 @@ void callerid_get(struct callerid_state *cid, char **name, char **number, int *f
|
|||
*number = cid->number;
|
||||
}
|
||||
|
||||
int ast_gen_cas(unsigned char *outbuf, int sendsas, int len)
|
||||
int ast_gen_cas(unsigned char *outbuf, int sendsas, int len, int codec)
|
||||
{
|
||||
int pos = 0;
|
||||
int cnt;
|
||||
int saslen=2400;
|
||||
float cr1 = 1.0;
|
||||
float ci1 = 0.0;
|
||||
float cr2 = 1.0;
|
||||
float ci2 = 0.0;
|
||||
if (sendsas) {
|
||||
if (len < saslen)
|
||||
return -1;
|
||||
while(saslen) {
|
||||
cnt = saslen;
|
||||
if (cnt > sizeof(sas))
|
||||
cnt = sizeof(sas);
|
||||
memcpy(outbuf + pos, sas, cnt);
|
||||
pos += cnt;
|
||||
len -= cnt;
|
||||
saslen -= cnt;
|
||||
}
|
||||
}
|
||||
while(len) {
|
||||
cnt = len;
|
||||
if (cnt > sizeof(cas))
|
||||
cnt = sizeof(cas);
|
||||
memcpy(outbuf + pos, cas, cnt);
|
||||
pos += cnt;
|
||||
len -= cnt;
|
||||
gen_tone(outbuf, saslen, codec, sasdr, sasdi, &cr1, &ci1);
|
||||
len -= saslen;
|
||||
pos += saslen;
|
||||
cr2 = cr1;
|
||||
ci2 = ci1;
|
||||
}
|
||||
gen_tones(outbuf + pos, len, codec, casdr1, casdi1, casdr2, casdi2, &cr1, &ci1, &cr2, &ci2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int callerid_feed(struct callerid_state *cid, unsigned char *ubuf, int len)
|
||||
int callerid_feed(struct callerid_state *cid, unsigned char *ubuf, int len, int codec)
|
||||
{
|
||||
int mylen = len;
|
||||
int olen;
|
||||
|
@ -145,7 +184,7 @@ int callerid_feed(struct callerid_state *cid, unsigned char *ubuf, int len)
|
|||
memcpy(buf, cid->oldstuff, cid->oldlen);
|
||||
mylen += cid->oldlen/2;
|
||||
for (x=0;x<len;x++)
|
||||
buf[x+cid->oldlen/2] = AST_MULAW(ubuf[x]);
|
||||
buf[x+cid->oldlen/2] = AST_XLAW(ubuf[x]);
|
||||
while(mylen >= 80) {
|
||||
olen = mylen;
|
||||
res = fsk_serie(&cid->fskd, buf, &mylen, &b);
|
||||
|
@ -282,7 +321,7 @@ void callerid_free(struct callerid_state *cid)
|
|||
free(cid);
|
||||
}
|
||||
|
||||
static void callerid_genmsg(char *msg, int size, char *number, char *name, int flags)
|
||||
static int callerid_genmsg(char *msg, int size, char *number, char *name, int flags)
|
||||
{
|
||||
time_t t;
|
||||
struct tm *tm;
|
||||
|
@ -311,9 +350,9 @@ static void callerid_genmsg(char *msg, int size, char *number, char *name, int f
|
|||
size -= res;
|
||||
ptr += res;
|
||||
} else {
|
||||
/* Send up to 10 digits of number MAX */
|
||||
/* Send up to 16 digits of number MAX */
|
||||
i = strlen(number);
|
||||
if (i > 10) i = 10;
|
||||
if (i > 16) i = 16;
|
||||
res = snprintf(ptr, size, "\002%c", i);
|
||||
size -= res;
|
||||
ptr += res;
|
||||
|
@ -335,7 +374,7 @@ static void callerid_genmsg(char *msg, int size, char *number, char *name, int f
|
|||
size -= res;
|
||||
ptr += res;
|
||||
} else {
|
||||
/* Send up to 10 digits of number MAX */
|
||||
/* Send up to 16 digits of name MAX */
|
||||
i = strlen(name);
|
||||
if (i > 16) i = 16;
|
||||
res = snprintf(ptr, size, "\007%c", i);
|
||||
|
@ -347,19 +386,80 @@ static void callerid_genmsg(char *msg, int size, char *number, char *name, int f
|
|||
ptr += i;
|
||||
size -= i;
|
||||
}
|
||||
return (ptr - msg);
|
||||
|
||||
}
|
||||
|
||||
int callerid_generate(unsigned char *buf, char *number, char *name, int flags, int callwaiting)
|
||||
int vmwi_generate(unsigned char *buf, int active, int mdmf, int codec)
|
||||
{
|
||||
unsigned char msg[256];
|
||||
int len=0;
|
||||
int sum;
|
||||
int x;
|
||||
int bytes = 0;
|
||||
float cr = 1.0;
|
||||
float ci = 0.0;
|
||||
float scont = 0.0;
|
||||
if (mdmf) {
|
||||
/* MDMF Message waiting */
|
||||
msg[len++] = 0x82;
|
||||
/* Length is 3 */
|
||||
msg[len++] = 3;
|
||||
/* IE is "Message Waiting Parameter" */
|
||||
msg[len++] = 0xb;
|
||||
/* Length of IE is one */
|
||||
msg[len++] = 1;
|
||||
/* Active or not */
|
||||
if (active)
|
||||
msg[len++] = 0xff;
|
||||
else
|
||||
msg[len++] = 0x00;
|
||||
} else {
|
||||
/* SDMF Message waiting */
|
||||
msg[len++] = 0x6;
|
||||
/* Length is 3 */
|
||||
msg[len++] = 3;
|
||||
if (active) {
|
||||
msg[len++] = 0x42;
|
||||
msg[len++] = 0x42;
|
||||
msg[len++] = 0x42;
|
||||
} else {
|
||||
msg[len++] = 0x6f;
|
||||
msg[len++] = 0x6f;
|
||||
msg[len++] = 0x6f;
|
||||
}
|
||||
}
|
||||
sum = 0;
|
||||
for (x=0;x<len;x++)
|
||||
sum += msg[x];
|
||||
sum = (256 - (sum & 255));
|
||||
msg[len++] = sum;
|
||||
/* Transmit 30 0x55's (looks like a square wave) for channel seizure */
|
||||
for (x=0;x<30;x++)
|
||||
PUT_CLID(0x55);
|
||||
/* Send 170ms of callerid marks */
|
||||
for (x=0;x<170;x++)
|
||||
PUT_CLID_MARKMS;
|
||||
for (x=0;x<len;x++) {
|
||||
PUT_CLID(msg[x]);
|
||||
}
|
||||
/* Send 50 more ms of marks */
|
||||
for (x=0;x<50;x++)
|
||||
PUT_CLID_MARKMS;
|
||||
return bytes;
|
||||
}
|
||||
|
||||
int callerid_generate(unsigned char *buf, char *number, char *name, int flags, int callwaiting, int codec)
|
||||
{
|
||||
int bytes=0;
|
||||
int x, sum;
|
||||
int len;
|
||||
/* Initial carriers (real/imaginary) */
|
||||
float cr = 1.0;
|
||||
float ci = 0.0;
|
||||
float scont = 0.0;
|
||||
char msg[256];
|
||||
callerid_genmsg(msg, sizeof(msg), number, name, flags);
|
||||
unsigned char msg[256];
|
||||
len = callerid_genmsg(msg, sizeof(msg), number, name, flags);
|
||||
if (!callwaiting) {
|
||||
/* Wait a half a second */
|
||||
for (x=0;x<4000;x++)
|
||||
|
@ -374,15 +474,16 @@ int callerid_generate(unsigned char *buf, char *number, char *name, int flags, i
|
|||
/* Send 0x80 indicating MDMF format */
|
||||
PUT_CLID(0x80);
|
||||
/* Put length of whole message */
|
||||
PUT_CLID(strlen(msg));
|
||||
PUT_CLID(len);
|
||||
sum = 0x80 + strlen(msg);
|
||||
/* Put each character of message and update checksum */
|
||||
for (x=0;x<strlen(msg); x++) {
|
||||
for (x=0;x<len; x++) {
|
||||
PUT_CLID(msg[x]);
|
||||
sum += msg[x];
|
||||
}
|
||||
/* Send 2's compliment of sum */
|
||||
PUT_CLID(256 - (sum & 255));
|
||||
|
||||
/* Send 50 more ms of marks */
|
||||
for (x=0;x<50;x++)
|
||||
PUT_CLID_MARKMS;
|
||||
|
@ -455,30 +556,30 @@ int ast_callerid_parse(char *instr, char **name, char **location)
|
|||
return -1;
|
||||
}
|
||||
|
||||
static int __ast_callerid_generate(unsigned char *buf, char *callerid, int callwaiting)
|
||||
static int __ast_callerid_generate(unsigned char *buf, char *callerid, int callwaiting, int codec)
|
||||
{
|
||||
char tmp[256];
|
||||
char *n, *l;
|
||||
if (!callerid)
|
||||
return callerid_generate(buf, NULL, NULL, 0, callwaiting);
|
||||
return callerid_generate(buf, NULL, NULL, 0, callwaiting, codec);
|
||||
strncpy(tmp, callerid, sizeof(tmp)-1);
|
||||
if (ast_callerid_parse(tmp, &n, &l)) {
|
||||
ast_log(LOG_WARNING, "Unable to parse '%s' into CallerID name & number\n", callerid);
|
||||
return callerid_generate(buf, NULL, NULL, 0, callwaiting);
|
||||
return callerid_generate(buf, NULL, NULL, 0, callwaiting, codec);
|
||||
}
|
||||
if (l)
|
||||
ast_shrink_phone_number(l);
|
||||
if (!ast_isphonenumber(l))
|
||||
return callerid_generate(buf, NULL, n, 0, callwaiting);
|
||||
return callerid_generate(buf, l, n, 0, callwaiting);
|
||||
return callerid_generate(buf, NULL, n, 0, callwaiting, codec);
|
||||
return callerid_generate(buf, l, n, 0, callwaiting, codec);
|
||||
}
|
||||
|
||||
int ast_callerid_generate(unsigned char *buf, char *callerid)
|
||||
int ast_callerid_generate(unsigned char *buf, char *callerid, int codec)
|
||||
{
|
||||
return __ast_callerid_generate(buf, callerid, 0);
|
||||
return __ast_callerid_generate(buf, callerid, 0, codec);
|
||||
}
|
||||
|
||||
int ast_callerid_callwaiting_generate(unsigned char *buf, char *callerid)
|
||||
int ast_callerid_callwaiting_generate(unsigned char *buf, char *callerid, int codec)
|
||||
{
|
||||
return __ast_callerid_generate(buf, callerid, 1);
|
||||
return __ast_callerid_generate(buf, callerid, 1, codec);
|
||||
}
|
||||
|
|
|
@ -24,6 +24,10 @@
|
|||
#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)))
|
||||
|
||||
|
||||
struct callerid_state;
|
||||
typedef struct callerid_state CIDSTATE;
|
||||
|
||||
|
@ -39,10 +43,11 @@ extern void callerid_init(void);
|
|||
* \param number Use NULL for no number or "P" for "private"
|
||||
* \param name name to be used
|
||||
* \param callwaiting callwaiting flag
|
||||
* \param codec -- either AST_FORMAT_ULAW or AST_FORMAT_ALAW
|
||||
* This function creates a stream of callerid (a callerid spill) data in ulaw format. It returns the size
|
||||
* (in bytes) of the data (if it returns a size of 0, there is probably an error)
|
||||
*/
|
||||
extern int callerid_generate(unsigned char *buf, char *number, char *name, int flags, int callwaiting);
|
||||
extern int callerid_generate(unsigned char *buf, char *number, char *name, int flags, int callwaiting, int codec);
|
||||
|
||||
//! Create a callerID state machine
|
||||
/*!
|
||||
|
@ -56,12 +61,13 @@ extern struct callerid_state *callerid_new(void);
|
|||
* \param cid Which state machine to act upon
|
||||
* \param buffer containing your samples
|
||||
* \param samples number of samples contained within the buffer.
|
||||
* \param codec which codec (AST_FORMAT_ALAW or AST_FORMAT_ULAW)
|
||||
*
|
||||
* Send received audio to the Caller*ID demodulator.
|
||||
* Returns -1 on error, 0 for "needs more samples",
|
||||
* and 1 if the CallerID spill reception is complete.
|
||||
*/
|
||||
extern int callerid_feed(struct callerid_state *cid, unsigned char *ubuf, int samples);
|
||||
extern int callerid_feed(struct callerid_state *cid, unsigned char *ubuf, int samples, int codec);
|
||||
|
||||
//! Extract info out of callerID state machine. Flags are listed above
|
||||
/*!
|
||||
|
@ -89,16 +95,20 @@ extern void callerid_free(struct callerid_state *cid);
|
|||
/*!
|
||||
* \param buf buffer for output samples. See callerid_generate() for details regarding buffer.
|
||||
* \param astcid Asterisk format callerid string, taken from the callerid field of asterisk.
|
||||
* \param codec Asterisk codec (either AST_FORMAT_ALAW or AST_FORMAT_ULAW)
|
||||
*
|
||||
* Acts like callerid_generate except uses an asterisk format callerid string.
|
||||
*/
|
||||
extern int ast_callerid_generate(unsigned char *buf, char *astcid);
|
||||
extern int ast_callerid_generate(unsigned char *buf, char *astcid, int codec);
|
||||
|
||||
//! Generate message waiting indicator
|
||||
extern int vmwi_generate(unsigned char *buf, int active, int mdmf, 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)
|
||||
/*!
|
||||
* See ast_callerid_generate for other details
|
||||
*/
|
||||
extern int ast_callerid_callwaiting_generate(unsigned char *buf, char *astcid);
|
||||
extern int ast_callerid_callwaiting_generate(unsigned char *buf, char *astcid, int codec);
|
||||
|
||||
//! Destructively parse inbuf into name and location (or number)
|
||||
/*!
|
||||
|
@ -115,9 +125,10 @@ extern int ast_callerid_parse(char *instr, char **name, char **location);
|
|||
* \param outbuf Allocated buffer for data. Must be at least 2400 bytes unless no SAS is desired
|
||||
* \param sas Non-zero if CAS should be preceeded by SAS
|
||||
* \param len How many samples to generate.
|
||||
* \param codec Which codec (AST_FORMAT_ALAW or AST_FORMAT_ULAW)
|
||||
* Returns -1 on error (if len is less than 2400), 0 on success.
|
||||
*/
|
||||
extern int ast_gen_cas(unsigned char *outbuf, int sas, int len);
|
||||
extern int ast_gen_cas(unsigned char *outbuf, int sas, int len, int codec);
|
||||
|
||||
//! Shrink a phone number in place to just digits (more accurately it just removes ()'s, .'s, and -'s...
|
||||
/*!
|
||||
|
@ -164,7 +175,7 @@ static inline float callerid_getcarrier(float *cr, float *ci, int bit)
|
|||
|
||||
#define PUT_AUDIO_SAMPLE(y) do { \
|
||||
int index = (short)(rint(8192.0 * (y))); \
|
||||
*(buf++) = AST_LIN2MU(index); \
|
||||
*(buf++) = AST_LIN2X(index); \
|
||||
bytes++; \
|
||||
} while(0)
|
||||
|
||||
|
|
Reference in New Issue