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