1 /******************************************************************************
2  *
3  *  Copyright 1999-2012 Broadcom Corporation
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at:
8  *
9  *  http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  ******************************************************************************/
18 
19 /******************************************************************************
20  *
21  *  this file contains the main GATT client functions
22  *
23  ******************************************************************************/
24 
25 #include "bt_target.h"
26 
27 #include <string.h>
28 #include "bt_common.h"
29 #include "bt_utils.h"
30 #include "gatt_int.h"
31 #include "l2c_api.h"
32 #include "log/log.h"
33 #include "osi/include/osi.h"
34 
35 #define GATT_WRITE_LONG_HDR_SIZE 5 /* 1 opcode + 2 handle + 2 offset */
36 #define GATT_READ_CHAR_VALUE_HDL (GATT_READ_CHAR_VALUE | 0x80)
37 #define GATT_READ_INC_SRV_UUID128 (GATT_DISC_INC_SRVC | 0x90)
38 
39 #define GATT_PREP_WRITE_RSP_MIN_LEN 4
40 #define GATT_NOTIFICATION_MIN_LEN 2
41 #define GATT_WRITE_RSP_MIN_LEN 2
42 #define GATT_INFO_RSP_MIN_LEN 1
43 #define GATT_MTU_RSP_MIN_LEN 2
44 #define GATT_READ_BY_TYPE_RSP_MIN_LEN 1
45 
46 using base::StringPrintf;
47 using bluetooth::Uuid;
48 
49 /*******************************************************************************
50  *                      G L O B A L      G A T T       D A T A                 *
51  ******************************************************************************/
52 void gatt_send_prepare_write(tGATT_TCB& tcb, tGATT_CLCB* p_clcb);
53 
54 uint8_t disc_type_to_att_opcode[GATT_DISC_MAX] = {
55     0,
56     GATT_REQ_READ_BY_GRP_TYPE, /*  GATT_DISC_SRVC_ALL = 1, */
57     GATT_REQ_FIND_TYPE_VALUE,  /*  GATT_DISC_SRVC_BY_UUID,  */
58     GATT_REQ_READ_BY_TYPE,     /*  GATT_DISC_INC_SRVC,      */
59     GATT_REQ_READ_BY_TYPE,     /*  GATT_DISC_CHAR,          */
60     GATT_REQ_FIND_INFO         /*  GATT_DISC_CHAR_DSCPT,    */
61 };
62 
63 uint16_t disc_type_to_uuid[GATT_DISC_MAX] = {
64     0,                         /* reserved */
65     GATT_UUID_PRI_SERVICE,     /* <service> DISC_SRVC_ALL */
66     GATT_UUID_PRI_SERVICE,     /* <service> for DISC_SERVC_BY_UUID */
67     GATT_UUID_INCLUDE_SERVICE, /* <include_service> for DISC_INC_SRVC */
68     GATT_UUID_CHAR_DECLARE,    /* <characteristic> for DISC_CHAR */
69     0                          /* no type filtering for DISC_CHAR_DSCPT */
70 };
71 
72 /*******************************************************************************
73  *
74  * Function         gatt_act_discovery
75  *
76  * Description      GATT discovery operation.
77  *
78  * Returns          void.
79  *
80  ******************************************************************************/
gatt_act_discovery(tGATT_CLCB * p_clcb)81 void gatt_act_discovery(tGATT_CLCB* p_clcb) {
82   uint8_t op_code = disc_type_to_att_opcode[p_clcb->op_subtype];
83 
84   if (p_clcb->s_handle > p_clcb->e_handle || p_clcb->s_handle == 0) {
85     /* end of handle range */
86     gatt_end_operation(p_clcb, GATT_SUCCESS, NULL);
87     return;
88   }
89 
90   tGATT_CL_MSG cl_req;
91   memset(&cl_req, 0, sizeof(tGATT_CL_MSG));
92 
93   cl_req.browse.s_handle = p_clcb->s_handle;
94   cl_req.browse.e_handle = p_clcb->e_handle;
95 
96   if (disc_type_to_uuid[p_clcb->op_subtype] != 0) {
97     cl_req.browse.uuid =
98         bluetooth::Uuid::From16Bit(disc_type_to_uuid[p_clcb->op_subtype]);
99   }
100 
101   if (p_clcb->op_subtype ==
102       GATT_DISC_SRVC_BY_UUID) /* fill in the FindByTypeValue request info*/
103   {
104     cl_req.find_type_value.uuid =
105         bluetooth::Uuid::From16Bit(disc_type_to_uuid[p_clcb->op_subtype]);
106     cl_req.find_type_value.s_handle = p_clcb->s_handle;
107     cl_req.find_type_value.e_handle = p_clcb->e_handle;
108 
109     size_t size = p_clcb->uuid.GetShortestRepresentationSize();
110     cl_req.find_type_value.value_len = size;
111     if (size == Uuid::kNumBytes16) {
112       uint8_t* p = cl_req.find_type_value.value;
113       UINT16_TO_STREAM(p, p_clcb->uuid.As16Bit());
114     } else if (size == Uuid::kNumBytes32) {
115       /* if service type is 32 bits UUID, convert it now */
116       memcpy(cl_req.find_type_value.value, p_clcb->uuid.To128BitLE().data(),
117             Uuid::kNumBytes128);
118       cl_req.find_type_value.value_len = Uuid::kNumBytes128;
119     } else
120       memcpy(cl_req.find_type_value.value, p_clcb->uuid.To128BitLE().data(),
121              size);
122   }
123 
124   tGATT_STATUS st = attp_send_cl_msg(*p_clcb->p_tcb, p_clcb, op_code, &cl_req);
125   if (st != GATT_SUCCESS && st != GATT_CMD_STARTED) {
126     gatt_end_operation(p_clcb, GATT_ERROR, NULL);
127   }
128 }
129 
130 /*******************************************************************************
131  *
132  * Function         gatt_act_read
133  *
134  * Description      GATT read operation.
135  *
136  * Returns          void.
137  *
138  ******************************************************************************/
gatt_act_read(tGATT_CLCB * p_clcb,uint16_t offset)139 void gatt_act_read(tGATT_CLCB* p_clcb, uint16_t offset) {
140   tGATT_TCB& tcb = *p_clcb->p_tcb;
141   uint8_t rt = GATT_INTERNAL_ERROR;
142   tGATT_CL_MSG msg;
143   uint8_t op_code = 0;
144 
145   memset(&msg, 0, sizeof(tGATT_CL_MSG));
146 
147   switch (p_clcb->op_subtype) {
148     case GATT_READ_CHAR_VALUE:
149     case GATT_READ_BY_TYPE:
150       op_code = GATT_REQ_READ_BY_TYPE;
151       msg.browse.s_handle = p_clcb->s_handle;
152       msg.browse.e_handle = p_clcb->e_handle;
153       if (p_clcb->op_subtype == GATT_READ_BY_TYPE)
154         msg.browse.uuid = p_clcb->uuid;
155       else {
156         msg.browse.uuid = bluetooth::Uuid::From16Bit(GATT_UUID_CHAR_DECLARE);
157       }
158       break;
159 
160     case GATT_READ_CHAR_VALUE_HDL:
161     case GATT_READ_BY_HANDLE:
162       if (!p_clcb->counter) {
163         op_code = GATT_REQ_READ;
164         msg.handle = p_clcb->s_handle;
165       } else {
166         if (!p_clcb->first_read_blob_after_read)
167           p_clcb->first_read_blob_after_read = true;
168         else
169           p_clcb->first_read_blob_after_read = false;
170 
171         VLOG(1) << __func__ << ": first_read_blob_after_read="
172                 << p_clcb->first_read_blob_after_read;
173         op_code = GATT_REQ_READ_BLOB;
174         msg.read_blob.offset = offset;
175         msg.read_blob.handle = p_clcb->s_handle;
176       }
177       p_clcb->op_subtype &= ~0x80;
178       break;
179 
180     case GATT_READ_PARTIAL:
181       op_code = GATT_REQ_READ_BLOB;
182       msg.read_blob.handle = p_clcb->s_handle;
183       msg.read_blob.offset = offset;
184       break;
185 
186     case GATT_READ_MULTIPLE:
187       op_code = GATT_REQ_READ_MULTI;
188       memcpy(&msg.read_multi, p_clcb->p_attr_buf, sizeof(tGATT_READ_MULTI));
189       break;
190 
191     case GATT_READ_INC_SRV_UUID128:
192       op_code = GATT_REQ_READ;
193       msg.handle = p_clcb->s_handle;
194       p_clcb->op_subtype &= ~0x90;
195       break;
196 
197     default:
198       LOG(ERROR) << "Unknown read type:" << +p_clcb->op_subtype;
199       break;
200   }
201 
202   if (op_code != 0) rt = attp_send_cl_msg(tcb, p_clcb, op_code, &msg);
203 
204   if (op_code == 0 || (rt != GATT_SUCCESS && rt != GATT_CMD_STARTED)) {
205     gatt_end_operation(p_clcb, rt, NULL);
206   }
207 }
208 
209 /** GATT write operation */
gatt_act_write(tGATT_CLCB * p_clcb,uint8_t sec_act)210 void gatt_act_write(tGATT_CLCB* p_clcb, uint8_t sec_act) {
211   tGATT_TCB& tcb = *p_clcb->p_tcb;
212 
213   CHECK(p_clcb->p_attr_buf);
214   tGATT_VALUE& attr = *((tGATT_VALUE*)p_clcb->p_attr_buf);
215 
216   switch (p_clcb->op_subtype) {
217     case GATT_WRITE_NO_RSP: {
218       p_clcb->s_handle = attr.handle;
219       uint8_t op_code = (sec_act == GATT_SEC_SIGN_DATA) ? GATT_SIGN_CMD_WRITE
220                                                         : GATT_CMD_WRITE;
221       uint8_t rt = gatt_send_write_msg(tcb, p_clcb, op_code, attr.handle,
222                                        attr.len, 0, attr.value);
223       if (rt != GATT_CMD_STARTED) {
224         if (rt != GATT_SUCCESS) {
225           LOG(ERROR) << StringPrintf(
226               "gatt_act_write() failed op_code=0x%x rt=%d", op_code, rt);
227         }
228         gatt_end_operation(p_clcb, rt, NULL);
229       }
230       return;
231     }
232 
233     case GATT_WRITE: {
234       if (attr.len <= (tcb.payload_size - GATT_HDR_SIZE)) {
235         p_clcb->s_handle = attr.handle;
236 
237         uint8_t rt = gatt_send_write_msg(tcb, p_clcb, GATT_REQ_WRITE,
238                                          attr.handle, attr.len, 0, attr.value);
239         if (rt != GATT_SUCCESS && rt != GATT_CMD_STARTED &&
240             rt != GATT_CONGESTED) {
241           if (rt != GATT_SUCCESS) {
242             LOG(ERROR) << StringPrintf(
243                 "gatt_act_write() failed op_code=0x%x rt=%d", GATT_REQ_WRITE,
244                 rt);
245           }
246           gatt_end_operation(p_clcb, rt, NULL);
247         }
248 
249       } else {
250         /* prepare write for long attribute */
251         gatt_send_prepare_write(tcb, p_clcb);
252       }
253       return;
254     }
255 
256     case GATT_WRITE_PREPARE:
257       gatt_send_prepare_write(tcb, p_clcb);
258       return;
259 
260     default:
261       CHECK(false) << "Unknown write type" << p_clcb->op_subtype;
262       return;
263   }
264 }
265 /*******************************************************************************
266  *
267  * Function         gatt_send_queue_write_cancel
268  *
269  * Description      send queue write cancel
270  *
271  * Returns          void.
272  *
273  ******************************************************************************/
gatt_send_queue_write_cancel(tGATT_TCB & tcb,tGATT_CLCB * p_clcb,tGATT_EXEC_FLAG flag)274 void gatt_send_queue_write_cancel(tGATT_TCB& tcb, tGATT_CLCB* p_clcb,
275                                   tGATT_EXEC_FLAG flag) {
276   uint8_t rt;
277 
278   VLOG(1) << __func__;
279 
280   tGATT_CL_MSG gatt_cl_msg;
281   gatt_cl_msg.exec_write = flag;
282   rt = attp_send_cl_msg(tcb, p_clcb, GATT_REQ_EXEC_WRITE, &gatt_cl_msg);
283 
284   if (rt != GATT_SUCCESS) {
285     gatt_end_operation(p_clcb, rt, NULL);
286   }
287 }
288 /*******************************************************************************
289  *
290  * Function         gatt_check_write_long_terminate
291  *
292  * Description      To terminate write long or not.
293  *
294  * Returns          true: write long is terminated; false keep sending.
295  *
296  ******************************************************************************/
gatt_check_write_long_terminate(tGATT_TCB & tcb,tGATT_CLCB * p_clcb,tGATT_VALUE * p_rsp_value)297 bool gatt_check_write_long_terminate(tGATT_TCB& tcb, tGATT_CLCB* p_clcb,
298                                      tGATT_VALUE* p_rsp_value) {
299   tGATT_VALUE* p_attr = (tGATT_VALUE*)p_clcb->p_attr_buf;
300   bool terminate = false;
301   tGATT_EXEC_FLAG flag = GATT_PREP_WRITE_EXEC;
302 
303   VLOG(1) << __func__;
304   /* check the first write response status */
305   if (p_rsp_value != NULL) {
306     if (p_rsp_value->handle != p_attr->handle ||
307         p_rsp_value->len != p_clcb->counter ||
308         memcmp(p_rsp_value->value, p_attr->value + p_attr->offset,
309                p_rsp_value->len)) {
310       /* data does not match    */
311       p_clcb->status = GATT_ERROR;
312       flag = GATT_PREP_WRITE_CANCEL;
313       terminate = true;
314     } else /* response checking is good */
315     {
316       p_clcb->status = GATT_SUCCESS;
317       /* update write offset and check if end of attribute value */
318       if ((p_attr->offset += p_rsp_value->len) >= p_attr->len) terminate = true;
319     }
320   }
321   if (terminate && p_clcb->op_subtype != GATT_WRITE_PREPARE) {
322     gatt_send_queue_write_cancel(tcb, p_clcb, flag);
323   }
324   return terminate;
325 }
326 
327 /** Send prepare write */
gatt_send_prepare_write(tGATT_TCB & tcb,tGATT_CLCB * p_clcb)328 void gatt_send_prepare_write(tGATT_TCB& tcb, tGATT_CLCB* p_clcb) {
329   tGATT_VALUE* p_attr = (tGATT_VALUE*)p_clcb->p_attr_buf;
330   uint8_t type = p_clcb->op_subtype;
331 
332   VLOG(1) << __func__ << StringPrintf(" type=0x%x", type);
333   uint16_t to_send = p_attr->len - p_attr->offset;
334 
335   if (to_send > (tcb.payload_size -
336                  GATT_WRITE_LONG_HDR_SIZE)) /* 2 = uint16_t offset bytes  */
337     to_send = tcb.payload_size - GATT_WRITE_LONG_HDR_SIZE;
338 
339   p_clcb->s_handle = p_attr->handle;
340 
341   uint16_t offset = p_attr->offset;
342   if (type == GATT_WRITE_PREPARE) {
343     offset += p_clcb->start_offset;
344   }
345 
346   VLOG(1) << StringPrintf("offset =0x%x len=%d", offset, to_send);
347 
348   uint8_t rt = gatt_send_write_msg(tcb, p_clcb, GATT_REQ_PREPARE_WRITE,
349                                    p_attr->handle, to_send, /* length */
350                                    offset,                  /* used as offset */
351                                    p_attr->value + p_attr->offset); /* data */
352 
353   /* remember the write long attribute length */
354   p_clcb->counter = to_send;
355 
356   if (rt != GATT_SUCCESS && rt != GATT_CMD_STARTED && rt != GATT_CONGESTED) {
357     gatt_end_operation(p_clcb, rt, NULL);
358   }
359 }
360 
361 /*******************************************************************************
362  *
363  * Function         gatt_process_find_type_value_rsp
364  *
365  * Description      This function handles the find by type value response.
366  *
367  *
368  * Returns          void
369  *
370  ******************************************************************************/
gatt_process_find_type_value_rsp(UNUSED_ATTR tGATT_TCB & tcb,tGATT_CLCB * p_clcb,uint16_t len,uint8_t * p_data)371 void gatt_process_find_type_value_rsp(UNUSED_ATTR tGATT_TCB& tcb,
372                                       tGATT_CLCB* p_clcb, uint16_t len,
373                                       uint8_t* p_data) {
374   tGATT_DISC_RES result;
375   uint8_t* p = p_data;
376 
377   VLOG(1) << __func__;
378   /* unexpected response */
379   if (p_clcb->operation != GATTC_OPTYPE_DISCOVERY ||
380       p_clcb->op_subtype != GATT_DISC_SRVC_BY_UUID)
381     return;
382 
383   memset(&result, 0, sizeof(tGATT_DISC_RES));
384   result.type = bluetooth::Uuid::From16Bit(GATT_UUID_PRI_SERVICE);
385 
386   /* returns a series of handle ranges */
387   while (len >= 4) {
388     STREAM_TO_UINT16(result.handle, p);
389     STREAM_TO_UINT16(result.value.group_value.e_handle, p);
390     result.value.group_value.service_type = p_clcb->uuid;
391 
392     len -= 4;
393 
394     if (p_clcb->p_reg->app_cb.p_disc_res_cb)
395       (*p_clcb->p_reg->app_cb.p_disc_res_cb)(p_clcb->conn_id,
396                                              p_clcb->op_subtype, &result);
397   }
398 
399   /* last handle  + 1 */
400   p_clcb->s_handle = (result.value.group_value.e_handle == 0)
401                          ? 0
402                          : (result.value.group_value.e_handle + 1);
403   /* initiate another request */
404   gatt_act_discovery(p_clcb);
405 }
406 /*******************************************************************************
407  *
408  * Function         gatt_process_read_info_rsp
409  *
410  * Description      This function is called to handle the read information
411  *                  response.
412  *
413  *
414  * Returns          void
415  *
416  ******************************************************************************/
gatt_process_read_info_rsp(UNUSED_ATTR tGATT_TCB & tcb,tGATT_CLCB * p_clcb,UNUSED_ATTR uint8_t op_code,uint16_t len,uint8_t * p_data)417 void gatt_process_read_info_rsp(UNUSED_ATTR tGATT_TCB& tcb, tGATT_CLCB* p_clcb,
418                                 UNUSED_ATTR uint8_t op_code, uint16_t len,
419                                 uint8_t* p_data) {
420   tGATT_DISC_RES result;
421   uint8_t *p = p_data, uuid_len = 0, type;
422 
423   if (len < GATT_INFO_RSP_MIN_LEN) {
424     LOG(ERROR) << "invalid Info Response PDU received, discard.";
425     gatt_end_operation(p_clcb, GATT_INVALID_PDU, NULL);
426     return;
427   }
428   /* unexpected response */
429   if (p_clcb->operation != GATTC_OPTYPE_DISCOVERY ||
430       p_clcb->op_subtype != GATT_DISC_CHAR_DSCPT)
431     return;
432 
433   STREAM_TO_UINT8(type, p);
434   len -= 1;
435 
436   if (type == GATT_INFO_TYPE_PAIR_16)
437     uuid_len = Uuid::kNumBytes16;
438   else if (type == GATT_INFO_TYPE_PAIR_128)
439     uuid_len = Uuid::kNumBytes128;
440 
441   while (len >= uuid_len + 2) {
442     STREAM_TO_UINT16(result.handle, p);
443 
444     if (uuid_len > 0) {
445       if (!gatt_parse_uuid_from_cmd(&result.type, uuid_len, &p)) break;
446     } else
447       result.type = p_clcb->uuid;
448 
449     len -= (uuid_len + 2);
450 
451     if (p_clcb->p_reg->app_cb.p_disc_res_cb)
452       (*p_clcb->p_reg->app_cb.p_disc_res_cb)(p_clcb->conn_id,
453                                              p_clcb->op_subtype, &result);
454   }
455 
456   p_clcb->s_handle = (result.handle == 0) ? 0 : (result.handle + 1);
457   /* initiate another request */
458   gatt_act_discovery(p_clcb);
459 }
460 /*******************************************************************************
461  *
462  * Function         gatt_proc_disc_error_rsp
463  *
464  * Description      Process the read by type response and send another request
465  *                  if needed.
466  *
467  * Returns          void.
468  *
469  ******************************************************************************/
gatt_proc_disc_error_rsp(UNUSED_ATTR tGATT_TCB & tcb,tGATT_CLCB * p_clcb,uint8_t opcode,UNUSED_ATTR uint16_t handle,uint8_t reason)470 void gatt_proc_disc_error_rsp(UNUSED_ATTR tGATT_TCB& tcb, tGATT_CLCB* p_clcb,
471                               uint8_t opcode, UNUSED_ATTR uint16_t handle,
472                               uint8_t reason) {
473   tGATT_STATUS status = (tGATT_STATUS)reason;
474 
475   VLOG(1) << __func__
476           << StringPrintf("reason: %02x cmd_code %04x", reason, opcode);
477 
478   switch (opcode) {
479     case GATT_REQ_READ_BY_GRP_TYPE:
480     case GATT_REQ_FIND_TYPE_VALUE:
481     case GATT_REQ_READ_BY_TYPE:
482     case GATT_REQ_FIND_INFO:
483       if (reason == GATT_NOT_FOUND) {
484         status = GATT_SUCCESS;
485         VLOG(1) << "Discovery completed";
486       }
487       break;
488     default:
489       LOG(ERROR) << StringPrintf("Incorrect discovery opcode %04x", opcode);
490       break;
491   }
492 
493   gatt_end_operation(p_clcb, status, NULL);
494 }
495 
496 /*******************************************************************************
497  *
498  * Function         gatt_process_error_rsp
499  *
500  * Description      This function is called to handle the error response
501  *
502  *
503  * Returns          void
504  *
505  ******************************************************************************/
gatt_process_error_rsp(tGATT_TCB & tcb,tGATT_CLCB * p_clcb,UNUSED_ATTR uint8_t op_code,UNUSED_ATTR uint16_t len,uint8_t * p_data)506 void gatt_process_error_rsp(tGATT_TCB& tcb, tGATT_CLCB* p_clcb,
507                             UNUSED_ATTR uint8_t op_code,
508                             UNUSED_ATTR uint16_t len, uint8_t* p_data) {
509   uint8_t opcode, reason, *p = p_data;
510   uint16_t handle;
511   tGATT_VALUE* p_attr = (tGATT_VALUE*)p_clcb->p_attr_buf;
512 
513   VLOG(1) << __func__;
514 
515   if (len < 4) {
516     android_errorWriteLog(0x534e4554, "79591688");
517     LOG(ERROR) << "Error response too short";
518     // Specification does not clearly define what should happen if error
519     // response is too short. General rule in BT Spec 5.0 Vol 3, Part F 3.4.1.1
520     // is: "If an error code is received in the Error Response that is not
521     // understood by the client, for example an error code that was reserved for
522     // future use that is now being used in a future version of this
523     // specification, then the Error Response shall still be considered to state
524     // that the given request cannot be performed for an unknown reason."
525     opcode = handle = 0;
526     reason = 0x7F;
527   } else {
528     STREAM_TO_UINT8(opcode, p);
529     STREAM_TO_UINT16(handle, p);
530     STREAM_TO_UINT8(reason, p);
531   }
532 
533   if (p_clcb->operation == GATTC_OPTYPE_DISCOVERY) {
534     gatt_proc_disc_error_rsp(tcb, p_clcb, opcode, handle, reason);
535   } else {
536     if ((p_clcb->operation == GATTC_OPTYPE_WRITE) &&
537         (p_clcb->op_subtype == GATT_WRITE) &&
538         (opcode == GATT_REQ_PREPARE_WRITE) && (p_attr) &&
539         (handle == p_attr->handle)) {
540       p_clcb->status = reason;
541       gatt_send_queue_write_cancel(tcb, p_clcb, GATT_PREP_WRITE_CANCEL);
542     } else if ((p_clcb->operation == GATTC_OPTYPE_READ) &&
543                ((p_clcb->op_subtype == GATT_READ_CHAR_VALUE_HDL) ||
544                 (p_clcb->op_subtype == GATT_READ_BY_HANDLE)) &&
545                (opcode == GATT_REQ_READ_BLOB) &&
546                p_clcb->first_read_blob_after_read &&
547                (reason == GATT_NOT_LONG)) {
548       gatt_end_operation(p_clcb, GATT_SUCCESS, (void*)p_clcb->p_attr_buf);
549     } else
550       gatt_end_operation(p_clcb, reason, NULL);
551   }
552 }
553 /*******************************************************************************
554  *
555  * Function         gatt_process_prep_write_rsp
556  *
557  * Description      This function is called to handle the read response
558  *
559  *
560  * Returns          void
561  *
562  ******************************************************************************/
gatt_process_prep_write_rsp(tGATT_TCB & tcb,tGATT_CLCB * p_clcb,uint8_t op_code,uint16_t len,uint8_t * p_data)563 void gatt_process_prep_write_rsp(tGATT_TCB& tcb, tGATT_CLCB* p_clcb,
564                                  uint8_t op_code, uint16_t len,
565                                  uint8_t* p_data) {
566   uint8_t* p = p_data;
567 
568   tGATT_VALUE value = {
569       .conn_id = p_clcb->conn_id, .auth_req = GATT_AUTH_REQ_NONE,
570   };
571 
572   LOG(ERROR) << StringPrintf("value resp op_code = %s len = %d",
573                              gatt_dbg_op_name(op_code), len);
574 
575   if (len < GATT_PREP_WRITE_RSP_MIN_LEN) {
576     LOG(ERROR) << "illegal prepare write response length, discard";
577     gatt_end_operation(p_clcb, GATT_INVALID_PDU, &value);
578     return;
579   }
580 
581   STREAM_TO_UINT16(value.handle, p);
582   STREAM_TO_UINT16(value.offset, p);
583 
584   value.len = len - 4;
585 
586   memcpy(value.value, p, value.len);
587 
588   if (!gatt_check_write_long_terminate(tcb, p_clcb, &value)) {
589     gatt_send_prepare_write(tcb, p_clcb);
590     return;
591   }
592 
593   if (p_clcb->op_subtype == GATT_WRITE_PREPARE) {
594     /* application should verify handle offset
595        and value are matched or not */
596     gatt_end_operation(p_clcb, p_clcb->status, &value);
597   }
598 }
599 /*******************************************************************************
600  *
601  * Function         gatt_process_notification
602  *
603  * Description      Handle the handle value indication/notification.
604  *
605  * Returns          void
606  *
607  ******************************************************************************/
gatt_process_notification(tGATT_TCB & tcb,uint8_t op_code,uint16_t len,uint8_t * p_data)608 void gatt_process_notification(tGATT_TCB& tcb, uint8_t op_code, uint16_t len,
609                                uint8_t* p_data) {
610   tGATT_VALUE value;
611   tGATT_REG* p_reg;
612   uint16_t conn_id;
613   tGATT_STATUS encrypt_status;
614   uint8_t* p = p_data;
615   uint8_t i;
616   uint8_t event = (op_code == GATT_HANDLE_VALUE_NOTIF)
617                       ? GATTC_OPTYPE_NOTIFICATION
618                       : GATTC_OPTYPE_INDICATION;
619 
620   VLOG(1) << __func__;
621 
622   if (len < GATT_NOTIFICATION_MIN_LEN) {
623     LOG(ERROR) << "illegal notification PDU length, discard";
624     return;
625   }
626 
627   memset(&value, 0, sizeof(value));
628   STREAM_TO_UINT16(value.handle, p);
629   value.len = len - 2;
630   if (value.len > GATT_MAX_ATTR_LEN) {
631     LOG(ERROR) << "value.len larger than GATT_MAX_ATTR_LEN, discard";
632     return;
633   }
634   memcpy(value.value, p, value.len);
635 
636   if (!GATT_HANDLE_IS_VALID(value.handle)) {
637     /* illegal handle, send ack now */
638     if (op_code == GATT_HANDLE_VALUE_IND)
639       attp_send_cl_msg(tcb, nullptr, GATT_HANDLE_VALUE_CONF, NULL);
640     return;
641   }
642 
643   if (event == GATTC_OPTYPE_INDICATION) {
644     if (tcb.ind_count) {
645       /* this is an error case that receiving an indication but we
646          still has an indication not being acked yet.
647          For now, just log the error reset the counter.
648          Later we need to disconnect the link unconditionally.
649       */
650       LOG(ERROR) << __func__ << " rcv Ind. but ind_count=" << tcb.ind_count
651                  << " (will reset ind_count)";
652     }
653     tcb.ind_count = 0;
654   }
655 
656   /* should notify all registered client with the handle value
657      notificaion/indication
658      Note: need to do the indication count and start timer first then do
659      callback
660    */
661 
662   for (i = 0, p_reg = gatt_cb.cl_rcb; i < GATT_MAX_APPS; i++, p_reg++) {
663     if (p_reg->in_use && p_reg->app_cb.p_cmpl_cb &&
664         (event == GATTC_OPTYPE_INDICATION))
665       tcb.ind_count++;
666   }
667 
668   if (event == GATTC_OPTYPE_INDICATION) {
669     /* start a timer for app confirmation */
670     if (tcb.ind_count > 0)
671       gatt_start_ind_ack_timer(tcb);
672     else /* no app to indicate, or invalid handle */
673       attp_send_cl_msg(tcb, nullptr, GATT_HANDLE_VALUE_CONF, NULL);
674   }
675 
676   encrypt_status = gatt_get_link_encrypt_status(tcb);
677   tGATT_CL_COMPLETE gatt_cl_complete;
678   gatt_cl_complete.att_value = value;
679   for (i = 0, p_reg = gatt_cb.cl_rcb; i < GATT_MAX_APPS; i++, p_reg++) {
680     if (p_reg->in_use && p_reg->app_cb.p_cmpl_cb) {
681       conn_id = GATT_CREATE_CONN_ID(tcb.tcb_idx, p_reg->gatt_if);
682       (*p_reg->app_cb.p_cmpl_cb)(conn_id, event, encrypt_status,
683                                  &gatt_cl_complete);
684     }
685   }
686 }
687 
688 /*******************************************************************************
689  *
690  * Function         gatt_process_read_by_type_rsp
691  *
692  * Description      This function is called to handle the read by type response.
693  *                  read by type can be used for discovery, or read by type or
694  *                  read characteristic value.
695  *
696  * Returns          void
697  *
698  ******************************************************************************/
gatt_process_read_by_type_rsp(tGATT_TCB & tcb,tGATT_CLCB * p_clcb,uint8_t op_code,uint16_t len,uint8_t * p_data)699 void gatt_process_read_by_type_rsp(tGATT_TCB& tcb, tGATT_CLCB* p_clcb,
700                                    uint8_t op_code, uint16_t len,
701                                    uint8_t* p_data) {
702   tGATT_DISC_RES result;
703   tGATT_DISC_VALUE record_value;
704   uint8_t *p = p_data, value_len, handle_len = 2;
705   uint16_t handle = 0;
706 
707   /* discovery procedure and no callback function registered */
708   if (((!p_clcb->p_reg) || (!p_clcb->p_reg->app_cb.p_disc_res_cb)) &&
709       (p_clcb->operation == GATTC_OPTYPE_DISCOVERY))
710     return;
711 
712   if (len < GATT_READ_BY_TYPE_RSP_MIN_LEN) {
713     LOG(ERROR) << "Illegal ReadByType/ReadByGroupType Response length, discard";
714     gatt_end_operation(p_clcb, GATT_INVALID_PDU, NULL);
715     return;
716   }
717 
718   STREAM_TO_UINT8(value_len, p);
719 
720   if ((value_len > (tcb.payload_size - 2)) || (value_len > (len - 1))) {
721     /* this is an error case that server's response containing a value length
722        which is larger than MTU-2
723        or value_len > message total length -1 */
724     LOG(ERROR) << __func__
725                << StringPrintf(
726                       ": Discard response op_code=%d "
727                       "vale_len=%d > (MTU-2=%d or msg_len-1=%d)",
728                       op_code, value_len, (tcb.payload_size - 2), (len - 1));
729     gatt_end_operation(p_clcb, GATT_ERROR, NULL);
730     return;
731   }
732 
733   if (op_code == GATT_RSP_READ_BY_GRP_TYPE) handle_len = 4;
734 
735   value_len -= handle_len; /* substract the handle pairs bytes */
736   len -= 1;
737 
738   while (len >= (handle_len + value_len)) {
739     STREAM_TO_UINT16(handle, p);
740 
741     if (!GATT_HANDLE_IS_VALID(handle)) {
742       gatt_end_operation(p_clcb, GATT_INVALID_HANDLE, NULL);
743       return;
744     }
745 
746     memset(&result, 0, sizeof(tGATT_DISC_RES));
747     memset(&record_value, 0, sizeof(tGATT_DISC_VALUE));
748 
749     result.handle = handle;
750     result.type =
751         bluetooth::Uuid::From16Bit(disc_type_to_uuid[p_clcb->op_subtype]);
752 
753     /* discover all services */
754     if (p_clcb->operation == GATTC_OPTYPE_DISCOVERY &&
755         p_clcb->op_subtype == GATT_DISC_SRVC_ALL &&
756         op_code == GATT_RSP_READ_BY_GRP_TYPE) {
757       STREAM_TO_UINT16(handle, p);
758 
759       if (!GATT_HANDLE_IS_VALID(handle)) {
760         gatt_end_operation(p_clcb, GATT_INVALID_HANDLE, NULL);
761         return;
762       } else {
763         record_value.group_value.e_handle = handle;
764         if (!gatt_parse_uuid_from_cmd(&record_value.group_value.service_type,
765                                       value_len, &p)) {
766           LOG(ERROR) << "discover all service response parsing failure";
767           break;
768         }
769       }
770     }
771     /* discover included service */
772     else if (p_clcb->operation == GATTC_OPTYPE_DISCOVERY &&
773              p_clcb->op_subtype == GATT_DISC_INC_SRVC) {
774       STREAM_TO_UINT16(record_value.incl_service.s_handle, p);
775       STREAM_TO_UINT16(record_value.incl_service.e_handle, p);
776 
777       if (!GATT_HANDLE_IS_VALID(record_value.incl_service.s_handle) ||
778           !GATT_HANDLE_IS_VALID(record_value.incl_service.e_handle)) {
779         gatt_end_operation(p_clcb, GATT_INVALID_HANDLE, NULL);
780         return;
781       }
782 
783       if (value_len == 6) {
784         uint16_t tmp;
785         STREAM_TO_UINT16(tmp, p);
786         record_value.incl_service.service_type =
787             bluetooth::Uuid::From16Bit(tmp);
788       } else if (value_len == 4) {
789         p_clcb->s_handle = record_value.incl_service.s_handle;
790         p_clcb->read_uuid128.wait_for_read_rsp = true;
791         p_clcb->read_uuid128.next_disc_start_hdl = handle + 1;
792         memcpy(&p_clcb->read_uuid128.result, &result, sizeof(result));
793         memcpy(&p_clcb->read_uuid128.result.value, &record_value,
794                sizeof(result.value));
795         p_clcb->op_subtype |= 0x90;
796         gatt_act_read(p_clcb, 0);
797         return;
798       } else {
799         LOG(ERROR) << __func__
800                    << ": INCL_SRVC failed with invalid data value_len="
801                    << +value_len;
802         gatt_end_operation(p_clcb, GATT_INVALID_PDU, (void*)p);
803         return;
804       }
805     }
806     /* read by type */
807     else if (p_clcb->operation == GATTC_OPTYPE_READ &&
808              p_clcb->op_subtype == GATT_READ_BY_TYPE) {
809       p_clcb->counter = len - 2;
810       p_clcb->s_handle = handle;
811       if (p_clcb->counter == (p_clcb->p_tcb->payload_size - 4)) {
812         p_clcb->op_subtype = GATT_READ_BY_HANDLE;
813         if (!p_clcb->p_attr_buf)
814           p_clcb->p_attr_buf = (uint8_t*)osi_malloc(GATT_MAX_ATTR_LEN);
815         if (p_clcb->counter <= GATT_MAX_ATTR_LEN) {
816           memcpy(p_clcb->p_attr_buf, p, p_clcb->counter);
817           gatt_act_read(p_clcb, p_clcb->counter);
818         } else {
819           gatt_end_operation(p_clcb, GATT_INTERNAL_ERROR, (void*)p);
820         }
821       } else {
822         gatt_end_operation(p_clcb, GATT_SUCCESS, (void*)p);
823       }
824       return;
825     } else /* discover characterisitic */
826     {
827       STREAM_TO_UINT8(record_value.dclr_value.char_prop, p);
828       STREAM_TO_UINT16(record_value.dclr_value.val_handle, p);
829       if (!GATT_HANDLE_IS_VALID(record_value.dclr_value.val_handle)) {
830         gatt_end_operation(p_clcb, GATT_INVALID_HANDLE, NULL);
831         return;
832       }
833       if (!gatt_parse_uuid_from_cmd(&record_value.dclr_value.char_uuid,
834                                     (uint16_t)(value_len - 3), &p)) {
835         gatt_end_operation(p_clcb, GATT_SUCCESS, NULL);
836         /* invalid format, and skip the result */
837         return;
838       }
839 
840       /* UUID not matching */
841       if (!p_clcb->uuid.IsEmpty() &&
842           !record_value.dclr_value.char_uuid.IsEmpty() &&
843           record_value.dclr_value.char_uuid != p_clcb->uuid) {
844         len -= (value_len + 2);
845         continue; /* skip the result, and look for next one */
846       }
847 
848       if (p_clcb->operation == GATTC_OPTYPE_READ)
849       /* UUID match for read characteristic value */
850       {
851         /* only read the first matching UUID characteristic value, and
852           discard the rest results */
853         p_clcb->s_handle = record_value.dclr_value.val_handle;
854         p_clcb->op_subtype |= 0x80;
855         gatt_act_read(p_clcb, 0);
856         return;
857       }
858     }
859     len -= (value_len + handle_len);
860 
861     /* result is (handle, 16bits UUID) pairs */
862     memcpy(&result.value, &record_value, sizeof(result.value));
863 
864     /* send callback if is discover procedure */
865     if (p_clcb->operation == GATTC_OPTYPE_DISCOVERY &&
866         p_clcb->p_reg->app_cb.p_disc_res_cb)
867       (*p_clcb->p_reg->app_cb.p_disc_res_cb)(p_clcb->conn_id,
868                                              p_clcb->op_subtype, &result);
869   }
870 
871   p_clcb->s_handle = (handle == 0) ? 0 : (handle + 1);
872 
873   if (p_clcb->operation == GATTC_OPTYPE_DISCOVERY) {
874     /* initiate another request */
875     gatt_act_discovery(p_clcb);
876   } else /* read characteristic value */
877   {
878     gatt_act_read(p_clcb, 0);
879   }
880 }
881 
882 /*******************************************************************************
883  *
884  * Function         gatt_process_read_rsp
885  *
886  * Description      This function is called to handle the read BLOB response
887  *
888  *
889  * Returns          void
890  *
891  ******************************************************************************/
gatt_process_read_rsp(tGATT_TCB & tcb,tGATT_CLCB * p_clcb,UNUSED_ATTR uint8_t op_code,uint16_t len,uint8_t * p_data)892 void gatt_process_read_rsp(tGATT_TCB& tcb, tGATT_CLCB* p_clcb,
893                            UNUSED_ATTR uint8_t op_code, uint16_t len,
894                            uint8_t* p_data) {
895   uint16_t offset = p_clcb->counter;
896   uint8_t* p = p_data;
897 
898   if (p_clcb->operation == GATTC_OPTYPE_READ) {
899     if (p_clcb->op_subtype != GATT_READ_BY_HANDLE) {
900       p_clcb->counter = len;
901       gatt_end_operation(p_clcb, GATT_SUCCESS, (void*)p);
902     } else {
903       /* allocate GKI buffer holding up long attribute value  */
904       if (!p_clcb->p_attr_buf)
905         p_clcb->p_attr_buf = (uint8_t*)osi_malloc(GATT_MAX_ATTR_LEN);
906 
907       /* copy attrobute value into cb buffer  */
908       if (offset < GATT_MAX_ATTR_LEN) {
909         if ((len + offset) > GATT_MAX_ATTR_LEN)
910           len = GATT_MAX_ATTR_LEN - offset;
911 
912         p_clcb->counter += len;
913 
914         memcpy(p_clcb->p_attr_buf + offset, p, len);
915 
916         /* full packet for read or read blob rsp */
917         bool packet_is_full;
918         if (tcb.payload_size == p_clcb->read_req_current_mtu) {
919           packet_is_full = (len == (tcb.payload_size - 1));
920         } else {
921           packet_is_full = (len == (p_clcb->read_req_current_mtu - 1) ||
922                             len == (tcb.payload_size - 1));
923           p_clcb->read_req_current_mtu = tcb.payload_size;
924         }
925 
926         /* send next request if needed  */
927         if (packet_is_full && (len + offset < GATT_MAX_ATTR_LEN)) {
928           VLOG(1) << StringPrintf(
929               "full pkt issue read blob for remianing bytes old offset=%d "
930               "len=%d new offset=%d",
931               offset, len, p_clcb->counter);
932           gatt_act_read(p_clcb, p_clcb->counter);
933         } else /* end of request, send callback */
934         {
935           gatt_end_operation(p_clcb, GATT_SUCCESS, (void*)p_clcb->p_attr_buf);
936         }
937       } else /* exception, should not happen */
938       {
939         LOG(ERROR) << "attr offset = " << +offset
940                    << " p_attr_buf = " << p_clcb->p_attr_buf;
941         gatt_end_operation(p_clcb, GATT_NO_RESOURCES,
942                            (void*)p_clcb->p_attr_buf);
943       }
944     }
945   } else {
946     if (p_clcb->operation == GATTC_OPTYPE_DISCOVERY &&
947         p_clcb->op_subtype == GATT_DISC_INC_SRVC &&
948         p_clcb->read_uuid128.wait_for_read_rsp) {
949       p_clcb->s_handle = p_clcb->read_uuid128.next_disc_start_hdl;
950       p_clcb->read_uuid128.wait_for_read_rsp = false;
951       if (len == Uuid::kNumBytes128) {
952         p_clcb->read_uuid128.result.value.incl_service.service_type =
953             bluetooth::Uuid::From128BitLE(p);
954         if (p_clcb->p_reg->app_cb.p_disc_res_cb)
955           (*p_clcb->p_reg->app_cb.p_disc_res_cb)(p_clcb->conn_id,
956                                                  p_clcb->op_subtype,
957                                                  &p_clcb->read_uuid128.result);
958         gatt_act_discovery(p_clcb);
959       } else {
960         gatt_end_operation(p_clcb, GATT_INVALID_PDU, (void*)p);
961       }
962     }
963   }
964 }
965 
966 /*******************************************************************************
967  *
968  * Function         gatt_process_handle_rsp
969  *
970  * Description      This function is called to handle the write response
971  *
972  *
973  * Returns          void
974  *
975  ******************************************************************************/
gatt_process_handle_rsp(tGATT_CLCB * p_clcb)976 void gatt_process_handle_rsp(tGATT_CLCB* p_clcb) {
977   gatt_end_operation(p_clcb, GATT_SUCCESS, NULL);
978 }
979 /*******************************************************************************
980  *
981  * Function         gatt_process_mtu_rsp
982  *
983  * Description      Process the configure MTU response.
984  *
985  *
986  * Returns          void
987  *
988  ******************************************************************************/
gatt_process_mtu_rsp(tGATT_TCB & tcb,tGATT_CLCB * p_clcb,uint16_t len,uint8_t * p_data)989 void gatt_process_mtu_rsp(tGATT_TCB& tcb, tGATT_CLCB* p_clcb, uint16_t len,
990                           uint8_t* p_data) {
991   uint16_t mtu;
992   tGATT_STATUS status = GATT_SUCCESS;
993 
994   if (len < GATT_MTU_RSP_MIN_LEN) {
995     LOG(ERROR) << "invalid MTU response PDU received, discard.";
996     status = GATT_INVALID_PDU;
997   } else {
998     STREAM_TO_UINT16(mtu, p_data);
999 
1000     if (mtu < tcb.payload_size && mtu >= GATT_DEF_BLE_MTU_SIZE)
1001       tcb.payload_size = mtu;
1002   }
1003 
1004   L2CA_SetLeFixedChannelTxDataLength(tcb.peer_bda, L2CAP_ATT_CID,
1005                                      tcb.payload_size);
1006   gatt_end_operation(p_clcb, status, NULL);
1007 }
1008 /*******************************************************************************
1009  *
1010  * Function         gatt_cmd_to_rsp_code
1011  *
1012  * Description      Convert an ATT command op code into the corresponding
1013  *                  response code assume no error occurs.
1014  *
1015  * Returns          response code.
1016  *
1017  ******************************************************************************/
gatt_cmd_to_rsp_code(uint8_t cmd_code)1018 uint8_t gatt_cmd_to_rsp_code(uint8_t cmd_code) {
1019   uint8_t rsp_code = 0;
1020 
1021   if (cmd_code > 1 && cmd_code != GATT_CMD_WRITE) {
1022     rsp_code = cmd_code + 1;
1023   }
1024   return rsp_code;
1025 }
1026 
1027 /** Find next command in queue and sent to server */
gatt_cl_send_next_cmd_inq(tGATT_TCB & tcb)1028 bool gatt_cl_send_next_cmd_inq(tGATT_TCB& tcb) {
1029   while (!tcb.cl_cmd_q.empty()) {
1030     tGATT_CMD_Q& cmd = tcb.cl_cmd_q.front();
1031     if (!cmd.to_send || cmd.p_cmd == NULL) return false;
1032 
1033     tGATT_STATUS att_ret = attp_send_msg_to_l2cap(tcb, cmd.p_cmd);
1034     if (att_ret != GATT_SUCCESS && att_ret != GATT_CONGESTED) {
1035       LOG(ERROR) << __func__ << ": L2CAP sent error";
1036       tcb.cl_cmd_q.pop();
1037       continue;
1038     }
1039 
1040     cmd.to_send = false;
1041     cmd.p_cmd = NULL;
1042 
1043     if (cmd.op_code == GATT_CMD_WRITE || cmd.op_code == GATT_SIGN_CMD_WRITE) {
1044       /* dequeue the request if is write command or sign write */
1045       uint8_t rsp_code;
1046       tGATT_CLCB* p_clcb = gatt_cmd_dequeue(tcb, &rsp_code);
1047 
1048       /* send command complete callback here */
1049       gatt_end_operation(p_clcb, att_ret, NULL);
1050 
1051       /* if no ack needed, keep sending */
1052       if (att_ret == GATT_SUCCESS) continue;
1053 
1054       return true;
1055     }
1056 
1057     gatt_start_rsp_timer(cmd.p_clcb);
1058     return true;
1059   }
1060 
1061   return false;
1062 }
1063 
1064 /** This function is called to handle the server response to client */
gatt_client_handle_server_rsp(tGATT_TCB & tcb,uint8_t op_code,uint16_t len,uint8_t * p_data)1065 void gatt_client_handle_server_rsp(tGATT_TCB& tcb, uint8_t op_code,
1066                                    uint16_t len, uint8_t* p_data) {
1067   if (op_code == GATT_HANDLE_VALUE_IND || op_code == GATT_HANDLE_VALUE_NOTIF) {
1068     if (len >= tcb.payload_size) {
1069       LOG(ERROR) << StringPrintf(
1070           "%s: invalid indicate pkt size: %d, PDU size: %d", __func__, len + 1,
1071           tcb.payload_size);
1072       return;
1073     }
1074 
1075     gatt_process_notification(tcb, op_code, len, p_data);
1076     return;
1077   }
1078 
1079   uint8_t cmd_code = 0;
1080   tGATT_CLCB* p_clcb = gatt_cmd_dequeue(tcb, &cmd_code);
1081   uint8_t rsp_code = gatt_cmd_to_rsp_code(cmd_code);
1082   if (!p_clcb || (rsp_code != op_code && op_code != GATT_RSP_ERROR)) {
1083     LOG(WARNING) << StringPrintf(
1084         "ATT - Ignore wrong response. Receives (%02x) Request(%02x) Ignored",
1085         op_code, rsp_code);
1086     return;
1087   }
1088 
1089   if (!p_clcb->in_use) {
1090     LOG(WARNING) << "ATT - clcb already not in use, ignoring response";
1091     gatt_cl_send_next_cmd_inq(tcb);
1092     return;
1093   }
1094 
1095   alarm_cancel(p_clcb->gatt_rsp_timer_ent);
1096   p_clcb->retry_count = 0;
1097 
1098   /* the size of the message may not be bigger than the local max PDU size*/
1099   /* The message has to be smaller than the agreed MTU, len does not count
1100    * op_code */
1101   if (len >= tcb.payload_size) {
1102     LOG(ERROR) << StringPrintf(
1103         "%s: invalid response pkt size: %d, PDU size: %d", __func__, len + 1,
1104         tcb.payload_size);
1105     gatt_end_operation(p_clcb, GATT_ERROR, NULL);
1106   } else {
1107     switch (op_code) {
1108       case GATT_RSP_ERROR:
1109         gatt_process_error_rsp(tcb, p_clcb, op_code, len, p_data);
1110         break;
1111 
1112       case GATT_RSP_MTU: /* 2 bytes mtu */
1113         gatt_process_mtu_rsp(tcb, p_clcb, len, p_data);
1114         break;
1115 
1116       case GATT_RSP_FIND_INFO:
1117         gatt_process_read_info_rsp(tcb, p_clcb, op_code, len, p_data);
1118         break;
1119 
1120       case GATT_RSP_READ_BY_TYPE:
1121       case GATT_RSP_READ_BY_GRP_TYPE:
1122         gatt_process_read_by_type_rsp(tcb, p_clcb, op_code, len, p_data);
1123         break;
1124 
1125       case GATT_RSP_READ:
1126       case GATT_RSP_READ_BLOB:
1127       case GATT_RSP_READ_MULTI:
1128         gatt_process_read_rsp(tcb, p_clcb, op_code, len, p_data);
1129         break;
1130 
1131       case GATT_RSP_FIND_TYPE_VALUE: /* disc service with UUID */
1132         gatt_process_find_type_value_rsp(tcb, p_clcb, len, p_data);
1133         break;
1134 
1135       case GATT_RSP_WRITE:
1136         gatt_process_handle_rsp(p_clcb);
1137         break;
1138 
1139       case GATT_RSP_PREPARE_WRITE:
1140         gatt_process_prep_write_rsp(tcb, p_clcb, op_code, len, p_data);
1141         break;
1142 
1143       case GATT_RSP_EXEC_WRITE:
1144         gatt_end_operation(p_clcb, p_clcb->status, NULL);
1145         break;
1146 
1147       default:
1148         LOG(ERROR) << __func__ << ": Unknown opcode = " << std::hex << op_code;
1149         break;
1150     }
1151   }
1152 
1153   gatt_cl_send_next_cmd_inq(tcb);
1154 }
1155