15738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************
25738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
35b790feeeb211c42bf78ca3ae9c26aa30e516765Jakub Pawlowski *  Copyright 2008-2014 Broadcom Corporation
45738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
55738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  Licensed under the Apache License, Version 2.0 (the "License");
65738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  you may not use this file except in compliance with the License.
75738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  You may obtain a copy of the License at:
85738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
95738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  http://www.apache.org/licenses/LICENSE-2.0
105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  Unless required by applicable law or agreed to in writing, software
125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  distributed under the License is distributed on an "AS IS" BASIS,
135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  See the License for the specific language governing permissions and
155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  limitations under the License.
165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ******************************************************************************/
185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************
205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  this file contains ATT protocol functions
225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ******************************************************************************/
245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "bt_target.h"
265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "gatt_int.h"
285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "l2c_api.h"
295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
30911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson#define GATT_HDR_FIND_TYPE_VALUE_LEN 21
31911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson#define GATT_OP_CODE_SIZE 1
32911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson#define GATT_START_END_HANDLE_SIZE 4
337da98621a4dfa8196b8d20e8955ad508f540e5d9Subramanian Srinivasan
34d8be0e590aa1efe1c33a8acfea0d7e14fd1a8030Jakub Pawlowskiusing base::StringPrintf;
35819e2ecb84a22d6e03ec9ed67b3260c0dd7e8abaJakub Pawlowskiusing bluetooth::Uuid;
365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/**********************************************************************
37ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *   ATT protocl message building utility                              *
38ee96a3c60fca590d38025925c072d264e06493c4Myles Watson **********************************************************************/
395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
40ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
41ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         attp_build_mtu_exec_cmd
42ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
43ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description      Build a exchange MTU request
44ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
45ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns          None.
46ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
47ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
48911d1ae03efec2d54c3b1b605589d790d1745488Myles WatsonBT_HDR* attp_build_mtu_cmd(uint8_t op_code, uint16_t rx_mtu) {
49911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint8_t* p;
50911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  BT_HDR* p_buf =
51911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      (BT_HDR*)osi_malloc(sizeof(BT_HDR) + GATT_HDR_SIZE + L2CAP_MIN_OFFSET);
525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
53911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p = (uint8_t*)(p_buf + 1) + L2CAP_MIN_OFFSET;
54911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  UINT8_TO_STREAM(p, op_code);
55911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  UINT16_TO_STREAM(p, rx_mtu);
565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
57911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_buf->offset = L2CAP_MIN_OFFSET;
58911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_buf->len = GATT_HDR_SIZE; /* opcode + 2 bytes mtu */
595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
60911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  return p_buf;
615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
63ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
64ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         attp_build_exec_write_cmd
65ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
66ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description      Build a execute write request or response.
67ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
68ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns          None.
69ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
70ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
71911d1ae03efec2d54c3b1b605589d790d1745488Myles WatsonBT_HDR* attp_build_exec_write_cmd(uint8_t op_code, uint8_t flag) {
72911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  BT_HDR* p_buf = (BT_HDR*)osi_malloc(GATT_DATA_BUF_SIZE);
73911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint8_t* p;
745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
75911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p = (uint8_t*)(p_buf + 1) + L2CAP_MIN_OFFSET;
765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
77911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_buf->offset = L2CAP_MIN_OFFSET;
78911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_buf->len = GATT_OP_CODE_SIZE;
795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
80911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  UINT8_TO_STREAM(p, op_code);
815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
82911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (op_code == GATT_REQ_EXEC_WRITE) {
83911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    flag &= GATT_PREP_WRITE_EXEC;
84911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    UINT8_TO_STREAM(p, flag);
85911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p_buf->len += 1;
86911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
88911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  return p_buf;
895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
92ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
93ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         attp_build_err_cmd
94ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
95ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description      Build a exchange MTU request
96ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
97ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns          None.
98ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
99ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
100911d1ae03efec2d54c3b1b605589d790d1745488Myles WatsonBT_HDR* attp_build_err_cmd(uint8_t cmd_code, uint16_t err_handle,
101911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                           uint8_t reason) {
102911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint8_t* p;
103911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  BT_HDR* p_buf = (BT_HDR*)osi_malloc(sizeof(BT_HDR) + L2CAP_MIN_OFFSET + 5);
104911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
105911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p = (uint8_t*)(p_buf + 1) + L2CAP_MIN_OFFSET;
106911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  UINT8_TO_STREAM(p, GATT_RSP_ERROR);
107911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  UINT8_TO_STREAM(p, cmd_code);
108911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  UINT16_TO_STREAM(p, err_handle);
109911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  UINT8_TO_STREAM(p, reason);
110911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
111911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_buf->offset = L2CAP_MIN_OFFSET;
112911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* GATT_HDR_SIZE (1B ERR_RSP op code+ 2B handle) + 1B cmd_op_code  + 1B status
113911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson   */
114911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_buf->len = GATT_HDR_SIZE + 1 + 1;
115911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
116911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  return p_buf;
1175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
1185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
119ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
120ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         attp_build_browse_cmd
121ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
122ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description      Build a read information request or read by type request
123ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
124ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns          None.
125ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
126ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
127911d1ae03efec2d54c3b1b605589d790d1745488Myles WatsonBT_HDR* attp_build_browse_cmd(uint8_t op_code, uint16_t s_hdl, uint16_t e_hdl,
128819e2ecb84a22d6e03ec9ed67b3260c0dd7e8abaJakub Pawlowski                              const bluetooth::Uuid& uuid) {
129911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  const size_t payload_size =
130819e2ecb84a22d6e03ec9ed67b3260c0dd7e8abaJakub Pawlowski      (GATT_OP_CODE_SIZE) + (GATT_START_END_HANDLE_SIZE) + (Uuid::kNumBytes128);
131911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  BT_HDR* p_buf =
132911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      (BT_HDR*)osi_malloc(sizeof(BT_HDR) + payload_size + L2CAP_MIN_OFFSET);
133911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
134911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint8_t* p = (uint8_t*)(p_buf + 1) + L2CAP_MIN_OFFSET;
135911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* Describe the built message location and size */
136911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_buf->offset = L2CAP_MIN_OFFSET;
137911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_buf->len = GATT_OP_CODE_SIZE + 4;
138911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
139911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  UINT8_TO_STREAM(p, op_code);
140911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  UINT16_TO_STREAM(p, s_hdl);
141911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  UINT16_TO_STREAM(p, e_hdl);
142911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_buf->len += gatt_build_uuid_to_stream(&p, uuid);
143911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
144911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  return p_buf;
1455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
146717a4a9f3a044f264ec2482c2d1806ec3093707aPavlin Radoslavov
1475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
148ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
149ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         attp_build_read_handles_cmd
150ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
151ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description      Build a read by type and value request.
152ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
153ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns          pointer to the command buffer.
154ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
155ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
156911d1ae03efec2d54c3b1b605589d790d1745488Myles WatsonBT_HDR* attp_build_read_by_type_value_cmd(uint16_t payload_size,
157911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                                          tGATT_FIND_TYPE_VALUE* p_value_type) {
158911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint8_t* p;
159911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint16_t len = p_value_type->value_len;
160911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  BT_HDR* p_buf =
161911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      (BT_HDR*)osi_malloc(sizeof(BT_HDR) + payload_size + L2CAP_MIN_OFFSET);
1625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
163911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p = (uint8_t*)(p_buf + 1) + L2CAP_MIN_OFFSET;
164911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_buf->offset = L2CAP_MIN_OFFSET;
165911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_buf->len = 5; /* opcode + s_handle + e_handle */
1665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
167911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  UINT8_TO_STREAM(p, GATT_REQ_FIND_TYPE_VALUE);
168911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  UINT16_TO_STREAM(p, p_value_type->s_handle);
169911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  UINT16_TO_STREAM(p, p_value_type->e_handle);
1705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
171911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_buf->len += gatt_build_uuid_to_stream(&p, p_value_type->uuid);
1725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
173911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (p_value_type->value_len + p_buf->len > payload_size)
174911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    len = payload_size - p_buf->len;
1755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
176911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  memcpy(p, p_value_type->value, len);
177911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_buf->len += len;
1785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
179911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  return p_buf;
1805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
181717a4a9f3a044f264ec2482c2d1806ec3093707aPavlin Radoslavov
1825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
183ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
184ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         attp_build_read_multi_cmd
185ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
186ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description      Build a read multiple request
187ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
188ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns          None.
189ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
190ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
191911d1ae03efec2d54c3b1b605589d790d1745488Myles WatsonBT_HDR* attp_build_read_multi_cmd(uint16_t payload_size, uint16_t num_handle,
192911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                                  uint16_t* p_handle) {
193911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint8_t *p, i = 0;
194911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  BT_HDR* p_buf = (BT_HDR*)osi_malloc(sizeof(BT_HDR) + num_handle * 2 + 1 +
195911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                                      L2CAP_MIN_OFFSET);
1965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
197911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p = (uint8_t*)(p_buf + 1) + L2CAP_MIN_OFFSET;
198911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_buf->offset = L2CAP_MIN_OFFSET;
199911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_buf->len = 1;
2005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
201911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  UINT8_TO_STREAM(p, GATT_REQ_READ_MULTI);
2025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
203911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  for (i = 0; i < num_handle && p_buf->len + 2 <= payload_size; i++) {
204911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    UINT16_TO_STREAM(p, *(p_handle + i));
205911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p_buf->len += 2;
206911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
2075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
208911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  return p_buf;
2095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
2105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
211ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
212ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         attp_build_handle_cmd
213ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
214ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description      Build a read /read blob request
215ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
216ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns          None.
217ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
218ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
219911d1ae03efec2d54c3b1b605589d790d1745488Myles WatsonBT_HDR* attp_build_handle_cmd(uint8_t op_code, uint16_t handle,
220911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                              uint16_t offset) {
221911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint8_t* p;
222911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  BT_HDR* p_buf = (BT_HDR*)osi_malloc(sizeof(BT_HDR) + 5 + L2CAP_MIN_OFFSET);
2235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
224911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p = (uint8_t*)(p_buf + 1) + L2CAP_MIN_OFFSET;
225911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_buf->offset = L2CAP_MIN_OFFSET;
2265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
227911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  UINT8_TO_STREAM(p, op_code);
228911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_buf->len = 1;
2295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
230911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  UINT16_TO_STREAM(p, handle);
231911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_buf->len += 2;
2325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
233911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (op_code == GATT_REQ_READ_BLOB) {
234911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    UINT16_TO_STREAM(p, offset);
235911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p_buf->len += 2;
236911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
2375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
238911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  return p_buf;
2395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
240717a4a9f3a044f264ec2482c2d1806ec3093707aPavlin Radoslavov
2415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
242ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
243ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         attp_build_opcode_cmd
244ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
245ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description      Build a  request/response with opcode only.
246ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
247ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns          None.
248ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
249ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
250911d1ae03efec2d54c3b1b605589d790d1745488Myles WatsonBT_HDR* attp_build_opcode_cmd(uint8_t op_code) {
251911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint8_t* p;
252911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  BT_HDR* p_buf = (BT_HDR*)osi_malloc(sizeof(BT_HDR) + 1 + L2CAP_MIN_OFFSET);
2535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
254911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p = (uint8_t*)(p_buf + 1) + L2CAP_MIN_OFFSET;
255911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_buf->offset = L2CAP_MIN_OFFSET;
2565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
257911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  UINT8_TO_STREAM(p, op_code);
258911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_buf->len = 1;
2595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
260911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  return p_buf;
2615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
262717a4a9f3a044f264ec2482c2d1806ec3093707aPavlin Radoslavov
2635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
264ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
265ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         attp_build_value_cmd
266ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
267ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description      Build a attribute value request
268ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
269ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns          None.
270ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
271ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
272911d1ae03efec2d54c3b1b605589d790d1745488Myles WatsonBT_HDR* attp_build_value_cmd(uint16_t payload_size, uint8_t op_code,
273911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                             uint16_t handle, uint16_t offset, uint16_t len,
274911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                             uint8_t* p_data) {
275911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint8_t *p, *pp, pair_len, *p_pair_len;
276911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  BT_HDR* p_buf =
277911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      (BT_HDR*)osi_malloc(sizeof(BT_HDR) + payload_size + L2CAP_MIN_OFFSET);
278911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
279911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p = pp = (uint8_t*)(p_buf + 1) + L2CAP_MIN_OFFSET;
280911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  UINT8_TO_STREAM(p, op_code);
281911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_buf->offset = L2CAP_MIN_OFFSET;
282911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_buf->len = 1;
283911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
284911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (op_code == GATT_RSP_READ_BY_TYPE) {
285911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p_pair_len = p;
286911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    pair_len = len + 2;
287911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    UINT8_TO_STREAM(p, pair_len);
288911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p_buf->len += 1;
289911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
290911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (op_code != GATT_RSP_READ_BLOB && op_code != GATT_RSP_READ) {
291911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    UINT16_TO_STREAM(p, handle);
292911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p_buf->len += 2;
293911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
2945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
295911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (op_code == GATT_REQ_PREPARE_WRITE || op_code == GATT_RSP_PREPARE_WRITE) {
296911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    UINT16_TO_STREAM(p, offset);
297911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p_buf->len += 2;
298911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
299717a4a9f3a044f264ec2482c2d1806ec3093707aPavlin Radoslavov
300911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (len > 0 && p_data != NULL) {
301911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    /* ensure data not exceed MTU size */
302911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if (payload_size - p_buf->len < len) {
303911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      len = payload_size - p_buf->len;
304911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      /* update handle value pair length */
305911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      if (op_code == GATT_RSP_READ_BY_TYPE) *p_pair_len = (len + 2);
306717a4a9f3a044f264ec2482c2d1806ec3093707aPavlin Radoslavov
307d8be0e590aa1efe1c33a8acfea0d7e14fd1a8030Jakub Pawlowski      LOG(WARNING) << StringPrintf(
308d8be0e590aa1efe1c33a8acfea0d7e14fd1a8030Jakub Pawlowski          "attribute value too long, to be truncated to %d", len);
3095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
310717a4a9f3a044f264ec2482c2d1806ec3093707aPavlin Radoslavov
311911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    ARRAY_TO_STREAM(p, p_data, len);
312911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p_buf->len += len;
313911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
314911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
315911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  return p_buf;
3165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
3175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
319ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
320ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         attp_send_msg_to_l2cap
321ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
322ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description      Send message to L2CAP.
323ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
324ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
325f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub PawlowskitGATT_STATUS attp_send_msg_to_l2cap(tGATT_TCB& tcb, BT_HDR* p_toL2CAP) {
326911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint16_t l2cap_ret;
327911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
328f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub Pawlowski  if (tcb.att_lcid == L2CAP_ATT_CID)
329f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub Pawlowski    l2cap_ret = L2CA_SendFixedChnlData(L2CAP_ATT_CID, tcb.peer_bda, p_toL2CAP);
330911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  else
331f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub Pawlowski    l2cap_ret = (uint16_t)L2CA_DataWrite(tcb.att_lcid, p_toL2CAP);
332911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
333911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (l2cap_ret == L2CAP_DW_FAILED) {
334a6864818430ae5931452d153c3276794c05156d3Nitin Shivpure    LOG(ERROR) << __func__ << ": failed to write data to L2CAP";
335911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    return GATT_INTERNAL_ERROR;
336911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  } else if (l2cap_ret == L2CAP_DW_CONGESTED) {
337d8be0e590aa1efe1c33a8acfea0d7e14fd1a8030Jakub Pawlowski    VLOG(1) << StringPrintf("ATT congested, message accepted");
338911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    return GATT_CONGESTED;
339911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
340911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  return GATT_SUCCESS;
3415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
3425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
343b4e47991544d8342b040bc01c1c81be1a383799fJakub Pawlowski/** Build ATT Server PDUs */
344f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub PawlowskiBT_HDR* attp_build_sr_msg(tGATT_TCB& tcb, uint8_t op_code,
345911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                          tGATT_SR_MSG* p_msg) {
346911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint16_t offset = 0;
3475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
348911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  switch (op_code) {
3495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case GATT_RSP_READ_BLOB:
3505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case GATT_RSP_PREPARE_WRITE:
351d8be0e590aa1efe1c33a8acfea0d7e14fd1a8030Jakub Pawlowski      VLOG(1) << StringPrintf(
352911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          "ATT_RSP_READ_BLOB/GATT_RSP_PREPARE_WRITE: len = %d offset = %d",
353911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          p_msg->attr_value.len, p_msg->attr_value.offset);
354911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      offset = p_msg->attr_value.offset;
355911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    /* Coverity: [FALSE-POSITIVE error] intended fall through */
356911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    /* Missing break statement between cases in switch statement */
357911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    /* fall through */
3585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case GATT_RSP_READ_BY_TYPE:
3595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case GATT_RSP_READ:
3605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case GATT_HANDLE_VALUE_NOTIF:
3615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case GATT_HANDLE_VALUE_IND:
362b4e47991544d8342b040bc01c1c81be1a383799fJakub Pawlowski      return attp_build_value_cmd(
363f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub Pawlowski          tcb.payload_size, op_code, p_msg->attr_value.handle, offset,
364911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          p_msg->attr_value.len, p_msg->attr_value.value);
3655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case GATT_RSP_WRITE:
367b4e47991544d8342b040bc01c1c81be1a383799fJakub Pawlowski      return attp_build_opcode_cmd(op_code);
3685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case GATT_RSP_ERROR:
370b4e47991544d8342b040bc01c1c81be1a383799fJakub Pawlowski      return attp_build_err_cmd(p_msg->error.cmd_code, p_msg->error.handle,
371b4e47991544d8342b040bc01c1c81be1a383799fJakub Pawlowski                                p_msg->error.reason);
3725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case GATT_RSP_EXEC_WRITE:
374b4e47991544d8342b040bc01c1c81be1a383799fJakub Pawlowski      return attp_build_exec_write_cmd(op_code, 0);
3755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case GATT_RSP_MTU:
377b4e47991544d8342b040bc01c1c81be1a383799fJakub Pawlowski      return attp_build_mtu_cmd(op_code, p_msg->mtu);
3785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    default:
380b4e47991544d8342b040bc01c1c81be1a383799fJakub Pawlowski      LOG(FATAL) << "attp_build_sr_msg: unknown op code = " << +op_code;
381b4e47991544d8342b040bc01c1c81be1a383799fJakub Pawlowski      return nullptr;
382911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
3835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
3845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
386ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
387ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         attp_send_sr_msg
388ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
3899ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson * Description      This function sends the server response or indication
3909ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson *                  message to client.
391ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
392ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Parameter        p_tcb: pointer to the connecton control block.
393ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  p_msg: pointer to message parameters structure.
394ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
395ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns          GATT_SUCCESS if sucessfully sent; otherwise error code.
396ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
397ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
398ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
399f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub PawlowskitGATT_STATUS attp_send_sr_msg(tGATT_TCB& tcb, BT_HDR* p_msg) {
400f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub Pawlowski  if (p_msg == NULL) return GATT_NO_RESOURCES;
401911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
402f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub Pawlowski  p_msg->offset = L2CAP_MIN_OFFSET;
403f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub Pawlowski  return attp_send_msg_to_l2cap(tcb, p_msg);
4045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
4055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
407ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
408ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         attp_cl_send_cmd
409ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
410ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description      Send a ATT command or enqueue it.
411ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
412ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns          GATT_SUCCESS if command sent
413ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  GATT_CONGESTED if command sent but channel congested
414ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  GATT_CMD_STARTED if command queue up in GATT
415ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  GATT_ERROR if command sending failure
416ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
417ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
418e4f42abab339b3329aec07502199e11d3d8b3d80Jakub PawlowskitGATT_STATUS attp_cl_send_cmd(tGATT_TCB& tcb, tGATT_CLCB* p_clcb,
419911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                              uint8_t cmd_code, BT_HDR* p_cmd) {
420f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub Pawlowski  cmd_code &= ~GATT_AUTH_SIGN_MASK;
421f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub Pawlowski
422d1a9313471ed5290ca560305978c3107020272c2Jakub Pawlowski  if (!tcb.cl_cmd_q.empty() && cmd_code != GATT_HANDLE_VALUE_CONF) {
423e4f42abab339b3329aec07502199e11d3d8b3d80Jakub Pawlowski    gatt_cmd_enq(tcb, p_clcb, true, cmd_code, p_cmd);
424f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub Pawlowski    return GATT_CMD_STARTED;
425f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub Pawlowski  }
4265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
427f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub Pawlowski  /* no pending request or value confirmation */
428f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub Pawlowski  tGATT_STATUS att_ret = attp_send_msg_to_l2cap(tcb, p_cmd);
429f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub Pawlowski  if (att_ret != GATT_CONGESTED && att_ret != GATT_SUCCESS) {
430f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub Pawlowski    return GATT_INTERNAL_ERROR;
431f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub Pawlowski  }
432f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub Pawlowski
433f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub Pawlowski  /* do not enq cmd if handle value confirmation or set request */
434d1a9313471ed5290ca560305978c3107020272c2Jakub Pawlowski  if (cmd_code == GATT_HANDLE_VALUE_CONF || cmd_code == GATT_CMD_WRITE) {
435d1a9313471ed5290ca560305978c3107020272c2Jakub Pawlowski    return att_ret;
436f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub Pawlowski  }
437d1a9313471ed5290ca560305978c3107020272c2Jakub Pawlowski
438e4f42abab339b3329aec07502199e11d3d8b3d80Jakub Pawlowski  gatt_start_rsp_timer(p_clcb);
439e4f42abab339b3329aec07502199e11d3d8b3d80Jakub Pawlowski  gatt_cmd_enq(tcb, p_clcb, false, cmd_code, NULL);
440911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  return att_ret;
4415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
442f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub Pawlowski
4435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
444ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
445ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         attp_send_cl_msg
446ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
4479ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson * Description      This function sends the client request or confirmation
4489ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson *                  message to server.
449ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
450ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Parameter        p_tcb: pointer to the connectino control block.
451e4f42abab339b3329aec07502199e11d3d8b3d80Jakub Pawlowski *                  p_clcb: clcb
452ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  op_code: message op code.
453ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  p_msg: pointer to message parameters structure.
454ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
455ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns          GATT_SUCCESS if sucessfully sent; otherwise error code.
456ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
457ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
458ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
459e4f42abab339b3329aec07502199e11d3d8b3d80Jakub PawlowskitGATT_STATUS attp_send_cl_msg(tGATT_TCB& tcb, tGATT_CLCB* p_clcb,
460911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                              uint8_t op_code, tGATT_CL_MSG* p_msg) {
461911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  BT_HDR* p_cmd = NULL;
462911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint16_t offset = 0, handle;
463f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub Pawlowski  switch (op_code) {
464f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub Pawlowski    case GATT_REQ_MTU:
465f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub Pawlowski      if (p_msg->mtu > GATT_MAX_MTU_SIZE) return GATT_ILLEGAL_PARAMETER;
466f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub Pawlowski
467f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub Pawlowski      tcb.payload_size = p_msg->mtu;
468f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub Pawlowski      p_cmd = attp_build_mtu_cmd(GATT_REQ_MTU, p_msg->mtu);
469f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub Pawlowski      break;
470911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
471f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub Pawlowski    case GATT_REQ_FIND_INFO:
472f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub Pawlowski    case GATT_REQ_READ_BY_TYPE:
473f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub Pawlowski    case GATT_REQ_READ_BY_GRP_TYPE:
474f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub Pawlowski      if (!GATT_HANDLE_IS_VALID(p_msg->browse.s_handle) ||
475f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub Pawlowski          !GATT_HANDLE_IS_VALID(p_msg->browse.e_handle) ||
476f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub Pawlowski          p_msg->browse.s_handle > p_msg->browse.e_handle)
477f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub Pawlowski        return GATT_ILLEGAL_PARAMETER;
478f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub Pawlowski
479f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub Pawlowski      p_cmd = attp_build_browse_cmd(op_code, p_msg->browse.s_handle,
480911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                                    p_msg->browse.e_handle, p_msg->browse.uuid);
481f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub Pawlowski      break;
482f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub Pawlowski
483f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub Pawlowski    case GATT_REQ_READ_BLOB:
484f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub Pawlowski      offset = p_msg->read_blob.offset;
485f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub Pawlowski    /* fall through */
486f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub Pawlowski    case GATT_REQ_READ:
487f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub Pawlowski      handle =
488f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub Pawlowski          (op_code == GATT_REQ_READ) ? p_msg->handle : p_msg->read_blob.handle;
489f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub Pawlowski      /*  handle checking */
490f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub Pawlowski      if (!GATT_HANDLE_IS_VALID(handle)) return GATT_ILLEGAL_PARAMETER;
491f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub Pawlowski
492f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub Pawlowski      p_cmd = attp_build_handle_cmd(op_code, handle, offset);
493f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub Pawlowski      break;
494f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub Pawlowski
495f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub Pawlowski    case GATT_HANDLE_VALUE_CONF:
496f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub Pawlowski      p_cmd = attp_build_opcode_cmd(op_code);
497f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub Pawlowski      break;
498f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub Pawlowski
499f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub Pawlowski    case GATT_REQ_PREPARE_WRITE:
500f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub Pawlowski      offset = p_msg->attr_value.offset;
501f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub Pawlowski    /* fall through */
502f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub Pawlowski    case GATT_REQ_WRITE:
503f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub Pawlowski    case GATT_CMD_WRITE:
504f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub Pawlowski    case GATT_SIGN_CMD_WRITE:
505f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub Pawlowski      if (!GATT_HANDLE_IS_VALID(p_msg->attr_value.handle))
506f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub Pawlowski        return GATT_ILLEGAL_PARAMETER;
5075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
508f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub Pawlowski      p_cmd = attp_build_value_cmd(
509f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub Pawlowski          tcb.payload_size, op_code, p_msg->attr_value.handle, offset,
510f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub Pawlowski          p_msg->attr_value.len, p_msg->attr_value.value);
511f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub Pawlowski      break;
512911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
513f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub Pawlowski    case GATT_REQ_EXEC_WRITE:
514f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub Pawlowski      p_cmd = attp_build_exec_write_cmd(op_code, p_msg->exec_write);
515f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub Pawlowski      break;
516f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub Pawlowski
517f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub Pawlowski    case GATT_REQ_FIND_TYPE_VALUE:
518f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub Pawlowski      p_cmd = attp_build_read_by_type_value_cmd(tcb.payload_size,
519f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub Pawlowski                                                &p_msg->find_type_value);
520f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub Pawlowski      break;
521f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub Pawlowski
522f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub Pawlowski    case GATT_REQ_READ_MULTI:
523f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub Pawlowski      p_cmd = attp_build_read_multi_cmd(tcb.payload_size,
524f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub Pawlowski                                        p_msg->read_multi.num_handles,
525f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub Pawlowski                                        p_msg->read_multi.handles);
526f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub Pawlowski      break;
527f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub Pawlowski
528f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub Pawlowski    default:
529f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub Pawlowski      break;
530911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
531911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
532f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub Pawlowski  if (p_cmd == NULL) return GATT_NO_RESOURCES;
533f4c0292c63085cd4d0f5c001974b6503aeaf8ed3Jakub Pawlowski
534e4f42abab339b3329aec07502199e11d3d8b3d80Jakub Pawlowski  return attp_cl_send_cmd(tcb, p_clcb, op_code, p_cmd);
5355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
536