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 (C) 2013-2014 NXP Semiconductors
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 <stdio.h>
40 #include <sys/stat.h>
41 #include <list>
42 #include <string>
43 #include <vector>
44 
45 #include <phNxpConfig.h>
46 #include <phNxpLog.h>
47 
48 #if GENERIC_TARGET
49 const char alternative_config_path[] = "/data/vendor/nfc/";
50 #else
51 const char alternative_config_path[] = "";
52 #endif
53 
54 #if 1
55 const char* transport_config_paths[] = {"/odm/etc/", "/vendor/etc/", "/etc/"};
56 #else
57 const char* transport_config_paths[] = {"res/"};
58 #endif
59 const int transport_config_path_size =
60     (sizeof(transport_config_paths) / sizeof(transport_config_paths[0]));
61 
62 #define config_name "libnfc-nxp.conf"
63 #define extra_config_base "libnfc-nxp-"
64 #define extra_config_ext ".conf"
65 #define IsStringValue 0x80000000
66 
67 const char config_timestamp_path[] =
68     "/data/vendor/nfc/libnfc-nxpConfigState.bin";
69 
70 using namespace ::std;
71 
72 class CNfcParam : public string {
73  public:
74   CNfcParam();
75   CNfcParam(const char* name, const string& value);
76   CNfcParam(const char* name, unsigned long value);
77   virtual ~CNfcParam();
numValue() const78   unsigned long numValue() const { return m_numValue; }
str_value() const79   const char* str_value() const { return m_str_value.c_str(); }
str_len() const80   size_t str_len() const { return m_str_value.length(); }
81 
82  private:
83   string m_str_value;
84   unsigned long m_numValue;
85 };
86 
87 class CNfcConfig : public vector<const CNfcParam*> {
88  public:
89   virtual ~CNfcConfig();
90   static CNfcConfig& GetInstance();
91   friend void readOptionalConfig(const char* optional);
92   int updateTimestamp();
93   int checkTimestamp();
94 
95   bool getValue(const char* name, char* pValue, size_t len) const;
96   bool getValue(const char* name, unsigned long& rValue) const;
97   bool getValue(const char* name, unsigned short& rValue) const;
98   bool getValue(const char* name, char* pValue, long len, long* readlen) const;
99   const CNfcParam* find(const char* p_name) const;
100   void clean();
101 
102  private:
103   CNfcConfig();
104   bool readConfig(const char* name, bool bResetContent);
105   void moveFromList();
106   void moveToList();
107   void add(const CNfcParam* pParam);
108   list<const CNfcParam*> m_list;
109   bool mValidFile;
110   unsigned long m_timeStamp;
111 
112   unsigned long state;
113 
Is(unsigned long f)114   inline bool Is(unsigned long f) { return (state & f) == f; }
Set(unsigned long f)115   inline void Set(unsigned long f) { state |= f; }
Reset(unsigned long f)116   inline void Reset(unsigned long f) { state &= ~f; }
117 };
118 
119 /*******************************************************************************
120 **
121 ** Function:    isPrintable()
122 **
123 ** Description: determine if 'c' is printable
124 **
125 ** Returns:     1, if printable, otherwise 0
126 **
127 *******************************************************************************/
isPrintable(char c)128 inline bool isPrintable(char c) {
129   return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') ||
130          (c >= '0' && c <= '9') || c == '/' || c == '_' || c == '-' || c == '.';
131 }
132 
133 /*******************************************************************************
134 **
135 ** Function:    isDigit()
136 **
137 ** Description: determine if 'c' is numeral digit
138 **
139 ** Returns:     true, if numerical digit
140 **
141 *******************************************************************************/
isDigit(char c,int base)142 inline bool isDigit(char c, int base) {
143   if ('0' <= c && c <= '9') return true;
144   if (base == 16) {
145     if (('A' <= c && c <= 'F') || ('a' <= c && c <= 'f')) return true;
146   }
147   return false;
148 }
149 
150 /*******************************************************************************
151 **
152 ** Function:    getDigitValue()
153 **
154 ** Description: return numerical value of a decimal or hex char
155 **
156 ** Returns:     numerical value if decimal or hex char, otherwise 0
157 **
158 *******************************************************************************/
getDigitValue(char c,int base)159 inline int getDigitValue(char c, int base) {
160   if ('0' <= c && c <= '9') return c - '0';
161   if (base == 16) {
162     if ('A' <= c && c <= 'F')
163       return c - 'A' + 10;
164     else if ('a' <= c && c <= 'f')
165       return c - 'a' + 10;
166   }
167   return 0;
168 }
169 
170 /*******************************************************************************
171 **
172 ** Function:    findConfigFilePathFromTransportConfigPaths()
173 **
174 ** Description: find a config file path with a given config name from transport
175 **              config paths
176 **
177 ** Returns:     none
178 **
179 *******************************************************************************/
findConfigFilePathFromTransportConfigPaths(const string & configName,string & filePath)180 void findConfigFilePathFromTransportConfigPaths(const string& configName,
181                                                 string& filePath) {
182   for (int i = 0; i < transport_config_path_size - 1; i++) {
183     filePath.assign(transport_config_paths[i]);
184     filePath += configName;
185     struct stat file_stat;
186     if (stat(filePath.c_str(), &file_stat) == 0 && S_ISREG(file_stat.st_mode)) {
187       return;
188     }
189   }
190   filePath.assign(transport_config_paths[transport_config_path_size - 1]);
191   filePath += configName;
192 }
193 
194 /*******************************************************************************
195 **
196 ** Function:    CNfcConfig::readConfig()
197 **
198 ** Description: read Config settings and parse them into a linked list
199 **              move the element from linked list to a array at the end
200 **
201 ** Returns:     1, if there are any config data, 0 otherwise
202 **
203 *******************************************************************************/
readConfig(const char * name,bool bResetContent)204 bool CNfcConfig::readConfig(const char* name, bool bResetContent) {
205   enum {
206     BEGIN_LINE = 1,
207     TOKEN,
208     STR_VALUE,
209     NUM_VALUE,
210     BEGIN_HEX,
211     BEGIN_QUOTE,
212     END_LINE
213   };
214 
215   FILE* fd;
216   struct stat buf;
217   string token;
218   string strValue;
219   unsigned long numValue = 0;
220   CNfcParam* pParam = NULL;
221   int i = 0;
222   int base = 0;
223   char c;
224   int bflag = 0;
225   state = BEGIN_LINE;
226   /* open config file, read it into a buffer */
227   if ((fd = fopen(name, "rb")) == NULL) {
228     ALOGE("%s Cannot open config file %s\n", __func__, name);
229     if (bResetContent) {
230       ALOGE("%s Using default value for all settings\n", __func__);
231       mValidFile = false;
232     }
233     return false;
234   }
235   stat(name, &buf);
236   m_timeStamp = (unsigned long)buf.st_mtime;
237 
238   mValidFile = true;
239   if (size() > 0) {
240     if (bResetContent)
241       clean();
242     else
243       moveToList();
244   }
245 
246   while (!feof(fd) && fread(&c, 1, 1, fd) == 1) {
247     switch (state & 0xff) {
248       case BEGIN_LINE:
249         if (c == '#')
250           state = END_LINE;
251         else if (isPrintable(c)) {
252           i = 0;
253           token.erase();
254           strValue.erase();
255           state = TOKEN;
256           token.push_back(c);
257         }
258         break;
259       case TOKEN:
260         if (c == '=') {
261           token.push_back('\0');
262           state = BEGIN_QUOTE;
263         } else if (isPrintable(c))
264           token.push_back(c);
265         else
266           state = END_LINE;
267         break;
268       case BEGIN_QUOTE:
269         if (c == '"') {
270           state = STR_VALUE;
271           base = 0;
272         } else if (c == '0')
273           state = BEGIN_HEX;
274         else if (isDigit(c, 10)) {
275           state = NUM_VALUE;
276           base = 10;
277           numValue = getDigitValue(c, base);
278           i = 0;
279         } else if (c == '{') {
280           state = NUM_VALUE;
281           bflag = 1;
282           base = 16;
283           i = 0;
284           Set(IsStringValue);
285         } else
286           state = END_LINE;
287         break;
288       case BEGIN_HEX:
289         if (c == 'x' || c == 'X') {
290           state = NUM_VALUE;
291           base = 16;
292           numValue = 0;
293           i = 0;
294           break;
295         } else if (isDigit(c, 10)) {
296           state = NUM_VALUE;
297           base = 10;
298           numValue = getDigitValue(c, base);
299           break;
300         } else if (c != '\n' && c != '\r') {
301           state = END_LINE;
302           break;
303         }
304       // fall through to numValue to handle numValue
305 
306       case NUM_VALUE:
307         if (isDigit(c, base)) {
308           numValue *= base;
309           numValue += getDigitValue(c, base);
310           ++i;
311         } else if (bflag == 1 &&
312                    (c == ' ' || c == '\r' || c == '\n' || c == '\t')) {
313           break;
314         } else if (base == 16 &&
315                    (c == ',' || c == ':' || c == '-' || c == ' ' || c == '}')) {
316           if (c == '}') {
317             bflag = 0;
318           }
319           if (i > 0) {
320             int n = (i + 1) / 2;
321             while (n-- > 0) {
322               numValue = numValue >> (n * 8);
323               unsigned char c = (numValue)&0xFF;
324               strValue.push_back(c);
325             }
326           }
327 
328           Set(IsStringValue);
329           numValue = 0;
330           i = 0;
331         } else {
332           if (c == '\n' || c == '\r') {
333             if (bflag == 0) {
334               state = BEGIN_LINE;
335             }
336           } else {
337             if (bflag == 0) {
338               state = END_LINE;
339             }
340           }
341           if (Is(IsStringValue) && base == 16 && i > 0) {
342             int n = (i + 1) / 2;
343             while (n-- > 0) strValue.push_back(((numValue >> (n * 8)) & 0xFF));
344           }
345           if (strValue.length() > 0)
346             pParam = new CNfcParam(token.c_str(), strValue);
347           else
348             pParam = new CNfcParam(token.c_str(), numValue);
349           add(pParam);
350           strValue.erase();
351           numValue = 0;
352         }
353         break;
354       case STR_VALUE:
355         if (c == '"') {
356           strValue.push_back('\0');
357           state = END_LINE;
358           pParam = new CNfcParam(token.c_str(), strValue);
359           add(pParam);
360         } else if (isPrintable(c))
361           strValue.push_back(c);
362         break;
363       case END_LINE:
364         if (c == '\n' || c == '\r') state = BEGIN_LINE;
365         break;
366       default:
367         break;
368     }
369   }
370 
371   fclose(fd);
372 
373   moveFromList();
374   return size() > 0;
375 }
376 
377 /*******************************************************************************
378 **
379 ** Function:    CNfcConfig::CNfcConfig()
380 **
381 ** Description: class constructor
382 **
383 ** Returns:     none
384 **
385 *******************************************************************************/
CNfcConfig()386 CNfcConfig::CNfcConfig() : mValidFile(true), m_timeStamp(0), state(0) {}
387 
388 /*******************************************************************************
389 **
390 ** Function:    CNfcConfig::~CNfcConfig()
391 **
392 ** Description: class destructor
393 **
394 ** Returns:     none
395 **
396 *******************************************************************************/
~CNfcConfig()397 CNfcConfig::~CNfcConfig() {}
398 
399 /*******************************************************************************
400 **
401 ** Function:    CNfcConfig::GetInstance()
402 **
403 ** Description: get class singleton object
404 **
405 ** Returns:     none
406 **
407 *******************************************************************************/
GetInstance()408 CNfcConfig& CNfcConfig::GetInstance() {
409   static CNfcConfig theInstance;
410 
411   if (theInstance.size() == 0 && theInstance.mValidFile) {
412     string strPath;
413     if (alternative_config_path[0] != '\0') {
414       strPath.assign(alternative_config_path);
415       strPath += config_name;
416       theInstance.readConfig(strPath.c_str(), true);
417       if (!theInstance.empty()) {
418         return theInstance;
419       }
420     }
421     findConfigFilePathFromTransportConfigPaths(config_name, strPath);
422     theInstance.readConfig(strPath.c_str(), true);
423   }
424 
425   return theInstance;
426 }
427 
428 /*******************************************************************************
429 **
430 ** Function:    CNfcConfig::getValue()
431 **
432 ** Description: get a string value of a setting
433 **
434 ** Returns:     true if setting exists
435 **              false if setting does not exist
436 **
437 *******************************************************************************/
getValue(const char * name,char * pValue,size_t len) const438 bool CNfcConfig::getValue(const char* name, char* pValue, size_t len) const {
439   const CNfcParam* pParam = find(name);
440   if (pParam == NULL) return false;
441 
442   if (pParam->str_len() > 0) {
443     memset(pValue, 0, len);
444     memcpy(pValue, pParam->str_value(), pParam->str_len());
445     return true;
446   }
447   return false;
448 }
449 
getValue(const char * name,char * pValue,long len,long * readlen) const450 bool CNfcConfig::getValue(const char* name, char* pValue, long len,
451                           long* readlen) const {
452   const CNfcParam* pParam = find(name);
453   if (pParam == NULL) return false;
454 
455   if (pParam->str_len() > 0) {
456     if (pParam->str_len() <= (unsigned long)len) {
457       memset(pValue, 0, len);
458       memcpy(pValue, pParam->str_value(), pParam->str_len());
459       *readlen = pParam->str_len();
460     } else {
461       *readlen = -1;
462     }
463 
464     return true;
465   }
466   return false;
467 }
468 
469 /*******************************************************************************
470 **
471 ** Function:    CNfcConfig::getValue()
472 **
473 ** Description: get a long numerical value of a setting
474 **
475 ** Returns:     true if setting exists
476 **              false if setting does not exist
477 **
478 *******************************************************************************/
getValue(const char * name,unsigned long & rValue) const479 bool CNfcConfig::getValue(const char* name, unsigned long& rValue) const {
480   const CNfcParam* pParam = find(name);
481   if (pParam == NULL) return false;
482 
483   if (pParam->str_len() == 0) {
484     rValue = static_cast<unsigned long>(pParam->numValue());
485     return true;
486   }
487   return false;
488 }
489 
490 /*******************************************************************************
491 **
492 ** Function:    CNfcConfig::getValue()
493 **
494 ** Description: get a short numerical value of a setting
495 **
496 ** Returns:     true if setting exists
497 **              false if setting does not exist
498 **
499 *******************************************************************************/
getValue(const char * name,unsigned short & rValue) const500 bool CNfcConfig::getValue(const char* name, unsigned short& rValue) const {
501   const CNfcParam* pParam = find(name);
502   if (pParam == NULL) return false;
503 
504   if (pParam->str_len() == 0) {
505     rValue = static_cast<unsigned short>(pParam->numValue());
506     return true;
507   }
508   return false;
509 }
510 
511 /*******************************************************************************
512 **
513 ** Function:    CNfcConfig::find()
514 **
515 ** Description: search if a setting exist in the setting array
516 **
517 ** Returns:     pointer to the setting object
518 **
519 *******************************************************************************/
find(const char * p_name) const520 const CNfcParam* CNfcConfig::find(const char* p_name) const {
521   if (size() == 0) return NULL;
522 
523   for (const_iterator it = begin(), itEnd = end(); it != itEnd; ++it) {
524     if (**it < p_name) {
525       continue;
526     } else if (**it == p_name) {
527       if ((*it)->str_len() > 0) {
528         NXPLOG_EXTNS_D("%s found %s=%s\n", __func__, p_name,
529                        (*it)->str_value());
530       } else {
531         NXPLOG_EXTNS_D("%s found %s=(0x%lx)\n", __func__, p_name,
532                        (*it)->numValue());
533       }
534       return *it;
535     } else
536       break;
537   }
538   return NULL;
539 }
540 
541 /*******************************************************************************
542 **
543 ** Function:    CNfcConfig::clean()
544 **
545 ** Description: reset the setting array
546 **
547 ** Returns:     none
548 **
549 *******************************************************************************/
clean()550 void CNfcConfig::clean() {
551   if (size() == 0) return;
552 
553   for (iterator it = begin(), itEnd = end(); it != itEnd; ++it) delete *it;
554   clear();
555 }
556 
557 /*******************************************************************************
558 **
559 ** Function:    CNfcConfig::Add()
560 **
561 ** Description: add a setting object to the list
562 **
563 ** Returns:     none
564 **
565 *******************************************************************************/
add(const CNfcParam * pParam)566 void CNfcConfig::add(const CNfcParam* pParam) {
567   if (m_list.size() == 0) {
568     m_list.push_back(pParam);
569     return;
570   }
571   for (list<const CNfcParam *>::iterator it = m_list.begin(),
572                                          itEnd = m_list.end();
573        it != itEnd; ++it) {
574     if (**it < pParam->c_str()) continue;
575     m_list.insert(it, pParam);
576     return;
577   }
578   m_list.push_back(pParam);
579 }
580 
581 /*******************************************************************************
582 **
583 ** Function:    CNfcConfig::moveFromList()
584 **
585 ** Description: move the setting object from list to array
586 **
587 ** Returns:     none
588 **
589 *******************************************************************************/
moveFromList()590 void CNfcConfig::moveFromList() {
591   if (m_list.size() == 0) return;
592 
593   for (list<const CNfcParam *>::iterator it = m_list.begin(),
594                                          itEnd = m_list.end();
595        it != itEnd; ++it)
596     push_back(*it);
597   m_list.clear();
598 }
599 
600 /*******************************************************************************
601 **
602 ** Function:    CNfcConfig::moveToList()
603 **
604 ** Description: move the setting object from array to list
605 **
606 ** Returns:     none
607 **
608 *******************************************************************************/
moveToList()609 void CNfcConfig::moveToList() {
610   if (m_list.size() != 0) m_list.clear();
611 
612   for (iterator it = begin(), itEnd = end(); it != itEnd; ++it)
613     m_list.push_back(*it);
614   clear();
615 }
616 
617 #if 0
618 /*******************************************************************************
619 **
620 ** Function:    CNfcConfig::checkTimestamp()
621 **
622 ** Description: check if config file has modified
623 **
624 ** Returns:     0 if not modified, 1 otherwise.
625 **
626 *******************************************************************************/
627 int CNfcConfig::checkTimestamp()
628 {
629     FILE*   fd;
630     struct stat st;
631     unsigned long value = 0;
632     int ret = 0;
633 
634     if(stat(config_timestamp_path, &st) != 0)
635     {
636         ALOGD("%s file %s not exist, creat it.\n", __func__, config_timestamp_path);
637         if ((fd = fopen(config_timestamp_path, "w+")) != NULL)
638         {
639             fwrite(&m_timeStamp, sizeof(unsigned long), 1, fd);
640             fclose(fd);
641         }
642         return 1;
643     }
644     else
645     {
646         fd = fopen(config_timestamp_path, "r+");
647         if(fd == NULL)
648         {
649             ALOGE("%s Cannot open file %s\n", __func__, config_timestamp_path);
650             return 1;
651         }
652 
653         fread(&value, sizeof(unsigned long), 1, fd);
654         ret = (value != m_timeStamp);
655         if(ret)
656         {
657             fseek(fd, 0, SEEK_SET);
658             fwrite(&m_timeStamp, sizeof(unsigned long), 1, fd);
659         }
660         fclose(fd);
661     }
662     return ret;
663 }
664 
665 #endif
666 /*******************************************************************************
667 **
668 ** Function:    CNfcConfig::checkforTimestamp()
669 **
670 ** Description: check if config file has modified
671 **
672 ** Returns:     0 if not modified, 1 otherwise.
673 **
674 *******************************************************************************/
checkTimestamp()675 int CNfcConfig::checkTimestamp() {
676   FILE* fd;
677   struct stat st;
678   unsigned long value = 0;
679   int ret = 0;
680 
681   if (stat(config_timestamp_path, &st) != 0) {
682     ALOGD("%s file not exist.\n", __func__);
683     return 1;
684   } else {
685     fd = fopen(config_timestamp_path, "r+");
686     if (fd == NULL) {
687       ALOGE("%s Cannot open file %s\n", __func__, config_timestamp_path);
688       return 1;
689     }
690 
691     fread(&value, sizeof(unsigned long), 1, fd);
692     ret = (value != m_timeStamp);
693     fclose(fd);
694   }
695   return ret;
696 }
697 
698 /*******************************************************************************
699 **
700 ** Function:    CNfcConfig::updateTimestamp()
701 **
702 ** Description: update if config file has modified
703 **
704 ** Returns:     0 if not modified, 1 otherwise.
705 **
706 *******************************************************************************/
updateTimestamp()707 int CNfcConfig::updateTimestamp() {
708   FILE* fd;
709   struct stat st;
710   unsigned long value = 0;
711   int ret = 0;
712 
713   if (stat(config_timestamp_path, &st) != 0) {
714     ALOGD("%s file %s not exist, creat it.\n", __func__, config_timestamp_path);
715     fd = fopen(config_timestamp_path, "w+");
716     if (fd != NULL) {
717       fwrite(&m_timeStamp, sizeof(unsigned long), 1, fd);
718       fclose(fd);
719     }
720     return 1;
721   } else {
722     fd = fopen(config_timestamp_path, "r+");
723     if (fd == NULL) {
724       ALOGE("%s Cannot open file %s\n", __func__, config_timestamp_path);
725       return 1;
726     }
727 
728     fread(&value, sizeof(unsigned long), 1, fd);
729     ret = (value != m_timeStamp);
730     if (ret) {
731       fseek(fd, 0, SEEK_SET);
732       fwrite(&m_timeStamp, sizeof(unsigned long), 1, fd);
733     }
734     fclose(fd);
735   }
736   return ret;
737 }
738 
739 /*******************************************************************************
740 **
741 ** Function:    CNfcParam::CNfcParam()
742 **
743 ** Description: class constructor
744 **
745 ** Returns:     none
746 **
747 *******************************************************************************/
CNfcParam()748 CNfcParam::CNfcParam() : m_numValue(0) {}
749 
750 /*******************************************************************************
751 **
752 ** Function:    CNfcParam::~CNfcParam()
753 **
754 ** Description: class destructor
755 **
756 ** Returns:     none
757 **
758 *******************************************************************************/
~CNfcParam()759 CNfcParam::~CNfcParam() {}
760 
761 /*******************************************************************************
762 **
763 ** Function:    CNfcParam::CNfcParam()
764 **
765 ** Description: class copy constructor
766 **
767 ** Returns:     none
768 **
769 *******************************************************************************/
CNfcParam(const char * name,const string & value)770 CNfcParam::CNfcParam(const char* name, const string& value)
771     : string(name), m_str_value(value), m_numValue(0) {}
772 
773 /*******************************************************************************
774 **
775 ** Function:    CNfcParam::CNfcParam()
776 **
777 ** Description: class copy constructor
778 **
779 ** Returns:     none
780 **
781 *******************************************************************************/
CNfcParam(const char * name,unsigned long value)782 CNfcParam::CNfcParam(const char* name, unsigned long value)
783     : string(name), m_numValue(value) {}
784 
785 /*******************************************************************************
786 **
787 ** Function:    GetStrValue
788 **
789 ** Description: API function for getting a string value of a setting
790 **
791 ** Returns:     True if found, otherwise False.
792 **
793 *******************************************************************************/
GetNxpStrValue(const char * name,char * pValue,unsigned long len)794 extern "C" int GetNxpStrValue(const char* name, char* pValue,
795                               unsigned long len) {
796   CNfcConfig& rConfig = CNfcConfig::GetInstance();
797 
798   return rConfig.getValue(name, pValue, len);
799 }
800 
801 /*******************************************************************************
802 **
803 ** Function:    GetByteArrayValue()
804 **
805 ** Description: Read byte array value from the config file.
806 **
807 ** Parameters:
808 **              name - name of the config param to read.
809 **              pValue  - pointer to input buffer.
810 **              bufflen - input buffer length.
811 **              len - out parameter to return the number of bytes read from
812 **                    config file, return -1 in case bufflen is not enough.
813 **
814 ** Returns:     TRUE[1] if config param name is found in the config file, else
815 **              FALSE[0]
816 **
817 *******************************************************************************/
GetNxpByteArrayValue(const char * name,char * pValue,long bufflen,long * len)818 extern "C" int GetNxpByteArrayValue(const char* name, char* pValue,
819                                     long bufflen, long* len) {
820   CNfcConfig& rConfig = CNfcConfig::GetInstance();
821 
822   return rConfig.getValue(name, pValue, bufflen, len);
823 }
824 
825 /*******************************************************************************
826 **
827 ** Function:    GetNumValue
828 **
829 ** Description: API function for getting a numerical value of a setting
830 **
831 ** Returns:     true, if successful
832 **
833 *******************************************************************************/
GetNxpNumValue(const char * name,void * pValue,unsigned long len)834 extern "C" int GetNxpNumValue(const char* name, void* pValue,
835                               unsigned long len) {
836   if (!pValue) return false;
837 
838   CNfcConfig& rConfig = CNfcConfig::GetInstance();
839   const CNfcParam* pParam = rConfig.find(name);
840 
841   if (pParam == NULL) return false;
842   unsigned long v = pParam->numValue();
843   if (v == 0 && pParam->str_len() > 0 && pParam->str_len() < 4) {
844     const unsigned char* p = (const unsigned char*)pParam->str_value();
845     for (unsigned int i = 0; i < pParam->str_len(); ++i) {
846       v *= 256;
847       v += *p++;
848     }
849   }
850   switch (len) {
851     case sizeof(unsigned long):
852       *(static_cast<unsigned long*>(pValue)) = (unsigned long)v;
853       break;
854     case sizeof(unsigned short):
855       *(static_cast<unsigned short*>(pValue)) = (unsigned short)v;
856       break;
857     case sizeof(unsigned char):
858       *(static_cast<unsigned char*>(pValue)) = (unsigned char)v;
859       break;
860     default:
861       return false;
862   }
863   return true;
864 }
865 
866 /*******************************************************************************
867 **
868 ** Function:    resetConfig
869 **
870 ** Description: reset settings array
871 **
872 ** Returns:     none
873 **
874 *******************************************************************************/
resetNxpConfig()875 extern "C" void resetNxpConfig()
876 
877 {
878   CNfcConfig& rConfig = CNfcConfig::GetInstance();
879 
880   rConfig.clean();
881 }
882 
883 /*******************************************************************************
884 **
885 ** Function:    readOptionalConfig()
886 **
887 ** Description: read Config settings from an optional conf file
888 **
889 ** Returns:     none
890 **
891 *******************************************************************************/
readOptionalConfig(const char * extra)892 void readOptionalConfig(const char* extra) {
893   string strPath;
894   string configName(extra_config_base);
895   configName += extra;
896   configName += extra_config_ext;
897 
898   if (alternative_config_path[0] != '\0') {
899     strPath.assign(alternative_config_path);
900     strPath += configName;
901   } else {
902     findConfigFilePathFromTransportConfigPaths(configName, strPath);
903   }
904 
905   CNfcConfig::GetInstance().readConfig(strPath.c_str(), false);
906 }
907 
908 /*******************************************************************************
909 **
910 ** Function:    isNxpConfigModified()
911 **
912 ** Description: check if config file has modified
913 **
914 ** Returns:     0 if not modified, 1 otherwise.
915 **
916 *******************************************************************************/
isNxpConfigModified()917 extern "C" int isNxpConfigModified() {
918   CNfcConfig& rConfig = CNfcConfig::GetInstance();
919   return rConfig.checkTimestamp();
920 }
921 
922 /*******************************************************************************
923 **
924 ** Function:    updateNxpConfigTimestamp()
925 **
926 ** Description: update if config file has modified
927 **
928 ** Returns:     0 if not modified, 1 otherwise.
929 **
930 *******************************************************************************/
updateNxpConfigTimestamp()931 extern "C" int updateNxpConfigTimestamp() {
932   CNfcConfig& rConfig = CNfcConfig::GetInstance();
933   return rConfig.updateTimestamp();
934 }
935