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