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

📄 ixjunix.cxx

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

  char * str = ::getenv("IXJ_COUNTRY");
  if (str != NULL) {
    if (isdigit(*str))
      SetCountryCode((T35CountryCodes)atoi(str));
    else
      SetCountryCodeName(PString(str));
  }

  // make sure the PSTN line is on-hook
  pstnIsOffHook = FALSE;
  gotWink       = FALSE;
  IOCTL2(os_handle, PHONE_PSTN_SET_STATE, PSTN_ON_HOOK);

  inRawMode     = FALSE;

  SetAEC         (0, AECOff);
  SetRecordVolume(0, 100);
  SetPlayVolume  (0, 100);

  return TRUE;
}

BOOL OpalIxJDevice::Close()
{
  if (!IsOpen())
    return FALSE;

  StopReadCodec(0);
  StopWriteCodec(0);
  RingLine(0, 0);
  SetLineToLineDirect(0, 1, TRUE);
  deviceName = PString();

  // close the device
  int stat = ::close(os_handle);

  // remove the device from the exception information
  {
    PWaitAndSignal m(exceptionMutex);
    ExceptionInfo * info = GetException();
    info->fd = -1;
  }

  os_handle = -1;

  return ConvertOSError(stat);
}


PString OpalIxJDevice::GetDeviceType() const
{
  return OPAL_IXJ_TYPE_NAME;
}


PString OpalIxJDevice::GetDeviceName() const
{
  return deviceName;
}

PString OpalIxJDevice::GetDescription() const
{
  PStringStream name;

  name << "Internet ";

  switch (dwCardType) {
    case 0 :
    case 1 :
      name << "PhoneJACK";
      break;
    case 3 :
      name << "LineJACK";
      break;
    case 4 :
      name << "PhoneJACK-Lite";
      break;
    case 5 :
      name << "PhoneJACK-PCI";
      break;
    case 6 :
      name << "PhoneCARD";
      break;
    default :
      name << "xJACK";
  }

  name << " (" << deviceName << ')';

  return name;
}

PStringArray OpalIxJDevice::GetAllNames() const
{
  return GetDeviceNames();
}

unsigned OpalIxJDevice::GetLineCount()
{
  return 1;     
  /*Each card has just one line that can be active. 
    Consequently, return (IsLineJACK() ? NumLines : 1); is wrong.*/
}

BOOL OpalIxJDevice::IsLinePresent(unsigned line, BOOL /* force */)
{
  if (line != PSTNLine)
    return FALSE;

  BOOL stat = IOCTL(os_handle, IXJCTL_PSTN_LINETEST) == 1;
  PThread::Sleep(2000);

  // clear ring signal status
  IsLineRinging(line);

  return stat;
}


BOOL OpalIxJDevice::IsLineOffHook(unsigned line)
{
  if (line == PSTNLine) 
    return pstnIsOffHook;
  
  PWaitAndSignal m(exceptionMutex);
  ExceptionInfo * info = GetException();

#ifdef MANUAL_FLASH
  if (info->hookState != lastHookState) {
    lastHookState = info->hookState;
    if (lastHookState) {
	currentHookState = lastHookState;
    } else {
	hookTimeout = FLASH_TIME;
    }
  } else if (!hookTimeout.IsRunning() && (currentHookState != info->hookState)) 
    currentHookState = info->hookState;

  return currentHookState;
#else
  return info->hookState;
#endif
}

BOOL OpalIxJDevice::HasHookFlash(unsigned line)
{ 
  if (line != POTSLine)
    return FALSE;
  
  PWaitAndSignal m(exceptionMutex);
  ExceptionInfo * info = GetException();
  
  BOOL flash = info->hasFlash;
  info->hasFlash = FALSE;
  return flash;
}


BOOL OpalIxJDevice::SetLineOffHook(unsigned line, BOOL newState)
{
  if (line == POTSLine) {
#ifdef PHONE_WINK
    IOCTL(os_handle, PHONE_WINK);
    return TRUE;
#else
    return FALSE;
#endif
  }

  pstnIsOffHook = newState;

  if (!pstnIsOffHook) {
    StopReadCodec(line);
    StopWriteCodec(line);
  }

  // reset wink detected state going on or off hook 
  gotWink = FALSE;

  IOCTL2(os_handle, PHONE_PSTN_SET_STATE, pstnIsOffHook ? PSTN_OFF_HOOK : PSTN_ON_HOOK);

  return TRUE;
}

OpalIxJDevice::ExceptionInfo * OpalIxJDevice::GetException()
{
  PINDEX i;
  for (i = 0; i < MaxIxjDevices; i++) 
    if (exceptionInfo[i].fd == os_handle) 
      return &exceptionInfo[i];

  PAssertAlways("Cannot find open device in exception list");
  return NULL;
}


BOOL OpalIxJDevice::IsLineRinging(unsigned line, DWORD * /*cadence*/)
{
  if (line != PSTNLine)
    return FALSE;

  PWaitAndSignal m(exceptionMutex);
  ExceptionInfo * info = GetException();

  BOOL ring = info->hasRing;
  info->hasRing = FALSE;
  return ring;
}


BOOL OpalIxJDevice::RingLine(unsigned line, DWORD cadence)
{
  if (line != POTSLine)
    return FALSE;

  if (cadence == 0)
    return ConvertOSError(IOCTL(os_handle, PHONE_RING_STOP));

  //if (!ConvertOSError(IOCTL2(os_handle, PHONE_RING_CADENCE, cadence)))
  //  return FALSE;

  int stat;
 
  // Need to add something to set caller ID here
#if TELEPHONY_VERSION >= 3000
  if (callerIdInfo.name[0] != '\0') {
    stat = IOCTLP(os_handle, PHONE_RING_START, &callerIdInfo);
    SetCallerID(line, "");
  } else
#endif
    stat = IOCTL2(os_handle, PHONE_RING_START, 0);

  return ConvertOSError(stat);
}


BOOL OpalIxJDevice::RingLine(unsigned line, PINDEX nCadence, unsigned * pattern)
{
  if (line >= GetLineCount())
    return FALSE;

  if (line != POTSLine)
    return FALSE;

  return RingLine(line, nCadence != 0 ? 0xaaa : 0);
}


BOOL OpalIxJDevice::IsLineDisconnected(unsigned line, BOOL checkForWink)
{
  if (line >= GetLineCount())
    return FALSE;

  if (line != PSTNLine)
    return !IsLineOffHook(line);

  if (checkForWink) {

    // if we got a wink previously, hangup
    if (gotWink)
      return TRUE;

    // if we have not got a wink, then check for one
    PWaitAndSignal m(exceptionMutex);
    ExceptionInfo * info = GetException();

    gotWink = info->hasWink;
    info->hasWink = FALSE;
    if (gotWink) {
      PTRACE(3, "xJack\tDetected wink");
      return TRUE;
    }
  }


  if (IsToneDetected(line) & (BusyTone)) {
    PTRACE(3, "xJack\tDetected end of call tone");
    return TRUE;
  }

  return FALSE;
}

BOOL OpalIxJDevice::SetLineToLineDirect(unsigned line1, unsigned line2, BOOL connect)
{
  if (connect && (line1 != line2)) 
    IOCTL2(os_handle, IXJCTL_POTS_PSTN, 1);
  else 
    IOCTL2(os_handle, IXJCTL_POTS_PSTN, 0);

  return TRUE;
}


BOOL OpalIxJDevice::IsLineToLineDirect(unsigned line1, unsigned line2)
{
  return FALSE;
}

BOOL OpalIxJDevice::ConvertOSError(int err) 
{
  PChannel::Errors normalisedError;
  return PChannel::ConvertOSError(err, normalisedError, osError);
}


static const struct {
  const char * mediaFormat;
  PINDEX writeFrameSize;
  PINDEX readFrameSize;
  int mode;
  int frameTime;
  BOOL vad;
} CodecInfo[] = {
  /* NOTE: These are enumerated in reverse order. */
  { OPAL_PCM16,         480, 480, LINEAR16, 30, FALSE },   // 480 bytes = 240 samples = 30ms
  { OPAL_G711_ULAW_64K, 240, 240, ULAW,     30, FALSE },   // 240 bytes = 240 samples = 30ms
  { OPAL_G711_ALAW_64K, 240, 240, ALAW,     30, FALSE },   // 240 bytes = 240 samples = 30ms
  { OPAL_G728,           60,  60, G728,     30, FALSE },   // 60 bytes  = 12 frames   = 30ms
  { OPAL_G729A,          10,  10, G729,     10, FALSE },   // 10 bytes = 1 frame = 10 ms
  { OPAL_G729AB,         10,  10, G729B,    10,  TRUE },   // 10 bytes = 1 frame = 10 ms
  { OPAL_G7231_5k3 ,     24,  20, G723_53,  30, FALSE },   // 20 bytes = 1 frame = 30 ms
  { OPAL_G7231_6k3,      24,  24, G723_63,  30, FALSE },   // 24 bytes = 1 frame = 30 ms
  { OPAL_G7231A_5k3 ,    24,  20, G723_53,  30,  TRUE },   // 20 bytes = 1 frame = 30 ms
  { OPAL_G7231A_6k3,     24,  24, G723_63,  30,  TRUE }    // 24 bytes = 1 frame = 30 ms
};



OpalMediaFormatList OpalIxJDevice::GetMediaFormats() const
{
  OpalMediaFormatList codecs;

  PINDEX idx = PARRAYSIZE(CodecInfo);
  while (idx-- > 0) {
    phone_capability cap;
    cap.captype = codec;
    cap.cap = CodecInfo[idx].mode;
    if (IOCTLP(os_handle, PHONE_CAPABILITIES_CHECK, &cap))
      codecs += CodecInfo[idx].mediaFormat;
  }

  return codecs;
}


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 OpalIxJDevice::SetReadFormat(unsigned line, const OpalMediaFormat & mediaFormat)
{
  {
    PWaitAndSignal mutex(toneMutex);
    if (tonePlaying) {
      tonePlaying = FALSE;
      IOCTL(os_handle, PHONE_CPT_STOP);
    }
  }

  PWaitAndSignal mutex(readMutex);

  if (!readStopped) {
    IOCTL(os_handle, PHONE_REC_STOP);
    readStopped = TRUE;
    OpalLineInterfaceDevice::StopReadCodec(line);
  }

  readCodecType = FindCodec(mediaFormat);
  if (readCodecType == P_MAX_INDEX) {
    PTRACE(1, "xJack\tUnsupported read codec requested: " << mediaFormat);
    return FALSE;
  }

  if (!writeStopped && readCodecType != writeCodecType) {
    PTRACE(1, "xJack\tAsymmectric codecs requested: "
              "read=" << CodecInfo[readCodecType].mediaFormat <<
              " write=" << CodecInfo[writeCodecType].mediaFormat);
    return FALSE;
  }

  PTRACE(2, "IXJ\tSetting read codec to "
         << CodecInfo[readCodecType].mediaFormat
         << " code=" << CodecInfo[readCodecType].mode);

  readFrameSize = CodecInfo[readCodecType].readFrameSize;

  // set frame time
  if (writeStopped)
    IOCTL2(os_handle, PHONE_FRAME, CodecInfo[readCodecType].frameTime);

  int stat = IOCTL2(os_handle, PHONE_REC_CODEC, CodecInfo[readCodecType].mode);
  if (stat != 0) {
    PTRACE(1, "IXJ\tSecond try on set record codec");
    stat = IOCTL2(os_handle, PHONE_REC_CODEC, CodecInfo[readCodecType].mode);
    if (stat != 0) {
      PTRACE(1, "IXJ\tFailed second try on set record codec");
      return FALSE;
    }
  }

  // PHONE_REC_DEPTH does not set return value
  IOCTL2(os_handle, PHONE_REC_DEPTH, 1);

  // PHONE_REC_START does not set return value
  stat = IOCTL(os_handle, PHONE_REC_START);
  if (stat != 0) {
    return FALSE;
  }

  readStopped = FALSE;

  return TRUE;
}

BOOL OpalIxJDevice::SetWriteFormat(unsigned line, const OpalMediaFormat & mediaFormat)
{
  {
    PWaitAndSignal mutex(toneMutex);
    if (tonePlaying) {
      tonePlaying = FALSE;
      IOCTL(os_handle, PHONE_CPT_STOP);
    }
  }

  PWaitAndSignal mutex(readMutex);

  if (!writeStopped) {
    IOCTL(os_handle, PHONE_PLAY_STOP);
    writeStopped = TRUE;
    OpalLineInterfaceDevice::StopWriteCodec(line);
  }


  writeCodecType = FindCodec(mediaFormat);
  if (writeCodecType == P_MAX_INDEX) {
    PTRACE(1, "xJack\tUnsupported write codec requested: " << mediaFormat);
    return FALSE;
  }

  if (!readStopped && writeCodecType != readCodecType) {
    PTRACE(1, "xJack\tAsymmectric codecs requested: "
              "read=" << CodecInfo[readCodecType].mediaFormat <<
              " write=" << CodecInfo[writeCodecType].mediaFormat);
    return FALSE;
  }

  PTRACE(2, "IXJ\tSetting write codec to "
         << CodecInfo[writeCodecType].mediaFormat
         << " code=" << CodecInfo[writeCodecType].mode);

  writeFrameSize = CodecInfo[writeCodecType].writeFrameSize;

  // set frame time
  if (readStopped)
    IOCTL2(os_handle, PHONE_FRAME, CodecInfo[writeCodecType].frameTime);

⌨️ 快捷键说明

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