BBA/BuiltIn: Move functions to anonymous namespace
This commit is contained in:
parent
b950d038b9
commit
be2ede6109
|
@ -12,12 +12,123 @@
|
||||||
|
|
||||||
namespace ExpansionInterface
|
namespace ExpansionInterface
|
||||||
{
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
u64 GetTickCountStd()
|
u64 GetTickCountStd()
|
||||||
{
|
{
|
||||||
using namespace std::chrono;
|
using namespace std::chrono;
|
||||||
return duration_cast<milliseconds>(steady_clock::now().time_since_epoch()).count();
|
return duration_cast<milliseconds>(steady_clock::now().time_since_epoch()).count();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<u8> BuildFINFrame(StackRef* ref)
|
||||||
|
{
|
||||||
|
const Common::TCPPacket result(ref->bba_mac, ref->my_mac, ref->from, ref->to, ref->seq_num,
|
||||||
|
ref->ack_num, TCP_FLAG_FIN | TCP_FLAG_ACK | TCP_FLAG_RST);
|
||||||
|
|
||||||
|
for (auto& tcp_buf : ref->tcp_buffers)
|
||||||
|
tcp_buf.used = false;
|
||||||
|
return result.Build();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<u8> BuildAckFrame(StackRef* ref)
|
||||||
|
{
|
||||||
|
const Common::TCPPacket result(ref->bba_mac, ref->my_mac, ref->from, ref->to, ref->seq_num,
|
||||||
|
ref->ack_num, TCP_FLAG_ACK);
|
||||||
|
return result.Build();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Change the IP identification and recompute the checksum
|
||||||
|
void SetIPIdentification(u8* ptr, std::size_t size, u16 value)
|
||||||
|
{
|
||||||
|
if (size < Common::EthernetHeader::SIZE + Common::IPv4Header::SIZE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
u8* const ip_ptr = ptr + Common::EthernetHeader::SIZE;
|
||||||
|
const u8 ip_header_size = (*ip_ptr & 0xf) * 4;
|
||||||
|
if (size < Common::EthernetHeader::SIZE + ip_header_size)
|
||||||
|
return;
|
||||||
|
|
||||||
|
u8* const ip_id_ptr = ip_ptr + offsetof(Common::IPv4Header, identification);
|
||||||
|
Common::BitCastPtr<u16>(ip_id_ptr) = htons(value);
|
||||||
|
|
||||||
|
u8* const ip_checksum_ptr = ip_ptr + offsetof(Common::IPv4Header, header_checksum);
|
||||||
|
auto checksum_bitcast_ptr = Common::BitCastPtr<u16>(ip_checksum_ptr);
|
||||||
|
checksum_bitcast_ptr = u16(0);
|
||||||
|
checksum_bitcast_ptr = htons(Common::ComputeNetworkChecksum(ip_ptr, ip_header_size));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<std::vector<u8>> TryGetDataFromSocket(StackRef* ref)
|
||||||
|
{
|
||||||
|
size_t datasize = 0; // Set by socket.receive using a non-const reference
|
||||||
|
unsigned short remote_port;
|
||||||
|
|
||||||
|
switch (ref->type)
|
||||||
|
{
|
||||||
|
case IPPROTO_UDP:
|
||||||
|
{
|
||||||
|
std::array<u8, MAX_UDP_LENGTH> buffer;
|
||||||
|
ref->udp_socket.receive(buffer.data(), MAX_UDP_LENGTH, datasize, ref->target, remote_port);
|
||||||
|
if (datasize > 0)
|
||||||
|
{
|
||||||
|
ref->from.sin_port = htons(remote_port);
|
||||||
|
ref->from.sin_addr.s_addr = htonl(ref->target.toInteger());
|
||||||
|
const std::vector<u8> udp_data(buffer.begin(), buffer.begin() + datasize);
|
||||||
|
const Common::UDPPacket packet(ref->bba_mac, ref->my_mac, ref->from, ref->to, udp_data);
|
||||||
|
return packet.Build();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case IPPROTO_TCP:
|
||||||
|
sf::Socket::Status st = sf::Socket::Status::Done;
|
||||||
|
TcpBuffer* tcp_buffer = nullptr;
|
||||||
|
for (auto& tcp_buf : ref->tcp_buffers)
|
||||||
|
{
|
||||||
|
if (tcp_buf.used)
|
||||||
|
continue;
|
||||||
|
tcp_buffer = &tcp_buf;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set default size to 0 to avoid issue
|
||||||
|
datasize = 0;
|
||||||
|
const bool can_go = (GetTickCountStd() - ref->poke_time > 100 || ref->window_size > 2000);
|
||||||
|
std::array<u8, MAX_TCP_LENGTH> buffer;
|
||||||
|
if (tcp_buffer != nullptr && ref->ready && can_go)
|
||||||
|
st = ref->tcp_socket.receive(buffer.data(), MAX_TCP_LENGTH, datasize);
|
||||||
|
|
||||||
|
if (datasize > 0)
|
||||||
|
{
|
||||||
|
Common::TCPPacket packet(ref->bba_mac, ref->my_mac, ref->from, ref->to, ref->seq_num,
|
||||||
|
ref->ack_num, TCP_FLAG_ACK);
|
||||||
|
packet.data = std::vector<u8>(buffer.begin(), buffer.begin() + datasize);
|
||||||
|
|
||||||
|
// build buffer
|
||||||
|
tcp_buffer->seq_id = ref->seq_num;
|
||||||
|
tcp_buffer->tick = GetTickCountStd();
|
||||||
|
tcp_buffer->data = packet.Build();
|
||||||
|
tcp_buffer->seq_id = ref->seq_num;
|
||||||
|
tcp_buffer->used = true;
|
||||||
|
ref->seq_num += static_cast<u32>(datasize);
|
||||||
|
ref->poke_time = GetTickCountStd();
|
||||||
|
return tcp_buffer->data;
|
||||||
|
}
|
||||||
|
if (GetTickCountStd() - ref->delay > 3000)
|
||||||
|
{
|
||||||
|
if (st == sf::Socket::Disconnected || st == sf::Socket::Error)
|
||||||
|
{
|
||||||
|
ref->ip = 0;
|
||||||
|
ref->tcp_socket.disconnect();
|
||||||
|
return BuildFINFrame(ref);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
bool CEXIETHERNET::BuiltInBBAInterface::Activate()
|
bool CEXIETHERNET::BuiltInBBAInterface::Activate()
|
||||||
{
|
{
|
||||||
if (IsActivated())
|
if (IsActivated())
|
||||||
|
@ -177,23 +288,6 @@ StackRef* CEXIETHERNET::BuiltInBBAInterface::GetTCPSlot(u16 src_port, u16 dst_po
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<u8> BuildFINFrame(StackRef* ref)
|
|
||||||
{
|
|
||||||
const Common::TCPPacket result(ref->bba_mac, ref->my_mac, ref->from, ref->to, ref->seq_num,
|
|
||||||
ref->ack_num, TCP_FLAG_FIN | TCP_FLAG_ACK | TCP_FLAG_RST);
|
|
||||||
|
|
||||||
for (auto& tcp_buf : ref->tcp_buffers)
|
|
||||||
tcp_buf.used = false;
|
|
||||||
return result.Build();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<u8> BuildAckFrame(StackRef* ref)
|
|
||||||
{
|
|
||||||
const Common::TCPPacket result(ref->bba_mac, ref->my_mac, ref->from, ref->to, ref->seq_num,
|
|
||||||
ref->ack_num, TCP_FLAG_ACK);
|
|
||||||
return result.Build();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CEXIETHERNET::BuiltInBBAInterface::HandleTCPFrame(const Common::TCPPacket& packet)
|
void CEXIETHERNET::BuiltInBBAInterface::HandleTCPFrame(const Common::TCPPacket& packet)
|
||||||
{
|
{
|
||||||
const auto& [hwdata, ip_header, tcp_header, ip_options, tcp_options, data] = packet;
|
const auto& [hwdata, ip_header, tcp_header, ip_options, tcp_options, data] = packet;
|
||||||
|
@ -482,97 +576,6 @@ bool CEXIETHERNET::BuiltInBBAInterface::SendFrame(const u8* frame, u32 size)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<std::vector<u8>> TryGetDataFromSocket(StackRef* ref)
|
|
||||||
{
|
|
||||||
size_t datasize = 0; // Set by socket.receive using a non-const reference
|
|
||||||
unsigned short remote_port;
|
|
||||||
|
|
||||||
switch (ref->type)
|
|
||||||
{
|
|
||||||
case IPPROTO_UDP:
|
|
||||||
{
|
|
||||||
std::array<u8, MAX_UDP_LENGTH> buffer;
|
|
||||||
ref->udp_socket.receive(buffer.data(), MAX_UDP_LENGTH, datasize, ref->target, remote_port);
|
|
||||||
if (datasize > 0)
|
|
||||||
{
|
|
||||||
ref->from.sin_port = htons(remote_port);
|
|
||||||
ref->from.sin_addr.s_addr = htonl(ref->target.toInteger());
|
|
||||||
const std::vector<u8> udp_data(buffer.begin(), buffer.begin() + datasize);
|
|
||||||
const Common::UDPPacket packet(ref->bba_mac, ref->my_mac, ref->from, ref->to, udp_data);
|
|
||||||
return packet.Build();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case IPPROTO_TCP:
|
|
||||||
sf::Socket::Status st = sf::Socket::Status::Done;
|
|
||||||
TcpBuffer* tcp_buffer = nullptr;
|
|
||||||
for (auto& tcp_buf : ref->tcp_buffers)
|
|
||||||
{
|
|
||||||
if (tcp_buf.used)
|
|
||||||
continue;
|
|
||||||
tcp_buffer = &tcp_buf;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// set default size to 0 to avoid issue
|
|
||||||
datasize = 0;
|
|
||||||
const bool can_go = (GetTickCountStd() - ref->poke_time > 100 || ref->window_size > 2000);
|
|
||||||
std::array<u8, MAX_TCP_LENGTH> buffer;
|
|
||||||
if (tcp_buffer != nullptr && ref->ready && can_go)
|
|
||||||
st = ref->tcp_socket.receive(buffer.data(), MAX_TCP_LENGTH, datasize);
|
|
||||||
|
|
||||||
if (datasize > 0)
|
|
||||||
{
|
|
||||||
Common::TCPPacket packet(ref->bba_mac, ref->my_mac, ref->from, ref->to, ref->seq_num,
|
|
||||||
ref->ack_num, TCP_FLAG_ACK);
|
|
||||||
packet.data = std::vector<u8>(buffer.begin(), buffer.begin() + datasize);
|
|
||||||
|
|
||||||
// build buffer
|
|
||||||
tcp_buffer->seq_id = ref->seq_num;
|
|
||||||
tcp_buffer->tick = GetTickCountStd();
|
|
||||||
tcp_buffer->data = packet.Build();
|
|
||||||
tcp_buffer->seq_id = ref->seq_num;
|
|
||||||
tcp_buffer->used = true;
|
|
||||||
ref->seq_num += static_cast<u32>(datasize);
|
|
||||||
ref->poke_time = GetTickCountStd();
|
|
||||||
return tcp_buffer->data;
|
|
||||||
}
|
|
||||||
if (GetTickCountStd() - ref->delay > 3000)
|
|
||||||
{
|
|
||||||
if (st == sf::Socket::Disconnected || st == sf::Socket::Error)
|
|
||||||
{
|
|
||||||
ref->ip = 0;
|
|
||||||
ref->tcp_socket.disconnect();
|
|
||||||
return BuildFINFrame(ref);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return std::nullopt;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Change the IP identification and recompute the checksum
|
|
||||||
static void SetIPIdentification(u8* ptr, std::size_t size, u16 value)
|
|
||||||
{
|
|
||||||
if (size < Common::EthernetHeader::SIZE + Common::IPv4Header::SIZE)
|
|
||||||
return;
|
|
||||||
|
|
||||||
u8* const ip_ptr = ptr + Common::EthernetHeader::SIZE;
|
|
||||||
const u8 ip_header_size = (*ip_ptr & 0xf) * 4;
|
|
||||||
if (size < Common::EthernetHeader::SIZE + ip_header_size)
|
|
||||||
return;
|
|
||||||
|
|
||||||
u8* const ip_id_ptr = ip_ptr + offsetof(Common::IPv4Header, identification);
|
|
||||||
Common::BitCastPtr<u16>(ip_id_ptr) = htons(value);
|
|
||||||
|
|
||||||
u8* const ip_checksum_ptr = ip_ptr + offsetof(Common::IPv4Header, header_checksum);
|
|
||||||
auto checksum_bitcast_ptr = Common::BitCastPtr<u16>(ip_checksum_ptr);
|
|
||||||
checksum_bitcast_ptr = u16(0);
|
|
||||||
checksum_bitcast_ptr = htons(Common::ComputeNetworkChecksum(ip_ptr, ip_header_size));
|
|
||||||
}
|
|
||||||
|
|
||||||
void CEXIETHERNET::BuiltInBBAInterface::ReadThreadHandler(CEXIETHERNET::BuiltInBBAInterface* self)
|
void CEXIETHERNET::BuiltInBBAInterface::ReadThreadHandler(CEXIETHERNET::BuiltInBBAInterface* self)
|
||||||
{
|
{
|
||||||
while (!self->m_read_thread_shutdown.IsSet())
|
while (!self->m_read_thread_shutdown.IsSet())
|
||||||
|
|
Loading…
Reference in New Issue