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 "bt_target.h"
26
27 #include <string.h>
28
29 #include "bt_common.h"
30 #include "bta_gatts_int.h"
31 #include "bta_sys.h"
32 #include "utl.h"
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;
70 i++, p_reg++) {
71 if (p_reg->in_use && p_reg->gatt_if == server_if) return p_reg;
72 }
73 return NULL;
74 }
75
76 /*******************************************************************************
77 *
78 * Function bta_gatts_find_app_rcb_idx_by_app_if
79 *
80 * Description find the index of the application control block by app ID.
81 *
82 * Returns index of the control block, or BTA_GATTS_INVALID_APP if
83 * failed.
84 *
85 ******************************************************************************/
86
bta_gatts_find_app_rcb_idx_by_app_if(tBTA_GATTS_CB * p_cb,tGATT_IF server_if)87 uint8_t bta_gatts_find_app_rcb_idx_by_app_if(tBTA_GATTS_CB* p_cb,
88 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) return i;
93 }
94 return BTA_GATTS_INVALID_APP;
95 }
96 /*******************************************************************************
97 *
98 * Function bta_gatts_find_srvc_cb_by_srvc_id
99 *
100 * Description find the service control block by service ID.
101 *
102 * Returns pointer to the rcb.
103 *
104 ******************************************************************************/
bta_gatts_find_srvc_cb_by_srvc_id(tBTA_GATTS_CB * p_cb,uint16_t service_id)105 tBTA_GATTS_SRVC_CB* bta_gatts_find_srvc_cb_by_srvc_id(tBTA_GATTS_CB* p_cb,
106 uint16_t service_id) {
107 uint8_t i;
108 VLOG(1) << __func__ << ": service_id=" << +service_id;
109 for (i = 0; i < BTA_GATTS_MAX_SRVC_NUM; i++) {
110 if (p_cb->srvc_cb[i].in_use && p_cb->srvc_cb[i].service_id == service_id) {
111 VLOG(1) << __func__ << ": found service cb index=" << +i;
112 return &p_cb->srvc_cb[i];
113 }
114 }
115 return NULL;
116 }
117 /*******************************************************************************
118 *
119 * Function bta_gatts_find_srvc_cb_by_attr_id
120 *
121 * Description find the service control block by attribute ID.
122 *
123 * Returns pointer to the rcb.
124 *
125 ******************************************************************************/
bta_gatts_find_srvc_cb_by_attr_id(tBTA_GATTS_CB * p_cb,uint16_t attr_id)126 tBTA_GATTS_SRVC_CB* bta_gatts_find_srvc_cb_by_attr_id(tBTA_GATTS_CB* p_cb,
127 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 &&
134 attr_id >= p_cb->srvc_cb[i].service_id &&
135 attr_id < p_cb->srvc_cb[i + 1].service_id) ||
136 /* last active service */
137 (i < (BTA_GATTS_MAX_SRVC_NUM - 1) && p_cb->srvc_cb[i].in_use &&
138 !p_cb->srvc_cb[i + 1].in_use &&
139 attr_id >= p_cb->srvc_cb[i].service_id) ||
140 /* last service incb */
141 (i == (BTA_GATTS_MAX_SRVC_NUM - 1) &&
142 attr_id >= p_cb->srvc_cb[i].service_id)) {
143 return &p_cb->srvc_cb[i];
144 }
145 }
146 return NULL;
147 }
148