void SpanDSP::T38Terminal::QueuePacket(const T38Packet & pkt) { #if SPANDSP_VER3 ::t38_core_rx_ifp_packet(&t38TerminalState.t38, pkt.sequence, &pkt[0], pkt.size()); #else ::t38_core_rx_ifp_packet(&t38TerminalState.t38, &pkt[0], pkt.size(), pkt.sequence); #endif }
bool SpanDSP::T38Element::SendT38Packet(socket_t fd, const T38Packet & pkt, const sockaddr * address) { RTPHeader rtpHeader; rtpHeader.flags = 0x80; rtpHeader.payloadMarker = 0x00 | 96; rtpHeader.sequence = htons(pkt.sequence); rtpHeader.timestamp = htonl(txTimestamp); rtpHeader.ssrc = 0; txTimestamp += 160; struct iovec vectors[2]; vectors[0].iov_base = &rtpHeader; vectors[0].iov_len = sizeof(rtpHeader); vectors[1].iov_base = (void *)&pkt[0]; vectors[1].iov_len = pkt.size(); msghdr msg; memset(&msg, 0, sizeof(msg)); msg.msg_iov = vectors; msg.msg_iovlen = 2; msg.msg_name = (void *)address; msg.msg_namelen = sizeof(sockaddr); static int counter = 0; if (verbose && (++counter % 25 == 0)) { cout << progmode << " " << counter << "t38 writes" << endl; } if (__socket_sendmsg(fd, &msg, 0) <= 0) { cerr << progmode << ": sendmsg failed - " ; __socket_error(cerr) << endl; return true; } if (verbose && firstT38Write) { cout << progmode << " first write from t38 socket to port " << htons(((sockaddr_in *)address)->sin_port) << endl; firstT38Write = false; } return true; }
void SpanDSP::T38Terminal::QueuePacket(const T38Packet & pkt) { t38_core_rx_ifp_packet(t38_terminal_get_t38_core_state(t38TerminalState), &pkt[0], pkt.size(), pkt.sequence); }
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; }
void SpanDSP::T38Gateway::QueuePacket(const T38Packet & pkt) { t38_core_rx_ifp_packet(t38_gateway_get_t38_core_state(t38GatewayState), &pkt[0], pkt.size(), pkt.sequence); }