1 /******************************************************************************
2 *
3 * Copyright 1999-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 file contains the main GATT client functions
22 *
23 ******************************************************************************/
24
25 #define LOG_TAG "bluetooth"
26
27 #include <bluetooth/log.h>
28 #include <string.h>
29
30 #include "gatt_int.h"
31 #include "hardware/bt_gatt_types.h"
32 #include "internal_include/bt_target.h"
33 #include "osi/include/allocator.h"
34 #include "stack/arbiter/acl_arbiter.h"
35 #include "stack/eatt/eatt.h"
36 #include "stack/include/bt_types.h"
37 #include "stack/include/btm_client_interface.h"
38 #include "stack/include/l2cdefs.h"
39 #include "types/bluetooth/uuid.h"
40
41 #define GATT_WRITE_LONG_HDR_SIZE 5 /* 1 opcode + 2 handle + 2 offset */
42 #define GATT_READ_CHAR_VALUE_HDL (GATT_READ_CHAR_VALUE | 0x80)
43 #define GATT_READ_INC_SRV_UUID128 (GATT_DISC_INC_SRVC | 0x90)
44
45 #define GATT_PREP_WRITE_RSP_MIN_LEN 4
46 #define GATT_NOTIFICATION_MIN_LEN 2
47 #define GATT_WRITE_RSP_MIN_LEN 2
48 #define GATT_INFO_RSP_MIN_LEN 1
49 #define GATT_MTU_RSP_MIN_LEN 2
50 #define GATT_READ_BY_TYPE_RSP_MIN_LEN 1
51
52 #define L2CAP_PKT_OVERHEAD 4
53
54 using namespace bluetooth;
55 using bluetooth::Uuid;
56 using bluetooth::eatt::EattChannel;
57 using bluetooth::eatt::EattExtension;
58
59 /*******************************************************************************
60 * G L O B A L G A T T D A T A *
61 ******************************************************************************/
62 void gatt_send_prepare_write(tGATT_TCB& tcb, tGATT_CLCB* p_clcb);
63
64 uint8_t disc_type_to_att_opcode[GATT_DISC_MAX] = {
65 0,
66 GATT_REQ_READ_BY_GRP_TYPE, /* GATT_DISC_SRVC_ALL = 1, */
67 GATT_REQ_FIND_TYPE_VALUE, /* GATT_DISC_SRVC_BY_UUID, */
68 GATT_REQ_READ_BY_TYPE, /* GATT_DISC_INC_SRVC, */
69 GATT_REQ_READ_BY_TYPE, /* GATT_DISC_CHAR, */
70 GATT_REQ_FIND_INFO /* GATT_DISC_CHAR_DSCPT, */
71 };
72
73 uint16_t disc_type_to_uuid[GATT_DISC_MAX] = {
74 0, /* reserved */
75 GATT_UUID_PRI_SERVICE, /* <service> DISC_SRVC_ALL */
76 GATT_UUID_PRI_SERVICE, /* <service> for DISC_SERVC_BY_UUID */
77 GATT_UUID_INCLUDE_SERVICE, /* <include_service> for DISC_INC_SRVC */
78 GATT_UUID_CHAR_DECLARE, /* <characteristic> for DISC_CHAR */
79 0 /* no type filtering for DISC_CHAR_DSCPT */
80 };
81
82 /*******************************************************************************
83 *
84 * Function gatt_act_discovery
85 *
86 * Description GATT discovery operation.
87 *
88 * Returns void.
89 *
90 ******************************************************************************/
gatt_act_discovery(tGATT_CLCB * p_clcb)91 void gatt_act_discovery(tGATT_CLCB* p_clcb) {
92 uint8_t op_code = disc_type_to_att_opcode[p_clcb->op_subtype];
93
94 if (p_clcb->s_handle > p_clcb->e_handle || p_clcb->s_handle == 0) {
95 log::debug("Completed GATT discovery of all handle ranges");
96 gatt_end_operation(p_clcb, GATT_SUCCESS, NULL);
97 return;
98 }
99
100 tGATT_CL_MSG cl_req;
101 memset(&cl_req, 0, sizeof(tGATT_CL_MSG));
102
103 cl_req.browse.s_handle = p_clcb->s_handle;
104 cl_req.browse.e_handle = p_clcb->e_handle;
105
106 if (disc_type_to_uuid[p_clcb->op_subtype] != 0) {
107 cl_req.browse.uuid = bluetooth::Uuid::From16Bit(disc_type_to_uuid[p_clcb->op_subtype]);
108 }
109
110 if (p_clcb->op_subtype == GATT_DISC_SRVC_BY_UUID) /* fill in the FindByTypeValue request info*/
111 {
112 cl_req.find_type_value.uuid = bluetooth::Uuid::From16Bit(disc_type_to_uuid[p_clcb->op_subtype]);
113 cl_req.find_type_value.s_handle = p_clcb->s_handle;
114 cl_req.find_type_value.e_handle = p_clcb->e_handle;
115
116 size_t size = p_clcb->uuid.GetShortestRepresentationSize();
117 cl_req.find_type_value.value_len = size;
118 if (size == Uuid::kNumBytes16) {
119 uint8_t* p = cl_req.find_type_value.value;
120 UINT16_TO_STREAM(p, p_clcb->uuid.As16Bit());
121 } else if (size == Uuid::kNumBytes32) {
122 /* if service type is 32 bits UUID, convert it now */
123 memcpy(cl_req.find_type_value.value, p_clcb->uuid.To128BitLE().data(), Uuid::kNumBytes128);
124 cl_req.find_type_value.value_len = Uuid::kNumBytes128;
125 } else {
126 memcpy(cl_req.find_type_value.value, p_clcb->uuid.To128BitLE().data(), size);
127 }
128 }
129
130 tGATT_STATUS st = attp_send_cl_msg(*p_clcb->p_tcb, p_clcb, op_code, &cl_req);
131 if (st != GATT_SUCCESS && st != GATT_CMD_STARTED) {
132 log::warn("Unable to send ATT message");
133 gatt_end_operation(p_clcb, GATT_ERROR, NULL);
134 }
135 }
136
137 /*******************************************************************************
138 *
139 * Function gatt_act_read
140 *
141 * Description GATT read operation.
142 *
143 * Returns void.
144 *
145 ******************************************************************************/
gatt_act_read(tGATT_CLCB * p_clcb,uint16_t offset)146 void gatt_act_read(tGATT_CLCB* p_clcb, uint16_t offset) {
147 tGATT_TCB& tcb = *p_clcb->p_tcb;
148 tGATT_STATUS rt = GATT_INTERNAL_ERROR;
149 tGATT_CL_MSG msg;
150 uint8_t op_code = 0;
151
152 memset(&msg, 0, sizeof(tGATT_CL_MSG));
153
154 switch (p_clcb->op_subtype) {
155 case GATT_READ_CHAR_VALUE:
156 case GATT_READ_BY_TYPE:
157 op_code = GATT_REQ_READ_BY_TYPE;
158 msg.browse.s_handle = p_clcb->s_handle;
159 msg.browse.e_handle = p_clcb->e_handle;
160 if (p_clcb->op_subtype == GATT_READ_BY_TYPE) {
161 msg.browse.uuid = p_clcb->uuid;
162 } else {
163 msg.browse.uuid = bluetooth::Uuid::From16Bit(GATT_UUID_CHAR_DECLARE);
164 }
165 break;
166
167 case GATT_READ_CHAR_VALUE_HDL:
168 case GATT_READ_BY_HANDLE:
169 if (!p_clcb->counter) {
170 op_code = GATT_REQ_READ;
171 msg.handle = p_clcb->s_handle;
172 } else {
173 if (!p_clcb->first_read_blob_after_read) {
174 p_clcb->first_read_blob_after_read = true;
175 } else {
176 p_clcb->first_read_blob_after_read = false;
177 }
178
179 log::verbose("first_read_blob_after_read={}", p_clcb->first_read_blob_after_read);
180 op_code = GATT_REQ_READ_BLOB;
181 msg.read_blob.offset = offset;
182 msg.read_blob.handle = p_clcb->s_handle;
183 }
184 p_clcb->op_subtype &= ~0x80;
185 break;
186
187 case GATT_READ_PARTIAL:
188 op_code = GATT_REQ_READ_BLOB;
189 msg.read_blob.handle = p_clcb->s_handle;
190 msg.read_blob.offset = offset;
191 break;
192
193 case GATT_READ_MULTIPLE:
194 op_code = GATT_REQ_READ_MULTI;
195 memcpy(&msg.read_multi, p_clcb->p_attr_buf, sizeof(tGATT_READ_MULTI));
196 break;
197
198 case GATT_READ_MULTIPLE_VAR_LEN:
199 op_code = GATT_REQ_READ_MULTI_VAR;
200 memcpy(&msg.read_multi, p_clcb->p_attr_buf, sizeof(tGATT_READ_MULTI));
201 break;
202
203 case GATT_READ_INC_SRV_UUID128:
204 op_code = GATT_REQ_READ;
205 msg.handle = p_clcb->s_handle;
206 p_clcb->op_subtype &= ~0x90;
207 break;
208
209 default:
210 log::error("Unknown read type:{}", p_clcb->op_subtype);
211 break;
212 }
213
214 if (op_code != 0) {
215 rt = attp_send_cl_msg(tcb, p_clcb, op_code, &msg);
216 }
217
218 if (op_code == 0 || (rt != GATT_SUCCESS && rt != GATT_CMD_STARTED)) {
219 gatt_end_operation(p_clcb, rt, NULL);
220 }
221 }
222
223 /** GATT write operation */
gatt_act_write(tGATT_CLCB * p_clcb,uint8_t sec_act)224 void gatt_act_write(tGATT_CLCB* p_clcb, uint8_t sec_act) {
225 tGATT_TCB& tcb = *p_clcb->p_tcb;
226
227 log::assert_that(p_clcb->p_attr_buf != nullptr, "assert failed: p_clcb->p_attr_buf != nullptr");
228 tGATT_VALUE& attr = *((tGATT_VALUE*)p_clcb->p_attr_buf);
229
230 uint16_t payload_size = gatt_tcb_get_payload_size(tcb, p_clcb->cid);
231
232 switch (p_clcb->op_subtype) {
233 case GATT_WRITE_NO_RSP: {
234 p_clcb->s_handle = attr.handle;
235 uint8_t op_code = (sec_act == GATT_SEC_SIGN_DATA) ? GATT_SIGN_CMD_WRITE : GATT_CMD_WRITE;
236 tGATT_STATUS rt =
237 gatt_send_write_msg(tcb, p_clcb, op_code, attr.handle, attr.len, 0, attr.value);
238 if (rt != GATT_CMD_STARTED) {
239 if (rt != GATT_SUCCESS) {
240 log::error("gatt_act_write() failed op_code=0x{:x} rt={}", op_code, rt);
241 }
242 gatt_end_operation(p_clcb, rt, NULL);
243 }
244 return;
245 }
246
247 case GATT_WRITE: {
248 if ((attr.len + GATT_HDR_SIZE) <= payload_size) {
249 p_clcb->s_handle = attr.handle;
250
251 tGATT_STATUS rt = gatt_send_write_msg(tcb, p_clcb, GATT_REQ_WRITE, attr.handle, attr.len, 0,
252 attr.value);
253 if (rt != GATT_SUCCESS && rt != GATT_CMD_STARTED && rt != GATT_CONGESTED) {
254 if (rt != GATT_SUCCESS) {
255 log::error("gatt_act_write() failed op_code=0x{:x} rt={}", GATT_REQ_WRITE, rt);
256 }
257 gatt_end_operation(p_clcb, rt, NULL);
258 }
259
260 } else {
261 /* prepare write for long attribute */
262 gatt_send_prepare_write(tcb, p_clcb);
263 }
264 return;
265 }
266
267 case GATT_WRITE_PREPARE:
268 gatt_send_prepare_write(tcb, p_clcb);
269 return;
270
271 default:
272 log::fatal("Unknown write type {}", p_clcb->op_subtype);
273 return;
274 }
275 }
276
277 /*******************************************************************************
278 *
279 * Function gatt_send_queue_write_cancel
280 *
281 * Description send queue write cancel
282 *
283 * Returns void.
284 *
285 ******************************************************************************/
gatt_send_queue_write_cancel(tGATT_TCB & tcb,tGATT_CLCB * p_clcb,tGATT_EXEC_FLAG flag)286 void gatt_send_queue_write_cancel(tGATT_TCB& tcb, tGATT_CLCB* p_clcb, tGATT_EXEC_FLAG flag) {
287 tGATT_STATUS rt;
288
289 log::verbose("");
290
291 tGATT_CL_MSG gatt_cl_msg;
292 gatt_cl_msg.exec_write = flag;
293 rt = attp_send_cl_msg(tcb, p_clcb, GATT_REQ_EXEC_WRITE, &gatt_cl_msg);
294
295 if (rt != GATT_SUCCESS) {
296 gatt_end_operation(p_clcb, rt, NULL);
297 }
298 }
299
300 /*******************************************************************************
301 *
302 * Function gatt_check_write_long_terminate
303 *
304 * Description To terminate write long or not.
305 *
306 * Returns true: write long is terminated; false keep sending.
307 *
308 ******************************************************************************/
gatt_check_write_long_terminate(tGATT_TCB & tcb,tGATT_CLCB * p_clcb,tGATT_VALUE * p_rsp_value)309 static bool gatt_check_write_long_terminate(tGATT_TCB& tcb, tGATT_CLCB* p_clcb,
310 tGATT_VALUE* p_rsp_value) {
311 tGATT_VALUE* p_attr = (tGATT_VALUE*)p_clcb->p_attr_buf;
312 bool terminate = false;
313 tGATT_EXEC_FLAG flag = GATT_PREP_WRITE_EXEC;
314
315 log::verbose("");
316 /* check the first write response status */
317 if (p_rsp_value != NULL) {
318 if (p_rsp_value->handle != p_attr->handle || p_rsp_value->len != p_clcb->counter ||
319 memcmp(p_rsp_value->value, p_attr->value + p_attr->offset, p_rsp_value->len)) {
320 /* data does not match */
321 p_clcb->status = GATT_ERROR;
322 flag = GATT_PREP_WRITE_CANCEL;
323 terminate = true;
324 } else /* response checking is good */
325 {
326 p_clcb->status = GATT_SUCCESS;
327 /* update write offset and check if end of attribute value */
328 if ((p_attr->offset += p_rsp_value->len) >= p_attr->len) {
329 terminate = true;
330 }
331 }
332 }
333 if (terminate && p_clcb->op_subtype != GATT_WRITE_PREPARE) {
334 gatt_send_queue_write_cancel(tcb, p_clcb, flag);
335 }
336 return terminate;
337 }
338
339 /** Send prepare write */
gatt_send_prepare_write(tGATT_TCB & tcb,tGATT_CLCB * p_clcb)340 void gatt_send_prepare_write(tGATT_TCB& tcb, tGATT_CLCB* p_clcb) {
341 tGATT_VALUE* p_attr = (tGATT_VALUE*)p_clcb->p_attr_buf;
342 uint8_t type = p_clcb->op_subtype;
343
344 log::verbose("type=0x{:x}", type);
345 uint16_t to_send = p_attr->len - p_attr->offset;
346
347 uint16_t payload_size = gatt_tcb_get_payload_size(tcb, p_clcb->cid);
348
349 if (payload_size <= GATT_WRITE_LONG_HDR_SIZE) {
350 log::error("too small mtu size {}, possibly due to disconnection", payload_size);
351 gatt_end_operation(p_clcb, GATT_ERROR, NULL);
352 return;
353 }
354
355 if (to_send > (payload_size - GATT_WRITE_LONG_HDR_SIZE)) {
356 to_send = payload_size - GATT_WRITE_LONG_HDR_SIZE;
357 }
358
359 p_clcb->s_handle = p_attr->handle;
360
361 uint16_t offset = p_attr->offset;
362 if (type == GATT_WRITE_PREPARE) {
363 offset += p_clcb->start_offset;
364 }
365
366 log::verbose("offset =0x{:x} len={}", offset, to_send);
367
368 tGATT_STATUS rt = gatt_send_write_msg(tcb, p_clcb, GATT_REQ_PREPARE_WRITE, p_attr->handle,
369 to_send, /* length */
370 offset, /* used as offset */
371 p_attr->value + p_attr->offset); /* data */
372
373 /* remember the write long attribute length */
374 p_clcb->counter = to_send;
375
376 if (rt != GATT_SUCCESS && rt != GATT_CMD_STARTED && rt != GATT_CONGESTED) {
377 gatt_end_operation(p_clcb, rt, NULL);
378 }
379 }
380
381 /*******************************************************************************
382 *
383 * Function gatt_process_find_type_value_rsp
384 *
385 * Description This function handles the find by type value response.
386 *
387 *
388 * Returns void
389 *
390 ******************************************************************************/
gatt_process_find_type_value_rsp(tGATT_TCB &,tGATT_CLCB * p_clcb,uint16_t len,uint8_t * p_data)391 static void gatt_process_find_type_value_rsp(tGATT_TCB& /* tcb */, tGATT_CLCB* p_clcb, uint16_t len,
392 uint8_t* p_data) {
393 tGATT_DISC_RES result;
394 uint8_t* p = p_data;
395
396 log::verbose("");
397 /* unexpected response */
398 if (p_clcb->operation != GATTC_OPTYPE_DISCOVERY || p_clcb->op_subtype != GATT_DISC_SRVC_BY_UUID) {
399 return;
400 }
401
402 memset(&result, 0, sizeof(tGATT_DISC_RES));
403 result.type = bluetooth::Uuid::From16Bit(GATT_UUID_PRI_SERVICE);
404
405 /* returns a series of handle ranges */
406 while (len >= 4) {
407 STREAM_TO_UINT16(result.handle, p);
408 STREAM_TO_UINT16(result.value.group_value.e_handle, p);
409 result.value.group_value.service_type = p_clcb->uuid;
410
411 len -= 4;
412
413 if (p_clcb->p_reg->app_cb.p_disc_res_cb) {
414 (*p_clcb->p_reg->app_cb.p_disc_res_cb)(
415 p_clcb->conn_id, static_cast<tGATT_DISC_TYPE>(p_clcb->op_subtype), &result);
416 }
417 }
418
419 /* last handle + 1 */
420 p_clcb->s_handle =
421 (result.value.group_value.e_handle == 0) ? 0 : (result.value.group_value.e_handle + 1);
422 /* initiate another request */
423 gatt_act_discovery(p_clcb);
424 }
425 /*******************************************************************************
426 *
427 * Function gatt_process_read_info_rsp
428 *
429 * Description This function is called to handle the read information
430 * response.
431 *
432 *
433 * Returns void
434 *
435 ******************************************************************************/
gatt_process_read_info_rsp(tGATT_TCB &,tGATT_CLCB * p_clcb,uint8_t,uint16_t len,uint8_t * p_data)436 static void gatt_process_read_info_rsp(tGATT_TCB& /* tcb */, tGATT_CLCB* p_clcb,
437 uint8_t /* op_code */, uint16_t len, uint8_t* p_data) {
438 tGATT_DISC_RES result;
439 uint8_t *p = p_data, uuid_len = 0, type;
440
441 if (len < GATT_INFO_RSP_MIN_LEN) {
442 log::error("invalid Info Response PDU received, discard.");
443 gatt_end_operation(p_clcb, GATT_INVALID_PDU, NULL);
444 return;
445 }
446 /* unexpected response */
447 if (p_clcb->operation != GATTC_OPTYPE_DISCOVERY || p_clcb->op_subtype != GATT_DISC_CHAR_DSCPT) {
448 return;
449 }
450
451 STREAM_TO_UINT8(type, p);
452 len -= 1;
453
454 if (type == GATT_INFO_TYPE_PAIR_16) {
455 uuid_len = Uuid::kNumBytes16;
456 } else if (type == GATT_INFO_TYPE_PAIR_128) {
457 uuid_len = Uuid::kNumBytes128;
458 }
459
460 while (len >= uuid_len + 2) {
461 STREAM_TO_UINT16(result.handle, p);
462
463 if (uuid_len > 0) {
464 if (!gatt_parse_uuid_from_cmd(&result.type, uuid_len, &p)) {
465 break;
466 }
467 } else {
468 result.type = p_clcb->uuid;
469 }
470
471 len -= (uuid_len + 2);
472
473 if (p_clcb->p_reg->app_cb.p_disc_res_cb) {
474 (*p_clcb->p_reg->app_cb.p_disc_res_cb)(
475 p_clcb->conn_id, static_cast<tGATT_DISC_TYPE>(p_clcb->op_subtype), &result);
476 }
477 }
478
479 p_clcb->s_handle = (result.handle == 0) ? 0 : (result.handle + 1);
480 /* initiate another request */
481 gatt_act_discovery(p_clcb);
482 }
483
484 /*******************************************************************************
485 *
486 * Function gatt_proc_disc_error_rsp
487 *
488 * Description Process the read by type response and send another request
489 * if needed.
490 *
491 * Returns void.
492 *
493 ******************************************************************************/
gatt_proc_disc_error_rsp(tGATT_TCB &,tGATT_CLCB * p_clcb,uint8_t opcode,uint16_t,uint8_t reason)494 static void gatt_proc_disc_error_rsp(tGATT_TCB& /* tcb */, tGATT_CLCB* p_clcb, uint8_t opcode,
495 uint16_t /* handle */, uint8_t reason) {
496 tGATT_STATUS status = (tGATT_STATUS)reason;
497
498 log::verbose("reason: {:02x} cmd_code {:04x}", reason, opcode);
499
500 switch (opcode) {
501 case GATT_REQ_READ_BY_GRP_TYPE:
502 case GATT_REQ_FIND_TYPE_VALUE:
503 case GATT_REQ_READ_BY_TYPE:
504 case GATT_REQ_FIND_INFO:
505 if (reason == GATT_NOT_FOUND) {
506 status = GATT_SUCCESS;
507 log::verbose("Discovery completed");
508 }
509 break;
510 default:
511 log::error("Incorrect discovery opcode {:04x}", opcode);
512 break;
513 }
514
515 gatt_end_operation(p_clcb, status, NULL);
516 }
517
518 /*******************************************************************************
519 *
520 * Function gatt_process_error_rsp
521 *
522 * Description This function is called to handle the error response
523 *
524 *
525 * Returns void
526 *
527 ******************************************************************************/
gatt_process_error_rsp(tGATT_TCB & tcb,tGATT_CLCB * p_clcb,uint8_t,uint16_t len,uint8_t * p_data)528 static void gatt_process_error_rsp(tGATT_TCB& tcb, tGATT_CLCB* p_clcb, uint8_t /* op_code */,
529 uint16_t len, uint8_t* p_data) {
530 uint8_t opcode, *p = p_data;
531 uint8_t reason;
532 uint16_t handle;
533 tGATT_VALUE* p_attr = (tGATT_VALUE*)p_clcb->p_attr_buf;
534
535 log::verbose("");
536
537 if (len < 4) {
538 log::error("Error response too short");
539 // Specification does not clearly define what should happen if error
540 // response is too short. General rule in BT Spec 5.0 Vol 3, Part F 3.4.1.1
541 // is: "If an error code is received in the Error Response that is not
542 // understood by the client, for example an error code that was reserved for
543 // future use that is now being used in a future version of this
544 // specification, then the Error Response shall still be considered to state
545 // that the given request cannot be performed for an unknown reason."
546 opcode = handle = 0;
547 reason = static_cast<tGATT_STATUS>(0x7f);
548 } else {
549 STREAM_TO_UINT8(opcode, p);
550 STREAM_TO_UINT16(handle, p);
551 STREAM_TO_UINT8(reason, p);
552 }
553
554 if (p_clcb->operation == GATTC_OPTYPE_DISCOVERY) {
555 gatt_proc_disc_error_rsp(tcb, p_clcb, opcode, handle, static_cast<tGATT_STATUS>(reason));
556 } else {
557 if ((p_clcb->operation == GATTC_OPTYPE_WRITE) && (p_clcb->op_subtype == GATT_WRITE) &&
558 (opcode == GATT_REQ_PREPARE_WRITE) && (p_attr) && (handle == p_attr->handle)) {
559 p_clcb->status = static_cast<tGATT_STATUS>(reason);
560 gatt_send_queue_write_cancel(tcb, p_clcb, GATT_PREP_WRITE_CANCEL);
561 } else if ((p_clcb->operation == GATTC_OPTYPE_READ) &&
562 ((p_clcb->op_subtype == GATT_READ_CHAR_VALUE_HDL) ||
563 (p_clcb->op_subtype == GATT_READ_BY_HANDLE)) &&
564 (opcode == GATT_REQ_READ_BLOB) && p_clcb->first_read_blob_after_read &&
565 (reason == GATT_NOT_LONG)) {
566 gatt_end_operation(p_clcb, GATT_SUCCESS, (void*)p_clcb->p_attr_buf);
567 } else {
568 gatt_end_operation(p_clcb, static_cast<tGATT_STATUS>(reason), NULL);
569 }
570 }
571 }
572
573 /*******************************************************************************
574 *
575 * Function gatt_process_prep_write_rsp
576 *
577 * Description This function is called to handle the read response
578 *
579 *
580 * Returns void
581 *
582 ******************************************************************************/
gatt_process_prep_write_rsp(tGATT_TCB & tcb,tGATT_CLCB * p_clcb,uint8_t op_code,uint16_t len,uint8_t * p_data)583 static void gatt_process_prep_write_rsp(tGATT_TCB& tcb, tGATT_CLCB* p_clcb, uint8_t op_code,
584 uint16_t len, uint8_t* p_data) {
585 uint8_t* p = p_data;
586
587 tGATT_VALUE value = {
588 .conn_id = p_clcb->conn_id,
589 .auth_req = GATT_AUTH_REQ_NONE,
590 };
591
592 log::verbose("value resp op_code = {} len = {}", gatt_dbg_op_name(op_code), len);
593
594 if (len < GATT_PREP_WRITE_RSP_MIN_LEN ||
595 len > GATT_PREP_WRITE_RSP_MIN_LEN + sizeof(value.value)) {
596 log::error("illegal prepare write response length, discard");
597 gatt_end_operation(p_clcb, GATT_INVALID_PDU, &value);
598 return;
599 }
600
601 STREAM_TO_UINT16(value.handle, p);
602 STREAM_TO_UINT16(value.offset, p);
603
604 value.len = len - GATT_PREP_WRITE_RSP_MIN_LEN;
605
606 memcpy(value.value, p, value.len);
607
608 bool subtype_is_write_prepare = (p_clcb->op_subtype == GATT_WRITE_PREPARE);
609
610 if (!gatt_check_write_long_terminate(tcb, p_clcb, &value)) {
611 gatt_send_prepare_write(tcb, p_clcb);
612 return;
613 }
614
615 // We now know that we have not terminated, or else we would have returned
616 // early. We free the buffer only if the subtype is not equal to
617 // GATT_WRITE_PREPARE, so checking here is adequate to prevent UAF.
618 if (subtype_is_write_prepare) {
619 /* application should verify handle offset
620 and value are matched or not */
621 gatt_end_operation(p_clcb, p_clcb->status, &value);
622 }
623 }
624
625 /*******************************************************************************
626 *
627 * Function gatt_process_notification
628 *
629 * Description Handle the handle value indication/notification.
630 *
631 * Returns void
632 *
633 ******************************************************************************/
gatt_process_notification(tGATT_TCB & tcb,uint16_t cid,uint8_t op_code,uint16_t len,uint8_t * p_data)634 static void gatt_process_notification(tGATT_TCB& tcb, uint16_t cid, uint8_t op_code, uint16_t len,
635 uint8_t* p_data) {
636 tGATT_VALUE value = {};
637 tGATT_REG* p_reg;
638 tCONN_ID conn_id;
639 tGATT_STATUS encrypt_status = {};
640 uint8_t* p = p_data;
641 uint8_t i;
642 tGATTC_OPTYPE event =
643 (op_code == GATT_HANDLE_VALUE_IND) ? GATTC_OPTYPE_INDICATION : GATTC_OPTYPE_NOTIFICATION;
644
645 log::verbose("");
646
647 // Ensure our packet has enough data (2 bytes)
648 if (len < GATT_NOTIFICATION_MIN_LEN) {
649 log::error("illegal notification PDU length, discard");
650 return;
651 }
652
653 // Get 2 byte handle
654 STREAM_TO_UINT16(value.handle, p);
655
656 // Fail early if the GATT handle is not valid
657 if (!GATT_HANDLE_IS_VALID(value.handle)) {
658 /* illegal handle, send ack now */
659 if (op_code == GATT_HANDLE_VALUE_IND) {
660 attp_send_cl_confirmation_msg(tcb, cid);
661 }
662 return;
663 }
664
665 // Calculate value length based on opcode
666 if (op_code == GATT_HANDLE_MULTI_VALUE_NOTIF) {
667 // Ensure our packet has enough data; MIN + 2 more bytes for len value
668 if (len < GATT_NOTIFICATION_MIN_LEN + 2) {
669 log::error("illegal notification PDU length, discard");
670 return;
671 }
672
673 // Allow multi value opcode to set value len from the packet
674 STREAM_TO_UINT16(value.len, p);
675
676 if (value.len > len - 4) {
677 log::error("value.len ({}) greater than length ({})", value.len, len - 4);
678 return;
679 }
680
681 } else {
682 // For single value, just use the passed in len minus opcode length (2)
683 value.len = len - 2;
684 }
685
686 // Verify the new calculated length
687 if (value.len > GATT_MAX_ATTR_LEN) {
688 log::error("value.len larger than GATT_MAX_ATTR_LEN, discard");
689 return;
690 }
691
692 // Handle indications differently
693 if (event == GATTC_OPTYPE_INDICATION) {
694 if (tcb.ind_count) {
695 /* this is an error case that receiving an indication but we
696 still has an indication not being acked yet.
697 For now, just log the error reset the counter.
698 Later we need to disconnect the link unconditionally.
699 */
700 log::error("rcv Ind. but ind_count={} (will reset ind_count)", tcb.ind_count);
701 }
702
703 // Zero out the ind_count
704 tcb.ind_count = 0;
705
706 // Notify all registered clients with the handle value
707 // notification/indication
708 // Note: need to do the indication count and start timer first then do
709 // callback
710 for (auto& [i, p_reg] : gatt_cb.cl_rcb_map) {
711 if (p_reg->in_use && p_reg->app_cb.p_cmpl_cb) {
712 tcb.ind_count++;
713 }
714 }
715
716 /* start a timer for app confirmation */
717 if (tcb.ind_count > 0) {
718 gatt_start_ind_ack_timer(tcb, cid);
719 } else { /* no app to indicate, or invalid handle */
720 attp_send_cl_confirmation_msg(tcb, cid);
721 }
722 }
723
724 encrypt_status = gatt_get_link_encrypt_status(tcb);
725
726 STREAM_TO_ARRAY(value.value, p, value.len);
727
728 tGATT_CL_COMPLETE gatt_cl_complete;
729 gatt_cl_complete.att_value = value;
730 gatt_cl_complete.cid = cid;
731
732 for (auto& [i, p_reg] : gatt_cb.cl_rcb_map) {
733 if (p_reg->in_use && p_reg->app_cb.p_cmpl_cb) {
734 conn_id = gatt_create_conn_id(tcb.tcb_idx, p_reg->gatt_if);
735 (*p_reg->app_cb.p_cmpl_cb)(conn_id, event, encrypt_status, &gatt_cl_complete);
736 }
737 }
738
739 // If this is single value, then nothing is left to do
740 if (op_code != GATT_HANDLE_MULTI_VALUE_NOTIF) {
741 return;
742 }
743
744 // Need a signed type to check if the value is below 0
745 // as uint16_t doesn't have negatives so the negatives register as a number
746 // thus anything less than zero won't trigger the conditional and it is not
747 // always 0
748 // when done looping as value.len is arbitrary.
749 int16_t rem_len = (int16_t)len - (4 /* octets */ + value.len);
750
751 // Already streamed the first value and sent it, lets send the rest
752 while (rem_len > 4 /* octets */) {
753 // 2
754 STREAM_TO_UINT16(value.handle, p);
755 // + 2 = 4
756 STREAM_TO_UINT16(value.len, p);
757 // Accounting
758 rem_len -= 4;
759 // Make sure we don't read past the remaining data even if the length says
760 // we can Also need to watch comparing the int16_t with the uint16_t
761 value.len = std::min((uint16_t)rem_len, value.len);
762 if (value.len > sizeof(value.value)) {
763 log::error("Unexpected value.len (>GATT_MAX_ATTR_LEN), stop");
764 return;
765 }
766 STREAM_TO_ARRAY(value.value, p, value.len);
767 // Accounting
768 rem_len -= value.len;
769
770 gatt_cl_complete.att_value = value;
771 gatt_cl_complete.cid = cid;
772
773 for (auto& [i, p_reg] : gatt_cb.cl_rcb_map) {
774 if (p_reg->in_use && p_reg->app_cb.p_cmpl_cb) {
775 conn_id = gatt_create_conn_id(tcb.tcb_idx, p_reg->gatt_if);
776 (*p_reg->app_cb.p_cmpl_cb)(conn_id, event, encrypt_status, &gatt_cl_complete);
777 }
778 }
779 }
780 }
781
782 /*******************************************************************************
783 *
784 * Function gatt_process_read_by_type_rsp
785 *
786 * Description This function is called to handle the read by type response.
787 * read by type can be used for discovery, or read by type or
788 * read characteristic value.
789 *
790 * Returns void
791 *
792 ******************************************************************************/
gatt_process_read_by_type_rsp(tGATT_TCB & tcb,tGATT_CLCB * p_clcb,uint8_t op_code,uint16_t len,uint8_t * p_data)793 static void gatt_process_read_by_type_rsp(tGATT_TCB& tcb, tGATT_CLCB* p_clcb, uint8_t op_code,
794 uint16_t len, uint8_t* p_data) {
795 tGATT_DISC_RES result;
796 tGATT_DISC_VALUE record_value;
797 uint8_t *p = p_data, value_len, handle_len = 2;
798 uint16_t handle = 0;
799
800 /* discovery procedure and no callback function registered */
801 if (((!p_clcb->p_reg) || (!p_clcb->p_reg->app_cb.p_disc_res_cb)) &&
802 (p_clcb->operation == GATTC_OPTYPE_DISCOVERY)) {
803 return;
804 }
805
806 if (len < GATT_READ_BY_TYPE_RSP_MIN_LEN) {
807 log::error("Illegal ReadByType/ReadByGroupType Response length, discard");
808 gatt_end_operation(p_clcb, GATT_INVALID_PDU, NULL);
809 return;
810 }
811
812 STREAM_TO_UINT8(value_len, p);
813 uint16_t payload_size = gatt_tcb_get_payload_size(tcb, p_clcb->cid);
814 if ((value_len > (payload_size - 2)) || (value_len > (len - 1))) {
815 /* this is an error case that server's response containing a value length
816 which is larger than MTU-2
817 or value_len > message total length -1 */
818 log::error("Discard response op_code={} vale_len={} > (MTU-2={} or msg_len-1={})", op_code,
819 value_len, payload_size - 2, len - 1);
820 gatt_end_operation(p_clcb, GATT_ERROR, NULL);
821 return;
822 }
823
824 if (op_code == GATT_RSP_READ_BY_GRP_TYPE) {
825 handle_len = 4;
826 }
827
828 value_len -= handle_len; /* subtract the handle pairs bytes */
829 len -= 1;
830
831 while (len >= (handle_len + value_len)) {
832 STREAM_TO_UINT16(handle, p);
833
834 if (!GATT_HANDLE_IS_VALID(handle)) {
835 gatt_end_operation(p_clcb, GATT_INVALID_HANDLE, NULL);
836 return;
837 }
838
839 memset(&result, 0, sizeof(tGATT_DISC_RES));
840 memset(&record_value, 0, sizeof(tGATT_DISC_VALUE));
841
842 result.handle = handle;
843 result.type = bluetooth::Uuid::From16Bit(disc_type_to_uuid[p_clcb->op_subtype]);
844
845 /* discover all services */
846 if (p_clcb->operation == GATTC_OPTYPE_DISCOVERY && p_clcb->op_subtype == GATT_DISC_SRVC_ALL &&
847 op_code == GATT_RSP_READ_BY_GRP_TYPE) {
848 STREAM_TO_UINT16(handle, p);
849
850 if (!GATT_HANDLE_IS_VALID(handle)) {
851 gatt_end_operation(p_clcb, GATT_INVALID_HANDLE, NULL);
852 return;
853 } else {
854 record_value.group_value.e_handle = handle;
855 if (!gatt_parse_uuid_from_cmd(&record_value.group_value.service_type, value_len, &p)) {
856 log::error("discover all service response parsing failure");
857 break;
858 }
859 }
860 } else if (p_clcb->operation == GATTC_OPTYPE_DISCOVERY &&
861 p_clcb->op_subtype == GATT_DISC_INC_SRVC) {
862 /* discover included service */
863 if (value_len < 4) {
864 log::error("Illegal Response length, must be at least 4.");
865 gatt_end_operation(p_clcb, GATT_INVALID_PDU, NULL);
866 return;
867 }
868 STREAM_TO_UINT16(record_value.incl_service.s_handle, p);
869 STREAM_TO_UINT16(record_value.incl_service.e_handle, p);
870
871 if (!GATT_HANDLE_IS_VALID(record_value.incl_service.s_handle) ||
872 !GATT_HANDLE_IS_VALID(record_value.incl_service.e_handle)) {
873 gatt_end_operation(p_clcb, GATT_INVALID_HANDLE, NULL);
874 return;
875 }
876
877 if (value_len == 6) {
878 uint16_t tmp;
879 STREAM_TO_UINT16(tmp, p);
880 record_value.incl_service.service_type = bluetooth::Uuid::From16Bit(tmp);
881 } else if (value_len == 4) {
882 p_clcb->s_handle = record_value.incl_service.s_handle;
883 p_clcb->read_uuid128.wait_for_read_rsp = true;
884 p_clcb->read_uuid128.next_disc_start_hdl = handle + 1;
885 memcpy(&p_clcb->read_uuid128.result, &result, sizeof(result));
886 memcpy(&p_clcb->read_uuid128.result.value, &record_value, sizeof(result.value));
887 p_clcb->op_subtype |= 0x90;
888 gatt_act_read(p_clcb, 0);
889 return;
890 } else {
891 log::error("INCL_SRVC failed with invalid data value_len={}", value_len);
892 gatt_end_operation(p_clcb, GATT_INVALID_PDU, (void*)p);
893 return;
894 }
895 } else if (p_clcb->operation == GATTC_OPTYPE_READ && p_clcb->op_subtype == GATT_READ_BY_TYPE) {
896 /* read by type */
897 p_clcb->counter = len - 2;
898 p_clcb->s_handle = handle;
899
900 if (p_clcb->counter == (payload_size - 4)) {
901 /* IOP: Some devices can't handle Read Blob request. Apps for such devices send their MTU
902 * preference with the connect request. Expectation is that the stack would exchange MTU
903 * immediately on connection and thereby avoid using Read Blob request.
904 * However, the stack does not support exchanging MTU immediately on connection at present.
905 * As a workaround, GATT client instead just avoids sending Read Blob request when certain
906 * conditions are met. */
907 tGATT_TCB* p_tcb = p_clcb->p_tcb;
908 if (p_tcb->transport == BT_TRANSPORT_LE && p_tcb->att_lcid == L2CAP_ATT_CID &&
909 p_tcb->app_mtu_pref > GATT_DEF_BLE_MTU_SIZE &&
910 p_tcb->payload_size <= GATT_DEF_BLE_MTU_SIZE && p_clcb->uuid.Is16Bit() &&
911 p_clcb->uuid.As16Bit() == GATT_UUID_GAP_DEVICE_NAME) {
912 log::warn("Skipping Read Blob request for reading device name {}", p_tcb->peer_bda);
913 gatt_end_operation(p_clcb, GATT_SUCCESS, (void*)p);
914 return;
915 }
916
917 /* Continue reading rest of value */
918 p_clcb->op_subtype = GATT_READ_BY_HANDLE;
919 if (!p_clcb->p_attr_buf) {
920 p_clcb->p_attr_buf = (uint8_t*)osi_malloc(GATT_MAX_ATTR_LEN);
921 }
922 if (p_clcb->counter <= GATT_MAX_ATTR_LEN) {
923 memcpy(p_clcb->p_attr_buf, p, p_clcb->counter);
924 gatt_act_read(p_clcb, p_clcb->counter);
925 } else {
926 gatt_end_operation(p_clcb, GATT_INTERNAL_ERROR, (void*)p);
927 }
928 } else {
929 gatt_end_operation(p_clcb, GATT_SUCCESS, (void*)p);
930 }
931 return;
932 } else /* discover characteristic */
933 {
934 if (value_len < 3) {
935 log::error("Illegal Response length, must be at least 3.");
936 gatt_end_operation(p_clcb, GATT_INVALID_PDU, NULL);
937 return;
938 }
939 STREAM_TO_UINT8(record_value.dclr_value.char_prop, p);
940 STREAM_TO_UINT16(record_value.dclr_value.val_handle, p);
941 if (!GATT_HANDLE_IS_VALID(record_value.dclr_value.val_handle)) {
942 gatt_end_operation(p_clcb, GATT_INVALID_HANDLE, NULL);
943 return;
944 }
945 if (!gatt_parse_uuid_from_cmd(&record_value.dclr_value.char_uuid, (uint16_t)(value_len - 3),
946 &p)) {
947 gatt_end_operation(p_clcb, GATT_SUCCESS, NULL);
948 /* invalid format, and skip the result */
949 return;
950 }
951
952 /* UUID not matching */
953 if (!p_clcb->uuid.IsEmpty() && !record_value.dclr_value.char_uuid.IsEmpty() &&
954 record_value.dclr_value.char_uuid != p_clcb->uuid) {
955 len -= (value_len + 2);
956 continue; /* skip the result, and look for next one */
957 }
958
959 if (p_clcb->operation == GATTC_OPTYPE_READ)
960 /* UUID match for read characteristic value */
961 {
962 /* only read the first matching UUID characteristic value, and
963 discard the rest results */
964 p_clcb->s_handle = record_value.dclr_value.val_handle;
965 p_clcb->op_subtype |= 0x80;
966 gatt_act_read(p_clcb, 0);
967 return;
968 }
969 }
970 len -= (value_len + handle_len);
971
972 /* result is (handle, 16bits UUID) pairs */
973 memcpy(&result.value, &record_value, sizeof(result.value));
974
975 /* send callback if is discover procedure */
976 if (p_clcb->operation == GATTC_OPTYPE_DISCOVERY && p_clcb->p_reg->app_cb.p_disc_res_cb) {
977 (*p_clcb->p_reg->app_cb.p_disc_res_cb)(
978 p_clcb->conn_id, static_cast<tGATT_DISC_TYPE>(p_clcb->op_subtype), &result);
979 }
980 }
981
982 p_clcb->s_handle = (handle == 0) ? 0 : (handle + 1);
983
984 if (p_clcb->operation == GATTC_OPTYPE_DISCOVERY) {
985 /* initiate another request */
986 gatt_act_discovery(p_clcb);
987 } else /* read characteristic value */
988 {
989 gatt_act_read(p_clcb, 0);
990 }
991 }
992
993 /*******************************************************************************
994 *
995 * Function gatt_process_read_rsp
996 *
997 * Description This function is called to handle the read BLOB response
998 *
999 *
1000 * Returns void
1001 *
1002 ******************************************************************************/
gatt_process_read_rsp(tGATT_TCB & tcb,tGATT_CLCB * p_clcb,uint8_t,uint16_t len,uint8_t * p_data)1003 static void gatt_process_read_rsp(tGATT_TCB& tcb, tGATT_CLCB* p_clcb, uint8_t /* op_code */,
1004 uint16_t len, uint8_t* p_data) {
1005 uint16_t offset = p_clcb->counter;
1006 uint8_t* p = p_data;
1007
1008 uint16_t payload_size = gatt_tcb_get_payload_size(tcb, p_clcb->cid);
1009
1010 if (p_clcb->operation == GATTC_OPTYPE_READ) {
1011 if (p_clcb->op_subtype != GATT_READ_BY_HANDLE) {
1012 p_clcb->counter = len;
1013 gatt_end_operation(p_clcb, GATT_SUCCESS, (void*)p);
1014 } else {
1015 /* allocate GKI buffer holding up long attribute value */
1016 if (!p_clcb->p_attr_buf) {
1017 p_clcb->p_attr_buf = (uint8_t*)osi_malloc(GATT_MAX_ATTR_LEN);
1018 }
1019
1020 /* copy attribute value into cb buffer */
1021 if (offset < GATT_MAX_ATTR_LEN) {
1022 if ((len + offset) > GATT_MAX_ATTR_LEN) {
1023 len = GATT_MAX_ATTR_LEN - offset;
1024 }
1025
1026 p_clcb->counter += len;
1027
1028 memcpy(p_clcb->p_attr_buf + offset, p, len);
1029
1030 /* full packet for read or read blob rsp */
1031 bool packet_is_full;
1032 if (payload_size == p_clcb->read_req_current_mtu) {
1033 packet_is_full = (len == (payload_size - 1));
1034 } else {
1035 packet_is_full = (len == (p_clcb->read_req_current_mtu - 1) || len == (payload_size - 1));
1036 p_clcb->read_req_current_mtu = payload_size;
1037 }
1038
1039 /* send next request if needed */
1040 if (packet_is_full && (len + offset < GATT_MAX_ATTR_LEN)) {
1041 log::verbose(
1042 "full pkt issue read blob for remaining bytes old offset={} len={} new offset={}",
1043 offset, len, p_clcb->counter);
1044 gatt_act_read(p_clcb, p_clcb->counter);
1045 } else /* end of request, send callback */
1046 {
1047 gatt_end_operation(p_clcb, GATT_SUCCESS, (void*)p_clcb->p_attr_buf);
1048 }
1049 } else /* exception, should not happen */
1050 {
1051 log::error("attr offset = {} p_attr_buf = {}", offset, std::format_ptr(p_clcb->p_attr_buf));
1052 gatt_end_operation(p_clcb, GATT_NO_RESOURCES, (void*)p_clcb->p_attr_buf);
1053 }
1054 }
1055 } else {
1056 if (p_clcb->operation == GATTC_OPTYPE_DISCOVERY && p_clcb->op_subtype == GATT_DISC_INC_SRVC &&
1057 p_clcb->read_uuid128.wait_for_read_rsp) {
1058 p_clcb->s_handle = p_clcb->read_uuid128.next_disc_start_hdl;
1059 p_clcb->read_uuid128.wait_for_read_rsp = false;
1060 if (len == Uuid::kNumBytes128) {
1061 p_clcb->read_uuid128.result.value.incl_service.service_type =
1062 bluetooth::Uuid::From128BitLE(p);
1063 if (p_clcb->p_reg->app_cb.p_disc_res_cb) {
1064 (*p_clcb->p_reg->app_cb.p_disc_res_cb)(p_clcb->conn_id,
1065 static_cast<tGATT_DISC_TYPE>(p_clcb->op_subtype),
1066 &p_clcb->read_uuid128.result);
1067 }
1068 gatt_act_discovery(p_clcb);
1069 } else {
1070 gatt_end_operation(p_clcb, GATT_INVALID_PDU, (void*)p);
1071 }
1072 }
1073 }
1074 }
1075
1076 /*******************************************************************************
1077 *
1078 * Function gatt_process_handle_rsp
1079 *
1080 * Description This function is called to handle the write response
1081 *
1082 *
1083 * Returns void
1084 *
1085 ******************************************************************************/
gatt_process_handle_rsp(tGATT_CLCB * p_clcb)1086 static void gatt_process_handle_rsp(tGATT_CLCB* p_clcb) {
1087 gatt_end_operation(p_clcb, GATT_SUCCESS, NULL);
1088 }
1089
1090 /*******************************************************************************
1091 *
1092 * Function gatt_process_mtu_rsp
1093 *
1094 * Description Process the configure MTU response.
1095 *
1096 *
1097 * Returns void
1098 *
1099 ******************************************************************************/
gatt_process_mtu_rsp(tGATT_TCB & tcb,tGATT_CLCB * p_clcb,uint16_t len,uint8_t * p_data)1100 static void gatt_process_mtu_rsp(tGATT_TCB& tcb, tGATT_CLCB* p_clcb, uint16_t len,
1101 uint8_t* p_data) {
1102 uint16_t mtu;
1103 tGATT_STATUS status = GATT_SUCCESS;
1104
1105 if (len < GATT_MTU_RSP_MIN_LEN) {
1106 log::error("invalid MTU response PDU received, discard.");
1107 status = GATT_INVALID_PDU;
1108 } else {
1109 STREAM_TO_UINT16(mtu, p_data);
1110
1111 log::info("Local pending MTU {}, Remote ({}) MTU {}", tcb.pending_user_mtu_exchange_value,
1112 tcb.peer_bda, mtu);
1113
1114 /* Aim for default as we did in the request */
1115 if (mtu < GATT_DEF_BLE_MTU_SIZE) {
1116 tcb.payload_size = GATT_DEF_BLE_MTU_SIZE;
1117 } else {
1118 tcb.payload_size = std::min(mtu, (uint16_t)(gatt_get_local_mtu()));
1119 }
1120
1121 bluetooth::shim::arbiter::GetArbiter().OnIncomingMtuResp(tcb.tcb_idx, tcb.payload_size);
1122
1123 /* This is just to track the biggest MTU requested by the user.
1124 * This value will be used in the BTM_SetBleDataLength */
1125 if (tcb.pending_user_mtu_exchange_value > tcb.max_user_mtu) {
1126 tcb.max_user_mtu = std::min(tcb.pending_user_mtu_exchange_value, tcb.payload_size);
1127 } else if (tcb.pending_user_mtu_exchange_value == 0) {
1128 tcb.max_user_mtu = tcb.payload_size;
1129 }
1130 tcb.pending_user_mtu_exchange_value = 0;
1131
1132 log::info("MTU Exchange resulted in: {}", tcb.payload_size);
1133
1134 if (get_btm_client_interface().ble.BTM_SetBleDataLength(
1135 tcb.peer_bda, tcb.max_user_mtu + L2CAP_PKT_OVERHEAD) != tBTM_STATUS::BTM_SUCCESS) {
1136 log::warn("Unable to set BLE data length peer:{} mtu:{}", tcb.peer_bda,
1137 tcb.max_user_mtu + L2CAP_PKT_OVERHEAD);
1138 }
1139 }
1140
1141 gatt_end_operation(p_clcb, status, NULL);
1142 }
1143 /*******************************************************************************
1144 *
1145 * Function gatt_cmd_to_rsp_code
1146 *
1147 * Description Convert an ATT command op code into the corresponding
1148 * response code assume no error occurs.
1149 *
1150 * Returns response code.
1151 *
1152 ******************************************************************************/
gatt_cmd_to_rsp_code(uint8_t cmd_code)1153 static uint8_t gatt_cmd_to_rsp_code(uint8_t cmd_code) {
1154 uint8_t rsp_code = 0;
1155
1156 if (cmd_code > 1 && cmd_code != GATT_CMD_WRITE) {
1157 rsp_code = cmd_code + 1;
1158 }
1159 return rsp_code;
1160 }
1161
1162 /** Find next command in queue and sent to server */
gatt_cl_send_next_cmd_inq(tGATT_TCB & tcb)1163 bool gatt_cl_send_next_cmd_inq(tGATT_TCB& tcb) {
1164 std::deque<tGATT_CMD_Q>* cl_cmd_q = nullptr;
1165
1166 while (gatt_is_outstanding_msg_in_att_send_queue(tcb) ||
1167 EattExtension::GetInstance()->IsOutstandingMsgInSendQueue(tcb.peer_bda)) {
1168 if (gatt_is_outstanding_msg_in_att_send_queue(tcb)) {
1169 cl_cmd_q = &tcb.cl_cmd_q;
1170 } else {
1171 EattChannel* channel =
1172 EattExtension::GetInstance()->GetChannelWithQueuedDataToSend(tcb.peer_bda);
1173 cl_cmd_q = &channel->cl_cmd_q_;
1174 }
1175
1176 tGATT_CMD_Q& cmd = cl_cmd_q->front();
1177 if (!cmd.to_send || cmd.p_cmd == NULL) {
1178 return false;
1179 }
1180
1181 tGATT_STATUS att_ret;
1182 att_ret = attp_send_msg_to_l2cap(tcb, cmd.cid, cmd.p_cmd);
1183
1184 if (att_ret != GATT_SUCCESS && att_ret != GATT_CONGESTED) {
1185 log::error("L2CAP sent error");
1186 cl_cmd_q->pop_front();
1187 continue;
1188 }
1189
1190 cmd.to_send = false;
1191 cmd.p_cmd = NULL;
1192
1193 if (cmd.op_code == GATT_CMD_WRITE || cmd.op_code == GATT_SIGN_CMD_WRITE) {
1194 /* dequeue the request if is write command or sign write */
1195 uint8_t rsp_code;
1196 tGATT_CLCB* p_clcb = gatt_cmd_dequeue(tcb, cmd.cid, &rsp_code);
1197
1198 /* send command complete callback here */
1199 gatt_end_operation(p_clcb, att_ret, NULL);
1200
1201 /* if no ack needed, keep sending */
1202 if (att_ret == GATT_SUCCESS) {
1203 continue;
1204 }
1205
1206 return true;
1207 }
1208
1209 gatt_start_rsp_timer(cmd.p_clcb);
1210 return true;
1211 }
1212
1213 return false;
1214 }
1215
1216 /** This function is called to handle the server response to client */
gatt_client_handle_server_rsp(tGATT_TCB & tcb,uint16_t cid,uint8_t op_code,uint16_t len,uint8_t * p_data)1217 void gatt_client_handle_server_rsp(tGATT_TCB& tcb, uint16_t cid, uint8_t op_code, uint16_t len,
1218 uint8_t* p_data) {
1219 log::verbose("opcode: 0x{:x} cid{}", op_code, cid);
1220
1221 uint16_t payload_size = gatt_tcb_get_payload_size(tcb, cid);
1222
1223 if (op_code == GATT_HANDLE_VALUE_IND || op_code == GATT_HANDLE_VALUE_NOTIF ||
1224 op_code == GATT_HANDLE_MULTI_VALUE_NOTIF) {
1225 if (len >= payload_size) {
1226 log::error("invalid indicate pkt size: {}, PDU size: {}", len + 1, payload_size);
1227 return;
1228 }
1229
1230 gatt_process_notification(tcb, cid, op_code, len, p_data);
1231 return;
1232 }
1233
1234 uint8_t cmd_code = 0;
1235 tGATT_CLCB* p_clcb = gatt_cmd_dequeue(tcb, cid, &cmd_code);
1236 if (!p_clcb) {
1237 log::warn("ATT - clcb already not in use, ignoring response");
1238 gatt_cl_send_next_cmd_inq(tcb);
1239 return;
1240 }
1241
1242 uint8_t rsp_code = gatt_cmd_to_rsp_code(cmd_code);
1243 if (!p_clcb) {
1244 log::warn("ATT - clcb already not in use, ignoring response");
1245 gatt_cl_send_next_cmd_inq(tcb);
1246 return;
1247 }
1248
1249 if (rsp_code != op_code && op_code != GATT_RSP_ERROR) {
1250 log::warn("ATT - Ignore wrong response. Receives ({:02x}) Request({:02x}) Ignored", op_code,
1251 rsp_code);
1252 return;
1253 }
1254
1255 gatt_stop_rsp_timer(p_clcb);
1256 p_clcb->retry_count = 0;
1257
1258 /* the size of the message may not be bigger than the local max PDU size*/
1259 /* The message has to be smaller than the agreed MTU, len does not count
1260 * op_code */
1261 if (len >= payload_size) {
1262 log::error("invalid response pkt size: {}, PDU size: {}", len + 1, payload_size);
1263 gatt_end_operation(p_clcb, GATT_ERROR, NULL);
1264 } else {
1265 switch (op_code) {
1266 case GATT_RSP_ERROR:
1267 gatt_process_error_rsp(tcb, p_clcb, op_code, len, p_data);
1268 break;
1269
1270 case GATT_RSP_MTU: /* 2 bytes mtu */
1271 gatt_process_mtu_rsp(tcb, p_clcb, len, p_data);
1272 break;
1273
1274 case GATT_RSP_FIND_INFO:
1275 gatt_process_read_info_rsp(tcb, p_clcb, op_code, len, p_data);
1276 break;
1277
1278 case GATT_RSP_READ_BY_TYPE:
1279 case GATT_RSP_READ_BY_GRP_TYPE:
1280 gatt_process_read_by_type_rsp(tcb, p_clcb, op_code, len, p_data);
1281 break;
1282
1283 case GATT_RSP_READ:
1284 case GATT_RSP_READ_BLOB:
1285 case GATT_RSP_READ_MULTI:
1286 case GATT_RSP_READ_MULTI_VAR:
1287 gatt_process_read_rsp(tcb, p_clcb, op_code, len, p_data);
1288 break;
1289
1290 case GATT_RSP_FIND_TYPE_VALUE: /* disc service with UUID */
1291 gatt_process_find_type_value_rsp(tcb, p_clcb, len, p_data);
1292 break;
1293
1294 case GATT_RSP_WRITE:
1295 gatt_process_handle_rsp(p_clcb);
1296 break;
1297
1298 case GATT_RSP_PREPARE_WRITE:
1299 gatt_process_prep_write_rsp(tcb, p_clcb, op_code, len, p_data);
1300 break;
1301
1302 case GATT_RSP_EXEC_WRITE:
1303 gatt_end_operation(p_clcb, p_clcb->status, NULL);
1304 break;
1305
1306 default:
1307 log::error("Unknown opcode = {:x}", op_code);
1308 break;
1309 }
1310 }
1311
1312 gatt_cl_send_next_cmd_inq(tcb);
1313 }
1314