• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 #include <cstdint>
20 #include <string>
21 
22 #include "device/include/esco_parameters.h"
23 #include "stack/include/btm_api_types.h"
24 
25 constexpr uint16_t kMaxScoLinks = static_cast<uint16_t>(BTM_MAX_SCO_LINKS);
26 
27 #ifndef ESCO_DATA_PATH
28 #ifdef OS_ANDROID
29 #define ESCO_DATA_PATH ESCO_DATA_PATH_PCM
30 #else
31 #define ESCO_DATA_PATH ESCO_DATA_PATH_HCI
32 #endif
33 #endif
34 
35 // SCO-over-HCI audio related definitions
36 namespace bluetooth::audio::sco {
37 
38 // Initialize SCO-over-HCI socket (UIPC); the client is audio server.
39 void init();
40 
41 // Open the socket when there is SCO connection open
42 void open();
43 
44 // Clean up the socket when the SCO connection is done
45 void cleanup();
46 
47 // Read from the socket (audio server) for SCO Tx
48 size_t read(uint8_t* p_buf, uint32_t len);
49 
50 // Write to the socket from SCO Rx
51 size_t write(const uint8_t* buf, uint32_t len);
52 }  // namespace bluetooth::audio::sco
53 
54 /* Define the structures needed by sco
55  */
56 
57 #ifndef CASE_RETURN_TEXT
58 #define CASE_RETURN_TEXT(code) \
59   case code:                   \
60     return #code
61 #endif
62 
63 /* Define the structures needed by sco */
64 typedef enum : uint16_t {
65   SCO_ST_UNUSED = 0,
66   SCO_ST_LISTENING = 1,
67   SCO_ST_W4_CONN_RSP = 2,
68   SCO_ST_CONNECTING = 3,
69   SCO_ST_CONNECTED = 4,
70   SCO_ST_DISCONNECTING = 5,
71   SCO_ST_PEND_UNPARK = 6,
72   SCO_ST_PEND_ROLECHANGE = 7,
73   SCO_ST_PEND_MODECHANGE = 8,
74 } tSCO_STATE;
75 
sco_state_text(const tSCO_STATE & state)76 inline std::string sco_state_text(const tSCO_STATE& state) {
77   switch (state) {
78     CASE_RETURN_TEXT(SCO_ST_UNUSED);
79     CASE_RETURN_TEXT(SCO_ST_LISTENING);
80     CASE_RETURN_TEXT(SCO_ST_W4_CONN_RSP);
81     CASE_RETURN_TEXT(SCO_ST_CONNECTING);
82     CASE_RETURN_TEXT(SCO_ST_CONNECTED);
83     CASE_RETURN_TEXT(SCO_ST_DISCONNECTING);
84     CASE_RETURN_TEXT(SCO_ST_PEND_UNPARK);
85     CASE_RETURN_TEXT(SCO_ST_PEND_ROLECHANGE);
86     CASE_RETURN_TEXT(SCO_ST_PEND_MODECHANGE);
87     default:
88       return std::string("unknown_sco_state: ") +
89              std::to_string(static_cast<uint16_t>(state));
90   }
91 }
92 
93 #undef CASE_RETURN_TEXT
94 
95 /* Define the structure that contains (e)SCO data */
96 typedef struct {
97   tBTM_ESCO_CBACK* p_esco_cback; /* Callback for eSCO events     */
98   enh_esco_params_t setup;
99   tBTM_ESCO_DATA data; /* Connection complete information */
100   uint8_t hci_status;
101 } tBTM_ESCO_INFO;
102 
103 /* Define the structure used for SCO Management
104  */
105 typedef struct {
106   tBTM_ESCO_INFO esco;    /* Current settings             */
107   tBTM_SCO_CB* p_conn_cb; /* Callback for when connected  */
108   tBTM_SCO_CB* p_disc_cb; /* Callback for when disconnect */
109   tSCO_STATE state;       /* The state of the SCO link    */
110 
111   uint16_t hci_handle;    /* HCI Handle                   */
112  public:
is_active__anon454a9aae0308113   bool is_active() const { return state != SCO_ST_UNUSED; }
Handle__anon454a9aae0308114   uint16_t Handle() const { return hci_handle; }
115 
116   bool is_orig;           /* true if the originator       */
117   bool rem_bd_known;      /* true if remote BD addr known */
118 
119 } tSCO_CONN;
120 
121 /* SCO Management control block */
122 typedef struct {
123   tSCO_CONN sco_db[BTM_MAX_SCO_LINKS];
124   enh_esco_params_t def_esco_parms;
125   bool esco_supported;        /* true if 1.2 cntlr AND supports eSCO links */
126 
get_sco_connection_from_index__anon454a9aae0408127   tSCO_CONN* get_sco_connection_from_index(uint16_t index) {
128     return (index < kMaxScoLinks) ? (&sco_db[index]) : nullptr;
129   }
130 
get_sco_connection_from_handle__anon454a9aae0408131   tSCO_CONN* get_sco_connection_from_handle(uint16_t handle) {
132     tSCO_CONN* p_sco = sco_db;
133     for (uint16_t xx = 0; xx < kMaxScoLinks; xx++, p_sco++) {
134       if (p_sco->hci_handle == handle) {
135         return p_sco;
136       }
137     }
138     return nullptr;
139   }
140 
Init__anon454a9aae0408141   void Init() {
142     def_esco_parms = esco_parameters_for_codec(ESCO_CODEC_CVSD_S3);
143   }
144 
Free__anon454a9aae0408145   void Free() { bluetooth::audio::sco::cleanup(); }
146 
get_index__anon454a9aae0408147   uint16_t get_index(const tSCO_CONN* p_sco) const {
148     CHECK(p_sco != nullptr);
149     const tSCO_CONN* p = sco_db;
150     for (uint16_t xx = 0; xx < kMaxScoLinks; xx++, p++) {
151       if (p_sco == p) {
152         return xx;
153       }
154     }
155     return 0xffff;
156   }
157 
158 } tSCO_CB;
159 
160 extern void btm_sco_chk_pend_rolechange(uint16_t hci_handle);
161 extern void btm_sco_disc_chk_pend_for_modechange(uint16_t hci_handle);
162 
163 // Visible for test only
164 BT_HDR* btm_sco_make_packet(std::vector<uint8_t> data, uint16_t sco_handle);
165 
166 // Send a SCO packet
167 void btm_send_sco_packet(std::vector<uint8_t> data);
168