blob: 0b511f83213ebf4219c01dd9ffa4f1b371203513 [file] [log] [blame]
/*
* 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.
*/
/*
* Manage listen-mode AID routing to the host.
*/
#include "OverrideLog.h"
#include "HostAidRouter.h"
#include "config.h"
#include "SecureElement.h"
HostAidRouter HostAidRouter::sHostAidRouter; //singleton HostAidRouter object
/*******************************************************************************
**
** Function: HostAidRouter
**
** Description: Private constructor to prevent public call.
**
** Returns: None.
**
*******************************************************************************/
HostAidRouter::HostAidRouter ()
: mTempHandle (NFA_HANDLE_INVALID),
mIsFeatureEnabled (true)
{
}
/*******************************************************************************
**
** Function: ~HostAidRouter
**
** Description: Private destructor to prevent public call.
**
** Returns: None.
**
*******************************************************************************/
HostAidRouter::~HostAidRouter ()
{
}
/*******************************************************************************
**
** Function: getInstance
**
** Description: Obtain a reference to the singleton object of HostAidRouter
**
** Returns: Reference to HostAidRouter object.
**
*******************************************************************************/
HostAidRouter& HostAidRouter::getInstance ()
{
return sHostAidRouter;
}
/*******************************************************************************
**
** Function: initialize
**
** Description: Initialize all resources.
**
** Returns: True if ok.
**
*******************************************************************************/
bool HostAidRouter::initialize ()
{
unsigned long num = 0;
mTempHandle = NFA_HANDLE_INVALID;
mHandleDatabase.clear ();
if (GetNumValue (NAME_REGISTER_VIRTUAL_SE, &num, sizeof (num)))
mIsFeatureEnabled = num != 0;
return true;
}
/*******************************************************************************
**
** Function: addPpseRoute
**
** Description: Route Proximity Payment System Environment request
** to the host. This function is called when there is no
** route data.
**
** Returns: True if ok.
**
*******************************************************************************/
bool HostAidRouter::addPpseRoute ()
{
static const char fn [] = "HostAidRouter::addPpseRoute";
ALOGD ("%s: enter", fn);
tNFA_STATUS nfaStat = NFA_STATUS_FAILED;
bool retval = false;
if (! mIsFeatureEnabled)
{
ALOGD ("%s: feature disabled", fn);
goto TheEnd;
}
{
ALOGD ("%s: register PPSE AID", fn);
SyncEventGuard guard (mRegisterEvent);
mTempHandle = NFA_HANDLE_INVALID;
nfaStat = NFA_CeRegisterAidOnDH ((UINT8*) "2PAY.SYS.DDF01", 14, stackCallback);
if (nfaStat == NFA_STATUS_OK)
{
mRegisterEvent.wait (); //wait for NFA_CE_REGISTERED_EVT
if (mTempHandle == NFA_HANDLE_INVALID)
{
ALOGE ("%s: received invalid handle", fn);
goto TheEnd;
}
else
mHandleDatabase.push_back (mTempHandle);
}
else
{
ALOGE ("%s: fail register", fn);
goto TheEnd;
}
}
retval = true;
TheEnd:
ALOGD ("%s: exit; ok=%u", fn, retval);
return retval;
}
/*******************************************************************************
**
** Function: deleteAllRoutes
**
** Description: Delete all AID routes to the host.
**
** Returns: True if ok.
**
*******************************************************************************/
bool HostAidRouter::deleteAllRoutes ()
{
static const char fn [] = "HostAidRouter::deleteAllRoutes";
ALOGD ("%s: enter", fn);
tNFA_STATUS nfaStat = NFA_STATUS_FAILED;
bool retval = false;
if (! mIsFeatureEnabled)
{
ALOGD ("%s: feature disabled", fn);
goto TheEnd;
}
//deregister each registered AID from the stack
for (AidHandleDatabase::iterator iter1 = mHandleDatabase.begin(); iter1 != mHandleDatabase.end(); iter1++)
{
tNFA_HANDLE aidHandle = *iter1;
ALOGD ("%s: deregister h=0x%X", fn, aidHandle);
SyncEventGuard guard (mDeregisterEvent);
nfaStat = NFA_CeDeregisterAidOnDH (aidHandle);
if (nfaStat == NFA_STATUS_OK)
mDeregisterEvent.wait (); //wait for NFA_CE_DEREGISTERED_EVT
else
ALOGE ("%s: fail deregister", fn);
}
mHandleDatabase.clear ();
retval = true;
TheEnd:
ALOGD ("%s: exit; ok=%u", fn, retval);
return retval;
}
/*******************************************************************************
**
** Function: startRoute
**
** Description: Begin to route AID request to the host.
** aid: Buffer that contains Application ID
** aidLen: Actual length of the buffer.
**
** Returns: True if ok.
**
*******************************************************************************/
bool HostAidRouter::startRoute (const UINT8* aid, UINT8 aidLen)
{
static const char fn [] = "HostAidRouter::startRoute";
ALOGD ("%s: enter", fn);
tNFA_STATUS nfaStat = NFA_STATUS_FAILED;
bool retval = false;
if (! mIsFeatureEnabled)
{
ALOGD ("%s: feature disabled", fn);
goto TheEnd;
}
{
ALOGD ("%s: register AID; len=%u", fn, aidLen);
SyncEventGuard guard (mRegisterEvent);
mTempHandle = NFA_HANDLE_INVALID;
nfaStat = NFA_CeRegisterAidOnDH ((UINT8*) aid, aidLen, stackCallback);
if (nfaStat == NFA_STATUS_OK)
{
mRegisterEvent.wait (); //wait for NFA_CE_REGISTERED_EVT
if (mTempHandle == NFA_HANDLE_INVALID)
{
ALOGE ("%s: received invalid handle", fn);
goto TheEnd;
}
else
mHandleDatabase.push_back (mTempHandle);
}
else
{
ALOGE ("%s: fail register", fn);
goto TheEnd;
}
}
TheEnd:
ALOGD ("%s: exit; ok=%u", fn, retval);
return retval;
}
/*******************************************************************************
**
** Function: stackCallback
**
** Description: Receive events from the NFC stack.
**
** Returns: None.
**
*******************************************************************************/
void HostAidRouter::stackCallback (UINT8 event, tNFA_CONN_EVT_DATA* eventData)
{
static const char fn [] = "HostAidRouter::stackCallback";
ALOGD("%s: event=0x%X", fn, event);
switch (event)
{
case NFA_CE_REGISTERED_EVT:
{
tNFA_CE_REGISTERED& ce_registered = eventData->ce_registered;
ALOGD("%s: NFA_CE_REGISTERED_EVT; status=0x%X; h=0x%X", fn, ce_registered.status, ce_registered.handle);
SyncEventGuard guard (sHostAidRouter.mRegisterEvent);
if (ce_registered.status == NFA_STATUS_OK)
sHostAidRouter.mTempHandle = ce_registered.handle;
else
sHostAidRouter.mTempHandle = NFA_HANDLE_INVALID;
sHostAidRouter.mRegisterEvent.notifyOne();
}
break;
case NFA_CE_DEREGISTERED_EVT:
{
tNFA_CE_DEREGISTERED& ce_deregistered = eventData->ce_deregistered;
ALOGD("%s: NFA_CE_DEREGISTERED_EVT; h=0x%X", fn, ce_deregistered.handle);
SyncEventGuard guard (sHostAidRouter.mDeregisterEvent);
sHostAidRouter.mDeregisterEvent.notifyOne();
}
break;
case NFA_CE_DATA_EVT:
{
tNFA_CE_DATA& ce_data = eventData->ce_data;
ALOGD("%s: NFA_CE_DATA_EVT; h=0x%X; data len=%u", fn, ce_data.handle, ce_data.len);
SecureElement::getInstance().notifyTransactionListenersOfAid ((UINT8 *)"2PAY.SYS.DDF01", 14);
}
break;
}
}