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; }
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; }
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; }