📄 vpblid.cxx
字号:
/*
* vpblid.cxx
*
* Voicetronix VPB4 line interface device
*
* 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.
*
* Contributor(s): ______________________________________.
*
* Patch: 2002/10/4 Peter Wintulich Peter@voicetronix.com.au
* IsLineDisconected was looking for any tone to signify hangup/busy.
* Changed so only BUSY tone reports line hangup/busy.
*
* $Log: vpblid.cxx,v $
* Revision 1.2 2007/06/04 16:06:30 joegenbaclor
* *** empty log message ***
*
* Revision 1.1 2006/06/26 03:03:21 joegenbaclor
* I have decided to include the latest development realease of OPAL tagged Deimos Devel 1 (June 8 2006) as inegrated classes to opensipstack to avoid future version conflicts due to the fast pace in OPAL development. This move is also aimed to reduce the size of projects using OPAL componets such as the soon to be relased OpenSIPPhone.
*
* Revision 2.9 2004/10/06 13:03:42 rjongbloed
* Added "configure" support for known LIDs
* Changed LID GetName() function to be normalised against the GetAllNames()
* return values and fixed the pre-factory registration system.
* Added a GetDescription() function to do what the previous GetName() did.
*
* Revision 2.8 2004/02/19 10:47:05 rjongbloed
* Merged OpenH323 version 1.13.1 changes.
*
* Revision 2.7 2003/03/24 07:18:30 robertj
* Added registration system for LIDs so can work with various LID types by
* name instead of class instance.
*
* Revision 2.6 2002/09/04 06:01:49 robertj
* Updated to OpenH323 v1.9.6
*
* Revision 2.5 2002/07/01 04:56:33 robertj
* Updated to OpenH323 v1.9.1
*
* Revision 2.4 2002/03/22 06:57:50 robertj
* Updated to OpenH323 version 1.8.2
*
* Revision 2.3 2002/01/14 06:35:58 robertj
* Updated to OpenH323 v1.7.9
*
* Revision 2.2 2001/10/05 00:22:14 robertj
* Updated to PWLib 1.2.0 and OpenH323 1.7.0
*
* Revision 2.1 2001/08/01 05:21:21 robertj
* Made OpalMediaFormatList class global to help with documentation.
*
* Revision 2.0 2001/07/27 15:48:25 robertj
* Conversion of OpenH323 to Open Phone Abstraction Library (OPAL)
*
* Revision 1.21 2003/08/13 22:02:03 dereksmithies
* Apply patch from Daniel Bichara to GetOSHandle() for VPB devices. Thanks.
*
* Revision 1.20 2003/03/12 00:15:40 dereks
* Fix compile error on RH8.0
*
* Revision 1.19 2003/03/05 06:26:44 robertj
* Added function to play a WAV file to LID, thanks Pietro Ravasio
*
* Revision 1.18 2002/09/03 06:22:26 robertj
* Cosmetic change to formatting.
*
* Revision 1.17 2002/08/01 01:33:42 dereks
* Adjust verbosity of PTRACE statements.
*
* Revision 1.16 2002/07/02 03:20:37 dereks
* Fix check for line disconnected state. Remove timer on line ringing.
*
* Revision 1.15 2002/07/01 23:57:35 dereks
* Clear dtmf and tone event queue when changing hook status, to remove spurious events.
*
* Revision 1.14 2002/07/01 02:52:52 dereks
* IsToneDetected now reports the RING tone. Add PTRACE statements.
*
* Revision 1.13 2002/05/21 09:16:31 robertj
* Fixed segmentation fault, if OpalVPBDevice::StopTone() is called more than
* once, thanks Artis Kugevics
*
* Revision 1.12 2002/03/20 06:05:04 robertj
* Improved multithreading support, thanks David Rowe
* NOTE: only works with VPB driver version 2.5.5
*
* Revision 1.11 2001/11/19 06:35:41 robertj
* Added tone generation handling
*
* Revision 1.10 2001/10/05 03:51:21 robertj
* Added missing pragma implementation
*
* Revision 1.9 2001/10/05 03:33:06 robertj
* Fixed compatibility with latest VPB drivers
*
* Revision 1.8 2001/09/13 05:27:46 robertj
* Fixed incorrect return type in virtual function, thanks Vjacheslav Andrejev
*
* Revision 1.7 2001/05/11 04:43:43 robertj
* Added variable names for standard PCM-16 media format name.
*
* Revision 1.6 2001/01/25 07:27:17 robertj
* Major changes to add more flexible OpalMediaFormat class to normalise
* all information about media types, especially codecs.
*
* Revision 1.5 2000/11/24 10:54:45 robertj
* Modified the ReadFrame/WriteFrame functions to allow for variable length codecs.
*
* Revision 1.4 2000/11/20 04:37:03 robertj
* Changed tone detection API slightly to allow detection of multiple
* simultaneous tones
*
* Revision 1.3 2000/05/02 04:32:28 robertj
* Fixed copyright notice comment.
*
* Revision 1.2 2000/01/07 08:28:09 robertj
* Additions and changes to line interface device base class.
*
* Revision 1.1 1999/12/23 23:02:36 robertj
* File reorganision for separating RTP from H.323 and creation of LID for VPB support.
*
*/
#include <ptlib.h>
#ifdef __GNUC__
#pragma implementation "vpblid.cxx"
#endif
#include <lids/vpblid.h>
////////////////////////////////////////////////
/// Get rid of LNK4221: no public symbols found;
/// archive member will be inaccessible
const char * vpdlid_file_content = NULL;
////////////////////////////////////////////////
#if HAS_VPB
#define new PNEW
#ifdef _MSC_VER
#pragma comment(lib, VPB_LIBRARY)
#endif
/////////////////////////////////////////////////////////////////////////////
OpalVpbDevice::OpalVpbDevice()
{
cardNumber = 0;
lineCount = 0;
vpb_seterrormode(VPB_ERROR_CODE);
}
BOOL OpalVpbDevice::Open(const PString & device)
{
Close();
cardNumber = device.AsUnsigned(10);
lineCount = 0;
while (lineCount < MaxLineCount && lineState[lineCount].Open(cardNumber, lineCount))
lineCount++;
os_handle = lineCount > 0 ? 1 : -1;
return IsOpen();
}
BOOL OpalVpbDevice::LineState::Open(unsigned cardNumber, unsigned lineNumber)
{
handle = vpb_open(cardNumber, lineNumber+1);
if (handle < 0)
return FALSE;
readIdle = writeIdle = TRUE;
readFrameSize = writeFrameSize = 480;
currentHookState = FALSE;
vpb_sethook_sync(handle, VPB_ONHOOK);
vpb_set_event_mask(handle, VPB_MRING | VPB_MTONEDETECT );
myToneThread = NULL;
return TRUE;
}
BOOL OpalVpbDevice::Close()
{
for (unsigned line = 0; line < lineCount; line++)
vpb_close(lineState[line].handle);
os_handle = -1;
return TRUE;
}
PString OpalVpbDevice::GetDeviceType() const
{
return OPAL_VPB_TYPE_NAME;
}
PString OpalVpbDevice::GetDeviceName() const
{
return psprintf("%u", cardNumber);
}
PStringArray OpalVpbDevice::GetAllNames() const
{
PStringArray devices(1);
devices[0] = "0";
return devices;
}
PString OpalVpbDevice::GetDescription() const
{
char buf[100];
vpb_get_model(buf);
return psprintf("VoiceTronics %s (%u)", buf, cardNumber);
}
unsigned OpalVpbDevice::GetLineCount()
{
return lineCount;
}
BOOL OpalVpbDevice::IsLineDisconnected(unsigned line, BOOL /*checkForWink*/)
{
// unsigned thisTone = IsToneDetected(line);
BOOL lineIsDisconnected = (IsToneDetected(line) == BusyTone);
PTRACE(3, "VPB\tLine " << line << " is disconnected: " << (lineIsDisconnected ? " TRUE" : "FALSE"));
return lineIsDisconnected;
}
BOOL OpalVpbDevice::IsLineOffHook(unsigned line)
{
if (line >= MaxLineCount)
return FALSE;
return lineState[line].currentHookState;
}
BOOL OpalVpbDevice::SetLineOffHook(unsigned line, BOOL newState)
{
if (line >= MaxLineCount)
return FALSE;
return lineState[line].SetLineOffHook(newState);
}
BOOL OpalVpbDevice::LineState::SetLineOffHook(BOOL newState)
{
currentHookState = newState;
VPB_EVENT event;
BOOL setHookOK = vpb_sethook_sync(handle, newState ? VPB_OFFHOOK : VPB_ONHOOK) >= 0;
PTRACE(3, "vpb\tSetLineOffHook to " << (newState ? "offhook" : "on hook") <<
(setHookOK ? " succeeded." : " failed."));
// clear DTMF buffer and event queue after changing hook state.
vpb_flush_digits(handle);
while (vpb_get_event_ch_async(handle, &event) == VPB_OK);
return setHookOK;
}
BOOL OpalVpbDevice::IsLineRinging(unsigned line, DWORD * cadence)
{
if (line >= MaxLineCount)
return FALSE;
return lineState[line].IsLineRinging(cadence);
}
BOOL OpalVpbDevice::LineState::IsLineRinging(DWORD * /*cadence*/)
{
VPB_EVENT event;
BOOL lineIsRinging = FALSE;
if (currentHookState) {
PTRACE(6, "VPB\tTest IsLineRinging() returns FALSE");
return FALSE;
}
// DR 13/1/02 - Dont look at event queue here if off hook, as we will steal events
// that IsToneDetected may be looking for.
if (vpb_get_event_ch_async(handle, &event) == VPB_OK)
if (event.type == VPB_RING) {
PTRACE(3, "VPB\tRing event detected in IsLineRinging");
lineIsRinging = TRUE;
}
return lineIsRinging;
}
static const struct {
const char * mediaFormat;
WORD mode;
} CodecInfo[] = {
{ OPAL_PCM16, VPB_LINEAR },
{ "G.711-uLaw-64k", VPB_MULAW },
{ "G.711-ALaw-64k", VPB_ALAW },
};
OpalMediaFormatList OpalVpbDevice::GetMediaFormats() const
{
OpalMediaFormatList formats;
for (PINDEX i = 0; i < PARRAYSIZE(CodecInfo); i++)
formats += CodecInfo[i].mediaFormat;
return formats;
}
static PINDEX FindCodec(const OpalMediaFormat & mediaFormat)
{
for (PINDEX codecType = 0; codecType < PARRAYSIZE(CodecInfo); codecType++) {
if (mediaFormat == CodecInfo[codecType].mediaFormat)
return codecType;
}
return P_MAX_INDEX;
}
BOOL OpalVpbDevice::SetReadFormat(unsigned line, const OpalMediaFormat & mediaFormat)
{
if (line >= MaxLineCount)
return FALSE;
PTRACE(4, "VPB\tSetReadFormat(" << mediaFormat << ')');
lineState[line].readFormat = FindCodec(mediaFormat);
if (lineState[line].readFormat == P_MAX_INDEX)
return FALSE;
if (vpb_record_buf_start(lineState[line].handle,
CodecInfo[lineState[line].readFormat].mode) < 0)
return FALSE;
lineState[line].readIdle = FALSE;
return TRUE;
}
BOOL OpalVpbDevice::SetWriteFormat(unsigned line, const OpalMediaFormat & mediaFormat)
{
if (line >= MaxLineCount)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -