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