Lightweight proxy for augmenting Bluetooth functionality.
Main docs: Home
Classes | |
| class | pw::bluetooth::proxy::H4PacketInterface |
| class | pw::bluetooth::proxy::H4PacketWithHci |
| H4PacketWithHci is an H4Packet backed by an HCI buffer. More... | |
| class | pw::bluetooth::proxy::H4PacketWithH4 |
| H4PacketWithH4 is an H4Packet backed by an H4 buffer. More... | |
| class | pw::bluetooth::proxy::ProxyHost |
Macros | |
| #define | PW_BLUETOOTH_PROXY_ASYNC 0 |
| #define | PW_BLUETOOTH_PROXY_MULTIBUF_V1 10 |
| #define | PW_BLUETOOTH_PROXY_MULTIBUF_V2 20 |
| #define | PW_BLUETOOTH_PROXY_MULTIBUF PW_BLUETOOTH_PROXY_MULTIBUF_V1 |
| Sets the version of MultiBuf used by pw_bluetooth_proxy. | |
| #define | PW_BLUETOOTH_PROXY_INTERNAL_ALLOCATOR_SIZE 13000 |
Typedefs | |
| using | pw::bluetooth::proxy::H4PacketInterface::ReleaseFn = Function< void(const uint8_t *)> |
Functions | |
| pw::bluetooth::proxy::H4PacketInterface::H4PacketInterface (span< uint8_t > buffer, size_t hci_offset, ReleaseFn &&release_fn) | |
| pw::bluetooth::proxy::H4PacketInterface::H4PacketInterface (const H4PacketInterface &other)=delete | |
| H4PacketInterface & | pw::bluetooth::proxy::H4PacketInterface::operator= (const H4PacketInterface &other)=delete |
| pw::bluetooth::proxy::H4PacketInterface::H4PacketInterface (H4PacketInterface &&other) | |
| H4PacketInterface & | pw::bluetooth::proxy::H4PacketInterface::operator= (H4PacketInterface &&other) |
| emboss::H4PacketType | pw::bluetooth::proxy::H4PacketInterface::GetH4Type () const |
| void | pw::bluetooth::proxy::H4PacketInterface::SetH4Type (emboss::H4PacketType type) |
| Sets HCI packet type indicator. | |
| constexpr span< uint8_t > | pw::bluetooth::proxy::H4PacketInterface::GetHciSpan () |
| constexpr span< const uint8_t > | pw::bluetooth::proxy::H4PacketInterface::GetHciSpan () const |
| bool | pw::bluetooth::proxy::H4PacketInterface::HasReleaseFn () |
| ReleaseFn | pw::bluetooth::proxy::H4PacketInterface::ResetAndReturnReleaseFn () |
| constexpr span< uint8_t > | pw::bluetooth::proxy::H4PacketInterface::buffer () |
| constexpr span< const uint8_t > | pw::bluetooth::proxy::H4PacketInterface::buffer () const |
| pw::bluetooth::proxy::H4PacketWithHci::H4PacketWithHci (emboss::H4PacketType h4_type, span< uint8_t > hci_span, ReleaseFn &&release_fn=nullptr) | |
| pw::bluetooth::proxy::H4PacketWithHci::H4PacketWithHci (span< uint8_t > h4_span, ReleaseFn &&release_fn=nullptr) | |
| pw::bluetooth::proxy::H4PacketWithHci::H4PacketWithHci (H4PacketWithHci &&other)=default | |
| H4PacketWithHci & | pw::bluetooth::proxy::H4PacketWithHci::operator= (H4PacketWithHci &&other)=default |
| pw::bluetooth::proxy::H4PacketWithH4::H4PacketWithH4 (span< uint8_t > h4_span, ReleaseFn &&release_fn=nullptr) | |
| pw::bluetooth::proxy::H4PacketWithH4::H4PacketWithH4 (emboss::H4PacketType h4_type, span< uint8_t > h4_span, ReleaseFn &&release_fn=nullptr) | |
| constexpr span< uint8_t > | pw::bluetooth::proxy::H4PacketWithH4::GetH4Span () |
| constexpr span< const uint8_t > | pw::bluetooth::proxy::H4PacketWithH4::GetH4Span () const |
| pw::bluetooth::proxy::ProxyHost::ProxyHost (pw::Function< void(H4PacketWithHci &&packet)> &&send_to_host_fn, pw::Function< void(H4PacketWithH4 &&packet)> &&send_to_controller_fn, uint16_t le_acl_credits_to_reserve, uint16_t br_edr_acl_credits_to_reserve, pw::Allocator *allocator=nullptr) | |
| pw::bluetooth::proxy::ProxyHost::ProxyHost (const ProxyHost &)=delete | |
| ProxyHost & | pw::bluetooth::proxy::ProxyHost::operator= (const ProxyHost &)=delete |
| pw::bluetooth::proxy::ProxyHost::ProxyHost (ProxyHost &&)=delete | |
| ProxyHost & | pw::bluetooth::proxy::ProxyHost::operator= (ProxyHost &&)=delete |
| pw::bluetooth::proxy::ProxyHost::~ProxyHost () | |
| void | pw::bluetooth::proxy::ProxyHost::HandleH4HciFromHost (H4PacketWithH4 &&h4_packet) |
| void | pw::bluetooth::proxy::ProxyHost::HandleH4HciFromController (H4PacketWithHci &&h4_packet) |
| void | pw::bluetooth::proxy::ProxyHost::Reset () |
| Status | pw::bluetooth::proxy::ProxyHost::SetDispatcher (async2::Dispatcher &dispatcher) |
| void | pw::bluetooth::proxy::ProxyHost::RegisterL2capStatusDelegate (L2capStatusDelegate &delegate) |
| void | pw::bluetooth::proxy::ProxyHost::UnregisterL2capStatusDelegate (L2capStatusDelegate &delegate) |
| pw::Result< L2capCoc > | pw::bluetooth::proxy::ProxyHost::AcquireL2capCoc (MultiBufAllocator &rx_multibuf_allocator, uint16_t connection_handle, L2capCoc::CocConfig rx_config, L2capCoc::CocConfig tx_config, Function< void(FlatConstMultiBuf &&payload)> &&receive_fn, ChannelEventCallback &&event_fn) |
| pw::Result< BasicL2capChannel > | pw::bluetooth::proxy::ProxyHost::AcquireBasicL2capChannel (MultiBufAllocator &rx_multibuf_allocator, uint16_t connection_handle, uint16_t local_cid, uint16_t remote_cid, AclTransportType transport, OptionalPayloadReceiveCallback &&payload_from_controller_fn, OptionalPayloadReceiveCallback &&payload_from_host_fn, ChannelEventCallback &&event_fn) |
| pw::Result< GattNotifyChannel > | pw::bluetooth::proxy::ProxyHost::AcquireGattNotifyChannel (int16_t connection_handle, uint16_t attribute_handle, ChannelEventCallback &&event_fn) |
| bool | pw::bluetooth::proxy::ProxyHost::HasSendLeAclCapability () const |
| bool | pw::bluetooth::proxy::ProxyHost::HasSendBrEdrAclCapability () const |
| uint16_t | pw::bluetooth::proxy::ProxyHost::GetNumFreeLeAclPackets () const |
| uint16_t | pw::bluetooth::proxy::ProxyHost::GetNumFreeBrEdrAclPackets () const |
| static constexpr size_t | pw::bluetooth::proxy::ProxyHost::GetMaxNumAclConnections () |
| Returns the max number of simultaneous LE ACL connections supported. | |
Variables | |
| static constexpr std::uint8_t | pw::bluetooth::proxy::H4PacketInterface::kH4PacketIndicatorSize = 1 |
Friends | |
| class | pw::bluetooth::proxy::ProxyHost::internal::ProxyHostImpl |
| #define PW_BLUETOOTH_PROXY_ASYNC 0 |
Indicates whether the proxy should operate asynchronously or not.
When set, public API methods will be able to use async2::Channel to communicate with tasks running on the dispatcher thread.
| #define PW_BLUETOOTH_PROXY_INTERNAL_ALLOCATOR_SIZE 13000 |
Sets the size of the internally provided memory region. If the proxy container provides an allocator, the internal allocator is not used and this should be set to 0.
TODO: https://pwbug.dev/369849508 - Fully migrate to container-provided allocator and remove internal allocator.
| #define PW_BLUETOOTH_PROXY_MULTIBUF_V1 10 |
Setting PW_BLUETOOTH_PROXY_MULTIBUF to this value builds the bt-proxy library using MultiBuf v1.
| #define PW_BLUETOOTH_PROXY_MULTIBUF_V2 20 |
Setting PW_BLUETOOTH_PROXY_MULTIBUF to this value builds the bt-proxy library using MultiBuf v2.
| pw::Result< BasicL2capChannel > pw::bluetooth::proxy::ProxyHost::AcquireBasicL2capChannel | ( | MultiBufAllocator & | rx_multibuf_allocator, |
| uint16_t | connection_handle, | ||
| uint16_t | local_cid, | ||
| uint16_t | remote_cid, | ||
| AclTransportType | transport, | ||
| OptionalPayloadReceiveCallback && | payload_from_controller_fn, | ||
| OptionalPayloadReceiveCallback && | payload_from_host_fn, | ||
| ChannelEventCallback && | event_fn | ||
| ) |
Returns an L2CAP channel operating in basic mode that supports writing to and reading from a remote peer.
| [in] | rx_multibuf_allocator | Provides the allocator the channel will use for its Rx buffers (for both queueing and returning to the client). |
| [in] | connection_handle | The connection handle of the remote peer. |
| [in] | local_cid | L2CAP channel ID of the local endpoint. |
| [in] | remote_cid | L2CAP channel ID of the remote endpoint. |
| [in] | transport | Logical link transport type. |
| [in] | payload_from_controller_fn | Read callback to be invoked on Rx SDUs. If a multibuf is returned by the callback, it is copied into the payload to be forwarded to the host. Optional null return indicates packet was handled and no forwarding is required. |
| [in] | payload_from_host_fn | Read callback to be invoked on Tx SDUs. If a multibuf is returned by the callback, it is copied into the payload to be forwarded to the controller. Optional null return indicates packet was handled and no forwarding is required. |
| [in] | event_fn | Handle asynchronous events such as errors and flow control events encountered by the channel. See l2cap_channel_common.h. Must outlive the channel and remain valid until the channel destructor returns. |
| pw::Result< GattNotifyChannel > pw::bluetooth::proxy::ProxyHost::AcquireGattNotifyChannel | ( | int16_t | connection_handle, |
| uint16_t | attribute_handle, | ||
| ChannelEventCallback && | event_fn | ||
| ) |
Returns a GATT Notify channel channel that supports sending notifications to a particular connection handle and attribute.
| [in] | connection_handle | The connection handle of the peer to notify. Maximum valid connection handle is 0x0EFF. |
| [in] | attribute_handle | The attribute handle the notify should be sent on. Cannot be 0. |
| [in] | event_fn | Handle asynchronous events such as errors and flow control events encountered by the channel. See l2cap_channel_common.h. Must outlive the channel and remain valid until the channel destructor returns. |
| pw::Result< L2capCoc > pw::bluetooth::proxy::ProxyHost::AcquireL2capCoc | ( | MultiBufAllocator & | rx_multibuf_allocator, |
| uint16_t | connection_handle, | ||
| L2capCoc::CocConfig | rx_config, | ||
| L2capCoc::CocConfig | tx_config, | ||
| Function< void(FlatConstMultiBuf &&payload)> && | receive_fn, | ||
| ChannelEventCallback && | event_fn | ||
| ) |
Returns an L2CAP connection-oriented channel that supports writing to and reading from a remote peer.
| [in] | rx_multibuf_allocator | Provides the allocator the channel will use for its Rx buffers (for both queueing and returning to the client). |
| [in] | connection_handle | The connection handle of the remote peer. |
| [in] | rx_config | Parameters applying to reading packets. See l2cap_coc.h for details. |
| [in] | tx_config | Parameters applying to writing packets. See l2cap_coc.h for details. |
| [in] | receive_fn | Read callback to be invoked on Rx SDUs. |
| [in] | event_fn | Handle asynchronous events such as errors and flow control events encountered by the channel. See l2cap_channel_common.h. Must outlive the channel and remain valid until the channel destructor returns. |
|
inlineoverrideprivatevirtual |
Implements pw::bluetooth::proxy::H4PacketInterface.
|
inlineoverrideprivatevirtual |
Implements pw::bluetooth::proxy::H4PacketInterface.
|
inlineoverrideprivatevirtual |
Implements pw::bluetooth::proxy::H4PacketInterface.
|
inlineoverrideprivatevirtual |
Implements pw::bluetooth::proxy::H4PacketInterface.
|
inline |
Returns HCI packet type indicator as defined in BT Core Spec Version 5.4 | Vol 4, Part A, Section 2.
|
inlineconstexpr |
Returns pw::span of HCI packet as defined in BT Core Spec Version 5.4 | Vol 4, Part E, Section 5.4.
| uint16_t pw::bluetooth::proxy::ProxyHost::GetNumFreeBrEdrAclPackets | ( | ) | const |
Returns the number of available BR/EDR ACL send credits for the proxy. Can be zero if the controller has not yet been initialized by the host.
| uint16_t pw::bluetooth::proxy::ProxyHost::GetNumFreeLeAclPackets | ( | ) | const |
Returns the number of available LE ACL send credits for the proxy. Can be zero if the controller has not yet been initialized by the host.
| void pw::bluetooth::proxy::ProxyHost::HandleH4HciFromController | ( | H4PacketWithHci && | h4_packet | ) |
Called by container to ask proxy to handle a H4 packet sent from the controller side towards the host side. Proxy will in turn call the send_to_host_fn provided during construction to pass the packet on to the host. Some packets may be modified, added, or removed.
To support all of its current functionality, the proxy host needs at least the following from-controller packets passed through it. It will pass on all other packets, so containers can choose to just pass all from-controller packets through the proxy host.
All packets of this type:
HCI_Command_Complete events (7.7.14) containing return parameters for these commands:
These HCI event packets:
Container is required to call this function synchronously (one packet at a time).
If using async mode, this function must only be called from the thread that the dispatcher is running on.
| void pw::bluetooth::proxy::ProxyHost::HandleH4HciFromHost | ( | H4PacketWithH4 && | h4_packet | ) |
Called by container to ask proxy to handle a H4 HCI packet sent from the host side towards the controller side. Proxy will in turn call the send_to_controller_fn provided during construction to pass the packet on to the controller. Some packets may be modified, added, or removed.
The proxy host currently does not require any from-host packets to support its current functionality. It will pass on all packets, so containers can choose to just pass all from-host packets through it.
Container is required to call this function synchronously (one packet at a time).
If using async mode, this function must only be called from the thread that the dispatcher is running on.
| bool pw::bluetooth::proxy::ProxyHost::HasSendBrEdrAclCapability | ( | ) | const |
Indicates whether the proxy has the capability of sending BR/EDR ACL packets. Note that this indicates intention, so it can be true even if the proxy has not yet or has been unable to reserve credits from the host.
| bool pw::bluetooth::proxy::ProxyHost::HasSendLeAclCapability | ( | ) | const |
Indicates whether the proxy has the capability of sending LE ACL packets. Note that this indicates intention, so it can be true even if the proxy has not yet or has been unable to reserve credits from the host.
| pw::bluetooth::proxy::ProxyHost::ProxyHost | ( | pw::Function< void(H4PacketWithHci &&packet)> && | send_to_host_fn, |
| pw::Function< void(H4PacketWithH4 &&packet)> && | send_to_controller_fn, | ||
| uint16_t | le_acl_credits_to_reserve, | ||
| uint16_t | br_edr_acl_credits_to_reserve, | ||
| pw::Allocator * | allocator = nullptr |
||
| ) |
Creates an ProxyHost that will process HCI packets.
| [in] | send_to_host_fn | Callback that will be called when proxy wants to send HCI packet towards the host. |
| [in] | send_to_controller_fn | - Callback that will be called when proxy wants to send HCI packet towards the controller. |
| [in] | le_acl_credits_to_reserve | - How many buffers to reserve for the proxy out of any LE ACL buffers received from controller. |
| [in] | br_edr_acl_credits_to_reserve | - How many buffers to reserve for the proxy out of any BR/EDR ACL buffers received from controller. |
| [in] | allocator | - General purpose allocator to use for internal packet buffers and objects. If null, an internal allocator and memory pool will be used. On multi-threaded systems this should be a SynchronizedAllocator. |
| void pw::bluetooth::proxy::ProxyHost::RegisterL2capStatusDelegate | ( | L2capStatusDelegate & | delegate | ) |
Register for notifications of connection and disconnection for a particular L2cap service identified by its PSM.
| [in] | delegate | A delegate that will be notified when a successful L2cap connection is made on its PSM. Note: This must outlive the ProxyHost. |
| void pw::bluetooth::proxy::ProxyHost::Reset | ( | ) |
Called when an HCI_Reset Command packet is observed. Proxy resets its internal state. Deregisters all channels, and if any channels are not yet closed, closes them and sends L2capChannelEvent::kReset.
May also be called by container to notify proxy that the Bluetooth system is being otherwise reset.
Warning: Outstanding H4 packets are not invalidated upon reset. If they are destructed post-reset, packets generated post-reset are liable to be overwritten prematurely.
| Status pw::bluetooth::proxy::ProxyHost::SetDispatcher | ( | async2::Dispatcher & | dispatcher | ) |
Sets dispatcher to use to run asynchronous tasks.
The dispatcher must outlive the ProxyHost and any clients. This method must called from the thread the dispatcher will run on.
| void pw::bluetooth::proxy::ProxyHost::UnregisterL2capStatusDelegate | ( | L2capStatusDelegate & | delegate | ) |
Unregister a service delegate.
| [in] | delegate | The delegate to unregister. Must have been previously registered. |
| pw::bluetooth::proxy::ProxyHost::~ProxyHost | ( | ) |
Deregisters all channels, and if any channels are not yet closed, closes them and sends L2capChannelEvent::kChannelClosedByOther.