mirror of
https://gitlab.com/suyu-emu/suyu.git
synced 2024-03-15 23:15:44 +00:00
189 lines
5.5 KiB
C++
189 lines
5.5 KiB
C++
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
#pragma once
|
|
|
|
#include <memory>
|
|
#include <span>
|
|
#include <vector>
|
|
|
|
#include "common/common_types.h"
|
|
#include "common/socket_types.h"
|
|
#include "core/hle/service/service.h"
|
|
#include "core/hle/service/sockets/sockets.h"
|
|
#include "network/network.h"
|
|
|
|
namespace Core {
|
|
class System;
|
|
}
|
|
|
|
namespace Network {
|
|
class SocketBase;
|
|
class Socket;
|
|
} // namespace Network
|
|
|
|
namespace Service::Sockets {
|
|
|
|
class BSD final : public ServiceFramework<BSD> {
|
|
public:
|
|
explicit BSD(Core::System& system_, const char* name);
|
|
~BSD() override;
|
|
|
|
private:
|
|
/// Maximum number of file descriptors
|
|
static constexpr size_t MAX_FD = 128;
|
|
|
|
struct FileDescriptor {
|
|
std::unique_ptr<Network::SocketBase> socket;
|
|
s32 flags = 0;
|
|
bool is_connection_based = false;
|
|
};
|
|
|
|
struct PollWork {
|
|
void Execute(BSD* bsd);
|
|
void Response(HLERequestContext& ctx);
|
|
|
|
s32 nfds;
|
|
s32 timeout;
|
|
std::span<const u8> read_buffer;
|
|
std::vector<u8> write_buffer;
|
|
s32 ret{};
|
|
Errno bsd_errno{};
|
|
};
|
|
|
|
struct AcceptWork {
|
|
void Execute(BSD* bsd);
|
|
void Response(HLERequestContext& ctx);
|
|
|
|
s32 fd;
|
|
std::vector<u8> write_buffer;
|
|
s32 ret{};
|
|
Errno bsd_errno{};
|
|
};
|
|
|
|
struct ConnectWork {
|
|
void Execute(BSD* bsd);
|
|
void Response(HLERequestContext& ctx);
|
|
|
|
s32 fd;
|
|
std::span<const u8> addr;
|
|
Errno bsd_errno{};
|
|
};
|
|
|
|
struct RecvWork {
|
|
void Execute(BSD* bsd);
|
|
void Response(HLERequestContext& ctx);
|
|
|
|
s32 fd;
|
|
u32 flags;
|
|
std::vector<u8> message;
|
|
s32 ret{};
|
|
Errno bsd_errno{};
|
|
};
|
|
|
|
struct RecvFromWork {
|
|
void Execute(BSD* bsd);
|
|
void Response(HLERequestContext& ctx);
|
|
|
|
s32 fd;
|
|
u32 flags;
|
|
std::vector<u8> message;
|
|
std::vector<u8> addr;
|
|
s32 ret{};
|
|
Errno bsd_errno{};
|
|
};
|
|
|
|
struct SendWork {
|
|
void Execute(BSD* bsd);
|
|
void Response(HLERequestContext& ctx);
|
|
|
|
s32 fd;
|
|
u32 flags;
|
|
std::span<const u8> message;
|
|
s32 ret{};
|
|
Errno bsd_errno{};
|
|
};
|
|
|
|
struct SendToWork {
|
|
void Execute(BSD* bsd);
|
|
void Response(HLERequestContext& ctx);
|
|
|
|
s32 fd;
|
|
u32 flags;
|
|
std::span<const u8> message;
|
|
std::span<const u8> addr;
|
|
s32 ret{};
|
|
Errno bsd_errno{};
|
|
};
|
|
|
|
void RegisterClient(HLERequestContext& ctx);
|
|
void StartMonitoring(HLERequestContext& ctx);
|
|
void Socket(HLERequestContext& ctx);
|
|
void Select(HLERequestContext& ctx);
|
|
void Poll(HLERequestContext& ctx);
|
|
void Accept(HLERequestContext& ctx);
|
|
void Bind(HLERequestContext& ctx);
|
|
void Connect(HLERequestContext& ctx);
|
|
void GetPeerName(HLERequestContext& ctx);
|
|
void GetSockName(HLERequestContext& ctx);
|
|
void GetSockOpt(HLERequestContext& ctx);
|
|
void Listen(HLERequestContext& ctx);
|
|
void Fcntl(HLERequestContext& ctx);
|
|
void SetSockOpt(HLERequestContext& ctx);
|
|
void Shutdown(HLERequestContext& ctx);
|
|
void Recv(HLERequestContext& ctx);
|
|
void RecvFrom(HLERequestContext& ctx);
|
|
void Send(HLERequestContext& ctx);
|
|
void SendTo(HLERequestContext& ctx);
|
|
void Write(HLERequestContext& ctx);
|
|
void Read(HLERequestContext& ctx);
|
|
void Close(HLERequestContext& ctx);
|
|
void EventFd(HLERequestContext& ctx);
|
|
|
|
template <typename Work>
|
|
void ExecuteWork(HLERequestContext& ctx, Work work);
|
|
|
|
std::pair<s32, Errno> SocketImpl(Domain domain, Type type, Protocol protocol);
|
|
std::pair<s32, Errno> PollImpl(std::vector<u8>& write_buffer, std::span<const u8> read_buffer,
|
|
s32 nfds, s32 timeout);
|
|
std::pair<s32, Errno> AcceptImpl(s32 fd, std::vector<u8>& write_buffer);
|
|
Errno BindImpl(s32 fd, std::span<const u8> addr);
|
|
Errno ConnectImpl(s32 fd, std::span<const u8> addr);
|
|
Errno GetPeerNameImpl(s32 fd, std::vector<u8>& write_buffer);
|
|
Errno GetSockNameImpl(s32 fd, std::vector<u8>& write_buffer);
|
|
Errno ListenImpl(s32 fd, s32 backlog);
|
|
std::pair<s32, Errno> FcntlImpl(s32 fd, FcntlCmd cmd, s32 arg);
|
|
Errno SetSockOptImpl(s32 fd, u32 level, OptName optname, size_t optlen, const void* optval);
|
|
Errno ShutdownImpl(s32 fd, s32 how);
|
|
std::pair<s32, Errno> RecvImpl(s32 fd, u32 flags, std::vector<u8>& message);
|
|
std::pair<s32, Errno> RecvFromImpl(s32 fd, u32 flags, std::vector<u8>& message,
|
|
std::vector<u8>& addr);
|
|
std::pair<s32, Errno> SendImpl(s32 fd, u32 flags, std::span<const u8> message);
|
|
std::pair<s32, Errno> SendToImpl(s32 fd, u32 flags, std::span<const u8> message,
|
|
std::span<const u8> addr);
|
|
Errno CloseImpl(s32 fd);
|
|
|
|
s32 FindFreeFileDescriptorHandle() noexcept;
|
|
bool IsFileDescriptorValid(s32 fd) const noexcept;
|
|
|
|
void BuildErrnoResponse(HLERequestContext& ctx, Errno bsd_errno) const noexcept;
|
|
|
|
std::array<std::optional<FileDescriptor>, MAX_FD> file_descriptors;
|
|
|
|
Network::RoomNetwork& room_network;
|
|
|
|
/// Callback to parse and handle a received wifi packet.
|
|
void OnProxyPacketReceived(const Network::ProxyPacket& packet);
|
|
|
|
// Callback identifier for the OnProxyPacketReceived event.
|
|
Network::RoomMember::CallbackHandle<Network::ProxyPacket> proxy_packet_received;
|
|
};
|
|
|
|
class BSDCFG final : public ServiceFramework<BSDCFG> {
|
|
public:
|
|
explicit BSDCFG(Core::System& system_);
|
|
~BSDCFG() override;
|
|
};
|
|
|
|
} // namespace Service::Sockets
|