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

📄 ixjunix.cxx

📁 sloedgy open sip stack source code
💻 CXX
📖 第 1 页 / 共 5 页
字号:
  case 0:
  case PhoneJACK:
    dspMax = isPlay ? 0x100 : 0x200;
    break;
  case LineJACK:
    dspMax = 0x200;
    break;
  case PhoneJACK_Lite:
    dspMax = 0x200;
    break;
  case PhoneJACK_PCI:
    dspMax = 0x100;
    break;
  case PhoneCARD:
    dspMax = 0x200;
    break;    
  case PhoneJACK_PCI_TJ:
    if (line == POTSLine)
      dspMax = 0x100;
    else
      dspMax = 0x60;
  }

/* The dsp volume is exponential in nature.
   You can plot this exponential function with gnuplot.
   gnuplot
   plot [t=0:100] exp((t/20) -1) / exp(4) */
  PINDEX res = (PINDEX) (dspMax * exp((((double)volume) / 20.0) - 1) / exp(4.0));

  return res;
}
 

BOOL OpalIxJDevice::SetRecordVolume(unsigned line, unsigned volume)
{
  PWaitAndSignal mutex1(readMutex);
  userRecVol = volume;
  if ((aecLevel == AECAGC) || inRawMode)
    return TRUE;

  return IOCTL2(os_handle, IXJCTL_REC_VOLUME, LogScaleVolume(line, volume, FALSE));
}

BOOL OpalIxJDevice::GetRecordVolume(unsigned, unsigned & volume)
{
  volume = userRecVol;
  return TRUE;
}

BOOL OpalIxJDevice::SetPlayVolume(unsigned line, unsigned volume)
{
  PWaitAndSignal mutex1(readMutex);
  userPlayVol = volume;
  if (inRawMode)
    return TRUE;

  return IOCTL2(os_handle, IXJCTL_PLAY_VOLUME, LogScaleVolume(line, volume, TRUE));
}

BOOL OpalIxJDevice::GetPlayVolume(unsigned, unsigned & volume)
{
  volume = userPlayVol;
  return TRUE;
}

OpalLineInterfaceDevice::AECLevels OpalIxJDevice::GetAEC(unsigned)
{
  return aecLevel;
}


BOOL OpalIxJDevice::SetAEC(unsigned line, AECLevels level)
{
  aecLevel = level;

  if (inRawMode)
    return TRUE;

  // IXJCTL_AEC_START does not set return code
  IOCTL2(os_handle, IXJCTL_AEC_START, aecLevel);

  // if coming out of AGC mode, then set record volume just in case
  if (aecLevel == AECAGC)
    SetRecordVolume(line, userRecVol);

  return TRUE;
}


unsigned OpalIxJDevice::GetWinkDuration(unsigned)
{
  if (!IsOpen())
    return 0;

  return IOCTL2(os_handle, IXJCTL_WINK_DURATION, 0);
}


BOOL OpalIxJDevice::SetWinkDuration(unsigned, unsigned winkDuration)
{
  if (!IsOpen())
    return FALSE;  

  return IOCTL2(os_handle, IXJCTL_WINK_DURATION, winkDuration);
}


BOOL OpalIxJDevice::GetVAD(unsigned)
{
  return FALSE;
}


BOOL OpalIxJDevice::SetVAD(unsigned, BOOL)
{
  return FALSE;
}


BOOL OpalIxJDevice::GetCallerID(unsigned line, PString & callerId, BOOL /*full*/)
{
#if TELEPHONY_VERSION < 3000
  return FALSE;
#else

  if (line != PSTNLine)
    return FALSE;

  // string is "number <TAB> time <TAB> name"

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

  if (info->hasCid) {
    PHONE_CID cid = info->cid;
    callerId  = PString(cid.number, cid.numlen) + '\t';
    callerId += PString(cid.hour, 3) + ':' + PString(cid.min, 3) + ' ' + PString(cid.month, 3) + '/' + PString(cid.day, 3) + '\t';
    callerId += PString(cid.name, cid.namelen);
    info->hasCid = FALSE;
    return TRUE;
  }

  return FALSE;
#endif
}

#if TELEPHONY_VERSION >= 3000

static BOOL IsPhoneDigits(const PString & str)
{
  PINDEX i;
  for (i = 0; i < str.GetLength(); i++) 
    if (!isdigit(str[i]) && str[i] != '*' && str[i] != '#')
      return FALSE;
  return TRUE;
}

static void FormatCallerIdString(const PString & idString, PHONE_CID & callerIdInfo)
{
  memset(&callerIdInfo, 0, sizeof(callerIdInfo));

  if (idString.IsEmpty())
    return;

  PString name, number;
  PTime theTime;

// string is "number <TAB> time <TAB> name"

  PStringArray fields = idString.Tokenise('\t', TRUE);
  int len = fields.GetSize();

  // if the name is specified, then use it
  if (len > 2)
    name = fields[2];

  // if the time is specified, then use it
  if (len > 1 && !fields[1].IsEmpty())
    theTime = PTime(fields[1]);

  // if the number is specified, then only use it if it is legal
  // otherwise put it into the name field
  if (len > 0) {
    if (IsPhoneDigits(fields[0]))
      number = fields[0];
    else if (name.IsEmpty())
      name = fields[0];
  }

  // truncate name and number fields
  if (name.GetLength() > (PINDEX)sizeof(callerIdInfo.name))
    name = name.Left(sizeof(callerIdInfo.name));
  if (number.GetLength() > (PINDEX)sizeof(callerIdInfo.number))
    number = number.Left(sizeof(callerIdInfo.number));

  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);
  callerIdInfo.namelen = name.GetLength();
  strncpy(callerIdInfo.number,  (const char *)number, sizeof(callerIdInfo.number)-1);
  callerIdInfo.numlen = number.GetLength();
}
#endif

BOOL OpalIxJDevice::SetCallerID(unsigned line, const PString & idString)
{
#if TELEPHONY_VERSION < 3000
  return FALSE;
#else
  if (line != POTSLine)
    return FALSE;

  FormatCallerIdString(idString, callerIdInfo);
#endif

  return TRUE;
}

BOOL OpalIxJDevice::SendCallerIDOnCallWaiting(unsigned line, const PString & idString)
{
#if TELEPHONY_VERSION < 3000
  return FALSE;
#else
  if (line != POTSLine)
    return FALSE;

  PHONE_CID callerInfo;
  FormatCallerIdString(idString, callerInfo);
  IOCTLP(os_handle, IXJCTL_CIDCW, &callerInfo);
  return TRUE;
#endif
}


BOOL OpalIxJDevice::SendVisualMessageWaitingIndicator(unsigned line, BOOL on)
{
#if TELEPHONY_VERSION < 3000
  return FALSE;
#else
  if (line != POTSLine)
    return FALSE;

  IOCTL2(os_handle, IXJCTL_VMWI, on);

  return TRUE;
#endif
}


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;

  IOCTL2(os_handle, PHONE_SET_TONE_ON_TIME,  onTime  * 4);
  IOCTL2(os_handle, PHONE_SET_TONE_OFF_TIME, offTime * 4);

  while (*tones != '\0') {

    char tone = toupper(*tones++);

    int code = -1;
    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 if ('E' <= tone && tone <= ('E' + 11))
      code = (tone - 'E') + 13;

    PTRACE(4, "IXJ\tPlaying tone " << tone);

    IOCTL2(os_handle, PHONE_PLAY_TONE, code);

    PThread::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::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)
{
  PWaitAndSignal m(exceptionMutex);
  ExceptionInfo * info = GetException();

  int p = info->dtmfOut;

  if (info->dtmfIn == p)
    return '\0';

  char ch = info->dtmf[p];
  p = (p + 1) % 16;
  info->dtmfOut = p;

  return ch;
}


BOOL OpalIxJDevice::GetRemoveDTMF(unsigned)
{
  return removeDTMF;
}


BOOL OpalIxJDevice::SetRemoveDTMF(unsigned, BOOL state)
{
  removeDTMF = state;
  return IOCTL2(os_handle, PHONE_DTMF_OOB, state);
}


unsigned OpalIxJDevice::IsToneDetected(unsigned)
{
  PWaitAndSignal m(exceptionMutex);
  ExceptionInfo * info = GetException();

  int tones = NoTone;

  if (info->cadence[0] != 0) {
    info->cadence[0] = 0;
    tones |= DialTone;
  }

  if (info->cadence[1] != 0) {
    info->cadence[1] = 0;
    tones |= RingTone;
  }

  if (info->cadence[2] != 0) {
    info->cadence[2] = 0;
    tones |= BusyTone;
  }

  if (info->cadence[3] != 0) {
    info->cadence[3] = 0;
    tones |= CNGTone;
  }

  return tones;
}


BOOL OpalIxJDevice::SetToneFilterParameters(unsigned /*line*/,
                                            CallProgressTones tone,
                                            unsigned   lowFrequency,
                                            unsigned   highFrequency,
                                            PINDEX     numCadences,
                                            const unsigned * onTimes,
                                            const unsigned * offTimes)
{
  int toneIndex;
  switch (tone) {
    case DialTone :
      toneIndex = 0;
      break;
    case RingTone :
      toneIndex = 1;
      break;
    case BusyTone :
      toneIndex = 2;
      break;
    case CNGTone :
      toneIndex = 3;
      break;
    default :
      PTRACE(1, "xJack\tCannot set filter for tone: " << tone);
      return FALSE;
  }

#ifdef IXJCTL_SET_FILTER
  int filterCode = -1;
  int minMatch = 0, maxMatch = 0;

  if (lowFrequency == highFrequency) {
    static struct {
      IXJ_FILTER_FREQ code;
      unsigned        hertz;
    } const FreqToIXJFreq[] = {
      { f350,   350 }, { f300,   300 }, { f330,   330 }, { f340,   340 },
      { f392,   392 }, { f400,   400 }, { f420,   420 }, { f425,   425 },
      { f435,   435 }, { f440,   440 }, { f445,   445 }, { f450,   450 },
      { f452,   452 }, { f475,   475 }, { f480,   480 }, { f494,   494 },
      { f500,   500 }, { f520,   520 }, { f523,   523 }, { f525,   525 },
      { f587,   587 }, { f590,   590 }, { f600,   600 }, { f620,   620 },
      { f660,   660 }, { f700,   700 }, { f740,   740 }, { f750,   750 },
      { f770,   770 }, { f800,   800 }, { f816,   816 }, { f850,   850 },
      { f900,   900 }, { f942,   942 }, { f950,   950 }, { f975,   975 },
      { f1000, 1000 }, { f1020, 1020 }, { f1050, 1050 }, { f1100, 1100 },
      { f1140, 1140 }, { f1200, 1200 }, { f1209, 1209 }, { f1330, 1330 },
      { f1336, 1336 }, { f1380, 1380 }, { f1400, 1400 }, { f1477, 1477 },
      { f1600, 1600 }, { f1800, 1800 }, { f1860, 1860 }
    };

    PINDEX i;
    for (i = 0; i < PARRAYSIZE(FreqToIXJFreq); i++) {
      if (lowFrequency == FreqToIXJFreq[i].hertz) { 
        filterCode = FreqToIXJFreq[i].code;
        minMatch = maxMatch = FreqToIXJFreq[i].hertz;
        break;
      }
    }

  } else {
    static struct {
      IXJ_FILTER_FREQ code;
      unsigned        minHertz;
      unsigned        maxHertz;
    } const FreqToIXJFreq2[] = {
      { f20_50,       20,   50 }, { f133_200,    133,  200 }, { f300_640,    300,  640 },
      { f300_500,    300,  500 }, { f300_425,    300,  425 }, { f350_400,    350,  400 },
      { f350_440,    350,  440 }, { f350_450,    350,  450 }, { f380_420,    380,  420 },
      { f400_425,    400,  425 }, { f400_440,    400,  440 }, { f400_450,    400,  450 },
      { f425_450,    425,  450 }, { f425_475,    425,  475 }, { f440_450,    440,  450 },
      { f440_480,    440,  480 }, { f480_620,    480,  620 }, { f540_660,    540,  660 }, 
      { f750_1450,   750, 1450 }, { f857_1645,   857, 1645 }, { f900_1300,   900, 1300 },
      { f935_1215,   935, 1215 }, { f941_1477,   941, 1477 }, { f950_1400,   950, 1400 },
      { f1100_1750, 1100, 1750 }, { f1633_1638, 1633, 1638 }
    };

    PINDEX i;

    // look for exact match
    for (i = 0; i < PARRAYSIZE(FreqToIXJFreq2); i++) {
      if ((lowFrequency == FreqToIXJFreq2[i].minHertz) && (highFrequency == FreqToIXJFreq2[i].maxHertz)) { 
        filterCode = FreqToIXJFreq2[i].code;
        minMatch = FreqToIXJFreq2[i].minHertz;
        maxMatch = FreqToIXJFreq2[i].maxHertz;
        break;
      }
    }

    // look for an approximate match
    if (filterCode == -1) {
      for (i = 0; i < PARRAY

⌨️ 快捷键说明

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