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"
305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <stdio.h>
325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <string.h>
335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "gatt_int.h"
345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "l2c_api.h"
355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/********************************************************************************
375738f83aeb59361a0a2eda2460113f6dc919427The 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            *
385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*********************************************************************************/
395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic BOOLEAN allocate_svc_db_buf(tGATT_SVC_DB *p_db);
405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void *allocate_attr_in_db(tGATT_SVC_DB *p_db, UINT16 uuid16, UINT8 *p_uuid128, tGATT_PERM perm);
415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic BOOLEAN deallocate_attr_in_db(tGATT_SVC_DB *p_db, void *p_attr);
425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic BOOLEAN copy_extra_byte_in_db(tGATT_SVC_DB *p_db, void **p_dst, UINT16 len);
435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void gatts_db_add_service_declaration(tGATT_SVC_DB *p_db, tBT_UUID service, BOOLEAN is_pri);
455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic tGATT_STATUS gatts_send_app_read_request(tGATT_TCB *p_tcb, UINT8 op_code,
465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                                UINT16 handle, UINT16 offset, UINT32 trans_id);
475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         gatts_init_service_db
515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function initialize a memory space to be a service database.
535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Parameter        p_db: database pointer.
555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  len: size of the memory space.
565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          Status of te operation.
585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjectBOOLEAN gatts_init_service_db (tGATT_SVC_DB *p_db, tBT_UUID service,  BOOLEAN is_pri,
615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                               UINT16 s_hdl, UINT16 num_handle)
625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (!allocate_svc_db_buf(p_db))
645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        GATT_TRACE_ERROR0("gatts_init_service_db failed, no resources");
665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return FALSE;
675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    GATT_TRACE_DEBUG0("gatts_init_service_db");
705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    GATT_TRACE_DEBUG2("s_hdl = %d num_handle = %d", s_hdl, num_handle );
715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* update service database information */
735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_db->next_handle   = s_hdl;
745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_db->end_handle    = s_hdl + num_handle;
755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    gatts_db_add_service_declaration(p_db, service, is_pri);
775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return TRUE;
795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         gatts_init_service_db
845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function initialize a memory space to be a service database.
865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Parameter        p_db: database pointer.
885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  len: size of the memory space.
895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          Status of te operation.
915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjecttBT_UUID * gatts_get_service_uuid (tGATT_SVC_DB *p_db)
945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (!p_db || !p_db->p_attr_list)
965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        GATT_TRACE_ERROR0("service DB empty");
985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return NULL;
1005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
1025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
1035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return &((tGATT_ATTR16 *)p_db->p_attr_list)->p_value->uuid;
1045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
1065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
1085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         gatts_check_attr_readability
1105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      check attribute readability
1125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          status of operation.
1145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
1165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic tGATT_STATUS gatts_check_attr_readability(tGATT_ATTR16 *p_attr,
1175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                                 UINT16 offset,
1185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                                 BOOLEAN read_long,
1195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                                 tGATT_SEC_FLAG sec_flag,
1205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                                 UINT8 key_size)
1215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
1225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16          min_key_size;
1235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tGATT_PERM      perm = p_attr->permission;
1245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    min_key_size = (((perm & GATT_ENCRYPT_KEY_SIZE_MASK) >> 12));
1265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (min_key_size != 0 )
1275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
1285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        min_key_size +=6;
1295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (!(perm & GATT_READ_ALLOWED))
1325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
1335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        GATT_TRACE_ERROR0( "GATT_READ_NOT_PERMIT");
1345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return GATT_READ_NOT_PERMIT;
1355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
137ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    if ((perm & GATT_READ_AUTH_REQUIRED ) && !(sec_flag & GATT_SEC_FLAG_LKEY_UNAUTHED) &&
138ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        !(sec_flag & BTM_SEC_FLAG_ENCRYPTED))
1395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
1405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        GATT_TRACE_ERROR0( "GATT_INSUF_AUTHENTICATION");
1415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return GATT_INSUF_AUTHENTICATION;
1425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((perm & GATT_READ_MITM_REQUIRED ) && !(sec_flag & GATT_SEC_FLAG_LKEY_AUTHED))
1455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
1465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        GATT_TRACE_ERROR0( "GATT_INSUF_AUTHENTICATION: MITM Required");
1475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return GATT_INSUF_AUTHENTICATION;
1485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((perm & GATT_READ_ENCRYPTED_REQUIRED ) && !(sec_flag & GATT_SEC_FLAG_ENCRYPTED))
1515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
1525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        GATT_TRACE_ERROR0( "GATT_INSUF_ENCRYPTION");
1535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return GATT_INSUF_ENCRYPTION;
1545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ( (perm & GATT_READ_ENCRYPTED_REQUIRED) && (sec_flag & GATT_SEC_FLAG_ENCRYPTED) && (key_size < min_key_size))
1575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
1585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        GATT_TRACE_ERROR0( "GATT_INSUF_KEY_SIZE");
1595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return GATT_INSUF_KEY_SIZE;
1605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (read_long)
1645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
1655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        switch (p_attr->uuid)
1665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
1675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            case GATT_UUID_PRI_SERVICE:
1685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            case GATT_UUID_SEC_SERVICE:
1695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            case GATT_UUID_CHAR_DECLARE:
1705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            case GATT_UUID_INCLUDE_SERVICE:
1715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            case GATT_UUID_CHAR_EXT_PROP:
1725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            case GATT_UUID_CHAR_CLIENT_CONFIG:
1735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            case GATT_UUID_CHAR_SRVR_CONFIG:
1745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            case GATT_UUID_CHAR_PRESENT_FORMAT:
1755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                GATT_TRACE_ERROR0("GATT_NOT_LONG");
1765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                return GATT_NOT_LONG;
1775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            default:
1795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                break;
1805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
1815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return GATT_SUCCESS;
1845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
1855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
1875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         read_attr_value
1895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Utility function to read an attribute value.
1915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Parameter        p_attr: pointer to the attribute to read.
1935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  offset: read offset.
1945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  p_value: output parameter to carry out the attribute value.
1955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  p_len: output parameter to carry out the attribute length.
1965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  read_long: this is a read blob request.
1975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  mtu: MTU
1985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  sec_flag: current link security status.
1995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  key_size: encryption key size.
2005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          status of operation.
2025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
2045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic tGATT_STATUS read_attr_value (void *p_attr,
2055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                     UINT16 offset,
2065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                     UINT8 **p_data,
2075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                     BOOLEAN read_long,
2085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                     UINT16 mtu,
2095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                     UINT16 *p_len,
2105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                     tGATT_SEC_FLAG sec_flag,
2115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                     UINT8 key_size)
2125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
2135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16          len = 0, uuid16 = 0;
2145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8           *p = *p_data;
2155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tGATT_STATUS    status;
2165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16          read_long_uuid=0;
2175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tGATT_ATTR16    *p_attr16  = (tGATT_ATTR16  *)p_attr;
2185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    GATT_TRACE_DEBUG5("read_attr_value uuid=0x%04x perm=0x%0x sec_flag=0x%x offset=%d read_long=%d",
2205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                      p_attr16->uuid,
2215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                      p_attr16->permission,
2225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                      sec_flag,
2235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                      offset,
2245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                      read_long);
2255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    status = gatts_check_attr_readability((tGATT_ATTR16 *)p_attr, offset, read_long, sec_flag, key_size);
2275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_attr16->uuid_type == GATT_ATTR_UUID_TYPE_16)
2295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        uuid16 = p_attr16->uuid;
2305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (status != GATT_SUCCESS)
2325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return status;
2335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    status = GATT_NO_RESOURCES;
2355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (read_long &&
2375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        (uuid16 == GATT_UUID_CHAR_DESCRIPTION || uuid16 == GATT_UUID_CHAR_AGG_FORMAT))
2385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
2395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        read_long_uuid = p_attr16->uuid;
2405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
2415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (uuid16 == GATT_UUID_PRI_SERVICE || uuid16 == GATT_UUID_SEC_SERVICE)
2435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
2445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        len = p_attr16->p_value->uuid.len;
2455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (mtu >= p_attr16->p_value->uuid.len)
2465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
2475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            gatt_build_uuid_to_stream(&p, p_attr16->p_value->uuid);
2485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            status = GATT_SUCCESS;
2495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
2505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
2515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else if (uuid16 == GATT_UUID_CHAR_DECLARE)
2525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
2535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        len = (((tGATT_ATTR16 *)(p_attr16->p_next))->uuid_type == GATT_ATTR_UUID_TYPE_16) ? 5 :19;
2545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (mtu >= len)
2565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
2575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            UINT8_TO_STREAM(p, p_attr16->p_value->char_decl.property);
2585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            UINT16_TO_STREAM(p, p_attr16->p_value->char_decl.char_val_handle);
2595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (((tGATT_ATTR16 *)(p_attr16->p_next))->uuid_type == GATT_ATTR_UUID_TYPE_16)
2615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
2625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                UINT16_TO_STREAM(p, ((tGATT_ATTR16 *)(p_attr16->p_next))->uuid);
2635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
2645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            else
2655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
2665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                ARRAY_TO_STREAM (p, ((tGATT_ATTR128 *)(p_attr16->p_next))->uuid, LEN_UUID_128);
2675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
2685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            status = GATT_SUCCESS;
2695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
2705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
2725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else if (uuid16 == GATT_UUID_INCLUDE_SERVICE)
2735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
2745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        len = (p_attr16->p_value->incl_handle.service_type.len == 2) ? 6 : 4;
2755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (mtu >= len)
2765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
2775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            UINT16_TO_STREAM(p, p_attr16->p_value->incl_handle.s_handle);
2785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            UINT16_TO_STREAM(p, p_attr16->p_value->incl_handle.e_handle);
2795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (p_attr16->p_value->incl_handle.service_type.len == 2)
2815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
2825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                UINT16_TO_STREAM(p, p_attr16->p_value->incl_handle.service_type.uu.uuid16);
2835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
2845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            status = GATT_SUCCESS;
2855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
2865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
2875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else /* characteristic description or characteristic value */
2885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
2895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        status = GATT_PENDING;
2905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
2915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    *p_len = len;
2935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    *p_data = p;
2945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return status;
2955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
2965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
2985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         gatts_db_read_attr_value_by_type
3005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
3015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Query attribute value by attribute type.
3025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
3035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Parameter        p_db: pointer to the attribute database.
3045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  p_rsp: Read By type response data.
3055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  s_handle: starting handle of the range we are looking for.
3065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  e_handle: ending handle of the range we are looking for.
3075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  type: Attribute type.
3085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  mtu: MTU.
3095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  sec_flag: current link security status.
3105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  key_size: encryption key size.
3115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
3125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          Status of the operation.
3135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
3145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
3155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjecttGATT_STATUS gatts_db_read_attr_value_by_type (tGATT_TCB   *p_tcb,
3165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                               tGATT_SVC_DB    *p_db,
3175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                               UINT8        op_code,
3185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                               BT_HDR      *p_rsp,
3195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                               UINT16       s_handle,
3205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                               UINT16       e_handle,
3215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                               tBT_UUID     type,
3225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                               UINT16      *p_len,
3235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                               tGATT_SEC_FLAG sec_flag,
3245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                               UINT8        key_size,
3255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                               UINT32       trans_id,
3265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                               UINT16       *p_cur_handle)
3275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
3285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tGATT_STATUS status = GATT_NOT_FOUND;
3295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tGATT_ATTR16  *p_attr;
3305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16      len = 0;
3315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8       *p = (UINT8 *)(p_rsp + 1) + p_rsp->len + L2CAP_MIN_OFFSET;
3325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tBT_UUID    attr_uuid;
3335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_db && p_db->p_attr_list)
3355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
3365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_attr = (tGATT_ATTR16 *)p_db->p_attr_list;
3375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        while (p_attr && p_attr->handle <= e_handle)
3395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
3405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (p_attr->uuid_type == GATT_ATTR_UUID_TYPE_16)
3415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
3425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                attr_uuid.len = LEN_UUID_16;
3435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                attr_uuid.uu.uuid16 = p_attr->uuid;
3445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
3455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            else
3465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
3475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                attr_uuid.len = LEN_UUID_128;
3485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                memcpy(attr_uuid.uu.uuid128, ((tGATT_ATTR128 *)p_attr)->uuid, LEN_UUID_128);
3495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
3505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (p_attr->handle >= s_handle && gatt_uuid_compare(type, attr_uuid))
3525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
3535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                if (*p_len <= 2)
3545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
3555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    status = GATT_NO_RESOURCES;
3565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    break;
3575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
3585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                UINT16_TO_STREAM (p, p_attr->handle);
3605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                status = read_attr_value ((void *)p_attr, 0, &p, FALSE, (UINT16)(*p_len -2), &len, sec_flag, key_size);
3625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                if (status == GATT_PENDING)
3645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
3655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    status = gatts_send_app_read_request(p_tcb, op_code, p_attr->handle, 0, trans_id);
3665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    /* one callback at a time */
3685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    break;
3695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
3705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                else if (status == GATT_SUCCESS)
3715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
3725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    if (p_rsp->offset == 0)
3735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        p_rsp->offset = len + 2;
3745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    if (p_rsp->offset == len + 2)
3765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    {
3775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        p_rsp->len += (len  + 2);
3785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        *p_len -= (len + 2);
3795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    }
3805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    else
3815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    {
3825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        GATT_TRACE_ERROR0("format mismatch");
3835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        status = GATT_NO_RESOURCES;
3845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        break;
3855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    }
3865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
3875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                else
3885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
3895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    *p_cur_handle = p_attr->handle;
3905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    break;
3915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
3925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
3935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_attr = (tGATT_ATTR16 *)p_attr->p_next;
3945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
3955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
3965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return status;
3985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
3995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
4015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         gatts_add_included_service
4035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function adds an included service into a database.
4055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Parameter        p_db: database pointer.
4075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  inc_srvc_type: included service type.
4085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          Status of the operation.
4105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
4125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjectUINT16 gatts_add_included_service (tGATT_SVC_DB *p_db, UINT16 s_handle, UINT16 e_handle,
4135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                   tBT_UUID service)
4145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
4155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tGATT_ATTR16      *p_attr;
4165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    GATT_TRACE_DEBUG3("gatts_add_included_service: s_hdl = 0x%04x e_hdl = 0x%04x uuid = 0x%04x",
4185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                      s_handle, e_handle, service.uu.uuid16);
4195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (service.len == 0 || s_handle == 0 || e_handle == 0)
4215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
4225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        GATT_TRACE_ERROR0("gatts_add_included_service Illegal Params.");
4235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return 0;
4245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
4255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((p_attr = (tGATT_ATTR16 *) allocate_attr_in_db(p_db, GATT_UUID_INCLUDE_SERVICE, NULL, GATT_PERM_READ)) != NULL)
4275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
4285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (copy_extra_byte_in_db(p_db, (void **)&p_attr->p_value, sizeof(tGATT_INCL_SRVC)))
4295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
4305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_attr->p_value->incl_handle.s_handle = s_handle;
4315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_attr->p_value->incl_handle.e_handle = e_handle;
4325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            memcpy(&p_attr->p_value->incl_handle.service_type, &service, sizeof(tBT_UUID));
4335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return p_attr->handle;
4355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
4365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else
4375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
4385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            deallocate_attr_in_db(p_db, p_attr);
4395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
4405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
4415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return 0;
4435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
4445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
4465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         gatts_add_characteristic
4485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function add a characteristics and its descriptor into
4505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  a servce identified by the service database pointer.
4515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Parameter        p_db: database pointer.
4535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  perm: permission (authentication and key size requirements)
4545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  property: property of the characteristic.
4555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  p_char: characteristic value information.
4565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          Status of te operation.
4585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
4605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjectUINT16 gatts_add_characteristic (tGATT_SVC_DB *p_db, tGATT_PERM perm,
4615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                 tGATT_CHAR_PROP property,
4625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                 tBT_UUID * p_char_uuid)
4635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
4645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tGATT_ATTR16     *p_char_decl, *p_char_val;
4655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16          uuid16 = (p_char_uuid->len == LEN_UUID_16) ? p_char_uuid->uu.uuid16 : 0;
4665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    GATT_TRACE_DEBUG2("gatts_add_characteristic perm=0x%0x property=0x%0x", perm, property);
4685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((p_char_decl = (tGATT_ATTR16 *)allocate_attr_in_db(p_db, GATT_UUID_CHAR_DECLARE, NULL, GATT_PERM_READ)) != NULL)
4705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
4715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (!copy_extra_byte_in_db(p_db, (void **)&p_char_decl->p_value, sizeof(tGATT_CHAR_DECL)))
4725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
4735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            deallocate_attr_in_db(p_db, p_char_decl);
4745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return 0;
4755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
4765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_char_val = (tGATT_ATTR16 *)allocate_attr_in_db(p_db, uuid16, p_char_uuid->uu.uuid128, perm);
4785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_char_val == NULL)
4805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
4815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            deallocate_attr_in_db(p_db, p_char_decl);
4825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return 0;
4835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
4845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_char_decl->p_value->char_decl.property = property;
4865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_char_decl->p_value->char_decl.char_val_handle  = p_char_val->handle;
4875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_char_val->p_value = NULL;
4895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return p_char_val->handle;
4915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
4925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return 0;
4945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
4955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
4975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         gatt_convertchar_descr_type
4995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function convert a char descript UUID into descriptor type.
5015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          descriptor type.
5035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
5055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjectUINT8 gatt_convertchar_descr_type(tBT_UUID *p_descr_uuid)
5065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
5075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tBT_UUID std_descr = {LEN_UUID_16, {GATT_UUID_CHAR_EXT_PROP}};
5085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (gatt_uuid_compare(std_descr, * p_descr_uuid))
5105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return GATT_DESCR_EXT_DSCPTOR;
5115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    std_descr.uu.uuid16 ++;
5135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (gatt_uuid_compare(std_descr,  * p_descr_uuid))
5145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return GATT_DESCR_USER_DSCPTOR;
5155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    std_descr.uu.uuid16 ++;
5175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (gatt_uuid_compare(std_descr,  * p_descr_uuid))
5185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return GATT_DESCR_CLT_CONFIG;
5195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    std_descr.uu.uuid16 ++;
5215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (gatt_uuid_compare(std_descr,  * p_descr_uuid))
5225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return GATT_DESCR_SVR_CONFIG;
5235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    std_descr.uu.uuid16 ++;
5255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (gatt_uuid_compare(std_descr,  * p_descr_uuid))
5265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return GATT_DESCR_PRES_FORMAT;
5275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    std_descr.uu.uuid16 ++;
5295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (gatt_uuid_compare(std_descr,  * p_descr_uuid))
5305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return GATT_DESCR_AGGR_FORMAT;
5315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    std_descr.uu.uuid16 ++;
5335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (gatt_uuid_compare(std_descr,  * p_descr_uuid))
5345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return GATT_DESCR_VALID_RANGE;
5355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return GATT_DESCR_UNKNOWN;
5385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
5395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
5415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         gatts_add_char_descr
5435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function add a characteristics descriptor.
5455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Parameter        p_db: database pointer.
5475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  perm: characteristic descriptor permission type.
5485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  char_dscp_tpye: the characteristic descriptor masks.
5495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  p_dscp_params: characteristic descriptors values.
5505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          Status of the operation.
5525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
5545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjectUINT16 gatts_add_char_descr (tGATT_SVC_DB *p_db, tGATT_PERM perm,
5555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                             tBT_UUID *     p_descr_uuid)
5565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
5575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tGATT_ATTR16    *p_char_dscptr;
5585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16    uuid16  = (p_descr_uuid->len == LEN_UUID_16)? p_descr_uuid->uu.uuid16 : 0;
5595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    GATT_TRACE_DEBUG1("gatts_add_char_descr uuid=0x%04x", p_descr_uuid->uu.uuid16);
5615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Add characteristic descriptors */
5635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((p_char_dscptr = (tGATT_ATTR16 *)allocate_attr_in_db(p_db,
5645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                                             uuid16,
5655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                                             p_descr_uuid->uu.uuid128,
5665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                                             perm))
5675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        == NULL)
5685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
5695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        GATT_TRACE_DEBUG0("gatts_add_char_descr Fail for adding char descriptors.");
5705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return 0;
5715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
5725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
5735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
5745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return p_char_dscptr->handle;
5755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
5765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
5775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************/
5795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/* Service Attribute Database Query Utility Functions */
5805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************/
5815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
5825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         gatts_read_attr_value_by_handle
5845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Query attribute value by attribute handle.
5865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Parameter        p_db: pointer to the attribute database.
5885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  handle: Attribute handle to read.
5895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  offset: Read offset.
5905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  p_value: output parameter to carry out the attribute value.
5915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  p_len: output parameter as attribute length read.
5925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  read_long: this is a read blob request.
5935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  mtu: MTU.
5945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  sec_flag: current link security status.
5955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  key_size: encryption key size
5965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          Status of operation.
5985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
6005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjecttGATT_STATUS gatts_read_attr_value_by_handle(tGATT_TCB *p_tcb,
6015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                             tGATT_SVC_DB *p_db,
6025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                             UINT8 op_code,
6035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                             UINT16 handle, UINT16 offset,
6045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                             UINT8 *p_value, UINT16 *p_len,
6055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                             UINT16 mtu,
6065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                             tGATT_SEC_FLAG sec_flag,
6075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                             UINT8 key_size,
6085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                             UINT32 trans_id)
6095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
6105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tGATT_STATUS status = GATT_NOT_FOUND;
6115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tGATT_ATTR16  *p_attr;
6125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8       *pp = p_value;
6135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_db && p_db->p_attr_list)
6155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
6165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_attr = (tGATT_ATTR16 *)p_db->p_attr_list;
6175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        while (p_attr && handle >= p_attr->handle)
6195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
6205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (p_attr->handle == handle)
6215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
6225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                status = read_attr_value (p_attr, offset, &pp,
6235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                          (BOOLEAN)(op_code == GATT_REQ_READ_BLOB),
6245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                          mtu, p_len, sec_flag, key_size);
6255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                if (status == GATT_PENDING)
6275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
6285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    status = gatts_send_app_read_request(p_tcb, op_code, p_attr->handle, offset, trans_id);
6295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
6305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                break;
6315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
6325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_attr = (tGATT_ATTR16 *)p_attr->p_next;
6335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
6345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
6355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return status;
6375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
6385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
6405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
6415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         gatts_read_attr_perm_check
6425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
6435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Check attribute readability.
6445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
6455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Parameter        p_db: pointer to the attribute database.
6465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  handle: Attribute handle to read.
6475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  offset: Read offset.
6485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  p_value: output parameter to carry out the attribute value.
6495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  p_len: output parameter as attribute length read.
6505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  read_long: this is a read blob request.
6515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  mtu: MTU.
6525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  sec_flag: current link security status.
6535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  key_size: encryption key size
6545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
6555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          Status of operation.
6565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
6575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
6585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjecttGATT_STATUS gatts_read_attr_perm_check(tGATT_SVC_DB *p_db,
6595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                        BOOLEAN is_long,
6605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                        UINT16 handle,
6615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                        tGATT_SEC_FLAG sec_flag,
6625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                        UINT8 key_size)
6635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
6645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tGATT_STATUS status = GATT_NOT_FOUND;
6655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tGATT_ATTR16  *p_attr;
6665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_db && p_db->p_attr_list)
6685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
6695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_attr = (tGATT_ATTR16 *)p_db->p_attr_list;
6705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        while (p_attr && handle >= p_attr->handle)
6725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
6735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (p_attr->handle == handle)
6745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
6755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                status = gatts_check_attr_readability (p_attr, 0,
6765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                                       is_long,
6775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                                       sec_flag, key_size);
6785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                break;
6795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
6805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_attr = (tGATT_ATTR16 *) p_attr->p_next;
6815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
6825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
6835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return status;
6855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
6865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
6875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
6885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         gatts_write_attr_perm_check
6895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
6905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Write attribute value into database.
6915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
6925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Parameter        p_db: pointer to the attribute database.
6935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  op_code:op code of this write.
6945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  handle: handle of the attribute to write.
6955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  offset: Write offset if write op code is write blob.
6965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  p_data: Attribute value to write.
6975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  len: attribute data length.
6985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  sec_flag: current link security status.
6995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  key_size: encryption key size
7005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
7015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          Status of the operation.
7025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
7035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
7045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjecttGATT_STATUS gatts_write_attr_perm_check (tGATT_SVC_DB *p_db, UINT8 op_code,
7055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                          UINT16 handle, UINT16 offset, UINT8 *p_data,
7065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                          UINT16 len, tGATT_SEC_FLAG sec_flag, UINT8 key_size)
7075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
7085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tGATT_STATUS    status = GATT_NOT_FOUND;
7095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tGATT_ATTR16    *p_attr;
7105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16          max_size = 0;
7115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tGATT_PERM      perm;
7125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16          min_key_size;
7135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    GATT_TRACE_DEBUG6( "gatts_write_attr_perm_check op_code=0x%0x handle=0x%04x offset=%d len=%d sec_flag=0x%0x key_size=%d",
7155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                       op_code, handle, offset, len, sec_flag, key_size);
7165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_db != NULL)
7185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
7195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_attr = (tGATT_ATTR16 *) p_db->p_attr_list;
7205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        while (p_attr != NULL)
7225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
7235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (p_attr->handle == handle)
7245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
7255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                perm = p_attr->permission;
7265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                min_key_size = (((perm & GATT_ENCRYPT_KEY_SIZE_MASK) >> 12));
7275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                if (min_key_size != 0 )
7285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
7295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    min_key_size +=6;
7305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
7315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                GATT_TRACE_DEBUG2( "gatts_write_attr_perm_check p_attr->permission =0x%04x min_key_size==0x%04x",
7325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                   p_attr->permission,
7335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                   min_key_size);
7345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
735ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                if ((op_code == GATT_CMD_WRITE || op_code == GATT_REQ_WRITE)
736ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                    && (perm & GATT_WRITE_SIGNED_PERM))
7375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
7385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    /* use the rules for the mixed security see section 10.2.3*/
739ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                    /* use security mode 1 level 2 when the following condition follows */
740ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                    /* LE security mode 2 level 1 and LE security mode 1 level 2 */
741ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                    if ((perm & GATT_PERM_WRITE_SIGNED) && (perm & GATT_PERM_WRITE_ENCRYPTED))
7425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    {
7435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        perm = GATT_PERM_WRITE_ENCRYPTED;
7445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    }
745ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                    /* use security mode 1 level 3 when the following condition follows */
746ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                    /* LE security mode 2 level 2 and security mode 1 and LE */
747ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                    else if (((perm & GATT_PERM_WRITE_SIGNED_MITM) && (perm & GATT_PERM_WRITE_ENCRYPTED)) ||
748ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                              /* LE security mode 2 and security mode 1 level 3 */
749ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                             ((perm & GATT_WRITE_SIGNED_PERM) && (perm & GATT_PERM_WRITE_ENC_MITM)))
7505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    {
7515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        perm = GATT_PERM_WRITE_ENC_MITM;
7525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    }
7535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
7545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                if ((op_code == GATT_SIGN_CMD_WRITE) && !(perm & GATT_WRITE_SIGNED_PERM))
7565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
7575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    status = GATT_WRITE_NOT_PERMIT;
7585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    GATT_TRACE_DEBUG0( "gatts_write_attr_perm_check - sign cmd write not allowed");
7595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
7605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                 if ((op_code == GATT_SIGN_CMD_WRITE) && (sec_flag & GATT_SEC_FLAG_ENCRYPTED))
7615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
7625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    status = GATT_INVALID_PDU;
7635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    GATT_TRACE_ERROR0( "gatts_write_attr_perm_check - Error!! sign cmd write sent on a encypted link");
7645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
7655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                else if (!(perm & GATT_WRITE_ALLOWED))
7665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
7675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    status = GATT_WRITE_NOT_PERMIT;
7685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    GATT_TRACE_ERROR0( "gatts_write_attr_perm_check - GATT_WRITE_NOT_PERMIT");
7695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
770ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                /* require authentication, but not been authenticated */
7715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                else if ((perm & GATT_WRITE_AUTH_REQUIRED ) && !(sec_flag & GATT_SEC_FLAG_LKEY_UNAUTHED))
7725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
7735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    status = GATT_INSUF_AUTHENTICATION;
7745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    GATT_TRACE_ERROR0( "gatts_write_attr_perm_check - GATT_INSUF_AUTHENTICATION");
7755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
7765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                else if ((perm & GATT_WRITE_MITM_REQUIRED ) && !(sec_flag & GATT_SEC_FLAG_LKEY_AUTHED))
7775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
7785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    status = GATT_INSUF_AUTHENTICATION;
7795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    GATT_TRACE_ERROR0( "gatts_write_attr_perm_check - GATT_INSUF_AUTHENTICATION: MITM required");
7805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
7815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                else if ((perm & GATT_WRITE_ENCRYPTED_PERM ) && !(sec_flag & GATT_SEC_FLAG_ENCRYPTED))
7825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
7835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    status = GATT_INSUF_ENCRYPTION;
7845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    GATT_TRACE_ERROR0( "gatts_write_attr_perm_check - GATT_INSUF_ENCRYPTION");
7855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
7865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                else if ((perm & GATT_WRITE_ENCRYPTED_PERM ) && (sec_flag & GATT_SEC_FLAG_ENCRYPTED) && (key_size < min_key_size))
7875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
7885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    status = GATT_INSUF_KEY_SIZE;
7895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    GATT_TRACE_ERROR0( "gatts_write_attr_perm_check - GATT_INSUF_KEY_SIZE");
7905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
791ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                /* LE security mode 2 attribute  */
792ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                else if (perm & GATT_WRITE_SIGNED_PERM && op_code != GATT_SIGN_CMD_WRITE && !(sec_flag & GATT_SEC_FLAG_ENCRYPTED))
793ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                {
794ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                    status = GATT_INSUF_AUTHENTICATION;
795ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                    GATT_TRACE_ERROR0( "gatts_write_attr_perm_check - GATT_INSUF_AUTHENTICATION: LE security mode 2 required");
796ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                }
7975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                else /* writable: must be char value declaration or char descritpors */
7985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
7995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    if(p_attr->uuid_type == GATT_ATTR_UUID_TYPE_16)
8005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    {
8015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    switch (p_attr->uuid)
8025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    {
8035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        case GATT_UUID_CHAR_PRESENT_FORMAT:/* should be readable only */
8045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        case GATT_UUID_CHAR_EXT_PROP:/* should be readable only */
8055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        case GATT_UUID_CHAR_AGG_FORMAT: /* should be readable only */
8065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                            case GATT_UUID_CHAR_VALID_RANGE:
8075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                            status = GATT_WRITE_NOT_PERMIT;
8085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                            break;
8095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        case GATT_UUID_CHAR_CLIENT_CONFIG:
811ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta/* coverity[MISSING_BREAK] */
812ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta/* intnended fall through, ignored */
813ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                            /* fall through */
8145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        case GATT_UUID_CHAR_SRVR_CONFIG:
8155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                            max_size = 2;
8165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        case GATT_UUID_CHAR_DESCRIPTION:
8175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        default: /* any other must be character value declaration */
8185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                            status = GATT_SUCCESS;
8195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                            break;
8205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        }
8215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    }
8225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    else if (p_attr->uuid_type == GATT_ATTR_UUID_TYPE_128)
8235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    {
8245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                         status = GATT_SUCCESS;
8255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    }
8265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    else
8275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    {
8285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        status = GATT_INVALID_PDU;
8295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    }
8305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    if (p_data == NULL && len  > 0)
8325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    {
8335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        status = GATT_INVALID_PDU;
8345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    }
8355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    /* these attribute does not allow write blob */
8365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project// btla-specific ++
8375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    else if ( (p_attr->uuid_type == GATT_ATTR_UUID_TYPE_16) &&
8385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                              (p_attr->uuid == GATT_UUID_CHAR_CLIENT_CONFIG ||
8395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                               p_attr->uuid == GATT_UUID_CHAR_SRVR_CONFIG) )
8405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project// btla-specific --
8415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    {
8425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        if (op_code == GATT_REQ_PREPARE_WRITE && offset != 0) /* does not allow write blob */
8435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        {
8445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                            status = GATT_NOT_LONG;
8455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                            GATT_TRACE_ERROR0( "gatts_write_attr_perm_check - GATT_NOT_LONG");
8465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        }
8475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        else if (len != max_size)    /* data does not match the required format */
8485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        {
849ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                            status = GATT_INVALID_ATTR_LEN;
8505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                            GATT_TRACE_ERROR0( "gatts_write_attr_perm_check - GATT_INVALID_PDU");
8515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        }
8525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        else
8535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        {
8545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                            status = GATT_SUCCESS;
8555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        }
8565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    }
8575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
8585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                break;
8595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
8605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            else
8615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_attr = (tGATT_ATTR16 *)p_attr->p_next;
8625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
8635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
8645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return status;
8665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
8675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
8695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
8705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         allocate_attr_in_db
8715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
8725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Allocate a memory space for a new attribute, and link this
8735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  attribute into the database attribute list.
8745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
8755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
8765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Parameter        p_db    : database pointer.
8775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  service : type of attribute to be added.
8785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
8795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          pointer to the newly allocated attribute.
8805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
8815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
8825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void *allocate_attr_in_db(tGATT_SVC_DB *p_db, UINT16 uuid16, UINT8 *uuid128, tGATT_PERM perm)
8835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
8845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tGATT_ATTR16    *p_attr16 = NULL, *p_last;
8855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tGATT_ATTR128   *p_attr128 = NULL;
8865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16      len = (uuid16 == 0) ? sizeof(tGATT_ATTR128): sizeof(tGATT_ATTR16);
8875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    GATT_TRACE_DEBUG1("allocate attr %d bytes ",len);
8895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (uuid16 == GATT_ILLEGAL_UUID && uuid128 == NULL)
8915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
8925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        GATT_TRACE_ERROR0("illegal UUID");
8935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return NULL;
8945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
8955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_db->end_handle <= p_db->next_handle)
8975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
8985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        GATT_TRACE_DEBUG2("handle space full. handle_max = %d next_handle = %d",
8995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                          p_db->end_handle, p_db->next_handle);
9005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return NULL;
9015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
9025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_db->mem_free < len)
9045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
9055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (!allocate_svc_db_buf(p_db))
9065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
9075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            GATT_TRACE_ERROR0("allocate_attr_in_db failed, no resources");
9085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return NULL;
9095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
9105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
9115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_attr16 = (tGATT_ATTR16 *) p_db->p_free_mem;
9135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_attr128 = (tGATT_ATTR128 *) p_db->p_free_mem;
9145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    memset(p_attr16, 0, len);
9165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (uuid16 != GATT_ILLEGAL_UUID)
9185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
9195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_attr16->uuid_type = GATT_ATTR_UUID_TYPE_16;
9205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_attr16->uuid = uuid16;
9215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
9225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
9235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
9245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_attr128->uuid_type = GATT_ATTR_UUID_TYPE_128;
9255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        memcpy(p_attr128->uuid, uuid128, LEN_UUID_128);
9265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
9275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_db->p_free_mem += len;
9295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_db->mem_free -= len;
9305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_attr16->handle = p_db->next_handle++;
9325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_attr16->permission = perm;
9335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_attr16->p_next = NULL;
9345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* link the attribute record into the end of DB */
9365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_db->p_attr_list == NULL)
9375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_db->p_attr_list = p_attr16;
9385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
9395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
9405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_last = (tGATT_ATTR16 *)p_db->p_attr_list;
9415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        while (p_last != NULL && p_last->p_next != NULL)
9435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_last = (tGATT_ATTR16 *)p_last->p_next;
9445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_last->p_next = p_attr16;
9465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
9475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_attr16->uuid_type == GATT_ATTR_UUID_TYPE_16)
9495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
9505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        GATT_TRACE_DEBUG3("=====> handle = [0x%04x] uuid = [0x%04x] perm=0x%02x ",
9515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                          p_attr16->handle, p_attr16->uuid, p_attr16->permission);
9525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
9535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
9545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
9555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        GATT_TRACE_DEBUG4("=====> handle = [0x%04x] uuid128 = [0x%02x:0x%02x] perm=0x%02x ",
9565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                          p_attr128->handle, p_attr128->uuid[0],p_attr128->uuid[1],
9575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                          p_attr128->permission);
9585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
9595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return(void *)p_attr16;
9605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
9615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
9635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
9645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         deallocate_attr_in_db
9655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
9665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Free an attribute within the database.
9675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
9685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Parameter        p_db: database pointer.
9695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  p_attr: pointer to the attribute record to be freed.
9705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
9715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          BOOLEAN: success
9725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
9735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
9745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic BOOLEAN deallocate_attr_in_db(tGATT_SVC_DB *p_db, void *p_attr)
9755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
9765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tGATT_ATTR16  *p_cur, *p_next;
9775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BOOLEAN     found = FALSE;
9785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_db->p_attr_list == NULL)
9805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return found;
9815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_cur   = (tGATT_ATTR16 *) p_db->p_attr_list;
9835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_next  = (tGATT_ATTR16 *) p_cur->p_next;
9845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    for (; p_cur != NULL && p_next != NULL;
9865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_cur = p_next, p_next = (tGATT_ATTR16 *)p_next->p_next)
9875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
9885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_next == p_attr)
9895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
9905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_cur->p_next = p_next->p_next;
9915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            found = TRUE;
9925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
9935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
9945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cur == p_attr && p_cur == p_db->p_attr_list)
9955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
9965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_db->p_attr_list = p_cur->p_next;
9975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        found = TRUE;
9985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
9995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* else attr not found */
10005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ( found)
10015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_db->next_handle --;
10025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return found;
10045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
10055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
10075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
10085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         copy_extra_byte_in_db
10095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
10105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Utility function to allocate extra bytes memory in DB and copy
10115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  the value from a source place.
10125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
10135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
10145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Parameter        p_db: database pointer.
10155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  p_dst: destination data pointer.
10165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  p_src: source data pointer.
10175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  len: data length to be copied.
10185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
10195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          None.
10205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
10215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
10225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic BOOLEAN copy_extra_byte_in_db(tGATT_SVC_DB *p_db, void **p_dst, UINT16 len)
10235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
10245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8 *p = (UINT8 *)*p_dst;
10255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_db->mem_free < len)
10275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
10285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (!allocate_svc_db_buf(p_db))
10295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
10305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            GATT_TRACE_ERROR0("copy_extra_byte_in_db failed, no resources");
10315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return FALSE;
10325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
10335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
10345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p = p_db->p_free_mem;
10365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_db->p_free_mem += len;
10375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_db->mem_free -= len;
10385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    memset((void *)p, 0, len);
10395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    *p_dst = (void *)p;
10405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return TRUE;
10425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
10435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
10455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
10465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         allocate_svc_db_buf
10475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
10485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Utility function to allocate extra buffer for service database.
10495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
10505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          TRUE if allocation succeed, otherwise FALSE.
10515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
10525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
10535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic BOOLEAN allocate_svc_db_buf(tGATT_SVC_DB *p_db)
10545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
10555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BT_HDR  *p_buf;
10565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    GATT_TRACE_DEBUG0("allocate_svc_db_buf allocating extra buffer");
10585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((p_buf = (BT_HDR *)GKI_getpoolbuf(GATT_DB_POOL_ID)) == NULL)
10605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
10615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        GATT_TRACE_ERROR0("allocate_svc_db_buf failed, no resources");
10625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return FALSE;
10635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
10645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    memset(p_buf, 0, GKI_get_buf_size(p_buf));
10665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_db->p_free_mem    = (UINT8 *) p_buf;
10675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_db->mem_free      = GKI_get_buf_size(p_buf);
10685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    GKI_enqueue(&p_db->svc_buffer, p_buf);
10705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return TRUE;
10725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
10745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
10765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
10775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         gatts_send_app_read_request
10785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
10795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Send application read request callback
10805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
10815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          status of operation.
10825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
10835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
10845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic tGATT_STATUS gatts_send_app_read_request(tGATT_TCB *p_tcb, UINT8 op_code,
10855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                                UINT16 handle, UINT16 offset, UINT32 trans_id)
10865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
10875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tGATTS_DATA   sr_data;
10885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8       i_rcb;
10895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tGATT_SR_REG *p_sreg;
10905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16   conn_id;
10915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    i_rcb = gatt_sr_find_i_rcb_by_handle(handle);
10935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_sreg = &gatt_cb.sr_reg[i_rcb];
10945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    conn_id = GATT_CREATE_CONN_ID(p_tcb->tcb_idx, p_sreg->gatt_if);
10955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (trans_id == 0)
10975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
10985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        trans_id = gatt_sr_enqueue_cmd(p_tcb, op_code, handle);
10995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        gatt_sr_update_cback_cnt(p_tcb, p_sreg->gatt_if, TRUE, TRUE);
11005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
11015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (trans_id != 0 )
11035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
11045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        memset(&sr_data, 0, sizeof(tGATTS_DATA));
11055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        sr_data.read_req.handle = handle;
11075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        sr_data.read_req.is_long = (BOOLEAN)(op_code == GATT_REQ_READ_BLOB);
11085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        sr_data.read_req.offset = offset;
11095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        gatt_sr_send_req_callback(conn_id,
11115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                  trans_id, GATTS_REQ_TYPE_READ, &sr_data);
11125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return(tGATT_STATUS) GATT_PENDING;
11135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
11145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
11155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return(tGATT_STATUS) GATT_BUSY; /* max pending command, application error */
11165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
11185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
11205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
11215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         gatts_db_add_service_declaration
11225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
11235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Update a service database service declaration record.
11245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
11255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Parameter        p_db: database pointer.
11265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  service: UUID of the service.
11275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
11285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
11295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
11305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
11315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void gatts_db_add_service_declaration(tGATT_SVC_DB *p_db, tBT_UUID service, BOOLEAN is_pri)
11325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
11335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tGATT_ATTR16  *p_attr;
11345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16      service_type = is_pri ? GATT_UUID_PRI_SERVICE: GATT_UUID_SEC_SERVICE;
11355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    GATT_TRACE_DEBUG0( "add_service_declaration");
11375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* add service declration record */
11395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((p_attr = (tGATT_ATTR16 *)(allocate_attr_in_db(p_db, service_type, NULL, GATT_PERM_READ))) != NULL)
11405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
11415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (copy_extra_byte_in_db (p_db, (void **)&p_attr->p_value, sizeof(tBT_UUID)))
11425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
11435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            memcpy (&p_attr->p_value->uuid, &service, sizeof(tBT_UUID));
11445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
11455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
11465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
11475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif /* BLE_INCLUDED */
1149