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