wanpipe/api/libstelephony/PToneDecoder.cpp

286 lines
7.1 KiB
C++

#if defined (__LINUX__)
# include <stdlib.h>
# include <string.h>
# include <memory.h>
#elif defined(__WINDOWS__)
#endif
#include "PToneDecoder.h"
#define DBG_FSK if(0)printf
#define DBG_DTMF if(0)printf
#define MX_CID_LEN 15
PhoneToneDecoder::PhoneToneDecoder(void)
{
rate = 8000;
bufSize = 256;
printf("Init FSK demodulator rate:%d buffer:%zu\n", rate, bufSize);
fskInit = fskEnable = dtmfInit = dtmfEnable = false;
memset(&sink_callback_functions, 0x00, sizeof(sink_callback_functions));
fskData = (fsk_data_state_t*) stel_malloc(sizeof(fsk_data_state_t));
if (fskData == NULL) {
STEL_ERR("Failed to allocate memory (%s:%d)\n", __FUNCTION__,__LINE__);
return;
}
fbuf = (unsigned char*)stel_malloc(bufSize);
if (fbuf == NULL) {
STEL_ERR("Failed to allocate memory (%s:%d)\n", __FUNCTION__,__LINE__);
return;
}
dtmfData = (teletone_dtmf_detect_state_t*) stel_malloc(sizeof(teletone_dtmf_detect_state_t));
if (dtmfData == NULL) {
STEL_ERR("Failed to allocate memory (%s:%d)\n", __FUNCTION__,__LINE__);
return;
}
}
PhoneToneDecoder::~PhoneToneDecoder(void)
{
STEL_FUNC_START();
if (fskData) {
DBG_FSK("Freeing fskData\n");
free(fskData);
}
if (fbuf) {
DBG_FSK("Freeing fbuf\n");
free(fbuf);
}
if (dtmfData) {
DBG_DTMF("Freeing dtmfData\n");
free(dtmfData);
}
STEL_FUNC_END();
}
int PhoneToneDecoder::Init()
{
if (fskData) {
memset(fskData, 0, sizeof(fsk_data_state_t));
} else {
STEL_ERR("Tone Decoder was not initialized (%s:%d)\n", __FUNCTION__,__LINE__);
return -1;
}
if (fbuf) {
memset(fbuf, 0, bufSize);
} else {
STEL_ERR("Tone Decoder was not initialized (%s:%d)\n", __FUNCTION__,__LINE__);
return -1;
}
if (dtmfData) {
memset(dtmfData, 0, sizeof(teletone_dtmf_detect_state_t));
} else {
STEL_ERR("Dtmf Decoder was not initialized (%s:%d)\n", __FUNCTION__,__LINE__);
}
return 0;
}
int PhoneToneDecoder::WaveStreamInputExFSK(int16_t* slinData, int dataLength, int *retvalue)
{
char CallerNumber[22], CallerName[52], DateTime[16];
memset(CallerNumber,0,sizeof(CallerNumber));
memset(CallerName,0,sizeof(CallerName));
memset(DateTime,0,sizeof(DateTime));
if (fsk_demod_feed(fskData, (int16_t*) slinData, dataLength)) {
size_t type, mlen;
char str[128], *sp;
DBG_FSK("Got FSK Data\n");
while(fsk_data_parse(fskData, &type, &sp, &mlen) == 0) {
*(str+mlen) = '\0';
strncpy(str, sp, (++mlen)-1);
my_clean_string(str);
//DBG_FSK("FSK: TYPE:%d LEN:%d VAL [%s]\n", type, mlen, str);
switch(type) {
case MDMF_DATETIME:
strncpy(DateTime, sp, mlen-1);
break;
case MDMF_DDN:
case MDMF_PHONE_NUM:
strncpy(CallerNumber, sp, mlen-1);
break;
case MDMF_NO_NUM:
memset(CallerNumber, 0, sizeof(CallerNumber));
break;
case MDMF_PHONE_NAME:
strncpy(CallerName, sp, mlen-1);
break;
case MDMF_NO_NAME:
memset(CallerName, 0, sizeof(CallerName));
break;
}
}
DBG_FSK("Date:[%s] Name:[%s] Number:[%s]\n", DateTime, CallerName, CallerNumber);
if (sink_callback_functions.OnCallerID) {
sink_callback_functions.OnCallerID(this->callback_obj, CallerName, CallerNumber, "Private", DateTime);
} else {
STEL_ERR("hello: No FSK callback function\n");
}
}
return 0;
}
int PhoneToneDecoder::WaveStreamInputExDtmf(int16_t* slinData, int dataLength, int *retvalue)
{
char digit_str[100] = "";
teletone_dtmf_detect(dtmfData, slinData, dataLength);
teletone_dtmf_get(dtmfData, digit_str, sizeof(digit_str));
if(*digit_str) {
char* p;
int len = strlen(digit_str);
p = digit_str;
//DBG_DTMF("DTMF DETECTED %s\n", digit_str);
while(len--) {
DBG_DTMF("DTMF DIGIT %c\n", *p);
if (sink_callback_functions.OnDTMF) {
sink_callback_functions.OnDTMF(this->callback_obj, *p);
} else {
DBG_DTMF("No DTMF callback function\n");
}
p++;
}
}
return 0;
}
int PhoneToneDecoder::WaveStreamInputEx(char* data, int dataLength, int *retValue)
{
int16_t *slinData = NULL;
int i;
//DBG_FSK("RX data len:%d\n", dataLength);
//STEL_FUNC_START();
if (fskEnable == false && dtmfEnable == false) {
return 0;
}
if (variant.intVal == WFI_CCITT_uLaw_8kHzMono ||
variant.intVal == WFI_CCITT_ALaw_8kHzMono) {
slinData = (int16_t*) stel_malloc(dataLength*2);
if (slinData == NULL) {
STEL_ERR("Failed to alloc mem (%s:%d)\n", __FUNCTION__,__LINE__);
return -1;
}
memset( slinData, 0, dataLength*2 );
if (variant.intVal==WFI_CCITT_uLaw_8kHzMono) {
for(i=0; i<dataLength; i++) {
/* Convert to linear data */
slinData[i] = ulaw_to_linear(data[i]);
}
} else {
/* Convert to linear data */
for(i=0; i<dataLength; i++) {
slinData[i] = alaw_to_linear(data[i]);
}
}
} else {
slinData = (int16_t*) data;
}
if (fskInit == true && fskEnable == true) {
WaveStreamInputExFSK(slinData, dataLength, retValue);
}
if (dtmfInit == true && dtmfEnable == true) {
WaveStreamInputExDtmf(slinData, dataLength, retValue);
}
if (variant.intVal == WFI_CCITT_uLaw_8kHzMono ||
variant.intVal == WFI_CCITT_ALaw_8kHzMono) {
free(slinData);
}
//STEL_FUNC_END();
return 0;
}
void PhoneToneDecoder::SetCallbackFunctions(sink_callback_functions_t *cbf)
{
DBG_FSK("%s(): cbf->OnCallerID: 0x%p\n", __FUNCTION__, cbf->OnCallerID);
DBG_DTMF("%s(): cbf->OnDTMF: 0x%p\n", __FUNCTION__, cbf->OnDTMF);
memcpy(&sink_callback_functions, cbf, sizeof(sink_callback_functions_t));
return;
}
void PhoneToneDecoder::GetCallbackFunctions(sink_callback_functions_t *cbf)
{
memcpy(cbf, &sink_callback_functions, sizeof(sink_callback_functions_t));
return;
}
void PhoneToneDecoder::SetCallbackFunctionsAndObject(sink_callback_functions_t* cbf, void *cbo)
{
DBG_FSK("%s(): cbf->OnCallerID: 0x%p\n", __FUNCTION__, cbf->OnCallerID);
DBG_DTMF("%s(): cbf->OnDTMF: 0x%p\n", __FUNCTION__, cbf->OnDTMF);
memcpy(&sink_callback_functions, cbf, sizeof(sink_callback_functions_t));
callback_obj = cbo;
return;
}
void PhoneToneDecoder::WaveStreamStart(void)
{
if (fsk_demod_init(fskData, rate, fbuf, bufSize)) {
STEL_ERR("Failed to initialize FSK demodulator\n");
} else {
fskInit = true;
}
teletone_dtmf_detect_init(dtmfData, rate);
dtmfInit = true;
return;
}
void PhoneToneDecoder::WaveStreamEnd(void)
{
if (fskInit == true) {
fsk_demod_destroy(fskData);
}
fskInit = false;
dtmfInit = false;
return;
}
void PhoneToneDecoder::put_WaveFormatID(variant_t _var)
{
DBG_FSK("Wave format:%s\n",
(_var.intVal==WFI_CCITT_uLaw_8kHzMono) ?"Alaw" :
(_var.intVal==WFI_CCITT_uLaw_8kHzMono) ?"Ulaw" :
"slinear");
memcpy(&variant, &_var, sizeof(variant_t));
return;
}
void PhoneToneDecoder::put_MonitorDTMF(bool val)
{
DBG_DTMF("DTMF Decoding: %s\n", (val==true ? "enabled" : "disabled"));
dtmfEnable = val;
return;
}
void PhoneToneDecoder::put_MonitorCallerID(bool val)
{
DBG_FSK("FSK Decoding: %s\n", (val==true? "enabled" : "disabled"));
fskEnable = val;
return;
}