1 // Copyright 2023 The Pigweed Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not 4 // use this file except in compliance with the License. You may obtain a copy of 5 // the License at 6 // 7 // https://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 // License for the specific language governing permissions and limitations under 13 // the License. 14 15 #pragma once 16 #include "fake_l2cap.h" 17 #include "pw_bluetooth_sapphire/internal/host/common/byte_buffer.h" 18 #include "pw_bluetooth_sapphire/internal/host/common/packet_view.h" 19 #include "pw_bluetooth_sapphire/internal/host/hci-spec/protocol.h" 20 #include "pw_bluetooth_sapphire/internal/host/l2cap/l2cap_defs.h" 21 #include "pw_bluetooth_sapphire/internal/host/testing/fake_dynamic_channel.h" 22 23 namespace bt::testing { 24 25 // This class unpacks signaling packets (generally received over a FakeL2cap 26 // link). Each FakePeer should own its own FakeSignalingServer. 27 class FakeSignalingServer final { 28 public: 29 FakeSignalingServer() = default; 30 31 // Registers this FakeSignalingServer's HandleSdu function with |l2cap_| on 32 // kSignalingChannelId such that all packets processed by |l2cap_| with the 33 // ChannelId kSignalingChanneld will be processed by this server. 34 // FakeL2cap will also handle actually sending packets generated by this 35 // FakeSignalingServer instance. 36 void RegisterWithL2cap(FakeL2cap* l2cap_); 37 38 // Handles the service data unit |sdu| received over link with handle |conn| 39 // by confirming that the received packet is valid and then calling 40 // ProcessSignalingPacket. 41 void HandleSdu(hci_spec::ConnectionHandle conn, const ByteBuffer& sdu); 42 43 // Parses the InformationRequest signaling packet |info_req| and then 44 // calls the appropriate function to construct and send a response packet 45 // over handle |conn| and ID |id|. 46 void ProcessInformationRequest(hci_spec::ConnectionHandle conn, 47 l2cap::CommandId id, 48 const ByteBuffer& info_req); 49 50 // Handle incoming ConnectionRequest |connection_req| by validating the 51 // request, creating a FakeDynamicChannel object, and registering that 52 // channel with the associated FakeL2cap module. Also will use the server's 53 // SendFrameCallback to send a ConnectionResponse and ConfigurationRequest 54 // over handle |conn| and ID |id|. 55 void ProcessConnectionRequest(hci_spec::ConnectionHandle conn, 56 l2cap::CommandId id, 57 const ByteBuffer& connection_req); 58 59 // Handle incoming ConfigurationRequest |configuration_req|. Note that 60 // because the all channels here are basic mode, this is simply part of the 61 // connection process and does not actually configure specific parameters 62 // of the associated FakeDynamicChannel aside from enabling data transfer 63 // when both sides send and receive connection requests. 64 // The emulator assumes that the ProcessConnectionRequest function handles 65 // sending the initial ConfigurationRequest from FakePeer, so if the emulator 66 // received a ConfigurationRequest from bt-host, it will assume the 67 // channel is ready to open. 68 // FakePeer will still respond with a ConfigurationResponse over handle 69 // |conn| using the ID |id| and send it using the FakeL2cap instance's 70 // SendFrameCallback. 71 void ProcessConfigurationRequest(hci_spec::ConnectionHandle conn, 72 l2cap::CommandId id, 73 const ByteBuffer& configuration_req); 74 75 // Handle configuration responses sent by bt-host. The emulator assumes that 76 // the ProcessConnectionRequest function handles sending the initial 77 // ConfigurationRequest from FakePeer, so it disregards this 78 // ConnfigurationResponse and instead only processes bt-host's inbound 79 // ConfigurationRequest. 80 void ProcessConfigurationResponse(hci_spec::ConnectionHandle conn, 81 l2cap::CommandId id, 82 const ByteBuffer& configuration_res); 83 84 // Upon receiving the disconnection request |disconnection_req|, close and 85 // delete the associated channel from the map associated with fake_l2cap_, 86 // and then send back a disconnection response with connection handle 87 // |conn| and ID |id| and send it using the FakeL2cap instance's 88 // SendFrameCallback.. 89 void ProcessDisconnectionRequest(hci_spec::ConnectionHandle conn, 90 l2cap::CommandId id, 91 const ByteBuffer& disconnection_req); 92 93 // Helper function for sending an individual payload buffer |payload_buffer| 94 // by assembling a header with CommandCode |code| and CommandId |id| and then 95 // send it over handle |conn| and with the FakeL2cap instance's 96 // SendFrameCallback. 97 void SendCFrame(hci_spec::ConnectionHandle conn, 98 l2cap::CommandCode code, 99 l2cap::CommandId id, 100 DynamicByteBuffer& payload_buffer); 101 102 // Reject a command packet for some |reason|. Assemble a command reject 103 // packet using the handle |conn| and the CommandId |id| and send with the 104 // FakeL2cap instance's SendFrameCallback. 105 void SendCommandReject(hci_spec::ConnectionHandle conn, 106 l2cap::CommandId id, 107 l2cap::RejectReason reason); 108 109 // Respond to a received fixed channels InformationRequest packet with a 110 // InformationResponse. Assemble the InformationResponse using the handle 111 // |conn| and id |id|. Send with the FakeL2cap instance's SendFrameCallback. 112 void SendInformationResponseFixedChannels(hci_spec::ConnectionHandle conn, 113 l2cap::CommandId id); 114 115 // Respond to a received extended features InformationRequest packet with a 116 // InformationResponse. Assemble the InformationResponse using the handle 117 // |conn| and id |id|. Send with the FakeL2cap instance's SendFrameCallback. 118 void SendInformationResponseExtendedFeatures(hci_spec::ConnectionHandle conn, 119 l2cap::CommandId id); 120 121 // Respond to a received ConnectionRequest packet with a ConnectionResponse. 122 // Assemble the ConnectionResponse using the handle |conn|, id |id|, local 123 // channel |local_id|, remote channel |remote_id|, ConnectionResult |result|, 124 // and ConnectionStatus |status|. Send with the FakeL2cap instance's 125 // SendFrameCallback. 126 void SendConnectionResponse(hci_spec::ConnectionHandle conn, 127 l2cap::CommandId id, 128 l2cap::ChannelId local_cid, 129 l2cap::ChannelId remote_id, 130 l2cap::ConnectionResult result, 131 l2cap::ConnectionStatus status); 132 133 // Send a ConfigurationRequest packet following a ConnectionResponse. 134 // Assemble the ConfigurationRequest using the handle |conn|, id |id|, 135 // and remote ID |remote_cid|. Send with the FakeL2cap instance's 136 // SendFrameCallback. 137 void SendConfigurationRequest(hci_spec::ConnectionHandle conn, 138 l2cap::CommandId id, 139 l2cap::ChannelId remote_cid); 140 141 // Respond to a received ConfigurationRequest packet with a 142 // ConfigurationResposne. Assemble the ConfigurationResposne using the handle 143 // |conn|, id |id|, local ID |local_cid|, and ConfigurationResult |result|. 144 // Send with the 145 /// FakeL2cap instance's SendFrameCallback. 146 void SendConfigurationResponse(hci_spec::ConnectionHandle conn, 147 l2cap::CommandId id, 148 l2cap::ChannelId local_cid, 149 l2cap::ConfigurationResult result); 150 151 // Respond to a received DisconnectionRequest packet with a 152 // DisconnectionResponse. Assemble the DisconnectionREsponse using the handle 153 // |conn|, id |id|, local ID |local_cid|, and remote ID |remote_cid|. Send 154 // with the FakeL2cap instance's SendFrameCallback. 155 void SendDisconnectionResponse(hci_spec::ConnectionHandle conn, 156 l2cap::CommandId id, 157 l2cap::ChannelId local_cid, 158 l2cap::ChannelId remote_cid); 159 160 // Return the FakeL2cap instance associated with this FakeSignalingServer. fake_l2cap()161 FakeL2cap* fake_l2cap() { return fake_l2cap_; } 162 163 private: 164 // FakeL2cap instance associated with this server, populated after this 165 // FakeSignalingServer registers itself with FakeL2cap. 166 FakeL2cap* fake_l2cap_; 167 168 BT_DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(FakeSignalingServer); 169 }; 170 171 } // namespace bt::testing 172