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 module of BTA.
22 *
23 ******************************************************************************/
24
25 #define LOG_TAG "bta_gattc_api"
26
27 #include <base/functional/bind.h>
28 #include <bluetooth/log.h>
29
30 #include <ios>
31 #include <list>
32 #include <vector>
33
34 #include "bta/gatt/bta_gattc_int.h"
35 #include "gd/hci/uuid.h"
36 #include "gd/os/rand.h"
37 #include "os/log.h"
38 #include "osi/include/allocator.h"
39 #include "stack/include/bt_hdr.h"
40 #include "stack/include/main_thread.h"
41 #include "types/bluetooth/uuid.h"
42 #include "types/bt_transport.h"
43 #include "types/raw_address.h"
44
45 using bluetooth::Uuid;
46 using namespace bluetooth;
47
48 /*****************************************************************************
49 * Constants
50 ****************************************************************************/
51
52 static const tBTA_SYS_REG bta_gattc_reg = {bta_gattc_hdl_event,
53 BTA_GATTC_Disable};
54
55 /*******************************************************************************
56 *
57 * Function BTA_GATTC_Disable
58 *
59 * Description This function is called to disable GATTC module
60 *
61 * Parameters None.
62 *
63 * Returns None
64 *
65 ******************************************************************************/
BTA_GATTC_Disable(void)66 void BTA_GATTC_Disable(void) {
67 if (!bta_sys_is_register(BTA_ID_GATTC)) {
68 log::warn("GATTC Module not enabled/already disabled");
69 return;
70 }
71
72 do_in_main_thread(FROM_HERE, base::BindOnce(&bta_gattc_disable));
73 bta_sys_deregister(BTA_ID_GATTC);
74 }
75
76 /**
77 * This function is called to register application callbacks with BTA GATTC
78 * module. |client_cb| pointer to the application callback function.
79 * |cb| one time callback when registration is finished
80 */
BTA_GATTC_AppRegister(tBTA_GATTC_CBACK * p_client_cb,BtaAppRegisterCallback cb,bool eatt_support)81 void BTA_GATTC_AppRegister(tBTA_GATTC_CBACK* p_client_cb,
82 BtaAppRegisterCallback cb, bool eatt_support) {
83 log::debug("eatt_support={}", eatt_support);
84 if (!bta_sys_is_register(BTA_ID_GATTC)) {
85 log::debug("BTA_ID_GATTC not registered in BTA, registering it");
86 bta_sys_register(BTA_ID_GATTC, &bta_gattc_reg);
87 }
88
89 Uuid uuid =
90 Uuid::From128BitBE(bluetooth::os::GenerateRandom<Uuid::kNumBytes128>());
91
92 do_in_main_thread(FROM_HERE,
93 base::BindOnce(&bta_gattc_register, uuid, p_client_cb,
94 std::move(cb), eatt_support));
95 }
96
app_deregister_impl(tGATT_IF client_if)97 static void app_deregister_impl(tGATT_IF client_if) {
98 tBTA_GATTC_RCB* p_clreg = bta_gattc_cl_get_regcb(client_if);
99
100 if (p_clreg != nullptr) {
101 bta_gattc_deregister(p_clreg);
102 } else {
103 log::error("Unknown GATT ID: {}, state: {}", client_if, bta_gattc_cb.state);
104 }
105 }
106 /*******************************************************************************
107 *
108 * Function BTA_GATTC_AppDeregister
109 *
110 * Description This function is called to deregister an application
111 * from BTA GATTC module.
112 *
113 * Parameters client_if - client interface identifier.
114 *
115 * Returns None
116 *
117 ******************************************************************************/
BTA_GATTC_AppDeregister(tGATT_IF client_if)118 void BTA_GATTC_AppDeregister(tGATT_IF client_if) {
119 do_in_main_thread(FROM_HERE, base::BindOnce(&app_deregister_impl, client_if));
120 }
121
122 /*******************************************************************************
123 *
124 * Function BTA_GATTC_Open
125 *
126 * Description Open a direct connection or add a background auto connection
127 * bd address
128 *
129 * Parameters client_if: server interface.
130 * remote_bda: remote device BD address.
131 * connection_type: connection type used for the peer device
132 * transport: Transport to be used for GATT connection
133 * (BREDR/LE)
134 * initiating_phys: LE PHY to use, optional
135 * opportunistic: whether the connection shall be
136 * opportunistic, and don't impact the disconnection timer
137 *
138 ******************************************************************************/
BTA_GATTC_Open(tGATT_IF client_if,const RawAddress & remote_bda,tBTM_BLE_CONN_TYPE connection_type,bool opportunistic)139 void BTA_GATTC_Open(tGATT_IF client_if, const RawAddress& remote_bda,
140 tBTM_BLE_CONN_TYPE connection_type, bool opportunistic) {
141 constexpr uint8_t kPhyLe1M = 0x01; // From the old controller shim.
142 uint8_t phy = kPhyLe1M;
143 BTA_GATTC_Open(client_if, remote_bda, connection_type, BT_TRANSPORT_LE,
144 opportunistic, phy);
145 }
146
BTA_GATTC_Open(tGATT_IF client_if,const RawAddress & remote_bda,tBLE_ADDR_TYPE addr_type,tBTM_BLE_CONN_TYPE connection_type,tBT_TRANSPORT transport,bool opportunistic,uint8_t initiating_phys)147 void BTA_GATTC_Open(tGATT_IF client_if, const RawAddress& remote_bda,
148 tBLE_ADDR_TYPE addr_type,
149 tBTM_BLE_CONN_TYPE connection_type, tBT_TRANSPORT transport,
150 bool opportunistic, uint8_t initiating_phys) {
151 tBTA_GATTC_DATA data = {
152 .api_conn =
153 {
154 .hdr =
155 {
156 .event = BTA_GATTC_API_OPEN_EVT,
157 },
158 .remote_bda = remote_bda,
159 .client_if = client_if,
160 .connection_type = connection_type,
161 .transport = transport,
162 .initiating_phys = initiating_phys,
163 .opportunistic = opportunistic,
164 .remote_addr_type = addr_type,
165 },
166 };
167
168 post_on_bt_main([data]() { bta_gattc_process_api_open(&data); });
169 }
170
BTA_GATTC_Open(tGATT_IF client_if,const RawAddress & remote_bda,tBTM_BLE_CONN_TYPE connection_type,tBT_TRANSPORT transport,bool opportunistic,uint8_t initiating_phys)171 void BTA_GATTC_Open(tGATT_IF client_if, const RawAddress& remote_bda,
172 tBTM_BLE_CONN_TYPE connection_type, tBT_TRANSPORT transport,
173 bool opportunistic, uint8_t initiating_phys) {
174 BTA_GATTC_Open(client_if, remote_bda, BLE_ADDR_PUBLIC, connection_type,
175 BT_TRANSPORT_LE, opportunistic, initiating_phys);
176 }
177
178 /*******************************************************************************
179 *
180 * Function BTA_GATTC_CancelOpen
181 *
182 * Description Cancel a direct open connection or remove a background auto
183 * connection
184 * bd address
185 *
186 * Parameters client_if: server interface.
187 * remote_bda: remote device BD address.
188 * is_direct: direct connection or background auto connection
189 *
190 * Returns void
191 *
192 ******************************************************************************/
BTA_GATTC_CancelOpen(tGATT_IF client_if,const RawAddress & remote_bda,bool is_direct)193 void BTA_GATTC_CancelOpen(tGATT_IF client_if, const RawAddress& remote_bda,
194 bool is_direct) {
195 tBTA_GATTC_API_CANCEL_OPEN* p_buf = (tBTA_GATTC_API_CANCEL_OPEN*)osi_malloc(
196 sizeof(tBTA_GATTC_API_CANCEL_OPEN));
197
198 p_buf->hdr.event = BTA_GATTC_API_CANCEL_OPEN_EVT;
199 p_buf->client_if = client_if;
200 p_buf->is_direct = is_direct;
201 p_buf->remote_bda = remote_bda;
202
203 bta_sys_sendmsg(p_buf);
204 }
205
206 /*******************************************************************************
207 *
208 * Function BTA_GATTC_Close
209 *
210 * Description Close a connection to a GATT server.
211 *
212 * Parameters conn_id: connectino ID to be closed.
213 *
214 * Returns void
215 *
216 ******************************************************************************/
BTA_GATTC_Close(uint16_t conn_id)217 void BTA_GATTC_Close(uint16_t conn_id) {
218 BT_HDR_RIGID* p_buf = (BT_HDR_RIGID*)osi_malloc(sizeof(BT_HDR_RIGID));
219
220 p_buf->event = BTA_GATTC_API_CLOSE_EVT;
221 p_buf->layer_specific = conn_id;
222
223 bta_sys_sendmsg(p_buf);
224 }
225
226 /*******************************************************************************
227 *
228 * Function BTA_GATTC_ConfigureMTU
229 *
230 * Description Configure the MTU size in the GATT channel. This can be done
231 * only once per connection.
232 *
233 * Parameters conn_id: connection ID.
234 * mtu: desired MTU size to use.
235 *
236 * Returns void
237 *
238 ******************************************************************************/
239
BTA_GATTC_ConfigureMTU(uint16_t conn_id,uint16_t mtu)240 void BTA_GATTC_ConfigureMTU(uint16_t conn_id, uint16_t mtu) {
241 BTA_GATTC_ConfigureMTU(conn_id, mtu, NULL, NULL);
242 }
243
BTA_GATTC_ConfigureMTU(uint16_t conn_id,uint16_t mtu,GATT_CONFIGURE_MTU_OP_CB callback,void * cb_data)244 void BTA_GATTC_ConfigureMTU(uint16_t conn_id, uint16_t mtu,
245 GATT_CONFIGURE_MTU_OP_CB callback, void* cb_data) {
246 tBTA_GATTC_API_CFG_MTU* p_buf =
247 (tBTA_GATTC_API_CFG_MTU*)osi_malloc(sizeof(tBTA_GATTC_API_CFG_MTU));
248
249 p_buf->hdr.event = BTA_GATTC_API_CFG_MTU_EVT;
250 p_buf->hdr.layer_specific = conn_id;
251 p_buf->mtu = mtu;
252 p_buf->mtu_cb = callback;
253 p_buf->mtu_cb_data = cb_data;
254
255 bta_sys_sendmsg(p_buf);
256 }
257
BTA_GATTC_ServiceSearchAllRequest(uint16_t conn_id)258 void BTA_GATTC_ServiceSearchAllRequest(uint16_t conn_id) {
259 const size_t len = sizeof(tBTA_GATTC_API_SEARCH);
260 tBTA_GATTC_API_SEARCH* p_buf = (tBTA_GATTC_API_SEARCH*)osi_calloc(len);
261
262 p_buf->hdr.event = BTA_GATTC_API_SEARCH_EVT;
263 p_buf->hdr.layer_specific = conn_id;
264 p_buf->p_srvc_uuid = NULL;
265
266 bta_sys_sendmsg(p_buf);
267 }
268
BTA_GATTC_ServiceSearchRequest(uint16_t conn_id,Uuid p_srvc_uuid)269 void BTA_GATTC_ServiceSearchRequest(uint16_t conn_id, Uuid p_srvc_uuid) {
270 const size_t len = sizeof(tBTA_GATTC_API_SEARCH) + sizeof(Uuid);
271 tBTA_GATTC_API_SEARCH* p_buf = (tBTA_GATTC_API_SEARCH*)osi_calloc(len);
272
273 p_buf->hdr.event = BTA_GATTC_API_SEARCH_EVT;
274 p_buf->hdr.layer_specific = conn_id;
275 p_buf->p_srvc_uuid = (Uuid*)(p_buf + 1);
276 *p_buf->p_srvc_uuid = p_srvc_uuid;
277
278 bta_sys_sendmsg(p_buf);
279 }
280
BTA_GATTC_DiscoverServiceByUuid(uint16_t conn_id,const Uuid & srvc_uuid)281 void BTA_GATTC_DiscoverServiceByUuid(uint16_t conn_id, const Uuid& srvc_uuid) {
282 do_in_main_thread(
283 FROM_HERE,
284 base::BindOnce(
285 base::IgnoreResult<tGATT_STATUS (*)(uint16_t, tGATT_DISC_TYPE,
286 uint16_t, uint16_t, const Uuid&)>(
287 &GATTC_Discover),
288 conn_id, GATT_DISC_SRVC_BY_UUID, 0x0001, 0xFFFF, srvc_uuid));
289 }
290
291 /*******************************************************************************
292 *
293 * Function BTA_GATTC_GetServices
294 *
295 * Description This function is called to find the services on the given
296 * server.
297 *
298 * Parameters conn_id: connection ID which identify the server.
299 *
300 * Returns returns list of gatt::Service or NULL.
301 *
302 ******************************************************************************/
BTA_GATTC_GetServices(uint16_t conn_id)303 const std::list<gatt::Service>* BTA_GATTC_GetServices(uint16_t conn_id) {
304 return bta_gattc_get_services(conn_id);
305 }
306
307 /*******************************************************************************
308 *
309 * Function BTA_GATTC_GetCharacteristic
310 *
311 * Description This function is called to find the characteristic on the
312 * given server.
313 *
314 * Parameters conn_id - connection ID which identify the server.
315 * handle - characteristic handle
316 *
317 * Returns returns pointer to gatt::Characteristic or NULL.
318 *
319 ******************************************************************************/
BTA_GATTC_GetCharacteristic(uint16_t conn_id,uint16_t handle)320 const gatt::Characteristic* BTA_GATTC_GetCharacteristic(uint16_t conn_id,
321 uint16_t handle) {
322 return bta_gattc_get_characteristic(conn_id, handle);
323 }
324
325 /*******************************************************************************
326 *
327 * Function BTA_GATTC_GetDescriptor
328 *
329 * Description This function is called to find the characteristic on the
330 * given server.
331 *
332 * Parameters conn_id - connection ID which identify the server.
333 * handle - descriptor handle
334 *
335 * Returns returns pointer to gatt::Descriptor or NULL.
336 *
337 ******************************************************************************/
BTA_GATTC_GetDescriptor(uint16_t conn_id,uint16_t handle)338 const gatt::Descriptor* BTA_GATTC_GetDescriptor(uint16_t conn_id,
339 uint16_t handle) {
340 return bta_gattc_get_descriptor(conn_id, handle);
341 }
342
343 /* Return characteristic that owns descriptor with handle equal to |handle|, or
344 * NULL */
BTA_GATTC_GetOwningCharacteristic(uint16_t conn_id,uint16_t handle)345 const gatt::Characteristic* BTA_GATTC_GetOwningCharacteristic(uint16_t conn_id,
346 uint16_t handle) {
347 return bta_gattc_get_owning_characteristic(conn_id, handle);
348 }
349
350 /* Return service that owns descriptor or characteristic with handle equal to
351 * |handle|, or NULL */
BTA_GATTC_GetOwningService(uint16_t conn_id,uint16_t handle)352 const gatt::Service* BTA_GATTC_GetOwningService(uint16_t conn_id,
353 uint16_t handle) {
354 return bta_gattc_get_service_for_handle(conn_id, handle);
355 }
356
357 /*******************************************************************************
358 *
359 * Function BTA_GATTC_GetGattDb
360 *
361 * Description This function is called to get the GATT database.
362 *
363 * Parameters conn_id: connection ID which identify the server.
364 * db: output parameter which will contain the GATT database
365 * copy. Caller is responsible for freeing it.
366 * count: number of elements in database.
367 *
368 ******************************************************************************/
BTA_GATTC_GetGattDb(uint16_t conn_id,uint16_t start_handle,uint16_t end_handle,btgatt_db_element_t ** db,int * count)369 void BTA_GATTC_GetGattDb(uint16_t conn_id, uint16_t start_handle,
370 uint16_t end_handle, btgatt_db_element_t** db,
371 int* count) {
372 bta_gattc_get_gatt_db(conn_id, start_handle, end_handle, db, count);
373 }
374
375 /*******************************************************************************
376 *
377 * Function BTA_GATTC_ReadCharacteristic
378 *
379 * Description This function is called to read a characteristics value
380 *
381 * Parameters conn_id - connection ID.
382 * handle - characteritic handle to read.
383 *
384 * Returns None
385 *
386 ******************************************************************************/
BTA_GATTC_ReadCharacteristic(uint16_t conn_id,uint16_t handle,tGATT_AUTH_REQ auth_req,GATT_READ_OP_CB callback,void * cb_data)387 void BTA_GATTC_ReadCharacteristic(uint16_t conn_id, uint16_t handle,
388 tGATT_AUTH_REQ auth_req,
389 GATT_READ_OP_CB callback, void* cb_data) {
390 tBTA_GATTC_API_READ* p_buf =
391 (tBTA_GATTC_API_READ*)osi_calloc(sizeof(tBTA_GATTC_API_READ));
392
393 p_buf->hdr.event = BTA_GATTC_API_READ_EVT;
394 p_buf->hdr.layer_specific = conn_id;
395 p_buf->is_multi_read = false;
396 p_buf->auth_req = auth_req;
397 p_buf->handle = handle;
398 p_buf->read_cb = callback;
399 p_buf->read_cb_data = cb_data;
400
401 bta_sys_sendmsg(p_buf);
402 }
403
404 /**
405 * This function is called to read a value of characteristic with uuid equal to
406 * |uuid|
407 */
BTA_GATTC_ReadUsingCharUuid(uint16_t conn_id,const Uuid & uuid,uint16_t s_handle,uint16_t e_handle,tGATT_AUTH_REQ auth_req,GATT_READ_OP_CB callback,void * cb_data)408 void BTA_GATTC_ReadUsingCharUuid(uint16_t conn_id, const Uuid& uuid,
409 uint16_t s_handle, uint16_t e_handle,
410 tGATT_AUTH_REQ auth_req,
411 GATT_READ_OP_CB callback, void* cb_data) {
412 tBTA_GATTC_API_READ* p_buf =
413 (tBTA_GATTC_API_READ*)osi_calloc(sizeof(tBTA_GATTC_API_READ));
414
415 p_buf->hdr.event = BTA_GATTC_API_READ_EVT;
416 p_buf->hdr.layer_specific = conn_id;
417 p_buf->is_multi_read = false;
418 p_buf->auth_req = auth_req;
419 p_buf->handle = 0;
420 p_buf->uuid = uuid;
421 p_buf->s_handle = s_handle;
422 p_buf->e_handle = e_handle;
423 p_buf->read_cb = callback;
424 p_buf->read_cb_data = cb_data;
425
426 bta_sys_sendmsg(p_buf);
427 }
428
429 /*******************************************************************************
430 *
431 * Function BTA_GATTC_ReadCharDescr
432 *
433 * Description This function is called to read a descriptor value.
434 *
435 * Parameters conn_id - connection ID.
436 * handle - descriptor handle to read.
437 *
438 * Returns None
439 *
440 ******************************************************************************/
BTA_GATTC_ReadCharDescr(uint16_t conn_id,uint16_t handle,tGATT_AUTH_REQ auth_req,GATT_READ_OP_CB callback,void * cb_data)441 void BTA_GATTC_ReadCharDescr(uint16_t conn_id, uint16_t handle,
442 tGATT_AUTH_REQ auth_req, GATT_READ_OP_CB callback,
443 void* cb_data) {
444 tBTA_GATTC_API_READ* p_buf =
445 (tBTA_GATTC_API_READ*)osi_calloc(sizeof(tBTA_GATTC_API_READ));
446
447 p_buf->hdr.event = BTA_GATTC_API_READ_EVT;
448 p_buf->hdr.layer_specific = conn_id;
449 p_buf->is_multi_read = false;
450 p_buf->auth_req = auth_req;
451 p_buf->handle = handle;
452 p_buf->read_cb = callback;
453 p_buf->read_cb_data = cb_data;
454
455 bta_sys_sendmsg(p_buf);
456 }
457
458 /*******************************************************************************
459 *
460 * Function BTA_GATTC_ReadMultiple
461 *
462 * Description This function is called to read multiple characteristic or
463 * characteristic descriptors.
464 *
465 * Parameters conn_id - connectino ID.
466 * p_read_multi - pointer to the read multiple parameter.
467 * variable_len - whether "read multi variable length" variant
468 * shall be used.
469 *
470 *
471 * Returns None
472 *
473 ******************************************************************************/
BTA_GATTC_ReadMultiple(uint16_t conn_id,tBTA_GATTC_MULTI & handles,bool variable_len,tGATT_AUTH_REQ auth_req,GATT_READ_MULTI_OP_CB callback,void * cb_data)474 void BTA_GATTC_ReadMultiple(uint16_t conn_id, tBTA_GATTC_MULTI& handles,
475 bool variable_len, tGATT_AUTH_REQ auth_req,
476 GATT_READ_MULTI_OP_CB callback, void* cb_data) {
477 tBTA_GATTC_API_READ_MULTI* p_buf =
478 (tBTA_GATTC_API_READ_MULTI*)osi_calloc(sizeof(tBTA_GATTC_API_READ_MULTI));
479
480 p_buf->hdr.event = BTA_GATTC_API_READ_MULTI_EVT;
481 p_buf->hdr.layer_specific = conn_id;
482 p_buf->is_multi_read = true;
483 p_buf->auth_req = auth_req;
484 p_buf->handles = handles;
485 p_buf->variable_len = variable_len;
486 p_buf->read_cb = callback;
487 p_buf->read_cb_data = cb_data;
488 bta_sys_sendmsg(p_buf);
489 }
490
491 /*******************************************************************************
492 *
493 * Function BTA_GATTC_WriteCharValue
494 *
495 * Description This function is called to write characteristic value.
496 *
497 * Parameters conn_id - connection ID.
498 * handle - characteristic handle to write.
499 * write_type - type of write.
500 * value - the value to be written.
501 *
502 * Returns None
503 *
504 ******************************************************************************/
BTA_GATTC_WriteCharValue(uint16_t conn_id,uint16_t handle,tGATT_WRITE_TYPE write_type,std::vector<uint8_t> value,tGATT_AUTH_REQ auth_req,GATT_WRITE_OP_CB callback,void * cb_data)505 void BTA_GATTC_WriteCharValue(uint16_t conn_id, uint16_t handle,
506 tGATT_WRITE_TYPE write_type,
507 std::vector<uint8_t> value,
508 tGATT_AUTH_REQ auth_req,
509 GATT_WRITE_OP_CB callback, void* cb_data) {
510 tBTA_GATTC_API_WRITE* p_buf = (tBTA_GATTC_API_WRITE*)osi_calloc(
511 sizeof(tBTA_GATTC_API_WRITE) + value.size());
512
513 p_buf->hdr.event = BTA_GATTC_API_WRITE_EVT;
514 p_buf->hdr.layer_specific = conn_id;
515 p_buf->auth_req = auth_req;
516 p_buf->handle = handle;
517 p_buf->write_type = write_type;
518 p_buf->len = value.size();
519 p_buf->write_cb = callback;
520 p_buf->write_cb_data = cb_data;
521
522 if (value.size() > 0) {
523 p_buf->p_value = (uint8_t*)(p_buf + 1);
524 memcpy(p_buf->p_value, value.data(), value.size());
525 }
526
527 bta_sys_sendmsg(p_buf);
528 }
529
530 /*******************************************************************************
531 *
532 * Function BTA_GATTC_WriteCharDescr
533 *
534 * Description This function is called to write descriptor value.
535 *
536 * Parameters conn_id - connection ID
537 * handle - descriptor hadle to write.
538 * value - the value to be written.
539 *
540 * Returns None
541 *
542 ******************************************************************************/
BTA_GATTC_WriteCharDescr(uint16_t conn_id,uint16_t handle,std::vector<uint8_t> value,tGATT_AUTH_REQ auth_req,GATT_WRITE_OP_CB callback,void * cb_data)543 void BTA_GATTC_WriteCharDescr(uint16_t conn_id, uint16_t handle,
544 std::vector<uint8_t> value,
545 tGATT_AUTH_REQ auth_req,
546 GATT_WRITE_OP_CB callback, void* cb_data) {
547 tBTA_GATTC_API_WRITE* p_buf = (tBTA_GATTC_API_WRITE*)osi_calloc(
548 sizeof(tBTA_GATTC_API_WRITE) + value.size());
549
550 p_buf->hdr.event = BTA_GATTC_API_WRITE_EVT;
551 p_buf->hdr.layer_specific = conn_id;
552 p_buf->auth_req = auth_req;
553 p_buf->handle = handle;
554 p_buf->write_type = GATT_WRITE;
555 p_buf->write_cb = callback;
556 p_buf->write_cb_data = cb_data;
557
558 if (value.size() != 0) {
559 p_buf->p_value = (uint8_t*)(p_buf + 1);
560 p_buf->len = value.size();
561 memcpy(p_buf->p_value, value.data(), value.size());
562 }
563
564 bta_sys_sendmsg(p_buf);
565 }
566
567 /*******************************************************************************
568 *
569 * Function BTA_GATTC_PrepareWrite
570 *
571 * Description This function is called to prepare write a characteristic
572 * value.
573 *
574 * Parameters conn_id - connection ID.
575 * p_char_id - GATT characteritic ID of the service.
576 * offset - offset of the write value.
577 * value - the value to be written.
578 *
579 * Returns None
580 *
581 ******************************************************************************/
BTA_GATTC_PrepareWrite(uint16_t conn_id,uint16_t handle,uint16_t offset,std::vector<uint8_t> value,tGATT_AUTH_REQ auth_req,GATT_WRITE_OP_CB callback,void * cb_data)582 void BTA_GATTC_PrepareWrite(uint16_t conn_id, uint16_t handle, uint16_t offset,
583 std::vector<uint8_t> value, tGATT_AUTH_REQ auth_req,
584 GATT_WRITE_OP_CB callback, void* cb_data) {
585 tBTA_GATTC_API_WRITE* p_buf = (tBTA_GATTC_API_WRITE*)osi_calloc(
586 sizeof(tBTA_GATTC_API_WRITE) + value.size());
587
588 p_buf->hdr.event = BTA_GATTC_API_WRITE_EVT;
589 p_buf->hdr.layer_specific = conn_id;
590 p_buf->auth_req = auth_req;
591 p_buf->handle = handle;
592 p_buf->write_cb = callback;
593 p_buf->write_cb_data = cb_data;
594
595 p_buf->write_type = BTA_GATTC_WRITE_PREPARE;
596 p_buf->offset = offset;
597 p_buf->len = value.size();
598
599 if (value.size() > 0) {
600 p_buf->p_value = (uint8_t*)(p_buf + 1);
601 memcpy(p_buf->p_value, value.data(), value.size());
602 }
603
604 bta_sys_sendmsg(p_buf);
605 }
606
607 /*******************************************************************************
608 *
609 * Function BTA_GATTC_ExecuteWrite
610 *
611 * Description This function is called to execute write a prepare write
612 * sequence.
613 *
614 * Parameters conn_id - connection ID.
615 * is_execute - execute or cancel.
616 *
617 * Returns None
618 *
619 ******************************************************************************/
BTA_GATTC_ExecuteWrite(uint16_t conn_id,bool is_execute)620 void BTA_GATTC_ExecuteWrite(uint16_t conn_id, bool is_execute) {
621 tBTA_GATTC_API_EXEC* p_buf =
622 (tBTA_GATTC_API_EXEC*)osi_calloc(sizeof(tBTA_GATTC_API_EXEC));
623
624 p_buf->hdr.event = BTA_GATTC_API_EXEC_EVT;
625 p_buf->hdr.layer_specific = conn_id;
626 p_buf->is_execute = is_execute;
627
628 bta_sys_sendmsg(p_buf);
629 }
630
631 /*******************************************************************************
632 *
633 * Function BTA_GATTC_SendIndConfirm
634 *
635 * Description This function is called to send handle value confirmation.
636 *
637 * Parameters conn_id - connection ID.
638 * cid
639 *
640 * Returns None
641 *
642 ******************************************************************************/
BTA_GATTC_SendIndConfirm(uint16_t conn_id,uint16_t cid)643 void BTA_GATTC_SendIndConfirm(uint16_t conn_id, uint16_t cid) {
644 tBTA_GATTC_API_CONFIRM* p_buf =
645 (tBTA_GATTC_API_CONFIRM*)osi_calloc(sizeof(tBTA_GATTC_API_CONFIRM));
646
647 log::verbose("conn_id={} cid=0x{:x}", conn_id, cid);
648
649 p_buf->hdr.event = BTA_GATTC_API_CONFIRM_EVT;
650 p_buf->hdr.layer_specific = conn_id;
651 p_buf->cid = cid;
652
653 bta_sys_sendmsg(p_buf);
654 }
655
656 /*******************************************************************************
657 *
658 * Function BTA_GATTC_RegisterForNotifications
659 *
660 * Description This function is called to register for notification of a
661 * service.
662 *
663 * Parameters client_if - client interface.
664 * bda - target GATT server.
665 * handle - GATT characteristic handle.
666 *
667 * Returns OK if registration succeed, otherwise failed.
668 *
669 ******************************************************************************/
BTA_GATTC_RegisterForNotifications(tGATT_IF client_if,const RawAddress & bda,uint16_t handle)670 tGATT_STATUS BTA_GATTC_RegisterForNotifications(tGATT_IF client_if,
671 const RawAddress& bda,
672 uint16_t handle) {
673 tBTA_GATTC_RCB* p_clreg;
674 tGATT_STATUS status = GATT_ILLEGAL_PARAMETER;
675 uint8_t i;
676
677 if (!handle) {
678 log::error("registration failed, handle is 0");
679 return status;
680 }
681
682 p_clreg = bta_gattc_cl_get_regcb(client_if);
683 if (p_clreg != NULL) {
684 for (i = 0; i < BTA_GATTC_NOTIF_REG_MAX; i++) {
685 if (p_clreg->notif_reg[i].in_use &&
686 p_clreg->notif_reg[i].remote_bda == bda &&
687 p_clreg->notif_reg[i].handle == handle) {
688 log::warn("notification already registered");
689 status = GATT_SUCCESS;
690 break;
691 }
692 }
693 if (status != GATT_SUCCESS) {
694 for (i = 0; i < BTA_GATTC_NOTIF_REG_MAX; i++) {
695 if (!p_clreg->notif_reg[i].in_use) {
696 memset((void*)&p_clreg->notif_reg[i], 0,
697 sizeof(tBTA_GATTC_NOTIF_REG));
698
699 p_clreg->notif_reg[i].in_use = true;
700 p_clreg->notif_reg[i].remote_bda = bda;
701
702 p_clreg->notif_reg[i].handle = handle;
703 status = GATT_SUCCESS;
704 break;
705 }
706 }
707 if (i == BTA_GATTC_NOTIF_REG_MAX) {
708 status = GATT_NO_RESOURCES;
709 log::error("Max Notification Reached, registration failed.");
710 }
711 }
712 } else {
713 log::error("client_if={} Not Registered", client_if);
714 }
715
716 return status;
717 }
718
719 /*******************************************************************************
720 *
721 * Function BTA_GATTC_DeregisterForNotifications
722 *
723 * Description This function is called to de-register for notification of a
724 * service.
725 *
726 * Parameters client_if - client interface.
727 * remote_bda - target GATT server.
728 * handle - GATT characteristic handle.
729 *
730 * Returns OK if deregistration succeed, otherwise failed.
731 *
732 ******************************************************************************/
BTA_GATTC_DeregisterForNotifications(tGATT_IF client_if,const RawAddress & bda,uint16_t handle)733 tGATT_STATUS BTA_GATTC_DeregisterForNotifications(tGATT_IF client_if,
734 const RawAddress& bda,
735 uint16_t handle) {
736 if (!handle) {
737 log::error("deregistration failed, handle is 0");
738 return GATT_ILLEGAL_PARAMETER;
739 }
740
741 tBTA_GATTC_RCB* p_clreg = bta_gattc_cl_get_regcb(client_if);
742 if (p_clreg == NULL) {
743 log::error("client_if={} not registered bd_addr={}", client_if, bda);
744 return GATT_ILLEGAL_PARAMETER;
745 }
746
747 for (int i = 0; i < BTA_GATTC_NOTIF_REG_MAX; i++) {
748 if (p_clreg->notif_reg[i].in_use &&
749 p_clreg->notif_reg[i].remote_bda == bda &&
750 p_clreg->notif_reg[i].handle == handle) {
751 log::verbose("deregistered bd_addr={}", bda);
752 memset(&p_clreg->notif_reg[i], 0, sizeof(tBTA_GATTC_NOTIF_REG));
753 return GATT_SUCCESS;
754 }
755 }
756
757 log::error("registration not found bd_addr={}", bda);
758 return GATT_ERROR;
759 }
760
761 /*******************************************************************************
762 *
763 * Function BTA_GATTC_Refresh
764 *
765 * Description Refresh the server cache of the remote device
766 *
767 * Parameters remote_bda: remote device BD address.
768 *
769 * Returns void
770 *
771 ******************************************************************************/
BTA_GATTC_Refresh(const RawAddress & remote_bda)772 void BTA_GATTC_Refresh(const RawAddress& remote_bda) {
773 do_in_main_thread(FROM_HERE,
774 base::Bind(&bta_gattc_process_api_refresh, remote_bda));
775 }
776