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

Commit 66bc02a2 authored by Hansong Zhang's avatar Hansong Zhang
Browse files

HCI_SCO: Add helpers to make and parse packet

It's not wired yet, but we will use these helpers later.

Tag: #refactor
Bug: 195344796
Test: net_test_stack_btm
Change-Id: I32d48547d2afc241bf6f6b44ae1f3278cc94986a
parent a382f969
Loading
Loading
Loading
Loading
+36 −0
Original line number Diff line number Diff line
@@ -173,11 +173,47 @@ static void btm_esco_conn_rsp(uint16_t sco_inx, uint8_t hci_status,
 *
 ******************************************************************************/
void btm_route_sco_data(BT_HDR* p_msg) {
  if (p_msg->len < 3) {
    LOG_ERROR("Received incomplete SCO header");
    osi_free(p_msg);
    return;
  }
  uint8_t* payload = p_msg->data;
  uint16_t handle_with_flags = 0;
  uint8_t length = 0;
  STREAM_TO_UINT16(handle_with_flags, payload);
  STREAM_TO_UINT8(length, payload);
  if (p_msg->len != length + 3) {
    LOG_ERROR("Received invalid SCO data of size: %hhu, dropping", length);
    osi_free(p_msg);
    return;
  }
  LOG_INFO("Received SCO packet from HCI. Dropping it since no handler so far");
  // TODO(b/195344796): Implement the SCO over HCI data path
  // std::vector<uint8_t> data(payload, payload + length);
  osi_free(p_msg);
}

void btm_send_sco_packet(std::vector<uint8_t> data, uint16_t sco_handle) {
  BT_HDR* packet = btm_sco_make_packet(std::move(data), sco_handle);
  bte_main_hci_send(packet, BT_EVT_TO_LM_HCI_SCO);
}

// Build a SCO packet from uint8
BT_HDR* btm_sco_make_packet(std::vector<uint8_t> data, uint16_t sco_handle) {
  ASSERT_LOG(data.size() <= BTM_SCO_DATA_SIZE_MAX, "Invalid SCO data size: %zu",
             data.size());
  BT_HDR* p_buf = (BT_HDR*)osi_calloc(BT_SMALL_BUFFER_SIZE);
  p_buf->event = BT_EVT_TO_LM_HCI_SCO;
  // SCO header size is 3 per Core 5.2 Vol 4 Part E 5.4.3 figure 5.3
  p_buf->len = data.size() + 3;
  uint8_t* payload = p_buf->data;
  UINT16_TO_STREAM(payload, sco_handle);
  UINT8_TO_STREAM(payload, data.size());
  ARRAY_TO_STREAM(payload, data.data(), static_cast<int>(data.size()));
  return p_buf;
}

/*******************************************************************************
 *
 * Function         btm_send_connect_request
+6 −0
Original line number Diff line number Diff line
@@ -132,3 +132,9 @@ typedef struct {

extern void btm_sco_chk_pend_rolechange(uint16_t hci_handle);
extern void btm_sco_disc_chk_pend_for_modechange(uint16_t hci_handle);

// Visible for test only
BT_HDR* btm_sco_make_packet(std::vector<uint8_t> data, uint16_t sco_handle);

// Send a SCO packet
void btm_send_sco_packet(std::vector<uint8_t> data, uint16_t sco_handle);
+17 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <map>
#include <vector>

#include "btif/include/btif_hh.h"
#include "hci/include/hci_layer.h"
@@ -26,6 +27,7 @@
#include "internal_include/stack_config.h"
#include "osi/include/osi.h"
#include "stack/btm/btm_int_types.h"
#include "stack/btm/btm_sco.h"
#include "stack/include/acl_api.h"
#include "stack/include/acl_hci_link_interface.h"
#include "stack/include/btm_client_interface.h"
@@ -181,4 +183,19 @@ TEST_F(StackBtmTest, change_packet_type) {
  get_btm_client_interface().lifecycle.btm_free();
}

TEST(ScoTest, make_sco_packet) {
  std::vector<uint8_t> data = {10, 20, 30};
  uint16_t handle = 0xab;
  BT_HDR* p = btm_sco_make_packet(data, handle);
  ASSERT_EQ(p->event, BT_EVT_TO_LM_HCI_SCO);
  ASSERT_EQ(p->len, 3 + data.size());
  ASSERT_EQ(p->data[0], 0xab);
  ASSERT_EQ(p->data[1], 0);
  ASSERT_EQ(p->data[2], 3);
  ASSERT_EQ(p->data[3], 10);
  ASSERT_EQ(p->data[4], 20);
  ASSERT_EQ(p->data[5], 30);
  osi_free(p);
}

}  // namespace