1 /******************************************************************************
2 *
3 * Copyright 2008-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 GATT server functions
22 *
23 ******************************************************************************/
24
25 #include <bluetooth/log.h>
26 #include <com_android_bluetooth_flags.h>
27 #include <string.h>
28
29 #include <algorithm>
30 #include <memory>
31
32 #include "hardware/bt_gatt_types.h"
33 #include "internal_include/bt_target.h"
34 #include "osi/include/allocator.h"
35 #include "stack/arbiter/acl_arbiter.h"
36 #include "stack/eatt/eatt.h"
37 #include "stack/gatt/gatt_int.h"
38 #include "stack/include/bt_hdr.h"
39 #include "stack/include/bt_types.h"
40 #include "stack/include/btm_client_interface.h"
41 #include "stack/include/l2cap_types.h"
42 #include "types/bluetooth/uuid.h"
43
44 #define GATT_MTU_REQ_MIN_LEN 2
45 #define L2CAP_PKT_OVERHEAD 4
46
47 using bluetooth::Uuid;
48 using bluetooth::eatt::EattChannel;
49 using bluetooth::eatt::EattExtension;
50 using namespace bluetooth;
51
52 /*******************************************************************************
53 *
54 * Function gatt_sr_enqueue_cmd
55 *
56 * Description This function enqueue the request from client which needs a
57 * application response, and update the transaction ID.
58 *
59 * Returns void
60 *
61 ******************************************************************************/
gatt_sr_enqueue_cmd(tGATT_TCB & tcb,uint16_t cid,uint8_t op_code,uint16_t handle)62 uint32_t gatt_sr_enqueue_cmd(tGATT_TCB& tcb, uint16_t cid, uint8_t op_code, uint16_t handle) {
63 tGATT_SR_CMD* p_cmd;
64
65 if (cid == tcb.att_lcid) {
66 p_cmd = &tcb.sr_cmd;
67 } else {
68 EattChannel* channel = EattExtension::GetInstance()->FindEattChannelByCid(tcb.peer_bda, cid);
69 if (channel == nullptr) {
70 log::warn("{}, cid 0x{:02x} already disconnected", tcb.peer_bda, cid);
71 return 0;
72 }
73
74 p_cmd = &channel->server_outstanding_cmd_;
75 }
76
77 uint32_t trans_id = 0;
78
79 p_cmd->cid = cid;
80
81 if ((p_cmd->op_code == 0) || (op_code == GATT_HANDLE_VALUE_CONF)) { /* no pending request */
82 if (op_code == GATT_CMD_WRITE || op_code == GATT_SIGN_CMD_WRITE || op_code == GATT_REQ_MTU ||
83 op_code == GATT_HANDLE_VALUE_CONF) {
84 trans_id = ++tcb.trans_id;
85 } else {
86 p_cmd->trans_id = ++tcb.trans_id;
87 p_cmd->op_code = op_code;
88 p_cmd->handle = handle;
89 p_cmd->status = GATT_NOT_FOUND;
90 tcb.trans_id %= GATT_TRANS_ID_MAX;
91 trans_id = p_cmd->trans_id;
92 }
93 }
94
95 return trans_id;
96 }
97
98 /*******************************************************************************
99 *
100 * Function gatt_sr_cmd_empty
101 *
102 * Description This function checks if the server command queue is empty.
103 *
104 * Returns true if empty, false if there is pending command.
105 *
106 ******************************************************************************/
gatt_sr_cmd_empty(tGATT_TCB & tcb,uint16_t cid)107 static bool gatt_sr_cmd_empty(tGATT_TCB& tcb, uint16_t cid) {
108 if (cid == tcb.att_lcid) {
109 return tcb.sr_cmd.op_code == 0;
110 }
111
112 EattChannel* channel = EattExtension::GetInstance()->FindEattChannelByCid(tcb.peer_bda, cid);
113 if (channel == nullptr) {
114 log::warn("{}, cid 0x{:02x} already disconnected", tcb.peer_bda, cid);
115 return false;
116 }
117
118 return channel->server_outstanding_cmd_.op_code == 0;
119 }
120
121 /*******************************************************************************
122 *
123 * Function gatt_dequeue_sr_cmd
124 *
125 * Description This function dequeue the request from command queue.
126 *
127 * Returns void
128 *
129 ******************************************************************************/
gatt_dequeue_sr_cmd(tGATT_TCB & tcb,uint16_t cid)130 void gatt_dequeue_sr_cmd(tGATT_TCB& tcb, uint16_t cid) {
131 tGATT_SR_CMD* p_cmd;
132
133 if (cid == tcb.att_lcid) {
134 p_cmd = &tcb.sr_cmd;
135 } else {
136 EattChannel* channel = EattExtension::GetInstance()->FindEattChannelByCid(tcb.peer_bda, cid);
137 if (channel == nullptr) {
138 log::warn("{}, cid 0x{:02x} already disconnected", tcb.peer_bda, cid);
139 return;
140 }
141
142 p_cmd = &channel->server_outstanding_cmd_;
143 }
144
145 /* Double check in case any buffers are queued */
146 log::verbose("gatt_dequeue_sr_cmd cid: 0x{:x}", cid);
147 if (p_cmd->p_rsp_msg) {
148 log::error("free tcb.sr_cmd.p_rsp_msg = {}", std::format_ptr(p_cmd->p_rsp_msg));
149 }
150 osi_free_and_reset((void**)&p_cmd->p_rsp_msg);
151
152 while (!fixed_queue_is_empty(p_cmd->multi_rsp_q)) {
153 osi_free(fixed_queue_try_dequeue(p_cmd->multi_rsp_q));
154 }
155 fixed_queue_free(p_cmd->multi_rsp_q, NULL);
156 *p_cmd = tGATT_SR_CMD{};
157 }
158
build_read_multi_rsp(tGATT_SR_CMD * p_cmd,uint16_t mtu)159 static void build_read_multi_rsp(tGATT_SR_CMD* p_cmd, uint16_t mtu) {
160 uint16_t ii;
161 size_t total_len, len;
162 uint8_t* p;
163 bool is_overflow = false;
164
165 // We need at least one extra byte for the opcode
166 if (mtu == 0) {
167 log::error("Invalid MTU");
168 p_cmd->status = GATT_ILLEGAL_PARAMETER;
169 return;
170 }
171
172 len = sizeof(BT_HDR) + L2CAP_MIN_OFFSET + mtu;
173 BT_HDR* p_buf = (BT_HDR*)osi_calloc(len);
174 p_buf->offset = L2CAP_MIN_OFFSET;
175 p = (uint8_t*)(p_buf + 1) + p_buf->offset;
176
177 /* First byte in the response is the opcode */
178 if (p_cmd->multi_req.variable_len) {
179 *p++ = GATT_RSP_READ_MULTI_VAR;
180 } else {
181 *p++ = GATT_RSP_READ_MULTI;
182 }
183
184 p_buf->len = 1;
185
186 // Now walk through the buffers putting the data into the response in order
187 list_t* list = NULL;
188 const list_node_t* node = NULL;
189 if (!fixed_queue_is_empty(p_cmd->multi_rsp_q)) {
190 list = fixed_queue_get_list(p_cmd->multi_rsp_q);
191 }
192 for (ii = 0; ii < p_cmd->multi_req.num_handles; ii++) {
193 tGATTS_RSP* p_rsp = NULL;
194
195 if (list != NULL) {
196 if (ii == 0) {
197 node = list_begin(list);
198 } else {
199 node = list_next(node);
200 }
201 if (node != list_end(list)) {
202 p_rsp = (tGATTS_RSP*)list_node(node);
203 }
204 }
205
206 if (p_rsp != NULL) {
207 total_len = p_buf->len;
208 if (p_cmd->multi_req.variable_len) {
209 total_len += 2;
210 }
211
212 if (total_len > mtu) {
213 log::verbose("Buffer space not enough for this data item, skipping");
214 break;
215 }
216
217 len = std::min((size_t)p_rsp->attr_value.len, mtu - total_len);
218
219 if (total_len == mtu && p_rsp->attr_value.len > 0) {
220 log::verbose("Buffer space not enough for this data item, skipping");
221 break;
222 }
223
224 if (len < p_rsp->attr_value.len) {
225 is_overflow = true;
226 log::verbose("multi read overflow available len={} val_len={}", len, p_rsp->attr_value.len);
227 }
228
229 if (p_cmd->multi_req.variable_len) {
230 UINT16_TO_STREAM(p, (uint16_t)len);
231 p_buf->len += 2;
232 }
233
234 if (p_rsp->attr_value.handle == p_cmd->multi_req.handles[ii]) {
235 ARRAY_TO_STREAM(p, p_rsp->attr_value.value, (uint16_t)len);
236 p_buf->len += (uint16_t)len;
237 } else {
238 p_cmd->status = GATT_NOT_FOUND;
239 break;
240 }
241
242 if (is_overflow) {
243 break;
244 }
245
246 } else {
247 p_cmd->status = GATT_NOT_FOUND;
248 break;
249 }
250 } /* loop through all handles*/
251
252 /* Sanity check on the buffer length */
253 if (p_buf->len == 0) {
254 log::error("nothing found!!");
255 p_cmd->status = GATT_NOT_FOUND;
256 osi_free(p_buf);
257 log::verbose("osi_free(p_buf)");
258 } else if (p_cmd->p_rsp_msg != NULL) {
259 osi_free(p_buf);
260 } else {
261 p_cmd->p_rsp_msg = p_buf;
262 }
263 }
264
265 /*******************************************************************************
266 *
267 * Function process_read_multi_rsp
268 *
269 * Description This function check the read multiple response.
270 *
271 * Returns bool if all replies have been received
272 *
273 ******************************************************************************/
process_read_multi_rsp(tGATT_SR_CMD * p_cmd,tGATT_STATUS status,tGATTS_RSP * p_msg,uint16_t mtu)274 static bool process_read_multi_rsp(tGATT_SR_CMD* p_cmd, tGATT_STATUS status, tGATTS_RSP* p_msg,
275 uint16_t mtu) {
276 log::verbose("status={} mtu={}", status, mtu);
277
278 if (p_cmd->multi_rsp_q == NULL) {
279 p_cmd->multi_rsp_q = fixed_queue_new(SIZE_MAX);
280 }
281
282 /* Enqueue the response */
283 BT_HDR* p_buf = (BT_HDR*)osi_malloc(sizeof(tGATTS_RSP));
284 memcpy((void*)p_buf, (const void*)p_msg, sizeof(tGATTS_RSP));
285 fixed_queue_enqueue(p_cmd->multi_rsp_q, p_buf);
286
287 p_cmd->status = status;
288 if (status == GATT_SUCCESS) {
289 log::verbose("Multi read count={} num_hdls={} variable={}",
290 fixed_queue_length(p_cmd->multi_rsp_q), p_cmd->multi_req.num_handles,
291 p_cmd->multi_req.variable_len);
292 /* Wait till we get all the responses */
293 if (fixed_queue_length(p_cmd->multi_rsp_q) == p_cmd->multi_req.num_handles) {
294 build_read_multi_rsp(p_cmd, mtu);
295 return true;
296 }
297 } else { /* any handle read exception occurs, return error */
298 return true;
299 }
300
301 /* If here, still waiting */
302 return false;
303 }
304
305 /*******************************************************************************
306 *
307 * Function gatt_sr_process_app_rsp
308 *
309 * Description This function checks whether the response message from
310 * application matches any pending request.
311 *
312 * Returns void
313 *
314 ******************************************************************************/
gatt_sr_process_app_rsp(tGATT_TCB & tcb,tGATT_IF gatt_if,uint32_t,uint8_t op_code,tGATT_STATUS status,tGATTS_RSP * p_msg,tGATT_SR_CMD * sr_res_p)315 tGATT_STATUS gatt_sr_process_app_rsp(tGATT_TCB& tcb, tGATT_IF gatt_if, uint32_t /* trans_id */,
316 uint8_t op_code, tGATT_STATUS status, tGATTS_RSP* p_msg,
317 tGATT_SR_CMD* sr_res_p) {
318 tGATT_STATUS ret_code = GATT_SUCCESS;
319 uint16_t payload_size = gatt_tcb_get_payload_size(tcb, sr_res_p->cid);
320
321 log::verbose("gatt_if={}", gatt_if);
322
323 gatt_sr_update_cback_cnt(tcb, sr_res_p->cid, gatt_if, false, false);
324
325 if ((op_code == GATT_REQ_READ_MULTI) || (op_code == GATT_REQ_READ_MULTI_VAR)) {
326 /* If no error and still waiting, just return */
327 if (!process_read_multi_rsp(sr_res_p, status, p_msg, payload_size)) {
328 return GATT_SUCCESS;
329 }
330 } else {
331 if (op_code == GATT_REQ_PREPARE_WRITE && status == GATT_SUCCESS) {
332 gatt_sr_update_prep_cnt(tcb, gatt_if, true, false);
333 }
334
335 if (op_code == GATT_REQ_EXEC_WRITE && status != GATT_SUCCESS) {
336 gatt_sr_reset_cback_cnt(tcb, sr_res_p->cid);
337 }
338
339 sr_res_p->status = status;
340
341 if (gatt_sr_is_cback_cnt_zero(tcb, sr_res_p->cid) && status == GATT_SUCCESS) {
342 if (sr_res_p->p_rsp_msg == NULL) {
343 sr_res_p->p_rsp_msg =
344 attp_build_sr_msg(tcb, (uint8_t)(op_code + 1), (tGATT_SR_MSG*)p_msg, payload_size);
345 } else {
346 log::error("Exception!!! already has respond message");
347 }
348 }
349 }
350 if (gatt_sr_is_cback_cnt_zero(tcb, sr_res_p->cid)) {
351 if ((sr_res_p->status == GATT_SUCCESS) && (sr_res_p->p_rsp_msg)) {
352 ret_code = attp_send_sr_msg(tcb, sr_res_p->cid, sr_res_p->p_rsp_msg);
353 sr_res_p->p_rsp_msg = NULL;
354 } else {
355 ret_code = gatt_send_error_rsp(tcb, sr_res_p->cid, status, op_code, sr_res_p->handle, false);
356 }
357
358 gatt_dequeue_sr_cmd(tcb, sr_res_p->cid);
359 }
360
361 log::verbose("ret_code={}", ret_code);
362
363 return ret_code;
364 }
365
366 /*******************************************************************************
367 *
368 * Function gatt_process_exec_write_req
369 *
370 * Description This function is called to process the execute write request
371 * from client.
372 *
373 * Returns void
374 *
375 ******************************************************************************/
gatt_process_exec_write_req(tGATT_TCB & tcb,uint16_t cid,uint8_t op_code,uint16_t len,uint8_t * p_data)376 static void gatt_process_exec_write_req(tGATT_TCB& tcb, uint16_t cid, uint8_t op_code, uint16_t len,
377 uint8_t* p_data) {
378 uint8_t *p = p_data, flag;
379 uint32_t trans_id = 0;
380 tGATT_IF gatt_if;
381 tCONN_ID conn_id;
382
383 #if (GATT_CONFORMANCE_TESTING == TRUE)
384 if (gatt_cb.enable_err_rsp && gatt_cb.req_op_code == op_code) {
385 log::verbose("Conformance tst: forced err rspv for Execute Write: error status={}",
386 gatt_cb.err_status);
387
388 gatt_send_error_rsp(tcb, cid, gatt_cb.err_status, gatt_cb.req_op_code, gatt_cb.handle, false);
389
390 return;
391 }
392 #endif
393
394 if (len < sizeof(flag)) {
395 log::error("invalid length");
396 gatt_send_error_rsp(tcb, cid, GATT_INVALID_PDU, GATT_REQ_EXEC_WRITE, 0, false);
397 return;
398 }
399
400 STREAM_TO_UINT8(flag, p);
401
402 /* mask the flag */
403 flag &= GATT_PREP_WRITE_EXEC;
404
405 /* no prep write is queued */
406 if (!gatt_sr_is_prep_cnt_zero(tcb)) {
407 trans_id = gatt_sr_enqueue_cmd(tcb, cid, op_code, 0);
408 gatt_sr_copy_prep_cnt_to_cback_cnt(tcb);
409
410 auto prep_cnt_it = tcb.prep_cnt_map.begin();
411 while (prep_cnt_it != tcb.prep_cnt_map.end()) {
412 gatt_if = prep_cnt_it->first;
413 conn_id = gatt_create_conn_id(tcb.tcb_idx, gatt_if);
414 tGATTS_DATA gatts_data;
415 gatts_data.exec_write = flag;
416 gatt_sr_send_req_callback(conn_id, trans_id, GATTS_REQ_TYPE_WRITE_EXEC, &gatts_data);
417 prep_cnt_it = tcb.prep_cnt_map.erase(prep_cnt_it);
418 }
419 } else { /* nothing needs to be executed , send response now */
420 log::warn("gatt_process_exec_write_req: no prepare write pending");
421 if (com::android::bluetooth::flags::fix_execute_write_no_pending()) {
422 uint16_t payload_size = gatt_tcb_get_payload_size(tcb, cid);
423 BT_HDR* p_buf =
424 attp_build_sr_msg(tcb, GATT_RSP_EXEC_WRITE, (tGATT_SR_MSG*)NULL, payload_size);
425 if (p_buf != NULL) {
426 attp_send_sr_msg(tcb, cid, p_buf);
427 } else {
428 gatt_send_error_rsp(tcb, cid, GATT_ERROR, GATT_REQ_EXEC_WRITE, 0, false);
429 }
430 } else {
431 gatt_send_error_rsp(tcb, cid, GATT_ERROR, GATT_REQ_EXEC_WRITE, 0, false);
432 }
433 }
434 }
435
436 /*******************************************************************************
437 *
438 * Function gatt_process_read_multi_req
439 *
440 * Description This function is called to process the read multiple request
441 * from client.
442 *
443 * Returns void
444 *
445 ******************************************************************************/
gatt_process_read_multi_req(tGATT_TCB & tcb,uint16_t cid,uint8_t op_code,uint16_t len,uint8_t * p_data)446 static void gatt_process_read_multi_req(tGATT_TCB& tcb, uint16_t cid, uint8_t op_code, uint16_t len,
447 uint8_t* p_data) {
448 uint32_t trans_id;
449 uint16_t handle = 0, ll = len;
450 uint8_t* p = p_data;
451 tGATT_STATUS err = GATT_SUCCESS;
452 tGATT_SEC_FLAG sec_flag;
453 uint8_t key_size;
454
455 log::verbose("");
456
457 tGATT_READ_MULTI* multi_req = gatt_sr_get_read_multi(tcb, cid);
458 if (multi_req == nullptr) {
459 log::error("Could not proceed request. {}, 0x{:02x}", tcb.peer_bda, cid);
460 return;
461 }
462 multi_req->num_handles = 0;
463 multi_req->variable_len = (op_code == GATT_REQ_READ_MULTI_VAR);
464 gatt_sr_get_sec_info(tcb.peer_bda, tcb.transport, &sec_flag, &key_size);
465
466 #if (GATT_CONFORMANCE_TESTING == TRUE)
467 if (gatt_cb.enable_err_rsp && gatt_cb.req_op_code == op_code) {
468 log::verbose("Conformance tst: forced err rspvofr ReadMultiple: error status={}",
469 gatt_cb.err_status);
470
471 STREAM_TO_UINT16(handle, p);
472
473 gatt_send_error_rsp(tcb, cid, gatt_cb.err_status, gatt_cb.req_op_code, handle, false);
474
475 return;
476 }
477 #endif
478
479 while (ll >= 2 && multi_req->num_handles < GATT_MAX_READ_MULTI_HANDLES) {
480 STREAM_TO_UINT16(handle, p);
481
482 auto it = gatt_sr_find_i_rcb_by_handle(handle);
483 if (it != gatt_cb.srv_list_info->end()) {
484 multi_req->handles[multi_req->num_handles++] = handle;
485
486 /* check read permission */
487 err = gatts_read_attr_perm_check(it->p_db, false, handle, sec_flag, key_size);
488 if (err != GATT_SUCCESS) {
489 log::verbose("read permission denied : 0x{:02x}", err);
490 break;
491 }
492 } else {
493 /* invalid handle */
494 err = GATT_INVALID_HANDLE;
495 break;
496 }
497 ll -= 2;
498 }
499
500 if (ll != 0) {
501 log::error("max attribute handle reached in ReadMultiple Request.");
502 }
503
504 if (multi_req->num_handles == 0) {
505 err = GATT_INVALID_HANDLE;
506 }
507
508 if (err == GATT_SUCCESS) {
509 trans_id = gatt_sr_enqueue_cmd(tcb, cid, op_code, multi_req->handles[0]);
510 if (trans_id != 0) {
511 tGATT_SR_CMD* sr_cmd_p = gatt_sr_get_cmd_by_cid(tcb, cid);
512 if (sr_cmd_p == nullptr) {
513 log::error("Could not send response on CID were request arrived. {}, 0x{:02x}",
514 tcb.peer_bda, cid);
515 return;
516 }
517 gatt_sr_reset_cback_cnt(tcb, cid); /* read multiple use multi_rsp_q's count*/
518
519 for (ll = 0; ll < multi_req->num_handles; ll++) {
520 tGATTS_RSP* p_msg = (tGATTS_RSP*)osi_calloc(sizeof(tGATTS_RSP));
521 handle = multi_req->handles[ll];
522 auto it = gatt_sr_find_i_rcb_by_handle(handle);
523
524 p_msg->attr_value.handle = handle;
525 err = gatts_read_attr_value_by_handle(tcb, cid, it->p_db, op_code, handle, 0,
526 p_msg->attr_value.value, &p_msg->attr_value.len,
527 GATT_MAX_ATTR_LEN, sec_flag, key_size, trans_id);
528
529 if (err == GATT_SUCCESS) {
530 gatt_sr_process_app_rsp(tcb, it->gatt_if, trans_id, op_code, GATT_SUCCESS, p_msg,
531 sr_cmd_p);
532 }
533 /* either not using or done using the buffer, release it now */
534 osi_free(p_msg);
535 }
536 } else {
537 err = GATT_NO_RESOURCES;
538 }
539 }
540
541 /* in theroy BUSY is not possible(should already been checked), protected
542 * check */
543 if (err != GATT_SUCCESS && err != GATT_PENDING && err != GATT_BUSY) {
544 gatt_send_error_rsp(tcb, cid, err, op_code, handle, false);
545 }
546 }
547
548 /*******************************************************************************
549 *
550 * Function gatt_build_primary_service_rsp
551 *
552 * Description Primamry service request processed internally. Theretically
553 * only deal with ReadByTypeValue and ReadByGroupType.
554 *
555 * Returns void
556 *
557 ******************************************************************************/
gatt_build_primary_service_rsp(BT_HDR * p_msg,tGATT_TCB & tcb,uint16_t cid,uint8_t op_code,uint16_t s_hdl,uint16_t e_hdl,uint8_t *,const Uuid & value)558 static tGATT_STATUS gatt_build_primary_service_rsp(BT_HDR* p_msg, tGATT_TCB& tcb, uint16_t cid,
559 uint8_t op_code, uint16_t s_hdl, uint16_t e_hdl,
560 uint8_t* /* p_data */, const Uuid& value) {
561 tGATT_STATUS status = GATT_NOT_FOUND;
562 uint8_t handle_len = 4;
563
564 uint8_t* p = (uint8_t*)(p_msg + 1) + L2CAP_MIN_OFFSET;
565
566 uint16_t payload_size = gatt_tcb_get_payload_size(tcb, cid);
567
568 for (tGATT_SRV_LIST_ELEM& el : *gatt_cb.srv_list_info) {
569 if (el.s_hdl < s_hdl || el.s_hdl > e_hdl || el.type != GATT_UUID_PRI_SERVICE) {
570 continue;
571 }
572
573 Uuid* p_uuid = gatts_get_service_uuid(el.p_db);
574 if (!p_uuid) {
575 continue;
576 }
577
578 if (op_code == GATT_REQ_READ_BY_GRP_TYPE) {
579 handle_len = 4 + gatt_build_uuid_to_stream_len(*p_uuid);
580 }
581
582 /* get the length byte in the repsonse */
583 if (p_msg->offset == 0) {
584 *p++ = op_code + 1;
585 p_msg->len++;
586 p_msg->offset = handle_len;
587
588 if (op_code == GATT_REQ_READ_BY_GRP_TYPE) {
589 *p++ = (uint8_t)p_msg->offset; /* length byte */
590 p_msg->len++;
591 }
592 }
593
594 if (p_msg->len + p_msg->offset > payload_size || handle_len != p_msg->offset) {
595 break;
596 }
597
598 if (op_code == GATT_REQ_FIND_TYPE_VALUE && value != *p_uuid) {
599 continue;
600 }
601
602 UINT16_TO_STREAM(p, el.s_hdl);
603
604 if (gatt_cb.last_service_handle && gatt_cb.last_service_handle == el.s_hdl) {
605 log::verbose("Use 0xFFFF for the last primary attribute");
606 /* see GATT ERRATA 4065, 4063, ATT ERRATA 4062 */
607 UINT16_TO_STREAM(p, 0xFFFF);
608 } else {
609 UINT16_TO_STREAM(p, el.e_hdl);
610 }
611
612 if (op_code == GATT_REQ_READ_BY_GRP_TYPE) {
613 gatt_build_uuid_to_stream(&p, *p_uuid);
614 }
615
616 status = GATT_SUCCESS;
617 p_msg->len += p_msg->offset;
618 }
619 p_msg->offset = L2CAP_MIN_OFFSET;
620
621 return status;
622 }
623
624 /**
625 * fill the find information response information in the given buffer.
626 *
627 * Returns true: if data filled sucessfully.
628 * false: packet full, or format mismatch.
629 */
gatt_build_find_info_rsp(tGATT_SRV_LIST_ELEM & el,BT_HDR * p_msg,uint16_t & len,uint16_t s_hdl,uint16_t e_hdl)630 static tGATT_STATUS gatt_build_find_info_rsp(tGATT_SRV_LIST_ELEM& el, BT_HDR* p_msg, uint16_t& len,
631 uint16_t s_hdl, uint16_t e_hdl) {
632 uint8_t info_pair_len[2] = {4, 18};
633
634 if (!el.p_db) {
635 return GATT_NOT_FOUND;
636 }
637
638 /* check the attribute database */
639
640 uint8_t* p = (uint8_t*)(p_msg + 1) + L2CAP_MIN_OFFSET + p_msg->len;
641
642 tGATT_STATUS status = GATT_NOT_FOUND;
643 for (auto& attr : el.p_db->attr_list) {
644 if (attr.handle > e_hdl) {
645 break;
646 }
647
648 if (attr.handle < s_hdl) {
649 continue;
650 }
651
652 uint8_t uuid_len = attr.uuid.GetShortestRepresentationSize();
653 if (p_msg->offset == 0) {
654 p_msg->offset =
655 (uuid_len == Uuid::kNumBytes16) ? GATT_INFO_TYPE_PAIR_16 : GATT_INFO_TYPE_PAIR_128;
656 }
657
658 if (len < info_pair_len[p_msg->offset - 1]) {
659 return GATT_NO_RESOURCES;
660 }
661
662 if (p_msg->offset == GATT_INFO_TYPE_PAIR_16 && uuid_len == Uuid::kNumBytes16) {
663 UINT16_TO_STREAM(p, attr.handle);
664 UINT16_TO_STREAM(p, attr.uuid.As16Bit());
665 } else if (p_msg->offset == GATT_INFO_TYPE_PAIR_128 && uuid_len == Uuid::kNumBytes128) {
666 UINT16_TO_STREAM(p, attr.handle);
667 ARRAY_TO_STREAM(p, attr.uuid.To128BitLE(), (int)Uuid::kNumBytes128);
668 } else if (p_msg->offset == GATT_INFO_TYPE_PAIR_128 && uuid_len == Uuid::kNumBytes32) {
669 UINT16_TO_STREAM(p, attr.handle);
670 ARRAY_TO_STREAM(p, attr.uuid.To128BitLE(), (int)Uuid::kNumBytes128);
671 } else {
672 log::error("format mismatch");
673 return GATT_NO_RESOURCES;
674 /* format mismatch */
675 }
676 p_msg->len += info_pair_len[p_msg->offset - 1];
677 len -= info_pair_len[p_msg->offset - 1];
678 status = GATT_SUCCESS;
679 }
680
681 return status;
682 }
683
read_handles(uint16_t & len,uint8_t * & p,uint16_t & s_hdl,uint16_t & e_hdl)684 static tGATT_STATUS read_handles(uint16_t& len, uint8_t*& p, uint16_t& s_hdl, uint16_t& e_hdl) {
685 if (len < 4) {
686 return GATT_INVALID_PDU;
687 }
688
689 /* obtain starting handle, and ending handle */
690 STREAM_TO_UINT16(s_hdl, p);
691 STREAM_TO_UINT16(e_hdl, p);
692 len -= 4;
693
694 if (s_hdl > e_hdl || !GATT_HANDLE_IS_VALID(s_hdl) || !GATT_HANDLE_IS_VALID(e_hdl)) {
695 return GATT_INVALID_HANDLE;
696 }
697
698 return GATT_SUCCESS;
699 }
700
gatts_validate_packet_format(uint8_t op_code,uint16_t & len,uint8_t * & p,Uuid * p_uuid,uint16_t & s_hdl,uint16_t & e_hdl)701 static tGATT_STATUS gatts_validate_packet_format(uint8_t op_code, uint16_t& len, uint8_t*& p,
702 Uuid* p_uuid, uint16_t& s_hdl, uint16_t& e_hdl) {
703 tGATT_STATUS ret = read_handles(len, p, s_hdl, e_hdl);
704 if (ret != GATT_SUCCESS) {
705 return ret;
706 }
707
708 if (len < 2) {
709 return GATT_INVALID_PDU;
710 }
711
712 /* parse uuid now */
713 log::assert_that(p_uuid != nullptr, "assert failed: p_uuid != nullptr");
714 uint16_t uuid_len = (op_code == GATT_REQ_FIND_TYPE_VALUE) ? 2 : len;
715 if (!gatt_parse_uuid_from_cmd(p_uuid, uuid_len, &p)) {
716 log::verbose("Bad UUID");
717 return GATT_INVALID_PDU;
718 }
719
720 len -= uuid_len;
721 return GATT_SUCCESS;
722 }
723
724 /*******************************************************************************
725 *
726 * Function gatts_process_primary_service_req
727 *
728 * Description Process ReadByGroupType/ReadByTypeValue request, for
729 * discovering all primary services or discover primary service
730 * by UUID request.
731 *
732 * Returns void
733 *
734 ******************************************************************************/
gatts_process_primary_service_req(tGATT_TCB & tcb,uint16_t cid,uint8_t op_code,uint16_t len,uint8_t * p_data)735 static void gatts_process_primary_service_req(tGATT_TCB& tcb, uint16_t cid, uint8_t op_code,
736 uint16_t len, uint8_t* p_data) {
737 uint16_t s_hdl = 0, e_hdl = 0;
738 Uuid uuid = Uuid::kEmpty;
739
740 uint8_t reason = gatts_validate_packet_format(op_code, len, p_data, &uuid, s_hdl, e_hdl);
741 if (reason != GATT_SUCCESS) {
742 gatt_send_error_rsp(tcb, cid, reason, op_code, s_hdl, false);
743 return;
744 }
745
746 if (uuid != Uuid::From16Bit(GATT_UUID_PRI_SERVICE)) {
747 if (op_code == GATT_REQ_READ_BY_GRP_TYPE) {
748 gatt_send_error_rsp(tcb, cid, GATT_UNSUPPORT_GRP_TYPE, op_code, s_hdl, false);
749 log::verbose("unexpected ReadByGrpType Group: {}", uuid.ToString());
750 return;
751 }
752
753 // we do not support ReadByTypeValue with any non-primamry_service type
754 gatt_send_error_rsp(tcb, cid, GATT_NOT_FOUND, op_code, s_hdl, false);
755 log::verbose("unexpected ReadByTypeValue type: {}", uuid.ToString());
756 return;
757 }
758
759 // TODO: we assume theh value is UUID, there is no such requirement in spec
760 Uuid value = Uuid::kEmpty;
761 if (op_code == GATT_REQ_FIND_TYPE_VALUE) {
762 if (!gatt_parse_uuid_from_cmd(&value, len, &p_data)) {
763 gatt_send_error_rsp(tcb, cid, GATT_INVALID_PDU, op_code, s_hdl, false);
764 }
765 }
766
767 uint16_t payload_size = gatt_tcb_get_payload_size(tcb, cid);
768
769 // This can happen if the channel is already closed.
770 if (payload_size == 0) {
771 return;
772 }
773
774 uint16_t msg_len = (uint16_t)(sizeof(BT_HDR) + payload_size + L2CAP_MIN_OFFSET);
775 BT_HDR* p_msg = (BT_HDR*)osi_calloc(msg_len);
776 reason = gatt_build_primary_service_rsp(p_msg, tcb, cid, op_code, s_hdl, e_hdl, p_data, value);
777 if (reason != GATT_SUCCESS) {
778 osi_free(p_msg);
779 gatt_send_error_rsp(tcb, cid, reason, op_code, s_hdl, false);
780 return;
781 }
782
783 attp_send_sr_msg(tcb, cid, p_msg);
784 }
785
786 /*******************************************************************************
787 *
788 * Function gatts_process_find_info
789 *
790 * Description process find information request, for discover character
791 * descriptors.
792 *
793 * Returns void
794 *
795 ******************************************************************************/
gatts_process_find_info(tGATT_TCB & tcb,uint16_t cid,uint8_t op_code,uint16_t len,uint8_t * p_data)796 static void gatts_process_find_info(tGATT_TCB& tcb, uint16_t cid, uint8_t op_code, uint16_t len,
797 uint8_t* p_data) {
798 uint16_t s_hdl = 0, e_hdl = 0;
799 uint8_t reason = read_handles(len, p_data, s_hdl, e_hdl);
800 if (reason != GATT_SUCCESS) {
801 gatt_send_error_rsp(tcb, cid, reason, op_code, s_hdl, false);
802 return;
803 }
804
805 uint16_t payload_size = gatt_tcb_get_payload_size(tcb, cid);
806
807 // This can happen if the channel is already closed.
808 if (payload_size == 0) {
809 return;
810 }
811
812 uint16_t buf_len = (uint16_t)(sizeof(BT_HDR) + payload_size + L2CAP_MIN_OFFSET);
813
814 BT_HDR* p_msg = (BT_HDR*)osi_calloc(buf_len);
815 reason = GATT_NOT_FOUND;
816
817 uint8_t* p = (uint8_t*)(p_msg + 1) + L2CAP_MIN_OFFSET;
818 *p++ = op_code + 1;
819 p_msg->len = 2;
820
821 buf_len = payload_size - 2;
822
823 for (tGATT_SRV_LIST_ELEM& el : *gatt_cb.srv_list_info) {
824 if (el.s_hdl <= e_hdl && el.e_hdl >= s_hdl) {
825 reason = gatt_build_find_info_rsp(el, p_msg, buf_len, s_hdl, e_hdl);
826 if (reason == GATT_NO_RESOURCES) {
827 reason = GATT_SUCCESS;
828 break;
829 }
830 }
831 }
832
833 *p = (uint8_t)p_msg->offset;
834
835 p_msg->offset = L2CAP_MIN_OFFSET;
836
837 if (reason != GATT_SUCCESS) {
838 osi_free(p_msg);
839 gatt_send_error_rsp(tcb, cid, reason, op_code, s_hdl, false);
840 } else {
841 attp_send_sr_msg(tcb, cid, p_msg);
842 }
843 }
844
845 /*******************************************************************************
846 *
847 * Function gatts_process_mtu_req
848 *
849 * Description This function is called to process excahnge MTU request.
850 * Only used on LE.
851 *
852 * Returns void
853 *
854 ******************************************************************************/
gatts_process_mtu_req(tGATT_TCB & tcb,uint16_t cid,uint16_t len,uint8_t * p_data)855 static void gatts_process_mtu_req(tGATT_TCB& tcb, uint16_t cid, uint16_t len, uint8_t* p_data) {
856 /* BR/EDR conenction, send error response */
857 if (cid != L2CAP_ATT_CID) {
858 gatt_send_error_rsp(tcb, cid, GATT_REQ_NOT_SUPPORTED, GATT_REQ_MTU, 0, false);
859 return;
860 }
861
862 if (len < GATT_MTU_REQ_MIN_LEN) {
863 log::error("invalid MTU request PDU received.");
864 gatt_send_error_rsp(tcb, cid, GATT_INVALID_PDU, GATT_REQ_MTU, 0, false);
865 return;
866 }
867
868 tGATT_SR_MSG gatt_sr_msg;
869
870 uint16_t mtu = 0;
871 uint8_t* p = p_data;
872 STREAM_TO_UINT16(mtu, p);
873 /* mtu must be greater than default MTU which is 23/48 */
874 if (mtu < GATT_DEF_BLE_MTU_SIZE) {
875 tcb.payload_size = GATT_DEF_BLE_MTU_SIZE;
876 } else {
877 tcb.payload_size = std::min(mtu, (uint16_t)(gatt_get_local_mtu()));
878 }
879
880 /* Always say to remote our default MTU. */
881 gatt_sr_msg.mtu = gatt_get_local_mtu();
882
883 log::info("MTU {} request from remote ({}), resulted MTU {}", mtu, tcb.peer_bda,
884 tcb.payload_size);
885
886 if (get_btm_client_interface().ble.BTM_SetBleDataLength(
887 tcb.peer_bda, tcb.payload_size + L2CAP_PKT_OVERHEAD) != tBTM_STATUS::BTM_SUCCESS) {
888 log::warn("Unable to set BLE data length peer:{} mtu:{}", tcb.peer_bda,
889 tcb.payload_size + L2CAP_PKT_OVERHEAD);
890 }
891
892 BT_HDR* p_buf = attp_build_sr_msg(tcb, GATT_RSP_MTU, &gatt_sr_msg, GATT_DEF_BLE_MTU_SIZE);
893 attp_send_sr_msg(tcb, cid, p_buf);
894
895 bluetooth::shim::arbiter::GetArbiter().OnIncomingMtuReq(tcb.tcb_idx, tcb.payload_size);
896
897 tGATTS_DATA gatts_data;
898 gatts_data.mtu = tcb.payload_size;
899 /* Notify all registered application with new MTU size. Use a transaction ID */
900 /* of 0, as no response is allowed from applications */
901 for (auto& [i, p_reg] : gatt_cb.cl_rcb_map) {
902 if (p_reg->in_use) {
903 tCONN_ID conn_id = gatt_create_conn_id(tcb.tcb_idx, p_reg->gatt_if);
904 gatt_sr_send_req_callback(conn_id, 0, GATTS_REQ_TYPE_MTU, &gatts_data);
905 }
906 }
907 }
908
909 /*******************************************************************************
910 *
911 * Function gatts_process_read_by_type_req
912 *
913 * Description process Read By type request.
914 * This PDU can be used to perform:
915 * - read characteristic value
916 * - read characteristic descriptor value
917 * - discover characteristic
918 * - discover characteristic by UUID
919 * - relationship discovery
920 *
921 * Returns void
922 *
923 ******************************************************************************/
gatts_process_read_by_type_req(tGATT_TCB & tcb,uint16_t cid,uint8_t op_code,uint16_t len,uint8_t * p_data)924 static void gatts_process_read_by_type_req(tGATT_TCB& tcb, uint16_t cid, uint8_t op_code,
925 uint16_t len, uint8_t* p_data) {
926 Uuid uuid = Uuid::kEmpty;
927 uint16_t s_hdl = 0, e_hdl = 0, err_hdl = 0;
928 tGATT_STATUS reason = gatts_validate_packet_format(op_code, len, p_data, &uuid, s_hdl, e_hdl);
929
930 #if (GATT_CONFORMANCE_TESTING == TRUE)
931 if (gatt_cb.enable_err_rsp && gatt_cb.req_op_code == op_code) {
932 log::verbose("Conformance tst: forced err rsp for ReadByType: error status={}",
933 gatt_cb.err_status);
934
935 gatt_send_error_rsp(tcb, cid, gatt_cb.err_status, gatt_cb.req_op_code, s_hdl, false);
936
937 return;
938 }
939 #endif
940
941 if (reason != GATT_SUCCESS) {
942 gatt_send_error_rsp(tcb, cid, reason, op_code, s_hdl, false);
943 return;
944 }
945
946 uint16_t payload_size = gatt_tcb_get_payload_size(tcb, cid);
947
948 // This can happen if the channel is already closed.
949 if (payload_size == 0) {
950 return;
951 }
952
953 size_t msg_len = sizeof(BT_HDR) + payload_size + L2CAP_MIN_OFFSET;
954 BT_HDR* p_msg = (BT_HDR*)osi_calloc(msg_len);
955 uint8_t* p = (uint8_t*)(p_msg + 1) + L2CAP_MIN_OFFSET;
956
957 *p++ = op_code + 1;
958 /* reserve length byte */
959 p_msg->len = 2;
960 uint16_t buf_len = payload_size - 2;
961
962 reason = GATT_NOT_FOUND;
963 for (tGATT_SRV_LIST_ELEM& el : *gatt_cb.srv_list_info) {
964 if (el.s_hdl <= e_hdl && el.e_hdl >= s_hdl) {
965 tGATT_SEC_FLAG sec_flag;
966 uint8_t key_size;
967 gatt_sr_get_sec_info(tcb.peer_bda, tcb.transport, &sec_flag, &key_size);
968
969 tGATT_STATUS ret =
970 gatts_db_read_attr_value_by_type(tcb, cid, el.p_db, op_code, p_msg, s_hdl, e_hdl,
971 uuid, &buf_len, sec_flag, key_size, 0, &err_hdl);
972 if (ret != GATT_NOT_FOUND) {
973 reason = ret;
974 if (ret == GATT_NO_RESOURCES) {
975 reason = GATT_SUCCESS;
976 }
977 }
978
979 if (ret != GATT_SUCCESS && ret != GATT_NOT_FOUND) {
980 s_hdl = err_hdl;
981 break;
982 }
983 }
984 }
985 *p = (uint8_t)p_msg->offset;
986 p_msg->offset = L2CAP_MIN_OFFSET;
987
988 if (reason != GATT_SUCCESS) {
989 osi_free(p_msg);
990
991 /* in theroy BUSY is not possible(should already been checked), protected
992 * check */
993 if (reason != GATT_PENDING && reason != GATT_BUSY) {
994 gatt_send_error_rsp(tcb, cid, reason, op_code, s_hdl, false);
995 }
996
997 return;
998 }
999
1000 attp_send_sr_msg(tcb, cid, p_msg);
1001 }
1002
1003 /**
1004 * This function is called to process the write request from client.
1005 */
gatts_process_write_req(tGATT_TCB & tcb,uint16_t cid,tGATT_SRV_LIST_ELEM & el,uint16_t handle,uint8_t op_code,uint16_t len,uint8_t * p_data,bt_gatt_db_attribute_type_t gatt_type)1006 static void gatts_process_write_req(tGATT_TCB& tcb, uint16_t cid, tGATT_SRV_LIST_ELEM& el,
1007 uint16_t handle, uint8_t op_code, uint16_t len, uint8_t* p_data,
1008 bt_gatt_db_attribute_type_t gatt_type) {
1009 tGATTS_DATA sr_data;
1010 uint32_t trans_id;
1011 tGATT_STATUS status;
1012 tGATT_SEC_FLAG sec_flag;
1013 uint8_t key_size, *p = p_data;
1014 tCONN_ID conn_id;
1015
1016 memset(&sr_data, 0, sizeof(tGATTS_DATA));
1017
1018 switch (op_code) {
1019 case GATT_REQ_PREPARE_WRITE:
1020 if (len < 2 || p == nullptr) {
1021 log::error("Prepare write request was invalid - missing offset, sending error response");
1022 gatt_send_error_rsp(tcb, cid, GATT_INVALID_PDU, op_code, handle, false);
1023 return;
1024 }
1025 sr_data.write_req.is_prep = true;
1026 STREAM_TO_UINT16(sr_data.write_req.offset, p);
1027 len -= 2;
1028 FALLTHROUGH_INTENDED; /* FALLTHROUGH */
1029 case GATT_SIGN_CMD_WRITE:
1030 if (op_code == GATT_SIGN_CMD_WRITE) {
1031 log::verbose("Write CMD with data sigining");
1032 len -= GATT_AUTH_SIGN_LEN;
1033 }
1034 FALLTHROUGH_INTENDED; /* FALLTHROUGH */
1035 case GATT_CMD_WRITE:
1036 case GATT_REQ_WRITE:
1037 if (op_code == GATT_REQ_WRITE || op_code == GATT_REQ_PREPARE_WRITE) {
1038 sr_data.write_req.need_rsp = true;
1039 }
1040 sr_data.write_req.handle = handle;
1041 if (len > GATT_MAX_ATTR_LEN) {
1042 len = GATT_MAX_ATTR_LEN;
1043 }
1044 sr_data.write_req.len = len;
1045 if (len != 0 && p != nullptr) {
1046 memcpy(sr_data.write_req.value, p, len);
1047 }
1048 break;
1049 }
1050
1051 gatt_sr_get_sec_info(tcb.peer_bda, tcb.transport, &sec_flag, &key_size);
1052
1053 status = gatts_write_attr_perm_check(el.p_db, op_code, handle, sr_data.write_req.offset, p, len,
1054 sec_flag, key_size);
1055
1056 if (status == GATT_SUCCESS) {
1057 trans_id = gatt_sr_enqueue_cmd(tcb, cid, op_code, handle);
1058 if (trans_id != 0) {
1059 conn_id = gatt_create_conn_id(tcb.tcb_idx, el.gatt_if);
1060
1061 uint8_t opcode = 0;
1062 if (gatt_type == BTGATT_DB_DESCRIPTOR) {
1063 opcode = GATTS_REQ_TYPE_WRITE_DESCRIPTOR;
1064 } else if (gatt_type == BTGATT_DB_CHARACTERISTIC) {
1065 opcode = GATTS_REQ_TYPE_WRITE_CHARACTERISTIC;
1066 } else {
1067 log::error(
1068 "Attempt to write attribute that's not tied with "
1069 "characteristic or descriptor value.");
1070 status = GATT_ERROR;
1071 }
1072
1073 if (opcode) {
1074 gatt_sr_send_req_callback(conn_id, trans_id, opcode, &sr_data);
1075 status = GATT_PENDING;
1076 }
1077 } else {
1078 log::error("max pending command, send error");
1079 status = GATT_BUSY; /* max pending command, application error */
1080 }
1081 }
1082
1083 /* in theroy BUSY is not possible(should already been checked), protected
1084 * check */
1085 if (status != GATT_PENDING && status != GATT_BUSY &&
1086 (op_code == GATT_REQ_PREPARE_WRITE || op_code == GATT_REQ_WRITE)) {
1087 gatt_send_error_rsp(tcb, cid, status, op_code, handle, false);
1088 }
1089 return;
1090 }
1091
1092 /**
1093 * This function is called to process the read request from client.
1094 */
gatts_process_read_req(tGATT_TCB & tcb,uint16_t cid,tGATT_SRV_LIST_ELEM & el,uint8_t op_code,uint16_t handle,uint16_t len,uint8_t * p_data)1095 static void gatts_process_read_req(tGATT_TCB& tcb, uint16_t cid, tGATT_SRV_LIST_ELEM& el,
1096 uint8_t op_code, uint16_t handle, uint16_t len,
1097 uint8_t* p_data) {
1098 uint16_t payload_size = gatt_tcb_get_payload_size(tcb, cid);
1099
1100 // This can happen if the channel is already closed.
1101 if (payload_size == 0) {
1102 return;
1103 }
1104
1105 size_t buf_len = sizeof(BT_HDR) + payload_size + L2CAP_MIN_OFFSET;
1106 uint16_t offset = 0;
1107
1108 if (op_code == GATT_REQ_READ_BLOB && len < sizeof(uint16_t)) {
1109 /* Error: packet length is too short */
1110 log::error("packet length={} too short. min={}", len, sizeof(uint16_t));
1111 gatt_send_error_rsp(tcb, cid, GATT_INVALID_PDU, op_code, 0, false);
1112 return;
1113 }
1114
1115 BT_HDR* p_msg = (BT_HDR*)osi_calloc(buf_len);
1116
1117 if (op_code == GATT_REQ_READ_BLOB) {
1118 STREAM_TO_UINT16(offset, p_data);
1119 }
1120
1121 uint8_t* p = (uint8_t*)(p_msg + 1) + L2CAP_MIN_OFFSET;
1122 *p++ = op_code + 1;
1123 p_msg->len = 1;
1124 buf_len = payload_size - 1;
1125
1126 tGATT_SEC_FLAG sec_flag;
1127 uint8_t key_size;
1128 gatt_sr_get_sec_info(tcb.peer_bda, tcb.transport, &sec_flag, &key_size);
1129
1130 uint16_t value_len = 0;
1131 tGATT_STATUS reason =
1132 gatts_read_attr_value_by_handle(tcb, cid, el.p_db, op_code, handle, offset, p, &value_len,
1133 (uint16_t)buf_len, sec_flag, key_size, 0);
1134 p_msg->len += value_len;
1135
1136 if (reason != GATT_SUCCESS) {
1137 osi_free(p_msg);
1138
1139 /* in theory BUSY is not possible(should already been checked), protected
1140 * check */
1141 if (reason != GATT_PENDING && reason != GATT_BUSY) {
1142 gatt_send_error_rsp(tcb, cid, reason, op_code, handle, false);
1143 }
1144
1145 return;
1146 }
1147
1148 attp_send_sr_msg(tcb, cid, p_msg);
1149 }
1150
1151 /*******************************************************************************
1152 *
1153 * Function gatts_process_attribute_req
1154 *
1155 * Description This function is called to process the per attribute handle
1156 * request from client.
1157 *
1158 * Returns void
1159 *
1160 ******************************************************************************/
gatts_process_attribute_req(tGATT_TCB & tcb,uint16_t cid,uint8_t op_code,uint16_t len,uint8_t * p_data)1161 static void gatts_process_attribute_req(tGATT_TCB& tcb, uint16_t cid, uint8_t op_code, uint16_t len,
1162 uint8_t* p_data) {
1163 uint16_t handle = 0;
1164 uint8_t* p = p_data;
1165 tGATT_STATUS status = GATT_INVALID_HANDLE;
1166
1167 if (len < 2) {
1168 log::error("Illegal PDU length, discard request");
1169 status = GATT_INVALID_PDU;
1170 } else {
1171 STREAM_TO_UINT16(handle, p);
1172 len -= 2;
1173 }
1174
1175 #if (GATT_CONFORMANCE_TESTING == TRUE)
1176 gatt_cb.handle = handle;
1177 if (gatt_cb.enable_err_rsp && gatt_cb.req_op_code == op_code) {
1178 log::verbose("Conformance tst: forced err rsp: error status={}", gatt_cb.err_status);
1179
1180 gatt_send_error_rsp(tcb, cid, gatt_cb.err_status, cid, gatt_cb.req_op_code, handle, false);
1181
1182 return;
1183 }
1184 #endif
1185
1186 if (GATT_HANDLE_IS_VALID(handle)) {
1187 for (auto& el : *gatt_cb.srv_list_info) {
1188 if (el.s_hdl <= handle && el.e_hdl >= handle) {
1189 for (const auto& attr : el.p_db->attr_list) {
1190 if (attr.handle == handle) {
1191 switch (op_code) {
1192 case GATT_REQ_READ: /* read char/char descriptor value */
1193 case GATT_REQ_READ_BLOB:
1194 gatts_process_read_req(tcb, cid, el, op_code, handle, len, p);
1195 break;
1196
1197 case GATT_REQ_WRITE: /* write char/char descriptor value */
1198 case GATT_CMD_WRITE:
1199 case GATT_SIGN_CMD_WRITE:
1200 case GATT_REQ_PREPARE_WRITE:
1201 gatts_process_write_req(tcb, cid, el, handle, op_code, len, p, attr.gatt_type);
1202 break;
1203 default:
1204 break;
1205 }
1206 status = GATT_SUCCESS;
1207 break;
1208 }
1209 }
1210 break;
1211 }
1212 }
1213 }
1214
1215 if (status != GATT_SUCCESS && op_code != GATT_CMD_WRITE && op_code != GATT_SIGN_CMD_WRITE) {
1216 gatt_send_error_rsp(tcb, cid, status, op_code, handle, false);
1217 }
1218 }
1219
1220 /*******************************************************************************
1221 *
1222 * Function gatts_proc_srv_chg_ind_ack
1223 *
1224 * Description This function process the service changed indicaiton ACK
1225 *
1226 * Returns void
1227 *
1228 ******************************************************************************/
gatts_proc_srv_chg_ind_ack(tGATT_TCB tcb)1229 void gatts_proc_srv_chg_ind_ack(tGATT_TCB tcb) {
1230 tGATTS_SRV_CHG_REQ req;
1231 tGATTS_SRV_CHG* p_buf = NULL;
1232
1233 log::verbose("");
1234
1235 p_buf = gatt_is_bda_in_the_srv_chg_clt_list(tcb.peer_bda);
1236 if (p_buf != NULL) {
1237 log::verbose("NV update set srv chg = false");
1238 p_buf->srv_changed = false;
1239 memcpy(&req.srv_chg, p_buf, sizeof(tGATTS_SRV_CHG));
1240 if (gatt_cb.cb_info.p_srv_chg_callback) {
1241 (*gatt_cb.cb_info.p_srv_chg_callback)(GATTS_SRV_CHG_CMD_UPDATE_CLIENT, &req, NULL);
1242 }
1243 }
1244 }
1245
1246 /*******************************************************************************
1247 *
1248 * Function gatts_chk_pending_ind
1249 *
1250 * Description This function check any pending indication needs to be sent
1251 * if there is a pending indication then sent the indication
1252 *
1253 * Returns void
1254 *
1255 ******************************************************************************/
gatts_chk_pending_ind(tGATT_TCB & tcb)1256 static void gatts_chk_pending_ind(tGATT_TCB& tcb) {
1257 log::verbose("");
1258
1259 tGATT_VALUE* p_buf = (tGATT_VALUE*)fixed_queue_try_peek_first(tcb.pending_ind_q);
1260 if (p_buf != NULL) {
1261 if (GATTS_HandleValueIndication(p_buf->conn_id, p_buf->handle, p_buf->len, p_buf->value) !=
1262 GATT_SUCCESS) {
1263 log::warn("Unable to send GATT server handle value conn_id:{}", p_buf->conn_id);
1264 }
1265 osi_free(fixed_queue_try_remove_from_queue(tcb.pending_ind_q, p_buf));
1266 }
1267 }
1268
1269 /*******************************************************************************
1270 *
1271 * Function gatts_proc_ind_ack
1272 *
1273 * Description This function processes the Indication ack
1274 *
1275 * Returns true continue to process the indication ack by the
1276 * application if the ACK is not a Service Changed Indication
1277 *
1278 ******************************************************************************/
gatts_proc_ind_ack(tGATT_TCB & tcb,uint16_t ack_handle)1279 static bool gatts_proc_ind_ack(tGATT_TCB& tcb, uint16_t ack_handle) {
1280 bool continue_processing = true;
1281
1282 log::verbose("ack handle={}", ack_handle);
1283
1284 if (ack_handle == gatt_cb.handle_of_h_r) {
1285 gatts_proc_srv_chg_ind_ack(tcb);
1286 /* there is no need to inform the application since srv chg is handled
1287 * internally by GATT */
1288 continue_processing = false;
1289
1290 // After receiving ack of svc_chg_ind, reset client status
1291 gatt_sr_update_cl_status(tcb, /* chg_aware= */ true);
1292 }
1293
1294 gatts_chk_pending_ind(tcb);
1295 return continue_processing;
1296 }
1297
1298 /*******************************************************************************
1299 *
1300 * Function gatts_process_value_conf
1301 *
1302 * Description This function is called to process the handle value
1303 * confirmation.
1304 *
1305 * Returns void
1306 *
1307 ******************************************************************************/
gatts_process_value_conf(tGATT_TCB & tcb,uint16_t cid,uint8_t op_code)1308 static void gatts_process_value_conf(tGATT_TCB& tcb, uint16_t cid, uint8_t op_code) {
1309 uint16_t handle;
1310
1311 if (!gatt_tcb_find_indicate_handle(tcb, cid, &handle)) {
1312 log::error("unexpected handle value confirmation");
1313 return;
1314 }
1315
1316 gatt_stop_conf_timer(tcb, cid);
1317
1318 bool continue_processing = gatts_proc_ind_ack(tcb, handle);
1319
1320 if (continue_processing) {
1321 tGATTS_DATA gatts_data;
1322 gatts_data.handle = handle;
1323 for (auto& el : *gatt_cb.srv_list_info) {
1324 if (el.s_hdl <= handle && el.e_hdl >= handle) {
1325 uint32_t trans_id = gatt_sr_enqueue_cmd(tcb, cid, op_code, handle);
1326 tCONN_ID conn_id = gatt_create_conn_id(tcb.tcb_idx, el.gatt_if);
1327 gatt_sr_send_req_callback(conn_id, trans_id, GATTS_REQ_TYPE_CONF, &gatts_data);
1328 }
1329 }
1330 }
1331 }
1332
gatts_process_db_out_of_sync(tGATT_TCB & tcb,uint16_t cid,uint8_t op_code,uint16_t len,uint8_t * p_data)1333 static bool gatts_process_db_out_of_sync(tGATT_TCB& tcb, uint16_t cid, uint8_t op_code,
1334 uint16_t len, uint8_t* p_data) {
1335 if (gatt_sr_is_cl_change_aware(tcb)) {
1336 return false;
1337 }
1338
1339 // default value
1340 bool should_ignore = true;
1341 bool should_rsp = true;
1342
1343 switch (op_code) {
1344 case GATT_REQ_READ_BY_TYPE: {
1345 // Check if read database hash by UUID
1346 Uuid uuid = Uuid::kEmpty;
1347 uint16_t s_hdl = 0, e_hdl = 0;
1348 uint16_t db_hash_handle = gatt_cb.handle_of_database_hash;
1349 tGATT_STATUS reason = gatts_validate_packet_format(op_code, len, p_data, &uuid, s_hdl, e_hdl);
1350 if (reason == GATT_SUCCESS && (s_hdl <= db_hash_handle && db_hash_handle <= e_hdl) &&
1351 (uuid == Uuid::From16Bit(GATT_UUID_DATABASE_HASH))) {
1352 should_ignore = false;
1353 }
1354 } break;
1355 case GATT_REQ_READ: {
1356 // Check if read database hash by handle
1357 uint16_t handle = 0;
1358 uint8_t* p = p_data;
1359 tGATT_STATUS status = GATT_SUCCESS;
1360
1361 if (len < 2) {
1362 status = GATT_INVALID_PDU;
1363 } else {
1364 STREAM_TO_UINT16(handle, p);
1365 len -= 2;
1366 }
1367
1368 if (status == GATT_SUCCESS && handle == gatt_cb.handle_of_database_hash) {
1369 should_ignore = false;
1370 }
1371 } break;
1372 case GATT_REQ_READ_BY_GRP_TYPE: /* discover primary services */
1373 case GATT_REQ_FIND_TYPE_VALUE: /* discover service by UUID */
1374 case GATT_REQ_FIND_INFO: /* discover char descrptor */
1375 case GATT_REQ_READ_BLOB: /* read long char */
1376 case GATT_REQ_READ_MULTI: /* read multi char*/
1377 case GATT_REQ_WRITE: /* write char/char descriptor value */
1378 case GATT_REQ_PREPARE_WRITE: /* write long char */
1379 // Use default value
1380 break;
1381 case GATT_CMD_WRITE: /* cmd */
1382 case GATT_SIGN_CMD_WRITE: /* sign cmd */
1383 should_rsp = false;
1384 break;
1385 case GATT_REQ_MTU: /* configure mtu */
1386 case GATT_REQ_EXEC_WRITE: /* execute write */
1387 case GATT_HANDLE_VALUE_CONF: /* confirm for indication */
1388 default:
1389 should_ignore = false;
1390 }
1391
1392 if (should_ignore) {
1393 if (should_rsp) {
1394 gatt_send_error_rsp(tcb, cid, GATT_DATABASE_OUT_OF_SYNC, op_code, 0x0000, false);
1395 }
1396 log::info("database out of sync, device={}, op_code=0x{:x}, should_rsp={}", tcb.peer_bda,
1397 (uint16_t)op_code, should_rsp);
1398 gatt_sr_update_cl_status(tcb, /* chg_aware= */ should_rsp);
1399 }
1400
1401 return should_ignore;
1402 }
1403
1404 /** This function is called to handle the client requests to server */
gatt_server_handle_client_req(tGATT_TCB & tcb,uint16_t cid,uint8_t op_code,uint16_t len,uint8_t * p_data)1405 void gatt_server_handle_client_req(tGATT_TCB& tcb, uint16_t cid, uint8_t op_code, uint16_t len,
1406 uint8_t* p_data) {
1407 /* there is pending command, discard this one */
1408 if (!gatt_sr_cmd_empty(tcb, cid) && op_code != GATT_HANDLE_VALUE_CONF) {
1409 return;
1410 }
1411
1412 /* the size of the message may not be bigger than the local max PDU size*/
1413 /* The message has to be smaller than the agreed MTU, len does not include op
1414 * code */
1415
1416 uint16_t payload_size = gatt_tcb_get_payload_size(tcb, cid);
1417 if (len >= payload_size) {
1418 log::error("server receive invalid PDU size:{} pdu size:{}", len + 1, payload_size);
1419 /* for invalid request expecting response, send it now */
1420 if (op_code != GATT_CMD_WRITE && op_code != GATT_SIGN_CMD_WRITE &&
1421 op_code != GATT_HANDLE_VALUE_CONF) {
1422 gatt_send_error_rsp(tcb, cid, GATT_INVALID_PDU, op_code, 0, false);
1423 }
1424 /* otherwise, ignore the pkt */
1425 } else {
1426 // handle database out of sync
1427 if (gatts_process_db_out_of_sync(tcb, cid, op_code, len, p_data)) {
1428 return;
1429 }
1430
1431 switch (op_code) {
1432 case GATT_REQ_READ_BY_GRP_TYPE: /* discover primary services */
1433 case GATT_REQ_FIND_TYPE_VALUE: /* discover service by UUID */
1434 gatts_process_primary_service_req(tcb, cid, op_code, len, p_data);
1435 break;
1436
1437 case GATT_REQ_FIND_INFO: /* discover char descrptor */
1438 gatts_process_find_info(tcb, cid, op_code, len, p_data);
1439 break;
1440
1441 case GATT_REQ_READ_BY_TYPE: /* read characteristic value, char descriptor
1442 value */
1443 /* discover characteristic, discover char by UUID */
1444 gatts_process_read_by_type_req(tcb, cid, op_code, len, p_data);
1445 break;
1446
1447 case GATT_REQ_READ: /* read char/char descriptor value */
1448 case GATT_REQ_READ_BLOB:
1449 case GATT_REQ_WRITE: /* write char/char descriptor value */
1450 case GATT_CMD_WRITE:
1451 case GATT_SIGN_CMD_WRITE:
1452 case GATT_REQ_PREPARE_WRITE:
1453 gatts_process_attribute_req(tcb, cid, op_code, len, p_data);
1454 break;
1455
1456 case GATT_HANDLE_VALUE_CONF:
1457 gatts_process_value_conf(tcb, cid, op_code);
1458 break;
1459
1460 case GATT_REQ_MTU:
1461 gatts_process_mtu_req(tcb, cid, len, p_data);
1462 break;
1463
1464 case GATT_REQ_EXEC_WRITE:
1465 gatt_process_exec_write_req(tcb, cid, op_code, len, p_data);
1466 break;
1467
1468 case GATT_REQ_READ_MULTI:
1469 case GATT_REQ_READ_MULTI_VAR:
1470 gatt_process_read_multi_req(tcb, cid, op_code, len, p_data);
1471 break;
1472
1473 default:
1474 break;
1475 }
1476 }
1477 }
1478