1 /******************************************************************************
2 *
3 * Copyright 2003-2012 Broadcom Corporation
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 ******************************************************************************/
18
19 /******************************************************************************
20 *
21 * This file contains the GATT client utility function.
22 *
23 ******************************************************************************/
24
25 #include <cstdint>
26
27 #include "bt_target.h" // Must be first to define build configuration
28
29 #include "bta/gatt/bta_gatts_int.h"
30
31 #include <base/logging.h>
32
33 /*******************************************************************************
34 *
35 * Function bta_gatts_alloc_srvc_cb
36 *
37 * Description allocate a service control block.
38 *
39 * Returns pointer to the control block, or otherwise NULL when failed.
40 *
41 ******************************************************************************/
bta_gatts_alloc_srvc_cb(tBTA_GATTS_CB * p_cb,uint8_t rcb_idx)42 uint8_t bta_gatts_alloc_srvc_cb(tBTA_GATTS_CB* p_cb, uint8_t rcb_idx) {
43 uint8_t i;
44
45 for (i = 0; i < BTA_GATTS_MAX_SRVC_NUM; i++) {
46 if (!p_cb->srvc_cb[i].in_use) {
47 p_cb->srvc_cb[i].in_use = true;
48 p_cb->srvc_cb[i].rcb_idx = rcb_idx;
49 return i;
50 }
51 }
52 return BTA_GATTS_INVALID_APP;
53 }
54
55 /*******************************************************************************
56 *
57 * Function bta_gatts_find_app_rcb_by_app_if
58 *
59 * Description find the index of the application control block by app ID.
60 *
61 * Returns pointer to the control block if success, otherwise NULL
62 *
63 ******************************************************************************/
bta_gatts_find_app_rcb_by_app_if(tGATT_IF server_if)64 tBTA_GATTS_RCB* bta_gatts_find_app_rcb_by_app_if(tGATT_IF server_if) {
65 uint8_t i;
66 tBTA_GATTS_RCB* p_reg;
67
68 for (i = 0, p_reg = bta_gatts_cb.rcb; i < BTA_GATTS_MAX_APP_NUM;
69 i++, p_reg++) {
70 if (p_reg->in_use && p_reg->gatt_if == server_if) return p_reg;
71 }
72 return NULL;
73 }
74
75 /*******************************************************************************
76 *
77 * Function bta_gatts_find_app_rcb_idx_by_app_if
78 *
79 * Description find the index of the application control block by app ID.
80 *
81 * Returns index of the control block, or BTA_GATTS_INVALID_APP if
82 * failed.
83 *
84 ******************************************************************************/
85
bta_gatts_find_app_rcb_idx_by_app_if(tBTA_GATTS_CB * p_cb,tGATT_IF server_if)86 uint8_t bta_gatts_find_app_rcb_idx_by_app_if(tBTA_GATTS_CB* p_cb,
87 tGATT_IF server_if) {
88 uint8_t i;
89
90 for (i = 0; i < BTA_GATTS_MAX_APP_NUM; i++) {
91 if (p_cb->rcb[i].in_use && p_cb->rcb[i].gatt_if == server_if) return i;
92 }
93 return BTA_GATTS_INVALID_APP;
94 }
95 /*******************************************************************************
96 *
97 * Function bta_gatts_find_srvc_cb_by_srvc_id
98 *
99 * Description find the service control block by service ID.
100 *
101 * Returns pointer to the rcb.
102 *
103 ******************************************************************************/
bta_gatts_find_srvc_cb_by_srvc_id(tBTA_GATTS_CB * p_cb,uint16_t service_id)104 tBTA_GATTS_SRVC_CB* bta_gatts_find_srvc_cb_by_srvc_id(tBTA_GATTS_CB* p_cb,
105 uint16_t service_id) {
106 uint8_t i;
107 VLOG(1) << __func__ << ": service_id=" << +service_id;
108 for (i = 0; i < BTA_GATTS_MAX_SRVC_NUM; i++) {
109 if (p_cb->srvc_cb[i].in_use && p_cb->srvc_cb[i].service_id == service_id) {
110 VLOG(1) << __func__ << ": found service cb index=" << +i;
111 return &p_cb->srvc_cb[i];
112 }
113 }
114 return NULL;
115 }
116 /*******************************************************************************
117 *
118 * Function bta_gatts_find_srvc_cb_by_attr_id
119 *
120 * Description find the service control block by attribute ID.
121 *
122 * Returns pointer to the rcb.
123 *
124 ******************************************************************************/
bta_gatts_find_srvc_cb_by_attr_id(tBTA_GATTS_CB * p_cb,uint16_t attr_id)125 tBTA_GATTS_SRVC_CB* bta_gatts_find_srvc_cb_by_attr_id(tBTA_GATTS_CB* p_cb,
126 uint16_t attr_id) {
127 uint8_t i;
128
129 for (i = 0; i < (BTA_GATTS_MAX_SRVC_NUM); i++) {
130 if (/* middle service */
131 (i < (BTA_GATTS_MAX_SRVC_NUM - 1) && p_cb->srvc_cb[i].in_use &&
132 p_cb->srvc_cb[i + 1].in_use &&
133 attr_id >= p_cb->srvc_cb[i].service_id &&
134 attr_id < p_cb->srvc_cb[i + 1].service_id) ||
135 /* last active service */
136 (i < (BTA_GATTS_MAX_SRVC_NUM - 1) && p_cb->srvc_cb[i].in_use &&
137 !p_cb->srvc_cb[i + 1].in_use &&
138 attr_id >= p_cb->srvc_cb[i].service_id) ||
139 /* last service incb */
140 (i == (BTA_GATTS_MAX_SRVC_NUM - 1) &&
141 attr_id >= p_cb->srvc_cb[i].service_id)) {
142 return &p_cb->srvc_cb[i];
143 }
144 }
145 return NULL;
146 }
147