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