1 /*
2  * Copyright 2022 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 #include <bluetooth/log.h>
18 #include <poll.h>
19 #include <sys/socket.h>
20 #include <unistd.h>
21 
22 #include <vector>
23 
24 #include "hci/controller_interface.h"
25 #include "main/shim/entry.h"
26 #include "osi/include/properties.h"
27 #include "stack/btm/btm_sco_hfp_hal.h"
28 #include "stack/include/hcimsgs.h"
29 #include "stack/include/sdpdefs.h"
30 
31 extern int GetAdapterIndex();
32 
33 using bluetooth::legacy::hci::GetInterface;
34 
35 namespace hfp_hal_interface {
36 namespace {
37 bool offload_supported = false;
38 bool offload_enabled = false;
39 
40 typedef struct cached_codec_info {
41   struct bt_codec inner;
42   size_t pkt_size;
43 } cached_codec_info;
44 
45 std::vector<cached_codec_info> cached_codecs;
46 
47 #define RETRY_ON_INTR(fn) \
48   do {                    \
49   } while ((fn) == -1 && errno == EINTR)
50 
51 #define MGMT_EV_SIZE_MAX 1024
52 #define MGMT_PKT_HDR_SIZE 6
53 struct mgmt_pkt {
54   uint16_t opcode;
55   uint16_t index;
56   uint16_t len;
57   uint8_t data[MGMT_EV_SIZE_MAX];
58 } __attribute__((packed));
59 
60 #define MGMT_EV_COMMAND_COMPLETE 0x1
61 
62 struct mgmt_ev_cmd_complete {
63   uint16_t opcode;
64   uint8_t status;
65   uint8_t data[];
66 } __attribute__((packed));
67 
68 #define MGMT_OP_GET_SCO_CODEC_CAPABILITIES 0x0100
69 #define MGMT_SCO_CODEC_CVSD 0x1
70 #define MGMT_SCO_CODEC_MSBC_TRANSPARENT 0x2
71 #define MGMT_SCO_CODEC_MSBC 0x3
72 
73 struct mgmt_cp_get_codec_capabilities {
74   uint16_t hci_dev;
75 } __attribute__((packed));
76 
77 struct mgmt_rp_get_codec_capabilities {
78   uint16_t hci_dev;
79   uint8_t transparent_wbs_supported;
80   uint8_t hci_data_path_id;
81   uint32_t wbs_pkt_len;
82 } __attribute__((packed));
83 
84 #define MGMT_POLL_TIMEOUT_MS 2000
85 
cache_codec_capabilities(struct mgmt_rp_get_codec_capabilities * rp)86 void cache_codec_capabilities(struct mgmt_rp_get_codec_capabilities* rp) {
87   const uint8_t kCodecMsbc = 0x5;
88 
89   // TODO(b/323087725): Query the codec capabilities and fill in c.inner.data.
90   // The capabilities are not used currently so it's safe to keep this for a
91   // while.
92 
93   // CVSD is mandatory in HFP.
94   cached_codecs.push_back({
95           .inner = {.codec = codec::CVSD},
96   });
97 
98   // No need to check GetLocalSupportedBrEdrCodecIds. Some legacy devices don't
99   // even support HCI command Read Local Supported Codecs so WBS quirk is more
100   // reliable.
101   if (rp->transparent_wbs_supported) {
102     cached_codecs.push_back({
103             .inner = {.codec = codec::MSBC_TRANSPARENT},
104             .pkt_size = rp->wbs_pkt_len,
105     });
106   }
107 
108   auto codecs = bluetooth::shim::GetController()->GetLocalSupportedBrEdrCodecIds();
109   if (std::find(codecs.begin(), codecs.end(), kCodecMsbc) != codecs.end()) {
110     offload_supported = true;
111     cached_codecs.push_back({
112             .inner = {.codec = codec::MSBC, .data_path = rp->hci_data_path_id},
113             .pkt_size = rp->wbs_pkt_len,
114     });
115   }
116 
117   for (const auto& c : cached_codecs) {
118     bluetooth::log::info("Caching HFP codec {}, data path {}, data len {}, pkt_size {}",
119                          (uint64_t)c.inner.codec, c.inner.data_path, c.inner.data.size(),
120                          c.pkt_size);
121   }
122 }
123 
124 struct sockaddr_hci {
125   sa_family_t hci_family;
126   uint16_t hci_dev;
127   uint16_t hci_channel;
128 };
129 
130 constexpr uint8_t BTPROTO_HCI = 1;
131 constexpr uint16_t HCI_CHANNEL_CONTROL = 3;
132 constexpr uint16_t HCI_DEV_NONE = 0xffff;
133 
btsocket_open_mgmt(uint16_t hci)134 int btsocket_open_mgmt(uint16_t hci) {
135   int fd = socket(PF_BLUETOOTH, SOCK_RAW | SOCK_NONBLOCK, BTPROTO_HCI);
136   if (fd < 0) {
137     bluetooth::log::debug("Failed to open BT socket, hci: %u", hci);
138     return -errno;
139   }
140 
141   struct sockaddr_hci addr = {
142           .hci_family = AF_BLUETOOTH,
143           .hci_dev = HCI_DEV_NONE,
144           .hci_channel = HCI_CHANNEL_CONTROL,
145   };
146 
147   int ret = bind(fd, (struct sockaddr*)&addr, sizeof(addr));
148   if (ret < 0) {
149     bluetooth::log::debug("Failed to bind BT socket.");
150     close(fd);
151     return -errno;
152   }
153 
154   return fd;
155 }
156 
mgmt_get_codec_capabilities(int fd,uint16_t hci)157 int mgmt_get_codec_capabilities(int fd, uint16_t hci) {
158   struct mgmt_pkt ev;
159   ev.opcode = MGMT_OP_GET_SCO_CODEC_CAPABILITIES;
160   ev.index = HCI_DEV_NONE;
161   ev.len = sizeof(struct mgmt_cp_get_codec_capabilities);
162 
163   struct mgmt_cp_get_codec_capabilities* cp =
164           reinterpret_cast<struct mgmt_cp_get_codec_capabilities*>(ev.data);
165   cp->hci_dev = hci;
166 
167   int ret;
168 
169   struct pollfd writable[1];
170   writable[0].fd = fd;
171   writable[0].events = POLLOUT;
172 
173   do {
174     ret = poll(writable, 1, MGMT_POLL_TIMEOUT_MS);
175     if (ret > 0) {
176       RETRY_ON_INTR(ret = write(fd, &ev, MGMT_PKT_HDR_SIZE + ev.len));
177       if (ret < 0) {
178         bluetooth::log::debug("Failed to call MGMT_OP_GET_SCO_CODEC_CAPABILITIES: {}", -errno);
179         return -errno;
180       }
181       break;
182     }
183   } while (ret > 0);
184 
185   if (ret <= 0) {
186     bluetooth::log::debug("Failed waiting for mgmt socket to be writable.");
187     return -1;
188   }
189 
190   struct pollfd fds[1];
191 
192   fds[0].fd = fd;
193   fds[0].events = POLLIN;
194 
195   do {
196     ret = poll(fds, 1, MGMT_POLL_TIMEOUT_MS);
197     if (ret > 0) {
198       if (fds[0].revents & POLLIN) {
199         RETRY_ON_INTR(ret = read(fd, &ev, sizeof(ev)));
200         if (ret < 0) {
201           bluetooth::log::debug("Failed to read mgmt socket: {}", -errno);
202           return -errno;
203         } else if (ret == 0) { // unlikely to happen, just a safeguard.
204           bluetooth::log::debug("Failed to read mgmt socket: EOF");
205           return -1;
206         }
207 
208         if (ev.opcode == MGMT_EV_COMMAND_COMPLETE) {
209           struct mgmt_ev_cmd_complete* cc = reinterpret_cast<struct mgmt_ev_cmd_complete*>(ev.data);
210           if (cc->opcode == MGMT_OP_GET_SCO_CODEC_CAPABILITIES && cc->status == 0) {
211             struct mgmt_rp_get_codec_capabilities* rp =
212                     reinterpret_cast<struct mgmt_rp_get_codec_capabilities*>(cc->data);
213             if (rp->hci_dev == hci) {
214               cache_codec_capabilities(rp);
215               return 0;
216             }
217           }
218         }
219       }
220     } else if (ret == 0) {
221       bluetooth::log::debug("Timeout while waiting for codec capabilities response.");
222       ret = -1;
223     }
224   } while (ret > 0);
225 
226   return ret;
227 }
228 
229 #define MGMT_OP_NOTIFY_SCO_CONNECTION_CHANGE 0x0101
230 struct mgmt_cp_notify_sco_connection_change {
231   uint16_t hci_dev;
232   uint8_t addr[6];
233   uint8_t addr_type;
234   uint8_t connected;
235   uint8_t codec;
236 } __attribute__((packed));
237 
mgmt_notify_sco_connection_change(int fd,int hci,RawAddress device,bool is_connected,int codec)238 int mgmt_notify_sco_connection_change(int fd, int hci, RawAddress device, bool is_connected,
239                                       int codec) {
240   struct mgmt_pkt ev;
241   ev.opcode = MGMT_OP_NOTIFY_SCO_CONNECTION_CHANGE;
242   ev.index = HCI_DEV_NONE;
243   ev.len = sizeof(struct mgmt_cp_notify_sco_connection_change);
244 
245   struct mgmt_cp_notify_sco_connection_change* cp =
246           reinterpret_cast<struct mgmt_cp_notify_sco_connection_change*>(ev.data);
247 
248   cp->hci_dev = hci;
249   cp->connected = is_connected;
250   cp->codec = codec;
251   memcpy(cp->addr, device.address, sizeof(cp->addr));
252   cp->addr_type = 0;
253 
254   int ret;
255 
256   struct pollfd writable[1];
257   writable[0].fd = fd;
258   writable[0].events = POLLOUT;
259 
260   do {
261     ret = poll(writable, 1, MGMT_POLL_TIMEOUT_MS);
262     if (ret > 0) {
263       RETRY_ON_INTR(ret = write(fd, &ev, MGMT_PKT_HDR_SIZE + ev.len));
264       if (ret < 0) {
265         bluetooth::log::error("Failed to call MGMT_OP_NOTIFY_SCO_CONNECTION_CHANGE: {}", -errno);
266         return -errno;
267       }
268       break;
269     }
270   } while (ret > 0);
271 
272   if (ret <= 0) {
273     bluetooth::log::debug("Failed waiting for mgmt socket to be writable.");
274     return -1;
275   }
276 
277   return 0;
278 }
279 }  // namespace
280 
init()281 void init() {
282   int hci = GetAdapterIndex();
283   int fd = btsocket_open_mgmt(hci);
284   if (fd < 0) {
285     bluetooth::log::error("Failed to open mgmt channel, error= {}.", fd);
286     return;
287   }
288 
289   int ret = mgmt_get_codec_capabilities(fd, hci);
290   if (ret) {
291     bluetooth::log::error("Failed to get codec capabilities with error = {}.", ret);
292   } else {
293     bluetooth::log::info("Successfully queried SCO codec capabilities.");
294   }
295 
296 #ifndef TARGET_FLOSS
297   // If hfp software path is not enabled, fallback to offload path.
298   if (!osi_property_get_bool("bluetooth.hfp.software_datapath.enabled", false)) {
299     enable_offload(true);
300   }
301 #endif
302 
303   close(fd);
304 }
305 
306 // Check if the specified coding format is supported by the adapter.
is_coding_format_supported(esco_coding_format_t coding_format)307 bool is_coding_format_supported(esco_coding_format_t coding_format) {
308   if (coding_format != ESCO_CODING_FORMAT_TRANSPNT && coding_format != ESCO_CODING_FORMAT_MSBC) {
309     bluetooth::log::warn("Unsupported coding format to query: {}", coding_format);
310     return false;
311   }
312 
313   for (cached_codec_info c : cached_codecs) {
314     if (c.inner.codec == MSBC_TRANSPARENT && coding_format == ESCO_CODING_FORMAT_TRANSPNT) {
315       return true;
316     }
317     if (c.inner.codec == MSBC && coding_format == ESCO_CODING_FORMAT_MSBC) {
318       return true;
319     }
320   }
321 
322   return false;
323 }
324 
325 // Check if wideband speech is supported on local device
get_wbs_supported()326 bool get_wbs_supported() {
327   return is_coding_format_supported(ESCO_CODING_FORMAT_TRANSPNT) ||
328          is_coding_format_supported(ESCO_CODING_FORMAT_MSBC);
329 }
330 
331 // Check if super-wideband speech is supported on local device
get_swb_supported()332 bool get_swb_supported() {
333 #ifdef TARGET_FLOSS
334   // We only support SWB via transparent mode.
335   return is_coding_format_supported(ESCO_CODING_FORMAT_TRANSPNT);
336 #else
337   return is_coding_format_supported(ESCO_CODING_FORMAT_TRANSPNT) &&
338          osi_property_get_bool("bluetooth.hfp.swb.supported", true);  // TODO: add SWB for desktop
339 #endif
340 }
341 
342 // Checks the supported codecs
get_codec_capabilities(uint64_t codecs)343 bt_codecs get_codec_capabilities(uint64_t codecs) {
344   bt_codecs codec_list = {.offload_capable = offload_supported};
345 
346   for (auto c : cached_codecs) {
347     if (c.inner.codec & codecs) {
348       codec_list.codecs.push_back(c.inner);
349     }
350   }
351 
352   return codec_list;
353 }
354 
355 // Check if hardware offload is supported
get_offload_supported()356 bool get_offload_supported() { return offload_supported; }
357 
358 // Check if hardware offload is enabled
get_offload_enabled()359 bool get_offload_enabled() { return offload_supported && offload_enabled; }
360 
361 // Set offload enable/disable
enable_offload(bool enable)362 bool enable_offload(bool enable) {
363   if (!offload_supported && enable) {
364     bluetooth::log::error("Cannot enable SCO-offload since it is not supported.");
365     return false;
366   }
367   offload_enabled = enable;
368   return true;
369 }
370 
get_single_codec(int codec,bt_codec ** out)371 static bool get_single_codec(int codec, bt_codec** out) {
372   for (cached_codec_info& c : cached_codecs) {
373     if (c.inner.codec == static_cast<uint64_t>(codec)) {
374       *out = &c.inner;
375       return true;
376     }
377   }
378 
379   return false;
380 }
381 
382 constexpr uint8_t OFFLOAD_DATAPATH = 0x01;
383 
384 // Notify the codec datapath to lower layer for offload mode
set_codec_datapath(tBTA_AG_UUID_CODEC codec_uuid)385 void set_codec_datapath(tBTA_AG_UUID_CODEC codec_uuid) {
386   bool found;
387   bt_codec* codec;
388   uint8_t codec_id;
389 
390   if (codec_uuid == tBTA_AG_UUID_CODEC::UUID_CODEC_LC3 && get_offload_enabled()) {
391     bluetooth::log::error("Offload path for LC3 is not implemented.");
392     return;
393   }
394 
395   switch (codec_uuid) {
396     case tBTA_AG_UUID_CODEC::UUID_CODEC_CVSD:
397       codec_id = codec::CVSD;
398       break;
399     case tBTA_AG_UUID_CODEC::UUID_CODEC_MSBC:
400       codec_id = get_offload_enabled() ? codec::MSBC : codec::MSBC_TRANSPARENT;
401       break;
402     case tBTA_AG_UUID_CODEC::UUID_CODEC_LC3:
403       codec_id = get_offload_enabled() ? codec::LC3 : codec::MSBC_TRANSPARENT;
404       break;
405     default:
406       bluetooth::log::warn("Unsupported codec ({}). Won't set datapath.",
407                            bta_ag_uuid_codec_text(codec_uuid));
408       return;
409   }
410 
411   found = get_single_codec(codec_id, &codec);
412   if (!found) {
413     bluetooth::log::error("Failed to find codec config for codec ({}). Won't set datapath.",
414                           bta_ag_uuid_codec_text(codec_uuid));
415     return;
416   }
417 
418   bluetooth::log::info("Configuring datapath for codec ({})", bta_ag_uuid_codec_text(codec_uuid));
419   if (codec->codec == codec::MSBC && !get_offload_enabled()) {
420     bluetooth::log::error(
421             "Tried to configure offload data path for format ({}) with offload "
422             "disabled. Won't set datapath.",
423             bta_ag_uuid_codec_text(codec_uuid));
424     return;
425   }
426 
427   if (get_offload_enabled()) {
428     std::vector<uint8_t> data;
429     switch (codec_uuid) {
430       case tBTA_AG_UUID_CODEC::UUID_CODEC_CVSD:
431         data = {0x00};
432         break;
433       case tBTA_AG_UUID_CODEC::UUID_CODEC_MSBC:
434         data = {0x01};
435         break;
436       default:
437         break;
438     }
439 
440     GetInterface().ConfigureDataPath(hci_data_direction_t::CONTROLLER_TO_HOST, OFFLOAD_DATAPATH,
441                                      data);
442     GetInterface().ConfigureDataPath(hci_data_direction_t::HOST_TO_CONTROLLER, OFFLOAD_DATAPATH,
443                                      data);
444   }
445 }
446 
get_packet_size(int codec)447 size_t get_packet_size(int codec) {
448   for (const cached_codec_info& c : cached_codecs) {
449     if (c.inner.codec == static_cast<uint64_t>(codec)) {
450       return c.pkt_size;
451     }
452   }
453 
454   return kDefaultPacketSize;
455 }
456 
notify_sco_connection_change(RawAddress device,bool is_connected,int codec)457 void notify_sco_connection_change(RawAddress device, bool is_connected, int codec) {
458   int hci = GetAdapterIndex();
459   int fd = btsocket_open_mgmt(hci);
460   if (fd < 0) {
461     bluetooth::log::error("Failed to open mgmt channel, error= {}.", fd);
462     return;
463   }
464 
465   if (codec == codec::LC3) {
466     bluetooth::log::error("Offload path for LC3 is not implemented.");
467     return;
468   }
469 
470   int converted_codec;
471 
472   switch (codec) {
473     case codec::MSBC:
474       converted_codec = MGMT_SCO_CODEC_MSBC;
475       break;
476     case codec::MSBC_TRANSPARENT:
477       converted_codec = MGMT_SCO_CODEC_MSBC_TRANSPARENT;
478       break;
479     default:
480       converted_codec = MGMT_SCO_CODEC_CVSD;
481   }
482 
483   int ret = mgmt_notify_sco_connection_change(fd, hci, device, is_connected, converted_codec);
484   if (ret) {
485     bluetooth::log::error(
486             "Failed to notify HAL of connection change: hci {}, device {}, "
487             "connected {}, codec {}",
488             hci, device, is_connected, codec);
489   } else {
490     bluetooth::log::info(
491             "Notified HAL of connection change: hci {}, device {}, connected {}, "
492             "codec {}",
493             hci, device, is_connected, codec);
494   }
495 
496   close(fd);
497 }
498 
update_esco_parameters(enh_esco_params_t * p_parms)499 void update_esco_parameters(enh_esco_params_t* p_parms) {
500   if (get_offload_enabled()) {
501     p_parms->input_transport_unit_size = 0x01;
502     p_parms->output_transport_unit_size = 0x01;
503   } else {
504     p_parms->input_transport_unit_size = 0x00;
505     p_parms->output_transport_unit_size = 0x00;
506   }
507 }
508 }  // namespace hfp_hal_interface
509