From 7e8b1a03892198f1c9b02e7e065b65958fafd478 Mon Sep 17 00:00:00 2001 From: Mark Spencer <markster@digium.com> Date: Fri, 29 Nov 2002 16:43:28 +0000 Subject: [PATCH] Version 0.3.0 from FTP git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@558 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- callerid.c | 185 ++++++++++++++++++++++++++++-------- include/asterisk/callerid.h | 23 +++-- 2 files changed, 160 insertions(+), 48 deletions(-) diff --git a/callerid.c b/callerid.c index 898396d861..f1827b76be 100755 --- a/callerid.c +++ b/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); } diff --git a/include/asterisk/callerid.h b/include/asterisk/callerid.h index 6d77e19ceb..8f8df457f5 100755 --- a/include/asterisk/callerid.h +++ b/include/asterisk/callerid.h @@ -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) -- GitLab