mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-30 21:30:04 +00:00 
			
		
		
		
	Services/UDS: Add functions to generate 802.11 auth and assoc response frames.
This commit is contained in:
		
							parent
							
								
									22e7402ab1
								
							
						
					
					
						commit
						54411bef4e
					
				
					 5 changed files with 144 additions and 11 deletions
				
			
		|  | @ -144,6 +144,7 @@ set(SRCS | ||||||
|             hle/service/nwm/nwm_tst.cpp |             hle/service/nwm/nwm_tst.cpp | ||||||
|             hle/service/nwm/nwm_uds.cpp |             hle/service/nwm/nwm_uds.cpp | ||||||
|             hle/service/nwm/uds_beacon.cpp |             hle/service/nwm/uds_beacon.cpp | ||||||
|  |             hle/service/nwm/uds_connection.cpp | ||||||
|             hle/service/nwm/uds_data.cpp |             hle/service/nwm/uds_data.cpp | ||||||
|             hle/service/pm_app.cpp |             hle/service/pm_app.cpp | ||||||
|             hle/service/ptm/ptm.cpp |             hle/service/ptm/ptm.cpp | ||||||
|  | @ -342,6 +343,7 @@ set(HEADERS | ||||||
|             hle/service/nwm/nwm_tst.h |             hle/service/nwm/nwm_tst.h | ||||||
|             hle/service/nwm/nwm_uds.h |             hle/service/nwm/nwm_uds.h | ||||||
|             hle/service/nwm/uds_beacon.h |             hle/service/nwm/uds_beacon.h | ||||||
|  |             hle/service/nwm/uds_connection.h | ||||||
|             hle/service/nwm/uds_data.h |             hle/service/nwm/uds_data.h | ||||||
|             hle/service/pm_app.h |             hle/service/pm_app.h | ||||||
|             hle/service/ptm/ptm.h |             hle/service/ptm/ptm.h | ||||||
|  |  | ||||||
|  | @ -42,6 +42,7 @@ using NodeList = std::vector<NodeInfo>; | ||||||
| enum class NetworkStatus { | enum class NetworkStatus { | ||||||
|     NotConnected = 3, |     NotConnected = 3, | ||||||
|     ConnectedAsHost = 6, |     ConnectedAsHost = 6, | ||||||
|  |     Connecting = 7, | ||||||
|     ConnectedAsClient = 9, |     ConnectedAsClient = 9, | ||||||
|     ConnectedAsSpectator = 10, |     ConnectedAsSpectator = 10, | ||||||
| }; | }; | ||||||
|  | @ -85,6 +86,17 @@ static_assert(offsetof(NetworkInfo, oui_value) == 0xC, "oui_value is at the wron | ||||||
| static_assert(offsetof(NetworkInfo, wlan_comm_id) == 0x10, "wlancommid is at the wrong offset."); | static_assert(offsetof(NetworkInfo, wlan_comm_id) == 0x10, "wlancommid is at the wrong offset."); | ||||||
| static_assert(sizeof(NetworkInfo) == 0x108, "NetworkInfo has incorrect size."); | static_assert(sizeof(NetworkInfo) == 0x108, "NetworkInfo has incorrect size."); | ||||||
| 
 | 
 | ||||||
|  | /// Additional block tag ids in the Beacon and Association Response frames
 | ||||||
|  | enum class TagId : u8 { | ||||||
|  |     SSID = 0, | ||||||
|  |     SupportedRates = 1, | ||||||
|  |     DSParameterSet = 2, | ||||||
|  |     TrafficIndicationMap = 5, | ||||||
|  |     CountryInformation = 7, | ||||||
|  |     ERPInformation = 42, | ||||||
|  |     VendorSpecific = 221 | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| class NWM_UDS final : public Interface { | class NWM_UDS final : public Interface { | ||||||
| public: | public: | ||||||
|     NWM_UDS(); |     NWM_UDS(); | ||||||
|  |  | ||||||
|  | @ -17,17 +17,6 @@ namespace NWM { | ||||||
| using MacAddress = std::array<u8, 6>; | using MacAddress = std::array<u8, 6>; | ||||||
| constexpr std::array<u8, 3> NintendoOUI = {0x00, 0x1F, 0x32}; | constexpr std::array<u8, 3> 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 |  * Internal vendor-specific tag ids as stored inside | ||||||
|  * VendorSpecific blocks in the Beacon frames. |  * VendorSpecific blocks in the Beacon frames. | ||||||
|  |  | ||||||
							
								
								
									
										79
									
								
								src/core/hle/service/nwm/uds_connection.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								src/core/hle/service/nwm/uds_connection.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,79 @@ | ||||||
|  | // Copyright 2017 Citra Emulator Project
 | ||||||
|  | // Licensed under GPLv2 or any later version
 | ||||||
|  | // Refer to the license.txt file included.
 | ||||||
|  | 
 | ||||||
|  | #include "core/hle/service/nwm/nwm_uds.h" | ||||||
|  | #include "core/hle/service/nwm/uds_connection.h" | ||||||
|  | #include "fmt/format.h" | ||||||
|  | 
 | ||||||
|  | namespace Service { | ||||||
|  | namespace NWM { | ||||||
|  | 
 | ||||||
|  | // Note: These values were taken from a packet capture of an o3DS XL
 | ||||||
|  | // broadcasting a Super Smash Bros. 4 lobby.
 | ||||||
|  | constexpr u16 DefaultExtraCapabilities = 0x0431; | ||||||
|  | 
 | ||||||
|  | std::vector<u8> GenerateAuthenticationFrame(AuthenticationSeq seq) { | ||||||
|  |     AuthenticationFrame frame{}; | ||||||
|  |     frame.auth_seq = static_cast<u16>(seq); | ||||||
|  | 
 | ||||||
|  |     std::vector<u8> data(sizeof(frame)); | ||||||
|  |     std::memcpy(data.data(), &frame, sizeof(frame)); | ||||||
|  | 
 | ||||||
|  |     return data; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | AuthenticationSeq GetAuthenticationSeqNumber(const std::vector<u8>& body) { | ||||||
|  |     AuthenticationFrame frame; | ||||||
|  |     std::memcpy(&frame, body.data(), sizeof(frame)); | ||||||
|  | 
 | ||||||
|  |     return static_cast<AuthenticationSeq>(frame.auth_seq); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Generates an SSID tag of an 802.11 Beacon frame with an 8-byte character representation of the | ||||||
|  |  * specified network id as the SSID value. | ||||||
|  |  * @param network_id The network id to use. | ||||||
|  |  * @returns A buffer with the SSID tag. | ||||||
|  |  */ | ||||||
|  | static std::vector<u8> GenerateSSIDTag(u32 network_id) { | ||||||
|  |     constexpr u8 SSIDSize = 8; | ||||||
|  | 
 | ||||||
|  |     struct { | ||||||
|  |         u8 id = static_cast<u8>(TagId::SSID); | ||||||
|  |         u8 size = SSIDSize; | ||||||
|  |     } tag_header; | ||||||
|  | 
 | ||||||
|  |     std::vector<u8> buffer(sizeof(tag_header) + SSIDSize); | ||||||
|  | 
 | ||||||
|  |     std::memcpy(buffer.data(), &tag_header, sizeof(tag_header)); | ||||||
|  | 
 | ||||||
|  |     std::string network_name = fmt::format("{0:08X}", network_id); | ||||||
|  | 
 | ||||||
|  |     std::memcpy(buffer.data() + sizeof(tag_header), network_name.c_str(), SSIDSize); | ||||||
|  | 
 | ||||||
|  |     return buffer; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | std::vector<u8> GenerateAssocResponseFrame(AssocStatus status, u16 association_id, u32 network_id) { | ||||||
|  |     AssociationResponseFrame frame{}; | ||||||
|  |     frame.capabilities = DefaultExtraCapabilities; | ||||||
|  |     frame.status_code = static_cast<u16>(status); | ||||||
|  |     // The association id is ORed with this magic value (0xC000)
 | ||||||
|  |     constexpr u16 AssociationIdMagic = 0xC000; | ||||||
|  |     frame.assoc_id = association_id | AssociationIdMagic; | ||||||
|  | 
 | ||||||
|  |     std::vector<u8> data(sizeof(frame)); | ||||||
|  |     std::memcpy(data.data(), &frame, sizeof(frame)); | ||||||
|  | 
 | ||||||
|  |     auto ssid_tag = GenerateSSIDTag(network_id); | ||||||
|  |     data.insert(data.end(), ssid_tag.begin(), ssid_tag.end()); | ||||||
|  | 
 | ||||||
|  |     // TODO(Subv): Add the SupportedRates tag.
 | ||||||
|  |     // TODO(Subv): Add the DSParameterSet tag.
 | ||||||
|  |     // TODO(Subv): Add the ERPInformation tag.
 | ||||||
|  |     return data; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | } // namespace NWM
 | ||||||
|  | } // namespace Service
 | ||||||
							
								
								
									
										51
									
								
								src/core/hle/service/nwm/uds_connection.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								src/core/hle/service/nwm/uds_connection.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,51 @@ | ||||||
|  | // Copyright 2017 Citra Emulator Project
 | ||||||
|  | // Licensed under GPLv2 or any later version
 | ||||||
|  | // Refer to the license.txt file included.
 | ||||||
|  | 
 | ||||||
|  | #pragma once | ||||||
|  | 
 | ||||||
|  | #include <vector> | ||||||
|  | #include "common/common_types.h" | ||||||
|  | #include "common/swap.h" | ||||||
|  | #include "core/hle/service/service.h" | ||||||
|  | 
 | ||||||
|  | namespace Service { | ||||||
|  | namespace NWM { | ||||||
|  | 
 | ||||||
|  | /// Sequence number of the 802.11 authentication frames.
 | ||||||
|  | enum class AuthenticationSeq : u16 { SEQ1 = 1, SEQ2 = 2 }; | ||||||
|  | 
 | ||||||
|  | enum class AuthAlgorithm : u16 { OpenSystem = 0 }; | ||||||
|  | 
 | ||||||
|  | enum class AuthStatus : u16 { Successful = 0 }; | ||||||
|  | 
 | ||||||
|  | enum class AssocStatus : u16 { Successful = 0 }; | ||||||
|  | 
 | ||||||
|  | struct AuthenticationFrame { | ||||||
|  |     u16_le auth_algorithm = static_cast<u16>(AuthAlgorithm::OpenSystem); | ||||||
|  |     u16_le auth_seq; | ||||||
|  |     u16_le status_code = static_cast<u16>(AuthStatus::Successful); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | static_assert(sizeof(AuthenticationFrame) == 6, "AuthenticationFrame has wrong size"); | ||||||
|  | 
 | ||||||
|  | struct AssociationResponseFrame { | ||||||
|  |     u16_le capabilities; | ||||||
|  |     u16_le status_code; | ||||||
|  |     u16_le assoc_id; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | static_assert(sizeof(AssociationResponseFrame) == 6, "AssociationResponseFrame has wrong size"); | ||||||
|  | 
 | ||||||
|  | /// Generates an 802.11 authentication frame, starting at the frame body.
 | ||||||
|  | std::vector<u8> GenerateAuthenticationFrame(AuthenticationSeq seq); | ||||||
|  | 
 | ||||||
|  | /// Returns the sequence number from the body of an Authentication frame.
 | ||||||
|  | AuthenticationSeq GetAuthenticationSeqNumber(const std::vector<u8>& body); | ||||||
|  | 
 | ||||||
|  | /// Generates an 802.11 association response frame with the specified status, association id and
 | ||||||
|  | /// network id, starting at the frame body.
 | ||||||
|  | std::vector<u8> GenerateAssocResponseFrame(AssocStatus status, u16 association_id, u32 network_id); | ||||||
|  | 
 | ||||||
|  | } // namespace NWM
 | ||||||
|  | } // namespace Service
 | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue