C/C++ API Reference
Loading...
Searching...
No Matches
proxy_host.h
1// Copyright 2024 The Pigweed Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License"); you may not
4// use this file except in compliance with the License. You may obtain a copy of
5// the License at
6//
7// https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12// License for the specific language governing permissions and limitations under
13// the License.
14
15#pragma once
16
17#include <bitset>
18
19#include "pw_bluetooth/hci_common.emb.h"
20#include "pw_bluetooth_proxy/gatt_notify_channel.h"
21#include "pw_bluetooth_proxy/internal/acl_data_channel.h"
22#include "pw_bluetooth_proxy/internal/hci_transport.h"
23#include "pw_bluetooth_proxy/internal/l2cap_channel_manager.h"
24#include "pw_bluetooth_proxy/l2cap_channel_common.h"
25#include "pw_bluetooth_proxy/l2cap_coc.h"
26#include "pw_bluetooth_proxy/l2cap_status_delegate.h"
27#include "pw_function/function.h"
28#include "pw_multibuf/multibuf.h"
29#include "pw_status/status.h"
30#include "pw_sync/lock_annotations.h"
31#include "pw_sync/mutex.h"
32
33#if PW_BLUETOOTH_PROXY_ASYNC == 0
34#include "pw_bluetooth_proxy/internal/proxy_host_sync.h"
35
36// TODO: b/472522742 - Forward-declare the dispatcher until downstream support
37// for pw_async2 is resolved.
38namespace pw::async2 {
39class Dispatcher;
40} // namespace pw::async2
41#else
42#include "pw_async2/dispatcher.h"
43#include "pw_bluetooth_proxy/internal/proxy_host_async.h"
44#endif // PW_BLUETOOTH_PROXY_ASYNC
45
47namespace pw::bluetooth::proxy {
48
50
53class ProxyHost : public L2capChannelManagerInterface {
54 public:
66 // TODO: b/505912880 - Fix deadlock when release_fn sends packets.
75 ProxyHost(pw::Function<void(H4PacketWithHci&& packet)>&& send_to_host_fn,
76 pw::Function<void(H4PacketWithH4&& packet)>&& send_to_controller_fn,
77 pw::Allocator& allocator);
78
95 ProxyHost(pw::Function<void(H4PacketWithHci&& packet)>&& send_to_host_fn,
96 pw::Function<void(H4PacketWithH4&& packet)>&& send_to_controller_fn,
97 uint16_t le_acl_credits_to_reserve,
98 uint16_t br_edr_acl_credits_to_reserve,
99 pw::Allocator* allocator);
100
101 ProxyHost() = delete;
102 ProxyHost(const ProxyHost&) = delete;
103 ProxyHost& operator=(const ProxyHost&) = delete;
104 ProxyHost(ProxyHost&&) = delete;
105 ProxyHost& operator=(ProxyHost&&) = delete;
108 ~ProxyHost() override;
109
110 // ##### Configuration APIs
111
117 void SetEventBlocked(emboss::EventCode event_code, bool blocked);
118
124 void SetLeSubeventBlocked(emboss::LeSubEventCode subevent_code, bool blocked);
125
128
130 bool IsEventBlocked(emboss::EventCode event_code) const;
131
133 bool IsLeSubeventBlocked(emboss::LeSubEventCode subevent_code) const;
134
135 // ##### Container API
136 // Containers are expected to call these functions (in addition to ctor).
137
153
183
197 void Reset();
198
199 // ##### Container async API
200
211
212 // ##### Client APIs
213
220 void RegisterL2capStatusDelegate(L2capStatusDelegate& delegate);
221
226 void UnregisterL2capStatusDelegate(L2capStatusDelegate& delegate);
227
261 multibuf::MultiBufAllocator& rx_multibuf_allocator,
262 uint16_t connection_handle,
263 L2capCoc::CocConfig rx_config,
264 L2capCoc::CocConfig tx_config,
265 Function<void(multibuf::MultiBuf&& payload)>&& receive_fn,
266 ChannelEventCallback&& event_fn);
267
318 multibuf::MultiBufAllocator& rx_multibuf_allocator,
319 uint16_t connection_handle,
320 uint16_t local_cid,
321 uint16_t remote_cid,
322 AclTransportType transport,
323 OptionalPayloadReceiveCallback&& payload_from_controller_fn,
324 OptionalPayloadReceiveCallback&& payload_from_host_fn,
325 ChannelEventCallback&& event_fn);
326
347 int16_t connection_handle,
348 uint16_t attribute_handle,
349 ChannelEventCallback&& event_fn);
350
355
360
363 uint16_t GetNumFreeLeAclPackets() const;
364
368
370 static constexpr size_t GetMaxNumAclConnections() {
371 return AclDataChannel::GetMaxNumAclConnections();
372 }
373
374 private:
375 friend class internal::ProxyHostImpl;
376
378 void DoHandleH4HciFromHost(H4PacketWithH4&& h4_packet);
379
381 void DoHandleH4HciFromController(H4PacketWithHci&& h4_packet);
382
384 void DoReset();
385
387 void DoRegisterL2capStatusDelegate(L2capStatusDelegate& delegate);
388
390 void DoUnregisterL2capStatusDelegate(L2capStatusDelegate& delegate);
391
393 pw::Result<L2capCoc> DoAcquireL2capCoc(
394 multibuf::MultiBufAllocator& rx_multibuf_allocator,
395 uint16_t connection_handle,
396 L2capCoc::CocConfig rx_config,
397 L2capCoc::CocConfig tx_config,
398 Function<void(multibuf::MultiBuf&& payload)>&& receive_fn,
399 ChannelEventCallback&& event_fn);
400
402 pw::Result<BasicL2capChannel> DoAcquireBasicL2capChannel(
403 multibuf::MultiBufAllocator& rx_multibuf_allocator,
404 uint16_t connection_handle,
405 uint16_t local_cid,
406 uint16_t remote_cid,
407 AclTransportType transport,
408 OptionalPayloadReceiveCallback&& payload_from_controller_fn,
409 OptionalPayloadReceiveCallback&& payload_from_host_fn,
410 ChannelEventCallback&& event_fn);
411
413 pw::Result<GattNotifyChannel> DoAcquireGattNotifyChannel(
414 int16_t connection_handle,
415 uint16_t attribute_handle,
416 ChannelEventCallback&& event_fn);
417
419 bool DoHasSendLeAclCapability() const;
420
422 bool DoHasSendBrEdrAclCapability() const;
423
425 uint16_t DoGetNumFreeLeAclPackets() const;
426
428 uint16_t DoGetNumFreeBrEdrAclPackets() const;
429
430 // Handle HCI Event packet from the controller.
431 void HandleEventFromController(H4PacketWithHci&& h4_packet);
432
433 // Handle HCI Event packet from the host.
434 void HandleEventFromHost(H4PacketWithH4&& h4_packet);
435
436 // Handle HCI ACL data packet from the controller.
437 void HandleAclFromController(H4PacketWithHci&& h4_packet);
438
439 // Process an LE_META_EVENT
440 bool HandleLeMetaEvent(H4PacketWithHci& h4_packet);
441
442 // Process a Command_Complete event.
443 bool HandleCommandCompleteEvent(H4PacketWithHci& h4_packet);
444
445 // Handle HCI Command packet from the host.
446 void HandleCommandFromHost(H4PacketWithH4&& h4_packet);
447
448 // Handle HCI ACL data packet from the host.
449 void HandleAclFromHost(H4PacketWithH4&& h4_packet);
450
451 // Called when any type of connection complete event is received.
452 void OnConnectionCompleteSuccess(uint16_t connection_handle,
453 AclTransportType transport);
454
455 // AclDataChannel callback for when new ACL TX credits are received and more
456 // L2CAP packets can be sent.
457 void OnAclTxCredits();
458
459 // L2capChannelManagerInterface override:
460 Result<UniquePtr<ChannelProxy>> DoInterceptBasicModeChannel(
461 ConnectionHandle connection_handle,
462 uint16_t local_channel_id,
463 uint16_t remote_channel_id,
464 AclTransportType transport,
465 BufferReceiveFunction&& payload_from_controller_fn,
466 BufferReceiveFunction&& payload_from_host_fn,
467 ChannelEventCallback&& event_fn) override;
468
469 Result<UniquePtr<ChannelProxy>> InternalDoInterceptBasicModeChannel(
470 ConnectionHandle connection_handle,
471 uint16_t local_channel_id,
472 uint16_t remote_channel_id,
473 AclTransportType transport,
474 BufferReceiveFunction&& payload_from_controller_fn,
475 BufferReceiveFunction&& payload_from_host_fn,
476 ChannelEventCallback&& event_fn);
477
478 Result<UniquePtr<ChannelProxy>> DoInterceptCreditBasedFlowControlChannel(
479 ConnectionHandle connection_handle,
480 ConnectionOrientedChannelConfig rx_config,
481 ConnectionOrientedChannelConfig tx_config,
482 MultiBufReceiveFunction&& receive_fn,
483 ChannelEventCallback&& event_fn) override;
484
485 // Implementation-specific details that may vary between sync and async modes.
486 internal::ProxyHostImpl impl_;
487
488 // For sending non-ACL data to the host and controller. ACL traffic shall be
489 // sent through the `acl_data_channel_`.
490 HciTransport hci_transport_;
491
492 // Owns management of the LE ACL data channel.
493 AclDataChannel acl_data_channel_;
494
495 // Keeps track of the L2CAP-based channels managed by the proxy.
496 L2capChannelManager l2cap_channel_manager_;
497
498 mutable sync::Mutex filter_mutex_;
499
500 // Storage for blocked events (256 bits for 256 possible codes)
501 std::bitset<256> blocked_events_ PW_GUARDED_BY(filter_mutex_);
502 std::bitset<256> blocked_le_subevents_ PW_GUARDED_BY(filter_mutex_);
503};
504
505} // namespace pw::bluetooth::proxy
Definition: allocator.h:42
Definition: result.h:145
Definition: status.h:120
Definition: dispatcher.h:74
H4PacketWithH4 is an H4Packet backed by an H4 buffer.
Definition: h4_packet.h:173
H4PacketWithHci is an H4Packet backed by an HCI buffer.
Definition: h4_packet.h:138
Definition: proxy_host.h:53
Definition: mutex.h:40
static constexpr size_t GetMaxNumAclConnections()
Returns the max number of simultaneous LE ACL connections supported.
Definition: proxy_host.h:370
pw::Result< GattNotifyChannel > AcquireGattNotifyChannel(int16_t connection_handle, uint16_t attribute_handle, ChannelEventCallback &&event_fn)
void HandleH4HciFromHost(H4PacketWithH4 &&h4_packet)
void RegisterL2capStatusDelegate(L2capStatusDelegate &delegate)
void SetLeSubeventBlocked(emboss::LeSubEventCode subevent_code, bool blocked)
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)
Status SetDispatcher(async2::Dispatcher &dispatcher)
uint16_t GetNumFreeLeAclPackets() const
void ResetFilters()
Resets all filters, allowing all events and subevents to pass through.
pw::Result< BasicL2capChannel > AcquireBasicL2capChannel(multibuf::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)
bool IsEventBlocked(emboss::EventCode event_code) const
Checks if a specific HCI event is currently blocked.
bool IsLeSubeventBlocked(emboss::LeSubEventCode subevent_code) const
Checks if a specific LE Meta subevent is currently blocked.
uint16_t GetNumFreeBrEdrAclPackets() const
pw::Result< L2capCoc > AcquireL2capCoc(multibuf::MultiBufAllocator &rx_multibuf_allocator, uint16_t connection_handle, L2capCoc::CocConfig rx_config, L2capCoc::CocConfig tx_config, Function< void(multibuf::MultiBuf &&payload)> &&receive_fn, ChannelEventCallback &&event_fn)
void UnregisterL2capStatusDelegate(L2capStatusDelegate &delegate)
ProxyHost(pw::Function< void(H4PacketWithHci &&packet)> &&send_to_host_fn, pw::Function< void(H4PacketWithH4 &&packet)> &&send_to_controller_fn, pw::Allocator &allocator)
void HandleH4HciFromController(H4PacketWithHci &&h4_packet)
void SetEventBlocked(emboss::EventCode event_code, bool blocked)
fit::function_impl< function_internal::config::kInlineCallableSize, !function_internal::config::kEnableDynamicAllocation, FunctionType, PW_FUNCTION_DEFAULT_ALLOCATOR_TYPE > Function
Definition: function.h:73
#define PW_GUARDED_BY(x)
Definition: lock_annotations.h:60
Lightweight proxy for augmenting Bluetooth functionality.
Definition: h4_packet.h:27