1 /*
2  * Copyright 2024 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 #include <cstdint>
20 
21 #include "module.h"
22 
23 namespace bluetooth::hal {
24 
25 enum SocketStatus {
26   SUCCESS = 0,
27   FAILURE,
28 };
29 
30 struct EndpointInfo {
31   // The ID of the Hub to which the end point belongs for hardware offload data path.
32   uint64_t hub_id;
33 
34   //  The ID of the Hub endpoint for hardware offload data path.
35   uint64_t endpoint_id;
36 };
37 
38 struct LeCocCapabilities {
39   // Maximum number of LE COC sockets supported. If not supported, the value must be zero.
40   int number_of_supported_sockets;
41 
42   // Local Maximum Transmission Unit size in octets.
43   uint16_t mtu;
44 };
45 
46 struct SocketCapabilities {
47   LeCocCapabilities le_coc_capabilities;
48 };
49 
50 struct LeCocChannelInfo {
51   // L2cap local channel ID.
52   uint16_t local_cid;
53 
54   // L2cap remote channel ID.
55   uint16_t remote_cid;
56 
57   // PSM for L2CAP LE CoC.
58   uint16_t psm;
59 
60   // Local Maximum Transmission Unit for LE COC specifying the maximum SDU size in bytes that the
61   // local L2CAP layer can receive.
62   uint16_t local_mtu;
63 
64   // Remote Maximum Transmission Unit for LE COC specifying the maximum SDU size in bytes that the
65   // remote L2CAP layer can receive.
66   uint16_t remote_mtu;
67 
68   // Local Maximum PDU payload Size in bytes that the local L2CAP layer can receive.
69   uint16_t local_mps;
70 
71   // Remote Maximum PDU payload Size in bytes that the remote L2CAP layer can receive.
72   uint16_t remote_mps;
73 
74   // Protocol initial credits at Rx path.
75   uint16_t initial_rx_credits;
76 
77   // Protocol initial credits at Tx path.
78   uint16_t initial_tx_credits;
79 };
80 
81 struct SocketContext {
82   // Identifier assigned to the socket by the host stack when the socket is connected.
83   uint64_t socket_id;
84 
85   // Descriptive socket name provided by the host app when it created this socket.
86   std::string name;
87 
88   // ACL connection handle for the socket.
89   uint16_t acl_connection_handle;
90 
91   // Channel information of different protocol used for the socket.
92   std::variant<LeCocChannelInfo> channel_info;
93 
94   // Endpoint information.
95   EndpointInfo endpoint_info;
96 };
97 
98 /**
99  * SocketHalCallback provides an interface for receiving asynchronous events from socket HAL.
100  * Implementations of this class can be registered with the stack to receive these callbacks.
101  *
102  * Callback methods in this interface are invoked from the binder thread. This means that
103  * implementations must be thread-safe and handle any necessary synchronization to avoid race
104  * conditions or other concurrency issues. The callee is solely responsible for ensuring thread
105  * safety within the callback methods.
106  */
107 class SocketHalCallback {
108 public:
109   virtual ~SocketHalCallback() = default;
110 
111   /**
112    * Invoked when IBluetoothSocket.opened() has been completed.
113    *
114    * @param socket_id Identifier assigned to the socket by the host stack
115    * @param status Status indicating success or failure
116    */
117   virtual void SocketOpenedComplete(uint64_t socket_id, SocketStatus status) const = 0;
118 
119   /**
120    * Invoked when offload app or stack requests host stack to close the socket.
121    *
122    * @param socket_id Identifier assigned to the socket by the host stack
123    */
124   virtual void SocketClose(uint64_t socket_id) const = 0;
125 };
126 
127 /**
128  * SocketHal provides an interface to low-power processors, enabling Bluetooth Offload Socket
129  * functionality.
130  *
131  * Bluetooth Offload Socket allows the transfer of channel information from an established
132  * BluetoothSocket to a low-power processor. This enables the offload stack on the low-power
133  * processor to handle packet reception, processing, and transmission independently. This offloading
134  * process prevents the need to wake the main application processor, improving power efficiency.
135  */
136 class SocketHal : public ::bluetooth::Module {
137 public:
138   static const ModuleFactory Factory;
139 
140   virtual ~SocketHal() = default;
141 
142   /**
143    * Registers a socket hal callback function to receive asynchronous events from socket HAL.
144    *
145    * @param callback A pointer to the callback function. Must not be nullptr and must have static
146    * lifetime.
147    * @return True if the callback was successfully registered, false otherwise.
148    */
149   virtual bool RegisterCallback(hal::SocketHalCallback const* callback) = 0;
150 
151   /**
152    * Retrieves the supported offloaded socket capabilities.
153    *
154    * @return Supported socket capabilities
155    */
156   virtual hal::SocketCapabilities GetSocketCapabilities() const = 0;
157 
158   /**
159    * Notifies the socket HAL that the socket has been opened.
160    *
161    * @param context Socket context including socket ID, channel, hub, and endpoint info
162    * @return Result of calling this method
163    */
164   virtual bool Opened(const hal::SocketContext& context) const = 0;
165 
166   /**
167    * Notifies the socket HAL that the socket has been closed.
168    *
169    * @param socket_id Identifier assigned to the socket by the host stack
170    */
171   virtual void Closed(uint64_t socket_id) const = 0;
172 };
173 
174 }  // namespace bluetooth::hal
175