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