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
20#include "gki.h"
21#include "bta_gattc_co.h"
22#include "bta_gattc_ci.h"
23#include "btif_util.h"
24#include "btm_int.h"
25
26#if( defined BLE_INCLUDED ) && (BLE_INCLUDED == TRUE)
27#if( defined BTA_GATT_INCLUDED ) && (BTA_GATT_INCLUDED == TRUE)
28
29#define GATT_CACHE_PREFIX "/data/misc/bluedroid/gatt_cache_"
30
31static FILE* sCacheFD = 0;
32
33static void getFilename(char *buffer, BD_ADDR bda)
34{
35    sprintf(buffer, "%s%02x%02x%02x%02x%02x%02x", GATT_CACHE_PREFIX
36        , bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]);
37}
38
39static void cacheClose()
40{
41    if (sCacheFD != 0)
42    {
43        fclose(sCacheFD);
44        sCacheFD = 0;
45    }
46}
47
48static bool cacheOpen(BD_ADDR bda, bool to_save)
49{
50    char fname[255] = {0};
51    getFilename(fname, bda);
52
53    cacheClose();
54    sCacheFD = fopen(fname, to_save ? "w" : "r");
55
56    return (sCacheFD != 0);
57}
58
59static void cacheReset(BD_ADDR bda)
60{
61    char fname[255] = {0};
62    getFilename(fname, bda);
63    unlink(fname);
64}
65
66
67/*****************************************************************************
68**  Function Declarations
69*****************************************************************************/
70
71/*******************************************************************************
72**
73** Function         bta_gattc_co_cache_open
74**
75** Description      This callout function is executed by GATTC when a GATT server
76**                  cache is ready to be sent.
77**
78** Parameter        server_bda: server bd address of this cache belongs to
79**                  evt: call in event to be passed in when cache open is done.
80**                  conn_id: connection ID of this cache operation attach to.
81**                  to_save: open cache to save or to load.
82**
83** Returns          void.
84**
85*******************************************************************************/
86void bta_gattc_co_cache_open(BD_ADDR server_bda, UINT16 evt, UINT16 conn_id, BOOLEAN to_save)
87{
88    /* open NV cache and send call in */
89    tBTA_GATT_STATUS    status = BTA_GATT_OK;
90    if (!btm_sec_is_a_bonded_dev(server_bda) || !cacheOpen(server_bda, to_save))
91        status = BTA_GATT_ERROR;
92
93    BTIF_TRACE_DEBUG("%s() - status=%d", __FUNCTION__, status);
94    bta_gattc_ci_cache_open(server_bda, evt, status, conn_id);
95}
96
97/*******************************************************************************
98**
99** Function         bta_gattc_co_cache_load
100**
101** Description      This callout function is executed by GATT when server cache
102**                  is required to load.
103**
104** Parameter        server_bda: server bd address of this cache belongs to
105**                  evt: call in event to be passed in when cache save is done.
106**                  num_attr: number of attribute to be save.
107**                  attr_index: starting attribute index of the save operation.
108**                  conn_id: connection ID of this cache operation attach to.
109** Returns
110**
111*******************************************************************************/
112void bta_gattc_co_cache_load(BD_ADDR server_bda, UINT16 evt, UINT16 start_index, UINT16 conn_id)
113{
114    UINT16              num_attr = 0;
115    tBTA_GATTC_NV_ATTR  attr[BTA_GATTC_NV_LOAD_MAX];
116    tBTA_GATT_STATUS    status = BTA_GATT_ERROR;
117
118    if (sCacheFD && (0 == fseek(sCacheFD, start_index * sizeof(tBTA_GATTC_NV_ATTR), SEEK_SET)))
119    {
120        num_attr = fread(attr, sizeof(tBTA_GATTC_NV_ATTR), BTA_GATTC_NV_LOAD_MAX, sCacheFD);
121        status = (num_attr < BTA_GATTC_NV_LOAD_MAX ? BTA_GATT_OK : BTA_GATT_MORE);
122    }
123
124    BTIF_TRACE_DEBUG("%s() - sCacheFD=%p, start_index=%d, read=%d, status=%d",
125        __FUNCTION__, sCacheFD, start_index, num_attr, status);
126    bta_gattc_ci_cache_load(server_bda, evt, num_attr, attr, status, conn_id);
127}
128
129/*******************************************************************************
130**
131** Function         bta_gattc_co_cache_save
132**
133** Description      This callout function is executed by GATT when a server cache
134**                  is available to save.
135**
136** Parameter        server_bda: server bd address of this cache belongs to
137**                  evt: call in event to be passed in when cache save is done.
138**                  num_attr: number of attribute to be save.
139**                  p_attr: pointer to the list of attributes to save.
140**                  attr_index: starting attribute index of the save operation.
141**                  conn_id: connection ID of this cache operation attach to.
142** Returns
143**
144*******************************************************************************/
145void bta_gattc_co_cache_save (BD_ADDR server_bda, UINT16 evt, UINT16 num_attr,
146                              tBTA_GATTC_NV_ATTR *p_attr_list, UINT16 attr_index, UINT16 conn_id)
147{
148    tBTA_GATT_STATUS    status = BTA_GATT_OK;
149    UNUSED(attr_index);
150
151    if (sCacheFD != 0)
152    {
153        int num = fwrite(p_attr_list, sizeof(tBTA_GATTC_NV_ATTR), num_attr, sCacheFD);
154        BTIF_TRACE_DEBUG("%s() wrote %d", __FUNCTION__, num);
155    }
156
157    bta_gattc_ci_cache_save(server_bda, evt, status, conn_id);
158}
159
160/*******************************************************************************
161**
162** Function         bta_gattc_co_cache_close
163**
164** Description      This callout function is executed by GATTC when a GATT server
165**                  cache is written completely.
166**
167** Parameter        server_bda: server bd address of this cache belongs to
168**                  conn_id: connection ID of this cache operation attach to.
169**
170** Returns          void.
171**
172*******************************************************************************/
173void bta_gattc_co_cache_close(BD_ADDR server_bda, UINT16 conn_id)
174{
175    UNUSED(server_bda);
176    UNUSED(conn_id);
177
178    cacheClose();
179
180    /* close NV when server cache is done saving or loading,
181       does not need to do anything for now on Insight */
182
183    BTIF_TRACE_DEBUG("%s()", __FUNCTION__);
184}
185
186/*******************************************************************************
187**
188** Function         bta_gattc_co_cache_reset
189**
190** Description      This callout function is executed by GATTC to reset cache in
191**                  application
192**
193** Parameter        server_bda: server bd address of this cache belongs to
194**
195** Returns          void.
196**
197*******************************************************************************/
198void bta_gattc_co_cache_reset(BD_ADDR server_bda)
199{
200    BTIF_TRACE_DEBUG("%s()", __FUNCTION__);
201    cacheReset(server_bda);
202}
203
204#endif
205#endif
206
207