diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a45439481..0b0e5f558 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -5,6 +5,7 @@ add_subdirectory(common) add_subdirectory(core) add_subdirectory(video_core) add_subdirectory(audio_core) +add_subdirectory(net_core) add_subdirectory(input_common) add_subdirectory(tests) if (ENABLE_SDL2) diff --git a/src/citra_qt/CMakeLists.txt b/src/citra_qt/CMakeLists.txt index 3e6106f0a..27e0dcfad 100644 --- a/src/citra_qt/CMakeLists.txt +++ b/src/citra_qt/CMakeLists.txt @@ -97,7 +97,7 @@ if (APPLE) else() add_executable(citra-qt ${SRCS} ${HEADERS} ${UI_HDRS}) endif() -target_link_libraries(citra-qt core video_core audio_core common input_common) +target_link_libraries(citra-qt core video_core audio_core net_core common input_common) target_link_libraries(citra-qt ${OPENGL_gl_LIBRARY} ${CITRA_QT_LIBS}) target_link_libraries(citra-qt ${PLATFORM_LIBRARIES} Threads::Threads) diff --git a/src/citra_qt/bootmanager.cpp b/src/citra_qt/bootmanager.cpp index bae576d6a..91e56eda2 100644 --- a/src/citra_qt/bootmanager.cpp +++ b/src/citra_qt/bootmanager.cpp @@ -16,6 +16,7 @@ #include "core/settings.h" #include "input_common/keyboard.h" #include "input_common/main.h" +#include "net_core/local.h" #include "video_core/debug_utils/debug_utils.h" #include "video_core/video_core.h" @@ -108,9 +109,11 @@ GRenderWindow::GRenderWindow(QWidget* parent, EmuThread* emu_thread) setWindowTitle(QString::fromStdString(window_title)); InputCommon::Init(); + NetCore::Local::Init(); } GRenderWindow::~GRenderWindow() { + NetCore::Local::Shutdown(); InputCommon::Shutdown(); } diff --git a/src/common/logging/backend.cpp b/src/common/logging/backend.cpp index 42f6a9918..553ad4bb1 100644 --- a/src/common/logging/backend.cpp +++ b/src/common/logging/backend.cpp @@ -72,6 +72,7 @@ namespace Log { SUB(Audio, DSP) \ SUB(Audio, Sink) \ CLS(Input) \ + CLS(Network) \ CLS(Loader) // GetClassName is a macro defined by Windows.h, grrr... diff --git a/src/common/logging/log.h b/src/common/logging/log.h index 1b905f66c..8f13b80b3 100644 --- a/src/common/logging/log.h +++ b/src/common/logging/log.h @@ -90,6 +90,7 @@ enum class Class : ClassType { Audio_Sink, ///< Emulator audio output backend Loader, ///< ROM loader Input, ///< Input emulation + Network, ///< Network emulation Count ///< Total number of logging classes }; diff --git a/src/net_core/CMakeLists.txt b/src/net_core/CMakeLists.txt new file mode 100644 index 000000000..4deed0731 --- /dev/null +++ b/src/net_core/CMakeLists.txt @@ -0,0 +1,14 @@ +set(SRCS + net_core.cpp + local.cpp + ) + +set(HEADERS + net_core.h + local.h + ) + + +create_directory_groups(${SRCS} ${HEADERS}) + +add_library(net_core STATIC ${SRCS} ${HEADERS}) diff --git a/src/net_core/local.cpp b/src/net_core/local.cpp new file mode 100644 index 000000000..d49808627 --- /dev/null +++ b/src/net_core/local.cpp @@ -0,0 +1,90 @@ +// Copyright 2017 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include "common/logging/log.h" +#include "net_core/local.h" + +namespace NetCore { +namespace Local { + +bool Init() { + LOG_DEBUG(Network, "(STUBBED) called"); + return true; +} + +void Shutdown() { + LOG_DEBUG(Network, "(STUBBED) called"); +} + +MemberState GetMemberState() { + LOG_DEBUG(Network, "(STUBBED) called"); + return MemberState::Idle; +} + +RoomState GetRoomState() { + LOG_DEBUG(Network, "(STUBBED) called"); + return RoomState::Closed; +} + +bool IsConnected() { + LOG_DEBUG(Network, "(STUBBED) called"); + return false; +} + +MemberList GetMemberInformation() { + LOG_DEBUG(Network, "(STUBBED) called"); + return {}; +} + +RoomInformation GetRoomInformation() { + LOG_DEBUG(Network, "(STUBBED) called"); + return {}; +} + +std::deque PopChatEntries() { + LOG_DEBUG(Network, "(STUBBED) called"); + return {}; +} + +std::deque PopWifiPackets(WifiPacket::PacketType type, const MacAddress& sender) { + LOG_DEBUG(Network, "(STUBBED) called"); + return {}; +} + +void SendChatMessage(const std::string& message) { + LOG_DEBUG(Network, "(STUBBED) called"); +} + +void SendWifiPacket(const WifiPacket& packet) { + LOG_DEBUG(Network, "(STUBBED) called"); +} + +std::string GetStatistics() { + LOG_DEBUG(Network, "(STUBBED) called"); + return ""; +} + +int GetPing() { + LOG_DEBUG(Network, "(STUBBED) called"); + return 0; +} + +void Join(const std::string& nickname, const std::string& server, const uint16_t serverPort, const uint16_t clientPort) { + LOG_DEBUG(Network, "(STUBBED) called"); +} + +void Leave() { + LOG_DEBUG(Network, "(STUBBED) called"); +} + +void Create(const std::string& name, const std::string& server, uint16_t server_port) { + LOG_DEBUG(Network, "(STUBBED) called"); +} + +void Destroy() { + LOG_DEBUG(Network, "(STUBBED) called"); +} + +} // namespace +} // namespace diff --git a/src/net_core/local.h b/src/net_core/local.h new file mode 100644 index 000000000..75e88de54 --- /dev/null +++ b/src/net_core/local.h @@ -0,0 +1,167 @@ +// Copyright 2017 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include +#include +#include +#include + +namespace NetCore { +namespace Local { + +const uint16_t DefaultPort = 1234; + +using MacAddress = std::array; +const MacAddress NoPreferredMac = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; +const MacAddress BroadcastMac = NoPreferredMac; + +struct MemberInformation { + std::string nickname; // Nickname of the member. + std::string game_name; // Name of the game they're currently playing, or empty if they're not playing anything. + MacAddress mac_address; // MAC address associated with this member. +}; +using MemberList = std::vector; + +struct RoomInformation { + std::string name; // Name of the room + uint32_t member_slots; // Maximum number of members in this room +}; + +/// Information about the received WiFi packets. +/// Acts as our own 802.11 header. +struct WifiPacket { + enum class PacketType { + Beacon, + ConnectionRequest, + ConnectionResponse, + Data + }; + PacketType type; ///< The type of 802.11 frame, Beacon / Data. + std::vector data; ///< Raw 802.11 frame data, starting at the management frame header for management frames. + MacAddress transmitter_address; ///< Mac address of the transmitter. + MacAddress destination_address; ///< Mac address of the receiver. + uint8_t data_channel; ///< The Data Channel used by NWM_UDS::SendTo and Bind. Works like a port. + /// Only used by Packets of Type Data +}; + +/// Represents a chat message. +struct ChatEntry { + std::string nickname; ///< Nickname of the client who sent this message. + std::string message; ///< Body of the message. +}; + +enum class MemberState { + Idle, // Default state + Error, // Some error [permissions to network device missing or something] + Joining, // The client is attempting to join a room. + Joined, // The client is connected to the room and is ready to send/receive packets. + Leaving, // The client is about to close the connection + + // Reasons for connection loss + LostConnection, + + // Reasons why connection was rejected + RoomFull, // The room is full and is not accepting any more connections. + RoomDestroyed, // Unknown reason, server not reachable or not responding for w/e reason + NameCollision, // Somebody is already using this name + MacCollision, // Somebody is already using that mac-address + WrongVersion, // The version does not match. +}; + + +enum class RoomState { + Open, // The room is open and ready to accept connections. + Closed, // The room is not opened and can not accept connections. +}; + +/// Initialise NetCore::Local +bool Init(); + +/// Shutdown NetCore::Local +void Shutdown(); + +/** +* Returns the status of our connection to the room. +*/ +MemberState GetMemberState(); + +/** +* Gets the current state of the room. +*/ +RoomState GetRoomState(); + +/** +* Returns whether we're connected to a room or not. +*/ +bool IsConnected(); + +/** +* Returns information about the members in the room we're currently connected to. +*/ +MemberList GetMemberInformation(); + +/** +* Returns information about the room we're currently connected to. +*/ +RoomInformation GetRoomInformation(); + +/** +* Returns a list of received chat messages since the last call. +*/ +std::deque PopChatEntries(); + +/** +* Returns a list of received 802.11 frames from the specified sender +* matching the type since the last call. +*/ +std::deque PopWifiPackets(WifiPacket::PacketType type, const MacAddress& sender = NoPreferredMac); + +/** +* Sends a chat message to the room. +* @param message The contents of the message. +*/ +void SendChatMessage(const std::string& message); + +/** +* Sends a WiFi packet to the room. +* @param packet The WiFi packet to send. +*/ +void SendWifiPacket(const WifiPacket& packet); + +/** +* Returns a string with informations about the connection +*/ +std::string GetStatistics(); + +/** +* Returns the latest ping to the room +*/ +int GetPing(); + +/** +* Attempts to join a room at the specified address and port, using the specified nickname. +* This may fail if the username is already taken. +*/ +void Join(const std::string& nickname, const std::string& server = "127.0.0.1", + const uint16_t serverPort = DefaultPort, const uint16_t clientPort = 0); + +/** +* Leaves the current room. +*/ +void Leave(); + +/** +* Creates a room to join to. Returns true on success. Will bind to default address if server is empty string. +*/ +void Create(const std::string& name, const std::string& server = "", uint16_t server_port = DefaultPort); + +/** +* Destroys the room +*/ +void Destroy(); + +} // namespace +} // namespace diff --git a/src/net_core/net_core.cpp b/src/net_core/net_core.cpp new file mode 100644 index 000000000..a826361d2 --- /dev/null +++ b/src/net_core/net_core.cpp @@ -0,0 +1,18 @@ +// Copyright 2017 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include "net_core/local.h" +#include "net_core/net_core.h" + +namespace NetCore { + +bool Init() { + return NetCore::Local::Init(); +} + +void Shutdown() { + NetCore::Local::Shutdown(); +} + +} // namespace diff --git a/src/net_core/net_core.h b/src/net_core/net_core.h new file mode 100644 index 000000000..7286de4e3 --- /dev/null +++ b/src/net_core/net_core.h @@ -0,0 +1,15 @@ +// Copyright 2017 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +namespace NetCore { + +/// Initialise NetCore +bool Init(); + +/// Shutdown NetCore +void Shutdown(); + +} // namespace diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index d1144ba77..3ad172769 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -13,7 +13,7 @@ create_directory_groups(${SRCS} ${HEADERS}) include_directories(../../externals/catch/single_include/) add_executable(tests ${SRCS} ${HEADERS}) -target_link_libraries(tests core video_core audio_core common) +target_link_libraries(tests core video_core audio_core net_core common) target_link_libraries(tests ${PLATFORM_LIBRARIES} Threads::Threads) add_test(NAME tests COMMAND $)