1 /****************************************************************************** 2 * 3 * Copyright (C) 2009-2013 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 #include "bta_api.h" 20 21 #if( defined BLE_INCLUDED ) && (BLE_INCLUDED == TRUE) 22 #if( defined BTA_GATT_INCLUDED ) && (BTA_GATT_INCLUDED == TRUE) 23 24 #include <stdlib.h> 25 #include "gki.h" 26 #include "bd.h" 27 #include "bta_gatts_co.h" 28 29 /***************************************************************************** 30 ** Local type definitions 31 *****************************************************************************/ 32 33 #define BTIF_GATTS_MAX_SRV_CHG_CLT_SIZE 50 34 35 typedef struct 36 { 37 BOOLEAN enable; 38 UINT8 num_clients; 39 tBTA_GATTS_SRV_CHG srv_chg[BTIF_GATTS_MAX_SRV_CHG_CLT_SIZE]; 40 } __attribute__((packed)) btif_gatts_srv_chg_cb_t; 41 42 /***************************************************************************** 43 ** Static variables 44 *****************************************************************************/ 45 46 static btif_gatts_srv_chg_cb_t btif_gatts_srv_chg_cb; 47 48 /***************************************************************************** 49 ** Static functions 50 *****************************************************************************/ 51 52 static void btif_gatts_check_init(void) 53 { 54 btif_gatts_srv_chg_cb_t *p_cb= &btif_gatts_srv_chg_cb; 55 56 if (!p_cb->enable) 57 { 58 memset(p_cb, 0, sizeof(btif_gatts_srv_chg_cb_t)); 59 p_cb->enable = TRUE; 60 } 61 } 62 63 static BOOLEAN btif_gatts_srv_chg(tBTA_GATTS_SRV_CHG_CMD cmd, 64 tBTA_GATTS_SRV_CHG_REQ *p_req, 65 tBTA_GATTS_SRV_CHG_RSP *p_rsp) 66 { 67 BOOLEAN status = TRUE; 68 BOOLEAN found = FALSE; 69 UINT8 i, j, idx, last_idx; 70 btif_gatts_srv_chg_cb_t *p_cb = &btif_gatts_srv_chg_cb; 71 72 btif_gatts_check_init(); 73 74 switch (cmd) 75 { 76 case BTA_GATTS_SRV_CHG_CMD_ADD_CLIENT: 77 78 if (p_cb->num_clients < BTIF_GATTS_MAX_SRV_CHG_CLT_SIZE) 79 { 80 memcpy(&p_cb->srv_chg[p_cb->num_clients], &p_req->srv_chg, sizeof(tBTA_GATTS_SRV_CHG)); 81 p_cb->num_clients++; 82 } else { 83 status = FALSE; 84 } 85 break; 86 87 case BTA_GATTS_SRV_CHG_CMD_UPDATE_CLIENT: 88 89 for (i=0; i != p_cb->num_clients; ++i) 90 { 91 if (!memcmp(p_cb->srv_chg[i].bda, p_req->srv_chg.bda, sizeof(BD_ADDR))) 92 { 93 found = TRUE; 94 memcpy(&p_cb->srv_chg[i], &p_req->srv_chg, sizeof(tBTA_GATTS_SRV_CHG)); 95 break; 96 } 97 } 98 99 if (!found) 100 status = FALSE; 101 break; 102 103 case BTA_GATTS_SRV_CHG_CMD_REMOVE_CLIENT: 104 105 for (i=0; i != p_cb->num_clients; ++i) 106 { 107 if (!memcmp(p_cb->srv_chg[i].bda, p_req->srv_chg.bda, sizeof(BD_ADDR))) 108 { 109 found = TRUE; 110 last_idx = p_cb->num_clients - 1; 111 112 if (i != last_idx ) 113 { 114 /* Update the array so there is no gap */ 115 for (j=i; j != last_idx; ++j ) 116 { 117 memcpy(&p_cb->srv_chg[j], &p_cb->srv_chg[j+1], sizeof(tBTA_GATTS_SRV_CHG)); 118 } 119 120 } 121 122 /* Reset the last client and update num_clients */ 123 memset(&p_cb->srv_chg[last_idx], 0, sizeof(tBTA_GATTS_SRV_CHG)); 124 p_cb->num_clients--; 125 break; 126 } 127 } 128 129 if (!found) 130 status = FALSE; 131 break; 132 133 case BTA_GATTS_SRV_CHG_CMD_READ_NUM_CLENTS: 134 p_rsp->num_clients = p_cb->num_clients; 135 break; 136 137 case BTA_GATTS_SRV_CHG_CMD_READ_CLENT: 138 idx = p_req->client_read_index - 1; 139 140 if (idx < p_cb->num_clients ) 141 memcpy(&p_rsp->srv_chg, &p_cb->srv_chg[idx], sizeof(tBTA_GATTS_SRV_CHG)); 142 else 143 status = FALSE; 144 break; 145 146 default: 147 status = FALSE; 148 break; 149 } 150 151 return status; 152 } 153 154 /***************************************************************************** 155 ** Externally called functions 156 *****************************************************************************/ 157 158 void btif_gatts_add_bonded_dev_from_nv(BD_ADDR bda) 159 { 160 btif_gatts_srv_chg_cb_t *p_cb= &btif_gatts_srv_chg_cb; 161 BOOLEAN found = FALSE; 162 UINT8 i; 163 164 btif_gatts_check_init(); 165 166 for (i=0; i != p_cb->num_clients; ++i) 167 { 168 if (!memcmp(p_cb->srv_chg[i].bda, bda, sizeof(BD_ADDR))) 169 { 170 found = TRUE; 171 break; 172 } 173 } 174 175 if (!found) 176 { 177 if (p_cb->num_clients < BTIF_GATTS_MAX_SRV_CHG_CLT_SIZE) 178 { 179 bdcpy(p_cb->srv_chg[p_cb->num_clients].bda, bda); 180 p_cb->srv_chg[p_cb->num_clients].srv_changed = FALSE; 181 p_cb->num_clients++; 182 } 183 } 184 } 185 186 /***************************************************************************** 187 ** Call-out functions 188 *****************************************************************************/ 189 190 /******************************************************************************* 191 ** 192 ** Function bta_gatts_co_update_handle_range 193 ** 194 ** Description This callout function is executed by GATTS when a GATT server 195 ** handle range ios to be added or removed. 196 ** 197 ** Parameter is_add: true is to add a handle range; otherwise is to delete. 198 ** p_hndl_range: handle range. 199 ** 200 ** Returns void. 201 ** 202 *******************************************************************************/ 203 void bta_gatts_co_update_handle_range(BOOLEAN is_add, tBTA_GATTS_HNDL_RANGE *p_hndl_range) 204 { 205 } 206 207 /******************************************************************************* 208 ** 209 ** Function bta_gatts_co_srv_chg 210 ** 211 ** Description This call-out is to read/write/remove service change related 212 ** informaiton. The request consists of the cmd and p_req and the 213 ** response is returned in p_rsp 214 ** 215 ** Parameter cmd - request command 216 ** p_req - request paramters 217 ** p_rsp - response data for the request 218 ** 219 ** Returns TRUE - if the request is processed successfully and 220 ** the response is returned in p_rsp. 221 ** FASLE - if the request can not be processed 222 ** 223 *******************************************************************************/ 224 BOOLEAN bta_gatts_co_srv_chg(tBTA_GATTS_SRV_CHG_CMD cmd, 225 tBTA_GATTS_SRV_CHG_REQ *p_req, 226 tBTA_GATTS_SRV_CHG_RSP *p_rsp) 227 { 228 return FALSE; 229 } 230 231 /******************************************************************************* 232 ** 233 ** Function bta_gatts_co_load_handle_range 234 ** 235 ** Description This callout function is executed by GATTS when a GATT server 236 ** handle range is requested to be loaded from NV. 237 ** 238 ** Parameter 239 ** 240 ** Returns void. 241 ** 242 *******************************************************************************/ 243 BOOLEAN bta_gatts_co_load_handle_range(UINT8 index, 244 tBTA_GATTS_HNDL_RANGE *p_handle_range) 245 { 246 return FALSE; 247 } 248 #endif 249 #endif 250