16ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach/****************************************************************************** 26ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach * 36ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach * Copyright (C) 2008-2012 Broadcom Corporation 46ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach * 56ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach * Licensed under the Apache License, Version 2.0 (the "License"); 66ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach * you may not use this file except in compliance with the License. 76ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach * You may obtain a copy of the License at: 86ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach * 96ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach * http://www.apache.org/licenses/LICENSE-2.0 106ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach * 116ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach * Unless required by applicable law or agreed to in writing, software 126ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach * distributed under the License is distributed on an "AS IS" BASIS, 136ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 146ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach * See the License for the specific language governing permissions and 156ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach * limitations under the License. 166ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach * 176ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach ******************************************************************************/ 186ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach 196ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach/****************************************************************************** 206ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach * 216ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach * this file contains the GATT server functions 226ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach * 236ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach ******************************************************************************/ 24e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 25e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach#include "bt_target.h" 26e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 27e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach#if BLE_INCLUDED == TRUE 286ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach#include <string.h> 29e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach#include "gatt_int.h" 30e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach#include "l2c_api.h" 31e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 32e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 33e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach/******************************************************************************* 34e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 35e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Function gatt_sr_enqueue_cmd 36e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 376ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach** Description This function enqueue the request from client which needs a 38e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** application response, and update the transaction ID. 39e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 40e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Returns void 41e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 42e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach*******************************************************************************/ 43e448862a47c08eb23185aaed574b39264f5005fcAndre EisenbachUINT32 gatt_sr_enqueue_cmd (tGATT_TCB *p_tcb, UINT8 op_code, UINT16 handle) 44e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach{ 45e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach tGATT_SR_CMD *p_cmd = &p_tcb->sr_cmd; 46e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach UINT32 trans_id = 0; 47e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 486ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach if ( (p_cmd->op_code == 0) || 49e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach (op_code == GATT_HANDLE_VALUE_CONF)) /* no pending request */ 50e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 516ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach if (op_code == GATT_CMD_WRITE || 526ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach op_code == GATT_SIGN_CMD_WRITE || 53e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach op_code == GATT_REQ_MTU || 54e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach op_code == GATT_HANDLE_VALUE_CONF) 55e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 56e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach trans_id = ++p_tcb->trans_id; 57e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 58e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach else 59e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 606ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach p_cmd->trans_id = ++p_tcb->trans_id; 61e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_cmd->op_code = op_code; 62e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_cmd->handle = handle; 63e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_cmd->status = GATT_NOT_FOUND; 64e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_tcb->trans_id %= GATT_TRANS_ID_MAX; 65e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach trans_id = p_cmd->trans_id; 66e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 67e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 68e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 69e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return trans_id; 70e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach} 71e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 72e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach/******************************************************************************* 73e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 74e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Function gatt_sr_cmd_empty 75e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 76e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Description This function check the server command queue is empty or not. 77e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 78e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Returns TRUE if empty, FALSE if there is pending command. 79e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 80e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach*******************************************************************************/ 81e448862a47c08eb23185aaed574b39264f5005fcAndre EisenbachBOOLEAN gatt_sr_cmd_empty (tGATT_TCB *p_tcb) 82e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach{ 83e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return(p_tcb->sr_cmd.op_code == 0); 84e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach} 85e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 86e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach/******************************************************************************* 87e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 88e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Function gatt_dequeue_sr_cmd 89e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 90e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Description This function dequeue the request from command queue. 91e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 92e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Returns void 93e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 94e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach*******************************************************************************/ 95e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbachvoid gatt_dequeue_sr_cmd (tGATT_TCB *p_tcb) 96e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach{ 97e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* Double check in case any buffers are queued */ 98e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach GATT_TRACE_DEBUG0("gatt_dequeue_sr_cmd" ); 99e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (p_tcb->sr_cmd.p_rsp_msg) 100e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 101e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach GATT_TRACE_ERROR1("free p_tcb->sr_cmd.p_rsp_msg = %d", p_tcb->sr_cmd.p_rsp_msg); 102e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 103e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach GKI_freebuf (p_tcb->sr_cmd.p_rsp_msg); 104e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 105e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 106e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach while (p_tcb->sr_cmd.multi_rsp_q.p_first) 107e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach GKI_freebuf (GKI_dequeue (&p_tcb->sr_cmd.multi_rsp_q)); 1086ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach memset( &p_tcb->sr_cmd, 0, sizeof(tGATT_SR_CMD)); 109e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach} 110e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 111e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach/******************************************************************************* 112e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 113e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Function process_read_multi_rsp 114e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 115e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Description This function check the read multiple response. 116e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 117e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Returns BOOLEAN if all replies have been received 118e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 119e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach*******************************************************************************/ 120e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbachstatic BOOLEAN process_read_multi_rsp (tGATT_SR_CMD *p_cmd, tGATT_STATUS status, 121e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach tGATTS_RSP *p_msg, UINT16 mtu) 122e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach{ 123e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach tGATTS_RSP *p_rsp; 124e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach UINT16 ii, total_len, len; 125e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach BT_HDR *p_buf = (BT_HDR *)GKI_getbuf((UINT16)sizeof(tGATTS_RSP)); 126e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach UINT8 *p; 127e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach BOOLEAN is_overflow = FALSE; 128e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 129e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach GATT_TRACE_DEBUG2 ("process_read_multi_rsp status=%d mtu=%d", status, mtu); 130e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 131e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (p_buf == NULL) 132e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 133e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_cmd->status = GATT_INSUF_RESOURCE; 134e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return FALSE; 135e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 136e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 137e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* Enqueue the response */ 138e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach memcpy((void *)p_buf, (const void *)p_msg, sizeof(tGATTS_RSP)); 139e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach GKI_enqueue (&p_cmd->multi_rsp_q, p_buf); 140e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 141e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_cmd->status = status; 142e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (status == GATT_SUCCESS) 143e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 1446ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach GATT_TRACE_DEBUG2 ("Multi read count=%d num_hdls=%d", 145e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_cmd->multi_rsp_q.count, p_cmd->multi_req.num_handles); 146e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* Wait till we get all the responses */ 147e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (p_cmd->multi_rsp_q.count == p_cmd->multi_req.num_handles) 148e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 149e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach len = sizeof(BT_HDR) + L2CAP_MIN_OFFSET + mtu; 150e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if ((p_buf = (BT_HDR *)GKI_getbuf(len)) == NULL) 151e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 152e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_cmd->status = GATT_INSUF_RESOURCE; 153e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return(TRUE); 154e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 155e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 156e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach memset(p_buf, 0, len); 157e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_buf->offset = L2CAP_MIN_OFFSET; 158e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p = (UINT8 *)(p_buf + 1) + p_buf->offset; 159e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 160e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* First byte in the response is the opcode */ 161e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach *p++ = GATT_RSP_READ_MULTI; 162e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_buf->len = 1; 163e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 164e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* Now walk through the buffers puting the data into the response in order */ 165e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach for (ii = 0; ii < p_cmd->multi_req.num_handles; ii++) 166e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 167e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (ii==0) 168e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 169e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_rsp = (tGATTS_RSP *)GKI_getfirst (&p_cmd->multi_rsp_q); 170e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 171e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach else 172e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 173e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_rsp = (tGATTS_RSP *)GKI_getnext (p_rsp); 174e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 175e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 176e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (p_rsp != NULL) 177e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 178e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 179e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach total_len = (p_buf->len + p_rsp->attr_value.len); 180e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 181e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (total_len > mtu) 182e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 183e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* just send the partial response for the overflow case */ 184e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach len = p_rsp->attr_value.len - (total_len - mtu); 1856ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach is_overflow = TRUE; 186e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach GATT_TRACE_DEBUG2 ("multi read overflow available len=%d val_len=%d", len, p_rsp->attr_value.len ); 187e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 188e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach else 189e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 190e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach len = p_rsp->attr_value.len; 191e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 192e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 193e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (p_rsp->attr_value.handle == p_cmd->multi_req.handles[ii]) 194e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 195e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach memcpy (p, p_rsp->attr_value.value, len); 196e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (!is_overflow) 197e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p += len; 198e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_buf->len += len; 199e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 200e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach else 201e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 2026ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach p_cmd->status = GATT_NOT_FOUND; 203e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach break; 204e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 205e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 206e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (is_overflow) 207e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach break; 208e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 209e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 210e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach else 211e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 2126ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach p_cmd->status = GATT_NOT_FOUND; 213e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach break; 214e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 215e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 216e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } /* loop through all handles*/ 217e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 218e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 219e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* Sanity check on the buffer length */ 220e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (p_buf->len == 0) 221e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 222e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach GATT_TRACE_ERROR0("process_read_multi_rsp - nothing found!!"); 223e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_cmd->status = GATT_NOT_FOUND; 224e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach GKI_freebuf (p_buf); 225e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach GATT_TRACE_DEBUG0(" GKI_freebuf (p_buf)"); 226e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 227e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach else if (p_cmd->p_rsp_msg != NULL) 228e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 229e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach GKI_freebuf (p_buf); 230e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 231e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach else 232e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 233e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_cmd->p_rsp_msg = p_buf; 234e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 235e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 236e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return(TRUE); 237e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 238e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 239e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach else /* any handle read exception occurs, return error */ 240e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 241e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return(TRUE); 242e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 243e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 244e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* If here, still waiting */ 245e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return(FALSE); 246e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach} 247e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 248e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach/******************************************************************************* 249e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 250e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Function gatt_sr_process_app_rsp 251e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 2526ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach** Description This function checks whether the response message from application 253e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** match any pending request or not. 254e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 255e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Returns void 256e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 257e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach*******************************************************************************/ 258e448862a47c08eb23185aaed574b39264f5005fcAndre EisenbachtGATT_STATUS gatt_sr_process_app_rsp (tGATT_TCB *p_tcb, tGATT_IF gatt_if, 259e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach UINT32 trans_id, UINT8 op_code, 260e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach tGATT_STATUS status, tGATTS_RSP *p_msg) 261e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach{ 262e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach tGATT_STATUS ret_code = GATT_SUCCESS; 263e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 264e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach GATT_TRACE_DEBUG1("gatt_sr_process_app_rsp gatt_if=%d", gatt_if); 265e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 266e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach gatt_sr_update_cback_cnt(p_tcb, gatt_if, FALSE, FALSE); 267e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 268e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (op_code == GATT_REQ_READ_MULTI) 269e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 270e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* If no error and still waiting, just return */ 271e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (!process_read_multi_rsp (&p_tcb->sr_cmd, status, p_msg, p_tcb->payload_size)) 272e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return(GATT_SUCCESS); 273e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 274e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach else 275e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 276e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (op_code == GATT_REQ_PREPARE_WRITE && status == GATT_SUCCESS) 277e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach gatt_sr_update_prep_cnt(p_tcb, gatt_if, TRUE, FALSE); 278e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 279e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (op_code == GATT_REQ_EXEC_WRITE && status != GATT_SUCCESS) 280e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach gatt_sr_reset_cback_cnt(p_tcb); 281e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 282e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_tcb->sr_cmd.status = status; 283e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 2846ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach if (gatt_sr_is_cback_cnt_zero(p_tcb) 285e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach && status == GATT_SUCCESS) 286e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 287e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (p_tcb->sr_cmd.p_rsp_msg == NULL) 288e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 289e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_tcb->sr_cmd.p_rsp_msg = attp_build_sr_msg (p_tcb, (UINT8)(op_code + 1), (tGATT_SR_MSG *)p_msg); 290e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 291e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach else 292e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 293e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach GATT_TRACE_ERROR0("Exception!!! already has respond message"); 294e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 295e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 296e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 2976ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach if (gatt_sr_is_cback_cnt_zero(p_tcb)) 298e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 299e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if ( (p_tcb->sr_cmd.status == GATT_SUCCESS) && (p_tcb->sr_cmd.p_rsp_msg) ) 300e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 301e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach ret_code = attp_send_sr_msg (p_tcb, p_tcb->sr_cmd.p_rsp_msg); 302e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_tcb->sr_cmd.p_rsp_msg = NULL; 303e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 304e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach else 305e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 3066ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach ret_code = gatt_send_error_rsp (p_tcb, status, op_code, p_tcb->sr_cmd.handle, FALSE); 307e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 308e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 309e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach gatt_dequeue_sr_cmd(p_tcb); 310e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 311e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 312e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach GATT_TRACE_DEBUG1("gatt_sr_process_app_rsp ret_code=%d", ret_code); 313e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 314e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return ret_code; 315e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach} 316e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 317e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach/******************************************************************************* 318e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 319e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Function gatt_process_exec_write_req 320e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 3216ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach** Description This function is called to process the execute write request 322e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** from client. 323e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 324e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Returns void 325e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 326e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach*******************************************************************************/ 327e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbachvoid gatt_process_exec_write_req (tGATT_TCB *p_tcb, UINT8 op_code, UINT16 len, UINT8 *p_data) 328e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach{ 329e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach UINT8 *p = p_data, flag, i = 0; 330e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach UINT32 trans_id = 0; 331e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach BT_HDR *p_buf; 332e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach tGATT_IF gatt_if; 333e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach UINT16 conn_id; 334e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 335e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach STREAM_TO_UINT8(flag, p); 336e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 337e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* mask the flag */ 338e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach flag &= GATT_PREP_WRITE_EXEC; 3396ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach 340e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 341e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* no prep write is queued */ 342e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (!gatt_sr_is_prep_cnt_zero(p_tcb)) 343e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 3446ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach trans_id = gatt_sr_enqueue_cmd(p_tcb, op_code, 0); 345e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach gatt_sr_copy_prep_cnt_to_cback_cnt(p_tcb); 346e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 347e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach for (i=0; i<GATT_MAX_APPS; i++) 348e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 349e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (p_tcb->prep_cnt[i]) 350e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 351e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach gatt_if = (tGATT_IF) (i+1); 352e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach conn_id = GATT_CREATE_CONN_ID(p_tcb->tcb_idx, gatt_if); 3536ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach gatt_sr_send_req_callback(conn_id, 3546ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach trans_id, 3556ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach GATTS_REQ_TYPE_WRITE_EXEC, 356e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach (tGATTS_DATA *)&flag); 357e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_tcb->prep_cnt[i]= 0; 358e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 359e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 360e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 361e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach else /* nothing needs to be executed , send response now */ 362e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 363e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach GATT_TRACE_ERROR0("gatt_process_exec_write_req: no prepare write pending"); 364e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 365e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if ((p_buf = attp_build_sr_msg(p_tcb, GATT_RSP_EXEC_WRITE, NULL)) != NULL) 366e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 367e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach attp_send_sr_msg (p_tcb, p_buf); 368e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 369e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 370e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 371e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach} 372e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 373e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach/******************************************************************************* 374e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 375e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Function gatt_process_read_multi_req 376e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 3776ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach** Description This function is called to process the read multiple request 378e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** from client. 379e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 380e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Returns void 381e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 382e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach*******************************************************************************/ 383e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbachvoid gatt_process_read_multi_req (tGATT_TCB *p_tcb, UINT8 op_code, UINT16 len, UINT8 *p_data) 384e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach{ 385e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach UINT32 trans_id; 386e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach UINT16 handle, ll = len; 387e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach UINT8 *p = p_data, i_rcb; 388e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach tGATT_STATUS err = GATT_SUCCESS; 389e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach UINT8 sec_flag, key_size; 390e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach tGATTS_RSP *p_msg; 391e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 3926ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach GATT_TRACE_DEBUG0("gatt_process_read_multi_req" ); 393e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_tcb->sr_cmd.multi_req.num_handles = 0; 394e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 3956ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach gatt_sr_get_sec_info(p_tcb->peer_bda, 3966ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach (BOOLEAN)(p_tcb->att_lcid == L2CAP_ATT_CID), 3976ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach &sec_flag, 398e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach &key_size); 399e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 400e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach#if GATT_CONFORMANCE_TESTING == TRUE 401e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (gatt_cb.enable_err_rsp && gatt_cb.req_op_code == op_code) 402e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 403e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach GATT_TRACE_DEBUG1("Conformance tst: forced err rspvofr ReadMultiple: error status=%d", gatt_cb.err_status); 404e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 405e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach STREAM_TO_UINT16(handle, p); 406e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 407e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach gatt_send_error_rsp (p_tcb, gatt_cb.err_status, gatt_cb.req_op_code, handle, FALSE); 408e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 409e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return; 410e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 411e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach#endif 412e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 413e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach while (ll >= 2 && p_tcb->sr_cmd.multi_req.num_handles < GATT_MAX_READ_MULTI_HANDLES) 414e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 415e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach STREAM_TO_UINT16(handle, p); 416e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 417e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if ((i_rcb = gatt_sr_find_i_rcb_by_handle(handle)) < GATT_MAX_SR_PROFILES) 418e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 419e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_tcb->sr_cmd.multi_req.handles[p_tcb->sr_cmd.multi_req.num_handles++] = handle; 420e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 421e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* check read permission */ 422e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if ((err = gatts_read_attr_perm_check( gatt_cb.sr_reg[i_rcb].p_db, 423e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach FALSE, 4246ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach handle, 425e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach sec_flag, 4266ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach key_size)) 427e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach != GATT_SUCCESS) 428e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 429e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach GATT_TRACE_DEBUG1("read permission denied : 0x%02x", err); 430e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach break; 431e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 432e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 433e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach else 434e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 435e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* invalid handle */ 436e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach err = GATT_INVALID_HANDLE; 437e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach break; 438e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 439e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach ll -= 2; 440e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 4416ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach 442e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (ll != 0) 443e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 444e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach GATT_TRACE_ERROR0("max attribute handle reached in ReadMultiple Request."); 445e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 446e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 447e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (p_tcb->sr_cmd.multi_req.num_handles == 0) 448e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach err = GATT_INVALID_HANDLE; 449e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 450e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (err == GATT_SUCCESS) 451e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 452e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if ((trans_id = gatt_sr_enqueue_cmd (p_tcb, op_code, p_tcb->sr_cmd.multi_req.handles[0])) != 0) 453e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 454e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach gatt_sr_reset_cback_cnt(p_tcb); /* read multiple use multi_rsp_q's count*/ 455e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 456e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach for (ll = 0; ll < p_tcb->sr_cmd.multi_req.num_handles; ll ++) 457e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 458e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if ((p_msg = (tGATTS_RSP *)GKI_getbuf(sizeof(tGATTS_RSP))) != NULL) 459e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 460e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach memset(p_msg, 0, sizeof(tGATTS_RSP)) 461e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach ; 462e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach handle = p_tcb->sr_cmd.multi_req.handles[ll]; 463e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach i_rcb = gatt_sr_find_i_rcb_by_handle(handle); 464e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 465e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_msg->attr_value.handle = handle; 466e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach err = gatts_read_attr_value_by_handle(p_tcb, 467e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach gatt_cb.sr_reg[i_rcb].p_db, 468e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach op_code, 4696ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach handle, 4706ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach 0, 4716ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach p_msg->attr_value.value, 472e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach &p_msg->attr_value.len, 4736ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach GATT_MAX_ATTR_LEN, 474e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach sec_flag, 475e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach key_size, 4766ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach trans_id); 477e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 478e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (err == GATT_SUCCESS) 479e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 480e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach gatt_sr_process_app_rsp(p_tcb, gatt_cb.sr_reg[i_rcb].gatt_if ,trans_id, op_code, GATT_SUCCESS, p_msg); 481e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 482e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* either not using or done using the buffer, release it now */ 4836ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach GKI_freebuf(p_msg); 484e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 485e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach else 486e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 487e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach err = GATT_NO_RESOURCES; 488e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach gatt_dequeue_sr_cmd(p_tcb); 489e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach break; 490e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 491e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 492e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 493e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach else 494e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach err = GATT_NO_RESOURCES; 495e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 496e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 497e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* in theroy BUSY is not possible(should already been checked), protected check */ 498e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (err != GATT_SUCCESS && err != GATT_PENDING && err != GATT_BUSY) 499e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach gatt_send_error_rsp(p_tcb, err, op_code, handle, FALSE); 500e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach} 501e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 502e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach/******************************************************************************* 503e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 504e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Function gatt_build_primary_service_rsp 505e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 506e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Description Primamry service request processed internally. Theretically 507e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** only deal with ReadByTypeVAlue and ReadByGroupType. 508e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 509e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Returns void 510e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 511e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach*******************************************************************************/ 5126ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbachstatic tGATT_STATUS gatt_build_primary_service_rsp (BT_HDR *p_msg, tGATT_TCB *p_tcb, 5136ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach UINT8 op_code, UINT16 s_hdl, 514e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach UINT16 e_hdl, UINT8 *p_data, tBT_UUID value) 515e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach{ 516e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach tGATT_STATUS status = GATT_NOT_FOUND; 517e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach UINT8 handle_len =4, *p ; 518e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach tGATT_SR_REG *p_rcb; 519e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach tGATT_SRV_LIST_INFO *p_list= &gatt_cb.srv_list_info; 520e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach tGATT_SRV_LIST_ELEM *p_srv=NULL; 521e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach tBT_UUID *p_uuid; 522e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 523e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p = (UINT8 *)(p_msg + 1) + L2CAP_MIN_OFFSET; 524e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 525e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_srv = p_list->p_first; 526e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 527e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach while (p_srv) 528e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 5296ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach p_rcb = GATT_GET_SR_REG_PTR(p_srv->i_sreg); 530e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 531e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (p_rcb->in_use && 532e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_rcb->s_hdl >= s_hdl && 533e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_rcb->s_hdl <= e_hdl && 534e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_rcb->type == GATT_UUID_PRI_SERVICE) 535e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 536e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_uuid = gatts_get_service_uuid (p_rcb->p_db); 537e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 538e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (op_code == GATT_REQ_READ_BY_GRP_TYPE) 539e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach handle_len = 4 + p_uuid->len; 540e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 541e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* get the length byte in the repsonse */ 542e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (p_msg->offset ==0) 543e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 544e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach *p ++ = op_code + 1; 545e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_msg->len ++; 546e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_msg->offset = handle_len; 547e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 548e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (op_code == GATT_REQ_READ_BY_GRP_TYPE) 549e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 550e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach *p ++ = (UINT8)p_msg->offset; /* length byte */ 551e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_msg->len ++; 552e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 553e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 554e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 555e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (p_msg->len + p_msg->offset <= p_tcb->payload_size && 556e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach handle_len == p_msg->offset) 557e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 558e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (op_code != GATT_REQ_FIND_TYPE_VALUE || 559e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach gatt_uuid_compare(value, *p_uuid)) 560e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 561e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach UINT16_TO_STREAM(p, p_rcb->s_hdl); 562e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 563e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (p_list->p_last_primary == p_srv && 564e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_list->p_last_primary == p_list->p_last) 565e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 566e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach GATT_TRACE_DEBUG0("Use 0xFFFF for the last primary attribute"); 567e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach UINT16_TO_STREAM(p, 0xFFFF); /* see GATT ERRATA 4065, 4063, ATT ERRATA 4062 */ 568e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 569e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach else 570e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 571e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach UINT16_TO_STREAM(p, p_rcb->e_hdl); 572e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 573e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 574e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (op_code == GATT_REQ_READ_BY_GRP_TYPE) 575e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach gatt_build_uuid_to_stream(&p, *p_uuid); 576e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 577e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach status = GATT_SUCCESS; 5786ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach p_msg->len += p_msg->offset; 579e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 580e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 581e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach else 582e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach break; 583e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 584e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_srv = p_srv->p_next; 585e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 586e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_msg->offset = L2CAP_MIN_OFFSET; 587e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 588e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return status; 589e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach} 590e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 591e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach/******************************************************************************* 592e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 593e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Function gatt_build_find_info_rsp 594e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 595e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Description fill the find information response information in the given 596e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** buffer. 597e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 598e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Returns TRUE: if data filled sucessfully. 599e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** FALSE: packet full, or format mismatch. 600e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 601e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach*******************************************************************************/ 6026ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbachstatic tGATT_STATUS gatt_build_find_info_rsp(tGATT_SR_REG *p_rcb, BT_HDR *p_msg, UINT16 *p_len, 603e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach UINT16 s_hdl, UINT16 e_hdl) 604e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach{ 605e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach tGATT_STATUS status = GATT_NOT_FOUND; 606e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach UINT8 *p; 607e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach UINT16 len = *p_len; 608e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach tGATT_ATTR16 *p_attr = NULL; 609e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach UINT8 info_pair_len[2] = {4, 18}; 610e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 611e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (!p_rcb->p_db || !p_rcb->p_db->p_attr_list) 612e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return status; 613e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 614e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* check the attribute database */ 615e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_attr = (tGATT_ATTR16 *) p_rcb->p_db->p_attr_list; 616e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 617e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p = (UINT8 *)(p_msg + 1) + L2CAP_MIN_OFFSET + p_msg->len; 618e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 619e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach while (p_attr) 620e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 621e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (p_attr->handle > e_hdl) 622e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 623e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach break; 624e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 625e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 626e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (p_attr->handle >= s_hdl) 627e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 628e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (p_msg->offset == 0) 629e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_msg->offset = (p_attr->uuid_type == GATT_ATTR_UUID_TYPE_128) ? GATT_INFO_TYPE_PAIR_128 : GATT_INFO_TYPE_PAIR_16; 630e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 631e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (len >= info_pair_len[p_msg->offset - 1]) 632e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 633e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (p_msg->offset == GATT_INFO_TYPE_PAIR_16 && p_attr->uuid_type == GATT_ATTR_UUID_TYPE_16) 634e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 635e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach UINT16_TO_STREAM(p, p_attr->handle); 636e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach UINT16_TO_STREAM(p, p_attr->uuid); 637e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 6386ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach else if (p_msg->offset == GATT_INFO_TYPE_PAIR_128 && 639e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_attr->uuid_type == GATT_ATTR_UUID_TYPE_128 ) 640e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 641e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach UINT16_TO_STREAM(p, p_attr->handle); 642e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach ARRAY_TO_STREAM (p, ((tGATT_ATTR128 *) p_attr)->uuid, LEN_UUID_128); 643e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 644e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach else 645e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 646e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach GATT_TRACE_ERROR0("format mismatch"); 647e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach status = GATT_NO_RESOURCES; 648e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach break; 649e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* format mismatch */ 650e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 651e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_msg->len += info_pair_len[p_msg->offset - 1]; 652e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach len -= info_pair_len[p_msg->offset - 1]; 653e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach status = GATT_SUCCESS; 654e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 655e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 656e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach else 657e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 658e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach status = GATT_NO_RESOURCES; 659e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach break; 660e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 661e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 662e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_attr = (tGATT_ATTR16 *)p_attr->p_next; 663e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 664e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 665e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach *p_len = len; 666e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return status; 667e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach} 668e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 669e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach/******************************************************************************* 670e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 671e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Function gatts_internal_read_by_type_req 672e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 673e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Description check to see if the ReadByType request can be handled internally. 674e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 675e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Returns void 676e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 677e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach*******************************************************************************/ 6786ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbachstatic tGATT_STATUS gatts_validate_packet_format(UINT8 op_code, UINT16 *p_len, 679e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach UINT8 **p_data, tBT_UUID *p_uuid_filter, 680e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach UINT16 *p_s_hdl, UINT16 *p_e_hdl) 681e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach{ 682e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach tGATT_STATUS reason = GATT_SUCCESS; 683e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach UINT16 uuid_len, s_hdl = 0, e_hdl = 0; 684e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach UINT16 len = *p_len; 685e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach UINT8 *p = *p_data; 686e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 687e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (len >= 4) 688e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 689e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* obtain starting handle, and ending handle */ 690e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach STREAM_TO_UINT16(s_hdl, p); 691e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach STREAM_TO_UINT16(e_hdl, p); 692e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach len -= 4; 693e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 694e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (s_hdl > e_hdl || !GATT_HANDLE_IS_VALID(s_hdl) || !GATT_HANDLE_IS_VALID(e_hdl)) 695e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 696e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach reason = GATT_INVALID_HANDLE; 697e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 698e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* for these PDUs, uuid filter must present */ 6996ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach else if (op_code == GATT_REQ_READ_BY_GRP_TYPE || 700e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach op_code == GATT_REQ_FIND_TYPE_VALUE || 701e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach op_code == GATT_REQ_READ_BY_TYPE) 702e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 703e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (len >= 2 && p_uuid_filter != NULL) 704e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 705e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach uuid_len = (op_code == GATT_REQ_FIND_TYPE_VALUE) ? 2 : len; 706e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 707e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* parse uuid now */ 708e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (gatt_parse_uuid_from_cmd (p_uuid_filter, uuid_len, &p) == FALSE || 709e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_uuid_filter->len == 0) 710e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 711e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach GATT_TRACE_DEBUG0("UUID filter does not exsit"); 712e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach reason = GATT_INVALID_PDU; 713e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 714e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach else 715e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach len -= p_uuid_filter->len; 716e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 717e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach else 718e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach reason = GATT_INVALID_PDU; 719e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 720e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 721e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 722e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach *p_data = p; 723e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach *p_len = len; 724e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach *p_s_hdl = s_hdl; 725e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach *p_e_hdl = e_hdl; 726e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 727e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return reason; 728e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach} 729e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 730e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach/******************************************************************************* 731e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 732e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Function gatts_process_primary_service_req 733e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 7346ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach** Description process ReadByGroupType/ReadByTypeValue request, for discover 735e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** all primary services or discover primary service by UUID request. 736e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 737e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Returns void 738e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 739e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach*******************************************************************************/ 740e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbachvoid gatts_process_primary_service_req(tGATT_TCB *p_tcb, UINT8 op_code, UINT16 len, UINT8 *p_data) 741e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach{ 742e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach UINT8 reason = GATT_INVALID_PDU; 743e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach UINT16 s_hdl = 0, e_hdl = 0; 744e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach tBT_UUID uuid, value, primary_service = {LEN_UUID_16, {GATT_UUID_PRI_SERVICE}}; 745e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach BT_HDR *p_msg = NULL; 746e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach UINT16 msg_len = (UINT16)(sizeof(BT_HDR) + p_tcb->payload_size + L2CAP_MIN_OFFSET); 747e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 748e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach reason = gatts_validate_packet_format(op_code, &len, &p_data, &uuid, &s_hdl, &e_hdl); 749e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 750e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (reason == GATT_SUCCESS) 751e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 752e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (gatt_uuid_compare(uuid, primary_service)) 753e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 754e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (op_code == GATT_REQ_FIND_TYPE_VALUE) 755e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 756e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (gatt_parse_uuid_from_cmd(&value, len, &p_data) == FALSE) 757e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach reason = GATT_INVALID_PDU; 758e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 759e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 760e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (reason == GATT_SUCCESS) 761e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 762e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if ((p_msg = (BT_HDR *)GKI_getbuf(msg_len)) == NULL) 763e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 764e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach GATT_TRACE_ERROR0("gatts_process_primary_service_req failed. no resources."); 765e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach reason = GATT_NO_RESOURCES; 766e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 767e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach else 768e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 769e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach memset(p_msg, 0, msg_len); 770e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach reason = gatt_build_primary_service_rsp (p_msg, p_tcb, op_code, s_hdl, e_hdl, p_data, value); 771e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 772e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 773e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 774e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach else 775e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 776e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (op_code == GATT_REQ_READ_BY_GRP_TYPE) 777e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 778e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach reason = GATT_UNSUPPORT_GRP_TYPE; 779e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach GATT_TRACE_DEBUG1("unexpected ReadByGrpType Group: 0x%04x", uuid.uu.uuid16); 780e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 781e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach else 782e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 783e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* we do not support ReadByTypeValue with any non-primamry_service type */ 784e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach reason = GATT_NOT_FOUND; 785e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach GATT_TRACE_DEBUG1("unexpected ReadByTypeValue type: 0x%04x", uuid.uu.uuid16); 7866ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach } 787e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 788e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 789e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 790e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (reason != GATT_SUCCESS) 791e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 792e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (p_msg) GKI_freebuf(p_msg); 793e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach gatt_send_error_rsp (p_tcb, reason, op_code, s_hdl, FALSE); 794e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 795e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach else 796e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach attp_send_sr_msg(p_tcb, p_msg); 797e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 798e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach} 799e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 800e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach/******************************************************************************* 801e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 802e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Function gatts_process_find_info 803e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 8046ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach** Description process find information request, for discover character 805e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** descriptors. 806e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 807e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Returns void 808e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 809e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach*******************************************************************************/ 810e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbachstatic void gatts_process_find_info(tGATT_TCB *p_tcb, UINT8 op_code, UINT16 len, UINT8 *p_data) 811e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach{ 812e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach UINT8 reason = GATT_INVALID_PDU, *p; 813e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach UINT16 s_hdl = 0, e_hdl = 0, buf_len; 814e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach BT_HDR *p_msg = NULL; 815e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach tGATT_SR_REG *p_rcb; 816e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach tGATT_SRV_LIST_INFO *p_list= &gatt_cb.srv_list_info; 817e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach tGATT_SRV_LIST_ELEM *p_srv=NULL; 818e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 819e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach reason = gatts_validate_packet_format(op_code, &len, &p_data, NULL, &s_hdl, &e_hdl); 820e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 821e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (reason == GATT_SUCCESS) 822e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 823e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach buf_len = (UINT16)(sizeof(BT_HDR) + p_tcb->payload_size + L2CAP_MIN_OFFSET); 824e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 825e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if ((p_msg = (BT_HDR *)GKI_getbuf(buf_len)) == NULL) 826e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 827e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach reason = GATT_NO_RESOURCES; 828e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 829e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach else 830e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 831e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach reason = GATT_NOT_FOUND; 832e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 833e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach memset(p_msg, 0, buf_len); 834e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p = (UINT8 *)(p_msg + 1) + L2CAP_MIN_OFFSET; 835e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach *p ++ = op_code + 1; 836e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_msg->len = 2; 837e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 838e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach buf_len = p_tcb->payload_size - 2; 839e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 840e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_srv = p_list->p_first; 841e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 842e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach while (p_srv) 843e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 8446ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach p_rcb = GATT_GET_SR_REG_PTR(p_srv->i_sreg); 845e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 846e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (p_rcb->in_use && 847e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach !(p_rcb->s_hdl > e_hdl || 848e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_rcb->e_hdl < s_hdl)) 849e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 850e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach reason = gatt_build_find_info_rsp(p_rcb, p_msg, &buf_len, s_hdl, e_hdl); 851e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (reason == GATT_NO_RESOURCES) 852e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 853e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach reason = GATT_SUCCESS; 854e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach break; 855e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 856e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 857e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_srv = p_srv->p_next; 858e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 859e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach *p = (UINT8)p_msg->offset; 860e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 861e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_msg->offset = L2CAP_MIN_OFFSET; 862e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 863e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 864e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 865e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (reason != GATT_SUCCESS) 866e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 867e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (p_msg) GKI_freebuf(p_msg); 868e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach gatt_send_error_rsp (p_tcb, reason, op_code, s_hdl, FALSE); 869e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 870e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach else 871e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach attp_send_sr_msg(p_tcb, p_msg); 872e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 873e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach} 874e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 875e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach/******************************************************************************* 876e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 877e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Function gatts_process_mtu_req 878e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 879e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Description This function is called to process excahnge MTU request. 880e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Only used on LE. 881e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 882e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Returns void 883e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 884e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach*******************************************************************************/ 885e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbachstatic void gatts_process_mtu_req (tGATT_TCB *p_tcb, UINT16 len, UINT8 *p_data) 886e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach{ 887e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach UINT16 mtu = 0; 888e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach UINT8 *p = p_data, i; 889e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach BT_HDR *p_buf; 8906ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach UINT16 conn_id; 891e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 892e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach STREAM_TO_UINT16 (mtu, p); 893e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 894e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* BR/EDR conenction, send error response */ 895e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (p_tcb->att_lcid != L2CAP_ATT_CID) 896e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 897e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach gatt_send_error_rsp (p_tcb, GATT_REQ_NOT_SUPPORTED, GATT_REQ_MTU, 0, FALSE); 898e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 899e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach else 900e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 901e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* mtu must be greater than default MTU which is 23/48 */ 902e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (mtu <= GATT_MAX_MTU_SIZE) 903e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_tcb->payload_size = mtu; 904e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach else 905e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_tcb->payload_size = GATT_MAX_MTU_SIZE; 906e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 907e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if ((p_buf = attp_build_sr_msg(p_tcb, GATT_RSP_MTU, (tGATT_SR_MSG *) &p_tcb->payload_size)) != NULL) 908e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 909e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach attp_send_sr_msg (p_tcb, p_buf); 910e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 911e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* Notify all registered applicaiton with new MTU size. Us a transaction ID */ 912e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* of 0, as no response is allowed from applcations */ 913e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 914e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach for (i = 0; i < GATT_MAX_APPS; i ++) 915e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 916e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (gatt_cb.cl_rcb[i].in_use ) 917e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 918e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach conn_id = GATT_CREATE_CONN_ID(p_tcb->tcb_idx, gatt_cb.cl_rcb[i].gatt_if); 9196ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach gatt_sr_send_req_callback(conn_id, 0, GATTS_REQ_TYPE_MTU, 920e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach (tGATTS_DATA *)&p_tcb->payload_size); 921e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 922e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 923e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 924e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 925e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 926e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach} 927e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 928e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach/******************************************************************************* 929e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 930e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Function gatts_process_read_by_type_req 931e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 932e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Description process Read By type request. 933e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** This PDU can be used to perform: 934e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** - read characteristic value 9356ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach** - read characteristic descriptor value 936e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** - discover characteristic 937e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** - discover characteristic by UUID 938e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** - relationship discovery 939e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 940e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Returns void 941e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 942e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach*******************************************************************************/ 943e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbachvoid gatts_process_read_by_type_req(tGATT_TCB *p_tcb, UINT8 op_code, UINT16 len, UINT8 *p_data) 944e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach{ 945e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach tBT_UUID uuid; 946e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach tGATT_SR_REG *p_rcb; 947e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach UINT16 msg_len = (UINT16)(sizeof(BT_HDR) + p_tcb->payload_size + L2CAP_MIN_OFFSET), 9486ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach buf_len, 949e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach s_hdl, e_hdl, err_hdl = 0; 950e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach BT_HDR *p_msg = NULL; 951e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach tGATT_STATUS reason, ret; 952e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach UINT8 *p; 953e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach UINT8 sec_flag, key_size; 954e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach tGATT_SRV_LIST_INFO *p_list= &gatt_cb.srv_list_info; 955e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach tGATT_SRV_LIST_ELEM *p_srv=NULL; 956e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 957e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach reason = gatts_validate_packet_format(op_code, &len, &p_data, &uuid, &s_hdl, &e_hdl); 958e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 959e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach#if GATT_CONFORMANCE_TESTING == TRUE 960e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (gatt_cb.enable_err_rsp && gatt_cb.req_op_code == op_code) 961e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 962e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach GATT_TRACE_DEBUG1("Conformance tst: forced err rsp for ReadByType: error status=%d", gatt_cb.err_status); 963e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 964e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach gatt_send_error_rsp (p_tcb, gatt_cb.err_status, gatt_cb.req_op_code, s_hdl, FALSE); 965e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 966e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return; 967e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 968e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach#endif 969e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 970e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (reason == GATT_SUCCESS) 971e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 972e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if ((p_msg = (BT_HDR *)GKI_getbuf(msg_len)) == NULL) 973e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 974e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach GATT_TRACE_ERROR0("gatts_process_find_info failed. no resources."); 975e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 976e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach reason = GATT_NO_RESOURCES; 977e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 978e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach else 979e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 980e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach memset(p_msg, 0, msg_len); 981e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p = (UINT8 *)(p_msg + 1) + L2CAP_MIN_OFFSET; 982e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 983e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach *p ++ = op_code + 1; 984e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* reserve length byte */ 985e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_msg->len = 2; 986e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach buf_len = p_tcb->payload_size - 2; 987e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 988e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach reason = GATT_NOT_FOUND; 989e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 990e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_srv = p_list->p_first; 991e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 992e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach while (p_srv) 993e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 9946ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach p_rcb = GATT_GET_SR_REG_PTR(p_srv->i_sreg); 995e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 996e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (p_rcb->in_use && 997e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach !(p_rcb->s_hdl > e_hdl || 998e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_rcb->e_hdl < s_hdl)) 999e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 10006ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach gatt_sr_get_sec_info(p_tcb->peer_bda, 10016ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach (BOOLEAN)(p_tcb->att_lcid == L2CAP_ATT_CID), 10026ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach &sec_flag, 1003e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach &key_size); 1004e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 10056ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach ret = gatts_db_read_attr_value_by_type(p_tcb, 10066ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach p_rcb->p_db, 1007e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach op_code, 10086ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach p_msg, 10096ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach s_hdl, 10106ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach e_hdl, 1011e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach uuid, 1012e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach &buf_len, 1013e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach sec_flag, 1014e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach key_size, 1015e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 0, 1016e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach &err_hdl); 1017e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (ret != GATT_NOT_FOUND) 1018e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 1019e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach reason = ret; 1020e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1021e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (ret == GATT_NO_RESOURCES) 1022e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach reason = GATT_SUCCESS; 1023e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 1024e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (ret != GATT_SUCCESS && ret != GATT_NOT_FOUND) 1025e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 1026e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach s_hdl = err_hdl; 1027e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach break; 1028e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 1029e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 1030e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_srv = p_srv->p_next; 1031e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 1032e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach *p = (UINT8)p_msg->offset; 1033e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_msg->offset = L2CAP_MIN_OFFSET; 1034e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 1035e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 1036e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (reason != GATT_SUCCESS) 1037e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 1038e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (p_msg) GKI_freebuf(p_msg); 1039e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1040e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* in theroy BUSY is not possible(should already been checked), protected check */ 1041e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (reason != GATT_PENDING && reason != GATT_BUSY) 1042e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach gatt_send_error_rsp (p_tcb, reason, op_code, s_hdl, FALSE); 1043e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 1044e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach else 1045e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach attp_send_sr_msg(p_tcb, p_msg); 1046e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1047e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach} 1048e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1049e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach/******************************************************************************* 1050e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 1051e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Function gatts_process_write_req 1052e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 10536ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach** Description This function is called to process the write request 1054e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** from client. 1055e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 1056e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Returns void 1057e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 1058e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach*******************************************************************************/ 1059e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbachvoid gatts_process_write_req (tGATT_TCB *p_tcb, UINT8 i_rcb, UINT16 handle, 1060e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach UINT8 op_code, UINT16 len, UINT8 *p_data) 1061e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach{ 1062e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach tGATTS_DATA sr_data; 1063e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach UINT32 trans_id; 1064e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach tGATT_STATUS status; 1065e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach UINT8 sec_flag, key_size, *p = p_data; 1066e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach tGATT_SR_REG *p_sreg; 1067e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach UINT16 conn_id; 1068e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1069e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach memset(&sr_data, 0, sizeof(tGATTS_DATA)); 1070e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1071e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach switch (op_code) 1072e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 1073e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach case GATT_REQ_PREPARE_WRITE: 1074e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach sr_data.write_req.is_prep = TRUE; 1075e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach STREAM_TO_UINT16(sr_data.write_req.offset, p); 1076e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach len -= 2; 1077e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* fall through */ 1078e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach case GATT_SIGN_CMD_WRITE: 1079e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (op_code == GATT_SIGN_CMD_WRITE) 1080e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 1081e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach GATT_TRACE_DEBUG0("Write CMD with data sigining" ); 10826ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach len -= GATT_AUTH_SIGN_LEN; 1083e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 1084e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* fall through */ 1085e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach case GATT_CMD_WRITE: 1086e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach case GATT_REQ_WRITE: 1087e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (op_code == GATT_REQ_WRITE || op_code == GATT_REQ_PREPARE_WRITE) 1088e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach sr_data.write_req.need_rsp = TRUE; 1089e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach sr_data.write_req.handle = handle; 1090e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach sr_data.write_req.len = len; 1091e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach memcpy (sr_data.write_req.value, p, len); 1092e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach break; 1093e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 1094e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 10956ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach gatt_sr_get_sec_info(p_tcb->peer_bda, 10966ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach (BOOLEAN)(p_tcb->att_lcid == L2CAP_ATT_CID), 10976ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach &sec_flag, 1098e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach &key_size); 1099e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1100e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach status = gatts_write_attr_perm_check (gatt_cb.sr_reg[i_rcb].p_db, 1101e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach op_code, 11026ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach handle, 11036ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach sr_data.write_req.offset, 11046ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach p, 11056ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach len, 11066ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach sec_flag, 1107e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach key_size); 1108e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1109e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (status == GATT_SUCCESS) 1110e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 1111e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if ((trans_id = gatt_sr_enqueue_cmd(p_tcb, op_code, handle)) != 0) 1112e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 1113e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_sreg = &gatt_cb.sr_reg[i_rcb]; 1114e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach conn_id = GATT_CREATE_CONN_ID(p_tcb->tcb_idx, p_sreg->gatt_if); 1115e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach gatt_sr_send_req_callback(conn_id, 11166ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach trans_id, 11176ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach GATTS_REQ_TYPE_WRITE, 1118e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach &sr_data); 11196ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach 1120e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach status = GATT_PENDING; 1121e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 1122e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach else 1123e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 1124e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach GATT_TRACE_ERROR0("max pending command, send error"); 1125e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach status = GATT_BUSY; /* max pending command, application error */ 1126e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 1127e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 1128e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1129e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* in theroy BUSY is not possible(should already been checked), protected check */ 1130e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (status != GATT_PENDING && status != GATT_BUSY && 1131e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach (op_code == GATT_REQ_PREPARE_WRITE || op_code == GATT_REQ_WRITE)) 1132e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 1133e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach gatt_send_error_rsp (p_tcb, status, op_code, handle, FALSE); 1134e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 1135e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return; 1136e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach} 1137e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1138e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach/******************************************************************************* 1139e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 1140e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Function gatts_process_read_req 1141e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 11426ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach** Description This function is called to process the read request 1143e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** from client. 1144e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 1145e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Returns void 1146e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 1147e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach*******************************************************************************/ 11486ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbachstatic void gatts_process_read_req(tGATT_TCB *p_tcb, tGATT_SR_REG *p_rcb, UINT8 op_code, 1149e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach UINT16 handle, UINT16 len, UINT8 *p_data) 1150e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach{ 1151e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach UINT16 buf_len = (UINT16)(sizeof(BT_HDR) + p_tcb->payload_size + L2CAP_MIN_OFFSET); 1152e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach tGATT_STATUS reason; 1153e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach BT_HDR *p_msg = NULL; 1154e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach UINT8 sec_flag, key_size, *p; 1155e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach UINT16 offset = 0, value_len = 0; 1156e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1157e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if ((p_msg = (BT_HDR *)GKI_getbuf(buf_len)) == NULL) 1158e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 1159e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach GATT_TRACE_ERROR0("gatts_process_find_info failed. no resources."); 1160e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1161e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach reason = GATT_NO_RESOURCES; 1162e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 1163e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach else 1164e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 1165e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (op_code == GATT_REQ_READ_BLOB) 1166e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach STREAM_TO_UINT16(offset, p_data); 1167e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1168e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach memset(p_msg, 0, buf_len); 1169e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p = (UINT8 *)(p_msg + 1) + L2CAP_MIN_OFFSET; 1170e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach *p ++ = op_code + 1; 1171e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_msg->len = 1; 1172e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach buf_len = p_tcb->payload_size - 1; 1173e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 11746ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach gatt_sr_get_sec_info(p_tcb->peer_bda, 11756ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach (BOOLEAN)(p_tcb->att_lcid == L2CAP_ATT_CID), 11766ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach &sec_flag, 1177e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach &key_size); 1178e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1179e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach reason = gatts_read_attr_value_by_handle(p_tcb, 1180e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_rcb->p_db, 1181e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach op_code, 11826ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach handle, 11836ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach offset, 11846ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach p, 1185e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach &value_len, 11866ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach buf_len, 1187e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach sec_flag, 1188e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach key_size, 11896ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach 0); 1190e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1191e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_msg->len += value_len; 1192e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 1193e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1194e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (reason != GATT_SUCCESS) 1195e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 1196e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (p_msg) GKI_freebuf(p_msg); 1197e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1198e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* in theroy BUSY is not possible(should already been checked), protected check */ 1199e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (reason != GATT_PENDING && reason != GATT_BUSY) 1200e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach gatt_send_error_rsp (p_tcb, reason, op_code, handle, FALSE); 1201e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 1202e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach else 1203e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach attp_send_sr_msg(p_tcb, p_msg); 1204e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1205e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach} 1206e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1207e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach/******************************************************************************* 1208e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 1209e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Function gatts_process_attribute_req 1210e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 12116ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach** Description This function is called to process the per attribute handle request 1212e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** from client. 1213e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 1214e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Returns void 1215e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 1216e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach*******************************************************************************/ 12176ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbachvoid gatts_process_attribute_req (tGATT_TCB *p_tcb, UINT8 op_code, 1218e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach UINT16 len, UINT8 *p_data) 1219e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach{ 1220e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach UINT16 handle; 1221e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach UINT8 *p = p_data, i; 1222e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach tGATT_SR_REG *p_rcb = gatt_cb.sr_reg; 1223e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach tGATT_STATUS status = GATT_INVALID_HANDLE; 1224e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach tGATT_ATTR16 *p_attr; 1225e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1226e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach STREAM_TO_UINT16(handle, p); 1227e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach len -= 2; 1228e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1229e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach#if GATT_CONFORMANCE_TESTING == TRUE 1230e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (gatt_cb.enable_err_rsp && gatt_cb.req_op_code == op_code) 1231e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 1232e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach GATT_TRACE_DEBUG1("Conformance tst: forced err rsp: error status=%d", gatt_cb.err_status); 1233e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1234e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach gatt_send_error_rsp (p_tcb, gatt_cb.err_status, gatt_cb.req_op_code, handle, FALSE); 1235e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1236e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return; 1237e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 1238e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach#endif 1239e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1240e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (GATT_HANDLE_IS_VALID(handle)) 1241e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 1242e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach for (i = 0; i < GATT_MAX_SR_PROFILES; i ++, p_rcb ++) 1243e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 1244e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (p_rcb->in_use && p_rcb->s_hdl <= handle && p_rcb->e_hdl >= handle) 1245e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 1246e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_attr = (tGATT_ATTR16 *)p_rcb->p_db->p_attr_list; 1247e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1248e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach while (p_attr) 1249e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 1250e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (p_attr->handle == handle) 1251e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 1252e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach switch (op_code) 1253e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 12546ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach case GATT_REQ_READ: /* read char/char descriptor value */ 1255e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach case GATT_REQ_READ_BLOB: 1256e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach gatts_process_read_req(p_tcb, p_rcb, op_code, handle, len, p); 1257e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach break; 1258e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1259e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach case GATT_REQ_WRITE: /* write char/char descriptor value */ 12606ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach case GATT_CMD_WRITE: 1261e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach case GATT_SIGN_CMD_WRITE: 1262e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach case GATT_REQ_PREPARE_WRITE: 1263e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach gatts_process_write_req(p_tcb, i, handle, op_code, len, p); 1264e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach break; 1265e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach default: 1266e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach break; 1267e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 1268e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach status = GATT_SUCCESS; 1269e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach break; 1270e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 1271e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_attr = (tGATT_ATTR16 *)p_attr->p_next; 1272e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 1273e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach break; 1274e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 1275e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 1276e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 1277e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1278e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (status != GATT_SUCCESS && op_code != GATT_CMD_WRITE && op_code != GATT_SIGN_CMD_WRITE) 1279e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach gatt_send_error_rsp (p_tcb, status, op_code, handle, FALSE); 1280e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach} 1281e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1282e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach/******************************************************************************* 1283e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 1284e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Function gatts_proc_srv_chg_ind_ack 1285e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 12866ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach** Description This function process the service changed indicaiton ACK 1287e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 1288e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Returns void 1289e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 1290e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach*******************************************************************************/ 1291e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbachstatic void gatts_proc_srv_chg_ind_ack(tGATT_TCB *p_tcb ) 12926ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach{ 1293e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach tGATTS_SRV_CHG_REQ req; 1294e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach tGATTS_SRV_CHG *p_buf = NULL; 1295e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1296e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach GATT_TRACE_DEBUG0("gatts_proc_srv_chg_ind_ack"); 1297e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1298e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if ((p_buf = gatt_is_bda_in_the_srv_chg_clt_list(p_tcb->peer_bda)) != NULL) 1299e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 1300e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach GATT_TRACE_DEBUG0("NV update set srv chg = FALSE"); 1301e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_buf->srv_changed = FALSE; 1302e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach memcpy(&req.srv_chg, p_buf, sizeof(tGATTS_SRV_CHG)); 1303e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (gatt_cb.cb_info.p_srv_chg_callback) 1304e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach (*gatt_cb.cb_info.p_srv_chg_callback)(GATTS_SRV_CHG_CMD_UPDATE_CLIENT,&req, NULL); 1305e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 1306e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach} 1307e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1308e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach/******************************************************************************* 1309e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 1310e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Function gatts_chk_pending_ind 1311e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 1312e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Description This function check any pending indication needs to be sent if 1313e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** there is a pending indication then sent the indication 1314e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 1315e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Returns void 1316e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 1317e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach*******************************************************************************/ 1318e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbachstatic void gatts_chk_pending_ind(tGATT_TCB *p_tcb ) 1319e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach{ 1320e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach tGATT_VALUE *p_buf = (tGATT_VALUE *)GKI_getfirst(&p_tcb->pending_ind_q); 1321e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach GATT_TRACE_DEBUG0("gatts_chk_pending_ind"); 1322e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1323e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (p_buf ) 1324e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 1325e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach GATTS_HandleValueIndication (p_buf->conn_id, 1326e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_buf->handle, 1327e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_buf->len, 1328e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_buf->value); 1329e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach GKI_freebuf(GKI_remove_from_queue (&p_tcb->pending_ind_q, p_buf)); 1330e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 1331e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach} 1332e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1333e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach/******************************************************************************* 1334e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 1335e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Function gatts_proc_ind_ack 1336e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 13376ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach** Description This function process the Indication ack 1338e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 1339e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Returns TRUE continue to process the indication ack by the aaplication 1340e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** if the ACk is not a Service Changed Indication Ack 1341e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 1342e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach*******************************************************************************/ 1343e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbachstatic BOOLEAN gatts_proc_ind_ack(tGATT_TCB *p_tcb, UINT16 ack_handle) 1344e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach{ 1345e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach BOOLEAN continue_processing = TRUE; 1346e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1347e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach GATT_TRACE_DEBUG1 ("gatts_proc_ind_ack ack handle=%d", ack_handle); 1348e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1349e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (ack_handle == gatt_cb.handle_of_h_r) 1350e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 1351e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach gatts_proc_srv_chg_ind_ack(p_tcb); 1352e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* there is no need to inform the application since srv chg is handled internally by GATT */ 1353e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach continue_processing = FALSE; 1354e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 1355e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1356e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach gatts_chk_pending_ind(p_tcb); 1357e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return continue_processing; 1358e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach} 1359e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1360e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach/******************************************************************************* 1361e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 1362e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Function gatts_process_value_conf 1363e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 1364e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Description This function is called to process the handle value confirmation. 1365e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 1366e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Returns void 1367e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 1368e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach*******************************************************************************/ 1369e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbachvoid gatts_process_value_conf(tGATT_TCB *p_tcb, UINT8 op_code) 1370e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach{ 1371e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach UINT16 handle = p_tcb->indicate_handle; 1372e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach UINT32 trans_id; 1373e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach UINT8 i; 1374e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach tGATT_SR_REG *p_rcb = gatt_cb.sr_reg; 1375e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach BOOLEAN continue_processing; 1376e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach UINT16 conn_id; 1377e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1378e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach btu_stop_timer (&p_tcb->conf_timer_ent); 1379e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (GATT_HANDLE_IS_VALID(handle)) 1380e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 1381e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_tcb->indicate_handle = 0; 1382e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach continue_processing = gatts_proc_ind_ack(p_tcb, handle); 1383e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1384e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (continue_processing) 1385e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 1386e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach for (i = 0; i < GATT_MAX_SR_PROFILES; i ++, p_rcb ++) 1387e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 1388e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (p_rcb->in_use && p_rcb->s_hdl <= handle && p_rcb->e_hdl >= handle) 1389e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 1390e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach trans_id = gatt_sr_enqueue_cmd(p_tcb, op_code, handle); 1391e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach conn_id = GATT_CREATE_CONN_ID(p_tcb->tcb_idx, p_rcb->gatt_if); 13926ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach gatt_sr_send_req_callback(conn_id, 1393e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach trans_id, GATTS_REQ_TYPE_CONF, (tGATTS_DATA *)&handle); 1394e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 1395e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 1396e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 1397e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 1398e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach else 1399e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 1400e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach GATT_TRACE_ERROR0("unexpected handle value confirmation"); 1401e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 1402e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach} 1403e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1404e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach/******************************************************************************* 1405e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 1406e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Function gatt_server_handle_client_req 1407e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 14086ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach** Description This function is called to handle the client requests to 1409e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** server. 1410e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 1411e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 1412e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Returns void 1413e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 1414e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach*******************************************************************************/ 14156ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbachvoid gatt_server_handle_client_req (tGATT_TCB *p_tcb, UINT8 op_code, 1416e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach UINT16 len, UINT8 *p_data) 1417e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach{ 1418e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* there is pending command, discard this one */ 1419e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (!gatt_sr_cmd_empty(p_tcb) && op_code != GATT_HANDLE_VALUE_CONF) 1420e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return; 1421e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1422e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* the size of the message may not be bigger than the local max PDU size*/ 1423e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* The message has to be smaller than the agreed MTU, len does not include op code */ 1424e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (len >= p_tcb->payload_size) 1425e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 1426e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach GATT_TRACE_ERROR2("server receive invalid PDU size:%d pdu size:%d", len + 1, p_tcb->payload_size ); 1427e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* for invalid request expecting response, send it now */ 14286ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach if (op_code != GATT_CMD_WRITE && 14296ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach op_code != GATT_SIGN_CMD_WRITE && 1430e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach op_code != GATT_HANDLE_VALUE_CONF) 1431e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 14326ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach gatt_send_error_rsp (p_tcb, GATT_INVALID_PDU, op_code, 0, FALSE); 1433e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 1434e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* otherwise, ignore the pkt */ 1435e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 1436e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach else 1437e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 1438e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach switch (op_code) 1439e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 1440e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach case GATT_REQ_READ_BY_GRP_TYPE: /* discover primary services */ 1441e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach case GATT_REQ_FIND_TYPE_VALUE: /* discover service by UUID */ 1442e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach gatts_process_primary_service_req (p_tcb, op_code, len, p_data); 1443e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach break; 1444e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1445e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach case GATT_REQ_FIND_INFO:/* discover char descrptor */ 1446e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach gatts_process_find_info(p_tcb, op_code, len, p_data); 1447e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach break; 1448e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1449e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach case GATT_REQ_READ_BY_TYPE: /* read characteristic value, char descriptor value */ 1450e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* discover characteristic, discover char by UUID */ 1451e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach gatts_process_read_by_type_req(p_tcb, op_code, len, p_data); 1452e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach break; 1453e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1454e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 14556ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach case GATT_REQ_READ: /* read char/char descriptor value */ 1456e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach case GATT_REQ_READ_BLOB: 1457e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach case GATT_REQ_WRITE: /* write char/char descriptor value */ 14586ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach case GATT_CMD_WRITE: 1459e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach case GATT_SIGN_CMD_WRITE: 1460e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach case GATT_REQ_PREPARE_WRITE: 1461e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach gatts_process_attribute_req (p_tcb, op_code, len, p_data); 1462e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach break; 1463e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1464e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach case GATT_HANDLE_VALUE_CONF: 1465e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach gatts_process_value_conf (p_tcb, op_code); 1466e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach break; 1467e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1468e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach case GATT_REQ_MTU: 1469e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach gatts_process_mtu_req (p_tcb, len, p_data); 1470e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach break; 1471e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1472e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach case GATT_REQ_EXEC_WRITE: 1473e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach gatt_process_exec_write_req (p_tcb, op_code, len, p_data); 1474e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach break; 1475e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1476e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach case GATT_REQ_READ_MULTI: 1477e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach gatt_process_read_multi_req (p_tcb, op_code, len, p_data); 1478e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach break; 1479e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1480e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach default: 14816ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach break; 1482e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 1483e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 1484e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach} 1485e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1486e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach#endif /* BLE_INCLUDED */ 1487