1 /****************************************************************************** 2 * 3 * Copyright (C) 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 <string.h> 26 #include "bta_ar_api.h" 27 #include "bta_ar_int.h" 28 29 30 /* AV control block */ 31 #if BTA_DYNAMIC_MEMORY == FALSE 32 tBTA_AR_CB bta_ar_cb; 33 #endif 34 35 /******************************************************************************* 36 ** 37 ** Function bta_ar_id 38 ** 39 ** Description This function maps sys_id to ar id mask. 40 ** 41 ** Returns void 42 ** 43 *******************************************************************************/ 44 static UINT8 bta_ar_id(tBTA_SYS_ID sys_id) 45 { 46 UINT8 mask = 0; 47 if (sys_id == BTA_ID_AV) 48 { 49 mask = BTA_AR_AV_MASK; 50 } 51 else if (sys_id == BTA_ID_AVK) 52 { 53 mask = BTA_AR_AVK_MASK; 54 } 55 56 return mask; 57 } 58 59 /******************************************************************************* 60 ** 61 ** Function bta_ar_init 62 ** 63 ** Description This function is called to register to AVDTP. 64 ** 65 ** Returns void 66 ** 67 *******************************************************************************/ 68 void bta_ar_init(void) 69 { 70 /* initialize control block */ 71 memset(&bta_ar_cb, 0, sizeof(tBTA_AR_CB)); 72 } 73 74 /******************************************************************************* 75 ** 76 ** Function bta_ar_reg_avdt 77 ** 78 ** Description This function is called to register to AVDTP. 79 ** 80 ** Returns void 81 ** 82 *******************************************************************************/ 83 static void bta_ar_avdt_cback(UINT8 handle, BD_ADDR bd_addr, UINT8 event, tAVDT_CTRL *p_data) 84 { 85 /* route the AVDT registration callback to av or avk */ 86 if (bta_ar_cb.p_av_conn_cback) 87 (*bta_ar_cb.p_av_conn_cback)(handle, bd_addr, event, p_data); 88 if (bta_ar_cb.p_avk_conn_cback) 89 (*bta_ar_cb.p_avk_conn_cback)(handle, bd_addr, event, p_data); 90 } 91 92 /******************************************************************************* 93 ** 94 ** Function bta_ar_reg_avdt 95 ** 96 ** Description AR module registration to AVDT. 97 ** 98 ** Returns void 99 ** 100 *******************************************************************************/ 101 void bta_ar_reg_avdt(tAVDT_REG *p_reg, tAVDT_CTRL_CBACK *p_cback, tBTA_SYS_ID sys_id) 102 { 103 UINT8 mask = 0; 104 105 if (sys_id == BTA_ID_AV) 106 { 107 bta_ar_cb.p_av_conn_cback = p_cback; 108 mask = BTA_AR_AV_MASK; 109 } 110 else if (sys_id == BTA_ID_AVK) 111 { 112 bta_ar_cb.p_avk_conn_cback = p_cback; 113 mask = BTA_AR_AVK_MASK; 114 } 115 #if (BTA_AR_DEBUG == TRUE) 116 else 117 { 118 APPL_TRACE_ERROR("bta_ar_reg_avdt: the registration is from wrong sys_id:%d", sys_id); 119 } 120 #endif 121 122 if (mask) 123 { 124 if (bta_ar_cb.avdt_registered == 0) 125 { 126 AVDT_Register(p_reg, bta_ar_avdt_cback); 127 } 128 bta_ar_cb.avdt_registered |= mask; 129 } 130 } 131 132 /******************************************************************************* 133 ** 134 ** Function bta_ar_dereg_avdt 135 ** 136 ** Description This function is called to de-register from AVDTP. 137 ** 138 ** Returns void 139 ** 140 *******************************************************************************/ 141 void bta_ar_dereg_avdt(tBTA_SYS_ID sys_id) 142 { 143 UINT8 mask = 0; 144 145 if (sys_id == BTA_ID_AV) 146 { 147 bta_ar_cb.p_av_conn_cback = NULL; 148 mask = BTA_AR_AV_MASK; 149 } 150 else if (sys_id == BTA_ID_AVK) 151 { 152 bta_ar_cb.p_avk_conn_cback = NULL; 153 mask = BTA_AR_AVK_MASK; 154 } 155 bta_ar_cb.avdt_registered &= ~mask; 156 157 if (bta_ar_cb.avdt_registered == 0) 158 AVDT_Deregister(); 159 } 160 161 /******************************************************************************* 162 ** 163 ** Function bta_ar_avdt_conn 164 ** 165 ** Description This function is called to let ar know that some AVDTP profile 166 ** is connected for this sys_id. 167 ** If the other sys modules started a timer for PENDING_EVT, 168 ** the timer can be stopped now. 169 ** 170 ** Returns void 171 ** 172 *******************************************************************************/ 173 void bta_ar_avdt_conn(tBTA_SYS_ID sys_id, BD_ADDR bd_addr) 174 { 175 UINT8 event = BTA_AR_AVDT_CONN_EVT; 176 tAVDT_CTRL data; 177 178 if (sys_id == BTA_ID_AV) 179 { 180 if (bta_ar_cb.p_avk_conn_cback) 181 { 182 (*bta_ar_cb.p_avk_conn_cback)(0, bd_addr, event, &data); 183 } 184 } 185 else if (sys_id == BTA_ID_AVK) 186 { 187 if (bta_ar_cb.p_av_conn_cback) 188 { 189 (*bta_ar_cb.p_av_conn_cback)(0, bd_addr, event, &data); 190 } 191 } 192 } 193 194 /******************************************************************************* 195 ** 196 ** Function bta_ar_reg_avct 197 ** 198 ** Description This function is called to register to AVCTP. 199 ** 200 ** Returns void 201 ** 202 *******************************************************************************/ 203 void bta_ar_reg_avct(UINT16 mtu, UINT16 mtu_br, UINT8 sec_mask, tBTA_SYS_ID sys_id) 204 { 205 UINT8 mask = bta_ar_id (sys_id); 206 207 if (mask) 208 { 209 if (bta_ar_cb.avct_registered == 0) 210 { 211 AVCT_Register(mtu, mtu_br, sec_mask); 212 } 213 bta_ar_cb.avct_registered |= mask; 214 } 215 } 216 217 /******************************************************************************* 218 ** 219 ** Function bta_ar_dereg_avct 220 ** 221 ** Description This function is called to deregister from AVCTP. 222 ** 223 ** Returns void 224 ** 225 *******************************************************************************/ 226 void bta_ar_dereg_avct(tBTA_SYS_ID sys_id) 227 { 228 UINT8 mask = bta_ar_id (sys_id); 229 230 bta_ar_cb.avct_registered &= ~mask; 231 232 if (bta_ar_cb.avct_registered == 0) 233 AVCT_Deregister(); 234 } 235 236 /****************************************************************************** 237 ** 238 ** Function bta_ar_reg_avrc 239 ** 240 ** Description This function is called to register an SDP record for AVRCP. 241 ** 242 ** Returns void 243 ** 244 ******************************************************************************/ 245 void bta_ar_reg_avrc(UINT16 service_uuid, char *service_name, char *provider_name, 246 UINT16 categories, tBTA_SYS_ID sys_id) 247 { 248 UINT8 mask = bta_ar_id (sys_id); 249 UINT8 temp[8], *p; 250 251 if (!mask || !categories) 252 return; 253 254 if (service_uuid == UUID_SERVCLASS_AV_REM_CTRL_TARGET) 255 { 256 if (bta_ar_cb.sdp_tg_handle == 0) 257 { 258 bta_ar_cb.tg_registered = mask; 259 bta_ar_cb.sdp_tg_handle = SDP_CreateRecord(); 260 AVRC_AddRecord(service_uuid, service_name, provider_name, categories, bta_ar_cb.sdp_tg_handle); 261 bta_sys_add_uuid(service_uuid); 262 } 263 /* only one TG is allowed (first-come, first-served). 264 * If sdp_tg_handle is non-0, ignore this request */ 265 } 266 else if ((service_uuid == UUID_SERVCLASS_AV_REMOTE_CONTROL) || (service_uuid == UUID_SERVCLASS_AV_REM_CTRL_CONTROL)) 267 { 268 bta_ar_cb.ct_categories [mask - 1] = categories; 269 categories = bta_ar_cb.ct_categories[0]|bta_ar_cb.ct_categories[1]; 270 if (bta_ar_cb.sdp_ct_handle == 0) 271 { 272 bta_ar_cb.sdp_ct_handle = SDP_CreateRecord(); 273 AVRC_AddRecord(service_uuid, service_name, provider_name, categories, bta_ar_cb.sdp_ct_handle); 274 bta_sys_add_uuid(service_uuid); 275 } 276 else 277 { 278 /* multiple CTs are allowed. 279 * Change supported categories on the second one */ 280 p = temp; 281 UINT16_TO_BE_STREAM(p, categories); 282 SDP_AddAttribute(bta_ar_cb.sdp_ct_handle, ATTR_ID_SUPPORTED_FEATURES, UINT_DESC_TYPE, 283 (UINT32)2, (UINT8*)temp); 284 } 285 } 286 } 287 288 /****************************************************************************** 289 ** 290 ** Function bta_ar_dereg_avrc 291 ** 292 ** Description This function is called to de-register/delete an SDP record for AVRCP. 293 ** 294 ** Returns void 295 ** 296 ******************************************************************************/ 297 void bta_ar_dereg_avrc(UINT16 service_uuid, tBTA_SYS_ID sys_id) 298 { 299 UINT8 mask = bta_ar_id (sys_id); 300 UINT16 categories = 0; 301 UINT8 temp[8], *p; 302 303 if (!mask) 304 return; 305 306 if (service_uuid == UUID_SERVCLASS_AV_REM_CTRL_TARGET) 307 { 308 if (bta_ar_cb.sdp_tg_handle && mask == bta_ar_cb.tg_registered) 309 { 310 bta_ar_cb.tg_registered = 0; 311 SDP_DeleteRecord(bta_ar_cb.sdp_tg_handle); 312 bta_ar_cb.sdp_tg_handle = 0; 313 bta_sys_remove_uuid(service_uuid); 314 } 315 } 316 else if (service_uuid == UUID_SERVCLASS_AV_REMOTE_CONTROL) 317 { 318 if (bta_ar_cb.sdp_ct_handle) 319 { 320 bta_ar_cb.ct_categories [mask - 1] = 0; 321 categories = bta_ar_cb.ct_categories[0]|bta_ar_cb.ct_categories[1]; 322 if (!categories) 323 { 324 /* no CT is still registered - cleaup */ 325 SDP_DeleteRecord(bta_ar_cb.sdp_ct_handle); 326 bta_ar_cb.sdp_ct_handle = 0; 327 bta_sys_remove_uuid(service_uuid); 328 } 329 else 330 { 331 /* change supported categories to the remaning one */ 332 p = temp; 333 UINT16_TO_BE_STREAM(p, categories); 334 SDP_AddAttribute(bta_ar_cb.sdp_ct_handle, ATTR_ID_SUPPORTED_FEATURES, UINT_DESC_TYPE, 335 (UINT32)2, (UINT8*)temp); 336 } 337 } 338 } 339 340 } 341