15738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************
25738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
35738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  Copyright (C) 2009-2012 Broadcom Corporation
45738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
55738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  Licensed under the Apache License, Version 2.0 (the "License");
65738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  you may not use this file except in compliance with the License.
75738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  You may obtain a copy of the License at:
85738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
95738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  http://www.apache.org/licenses/LICENSE-2.0
105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  Unless required by applicable law or agreed to in writing, software
125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  distributed under the License is distributed on an "AS IS" BASIS,
135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  See the License for the specific language governing permissions and
155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  limitations under the License.
165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ******************************************************************************/
185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************
205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  this file contains GATT database building and query functions
225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ******************************************************************************/
245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "bt_target.h"
265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if BLE_INCLUDED == TRUE
285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "bt_trace.h"
307fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta#include "bt_utils.h"
315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <stdio.h>
335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <string.h>
345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "gatt_int.h"
355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "l2c_api.h"
365702d5c6197404823f5e594764e2c67cf2416da1Zhihai Xu#include "btm_int.h"
375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/********************************************************************************
395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**              L O C A L    F U N C T I O N     P R O T O T Y P E S            *
405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*********************************************************************************/
415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic BOOLEAN allocate_svc_db_buf(tGATT_SVC_DB *p_db);
427fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Battastatic void *allocate_attr_in_db(tGATT_SVC_DB *p_db, tBT_UUID *p_uuid, tGATT_PERM perm);
435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic BOOLEAN deallocate_attr_in_db(tGATT_SVC_DB *p_db, void *p_attr);
445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic BOOLEAN copy_extra_byte_in_db(tGATT_SVC_DB *p_db, void **p_dst, UINT16 len);
455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
467fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Battastatic BOOLEAN gatts_db_add_service_declaration(tGATT_SVC_DB *p_db, tBT_UUID *p_service, BOOLEAN is_pri);
475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic tGATT_STATUS gatts_send_app_read_request(tGATT_TCB *p_tcb, UINT8 op_code,
485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                                UINT16 handle, UINT16 offset, UINT32 trans_id);
495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         gatts_init_service_db
535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function initialize a memory space to be a service database.
555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Parameter        p_db: database pointer.
575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  len: size of the memory space.
585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          Status of te operation.
605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
627fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi BattaBOOLEAN gatts_init_service_db (tGATT_SVC_DB *p_db, tBT_UUID *p_service,  BOOLEAN is_pri,
635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                               UINT16 s_hdl, UINT16 num_handle)
645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
651a3844f933bd63c8a381371dabfb35c6a0249e3ePavlin Radoslavov    p_db->svc_buffer = fixed_queue_new(SIZE_MAX);
66fe7216ca12f91baae733e7c93063db73121af308Chris Manton
675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (!allocate_svc_db_buf(p_db))
685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
69b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati        GATT_TRACE_ERROR("gatts_init_service_db failed, no resources");
705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return FALSE;
715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
73b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati    GATT_TRACE_DEBUG("gatts_init_service_db");
74b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati    GATT_TRACE_DEBUG("s_hdl = %d num_handle = %d", s_hdl, num_handle );
755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* update service database information */
775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_db->next_handle   = s_hdl;
785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_db->end_handle    = s_hdl + num_handle;
795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
807fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta    return gatts_db_add_service_declaration(p_db, p_service, is_pri);
815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         gatts_init_service_db
865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function initialize a memory space to be a service database.
885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Parameter        p_db: database pointer.
905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  len: size of the memory space.
915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          Status of te operation.
935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjecttBT_UUID * gatts_get_service_uuid (tGATT_SVC_DB *p_db)
965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (!p_db || !p_db->p_attr_list)
985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
99b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati        GATT_TRACE_ERROR("service DB empty");
1005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return NULL;
1025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
1045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
1055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return &((tGATT_ATTR16 *)p_db->p_attr_list)->p_value->uuid;
1065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
1085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
1105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         gatts_check_attr_readability
1125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      check attribute readability
1145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          status of operation.
1165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
1185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic tGATT_STATUS gatts_check_attr_readability(tGATT_ATTR16 *p_attr,
1197fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta                                                 UINT16 offset,
1205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                                 BOOLEAN read_long,
1215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                                 tGATT_SEC_FLAG sec_flag,
1225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                                 UINT8 key_size)
1235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
1245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16          min_key_size;
1255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tGATT_PERM      perm = p_attr->permission;
1265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1277fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta    UNUSED(offset);
1285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    min_key_size = (((perm & GATT_ENCRYPT_KEY_SIZE_MASK) >> 12));
1295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (min_key_size != 0 )
1305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
1315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        min_key_size +=6;
1325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (!(perm & GATT_READ_ALLOWED))
1355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
136b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati        GATT_TRACE_ERROR( "GATT_READ_NOT_PERMIT");
1375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return GATT_READ_NOT_PERMIT;
1385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
140ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    if ((perm & GATT_READ_AUTH_REQUIRED ) && !(sec_flag & GATT_SEC_FLAG_LKEY_UNAUTHED) &&
141ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        !(sec_flag & BTM_SEC_FLAG_ENCRYPTED))
1425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
143b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati        GATT_TRACE_ERROR( "GATT_INSUF_AUTHENTICATION");
1445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return GATT_INSUF_AUTHENTICATION;
1455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((perm & GATT_READ_MITM_REQUIRED ) && !(sec_flag & GATT_SEC_FLAG_LKEY_AUTHED))
1485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
149b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati        GATT_TRACE_ERROR( "GATT_INSUF_AUTHENTICATION: MITM Required");
1505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return GATT_INSUF_AUTHENTICATION;
1515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((perm & GATT_READ_ENCRYPTED_REQUIRED ) && !(sec_flag & GATT_SEC_FLAG_ENCRYPTED))
1545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
155b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati        GATT_TRACE_ERROR( "GATT_INSUF_ENCRYPTION");
1565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return GATT_INSUF_ENCRYPTION;
1575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ( (perm & GATT_READ_ENCRYPTED_REQUIRED) && (sec_flag & GATT_SEC_FLAG_ENCRYPTED) && (key_size < min_key_size))
1605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
161b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati        GATT_TRACE_ERROR( "GATT_INSUF_KEY_SIZE");
1625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return GATT_INSUF_KEY_SIZE;
1635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (read_long)
1675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
1685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        switch (p_attr->uuid)
1695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
1705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            case GATT_UUID_PRI_SERVICE:
1715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            case GATT_UUID_SEC_SERVICE:
1725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            case GATT_UUID_CHAR_DECLARE:
1735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            case GATT_UUID_INCLUDE_SERVICE:
1745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            case GATT_UUID_CHAR_EXT_PROP:
1755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            case GATT_UUID_CHAR_CLIENT_CONFIG:
1765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            case GATT_UUID_CHAR_SRVR_CONFIG:
1775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            case GATT_UUID_CHAR_PRESENT_FORMAT:
178b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati                GATT_TRACE_ERROR("GATT_NOT_LONG");
1795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                return GATT_NOT_LONG;
1805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            default:
1825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                break;
1835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
1845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return GATT_SUCCESS;
1875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
1885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
1905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         read_attr_value
1925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Utility function to read an attribute value.
1945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Parameter        p_attr: pointer to the attribute to read.
1965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  offset: read offset.
1975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  p_value: output parameter to carry out the attribute value.
1985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  p_len: output parameter to carry out the attribute length.
1995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  read_long: this is a read blob request.
2005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  mtu: MTU
2015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  sec_flag: current link security status.
2025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  key_size: encryption key size.
2035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          status of operation.
2055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
2075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic tGATT_STATUS read_attr_value (void *p_attr,
2085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                     UINT16 offset,
2095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                     UINT8 **p_data,
2105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                     BOOLEAN read_long,
2115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                     UINT16 mtu,
2125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                     UINT16 *p_len,
2135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                     tGATT_SEC_FLAG sec_flag,
2145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                     UINT8 key_size)
2155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
2165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16          len = 0, uuid16 = 0;
2175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8           *p = *p_data;
2185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tGATT_STATUS    status;
2195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tGATT_ATTR16    *p_attr16  = (tGATT_ATTR16  *)p_attr;
2205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
221b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati    GATT_TRACE_DEBUG("read_attr_value uuid=0x%04x perm=0x%0x sec_flag=0x%x offset=%d read_long=%d",
2225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                      p_attr16->uuid,
2235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                      p_attr16->permission,
2245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                      sec_flag,
2255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                      offset,
2265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                      read_long);
2275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2287fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta    status = gatts_check_attr_readability((tGATT_ATTR16 *)p_attr, offset, read_long, sec_flag, key_size);
2295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (status != GATT_SUCCESS)
2315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return status;
2325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2337fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta    if (p_attr16->uuid_type == GATT_ATTR_UUID_TYPE_16)
2347fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta        uuid16 = p_attr16->uuid;
2357fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta
2365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    status = GATT_NO_RESOURCES;
2375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (uuid16 == GATT_UUID_PRI_SERVICE || uuid16 == GATT_UUID_SEC_SERVICE)
2395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
2405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        len = p_attr16->p_value->uuid.len;
2415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (mtu >= p_attr16->p_value->uuid.len)
2425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
2435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            gatt_build_uuid_to_stream(&p, p_attr16->p_value->uuid);
2445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            status = GATT_SUCCESS;
2455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
2465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
2475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else if (uuid16 == GATT_UUID_CHAR_DECLARE)
2485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
2495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        len = (((tGATT_ATTR16 *)(p_attr16->p_next))->uuid_type == GATT_ATTR_UUID_TYPE_16) ? 5 :19;
2505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (mtu >= len)
2525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
2535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            UINT8_TO_STREAM(p, p_attr16->p_value->char_decl.property);
2545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            UINT16_TO_STREAM(p, p_attr16->p_value->char_decl.char_val_handle);
2555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (((tGATT_ATTR16 *)(p_attr16->p_next))->uuid_type == GATT_ATTR_UUID_TYPE_16)
2575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
2585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                UINT16_TO_STREAM(p, ((tGATT_ATTR16 *)(p_attr16->p_next))->uuid);
2595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
2607fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta            /* convert a 32bits UUID to 128 bits */
2617fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta            else if (((tGATT_ATTR32 *)(p_attr16->p_next))->uuid_type == GATT_ATTR_UUID_TYPE_32)
2627fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta            {
2637fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta                gatt_convert_uuid32_to_uuid128 (p, ((tGATT_ATTR32 *)(p_attr16->p_next))->uuid);
2647fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta                p += LEN_UUID_128;
2657fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta            }
2665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            else
2675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
2685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                ARRAY_TO_STREAM (p, ((tGATT_ATTR128 *)(p_attr16->p_next))->uuid, LEN_UUID_128);
2695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
2705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            status = GATT_SUCCESS;
2715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
2725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
2745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else if (uuid16 == GATT_UUID_INCLUDE_SERVICE)
2755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
2767fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta        if (p_attr16->p_value->incl_handle.service_type.len == LEN_UUID_16)
2777fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta            len = 6;
2787fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta        else
2797fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta            len = 4;
2807fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta
2815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (mtu >= len)
2825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
2835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            UINT16_TO_STREAM(p, p_attr16->p_value->incl_handle.s_handle);
2845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            UINT16_TO_STREAM(p, p_attr16->p_value->incl_handle.e_handle);
2855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2867fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta            if (p_attr16->p_value->incl_handle.service_type.len == LEN_UUID_16)
2875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
2885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                UINT16_TO_STREAM(p, p_attr16->p_value->incl_handle.service_type.uu.uuid16);
2895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
2905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            status = GATT_SUCCESS;
2915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
2925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
2935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else /* characteristic description or characteristic value */
2945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
2955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        status = GATT_PENDING;
2965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
2975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    *p_len = len;
2995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    *p_data = p;
3005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return status;
3015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
3025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
3045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
3055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         gatts_db_read_attr_value_by_type
3065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
3075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Query attribute value by attribute type.
3085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
3095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Parameter        p_db: pointer to the attribute database.
3105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  p_rsp: Read By type response data.
3115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  s_handle: starting handle of the range we are looking for.
3125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  e_handle: ending handle of the range we are looking for.
3135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  type: Attribute type.
3145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  mtu: MTU.
3155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  sec_flag: current link security status.
3165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  key_size: encryption key size.
3175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
3185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          Status of the operation.
3195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
3205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
3215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjecttGATT_STATUS gatts_db_read_attr_value_by_type (tGATT_TCB   *p_tcb,
3225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                               tGATT_SVC_DB    *p_db,
3235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                               UINT8        op_code,
3245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                               BT_HDR      *p_rsp,
3255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                               UINT16       s_handle,
3265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                               UINT16       e_handle,
3275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                               tBT_UUID     type,
3285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                               UINT16      *p_len,
3295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                               tGATT_SEC_FLAG sec_flag,
3305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                               UINT8        key_size,
3315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                               UINT32       trans_id,
3325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                               UINT16       *p_cur_handle)
3335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
3345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tGATT_STATUS status = GATT_NOT_FOUND;
3355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tGATT_ATTR16  *p_attr;
3365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16      len = 0;
3375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8       *p = (UINT8 *)(p_rsp + 1) + p_rsp->len + L2CAP_MIN_OFFSET;
3385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tBT_UUID    attr_uuid;
3395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_db && p_db->p_attr_list)
3415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
3425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_attr = (tGATT_ATTR16 *)p_db->p_attr_list;
3435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        while (p_attr && p_attr->handle <= e_handle)
3455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
3465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (p_attr->uuid_type == GATT_ATTR_UUID_TYPE_16)
3475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
3485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                attr_uuid.len = LEN_UUID_16;
3495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                attr_uuid.uu.uuid16 = p_attr->uuid;
3505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
3517fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta            else if (p_attr->uuid_type == GATT_ATTR_UUID_TYPE_32)
3527fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta            {
3537fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta                attr_uuid.len = LEN_UUID_32;
3547fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta                attr_uuid.uu.uuid32 = ((tGATT_ATTR32 *)p_attr)->uuid;
3557fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta            }
3565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            else
3575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
3585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                attr_uuid.len = LEN_UUID_128;
3595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                memcpy(attr_uuid.uu.uuid128, ((tGATT_ATTR128 *)p_attr)->uuid, LEN_UUID_128);
3605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
3615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (p_attr->handle >= s_handle && gatt_uuid_compare(type, attr_uuid))
3635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
3645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                if (*p_len <= 2)
3655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
3665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    status = GATT_NO_RESOURCES;
3675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    break;
3685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
3695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                UINT16_TO_STREAM (p, p_attr->handle);
3715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                status = read_attr_value ((void *)p_attr, 0, &p, FALSE, (UINT16)(*p_len -2), &len, sec_flag, key_size);
3735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                if (status == GATT_PENDING)
3755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
3765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    status = gatts_send_app_read_request(p_tcb, op_code, p_attr->handle, 0, trans_id);
3775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    /* one callback at a time */
3795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    break;
3805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
3815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                else if (status == GATT_SUCCESS)
3825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
3835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    if (p_rsp->offset == 0)
3845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        p_rsp->offset = len + 2;
3855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    if (p_rsp->offset == len + 2)
3875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    {
3885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        p_rsp->len += (len  + 2);
3895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        *p_len -= (len + 2);
3905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    }
3915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    else
3925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    {
393b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati                        GATT_TRACE_ERROR("format mismatch");
3945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        status = GATT_NO_RESOURCES;
3955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        break;
3965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    }
3975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
3985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                else
3995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
4005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    *p_cur_handle = p_attr->handle;
4015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    break;
4025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
4035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
4045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_attr = (tGATT_ATTR16 *)p_attr->p_next;
4055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
4065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
4075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4085702d5c6197404823f5e594764e2c67cf2416da1Zhihai Xu#if (defined(BLE_DELAY_REQUEST_ENC) && (BLE_DELAY_REQUEST_ENC == TRUE))
409a5090f2c33919f57c82107ec62ce5ec5705e7e21Prashant Malani    UINT8 flag = 0;
4105702d5c6197404823f5e594764e2c67cf2416da1Zhihai Xu    if (BTM_GetSecurityFlags(p_tcb->peer_bda, &flag))
4115702d5c6197404823f5e594764e2c67cf2416da1Zhihai Xu    {
4125702d5c6197404823f5e594764e2c67cf2416da1Zhihai Xu        if ((p_tcb->att_lcid == L2CAP_ATT_CID) && (status == GATT_PENDING) &&
4135702d5c6197404823f5e594764e2c67cf2416da1Zhihai Xu            (type.uu.uuid16 == GATT_UUID_GAP_DEVICE_NAME))
4145702d5c6197404823f5e594764e2c67cf2416da1Zhihai Xu        {
4155702d5c6197404823f5e594764e2c67cf2416da1Zhihai Xu            if ((flag & (BTM_SEC_LINK_KEY_KNOWN | BTM_SEC_FLAG_ENCRYPTED)) ==
4165702d5c6197404823f5e594764e2c67cf2416da1Zhihai Xu                 BTM_SEC_LINK_KEY_KNOWN)
4175702d5c6197404823f5e594764e2c67cf2416da1Zhihai Xu            {
418a5090f2c33919f57c82107ec62ce5ec5705e7e21Prashant Malani                tACL_CONN *p = btm_bda_to_acl(p_tcb->peer_bda, BT_TRANSPORT_LE);
4195702d5c6197404823f5e594764e2c67cf2416da1Zhihai Xu                if ((p != NULL) && (p->link_role == BTM_ROLE_MASTER))
420a5090f2c33919f57c82107ec62ce5ec5705e7e21Prashant Malani                    btm_ble_set_encryption(p_tcb->peer_bda, BTM_BLE_SEC_ENCRYPT, p->link_role);
4215702d5c6197404823f5e594764e2c67cf2416da1Zhihai Xu            }
4225702d5c6197404823f5e594764e2c67cf2416da1Zhihai Xu        }
4235702d5c6197404823f5e594764e2c67cf2416da1Zhihai Xu    }
4245702d5c6197404823f5e594764e2c67cf2416da1Zhihai Xu#endif
4255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return status;
4265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
4275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
4295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         gatts_add_included_service
4315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function adds an included service into a database.
4335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Parameter        p_db: database pointer.
4355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  inc_srvc_type: included service type.
4365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          Status of the operation.
4385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
4405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjectUINT16 gatts_add_included_service (tGATT_SVC_DB *p_db, UINT16 s_handle, UINT16 e_handle,
4415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                   tBT_UUID service)
4425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
4435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tGATT_ATTR16      *p_attr;
4447fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta    tBT_UUID         uuid = {LEN_UUID_16, {GATT_UUID_INCLUDE_SERVICE}};
4455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
446b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati    GATT_TRACE_DEBUG("gatts_add_included_service: s_hdl = 0x%04x e_hdl = 0x%04x uuid = 0x%04x",
4475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                      s_handle, e_handle, service.uu.uuid16);
4485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (service.len == 0 || s_handle == 0 || e_handle == 0)
4505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
451b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati        GATT_TRACE_ERROR("gatts_add_included_service Illegal Params.");
4525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return 0;
4535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
4545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4557fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta    if ((p_attr = (tGATT_ATTR16 *) allocate_attr_in_db(p_db, &uuid, GATT_PERM_READ)) != NULL)
4565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
4575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (copy_extra_byte_in_db(p_db, (void **)&p_attr->p_value, sizeof(tGATT_INCL_SRVC)))
4585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
4595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_attr->p_value->incl_handle.s_handle = s_handle;
4605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_attr->p_value->incl_handle.e_handle = e_handle;
4615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            memcpy(&p_attr->p_value->incl_handle.service_type, &service, sizeof(tBT_UUID));
4625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return p_attr->handle;
4645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
4655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else
4665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
4675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            deallocate_attr_in_db(p_db, p_attr);
4685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
4695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
4705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return 0;
4725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
4735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
4755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         gatts_add_characteristic
4775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function add a characteristics and its descriptor into
4795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  a servce identified by the service database pointer.
4805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Parameter        p_db: database pointer.
4825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  perm: permission (authentication and key size requirements)
4835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  property: property of the characteristic.
4845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  p_char: characteristic value information.
4855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          Status of te operation.
4875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
4895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjectUINT16 gatts_add_characteristic (tGATT_SVC_DB *p_db, tGATT_PERM perm,
4905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                 tGATT_CHAR_PROP property,
4915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                 tBT_UUID * p_char_uuid)
4925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
4935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tGATT_ATTR16     *p_char_decl, *p_char_val;
4947fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta    tBT_UUID        uuid = {LEN_UUID_16, {GATT_UUID_CHAR_DECLARE}};
4955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
496b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati    GATT_TRACE_DEBUG("gatts_add_characteristic perm=0x%0x property=0x%0x", perm, property);
4975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4987fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta    if ((p_char_decl = (tGATT_ATTR16 *)allocate_attr_in_db(p_db, &uuid, GATT_PERM_READ)) != NULL)
4995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
5005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (!copy_extra_byte_in_db(p_db, (void **)&p_char_decl->p_value, sizeof(tGATT_CHAR_DECL)))
5015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
5025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            deallocate_attr_in_db(p_db, p_char_decl);
5035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return 0;
5045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
5055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5067fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta        p_char_val = (tGATT_ATTR16 *)allocate_attr_in_db(p_db, p_char_uuid, perm);
5075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_char_val == NULL)
5095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
5105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            deallocate_attr_in_db(p_db, p_char_decl);
5115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return 0;
5125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
5135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_char_decl->p_value->char_decl.property = property;
5155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_char_decl->p_value->char_decl.char_val_handle  = p_char_val->handle;
5165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_char_val->p_value = NULL;
5185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return p_char_val->handle;
5205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
5215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return 0;
5235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
5245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
5265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         gatt_convertchar_descr_type
5285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function convert a char descript UUID into descriptor type.
5305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          descriptor type.
5325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
5345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjectUINT8 gatt_convertchar_descr_type(tBT_UUID *p_descr_uuid)
5355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
5365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tBT_UUID std_descr = {LEN_UUID_16, {GATT_UUID_CHAR_EXT_PROP}};
5375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (gatt_uuid_compare(std_descr, * p_descr_uuid))
5395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return GATT_DESCR_EXT_DSCPTOR;
5405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    std_descr.uu.uuid16 ++;
5425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (gatt_uuid_compare(std_descr,  * p_descr_uuid))
5435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return GATT_DESCR_USER_DSCPTOR;
5445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    std_descr.uu.uuid16 ++;
5465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (gatt_uuid_compare(std_descr,  * p_descr_uuid))
5475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return GATT_DESCR_CLT_CONFIG;
5485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    std_descr.uu.uuid16 ++;
5505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (gatt_uuid_compare(std_descr,  * p_descr_uuid))
5515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return GATT_DESCR_SVR_CONFIG;
5525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    std_descr.uu.uuid16 ++;
5545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (gatt_uuid_compare(std_descr,  * p_descr_uuid))
5555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return GATT_DESCR_PRES_FORMAT;
5565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    std_descr.uu.uuid16 ++;
5585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (gatt_uuid_compare(std_descr,  * p_descr_uuid))
5595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return GATT_DESCR_AGGR_FORMAT;
5605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    std_descr.uu.uuid16 ++;
5625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (gatt_uuid_compare(std_descr,  * p_descr_uuid))
5635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return GATT_DESCR_VALID_RANGE;
5645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return GATT_DESCR_UNKNOWN;
5675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
5685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
5705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         gatts_add_char_descr
5725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function add a characteristics descriptor.
5745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Parameter        p_db: database pointer.
5765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  perm: characteristic descriptor permission type.
5775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  char_dscp_tpye: the characteristic descriptor masks.
5785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  p_dscp_params: characteristic descriptors values.
5795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          Status of the operation.
5815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
5835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjectUINT16 gatts_add_char_descr (tGATT_SVC_DB *p_db, tGATT_PERM perm,
5845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                             tBT_UUID *     p_descr_uuid)
5855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
5865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tGATT_ATTR16    *p_char_dscptr;
5875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
588b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati    GATT_TRACE_DEBUG("gatts_add_char_descr uuid=0x%04x", p_descr_uuid->uu.uuid16);
5895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Add characteristic descriptors */
5915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((p_char_dscptr = (tGATT_ATTR16 *)allocate_attr_in_db(p_db,
5927fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta                                                             p_descr_uuid,
5935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                                             perm))
5945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        == NULL)
5955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
596b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati        GATT_TRACE_DEBUG("gatts_add_char_descr Fail for adding char descriptors.");
5975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return 0;
5985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
5995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
6005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
6015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return p_char_dscptr->handle;
6025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
6035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
6045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************/
6065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/* Service Attribute Database Query Utility Functions */
6075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************/
6085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
6095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
6105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         gatts_read_attr_value_by_handle
6115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
6125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Query attribute value by attribute handle.
6135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
6145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Parameter        p_db: pointer to the attribute database.
6155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  handle: Attribute handle to read.
6165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  offset: Read offset.
6175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  p_value: output parameter to carry out the attribute value.
6185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  p_len: output parameter as attribute length read.
6195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  read_long: this is a read blob request.
6205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  mtu: MTU.
6215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  sec_flag: current link security status.
6225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  key_size: encryption key size
6235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
6245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          Status of operation.
6255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
6265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
6275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjecttGATT_STATUS gatts_read_attr_value_by_handle(tGATT_TCB *p_tcb,
6285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                             tGATT_SVC_DB *p_db,
6295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                             UINT8 op_code,
6305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                             UINT16 handle, UINT16 offset,
6315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                             UINT8 *p_value, UINT16 *p_len,
6325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                             UINT16 mtu,
6335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                             tGATT_SEC_FLAG sec_flag,
6345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                             UINT8 key_size,
6355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                             UINT32 trans_id)
6365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
6375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tGATT_STATUS status = GATT_NOT_FOUND;
6385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tGATT_ATTR16  *p_attr;
6395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8       *pp = p_value;
6405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_db && p_db->p_attr_list)
6425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
6435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_attr = (tGATT_ATTR16 *)p_db->p_attr_list;
6445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        while (p_attr && handle >= p_attr->handle)
6465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
6475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (p_attr->handle == handle)
6485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
6495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                status = read_attr_value (p_attr, offset, &pp,
6505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                          (BOOLEAN)(op_code == GATT_REQ_READ_BLOB),
6515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                          mtu, p_len, sec_flag, key_size);
6525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                if (status == GATT_PENDING)
6545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
6555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    status = gatts_send_app_read_request(p_tcb, op_code, p_attr->handle, offset, trans_id);
6565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
6575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                break;
6585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
6595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_attr = (tGATT_ATTR16 *)p_attr->p_next;
6605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
6615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
6625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return status;
6645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
6655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
6675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
6685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         gatts_read_attr_perm_check
6695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
6705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Check attribute readability.
6715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
6725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Parameter        p_db: pointer to the attribute database.
6735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  handle: Attribute handle to read.
6745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  offset: Read offset.
6755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  p_value: output parameter to carry out the attribute value.
6765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  p_len: output parameter as attribute length read.
6775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  read_long: this is a read blob request.
6785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  mtu: MTU.
6795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  sec_flag: current link security status.
6805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  key_size: encryption key size
6815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
6825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          Status of operation.
6835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
6845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
6855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjecttGATT_STATUS gatts_read_attr_perm_check(tGATT_SVC_DB *p_db,
6865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                        BOOLEAN is_long,
6875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                        UINT16 handle,
6885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                        tGATT_SEC_FLAG sec_flag,
6895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                        UINT8 key_size)
6905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
6915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tGATT_STATUS status = GATT_NOT_FOUND;
6925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tGATT_ATTR16  *p_attr;
6935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_db && p_db->p_attr_list)
6955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
6965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_attr = (tGATT_ATTR16 *)p_db->p_attr_list;
6975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        while (p_attr && handle >= p_attr->handle)
6995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
7005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (p_attr->handle == handle)
7015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
7027fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta                status = gatts_check_attr_readability (p_attr, 0,
7035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                                       is_long,
7045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                                       sec_flag, key_size);
7055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                break;
7065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
7075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_attr = (tGATT_ATTR16 *) p_attr->p_next;
7085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
7095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
7105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return status;
7125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
7135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
7145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
7155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         gatts_write_attr_perm_check
7165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
7175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Write attribute value into database.
7185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
7195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Parameter        p_db: pointer to the attribute database.
7205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  op_code:op code of this write.
7215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  handle: handle of the attribute to write.
7225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  offset: Write offset if write op code is write blob.
7235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  p_data: Attribute value to write.
7245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  len: attribute data length.
7255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  sec_flag: current link security status.
7265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  key_size: encryption key size
7275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
7285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          Status of the operation.
7295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
7305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
7315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjecttGATT_STATUS gatts_write_attr_perm_check (tGATT_SVC_DB *p_db, UINT8 op_code,
7325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                          UINT16 handle, UINT16 offset, UINT8 *p_data,
7335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                          UINT16 len, tGATT_SEC_FLAG sec_flag, UINT8 key_size)
7345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
7355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tGATT_STATUS    status = GATT_NOT_FOUND;
7365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tGATT_ATTR16    *p_attr;
7375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16          max_size = 0;
7385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tGATT_PERM      perm;
7395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16          min_key_size;
7405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
741b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati    GATT_TRACE_DEBUG( "gatts_write_attr_perm_check op_code=0x%0x handle=0x%04x offset=%d len=%d sec_flag=0x%0x key_size=%d",
7425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                       op_code, handle, offset, len, sec_flag, key_size);
7435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_db != NULL)
7455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
7465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_attr = (tGATT_ATTR16 *) p_db->p_attr_list;
7475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        while (p_attr != NULL)
7495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
7505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (p_attr->handle == handle)
7515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
7525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                perm = p_attr->permission;
7535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                min_key_size = (((perm & GATT_ENCRYPT_KEY_SIZE_MASK) >> 12));
7545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                if (min_key_size != 0 )
7555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
7565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    min_key_size +=6;
7575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
758b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati                GATT_TRACE_DEBUG( "gatts_write_attr_perm_check p_attr->permission =0x%04x min_key_size==0x%04x",
7595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                   p_attr->permission,
7605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                   min_key_size);
7615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
762ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                if ((op_code == GATT_CMD_WRITE || op_code == GATT_REQ_WRITE)
763ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                    && (perm & GATT_WRITE_SIGNED_PERM))
7645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
7655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    /* use the rules for the mixed security see section 10.2.3*/
766ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                    /* use security mode 1 level 2 when the following condition follows */
767ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                    /* LE security mode 2 level 1 and LE security mode 1 level 2 */
768ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                    if ((perm & GATT_PERM_WRITE_SIGNED) && (perm & GATT_PERM_WRITE_ENCRYPTED))
7695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    {
7705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        perm = GATT_PERM_WRITE_ENCRYPTED;
7715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    }
772ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                    /* use security mode 1 level 3 when the following condition follows */
773ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                    /* LE security mode 2 level 2 and security mode 1 and LE */
774ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                    else if (((perm & GATT_PERM_WRITE_SIGNED_MITM) && (perm & GATT_PERM_WRITE_ENCRYPTED)) ||
775ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                              /* LE security mode 2 and security mode 1 level 3 */
776ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                             ((perm & GATT_WRITE_SIGNED_PERM) && (perm & GATT_PERM_WRITE_ENC_MITM)))
7775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    {
7785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        perm = GATT_PERM_WRITE_ENC_MITM;
7795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    }
7805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
7815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                if ((op_code == GATT_SIGN_CMD_WRITE) && !(perm & GATT_WRITE_SIGNED_PERM))
7835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
7845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    status = GATT_WRITE_NOT_PERMIT;
785b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati                    GATT_TRACE_DEBUG( "gatts_write_attr_perm_check - sign cmd write not allowed");
7865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
7875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                 if ((op_code == GATT_SIGN_CMD_WRITE) && (sec_flag & GATT_SEC_FLAG_ENCRYPTED))
7885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
7895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    status = GATT_INVALID_PDU;
790b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati                    GATT_TRACE_ERROR( "gatts_write_attr_perm_check - Error!! sign cmd write sent on a encypted link");
7915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
7925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                else if (!(perm & GATT_WRITE_ALLOWED))
7935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
7945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    status = GATT_WRITE_NOT_PERMIT;
795b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati                    GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_WRITE_NOT_PERMIT");
7965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
797ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                /* require authentication, but not been authenticated */
7985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                else if ((perm & GATT_WRITE_AUTH_REQUIRED ) && !(sec_flag & GATT_SEC_FLAG_LKEY_UNAUTHED))
7995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
8005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    status = GATT_INSUF_AUTHENTICATION;
801b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati                    GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_INSUF_AUTHENTICATION");
8025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
8035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                else if ((perm & GATT_WRITE_MITM_REQUIRED ) && !(sec_flag & GATT_SEC_FLAG_LKEY_AUTHED))
8045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
8055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    status = GATT_INSUF_AUTHENTICATION;
806b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati                    GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_INSUF_AUTHENTICATION: MITM required");
8075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
8085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                else if ((perm & GATT_WRITE_ENCRYPTED_PERM ) && !(sec_flag & GATT_SEC_FLAG_ENCRYPTED))
8095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
8105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    status = GATT_INSUF_ENCRYPTION;
811b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati                    GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_INSUF_ENCRYPTION");
8125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
8135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                else if ((perm & GATT_WRITE_ENCRYPTED_PERM ) && (sec_flag & GATT_SEC_FLAG_ENCRYPTED) && (key_size < min_key_size))
8145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
8155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    status = GATT_INSUF_KEY_SIZE;
816b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati                    GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_INSUF_KEY_SIZE");
8175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
818ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                /* LE security mode 2 attribute  */
8197fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta                else if (perm & GATT_WRITE_SIGNED_PERM && op_code != GATT_SIGN_CMD_WRITE && !(sec_flag & GATT_SEC_FLAG_ENCRYPTED)
8207fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta                    &&  (perm & GATT_WRITE_ALLOWED) == 0)
821ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                {
822ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                    status = GATT_INSUF_AUTHENTICATION;
823b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati                    GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_INSUF_AUTHENTICATION: LE security mode 2 required");
824ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                }
8255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                else /* writable: must be char value declaration or char descritpors */
8265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
8275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    if(p_attr->uuid_type == GATT_ATTR_UUID_TYPE_16)
8285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    {
8295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    switch (p_attr->uuid)
8305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    {
8315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        case GATT_UUID_CHAR_PRESENT_FORMAT:/* should be readable only */
8325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        case GATT_UUID_CHAR_EXT_PROP:/* should be readable only */
8335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        case GATT_UUID_CHAR_AGG_FORMAT: /* should be readable only */
8345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                            case GATT_UUID_CHAR_VALID_RANGE:
8355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                            status = GATT_WRITE_NOT_PERMIT;
8365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                            break;
8375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        case GATT_UUID_CHAR_CLIENT_CONFIG:
839ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta/* coverity[MISSING_BREAK] */
840ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta/* intnended fall through, ignored */
841ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                            /* fall through */
8425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        case GATT_UUID_CHAR_SRVR_CONFIG:
8435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                            max_size = 2;
8445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        case GATT_UUID_CHAR_DESCRIPTION:
8455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        default: /* any other must be character value declaration */
8465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                            status = GATT_SUCCESS;
8475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                            break;
8485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        }
8495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    }
8507fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta                    else if (p_attr->uuid_type == GATT_ATTR_UUID_TYPE_128 ||
8517fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta				              p_attr->uuid_type == GATT_ATTR_UUID_TYPE_32)
8525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    {
8535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                         status = GATT_SUCCESS;
8545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    }
8555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    else
8565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    {
8575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        status = GATT_INVALID_PDU;
8585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    }
8595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    if (p_data == NULL && len  > 0)
8615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    {
8625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        status = GATT_INVALID_PDU;
8635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    }
8645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    /* these attribute does not allow write blob */
8655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    else if ( (p_attr->uuid_type == GATT_ATTR_UUID_TYPE_16) &&
8665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                              (p_attr->uuid == GATT_UUID_CHAR_CLIENT_CONFIG ||
8675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                               p_attr->uuid == GATT_UUID_CHAR_SRVR_CONFIG) )
8685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    {
8695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        if (op_code == GATT_REQ_PREPARE_WRITE && offset != 0) /* does not allow write blob */
8705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        {
8715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                            status = GATT_NOT_LONG;
872b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati                            GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_NOT_LONG");
8735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        }
8745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        else if (len != max_size)    /* data does not match the required format */
8755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        {
876ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                            status = GATT_INVALID_ATTR_LEN;
877b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati                            GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_INVALID_PDU");
8785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        }
8795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        else
8805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        {
8815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                            status = GATT_SUCCESS;
8825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        }
8835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    }
8845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
8855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                break;
8865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
8875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            else
8885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_attr = (tGATT_ATTR16 *)p_attr->p_next;
8895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
8905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
8915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return status;
8935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
8945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
8965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
8975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         allocate_attr_in_db
8985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
8995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Allocate a memory space for a new attribute, and link this
9005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  attribute into the database attribute list.
9015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
9025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
9035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Parameter        p_db    : database pointer.
9047fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta**                  p_uuid:     pointer to attribute UUID
9055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  service : type of attribute to be added.
9065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
9075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          pointer to the newly allocated attribute.
9085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
9095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
9107fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Battastatic void *allocate_attr_in_db(tGATT_SVC_DB *p_db, tBT_UUID *p_uuid, tGATT_PERM perm)
9115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
9125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tGATT_ATTR16    *p_attr16 = NULL, *p_last;
9137fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta    tGATT_ATTR32    *p_attr32 = NULL;
9145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tGATT_ATTR128   *p_attr128 = NULL;
9157fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta    UINT16      len = sizeof(tGATT_ATTR128);
9165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9177fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta    if (p_uuid == NULL)
9185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
919b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati        GATT_TRACE_ERROR("illegal UUID");
9205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return NULL;
9215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
9225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9237fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta    if (p_uuid->len == LEN_UUID_16)
9247fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta        len = sizeof(tGATT_ATTR16);
9257fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta    else if (p_uuid->len == LEN_UUID_32)
9267fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta        len = sizeof(tGATT_ATTR32);
9277fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta
928b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati    GATT_TRACE_DEBUG("allocate attr %d bytes ",len);
9297fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta
9305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_db->end_handle <= p_db->next_handle)
9315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
932b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati        GATT_TRACE_DEBUG("handle space full. handle_max = %d next_handle = %d",
9335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                          p_db->end_handle, p_db->next_handle);
9345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return NULL;
9355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
9365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_db->mem_free < len)
9385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
9395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (!allocate_svc_db_buf(p_db))
9405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
941b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati            GATT_TRACE_ERROR("allocate_attr_in_db failed, no resources");
9425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return NULL;
9435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
9445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
9457fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta    memset(p_db->p_free_mem, 0, len);
9465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_attr16 = (tGATT_ATTR16 *) p_db->p_free_mem;
9475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9487fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta    if (p_uuid->len == LEN_UUID_16 && p_uuid->uu.uuid16 != GATT_ILLEGAL_UUID)
9495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
9505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_attr16->uuid_type = GATT_ATTR_UUID_TYPE_16;
9517fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta        p_attr16->uuid = p_uuid->uu.uuid16;
9525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
9537fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta    else if (p_uuid->len == LEN_UUID_32)
9545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
9557fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta        p_attr32 = (tGATT_ATTR32 *) p_db->p_free_mem;
9567fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta        p_attr32->uuid_type = GATT_ATTR_UUID_TYPE_32;
9577fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta        p_attr32->uuid = p_uuid->uu.uuid32;
9587fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta    }
9597fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta    else if (p_uuid->len == LEN_UUID_128)
9607fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta    {
9617fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta        p_attr128 = (tGATT_ATTR128 *) p_db->p_free_mem;
9625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_attr128->uuid_type = GATT_ATTR_UUID_TYPE_128;
9637fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta        memcpy(p_attr128->uuid, p_uuid->uu.uuid128, LEN_UUID_128);
9645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
9655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_db->p_free_mem += len;
9675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_db->mem_free -= len;
9685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_attr16->handle = p_db->next_handle++;
9705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_attr16->permission = perm;
9715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_attr16->p_next = NULL;
9725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* link the attribute record into the end of DB */
9745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_db->p_attr_list == NULL)
9755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_db->p_attr_list = p_attr16;
9765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
9775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
9785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_last = (tGATT_ATTR16 *)p_db->p_attr_list;
9795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        while (p_last != NULL && p_last->p_next != NULL)
9815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_last = (tGATT_ATTR16 *)p_last->p_next;
9825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_last->p_next = p_attr16;
9845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
9855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_attr16->uuid_type == GATT_ATTR_UUID_TYPE_16)
9875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
988b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati        GATT_TRACE_DEBUG("=====> handle = [0x%04x] uuid16 = [0x%04x] perm=0x%02x ",
9895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                          p_attr16->handle, p_attr16->uuid, p_attr16->permission);
9905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
9917fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta    else if (p_attr16->uuid_type == GATT_ATTR_UUID_TYPE_32)
9927fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta    {
993b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati        GATT_TRACE_DEBUG("=====> handle = [0x%04x] uuid32 = [0x%08x] perm=0x%02x ",
9947fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta                          p_attr32->handle, p_attr32->uuid, p_attr32->permission);
9957fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta    }
9965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
9975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
998b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati        GATT_TRACE_DEBUG("=====> handle = [0x%04x] uuid128 = [0x%02x:0x%02x] perm=0x%02x ",
9995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                          p_attr128->handle, p_attr128->uuid[0],p_attr128->uuid[1],
10005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                          p_attr128->permission);
10015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
10025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return(void *)p_attr16;
10035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
10045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
10065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
10075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         deallocate_attr_in_db
10085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
10095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Free an attribute within the database.
10105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
10115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Parameter        p_db: database pointer.
10125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  p_attr: pointer to the attribute record to be freed.
10135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
10145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          BOOLEAN: success
10155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
10165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
10175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic BOOLEAN deallocate_attr_in_db(tGATT_SVC_DB *p_db, void *p_attr)
10185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
10195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tGATT_ATTR16  *p_cur, *p_next;
10205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BOOLEAN     found = FALSE;
10215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_db->p_attr_list == NULL)
10235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return found;
10245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_cur   = (tGATT_ATTR16 *) p_db->p_attr_list;
10265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_next  = (tGATT_ATTR16 *) p_cur->p_next;
10275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    for (; p_cur != NULL && p_next != NULL;
10295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_cur = p_next, p_next = (tGATT_ATTR16 *)p_next->p_next)
10305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
10315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_next == p_attr)
10325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
10335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_cur->p_next = p_next->p_next;
10345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            found = TRUE;
10355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
10365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
10375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cur == p_attr && p_cur == p_db->p_attr_list)
10385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
10395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_db->p_attr_list = p_cur->p_next;
10405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        found = TRUE;
10415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
10425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* else attr not found */
10435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ( found)
10445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_db->next_handle --;
10455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return found;
10475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
10485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
10505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
10515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         copy_extra_byte_in_db
10525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
10535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Utility function to allocate extra bytes memory in DB and copy
10545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  the value from a source place.
10555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
10565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
10575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Parameter        p_db: database pointer.
10585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  p_dst: destination data pointer.
10595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  p_src: source data pointer.
10605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  len: data length to be copied.
10615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
10625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          None.
10635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
10645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
10655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic BOOLEAN copy_extra_byte_in_db(tGATT_SVC_DB *p_db, void **p_dst, UINT16 len)
10665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
10675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8 *p = (UINT8 *)*p_dst;
10685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_db->mem_free < len)
10705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
10715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (!allocate_svc_db_buf(p_db))
10725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
1073b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati            GATT_TRACE_ERROR("copy_extra_byte_in_db failed, no resources");
10745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return FALSE;
10755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
10765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
10775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p = p_db->p_free_mem;
10795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_db->p_free_mem += len;
10805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_db->mem_free -= len;
10815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    memset((void *)p, 0, len);
10825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    *p_dst = (void *)p;
10835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return TRUE;
10855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
10865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
10885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
10895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         allocate_svc_db_buf
10905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
10915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Utility function to allocate extra buffer for service database.
10925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
10935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          TRUE if allocation succeed, otherwise FALSE.
10945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
10955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
10965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic BOOLEAN allocate_svc_db_buf(tGATT_SVC_DB *p_db)
10975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
10985fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov    BT_HDR *p_buf = (BT_HDR *)osi_calloc(GATT_DB_BUF_SIZE);
10995fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov
110020524d393e8b3bea4c573f7980cd843500b0e6a4Pavlin Radoslavov    GATT_TRACE_DEBUG("%s allocating extra buffer", __func__);
11015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
110220524d393e8b3bea4c573f7980cd843500b0e6a4Pavlin Radoslavov    p_db->p_free_mem = (UINT8 *) p_buf;
110320524d393e8b3bea4c573f7980cd843500b0e6a4Pavlin Radoslavov    p_db->mem_free = GATT_DB_BUF_SIZE;
11045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11051a3844f933bd63c8a381371dabfb35c6a0249e3ePavlin Radoslavov    fixed_queue_enqueue(p_db->svc_buffer, p_buf);
11065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return TRUE;
11085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
11105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
11125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
11135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         gatts_send_app_read_request
11145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
11155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Send application read request callback
11165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
11175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          status of operation.
11185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
11195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
11205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic tGATT_STATUS gatts_send_app_read_request(tGATT_TCB *p_tcb, UINT8 op_code,
11215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                                UINT16 handle, UINT16 offset, UINT32 trans_id)
11225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
11235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tGATTS_DATA   sr_data;
11245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8       i_rcb;
11255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tGATT_SR_REG *p_sreg;
11265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16   conn_id;
11275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    i_rcb = gatt_sr_find_i_rcb_by_handle(handle);
11295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_sreg = &gatt_cb.sr_reg[i_rcb];
11305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    conn_id = GATT_CREATE_CONN_ID(p_tcb->tcb_idx, p_sreg->gatt_if);
11315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (trans_id == 0)
11335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
11345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        trans_id = gatt_sr_enqueue_cmd(p_tcb, op_code, handle);
11355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        gatt_sr_update_cback_cnt(p_tcb, p_sreg->gatt_if, TRUE, TRUE);
11365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
11375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (trans_id != 0 )
11395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
11405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        memset(&sr_data, 0, sizeof(tGATTS_DATA));
11415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        sr_data.read_req.handle = handle;
11435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        sr_data.read_req.is_long = (BOOLEAN)(op_code == GATT_REQ_READ_BLOB);
11445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        sr_data.read_req.offset = offset;
11455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        gatt_sr_send_req_callback(conn_id,
11475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                  trans_id, GATTS_REQ_TYPE_READ, &sr_data);
11485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return(tGATT_STATUS) GATT_PENDING;
11495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
11505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
11515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return(tGATT_STATUS) GATT_BUSY; /* max pending command, application error */
11525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
11545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
11565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
11575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         gatts_db_add_service_declaration
11585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
11595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Update a service database service declaration record.
11605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
11615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Parameter        p_db: database pointer.
11625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  service: UUID of the service.
11635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
11645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
11655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
11665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
11677fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Battastatic BOOLEAN gatts_db_add_service_declaration(tGATT_SVC_DB *p_db, tBT_UUID *p_service, BOOLEAN is_pri)
11685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
11695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tGATT_ATTR16  *p_attr;
11707fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta    tBT_UUID    uuid = {LEN_UUID_16, {0}};
11717fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta    BOOLEAN     rt = FALSE;
11725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1173b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati    GATT_TRACE_DEBUG( "add_service_declaration");
11745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11757fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta    if (is_pri)
11767fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta        uuid.uu.uuid16 = GATT_UUID_PRI_SERVICE;
11777fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta    else
11787fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta        uuid.uu.uuid16 = GATT_UUID_SEC_SERVICE;
11797fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta
11805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* add service declration record */
11817fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta    if ((p_attr = (tGATT_ATTR16 *)(allocate_attr_in_db(p_db, &uuid, GATT_PERM_READ))) != NULL)
11825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
11835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (copy_extra_byte_in_db (p_db, (void **)&p_attr->p_value, sizeof(tBT_UUID)))
11845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
11857fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta            if (p_service->len == LEN_UUID_16)
11867fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta            {
11877fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta                p_attr->p_value->uuid.len = LEN_UUID_16;
11887fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta                p_attr->p_value->uuid.uu.uuid16 = p_service->uu.uuid16;
11897fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta            }
11907fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta            else if (p_service->len == LEN_UUID_32)
11917fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta            {
11927fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta                p_attr->p_value->uuid.len = LEN_UUID_128;
11937fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta                gatt_convert_uuid32_to_uuid128(p_attr->p_value->uuid.uu.uuid128, p_service->uu.uuid32);
11947fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta            }
11957fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta            else
11967fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta            {
11977fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta                p_attr->p_value->uuid.len = LEN_UUID_128;
11987fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta                memcpy(p_attr->p_value->uuid.uu.uuid128, p_service->uu.uuid128, LEN_UUID_128);
11997fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta            }
12007fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta            rt = TRUE;
12015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
12027fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta
12035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
12047fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta    return rt;
12055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
12065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
12075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif /* BLE_INCLUDED */
1208