15738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/****************************************************************************** 25738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * 35738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * Copyright (C) 1999-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 interface functions 225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * 235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ******************************************************************************/ 245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "bt_target.h" 255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 26eafd45d08653bb1621c82a2f3cf922a43a0b1bc5Jakub Pawlowski#include <base/bind.h> 275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <stdio.h> 285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <string.h> 29911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson#include "bt_common.h" 30911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson#include "btm_int.h" 31eafd45d08653bb1621c82a2f3cf922a43a0b1bc5Jakub Pawlowski#include "btu.h" 3296fb273d92a31204edcf43ab2594a19876d14056Jakub Pawlowski#include "device/include/controller.h" 335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "gatt_api.h" 345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "gatt_int.h" 355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "l2c_api.h" 365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 38ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 39ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function GATT_SetTraceLevel 40ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 41ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description This function sets the trace level. If called with 42ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * a value of 0xFF, it simply returns the current trace level. 43ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 44ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Input Parameters: 45ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * level: The level to set the GATT tracing to: 46ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 0xff-returns the current setting. 47ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 0-turns off tracing. 48ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * >= 1-Errors. 49ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * >= 2-Warnings. 50ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * >= 3-APIs. 51ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * >= 4-Events. 52ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * >= 5-Debug. 53ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 54ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns The new or current trace level 55ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 56ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/ 57911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonuint8_t GATT_SetTraceLevel(uint8_t new_level) { 58911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (new_level != 0xFF) gatt_cb.trace_level = new_level; 595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 60911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson return (gatt_cb.trace_level); 615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 63ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski/** 64ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski * Add an service handle range to the list in decending order of the start 65ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski * handle. Return reference to the newly added element. 66ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski **/ 67ad3ab46b727119f3f7233e392d3d628909234e61Jakub PawlowskitGATT_HDL_LIST_ELEM& gatt_add_an_item_to_list(uint16_t s_handle) { 68ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski auto lst_ptr = gatt_cb.hdl_list_info; 69ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski auto it = lst_ptr->begin(); 70ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski for (; it != lst_ptr->end(); it++) { 71ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski if (s_handle > it->asgn_range.s_handle) break; 72ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski } 73ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski 74ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski auto rit = lst_ptr->emplace(it); 75ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski return *rit; 76ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski} 77ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski 785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/***************************************************************************** 79ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 80ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * GATT SERVER API 81ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 82ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *****************************************************************************/ 835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 84ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 85ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function GATTS_AddHandleRange 86ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 879ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson * Description This function add the allocated handles range for the 889ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson * specified application UUID, service UUID and service 899ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson * instance 90ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 91ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Parameter p_hndl_range: pointer to allocated handles information 92ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 93ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski **/ 945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 95ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowskivoid GATTS_AddHandleRange(tGATTS_HNDL_RANGE* p_hndl_range) { 96ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski gatt_add_an_item_to_list(p_hndl_range->s_handle); 975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 100ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 101ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function GATTS_NVRegister 102ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 103ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description Application manager calls this function to register for 104ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * NV save callback function. There can be one and only one 105ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * NV save callback function. 106ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 107ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Parameter p_cb_info : callback informaiton 108ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 109ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns true if registered OK, else false 110ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 111ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/ 112911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonbool GATTS_NVRegister(tGATT_APPL_INFO* p_cb_info) { 113911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson bool status = false; 114911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (p_cb_info) { 115911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson gatt_cb.cb_info = *p_cb_info; 116911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson status = true; 117911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson gatt_init_srv_chg(); 118911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 119911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 120911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson return status; 1215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 1225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1237680a0b1f60425a654a7186a74f1483194f9f0cdJakub Pawlowskistatic uint8_t BASE_UUID[16] = {0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80, 1247680a0b1f60425a654a7186a74f1483194f9f0cdJakub Pawlowski 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 125a641b6fa2a25e1b5382945d13c4fa49d36084a78Jakub Pawlowski 126911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonstatic int uuidType(unsigned char* p_uuid) { 127911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (memcmp(p_uuid, BASE_UUID, 12) != 0) return LEN_UUID_128; 128911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (memcmp(p_uuid + 14, BASE_UUID + 14, 2) != 0) return LEN_UUID_32; 129a641b6fa2a25e1b5382945d13c4fa49d36084a78Jakub Pawlowski 130911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson return LEN_UUID_16; 131a641b6fa2a25e1b5382945d13c4fa49d36084a78Jakub Pawlowski} 132a641b6fa2a25e1b5382945d13c4fa49d36084a78Jakub Pawlowski 133a641b6fa2a25e1b5382945d13c4fa49d36084a78Jakub Pawlowski/******************************************************************************* 134a641b6fa2a25e1b5382945d13c4fa49d36084a78Jakub Pawlowski * BTIF -> BTA conversion functions 135ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/ 136a641b6fa2a25e1b5382945d13c4fa49d36084a78Jakub Pawlowski 137911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonstatic void btif_to_bta_uuid(tBT_UUID* p_dest, bt_uuid_t* p_src) { 138911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson char* p_byte = (char*)p_src; 139911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson int i = 0; 140a641b6fa2a25e1b5382945d13c4fa49d36084a78Jakub Pawlowski 141911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_dest->len = uuidType(p_src->uu); 142a641b6fa2a25e1b5382945d13c4fa49d36084a78Jakub Pawlowski 143911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson switch (p_dest->len) { 144911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson case LEN_UUID_16: 145911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_dest->uu.uuid16 = (p_src->uu[13] << 8) + p_src->uu[12]; 146911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson break; 147a641b6fa2a25e1b5382945d13c4fa49d36084a78Jakub Pawlowski 148911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson case LEN_UUID_32: 149911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_dest->uu.uuid32 = (p_src->uu[15] << 24) + (p_src->uu[14] << 16) + 150911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson (p_src->uu[13] << 8) + p_src->uu[12]; 151911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson break; 152a641b6fa2a25e1b5382945d13c4fa49d36084a78Jakub Pawlowski 153911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson case LEN_UUID_128: 154911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson for (i = 0; i != 16; ++i) p_dest->uu.uuid128[i] = p_byte[i]; 155911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson break; 156a641b6fa2a25e1b5382945d13c4fa49d36084a78Jakub Pawlowski 157911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson default: 158911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson GATT_TRACE_ERROR("%s: Unknown UUID length %d!", __func__, p_dest->len); 159911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson break; 160911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 161a641b6fa2a25e1b5382945d13c4fa49d36084a78Jakub Pawlowski} 162a641b6fa2a25e1b5382945d13c4fa49d36084a78Jakub Pawlowski 163911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid uuid_128_from_16(bt_uuid_t* uuid, uint16_t uuid16) { 1647680a0b1f60425a654a7186a74f1483194f9f0cdJakub Pawlowski memcpy(uuid, &BASE_UUID, sizeof(bt_uuid_t)); 1657680a0b1f60425a654a7186a74f1483194f9f0cdJakub Pawlowski 166911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson uuid->uu[13] = (uint8_t)((0xFF00 & uuid16) >> 8); 1677680a0b1f60425a654a7186a74f1483194f9f0cdJakub Pawlowski uuid->uu[12] = (uint8_t)(0x00FF & uuid16); 1687680a0b1f60425a654a7186a74f1483194f9f0cdJakub Pawlowski} 1697680a0b1f60425a654a7186a74f1483194f9f0cdJakub Pawlowski 170911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonstatic uint16_t compute_service_size(btgatt_db_element_t* service, int count) { 171911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson int db_size = 0; 172911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson btgatt_db_element_t* el = service; 173911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 174911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson for (int i = 0; i < count; i++, el++) 175911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (el->type == BTGATT_DB_PRIMARY_SERVICE || 176911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson el->type == BTGATT_DB_SECONDARY_SERVICE || 177911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson el->type == BTGATT_DB_DESCRIPTOR || 178911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson el->type == BTGATT_DB_INCLUDED_SERVICE) 179911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson db_size += 1; 180911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson else if (el->type == BTGATT_DB_CHARACTERISTIC) 181911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson db_size += 2; 182911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson else 183911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson GATT_TRACE_ERROR("%s: Unknown element type: %d", __func__, el->type); 1847680a0b1f60425a654a7186a74f1483194f9f0cdJakub Pawlowski 185911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson return db_size; 186a641b6fa2a25e1b5382945d13c4fa49d36084a78Jakub Pawlowski} 1875c1fe35097f5bb48c419a69605fed0e094e797d2Jakub Pawlowski 1885c1fe35097f5bb48c419a69605fed0e094e797d2Jakub Pawlowskistatic bool is_gatt_attr_type(const tBT_UUID& uuid) { 1895c1fe35097f5bb48c419a69605fed0e094e797d2Jakub Pawlowski if (uuid.len == LEN_UUID_16 && (uuid.uu.uuid16 == GATT_UUID_PRI_SERVICE || 1905c1fe35097f5bb48c419a69605fed0e094e797d2Jakub Pawlowski uuid.uu.uuid16 == GATT_UUID_SEC_SERVICE || 1915c1fe35097f5bb48c419a69605fed0e094e797d2Jakub Pawlowski uuid.uu.uuid16 == GATT_UUID_INCLUDE_SERVICE || 1925c1fe35097f5bb48c419a69605fed0e094e797d2Jakub Pawlowski uuid.uu.uuid16 == GATT_UUID_CHAR_DECLARE)) { 1935c1fe35097f5bb48c419a69605fed0e094e797d2Jakub Pawlowski return true; 1945c1fe35097f5bb48c419a69605fed0e094e797d2Jakub Pawlowski } 1955c1fe35097f5bb48c419a69605fed0e094e797d2Jakub Pawlowski return false; 1965c1fe35097f5bb48c419a69605fed0e094e797d2Jakub Pawlowski} 1975c1fe35097f5bb48c419a69605fed0e094e797d2Jakub Pawlowski 198ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski/** Update the the last primary info for the service list info */ 199ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowskistatic void gatt_update_last_pri_srv_info() { 200ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski gatt_cb.last_primary_s_handle = 0; 201ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski 202ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski for (tGATT_SRV_LIST_ELEM& el : *gatt_cb.srv_list_info) 203ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski if (el.is_primary) gatt_cb.last_primary_s_handle = el.s_hdl; 204ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski} 205ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski 2065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 207ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 208ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function GATTS_AddService 209ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 210ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description This function is called to add GATT service. 211ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 212ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Parameter gatt_if : application if 213ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * service : pseudo-representation of service and it's content 214ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * count : size of service 215ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 216ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns on success GATT_SERVICE_STARTED is returned, and 217ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * attribute_handle field inside service elements are filled. 218ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * on error error status is returned. 219ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 220ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/ 221911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonuint16_t GATTS_AddService(tGATT_IF gatt_if, btgatt_db_element_t* service, 222911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson int count) { 223911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson uint16_t s_hdl = 0; 224911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson bool save_hdl = false; 225911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tGATT_REG* p_reg = gatt_get_regcb(gatt_if); 226911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tBT_UUID* p_app_uuid128; 227911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 228911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson bool is_pri = (service->type == BTGATT_DB_PRIMARY_SERVICE) ? true : false; 229911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tBT_UUID svc_uuid; 230911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson btif_to_bta_uuid(&svc_uuid, &service->uuid); 231911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 232911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson GATT_TRACE_API("%s", __func__); 233911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 234911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (p_reg == NULL) { 235911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson GATT_TRACE_ERROR("Inavlid gatt_if=%d", gatt_if); 236911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson return GATT_INTERNAL_ERROR; 237911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 238911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 239911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_app_uuid128 = &p_reg->app_uuid128; 240911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 241911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson uint16_t num_handles = compute_service_size(service, count); 242911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 243911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if ((svc_uuid.len == LEN_UUID_16) && 244911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson (svc_uuid.uu.uuid16 == UUID_SERVCLASS_GATT_SERVER)) { 245911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson s_hdl = gatt_cb.hdl_cfg.gatt_start_hdl; 246911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } else if ((svc_uuid.len == LEN_UUID_16) && 247911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson (svc_uuid.uu.uuid16 == UUID_SERVCLASS_GAP_SERVER)) { 248911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson s_hdl = gatt_cb.hdl_cfg.gap_start_hdl; 249911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } else { 250ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski if (!gatt_cb.hdl_list_info->empty()) { 251ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski s_hdl = gatt_cb.hdl_list_info->front().asgn_range.e_handle + 1; 252ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski } 253911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 254911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (s_hdl < gatt_cb.hdl_cfg.app_start_hdl) 255911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson s_hdl = gatt_cb.hdl_cfg.app_start_hdl; 256911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 257911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson save_hdl = true; 258911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 259911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 260911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson /* check for space */ 261911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (num_handles > (0xFFFF - s_hdl + 1)) { 262911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson GATT_TRACE_ERROR("GATTS_ReserveHandles: no handles, s_hdl: %u needed: %u", 263911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson s_hdl, num_handles); 264911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson return GATT_INTERNAL_ERROR; 265911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 266911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 267ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski tGATT_HDL_LIST_ELEM& list = gatt_add_an_item_to_list(s_hdl); 268ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski list.asgn_range.app_uuid128 = *p_app_uuid128; 269ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski list.asgn_range.svc_uuid = svc_uuid; 270ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski list.asgn_range.s_handle = s_hdl; 271ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski list.asgn_range.e_handle = s_hdl + num_handles - 1; 272ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski list.asgn_range.is_primary = is_pri; 273911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 274911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (save_hdl) { 275911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (gatt_cb.cb_info.p_nv_save_callback) 276ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski (*gatt_cb.cb_info.p_nv_save_callback)(true, &list.asgn_range); 277911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 278911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 279ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski gatts_init_service_db(list.svc_db, &svc_uuid, is_pri, s_hdl, num_handles); 280911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 281911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson GATT_TRACE_DEBUG( 282911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson "%d: handles needed:%u s_hdl=%u e_hdl=%u %s[%x] is_primary=%d", __func__, 283ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski num_handles, list.asgn_range.s_handle, list.asgn_range.e_handle, 284ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski ((list.asgn_range.svc_uuid.len == 2) ? "uuid16" : "uuid128"), 285ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski list.asgn_range.svc_uuid.uu.uuid16, list.asgn_range.is_primary); 286911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 287911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson service->attribute_handle = s_hdl; 288911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 289911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson btgatt_db_element_t* el = service + 1; 290911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson for (int i = 0; i < count - 1; i++, el++) { 291911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tBT_UUID uuid; 292911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson btif_to_bta_uuid(&uuid, &el->uuid); 293911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 294911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (el->type == BTGATT_DB_CHARACTERISTIC) { 295911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson /* data validity checking */ 296911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (((el->properties & GATT_CHAR_PROP_BIT_AUTH) && 297911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson !(el->permissions & GATT_WRITE_SIGNED_PERM)) || 298911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson ((el->permissions & GATT_WRITE_SIGNED_PERM) && 299911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson !(el->properties & GATT_CHAR_PROP_BIT_AUTH))) { 300911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson GATT_TRACE_DEBUG("Invalid configuration property=0x%02x perm=0x%04x ", 301911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson el->properties, el->permissions); 302a641b6fa2a25e1b5382945d13c4fa49d36084a78Jakub Pawlowski return GATT_INTERNAL_ERROR; 303911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 304911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 3055c1fe35097f5bb48c419a69605fed0e094e797d2Jakub Pawlowski if (is_gatt_attr_type(uuid)) { 3065c1fe35097f5bb48c419a69605fed0e094e797d2Jakub Pawlowski GATT_TRACE_ERROR( 3075c1fe35097f5bb48c419a69605fed0e094e797d2Jakub Pawlowski "%s: attept to add characteristic with UUID equal to GATT " 3085c1fe35097f5bb48c419a69605fed0e094e797d2Jakub Pawlowski "Attribute Type 0x%04x ", 3095c1fe35097f5bb48c419a69605fed0e094e797d2Jakub Pawlowski __func__, uuid.uu.uuid16); 3105c1fe35097f5bb48c419a69605fed0e094e797d2Jakub Pawlowski return GATT_INTERNAL_ERROR; 3115c1fe35097f5bb48c419a69605fed0e094e797d2Jakub Pawlowski } 3125c1fe35097f5bb48c419a69605fed0e094e797d2Jakub Pawlowski 313911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson el->attribute_handle = gatts_add_characteristic( 314ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski list.svc_db, el->permissions, el->properties, uuid); 315911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } else if (el->type == BTGATT_DB_DESCRIPTOR) { 3165c1fe35097f5bb48c419a69605fed0e094e797d2Jakub Pawlowski if (is_gatt_attr_type(uuid)) { 3175c1fe35097f5bb48c419a69605fed0e094e797d2Jakub Pawlowski GATT_TRACE_ERROR( 3185c1fe35097f5bb48c419a69605fed0e094e797d2Jakub Pawlowski "%s: attept to add descriptor with UUID equal to GATT " 3195c1fe35097f5bb48c419a69605fed0e094e797d2Jakub Pawlowski "Attribute Type 0x%04x ", 3205c1fe35097f5bb48c419a69605fed0e094e797d2Jakub Pawlowski __func__, uuid.uu.uuid16); 3215c1fe35097f5bb48c419a69605fed0e094e797d2Jakub Pawlowski return GATT_INTERNAL_ERROR; 3225c1fe35097f5bb48c419a69605fed0e094e797d2Jakub Pawlowski } 3235c1fe35097f5bb48c419a69605fed0e094e797d2Jakub Pawlowski 324911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson el->attribute_handle = 325ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski gatts_add_char_descr(list.svc_db, el->permissions, uuid); 326911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } else if (el->type == BTGATT_DB_INCLUDED_SERVICE) { 327911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tGATT_HDL_LIST_ELEM* p_incl_decl; 328911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_incl_decl = gatt_find_hdl_buffer_by_handle(el->attribute_handle); 329ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski if (p_incl_decl == nullptr) { 330911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson GATT_TRACE_DEBUG("Included Service not created"); 331a641b6fa2a25e1b5382945d13c4fa49d36084a78Jakub Pawlowski return GATT_INTERNAL_ERROR; 332911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 3335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 334911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson el->attribute_handle = gatts_add_included_service( 335ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski list.svc_db, p_incl_decl->asgn_range.s_handle, 336911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_incl_decl->asgn_range.e_handle, p_incl_decl->asgn_range.svc_uuid); 3375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 338911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 3395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 340911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson GATT_TRACE_API("%s: service parsed correctly, now starting", __func__); 3415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 342ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski /*this is a new application service start */ 343a641b6fa2a25e1b5382945d13c4fa49d36084a78Jakub Pawlowski 344ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski // find a place for this service in the list 345ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski auto lst_ptr = gatt_cb.srv_list_info; 346ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski auto it = lst_ptr->begin(); 347ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski for (; it != lst_ptr->end(); it++) { 348ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski if (list.asgn_range.s_handle < it->s_hdl) break; 349ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski } 350ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski auto rit = lst_ptr->emplace(it); 351ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski 352ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski tGATT_SRV_LIST_ELEM& elem = *rit; 353ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski elem.gatt_if = gatt_if; 354ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski elem.s_hdl = list.asgn_range.s_handle; 355ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski elem.e_hdl = list.asgn_range.e_handle; 356ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski elem.p_db = &list.svc_db; 357ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski elem.is_primary = list.asgn_range.is_primary; 358ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski 359ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski memcpy(&elem.app_uuid, &list.asgn_range.app_uuid128, sizeof(tBT_UUID)); 360ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski elem.type = list.asgn_range.is_primary ? GATT_UUID_PRI_SERVICE 361ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski : GATT_UUID_SEC_SERVICE; 362ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski 363ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski if (elem.type == GATT_UUID_PRI_SERVICE) { 364ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski tBT_UUID* p_uuid = gatts_get_service_uuid(elem.p_db); 365ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski elem.sdp_handle = gatt_add_sdp_record(p_uuid, elem.s_hdl, elem.e_hdl); 366ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski } else { 367ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski elem.sdp_handle = 0; 368911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 3695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 370ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski gatt_update_last_pri_srv_info(); 3715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 372ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski GATT_TRACE_DEBUG("%s: allocated el: s_hdl=%d e_hdl=%d type=0x%x sdp_hdl=0x%x", 373ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski __func__, elem.s_hdl, elem.e_hdl, elem.type, 374ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski elem.sdp_handle); 375a641b6fa2a25e1b5382945d13c4fa49d36084a78Jakub Pawlowski 376911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson gatt_proc_srv_chg(); 377a641b6fa2a25e1b5382945d13c4fa49d36084a78Jakub Pawlowski 378911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson return GATT_SERVICE_STARTED; 3795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 380a641b6fa2a25e1b5382945d13c4fa49d36084a78Jakub Pawlowski 381ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowskibool is_active_service(tBT_UUID* p_app_uuid128, tBT_UUID* p_svc_uuid, 382ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski uint16_t start_handle) { 383ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski for (auto& info : *gatt_cb.srv_list_info) { 384ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski tBT_UUID* p_this_uuid = gatts_get_service_uuid(info.p_db); 385ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski 386ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski if (p_this_uuid && gatt_uuid_compare(*p_app_uuid128, info.app_uuid) && 387ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski gatt_uuid_compare(*p_svc_uuid, *p_this_uuid) && 388ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski (start_handle == info.s_hdl)) { 389ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski GATT_TRACE_ERROR("Active Service Found "); 390ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski gatt_dbg_display_uuid(*p_svc_uuid); 391ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski 392ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski return true; 393ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski } 394ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski } 395ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski return false; 396ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski} 397ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski 3985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 399ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 400ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function GATTS_DeleteService 401ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 402ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description This function is called to delete a service. 403ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 404ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Parameter gatt_if : application interface 405ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * p_svc_uuid : service UUID 406ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * start_handle : start handle of the service 407ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 4089ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson * Returns true if the operation succeeded, false if the handle block 4099ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson * was not found. 410ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 411ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/ 412911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonbool GATTS_DeleteService(tGATT_IF gatt_if, tBT_UUID* p_svc_uuid, 413911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson uint16_t svc_inst) { 414911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson GATT_TRACE_DEBUG("GATTS_DeleteService"); 415911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 416ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski tGATT_REG* p_reg = gatt_get_regcb(gatt_if); 417911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (p_reg == NULL) { 418911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson GATT_TRACE_ERROR("Applicaiton not foud"); 419911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson return false; 420911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 421911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 422ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski tBT_UUID* p_app_uuid128 = &p_reg->app_uuid128; 423ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski auto it = gatt_find_hdl_buffer_by_app_id(p_app_uuid128, p_svc_uuid, svc_inst); 424ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski if (it == gatt_cb.hdl_list_info->end()) { 425911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson GATT_TRACE_ERROR("No Service found"); 426911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson return false; 427911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 428911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 429911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson gatt_proc_srv_chg(); 430911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 431ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski if (is_active_service(p_app_uuid128, p_svc_uuid, svc_inst)) { 432ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski GATTS_StopService(it->asgn_range.s_handle); 433911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 434911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 435911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson GATT_TRACE_DEBUG("released handles s_hdl=%u e_hdl=%u", 436ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski it->asgn_range.s_handle, it->asgn_range.e_handle); 437911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 438ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski if ((it->asgn_range.s_handle >= gatt_cb.hdl_cfg.app_start_hdl) && 439911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson gatt_cb.cb_info.p_nv_save_callback) 440ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski (*gatt_cb.cb_info.p_nv_save_callback)(false, &it->asgn_range); 441911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 442ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski gatt_cb.hdl_list_info->erase(it); 443911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson return true; 4445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 4455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 447ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 448ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function GATTS_StopService 449ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 450ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description This function is called to stop a service 451ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 452ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Parameter service_handle : this is the start handle of a service 453ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 454ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns None. 455ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 456ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/ 457911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid GATTS_StopService(uint16_t service_handle) { 458ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski GATT_TRACE_API("%s: %u", __func__, service_handle); 459911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 460ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski auto it = gatt_sr_find_i_rcb_by_handle(service_handle); 461ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski if (it == gatt_cb.srv_list_info->end()) { 462ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski GATT_TRACE_ERROR("%s: service_handle: %u is not in use", __func__, 463911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson service_handle); 464911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 465ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski 466ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski if (it->sdp_handle) { 467ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski SDP_DeleteRecord(it->sdp_handle); 468ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski } 469ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski 470ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski gatt_cb.srv_list_info->erase(it); 471ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski gatt_update_last_pri_srv_info(); 4725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 4735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 474ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 475ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function GATTs_HandleValueIndication 476ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 477ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description This function sends a handle value indication to a client. 478ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 479ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Parameter conn_id: connection identifier. 4809ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson * attr_handle: Attribute handle of this handle value 4819ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson * indication. 482ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * val_len: Length of the indicated attribute value. 483ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * p_val: Pointer to the indicated attribute value data. 484ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 4859ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson * Returns GATT_SUCCESS if sucessfully sent or queued; otherwise error 4869ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson * code. 487ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 488ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/ 489911d1ae03efec2d54c3b1b605589d790d1745488Myles WatsontGATT_STATUS GATTS_HandleValueIndication(uint16_t conn_id, uint16_t attr_handle, 490911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson uint16_t val_len, uint8_t* p_val) { 491911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tGATT_STATUS cmd_status = GATT_NO_RESOURCES; 492911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 493911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tGATT_VALUE indication; 494911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson BT_HDR* p_msg; 495911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tGATT_VALUE* p_buf; 496911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tGATT_IF gatt_if = GATT_GET_GATT_IF(conn_id); 497911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson uint8_t tcb_idx = GATT_GET_TCB_IDX(conn_id); 498911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tGATT_REG* p_reg = gatt_get_regcb(gatt_if); 499911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tGATT_TCB* p_tcb = gatt_get_tcb_by_idx(tcb_idx); 500911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 501911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson GATT_TRACE_API("GATTS_HandleValueIndication"); 502911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if ((p_reg == NULL) || (p_tcb == NULL)) { 503911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson GATT_TRACE_ERROR("GATTS_HandleValueIndication Unknown conn_id: %u ", 504911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson conn_id); 505911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson return (tGATT_STATUS)GATT_INVALID_CONN_ID; 506911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 507911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 508911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (!GATT_HANDLE_IS_VALID(attr_handle)) return GATT_ILLEGAL_PARAMETER; 509911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 510911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson indication.conn_id = conn_id; 511911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson indication.handle = attr_handle; 512911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson indication.len = val_len; 513911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson memcpy(indication.value, p_val, val_len); 514911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson indication.auth_req = GATT_AUTH_REQ_NONE; 515911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 516911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (GATT_HANDLE_IS_VALID(p_tcb->indicate_handle)) { 517911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson GATT_TRACE_DEBUG("Add a pending indication"); 518911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_buf = gatt_add_pending_ind(p_tcb, &indication); 519911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (p_buf != NULL) { 520911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson cmd_status = GATT_SUCCESS; 521911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } else { 522911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson cmd_status = GATT_NO_RESOURCES; 5235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 524911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } else { 525911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_msg = attp_build_sr_msg(p_tcb, GATT_HANDLE_VALUE_IND, 526911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson (tGATT_SR_MSG*)&indication); 527911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (p_msg != NULL) { 528911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson cmd_status = attp_send_sr_msg(p_tcb, p_msg); 529911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 530911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (cmd_status == GATT_SUCCESS || cmd_status == GATT_CONGESTED) { 531911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_tcb->indicate_handle = indication.handle; 532911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson gatt_start_conf_timer(p_tcb); 533911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 53417b04bd498405f2bb109a85562ebbdcb6bb06e95Andre Eisenbach } 535911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 536911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson return cmd_status; 5375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 5385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 5395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 540ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 541ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function GATTS_HandleValueNotification 542ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 543ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description This function sends a handle value notification to a client. 544ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 545ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Parameter conn_id: connection identifier. 5469ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson * attr_handle: Attribute handle of this handle value 5479ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson * indication. 548ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * val_len: Length of the indicated attribute value. 549ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * p_val: Pointer to the indicated attribute value data. 550ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 551ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns GATT_SUCCESS if sucessfully sent; otherwise error code. 552ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 553ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/ 554911d1ae03efec2d54c3b1b605589d790d1745488Myles WatsontGATT_STATUS GATTS_HandleValueNotification(uint16_t conn_id, 555911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson uint16_t attr_handle, 556911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson uint16_t val_len, uint8_t* p_val) { 557911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tGATT_STATUS cmd_sent = GATT_ILLEGAL_PARAMETER; 558911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson BT_HDR* p_buf; 559911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tGATT_VALUE notif; 560911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tGATT_IF gatt_if = GATT_GET_GATT_IF(conn_id); 561911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson uint8_t tcb_idx = GATT_GET_TCB_IDX(conn_id); 562911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tGATT_REG* p_reg = gatt_get_regcb(gatt_if); 563911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tGATT_TCB* p_tcb = gatt_get_tcb_by_idx(tcb_idx); 564911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 565911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson GATT_TRACE_API("GATTS_HandleValueNotification"); 566911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 567911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if ((p_reg == NULL) || (p_tcb == NULL)) { 568911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson GATT_TRACE_ERROR("GATTS_HandleValueNotification Unknown conn_id: %u ", 569911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson conn_id); 570911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson return (tGATT_STATUS)GATT_INVALID_CONN_ID; 571911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 572911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 573911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (GATT_HANDLE_IS_VALID(attr_handle)) { 574911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson notif.handle = attr_handle; 575911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson notif.len = val_len; 576911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson memcpy(notif.value, p_val, val_len); 577911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson notif.auth_req = GATT_AUTH_REQ_NONE; 578911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson ; 579911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 580911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_buf = attp_build_sr_msg(p_tcb, GATT_HANDLE_VALUE_NOTIF, 581911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson (tGATT_SR_MSG*)¬if); 582911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (p_buf != NULL) { 583911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson cmd_sent = attp_send_sr_msg(p_tcb, p_buf); 584911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } else 585911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson cmd_sent = GATT_NO_RESOURCES; 586911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 587911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson return cmd_sent; 5885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 5895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 5905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 591ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 592ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function GATTS_SendRsp 593ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 594ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description This function sends the server response to client. 595ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 596ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Parameter conn_id: connection identifier. 597ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * trans_id: transaction id 598ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * status: response status 599ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * p_msg: pointer to message parameters structure. 600ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 601ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns GATT_SUCCESS if sucessfully sent; otherwise error code. 602ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 603ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/ 604911d1ae03efec2d54c3b1b605589d790d1745488Myles WatsontGATT_STATUS GATTS_SendRsp(uint16_t conn_id, uint32_t trans_id, 605911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tGATT_STATUS status, tGATTS_RSP* p_msg) { 606911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tGATT_STATUS cmd_sent = GATT_ILLEGAL_PARAMETER; 607911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tGATT_IF gatt_if = GATT_GET_GATT_IF(conn_id); 608911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson uint8_t tcb_idx = GATT_GET_TCB_IDX(conn_id); 609911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tGATT_REG* p_reg = gatt_get_regcb(gatt_if); 610911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tGATT_TCB* p_tcb = gatt_get_tcb_by_idx(tcb_idx); 611911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 612911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson GATT_TRACE_API("GATTS_SendRsp: conn_id: %u trans_id: %u Status: 0x%04x", 613911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson conn_id, trans_id, status); 614911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 615911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if ((p_reg == NULL) || (p_tcb == NULL)) { 616911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson GATT_TRACE_ERROR("GATTS_SendRsp Unknown conn_id: %u ", conn_id); 617911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson return (tGATT_STATUS)GATT_INVALID_CONN_ID; 618911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 619911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 620911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (p_tcb->sr_cmd.trans_id != trans_id) { 621911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson GATT_TRACE_ERROR("GATTS_SendRsp conn_id: %u waiting for op_code = %02x", 622911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson conn_id, p_tcb->sr_cmd.op_code); 623911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 624911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson return (GATT_WRONG_STATE); 625911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 626911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson /* Process App response */ 627911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson cmd_sent = gatt_sr_process_app_rsp(p_tcb, gatt_if, trans_id, 628911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_tcb->sr_cmd.op_code, status, p_msg); 629911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 630911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson return cmd_sent; 6315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 6325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 633ee96a3c60fca590d38025925c072d264e06493c4Myles Watson/******************************************************************************/ 6345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/* GATT Profile Srvr Functions */ 635ee96a3c60fca590d38025925c072d264e06493c4Myles Watson/******************************************************************************/ 6365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 637ee96a3c60fca590d38025925c072d264e06493c4Myles Watson/******************************************************************************/ 6389ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson/* */ 6399ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson/* GATT CLIENT APIs */ 6409ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson/* */ 641ee96a3c60fca590d38025925c072d264e06493c4Myles Watson/******************************************************************************/ 6425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 6435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 644ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 645ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function GATTC_ConfigureMTU 646ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 647ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description This function is called to configure the ATT MTU size. 648ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 649ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Parameters conn_id: connection identifier. 650ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * mtu - attribute MTU size.. 651ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 652ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns GATT_SUCCESS if command started successfully. 653ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 654ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/ 655911d1ae03efec2d54c3b1b605589d790d1745488Myles WatsontGATT_STATUS GATTC_ConfigureMTU(uint16_t conn_id, uint16_t mtu) { 656911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson uint8_t ret = GATT_NO_RESOURCES; 657911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tGATT_IF gatt_if = GATT_GET_GATT_IF(conn_id); 658911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson uint8_t tcb_idx = GATT_GET_TCB_IDX(conn_id); 659911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tGATT_TCB* p_tcb = gatt_get_tcb_by_idx(tcb_idx); 660911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tGATT_REG* p_reg = gatt_get_regcb(gatt_if); 661911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 662911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tGATT_CLCB* p_clcb; 663911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 664911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson GATT_TRACE_API("GATTC_ConfigureMTU conn_id=%d mtu=%d", conn_id, mtu); 665911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 666911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if ((p_tcb == NULL) || (p_reg == NULL) || (mtu < GATT_DEF_BLE_MTU_SIZE) || 667911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson (mtu > GATT_MAX_MTU_SIZE)) { 668911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson return GATT_ILLEGAL_PARAMETER; 669911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 670911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 671911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson /* Validate that the link is BLE, not BR/EDR */ 672911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (p_tcb->transport != BT_TRANSPORT_LE) { 673911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson return GATT_ERROR; 674911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 675911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 676911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (gatt_is_clcb_allocated(conn_id)) { 677911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson GATT_TRACE_ERROR("GATTC_ConfigureMTU GATT_BUSY conn_id = %d", conn_id); 678911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson return GATT_BUSY; 679911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 680911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 681911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_clcb = gatt_clcb_alloc(conn_id); 682911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (p_clcb != NULL) { 683911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_clcb->p_tcb->payload_size = mtu; 684911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_clcb->operation = GATTC_OPTYPE_CONFIG; 685911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 686911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson ret = attp_send_cl_msg(p_clcb->p_tcb, p_clcb->clcb_idx, GATT_REQ_MTU, 687911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson (tGATT_CL_MSG*)&mtu); 688911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 689911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 690911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson return ret; 6915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 6925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 693eafd45d08653bb1621c82a2f3cf922a43a0b1bc5Jakub Pawlowskivoid read_phy_cb( 694eafd45d08653bb1621c82a2f3cf922a43a0b1bc5Jakub Pawlowski base::Callback<void(uint8_t tx_phy, uint8_t rx_phy, uint8_t status)> cb, 695eafd45d08653bb1621c82a2f3cf922a43a0b1bc5Jakub Pawlowski uint8_t* data, uint16_t len) { 696eafd45d08653bb1621c82a2f3cf922a43a0b1bc5Jakub Pawlowski uint8_t status, tx_phy, rx_phy; 697eafd45d08653bb1621c82a2f3cf922a43a0b1bc5Jakub Pawlowski uint16_t handle; 698eafd45d08653bb1621c82a2f3cf922a43a0b1bc5Jakub Pawlowski 699b5ba4fdbc433544de3806f8e82976898e444b491Jakub Pawlowski LOG_ASSERT(len == 5) << "Received bad response length: " << len; 700eafd45d08653bb1621c82a2f3cf922a43a0b1bc5Jakub Pawlowski uint8_t* pp = data; 701eafd45d08653bb1621c82a2f3cf922a43a0b1bc5Jakub Pawlowski STREAM_TO_UINT8(status, pp); 702eafd45d08653bb1621c82a2f3cf922a43a0b1bc5Jakub Pawlowski STREAM_TO_UINT16(handle, pp); 703eafd45d08653bb1621c82a2f3cf922a43a0b1bc5Jakub Pawlowski handle = handle & 0x0FFF; 704eafd45d08653bb1621c82a2f3cf922a43a0b1bc5Jakub Pawlowski STREAM_TO_UINT8(tx_phy, pp); 705eafd45d08653bb1621c82a2f3cf922a43a0b1bc5Jakub Pawlowski STREAM_TO_UINT8(rx_phy, pp); 706eafd45d08653bb1621c82a2f3cf922a43a0b1bc5Jakub Pawlowski 707eafd45d08653bb1621c82a2f3cf922a43a0b1bc5Jakub Pawlowski DVLOG(1) << __func__ << " Received read_phy_cb"; 708eafd45d08653bb1621c82a2f3cf922a43a0b1bc5Jakub Pawlowski cb.Run(tx_phy, rx_phy, status); 709eafd45d08653bb1621c82a2f3cf922a43a0b1bc5Jakub Pawlowski} 710eafd45d08653bb1621c82a2f3cf922a43a0b1bc5Jakub Pawlowski 711eafd45d08653bb1621c82a2f3cf922a43a0b1bc5Jakub Pawlowskivoid GATTC_ReadPHY( 712eafd45d08653bb1621c82a2f3cf922a43a0b1bc5Jakub Pawlowski uint16_t conn_id, 713eafd45d08653bb1621c82a2f3cf922a43a0b1bc5Jakub Pawlowski base::Callback<void(uint8_t tx_phy, uint8_t rx_phy, uint8_t status)> cb) { 714eafd45d08653bb1621c82a2f3cf922a43a0b1bc5Jakub Pawlowski uint8_t tcb_idx = GATT_GET_TCB_IDX(conn_id); 715eafd45d08653bb1621c82a2f3cf922a43a0b1bc5Jakub Pawlowski tGATT_TCB* p_tcb = gatt_get_tcb_by_idx(tcb_idx); 716eafd45d08653bb1621c82a2f3cf922a43a0b1bc5Jakub Pawlowski if (p_tcb == NULL) { 717eafd45d08653bb1621c82a2f3cf922a43a0b1bc5Jakub Pawlowski GATT_TRACE_ERROR("%s: no p_tcb for conn_id %d", __func__, conn_id); 718eafd45d08653bb1621c82a2f3cf922a43a0b1bc5Jakub Pawlowski cb.Run(0, 0, GATT_INVALID_HANDLE); 719eafd45d08653bb1621c82a2f3cf922a43a0b1bc5Jakub Pawlowski return; 720eafd45d08653bb1621c82a2f3cf922a43a0b1bc5Jakub Pawlowski } 721eafd45d08653bb1621c82a2f3cf922a43a0b1bc5Jakub Pawlowski 722eafd45d08653bb1621c82a2f3cf922a43a0b1bc5Jakub Pawlowski tACL_CONN* p_lcb = btm_bda_to_acl(p_tcb->peer_bda, BT_TRANSPORT_LE); 723eafd45d08653bb1621c82a2f3cf922a43a0b1bc5Jakub Pawlowski if (p_lcb == NULL) { 724eafd45d08653bb1621c82a2f3cf922a43a0b1bc5Jakub Pawlowski GATT_TRACE_ERROR("%s: no p_lcb for conn_id %d", __func__, conn_id); 725eafd45d08653bb1621c82a2f3cf922a43a0b1bc5Jakub Pawlowski cb.Run(0, 0, GATT_INVALID_HANDLE); 726eafd45d08653bb1621c82a2f3cf922a43a0b1bc5Jakub Pawlowski return; 727eafd45d08653bb1621c82a2f3cf922a43a0b1bc5Jakub Pawlowski } 728eafd45d08653bb1621c82a2f3cf922a43a0b1bc5Jakub Pawlowski uint16_t handle = p_lcb->hci_handle; 729eafd45d08653bb1621c82a2f3cf922a43a0b1bc5Jakub Pawlowski 730eafd45d08653bb1621c82a2f3cf922a43a0b1bc5Jakub Pawlowski const uint8_t len = 2; 731eafd45d08653bb1621c82a2f3cf922a43a0b1bc5Jakub Pawlowski uint8_t data[len]; 732eafd45d08653bb1621c82a2f3cf922a43a0b1bc5Jakub Pawlowski uint8_t* pp = data; 733eafd45d08653bb1621c82a2f3cf922a43a0b1bc5Jakub Pawlowski UINT16_TO_STREAM(pp, handle); 734eafd45d08653bb1621c82a2f3cf922a43a0b1bc5Jakub Pawlowski btu_hcif_send_cmd_with_cb(FROM_HERE, HCI_LE_READ_PHY, data, len, 735eafd45d08653bb1621c82a2f3cf922a43a0b1bc5Jakub Pawlowski base::Bind(&read_phy_cb, std::move(cb))); 736eafd45d08653bb1621c82a2f3cf922a43a0b1bc5Jakub Pawlowski} 737eafd45d08653bb1621c82a2f3cf922a43a0b1bc5Jakub Pawlowski 738eafd45d08653bb1621c82a2f3cf922a43a0b1bc5Jakub Pawlowskivoid doNothing(uint8_t* data, uint16_t len) {} 739eafd45d08653bb1621c82a2f3cf922a43a0b1bc5Jakub Pawlowski 740eafd45d08653bb1621c82a2f3cf922a43a0b1bc5Jakub Pawlowskivoid GATTC_SetPreferredPHY(uint16_t conn_id, uint8_t tx_phy, uint8_t rx_phy, 741eafd45d08653bb1621c82a2f3cf922a43a0b1bc5Jakub Pawlowski uint16_t phy_options) { 742eafd45d08653bb1621c82a2f3cf922a43a0b1bc5Jakub Pawlowski uint8_t tcb_idx = GATT_GET_TCB_IDX(conn_id); 743eafd45d08653bb1621c82a2f3cf922a43a0b1bc5Jakub Pawlowski tGATT_TCB* p_tcb = gatt_get_tcb_by_idx(tcb_idx); 744eafd45d08653bb1621c82a2f3cf922a43a0b1bc5Jakub Pawlowski if (p_tcb == NULL) { 745eafd45d08653bb1621c82a2f3cf922a43a0b1bc5Jakub Pawlowski GATT_TRACE_ERROR("%s: no p_tcb for conn_id %d", __func__, conn_id); 746eafd45d08653bb1621c82a2f3cf922a43a0b1bc5Jakub Pawlowski return; 747eafd45d08653bb1621c82a2f3cf922a43a0b1bc5Jakub Pawlowski } 748eafd45d08653bb1621c82a2f3cf922a43a0b1bc5Jakub Pawlowski 749eafd45d08653bb1621c82a2f3cf922a43a0b1bc5Jakub Pawlowski tACL_CONN* p_lcb = btm_bda_to_acl(p_tcb->peer_bda, BT_TRANSPORT_LE); 750eafd45d08653bb1621c82a2f3cf922a43a0b1bc5Jakub Pawlowski if (p_lcb == NULL) { 751eafd45d08653bb1621c82a2f3cf922a43a0b1bc5Jakub Pawlowski GATT_TRACE_ERROR("%s: no p_lcb for conn_id %d", __func__, conn_id); 752eafd45d08653bb1621c82a2f3cf922a43a0b1bc5Jakub Pawlowski return; 753eafd45d08653bb1621c82a2f3cf922a43a0b1bc5Jakub Pawlowski } 754eafd45d08653bb1621c82a2f3cf922a43a0b1bc5Jakub Pawlowski uint16_t handle = p_lcb->hci_handle; 755eafd45d08653bb1621c82a2f3cf922a43a0b1bc5Jakub Pawlowski 756eafd45d08653bb1621c82a2f3cf922a43a0b1bc5Jakub Pawlowski uint8_t all_phys = 0; 757eafd45d08653bb1621c82a2f3cf922a43a0b1bc5Jakub Pawlowski if (tx_phy == 0) all_phys &= 0x01; 758eafd45d08653bb1621c82a2f3cf922a43a0b1bc5Jakub Pawlowski if (rx_phy == 0) all_phys &= 0x02; 759eafd45d08653bb1621c82a2f3cf922a43a0b1bc5Jakub Pawlowski 760eafd45d08653bb1621c82a2f3cf922a43a0b1bc5Jakub Pawlowski const uint8_t len = 7; 761eafd45d08653bb1621c82a2f3cf922a43a0b1bc5Jakub Pawlowski uint8_t data[len]; 762eafd45d08653bb1621c82a2f3cf922a43a0b1bc5Jakub Pawlowski uint8_t* pp = data; 763eafd45d08653bb1621c82a2f3cf922a43a0b1bc5Jakub Pawlowski UINT16_TO_STREAM(pp, handle); 764eafd45d08653bb1621c82a2f3cf922a43a0b1bc5Jakub Pawlowski UINT8_TO_STREAM(pp, all_phys); 765eafd45d08653bb1621c82a2f3cf922a43a0b1bc5Jakub Pawlowski UINT8_TO_STREAM(pp, tx_phy); 766eafd45d08653bb1621c82a2f3cf922a43a0b1bc5Jakub Pawlowski UINT8_TO_STREAM(pp, rx_phy); 767eafd45d08653bb1621c82a2f3cf922a43a0b1bc5Jakub Pawlowski UINT16_TO_STREAM(pp, phy_options); 768eafd45d08653bb1621c82a2f3cf922a43a0b1bc5Jakub Pawlowski btu_hcif_send_cmd_with_cb(FROM_HERE, HCI_LE_SET_PHY, data, len, 769eafd45d08653bb1621c82a2f3cf922a43a0b1bc5Jakub Pawlowski base::Bind(doNothing)); 770eafd45d08653bb1621c82a2f3cf922a43a0b1bc5Jakub Pawlowski} 771eafd45d08653bb1621c82a2f3cf922a43a0b1bc5Jakub Pawlowski 7725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 773ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 774ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function GATTC_Discover 775ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 7769ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson * Description This function is called to do a discovery procedure on ATT 7779ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson * server. 778ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 779ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Parameters conn_id: connection identifier. 780ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * disc_type:discovery type. 781ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * p_param: parameters of discovery requirement. 782ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 783ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns GATT_SUCCESS if command received/sent successfully. 784ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 785ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/ 786911d1ae03efec2d54c3b1b605589d790d1745488Myles WatsontGATT_STATUS GATTC_Discover(uint16_t conn_id, tGATT_DISC_TYPE disc_type, 787911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tGATT_DISC_PARAM* p_param) { 788911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tGATT_STATUS status = GATT_SUCCESS; 789911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tGATT_CLCB* p_clcb; 790911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tGATT_IF gatt_if = GATT_GET_GATT_IF(conn_id); 791911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson uint8_t tcb_idx = GATT_GET_TCB_IDX(conn_id); 792911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tGATT_TCB* p_tcb = gatt_get_tcb_by_idx(tcb_idx); 793911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tGATT_REG* p_reg = gatt_get_regcb(gatt_if); 794911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 795911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson GATT_TRACE_API("GATTC_Discover conn_id=%d disc_type=%d", conn_id, disc_type); 796911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 797911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if ((p_tcb == NULL) || (p_reg == NULL) || (p_param == NULL) || 798911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson (disc_type >= GATT_DISC_MAX)) { 799911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson GATT_TRACE_ERROR("GATTC_Discover Illegal param: disc_type %d conn_id = %d", 800911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson disc_type, conn_id); 801911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson return GATT_ILLEGAL_PARAMETER; 802911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 803911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 804911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (gatt_is_clcb_allocated(conn_id)) { 805911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson GATT_TRACE_ERROR("GATTC_Discover GATT_BUSY conn_id = %d", conn_id); 806911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson return GATT_BUSY; 807911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 808911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 809911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_clcb = gatt_clcb_alloc(conn_id); 810911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (p_clcb != NULL) { 811911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (!GATT_HANDLE_IS_VALID(p_param->s_handle) || 812911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson !GATT_HANDLE_IS_VALID(p_param->e_handle) || 813911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson /* search by type does not have a valid UUID param */ 814911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson (disc_type == GATT_DISC_SRVC_BY_UUID && p_param->service.len == 0)) { 815911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson gatt_clcb_dealloc(p_clcb); 816911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson return GATT_ILLEGAL_PARAMETER; 8175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 8185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 819911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_clcb->operation = GATTC_OPTYPE_DISCOVERY; 820911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_clcb->op_subtype = disc_type; 821911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_clcb->s_handle = p_param->s_handle; 822911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_clcb->e_handle = p_param->e_handle; 823911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_clcb->uuid = p_param->service; 824911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 825911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson gatt_act_discovery(p_clcb); 826911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } else { 827911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson status = GATT_NO_RESOURCES; 828911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 829911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson return status; 8305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 8315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 8325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 833ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 834ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function GATTC_Read 835ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 8369ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson * Description This function is called to read the value of an attribute 8379ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson * from the server. 838ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 839ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Parameters conn_id: connection identifier. 840ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * type - attribute read type. 841ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * p_read - read operation parameters. 842ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 843ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns GATT_SUCCESS if command started successfully. 844ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 845ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/ 846911d1ae03efec2d54c3b1b605589d790d1745488Myles WatsontGATT_STATUS GATTC_Read(uint16_t conn_id, tGATT_READ_TYPE type, 847911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tGATT_READ_PARAM* p_read) { 848911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tGATT_STATUS status = GATT_SUCCESS; 849911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tGATT_CLCB* p_clcb; 850911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tGATT_IF gatt_if = GATT_GET_GATT_IF(conn_id); 851911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson uint8_t tcb_idx = GATT_GET_TCB_IDX(conn_id); 852911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tGATT_TCB* p_tcb = gatt_get_tcb_by_idx(tcb_idx); 853911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tGATT_REG* p_reg = gatt_get_regcb(gatt_if); 854911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 855911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson GATT_TRACE_API("GATTC_Read conn_id=%d type=%d", conn_id, type); 856911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 857911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if ((p_tcb == NULL) || (p_reg == NULL) || (p_read == NULL) || 858911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson ((type >= GATT_READ_MAX) || (type == 0))) { 859911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson GATT_TRACE_ERROR("GATT_Read Illegal param: conn_id %d, type 0%d,", conn_id, 860911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson type); 861911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson return GATT_ILLEGAL_PARAMETER; 862911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 863911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 864911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (gatt_is_clcb_allocated(conn_id)) { 865911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson GATT_TRACE_ERROR("GATTC_Read GATT_BUSY conn_id = %d", conn_id); 866911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson return GATT_BUSY; 867911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 868911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 869911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_clcb = gatt_clcb_alloc(conn_id); 870911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (p_clcb != NULL) { 871911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_clcb->operation = GATTC_OPTYPE_READ; 872911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_clcb->op_subtype = type; 873911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_clcb->auth_req = p_read->by_handle.auth_req; 874911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_clcb->counter = 0; 875911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 876911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson switch (type) { 877911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson case GATT_READ_BY_TYPE: 878911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson case GATT_READ_CHAR_VALUE: 879911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_clcb->s_handle = p_read->service.s_handle; 880911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_clcb->e_handle = p_read->service.e_handle; 881911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson memcpy(&p_clcb->uuid, &p_read->service.uuid, sizeof(tBT_UUID)); 882911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson break; 883911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson case GATT_READ_MULTIPLE: { 884911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_clcb->s_handle = 0; 885911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson /* copy multiple handles in CB */ 886911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tGATT_READ_MULTI* p_read_multi = 887911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson (tGATT_READ_MULTI*)osi_malloc(sizeof(tGATT_READ_MULTI)); 888911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_clcb->p_attr_buf = (uint8_t*)p_read_multi; 889911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson memcpy(p_read_multi, &p_read->read_multiple, sizeof(tGATT_READ_MULTI)); 890911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson break; 891911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 892911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson case GATT_READ_BY_HANDLE: 893911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson case GATT_READ_PARTIAL: 894911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson memset(&p_clcb->uuid, 0, sizeof(tBT_UUID)); 895911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_clcb->s_handle = p_read->by_handle.handle; 896911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 897911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (type == GATT_READ_PARTIAL) { 898911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_clcb->counter = p_read->partial.offset; 8995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 900911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 901911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson break; 902911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson default: 903911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson break; 9045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 905911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson /* start security check */ 906911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (gatt_security_check_start(p_clcb) == false) { 907911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson status = GATT_NO_RESOURCES; 908911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson gatt_clcb_dealloc(p_clcb); 9095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 910911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } else { 911911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson status = GATT_NO_RESOURCES; 912911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 913911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson return status; 9145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 9155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 9165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 917ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 918ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function GATTC_Write 919ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 9209ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson * Description This function is called to write the value of an attribute 9219ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson * to the server. 922ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 923ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Parameters conn_id: connection identifier. 924ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * type - attribute write type. 925ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * p_write - write operation parameters. 926ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 927ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns GATT_SUCCESS if command started successfully. 928ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 929ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/ 930911d1ae03efec2d54c3b1b605589d790d1745488Myles WatsontGATT_STATUS GATTC_Write(uint16_t conn_id, tGATT_WRITE_TYPE type, 931911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tGATT_VALUE* p_write) { 932911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tGATT_STATUS status = GATT_SUCCESS; 933911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tGATT_CLCB* p_clcb; 934911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tGATT_VALUE* p; 935911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tGATT_IF gatt_if = GATT_GET_GATT_IF(conn_id); 936911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson uint8_t tcb_idx = GATT_GET_TCB_IDX(conn_id); 937911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tGATT_TCB* p_tcb = gatt_get_tcb_by_idx(tcb_idx); 938911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tGATT_REG* p_reg = gatt_get_regcb(gatt_if); 939911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 940911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if ((p_tcb == NULL) || (p_reg == NULL) || (p_write == NULL) || 941911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson ((type != GATT_WRITE) && (type != GATT_WRITE_PREPARE) && 942911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson (type != GATT_WRITE_NO_RSP))) { 943911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson GATT_TRACE_ERROR("GATT_Write Illegal param: conn_id %d, type 0%d,", conn_id, 944911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson type); 945911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson return GATT_ILLEGAL_PARAMETER; 946911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 947911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 948911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (gatt_is_clcb_allocated(conn_id)) { 949911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson GATT_TRACE_ERROR("GATTC_Write GATT_BUSY conn_id = %d", conn_id); 950911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson return GATT_BUSY; 951911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 952911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 953911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_clcb = gatt_clcb_alloc(conn_id); 954911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (p_clcb != NULL) { 955911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_clcb->operation = GATTC_OPTYPE_WRITE; 956911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_clcb->op_subtype = type; 957911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_clcb->auth_req = p_write->auth_req; 958911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 959911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_clcb->p_attr_buf = (uint8_t*)osi_malloc(sizeof(tGATT_VALUE)); 960911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson memcpy(p_clcb->p_attr_buf, (void*)p_write, sizeof(tGATT_VALUE)); 961911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 962911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p = (tGATT_VALUE*)p_clcb->p_attr_buf; 963911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (type == GATT_WRITE_PREPARE) { 964911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_clcb->start_offset = p_write->offset; 965911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p->offset = 0; 9665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 9675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 968911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (gatt_security_check_start(p_clcb) == false) { 969911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson status = GATT_NO_RESOURCES; 9705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 9715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 972911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (status == GATT_NO_RESOURCES) gatt_clcb_dealloc(p_clcb); 973911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } else { 974911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson status = GATT_NO_RESOURCES; 975911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 976911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson return status; 9775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 9785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 9795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 980ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 981ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function GATTC_ExecuteWrite 982ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 983ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description This function is called to send an Execute write request to 984ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * the server. 985ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 986ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Parameters conn_id: connection identifier. 9879ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson * is_execute - to execute or cancel the prepared write 9889ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson * request(s) 989ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 990ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns GATT_SUCCESS if command started successfully. 991ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 992ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/ 993911d1ae03efec2d54c3b1b605589d790d1745488Myles WatsontGATT_STATUS GATTC_ExecuteWrite(uint16_t conn_id, bool is_execute) { 994911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tGATT_STATUS status = GATT_SUCCESS; 995911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tGATT_CLCB* p_clcb; 996911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tGATT_EXEC_FLAG flag; 997911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tGATT_IF gatt_if = GATT_GET_GATT_IF(conn_id); 998911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson uint8_t tcb_idx = GATT_GET_TCB_IDX(conn_id); 999911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tGATT_TCB* p_tcb = gatt_get_tcb_by_idx(tcb_idx); 1000911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tGATT_REG* p_reg = gatt_get_regcb(gatt_if); 1001911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 1002911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson GATT_TRACE_API("GATTC_ExecuteWrite conn_id=%d is_execute=%d", conn_id, 1003911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson is_execute); 1004911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 1005911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if ((p_tcb == NULL) || (p_reg == NULL)) { 1006911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson GATT_TRACE_ERROR("GATTC_ExecuteWrite Illegal param: conn_id %d", conn_id); 1007911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson return GATT_ILLEGAL_PARAMETER; 1008911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 1009911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 1010911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (gatt_is_clcb_allocated(conn_id)) { 1011911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson GATT_TRACE_ERROR("GATTC_Write GATT_BUSY conn_id = %d", conn_id); 1012911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson return GATT_BUSY; 1013911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 1014911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 1015911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_clcb = gatt_clcb_alloc(conn_id); 1016911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (p_clcb != NULL) { 1017911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_clcb->operation = GATTC_OPTYPE_EXE_WRITE; 1018911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson flag = is_execute ? GATT_PREP_WRITE_EXEC : GATT_PREP_WRITE_CANCEL; 1019911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson gatt_send_queue_write_cancel(p_clcb->p_tcb, p_clcb, flag); 1020911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } else { 1021911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson GATT_TRACE_ERROR("Unable to allocate client CB for conn_id %d ", conn_id); 1022911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson status = GATT_NO_RESOURCES; 1023911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 1024911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson return status; 10255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 10265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 10275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 1028ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 1029ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function GATTC_SendHandleValueConfirm 1030ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 1031ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description This function is called to send a handle value confirmation 1032ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * as response to a handle value notification from server. 1033ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 1034ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Parameters conn_id: connection identifier. 1035ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * handle: the handle of the attribute confirmation. 1036ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 1037ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns GATT_SUCCESS if command started successfully. 1038ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 1039ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/ 1040911d1ae03efec2d54c3b1b605589d790d1745488Myles WatsontGATT_STATUS GATTC_SendHandleValueConfirm(uint16_t conn_id, uint16_t handle) { 1041911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tGATT_STATUS ret = GATT_ILLEGAL_PARAMETER; 1042911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tGATT_TCB* p_tcb = gatt_get_tcb_by_idx(GATT_GET_TCB_IDX(conn_id)); 10435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1044911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson GATT_TRACE_API("GATTC_SendHandleValueConfirm conn_id=%d handle=0x%x", conn_id, 1045911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson handle); 10465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1047911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (p_tcb) { 1048911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (p_tcb->ind_count > 0) { 1049911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson alarm_cancel(p_tcb->ind_ack_timer); 10505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1051911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson GATT_TRACE_DEBUG("notif_count=%d ", p_tcb->ind_count); 1052911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson /* send confirmation now */ 1053911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson ret = attp_send_cl_msg(p_tcb, 0, GATT_HANDLE_VALUE_CONF, 1054911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson (tGATT_CL_MSG*)&handle); 10555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1056911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_tcb->ind_count = 0; 10575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1058911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } else { 1059911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson GATT_TRACE_DEBUG( 1060911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson "GATTC_SendHandleValueConfirm - conn_id: %u - ignored not waiting " 1061911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson "for indicaiton ack", 1062911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson conn_id); 1063911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson ret = GATT_SUCCESS; 10645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 1065911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } else { 1066911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson GATT_TRACE_ERROR("GATTC_SendHandleValueConfirm - Unknown conn_id: %u", 1067911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson conn_id); 1068911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 1069911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson return ret; 10705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 10715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1072ee96a3c60fca590d38025925c072d264e06493c4Myles Watson/******************************************************************************/ 10739ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson/* */ 10749ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson/* GATT APIs */ 10759ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson/* */ 1076ee96a3c60fca590d38025925c072d264e06493c4Myles Watson/******************************************************************************/ 10775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 1078ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 1079ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function GATT_SetIdleTimeout 1080ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 10819ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson * Description This function (common to both client and server) sets the 10829ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson * idle timeout for a tansport connection 1083ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 1084ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Parameter bd_addr: target device bd address. 1085ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * idle_tout: timeout value in seconds. 1086ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 1087ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns void 1088ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 1089ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/ 1090911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid GATT_SetIdleTimeout(BD_ADDR bd_addr, uint16_t idle_tout, 1091911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tBT_TRANSPORT transport) { 1092911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tGATT_TCB* p_tcb; 1093911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson bool status = false; 1094911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 1095911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_tcb = gatt_find_tcb_by_addr(bd_addr, transport); 1096911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (p_tcb != NULL) { 1097911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (p_tcb->att_lcid == L2CAP_ATT_CID) { 1098911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson status = L2CA_SetFixedChannelTout(bd_addr, L2CAP_ATT_CID, idle_tout); 1099911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 1100911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (idle_tout == GATT_LINK_IDLE_TIMEOUT_WHEN_NO_APP) 1101911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson L2CA_SetIdleTimeoutByBdAddr(p_tcb->peer_bda, 1102911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson GATT_LINK_IDLE_TIMEOUT_WHEN_NO_APP, 1103911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson BT_TRANSPORT_LE); 1104911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } else { 1105911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson status = L2CA_SetIdleTimeout(p_tcb->att_lcid, idle_tout, false); 11065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 1107911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 11085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1109911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson GATT_TRACE_API( 1110911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson "GATT_SetIdleTimeout idle_tout=%d status=%d(1-OK 0-not performed)", 1111911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson idle_tout, status); 11125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 11135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 11145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 1115ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 1116ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function GATT_Register 1117ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 1118ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description This function is called to register an application 1119ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * with GATT 1120ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 1121ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Parameter p_app_uuid128: Application UUID 1122ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * p_cb_info: callback functions. 1123ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 11249ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson * Returns 0 for error, otherwise the index of the client registered 11259ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson * with GATT 1126ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 1127ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/ 1128911d1ae03efec2d54c3b1b605589d790d1745488Myles WatsontGATT_IF GATT_Register(tBT_UUID* p_app_uuid128, tGATT_CBACK* p_cb_info) { 1129911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tGATT_REG* p_reg; 1130911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson uint8_t i_gatt_if = 0; 1131911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tGATT_IF gatt_if = 0; 1132911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 1133911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson GATT_TRACE_API("%s", __func__); 1134911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson gatt_dbg_display_uuid(*p_app_uuid128); 1135911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 1136911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson for (i_gatt_if = 0, p_reg = gatt_cb.cl_rcb; i_gatt_if < GATT_MAX_APPS; 1137911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson i_gatt_if++, p_reg++) { 1138911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (p_reg->in_use && 1139911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson !memcmp(p_app_uuid128->uu.uuid128, p_reg->app_uuid128.uu.uuid128, 1140911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson LEN_UUID_128)) { 1141911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson GATT_TRACE_ERROR("application already registered."); 1142911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson return 0; 11435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 1144911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 1145911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 1146911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson for (i_gatt_if = 0, p_reg = gatt_cb.cl_rcb; i_gatt_if < GATT_MAX_APPS; 1147911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson i_gatt_if++, p_reg++) { 1148911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (!p_reg->in_use) { 1149911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson memset(p_reg, 0, sizeof(tGATT_REG)); 1150911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson i_gatt_if++; /* one based number */ 1151911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_reg->app_uuid128 = *p_app_uuid128; 1152911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson gatt_if = p_reg->gatt_if = (tGATT_IF)i_gatt_if; 1153911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_reg->app_cb = *p_cb_info; 1154911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_reg->in_use = true; 1155911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 1156911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson GATT_TRACE_API("%s: allocated gatt_if=%d", __func__, gatt_if); 1157911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson return gatt_if; 11585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 1159911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 1160db4ec762f0825a944923bd3a4ff69d3147b68dfaJakub Pawlowski 1161911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson GATT_TRACE_ERROR("%s: can't Register GATT client, MAX client %d reached!", 1162911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson __func__, GATT_MAX_APPS); 1163911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson return 0; 11645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 11655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 11665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 1167ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 1168ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function GATT_Deregister 1169ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 1170ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description This function deregistered the application from GATT. 1171ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 1172ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Parameters gatt_if: applicaiton interface. 1173ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 1174ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns None. 1175ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 1176ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/ 1177911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid GATT_Deregister(tGATT_IF gatt_if) { 1178911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson GATT_TRACE_API("GATT_Deregister gatt_if=%d", gatt_if); 1179ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski 1180ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski tGATT_REG* p_reg = gatt_get_regcb(gatt_if); 1181911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson /* Index 0 is GAP and is never deregistered */ 1182911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if ((gatt_if == 0) || (p_reg == NULL)) { 1183911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson GATT_TRACE_ERROR("GATT_Deregister with invalid gatt_if: %u", gatt_if); 1184911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson return; 1185911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 1186911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 1187911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson /* stop all services */ 1188911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson /* todo an applcaiton can not be deregistered if its services is also used by 1189911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson other application 1190911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson deregisteration need to bed performed in an orderly fashion 1191911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson no check for now */ 1192ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski for (auto& el : *gatt_cb.srv_list_info) { 1193ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski if (el.gatt_if == gatt_if) { 1194ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski GATTS_StopService(el.s_hdl); 11955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 1196911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 11975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1198911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson /* free all services db buffers if owned by this application */ 1199911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson gatt_free_srvc_db_buffer_app_id(&p_reg->app_uuid128); 12005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1201911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson /* When an application deregisters, check remove the link associated with the 1202911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson * app */ 1203ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski tGATT_TCB* p_tcb; 1204ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski int i, j; 1205911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson for (i = 0, p_tcb = gatt_cb.tcb; i < GATT_MAX_PHY_CHANNEL; i++, p_tcb++) { 1206911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (p_tcb->in_use) { 1207911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (gatt_get_ch_state(p_tcb) != GATT_CH_CLOSE) { 1208911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson gatt_update_app_use_link_flag(gatt_if, p_tcb, false, true); 1209911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 1210911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 1211ad3ab46b727119f3f7233e392d3d628909234e61Jakub Pawlowski tGATT_CLCB* p_clcb; 1212911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson for (j = 0, p_clcb = &gatt_cb.clcb[j]; j < GATT_CL_MAX_LCB; 1213911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson j++, p_clcb++) { 1214911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (p_clcb->in_use && (p_clcb->p_reg->gatt_if == gatt_if) && 1215911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson (p_clcb->p_tcb->tcb_idx == p_tcb->tcb_idx)) { 1216911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson alarm_cancel(p_clcb->gatt_rsp_timer_ent); 1217911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson gatt_clcb_dealloc(p_clcb); 1218911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson break; 12195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 1220911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 12215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 1222911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 12235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1224911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson gatt_deregister_bgdev_list(gatt_if); 1225e1202caae4920139ea0cfed5c51f5f76b2dc8bc4Andre Eisenbach 1226911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson memset(p_reg, 0, sizeof(tGATT_REG)); 12275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 12285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 12295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 1230ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 1231ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function GATT_StartIf 1232ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 12339ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson * Description This function is called after registration to start 12349ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson * receiving callbacks for registered interface. Function may 12359ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson * call back with connection status and queued notifications 1236ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 1237ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Parameter gatt_if: applicaiton interface. 1238ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 1239ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns None. 1240ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 1241ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/ 1242911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid GATT_StartIf(tGATT_IF gatt_if) { 1243911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tGATT_REG* p_reg; 1244911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tGATT_TCB* p_tcb; 1245911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson BD_ADDR bda; 1246911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson uint8_t start_idx, found_idx; 1247911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson uint16_t conn_id; 1248911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tGATT_TRANSPORT transport; 1249911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 1250911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson GATT_TRACE_API("GATT_StartIf gatt_if=%d", gatt_if); 1251911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_reg = gatt_get_regcb(gatt_if); 1252911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (p_reg != NULL) { 1253911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson start_idx = 0; 1254911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson while ( 1255911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson gatt_find_the_connected_bda(start_idx, bda, &found_idx, &transport)) { 1256911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_tcb = gatt_find_tcb_by_addr(bda, transport); 1257911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (p_reg->app_cb.p_conn_cb && p_tcb) { 1258911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson conn_id = GATT_CREATE_CONN_ID(p_tcb->tcb_idx, gatt_if); 1259911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson (*p_reg->app_cb.p_conn_cb)(gatt_if, bda, conn_id, true, 0, transport); 1260911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 1261911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson start_idx = ++found_idx; 12625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 1263911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 12645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 12655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 12665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 1267ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 1268ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function GATT_Connect 1269ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 12709ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson * Description This function initiate a connecttion to a remote device on 12719ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson * GATT channel. 1272ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 1273ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Parameters gatt_if: applicaiton interface 1274ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * bd_addr: peer device address. 12759ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson * is_direct: is a direct conenection or a background auto 12769ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson * connection 1277ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 12789ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson * Returns true if connection started; false if connection start 12799ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson * failure. 1280ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 1281ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/ 1282911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonbool GATT_Connect(tGATT_IF gatt_if, BD_ADDR bd_addr, bool is_direct, 1283911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tBT_TRANSPORT transport, bool opportunistic) { 128496fb273d92a31204edcf43ab2594a19876d14056Jakub Pawlowski uint8_t phy = controller_get_interface()->get_le_all_initiating_phys(); 128596fb273d92a31204edcf43ab2594a19876d14056Jakub Pawlowski return GATT_Connect(gatt_if, bd_addr, is_direct, transport, opportunistic, 128696fb273d92a31204edcf43ab2594a19876d14056Jakub Pawlowski phy); 128796fb273d92a31204edcf43ab2594a19876d14056Jakub Pawlowski} 128896fb273d92a31204edcf43ab2594a19876d14056Jakub Pawlowski 128996fb273d92a31204edcf43ab2594a19876d14056Jakub Pawlowskibool GATT_Connect(tGATT_IF gatt_if, BD_ADDR bd_addr, bool is_direct, 129096fb273d92a31204edcf43ab2594a19876d14056Jakub Pawlowski tBT_TRANSPORT transport, bool opportunistic, 129196fb273d92a31204edcf43ab2594a19876d14056Jakub Pawlowski uint8_t initiating_phys) { 1292911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tGATT_REG* p_reg; 1293911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson bool status = false; 1294911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 1295911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson GATT_TRACE_API("GATT_Connect gatt_if=%d", gatt_if); 1296911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 1297911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson /* Make sure app is registered */ 1298911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_reg = gatt_get_regcb(gatt_if); 1299911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (p_reg == NULL) { 1300911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson GATT_TRACE_ERROR("GATT_Connect - gatt_if =%d is not registered", gatt_if); 1301911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson return (false); 1302911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 1303911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 1304911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (is_direct) 130596fb273d92a31204edcf43ab2594a19876d14056Jakub Pawlowski status = gatt_act_connect(p_reg, bd_addr, transport, opportunistic, 130696fb273d92a31204edcf43ab2594a19876d14056Jakub Pawlowski initiating_phys); 1307911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson else { 1308911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (transport == BT_TRANSPORT_LE) 1309911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson status = gatt_update_auto_connect_dev(gatt_if, true, bd_addr); 1310911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson else { 1311911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson GATT_TRACE_ERROR("Unsupported transport for background connection"); 13125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 1313911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 13145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1315911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson return status; 13165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 13175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 13185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 1319ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 1320ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function GATT_CancelConnect 1321ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 13229ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson * Description This function terminate the connection initaition to a 13239ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson * remote device on GATT channel. 1324ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 13259ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson * Parameters gatt_if: client interface. If 0 used as unconditionally 13269ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson * disconnect, typically used for direct connection 13279ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson * cancellation. 1328ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * bd_addr: peer device address. 1329ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 13309ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson * Returns true if the connection started; false otherwise. 1331ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 1332ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/ 1333911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonbool GATT_CancelConnect(tGATT_IF gatt_if, BD_ADDR bd_addr, bool is_direct) { 1334911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tGATT_REG* p_reg; 1335911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tGATT_TCB* p_tcb; 1336911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson bool status = true; 1337911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tGATT_IF temp_gatt_if; 1338911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson uint8_t start_idx, found_idx; 1339911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 1340911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson GATT_TRACE_API("GATT_CancelConnect gatt_if=%d", gatt_if); 1341911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 1342f9c5752344ec459def74765f512d28fa0f402168Marie Janssen if (gatt_if != 0) { 1343f9c5752344ec459def74765f512d28fa0f402168Marie Janssen p_reg = gatt_get_regcb(gatt_if); 1344f9c5752344ec459def74765f512d28fa0f402168Marie Janssen if (p_reg == NULL) { 1345f9c5752344ec459def74765f512d28fa0f402168Marie Janssen GATT_TRACE_ERROR("GATT_CancelConnect - gatt_if =%d is not registered", 1346f9c5752344ec459def74765f512d28fa0f402168Marie Janssen gatt_if); 1347f9c5752344ec459def74765f512d28fa0f402168Marie Janssen return (false); 1348f9c5752344ec459def74765f512d28fa0f402168Marie Janssen } 1349911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 1350911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 1351911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (is_direct) { 1352911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (!gatt_if) { 1353911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson GATT_TRACE_DEBUG("GATT_CancelConnect - unconditional"); 1354911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson start_idx = 0; 1355911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson /* only LE connection can be cancelled */ 1356911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_tcb = gatt_find_tcb_by_addr(bd_addr, BT_TRANSPORT_LE); 1357911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (p_tcb && gatt_num_apps_hold_link(p_tcb)) { 1358911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson while (status && gatt_find_app_hold_link(p_tcb, start_idx, &found_idx, 1359911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson &temp_gatt_if)) { 1360911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson status = gatt_cancel_open(temp_gatt_if, bd_addr); 1361911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson start_idx = ++found_idx; 13625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 1363911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } else { 1364911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson GATT_TRACE_ERROR("GATT_CancelConnect - no app found"); 1365911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson status = false; 1366911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 1367911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } else { 1368911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson status = gatt_cancel_open(gatt_if, bd_addr); 13695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 1370911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } else { 1371911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (!gatt_if) { 1372911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (gatt_get_num_apps_for_bg_dev(bd_addr)) { 1373911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson while (gatt_find_app_for_bg_dev(bd_addr, &temp_gatt_if)) 1374911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson gatt_remove_bg_dev_for_app(temp_gatt_if, bd_addr); 1375911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } else { 1376911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson GATT_TRACE_ERROR( 1377911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson "GATT_CancelConnect -no app associated with the bg device for " 1378911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson "unconditional removal"); 1379911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson status = false; 1380911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 1381911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } else { 1382911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson status = gatt_remove_bg_dev_for_app(gatt_if, bd_addr); 13835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 1384911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 13855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1386911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson return status; 13875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 13885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 13895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 1390ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 1391ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function GATT_Disconnect 1392ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 13939ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson * Description This function disconnects the GATT channel for this 13949ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson * registered application. 1395ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 1396ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Parameters conn_id: connection identifier. 1397ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 1398ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns GATT_SUCCESS if disconnected. 1399ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 1400ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/ 1401911d1ae03efec2d54c3b1b605589d790d1745488Myles WatsontGATT_STATUS GATT_Disconnect(uint16_t conn_id) { 1402911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tGATT_STATUS ret = GATT_ILLEGAL_PARAMETER; 1403911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tGATT_TCB* p_tcb = NULL; 1404911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tGATT_IF gatt_if = GATT_GET_GATT_IF(conn_id); 1405911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson uint8_t tcb_idx = GATT_GET_TCB_IDX(conn_id); 14065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1407911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson GATT_TRACE_API("GATT_Disconnect conn_id=%d ", conn_id); 14085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1409911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_tcb = gatt_get_tcb_by_idx(tcb_idx); 14105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1411911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (p_tcb) { 1412911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson gatt_update_app_use_link_flag(gatt_if, p_tcb, false, true); 1413911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson ret = GATT_SUCCESS; 1414911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 1415911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson return ret; 14165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 14175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 14185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 1419ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 1420ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function GATT_GetConnectionInfor 1421ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 14229ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson * Description This function uses conn_id to find its associated BD address 14239ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson * and application interface 1424ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 1425ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Parameters conn_id: connection id (input) 1426ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * p_gatt_if: applicaiton interface (output) 1427ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * bd_addr: peer device address. (output) 1428ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 1429ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns true the ligical link information is found for conn_id 1430ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 1431ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/ 1432911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonbool GATT_GetConnectionInfor(uint16_t conn_id, tGATT_IF* p_gatt_if, 1433911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson BD_ADDR bd_addr, tBT_TRANSPORT* p_transport) { 1434911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tGATT_IF gatt_if = GATT_GET_GATT_IF(conn_id); 1435911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tGATT_REG* p_reg = gatt_get_regcb(gatt_if); 1436911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson uint8_t tcb_idx = GATT_GET_TCB_IDX(conn_id); 1437911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tGATT_TCB* p_tcb = gatt_get_tcb_by_idx(tcb_idx); 1438911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson bool status = false; 1439911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 1440911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson GATT_TRACE_API("GATT_GetConnectionInfor conn_id=%d", conn_id); 1441911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 1442911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (p_tcb && p_reg) { 1443911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson memcpy(bd_addr, p_tcb->peer_bda, BD_ADDR_LEN); 1444911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson *p_gatt_if = gatt_if; 1445911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson *p_transport = p_tcb->transport; 1446911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson status = true; 1447911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 1448911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson return status; 14495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 14505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 14515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 1452ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 1453ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function GATT_GetConnIdIfConnected 1454ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 14559ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson * Description This function find the conn_id if the logical link for BD 14569ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson * address and applciation interface is connected 1457ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 1458ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Parameters gatt_if: applicaiton interface (input) 1459ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * bd_addr: peer device address. (input) 1460ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * p_conn_id: connection id (output) 1461ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * transport: transport option 1462ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 1463ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns true the logical link is connected 1464ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 1465ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/ 1466911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonbool GATT_GetConnIdIfConnected(tGATT_IF gatt_if, BD_ADDR bd_addr, 1467911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson uint16_t* p_conn_id, tBT_TRANSPORT transport) { 1468911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tGATT_REG* p_reg = gatt_get_regcb(gatt_if); 1469911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tGATT_TCB* p_tcb = gatt_find_tcb_by_addr(bd_addr, transport); 1470911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson bool status = false; 1471911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 1472911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (p_reg && p_tcb && (gatt_get_ch_state(p_tcb) == GATT_CH_OPEN)) { 1473911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson *p_conn_id = GATT_CREATE_CONN_ID(p_tcb->tcb_idx, gatt_if); 1474911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson status = true; 1475911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 1476911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 1477911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson GATT_TRACE_API("GATT_GetConnIdIfConnected status=%d", status); 1478911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson return status; 14795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 1480