diff options
Diffstat (limited to 'mobicore/MobiCoreDriverLib/Daemon/Device/MobiCoreDevice.cpp')
-rw-r--r-- | mobicore/MobiCoreDriverLib/Daemon/Device/MobiCoreDevice.cpp | 151 |
1 files changed, 87 insertions, 64 deletions
diff --git a/mobicore/MobiCoreDriverLib/Daemon/Device/MobiCoreDevice.cpp b/mobicore/MobiCoreDriverLib/Daemon/Device/MobiCoreDevice.cpp index 3e86dcb..3ff8ec3 100644 --- a/mobicore/MobiCoreDriverLib/Daemon/Device/MobiCoreDevice.cpp +++ b/mobicore/MobiCoreDriverLib/Daemon/Device/MobiCoreDevice.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2014 TRUSTONIC LIMITED + * Copyright (c) 2013-2015 TRUSTONIC LIMITED * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -57,6 +57,8 @@ MobiCoreDevice::MobiCoreDevice() mcFault = false; mciReused = false; mcpMessage = NULL; + notifySessionRemoved = false; + } //------------------------------------------------------------------------------ @@ -68,6 +70,8 @@ MobiCoreDevice::~MobiCoreDevice() mcVersionInfo = NULL; mcFlags = NULL; nq = NULL; + notifySessionRemoved = false; + } //------------------------------------------------------------------------------ @@ -234,26 +238,31 @@ void MobiCoreDevice::close( // make this a bit easier for everbody. // Cannot lock list as we need to receive notifications, but it may change, so search under lock - trustletSessionList_t sessions_list; - mutex_tslist.lock(); - for (trustletSessionList_t::reverse_iterator revIt = trustletSessions.rbegin(); revIt != trustletSessions.rend(); revIt++) - { - if ((*revIt)->deviceConnection == connection) { - LOG_I("MobiCoreDevice::close found a session %p", *revIt); + for (;;) { + TrustletSession *session = NULL; - sessions_list.push_back(*revIt); + mutex_tslist.lock(); + for (trustletSessionList_t::reverse_iterator revIt = trustletSessions.rbegin(); revIt != trustletSessions.rend(); revIt++) + { + if ((*revIt)->deviceConnection == connection) { + session = *revIt; + break; + } + } + mutex_tslist.unlock(); + if (!session) { break; } - } - mutex_tslist.unlock(); - - for (trustletSessionList_t::iterator it = sessions_list.begin(); it != sessions_list.end(); it++) { - mcResult_t mcRet = closeSession(connection, (*it)->sessionId); + mcResult_t mcRet = closeSession(connection, session->sessionId); if (mcRet != MC_MCP_RET_OK) { - LOG_I("device closeSession failed for %p with %d", *it, mcRet); + LOG_I("device closeSession failed with %d", mcRet); } } + // After the trustlet is done make sure to tell the driver to cleanup + // all the orphaned drivers + cleanupWsmL2(); + connection->connectionData = NULL; // Leave critical section @@ -261,6 +270,7 @@ void MobiCoreDevice::close( } + //------------------------------------------------------------------------------ void MobiCoreDevice::start(void) { @@ -284,6 +294,7 @@ void MobiCoreDevice::start(void) if (mciReused) { + notifySessionRemoved = true; // Remove all pending sessions. In <t-base-301, there is a maximum of 32 sessions. // Few sessions in the start are reserved by the system. #define LOG_SOURCE_TASK_SHIFT 8 @@ -291,6 +302,11 @@ void MobiCoreDevice::start(void) int sessionId = ((sessionNumber<<LOG_SOURCE_TASK_SHIFT)+1); LOG_I("invalidating session %03x", sessionId); mcResult_t mcRet = sendSessionCloseCmd(sessionId); + if (mcRet==MC_DRV_ERR_DAEMON_MCI_ERROR) { + LOG_I("invalid MCP response for CLOSE_SESSION, try again"); + mcRet = sendSessionCloseCmd(sessionId); + } + if (mcRet != MC_MCP_RET_OK) { LOG_I("sendSessionCloseCmd error %d", mcRet); } @@ -340,46 +356,46 @@ bool MobiCoreDevice::waitMcpNotification(void) mcFault = true; return false; } - } // while(1)
-
- // Check healthiness state of the device
- if (DeviceIrqHandler::isExiting() ||
- DeviceScheduler::isExiting() ||
- TAExitHandler::isExiting())
- {
- LOG_I("waitMcpNotification(): Threads state:");
- LOG_I("Irq handler : %s", (DeviceIrqHandler::isExiting()==true)?"running":"exit");
- LOG_I("Scheduler : %s", (DeviceScheduler::isExiting()==true)?"running":"exit");
- LOG_I("Exit handler: %s", (TAExitHandler::isExiting()==true)?"running":"exit");
-
- //There is no CThread::wait() so no need to wake up
- LOG_I("waitMcpNotification(): IrqHandler thread should exit automatically");
-
- DeviceScheduler::terminate();
- //Cancel waiting just in case.
- DeviceScheduler::wakeup();
- LOG_I("waitMcpNotification(): terminate Scheduler thread");
-
- TAExitHandler::terminate();
- //Cancel waiting just in case.
- TAExitHandler::wakeup();
- LOG_I("waitMcpNotification(): terminate Exit handler thread");
-
- DeviceIrqHandler::join();
- LOG_I("waitMcpNotification(): IrqHandler joined");
- LOG_E("IrqHandler thread died!");
-
- DeviceScheduler::join();
- LOG_I("waitMcpNotification(): Scheduler Joined");
- LOG_E("Scheduler thread died!");
-
- TAExitHandler::join();
- LOG_I("waitMcpNotification(): Exit handler Joined");
- LOG_E("TAExitHandler thread died!");
-
- return false;
- }
- return true;
+ } // while(1) + + // Check healthiness state of the device + if (DeviceIrqHandler::isExiting() || + DeviceScheduler::isExiting() || + TAExitHandler::isExiting()) + { + LOG_I("waitMcpNotification(): Threads state:"); + LOG_I("Irq handler : %s", (DeviceIrqHandler::isExiting()==true)?"running":"exit"); + LOG_I("Scheduler : %s", (DeviceScheduler::isExiting()==true)?"running":"exit"); + LOG_I("Exit handler: %s", (TAExitHandler::isExiting()==true)?"running":"exit"); + + //There is no CThread::wait() so no need to wake up + LOG_I("waitMcpNotification(): IrqHandler thread should exit automatically"); + + DeviceScheduler::terminate(); + //Cancel waiting just in case. + DeviceScheduler::wakeup(); + LOG_I("waitMcpNotification(): terminate Scheduler thread"); + + TAExitHandler::terminate(); + //Cancel waiting just in case. + TAExitHandler::wakeup(); + LOG_I("waitMcpNotification(): terminate Exit handler thread"); + + DeviceIrqHandler::join(); + LOG_I("waitMcpNotification(): IrqHandler joined"); + LOG_E("IrqHandler thread died!"); + + DeviceScheduler::join(); + LOG_I("waitMcpNotification(): Scheduler Joined"); + LOG_E("Scheduler thread died!"); + + TAExitHandler::join(); + LOG_I("waitMcpNotification(): Exit handler Joined"); + LOG_E("TAExitHandler thread died!"); + + return false; + } + return true; } @@ -537,6 +553,9 @@ mcResult_t MobiCoreDevice::checkLoad( loadDataOpenSession_ptr pLoadDataOpenSession, mcDrvRspOpenSessionPayload_ptr /*pRspOpenSessionPayload*/) { + mcResult_t mcRet = MC_DRV_OK; + mutex_mcp.lock(); + do { // Write MCP open message to buffer mcpMessage->cmdCheckLoad.cmdHeader.cmdId = MC_MCP_CMD_CHECK_LOAD_TA; @@ -553,33 +572,34 @@ mcResult_t MobiCoreDevice::checkLoad( // seen in openSession never happens elsewhere notifications = std::queue<notification_t>(); - mcResult_t mcRet = mshNotifyAndWait(); + mcRet = mshNotifyAndWait(); if (mcRet != MC_MCP_RET_OK) { LOG_E("mshNotifyAndWait failed for CHECK_LOAD_TA, code %d.", mcRet); // Here Mobicore can be considered dead. - return mcRet; + break; } // Check if the command response ID is correct if ((MC_MCP_CMD_CHECK_LOAD_TA | FLAG_RESPONSE) != mcpMessage->rspHeader.rspId) { - LOG_E("CMD_OPEN_SESSION got invalid MCP command response(0x%X)", mcpMessage->rspHeader.rspId); + LOG_E("CMD_CHECK_LOAD_TA got invalid MCP command response(0x%X)", mcpMessage->rspHeader.rspId); // Something is messing with our MCI memory, we cannot know if the Trustlet was loaded. // Had in been loaded, we are loosing track of it here. - return MC_DRV_ERR_DAEMON_MCI_ERROR; + mcRet = MC_DRV_ERR_DAEMON_MCI_ERROR; + break; } mcRet = mcpMessage->rspCheckLoad.rspHeader.result; - if (mcRet != MC_MCP_RET_OK) { LOG_E("MCP CHECK_LOAD returned code %d.", mcRet); - return MAKE_MC_DRV_MCP_ERROR(mcRet); + mcRet = MAKE_MC_DRV_MCP_ERROR(mcRet); + break; } - return MC_DRV_OK; - } while (0); - return MC_DRV_ERR_UNKNOWN; + + mutex_mcp.unlock(); + return mcRet; } @@ -635,7 +655,7 @@ mcResult_t MobiCoreDevice::closeSession( Connection *deviceConnection, uint32_t sessionId ) { - TrustletSession *session = findSession(deviceConnection,sessionId); + TrustletSession *session = findSession(deviceConnection, sessionId); if (session == NULL) { LOG_E("cannot close session %03x", sessionId); return MC_DRV_ERR_DAEMON_UNKNOWN_SESSION; @@ -875,6 +895,9 @@ mcResult_t MobiCoreDevice::getMobiCoreVersion( } pRspGetMobiCoreVersionPayload->versionInfo = mcpMessage->rspGetMobiCoreVersion.versionInfo; + // The CMP version is meaningless in this case, and is replaced by the NWd version (1.5) + pRspGetMobiCoreVersionPayload->versionInfo.versionCmp = 0x00010005; + // Store MobiCore info for future reference. mcVersionInfo = new mcVersionInfo_t(); |