1dbba0e652e0ce23dd691df3c03979ec6e32c8db3Matthew Xie/******************************************************************************
2dbba0e652e0ce23dd691df3c03979ec6e32c8db3Matthew Xie *
3dbba0e652e0ce23dd691df3c03979ec6e32c8db3Matthew Xie *  Copyright (C) 1999-2013 Broadcom Corporation
4dbba0e652e0ce23dd691df3c03979ec6e32c8db3Matthew Xie *
5dbba0e652e0ce23dd691df3c03979ec6e32c8db3Matthew Xie *  Licensed under the Apache License, Version 2.0 (the "License");
6dbba0e652e0ce23dd691df3c03979ec6e32c8db3Matthew Xie *  you may not use this file except in compliance with the License.
7dbba0e652e0ce23dd691df3c03979ec6e32c8db3Matthew Xie *  You may obtain a copy of the License at:
8dbba0e652e0ce23dd691df3c03979ec6e32c8db3Matthew Xie *
9dbba0e652e0ce23dd691df3c03979ec6e32c8db3Matthew Xie *  http://www.apache.org/licenses/LICENSE-2.0
10dbba0e652e0ce23dd691df3c03979ec6e32c8db3Matthew Xie *
11dbba0e652e0ce23dd691df3c03979ec6e32c8db3Matthew Xie *  Unless required by applicable law or agreed to in writing, software
12dbba0e652e0ce23dd691df3c03979ec6e32c8db3Matthew Xie *  distributed under the License is distributed on an "AS IS" BASIS,
13dbba0e652e0ce23dd691df3c03979ec6e32c8db3Matthew Xie *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14dbba0e652e0ce23dd691df3c03979ec6e32c8db3Matthew Xie *  See the License for the specific language governing permissions and
15dbba0e652e0ce23dd691df3c03979ec6e32c8db3Matthew Xie *  limitations under the License.
16dbba0e652e0ce23dd691df3c03979ec6e32c8db3Matthew Xie *
17dbba0e652e0ce23dd691df3c03979ec6e32c8db3Matthew Xie ******************************************************************************/
182e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
192e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach#include "bt_target.h"
205cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen#include "bt_utils.h"
212e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach#include "gatt_api.h"
222e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach#include "gatt_int.h"
23778d57b7e8222fff731d7deabed25983d508dc14Ajay Panicker#include "osi/include/osi.h"
242e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach#include "srvc_eng_int.h"
252e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
262e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach#include "srvc_battery_int.h"
27911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson#include "srvc_dis_int.h"
282e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
29d8be0e590aa1efe1c33a8acfea0d7e14fd1a8030Jakub Pawlowskiusing base::StringPrintf;
30911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonstatic void srvc_eng_s_request_cback(uint16_t conn_id, uint32_t trans_id,
31911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                                     uint8_t op_code, tGATTS_DATA* p_data);
32c2276b06572ab6fc1f900fbb1f41087e77d47e2aJakub Pawlowskistatic void srvc_eng_connect_cback(UNUSED_ATTR tGATT_IF gatt_if,
339e030fde05352ec4385d7baf6cc2af89e95e039cJakub Pawlowski                                   const RawAddress& bda, uint16_t conn_id,
34c2276b06572ab6fc1f900fbb1f41087e77d47e2aJakub Pawlowski                                   bool connected, tGATT_DISCONN_REASON reason,
35911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                                   tBT_TRANSPORT transport);
36911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonstatic void srvc_eng_c_cmpl_cback(uint16_t conn_id, tGATTC_OPTYPE op,
37911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                                  tGATT_STATUS status,
38911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                                  tGATT_CL_COMPLETE* p_data);
39911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
40911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonstatic tGATT_CBACK srvc_gatt_cback = {srvc_eng_connect_cback,
41911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                                      srvc_eng_c_cmpl_cback,
42911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                                      NULL,
43911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                                      NULL,
44911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                                      srvc_eng_s_request_cback,
45911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                                      NULL,
46b5ba4fdbc433544de3806f8e82976898e444b491Jakub Pawlowski                                      NULL,
47eafd45d08653bb1621c82a2f3cf922a43a0b1bc5Jakub Pawlowski                                      NULL,
48911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                                      NULL};
492e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach/* type for action functions */
50911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsontypedef void (*tSRVC_ENG_C_CMPL_ACTION)(tSRVC_CLCB* p_clcb, tGATTC_OPTYPE op,
51911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                                        tGATT_STATUS status,
52911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                                        tGATT_CL_COMPLETE* p_data);
532e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
54911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonconst tSRVC_ENG_C_CMPL_ACTION srvc_eng_c_cmpl_act[SRVC_ID_MAX] = {
552e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    dis_c_cmpl_cback,
562e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach};
572e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
582e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre EisenbachtSRVC_ENG_CB srvc_eng_cb;
592e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
602e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach/*******************************************************************************
61ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
62ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         srvc_eng_find_conn_id_by_bd_addr
63ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
64ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description      The function searches all LCB with macthing bd address
65ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
66ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns          total number of clcb found.
67ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
68ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
699e030fde05352ec4385d7baf6cc2af89e95e039cJakub Pawlowskiuint16_t srvc_eng_find_conn_id_by_bd_addr(const RawAddress& bda) {
70911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint8_t i_clcb;
71911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  tSRVC_CLCB* p_clcb = NULL;
72911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
73911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  for (i_clcb = 0, p_clcb = srvc_eng_cb.clcb; i_clcb < SRVC_MAX_APPS;
74911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson       i_clcb++, p_clcb++) {
75c2276b06572ab6fc1f900fbb1f41087e77d47e2aJakub Pawlowski    if (p_clcb->in_use && p_clcb->connected && p_clcb->bda == bda) {
76911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      return p_clcb->conn_id;
772e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    }
78911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
792e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
80911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  return GATT_INVALID_CONN_ID;
812e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach}
822e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
832e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach/*******************************************************************************
84ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
85ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         srvc_eng_find_clcb_by_bd_addr
86ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
87ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description      The function searches all LCBs with macthing bd address.
88ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
89ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns          Pointer to the found link conenction control block.
90ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
91ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
929e030fde05352ec4385d7baf6cc2af89e95e039cJakub PawlowskitSRVC_CLCB* srvc_eng_find_clcb_by_bd_addr(const RawAddress& bda) {
93911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint8_t i_clcb;
94911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  tSRVC_CLCB* p_clcb = NULL;
95911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
96911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  for (i_clcb = 0, p_clcb = srvc_eng_cb.clcb; i_clcb < SRVC_MAX_APPS;
97911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson       i_clcb++, p_clcb++) {
98c2276b06572ab6fc1f900fbb1f41087e77d47e2aJakub Pawlowski    if (p_clcb->in_use && p_clcb->connected && p_clcb->bda == bda) {
99911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      return p_clcb;
1002e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    }
101911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
1022e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
103911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  return NULL;
1042e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach}
1052e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach/*******************************************************************************
106ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
107ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         srvc_eng_find_clcb_by_conn_id
108ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
109ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description      The function searches all LCBs with macthing connection ID.
110ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
111ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns          Pointer to the found link conenction control block.
112ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
113ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
114911d1ae03efec2d54c3b1b605589d790d1745488Myles WatsontSRVC_CLCB* srvc_eng_find_clcb_by_conn_id(uint16_t conn_id) {
115911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint8_t i_clcb;
116911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  tSRVC_CLCB* p_clcb = NULL;
117911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
118911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  for (i_clcb = 0, p_clcb = srvc_eng_cb.clcb; i_clcb < SRVC_MAX_APPS;
119911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson       i_clcb++, p_clcb++) {
120911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if (p_clcb->in_use && p_clcb->connected && p_clcb->conn_id == conn_id) {
121911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      return p_clcb;
1222e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    }
123911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
1242e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
125911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  return NULL;
1262e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach}
1272e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach/*******************************************************************************
128ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
129ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         srvc_eng_find_clcb_by_conn_id
130ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
131ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description      The function searches all LCBs with macthing connection ID.
132ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
133ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns          Pointer to the found link conenction control block.
134ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
135ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
136911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonuint8_t srvc_eng_find_clcb_idx_by_conn_id(uint16_t conn_id) {
137911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint8_t i_clcb;
138911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  tSRVC_CLCB* p_clcb = NULL;
139911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
140911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  for (i_clcb = 0, p_clcb = srvc_eng_cb.clcb; i_clcb < SRVC_MAX_APPS;
141911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson       i_clcb++, p_clcb++) {
142911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if (p_clcb->in_use && p_clcb->connected && p_clcb->conn_id == conn_id) {
143911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      return i_clcb;
1442e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    }
145911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
1462e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
147911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  return SRVC_MAX_APPS;
1482e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach}
1492e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach/*******************************************************************************
150ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
151ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         srvc_eng_clcb_alloc
152ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
1539ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson * Description      Allocate a GATT profile connection link control block
154ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
1559ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson * Returns          NULL if not found. Otherwise pointer to the connection link
1569ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson *                  block.
157ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
158ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
1599e030fde05352ec4385d7baf6cc2af89e95e039cJakub PawlowskitSRVC_CLCB* srvc_eng_clcb_alloc(uint16_t conn_id, const RawAddress& bda) {
160911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint8_t i_clcb = 0;
161911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  tSRVC_CLCB* p_clcb = NULL;
162911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
163911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  for (i_clcb = 0, p_clcb = srvc_eng_cb.clcb; i_clcb < SRVC_MAX_APPS;
164911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson       i_clcb++, p_clcb++) {
165911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if (!p_clcb->in_use) {
166911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p_clcb->in_use = true;
167911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p_clcb->conn_id = conn_id;
168911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p_clcb->connected = true;
169c2276b06572ab6fc1f900fbb1f41087e77d47e2aJakub Pawlowski      p_clcb->bda = bda;
170911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      break;
1712e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    }
172911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
173911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  return p_clcb;
1742e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach}
1752e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach/*******************************************************************************
176ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
177ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         srvc_eng_clcb_dealloc
178ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
1799ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson * Description      De-allocate a GATT profile connection link control block
180ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
1819ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson * Returns          True the deallocation is successful
182ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
183ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
184911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonbool srvc_eng_clcb_dealloc(uint16_t conn_id) {
185911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint8_t i_clcb = 0;
186911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  tSRVC_CLCB* p_clcb = NULL;
187911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
188911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  for (i_clcb = 0, p_clcb = srvc_eng_cb.clcb; i_clcb < SRVC_MAX_APPS;
189911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson       i_clcb++, p_clcb++) {
190911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if (p_clcb->in_use && p_clcb->connected && (p_clcb->conn_id == conn_id)) {
191911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      unsigned j;
192911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      for (j = 0; j < ARRAY_SIZE(p_clcb->dis_value.data_string); j++)
193911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        osi_free(p_clcb->dis_value.data_string[j]);
194911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
195911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      memset(p_clcb, 0, sizeof(tSRVC_CLCB));
196911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      return true;
1972e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    }
198911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
199911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  return false;
2002e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach}
2012e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach/*******************************************************************************
202ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *   Service Engine Server Attributes Database Read/Read Blob Request process
203ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
204911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonuint8_t srvc_eng_process_read_req(uint8_t clcb_idx, tGATT_READ_REQ* p_data,
205911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                                  tGATTS_RSP* p_rsp, tGATT_STATUS* p_status) {
206911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  tGATT_STATUS status = GATT_NOT_FOUND;
207911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint8_t act = SRVC_ACT_RSP;
2082e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
209911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (p_data->is_long) p_rsp->attr_value.offset = p_data->offset;
2102e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
211911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_rsp->attr_value.handle = p_data->handle;
2122e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
213911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (dis_valid_handle_range(p_data->handle))
214911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    act = dis_read_attr_value(clcb_idx, p_data->handle, &p_rsp->attr_value,
215911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                              p_data->is_long, p_status);
2162e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
217911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  else if (battery_valid_handle_range(p_data->handle))
218911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    act =
219911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        battery_s_read_attr_value(clcb_idx, p_data->handle, &p_rsp->attr_value,
220911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                                  p_data->is_long, p_status);
2212e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
222911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  else
223911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    *p_status = status;
224911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  return act;
2252e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach}
2262e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach/*******************************************************************************
227ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *   Service Engine Server Attributes Database write Request process
228ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
229911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonuint8_t srvc_eng_process_write_req(uint8_t clcb_idx, tGATT_WRITE_REQ* p_data,
230911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                                   UNUSED_ATTR tGATTS_RSP* p_rsp,
231911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                                   tGATT_STATUS* p_status) {
232911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint8_t act = SRVC_ACT_RSP;
233911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
234911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (dis_valid_handle_range(p_data->handle)) {
235911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    act = dis_write_attr_value(p_data, p_status);
236911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  } else if (battery_valid_handle_range(p_data->handle)) {
237911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    act = battery_s_write_attr_value(clcb_idx, p_data, p_status);
238911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  } else
239911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    *p_status = GATT_NOT_FOUND;
240911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
241911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  return act;
2422e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach}
2432e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
2442e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach/*******************************************************************************
245ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
246ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         srvc_eng_s_request_cback
247ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
248ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description      GATT DIS attribute access request callback.
249ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
250ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns          void.
251ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
252ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
253911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonstatic void srvc_eng_s_request_cback(uint16_t conn_id, uint32_t trans_id,
254911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                                     tGATTS_REQ_TYPE type,
255911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                                     tGATTS_DATA* p_data) {
256911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint8_t status = GATT_INVALID_PDU;
257911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  tGATTS_RSP rsp_msg;
258911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint8_t act = SRVC_ACT_IGNORE;
259911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint8_t clcb_idx = srvc_eng_find_clcb_idx_by_conn_id(conn_id);
260911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
261d8be0e590aa1efe1c33a8acfea0d7e14fd1a8030Jakub Pawlowski  VLOG(1) << StringPrintf("srvc_eng_s_request_cback : recv type (0x%02x)",
262d8be0e590aa1efe1c33a8acfea0d7e14fd1a8030Jakub Pawlowski                          type);
263911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
264911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  memset(&rsp_msg, 0, sizeof(tGATTS_RSP));
265911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
266911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  srvc_eng_cb.clcb[clcb_idx].trans_id = trans_id;
267911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
268911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  switch (type) {
269911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    case GATTS_REQ_TYPE_READ_CHARACTERISTIC:
270911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    case GATTS_REQ_TYPE_READ_DESCRIPTOR:
271911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      act = srvc_eng_process_read_req(clcb_idx, &p_data->read_req, &rsp_msg,
272911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                                      &status);
273911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      break;
274911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
275911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    case GATTS_REQ_TYPE_WRITE_CHARACTERISTIC:
276911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    case GATTS_REQ_TYPE_WRITE_DESCRIPTOR:
277911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      act = srvc_eng_process_write_req(clcb_idx, &p_data->write_req, &rsp_msg,
278911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                                       &status);
279911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      if (!p_data->write_req.need_rsp) act = SRVC_ACT_IGNORE;
280911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      break;
281911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
282911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    case GATTS_REQ_TYPE_WRITE_EXEC:
283d8be0e590aa1efe1c33a8acfea0d7e14fd1a8030Jakub Pawlowski      VLOG(1) << "Ignore GATT_REQ_EXEC_WRITE/WRITE_CMD";
284911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      break;
285911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
286911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    case GATTS_REQ_TYPE_MTU:
287d8be0e590aa1efe1c33a8acfea0d7e14fd1a8030Jakub Pawlowski      VLOG(1) << "Get MTU exchange new mtu size: " << p_data->mtu;
288911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      break;
289911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
290911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    default:
291d8be0e590aa1efe1c33a8acfea0d7e14fd1a8030Jakub Pawlowski      VLOG(1) << StringPrintf("Unknown/unexpected LE GAP ATT request: 0x%02x",
292d8be0e590aa1efe1c33a8acfea0d7e14fd1a8030Jakub Pawlowski                              type);
293911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      break;
294911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
295911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
296911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  srvc_eng_cb.clcb[clcb_idx].trans_id = 0;
297911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
298911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (act == SRVC_ACT_RSP) GATTS_SendRsp(conn_id, trans_id, status, &rsp_msg);
2992e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach}
3002e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
3012e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach/*******************************************************************************
302ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
303ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         srvc_eng_c_cmpl_cback
304ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
305ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description      Client operation complete callback.
306ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
307ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns          void
308ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
309ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
310911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonstatic void srvc_eng_c_cmpl_cback(uint16_t conn_id, tGATTC_OPTYPE op,
311911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                                  tGATT_STATUS status,
312911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                                  tGATT_CL_COMPLETE* p_data) {
313911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  tSRVC_CLCB* p_clcb = srvc_eng_find_clcb_by_conn_id(conn_id);
3142e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
315d8be0e590aa1efe1c33a8acfea0d7e14fd1a8030Jakub Pawlowski  VLOG(1) << StringPrintf(
316d8be0e590aa1efe1c33a8acfea0d7e14fd1a8030Jakub Pawlowski      "srvc_eng_c_cmpl_cback() - op_code: 0x%02x  status: 0x%02x ", op, status);
3172e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
318911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (p_clcb == NULL) {
319d8be0e590aa1efe1c33a8acfea0d7e14fd1a8030Jakub Pawlowski    LOG(ERROR) << __func__ << " received for unknown connection";
320911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    return;
321911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
3222e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
323911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (p_clcb->cur_srvc_id != SRVC_ID_NONE && p_clcb->cur_srvc_id <= SRVC_ID_MAX)
324911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    srvc_eng_c_cmpl_act[p_clcb->cur_srvc_id - 1](p_clcb, op, status, p_data);
3252e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach}
3262e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
3272e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach/*******************************************************************************
328ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
329ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         srvc_eng_connect_cback
330ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
331ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description      Gatt profile connection callback.
332ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
333ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns          void
334ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
335ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
336c2276b06572ab6fc1f900fbb1f41087e77d47e2aJakub Pawlowskistatic void srvc_eng_connect_cback(UNUSED_ATTR tGATT_IF gatt_if,
3379e030fde05352ec4385d7baf6cc2af89e95e039cJakub Pawlowski                                   const RawAddress& bda, uint16_t conn_id,
338c2276b06572ab6fc1f900fbb1f41087e77d47e2aJakub Pawlowski                                   bool connected, tGATT_DISCONN_REASON reason,
339911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                                   UNUSED_ATTR tBT_TRANSPORT transport) {
340c2276b06572ab6fc1f900fbb1f41087e77d47e2aJakub Pawlowski  VLOG(1) << __func__ << ": from " << bda
341c2276b06572ab6fc1f900fbb1f41087e77d47e2aJakub Pawlowski          << StringPrintf(" connected:%d conn_id=%d reason = 0x%04x", connected,
342c2276b06572ab6fc1f900fbb1f41087e77d47e2aJakub Pawlowski                          conn_id, reason);
343911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
344911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (connected) {
345911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if (srvc_eng_clcb_alloc(conn_id, bda) == NULL) {
346d8be0e590aa1efe1c33a8acfea0d7e14fd1a8030Jakub Pawlowski      LOG(ERROR) << __func__ << "srvc_eng_connect_cback: no_resource";
347911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      return;
3482e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    }
349911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  } else {
350911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    srvc_eng_clcb_dealloc(conn_id);
351911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
3522e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach}
3532e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach/*******************************************************************************
354ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
355ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         srvc_eng_c_cmpl_cback
356ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
357ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description      Client operation complete callback.
358ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
359ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns          void
360ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
361ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
3629e030fde05352ec4385d7baf6cc2af89e95e039cJakub Pawlowskibool srvc_eng_request_channel(const RawAddress& remote_bda, uint8_t srvc_id) {
363911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  bool set = true;
364911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  tSRVC_CLCB* p_clcb = srvc_eng_find_clcb_by_bd_addr(remote_bda);
3652e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
366911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (p_clcb == NULL) p_clcb = srvc_eng_clcb_alloc(0, remote_bda);
3672e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
368911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (p_clcb && p_clcb->cur_srvc_id == SRVC_ID_NONE)
369911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p_clcb->cur_srvc_id = srvc_id;
370911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  else
371911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    set = false;
3722e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
373911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  return set;
3742e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach}
3752e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach/*******************************************************************************
376ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
377ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         srvc_eng_release_channel
378ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
379ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description      Client operation complete callback.
380ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
381ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns          void
382ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
383ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
384911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid srvc_eng_release_channel(uint16_t conn_id) {
385911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  tSRVC_CLCB* p_clcb = srvc_eng_find_clcb_by_conn_id(conn_id);
386911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
387911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (p_clcb == NULL) {
388d8be0e590aa1efe1c33a8acfea0d7e14fd1a8030Jakub Pawlowski    LOG(ERROR) << __func__ << ": invalid connection id " << conn_id;
389911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    return;
390911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
391c8eddb5ae46da76552d3cd3d9fff8d33c1880a52Matthew Xie
392911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_clcb->cur_srvc_id = SRVC_ID_NONE;
3932e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
394911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* check pending request */
395911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  GATT_Disconnect(p_clcb->conn_id);
3962e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach}
3972e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach/*******************************************************************************
398ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
399ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         srvc_eng_init
400ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
401ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description      Initializa the GATT Service engine.
402ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
403ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
404911d1ae03efec2d54c3b1b605589d790d1745488Myles WatsontGATT_STATUS srvc_eng_init(void) {
405911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  tBT_UUID app_uuid = {LEN_UUID_16, {UUID_SERVCLASS_DEVICE_INFO}};
4062e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
407911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (srvc_eng_cb.enabled) {
408d8be0e590aa1efe1c33a8acfea0d7e14fd1a8030Jakub Pawlowski    LOG(ERROR) << "DIS already initalized";
409911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  } else {
410911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    memset(&srvc_eng_cb, 0, sizeof(tSRVC_ENG_CB));
4112e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
412911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    /* Create a GATT profile service */
413911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    srvc_eng_cb.gatt_if = GATT_Register(&app_uuid, &srvc_gatt_cback);
414911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    GATT_StartIf(srvc_eng_cb.gatt_if);
4152e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
416d8be0e590aa1efe1c33a8acfea0d7e14fd1a8030Jakub Pawlowski    VLOG(1) << "Srvc_Init:  gatt_if=" << +srvc_eng_cb.gatt_if;
4172e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
418911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    srvc_eng_cb.enabled = true;
419911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    dis_cb.dis_read_uuid_idx = 0xff;
420911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
421911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  return GATT_SUCCESS;
4222e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach}
4232e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
424911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid srvc_sr_rsp(uint8_t clcb_idx, tGATT_STATUS st, tGATTS_RSP* p_rsp) {
425911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (srvc_eng_cb.clcb[clcb_idx].trans_id != 0) {
426911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    GATTS_SendRsp(srvc_eng_cb.clcb[clcb_idx].conn_id,
427911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                  srvc_eng_cb.clcb[clcb_idx].trans_id, st, p_rsp);
4282e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
429911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    srvc_eng_cb.clcb[clcb_idx].trans_id = 0;
430911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
4312e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach}
4329e030fde05352ec4385d7baf6cc2af89e95e039cJakub Pawlowskivoid srvc_sr_notify(const RawAddress& remote_bda, uint16_t handle, uint16_t len,
4339e030fde05352ec4385d7baf6cc2af89e95e039cJakub Pawlowski                    uint8_t* p_value) {
434911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint16_t conn_id = srvc_eng_find_conn_id_by_bd_addr(remote_bda);
4352e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
436911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (conn_id != GATT_INVALID_CONN_ID) {
437911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    GATTS_HandleValueNotification(conn_id, handle, len, p_value);
438911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
4392e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach}
440