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