//------------------------------------------------------------------------------
bool MobiCoreDriverDaemon::loadDeviceDriver(
    std::string driverPath
)
{
    bool ret = false;
    CWsm_ptr pWsm = NULL, pTciWsm = NULL;
    regObject_t *regObj = NULL;
    Connection *conn = NULL;
    mcDrvRspOpenSession_t rspOpenSession;

    do {
        //mobiCoreDevice
        LOG_I("%s: loading %s", __FUNCTION__, driverPath.c_str());

        regObj = mcRegistryGetDriverBlob(driverPath.c_str());
        if (regObj == NULL) {
            break;;
        }

        LOG_I("registering L2 in kmod, p=%p, len=%i",
              regObj->value, regObj->len);

        pWsm = mobiCoreDevice->registerWsmL2(
                   (addr_t)(regObj->value), regObj->len, 0);
        if (pWsm == NULL) {
            LOG_E("allocating WSM for Trustlet failed");
            break;
        }
        // Initialize information data of open session command
        loadDataOpenSession_t loadDataOpenSession;
        loadDataOpenSession.baseAddr = pWsm->physAddr;
        loadDataOpenSession.offs = ((uintptr_t) regObj->value) & 0xFFF;
        loadDataOpenSession.len = regObj->len;
        loadDataOpenSession.tlHeader = (mclfHeader_ptr) (regObj->value + regObj->tlStartOffset);

        pTciWsm = mobiCoreDevice->allocateContiguousPersistentWsm(DRIVER_TCI_LEN);
        if (pTciWsm == NULL) {
            LOG_E("allocating WSM TCI for Trustlet failed");
            break;
        }

        conn = new Connection();
        uint32_t mcRet = mobiCoreDevice->openSession(
                             conn,
                             &loadDataOpenSession,
                             pTciWsm->handle,
                             pTciWsm->len,
                             0,
                             &(rspOpenSession.payload));

        // Unregister physical memory from kernel module.
        // This will also destroy the WSM object.
        mobiCoreDevice->unregisterWsmL2(pWsm);
        pWsm = NULL;

        // Free memory occupied by Trustlet data
        free(regObj);
        regObj = NULL;

        if (mcRet != MC_MCP_RET_OK) {
            LOG_E("open session error %d", mcRet);
            break;
        }

        ret = true;
    } while (false);
    // Free all allocated resources
    if (ret == false) {
        LOG_I("%s: Freeing previously allocated resources!", __FUNCTION__);
        if (pWsm != NULL) {
            if (!mobiCoreDevice->unregisterWsmL2(pWsm)) {
                // At least make sure we don't leak the WSM object
                delete pWsm;
            }
        }
        // No matter if we free NULL objects
        free(regObj);

        if (conn != NULL) {
            delete conn;
        }
    } else if (conn != NULL) {
        driverResources.push_back(new MobicoreDriverResources(
                                      conn, pTciWsm, rspOpenSession.payload.sessionId));
    }

    return ret;
}
//------------------------------------------------------------------------------
bool MobiCoreDriverDaemon::loadDeviceDriver(
	std::string driverPath
) {
	bool ret = false;
	CWsm_ptr pWsm = NULL, pTciWsm = NULL;
	regObject_t *regObj = NULL;
	Connection *conn = NULL;
	uint8_t *tci = NULL;
	mcDrvRspOpenSession_t rspOpenSession;
	
	do
	{
		//mobiCoreDevice
		ifstream fs(driverPath.c_str(), ios_base::binary);
		if (!fs) {
			LOG_E("%s: failed: cannot open %s", __func__, driverPath.c_str());
			break;
		}
		
		LOG_I("%s: loading %s", __func__, driverPath.c_str());
		
		regObj = mcRegistryGetDriverBlob(driverPath.c_str());
		if (regObj == NULL) {
			break;;
		}

		LOG_I("registering L2 in kmod, p=%p, len=%i",
				regObj->value, regObj->len);
		
		// Prepare the interface structure for memory registration, then
		// register virtual memory in kernel module, create L2 table
		// TODO xgal: refactor naming of datatypes and WSM handling
		pWsm = mobiCoreDevice->registerWsmL2(
			(addr_t)(regObj->value), regObj->len, 0);
		if (pWsm == NULL)
		{
			LOG_E("allocating WSM for Trustlet failed");
			break;
		}
		// Initialize information data of open session command
		loadDataOpenSession_t loadDataOpenSession;
		loadDataOpenSession.baseAddr = pWsm->physAddr;
		loadDataOpenSession.offs = ((uint32_t) regObj->value) & 0xFFF;
		loadDataOpenSession.len = regObj->len;
		loadDataOpenSession.tlHeader = (mclfHeader_ptr) regObj->value;
		
		mcDrvCmdOpenSessionPayload_t  openSessionPayload;
		tci = (uint8_t*)malloc(DRIVER_TCI_LEN);
		pTciWsm = mobiCoreDevice->registerWsmL2(
			(addr_t)tci, DRIVER_TCI_LEN, 0);
		if (pTciWsm == NULL)
		{
			LOG_E("allocating WSM TCI for Trustlet failed");
			break;
		}
		openSessionPayload.deviceId = MC_DEVICE_ID_DEFAULT;
		openSessionPayload.tci = (uint32_t)pTciWsm->physAddr;
		openSessionPayload.len = DRIVER_TCI_LEN;

		conn = new Connection();
		mobiCoreDevice->openSession(
			conn,
			&loadDataOpenSession,
			&openSessionPayload,
			&(rspOpenSession.payload));
		
		// Unregister physical memory from kernel module.
		// This will also destroy the WSM object.
		mobiCoreDevice->unregisterWsmL2(pWsm);
		pWsm = NULL;
		
		// Free memory occupied by Trustlet data
		free(regObj);
		regObj = NULL;
		
		if (rspOpenSession.payload.mcResult != MC_MCP_RET_OK)
		{
			LOG_E("%s: rspOpenSession mcResult %d", __func__, 
				  rspOpenSession.payload.mcResult);
			break;
		}
		
		ret = true;
	} while (false);
	// Free all allocated resources
	if (ret == false) {
		LOG_I("%s: Freeing previously allocated resources!", __func__);
		if (pWsm != NULL) {
			if(!mobiCoreDevice->unregisterWsmL2(pWsm)) {
				// At least make sure we don't leak the WSM object
				delete pWsm;
			}
		}
		// No matter if we free NULL objects
		free(regObj);
		
		if (conn != NULL) {
			delete conn;
		}
	} else if (conn != NULL) {
		driverResources.push_back(new MobicoreDriverResources(
			conn, tci, pTciWsm, rspOpenSession.payload.sessionId));
	}
	
	return ret;
}