1 /******************************************************************************
2  *
3  *  Copyright 2008-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 is the implementation for the audio/video registration module.
22  *
23  ******************************************************************************/
24 
25 #include <bluetooth/log.h>
26 
27 #include <cstdint>
28 
29 #include "bta/ar/bta_ar_int.h"
30 #include "bta/sys/bta_sys.h"
31 #include "stack/include/avct_api.h"
32 #include "stack/include/avrc_api.h"
33 #include "stack/include/bt_types.h"
34 #include "stack/include/bt_uuid16.h"
35 #include "stack/include/sdp_api.h"
36 #include "types/raw_address.h"
37 
38 using namespace bluetooth::legacy::stack::sdp;
39 using namespace bluetooth;
40 
41 /* AV control block */
42 tBTA_AR_CB bta_ar_cb;
43 
44 /*******************************************************************************
45  *
46  * Function         bta_ar_id
47  *
48  * Description      This function maps sys_id to ar id mask.
49  *
50  * Returns          void
51  *
52  ******************************************************************************/
bta_ar_id(tBTA_SYS_ID sys_id)53 static uint8_t bta_ar_id(tBTA_SYS_ID sys_id) {
54   uint8_t mask = 0;
55   if (sys_id == BTA_ID_AV) {
56     mask = BTA_AR_AV_MASK;
57   } else if (sys_id == BTA_ID_AVK) {
58     mask = BTA_AR_AVK_MASK;
59   }
60   return mask;
61 }
bta_ar_avrc_add_cat(uint16_t categories)62 static void bta_ar_avrc_add_cat(uint16_t categories) {
63   uint8_t temp[sizeof(uint16_t)], *p;
64   /* Change supported categories on the second one */
65   if (bta_ar_cb.sdp_tg_handle != 0) {
66     p = temp;
67     UINT16_TO_BE_STREAM(p, categories);
68     if (!get_legacy_stack_sdp_api()->handle.SDP_AddAttribute(
69             bta_ar_cb.sdp_tg_handle, ATTR_ID_SUPPORTED_FEATURES, UINT_DESC_TYPE,
70             sizeof(temp), (uint8_t*)temp)) {
71       log::warn(
72           "Unable to add SDP attribute for supported categories handle:{}",
73           bta_ar_cb.sdp_tg_handle);
74     }
75   }
76 }
77 
78 /*******************************************************************************
79  *
80  * Function         bta_ar_init
81  *
82  * Description      This function is called to register to AVDTP.
83  *
84  * Returns          void
85  *
86  ******************************************************************************/
bta_ar_init(void)87 void bta_ar_init(void) {
88   /* initialize control block */
89   memset(&bta_ar_cb, 0, sizeof(tBTA_AR_CB));
90 }
91 
92 /*******************************************************************************
93  *
94  * Function         bta_ar_reg_avdt
95  *
96  * Description      This function is called to register to AVDTP.
97  *
98  * Returns          void
99  *
100  ******************************************************************************/
bta_ar_avdt_cback(uint8_t handle,const RawAddress & bd_addr,uint8_t event,tAVDT_CTRL * p_data,uint8_t scb_index)101 static void bta_ar_avdt_cback(uint8_t handle, const RawAddress& bd_addr,
102                               uint8_t event, tAVDT_CTRL* p_data,
103                               uint8_t scb_index) {
104   /* route the AVDT registration callback to av or avk */
105   if (bta_ar_cb.p_av_conn_cback)
106     (*bta_ar_cb.p_av_conn_cback)(handle, bd_addr, event, p_data, scb_index);
107 }
108 
109 /*******************************************************************************
110  *
111  * Function         bta_ar_reg_avdt
112  *
113  * Description      AR module registration to AVDT.
114  *
115  * Returns          void
116  *
117  ******************************************************************************/
bta_ar_reg_avdt(AvdtpRcb * p_reg,tAVDT_CTRL_CBACK * p_cback)118 void bta_ar_reg_avdt(AvdtpRcb* p_reg, tAVDT_CTRL_CBACK* p_cback) {
119   bta_ar_cb.p_av_conn_cback = p_cback;
120   if (bta_ar_cb.avdt_registered == 0) {
121     AVDT_Register(p_reg, bta_ar_avdt_cback);
122   } else {
123     log::warn("doesn't register again (registered:{})",
124               bta_ar_cb.avdt_registered);
125   }
126   bta_ar_cb.avdt_registered |= BTA_AR_AV_MASK;
127 }
128 
129 /*******************************************************************************
130  *
131  * Function         bta_ar_dereg_avdt
132  *
133  * Description      This function is called to de-register from AVDTP.
134  *
135  * Returns          void
136  *
137  ******************************************************************************/
bta_ar_dereg_avdt()138 void bta_ar_dereg_avdt() {
139   bta_ar_cb.p_av_conn_cback = NULL;
140   bta_ar_cb.avdt_registered &= ~BTA_AR_AV_MASK;
141 
142   if (bta_ar_cb.avdt_registered == 0) AVDT_Deregister();
143 }
144 
145 /*******************************************************************************
146  *
147  * Function         bta_ar_avdt_conn
148  *
149  * Description      This function is called to let ar know that some AVDTP
150  *                  profile is connected for this sys_id.
151  *                  If the other sys modules started a timer for PENDING_EVT,
152  *                  the timer can be stopped now.
153  *
154  * Returns          void
155  *
156  ******************************************************************************/
bta_ar_avdt_conn(tBTA_SYS_ID sys_id,const RawAddress & bd_addr,uint8_t scb_index)157 void bta_ar_avdt_conn(tBTA_SYS_ID sys_id, const RawAddress& bd_addr,
158                       uint8_t scb_index) {
159 }
160 
161 /*******************************************************************************
162  *
163  * Function         bta_ar_reg_avct
164  *
165  * Description      This function is called to register to AVCTP.
166  *
167  * Returns          void
168  *
169  ******************************************************************************/
bta_ar_reg_avct()170 void bta_ar_reg_avct() {
171   if (bta_ar_cb.avct_registered == 0) {
172     AVCT_Register();
173   }
174   bta_ar_cb.avct_registered |= BTA_AR_AV_MASK;
175 }
176 
177 /*******************************************************************************
178  *
179  * Function         bta_ar_dereg_avct
180  *
181  * Description      This function is called to deregister from AVCTP.
182  *
183  * Returns          void
184  *
185  ******************************************************************************/
bta_ar_dereg_avct()186 void bta_ar_dereg_avct() {
187   bta_ar_cb.avct_registered &= ~BTA_AR_AV_MASK;
188 
189   if (bta_ar_cb.avct_registered == 0) AVCT_Deregister();
190 }
191 
192 /******************************************************************************
193  *
194  * Function         bta_ar_reg_avrc
195  *
196  * Description      This function is called to register an SDP record for AVRCP.
197  *
198  * Returns          void
199  *
200  *****************************************************************************/
bta_ar_reg_avrc(uint16_t service_uuid,const char * service_name,const char * provider_name,uint16_t categories,bool browse_supported,uint16_t profile_version)201 void bta_ar_reg_avrc(uint16_t service_uuid, const char* service_name,
202                      const char* provider_name, uint16_t categories,
203                      bool browse_supported, uint16_t profile_version) {
204   uint8_t mask = BTA_AR_AV_MASK;
205   uint8_t temp[8], *p;
206 
207   if (!categories) return;
208 
209   if (service_uuid == UUID_SERVCLASS_AV_REM_CTRL_TARGET) {
210     if (bta_ar_cb.sdp_tg_handle == 0) {
211       bta_ar_cb.tg_registered = mask;
212       bta_ar_cb.sdp_tg_handle =
213           get_legacy_stack_sdp_api()->handle.SDP_CreateRecord();
214       AVRC_AddRecord(service_uuid, service_name, provider_name, categories,
215                      bta_ar_cb.sdp_tg_handle, browse_supported,
216                      profile_version, 0);
217       bta_sys_add_uuid(service_uuid);
218     }
219     /* only one TG is allowed (first-come, first-served).
220      * If sdp_tg_handle is non-0, ignore this request */
221   } else if ((service_uuid == UUID_SERVCLASS_AV_REMOTE_CONTROL) ||
222              (service_uuid == UUID_SERVCLASS_AV_REM_CTRL_CONTROL)) {
223     bta_ar_cb.ct_categories[mask - 1] = categories;
224     categories = bta_ar_cb.ct_categories[0] | bta_ar_cb.ct_categories[1];
225     if (bta_ar_cb.sdp_ct_handle == 0) {
226       bta_ar_cb.sdp_ct_handle =
227           get_legacy_stack_sdp_api()->handle.SDP_CreateRecord();
228       AVRC_AddRecord(service_uuid, service_name, provider_name, categories,
229                      bta_ar_cb.sdp_ct_handle, browse_supported,
230                      profile_version, 0);
231       bta_sys_add_uuid(service_uuid);
232     } else {
233       /* multiple CTs are allowed.
234        * Change supported categories on the second one */
235       p = temp;
236       UINT16_TO_BE_STREAM(p, categories);
237       if (!get_legacy_stack_sdp_api()->handle.SDP_AddAttribute(
238               bta_ar_cb.sdp_ct_handle, ATTR_ID_SUPPORTED_FEATURES,
239               UINT_DESC_TYPE, (uint32_t)2, (uint8_t*)temp)) {
240         log::warn("Unable to add supported features handle:{}",
241                   bta_ar_cb.sdp_ct_handle);
242       }
243     }
244   }
245 }
246 
247 /******************************************************************************
248  *
249  * Function         bta_ar_dereg_avrc
250  *
251  * Description      This function is called to de-register/delete an SDP record
252  *                  for AVRCP.
253  *
254  * Returns          void
255  *
256  *****************************************************************************/
bta_ar_dereg_avrc(uint16_t service_uuid)257 void bta_ar_dereg_avrc(uint16_t service_uuid) {
258   uint8_t mask = BTA_AR_AV_MASK;
259   uint16_t categories = 0;
260   uint8_t temp[8], *p;
261 
262   if (service_uuid == UUID_SERVCLASS_AV_REM_CTRL_TARGET) {
263     if (bta_ar_cb.sdp_tg_handle && mask == bta_ar_cb.tg_registered) {
264       bta_ar_cb.tg_registered = 0;
265       if (!get_legacy_stack_sdp_api()->handle.SDP_DeleteRecord(
266               bta_ar_cb.sdp_tg_handle)) {
267         log::warn("Unable to delete SDP record handle:{}",
268                   bta_ar_cb.sdp_tg_handle);
269       }
270       bta_ar_cb.sdp_tg_handle = 0;
271       bta_sys_remove_uuid(service_uuid);
272     }
273   } else if (service_uuid == UUID_SERVCLASS_AV_REMOTE_CONTROL) {
274     if (bta_ar_cb.sdp_ct_handle) {
275       bta_ar_cb.ct_categories[mask - 1] = 0;
276       categories = bta_ar_cb.ct_categories[0] | bta_ar_cb.ct_categories[1];
277       if (!categories) {
278         /* no CT is still registered - cleaup */
279         if (get_legacy_stack_sdp_api()->handle.SDP_DeleteRecord(
280                 bta_ar_cb.sdp_ct_handle)) {
281           log::warn("Unable to delete SDP record handle:{}",
282                     bta_ar_cb.sdp_ct_handle);
283         }
284         bta_ar_cb.sdp_ct_handle = 0;
285         bta_sys_remove_uuid(service_uuid);
286       } else {
287         /* change supported categories to the remaning one */
288         p = temp;
289         UINT16_TO_BE_STREAM(p, categories);
290         if (!get_legacy_stack_sdp_api()->handle.SDP_AddAttribute(
291                 bta_ar_cb.sdp_ct_handle, ATTR_ID_SUPPORTED_FEATURES,
292                 UINT_DESC_TYPE, (uint32_t)2, (uint8_t*)temp)) {
293           log::warn("Unable to add SDP supported features handle:{}",
294                     bta_ar_cb.sdp_ct_handle);
295         }
296       }
297     }
298   }
299 }
300 
301 /******************************************************************************
302  *
303  * Function         bta_ar_reg_avrc_for_src_sink_coexist
304  *
305  * Description      This function is called to register an SDP record for AVRCP.
306  *                  Add sys_id to distinguish src or sink role and add also save
307  *tg_categories
308  *
309  * Returns          void
310  *
311  *****************************************************************************/
bta_ar_reg_avrc_for_src_sink_coexist(uint16_t service_uuid,const char * service_name,const char * provider_name,uint16_t categories,tBTA_SYS_ID sys_id,bool browse_supported,uint16_t profile_version)312 void bta_ar_reg_avrc_for_src_sink_coexist(
313     uint16_t service_uuid, const char* service_name, const char* provider_name,
314     uint16_t categories, tBTA_SYS_ID sys_id, bool browse_supported,
315     uint16_t profile_version) {
316   uint8_t mask = bta_ar_id(sys_id);
317   uint8_t temp[8], *p;
318   uint16_t class_list[2];
319   uint16_t count = 1;
320   if (!mask || !categories) return;
321   if (service_uuid == UUID_SERVCLASS_AV_REM_CTRL_TARGET) {
322     bta_ar_cb.tg_categories[mask - 1] = categories;
323     categories = bta_ar_cb.tg_categories[0] | bta_ar_cb.tg_categories[1];
324     if (bta_ar_cb.sdp_tg_handle == 0) {
325       bta_ar_cb.tg_registered = mask;
326       bta_ar_cb.sdp_tg_handle =
327           get_legacy_stack_sdp_api()->handle.SDP_CreateRecord();
328       AVRC_AddRecord(service_uuid, service_name, provider_name, categories,
329                      bta_ar_cb.sdp_tg_handle, browse_supported, profile_version,
330                      0);
331       bta_sys_add_uuid(service_uuid);
332     }
333     /* Change supported categories on the second one */
334     bta_ar_avrc_add_cat(categories);
335     /* only one TG is allowed (first-come, first-served).
336      * If sdp_tg_handle is non-0, ignore this request */
337   } else if ((service_uuid == UUID_SERVCLASS_AV_REMOTE_CONTROL) ||
338              (service_uuid == UUID_SERVCLASS_AV_REM_CTRL_CONTROL)) {
339     bta_ar_cb.ct_categories[mask - 1] = categories;
340     categories = bta_ar_cb.ct_categories[0] | bta_ar_cb.ct_categories[1];
341     if (bta_ar_cb.sdp_ct_handle == 0) {
342       bta_ar_cb.sdp_ct_handle =
343           get_legacy_stack_sdp_api()->handle.SDP_CreateRecord();
344       AVRC_AddRecord(service_uuid, service_name, provider_name, categories,
345                      bta_ar_cb.sdp_ct_handle, browse_supported, profile_version,
346                      0);
347       bta_sys_add_uuid(service_uuid);
348       bta_ar_cb.ct_ver = categories;
349     } else {
350       /* If first reg 1,3 version, reg 1.6 must update class id */
351       if (bta_ar_cb.ct_ver < profile_version) {
352         log::verbose("ver=0x{:x}", profile_version);
353         if (bta_ar_cb.ct_ver <= AVRC_REV_1_3 &&
354             profile_version > AVRC_REV_1_3) {
355           bta_ar_cb.ct_ver = profile_version;
356           /* add service class id list */
357           class_list[0] = service_uuid;
358           if (service_uuid == UUID_SERVCLASS_AV_REMOTE_CONTROL) {
359             class_list[1] = UUID_SERVCLASS_AV_REM_CTRL_CONTROL;
360             count = 2;
361           }
362           if (!get_legacy_stack_sdp_api()->handle.SDP_AddServiceClassIdList(
363                   bta_ar_cb.sdp_ct_handle, count, class_list)) {
364             log::warn("Unable to add SDP service class id list handle:{}",
365                       bta_ar_cb.sdp_ct_handle);
366           }
367         } else {
368           bta_ar_cb.ct_ver = profile_version;
369         }
370         if (!get_legacy_stack_sdp_api()->handle.SDP_AddProfileDescriptorList(
371                 bta_ar_cb.sdp_ct_handle, service_uuid, profile_version)) {
372           log::warn("Unable to add SDP profile descriptor version handle:{}",
373                     bta_ar_cb.sdp_ct_handle);
374         }
375       }
376       /* multiple CT are allowed.
377        * Change supported categories on the second one */
378       p = temp;
379       UINT16_TO_BE_STREAM(p, categories);
380       if (!get_legacy_stack_sdp_api()->handle.SDP_AddAttribute(
381               bta_ar_cb.sdp_ct_handle, ATTR_ID_SUPPORTED_FEATURES,
382               UINT_DESC_TYPE, (uint32_t)2, (uint8_t*)temp)) {
383         log::warn("Unable to add SDP attribute supported features handle:{}",
384                   bta_ar_cb.sdp_ct_handle);
385       }
386     }
387   }
388 }
389