⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vblasterlid.cxx

📁 sloedgy open sip stack source code
💻 CXX
📖 第 1 页 / 共 3 页
字号:


BOOL OpalVoipBlasterDevice::GetRemoveDTMF(unsigned)
{
  return TRUE;
}


BOOL OpalVoipBlasterDevice::SetRemoveDTMF(unsigned, BOOL /*state*/)
{
  return TRUE;
}


unsigned OpalVoipBlasterDevice::IsToneDetected(unsigned /*line*/)
{
  return FALSE;
}


BOOL OpalVoipBlasterDevice::PlayTone(unsigned /*line*/, CallProgressTones /*tone*/)
{
  return FALSE;
}

BOOL OpalVoipBlasterDevice::IsTonePlaying(unsigned)
{
  return FALSE;
}


BOOL OpalVoipBlasterDevice::StopTone(unsigned)
{
  return FALSE;
}


DWORD OpalVoipBlasterDevice::GetSerialNumber()
{
  return 0;
}


PStringArray OpalVoipBlasterDevice::GetDeviceNames()
{
  PStringArray array;

  VoipBlasterInterface blaster;
  PINDEX i = 0;
  while ((i < 16) && blaster.IsDevicePresent(i)) {
    array[i] = i;
    i++;
  }

  return array;
}

BOOL OpalVoipBlasterDevice::SetCountryCode(T35CountryCodes /*country*/)
{
  return TRUE;
}


/////////////////////////////////////////////////////////////////////////////

OpalVoipBlasterDevice::ByteQueue::ByteQueue(PINDEX _qMax)
  : qMax(_qMax)
{
  qOut = qLen = 0;
  queue.SetSize(qMax);
}

int OpalVoipBlasterDevice::ByteQueue::Dequeue()
{
  PWaitAndSignal m(mutex);
  if (qLen == 0)
    return -1;

  int v = queue[qOut];

  qOut = (qOut % qMax);
  qLen--;

  return v;
}

BOOL OpalVoipBlasterDevice::ByteQueue::Enqueue(BYTE v)
{
  PWaitAndSignal m(mutex);

  if (qLen == qMax)
    return FALSE;

  queue[(qOut + qLen) % qMax] = v;
  qLen++;

  return TRUE;
}


/////////////////////////////////////////////////////////////////////////////

#ifdef _WIN32

#include <initguid.h>
#include <setupapi.h>

#pragma comment(lib, "setupapi.lib")

// {00873FDF-61A8-11d1-AA5E-00C04FB1728B}  for VB_USB.SYS

DEFINE_GUID(GUID_CLASS_VOIP_BLASTER,
  0x873fdf, 0x61a8, 0x11d1, 0xaa, 0x5e, 0x0, 0xc0, 0x4f, 0xb1, 0x72, 0x8b);

static BOOL GetDeviceInterfacePath(HDEVINFO hDevInfo,
                                   PSP_DEVICE_INTERFACE_DATA pDeviceInterfaceData,
                                   char *dest, DWORD dwMaxLen)
{
  PSP_INTERFACE_DEVICE_DETAIL_DATA pDetailData     = NULL;
  ULONG                            requiredLength  =    0;

  // allocate a function class device data structure to receive the
  // goods about this particular device.
  SetupDiGetInterfaceDeviceDetail(hDevInfo,
            pDeviceInterfaceData, //
            NULL,            // probing so no output buffer yet
            0,               // probing so output buffer length of zero
            &requiredLength, //
            NULL);           // not interested in the specific dev-node

  pDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)LocalAlloc(LPTR, requiredLength);
  ZeroMemory(pDetailData, requiredLength );
  pDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);

  // Retrieve the information from Plug and Play.
  if (!SetupDiGetDeviceInterfaceDetail(hDevInfo,
               pDeviceInterfaceData,
               pDetailData,
               requiredLength,
               NULL,
               NULL)) {
    PTRACE(1, "VB\tError " << GetLastError() << " in GetDeviceInterfacePath");
    LocalFree(pDetailData);
    return FALSE;
  }

  strncpy(dest,pDetailData->DevicePath, dwMaxLen);
  LocalFree(pDetailData);
  return TRUE;
}

static BOOL GetDevicePath( LPGUID pGuid, DWORD dwIndex, char *dest, DWORD dwMaxLen )
{
  
  SP_DEVINFO_DATA DeviceInfoData;
  SP_DEVICE_INTERFACE_DATA DeviceInterfaceData;
  BOOL result;

    // Create a HDEVINFO with all present devices.
  HDEVINFO hDevInfoList = SetupDiGetClassDevs(
        pGuid,  // this guid only
        0,      // Enumerator
        0,
        DIGCF_PRESENT | DIGCF_INTERFACEDEVICE );
    
  if (hDevInfoList == INVALID_HANDLE_VALUE) {
    PTRACE(1, "VB\tError " << GetLastError() << " in GetDevicePath:SetupDiGetClassDevs");
    return FALSE;
  }
    
  // Get the Info for the specific device instance (dwIndex)
  DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
  if (!SetupDiEnumDeviceInfo(hDevInfoList, dwIndex, &DeviceInfoData)) {
    PTRACE(1, "VB\tError " << GetLastError() << " in GetDevicePath:SetupDiEnumDeviceInfo");
    SetupDiDestroyDeviceInfoList(hDevInfoList); // Cleanup
    return FALSE;
  }

  // for the desired interface, get the path
  ZeroMemory(&DeviceInterfaceData, sizeof(DeviceInterfaceData));
  DeviceInterfaceData.cbSize = sizeof(DeviceInterfaceData);
  if(!SetupDiEnumDeviceInterfaces(hDevInfoList, &DeviceInfoData, pGuid, 0, &DeviceInterfaceData)) {
    PTRACE(1, "VB\tError " << GetLastError() << " in GetDevicePath:SetupDiEnumDeviceInterfaces");
    SetupDiDestroyDeviceInfoList(hDevInfoList); // Cleanup
    return FALSE;
  }

  result = GetDeviceInterfacePath( hDevInfoList, &DeviceInterfaceData, dest, dwMaxLen );
    
  SetupDiDestroyDeviceInfoList(hDevInfoList); // Cleanup

  return result;
}

static HANDLE OpenPipe(const PString & filename, DWORD dwIndex)
{
  char completeDeviceName[256] = "";

  if (!GetDevicePath((LPGUID)&GUID_CLASS_VOIP_BLASTER, dwIndex, 
        completeDeviceName, sizeof(completeDeviceName))) {
    return  INVALID_HANDLE_VALUE;
  }

  strcat(completeDeviceName, "\\" );
  strcat(completeDeviceName, filename);

  HANDLE h = CreateFile(completeDeviceName, 
                        GENERIC_WRITE | GENERIC_READ,
                        FILE_SHARE_WRITE | FILE_SHARE_READ, 
                        NULL, 
                        OPEN_EXISTING, 
                        FILE_FLAG_OVERLAPPED, 
                        NULL);

  if (h == INVALID_HANDLE_VALUE) {
    PTRACE(1, "Failed to open " << completeDeviceName << " : " << GetLastError());
  }

  return h;
}


/////////////////////////////////////////////////////////////////////////////

VoipBlasterInterface::VoipBlasterInterface()
{
  deviceIndex = P_MAX_INDEX;
  PINDEX i;
  for (i = 0; i < NumPipes; i++) 
    pipes[i] = INVALID_HANDLE_VALUE;

}

BOOL VoipBlasterInterface::IsDevicePresent(PINDEX deviceIndex)
{
  char completeDeviceName[256] = "";

  return GetDevicePath((LPGUID)&GUID_CLASS_VOIP_BLASTER, deviceIndex, 
        completeDeviceName, sizeof(completeDeviceName));
}


BOOL VoipBlasterInterface::OpenCommand(PINDEX _deviceIndex)
{
  CloseCommand();

  deviceIndex = _deviceIndex;

  // open the command and status pipes to the driver
  if (!OpenVOIPPipe(CommandPipe)) {
    PTRACE(1, "VB\tOpen of command pipe failed");
    CloseCommand();
    return FALSE;
  }

  if (!OpenVOIPPipe(StatusPipe)) {
    PTRACE(1, "VB\tOpen of status pipe failed");
    CloseCommand();
    return FALSE;
  }

  return TRUE;
}

BOOL VoipBlasterInterface::CloseCommand()
{
  CloseData();

  if (deviceIndex == P_MAX_INDEX)
    return FALSE;

  CloseHandle(pipes[CommandPipe]);
  pipes[CommandPipe] = INVALID_HANDLE_VALUE;

  CloseHandle(pipes[StatusPipe]);
  pipes[StatusPipe] = INVALID_HANDLE_VALUE;

  deviceIndex = P_MAX_INDEX;

  return TRUE;
}


BOOL VoipBlasterInterface::OpenData()
{
  if (deviceIndex == P_MAX_INDEX)
    return FALSE;

  // open the data pipes to the driver
  if (!OpenVOIPPipe(VoiceOutPipe)) {
    PTRACE(1, "VB\tOpen of command pipe failed");
    CloseCommand();
    return FALSE;
  }

  if (!OpenVOIPPipe(VoiceInPipe)) {
    PTRACE(1, "VB\tOpen of status pipe failed");
    CloseCommand();
    return FALSE;
  }

  return TRUE;
}


BOOL VoipBlasterInterface::CloseData()
{
  if (deviceIndex == P_MAX_INDEX)
    return FALSE;

  CloseHandle(pipes[VoiceOutPipe]);
  pipes[VoiceOutPipe] = INVALID_HANDLE_VALUE;

  CloseHandle(pipes[VoiceInPipe]);
  pipes[VoiceInPipe] = INVALID_HANDLE_VALUE;

  return TRUE;
}

BOOL VoipBlasterInterface::OpenVOIPPipe(VoipBlasterInterface::Pipe pipeIndex)
{
  if (deviceIndex == P_MAX_INDEX)
    return FALSE;

  return (pipes[pipeIndex] = OpenPipe(psprintf("PIPE%02i", pipeIndex), deviceIndex)) != INVALID_HANDLE_VALUE;
}


BOOL VoipBlasterInterface::WriteCommand(Command cmd)
{
  BYTE b = (BYTE)cmd;
  return WritePipe(pipes[CommandPipe], &b, 1) == 1;
}

VoipBlasterInterface::Status VoipBlasterInterface::ReadStatus(const PTimeInterval duration)
{
  BYTE b;
  if (ReadPipe(pipes[StatusPipe], &b, 1, duration) == 1)
    return (Status)b;

  return Status_Empty;
}

BOOL VoipBlasterInterface::WriteData(const void * data, PINDEX len)
{
  return WritePipe(pipes[VoiceOutPipe], data, len) == len;
}

int VoipBlasterInterface::ReadData(void * data, PINDEX len, const PTimeInterval duration)
{
  return ReadPipe(pipes[VoiceInPipe], data, len, duration);
}

void VoipBlasterInterface::Flush(const PTimeInterval wait)
{
  BYTE buffer[1000];
  while (ReadData(buffer, 1000, wait) > 0)
    ;

  while (ReadPipe(pipes[StatusPipe], buffer, 1000, wait) > 0)
    ;

#if 0
  BOOL closeOnEnd = (pipes[VoiceInPipe] == INVALID_HANDLE_VALUE);
  if (closeOnEnd && !OpenVOIPPipe(VoiceInPipe)) {
    PTRACE(2, "VB\tCould not open voice in pipe for flush");
    return;
  }

  PTimer closeTimer;
  closeTimer.SetNotifier(PCREATE_NOTIFIER(CloseTimeout));
  closeTimer = wait;
  PINDEX count = 0;
  for (;;) {
    BYTE b;
    if (ReadPipe(pipes[VoiceInPipe], &b, 1) != 1)
      break;
    count++;
    closeTimer.Reset();
  }

  closeTimer.Stop();

  PError << "Flushed " << count << " bytes" << endl;
#endif
}

void VoipBlasterInterface::CloseTimeout(PTimer &, INT)
{
  if (pipes[VoiceInPipe] != INVALID_HANDLE_VALUE) {
    CloseHandle(pipes[VoiceInPipe]);
    pipes[VoiceInPipe] = INVALID_HANDLE_VALUE;
  }
}

int VoipBlasterInterface::WritePipe(HANDLE handle, const void *bp, DWORD len)
{
  DWORD writeCount;
  PWin32Overlapped overlap;

  ResetEvent(overlap.hEvent);

  if (::WriteFile(handle, bp, len, &writeCount, &overlap))
    return writeCount; 

  if (GetLastError() != ERROR_IO_PENDING) {
    PTRACE(1, "VB\tWriteFile to pipe failed");
    return -1;
  }

  if (!GetOverlappedResult(handle, &overlap, &writeCount, TRUE)) {
    PTRACE(1, "VB\tGetOverlappedResult on pipe failed");
    return -1;
  }
  
  return writeCount;
}


int VoipBlasterInterface::ReadPipe(HANDLE handle, void *bp, DWORD len, const PTimeInterval duration)
{
  DWORD readCount;
  PWin32Overlapped overlap;

  ResetEvent(overlap.hEvent);

  if (::ReadFile(handle, bp, len, &readCount, &overlap))
    return readCount;

  if (GetLastError() != ERROR_IO_PENDING) {
    PTRACE(1, "VB\tReadFile from pipe failed");
    return -1;
  }

  DWORD msecs = (duration == PMaxTimeInterval) ? INFINITE : duration.GetInterval();
  if (msecs < 500)
    msecs = 500;

  switch (WaitForSingleObject(overlap.hEvent, msecs)) {
    case WAIT_OBJECT_0:
      // do nothing ; the device is ready
      break;

    case WAIT_TIMEOUT:
      // cancel the I/O operation;
      CancelIo(handle);
      break;

    default:
      PTRACE(1, "VB\tWaitForSingleObject on pipe failed");
      return -1;
  }

  if (!GetOverlappedResult(handle, &overlap, &readCount, TRUE)) {
    PTRACE(1, "VB\tGetOverlappedResult on pipe failed");
    return -1;
  }

  return readCount;
}


#endif // _WIN32

#endif // HAS_VBLASTER

/////////////////////////////////////////////////////////////////////////////

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -