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 #include <sys/types.h>
20 #include <sys/stat.h>
21 #include <fcntl.h>
22 #include <errno.h>
23 #include "buildcfg.h"
24 #include "nfa_nv_co.h"
25 #include "config.h"
26 #include "nfc_hal_target.h"
27 #include "nfc_hal_nv_co.h"
28 extern char bcm_nfc_location[];
29 static const char* sNfaStorageBin = "/nfaStorage.bin";
30
31 /*******************************************************************************
32 **
33 ** Function nfa_mem_co_alloc
34 **
35 ** Description allocate a buffer from platform's memory pool
36 **
37 ** Returns:
38 ** pointer to buffer if successful
39 ** NULL otherwise
40 **
41 *******************************************************************************/
nfa_mem_co_alloc(UINT32 num_bytes)42 extern 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 *******************************************************************************/
nfa_mem_co_free(void * pBuffer)58 extern 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 *******************************************************************************/
nfa_nv_co_read(UINT8 * pBuffer,UINT16 nbytes,UINT8 block)84 extern 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 *******************************************************************************/
nfa_nv_co_write(const UINT8 * pBuffer,UINT16 nbytes,UINT8 block)143 extern 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 *******************************************************************************/
delete_stack_non_volatile_store(BOOLEAN forceDelete)197 void 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 *******************************************************************************/
verify_stack_non_volatile_store()240 void 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