You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
536 lines
18 KiB
536 lines
18 KiB
7 months ago
|
/*
|
||
|
* Copyright (C) 2012 The Android Open Source Project
|
||
|
*
|
||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||
|
* you may not use this file except in compliance with the License.
|
||
|
* You may obtain a copy of the License at
|
||
|
*
|
||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||
|
*
|
||
|
* Unless required by applicable law or agreed to in writing, software
|
||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
|
* See the License for the specific language governing permissions and
|
||
|
* limitations under the License.
|
||
|
*/
|
||
|
|
||
|
/*
|
||
|
* Import and export general routing data using a XML file.
|
||
|
*/
|
||
|
|
||
|
#include <android-base/stringprintf.h>
|
||
|
#include <base/logging.h>
|
||
|
#include <errno.h>
|
||
|
#include <sys/stat.h>
|
||
|
|
||
|
/* NOTE:
|
||
|
* This has to be included AFTER the android-base includes since
|
||
|
* android-base/macros.h defines ATTRIBUTE_UNUSED, also used in the
|
||
|
* tiny XML library.
|
||
|
*/
|
||
|
#include "RouteDataSet.h"
|
||
|
|
||
|
#include "libxml/xmlmemory.h"
|
||
|
|
||
|
using android::base::StringPrintf;
|
||
|
|
||
|
extern std::string nfc_storage_path;
|
||
|
extern bool nfc_debug_enabled;
|
||
|
|
||
|
/*******************************************************************************
|
||
|
**
|
||
|
** Function: AidBuffer
|
||
|
**
|
||
|
** Description: Parse a string of hex numbers. Store result in an array of
|
||
|
** bytes.
|
||
|
** aid: string of hex numbers.
|
||
|
**
|
||
|
** Returns: None.
|
||
|
**
|
||
|
*******************************************************************************/
|
||
|
AidBuffer::AidBuffer(std::string& aid) : mBuffer(NULL), mBufferLen(0) {
|
||
|
unsigned int num = 0;
|
||
|
const char delimiter = ':';
|
||
|
std::string::size_type pos1 = 0;
|
||
|
std::string::size_type pos2 = aid.find_first_of(delimiter);
|
||
|
|
||
|
// parse the AID string; each hex number is separated by a colon;
|
||
|
mBuffer = new uint8_t[aid.length()];
|
||
|
while (true) {
|
||
|
num = 0;
|
||
|
if (pos2 == std::string::npos) {
|
||
|
sscanf(aid.substr(pos1).c_str(), "%x", &num);
|
||
|
mBuffer[mBufferLen] = (uint8_t)num;
|
||
|
mBufferLen++;
|
||
|
break;
|
||
|
} else {
|
||
|
sscanf(aid.substr(pos1, pos2 - pos1 + 1).c_str(), "%x", &num);
|
||
|
mBuffer[mBufferLen] = (uint8_t)num;
|
||
|
mBufferLen++;
|
||
|
pos1 = pos2 + 1;
|
||
|
pos2 = aid.find_first_of(delimiter, pos1);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*******************************************************************************
|
||
|
**
|
||
|
** Function: ~AidBuffer
|
||
|
**
|
||
|
** Description: Release all resources.
|
||
|
**
|
||
|
** Returns: None.
|
||
|
**
|
||
|
*******************************************************************************/
|
||
|
AidBuffer::~AidBuffer() { delete[] mBuffer; }
|
||
|
|
||
|
/*******************************************************************************/
|
||
|
/*******************************************************************************/
|
||
|
|
||
|
const char* RouteDataSet::sConfigFile = "/param/route.xml";
|
||
|
|
||
|
/*******************************************************************************
|
||
|
**
|
||
|
** Function: ~RouteDataSet
|
||
|
**
|
||
|
** Description: Release all resources.
|
||
|
**
|
||
|
** Returns: None.
|
||
|
**
|
||
|
*******************************************************************************/
|
||
|
RouteDataSet::~RouteDataSet() { deleteDatabase(); }
|
||
|
|
||
|
/*******************************************************************************
|
||
|
**
|
||
|
** Function: initialize
|
||
|
**
|
||
|
** Description: Initialize resources.
|
||
|
**
|
||
|
** Returns: True if ok.
|
||
|
**
|
||
|
*******************************************************************************/
|
||
|
bool RouteDataSet::initialize() {
|
||
|
DLOG_IF(INFO, nfc_debug_enabled)
|
||
|
<< StringPrintf("%s: enter", "RouteDataSet::initialize");
|
||
|
// check that the libxml2 version in use is compatible
|
||
|
// with the version the software has been compiled with
|
||
|
LIBXML_TEST_VERSION
|
||
|
DLOG_IF(INFO, nfc_debug_enabled)
|
||
|
<< StringPrintf("%s: exit; return=true", "RouteDataSet::initialize");
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
/*******************************************************************************
|
||
|
**
|
||
|
** Function: deleteDatabase
|
||
|
**
|
||
|
** Description: Delete all routes stored in all databases.
|
||
|
**
|
||
|
** Returns: None.
|
||
|
**
|
||
|
*******************************************************************************/
|
||
|
void RouteDataSet::deleteDatabase() {
|
||
|
DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
|
||
|
"%s: default db size=%zu; sec elem db size=%zu",
|
||
|
"RouteDataSet::deleteDatabase", mDefaultRouteDatabase.size(),
|
||
|
mSecElemRouteDatabase.size());
|
||
|
Database::iterator it;
|
||
|
|
||
|
for (it = mDefaultRouteDatabase.begin(); it != mDefaultRouteDatabase.end();
|
||
|
it++)
|
||
|
delete (*it);
|
||
|
mDefaultRouteDatabase.clear();
|
||
|
|
||
|
for (it = mSecElemRouteDatabase.begin(); it != mSecElemRouteDatabase.end();
|
||
|
it++)
|
||
|
delete (*it);
|
||
|
mSecElemRouteDatabase.clear();
|
||
|
}
|
||
|
|
||
|
/*******************************************************************************
|
||
|
**
|
||
|
** Function: import
|
||
|
**
|
||
|
** Description: Import data from an XML file. Fill the databases.
|
||
|
**
|
||
|
** Returns: True if ok.
|
||
|
**
|
||
|
*******************************************************************************/
|
||
|
bool RouteDataSet::import() {
|
||
|
static const char fn[] = "RouteDataSet::import";
|
||
|
DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: enter", fn);
|
||
|
bool retval = false;
|
||
|
xmlDocPtr doc;
|
||
|
xmlNodePtr node1;
|
||
|
std::string strFilename(nfc_storage_path);
|
||
|
strFilename += sConfigFile;
|
||
|
|
||
|
deleteDatabase();
|
||
|
|
||
|
doc = xmlParseFile(strFilename.c_str());
|
||
|
if (doc == NULL) {
|
||
|
DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: fail parse", fn);
|
||
|
goto TheEnd;
|
||
|
}
|
||
|
|
||
|
node1 = xmlDocGetRootElement(doc);
|
||
|
if (node1 == NULL) {
|
||
|
LOG(ERROR) << StringPrintf("%s: fail root element", fn);
|
||
|
goto TheEnd;
|
||
|
}
|
||
|
DLOG_IF(INFO, nfc_debug_enabled)
|
||
|
<< StringPrintf("%s: root=%s", fn, node1->name);
|
||
|
|
||
|
node1 = node1->xmlChildrenNode;
|
||
|
while (node1) // loop through all elements in <Routes ...
|
||
|
{
|
||
|
if (xmlStrcmp(node1->name, (const xmlChar*)"Route") == 0) {
|
||
|
xmlChar* value = xmlGetProp(node1, (const xmlChar*)"Type");
|
||
|
if (value &&
|
||
|
(xmlStrcmp(value, (const xmlChar*)"SecElemSelectedRoutes") == 0)) {
|
||
|
DLOG_IF(INFO, nfc_debug_enabled)
|
||
|
<< StringPrintf("%s: found SecElemSelectedRoutes", fn);
|
||
|
xmlNodePtr node2 = node1->xmlChildrenNode;
|
||
|
while (node2) // loop all elements in <Route
|
||
|
// Type="SecElemSelectedRoutes" ...
|
||
|
{
|
||
|
if (xmlStrcmp(node2->name, (const xmlChar*)"Proto") == 0)
|
||
|
importProtocolRoute(node2, mSecElemRouteDatabase);
|
||
|
else if (xmlStrcmp(node2->name, (const xmlChar*)"Tech") == 0)
|
||
|
importTechnologyRoute(node2, mSecElemRouteDatabase);
|
||
|
node2 = node2->next;
|
||
|
} // loop all elements in <Route Type="SecElemSelectedRoutes" ...
|
||
|
} else if (value &&
|
||
|
(xmlStrcmp(value, (const xmlChar*)"DefaultRoutes") == 0)) {
|
||
|
DLOG_IF(INFO, nfc_debug_enabled)
|
||
|
<< StringPrintf("%s: found DefaultRoutes", fn);
|
||
|
xmlNodePtr node2 = node1->xmlChildrenNode;
|
||
|
while (node2) // loop all elements in <Route Type="DefaultRoutes" ...
|
||
|
{
|
||
|
if (xmlStrcmp(node2->name, (const xmlChar*)"Proto") == 0)
|
||
|
importProtocolRoute(node2, mDefaultRouteDatabase);
|
||
|
else if (xmlStrcmp(node2->name, (const xmlChar*)"Tech") == 0)
|
||
|
importTechnologyRoute(node2, mDefaultRouteDatabase);
|
||
|
node2 = node2->next;
|
||
|
} // loop all elements in <Route Type="DefaultRoutes" ...
|
||
|
}
|
||
|
if (value) xmlFree(value);
|
||
|
} // check <Route ...
|
||
|
node1 = node1->next;
|
||
|
} // loop through all elements in <Routes ...
|
||
|
retval = true;
|
||
|
|
||
|
TheEnd:
|
||
|
xmlFreeDoc(doc);
|
||
|
xmlCleanupParser();
|
||
|
DLOG_IF(INFO, nfc_debug_enabled)
|
||
|
<< StringPrintf("%s: exit; return=%u", fn, retval);
|
||
|
return retval;
|
||
|
}
|
||
|
|
||
|
/*******************************************************************************
|
||
|
**
|
||
|
** Function: saveToFile
|
||
|
**
|
||
|
** Description: Save XML data from a string into a file.
|
||
|
** routesXml: XML that represents routes.
|
||
|
**
|
||
|
** Returns: True if ok.
|
||
|
**
|
||
|
*******************************************************************************/
|
||
|
bool RouteDataSet::saveToFile(const char* routesXml) {
|
||
|
static const char fn[] = "RouteDataSet::saveToFile";
|
||
|
FILE* fh = NULL;
|
||
|
size_t actualWritten = 0;
|
||
|
bool retval = false;
|
||
|
std::string filename(nfc_storage_path);
|
||
|
int stat = 0;
|
||
|
|
||
|
filename.append(sConfigFile);
|
||
|
fh = fopen(filename.c_str(), "w");
|
||
|
if (fh == NULL) {
|
||
|
LOG(ERROR) << StringPrintf("%s: fail to open file", fn);
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
actualWritten = fwrite(routesXml, sizeof(char), strlen(routesXml), fh);
|
||
|
retval = actualWritten == strlen(routesXml);
|
||
|
fclose(fh);
|
||
|
DLOG_IF(INFO, nfc_debug_enabled)
|
||
|
<< StringPrintf("%s: wrote %zu bytes", fn, actualWritten);
|
||
|
if (retval == false) LOG(ERROR) << StringPrintf("%s: error during write", fn);
|
||
|
|
||
|
// set file permission to
|
||
|
// owner read, write; group read; other read
|
||
|
stat = chmod(filename.c_str(), S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
|
||
|
if (stat == -1) LOG(ERROR) << StringPrintf("%s: error during chmod", fn);
|
||
|
return retval;
|
||
|
}
|
||
|
|
||
|
/*******************************************************************************
|
||
|
**
|
||
|
** Function: loadFromFile
|
||
|
**
|
||
|
** Description: Load XML data from file into a string.
|
||
|
** routesXml: string to receive XML data.
|
||
|
**
|
||
|
** Returns: True if ok.
|
||
|
**
|
||
|
*******************************************************************************/
|
||
|
bool RouteDataSet::loadFromFile(std::string& routesXml) {
|
||
|
FILE* fh = NULL;
|
||
|
size_t actual = 0;
|
||
|
char buffer[1024];
|
||
|
std::string filename(nfc_storage_path);
|
||
|
|
||
|
filename.append(sConfigFile);
|
||
|
fh = fopen(filename.c_str(), "r");
|
||
|
if (fh == NULL) {
|
||
|
DLOG_IF(INFO, nfc_debug_enabled)
|
||
|
<< StringPrintf("%s: fail to open file", "RouteDataSet::loadFromFile");
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
while (true) {
|
||
|
actual = fread(buffer, sizeof(char), sizeof(buffer), fh);
|
||
|
if (actual == 0) break;
|
||
|
routesXml.append(buffer, actual);
|
||
|
}
|
||
|
fclose(fh);
|
||
|
DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
|
||
|
"%s: read %zu bytes", "RouteDataSet::loadFromFile", routesXml.length());
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
/*******************************************************************************
|
||
|
**
|
||
|
** Function: importProtocolRoute
|
||
|
**
|
||
|
** Description: Parse data for protocol routes.
|
||
|
** element: XML node for one protocol route.
|
||
|
** database: store data in this database.
|
||
|
**
|
||
|
** Returns: None.
|
||
|
**
|
||
|
*******************************************************************************/
|
||
|
void RouteDataSet::importProtocolRoute(xmlNodePtr& element,
|
||
|
Database& database) {
|
||
|
const xmlChar* id = (const xmlChar*)"Id";
|
||
|
const xmlChar* secElem = (const xmlChar*)"SecElem";
|
||
|
const xmlChar* trueString = (const xmlChar*)"true";
|
||
|
const xmlChar* switchOn = (const xmlChar*)"SwitchOn";
|
||
|
const xmlChar* switchOff = (const xmlChar*)"SwitchOff";
|
||
|
const xmlChar* batteryOff = (const xmlChar*)"BatteryOff";
|
||
|
RouteDataForProtocol* data = new RouteDataForProtocol;
|
||
|
xmlChar* value = NULL;
|
||
|
|
||
|
DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
|
||
|
"%s: element=%s", "RouteDataSet::importProtocolRoute", element->name);
|
||
|
value = xmlGetProp(element, id);
|
||
|
if (value) {
|
||
|
if (xmlStrcmp(value, (const xmlChar*)"T1T") == 0)
|
||
|
data->mProtocol = NFA_PROTOCOL_MASK_T1T;
|
||
|
else if (xmlStrcmp(value, (const xmlChar*)"T2T") == 0)
|
||
|
data->mProtocol = NFA_PROTOCOL_MASK_T2T;
|
||
|
else if (xmlStrcmp(value, (const xmlChar*)"T3T") == 0)
|
||
|
data->mProtocol = NFA_PROTOCOL_MASK_T3T;
|
||
|
else if (xmlStrcmp(value, (const xmlChar*)"IsoDep") == 0)
|
||
|
data->mProtocol = NFA_PROTOCOL_MASK_ISO_DEP;
|
||
|
xmlFree(value);
|
||
|
DLOG_IF(INFO, nfc_debug_enabled)
|
||
|
<< StringPrintf("%s: %s=0x%X", "RouteDataSet::importProtocolRoute", id,
|
||
|
data->mProtocol);
|
||
|
}
|
||
|
|
||
|
value = xmlGetProp(element, secElem);
|
||
|
if (value) {
|
||
|
data->mNfaEeHandle = strtol((char*)value, NULL, 16);
|
||
|
xmlFree(value);
|
||
|
data->mNfaEeHandle = data->mNfaEeHandle | NFA_HANDLE_GROUP_EE;
|
||
|
DLOG_IF(INFO, nfc_debug_enabled)
|
||
|
<< StringPrintf("%s: %s=0x%X", "RouteDataSet::importProtocolRoute",
|
||
|
secElem, data->mNfaEeHandle);
|
||
|
}
|
||
|
|
||
|
value = xmlGetProp(element, switchOn);
|
||
|
if (value) {
|
||
|
data->mSwitchOn = (xmlStrcmp(value, trueString) == 0);
|
||
|
xmlFree(value);
|
||
|
}
|
||
|
|
||
|
value = xmlGetProp(element, switchOff);
|
||
|
if (value) {
|
||
|
data->mSwitchOff = (xmlStrcmp(value, trueString) == 0);
|
||
|
xmlFree(value);
|
||
|
}
|
||
|
|
||
|
value = xmlGetProp(element, batteryOff);
|
||
|
if (value) {
|
||
|
data->mBatteryOff = (xmlStrcmp(value, trueString) == 0);
|
||
|
xmlFree(value);
|
||
|
}
|
||
|
database.push_back(data);
|
||
|
}
|
||
|
|
||
|
/*******************************************************************************
|
||
|
**
|
||
|
** Function: importTechnologyRoute
|
||
|
**
|
||
|
** Description: Parse data for technology routes.
|
||
|
** element: XML node for one technology route.
|
||
|
** database: store data in this database.
|
||
|
**
|
||
|
** Returns: None.
|
||
|
**
|
||
|
*******************************************************************************/
|
||
|
void RouteDataSet::importTechnologyRoute(xmlNodePtr& element,
|
||
|
Database& database) {
|
||
|
const xmlChar* id = (const xmlChar*)"Id";
|
||
|
const xmlChar* secElem = (const xmlChar*)"SecElem";
|
||
|
const xmlChar* trueString = (const xmlChar*)"true";
|
||
|
const xmlChar* switchOn = (const xmlChar*)"SwitchOn";
|
||
|
const xmlChar* switchOff = (const xmlChar*)"SwitchOff";
|
||
|
const xmlChar* batteryOff = (const xmlChar*)"BatteryOff";
|
||
|
RouteDataForTechnology* data = new RouteDataForTechnology;
|
||
|
xmlChar* value = NULL;
|
||
|
|
||
|
DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
|
||
|
"%s: element=%s", "RouteDataSet::importTechnologyRoute", element->name);
|
||
|
value = xmlGetProp(element, id);
|
||
|
if (value) {
|
||
|
if (xmlStrcmp(value, (const xmlChar*)"NfcA") == 0)
|
||
|
data->mTechnology = NFA_TECHNOLOGY_MASK_A;
|
||
|
else if (xmlStrcmp(value, (const xmlChar*)"NfcB") == 0)
|
||
|
data->mTechnology = NFA_TECHNOLOGY_MASK_B;
|
||
|
else if (xmlStrcmp(value, (const xmlChar*)"NfcF") == 0)
|
||
|
data->mTechnology = NFA_TECHNOLOGY_MASK_F;
|
||
|
xmlFree(value);
|
||
|
DLOG_IF(INFO, nfc_debug_enabled)
|
||
|
<< StringPrintf("%s: %s=0x%X", "RouteDataSet::importTechnologyRoute",
|
||
|
id, data->mTechnology);
|
||
|
}
|
||
|
|
||
|
value = xmlGetProp(element, secElem);
|
||
|
if (value) {
|
||
|
data->mNfaEeHandle = strtol((char*)value, NULL, 16);
|
||
|
xmlFree(value);
|
||
|
data->mNfaEeHandle = data->mNfaEeHandle | NFA_HANDLE_GROUP_EE;
|
||
|
DLOG_IF(INFO, nfc_debug_enabled)
|
||
|
<< StringPrintf("%s: %s=0x%X", "RouteDataSet::importTechnologyRoute",
|
||
|
secElem, data->mNfaEeHandle);
|
||
|
}
|
||
|
|
||
|
value = xmlGetProp(element, switchOn);
|
||
|
if (value) {
|
||
|
data->mSwitchOn = (xmlStrcmp(value, trueString) == 0);
|
||
|
xmlFree(value);
|
||
|
}
|
||
|
|
||
|
value = xmlGetProp(element, switchOff);
|
||
|
if (value) {
|
||
|
data->mSwitchOff = (xmlStrcmp(value, trueString) == 0);
|
||
|
xmlFree(value);
|
||
|
}
|
||
|
|
||
|
value = xmlGetProp(element, batteryOff);
|
||
|
if (value) {
|
||
|
data->mBatteryOff = (xmlStrcmp(value, trueString) == 0);
|
||
|
xmlFree(value);
|
||
|
}
|
||
|
database.push_back(data);
|
||
|
}
|
||
|
|
||
|
/*******************************************************************************
|
||
|
**
|
||
|
** Function: deleteFile
|
||
|
**
|
||
|
** Description: Delete route data XML file.
|
||
|
**
|
||
|
** Returns: True if ok.
|
||
|
**
|
||
|
*******************************************************************************/
|
||
|
bool RouteDataSet::deleteFile() {
|
||
|
static const char fn[] = "RouteDataSet::deleteFile";
|
||
|
std::string filename(nfc_storage_path);
|
||
|
filename.append(sConfigFile);
|
||
|
int stat = remove(filename.c_str());
|
||
|
DLOG_IF(INFO, nfc_debug_enabled)
|
||
|
<< StringPrintf("%s: exit %u", fn, stat == 0);
|
||
|
return stat == 0;
|
||
|
}
|
||
|
|
||
|
/*******************************************************************************
|
||
|
**
|
||
|
** Function: getDatabase
|
||
|
**
|
||
|
** Description: Obtain a database of routing data.
|
||
|
** selection: which database.
|
||
|
**
|
||
|
** Returns: Pointer to database.
|
||
|
**
|
||
|
*******************************************************************************/
|
||
|
RouteDataSet::Database* RouteDataSet::getDatabase(DatabaseSelection selection) {
|
||
|
switch (selection) {
|
||
|
case DefaultRouteDatabase:
|
||
|
return &mDefaultRouteDatabase;
|
||
|
case SecElemRouteDatabase:
|
||
|
return &mSecElemRouteDatabase;
|
||
|
}
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
/*******************************************************************************
|
||
|
**
|
||
|
** Function: printDiagnostic
|
||
|
**
|
||
|
** Description: Print some diagnostic output.
|
||
|
**
|
||
|
** Returns: None.
|
||
|
**
|
||
|
*******************************************************************************/
|
||
|
void RouteDataSet::printDiagnostic() {
|
||
|
static const char fn[] = "RouteDataSet::printDiagnostic";
|
||
|
Database* db = getDatabase(DefaultRouteDatabase);
|
||
|
|
||
|
DLOG_IF(INFO, nfc_debug_enabled)
|
||
|
<< StringPrintf("%s: default route database", fn);
|
||
|
for (Database::iterator iter = db->begin(); iter != db->end(); iter++) {
|
||
|
RouteData* routeData = *iter;
|
||
|
switch (routeData->mRouteType) {
|
||
|
case RouteData::ProtocolRoute: {
|
||
|
RouteDataForProtocol* proto = (RouteDataForProtocol*)routeData;
|
||
|
DLOG_IF(INFO, nfc_debug_enabled)
|
||
|
<< StringPrintf("%s: ee h=0x%X; protocol=0x%X", fn,
|
||
|
proto->mNfaEeHandle, proto->mProtocol);
|
||
|
} break;
|
||
|
case RouteData::TechnologyRoute: {
|
||
|
RouteDataForTechnology* tech = (RouteDataForTechnology*)routeData;
|
||
|
DLOG_IF(INFO, nfc_debug_enabled)
|
||
|
<< StringPrintf("%s: ee h=0x%X; technology=0x%X", fn,
|
||
|
tech->mNfaEeHandle, tech->mTechnology);
|
||
|
} break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
DLOG_IF(INFO, nfc_debug_enabled)
|
||
|
<< StringPrintf("%s: sec elem route database", fn);
|
||
|
db = getDatabase(SecElemRouteDatabase);
|
||
|
for (Database::iterator iter2 = db->begin(); iter2 != db->end(); iter2++) {
|
||
|
RouteData* routeData = *iter2;
|
||
|
switch (routeData->mRouteType) {
|
||
|
case RouteData::ProtocolRoute: {
|
||
|
RouteDataForProtocol* proto = (RouteDataForProtocol*)routeData;
|
||
|
DLOG_IF(INFO, nfc_debug_enabled)
|
||
|
<< StringPrintf("%s: ee h=0x%X; protocol=0x%X", fn,
|
||
|
proto->mNfaEeHandle, proto->mProtocol);
|
||
|
} break;
|
||
|
case RouteData::TechnologyRoute: {
|
||
|
RouteDataForTechnology* tech = (RouteDataForTechnology*)routeData;
|
||
|
DLOG_IF(INFO, nfc_debug_enabled)
|
||
|
<< StringPrintf("%s: ee h=0x%X; technology=0x%X", fn,
|
||
|
tech->mNfaEeHandle, tech->mTechnology);
|
||
|
} break;
|
||
|
}
|
||
|
}
|
||
|
}
|