📄 ixjunix.cxx
字号:
// PHONE_REC_START does not set return value ::ioctl(os_handle, PHONE_REC_START); readStopped = FALSE; // IXJCTL_AEC_START does not set return code ::ioctl(os_handle, IXJCTL_AEC_START, aecLevel); return TRUE;}BOOL OpalIxJDevice::SetWriteCodec(unsigned, RTP_DataFrame::PayloadTypes rtpType){ { PWaitAndSignal mutex(toneMutex); if (tonePlaying) { tonePlaying = FALSE; ::ioctl(os_handle, PHONE_CPT_STOP); } } PWaitAndSignal mutex(writeMutex); ::ioctl(os_handle, PHONE_PLAY_STOP); writeStopped = TRUE; PINDEX codec; for (codec = 0; codec < PARRAYSIZE(CodecInfo); codec++) if (CodecInfo[codec].rtpType == rtpType) break; if (codec >= PARRAYSIZE(CodecInfo)) return FALSE; PTRACE(2, "IXJ\tSetting write codec to " << CodecInfo[codec].mode); writeCodecType = CodecInfo[codec].mode; writeFrameSize = CodecInfo[codec].frameSize; if (codec == G729) ::ioctl(os_handle, PHONE_FRAME, writeFrameSize); int stat = ::ioctl(os_handle, PHONE_PLAY_CODEC, CodecInfo[codec].mode); if (stat != 0) { PTRACE(1, "IXJ\tSecond try on set play codec"); stat = ::ioctl(os_handle, PHONE_PLAY_CODEC, CodecInfo[codec].mode); if (!ConvertOSError(stat)) return FALSE; } // PHONE_PLAY_DEPTH does not set return value ::ioctl(os_handle, PHONE_PLAY_DEPTH, CodecInfo[codec].depth); stat = ::ioctl(os_handle, PHONE_PLAY_START); if (stat != 0) { PTRACE(1, "IXJ\tSecond try on start play codec"); stat = ::ioctl(os_handle, PHONE_PLAY_START); if (!ConvertOSError(stat)) return FALSE; } writeStopped = FALSE; // IXJCTL_AEC_START does not set return code ::ioctl(os_handle, IXJCTL_AEC_START, aecLevel); return TRUE;}BOOL OpalIxJDevice::StopReadCodec(unsigned){ PTRACE(3, "xJack\tStopping read codec"); readMutex.Wait(); readStopped = TRUE; ::ioctl(os_handle, PHONE_REC_STOP); readMutex.Signal(); return TRUE;}BOOL OpalIxJDevice::StopWriteCodec(unsigned){ PTRACE(3, "xJack\tStopping write codec"); writeMutex.Wait(); writeStopped = TRUE; ::ioctl(os_handle, PHONE_PLAY_STOP); writeMutex.Signal(); return TRUE;}PINDEX OpalIxJDevice::GetReadFrameSize(unsigned){ return readFrameSize;}PINDEX OpalIxJDevice::GetWriteFrameSize(unsigned){ return writeFrameSize;}BOOL OpalIxJDevice::ReadFrame(unsigned, void * buf){ PWaitAndSignal rmutex(readMutex); PWaitAndSignal wmutex(writeMutex); if (readStopped) return FALSE; if (writeStopped) { PThread::Current()->Sleep(30); memset(buf, 0, readFrameSize); switch (readCodecType) { case G723_63: case G723_53: *((BYTE *)buf) = 0x02; break; case ULAW: case ALAW: memset((BYTE *)buf, 0x80, readFrameSize); break; case LINEAR16: memset((BYTE *)buf, 0x00, readFrameSize); break; } return TRUE; } for (;;) { int stat = ::read(os_handle, buf, readFrameSize); if (stat == (int)readFrameSize) return TRUE; if ((stat >= 0) || (errno != EINTR)) break; PTRACE(1, "IXJ\tRead EINTR"); } PTRACE(1, "IXJ\tRead error = " << errno); return FALSE;}BOOL OpalIxJDevice::WriteFrame(unsigned, const void * buf){ PWaitAndSignal rmutex(readMutex); PWaitAndSignal wmutex(writeMutex); if (writeStopped) return FALSE; if (readStopped) { PThread::Current()->Sleep(30); return TRUE; } for (;;) { fd_set wfds; FD_ZERO(&wfds); FD_SET(os_handle, &wfds); struct timeval ts; ts.tv_sec = 0; ts.tv_usec = 100*1000; int stat = ::select(os_handle+1, NULL, &wfds, NULL, &ts); if (stat < 0) stat = -stat; else if (stat == 0) { PTRACE(1, "IXJ\tWrite timeout"); return FALSE; } else { stat = ::write(os_handle, buf, writeFrameSize); if (stat == (int)writeFrameSize) return TRUE; } if ((stat >= 0) || (errno != EINTR)) break; PTRACE(1, "IXJ\tWrite EINTR"); } PTRACE(1, "IXJ\tWrite error = " << errno); return FALSE;}unsigned OpalIxJDevice::GetAverageSignalLevel(unsigned){ return ::ioctl(os_handle, PHONE_REC_LEVEL);}BOOL OpalIxJDevice::EnableAudio(unsigned line, BOOL enable){ int port = PORT_SPEAKER; if (enable) port = line == 0 ? PORT_POTS : PORT_PSTN; return ConvertOSError(::ioctl(os_handle, IXJCTL_PORT, port));}/* version 0.3.31-gpl of the IXJ driver and earlier return bogus values for the record volume. Hence we make sure that if we get a bogus value first time around, then we mark the routine as faulty*/static BOOL bogusRecordVolume = FALSE;static unsigned savedRecordVolume = 0x100;static BOOL firstTime = TRUE;BOOL OpalIxJDevice::SetRecordVolume(unsigned, unsigned volume){ PWaitAndSignal mutex1(readMutex); PWaitAndSignal mutex2(writeMutex); BOOL stat = ::ioctl(os_handle, IXJCTL_REC_VOLUME, volume); savedRecordVolume = volume; return stat;}BOOL OpalIxJDevice::GetRecordVolume(unsigned, unsigned & volume){ PWaitAndSignal mutex1(readMutex); PWaitAndSignal mutex2(writeMutex); if (firstTime) { firstTime = FALSE; volume = ::ioctl(os_handle, IXJCTL_REC_VOLUME, -1); if (volume > 50000) { volume = savedRecordVolume; ::ioctl(os_handle, IXJCTL_REC_VOLUME, volume); ::ioctl(os_handle, IXJCTL_REC_VOLUME, volume); bogusRecordVolume = TRUE; cerr << "\n" "**********************************************************************\n" "*** warning: your ixj driver needs a patch to fix PHONE_REC_VOLUME ***\n" "**********************************************************************\n" "\n" << endl; } } if (bogusRecordVolume) volume = savedRecordVolume; else volume = ::ioctl(os_handle, IXJCTL_REC_VOLUME, -1); return TRUE;}BOOL OpalIxJDevice::SetPlayVolume(unsigned, unsigned volume){ PWaitAndSignal mutex1(readMutex); PWaitAndSignal mutex2(writeMutex); return ::ioctl(os_handle, IXJCTL_PLAY_VOLUME, volume);}BOOL OpalIxJDevice::GetPlayVolume(unsigned, unsigned & volume){ PWaitAndSignal mutex1(readMutex); PWaitAndSignal mutex2(writeMutex); volume = ::ioctl(os_handle, IXJCTL_PLAY_VOLUME, -1); if (volume == 0xcf00) volume = ::ioctl(os_handle, IXJCTL_PLAY_VOLUME, -1); return TRUE;}OpalLineInterfaceDevice::AECLevels OpalIxJDevice::GetAEC(unsigned){ return aecLevel;}BOOL OpalIxJDevice::SetAEC(unsigned, AECLevels level){ aecLevel = level; PWaitAndSignal mutex1(readMutex); PWaitAndSignal mutex2(writeMutex); if (writeStopped && readStopped) return TRUE; // IXJCTL_AEC_START does not set return code ::ioctl(os_handle, IXJCTL_AEC_START, aecLevel); return TRUE;}BOOL OpalIxJDevice::GetCallerID(unsigned line, PString & callerId, BOOL full){ if (line != PSTNLine) return FALSE; if (exceptionBits.bits.caller_id == 0) GetException(exceptionBits); if (exceptionBits.bits.caller_id != 0) { exceptionBits.bits.caller_id = 0; return TRUE; } return FALSE;}BOOL OpalIxJDevice::SetCallerID(unsigned line, const PString & idString){ if (line != POTSLine) return FALSE;#ifdef IXJCTL_VMWI memset(&callerIdInfo, 0, sizeof(callerIdInfo)); if (idString.IsEmpty()) return TRUE; PString name, number; PTime theTime; PStringArray fields = idString.Tokenise('\t', TRUE); switch (fields.GetSize()) { case 3 : if (!fields[2]) name = fields[2]; case 2 : if (!fields[1]) theTime = PTime(fields[1]); case 1 : if (!fields[0]) number = fields[0]; break; default : return FALSE; } sprintf(callerIdInfo.month, "%02i", theTime.GetMonth()); sprintf(callerIdInfo.day, "%02i", theTime.GetDay()); sprintf(callerIdInfo.hour, "%02i", theTime.GetHour()); sprintf(callerIdInfo.min, "%02i", theTime.GetMinute()); strncpy(callerIdInfo.name, (const char *)name, sizeof(callerIdInfo.name)-1); strncpy(callerIdInfo.number, (const char *)number, sizeof(callerIdInfo.number)-1);#endif return TRUE;}BOOL OpalIxJDevice::PlayDTMF(unsigned, const char * tones, DWORD onTime, DWORD offTime){ PWaitAndSignal mutex(toneMutex); if (tonePlaying) return FALSE; // not really needed, as we have the tone mutex locked tonePlaying = TRUE; ::ioctl(os_handle, PHONE_SET_TONE_ON_TIME, onTime * 4); ::ioctl(os_handle, PHONE_SET_TONE_OFF_TIME, offTime * 4); while (*tones != '\0') { char tone = *tones++; int code; if ('1' <= tone && tone <= '9') code = tone - '0'; else if (tone == '*') code = 10; else if (tone == '0') code = 11; else if (tone == '#') code = 12; else if ('A' <= tone && tone <= 'D') code = tone - 'A' + 28; else code = 0; ::ioctl(os_handle, PHONE_PLAY_TONE, code); PThread::Current()->Sleep(onTime + offTime); long countDown = 200; // a tone longer than 2 seconds? I don't think so... while ((countDown > 0) && ::ioctl(os_handle, PHONE_GET_TONE_STATE) != 0) { PThread::Current()->Sleep(10); countDown--; } if (countDown == 0) cerr << "Timeout whilst waiting for DTMF tone to end" << endl; } // "Realize the truth....There is no tone." tonePlaying = FALSE; return TRUE;}char OpalIxJDevice::ReadDTMF(unsigned){ if (::ioctl(os_handle, PHONE_DTMF_READY) <= 0) return '\0'; return (char)::ioctl(os_handle , PHONE_GET_DTMF_ASCII);}BOOL OpalIxJDevice::GetRemoveDTMF(unsigned){ return removeDTMF;}BOOL OpalIxJDevice::SetRemoveDTMF(unsigned, BOOL state){ removeDTMF = state; return ::ioctl(os_handle, PHONE_DTMF_OOB, state);}OpalLineInterfaceDevice::CallProgressTones OpalIxJDevice::IsToneDetected(unsigned){ return NumTones;}BOOL OpalIxJDevice::PlayTone(unsigned line, CallProgressTones tone){ { PWaitAndSignal mutex(toneMutex); if (tonePlaying) { tonePlaying = FALSE; ::ioctl(os_handle, PHONE_CPT_STOP); } switch (tone) { case DialTone : tonePlaying = TRUE; return ::ioctl(os_handle, PHONE_DIALTONE); case RingTone : tonePlaying = TRUE; return ::ioctl(os_handle, PHONE_RINGBACK); case BusyTone : tonePlaying = TRUE; return ::ioctl(os_handle, PHONE_BUSY); default : break; } } PWaitAndSignal mutex(toneMutex); StopTone(line); return FALSE;}BOOL OpalIxJDevice::IsTonePlaying(unsigned){// if (::ioctl(os_handle, PHONE_GET_TONE_STATE) != 0) // return TRUE;// return FALSE; return tonePlaying;}BOOL OpalIxJDevice::StopTone(unsigned){ PWaitAndSignal mutex(toneMutex); if (!tonePlaying) return TRUE; tonePlaying = FALSE; return ::ioctl(os_handle, PHONE_CPT_STOP);}BOOL OpalIxJDevice::SetCountryCode(T35CountryCodes country){ OpalLineInterfaceDevice::SetCountryCode(country); // if a LineJack, the set the DAA coeffiecients if (!IsLineJACK()) return FALSE; if (country != UnknownCountry) { static int ixjCountry[NumCountryCodes] = { DAA_JAPAN, 0, 0, 0, DAA_GERMANY, 0, 0, 0, 0, DAA_AUSTRALIA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, DAA_FRANCE, 0, 0, 0, 0, DAA_GERMANY, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, DAA_UK, DAA_US, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; ::ioctl(os_handle, IXJCTL_DAA_COEFF_SET, ixjCountry[countryCode]); } return TRUE;}PStringArray OpalIxJDevice::GetDeviceNames(){ PStringArray array; PINDEX i = 0; for (;;) { PString devName = psprintf("/dev/phone%i", i); int handle = ::open((const char *)devName, O_RDWR); if (handle < 0) break; ::close(handle); array[i++] = devName; } return array;}/////////////////////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -