📄 phonecarddevice.cxx
字号:
//int localRtcpPort = (request.localPort > 0) ? request.localPort + 1 : 0; const char* remoteHost = 0; if ( request.remotePort != 0 ) remoteHost = request.remoteHost; if ( request.localPort != 0 && request.remotePort != 0 ) { //full duplex audio audioStack->setSessionState(rtp_session_sendrecv); audioStack->setReceiver(request.localPort, request.localPort + 1, 0, rtpPayloadPCMU, rtpPayloadPCMU, 5); audioStack->setTransmiter(request.remoteHost, request.remotePort, request.remotePort + 1, rtpPayloadPCMU, rtpPayloadPCMU); ioctl( myFD, IXJCTL_PLAY_CODEC, ULAW ); ioctl( myFD, IXJCTL_PLAY_START ); ioctl( myFD, IXJCTL_REC_CODEC, ULAW ); ioctl( myFD, IXJCTL_REC_START ); } else if ( request.localPort != 0 ) { //receive only audioStack->setSessionState(rtp_session_sendrecv); audioStack->setReceiver(request.localPort, request.localPort + 1, 0, rtpPayloadPCMU, rtpPayloadPCMU, 5); ioctl( myFD, IXJCTL_PLAY_CODEC, ULAW ); ioctl( myFD, IXJCTL_PLAY_START ); } else if ( request.remotePort != 0 ) { //transmit only audioStack->setSessionState( rtp_session_sendrecv ); audioStack->setTransmiter( request.remoteHost, request.remotePort, request.remotePort + 1, rtpPayloadPCMU, rtpPayloadPCMU ); ioctl( myFD, IXJCTL_REC_CODEC, ULAW ); ioctl( myFD, IXJCTL_REC_START ); }#if 0 // Echo Cancellation doesn't work with VM. if (request.echoCancellation) { ioctl(myFD, IXJCTL_AEC_START, 1); cerr << "echoCancellation is on" << endl; } else { cpLog(LOG_DEBUG, "echoCancellation is off"); ioctl(myFD, IXJCTL_AEC_START, 0); } ioctl(myFD, IXJCTL_MIXER, 0x0C03); // 06 is too soft ioctl(myFD, IXJCTL_MIXER, 0x0F01); // 02 is too soft#endif if ( request.sendRingback ) startSendRingback(); else stopSendRingback(); deviceMutex.unlock(); return 0;} // end PhoneCardDevice::audioResume()//***************************************************************************// PhoneCardDevice::provideTone//// description: quicknet does not provide all the tone that are needed.// this function will provide the tone for quicknet by playing// a sound file of that particular tone.//***************************************************************************voidPhoneCardDevice::provideTone( PhoneCardTone tone ){ int size; int keypress = 0; char buff1[ULAW_SAMPLE_RATE]; int toneFD; bool provideTone = true; switch ( tone ) { case PhoneCardDialTone: { cpLog( LOG_DEBUG, "*** Provide dial tone ***" ); toneFD = open( "Tone/dialtone", O_RDONLY ); } break; case PhoneCardRingbackTone: { cpLog( LOG_DEBUG, "*** Provide ringback tone ***" ); toneFD = open( "Tone/ringback", O_RDONLY ); } break; default: { cpLog( LOG_ERR, "unsupported tone requested" ); ; toneFD = -1; } break; } // end switch if ( toneFD < 0 ) { cpLog( LOG_ERR, "Cannot open tone file" ); ; provideTone = false; } else { bool redo = true; while ( redo ) { redo = false; close( myFD ); vusleep( 10000 ); myFD = open( myDeviceName, O_WRONLY ); if ( myFD < 0 ) { cpLog( LOG_ERR, "Cannot open device %s", myDeviceName ); ; provideTone = false; } else { struct timeval start; // ctam struct timeval finish; // ctam gettimeofday( &start, 0 ); // ctam deviceMutex.lock(); ioctl( myFD, IXJCTL_PLAY_CODEC, ULAW ); ioctl( myFD, IXJCTL_PLAY_START ); deviceMutex.unlock(); gettimeofday( &finish, 0 ); // ctam long diff = finish.tv_usec - start.tv_usec + 1000000 * (finish.tv_sec - start.tv_sec); if ( diff > 100000 ) redo = true; } } } // play until file ends or onhook or dtmf is ready while ( provideTone ) { size = read( toneFD, buff1, ULAW_SAMPLE_RATE ); fflush( stdout ); if ( size > 0 ) { deviceMutex.lock(); // play some tone write( myFD, buff1, size ); // now, we only need to watch for a key press keypress = cin.peek(); if ( keypress != 0 ) // something in the keyboard buffer { provideTone = false; } if ( myQ->size() > 0 ) { // need to stop tone and process endpoint msg provideTone = false; } deviceMutex.unlock(); } else { // end of file provideTone = false; } } // end while provideTone // stop playing and close file deviceMutex.lock(); ioctl( myFD, IXJCTL_AEC_STOP ); ioctl( myFD, IXJCTL_PLAY_STOP ); deviceMutex.unlock(); close( myFD ); myFD = open( myDeviceName, O_RDWR ); if ( myFD < 0 ) { cpLog( LOG_ERR, "Cannot re-open device %s", myDeviceName ); ; exit( 1 ); } close( toneFD );} // end provideTone()// ****************// ****************intPhoneCardDevice::getRingbackTone( char *ringData, int size ){ struct timeval start; // ctam struct timeval finish; // ctam gettimeofday( &start, 0 ); // ctam int cc = 0; char tone[RESID_RTP_RATE]; if ( ringbackFd == -1 ) { cpLog( LOG_INFO, "opening ringback tone to provide remote ringback" ); ringbackFd = open( "Tone/ringback", O_RDONLY ); } if ( ringbackFd == -1 ) { cpLog( LOG_ERR, "can not open Tone/ringback" ); return cc; } cc = read( ringbackFd, tone, RESID_RTP_RATE ); fflush( stdout );#if 1 while ( cc < size ) { lseek( ringbackFd, 0, SEEK_SET ); cc += read( ringbackFd, tone + cc, size - cc ); }#endif memcpy( ringData, tone, size ); long diff = 0; while ( diff < 29500 ) { if ( diff < 20000 ) vusleep( 1000 ); gettimeofday( &finish, 0 ); // ctam diff = finish.tv_usec - start.tv_usec + 1000000 * (finish.tv_sec - start.tv_sec); } return cc;}//***************************************************************************// PhoneCardDevice::onhookOrFlash//// THIS FEATURE IS TURNED OFF IN THE PHONECARDDEVICE UNTIL QUICKNET// RELEASES THE SMARTCABLE.// description: quicknet does not implement a flash function on their cards.// so, we have to implement our own, by checking the hook state// of the phone. this function will tell us whether the phone// is being flashed or being placed onhook.//***************************************************************************voidPhoneCardDevice::onhookOrFlash(){ cpLog( LOG_DEBUG, "We know this isn't a flash!" );}// turn it off for now ----------------------------------------------------#if 0voidPhoneCardDevice::onhookOrFlash(){ deviceMutex.lock(); vusleep(20000); // needed to stabilize hookstate readings if (!ioctl(myFD, IXJCTL_HOOKSTATE)) // onhook { // user is onhook or doing a flash hookStateOffhook = false; // need to wait FLASH_TIMEOUT microsec before reporting onhook // if user picks up before the timeout, report flash int flashTime = 0; /*debug*/ cpLog(LOG_DEBUG, "Starting Flash Timer"); while (flashTime < FLASH_TIMEOUT) // begin testing for flash event { vusleep(50000); // sleep for 50,000 microsec (50 ms) flashTime += 50000; if (ioctl(myFD, IXJCTL_HOOKSTATE)) // user is offhook = flash! { flashTime = FLASH_TIMEOUT; // will get us out of while-loop /*debug*/ cpLog(LOG_DEBUG, "Hardware Event: deviceEventFlash"); hookStateOffhook = true; reportEvent(sessionQ, DeviceEventFlash); } } // end period for testing for a flash event /*debug*/ cpLog(LOG_DEBUG, "End Flash Timer"); if (hookStateOffhook == false) // this must be an actual onhook event { /*debug*/ cpLog(LOG_DEBUG, "Hardware Event: deviceEventHookDown"); reportEvent(sessionQ, DeviceEventHookDown); } } deviceMutex.unlock();} // end onhookOrFlash#endif// -------------------------------------------------------------------------// ****************// ****************voidPhoneCardDevice::provideDialToneStart(){ playDialTone = true; cpLog( LOG_DEBUG, "*** Start dial tone ***" ); deviceMutex.lock(); // this ioctl works when using the phonecard ioctl( myFD, IXJCTL_DIALTONE ); deviceMutex.unlock();}voidPhoneCardDevice::provideDialToneStop(){ playDialTone = false; cpLog( LOG_DEBUG, "*** Stop dial tone ***" ); deviceMutex.lock(); // this ioctl works when using the phonecard ioctl( myFD, IXJCTL_CPT_STOP ); deviceMutex.unlock();}voidPhoneCardDevice::provideRingStart(){ cpLog( LOG_DEBUG, "*** Start Ringing ***" ); cout << "PHONE IS RINGING..." << endl; // provideTone( PhoneCardRingbackTone );}voidPhoneCardDevice::provideRingStop(){ cpLog( LOG_DEBUG, "*** Stop Ringing ***" ); cout << "PHONE HAS STOPPED RINGING..." << endl;}voidPhoneCardDevice::provideLocalRingbackStart(){ cpLog( LOG_DEBUG, "*** Start local ringback ***" ); // the PhoneCARD does not support ringback. // so we need a wav file, but for now: cout << "START LOCAL RINGBACK" << endl; // provideTone( PhoneCardRingbackTone );};voidPhoneCardDevice::provideLocalRingbackStop(){ cpLog( LOG_DEBUG, "*** Stop local ringback ***" ); cout << "STOP LOCAL RINGBACK" << endl;};voidPhoneCardDevice::provideBusyToneStart(){ cpLog( LOG_DEBUG, "*** Start busy tone ***" ); deviceMutex.lock(); ioctl( myFD, IXJCTL_BUSY ); deviceMutex.unlock();};voidPhoneCardDevice::provideBusyToneStop(){ cpLog( LOG_DEBUG, "*** Stop busy tone ***" ); deviceMutex.lock(); ioctl(myFD, IXJCTL_CPT_STOP); deviceMutex.unlock();};voidPhoneCardDevice::provideFastBusyToneStart(){ cpLog( LOG_DEBUG, "*** Start fast busy tone ***" ); deviceMutex.lock(); //for now using regular busy tone ioctl( myFD, IXJCTL_BUSY ); deviceMutex.unlock();};voidPhoneCardDevice::provideFastBusyToneStop(){ cpLog( LOG_DEBUG, "*** Stop fast busy tone ***" ); deviceMutex.lock(); ioctl( myFD, IXJCTL_CPT_STOP ); deviceMutex.unlock();};voidPhoneCardDevice::provideDtmf( DeviceSignalType signal ){ char digit = ' '; if ( signal >= DeviceSignalDigit0 && signal <= DeviceSignalDigit9 ) { digit = '0' + signal - DeviceSignalDigit0; } else if ( signal == DeviceSignalDigitHash ) { digit = '#'; } else if ( signal == DeviceSignalDigitStar ) { digit = '*'; } cpLog( LOG_DEBUG, "*** DTMF %c ***", digit );};voidPhoneCardDevice::provideCallInfo(string, string, string){};voidPhoneCardDevice::killTone(){ if ( playDialTone == true ) { cpLog( LOG_DEBUG, "killing tone on phonecard device" ); ioctl( myFD, IXJCTL_CPT_STOP ); playDialTone = false; }};voidPhoneCardDevice::provideCallWaitingBeepStart(){ // Not yet implemented by phonecard device cpLog( LOG_DEBUG, "in provideCallWaitingBeepStart()" );};voidPhoneCardDevice::provideCallWaitingBeepStop(){ // Not yet implemented by phonecard device cpLog( LOG_DEBUG, "in provideCallWaitingBeepStop()" );};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -