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.
This commit is contained in:
		| @@ -91,12 +91,95 @@ void HandleBeaconFrame(const Network::WifiPacket& packet) { | ||||
|         received_beacons.pop_front(); | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Returns an available index in the nodes array for the | ||||
|  * currently-hosted UDS network. | ||||
|  */ | ||||
| static u16 GetNextAvailableNodeId() { | ||||
|     ASSERT_MSG(connection_status.status == static_cast<u32>(NetworkStatus::ConnectedAsHost), | ||||
|                "Can not accept clients if we're not hosting a network"); | ||||
|  | ||||
|     for (u16 index = 0; index < connection_status.max_nodes; ++index) { | ||||
|         if ((connection_status.node_bitmask & (1 << index)) == 0) | ||||
|             return index; | ||||
|     } | ||||
|  | ||||
|     // Any connection attempts to an already full network should have been refused. | ||||
|     ASSERT_MSG(false, "No available connection slots in the network"); | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Start a connection sequence with an UDS server. The sequence starts by sending an 802.11 | ||||
|  * authentication frame with SEQ1. | ||||
|  */ | ||||
| void StartConnectionSequence(const MacAddress& server) { | ||||
|     ASSERT(connection_status.status == static_cast<u32>(NetworkStatus::NotConnected)); | ||||
|  | ||||
|     // TODO(Subv): Handle timeout. | ||||
|  | ||||
|     // Send an authentication frame with SEQ1 | ||||
|     using Network::WifiPacket; | ||||
|     WifiPacket auth_request; | ||||
|     auth_request.channel = network_channel; | ||||
|     auth_request.data = GenerateAuthenticationFrame(AuthenticationSeq::SEQ1); | ||||
|     auth_request.destination_address = server; | ||||
|     auth_request.type = WifiPacket::PacketType::Authentication; | ||||
|  | ||||
|     SendPacket(auth_request); | ||||
| } | ||||
|  | ||||
| /// Sends an Association Response frame to the specified mac address | ||||
| void SendAssociationResponseFrame(const MacAddress& address) { | ||||
|     ASSERT_MSG(connection_status.status == static_cast<u32>(NetworkStatus::ConnectedAsHost)); | ||||
|  | ||||
|     using Network::WifiPacket; | ||||
|     WifiPacket assoc_response; | ||||
|     assoc_response.channel = network_channel; | ||||
|     // TODO(Subv): This will cause multiple clients to end up with the same association id, but | ||||
|     // we're not using that for anything. | ||||
|     u16 association_id = 1; | ||||
|     assoc_response.data = GenerateAssocResponseFrame(AssocStatus::Successful, association_id, | ||||
|                                                      network_info.network_id); | ||||
|     assoc_response.destination_address = address; | ||||
|     assoc_response.type = WifiPacket::PacketType::AssociationResponse; | ||||
|  | ||||
|     SendPacket(assoc_response); | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Handles the authentication request frame and sends the authentication response and association | ||||
|  * response frames. Once an Authentication frame with SEQ1 is received by the server, it responds | ||||
|  * with an Authentication frame containing SEQ2, and immediately sends an Association response frame | ||||
|  * containing the details of the access point and the assigned association id for the new client. | ||||
|  */ | ||||
| void HandleAuthenticationFrame(const Network::WifiPacket& packet) { | ||||
|     // Only the SEQ1 auth frame is handled here, the SEQ2 frame doesn't need any special behavior | ||||
|     if (GetAuthenticationSeqNumber(packet.data) == AuthenticationSeq::SEQ1) { | ||||
|         ASSERT_MSG(connection_status.status == static_cast<u32>(NetworkStatus::ConnectedAsHost)); | ||||
|  | ||||
|         // Respond with an authentication response frame with SEQ2 | ||||
|         using Network::WifiPacket; | ||||
|         WifiPacket auth_request; | ||||
|         auth_request.channel = network_channel; | ||||
|         auth_request.data = GenerateAuthenticationFrame(AuthenticationSeq::SEQ2); | ||||
|         auth_request.destination_address = packet.transmitter_address; | ||||
|         auth_request.type = WifiPacket::PacketType::Authentication; | ||||
|  | ||||
|         SendPacket(auth_request); | ||||
|  | ||||
|         SendAssociationResponseFrame(packet.transmitter_address); | ||||
|     } | ||||
| } | ||||
|  | ||||
| /// Callback to parse and handle a received wifi packet. | ||||
| void OnWifiPacketReceived(const Network::WifiPacket& packet) { | ||||
|     switch (packet.type) { | ||||
|     case Network::WifiPacket::PacketType::Beacon: | ||||
|         HandleBeaconFrame(packet); | ||||
|         break; | ||||
|     case Network::WifiPacket::PacketType::Authentication: | ||||
|         HandleAuthenticationFrame(packet); | ||||
|         break; | ||||
|     } | ||||
| } | ||||
|  | ||||
| @@ -677,23 +760,6 @@ static void BeaconBroadcastCallback(u64 userdata, int cycles_late) { | ||||
|                               beacon_broadcast_event, 0); | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Returns an available index in the nodes array for the | ||||
|  * currently-hosted UDS network. | ||||
|  */ | ||||
| static u32 GetNextAvailableNodeId() { | ||||
|     ASSERT_MSG(connection_status.status == static_cast<u32>(NetworkStatus::ConnectedAsHost), | ||||
|                "Can not accept clients if we're not hosting a network"); | ||||
|  | ||||
|     for (unsigned index = 0; index < connection_status.max_nodes; ++index) { | ||||
|         if ((connection_status.node_bitmask & (1 << index)) == 0) | ||||
|             return index; | ||||
|     } | ||||
|  | ||||
|     // Any connection attempts to an already full network should have been refused. | ||||
|     ASSERT_MSG(false, "No available connection slots in the network"); | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Called when a client connects to an UDS network we're hosting, | ||||
|  * updates the connection status and signals the update event. | ||||
|   | ||||
		Reference in New Issue
	
	Block a user