NonVolatileStore.cpp revision 46f4e4f7099609ff6b5e7efce7b91b4252bdbfb1
1/******************************************************************************
2 *
3 *  Copyright (C) 1999-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#include "OverrideLog.h"
19#define LOG_TAG "NfcNciHal"
20#include "gki.h"
21extern "C"
22{
23    #include "nfc_hal_target.h"
24    #include "nfc_hal_nv_ci.h"
25}
26#include "config.h"
27#include "CrcChecksum.h"
28#include <sys/types.h>
29#include <sys/stat.h>
30#include <fcntl.h>
31#include <errno.h>
32#include <string>
33
34
35//directory of HAL's non-volatile storage
36static const char* default_location = "/data/nfc";
37static const char* filename_prefix = "/halStorage.bin";
38static const std::string get_storage_location ();
39void delete_hal_non_volatile_store (bool forceDelete);
40void verify_hal_non_volatile_store ();
41
42
43/*******************************************************************************
44**
45** Function         nfc_hal_nv_co_read
46**
47** Description      This function is called by NFA to read in data from the
48**                  previously opened file.
49**
50** Parameters       p_buf   - buffer to read the data into.
51**                  nbytes  - number of bytes to read into the buffer.
52**
53** Returns          void
54**
55**                  Note: Upon completion of the request, nfc_hal_nv_ci_read () is
56**                        called with the buffer of data, along with the number
57**                        of bytes read into the buffer, and a status.  The
58**                        call-in function should only be called when ALL requested
59**                        bytes have been read, the end of file has been detected,
60**                        or an error has occurred.
61**
62*******************************************************************************/
63void nfc_hal_nv_co_read (UINT8 *p_buf, UINT16 nbytes, UINT8 block)
64{
65    std::string fn = get_storage_location();
66    char filename[256];
67
68    fn.append (filename_prefix);
69    if (fn.length() > 200)
70    {
71        ALOGE ("%s: filename too long", __FUNCTION__);
72        return;
73    }
74    snprintf (filename, sizeof(filename), "%s%u", fn.c_str(), block);
75
76    ALOGD ("%s: buffer len=%u; file=%s", __FUNCTION__, nbytes, filename);
77    int fileStream = open (filename, O_RDONLY);
78    if (fileStream >= 0)
79    {
80        unsigned short checksum = 0;
81        size_t actualReadCrc = read (fileStream, &checksum, sizeof(checksum));
82        size_t actualReadData = read (fileStream, p_buf, nbytes);
83        close (fileStream);
84        if (actualReadData > 0)
85        {
86            ALOGD ("%s: data size=%u", __FUNCTION__, actualReadData);
87            nfc_hal_nv_ci_read (actualReadData, NFC_HAL_NV_CO_OK, block);
88        }
89        else
90        {
91            ALOGE ("%s: fail to read", __FUNCTION__);
92            nfc_hal_nv_ci_read (0, NFC_HAL_NV_CO_FAIL, block);
93        }
94    }
95    else
96    {
97        ALOGD ("%s: fail to open", __FUNCTION__);
98        nfc_hal_nv_ci_read (0, NFC_HAL_NV_CO_FAIL, block);
99    }
100}
101
102
103/*******************************************************************************
104**
105** Function         nfc_hal_nv_co_write
106**
107** Description      This function is called by io to send file data to the
108**                  phone.
109**
110** Parameters       p_buf   - buffer to read the data from.
111**                  nbytes  - number of bytes to write out to the file.
112**
113** Returns          void
114**
115**                  Note: Upon completion of the request, nfc_hal_nv_ci_write () is
116**                        called with the file descriptor and the status.  The
117**                        call-in function should only be called when ALL requested
118**                        bytes have been written, or an error has been detected,
119**
120*******************************************************************************/
121void nfc_hal_nv_co_write (const UINT8 *p_buf, UINT16 nbytes, UINT8 block)
122{
123    std::string fn = get_storage_location();
124    char filename[256];
125    int fileStream = 0;
126
127    fn.append (filename_prefix);
128    if (fn.length() > 200)
129    {
130        ALOGE ("%s: filename too long", __FUNCTION__);
131        return;
132    }
133    snprintf (filename, sizeof(filename), "%s%u", fn.c_str(), block);
134    ALOGD ("%s: bytes=%u; file=%s", __FUNCTION__, nbytes, filename);
135
136    fileStream = open (filename, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
137    if (fileStream >= 0)
138    {
139        unsigned short checksum = crcChecksumCompute (p_buf, nbytes);
140        size_t actualWrittenCrc = write (fileStream, &checksum, sizeof(checksum));
141        size_t actualWrittenData = write (fileStream, p_buf, nbytes);
142        ALOGD ("%s: %d bytes written", __FUNCTION__, actualWrittenData);
143        if ((actualWrittenData == nbytes) && (actualWrittenCrc == sizeof(checksum)))
144        {
145            nfc_hal_nv_ci_write (NFC_HAL_NV_CO_OK);
146        }
147        else
148        {
149            ALOGE ("%s: fail to write", __FUNCTION__);
150            nfc_hal_nv_ci_write (NFC_HAL_NV_CO_FAIL);
151        }
152        close (fileStream);
153    }
154    else
155    {
156        ALOGE ("%s: fail to open, error = %d", __FUNCTION__, errno);
157        nfc_hal_nv_ci_write (NFC_HAL_NV_CO_FAIL);
158    }
159}
160
161
162/*******************************************************************************
163**
164** Function         get_storage_location
165**
166** Description      Get the absolute directory path of the HAL's storage location.
167**
168** Parameters       none
169**
170** Returns          Absolute path.
171**
172*******************************************************************************/
173const std::string get_storage_location ()
174{
175    char buffer [100];
176    memset (buffer, 0, sizeof(buffer));
177    if (!GetStrValue (NAME_NFA_STORAGE, buffer, sizeof(buffer)))
178        return default_location;
179    else
180        return std::string (buffer);
181}
182
183
184/*******************************************************************************
185**
186** Function         delete_hal_non_volatile_store
187**
188** Description      Delete all the content of the HAL's storage location.
189**
190** Parameters       forceDelete: unconditionally delete the storage.
191**
192** Returns          none
193**
194*******************************************************************************/
195void delete_hal_non_volatile_store (bool forceDelete)
196{
197    static bool firstTime = true;
198    std::string fn = get_storage_location();
199    char filename[256];
200    int stat = 0;
201
202    if ((firstTime == false) && (forceDelete == false))
203        return;
204    firstTime = false;
205
206    ALOGD ("%s", __FUNCTION__);
207
208    fn.append (filename_prefix);
209    if (fn.length() > 200)
210    {
211        ALOGE ("%s: filename too long", __FUNCTION__);
212        return;
213    }
214
215    snprintf (filename, sizeof(filename), "%s%u", fn.c_str(), DH_NV_BLOCK);
216    remove (filename);
217    snprintf (filename, sizeof(filename), "%s%u", fn.c_str(), HC_F3_NV_BLOCK);
218    remove (filename);
219    snprintf (filename, sizeof(filename), "%s%u", fn.c_str(), HC_F4_NV_BLOCK);
220    remove (filename);
221    snprintf (filename, sizeof(filename), "%s%u", fn.c_str(), HC_F2_NV_BLOCK);
222    remove (filename);
223    snprintf (filename, sizeof(filename), "%s%u", fn.c_str(), HC_F5_NV_BLOCK);
224    remove (filename);
225}
226
227
228/*******************************************************************************
229**
230** Function         verify_hal_non_volatile_store
231**
232** Description      Verify the content of all non-volatile store.
233**
234** Parameters       none
235**
236** Returns          none
237**
238*******************************************************************************/
239void verify_hal_non_volatile_store ()
240{
241    ALOGD ("%s", __FUNCTION__);
242    std::string fn = get_storage_location();
243    char filename[256];
244    bool isValid = false;
245
246    fn.append (filename_prefix);
247    if (fn.length() > 200)
248    {
249        ALOGE ("%s: filename too long", __FUNCTION__);
250        return;
251    }
252
253    snprintf (filename, sizeof(filename), "%s%u", fn.c_str(), DH_NV_BLOCK);
254    if (crcChecksumVerifyIntegrity (filename))
255    {
256        snprintf (filename, sizeof(filename), "%s%u", fn.c_str(), HC_F3_NV_BLOCK);
257        if (crcChecksumVerifyIntegrity (filename))
258        {
259            snprintf (filename, sizeof(filename), "%s%u", fn.c_str(), HC_F4_NV_BLOCK);
260            if (crcChecksumVerifyIntegrity (filename))
261            {
262                snprintf (filename, sizeof(filename), "%s%u", fn.c_str(), HC_F2_NV_BLOCK);
263                if (crcChecksumVerifyIntegrity (filename))
264                {
265                    snprintf (filename, sizeof(filename), "%s%u", fn.c_str(), HC_F5_NV_BLOCK);
266                    if (crcChecksumVerifyIntegrity (filename))
267                        isValid = true;
268                }
269            }
270        }
271    }
272
273    if (isValid == false)
274        delete_hal_non_volatile_store (true);
275}
276