diff options
Diffstat (limited to '')
| -rw-r--r-- | src/core/hle/service/nwm/nwm_uds.cpp | 65 |
1 files changed, 62 insertions, 3 deletions
diff --git a/src/core/hle/service/nwm/nwm_uds.cpp b/src/core/hle/service/nwm/nwm_uds.cpp index 6dbdff044..8fdf160ff 100644 --- a/src/core/hle/service/nwm/nwm_uds.cpp +++ b/src/core/hle/service/nwm/nwm_uds.cpp | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | #include <array> | 5 | #include <array> |
| 6 | #include <cstring> | 6 | #include <cstring> |
| 7 | #include <mutex> | ||
| 7 | #include <unordered_map> | 8 | #include <unordered_map> |
| 8 | #include <vector> | 9 | #include <vector> |
| 9 | #include "common/common_types.h" | 10 | #include "common/common_types.h" |
| @@ -15,8 +16,10 @@ | |||
| 15 | #include "core/hle/result.h" | 16 | #include "core/hle/result.h" |
| 16 | #include "core/hle/service/nwm/nwm_uds.h" | 17 | #include "core/hle/service/nwm/nwm_uds.h" |
| 17 | #include "core/hle/service/nwm/uds_beacon.h" | 18 | #include "core/hle/service/nwm/uds_beacon.h" |
| 19 | #include "core/hle/service/nwm/uds_connection.h" | ||
| 18 | #include "core/hle/service/nwm/uds_data.h" | 20 | #include "core/hle/service/nwm/uds_data.h" |
| 19 | #include "core/memory.h" | 21 | #include "core/memory.h" |
| 22 | #include "network/network.h" | ||
| 20 | 23 | ||
| 21 | namespace Service { | 24 | namespace Service { |
| 22 | namespace NWM { | 25 | namespace NWM { |
| @@ -51,6 +54,52 @@ static NetworkInfo network_info; | |||
| 51 | // Event that will generate and send the 802.11 beacon frames. | 54 | // Event that will generate and send the 802.11 beacon frames. |
| 52 | static int beacon_broadcast_event; | 55 | static int beacon_broadcast_event; |
| 53 | 56 | ||
| 57 | // Mutex to synchronize access to the list of received beacons between the emulation thread and the | ||
| 58 | // network thread. | ||
| 59 | static std::mutex beacon_mutex; | ||
| 60 | |||
| 61 | // Number of beacons to store before we start dropping the old ones. | ||
| 62 | // TODO(Subv): Find a more accurate value for this limit. | ||
| 63 | constexpr size_t MaxBeaconFrames = 15; | ||
| 64 | |||
| 65 | // List of the last <MaxBeaconFrames> beacons received from the network. | ||
| 66 | static std::deque<Network::WifiPacket> received_beacons; | ||
| 67 | |||
| 68 | /** | ||
| 69 | * Returns a list of received 802.11 beacon frames from the specified sender since the last call. | ||
| 70 | */ | ||
| 71 | std::deque<Network::WifiPacket> GetReceivedBeacons(const MacAddress& sender) { | ||
| 72 | std::lock_guard<std::mutex> lock(beacon_mutex); | ||
| 73 | // TODO(Subv): Filter by sender. | ||
| 74 | return std::move(received_beacons); | ||
| 75 | } | ||
| 76 | |||
| 77 | /// Sends a WifiPacket to the room we're currently connected to. | ||
| 78 | void SendPacket(Network::WifiPacket& packet) { | ||
| 79 | // TODO(Subv): Implement. | ||
| 80 | } | ||
| 81 | |||
| 82 | // Inserts the received beacon frame in the beacon queue and removes any older beacons if the size | ||
| 83 | // limit is exceeded. | ||
| 84 | void HandleBeaconFrame(const Network::WifiPacket& packet) { | ||
| 85 | std::lock_guard<std::mutex> lock(beacon_mutex); | ||
| 86 | |||
| 87 | received_beacons.emplace_back(packet); | ||
| 88 | |||
| 89 | // Discard old beacons if the buffer is full. | ||
| 90 | if (received_beacons.size() > MaxBeaconFrames) | ||
| 91 | received_beacons.pop_front(); | ||
| 92 | } | ||
| 93 | |||
| 94 | /// Callback to parse and handle a received wifi packet. | ||
| 95 | void OnWifiPacketReceived(const Network::WifiPacket& packet) { | ||
| 96 | switch (packet.type) { | ||
| 97 | case Network::WifiPacket::PacketType::Beacon: | ||
| 98 | HandleBeaconFrame(packet); | ||
| 99 | break; | ||
| 100 | } | ||
| 101 | } | ||
| 102 | |||
| 54 | /** | 103 | /** |
| 55 | * NWM_UDS::Shutdown service function | 104 | * NWM_UDS::Shutdown service function |
| 56 | * Inputs: | 105 | * Inputs: |
| @@ -111,8 +160,7 @@ static void RecvBeaconBroadcastData(Interface* self) { | |||
| 111 | u32 total_size = sizeof(BeaconDataReplyHeader); | 160 | u32 total_size = sizeof(BeaconDataReplyHeader); |
| 112 | 161 | ||
| 113 | // Retrieve all beacon frames that were received from the desired mac address. | 162 | // Retrieve all beacon frames that were received from the desired mac address. |
| 114 | std::deque<WifiPacket> beacons = | 163 | auto beacons = GetReceivedBeacons(mac_address); |
| 115 | GetReceivedPackets(WifiPacket::PacketType::Beacon, mac_address); | ||
| 116 | 164 | ||
| 117 | BeaconDataReplyHeader data_reply_header{}; | 165 | BeaconDataReplyHeader data_reply_header{}; |
| 118 | data_reply_header.total_entries = beacons.size(); | 166 | data_reply_header.total_entries = beacons.size(); |
| @@ -193,6 +241,9 @@ static void InitializeWithVersion(Interface* self) { | |||
| 193 | rb.Push(RESULT_SUCCESS); | 241 | rb.Push(RESULT_SUCCESS); |
| 194 | rb.PushCopyHandles(Kernel::g_handle_table.Create(connection_status_event).Unwrap()); | 242 | rb.PushCopyHandles(Kernel::g_handle_table.Create(connection_status_event).Unwrap()); |
| 195 | 243 | ||
| 244 | // TODO(Subv): Connect the OnWifiPacketReceived function to the wifi packet received callback of | ||
| 245 | // the room we're currently in. | ||
| 246 | |||
| 196 | LOG_DEBUG(Service_NWM, "called sharedmem_size=0x%08X, version=0x%08X, sharedmem_handle=0x%08X", | 247 | LOG_DEBUG(Service_NWM, "called sharedmem_size=0x%08X, version=0x%08X, sharedmem_handle=0x%08X", |
| 197 | sharedmem_size, version, sharedmem_handle); | 248 | sharedmem_size, version, sharedmem_handle); |
| 198 | } | 249 | } |
| @@ -610,9 +661,17 @@ static void BeaconBroadcastCallback(u64 userdata, int cycles_late) { | |||
| 610 | if (connection_status.status != static_cast<u32>(NetworkStatus::ConnectedAsHost)) | 661 | if (connection_status.status != static_cast<u32>(NetworkStatus::ConnectedAsHost)) |
| 611 | return; | 662 | return; |
| 612 | 663 | ||
| 613 | // TODO(Subv): Actually send the beacon. | ||
| 614 | std::vector<u8> frame = GenerateBeaconFrame(network_info, node_info); | 664 | std::vector<u8> frame = GenerateBeaconFrame(network_info, node_info); |
| 615 | 665 | ||
| 666 | using Network::WifiPacket; | ||
| 667 | WifiPacket packet; | ||
| 668 | packet.type = WifiPacket::PacketType::Beacon; | ||
| 669 | packet.data = std::move(frame); | ||
| 670 | packet.destination_address = Network::BroadcastMac; | ||
| 671 | packet.channel = network_channel; | ||
| 672 | |||
| 673 | SendPacket(packet); | ||
| 674 | |||
| 616 | // Start broadcasting the network, send a beacon frame every 102.4ms. | 675 | // Start broadcasting the network, send a beacon frame every 102.4ms. |
| 617 | CoreTiming::ScheduleEvent(msToCycles(DefaultBeaconInterval * MillisecondsPerTU) - cycles_late, | 676 | CoreTiming::ScheduleEvent(msToCycles(DefaultBeaconInterval * MillisecondsPerTU) - cycles_late, |
| 618 | beacon_broadcast_event, 0); | 677 | beacon_broadcast_event, 0); |