• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 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 #if (NXP_EXTNS == TRUE)
516     theInstance.readNxpRFConfig(nxp_rf_config_path);
517     theInstance.readNxpTransitConfig(transit_config_path);
518 #endif
519   }
520   return theInstance;
521 }
522 
523 /*******************************************************************************
524 **
525 ** Function:    CNfcConfig::getValue()
526 **
527 ** Description: get a string value of a setting
528 **
529 ** Returns:     true if setting exists
530 **              false if setting does not exist
531 **
532 *******************************************************************************/
getValue(const char * name,char * pValue,size_t len) const533 bool CNfcConfig::getValue(const char* name, char* pValue, size_t len) const {
534   const CNfcParam* pParam = find(name);
535   if (pParam == NULL) return false;
536 
537   if (pParam->str_len() > 0) {
538     memset(pValue, 0, len);
539     memcpy(pValue, pParam->str_value(), pParam->str_len());
540     return true;
541   }
542   return false;
543 }
544 
getValue(const char * name,char * pValue,long len,long * readlen) const545 bool CNfcConfig::getValue(const char* name, char* pValue, long len,
546                           long* readlen) const {
547   const CNfcParam* pParam = find(name);
548   if (pParam == NULL) return false;
549 
550   if (pParam->str_len() > 0) {
551     if (pParam->str_len() <= (unsigned long)len) {
552       memset(pValue, 0, len);
553       memcpy(pValue, pParam->str_value(), pParam->str_len());
554       *readlen = pParam->str_len();
555     } else {
556       *readlen = -1;
557     }
558 
559     return true;
560   }
561   return false;
562 }
563 
564 /*******************************************************************************
565 **
566 ** Function:    CNfcConfig::getValue()
567 **
568 ** Description: get a long numerical value of a setting
569 **
570 ** Returns:     true if setting exists
571 **              false if setting does not exist
572 **
573 *******************************************************************************/
getValue(const char * name,unsigned long & rValue) const574 bool CNfcConfig::getValue(const char* name, unsigned long& rValue) const {
575   const CNfcParam* pParam = find(name);
576   if (pParam == NULL) return false;
577 
578   if (pParam->str_len() == 0) {
579     rValue = static_cast<unsigned long>(pParam->numValue());
580     return true;
581   }
582   return false;
583 }
584 
585 /*******************************************************************************
586 **
587 ** Function:    CNfcConfig::getValue()
588 **
589 ** Description: get a short numerical value of a setting
590 **
591 ** Returns:     true if setting exists
592 **              false if setting does not exist
593 **
594 *******************************************************************************/
getValue(const char * name,unsigned short & rValue) const595 bool CNfcConfig::getValue(const char* name, unsigned short& rValue) const {
596   const CNfcParam* pParam = find(name);
597   if (pParam == NULL) return false;
598 
599   if (pParam->str_len() == 0) {
600     rValue = static_cast<unsigned short>(pParam->numValue());
601     return true;
602   }
603   return false;
604 }
605 
606 /*******************************************************************************
607 **
608 ** Function:    CNfcConfig::find()
609 **
610 ** Description: search if a setting exist in the setting array
611 **
612 ** Returns:     pointer to the setting object
613 **
614 *******************************************************************************/
find(const char * p_name) const615 const CNfcParam* CNfcConfig::find(const char* p_name) const {
616   if (size() == 0) return NULL;
617 
618   for (const_iterator it = begin(), itEnd = end(); it != itEnd; ++it) {
619     if (**it < p_name) {
620       continue;
621     } else if (**it == p_name) {
622       if ((*it)->str_len() > 0) {
623         NXPLOG_EXTNS_D("%s found %s=%s\n", __func__, p_name,
624                        (*it)->str_value());
625       } else {
626         NXPLOG_EXTNS_D("%s found %s=(0x%lx)\n", __func__, p_name,
627                        (*it)->numValue());
628       }
629       return *it;
630     } else
631       break;
632   }
633   return NULL;
634 }
635 
636 /*******************************************************************************
637 **
638 ** Function:    CNfcConfig::readNxpTransitConfig()
639 **
640 ** Description: read Config settings from transit conf file
641 **
642 ** Returns:     none
643 **
644 *******************************************************************************/
readNxpTransitConfig(const char * fileName) const645 void CNfcConfig::readNxpTransitConfig(const char* fileName) const {
646   ALOGD("readNxpTransitConfig-Enter..Reading %s", fileName);
647   CNfcConfig::GetInstance().readConfig(fileName, false);
648 }
649 
650 /*******************************************************************************
651 **
652 ** Function:    CNfcConfig::readNxpRFConfig()
653 **
654 ** Description: read Config settings from RF conf file
655 **
656 ** Returns:     none
657 **
658 *******************************************************************************/
readNxpRFConfig(const char * fileName) const659 void CNfcConfig::readNxpRFConfig(const char* fileName) const {
660   ALOGD("readNxpRFConfig-Enter..Reading %s", fileName);
661   CNfcConfig::GetInstance().readConfig(fileName, false);
662 }
663 
664 /*******************************************************************************
665 **
666 ** Function:    CNfcConfig::clean()
667 **
668 ** Description: reset the setting array
669 **
670 ** Returns:     none
671 **
672 *******************************************************************************/
clean()673 void CNfcConfig::clean() {
674   if (size() == 0) return;
675 
676   for (iterator it = begin(), itEnd = end(); it != itEnd; ++it) delete *it;
677   clear();
678 }
679 
680 /*******************************************************************************
681 **
682 ** Function:    CNfcConfig::Add()
683 **
684 ** Description: add a setting object to the list
685 **
686 ** Returns:     none
687 **
688 *******************************************************************************/
add(const CNfcParam * pParam)689 void CNfcConfig::add(const CNfcParam* pParam) {
690   if (m_list.size() == 0) {
691     m_list.push_back(pParam);
692     return;
693   }
694   if ((mCurrentFile.find("nxpTransit") != std::string::npos) &&
695       !isAllowed(pParam->c_str())) {
696     ALOGD("%s Token restricted. Returning", __func__);
697     return;
698   }
699   for (list<const CNfcParam*>::iterator it = m_list.begin(),
700                                         itEnd = m_list.end();
701        it != itEnd; ++it) {
702     if (**it < pParam->c_str()) continue;
703     if (**it == pParam->c_str())
704       m_list.insert(m_list.erase(it), pParam);
705     else
706       m_list.insert(it, pParam);
707 
708     return;
709   }
710   m_list.push_back(pParam);
711 }
712 /*******************************************************************************
713 **
714 ** Function:    CNfcConfig::dump()
715 **
716 ** Description: prints all elements in the list
717 **
718 ** Returns:     none
719 **
720 *******************************************************************************/
dump()721 void CNfcConfig::dump() {
722   ALOGD("%s Enter", __func__);
723 
724   for (list<const CNfcParam*>::iterator it = m_list.begin(),
725                                         itEnd = m_list.end();
726        it != itEnd; ++it) {
727     if ((*it)->str_len() > 0)
728       ALOGD("%s %s \t= %s", __func__, (*it)->c_str(), (*it)->str_value());
729     else
730       ALOGD("%s %s \t= (0x%0lX)\n", __func__, (*it)->c_str(),
731             (*it)->numValue());
732   }
733 }
734 /*******************************************************************************
735 **
736 ** Function:    CNfcConfig::isAllowed()
737 **
738 ** Description: checks if token update is allowed
739 **
740 ** Returns:     true if allowed else false
741 **
742 *******************************************************************************/
isAllowed(const char * name)743 bool CNfcConfig::isAllowed(const char* name) {
744   string token(name);
745   bool stat = false;
746   if ((token.find("P2P_LISTEN_TECH_MASK") != std::string::npos) ||
747       (token.find("HOST_LISTEN_TECH_MASK") != std::string::npos) ||
748       (token.find("UICC_LISTEN_TECH_MASK") != std::string::npos) ||
749       (token.find("NXP_ESE_LISTEN_TECH_MASK") != std::string::npos) ||
750       (token.find("POLLING_TECH_MASK") != std::string::npos) ||
751       (token.find("NXP_RF_CONF_BLK") != std::string::npos) ||
752       (token.find("NXP_CN_TRANSIT_BLK_NUM_CHECK_ENABLE") !=
753        std::string::npos) ||
754       (token.find("NXP_FWD_FUNCTIONALITY_ENABLE") != std::string::npos) ||
755       (token.find("NXP_MIFARE_NACK_TO_RATS_ENABLE") != std::string::npos))
756 
757   {
758     stat = true;
759   }
760   return stat;
761 }
762 /*******************************************************************************
763 **
764 ** Function:    CNfcConfig::moveFromList()
765 **
766 ** Description: move the setting object from list to array
767 **
768 ** Returns:     none
769 **
770 *******************************************************************************/
moveFromList()771 void CNfcConfig::moveFromList() {
772   if (m_list.size() == 0) return;
773 
774   for (list<const CNfcParam*>::iterator it = m_list.begin(),
775                                         itEnd = m_list.end();
776        it != itEnd; ++it)
777     push_back(*it);
778   m_list.clear();
779 }
780 
781 /*******************************************************************************
782 **
783 ** Function:    CNfcConfig::moveToList()
784 **
785 ** Description: move the setting object from array to list
786 **
787 ** Returns:     none
788 **
789 *******************************************************************************/
moveToList()790 void CNfcConfig::moveToList() {
791   if (m_list.size() != 0) m_list.clear();
792 
793   for (iterator it = begin(), itEnd = end(); it != itEnd; ++it)
794     m_list.push_back(*it);
795   clear();
796 }
isModified(tNXP_CONF_FILE aType)797 bool CNfcConfig::isModified(tNXP_CONF_FILE aType) {
798   FILE* fd = NULL;
799   bool isModified = false;
800 
801   ALOGD("isModified enter; conf file type %d", aType);
802   switch (aType) {
803     case CONF_FILE_NXP:
804       fd = fopen(config_timestamp_path, "r+");
805       break;
806     case CONF_FILE_NXP_RF:
807       fd = fopen(rf_config_timestamp_path, "r+");
808       break;
809     case CONF_FILE_NXP_TRANSIT:
810       fd = fopen(tr_config_timestamp_path, "r+");
811       break;
812     default:
813       ALOGD("Invalid conf file type");
814       return false;
815   }
816   if (fd == nullptr) {
817     ALOGE("%s Unable to open file assume modified", __func__);
818     return true;
819   }
820 
821   uint32_t stored_crc32 = 0;
822   if (fread(&stored_crc32, sizeof(uint32_t), 1, fd) != 1) {
823     ALOGE("%s File read is not successful errno = %d", __func__, errno);
824   }
825 
826   fclose(fd);
827   ALOGD("stored_crc32 is %d config_crc32_ is %d", stored_crc32, config_crc32_);
828 
829   switch (aType) {
830     case CONF_FILE_NXP:
831       isModified = stored_crc32 != config_crc32_;
832       break;
833     case CONF_FILE_NXP_RF:
834       isModified = stored_crc32 != config_rf_crc32_;
835       break;
836     case CONF_FILE_NXP_TRANSIT:
837       isModified = stored_crc32 != config_tr_crc32_;
838       break;
839   }
840   return isModified;
841 }
842 
resetModified(tNXP_CONF_FILE aType)843 void CNfcConfig::resetModified(tNXP_CONF_FILE aType) {
844   FILE* fd = NULL;
845 
846   ALOGD("resetModified enter; conf file type is %d", aType);
847   switch (aType) {
848     case CONF_FILE_NXP:
849       fd = fopen(config_timestamp_path, "w+");
850       break;
851     case CONF_FILE_NXP_RF:
852       fd = fopen(rf_config_timestamp_path, "w+");
853       break;
854     case CONF_FILE_NXP_TRANSIT:
855       fd = fopen(tr_config_timestamp_path, "w+");
856       break;
857     default:
858       ALOGD("Invalid conf file type");
859       return;
860   }
861 
862   if (fd == nullptr) {
863     ALOGE("%s Unable to open file for writing", __func__);
864     return;
865   }
866 
867   switch (aType) {
868     case CONF_FILE_NXP:
869       fwrite(&config_crc32_, sizeof(uint32_t), 1, fd);
870       break;
871     case CONF_FILE_NXP_RF:
872       fwrite(&config_rf_crc32_, sizeof(uint32_t), 1, fd);
873       break;
874     case CONF_FILE_NXP_TRANSIT:
875       fwrite(&config_tr_crc32_, sizeof(uint32_t), 1, fd);
876       break;
877   }
878   fclose(fd);
879 }
880 
881 /*******************************************************************************
882 **
883 ** Function:    CNfcParam::CNfcParam()
884 **
885 ** Description: class constructor
886 **
887 ** Returns:     none
888 **
889 *******************************************************************************/
CNfcParam()890 CNfcParam::CNfcParam() : m_numValue(0) {}
891 
892 /*******************************************************************************
893 **
894 ** Function:    CNfcParam::~CNfcParam()
895 **
896 ** Description: class destructor
897 **
898 ** Returns:     none
899 **
900 *******************************************************************************/
~CNfcParam()901 CNfcParam::~CNfcParam() {}
902 
903 /*******************************************************************************
904 **
905 ** Function:    CNfcParam::CNfcParam()
906 **
907 ** Description: class copy constructor
908 **
909 ** Returns:     none
910 **
911 *******************************************************************************/
CNfcParam(const char * name,const string & value)912 CNfcParam::CNfcParam(const char* name, const string& value)
913     : string(name), m_str_value(value), m_numValue(0) {}
914 
915 /*******************************************************************************
916 **
917 ** Function:    CNfcParam::CNfcParam()
918 **
919 ** Description: class copy constructor
920 **
921 ** Returns:     none
922 **
923 *******************************************************************************/
CNfcParam(const char * name,unsigned long value)924 CNfcParam::CNfcParam(const char* name, unsigned long value)
925     : string(name), m_numValue(value) {}
926 
927 /*******************************************************************************
928 **
929 ** Function:    readOptionalConfig()
930 **
931 ** Description: read Config settings from an optional conf file
932 **
933 ** Returns:     none
934 **
935 *******************************************************************************/
readOptionalConfig(const char * extra)936 void readOptionalConfig(const char* extra) {
937   string strPath;
938   string configName(extra_config_base);
939   configName += extra;
940   configName += extra_config_ext;
941 
942   if (alternative_config_path[0] != '\0') {
943     strPath.assign(alternative_config_path);
944     strPath += configName;
945   } else {
946     findConfigFilePathFromTransportConfigPaths(configName, strPath);
947   }
948 
949   CNfcConfig::GetInstance().readConfig(strPath.c_str(), false);
950 }
951 
952 /*******************************************************************************
953 **
954 ** Function:    GetStrValue
955 **
956 ** Description: API function for getting a string value of a setting
957 **
958 ** Returns:     True if found, otherwise False.
959 **
960 *******************************************************************************/
GetNxpStrValue(const char * name,char * pValue,unsigned long len)961 extern "C" int GetNxpStrValue(const char* name, char* pValue,
962                               unsigned long len) {
963   CNfcConfig& rConfig = CNfcConfig::GetInstance();
964 
965   return rConfig.getValue(name, pValue, len);
966 }
967 
968 /*******************************************************************************
969 **
970 ** Function:    GetByteArrayValue()
971 **
972 ** Description: Read byte array value from the config file.
973 **
974 ** Parameters:
975 **              name - name of the config param to read.
976 **              pValue  - pointer to input buffer.
977 **              bufflen - input buffer length.
978 **              len - out parameter to return the number of bytes read from
979 **                    config file, return -1 in case bufflen is not enough.
980 **
981 ** Returns:     TRUE[1] if config param name is found in the config file, else
982 **              FALSE[0]
983 **
984 *******************************************************************************/
GetNxpByteArrayValue(const char * name,char * pValue,long bufflen,long * len)985 extern "C" int GetNxpByteArrayValue(const char* name, char* pValue,
986                                     long bufflen, long* len) {
987   CNfcConfig& rConfig = CNfcConfig::GetInstance();
988 
989   return rConfig.getValue(name, pValue, bufflen, len);
990 }
991 
992 /*******************************************************************************
993 **
994 ** Function:    GetNumValue
995 **
996 ** Description: API function for getting a numerical value of a setting
997 **
998 ** Returns:     true, if successful
999 **
1000 *******************************************************************************/
GetNxpNumValue(const char * name,void * pValue,unsigned long len)1001 extern "C" int GetNxpNumValue(const char* name, void* pValue,
1002                               unsigned long len) {
1003   if (!pValue) return false;
1004 
1005   CNfcConfig& rConfig = CNfcConfig::GetInstance();
1006   const CNfcParam* pParam = rConfig.find(name);
1007 
1008   if (pParam == NULL) return false;
1009   unsigned long v = pParam->numValue();
1010   if (v == 0 && pParam->str_len() > 0 && pParam->str_len() < 4) {
1011     const unsigned char* p = (const unsigned char*)pParam->str_value();
1012     for (size_t i = 0; i < pParam->str_len(); ++i) {
1013       v *= 256;
1014       v += *p++;
1015     }
1016   }
1017   switch (len) {
1018     case sizeof(unsigned long):
1019       *(static_cast<unsigned long*>(pValue)) = (unsigned long)v;
1020       break;
1021     case sizeof(unsigned short):
1022       *(static_cast<unsigned short*>(pValue)) = (unsigned short)v;
1023       break;
1024     case sizeof(unsigned char):
1025       *(static_cast<unsigned char*>(pValue)) = (unsigned char)v;
1026       break;
1027     default:
1028       return false;
1029   }
1030   return true;
1031 }
1032 
1033 /*******************************************************************************
1034 **
1035 ** Function:    setNxpRfConfigPath
1036 **
1037 ** Description: sets the path of the NXP RF config file
1038 **
1039 ** Returns:     none
1040 **
1041 *******************************************************************************/
setNxpRfConfigPath(const char * name)1042 extern "C" void setNxpRfConfigPath(const char* name) {
1043   memset(nxp_rf_config_path, 0, sizeof(nxp_rf_config_path));
1044   strlcpy(nxp_rf_config_path, name, sizeof(nxp_rf_config_path));
1045   ALOGD("nxp_rf_config_path=%s", nxp_rf_config_path);
1046 }
1047 
1048 /*******************************************************************************
1049 **
1050 ** Function:    setNxpFwConfigPath
1051 **
1052 ** Description: sets the path of the NXP FW library
1053 **
1054 ** Returns:     none
1055 **
1056 *******************************************************************************/
setNxpFwConfigPath()1057 extern "C" void setNxpFwConfigPath() {
1058   unsigned long fwType = FW_FORMAT_SO;
1059   if (GetNxpNumValue(NAME_NXP_FW_TYPE, &fwType, sizeof(fwType))) {
1060     NXPLOG_FWDNLD_D("firmware type from conf file: %lu", fwType);
1061   }
1062 
1063   memset(Fw_Lib_Path, 0, sizeof(Fw_Lib_Path));
1064   if (fwType == FW_FORMAT_BIN) {
1065     strlcpy(Fw_Lib_Path, nfcFL._FW_BIN_PATH.c_str(), sizeof(Fw_Lib_Path));
1066   } else {
1067     strlcpy(Fw_Lib_Path, nfcFL._FW_LIB_PATH.c_str(), sizeof(Fw_Lib_Path));
1068   }
1069 
1070   ALOGD("Fw_Lib_Path=%s", Fw_Lib_Path);
1071 }
1072 
1073 /*******************************************************************************
1074 **
1075 ** Function:    resetConfig
1076 **
1077 ** Description: reset settings array
1078 **
1079 ** Returns:     none
1080 **
1081 *******************************************************************************/
resetNxpConfig()1082 extern "C" void resetNxpConfig()
1083 
1084 {
1085   CNfcConfig& rConfig = CNfcConfig::GetInstance();
1086 
1087   rConfig.clean();
1088 }
1089 
1090 /*******************************************************************************
1091 **
1092 ** Function:    isNxpConfigModified()
1093 **
1094 ** Description: check if config file has modified
1095 **
1096 ** Returns:     0 if not modified, 1 otherwise.
1097 **
1098 *******************************************************************************/
isNxpConfigModified()1099 extern "C" int isNxpConfigModified() {
1100   CNfcConfig& rConfig = CNfcConfig::GetInstance();
1101   return rConfig.isModified(CONF_FILE_NXP);
1102 }
1103 
1104 /*******************************************************************************
1105 **
1106 ** Function:    isNxpRFConfigModified()
1107 **
1108 ** Description: check if config file has modified
1109 **
1110 ** Returns:     0 if not modified, 1 otherwise.
1111 **
1112 *******************************************************************************/
isNxpRFConfigModified()1113 extern "C" int isNxpRFConfigModified() {
1114   int retRF = 0, rettransit = 0, ret = 0;
1115   CNfcConfig& rConfig = CNfcConfig::GetInstance();
1116   retRF = rConfig.isModified(CONF_FILE_NXP_RF);
1117   rettransit = rConfig.isModified(CONF_FILE_NXP_TRANSIT);
1118   ret = retRF | rettransit;
1119   ALOGD("ret RF or Transit value %d", ret);
1120   return ret;
1121 }
1122 
1123 /*******************************************************************************
1124 **
1125 ** Function:    updateNxpConfigTimestamp()
1126 **
1127 ** Description: update if config file has modified
1128 **
1129 ** Returns:     0 if not modified, 1 otherwise.
1130 **
1131 *******************************************************************************/
updateNxpConfigTimestamp()1132 extern "C" int updateNxpConfigTimestamp() {
1133   CNfcConfig& rConfig = CNfcConfig::GetInstance();
1134   rConfig.resetModified(CONF_FILE_NXP);
1135   return 0;
1136 }
1137 /*******************************************************************************
1138 **
1139 ** Function:    updateNxpConfigTimestamp()
1140 **
1141 ** Description: update if config file has modified
1142 **
1143 ** Returns:     0 if not modified, 1 otherwise.
1144 **
1145 *******************************************************************************/
updateNxpRfConfigTimestamp()1146 extern "C" int updateNxpRfConfigTimestamp() {
1147   CNfcConfig& rConfig = CNfcConfig::GetInstance();
1148   rConfig.resetModified(CONF_FILE_NXP_RF);
1149   rConfig.resetModified(CONF_FILE_NXP_TRANSIT);
1150   return 0;
1151 }
1152