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