1 /*
2 * Copyright 2019-2024 NXP
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "phNxpNciHal_IoctlOperations.h"
18
19 #include <android-base/file.h>
20 #include <android-base/parseint.h>
21 #include <android-base/strings.h>
22
23 #include <map>
24 #include <set>
25 #include <unordered_map>
26 #include <vector>
27
28 #include "EseAdaptation.h"
29 #include "NfccTransport.h"
30 #include "NfccTransportFactory.h"
31 #include "phDnldNfc_Internal.h"
32 #include "phNfcCommon.h"
33 #include "phNxpNciHal_Adaptation.h"
34 #include "phNxpNciHal_ULPDet.h"
35 #include "phNxpNciHal_ext.h"
36 #include "phNxpNciHal_extOperations.h"
37 #include "phNxpNciHal_utils.h"
38
39 using android::base::WriteStringToFile;
40 using namespace ::std;
41 using namespace ::android::base;
42
43 #define TERMINAL_LEN 5
44 /* HAL_NFC_STATUS_REFUSED sent to restart NFC service */
45 #define HAL_NFC_STATUS_RESTART HAL_NFC_STATUS_REFUSED
46
47 #define GET_RES_STATUS_CHECK(len, data) \
48 (((len) < NCI_HEADER_SIZE) || \
49 ((len) != ((data[NCI_PACKET_LEN_INDEX]) + NCI_HEADER_SIZE)) || \
50 (NFCSTATUS_SUCCESS != (data[NCI_GET_RES_STATUS_INDEX])))
51
52 typedef enum {
53 UPDATE_DLMA_ID_TX_ENTRY,
54 UPDATE_RF_CM_TX_UNDERSHOOT_CONFIG,
55 UPDATE_MIFARE_NACK_TO_RATS_ENABLE,
56 UPDATE_MIFARE_MUTE_TO_RATS_ENABLE,
57 UPDATE_CHINA_TIANJIN_RF_ENABLED,
58 UPDATE_CN_TRANSIT_CMA_BYPASSMODE_ENABLE,
59 UPDATE_CN_TRANSIT_BLK_NUM_CHECK_ENABLE,
60 UPDATE_ISO_DEP_MERGE_SAK,
61 UPDATE_PHONEOFF_TECH_DISABLE,
62 UPDATE_INITIAL_TX_PHASE,
63 UPDATE_GUARD_TIMEOUT_TX2RX,
64 UPDATE_LPDET_THRESHOLD,
65 UPDATE_NFCLD_THRESHOLD,
66 UPDATE_RF_PATTERN_CHK,
67 UPDATE_UNKNOWN = 0xFF
68 } tNFC_setDynamicRfConfigType;
69 static const std::unordered_map<std::string, uint8_t> tokenMap = {
70 {"UPDATE_DLMA_ID_TX_ENTRY", UPDATE_DLMA_ID_TX_ENTRY},
71 {"UPDATE_RF_CM_TX_UNDERSHOOT_CONFIG", UPDATE_RF_CM_TX_UNDERSHOOT_CONFIG},
72 {"UPDATE_MIFARE_NACK_TO_RATS_ENABLE", UPDATE_MIFARE_NACK_TO_RATS_ENABLE},
73 {"UPDATE_MIFARE_MUTE_TO_RATS_ENABLE", UPDATE_MIFARE_MUTE_TO_RATS_ENABLE},
74 {"UPDATE_CHINA_TIANJIN_RF_ENABLED", UPDATE_CHINA_TIANJIN_RF_ENABLED},
75 {"UPDATE_CN_TRANSIT_CMA_BYPASSMODE_ENABLE",
76 UPDATE_CN_TRANSIT_CMA_BYPASSMODE_ENABLE},
77 {"UPDATE_CN_TRANSIT_BLK_NUM_CHECK_ENABLE",
78 UPDATE_CN_TRANSIT_BLK_NUM_CHECK_ENABLE},
79 {"UPDATE_ISO_DEP_MERGE_SAK", UPDATE_ISO_DEP_MERGE_SAK},
80 {"UPDATE_PHONEOFF_TECH_DISABLE", UPDATE_PHONEOFF_TECH_DISABLE},
81 {"UPDATE_INITIAL_TX_PHASE", UPDATE_INITIAL_TX_PHASE},
82 {"UPDATE_GUARD_TIMEOUT_TX2RX", UPDATE_GUARD_TIMEOUT_TX2RX},
83 {"UPDATE_LPDET_THRESHOLD", UPDATE_LPDET_THRESHOLD},
84 {"UPDATE_NFCLD_THRESHOLD", UPDATE_NFCLD_THRESHOLD},
85 {"UPDATE_RF_PATTERN_CHK", UPDATE_RF_PATTERN_CHK}};
86
87 static const std::unordered_map<uint8_t, uint8_t> rfReg_A085_Map = {
88 {UPDATE_MIFARE_NACK_TO_RATS_ENABLE, MIFARE_NACK_TO_RATS_ENABLE_BIT_POS},
89 {UPDATE_MIFARE_MUTE_TO_RATS_ENABLE, MIFARE_MUTE_TO_RATS_ENABLE_BIT_POS},
90 {UPDATE_CHINA_TIANJIN_RF_ENABLED, CHINA_TIANJIN_RF_ENABLE_BIT_POS},
91 {UPDATE_CN_TRANSIT_CMA_BYPASSMODE_ENABLE,
92 CN_TRANSIT_CMA_BYPASSMODE_ENABLE_BIT_POS},
93 {UPDATE_CN_TRANSIT_BLK_NUM_CHECK_ENABLE,
94 CN_TRANSIT_BLK_NUM_CHECK_ENABLE_BIT_POS}};
95 /****************************************************************
96 * Global Variables Declaration
97 ***************************************************************/
98 /* External global variable to get FW version from NCI response*/
99 extern uint32_t wFwVerRsp;
100 /* External global variable to get FW version from FW file*/
101 extern uint16_t wFwVer;
102 /* NCI HAL Control structure */
103 extern phNxpNciHal_Control_t nxpncihal_ctrl;
104 extern phNxpNci_getCfg_info_t* mGetCfg_info;
105 extern EseAdaptation* gpEseAdapt;
106 extern nfc_stack_callback_t* p_nfc_stack_cback_backup;
107 #ifndef FW_DWNLD_FLAG
108 extern uint8_t fw_dwnld_flag;
109 #endif
110
111 /* TML Context */
112 extern phTmlNfc_Context_t* gpphTmlNfc_Context;
113 extern bool nfc_debug_enabled;
114 extern NFCSTATUS phNxpLog_EnableDisableLogLevel(uint8_t enable);
115 extern phNxpNciClock_t phNxpNciClock;
116 extern NfcHalThreadMutex sHalFnLock;
117
118 /*******************************************************************************
119 **
120 ** Function: property_get_intf()
121 **
122 ** Description: Gets property value for the input property name
123 **
124 ** Parameters propName: Name of the property whichs value need to get
125 ** valueStr: output value of the property.
126 ** defaultStr: default value of the property if value is not
127 ** there this will be set to output value.
128 **
129 ** Returns: actual length of the property value
130 **
131 ********************************************************************************/
property_get_intf(const char * propName,char * valueStr,const char * defaultStr)132 int property_get_intf(const char* propName, char* valueStr,
133 const char* defaultStr) {
134 string propValue;
135 string propValueDefault = defaultStr;
136 int len = 0;
137
138 propValue = phNxpNciHal_getSystemProperty(propName);
139 if (propValue.length() > 0) {
140 NXPLOG_NCIHAL_D("property_get_intf , key[%s], propValue[%s], length[%zu]",
141 propName, propValue.c_str(), propValue.length());
142 len = propValue.length();
143 strlcpy(valueStr, propValue.c_str(), PROPERTY_VALUE_MAX);
144 } else {
145 if (propValueDefault.length() > 0) {
146 len = propValueDefault.length();
147 strlcpy(valueStr, propValueDefault.c_str(), PROPERTY_VALUE_MAX);
148 }
149 }
150
151 return len;
152 }
153
154 /*******************************************************************************
155 **
156 ** Function: property_set_intf()
157 **
158 ** Description: Sets property value for the input property name
159 **
160 ** Parameters propName: Name of the property whichs value need to set
161 ** valueStr: value of the property.
162 **
163 ** Returns: returns 0 on success, < 0 on failure
164 **
165 ********************************************************************************/
property_set_intf(const char * propName,const char * valueStr)166 int property_set_intf(const char* propName, const char* valueStr) {
167 NXPLOG_NCIHAL_D("property_set_intf, key[%s], value[%s]", propName, valueStr);
168 if (phNxpNciHal_setSystemProperty(propName, valueStr))
169 return NFCSTATUS_SUCCESS;
170 else
171 return NFCSTATUS_FAILED;
172 }
173
174 extern size_t readConfigFile(const char* fileName, uint8_t** p_data);
175 extern NFCSTATUS phNxpNciHal_ext_send_sram_config_to_flash();
176 static bool phNxpNciHal_checkUpdateRfTransitConfig(const char* config);
177 static string phNxpNciHal_parseBytesString(string in);
178 static bool phNxpNciHal_parseValueFromString(string& in);
179 static bool phNxpNciHal_CheckKeyNeeded(string key);
180 static string phNxpNciHal_UpdatePwrStateConfigs(string& config);
181 static bool phNxpNciHal_IsAutonmousModeSet(string config);
182 static string phNxpNciHal_extractConfig(string& config);
183 static void phNxpNciHal_getFilteredConfig(string& config);
184
185 typedef std::map<std::string, std::string> systemProperty;
186 systemProperty gsystemProperty = {
187 {"nfc.nxp_log_level_global", ""},
188 {"nfc.nxp_log_level_extns", ""},
189 {"nfc.nxp_log_level_hal", ""},
190 {"nfc.nxp_log_level_nci", ""},
191 {"nfc.nxp_log_level_dnld", ""},
192 {"nfc.nxp_log_level_tml", ""},
193 {"nfc.fw.dfl", ""},
194 {"nfc.fw.downloadmode_force", ""},
195 {"nfc.debug_enabled", ""},
196 {"nfc.product.support.ese", ""},
197 {"nfc.product.support.uicc", ""},
198 {"nfc.product.support.uicc2", ""},
199 {"nfc.fw.rfreg_ver", ""},
200 {"nfc.fw.rfreg_display_ver", ""},
201 {"nfc.fw.dfl_areacode", ""},
202 {"nfc.cover.cover_id", ""},
203 {"nfc.cover.state", ""},
204 {"ro.factory.factory_binary", ""},
205 };
206 const char default_nxp_config_path[] = "/vendor/etc/libnfc-nxp.conf";
207 std::set<string> gNciConfigs = {"NXP_SE_COLD_TEMP_ERROR_DELAY",
208 "NXP_SWP_RD_TAG_OP_TIMEOUT",
209 "NXP_DUAL_UICC_ENABLE",
210 "DEFAULT_AID_ROUTE",
211 "DEFAULT_MIFARE_CLT_ROUTE",
212 "DEFAULT_FELICA_CLT_ROUTE",
213 "DEFAULT_AID_PWR_STATE",
214 "DEFAULT_DESFIRE_PWR_STATE",
215 "DEFAULT_MIFARE_CLT_PWR_STATE",
216 "DEFAULT_FELICA_CLT_PWR_STATE",
217 "HOST_LISTEN_TECH_MASK",
218 "FORWARD_FUNCTIONALITY_ENABLE",
219 "DEFAULT_GSMA_PWR_STATE",
220 "NXP_DEFAULT_UICC2_SELECT",
221 "NXP_SMB_TRANSCEIVE_TIMEOUT",
222 "NXP_SMB_ERROR_RETRY",
223 "NXP_CHECK_DEFAULT_PROTO_SE_ID",
224 "NXPLOG_NCIHAL_LOGLEVEL",
225 "NXPLOG_EXTNS_LOGLEVEL",
226 "NXPLOG_TML_LOGLEVEL",
227 "NXPLOG_FWDNLD_LOGLEVEL",
228 "NXPLOG_NCIX_LOGLEVEL",
229 "NXPLOG_NCIR_LOGLEVEL",
230 "NXP_NFC_SE_TERMINAL_NUM",
231 "NXP_POLL_FOR_EFD_TIMEDELAY",
232 "NXP_NFCC_MERGE_SAK_ENABLE",
233 "NXP_STAG_TIMEOUT_CFG",
234 "DEFAULT_T4TNFCEE_AID_POWER_STATE",
235 "RF_STORAGE",
236 "FW_STORAGE",
237 "NXP_CORE_CONF",
238 "NXP_RF_FILE_VERSION_INFO",
239 "NXP_AUTONOMOUS_ENABLE",
240 "NXP_PROP_RESET_EMVCO_CMD",
241 "NFA_CONFIG_FORMAT",
242 "NXP_T4T_NFCEE_ENABLE",
243 "NXP_DISCONNECT_TAG_IN_SCRN_OFF",
244 "NXP_CE_PRIORITY_ENABLED",
245 "NXP_RDR_REQ_GUARD_TIME",
246 "NXP_ENABLE_DISABLE_LOGS",
247 "NXP_RDR_DISABLE_ENABLE_LPCD",
248 "NXP_SUPPORT_NON_STD_CARD",
249 "NXP_GET_HW_INFO_LOG",
250 "NXP_WLC_MODE",
251 "NXP_T4T_NDEF_NFCEE_AID",
252 "NXP_NON_STD_CARD_TIMEDIFF",
253 "NXP_SRD_TIMEOUT",
254 "NXP_UICC_ETSI_SUPPORT",
255 "NXP_MINIMAL_FW_VERSION",
256 "NXP_RESTART_RF_FOR_NFCEE_RECOVERY",
257 "NXP_NFCC_RECOVERY_SUPPORT",
258 "NXP_AGC_DEBUG_ENABLE",
259 "NXP_EXTENDED_FIELD_DETECT_MODE",
260 "NXP_SE_SMB_TERMINAL_TYPE"};
261
262 /****************************************************************
263 * Local Functions
264 ***************************************************************/
265
266 /******************************************************************************
267 ** Function phNxpNciHal_ioctlIf
268 **
269 ** Description This function shall be called from HAL when libnfc-nci
270 ** calls phNxpNciHal_ioctl() to perform any IOCTL operation
271 **
272 ** Returns return 0 on success and -1 on fail,
273 ******************************************************************************/
phNxpNciHal_ioctlIf(long arg,void * p_data)274 int phNxpNciHal_ioctlIf(long arg, void* p_data) {
275 NXPLOG_NCIHAL_D("%s : enter - arg = %ld", __func__, arg);
276 ese_nxp_IoctlInOutData_t* pInpOutData = (ese_nxp_IoctlInOutData_t*)p_data;
277 int ret = -1;
278
279 switch (arg) {
280 case HAL_ESE_IOCTL_NFC_JCOP_DWNLD:
281 if (pInpOutData == NULL) {
282 NXPLOG_NCIHAL_E("%s : received invalid param", __func__);
283 break;
284 }
285
286 if (gpEseAdapt == NULL) {
287 gpEseAdapt = &EseAdaptation::GetInstance();
288 if (gpEseAdapt == NULL) {
289 NXPLOG_NCIHAL_E("%s :invalid gpEseAdapt param", __func__);
290 break;
291 }
292 gpEseAdapt->Initialize();
293 }
294
295 NXPLOG_NCIHAL_D("HAL_ESE_IOCTL_NFC_JCOP_DWNLD Enter value is %d: \n",
296 pInpOutData->inp.data.nxpCmd.p_cmd[0]);
297
298 gpEseAdapt->HalIoctl(HAL_ESE_IOCTL_NFC_JCOP_DWNLD, pInpOutData);
299 ret = 0;
300 break;
301 default:
302 NXPLOG_NCIHAL_E("%s : Wrong arg = %ld", __func__, arg);
303 break;
304 }
305 NXPLOG_NCIHAL_D("%s : exit - ret = %d", __func__, ret);
306 return ret;
307 }
308
309 /*******************************************************************************
310 **
311 ** Function phNxpNciHal_getSystemProperty
312 **
313 ** Description It shall be used to get property value of the given Key
314 **
315 ** Parameters string key
316 **
317 ** Returns If Key is found, returns the respective property values
318 ** else returns the null/empty string
319 *******************************************************************************/
phNxpNciHal_getSystemProperty(string key)320 string phNxpNciHal_getSystemProperty(string key) {
321 string propValue;
322 std::map<std::string, std::string>::iterator prop;
323
324 if (key == "libnfc-nxp.conf") {
325 return phNxpNciHal_getNxpConfigIf();
326 } else {
327 prop = gsystemProperty.find(key);
328 if (prop != gsystemProperty.end()) {
329 propValue = prop->second;
330 } else {
331 /* else Pass a null string */
332 }
333 }
334 return propValue;
335 }
336 /*******************************************************************************
337 **
338 ** Function phNxpNciHal_setSystemProperty
339 **
340 ** Description It shall be used to save/change value to system property
341 ** based on provided key.
342 **
343 ** Parameters string key, string value
344 **
345 ** Returns true if success, false if fail
346 *******************************************************************************/
phNxpNciHal_setSystemProperty(string key,string value)347 bool phNxpNciHal_setSystemProperty(string key, string value) {
348 bool stat = true;
349 if (strcmp(key.c_str(), "nfc.debug_enabled") != 0)
350 NXPLOG_NCIHAL_D("%s : Enter Key = %s, value = %s", __func__, key.c_str(),
351 value.c_str());
352
353 unsigned tmp = 0;
354 if (strcmp(key.c_str(), "nfc.debug_enabled") == 0) {
355 if (ParseUint(value.c_str(), &tmp)) {
356 if (phNxpLog_EnableDisableLogLevel((uint8_t)tmp) != NFCSTATUS_SUCCESS) {
357 stat = false;
358 }
359 } else {
360 NXPLOG_NCIHAL_W(
361 "%s : Failed to parse the string to uint. "
362 "nfc.debug_enabled string : %s",
363 __func__, value.c_str());
364 }
365 } else if (strcmp(key.c_str(), "nfc.cover.state") == 0) {
366 unsigned cid, cstate;
367 string strtmp;
368 if (ParseUint(value.c_str(), &cstate)) {
369 strtmp = phNxpNciHal_getSystemProperty("nfc.cover.cover_id");
370 if (ParseUint(strtmp.c_str(), &cid)) {
371 if (fpPropConfCover != NULL) {
372 stat = (fpPropConfCover(cstate, cid) == NFCSTATUS_SUCCESS) ? true
373 : false;
374 }
375 } else {
376 NXPLOG_NCIHAL_W(
377 "%s : Failed to parse the string to uint. "
378 "nfc.cover.cover_id string : %s",
379 __func__, value.c_str());
380 }
381 } else {
382 NXPLOG_NCIHAL_W(
383 "%s : Failed to parse the string to uint. "
384 "nfc.cover.state string : %s",
385 __func__, value.c_str());
386 }
387 } else if (strcmp(key.c_str(), "nfc.cmd_timeout") == 0) {
388 NXPLOG_NCIHAL_E("%s : nci_timeout, sem post", __func__);
389 sem_post(&(nxpncihal_ctrl.syncSpiNfc));
390 }
391 gsystemProperty[key] = std::move(value);
392 return stat;
393 }
394
395 /*******************************************************************************
396 **
397 ** Function phNxpNciHal_getNxpConfig
398 **
399 ** Description It shall be used to read config values from the
400 *libnfc-nxp.conf
401 **
402 ** Parameters nxpConfigs config
403 **
404 ** Returns void
405 *******************************************************************************/
phNxpNciHal_getNxpConfigIf()406 string phNxpNciHal_getNxpConfigIf() {
407 std::string config;
408 uint8_t* p_config = nullptr;
409 size_t config_size = readConfigFile(default_nxp_config_path, &p_config);
410 if (config_size) {
411 config.assign((char*)p_config, config_size);
412 free(p_config);
413 phNxpNciHal_getFilteredConfig(config);
414 }
415 return config;
416 }
417
418 /*******************************************************************************
419 **
420 ** Function phNxpNciHal_getFilteredConfig
421 **
422 ** Description It reads only configs needed for libnfc from
423 * libnfc-nxp.conf
424 **
425 ** Parameters string config
426 **
427 ** Returns void
428 *******************************************************************************/
phNxpNciHal_getFilteredConfig(string & config)429 static void phNxpNciHal_getFilteredConfig(string& config) {
430 config = phNxpNciHal_extractConfig(config);
431 if (phNxpNciHal_IsAutonmousModeSet(config)) {
432 config = phNxpNciHal_UpdatePwrStateConfigs(config);
433 }
434 }
435
436 /*******************************************************************************
437 **
438 ** Function phNxpNciHal_extractConfig
439 **
440 ** Description It parses complete config file and extracts only
441 * enabled options ignores comments etc.
442 **
443 ** Parameters string config
444 **
445 ** Returns Resultant string
446 *******************************************************************************/
phNxpNciHal_extractConfig(string & config)447 static string phNxpNciHal_extractConfig(string& config) {
448 stringstream ss(config);
449 string line;
450 string result;
451 bool apduGate = false;
452 while (getline(ss, line)) {
453 line = Trim(line);
454 if (line.empty()) continue;
455 if (line.at(0) == '#') continue;
456 if (line.at(0) == 0) continue;
457
458 auto search = line.find('=');
459 if (search == string::npos) continue;
460
461 string key(Trim(line.substr(0, search)));
462 if (!phNxpNciHal_CheckKeyNeeded(key)) continue;
463 if (key == "NXP_NFC_SE_TERMINAL_NUM" && !apduGate) {
464 line = "NXP_SE_APDU_GATE_SUPPORT=0x01\n";
465 result += line;
466 apduGate = true;
467 continue;
468 }
469 string value_string(Trim(line.substr(search + 1, string::npos)));
470
471 if (value_string[0] == '{' &&
472 value_string[value_string.length() - 1] != '}') {
473 string line_append;
474
475 do {
476 getline(ss, line_append);
477 if (line_append.empty()) break;
478 if (line_append.at(0) == '#') break;
479 if (line_append.at(0) == 0) break;
480 line_append = Trim(line_append);
481 value_string.append(line_append);
482 } while (line_append[line_append.length() - 1] != '}');
483 }
484
485 if (!phNxpNciHal_parseValueFromString(value_string)) continue;
486
487 line = key + "=" + value_string + "\n";
488 result += line;
489 if (key == "NXP_GET_HW_INFO_LOG" &&
490 (value_string == "1" || value_string == "0x01")) {
491 if (!apduGate) {
492 line = "NXP_SE_APDU_GATE_SUPPORT=0x01\n";
493 result += line;
494 apduGate = true;
495 }
496 }
497 }
498
499 return result;
500 }
501
502 /*******************************************************************************
503 **
504 ** Function phNxpNciHal_IsAutonmousModeSet
505 **
506 ** Description It check whether autonomous mode is enabled
507 * in config file
508 **
509 ** Parameters string config
510 **
511 ** Returns boolean(TRUE/FALSE)
512 *******************************************************************************/
phNxpNciHal_IsAutonmousModeSet(string config)513 static bool phNxpNciHal_IsAutonmousModeSet(string config) {
514 stringstream ss(config);
515 string line;
516 unsigned tmp = 0;
517 while (getline(ss, line)) {
518 auto search = line.find('=');
519 if (search == string::npos) continue;
520
521 string key(Trim(line.substr(0, search)));
522 if (key == "NXP_AUTONOMOUS_ENABLE") {
523 string value(Trim(line.substr(search + 1, string::npos)));
524 if (ParseUint(value.c_str(), &tmp)) {
525 if (tmp == 1) {
526 return true;
527 } else {
528 NXPLOG_NCIHAL_D("Autonomous flag disabled");
529 return false;
530 }
531 }
532 } else {
533 continue;
534 }
535 }
536 NXPLOG_NCIHAL_D("Autonomous flag disabled");
537 return false;
538 }
539
540 /*******************************************************************************
541 **
542 ** Function phNxpNciHal_UpdatePwrStateConfigs
543 **
544 ** Description Updates default pwr state accordingly if autonomous mode
545 * is enabled
546 **
547 ** Parameters string config
548 **
549 ** Returns Resultant string
550 *******************************************************************************/
phNxpNciHal_UpdatePwrStateConfigs(string & config)551 static string phNxpNciHal_UpdatePwrStateConfigs(string& config) {
552 stringstream ss(config);
553 string line;
554 string result;
555 unsigned tmp = 0;
556 while (getline(ss, line)) {
557 auto search = line.find('=');
558 if (search == string::npos) continue;
559
560 string key(Trim(line.substr(0, search)));
561 if ((key == "DEFAULT_AID_PWR_STATE" || key == "DEFAULT_DESFIRE_PWR_STATE" ||
562 key == "DEFAULT_MIFARE_CLT_PWR_STATE" ||
563 key == "DEFAULT_FELICA_CLT_PWR_STATE")) {
564 string value(Trim(line.substr(search + 1, string::npos)));
565 if (ParseUint(value.c_str(), &tmp)) {
566 tmp = phNxpNciHal_updateAutonomousPwrState(tmp);
567 value = to_string(tmp);
568 line = key + "=" + value + "\n";
569 result += line;
570 }
571 } else {
572 result += (line + "\n");
573 continue;
574 }
575 }
576 return result;
577 }
578
579 /*******************************************************************************
580 **
581 ** Function phNxpNciHal_CheckKeyNeeded
582 **
583 ** Description Check if the config needed for libnfc as per gNciConfigs
584 * list
585 **
586 ** Parameters string config
587 **
588 ** Returns bool(true/false)
589 *******************************************************************************/
phNxpNciHal_CheckKeyNeeded(string key)590 static bool phNxpNciHal_CheckKeyNeeded(string key) {
591 return ((gNciConfigs.find(key) != gNciConfigs.end()) ? true : false);
592 }
593
594 /*******************************************************************************
595 **
596 ** Function phNxpNciHal_parseValueFromString
597 **
598 ** Description Parse value determine data type of config option
599 **
600 ** Parameters string config
601 **
602 ** Returns bool(true/false)
603 *******************************************************************************/
phNxpNciHal_parseValueFromString(string & in)604 static bool phNxpNciHal_parseValueFromString(string& in) {
605 unsigned tmp = 0;
606 bool stat = false;
607 if (in.length() >= 1) {
608 switch (in[0]) {
609 case '"':
610 if (in[in.length() - 1] == '"' && in.length() > 2) stat = true;
611 break;
612 case '{':
613 if (in[in.length() - 1] == '}' && in.length() >= 3) {
614 in = phNxpNciHal_parseBytesString(in);
615 stat = true;
616 }
617 break;
618 default:
619 if (ParseUint(in.c_str(), &tmp)) stat = true;
620 break;
621 }
622 } else {
623 NXPLOG_NCIHAL_E("%s : Invalid config string ", __func__);
624 }
625 return stat;
626 }
627
628 /*******************************************************************************
629 **
630 ** Function phNxpNciHal_parseBytesString
631 **
632 ** Description Parse bytes from string
633 **
634 ** Parameters string config
635 **
636 ** Returns Resultant string
637 *******************************************************************************/
phNxpNciHal_parseBytesString(string in)638 static string phNxpNciHal_parseBytesString(string in) {
639 size_t pos;
640 in.erase(remove(in.begin(), in.end(), ' '), in.end());
641 pos = in.find(",");
642 while (pos != string::npos) {
643 in = in.replace(pos, 1, ":");
644 pos = in.find(",", pos);
645 }
646 return in;
647 }
648
649 /*******************************************************************************
650 **
651 ** Function phNxpNciHal_resetEse
652 **
653 ** Description It shall be used to reset eSE by proprietary command.
654 **
655 ** Parameters
656 **
657 ** Returns status of eSE reset response
658 *******************************************************************************/
phNxpNciHal_resetEse(uint64_t resetType)659 NFCSTATUS phNxpNciHal_resetEse(uint64_t resetType) {
660 NFCSTATUS status = NFCSTATUS_FAILED;
661
662 {
663 NfcHalAutoThreadMutex a(sHalFnLock);
664 if (nxpncihal_ctrl.halStatus == HAL_STATUS_CLOSE) {
665 if (NFCSTATUS_SUCCESS != phNxpNciHal_MinOpen()) {
666 return NFCSTATUS_FAILED;
667 }
668 }
669 }
670
671 CONCURRENCY_LOCK();
672 status = gpTransportObj->EseReset(gpphTmlNfc_Context->pDevHandle,
673 (EseResetType)resetType);
674 CONCURRENCY_UNLOCK();
675 if (status != NFCSTATUS_SUCCESS) {
676 NXPLOG_NCIHAL_E("EsePowerCycle failed");
677 }
678
679 if (nxpncihal_ctrl.halStatus == HAL_STATUS_MIN_OPEN) {
680 phNxpNciHal_close(false);
681 }
682
683 return status;
684 }
685
686 /*******************************************************************************
687 **
688 ** Function: phNxpNciHal_GetNfcGpiosStatus()
689 **
690 ** Description: Sets the gpios status flag byte
691 **
692 ** Parameters gpiostatus: flag byte
693 **
694 ** Returns: returns 0 on success, < 0 on failure
695 **
696 ********************************************************************************/
phNxpNciHal_GetNfcGpiosStatus(uint32_t * gpiosstatus)697 NFCSTATUS phNxpNciHal_GetNfcGpiosStatus(uint32_t* gpiosstatus) {
698 NFCSTATUS status = NFCSTATUS_FAILED;
699 status = gpTransportObj->NfcGetGpioStatus(gpphTmlNfc_Context->pDevHandle,
700 gpiosstatus);
701 return status;
702 }
703 /******************************************************************************
704 * Function phNxpNciHal_setNxpTransitConfig
705 *
706 * Description This function overwrite libnfc-nxpTransit.conf file
707 * with transitConfValue.
708 *
709 * Returns bool.
710 *
711 ******************************************************************************/
phNxpNciHal_setNxpTransitConfig(char * transitConfValue)712 bool phNxpNciHal_setNxpTransitConfig(char* transitConfValue) {
713 bool status = true;
714 NXPLOG_NCIHAL_D("%s : Enter", __func__);
715 std::string transitConfFileName = "/data/vendor/nfc/libnfc-nxpTransit.conf";
716 long transitConfValueLen = strlen(transitConfValue) + 1;
717
718 if (transitConfValueLen > 1) {
719 if (strncmp(transitConfValue, "UPDATE_", 7) == 0) {
720 if (IS_CHIP_TYPE_GE(sn220u) &&
721 phNxpNciHal_checkUpdateRfTransitConfig(transitConfValue)) {
722 NXPLOG_NCIHAL_D("%s :RfTransit values updated", __func__);
723 } else {
724 NXPLOG_NCIHAL_E("Failed to update RfTransit values");
725 status = false;
726 }
727 } else {
728 if (!WriteStringToFile(transitConfValue, transitConfFileName)) {
729 NXPLOG_NCIHAL_E("WriteStringToFile: Failed");
730 status = false;
731 }
732 }
733 } else {
734 if (!WriteStringToFile("", transitConfFileName)) {
735 NXPLOG_NCIHAL_E("WriteStringToFile: Failed");
736 status = false;
737 }
738 if (remove(transitConfFileName.c_str())) {
739 NXPLOG_NCIHAL_E("Unable to remove file");
740 status = false;
741 }
742 }
743 NXPLOG_NCIHAL_D("%s : Exit", __func__);
744 return status;
745 }
746
747 /******************************************************************************
748 ** Function phNxpNciHal_Abort
749 **
750 ** Description This function shall be used to trigger the abort in libnfc
751 **
752 ** Parameters None
753 **
754 ** Returns bool.
755 **
756 *******************************************************************************/
phNxpNciHal_Abort()757 bool phNxpNciHal_Abort() {
758 bool ret = true;
759
760 NXPLOG_NCIHAL_D("phNxpNciHal_Abort aborting. \n");
761 /* When JCOP download is triggered phNxpNciHal_open is blocked, in this case
762 only we need to abort the libnfc , this can be done only by check the
763 p_nfc_stack_cback_backup pointer which is assigned before the JCOP
764 download.*/
765 if (p_nfc_stack_cback_backup != NULL) {
766 (*p_nfc_stack_cback_backup)(HAL_NFC_OPEN_CPLT_EVT, HAL_NFC_STATUS_RESTART);
767 } else {
768 ret = false;
769 NXPLOG_NCIHAL_D("phNxpNciHal_Abort not triggered\n");
770 }
771 return ret;
772 }
773
774 /*******************************************************************************
775 **
776 ** Function: phNxpNciHal_CheckFwRegFlashRequired()
777 **
778 ** Description: Updates FW and Reg configurations if required
779 **
780 ** Returns: status
781 **
782 ********************************************************************************/
phNxpNciHal_CheckFwRegFlashRequired(uint8_t * fw_update_req,uint8_t * rf_update_req,uint8_t skipEEPROMRead)783 int phNxpNciHal_CheckFwRegFlashRequired(uint8_t* fw_update_req,
784 uint8_t* rf_update_req,
785 uint8_t skipEEPROMRead) {
786 NXPLOG_NCIHAL_D("phNxpNciHal_CheckFwRegFlashRequired() : enter");
787 int status = NFCSTATUS_OK;
788 long option;
789 if (fpRegRfFwDndl != NULL) {
790 status = fpRegRfFwDndl(fw_update_req, rf_update_req, skipEEPROMRead);
791 } else {
792 status = phDnldNfc_InitImgInfo();
793 NXPLOG_NCIHAL_D("FW version from the binary(.so/bin) = 0x%x", wFwVer);
794 NXPLOG_NCIHAL_D("FW version found on the device = 0x%x", wFwVerRsp);
795
796 if (!GetNxpNumValue(NAME_NXP_FLASH_CONFIG, &option,
797 sizeof(unsigned long))) {
798 NXPLOG_NCIHAL_D("Flash option not found; giving default value");
799 option = 1;
800 }
801 switch (option) {
802 case FLASH_UPPER_VERSION:
803 wFwUpdateReq = (utf8_t)wFwVer > (utf8_t)wFwVerRsp ? true : false;
804 break;
805 case FLASH_DIFFERENT_VERSION:
806 wFwUpdateReq = ((wFwVerRsp & 0x0000FFFF) != wFwVer) ? true : false;
807 break;
808 case FLASH_ALWAYS:
809 wFwUpdateReq = true;
810 break;
811 default:
812 NXPLOG_NCIHAL_D("Invalid flash option selected");
813 status = NFCSTATUS_INVALID_PARAMETER;
814 break;
815 }
816 }
817 *fw_update_req = wFwUpdateReq;
818
819 if (false == wFwUpdateReq) {
820 NXPLOG_NCIHAL_D("FW update not required");
821 phDnldNfc_ReSetHwDevHandle();
822 } else {
823 property_set("nfc.fw.downloadmode_force", "1");
824 }
825
826 NXPLOG_NCIHAL_D(
827 "phNxpNciHal_CheckFwRegFlashRequired() : exit - status = %x "
828 "wFwUpdateReq=%u, wRfUpdateReq=%u",
829 status, *fw_update_req, *rf_update_req);
830 return status;
831 }
832
833 /******************************************************************************
834 * Function phNxpNciHal_txNfccClockSetCmd
835 *
836 * Description This function is called after successful download
837 * to apply the clock setting provided in config file
838 *
839 * Returns void.
840 *
841 ******************************************************************************/
phNxpNciHal_txNfccClockSetCmd(void)842 void phNxpNciHal_txNfccClockSetCmd(void) {
843 NFCSTATUS status = NFCSTATUS_FAILED;
844
845 uint8_t set_clock_cmd[] = {0x20, 0x02, 0x05, 0x01, 0xA0, 0x03, 0x01, 0x08};
846 uint8_t setClkCmdLen = sizeof(set_clock_cmd);
847 unsigned long clockSource = 0;
848 unsigned long frequency = 0;
849 uint32_t pllSetRetryCount = 3, dpllSetRetryCount = 3,
850 setClockCmdWriteRetryCnt = 0;
851 uint8_t* pCmd4PllSetting = NULL;
852 uint8_t* pCmd4DpllSetting = NULL;
853 uint32_t pllCmdLen = 0, dpllCmdLen = 0;
854 int srcCfgFound = 0, freqCfgFound = 0;
855
856 srcCfgFound = (GetNxpNumValue(NAME_NXP_SYS_CLK_SRC_SEL, &clockSource,
857 sizeof(clockSource)) > 0);
858
859 freqCfgFound = (GetNxpNumValue(NAME_NXP_SYS_CLK_FREQ_SEL, &frequency,
860 sizeof(frequency)) > 0);
861
862 NXPLOG_NCIHAL_D("%s : clock source = %lu, frequency = %lu", __FUNCTION__,
863 clockSource, frequency);
864
865 if (srcCfgFound && freqCfgFound && (clockSource == CLK_SRC_PLL)) {
866 phNxpNciClock.isClockSet = TRUE;
867
868 switch (frequency) {
869 case CLK_FREQ_13MHZ: {
870 NXPLOG_NCIHAL_D("PLL setting for CLK_FREQ_13MHZ");
871 pCmd4PllSetting = (uint8_t*)PN557_SET_CONFIG_CMD_PLL_13MHZ;
872 pllCmdLen = sizeof(PN557_SET_CONFIG_CMD_PLL_13MHZ);
873 pCmd4DpllSetting = (uint8_t*)PN557_SET_CONFIG_CMD_DPLL_13MHZ;
874 dpllCmdLen = sizeof(PN557_SET_CONFIG_CMD_DPLL_13MHZ);
875 break;
876 }
877 case CLK_FREQ_19_2MHZ: {
878 NXPLOG_NCIHAL_D("PLL setting for CLK_FREQ_19_2MHZ");
879 pCmd4PllSetting = (uint8_t*)PN557_SET_CONFIG_CMD_PLL_19_2MHZ;
880 pllCmdLen = sizeof(PN557_SET_CONFIG_CMD_PLL_19_2MHZ);
881 pCmd4DpllSetting = (uint8_t*)PN557_SET_CONFIG_CMD_DPLL_19_2MHZ;
882 dpllCmdLen = sizeof(PN557_SET_CONFIG_CMD_DPLL_19_2MHZ);
883 break;
884 }
885 case CLK_FREQ_24MHZ: {
886 NXPLOG_NCIHAL_D("PLL setting for CLK_FREQ_24MHZ");
887 pCmd4PllSetting = (uint8_t*)PN557_SET_CONFIG_CMD_PLL_24MHZ;
888 pllCmdLen = sizeof(PN557_SET_CONFIG_CMD_PLL_24MHZ);
889 pCmd4DpllSetting = (uint8_t*)PN557_SET_CONFIG_CMD_DPLL_24MHZ;
890 dpllCmdLen = sizeof(PN557_SET_CONFIG_CMD_DPLL_24MHZ);
891 break;
892 }
893 case CLK_FREQ_26MHZ: {
894 NXPLOG_NCIHAL_D("PLL setting for CLK_FREQ_26MHZ");
895 pCmd4PllSetting = (uint8_t*)PN557_SET_CONFIG_CMD_PLL_26MHZ;
896 pllCmdLen = sizeof(PN557_SET_CONFIG_CMD_PLL_26MHZ);
897 pCmd4DpllSetting = (uint8_t*)PN557_SET_CONFIG_CMD_DPLL_26MHZ;
898 dpllCmdLen = sizeof(PN557_SET_CONFIG_CMD_DPLL_26MHZ);
899 break;
900 }
901 case CLK_FREQ_32MHZ: {
902 NXPLOG_NCIHAL_D("PLL setting for CLK_FREQ_32MHZ");
903 pCmd4PllSetting = (uint8_t*)PN557_SET_CONFIG_CMD_PLL_32MHZ;
904 pllCmdLen = sizeof(PN557_SET_CONFIG_CMD_PLL_32MHZ);
905 pCmd4DpllSetting = (uint8_t*)PN557_SET_CONFIG_CMD_DPLL_32MHZ;
906 dpllCmdLen = sizeof(PN557_SET_CONFIG_CMD_DPLL_32MHZ);
907 break;
908 }
909 case CLK_FREQ_38_4MHZ: {
910 NXPLOG_NCIHAL_D("PLL setting for CLK_FREQ_38_4MHZ");
911 pCmd4PllSetting = (uint8_t*)PN557_SET_CONFIG_CMD_PLL_38_4MHZ;
912 pllCmdLen = sizeof(PN557_SET_CONFIG_CMD_PLL_38_4MHZ);
913 pCmd4DpllSetting = (uint8_t*)PN557_SET_CONFIG_CMD_DPLL_38_4MHZ;
914 dpllCmdLen = sizeof(PN557_SET_CONFIG_CMD_DPLL_38_4MHZ);
915 break;
916 }
917 case CLK_FREQ_48MHZ: {
918 NXPLOG_NCIHAL_D("PLL setting for CLK_FREQ_48MHZ");
919 pCmd4PllSetting = (uint8_t*)PN557_SET_CONFIG_CMD_PLL_48MHZ;
920 pllCmdLen = sizeof(PN557_SET_CONFIG_CMD_PLL_48MHZ);
921 pCmd4DpllSetting = (uint8_t*)PN557_SET_CONFIG_CMD_DPLL_48MHZ;
922 dpllCmdLen = sizeof(PN557_SET_CONFIG_CMD_DPLL_48MHZ);
923 break;
924 }
925 default:
926 phNxpNciClock.isClockSet = FALSE;
927 NXPLOG_NCIHAL_E("ERROR: Invalid clock frequency!!");
928 return;
929 }
930 }
931 switch (clockSource) {
932 case CLK_SRC_PLL: {
933 set_clock_cmd[setClkCmdLen - 1] = 0x00;
934 while (status != NFCSTATUS_SUCCESS &&
935 setClockCmdWriteRetryCnt++ < MAX_RETRY_COUNT)
936 status = phNxpNciHal_send_ext_cmd(setClkCmdLen, set_clock_cmd);
937
938 status = NFCSTATUS_FAILED;
939
940 while (status != NFCSTATUS_SUCCESS && pllSetRetryCount-- > 0)
941 status = phNxpNciHal_send_ext_cmd(pllCmdLen, pCmd4PllSetting);
942
943 status = NFCSTATUS_FAILED;
944
945 while (status != NFCSTATUS_SUCCESS && dpllSetRetryCount-- > 0)
946 status = phNxpNciHal_send_ext_cmd(dpllCmdLen, pCmd4DpllSetting);
947
948 break;
949 }
950 case CLK_SRC_XTAL: {
951 status = phNxpNciHal_send_ext_cmd(setClkCmdLen, set_clock_cmd);
952 if (status != NFCSTATUS_SUCCESS) {
953 NXPLOG_NCIHAL_E("XTAL clock setting failed !!");
954 }
955 break;
956 }
957 default:
958 NXPLOG_NCIHAL_E("Wrong clock source. Don't apply any modification");
959 return;
960 }
961 phNxpNciClock.isClockSet = FALSE;
962 if (status == NFCSTATUS_SUCCESS &&
963 phNxpNciClock.p_rx_data[3] == NFCSTATUS_SUCCESS) {
964 NXPLOG_NCIHAL_D("PLL and DPLL settings applied successfully");
965 }
966 return;
967 }
968
969 /*******************************************************************************
970 **
971 ** Function phNxpNciHal_updateRfSetConfig
972 **
973 ** Description Update the set RF settings.
974 **
975 ** Parameters setConfCmd - Update the set config buffer based on getConfig
976 ** getResData - Response data.
977 ** Returns True/False
978 *******************************************************************************/
phNxpNciHal_updateRfSetConfig(vector<uint8_t> & setConfCmd,vector<uint8_t> & getResData)979 bool phNxpNciHal_updateRfSetConfig(vector<uint8_t>& setConfCmd,
980 vector<uint8_t>& getResData) {
981 uint8_t res_data_packet_len = 0;
982 if ((getResData.size() <= 5) ||
983 (getResData.size() !=
984 (getResData[NCI_PACKET_LEN_INDEX] + NCI_HEADER_SIZE))) {
985 NXPLOG_NCIHAL_E("%s : Invalid res data length", __FUNCTION__);
986 return false;
987 }
988 /*Updating the actual TLV packet length by excluding the status & tlv bytes */
989 res_data_packet_len = getResData[NCI_PACKET_LEN_INDEX] - 2;
990 /*Copying the TLV packet and excluding NCI header, status & tlv bytes*/
991 setConfCmd.insert(setConfCmd.end(), getResData.begin() + 5, getResData.end());
992 if (setConfCmd.size() >= 0xFF) {
993 if (NFCSTATUS_SUCCESS !=
994 phNxpNciHal_send_ext_cmd((setConfCmd.size() - res_data_packet_len),
995 &setConfCmd[0])) {
996 NXPLOG_NCIHAL_E("%s : Set config failed", __FUNCTION__);
997 return false;
998 }
999 // Clear setConf Data expect the last command response.
1000 setConfCmd.erase(setConfCmd.begin() + 4,
1001 setConfCmd.end() - res_data_packet_len);
1002 // Clear the length and TLV after sending the packet.
1003 setConfCmd[NCI_PACKET_LEN_INDEX] = 0x01;
1004 setConfCmd[NCI_PACKET_TLV_INDEX] = 0x00;
1005 }
1006 setConfCmd[NCI_PACKET_LEN_INDEX] += res_data_packet_len;
1007 setConfCmd[NCI_PACKET_TLV_INDEX] += getResData[NCI_GET_RES_TLV_INDEX];
1008
1009 return true;
1010 }
1011 /*******************************************************************************
1012 **
1013 ** Function phNxpNciHal_getUpdatePropRfSetConfig
1014 **
1015 ** Description Get and update the Prop RF settings.
1016 **
1017 ** Parameters IndexValue poniting to the vector
1018 ** NewValue - To be update at the index position
1019 ** propCmdresData - Update the prop response buffer based on
1020 ** prop getConfig response.
1021 ** Returns bool value true/false
1022 *******************************************************************************/
phNxpNciHal_getUpdatePropRfSetConfig(unsigned newValue,vector<uint8_t> & propCmdresData)1023 bool phNxpNciHal_getUpdatePropRfSetConfig(unsigned newValue,
1024 vector<uint8_t>& propCmdresData) {
1025 vector<uint8_t> prop_cmd_get_rftxval{0x2F, 0x14, 0x02, 0x62, 0x32};
1026 uint8_t getPropRfCount = 0;
1027 uint8_t index = 10; // Index for RF register 6232
1028 do {
1029 if (NFCSTATUS_SUCCESS !=
1030 phNxpNciHal_send_ext_cmd(prop_cmd_get_rftxval.size(),
1031 &prop_cmd_get_rftxval[0])) {
1032 NXPLOG_NCIHAL_E("%s : Get config failed for A00D", __FUNCTION__);
1033 return false;
1034 }
1035 if (GET_RES_STATUS_CHECK(nxpncihal_ctrl.rx_data_len,
1036 nxpncihal_ctrl.p_rx_data)) {
1037 NXPLOG_NCIHAL_E("%s : Get response failed", __FUNCTION__);
1038 return false;
1039 }
1040 if (nxpncihal_ctrl.p_rx_data[RF_CM_TX_UNDERSHOOT_INDEX] == newValue)
1041 return true;
1042
1043 // Mapping Prop command response to NCI command response.
1044 propCmdresData[index] = (uint8_t)(newValue & BYTE0_SHIFT_MASK);
1045 propCmdresData[index + 1] =
1046 nxpncihal_ctrl.p_rx_data[RF_CM_TX_UNDERSHOOT_INDEX + 1];
1047 propCmdresData[index + 2] =
1048 nxpncihal_ctrl.p_rx_data[RF_CM_TX_UNDERSHOOT_INDEX + 2];
1049 propCmdresData[index + 3] =
1050 nxpncihal_ctrl.p_rx_data[RF_CM_TX_UNDERSHOOT_INDEX + 3];
1051
1052 getPropRfCount++;
1053 if (getPropRfCount == 1) {
1054 index = 19; // Index for RF register 6732
1055 prop_cmd_get_rftxval[NCI_PACKET_TLV_INDEX] = 0x67;
1056 }
1057 } while (getPropRfCount < 2);
1058
1059 return true;
1060 }
1061
1062 /*******************************************************************************
1063 **
1064 ** Function phNxpNciHal_checkUpdateRfTransitConfig
1065 **
1066 ** Description Check and update selected RF settings dynamically.
1067 **
1068 ** Parameters char config
1069 **
1070 ** Returns bool value true/false
1071 *******************************************************************************/
phNxpNciHal_checkUpdateRfTransitConfig(const char * config)1072 bool phNxpNciHal_checkUpdateRfTransitConfig(const char* config) {
1073 vector<uint8_t> cmd_get_rfconfval{0x20, 0x03, 0x03, 0x01, 0xA0, 0x85};
1074 vector<uint8_t> cmd_response{};
1075 vector<uint8_t> lpdet_cmd_response{};
1076 vector<uint8_t> get_cmd_response{};
1077 vector<uint8_t> cmd_set_rfconfval{0x20, 0x02, 0x01, 0x00};
1078 vector<uint8_t> prop_Cmd_Response{
1079 /*Preset get config response for A00D register*/
1080 0x40, 0x03, 0x14, 0x00, 0x02, 0xA0, 0x0D, 0x06, 0x62, 0x32, 0xAE, 0x00,
1081 0x7F, 0x00, 0xA0, 0x0D, 0x06, 0x67, 0x32, 0xAE, 0x00, 0x1F, 0x00};
1082 bool is_feature_update_required = false;
1083 bool is_lpdet_threshold_required = false;
1084 uint8_t index_to_value = 0;
1085 uint8_t update_mode = BITWISE;
1086 uint8_t condition = 0;
1087 stringstream key_value_pairs(config);
1088 string single_key_value;
1089 unsigned b_position = 0;
1090 unsigned new_value = 0;
1091 unsigned read_value = 0;
1092 unsigned rf_reg_A085_value = 0;
1093
1094 NXPLOG_NCIHAL_D("%s : Enter", __FUNCTION__);
1095
1096 if (NFCSTATUS_SUCCESS != phNxpNciHal_send_ext_cmd(cmd_get_rfconfval.size(),
1097 &cmd_get_rfconfval[0])) {
1098 NXPLOG_NCIHAL_E("%s : Get config failed for A085", __FUNCTION__);
1099 return false;
1100 }
1101 if (GET_RES_STATUS_CHECK(nxpncihal_ctrl.rx_data_len,
1102 nxpncihal_ctrl.p_rx_data)) {
1103 NXPLOG_NCIHAL_E("%s : Get config failed", __FUNCTION__);
1104 return false;
1105 }
1106 // Updating the A085 get config command response to vector.
1107 cmd_response.insert(
1108 cmd_response.end(), &nxpncihal_ctrl.p_rx_data[0],
1109 (&nxpncihal_ctrl.p_rx_data[0] +
1110 (nxpncihal_ctrl.p_rx_data[NCI_PACKET_LEN_INDEX] + NCI_HEADER_SIZE)));
1111 rf_reg_A085_value = (unsigned)((cmd_response[REG_A085_DATA_INDEX + 3] << 24) |
1112 (cmd_response[REG_A085_DATA_INDEX + 2] << 16) |
1113 (cmd_response[REG_A085_DATA_INDEX + 1] << 8) |
1114 (cmd_response[REG_A085_DATA_INDEX]));
1115
1116 cmd_get_rfconfval[NCI_GET_CMD_TLV_INDEX2] = 0x9E;
1117 if (NFCSTATUS_SUCCESS != phNxpNciHal_send_ext_cmd(cmd_get_rfconfval.size(),
1118 &cmd_get_rfconfval[0])) {
1119 NXPLOG_NCIHAL_E("%s : Get config failed for A09E", __FUNCTION__);
1120 return false;
1121 }
1122 if (GET_RES_STATUS_CHECK(nxpncihal_ctrl.rx_data_len,
1123 nxpncihal_ctrl.p_rx_data)) {
1124 NXPLOG_NCIHAL_E("%s : Get config failed", __FUNCTION__);
1125 return false;
1126 }
1127 // Updating the A09E get config command response to vector.
1128 lpdet_cmd_response.insert(
1129 lpdet_cmd_response.end(), &nxpncihal_ctrl.p_rx_data[0],
1130 (&nxpncihal_ctrl.p_rx_data[0] +
1131 (nxpncihal_ctrl.p_rx_data[NCI_PACKET_LEN_INDEX] + NCI_HEADER_SIZE)));
1132
1133 while (getline(key_value_pairs, single_key_value)) {
1134 auto search = single_key_value.find('=');
1135 if (search == string::npos) continue;
1136
1137 string key(Trim(single_key_value.substr(0, search)));
1138 string value(Trim(single_key_value.substr(search + 1, string::npos)));
1139 ParseUint(value.c_str(), &new_value);
1140 update_mode = BITWISE;
1141 NXPLOG_NCIHAL_D("%s : Update Key = %s Value: %02x", __FUNCTION__,
1142 key.c_str(), new_value);
1143 auto it = tokenMap.find(key);
1144 if (it != tokenMap.end()) {
1145 condition = it->second;
1146 } else
1147 condition = UPDATE_UNKNOWN;
1148
1149 switch (condition) {
1150 case UPDATE_DLMA_ID_TX_ENTRY:
1151 cmd_get_rfconfval[NCI_GET_CMD_TLV_INDEX1] = 0xA0;
1152 cmd_get_rfconfval[NCI_GET_CMD_TLV_INDEX2] = 0x34;
1153 index_to_value = DLMA_ID_TX_ENTRY_INDEX;
1154 break;
1155 case UPDATE_RF_CM_TX_UNDERSHOOT_CONFIG:
1156 if (!phNxpNciHal_getUpdatePropRfSetConfig(new_value, prop_Cmd_Response))
1157 return false;
1158
1159 if ((nxpncihal_ctrl.rx_data_len > RF_CM_TX_UNDERSHOOT_INDEX) &&
1160 (nxpncihal_ctrl.p_rx_data[RF_CM_TX_UNDERSHOOT_INDEX] !=
1161 new_value)) {
1162 if (!phNxpNciHal_updateRfSetConfig(cmd_set_rfconfval,
1163 prop_Cmd_Response))
1164 return false;
1165 }
1166 break;
1167 case UPDATE_INITIAL_TX_PHASE:
1168 cmd_get_rfconfval[NCI_GET_CMD_TLV_INDEX1] = 0xA0;
1169 cmd_get_rfconfval[NCI_GET_CMD_TLV_INDEX2] = 0x6A;
1170 index_to_value = INITIAL_TX_PHASE_INDEX;
1171 update_mode = BYTEWISE;
1172 break;
1173 case UPDATE_LPDET_THRESHOLD:
1174 read_value = 0;
1175 read_value = lpdet_cmd_response[LPDET_THRESHOLD_INDEX];
1176 read_value |= (lpdet_cmd_response[LPDET_THRESHOLD_INDEX + 1] << 8);
1177 NXPLOG_NCIHAL_D("%s : read_value = %02x Value: %02x", __FUNCTION__,
1178 read_value, new_value);
1179 if (read_value != new_value) {
1180 lpdet_cmd_response[LPDET_THRESHOLD_INDEX] =
1181 (uint8_t)(new_value & BYTE0_SHIFT_MASK);
1182 lpdet_cmd_response[LPDET_THRESHOLD_INDEX + 1] =
1183 (uint8_t)((new_value & BYTE1_SHIFT_MASK) >> 8);
1184 is_lpdet_threshold_required = true;
1185 }
1186 break;
1187 case UPDATE_NFCLD_THRESHOLD:
1188 read_value = 0;
1189 read_value = lpdet_cmd_response[NFCLD_THRESHOLD_INDEX];
1190 read_value |= (lpdet_cmd_response[NFCLD_THRESHOLD_INDEX + 1] << 8);
1191 NXPLOG_NCIHAL_D("%s : read_value = %02x Value: %02x", __FUNCTION__,
1192 read_value, new_value);
1193 if (read_value != new_value) {
1194 lpdet_cmd_response[NFCLD_THRESHOLD_INDEX] =
1195 (uint8_t)(new_value & BYTE0_SHIFT_MASK);
1196 lpdet_cmd_response[NFCLD_THRESHOLD_INDEX + 1] =
1197 (uint8_t)((new_value & BYTE1_SHIFT_MASK) >> 8);
1198 is_lpdet_threshold_required = true;
1199 }
1200 break;
1201 case UPDATE_GUARD_TIMEOUT_TX2RX:
1202 cmd_get_rfconfval[NCI_GET_CMD_TLV_INDEX1] = 0xA1;
1203 cmd_get_rfconfval[NCI_GET_CMD_TLV_INDEX2] = 0x0E;
1204 index_to_value = GUARD_TIMEOUT_TX2RX_INDEX;
1205 break;
1206 case UPDATE_RF_PATTERN_CHK:
1207 cmd_get_rfconfval[NCI_GET_CMD_TLV_INDEX1] = 0xA1;
1208 cmd_get_rfconfval[NCI_GET_CMD_TLV_INDEX2] = 0x48;
1209 index_to_value = RF_PATTERN_CHK_INDEX;
1210 break;
1211 case UPDATE_MIFARE_NACK_TO_RATS_ENABLE:
1212 case UPDATE_MIFARE_MUTE_TO_RATS_ENABLE:
1213 case UPDATE_CHINA_TIANJIN_RF_ENABLED:
1214 case UPDATE_CN_TRANSIT_CMA_BYPASSMODE_ENABLE:
1215 case UPDATE_CN_TRANSIT_BLK_NUM_CHECK_ENABLE: {
1216 auto itReg = rfReg_A085_Map.find(condition);
1217 if (itReg == rfReg_A085_Map.end()) continue;
1218
1219 NXPLOG_NCIHAL_D("%s : Reg A085 Update Key = %s and Bit Position: %d",
1220 __FUNCTION__, key.c_str(), itReg->second);
1221 b_position = (unsigned)(0x01 << itReg->second);
1222 if ((rf_reg_A085_value & b_position) !=
1223 ((new_value & 0x01) << itReg->second)) {
1224 rf_reg_A085_value ^= (1 << itReg->second);
1225 is_feature_update_required = true;
1226 }
1227 } break;
1228 case UPDATE_PHONEOFF_TECH_DISABLE:
1229 cmd_get_rfconfval[NCI_GET_CMD_TLV_INDEX1] = 0xA1;
1230 cmd_get_rfconfval[NCI_GET_CMD_TLV_INDEX2] = 0x1A;
1231 index_to_value = PHONEOFF_TECH_DISABLE_INDEX;
1232 break;
1233 case UPDATE_ISO_DEP_MERGE_SAK:
1234 cmd_get_rfconfval[NCI_GET_CMD_TLV_INDEX1] = 0xA1;
1235 cmd_get_rfconfval[NCI_GET_CMD_TLV_INDEX2] = 0x1B;
1236 index_to_value = ISO_DEP_MERGE_SAK_INDEX;
1237 break;
1238 default:
1239 NXPLOG_NCIHAL_D("%s : default = %x", __FUNCTION__, new_value);
1240 break;
1241 }
1242 if (index_to_value) {
1243 if (NFCSTATUS_SUCCESS !=
1244 phNxpNciHal_send_ext_cmd(cmd_get_rfconfval.size(),
1245 &cmd_get_rfconfval[0])) {
1246 NXPLOG_NCIHAL_E("%s : Get config failed for %s", __FUNCTION__,
1247 key.c_str());
1248 return false;
1249 }
1250 if (GET_RES_STATUS_CHECK(nxpncihal_ctrl.rx_data_len,
1251 nxpncihal_ctrl.p_rx_data)) {
1252 NXPLOG_NCIHAL_E("%s : Get config response failed ", __FUNCTION__);
1253 return false;
1254 }
1255 read_value = 0;
1256 read_value = nxpncihal_ctrl.p_rx_data[index_to_value];
1257 if (update_mode == BYTEWISE)
1258 read_value |= (nxpncihal_ctrl.p_rx_data[index_to_value + 1] << 8);
1259 if (read_value == new_value) {
1260 index_to_value = 0;
1261 continue;
1262 }
1263 nxpncihal_ctrl.p_rx_data[index_to_value] =
1264 (uint8_t)(new_value & BYTE0_SHIFT_MASK);
1265 if (update_mode == BYTEWISE)
1266 nxpncihal_ctrl.p_rx_data[index_to_value + 1] =
1267 (uint8_t)((new_value & BYTE1_SHIFT_MASK) >> 8);
1268
1269 // Updating the get config command response to vector.
1270 get_cmd_response.insert(
1271 get_cmd_response.end(), &nxpncihal_ctrl.p_rx_data[0],
1272 (&nxpncihal_ctrl.p_rx_data[0] +
1273 (nxpncihal_ctrl.p_rx_data[NCI_PACKET_LEN_INDEX] + NCI_HEADER_SIZE)));
1274 if (!phNxpNciHal_updateRfSetConfig(cmd_set_rfconfval, get_cmd_response))
1275 return false;
1276
1277 get_cmd_response.clear();
1278 index_to_value = 0;
1279 }
1280 }
1281 if (is_feature_update_required) {
1282 // Updating the A085 response to set config command.
1283 cmd_response[REG_A085_DATA_INDEX + 3] =
1284 (uint8_t)((rf_reg_A085_value & BYTE3_SHIFT_MASK) >> 24);
1285 cmd_response[REG_A085_DATA_INDEX + 2] =
1286 (uint8_t)((rf_reg_A085_value & BYTE2_SHIFT_MASK) >> 16);
1287 cmd_response[REG_A085_DATA_INDEX + 1] =
1288 (uint8_t)((rf_reg_A085_value & BYTE1_SHIFT_MASK) >> 8);
1289 cmd_response[REG_A085_DATA_INDEX] =
1290 (uint8_t)(rf_reg_A085_value & BYTE0_SHIFT_MASK);
1291 if (!phNxpNciHal_updateRfSetConfig(cmd_set_rfconfval, cmd_response))
1292 return false;
1293 }
1294 if (is_lpdet_threshold_required) {
1295 // Updating the A09E response to set config command.
1296 if (!phNxpNciHal_updateRfSetConfig(cmd_set_rfconfval, lpdet_cmd_response))
1297 return false;
1298 }
1299 if (cmd_set_rfconfval.size() <= NCI_HEADER_SIZE) {
1300 NXPLOG_NCIHAL_E("%s : Invalid NCI Command length = %zu", __FUNCTION__,
1301 cmd_set_rfconfval.size());
1302 return false;
1303 }
1304 if (cmd_set_rfconfval[NCI_PACKET_TLV_INDEX] != 0x00) {
1305 /*If update require do set-config in NFCC otherwise skip */
1306 if (NFCSTATUS_SUCCESS == phNxpNciHal_send_ext_cmd(cmd_set_rfconfval.size(),
1307 &cmd_set_rfconfval[0])) {
1308 if (is_feature_update_required) {
1309 if (NFCSTATUS_SUCCESS != phNxpNciHal_ext_send_sram_config_to_flash()) {
1310 NXPLOG_NCIHAL_E("%s :Updation of the SRAM contents failed",
1311 __FUNCTION__);
1312 return false;
1313 }
1314 }
1315 } else {
1316 NXPLOG_NCIHAL_D("Set RF update cmd is failed..");
1317 return false;
1318 }
1319 }
1320 return true;
1321 }
1322