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