Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f0b905fb authored by Hansong Zhang's avatar Hansong Zhang
Browse files

L2CAP: Notify DynamicChannel open after configuration is done

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
parent 9f111f84
Loading
Loading
Loading
Loading
+7 −5
Original line number Diff line number Diff line
@@ -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

+8 −0
Original line number Diff line number Diff line
@@ -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
+15 −0
Original line number Diff line number Diff line
@@ -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);
};
+15 −4
Original line number Diff line number Diff line
@@ -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() {