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