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 <cstdint>
26 
27 #include "bta/ar/bta_ar_int.h"
28 #include "bta/sys/bta_sys.h"
29 #include "stack/include/avct_api.h"
30 #include "stack/include/avrc_api.h"
31 
32 /* AV control block */
33 tBTA_AR_CB bta_ar_cb;
34 
35 /*******************************************************************************
36  *
37  * Function         bta_ar_init
38  *
39  * Description      This function is called to register to AVDTP.
40  *
41  * Returns          void
42  *
43  ******************************************************************************/
bta_ar_init(void)44 void bta_ar_init(void) {
45   /* initialize control block */
46   memset(&bta_ar_cb, 0, sizeof(tBTA_AR_CB));
47 }
48 
49 /*******************************************************************************
50  *
51  * Function         bta_ar_reg_avdt
52  *
53  * Description      This function is called to register to AVDTP.
54  *
55  * Returns          void
56  *
57  ******************************************************************************/
bta_ar_avdt_cback(uint8_t handle,const RawAddress & bd_addr,uint8_t event,tAVDT_CTRL * p_data,uint8_t scb_index)58 static void bta_ar_avdt_cback(uint8_t handle, const RawAddress& bd_addr,
59                               uint8_t event, tAVDT_CTRL* p_data,
60                               uint8_t scb_index) {
61   /* route the AVDT registration callback to av or avk */
62   if (bta_ar_cb.p_av_conn_cback)
63     (*bta_ar_cb.p_av_conn_cback)(handle, bd_addr, event, p_data, scb_index);
64 }
65 
66 /*******************************************************************************
67  *
68  * Function         bta_ar_reg_avdt
69  *
70  * Description      AR module registration to AVDT.
71  *
72  * Returns          void
73  *
74  ******************************************************************************/
bta_ar_reg_avdt(AvdtpRcb * p_reg,tAVDT_CTRL_CBACK * p_cback)75 void bta_ar_reg_avdt(AvdtpRcb* p_reg, tAVDT_CTRL_CBACK* p_cback) {
76   bta_ar_cb.p_av_conn_cback = p_cback;
77   if (bta_ar_cb.avdt_registered == 0) {
78     AVDT_Register(p_reg, bta_ar_avdt_cback);
79   } else {
80     APPL_TRACE_WARNING("%s: doesn't register again (registered:%d)", __func__,
81                        bta_ar_cb.avdt_registered);
82   }
83   bta_ar_cb.avdt_registered |= BTA_AR_AV_MASK;
84 }
85 
86 /*******************************************************************************
87  *
88  * Function         bta_ar_dereg_avdt
89  *
90  * Description      This function is called to de-register from AVDTP.
91  *
92  * Returns          void
93  *
94  ******************************************************************************/
bta_ar_dereg_avdt()95 void bta_ar_dereg_avdt() {
96   bta_ar_cb.p_av_conn_cback = NULL;
97   bta_ar_cb.avdt_registered &= ~BTA_AR_AV_MASK;
98 
99   if (bta_ar_cb.avdt_registered == 0) AVDT_Deregister();
100 }
101 
102 /*******************************************************************************
103  *
104  * Function         bta_ar_avdt_conn
105  *
106  * Description      This function is called to let ar know that some AVDTP
107  *                  profile is connected for this sys_id.
108  *                  If the other sys modules started a timer for PENDING_EVT,
109  *                  the timer can be stopped now.
110  *
111  * Returns          void
112  *
113  ******************************************************************************/
bta_ar_avdt_conn(tBTA_SYS_ID sys_id,const RawAddress & bd_addr,uint8_t scb_index)114 void bta_ar_avdt_conn(tBTA_SYS_ID sys_id, const RawAddress& bd_addr,
115                       uint8_t scb_index) {
116 }
117 
118 /*******************************************************************************
119  *
120  * Function         bta_ar_reg_avct
121  *
122  * Description      This function is called to register to AVCTP.
123  *
124  * Returns          void
125  *
126  ******************************************************************************/
bta_ar_reg_avct()127 void bta_ar_reg_avct() {
128   if (bta_ar_cb.avct_registered == 0) {
129     AVCT_Register();
130   }
131   bta_ar_cb.avct_registered |= BTA_AR_AV_MASK;
132 }
133 
134 /*******************************************************************************
135  *
136  * Function         bta_ar_dereg_avct
137  *
138  * Description      This function is called to deregister from AVCTP.
139  *
140  * Returns          void
141  *
142  ******************************************************************************/
bta_ar_dereg_avct()143 void bta_ar_dereg_avct() {
144   bta_ar_cb.avct_registered &= ~BTA_AR_AV_MASK;
145 
146   if (bta_ar_cb.avct_registered == 0) AVCT_Deregister();
147 }
148 
149 /******************************************************************************
150  *
151  * Function         bta_ar_reg_avrc
152  *
153  * Description      This function is called to register an SDP record for AVRCP.
154  *
155  * Returns          void
156  *
157  *****************************************************************************/
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)158 void bta_ar_reg_avrc(uint16_t service_uuid, const char* service_name,
159                      const char* provider_name, uint16_t categories,
160                      bool browse_supported, uint16_t profile_version) {
161   uint8_t mask = BTA_AR_AV_MASK;
162   uint8_t temp[8], *p;
163 
164   if (!categories) return;
165 
166   if (service_uuid == UUID_SERVCLASS_AV_REM_CTRL_TARGET) {
167     if (bta_ar_cb.sdp_tg_handle == 0) {
168       bta_ar_cb.tg_registered = mask;
169       bta_ar_cb.sdp_tg_handle = SDP_CreateRecord();
170       AVRC_AddRecord(service_uuid, service_name, provider_name, categories,
171                      bta_ar_cb.sdp_tg_handle, browse_supported,
172                      profile_version, 0);
173       bta_sys_add_uuid(service_uuid);
174     }
175     /* only one TG is allowed (first-come, first-served).
176      * If sdp_tg_handle is non-0, ignore this request */
177   } else if ((service_uuid == UUID_SERVCLASS_AV_REMOTE_CONTROL) ||
178              (service_uuid == UUID_SERVCLASS_AV_REM_CTRL_CONTROL)) {
179     bta_ar_cb.ct_categories[mask - 1] = categories;
180     categories = bta_ar_cb.ct_categories[0] | bta_ar_cb.ct_categories[1];
181     if (bta_ar_cb.sdp_ct_handle == 0) {
182       bta_ar_cb.sdp_ct_handle = SDP_CreateRecord();
183       AVRC_AddRecord(service_uuid, service_name, provider_name, categories,
184                      bta_ar_cb.sdp_ct_handle, browse_supported,
185                      profile_version, 0);
186       bta_sys_add_uuid(service_uuid);
187     } else {
188       /* multiple CTs are allowed.
189        * Change supported categories on the second one */
190       p = temp;
191       UINT16_TO_BE_STREAM(p, categories);
192       SDP_AddAttribute(bta_ar_cb.sdp_ct_handle, ATTR_ID_SUPPORTED_FEATURES,
193                        UINT_DESC_TYPE, (uint32_t)2, (uint8_t*)temp);
194     }
195   }
196 }
197 
198 /******************************************************************************
199  *
200  * Function         bta_ar_dereg_avrc
201  *
202  * Description      This function is called to de-register/delete an SDP record
203  *                  for AVRCP.
204  *
205  * Returns          void
206  *
207  *****************************************************************************/
bta_ar_dereg_avrc(uint16_t service_uuid)208 void bta_ar_dereg_avrc(uint16_t service_uuid) {
209   uint8_t mask = BTA_AR_AV_MASK;
210   uint16_t categories = 0;
211   uint8_t temp[8], *p;
212 
213   if (service_uuid == UUID_SERVCLASS_AV_REM_CTRL_TARGET) {
214     if (bta_ar_cb.sdp_tg_handle && mask == bta_ar_cb.tg_registered) {
215       bta_ar_cb.tg_registered = 0;
216       SDP_DeleteRecord(bta_ar_cb.sdp_tg_handle);
217       bta_ar_cb.sdp_tg_handle = 0;
218       bta_sys_remove_uuid(service_uuid);
219     }
220   } else if (service_uuid == UUID_SERVCLASS_AV_REMOTE_CONTROL) {
221     if (bta_ar_cb.sdp_ct_handle) {
222       bta_ar_cb.ct_categories[mask - 1] = 0;
223       categories = bta_ar_cb.ct_categories[0] | bta_ar_cb.ct_categories[1];
224       if (!categories) {
225         /* no CT is still registered - cleaup */
226         SDP_DeleteRecord(bta_ar_cb.sdp_ct_handle);
227         bta_ar_cb.sdp_ct_handle = 0;
228         bta_sys_remove_uuid(service_uuid);
229       } else {
230         /* change supported categories to the remaning one */
231         p = temp;
232         UINT16_TO_BE_STREAM(p, categories);
233         SDP_AddAttribute(bta_ar_cb.sdp_ct_handle, ATTR_ID_SUPPORTED_FEATURES,
234                          UINT_DESC_TYPE, (uint32_t)2, (uint8_t*)temp);
235       }
236     }
237   }
238 }
239