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