From 528dea988c9f8012a2872e78f168eac1b3161c57 Mon Sep 17 00:00:00 2001 From: Subv Date: Sun, 19 Mar 2017 21:36:51 -0500 Subject: Services/UDS: Generate the UDS beacons when the beacon callback fires. --- src/core/hle/service/nwm/uds_beacon.h | 173 ++++++++++++++++++++++++++++++++++ 1 file changed, 173 insertions(+) create mode 100644 src/core/hle/service/nwm/uds_beacon.h (limited to 'src/core/hle/service/nwm/uds_beacon.h') diff --git a/src/core/hle/service/nwm/uds_beacon.h b/src/core/hle/service/nwm/uds_beacon.h new file mode 100644 index 000000000..6df4c4f47 --- /dev/null +++ b/src/core/hle/service/nwm/uds_beacon.h @@ -0,0 +1,173 @@ +// 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 "common/common_types.h" +#include "common/swap.h" +#include "core/hle/service/service.h" + +namespace Service { +namespace NWM { + +using MacAddress = std::array; + +/// The maximum number of nodes that can exist in an UDS session. +constexpr u32 UDSMaxNodes = 16; +constexpr std::array NintendoOUI = {0x00, 0x1F, 0x32}; + +/// Additional block tag ids in the Beacon frames +enum class TagId : u8 { + SSID = 0, + SupportedRates = 1, + DSParameterSet = 2, + TrafficIndicationMap = 5, + CountryInformation = 7, + ERPInformation = 42, + VendorSpecific = 221 +}; + +/** + * Internal vendor-specific tag ids as stored inside + * VendorSpecific blocks in the Beacon frames. + */ +enum class NintendoTagId : u8 { + Dummy = 20, + NetworkInfo = 21, + EncryptedData0 = 24, + EncryptedData1 = 25, +}; + +struct BeaconEntryHeader { + u32_le total_size; + INSERT_PADDING_BYTES(1); + u8 wifi_channel; + INSERT_PADDING_BYTES(2); + MacAddress mac_address; + INSERT_PADDING_BYTES(6); + u32_le unk_size; + u32_le header_size; +}; + +static_assert(sizeof(BeaconEntryHeader) == 0x1C, "BeaconEntryHeader has incorrect size."); + +struct BeaconDataReplyHeader { + u32_le max_output_size; + u32_le total_size; + u32_le total_entries; +}; + +static_assert(sizeof(BeaconDataReplyHeader) == 12, "BeaconDataReplyHeader has incorrect size."); + +#pragma pack(push, 1) +struct BeaconFrameHeader { + // Number of microseconds the AP has been active. + u64_le timestamp; + // Interval between beacon transmissions, expressed in TU. + u16_le beacon_interval; + // Indicates the presence of optional capabilities. + u16_le capabilities; +}; +#pragma pack(pop) + +static_assert(sizeof(BeaconFrameHeader) == 12, "BeaconFrameHeader has incorrect size."); + +struct TagHeader { + u8 tag_id; + u8 length; +}; + +static_assert(sizeof(TagHeader) == 2, "TagHeader has incorrect size."); + +struct DummyTag { + TagHeader header; + std::array oui; + u8 oui_type; + std::array data; +}; + +static_assert(sizeof(DummyTag) == 9, "DummyTag has incorrect size."); + +struct NetworkInfoTag { + TagHeader header; + std::array network_info; + std::array sha_hash; + u8 appdata_size; +}; + +static_assert(sizeof(NetworkInfoTag) == 54, "NetworkInfoTag has incorrect size."); + +struct EncryptedDataTag { + TagHeader header; + std::array oui; + u8 oui_type; +}; + +static_assert(sizeof(EncryptedDataTag) == 6, "EncryptedDataTag has incorrect size."); + +#pragma pack(push, 1) +// The raw bytes of this structure are the CTR used in the encryption (AES-CTR) +// of the beacon data stored in the EncryptedDataTags. +struct BeaconDataCryptoCTR { + MacAddress host_mac; + u32_le wlan_comm_id; + u8 id; + INSERT_PADDING_BYTES(1); + u32_le network_id; +}; + +static_assert(sizeof(BeaconDataCryptoCTR) == 0x10, "BeaconDataCryptoCTR has incorrect size."); + +struct BeaconNodeInfo { + u64_be friend_code_seed; + std::array username; + u16_be network_node_id; +}; + +static_assert(sizeof(BeaconNodeInfo) == 0x1E, "BeaconNodeInfo has incorrect size."); + +struct BeaconData { + std::array md5_hash; + u16_be bitmask; +}; +#pragma pack(pop) + +static_assert(sizeof(BeaconData) == 0x12, "BeaconData has incorrect size."); + +/// Information about a received WiFi packet. +/// Acts as our own 802.11 header. +struct WifiPacket { + enum class PacketType { Beacon, Data }; + + PacketType type; ///< The type of 802.11 frame, Beacon / Data. + + /// Raw 802.11 frame data, starting at the management frame header for management frames. + std::vector data; + MacAddress transmitter_address; ///< Mac address of the transmitter. + MacAddress destination_address; ///< Mac address of the receiver. + u8 channel; ///< WiFi channel where this frame was transmitted. +}; + +/** + * Decrypts the beacon data buffer for the network described by `network_info`. + */ +void DecryptBeaconData(const NetworkInfo& network_info, std::vector& buffer); + +/** + * Generates an 802.11 beacon frame starting at the management frame header. + * This frame contains information about the network and its connected clients. + * @returns The generated frame. + */ +std::vector GenerateBeaconFrame(const NetworkInfo& network_info, const NodeList& nodes); + +/** + * Returns a list of received 802.11 frames from the specified sender + * matching the type since the last call. + */ +std::deque GetReceivedPackets(WifiPacket::PacketType type, const MacAddress& sender); +} // namespace NWM +} // namespace Service -- cgit v1.2.3