• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  *
3  *  Copyright 2000-2012 Broadcom Corporation
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at:
8  *
9  *  http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  ******************************************************************************/
18 
19 /******************************************************************************
20  *
21  *  This file contains functions that handle SCO connections. This includes
22  *  operations such as connect, disconnect, change supported packet types.
23  *
24  ******************************************************************************/
25 
26 #include <base/logging.h>
27 #include <base/strings/stringprintf.h>
28 
29 #include <cstdint>
30 #include <string>
31 
32 #include "device/include/controller.h"
33 #include "osi/include/allocator.h"
34 #include "osi/include/log.h"
35 #include "osi/include/osi.h"
36 #include "stack/btm/btm_sec.h"
37 #include "stack/btm/security_device_record.h"
38 #include "stack/include/acl_api.h"
39 #include "stack/include/bt_hdr.h"
40 #include "stack/include/btm_api.h"
41 #include "stack/include/btm_api_types.h"
42 #include "stack/include/hci_error_code.h"
43 #include "types/class_of_device.h"
44 #include "types/raw_address.h"
45 
46 extern tBTM_CB btm_cb;
47 
48 namespace {
49 constexpr char kBtmLogTag[] = "SCO";
50 
GetLegacyHciInterface()51 const bluetooth::legacy::hci::Interface& GetLegacyHciInterface() {
52   return bluetooth::legacy::hci::GetInterface();
53 }
54 
55 };  // namespace
56 
57 /******************************************************************************/
58 /*               L O C A L    D A T A    D E F I N I T I O N S                */
59 /******************************************************************************/
60 
61 /* MACROs to convert from SCO packet types mask to ESCO and back */
62 #define BTM_SCO_PKT_TYPE_MASK \
63   (HCI_PKT_TYPES_MASK_HV1 | HCI_PKT_TYPES_MASK_HV2 | HCI_PKT_TYPES_MASK_HV3)
64 
65 /* Mask defining only the SCO types of an esco packet type */
66 #define BTM_ESCO_PKT_TYPE_MASK \
67   (ESCO_PKT_TYPES_MASK_HV1 | ESCO_PKT_TYPES_MASK_HV2 | ESCO_PKT_TYPES_MASK_HV3)
68 
69 #define BTM_ESCO_2_SCO(escotype) \
70   ((uint16_t)(((escotype)&BTM_ESCO_PKT_TYPE_MASK) << 5))
71 
72 /* Define masks for supported and exception 2.0 SCO packet types
73  */
74 #define BTM_SCO_SUPPORTED_PKTS_MASK                    \
75   (ESCO_PKT_TYPES_MASK_HV1 | ESCO_PKT_TYPES_MASK_HV2 | \
76    ESCO_PKT_TYPES_MASK_HV3 | ESCO_PKT_TYPES_MASK_EV3 | \
77    ESCO_PKT_TYPES_MASK_EV4 | ESCO_PKT_TYPES_MASK_EV5)
78 
79 #define BTM_SCO_EXCEPTION_PKTS_MASK                              \
80   (ESCO_PKT_TYPES_MASK_NO_2_EV3 | ESCO_PKT_TYPES_MASK_NO_3_EV3 | \
81    ESCO_PKT_TYPES_MASK_NO_2_EV5 | ESCO_PKT_TYPES_MASK_NO_3_EV5)
82 
83 /******************************************************************************/
84 /*            L O C A L    F U N C T I O N     P R O T O T Y P E S            */
85 /******************************************************************************/
86 static tBTM_STATUS BTM_ChangeEScoLinkParms(uint16_t sco_inx,
87                                            tBTM_CHG_ESCO_PARAMS* p_parms);
88 
89 static uint16_t btm_sco_voice_settings_to_legacy(enh_esco_params_t* p_parms);
90 
91 /*******************************************************************************
92  *
93  * Function         btm_esco_conn_rsp
94  *
95  * Description      This function is called upon receipt of an (e)SCO connection
96  *                  request event (BTM_ESCO_CONN_REQ_EVT) to accept or reject
97  *                  the request. Parameters used to negotiate eSCO links.
98  *                  If p_parms is NULL, then default values are used.
99  *                  If the link type of the incoming request is SCO, then only
100  *                  the tx_bw, max_latency, content format, and packet_types are
101  *                  valid.  The hci_status parameter should be
102  *                  ([0x0] to accept, [0x0d..0x0f] to reject)
103  *
104  * Returns          void
105  *
106  ******************************************************************************/
btm_esco_conn_rsp(uint16_t sco_inx,uint8_t hci_status,const RawAddress & bda,enh_esco_params_t * p_parms)107 static void btm_esco_conn_rsp(uint16_t sco_inx, uint8_t hci_status,
108                               const RawAddress& bda,
109                               enh_esco_params_t* p_parms) {
110   tSCO_CONN* p_sco = NULL;
111 
112   if (BTM_MAX_SCO_LINKS == 0) return;
113 
114   if (sco_inx < BTM_MAX_SCO_LINKS) p_sco = &btm_cb.sco_cb.sco_db[sco_inx];
115 
116   /* Reject the connect request if refused by caller or wrong state */
117   if (hci_status != HCI_SUCCESS || p_sco == NULL) {
118     if (p_sco) {
119       p_sco->state = (p_sco->state == SCO_ST_W4_CONN_RSP) ? SCO_ST_LISTENING
120                                                           : SCO_ST_UNUSED;
121     }
122     if (!btm_cb.sco_cb.esco_supported) {
123       btsnd_hcic_reject_conn(bda, hci_status);
124     } else {
125       btsnd_hcic_reject_esco_conn(bda, hci_status);
126     }
127   } else {
128     /* Connection is being accepted */
129     p_sco->state = SCO_ST_CONNECTING;
130     enh_esco_params_t* p_setup = &p_sco->esco.setup;
131     /* If parameters not specified use the default */
132     if (p_parms) {
133       *p_setup = *p_parms;
134     } else if (p_sco->esco.data.link_type == BTM_LINK_TYPE_SCO ||
135                !sco_peer_supports_esco_ev3(bda)) {
136       *p_setup = esco_parameters_for_codec(SCO_CODEC_CVSD_D1);
137     } else {
138       /* Use the last setup passed thru BTM_SetEscoMode (or defaults) */
139       *p_setup = btm_cb.sco_cb.def_esco_parms;
140     }
141     /* Use Enhanced Synchronous commands if supported */
142     if (controller_get_interface()
143             ->supports_enhanced_setup_synchronous_connection()) {
144       /* Use the saved SCO routing */
145       p_setup->input_data_path = p_setup->output_data_path = ESCO_DATA_PATH;
146 
147       BTM_TRACE_DEBUG(
148           "%s: txbw 0x%x, rxbw 0x%x, lat 0x%x, retrans 0x%02x, "
149           "pkt 0x%04x, path %u",
150           __func__, p_setup->transmit_bandwidth, p_setup->receive_bandwidth,
151           p_setup->max_latency_ms, p_setup->retransmission_effort,
152           p_setup->packet_types, p_setup->input_data_path);
153 
154       btsnd_hcic_enhanced_accept_synchronous_connection(bda, p_setup);
155 
156     } else {
157       /* Use legacy command if enhanced SCO setup is not supported */
158       uint16_t voice_content_format = btm_sco_voice_settings_to_legacy(p_setup);
159       btsnd_hcic_accept_esco_conn(
160           bda, p_setup->transmit_bandwidth, p_setup->receive_bandwidth,
161           p_setup->max_latency_ms, voice_content_format,
162           p_setup->retransmission_effort, p_setup->packet_types);
163     }
164   }
165 }
166 
167 // Return the active (first connected) SCO connection block
btm_get_active_sco()168 static tSCO_CONN* btm_get_active_sco() {
169   for (auto& link : btm_cb.sco_cb.sco_db) {
170     if (link.state == SCO_ST_CONNECTED) {
171       return &link;
172     }
173   }
174   return nullptr;
175 }
176 
177 /*******************************************************************************
178  *
179  * Function         btm_route_sco_data
180  *
181  * Description      Route received SCO data.
182  *
183  * Returns          void
184  *
185  ******************************************************************************/
btm_route_sco_data(BT_HDR * p_msg)186 void btm_route_sco_data(BT_HDR* p_msg) {
187   if (p_msg->len < 3) {
188     LOG_ERROR("Received incomplete SCO header");
189     osi_free(p_msg);
190     return;
191   }
192   uint8_t* payload = p_msg->data;
193   uint16_t handle_with_flags = 0;
194   uint8_t length = 0;
195   STREAM_TO_UINT16(handle_with_flags, payload);
196   STREAM_TO_UINT8(length, payload);
197   if (p_msg->len != length + 3) {
198     LOG_ERROR("Received invalid SCO data of size: %hhu, dropping", length);
199     osi_free(p_msg);
200     return;
201   }
202   uint16_t handle = handle_with_flags & 0xFFF;
203   ASSERT_LOG(handle <= 0xEFF, "Require handle <= 0xEFF, but is 0x%X", handle);
204   auto* active_sco = btm_get_active_sco();
205   if (active_sco != nullptr && active_sco->hci_handle == handle) {
206     // TODO: For MSBC, we need to decode here
207     bluetooth::audio::sco::write(payload, length);
208   }
209   osi_free(p_msg);
210   // For Chrome OS, we send the outgoing data after receiving an incoming one
211   uint8_t out_buf[BTM_SCO_DATA_SIZE_MAX];
212   auto size_read = bluetooth::audio::sco::read(out_buf, length);
213   auto data = std::vector<uint8_t>(out_buf, out_buf + size_read);
214   // TODO: For MSBC, we need to encode here
215   btm_send_sco_packet(std::move(data));
216 }
217 
btm_send_sco_packet(std::vector<uint8_t> data)218 void btm_send_sco_packet(std::vector<uint8_t> data) {
219   auto* active_sco = btm_get_active_sco();
220   if (active_sco == nullptr || data.empty()) {
221     return;
222   }
223   BT_HDR* packet = btm_sco_make_packet(std::move(data), active_sco->hci_handle);
224   bte_main_hci_send(packet, BT_EVT_TO_LM_HCI_SCO);
225 }
226 
227 // Build a SCO packet from uint8
btm_sco_make_packet(std::vector<uint8_t> data,uint16_t sco_handle)228 BT_HDR* btm_sco_make_packet(std::vector<uint8_t> data, uint16_t sco_handle) {
229   ASSERT_LOG(data.size() <= BTM_SCO_DATA_SIZE_MAX, "Invalid SCO data size: %zu",
230              data.size());
231   BT_HDR* p_buf = (BT_HDR*)osi_calloc(BT_SMALL_BUFFER_SIZE);
232   p_buf->event = BT_EVT_TO_LM_HCI_SCO;
233   // SCO header size is 3 per Core 5.2 Vol 4 Part E 5.4.3 figure 5.3
234   p_buf->len = data.size() + 3;
235   uint8_t* payload = p_buf->data;
236   UINT16_TO_STREAM(payload, sco_handle);
237   UINT8_TO_STREAM(payload, data.size());
238   ARRAY_TO_STREAM(payload, data.data(), static_cast<int>(data.size()));
239   return p_buf;
240 }
241 
242 /*******************************************************************************
243  *
244  * Function         btm_send_connect_request
245  *
246  * Description      This function is called to respond to SCO connect
247  *                  indications
248  *
249  * Returns          void
250  *
251  ******************************************************************************/
btm_send_connect_request(uint16_t acl_handle,enh_esco_params_t * p_setup)252 static tBTM_STATUS btm_send_connect_request(uint16_t acl_handle,
253                                             enh_esco_params_t* p_setup) {
254   /* Send connect request depending on version of spec */
255   if (!btm_cb.sco_cb.esco_supported) {
256     LOG(INFO) << __func__ << ": sending non-eSCO request for handle="
257               << unsigned(acl_handle);
258     btsnd_hcic_add_SCO_conn(acl_handle, BTM_ESCO_2_SCO(p_setup->packet_types));
259   } else {
260     /* Save the previous values in case command fails */
261     uint16_t saved_packet_types = p_setup->packet_types;
262     uint8_t saved_retransmission_effort = p_setup->retransmission_effort;
263     uint16_t saved_max_latency_ms = p_setup->max_latency_ms;
264 
265     uint16_t temp_packet_types =
266         (p_setup->packet_types &
267          static_cast<uint16_t>(BTM_SCO_SUPPORTED_PKTS_MASK) &
268          btm_cb.btm_sco_pkt_types_supported);
269 
270     /* OR in any exception packet types */
271     temp_packet_types |=
272         ((p_setup->packet_types & BTM_SCO_EXCEPTION_PKTS_MASK) |
273          (btm_cb.btm_sco_pkt_types_supported & BTM_SCO_EXCEPTION_PKTS_MASK));
274 
275     /* Finally, remove EDR eSCO if the remote device doesn't support it */
276     /* UPF25:  Only SCO was brought up in this case */
277     const RawAddress bd_addr = acl_address_from_handle(acl_handle);
278     if (bd_addr != RawAddress::kEmpty) {
279       if (!sco_peer_supports_esco_2m_phy(bd_addr)) {
280         BTM_TRACE_DEBUG("BTM Remote does not support 2-EDR eSCO");
281         temp_packet_types |=
282             (ESCO_PKT_TYPES_MASK_NO_2_EV3 | ESCO_PKT_TYPES_MASK_NO_2_EV5);
283       }
284       if (!sco_peer_supports_esco_3m_phy(bd_addr)) {
285         BTM_TRACE_DEBUG("BTM Remote does not support 3-EDR eSCO");
286         temp_packet_types |=
287             (ESCO_PKT_TYPES_MASK_NO_3_EV3 | ESCO_PKT_TYPES_MASK_NO_3_EV5);
288       }
289       if (!sco_peer_supports_esco_ev3(bd_addr)) {
290         BTM_TRACE_DEBUG("BTM Remote does not support EV3 eSCO");
291         // If EV3 is not supported, EV4 and EV% are not supported, either.
292         temp_packet_types &= ~BTM_ESCO_LINK_ONLY_MASK;
293         p_setup->retransmission_effort = ESCO_RETRANSMISSION_OFF;
294         p_setup->max_latency_ms = 10;
295       }
296 
297       /* Check to see if BR/EDR Secure Connections is being used
298       ** If so, we cannot use SCO-only packet types (HFP 1.7)
299       */
300       const bool local_supports_sc =
301           controller_get_interface()->supports_secure_connections();
302       const bool remote_supports_sc =
303           BTM_PeerSupportsSecureConnections(bd_addr);
304 
305       if (local_supports_sc && remote_supports_sc) {
306         temp_packet_types &= ~(BTM_SCO_PKT_TYPE_MASK);
307         if (temp_packet_types == 0) {
308           LOG_ERROR(
309               "SCO connection cannot support any packet types for "
310               "acl_handle:0x%04x",
311               acl_handle);
312           return BTM_WRONG_MODE;
313         }
314         LOG_DEBUG(
315             "Both local and remote controllers support SCO secure connections "
316             "handle:0x%04x pkt_types:0x%04x",
317             acl_handle, temp_packet_types);
318 
319       } else if (!local_supports_sc && !remote_supports_sc) {
320         LOG_DEBUG(
321             "Both local and remote controllers do not support secure "
322             "connections for handle:0x%04x",
323             acl_handle);
324       } else if (remote_supports_sc) {
325         LOG_DEBUG(
326             "Only remote controller supports secure connections for "
327             "handle:0x%04x",
328             acl_handle);
329       } else {
330         LOG_DEBUG(
331             "Only local controller supports secure connections for "
332             "handle:0x%04x",
333             acl_handle);
334       }
335     } else {
336       LOG_ERROR("Received SCO connect from unknown peer:%s",
337                 PRIVATE_ADDRESS(bd_addr));
338     }
339 
340     p_setup->packet_types = temp_packet_types;
341 
342     /* Use Enhanced Synchronous commands if supported */
343     if (controller_get_interface()
344             ->supports_enhanced_setup_synchronous_connection()) {
345       LOG_INFO("Sending enhanced SCO connect request over handle:0x%04x",
346                acl_handle);
347       /* Use the saved SCO routing */
348       p_setup->input_data_path = p_setup->output_data_path = ESCO_DATA_PATH;
349       LOG(INFO) << __func__ << std::hex << ": enhanced parameter list"
350                 << " txbw=0x" << unsigned(p_setup->transmit_bandwidth)
351                 << ", rxbw=0x" << unsigned(p_setup->receive_bandwidth)
352                 << ", latency_ms=0x" << unsigned(p_setup->max_latency_ms)
353                 << ", retransmit_effort=0x"
354                 << unsigned(p_setup->retransmission_effort) << ", pkt_type=0x"
355                 << unsigned(p_setup->packet_types) << ", path=0x"
356                 << unsigned(p_setup->input_data_path);
357       btsnd_hcic_enhanced_set_up_synchronous_connection(acl_handle, p_setup);
358       p_setup->packet_types = saved_packet_types;
359       p_setup->retransmission_effort = saved_retransmission_effort;
360       p_setup->max_latency_ms = saved_max_latency_ms;
361     } else { /* Use older command */
362       LOG_INFO("Sending eSCO connect request over handle:0x%04x", acl_handle);
363       uint16_t voice_content_format = btm_sco_voice_settings_to_legacy(p_setup);
364       LOG(INFO) << __func__ << std::hex << ": legacy parameter list"
365                 << " txbw=0x" << unsigned(p_setup->transmit_bandwidth)
366                 << ", rxbw=0x" << unsigned(p_setup->receive_bandwidth)
367                 << ", latency_ms=0x" << unsigned(p_setup->max_latency_ms)
368                 << ", retransmit_effort=0x"
369                 << unsigned(p_setup->retransmission_effort)
370                 << ", voice_content_format=0x" << unsigned(voice_content_format)
371                 << ", pkt_type=0x" << unsigned(p_setup->packet_types);
372       btsnd_hcic_setup_esco_conn(
373           acl_handle, p_setup->transmit_bandwidth, p_setup->receive_bandwidth,
374           p_setup->max_latency_ms, voice_content_format,
375           p_setup->retransmission_effort, p_setup->packet_types);
376     }
377   }
378 
379   return (BTM_CMD_STARTED);
380 }
381 
382 /*******************************************************************************
383  *
384  * Function         BTM_CreateSco
385  *
386  * Description      This function is called to create an SCO connection. If the
387  *                  "is_orig" flag is true, the connection will be originated,
388  *                  otherwise BTM will wait for the other side to connect.
389  *
390  *                  NOTE:  If BTM_IGNORE_SCO_PKT_TYPE is passed in the pkt_types
391  *                      parameter the default packet types is used.
392  *
393  * Returns          BTM_UNKNOWN_ADDR if the ACL connection is not up
394  *                  BTM_BUSY         if another SCO being set up to
395  *                                   the same BD address
396  *                  BTM_NO_RESOURCES if the max SCO limit has been reached
397  *                  BTM_CMD_STARTED  if the connection establishment is started.
398  *                                   In this case, "*p_sco_inx" is filled in
399  *                                   with the sco index used for the connection.
400  *
401  ******************************************************************************/
BTM_CreateSco(const RawAddress * remote_bda,bool is_orig,uint16_t pkt_types,uint16_t * p_sco_inx,tBTM_SCO_CB * p_conn_cb,tBTM_SCO_CB * p_disc_cb)402 tBTM_STATUS BTM_CreateSco(const RawAddress* remote_bda, bool is_orig,
403                           uint16_t pkt_types, uint16_t* p_sco_inx,
404                           tBTM_SCO_CB* p_conn_cb, tBTM_SCO_CB* p_disc_cb) {
405   enh_esco_params_t* p_setup;
406   tSCO_CONN* p = &btm_cb.sco_cb.sco_db[0];
407   uint16_t xx;
408   uint16_t acl_handle = HCI_INVALID_HANDLE;
409   *p_sco_inx = BTM_INVALID_SCO_INDEX;
410 
411   if (BTM_MAX_SCO_LINKS == 0) {
412     return BTM_NO_RESOURCES;
413   }
414 
415   /* If originating, ensure that there is an ACL connection to the BD Address */
416 
417   if (is_orig) {
418     if (!remote_bda) {
419       LOG(ERROR) << __func__ << ": remote_bda is null";
420       return BTM_ILLEGAL_VALUE;
421     }
422     acl_handle = BTM_GetHCIConnHandle(*remote_bda, BT_TRANSPORT_BR_EDR);
423     if (acl_handle == HCI_INVALID_HANDLE) {
424       LOG(ERROR) << __func__ << ": cannot find ACL handle for remote device "
425                  << remote_bda;
426       return BTM_UNKNOWN_ADDR;
427     }
428   }
429 
430   if (remote_bda) {
431     /* If any SCO is being established to the remote BD address, refuse this */
432     for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
433       if (((p->state == SCO_ST_CONNECTING) || (p->state == SCO_ST_LISTENING) ||
434            (p->state == SCO_ST_PEND_UNPARK)) &&
435           (p->esco.data.bd_addr == *remote_bda)) {
436         LOG(ERROR) << __func__ << ": a sco connection is already going on for "
437                    << *remote_bda << ", at state " << unsigned(p->state);
438         return BTM_BUSY;
439       }
440     }
441   } else {
442     /* Support only 1 wildcard BD address at a time */
443     for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
444       if ((p->state == SCO_ST_LISTENING) && (!p->rem_bd_known)) {
445         LOG(ERROR)
446             << __func__
447             << ": remote_bda is null and not known and we are still listening";
448         return BTM_BUSY;
449       }
450     }
451   }
452 
453   /* Try to find an unused control block, and kick off the SCO establishment */
454   for (xx = 0, p = &btm_cb.sco_cb.sco_db[0]; xx < BTM_MAX_SCO_LINKS;
455        xx++, p++) {
456     if (p->state == SCO_ST_UNUSED) {
457       if (remote_bda) {
458         if (is_orig) {
459           // can not create SCO link if in park mode
460           tBTM_PM_STATE state;
461           if (BTM_ReadPowerMode(*remote_bda, &state)) {
462             if (state == BTM_PM_ST_SNIFF || state == BTM_PM_ST_PARK ||
463                 state == BTM_PM_ST_PENDING) {
464               LOG(INFO) << __func__ << ": " << *remote_bda
465                         << " in sniff, park or pending mode "
466                         << unsigned(state);
467               if (!BTM_SetLinkPolicyActiveMode(*remote_bda)) {
468                 LOG_WARN("Unable to set link policy active");
469               }
470               p->state = SCO_ST_PEND_UNPARK;
471             }
472           } else {
473             LOG(ERROR) << __func__ << ": failed to read power mode for "
474                        << *remote_bda;
475           }
476         }
477         p->esco.data.bd_addr = *remote_bda;
478         p->rem_bd_known = true;
479       } else
480         p->rem_bd_known = false;
481 
482       p_setup = &p->esco.setup;
483       *p_setup = btm_cb.sco_cb.def_esco_parms;
484 
485       /* Determine the packet types */
486       p_setup->packet_types = pkt_types & BTM_SCO_SUPPORTED_PKTS_MASK &
487                               btm_cb.btm_sco_pkt_types_supported;
488       /* OR in any exception packet types */
489       if (controller_get_interface()->get_bt_version()->hci_version >=
490           HCI_PROTO_VERSION_2_0) {
491         p_setup->packet_types |=
492             (pkt_types & BTM_SCO_EXCEPTION_PKTS_MASK) |
493             (btm_cb.btm_sco_pkt_types_supported & BTM_SCO_EXCEPTION_PKTS_MASK);
494       }
495 
496       p->p_conn_cb = p_conn_cb;
497       p->p_disc_cb = p_disc_cb;
498       p->hci_handle = HCI_INVALID_HANDLE;
499       p->is_orig = is_orig;
500 
501       if (p->state != SCO_ST_PEND_UNPARK) {
502         if (is_orig) {
503           /* If role change is in progress, do not proceed with SCO setup
504            * Wait till role change is complete */
505           if (!acl_is_switch_role_idle(*remote_bda, BT_TRANSPORT_BR_EDR)) {
506             BTM_TRACE_API("Role Change is in progress for ACL handle 0x%04x",
507                           acl_handle);
508             p->state = SCO_ST_PEND_ROLECHANGE;
509           }
510         }
511       }
512 
513       if (p->state != SCO_ST_PEND_UNPARK &&
514           p->state != SCO_ST_PEND_ROLECHANGE) {
515         if (is_orig) {
516           LOG_DEBUG("Initiating (e)SCO link for ACL handle:0x%04x", acl_handle);
517 
518           if ((btm_send_connect_request(acl_handle, p_setup)) !=
519               BTM_CMD_STARTED) {
520             LOG(ERROR) << __func__ << ": failed to send connect request for "
521                        << *remote_bda;
522             return (BTM_NO_RESOURCES);
523           }
524 
525           p->state = SCO_ST_CONNECTING;
526         } else {
527           LOG_DEBUG("Listening for (e)SCO on ACL handle:0x%04x", acl_handle);
528           p->state = SCO_ST_LISTENING;
529         }
530       }
531 
532       *p_sco_inx = xx;
533       LOG_DEBUG("SCO connection successfully requested");
534       if (p->state == SCO_ST_CONNECTING) {
535         BTM_LogHistory(
536             kBtmLogTag, *remote_bda, "Connecting",
537             base::StringPrintf("local initiated acl:0x%04x", acl_handle));
538       }
539       return BTM_CMD_STARTED;
540     }
541   }
542 
543   /* If here, all SCO blocks in use */
544   LOG(ERROR) << __func__ << ": all SCO control blocks are in use";
545   return BTM_NO_RESOURCES;
546 }
547 
548 /*******************************************************************************
549  *
550  * Function         btm_sco_chk_pend_unpark
551  *
552  * Description      This function is called by BTIF when there is a mode change
553  *                  event to see if there are SCO commands waiting for the
554  *                  unpark.
555  *
556  * Returns          void
557  *
558  ******************************************************************************/
btm_sco_chk_pend_unpark(tHCI_STATUS hci_status,uint16_t hci_handle)559 void btm_sco_chk_pend_unpark(tHCI_STATUS hci_status, uint16_t hci_handle) {
560   tSCO_CONN* p = &btm_cb.sco_cb.sco_db[0];
561   for (uint16_t xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
562     uint16_t acl_handle =
563         BTM_GetHCIConnHandle(p->esco.data.bd_addr, BT_TRANSPORT_BR_EDR);
564     if ((p->state == SCO_ST_PEND_UNPARK) && (acl_handle == hci_handle)) {
565       LOG(INFO) << __func__ << ": " << p->esco.data.bd_addr
566                 << " unparked, sending connection request, acl_handle="
567                 << unsigned(acl_handle)
568                 << ", hci_status=" << unsigned(hci_status);
569       if (btm_send_connect_request(acl_handle, &p->esco.setup) ==
570           BTM_CMD_STARTED) {
571         p->state = SCO_ST_CONNECTING;
572       } else {
573         LOG(ERROR) << __func__ << ": failed to send connection request for "
574                    << p->esco.data.bd_addr;
575       }
576     }
577   }
578 }
579 
580 /*******************************************************************************
581  *
582  * Function         btm_sco_chk_pend_rolechange
583  *
584  * Description      This function is called by BTIF when there is a role change
585  *                  event to see if there are SCO commands waiting for the role
586  *                  change.
587  *
588  * Returns          void
589  *
590  ******************************************************************************/
btm_sco_chk_pend_rolechange(uint16_t hci_handle)591 void btm_sco_chk_pend_rolechange(uint16_t hci_handle) {
592   uint16_t xx;
593   uint16_t acl_handle;
594   tSCO_CONN* p = &btm_cb.sco_cb.sco_db[0];
595 
596   for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
597     if ((p->state == SCO_ST_PEND_ROLECHANGE) &&
598         ((acl_handle = BTM_GetHCIConnHandle(
599               p->esco.data.bd_addr, BT_TRANSPORT_BR_EDR)) == hci_handle))
600 
601     {
602       BTM_TRACE_API(
603           "btm_sco_chk_pend_rolechange -> (e)SCO Link for ACL handle 0x%04x",
604           acl_handle);
605 
606       if ((btm_send_connect_request(acl_handle, &p->esco.setup)) ==
607           BTM_CMD_STARTED)
608         p->state = SCO_ST_CONNECTING;
609     }
610   }
611 }
612 
613 /*******************************************************************************
614  *
615  * Function        btm_sco_disc_chk_pend_for_modechange
616  *
617  * Description     This function is called by btm when there is a mode change
618  *                 event to see if there are SCO  disconnect commands waiting
619  *                 for the mode change.
620  *
621  * Returns         void
622  *
623  ******************************************************************************/
btm_sco_disc_chk_pend_for_modechange(uint16_t hci_handle)624 void btm_sco_disc_chk_pend_for_modechange(uint16_t hci_handle) {
625   tSCO_CONN* p = &btm_cb.sco_cb.sco_db[0];
626 
627   LOG_DEBUG(
628       "Checking for SCO pending mode change events hci_handle:0x%04x "
629       "p->state:%s",
630       hci_handle, sco_state_text(p->state).c_str());
631 
632   for (uint16_t xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
633     if ((p->state == SCO_ST_PEND_MODECHANGE) &&
634         (BTM_GetHCIConnHandle(p->esco.data.bd_addr, BT_TRANSPORT_BR_EDR)) ==
635             hci_handle)
636 
637     {
638       LOG_DEBUG("Removing SCO Link handle 0x%04x", p->hci_handle);
639       BTM_RemoveSco(xx);
640     }
641   }
642 }
643 
644 /*******************************************************************************
645  *
646  * Function         btm_sco_conn_req
647  *
648  * Description      This function is called by BTU HCIF when an SCO connection
649  *                  request is received from a remote.
650  *
651  * Returns          void
652  *
653  ******************************************************************************/
btm_sco_conn_req(const RawAddress & bda,const DEV_CLASS & dev_class,uint8_t link_type)654 void btm_sco_conn_req(const RawAddress& bda, const DEV_CLASS& dev_class,
655                       uint8_t link_type) {
656   tSCO_CB* p_sco = &btm_cb.sco_cb;
657   tSCO_CONN* p = &p_sco->sco_db[0];
658   tBTM_ESCO_CONN_REQ_EVT_DATA evt_data = {};
659 
660   for (uint16_t sco_index = 0; sco_index < BTM_MAX_SCO_LINKS;
661        sco_index++, p++) {
662     /*
663      * If the sco state is in the SCO_ST_CONNECTING state, we still need
664      * to return accept sco to avoid race conditon for sco creation
665      */
666     bool rem_bd_matches = p->rem_bd_known && p->esco.data.bd_addr == bda;
667     if (((p->state == SCO_ST_CONNECTING) && rem_bd_matches) ||
668         ((p->state == SCO_ST_LISTENING) &&
669          (rem_bd_matches || !p->rem_bd_known))) {
670       /* If this was a wildcard, it is not one any more */
671       p->rem_bd_known = true;
672       p->esco.data.link_type = link_type;
673       p->state = SCO_ST_W4_CONN_RSP;
674       p->esco.data.bd_addr = bda;
675 
676       /* If no callback, auto-accept the connection if packet types match */
677       if (!p->esco.p_esco_cback) {
678         /* If requesting eSCO reject if default parameters are SCO only */
679         if ((link_type == BTM_LINK_TYPE_ESCO &&
680              !(p_sco->def_esco_parms.packet_types & BTM_ESCO_LINK_ONLY_MASK) &&
681              ((p_sco->def_esco_parms.packet_types &
682                BTM_SCO_EXCEPTION_PKTS_MASK) == BTM_SCO_EXCEPTION_PKTS_MASK))
683 
684             /* Reject request if SCO is desired but no SCO packets delected */
685             ||
686             (link_type == BTM_LINK_TYPE_SCO &&
687              !(p_sco->def_esco_parms.packet_types & BTM_SCO_LINK_ONLY_MASK))) {
688           btm_esco_conn_rsp(sco_index, HCI_ERR_HOST_REJECT_RESOURCES, bda,
689                             nullptr);
690         } else {
691           /* Accept the request */
692           btm_esco_conn_rsp(sco_index, HCI_SUCCESS, bda, nullptr);
693         }
694       } else {
695         /* Notify upper layer of connect indication */
696         evt_data.bd_addr = bda;
697         memcpy(evt_data.dev_class, dev_class, DEV_CLASS_LEN);
698         evt_data.link_type = link_type;
699         evt_data.sco_inx = sco_index;
700         tBTM_ESCO_EVT_DATA btm_esco_evt_data = {};
701         btm_esco_evt_data.conn_evt = evt_data;
702         p->esco.p_esco_cback(BTM_ESCO_CONN_REQ_EVT, &btm_esco_evt_data);
703       }
704 
705       return;
706     }
707   }
708 
709   /* If here, no one wants the SCO connection. Reject it */
710   BTM_TRACE_WARNING("%s: rejecting SCO for %s", __func__,
711                     bda.ToString().c_str());
712   btm_esco_conn_rsp(BTM_MAX_SCO_LINKS, HCI_ERR_HOST_REJECT_RESOURCES, bda,
713                     nullptr);
714 }
715 
716 /*******************************************************************************
717  *
718  * Function         btm_sco_connected
719  *
720  * Description      This function is called by BTIF when an (e)SCO connection
721  *                  is connected.
722  *
723  * Returns          void
724  *
725  ******************************************************************************/
btm_sco_connected(const RawAddress & bda,uint16_t hci_handle,tBTM_ESCO_DATA * p_esco_data)726 void btm_sco_connected(const RawAddress& bda, uint16_t hci_handle,
727                        tBTM_ESCO_DATA* p_esco_data) {
728   tSCO_CONN* p = &btm_cb.sco_cb.sco_db[0];
729   uint16_t xx;
730   bool spt = false;
731   tBTM_CHG_ESCO_PARAMS parms = {};
732 
733   for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
734     if (((p->state == SCO_ST_CONNECTING) || (p->state == SCO_ST_LISTENING) ||
735          (p->state == SCO_ST_W4_CONN_RSP)) &&
736         (p->rem_bd_known) && (p->esco.data.bd_addr == bda)) {
737       BTM_LogHistory(
738           kBtmLogTag, bda, "Connection created",
739           base::StringPrintf("sco_idx:%hu handle:0x%04x ", xx, hci_handle));
740 
741       if (p->state == SCO_ST_LISTENING) spt = true;
742 
743       p->state = SCO_ST_CONNECTED;
744       p->hci_handle = hci_handle;
745 
746       BTM_LogHistory(kBtmLogTag, bda, "Connection success",
747                      base::StringPrintf("handle:0x%04x %s", hci_handle,
748                                         (spt) ? "listener" : "initiator"));
749 
750       if (!btm_cb.sco_cb.esco_supported) {
751         p->esco.data.link_type = BTM_LINK_TYPE_SCO;
752         if (spt) {
753           parms.packet_types = p->esco.setup.packet_types;
754           /* Keep the other parameters the same for SCO */
755           parms.max_latency_ms = p->esco.setup.max_latency_ms;
756           parms.retransmission_effort = p->esco.setup.retransmission_effort;
757 
758           BTM_ChangeEScoLinkParms(xx, &parms);
759         }
760       } else {
761         if (p_esco_data) p->esco.data = *p_esco_data;
762       }
763 
764       (*p->p_conn_cb)(xx);
765 
766       bluetooth::audio::sco::open();
767 
768       return;
769     }
770   }
771 }
772 
773 /*******************************************************************************
774  *
775  * Function         btm_sco_connection_failed
776  *
777  * Description      This function is called by BTIF when an (e)SCO connection
778  *                  setup is failed.
779  *
780  * Returns          void
781  *
782  ******************************************************************************/
btm_sco_connection_failed(tHCI_STATUS hci_status,const RawAddress & bda,uint16_t hci_handle,tBTM_ESCO_DATA * p_esco_data)783 void btm_sco_connection_failed(tHCI_STATUS hci_status, const RawAddress& bda,
784                                uint16_t hci_handle,
785                                tBTM_ESCO_DATA* p_esco_data) {
786   tSCO_CONN* p = &btm_cb.sco_cb.sco_db[0];
787   uint16_t xx;
788 
789   for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
790     if (((p->state == SCO_ST_CONNECTING) || (p->state == SCO_ST_LISTENING) ||
791          (p->state == SCO_ST_W4_CONN_RSP)) &&
792         (p->rem_bd_known) &&
793         (p->esco.data.bd_addr == bda || bda == RawAddress::kEmpty)) {
794       /* Report the error if originator, otherwise remain in Listen mode */
795       if (p->is_orig) {
796         LOG_DEBUG("SCO initiating connection failed handle:0x%04x reason:%s",
797                   hci_handle, hci_error_code_text(hci_status).c_str());
798         switch (hci_status) {
799           case HCI_ERR_ROLE_SWITCH_PENDING:
800             /* If role switch is pending, we need try again after role switch
801              * is complete */
802             p->state = SCO_ST_PEND_ROLECHANGE;
803             break;
804           case HCI_ERR_LMP_ERR_TRANS_COLLISION:
805             /* Avoid calling disconnect callback because of sco creation race
806              */
807             break;
808           default: /* Notify client about SCO failure */
809             p->state = SCO_ST_UNUSED;
810             (*p->p_disc_cb)(xx);
811         }
812         BTM_LogHistory(
813             kBtmLogTag, bda, "Connection failed",
814             base::StringPrintf(
815                 "locally_initiated reason:%s",
816                 hci_reason_code_text(static_cast<tHCI_REASON>(hci_status))
817                     .c_str()));
818       } else {
819         LOG_DEBUG("SCO terminating connection failed handle:0x%04x reason:%s",
820                   hci_handle, hci_error_code_text(hci_status).c_str());
821         if (p->state == SCO_ST_CONNECTING) {
822           p->state = SCO_ST_UNUSED;
823           (*p->p_disc_cb)(xx);
824         } else
825           p->state = SCO_ST_LISTENING;
826         BTM_LogHistory(
827             kBtmLogTag, bda, "Connection failed",
828             base::StringPrintf(
829                 "remote_initiated reason:%s",
830                 hci_reason_code_text(static_cast<tHCI_REASON>(hci_status))
831                     .c_str()));
832       }
833       return;
834     }
835   }
836 }
837 
838 /*******************************************************************************
839  *
840  * Function         BTM_RemoveSco
841  *
842  * Description      This function is called to remove a specific SCO connection.
843  *
844  * Returns          status of the operation
845  *
846  ******************************************************************************/
BTM_RemoveSco(uint16_t sco_inx)847 tBTM_STATUS BTM_RemoveSco(uint16_t sco_inx) {
848   tSCO_CONN* p = &btm_cb.sco_cb.sco_db[sco_inx];
849   tBTM_PM_STATE state = BTM_PM_ST_INVALID;
850 
851   BTM_TRACE_DEBUG("%s", __func__);
852 
853   if (BTM_MAX_SCO_LINKS == 0) {
854     return BTM_NO_RESOURCES;
855   }
856 
857   /* Validity check */
858   if ((sco_inx >= BTM_MAX_SCO_LINKS) || (p->state == SCO_ST_UNUSED))
859     return (BTM_UNKNOWN_ADDR);
860 
861   /* If no HCI handle, simply drop the connection and return */
862   if (p->hci_handle == HCI_INVALID_HANDLE || p->state == SCO_ST_PEND_UNPARK) {
863     p->hci_handle = HCI_INVALID_HANDLE;
864     p->state = SCO_ST_UNUSED;
865     p->esco.p_esco_cback = NULL; /* Deregister the eSCO event callback */
866     return (BTM_SUCCESS);
867   }
868 
869   if (BTM_ReadPowerMode(p->esco.data.bd_addr, &state) &&
870       (state == BTM_PM_ST_PENDING)) {
871     BTM_TRACE_DEBUG("%s: BTM_PM_ST_PENDING for ACL mapped with SCO Link 0x%04x",
872                     __func__, p->hci_handle);
873     p->state = SCO_ST_PEND_MODECHANGE;
874     return (BTM_CMD_STARTED);
875   }
876 
877   tSCO_STATE old_state = p->state;
878   p->state = SCO_ST_DISCONNECTING;
879 
880   GetLegacyHciInterface().Disconnect(p->Handle(), HCI_ERR_PEER_USER);
881 
882   LOG_DEBUG("Disconnecting link sco_handle:0x%04x peer:%s", p->Handle(),
883             PRIVATE_ADDRESS(p->esco.data.bd_addr));
884   BTM_LogHistory(
885       kBtmLogTag, p->esco.data.bd_addr, "Disconnecting",
886       base::StringPrintf("local initiated handle:0x%04x previous_state:%s",
887                          p->Handle(), sco_state_text(old_state).c_str()));
888   return (BTM_CMD_STARTED);
889 }
890 
BTM_RemoveSco(const RawAddress & bda)891 void BTM_RemoveSco(const RawAddress& bda) {
892   tSCO_CONN* p = &btm_cb.sco_cb.sco_db[0];
893   uint16_t xx;
894 
895   for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
896     if (p->rem_bd_known && p->esco.data.bd_addr == bda) {
897       BTM_RemoveSco(xx);
898     }
899   }
900 }
901 
902 /*******************************************************************************
903  *
904  * Function         btm_sco_removed
905  *
906  * Description      This function is called by lower layers when an
907  *                  disconnect is received.
908  *
909  * Returns          true if the link is known about, else false
910  *
911  ******************************************************************************/
btm_sco_removed(uint16_t hci_handle,tHCI_REASON reason)912 bool btm_sco_removed(uint16_t hci_handle, tHCI_REASON reason) {
913   tSCO_CONN* p = &btm_cb.sco_cb.sco_db[0];
914   uint16_t xx;
915 
916   p = &btm_cb.sco_cb.sco_db[0];
917   for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
918     if ((p->state != SCO_ST_UNUSED) && (p->state != SCO_ST_LISTENING) &&
919         (p->hci_handle == hci_handle)) {
920       p->state = SCO_ST_UNUSED;
921       p->hci_handle = HCI_INVALID_HANDLE;
922       p->rem_bd_known = false;
923       p->esco.p_esco_cback = NULL; /* Deregister eSCO callback */
924       (*p->p_disc_cb)(xx);
925       LOG_DEBUG("Disconnected SCO link handle:%hu reason:%s", hci_handle,
926                 hci_reason_code_text(reason).c_str());
927       return true;
928     }
929   }
930   return false;
931 }
932 
btm_sco_on_esco_connect_request(const RawAddress & bda,const bluetooth::types::ClassOfDevice & cod)933 void btm_sco_on_esco_connect_request(
934     const RawAddress& bda, const bluetooth::types::ClassOfDevice& cod) {
935   LOG_DEBUG("Remote ESCO connect request remote:%s cod:%s",
936             PRIVATE_ADDRESS(bda), cod.ToString().c_str());
937   btm_sco_conn_req(bda, cod.cod, BTM_LINK_TYPE_ESCO);
938 }
939 
btm_sco_on_sco_connect_request(const RawAddress & bda,const bluetooth::types::ClassOfDevice & cod)940 void btm_sco_on_sco_connect_request(
941     const RawAddress& bda, const bluetooth::types::ClassOfDevice& cod) {
942   LOG_DEBUG("Remote SCO connect request remote:%s cod:%s", PRIVATE_ADDRESS(bda),
943             cod.ToString().c_str());
944   btm_sco_conn_req(bda, cod.cod, BTM_LINK_TYPE_SCO);
945 }
946 
btm_sco_on_disconnected(uint16_t hci_handle,tHCI_REASON reason)947 void btm_sco_on_disconnected(uint16_t hci_handle, tHCI_REASON reason) {
948   tSCO_CONN* p_sco = btm_cb.sco_cb.get_sco_connection_from_handle(hci_handle);
949   if (p_sco == nullptr) {
950     LOG_ERROR("Unable to find sco connection");
951     return;
952   }
953 
954   if (!p_sco->is_active()) {
955     LOG_ERROR("Connection is not active handle:0x%04x reason:%s", hci_handle,
956               hci_reason_code_text(reason).c_str());
957     return;
958   }
959 
960   if (p_sco->state == SCO_ST_LISTENING) {
961     LOG_ERROR("Connection is in listening state handle:0x%04x reason:%s",
962               hci_handle, hci_reason_code_text(reason).c_str());
963     return;
964   }
965 
966   const RawAddress bd_addr(p_sco->esco.data.bd_addr);
967 
968   p_sco->state = SCO_ST_UNUSED;
969   p_sco->hci_handle = HCI_INVALID_HANDLE;
970   p_sco->rem_bd_known = false;
971   p_sco->esco.p_esco_cback = NULL; /* Deregister eSCO callback */
972   (*p_sco->p_disc_cb)(btm_cb.sco_cb.get_index(p_sco));
973   LOG_DEBUG("Disconnected SCO link handle:%hu reason:%s", hci_handle,
974             hci_reason_code_text(reason).c_str());
975   BTM_LogHistory(kBtmLogTag, bd_addr, "Disconnected",
976                  base::StringPrintf("handle:0x%04x reason:%s", hci_handle,
977                                     hci_reason_code_text(reason).c_str()));
978 
979   bluetooth::audio::sco::cleanup();
980 }
981 
982 /*******************************************************************************
983  *
984  * Function         btm_sco_acl_removed
985  *
986  * Description      This function is called when an ACL connection is
987  *                  removed. If the BD address is NULL, it is assumed that
988  *                  the local device is down, and all SCO links are removed.
989  *                  If a specific BD address is passed, only SCO connections
990  *                  to that BD address are removed.
991  *
992  * Returns          void
993  *
994  ******************************************************************************/
btm_sco_acl_removed(const RawAddress * bda)995 void btm_sco_acl_removed(const RawAddress* bda) {
996   tSCO_CONN* p = &btm_cb.sco_cb.sco_db[0];
997   uint16_t xx;
998 
999   for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
1000     if (p->state != SCO_ST_UNUSED) {
1001       if ((!bda) || (p->esco.data.bd_addr == *bda && p->rem_bd_known)) {
1002         p->state = SCO_ST_UNUSED;
1003         p->esco.p_esco_cback = NULL; /* Deregister eSCO callback */
1004         (*p->p_disc_cb)(xx);
1005       }
1006     }
1007   }
1008 }
1009 
1010 /*******************************************************************************
1011  *
1012  * Function         BTM_ReadScoBdAddr
1013  *
1014  * Description      This function is read the remote BD Address for a specific
1015  *                  SCO connection,
1016  *
1017  * Returns          pointer to BD address or NULL if not known
1018  *
1019  ******************************************************************************/
BTM_ReadScoBdAddr(uint16_t sco_inx)1020 const RawAddress* BTM_ReadScoBdAddr(uint16_t sco_inx) {
1021   tSCO_CONN* p = &btm_cb.sco_cb.sco_db[sco_inx];
1022 
1023   /* Validity check */
1024   if ((sco_inx < BTM_MAX_SCO_LINKS) && (p->rem_bd_known))
1025     return &(p->esco.data.bd_addr);
1026   else
1027     return (NULL);
1028 }
1029 
1030 /*******************************************************************************
1031  *
1032  * Function         BTM_SetEScoMode
1033  *
1034  * Description      This function sets up the negotiated parameters for SCO or
1035  *                  eSCO, and sets as the default mode used for outgoing calls
1036  *                  to BTM_CreateSco.  It does not change any currently active
1037  *                  (e)SCO links.
1038  *                  Note:  Incoming (e)SCO connections will always use packet
1039  *                      types supported by the controller.  If eSCO is not
1040  *                      desired the feature should be disabled in the
1041  *                      controller's feature mask.
1042  *
1043  * Returns          BTM_SUCCESS if the successful.
1044  *                  BTM_BUSY if there are one or more active (e)SCO links.
1045  *
1046  ******************************************************************************/
BTM_SetEScoMode(enh_esco_params_t * p_parms)1047 tBTM_STATUS BTM_SetEScoMode(enh_esco_params_t* p_parms) {
1048   ASSERT_LOG(p_parms != nullptr, "eSCO parameters must have a value");
1049   enh_esco_params_t* p_def = &btm_cb.sco_cb.def_esco_parms;
1050 
1051   if (btm_cb.sco_cb.esco_supported) {
1052     *p_def = *p_parms;
1053     LOG_DEBUG(
1054         "Setting eSCO mode parameters txbw:0x%08x rxbw:0x%08x max_lat:0x%04x"
1055         " pkt:0x%04x rtx_effort:0x%02x",
1056         p_def->transmit_bandwidth, p_def->receive_bandwidth,
1057         p_def->max_latency_ms, p_def->packet_types,
1058         p_def->retransmission_effort);
1059   } else {
1060     /* Load defaults for SCO only */
1061     *p_def = esco_parameters_for_codec(SCO_CODEC_CVSD_D1);
1062     LOG_WARN("eSCO not supported so setting SCO parameters instead");
1063     LOG_DEBUG(
1064         "Setting SCO mode parameters txbw:0x%08x rxbw:0x%08x max_lat:0x%04x"
1065         " pkt:0x%04x rtx_effort:0x%02x",
1066         p_def->transmit_bandwidth, p_def->receive_bandwidth,
1067         p_def->max_latency_ms, p_def->packet_types,
1068         p_def->retransmission_effort);
1069   }
1070   return BTM_SUCCESS;
1071 }
1072 
1073 /*******************************************************************************
1074  *
1075  * Function         BTM_RegForEScoEvts
1076  *
1077  * Description      This function registers a SCO event callback with the
1078  *                  specified instance.  It should be used to received
1079  *                  connection indication events and change of link parameter
1080  *                  events.
1081  *
1082  * Returns          BTM_SUCCESS if the successful.
1083  *                  BTM_ILLEGAL_VALUE if there is an illegal sco_inx
1084  *                  BTM_MODE_UNSUPPORTED if controller version is not BT1.2 or
1085  *                          later or does not support eSCO.
1086  *
1087  ******************************************************************************/
BTM_RegForEScoEvts(uint16_t sco_inx,tBTM_ESCO_CBACK * p_esco_cback)1088 tBTM_STATUS BTM_RegForEScoEvts(uint16_t sco_inx,
1089                                tBTM_ESCO_CBACK* p_esco_cback) {
1090   if (BTM_MAX_SCO_LINKS == 0) {
1091     return BTM_MODE_UNSUPPORTED;
1092   }
1093 
1094   if (!btm_cb.sco_cb.esco_supported) {
1095     btm_cb.sco_cb.sco_db[sco_inx].esco.p_esco_cback = NULL;
1096     return (BTM_MODE_UNSUPPORTED);
1097   }
1098 
1099   if (sco_inx < BTM_MAX_SCO_LINKS &&
1100       btm_cb.sco_cb.sco_db[sco_inx].state != SCO_ST_UNUSED) {
1101     btm_cb.sco_cb.sco_db[sco_inx].esco.p_esco_cback = p_esco_cback;
1102     return (BTM_SUCCESS);
1103   }
1104   return (BTM_ILLEGAL_VALUE);
1105 }
1106 
1107 /*******************************************************************************
1108  *
1109  * Function         BTM_ChangeEScoLinkParms
1110  *
1111  * Description      This function requests renegotiation of the parameters on
1112  *                  the current eSCO Link.  If any of the changes are accepted
1113  *                  by the controllers, the BTM_ESCO_CHG_EVT event is sent in
1114  *                  the tBTM_ESCO_CBACK function with the current settings of
1115  *                  the link. The callback is registered through the call to
1116  *                  BTM_SetEScoMode.
1117  *
1118  *                  Note: If called over a SCO link (including 1.1 controller),
1119  *                        a change packet type request is sent out instead.
1120  *
1121  * Returns          BTM_CMD_STARTED if command is successfully initiated.
1122  *                  BTM_NO_RESOURCES - not enough resources to initiate command.
1123  *                  BTM_WRONG_MODE if no connection with a peer device or bad
1124  *                                 sco_inx.
1125  *
1126  ******************************************************************************/
BTM_ChangeEScoLinkParms(uint16_t sco_inx,tBTM_CHG_ESCO_PARAMS * p_parms)1127 static tBTM_STATUS BTM_ChangeEScoLinkParms(uint16_t sco_inx,
1128                                            tBTM_CHG_ESCO_PARAMS* p_parms) {
1129   /* Make sure sco handle is valid and on an active link */
1130   if (sco_inx >= BTM_MAX_SCO_LINKS ||
1131       btm_cb.sco_cb.sco_db[sco_inx].state != SCO_ST_CONNECTED)
1132     return (BTM_WRONG_MODE);
1133 
1134   tSCO_CONN* p_sco = &btm_cb.sco_cb.sco_db[sco_inx];
1135   enh_esco_params_t* p_setup = &p_sco->esco.setup;
1136 
1137   /* Save the previous types in case command fails */
1138   uint16_t saved_packet_types = p_setup->packet_types;
1139 
1140   /* If SCO connection OR eSCO not supported just send change packet types */
1141   if (p_sco->esco.data.link_type == BTM_LINK_TYPE_SCO ||
1142       !btm_cb.sco_cb.esco_supported) {
1143     p_setup->packet_types =
1144         p_parms->packet_types &
1145         (btm_cb.btm_sco_pkt_types_supported & BTM_SCO_LINK_ONLY_MASK);
1146 
1147     BTM_TRACE_API("%s: SCO Link for handle 0x%04x, pkt 0x%04x", __func__,
1148                   p_sco->hci_handle, p_setup->packet_types);
1149 
1150     BTM_TRACE_API("%s: SCO Link for handle 0x%04x, pkt 0x%04x", __func__,
1151                   p_sco->hci_handle, p_setup->packet_types);
1152 
1153     btsnd_hcic_change_conn_type(p_sco->hci_handle,
1154                                 BTM_ESCO_2_SCO(p_setup->packet_types));
1155   } else /* eSCO is supported and the link type is eSCO */
1156   {
1157     uint16_t temp_packet_types =
1158         (p_parms->packet_types & BTM_SCO_SUPPORTED_PKTS_MASK &
1159          btm_cb.btm_sco_pkt_types_supported);
1160 
1161     /* OR in any exception packet types */
1162     temp_packet_types |=
1163         ((p_parms->packet_types & BTM_SCO_EXCEPTION_PKTS_MASK) |
1164          (btm_cb.btm_sco_pkt_types_supported & BTM_SCO_EXCEPTION_PKTS_MASK));
1165     p_setup->packet_types = temp_packet_types;
1166 
1167     BTM_TRACE_API("%s -> eSCO Link for handle 0x%04x", __func__,
1168                   p_sco->hci_handle);
1169     BTM_TRACE_API(
1170         "   txbw 0x%x, rxbw 0x%x, lat 0x%x, retrans 0x%02x, pkt 0x%04x",
1171         p_setup->transmit_bandwidth, p_setup->receive_bandwidth,
1172         p_parms->max_latency_ms, p_parms->retransmission_effort,
1173         temp_packet_types);
1174 
1175     /* Use Enhanced Synchronous commands if supported */
1176     if (controller_get_interface()
1177             ->supports_enhanced_setup_synchronous_connection()) {
1178       /* Use the saved SCO routing */
1179       p_setup->input_data_path = p_setup->output_data_path = ESCO_DATA_PATH;
1180 
1181       btsnd_hcic_enhanced_set_up_synchronous_connection(p_sco->hci_handle,
1182                                                         p_setup);
1183       p_setup->packet_types = saved_packet_types;
1184     } else { /* Use older command */
1185       uint16_t voice_content_format = btm_sco_voice_settings_to_legacy(p_setup);
1186       /* When changing an existing link, only change latency, retrans, and
1187        * pkts */
1188       btsnd_hcic_setup_esco_conn(p_sco->hci_handle, p_setup->transmit_bandwidth,
1189                                  p_setup->receive_bandwidth,
1190                                  p_parms->max_latency_ms, voice_content_format,
1191                                  p_parms->retransmission_effort,
1192                                  p_setup->packet_types);
1193     }
1194 
1195     BTM_TRACE_API(
1196         "%s: txbw 0x%x, rxbw 0x%x, lat 0x%x, retrans 0x%02x, pkt 0x%04x",
1197         __func__, p_setup->transmit_bandwidth, p_setup->receive_bandwidth,
1198         p_parms->max_latency_ms, p_parms->retransmission_effort,
1199         temp_packet_types);
1200   }
1201 
1202   return (BTM_CMD_STARTED);
1203 }
1204 
1205 /*******************************************************************************
1206  *
1207  * Function         BTM_EScoConnRsp
1208  *
1209  * Description      This function is called upon receipt of an (e)SCO connection
1210  *                  request event (BTM_ESCO_CONN_REQ_EVT) to accept or reject
1211  *                  the request. Parameters used to negotiate eSCO links.
1212  *                  If p_parms is NULL, then values set through BTM_SetEScoMode
1213  *                  are used.
1214  *                  If the link type of the incoming request is SCO, then only
1215  *                  the tx_bw, max_latency, content format, and packet_types are
1216  *                  valid.  The hci_status parameter should be
1217  *                  ([0x0] to accept, [0x0d..0x0f] to reject)
1218  *
1219  *
1220  * Returns          void
1221  *
1222  ******************************************************************************/
BTM_EScoConnRsp(uint16_t sco_inx,uint8_t hci_status,enh_esco_params_t * p_parms)1223 void BTM_EScoConnRsp(uint16_t sco_inx, uint8_t hci_status,
1224                      enh_esco_params_t* p_parms) {
1225   if (sco_inx < BTM_MAX_SCO_LINKS &&
1226       btm_cb.sco_cb.sco_db[sco_inx].state == SCO_ST_W4_CONN_RSP) {
1227     btm_esco_conn_rsp(sco_inx, hci_status,
1228                       btm_cb.sco_cb.sco_db[sco_inx].esco.data.bd_addr, p_parms);
1229   }
1230 }
1231 
1232 /*******************************************************************************
1233  *
1234  * Function         btm_is_sco_active
1235  *
1236  * Description      This function is called to see if a SCO handle is already in
1237  *                  use.
1238  *
1239  * Returns          bool
1240  *
1241  ******************************************************************************/
btm_is_sco_active(uint16_t handle)1242 bool btm_is_sco_active(uint16_t handle) {
1243   uint16_t xx;
1244   tSCO_CONN* p = &btm_cb.sco_cb.sco_db[0];
1245 
1246   for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
1247     if (handle == p->hci_handle && p->state == SCO_ST_CONNECTED) return (true);
1248   }
1249   return (false);
1250 }
1251 
1252 /*******************************************************************************
1253  *
1254  * Function         BTM_GetNumScoLinks
1255  *
1256  * Description      This function returns the number of active sco links.
1257  *
1258  * Returns          uint8_t
1259  *
1260  ******************************************************************************/
BTM_GetNumScoLinks(void)1261 uint8_t BTM_GetNumScoLinks(void) {
1262   tSCO_CONN* p = &btm_cb.sco_cb.sco_db[0];
1263   uint16_t xx;
1264   uint8_t num_scos = 0;
1265 
1266   for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
1267     switch (p->state) {
1268       case SCO_ST_W4_CONN_RSP:
1269       case SCO_ST_CONNECTING:
1270       case SCO_ST_CONNECTED:
1271       case SCO_ST_DISCONNECTING:
1272       case SCO_ST_PEND_UNPARK:
1273         num_scos++;
1274         break;
1275       default:
1276         break;
1277     }
1278   }
1279   return (num_scos);
1280 }
1281 
1282 /*******************************************************************************
1283  *
1284  * Function         BTM_IsScoActiveByBdaddr
1285  *
1286  * Description      This function is called to see if a SCO connection is active
1287  *                  for a bd address.
1288  *
1289  * Returns          bool
1290  *
1291  ******************************************************************************/
BTM_IsScoActiveByBdaddr(const RawAddress & remote_bda)1292 bool BTM_IsScoActiveByBdaddr(const RawAddress& remote_bda) {
1293   uint8_t xx;
1294   tSCO_CONN* p = &btm_cb.sco_cb.sco_db[0];
1295 
1296   /* If any SCO is being established to the remote BD address, refuse this */
1297   for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
1298     if (p->esco.data.bd_addr == remote_bda && p->state == SCO_ST_CONNECTED) {
1299       return (true);
1300     }
1301   }
1302   return (false);
1303 }
1304 
1305 /*******************************************************************************
1306  *
1307  * Function         btm_sco_voice_settings_2_legacy
1308  *
1309  * Description      This function is called to convert the Enhanced eSCO
1310  *                  parameters into voice setting parameter mask used
1311  *                  for legacy setup synchronous connection HCI commands
1312  *
1313  * Returns          UINT16 - 16-bit mask for voice settings
1314  *
1315  *          HCI_INP_CODING_LINEAR           0x0000 (0000000000)
1316  *          HCI_INP_CODING_U_LAW            0x0100 (0100000000)
1317  *          HCI_INP_CODING_A_LAW            0x0200 (1000000000)
1318  *          HCI_INP_CODING_MASK             0x0300 (1100000000)
1319  *
1320  *          HCI_INP_DATA_FMT_1S_COMPLEMENT  0x0000 (0000000000)
1321  *          HCI_INP_DATA_FMT_2S_COMPLEMENT  0x0040 (0001000000)
1322  *          HCI_INP_DATA_FMT_SIGN_MAGNITUDE 0x0080 (0010000000)
1323  *          HCI_INP_DATA_FMT_UNSIGNED       0x00c0 (0011000000)
1324  *          HCI_INP_DATA_FMT_MASK           0x00c0 (0011000000)
1325  *
1326  *          HCI_INP_SAMPLE_SIZE_8BIT        0x0000 (0000000000)
1327  *          HCI_INP_SAMPLE_SIZE_16BIT       0x0020 (0000100000)
1328  *          HCI_INP_SAMPLE_SIZE_MASK        0x0020 (0000100000)
1329  *
1330  *          HCI_INP_LINEAR_PCM_BIT_POS_MASK 0x001c (0000011100)
1331  *          HCI_INP_LINEAR_PCM_BIT_POS_OFFS 2
1332  *
1333  *          HCI_AIR_CODING_FORMAT_CVSD      0x0000 (0000000000)
1334  *          HCI_AIR_CODING_FORMAT_U_LAW     0x0001 (0000000001)
1335  *          HCI_AIR_CODING_FORMAT_A_LAW     0x0002 (0000000010)
1336  *          HCI_AIR_CODING_FORMAT_TRANSPNT  0x0003 (0000000011)
1337  *          HCI_AIR_CODING_FORMAT_MASK      0x0003 (0000000011)
1338  *
1339  *          default (0001100000)
1340  *          HCI_DEFAULT_VOICE_SETTINGS    (HCI_INP_CODING_LINEAR \
1341  *                                   | HCI_INP_DATA_FMT_2S_COMPLEMENT \
1342  *                                   | HCI_INP_SAMPLE_SIZE_16BIT \
1343  *                                   | HCI_AIR_CODING_FORMAT_CVSD)
1344  *
1345  ******************************************************************************/
btm_sco_voice_settings_to_legacy(enh_esco_params_t * p_params)1346 static uint16_t btm_sco_voice_settings_to_legacy(enh_esco_params_t* p_params) {
1347   uint16_t voice_settings = 0;
1348 
1349   /* Convert Input Coding Format: If no uLaw or aLAW then Linear will be used
1350    * (0) */
1351   if (p_params->input_coding_format.coding_format == ESCO_CODING_FORMAT_ULAW)
1352     voice_settings |= HCI_INP_CODING_U_LAW;
1353   else if (p_params->input_coding_format.coding_format ==
1354            ESCO_CODING_FORMAT_ALAW)
1355     voice_settings |= HCI_INP_CODING_A_LAW;
1356   /* else default value of '0 is good 'Linear' */
1357 
1358   /* Convert Input Data Format. Use 2's Compliment as the default */
1359   switch (p_params->input_pcm_data_format) {
1360     case ESCO_PCM_DATA_FORMAT_1_COMP:
1361       /* voice_settings |= HCI_INP_DATA_FMT_1S_COMPLEMENT;     value is '0'
1362        * already */
1363       break;
1364 
1365     case ESCO_PCM_DATA_FORMAT_SIGN:
1366       voice_settings |= HCI_INP_DATA_FMT_SIGN_MAGNITUDE;
1367       break;
1368 
1369     case ESCO_PCM_DATA_FORMAT_UNSIGN:
1370       voice_settings |= HCI_INP_DATA_FMT_UNSIGNED;
1371       break;
1372 
1373     default: /* 2's Compliment */
1374       voice_settings |= HCI_INP_DATA_FMT_2S_COMPLEMENT;
1375       break;
1376   }
1377 
1378   /* Convert Over the Air Coding. Use CVSD as the default */
1379   switch (p_params->transmit_coding_format.coding_format) {
1380     case ESCO_CODING_FORMAT_ULAW:
1381       voice_settings |= HCI_AIR_CODING_FORMAT_U_LAW;
1382       break;
1383 
1384     case ESCO_CODING_FORMAT_ALAW:
1385       voice_settings |= HCI_AIR_CODING_FORMAT_A_LAW;
1386       break;
1387 
1388     case ESCO_CODING_FORMAT_MSBC:
1389       voice_settings |= HCI_AIR_CODING_FORMAT_TRANSPNT;
1390       break;
1391 
1392     default: /* CVSD (0) */
1393       break;
1394   }
1395 
1396   /* Convert PCM payload MSB position (0000011100) */
1397   voice_settings |= (uint16_t)(((p_params->input_pcm_payload_msb_position & 0x7)
1398                                 << HCI_INP_LINEAR_PCM_BIT_POS_OFFS));
1399 
1400   /* Convert Input Sample Size (0000011100) */
1401   if (p_params->input_coded_data_size == 16)
1402     voice_settings |= HCI_INP_SAMPLE_SIZE_16BIT;
1403   else /* Use 8 bit for all others */
1404     voice_settings |= HCI_INP_SAMPLE_SIZE_8BIT;
1405 
1406   BTM_TRACE_DEBUG("%s: voice setting for legacy 0x%03x", __func__,
1407                   voice_settings);
1408 
1409   return (voice_settings);
1410 }
1411