• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <android-base/stringprintf.h>
19 #include <base/logging.h>
20 #include <fcntl.h>
21 
22 #include <vector>
23 
24 #include "CrcChecksum.h"
25 #include "nfa_nv_ci.h"
26 #include "nfc_hal_nv_co.h"
27 
28 using android::base::StringPrintf;
29 
30 extern std::string nfc_storage_path;
31 extern bool nfc_debug_enabled;
32 
33 namespace {
getFilenameForBlock(const unsigned block)34 std::string getFilenameForBlock(const unsigned block) {
35   std::string bin = "nfaStorage.bin";
36   return StringPrintf("%s/%s%u", nfc_storage_path.c_str(), bin.c_str(), block);
37 }
38 }  // namespace
39 
40 /*******************************************************************************
41 **
42 ** Function         nfa_mem_co_alloc
43 **
44 ** Description      allocate a buffer from platform's memory pool
45 **
46 ** Returns:
47 **                  pointer to buffer if successful
48 **                  NULL otherwise
49 **
50 *******************************************************************************/
nfa_mem_co_alloc(uint32_t num_bytes)51 extern void* nfa_mem_co_alloc(uint32_t num_bytes) { return malloc(num_bytes); }
52 
53 /*******************************************************************************
54 **
55 ** Function         nfa_mem_co_free
56 **
57 ** Description      free buffer previously allocated using nfa_mem_co_alloc
58 **
59 ** Returns:
60 **                  Nothing
61 **
62 *******************************************************************************/
nfa_mem_co_free(void * pBuffer)63 extern void nfa_mem_co_free(void* pBuffer) { free(pBuffer); }
64 
65 /*******************************************************************************
66 **
67 ** Function         nfa_nv_co_read
68 **
69 ** Description      This function is called by NFA to read in data from the
70 **                  previously opened file.
71 **
72 ** Parameters       pBuffer   - buffer to read the data into.
73 **                  nbytes  - number of bytes to read into the buffer.
74 **
75 ** Returns          void
76 **
77 **                  Note: Upon completion of the request, nfa_nv_ci_read() is
78 **                        called with the buffer of data, along with the number
79 **                        of bytes read into the buffer, and a status.  The
80 **                        call-in function should only be called when ALL
81 **                        requested bytes have been read, the end of file has
82 **                        been detected, or an error has occurred.
83 **
84 *******************************************************************************/
nfa_nv_co_read(uint8_t * pBuffer,uint16_t nbytes,uint8_t block)85 extern void nfa_nv_co_read(uint8_t* pBuffer, uint16_t nbytes, uint8_t block) {
86   std::string filename = getFilenameForBlock(block);
87 
88   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
89       "%s: buffer len=%u; file=%s", __func__, nbytes, filename.c_str());
90   int fileStream = open(filename.c_str(), O_RDONLY);
91   if (fileStream >= 0) {
92     uint16_t checksum = 0;
93     size_t checkSumRdData = read(fileStream, &checksum, sizeof(checksum));
94     if (checkSumRdData <= 0) {
95       LOG(ERROR) << StringPrintf("%s: failed to read checksum, errno = 0x%02x",
96                                  __func__, errno);
97     }
98     size_t actualReadData = read(fileStream, pBuffer, nbytes);
99     close(fileStream);
100     if (actualReadData > 0) {
101       DLOG_IF(INFO, nfc_debug_enabled)
102           << StringPrintf("%s: data size=%zu", __func__, actualReadData);
103       nfa_nv_ci_read(actualReadData, NFA_NV_CO_OK, block);
104     } else {
105       LOG(ERROR) << StringPrintf("%s: fail to read", __func__);
106       nfa_nv_ci_read(0, NFA_NV_CO_FAIL, block);
107     }
108   } else {
109     DLOG_IF(INFO, nfc_debug_enabled)
110         << StringPrintf("%s: fail to open", __func__);
111     nfa_nv_ci_read(0, NFA_NV_CO_FAIL, block);
112   }
113 }
114 
115 /*******************************************************************************
116 **
117 ** Function         nfa_nv_co_write
118 **
119 ** Description      This function is called by io to send file data to the
120 **                  phone.
121 **
122 ** Parameters       pBuffer   - buffer to read the data from.
123 **                  nbytes  - number of bytes to write out to the file.
124 **
125 ** Returns          void
126 **
127 **                  Note: Upon completion of the request, nfa_nv_ci_write() is
128 **                        called with the file descriptor and the status.  The
129 **                        call-in function should only be called when ALL
130 **                        requested bytes have been written, or an error has
131 **                        been detected,
132 **
133 *******************************************************************************/
nfa_nv_co_write(const uint8_t * pBuffer,uint16_t nbytes,uint8_t block)134 extern void nfa_nv_co_write(const uint8_t* pBuffer, uint16_t nbytes,
135                             uint8_t block) {
136   std::string filename = getFilenameForBlock(block);
137 
138   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
139       "%s: bytes=%u; file=%s", __func__, nbytes, filename.c_str());
140 
141   int fileStream =
142       open(filename.c_str(), O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
143   if (fileStream >= 0) {
144     uint16_t checksum = crcChecksumCompute(pBuffer, nbytes);
145     size_t actualWrittenCrc = write(fileStream, &checksum, sizeof(checksum));
146     size_t actualWrittenData = write(fileStream, pBuffer, nbytes);
147     DLOG_IF(INFO, nfc_debug_enabled)
148         << StringPrintf("%s: %zu bytes written", __func__, actualWrittenData);
149     if ((actualWrittenData == nbytes) &&
150         (actualWrittenCrc == sizeof(checksum))) {
151       nfa_nv_ci_write(NFA_NV_CO_OK);
152     } else {
153       LOG(ERROR) << StringPrintf("%s: fail to write", __func__);
154       nfa_nv_ci_write(NFA_NV_CO_FAIL);
155     }
156     close(fileStream);
157   } else {
158     LOG(ERROR) << StringPrintf("%s: fail to open, error = %d", __func__, errno);
159     nfa_nv_ci_write(NFA_NV_CO_FAIL);
160   }
161 }
162 
163 /*******************************************************************************
164 **
165 ** Function         delete_stack_non_volatile_store
166 **
167 ** Description      Delete all the content of the stack's storage location.
168 **
169 ** Parameters       forceDelete: unconditionally delete the storage.
170 **
171 ** Returns          none
172 **
173 *******************************************************************************/
delete_stack_non_volatile_store(bool forceDelete)174 void delete_stack_non_volatile_store(bool forceDelete) {
175   static bool firstTime = true;
176 
177   if ((firstTime == false) && (forceDelete == false)) return;
178   firstTime = false;
179 
180   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s", __func__);
181 
182   if (remove(getFilenameForBlock(DH_NV_BLOCK).c_str())) {
183     LOG(ERROR) << StringPrintf(
184         "%s: fail to delete DH_NV_BLOCK file, errno = 0x%02X", __func__, errno);
185   }
186   if (remove(getFilenameForBlock(HC_F2_NV_BLOCK).c_str())) {
187     LOG(ERROR) << StringPrintf(
188         "%s: fail to delete HC_F2_NV_BLOCK file, errno = 0x%02X", __func__,
189         errno);
190   }
191   if (remove(getFilenameForBlock(HC_F3_NV_BLOCK).c_str())) {
192     LOG(ERROR) << StringPrintf(
193         "%s: fail to delete HC_F3_NV_BLOCK file, errno = 0x%02X", __func__,
194         errno);
195   }
196   if (remove(getFilenameForBlock(HC_F4_NV_BLOCK).c_str())) {
197     LOG(ERROR) << StringPrintf(
198         "%s: fail to delete HC_F4_NV_BLOCK file, errno = 0x%02X", __func__,
199         errno);
200   }
201   if (remove(getFilenameForBlock(HC_F5_NV_BLOCK).c_str())) {
202     LOG(ERROR) << StringPrintf(
203         "%s: fail to delete HC_F5_NV_BLOCK file, errno = 0x%02X", __func__,
204         errno);
205   }
206 }
207 
208 /*******************************************************************************
209 **
210 ** Function         verify_stack_non_volatile_store
211 **
212 ** Description      Verify the content of all non-volatile store.
213 **
214 ** Parameters       none
215 **
216 ** Returns          none
217 **
218 *******************************************************************************/
verify_stack_non_volatile_store()219 void verify_stack_non_volatile_store() {
220   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s", __func__);
221 
222   const std::vector<unsigned> verify_blocks = {DH_NV_BLOCK, HC_F2_NV_BLOCK,
223                                                HC_F3_NV_BLOCK, HC_F4_NV_BLOCK,
224                                                HC_F5_NV_BLOCK};
225 
226   size_t verified = 0;
227   for (auto block : verify_blocks) {
228     if (!crcChecksumVerifyIntegrity(getFilenameForBlock(block).c_str())) break;
229     ++verified;
230   }
231 
232   if (verified != verify_blocks.size()) delete_stack_non_volatile_store(true);
233 }
234