pw_bluetooth#

Host-layer Bluetooth Low Energy APIs and utilities

Unstable C++

The pw_bluetooth module contains APIs and utilities for the host layer of Bluetooth Low Energy.

Host API#

Attention

This module is still under construction, the API is not yet stable.

The headers in public/pw_bluetooth constitute generic interfaces and types for a Bluetooth Host API. Currently, only Low Energy APIs exist.

API reference#

Moved: pw_bluetooth

Module Configuration Options#

The following configurations can be adjusted via compile-time configuration of this module, see the module documentation for more details.

PW_BLUETOOTH_DESCRIPTOR_VEC_SIZE#

Controls the size of Vector<Descriptor> in the above APIs.

Emboss Packet Definitions#

pw_bluetooth contains Emboss packet definitions. So far, some packets and enums from the following protocols are defined:

  • HCI

  • L2CAP

  • H4

Usage#

  1. Add Emboss to your project as described in Emboss.

  1. Add the Emboss target you require to your build target’s dependency list - for example, @pigweed//pw_bluetooth:emboss_hci_group for HCI packets.

  1. Add the Emboss target you require to your build target’s dependency list - for example, $dir_pw_bluetooth/emboss_hci_group for HCI packets.

  1. Add the Emboss target you require to your build target’s dependency list - for example, pw_bluetooth.emboss_hci_group for HCI packets.

  1. Include the generated header files you require in your source files.

#include "pw_bluetooth/hci_commands.emb.h"
#include "pw_bluetooth/hci_android.emb.h"
  1. Construct an Emboss view over a buffer as described in the Emboss User Guide.

  std::array<uint8_t, 4> buffer = {0x00, 0x01, 0x02, 0x03};
  auto view = emboss::MakeTestCommandPacketView(&buffer);
  EXPECT_TRUE(view.IsComplete());
  EXPECT_EQ(view.payload().Read(), 0x03);

Note

When you first add generated headers, clangd may complain that the generated header files do not exist. You need to build your project to resolve this. Similarly, you need to rebuild in order for .emb file updates to be reflected in the generated headers.

Contributing#

Emboss .emb files can be edited to add additional packets and enums.

Emboss files should be formatted by running the following from the Pigweed root.

(export EMBOSS_PATH="environment/packages/emboss" &&
    export PYTHONPATH+=":${EMBOSS_PATH}" &&
    python3 "${EMBOSS_PATH}/compiler/front_end/format.py" pw_bluetooth/public/pw_bluetooth/*.emb)

If adding files, be sure to update the GN, Bazel, and CMake build rules. Presubmit runs the emboss_test.cc test on all three.

Snoop Log#

pw_bluetooth contains an HCI snoop log implementation for recording Rx/Tx HCI traffic.

The snoop log is easy to integrate into your H4 Uart driver.

  • Add pw::bluetooth::SnoopBuffer to your H4 Uart class.

  • Add a call to pw::bluetooth::SnoopBuffer::AddRx() in your H4Packet Receive function.

  • Add a call to pw::bluetooth::SnoopBuffer::AddTx() in your H4Packet Transmit function.

  • Dump the snoop log via pw::bluetooth::Snoop::Dump()

  • Dump the snoop log to the logger via pw::bluetooth::Snoop::DumpToLog()

class H4Uart {
 public:
  void OnH4PacketReceived(proxy::H4PacketInterface& hci_packet) {
    snoop_.addRx(packet);
  }
  void OnH4PacketTransmitted(proxy::H4PacketInterface& hci_packet) {
    snoop_.addTx(packet);
  }
  void GetSnoopLog() { snoop_.DumpToLog(); }

 private:
  pw::bluetooth::SnoopBuffer</*kTotalSize=*/4096, /*kMaxHciPacketSize*/ 128>
      snoop_{pw::chrono::VirtualSystemClock::RealClock()};
};

HCI Utils#

pw_bluetooth contains a header with HCI utility functions. See pw::bluetooth::GetHciHeaderSize() and pw::bluetooth::GetHciPayloadSize().

Size Report#

Delta when constructing the first packet view and reading/writing a field. This includes the runtime library and the 4-byte buffer.

Label

Segment

Delta

Make view and write field

FLASH

+1,228

[section .rodata]

-4

__bi_84

+56

main

+8

vClearInterruptMaskFromISR

NEW

+72

emboss::support::ContiguousBuffer<>::GetOffsetStorage<>()

NEW

+44

emboss::support::ContiguousBuffer<>::WriteLittleEndianUInt<>()

NEW

+40

emboss::prelude::UIntView<>::TryToWrite<>()

NEW

+40

emboss::support::ContiguousBuffer<>::ReadLittleEndianUInt<>()

NEW

+36

emboss::prelude::UIntView<>::Write<>()

NEW

+24

pw::bluetooth::emboss::GenericTestCommandPacketView<>::payload()

+1,544

Delta when adding a second packet view and reading/writing a field.

Label

Segment

Delta

Size difference when adding a second view

FLASH

+224

[section .rodata]

+72

emboss::support::ContiguousBuffer<>::GetOffsetStorage<>()

+40

main

-8

vClearInterruptMaskFromISR

NEW

+24

pw::bluetooth::emboss::GenericTestEventPacketView<>::payload()

+352

Roadmap#

  • Add automated Emboss file formatting to pw format (b/331195584)

  • Create a backend for the Bluetooth API using Fuchsia’s Bluetooth stack (Sapphire).

  • Stabilize the Bluetooth API.

  • Add BR/EDR APIs.