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 <bluetooth/log.h>
26
27 #include <cstdint>
28
29 #include "bta/gatt/bta_gatts_int.h"
30 #include "internal_include/bt_target.h"
31
32 using namespace bluetooth;
33
34 /*******************************************************************************
35 *
36 * Function bta_gatts_alloc_srvc_cb
37 *
38 * Description allocate a service control block.
39 *
40 * Returns pointer to the control block, or otherwise NULL when failed.
41 *
42 ******************************************************************************/
bta_gatts_alloc_srvc_cb(tBTA_GATTS_CB * p_cb,uint8_t rcb_idx)43 uint8_t bta_gatts_alloc_srvc_cb(tBTA_GATTS_CB* p_cb, uint8_t rcb_idx) {
44 uint8_t i;
45
46 for (i = 0; i < BTA_GATTS_MAX_SRVC_NUM; i++) {
47 if (!p_cb->srvc_cb[i].in_use) {
48 p_cb->srvc_cb[i].in_use = true;
49 p_cb->srvc_cb[i].rcb_idx = rcb_idx;
50 return i;
51 }
52 }
53 return BTA_GATTS_INVALID_APP;
54 }
55
56 /*******************************************************************************
57 *
58 * Function bta_gatts_find_app_rcb_by_app_if
59 *
60 * Description find the index of the application control block by app ID.
61 *
62 * Returns pointer to the control block if success, otherwise NULL
63 *
64 ******************************************************************************/
bta_gatts_find_app_rcb_by_app_if(tGATT_IF server_if)65 tBTA_GATTS_RCB* bta_gatts_find_app_rcb_by_app_if(tGATT_IF server_if) {
66 uint8_t i;
67 tBTA_GATTS_RCB* p_reg;
68
69 for (i = 0, p_reg = bta_gatts_cb.rcb; i < BTA_GATTS_MAX_APP_NUM; i++, p_reg++) {
70 if (p_reg->in_use && p_reg->gatt_if == server_if) {
71 return p_reg;
72 }
73 }
74 return NULL;
75 }
76
77 /*******************************************************************************
78 *
79 * Function bta_gatts_find_app_rcb_idx_by_app_if
80 *
81 * Description find the index of the application control block by app ID.
82 *
83 * Returns index of the control block, or BTA_GATTS_INVALID_APP if
84 * failed.
85 *
86 ******************************************************************************/
87
bta_gatts_find_app_rcb_idx_by_app_if(tBTA_GATTS_CB * p_cb,tGATT_IF server_if)88 uint8_t bta_gatts_find_app_rcb_idx_by_app_if(tBTA_GATTS_CB* p_cb, tGATT_IF server_if) {
89 uint8_t i;
90
91 for (i = 0; i < BTA_GATTS_MAX_APP_NUM; i++) {
92 if (p_cb->rcb[i].in_use && p_cb->rcb[i].gatt_if == server_if) {
93 return i;
94 }
95 }
96 return BTA_GATTS_INVALID_APP;
97 }
98 /*******************************************************************************
99 *
100 * Function bta_gatts_find_srvc_cb_by_srvc_id
101 *
102 * Description find the service control block by service ID.
103 *
104 * Returns pointer to the rcb.
105 *
106 ******************************************************************************/
bta_gatts_find_srvc_cb_by_srvc_id(tBTA_GATTS_CB * p_cb,uint16_t service_id)107 tBTA_GATTS_SRVC_CB* bta_gatts_find_srvc_cb_by_srvc_id(tBTA_GATTS_CB* p_cb, uint16_t service_id) {
108 uint8_t i;
109 log::verbose("service_id={}", service_id);
110 for (i = 0; i < BTA_GATTS_MAX_SRVC_NUM; i++) {
111 if (p_cb->srvc_cb[i].in_use && p_cb->srvc_cb[i].service_id == service_id) {
112 log::verbose("found service cb index={}", i);
113 return &p_cb->srvc_cb[i];
114 }
115 }
116 return NULL;
117 }
118 /*******************************************************************************
119 *
120 * Function bta_gatts_find_srvc_cb_by_attr_id
121 *
122 * Description find the service control block by attribute ID.
123 *
124 * Returns pointer to the rcb.
125 *
126 ******************************************************************************/
bta_gatts_find_srvc_cb_by_attr_id(tBTA_GATTS_CB * p_cb,uint16_t attr_id)127 tBTA_GATTS_SRVC_CB* bta_gatts_find_srvc_cb_by_attr_id(tBTA_GATTS_CB* p_cb, uint16_t attr_id) {
128 uint8_t i;
129
130 for (i = 0; i < (BTA_GATTS_MAX_SRVC_NUM); i++) {
131 if (/* middle service */
132 (i < (BTA_GATTS_MAX_SRVC_NUM - 1) && p_cb->srvc_cb[i].in_use &&
133 p_cb->srvc_cb[i + 1].in_use && 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 && attr_id >= p_cb->srvc_cb[i].service_id) ||
138 /* last service incb */
139 (i == (BTA_GATTS_MAX_SRVC_NUM - 1) && attr_id >= p_cb->srvc_cb[i].service_id)) {
140 return &p_cb->srvc_cb[i];
141 }
142 }
143 return NULL;
144 }
145