gatt_db.c revision b44cc59d286ad255e872c60df02e032bd8d9d75b
1ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta/****************************************************************************** 2ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta * 3ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta * Copyright (C) 2009-2012 Broadcom Corporation 4ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta * 5ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta * Licensed under the Apache License, Version 2.0 (the "License"); 6ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta * you may not use this file except in compliance with the License. 7ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta * You may obtain a copy of the License at: 8ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta * 9ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta * http://www.apache.org/licenses/LICENSE-2.0 10ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta * 11ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta * Unless required by applicable law or agreed to in writing, software 12ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta * distributed under the License is distributed on an "AS IS" BASIS, 13ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta * See the License for the specific language governing permissions and 15ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta * limitations under the License. 16ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta * 17ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta ******************************************************************************/ 18ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta 19ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta/****************************************************************************** 20ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta * 21ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta * this file contains GATT database building and query functions 22ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta * 23ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta ******************************************************************************/ 24ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta 25ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#include "bt_target.h" 26ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta 27ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#if BLE_INCLUDED == TRUE 28ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta 29ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#include "bt_trace.h" 30ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#include "bt_utils.h" 31ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta 32ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#include <stdio.h> 33ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#include <string.h> 34ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#include "gatt_int.h" 35ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#include "l2c_api.h" 36ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#include "btm_int.h" 37ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta 38ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta/******************************************************************************** 39ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** L O C A L F U N C T I O N P R O T O T Y P E S * 40ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta*********************************************************************************/ 41ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Battastatic BOOLEAN allocate_svc_db_buf(tGATT_SVC_DB *p_db); 42ca22ac493ab777199084d87b3c7627e7f27555afAndre Eisenbachstatic void *allocate_attr_in_db(tGATT_SVC_DB *p_db, tBT_UUID *p_uuid, tGATT_PERM perm); 43ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Battastatic BOOLEAN deallocate_attr_in_db(tGATT_SVC_DB *p_db, void *p_attr); 44ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Battastatic BOOLEAN copy_extra_byte_in_db(tGATT_SVC_DB *p_db, void **p_dst, UINT16 len); 45ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta 46ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Battastatic BOOLEAN gatts_db_add_service_declaration(tGATT_SVC_DB *p_db, tBT_UUID *p_service, BOOLEAN is_pri); 47ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Battastatic tGATT_STATUS gatts_send_app_read_request(tGATT_TCB *p_tcb, UINT8 op_code, 48ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta UINT16 handle, UINT16 offset, UINT32 trans_id); 49ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta 50ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta/******************************************************************************* 51ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** 52ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** Function gatts_init_service_db 53ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** 54ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** Description This function initialize a memory space to be a service database. 55ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** 56ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** Parameter p_db: database pointer. 57ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** len: size of the memory space. 58ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** 59ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** Returns Status of te operation. 60ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** 61ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta*******************************************************************************/ 62ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi BattaBOOLEAN gatts_init_service_db (tGATT_SVC_DB *p_db, tBT_UUID *p_service, BOOLEAN is_pri, 63ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta UINT16 s_hdl, UINT16 num_handle) 64ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta{ 65ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta if (!allocate_svc_db_buf(p_db)) 66ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta { 67ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta GATT_TRACE_ERROR("gatts_init_service_db failed, no resources"); 68ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta return FALSE; 69ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta } 70ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta 71ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta GATT_TRACE_DEBUG("gatts_init_service_db"); 72ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta GATT_TRACE_DEBUG("s_hdl = %d num_handle = %d", s_hdl, num_handle ); 73ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta 74ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta /* update service database information */ 75ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta p_db->next_handle = s_hdl; 76ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta p_db->end_handle = s_hdl + num_handle; 77ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta 78ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta return gatts_db_add_service_declaration(p_db, p_service, is_pri); 79ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta} 80ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta 81ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta/******************************************************************************* 82ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** 83ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** Function gatts_init_service_db 84ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** 85ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** Description This function initialize a memory space to be a service database. 86ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** 87ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** Parameter p_db: database pointer. 88ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** len: size of the memory space. 89ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** 90ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** Returns Status of te operation. 91ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** 92ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta*******************************************************************************/ 93ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi BattatBT_UUID * gatts_get_service_uuid (tGATT_SVC_DB *p_db) 94ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta{ 95ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta if (!p_db || !p_db->p_attr_list) 96ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta { 97ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta GATT_TRACE_ERROR("service DB empty"); 98ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta 99ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta return NULL; 100ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta } 101ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta else 102ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta { 103ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta return &((tGATT_ATTR16 *)p_db->p_attr_list)->p_value->uuid; 104ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta } 1057fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta} 1067fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta 107ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta/******************************************************************************* 108ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** 109ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** Function gatts_check_attr_readability 110ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** 111ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** Description check attribute readability 112ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** 113ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** Returns status of operation. 114ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** 115ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta*******************************************************************************/ 116ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Battastatic tGATT_STATUS gatts_check_attr_readability(tGATT_ATTR16 *p_attr, 117ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta UINT16 offset, 118ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta BOOLEAN read_long, 119ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta tGATT_SEC_FLAG sec_flag, 120ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta UINT8 key_size) 121ca22ac493ab777199084d87b3c7627e7f27555afAndre Eisenbach{ 122ca22ac493ab777199084d87b3c7627e7f27555afAndre Eisenbach UINT16 min_key_size; 123ca22ac493ab777199084d87b3c7627e7f27555afAndre Eisenbach tGATT_PERM perm = p_attr->permission; 124ca22ac493ab777199084d87b3c7627e7f27555afAndre Eisenbach 125ca22ac493ab777199084d87b3c7627e7f27555afAndre Eisenbach UNUSED(offset); 126ca22ac493ab777199084d87b3c7627e7f27555afAndre Eisenbach min_key_size = (((perm & GATT_ENCRYPT_KEY_SIZE_MASK) >> 12)); 127ca22ac493ab777199084d87b3c7627e7f27555afAndre Eisenbach if (min_key_size != 0 ) 128ca22ac493ab777199084d87b3c7627e7f27555afAndre Eisenbach { 129ca22ac493ab777199084d87b3c7627e7f27555afAndre Eisenbach min_key_size +=6; 130ca22ac493ab777199084d87b3c7627e7f27555afAndre Eisenbach } 131ca22ac493ab777199084d87b3c7627e7f27555afAndre Eisenbach 132ca22ac493ab777199084d87b3c7627e7f27555afAndre Eisenbach if (!(perm & GATT_READ_ALLOWED)) 133ca22ac493ab777199084d87b3c7627e7f27555afAndre Eisenbach { 134ca22ac493ab777199084d87b3c7627e7f27555afAndre Eisenbach GATT_TRACE_ERROR( "GATT_READ_NOT_PERMIT"); 135ca22ac493ab777199084d87b3c7627e7f27555afAndre Eisenbach return GATT_READ_NOT_PERMIT; 136ca22ac493ab777199084d87b3c7627e7f27555afAndre Eisenbach } 137ca22ac493ab777199084d87b3c7627e7f27555afAndre Eisenbach 138ca22ac493ab777199084d87b3c7627e7f27555afAndre Eisenbach if ((perm & GATT_READ_AUTH_REQUIRED ) && !(sec_flag & GATT_SEC_FLAG_LKEY_UNAUTHED) && 139ca22ac493ab777199084d87b3c7627e7f27555afAndre Eisenbach !(sec_flag & BTM_SEC_FLAG_ENCRYPTED)) 140ca22ac493ab777199084d87b3c7627e7f27555afAndre Eisenbach { 141ca22ac493ab777199084d87b3c7627e7f27555afAndre Eisenbach GATT_TRACE_ERROR( "GATT_INSUF_AUTHENTICATION"); 142ca22ac493ab777199084d87b3c7627e7f27555afAndre Eisenbach return GATT_INSUF_AUTHENTICATION; 143ca22ac493ab777199084d87b3c7627e7f27555afAndre Eisenbach } 144ca22ac493ab777199084d87b3c7627e7f27555afAndre Eisenbach 145ca22ac493ab777199084d87b3c7627e7f27555afAndre Eisenbach if ((perm & GATT_READ_MITM_REQUIRED ) && !(sec_flag & GATT_SEC_FLAG_LKEY_AUTHED)) 146ca22ac493ab777199084d87b3c7627e7f27555afAndre Eisenbach { 147ca22ac493ab777199084d87b3c7627e7f27555afAndre Eisenbach GATT_TRACE_ERROR( "GATT_INSUF_AUTHENTICATION: MITM Required"); 148ca22ac493ab777199084d87b3c7627e7f27555afAndre Eisenbach return GATT_INSUF_AUTHENTICATION; 149ca22ac493ab777199084d87b3c7627e7f27555afAndre Eisenbach } 150ca22ac493ab777199084d87b3c7627e7f27555afAndre Eisenbach 151ca22ac493ab777199084d87b3c7627e7f27555afAndre Eisenbach if ((perm & GATT_READ_ENCRYPTED_REQUIRED ) && !(sec_flag & GATT_SEC_FLAG_ENCRYPTED)) 152ca22ac493ab777199084d87b3c7627e7f27555afAndre Eisenbach { 153ca22ac493ab777199084d87b3c7627e7f27555afAndre Eisenbach GATT_TRACE_ERROR( "GATT_INSUF_ENCRYPTION"); 154ca22ac493ab777199084d87b3c7627e7f27555afAndre Eisenbach return GATT_INSUF_ENCRYPTION; 155ca22ac493ab777199084d87b3c7627e7f27555afAndre Eisenbach } 156ca22ac493ab777199084d87b3c7627e7f27555afAndre Eisenbach 157ca22ac493ab777199084d87b3c7627e7f27555afAndre Eisenbach if ( (perm & GATT_READ_ENCRYPTED_REQUIRED) && (sec_flag & GATT_SEC_FLAG_ENCRYPTED) && (key_size < min_key_size)) 158ca22ac493ab777199084d87b3c7627e7f27555afAndre Eisenbach { 159ca22ac493ab777199084d87b3c7627e7f27555afAndre Eisenbach GATT_TRACE_ERROR( "GATT_INSUF_KEY_SIZE"); 160ca22ac493ab777199084d87b3c7627e7f27555afAndre Eisenbach return GATT_INSUF_KEY_SIZE; 161ca22ac493ab777199084d87b3c7627e7f27555afAndre Eisenbach } 162ca22ac493ab777199084d87b3c7627e7f27555afAndre Eisenbach 163ca22ac493ab777199084d87b3c7627e7f27555afAndre Eisenbach 164ca22ac493ab777199084d87b3c7627e7f27555afAndre Eisenbach if (read_long) 165ca22ac493ab777199084d87b3c7627e7f27555afAndre Eisenbach { 166ca22ac493ab777199084d87b3c7627e7f27555afAndre Eisenbach switch (p_attr->uuid) 167ca22ac493ab777199084d87b3c7627e7f27555afAndre Eisenbach { 168ca22ac493ab777199084d87b3c7627e7f27555afAndre Eisenbach case GATT_UUID_PRI_SERVICE: 169ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta case GATT_UUID_SEC_SERVICE: 170ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta case GATT_UUID_CHAR_DECLARE: 171ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta case GATT_UUID_INCLUDE_SERVICE: 172ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta case GATT_UUID_CHAR_EXT_PROP: 173ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta case GATT_UUID_CHAR_CLIENT_CONFIG: 174ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta case GATT_UUID_CHAR_SRVR_CONFIG: 175ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta case GATT_UUID_CHAR_PRESENT_FORMAT: 176ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta GATT_TRACE_ERROR("GATT_NOT_LONG"); 177ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta return GATT_NOT_LONG; 178ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta 179ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta default: 180ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta break; 181ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta } 182ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta } 183ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta 184ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta return GATT_SUCCESS; 185ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta} 186ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta 187ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta/******************************************************************************* 188ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** 189ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** Function read_attr_value 190ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** 191ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** Description Utility function to read an attribute value. 192ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** 193ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** Parameter p_attr: pointer to the attribute to read. 194ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** offset: read offset. 195ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** p_value: output parameter to carry out the attribute value. 196ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** p_len: output parameter to carry out the attribute length. 197ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** read_long: this is a read blob request. 198ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** mtu: MTU 199977b854e5121c0ea19ecab6eb2bdb3583f439568Andre Eisenbach** sec_flag: current link security status. 200ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** key_size: encryption key size. 201ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** 202ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** Returns status of operation. 203ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** 204ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta*******************************************************************************/ 205ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Battastatic tGATT_STATUS read_attr_value (void *p_attr, 206ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta UINT16 offset, 207ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta UINT8 **p_data, 208ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta BOOLEAN read_long, 209977b854e5121c0ea19ecab6eb2bdb3583f439568Andre Eisenbach UINT16 mtu, 210ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta UINT16 *p_len, 211ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta tGATT_SEC_FLAG sec_flag, 212ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta UINT8 key_size) 213ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta{ 214ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta UINT16 len = 0, uuid16 = 0; 215ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta UINT8 *p = *p_data; 216ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta tGATT_STATUS status; 217ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta UINT16 read_long_uuid=0; 218ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta tGATT_ATTR16 *p_attr16 = (tGATT_ATTR16 *)p_attr; 219ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta 220ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta GATT_TRACE_DEBUG("read_attr_value uuid=0x%04x perm=0x%0x sec_flag=0x%x offset=%d read_long=%d", 221ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta p_attr16->uuid, 222ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta p_attr16->permission, 223ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta sec_flag, 224ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta offset, 225ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta read_long); 226ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta 227ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta status = gatts_check_attr_readability((tGATT_ATTR16 *)p_attr, offset, read_long, sec_flag, key_size); 228ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta 229ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta if (status != GATT_SUCCESS) 230ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta return status; 231ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta 232ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta if (p_attr16->uuid_type == GATT_ATTR_UUID_TYPE_16) 233ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta uuid16 = p_attr16->uuid; 234ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta 235ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta status = GATT_NO_RESOURCES; 236ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta 237ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta if (read_long && 238ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta (uuid16 == GATT_UUID_CHAR_DESCRIPTION || uuid16 == GATT_UUID_CHAR_AGG_FORMAT)) 239ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta { 240ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta read_long_uuid = p_attr16->uuid; 241ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta } 242ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta 243ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta if (uuid16 == GATT_UUID_PRI_SERVICE || uuid16 == GATT_UUID_SEC_SERVICE) 244ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta { 245ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta len = p_attr16->p_value->uuid.len; 246ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta if (mtu >= p_attr16->p_value->uuid.len) 247ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta { 248ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta gatt_build_uuid_to_stream(&p, p_attr16->p_value->uuid); 249ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta status = GATT_SUCCESS; 250ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta } 251ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta } 252ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta else if (uuid16 == GATT_UUID_CHAR_DECLARE) 253ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta { 254ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta len = (((tGATT_ATTR16 *)(p_attr16->p_next))->uuid_type == GATT_ATTR_UUID_TYPE_16) ? 5 :19; 255ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta 256ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta if (mtu >= len) 257ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta { 258ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta UINT8_TO_STREAM(p, p_attr16->p_value->char_decl.property); 259ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta UINT16_TO_STREAM(p, p_attr16->p_value->char_decl.char_val_handle); 260ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta 261ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta if (((tGATT_ATTR16 *)(p_attr16->p_next))->uuid_type == GATT_ATTR_UUID_TYPE_16) 262ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta { 263ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta UINT16_TO_STREAM(p, ((tGATT_ATTR16 *)(p_attr16->p_next))->uuid); 264ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta } 265ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta /* convert a 32bits UUID to 128 bits */ 266ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta else if (((tGATT_ATTR32 *)(p_attr16->p_next))->uuid_type == GATT_ATTR_UUID_TYPE_32) 267ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta { 268ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta gatt_convert_uuid32_to_uuid128 (p, ((tGATT_ATTR32 *)(p_attr16->p_next))->uuid); 269ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta p += LEN_UUID_128; 270ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta } 271ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta else 272ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta { 273ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta ARRAY_TO_STREAM (p, ((tGATT_ATTR128 *)(p_attr16->p_next))->uuid, LEN_UUID_128); 274ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta } 275ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta status = GATT_SUCCESS; 276ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta } 277ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta 278ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta } 279ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta else if (uuid16 == GATT_UUID_INCLUDE_SERVICE) 280ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta { 281ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta if (p_attr16->p_value->incl_handle.service_type.len == LEN_UUID_16) 282ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta len = 6; 283ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta else 284ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta len = 4; 285ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta 286ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta if (mtu >= len) 287ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta { 288ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta UINT16_TO_STREAM(p, p_attr16->p_value->incl_handle.s_handle); 289ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta UINT16_TO_STREAM(p, p_attr16->p_value->incl_handle.e_handle); 290ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta 291ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta if (p_attr16->p_value->incl_handle.service_type.len == LEN_UUID_16) 292ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta { 293ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta UINT16_TO_STREAM(p, p_attr16->p_value->incl_handle.service_type.uu.uuid16); 294ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta } 295ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta status = GATT_SUCCESS; 296ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta } 297ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta } 298ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta else /* characteristic description or characteristic value */ 299ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta { 300ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta status = GATT_PENDING; 301ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta } 302ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta 303ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta *p_len = len; 304ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta *p_data = p; 305ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta return status; 306ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta} 307ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta 308ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta/******************************************************************************* 309ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** 310ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** Function gatts_db_read_attr_value_by_type 311ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** 312ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** Description Query attribute value by attribute type. 313ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** 314ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** Parameter p_db: pointer to the attribute database. 315ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** p_rsp: Read By type response data. 316ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** s_handle: starting handle of the range we are looking for. 317ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** e_handle: ending handle of the range we are looking for. 318ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** type: Attribute type. 319ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** mtu: MTU. 320ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** sec_flag: current link security status. 321ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** key_size: encryption key size. 322ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** 323ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** Returns Status of the operation. 32417b04bd498405f2bb109a85562ebbdcb6bb06e95Andre Eisenbach** 32517b04bd498405f2bb109a85562ebbdcb6bb06e95Andre Eisenbach*******************************************************************************/ 32617b04bd498405f2bb109a85562ebbdcb6bb06e95Andre EisenbachtGATT_STATUS gatts_db_read_attr_value_by_type (tGATT_TCB *p_tcb, 32717b04bd498405f2bb109a85562ebbdcb6bb06e95Andre Eisenbach tGATT_SVC_DB *p_db, 32817b04bd498405f2bb109a85562ebbdcb6bb06e95Andre Eisenbach UINT8 op_code, 32917b04bd498405f2bb109a85562ebbdcb6bb06e95Andre Eisenbach BT_HDR *p_rsp, 33017b04bd498405f2bb109a85562ebbdcb6bb06e95Andre Eisenbach UINT16 s_handle, 33117b04bd498405f2bb109a85562ebbdcb6bb06e95Andre Eisenbach UINT16 e_handle, 33217b04bd498405f2bb109a85562ebbdcb6bb06e95Andre Eisenbach tBT_UUID type, 33317b04bd498405f2bb109a85562ebbdcb6bb06e95Andre Eisenbach UINT16 *p_len, 33417b04bd498405f2bb109a85562ebbdcb6bb06e95Andre Eisenbach tGATT_SEC_FLAG sec_flag, 33517b04bd498405f2bb109a85562ebbdcb6bb06e95Andre Eisenbach UINT8 key_size, 336ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta UINT32 trans_id, 337ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta UINT16 *p_cur_handle) 338ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta{ 339ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta tGATT_STATUS status = GATT_NOT_FOUND; 340ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta tGATT_ATTR16 *p_attr; 341ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta UINT16 len = 0; 342ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta UINT8 *p = (UINT8 *)(p_rsp + 1) + p_rsp->len + L2CAP_MIN_OFFSET; 343ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta tBT_UUID attr_uuid; 344ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#if (defined(BLE_DELAY_REQUEST_ENC) && (BLE_DELAY_REQUEST_ENC == TRUE)) 345ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta UINT8 flag; 346ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#endif 347ca22ac493ab777199084d87b3c7627e7f27555afAndre Eisenbach 348ca22ac493ab777199084d87b3c7627e7f27555afAndre Eisenbach if (p_db && p_db->p_attr_list) 349ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta { 350ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta p_attr = (tGATT_ATTR16 *)p_db->p_attr_list; 351ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta 352ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta while (p_attr && p_attr->handle <= e_handle) 353ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta { 354ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta if (p_attr->uuid_type == GATT_ATTR_UUID_TYPE_16) 355ca22ac493ab777199084d87b3c7627e7f27555afAndre Eisenbach { 356ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta attr_uuid.len = LEN_UUID_16; 357ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta attr_uuid.uu.uuid16 = p_attr->uuid; 358ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta } 359ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta else if (p_attr->uuid_type == GATT_ATTR_UUID_TYPE_32) 360ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta { 361ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta attr_uuid.len = LEN_UUID_32; 362ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta attr_uuid.uu.uuid32 = ((tGATT_ATTR32 *)p_attr)->uuid; 363ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta } 364ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta else 365ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta { 366ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta attr_uuid.len = LEN_UUID_128; 367ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta memcpy(attr_uuid.uu.uuid128, ((tGATT_ATTR128 *)p_attr)->uuid, LEN_UUID_128); 368ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta } 369ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta 370ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta if (p_attr->handle >= s_handle && gatt_uuid_compare(type, attr_uuid)) 371ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta { 372ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta if (*p_len <= 2) 373ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta { 374ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta status = GATT_NO_RESOURCES; 375ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta break; 376ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta } 377ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta 378ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta UINT16_TO_STREAM (p, p_attr->handle); 379ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta 380ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta status = read_attr_value ((void *)p_attr, 0, &p, FALSE, (UINT16)(*p_len -2), &len, sec_flag, key_size); 381306bddadeec993013cfed6bf0e41a1a47a69367cAndre Eisenbach 382306bddadeec993013cfed6bf0e41a1a47a69367cAndre Eisenbach if (status == GATT_PENDING) 383306bddadeec993013cfed6bf0e41a1a47a69367cAndre Eisenbach { 384306bddadeec993013cfed6bf0e41a1a47a69367cAndre Eisenbach status = gatts_send_app_read_request(p_tcb, op_code, p_attr->handle, 0, trans_id); 3857fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta 386306bddadeec993013cfed6bf0e41a1a47a69367cAndre Eisenbach /* one callback at a time */ 387306bddadeec993013cfed6bf0e41a1a47a69367cAndre Eisenbach break; 388306bddadeec993013cfed6bf0e41a1a47a69367cAndre Eisenbach } 389306bddadeec993013cfed6bf0e41a1a47a69367cAndre Eisenbach else if (status == GATT_SUCCESS) 390306bddadeec993013cfed6bf0e41a1a47a69367cAndre Eisenbach { 391306bddadeec993013cfed6bf0e41a1a47a69367cAndre Eisenbach if (p_rsp->offset == 0) 392ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta p_rsp->offset = len + 2; 393ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta 394306bddadeec993013cfed6bf0e41a1a47a69367cAndre Eisenbach if (p_rsp->offset == len + 2) 3957fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta { 3967fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta p_rsp->len += (len + 2); 3977fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta *p_len -= (len + 2); 3987fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta } 3997fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta else 4007fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta { 4017fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta GATT_TRACE_ERROR("format mismatch"); 4027fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta status = GATT_NO_RESOURCES; 4037fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta break; 4047fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta } 4057fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta } 4067fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta else 4077fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta { 4087fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta *p_cur_handle = p_attr->handle; 4097fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta break; 4107fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta } 4117fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta } 4127fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta p_attr = (tGATT_ATTR16 *)p_attr->p_next; 4137fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta } 4147fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta } 4157fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta 4167fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta#if (defined(BLE_DELAY_REQUEST_ENC) && (BLE_DELAY_REQUEST_ENC == TRUE)) 4177fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta if (BTM_GetSecurityFlags(p_tcb->peer_bda, &flag)) 418306bddadeec993013cfed6bf0e41a1a47a69367cAndre Eisenbach { 419ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta if ((p_tcb->att_lcid == L2CAP_ATT_CID) && (status == GATT_PENDING) && 4207fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta (type.uu.uuid16 == GATT_UUID_GAP_DEVICE_NAME)) 421ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta { 422306bddadeec993013cfed6bf0e41a1a47a69367cAndre Eisenbach if ((flag & (BTM_SEC_LINK_KEY_KNOWN | BTM_SEC_FLAG_ENCRYPTED)) == 423ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta BTM_SEC_LINK_KEY_KNOWN) 424ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta { 425ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta tACL_CONN *p; 426ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta p = btm_bda_to_acl(p_tcb->peer_bda); 427ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta if ((p != NULL) && (p->link_role == BTM_ROLE_MASTER)) 428ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta { 429ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta tBTM_BLE_SEC_ACT sec_act = BTM_BLE_SEC_ENCRYPT; 430ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta btm_ble_set_encryption(p_tcb->peer_bda, &sec_act, p->link_role); 431ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta } 432ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta } 433ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta } 434ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta } 435ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#endif 436ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta return status; 437ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta} 438ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta 439ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta/******************************************************************************* 440ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** 441ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** Function gatts_add_included_service 442ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** 443ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** Description This function adds an included service into a database. 444ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** 445ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** Parameter p_db: database pointer. 446ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** inc_srvc_type: included service type. 447ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** 448ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** Returns Status of the operation. 449ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** 450ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta*******************************************************************************/ 451ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi BattaUINT16 gatts_add_included_service (tGATT_SVC_DB *p_db, UINT16 s_handle, UINT16 e_handle, 452ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta tBT_UUID service) 453ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta{ 454ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta tGATT_ATTR16 *p_attr; 455ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta tBT_UUID uuid = {LEN_UUID_16, {GATT_UUID_INCLUDE_SERVICE}}; 456ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta 457ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta GATT_TRACE_DEBUG("gatts_add_included_service: s_hdl = 0x%04x e_hdl = 0x%04x uuid = 0x%04x", 458ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta s_handle, e_handle, service.uu.uuid16); 459ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta 460ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta if (service.len == 0 || s_handle == 0 || e_handle == 0) 461ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta { 462ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta GATT_TRACE_ERROR("gatts_add_included_service Illegal Params."); 463ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta return 0; 464ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta } 465ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta 466ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta if ((p_attr = (tGATT_ATTR16 *) allocate_attr_in_db(p_db, &uuid, GATT_PERM_READ)) != NULL) 467ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta { 468ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta if (copy_extra_byte_in_db(p_db, (void **)&p_attr->p_value, sizeof(tGATT_INCL_SRVC))) 469ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta { 470ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta p_attr->p_value->incl_handle.s_handle = s_handle; 471ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta p_attr->p_value->incl_handle.e_handle = e_handle; 472ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta memcpy(&p_attr->p_value->incl_handle.service_type, &service, sizeof(tBT_UUID)); 473ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta 474ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta return p_attr->handle; 475ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta } 476ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta else 477ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta { 478ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta deallocate_attr_in_db(p_db, p_attr); 479ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta } 480ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta } 481ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta 482ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta return 0; 483ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta} 484ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta 485ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta/******************************************************************************* 486ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** 487ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** Function gatts_add_characteristic 488ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** 489ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** Description This function add a characteristics and its descriptor into 490ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** a servce identified by the service database pointer. 491ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** 492ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** Parameter p_db: database pointer. 493ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** perm: permission (authentication and key size requirements) 494ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** property: property of the characteristic. 495ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** p_char: characteristic value information. 496ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** 497ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** Returns Status of te operation. 498ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** 499ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta*******************************************************************************/ 500ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi BattaUINT16 gatts_add_characteristic (tGATT_SVC_DB *p_db, tGATT_PERM perm, 501ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta tGATT_CHAR_PROP property, 502ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta tBT_UUID * p_char_uuid) 503ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta{ 504ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta tGATT_ATTR16 *p_char_decl, *p_char_val; 505ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta tBT_UUID uuid = {LEN_UUID_16, {GATT_UUID_CHAR_DECLARE}}; 506ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta 507ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta GATT_TRACE_DEBUG("gatts_add_characteristic perm=0x%0x property=0x%0x", perm, property); 508ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta 509ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta if ((p_char_decl = (tGATT_ATTR16 *)allocate_attr_in_db(p_db, &uuid, GATT_PERM_READ)) != NULL) 510ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta { 511ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta if (!copy_extra_byte_in_db(p_db, (void **)&p_char_decl->p_value, sizeof(tGATT_CHAR_DECL))) 512ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta { 513ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta deallocate_attr_in_db(p_db, p_char_decl); 514ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta return 0; 515ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta } 516ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta 517ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta p_char_val = (tGATT_ATTR16 *)allocate_attr_in_db(p_db, p_char_uuid, perm); 518ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta 519ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta if (p_char_val == NULL) 520ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta { 521ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta deallocate_attr_in_db(p_db, p_char_decl); 522ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta return 0; 523ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta } 524ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta 525ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta p_char_decl->p_value->char_decl.property = property; 526ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta p_char_decl->p_value->char_decl.char_val_handle = p_char_val->handle; 527ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta 528ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta p_char_val->p_value = NULL; 5297fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta 5307fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta return p_char_val->handle; 531ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta } 532ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta 533ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta return 0; 534ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta} 535ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta 5367fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta/******************************************************************************* 537ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** 538ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** Function gatt_convertchar_descr_type 539ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** 540ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** Description This function convert a char descript UUID into descriptor type. 541ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** 542ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** Returns descriptor type. 543ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** 544ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta*******************************************************************************/ 545ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi BattaUINT8 gatt_convertchar_descr_type(tBT_UUID *p_descr_uuid) 546ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta{ 547ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta tBT_UUID std_descr = {LEN_UUID_16, {GATT_UUID_CHAR_EXT_PROP}}; 548ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta 549ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta if (gatt_uuid_compare(std_descr, * p_descr_uuid)) 550ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta return GATT_DESCR_EXT_DSCPTOR; 551ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta 552ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta std_descr.uu.uuid16 ++; 553ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta if (gatt_uuid_compare(std_descr, * p_descr_uuid)) 554ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta return GATT_DESCR_USER_DSCPTOR; 555ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta 556ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta std_descr.uu.uuid16 ++; 557ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta if (gatt_uuid_compare(std_descr, * p_descr_uuid)) 558ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta return GATT_DESCR_CLT_CONFIG; 559ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta 560ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta std_descr.uu.uuid16 ++; 561ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta if (gatt_uuid_compare(std_descr, * p_descr_uuid)) 562ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta return GATT_DESCR_SVR_CONFIG; 563ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta 564ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta std_descr.uu.uuid16 ++; 565ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta if (gatt_uuid_compare(std_descr, * p_descr_uuid)) 566ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta return GATT_DESCR_PRES_FORMAT; 567ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta 568ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta std_descr.uu.uuid16 ++; 569ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta if (gatt_uuid_compare(std_descr, * p_descr_uuid)) 570ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta return GATT_DESCR_AGGR_FORMAT; 571ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta 572ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta std_descr.uu.uuid16 ++; 573ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta if (gatt_uuid_compare(std_descr, * p_descr_uuid)) 574ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta return GATT_DESCR_VALID_RANGE; 575ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta 576ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta 577ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta return GATT_DESCR_UNKNOWN; 578ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta} 579ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta 580ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta/******************************************************************************* 581ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** 582ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** Function gatts_add_char_descr 583ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** 584ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** Description This function add a characteristics descriptor. 585ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** 586ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** Parameter p_db: database pointer. 587ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** perm: characteristic descriptor permission type. 588ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** char_dscp_tpye: the characteristic descriptor masks. 589ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** p_dscp_params: characteristic descriptors values. 590ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** 591ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** Returns Status of the operation. 592ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** 593ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta*******************************************************************************/ 594ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi BattaUINT16 gatts_add_char_descr (tGATT_SVC_DB *p_db, tGATT_PERM perm, 595ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta tBT_UUID * p_descr_uuid) 596ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta{ 597ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta tGATT_ATTR16 *p_char_dscptr; 598ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta 599ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta GATT_TRACE_DEBUG("gatts_add_char_descr uuid=0x%04x", p_descr_uuid->uu.uuid16); 600ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta 601ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta /* Add characteristic descriptors */ 602ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta if ((p_char_dscptr = (tGATT_ATTR16 *)allocate_attr_in_db(p_db, 603ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta p_descr_uuid, 604ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta perm)) 605ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta == NULL) 606ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta { 607ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta GATT_TRACE_DEBUG("gatts_add_char_descr Fail for adding char descriptors."); 608ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta return 0; 609ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta } 610ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta else 611ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta { 612ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta return p_char_dscptr->handle; 613ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta } 614ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta} 615ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta 616ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta/*******************************************************************************/ 617ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta/* Service Attribute Database Query Utility Functions */ 618ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta/*******************************************************************************/ 619ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta/******************************************************************************* 620ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** 621ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** Function gatts_read_attr_value_by_handle 622ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** 623ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** Description Query attribute value by attribute handle. 624ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** 625ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** Parameter p_db: pointer to the attribute database. 626ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** handle: Attribute handle to read. 627ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** offset: Read offset. 628ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** p_value: output parameter to carry out the attribute value. 629ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** p_len: output parameter as attribute length read. 630ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** read_long: this is a read blob request. 631ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** mtu: MTU. 632ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** sec_flag: current link security status. 633ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** key_size: encryption key size 634ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** 635ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** Returns Status of operation. 636ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** 637ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta*******************************************************************************/ 638ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi BattatGATT_STATUS gatts_read_attr_value_by_handle(tGATT_TCB *p_tcb, 639ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta tGATT_SVC_DB *p_db, 640ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta UINT8 op_code, 641ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta UINT16 handle, UINT16 offset, 642ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta UINT8 *p_value, UINT16 *p_len, 643ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta UINT16 mtu, 644ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta tGATT_SEC_FLAG sec_flag, 645ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta UINT8 key_size, 646ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta UINT32 trans_id) 647ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta{ 648ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta tGATT_STATUS status = GATT_NOT_FOUND; 649ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta tGATT_ATTR16 *p_attr; 650ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta UINT8 *pp = p_value; 651ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta 652ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta if (p_db && p_db->p_attr_list) 653ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta { 654ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta p_attr = (tGATT_ATTR16 *)p_db->p_attr_list; 655ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta 656ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta while (p_attr && handle >= p_attr->handle) 657ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta { 658ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta if (p_attr->handle == handle) 659ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta { 660ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta status = read_attr_value (p_attr, offset, &pp, 661ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta (BOOLEAN)(op_code == GATT_REQ_READ_BLOB), 662ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta mtu, p_len, sec_flag, key_size); 663ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta 664ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta if (status == GATT_PENDING) 665ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta { 666ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta status = gatts_send_app_read_request(p_tcb, op_code, p_attr->handle, offset, trans_id); 667ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta } 668ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta break; 669ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta } 670ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta p_attr = (tGATT_ATTR16 *)p_attr->p_next; 671ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta } 672ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta } 673ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta 674ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta return status; 675ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta} 676ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta 677ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta/******************************************************************************* 678ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** 679ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** Function gatts_read_attr_perm_check 680ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** 681** Description Check attribute readability. 682** 683** Parameter p_db: pointer to the attribute database. 684** handle: Attribute handle to read. 685** offset: Read offset. 686** p_value: output parameter to carry out the attribute value. 687** p_len: output parameter as attribute length read. 688** read_long: this is a read blob request. 689** mtu: MTU. 690** sec_flag: current link security status. 691** key_size: encryption key size 692** 693** Returns Status of operation. 694** 695*******************************************************************************/ 696tGATT_STATUS gatts_read_attr_perm_check(tGATT_SVC_DB *p_db, 697 BOOLEAN is_long, 698 UINT16 handle, 699 tGATT_SEC_FLAG sec_flag, 700 UINT8 key_size) 701{ 702 tGATT_STATUS status = GATT_NOT_FOUND; 703 tGATT_ATTR16 *p_attr; 704 705 if (p_db && p_db->p_attr_list) 706 { 707 p_attr = (tGATT_ATTR16 *)p_db->p_attr_list; 708 709 while (p_attr && handle >= p_attr->handle) 710 { 711 if (p_attr->handle == handle) 712 { 713 status = gatts_check_attr_readability (p_attr, 0, 714 is_long, 715 sec_flag, key_size); 716 break; 717 } 718 p_attr = (tGATT_ATTR16 *) p_attr->p_next; 719 } 720 } 721 722 return status; 723} 724/******************************************************************************* 725** 726** Function gatts_write_attr_perm_check 727** 728** Description Write attribute value into database. 729** 730** Parameter p_db: pointer to the attribute database. 731** op_code:op code of this write. 732** handle: handle of the attribute to write. 733** offset: Write offset if write op code is write blob. 734** p_data: Attribute value to write. 735** len: attribute data length. 736** sec_flag: current link security status. 737** key_size: encryption key size 738** 739** Returns Status of the operation. 740** 741*******************************************************************************/ 742tGATT_STATUS gatts_write_attr_perm_check (tGATT_SVC_DB *p_db, UINT8 op_code, 743 UINT16 handle, UINT16 offset, UINT8 *p_data, 744 UINT16 len, tGATT_SEC_FLAG sec_flag, UINT8 key_size) 745{ 746 tGATT_STATUS status = GATT_NOT_FOUND; 747 tGATT_ATTR16 *p_attr; 748 UINT16 max_size = 0; 749 tGATT_PERM perm; 750 UINT16 min_key_size; 751 752 GATT_TRACE_DEBUG( "gatts_write_attr_perm_check op_code=0x%0x handle=0x%04x offset=%d len=%d sec_flag=0x%0x key_size=%d", 753 op_code, handle, offset, len, sec_flag, key_size); 754 755 if (p_db != NULL) 756 { 757 p_attr = (tGATT_ATTR16 *) p_db->p_attr_list; 758 759 while (p_attr != NULL) 760 { 761 if (p_attr->handle == handle) 762 { 763 perm = p_attr->permission; 764 min_key_size = (((perm & GATT_ENCRYPT_KEY_SIZE_MASK) >> 12)); 765 if (min_key_size != 0 ) 766 { 767 min_key_size +=6; 768 } 769 GATT_TRACE_DEBUG( "gatts_write_attr_perm_check p_attr->permission =0x%04x min_key_size==0x%04x", 770 p_attr->permission, 771 min_key_size); 772 773 if ((op_code == GATT_CMD_WRITE || op_code == GATT_REQ_WRITE) 774 && (perm & GATT_WRITE_SIGNED_PERM)) 775 { 776 /* use the rules for the mixed security see section 10.2.3*/ 777 /* use security mode 1 level 2 when the following condition follows */ 778 /* LE security mode 2 level 1 and LE security mode 1 level 2 */ 779 if ((perm & GATT_PERM_WRITE_SIGNED) && (perm & GATT_PERM_WRITE_ENCRYPTED)) 780 { 781 perm = GATT_PERM_WRITE_ENCRYPTED; 782 } 783 /* use security mode 1 level 3 when the following condition follows */ 784 /* LE security mode 2 level 2 and security mode 1 and LE */ 785 else if (((perm & GATT_PERM_WRITE_SIGNED_MITM) && (perm & GATT_PERM_WRITE_ENCRYPTED)) || 786 /* LE security mode 2 and security mode 1 level 3 */ 787 ((perm & GATT_WRITE_SIGNED_PERM) && (perm & GATT_PERM_WRITE_ENC_MITM))) 788 { 789 perm = GATT_PERM_WRITE_ENC_MITM; 790 } 791 } 792 793 if ((op_code == GATT_SIGN_CMD_WRITE) && !(perm & GATT_WRITE_SIGNED_PERM)) 794 { 795 status = GATT_WRITE_NOT_PERMIT; 796 GATT_TRACE_DEBUG( "gatts_write_attr_perm_check - sign cmd write not allowed"); 797 } 798 if ((op_code == GATT_SIGN_CMD_WRITE) && (sec_flag & GATT_SEC_FLAG_ENCRYPTED)) 799 { 800 status = GATT_INVALID_PDU; 801 GATT_TRACE_ERROR( "gatts_write_attr_perm_check - Error!! sign cmd write sent on a encypted link"); 802 } 803 else if (!(perm & GATT_WRITE_ALLOWED)) 804 { 805 status = GATT_WRITE_NOT_PERMIT; 806 GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_WRITE_NOT_PERMIT"); 807 } 808 /* require authentication, but not been authenticated */ 809 else if ((perm & GATT_WRITE_AUTH_REQUIRED ) && !(sec_flag & GATT_SEC_FLAG_LKEY_UNAUTHED)) 810 { 811 status = GATT_INSUF_AUTHENTICATION; 812 GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_INSUF_AUTHENTICATION"); 813 } 814 else if ((perm & GATT_WRITE_MITM_REQUIRED ) && !(sec_flag & GATT_SEC_FLAG_LKEY_AUTHED)) 815 { 816 status = GATT_INSUF_AUTHENTICATION; 817 GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_INSUF_AUTHENTICATION: MITM required"); 818 } 819 else if ((perm & GATT_WRITE_ENCRYPTED_PERM ) && !(sec_flag & GATT_SEC_FLAG_ENCRYPTED)) 820 { 821 status = GATT_INSUF_ENCRYPTION; 822 GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_INSUF_ENCRYPTION"); 823 } 824 else if ((perm & GATT_WRITE_ENCRYPTED_PERM ) && (sec_flag & GATT_SEC_FLAG_ENCRYPTED) && (key_size < min_key_size)) 825 { 826 status = GATT_INSUF_KEY_SIZE; 827 GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_INSUF_KEY_SIZE"); 828 } 829 /* LE security mode 2 attribute */ 830 else if (perm & GATT_WRITE_SIGNED_PERM && op_code != GATT_SIGN_CMD_WRITE && !(sec_flag & GATT_SEC_FLAG_ENCRYPTED) 831 && (perm & GATT_WRITE_ALLOWED) == 0) 832 { 833 status = GATT_INSUF_AUTHENTICATION; 834 GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_INSUF_AUTHENTICATION: LE security mode 2 required"); 835 } 836 else /* writable: must be char value declaration or char descritpors */ 837 { 838 if(p_attr->uuid_type == GATT_ATTR_UUID_TYPE_16) 839 { 840 switch (p_attr->uuid) 841 { 842 case GATT_UUID_CHAR_PRESENT_FORMAT:/* should be readable only */ 843 case GATT_UUID_CHAR_EXT_PROP:/* should be readable only */ 844 case GATT_UUID_CHAR_AGG_FORMAT: /* should be readable only */ 845 case GATT_UUID_CHAR_VALID_RANGE: 846 status = GATT_WRITE_NOT_PERMIT; 847 break; 848 849 case GATT_UUID_CHAR_CLIENT_CONFIG: 850/* coverity[MISSING_BREAK] */ 851/* intnended fall through, ignored */ 852 /* fall through */ 853 case GATT_UUID_CHAR_SRVR_CONFIG: 854 max_size = 2; 855 case GATT_UUID_CHAR_DESCRIPTION: 856 default: /* any other must be character value declaration */ 857 status = GATT_SUCCESS; 858 break; 859 } 860 } 861 else if (p_attr->uuid_type == GATT_ATTR_UUID_TYPE_128 || 862 p_attr->uuid_type == GATT_ATTR_UUID_TYPE_32) 863 { 864 status = GATT_SUCCESS; 865 } 866 else 867 { 868 status = GATT_INVALID_PDU; 869 } 870 871 if (p_data == NULL && len > 0) 872 { 873 status = GATT_INVALID_PDU; 874 } 875 /* these attribute does not allow write blob */ 876// btla-specific ++ 877 else if ( (p_attr->uuid_type == GATT_ATTR_UUID_TYPE_16) && 878 (p_attr->uuid == GATT_UUID_CHAR_CLIENT_CONFIG || 879 p_attr->uuid == GATT_UUID_CHAR_SRVR_CONFIG) ) 880// btla-specific -- 881 { 882 if (op_code == GATT_REQ_PREPARE_WRITE && offset != 0) /* does not allow write blob */ 883 { 884 status = GATT_NOT_LONG; 885 GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_NOT_LONG"); 886 } 887 else if (len != max_size) /* data does not match the required format */ 888 { 889 status = GATT_INVALID_ATTR_LEN; 890 GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_INVALID_PDU"); 891 } 892 else 893 { 894 status = GATT_SUCCESS; 895 } 896 } 897 } 898 break; 899 } 900 else 901 p_attr = (tGATT_ATTR16 *)p_attr->p_next; 902 } 903 } 904 905 return status; 906} 907 908/******************************************************************************* 909** 910** Function allocate_attr_in_db 911** 912** Description Allocate a memory space for a new attribute, and link this 913** attribute into the database attribute list. 914** 915** 916** Parameter p_db : database pointer. 917** p_uuid: pointer to attribute UUID 918** service : type of attribute to be added. 919** 920** Returns pointer to the newly allocated attribute. 921** 922*******************************************************************************/ 923static void *allocate_attr_in_db(tGATT_SVC_DB *p_db, tBT_UUID *p_uuid, tGATT_PERM perm) 924{ 925 tGATT_ATTR16 *p_attr16 = NULL, *p_last; 926 tGATT_ATTR32 *p_attr32 = NULL; 927 tGATT_ATTR128 *p_attr128 = NULL; 928 UINT16 len = sizeof(tGATT_ATTR128); 929 930 if (p_uuid == NULL) 931 { 932 GATT_TRACE_ERROR("illegal UUID"); 933 return NULL; 934 } 935 936 if (p_uuid->len == LEN_UUID_16) 937 len = sizeof(tGATT_ATTR16); 938 else if (p_uuid->len == LEN_UUID_32) 939 len = sizeof(tGATT_ATTR32); 940 941 GATT_TRACE_DEBUG("allocate attr %d bytes ",len); 942 943 if (p_db->end_handle <= p_db->next_handle) 944 { 945 GATT_TRACE_DEBUG("handle space full. handle_max = %d next_handle = %d", 946 p_db->end_handle, p_db->next_handle); 947 return NULL; 948 } 949 950 if (p_db->mem_free < len) 951 { 952 if (!allocate_svc_db_buf(p_db)) 953 { 954 GATT_TRACE_ERROR("allocate_attr_in_db failed, no resources"); 955 return NULL; 956 } 957 } 958 memset(p_db->p_free_mem, 0, len); 959 p_attr16 = (tGATT_ATTR16 *) p_db->p_free_mem; 960 961 if (p_uuid->len == LEN_UUID_16 && p_uuid->uu.uuid16 != GATT_ILLEGAL_UUID) 962 { 963 p_attr16->uuid_type = GATT_ATTR_UUID_TYPE_16; 964 p_attr16->uuid = p_uuid->uu.uuid16; 965 } 966 else if (p_uuid->len == LEN_UUID_32) 967 { 968 p_attr32 = (tGATT_ATTR32 *) p_db->p_free_mem; 969 p_attr32->uuid_type = GATT_ATTR_UUID_TYPE_32; 970 p_attr32->uuid = p_uuid->uu.uuid32; 971 } 972 else if (p_uuid->len == LEN_UUID_128) 973 { 974 p_attr128 = (tGATT_ATTR128 *) p_db->p_free_mem; 975 p_attr128->uuid_type = GATT_ATTR_UUID_TYPE_128; 976 memcpy(p_attr128->uuid, p_uuid->uu.uuid128, LEN_UUID_128); 977 } 978 979 p_db->p_free_mem += len; 980 p_db->mem_free -= len; 981 982 p_attr16->handle = p_db->next_handle++; 983 p_attr16->permission = perm; 984 p_attr16->p_next = NULL; 985 986 /* link the attribute record into the end of DB */ 987 if (p_db->p_attr_list == NULL) 988 p_db->p_attr_list = p_attr16; 989 else 990 { 991 p_last = (tGATT_ATTR16 *)p_db->p_attr_list; 992 993 while (p_last != NULL && p_last->p_next != NULL) 994 p_last = (tGATT_ATTR16 *)p_last->p_next; 995 996 p_last->p_next = p_attr16; 997 } 998 999 if (p_attr16->uuid_type == GATT_ATTR_UUID_TYPE_16) 1000 { 1001 GATT_TRACE_DEBUG("=====> handle = [0x%04x] uuid16 = [0x%04x] perm=0x%02x ", 1002 p_attr16->handle, p_attr16->uuid, p_attr16->permission); 1003 } 1004 else if (p_attr16->uuid_type == GATT_ATTR_UUID_TYPE_32) 1005 { 1006 GATT_TRACE_DEBUG("=====> handle = [0x%04x] uuid32 = [0x%08x] perm=0x%02x ", 1007 p_attr32->handle, p_attr32->uuid, p_attr32->permission); 1008 } 1009 else 1010 { 1011 GATT_TRACE_DEBUG("=====> handle = [0x%04x] uuid128 = [0x%02x:0x%02x] perm=0x%02x ", 1012 p_attr128->handle, p_attr128->uuid[0],p_attr128->uuid[1], 1013 p_attr128->permission); 1014 } 1015 return(void *)p_attr16; 1016} 1017 1018/******************************************************************************* 1019** 1020** Function deallocate_attr_in_db 1021** 1022** Description Free an attribute within the database. 1023** 1024** Parameter p_db: database pointer. 1025** p_attr: pointer to the attribute record to be freed. 1026** 1027** Returns BOOLEAN: success 1028** 1029*******************************************************************************/ 1030static BOOLEAN deallocate_attr_in_db(tGATT_SVC_DB *p_db, void *p_attr) 1031{ 1032 tGATT_ATTR16 *p_cur, *p_next; 1033 BOOLEAN found = FALSE; 1034 1035 if (p_db->p_attr_list == NULL) 1036 return found; 1037 1038 p_cur = (tGATT_ATTR16 *) p_db->p_attr_list; 1039 p_next = (tGATT_ATTR16 *) p_cur->p_next; 1040 1041 for (; p_cur != NULL && p_next != NULL; 1042 p_cur = p_next, p_next = (tGATT_ATTR16 *)p_next->p_next) 1043 { 1044 if (p_next == p_attr) 1045 { 1046 p_cur->p_next = p_next->p_next; 1047 found = TRUE; 1048 } 1049 } 1050 if (p_cur == p_attr && p_cur == p_db->p_attr_list) 1051 { 1052 p_db->p_attr_list = p_cur->p_next; 1053 found = TRUE; 1054 } 1055 /* else attr not found */ 1056 if ( found) 1057 p_db->next_handle --; 1058 1059 return found; 1060} 1061 1062/******************************************************************************* 1063** 1064** Function copy_extra_byte_in_db 1065** 1066** Description Utility function to allocate extra bytes memory in DB and copy 1067** the value from a source place. 1068** 1069** 1070** Parameter p_db: database pointer. 1071** p_dst: destination data pointer. 1072** p_src: source data pointer. 1073** len: data length to be copied. 1074** 1075** Returns None. 1076** 1077*******************************************************************************/ 1078static BOOLEAN copy_extra_byte_in_db(tGATT_SVC_DB *p_db, void **p_dst, UINT16 len) 1079{ 1080 UINT8 *p = (UINT8 *)*p_dst; 1081 1082 if (p_db->mem_free < len) 1083 { 1084 if (!allocate_svc_db_buf(p_db)) 1085 { 1086 GATT_TRACE_ERROR("copy_extra_byte_in_db failed, no resources"); 1087 return FALSE; 1088 } 1089 } 1090 1091 p = p_db->p_free_mem; 1092 p_db->p_free_mem += len; 1093 p_db->mem_free -= len; 1094 memset((void *)p, 0, len); 1095 *p_dst = (void *)p; 1096 1097 return TRUE; 1098} 1099 1100/******************************************************************************* 1101** 1102** Function allocate_svc_db_buf 1103** 1104** Description Utility function to allocate extra buffer for service database. 1105** 1106** Returns TRUE if allocation succeed, otherwise FALSE. 1107** 1108*******************************************************************************/ 1109static BOOLEAN allocate_svc_db_buf(tGATT_SVC_DB *p_db) 1110{ 1111 BT_HDR *p_buf; 1112 1113 GATT_TRACE_DEBUG("allocate_svc_db_buf allocating extra buffer"); 1114 1115 if ((p_buf = (BT_HDR *)GKI_getpoolbuf(GATT_DB_POOL_ID)) == NULL) 1116 { 1117 GATT_TRACE_ERROR("allocate_svc_db_buf failed, no resources"); 1118 return FALSE; 1119 } 1120 1121 memset(p_buf, 0, GKI_get_buf_size(p_buf)); 1122 p_db->p_free_mem = (UINT8 *) p_buf; 1123 p_db->mem_free = GKI_get_buf_size(p_buf); 1124 1125 GKI_enqueue(&p_db->svc_buffer, p_buf); 1126 1127 return TRUE; 1128 1129} 1130 1131/******************************************************************************* 1132** 1133** Function gatts_send_app_read_request 1134** 1135** Description Send application read request callback 1136** 1137** Returns status of operation. 1138** 1139*******************************************************************************/ 1140static tGATT_STATUS gatts_send_app_read_request(tGATT_TCB *p_tcb, UINT8 op_code, 1141 UINT16 handle, UINT16 offset, UINT32 trans_id) 1142{ 1143 tGATTS_DATA sr_data; 1144 UINT8 i_rcb; 1145 tGATT_SR_REG *p_sreg; 1146 UINT16 conn_id; 1147 1148 i_rcb = gatt_sr_find_i_rcb_by_handle(handle); 1149 p_sreg = &gatt_cb.sr_reg[i_rcb]; 1150 conn_id = GATT_CREATE_CONN_ID(p_tcb->tcb_idx, p_sreg->gatt_if); 1151 1152 if (trans_id == 0) 1153 { 1154 trans_id = gatt_sr_enqueue_cmd(p_tcb, op_code, handle); 1155 gatt_sr_update_cback_cnt(p_tcb, p_sreg->gatt_if, TRUE, TRUE); 1156 } 1157 1158 if (trans_id != 0 ) 1159 { 1160 memset(&sr_data, 0, sizeof(tGATTS_DATA)); 1161 1162 sr_data.read_req.handle = handle; 1163 sr_data.read_req.is_long = (BOOLEAN)(op_code == GATT_REQ_READ_BLOB); 1164 sr_data.read_req.offset = offset; 1165 1166 gatt_sr_send_req_callback(conn_id, 1167 trans_id, GATTS_REQ_TYPE_READ, &sr_data); 1168 return(tGATT_STATUS) GATT_PENDING; 1169 } 1170 else 1171 return(tGATT_STATUS) GATT_BUSY; /* max pending command, application error */ 1172 1173} 1174 1175/******************************************************************************* 1176** 1177** Function gatts_db_add_service_declaration 1178** 1179** Description Update a service database service declaration record. 1180** 1181** Parameter p_db: database pointer. 1182** service: UUID of the service. 1183** 1184** Returns void 1185** 1186*******************************************************************************/ 1187static BOOLEAN gatts_db_add_service_declaration(tGATT_SVC_DB *p_db, tBT_UUID *p_service, BOOLEAN is_pri) 1188{ 1189 tGATT_ATTR16 *p_attr; 1190 tBT_UUID uuid = {LEN_UUID_16, {0}}; 1191 BOOLEAN rt = FALSE; 1192 1193 GATT_TRACE_DEBUG( "add_service_declaration"); 1194 1195 if (is_pri) 1196 uuid.uu.uuid16 = GATT_UUID_PRI_SERVICE; 1197 else 1198 uuid.uu.uuid16 = GATT_UUID_SEC_SERVICE; 1199 1200 /* add service declration record */ 1201 if ((p_attr = (tGATT_ATTR16 *)(allocate_attr_in_db(p_db, &uuid, GATT_PERM_READ))) != NULL) 1202 { 1203 if (copy_extra_byte_in_db (p_db, (void **)&p_attr->p_value, sizeof(tBT_UUID))) 1204 { 1205 if (p_service->len == LEN_UUID_16) 1206 { 1207 p_attr->p_value->uuid.len = LEN_UUID_16; 1208 p_attr->p_value->uuid.uu.uuid16 = p_service->uu.uuid16; 1209 } 1210 else if (p_service->len == LEN_UUID_32) 1211 { 1212 p_attr->p_value->uuid.len = LEN_UUID_128; 1213 gatt_convert_uuid32_to_uuid128(p_attr->p_value->uuid.uu.uuid128, p_service->uu.uuid32); 1214 } 1215 else 1216 { 1217 p_attr->p_value->uuid.len = LEN_UUID_128; 1218 memcpy(p_attr->p_value->uuid.uu.uuid128, p_service->uu.uuid128, LEN_UUID_128); 1219 } 1220 rt = TRUE; 1221 } 1222 1223 } 1224 return rt; 1225} 1226 1227#endif /* BLE_INCLUDED */ 1228