Пример #1
0
bool SpanDSP::FaxTerminal::Serve(socket_t fd, sockaddr_in & address, bool listen)
{
  int port;
  {
    sockaddr_in local;
    socklen_t len = sizeof(local);
    if (getsockname(fd, (sockaddr *)&local, &len) != 0) {
      cerr << progmode << ": cannot get local port number" << endl;
      return false;
    }
    port = ntohs(local.sin_port);
    if (verbose)
      cout << progmode << ": local fax port = " << port << endl;
  }

  // set socket into non-blocking mode
  int cmd = 1;
  if (__socket_ioctl(fd, FIONBIO, &cmd) != 0) {
     cerr << progmode << ": cannot set socket into non-blocking mode" << endl;
     return false;
  }

  AdaptiveDelay delay;

#if WRITE_PCM_FILES
  int outFile;
  int inFile;
  {
    char fn[1024];

    strcpy(fn, "fax_audio_out_");
    strcat(fn, progmode);
    strcat(fn, ".pcm");
    outFile = _open(fn, _O_BINARY | _O_CREAT | _O_TRUNC | _O_WRONLY, _S_IREAD | _S_IWRITE);
    if (outFile < 0) {
      cerr << progmode << ": cannot open " << fn << endl;
    }
    else
    {
      cerr << progmode << ": opened " << fn << endl;
    }

    strcpy(fn, "fax_audio_in_");
    strcat(fn, progmode);
    strcat(fn, ".pcm");
    inFile = _open(fn, _O_BINARY | _O_CREAT | _O_TRUNC | _O_WRONLY, _S_IREAD | _S_IWRITE);
    if (outFile < 0) {
      cerr << progmode << ": cannot open " << fn << endl;
    }
    else
    {
      cerr << progmode << ": opened " << fn << endl;
    }
  }
#endif

  while (!finished) {

    delay.Delay(20);

    // get audio data from terminal and send to socket
    {
      short data[SAMPLES_PER_CHUNK];
      int len = GetPCMData(data, sizeof(data)/2) * 2;
      if (!listen) {
#if WRITE_PCM_FILES      	
        if (outFile >= 0) {
          if (write(outFile, data, len) < len) {
            cerr << progmode << ": cannot write output PCM data to file" << endl;
            outFile = -1;
          }
        }
#endif        

        if (__socket_sendto(fd, data, len, 0, (sockaddr *)&address, sizeof(address)) != len) {
          if ( __socket_getlasterror() == ENOENT)
            cerr << progmode << ": audio write socket not ready" << endl;
          else {
            cerr << progmode << ": write to audio socket failed\n";  __socket_error(cerr) << endl;
            break;
          }
        } else if (verbose && firstAudioWrite) {
          cout << progmode << ": first send from audio socket" << endl;
          firstAudioWrite = false;
        }
      }
    }

    // get audio data from the fax socket and send to the terminal
    int len;
    short data[750];
    if (!ReadAudioPacket(fd, data, len, address, listen, verbose))
      break;
    if (len > 0) {
#if WRITE_PCM_FILES    	
      if (inFile >= 0) {
        if (write(inFile, data, len) < len) {
          cerr << progmode << ": cannot write input PCM data to file" << endl;
          outFile = -1;
        }
      }
#endif

      if (!PutPCMData(data, len/2)) {
        cerr << progmode << ": write to terminal failed" << endl;
        break;
      }
    }
  }

  cout << progmode << ": finished." << endl;

  // keep sending silence until the UDP socket closed
  if (SendFiller()) {
    short data[SAMPLES_PER_CHUNK];
    memset(&data, 0, sizeof(data));
    int i = 100;
    while (i-- > 0) {
      if (__socket_sendto(fd, data, sizeof(data), 0, (sockaddr *)&address, sizeof(address)) <= 0) 
        break;
      delay.Delay(20);
    }
  }

  return true;
}
Пример #2
0
bool SpanDSP::T38Terminal::Serve(socket_t fd, sockaddr_in & address, bool listen)
{
  {
    sockaddr_in local;
    socklen_t len = sizeof(local);
    if (getsockname(fd, (sockaddr *)&local, &len) != 0) {
      cerr << progmode << ": cannot get local port number" << endl;
      return false;
    }
  }

  if (!listen) {
    txFd = fd;
    memcpy(&txAddr, &address, sizeof(txAddr));
  }

  // set socket into non-blocking mode
  int cmd = 1;
  if (__socket_ioctl(fd, FIONBIO, &cmd) != 0) {
    cerr << progmode << ": cannot set socket into non-blocking mode" << endl;
    return false;
  }

  int done = 0;

#ifdef USE_PACING
  int started = 0;
#else
  AdaptiveDelay delay;
#endif

  while (!finished) {

    done = t38_terminal_send_timeout(t38TerminalState, SAMPLES_PER_CHUNK);

    SpanDSP::T38Terminal::T38Packet pkt;

#ifndef USE_PACING
    delay.Delay(20);

    if (!ReceiveT38Packet(fd, pkt, address, listen)) {
      finished = true;
      break;
    }

    if (pkt.size() != 0) 
      QueuePacket(pkt);

    if (finished || done)
      break;
#else
    int ret;
    {
      fd_set rfds;
      FD_ZERO(&rfds);
      FD_SET(fd, &rfds);
      timeval t;

      if (!started) {
        t.tv_sec  = 60;
        t.tv_usec = 0;
      }
      else
      {
        t.tv_sec  = 0;
        t.tv_usec = 30000;
      }

      ret = select(fd+1, &rfds, NULL, NULL, &t);
    }

    // read incoming packets
    if (!started) {
      if (ret <= 0 || !ReceiveT38Packet(fd, pkt, address, listen))
        finished = true;
      started = 1;
    }
    else if (ret != 0) {
      if (ret < 0 || !ReceiveT38Packet(fd, pkt, address, listen)) {
        finished = true;
        break;
      } else if (pkt.size() != 0) 
        QueuePacket(pkt);
    }
#endif
  }

  cout << progmode << ": finished." << endl;

  return true;
}
Пример #3
0
bool SpanDSP::T38Gateway::Serve(socket_t fax, sockaddr_in & faxAddress, socket_t t38, sockaddr_in & t38Address, bool listenFlag)
{
  bool faxListen, t38Listen;
  faxListen = t38Listen = listenFlag;

  {
    sockaddr_in local;
    socklen_t len = sizeof(local);
    if (getsockname(fax, (sockaddr *)&local, &len) != 0) {
      cerr << progmode << ": cannot get local fax port number" << endl;
      return false;
    }
    if (verbose)
      cout << progmode << ": local fax port = " << ntohs(local.sin_port) << endl;
  }

  {
    sockaddr_in local;
    socklen_t len = sizeof(local);
    if (getsockname(t38, (sockaddr *)&local, &len) != 0) {
      cerr << progmode << ": cannot get local t38 port number" << endl;
      return false;
    }
    if (verbose)
      cout << progmode << ": local t38 port = " << ntohs(local.sin_port) << endl;
  }

  // set sockets into non-blocking mode
  int cmd = 1;
  if (__socket_ioctl(fax, FIONBIO, &cmd) != 0) {
     cerr << progmode << ": cannot set fax socket into non-blocking mode" << endl;
     return false;
  }

  // set socket into non-blocking mode
  cmd = 1;
  if (__socket_ioctl(t38, FIONBIO, &cmd) != 0) {
     cerr << progmode << ": cannot set t38 socket into non-blocking mode" << endl;
     return false;
  }

  if (!listenFlag) {
    txFd = t38;
    memcpy(&txAddr, &t38Address, sizeof(txAddr));
  }

#if WRITE_PCM_FILES
  int outFile;
  int inFile;
  {
    char fn[1024];

    strcpy(fn, "gw_audio_out_");
    strcat(fn, progmode);
    strcat(fn, ".pcm");
    outFile = _open(fn, _O_BINARY | _O_CREAT | _O_TRUNC | _O_WRONLY, _S_IREAD | _S_IWRITE);
    if (outFile < 0) {
      cerr << progmode << ": cannot open " << fn << endl;
    }
    else
    {
      cerr << progmode << ": opened " << fn << endl;
    }

    strcpy(fn, "gw_audio_in_");
    strcat(fn, progmode);
    strcat(fn, ".pcm");
    inFile = _open(fn, _O_BINARY | _O_CREAT | _O_TRUNC | _O_WRONLY, _S_IREAD | _S_IWRITE);
    if (outFile < 0) {
      cerr << progmode << ": cannot open " << fn << endl;
    }
    else
    {
      cerr << progmode << ": opened " << fn << endl;
    }
  }
#endif

  AdaptiveDelay delay;

  while (!finished) {

    delay.Delay(20);

    // get audio data from the fax socket and give to the gateway
    {
      int len;
      short data[750];
      if (ReadAudioPacket(fax, data, len, faxAddress, faxListen, verbose)) {
#if WRITE_PCM_FILES
        if (inFile >= 0) {
          if (write(inFile, data, len) < len) {
            cerr << progmode << ": cannot write input PCM data to file" << endl;
            outFile = -1;
          }
        }
#endif        
        if (len > 0) {
          if (!PutPCMData(data, len/2)) {
            cerr << progmode << ": write to terminal failed" << endl;
            break;
          }
        }
      }
    }

    // get audio data from the gateway and send to the fax socket
    {
      short data[SAMPLES_PER_CHUNK];
      unsigned len = GetPCMData(data, sizeof(data)/2) * 2;
#if _WIN32
      if (!faxListen && (__socket_sendto(fax, data, len, 0, (sockaddr *)&faxAddress, sizeof(faxAddress)) <= 0)) {
#else
      if (__socket_write(fax, data, len) <= 0) {
#endif
        if ( __socket_getlasterror() == ENOENT)
          cerr << progmode << ": fax write socket not ready" << endl;
        else {
          cerr << progmode << ": write to fax socket failed\n";  __socket_error(cerr) << endl;
          break;
        }
      }
      if (verbose && firstAudioWrite) {
        cout << progmode << ": first send from audio socket " << len << endl;
        firstAudioWrite = false;
      }
#if WRITE_PCM_FILES
      if (outFile >= 0) {
        if (write(outFile, data, len) < len) {
          cerr << progmode << ": cannot write output PCM data to file" << endl;
          outFile = -1;
        }
      }
#endif      
    }

    if (finished) {
      if (verbose)
        cout << progmode << ": finished." << endl;
      break;
    }

    // read any T38 packets received and send to the gateway
    T38Packet pkt;
    for (;;) {
      if (!ReceiveT38Packet(t38, pkt, t38Address, t38Listen)) {
        cerr << progmode << ": receive failed" << endl;
        finished = true;
        break;
      }
      if (pkt.size() == 0) 
        break;
      QueuePacket(pkt);
    }
  }

  cout << progmode << ": finished." << endl;

  // keep sending silence until the UDP socket closed
  {
    short data[SAMPLES_PER_CHUNK];
    memset(&data, 0, sizeof(data));
    int i = 100;
    while (i-- > 0) {
      if (__socket_sendto(fax, data, sizeof(data), 0, (sockaddr *)&faxAddress, sizeof(faxAddress)) <= 0) 
        break;
      delay.Delay(20);
    }
  }

  return true;
}