15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)/****************************************************************************** 25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * 35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * Copyright (C) 2011-2012 Broadcom Corporation 45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * 55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * Licensed under the Apache License, Version 2.0 (the "License"); 65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * you may not use this file except in compliance with the License. 75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * You may obtain a copy of the License at: 85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * 95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * http://www.apache.org/licenses/LICENSE-2.0 105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * 115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * Unless required by applicable law or agreed to in writing, software 125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * distributed under the License is distributed on an "AS IS" BASIS, 135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * See the License for the specific language governing permissions and 155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * limitations under the License. 165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * 175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ******************************************************************************/ 185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "OverrideLog.h" 195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <sys/types.h> 205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <sys/stat.h> 215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <fcntl.h> 225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <errno.h> 235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "buildcfg.h" 245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "nfa_nv_co.h" 255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "config.h" 265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "nfc_hal_target.h" 275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "nfc_hal_nv_co.h" 285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)extern char bcm_nfc_location[]; 295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)static const char* sNfaStorageBin = "/nfaStorage.bin"; 305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)/******************************************************************************* 325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)** 335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)** Function nfa_mem_co_alloc 345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)** 355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)** Description allocate a buffer from platform's memory pool 365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)** 375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)** Returns: 385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)** pointer to buffer if successful 395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)** NULL otherwise 40** 41*******************************************************************************/ 42extern void *nfa_mem_co_alloc(UINT32 num_bytes) 43{ 44 return malloc(num_bytes); 45} 46 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*******************************************************************************/ 58extern void nfa_mem_co_free(void *pBuffer) 59{ 60 free(pBuffer); 61} 62 63 64/******************************************************************************* 65** 66** Function nfa_nv_co_read 67** 68** Description This function is called by NFA to read in data from the 69** previously opened file. 70** 71** Parameters pBuffer - buffer to read the data into. 72** nbytes - number of bytes to read into the buffer. 73** 74** Returns void 75** 76** Note: Upon completion of the request, nfa_nv_ci_read() is 77** called with the buffer of data, along with the number 78** of bytes read into the buffer, and a status. The 79** call-in function should only be called when ALL requested 80** bytes have been read, the end of file has been detected, 81** or an error has occurred. 82** 83*******************************************************************************/ 84extern void nfa_nv_co_read(UINT8 *pBuffer, UINT16 nbytes, UINT8 block) 85{ 86 char filename[256], filename2[256]; 87 88 memset (filename, 0, sizeof(filename)); 89 memset (filename2, 0, sizeof(filename2)); 90 strcpy(filename2, bcm_nfc_location); 91 strncat(filename2, sNfaStorageBin, sizeof(filename2)-strlen(filename2)-1); 92 if (strlen(filename2) > 200) 93 { 94 ALOGE ("%s: filename too long", __FUNCTION__); 95 return; 96 } 97 sprintf (filename, "%s%u", filename2, block); 98 99 ALOGD ("%s: buffer len=%u; file=%s", __FUNCTION__, nbytes, filename); 100 int fileStream = open (filename, O_RDONLY); 101 if (fileStream >= 0) 102 { 103 unsigned short checksum = 0; 104 size_t actualReadCrc = read (fileStream, &checksum, sizeof(checksum)); 105 size_t actualReadData = read (fileStream, pBuffer, nbytes); 106 close (fileStream); 107 if (actualReadData > 0) 108 { 109 ALOGD ("%s: data size=%zu", __FUNCTION__, actualReadData); 110 nfa_nv_ci_read (actualReadData, NFA_NV_CO_OK, block); 111 } 112 else 113 { 114 ALOGE ("%s: fail to read", __FUNCTION__); 115 nfa_nv_ci_read (0, NFA_NV_CO_FAIL, block); 116 } 117 } 118 else 119 { 120 ALOGD ("%s: fail to open", __FUNCTION__); 121 nfa_nv_ci_read (0, NFA_NV_CO_FAIL, block); 122 } 123} 124 125/******************************************************************************* 126** 127** Function nfa_nv_co_write 128** 129** Description This function is called by io to send file data to the 130** phone. 131** 132** Parameters pBuffer - buffer to read the data from. 133** nbytes - number of bytes to write out to the file. 134** 135** Returns void 136** 137** Note: Upon completion of the request, nfa_nv_ci_write() is 138** called with the file descriptor and the status. The 139** call-in function should only be called when ALL requested 140** bytes have been written, or an error has been detected, 141** 142*******************************************************************************/ 143extern void nfa_nv_co_write(const UINT8 *pBuffer, UINT16 nbytes, UINT8 block) 144{ 145 char filename[256], filename2[256]; 146 147 memset (filename, 0, sizeof(filename)); 148 memset (filename2, 0, sizeof(filename2)); 149 strcpy(filename2, bcm_nfc_location); 150 strncat(filename2, sNfaStorageBin, sizeof(filename2)-strlen(filename2)-1); 151 if (strlen(filename2) > 200) 152 { 153 ALOGE ("%s: filename too long", __FUNCTION__); 154 return; 155 } 156 sprintf (filename, "%s%u", filename2, block); 157 ALOGD ("%s: bytes=%u; file=%s", __FUNCTION__, nbytes, filename); 158 159 int fileStream = 0; 160 161 fileStream = open (filename, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR); 162 if (fileStream >= 0) 163 { 164 unsigned short checksum = crcChecksumCompute (pBuffer, nbytes); 165 size_t actualWrittenCrc = write (fileStream, &checksum, sizeof(checksum)); 166 size_t actualWrittenData = write (fileStream, pBuffer, nbytes); 167 ALOGD ("%s: %zu bytes written", __FUNCTION__, actualWrittenData); 168 if ((actualWrittenData == nbytes) && (actualWrittenCrc == sizeof(checksum))) 169 { 170 nfa_nv_ci_write (NFA_NV_CO_OK); 171 } 172 else 173 { 174 ALOGE ("%s: fail to write", __FUNCTION__); 175 nfa_nv_ci_write (NFA_NV_CO_FAIL); 176 } 177 close (fileStream); 178 } 179 else 180 { 181 ALOGE ("%s: fail to open, error = %d", __FUNCTION__, errno); 182 nfa_nv_ci_write (NFA_NV_CO_FAIL); 183 } 184} 185 186/******************************************************************************* 187** 188** Function delete_stack_non_volatile_store 189** 190** Description Delete all the content of the stack's storage location. 191** 192** Parameters forceDelete: unconditionally delete the storage. 193** 194** Returns none 195** 196*******************************************************************************/ 197void delete_stack_non_volatile_store (BOOLEAN forceDelete) 198{ 199 static BOOLEAN firstTime = TRUE; 200 char filename[256], filename2[256]; 201 202 if ((firstTime == FALSE) && (forceDelete == FALSE)) 203 return; 204 firstTime = FALSE; 205 206 ALOGD ("%s", __FUNCTION__); 207 208 memset (filename, 0, sizeof(filename)); 209 memset (filename2, 0, sizeof(filename2)); 210 strcpy(filename2, bcm_nfc_location); 211 strncat(filename2, sNfaStorageBin, sizeof(filename2)-strlen(filename2)-1); 212 if (strlen(filename2) > 200) 213 { 214 ALOGE ("%s: filename too long", __FUNCTION__); 215 return; 216 } 217 sprintf (filename, "%s%u", filename2, DH_NV_BLOCK); 218 remove (filename); 219 sprintf (filename, "%s%u", filename2, HC_F3_NV_BLOCK); 220 remove (filename); 221 sprintf (filename, "%s%u", filename2, HC_F4_NV_BLOCK); 222 remove (filename); 223 sprintf (filename, "%s%u", filename2, HC_F2_NV_BLOCK); 224 remove (filename); 225 sprintf (filename, "%s%u", filename2, HC_F5_NV_BLOCK); 226 remove (filename); 227} 228 229/******************************************************************************* 230** 231** Function verify_stack_non_volatile_store 232** 233** Description Verify the content of all non-volatile store. 234** 235** Parameters none 236** 237** Returns none 238** 239*******************************************************************************/ 240void verify_stack_non_volatile_store () 241{ 242 ALOGD ("%s", __FUNCTION__); 243 char filename[256], filename2[256]; 244 BOOLEAN isValid = FALSE; 245 246 memset (filename, 0, sizeof(filename)); 247 memset (filename2, 0, sizeof(filename2)); 248 strcpy(filename2, bcm_nfc_location); 249 strncat(filename2, sNfaStorageBin, sizeof(filename2)-strlen(filename2)-1); 250 if (strlen(filename2) > 200) 251 { 252 ALOGE ("%s: filename too long", __FUNCTION__); 253 return; 254 } 255 256 sprintf (filename, "%s%u", filename2, DH_NV_BLOCK); 257 if (crcChecksumVerifyIntegrity (filename)) 258 { 259 sprintf (filename, "%s%u", filename2, HC_F3_NV_BLOCK); 260 if (crcChecksumVerifyIntegrity (filename)) 261 { 262 sprintf (filename, "%s%u", filename2, HC_F4_NV_BLOCK); 263 if (crcChecksumVerifyIntegrity (filename)) 264 { 265 sprintf (filename, "%s%u", filename2, HC_F2_NV_BLOCK); 266 if (crcChecksumVerifyIntegrity (filename)) 267 { 268 sprintf (filename, "%s%u", filename2, HC_F5_NV_BLOCK); 269 if (crcChecksumVerifyIntegrity (filename)) 270 isValid = TRUE; 271 } 272 } 273 } 274 } 275 276 if (isValid == FALSE) 277 delete_stack_non_volatile_store (TRUE); 278} 279 280