1 /****************************************************************************** 2 * 3 * Copyright 2010-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 of the API for GATT server of BTA. 22 * 23 ******************************************************************************/ 24 25 #include "bt_target.h" 26 27 #include <base/bind.h> 28 #include <string.h> 29 30 #include "bt_common.h" 31 #include "bta_closure_api.h" 32 #include "bta_gatt_api.h" 33 #include "bta_gatts_int.h" 34 #include "bta_sys.h" 35 36 /***************************************************************************** 37 * Constants 38 ****************************************************************************/ 39 40 static const tBTA_SYS_REG bta_gatts_reg = {bta_gatts_hdl_event, 41 BTA_GATTS_Disable}; 42 43 /******************************************************************************* 44 * 45 * Function BTA_GATTS_Disable 46 * 47 * Description This function is called to disable GATTS module 48 * 49 * Parameters None. 50 * 51 * Returns None 52 * 53 ******************************************************************************/ 54 void BTA_GATTS_Disable(void) { 55 if (!bta_sys_is_register(BTA_ID_GATTS)) { 56 LOG(WARNING) << "GATTS Module not enabled/already disabled"; 57 return; 58 } 59 60 BT_HDR* p_buf = (BT_HDR*)osi_malloc(sizeof(BT_HDR)); 61 p_buf->event = BTA_GATTS_API_DISABLE_EVT; 62 bta_sys_sendmsg(p_buf); 63 bta_sys_deregister(BTA_ID_GATTS); 64 } 65 66 /******************************************************************************* 67 * 68 * Function BTA_GATTS_AppRegister 69 * 70 * Description This function is called to register application callbacks 71 * with BTA GATTS module. 72 * 73 * Parameters p_app_uuid - applicaiton UUID 74 * p_cback - pointer to the application callback function. 75 * 76 * Returns None 77 * 78 ******************************************************************************/ 79 void BTA_GATTS_AppRegister(const bluetooth::Uuid& app_uuid, 80 tBTA_GATTS_CBACK* p_cback) { 81 tBTA_GATTS_API_REG* p_buf = 82 (tBTA_GATTS_API_REG*)osi_malloc(sizeof(tBTA_GATTS_API_REG)); 83 84 /* register with BTA system manager */ 85 if (!bta_sys_is_register(BTA_ID_GATTS)) 86 bta_sys_register(BTA_ID_GATTS, &bta_gatts_reg); 87 88 p_buf->hdr.event = BTA_GATTS_API_REG_EVT; 89 p_buf->app_uuid = app_uuid; 90 p_buf->p_cback = p_cback; 91 92 bta_sys_sendmsg(p_buf); 93 } 94 95 /******************************************************************************* 96 * 97 * Function BTA_GATTS_AppDeregister 98 * 99 * Description De-register with GATT Server. 100 * 101 * Parameters app_id: applicatino ID. 102 * 103 * Returns void 104 * 105 ******************************************************************************/ 106 void BTA_GATTS_AppDeregister(tGATT_IF server_if) { 107 tBTA_GATTS_API_DEREG* p_buf = 108 (tBTA_GATTS_API_DEREG*)osi_malloc(sizeof(tBTA_GATTS_API_DEREG)); 109 110 p_buf->hdr.event = BTA_GATTS_API_DEREG_EVT; 111 p_buf->server_if = server_if; 112 113 bta_sys_sendmsg(p_buf); 114 } 115 116 void bta_gatts_add_service_impl(tGATT_IF server_if, 117 std::vector<btgatt_db_element_t> service, 118 BTA_GATTS_AddServiceCb cb) { 119 uint8_t rcb_idx = 120 bta_gatts_find_app_rcb_idx_by_app_if(&bta_gatts_cb, server_if); 121 122 LOG(INFO) << __func__ << ": rcb_idx=" << +rcb_idx; 123 124 if (rcb_idx == BTA_GATTS_INVALID_APP) { 125 cb.Run(GATT_ERROR, server_if, std::move(service)); 126 return; 127 } 128 129 uint8_t srvc_idx = bta_gatts_alloc_srvc_cb(&bta_gatts_cb, rcb_idx); 130 if (srvc_idx == BTA_GATTS_INVALID_APP) { 131 cb.Run(GATT_ERROR, server_if, std::move(service)); 132 return; 133 } 134 135 uint16_t status = GATTS_AddService(server_if, service.data(), service.size()); 136 if (status != GATT_SERVICE_STARTED) { 137 memset(&bta_gatts_cb.srvc_cb[srvc_idx], 0, sizeof(tBTA_GATTS_SRVC_CB)); 138 LOG(ERROR) << __func__ << ": service creation failed."; 139 cb.Run(GATT_ERROR, server_if, std::move(service)); 140 return; 141 } 142 143 bta_gatts_cb.srvc_cb[srvc_idx].service_uuid = service[0].uuid; 144 145 // service_id is equal to service start handle 146 bta_gatts_cb.srvc_cb[srvc_idx].service_id = service[0].attribute_handle; 147 bta_gatts_cb.srvc_cb[srvc_idx].idx = srvc_idx; 148 149 cb.Run(GATT_SUCCESS, server_if, std::move(service)); 150 return; 151 } 152 153 /******************************************************************************* 154 * 155 * Function BTA_GATTS_AddService 156 * 157 * Description Add the given |service| and all included elements to the 158 * GATT database. a |BTA_GATTS_ADD_SRVC_EVT| is triggered to 159 * report the status and attribute handles. 160 * 161 * Parameters server_if: server interface. 162 * service: pointer vector describing service. 163 * 164 * Returns Returns |GATT_SUCCESS| on success or |GATT_ERROR| if the 165 * service cannot be added. 166 * 167 ******************************************************************************/ 168 extern void BTA_GATTS_AddService(tGATT_IF server_if, 169 std::vector<btgatt_db_element_t> service, 170 BTA_GATTS_AddServiceCb cb) { 171 do_in_bta_thread(FROM_HERE, base::Bind(&bta_gatts_add_service_impl, server_if, 172 std::move(service), std::move(cb))); 173 } 174 175 /******************************************************************************* 176 * 177 * Function BTA_GATTS_DeleteService 178 * 179 * Description This function is called to delete a service. When this is 180 * done, a callback event BTA_GATTS_DELETE_EVT is report with 181 * the status. 182 * 183 * Parameters service_id: service_id to be deleted. 184 * 185 * Returns returns none. 186 * 187 ******************************************************************************/ 188 void BTA_GATTS_DeleteService(uint16_t service_id) { 189 BT_HDR* p_buf = (BT_HDR*)osi_malloc(sizeof(BT_HDR)); 190 191 p_buf->event = BTA_GATTS_API_DEL_SRVC_EVT; 192 p_buf->layer_specific = service_id; 193 194 bta_sys_sendmsg(p_buf); 195 } 196 197 /******************************************************************************* 198 * 199 * Function BTA_GATTS_StopService 200 * 201 * Description This function is called to stop a service. 202 * 203 * Parameters service_id - service to be topped. 204 * 205 * Returns None 206 * 207 ******************************************************************************/ 208 void BTA_GATTS_StopService(uint16_t service_id) { 209 BT_HDR* p_buf = (BT_HDR*)osi_malloc(sizeof(BT_HDR)); 210 211 p_buf->event = BTA_GATTS_API_STOP_SRVC_EVT; 212 p_buf->layer_specific = service_id; 213 214 bta_sys_sendmsg(p_buf); 215 } 216 217 /******************************************************************************* 218 * 219 * Function BTA_GATTS_HandleValueIndication 220 * 221 * Description This function is called to read a characteristics 222 * descriptor. 223 * 224 * Parameters bda - remote device bd address to indicate. 225 * attr_id - attribute ID to indicate. 226 * value - data to indicate. 227 * need_confirm - if this indication expects a confirmation or 228 * not. 229 * 230 * Returns None 231 * 232 ******************************************************************************/ 233 void BTA_GATTS_HandleValueIndication(uint16_t conn_id, uint16_t attr_id, 234 std::vector<uint8_t> value, 235 bool need_confirm) { 236 tBTA_GATTS_API_INDICATION* p_buf = 237 (tBTA_GATTS_API_INDICATION*)osi_calloc(sizeof(tBTA_GATTS_API_INDICATION)); 238 239 p_buf->hdr.event = BTA_GATTS_API_INDICATION_EVT; 240 p_buf->hdr.layer_specific = conn_id; 241 p_buf->attr_id = attr_id; 242 p_buf->need_confirm = need_confirm; 243 if (value.size() > 0) { 244 p_buf->len = value.size(); 245 memcpy(p_buf->value, value.data(), value.size()); 246 } 247 248 bta_sys_sendmsg(p_buf); 249 } 250 251 /******************************************************************************* 252 * 253 * Function BTA_GATTS_SendRsp 254 * 255 * Description This function is called to send a response to a request. 256 * 257 * Parameters conn_id - connection identifier. 258 * trans_id - transaction ID. 259 * status - response status 260 * p_msg - response data. 261 * 262 * Returns None 263 * 264 ******************************************************************************/ 265 void BTA_GATTS_SendRsp(uint16_t conn_id, uint32_t trans_id, tGATT_STATUS status, 266 tGATTS_RSP* p_msg) { 267 const size_t len = sizeof(tBTA_GATTS_API_RSP) + sizeof(tGATTS_RSP); 268 tBTA_GATTS_API_RSP* p_buf = (tBTA_GATTS_API_RSP*)osi_calloc(len); 269 270 p_buf->hdr.event = BTA_GATTS_API_RSP_EVT; 271 p_buf->hdr.layer_specific = conn_id; 272 p_buf->trans_id = trans_id; 273 p_buf->status = status; 274 if (p_msg != NULL) { 275 p_buf->p_rsp = (tGATTS_RSP*)(p_buf + 1); 276 memcpy(p_buf->p_rsp, p_msg, sizeof(tGATTS_RSP)); 277 } 278 279 bta_sys_sendmsg(p_buf); 280 } 281 282 /******************************************************************************* 283 * 284 * Function BTA_GATTS_Open 285 * 286 * Description Open a direct open connection or add a background auto 287 * connection bd address 288 * 289 * Parameters server_if: server interface. 290 * remote_bda: remote device BD address. 291 * is_direct: direct connection or background auto connection 292 * transport : Transport on which GATT connection to be opened 293 * (BR/EDR or LE) 294 * 295 * Returns void 296 * 297 ******************************************************************************/ 298 void BTA_GATTS_Open(tGATT_IF server_if, const RawAddress& remote_bda, 299 bool is_direct, tGATT_TRANSPORT transport) { 300 tBTA_GATTS_API_OPEN* p_buf = 301 (tBTA_GATTS_API_OPEN*)osi_malloc(sizeof(tBTA_GATTS_API_OPEN)); 302 303 p_buf->hdr.event = BTA_GATTS_API_OPEN_EVT; 304 p_buf->server_if = server_if; 305 p_buf->is_direct = is_direct; 306 p_buf->transport = transport; 307 p_buf->remote_bda = remote_bda; 308 309 bta_sys_sendmsg(p_buf); 310 } 311 312 /******************************************************************************* 313 * 314 * Function BTA_GATTS_CancelOpen 315 * 316 * Description Cancel a direct open connection or remove a background auto 317 * connection bd address 318 * 319 * Parameters server_if: server interface. 320 * remote_bda: remote device BD address. 321 * is_direct: direct connection or background auto connection 322 * 323 * Returns void 324 * 325 ******************************************************************************/ 326 void BTA_GATTS_CancelOpen(tGATT_IF server_if, const RawAddress& remote_bda, 327 bool is_direct) { 328 tBTA_GATTS_API_CANCEL_OPEN* p_buf = (tBTA_GATTS_API_CANCEL_OPEN*)osi_malloc( 329 sizeof(tBTA_GATTS_API_CANCEL_OPEN)); 330 331 p_buf->hdr.event = BTA_GATTS_API_CANCEL_OPEN_EVT; 332 p_buf->server_if = server_if; 333 p_buf->is_direct = is_direct; 334 p_buf->remote_bda = remote_bda; 335 336 bta_sys_sendmsg(p_buf); 337 } 338 339 /******************************************************************************* 340 * 341 * Function BTA_GATTS_Close 342 * 343 * Description Close a connection a remote device. 344 * 345 * Parameters conn_id: connectino ID to be closed. 346 * 347 * Returns void 348 * 349 ******************************************************************************/ 350 void BTA_GATTS_Close(uint16_t conn_id) { 351 BT_HDR* p_buf = (BT_HDR*)osi_malloc(sizeof(BT_HDR)); 352 353 p_buf->event = BTA_GATTS_API_CLOSE_EVT; 354 p_buf->layer_specific = conn_id; 355 356 bta_sys_sendmsg(p_buf); 357 } 358