15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)/******************************************************************************
25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *
35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *  Copyright (C) 2011-2012 Broadcom Corporation
45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *
55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *  Licensed under the Apache License, Version 2.0 (the "License");
65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *  you may not use this file except in compliance with the License.
75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *  You may obtain a copy of the License at:
85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *
95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *  http://www.apache.org/licenses/LICENSE-2.0
105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *
115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *  Unless required by applicable law or agreed to in writing, software
125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *  distributed under the License is distributed on an "AS IS" BASIS,
135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *  See the License for the specific language governing permissions and
155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *  limitations under the License.
165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *
175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ******************************************************************************/
185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "OverrideLog.h"
195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <sys/types.h>
205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <sys/stat.h>
215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <fcntl.h>
225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <errno.h>
235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "buildcfg.h"
245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "nfa_nv_co.h"
255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "config.h"
265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "nfc_hal_target.h"
275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "nfc_hal_nv_co.h"
285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)extern char bcm_nfc_location[];
295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)static const char* sNfaStorageBin = "/nfaStorage.bin";
305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)/*******************************************************************************
325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)**
335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)** Function         nfa_mem_co_alloc
345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)**
355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)** Description      allocate a buffer from platform's memory pool
365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)**
375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)** Returns:
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)**                  pointer to buffer if successful
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)**                  NULL otherwise
40**
41*******************************************************************************/
42extern void *nfa_mem_co_alloc(UINT32 num_bytes)
43{
44    return malloc(num_bytes);
45}
46
47
48/*******************************************************************************
49**
50** Function         nfa_mem_co_free
51**
52** Description      free buffer previously allocated using nfa_mem_co_alloc
53**
54** Returns:
55**                  Nothing
56**
57*******************************************************************************/
58extern void nfa_mem_co_free(void *pBuffer)
59{
60    free(pBuffer);
61}
62
63
64/*******************************************************************************
65**
66** Function         nfa_nv_co_read
67**
68** Description      This function is called by NFA to read in data from the
69**                  previously opened file.
70**
71** Parameters       pBuffer   - buffer to read the data into.
72**                  nbytes  - number of bytes to read into the buffer.
73**
74** Returns          void
75**
76**                  Note: Upon completion of the request, nfa_nv_ci_read() is
77**                        called with the buffer of data, along with the number
78**                        of bytes read into the buffer, and a status.  The
79**                        call-in function should only be called when ALL requested
80**                        bytes have been read, the end of file has been detected,
81**                        or an error has occurred.
82**
83*******************************************************************************/
84extern void nfa_nv_co_read(UINT8 *pBuffer, UINT16 nbytes, UINT8 block)
85{
86    char filename[256], filename2[256];
87
88    memset (filename, 0, sizeof(filename));
89    memset (filename2, 0, sizeof(filename2));
90    strcpy(filename2, bcm_nfc_location);
91    strncat(filename2, sNfaStorageBin, sizeof(filename2)-strlen(filename2)-1);
92    if (strlen(filename2) > 200)
93    {
94        ALOGE ("%s: filename too long", __FUNCTION__);
95        return;
96    }
97    sprintf (filename, "%s%u", filename2, block);
98
99    ALOGD ("%s: buffer len=%u; file=%s", __FUNCTION__, nbytes, filename);
100    int fileStream = open (filename, O_RDONLY);
101    if (fileStream >= 0)
102    {
103        unsigned short checksum = 0;
104        size_t actualReadCrc = read (fileStream, &checksum, sizeof(checksum));
105        size_t actualReadData = read (fileStream, pBuffer, nbytes);
106        close (fileStream);
107        if (actualReadData > 0)
108        {
109            ALOGD ("%s: data size=%zu", __FUNCTION__, actualReadData);
110            nfa_nv_ci_read (actualReadData, NFA_NV_CO_OK, block);
111        }
112        else
113        {
114            ALOGE ("%s: fail to read", __FUNCTION__);
115            nfa_nv_ci_read (0, NFA_NV_CO_FAIL, block);
116        }
117    }
118    else
119    {
120        ALOGD ("%s: fail to open", __FUNCTION__);
121        nfa_nv_ci_read (0, NFA_NV_CO_FAIL, block);
122    }
123}
124
125/*******************************************************************************
126**
127** Function         nfa_nv_co_write
128**
129** Description      This function is called by io to send file data to the
130**                  phone.
131**
132** Parameters       pBuffer   - buffer to read the data from.
133**                  nbytes  - number of bytes to write out to the file.
134**
135** Returns          void
136**
137**                  Note: Upon completion of the request, nfa_nv_ci_write() is
138**                        called with the file descriptor and the status.  The
139**                        call-in function should only be called when ALL requested
140**                        bytes have been written, or an error has been detected,
141**
142*******************************************************************************/
143extern void nfa_nv_co_write(const UINT8 *pBuffer, UINT16 nbytes, UINT8 block)
144{
145    char filename[256], filename2[256];
146
147    memset (filename, 0, sizeof(filename));
148    memset (filename2, 0, sizeof(filename2));
149    strcpy(filename2, bcm_nfc_location);
150    strncat(filename2, sNfaStorageBin, sizeof(filename2)-strlen(filename2)-1);
151    if (strlen(filename2) > 200)
152    {
153        ALOGE ("%s: filename too long", __FUNCTION__);
154        return;
155    }
156    sprintf (filename, "%s%u", filename2, block);
157    ALOGD ("%s: bytes=%u; file=%s", __FUNCTION__, nbytes, filename);
158
159    int fileStream = 0;
160
161    fileStream = open (filename, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
162    if (fileStream >= 0)
163    {
164        unsigned short checksum = crcChecksumCompute (pBuffer, nbytes);
165        size_t actualWrittenCrc = write (fileStream, &checksum, sizeof(checksum));
166        size_t actualWrittenData = write (fileStream, pBuffer, nbytes);
167        ALOGD ("%s: %zu bytes written", __FUNCTION__, actualWrittenData);
168        if ((actualWrittenData == nbytes) && (actualWrittenCrc == sizeof(checksum)))
169        {
170            nfa_nv_ci_write (NFA_NV_CO_OK);
171        }
172        else
173        {
174            ALOGE ("%s: fail to write", __FUNCTION__);
175            nfa_nv_ci_write (NFA_NV_CO_FAIL);
176        }
177        close (fileStream);
178    }
179    else
180    {
181        ALOGE ("%s: fail to open, error = %d", __FUNCTION__, errno);
182        nfa_nv_ci_write (NFA_NV_CO_FAIL);
183    }
184}
185
186/*******************************************************************************
187**
188** Function         delete_stack_non_volatile_store
189**
190** Description      Delete all the content of the stack's storage location.
191**
192** Parameters       forceDelete: unconditionally delete the storage.
193**
194** Returns          none
195**
196*******************************************************************************/
197void delete_stack_non_volatile_store (BOOLEAN forceDelete)
198{
199    static BOOLEAN firstTime = TRUE;
200    char filename[256], filename2[256];
201
202    if ((firstTime == FALSE) && (forceDelete == FALSE))
203        return;
204    firstTime = FALSE;
205
206    ALOGD ("%s", __FUNCTION__);
207
208    memset (filename, 0, sizeof(filename));
209    memset (filename2, 0, sizeof(filename2));
210    strcpy(filename2, bcm_nfc_location);
211    strncat(filename2, sNfaStorageBin, sizeof(filename2)-strlen(filename2)-1);
212    if (strlen(filename2) > 200)
213    {
214        ALOGE ("%s: filename too long", __FUNCTION__);
215        return;
216    }
217    sprintf (filename, "%s%u", filename2, DH_NV_BLOCK);
218    remove (filename);
219    sprintf (filename, "%s%u", filename2, HC_F3_NV_BLOCK);
220    remove (filename);
221    sprintf (filename, "%s%u", filename2, HC_F4_NV_BLOCK);
222    remove (filename);
223    sprintf (filename, "%s%u", filename2, HC_F2_NV_BLOCK);
224    remove (filename);
225    sprintf (filename, "%s%u", filename2, HC_F5_NV_BLOCK);
226    remove (filename);
227}
228
229/*******************************************************************************
230**
231** Function         verify_stack_non_volatile_store
232**
233** Description      Verify the content of all non-volatile store.
234**
235** Parameters       none
236**
237** Returns          none
238**
239*******************************************************************************/
240void verify_stack_non_volatile_store ()
241{
242    ALOGD ("%s", __FUNCTION__);
243    char filename[256], filename2[256];
244    BOOLEAN isValid = FALSE;
245
246    memset (filename, 0, sizeof(filename));
247    memset (filename2, 0, sizeof(filename2));
248    strcpy(filename2, bcm_nfc_location);
249    strncat(filename2, sNfaStorageBin, sizeof(filename2)-strlen(filename2)-1);
250    if (strlen(filename2) > 200)
251    {
252        ALOGE ("%s: filename too long", __FUNCTION__);
253        return;
254    }
255
256    sprintf (filename, "%s%u", filename2, DH_NV_BLOCK);
257    if (crcChecksumVerifyIntegrity (filename))
258    {
259        sprintf (filename, "%s%u", filename2, HC_F3_NV_BLOCK);
260        if (crcChecksumVerifyIntegrity (filename))
261        {
262            sprintf (filename, "%s%u", filename2, HC_F4_NV_BLOCK);
263            if (crcChecksumVerifyIntegrity (filename))
264            {
265                sprintf (filename, "%s%u", filename2, HC_F2_NV_BLOCK);
266                if (crcChecksumVerifyIntegrity (filename))
267                {
268                    sprintf (filename, "%s%u", filename2, HC_F5_NV_BLOCK);
269                    if (crcChecksumVerifyIntegrity (filename))
270                        isValid = TRUE;
271                }
272            }
273        }
274    }
275
276    if (isValid == FALSE)
277        delete_stack_non_volatile_store (TRUE);
278}
279
280