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

Commit fed51de5 authored by Erwin Jansen's avatar Erwin Jansen Committed by Myles Watson
Browse files

Rootcanal: Clean up disconnected socket devices.

Link layer devices where not properly garbage collected, resulting in
lingering connections that would keep receiving timer ticks. We now add
support for registering close callbacks on a Device object, and we add
support for a Close method on a device.

Device can implement Close to properly close themselves and notify the
listener of closing. The link layer socket can now clean it self up
properly.

Bug: 198300862
Test: cert/run
Change-Id: Ibff03eea836359770937b4ffe57c79bad3682a8f
parent 93c9c87f
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -74,6 +74,16 @@ void Device::SendLinkLayerPacket(model::packets::LinkLayerPacketView to_send,
  }
}

void Device::Close()  {
  if (close_callback_) {
    close_callback_();
  }
}

void Device::RegisterCloseCallback(std::function<void()> close_callback) {
   close_callback_ = close_callback;
}

void Device::SetAddress(Address) {
  LOG_INFO("%s does not implement %s", GetTypeString().c_str(), __func__);
}
+8 −0
Original line number Diff line number Diff line
@@ -85,6 +85,11 @@ class Device {
  virtual void SendLinkLayerPacket(model::packets::LinkLayerPacketView packet,
                                   Phy::Type phy_type);


  virtual void Close();

  void RegisterCloseCallback(std::function<void()>);

 protected:
  std::vector<std::shared_ptr<PhyLayer>> phy_layers_;

@@ -98,6 +103,9 @@ class Device {
  std::chrono::milliseconds advertising_interval_ms_{};

  DeviceProperties properties_;

  // Callback to be invoked when this device is closed.
  std::function<void()> close_callback_;
};

}  // namespace test_vendor_lib
+6 −5
Original line number Diff line number Diff line
@@ -98,7 +98,7 @@ HciSocketDevice::HciSocketDevice(std::shared_ptr<AsyncDataChannel> socket)
      },
      [this]() {
        LOG_INFO("HCI socket device disconnected");
        close_callback_();
        Close();
      });

  RegisterEventChannel([this](std::shared_ptr<std::vector<uint8_t>> packet) {
@@ -132,11 +132,12 @@ void HciSocketDevice::SendHci(
  h4_.Send(type, packet->data(), packet->size());
}

void HciSocketDevice::RegisterCloseCallback(
    std::function<void()> close_callback) {
  if (socket_ && socket_->Connected()) {
    close_callback_ = close_callback;
void HciSocketDevice::Close()  {
  if (socket_) {
    socket_->Close();
  }
  Device::Close();
}


}  // namespace test_vendor_lib
+3 −5
Original line number Diff line number Diff line
@@ -41,16 +41,16 @@ class HciSocketDevice : public DualModeController {
    return std::make_shared<HciSocketDevice>(socket);
  }

  virtual std::string GetTypeString() const override {
  std::string GetTypeString() const override {
    return "hci_socket_device";
  }

  virtual void TimerTick() override;
  void TimerTick() override;

  void SendHci(PacketType packet_type,
               const std::shared_ptr<std::vector<uint8_t>> packet);

  void RegisterCloseCallback(std::function<void()>);
  void Close() override;

 private:
  std::shared_ptr<AsyncDataChannel> socket_;
@@ -61,8 +61,6 @@ class HciSocketDevice : public DualModeController {
                              [](const std::vector<uint8_t>&) {},
                              [](const std::vector<uint8_t>&) {},
                              [] {}};

  std::function<void()> close_callback_;
};

}  // namespace test_vendor_lib
+20 −2
Original line number Diff line number Diff line
@@ -41,9 +41,14 @@ void LinkLayerSocketDevice::TimerTick() {
    ssize_t bytes_received =
        socket_->Recv(size_bytes_->data() + offset_, kSizeBytes);
    if (bytes_received <= 0) {
      if (errno == EAGAIN || errno == EWOULDBLOCK) {
        // Nothing available yet.
        // LOG_DEBUG("Nothing available yet...");
        return;
      }
      LOG_INFO("Closing socket, received: %zd, %s", bytes_received,
               strerror(errno));
      socket_->Close();
      Close();
      return;
    }
    if (bytes_received < bytes_left_) {
@@ -61,9 +66,14 @@ void LinkLayerSocketDevice::TimerTick() {
  ssize_t bytes_received =
      socket_->Recv(received_->data() + offset_, bytes_left_);
  if (bytes_received <= 0) {
    if (errno == EAGAIN || errno == EWOULDBLOCK) {
        // Nothing available yet.
        // LOG_DEBUG("Nothing available yet...");
        return;
      }
    LOG_INFO("Closing socket, received: %zd, %s", bytes_received,
             strerror(errno));
    socket_->Close();
    Close();
    return;
  }
  if (bytes_received < bytes_left_) {
@@ -81,6 +91,14 @@ void LinkLayerSocketDevice::TimerTick() {
  SendLinkLayerPacket(packet, phy_type_);
}

void LinkLayerSocketDevice::Close()
{
  if (socket_) {
    socket_->Close();
  }
  Device::Close();
}

void LinkLayerSocketDevice::IncomingPacket(
    model::packets::LinkLayerPacketView packet) {
  auto size_packet = bluetooth::packet::RawBuilder();
Loading