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