• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2023 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 // This file contains general opcode/number and static packet definitions for
17 // extensions to the Bluetooth Host-Controller interface. These extensions
18 // aren't standardized through the Bluetooth SIG and their documentation is
19 // available separately (linked below). Each packet payload structure contains
20 // parameter descriptions based on their respective documentation.
21 //
22 // Documentation links:
23 //
24 //    - Android: https://source.android.com/devices/bluetooth/hci_requirements
25 //
26 // NOTE: The definitions below are incomplete. They get added as needed. This
27 // list will grow as we support more vendor features.
28 //
29 // NOTE: Avoid casting raw buffer pointers to the packet payload structure types
30 // below; use as template parameter to PacketView::payload(),
31 // MutableBufferView::mutable_payload(), or CommandPacket::mutable_payload()
32 // instead. Take extra care when accessing flexible array members.
33 
34 #include <pw_bluetooth/hci_android.emb.h>
35 
36 #include "pw_bluetooth_sapphire/internal/host/hci-spec/protocol.h"
37 
38 namespace bt::hci_spec::vendor::android {
39 
40 // Bitmask values for A2DP supported codecs
41 enum class A2dpCodecType : uint32_t {
42   // clang-format off
43   kSbc    = (1 << 0),
44   kAac    = (1 << 1),
45   kAptx   = (1 << 2),
46   kAptxhd = (1 << 3),
47   kLdac   = (1 << 4),
48   // Bits 5 - 31 are reserved
49   // clang-format on
50 };
51 
52 // Bitmask values for Sampling Frequency
53 enum class A2dpSamplingFrequency : uint32_t {
54   // clang-format off
55   k44100Hz  = (1 << 0),
56   k48000Hz  = (1 << 1),
57   k88200Hz  = (1 << 2),
58   k96000Hz  = (1 << 3),
59   // clang-format on
60 };
61 
62 // Bitmask values for Bits per Sample
63 enum class A2dpBitsPerSample : uint8_t {
64   // clang-format off
65   k16BitsPerSample  = (1 << 0),
66   k24BitsPerSample  = (1 << 1),
67   k32BitsPerSample  = (1 << 2),
68   // clang-format on
69 };
70 
71 // Bitmask values for Channel Mode
72 enum class A2dpChannelMode : uint8_t {
73   // clang-format off
74   kMono   = (1 << 0),
75   kStereo = (1 << 1),
76   // clang-format on
77 };
78 
79 // Bitmask values for Bitrate Index
80 enum class A2dpBitrateIndex : uint8_t {
81   // clang-format off
82   kHigh             = 0x00,
83   kMild             = 0x01,
84   kLow              = 0x02,
85   // Values 0x03 - 0x7E are reserved
86   kAdaptiveBitrate  = 0x7F,
87   // Values 0x80 - 0xFF are reserved
88   // clang-format on
89 };
90 
91 // Bitmask values for LDAC Channel Mode
92 enum class A2dpLdacChannelMode : uint8_t {
93   // clang-format off
94   kStereo = (1 << 0),
95   kDual   = (1 << 1),
96   kMono   = (1 << 2),
97   // clang-format on
98 };
99 
100 // 1-octet boolean "enable"/"disable" parameter for AAC variable bitrate
101 enum class A2dpAacEnableVariableBitRate : uint8_t {
102   kDisable = 0x00,
103   kEnable = 0x80,
104 };
105 
106 // ============================================================================
107 // LE Get Vendor Capabilities Command
108 constexpr OpCode kLEGetVendorCapabilities = VendorOpCode(0x153);
109 
110 // ============================================================================
111 // A2DP Offload Commands
112 
113 constexpr OpCode kA2dpOffloadCommand = VendorOpCode(0x15D);
114 constexpr uint8_t kStartA2dpOffloadCommandSubopcode = 0x01;
115 constexpr uint8_t kStopA2dpOffloadCommandSubopcode = 0x02;
116 constexpr uint32_t kLdacVendorId = 0x0000012D;
117 constexpr uint16_t kLdacCodecId = 0x00AA;
118 
119 struct A2dpScmsTEnable {
120   GenericEnableParam enabled;
121   uint8_t header;
122 } __attribute__((packed));
123 
124 struct SbcCodecInformation {
125   // Bitmask: block length | subbands | allocation method
126   // Block length: bits 7-4
127   // Subbands: bits 3-2
128   // Allocation method: bits 1-0
129   uint8_t blocklen_subbands_alloc_method;
130 
131   uint8_t min_bitpool_value;
132 
133   uint8_t max_bitpool_value;
134 
135   // Bitmask: sampling frequency | channel mode
136   // Sampling frequency: bits 7-4
137   // Channel mode: bits 3-0
138   uint8_t sampling_freq_channel_mode;
139 
140   // Bytes 4 - 31 are reserved
141   uint8_t reserved[28];
142 } __attribute__((packed));
143 
144 static_assert(sizeof(SbcCodecInformation) == 32,
145               "SbcCodecInformation must take up exactly 32 bytes");
146 
147 struct AacCodecInformation {
148   // Object type
149   uint8_t object_type;
150 
151   A2dpAacEnableVariableBitRate variable_bit_rate;
152 
153   // Bytes 2 - 31 are reserved
154   uint8_t reserved[30];
155 } __attribute__((packed));
156 
157 static_assert(sizeof(AacCodecInformation) == 32,
158               "AacCodecInformation must take up exactly 32 bytes");
159 
160 struct LdacCodecInformation {
161   // Must always be set to kLdacVendorId
162   uint32_t vendor_id;
163 
164   // Must always be set to kLdacCodecId
165   // All other values are reserved
166   uint16_t codec_id;
167 
168   // Bitmask: bitrate index (see A2dpBitrateIndex for bitmask values)
169   A2dpBitrateIndex bitrate_index;
170 
171   // Bitmask: LDAC channel mode (see A2dpLdacChannelMode for bitmask values)
172   A2dpLdacChannelMode ldac_channel_mode;
173 
174   // Bytes 8 - 31 are reserved
175   uint8_t reserved[24];
176 } __attribute__((packed));
177 
178 static_assert(sizeof(LdacCodecInformation) == 32,
179               "LdacCodecInformation must take up exactly 32 bytes");
180 
181 struct AptxCodecInformation {
182   // Bits 0 - 31 are reserved
183   uint8_t reserved[32];
184 } __attribute__((packed));
185 
186 static_assert(sizeof(AptxCodecInformation) == 32,
187               "AptxCodecInformation must take up exactly 32 bytes");
188 
189 // TODO(fxbug.dev/42078774): Migrate A2dpOffloadCodecInformation to Emboss
190 union A2dpOffloadCodecInformation {
191   SbcCodecInformation sbc;
192   AacCodecInformation aac;
193   LdacCodecInformation ldac;
194   AptxCodecInformation aptx;
195 } __attribute__((packed));
196 
197 static_assert(sizeof(A2dpOffloadCodecInformation) == 32,
198               "A2dpOffloadCodecInformation must take up exactly 32 bytes");
199 
200 struct StartA2dpOffloadCommandReturnParams {
201   StatusCode status;
202 
203   // Will always be set to kStartA2dpOffloadCommandSubopcode
204   uint8_t opcode;
205 } __attribute__((packed));
206 
207 struct StopA2dpOffloadCommandReturnParams {
208   StatusCode status;
209 
210   // Will always be set to kStopA2dpOffloadCommandSubopcode
211   uint8_t opcode;
212 } __attribute__((packed));
213 
214 // ============================================================================
215 // Multiple Advertising
216 //
217 // NOTE: Multiple advertiser support is deprecated in the Google feature spec
218 // v0.98 and above. Users of the following vendor extension HCI commands should
219 // first ensure that the controller is using a compatible Google feature spec.
220 
221 // The kLEMultiAdvt opcode is shared across all multiple advertising HCI
222 // commands. To differentiate between the multiple commands, a subopcode field
223 // is included in the command payload.
224 constexpr OpCode kLEMultiAdvt = VendorOpCode(0x154);
225 
226 // ============================================================================
227 // LE Multiple Advertising Set Advertising Parameters
228 constexpr uint8_t kLEMultiAdvtSetAdvtParamSubopcode = 0x01;
229 
230 struct LEMultiAdvtSetAdvtParamCommandParams {
231   // Must always be set to kLEMultiAdvtSetAdvtParametersSubopcode
232   uint8_t opcode;
233 
234   // Range: see kLEAdvertisingInterval[Min|Max] in hci_constants.h
235   // Default: N = kLEAdvertisingIntervalDefault (see hci_constants.h)
236   // Time: N * 0.625 ms
237   // Time Range: 20 ms to 10.24 s
238   uint16_t adv_interval_min;
239 
240   // Range: see kLEAdvertisingInterval[Min|Max] in hci_constants.h
241   // Default: N = kLEAdvertisingIntervalDefault (see hci_constants.h)
242   // Time: N * 0.625 ms
243   // Time Range: 20 ms to 10.24 s
244   uint16_t adv_interval_max;
245 
246   // Used to determine the packet type that is used for advertising when
247   // advertising is enabled (see hci_constants.h)
248   pw::bluetooth::emboss::LEAdvertisingType adv_type;
249 
250   pw::bluetooth::emboss::LEOwnAddressType own_address_type;
251   LEPeerAddressType peer_address_type;
252 
253   // Public Device Address, Random Device Address, Public Identity Address, or
254   // Random (static) Identity Address of the device to be connected.
255   DeviceAddressBytes peer_address;
256 
257   // (See the constants kLEAdvertisingChannel* in hci_constants.h for possible
258   // values).
259   uint8_t adv_channel_map;
260 
261   // This parameter shall be ignored when directed advertising is enabled (see
262   // hci_constants.h for possible values).
263   LEAdvFilterPolicy adv_filter_policy;
264 
265   // Handle used to identify an advertising set.
266   AdvertisingHandle adv_handle;
267 
268   // Transmit_Power, Unit: dBm
269   // Range (-70 to +20)
270   int8_t adv_tx_power;
271 } __attribute__((packed));
272 
273 struct LEMultiAdvtSetAdvtParamReturnParams {
274   StatusCode status;
275 
276   // Will always be set to kLEMultiAdvtSetAdvtParametersSubopcode
277   uint8_t opcode;
278 } __attribute__((packed));
279 
280 // =======================================
281 // LE Multiple Advertising Set Advertising Data
282 constexpr uint8_t kLEMultiAdvtSetAdvtDataSubopcode = 0x2;
283 
284 struct LEMultiAdvtSetAdvtDataCommandParams {
285   // Must always be set to kLEMultiAdvtSetAdvtDataSubopcode
286   uint8_t opcode;
287 
288   // Length of the advertising data included in this command packet, up to
289   // kMaxLEAdvertisingDataLength bytes.
290   uint8_t adv_data_length;
291 
292   // 31 octets of advertising data formatted as defined in Core Spec v5.0, Vol
293   // 3, Part C, Section 11
294   uint8_t adv_data[kMaxLEAdvertisingDataLength];
295 
296   // Handle used to identify an advertising set.
297   AdvertisingHandle adv_handle;
298 } __attribute__((packed));
299 
300 struct LEMultiAdvtSetAdvtDataReturnParams {
301   StatusCode status;
302 
303   // Will always be set to kLEMultiAdvtSetAdvtDataSubopcode
304   uint8_t opcode;
305 } __attribute__((packed));
306 
307 // =======================================
308 // LE Multiple Advertising Set Scan Response
309 constexpr uint8_t kLEMultiAdvtSetScanRespSubopcode = 0x3;
310 
311 struct LEMultiAdvtSetScanRespCommandParams {
312   // Must always be set to kLEMultiAdvtSetScanRespSubopcode
313   uint8_t opcode;
314 
315   // Length of the scan response data included in this command packet, up to
316   // kMaxLEAdvertisingDataLength bytes.
317   uint8_t scan_rsp_data_length;
318 
319   // 31 octets of advertising data formatted as defined in Core Spec v5.0, Vol
320   // 3, Part C, Section 11
321   uint8_t scan_rsp_data[kMaxLEAdvertisingDataLength];
322 
323   // Handle used to identify an advertising set.
324   AdvertisingHandle adv_handle;
325 } __attribute__((packed));
326 
327 struct LEMultiAdvtSetScanRespReturnParams {
328   StatusCode status;
329 
330   // Will always be set to kLEMultiAdvtSetScanRespSubopcode
331   uint8_t opcode;
332 } __attribute__((packed));
333 
334 // =======================================
335 // LE Multiple Advertising Set Random Address
336 constexpr uint8_t kLEMultiAdvtSetRandomAddrSubopcode = 0x4;
337 
338 struct LEMultiAdvtSetRandomAddrCommandParams {
339   // Must always be set to kLEMultiAdvtSetRandomAddrSubopcode
340   uint8_t opcode;
341 
342   DeviceAddressBytes random_address;
343 
344   // Handle used to identify an advertising set.
345   AdvertisingHandle adv_handle;
346 } __attribute__((packed));
347 
348 struct LEMultiAdvtSetRandomAddrReturnParams {
349   StatusCode status;
350 
351   // Will always be set to kLEMultiAdvtSetRandomAddrSubopcode
352   uint8_t opcode;
353 } __attribute__((packed));
354 
355 // =======================================
356 // LE Multiple Advertising Set Advertising Enable
357 constexpr uint8_t kLEMultiAdvtEnableSubopcode = 0x5;
358 
359 struct LEMultiAdvtEnableReturnParams {
360   StatusCode status;
361 
362   // Will always be set to kLEMultiAdvtSetRandomAddrSubopcode
363   uint8_t opcode;
364 } __attribute__((packed));
365 
366 // ======= Events =======
367 
368 // LE multi-advertising state change sub-event
369 constexpr EventCode kLEMultiAdvtStateChangeSubeventCode = 0x55;
370 
371 }  // namespace bt::hci_spec::vendor::android
372