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*)&notif);
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