📄 srldevice.cpp
字号:
// [in] data length
// [in] METAEVENT (not used)
// Returns:
// none
//*****************************************************************************
void CSrlDevice::HandleEvent(int event,
void *evtdata, int evtlen,
METAEVENT *metaeventp){
UNREFERENCED_PARAMETER(metaeventp);
UNREFERENCED_PARAMETER(evtlen);
LOG (LOG_DBG, GetName(),
"Current state is %d %s",
GetCurrentState(), state_name(GetCurrentState()));
switch (event) {
case GCEV_BLOCKED:
SetSrlState(SRLSTATE_BLOCKED,SET_SRL_STATE);
break;
case GCEV_UNBLOCKED:
SetSrlState(SRLSTATE_BLOCKED,RESET_SRL_STATE);
break;
case USREV_EXIT_REQUEST:
SetSrlState(SRLSTATE_REQUESTED_STOP);
break;
case TDX_CST:
{
DX_CST *cstp = (DX_CST *)evtdata;
dx_dump(cstp);
}
break;
default:
break;
} // switch (event)
if (evt_isnotification(event) ){
// notification - dump info
dump_notification_data(event, evtdata);
}
if (!AdvanceStateMachine(event) ){
LOG ( LOG_WARNING, GetName(),
"Did not advance: from state %d %s",
GetCurrentState(), state_name(GetCurrentState()));
}
return ;
} // End of HandleEvent()
//*****************************************************************************
// Purpose :
// Indicate state machine error
// Parameters:
// None
// Returns:
// none
//*****************************************************************************
bool CSrlDevice::StateMachineError(){
LOG( LOG_DBG, GetName(),
"Cannot handle event in current state %d %s",
GetCurrentState(), state_name(GetCurrentState()));
return false;
} // End of StateMachineError()
//*****************************************************************************
// Purpose :
// Request state machine to exit gracefully
// Parameters:
// None
// Returns:
// none
//*****************************************************************************
bool CSrlDevice::ExitRequest(){
bool brc = PutEvent(USREV_EXIT_REQUEST, GetName());
return brc;
} // End of ExitRequest()
//*****************************************************************************
// Purpose :
// Request state machine to drop the call gracefully and proceed with other calls
// Parameters:
// None
// Returns:
// none
//*****************************************************************************
bool CSrlDevice::DropRequest(){
bool brc = PutEvent(USREV_CNF_TIMEOUT, GetName());
return brc;
} // End of DropRequest()
//*****************************************************************************
// Purpose :
// Send event to this object
// Parameters:
// [in] event code
// [in] sender ( string )
// [in] optional data length
// [in] optional event data
// Returns:
// true = success
//*****************************************************************************
bool CSrlDevice::PutEvent(int event,
const char *sender,
long len, void *datap){
int rc = AT_FAILURE;
if (IS_VALID_HANDLE(m_srl_handle) ){
rc = sr_putevtUserContext(m_srl_handle, event, len, &datap, 0, this);
const char *evname;
evt_getname(event,&evname);
LOG( LOG_DBG, GetName(),
"%d = [from %s] sr_putevtUserContext(0x%x, %s, %d, 0x%x, 0x%x(this %s)",
rc, sender,
m_srl_handle, evname, len, datap, this, GetName());
}
return 0 == rc;
} // End of PutEvent()
//*****************************************************************************
// Purpose :
// Dump all events that can possibly advance state machine from the current state
// Parameters:
// none
// Returns:
// none
//*****************************************************************************
void CSrlDevice::DumpMissingEvents(){
LOG( LOG_ERR1, GetName(), "Timed out waiting for event(s):");
int search_handle = BEGIN_SEARCH;
int missing;
while (m_pStateMachine->EnumMissingEvents(&missing, &search_handle) ){
if ( ! evt_isuser(missing)
&& evt_issignificant(missing) ) {
const char *ev_name;
evt_getname(missing, &ev_name);
LOG( LOG_ERR1, GetName(),
" Event 0x%x %s", missing, ev_name);
}
}
} // End of DumpMissingEvents()
//----------------------------------------------------------------
// Voice
//----------------------------------------------------------------
//*****************************************************************************
// Purpose :
// Play a file
// Parameters:
// [in] file name
// Returns:
// true = success
//*****************************************************************************
bool CSrlDevice::PlayFile(const char *filename){
int rc;
SetDfltTimer(VOICE_TMO);
// Termination condition: any digit
DV_TPT tpt[1];
dx_clrtpt(tpt,1);
tpt[0].tp_type = IO_EOT;
tpt[0].tp_termno = DX_MAXDTMF;
tpt[0].tp_length = 1;
tpt[0].tp_flags = TF_MAXDTMF;
// Remove any existing digits
// otherwise, play will not start at all
ClearDigits();
// init IOTT block
// This is class member because we need to close file later
// after TDX_PLAY or TDX_ERROR event is received
memset (&m_iott,0,sizeof(m_iott));
m_iott.io_fhandle = dx_fileopen(filename, O_RDONLY|O_BINARY);
m_iott.io_type = IO_DEV|IO_EOT;
m_iott.io_bufp = 0;
m_iott.io_offset = 0;
m_iott.io_length = -1;
if(m_iott.io_fhandle == INV_FILE_HANDLE) {
LOG( LOG_ERR2, GetName(), "Cannot open file %s",filename);
return false;
}
// These are valid for our sample play files
DX_XPB xpb;
xpb.wFileFormat = FILE_FORMAT_VOX;
xpb.wDataFormat = DATA_FORMAT_MULAW;
xpb.nSamplesPerSec = DRT_8KHZ;
xpb.wBitsPerSample = 8;
rc = dx_playiottdata (m_dx_srl_handle, &m_iott, tpt, &xpb, EV_ASYNC);
LOG( RC(rc), GetName(),
"%d = dx_playiottdata(hndl=0x%x, iott(%s), tpt, xpb, EV_ASYNC)",
rc, m_dx_srl_handle,filename );
if ( rc == AT_FAILURE){
process_dx_error(m_dx_srl_handle, GetName());
return false;
}
return true;
} // End of PlayFile()
//*****************************************************************************
// Purpose :
// Record a file
// Parameters: none
// Returns:
// true = success
//*****************************************************************************
bool CSrlDevice::RecFile(){
int rc;
SetDfltTimer(VOICE_TMO);
// Termination condition: any digit
DV_TPT tpt[1];
dx_clrtpt(tpt,1);
tpt[0].tp_type = IO_EOT;
tpt[0].tp_termno = DX_MAXDTMF;
tpt[0].tp_length = 1;
tpt[0].tp_flags = TF_MAXDTMF;
// Remove any existing digits
// otherwise, play will not start at all
ClearDigits();
// init IOTT block
// This is class member because we need to close file later
// after TDX_PLAY or TDX_ERROR event is received
memset (&m_iott,0,sizeof(m_iott));
char filename[256];
snprintf(filename,sizeof(filename),"%s_%d.pcm",GetName(),file_index++);
m_iott.io_fhandle = dx_fileopen(filename, O_RDWR|O_TRUNC|O_CREAT|O_BINARY, 0666);
m_iott.io_type = IO_DEV|IO_EOT;
m_iott.io_bufp = 0;
m_iott.io_offset = 0;
m_iott.io_length = -1;
if(m_iott.io_fhandle == INV_FILE_HANDLE) {
LOG( LOG_ERR2, GetName(), "Cannot open file %s",filename);
return false;
}
DX_XPB xpb;
// xpb.wFileFormat = FILE_FORMAT_WAVE;
xpb.wFileFormat = FILE_FORMAT_VOX;
xpb.wDataFormat = DATA_FORMAT_MULAW;
xpb.nSamplesPerSec = DRT_8KHZ;
xpb.wBitsPerSample = 8;
rc = dx_reciottdata (m_dx_srl_handle, &m_iott, tpt, &xpb, EV_ASYNC);
LOG( RC(rc), GetName(),
"%d = dx_reciottdata(hndl=0x%x, iott(%s), tpt, xpb, EV_ASYNC)",
rc, m_dx_srl_handle,filename );
if ( rc == AT_FAILURE){
process_dx_error(m_dx_srl_handle, GetName());
return false;
}
return true;
} // End of RecFile()
//*****************************************************************************
// Purpose :
// Get Digits (conference pass word)
// Parameters:
// none
// Returns:
// true = success
//*****************************************************************************
bool CSrlDevice::GetDigits(){
int rc;
unsigned short tmo = 100; // in 1/10 sec, 10 seconds
set_dx_cst(DM_DIGITS | DM_SILON | DM_SILOFF);
SetDfltTimer(6*tmo*1000); // 6 very slow digits
// Termination condition: any '#', tmo 10 sec or interdigit tmo 5 sec
DV_TPT tpt[2];
dx_clrtpt(tpt,2);
tpt[0].tp_type = IO_CONT;
tpt[0].tp_termno = DX_DIGMASK;
tpt[0].tp_length = DM_P; // #
tpt[0].tp_flags = TF_DIGMASK;
tpt[1].tp_type = IO_EOT;
tpt[1].tp_termno = DX_IDDTIME;
tpt[1].tp_length = tmo;
tpt[1].tp_flags = TF_IDDTIME;
m_digits.dg_value[0] = 0; //clean old content
// get it
rc = dx_getdig (m_dx_srl_handle, tpt, &m_digits, EV_ASYNC);
LOG( RC(rc), GetName(),
"%d = dx_getdig(hndl=0x%x, tpt, m_digits, EV_ASYNC)",
rc, m_dx_srl_handle);
if ( rc == AT_FAILURE){
process_dx_error(m_dx_srl_handle, GetName());
return false;
}
return true;
} // End of GetDigits()
//*****************************************************************************
// Purpose :
// Play short beep
// Parameters:
// [in]beep type
// Returns:
// true = success
//*****************************************************************************
bool CSrlDevice::DxBeep(BEEP_TYPE beep){
TN_GENCAD ToneGenCad ;
memset (&ToneGenCad, 0, sizeof(ToneGenCad));
const char *tname = "";
DV_TPT tpt[1];
dx_clrtpt(tpt,1);
tpt[0].tp_type = IO_EOT;
tpt[0].tp_termno = DX_DIGMASK;
tpt[0].tp_length = DM_P; // #
tpt[0].tp_flags = TF_DIGMASK;
switch (beep){
case BEEP_OUT:
tname = "beep_out";
ToneGenCad.cycles = 1;
ToneGenCad.numsegs = 1;
ToneGenCad.offtime[0] = 10;
ToneGenCad.offtime[1] = 10;
dx_bldtngen( &(ToneGenCad.tone[0]), 640, 0,-7,0,10);
break;
case BEEP_IN:
tname = "beep_in";
ToneGenCad.cycles = 1;
ToneGenCad.numsegs = 1;
ToneGenCad.offtime[0] = 10;
ToneGenCad.offtime[1] = 10;
dx_bldtngen( &(ToneGenCad.tone[0]), 440, 0,-7,0,10);
dx_bldtngen( &(ToneGenCad.tone[1]), 440, 0,-7,0,10);
break;
case BEEP_BYE:
tname = "beep_bye";
ToneGenCad.cycles = 3;
ToneGenCad.numsegs = 1;
ToneGenCad.offtime[0] = 10;
ToneGenCad.offtime[1] = 10;
dx_bldtngen( &(ToneGenCad.tone[0]), 440, 0,-7,0,10);
break;
default:
LOG(LOG_ASSERT, GetName(), "Invalid beep type %d", beep);
break;
} // switch (beep)
int rc = dx_playtoneEx(m_dx_srl_handle,&ToneGenCad, tpt, EV_ASYNC);
LOG( RC(rc),GetName(),
"%d = dx_playtoneEx(0x%x, tone('%s'), EV_ASYNC)",
rc, m_dx_srl_handle, tname);
if ( rc == AT_FAILURE){
process_dx_error(m_dx_srl_handle, GetName());
return false;
}
return true;
} // End of DxBeep()
//*****************************************************************************
// Purpose :
// Terminate current voice operation
// Parameters:
// none
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -