diff --git a/src/network/room.cpp b/src/network/room.cpp index 3502264e1..3caa3aeae 100644 --- a/src/network/room.cpp +++ b/src/network/room.cpp @@ -98,6 +98,12 @@ public: * The first 3 bytes are the NintendoOUI 0x00, 0x1F, 0x32 */ MacAddress GenerateMacAddress(); + + /** + * Broadcasts this packet to all members except the sender. + * @param event The ENet event containing the data + */ + void HandleWifiPacket(const ENetEvent* event); }; // RoomImpl @@ -111,7 +117,10 @@ void Room::RoomImpl::ServerLoop() { case IdJoinRequest: HandleJoinRequest(&event); break; - // TODO(B3N30): Handle the other message types + // TODO(B3N30): Handle the other message types + case IdWifiPacket: + HandleWifiPacket(&event); + break; } enet_packet_destroy(event.packet); break; @@ -247,6 +256,14 @@ MacAddress Room::RoomImpl::GenerateMacAddress() { return result_mac; } +void Room::RoomImpl::HandleWifiPacket(const ENetEvent* event) { + for (auto it = members.begin(); it != members.end(); ++it) { + if (it->peer != event->peer) + enet_peer_send(it->peer, 0, event->packet); + } + enet_host_flush(server); +} + // Room Room::Room() : room_impl{std::make_unique()} {} diff --git a/src/network/room_member.cpp b/src/network/room_member.cpp index 09573ee43..f919e4de0 100644 --- a/src/network/room_member.cpp +++ b/src/network/room_member.cpp @@ -62,6 +62,12 @@ public: * @param event The ENet event that was received. */ void HandleRoomInformationPacket(const ENetEvent* event); + + /** + * Extracts a WifiPacket from a received ENet packet. + * @param event The ENet event that was received. + */ + void HandleWifiPackets(const ENetEvent* event); }; // RoomMemberImpl @@ -174,6 +180,34 @@ void RoomMember::RoomMemberImpl::HandleJoinPacket(const ENetEvent* event) { // TODO(B3N30): Invoke callbacks } +void RoomMember::RoomMemberImpl::HandleWifiPackets(const ENetEvent* event) { + WifiPacket wifi_packet{}; + Packet packet; + packet.Append(event->packet->data, event->packet->dataLength); + + // Ignore the first byte, which is the message id. + packet.IgnoreBytes(sizeof(MessageID)); + + // Parse the WifiPacket from the BitStream + uint8_t frame_type; + packet >> frame_type; + WifiPacket::PacketType type = static_cast(frame_type); + + wifi_packet.type = type; + packet >> wifi_packet.channel; + packet >> wifi_packet.transmitter_address; + packet >> wifi_packet.destination_address; + + uint32_t data_length; + packet >> data_length; + + std::vector data(data_length); + packet >> data; + + wifi_packet.data = std::move(data); + // TODO(B3N30): Invoke callbacks +} + // RoomMember RoomMember::RoomMember() : room_member_impl{std::make_unique()} { room_member_impl->client = enet_host_create(nullptr, 1, NumChannels, 0, 0); @@ -227,6 +261,18 @@ bool RoomMember::IsConnected() const { return room_member_impl->IsConnected(); } +void RoomMember::SendWifiPacket(const WifiPacket& wifi_packet) { + Packet packet; + packet << static_cast(IdWifiPacket); + packet << static_cast(wifi_packet.type); + packet << wifi_packet.channel; + packet << wifi_packet.transmitter_address; + packet << wifi_packet.destination_address; + packet << static_cast(wifi_packet.data.size()); + packet << wifi_packet.data; + room_member_impl->Send(packet); +} + void RoomMember::Leave() { ASSERT_MSG(room_member_impl->receive_thread != nullptr, "Must be in a room to leave it."); { diff --git a/src/network/room_member.h b/src/network/room_member.h index f8bdbaea8..d23f5d4b6 100644 --- a/src/network/room_member.h +++ b/src/network/room_member.h @@ -12,6 +12,18 @@ namespace Network { +/// Information about the received WiFi packets. +/// Acts as our own 802.11 header. +struct WifiPacket { + enum class PacketType { Beacon, Data, Management }; + PacketType type; ///< The type of 802.11 frame, Beacon / Data. + std::vector data; ///< Raw 802.11 frame data, starting at the management frame header + /// for management frames. + MacAddress transmitter_address; ///< Mac address of the transmitter. + MacAddress destination_address; ///< Mac address of the receiver. + uint8_t channel; ///< WiFi channel where this frame was transmitted. +}; + /** * This is what a client [person joining a server] would use. * It also has to be used if you host a game yourself (You'd create both, a Room and a @@ -69,6 +81,12 @@ public: void Join(const std::string& nickname, const char* server_addr = "127.0.0.1", const u16 serverPort = DefaultRoomPort, const u16 clientPort = 0); + /** + * Sends a WiFi packet to the room. + * @param packet The WiFi packet to send. + */ + void SendWifiPacket(const WifiPacket& packet); + /** * Leaves the current room. */