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
19 /******************************************************************************
20 *
21 * The original Work has been changed by NXP.
22 *
23 * Licensed under the Apache License, Version 2.0 (the "License");
24 * you may not use this file except in compliance with the License.
25 * You may obtain a copy of the License at
26 *
27 * http://www.apache.org/licenses/LICENSE-2.0
28 *
29 * Unless required by applicable law or agreed to in writing, software
30 * distributed under the License is distributed on an "AS IS" BASIS,
31 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
32 * See the License for the specific language governing permissions and
33 * limitations under the License.
34 *
35 * Copyright 2013-2021, 2023 NXP
36 *
37 ******************************************************************************/
38
39 #include <android-base/properties.h>
40 #include <errno.h>
41 #include <log/log.h>
42 #include <phDnldNfc_Internal.h>
43 #include <phNxpConfig.h>
44 #include <phNxpLog.h>
45 #include <stdio.h>
46 #include <sys/stat.h>
47
48 #include <list>
49 #include <string>
50 #include <vector>
51
52 #include "sparse_crc32.h"
53 #if GENERIC_TARGET
54 const char alternative_config_path[] = "/data/vendor/nfc/";
55 #else
56 const char alternative_config_path[] = "";
57 #endif
58
59 #if 1
60 const char* transport_config_paths[] = {"/odm/etc/", "/vendor/etc/", "/etc/"};
61 #else
62 const char* transport_config_paths[] = {"res/"};
63 #endif
64 const int transport_config_path_size =
65 (sizeof(transport_config_paths) / sizeof(transport_config_paths[0]));
66
67 #define config_name "libnfc-nxp.conf"
68 #define extra_config_base "libnfc-"
69 #define extra_config_ext ".conf"
70 #define IsStringValue 0x80000000
71
72 typedef enum {
73 CONF_FILE_NXP = 0x00,
74 CONF_FILE_NXP_RF,
75 CONF_FILE_NXP_TRANSIT
76 } tNXP_CONF_FILE;
77
78 const char rf_config_timestamp_path[] =
79 "/data/vendor/nfc/libnfc-nxpRFConfigState.bin";
80 const char tr_config_timestamp_path[] =
81 "/data/vendor/nfc/libnfc-nxpTransitConfigState.bin";
82 const char config_timestamp_path[] =
83 "/data/vendor/nfc/libnfc-nxpConfigState.bin";
84 /*const char default_nxp_config_path[] =
85 "/vendor/etc/libnfc-nxp.conf";*/
86 char nxp_rf_config_path[256] = "/system/vendor/libnfc-nxp_RF.conf";
87 #if (defined(__arm64__) || defined(__aarch64__) || defined(_M_ARM64))
88 char Fw_Lib_Path[256] = "/vendor/lib64/libsn100u_fw.so";
89 #else
90 char Fw_Lib_Path[256] = "/vendor/lib/libsn100u_fw.so";
91 #endif
92
93 const char transit_config_path[] = "/data/vendor/nfc/libnfc-nxpTransit.conf";
94 void readOptionalConfig(const char* optional);
95
readConfigFile(const char * fileName,uint8_t ** p_data)96 size_t readConfigFile(const char* fileName, uint8_t** p_data) {
97 FILE* fd = fopen(fileName, "rb");
98 if (fd == nullptr) return 0;
99
100 fseek(fd, 0L, SEEK_END);
101 const size_t file_size = ftell(fd);
102 rewind(fd);
103 if ((long)file_size < 0) {
104 ALOGE("%s Invalid file size file_size = %zu\n", __func__, file_size);
105 fclose(fd);
106 return 0;
107 }
108 uint8_t* buffer = new uint8_t[file_size + 1];
109 if (!buffer) {
110 fclose(fd);
111 return 0;
112 }
113 size_t read = fread(buffer, file_size, 1, fd);
114 fclose(fd);
115
116 if (read == 1) {
117 buffer[file_size] = '\n';
118 *p_data = buffer;
119 return file_size + 1;
120 }
121 delete[] buffer;
122 return 0;
123 }
124
125 using namespace ::std;
126
127 class CNfcParam : public string {
128 public:
129 CNfcParam();
130 CNfcParam(const char* name, const string& value);
131 CNfcParam(const char* name, unsigned long value);
132 virtual ~CNfcParam();
numValue() const133 unsigned long numValue() const { return m_numValue; }
str_value() const134 const char* str_value() const { return m_str_value.c_str(); }
str_len() const135 size_t str_len() const { return m_str_value.length(); }
136
137 private:
138 string m_str_value;
139 unsigned long m_numValue;
140 };
141
142 class CNfcConfig : public vector<const CNfcParam*> {
143 public:
144 virtual ~CNfcConfig();
145 static CNfcConfig& GetInstance();
146 friend void readOptionalConfig(const char* optional);
147 bool isModified(tNXP_CONF_FILE aType);
148 void resetModified(tNXP_CONF_FILE aType);
149
150 bool getValue(const char* name, char* pValue, size_t len) const;
151 bool getValue(const char* name, unsigned long& rValue) const;
152 bool getValue(const char* name, unsigned short& rValue) const;
153 bool getValue(const char* name, char* pValue, long len, long* readlen) const;
154 const CNfcParam* find(const char* p_name) const;
155 void readNxpTransitConfig(const char* fileName) const;
156 void readNxpRFConfig(const char* fileName) const;
157 void clean();
158
159 private:
160 CNfcConfig();
161 bool readConfig(const char* name, bool bResetContent);
162 void moveFromList();
163 void moveToList();
164 void add(const CNfcParam* pParam);
165 void dump();
166 bool isAllowed(const char* name);
167 list<const CNfcParam*> m_list;
168 bool mValidFile;
169 uint32_t config_crc32_;
170 uint32_t config_rf_crc32_;
171 uint32_t config_tr_crc32_;
172 string mCurrentFile;
173
174 unsigned long state;
175
Is(unsigned long f)176 inline bool Is(unsigned long f) { return (state & f) == f; }
Set(unsigned long f)177 inline void Set(unsigned long f) { state |= f; }
Reset(unsigned long f)178 inline void Reset(unsigned long f) { state &= ~f; }
179 };
180
181 /*******************************************************************************
182 **
183 ** Function: isPrintable()
184 **
185 ** Description: determine if 'c' is printable
186 **
187 ** Returns: 1, if printable, otherwise 0
188 **
189 *******************************************************************************/
isPrintable(char c)190 inline bool isPrintable(char c) {
191 return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') ||
192 (c >= '0' && c <= '9') || c == '/' || c == '_' || c == '-' || c == '.';
193 }
194
195 /*******************************************************************************
196 **
197 ** Function: isDigit()
198 **
199 ** Description: determine if 'c' is numeral digit
200 **
201 ** Returns: true, if numerical digit
202 **
203 *******************************************************************************/
isDigit(char c,int base)204 inline bool isDigit(char c, int base) {
205 if ('0' <= c && c <= '9') return true;
206 if (base == 16) {
207 if (('A' <= c && c <= 'F') || ('a' <= c && c <= 'f')) return true;
208 }
209 return false;
210 }
211
212 /*******************************************************************************
213 **
214 ** Function: getDigitValue()
215 **
216 ** Description: return numerical value of a decimal or hex char
217 **
218 ** Returns: numerical value if decimal or hex char, otherwise 0
219 **
220 *******************************************************************************/
getDigitValue(char c,int base)221 inline int getDigitValue(char c, int base) {
222 if ('0' <= c && c <= '9') return c - '0';
223 if (base == 16) {
224 if ('A' <= c && c <= 'F')
225 return c - 'A' + 10;
226 else if ('a' <= c && c <= 'f')
227 return c - 'a' + 10;
228 }
229 return 0;
230 }
231
232 /*******************************************************************************
233 **
234 ** Function: findConfigFilePathFromTransportConfigPaths()
235 **
236 ** Description: find a config file path with a given config name from transport
237 ** config paths
238 **
239 ** Returns: none
240 **
241 *******************************************************************************/
findConfigFilePathFromTransportConfigPaths(const string & configName,string & filePath)242 bool findConfigFilePathFromTransportConfigPaths(const string& configName,
243 string& filePath) {
244 for (int i = 0; i < transport_config_path_size - 1; i++) {
245 if (configName.empty()) break;
246 filePath.assign(transport_config_paths[i]);
247 filePath += configName;
248 struct stat file_stat;
249 if (stat(filePath.c_str(), &file_stat) == 0 && S_ISREG(file_stat.st_mode)) {
250 return true;
251 }
252 }
253 filePath = "";
254 return false;
255 }
256
257 /*******************************************************************************
258 **
259 ** Function: CNfcConfig::readConfig()
260 **
261 ** Description: read Config settings and parse them into a linked list
262 ** move the element from linked list to a array at the end
263 **
264 ** Returns: 1, if there are any config data, 0 otherwise
265 **
266 *******************************************************************************/
readConfig(const char * name,bool bResetContent)267 bool CNfcConfig::readConfig(const char* name, bool bResetContent) {
268 enum {
269 BEGIN_LINE = 1,
270 TOKEN,
271 STR_VALUE,
272 NUM_VALUE,
273 BEGIN_HEX,
274 BEGIN_QUOTE,
275 END_LINE
276 };
277
278 uint8_t* p_config = nullptr;
279 size_t config_size = readConfigFile(name, &p_config);
280 if (p_config == nullptr) {
281 ALOGE("%s Cannot open config file %s\n", __func__, name);
282 if (bResetContent) {
283 ALOGE("%s Using default value for all settings\n", __func__);
284 mValidFile = false;
285 }
286 return false;
287 }
288
289 string token;
290 string strValue;
291 unsigned long numValue = 0;
292 CNfcParam* pParam = NULL;
293 int i = 0;
294 int base = 0;
295 char c;
296 int bflag = 0;
297 state = BEGIN_LINE;
298
299 ALOGD("readConfig; filename is %s", name);
300 if (strcmp(name, nxp_rf_config_path) == 0) {
301 config_rf_crc32_ = sparse_crc32(0, (const void*)p_config, (int)config_size);
302 } else if (strcmp(name, transit_config_path) == 0) {
303 config_tr_crc32_ = sparse_crc32(0, (const void*)p_config, (int)config_size);
304 } else {
305 config_crc32_ = sparse_crc32(0, (const void*)p_config, (int)config_size);
306 }
307
308 mValidFile = true;
309 if (size() > 0) {
310 if (bResetContent)
311 clean();
312 else
313 moveToList();
314 }
315
316 for (size_t offset = 0; offset != config_size; ++offset) {
317 c = p_config[offset];
318 switch (state & 0xff) {
319 case BEGIN_LINE:
320 if (c == '#')
321 state = END_LINE;
322 else if (isPrintable(c)) {
323 i = 0;
324 token.erase();
325 strValue.erase();
326 state = TOKEN;
327 token.push_back(c);
328 }
329 break;
330 case TOKEN:
331 if (c == '=') {
332 token.push_back('\0');
333 state = BEGIN_QUOTE;
334 } else if (isPrintable(c))
335 token.push_back(c);
336 else
337 state = END_LINE;
338 break;
339 case BEGIN_QUOTE:
340 if (c == '"') {
341 state = STR_VALUE;
342 base = 0;
343 } else if (c == '0')
344 state = BEGIN_HEX;
345 else if (isDigit(c, 10)) {
346 state = NUM_VALUE;
347 base = 10;
348 numValue = getDigitValue(c, base);
349 i = 0;
350 } else if (c == '{') {
351 state = NUM_VALUE;
352 bflag = 1;
353 base = 16;
354 i = 0;
355 Set(IsStringValue);
356 } else
357 state = END_LINE;
358 break;
359 case BEGIN_HEX:
360 if (c == 'x' || c == 'X') {
361 state = NUM_VALUE;
362 base = 16;
363 numValue = 0;
364 i = 0;
365 break;
366 } else if (isDigit(c, 10)) {
367 state = NUM_VALUE;
368 base = 10;
369 numValue = getDigitValue(c, base);
370 break;
371 } else if (c != '\n' && c != '\r') {
372 state = END_LINE;
373 break;
374 }
375 // fall through to numValue to handle numValue
376 [[fallthrough]];
377 case NUM_VALUE:
378 if (isDigit(c, base)) {
379 numValue *= base;
380 numValue += getDigitValue(c, base);
381 ++i;
382 } else if (bflag == 1 &&
383 (c == ' ' || c == '\r' || c == '\n' || c == '\t')) {
384 break;
385 } else if (base == 16 &&
386 (c == ',' || c == ':' || c == '-' || c == ' ' || c == '}')) {
387 if (c == '}') {
388 bflag = 0;
389 }
390 if (i > 0) {
391 int n = (i + 1) / 2;
392 while (n-- > 0) {
393 numValue = numValue >> (n * 8);
394 unsigned char c = (numValue)&0xFF;
395 strValue.push_back(c);
396 }
397 }
398
399 Set(IsStringValue);
400 numValue = 0;
401 i = 0;
402 } else {
403 if (c == '\n' || c == '\r') {
404 if (bflag == 0) {
405 state = BEGIN_LINE;
406 }
407 } else {
408 if (bflag == 0) {
409 state = END_LINE;
410 }
411 }
412 if (Is(IsStringValue) && base == 16 && i > 0) {
413 int n = (i + 1) / 2;
414 while (n-- > 0) strValue.push_back(((numValue >> (n * 8)) & 0xFF));
415 }
416 if (strValue.length() > 0)
417 pParam = new CNfcParam(token.c_str(), strValue);
418 else
419 pParam = new CNfcParam(token.c_str(), numValue);
420 add(pParam);
421 strValue.erase();
422 numValue = 0;
423 }
424 break;
425 case STR_VALUE:
426 if (c == '"') {
427 strValue.push_back('\0');
428 state = END_LINE;
429 pParam = new CNfcParam(token.c_str(), strValue);
430 add(pParam);
431 } else if (isPrintable(c))
432 strValue.push_back(c);
433 break;
434 case END_LINE:
435 if (c == '\n' || c == '\r') state = BEGIN_LINE;
436 break;
437 default:
438 break;
439 }
440 }
441
442 delete[] p_config;
443
444 moveFromList();
445 return size() > 0;
446 }
447
448 /*******************************************************************************
449 **
450 ** Function: CNfcConfig::CNfcConfig()
451 **
452 ** Description: class constructor
453 **
454 ** Returns: none
455 **
456 *******************************************************************************/
CNfcConfig()457 CNfcConfig::CNfcConfig()
458 : mValidFile(true),
459 config_crc32_(0),
460 config_rf_crc32_(0),
461 config_tr_crc32_(0),
462 state(0) {}
463
464 /*******************************************************************************
465 **
466 ** Function: CNfcConfig::~CNfcConfig()
467 **
468 ** Description: class destructor
469 **
470 ** Returns: none
471 **
472 *******************************************************************************/
~CNfcConfig()473 CNfcConfig::~CNfcConfig() {}
474
475 /*******************************************************************************
476 **
477 ** Function: CNfcConfig::GetInstance()
478 **
479 ** Description: get class singleton object
480 **
481 ** Returns: none
482 **
483 *******************************************************************************/
GetInstance()484 CNfcConfig& CNfcConfig::GetInstance() {
485 static CNfcConfig theInstance;
486
487 if (theInstance.size() == 0 && theInstance.mValidFile) {
488 string strPath;
489 if (alternative_config_path[0] != '\0') {
490 strPath.assign(alternative_config_path);
491 strPath += config_name;
492 theInstance.readConfig(strPath.c_str(), true);
493 if (!theInstance.empty()) {
494 return theInstance;
495 }
496 }
497
498 if (findConfigFilePathFromTransportConfigPaths(
499 android::base::GetProperty("persist.vendor.nfc.config_file_name",
500 ""),
501 strPath)) {
502 NXPLOG_EXTNS_D("%s load %s\n", __func__, strPath.c_str());
503 } else if (findConfigFilePathFromTransportConfigPaths(
504 extra_config_base +
505 android::base::GetProperty(
506 "ro.boot.product.hardware.sku", "") +
507 +extra_config_ext,
508 strPath)) {
509 NXPLOG_EXTNS_D("%s load %s\n", __func__, strPath.c_str());
510 } else {
511 findConfigFilePathFromTransportConfigPaths(config_name, strPath);
512 }
513
514 theInstance.readConfig(strPath.c_str(), true);
515 theInstance.readNxpRFConfig(nxp_rf_config_path);
516 theInstance.readNxpTransitConfig(transit_config_path);
517 }
518 return theInstance;
519 }
520
521 /*******************************************************************************
522 **
523 ** Function: CNfcConfig::getValue()
524 **
525 ** Description: get a string value of a setting
526 **
527 ** Returns: true if setting exists
528 ** false if setting does not exist
529 **
530 *******************************************************************************/
getValue(const char * name,char * pValue,size_t len) const531 bool CNfcConfig::getValue(const char* name, char* pValue, size_t len) const {
532 const CNfcParam* pParam = find(name);
533 if (pParam == NULL) return false;
534
535 if (pParam->str_len() > 0) {
536 memset(pValue, 0, len);
537 memcpy(pValue, pParam->str_value(), pParam->str_len());
538 return true;
539 }
540 return false;
541 }
542
getValue(const char * name,char * pValue,long len,long * readlen) const543 bool CNfcConfig::getValue(const char* name, char* pValue, long len,
544 long* readlen) const {
545 const CNfcParam* pParam = find(name);
546 if (pParam == NULL) return false;
547
548 if (pParam->str_len() > 0) {
549 if (pParam->str_len() <= (unsigned long)len) {
550 memset(pValue, 0, len);
551 memcpy(pValue, pParam->str_value(), pParam->str_len());
552 *readlen = pParam->str_len();
553 } else {
554 *readlen = -1;
555 }
556
557 return true;
558 }
559 return false;
560 }
561
562 /*******************************************************************************
563 **
564 ** Function: CNfcConfig::getValue()
565 **
566 ** Description: get a long numerical value of a setting
567 **
568 ** Returns: true if setting exists
569 ** false if setting does not exist
570 **
571 *******************************************************************************/
getValue(const char * name,unsigned long & rValue) const572 bool CNfcConfig::getValue(const char* name, unsigned long& rValue) const {
573 const CNfcParam* pParam = find(name);
574 if (pParam == NULL) return false;
575
576 if (pParam->str_len() == 0) {
577 rValue = static_cast<unsigned long>(pParam->numValue());
578 return true;
579 }
580 return false;
581 }
582
583 /*******************************************************************************
584 **
585 ** Function: CNfcConfig::getValue()
586 **
587 ** Description: get a short numerical value of a setting
588 **
589 ** Returns: true if setting exists
590 ** false if setting does not exist
591 **
592 *******************************************************************************/
getValue(const char * name,unsigned short & rValue) const593 bool CNfcConfig::getValue(const char* name, unsigned short& rValue) const {
594 const CNfcParam* pParam = find(name);
595 if (pParam == NULL) return false;
596
597 if (pParam->str_len() == 0) {
598 rValue = static_cast<unsigned short>(pParam->numValue());
599 return true;
600 }
601 return false;
602 }
603
604 /*******************************************************************************
605 **
606 ** Function: CNfcConfig::find()
607 **
608 ** Description: search if a setting exist in the setting array
609 **
610 ** Returns: pointer to the setting object
611 **
612 *******************************************************************************/
find(const char * p_name) const613 const CNfcParam* CNfcConfig::find(const char* p_name) const {
614 if (size() == 0) return NULL;
615
616 for (const_iterator it = begin(), itEnd = end(); it != itEnd; ++it) {
617 if (**it < p_name) {
618 continue;
619 } else if (**it == p_name) {
620 if ((*it)->str_len() > 0) {
621 NXPLOG_EXTNS_D("%s found %s=%s\n", __func__, p_name,
622 (*it)->str_value());
623 } else {
624 NXPLOG_EXTNS_D("%s found %s=(0x%lx)\n", __func__, p_name,
625 (*it)->numValue());
626 }
627 return *it;
628 } else
629 break;
630 }
631 return NULL;
632 }
633
634 /*******************************************************************************
635 **
636 ** Function: CNfcConfig::readNxpTransitConfig()
637 **
638 ** Description: read Config settings from transit conf file
639 **
640 ** Returns: none
641 **
642 *******************************************************************************/
readNxpTransitConfig(const char * fileName) const643 void CNfcConfig::readNxpTransitConfig(const char* fileName) const {
644 ALOGD("readNxpTransitConfig-Enter..Reading %s", fileName);
645 CNfcConfig::GetInstance().readConfig(fileName, false);
646 }
647
648 /*******************************************************************************
649 **
650 ** Function: CNfcConfig::readNxpRFConfig()
651 **
652 ** Description: read Config settings from RF conf file
653 **
654 ** Returns: none
655 **
656 *******************************************************************************/
readNxpRFConfig(const char * fileName) const657 void CNfcConfig::readNxpRFConfig(const char* fileName) const {
658 ALOGD("readNxpRFConfig-Enter..Reading %s", fileName);
659 CNfcConfig::GetInstance().readConfig(fileName, false);
660 }
661
662 /*******************************************************************************
663 **
664 ** Function: CNfcConfig::clean()
665 **
666 ** Description: reset the setting array
667 **
668 ** Returns: none
669 **
670 *******************************************************************************/
clean()671 void CNfcConfig::clean() {
672 if (size() == 0) return;
673
674 for (iterator it = begin(), itEnd = end(); it != itEnd; ++it) delete *it;
675 clear();
676 }
677
678 /*******************************************************************************
679 **
680 ** Function: CNfcConfig::Add()
681 **
682 ** Description: add a setting object to the list
683 **
684 ** Returns: none
685 **
686 *******************************************************************************/
add(const CNfcParam * pParam)687 void CNfcConfig::add(const CNfcParam* pParam) {
688 if (m_list.size() == 0) {
689 m_list.push_back(pParam);
690 return;
691 }
692 if ((mCurrentFile.find("nxpTransit") != std::string::npos) &&
693 !isAllowed(pParam->c_str())) {
694 ALOGD("%s Token restricted. Returning", __func__);
695 return;
696 }
697 for (list<const CNfcParam*>::iterator it = m_list.begin(),
698 itEnd = m_list.end();
699 it != itEnd; ++it) {
700 if (**it < pParam->c_str()) continue;
701 if (**it == pParam->c_str())
702 m_list.insert(m_list.erase(it), pParam);
703 else
704 m_list.insert(it, pParam);
705
706 return;
707 }
708 m_list.push_back(pParam);
709 }
710 /*******************************************************************************
711 **
712 ** Function: CNfcConfig::dump()
713 **
714 ** Description: prints all elements in the list
715 **
716 ** Returns: none
717 **
718 *******************************************************************************/
dump()719 void CNfcConfig::dump() {
720 ALOGD("%s Enter", __func__);
721
722 for (list<const CNfcParam*>::iterator it = m_list.begin(),
723 itEnd = m_list.end();
724 it != itEnd; ++it) {
725 if ((*it)->str_len() > 0)
726 ALOGD("%s %s \t= %s", __func__, (*it)->c_str(), (*it)->str_value());
727 else
728 ALOGD("%s %s \t= (0x%0lX)\n", __func__, (*it)->c_str(),
729 (*it)->numValue());
730 }
731 }
732 /*******************************************************************************
733 **
734 ** Function: CNfcConfig::isAllowed()
735 **
736 ** Description: checks if token update is allowed
737 **
738 ** Returns: true if allowed else false
739 **
740 *******************************************************************************/
isAllowed(const char * name)741 bool CNfcConfig::isAllowed(const char* name) {
742 string token(name);
743 bool stat = false;
744 if ((token.find("P2P_LISTEN_TECH_MASK") != std::string::npos) ||
745 (token.find("HOST_LISTEN_TECH_MASK") != std::string::npos) ||
746 (token.find("UICC_LISTEN_TECH_MASK") != std::string::npos) ||
747 (token.find("NXP_ESE_LISTEN_TECH_MASK") != std::string::npos) ||
748 (token.find("POLLING_TECH_MASK") != std::string::npos) ||
749 (token.find("NXP_RF_CONF_BLK") != std::string::npos) ||
750 (token.find("NXP_CN_TRANSIT_BLK_NUM_CHECK_ENABLE") !=
751 std::string::npos) ||
752 (token.find("NXP_FWD_FUNCTIONALITY_ENABLE") != std::string::npos) ||
753 (token.find("NXP_MIFARE_NACK_TO_RATS_ENABLE") != std::string::npos))
754
755 {
756 stat = true;
757 }
758 return stat;
759 }
760 /*******************************************************************************
761 **
762 ** Function: CNfcConfig::moveFromList()
763 **
764 ** Description: move the setting object from list to array
765 **
766 ** Returns: none
767 **
768 *******************************************************************************/
moveFromList()769 void CNfcConfig::moveFromList() {
770 if (m_list.size() == 0) return;
771
772 for (list<const CNfcParam*>::iterator it = m_list.begin(),
773 itEnd = m_list.end();
774 it != itEnd; ++it)
775 push_back(*it);
776 m_list.clear();
777 }
778
779 /*******************************************************************************
780 **
781 ** Function: CNfcConfig::moveToList()
782 **
783 ** Description: move the setting object from array to list
784 **
785 ** Returns: none
786 **
787 *******************************************************************************/
moveToList()788 void CNfcConfig::moveToList() {
789 if (m_list.size() != 0) m_list.clear();
790
791 for (iterator it = begin(), itEnd = end(); it != itEnd; ++it)
792 m_list.push_back(*it);
793 clear();
794 }
isModified(tNXP_CONF_FILE aType)795 bool CNfcConfig::isModified(tNXP_CONF_FILE aType) {
796 FILE* fd = NULL;
797 bool isModified = false;
798
799 ALOGD("isModified enter; conf file type %d", aType);
800 switch (aType) {
801 case CONF_FILE_NXP:
802 fd = fopen(config_timestamp_path, "r+");
803 break;
804 case CONF_FILE_NXP_RF:
805 fd = fopen(rf_config_timestamp_path, "r+");
806 break;
807 case CONF_FILE_NXP_TRANSIT:
808 fd = fopen(tr_config_timestamp_path, "r+");
809 break;
810 default:
811 ALOGD("Invalid conf file type");
812 return false;
813 }
814 if (fd == nullptr) {
815 ALOGE("%s Unable to open file assume modified", __func__);
816 return true;
817 }
818
819 uint32_t stored_crc32 = 0;
820 if (fread(&stored_crc32, sizeof(uint32_t), 1, fd) != 1) {
821 ALOGE("%s File read is not successful errno = %d", __func__, errno);
822 }
823
824 fclose(fd);
825 ALOGD("stored_crc32 is %d config_crc32_ is %d", stored_crc32, config_crc32_);
826
827 switch (aType) {
828 case CONF_FILE_NXP:
829 isModified = stored_crc32 != config_crc32_;
830 break;
831 case CONF_FILE_NXP_RF:
832 isModified = stored_crc32 != config_rf_crc32_;
833 break;
834 case CONF_FILE_NXP_TRANSIT:
835 isModified = stored_crc32 != config_tr_crc32_;
836 break;
837 }
838 return isModified;
839 }
840
resetModified(tNXP_CONF_FILE aType)841 void CNfcConfig::resetModified(tNXP_CONF_FILE aType) {
842 FILE* fd = NULL;
843
844 ALOGD("resetModified enter; conf file type is %d", aType);
845 switch (aType) {
846 case CONF_FILE_NXP:
847 fd = fopen(config_timestamp_path, "w+");
848 break;
849 case CONF_FILE_NXP_RF:
850 fd = fopen(rf_config_timestamp_path, "w+");
851 break;
852 case CONF_FILE_NXP_TRANSIT:
853 fd = fopen(tr_config_timestamp_path, "w+");
854 break;
855 default:
856 ALOGD("Invalid conf file type");
857 return;
858 }
859
860 if (fd == nullptr) {
861 ALOGE("%s Unable to open file for writing", __func__);
862 return;
863 }
864
865 switch (aType) {
866 case CONF_FILE_NXP:
867 fwrite(&config_crc32_, sizeof(uint32_t), 1, fd);
868 break;
869 case CONF_FILE_NXP_RF:
870 fwrite(&config_rf_crc32_, sizeof(uint32_t), 1, fd);
871 break;
872 case CONF_FILE_NXP_TRANSIT:
873 fwrite(&config_tr_crc32_, sizeof(uint32_t), 1, fd);
874 break;
875 }
876 fclose(fd);
877 }
878
879 /*******************************************************************************
880 **
881 ** Function: CNfcParam::CNfcParam()
882 **
883 ** Description: class constructor
884 **
885 ** Returns: none
886 **
887 *******************************************************************************/
CNfcParam()888 CNfcParam::CNfcParam() : m_numValue(0) {}
889
890 /*******************************************************************************
891 **
892 ** Function: CNfcParam::~CNfcParam()
893 **
894 ** Description: class destructor
895 **
896 ** Returns: none
897 **
898 *******************************************************************************/
~CNfcParam()899 CNfcParam::~CNfcParam() {}
900
901 /*******************************************************************************
902 **
903 ** Function: CNfcParam::CNfcParam()
904 **
905 ** Description: class copy constructor
906 **
907 ** Returns: none
908 **
909 *******************************************************************************/
CNfcParam(const char * name,const string & value)910 CNfcParam::CNfcParam(const char* name, const string& value)
911 : string(name), m_str_value(value), m_numValue(0) {}
912
913 /*******************************************************************************
914 **
915 ** Function: CNfcParam::CNfcParam()
916 **
917 ** Description: class copy constructor
918 **
919 ** Returns: none
920 **
921 *******************************************************************************/
CNfcParam(const char * name,unsigned long value)922 CNfcParam::CNfcParam(const char* name, unsigned long value)
923 : string(name), m_numValue(value) {}
924
925 /*******************************************************************************
926 **
927 ** Function: readOptionalConfig()
928 **
929 ** Description: read Config settings from an optional conf file
930 **
931 ** Returns: none
932 **
933 *******************************************************************************/
readOptionalConfig(const char * extra)934 void readOptionalConfig(const char* extra) {
935 string strPath;
936 string configName(extra_config_base);
937 configName += extra;
938 configName += extra_config_ext;
939
940 if (alternative_config_path[0] != '\0') {
941 strPath.assign(alternative_config_path);
942 strPath += configName;
943 } else {
944 findConfigFilePathFromTransportConfigPaths(configName, strPath);
945 }
946
947 CNfcConfig::GetInstance().readConfig(strPath.c_str(), false);
948 }
949
950 /*******************************************************************************
951 **
952 ** Function: GetStrValue
953 **
954 ** Description: API function for getting a string value of a setting
955 **
956 ** Returns: True if found, otherwise False.
957 **
958 *******************************************************************************/
GetNxpStrValue(const char * name,char * pValue,unsigned long len)959 extern "C" int GetNxpStrValue(const char* name, char* pValue,
960 unsigned long len) {
961 CNfcConfig& rConfig = CNfcConfig::GetInstance();
962
963 return rConfig.getValue(name, pValue, len);
964 }
965
966 /*******************************************************************************
967 **
968 ** Function: GetByteArrayValue()
969 **
970 ** Description: Read byte array value from the config file.
971 **
972 ** Parameters:
973 ** name - name of the config param to read.
974 ** pValue - pointer to input buffer.
975 ** bufflen - input buffer length.
976 ** len - out parameter to return the number of bytes read from
977 ** config file, return -1 in case bufflen is not enough.
978 **
979 ** Returns: TRUE[1] if config param name is found in the config file, else
980 ** FALSE[0]
981 **
982 *******************************************************************************/
GetNxpByteArrayValue(const char * name,char * pValue,long bufflen,long * len)983 extern "C" int GetNxpByteArrayValue(const char* name, char* pValue,
984 long bufflen, long* len) {
985 CNfcConfig& rConfig = CNfcConfig::GetInstance();
986
987 return rConfig.getValue(name, pValue, bufflen, len);
988 }
989
990 /*******************************************************************************
991 **
992 ** Function: GetNumValue
993 **
994 ** Description: API function for getting a numerical value of a setting
995 **
996 ** Returns: true, if successful
997 **
998 *******************************************************************************/
GetNxpNumValue(const char * name,void * pValue,unsigned long len)999 extern "C" int GetNxpNumValue(const char* name, void* pValue,
1000 unsigned long len) {
1001 if (!pValue) return false;
1002
1003 CNfcConfig& rConfig = CNfcConfig::GetInstance();
1004 const CNfcParam* pParam = rConfig.find(name);
1005
1006 if (pParam == NULL) return false;
1007 unsigned long v = pParam->numValue();
1008 if (v == 0 && pParam->str_len() > 0 && pParam->str_len() < 4) {
1009 const unsigned char* p = (const unsigned char*)pParam->str_value();
1010 for (size_t i = 0; i < pParam->str_len(); ++i) {
1011 v *= 256;
1012 v += *p++;
1013 }
1014 }
1015 switch (len) {
1016 case sizeof(unsigned long):
1017 *(static_cast<unsigned long*>(pValue)) = (unsigned long)v;
1018 break;
1019 case sizeof(unsigned short):
1020 *(static_cast<unsigned short*>(pValue)) = (unsigned short)v;
1021 break;
1022 case sizeof(unsigned char):
1023 *(static_cast<unsigned char*>(pValue)) = (unsigned char)v;
1024 break;
1025 default:
1026 return false;
1027 }
1028 return true;
1029 }
1030
1031 /*******************************************************************************
1032 **
1033 ** Function: setNxpRfConfigPath
1034 **
1035 ** Description: sets the path of the NXP RF config file
1036 **
1037 ** Returns: none
1038 **
1039 *******************************************************************************/
setNxpRfConfigPath(const char * name)1040 extern "C" void setNxpRfConfigPath(const char* name) {
1041 memset(nxp_rf_config_path, 0, sizeof(nxp_rf_config_path));
1042 strlcpy(nxp_rf_config_path, name, sizeof(nxp_rf_config_path));
1043 ALOGD("nxp_rf_config_path=%s", nxp_rf_config_path);
1044 }
1045
1046 /*******************************************************************************
1047 **
1048 ** Function: setNxpFwConfigPath
1049 **
1050 ** Description: sets the path of the NXP FW library
1051 **
1052 ** Returns: none
1053 **
1054 *******************************************************************************/
setNxpFwConfigPath()1055 extern "C" void setNxpFwConfigPath() {
1056 unsigned long fwType = FW_FORMAT_SO;
1057 if (GetNxpNumValue(NAME_NXP_FW_TYPE, &fwType, sizeof(fwType))) {
1058 NXPLOG_FWDNLD_D("firmware type from conf file: %lu", fwType);
1059 }
1060
1061 memset(Fw_Lib_Path, 0, sizeof(Fw_Lib_Path));
1062 if (fwType == FW_FORMAT_BIN) {
1063 strlcpy(Fw_Lib_Path, nfcFL._FW_BIN_PATH.c_str(), sizeof(Fw_Lib_Path));
1064 } else {
1065 strlcpy(Fw_Lib_Path, nfcFL._FW_LIB_PATH.c_str(), sizeof(Fw_Lib_Path));
1066 }
1067
1068 ALOGD("Fw_Lib_Path=%s", Fw_Lib_Path);
1069 }
1070
1071 /*******************************************************************************
1072 **
1073 ** Function: resetConfig
1074 **
1075 ** Description: reset settings array
1076 **
1077 ** Returns: none
1078 **
1079 *******************************************************************************/
resetNxpConfig()1080 extern "C" void resetNxpConfig()
1081
1082 {
1083 CNfcConfig& rConfig = CNfcConfig::GetInstance();
1084
1085 rConfig.clean();
1086 }
1087
1088 /*******************************************************************************
1089 **
1090 ** Function: isNxpConfigModified()
1091 **
1092 ** Description: check if config file has modified
1093 **
1094 ** Returns: 0 if not modified, 1 otherwise.
1095 **
1096 *******************************************************************************/
isNxpConfigModified()1097 extern "C" int isNxpConfigModified() {
1098 CNfcConfig& rConfig = CNfcConfig::GetInstance();
1099 return rConfig.isModified(CONF_FILE_NXP);
1100 }
1101
1102 /*******************************************************************************
1103 **
1104 ** Function: isNxpRFConfigModified()
1105 **
1106 ** Description: check if config file has modified
1107 **
1108 ** Returns: 0 if not modified, 1 otherwise.
1109 **
1110 *******************************************************************************/
isNxpRFConfigModified()1111 extern "C" int isNxpRFConfigModified() {
1112 int retRF = 0, rettransit = 0, ret = 0;
1113 CNfcConfig& rConfig = CNfcConfig::GetInstance();
1114 retRF = rConfig.isModified(CONF_FILE_NXP_RF);
1115 rettransit = rConfig.isModified(CONF_FILE_NXP_TRANSIT);
1116 ret = retRF | rettransit;
1117 ALOGD("ret RF or Transit value %d", ret);
1118 return ret;
1119 }
1120
1121 /*******************************************************************************
1122 **
1123 ** Function: updateNxpConfigTimestamp()
1124 **
1125 ** Description: update if config file has modified
1126 **
1127 ** Returns: 0 if not modified, 1 otherwise.
1128 **
1129 *******************************************************************************/
updateNxpConfigTimestamp()1130 extern "C" int updateNxpConfigTimestamp() {
1131 CNfcConfig& rConfig = CNfcConfig::GetInstance();
1132 rConfig.resetModified(CONF_FILE_NXP);
1133 return 0;
1134 }
1135 /*******************************************************************************
1136 **
1137 ** Function: updateNxpConfigTimestamp()
1138 **
1139 ** Description: update if config file has modified
1140 **
1141 ** Returns: 0 if not modified, 1 otherwise.
1142 **
1143 *******************************************************************************/
updateNxpRfConfigTimestamp()1144 extern "C" int updateNxpRfConfigTimestamp() {
1145 CNfcConfig& rConfig = CNfcConfig::GetInstance();
1146 rConfig.resetModified(CONF_FILE_NXP_RF);
1147 rConfig.resetModified(CONF_FILE_NXP_TRANSIT);
1148 return 0;
1149 }
1150