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