@ -21,12 +21,11 @@
# include <unistd.h>
# include <unistd.h>
# include <math.h>
# include <math.h>
# include <asterisk/ulaw.h>
# include <asterisk/ulaw.h>
# include <asterisk/alaw.h>
# include <asterisk/frame.h>
# include <asterisk/callerid.h>
# include <asterisk/callerid.h>
# include <asterisk/logger.h>
# include <asterisk/logger.h>
# include <asterisk/fskmodem.h>
# include <asterisk/fskmodem.h>
# include "sas.h"
# include "cas.h"
struct callerid_state {
struct callerid_state {
fsk_data fskd ;
fsk_data fskd ;
@ -46,9 +45,51 @@ struct callerid_state {
float cid_dr [ 4 ] , cid_di [ 4 ] ;
float cid_dr [ 4 ] , cid_di [ 4 ] ;
float clidsb = 8000.0 / 1200.0 ;
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_SPACE 2200.0 /* 2200 hz for "0" */
# define CALLERID_MARK 1200.0 /* 1200 hz for "1" */
# 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 )
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_di [ 0 ] = sin ( CALLERID_SPACE * 2.0 * M_PI / 8000.0 ) ;
cid_dr [ 1 ] = cos ( CALLERID_MARK * 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 ) ;
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 )
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 ;
* 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 pos = 0 ;
int cnt ;
int saslen = 2400 ;
int saslen = 2400 ;
float cr1 = 1.0 ;
float ci1 = 0.0 ;
float cr2 = 1.0 ;
float ci2 = 0.0 ;
if ( sendsas ) {
if ( sendsas ) {
if ( len < saslen )
if ( len < saslen )
return - 1 ;
return - 1 ;
while ( saslen ) {
gen_tone ( outbuf , saslen , codec , sasdr , sasdi , & cr1 , & ci1 ) ;
cnt = saslen ;
len - = saslen ;
if ( cnt > sizeof ( sas ) )
pos + = saslen ;
cnt = sizeof ( sas ) ;
cr2 = cr1 ;
memcpy ( outbuf + pos , sas , cnt ) ;
ci2 = ci1 ;
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_tones ( outbuf + pos , len , codec , casdr1 , casdi1 , casdr2 , casdi2 , & cr1 , & ci1 , & cr2 , & ci2 ) ;
return 0 ;
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 mylen = len ;
int olen ;
int olen ;
@ -145,7 +184,7 @@ int callerid_feed(struct callerid_state *cid, unsigned char *ubuf, int len)
memcpy ( buf , cid - > oldstuff , cid - > oldlen ) ;
memcpy ( buf , cid - > oldstuff , cid - > oldlen ) ;
mylen + = cid - > oldlen / 2 ;
mylen + = cid - > oldlen / 2 ;
for ( x = 0 ; x < len ; x + + )
for ( x = 0 ; x < len ; x + + )
buf [ x + cid - > oldlen / 2 ] = AST_ MU LAW( ubuf [ x ] ) ;
buf [ x + cid - > oldlen / 2 ] = AST_ X LAW( ubuf [ x ] ) ;
while ( mylen > = 80 ) {
while ( mylen > = 80 ) {
olen = mylen ;
olen = mylen ;
res = fsk_serie ( & cid - > fskd , buf , & mylen , & b ) ;
res = fsk_serie ( & cid - > fskd , buf , & mylen , & b ) ;
@ -282,7 +321,7 @@ void callerid_free(struct callerid_state *cid)
free ( 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 ;
time_t t ;
struct tm * tm ;
struct tm * tm ;
@ -311,9 +350,9 @@ static void callerid_genmsg(char *msg, int size, char *number, char *name, int f
size - = res ;
size - = res ;
ptr + = res ;
ptr + = res ;
} else {
} else {
/* Send up to 1 0 digits of number MAX */
/* Send up to 1 6 digits of number MAX */
i = strlen ( number ) ;
i = strlen ( number ) ;
if ( i > 1 0) i = 10 ;
if ( i > 1 6) i = 16 ;
res = snprintf ( ptr , size , " \002 %c " , i ) ;
res = snprintf ( ptr , size , " \002 %c " , i ) ;
size - = res ;
size - = res ;
ptr + = res ;
ptr + = res ;
@ -335,7 +374,7 @@ static void callerid_genmsg(char *msg, int size, char *number, char *name, int f
size - = res ;
size - = res ;
ptr + = res ;
ptr + = res ;
} else {
} else {
/* Send up to 1 0 digits of number MAX */
/* Send up to 1 6 digits of name MAX */
i = strlen ( name ) ;
i = strlen ( name ) ;
if ( i > 16 ) i = 16 ;
if ( i > 16 ) i = 16 ;
res = snprintf ( ptr , size , " \007 %c " , i ) ;
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 ;
ptr + = i ;
size - = i ;
size - = i ;
}
}
return ( ptr - msg ) ;
}
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 callerid_generate ( unsigned char * buf , char * number , char * name , int flags , int callwaiting , int codec )
{
{
int bytes = 0 ;
int bytes = 0 ;
int x , sum ;
int x , sum ;
int len ;
/* Initial carriers (real/imaginary) */
/* Initial carriers (real/imaginary) */
float cr = 1.0 ;
float cr = 1.0 ;
float ci = 0.0 ;
float ci = 0.0 ;
float scont = 0.0 ;
float scont = 0.0 ;
char msg [ 256 ] ;
unsigned char msg [ 256 ] ;
callerid_genmsg ( msg , sizeof ( msg ) , number , name , flags ) ;
len = callerid_genmsg ( msg , sizeof ( msg ) , number , name , flags ) ;
if ( ! callwaiting ) {
if ( ! callwaiting ) {
/* Wait a half a second */
/* Wait a half a second */
for ( x = 0 ; x < 4000 ; x + + )
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 */
/* Send 0x80 indicating MDMF format */
PUT_CLID ( 0x80 ) ;
PUT_CLID ( 0x80 ) ;
/* Put length of whole message */
/* Put length of whole message */
PUT_CLID ( strlen ( msg ) ) ;
PUT_CLID ( len ) ;
sum = 0x80 + strlen ( msg ) ;
sum = 0x80 + strlen ( msg ) ;
/* Put each character of message and update checksum */
/* 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 ] ) ;
PUT_CLID ( msg [ x ] ) ;
sum + = msg [ x ] ;
sum + = msg [ x ] ;
}
}
/* Send 2's compliment of sum */
/* Send 2's compliment of sum */
PUT_CLID ( 256 - ( sum & 255 ) ) ;
PUT_CLID ( 256 - ( sum & 255 ) ) ;
/* Send 50 more ms of marks */
/* Send 50 more ms of marks */
for ( x = 0 ; x < 50 ; x + + )
for ( x = 0 ; x < 50 ; x + + )
PUT_CLID_MARKMS ;
PUT_CLID_MARKMS ;
@ -455,30 +556,30 @@ int ast_callerid_parse(char *instr, char **name, char **location)
return - 1 ;
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 tmp [ 256 ] ;
char * n , * l ;
char * n , * l ;
if ( ! callerid )
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 ) ;
strncpy ( tmp , callerid , sizeof ( tmp ) - 1 ) ;
if ( ast_callerid_parse ( tmp , & n , & l ) ) {
if ( ast_callerid_parse ( tmp , & n , & l ) ) {
ast_log ( LOG_WARNING , " Unable to parse '%s' into CallerID name & number \n " , callerid ) ;
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 )
if ( l )
ast_shrink_phone_number ( l ) ;
ast_shrink_phone_number ( l ) ;
if ( ! ast_isphonenumber ( l ) )
if ( ! ast_isphonenumber ( l ) )
return callerid_generate ( buf , NULL , n , 0 , callwaiting );
return callerid_generate ( buf , NULL , n , 0 , callwaiting , codec );
return callerid_generate ( buf , l , n , 0 , callwaiting );
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 );
}
}