📄 quicknetdevice.cxx
字号:
QuickNetDevice::provideTone (IPJackTone tone){ int size; char buff1[ULAW_SAMPLE_RATE]; int toneFD; bool provideTone = true; switch (tone) { case IPJackDialTone: { cpLog( LOG_DEBUG, "*** Provide dial tone ***" ); toneFD = open("Tone/dialtone", O_RDONLY); } break; case IPJackRingbackTone: { 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_RDWR); ioctl(myFD, IXJCTL_PORT, PORT_POTS); 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, PHONE_PLAY_CODEC, ULAW); ioctl(myFD, PHONE_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); if (ioctl(myFD, PHONE_DTMF_READY)) { // digit is ready if (tone == IPJackDialTone) { // stop tone and process digit provideTone = false; } else {#if 0 // throw digits away while playing tone int digit = ioctl(myFD, PHONE_GET_DTMF); if (digit > 0) { cerr << "bad digit: " << digit << endl; }#endif } } else if (!(ioctl(myFD, PHONE_HOOKSTATE))) { // we only enter onhookOrFlash if we are onhook AND we have // BEEN offhook deviceMutex.unlock(); onhookOrFlash(); deviceMutex.lock();#if 0 // report change from offhook to onhook reportEvent(sessionQ, DeviceEventHookDown); hookStateOffhook = false;#endif provideTone = false; } else if ( myQ->size() > 0 ) { // need to stop tone and process endpoint msg provideTone = false; } else { char keystroke = '\0'; if( read( stdinFD, &keystroke, 1 ) > 0 ) { if( keystroke != '\n' ) { cpLog( LOG_DEBUG, "Keystroke read: '%c'(%x)", ( keystroke >= ' ' && keystroke <= '~' ) ? keystroke : '.', keystroke ); } if( keystroke == 'u' ) { if( hookStateOffhook ) { provideTone = false; cout << "\nEnter URL: "; cout.flush(); myEntryState = EntryStateEnterUrl; } } else { cpLog( LOG_ERR, "Enter 'u' for direct URL entry" ); } } } deviceMutex.unlock(); } else { // end of file provideTone = false; } } // end while provideTone ioctl(myFD, PHONE_PLAY_STOP); ioctl(myFD, PHONE_PLAY_START);#if 0 // stop playing and close file deviceMutex.lock(); ioctl(myFD, IXJCTL_AEC_STOP); ioctl(myFD, PHONE_PLAY_STOP); deviceMutex.unlock(); close(myFD); myFD = open(myDeviceName, O_RDWR); ioctl(myFD, IXJCTL_PORT, PORT_POTS); if (myFD < 0) { cpLog( LOG_ERR, "Cannot re-open device %s", myDeviceName ); ; exit(1); }#endif close(toneFD);} // end provideTone()// ****************// ****************intQuickNetDevice::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;}char*QuickNetDevice::getCwBeep(){ char *beep = 0; if( cwCadenceOn ) { beep = cwBeep + cwCnt; cwCnt += RESID_RTP_RATE; if( cwCnt >= CWBEEP_ON_TIME ) { cwCnt = 0; cwCadenceOn = false; } } else { cwCnt += RESID_RTP_RATE; if( cwCnt >= (CWBEEP_OFF_TIME - RESID_RTP_RATE) ) { cwCnt = 0; cwCadenceOn = true; } } return beep;}//***************************************************************************// QuickNetDevice::onhookOrFlash//// 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.//***************************************************************************voidQuickNetDevice::onhookOrFlash(){ deviceMutex.lock(); vusleep(20000); // needed to stabilize hookstate readings if (!ioctl(myFD, PHONE_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; //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, PHONE_HOOKSTATE)) // user is offhook = flash! { flashTime = FLASH_TIMEOUT; // will get us out of while-loop //cpLog(LOG_DEBUG, "Hardware Event: deviceEventFlash"); hookStateOffhook = true; reportEvent(sessionQ, DeviceEventFlash); } } // end period for testing for a flash event //cpLog(LOG_DEBUG, "End Flash Timer"); if (hookStateOffhook == false) // this must be an actual onhook event { //cpLog(LOG_DEBUG, "Hardware Event: deviceEventHookDown"); reportEvent(sessionQ, DeviceEventHookDown); } } deviceMutex.unlock();} // end onhookOrFlashvoidQuickNetDevice::provideDialToneStart(){ cpLog( LOG_DEBUG, "*** Start dial tone ***" ); //deviceMutex.lock(); //ioctl(myFD, PHONE_DIALTONE); //deviceMutex.unlock(); //provide simulated dialtone by playing an audio file provideTone(IPJackDialTone);}voidQuickNetDevice::provideDialToneStop(){ cpLog( LOG_DEBUG, "*** Stop dial tone ***" ); //deviceMutex.lock(); //ioctl(myFD, PHONE_CPT_STOP); //deviceMutex.unlock();}voidQuickNetDevice::provideRingStart(){ cpLog( LOG_DEBUG, "*** Start Ringing ***" ); deviceMutex.lock(); ioctl(myFD, PHONE_RING_START); deviceMutex.unlock();}voidQuickNetDevice::provideRingStop(){ cpLog( LOG_DEBUG, "*** Stop Ringing ***" ); // no call to explicitly stop ringing is available at this time deviceMutex.lock(); ioctl(myFD, PHONE_RING_STOP); deviceMutex.unlock();}voidQuickNetDevice::provideLocalRingbackStart(){ cpLog( LOG_DEBUG, "*** Start local ringback ***" ); deviceMutex.lock(); ioctl(myFD, PHONE_RINGBACK); deviceMutex.unlock(); // provide simulated dialtone by playing an audio file //provideTone(IPJackRingbackTone);}voidQuickNetDevice::provideLocalRingbackStop(){ cpLog( LOG_DEBUG, "*** Stop local ringback ***" ); deviceMutex.lock(); ioctl(myFD, PHONE_CPT_STOP); deviceMutex.unlock();}voidQuickNetDevice::provideBusyToneStart(){ cpLog( LOG_DEBUG, "*** Start busy tone ***" ); deviceMutex.lock(); ioctl(myFD, PHONE_BUSY); deviceMutex.unlock();}voidQuickNetDevice::provideBusyToneStop(){ cpLog( LOG_DEBUG, "*** Stop busy tone ***" ); deviceMutex.lock(); ioctl(myFD, PHONE_CPT_STOP); deviceMutex.unlock();}voidQuickNetDevice::provideFastBusyToneStart(){ cpLog( LOG_DEBUG, "*** Start fast busy tone ***" ); deviceMutex.lock(); //for now using regular busy tone ioctl(myFD, PHONE_BUSY); deviceMutex.unlock();}voidQuickNetDevice::provideFastBusyToneStop(){ cpLog( LOG_DEBUG, "*** Stop fast busy tone ***" ); deviceMutex.lock(); //for now using regular busy tone ioctl(myFD, PHONE_CPT_STOP); deviceMutex.unlock();}voidQuickNetDevice::provideCallWaitingBeepStart(){ cpLog( LOG_DEBUG, "*** Start call waiting beep ***" ); //TODO: figure out how to do this with Quicknet //for now, just print something cout << "!!!!!!! Start call waiting beep" << endl; deviceMutex.lock(); cwBeepOn = true; cwCnt = 0; cwCadenceOn = true; deviceMutex.unlock();}voidQuickNetDevice::provideCallWaitingBeepStop(){ cpLog( LOG_DEBUG, "*** Stop call waiting beep ***" ); //TODO: figure out how to do this with Quicknet //for now, just print something cout << "!!!!!!! Stop call waiting beep" << endl; cwBeepOn = false;}voidQuickNetDevice::provideDtmf(DeviceSignalType signal){ char digit = ' '; int dtmfEvent = 0; switch( signal ) { case DeviceSignalDigitStar: digit = '*'; dtmfEvent = 10; break; case DeviceSignalDigitHash: digit = '#'; dtmfEvent = 11; break; case DeviceSignalDigit0: case DeviceSignalDigit1: case DeviceSignalDigit2: case DeviceSignalDigit3: case DeviceSignalDigit4: case DeviceSignalDigit5: case DeviceSignalDigit6: case DeviceSignalDigit7: case DeviceSignalDigit8: case DeviceSignalDigit9: digit = '0' + signal - DeviceSignalDigit0; dtmfEvent = signal - DeviceSignalDigit0; break; default: cpLog( LOG_DEBUG, "Unknown DTMF Signal %d", signal ); return; } if( audioStack ) { cpLog( LOG_DEBUG, "DTMF %c sent out in RTP ", digit ); audioStack->transmitEvent( dtmfEvent ); } else { cpLog( LOG_DEBUG, "No audio stack existing to send DTMF event" ); }}voidQuickNetDevice::provideCallInfo(string, string, string){}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -