• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "pw_assert/check.h"  // IWYU pragma: keep
18 #include "pw_bluetooth_proxy/acl_data_channel.h"
19 #include "pw_bluetooth_proxy/common.h"
20 #include "pw_status/status.h"
21 
22 namespace pw::bluetooth::proxy {
23 
24 /// `ProxyHost` acts as the main coordinator for proxy functionality. After
25 /// creation, the container then passes packets through the proxy.
26 class ProxyHost {
27  public:
28   /// Creates an `ProxyHost` that will process HCI packets.
29   /// @param[in] send_to_host_fn Callback that will be called when proxy wants
30   /// to send HCI packet towards the host.
31   /// @param[in] send_to_controller_fn - Callback that will be called when proxy
32   /// wants to send HCI packet towards the controller.
33   ProxyHost(H4HciPacketSendFn&& send_to_host_fn,
34             H4HciPacketSendFn&& send_to_controller_fn,
35             uint16_t le_acl_credits_to_reserve);
36 
37   ProxyHost() = delete;
38   virtual ~ProxyHost() = default;
39   ProxyHost(const ProxyHost&) = delete;
40   ProxyHost& operator=(const ProxyHost&) = delete;
41   ProxyHost(ProxyHost&&) = delete;
42   ProxyHost& operator=(ProxyHost&&) = delete;
43 
44   // ##### Container APIs
45 
46   /// Called by container to ask proxy to handle a H4 HCI packet sent from the
47   /// host side towards the controller side. Proxy will in turn call the
48   /// `send_to_controller_fn` provided during construction to pass the packet on
49   /// to the controller. Some packets may be modified, added, or removed.
50   void HandleH4HciFromHost(H4HciPacket h4_packet);
51 
52   /// Called by container to ask proxy to handle a H4 packet sent from the
53   /// controller side towards the host side. Proxy will in turn call the
54   /// `send_to_host_fn` provided during construction to pass the packet on to
55   /// the host. Some packets may be modified, added, or removed.
56   void HandleH4HciFromController(H4HciPacket h4_packet);
57 
58   // ##### Client APIs
59 
60   /// Send a GATT Notify to the indicated connection.
61   ///
62   /// @param[in] connection_handle The connection handle of the peer the notify
63   ///                              is being sent to.
64   ///
65   /// @param[in] attribute_handle  The attribute handle the notify should be
66   ///                              sent on.
67   /// @param[in] attribute_value   The data to be sent. Data will be copied
68   ///                              before function completes.
69   ///
70   /// @returns @rst
71   ///
72   /// .. pw-status-codes::
73   ///  OK: If notify was successfully queued for send.
74   ///  UNAVAILABLE: If CHRE doesn't have resources to queue the send
75   ///               at this time (transient error).
76   ///  UNIMPLEMENTED: If send is not supported by the current implementation.
77   ///  INVALID_ARGUMENT: If arguments are invalid.
78   /// @endrst
sendGattNotify(uint16_t connection_handle,uint16_t attribute_handle,pw::span<const uint8_t> attribute_value)79   pw::Status sendGattNotify(
80       [[maybe_unused]] uint16_t connection_handle,
81       [[maybe_unused]] uint16_t attribute_handle,
82       [[maybe_unused]] pw::span<const uint8_t> attribute_value) {
83     return pw::Status::Unimplemented();
84   }
85 
86   /// Indicates whether the proxy has the capability of sending ACL packets.
87   /// Note that this indicates intention, so it can be true even if the proxy
88   /// has not yet or has been unable to reserve credits from the host.
89   bool HasSendAclCapability() const;
90 
91   /// Returns the number of available LE ACL send credits for the proxy.
92   /// Can be zero if the controller has not yet been initialized by the host.
93   uint16_t GetNumFreeLeAclPackets() const;
94 
95  private:
96   // Process/update the packet.
97   void ProcessH4HciFromController(H4HciPacket h4_packet);
98 
99   // Send packet onwards to host.
100   void SendToHost(H4HciPacket h4_packet);
101 
102   // Send packet onwards to controller.
103   void SendToController(H4HciPacket h4_packet);
104 
105   // Function to call when proxy wants proxy container to pass a packet to the
106   // host.
107   H4HciPacketSendFn outward_send_to_host_fn_;
108 
109   // Function to call when proxy wants proxy container to pass a packet to the
110   // controller.
111   H4HciPacketSendFn outward_send_to_controller_fn_;
112 
113   // Owns management of the HCI LE ACL data channel.
114   AclDataChannel acl_data_channel_;
115 };
116 
117 }  // namespace pw::bluetooth::proxy
118