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