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 
    257     filename.append (sConfigFile);
    258     fh = fopen (filename.c_str (), "w");
    259     if (fh == NULL)
    260     {
    261         ALOGE ("%s: fail to open file", fn);
    262         return false;
    263     }
    264 
    265     actualWritten = fwrite (routesXml, sizeof(char), strlen(routesXml), fh);
    266     retval = actualWritten == strlen(routesXml);
    267     fclose (fh);
    268     ALOGD ("%s: wrote %u bytes", fn, actualWritten);
    269     if (retval == false)
    270         ALOGE ("%s: error during write", fn);
    271 
    272     //set file permission to
    273     //owner read, write; group read; other read
    274     chmod (filename.c_str (), S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
    275     return retval;
    276 }
    277 
    278 
    279 /*******************************************************************************
    280 **
    281 ** Function:        loadFromFile
    282 **
    283 ** Description:     Load XML data from file into a string.
    284 **                  routesXml: string to receive XML data.
    285 **
    286 ** Returns:         True if ok.
    287 **
    288 *******************************************************************************/
    289 bool RouteDataSet::loadFromFile (std::string& routesXml)
    290 {
    291     static const char fn [] = "RouteDataSet::loadFromFile";
    292     FILE* fh = NULL;
    293     size_t actual = 0;
    294     char buffer [1024];
    295     std::string filename (bcm_nfc_location);
    296 
    297     filename.append (sConfigFile);
    298     fh = fopen (filename.c_str (), "r");
    299     if (fh == NULL)
    300     {
    301         ALOGD ("%s: fail to open file", fn);
    302         return false;
    303     }
    304 
    305     while (true)
    306     {
    307         actual = fread (buffer, sizeof(char), sizeof(buffer), fh);
    308         if (actual == 0)
    309             break;
    310         routesXml.append (buffer, actual);
    311     }
    312     fclose (fh);
    313     ALOGD ("%s: read %u bytes", fn, routesXml.length());
    314     return true;
    315 }
    316 
    317 
    318 
    319 
    320 /*******************************************************************************
    321 **
    322 ** Function:        importProtocolRoute
    323 **
    324 ** Description:     Parse data for protocol routes.
    325 **                  element: XML node for one protocol route.
    326 **                  database: store data in this database.
    327 **
    328 ** Returns:         None.
    329 **
    330 *******************************************************************************/
    331 void RouteDataSet::importProtocolRoute (xmlNodePtr& element, Database& database)
    332 {
    333     static const char fn [] = "RouteDataSet::importProtocolRoute";
    334     const xmlChar* id = (const xmlChar*) "Id";
    335     const xmlChar* secElem = (const xmlChar*) "SecElem";
    336     const xmlChar* trueString = (const xmlChar*) "true";
    337     const xmlChar* switchOn = (const xmlChar*) "SwitchOn";
    338     const xmlChar* switchOff = (const xmlChar*) "SwitchOff";
    339     const xmlChar* batteryOff = (const xmlChar*) "BatteryOff";
    340     RouteDataForProtocol* data = new RouteDataForProtocol;
    341     xmlChar* value = NULL;
    342 
    343     ALOGD_IF (sDebug, "%s: element=%s", fn, element->name);
    344     value = xmlGetProp (element, id);
    345     if (value)
    346     {
    347         if (xmlStrcmp (value, (const xmlChar*) "T1T") == 0)
    348             data->mProtocol = NFA_PROTOCOL_MASK_T1T;
    349         else if (xmlStrcmp (value, (const xmlChar*) "T2T") == 0)
    350             data->mProtocol = NFA_PROTOCOL_MASK_T2T;
    351         else if (xmlStrcmp (value, (const xmlChar*) "T3T") == 0)
    352             data->mProtocol = NFA_PROTOCOL_MASK_T3T;
    353         else if (xmlStrcmp (value, (const xmlChar*) "IsoDep") == 0)
    354             data->mProtocol = NFA_PROTOCOL_MASK_ISO_DEP;
    355         xmlFree (value);
    356         ALOGD_IF (sDebug, "%s: %s=0x%X", fn, id, data->mProtocol);
    357     }
    358 
    359     value = xmlGetProp (element, secElem);
    360     if (value)
    361     {
    362         data->mNfaEeHandle = strtol ((char*) value, NULL, 16);
    363         xmlFree (value);
    364         data->mNfaEeHandle = data->mNfaEeHandle | NFA_HANDLE_GROUP_EE;
    365         ALOGD_IF (sDebug, "%s: %s=0x%X", fn, secElem, data->mNfaEeHandle);
    366     }
    367 
    368     value = xmlGetProp (element, switchOn);
    369     if (value)
    370     {
    371         data->mSwitchOn = (xmlStrcmp (value, trueString) == 0);
    372         xmlFree (value);
    373     }
    374 
    375     value = xmlGetProp (element, switchOff);
    376     if (value)
    377     {
    378         data->mSwitchOff = (xmlStrcmp (value, trueString) == 0);
    379         xmlFree (value);
    380     }
    381 
    382     value = xmlGetProp (element, batteryOff);
    383     if (value)
    384     {
    385         data->mBatteryOff = (xmlStrcmp (value, trueString) == 0);
    386         xmlFree (value);
    387     }
    388     database.push_back (data);
    389 }
    390 
    391 
    392 /*******************************************************************************
    393 **
    394 ** Function:        importTechnologyRoute
    395 **
    396 ** Description:     Parse data for technology routes.
    397 **                  element: XML node for one technology route.
    398 **                  database: store data in this database.
    399 **
    400 ** Returns:         None.
    401 **
    402 *******************************************************************************/
    403 void RouteDataSet::importTechnologyRoute (xmlNodePtr& element, Database& database)
    404 {
    405     static const char fn [] = "RouteDataSet::importTechnologyRoute";
    406     const xmlChar* id = (const xmlChar*) "Id";
    407     const xmlChar* secElem = (const xmlChar*) "SecElem";
    408     const xmlChar* trueString = (const xmlChar*) "true";
    409     const xmlChar* switchOn = (const xmlChar*) "SwitchOn";
    410     const xmlChar* switchOff = (const xmlChar*) "SwitchOff";
    411     const xmlChar* batteryOff = (const xmlChar*) "BatteryOff";
    412     RouteDataForTechnology* data = new RouteDataForTechnology;
    413     xmlChar* value = NULL;
    414 
    415     ALOGD_IF (sDebug, "%s: element=%s", fn, element->name);
    416     value = xmlGetProp (element, id);
    417     if (value)
    418     {
    419         if (xmlStrcmp (value, (const xmlChar*) "NfcA") == 0)
    420             data->mTechnology = NFA_TECHNOLOGY_MASK_A;
    421         else if (xmlStrcmp (value, (const xmlChar*) "NfcB") == 0)
    422             data->mTechnology = NFA_TECHNOLOGY_MASK_B;
    423         else if (xmlStrcmp (value, (const xmlChar*) "NfcF") == 0)
    424             data->mTechnology = NFA_TECHNOLOGY_MASK_F;
    425         xmlFree (value);
    426         ALOGD_IF (sDebug, "%s: %s=0x%X", fn, id, data->mTechnology);
    427     }
    428 
    429     value = xmlGetProp (element, secElem);
    430     if (value)
    431     {
    432         data->mNfaEeHandle = strtol ((char*) value, NULL, 16);
    433         xmlFree (value);
    434         data->mNfaEeHandle = data->mNfaEeHandle | NFA_HANDLE_GROUP_EE;
    435         ALOGD_IF (sDebug, "%s: %s=0x%X", fn, secElem, data->mNfaEeHandle);
    436     }
    437 
    438     value = xmlGetProp (element, switchOn);
    439     if (value)
    440     {
    441         data->mSwitchOn = (xmlStrcmp (value, trueString) == 0);
    442         xmlFree (value);
    443     }
    444 
    445     value = xmlGetProp (element, switchOff);
    446     if (value)
    447     {
    448         data->mSwitchOff = (xmlStrcmp (value, trueString) == 0);
    449         xmlFree (value);
    450     }
    451 
    452     value = xmlGetProp (element, batteryOff);
    453     if (value)
    454     {
    455         data->mBatteryOff = (xmlStrcmp (value, trueString) == 0);
    456         xmlFree (value);
    457     }
    458     database.push_back (data);
    459 }
    460 
    461 
    462 /*******************************************************************************
    463 **
    464 ** Function:        deleteFile
    465 **
    466 ** Description:     Delete route data XML file.
    467 **
    468 ** Returns:         True if ok.
    469 **
    470 *******************************************************************************/
    471 bool RouteDataSet::deleteFile ()
    472 {
    473     static const char fn [] = "RouteDataSet::deleteFile";
    474     std::string filename (bcm_nfc_location);
    475     filename.append (sConfigFile);
    476     int stat = remove (filename.c_str());
    477     ALOGD ("%s: exit %u", fn, stat==0);
    478     return stat == 0;
    479 }
    480 
    481 
    482 /*******************************************************************************
    483 **
    484 ** Function:        getDatabase
    485 **
    486 ** Description:     Obtain a database of routing data.
    487 **                  selection: which database.
    488 **
    489 ** Returns:         Pointer to database.
    490 **
    491 *******************************************************************************/
    492 RouteDataSet::Database* RouteDataSet::getDatabase (DatabaseSelection selection)
    493 {
    494     switch (selection)
    495     {
    496     case DefaultRouteDatabase:
    497         return &mDefaultRouteDatabase;
    498     case SecElemRouteDatabase:
    499         return &mSecElemRouteDatabase;
    500     }
    501     return NULL;
    502 }
    503 
    504 
    505 /*******************************************************************************
    506 **
    507 ** Function:        printDiagnostic
    508 **
    509 ** Description:     Print some diagnostic output.
    510 **
    511 ** Returns:         None.
    512 **
    513 *******************************************************************************/
    514 void RouteDataSet::printDiagnostic ()
    515 {
    516     static const char fn [] = "RouteDataSet::printDiagnostic";
    517     Database* db = getDatabase (DefaultRouteDatabase);
    518 
    519     ALOGD ("%s: default route database", fn);
    520     for (Database::iterator iter = db->begin(); iter != db->end(); iter++)
    521     {
    522         RouteData* routeData = *iter;
    523         switch (routeData->mRouteType)
    524         {
    525         case RouteData::ProtocolRoute:
    526             {
    527                 RouteDataForProtocol* proto = (RouteDataForProtocol*) routeData;
    528                 ALOGD ("%s: ee h=0x%X; protocol=0x%X", fn, proto->mNfaEeHandle, proto->mProtocol);
    529             }
    530             break;
    531         // TODO: RouteData::TechnologyRoute isn't handled --- bug?
    532         }
    533     }
    534 
    535     ALOGD ("%s: sec elem route database", fn);
    536     db = getDatabase (SecElemRouteDatabase);
    537     for (Database::iterator iter2 = db->begin(); iter2 != db->end(); iter2++)
    538     {
    539         RouteData* routeData = *iter2;
    540         switch (routeData->mRouteType)
    541         {
    542         case RouteData::ProtocolRoute:
    543             {
    544                 RouteDataForProtocol* proto = (RouteDataForProtocol*) routeData;
    545                 ALOGD ("%s: ee h=0x%X; protocol=0x%X", fn, proto->mNfaEeHandle, proto->mProtocol);
    546             }
    547             break;
    548         case RouteData::TechnologyRoute:
    549             {
    550                 RouteDataForTechnology* tech = (RouteDataForTechnology*) routeData;
    551                 ALOGD ("%s: ee h=0x%X; technology=0x%X", fn, tech->mNfaEeHandle, tech->mTechnology);
    552             }
    553             break;
    554         }
    555     }
    556 }
    557