diff options
| author | 2017-07-17 09:51:03 -0500 | |
|---|---|---|
| committer | 2017-08-27 10:48:13 -0500 | |
| commit | d088dbfbe1064bb5212e83c50e71e4b2ea5b00cd (patch) | |
| tree | d0050ed036f228bff3ce4cc68fb3dcde93f22e8c /src | |
| parent | Services/UDS: Store the received beacon frames until RecvBeaconBroadcastData ... (diff) | |
| download | yuzu-d088dbfbe1064bb5212e83c50e71e4b2ea5b00cd.tar.gz yuzu-d088dbfbe1064bb5212e83c50e71e4b2ea5b00cd.tar.xz yuzu-d088dbfbe1064bb5212e83c50e71e4b2ea5b00cd.zip | |
Services/UDS: Handle the connection sequence packets.
There is currently no stage tracking, a client is considered "Connected" when it receives the EAPoL Logoff packet from the server, this is not yet implemented.
Diffstat (limited to '')
| -rw-r--r-- | src/core/hle/service/nwm/nwm_uds.cpp | 100 |
1 files changed, 83 insertions, 17 deletions
diff --git a/src/core/hle/service/nwm/nwm_uds.cpp b/src/core/hle/service/nwm/nwm_uds.cpp index 8fdf160ff..893bbb1e7 100644 --- a/src/core/hle/service/nwm/nwm_uds.cpp +++ b/src/core/hle/service/nwm/nwm_uds.cpp | |||
| @@ -91,12 +91,95 @@ void HandleBeaconFrame(const Network::WifiPacket& packet) { | |||
| 91 | received_beacons.pop_front(); | 91 | received_beacons.pop_front(); |
| 92 | } | 92 | } |
| 93 | 93 | ||
| 94 | /* | ||
| 95 | * Returns an available index in the nodes array for the | ||
| 96 | * currently-hosted UDS network. | ||
| 97 | */ | ||
| 98 | static u16 GetNextAvailableNodeId() { | ||
| 99 | ASSERT_MSG(connection_status.status == static_cast<u32>(NetworkStatus::ConnectedAsHost), | ||
| 100 | "Can not accept clients if we're not hosting a network"); | ||
| 101 | |||
| 102 | for (u16 index = 0; index < connection_status.max_nodes; ++index) { | ||
| 103 | if ((connection_status.node_bitmask & (1 << index)) == 0) | ||
| 104 | return index; | ||
| 105 | } | ||
| 106 | |||
| 107 | // Any connection attempts to an already full network should have been refused. | ||
| 108 | ASSERT_MSG(false, "No available connection slots in the network"); | ||
| 109 | } | ||
| 110 | |||
| 111 | /* | ||
| 112 | * Start a connection sequence with an UDS server. The sequence starts by sending an 802.11 | ||
| 113 | * authentication frame with SEQ1. | ||
| 114 | */ | ||
| 115 | void StartConnectionSequence(const MacAddress& server) { | ||
| 116 | ASSERT(connection_status.status == static_cast<u32>(NetworkStatus::NotConnected)); | ||
| 117 | |||
| 118 | // TODO(Subv): Handle timeout. | ||
| 119 | |||
| 120 | // Send an authentication frame with SEQ1 | ||
| 121 | using Network::WifiPacket; | ||
| 122 | WifiPacket auth_request; | ||
| 123 | auth_request.channel = network_channel; | ||
| 124 | auth_request.data = GenerateAuthenticationFrame(AuthenticationSeq::SEQ1); | ||
| 125 | auth_request.destination_address = server; | ||
| 126 | auth_request.type = WifiPacket::PacketType::Authentication; | ||
| 127 | |||
| 128 | SendPacket(auth_request); | ||
| 129 | } | ||
| 130 | |||
| 131 | /// Sends an Association Response frame to the specified mac address | ||
| 132 | void SendAssociationResponseFrame(const MacAddress& address) { | ||
| 133 | ASSERT_MSG(connection_status.status == static_cast<u32>(NetworkStatus::ConnectedAsHost)); | ||
| 134 | |||
| 135 | using Network::WifiPacket; | ||
| 136 | WifiPacket assoc_response; | ||
| 137 | assoc_response.channel = network_channel; | ||
| 138 | // TODO(Subv): This will cause multiple clients to end up with the same association id, but | ||
| 139 | // we're not using that for anything. | ||
| 140 | u16 association_id = 1; | ||
| 141 | assoc_response.data = GenerateAssocResponseFrame(AssocStatus::Successful, association_id, | ||
| 142 | network_info.network_id); | ||
| 143 | assoc_response.destination_address = address; | ||
| 144 | assoc_response.type = WifiPacket::PacketType::AssociationResponse; | ||
| 145 | |||
| 146 | SendPacket(assoc_response); | ||
| 147 | } | ||
| 148 | |||
| 149 | /* | ||
| 150 | * Handles the authentication request frame and sends the authentication response and association | ||
| 151 | * response frames. Once an Authentication frame with SEQ1 is received by the server, it responds | ||
| 152 | * with an Authentication frame containing SEQ2, and immediately sends an Association response frame | ||
| 153 | * containing the details of the access point and the assigned association id for the new client. | ||
| 154 | */ | ||
| 155 | void HandleAuthenticationFrame(const Network::WifiPacket& packet) { | ||
| 156 | // Only the SEQ1 auth frame is handled here, the SEQ2 frame doesn't need any special behavior | ||
| 157 | if (GetAuthenticationSeqNumber(packet.data) == AuthenticationSeq::SEQ1) { | ||
| 158 | ASSERT_MSG(connection_status.status == static_cast<u32>(NetworkStatus::ConnectedAsHost)); | ||
| 159 | |||
| 160 | // Respond with an authentication response frame with SEQ2 | ||
| 161 | using Network::WifiPacket; | ||
| 162 | WifiPacket auth_request; | ||
| 163 | auth_request.channel = network_channel; | ||
| 164 | auth_request.data = GenerateAuthenticationFrame(AuthenticationSeq::SEQ2); | ||
| 165 | auth_request.destination_address = packet.transmitter_address; | ||
| 166 | auth_request.type = WifiPacket::PacketType::Authentication; | ||
| 167 | |||
| 168 | SendPacket(auth_request); | ||
| 169 | |||
| 170 | SendAssociationResponseFrame(packet.transmitter_address); | ||
| 171 | } | ||
| 172 | } | ||
| 173 | |||
| 94 | /// Callback to parse and handle a received wifi packet. | 174 | /// Callback to parse and handle a received wifi packet. |
| 95 | void OnWifiPacketReceived(const Network::WifiPacket& packet) { | 175 | void OnWifiPacketReceived(const Network::WifiPacket& packet) { |
| 96 | switch (packet.type) { | 176 | switch (packet.type) { |
| 97 | case Network::WifiPacket::PacketType::Beacon: | 177 | case Network::WifiPacket::PacketType::Beacon: |
| 98 | HandleBeaconFrame(packet); | 178 | HandleBeaconFrame(packet); |
| 99 | break; | 179 | break; |
| 180 | case Network::WifiPacket::PacketType::Authentication: | ||
| 181 | HandleAuthenticationFrame(packet); | ||
| 182 | break; | ||
| 100 | } | 183 | } |
| 101 | } | 184 | } |
| 102 | 185 | ||
| @@ -678,23 +761,6 @@ static void BeaconBroadcastCallback(u64 userdata, int cycles_late) { | |||
| 678 | } | 761 | } |
| 679 | 762 | ||
| 680 | /* | 763 | /* |
| 681 | * Returns an available index in the nodes array for the | ||
| 682 | * currently-hosted UDS network. | ||
| 683 | */ | ||
| 684 | static u32 GetNextAvailableNodeId() { | ||
| 685 | ASSERT_MSG(connection_status.status == static_cast<u32>(NetworkStatus::ConnectedAsHost), | ||
| 686 | "Can not accept clients if we're not hosting a network"); | ||
| 687 | |||
| 688 | for (unsigned index = 0; index < connection_status.max_nodes; ++index) { | ||
| 689 | if ((connection_status.node_bitmask & (1 << index)) == 0) | ||
| 690 | return index; | ||
| 691 | } | ||
| 692 | |||
| 693 | // Any connection attempts to an already full network should have been refused. | ||
| 694 | ASSERT_MSG(false, "No available connection slots in the network"); | ||
| 695 | } | ||
| 696 | |||
| 697 | /* | ||
| 698 | * Called when a client connects to an UDS network we're hosting, | 764 | * Called when a client connects to an UDS network we're hosting, |
| 699 | * updates the connection status and signals the update event. | 765 | * updates the connection status and signals the update event. |
| 700 | * @param network_node_id Network Node Id of the connecting client. | 766 | * @param network_node_id Network Node Id of the connecting client. |