1 /******************************************************************************
2  *
3  *  Copyright (C) 2011-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 
20 #include <errno.h>
21 #include <fcntl.h>
22 #include <malloc.h>
23 #include <sys/stat.h>
24 #include <sys/types.h>
25 #include "CrcChecksum.h"
26 #include "buildcfg.h"
27 #include "config.h"
28 #include "nfa_nv_ci.h"
29 #include "nfa_nv_co.h"
30 #include "nfc_hal_nv_co.h"
31 #include "nfc_hal_target.h"
32 extern char bcm_nfc_location[];
33 static const char* sNfaStorageBin = "/nfaStorage.bin";
34 
35 /*******************************************************************************
36 **
37 ** Function         nfa_mem_co_alloc
38 **
39 ** Description      allocate a buffer from platform's memory pool
40 **
41 ** Returns:
42 **                  pointer to buffer if successful
43 **                  NULL otherwise
44 **
45 *******************************************************************************/
nfa_mem_co_alloc(uint32_t num_bytes)46 extern void* nfa_mem_co_alloc(uint32_t num_bytes) { return malloc(num_bytes); }
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 *******************************************************************************/
nfa_mem_co_free(void * pBuffer)58 extern void nfa_mem_co_free(void* pBuffer) { free(pBuffer); }
59 
60 /*******************************************************************************
61 **
62 ** Function         nfa_nv_co_read
63 **
64 ** Description      This function is called by NFA to read in data from the
65 **                  previously opened file.
66 **
67 ** Parameters       pBuffer   - buffer to read the data into.
68 **                  nbytes  - number of bytes to read into the buffer.
69 **
70 ** Returns          void
71 **
72 **                  Note: Upon completion of the request, nfa_nv_ci_read() is
73 **                        called with the buffer of data, along with the number
74 **                        of bytes read into the buffer, and a status.  The
75 **                        call-in function should only be called when ALL
76 **                        requested bytes have been read, the end of file has
77 **                        been detected, or an error has occurred.
78 **
79 *******************************************************************************/
nfa_nv_co_read(uint8_t * pBuffer,uint16_t nbytes,uint8_t block)80 extern void nfa_nv_co_read(uint8_t* pBuffer, uint16_t nbytes, uint8_t block) {
81   char filename[256], filename2[256];
82 
83   memset(filename, 0, sizeof(filename));
84   memset(filename2, 0, sizeof(filename2));
85   strcpy(filename2, bcm_nfc_location);
86   strncat(filename2, sNfaStorageBin, sizeof(filename2) - strlen(filename2) - 1);
87   if (strlen(filename2) > 200) {
88     ALOGE("%s: filename too long", __func__);
89     return;
90   }
91   sprintf(filename, "%s%u", filename2, block);
92 
93   ALOGD("%s: buffer len=%u; file=%s", __func__, nbytes, filename);
94   int fileStream = open(filename, O_RDONLY);
95   if (fileStream >= 0) {
96     unsigned short checksum = 0;
97     size_t actualReadCrc = read(fileStream, &checksum, sizeof(checksum));
98     size_t actualReadData = read(fileStream, pBuffer, nbytes);
99     close(fileStream);
100     if (actualReadData > 0) {
101       ALOGD("%s: data size=%zu", __func__, actualReadData);
102       nfa_nv_ci_read(actualReadData, NFA_NV_CO_OK, block);
103     } else {
104       ALOGE("%s: fail to read", __func__);
105       nfa_nv_ci_read(0, NFA_NV_CO_FAIL, block);
106     }
107   } else {
108     ALOGD("%s: fail to open", __func__);
109     nfa_nv_ci_read(0, NFA_NV_CO_FAIL, block);
110   }
111 }
112 
113 /*******************************************************************************
114 **
115 ** Function         nfa_nv_co_write
116 **
117 ** Description      This function is called by io to send file data to the
118 **                  phone.
119 **
120 ** Parameters       pBuffer   - buffer to read the data from.
121 **                  nbytes  - number of bytes to write out to the file.
122 **
123 ** Returns          void
124 **
125 **                  Note: Upon completion of the request, nfa_nv_ci_write() is
126 **                        called with the file descriptor and the status.  The
127 **                        call-in function should only be called when ALL
128 **                        requested bytes have been written, or an error has
129 **                        been detected,
130 **
131 *******************************************************************************/
nfa_nv_co_write(const uint8_t * pBuffer,uint16_t nbytes,uint8_t block)132 extern void nfa_nv_co_write(const uint8_t* pBuffer, uint16_t nbytes,
133                             uint8_t block) {
134   char filename[256], filename2[256];
135 
136   memset(filename, 0, sizeof(filename));
137   memset(filename2, 0, sizeof(filename2));
138   strcpy(filename2, bcm_nfc_location);
139   strncat(filename2, sNfaStorageBin, sizeof(filename2) - strlen(filename2) - 1);
140   if (strlen(filename2) > 200) {
141     ALOGE("%s: filename too long", __func__);
142     return;
143   }
144   sprintf(filename, "%s%u", filename2, block);
145   ALOGD("%s: bytes=%u; file=%s", __func__, nbytes, filename);
146 
147   int fileStream = 0;
148 
149   fileStream = open(filename, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
150   if (fileStream >= 0) {
151     unsigned short checksum = crcChecksumCompute(pBuffer, nbytes);
152     size_t actualWrittenCrc = write(fileStream, &checksum, sizeof(checksum));
153     size_t actualWrittenData = write(fileStream, pBuffer, nbytes);
154     ALOGD("%s: %zu bytes written", __func__, actualWrittenData);
155     if ((actualWrittenData == nbytes) &&
156         (actualWrittenCrc == sizeof(checksum))) {
157       nfa_nv_ci_write(NFA_NV_CO_OK);
158     } else {
159       ALOGE("%s: fail to write", __func__);
160       nfa_nv_ci_write(NFA_NV_CO_FAIL);
161     }
162     close(fileStream);
163   } else {
164     ALOGE("%s: fail to open, error = %d", __func__, errno);
165     nfa_nv_ci_write(NFA_NV_CO_FAIL);
166   }
167 }
168 
169 /*******************************************************************************
170 **
171 ** Function         delete_stack_non_volatile_store
172 **
173 ** Description      Delete all the content of the stack's storage location.
174 **
175 ** Parameters       forceDelete: unconditionally delete the storage.
176 **
177 ** Returns          none
178 **
179 *******************************************************************************/
delete_stack_non_volatile_store(bool forceDelete)180 void delete_stack_non_volatile_store(bool forceDelete) {
181   static bool firstTime = true;
182   char filename[256], filename2[256];
183 
184   if ((firstTime == false) && (forceDelete == false)) return;
185   firstTime = false;
186 
187   ALOGD("%s", __func__);
188 
189   memset(filename, 0, sizeof(filename));
190   memset(filename2, 0, sizeof(filename2));
191   strcpy(filename2, bcm_nfc_location);
192   strncat(filename2, sNfaStorageBin, sizeof(filename2) - strlen(filename2) - 1);
193   if (strlen(filename2) > 200) {
194     ALOGE("%s: filename too long", __func__);
195     return;
196   }
197   sprintf(filename, "%s%u", filename2, DH_NV_BLOCK);
198   remove(filename);
199   sprintf(filename, "%s%u", filename2, HC_F3_NV_BLOCK);
200   remove(filename);
201   sprintf(filename, "%s%u", filename2, HC_F4_NV_BLOCK);
202   remove(filename);
203   sprintf(filename, "%s%u", filename2, HC_F2_NV_BLOCK);
204   remove(filename);
205   sprintf(filename, "%s%u", filename2, HC_F5_NV_BLOCK);
206   remove(filename);
207 }
208 
209 /*******************************************************************************
210 **
211 ** Function         verify_stack_non_volatile_store
212 **
213 ** Description      Verify the content of all non-volatile store.
214 **
215 ** Parameters       none
216 **
217 ** Returns          none
218 **
219 *******************************************************************************/
verify_stack_non_volatile_store()220 void verify_stack_non_volatile_store() {
221   ALOGD("%s", __func__);
222   char filename[256], filename2[256];
223   bool isValid = false;
224 
225   memset(filename, 0, sizeof(filename));
226   memset(filename2, 0, sizeof(filename2));
227   strcpy(filename2, bcm_nfc_location);
228   strncat(filename2, sNfaStorageBin, sizeof(filename2) - strlen(filename2) - 1);
229   if (strlen(filename2) > 200) {
230     ALOGE("%s: filename too long", __func__);
231     return;
232   }
233 
234   sprintf(filename, "%s%u", filename2, DH_NV_BLOCK);
235   if (crcChecksumVerifyIntegrity(filename)) {
236     sprintf(filename, "%s%u", filename2, HC_F3_NV_BLOCK);
237     if (crcChecksumVerifyIntegrity(filename)) {
238       sprintf(filename, "%s%u", filename2, HC_F4_NV_BLOCK);
239       if (crcChecksumVerifyIntegrity(filename)) {
240         sprintf(filename, "%s%u", filename2, HC_F2_NV_BLOCK);
241         if (crcChecksumVerifyIntegrity(filename)) {
242           sprintf(filename, "%s%u", filename2, HC_F5_NV_BLOCK);
243           if (crcChecksumVerifyIntegrity(filename)) isValid = true;
244         }
245       }
246     }
247   }
248 
249   if (isValid == false) delete_stack_non_volatile_store(true);
250 }
251