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