Home | History | Annotate | Download | only in jni
      1 /*
      2  * Copyright (C) 2012 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 /*
     18  *  Import and export general routing data using a XML file.
     19  */
     20 #include "OverrideLog.h"
     21 #include "RouteDataSet.h"
     22 #include "libxml/xmlmemory.h"
     23 #include <errno.h>
     24 #include <sys/stat.h>
     25 
     26 extern char bcm_nfc_location[];
     27 
     28 
     29 /*******************************************************************************
     30 **
     31 ** Function:        AidBuffer
     32 **
     33 ** Description:     Parse a string of hex numbers.  Store result in an array of
     34 **                  bytes.
     35 **                  aid: string of hex numbers.
     36 **
     37 ** Returns:         None.
     38 **
     39 *******************************************************************************/
     40 AidBuffer::AidBuffer (std::string& aid)
     41 :   mBuffer (NULL),
     42     mBufferLen (0)
     43 {
     44     unsigned int num = 0;
     45     const char delimiter = ':';
     46     std::string::size_type pos1 = 0;
     47     std::string::size_type pos2 = aid.find_first_of (delimiter);
     48 
     49     //parse the AID string; each hex number is separated by a colon;
     50     mBuffer = new UINT8 [aid.length()];
     51     while (true)
     52     {
     53         num = 0;
     54         if (pos2 == std::string::npos)
     55         {
     56             sscanf (aid.substr(pos1).c_str(), "%x", &num);
     57             mBuffer [mBufferLen] = (UINT8) num;
     58             mBufferLen++;
     59             break;
     60         }
     61         else
     62         {
     63             sscanf (aid.substr(pos1, pos2-pos1+1).c_str(), "%x", &num);
     64             mBuffer [mBufferLen] = (UINT8) num;
     65             mBufferLen++;
     66             pos1 = pos2 + 1;
     67             pos2 = aid.find_first_of (delimiter, pos1);
     68         }
     69     }
     70 }
     71 
     72 
     73 /*******************************************************************************
     74 **
     75 ** Function:        ~AidBuffer
     76 **
     77 ** Description:     Release all resources.
     78 **
     79 ** Returns:         None.
     80 **
     81 *******************************************************************************/
     82 AidBuffer::~AidBuffer ()
     83 {
     84     delete [] mBuffer;
     85 }
     86 
     87 
     88 /*******************************************************************************/
     89 /*******************************************************************************/
     90 
     91 
     92 const char* RouteDataSet::sConfigFile = "/param/route.xml";
     93 
     94 
     95 /*******************************************************************************
     96 **
     97 ** Function:        ~RouteDataSet
     98 **
     99 ** Description:     Release all resources.
    100 **
    101 ** Returns:         None.
    102 **
    103 *******************************************************************************/
    104 RouteDataSet::~RouteDataSet ()
    105 {
    106     deleteDatabase ();
    107 }
    108 
    109 
    110 /*******************************************************************************
    111 **
    112 ** Function:        initialize
    113 **
    114 ** Description:     Initialize resources.
    115 **
    116 ** Returns:         True if ok.
    117 **
    118 *******************************************************************************/
    119 bool RouteDataSet::initialize ()
    120 {
    121     static const char fn [] = "RouteDataSet::initialize";
    122     ALOGD ("%s: enter", fn);
    123     //check that the libxml2 version in use is compatible
    124     //with the version the software has been compiled with
    125     LIBXML_TEST_VERSION
    126     ALOGD ("%s: exit; return=true", fn);
    127     return true;
    128 }
    129 
    130 
    131 /*******************************************************************************
    132 **
    133 ** Function:        deleteDatabase
    134 **
    135 ** Description:     Delete all routes stored in all databases.
    136 **
    137 ** Returns:         None.
    138 **
    139 *******************************************************************************/
    140 void RouteDataSet::deleteDatabase ()
    141 {
    142     static const char fn [] = "RouteDataSet::deleteDatabase";
    143     ALOGD ("%s: default db size=%u; sec elem db size=%u", fn, mDefaultRouteDatabase.size(), mSecElemRouteDatabase.size());
    144     Database::iterator it;
    145 
    146     for (it = mDefaultRouteDatabase.begin(); it != mDefaultRouteDatabase.end(); it++)
    147         delete (*it);
    148     mDefaultRouteDatabase.clear ();
    149 
    150     for (it = mSecElemRouteDatabase.begin(); it != mSecElemRouteDatabase.end(); it++)
    151         delete (*it);
    152     mSecElemRouteDatabase.clear ();
    153 }
    154 
    155 
    156 /*******************************************************************************
    157 **
    158 ** Function:        import
    159 **
    160 ** Description:     Import data from an XML file.  Fill the databases.
    161 **
    162 ** Returns:         True if ok.
    163 **
    164 *******************************************************************************/
    165 bool RouteDataSet::import ()
    166 {
    167     static const char fn [] = "RouteDataSet::import";
    168     ALOGD ("%s: enter", fn);
    169     bool retval = false;
    170     xmlDocPtr doc;
    171     xmlNodePtr node1;
    172     std::string strFilename(bcm_nfc_location);
    173     strFilename += sConfigFile;
    174 
    175     deleteDatabase ();
    176 
    177     doc = xmlParseFile (strFilename.c_str());
    178     if (doc == NULL)
    179     {
    180         ALOGD ("%s: fail parse", fn);
    181         goto TheEnd;
    182     }
    183 
    184     node1 = xmlDocGetRootElement (doc);
    185     if (node1 == NULL)
    186     {
    187         ALOGE ("%s: fail root element", fn);
    188         goto TheEnd;
    189     }
    190     ALOGD ("%s: root=%s", fn, node1->name);
    191 
    192     node1 = node1->xmlChildrenNode;
    193     while (node1) //loop through all elements in <Routes ...
    194     {
    195         if (xmlStrcmp(node1->name, (const xmlChar*) "Route")==0)
    196         {
    197             xmlChar* value = xmlGetProp (node1, (const xmlChar*) "Type");
    198             if (value && (xmlStrcmp (value, (const xmlChar*) "SecElemSelectedRoutes") == 0))
    199             {
    200                 ALOGD ("%s: found SecElemSelectedRoutes", fn);
    201                 xmlNodePtr node2 = node1->xmlChildrenNode;
    202                 while (node2) //loop all elements in <Route Type="SecElemSelectedRoutes" ...
    203                 {
    204                     if (xmlStrcmp(node2->name, (const xmlChar*) "Proto")==0)
    205                         importProtocolRoute (node2, mSecElemRouteDatabase);
    206                     else if (xmlStrcmp(node2->name, (const xmlChar*) "Tech")==0)
    207                         importTechnologyRoute (node2, mSecElemRouteDatabase);
    208                     node2 = node2->next;
    209                 } //loop all elements in <Route Type="SecElemSelectedRoutes" ...
    210             }
    211             else if (value && (xmlStrcmp (value, (const xmlChar*) "DefaultRoutes") == 0))
    212             {
    213                 ALOGD ("%s: found DefaultRoutes", fn);
    214                 xmlNodePtr node2 = node1->xmlChildrenNode;
    215                 while (node2) //loop all elements in <Route Type="DefaultRoutes" ...
    216                 {
    217                     if (xmlStrcmp(node2->name, (const xmlChar*) "Proto")==0)
    218                         importProtocolRoute (node2, mDefaultRouteDatabase);
    219                     else if (xmlStrcmp(node2->name, (const xmlChar*) "Tech")==0)
    220                         importTechnologyRoute (node2, mDefaultRouteDatabase);
    221                     node2 = node2->next;
    222                 } //loop all elements in <Route Type="DefaultRoutes" ...
    223             }
    224             if (value)
    225                 xmlFree (value);
    226         } //check <Route ...
    227         node1 = node1->next;
    228     } //loop through all elements in <Routes ...
    229     retval = true;
    230 
    231 TheEnd:
    232     xmlFreeDoc (doc);
    233     xmlCleanupParser ();
    234     ALOGD ("%s: exit; return=%u", fn, retval);
    235     return retval;
    236 }
    237 
    238 
    239 /*******************************************************************************
    240 **
    241 ** Function:        saveToFile
    242 **
    243 ** Description:     Save XML data from a string into a file.
    244 **                  routesXml: XML that represents routes.
    245 **
    246 ** Returns:         True if ok.
    247 **
    248 *******************************************************************************/
    249 bool RouteDataSet::saveToFile (const char* routesXml)
    250 {
    251     static const char fn [] = "RouteDataSet::saveToFile";
    252     FILE* fh = NULL;
    253     size_t actualWritten = 0;
    254     bool retval = false;
    255     std::string filename (bcm_nfc_location);
    256     int stat = 0;
    257 
    258     filename.append (sConfigFile);
    259     fh = fopen (filename.c_str (), "w");
    260     if (fh == NULL)
    261     {
    262         ALOGE ("%s: fail to open file", fn);
    263         return false;
    264     }
    265 
    266     actualWritten = fwrite (routesXml, sizeof(char), strlen(routesXml), fh);
    267     retval = actualWritten == strlen(routesXml);
    268     fclose (fh);
    269     ALOGD ("%s: wrote %u bytes", fn, actualWritten);
    270     if (retval == false)
    271         ALOGE ("%s: error during write", fn);
    272 
    273     //set file permission to
    274     //owner read, write; group read; other read
    275     stat = chmod (filename.c_str (), S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
    276     if (stat == -1)
    277         ALOGE ("%s: error during chmod", fn);
    278     return retval;
    279 }
    280 
    281 
    282 /*******************************************************************************
    283 **
    284 ** Function:        loadFromFile
    285 **
    286 ** Description:     Load XML data from file into a string.
    287 **                  routesXml: string to receive XML data.
    288 **
    289 ** Returns:         True if ok.
    290 **
    291 *******************************************************************************/
    292 bool RouteDataSet::loadFromFile (std::string& routesXml)
    293 {
    294     static const char fn [] = "RouteDataSet::loadFromFile";
    295     FILE* fh = NULL;
    296     size_t actual = 0;
    297     char buffer [1024];
    298     std::string filename (bcm_nfc_location);
    299 
    300     filename.append (sConfigFile);
    301     fh = fopen (filename.c_str (), "r");
    302     if (fh == NULL)
    303     {
    304         ALOGD ("%s: fail to open file", fn);
    305         return false;
    306     }
    307 
    308     while (true)
    309     {
    310         actual = fread (buffer, sizeof(char), sizeof(buffer), fh);
    311         if (actual == 0)
    312             break;
    313         routesXml.append (buffer, actual);
    314     }
    315     fclose (fh);
    316     ALOGD ("%s: read %u bytes", fn, routesXml.length());
    317     return true;
    318 }
    319 
    320 
    321 
    322 
    323 /*******************************************************************************
    324 **
    325 ** Function:        importProtocolRoute
    326 **
    327 ** Description:     Parse data for protocol routes.
    328 **                  element: XML node for one protocol route.
    329 **                  database: store data in this database.
    330 **
    331 ** Returns:         None.
    332 **
    333 *******************************************************************************/
    334 void RouteDataSet::importProtocolRoute (xmlNodePtr& element, Database& database)
    335 {
    336     static const char fn [] = "RouteDataSet::importProtocolRoute";
    337     const xmlChar* id = (const xmlChar*) "Id";
    338     const xmlChar* secElem = (const xmlChar*) "SecElem";
    339     const xmlChar* trueString = (const xmlChar*) "true";
    340     const xmlChar* switchOn = (const xmlChar*) "SwitchOn";
    341     const xmlChar* switchOff = (const xmlChar*) "SwitchOff";
    342     const xmlChar* batteryOff = (const xmlChar*) "BatteryOff";
    343     RouteDataForProtocol* data = new RouteDataForProtocol;
    344     xmlChar* value = NULL;
    345 
    346     ALOGD_IF (sDebug, "%s: element=%s", fn, element->name);
    347     value = xmlGetProp (element, id);
    348     if (value)
    349     {
    350         if (xmlStrcmp (value, (const xmlChar*) "T1T") == 0)
    351             data->mProtocol = NFA_PROTOCOL_MASK_T1T;
    352         else if (xmlStrcmp (value, (const xmlChar*) "T2T") == 0)
    353             data->mProtocol = NFA_PROTOCOL_MASK_T2T;
    354         else if (xmlStrcmp (value, (const xmlChar*) "T3T") == 0)
    355             data->mProtocol = NFA_PROTOCOL_MASK_T3T;
    356         else if (xmlStrcmp (value, (const xmlChar*) "IsoDep") == 0)
    357             data->mProtocol = NFA_PROTOCOL_MASK_ISO_DEP;
    358         xmlFree (value);
    359         ALOGD_IF (sDebug, "%s: %s=0x%X", fn, id, data->mProtocol);
    360     }
    361 
    362     value = xmlGetProp (element, secElem);
    363     if (value)
    364     {
    365         data->mNfaEeHandle = strtol ((char*) value, NULL, 16);
    366         xmlFree (value);
    367         data->mNfaEeHandle = data->mNfaEeHandle | NFA_HANDLE_GROUP_EE;
    368         ALOGD_IF (sDebug, "%s: %s=0x%X", fn, secElem, data->mNfaEeHandle);
    369     }
    370 
    371     value = xmlGetProp (element, switchOn);
    372     if (value)
    373     {
    374         data->mSwitchOn = (xmlStrcmp (value, trueString) == 0);
    375         xmlFree (value);
    376     }
    377 
    378     value = xmlGetProp (element, switchOff);
    379     if (value)
    380     {
    381         data->mSwitchOff = (xmlStrcmp (value, trueString) == 0);
    382         xmlFree (value);
    383     }
    384 
    385     value = xmlGetProp (element, batteryOff);
    386     if (value)
    387     {
    388         data->mBatteryOff = (xmlStrcmp (value, trueString) == 0);
    389         xmlFree (value);
    390     }
    391     database.push_back (data);
    392 }
    393 
    394 
    395 /*******************************************************************************
    396 **
    397 ** Function:        importTechnologyRoute
    398 **
    399 ** Description:     Parse data for technology routes.
    400 **                  element: XML node for one technology route.
    401 **                  database: store data in this database.
    402 **
    403 ** Returns:         None.
    404 **
    405 *******************************************************************************/
    406 void RouteDataSet::importTechnologyRoute (xmlNodePtr& element, Database& database)
    407 {
    408     static const char fn [] = "RouteDataSet::importTechnologyRoute";
    409     const xmlChar* id = (const xmlChar*) "Id";
    410     const xmlChar* secElem = (const xmlChar*) "SecElem";
    411     const xmlChar* trueString = (const xmlChar*) "true";
    412     const xmlChar* switchOn = (const xmlChar*) "SwitchOn";
    413     const xmlChar* switchOff = (const xmlChar*) "SwitchOff";
    414     const xmlChar* batteryOff = (const xmlChar*) "BatteryOff";
    415     RouteDataForTechnology* data = new RouteDataForTechnology;
    416     xmlChar* value = NULL;
    417 
    418     ALOGD_IF (sDebug, "%s: element=%s", fn, element->name);
    419     value = xmlGetProp (element, id);
    420     if (value)
    421     {
    422         if (xmlStrcmp (value, (const xmlChar*) "NfcA") == 0)
    423             data->mTechnology = NFA_TECHNOLOGY_MASK_A;
    424         else if (xmlStrcmp (value, (const xmlChar*) "NfcB") == 0)
    425             data->mTechnology = NFA_TECHNOLOGY_MASK_B;
    426         else if (xmlStrcmp (value, (const xmlChar*) "NfcF") == 0)
    427             data->mTechnology = NFA_TECHNOLOGY_MASK_F;
    428         xmlFree (value);
    429         ALOGD_IF (sDebug, "%s: %s=0x%X", fn, id, data->mTechnology);
    430     }
    431 
    432     value = xmlGetProp (element, secElem);
    433     if (value)
    434     {
    435         data->mNfaEeHandle = strtol ((char*) value, NULL, 16);
    436         xmlFree (value);
    437         data->mNfaEeHandle = data->mNfaEeHandle | NFA_HANDLE_GROUP_EE;
    438         ALOGD_IF (sDebug, "%s: %s=0x%X", fn, secElem, data->mNfaEeHandle);
    439     }
    440 
    441     value = xmlGetProp (element, switchOn);
    442     if (value)
    443     {
    444         data->mSwitchOn = (xmlStrcmp (value, trueString) == 0);
    445         xmlFree (value);
    446     }
    447 
    448     value = xmlGetProp (element, switchOff);
    449     if (value)
    450     {
    451         data->mSwitchOff = (xmlStrcmp (value, trueString) == 0);
    452         xmlFree (value);
    453     }
    454 
    455     value = xmlGetProp (element, batteryOff);
    456     if (value)
    457     {
    458         data->mBatteryOff = (xmlStrcmp (value, trueString) == 0);
    459         xmlFree (value);
    460     }
    461     database.push_back (data);
    462 }
    463 
    464 
    465 /*******************************************************************************
    466 **
    467 ** Function:        deleteFile
    468 **
    469 ** Description:     Delete route data XML file.
    470 **
    471 ** Returns:         True if ok.
    472 **
    473 *******************************************************************************/
    474 bool RouteDataSet::deleteFile ()
    475 {
    476     static const char fn [] = "RouteDataSet::deleteFile";
    477     std::string filename (bcm_nfc_location);
    478     filename.append (sConfigFile);
    479     int stat = remove (filename.c_str());
    480     ALOGD ("%s: exit %u", fn, stat==0);
    481     return stat == 0;
    482 }
    483 
    484 
    485 /*******************************************************************************
    486 **
    487 ** Function:        getDatabase
    488 **
    489 ** Description:     Obtain a database of routing data.
    490 **                  selection: which database.
    491 **
    492 ** Returns:         Pointer to database.
    493 **
    494 *******************************************************************************/
    495 RouteDataSet::Database* RouteDataSet::getDatabase (DatabaseSelection selection)
    496 {
    497     switch (selection)
    498     {
    499     case DefaultRouteDatabase:
    500         return &mDefaultRouteDatabase;
    501     case SecElemRouteDatabase:
    502         return &mSecElemRouteDatabase;
    503     }
    504     return NULL;
    505 }
    506 
    507 
    508 /*******************************************************************************
    509 **
    510 ** Function:        printDiagnostic
    511 **
    512 ** Description:     Print some diagnostic output.
    513 **
    514 ** Returns:         None.
    515 **
    516 *******************************************************************************/
    517 void RouteDataSet::printDiagnostic ()
    518 {
    519     static const char fn [] = "RouteDataSet::printDiagnostic";
    520     Database* db = getDatabase (DefaultRouteDatabase);
    521 
    522     ALOGD ("%s: default route database", fn);
    523     for (Database::iterator iter = db->begin(); iter != db->end(); iter++)
    524     {
    525         RouteData* routeData = *iter;
    526         switch (routeData->mRouteType)
    527         {
    528         case RouteData::ProtocolRoute:
    529             {
    530                 RouteDataForProtocol* proto = (RouteDataForProtocol*) routeData;
    531                 ALOGD ("%s: ee h=0x%X; protocol=0x%X", fn, proto->mNfaEeHandle, proto->mProtocol);
    532             }
    533             break;
    534         case RouteData::TechnologyRoute:
    535             {
    536                 RouteDataForTechnology* tech = (RouteDataForTechnology*) routeData;
    537                 ALOGD ("%s: ee h=0x%X; technology=0x%X", fn, tech->mNfaEeHandle, tech->mTechnology);
    538             }
    539             break;
    540         }
    541     }
    542 
    543     ALOGD ("%s: sec elem route database", fn);
    544     db = getDatabase (SecElemRouteDatabase);
    545     for (Database::iterator iter2 = db->begin(); iter2 != db->end(); iter2++)
    546     {
    547         RouteData* routeData = *iter2;
    548         switch (routeData->mRouteType)
    549         {
    550         case RouteData::ProtocolRoute:
    551             {
    552                 RouteDataForProtocol* proto = (RouteDataForProtocol*) routeData;
    553                 ALOGD ("%s: ee h=0x%X; protocol=0x%X", fn, proto->mNfaEeHandle, proto->mProtocol);
    554             }
    555             break;
    556         case RouteData::TechnologyRoute:
    557             {
    558                 RouteDataForTechnology* tech = (RouteDataForTechnology*) routeData;
    559                 ALOGD ("%s: ee h=0x%X; technology=0x%X", fn, tech->mNfaEeHandle, tech->mTechnology);
    560             }
    561             break;
    562         }
    563     }
    564 }
    565