//------------------------------------------------------------------------------ Connection *MobiCoreDevice::getSessionConnection(uint32_t sessionId, notification_t *notification) { Connection *con = NULL; TrustletSession *ts = NULL; ts = getTrustletSession(sessionId); if (ts == NULL) { return NULL; } con = ts->notificationConnection; if (con == NULL) { ts->queueNotification(notification); return NULL; } return con; }
//------------------------------------------------------------------------------ mcResult_t MobiCoreDevice::unmapBulk(uint32_t sessionId, uint32_t handle, uint32_t secureVirtualAdr, uint32_t lenBulkMem) { TrustletSession *ts = getTrustletSession(sessionId); if (ts == NULL) { LOG_E("no session found with id=%d", sessionId); return MC_DRV_ERR_DAEMON_UNKNOWN_SESSION; } // Write MCP unmap command to buffer mcpMessage->cmdUnmap.cmdHeader.cmdId = MC_MCP_CMD_UNMAP; mcpMessage->cmdUnmap.sessionId = sessionId; mcpMessage->cmdUnmap.wsmType = WSM_L2; mcpMessage->cmdUnmap.secureVirtualAdr = secureVirtualAdr; mcpMessage->cmdUnmap.lenVirtualBuffer = lenBulkMem; // Notify MC about the availability of a new command inside the MCP buffer notify(SID_MCP); // Wait till response from MC is available if (!waitMcpNotification()) { return MC_DRV_ERR_DAEMON_MCI_ERROR; } // Check if the command response ID is correct if (mcpMessage->rspHeader.rspId != (MC_MCP_CMD_UNMAP | FLAG_RESPONSE)) { LOG_E("CMD_OPEN_SESSION got invalid MCP response"); return MC_DRV_ERR_DAEMON_MCI_ERROR; } uint32_t mcRet = mcpMessage->rspUnmap.rspHeader.result; if (mcRet != MC_MCP_RET_OK) { LOG_E("MCP UNMAP returned code %d.", mcRet); return MAKE_MC_DRV_MCP_ERROR(mcRet); } else { // Just remove the buffer // TODO-2012-09-06-haenellu: Haven't we removed it already? if (!ts->removeBulkBuff(handle)) LOG_I("unmapBulk(): no buffer found found with handle=%u", handle); } return MC_DRV_OK; }
//------------------------------------------------------------------------------ mcResult_t MobiCoreDevice::mapBulk(uint32_t sessionId, uint32_t handle, uint32_t pAddrL2, uint32_t offsetPayload, uint32_t lenBulkMem, uint32_t *secureVirtualAdr) { TrustletSession *ts = getTrustletSession(sessionId); if (ts == NULL) { LOG_E("no session found with id=%d", sessionId); return MC_DRV_ERR_DAEMON_UNKNOWN_SESSION; } // TODO-2012-09-06-haenellu: Think about not ignoring the error case, ClientLib does not allow this. ts->addBulkBuff(new CWsm((void *)offsetPayload, lenBulkMem, handle, (void *)pAddrL2)); // Write MCP map message to buffer mcpMessage->cmdMap.cmdHeader.cmdId = MC_MCP_CMD_MAP; mcpMessage->cmdMap.sessionId = sessionId; mcpMessage->cmdMap.wsmType = WSM_L2; mcpMessage->cmdMap.adrBuffer = (uint32_t)(pAddrL2); mcpMessage->cmdMap.ofsBuffer = offsetPayload; mcpMessage->cmdMap.lenBuffer = lenBulkMem; // Notify MC about the availability of a new command inside the MCP buffer notify(SID_MCP); // Wait till response from MC is available if (!waitMcpNotification()) { return MC_DRV_ERR_DAEMON_MCI_ERROR; } // Check if the command response ID is correct if (mcpMessage->rspHeader.rspId != (MC_MCP_CMD_MAP | FLAG_RESPONSE)) { LOG_E("CMD_MAP got invalid MCP response"); return MC_DRV_ERR_DAEMON_MCI_ERROR; } uint32_t mcRet = mcpMessage->rspMap.rspHeader.result; if (mcRet != MC_MCP_RET_OK) { LOG_E("MCP MAP returned code %d.", mcRet); return MAKE_MC_DRV_MCP_ERROR(mcRet); } *secureVirtualAdr = mcpMessage->rspMap.secureVirtualAdr; return MC_DRV_OK; }
/** * TODO-2012-09-19-haenellu: Do some more checks here, otherwise rogue clientLib * can close sessions from different TLCs. That is, deviceConnection is ignored below. * * Need connection as well as according session ID, so that a client can not * close sessions not belonging to him. */ mcResult_t MobiCoreDevice::closeSession(Connection *deviceConnection, uint32_t sessionId) { TrustletSession *ts = getTrustletSession(sessionId); if (ts == NULL) { LOG_E("no session found with id=%d", sessionId); return MC_DRV_ERR_DAEMON_UNKNOWN_SESSION; } uint32_t mcRet = closeSession(sessionId); if (mcRet != MC_DRV_OK) { return mcRet; } // remove objects removeTrustletSession(sessionId); delete ts; return MC_DRV_OK; }
//------------------------------------------------------------------------------ void TrustZoneDevice::notify( uint32_t sessionId ) { // Check if it is MCP session - handle openSession() command if (sessionId != SID_MCP) { // Check if session ID exists to avoid flooding of nq by clients TrustletSession *ts = getTrustletSession(sessionId); if (ts == NULL) { LOG_E("no session with id=%d", sessionId); return; } LOG_I(" Sending notification for session %d to MobiCore", sessionId); } else { LOG_I(" Sending MCP notification to MobiCore"); } // Notify MobiCore about new data notification_t notification = { .sessionId = sessionId, .payload = 0 }; nq->putNotification(¬ification); //IMPROVEMENT-2012-03-07-maneaval What happens when/if nsiq fails? //In the old days an exception would be thrown but it was uncertain //where it was handled, some server(sock or Netlink). In that case //the server would just die but never actually signaled to the client //any error condition nsiq(); } //------------------------------------------------------------------------------ uint32_t TrustZoneDevice::getMobicoreStatus(void) { uint32_t status; pMcKMod->fcInfo(1, &status, NULL); return status; }
//------------------------------------------------------------------------------ void TrustZoneDevice::notify( uint32_t sessionId ) { do { // Check if it is MCP session - handle openSession() command if (SID_MCP != sessionId) { // Check if session ID exists to avoid flooding of nq by clients TrustletSession* ts = getTrustletSession(sessionId); if (NULL == ts) { LOG_E("notify(): no session with id=%d", sessionId); break; } } LOG_I("notify(): Send notification for id=%d", sessionId); // Notify MobiCore about new data notification_t notification = { // C++ does not support C99 designated initializers /* .sessionId = */ sessionId, /* .payload = */ 0 }; nq->putNotification(¬ification); //IMPROVEMENT-2012-03-07-maneaval What happens when/if nsiq fails? //In the old days an exception would be thrown but it was uncertain //where it was handled, some server(sock or Netlink). In that case //the server would just die but never actually signaled to the client //any error condition nsiq(); } while(0); }