Home | History | Annotate | Download | only in adaptation
      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 <android-base/stringprintf.h>
     19 #include <base/logging.h>
     20 #include <fcntl.h>
     21 #include <vector>
     22 
     23 #include "CrcChecksum.h"
     24 #include "nfa_nv_ci.h"
     25 #include "nfc_hal_nv_co.h"
     26 
     27 using android::base::StringPrintf;
     28 
     29 extern std::string nfc_storage_path;
     30 extern bool nfc_debug_enabled;
     31 
     32 namespace {
     33 std::string getFilenameForBlock(const unsigned block) {
     34   std::string bin = "nfaStorage.bin";
     35   return StringPrintf("%s/%s%u", nfc_storage_path.c_str(), bin.c_str(), block);
     36 }
     37 }  // namespace
     38 
     39 /*******************************************************************************
     40 **
     41 ** Function         nfa_mem_co_alloc
     42 **
     43 ** Description      allocate a buffer from platform's memory pool
     44 **
     45 ** Returns:
     46 **                  pointer to buffer if successful
     47 **                  NULL otherwise
     48 **
     49 *******************************************************************************/
     50 extern void* nfa_mem_co_alloc(uint32_t num_bytes) { return malloc(num_bytes); }
     51 
     52 /*******************************************************************************
     53 **
     54 ** Function         nfa_mem_co_free
     55 **
     56 ** Description      free buffer previously allocated using nfa_mem_co_alloc
     57 **
     58 ** Returns:
     59 **                  Nothing
     60 **
     61 *******************************************************************************/
     62 extern void nfa_mem_co_free(void* pBuffer) { free(pBuffer); }
     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
     80 **                        requested bytes have been read, the end of file has
     81 **                        been detected, or an error has occurred.
     82 **
     83 *******************************************************************************/
     84 extern void nfa_nv_co_read(uint8_t* pBuffer, uint16_t nbytes, uint8_t block) {
     85   std::string filename = getFilenameForBlock(block);
     86 
     87   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
     88       "%s: buffer len=%u; file=%s", __func__, nbytes, filename.c_str());
     89   int fileStream = open(filename.c_str(), O_RDONLY);
     90   if (fileStream >= 0) {
     91     unsigned short checksum = 0;
     92     read(fileStream, &checksum, sizeof(checksum));
     93     size_t actualReadData = read(fileStream, pBuffer, nbytes);
     94     close(fileStream);
     95     if (actualReadData > 0) {
     96       DLOG_IF(INFO, nfc_debug_enabled)
     97           << StringPrintf("%s: data size=%zu", __func__, actualReadData);
     98       nfa_nv_ci_read(actualReadData, NFA_NV_CO_OK, block);
     99     } else {
    100       LOG(ERROR) << StringPrintf("%s: fail to read", __func__);
    101       nfa_nv_ci_read(0, NFA_NV_CO_FAIL, block);
    102     }
    103   } else {
    104     DLOG_IF(INFO, nfc_debug_enabled)
    105         << StringPrintf("%s: fail to open", __func__);
    106     nfa_nv_ci_read(0, NFA_NV_CO_FAIL, block);
    107   }
    108 }
    109 
    110 /*******************************************************************************
    111 **
    112 ** Function         nfa_nv_co_write
    113 **
    114 ** Description      This function is called by io to send file data to the
    115 **                  phone.
    116 **
    117 ** Parameters       pBuffer   - buffer to read the data from.
    118 **                  nbytes  - number of bytes to write out to the file.
    119 **
    120 ** Returns          void
    121 **
    122 **                  Note: Upon completion of the request, nfa_nv_ci_write() is
    123 **                        called with the file descriptor and the status.  The
    124 **                        call-in function should only be called when ALL
    125 **                        requested bytes have been written, or an error has
    126 **                        been detected,
    127 **
    128 *******************************************************************************/
    129 extern void nfa_nv_co_write(const uint8_t* pBuffer, uint16_t nbytes,
    130                             uint8_t block) {
    131   std::string filename = getFilenameForBlock(block);
    132 
    133   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
    134       "%s: bytes=%u; file=%s", __func__, nbytes, filename.c_str());
    135 
    136   int fileStream =
    137       open(filename.c_str(), O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
    138   if (fileStream >= 0) {
    139     unsigned short checksum = crcChecksumCompute(pBuffer, nbytes);
    140     size_t actualWrittenCrc = write(fileStream, &checksum, sizeof(checksum));
    141     size_t actualWrittenData = write(fileStream, pBuffer, nbytes);
    142     DLOG_IF(INFO, nfc_debug_enabled)
    143         << StringPrintf("%s: %zu bytes written", __func__, actualWrittenData);
    144     if ((actualWrittenData == nbytes) &&
    145         (actualWrittenCrc == sizeof(checksum))) {
    146       nfa_nv_ci_write(NFA_NV_CO_OK);
    147     } else {
    148       LOG(ERROR) << StringPrintf("%s: fail to write", __func__);
    149       nfa_nv_ci_write(NFA_NV_CO_FAIL);
    150     }
    151     close(fileStream);
    152   } else {
    153     LOG(ERROR) << StringPrintf("%s: fail to open, error = %d", __func__, errno);
    154     nfa_nv_ci_write(NFA_NV_CO_FAIL);
    155   }
    156 }
    157 
    158 /*******************************************************************************
    159 **
    160 ** Function         delete_stack_non_volatile_store
    161 **
    162 ** Description      Delete all the content of the stack's storage location.
    163 **
    164 ** Parameters       forceDelete: unconditionally delete the storage.
    165 **
    166 ** Returns          none
    167 **
    168 *******************************************************************************/
    169 void delete_stack_non_volatile_store(bool forceDelete) {
    170   static bool firstTime = true;
    171 
    172   if ((firstTime == false) && (forceDelete == false)) return;
    173   firstTime = false;
    174 
    175   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s", __func__);
    176 
    177   remove(getFilenameForBlock(DH_NV_BLOCK).c_str());
    178   remove(getFilenameForBlock(HC_F2_NV_BLOCK).c_str());
    179   remove(getFilenameForBlock(HC_F3_NV_BLOCK).c_str());
    180   remove(getFilenameForBlock(HC_F4_NV_BLOCK).c_str());
    181   remove(getFilenameForBlock(HC_F5_NV_BLOCK).c_str());
    182 }
    183 
    184 /*******************************************************************************
    185 **
    186 ** Function         verify_stack_non_volatile_store
    187 **
    188 ** Description      Verify the content of all non-volatile store.
    189 **
    190 ** Parameters       none
    191 **
    192 ** Returns          none
    193 **
    194 *******************************************************************************/
    195 void verify_stack_non_volatile_store() {
    196   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s", __func__);
    197 
    198   const std::vector<unsigned> verify_blocks = {DH_NV_BLOCK, HC_F2_NV_BLOCK,
    199                                                HC_F3_NV_BLOCK, HC_F4_NV_BLOCK,
    200                                                HC_F5_NV_BLOCK};
    201 
    202   size_t verified = 0;
    203   for (auto block : verify_blocks) {
    204     if (!crcChecksumVerifyIntegrity(getFilenameForBlock(block).c_str())) break;
    205     ++verified;
    206   }
    207 
    208   if (verified != verify_blocks.size()) delete_stack_non_volatile_store(true);
    209 }
    210