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

Commit af8b6185 authored by Dennis Cheng's avatar Dennis Cheng
Browse files

test_vendor_lib: Implement event loop with libbase

Adds event loop functionality by handling IO in the Watcher class,
HciTransport. Also fixes a bug where the vendor's file descriptor was
closed early and another where an object was mistakingly being passed
by value.

Bug: 21586676
Change-Id: I2ec30b68c0ede47bf1ad78ec13beee93d0f8ab9d
parent e51fbf95
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -355,6 +355,8 @@ class DualModeController {
  // 0x02 Inquiry Result with RSSI format or Extended Inquiry Result format.
  // 0x03-0xFF: Reserved.
  std::uint8_t inquiry_mode_;

  DISALLOW_COPY_AND_ASSIGN(DualModeController);
};

}  // namespace test_vendor_lib
+2 −0
Original line number Diff line number Diff line
@@ -62,6 +62,8 @@ class HciHandler {
  std::unordered_map<std::uint16_t,
                     std::function<void(const std::vector<std::uint8_t> args)> >
      commands_;

  DISALLOW_COPY_AND_ASSIGN(HciHandler);
};

}  // namespace test_vendor_lib
+19 −12
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ extern "C" {
#include <sys/epoll.h>
}  // extern "C"

#include "base/files/scoped_file.h"
#include "base/message_loop/message_loop.h"
#include "vendor_libs/test_vendor_lib/include/command_packet.h"
#include "vendor_libs/test_vendor_lib/include/event_packet.h"
@@ -40,12 +41,15 @@ class HciTransport : public base::MessageLoopForIO::Watcher {

  virtual ~HciTransport() = default;

  void CloseHciFd();

  int GetHciFd() const;

  int GetVendorFd() const;

  // Creates the underlying socketpair to be used as a communication channel
  // between the HCI and the vendor library/controller.
  // between the HCI and the vendor library/controller. Returns false if an
  // error occurs.
  bool SetUp();

  // Sets the callback that is run when command packets are received.
@@ -62,29 +66,32 @@ class HciTransport : public base::MessageLoopForIO::Watcher {

  void OnFileCanWriteWithoutBlocking(int fd) override;

  // Reads in a command packet and calls the HciHandler's command ready
  // callback, passing owernship of the command packet to the HciHandler.
  // Reads in a command packet and calls the command ready callback,
  // |command_handler_|, passing ownership of the command packet to the handler.
  void ReceiveReadyCommand() const;

  // Write queue for sending events to the HCI. Event packets are removed from
  // the queue and written when write-readiness is signalled by the message
  // loop.
  // TODO(dennischeng): Use std::unique_ptr here.
  std::queue<EventPacket*> outgoing_events_;
  std::queue<std::unique_ptr<EventPacket>> outgoing_events_;

  // Callback executed in ReceiveReadyCommand() to pass the incoming command
  // over to the HciHandler for further processing.
  // over to the handler for further processing.
  std::function<void(std::unique_ptr<CommandPacket>)> command_handler_;

  // For performing packet-based IO.
  PacketStream packet_stream_;

  // The two ends of the socket pair used to communicate with the HCI.
  // |socketpair_fds_[0]| is the end that is handed back to the HCI in
  // bt_vendor.cc. It is also closed in bt_vendor.cc by the HCI.
  // |socketpair_fds_[1]| is the vendor end, used to receive and send data in
  // the vendor library and controller. It is closed by |packet_stream_|.
  int socketpair_fds_[2];
  // The two ends of the socketpair. |hci_fd_| is handed back to the HCI in
  // bt_vendor.cc and |vendor_fd_| is used by |packet_stream_| to receive/send
  // data from/to the HCI. Both file descriptors are owned and managed by the
  // transport object, although |hci_fd_| can be closed by the HCI in
  // TestVendorOp().
  std::unique_ptr<base::ScopedFD> hci_fd_;

  std::unique_ptr<base::ScopedFD> vendor_fd_;

  DISALLOW_COPY_AND_ASSIGN(HciTransport);
};

}  // namespace test_vendor_lib
+3 −3
Original line number Diff line number Diff line
@@ -25,9 +25,9 @@ extern "C" {

namespace test_vendor_lib {

// Abstract base class that manages a contiguous block of data and is
// subclassed to provide type-specifc accessors on said data. Manages the data's
// memory and guarantees the data's persistence for IO operations.
// Abstract base class that is subclassed to provide type-specifc accessors on
// data. Manages said data's memory and guarantees the data's persistence for IO
// operations.
class Packet {
 public:
  virtual ~Packet() = default;
+5 −13
Original line number Diff line number Diff line
@@ -34,27 +34,20 @@ class PacketStream {
  // before use.
  PacketStream();

  // Closes |fd_|. Careful attention must be paid to when PacketStream objects
  // are destructed because other objects may rely on the PacketStream's
  // file descriptor.
  virtual ~PacketStream();
  virtual ~PacketStream() = default;

  // Reads a command packet and returns the packet back to the caller, along
  // with the responsibility of managing the packet's memory.
  // with the responsibility of managing the packet.
  std::unique_ptr<CommandPacket> ReceiveCommand() const;

  // Reads and interprets a single octet as a packet type octet. Validates the
  // type octet for correctness.
  serial_data_type_t ReceivePacketType() const;

  // Sends an event to the HCI. The memory management and ownership of the event
  // is left with the caller.
  // Sends an event to the HCI. The ownership of the event is left with the
  // caller.
  bool SendEvent(const EventPacket& event) const;

  // Sets the file descriptor used in reading and writing. The PacketStream
  // takes ownership of the descriptor at |fd| and closes it during destruction.
  // This (as opposed to initializing fd_ in a constructor) helps prevent
  // premature closing of the descriptor.
  void SetFd(int fd);

 private:
@@ -72,8 +65,7 @@ class PacketStream {
  bool SendAll(const std::vector<std::uint8_t>& source,
               size_t num_octets_to_send) const;

  // File descriptor to read from and write to. This is the descriptor given to
  // the HCI from the HciTransport.
  // PacketStream does not take ownership of the file descriptor it uses.
  int fd_;
};

Loading