bool CThread::getStopFlag() const { mStopFlagMutex.lock(); bool stop = mStopFlag; mStopFlagMutex.unlock(); return stop; }
/** * Close device. * * Removes all sessions to a connection. Though, clientLib rejects the closeDevice() * command if still sessions connected to the device, this is needed to clean up all * sessions if client dies. */ void MobiCoreDevice::close(Connection *connection) { trustletSessionList_t::reverse_iterator interator; static CMutex mutex; // 1. Iterate through device session to find connection // 2. Decide what to do with open Trustlet sessions // 3. Remove & delete deviceSession from vector // Enter critical section mutex.lock(); for (interator = trustletSessions.rbegin(); interator != trustletSessions.rend(); interator++) { TrustletSession *ts = *interator; if (ts->deviceConnection == connection) { closeSession(connection, ts->sessionId); } } // Leave critical section mutex.unlock(); // After the trustlet is done make sure to tell the driver to cleanup // all the orphaned drivers cleanupWsmL2(); connection->connectionData = NULL; }
void CAppManConnectController::deleteInstance() { gInstanceMutex.lock(); delete mspInstance; mspInstance = 0; gInstanceMutex.unlock(); }
static void dyn_lock_callback(int mode, CRYPTO_dynlock_value *dlock, const char *file, int line) { CMutex *mtx = (CMutex*)dlock; if(mode & CRYPTO_LOCK) { mtx->lock(); } else { mtx->unlock(); } }
//------------------------------------------------------------------------------ __MC_CLIENT_LIB_API mcResult_t mcCloseDevice( uint32_t deviceId ) { mcResult_t mcResult = MC_DRV_OK; #ifndef WIN32 devMutex.lock(); LOG_I("===%s(%i)===", __FUNCTION__, deviceId); do { Device *device = resolveDeviceId(deviceId); CHECK_DEVICE_CLOSED(device, deviceId); Connection *devCon = device->connection; if (device->openCount != 1) { device->openCount--; break; } // Check if daemon is still alive if (!devCon->isConnectionAlive()) { removeDevice(deviceId); LOG_E("Daemon is dead removing device"); mcResult = MC_DRV_ERR_DAEMON_UNREACHABLE; break; } // Return if not all sessions have been closed // TODO-2012-08-31-haenellu: improve check, if device connection is dead, this makes no more sense. if (device->hasSessions()) { LOG_E("Trying to close device while sessions are still pending."); mcResult = MC_DRV_ERR_SESSION_PENDING; break; } SEND_TO_DAEMON(devCon, MC_DRV_CMD_CLOSE_DEVICE); RECV_FROM_DAEMON(devCon, &mcResult); if (mcResult != MC_DRV_OK) { LOG_W(" %s(): Request at Daemon failed, respId=%d ", __FUNCTION__, mcResult); break; } removeDevice(deviceId); } while (false); devMutex.unlock(); #endif /* WIN32 */ return mcResult; }
void CTimeoutManager::deleteInstance() { gsInstanceMutex.lock(); if (msInstance) { msInstance->finish(); delete msInstance; msInstance = 0; } gsInstanceMutex.unlock(); }
iviLink::BaseUid iviLink::generateUid() { std::stringstream ss; gMutex.lock(); { ss << gCounter; ++gCounter; } gMutex.unlock(); return BaseUid(ss.str()); }
//------------------------------------------------------------------------------ __MC_CLIENT_LIB_API mcResult_t mcCloseSession(mcSessionHandle_t *session) { mcResult_t mcResult = MC_DRV_OK; #ifndef WIN32 LOG_I("===%s()===", __FUNCTION__); devMutex.lock(); do { CHECK_NOT_NULL(session); LOG_I(" Closing session %03x.", session->sessionId); Device *device = resolveDeviceId(session->deviceId); CHECK_DEVICE(device); Connection *devCon = device->connection; Session *nqSession = device->resolveSessionId(session->sessionId); CHECK_SESSION(nqSession, session->sessionId); SEND_TO_DAEMON(devCon, MC_DRV_CMD_CLOSE_SESSION, session->sessionId); RECV_FROM_DAEMON(devCon, &mcResult); if (mcResult != MC_DRV_OK) { LOG_E("CMD_CLOSE_SESSION failed, respId=%d", mcResult); // TODO-2012-08-03-haenellu: Remove once tests can handle it. mcResult = MC_DRV_ERR_UNKNOWN_DEVICE; break; } bool r = device->removeSession(session->sessionId); if (!r) { LOG_E("removeSession failed"); assert(0); } } while (false); if (mcResult == MC_DRV_ERR_SOCKET_WRITE || mcResult == MC_DRV_ERR_SOCKET_READ) { LOG_E("Connection is dead, removing device."); removeDevice(session->deviceId); } devMutex.unlock(); #endif /* WIN32 */ return mcResult; }
CTimeoutManager * CTimeoutManager::getInstance() { if (0 == CTimeoutManager::msInstance) { gsInstanceMutex.lock(); if (0 == CTimeoutManager::msInstance) { CTimeoutManager::msInstance = new CTimeoutManager(); } gsInstanceMutex.unlock(); } return CTimeoutManager::msInstance; }
CAppManConnectController * CAppManConnectController::instance() { LOG4CPLUS_TRACE(msLogger,"instance()"); if (!mspInstance) { gInstanceMutex.lock(); if (!mspInstance) { mspInstance = new CAppManConnectController(); } gInstanceMutex.unlock(); } return mspInstance; }
//------------------------------------------------------------------------------ __MC_CLIENT_LIB_API mcResult_t mcGetMobiCoreVersion( uint32_t deviceId, mcVersionInfo_t *versionInfo ) { mcResult_t mcResult = MC_DRV_OK; #ifndef WIN32 devMutex.lock(); LOG_I("===%s()===", __FUNCTION__); do { Device *device = resolveDeviceId(deviceId); // Is the device known CHECK_DEVICE(device); // Is the device opened. CHECK_DEVICE_CLOSED(device, deviceId) CHECK_NOT_NULL(versionInfo); Connection *devCon = device->connection; SEND_TO_DAEMON(devCon, MC_DRV_CMD_GET_MOBICORE_VERSION); // Read GET MOBICORE VERSION response. RECV_FROM_DAEMON(devCon, &mcResult); if (mcResult != MC_DRV_OK) { LOG_E("MC_DRV_CMD_GET_MOBICORE_VERSION bad response, respId=%d", mcResult); // TODO-2012-09-06-haenellu: Remove once tests can handle it. mcResult = MC_DRV_ERR_DAEMON_UNREACHABLE; break; } // Read payload. mcVersionInfo_t versionInfo_socket; RECV_FROM_DAEMON(devCon, &versionInfo_socket); *versionInfo = versionInfo_socket; } while (0); devMutex.unlock(); #endif /* WIN32 */ return mcResult; }
CAppManConnectController * CAppManConnectController::instance(Android::AppInfo appInfo) { LOG4CPLUS_TRACE_METHOD(msLogger, __PRETTY_FUNCTION__); if (!mspInstance) { gInstanceMutex.lock(); if (!mspInstance) { mspInstance = new CAppManConnectController(appInfo); } gInstanceMutex.unlock(); } return mspInstance; }
//------------------------------------------------------------------------------ __MC_CLIENT_LIB_API mcResult_t mcFreeWsm( uint32_t deviceId, uint8_t *wsm ) { mcResult_t mcResult = MC_DRV_ERR_UNKNOWN; #ifndef WIN32 Device *device; devMutex.lock(); LOG_I("===%s(%p)===", __FUNCTION__, wsm); do { // Get the device associated wit the given session device = resolveDeviceId(deviceId); // Is the device known CHECK_DEVICE(device); // Is the device opened. CHECK_DEVICE_CLOSED(device, deviceId) // find WSM object CWsm_ptr pWsm = device->findContiguousWsm(wsm); if (pWsm == NULL) { LOG_E("address is unknown to mcFreeWsm"); mcResult = MC_DRV_ERR_WSM_NOT_FOUND; break; } // Free the given virtual address mcResult = device->freeContiguousWsm(pWsm); if (mcResult != MC_DRV_OK) { LOG_E("Free of virtual address failed"); break; } mcResult = MC_DRV_OK; } while (false); devMutex.unlock(); #endif /* WIN32 */ return mcResult; }
//------------------------------------------------------------------------------ __MC_CLIENT_LIB_API mcResult_t mcFreeWsm( uint32_t deviceId, uint8_t *wsm ) { mcResult_t mcResult = MC_DRV_ERR_UNKNOWN; Device *device; static CMutex mutex; LOG_I("===%s()===", __func__); mutex.lock(); // Enter critical section do { // Get the device associated wit the given session device = resolveDeviceId(deviceId); if (NULL == device) { LOG_E("mcFreeWsm(): Device not found"); mcResult = MC_DRV_ERR_UNKNOWN_DEVICE; break; } // find WSM object CWsm_ptr pWsm = device->findContiguousWsm(wsm); if (NULL == pWsm) { LOG_E("mcFreeWsm(): unknown address"); mcResult = MC_DRV_ERR_INVALID_PARAMETER; break; } // Free the given virtual address if (!device->freeContiguousWsm(pWsm)) { LOG_E("mcFreeWsm(): Free of virtual address failed"); mcResult = MC_DRV_ERR_FREE_MEMORY_FAILED; break; } mcResult = MC_DRV_OK; } while (false); mutex.unlock(); // Exit critical section return mcResult; }
//------------------------------------------------------------------------------ __MC_CLIENT_LIB_API mcResult_t mcMallocWsm( uint32_t deviceId, uint32_t align, uint32_t len, uint8_t **wsm, uint32_t wsmFlags ) { mcResult_t mcResult = MC_DRV_ERR_UNKNOWN; static CMutex mutex; LOG_I("===%s()===", __func__); mutex.lock(); // Enter critical section do { Device *device = resolveDeviceId(deviceId); if (NULL == device) { LOG_E("mcMallocWsm(): Device not found"); mcResult = MC_DRV_ERR_UNKNOWN_DEVICE; break; } if(NULL == wsm) { mcResult = MC_DRV_ERR_INVALID_PARAMETER; break; } CWsm_ptr pWsm = device->allocateContiguousWsm(len); if (NULL == pWsm) { LOG_E("mcMallocWsm(): Allocation of WSM failed"); mcResult = MC_DRV_ERR_NO_FREE_MEMORY; break; } *wsm = (uint8_t*)pWsm->virtAddr; mcResult = MC_DRV_OK; } while (false); mutex.unlock(); // Exit critical section return mcResult; }
//------------------------------------------------------------------------------ __MC_CLIENT_LIB_API mcResult_t mcMallocWsm( uint32_t deviceId, uint32_t align, uint32_t len, uint8_t **wsm, uint32_t wsmFlags) { mcResult_t mcResult = MC_DRV_ERR_UNKNOWN; #ifndef WIN32 LOG_I("===%s(len=%i)===", __FUNCTION__, len); devMutex.lock(); do { Device *device = resolveDeviceId(deviceId); // Is the device known // CHECK_DEVICE(device); // Is the device opened. CHECK_DEVICE_CLOSED(device, deviceId) CHECK_NOT_NULL(wsm); CWsm_ptr pWsm; mcResult = device->allocateContiguousWsm(len, &pWsm); if (mcResult != MC_DRV_OK) { LOG_W(" Allocation of WSM failed"); break; } *wsm = (uint8_t *)pWsm->virtAddr; mcResult = MC_DRV_OK; } while (false); devMutex.unlock(); #endif /* WIN32 */ return mcResult; }
//------------------------------------------------------------------------------ __MC_CLIENT_LIB_API mcResult_t mcGetSessionErrorCode( mcSessionHandle_t *session, int32_t *lastErr ) { mcResult_t mcResult = MC_DRV_OK; #ifndef WIN32 devMutex.lock(); LOG_I("===%s()===", __FUNCTION__); do { CHECK_NOT_NULL(session); CHECK_NOT_NULL(lastErr); // Get device Device *device = resolveDeviceId(session->deviceId); // Is the device known CHECK_DEVICE(device); // Is the device opened. CHECK_DEVICE_CLOSED(device, session->deviceId) // Get session Session *nqsession = device->resolveSessionId(session->sessionId); CHECK_SESSION(nqsession, session->sessionId); // get session error code from session *lastErr = nqsession->getLastErr(); } while (false); devMutex.unlock(); #endif /* WIN32 */ return mcResult; }
//------------------------------------------------------------------------------ __MC_CLIENT_LIB_API mcResult_t mcNotify( mcSessionHandle_t *session ) { mcResult_t mcResult = MC_DRV_OK; #ifndef WIN32 devMutex.lock(); LOG_I("===%s()===", __FUNCTION__); do { CHECK_NOT_NULL(session); LOG_I(" Notifying session %03x.", session->sessionId); Device *device = resolveDeviceId(session->deviceId); CHECK_DEVICE(device); Connection *devCon = device->connection; Session *nqsession = device->resolveSessionId(session->sessionId); CHECK_SESSION(nqsession, session->sessionId); SEND_TO_DAEMON(devCon, MC_DRV_CMD_NOTIFY, session->sessionId); // Daemon will not return a response } while (false); if (mcResult == MC_DRV_ERR_SOCKET_WRITE) { LOG_E("Connection is dead, removing device."); removeDevice(session->deviceId); } devMutex.unlock(); #endif /* WIN32 */ return mcResult; }
//------------------------------------------------------------------------------ __MC_CLIENT_LIB_API mcResult_t mcOpenDevice( uint32_t deviceId ) { mcResult_t mcResult = MC_DRV_OK; static CMutex mutex; Connection *devCon = NULL; mutex.lock(); // Enter critical section do { Device *device = resolveDeviceId(deviceId); if (NULL != device) { LOG_E("mcOpenDevice(): Device %d already opened", deviceId); mcResult = MC_DRV_ERR_INVALID_OPERATION; break; } // Open new connection to device devCon = new Connection(); if (!devCon->connect(SOCK_PATH)) { LOG_E("mcOpenDevice(): Could not connect to %s", SOCK_PATH); mcResult = MC_DRV_ERR_DAEMON_UNREACHABLE; break; } // Runtime check of Daemon version. char* errmsg; if (!checkVersionOkDAEMON(getDaemonVersion(devCon), &errmsg)) { LOG_E("%s", errmsg); mcResult = MC_DRV_ERR_DAEMON_VERSION; break; } LOG_I("%s", errmsg); // Forward device open to the daemon and read result mcDrvCmdOpenDevice_t mcDrvCmdOpenDevice = { // C++ does not support C99 designated initializers /* .header = */ { /* .commandId = */ MC_DRV_CMD_OPEN_DEVICE }, /* .payload = */ { /* .deviceId = */ deviceId } }; int len = devCon->writeData( &mcDrvCmdOpenDevice, sizeof(mcDrvCmdOpenDevice)); if (len < 0) { LOG_E("mcOpenDevice(): CMD_OPEN_DEVICE writeCmd failed, ret=%d", len); mcResult = MC_DRV_ERR_DAEMON_UNREACHABLE; break; } mcDrvResponseHeader_t rspHeader; len = devCon->readData( &rspHeader, sizeof(rspHeader)); if (len != sizeof(rspHeader)) { LOG_E("mcOpenDevice(): CMD_OPEN_DEVICE readRsp failed, ret=%d", len); mcResult = MC_DRV_ERR_DAEMON_UNREACHABLE; break; } if (MC_DRV_RSP_OK != rspHeader.responseId) { LOG_E("mcOpenDevice(): CMD_OPEN_DEVICE failed, respId=%d", rspHeader.responseId); switch(rspHeader.responseId) { case MC_DRV_RSP_PAYLOAD_LENGTH_ERROR: mcResult = MC_DRV_ERR_DAEMON_UNREACHABLE; break; case MC_DRV_INVALID_DEVICE_NAME: mcResult = MC_DRV_ERR_UNKNOWN_DEVICE; break; case MC_DRV_RSP_DEVICE_ALREADY_OPENED: default: mcResult = MC_DRV_ERR_INVALID_OPERATION; break; } break; } // there is no payload to read device = new Device(deviceId, devCon); if (!device->open(MC_DRV_MOD_DEVNODE_FULLPATH)) { delete device; // devCon is freed in the Device destructor devCon = NULL; LOG_E("mcOpenDevice(): could not open device file: %s", MC_DRV_MOD_DEVNODE_FULLPATH); mcResult = MC_DRV_ERR_INVALID_DEVICE_FILE; break; } addDevice(device); } while (false); if (mcResult != MC_DRV_OK && devCon != NULL) { delete devCon; } mutex.unlock(); // Exit critical section return mcResult; }
//------------------------------------------------------------------------------ __MC_CLIENT_LIB_API mcResult_t mcOpenDevice(uint32_t deviceId) { mcResult_t mcResult = MC_DRV_OK; #ifndef WIN32 Connection *devCon = NULL; devMutex.lock(); LOG_I("===%s(%i)===", __FUNCTION__, deviceId); do { Device *device = resolveDeviceId(deviceId); if (device != NULL) { LOG_E("Device %d already opened", deviceId); mcResult = MC_DRV_OK; device->openCount++; break; } // Handle SIGPIPE inside write() // If Daemon crashes and ClientLib writes to named socket, // a sigpipe is send to ClientLib/TLC and kills it. signal(SIGPIPE, SIG_IGN); // Open new connection to device devCon = new Connection(); if (!devCon->connect(SOCK_PATH)) { LOG_W(" Could not connect to %s socket", SOCK_PATH); mcResult = MC_DRV_ERR_SOCKET_CONNECT; break; } // Runtime check of Daemon version. char *errmsg; uint32_t version = 0; mcResult = getDaemonVersion(devCon, &version); if (mcResult != MC_DRV_OK) { break; } if (!checkVersionOkDAEMON(version, &errmsg)) { LOG_E("%s", errmsg); mcResult = MC_DRV_ERR_DAEMON_VERSION; break; } LOG_I(" %s", errmsg); // Forward device open to the daemon and read result SEND_TO_DAEMON(devCon, MC_DRV_CMD_OPEN_DEVICE, deviceId); RECV_FROM_DAEMON(devCon, &mcResult); if (mcResult != MC_DRV_OK) { LOG_W(" %s(): Request at Daemon failed, respId=%x ", __FUNCTION__, mcResult); break; } // there is no payload to read device = new Device(deviceId, devCon); mcResult = device->open("/dev/" MC_USER_DEVNODE); if (mcResult != MC_DRV_OK) { delete device; // devCon is freed in the Device destructor devCon = NULL; LOG_E("Could not open device file: /dev/%s", MC_USER_DEVNODE); break; } addDevice(device); device->openCount++; } while (false); devMutex.unlock(); if (mcResult != MC_DRV_OK) { if (devCon != NULL) delete devCon; LOG_I(" Device not opened."); } else { LOG_I(" Successfully opened the device."); } #endif /* WIN32 */ return mcResult; }
//------------------------------------------------------------------------------ __MC_CLIENT_LIB_API mcResult_t mcOpenGPTA( mcSessionHandle_t *session, const mcUuid_t *uuid, uint8_t *tci, uint32_t len ) { mcResult_t mcResult = MC_DRV_OK; #ifndef WIN32 devMutex.lock(); LOG_I("===%s()===", __FUNCTION__); BulkBufferDescriptor *bulkBuf = NULL; do { uint32_t handle = 0; CHECK_NOT_NULL(session); CHECK_NOT_NULL(uuid); if (len > MC_MAX_TCI_LEN) { LOG_E("TCI length is longer than %d", MC_MAX_TCI_LEN); mcResult = MC_DRV_ERR_TCI_TOO_BIG; break; } // Get the device associated with the given session Device *device = resolveDeviceId(session->deviceId); CHECK_DEVICE(device); Connection *devCon = device->connection; // First assume the TCI is a contiguous buffer // Get the physical address of the given TCI CWsm_ptr pWsm = device->findContiguousWsm(tci); if (pWsm == NULL) { if (tci != NULL && len != 0) { // Then assume it's a normal buffer that needs to be mapped mcResult = device->mapBulkBuf(tci, len, &bulkBuf); if (mcResult != MC_DRV_OK) { LOG_E("Registering buffer failed. ret=%x", mcResult); mcResult = MC_DRV_ERR_WSM_NOT_FOUND; break; } handle = bulkBuf->handle; } else if ( len != 0 ) { LOG_E("mcOpenSession(): length is more than allocated TCI"); mcResult = MC_DRV_ERR_TCI_GREATER_THAN_WSM; break; } } else { if (pWsm->len < len) { LOG_E("mcOpenSession(): length is more than allocated TCI"); mcResult = MC_DRV_ERR_TCI_GREATER_THAN_WSM; break; } handle = pWsm->handle; } SEND_TO_DAEMON(devCon, MC_DRV_CMD_OPEN_TRUSTED_APP, session->deviceId, *uuid, (uint32_t)((uintptr_t)tci & 0xFFF), handle, len); // Read command response RECV_FROM_DAEMON(devCon, &mcResult); if (mcResult != MC_DRV_OK) { // TODO-2012-09-06-haenellu: Remove this code once tests can handle it if (MC_DRV_ERROR_MAJOR(mcResult) != MC_DRV_ERR_MCP_ERROR) { LOG_E("Daemon could not open session, responseId %d.", mcResult); } else { uint32_t mcpResult = MC_DRV_ERROR_MCP(mcResult); LOG_E("<t-base reported failing of MC_MCP_CMD_OPEN_SESSION command, mcpResult %d.", mcpResult); // IMPROVEMENT-2012-09-03-haenellu: Remove this switch case and use MCP code in tests. switch (mcpResult) { case MC_MCP_RET_ERR_WRONG_PUBLIC_KEY: mcResult = MC_DRV_ERR_WRONG_PUBLIC_KEY; break; case MC_MCP_RET_ERR_CONTAINER_TYPE_MISMATCH: mcResult = MC_DRV_ERR_CONTAINER_TYPE_MISMATCH; break; case MC_MCP_RET_ERR_CONTAINER_LOCKED: mcResult = MC_DRV_ERR_CONTAINER_LOCKED; break; case MC_MCP_RET_ERR_SP_NO_CHILD: mcResult = MC_DRV_ERR_SP_NO_CHILD; break; case MC_MCP_RET_ERR_TL_NO_CHILD: mcResult = MC_DRV_ERR_TL_NO_CHILD; break; case MC_MCP_RET_ERR_UNWRAP_ROOT_FAILED: mcResult = MC_DRV_ERR_UNWRAP_ROOT_FAILED; break; case MC_MCP_RET_ERR_UNWRAP_SP_FAILED: mcResult = MC_DRV_ERR_UNWRAP_SP_FAILED; break; case MC_MCP_RET_ERR_UNWRAP_TRUSTLET_FAILED: mcResult = MC_DRV_ERR_UNWRAP_TRUSTLET_FAILED; break; case MC_MCP_RET_ERR_UNKNOWN_UUID: mcResult = MC_DRV_ERR_TRUSTED_APPLICATION_NOT_FOUND; break; case MC_MCP_RET_ERR_SERVICE_BLOCKED: mcResult = MC_DRV_ERR_SERVICE_BLOCKED; break; case MC_MCP_RET_ERR_SERVICE_LOCKED: mcResult = MC_DRV_ERR_SERVICE_LOCKED; break; case MC_MCP_RET_ERR_SERVICE_KILLED: /* because a session can execute as part of the Open Session * command, it can also be killed during that phase. * or can it? */ mcResult = MC_DRV_ERR_SERVICE_KILLED; break; case MC_MCP_RET_ERR_NO_MORE_SESSIONS: mcResult = MC_DRV_ERR_NO_FREE_INSTANCES; break; default: // TODO-2012-09-06-haenellu: Remove line and adapt codes in tests. mcResult = MC_DRV_ERR_MCP_ERROR; break; } } break; // loading of Trustlet failed, unlock mutex and return } // read payload mcDrvRspOpenSessionPayload_t rspOpenSessionPayload; RECV_FROM_DAEMON(devCon, &rspOpenSessionPayload); // Register session with handle session->sessionId = rspOpenSessionPayload.sessionId; LOG_I(" Service is started. Setting up channel for notifications."); // Set up second channel for notifications Connection *sessionConnection = new Connection(); if (!sessionConnection->connect(SOCK_PATH)) { LOG_E("Could not connect to %s", SOCK_PATH); delete sessionConnection; // Here we know we couldn't connect to the Daemon. // Maybe we should use existing connection to close Trustlet. mcResult = MC_DRV_ERR_SOCKET_CONNECT; break; } do { SEND_TO_DAEMON(sessionConnection, MC_DRV_CMD_NQ_CONNECT, session->deviceId, session->sessionId, rspOpenSessionPayload.deviceSessionId, rspOpenSessionPayload.sessionMagic); RECV_FROM_DAEMON(sessionConnection, &mcResult); if (mcResult != MC_DRV_OK) { LOG_E("CMD_NQ_CONNECT failed, respId=%d", mcResult); break; } } while (0); if (mcResult != MC_DRV_OK) { delete sessionConnection; // Here we know we couldn't communicate well with the Daemon. // Maybe we should use existing connection to close Trustlet. break; // unlock mutex and return } // there is no payload. // Session has been established, new session object must be created Session *sessionObj = device->createNewSession(session->sessionId, sessionConnection); // If the session tci was a mapped buffer then register it if (bulkBuf) sessionObj->addBulkBuf(bulkBuf); LOG_I(" Successfully opened session %03x.", session->sessionId); } while (false); if (mcResult != MC_DRV_OK && bulkBuf) { delete bulkBuf; } // TODO: enable as soon as there are more error codes // if (mcResult == MC_DRV_ERR_SOCKET_WRITE || mcResult == MC_DRV_ERR_SOCKET_READ) { // LOG_E("Connection is dead, removing device."); // removeDevice(session->deviceId); // } devMutex.unlock(); #endif /* WIN32 */ return mcResult; }
//------------------------------------------------------------------------------ __MC_CLIENT_LIB_API mcResult_t mcMap( mcSessionHandle_t *sessionHandle, void *buf, uint32_t bufLen, mcBulkMap_t *mapInfo ) { mcResult_t mcResult = MC_DRV_ERR_UNKNOWN; static CMutex mutex; mutex.lock(); // Enter critical section do { if (NULL == sessionHandle) { LOG_E("mcMap(): sessionHandle is null"); mcResult = MC_DRV_ERR_INVALID_PARAMETER; break; } if (NULL == mapInfo) { LOG_E("mcMap(): mapInfo is null"); mcResult = MC_DRV_ERR_INVALID_PARAMETER; break; } if (NULL == buf) { LOG_E("mcMap(): buf is null"); mcResult = MC_DRV_ERR_INVALID_PARAMETER; break; } // Determine device the session belongs to Device *device = resolveDeviceId(sessionHandle->deviceId); if (NULL == device) { LOG_E("mcMap(): Device not found"); mcResult = MC_DRV_ERR_UNKNOWN_DEVICE; break; } Connection *devCon = device->connection; // Get session Session *session = device->resolveSessionId(sessionHandle->sessionId); if (NULL == session) { LOG_E("mcMap(): Session not found"); mcResult = MC_DRV_ERR_UNKNOWN_SESSION; break; } // Workaround Linux memory handling if (NULL != buf) { for (uint32_t i = 0; i < bufLen; i += 4096) { volatile uint8_t x = ((uint8_t *) buf)[i]; x = x; } } // Register mapped bulk buffer to Kernel Module and keep mapped bulk buffer in mind BulkBufferDescriptor *bulkBuf = session->addBulkBuf(buf, bufLen); if (NULL == bulkBuf) { LOG_E("mcMap(): Error mapping bulk buffer"); mcResult = MC_DRV_ERR_BULK_MAPPING; break; } // Prepare map command mcDrvCmdMapBulkMem_t mcDrvCmdMapBulkMem = { // C++ does not support C99 designated initializers /* .header = */ { /* .commandId = */ MC_DRV_CMD_MAP_BULK_BUF }, /* .payload = */ { /* .sessionId = */ session->sessionId, /* .pAddrL2 = */ (uint32_t)bulkBuf->physAddrWsmL2, /* .offsetPayload = */ (uint32_t)(bulkBuf->virtAddr) & 0xFFF, /* .lenBulkMem = */ bulkBuf->len } }; // Transmit map command to MobiCore device devCon->writeData( &mcDrvCmdMapBulkMem, sizeof(mcDrvCmdMapBulkMem)); // Read command response mcDrvResponseHeader_t rspHeader; int len = devCon->readData( &rspHeader, sizeof(rspHeader)); if (sizeof(rspHeader) != len) { LOG_E("mcMap(): CMD_MAP_BULK_BUF readRsp failed, ret=%d", len); mcResult = MC_DRV_ERR_DAEMON_UNREACHABLE; break; } if (MC_DRV_RSP_OK != rspHeader.responseId) { LOG_E("mcMap(): CMD_MAP_BULK_BUF failed, respId=%d", rspHeader.responseId); // REV We ignore Daemon Error code because client cannot handle it anyhow. mcResult = MC_DRV_ERR_DAEMON_UNREACHABLE; // Unregister mapped bulk buffer from Kernel Module and remove mapped // bulk buffer from session maintenance if (!session->removeBulkBuf(buf)) { // Removing of bulk buffer not possible LOG_E("mcMap(): Unregistering of bulk memory from Kernel Module failed"); } break; } mcDrvRspMapBulkMemPayload_t rspMapBulkMemPayload; devCon->readData( &rspMapBulkMemPayload, sizeof(rspMapBulkMemPayload)); // Set mapping info for Trustlet mapInfo->sVirtualAddr = (void *) (rspMapBulkMemPayload.secureVirtualAdr); mapInfo->sVirtualLen = bufLen; mcResult = MC_DRV_OK; } while (false); mutex.unlock(); // Exit critical section return mcResult; }
//------------------------------------------------------------------------------ __MC_CLIENT_LIB_API mcResult_t mcCloseSession( mcSessionHandle_t *session ) { mcResult_t mcResult = MC_DRV_OK; static CMutex mutex; mutex.lock(); // Enter critical section do { if (NULL == session) { LOG_E("mcCloseSession(): Session is null"); mcResult = MC_DRV_ERR_INVALID_PARAMETER; break; } Device *device = resolveDeviceId(session->deviceId); if (NULL == device) { LOG_E("mcCloseSession(): Device not found"); mcResult = MC_DRV_ERR_UNKNOWN_DEVICE; break; } Connection *devCon = device->connection; Session *nqSession = device->resolveSessionId(session->sessionId); if (NULL == nqSession) { LOG_E("mcCloseSession(): Session not found"); mcResult = MC_DRV_ERR_UNKNOWN_SESSION; break; } // Write close session command mcDrvCmdCloseSession_t cmdCloseSession = { // C++ does not support C99 designated initializers /* .header = */ { /* .commandId = */ MC_DRV_CMD_CLOSE_SESSION }, /* .payload = */ { /* .sessionId = */ session->sessionId, } }; devCon->writeData( &cmdCloseSession, sizeof(cmdCloseSession)); // Read command response mcDrvResponseHeader_t rspHeader; int len = devCon->readData( &rspHeader, sizeof(rspHeader)); if (sizeof(rspHeader) != len) { LOG_E("mcCloseSession(): CMD_CLOSE_SESSION readRsp failed, ret=%d", len); mcResult = MC_DRV_ERR_DAEMON_UNREACHABLE; break; } if (MC_DRV_RSP_OK != rspHeader.responseId) { LOG_E("mcCloseSession(): CMD_CLOSE_SESSION failed, respId=%d", rspHeader.responseId); mcResult = MC_DRV_ERR_UNKNOWN_DEVICE; break; } bool r = device->removeSession(session->sessionId); assert(r == true); mcResult = MC_DRV_OK; } while (false); mutex.unlock(); // Exit critical section return mcResult; }
//------------------------------------------------------------------------------ __MC_CLIENT_LIB_API mcResult_t mcOpenSession( mcSessionHandle_t *session, const mcUuid_t *uuid, uint8_t *tci, uint32_t len ) { mcResult_t mcResult = MC_DRV_OK; static CMutex mutex; mutex.lock(); // Enter critical section do { if (NULL == session) { LOG_E("mcOpenSession(): Session is null"); mcResult = MC_DRV_ERR_INVALID_PARAMETER; break; } if (NULL == uuid) { LOG_E("mcOpenSession(): UUID is null"); mcResult = MC_DRV_ERR_INVALID_PARAMETER; break; } if (NULL == tci) { LOG_E("mcOpenSession(): TCI is null"); mcResult = MC_DRV_ERR_INVALID_PARAMETER; break; } if (len > MC_MAX_TCI_LEN) { LOG_E("mcOpenSession(): TCI length is longer than %d", MC_MAX_TCI_LEN); mcResult = MC_DRV_ERR_INVALID_PARAMETER; break; } // Get the device associated with the given session Device *device = resolveDeviceId(session->deviceId); if (NULL == device) { LOG_E("mcOpenSession(): Device not found"); mcResult = MC_DRV_ERR_UNKNOWN_DEVICE; break; } Connection *devCon = device->connection; // Get the physical address of the given TCI CWsm_ptr pWsm = device->findContiguousWsm(tci); if (NULL == pWsm) { LOG_E("mcOpenSession(): Could not resolve physical address of TCI"); mcResult = MC_DRV_ERR_INVALID_PARAMETER; break; } if (pWsm->len < len) { LOG_E("mcOpenSession(): length is more than allocated TCI"); mcResult = MC_DRV_ERR_INVALID_PARAMETER; break; } // Prepare open session command mcDrvCmdOpenSession_t cmdOpenSession = { // C++ does not support C99 designated initializers /* .header = */ { /* .commandId = */ MC_DRV_CMD_OPEN_SESSION }, /* .payload = */ { /* .deviceId = */ session->deviceId, /* .uuid = */ *uuid, /* .tci = */ (uint32_t)pWsm->physAddr, /* .len = */ len } }; // Transmit command data int len = devCon->writeData( &cmdOpenSession, sizeof(cmdOpenSession)); if (sizeof(cmdOpenSession) != len) { LOG_E("mcOpenSession(): CMD_OPEN_SESSION writeData failed, ret=%d", len); mcResult = MC_DRV_ERR_DAEMON_UNREACHABLE; break; } // Read command response // read header first mcDrvResponseHeader_t rspHeader; len = devCon->readData( &rspHeader, sizeof(rspHeader)); if (sizeof(rspHeader) != len) { LOG_E("mcOpenSession(): CMD_OPEN_SESSION readResp failed, ret=%d", len); mcResult = MC_DRV_ERR_DAEMON_UNREACHABLE; break; } if (MC_DRV_RSP_OK != rspHeader.responseId) { LOG_E("mcOpenSession(): CMD_OPEN_SESSION failed, respId=%d", rspHeader.responseId); switch(rspHeader.responseId) { case MC_DRV_RSP_WRONG_PUBLIC_KEY: mcResult = MC_DRV_ERR_WRONG_PUBLIC_KEY; break; case MC_DRV_RSP_CONTAINER_TYPE_MISMATCH: mcResult = MC_DRV_ERR_CONTAINER_TYPE_MISMATCH; break; case MC_DRV_RSP_CONTAINER_LOCKED: mcResult = MC_DRV_ERR_CONTAINER_LOCKED; break; case MC_DRV_RSP_SP_NO_CHILD: mcResult = MC_DRV_ERR_SP_NO_CHILD; break; case MC_DRV_RSP_TL_NO_CHILD: mcResult = MC_DRV_ERR_TL_NO_CHILD; break; case MC_DRV_RSP_UNWRAP_ROOT_FAILED: mcResult = MC_DRV_ERR_UNWRAP_ROOT_FAILED; break; case MC_DRV_RSP_UNWRAP_SP_FAILED: mcResult = MC_DRV_ERR_UNWRAP_SP_FAILED; break; case MC_DRV_RSP_UNWRAP_TRUSTLET_FAILED: mcResult = MC_DRV_ERR_UNWRAP_TRUSTLET_FAILED; break; case MC_DRV_RSP_TRUSTLET_NOT_FOUND: mcResult = MC_DRV_ERR_INVALID_DEVICE_FILE; break; case MC_DRV_RSP_PAYLOAD_LENGTH_ERROR: case MC_DRV_RSP_DEVICE_NOT_OPENED: case MC_DRV_RSP_FAILED: default: mcResult = MC_DRV_ERR_DAEMON_UNREACHABLE; break; } break; } // read payload mcDrvRspOpenSessionPayload_t rspOpenSessionPayload; len = devCon->readData( &rspOpenSessionPayload, sizeof(rspOpenSessionPayload)); if (sizeof(rspOpenSessionPayload) != len) { LOG_E("mcOpenSession(): CMD_OPEN_SESSION readPayload failed, ret=%d", len); mcResult = MC_DRV_ERR_DAEMON_UNREACHABLE; break; } // Register session with handle session->sessionId = rspOpenSessionPayload.sessionId; // Set up second channel for notifications Connection *sessionConnection = new Connection(); if (!sessionConnection->connect(SOCK_PATH)) { LOG_E("mcOpenSession(): Could not connect to %s", SOCK_PATH); delete sessionConnection; mcResult = MC_DRV_ERR_DAEMON_UNREACHABLE; break; } //TODO CONTINOUE HERE !!!! FIX RW RETURN HANDLING!!!! // Write command to use channel for notifications mcDrvCmdNqConnect_t cmdNqConnect = { // C++ does not support C99 designated initializers /* .header = */ { /* .commandId = */ MC_DRV_CMD_NQ_CONNECT }, /* .payload = */ { /* .deviceId = */ session->deviceId, /* .sessionId = */ session->sessionId, /* .deviceSessionId = */ rspOpenSessionPayload.deviceSessionId, /* .sessionMagic = */ rspOpenSessionPayload.sessionMagic } }; sessionConnection->writeData( &cmdNqConnect, sizeof(cmdNqConnect)); // Read command response, header first len = sessionConnection->readData( &rspHeader, sizeof(rspHeader)); if (sizeof(rspHeader) != len) { LOG_E("mcOpenSession(): CMD_NQ_CONNECT readRsp failed, ret=%d", len); delete sessionConnection; mcResult = MC_DRV_ERR_DAEMON_UNREACHABLE; break; } if (MC_DRV_RSP_OK != rspHeader.responseId) { LOG_E("mcOpenSession(): CMD_NQ_CONNECT failed, respId=%d", rspHeader.responseId); delete sessionConnection; mcResult = MC_DRV_ERR_NQ_FAILED; break; } // there is no payload. // Session has been established, new session object must be created device->createNewSession( session->sessionId, sessionConnection); } while (false); mutex.unlock(); // Exit critical section return mcResult; }
int CLocalSocket::write(const char * szDataBlock, int nSizeOfBlock) { if (NULL == szDataBlock) return FUNCTION_WRONG_PARAMETER; if (IsAlreadyConnected()) { HANDLE hDataReadEvent, hDataWrittenEvent; s_PacketBuffer * pDataBuffer = GetWriteDataBuffer(); CMutex dataAccessMutex = GetWriteDataAccessMutex(); CEvent dataReadEvent = GetWriteDataReadEvent(); CEvent dataWrittenEvent = GetWriteDataWrittenEvent(); int nAmountOfPackets = nSizeOfBlock / PACKET_SIZE; int nLastUsedPacketBytes = nSizeOfBlock % PACKET_SIZE; if (0 != nLastUsedPacketBytes && 0 != nAmountOfPackets) { nAmountOfPackets++; } if (0 == nAmountOfPackets) nAmountOfPackets++; if (!dataAccessMutex.lock()) return LOCAL_SOCKET_ERROR; pDataBuffer->nPacketsToBeSent = nAmountOfPackets; pDataBuffer->nBytesToBeSent = PACKET_SIZE; dataAccessMutex.unlock(); int nAmountOfBytesToBeWritten = PACKET_SIZE; int nPacketOffset = 0; for (int nCur = 0; nCur < nAmountOfPackets; nCur++) { dataAccessMutex.lock(); pDataBuffer->nCurrentNumber = nCur; if (nCur == nAmountOfPackets - 1) { (nLastUsedPacketBytes == 0) ? (nLastUsedPacketBytes = PACKET_SIZE) : (pDataBuffer->nBytesToBeSent = nLastUsedPacketBytes); nAmountOfBytesToBeWritten = nLastUsedPacketBytes; } memcpy(&pDataBuffer->cStorage[0], &szDataBlock[nPacketOffset], nAmountOfBytesToBeWritten); nPacketOffset += PACKET_SIZE; dataWrittenEvent.fire_signal(); dataAccessMutex.unlock(); if (!dataReadEvent.get_signal()) return LOCAL_SOCKET_ERROR; if (CheckForDisconnection()) return LOCAL_SOCKET_ERROR; } return (nSizeOfBlock); } return LOCAL_SOCKET_ERROR; }
int CLocalSocket::read(char * szDataBlock, int nSizeOfBlock) { if (NULL == szDataBlock) return FUNCTION_WRONG_PARAMETER; if (IsAlreadyConnected()) { HANDLE hDataReadEvent, hDataWrittenEvent; s_PacketBuffer * pDataBuffer = GetReadDataBuffer(); CMutex dataAccessMutex = GetReadDataAccessMutex(); CEvent dataReadEvent = GetReadDataReadEvent(); CEvent dataWrittenEvent = GetReadDataWrittenEvent(); dataWrittenEvent.SetTimeout(INFINITE); if (!dataWrittenEvent.get_signal()) return LOCAL_SOCKET_ERROR; if (CheckForDisconnection()) return LOCAL_SOCKET_ERROR; int nAmountOfIncomingPackets = 0; if (!dataAccessMutex.lock()) return LOCAL_SOCKET_ERROR; nAmountOfIncomingPackets = pDataBuffer->nPacketsToBeSent; int nPacketOffset = 0; if (nAmountOfIncomingPackets > 1) { int nLastUsedPacketBytes = 0; for(int nCur = 0; nCur < nAmountOfIncomingPackets; nCur++) { if (nCur > 0) { if (!dataWrittenEvent.get_signal()) return LOCAL_SOCKET_ERROR; if (CheckForDisconnection()) return LOCAL_SOCKET_ERROR; if (!dataAccessMutex.lock()) return LOCAL_SOCKET_ERROR; } if (nCur == nAmountOfIncomingPackets - 1) nLastUsedPacketBytes = pDataBuffer->nBytesToBeSent; int nAmountOfIncomingBytes = pDataBuffer->nBytesToBeSent; if (nAmountOfIncomingBytes > nSizeOfBlock) // truncate the data memcpy(&szDataBlock[nPacketOffset], &pDataBuffer->cStorage[0], nSizeOfBlock); else memcpy(&szDataBlock[nPacketOffset], &pDataBuffer->cStorage[0], nAmountOfIncomingBytes); nPacketOffset += PACKET_SIZE; dataAccessMutex.unlock(); dataReadEvent.fire_signal(); } return (nLastUsedPacketBytes == 0 ? nAmountOfIncomingPackets * PACKET_SIZE : nAmountOfIncomingPackets * PACKET_SIZE - PACKET_SIZE + nLastUsedPacketBytes); } else { int nAmountOfIncomingBytes = pDataBuffer->nBytesToBeSent; if (nAmountOfIncomingBytes > nSizeOfBlock) // truncate the data memcpy(szDataBlock, &pDataBuffer->cStorage[0], nSizeOfBlock); else memcpy(szDataBlock, &pDataBuffer->cStorage[0], nAmountOfIncomingBytes); dataAccessMutex.unlock(); dataReadEvent.fire_signal(); return nSizeOfBlock; } } return LOCAL_SOCKET_ERROR; }
explicit MutexLocker( CMutex& m ) : m(m) { m.lock(); }
//------------------------------------------------------------------------------ __MC_CLIENT_LIB_API mcResult_t mcCloseDevice( uint32_t deviceId ) { mcResult_t mcResult = MC_DRV_OK; static CMutex mutex; mutex.lock(); // Enter critical section do { Device *device = resolveDeviceId(deviceId); if (NULL == device) { LOG_E("mcCloseDevice(): Device not found"); mcResult = MC_DRV_ERR_UNKNOWN_DEVICE; break; } Connection *devCon = device->connection; // Return if not all sessions have been closed if (device->hasSessions()) { LOG_E("mcCloseDevice(): cannot close with sessions still pending"); mcResult = MC_DRV_ERR_SESSION_PENDING; break; } mcDrvCmdCloseDevice_t mcDrvCmdCloseDevice = { // C++ does not support C99 designated initializers /* .header = */ { /* .commandId = */ MC_DRV_CMD_CLOSE_DEVICE } }; int len = devCon->writeData( &mcDrvCmdCloseDevice, sizeof(mcDrvCmdCloseDevice)); // ignore error, but log details if (len < 0) { LOG_E("mcCloseDevice(): CMD_CLOSE_DEVICE writeCmd failed, ret=%d", len); mcResult = MC_DRV_ERR_DAEMON_UNREACHABLE; } mcDrvResponseHeader_t rspHeader; len = devCon->readData( &rspHeader, sizeof(rspHeader)); if (len != sizeof(rspHeader)) { LOG_E("mcCloseDevice(): CMD_CLOSE_DEVICE readResp failed, ret=%d", len); mcResult = MC_DRV_ERR_DAEMON_UNREACHABLE; break; } if (MC_DRV_RSP_OK != rspHeader.responseId) { LOG_E("mcCloseDevice(): CMD_CLOSE_DEVICE failed, respId=%d", rspHeader.responseId); mcResult = MC_DRV_ERR_DAEMON_UNREACHABLE; break; } removeDevice(deviceId); } while (false); mutex.unlock(); // Exit critical section return mcResult; }
//------------------------------------------------------------------------------ __MC_CLIENT_LIB_API mcResult_t mcUnmap( mcSessionHandle_t *sessionHandle, void *buf, mcBulkMap_t *mapInfo ) { mcResult_t mcResult = MC_DRV_ERR_UNKNOWN; static CMutex mutex; LOG_I("===%s()===", __func__); mutex.lock(); // Enter critical section do { if (NULL == sessionHandle) { LOG_E("mcUnmap(): sessionHandle is null"); mcResult = MC_DRV_ERR_INVALID_PARAMETER; break; } if (NULL == mapInfo) { LOG_E("mcUnmap(): mapInfo is null"); mcResult = MC_DRV_ERR_INVALID_PARAMETER; break; } if (NULL == buf) { LOG_E("mcUnmap(): buf is null"); mcResult = MC_DRV_ERR_INVALID_PARAMETER; break; } // Determine device the session belongs to Device *device = resolveDeviceId(sessionHandle->deviceId); if (NULL == device) { LOG_E("mcUnmap(): Device not found"); mcResult = MC_DRV_ERR_UNKNOWN_DEVICE; break; } Connection *devCon = device->connection; // Get session Session *session = device->resolveSessionId(sessionHandle->sessionId); if (NULL == session) { LOG_E("mcUnmap(): Session not found"); mcResult = MC_DRV_ERR_UNKNOWN_SESSION; break; } // Prepare unmap command mcDrvCmdUnmapBulkMem_t cmdUnmapBulkMem = { // C++ does not support C99 designated initializers /* .header = */ { /* .commandId = */ MC_DRV_CMD_UNMAP_BULK_BUF }, /* .payload = */ { /* .sessionId = */ session->sessionId, /* .secureVirtualAdr = */ (uint32_t)(mapInfo->sVirtualAddr), /* .lenBulkMem = mapInfo->sVirtualLen*/ } }; devCon->writeData( &cmdUnmapBulkMem, sizeof(cmdUnmapBulkMem)); // Read command response mcDrvResponseHeader_t rspHeader; int len = devCon->readData( &rspHeader, sizeof(rspHeader)); if (sizeof(rspHeader) != len) { LOG_E("mcUnmap(): CMD_UNMAP_BULK_BUF readRsp failed, ret=%d", len); mcResult = MC_DRV_ERR_DAEMON_UNREACHABLE; break; } if (MC_DRV_RSP_OK != rspHeader.responseId) { LOG_E("mcUnmap(): CMD_UNMAP_BULK_BUF failed, respId=%d", rspHeader.responseId); // REV We ignore Daemon Error code because client cannot handle it anyhow. mcResult = MC_DRV_ERR_DAEMON_UNREACHABLE; break; } mcDrvRspUnmapBulkMemPayload_t rspUnmapBulkMemPayload; devCon->readData( &rspUnmapBulkMemPayload, sizeof(rspUnmapBulkMemPayload)); // REV axh: what about check the payload? // Unregister mapped bulk buffer from Kernel Module and remove mapped // bulk buffer from session maintenance if (!session->removeBulkBuf(buf)) { // Removing of bulk buffer not possible LOG_E("mcUnmap(): Unregistering of bulk memory from Kernel Module failed"); mcResult = MC_DRV_ERR_BULK_UNMAPPING; break; } mcResult = MC_DRV_OK; } while (false); mutex.unlock(); // Exit critical section return mcResult; }
//------------------------------------------------------------------------------ __MC_CLIENT_LIB_API mcResult_t mcUnmap( mcSessionHandle_t *sessionHandle, void *buf, mcBulkMap_t *mapInfo ) { mcResult_t mcResult = MC_DRV_ERR_UNKNOWN; #ifndef WIN32 static CMutex mutex; LOG_I("===%s()===", __FUNCTION__); devMutex.lock(); do { CHECK_NOT_NULL(sessionHandle); CHECK_NOT_NULL(mapInfo); CHECK_NOT_NULL(buf); if (mapInfo->sVirtualAddr == 0) { LOG_E("Invalid secure virtual address %u.", (uint32_t)mapInfo->sVirtualAddr); mcResult = MC_DRV_ERR_NULL_POINTER; break; } // Determine device the session belongs to Device *device = resolveDeviceId(sessionHandle->deviceId); // Is the device known CHECK_DEVICE(device); // Is the device opened. CHECK_DEVICE_CLOSED(device, sessionHandle->deviceId) Connection *devCon = device->connection; // Get session Session *session = device->resolveSessionId(sessionHandle->sessionId); CHECK_SESSION(session, sessionHandle->sessionId); uint32_t handle = session->getBufHandle((uint32_t)mapInfo->sVirtualAddr, mapInfo->sVirtualLen); if (handle == 0) { LOG_E("Unable to find internal handle for buffer %u.", (uint32_t)mapInfo->sVirtualAddr); mcResult = MC_DRV_ERR_BLK_BUFF_NOT_FOUND; break; } LOG_I(" Unmapping %p(handle=%u) from session %03x.", buf, handle, sessionHandle->sessionId); SEND_TO_DAEMON(devCon, MC_DRV_CMD_UNMAP_BULK_BUF, session->sessionId, handle, (uint32_t)mapInfo->sVirtualAddr, mapInfo->sVirtualLen); RECV_FROM_DAEMON(devCon, &mcResult); if (mcResult != MC_DRV_OK) { LOG_E("Daemon reported failing of UNMAP BULK BUF command, responseId %d.", mcResult); // TODO-2012-09-06-haenellu: Remove once tests can handle it. mcResult = MC_DRV_ERR_DAEMON_UNREACHABLE; break; } // Unregister mapped bulk buffer from Kernel Module and remove mapped // bulk buffer from session maintenance mcResult = session->removeBulkBuf(buf); if (mcResult != MC_DRV_OK) { LOG_E("Unregistering of bulk memory from Kernel Module failed."); break; } mcResult = MC_DRV_OK; } while (false); if (mcResult == MC_DRV_ERR_SOCKET_WRITE || mcResult == MC_DRV_ERR_SOCKET_READ) { LOG_E("Connection is dead, removing device."); removeDevice(sessionHandle->deviceId); } devMutex.unlock(); #endif /* WIN32 */ return mcResult; }