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