📄 ixjwin32.cxx
字号:
/* * ixjwin32.cxx * * QuickNet Internet Phone/Line JACK codec interface * * Open H323 Library * * Copyright (c) 1999-2000 Equivalence Pty. Ltd. * * The contents of this file are subject to the Mozilla Public License * Version 1.0 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See * the License for the specific language governing rights and limitations * under the License. * * The Original Code is Open H323 Library. * * The Initial Developer of the Original Code is Equivalence Pty. Ltd. * * Portions of this code were written with the assisance of funding from * Quicknet Technologies, Inc. http://www.quicknet.net. * * Contributor(s): ______________________________________. * * $Log: ixjwin32.cxx,v $ * Revision 1.47 2000/07/25 02:07:34 robertj * Reduced max range of device numbers as can get some low serial numbers. * * Revision 1.46 2000/07/14 14:12:06 robertj * Added turning off of VAD which results in 1 byte G.723.1 frames that not * everyone supports yet. * * Revision 1.45 2000/07/12 10:25:07 robertj * Added PhoneCARD support on Win9x systems. * * Revision 1.44 2000/06/20 12:51:23 robertj * Changed IXJ driver open so does not change selected line to PSTN. * * Revision 1.43 2000/06/20 02:22:41 robertj * Fixed NT version so can still use serial number to open device. * * Revision 1.42 2000/06/19 00:31:30 robertj * Changed NT device name to be a bit more user friendly. * * Revision 1.41 2000/06/08 02:33:25 robertj * Fixed detection of correct xJack card type under NT. * Added ability to use just "0" or "1" instead of "\\.\QTJackDevice0" as device name. * * Revision 1.40 2000/05/25 02:23:25 robertj * Added calls to get volume settings * * Revision 1.39 2000/05/15 08:38:59 robertj * Changed LineJACK PSTN check so is initiated only if state unknown. * * Revision 1.38 2000/05/02 04:32:27 robertj * Fixed copyright notice comment. * * Revision 1.37 2000/04/30 04:00:33 robertj * Changed determination of frame size to use driver ioctl for PCM, uLAw and ALaw. * * Revision 1.36 2000/04/28 07:00:26 robertj * Fixed race condition causing RTP send thread to randomly shut down. * * Revision 1.35 2000/04/19 01:57:39 robertj * Added mixer code to get volume control support on LineJACK;s. * Attempt to prevent getting very occassional ReadFrame() failure causing tx channel stop. * * Revision 1.34 2000/04/12 23:56:37 robertj * Fixed detection of PCI PhoneJACK on NT. * * Revision 1.33 2000/04/06 20:36:25 robertj * Fixed some LineJACK compatbility problems (eg DTMF detect stopping). * * Revision 1.32 2000/04/05 20:55:41 robertj * Added caller ID send, and fixed receive for multiple fields. * * Revision 1.31 2000/04/05 18:04:12 robertj * Changed caller ID code for better portability. * * Revision 1.30 2000/03/30 01:55:13 robertj * Added function so silence detection can work on xJack internetl codecs. * Fixed length of G.728 codec frames * * Revision 1.29 2000/03/29 20:59:52 robertj * Added function on LID to get available codecs. * Improved consistency in "device name". * Fixed codec table for G.729 codec * Fixed lockup bug with tone/codec interaction. * * Revision 1.28 2000/03/23 02:48:49 robertj * Added calling tone detection code. * * Revision 1.27 2000/03/17 20:59:42 robertj * Fixed line count to be xJACK card dependent. * Added support for more xJACK card types. * * Revision 1.26 2000/02/24 00:35:22 robertj * Fixed problem with unresolved SetRemoveDTMF function when not using linux telephony. * * Revision 1.25 2000/02/16 04:04:37 robertj * Fixed bug where IXJ POTS handset never returned off hook. * * Revision 1.24 2000/01/07 08:28:09 robertj * Additions and changes to line interface device base class. * * Revision 1.23 1999/12/30 09:16:41 robertj * Fixed initialisation of driver handle, prevent crash in Close(). * * Revision 1.22 1999/12/23 23:02:36 robertj * File reorganision for separating RTP from H.323 and creation of LID for VPB support. * * Revision 1.21 1999/11/29 04:50:11 robertj * Added adaptive threshold calculation to silence detection. * * Revision 1.20 1999/11/20 04:38:03 robertj * Removed potential driver lockups by doing overlapped I/O only on read/write ioctls. * * Revision 1.19 1999/11/19 09:17:15 robertj * Fixed problems with aycnhronous shut down of logical channels. * * Revision 1.18 1999/11/16 12:43:02 robertj * Dixed missing initialise of AEC variable. * * Revision 1.17 1999/11/16 11:32:06 robertj * Added some calling tones. * * Revision 1.16 1999/11/12 02:25:01 robertj * More NT support. * * Revision 1.15 1999/11/11 23:15:31 robertj * Fixed bug where closed driver was not flagged as closed. * * Revision 1.14 1999/11/11 01:16:57 robertj * Added NT support, debounce of phone hook state and wait for line test completion. * * Revision 1.13 1999/11/06 05:36:19 robertj * Fixed problem with read/write locking up when stopping codec. * * Revision 1.12 1999/11/06 03:32:27 robertj * Added volume control functions for record/playback. * * Revision 1.11 1999/11/05 12:53:40 robertj * Fixed warnings on notrace version. * * Revision 1.10 1999/11/05 10:51:18 robertj * Fixed problem with new ixj channel doing incorrect double initialise * * Revision 1.9 1999/11/05 08:54:41 robertj * Rewrite of ixj interface code to fix support for arbitrary codecs. * * Revision 1.8 1999/11/02 00:24:29 robertj * Added GetCallerID() function and implemented some LineJACK code. * * Revision 1.7 1999/11/01 01:20:26 robertj * Added flunction to enabled/disable DTM detection * * Revision 1.6 1999/11/01 00:47:14 robertj * Fixed problems with stopping codecs * * Revision 1.5 1999/10/30 12:43:25 robertj * Fixed "lock up" problem, DTMF problem and added function to get line status. * * Revision 1.4 1999/10/28 12:21:34 robertj * Added AEC support and speakerphone switching button. * * Revision 1.3 1999/10/27 06:30:31 robertj * Added CancelIO command when closing channel. * * Revision 1.2 1999/10/24 14:51:41 robertj * Removed EnableDetectDTMF() as unix ioctl does not exist. * * Revision 1.1 1999/10/24 12:59:41 robertj * Added platform independent support for Quicknet xJACK cards. * */#include <ptlib.h>#include "ixjlid.h"#include <QTIoctl.h>#include <ixjDefs.h>#define new PNEWstatic BOOL IsWindows95(){ static OSVERSIONINFO version; if (version.dwOSVersionInfoSize == 0) { version.dwOSVersionInfoSize = sizeof(version); GetVersionEx(&version); } return version.dwPlatformId != VER_PLATFORM_WIN32_NT;}#define IsLineJACK() (dwCardType == 3)/////////////////////////////////////////////////////////////////////////////OpalIxJDevice::OpalIxJDevice(){ hDriver = INVALID_HANDLE_VALUE; readStopped = writeStopped = TRUE; readFrameSize = writeFrameSize = 480; // 30 milliseconds of 16 bit PCM data aecLevel = AECOff; lastDTMFDigit = 0;}BOOL OpalIxJDevice::Open(const PString & device){ Close(); PTRACE(3, "xJack\tOpening IxJ device \"" << device << '"'); static const char DevicePathPrefix[] = "\\\\.\\QTJackDevice"; DWORD dwDeviceId = device.AsUnsigned(16); PString devicePath; if (IsWindows95()) devicePath = "\\\\.\\Qtipj.vxd"; else { if (dwDeviceId < 100) { devicePath = device.Left(device.Find(' ')); if (strspn(devicePath, "0123456789") == strlen(devicePath)) devicePath = DevicePathPrefix + devicePath; } else { PStringArray allDevices = GetDeviceNames(); for (PINDEX dev = 0; dev < allDevices.GetSize(); dev++) { PString thisDevice = allDevices[dev]; if (thisDevice.Find(device) != P_MAX_INDEX) { devicePath = thisDevice.Left(thisDevice.Find(' ')); break; } } } } hDriver = CreateFile(devicePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL); if (hDriver == INVALID_HANDLE_VALUE) { osError = ::GetLastError(); return FALSE; } if (IsWindows95()) { DWORD dwResult = 0; if (!IoControl(IOCTL_Device_Open, dwDeviceId, &dwResult) || dwResult == 0) { CloseHandle(hDriver); hDriver = INVALID_HANDLE_VALUE; osError = ENOENT; return FALSE; } dwCardType = dwDeviceId >> 28; deviceName = psprintf("%08X", dwDeviceId); } else { PString prefix = devicePath.Mid(sizeof(DevicePathPrefix)-1); if (prefix == DevicePathPrefix) deviceName = prefix; else deviceName = devicePath; DWORD devId = 0, bytesReturned; if (DeviceIoControl(hDriver, IOCTL_Device_GetSerialNumber, NULL, 0, &devId, sizeof(devId), &bytesReturned, NULL) && bytesReturned == sizeof(devId) && devId != 0) dwCardType = devId >> 28; else { PINDEX pos = device.Find('('); if (pos != P_MAX_INDEX) dwCardType = device[pos+1]-'0'; else { PStringArray names = GetDeviceNames(); dwCardType = 0; for (PINDEX i = 0; i < names.GetSize(); i++) { if (names[i].Left(devicePath.GetLength()) == devicePath) { pos = names[i].Find('('); if (pos != P_MAX_INDEX) dwCardType = names[i][pos+1]-'0'; break; } } } } } IoControl(IOCTL_Idle_Idle); IoControl(IOCTL_Codec_SetKHz, 8000); IoControl(IOCTL_Idle_SetMasterGain, 15); IoControl(IOCTL_Filter_EnableDTMFDetect); PTRACE(2, "xJack\tOpened IxJ device " << GetName()); os_handle = 1; return TRUE;}BOOL OpalIxJDevice::Close(){ if (!IsOpen()) return FALSE; RingLine(0, 0); SetLineToLineDirect(0, 1, FALSE); IoControl(IOCTL_Record_Stop); IoControl(IOCTL_Playback_Stop); if (IsWindows95()) IoControl(IOCTL_Device_Close); deviceName = PString(); BOOL ok = CloseHandle(hDriver); hDriver = INVALID_HANDLE_VALUE; os_handle = -1; return ok;}PString OpalIxJDevice::GetName() const{ switch (dwCardType) { case 0 : case 1 : return "PhoneJACK (" + deviceName + ')'; case 3 : return "LineJACK (" + deviceName + ')'; case 4 : return "PhoneJACK-Lite (" + deviceName + ')'; } return "xJACK (" + deviceName + ')';}unsigned OpalIxJDevice::GetLineCount(){ return IsLineJACK() ? NumLines : 1;}BOOL OpalIxJDevice::IsLinePresent(unsigned line){ if (line >= GetLineCount()) return FALSE; if (line != PSTNLine) return FALSE; DWORD dwResult = 0; do { if (!IoControl(IOCTL_DevCtrl_GetLineTestResult, 0, &dwResult)) return FALSE; if (dwResult == 0xffffffff) { IoControl(IOCTL_DevCtrl_LineTest); dwResult = LINE_TEST_TESTING; } } while (dwResult == LINE_TEST_TESTING); return dwResult == LINE_TEST_OK;}BOOL OpalIxJDevice::IsLineOffHook(unsigned line){ if (line >= GetLineCount()) return FALSE; DWORD dwResult = 0; if (line == PSTNLine) { DWORD dwResult = 0; if (!IoControl(IOCTL_DevCtrl_GetLineOnHook, 0, &dwResult)) return FALSE; return dwResult == 0; } BOOL state = FALSE; for (PINDEX retry = 0; retry < 10; retry++) { dwResult = 0; if (!IoControl(IsLineJACK() ? IOCTL_DevCtrl_GetLinePhoneOnHook : IOCTL_DevCtrl_GetOnHook, 0, &dwResult)) return FALSE; if (dwResult != 0 && state) { state = FALSE; retry = 0; } else if (dwResult == 0 && !state) { state = TRUE; retry = 0; } Sleep(10); } return state;}BOOL OpalIxJDevice::SetLineOffHook(unsigned line, BOOL newState){ if (line >= GetLineCount()) return FALSE; if (line != PSTNLine) return FALSE; return IoControl(IOCTL_DevCtrl_LineSetOnHook, !newState);}BOOL OpalIxJDevice::IsLineRinging(unsigned line, DWORD * /*cadence*/){ if (line >= GetLineCount()) return FALSE; if (line != PSTNLine) return FALSE; if (ringTimeout.IsRunning()) return TRUE; DWORD dwResult = 0; if (!IoControl(IOCTL_DevCtrl_LineGetRinging, 0, &dwResult) || dwResult == 0)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -