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 32tBTA_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*******************************************************************************/ 44static 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*******************************************************************************/ 68void 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*******************************************************************************/ 83static 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*******************************************************************************/ 101void 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_ERROR1("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*******************************************************************************/ 141void 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*******************************************************************************/ 173void 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*******************************************************************************/ 203void 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*******************************************************************************/ 226void 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******************************************************************************/ 245void 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#if ( BTM_EIR_SERVER_INCLUDED == TRUE )&&(BTA_EIR_CANNED_UUID_LIST != TRUE) 262 bta_sys_add_uuid(service_uuid); 263#endif 264 } 265 /* only one TG is allowed (first-come, first-served). 266 * If sdp_tg_handle is non-0, ignore this request */ 267 } 268 else if ((service_uuid == UUID_SERVCLASS_AV_REMOTE_CONTROL) || (service_uuid == UUID_SERVCLASS_AV_REM_CTRL_CONTROL)) 269 { 270 bta_ar_cb.ct_categories [mask - 1] = categories; 271 categories = bta_ar_cb.ct_categories[0]|bta_ar_cb.ct_categories[1]; 272 if (bta_ar_cb.sdp_ct_handle == 0) 273 { 274 bta_ar_cb.sdp_ct_handle = SDP_CreateRecord(); 275 AVRC_AddRecord(service_uuid, service_name, provider_name, categories, bta_ar_cb.sdp_ct_handle); 276#if ( BTM_EIR_SERVER_INCLUDED == TRUE )&&(BTA_EIR_CANNED_UUID_LIST != TRUE) 277 bta_sys_add_uuid(service_uuid); 278#endif 279 } 280 else 281 { 282 /* multiple CTs are allowed. 283 * Change supported categories on the second one */ 284 p = temp; 285 UINT16_TO_BE_STREAM(p, categories); 286 SDP_AddAttribute(bta_ar_cb.sdp_ct_handle, ATTR_ID_SUPPORTED_FEATURES, UINT_DESC_TYPE, 287 (UINT32)2, (UINT8*)temp); 288 } 289 } 290} 291 292/****************************************************************************** 293** 294** Function bta_ar_dereg_avrc 295** 296** Description This function is called to de-register/delete an SDP record for AVRCP. 297** 298** Returns void 299** 300******************************************************************************/ 301void bta_ar_dereg_avrc(UINT16 service_uuid, tBTA_SYS_ID sys_id) 302{ 303 UINT8 mask = bta_ar_id (sys_id); 304 UINT16 categories = 0; 305 UINT8 temp[8], *p; 306 307 if (!mask) 308 return; 309 310 if (service_uuid == UUID_SERVCLASS_AV_REM_CTRL_TARGET) 311 { 312 if (bta_ar_cb.sdp_tg_handle && mask == bta_ar_cb.tg_registered) 313 { 314 bta_ar_cb.tg_registered = 0; 315 SDP_DeleteRecord(bta_ar_cb.sdp_tg_handle); 316 bta_ar_cb.sdp_tg_handle = 0; 317#if ( BTM_EIR_SERVER_INCLUDED == TRUE )&&(BTA_EIR_CANNED_UUID_LIST != TRUE) 318 bta_sys_remove_uuid(service_uuid); 319#endif 320 } 321 } 322 else if (service_uuid == UUID_SERVCLASS_AV_REMOTE_CONTROL) 323 { 324 if (bta_ar_cb.sdp_ct_handle) 325 { 326 bta_ar_cb.ct_categories [mask - 1] = 0; 327 categories = bta_ar_cb.ct_categories[0]|bta_ar_cb.ct_categories[1]; 328 if (!categories) 329 { 330 /* no CT is still registered - cleaup */ 331 SDP_DeleteRecord(bta_ar_cb.sdp_ct_handle); 332 bta_ar_cb.sdp_ct_handle = 0; 333#if ( BTM_EIR_SERVER_INCLUDED == TRUE )&&(BTA_EIR_CANNED_UUID_LIST != TRUE) 334 bta_sys_remove_uuid(service_uuid); 335#endif 336 } 337 else 338 { 339 /* change supported categories to the remaning one */ 340 p = temp; 341 UINT16_TO_BE_STREAM(p, categories); 342 SDP_AddAttribute(bta_ar_cb.sdp_ct_handle, ATTR_ID_SUPPORTED_FEATURES, UINT_DESC_TYPE, 343 (UINT32)2, (UINT8*)temp); 344 } 345 } 346 } 347 348} 349