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