Ejemplo n.º 1
0
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;
}
Ejemplo n.º 3
0
void CAppManConnectController::deleteInstance()
{
    gInstanceMutex.lock();
    delete mspInstance;
    mspInstance = 0;
    gInstanceMutex.unlock();
}
Ejemplo n.º 4
0
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;
}
Ejemplo n.º 6
0
void CTimeoutManager::deleteInstance()
{
   gsInstanceMutex.lock();
   if (msInstance)
   {
      msInstance->finish();
      delete msInstance;
      msInstance = 0;
   }
   gsInstanceMutex.unlock();
}
Ejemplo n.º 7
0
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;
}
Ejemplo n.º 9
0
CTimeoutManager * CTimeoutManager::getInstance()
{
   if (0 == CTimeoutManager::msInstance)
   {
      gsInstanceMutex.lock();
      if (0 == CTimeoutManager::msInstance)
      {
         CTimeoutManager::msInstance = new CTimeoutManager();
      }
      gsInstanceMutex.unlock();
   }
   return CTimeoutManager::msInstance;
}
Ejemplo n.º 10
0
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;
}
Ejemplo n.º 12
0
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;
}
Ejemplo n.º 25
0
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;
}
Ejemplo n.º 26
0
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;
}
Ejemplo n.º 27
0
 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;
}