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

Commit 2d22ba39 authored by Myles Watson's avatar Myles Watson
Browse files

Only fragment and reassemble ISO

Bug: 283254594
Test: presubmit
Change-Id: I6c70577733d8ff09d471f137644bdf49b4fbf4ac
parent 677500cc
Loading
Loading
Loading
Loading
+2 −9
Original line number Diff line number Diff line
@@ -23,7 +23,6 @@
#include "osi/include/allocator.h"
#include "stack/include/bt_hdr.h"

typedef void (*transmit_finished_cb)(BT_HDR* packet, bool all_fragments_sent);
typedef void (*packet_reassembled_cb)(BT_HDR* packet);
typedef void (*packet_fragmented_cb)(BT_HDR* packet,
                                     bool send_transmit_finished);
@@ -34,10 +33,6 @@ typedef struct {

  // Called for every completely reassembled packet.
  packet_reassembled_cb reassembled;

  // Called when the fragmenter finishes sending all requested fragments,
  // but the packet has not been entirely sent.
  transmit_finished_cb transmit_finished;
} packet_fragmenter_callbacks_t;

typedef struct packet_fragmenter_t {
@@ -51,10 +46,8 @@ typedef struct packet_fragmenter_t {
  // callback.
  void (*fragment_and_dispatch)(BT_HDR* packet);
  // If |packet| is a complete packet, forwards to the reassembled callback.
  // Otherwise
  // holds onto it until all fragments arrive, at which point the reassembled
  // callback is called
  // with the reassembled data.
  // Otherwise holds onto it until all fragments arrive, at which point the
  // reassembled callback is called with the reassembled data.
  void (*reassemble_and_dispatch)(BT_HDR* packet);
} packet_fragmenter_t;

+6 −28
Original line number Diff line number Diff line
@@ -30,7 +30,6 @@
#include "device/include/controller.h"
#include "hci/include/buffer_allocator.h"
#include "osi/include/log.h"
#include "osi/include/osi.h"
#include "stack/include/bt_hdr.h"

#define HCI_ISO_BF_FIRST_FRAGMENTED_PACKET (0)
@@ -81,35 +80,21 @@ static const allocator_t* buffer_allocator;
static const controller_t* controller;
static const packet_fragmenter_callbacks_t* callbacks;

static std::unordered_map<uint16_t /* handle */, BT_HDR*> partial_packets;
static std::unordered_map<uint16_t /* handle */, BT_HDR*> partial_iso_packets;

static void init(const packet_fragmenter_callbacks_t* result_callbacks) {
  callbacks = result_callbacks;
}

static void cleanup() {
  partial_packets.clear();
  partial_iso_packets.clear();
}

static void fragment_and_dispatch_iso(BT_HDR* packet);
static void cleanup() { partial_iso_packets.clear(); }

static void fragment_and_dispatch(BT_HDR* packet) {
  CHECK(packet != NULL);

  uint16_t event = packet->event & MSG_EVT_MASK;

  if (event == MSG_HC_TO_STACK_HCI_SCO) {
    callbacks->fragmented(packet, true);
  } else if (event == MSG_STACK_TO_HC_HCI_ISO) {
    fragment_and_dispatch_iso(packet);
  } else {
    callbacks->fragmented(packet, true);
  }
}
  CHECK(event == MSG_STACK_TO_HC_HCI_ISO);

static void fragment_and_dispatch_iso(BT_HDR* packet) {
  uint8_t* stream = packet->data + packet->offset;
  uint16_t max_data_size = controller->get_iso_data_size();
  uint16_t max_packet_size = max_data_size + HCI_ISO_PREAMBLE_SIZE;
@@ -155,7 +140,7 @@ static void fragment_and_dispatch_iso(BT_HDR* packet) {
  callbacks->fragmented(packet, true);
}

static void reassemble_and_dispatch_iso(UNUSED_ATTR BT_HDR* packet) {
static void reassemble_and_dispatch(UNUSED_ATTR BT_HDR* packet) {
  uint8_t* stream = packet->data;
  uint16_t handle;
  uint16_t iso_length;
@@ -163,6 +148,9 @@ static void reassemble_and_dispatch_iso(UNUSED_ATTR BT_HDR* packet) {
  BT_HDR* partial_packet;
  uint16_t iso_full_len;

  uint16_t event = packet->event & MSG_EVT_MASK;
  CHECK(event == MSG_HC_TO_STACK_HCI_ISO);

  STREAM_TO_UINT16(handle, stream);
  STREAM_TO_UINT16(iso_length, stream);
  // last 2 bits is RFU
@@ -336,16 +324,6 @@ static void reassemble_and_dispatch_iso(UNUSED_ATTR BT_HDR* packet) {
  }
}

static void reassemble_and_dispatch(BT_HDR* packet) {
  if ((packet->event & MSG_EVT_MASK) == MSG_HC_TO_STACK_HCI_SCO) {
    callbacks->reassembled(packet);
  } else if ((packet->event & MSG_EVT_MASK) == MSG_HC_TO_STACK_HCI_ISO) {
    reassemble_and_dispatch_iso(packet);
  } else {
    callbacks->reassembled(packet);
  }
}

static const packet_fragmenter_t interface = {init, cleanup,

                                              fragment_and_dispatch,
+0 −27
Original line number Diff line number Diff line
@@ -389,12 +389,6 @@ DURING(non_acl_passthrough_reassembly) AT_CALL(0) {
UNEXPECTED_CALL;
}

STUB_FUNCTION(void, transmit_finished_callback,
              (UNUSED_ATTR BT_HDR * packet,
               UNUSED_ATTR bool sent_all_fragments))
UNEXPECTED_CALL;
}

STUB_FUNCTION(uint16_t, get_acl_data_size_classic, (void))
DURING(no_fragmentation, non_acl_passthrough_fragmentation, no_reassembly)
return 42;
@@ -424,7 +418,6 @@ return 0;
static void reset_for(TEST_MODES_T next) {
  RESET_CALL_COUNT(fragmented_callback);
  RESET_CALL_COUNT(reassembled_callback);
  RESET_CALL_COUNT(transmit_finished_callback);
  RESET_CALL_COUNT(get_acl_data_size_classic);
  RESET_CALL_COUNT(get_acl_data_size_ble);
  RESET_CALL_COUNT(get_iso_data_size);
@@ -443,7 +436,6 @@ class PacketFragmenterTest : public AllocationTestHarness {

    callbacks.fragmented = fragmented_callback;
    callbacks.reassembled = reassembled_callback;
    callbacks.transmit_finished = transmit_finished_callback;
    controller.get_acl_data_size_classic = get_acl_data_size_classic;
    controller.get_acl_data_size_ble = get_acl_data_size_ble;
    controller.get_iso_data_size = get_iso_data_size;
@@ -461,25 +453,6 @@ class PacketFragmenterTest : public AllocationTestHarness {
  packet_fragmenter_callbacks_t callbacks;
};

TEST_F(PacketFragmenterTest, test_non_acl_passthrough_fragmentation) {
  reset_for(non_acl_passthrough_fragmentation);
  BT_HDR* packet = manufacture_packet_for_fragmentation(MSG_STACK_TO_HC_HCI_CMD,
                                                        sample_data);
  fragmenter->fragment_and_dispatch(packet);

  EXPECT_EQ(strlen(sample_data), data_size_sum);
  EXPECT_CALL_COUNT(fragmented_callback, 1);
}

TEST_F(PacketFragmenterTest, test_non_acl_passthrough_reasseembly) {
  reset_for(non_acl_passthrough_reassembly);
  manufacture_packet_and_then_reassemble(MSG_HC_TO_STACK_HCI_EVT, 42,
                                         sample_data);

  EXPECT_EQ(strlen(sample_data), data_size_sum);
  EXPECT_CALL_COUNT(reassembled_callback, 1);
}

TEST_F(PacketFragmenterTest, test_iso_fragment_necessary) {
  reset_for(iso_fragmentation);
  iso_has_ts = true;
+3 −14
Original line number Diff line number Diff line
@@ -588,25 +588,14 @@ static void transmit_fragment(BT_HDR* packet, bool send_transmit_finished) {
  }
}
static void dispatch_reassembled(BT_HDR* packet) {
  // Events should already have been dispatched before this point
  CHECK((packet->event & MSG_EVT_MASK) != MSG_HC_TO_STACK_HCI_EVT);
  // Only ISO should be handled here
  CHECK((packet->event & MSG_EVT_MASK) == MSG_HC_TO_STACK_HCI_ISO);
  CHECK(!send_data_upwards.is_null());
  send_data_upwards.Run(FROM_HERE, packet);
}
static void fragmenter_transmit_finished(BT_HDR* packet,
                                         bool all_fragments_sent) {
  if (all_fragments_sent) {
    osi_free(packet);
  } else {
    // This is kind of a weird case, since we're dispatching a partially sent
    // packet up to a higher layer.
    // TODO(zachoverflow): rework upper layer so this isn't necessary.
    send_data_upwards.Run(FROM_HERE, packet);
  }
}

static const packet_fragmenter_callbacks_t packet_fragmenter_callbacks = {
    transmit_fragment, dispatch_reassembled, fragmenter_transmit_finished};
    transmit_fragment, dispatch_reassembled};

static void transmit_downward(uint16_t type, void* raw_data) {
  if (type == BT_EVT_TO_LM_HCI_SCO) {