1 /****************************************************************************** 2 * 3 * Copyright (C) 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 <string.h> 28 29 #include "bt_common.h" 30 #include "bta_gatt_api.h" 31 #include "bta_gatts_int.h" 32 #include "bta_sys.h" 33 34 void btif_to_bta_uuid(tBT_UUID* p_dest, const bt_uuid_t* p_src); 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) == false) { 56 APPL_TRACE_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(tBT_UUID* p_app_uuid, tBTA_GATTS_CBACK* p_cback) { 80 tBTA_GATTS_API_REG* p_buf = 81 (tBTA_GATTS_API_REG*)osi_malloc(sizeof(tBTA_GATTS_API_REG)); 82 83 /* register with BTA system manager */ 84 if (bta_sys_is_register(BTA_ID_GATTS) == false) 85 bta_sys_register(BTA_ID_GATTS, &bta_gatts_reg); 86 87 p_buf->hdr.event = BTA_GATTS_API_REG_EVT; 88 if (p_app_uuid != NULL) 89 memcpy(&p_buf->app_uuid, p_app_uuid, sizeof(tBT_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(tBTA_GATTS_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 /******************************************************************************* 117 * 118 * Function BTA_GATTS_AddService 119 * 120 * Description Add the given |service| and all included elements to the 121 * GATT database. a |BTA_GATTS_ADD_SRVC_EVT| is triggered to 122 * report the status and attribute handles. 123 * 124 * Parameters server_if: server interface. 125 * service: pointer vector describing service. 126 * 127 * Returns Returns |BTA_GATT_OK| on success or |BTA_GATT_ERROR| if the 128 * service cannot be added. 129 * 130 ******************************************************************************/ 131 extern uint16_t BTA_GATTS_AddService(tBTA_GATTS_IF server_if, 132 vector<btgatt_db_element_t>& service) { 133 uint8_t rcb_idx = 134 bta_gatts_find_app_rcb_idx_by_app_if(&bta_gatts_cb, server_if); 135 136 APPL_TRACE_ERROR("%s: rcb_idx = %d", __func__, rcb_idx); 137 138 if (rcb_idx == BTA_GATTS_INVALID_APP) return BTA_GATT_ERROR; 139 140 uint8_t srvc_idx = bta_gatts_alloc_srvc_cb(&bta_gatts_cb, rcb_idx); 141 if (srvc_idx == BTA_GATTS_INVALID_APP) return BTA_GATT_ERROR; 142 143 uint16_t status = GATTS_AddService(server_if, service.data(), service.size()); 144 145 if (status == GATT_SERVICE_STARTED) { 146 btif_to_bta_uuid(&bta_gatts_cb.srvc_cb[srvc_idx].service_uuid, 147 &service[0].uuid); 148 149 // service_id is equal to service start handle 150 bta_gatts_cb.srvc_cb[srvc_idx].service_id = service[0].attribute_handle; 151 bta_gatts_cb.srvc_cb[srvc_idx].idx = srvc_idx; 152 153 return BTA_GATT_OK; 154 } else { 155 memset(&bta_gatts_cb.srvc_cb[srvc_idx], 0, sizeof(tBTA_GATTS_SRVC_CB)); 156 APPL_TRACE_ERROR("%s: service creation failed.", __func__); 157 return BTA_GATT_ERROR; 158 } 159 } 160 161 /******************************************************************************* 162 * 163 * Function BTA_GATTS_DeleteService 164 * 165 * Description This function is called to delete a service. When this is 166 * done, a callback event BTA_GATTS_DELETE_EVT is report with 167 * the status. 168 * 169 * Parameters service_id: service_id to be deleted. 170 * 171 * Returns returns none. 172 * 173 ******************************************************************************/ 174 void BTA_GATTS_DeleteService(uint16_t service_id) { 175 BT_HDR* p_buf = (BT_HDR*)osi_malloc(sizeof(BT_HDR)); 176 177 p_buf->event = BTA_GATTS_API_DEL_SRVC_EVT; 178 p_buf->layer_specific = service_id; 179 180 bta_sys_sendmsg(p_buf); 181 } 182 183 /******************************************************************************* 184 * 185 * Function BTA_GATTS_StopService 186 * 187 * Description This function is called to stop a service. 188 * 189 * Parameters service_id - service to be topped. 190 * 191 * Returns None 192 * 193 ******************************************************************************/ 194 void BTA_GATTS_StopService(uint16_t service_id) { 195 BT_HDR* p_buf = (BT_HDR*)osi_malloc(sizeof(BT_HDR)); 196 197 p_buf->event = BTA_GATTS_API_STOP_SRVC_EVT; 198 p_buf->layer_specific = service_id; 199 200 bta_sys_sendmsg(p_buf); 201 } 202 203 /******************************************************************************* 204 * 205 * Function BTA_GATTS_HandleValueIndication 206 * 207 * Description This function is called to read a characteristics 208 * descriptor. 209 * 210 * Parameters bda - remote device bd address to indicate. 211 * attr_id - attribute ID to indicate. 212 * value - data to indicate. 213 * need_confirm - if this indication expects a confirmation or 214 * not. 215 * 216 * Returns None 217 * 218 ******************************************************************************/ 219 void BTA_GATTS_HandleValueIndication(uint16_t conn_id, uint16_t attr_id, 220 std::vector<uint8_t> value, 221 bool need_confirm) { 222 tBTA_GATTS_API_INDICATION* p_buf = 223 (tBTA_GATTS_API_INDICATION*)osi_calloc(sizeof(tBTA_GATTS_API_INDICATION)); 224 225 p_buf->hdr.event = BTA_GATTS_API_INDICATION_EVT; 226 p_buf->hdr.layer_specific = conn_id; 227 p_buf->attr_id = attr_id; 228 p_buf->need_confirm = need_confirm; 229 if (value.size() > 0) { 230 p_buf->len = value.size(); 231 memcpy(p_buf->value, value.data(), value.size()); 232 } 233 234 bta_sys_sendmsg(p_buf); 235 } 236 237 /******************************************************************************* 238 * 239 * Function BTA_GATTS_SendRsp 240 * 241 * Description This function is called to send a response to a request. 242 * 243 * Parameters conn_id - connection identifier. 244 * trans_id - transaction ID. 245 * status - response status 246 * p_msg - response data. 247 * 248 * Returns None 249 * 250 ******************************************************************************/ 251 void BTA_GATTS_SendRsp(uint16_t conn_id, uint32_t trans_id, 252 tBTA_GATT_STATUS status, tBTA_GATTS_RSP* p_msg) { 253 const size_t len = sizeof(tBTA_GATTS_API_RSP) + sizeof(tBTA_GATTS_RSP); 254 tBTA_GATTS_API_RSP* p_buf = (tBTA_GATTS_API_RSP*)osi_calloc(len); 255 256 p_buf->hdr.event = BTA_GATTS_API_RSP_EVT; 257 p_buf->hdr.layer_specific = conn_id; 258 p_buf->trans_id = trans_id; 259 p_buf->status = status; 260 if (p_msg != NULL) { 261 p_buf->p_rsp = (tBTA_GATTS_RSP*)(p_buf + 1); 262 memcpy(p_buf->p_rsp, p_msg, sizeof(tBTA_GATTS_RSP)); 263 } 264 265 bta_sys_sendmsg(p_buf); 266 } 267 268 /******************************************************************************* 269 * 270 * Function BTA_GATTS_Open 271 * 272 * Description Open a direct open connection or add a background auto 273 * connection bd address 274 * 275 * Parameters server_if: server interface. 276 * remote_bda: remote device BD address. 277 * is_direct: direct connection or background auto connection 278 * transport : Transport on which GATT connection to be opened 279 * (BR/EDR or LE) 280 * 281 * Returns void 282 * 283 ******************************************************************************/ 284 void BTA_GATTS_Open(tBTA_GATTS_IF server_if, BD_ADDR remote_bda, bool is_direct, 285 tBTA_GATT_TRANSPORT transport) { 286 tBTA_GATTS_API_OPEN* p_buf = 287 (tBTA_GATTS_API_OPEN*)osi_malloc(sizeof(tBTA_GATTS_API_OPEN)); 288 289 p_buf->hdr.event = BTA_GATTS_API_OPEN_EVT; 290 p_buf->server_if = server_if; 291 p_buf->is_direct = is_direct; 292 p_buf->transport = transport; 293 memcpy(p_buf->remote_bda, remote_bda, BD_ADDR_LEN); 294 295 bta_sys_sendmsg(p_buf); 296 } 297 298 /******************************************************************************* 299 * 300 * Function BTA_GATTS_CancelOpen 301 * 302 * Description Cancel a direct open connection or remove a background auto 303 * connection bd address 304 * 305 * Parameters server_if: server interface. 306 * remote_bda: remote device BD address. 307 * is_direct: direct connection or background auto connection 308 * 309 * Returns void 310 * 311 ******************************************************************************/ 312 void BTA_GATTS_CancelOpen(tBTA_GATTS_IF server_if, BD_ADDR remote_bda, 313 bool is_direct) { 314 tBTA_GATTS_API_CANCEL_OPEN* p_buf = (tBTA_GATTS_API_CANCEL_OPEN*)osi_malloc( 315 sizeof(tBTA_GATTS_API_CANCEL_OPEN)); 316 317 p_buf->hdr.event = BTA_GATTS_API_CANCEL_OPEN_EVT; 318 p_buf->server_if = server_if; 319 p_buf->is_direct = is_direct; 320 memcpy(p_buf->remote_bda, remote_bda, BD_ADDR_LEN); 321 322 bta_sys_sendmsg(p_buf); 323 } 324 325 /******************************************************************************* 326 * 327 * Function BTA_GATTS_Close 328 * 329 * Description Close a connection a remote device. 330 * 331 * Parameters conn_id: connectino ID to be closed. 332 * 333 * Returns void 334 * 335 ******************************************************************************/ 336 void BTA_GATTS_Close(uint16_t conn_id) { 337 BT_HDR* p_buf = (BT_HDR*)osi_malloc(sizeof(BT_HDR)); 338 339 p_buf->event = BTA_GATTS_API_CLOSE_EVT; 340 p_buf->layer_specific = conn_id; 341 342 bta_sys_sendmsg(p_buf); 343 } 344