OSDN Git Service

L2CAP: Notify DynamicChannel open after configuration is done
authorHansong Zhang <hsz@google.com>
Fri, 8 Nov 2019 01:09:00 +0000 (17:09 -0800)
committerHansong Zhang <hsz@google.com>
Fri, 8 Nov 2019 01:13:34 +0000 (17:13 -0800)
DynamicChannel is usable only after two-way configuration is done. Also
we need to cancel alarm when we receive a response for signalling
packet.

Test: cert/run_cert.sh
Bug: 141557006
Change-Id: Iff769fda8af277734566a74327e85ddd4b78771a

gd/l2cap/classic/cert/simple_l2cap_test.py
gd/l2cap/classic/internal/dynamic_channel_impl.cc
gd/l2cap/classic/internal/dynamic_channel_impl.h
gd/l2cap/classic/internal/signalling_manager.cc

index 48065c4..eb4363f 100644 (file)
@@ -29,6 +29,8 @@ from l2cap.classic.cert import api_pb2 as l2cap_cert_pb2
 
 import time
 
+ASYNC_OP_TIME_SECONDS = 1  # TODO: Use events to synchronize events instead
+
 class SimpleL2capTest(GdBaseTestClass):
     def setup_test(self):
         self.device_under_test = self.gd_devices[0]
@@ -85,14 +87,14 @@ class SimpleL2capTest(GdBaseTestClass):
         dut_connection_stream.unsubscribe()
 
         self.cert_device.l2cap.SendConnectionRequest(l2cap_cert_pb2.ConnectionRequest(scid=0x101, psm=1))
-        time.sleep(1)
-
+        time.sleep(ASYNC_OP_TIME_SECONDS)
         open_channels = self.cert_device.l2cap.FetchOpenedChannels(l2cap_cert_pb2.FetchOpenedChannelsRequest())
         cid = open_channels.dcid[0]
+        self.cert_device.l2cap.SendConfigurationRequest(l2cap_cert_pb2.ConfigurationRequest(scid=cid))
+        time.sleep(ASYNC_OP_TIME_SECONDS)
 
         dut_packet_stream.subscribe()
         cert_packet_stream.subscribe()
-        self.cert_device.l2cap.SendConfigurationRequest(l2cap_cert_pb2.ConfigurationRequest(scid=cid))
 
         self.cert_device.l2cap.SendL2capPacket(l2cap_facade_pb2.L2capPacket(channel=2, payload=b"abc"))
         dut_packet_stream.assert_event_occurs(
@@ -114,7 +116,7 @@ class SimpleL2capTest(GdBaseTestClass):
         )
 
         self.cert_device.l2cap.SendDisconnectionRequest(l2cap_cert_pb2.DisconnectionRequest(dcid=0x40, scid=101))
-        time.sleep(1)
+        time.sleep(ASYNC_OP_TIME_SECONDS)
         dut_packet_stream.unsubscribe()
         cert_packet_stream.unsubscribe()
 
@@ -127,7 +129,7 @@ class SimpleL2capTest(GdBaseTestClass):
             lambda device: device.remote == self.dut_address
         )
         cert_connection_stream.unsubscribe()
-        time.sleep(1)
+        time.sleep(ASYNC_OP_TIME_SECONDS)
         open_channels = self.cert_device.l2cap.FetchOpenedChannels(l2cap_cert_pb2.FetchOpenedChannelsRequest())
         assert len(open_channels.dcid) == 2
 
index 47bfd5e..d81096d 100644 (file)
@@ -81,6 +81,14 @@ std::string DynamicChannelImpl::ToString() {
   return ss.str();
 }
 
+void DynamicChannelImpl::SetOutgoingConfigurationStatus(ConfigurationStatus status) {
+  outgoing_configuration_status_ = status;
+}
+
+void DynamicChannelImpl::SetIncomingConfigurationStatus(ConfigurationStatus status) {
+  incoming_configuration_status_ = status;
+}
+
 }  // namespace internal
 }  // namespace classic
 }  // namespace l2cap
index 8a6270a..1f293eb 100644 (file)
@@ -65,6 +65,19 @@ class DynamicChannelImpl {
     return psm_;
   }
 
+  enum class ConfigurationStatus { NOT_CONFIGURED, CONFIGURED };
+
+  virtual void SetOutgoingConfigurationStatus(ConfigurationStatus status);
+  virtual void SetIncomingConfigurationStatus(ConfigurationStatus status);
+
+  virtual ConfigurationStatus GetOutgoingConfigurationStatus() const {
+    return outgoing_configuration_status_;
+  }
+
+  virtual ConfigurationStatus GetIncomingConfigurationStatus() const {
+    return incoming_configuration_status_;
+  }
+
  private:
   const Psm psm_;
   const Cid cid_;
@@ -83,6 +96,8 @@ class DynamicChannelImpl {
   static constexpr size_t kChannelQueueSize = 10;
   common::BidiQueue<packet::PacketView<packet::kLittleEndian>, packet::BasePacketBuilder> channel_queue_{
       kChannelQueueSize};
+  ConfigurationStatus outgoing_configuration_status_ = ConfigurationStatus::NOT_CONFIGURED;
+  ConfigurationStatus incoming_configuration_status_ = ConfigurationStatus::NOT_CONFIGURED;
 
   DISALLOW_COPY_AND_ASSIGN(DynamicChannelImpl);
 };
index 8475bcc..7ba61a7 100644 (file)
@@ -147,9 +147,7 @@ void ClassicSignallingManager::OnConnectionRequest(SignalId signal_id, Psm psm,
   }
   send_connection_response(signal_id, remote_cid, new_channel->GetCid(), ConnectionResponseResult::SUCCESS,
                            ConnectionResponseStatus::NO_FURTHER_INFORMATION_AVAILABLE);
-  std::unique_ptr<DynamicChannel> channel = std::make_unique<DynamicChannel>(new_channel, handler_);
   SendConfigurationRequest(remote_cid, {});
-  dynamic_service_manager_->GetService(psm)->NotifyChannelCreation(std::move(channel));
 }
 
 void ClassicSignallingManager::OnConnectionResponse(SignalId signal_id, Cid remote_cid, Cid cid,
@@ -180,8 +178,6 @@ void ClassicSignallingManager::OnConnectionResponse(SignalId signal_id, Cid remo
     handle_send_next_command();
     return;
   }
-  std::unique_ptr<DynamicChannel> channel = std::make_unique<DynamicChannel>(new_channel, handler_);
-  dynamic_service_manager_->GetService(pending_psm)->NotifyChannelCreation(std::move(channel));
   SendConfigurationRequest(remote_cid, {});
   alarm_.Cancel();
   handle_send_next_command();
@@ -198,6 +194,12 @@ void ClassicSignallingManager::OnConfigurationRequest(SignalId signal_id, Cid ci
                                                        ConfigurationResponseResult::SUCCESS, {});
   enqueue_buffer_->Enqueue(std::move(response), handler_);
   handle_send_next_command();
+  channel->SetIncomingConfigurationStatus(DynamicChannelImpl::ConfigurationStatus::CONFIGURED);
+  if (channel->GetOutgoingConfigurationStatus() == DynamicChannelImpl::ConfigurationStatus::CONFIGURED) {
+    LOG_INFO();
+    std::unique_ptr<DynamicChannel> user_channel = std::make_unique<DynamicChannel>(channel, handler_);
+    dynamic_service_manager_->GetService(channel->GetPsm())->NotifyChannelCreation(std::move(user_channel));
+  }
 }
 
 void ClassicSignallingManager::OnConfigurationResponse(SignalId signal_id, Cid cid, Continuation is_continuation,
@@ -220,6 +222,12 @@ void ClassicSignallingManager::OnConfigurationResponse(SignalId signal_id, Cid c
   // TODO(cmanton) verify configuration parameters are satisfied
   // TODO(cmanton) Indicate channel is open if config params are agreed upon
   handle_send_next_command();
+  channel->SetOutgoingConfigurationStatus(DynamicChannelImpl::ConfigurationStatus::CONFIGURED);
+  if (channel->GetIncomingConfigurationStatus() == DynamicChannelImpl::ConfigurationStatus::CONFIGURED) {
+    std::unique_ptr<DynamicChannel> user_channel = std::make_unique<DynamicChannel>(channel, handler_);
+    dynamic_service_manager_->GetService(channel->GetPsm())->NotifyChannelCreation(std::move(user_channel));
+  }
+  alarm_.Cancel();
 }
 
 void ClassicSignallingManager::OnDisconnectionRequest(SignalId signal_id, Cid cid, Cid remote_cid) {
@@ -259,6 +267,7 @@ void ClassicSignallingManager::OnDisconnectionResponse(SignalId signal_id, Cid c
   channel->OnClosed(hci::ErrorCode::SUCCESS);
   link_->FreeDynamicChannel(cid);
   handle_send_next_command();
+  alarm_.Cancel();
 }
 
 void ClassicSignallingManager::OnEchoRequest(SignalId signal_id, const PacketView<kLittleEndian>& packet) {
@@ -283,6 +292,7 @@ void ClassicSignallingManager::OnEchoResponse(SignalId signal_id, const PacketVi
   }
   LOG_INFO("Echo response received");
   handle_send_next_command();
+  alarm_.Cancel();
 }
 
 void ClassicSignallingManager::OnInformationRequest(SignalId signal_id, InformationRequestInfoType type) {
@@ -323,6 +333,7 @@ void ClassicSignallingManager::OnInformationResponse(SignalId signal_id, const I
   }
   // TODO (hsz): Store the information response
   handle_send_next_command();
+  alarm_.Cancel();
 }
 
 void ClassicSignallingManager::on_incoming_packet() {