mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 05:40: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_uds.cpp | ||||
|             hle/service/nwm/uds_beacon.cpp | ||||
|             hle/service/nwm/uds_connection.cpp | ||||
|             hle/service/nwm/uds_data.cpp | ||||
|             hle/service/pm_app.cpp | ||||
|             hle/service/ptm/ptm.cpp | ||||
|  | @ -342,6 +343,7 @@ set(HEADERS | |||
|             hle/service/nwm/nwm_tst.h | ||||
|             hle/service/nwm/nwm_uds.h | ||||
|             hle/service/nwm/uds_beacon.h | ||||
|             hle/service/nwm/uds_connection.h | ||||
|             hle/service/nwm/uds_data.h | ||||
|             hle/service/pm_app.h | ||||
|             hle/service/ptm/ptm.h | ||||
|  |  | |||
|  | @ -42,6 +42,7 @@ using NodeList = std::vector<NodeInfo>; | |||
| enum class NetworkStatus { | ||||
|     NotConnected = 3, | ||||
|     ConnectedAsHost = 6, | ||||
|     Connecting = 7, | ||||
|     ConnectedAsClient = 9, | ||||
|     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(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 { | ||||
| public: | ||||
|     NWM_UDS(); | ||||
|  |  | |||
|  | @ -17,17 +17,6 @@ namespace NWM { | |||
| using MacAddress = std::array<u8, 6>; | ||||
| 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 | ||||
|  * 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