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