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