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