::grpc::ServerContext* context, const ::bluetooth::l2cap::classic::cert::ConfigurationRequest* request,
::bluetooth::l2cap::classic::cert::SendConfigurationRequestResult* response) override {
auto builder = ConfigurationRequestBuilder::Create(1, request->scid(), Continuation::END, {});
- auto l2cap_builder = BasicFrameBuilder::Create(1, std::move(builder));
+ auto l2cap_builder = BasicFrameBuilder::Create(kClassicSignallingCid, std::move(builder));
outgoing_packet_queue_.push(std::move(l2cap_builder));
if (outgoing_packet_queue_.size() == 1) {
acl_connection_->GetAclQueueEnd()->RegisterEnqueue(
::grpc::Status SendDisconnectionRequest(::grpc::ServerContext* context, const cert::DisconnectionRequest* request,
::google::protobuf::Empty* response) override {
- auto builder = DisconnectionRequestBuilder::Create(3, 0x40, 101);
- auto l2cap_builder = BasicFrameBuilder::Create(1, std::move(builder));
+ auto builder = DisconnectionRequestBuilder::Create(3, request->dcid(), request->scid());
+ auto l2cap_builder = BasicFrameBuilder::Create(kClassicSignallingCid, std::move(builder));
outgoing_packet_queue_.push(std::move(l2cap_builder));
if (outgoing_packet_queue_.size() == 1) {
acl_connection_->GetAclQueueEnd()->RegisterEnqueue(
lambda packet: b"abc" in packet.payload
)
- self.cert_device.l2cap.SendDisconnectionRequest(l2cap_cert_pb2.DisconnectionRequest())
+ self.cert_device.l2cap.SendDisconnectionRequest(l2cap_cert_pb2.DisconnectionRequest(dcid=0x40, scid=101))
time.sleep(1)
dut_packet_stream.unsubscribe()
cert_packet_stream.unsubscribe()
+ def test_open_two_channels(self):
+ cert_connection_stream = self.cert_device.l2cap.connection_complete_stream
+ cert_connection_stream.subscribe()
+ self.device_under_test.l2cap.OpenChannel(l2cap_facade_pb2.OpenChannelRequest(remote=self.cert_address, psm=0x01))
+ self.device_under_test.l2cap.OpenChannel(l2cap_facade_pb2.OpenChannelRequest(remote=self.cert_address, psm=0x03))
+ cert_connection_stream.assert_event_occurs(
+ lambda device: device.remote == self.dut_address
+ )
+ cert_connection_stream.unsubscribe()
+ time.sleep(1)
+ open_channels = self.cert_device.l2cap.FetchOpenedChannels(l2cap_cert_pb2.FetchOpenedChannelsRequest())
+ print (len(open_channels.cid))
+ assert len(open_channels.cid) == 2
+
def test_basic_operation_request_connection(self):
"""
L2CAP/COS/CED/BV-01-C [Request Connection]
Verify that the IUT is able to request the connection establishment for an L2CAP data channel and
initiate the configuration procedure.
"""
- self.device_under_test.l2cap.RegisterChannel(l2cap_facade_pb2.RegisterChannelRequest(channel=2))
cert_connection_stream = self.cert_device.l2cap.connection_complete_stream
cert_connection_stream.subscribe()
- self.device_under_test.l2cap.Connect(self.cert_address)
+ self.device_under_test.l2cap.OpenChannel(l2cap_facade_pb2.OpenChannelRequest(remote=self.cert_address, psm=0x01))
cert_connection_stream.assert_event_occurs(
lambda device: device.remote == self.dut_address
)
cert_connection_stream.unsubscribe()
- self.device_under_test.l2cap.OpenChannel(l2cap_facade_pb2.OpenChannelRequest(remote=self.cert_address, psm=0x01))
- time.sleep(1)
-
def test_respond_to_echo_request(self):
"""
}
void ClassicSignallingManager::OnCommandReject(CommandRejectView command_reject_view) {
+ if (pending_commands_.empty()) {
+ LOG_WARN("Unexpected command reject: no pending request");
+ return;
+ }
+ auto last_sent_command = std::move(pending_commands_.front());
+ pending_commands_.pop();
+
SignalId signal_id = command_reject_view.GetIdentifier();
- if (last_sent_command_.signal_id_ != signal_id) {
+ if (last_sent_command.signal_id_ != signal_id) {
LOG_WARN("Unknown command reject");
return;
}
void ClassicSignallingManager::OnConnectionResponse(SignalId signal_id, Cid cid, Cid remote_cid,
ConnectionResponseResult result, ConnectionResponseStatus status) {
- if (last_sent_command_.signal_id_ != signal_id ||
- last_sent_command_.command_code_ != CommandCode::CONNECTION_REQUEST) {
+ if (pending_commands_.empty()) {
+ LOG_WARN("Unexpected response: no pending request");
+ return;
+ }
+ auto last_sent_command = std::move(pending_commands_.front());
+ pending_commands_.pop();
+ if (last_sent_command.signal_id_ != signal_id || last_sent_command.command_code_ != CommandCode::CONNECTION_REQUEST) {
LOG_WARN("Received unexpected connection response");
return;
}
- if (last_sent_command_.source_cid_ != cid) {
- LOG_WARN("SCID doesn't match: expected %d, received %d", last_sent_command_.source_cid_, cid);
+ if (last_sent_command.source_cid_ != cid) {
+ LOG_WARN("SCID doesn't match: expected %d, received %d", last_sent_command.source_cid_, cid);
return;
}
if (result != ConnectionResponseResult::SUCCESS) {
return;
}
- Psm pending_psm = last_sent_command_.psm_;
- last_sent_command_ = {};
+ Psm pending_psm = last_sent_command.psm_;
auto new_channel = link_->AllocateReservedDynamicChannel(cid, pending_psm, remote_cid, {});
if (new_channel == nullptr) {
LOG_WARN("Can't allocate dynamic channel");
void ClassicSignallingManager::OnConfigurationResponse(SignalId signal_id, Cid cid, Continuation is_continuation,
ConfigurationResponseResult result,
- std::vector<std::unique_ptr<ConfigurationOption>> option) {}
+ std::vector<std::unique_ptr<ConfigurationOption>> option) {
+ if (pending_commands_.empty()) {
+ LOG_WARN("Unexpected response: no pending request");
+ return;
+ }
+
+ auto last_sent_command = std::move(pending_commands_.front());
+ pending_commands_.pop();
+}
void ClassicSignallingManager::OnDisconnectionRequest(SignalId signal_id, Cid cid, Cid remote_cid) {
// TODO: check cid match
}
void ClassicSignallingManager::OnDisconnectionResponse(SignalId signal_id, Cid cid, Cid remote_cid) {
- if (last_sent_command_.signal_id_ != signal_id ||
- last_sent_command_.command_code_ != CommandCode::DISCONNECTION_REQUEST) {
+ if (pending_commands_.empty()) {
+ LOG_WARN("Unexpected response: no pending request");
+ return;
+ }
+ auto last_sent_command = std::move(pending_commands_.front());
+ pending_commands_.pop();
+
+ if (last_sent_command.signal_id_ != signal_id ||
+ last_sent_command.command_code_ != CommandCode::DISCONNECTION_REQUEST) {
return;
}
}
void ClassicSignallingManager::OnEchoResponse(SignalId signal_id, const PacketView<kLittleEndian>& packet) {
- if (last_sent_command_.signal_id_ != signal_id || last_sent_command_.command_code_ != CommandCode::ECHO_REQUEST) {
+ if (pending_commands_.empty()) {
+ LOG_WARN("Unexpected response: no pending request");
+ return;
+ }
+ auto last_sent_command = std::move(pending_commands_.front());
+ pending_commands_.pop();
+
+ if (last_sent_command.signal_id_ != signal_id || last_sent_command.command_code_ != CommandCode::ECHO_REQUEST) {
return;
}
LOG_INFO("Echo response received");
}
void ClassicSignallingManager::OnInformationResponse(SignalId signal_id, const InformationResponseView& view) {
- if (last_sent_command_.signal_id_ != signal_id ||
- last_sent_command_.command_code_ != CommandCode::INFORMATION_REQUEST) {
+ if (pending_commands_.empty()) {
+ LOG_WARN("Unexpected response: no pending request");
+ return;
+ }
+ auto last_sent_command = std::move(pending_commands_.front());
+ pending_commands_.pop();
+
+ if (last_sent_command.signal_id_ != signal_id ||
+ last_sent_command.command_code_ != CommandCode::INFORMATION_REQUEST) {
return;
}
if (view.GetResult() != InformationRequestResult::SUCCESS) {
if (pending_commands_.empty()) {
return;
}
- last_sent_command_ = std::move(pending_commands_.front());
- pending_commands_.pop();
-
- auto signal_id = last_sent_command_.signal_id_;
- auto psm = last_sent_command_.psm_;
- auto source_cid = last_sent_command_.source_cid_;
- auto destination_cid = last_sent_command_.destination_cid_;
- auto info_type = last_sent_command_.info_type_;
- auto config = std::move(last_sent_command_.config_);
- switch (last_sent_command_.command_code_) {
+ auto& last_sent_command = pending_commands_.front();
+
+ auto signal_id = last_sent_command.signal_id_;
+ auto psm = last_sent_command.psm_;
+ auto source_cid = last_sent_command.source_cid_;
+ auto destination_cid = last_sent_command.destination_cid_;
+ auto info_type = last_sent_command.info_type_;
+ auto config = std::move(last_sent_command.config_);
+ switch (last_sent_command.command_code_) {
case CommandCode::CONNECTION_REQUEST: {
auto builder = ConnectionRequestBuilder::Create(signal_id.Value(), psm, source_cid);
enqueue_buffer_->Enqueue(std::move(builder), handler_);
break;
}
default:
- LOG_WARN("Unsupported command code 0x%x", static_cast<int>(last_sent_command_.command_code_));
+ LOG_WARN("Unsupported command code 0x%x", static_cast<int>(last_sent_command.command_code_));
}
}