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

Commit 0e49715b authored by Hansong Zhang's avatar Hansong Zhang
Browse files

Rootcanal HCI HAL: Set read from socket blocking

In HciSocketDevice::SendHci, rootcanal first writes to HCI socket one
byte HCI packet type first, then HCI packet body. When the stack
receives the first byte, it tries to read the entire packet, but
sometimes the rest of packet was not delivered yet, so the stack will
crash. Instead, the stack should be blocked until all bytes are read,
with a 3 second timeout when rootcanal can't deliver all bytes to stack.

Test: try cert/run_cert.sh multiple times
Bug: 131625008
Change-Id: I99df53c658717a5c931ebc075eb75df447e10332
parent b907d52e
Loading
Loading
Loading
Loading
+18 −7
Original line number Diff line number Diff line
@@ -17,10 +17,11 @@
#include "hal/hci_hal_host_rootcanal.h"
#include "hal/hci_hal.h"

#include <csignal>
#include <fcntl.h>
#include <netdb.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include <csignal>
#include <mutex>
#include <queue>

@@ -71,8 +72,11 @@ int ConnectToRootCanal(const std::string& server, int port) {
    return INVALID_FD;
  }

  int flags = fcntl(socket_fd, F_GETFL, NULL);
  int ret = fcntl(socket_fd, F_SETFL, flags | O_NONBLOCK);
  timeval socket_timeout{
      .tv_sec = 3,
      .tv_usec = 0,
  };
  int ret = setsockopt(socket_fd, SOL_SOCKET, SO_RCVTIMEO, &socket_timeout, sizeof(socket_timeout));
  if (ret == -1) {
    LOG_ERROR("can't control socket fd: %s", strerror(errno));
    return INVALID_FD;
@@ -199,12 +203,14 @@ class HciHalHostRootcanal : public HciHal {

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

      uint8_t hci_evt_parameter_total_length = buf[2];
      ssize_t payload_size;
      RUN_NO_INTR(payload_size =
                      recv(sock_fd_, buf + kH4HeaderSize + kHciEvtHeaderSize, hci_evt_parameter_total_length, 0));
      ASSERT_LOG(payload_size != -1, "Can't receive from socket: %s", strerror(errno));
      ASSERT_LOG(payload_size == hci_evt_parameter_total_length,
                 "malformed HCI event total parameter size received: %zu != %d", payload_size,
                 hci_evt_parameter_total_length);
@@ -217,12 +223,14 @@ class HciHalHostRootcanal : public HciHal {
    }

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

      uint16_t hci_acl_data_total_length = buf[4] * 256 + buf[3];
      int payload_size;
      RUN_NO_INTR(payload_size = recv(sock_fd_, buf + kH4HeaderSize + kHciAclHeaderSize, hci_acl_data_total_length, 0));
      ASSERT_LOG(payload_size != -1, "Can't receive from socket: %s", strerror(errno));
      ASSERT_LOG(payload_size == hci_acl_data_total_length, "malformed ACL length received: %d != %d", payload_size,
                 hci_acl_data_total_length);
      ASSERT_LOG(hci_acl_data_total_length <= kBufSize - kH4HeaderSize - kHciAclHeaderSize, "packet too long");
@@ -235,11 +243,14 @@ class HciHalHostRootcanal : public HciHal {
    }

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

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

      HciPacket receivedHciPacket;