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

Commit 636e846f authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "HAL: Add ISO packet callbacks"

parents 301c51df 2642f360
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -93,6 +93,13 @@ class HciHalFacadeService : public HciHalFacade::Service, public ::bluetooth::ha
    return pending_sco_events_.RunLoop(context, writer);
  };

  ::grpc::Status FetchHciIso(
      ::grpc::ServerContext* context,
      const ::google::protobuf::Empty* request,
      ::grpc::ServerWriter<HciIsoPacket>* writer) override {
    return pending_iso_events_.RunLoop(context, writer);
  };

  void hciEventReceived(bluetooth::hal::HciPacket event) override {
    {
      HciEventPacket response;
@@ -115,6 +122,12 @@ class HciHalFacadeService : public HciHalFacade::Service, public ::bluetooth::ha
    pending_sco_events_.OnIncomingEvent(std::move(response));
  }

  void isoDataReceived(bluetooth::hal::HciPacket data) override {
    HciIsoPacket response;
    response.set_payload(std::string(data.begin(), data.end()));
    pending_iso_events_.OnIncomingEvent(std::move(response));
  }

 private:
  HciHal* hal_;
  bool can_send_hci_command_ = true;
@@ -123,6 +136,7 @@ class HciHalFacadeService : public HciHalFacade::Service, public ::bluetooth::ha
  ::bluetooth::grpc::GrpcEventQueue<HciEventPacket> pending_hci_events_{"FetchHciEvent"};
  ::bluetooth::grpc::GrpcEventQueue<HciAclPacket> pending_acl_events_{"FetchHciAcl"};
  ::bluetooth::grpc::GrpcEventQueue<HciScoPacket> pending_sco_events_{"FetchHciSco"};
  ::bluetooth::grpc::GrpcEventQueue<HciIsoPacket> pending_iso_events_{"FetchHciIso"};
};

void HciHalFacadeModule::ListDependencies(ModuleList* list) {
+6 −0
Original line number Diff line number Diff line
@@ -8,10 +8,12 @@ service HciHalFacade {
  rpc SendHciCommand(HciCommandPacket) returns (google.protobuf.Empty) {}
  rpc SendHciAcl(HciAclPacket) returns (google.protobuf.Empty) {}
  rpc SendHciSco(HciScoPacket) returns (google.protobuf.Empty) {}
  rpc SendHciIso(HciIsoPacket) returns (google.protobuf.Empty) {}

  rpc FetchHciEvent(google.protobuf.Empty) returns (stream HciEventPacket) {}
  rpc FetchHciAcl(google.protobuf.Empty) returns (stream HciAclPacket) {}
  rpc FetchHciSco(google.protobuf.Empty) returns (stream HciScoPacket) {}
  rpc FetchHciIso(google.protobuf.Empty) returns (stream HciIsoPacket) {}
}

message HciEventPacket {
@@ -29,3 +31,7 @@ message HciAclPacket {
message HciScoPacket {
  bytes payload = 1;
}

message HciIsoPacket {
  bytes payload = 1;
}
+6 −2
Original line number Diff line number Diff line
@@ -40,13 +40,17 @@ class HciHalCallbacks {
  // @param event is the HCI event to be sent to the Bluetooth stack
  virtual void hciEventReceived(HciPacket event) = 0;

  // Send an ACL data packet form the controller to the host
  // Send an ACL data packet from the controller to the host
  // @param data the ACL HCI packet to be passed to the host stack
  virtual void aclDataReceived(HciPacket data) = 0;

  // Send a SCO data packet form the controller to the host
  // Send a SCO data packet from the controller to the host
  // @param data the SCO HCI packet to be passed to the host stack
  virtual void scoDataReceived(HciPacket data) = 0;

  // Send an ISO data packet from the controller to the host
  // @param data the ISO HCI packet to be passed to the host stack
  virtual void isoDataReceived(HciPacket data) = 0;
};

// Mirrors hardware/interfaces/bluetooth/1.0/IBluetoothHci.hal in Android
+26 −0
Original line number Diff line number Diff line
@@ -39,11 +39,13 @@ constexpr uint8_t kH4Command = 0x01;
constexpr uint8_t kH4Acl = 0x02;
constexpr uint8_t kH4Sco = 0x03;
constexpr uint8_t kH4Event = 0x04;
constexpr uint8_t kH4Iso = 0x05;

constexpr uint8_t kH4HeaderSize = 1;
constexpr uint8_t kHciAclHeaderSize = 4;
constexpr uint8_t kHciScoHeaderSize = 3;
constexpr uint8_t kHciEvtHeaderSize = 2;
constexpr uint8_t kHciIsoHeaderSize = 4;
constexpr int kBufSize = 1024 + 4 + 1;  // DeviceProperties::acl_data_packet_size_ + ACL header + H4 header

int ConnectToRootCanal(const std::string& server, int port) {
@@ -317,6 +319,30 @@ class HciHalHostRootcanal : public HciHal {
        incoming_packet_callback_->scoDataReceived(receivedHciPacket);
      }
    }

    if (buf[0] == kH4Iso) {
      RUN_NO_INTR(received_size = recv(sock_fd_, buf + kH4HeaderSize, kHciIsoHeaderSize, 0));
      ASSERT_LOG(received_size != -1, "Can't receive from socket: %s", strerror(errno));
      ASSERT_LOG(received_size == kHciIsoHeaderSize, "malformed ISO header received");

      uint8_t hci_iso_data_total_length = buf[3];
      int payload_size;
      RUN_NO_INTR(payload_size = recv(sock_fd_, buf + kH4HeaderSize + kHciIsoHeaderSize, hci_iso_data_total_length, 0));
      ASSERT_LOG(payload_size != -1, "Can't receive from socket: %s", strerror(errno));
      ASSERT_LOG(payload_size == hci_iso_data_total_length, "malformed ISO packet received: size mismatch");

      HciPacket receivedHciPacket;
      receivedHciPacket.assign(buf + kH4HeaderSize, buf + kH4HeaderSize + kHciIsoHeaderSize + payload_size);
      btsnoop_logger_->Capture(receivedHciPacket, SnoopLogger::Direction::INCOMING, SnoopLogger::PacketType::ISO);
      {
        std::lock_guard<std::mutex> incoming_packet_callback_lock(incoming_packet_callback_mutex_);
        if (incoming_packet_callback_ == nullptr) {
          LOG_INFO("Dropping a ISO packet after processing");
          return;
        }
        incoming_packet_callback_->isoDataReceived(receivedHciPacket);
      }
    }
    memset(buf, 0, kBufSize);
  }
};
+24 −0
Original line number Diff line number Diff line
@@ -50,6 +50,7 @@ constexpr uint8_t kH4Command = 0x01;
constexpr uint8_t kH4Acl = 0x02;
constexpr uint8_t kH4Sco = 0x03;
constexpr uint8_t kH4Event = 0x04;
constexpr uint8_t kH4Iso = 0x05;

using H4Packet = std::vector<uint8_t>;

@@ -68,6 +69,10 @@ class TestHciHalCallbacks : public HciHalCallbacks {
  void scoDataReceived(HciPacket packet) override {
    incoming_packets_queue_.emplace(kH4Sco, packet);
  }

  void isoDataReceived(HciPacket packet) override {
    incoming_packets_queue_.emplace(kH4Iso, packet);
  }
};

// An implementation of rootcanal desktop HCI server which listens on localhost:kListeningPort
@@ -223,6 +228,15 @@ HciPacket make_sample_h4_sco_pkt(uint8_t payload_size) {
  return pkt;
}

HciPacket make_sample_h4_iso_pkt(uint8_t payload_size) {
  HciPacket pkt;
  pkt.assign(1 + 4 + payload_size, 0x01);
  pkt[0] = kH4Iso;
  pkt[3] = payload_size;
  pkt[4] = 0;
  return pkt;
}

size_t read_with_retry(int socket, uint8_t* data, size_t length) {
  size_t bytes_read = 0;
  ssize_t bytes_read_current = 0;
@@ -265,6 +279,16 @@ TEST_F(HciHalRootcanalTest, receive_hci_sco) {
  check_packet_equal(packet, incoming_packet);
}

TEST_F(HciHalRootcanalTest, receive_hci_iso) {
  H4Packet incoming_packet = make_sample_h4_iso_pkt(3);
  write(fake_server_socket_, incoming_packet.data(), incoming_packet.size());
  while (incoming_packets_queue_.size() != 1) {
  }
  auto packet = incoming_packets_queue_.front();
  incoming_packets_queue_.pop();
  check_packet_equal(packet, incoming_packet);
}

TEST_F(HciHalRootcanalTest, receive_two_hci_evts) {
  H4Packet incoming_packet = make_sample_h4_evt_pkt(3);
  H4Packet incoming_packet2 = make_sample_h4_evt_pkt(5);
Loading