/* * Copyright 2019-2024 NXP * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "phNxpNciHal_IoctlOperations.h" #include #include #include #include #include #include #include #include "EseAdaptation.h" #include "NfccTransport.h" #include "NfccTransportFactory.h" #include "phDnldNfc_Internal.h" #include "phNfcCommon.h" #include "phNxpNciHal_Adaptation.h" #include "phNxpNciHal_ULPDet.h" #include "phNxpNciHal_ext.h" #include "phNxpNciHal_extOperations.h" #include "phNxpNciHal_utils.h" using android::base::WriteStringToFile; using namespace ::std; using namespace ::android::base; #define TERMINAL_LEN 5 /* HAL_NFC_STATUS_REFUSED sent to restart NFC service */ #define HAL_NFC_STATUS_RESTART HAL_NFC_STATUS_REFUSED #define GET_RES_STATUS_CHECK(len, data) \ (((len) < NCI_HEADER_SIZE) || \ ((len) != ((data[NCI_PACKET_LEN_INDEX]) + NCI_HEADER_SIZE)) || \ (NFCSTATUS_SUCCESS != (data[NCI_GET_RES_STATUS_INDEX]))) typedef enum { UPDATE_DLMA_ID_TX_ENTRY, UPDATE_RF_CM_TX_UNDERSHOOT_CONFIG, UPDATE_MIFARE_NACK_TO_RATS_ENABLE, UPDATE_MIFARE_MUTE_TO_RATS_ENABLE, UPDATE_CHINA_TIANJIN_RF_ENABLED, UPDATE_CN_TRANSIT_CMA_BYPASSMODE_ENABLE, UPDATE_CN_TRANSIT_BLK_NUM_CHECK_ENABLE, UPDATE_ISO_DEP_MERGE_SAK, UPDATE_PHONEOFF_TECH_DISABLE, UPDATE_INITIAL_TX_PHASE, UPDATE_GUARD_TIMEOUT_TX2RX, UPDATE_LPDET_THRESHOLD, UPDATE_NFCLD_THRESHOLD, UPDATE_RF_PATTERN_CHK, UPDATE_UNKNOWN = 0xFF } tNFC_setDynamicRfConfigType; static const std::unordered_map tokenMap = { {"UPDATE_DLMA_ID_TX_ENTRY", UPDATE_DLMA_ID_TX_ENTRY}, {"UPDATE_RF_CM_TX_UNDERSHOOT_CONFIG", UPDATE_RF_CM_TX_UNDERSHOOT_CONFIG}, {"UPDATE_MIFARE_NACK_TO_RATS_ENABLE", UPDATE_MIFARE_NACK_TO_RATS_ENABLE}, {"UPDATE_MIFARE_MUTE_TO_RATS_ENABLE", UPDATE_MIFARE_MUTE_TO_RATS_ENABLE}, {"UPDATE_CHINA_TIANJIN_RF_ENABLED", UPDATE_CHINA_TIANJIN_RF_ENABLED}, {"UPDATE_CN_TRANSIT_CMA_BYPASSMODE_ENABLE", UPDATE_CN_TRANSIT_CMA_BYPASSMODE_ENABLE}, {"UPDATE_CN_TRANSIT_BLK_NUM_CHECK_ENABLE", UPDATE_CN_TRANSIT_BLK_NUM_CHECK_ENABLE}, {"UPDATE_ISO_DEP_MERGE_SAK", UPDATE_ISO_DEP_MERGE_SAK}, {"UPDATE_PHONEOFF_TECH_DISABLE", UPDATE_PHONEOFF_TECH_DISABLE}, {"UPDATE_INITIAL_TX_PHASE", UPDATE_INITIAL_TX_PHASE}, {"UPDATE_GUARD_TIMEOUT_TX2RX", UPDATE_GUARD_TIMEOUT_TX2RX}, {"UPDATE_LPDET_THRESHOLD", UPDATE_LPDET_THRESHOLD}, {"UPDATE_NFCLD_THRESHOLD", UPDATE_NFCLD_THRESHOLD}, {"UPDATE_RF_PATTERN_CHK", UPDATE_RF_PATTERN_CHK}}; static const std::unordered_map rfReg_A085_Map = { {UPDATE_MIFARE_NACK_TO_RATS_ENABLE, MIFARE_NACK_TO_RATS_ENABLE_BIT_POS}, {UPDATE_MIFARE_MUTE_TO_RATS_ENABLE, MIFARE_MUTE_TO_RATS_ENABLE_BIT_POS}, {UPDATE_CHINA_TIANJIN_RF_ENABLED, CHINA_TIANJIN_RF_ENABLE_BIT_POS}, {UPDATE_CN_TRANSIT_CMA_BYPASSMODE_ENABLE, CN_TRANSIT_CMA_BYPASSMODE_ENABLE_BIT_POS}, {UPDATE_CN_TRANSIT_BLK_NUM_CHECK_ENABLE, CN_TRANSIT_BLK_NUM_CHECK_ENABLE_BIT_POS}}; /**************************************************************** * Global Variables Declaration ***************************************************************/ /* External global variable to get FW version from NCI response*/ extern uint32_t wFwVerRsp; /* External global variable to get FW version from FW file*/ extern uint16_t wFwVer; /* NCI HAL Control structure */ extern phNxpNciHal_Control_t nxpncihal_ctrl; extern phNxpNci_getCfg_info_t* mGetCfg_info; extern EseAdaptation* gpEseAdapt; extern nfc_stack_callback_t* p_nfc_stack_cback_backup; #ifndef FW_DWNLD_FLAG extern uint8_t fw_dwnld_flag; #endif /* TML Context */ extern phTmlNfc_Context_t* gpphTmlNfc_Context; extern bool nfc_debug_enabled; extern NFCSTATUS phNxpLog_EnableDisableLogLevel(uint8_t enable); extern phNxpNciClock_t phNxpNciClock; extern NfcHalThreadMutex sHalFnLock; /******************************************************************************* ** ** Function: property_get_intf() ** ** Description: Gets property value for the input property name ** ** Parameters propName: Name of the property whichs value need to get ** valueStr: output value of the property. ** defaultStr: default value of the property if value is not ** there this will be set to output value. ** ** Returns: actual length of the property value ** ********************************************************************************/ int property_get_intf(const char* propName, char* valueStr, const char* defaultStr) { string propValue; string propValueDefault = defaultStr; int len = 0; propValue = phNxpNciHal_getSystemProperty(propName); if (propValue.length() > 0) { NXPLOG_NCIHAL_D("property_get_intf , key[%s], propValue[%s], length[%zu]", propName, propValue.c_str(), propValue.length()); len = propValue.length(); strlcpy(valueStr, propValue.c_str(), PROPERTY_VALUE_MAX); } else { if (propValueDefault.length() > 0) { len = propValueDefault.length(); strlcpy(valueStr, propValueDefault.c_str(), PROPERTY_VALUE_MAX); } } return len; } /******************************************************************************* ** ** Function: property_set_intf() ** ** Description: Sets property value for the input property name ** ** Parameters propName: Name of the property whichs value need to set ** valueStr: value of the property. ** ** Returns: returns 0 on success, < 0 on failure ** ********************************************************************************/ int property_set_intf(const char* propName, const char* valueStr) { NXPLOG_NCIHAL_D("property_set_intf, key[%s], value[%s]", propName, valueStr); if (phNxpNciHal_setSystemProperty(propName, valueStr)) return NFCSTATUS_SUCCESS; else return NFCSTATUS_FAILED; } extern size_t readConfigFile(const char* fileName, uint8_t** p_data); extern NFCSTATUS phNxpNciHal_ext_send_sram_config_to_flash(); static bool phNxpNciHal_checkUpdateRfTransitConfig(const char* config); static string phNxpNciHal_parseBytesString(string in); static bool phNxpNciHal_parseValueFromString(string& in); static bool phNxpNciHal_CheckKeyNeeded(string key); static string phNxpNciHal_UpdatePwrStateConfigs(string& config); static bool phNxpNciHal_IsAutonmousModeSet(string config); static string phNxpNciHal_extractConfig(string& config); static void phNxpNciHal_getFilteredConfig(string& config); typedef std::map systemProperty; systemProperty gsystemProperty = { {"nfc.nxp_log_level_global", ""}, {"nfc.nxp_log_level_extns", ""}, {"nfc.nxp_log_level_hal", ""}, {"nfc.nxp_log_level_nci", ""}, {"nfc.nxp_log_level_dnld", ""}, {"nfc.nxp_log_level_tml", ""}, {"nfc.fw.dfl", ""}, {"nfc.fw.downloadmode_force", ""}, {"nfc.debug_enabled", ""}, {"nfc.product.support.ese", ""}, {"nfc.product.support.uicc", ""}, {"nfc.product.support.uicc2", ""}, {"nfc.fw.rfreg_ver", ""}, {"nfc.fw.rfreg_display_ver", ""}, {"nfc.fw.dfl_areacode", ""}, {"nfc.cover.cover_id", ""}, {"nfc.cover.state", ""}, {"ro.factory.factory_binary", ""}, }; const char default_nxp_config_path[] = "/vendor/etc/libnfc-nxp.conf"; std::set gNciConfigs = {"NXP_SE_COLD_TEMP_ERROR_DELAY", "NXP_SWP_RD_TAG_OP_TIMEOUT", "NXP_DUAL_UICC_ENABLE", "DEFAULT_AID_ROUTE", "DEFAULT_MIFARE_CLT_ROUTE", "DEFAULT_FELICA_CLT_ROUTE", "DEFAULT_AID_PWR_STATE", "DEFAULT_DESFIRE_PWR_STATE", "DEFAULT_MIFARE_CLT_PWR_STATE", "DEFAULT_FELICA_CLT_PWR_STATE", "HOST_LISTEN_TECH_MASK", "FORWARD_FUNCTIONALITY_ENABLE", "DEFAULT_GSMA_PWR_STATE", "NXP_DEFAULT_UICC2_SELECT", "NXP_SMB_TRANSCEIVE_TIMEOUT", "NXP_SMB_ERROR_RETRY", "NXP_CHECK_DEFAULT_PROTO_SE_ID", "NXPLOG_NCIHAL_LOGLEVEL", "NXPLOG_EXTNS_LOGLEVEL", "NXPLOG_TML_LOGLEVEL", "NXPLOG_FWDNLD_LOGLEVEL", "NXPLOG_NCIX_LOGLEVEL", "NXPLOG_NCIR_LOGLEVEL", "NXP_NFC_SE_TERMINAL_NUM", "NXP_POLL_FOR_EFD_TIMEDELAY", "NXP_NFCC_MERGE_SAK_ENABLE", "NXP_STAG_TIMEOUT_CFG", "DEFAULT_T4TNFCEE_AID_POWER_STATE", "RF_STORAGE", "FW_STORAGE", "NXP_CORE_CONF", "NXP_RF_FILE_VERSION_INFO", "NXP_AUTONOMOUS_ENABLE", "NXP_PROP_RESET_EMVCO_CMD", "NFA_CONFIG_FORMAT", "NXP_T4T_NFCEE_ENABLE", "NXP_DISCONNECT_TAG_IN_SCRN_OFF", "NXP_CE_PRIORITY_ENABLED", "NXP_RDR_REQ_GUARD_TIME", "NXP_ENABLE_DISABLE_LOGS", "NXP_RDR_DISABLE_ENABLE_LPCD", "NXP_SUPPORT_NON_STD_CARD", "NXP_GET_HW_INFO_LOG", "NXP_WLC_MODE", "NXP_T4T_NDEF_NFCEE_AID", "NXP_NON_STD_CARD_TIMEDIFF", "NXP_SRD_TIMEOUT", "NXP_UICC_ETSI_SUPPORT", "NXP_MINIMAL_FW_VERSION", "NXP_RESTART_RF_FOR_NFCEE_RECOVERY", "NXP_NFCC_RECOVERY_SUPPORT", "NXP_AGC_DEBUG_ENABLE", "NXP_EXTENDED_FIELD_DETECT_MODE", "NXP_SE_SMB_TERMINAL_TYPE"}; /**************************************************************** * Local Functions ***************************************************************/ /****************************************************************************** ** Function phNxpNciHal_ioctlIf ** ** Description This function shall be called from HAL when libnfc-nci ** calls phNxpNciHal_ioctl() to perform any IOCTL operation ** ** Returns return 0 on success and -1 on fail, ******************************************************************************/ int phNxpNciHal_ioctlIf(long arg, void* p_data) { NXPLOG_NCIHAL_D("%s : enter - arg = %ld", __func__, arg); ese_nxp_IoctlInOutData_t* pInpOutData = (ese_nxp_IoctlInOutData_t*)p_data; int ret = -1; switch (arg) { case HAL_ESE_IOCTL_NFC_JCOP_DWNLD: if (pInpOutData == NULL) { NXPLOG_NCIHAL_E("%s : received invalid param", __func__); break; } if (gpEseAdapt == NULL) { gpEseAdapt = &EseAdaptation::GetInstance(); if (gpEseAdapt == NULL) { NXPLOG_NCIHAL_E("%s :invalid gpEseAdapt param", __func__); break; } gpEseAdapt->Initialize(); } NXPLOG_NCIHAL_D("HAL_ESE_IOCTL_NFC_JCOP_DWNLD Enter value is %d: \n", pInpOutData->inp.data.nxpCmd.p_cmd[0]); gpEseAdapt->HalIoctl(HAL_ESE_IOCTL_NFC_JCOP_DWNLD, pInpOutData); ret = 0; break; default: NXPLOG_NCIHAL_E("%s : Wrong arg = %ld", __func__, arg); break; } NXPLOG_NCIHAL_D("%s : exit - ret = %d", __func__, ret); return ret; } /******************************************************************************* ** ** Function phNxpNciHal_getSystemProperty ** ** Description It shall be used to get property value of the given Key ** ** Parameters string key ** ** Returns If Key is found, returns the respective property values ** else returns the null/empty string *******************************************************************************/ string phNxpNciHal_getSystemProperty(string key) { string propValue; std::map::iterator prop; if (key == "libnfc-nxp.conf") { return phNxpNciHal_getNxpConfigIf(); } else { prop = gsystemProperty.find(key); if (prop != gsystemProperty.end()) { propValue = prop->second; } else { /* else Pass a null string */ } } return propValue; } /******************************************************************************* ** ** Function phNxpNciHal_setSystemProperty ** ** Description It shall be used to save/change value to system property ** based on provided key. ** ** Parameters string key, string value ** ** Returns true if success, false if fail *******************************************************************************/ bool phNxpNciHal_setSystemProperty(string key, string value) { bool stat = true; if (strcmp(key.c_str(), "nfc.debug_enabled") != 0) NXPLOG_NCIHAL_D("%s : Enter Key = %s, value = %s", __func__, key.c_str(), value.c_str()); unsigned tmp = 0; if (strcmp(key.c_str(), "nfc.debug_enabled") == 0) { if (ParseUint(value.c_str(), &tmp)) { if (phNxpLog_EnableDisableLogLevel((uint8_t)tmp) != NFCSTATUS_SUCCESS) { stat = false; } } else { NXPLOG_NCIHAL_W( "%s : Failed to parse the string to uint. " "nfc.debug_enabled string : %s", __func__, value.c_str()); } } else if (strcmp(key.c_str(), "nfc.cover.state") == 0) { unsigned cid, cstate; string strtmp; if (ParseUint(value.c_str(), &cstate)) { strtmp = phNxpNciHal_getSystemProperty("nfc.cover.cover_id"); if (ParseUint(strtmp.c_str(), &cid)) { if (fpPropConfCover != NULL) { stat = (fpPropConfCover(cstate, cid) == NFCSTATUS_SUCCESS) ? true : false; } } else { NXPLOG_NCIHAL_W( "%s : Failed to parse the string to uint. " "nfc.cover.cover_id string : %s", __func__, value.c_str()); } } else { NXPLOG_NCIHAL_W( "%s : Failed to parse the string to uint. " "nfc.cover.state string : %s", __func__, value.c_str()); } } else if (strcmp(key.c_str(), "nfc.cmd_timeout") == 0) { NXPLOG_NCIHAL_E("%s : nci_timeout, sem post", __func__); sem_post(&(nxpncihal_ctrl.syncSpiNfc)); } gsystemProperty[key] = std::move(value); return stat; } /******************************************************************************* ** ** Function phNxpNciHal_getNxpConfig ** ** Description It shall be used to read config values from the *libnfc-nxp.conf ** ** Parameters nxpConfigs config ** ** Returns void *******************************************************************************/ string phNxpNciHal_getNxpConfigIf() { std::string config; uint8_t* p_config = nullptr; size_t config_size = readConfigFile(default_nxp_config_path, &p_config); if (config_size) { config.assign((char*)p_config, config_size); free(p_config); phNxpNciHal_getFilteredConfig(config); } return config; } /******************************************************************************* ** ** Function phNxpNciHal_getFilteredConfig ** ** Description It reads only configs needed for libnfc from * libnfc-nxp.conf ** ** Parameters string config ** ** Returns void *******************************************************************************/ static void phNxpNciHal_getFilteredConfig(string& config) { config = phNxpNciHal_extractConfig(config); if (phNxpNciHal_IsAutonmousModeSet(config)) { config = phNxpNciHal_UpdatePwrStateConfigs(config); } } /******************************************************************************* ** ** Function phNxpNciHal_extractConfig ** ** Description It parses complete config file and extracts only * enabled options ignores comments etc. ** ** Parameters string config ** ** Returns Resultant string *******************************************************************************/ static string phNxpNciHal_extractConfig(string& config) { stringstream ss(config); string line; string result; bool apduGate = false; while (getline(ss, line)) { line = Trim(line); if (line.empty()) continue; if (line.at(0) == '#') continue; if (line.at(0) == 0) continue; auto search = line.find('='); if (search == string::npos) continue; string key(Trim(line.substr(0, search))); if (!phNxpNciHal_CheckKeyNeeded(key)) continue; if (key == "NXP_NFC_SE_TERMINAL_NUM" && !apduGate) { line = "NXP_SE_APDU_GATE_SUPPORT=0x01\n"; result += line; apduGate = true; continue; } string value_string(Trim(line.substr(search + 1, string::npos))); if (value_string[0] == '{' && value_string[value_string.length() - 1] != '}') { string line_append; do { getline(ss, line_append); if (line_append.empty()) break; if (line_append.at(0) == '#') break; if (line_append.at(0) == 0) break; line_append = Trim(line_append); value_string.append(line_append); } while (line_append[line_append.length() - 1] != '}'); } if (!phNxpNciHal_parseValueFromString(value_string)) continue; line = key + "=" + value_string + "\n"; result += line; if (key == "NXP_GET_HW_INFO_LOG" && (value_string == "1" || value_string == "0x01")) { if (!apduGate) { line = "NXP_SE_APDU_GATE_SUPPORT=0x01\n"; result += line; apduGate = true; } } } return result; } /******************************************************************************* ** ** Function phNxpNciHal_IsAutonmousModeSet ** ** Description It check whether autonomous mode is enabled * in config file ** ** Parameters string config ** ** Returns boolean(TRUE/FALSE) *******************************************************************************/ static bool phNxpNciHal_IsAutonmousModeSet(string config) { stringstream ss(config); string line; unsigned tmp = 0; while (getline(ss, line)) { auto search = line.find('='); if (search == string::npos) continue; string key(Trim(line.substr(0, search))); if (key == "NXP_AUTONOMOUS_ENABLE") { string value(Trim(line.substr(search + 1, string::npos))); if (ParseUint(value.c_str(), &tmp)) { if (tmp == 1) { return true; } else { NXPLOG_NCIHAL_D("Autonomous flag disabled"); return false; } } } else { continue; } } NXPLOG_NCIHAL_D("Autonomous flag disabled"); return false; } /******************************************************************************* ** ** Function phNxpNciHal_UpdatePwrStateConfigs ** ** Description Updates default pwr state accordingly if autonomous mode * is enabled ** ** Parameters string config ** ** Returns Resultant string *******************************************************************************/ static string phNxpNciHal_UpdatePwrStateConfigs(string& config) { stringstream ss(config); string line; string result; unsigned tmp = 0; while (getline(ss, line)) { auto search = line.find('='); if (search == string::npos) continue; string key(Trim(line.substr(0, search))); if ((key == "DEFAULT_AID_PWR_STATE" || key == "DEFAULT_DESFIRE_PWR_STATE" || key == "DEFAULT_MIFARE_CLT_PWR_STATE" || key == "DEFAULT_FELICA_CLT_PWR_STATE")) { string value(Trim(line.substr(search + 1, string::npos))); if (ParseUint(value.c_str(), &tmp)) { tmp = phNxpNciHal_updateAutonomousPwrState(tmp); value = to_string(tmp); line = key + "=" + value + "\n"; result += line; } } else { result += (line + "\n"); continue; } } return result; } /******************************************************************************* ** ** Function phNxpNciHal_CheckKeyNeeded ** ** Description Check if the config needed for libnfc as per gNciConfigs * list ** ** Parameters string config ** ** Returns bool(true/false) *******************************************************************************/ static bool phNxpNciHal_CheckKeyNeeded(string key) { return ((gNciConfigs.find(key) != gNciConfigs.end()) ? true : false); } /******************************************************************************* ** ** Function phNxpNciHal_parseValueFromString ** ** Description Parse value determine data type of config option ** ** Parameters string config ** ** Returns bool(true/false) *******************************************************************************/ static bool phNxpNciHal_parseValueFromString(string& in) { unsigned tmp = 0; bool stat = false; if (in.length() >= 1) { switch (in[0]) { case '"': if (in[in.length() - 1] == '"' && in.length() > 2) stat = true; break; case '{': if (in[in.length() - 1] == '}' && in.length() >= 3) { in = phNxpNciHal_parseBytesString(in); stat = true; } break; default: if (ParseUint(in.c_str(), &tmp)) stat = true; break; } } else { NXPLOG_NCIHAL_E("%s : Invalid config string ", __func__); } return stat; } /******************************************************************************* ** ** Function phNxpNciHal_parseBytesString ** ** Description Parse bytes from string ** ** Parameters string config ** ** Returns Resultant string *******************************************************************************/ static string phNxpNciHal_parseBytesString(string in) { size_t pos; in.erase(remove(in.begin(), in.end(), ' '), in.end()); pos = in.find(","); while (pos != string::npos) { in = in.replace(pos, 1, ":"); pos = in.find(",", pos); } return in; } /******************************************************************************* ** ** Function phNxpNciHal_resetEse ** ** Description It shall be used to reset eSE by proprietary command. ** ** Parameters ** ** Returns status of eSE reset response *******************************************************************************/ NFCSTATUS phNxpNciHal_resetEse(uint64_t resetType) { NFCSTATUS status = NFCSTATUS_FAILED; { NfcHalAutoThreadMutex a(sHalFnLock); if (nxpncihal_ctrl.halStatus == HAL_STATUS_CLOSE) { if (NFCSTATUS_SUCCESS != phNxpNciHal_MinOpen()) { return NFCSTATUS_FAILED; } } } CONCURRENCY_LOCK(); status = gpTransportObj->EseReset(gpphTmlNfc_Context->pDevHandle, (EseResetType)resetType); CONCURRENCY_UNLOCK(); if (status != NFCSTATUS_SUCCESS) { NXPLOG_NCIHAL_E("EsePowerCycle failed"); } if (nxpncihal_ctrl.halStatus == HAL_STATUS_MIN_OPEN) { phNxpNciHal_close(false); } return status; } /******************************************************************************* ** ** Function: phNxpNciHal_GetNfcGpiosStatus() ** ** Description: Sets the gpios status flag byte ** ** Parameters gpiostatus: flag byte ** ** Returns: returns 0 on success, < 0 on failure ** ********************************************************************************/ NFCSTATUS phNxpNciHal_GetNfcGpiosStatus(uint32_t* gpiosstatus) { NFCSTATUS status = NFCSTATUS_FAILED; status = gpTransportObj->NfcGetGpioStatus(gpphTmlNfc_Context->pDevHandle, gpiosstatus); return status; } /****************************************************************************** * Function phNxpNciHal_setNxpTransitConfig * * Description This function overwrite libnfc-nxpTransit.conf file * with transitConfValue. * * Returns bool. * ******************************************************************************/ bool phNxpNciHal_setNxpTransitConfig(char* transitConfValue) { bool status = true; NXPLOG_NCIHAL_D("%s : Enter", __func__); std::string transitConfFileName = "/data/vendor/nfc/libnfc-nxpTransit.conf"; long transitConfValueLen = strlen(transitConfValue) + 1; if (transitConfValueLen > 1) { if (strncmp(transitConfValue, "UPDATE_", 7) == 0) { if (IS_CHIP_TYPE_GE(sn220u) && phNxpNciHal_checkUpdateRfTransitConfig(transitConfValue)) { NXPLOG_NCIHAL_D("%s :RfTransit values updated", __func__); } else { NXPLOG_NCIHAL_E("Failed to update RfTransit values"); status = false; } } else { if (!WriteStringToFile(transitConfValue, transitConfFileName)) { NXPLOG_NCIHAL_E("WriteStringToFile: Failed"); status = false; } } } else { if (!WriteStringToFile("", transitConfFileName)) { NXPLOG_NCIHAL_E("WriteStringToFile: Failed"); status = false; } if (remove(transitConfFileName.c_str())) { NXPLOG_NCIHAL_E("Unable to remove file"); status = false; } } NXPLOG_NCIHAL_D("%s : Exit", __func__); return status; } /****************************************************************************** ** Function phNxpNciHal_Abort ** ** Description This function shall be used to trigger the abort in libnfc ** ** Parameters None ** ** Returns bool. ** *******************************************************************************/ bool phNxpNciHal_Abort() { bool ret = true; NXPLOG_NCIHAL_D("phNxpNciHal_Abort aborting. \n"); /* When JCOP download is triggered phNxpNciHal_open is blocked, in this case only we need to abort the libnfc , this can be done only by check the p_nfc_stack_cback_backup pointer which is assigned before the JCOP download.*/ if (p_nfc_stack_cback_backup != NULL) { (*p_nfc_stack_cback_backup)(HAL_NFC_OPEN_CPLT_EVT, HAL_NFC_STATUS_RESTART); } else { ret = false; NXPLOG_NCIHAL_D("phNxpNciHal_Abort not triggered\n"); } return ret; } /******************************************************************************* ** ** Function: phNxpNciHal_CheckFwRegFlashRequired() ** ** Description: Updates FW and Reg configurations if required ** ** Returns: status ** ********************************************************************************/ int phNxpNciHal_CheckFwRegFlashRequired(uint8_t* fw_update_req, uint8_t* rf_update_req, uint8_t skipEEPROMRead) { NXPLOG_NCIHAL_D("phNxpNciHal_CheckFwRegFlashRequired() : enter"); int status = NFCSTATUS_OK; long option; if (fpRegRfFwDndl != NULL) { status = fpRegRfFwDndl(fw_update_req, rf_update_req, skipEEPROMRead); } else { status = phDnldNfc_InitImgInfo(); NXPLOG_NCIHAL_D("FW version from the binary(.so/bin) = 0x%x", wFwVer); NXPLOG_NCIHAL_D("FW version found on the device = 0x%x", wFwVerRsp); if (!GetNxpNumValue(NAME_NXP_FLASH_CONFIG, &option, sizeof(unsigned long))) { NXPLOG_NCIHAL_D("Flash option not found; giving default value"); option = 1; } switch (option) { case FLASH_UPPER_VERSION: wFwUpdateReq = (utf8_t)wFwVer > (utf8_t)wFwVerRsp ? true : false; break; case FLASH_DIFFERENT_VERSION: wFwUpdateReq = ((wFwVerRsp & 0x0000FFFF) != wFwVer) ? true : false; break; case FLASH_ALWAYS: wFwUpdateReq = true; break; default: NXPLOG_NCIHAL_D("Invalid flash option selected"); status = NFCSTATUS_INVALID_PARAMETER; break; } } *fw_update_req = wFwUpdateReq; if (false == wFwUpdateReq) { NXPLOG_NCIHAL_D("FW update not required"); phDnldNfc_ReSetHwDevHandle(); } else { property_set("nfc.fw.downloadmode_force", "1"); } NXPLOG_NCIHAL_D( "phNxpNciHal_CheckFwRegFlashRequired() : exit - status = %x " "wFwUpdateReq=%u, wRfUpdateReq=%u", status, *fw_update_req, *rf_update_req); return status; } /****************************************************************************** * Function phNxpNciHal_txNfccClockSetCmd * * Description This function is called after successful download * to apply the clock setting provided in config file * * Returns void. * ******************************************************************************/ void phNxpNciHal_txNfccClockSetCmd(void) { NFCSTATUS status = NFCSTATUS_FAILED; uint8_t set_clock_cmd[] = {0x20, 0x02, 0x05, 0x01, 0xA0, 0x03, 0x01, 0x08}; uint8_t setClkCmdLen = sizeof(set_clock_cmd); unsigned long clockSource = 0; unsigned long frequency = 0; uint32_t pllSetRetryCount = 3, dpllSetRetryCount = 3, setClockCmdWriteRetryCnt = 0; uint8_t* pCmd4PllSetting = NULL; uint8_t* pCmd4DpllSetting = NULL; uint32_t pllCmdLen = 0, dpllCmdLen = 0; int srcCfgFound = 0, freqCfgFound = 0; srcCfgFound = (GetNxpNumValue(NAME_NXP_SYS_CLK_SRC_SEL, &clockSource, sizeof(clockSource)) > 0); freqCfgFound = (GetNxpNumValue(NAME_NXP_SYS_CLK_FREQ_SEL, &frequency, sizeof(frequency)) > 0); NXPLOG_NCIHAL_D("%s : clock source = %lu, frequency = %lu", __FUNCTION__, clockSource, frequency); if (srcCfgFound && freqCfgFound && (clockSource == CLK_SRC_PLL)) { phNxpNciClock.isClockSet = TRUE; switch (frequency) { case CLK_FREQ_13MHZ: { NXPLOG_NCIHAL_D("PLL setting for CLK_FREQ_13MHZ"); pCmd4PllSetting = (uint8_t*)PN557_SET_CONFIG_CMD_PLL_13MHZ; pllCmdLen = sizeof(PN557_SET_CONFIG_CMD_PLL_13MHZ); pCmd4DpllSetting = (uint8_t*)PN557_SET_CONFIG_CMD_DPLL_13MHZ; dpllCmdLen = sizeof(PN557_SET_CONFIG_CMD_DPLL_13MHZ); break; } case CLK_FREQ_19_2MHZ: { NXPLOG_NCIHAL_D("PLL setting for CLK_FREQ_19_2MHZ"); pCmd4PllSetting = (uint8_t*)PN557_SET_CONFIG_CMD_PLL_19_2MHZ; pllCmdLen = sizeof(PN557_SET_CONFIG_CMD_PLL_19_2MHZ); pCmd4DpllSetting = (uint8_t*)PN557_SET_CONFIG_CMD_DPLL_19_2MHZ; dpllCmdLen = sizeof(PN557_SET_CONFIG_CMD_DPLL_19_2MHZ); break; } case CLK_FREQ_24MHZ: { NXPLOG_NCIHAL_D("PLL setting for CLK_FREQ_24MHZ"); pCmd4PllSetting = (uint8_t*)PN557_SET_CONFIG_CMD_PLL_24MHZ; pllCmdLen = sizeof(PN557_SET_CONFIG_CMD_PLL_24MHZ); pCmd4DpllSetting = (uint8_t*)PN557_SET_CONFIG_CMD_DPLL_24MHZ; dpllCmdLen = sizeof(PN557_SET_CONFIG_CMD_DPLL_24MHZ); break; } case CLK_FREQ_26MHZ: { NXPLOG_NCIHAL_D("PLL setting for CLK_FREQ_26MHZ"); pCmd4PllSetting = (uint8_t*)PN557_SET_CONFIG_CMD_PLL_26MHZ; pllCmdLen = sizeof(PN557_SET_CONFIG_CMD_PLL_26MHZ); pCmd4DpllSetting = (uint8_t*)PN557_SET_CONFIG_CMD_DPLL_26MHZ; dpllCmdLen = sizeof(PN557_SET_CONFIG_CMD_DPLL_26MHZ); break; } case CLK_FREQ_32MHZ: { NXPLOG_NCIHAL_D("PLL setting for CLK_FREQ_32MHZ"); pCmd4PllSetting = (uint8_t*)PN557_SET_CONFIG_CMD_PLL_32MHZ; pllCmdLen = sizeof(PN557_SET_CONFIG_CMD_PLL_32MHZ); pCmd4DpllSetting = (uint8_t*)PN557_SET_CONFIG_CMD_DPLL_32MHZ; dpllCmdLen = sizeof(PN557_SET_CONFIG_CMD_DPLL_32MHZ); break; } case CLK_FREQ_38_4MHZ: { NXPLOG_NCIHAL_D("PLL setting for CLK_FREQ_38_4MHZ"); pCmd4PllSetting = (uint8_t*)PN557_SET_CONFIG_CMD_PLL_38_4MHZ; pllCmdLen = sizeof(PN557_SET_CONFIG_CMD_PLL_38_4MHZ); pCmd4DpllSetting = (uint8_t*)PN557_SET_CONFIG_CMD_DPLL_38_4MHZ; dpllCmdLen = sizeof(PN557_SET_CONFIG_CMD_DPLL_38_4MHZ); break; } case CLK_FREQ_48MHZ: { NXPLOG_NCIHAL_D("PLL setting for CLK_FREQ_48MHZ"); pCmd4PllSetting = (uint8_t*)PN557_SET_CONFIG_CMD_PLL_48MHZ; pllCmdLen = sizeof(PN557_SET_CONFIG_CMD_PLL_48MHZ); pCmd4DpllSetting = (uint8_t*)PN557_SET_CONFIG_CMD_DPLL_48MHZ; dpllCmdLen = sizeof(PN557_SET_CONFIG_CMD_DPLL_48MHZ); break; } default: phNxpNciClock.isClockSet = FALSE; NXPLOG_NCIHAL_E("ERROR: Invalid clock frequency!!"); return; } } switch (clockSource) { case CLK_SRC_PLL: { set_clock_cmd[setClkCmdLen - 1] = 0x00; while (status != NFCSTATUS_SUCCESS && setClockCmdWriteRetryCnt++ < MAX_RETRY_COUNT) status = phNxpNciHal_send_ext_cmd(setClkCmdLen, set_clock_cmd); status = NFCSTATUS_FAILED; while (status != NFCSTATUS_SUCCESS && pllSetRetryCount-- > 0) status = phNxpNciHal_send_ext_cmd(pllCmdLen, pCmd4PllSetting); status = NFCSTATUS_FAILED; while (status != NFCSTATUS_SUCCESS && dpllSetRetryCount-- > 0) status = phNxpNciHal_send_ext_cmd(dpllCmdLen, pCmd4DpllSetting); break; } case CLK_SRC_XTAL: { status = phNxpNciHal_send_ext_cmd(setClkCmdLen, set_clock_cmd); if (status != NFCSTATUS_SUCCESS) { NXPLOG_NCIHAL_E("XTAL clock setting failed !!"); } break; } default: NXPLOG_NCIHAL_E("Wrong clock source. Don't apply any modification"); return; } phNxpNciClock.isClockSet = FALSE; if (status == NFCSTATUS_SUCCESS && phNxpNciClock.p_rx_data[3] == NFCSTATUS_SUCCESS) { NXPLOG_NCIHAL_D("PLL and DPLL settings applied successfully"); } return; } /******************************************************************************* ** ** Function phNxpNciHal_updateRfSetConfig ** ** Description Update the set RF settings. ** ** Parameters setConfCmd - Update the set config buffer based on getConfig ** getResData - Response data. ** Returns True/False *******************************************************************************/ bool phNxpNciHal_updateRfSetConfig(vector& setConfCmd, vector& getResData) { uint8_t res_data_packet_len = 0; if ((getResData.size() <= 5) || (getResData.size() != (getResData[NCI_PACKET_LEN_INDEX] + NCI_HEADER_SIZE))) { NXPLOG_NCIHAL_E("%s : Invalid res data length", __FUNCTION__); return false; } /*Updating the actual TLV packet length by excluding the status & tlv bytes */ res_data_packet_len = getResData[NCI_PACKET_LEN_INDEX] - 2; /*Copying the TLV packet and excluding NCI header, status & tlv bytes*/ setConfCmd.insert(setConfCmd.end(), getResData.begin() + 5, getResData.end()); if (setConfCmd.size() >= 0xFF) { if (NFCSTATUS_SUCCESS != phNxpNciHal_send_ext_cmd((setConfCmd.size() - res_data_packet_len), &setConfCmd[0])) { NXPLOG_NCIHAL_E("%s : Set config failed", __FUNCTION__); return false; } // Clear setConf Data expect the last command response. setConfCmd.erase(setConfCmd.begin() + 4, setConfCmd.end() - res_data_packet_len); // Clear the length and TLV after sending the packet. setConfCmd[NCI_PACKET_LEN_INDEX] = 0x01; setConfCmd[NCI_PACKET_TLV_INDEX] = 0x00; } setConfCmd[NCI_PACKET_LEN_INDEX] += res_data_packet_len; setConfCmd[NCI_PACKET_TLV_INDEX] += getResData[NCI_GET_RES_TLV_INDEX]; return true; } /******************************************************************************* ** ** Function phNxpNciHal_getUpdatePropRfSetConfig ** ** Description Get and update the Prop RF settings. ** ** Parameters IndexValue poniting to the vector ** NewValue - To be update at the index position ** propCmdresData - Update the prop response buffer based on ** prop getConfig response. ** Returns bool value true/false *******************************************************************************/ bool phNxpNciHal_getUpdatePropRfSetConfig(unsigned newValue, vector& propCmdresData) { vector prop_cmd_get_rftxval{0x2F, 0x14, 0x02, 0x62, 0x32}; uint8_t getPropRfCount = 0; uint8_t index = 10; // Index for RF register 6232 do { if (NFCSTATUS_SUCCESS != phNxpNciHal_send_ext_cmd(prop_cmd_get_rftxval.size(), &prop_cmd_get_rftxval[0])) { NXPLOG_NCIHAL_E("%s : Get config failed for A00D", __FUNCTION__); return false; } if (GET_RES_STATUS_CHECK(nxpncihal_ctrl.rx_data_len, nxpncihal_ctrl.p_rx_data)) { NXPLOG_NCIHAL_E("%s : Get response failed", __FUNCTION__); return false; } if (nxpncihal_ctrl.p_rx_data[RF_CM_TX_UNDERSHOOT_INDEX] == newValue) return true; // Mapping Prop command response to NCI command response. propCmdresData[index] = (uint8_t)(newValue & BYTE0_SHIFT_MASK); propCmdresData[index + 1] = nxpncihal_ctrl.p_rx_data[RF_CM_TX_UNDERSHOOT_INDEX + 1]; propCmdresData[index + 2] = nxpncihal_ctrl.p_rx_data[RF_CM_TX_UNDERSHOOT_INDEX + 2]; propCmdresData[index + 3] = nxpncihal_ctrl.p_rx_data[RF_CM_TX_UNDERSHOOT_INDEX + 3]; getPropRfCount++; if (getPropRfCount == 1) { index = 19; // Index for RF register 6732 prop_cmd_get_rftxval[NCI_PACKET_TLV_INDEX] = 0x67; } } while (getPropRfCount < 2); return true; } /******************************************************************************* ** ** Function phNxpNciHal_checkUpdateRfTransitConfig ** ** Description Check and update selected RF settings dynamically. ** ** Parameters char config ** ** Returns bool value true/false *******************************************************************************/ bool phNxpNciHal_checkUpdateRfTransitConfig(const char* config) { vector cmd_get_rfconfval{0x20, 0x03, 0x03, 0x01, 0xA0, 0x85}; vector cmd_response{}; vector lpdet_cmd_response{}; vector get_cmd_response{}; vector cmd_set_rfconfval{0x20, 0x02, 0x01, 0x00}; vector prop_Cmd_Response{ /*Preset get config response for A00D register*/ 0x40, 0x03, 0x14, 0x00, 0x02, 0xA0, 0x0D, 0x06, 0x62, 0x32, 0xAE, 0x00, 0x7F, 0x00, 0xA0, 0x0D, 0x06, 0x67, 0x32, 0xAE, 0x00, 0x1F, 0x00}; bool is_feature_update_required = false; bool is_lpdet_threshold_required = false; uint8_t index_to_value = 0; uint8_t update_mode = BITWISE; uint8_t condition = 0; stringstream key_value_pairs(config); string single_key_value; unsigned b_position = 0; unsigned new_value = 0; unsigned read_value = 0; unsigned rf_reg_A085_value = 0; NXPLOG_NCIHAL_D("%s : Enter", __FUNCTION__); if (NFCSTATUS_SUCCESS != phNxpNciHal_send_ext_cmd(cmd_get_rfconfval.size(), &cmd_get_rfconfval[0])) { NXPLOG_NCIHAL_E("%s : Get config failed for A085", __FUNCTION__); return false; } if (GET_RES_STATUS_CHECK(nxpncihal_ctrl.rx_data_len, nxpncihal_ctrl.p_rx_data)) { NXPLOG_NCIHAL_E("%s : Get config failed", __FUNCTION__); return false; } // Updating the A085 get config command response to vector. cmd_response.insert( cmd_response.end(), &nxpncihal_ctrl.p_rx_data[0], (&nxpncihal_ctrl.p_rx_data[0] + (nxpncihal_ctrl.p_rx_data[NCI_PACKET_LEN_INDEX] + NCI_HEADER_SIZE))); rf_reg_A085_value = (unsigned)((cmd_response[REG_A085_DATA_INDEX + 3] << 24) | (cmd_response[REG_A085_DATA_INDEX + 2] << 16) | (cmd_response[REG_A085_DATA_INDEX + 1] << 8) | (cmd_response[REG_A085_DATA_INDEX])); cmd_get_rfconfval[NCI_GET_CMD_TLV_INDEX2] = 0x9E; if (NFCSTATUS_SUCCESS != phNxpNciHal_send_ext_cmd(cmd_get_rfconfval.size(), &cmd_get_rfconfval[0])) { NXPLOG_NCIHAL_E("%s : Get config failed for A09E", __FUNCTION__); return false; } if (GET_RES_STATUS_CHECK(nxpncihal_ctrl.rx_data_len, nxpncihal_ctrl.p_rx_data)) { NXPLOG_NCIHAL_E("%s : Get config failed", __FUNCTION__); return false; } // Updating the A09E get config command response to vector. lpdet_cmd_response.insert( lpdet_cmd_response.end(), &nxpncihal_ctrl.p_rx_data[0], (&nxpncihal_ctrl.p_rx_data[0] + (nxpncihal_ctrl.p_rx_data[NCI_PACKET_LEN_INDEX] + NCI_HEADER_SIZE))); while (getline(key_value_pairs, single_key_value)) { auto search = single_key_value.find('='); if (search == string::npos) continue; string key(Trim(single_key_value.substr(0, search))); string value(Trim(single_key_value.substr(search + 1, string::npos))); ParseUint(value.c_str(), &new_value); update_mode = BITWISE; NXPLOG_NCIHAL_D("%s : Update Key = %s Value: %02x", __FUNCTION__, key.c_str(), new_value); auto it = tokenMap.find(key); if (it != tokenMap.end()) { condition = it->second; } else condition = UPDATE_UNKNOWN; switch (condition) { case UPDATE_DLMA_ID_TX_ENTRY: cmd_get_rfconfval[NCI_GET_CMD_TLV_INDEX1] = 0xA0; cmd_get_rfconfval[NCI_GET_CMD_TLV_INDEX2] = 0x34; index_to_value = DLMA_ID_TX_ENTRY_INDEX; break; case UPDATE_RF_CM_TX_UNDERSHOOT_CONFIG: if (!phNxpNciHal_getUpdatePropRfSetConfig(new_value, prop_Cmd_Response)) return false; if ((nxpncihal_ctrl.rx_data_len > RF_CM_TX_UNDERSHOOT_INDEX) && (nxpncihal_ctrl.p_rx_data[RF_CM_TX_UNDERSHOOT_INDEX] != new_value)) { if (!phNxpNciHal_updateRfSetConfig(cmd_set_rfconfval, prop_Cmd_Response)) return false; } break; case UPDATE_INITIAL_TX_PHASE: cmd_get_rfconfval[NCI_GET_CMD_TLV_INDEX1] = 0xA0; cmd_get_rfconfval[NCI_GET_CMD_TLV_INDEX2] = 0x6A; index_to_value = INITIAL_TX_PHASE_INDEX; update_mode = BYTEWISE; break; case UPDATE_LPDET_THRESHOLD: read_value = 0; read_value = lpdet_cmd_response[LPDET_THRESHOLD_INDEX]; read_value |= (lpdet_cmd_response[LPDET_THRESHOLD_INDEX + 1] << 8); NXPLOG_NCIHAL_D("%s : read_value = %02x Value: %02x", __FUNCTION__, read_value, new_value); if (read_value != new_value) { lpdet_cmd_response[LPDET_THRESHOLD_INDEX] = (uint8_t)(new_value & BYTE0_SHIFT_MASK); lpdet_cmd_response[LPDET_THRESHOLD_INDEX + 1] = (uint8_t)((new_value & BYTE1_SHIFT_MASK) >> 8); is_lpdet_threshold_required = true; } break; case UPDATE_NFCLD_THRESHOLD: read_value = 0; read_value = lpdet_cmd_response[NFCLD_THRESHOLD_INDEX]; read_value |= (lpdet_cmd_response[NFCLD_THRESHOLD_INDEX + 1] << 8); NXPLOG_NCIHAL_D("%s : read_value = %02x Value: %02x", __FUNCTION__, read_value, new_value); if (read_value != new_value) { lpdet_cmd_response[NFCLD_THRESHOLD_INDEX] = (uint8_t)(new_value & BYTE0_SHIFT_MASK); lpdet_cmd_response[NFCLD_THRESHOLD_INDEX + 1] = (uint8_t)((new_value & BYTE1_SHIFT_MASK) >> 8); is_lpdet_threshold_required = true; } break; case UPDATE_GUARD_TIMEOUT_TX2RX: cmd_get_rfconfval[NCI_GET_CMD_TLV_INDEX1] = 0xA1; cmd_get_rfconfval[NCI_GET_CMD_TLV_INDEX2] = 0x0E; index_to_value = GUARD_TIMEOUT_TX2RX_INDEX; break; case UPDATE_RF_PATTERN_CHK: cmd_get_rfconfval[NCI_GET_CMD_TLV_INDEX1] = 0xA1; cmd_get_rfconfval[NCI_GET_CMD_TLV_INDEX2] = 0x48; index_to_value = RF_PATTERN_CHK_INDEX; break; case UPDATE_MIFARE_NACK_TO_RATS_ENABLE: case UPDATE_MIFARE_MUTE_TO_RATS_ENABLE: case UPDATE_CHINA_TIANJIN_RF_ENABLED: case UPDATE_CN_TRANSIT_CMA_BYPASSMODE_ENABLE: case UPDATE_CN_TRANSIT_BLK_NUM_CHECK_ENABLE: { auto itReg = rfReg_A085_Map.find(condition); if (itReg == rfReg_A085_Map.end()) continue; NXPLOG_NCIHAL_D("%s : Reg A085 Update Key = %s and Bit Position: %d", __FUNCTION__, key.c_str(), itReg->second); b_position = (unsigned)(0x01 << itReg->second); if ((rf_reg_A085_value & b_position) != ((new_value & 0x01) << itReg->second)) { rf_reg_A085_value ^= (1 << itReg->second); is_feature_update_required = true; } } break; case UPDATE_PHONEOFF_TECH_DISABLE: cmd_get_rfconfval[NCI_GET_CMD_TLV_INDEX1] = 0xA1; cmd_get_rfconfval[NCI_GET_CMD_TLV_INDEX2] = 0x1A; index_to_value = PHONEOFF_TECH_DISABLE_INDEX; break; case UPDATE_ISO_DEP_MERGE_SAK: cmd_get_rfconfval[NCI_GET_CMD_TLV_INDEX1] = 0xA1; cmd_get_rfconfval[NCI_GET_CMD_TLV_INDEX2] = 0x1B; index_to_value = ISO_DEP_MERGE_SAK_INDEX; break; default: NXPLOG_NCIHAL_D("%s : default = %x", __FUNCTION__, new_value); break; } if (index_to_value) { if (NFCSTATUS_SUCCESS != phNxpNciHal_send_ext_cmd(cmd_get_rfconfval.size(), &cmd_get_rfconfval[0])) { NXPLOG_NCIHAL_E("%s : Get config failed for %s", __FUNCTION__, key.c_str()); return false; } if (GET_RES_STATUS_CHECK(nxpncihal_ctrl.rx_data_len, nxpncihal_ctrl.p_rx_data)) { NXPLOG_NCIHAL_E("%s : Get config response failed ", __FUNCTION__); return false; } read_value = 0; read_value = nxpncihal_ctrl.p_rx_data[index_to_value]; if (update_mode == BYTEWISE) read_value |= (nxpncihal_ctrl.p_rx_data[index_to_value + 1] << 8); if (read_value == new_value) { index_to_value = 0; continue; } nxpncihal_ctrl.p_rx_data[index_to_value] = (uint8_t)(new_value & BYTE0_SHIFT_MASK); if (update_mode == BYTEWISE) nxpncihal_ctrl.p_rx_data[index_to_value + 1] = (uint8_t)((new_value & BYTE1_SHIFT_MASK) >> 8); // Updating the get config command response to vector. get_cmd_response.insert( get_cmd_response.end(), &nxpncihal_ctrl.p_rx_data[0], (&nxpncihal_ctrl.p_rx_data[0] + (nxpncihal_ctrl.p_rx_data[NCI_PACKET_LEN_INDEX] + NCI_HEADER_SIZE))); if (!phNxpNciHal_updateRfSetConfig(cmd_set_rfconfval, get_cmd_response)) return false; get_cmd_response.clear(); index_to_value = 0; } } if (is_feature_update_required) { // Updating the A085 response to set config command. cmd_response[REG_A085_DATA_INDEX + 3] = (uint8_t)((rf_reg_A085_value & BYTE3_SHIFT_MASK) >> 24); cmd_response[REG_A085_DATA_INDEX + 2] = (uint8_t)((rf_reg_A085_value & BYTE2_SHIFT_MASK) >> 16); cmd_response[REG_A085_DATA_INDEX + 1] = (uint8_t)((rf_reg_A085_value & BYTE1_SHIFT_MASK) >> 8); cmd_response[REG_A085_DATA_INDEX] = (uint8_t)(rf_reg_A085_value & BYTE0_SHIFT_MASK); if (!phNxpNciHal_updateRfSetConfig(cmd_set_rfconfval, cmd_response)) return false; } if (is_lpdet_threshold_required) { // Updating the A09E response to set config command. if (!phNxpNciHal_updateRfSetConfig(cmd_set_rfconfval, lpdet_cmd_response)) return false; } if (cmd_set_rfconfval.size() <= NCI_HEADER_SIZE) { NXPLOG_NCIHAL_E("%s : Invalid NCI Command length = %zu", __FUNCTION__, cmd_set_rfconfval.size()); return false; } if (cmd_set_rfconfval[NCI_PACKET_TLV_INDEX] != 0x00) { /*If update require do set-config in NFCC otherwise skip */ if (NFCSTATUS_SUCCESS == phNxpNciHal_send_ext_cmd(cmd_set_rfconfval.size(), &cmd_set_rfconfval[0])) { if (is_feature_update_required) { if (NFCSTATUS_SUCCESS != phNxpNciHal_ext_send_sram_config_to_flash()) { NXPLOG_NCIHAL_E("%s :Updation of the SRAM contents failed", __FUNCTION__); return false; } } } else { NXPLOG_NCIHAL_D("Set RF update cmd is failed.."); return false; } } return true; }