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