t-base-300: First Release of t-base-300 Daemon and RootPA.

Signed-off-by: Oana Medvesan <medvesan.oana@gmail.com>
diff --git a/Android.mk b/Android.mk
index a828b42..43ad238 100755
--- a/Android.mk
+++ b/Android.mk
@@ -20,13 +20,13 @@
 GLOBAL_LIBRARIES := libstlport
 
 # Include the Daemon
-include $(MOBICORE_PROJECT_PATH)/daemon/Android.mk
+include $(MOBICORE_PROJECT_PATH)/MobiCoreDriverLib/Android.mk
 
 MC_INCLUDE_DIR := $(COMP_PATH_MobiCore)/inc \
     $(COMP_PATH_MobiCore)/inc/TlCm \
     $(COMP_PATH_MobiCore)/inc/TlCm/2.0 \
-    $(MOBICORE_PROJECT_PATH)/daemon/ClientLib/public \
-    $(MOBICORE_PROJECT_PATH)/daemon/Registry/Public
+    $(MOBICORE_PROJECT_PATH)/MobiCoreDriverLib/ClientLib/public \
+    $(MOBICORE_PROJECT_PATH)/MobiCoreDriverLib/Registry/Public
 MC_DEBUG := _DEBUG
 SYSTEM_LIB_DIR=/system/lib
 
diff --git a/MobiCoreDriverLib/Android.mk b/MobiCoreDriverLib/Android.mk
new file mode 100755
index 0000000..89696ad
--- /dev/null
+++ b/MobiCoreDriverLib/Android.mk
@@ -0,0 +1,121 @@
+# =============================================================================
+#
+# MobiCore Android build components
+#
+# =============================================================================
+
+LOCAL_PATH := $(call my-dir)
+
+# Client Library
+# =============================================================================
+include $(CLEAR_VARS)
+LOCAL_MODULE := libMcClient
+LOCAL_MODULE_TAGS := debug eng optional
+LOCAL_C_INCLUDES += $(GLOBAL_INCLUDES)
+LOCAL_SHARED_LIBRARIES += $(GLOBAL_LIBRARIES)
+
+LOCAL_CFLAGS := -fvisibility=hidden -fvisibility-inlines-hidden
+LOCAL_CFLAGS += -include buildTag.h
+LOCAL_CFLAGS += -DLOG_TAG=\"McClient\"
+LOCAL_CFLAGS += -DTBASE_API_LEVEL=3
+
+# Add new source files here
+LOCAL_SRC_FILES += \
+    ClientLib/Device.cpp \
+    ClientLib/ClientLib.cpp \
+    ClientLib/Session.cpp \
+    Common/CMutex.cpp \
+    Common/Connection.cpp \
+    ClientLib/GP/tee_client_api.cpp
+
+LOCAL_C_INCLUDES +=\
+    $(LOCAL_PATH)/Common \
+    $(LOCAL_PATH)/ClientLib/public \
+    $(LOCAL_PATH)/ClientLib/public/GP \
+    $(MOBICORE_PROJECT_PATH)/include/GPD_TEE_Internal_API \
+    $(MOBICORE_PROJECT_PATH)/include/public \
+    $(COMP_PATH_MobiCore)/inc \
+    $(COMP_PATH_MobiCore)/inc/McLib 
+
+LOCAL_EXPORT_C_INCLUDE_DIRS +=\
+     $(COMP_PATH_MobiCore)/inc \
+     $(LOCAL_PATH)/ClientLib/public 
+
+include $(LOCAL_PATH)/Kernel/Android.mk
+# Import logwrapper
+include $(LOG_WRAPPER)/Android.mk
+
+include $(BUILD_SHARED_LIBRARY)
+
+# Daemon Application
+# =============================================================================
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := mcDriverDaemon
+LOCAL_MODULE_TAGS := debug eng optional
+LOCAL_CFLAGS += -include buildTag.h
+LOCAL_CFLAGS += -DLOG_TAG=\"McDaemon\"
+LOCAL_CFLAGS += -DTBASE_API_LEVEL=3
+LOCAL_C_INCLUDES += $(GLOBAL_INCLUDES)
+LOCAL_SHARED_LIBRARIES += $(GLOBAL_LIBRARIES) libMcClient
+
+include $(LOCAL_PATH)/Daemon/Android.mk
+
+# Common Source files required for building the daemon
+LOCAL_SRC_FILES += Common/CMutex.cpp \
+    Common/Connection.cpp \
+    Common/NetlinkConnection.cpp \
+    Common/CSemaphore.cpp \
+    Common/CThread.cpp
+
+# Includes required for the Daemon
+LOCAL_C_INCLUDES +=\
+    $(LOCAL_PATH)/Common \
+    $(LOCAL_PATH)/common/MobiCore/inc \
+    $(LOCAL_PATH)/ClientLib/public \
+    $(LOCAL_PATH)/ClientLib/public/GP \
+    $(MOBICORE_PROJECT_PATH)/include/public \
+    $(COMP_PATH_MobiCore)/inc \
+    $(COMP_PATH_MobiCore)/inc/McLib 
+
+# Private Registry components
+LOCAL_C_INCLUDES += $(LOCAL_PATH)/Registry/Public \
+  $(LOCAL_PATH)/Registry 
+
+LOCAL_SRC_FILES  += Registry/PrivateRegistry.cpp
+
+# Common components
+include $(LOCAL_PATH)/Kernel/Android.mk
+# Logwrapper
+include $(LOG_WRAPPER)/Android.mk
+
+include $(BUILD_EXECUTABLE)
+
+# Registry Shared Library
+# =============================================================================
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := libMcRegistry
+LOCAL_MODULE_TAGS := debug eng optional
+LOCAL_CFLAGS += -DLOG_TAG=\"McRegistry\"
+LOCAL_C_INCLUDES += $(GLOBAL_INCLUDES)
+LOCAL_SHARED_LIBRARIES += $(GLOBAL_LIBRARIES)
+
+LOCAL_C_INCLUDES += $(LOCAL_PATH)/Common \
+     $(LOCAL_PATH)/Daemon/public \
+     $(LOCAL_PATH)/ClientLib/public
+
+# Common Source files required for building the daemon
+LOCAL_SRC_FILES += Common/CMutex.cpp \
+     Common/Connection.cpp \
+     Common/CSemaphore.cpp 
+#     Common/CThread.cpp
+
+#LOCAL_LDLIBS := -lthread_db
+
+include $(LOCAL_PATH)/Registry/Android.mk
+
+# Import logwrapper
+include $(LOG_WRAPPER)/Android.mk
+
+include $(BUILD_SHARED_LIBRARY)
\ No newline at end of file
diff --git a/daemon/Application.mk b/MobiCoreDriverLib/Application.mk
old mode 100644
new mode 100755
similarity index 96%
rename from daemon/Application.mk
rename to MobiCoreDriverLib/Application.mk
index df782e0..d36202d
--- a/daemon/Application.mk
+++ b/MobiCoreDriverLib/Application.mk
@@ -25,3 +25,5 @@
 APP_CFLAGS += -Wall
 
 LOG_WRAPPER := $(COMP_PATH_Logwrapper)
+
+APP_PLATFORM := android-9
diff --git a/daemon/ClientLib/Android.mk b/MobiCoreDriverLib/ClientLib/Android.mk
old mode 100644
new mode 100755
similarity index 100%
rename from daemon/ClientLib/Android.mk
rename to MobiCoreDriverLib/ClientLib/Android.mk
diff --git a/daemon/ClientLib/ClientLib.cpp b/MobiCoreDriverLib/ClientLib/ClientLib.cpp
old mode 100644
new mode 100755
similarity index 78%
rename from daemon/ClientLib/ClientLib.cpp
rename to MobiCoreDriverLib/ClientLib/ClientLib.cpp
index 8bbd5e8..20b08db
--- a/daemon/ClientLib/ClientLib.cpp
+++ b/MobiCoreDriverLib/ClientLib/ClientLib.cpp
@@ -2,44 +2,51 @@
  * @{
  * @file
  *
- * MobiCore Driver API.
+ * <t-base Driver API.
  *
- * Functions for accessing MobiCore functionality from the normal world.
+ * Functions for accessing <t-base functionality from the normal world.
  * Handles sessions and notifications via MCI buffer.
  *
- * <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
+ *
+ * Copyright (c) 2013 TRUSTONIC LIMITED
+ * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- *    products derived from this software without specific prior
- *    written permission.
  *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 3. Neither the name of the TRUSTONIC LIMITED nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 #include <stdint.h>
+#ifndef WIN32
 #include <stdbool.h>
 #include <list>
 #include "assert.h"
+#endif
 
 #include "public/MobiCoreDriverApi.h"
 
+#ifndef WIN32
 #include "mc_linux.h"
 #include "Connection.h"
 #include "CMutex.h"
@@ -73,8 +80,8 @@
 Device *resolveDeviceId(uint32_t deviceId)
 {
     for (list<Device *>::iterator iterator = devices.begin();
-         iterator != devices.end();
-         ++iterator) {
+            iterator != devices.end();
+            ++iterator) {
         Device  *device = (*iterator);
 
         if (device->deviceId == deviceId) {
@@ -129,7 +136,7 @@
         mcResult = MC_DRV_ERR_DAEMON_DEVICE_NOT_OPEN; \
         break; \
     } else \
-    	CHECK_DEVICE(device);
+        CHECK_DEVICE(device);
 
 
 
@@ -181,11 +188,13 @@
         break; \
     } \
 }
+#endif /* WIN32 */
 
 //------------------------------------------------------------------------------
 __MC_CLIENT_LIB_API mcResult_t mcOpenDevice(uint32_t deviceId)
 {
     mcResult_t mcResult = MC_DRV_OK;
+#ifndef WIN32
 
     Connection *devCon = NULL;
 
@@ -217,7 +226,7 @@
         char *errmsg;
         uint32_t version = 0;
         mcResult = getDaemonVersion(devCon, &version);
-        if(mcResult != MC_DRV_OK) {
+        if (mcResult != MC_DRV_OK) {
             break;
         }
         if (!checkVersionOkDAEMON(version, &errmsg)) {
@@ -262,6 +271,7 @@
         LOG_I(" Successfully opened the device.");
     }
 
+#endif /* WIN32 */
     return mcResult;
 }
 
@@ -272,7 +282,9 @@
 )
 {
     mcResult_t mcResult = MC_DRV_OK;
-    devMutex.lock();
+#ifndef WIN32
+
+	devMutex.lock();
     LOG_I("===%s(%i)===", __FUNCTION__, deviceId);
     do {
         Device *device = resolveDeviceId(deviceId);
@@ -311,7 +323,9 @@
     } while (false);
 
     devMutex.unlock();
-    return mcResult;
+
+#endif /* WIN32 */
+	return mcResult;
 }
 
 
@@ -324,15 +338,17 @@
 )
 {
     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);
-        CHECK_NOT_NULL(tci);
 
         if (len > MC_MAX_TCI_LEN) {
             LOG_E("TCI length is longer than %d", MC_MAX_TCI_LEN);
@@ -342,7 +358,6 @@
 
         // Get the device associated with the given session
         Device *device = resolveDeviceId(session->deviceId);
-        BulkBufferDescriptor *bulkBuf = NULL;
         CHECK_DEVICE(device);
 
         Connection *devCon = device->connection;
@@ -351,17 +366,21 @@
         // Get the physical address of the given TCI
         CWsm_ptr pWsm = device->findContiguousWsm(tci);
         if (pWsm == NULL) {
-            // Then assume it's a normal buffer that needs to be mapped
-            mcResult = device->mapBulkBuf(tci, len, &bulkBuf);
-            if (mcResult != MC_DRV_OK) {
-                bulkBuf = NULL;
-                LOG_E("Registering buffer failed. ret=%x", mcResult);
-                mcResult = MC_DRV_ERR_WSM_NOT_FOUND;;
+            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;
             }
-            handle = bulkBuf->handle;
-        }
-        else {
+        } else {
             if (pWsm->len < len) {
                 LOG_E("mcOpenSession(): length is more than allocated TCI");
                 mcResult = MC_DRV_ERR_TCI_GREATER_THAN_WSM;
@@ -387,7 +406,7 @@
                 LOG_E("Daemon could not open session, responseId %d.", mcResult);
             } else {
                 uint32_t mcpResult = MC_DRV_ERROR_MCP(mcResult);
-                LOG_E("MobiCore reported failing of MC_MCP_CMD_OPEN_SESSION command, mcpResult %d.", mcpResult);
+                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) {
@@ -471,13 +490,17 @@
         // 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)
+        if (bulkBuf)
             sessionObj->addBulkBuf(bulkBuf);
 
         LOG_I(" Successfully opened session %d.", 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.");
@@ -486,6 +509,7 @@
 
     devMutex.unlock();
 
+#endif /* WIN32 */
     return mcResult;
 }
 
@@ -500,10 +524,13 @@
 )
 {
     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);
@@ -518,7 +545,6 @@
 
         // Get the device associated with the given session
         Device *device = resolveDeviceId(session->deviceId);
-        BulkBufferDescriptor *bulkBuf = NULL;
         CHECK_DEVICE(device);
 
         Connection *devCon = device->connection;
@@ -530,14 +556,12 @@
             // Then assume it's a normal buffer that needs to be mapped
             mcResult = device->mapBulkBuf(tci, len, &bulkBuf);
             if (mcResult != MC_DRV_OK) {
-                bulkBuf = NULL;
                 LOG_E("Registering buffer failed. ret=%x", mcResult);
                 mcResult = MC_DRV_ERR_WSM_NOT_FOUND;;
                 break;
             }
             handle = bulkBuf->handle;
-        }
-        else {
+        } else {
             if (pWsm->len < len) {
                 LOG_E("mcOpenSession(): length is more than allocated TCI");
                 mcResult = MC_DRV_ERR_TCI_GREATER_THAN_WSM;
@@ -556,9 +580,11 @@
 
         // Send the full trustlet data
         int ret = devCon->writeData(trustlet, tlen);
-        if(ret < 0) {
-            LOG_E("sending to Daemon failed."); \
-            mcResult = MC_DRV_ERR_SOCKET_WRITE; \
+        if (ret < 0) {
+            LOG_E("sending to Daemon failed.");
+            \
+            mcResult = MC_DRV_ERR_SOCKET_WRITE;
+            \
             break;
         }
 
@@ -572,7 +598,7 @@
                 LOG_E("Daemon could not open session, responseId %d.", mcResult);
             } else {
                 uint32_t mcpResult = MC_DRV_ERROR_MCP(mcResult);
-                LOG_E("MobiCore reported failing of MC_MCP_CMD_OPEN_SESSION command, mcpResult %d.", mcpResult);
+                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) {
@@ -657,13 +683,17 @@
         // 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)
+        if (bulkBuf)
             sessionObj->addBulkBuf(bulkBuf);
 
         LOG_I(" Successfully opened session %d.", 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.");
@@ -672,6 +702,191 @@
 
     devMutex.unlock();
 
+#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)(tci) & 0xFFF,
+                       (uint32_t)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;
+                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 %d.", 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;
 }
 
@@ -679,6 +894,7 @@
 __MC_CLIENT_LIB_API mcResult_t mcCloseSession(mcSessionHandle_t *session)
 {
     mcResult_t mcResult = MC_DRV_OK;
+#ifndef WIN32
 
     LOG_I("===%s()===", __FUNCTION__);
     devMutex.lock();
@@ -707,7 +923,13 @@
         }
 
         bool r = device->removeSession(session->sessionId);
-        assert(r == true);
+        if (!r) 
+        {
+            LOG_E("removeSession failed");
+            assert(0);
+        }
+
+
 
     } while (false);
 
@@ -718,6 +940,7 @@
 
     devMutex.unlock();
 
+#endif /* WIN32 */
     return mcResult;
 }
 
@@ -728,7 +951,9 @@
 )
 {
     mcResult_t mcResult = MC_DRV_OK;
-    devMutex.lock();
+#ifndef WIN32
+
+	devMutex.lock();
     LOG_I("===%s()===", __FUNCTION__);
 
     do {
@@ -753,6 +978,8 @@
     }
 
     devMutex.unlock();
+
+#endif /* WIN32 */
     return mcResult;
 }
 
@@ -764,6 +991,7 @@
 )
 {
     mcResult_t mcResult = MC_DRV_OK;
+#ifndef WIN32
 
     // TODO-2012-11-02-gurel: devMutex locking and unlocking had to be commented out
     // below. Otherwise, when there are multiple threads in Nwd TLC side, we endup a
@@ -840,6 +1068,8 @@
     } while (false);
 
     //devMutex.unlock();
+
+#endif /* WIN32 */
     return mcResult;
 }
 
@@ -853,6 +1083,7 @@
     uint32_t    wsmFlags)
 {
     mcResult_t mcResult = MC_DRV_ERR_UNKNOWN;
+#ifndef WIN32
 
     LOG_I("===%s(len=%i)===", __FUNCTION__, len);
 
@@ -883,6 +1114,7 @@
 
     devMutex.unlock();
 
+#endif /* WIN32 */
     return mcResult;
 }
 
@@ -894,6 +1126,8 @@
 )
 {
     mcResult_t mcResult = MC_DRV_ERR_UNKNOWN;
+#ifndef WIN32
+
     Device *device;
 
     devMutex.lock();
@@ -931,6 +1165,7 @@
 
     devMutex.unlock();
 
+#endif /* WIN32 */
     return mcResult;
 }
 
@@ -943,6 +1178,8 @@
 )
 {
     mcResult_t mcResult = MC_DRV_ERR_UNKNOWN;
+#ifndef WIN32
+
     static CMutex mutex;
 
     LOG_I("===%s()===", __FUNCTION__);
@@ -1022,6 +1259,7 @@
 
     devMutex.unlock();
 
+#endif /* WIN32 */
     return mcResult;
 }
 
@@ -1033,6 +1271,8 @@
 )
 {
     mcResult_t mcResult = MC_DRV_ERR_UNKNOWN;
+#ifndef WIN32
+
     static CMutex mutex;
 
     LOG_I("===%s()===", __FUNCTION__);
@@ -1042,6 +1282,7 @@
     do {
         CHECK_NOT_NULL(sessionHandle);
         CHECK_NOT_NULL(mapInfo);
+        CHECK_NOT_NULL(mapInfo->sVirtualAddr);
         CHECK_NOT_NULL(buf);
 
         // Determine device the session belongs to
@@ -1058,7 +1299,7 @@
         Session *session = device->resolveSessionId(sessionHandle->sessionId);
         CHECK_SESSION(session, sessionHandle->sessionId);
 
-        uint32_t handle = session->getBufHandle(mapInfo->sVirtualAddr);
+        uint32_t handle = session->getBufHandle(mapInfo->sVirtualAddr, mapInfo->sVirtualLen);
         if (handle == 0) {
             LOG_E("Unable to find internal handle for buffer %p.", mapInfo->sVirtualAddr);
             mcResult = MC_DRV_ERR_BLK_BUFF_NOT_FOUND;
@@ -1101,6 +1342,7 @@
 
     devMutex.unlock();
 
+#endif /* WIN32 */
     return mcResult;
 }
 
@@ -1112,6 +1354,7 @@
 )
 {
     mcResult_t mcResult = MC_DRV_OK;
+#ifndef WIN32
 
     devMutex.lock();
     LOG_I("===%s()===", __FUNCTION__);
@@ -1138,7 +1381,9 @@
     } while (false);
 
     devMutex.unlock();
-    return mcResult;
+
+#endif /* WIN32 */
+	return mcResult;
 }
 
 //------------------------------------------------------------------------------
@@ -1148,7 +1393,11 @@
     uint32_t        len
 )
 {
+#ifndef WIN32
+
     LOG_W("mcDriverCtrl(): not implemented");
+
+#endif /* WIN32 */
     return MC_DRV_ERR_NOT_IMPLEMENTED;
 }
 
@@ -1159,6 +1408,7 @@
 )
 {
     mcResult_t mcResult = MC_DRV_OK;
+#ifndef WIN32
 
     devMutex.lock();
     LOG_I("===%s()===", __FUNCTION__);
@@ -1198,10 +1448,12 @@
     } while (0);
 
     devMutex.unlock();
+
+#endif /* WIN32 */
     return mcResult;
 }
 
-
+#ifndef WIN32
 //------------------------------------------------------------------------------
 // Only called by mcOpenDevice()
 // Must be taken with devMutex locked.
@@ -1235,5 +1487,6 @@
 
     return mcResult;
 }
+#endif /* WIN32 */
 
 /** @} */
diff --git a/daemon/ClientLib/Device.cpp b/MobiCoreDriverLib/ClientLib/Device.cpp
old mode 100644
new mode 100755
similarity index 80%
rename from daemon/ClientLib/Device.cpp
rename to MobiCoreDriverLib/ClientLib/Device.cpp
index 6b3bfbb..2141f99
--- a/daemon/ClientLib/Device.cpp
+++ b/MobiCoreDriverLib/ClientLib/Device.cpp
@@ -6,31 +6,35 @@
  *
  * Device and Trustlet Session management Funtions.
  *
- * <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
+ *
+ * Copyright (c) 2013 TRUSTONIC LIMITED
+ * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- *    products derived from this software without specific prior
- *    written permission.
  *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 3. Neither the name of the TRUSTONIC LIMITED nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 #include <stdint.h>
 #include <vector>
@@ -154,7 +158,7 @@
     // Allocate shared memory
     addr_t    virtAddr;
     uint32_t  handle;
-    addr_t    physAddr;
+    uint64_t    physAddr;
     mcResult_t  ret;
 
     assert(wsm != NULL);
@@ -168,7 +172,7 @@
         return ret;
     }
 
-    LOG_I(" mapped handle %d to %p, phys=%p ", handle, virtAddr, physAddr);
+    LOG_I(" mapped handle %d to %p, phys=%#llx  ", handle, virtAddr, physAddr);
 
     // Register (vaddr,paddr) with device
     *wsm = new CWsm(virtAddr, len, handle, physAddr);
@@ -195,7 +199,7 @@
     // We just looked this up using findContiguousWsm
     assert(ret == MC_DRV_OK);
 
-    LOG_I(" unmapping handle %d from %p, phys=%p",
+    LOG_I(" unmapping handle %d from %p, phys=%#llx",
           pWsm->handle, pWsm->virtAddr, pWsm->physAddr);
 
     ret = pMcKMod->free(pWsm->handle, pWsm->virtAddr, pWsm->len);
@@ -216,6 +220,10 @@
 {
     CWsm_ptr pWsm = NULL;
 
+    if (virtAddr == NULL) {
+        return pWsm;
+    }
+
     for ( wsmIterator_t iterator = wsmL2List.begin();
             iterator != wsmL2List.end();
             ++iterator) {
@@ -233,13 +241,13 @@
 //------------------------------------------------------------------------------
 mcResult_t Device::mapBulkBuf(addr_t buf, uint32_t len, BulkBufferDescriptor **blkBuf)
 {
-    addr_t pPhysWsmL2;
+    uint64_t PhysWsmL2;
     uint32_t handle;
 
     *blkBuf = NULL;
 
     // Prepare the interface structure for memory registration in Kernel Module
-    mcResult_t ret = pMcKMod->registerWsmL2(buf, len, 0, &handle, &pPhysWsmL2);
+    mcResult_t ret = pMcKMod->registerWsmL2(buf, len, 0, &handle, &PhysWsmL2);
     if (ret != MC_DRV_OK) {
         LOG_V(" mcKMod->registerWsmL2() failed with %x", ret);
         return ret;
@@ -248,7 +256,7 @@
     LOG_V(" addBulkBuf - Handle of L2 Table = %u", handle);
 
     // Create new descriptor - secure virtual virtual set to 0, unknown!
-    *blkBuf = new BulkBufferDescriptor(buf, 0x0, len, handle, pPhysWsmL2);
+          *blkBuf = new BulkBufferDescriptor(buf, 0x0, len, handle);
 
     return MC_DRV_OK;
 }
diff --git a/daemon/ClientLib/Device.h b/MobiCoreDriverLib/ClientLib/Device.h
old mode 100644
new mode 100755
similarity index 76%
rename from daemon/ClientLib/Device.h
rename to MobiCoreDriverLib/ClientLib/Device.h
index d9a5741..767f20e
--- a/daemon/ClientLib/Device.h
+++ b/MobiCoreDriverLib/ClientLib/Device.h
@@ -6,31 +6,35 @@
  *
  * Device and Trustlet Session management Functions.
  *
- * <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
+ *
+ * Copyright (c) 2013 TRUSTONIC LIMITED
+ * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- *    products derived from this software without specific prior
- *    written permission.
  *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 3. Neither the name of the TRUSTONIC LIMITED nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 #ifndef DEVICE_H_
 #define DEVICE_H_
diff --git a/MobiCoreDriverLib/ClientLib/GP/tee_client_api.cpp b/MobiCoreDriverLib/ClientLib/GP/tee_client_api.cpp
new file mode 100755
index 0000000..e86fa97
--- /dev/null
+++ b/MobiCoreDriverLib/ClientLib/GP/tee_client_api.cpp
@@ -0,0 +1,833 @@
+/*
+ * Copyright (c) 2013 TRUSTONIC LIMITED
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the TRUSTONIC LIMITED nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#undef LOG_TAG
+#define LOG_TAG "GpClient"
+#include "tee_client_api.h"
+#include "log.h"
+#include "MobiCoreDriverApi.h"
+#include "Mci/mcinq.h"
+#include <sys/mman.h>
+#include "GpTci.h"
+
+//------------------------------------------------------------------------------
+// Macros
+#define _TEEC_GET_PARAM_TYPE(t, i) (((t) >> (4*i)) & 0xF)
+
+// Max. session number
+#define _TEEC_SESSION_NUMBER        50
+
+//Parameter number
+#define _TEEC_PARAMETER_NUMBER      4
+
+
+//------------------------------------------------------------------------------
+//Local satic functions
+static void _libUuidToArray(
+    const TEEC_UUID *uuid,
+    uint8_t         *uuid_str);
+
+
+static TEEC_Result _TEEC_UnwindOperation(
+    _TEEC_TCI           *tci,
+    mcSessionHandle_t   *handle,
+    TEEC_Operation      *operation,
+    bool                copyValues,
+    uint32_t            *returnOrigin);
+
+static TEEC_Result _TEEC_SetupOperation(
+    _TEEC_TCI           *tci,
+    mcSessionHandle_t   *handle,
+    TEEC_Operation      *operation,
+    uint32_t            *returnOrigin);
+
+static TEEC_Result _TEEC_CallTA(
+    TEEC_Session    *session,
+    TEEC_Operation  *operation,
+    uint32_t        *returnOrigin);
+
+//------------------------------------------------------------------------------
+static void _libUuidToArray(
+    const TEEC_UUID *uuid,
+    uint8_t         *uuidArr)
+{
+    uint8_t *pIdentifierCursor = (uint8_t *)uuid;
+    /* offsets and syntax constants. See explanations above */
+#ifdef S_BIG_ENDIAN
+    uint32_t offsets = 0;
+#else
+    uint32_t offsets = 0xF1F1DF13;
+#endif
+    uint32_t i;
+
+    for (i = 0; i < sizeof(TEEC_UUID); i++) {
+        /* Two-digit hex number */
+        uint8_t number;
+        int32_t offset = ((int32_t)((offsets & 0xF) << 28)) >> 28;
+        number = pIdentifierCursor[offset];
+        offsets >>= 4;
+        pIdentifierCursor++;
+
+        uuidArr[i] = number;
+    }
+}
+
+//------------------------------------------------------------------------------
+static TEEC_Result _TEEC_SetupOperation(
+    _TEEC_TCI           *tci,
+    mcSessionHandle_t   *handle,
+    TEEC_Operation      *operation,
+    uint32_t            *returnOrigin)
+{
+    uint32_t                    i;
+    _TEEC_ParameterInternal     *imp;
+    TEEC_Parameter              *ext;
+    mcResult_t                  mcRet = MC_DRV_OK;
+    TEEC_Result                 teecResult = TEEC_SUCCESS;
+
+    //operation can be NULL
+    tci->operation.isCancelled = false;
+    if (operation != NULL) {
+        LOG_I(" %s()", __func__);
+
+        tci->operation.paramTypes = operation->paramTypes;
+        operation->started = 1;
+
+        //TODO: This design allows a non-NULL buffer with a size of 0 bytes to allow trivial integration with any
+        //implementations of the C library malloc, in which is valid to allocate a zero byte buffer and receive a non-
+        //NULL pointer which may not be de-referenced in return.
+
+
+        for (i = 0; i < _TEEC_PARAMETER_NUMBER; i++) {
+            imp = &tci->operation.params[i];
+            ext = &operation->params[i];
+
+            switch (_TEEC_GET_PARAM_TYPE(operation->paramTypes, i)) {
+            case TEEC_VALUE_OUTPUT:
+                break;
+            case TEEC_NONE:
+                LOG_I("  cycle %d, TEEC_NONE", i);
+                break;
+            case TEEC_VALUE_INPUT:
+            case TEEC_VALUE_INOUT: {
+                LOG_I("  cycle %d, TEEC_VALUE_IN*", i);
+                imp->value.a = ext->value.a;
+                imp->value.b = ext->value.b;
+                break;
+            }
+            case TEEC_MEMREF_TEMP_INPUT:
+            case TEEC_MEMREF_TEMP_OUTPUT:
+            case TEEC_MEMREF_TEMP_INOUT: {
+                //TODO: A Temporary Memory Reference may be null, which can be used to denote a special case for the
+                //parameter. Output Memory References that are null are typically used to request the required output size.
+                LOG_I("  cycle %d, TEEC_TEMP_IN*", i);
+                imp->memref.mapInfo.sVirtualLen = 0;
+                if ((ext->tmpref.size) && (ext->tmpref.buffer)) {
+                    mcRet = mcMap(handle, ext->tmpref.buffer, ext->tmpref.size, &imp->memref.mapInfo);
+                    if (mcRet != MC_DRV_OK) {
+                        LOG_E("mcMap failed, mcRet=0x%08X", mcRet);
+                        *returnOrigin = TEEC_ORIGIN_COMMS;
+                        i = _TEEC_PARAMETER_NUMBER;
+                    }
+                } else {
+                    LOG_I("  cycle %d, TEEC_TEMP_IN*  - zero pointer or size", i);
+                }
+                break;
+            }
+            case TEEC_MEMREF_WHOLE: {
+                LOG_I("  cycle %d, TEEC_MEMREF_WHOLE", i);
+                imp->memref.mapInfo.sVirtualLen = 0;
+                if (ext->memref.parent->size) {
+                    mcRet = mcMap(handle, ext->memref.parent->buffer, ext->memref.parent->size, &imp->memref.mapInfo);
+                    if (mcRet != MC_DRV_OK) {
+                        LOG_E("mcMap failed, mcRet=0x%08X", mcRet);
+                        *returnOrigin = TEEC_ORIGIN_COMMS;
+                        i = _TEEC_PARAMETER_NUMBER;
+                    }
+                }
+                break;
+            }
+            case TEEC_MEMREF_PARTIAL_INPUT:
+            case TEEC_MEMREF_PARTIAL_OUTPUT:
+            case TEEC_MEMREF_PARTIAL_INOUT: {
+                LOG_I("  cycle %d, TEEC_PARTIAL_IN*", i);
+                //Check data flow consistency
+                if ((((ext->memref.parent->flags & (TEEC_MEM_INPUT | TEEC_MEM_OUTPUT)) == TEEC_MEM_INPUT) &&
+                        (_TEEC_GET_PARAM_TYPE(operation->paramTypes, i) == TEEC_MEMREF_PARTIAL_OUTPUT)) ||
+                        (((ext->memref.parent->flags & (TEEC_MEM_INPUT | TEEC_MEM_OUTPUT)) == TEEC_MEM_OUTPUT) &&
+                         (_TEEC_GET_PARAM_TYPE(operation->paramTypes, i) == TEEC_MEMREF_PARTIAL_INPUT))) {
+                    LOG_E("PARTIAL data flow inconsistency");
+                    *returnOrigin = TEEC_ORIGIN_API;
+                    teecResult = TEEC_ERROR_BAD_PARAMETERS;
+                    i = _TEEC_PARAMETER_NUMBER;
+                    break;
+                }
+
+                if (ext->memref.offset + ext->memref.size > ext->memref.parent->size) {
+                    LOG_E("PARTIAL offset/size error");
+                    *returnOrigin = TEEC_ORIGIN_API;
+                    teecResult = TEEC_ERROR_BAD_PARAMETERS;
+                    i = _TEEC_PARAMETER_NUMBER;
+                    break;
+                }
+                imp->memref.mapInfo.sVirtualLen = 0;
+                if (ext->memref.size) {
+                    mcRet = mcMap(handle, (uint8_t *)ext->memref.parent->buffer + ext->memref.offset, ext->memref.size, &imp->memref.mapInfo);
+                    if (mcRet != MC_DRV_OK) {
+                        LOG_E("mcMap failed, mcRet=0x%08X", mcRet);
+                        *returnOrigin = TEEC_ORIGIN_COMMS;
+                        i = _TEEC_PARAMETER_NUMBER;
+                    }
+                }
+                break;
+            }
+            default:
+                LOG_E("cycle %d, default", i);
+                *returnOrigin = TEEC_ORIGIN_API;
+                teecResult = TEEC_ERROR_BAD_PARAMETERS;
+                i = _TEEC_PARAMETER_NUMBER;
+                break;
+            }
+        }
+
+        if (tci->operation.isCancelled) {
+            LOG_E("the operation has been cancelled in COMMS");
+            *returnOrigin = TEEC_ORIGIN_COMMS;
+            teecResult = TEEC_ERROR_CANCEL;
+        }
+
+        if ((mcRet != MC_DRV_OK) || (teecResult != TEEC_SUCCESS)) {
+            uint32_t retOrigIgnored;
+            _TEEC_UnwindOperation(tci, handle, operation, false, &retOrigIgnored);
+            //Zeroing out tci->operation
+            memset(&tci->operation, 0, sizeof(TEEC_Operation));
+            if (teecResult != TEEC_SUCCESS) return teecResult;
+            return TEEC_ERROR_GENERIC;
+        }
+    }
+
+    //Copy version indicator field
+    strcpy(tci->header, "TCIGP000");
+
+    // Fill in invalid values for secure world to overwrite
+    tci->returnStatus = 0;
+    tci->returnStatus = TEE_ERROR_BAD_STATE;
+
+    // Signal completion of request writing
+    tci->ready = 1;
+
+    return teecResult;
+}
+
+//------------------------------------------------------------------------------
+static TEEC_Result _TEEC_UnwindOperation(
+    _TEEC_TCI           *tci,
+    mcSessionHandle_t   *handle,
+    TEEC_Operation      *operation,
+    bool                copyValues,
+    uint32_t            *returnOrigin)
+{
+    uint32_t                    i;
+    _TEEC_ParameterInternal     *imp;
+    TEEC_Parameter              *ext;
+    //mcResult_t                  mcRet = MC_DRV_OK;
+    //bool                        doUnmap = false;
+    uint8_t                     *buffer;
+
+    //operation can be NULL
+    if (operation == NULL) return  TEEC_SUCCESS;
+
+    LOG_I(" %s()", __func__);
+
+    operation->started = 2;
+
+    // Some sanity checks
+    if (tci->returnOrigin == 0 ||
+            ((tci->returnOrigin != TEEC_ORIGIN_TRUSTED_APP) && (tci->returnStatus != TEEC_SUCCESS))) {
+        *returnOrigin = TEEC_ORIGIN_COMMS;
+        return TEEC_ERROR_COMMUNICATION;
+    }
+    *returnOrigin = tci->returnOrigin;
+
+    //Clear sVirtualLen to unMap further
+    for (i = 0; i < _TEEC_PARAMETER_NUMBER; i++) {
+        imp = &tci->operation.params[i];
+        ext = &operation->params[i];
+        buffer = NULL;
+
+        switch (_TEEC_GET_PARAM_TYPE(operation->paramTypes, i)) {
+        case TEEC_VALUE_INPUT:
+            LOG_I("  cycle %d, TEEC_VALUE_INPUT", i);
+            break;
+        case TEEC_NONE:
+            LOG_I("  cycle %d, TEEC_NONE", i);
+            break;
+        case TEEC_VALUE_OUTPUT:
+        case TEEC_VALUE_INOUT: {
+            LOG_I("  cycle %d, TEEC_VALUE_OUT*", i);
+            if (copyValues) {
+                ext->value.a = imp->value.a;
+                ext->value.b = imp->value.b;
+            }
+            break;
+        }
+        case TEEC_MEMREF_TEMP_OUTPUT:
+        case TEEC_MEMREF_TEMP_INPUT:
+        case TEEC_MEMREF_TEMP_INOUT: {
+            LOG_I("  cycle %d, TEEC_TEMP*", i);
+            if ((copyValues) && (_TEEC_GET_PARAM_TYPE(operation->paramTypes, i) != TEEC_MEMREF_TEMP_INPUT)) {
+                ext->tmpref.size = imp->memref.outputSize;
+            }
+            //doUnmap = true;
+            buffer = (uint8_t *)ext->tmpref.buffer;
+            break;
+        }
+        case TEEC_MEMREF_WHOLE: {
+            LOG_I("  cycle %d, TEEC_MEMREF_WHOLE", i);
+            if (copyValues) ext->memref.size = imp->memref.outputSize;
+            //doUnmap = true;
+            buffer = (uint8_t *)ext->memref.parent->buffer;
+            break;
+        }
+
+        case TEEC_MEMREF_PARTIAL_OUTPUT:
+        case TEEC_MEMREF_PARTIAL_INOUT:
+        case TEEC_MEMREF_PARTIAL_INPUT: {
+            LOG_I("  cycle %d, TEEC_MEMREF_PARTIAL*", i);
+            if ((copyValues) && (_TEEC_GET_PARAM_TYPE(operation->paramTypes, i) != TEEC_MEMREF_PARTIAL_INPUT)) {
+                ext->memref.size = imp->memref.outputSize;
+            }
+            buffer = (uint8_t *)ext->memref.parent->buffer + ext->memref.offset;
+            break;
+        }
+        default:
+            LOG_E("cycle %d, bad parameter", i);
+            break;
+        }
+
+        if ((buffer != NULL) && (imp->memref.mapInfo.sVirtualLen != 0)) {
+            // This function assumes that we cannot handle error of mcUnmap
+            mcUnmap(handle, buffer, &imp->memref.mapInfo);
+        }
+    }
+
+    return tci->returnStatus;
+}
+
+//------------------------------------------------------------------------------
+//TEEC_InitializeContext: TEEC_SUCCESS, Another error code from Table 4-2.
+//MC_DRV_OK, MC_DRV_ERR_INVALID_OPERATION, MC_DRV_ERR_DAEMON_UNREACHABLE, MC_DRV_ERR_UNKNOWN_DEVICE, MC_DRV_ERR_INVALID_DEVICE_FILE
+TEEC_Result TEEC_InitializeContext(
+    const char   *name,
+    TEEC_Context *context)
+{
+    LOG_I("== %s() ==============", __func__);
+
+    if (context == NULL) return TEEC_ERROR_BAD_PARAMETERS;
+    context->imp.reserved = MC_DEVICE_ID_DEFAULT;
+
+    switch (mcOpenDevice(MC_DEVICE_ID_DEFAULT)) {
+    case MC_DRV_OK:
+        return TEEC_SUCCESS;
+    case MC_DRV_ERR_INVALID_OPERATION:
+        return TEEC_ERROR_BAD_STATE;
+    case MC_DRV_ERR_DAEMON_UNREACHABLE:
+        return TEEC_ERROR_COMMUNICATION;
+    case MC_DRV_ERR_UNKNOWN_DEVICE:
+        return TEEC_ERROR_BAD_PARAMETERS;
+    case MC_DRV_ERR_INVALID_DEVICE_FILE:
+        return TEEC_ERROR_COMMUNICATION;
+    }
+
+    return TEEC_ERROR_GENERIC;
+}
+
+//------------------------------------------------------------------------------
+//mcCloseDevice: MC_DRV_OK, MC_DRV_ERR_UNKNOWN_DEVICE, MC_DRV_ERR_SESSION_PENDING, MC_DRV_ERR_DAEMON_UNREACHABLE
+//TEEC_FinalizeContext: void
+
+//TODO: The implementation of this function MUST NOT be able to fail: after this function returns the Client
+//Application must be able to consider that the Context has been closed.
+
+void TEEC_FinalizeContext(TEEC_Context *context)
+{
+    mcResult_t      mcRet;
+
+    LOG_I("== %s() ==============", __func__);
+
+    //The parameter context MUST point to an initialized TEE Context.
+    //Just realized: The function implementation MUST do nothing if context is NULL.
+    if (context == NULL) {
+        LOG_E("context is NULL");
+        return;
+    }
+
+    //The implementation of this function MUST NOT be able to fail: after this function returns the Client
+    //Application must be able to consider that the Context has been closed.
+    mcRet = mcCloseDevice(context->imp.reserved);
+    if (mcRet != MC_DRV_OK) {
+        LOG_E("mcCloseDevice failed (%08x)", mcRet);
+        /* continue even in case of error */;
+    }
+}
+
+//------------------------------------------------------------------------------
+static TEEC_Result _TEEC_CallTA(
+    TEEC_Session    *session,
+    TEEC_Operation  *operation,
+    uint32_t        *returnOrigin)
+{
+    mcResult_t      mcRet;
+    TEEC_Result     teecRes;
+    TEEC_Result     teecError = TEEC_SUCCESS;
+
+    LOG_I(" %s()", __func__);
+
+    // Phase 1: start the operation and wait for the result
+    teecRes = _TEEC_SetupOperation((_TEEC_TCI *)session->imp.tci, &session->imp.handle, operation, returnOrigin);
+    if (teecRes != TEEC_SUCCESS ) {
+        LOG_E("_TEEC_SetupOperation failed (%08x)", teecRes);
+        return teecRes;
+    }
+
+    // Signal the Trusted App
+    mcRet = mcNotify(&session->imp.handle);
+    if (MC_DRV_OK != mcRet) {
+        LOG_E("Notify failed (%08x)", mcRet);
+        teecError = TEEC_ERROR_COMMUNICATION;
+        goto end;
+    }
+
+    // -------------------------------------------------------------
+    // Wait for the Trusted App response
+    mcRet = mcWaitNotification(&session->imp.handle, MC_INFINITE_TIMEOUT);
+    if (mcRet != MC_DRV_OK) {
+        LOG_E("mcWaitNotification failed (%08x)", mcRet);
+        teecError = TEEC_ERROR_COMMUNICATION;
+        if (mcRet == MC_DRV_INFO_NOTIFICATION) {
+            int32_t lastErr;
+            mcGetSessionErrorCode(&session->imp.handle, &lastErr);
+            LOG_E("mcGetSessionErrorCode returned %d", lastErr);
+            if (lastErr == TA_EXIT_CODE_FINISHED) {
+                // We may get here if the TA_OpenSessionEntryPoint returns an error and TA goes fast through DestroyEntryPoint and exits the TA.
+                teecError = TEEC_SUCCESS;
+            } else  if (lastErr != ERR_INVALID_SID && lastErr != ERR_SID_NOT_ACTIVE) {
+                LOG_E("Target is DEAD");
+
+                *returnOrigin = TEEC_ORIGIN_TEE;
+                teecError = TEE_ERROR_TARGET_DEAD;
+            }
+        }
+    }
+    // Phase 2: Return values and cleanup
+end:
+    // unmap memory and copy values if no error
+    teecRes = _TEEC_UnwindOperation((_TEEC_TCI *)session->imp.tci, &session->imp.handle, operation,
+                                    (teecError == TEEC_SUCCESS), returnOrigin);
+    if (teecRes != TEEC_SUCCESS ) {
+        LOG_E("_TEEC_UnwindOperation (%08x)", teecRes);
+        /* continue even in case of error */;
+    }
+
+    // Cleanup
+    if (teecError != TEEC_SUCCESS) {
+        // Previous interactions failed, either TA is dead or communication error
+        mcRet = mcCloseSession(&session->imp.handle);
+        if (mcRet != MC_DRV_OK) {
+            LOG_E("mcCloseSession failed (%08x)", mcRet);
+            /* continue even in case of error */;
+        }
+        session->imp.active = false;
+        if (teecError == TEEC_ERROR_COMMUNICATION) {
+            *returnOrigin = TEEC_ORIGIN_COMMS;
+        }
+        munmap(session->imp.tci, sysconf(_SC_PAGESIZE));
+        session->imp.tci = NULL;
+    }
+    return teecError;
+}
+
+//------------------------------------------------------------------------------
+__MC_CLIENT_LIB_API mcResult_t mcOpenGPTA(
+    mcSessionHandle_t  *session,
+    const mcUuid_t     *uuid,
+    uint8_t            *tci,
+    uint32_t           len
+);
+//------------------------------------------------------------------------------
+//TEEC_OpenSession: if the returnOrigin is different from TEEC_ORIGIN_TRUSTED_APP, an error code from Table 4-2
+// If the returnOrigin is equal to TEEC_ORIGIN_TRUSTED_APP, a return code defined by the
+//protocol between the Client Application and the Trusted Application.
+TEEC_Result TEEC_OpenSession (
+    TEEC_Context    *context,
+    TEEC_Session    *session,
+    const TEEC_UUID *destination,
+    uint32_t        connectionMethod,
+    void            *connectionData,
+    TEEC_Operation  *operation,
+    uint32_t        *returnOrigin)
+{
+    mcResult_t      mcRet;
+    TEEC_Result     teecRes;
+    uint32_t        returnOrigin_local;
+    mcUuid_t        tauuid;
+
+    LOG_I("== %s() ==============", __func__);
+    // -------------------------------------------------------------
+    //The parameter context MUST point to an initialized TEE Context.
+    if (context == NULL) {
+        LOG_E("context is NULL");
+        if (returnOrigin != NULL) *returnOrigin = TEEC_ORIGIN_API;
+        return TEEC_ERROR_BAD_PARAMETERS;
+    }
+
+    if (session == NULL) {
+        LOG_E("session is NULL");
+        if (returnOrigin != NULL) *returnOrigin = TEEC_ORIGIN_API;
+        return TEEC_ERROR_BAD_PARAMETERS;
+    }
+
+    if (connectionMethod != TEEC_LOGIN_PUBLIC) {
+        //JACKET: Client authorization is not supported. The connectionMethod parameter
+        //must be TEEC LOGIN PUBLIC, otherwise return TEEC ERROR NOT IMPLEMENTED.
+        LOG_E("connectionMethod != TEEC_LOGIN_PUBLIC");
+        if (returnOrigin != NULL) *returnOrigin = TEEC_ORIGIN_API;
+        return TEEC_ERROR_NOT_IMPLEMENTED;
+    }
+
+    // -------------------------------------------------------------
+    session->imp.active = false;
+
+    _libUuidToArray((TEEC_UUID *)destination, (uint8_t *)tauuid.value);
+
+    if (operation) operation->imp.session = &session->imp;
+
+    //Allocate a 4kB page with mmap, zero it out, and set session->imp.tci to its address.
+    session->imp.tci = NULL;
+    void *bulkBuf = (void *)mmap(0, sysconf(_SC_PAGESIZE), PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+    if (bulkBuf == MAP_FAILED) {
+        LOG_E("mmap filed on tci buffer allocation");
+        if (returnOrigin != NULL) *returnOrigin = TEEC_ORIGIN_API;
+        return TEEC_ERROR_OUT_OF_MEMORY;
+    }
+
+    session->imp.tci = bulkBuf;
+    memset(session->imp.tci, 0, sysconf(_SC_PAGESIZE));
+
+    pthread_mutex_init(&session->imp.mutex_tci, NULL);
+    pthread_mutex_lock(&session->imp.mutex_tci);
+
+    //Fill the TCI buffer session.tci with the destination UUID.
+    memcpy(&(((_TEEC_TCI *)session->imp.tci)->destination), destination, sizeof(TEEC_UUID));
+    // -------------------------------------------------------------
+    memset(&session->imp.handle, 0, sizeof(mcSessionHandle_t));
+    session->imp.handle.deviceId = context->imp.reserved ; // The device ID (default device is used)
+    mcRet = mcOpenGPTA(
+                &session->imp.handle,
+                &tauuid,
+                (uint8_t *)session->imp.tci,
+                sizeof(_TEEC_TCI));
+    if (mcRet != MC_DRV_OK) {
+        LOG_E("mcOpenTrustlet failed (%08x)", mcRet);
+        if (returnOrigin != NULL) *returnOrigin = TEEC_ORIGIN_COMMS;
+        if (mcRet == MC_DRV_ERR_TRUSTED_APPLICATION_NOT_FOUND) {
+            teecRes = TEEC_ERROR_ITEM_NOT_FOUND;
+        } else {
+            //TODO: Improve the error codes
+            teecRes = TEEC_ERROR_GENERIC;
+        }
+        goto error;
+    }
+
+    session->imp.active = true;
+
+    // Let TA go through entry points
+    LOG_I(" let TA go through entry points");
+    ((_TEEC_TCI *)session->imp.tci)->operation.type = _TA_OPERATION_OPEN_SESSION;
+    teecRes = _TEEC_CallTA(session, operation, &returnOrigin_local);
+
+    // Check for error on communication level
+    if (teecRes != TEEC_SUCCESS ) {
+        LOG_E("_TEEC_CallTA failed(%08x)", teecRes);
+        // Nothing to do here because _TEEC_CallTA closes broken sessions
+        if (returnOrigin != NULL) *returnOrigin = returnOrigin_local;
+        goto error;
+    }
+    LOG_I(" no errors in com layer");
+
+    // Check for error from TA
+    if (returnOrigin != NULL) *returnOrigin = ((_TEEC_TCI *)session->imp.tci)->returnOrigin;
+    teecRes = ((_TEEC_TCI *)session->imp.tci)->returnStatus;
+    if (teecRes != TEEC_SUCCESS ) {
+        LOG_E("TA OpenSession EP failed(%08x)", teecRes);
+        goto error;
+    }
+
+    LOG_I(" %s() = TEEC_SUCCESS ", __func__);
+    pthread_mutex_unlock(&session->imp.mutex_tci);
+
+    if (returnOrigin != NULL) *returnOrigin = TEEC_ORIGIN_TRUSTED_APP;
+    return TEEC_SUCCESS;
+
+    // -------------------------------------------------------------
+error:
+    if (session->imp.active) {
+        // After notifying us, TA went to Destry EP, so close session now
+        mcRet = mcCloseSession(&session->imp.handle);
+        if (mcRet != MC_DRV_OK) {
+            LOG_E("mcCloseSession failed (%08x)", mcRet);
+            /* continue even in case of error */;
+        }
+        session->imp.active = false;
+    }
+
+    pthread_mutex_unlock(&session->imp.mutex_tci);
+    pthread_mutex_destroy(&session->imp.mutex_tci);
+    if (session->imp.tci) {
+        munmap(session->imp.tci, sysconf(_SC_PAGESIZE));
+        session->imp.tci = NULL;
+    }
+
+    LOG_I(" %s() = 0x%x", __func__, teecRes);
+    return teecRes;
+}
+
+//------------------------------------------------------------------------------
+TEEC_Result TEEC_InvokeCommand(
+    TEEC_Session     *session,
+    uint32_t         commandID,
+    TEEC_Operation   *operation,
+    uint32_t         *returnOrigin)
+{
+    TEEC_Result teecRes;
+    uint32_t returnOrigin_local;
+
+    LOG_I("== %s() ==============", __func__);
+
+    // -------------------------------------------------------------
+    if (session == NULL) {
+        LOG_E("session is NULL");
+        if (returnOrigin != NULL) *returnOrigin = TEEC_ORIGIN_API;
+        return TEEC_ERROR_BAD_PARAMETERS;
+    }
+
+    if (!session->imp.active) {
+        LOG_E("session is inactive");
+        if (returnOrigin != NULL) *returnOrigin = TEEC_ORIGIN_API;
+        return TEEC_ERROR_BAD_STATE;
+    }
+    // -------------------------------------------------------------
+    if (operation) operation->imp.session = &session->imp;
+
+    pthread_mutex_lock(&session->imp.mutex_tci);
+
+    // Call TA
+    ((_TEEC_TCI *)session->imp.tci)->operation.commandId = commandID;
+    ((_TEEC_TCI *)session->imp.tci)->operation.type = _TA_OPERATION_INVOKE_COMMAND;
+    teecRes = _TEEC_CallTA(session, operation, &returnOrigin_local);
+    if (teecRes != TEEC_SUCCESS ) {
+        LOG_E("_TEEC_CallTA failed(%08x)", teecRes);
+        if (returnOrigin != NULL) *returnOrigin = returnOrigin_local;
+    } else {
+        if (returnOrigin != NULL) *returnOrigin = ((_TEEC_TCI *)session->imp.tci)->returnOrigin;
+        teecRes                                 = ((_TEEC_TCI *)session->imp.tci)->returnStatus;
+    }
+
+    pthread_mutex_unlock(&session->imp.mutex_tci);
+    LOG_I(" %s() = 0x%x", __func__, teecRes);
+    return teecRes;
+}
+
+//------------------------------------------------------------------------------
+void TEEC_CloseSession(TEEC_Session *session)
+{
+    mcResult_t      mcRet;
+    TEEC_Result     teecRes = TEEC_SUCCESS;
+    uint32_t        returnOrigin;
+
+    LOG_I("== %s() ==============", __func__);
+
+    // -------------------------------------------------------------
+    //The Implementation MUST do nothing if the session parameter is NULL.
+    if (session == NULL) {
+        LOG_E("session is NULL");
+        return;
+    }
+
+    // -------------------------------------------------------------
+    if (session->imp.active) {
+        // Let TA go through CloseSession and Destroy entry points
+        LOG_I(" let TA go through close entry points");
+        pthread_mutex_lock(&session->imp.mutex_tci);
+        ((_TEEC_TCI *)session->imp.tci)->operation.type = _TA_OPERATION_CLOSE_SESSION;
+        teecRes = _TEEC_CallTA(session, NULL, &returnOrigin);
+        if (teecRes != TEEC_SUCCESS ) {
+            /* continue even in case of error */;
+            LOG_E("_TEEC_CallTA failed(%08x)", teecRes);
+        }
+
+        if (session->imp.active) {
+            // Close Session
+            mcRet = mcCloseSession(&session->imp.handle);
+            if (mcRet != MC_DRV_OK) {
+                LOG_E("mcCloseSession failed (%08x)", mcRet);
+                /* ignore error and also there shouldn't be one */
+            }
+        }
+        pthread_mutex_unlock(&session->imp.mutex_tci);
+    }
+
+    pthread_mutex_destroy(&session->imp.mutex_tci);
+    if (session->imp.tci) {
+        munmap(session->imp.tci, sysconf(_SC_PAGESIZE));
+        session->imp.tci = NULL;
+    }
+    session->imp.active = false;
+
+    LOG_I(" %s() = 0x%x", __func__, teecRes);
+}
+
+//------------------------------------------------------------------------------
+TEEC_Result TEEC_RegisterSharedMemory(
+    TEEC_Context      *context,
+    TEEC_SharedMemory *sharedMem)
+{
+    LOG_I("== %s() ==============", __func__);
+
+    //The parameter context MUST point to an initialized TEE Context.
+    if (context == NULL) {
+        LOG_E("context is NULL");
+        return TEEC_ERROR_BAD_PARAMETERS;
+    }
+    //The parameter sharedMem MUST point to the Shared Memory structure defining
+    //the memory region to register.
+    if (sharedMem == NULL) {
+        LOG_E("sharedMem is NULL");
+        return TEEC_ERROR_BAD_PARAMETERS;
+    }
+    //The buffer field MUST point to the memory region to be shared, and MUST not be NULL.
+    if (sharedMem->buffer == NULL) {
+        LOG_E("sharedMem->buffer is NULL");
+        return TEEC_ERROR_BAD_PARAMETERS;
+    }
+
+    sharedMem->imp.implementation_allocated = false;
+    return TEEC_SUCCESS;
+}
+
+//------------------------------------------------------------------------------
+TEEC_Result TEEC_AllocateSharedMemory(
+    TEEC_Context      *context,
+    TEEC_SharedMemory *sharedMem)
+{
+    //No connection to "context"?
+    LOG_I("== %s() ==============", __func__);
+
+    //The parameter context MUST point to an initialized TEE Context.
+    if (context == NULL) {
+        LOG_E("context is NULL");
+        return TEEC_ERROR_BAD_PARAMETERS;
+    }
+    //The parameter sharedMem MUST point to the Shared Memory structure defining
+    //the memory region to register.
+    if (sharedMem == NULL) {
+        LOG_E("sharedMem is NULL");
+        return TEEC_ERROR_BAD_PARAMETERS;
+    }
+
+    sharedMem->buffer = malloc(sharedMem->size);
+    if (sharedMem->buffer == NULL) {
+        LOG_E("malloc failed");
+        return TEEC_ERROR_OUT_OF_MEMORY;
+    }
+    sharedMem->imp.implementation_allocated = true;
+
+    return TEEC_SUCCESS;
+}
+
+//------------------------------------------------------------------------------
+void TEEC_ReleaseSharedMemory (
+    TEEC_SharedMemory *sharedMem)
+{
+    //No connection to "context"?
+    LOG_I("== %s() ==============", __func__);
+
+    //The Implementation MUST do nothing if the sharedMem parameter is NULL
+    if (sharedMem == NULL) {
+        LOG_E("sharedMem is NULL");
+        return;
+    }
+
+    //For a memory buffer allocated using TEEC_AllocateSharedMemory the Implementation
+    //MUST free the underlying memory
+    if (sharedMem->imp.implementation_allocated) {
+        if (sharedMem->buffer) {
+            free(sharedMem->buffer);
+            sharedMem->buffer = NULL;
+            sharedMem->size = 0;
+        }
+    }
+
+    //TODO: Attempting to release Shared Memory which is used by a pending operation.
+
+}
+
+//------------------------------------------------------------------------------
+void TEEC_RequestCancellation(
+    TEEC_Operation *operation)
+{
+    LOG_I("== %s() ==============", __func__);
+
+    while (operation->started == 0);
+
+    LOG_I("while(operation->started ==0) passed");
+
+    if (operation->started > 1) {
+        LOG_I("The operation has finished");
+        return;
+    }
+
+    TEEC_Session_IMP *session = operation->imp.session;
+    operation->started = 2;
+
+    if (!session->active)  {
+        LOG_I("Corresponding session is not active");
+        return;
+    }
+    ((_TEEC_TCI *)session->tci)->operation.isCancelled = true;
+
+    // Step 4.3: signal the Trustlet
+    mcResult_t mcRet = mcNotify(&session->handle);
+    if (MC_DRV_OK != mcRet) {
+        LOG_E("Notify failed (%08x)", mcRet);
+    }
+}
+
+//------------------------------------------------------------------------------
diff --git a/daemon/ClientLib/Session.cpp b/MobiCoreDriverLib/ClientLib/Session.cpp
old mode 100644
new mode 100755
similarity index 77%
rename from daemon/ClientLib/Session.cpp
rename to MobiCoreDriverLib/ClientLib/Session.cpp
index 9f68984..259dd1b
--- a/daemon/ClientLib/Session.cpp
+++ b/MobiCoreDriverLib/ClientLib/Session.cpp
@@ -1,31 +1,34 @@
 /** @addtogroup MCD_IMPL_LIB
  * @{
  * @file
- * <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
+ * Copyright (c) 2013 TRUSTONIC LIMITED
+ * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- *    products derived from this software without specific prior
- *    written permission.
  *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 3. Neither the name of the TRUSTONIC LIMITED nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 #include <stdint.h>
 #include <vector>
@@ -64,8 +67,7 @@
             ++iterator) {
         pBlkBufDescr = *iterator;
 
-        LOG_I("removeBulkBuf - Physical Address of L2 Table = 0x%X, handle= %d",
-              (unsigned int)pBlkBufDescr->physAddrWsmL2,
+        LOG_I("removeBulkBuf - handle= %d",
               pBlkBufDescr->handle);
 
         // ignore any error, as we cannot do anything in this case.
@@ -106,7 +108,7 @@
 //------------------------------------------------------------------------------
 mcResult_t Session::addBulkBuf(addr_t buf, uint32_t len, BulkBufferDescriptor **blkBuf)
 {
-    addr_t pPhysWsmL2;
+    uint64_t pPhysWsmL2;
     uint32_t handle;
 
     assert(blkBuf != NULL);
@@ -133,7 +135,7 @@
     LOG_V(" addBulkBuf - Handle of L2 Table = %u", handle);
 
     // Create new descriptor - secure virtual virtual set to 0, unknown!
-    *blkBuf = new BulkBufferDescriptor(buf, 0x0, len, handle, pPhysWsmL2);
+    *blkBuf = new BulkBufferDescriptor(buf, 0x0, len, handle);
 
     // Add to vector of descriptors
     bulkBufferDescriptors.push_back(*blkBuf);
@@ -144,13 +146,13 @@
 //------------------------------------------------------------------------------
 void Session::addBulkBuf(BulkBufferDescriptor *blkBuf)
 {
-    if(blkBuf)
+    if (blkBuf)
         // Add to vector of descriptors
         bulkBufferDescriptors.push_back(blkBuf);
 }
 
 //------------------------------------------------------------------------------
-uint32_t Session::getBufHandle(addr_t sVirtAddr)
+uint32_t Session::getBufHandle(addr_t sVirtAddr, uint32_t sVirtualLen)
 {
     LOG_V("getBufHandle(): Virtual Address = 0x%X", (unsigned int) virtAddr);
 
@@ -158,7 +160,7 @@
     for ( bulkBufferDescrIterator_t iterator = bulkBufferDescriptors.begin();
             iterator != bulkBufferDescriptors.end();
             ++iterator ) {
-        if ((*iterator)->sVirtualAddr == sVirtAddr) {
+        if (((*iterator)->sVirtualAddr == sVirtAddr) && ((*iterator)->len == sVirtualLen)) {
             return (*iterator)->handle;
         }
     }
diff --git a/daemon/ClientLib/Session.h b/MobiCoreDriverLib/ClientLib/Session.h
old mode 100644
new mode 100755
similarity index 77%
rename from daemon/ClientLib/Session.h
rename to MobiCoreDriverLib/ClientLib/Session.h
index f24d6ce..5fc1e94
--- a/daemon/ClientLib/Session.h
+++ b/MobiCoreDriverLib/ClientLib/Session.h
@@ -1,31 +1,34 @@
 /** @addtogroup MCD_IMPL_LIB
  * @{
  * @file
- * <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
+ * Copyright (c) 2013 TRUSTONIC LIMITED
+ * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- *    products derived from this software without specific prior
- *    written permission.
  *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 3. Neither the name of the TRUSTONIC LIMITED nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 #ifndef SESSION_H_
 #define SESSION_H_
@@ -46,20 +49,17 @@
     addr_t    sVirtualAddr; /**< The secure virtual address of the Bulk buffer*/
     uint32_t  len; /**< Length of the Bulk buffer*/
     uint32_t  handle;
-    addr_t    physAddrWsmL2; /**< The physical address of the L2 table of the Bulk buffer*/
 
     BulkBufferDescriptor(
         addr_t    virtAddr,
         addr_t    sVirtAddr,
         uint32_t  len,
-        uint32_t  handle,
-        addr_t    physAddrWsmL2
+        uint32_t  handle
     ) :
         virtAddr(virtAddr),
         sVirtualAddr(sVirtAddr),
         len(len),
-        handle(handle),
-        physAddrWsmL2(physAddrWsmL2)
+        handle(handle)
     {};
 
 };
@@ -146,7 +146,7 @@
      *
      * @return the Handle or 0 for failure
      */
-    uint32_t getBufHandle(addr_t sVirtualAddr);
+    uint32_t getBufHandle(addr_t sVirtAddr, uint32_t sVirtualLen);
 
     /**
      * Set additional error information of the last error that occured.
diff --git a/MobiCoreDriverLib/ClientLib/public/GP/tee_client_api.h b/MobiCoreDriverLib/ClientLib/public/GP/tee_client_api.h
new file mode 100755
index 0000000..c6f2090
--- /dev/null
+++ b/MobiCoreDriverLib/ClientLib/public/GP/tee_client_api.h
@@ -0,0 +1,190 @@
+/*
+ * Copyright (c) 2013 TRUSTONIC LIMITED
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the TRUSTONIC LIMITED nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This header file corresponds to V1.0 of the GlobalPlatform
+ * TEE Client API Specification
+ */
+#ifndef   __TEE_CLIENT_API_H__
+#define   __TEE_CLIENT_API_H__
+
+#include "tee_type.h"
+#include "tee_error.h"
+
+#if TBASE_API_LEVEL >= 3
+
+#if (!defined(TEEC_EXPORT)) && __cplusplus
+#define TEEC_EXPORT       extern "C"
+#else
+#define TEEC_EXPORT
+#endif // __cplusplus
+
+
+
+/* The header tee_client_api_imp.h must define implementation-dependent
+   types, constants and macros.
+
+   The implementation-dependent types are:
+     - TEEC_Context_IMP
+     - TEEC_Session_IMP
+     - TEEC_SharedMemory_IMP
+     - TEEC_Operation_IMP
+
+   The implementation-dependent constants are:
+     - TEEC_CONFIG_SHAREDMEM_MAX_SIZE
+   The implementation-dependent macros are:
+     - TEEC_PARAM_TYPES
+*/
+
+typedef struct {
+    uint32_t   a;
+    uint32_t   b;
+} TEEC_Value;
+
+
+#include "tee_client_api_imp.h"
+
+/* Type definitions */
+typedef struct TEEC_Context {
+    TEEC_Context_IMP imp;
+} TEEC_Context;
+
+typedef struct TEEC_Session {
+    TEEC_Session_IMP imp;
+} TEEC_Session;
+
+typedef struct TEEC_SharedMemory {
+    void                    *buffer;
+    size_t                  size;
+    uint32_t                flags;
+    TEEC_SharedMemory_IMP   imp;
+} TEEC_SharedMemory;
+
+typedef struct {
+    void    *buffer;
+    size_t  size;
+} TEEC_TempMemoryReference;
+
+typedef struct {
+    TEEC_SharedMemory *parent;
+    size_t  size;
+    size_t  offset;
+} TEEC_RegisteredMemoryReference;
+
+
+
+typedef union {
+    TEEC_TempMemoryReference        tmpref;
+    TEEC_RegisteredMemoryReference  memref;
+    TEEC_Value                      value;
+} TEEC_Parameter;
+
+typedef struct TEEC_Operation {
+    volatile uint32_t    started;
+    uint32_t             paramTypes;
+    TEEC_Parameter       params[4];
+    TEEC_Operation_IMP   imp;
+} TEEC_Operation;
+
+
+#define TEEC_ORIGIN_API                      0x00000001
+#define TEEC_ORIGIN_COMMS                    0x00000002
+#define TEEC_ORIGIN_TEE                      0x00000003
+#define TEEC_ORIGIN_TRUSTED_APP              0x00000004
+
+#define TEEC_MEM_INPUT                       0x00000001
+#define TEEC_MEM_OUTPUT                      0x00000002
+
+#define TEEC_NONE                     0x0
+#define TEEC_VALUE_INPUT              0x1
+#define TEEC_VALUE_OUTPUT             0x2
+#define TEEC_VALUE_INOUT              0x3
+#define TEEC_MEMREF_TEMP_INPUT        0x5
+#define TEEC_MEMREF_TEMP_OUTPUT       0x6
+#define TEEC_MEMREF_TEMP_INOUT        0x7
+#define TEEC_MEMREF_WHOLE             0xC
+#define TEEC_MEMREF_PARTIAL_INPUT     0xD
+#define TEEC_MEMREF_PARTIAL_OUTPUT    0xE
+#define TEEC_MEMREF_PARTIAL_INOUT     0xF
+
+#define TEEC_LOGIN_PUBLIC                    0x00000000
+#define TEEC_LOGIN_USER                      0x00000001
+#define TEEC_LOGIN_GROUP                     0x00000002
+#define TEEC_LOGIN_APPLICATION               0x00000004
+#define TEEC_LOGIN_USER_APPLICATION          0x00000005
+#define TEEC_LOGIN_GROUP_APPLICATION         0x00000006
+
+#pragma GCC visibility push(default)
+
+TEEC_EXPORT TEEC_Result TEEC_InitializeContext(
+    const char   *name,
+    TEEC_Context *context);
+
+TEEC_EXPORT void  TEEC_FinalizeContext(
+    TEEC_Context *context);
+
+TEEC_EXPORT TEEC_Result  TEEC_RegisterSharedMemory(
+    TEEC_Context      *context,
+    TEEC_SharedMemory *sharedMem);
+
+TEEC_EXPORT TEEC_Result  TEEC_AllocateSharedMemory(
+    TEEC_Context      *context,
+    TEEC_SharedMemory *sharedMem);
+
+TEEC_EXPORT void  TEEC_ReleaseSharedMemory (
+    TEEC_SharedMemory *sharedMem);
+
+TEEC_EXPORT TEEC_Result  TEEC_OpenSession (
+    TEEC_Context    *context,
+    TEEC_Session    *session,
+    const TEEC_UUID *destination,
+    uint32_t        connectionMethod,
+    void            *connectionData,
+    TEEC_Operation  *operation,
+    uint32_t        *returnOrigin);
+
+TEEC_EXPORT void  TEEC_CloseSession (
+    TEEC_Session *session);
+
+TEEC_EXPORT TEEC_Result TEEC_InvokeCommand(
+    TEEC_Session     *session,
+    uint32_t         commandID,
+    TEEC_Operation   *operation,
+    uint32_t         *returnOrigin);
+
+TEEC_EXPORT void  TEEC_RequestCancellation(
+    TEEC_Operation *operation);
+
+#pragma GCC visibility pop
+
+#endif /* TBASE_API_LEVEL */
+
+#endif /* __TEE_CLIENT_API_H__ */
diff --git a/MobiCoreDriverLib/ClientLib/public/GP/tee_client_api_imp.h b/MobiCoreDriverLib/ClientLib/public/GP/tee_client_api_imp.h
new file mode 100755
index 0000000..75c01fe
--- /dev/null
+++ b/MobiCoreDriverLib/ClientLib/public/GP/tee_client_api_imp.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2013 TRUSTONIC LIMITED
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the TRUSTONIC LIMITED nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This header file defines the implementation-dependent types,
+ * constants and macros for all the Trusted Foundations implementations
+ * of the TEE Client API
+ */
+#ifndef   __TEE_CLIENT_API_IMP_H__
+#define   __TEE_CLIENT_API_IMP_H__
+
+#if TBASE_API_LEVEL >= 3
+
+#include <pthread.h>
+
+#include "tee_type.h"
+#include "tee_error.h"
+#include "MobiCoreDriverApi.h"
+
+
+typedef struct {
+    uint32_t    reserved;
+}
+TEEC_Context_IMP;
+
+
+typedef struct {
+    mcSessionHandle_t   handle;
+    void                *tci;
+    bool                active;
+    pthread_mutex_t     mutex_tci;  //mutex to serialize CA requests
+}
+TEEC_Session_IMP;
+
+typedef struct {
+    bool    implementation_allocated;
+}
+TEEC_SharedMemory_IMP;
+
+typedef struct {
+    TEEC_Session_IMP    *session;
+}
+TEEC_Operation_IMP;
+
+/* There is no natural, compile-time limit on the shared memory, but a specific
+   implementation may introduce a limit (in particular on TrustZone) */
+#define TEEC_CONFIG_SHAREDMEM_MAX_SIZE ((size_t)0xFFFFFFFF)
+
+#define TEEC_PARAM_TYPES(entry0Type, entry1Type, entry2Type, entry3Type) \
+   ((entry0Type) | ((entry1Type) << 4) | ((entry2Type) << 8) | ((entry3Type) << 12))
+
+#endif /* TBASE_API_LEVEL */
+
+#endif /* __TEE_CLIENT_API_IMP_H__ */
diff --git a/MobiCoreDriverLib/ClientLib/public/GP/tee_error.h b/MobiCoreDriverLib/ClientLib/public/GP/tee_error.h
new file mode 100755
index 0000000..79d99e8
--- /dev/null
+++ b/MobiCoreDriverLib/ClientLib/public/GP/tee_error.h
@@ -0,0 +1,197 @@
+ /*
+ * Copyright (c) 2013 TRUSTONIC LIMITED
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the TRUSTONIC LIMITED nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __TEE_ERROR_H__
+#define __TEE_ERROR_H__
+
+#define TEE_SUCCESS                      ((TEE_Result)0x00000000)
+#define TEEC_SUCCESS                   TEE_SUCCESS
+
+#define TEE_ERROR_CORRUPT_OBJECT         ((TEE_Result)0xF0100001)
+#define TEE_ERROR_CORRUPT_OBJECT_2       ((TEE_Result)0xF0100002)
+
+/**
+ * Generic error code : Generic error
+ **/
+#define TEE_ERROR_GENERIC                ((TEE_Result)0xFFFF0000)
+#define TEEC_ERROR_GENERIC             TEE_ERROR_GENERIC
+
+/**
+ * Generic error code : The underlying security system denies the access to the
+ * object
+ **/
+#define TEE_ERROR_ACCESS_DENIED          ((TEE_Result)0xFFFF0001)
+#define TEEC_ERROR_ACCESS_DENIED       TEE_ERROR_ACCESS_DENIED
+
+/**
+ * Generic error code : The pending operation is cancelled.
+ **/
+#define TEE_ERROR_CANCEL                 ((TEE_Result)0xFFFF0002)
+#define TEEC_ERROR_CANCEL              TEE_ERROR_CANCEL
+
+/**
+ * Generic error code : The underlying system detects a conflict
+ **/
+#define TEE_ERROR_ACCESS_CONFLICT        ((TEE_Result)0xFFFF0003)
+#define TEEC_ERROR_ACCESS_CONFLICT     TEE_ERROR_ACCESS_CONFLICT
+
+/**
+ * Generic error code : Too much data for the operation or some data remain
+ * unprocessed by the operation.
+ **/
+#define TEE_ERROR_EXCESS_DATA            ((TEE_Result)0xFFFF0004)
+#define TEEC_ERROR_EXCESS_DATA         TEE_ERROR_EXCESS_DATA
+
+/**
+ * Generic error code : Error of data format
+ **/
+#define TEE_ERROR_BAD_FORMAT             ((TEE_Result)0xFFFF0005)
+#define TEEC_ERROR_BAD_FORMAT          TEE_ERROR_BAD_FORMAT
+
+/**
+ * Generic error code : The specified parameters are invalid
+ **/
+#define TEE_ERROR_BAD_PARAMETERS         ((TEE_Result)0xFFFF0006)
+#define TEEC_ERROR_BAD_PARAMETERS      TEE_ERROR_BAD_PARAMETERS
+
+
+/**
+ * Generic error code : Illegal state for the operation.
+ **/
+#define TEE_ERROR_BAD_STATE              ((TEE_Result)0xFFFF0007)
+#define TEEC_ERROR_BAD_STATE           TEE_ERROR_BAD_STATE
+
+/**
+ * Generic error code : The item is not found
+ **/
+#define TEE_ERROR_ITEM_NOT_FOUND         ((TEE_Result)0xFFFF0008)
+#define TEEC_ERROR_ITEM_NOT_FOUND      TEE_ERROR_ITEM_NOT_FOUND
+
+/**
+ * Generic error code : The specified operation is not implemented
+ **/
+#define TEE_ERROR_NOT_IMPLEMENTED        ((TEE_Result)0xFFFF0009)
+#define TEEC_ERROR_NOT_IMPLEMENTED     TEE_ERROR_NOT_IMPLEMENTED
+
+/**
+ * Generic error code : The specified operation is not supported
+ **/
+#define TEE_ERROR_NOT_SUPPORTED          ((TEE_Result)0xFFFF000A)
+#define TEEC_ERROR_NOT_SUPPORTED       TEE_ERROR_NOT_SUPPORTED
+
+/**
+ * Generic error code : Insufficient data is available for the operation.
+ **/
+#define TEE_ERROR_NO_DATA                ((TEE_Result)0xFFFF000B)
+#define TEEC_ERROR_NO_DATA             TEE_ERROR_NO_DATA
+
+/**
+ * Generic error code : Not enough memory to perform the operation
+ **/
+#define TEE_ERROR_OUT_OF_MEMORY          ((TEE_Result)0xFFFF000C)
+#define TEEC_ERROR_OUT_OF_MEMORY       TEE_ERROR_OUT_OF_MEMORY
+
+/**
+ * Generic error code : The service is currently unable to handle the request;
+ * try later
+ **/
+#define TEE_ERROR_BUSY                   ((TEE_Result)0xFFFF000D)
+#define TEEC_ERROR_BUSY                TEE_ERROR_BUSY
+
+/**
+ * Generic communication error
+ **/
+#define TEE_ERROR_COMMUNICATION          ((TEE_Result)0xFFFF000E)
+#define TEEC_ERROR_COMMUNICATION       TEE_ERROR_COMMUNICATION
+
+/**
+ * Generic error code : security violation
+ **/
+#define TEE_ERROR_SECURITY               ((TEE_Result)0xFFFF000F)
+#define TEEC_ERROR_SECURITY            TEE_ERROR_SECURITY
+
+/**
+ * Generic error code : the buffer is too short
+ **/
+#define TEE_ERROR_SHORT_BUFFER           ((TEE_Result)0xFFFF0010)
+#define TEEC_ERROR_SHORT_BUFFER        TEE_ERROR_SHORT_BUFFER
+
+/**
+ * Generic error code : The pending operation is cancelled.
+ */
+#define TEE_ERROR_EXTERNAL_CANCEL        ((TEE_Result)0xFFFF0011)
+
+/**
+ * Generic error code : the operation is not terminated
+ **/
+#define TEE_PENDING                      ((TEE_Result)0xFFFF2000)
+
+/**
+ * Generic error code : A timeout occurred
+ **/
+#define TEE_ERROR_TIMEOUT                ((TEE_Result)0xFFFF3001)
+
+/**
+ * Generic error code : Overflow
+ **/
+#define TEE_ERROR_OVERFLOW               ((TEE_Result)0xFFFF300F)
+
+/**
+ * Error of communication: The target of the connection is dead
+ **/
+#define TEE_ERROR_TARGET_DEAD            ((TEE_Result)0xFFFF3024)
+#define TEEC_ERROR_TARGET_DEAD         TEE_ERROR_TARGET_DEAD
+
+/*------------------------------------------------------------------------------
+   Storage Error Codes
+------------------------------------------------------------------------------*/
+
+/** File system error code: not enough space to complete the operation. */
+#define TEE_ERROR_STORAGE_NO_SPACE       ((TEE_Result)0xFFFF3041)
+
+/*------------------------------------------------------------------------------
+   Crypto error codes
+------------------------------------------------------------------------------*/
+
+#define TEE_ERROR_MAC_INVALID          ((TEE_Result)0xFFFF3071)
+
+#define TEE_ERROR_SIGNATURE_INVALID    ((TEE_Result)0xFFFF3072)
+
+/*------------------------------------------------------------------------------
+   Date error codes
+------------------------------------------------------------------------------*/
+
+#define TEE_ERROR_TIME_NOT_SET         ((TEE_Result)0xFFFF5000)
+
+#define TEE_ERROR_TIME_NEEDS_RESET     ((TEE_Result)0xFFFF5001)
+
+#endif /* __TEE_ERROR_H__ */
+
diff --git a/MobiCoreDriverLib/ClientLib/public/GP/tee_type.h b/MobiCoreDriverLib/ClientLib/public/GP/tee_type.h
new file mode 100755
index 0000000..48d7293
--- /dev/null
+++ b/MobiCoreDriverLib/ClientLib/public/GP/tee_type.h
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 2013 TRUSTONIC LIMITED
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the TRUSTONIC LIMITED nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * Definition of the machine-specific integer types
+ **/
+#ifndef __TEE_TYPE_H__
+#define __TEE_TYPE_H__
+
+/* C99 integer types */
+#if (!defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L) &&(!defined(ANDROID))
+
+#include <limits.h>
+
+/* Figure out if a 64-bit integer types is available */
+#if \
+    defined(_MSC_VER) || \
+    defined(__SYMBIAN32__) || \
+    defined(_WIN32_WCE) || \
+    (defined(ULLONG_MAX) && ULLONG_MAX == 0xFFFFFFFFFFFFFFFFULL) || \
+    (defined(ULONG_LONG_MAX) && ULONG_LONG_MAX == 0xFFFFFFFFFFFFFFFFULL)
+typedef unsigned long long uint64_t;
+typedef long long int64_t;
+#else
+#define __S_TYPE_INT64_UNDEFINED
+#endif
+
+#if UINT_MAX == 0xFFFFFFFF
+typedef unsigned int uint32_t;
+typedef int int32_t;
+#elif ULONG_MAX == 0xFFFFFFFF
+typedef unsigned long uint32_t;
+typedef long int32_t;
+#else
+#error This compiler is not supported.
+#endif
+
+#if USHRT_MAX == 0xFFFF
+typedef unsigned short uint16_t;
+typedef short  int16_t;
+#else
+#error This compiler is not supported.
+#endif
+
+#if UCHAR_MAX == 0xFF
+typedef unsigned char uint8_t;
+typedef signed char   int8_t;
+#else
+#error This compiler is not supported.
+#endif
+
+#if !defined(__cplusplus)
+typedef unsigned char bool;
+#define false ( (bool)0 )
+#define true  ( (bool)1 )
+#endif
+
+#else  /* !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L */
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#endif  /* !(!defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L) */
+
+#include <stddef.h>
+
+#ifndef NULL
+#  ifdef __cplusplus
+#     define NULL  0
+#  else
+#     define NULL  ((void *)0)
+#  endif
+#endif
+
+#define IN
+#define OUT
+
+/*
+ * Definition of other common types
+ */
+
+// to delete when all completed
+typedef uint32_t TEE_Result;
+typedef TEE_Result TEEC_Result;
+
+typedef uint32_t TEE_HANDLE;
+
+/** Definition of an UUID (from RFC 4122 http://www.ietf.org/rfc/rfc4122.txt) */
+typedef struct TEE_UUID {
+    uint32_t timeLow;
+    uint16_t timeMid;
+    uint16_t timeHiAndVersion;
+    uint8_t clockSeqAndNode[8];
+} TEE_UUID;
+typedef TEE_UUID TEEC_UUID;
+
+/** Type definition for a TEE Identity */
+typedef struct TEE_Identity {
+    uint32_t login;
+    TEE_UUID uuid;
+} TEE_Identity;
+
+typedef struct __TEE_PropSetHandle {
+    unsigned char reserved;
+} __TEE_PropSetHandle;
+
+typedef struct __TEE_PropSetHandle* TEE_PropSetHandle;
+
+/* Property Sets Pseudo Handles */
+#define TEE_PROPSET_CURRENT_TA               (TEE_PropSetHandle)0xFFFFFFFF
+#define TEE_PROPSET_CURRENT_CLIENT           (TEE_PropSetHandle)0xFFFFFFFE
+#define TEE_PROPSET_TEE_IMPLEMENTATION       (TEE_PropSetHandle)0xFFFFFFFD
+
+
+/* DLL Import/Export directives */
+
+#if defined(WIN32) || defined(__ARMCC_VERSION) || defined(__WINSCW__) || defined(_WIN32_WCE)
+#  define S_DLL_EXPORT __declspec(dllexport)
+#  define S_DLL_IMPORT __declspec(dllimport)
+#  define S_NO_RETURN  __declspec(noreturn)
+#elif defined(__GNUC__)
+#  define S_DLL_EXPORT __attribute__ ((visibility ("default")))
+#  define S_DLL_IMPORT __attribute__ ((visibility ("default")))
+#  define S_NO_RETURN  __attribute__ ((noreturn))
+#else
+#  define S_DLL_EXPORT
+#  define S_DLL_IMPORT
+#  define S_NO_RETURN
+#endif
+
+#if defined(_MSC_VER)
+#define __func__ __FUNCTION__
+#endif
+
+#endif /* __TEE_TYPE_H__ */
diff --git a/MobiCoreDriverLib/ClientLib/public/GP/uuid_attestation.h b/MobiCoreDriverLib/ClientLib/public/GP/uuid_attestation.h
new file mode 100755
index 0000000..ea562fd
--- /dev/null
+++ b/MobiCoreDriverLib/ClientLib/public/GP/uuid_attestation.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2013 TRUSTONIC LIMITED
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the TRUSTONIC LIMITED nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __TEE_UUID_ATTESTATION_H__
+#define __TEE_UUID_ATTESTATION_H__
+
+#include "tee_type.h"
+
+// Sizes of the fields of attestation structure
+#define AT_MAGIC_SIZE           8
+#define AT_SIZE_SIZE            sizeof(uint32_t)
+#define AT_VERSION_SIZE         sizeof(uint32_t)
+#define AT_UUID_SIZE            sizeof(TEE_UUID)
+
+// Sizes of the fields used to generate signature
+#define AT_TAG_SIZE             20
+#define AT_SHA1_HASH_SIZE       20
+
+// Max size of RSA modulus supported 
+#define AT_MODULUS_MAX_SIZE     256
+// Max size of RSA public exponent supported 
+#define AT_PUBLIC_EXPO_MAX_SIZE 4
+
+// Attestation version
+#define AT_VERSION              1
+
+// Name space ID (the UUID of the RSA OID)
+const uint8_t       RSA_OID_UUID[AT_UUID_SIZE] = {0x6b, 0x8e, 0x02, 0x6b, 0x63, 0xc1, 0x5d, 0x58, 0xb0, 0x64, 0x00, 0xd3, 0x51, 0x89, 0xce, 0x65};
+// Magic word
+const char          MAGIC[AT_MAGIC_SIZE] = "TAUUID\0";
+
+// Tag for signature generation
+const char          TAG[AT_TAG_SIZE]="Trusted Application";
+
+// Public key structure
+typedef struct uuid_public_key {
+    uint32_t    type;           // TEE TYPE RSA KEYPAIR: 0xa0000030
+    uint16_t    modulus_bytes;  // Length of the modulus in bytes
+    uint16_t    exponent_bytes; // Length of the exponent in bytes
+    uint8_t     data[];         // Key material
+} uuid_public_key;
+
+// Attestation structure
+typedef struct uuid_attestation {
+    uint8_t         magic[AT_MAGIC_SIZE];   // Magic word: "TAUUID\0\0"
+    uint32_t        size;                   // Attestation size (4 bytes)
+    uint32_t        version;                // Version number: 1 (4 bytes)
+    uint8_t         uuid[AT_UUID_SIZE];     // UUID
+    uuid_public_key key;                    // Public key
+} uuid_attestation;
+
+#endif /* __TEE_UUID_ATTESTATION_H__ */
diff --git a/daemon/ClientLib/public/MobiCoreDriverApi.h b/MobiCoreDriverLib/ClientLib/public/MobiCoreDriverApi.h
old mode 100644
new mode 100755
similarity index 82%
rename from daemon/ClientLib/public/MobiCoreDriverApi.h
rename to MobiCoreDriverLib/ClientLib/public/MobiCoreDriverApi.h
index 8d36fc0..425f5e5
--- a/daemon/ClientLib/public/MobiCoreDriverApi.h
+++ b/MobiCoreDriverLib/ClientLib/public/MobiCoreDriverApi.h
@@ -9,10 +9,10 @@
  *
  * MobiCore Driver API.
  *
- * The MobiCore (MC) Driver API provides access functions to the MobiCore runtime environment and the contained Trustlets.
+ * The MobiCore (MC) Driver API provides access functions to the t-base trusted execution environment and the contained Trusted Applications.
  *
  * @image html DoxyOverviewDrvApi500x.png
- * @image latex DoxyOverviewDrvApi500x.png "MobiCore Overview" width=12cm
+ * @image latex DoxyOverviewDrvApi500x.png "t-base Overview" width=12cm
  */
 /* <!-- Copyright Trustonic 2013-2014 -->
  *
@@ -51,7 +51,9 @@
 
 
 #include <stdint.h>
+#ifndef WIN32
 #include <stdbool.h>
+#endif
 
 #include "mcUuid.h"
 #include "mcSpid.h"
@@ -103,7 +105,7 @@
 
 // those should become MCP or even detail codes on top of MC_DRV_ERR_MCP_ERROR
 #define MC_DRV_ERR_WRONG_PUBLIC_KEY                 0x00000019 /**< System Trustlet public key is wrong. */
-#define MC_DRV_ERR_CONTAINER_TYPE_MISMATCH          0x0000001a /**< Wrong containter type(s). */
+#define MC_DRV_ERR_CONTAINER_TYPE_MISMATCH          0x0000001a /**< Wrong container type(s). */
 #define MC_DRV_ERR_CONTAINER_LOCKED                 0x0000001b /**< Container is locked (or not activated). */
 #define MC_DRV_ERR_SP_NO_CHILD                      0x0000001c /**< SPID is not registered with root container. */
 #define MC_DRV_ERR_TL_NO_CHILD                      0x0000001d /**< UUID is not registered with sp container. */
@@ -124,18 +126,25 @@
 #define MC_DRV_ERR_WSM_NOT_FOUND                    MC_DRV_ERR_INVALID_PARAMETER /**< Requested TCI was not allocated with mallocWsm(). */
 #define MC_DRV_ERR_TCI_GREATER_THAN_WSM             MC_DRV_ERR_INVALID_PARAMETER /**< Requested TCI length is bigger than allocated WSM. */
 #define MC_DRV_ERR_TRUSTLET_NOT_FOUND               MC_DRV_ERR_INVALID_DEVICE_FILE /** < Trustlet could not be found in mcRegistry. */
+#define MC_DRV_ERR_TRUSTED_APPLICATION_NOT_FOUND    MC_DRV_ERR_TRUSTLET_NOT_FOUND /** < Trusted Application could not be found in mcRegistry. */
 #define MC_DRV_ERR_DAEMON_KMOD_ERROR                MC_DRV_ERR_DAEMON_UNREACHABLE /**< Daemon cannot use Kernel module as expected. */
 #define MC_DRV_ERR_DAEMON_MCI_ERROR                 MC_DRV_ERR_DAEMON_UNREACHABLE /**< Daemon cannot use MCI as expected. */
 #define MC_DRV_ERR_MCP_ERROR                        MC_DRV_ERR_DAEMON_UNREACHABLE /**< MobiCore Control Protocol error. See MC_DRV_ERROR_MCP(). */
 #define MC_DRV_ERR_INVALID_LENGTH                   MC_DRV_ERR_NO_FREE_MEMORY /**< Invalid length. */
 #define MC_DRV_ERR_KMOD_NOT_OPEN                    MC_DRV_ERR_NO_FREE_MEMORY /**< Device not open. */
-#define MC_DRV_ERR_BUFFER_ALREADY_MAPPED            MC_DRV_ERR_BULK_MAPPING /**< Buffer is already mapped to this Trustlet. */
+#define MC_DRV_ERR_BUFFER_ALREADY_MAPPED            MC_DRV_ERR_BULK_MAPPING /**< Buffer is already mapped to this Trusted Application. */
 #define MC_DRV_ERR_BLK_BUFF_NOT_FOUND               MC_DRV_ERR_BULK_UNMAPPING /**< Unable to find internal handle for buffer. */
 
 #define MC_DRV_ERR_DAEMON_DEVICE_NOT_OPEN           0x00000021 /**< No device associated with connection. */
 #define MC_DRV_ERR_DAEMON_WSM_HANDLE_NOT_FOUND      MC_DRV_ERR_WSM_NOT_FOUND /**< Daemon could not find WSM handle. */
 #define MC_DRV_ERR_DAEMON_UNKNOWN_SESSION           MC_DRV_ERR_UNKNOWN_SESSION /**< The specified session is unknown to Daemon. */
 
+#if TBASE_API_LEVEL >= 3
+// Installation errors
+#define MC_DRV_ERR_TA_HEADER_ERROR                  0x00000021 /**< TA blob header is incorrect. */
+#define MC_DRV_ERR_TA_ATTESTATION_ERROR             0x00000022 /**< TA blob attestation is incorrect. */
+#endif /* TBASE_API_LEVEL */
+
 #define MAKE_MC_DRV_MCP_ERROR(mcpCode)              (MC_DRV_ERR_MCP_ERROR | ((mcpCode&0x000FFFFF)<<8))
 #define MAKE_MC_DRV_KMOD_WITH_ERRNO(theErrno)       (MC_DRV_ERR_KERNEL_MODULE| (((theErrno)&0x0000FFFF)<<16))
 
@@ -148,21 +157,21 @@
 
 
 /** Structure of Session Handle, includes the Session ID and the Device ID the Session belongs to.
- * The session handle will be used for session-based MobiCore communication.
- * It will be passed to calls which address a communication end point in the MobiCore environment.
+ * The session handle will be used for session-based t-base communication.
+ * It will be passed to calls which address a communication end point in the t-base environment.
  */
 typedef struct {
-    uint32_t sessionId; /**< MobiCore session ID */
+    uint32_t sessionId; /**< t-base session ID */
     uint32_t deviceId; /**< Device ID the session belongs to */
 } mcSessionHandle_t;
 
-/** Information structure about additional mapped Bulk buffer between the Trustlet Connector (Nwd) and
- * the Trustlet (Swd). This structure is initialized from a Trustlet Connector by calling mcMap().
- * In order to use the memory within a Trustlet the Trustlet Connector has to inform the Trustlet with
+/** Information structure about additional mapped Bulk buffer between the Client Application (NWd) and
+ * the Trusted Application (SWd). This structure is initialized from a Client Application by calling mcMap().
+ * In order to use the memory within a Trusted Application the Client Application has to inform the Trusted Application with
  * the content of this structure via the TCI.
  */
 typedef struct {
-    void *sVirtualAddr;         /**< The virtual address of the Bulk buffer regarding the address space of the Trustlet, already includes a possible offset! */
+    void *sVirtualAddr;         /**< The virtual address of the Bulk buffer regarding the address space of the Trusted Application, already includes a possible offset! */
     uint32_t sVirtualLen;       /**< Length of the mapped Bulk buffer */
 } mcBulkMap_t;
 
@@ -172,16 +181,18 @@
 #define MC_NO_TIMEOUT              0   /**< Do not wait for a response of the MC. */
 #define MC_MAX_TCI_LEN             0x100000 /**< TCI/DCI must not exceed 1MiB */
 
+#ifndef WIN32
 /* Mark only the following functions for export */
 #pragma GCC visibility push(default)
+#endif
 
-/** Open a new connection to a MobiCore device.
+/** Open a new connection to a t-base device.
  *
  * mcOpenDevice() initializes all device specific resources required to communicate
- * with an MobiCore instance located on the specified device in the system. If the device
+ * with an t-base instance located on the specified device in the system. If the device
  * does not exist the function will return MC_DRV_ERR_UNKNOWN_DEVICE.
  *
- * @param [in] deviceId Identifier for the MobiCore device to be used. MC_DEVICE_ID_DEFAULT refers to the default device.
+ * @param [in] deviceId Identifier for the t-base device to be used. MC_DEVICE_ID_DEFAULT refers to the default device.
  *
  * @return MC_DRV_OK if operation has been successfully completed.
  * @return MC_DRV_ERR_INVALID_OPERATION if device already opened.
@@ -195,12 +206,12 @@
     uint32_t deviceId
 );
 
-/** Close the connection to a MobiCore device.
+/** Close the connection to a t-base device.
  * When closing a device, active sessions have to be closed beforehand.
  * Resources associated with the device will be released.
  * The device may be opened again after it has been closed.
  *
- * @param [in] deviceId Identifier for the MobiCore device. MC_DEVICE_ID_DEFAULT refers to the default device.
+ * @param [in] deviceId Identifier for the t-base device. MC_DEVICE_ID_DEFAULT refers to the default device.
  *
  * @return MC_DRV_OK if operation has been successfully completed.
  * @return MC_DRV_ERR_UNKNOWN_DEVICE when device id is invalid.
@@ -213,14 +224,14 @@
     uint32_t deviceId
 );
 
-/** Open a new session to a Trustlet. The trustlet with the given UUID has to be available in the flash filesystem.
+/** Open a new session to a Trusted Application. The Trusted Application with the given UUID has to be available in the flash filesystem.
  *
- * Write MCP open message to buffer and notify MobiCore about the availability of a new command.
- * Waits till the MobiCore responses with the new session ID (stored in the MCP buffer).
+ * Write MCP open message to buffer and notify t-base about the availability of a new command.
+ * Waits till t-base responds with the new session ID (stored in the MCP buffer).
  *
  * @param [in,out] session On success, the session data will be returned. Note that session.deviceId has to be the device id of an opened device.
- * @param [in] uuid UUID of the Trustlet to be opened.
- * @param [in] tci TCI buffer for communicating with the trustlet.
+ * @param [in] uuid UUID of the Trusted Application to be opened.
+ * @param [in] tci TCI buffer for communicating with the Trusted Application.
  * @param [in] tciLen Length of the TCI buffer. Maximum allowed value is MC_MAX_TCI_LEN.
  *
  * @return MC_DRV_OK if operation has been successfully completed.
@@ -228,7 +239,7 @@
  * @return MC_DRV_ERR_UNKNOWN_DEVICE when device id is invalid.
  * @return MC_DRV_ERR_DAEMON_UNREACHABLE when problems with daemon socket occur.
  * @return MC_DRV_ERR_UNKNOWN_DEVICE when daemon returns an error.
- * @return MC_DRV_ERR_TRUSTLET_NOT_FOUND when trustlet or driver cannot be loaded.
+ * @return MC_DRV_ERR_TRUSTED_APPLICATION_NOT_FOUND when Trusted Application or driver cannot be loaded.
  *
  * Uses a Mutex.
  */
@@ -239,17 +250,16 @@
     uint32_t           tciLen
 );
 
-/** Open a new session to a Trustlet. The trustlet will be loaded from the memory
- * buffer
+/** Open a new session to a Trusted Application(Trustlet). The Trusted Application will be loaded from the memory buffer.
  *
- * Write MCP open message to buffer and notify MobiCore about the availability of a new command.
- * Waits till the MobiCore responses with the new session ID (stored in the MCP buffer).
+ * Write MCP open message to buffer and notify t-base about the availability of a new command.
+ * Waits till t-base responds with the new session ID (stored in the MCP buffer).
  *
  * @param [in,out] session On success, the session data will be returned. Note that session.deviceId has to be the device id of an opened device.
  * @param [in] spid Service Provider ID(for Service provider trustlets otherwise ignored)
- * @param [in] trustlet memory buffer containing the trustlet binary
- * @param [in] tlen length of the memory buffer containing the trustlet
- * @param [in] tci TCI buffer for communicating with the trustlet.
+ * @param [in] trustedapp memory buffer containing the Trusted Application binary
+ * @param [in] tlen length of the memory buffer containing the Trusted Application
+ * @param [in] tci TCI buffer for communicating with the Trusted Application.
  * @param [in] tciLen Length of the TCI buffer. Maximum allowed value is MC_MAX_TCI_LEN.
  *
  * @return MC_DRV_OK if operation has been successfully completed.
@@ -257,23 +267,23 @@
  * @return MC_DRV_ERR_UNKNOWN_DEVICE when device id is invalid.
  * @return MC_DRV_ERR_DAEMON_UNREACHABLE when problems with daemon socket occur.
  * @return MC_DRV_ERR_UNKNOWN_DEVICE when daemon returns an error.
- * @return MC_DRV_ERR_TRUSTLET_NOT_FOUND when trustlet cannot be loaded.
+ * @return MC_DRV_ERR_TRUSTED_APPLICATION_NOT_FOUND when Trusted Application cannot be loaded.
  *
  * Uses a Mutex.
  */
 __MC_CLIENT_LIB_API mcResult_t mcOpenTrustlet(
     mcSessionHandle_t  *session,
     mcSpid_t           spid,
-    uint8_t            *trustlet,
+    uint8_t            *trustedapp,
     uint32_t           tLen,
     uint8_t            *tci,
     uint32_t           tciLen
 );
 
 
-/** Close a Trustlet session.
+/** Close a Trusted Application session.
  *
- * Closes the specified MobiCore session. The call will block until the session has been closed.
+ * Closes the specified t-base session. The call will block until the session has been closed.
  *
  * @pre Device deviceId has to be opened in advance.
  *
@@ -311,7 +321,7 @@
 
 /** Wait for a notification.
  *
- * Wait for a notification issued by the MobiCore for a specific session.
+ * Wait for a notification issued by t-base for a specific session.
  * The timeout parameter specifies the number of milliseconds the call will wait for a notification.
  * If the caller passes 0 as timeout value the call will immediately return. If timeout value is below 0 the call will block
  * until a notification for the session has been received.
@@ -342,7 +352,7 @@
  * Always returns a buffer of size WSM_SIZE aligned to 4K.
  *
  * @param [in]  deviceId The ID of an opened device to retrieve the WSM from.
- * @param [in]  align The alignment (number of pages) of the memory block (e.g. 0x00000001 for 4kb).
+ * @param [in]  align The alignment (number of pages) of the memory block (e.g. 0x00000001 for 4kB).
  * @param [in]  len Length of the block in bytes.
  * @param [out] wsm Virtual address of the world shared memory block.
  * @param [in]  wsmFlags Platform specific flags describing the memory to be allocated.
@@ -386,19 +396,19 @@
 );
 
 /**
- * Map additional bulk buffer between a Trustlet Connector (TLC) and the Trustlet (TL) for a session.
- * Memory allocated in user space of the TLC can be mapped as additional communication channel
- * (besides TCI) to the Trustlet. Limitation of the Trustlet memory structure apply: only 6 chunks can be mapped
+ * Map additional bulk buffer between a Client Application (CA) and the Trusted Application (TA) for a session.
+ * Memory allocated in user space of the CA can be mapped as additional communication channel
+ * (besides TCI) to the Trusted Application. Limitation of the Trusted Application memory structure apply: only 6 chunks can be mapped
  * with a maximum chunk size of 1 MiB each.
  *
- * @attention It is up to the application layer (TLC) to inform the Trustlet about the additional mapped bulk memory.
+ * @attention It is up to the application layer (CA) to inform the Trusted Application about the additional mapped bulk memory.
  *
  * @param [in] session Session handle with information of the deviceId and the sessionId. The
  * given buffer is mapped to the session specified in the sessionHandle.
- * @param [in] buf Virtual address of a memory portion (relative to TLC) to be shared with the Trustlet, already includes a possible offset!
+ * @param [in] buf Virtual address of a memory portion (relative to CA) to be shared with the Trusted Application, already includes a possible offset!
  * @param [in] len length of buffer block in bytes.
- * @param [out] mapInfo Information structure about the mapped Bulk buffer between the TLC (Nwd) and
- * the TL (Swd).
+ * @param [out] mapInfo Information structure about the mapped Bulk buffer between the CA (NWd) and
+ * the TA (SWd).
  *
  * @return MC_DRV_OK if operation has been successfully completed.
  * @return MC_DRV_INVALID_PARAMETER if a parameter is invalid.
@@ -417,16 +427,16 @@
 );
 
 /**
- * Remove additional mapped bulk buffer between Trustlet Connector (TLC) and the Trustlet (TL) for a session.
+ * Remove additional mapped bulk buffer between Client Application (CA) and the Trusted Application (TA) for a session.
  *
  * @attention The bulk buffer will immediately be unmapped from the session context.
- * @attention The application layer (TLC) must inform the TL about unmapping of the additional bulk memory before calling mcUnmap!
+ * @attention The application layer (CA) must inform the TA about unmapping of the additional bulk memory before calling mcUnmap!
  *
  * @param [in] session Session handle with information of the deviceId and the sessionId. The
  * given buffer is unmapped from the session specified in the sessionHandle.
- * @param [in] buf Virtual address of a memory portion (relative to TLC) shared with the TL, already includes a possible offset!
- * @param [in] mapInfo Information structure about the mapped Bulk buffer between the TLC (Nwd) and
- * the TL (Swd).
+ * @param [in] buf Virtual address of a memory portion (relative to CA) shared with the TA, already includes a possible offset!
+ * @param [in] mapInfo Information structure about the mapped Bulk buffer between the CA (NWd) and
+ * the TA (SWd).
  * @attention The clientlib currently ignores the len field in mapInfo.
  *
  * @return MC_DRV_OK if operation has been successfully completed.
@@ -465,11 +475,11 @@
 );
 
 /**
- * Get additional error information of the last error that occured on a session.
+ * Get additional error information of the last error that occurred on a session.
  * After the request the stored error code will be deleted.
  *
  * @param [in] session Session handle with information of the deviceId and the sessionId.
- * @param [out] lastErr >0 Trustlet has terminated itself with this value, <0 Trustlet is dead because of an error within the MobiCore (e.g. Kernel exception).
+ * @param [out] lastErr >0 Trusted Application has terminated itself with this value, <0 Trusted Application is dead because of an error within t-base (e.g. Kernel exception).
  * See also notificationPayload_t enum in MCI definition at "mcinq.h".
  *
  * @return MC_DRV_OK if operation has been successfully completed.
@@ -483,10 +493,10 @@
 );
 
 /**
- * Get MobiCore version information of a device.
+ * Get t-base version information of a device.
  *
  * @param [in] deviceId of an open device.
- * @param [out] versionInfo MobiCore version info.
+ * @param [out] versionInfo t-base version info.
  *
  * @return MC_DRV_OK if operation has been successfully completed.
  * @return MC_DRV_ERR_UNKNOWN_DEVICE when device is not open.
@@ -497,7 +507,9 @@
     uint32_t  deviceId,
     mcVersionInfo_t *versionInfo
 );
+#ifndef WIN32
 #pragma GCC visibility pop
+#endif
 #endif /** MCDRIVER_H_ */
 
 /** @} */
diff --git a/daemon/Common/Android.mk b/MobiCoreDriverLib/Common/Android.mk
old mode 100644
new mode 100755
similarity index 100%
rename from daemon/Common/Android.mk
rename to MobiCoreDriverLib/Common/Android.mk
diff --git a/MobiCoreDriverLib/Common/CMutex.cpp b/MobiCoreDriverLib/Common/CMutex.cpp
new file mode 100755
index 0000000..dc9e24f
--- /dev/null
+++ b/MobiCoreDriverLib/Common/CMutex.cpp
@@ -0,0 +1,86 @@
+/** @addtogroup MCD_MCDIMPL_DAEMON_SRV
+ * @{
+ * @file
+ *
+ * Mutex implementation (pthread wrapper).
+ *
+ * Copyright (c) 2013 TRUSTONIC LIMITED
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the TRUSTONIC LIMITED nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "CMutex.h"
+#include "log.h"
+
+
+//------------------------------------------------------------------------------
+CMutex::CMutex(
+    void
+)
+{
+    pthread_mutex_init(&m_mutex, NULL);
+    pthread_cond_init(&m_cond, NULL);
+}
+
+
+//------------------------------------------------------------------------------
+CMutex::~CMutex(
+    void
+)
+{
+    pthread_mutex_destroy(&m_mutex);
+    pthread_cond_destroy(&m_cond);
+}
+
+
+//------------------------------------------------------------------------------
+int32_t CMutex::lock(
+    void
+)
+{
+    return pthread_mutex_lock(&m_mutex);
+}
+
+
+//------------------------------------------------------------------------------
+int32_t CMutex::trylock(
+    void
+)
+{
+    return pthread_mutex_trylock(&m_mutex);
+}
+
+
+//------------------------------------------------------------------------------
+int32_t CMutex::unlock(
+    void
+)
+{
+    return pthread_mutex_unlock(&m_mutex);
+}
+
+/** @} */
diff --git a/MobiCoreDriverLib/Common/CMutex.h b/MobiCoreDriverLib/Common/CMutex.h
new file mode 100755
index 0000000..22beacb
--- /dev/null
+++ b/MobiCoreDriverLib/Common/CMutex.h
@@ -0,0 +1,67 @@
+/** @addtogroup MCD_MCDIMPL_DAEMON_SRV
+ * @{
+ * @file
+ *
+ * Mutex implementation (pthread wrapper).
+ *
+ * Copyright (c) 2013 TRUSTONIC LIMITED
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the TRUSTONIC LIMITED nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef CMUTEX_H_
+#define CMUTEX_H_
+
+#include <inttypes.h>
+#include "pthread.h"
+
+
+class CMutex
+{
+
+public:
+
+    CMutex(void);
+
+    ~CMutex(void);
+
+    int32_t lock(void);
+
+    int32_t trylock(void);
+
+    int32_t unlock(void);
+
+private:
+
+    pthread_mutex_t m_mutex;
+    pthread_cond_t m_cond;
+
+};
+
+#endif /* CMUTEX_H_ */
+
+/** @} */
diff --git a/daemon/Common/CSemaphore.cpp b/MobiCoreDriverLib/Common/CSemaphore.cpp
old mode 100644
new mode 100755
similarity index 68%
rename from daemon/Common/CSemaphore.cpp
rename to MobiCoreDriverLib/Common/CSemaphore.cpp
index 066d40e..efa06c4
--- a/daemon/Common/CSemaphore.cpp
+++ b/MobiCoreDriverLib/Common/CSemaphore.cpp
@@ -4,31 +4,34 @@
  *
  * Semaphore implementation (pthread wrapper).
  *
- * <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
+ * Copyright (c) 2013 TRUSTONIC LIMITED
+ * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- *    products derived from this software without specific prior
- *    written permission.
  *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 3. Neither the name of the TRUSTONIC LIMITED nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 #include <time.h>
 #include <limits.h>
diff --git a/MobiCoreDriverLib/Common/CSemaphore.h b/MobiCoreDriverLib/Common/CSemaphore.h
new file mode 100755
index 0000000..fa08b70
--- /dev/null
+++ b/MobiCoreDriverLib/Common/CSemaphore.h
@@ -0,0 +1,74 @@
+/** @addtogroup MCD_MCDIMPL_DAEMON_SRV
+ * @{
+ * @file
+ *
+ * Semaphore implementation (pthread wrapper).
+ *
+ * Copyright (c) 2013 TRUSTONIC LIMITED
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the TRUSTONIC LIMITED nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef CSEMAPHORE_H_
+#define CSEMAPHORE_H_
+
+#include "pthread.h"
+
+/**
+ * Could inherit from CMutex, or use CMutex internally.
+ * Semaphore is a mutex with a counter. Constructor and destructor
+ * code is the same.
+ */
+
+class CSemaphore
+{
+
+public:
+
+    CSemaphore(int size = 0);
+
+    ~CSemaphore(void);
+
+    void wait(void);
+    bool wait(int sec);
+
+    bool wouldWait(void);
+
+    void signal(void);
+
+private:
+
+    pthread_mutex_t m_mutex;
+    pthread_cond_t m_cond;
+    int m_waiters_count;
+    int m_count;
+
+};
+
+#endif /*CSEMAPHORE_H_*/
+
+/** @} */
diff --git a/daemon/Common/CThread.cpp b/MobiCoreDriverLib/Common/CThread.cpp
old mode 100644
new mode 100755
similarity index 64%
rename from daemon/Common/CThread.cpp
rename to MobiCoreDriverLib/Common/CThread.cpp
index e45c423..566dafd
--- a/daemon/Common/CThread.cpp
+++ b/MobiCoreDriverLib/Common/CThread.cpp
@@ -4,31 +4,34 @@
  *
  * Thread implementation (pthread abstraction).
  *
- * <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
+ * Copyright (c) 2013 TRUSTONIC LIMITED
+ * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- *    products derived from this software without specific prior
- *    written permission.
  *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 3. Neither the name of the TRUSTONIC LIMITED nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 #include "CThread.h"
 
@@ -40,9 +43,9 @@
     m_terminate(false), m_isExiting(false)
 {
     m_sem = new CSemaphore();
+    m_thread=0;
 }
 
-
 //------------------------------------------------------------------------------
 CThread::~CThread(
     void
@@ -109,6 +112,16 @@
         LOG_E("pthread_create failed with error code %d", ret);
 }
 
+//------------------------------------------------------------------------------
+void CThread::start(
+    const char* name
+)
+{
+    start();
+    int ret = pthread_setname_np(m_thread, name);
+    if (0 != ret)
+        LOG_E("pthread_setname_np failed with error code %d %s", ret, name);
+}
 
 //------------------------------------------------------------------------------
 void CThread::join(
diff --git a/MobiCoreDriverLib/Common/CThread.h b/MobiCoreDriverLib/Common/CThread.h
new file mode 100755
index 0000000..ad2e4e7
--- /dev/null
+++ b/MobiCoreDriverLib/Common/CThread.h
@@ -0,0 +1,92 @@
+/** @addtogroup MCD_MCDIMPL_DAEMON_SRV
+ * @{
+ * @file
+ *
+ * Thread implementation (pthread abstraction).
+ *
+ * Copyright (c) 2013 TRUSTONIC LIMITED
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the TRUSTONIC LIMITED nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef CTHREAD_H_
+#define CTHREAD_H_
+
+#include <inttypes.h>
+#include "CSemaphore.h"
+#include "pthread.h"
+
+using namespace std;
+
+
+class CThread
+{
+
+public:
+
+    CThread(void);
+
+    virtual ~CThread(void);
+
+    virtual void run(void) = 0;
+
+    void start(void);
+
+    void start(const char* name);
+
+    void join(void);
+
+    void sleep(void);
+
+    void wakeup(void);
+
+    void terminate(void);
+
+    bool isExiting(void);
+
+    void setExiting(void);
+
+protected:
+
+    bool shouldTerminate(void);
+
+    void exit(int32_t exitcode);
+
+private:
+
+    CSemaphore *m_sem;
+    pthread_t m_thread;
+    bool m_terminate;
+    bool m_isExiting;
+
+};
+
+extern "C" void *CThreadStartup(void *);
+
+#endif /*CTHREAD_H_*/
+
+/** @} */
diff --git a/MobiCoreDriverLib/Common/CWsm.h b/MobiCoreDriverLib/Common/CWsm.h
new file mode 100755
index 0000000..33d82ab
--- /dev/null
+++ b/MobiCoreDriverLib/Common/CWsm.h
@@ -0,0 +1,71 @@
+/** @addtogroup MCD_MCDIMPL_DAEMON_SRV
+ * @{
+ * @file
+ *
+ * World shared memory definitions.
+ *
+ * Copyright (c) 2013 TRUSTONIC LIMITED
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the TRUSTONIC LIMITED nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef CWSM_H_
+#define CWSM_H_
+
+#include <stdint.h>
+#include <list>
+#include "McTypes.h"
+
+
+class CWsm
+{
+public:
+    addr_t virtAddr;
+    uint32_t len;
+    uint32_t handle;
+    uint64_t physAddr;
+
+    CWsm(addr_t virtAddr,
+         uint32_t  len,
+         uint32_t  handle,
+         // this may be unknown, so is can be omitted.
+         uint64_t    physAddr = NULL) :
+        virtAddr(virtAddr),
+        len(len),
+        handle(handle),
+        physAddr(physAddr)
+    { };
+
+};
+
+typedef CWsm                   *CWsm_ptr;
+typedef std::list<CWsm_ptr>  wsmList_t;
+typedef wsmList_t::iterator  wsmIterator_t;
+
+#endif /* CWSM_H_ */
+
+/** @} */
diff --git a/daemon/Common/Connection.cpp b/MobiCoreDriverLib/Common/Connection.cpp
old mode 100644
new mode 100755
similarity index 76%
rename from daemon/Common/Connection.cpp
rename to MobiCoreDriverLib/Common/Connection.cpp
index 7468d4b..fc3cdda
--- a/daemon/Common/Connection.cpp
+++ b/MobiCoreDriverLib/Common/Connection.cpp
@@ -3,33 +3,35 @@
  * @file
  *
  * Connection data.
- */
-
-/* <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
+ *
+ * Copyright (c) 2013 TRUSTONIC LIMITED
+ * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- *    products derived from this software without specific prior
- *    written permission.
  *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 3. Neither the name of the TRUSTONIC LIMITED nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 #include <unistd.h>
 #include <assert.h>
@@ -51,6 +53,11 @@
     connectionData = NULL;
     // Set invalid socketDescriptor
     socketDescriptor = -1;
+
+    detached = false;
+
+    remote.sun_family = AF_UNIX;
+    memset(remote.sun_path, 0, sizeof(remote.sun_path));
 }
 
 
@@ -63,15 +70,20 @@
     this->socketDescriptor = socketDescriptor;
     this->remote = *remote;
     connectionData = NULL;
+    detached = false;
 }
 
 
 //------------------------------------------------------------------------------
 Connection::~Connection(void)
 {
-    LOG_V(" closing Connection...");
-    if (socketDescriptor != -1)
-        close(socketDescriptor);
+    LOG_V(" closing Connection... fd=%i", socketDescriptor);
+    if (socketDescriptor != -1) {
+        int ret = close(socketDescriptor);
+        if(ret) {
+            LOG_ERRNO("close");
+        }
+    }
     LOG_I(" Socket connection closed.");
 }
 
@@ -101,7 +113,7 @@
         LOG_ERRNO("connect()");
         return false;
     }
-    
+
     return true;
 }
 
@@ -219,14 +231,14 @@
 {
     assert(socketDescriptor != -1);
     int retval;
-    struct pollfd ufds[1];      
+    struct pollfd ufds[1];
     ufds[0].fd = socketDescriptor;
     ufds[0].events = POLLRDHUP;
 
     retval = poll(ufds, 1, 10);
     if (retval < 0 || retval > 0) {
-      LOG_ERRNO("poll");
-      return false;
+        LOG_ERRNO("poll");
+        return false;
     }
     return true;
 }
@@ -237,7 +249,12 @@
     struct ucred cred;
     int len = sizeof (cred);
     assert(socketDescriptor != -1);
-    getsockopt(socketDescriptor, SOL_SOCKET, SO_PEERCRED, &cred, &len);
+    int ret = getsockopt(socketDescriptor, SOL_SOCKET, SO_PEERCRED, &cred,
+                         &len);
+    if (ret != 0) {
+        LOG_ERRNO("getsockopt");
+        return false;
+    }
     if (len == sizeof(cred)) {
         cr = cred;
         return true;
diff --git a/daemon/Common/Connection.h b/MobiCoreDriverLib/Common/Connection.h
old mode 100644
new mode 100755
similarity index 71%
rename from daemon/Common/Connection.h
rename to MobiCoreDriverLib/Common/Connection.h
index 606c039..89bc585
--- a/daemon/Common/Connection.h
+++ b/MobiCoreDriverLib/Common/Connection.h
@@ -4,31 +4,34 @@
  *
  * Connection data.
  *
- * <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
+ * Copyright (c) 2013 TRUSTONIC LIMITED
+ * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- *    products derived from this software without specific prior
- *    written permission.
  *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 3. Neither the name of the TRUSTONIC LIMITED nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 #ifndef CONNECTION_H_
 #define CONNECTION_H_
diff --git a/MobiCoreDriverLib/Common/McTypes.h b/MobiCoreDriverLib/Common/McTypes.h
new file mode 100755
index 0000000..6e8989e
--- /dev/null
+++ b/MobiCoreDriverLib/Common/McTypes.h
@@ -0,0 +1,43 @@
+/** @addtogroup MCD_MCDIMPL_DAEMON_SRV
+ * @{
+ * @file
+ *
+ * MobiCore types redefinition.
+ *
+ * Copyright (c) 2013 TRUSTONIC LIMITED
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the TRUSTONIC LIMITED nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef MCTYPES_H_
+#define MCTYPES_H_
+
+typedef void    *addr_t;
+
+#endif /* MCTYPES_H_ */
+
+/** @} */
diff --git a/daemon/Common/NetlinkConnection.cpp b/MobiCoreDriverLib/Common/NetlinkConnection.cpp
old mode 100644
new mode 100755
similarity index 83%
rename from daemon/Common/NetlinkConnection.cpp
rename to MobiCoreDriverLib/Common/NetlinkConnection.cpp
index 4e475b6..f91d4e9
--- a/daemon/Common/NetlinkConnection.cpp
+++ b/MobiCoreDriverLib/Common/NetlinkConnection.cpp
@@ -4,31 +4,34 @@
  *
  * Connection data.
  *
- * <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
+ * Copyright (c) 2013 TRUSTONIC LIMITED
+ * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- *    products derived from this software without specific prior
- *    written permission.
  *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 3. Neither the name of the TRUSTONIC LIMITED nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 #include <stdlib.h>
 #include <unistd.h>
@@ -243,12 +246,18 @@
     //LOG_I("%s: send data %u to PID %u", __FUNCTION__, len, sequenceMagic);
 
     memset(&dest_addr, 0, sizeof(dest_addr));
+    memset(&msg, 0, sizeof(msghdr));
     dest_addr.nl_family = AF_NETLINK;
     dest_addr.nl_pid = peerPid;
     dest_addr.nl_groups = 0; /* unicast */
 
     nlh = (struct nlmsghdr *)malloc(
               NLMSG_SPACE(len));
+    if (nlh == NULL) {
+        LOG_E("Allocation failure");
+        return -1;
+    }
+
     /* Fill the netlink message header */
     nlh->nlmsg_len = NLMSG_SPACE(len);
     nlh->nlmsg_pid = selfPid;
diff --git a/daemon/Common/NetlinkConnection.h b/MobiCoreDriverLib/Common/NetlinkConnection.h
old mode 100644
new mode 100755
similarity index 82%
rename from daemon/Common/NetlinkConnection.h
rename to MobiCoreDriverLib/Common/NetlinkConnection.h
index 64e317e..5be3f30
--- a/daemon/Common/NetlinkConnection.h
+++ b/MobiCoreDriverLib/Common/NetlinkConnection.h
@@ -4,31 +4,34 @@
  *
  * Connection data.
  *
- * <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
+ * Copyright (c) 2013 TRUSTONIC LIMITED
+ * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- *    products derived from this software without specific prior
- *    written permission.
  *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 3. Neither the name of the TRUSTONIC LIMITED nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 #ifndef NETLINKCONNECTION_H_
 #define NETLINKCONNECTION_H_
diff --git a/daemon/Daemon/Android.mk b/MobiCoreDriverLib/Daemon/Android.mk
old mode 100644
new mode 100755
similarity index 91%
rename from daemon/Daemon/Android.mk
rename to MobiCoreDriverLib/Daemon/Android.mk
index 37d977a..de2c1a1
--- a/daemon/Daemon/Android.mk
+++ b/MobiCoreDriverLib/Daemon/Android.mk
@@ -13,3 +13,4 @@
 # Internal components
 include $(LOCAL_PATH)/Daemon/Device/Android.mk
 include $(LOCAL_PATH)/Daemon/Server/Android.mk
+include $(LOCAL_PATH)/Daemon/FSD/Android.mk
diff --git a/daemon/Daemon/Device/Android.mk b/MobiCoreDriverLib/Daemon/Device/Android.mk
old mode 100644
new mode 100755
similarity index 95%
rename from daemon/Daemon/Device/Android.mk
rename to MobiCoreDriverLib/Daemon/Device/Android.mk
index 2e8fc50..e830526
--- a/daemon/Daemon/Device/Android.mk
+++ b/MobiCoreDriverLib/Daemon/Device/Android.mk
@@ -19,6 +19,7 @@
 # Add new source files here
 LOCAL_SRC_FILES += $(DEVICE_PATH)/DeviceIrqHandler.cpp \
 	$(DEVICE_PATH)/DeviceScheduler.cpp \
+	$(DEVICE_PATH)/TAExitHandler.cpp \
 	$(DEVICE_PATH)/MobiCoreDevice.cpp \
 	$(DEVICE_PATH)/NotificationQueue.cpp \
 	$(DEVICE_PATH)/TrustletSession.cpp \
diff --git a/MobiCoreDriverLib/Daemon/Device/DeviceIrqHandler.cpp b/MobiCoreDriverLib/Daemon/Device/DeviceIrqHandler.cpp
new file mode 100755
index 0000000..877e2da
--- /dev/null
+++ b/MobiCoreDriverLib/Daemon/Device/DeviceIrqHandler.cpp
@@ -0,0 +1,48 @@
+/** @addtogroup MCD_MCDIMPL_DAEMON_DEV
+ * @{
+ * @file
+ *
+ *
+ * Copyright (c) 2013 TRUSTONIC LIMITED
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the TRUSTONIC LIMITED nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "DeviceIrqHandler.h"
+#include "log.h"
+
+//------------------------------------------------------------------------------
+void DeviceIrqHandler::run(
+    void
+)
+{
+    handleIrq();
+    this->exit(-1);
+}
+
+/** @} */
diff --git a/MobiCoreDriverLib/Daemon/Device/DeviceIrqHandler.h b/MobiCoreDriverLib/Daemon/Device/DeviceIrqHandler.h
new file mode 100755
index 0000000..449e2af
--- /dev/null
+++ b/MobiCoreDriverLib/Daemon/Device/DeviceIrqHandler.h
@@ -0,0 +1,55 @@
+/** @addtogroup MCD_MCDIMPL_DAEMON_DEV
+ * @{
+ * @file
+ *
+ * IRQ handler thread.
+ *
+ * Copyright (c) 2013 TRUSTONIC LIMITED
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the TRUSTONIC LIMITED nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DEVICEIRQHANDLER_H_
+#define DEVICEIRQHANDLER_H_
+
+#include "CThread.h"
+
+
+class DeviceIrqHandler: public CThread
+{
+
+public:
+
+    virtual void handleIrq() = 0;
+
+    void run();
+};
+
+#endif /* DEVICEIRQHANDLER_H_ */
+
+/** @} */
diff --git a/MobiCoreDriverLib/Daemon/Device/DeviceScheduler.cpp b/MobiCoreDriverLib/Daemon/Device/DeviceScheduler.cpp
new file mode 100755
index 0000000..1481c3c
--- /dev/null
+++ b/MobiCoreDriverLib/Daemon/Device/DeviceScheduler.cpp
@@ -0,0 +1,48 @@
+/** @addtogroup MCD_MCDIMPL_DAEMON_DEV
+ * @{
+ * @file
+ *
+ *
+ * Copyright (c) 2013 TRUSTONIC LIMITED
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the TRUSTONIC LIMITED nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "DeviceScheduler.h"
+
+
+//------------------------------------------------------------------------------
+void DeviceScheduler::run(
+    void
+)
+{
+    schedule();
+    exit(-1);
+}
+
+/** @} */
diff --git a/MobiCoreDriverLib/Daemon/Device/DeviceScheduler.h b/MobiCoreDriverLib/Daemon/Device/DeviceScheduler.h
new file mode 100755
index 0000000..3b818bf
--- /dev/null
+++ b/MobiCoreDriverLib/Daemon/Device/DeviceScheduler.h
@@ -0,0 +1,56 @@
+/** @addtogroup MCD_MCDIMPL_DAEMON_DEV
+ * @{
+ * @file
+ *
+ * Scheduler thread
+ *
+ * Copyright (c) 2013 TRUSTONIC LIMITED
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the TRUSTONIC LIMITED nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DEVICESCHEDULER_H_
+#define DEVICESCHEDULER_H_
+
+#include "CThread.h"
+
+
+class DeviceScheduler: public CThread
+{
+
+public:
+
+    virtual void schedule() = 0;
+
+    void run();
+
+};
+
+#endif /* DEVICESCHEDULER_H_ */
+
+/** @} */
diff --git a/daemon/Daemon/Device/MobiCoreDevice.cpp b/MobiCoreDriverLib/Daemon/Device/MobiCoreDevice.cpp
old mode 100644
new mode 100755
similarity index 61%
rename from daemon/Daemon/Device/MobiCoreDevice.cpp
rename to MobiCoreDriverLib/Daemon/Device/MobiCoreDevice.cpp
index ec404bf..1ec40f0
--- a/daemon/Daemon/Device/MobiCoreDevice.cpp
+++ b/MobiCoreDriverLib/Daemon/Device/MobiCoreDevice.cpp
@@ -4,35 +4,39 @@
  */
 
 /*
- * <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
+ * Copyright (c) 2013 TRUSTONIC LIMITED
+ * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- *    products derived from this software without specific prior
- *    written permission.
  *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 3. Neither the name of the TRUSTONIC LIMITED nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 #include <cstdlib>
 #include <pthread.h>
+#include <assert.h>
 #include "McTypes.h"
 
 #include "DeviceScheduler.h"
@@ -50,6 +54,7 @@
 #include "public/MobiCoreDevice.h"
 
 
+
 //------------------------------------------------------------------------------
 MobiCoreDevice::MobiCoreDevice()
 {
@@ -58,6 +63,7 @@
     mcVersionInfo = NULL;
     mcFault = false;
     mciReused = false;
+    mcpMessage = NULL;
 }
 
 //------------------------------------------------------------------------------
@@ -77,10 +83,9 @@
 ) {
     for (trustletSessionIterator_t iterator = trustletSessions.begin();
          iterator != trustletSessions.end();
-         ++iterator) 
+         ++iterator)
     {
         TrustletSession *session = *iterator;
-
         if (session->sessionId == sessionId) {
             return session;
         }
@@ -90,24 +95,26 @@
 
 
 //------------------------------------------------------------------------------
-Connection *MobiCoreDevice::getSessionConnection(
-    uint32_t sessionId, 
-    notification_t *notification
-) {
-    Connection *con = NULL;
-
-    TrustletSession *session = getTrustletSession(sessionId);
-    if (session != NULL) 
-    {
-        con = session->notificationConnection;
-        if (con == NULL) 
-        {
-            session->queueNotification(notification);
-        }
-    }
-
-    return con;
-}
+//Connection *MobiCoreDevice::getSessionConnection(
+//    uint32_t sessionId,
+//    notification_t *notification
+//) {
+//    Connection *con = NULL;
+//
+//    mutex_tslist.lock();
+//    TrustletSession *session = getTrustletSession(sessionId);
+//    if (session != NULL)
+//    {
+//        con = session->notificationConnection;
+//        if (con == NULL)
+//        {
+//            session->queueNotification(notification);
+//        }
+//    }
+//    mutex_tslist.unlock();
+//
+//    return con;
+//}
 
 
 //------------------------------------------------------------------------------
@@ -115,20 +122,22 @@
     Connection *deviceConnection,
     uint32_t sessionId
 ) {
+    mutex_tslist.lock();
     TrustletSession *session = getTrustletSession(sessionId);
-    if (session == NULL) 
+    if (session == NULL)
     {
         LOG_E("no session found with id=%d", sessionId);
     }
     else
-    {    
+    {
         // check is connection own this session
-        if (session->deviceConnection != deviceConnection) 
+        if (session->deviceConnection != deviceConnection)
         {
             LOG_E("connection does not own session id=%d", sessionId);
             session = NULL;
         }
     }
+    mutex_tslist.unlock();
     return session;
 }
 
@@ -144,7 +153,7 @@
 
 //------------------------------------------------------------------------------
 // send a close session message. Used in three cases:
-// 1) during init to tell SWd to invalidate this session, if it is still open 
+// 1) during init to tell SWd to invalidate this session, if it is still open
 //    from a prev Daemon instance
 // 2) normal session close
 // 3) close all session when Daemon terminates
@@ -187,20 +196,19 @@
         return MAKE_MC_DRV_MCP_ERROR(mcRet);
     }
 
-    // clean session WSM
-    LOG_I("unlocking session buffers!");
-    CWsm_ptr pWsm = session->popBulkBuff();
-    while (pWsm) 
-    {
-        unlockWsmL2(pWsm->handle);
-        delete pWsm;
-        pWsm = session->popBulkBuff();
-    }
+//    // clean session WSM
+//    LOG_I("unlocking session buffers!");
+//    CWsm_ptr pWsm = session->popBulkBuff();
+//    while (pWsm)
+//    {
+//        unlockWsmL2(pWsm->handle);
+//        delete pWsm;
+//        pWsm = session->popBulkBuff();
+//    }
 
     return MC_DRV_OK;
 }
 
-
 //------------------------------------------------------------------------------
 /**
  * Close device.
@@ -212,7 +220,7 @@
 void MobiCoreDevice::close(
     Connection *connection
 ) {
-    // static mutex is the the same for each thread. So this serializes 
+    // static mutex is the the same for each thread. So this serializes
     // multiple connections failing at the same time.
     static CMutex mutex;
     // Enter critical section
@@ -222,43 +230,44 @@
     // 2. Decide what to do with open Trustlet sessions
     // 3. Remove & delete deviceSession from vector
 
-    // iterating over the list in reverse order, as the LIFO approach may 
+    // iterating over the list in reverse order, as the LIFO approach may
     // avoid some quirks. The assumption is that a driver is opened before a
     // TA, so we want to terminate the TA first and then the driver. This may
-    // make this a bit easier for everbody. 
+    // make this a bit easier for everbody.
 
     trustletSessionList_t::reverse_iterator revIt = trustletSessions.rbegin();
     while (revIt != trustletSessions.rend())
     {
-        TrustletSession *session = *revIt; 
+        TrustletSession *session = *revIt;
 
         // wiredness of reverse iterators
         // * is is incremented to get the next lowe element
-        // * to delete something from the list, we need the "normal" iterator. 
+        // * to delete something from the list, we need the "normal" iterator.
         //   This is simpy "one off" the current revIt. So we can savely use
-        //   the increment below in both cases. 
+        //   the increment below in both cases.
         revIt++;
 
-        if (session->deviceConnection == connection) 
+        if (session->deviceConnection == connection)
         {
             // close session, log any error but ignore it.
-            mcResult_t mcRet = closeSessionInternal(session);
+            //mcResult_t mcRet = closeSessionInternal(session);
+            mcResult_t mcRet = closeSession(connection, session->sessionId);
             if (mcRet != MC_MCP_RET_OK) {
                 LOG_I("device closeSession failed with %d", mcRet);
             }
 
-            // removing an element from the list it tricky. Convert the revIt 
+            // removing an element from the list it tricky. Convert the revIt
             // to a "normal" iterator. Remember here that the revIt is one off,
-            // but we have done an increment above, so we are fine here. So 
+            // but we have done an increment above, so we are fine here. So
             // after we have the normal iterator, ude it to delete and then
             // convert the returned iterator back to a reverse iterator, which
-            // we will use for the loop. 
-            trustletSessionIterator_t it = revIt.base();
-            it = trustletSessions.erase(it); // delete 
-            revIt =  trustletSessionList_t::reverse_iterator(it);
+            // we will use for the loop.
+            //trustletSessionIterator_t it = revIt.base();
+            //it = trustletSessions.erase(it); // delete
+            //revIt =  trustletSessionList_t::reverse_iterator(it);
 
-            // free object 
-            delete session;
+            // free object
+            //delete session;
         }
     }
 
@@ -269,7 +278,12 @@
     // all the orphaned drivers
     cleanupWsmL2();
 
+
+
     connection->connectionData = NULL;
+
+    // Leave critical section
+    mutex.unlock();
 }
 
 
@@ -278,9 +292,9 @@
 {
     LOG_I("Starting DeviceIrqHandler...");
     // Start the irq handling thread
-    DeviceIrqHandler::start();
+    DeviceIrqHandler::start("DevIrqHandler");
 
-    if (schedulerAvailable()) 
+    if (schedulerAvailable())
     {
         LOG_I("Starting DeviceScheduler...");
         // Start the scheduling handling thread
@@ -291,10 +305,13 @@
         LOG_I("No DeviceScheduler available.");
     }
 
-    if (mciReused) 
+    LOG_I("Starting TAExitHandler...");
+    TAExitHandler::start("TAExitHandler");
+
+    if (mciReused)
     {
-        // remove all pending sessions. 20 is as good a any other number, we 
-        // actually should ass a MCP message that tells SWd to invalidate all 
+        // remove all pending sessions. 20 is as good a any other number, we-
+        // actually should ass a MCP message that tells SWd to invalidate all-
         // session that are there besides the MSH session.
         for (int sessionId = 2; sessionId<20; sessionId++) {
             LOG_I("invalidating session %d",sessionId);
@@ -320,53 +337,60 @@
 bool MobiCoreDevice::waitMcpNotification(void)
 {
     int counter = 5; // retry 5 times
-    while (1) 
-    {
+    while (1)
+	{
         // In case of fault just return, nothing to do here
-        if (mcFault) 
-        {
+        if (mcFault)
+		{
             return false;
         }
         // Wait 10 seconds for notification
-        if ( mcpSessionNotification.wait(10) ) 
-        {
-            break; // seem we got one.
+        if ( mcpSessionNotification.wait(10) )
+		{
+			break; // seem we got one.
         }
         // No MCP answer received and mobicore halted, dump mobicore status
         // then throw exception
         LOG_I("No MCP answer received in 2 seconds.");
-        if (getMobicoreStatus() == MC_STATUS_HALT) 
-        {
+        if (getMobicoreStatus() == MC_STATUS_HALT)
+		{
             dumpMobicoreStatus();
             mcFault = true;
             return false;
         }
 
         counter--;
-        if (counter < 1) 
-        {
+        if (counter < 1)
+		{
             mcFault = true;
             return false;
         }
     } // while(1)
-            // Check healthiness state of the device
-            if (DeviceIrqHandler::isExiting()) 
-            {
-                LOG_I("waitMcpNotification(): IrqHandler thread died! Joining");
-                DeviceIrqHandler::join();
-                LOG_I("waitMcpNotification(): Joined");
-                LOG_E("IrqHandler thread died!");
-                return false;
-            }
 
-            if (DeviceScheduler::isExiting()) 
-            {
-                LOG_I("waitMcpNotification(): Scheduler thread died! Joining");
-                DeviceScheduler::join();
-                LOG_I("waitMcpNotification(): Joined");
-                LOG_E("Scheduler thread died!");
-                return false;
-            }
+    // Check healthiness state of the device
+    if (DeviceIrqHandler::isExiting()) {
+        LOG_I("waitMcpNotification(): IrqHandler thread died! Joining");
+        DeviceIrqHandler::join();
+        LOG_I("waitMcpNotification(): Joined");
+        LOG_E("IrqHandler thread died!");
+        return false;
+    }
+
+    if (DeviceScheduler::isExiting()) {
+        LOG_I("waitMcpNotification(): Scheduler thread died! Joining");
+        DeviceScheduler::join();
+        LOG_I("waitMcpNotification(): Joined");
+        LOG_E("Scheduler thread died!");
+        return false;
+    }
+
+    if (TAExitHandler::isExiting()) {
+        LOG_I("waitMcpNotification(): TAExitHandler thread died! Joining");
+        TAExitHandler::join();
+        LOG_I("waitMcpNotification(): Joined");
+        LOG_E("TAExitHandler thread died!");
+        return false;
+    }
     return true;
 }
 
@@ -378,7 +402,7 @@
     notify(SID_MCP);
 
     // Wait till response from MSH is available
-    if (!waitMcpNotification()) 
+    if (!waitMcpNotification())
     {
         LOG_E("waiting for MCP notification failed");
         return MC_DRV_ERR_DAEMON_MCI_ERROR;
@@ -397,50 +421,53 @@
     mcDrvRspOpenSessionPayload_ptr  pRspOpenSessionPayload)
 {
     do {
-        addr_t tci;
-        uint32_t len;
+        uint64_t tci = 0;
+        uint32_t len = 0;
 
-        // Check if we have a cont WSM or normal one
-        if (findContiguousWsm(tciHandle, deviceConnection->socketDescriptor, &tci, &len)) {
-            mcpMessage->cmdOpen.wsmTypeTci = WSM_CONTIGUOUS;
-            mcpMessage->cmdOpen.adrTciBuffer = (uint32_t)(tci);
-            mcpMessage->cmdOpen.ofsTciBuffer = 0;
-        }
-        else if((tci = findWsmL2(tciHandle, deviceConnection->socketDescriptor))) {
-            // We don't actually care about the len as the L2 table mapping is done
-            // and the TL will segfault if it's trying to access non-allocated memory
-            len = tciLen;
-            mcpMessage->cmdOpen.wsmTypeTci = WSM_L2;
+        if (tciHandle != 0 && tciLen != 0) {
+            // Check if we have a cont WSM or normal one
+            if (findContiguousWsm(tciHandle,
+                                  deviceConnection->socketDescriptor, &tci, &len)) {
+                mcpMessage->cmdOpen.wsmTypeTci = WSM_CONTIGUOUS;
+            mcpMessage->cmdOpen.adrTciBuffer = tci;
+                mcpMessage->cmdOpen.ofsTciBuffer = 0;
+            } else if ((tci = findWsmL2(tciHandle, deviceConnection->socketDescriptor))) {
+                // We don't actually care about the len as the L2 table mapping is done
+                // // and the TL will segfault if it's trying to access non-allocated memory
+                len = tciLen;
+                mcpMessage->cmdOpen.wsmTypeTci = WSM_L2;
+            mcpMessage->cmdOpen.adrTciBuffer = tci;
+                mcpMessage->cmdOpen.ofsTciBuffer = tciOffset;
+            } else {
+                LOG_E("Failed to find contiguous WSM %u", tciHandle);
+                return MC_DRV_ERR_DAEMON_WSM_HANDLE_NOT_FOUND;
+            }
+
+            if (!lockWsmL2(tciHandle)) {
+                LOG_E("Failed to lock contiguous WSM %u", tciHandle);
+                return MC_DRV_ERR_DAEMON_WSM_HANDLE_NOT_FOUND;
+            }
+        } else if (tciHandle == 0 && tciLen == 0) {
+            mcpMessage->cmdOpen.wsmTypeTci = WSM_INVALID;
             mcpMessage->cmdOpen.adrTciBuffer = (uint32_t)(tci);
             mcpMessage->cmdOpen.ofsTciBuffer = tciOffset;
         }
-        else {
-            LOG_E("Failed to find contiguous WSM %u", tciHandle);
-            return MC_DRV_ERR_DAEMON_WSM_HANDLE_NOT_FOUND;
-        }
 
-
-        if (!lockWsmL2(tciHandle)) {
-            LOG_E("Failed to lock contiguous WSM %u", tciHandle);
-            return MC_DRV_ERR_DAEMON_WSM_HANDLE_NOT_FOUND;
-        }
-
-        if (tciLen == 0 ||  tciLen > len) {
-            LOG_E("Invalid TCI len from client %u, driver = %u",
-                  pLoadDataOpenSession->len, len);
+        if ((tciHandle != 0 && tciLen == 0) || tciLen > len) {
+            LOG_E("Invalid TCI len from client - %u, tciHandle %d, Wsm len found %u",
+                  tciLen, tciHandle, len);
             return MC_DRV_ERR_TCI_GREATER_THAN_WSM;
         }
 
-
         // Write MCP open message to buffer
         mcpMessage->cmdOpen.cmdHeader.cmdId = MC_MCP_CMD_OPEN_SESSION;
         mcpMessage->cmdOpen.uuid = pLoadDataOpenSession->tlHeader->mclfHeaderV2.uuid;
         mcpMessage->cmdOpen.lenTciBuffer = tciLen;
-        LOG_I(" Using phys=%p, len=%d as TCI buffer", (addr_t)tci, tciLen);
+        LOG_I(" Using phys=%#llx, len=%d as TCI buffer", (uint64_t)tci, tciLen);
 
         // check if load data is provided
         mcpMessage->cmdOpen.wsmTypeLoadData = WSM_L2;
-        mcpMessage->cmdOpen.adrLoadData = (uint32_t)pLoadDataOpenSession->baseAddr;
+        mcpMessage->cmdOpen.adrLoadData = pLoadDataOpenSession->baseAddr;
         mcpMessage->cmdOpen.ofsLoadData = pLoadDataOpenSession->offs;
         mcpMessage->cmdOpen.lenLoadData = pLoadDataOpenSession->len;
         memcpy(&mcpMessage->cmdOpen.tlHeader, pLoadDataOpenSession->tlHeader, sizeof(*pLoadDataOpenSession->tlHeader));
@@ -454,7 +481,7 @@
         {
             LOG_E("mshNotifyAndWait failed for OPEN_SESSION, code %d.", mcRet);
             // Here Mobicore can be considered dead.
-            if ((tciHandle != 0) && (tciLen != 0)) 
+            if ((tciHandle != 0) && (tciLen != 0))
             {
                 unlockWsmL2(tciHandle);
             }
@@ -466,7 +493,9 @@
             LOG_E("CMD_OPEN_SESSION got invalid MCP command response(0x%X)", mcpMessage->rspHeader.rspId);
             // Something is messing with our MCI memory, we cannot know if the Trustlet was loaded.
             // Had in been loaded, we are loosing track of it here.
-            unlockWsmL2(tciHandle);
+            if (tciHandle != 0 && tciLen != 0) {
+                unlockWsmL2(tciHandle);
+            }
             return MC_DRV_ERR_DAEMON_MCI_ERROR;
         }
 
@@ -474,7 +503,9 @@
 
         if (mcRet != MC_MCP_RET_OK) {
             LOG_E("MCP OPEN returned code %d.", mcRet);
-            unlockWsmL2(tciHandle);
+            if (tciHandle != 0 && tciLen != 0) {
+                unlockWsmL2(tciHandle);
+            }
             return MAKE_MC_DRV_MCP_ERROR(mcRet);
         }
 
@@ -489,9 +520,17 @@
         pRspOpenSessionPayload->deviceSessionId = (uint32_t)trustletSession;
         pRspOpenSessionPayload->sessionMagic = trustletSession->sessionMagic;
 
-        trustletSessions.push_back(trustletSession);
+        trustletSession->gp_level=((mclfHeaderV24_ptr)&pLoadDataOpenSession->tlHeader->mclfHeaderV2)->gp_level;
+        LOG_I(" Trusted App has gp_level %d",trustletSession->gp_level);
+        trustletSession->sessionState = TrustletSession::TS_TA_RUNNING;
 
-        trustletSession->addBulkBuff(new CWsm((void *)pLoadDataOpenSession->offs, pLoadDataOpenSession->len, tciHandle, 0));
+        mutex_tslist.lock();
+        trustletSessions.push_back(trustletSession);
+        mutex_tslist.unlock();
+
+        if (tciHandle != 0 && tciLen != 0) {
+            trustletSession->addBulkBuff(new CWsm((void *)pLoadDataOpenSession->offs, pLoadDataOpenSession->len, tciHandle, 0));
+        }
 
         // We have some queued notifications and we need to send them to them
         // trustlet session
@@ -504,6 +543,56 @@
     return MC_DRV_OK;
 }
 
+mcResult_t MobiCoreDevice::checkLoad(
+    loadDataOpenSession_ptr         pLoadDataOpenSession,
+    mcDrvRspOpenSessionPayload_ptr  pRspOpenSessionPayload)
+{
+    do {
+        // Write MCP open message to buffer
+        mcpMessage->cmdCheckLoad.cmdHeader.cmdId = MC_MCP_CMD_CHECK_LOAD_TA;
+        mcpMessage->cmdCheckLoad.uuid = pLoadDataOpenSession->tlHeader->mclfHeaderV2.uuid;
+
+        // check if load data is provided
+        mcpMessage->cmdCheckLoad.wsmTypeLoadData = WSM_L2;
+        mcpMessage->cmdCheckLoad.adrLoadData = pLoadDataOpenSession->baseAddr;
+        mcpMessage->cmdCheckLoad.ofsLoadData = pLoadDataOpenSession->offs;
+        mcpMessage->cmdCheckLoad.lenLoadData = pLoadDataOpenSession->len;
+        memcpy(&mcpMessage->cmdCheckLoad.tlHeader, pLoadDataOpenSession->tlHeader, sizeof(*pLoadDataOpenSession->tlHeader));
+
+        // Clear the notifications queue. We asume the race condition we have
+        // seen in openSession never happens elsewhere
+        notifications = std::queue<notification_t>();
+
+        mcResult_t mcRet = mshNotifyAndWait();
+        if (mcRet != MC_MCP_RET_OK)
+        {
+            LOG_E("mshNotifyAndWait failed for CHECK_LOAD_TA, code %d.", mcRet);
+            // Here Mobicore can be considered dead.
+            return mcRet;
+        }
+
+        // Check if the command response ID is correct
+        if ((MC_MCP_CMD_CHECK_LOAD_TA | FLAG_RESPONSE) != mcpMessage->rspHeader.rspId) {
+            LOG_E("CMD_OPEN_SESSION got invalid MCP command response(0x%X)", mcpMessage->rspHeader.rspId);
+            // Something is messing with our MCI memory, we cannot know if the Trustlet was loaded.
+            // Had in been loaded, we are loosing track of it here.
+
+            return MC_DRV_ERR_DAEMON_MCI_ERROR;
+        }
+
+        mcRet = mcpMessage->rspCheckLoad.rspHeader.result;
+
+        if (mcRet != MC_MCP_RET_OK) {
+            LOG_E("MCP CHECK_LOAD returned code %d.", mcRet);
+            return MAKE_MC_DRV_MCP_ERROR(mcRet);
+        }
+        return MC_DRV_OK;
+
+    } while (0);
+    return MC_DRV_ERR_UNKNOWN;
+}
+
+
 
 //------------------------------------------------------------------------------
 TrustletSession *MobiCoreDevice::registerTrustletConnection(
@@ -517,9 +606,10 @@
           cmdNqConnect->sessionId,
           cmdNqConnect->sessionMagic);
 
+    mutex_tslist.lock();
     for (trustletSessionIterator_t iterator = trustletSessions.begin();
          iterator != trustletSessions.end();
-         ++iterator) 
+         ++iterator)
     {
         TrustletSession *session = *iterator;
 
@@ -536,8 +626,10 @@
 
         LOG_I(" Found Service session, registered connection.");
 
+        mutex_tslist.unlock();
         return session;
     }
+    mutex_tslist.unlock();
 
     LOG_I("registerTrustletConnection(): search failed");
     return NULL;
@@ -550,7 +642,7 @@
  * close sessions not belonging to him.
  */
 mcResult_t MobiCoreDevice::closeSession(
-    Connection  *deviceConnection, 
+    Connection  *deviceConnection,
     uint32_t    sessionId
 ) {
     TrustletSession *session = findSession(deviceConnection,sessionId);
@@ -559,25 +651,67 @@
         return MC_DRV_ERR_DAEMON_UNKNOWN_SESSION;
     }
 
+    if (session->gp_level == 1) {
+        mutex_connection.lock();
+        LOG_I(" Closing GP TA session...");
+        // Disconnect client from this session
+        session->deviceConnection = NULL;
+        // Free connection, i.e. close nq socket
+        delete session->notificationConnection;
+        session->notificationConnection = NULL;
+        // If exit notification from task arrives during MCP_CLOSE,
+        // Daemon can see that CA is already away
+        session->sessionState = TrustletSession::TS_CLOSE_SEND;
+        mutex_connection.unlock();
+    }
+
     /* close session */
     mcResult_t mcRet = closeSessionInternal(session);
+
+    if ((session->gp_level==1) && (mcRet == MAKE_MC_DRV_MCP_ERROR(MC_MCP_RET_ERR_CLOSE_TASK_FAILED))) {
+        LOG_I(" Close session failed this time.");
+        // We could have received a spurious notification of TA dead
+        if (session->sessionState == TrustletSession::TS_TA_DEAD) {
+            LOG_V(" TA died in the meantime, try closing again");
+            // Try again
+            mcRet = closeSessionInternal(session);
+            assert(mcRet == MC_MCP_RET_OK);
+        } else {
+            // Clean up is deferred to handleTaExit()
+            return MC_MCP_RET_OK;
+        }
+    }
+
     if (mcRet != MC_MCP_RET_OK) {
         LOG_E("closeSession failed with %d", mcRet);
         return MAKE_MC_DRV_MCP_ERROR(mcRet);
     }
 
-    // remove sesson from list. 
+
+    // clean session WSM
+    LOG_I("unlocking session buffers!");
+    CWsm_ptr pWsm = session->popBulkBuff();
+    while (pWsm)
+    {
+        unlockWsmL2(pWsm->handle);
+        delete pWsm;
+        pWsm = session->popBulkBuff();
+    }
+
+    // remove sesson from list.
+    mutex_tslist.lock();
     for (trustletSessionIterator_t iterator = trustletSessions.begin();
          iterator != trustletSessions.end();
-         ++iterator) 
+         ++iterator)
     {
-        if (session == *iterator) 
+        if (session == *iterator)
         {
             trustletSessions.erase(iterator);
             delete session;
             break;
         }
     }
+    mutex_tslist.unlock();
 
     return MC_MCP_RET_OK;
 }
@@ -585,19 +719,18 @@
 
 //------------------------------------------------------------------------------
 void MobiCoreDevice::queueUnknownNotification(
-    notification_t notification
+     notification_t notification
 ) {
     notifications.push(notification);
 }
 
-
 //------------------------------------------------------------------------------
 mcResult_t MobiCoreDevice::notify(
-    Connection  *deviceConnection, 
+    Connection  *deviceConnection,
     uint32_t    sessionId
 ) {
     TrustletSession *session = findSession(deviceConnection,sessionId);
-    if (session == NULL) 
+    if (session == NULL)
     {
         LOG_E("cannot notify session with id=%d", sessionId);
         return MC_DRV_ERR_DAEMON_UNKNOWN_SESSION;
@@ -608,15 +741,14 @@
     return MC_DRV_OK;
 }
 
-
 //------------------------------------------------------------------------------
 mcResult_t MobiCoreDevice::mapBulk(
-    Connection *deviceConnection, 
-    uint32_t  sessionId, 
-    uint32_t  handle, 
-    uint32_t  pAddrL2,
-    uint32_t  offsetPayload, 
-    uint32_t  lenBulkMem, 
+    Connection *deviceConnection,
+    uint32_t  sessionId,
+    uint32_t  handle,
+    uint64_t  pAddrL2,
+    uint32_t  offsetPayload,
+    uint32_t  lenBulkMem,
     uint32_t  *secureVirtualAdr
 ) {
     TrustletSession *session = findSession(deviceConnection,sessionId);
@@ -628,16 +760,16 @@
     // TODO-2012-09-06-haenellu: considernot ignoring the error case, ClientLib
     //                           does not allow this.
     session->addBulkBuff(
-                new CWsm((void *)offsetPayload, 
-                lenBulkMem, 
-                handle, 
-                (void *)pAddrL2));
+                new CWsm((void *)offsetPayload,
+                lenBulkMem,
+                handle,
+                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.adrBuffer = pAddrL2;
     mcpMessage->cmdMap.ofsBuffer = offsetPayload;
     mcpMessage->cmdMap.lenBuffer = lenBulkMem;
 
@@ -668,10 +800,10 @@
 
 //------------------------------------------------------------------------------
 mcResult_t MobiCoreDevice::unmapBulk(
-    Connection  *deviceConnection, 
-    uint32_t    sessionId, 
+    Connection  *deviceConnection,
+    uint32_t    sessionId,
     uint32_t    handle,
-    uint32_t    secureVirtualAdr, 
+    uint32_t    secureVirtualAdr,
     uint32_t    lenBulkMem
 ) {
     TrustletSession *session = findSession(deviceConnection,sessionId);
@@ -680,6 +812,11 @@
         return MC_DRV_ERR_DAEMON_UNKNOWN_SESSION;
     }
 
+    if (!session->findBulkBuff(handle, lenBulkMem)) {
+        LOG_E("cannot unmapBulk with handle=%d", handle);
+        return MC_DRV_ERR_DAEMON_WSM_HANDLE_NOT_FOUND;       
+    }
+
     // Write MCP unmap command to buffer
     mcpMessage->cmdUnmap.cmdHeader.cmdId = MC_MCP_CMD_UNMAP;
     mcpMessage->cmdUnmap.sessionId = sessionId;
@@ -717,75 +854,21 @@
     return MC_DRV_OK;
 }
 
-
-//------------------------------------------------------------------------------
-void MobiCoreDevice::donateRam(const uint32_t donationSize)
-{
-    // Donate additional RAM to the MobiCore
-    CWsm_ptr ram = allocateContiguousPersistentWsm(donationSize);
-    if (NULL == ram) {
-        LOG_E("Allocation of additional RAM failed");
-        return;
-    }
-    ramType_t ramType = RAM_GENERIC;
-    addr_t adrBuffer = ram->physAddr;
-    const uint32_t numPages = donationSize / (4 * 1024);
-
-
-    LOG_I("donateRam(): adrBuffer=%p, numPages=%d, ramType=%d",
-          adrBuffer,
-          numPages,
-          ramType);
-
-    do {
-        // Write MCP open message to buffer
-        mcpMessage->cmdDonateRam.cmdHeader.cmdId = MC_MCP_CMD_DONATE_RAM;
-        mcpMessage->cmdDonateRam.adrBuffer = (uint32_t) adrBuffer;
-        mcpMessage->cmdDonateRam.numPages = numPages;
-        mcpMessage->cmdDonateRam.ramType = ramType;
-
-        // Notify MC about a new command inside the MCP buffer
-        notify(SID_MCP);
-
-        // Wait till response from MC is available
-        if (!waitMcpNotification()) {
-            break;
-        }
-
-        // Check if the command response ID is correct
-        if ((MC_MCP_CMD_DONATE_RAM | FLAG_RESPONSE) != mcpMessage->rspHeader.rspId) {
-            LOG_E("donateRam(): CMD_DONATE_RAM got invalid MCP response - rspId is: %d",
-                  mcpMessage->rspHeader.rspId);
-            break;
-        }
-
-        uint32_t mcRet = mcpMessage->rspDonateRam.rspHeader.result;
-        if (MC_MCP_RET_OK != mcRet) {
-            LOG_E("donateRam(): CMD_DONATE_RAM error %d", mcRet);
-            break;
-        }
-
-        LOG_I("donateRam() succeeded.");
-
-    } while (0);
-}
-
-//------------------------------------------------------------------------------
 mcResult_t MobiCoreDevice::getMobiCoreVersion(
     mcDrvRspGetMobiCoreVersionPayload_ptr pRspGetMobiCoreVersionPayload
 ) {
     // retunt info it we have already fetched it before
-    if (mcVersionInfo != NULL) 
+    if (mcVersionInfo != NULL)
     {
         pRspGetMobiCoreVersionPayload->versionInfo = *mcVersionInfo;
         return MC_DRV_OK;
-    } 
+    }
 
-    // Write MCP command to buffer
+    // Write MCP unmap command to buffer
     mcpMessage->cmdGetMobiCoreVersion.cmdHeader.cmdId = MC_MCP_CMD_GET_MOBICORE_VERSION;
 
     mcResult_t mcRet = mshNotifyAndWait();
-    if (mcRet != MC_MCP_RET_OK) 
+    if (mcRet != MC_MCP_RET_OK)
     {
         LOG_E("mshNotifyAndWait failed for GET_MOBICORE_VERSION, code %d.", mcRet);
         return mcRet;
@@ -812,4 +895,48 @@
     return MC_DRV_OK;
 }
 
+//------------------------------------------------------------------------------
+mcResult_t MobiCoreDevice::loadToken(Connection        *deviceConnection,
+                                     loadTokenData_ptr pLoadTokenData)
+{
+    do {
+        mcpMessage->cmdLoadToken.cmdHeader.cmdId = MC_MCP_CMD_LOAD_TOKEN;
+        mcpMessage->cmdLoadToken.wsmTypeLoadData = WSM_L2;
+        mcpMessage->cmdLoadToken.adrLoadData = (uint32_t) pLoadTokenData->addr;
+        mcpMessage->cmdLoadToken.ofsLoadData = pLoadTokenData->offs;
+        mcpMessage->cmdLoadToken.lenLoadData = pLoadTokenData->len;
+
+        /* Clear the notifications queue. We asume the race condition we have
+         * seen in openSession never happens elsewhere
+         */
+        notifications = std::queue<notification_t>();
+
+        mcResult_t mcRet = mshNotifyAndWait();
+        if (mcRet != MC_MCP_RET_OK)
+        {
+            LOG_E("mshNotifyAndWait failed for LOAD_TOKEN, code 0x%x.", mcRet);
+            /* Here <t-base can be considered dead. */
+            return mcRet;
+        }
+
+        /* Check if the command response ID is correct */
+        if ((MC_MCP_CMD_LOAD_TOKEN | FLAG_RESPONSE) !=
+            mcpMessage->rspHeader.rspId) {
+            LOG_E("CMD_LOAD_TOKEN got invalid MCP command response(0x%X)",
+                  mcpMessage->rspHeader.rspId);
+            return MC_DRV_ERR_DAEMON_MCI_ERROR;
+        }
+
+        mcRet = mcpMessage->rspLoadToken.rspHeader.result;
+
+        if (mcRet != MC_MCP_RET_OK) {
+            LOG_E("MCP LOAD_TOKEN returned code 0x%x.", mcRet);
+            return MAKE_MC_DRV_MCP_ERROR(mcRet);
+        }
+
+    } while (0);
+
+    return MC_DRV_OK;
+}
+
 /** @} */
diff --git a/MobiCoreDriverLib/Daemon/Device/NotificationQueue.cpp b/MobiCoreDriverLib/Daemon/Device/NotificationQueue.cpp
new file mode 100755
index 0000000..a034c4c
--- /dev/null
+++ b/MobiCoreDriverLib/Daemon/Device/NotificationQueue.cpp
@@ -0,0 +1,82 @@
+/** @addtogroup MCD_MCDIMPL_DAEMON_DEV
+ * @{
+ * @file
+ *
+ *
+ * Copyright (c) 2013 TRUSTONIC LIMITED
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the TRUSTONIC LIMITED nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "NotificationQueue.h"
+#include <stddef.h>
+
+#include "log.h"
+
+//------------------------------------------------------------------------------
+NotificationQueue::NotificationQueue(
+    notificationQueue_t *i,
+    notificationQueue_t *o,
+    uint32_t size
+) : in(i), out(o)
+{
+    in->hdr.queueSize = size;
+    out->hdr.queueSize = size;
+}
+
+
+//------------------------------------------------------------------------------
+void NotificationQueue::putNotification(
+    notification_t *notification
+)
+{
+    mutex.lock();
+    if ((out->hdr.writeCnt - out->hdr.readCnt) < out->hdr.queueSize) {
+        out->notification[out->hdr.writeCnt & (out->hdr.queueSize - 1)]
+        = *notification;
+        out->hdr.writeCnt++;
+    }
+    mutex.unlock();
+}
+
+
+//------------------------------------------------------------------------------
+notification_t *NotificationQueue::getNotification(
+    void
+)
+{
+    notification_t *ret = NULL;
+    mutex.lock();
+    if ((in->hdr.writeCnt - in->hdr.readCnt) > 0) {
+        ret = &(in->notification[in->hdr.readCnt & (in->hdr.queueSize - 1)]);
+        in->hdr.readCnt++;
+    }
+    mutex.unlock();
+    return ret;
+}
+
+/** @} */
diff --git a/MobiCoreDriverLib/Daemon/Device/NotificationQueue.h b/MobiCoreDriverLib/Daemon/Device/NotificationQueue.h
new file mode 100755
index 0000000..cd004bb
--- /dev/null
+++ b/MobiCoreDriverLib/Daemon/Device/NotificationQueue.h
@@ -0,0 +1,90 @@
+/** @addtogroup MCD_MCDIMPL_DAEMON_DEV
+ * @{
+ * @file
+ *
+ * MobiCore Notification Queue handling.
+ *
+ * Copyright (c) 2013 TRUSTONIC LIMITED
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the TRUSTONIC LIMITED nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef NOTIFICATIONQUEUE_H_
+#define NOTIFICATIONQUEUE_H_
+
+#include <inttypes.h> //C99 data
+#include "Mci/mcinq.h"
+#include "CMutex.h"
+
+
+class NotificationQueue
+{
+
+public:
+
+    /** NQ Constructor, initializes the NQ component.
+     *
+     * makes the given queue object usable with the queue<Command> type of functions
+     *
+     * @param in queue to initialize
+     * @param out beginning of queue header
+     * @param queueSize Size of the queue
+     */
+    NotificationQueue(
+        notificationQueue_t *in,
+        notificationQueue_t *out,
+        uint32_t size
+    );
+
+    /** Places an element to the outgoing queue.
+     *
+     * @param notification Data to be placed in queue.
+     */
+    void putNotification(
+        notification_t *notification
+    );
+
+    /** Retrieves the first element from the queue.
+     *
+     * @return first notification Queue element.
+     * @return NULL if the queue is empty.
+     */
+    notification_t *getNotification(
+        void
+    );
+
+private:
+
+    notificationQueue_t *in;
+    notificationQueue_t *out;
+    CMutex mutex;
+
+};
+
+#endif /* NOTIFICATIONQUEUE_H_ */
+
+/** @} */
diff --git a/daemon/Daemon/Device/Platforms/Android.mk b/MobiCoreDriverLib/Daemon/Device/Platforms/Android.mk
old mode 100644
new mode 100755
similarity index 100%
rename from daemon/Daemon/Device/Platforms/Android.mk
rename to MobiCoreDriverLib/Daemon/Device/Platforms/Android.mk
diff --git a/daemon/Daemon/Device/Platforms/Generic/Android.mk b/MobiCoreDriverLib/Daemon/Device/Platforms/Generic/Android.mk
old mode 100644
new mode 100755
similarity index 100%
rename from daemon/Daemon/Device/Platforms/Generic/Android.mk
rename to MobiCoreDriverLib/Daemon/Device/Platforms/Generic/Android.mk
diff --git a/daemon/Daemon/Device/Platforms/Generic/TrustZoneDevice.cpp b/MobiCoreDriverLib/Daemon/Device/Platforms/Generic/TrustZoneDevice.cpp
old mode 100644
new mode 100755
similarity index 60%
rename from daemon/Daemon/Device/Platforms/Generic/TrustZoneDevice.cpp
rename to MobiCoreDriverLib/Daemon/Device/Platforms/Generic/TrustZoneDevice.cpp
index 7391775..4db0c43
--- a/daemon/Daemon/Device/Platforms/Generic/TrustZoneDevice.cpp
+++ b/MobiCoreDriverLib/Daemon/Device/Platforms/Generic/TrustZoneDevice.cpp
@@ -4,31 +4,34 @@
  */
 
 /*
- * <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
+ * Copyright (c) 2013 TRUSTONIC LIMITED
+ * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- *    products derived from this software without specific prior
- *    written permission.
  *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 3. Neither the name of the TRUSTONIC LIMITED nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 #include <cstdlib>
@@ -36,6 +39,7 @@
 #include <inttypes.h>
 #include <list>
 
+#include "McTypes.h"
 #include "mc_linux.h"
 #include "McTypes.h"
 #include "Mci/mci.h"
@@ -72,7 +76,10 @@
     void
 )
 {
-    // nothing to do
+    schedulerEnabled = false;
+    pMcKMod = NULL;
+    pWsmMcp = NULL;
+    mobicoreInDDR = NULL;
 }
 
 //------------------------------------------------------------------------------
@@ -89,7 +96,7 @@
 //------------------------------------------------------------------------------
 /**
  * Set up MCI and wait till MC is initialized
- * @return true if mobicore is already initialized
+ * @return true if <t-base is already initialized
  */
 bool TrustZoneDevice::initDevice(
     const char  *devFile,
@@ -101,12 +108,12 @@
 
     pMcKMod = new CMcKMod();
     mcResult_t ret = pMcKMod->open(devFile);
-    if (ret != MC_DRV_OK) 
+    if (ret != MC_DRV_OK)
     {
         LOG_W(" Opening kernel module device failed");
         return false;
     }
-    if (!pMcKMod->checkVersion()) 
+    if (!pMcKMod->checkVersion())
     {
         LOG_E("kernel module version mismatch");
         return false;
@@ -117,58 +124,58 @@
     // Init MC with NQ and MCP buffer addresses
 
     // Set up MCI buffer
-    if (!getMciInstance(MCI_BUFFER_SIZE, &pWsmMcp, &mciReused)) 
+    if (!getMciInstance(MCI_BUFFER_SIZE, &pWsmMcp, &mciReused))
     {
         LOG_E("getMciInstance failed");
         return false;
     }
     mciBuffer = pWsmMcp->virtAddr;
 
-    if (!checkMciVersion()) 
+    if (!checkMciVersion())
     {
         LOG_E("checkMciVersion failed");
         return false;
     }
 
     // Only do a fastcall if MCI has not been reused (MC already initialized)
-    if (!mciReused) 
+    if (!mciReused)
     {
         // Wipe memory before first usage
-        bzero(mciBuffer, MCI_BUFFER_SIZE);
+        memset(mciBuffer, 0, MCI_BUFFER_SIZE);
 
         // Init MC with NQ and MCP buffer addresses
-        int ret = pMcKMod->fcInit(0, NQ_BUFFER_SIZE, NQ_BUFFER_SIZE, MCP_BUFFER_SIZE);
-        if (ret != 0) 
+        int ret = pMcKMod->fcInit(NQ_BUFFER_SIZE, NQ_BUFFER_SIZE, MCP_BUFFER_SIZE);
+        if (ret != 0)
         {
             LOG_E("pMcKMod->fcInit() failed");
             return false;
         }
 
-        // Here we are safe to setup the MobiCore logs
+        // Here we are safe to setup the <t-base logs
         setupLog();
 
         // First empty N-SIQ which results in set up of the MCI structure
-        if (!nsiq()) 
+        if (!nsiq())
         {
             LOG_E("sending N-SIQ failed");
             return false;
         }
 
-        // Wait until MobiCore state switches to MC_STATUS_INITIALIZED
-        // It is assumed that MobiCore always switches state at a certain point in time.
+        // Wait until <t-base state switches to MC_STATUS_INITIALIZED
+        // It is assumed that <t-base always switches state at a certain point in time.
         for(;;)
         {
             uint32_t timeslot;
             uint32_t status = getMobicoreStatus();
 
-            if (MC_STATUS_INITIALIZED == status) 
+            if (MC_STATUS_INITIALIZED == status)
             {
                 break;
-            } 
+            }
 
-            if (MC_STATUS_NOT_INITIALIZED == status) 
+            if (MC_STATUS_NOT_INITIALIZED == status)
             {
-                // Switch to MobiCore to give it more CPU time.
+                // Switch to <t-base to give it more CPU time.
                 for (timeslot = 0; timeslot < 10; timeslot++)
                 {
                     if (!yield())
@@ -178,14 +185,14 @@
                     }
                 }
                 continue;
-            } 
+            }
 
-            if (MC_STATUS_HALT == status) 
+            if (MC_STATUS_HALT == status)
             {
                 dumpMobicoreStatus();
-                LOG_E("MobiCore halted during init !!!, state is 0x%x", status);
+                LOG_E("<t-base halted during init !!!, state is 0x%x", status);
                 return false;
-            } 
+            }
 
             // MC_STATUS_BAD_INIT or anything else
             LOG_E("MCI buffer init failed, state is 0x%x", status);
@@ -211,7 +218,7 @@
     mcpMessage = &(mcpBuf->mcpMessage);
 
     // convert virtual address of mapping to physical address for the init.
-    LOG_I("MCI established, at %p, phys=%p, reused=%s",
+    LOG_I("MCI established, at %p, phys=%#llx, reused=%s",
           pWsmMcp->virtAddr,
           pWsmMcp->physAddr,
           mciReused ? "true" : "false");
@@ -247,7 +254,7 @@
 )
 {
     // There is no need to set the NON-IDLE flag here. Sending an N-SIQ will
-    // make the MobiCore run until it could set itself to a state where it
+    // make the <t-base run until it could set itself to a state where it
     // set the flag itself. IRQs and FIQs are disbaled for this period, so
     // there is no way the NWd can interrupt here.
 
@@ -258,7 +265,7 @@
         LOG_E("pMcKMod->fcNSIQ() failed : %d", ret);
         return false;
     }
-    // now we have to wake the scheduler, so MobiCore gets CPU time.
+    // now we have to wake the scheduler, so <t-base gets CPU time.
     schedSync.signal();
     return true;
 }
@@ -271,22 +278,19 @@
 {
     // 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);
+//        // 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 <t-base", sessionId);
     } else {
-        LOG_I(" Sending MCP notification to MobiCore");
+        LOG_I(" Sending MCP notification to <t-base");
     }
 
-    // Notify MobiCore about new data
-    notification_t notification = { sessionId :
-                                    sessionId, payload : 0
-                                  };
+    // Notify <t-base about new data
+    notification_t notification = { sessionId : sessionId, payload : 0 };
 
     nq->putNotification(&notification);
     //IMPROVEMENT-2012-03-07-maneaval What happens when/if nsiq fails?
@@ -333,52 +337,51 @@
 //------------------------------------------------------------------------------
 void TrustZoneDevice::dumpMobicoreStatus(
     void
-)
-{
-    int ret;
+) {
     uint32_t status, info;
+
     // read additional info about exception-point and print
-    LOG_E("MobiCore halted !!!");
-    ret = pMcKMod->fcInfo(1, &status, &info);
-    LOG_W("MC_HALT: flags               : 0x%8x", info);
-    ret = pMcKMod->fcInfo(2, &status, &info);
-    LOG_W("MC_HALT: haltCode            : 0x%8x", info);
-    ret = pMcKMod->fcInfo(3, &status, &info);
-    LOG_W("MC_HALT: haltIp              : 0x%8x", info);
-    ret = pMcKMod->fcInfo(4, &status, &info);
-    LOG_W("MC_HALT: faultRec.cnt        : 0x%8x", info);
-    ret = pMcKMod->fcInfo(5, &status, &info);
-    LOG_W("MC_HALT: faultRec.cause      : 0x%8x", info);
-    ret = pMcKMod->fcInfo(6, &status, &info);
-    LOG_W("MC_HALT: faultRec.meta       : 0x%8x", info);
-    ret = pMcKMod->fcInfo(7, &status, &info);
-    LOG_W("MC_HALT: faultRec.thread     : 0x%8x", info);
-    ret = pMcKMod->fcInfo(8, &status, &info);
-    LOG_W("MC_HALT: faultRec.ip         : 0x%8x", info);
-    ret = pMcKMod->fcInfo(9, &status, &info);
-    LOG_W("MC_HALT: faultRec.sp         : 0x%8x", info);
-    ret = pMcKMod->fcInfo(10, &status, &info);
-    LOG_W("MC_HALT: faultRec.arch.dfsr  : 0x%8x", info);
-    ret = pMcKMod->fcInfo(11, &status, &info);
-    LOG_W("MC_HALT: faultRec.arch.adfsr : 0x%8x", info);
-    ret = pMcKMod->fcInfo(12, &status, &info);
-    LOG_W("MC_HALT: faultRec.arch.dfar  : 0x%8x", info);
-    ret = pMcKMod->fcInfo(13, &status, &info);
-    LOG_W("MC_HALT: faultRec.arch.ifsr  : 0x%8x", info);
-    ret = pMcKMod->fcInfo(14, &status, &info);
-    LOG_W("MC_HALT: faultRec.arch.aifsr : 0x%8x", info);
-    ret = pMcKMod->fcInfo(15, &status, &info);
-    LOG_W("MC_HALT: faultRec.arch.ifar  : 0x%8x", info);
-    ret = pMcKMod->fcInfo(16, &status, &info);
-    LOG_W("MC_HALT: mcData.flags        : 0x%8x", info);
-    ret = pMcKMod->fcInfo(19, &status, &info);
-    LOG_W("MC_HALT: mcExcep.partner     : 0x%8x", info);
-    ret = pMcKMod->fcInfo(20, &status, &info);
-    LOG_W("MC_HALT: mcExcep.peer        : 0x%8x", info);
-    ret = pMcKMod->fcInfo(21, &status, &info);
-    LOG_W("MC_HALT: mcExcep.message     : 0x%8x", info);
-    ret = pMcKMod->fcInfo(22, &status, &info);
-    LOG_W("MC_HALT: mcExcep.data        : 0x%8x", info);
+    LOG_E("<t-base halted. Status dump:");
+    pMcKMod->fcInfo(1, &status, &info);
+    LOG_W("  flags               = 0x%08x", info);
+    pMcKMod->fcInfo(2, &status, &info);
+    LOG_W("  haltCode            = 0x%08x", info);
+    pMcKMod->fcInfo(3, &status, &info);
+    LOG_W("  haltIp              = 0x%08x", info);
+    pMcKMod->fcInfo(4, &status, &info);
+    LOG_W("  faultRec.cnt        = 0x%08x", info);
+    pMcKMod->fcInfo(5, &status, &info);
+    LOG_W("  faultRec.cause      = 0x%08x", info);
+    pMcKMod->fcInfo(6, &status, &info);
+    LOG_W("  faultRec.meta       = 0x%08x", info);
+    pMcKMod->fcInfo(7, &status, &info);
+    LOG_W("  faultRec.thread     = 0x%08x", info);
+    pMcKMod->fcInfo(8, &status, &info);
+    LOG_W("  faultRec.ip         = 0x%08x", info);
+    pMcKMod->fcInfo(9, &status, &info);
+    LOG_W("  faultRec.sp         = 0x%08x", info);
+    pMcKMod->fcInfo(10, &status, &info);
+    LOG_W("  faultRec.arch.dfsr  = 0x%08x", info);
+    pMcKMod->fcInfo(11, &status, &info);
+    LOG_W("  faultRec.arch.adfsr = 0x%08x", info);
+    pMcKMod->fcInfo(12, &status, &info);
+    LOG_W("  faultRec.arch.dfar  = 0x%08x", info);
+    pMcKMod->fcInfo(13, &status, &info);
+    LOG_W("  faultRec.arch.ifsr  = 0x%08x", info);
+    pMcKMod->fcInfo(14, &status, &info);
+    LOG_W("  faultRec.arch.aifsr = 0x%08x", info);
+    pMcKMod->fcInfo(15, &status, &info);
+    LOG_W("  faultRec.arch.ifar  = 0x%08x", info);
+    pMcKMod->fcInfo(16, &status, &info);
+    LOG_W("  mcData.flags        = 0x%08x", info);
+    pMcKMod->fcInfo(19, &status, &info);
+    LOG_W("  mcExcep.partner     = 0x%08x", info);
+    pMcKMod->fcInfo(20, &status, &info);
+    LOG_W("  mcExcep.peer        = 0x%08x", info);
+    pMcKMod->fcInfo(21, &status, &info);
+    LOG_W("  mcExcep.message     = 0x%08x", info);
+    pMcKMod->fcInfo(22, &status, &info);
+    LOG_W("  mcExcep.data        = 0x%08x", info);
 }
 
 //------------------------------------------------------------------------------
@@ -389,7 +392,7 @@
         LOG_E("pMcKMod->SSIQ() failed");
         return false;
     }
-    LOG_I(" Received SSIQ interrupt from MobiCore, counter=%u", cnt);
+    LOG_I(" Received SSIQ interrupt from <t-base, counter=%u", cnt);
     return true;
 }
 
@@ -399,7 +402,7 @@
 {
     addr_t virtAddr;
     uint32_t handle;
-    addr_t physAddr;
+    uint64_t physAddr;
     bool isReused = true;
     if (len == 0) {
         LOG_E("allocateWsm() length is 0");
@@ -434,7 +437,7 @@
 //------------------------------------------------------------------------------
 CWsm_ptr TrustZoneDevice::registerWsmL2(addr_t buffer, uint32_t len, uint32_t pid)
 {
-    addr_t physAddr;
+    uint64_t physAddr;
     uint32_t handle;
 
     int ret = pMcKMod->registerWsmL2(
@@ -459,7 +462,7 @@
     // Allocate shared memory
     addr_t virtAddr;
     uint32_t handle;
-    addr_t physAddr;
+    uint64_t physAddr;
 
     if (len == 0 )
         return NULL;
@@ -502,11 +505,11 @@
 //------------------------------------------------------------------------------
 bool TrustZoneDevice::unlockWsmL2(uint32_t handle)
 {
-    LOG_I("Unlocking buffer with handle %u", handle);
+    LOG_I(" Unlocking buffer with handle %u", handle);
     int ret = pMcKMod->unlockWsmL2(handle);
     if (ret != 0) {
         // Failure here is not important
-        LOG_I("pMcKMod->unregisterWsmL2 failed: %d", ret);
+        LOG_I(" pMcKMod->unregisterWsmL2 failed: %d", ret);
         return false;
     }
     return true;
@@ -524,32 +527,32 @@
 }
 
 //------------------------------------------------------------------------------
-addr_t TrustZoneDevice::findWsmL2(uint32_t handle, int fd)
+uint64_t TrustZoneDevice::findWsmL2(uint32_t handle, int fd)
 {
-    addr_t ret = pMcKMod->findWsmL2(handle, fd);
-    if (ret == NULL) {
+	uint64_t ret = pMcKMod->findWsmL2(handle, fd);
+    if (!ret) {
         LOG_E("pMcKMod->findWsmL2 failed");
-        return NULL;
+        return 0;
     }
-    LOG_I("Resolved buffer with handle %u to %p", handle, ret);
+    LOG_I("Resolved buffer with handle %u to %#llx", handle, ret);
     return ret;
 }
 
 //------------------------------------------------------------------------------
-bool TrustZoneDevice::findContiguousWsm(uint32_t handle, int fd, addr_t *phys, uint32_t *len)
+bool TrustZoneDevice::findContiguousWsm(uint32_t handle, int fd, uint64_t *phys, uint32_t *len)
 {
     if (pMcKMod->findContiguousWsm(handle, fd, phys, len)) {
-        LOG_E("pMcKMod->findContiguousWsm failed");
+        LOG_V(" pMcKMod->findContiguousWsm failed");
         return false;
     }
-    LOG_I("Resolved buffer with handle %u to %p", handle, phys);
+    LOG_I("Resolved buffer with handle %u to %#llx", handle, *phys);
     return true;
 }
 //------------------------------------------------------------------------------
 bool TrustZoneDevice::setupLog(void)
 {
     if (pMcKMod->setupLog()) {
-        LOG_E("pMcKMod->setupLog failed");
+        LOG_W("pMcKMod->setupLog failed");
         return false;
     }
     return true;
@@ -569,33 +572,33 @@
     uint32_t timeslice = SCHEDULING_FREQ;
 
     // loop forever
-    for (;;) 
+    for (;;)
     {
         // Scheduling decision
-        if (MC_FLAG_SCHEDULE_IDLE == mcFlags->schedule) 
+        if (MC_FLAG_SCHEDULE_IDLE == mcFlags->schedule)
         {
             // <t-base is IDLE. Prevent unnecessary consumption of CPU cycles
             // and wait for S-SIQ
             schedSync.wait(); // check return code?
             continue;
-        } 
+        }
 
         // <t-base is no longer IDLE, Check timeslice
-        if (timeslice == 0) 
+        if (timeslice == 0)
         {
             // Slice expired, so force MC internal scheduling decision
             timeslice = SCHEDULING_FREQ;
-            if (!nsiq()) 
+            if (!nsiq())
             {
                 LOG_E("sending N-SIQ failed");
                 break;
             }
             continue;
-        } 
+        }
 
         // Slice not used up, simply hand over control to the MC
         timeslice--;
-        if (!yield()) 
+        if (!yield())
         {
             LOG_E("yielding to SWd failed");
             break;
@@ -607,16 +610,65 @@
 
 
 //------------------------------------------------------------------------------
+void TrustZoneDevice::handleTaExit(void)
+{
+    LOG_I("Starting Trusted Application Exit handler...");
+    for (;;) {
+        // Wait until we get a notification without CA
+        taExitNotification.wait();
+
+        // Wait until socket server frees MCP
+        // Make sure we don't interfere with handleConnection/dropConnection
+        mutex_mcp.lock();
+
+        // Check all sessions
+        // Socket server might have closed already and removed the session we were waken up for
+        for (trustletSessionIterator_t iterator = trustletSessions.begin();
+                iterator != trustletSessions.end();
+                )
+        {
+            TrustletSession *ts = *iterator;
+
+            if (ts->sessionState == TrustletSession::TS_TA_DEAD) {
+                LOG_I("Cleaning up session %i", ts->sessionId);
+
+                // Tell t-base to close the session
+                mcResult_t mcRet = closeSessionInternal(ts);
+
+                // If ok, remove objects
+                if (mcRet == MC_DRV_OK) {
+                    mutex_tslist.lock();
+                    iterator = trustletSessions.erase(iterator);
+                    LOG_I("TA session %i finally closed", ts->sessionId);
+                    delete ts;
+                    mutex_tslist.unlock();
+                    continue;
+                } else {
+                    LOG_I("TA session %i could not be closed yet.", ts->sessionId);
+                }
+            }
+            ++iterator;
+        }
+        mutex_mcp.unlock();
+    }
+    TAExitHandler::setExiting();
+    signalMcpNotification();
+
+    LOG_E("schedule loop terminated");
+}
+
+
+//------------------------------------------------------------------------------
 void TrustZoneDevice::handleIrq(
     void
 ) {
     LOG_I("Starting Notification Queue IRQ handler...");
 
-    for (;;) 
+    for (;;)
     {
 
         LOG_I(" No notifications pending, waiting for S-SIQ");
-        if (!waitSsiq()) 
+        if (!waitSsiq())
         {
             LOG_E("Waiting for S-SIQ failed");
             break;
@@ -624,18 +676,18 @@
 
         LOG_V("S-SIQ received");
 
-        // get notifications from queue 
-        for (;;) 
+        // get notifications from queue
+        for (;;)
         {
             notification_t *notification = nq->getNotification();
-            if (NULL == notification) 
+            if (NULL == notification)
             {
                 break;
             }
 
-            // process the notification 
+            // process the notification
             // check if the notification belongs to the MCP session
-            if (notification->sessionId == SID_MCP) 
+            if (notification->sessionId == SID_MCP)
             {
                 LOG_I(" Notification for MCP, payload=%d",
                       notification->payload);
@@ -643,36 +695,52 @@
                 // Signal main thread of the driver to continue after MCP
                 // command has been processed by the MC
                 signalMcpNotification();
-               continue;
+
+                continue;
             }
 
-            // Get the NQ connection for the session ID. Usually, this will work 
-            // fine. But there could be a race condition between RTM and the 
-            // Daemon where RTM won. We shouldn't drop the notification right away,
-            // but just queue it in the device.
-            Connection *connection = getSessionConnection(
-                                         notification->sessionId, 
-                                         notification);
-            if (connection == NULL) 
-            {
-                LOG_W("Notification for unknown session  %d",
-                      notification->sessionId);
-                queueUnknownNotification(*notification);
-                continue;
-            } 
-
             LOG_I(" Notification for session %d, payload=%d",
-                  notification->sessionId, notification->payload);
-            // Forward session ID and additional payload of
-            // notification to the TLC/Application layer
-            connection->writeData((void *)notification,
-                                  sizeof(notification_t));
+                notification->sessionId, notification->payload);
 
+            // Get the Trustlet session for the session ID
+            TrustletSession *ts = NULL;
+
+            mutex_tslist.lock();
+            ts = getTrustletSession(notification->sessionId);
+            if (ts == NULL) {
+                /* Couldn't find the session for this notifications
+                 * In practice this only means one thing: there is
+                 * a race condition between RTM and the Daemon and
+                 * RTM won. But we shouldn't drop the notification
+                 * right away we should just queue it in the device
+                 */
+                LOG_W("Notification for unknown session ID");
+                queueUnknownNotification(*notification);
+            } else {
+                mutex_connection.lock();
+                // Get the NQ connection for the session ID
+                Connection *connection = ts->notificationConnection;
+                if (connection == NULL) {
+                    ts->queueNotification(notification);
+                    if (ts->deviceConnection == NULL) {
+                        LOG_I("  Notification for disconnected client, scheduling cleanup of sessions.");
+                        taExitNotification.signal();
+                    }
+                } else {
+                    LOG_I(" Forward notification to McClient.");
+                    // Forward session ID and additional payload of
+                    // notification to the TLC/Application layer
+                    connection->writeData((void *)notification,
+                                          sizeof(notification_t));
+                }
+                mutex_connection.unlock();
+            }
+            mutex_tslist.unlock();
         } // for (;;) over notifiction queue
 
         // finished processing notifications. It does not matter if there were
-        // any notification or not. S-SIQs can also be triggered by an SWd 
-        // driver which was waiting for a FIQ. In this case the S-SIQ tells 
+        // any notification or not. S-SIQs can also be triggered by an SWd
+        // driver which was waiting for a FIQ. In this case the S-SIQ tells
         // NWd that SWd is no longer idle an will need scheduling again
         schedSync.signal();
 
diff --git a/daemon/Daemon/Device/Platforms/Generic/TrustZoneDevice.h b/MobiCoreDriverLib/Daemon/Device/Platforms/Generic/TrustZoneDevice.h
old mode 100644
new mode 100755
similarity index 68%
rename from daemon/Daemon/Device/Platforms/Generic/TrustZoneDevice.h
rename to MobiCoreDriverLib/Daemon/Device/Platforms/Generic/TrustZoneDevice.h
index 37646c7..a895fa2
--- a/daemon/Daemon/Device/Platforms/Generic/TrustZoneDevice.h
+++ b/MobiCoreDriverLib/Daemon/Device/Platforms/Generic/TrustZoneDevice.h
@@ -6,31 +6,34 @@
  * TrustZone device implements communication functions needed for
  * accessing MobiCore located in an TrustZone environment.
  *
- * <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
+ * Copyright (c) 2013 TRUSTONIC LIMITED
+ * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- *    products derived from this software without specific prior
- *    written permission.
  *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 3. Neither the name of the TRUSTONIC LIMITED nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 #ifndef TRUSTZONEDEVICE_H_
 #define TRUSTZONEDEVICE_H_
@@ -115,9 +118,9 @@
 
     bool unlockWsmL2(uint32_t handle);
 
-    addr_t findWsmL2(uint32_t handle, int fd);
+    uint64_t findWsmL2(uint32_t handle, int fd);
 
-    bool findContiguousWsm(uint32_t handle, int fd, addr_t *phys, uint32_t *len);
+    bool findContiguousWsm(uint32_t handle, int fd, uint64_t *phys, uint32_t *len);
 
     /**
      * Cleanup all orphaned bulk buffers.
@@ -136,6 +139,8 @@
     void schedule(void);
 
     void handleIrq(void);
+
+    void handleTaExit(void);
 };
 
 #endif /* TRUSTZONEDEVICE_H_ */
diff --git a/MobiCoreDriverLib/Daemon/Device/TAExitHandler.cpp b/MobiCoreDriverLib/Daemon/Device/TAExitHandler.cpp
new file mode 100755
index 0000000..cf60b04
--- /dev/null
+++ b/MobiCoreDriverLib/Daemon/Device/TAExitHandler.cpp
@@ -0,0 +1,48 @@
+/** @addtogroup MCD_MCDIMPL_DAEMON_DEV
+ * @{
+ * @file
+ *
+ *
+ * Copyright (c) 2013 TRUSTONIC LIMITED
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the TRUSTONIC LIMITED nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "TAExitHandler.h"
+#include "log.h"
+
+//------------------------------------------------------------------------------
+void TAExitHandler::run(
+    void
+)
+{
+    handleTaExit();
+    this->exit(-1);
+}
+
+/** @} */
diff --git a/MobiCoreDriverLib/Daemon/Device/TAExitHandler.h b/MobiCoreDriverLib/Daemon/Device/TAExitHandler.h
new file mode 100755
index 0000000..037cd12
--- /dev/null
+++ b/MobiCoreDriverLib/Daemon/Device/TAExitHandler.h
@@ -0,0 +1,57 @@
+/** @addtogroup MCD_MCDIMPL_DAEMON_DEV
+ * @{
+ * @file
+ *
+ * Trusted Application exit handler thread.
+ *
+ * Copyright (c) 2013 TRUSTONIC LIMITED
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the TRUSTONIC LIMITED nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _TAEXITHANDLER_H_
+#define _TAEXITHANDLER_H_
+
+#include "CThread.h"
+#include "CMutex.h"
+#include "TrustletSession.h"
+
+
+class TAExitHandler: public CThread
+{
+public:
+    CSemaphore taExitNotification;
+
+    virtual void handleTaExit() = 0;
+
+    void run();
+};
+
+#endif /* TAEXITHANDLER_H_ */
+
+/** @} */
diff --git a/MobiCoreDriverLib/Daemon/Device/TrustletSession.cpp b/MobiCoreDriverLib/Daemon/Device/TrustletSession.cpp
new file mode 100755
index 0000000..d0bd1e0
--- /dev/null
+++ b/MobiCoreDriverLib/Daemon/Device/TrustletSession.cpp
@@ -0,0 +1,161 @@
+/** @addtogroup MCD_MCDIMPL_DAEMON_DEV
+ * @{
+ * @file
+ *
+ * Copyright (c) 2013 TRUSTONIC LIMITED
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the TRUSTONIC LIMITED nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "TrustletSession.h"
+#include <cstdlib>
+
+#include "log.h"
+
+using namespace std;
+
+//------------------------------------------------------------------------------
+TrustletSession::TrustletSession(Connection *deviceConnection, uint32_t sessionId)
+{
+    this->deviceConnection = deviceConnection;
+    this->notificationConnection = NULL;
+    this->sessionId = sessionId;
+    sessionMagic = rand();
+    this->gp_level=0;
+    this->sessionState=TS_TA_RUNNING;
+}
+
+
+//------------------------------------------------------------------------------
+TrustletSession::~TrustletSession(void)
+{
+    map<uint32_t, CWsm_ptr>::iterator it;
+    delete notificationConnection;
+
+    if (!buffers.empty()) {
+        LOG_W("%s: Mapped buffers still available %u", __func__, buffers.size());
+    }
+    for ( it = buffers.begin() ; it != buffers.end(); it++ )
+        delete (*it).second;
+
+    buffers.clear();
+}
+
+//------------------------------------------------------------------------------
+void TrustletSession::queueNotification(notification_t *notification)
+{
+    if (sessionState == TS_TA_DEAD) {
+        return;
+    }
+    if ((gp_level == 1) && (notification->payload != 0)) {
+        LOG_I("  Mark session %i dead", sessionId);
+        sessionState = TS_TA_DEAD;
+    }
+    // Note this is a very subtle synchronization requirement:
+    //  The TrustletSession object is manipulated by several threads
+    //  If the sessionState is set to closed,
+    //  it means another thread could soon delete the object
+    //  Also in this case we don't care about any notifications anymore
+    if (sessionState == TS_CLOSE_SEND) {
+        return;
+    }
+
+    notifications.push(*notification);
+}
+
+//------------------------------------------------------------------------------
+void TrustletSession::processQueuedNotifications(void)
+{
+    LOG_I(" %s:%i", __FILE__, __LINE__ );
+
+    // Nothing to do here!
+    if (notificationConnection == NULL)
+        return;
+
+    while (!notifications.empty()) {
+        // Forward session ID and additional payload of
+        // notification to the just established connection
+        notificationConnection->writeData((void *)&notifications.front(),
+                                          sizeof(notification_t));
+        notifications.pop();
+    }
+}
+
+//------------------------------------------------------------------------------
+bool TrustletSession::addBulkBuff(CWsm_ptr pWsm)
+{
+    if (!pWsm)
+        return false;
+    if (buffers.find(pWsm->handle) != buffers.end()) {
+        delete pWsm;
+        return false;
+    }
+    buffers[pWsm->handle] = pWsm;
+    return true;
+}
+
+//------------------------------------------------------------------------------
+bool TrustletSession::removeBulkBuff(uint32_t handle)
+{
+    if (buffers.find(handle) == buffers.end()) {
+        return false;
+    }
+    CWsm_ptr pWsm = buffers[handle];
+    delete pWsm;
+    buffers.erase(handle);
+    return true;
+}
+
+//------------------------------------------------------------------------------
+bool TrustletSession::findBulkBuff(uint32_t handle, uint32_t lenBulkMem)
+{
+    if (buffers.find(handle) == buffers.end()) {
+        return false;
+    }
+    CWsm_ptr pWsm = buffers[handle];
+    if ((uint32_t)pWsm->len != lenBulkMem) {
+        return false;
+    }
+
+    return true;
+}
+
+//------------------------------------------------------------------------------
+CWsm_ptr TrustletSession::popBulkBuff()
+{
+    if (buffers.empty()) {
+        return NULL;
+    }
+
+    CWsm_ptr pWsm = buffers.begin()->second;
+    // Remove it from the map
+    buffers.erase(pWsm->handle);
+    return pWsm;
+}
+
+/** @} */
diff --git a/MobiCoreDriverLib/Daemon/Device/TrustletSession.h b/MobiCoreDriverLib/Daemon/Device/TrustletSession.h
new file mode 100755
index 0000000..c7c2cad
--- /dev/null
+++ b/MobiCoreDriverLib/Daemon/Device/TrustletSession.h
@@ -0,0 +1,86 @@
+/** @addtogroup MCD_MCDIMPL_DAEMON_DEV
+ * @{
+ * @file
+ *
+ * Copyright (c) 2013 TRUSTONIC LIMITED
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the TRUSTONIC LIMITED nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef TRUSTLETSESSION_H_
+#define TRUSTLETSESSION_H_
+
+#include "NotificationQueue.h"
+#include "CWsm.h"
+#include "Connection.h"
+#include <queue>
+#include <map>
+
+
+class TrustletSession
+{
+private:
+    std::queue<notification_t> notifications;
+    std::map<uint32_t, CWsm_ptr> buffers;
+
+public:
+    uint32_t sessionId; // Assigned by t-base
+    uint32_t sessionMagic; // Random data
+    Connection *deviceConnection; // Command socket for client "device"
+    Connection *notificationConnection; // Notification socket for client session
+    uint32_t gp_level;
+    enum TS_STATE {
+        TS_TA_RUNNING,//->dead,close_send
+        TS_TA_DEAD, //->close_send, closed
+        TS_CLOSE_SEND,//->close_send, dead, closed
+        TS_CLOSED,//unused
+    } sessionState;
+
+    TrustletSession(Connection *deviceConnection, uint32_t sessionId);
+
+    ~TrustletSession(void);
+
+    void queueNotification(notification_t *notification);
+
+    void processQueuedNotifications(void);
+
+    bool addBulkBuff(CWsm_ptr pWsm);
+
+    bool removeBulkBuff(uint32_t handle);
+    
+    bool findBulkBuff(uint32_t handle, uint32_t lenBulkMem);
+
+    CWsm_ptr popBulkBuff();
+
+};
+
+typedef std::list<TrustletSession *> trustletSessionList_t;
+typedef trustletSessionList_t::iterator trustletSessionIterator_t;
+
+#endif /* TRUSTLETSESSION_H_ */
+
+/** @} */
diff --git a/MobiCoreDriverLib/Daemon/Device/public/ExcDevice.h b/MobiCoreDriverLib/Daemon/Device/public/ExcDevice.h
new file mode 100755
index 0000000..733fbcd
--- /dev/null
+++ b/MobiCoreDriverLib/Daemon/Device/public/ExcDevice.h
@@ -0,0 +1,72 @@
+/** @addtogroup MCD_MCDIMPL_DAEMON_DEV
+ * @{
+ * @file
+ *
+ * Device exceptions.
+ *
+ * Copyright (c) 2013 TRUSTONIC LIMITED
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the TRUSTONIC LIMITED nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef EXCDEVICE_H_
+#define EXCDEVICE_H_
+
+#include <stdint.h>
+#include <exception>
+#include <cstdio>
+#include <cstdlib>
+
+#define ERROR_MCI_VERSION_MISMATCH  ((int)(-2))
+#define ERROR_KMOD_VERSION_MISMATCH  ((int)(-3))
+
+class ExcDevice: public std::exception
+{
+
+public:
+
+    ExcDevice(const char *description, int cause) :
+        cause(cause), description(description) {
+    }
+
+    virtual int getCause() const throw () {
+        return cause;
+    }
+
+    virtual const char *getDescription() const throw () {
+        return description;
+    }
+
+private:
+
+    int cause;
+    const char *description;
+};
+
+#endif /* EXCDEVICE_H_ */
+
+/** @} */
diff --git a/daemon/Daemon/Device/public/MobiCoreDevice.h b/MobiCoreDriverLib/Daemon/Device/public/MobiCoreDevice.h
old mode 100644
new mode 100755
similarity index 72%
rename from daemon/Daemon/Device/public/MobiCoreDevice.h
rename to MobiCoreDriverLib/Daemon/Device/public/MobiCoreDevice.h
index 3e047cd..14d2cf9
--- a/daemon/Daemon/Device/public/MobiCoreDevice.h
+++ b/MobiCoreDriverLib/Daemon/Device/public/MobiCoreDevice.h
@@ -7,31 +7,34 @@
  * Concrete devices implementing the communication behavior for the platforms have to be derived
  * from this.
  *
- * <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
+ * Copyright (c) 2013 TRUSTONIC LIMITED
+ * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- *    products derived from this software without specific prior
- *    written permission.
  *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 3. Neither the name of the TRUSTONIC LIMITED nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 #ifndef MOBICOREDEVICE_H_
 #define MOBICOREDEVICE_H_
@@ -52,6 +55,7 @@
 #include "ExcDevice.h"
 #include "DeviceScheduler.h"
 #include "DeviceIrqHandler.h"
+#include "TAExitHandler.h"
 #include "NotificationQueue.h"
 #include "TrustletSession.h"
 #include "mcVersionInfo.h"
@@ -60,19 +64,25 @@
 class MobiCoreDevice;
 
 typedef struct {
-    addr_t baseAddr;    /**< Physical address of the data to load. */
+    uint64_t baseAddr;    /**< Physical address of the data to load. */
     uint32_t offs;      /**< Offset to the data. */
     uint32_t len;       /**< Length of the data to load. */
     mclfHeader_ptr tlHeader; /**< Pointer to trustlet header. */
 } loadDataOpenSession_t, *loadDataOpenSession_ptr;
 
+typedef struct {
+    uint64_t addr;      /**< Physical address of the data to load. */
+    uint64_t offs;      /**< Offset to the data. */
+    uint64_t len;       /**< Length of the data to load. */
+} loadTokenData_t, *loadTokenData_ptr;
+
 /**
  * Factory method to return the platform specific MobiCore device.
  * Implemented in the platform specific *Device.cpp
  */
 extern MobiCoreDevice *getDeviceInstance(void);
 
-class MobiCoreDevice : public DeviceScheduler, public DeviceIrqHandler
+class MobiCoreDevice : public DeviceScheduler, public DeviceIrqHandler, public TAExitHandler
 {
 
 protected:
@@ -86,6 +96,8 @@
     mcVersionInfo_t     *mcVersionInfo; /**< MobiCore version info. */
     bool                mcFault; /**< Signal RTM fault */
     bool                mciReused; /**< Signal restart of Daemon. */
+    CMutex              mutex_connection; // Mutex to share session->notificationConnection for GP cases
+    CMutex              mutex_tslist;       // Mutex to share Trustlet  session list
 
     /* In a special case a Trustlet can create a race condition in the daemon.
      * If at Trustlet start it detects an error of some sort and calls the
@@ -130,9 +142,11 @@
     virtual bool waitSsiq(void) = 0;
 
 public:
+    CMutex mutex_mcp; // This mutex should be taken before any access to below functions
+
     virtual ~MobiCoreDevice();
 
-    Connection *getSessionConnection(uint32_t sessionId, notification_t *notification);
+    //Connection *getSessionConnection(uint32_t sessionId, notification_t *notification);
 
     bool open(Connection *connection);
 
@@ -145,6 +159,10 @@
                            uint32_t                        tciOffset,
                            mcDrvRspOpenSessionPayload_ptr  pRspOpenSessionPayload);
 
+    mcResult_t checkLoad(loadDataOpenSession_ptr           pLoadDataOpenSession,
+                         mcDrvRspOpenSessionPayload_ptr   pRspOpenSessionPayload);
+
+
     TrustletSession *registerTrustletConnection(Connection *connection,
             MC_DRV_CMD_NQ_CONNECT_struct  *cmdNqConnect);
 
@@ -155,16 +173,14 @@
 
     virtual void notify(uint32_t  sessionId) = 0;
 
-    mcResult_t mapBulk(Connection *deviceConnection, uint32_t sessionId, uint32_t handle, uint32_t pAddrL2,
+    mcResult_t mapBulk(Connection *deviceConnection, uint32_t sessionId, uint32_t handle, uint64_t pAddrL2,
                         uint32_t offsetPayload, uint32_t lenBulkMem, uint32_t *secureVirtualAdr);
 
     mcResult_t unmapBulk(Connection *deviceConnection, uint32_t sessionId, uint32_t handle,
-                        uint32_t secureVirtualAdr, uint32_t lenBulkMem);
+                         uint32_t secureVirtualAdr, uint32_t lenBulkMem);
 
     void start();
 
-    void donateRam(const uint32_t donationSize);
-
     mcResult_t getMobiCoreVersion(mcDrvRspGetMobiCoreVersionPayload_ptr pRspGetMobiCoreVersionPayload);
 
     bool getMcFault() {
@@ -212,9 +228,9 @@
 
     virtual bool unlockWsmL2(uint32_t handle) = 0;
 
-    virtual addr_t findWsmL2(uint32_t handle, int fd) = 0;
+    virtual uint64_t findWsmL2(uint32_t handle, int fd) = 0;
 
-    virtual bool findContiguousWsm(uint32_t handle, int fd, addr_t *phys, uint32_t *len) = 0;
+    virtual bool findContiguousWsm(uint32_t handle, int fd, uint64_t *phys, uint32_t *len) = 0;
 
     /**
      * Cleanup all orphaned bulk buffers.
@@ -228,6 +244,9 @@
      */
     virtual CWsm_ptr allocateContiguousPersistentWsm(uint32_t len) = 0;
 
+    mcResult_t loadToken(Connection        *deviceConnection,
+                         loadTokenData_ptr pLoadTokenData);
+
 };
 
 #endif /* MOBICOREDEVICE_H_ */
diff --git a/MobiCoreDriverLib/Daemon/FSD/Android.mk b/MobiCoreDriverLib/Daemon/FSD/Android.mk
new file mode 100755
index 0000000..77f7cd3
--- /dev/null
+++ b/MobiCoreDriverLib/Daemon/FSD/Android.mk
@@ -0,0 +1,18 @@
+# =============================================================================
+#
+# MC driver server files
+#
+# =============================================================================
+
+# This is not a separate module.
+# Only for inclusion by other modules.
+
+FSD_PATH := Daemon/FSD
+
+# Add new folders with header files here
+LOCAL_C_INCLUDES += $(LOCAL_PATH)/$(FSD_PATH)/public \
+                    $(COMP_PATH_DrSecureStorage)/Public \
+                    $(MOBICORE_PROJECT_PATH)/include/GPD_TEE_Internal_API
+
+# Add new source files here
+LOCAL_SRC_FILES += $(FSD_PATH)/FSD.cpp \
\ No newline at end of file
diff --git a/MobiCoreDriverLib/Daemon/FSD/FSD.cpp b/MobiCoreDriverLib/Daemon/FSD/FSD.cpp
new file mode 100755
index 0000000..e1617ba
--- /dev/null
+++ b/MobiCoreDriverLib/Daemon/FSD/FSD.cpp
@@ -0,0 +1,602 @@
+/** @addtogroup MCD_MCDIMPL_DAEMON_SRV
+ * @{
+ * @file
+ *
+ * FSD server.
+ *
+ * Handles incoming storage requests from TA through STH
+ */
+/* Copyright (c) 2013 TRUSTONIC LIMITED
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the TRUSTONIC LIMITED nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "public/FSD.h"
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <cstdlib>
+#include <stdio.h>
+
+//#define LOG_VERBOSE
+#include "log.h"
+
+#define TEE_DATA_FLAG_EXCLUSIVE              0x00000400
+
+extern string getTbStoragePath();
+
+extern pthread_mutex_t         syncMutex;
+extern pthread_cond_t          syncCondition;
+extern bool Th_sync;
+
+//------------------------------------------------------------------------------
+FSD::FSD(
+		void
+)
+{
+    memset(&sessionHandle, 0, sizeof(mcSessionHandle_t));
+    dci = NULL;
+}
+
+FSD::~FSD(
+    void
+)
+{
+	FSD_Close();
+}
+
+//------------------------------------------------------------------------------
+void FSD::run(
+    void
+)
+{
+	struct stat st = {0};
+	mcResult_t ret;
+	string storage = getTbStoragePath();
+	const char* tbstpath = storage.c_str();
+
+	/*Create Tbase storage directory*/
+	if (stat(tbstpath, &st) == -1) {
+		LOG_I("%s: Creating <t-base storage Folder %s\n",TAG_LOG,tbstpath);
+		if(mkdir(tbstpath, 0600)==-1)
+		{
+			LOG_E("%s: failed creating storage folder\n",TAG_LOG);
+		}
+	}
+	do{
+		pthread_mutex_lock(&syncMutex);
+		pthread_cond_wait(&syncCondition, &syncMutex);
+		if (Th_sync==true)
+		{
+			LOG_I("%s: starting File Storage Daemon", TAG_LOG);
+
+		}
+		pthread_mutex_unlock(&syncMutex);
+
+		ret = FSD_Open();
+		if (ret != MC_DRV_OK)
+			break;
+		LOG_I("%s: Start listening for request from STH", TAG_LOG);
+		FSD_listenDci();
+	}while(false);
+	LOG_E("Exiting File Storage Daemon 0x%08X", ret);
+}
+
+
+mcResult_t FSD::FSD_Open(void) {
+    mcResult_t   mcRet;
+    const mcUuid_t uuid = DRV_STH_UUID;
+
+    memset(&sessionHandle,0, sizeof(mcSessionHandle_t));
+
+    dci = (dciMessage_t*)calloc(DCI_BUFF_SIZE,sizeof(uint8_t));
+    if (dci == NULL) {
+        LOG_E("FSD_Open(): allocation failed");
+        return MC_DRV_ERR_NO_FREE_MEMORY;
+    }
+
+    /* Open <t-base device */
+    mcRet = mcOpenDevice(MC_DEVICE_ID_DEFAULT);
+    if (MC_DRV_OK != mcRet)
+    {
+        LOG_E("FSD_Open(): mcOpenDevice returned: %d\n", mcRet);
+        goto error;
+    }
+
+    /* Open session to the sth driver */
+    sessionHandle.deviceId = MC_DEVICE_ID_DEFAULT;
+    mcRet = mcOpenSession(&sessionHandle,
+                          &uuid,
+                          (uint8_t *) dci,
+                          DCI_BUFF_SIZE);
+    if (MC_DRV_OK != mcRet)
+    {
+        LOG_E("FSD_Open(): mcOpenSession returned: %d\n", mcRet);
+        goto close_device;
+    }
+
+    /* Wait for notification from SWd */
+    mcRet = mcWaitNotification(&sessionHandle, MC_INFINITE_TIMEOUT);
+    if (MC_DRV_OK != mcRet)
+    {
+        goto close_session;
+    }
+
+    /**
+     * The following notification is required for initial sync up
+     * with the driver
+     */
+    dci->command.header.commandId = CMD_ST_SYNC;
+    mcRet = mcNotify(&sessionHandle);
+    if (MC_DRV_OK != mcRet)
+    {
+        LOG_E("FSD_Open(): mcNotify returned: %d\n", mcRet);
+        goto close_session;
+    }
+
+    /* Wait for notification from SWd */
+    mcRet = mcWaitNotification(&sessionHandle, MC_INFINITE_TIMEOUT);
+    if (MC_DRV_OK != mcRet)
+    {
+        goto close_session;
+    }
+    LOG_I("FSD_Open(): received first notification \n");
+    LOG_I("FSD_Open(): send notification  back \n");
+    mcRet = mcNotify(&sessionHandle);
+    if (MC_DRV_OK != mcRet)
+    {
+        LOG_E("FSD_Open(): mcNotify returned: %d\n", mcRet);
+        goto close_session;
+    }
+
+    LOG_I("FSD_Open(): returning success");
+    return mcRet;
+
+close_session:
+    mcCloseSession(&sessionHandle);
+
+close_device:
+    mcCloseDevice(MC_DEVICE_ID_DEFAULT);
+
+error:
+    free(dci);
+    dci = NULL;
+
+    return mcRet;
+}
+
+mcResult_t FSD::FSD_Close(void){
+    mcResult_t   mcRet;
+
+    /* Clear DCI message buffer */
+    memset(dci, 0, sizeof(dciMessage_t));
+
+    /* Close session to the debug driver trustlet */
+    mcRet = mcCloseSession(&sessionHandle);
+    if (MC_DRV_OK != mcRet)
+    {
+        LOG_E("FSD_Close(): mcCloseSession returned: %d\n", mcRet);
+    }
+
+    free(dci);
+    dci = NULL;
+    memset(&sessionHandle,0,sizeof(mcSessionHandle_t));
+
+    /* Close <t-base device */
+    mcRet = mcCloseDevice(MC_DEVICE_ID_DEFAULT);
+    if (MC_DRV_OK != mcRet)
+    {
+        LOG_E("FSD_Close(): mcCloseDevice returned: %d\n", mcRet);
+    }
+
+    LOG_I("FSD_Close(): returning: 0x%.8x\n", mcRet);
+
+    return mcRet;
+}
+
+
+void FSD::FSD_listenDci(void){
+    mcResult_t  mcRet;
+    LOG_I("FSD_listenDci(): DCI listener \n");
+
+
+    for(;;)
+    {
+        LOG_I("FSD_listenDci(): Waiting for notification\n");
+
+        /* Wait for notification from SWd */
+        if (MC_DRV_OK != mcWaitNotification(&sessionHandle, MC_INFINITE_TIMEOUT))
+        {
+            LOG_E("FSD_listenDci(): mcWaitNotification failed\n");
+            break;
+        }
+
+		/* Received exception. */
+		LOG_I("FSD_listenDci(): Received Command (0x%.8x) from STH\n", dci->sth_request.type);
+
+		mcRet = FSD_ExecuteCommand();
+
+		/* notify the STH*/
+		mcRet = mcNotify(&sessionHandle);
+		if (MC_DRV_OK != mcRet)
+		{
+			LOG_E("FSD_executeCommand(): mcNotify returned: %d\n", mcRet);
+			break;
+		}
+    }
+}
+
+void FSD_HexFileName(
+				unsigned char*		fn,
+				char*				FileName,
+				uint32_t 			elems
+){
+
+	char tmp[elems * 2 + 1];
+	uint32_t i=0;
+
+	for (i = 0; i < elems; i++) {
+		sprintf(&tmp[i * 2], "%02x", fn[i]);
+	}
+	strcpy(FileName,tmp);
+}
+
+
+void FSD_CreateTaDirName(
+				TEE_UUID*			ta_uuid,
+				char*				DirName,
+				uint32_t 			elems
+){
+
+	char tmp[elems * 2 + 1];
+	unsigned char*		fn;
+	uint32_t i=0;
+
+	fn = (unsigned char*)ta_uuid;
+	for (i = 0; i < elems; i++) {
+		sprintf(&tmp[i * 2], "%02x", fn[i]);
+	}
+	strcat(DirName,tmp);
+}
+
+//------------------------------------------------------------------------------
+mcResult_t FSD::FSD_ExecuteCommand(void){
+	switch(dci->sth_request.type)
+			{
+				//--------------------------------------
+				case STH_MESSAGE_TYPE_LOOK:
+					LOG_I("FSD_ExecuteCommand(): Looking for file\n");
+					dci->sth_request.status=FSD_LookFile();
+
+					break;
+				//--------------------------------------
+				case STH_MESSAGE_TYPE_READ:
+					LOG_I("FSD_ExecuteCommand(): Reading file\n");
+					dci->sth_request.status=FSD_ReadFile();
+
+					break;
+				//--------------------------------------
+				case STH_MESSAGE_TYPE_WRITE:
+					LOG_I("FSD_ExecuteCommand(): Writing file\n");
+					dci->sth_request.status=FSD_WriteFile();
+
+					break;
+				//--------------------------------------
+				case STH_MESSAGE_TYPE_DELETE:
+					LOG_I("FSD_ExecuteCommand(): Deleting file\n");
+					dci->sth_request.status=FSD_DeleteFile();
+					LOG_I("FSD_ExecuteCommand(): file deleted status is 0x%08x\n",dci->sth_request.status);
+
+					break;
+				//--------------------------------------
+				default:
+					LOG_E("FSD_ExecuteCommand(): Received unknown command %x. Ignoring..\n", dci->sth_request.type);
+					break;
+			}
+	return dci->sth_request.status;
+}
+
+
+/****************************  File operations  *******************************/
+
+
+mcResult_t FSD::FSD_LookFile(void){
+	FILE * pFile=NULL;
+	STH_FSD_message_t* sth_request=NULL;
+	size_t res;
+	string storage = getTbStoragePath();
+	const char* tbstpath = storage.c_str();
+	char tadirname[TEE_UUID_STRING_SIZE+1];
+	char filename[2*FILENAMESIZE+1];
+	char TAdirpath[strlen(tbstpath)+1+TEE_UUID_STRING_SIZE+1];
+	char Filepath[strlen(tbstpath)+1+TEE_UUID_STRING_SIZE+1+2*FILENAMESIZE+1];
+
+	sth_request= &dci->sth_request;
+	//create TA folder name from TA UUID
+	FSD_CreateTaDirName(&sth_request->uuid,tadirname,sizeof(TEE_UUID));
+	FSD_HexFileName(sth_request->filename,filename,FILENAMESIZE);
+
+	//Create path to TA folder and test if does exist
+	strcpy(TAdirpath,tbstpath);
+	strcat(TAdirpath, "/");
+	strcat(TAdirpath, tadirname);
+
+	strcpy(Filepath, TAdirpath);
+	strcat(Filepath, "/");
+	strcat(Filepath, filename);
+	LOG_I("%s: Storage    %s\n", __func__, tbstpath);
+	LOG_I("%s: TA dirname %s\n", __func__, tadirname);
+	LOG_I("%s: filename   %s\n", __func__, filename);
+	LOG_I("%s: fullpath   %s\n", __func__, Filepath);
+	pFile = fopen(Filepath, "r");
+	if (pFile==NULL)
+	{
+		LOG_E("%s: Error looking for file 0x%.8x\n",__func__,TEE_ERROR_ITEM_NOT_FOUND);
+		return TEE_ERROR_ITEM_NOT_FOUND;
+	}
+
+	res = fread(sth_request->payload,sizeof(char),sth_request->payloadLen,pFile);
+	fclose(pFile);
+
+	if ((uint32_t)res != sth_request->payloadLen)
+	{
+		LOG_E("%s: Error reading file res is %d and errno is %s\n",__func__,res,strerror(errno));
+		return TEE_ERROR_ITEM_NOT_FOUND;
+	}
+	return TEE_SUCCESS;
+}
+
+
+mcResult_t FSD::FSD_ReadFile(void){
+	FILE * pFile=NULL;
+	STH_FSD_message_t* sth_request=NULL;
+	size_t res;
+	string storage = getTbStoragePath();
+	const char* tbstpath = storage.c_str();
+	char tadirname[TEE_UUID_STRING_SIZE+1];
+	char filename[2*FILENAMESIZE+1];
+	char TAdirpath[strlen(tbstpath)+1+TEE_UUID_STRING_SIZE+1];
+	char Filepath[strlen(tbstpath)+1+TEE_UUID_STRING_SIZE+1+2*FILENAMESIZE+1];
+
+	sth_request= &dci->sth_request;
+	//create TA folder name from TA UUID
+	FSD_CreateTaDirName(&sth_request->uuid,tadirname,sizeof(TEE_UUID));
+	FSD_HexFileName(sth_request->filename,filename,FILENAMESIZE);
+
+	//Create path to TA folder and test if does exist
+	strcpy(TAdirpath,tbstpath);
+	strcat(TAdirpath, "/");
+	strcat(TAdirpath, tadirname);
+
+	strcpy(Filepath, TAdirpath);
+	strcat(Filepath, "/");
+	strcat(Filepath, filename);
+	LOG_I("%s: Storage    %s\n", __func__, tbstpath);
+	LOG_I("%s: TA dirname %s\n", __func__, tadirname);
+	LOG_I("%s: filename   %s\n", __func__, filename);
+	LOG_I("%s: fullpath   %s\n", __func__, Filepath);
+	pFile = fopen(Filepath, "r");
+	if (pFile==NULL)
+	{
+		LOG_E("%s: Error looking for file 0x%.8x\n", __func__,TEE_ERROR_ITEM_NOT_FOUND);
+		return TEE_ERROR_ITEM_NOT_FOUND;
+	}
+	res = fread(sth_request->payload,sizeof(char),sth_request->payloadLen,pFile);
+
+	fclose(pFile);
+
+	if ((uint32_t)res != sth_request->payloadLen)
+	{
+		LOG_E("%s: Error reading file res is %d and errno is %s\n",__func__,res,strerror(errno));
+		return TEE_ERROR_ITEM_NOT_FOUND;
+	}
+	return TEE_SUCCESS;
+}
+
+
+mcResult_t FSD::FSD_WriteFile(void){
+	FILE * pFile=NULL;
+	int fd=0;
+	STH_FSD_message_t* sth_request=NULL;
+	size_t res=0;
+	int stat=0;
+	string storage = getTbStoragePath();
+	const char* tbstpath = storage.c_str();
+	char tadirname[TEE_UUID_STRING_SIZE+1];
+	char filename[2*FILENAMESIZE+1];
+	char TAdirpath[strlen(tbstpath)+1+TEE_UUID_STRING_SIZE+1];
+	char Filepath[strlen(tbstpath)+1+TEE_UUID_STRING_SIZE+1+2*FILENAMESIZE+1];
+	char Filepath_new[strlen(tbstpath)+TEE_UUID_STRING_SIZE+2*FILENAMESIZE+strlen(NEW_EXT)+1];
+
+	sth_request= &dci->sth_request;
+
+	FSD_CreateTaDirName(&sth_request->uuid,tadirname,sizeof(TEE_UUID));
+	FSD_HexFileName(sth_request->filename,filename,FILENAMESIZE);
+
+	strcpy(TAdirpath,tbstpath);
+	strcat(TAdirpath, "/");
+	strcat(TAdirpath, tadirname);
+
+	stat = mkdir(TAdirpath, 0700);
+	if((stat==-1) && (errno!=EEXIST))
+	{
+		LOG_E("%s: error when creating TA dir: %s (%s)\n",__func__,TAdirpath,strerror(errno));
+		return TEE_ERROR_STORAGE_NO_SPACE;
+	}
+
+	/* Directory exists. */
+	strcpy(Filepath, TAdirpath);
+	strcat(Filepath, "/");
+	strcat(Filepath, filename);
+	strcpy(Filepath_new,Filepath);
+	strcat(Filepath_new, NEW_EXT);
+	LOG_I("%s: Storage    %s\n", __func__, tbstpath);
+	LOG_I("%s: TA dirname %s\n", __func__, tadirname);
+	LOG_I("%s: filename   %s\n", __func__, filename);
+	LOG_I("%s: fullpath   %s\n", __func__, Filepath);
+	LOG_I("%s: filename.new   %s\n", __func__, Filepath_new);
+	if(sth_request->flags == TEE_DATA_FLAG_EXCLUSIVE)
+	{
+		LOG_I("%s: opening file in exclusive mode\n",__func__);
+		fd = open(Filepath, O_WRONLY | O_CREAT | O_EXCL, S_IWUSR);
+		if (fd == -1)
+		{
+			LOG_E("%s: error creating file: %s (%s)\n",__func__,Filepath,strerror(errno));
+			return TEE_ERROR_CORRUPT_OBJECT;
+		}
+		else
+		{
+			close(fd);
+		}
+	}
+	pFile = fopen(Filepath_new, "w");
+	LOG_I("%s: opening file for writing\n",__func__);
+	if(pFile==NULL)
+	{
+		if(remove(Filepath)==-1)
+		{
+			LOG_E("%s: remove failed: %s\n",__func__, strerror(errno));
+		}
+		return TEE_ERROR_STORAGE_NO_SPACE;
+	}
+	res = fwrite(sth_request->payload,sizeof(char),sth_request->payloadLen,pFile);
+
+	if ((uint32_t)res != sth_request->payloadLen)
+	{
+		LOG_E("%s: Error writing file res is %d and errno is %s\n",__func__,res,strerror(errno));
+		fclose(pFile);
+		if(remove(Filepath)==-1)
+		{
+			LOG_E("%s: remove failed: %s\n",__func__, strerror(errno));
+		}
+		if(remove(Filepath_new)==-1)
+		{
+			LOG_E("%s: remove failed: %s\n",__func__, strerror(errno));
+		}
+		return TEE_ERROR_ITEM_NOT_FOUND;
+	}
+	else
+	{
+		res = fclose(pFile);
+		if (res < 0)
+		{
+			LOG_E("%s: Error closing file res is %d and errno is %s\n",__func__,res,strerror(errno));
+			if(remove(Filepath)==-1)
+            {
+                LOG_E("%s: remove failed: %s\n",__func__, strerror(errno));
+            }
+			if(remove(Filepath_new)==-1)
+            {
+                LOG_E("%s: remove failed: %s\n",__func__, strerror(errno));
+            }
+			return TEE_ERROR_STORAGE_NO_SPACE;
+		}
+
+		res = rename(Filepath_new,Filepath);
+		if (res < 0)
+		{
+			LOG_E("%s: Error renaming %s: %s\n",__func__,Filepath_new,strerror(errno));
+			if(remove(Filepath)==-1)
+            {
+                LOG_E("%s: remove failed: %s\n",__func__, strerror(errno));
+            }
+			if(remove(Filepath_new)==-1)
+            {
+                LOG_E("%s: remove failed: %s\n",__func__, strerror(errno));
+            }
+			return TEE_ERROR_STORAGE_NO_SPACE;
+		}
+	}
+	return TEE_SUCCESS;
+}
+
+
+mcResult_t FSD::FSD_DeleteFile(void){
+	FILE * pFile=NULL;
+	mcResult_t ret;
+	size_t res;
+	STH_FSD_message_t* sth_request=NULL;
+	string storage = getTbStoragePath();
+	const char* tbstpath = storage.c_str();
+	char tadirname[TEE_UUID_STRING_SIZE+1];
+	char filename[2*FILENAMESIZE+1];
+	char TAdirpath[strlen(tbstpath)+1+TEE_UUID_STRING_SIZE+1];
+	char Filepath[strlen(tbstpath)+1+TEE_UUID_STRING_SIZE+1+2*FILENAMESIZE+1];
+
+	sth_request= &dci->sth_request;
+
+	//create TA folder name from TA UUID
+	FSD_CreateTaDirName(&sth_request->uuid,tadirname,sizeof(TEE_UUID));
+	FSD_HexFileName(sth_request->filename,filename,FILENAMESIZE);
+
+	//Create path to TA folder and test if does exist
+	strcpy(TAdirpath,tbstpath);
+	strcat(TAdirpath, "/");
+	strcat(TAdirpath, tadirname);
+
+	/* Directory exists. */
+	strcpy(Filepath, TAdirpath);
+	strcat(Filepath, "/");
+	strcat(Filepath, filename);
+	LOG_I("%s: Storage    %s\n", __func__, tbstpath);
+	LOG_I("%s: TA dirname %s\n", __func__, tadirname);
+	LOG_I("%s: filename   %s\n", __func__, filename);
+	LOG_I("%s: fullpath   %s\n", __func__, Filepath);
+
+	pFile = fopen(Filepath, "r");
+	if (pFile==NULL)
+	{
+		LOG_I("%s: file not found: %s (%s)\n",__func__, Filepath, strerror(errno));
+		ret = TEE_SUCCESS;
+	}
+	else
+	{
+		fclose(pFile);
+		if(remove(Filepath)==-1)
+		{
+			ret = TEE_ERROR_STORAGE_NO_SPACE;
+		}
+	}
+
+	res = rmdir(TAdirpath);
+	if ((res < 0) && (errno != ENOTEMPTY) && (errno != EEXIST) && (errno != ENOENT))
+	{
+		ret = TEE_ERROR_STORAGE_NO_SPACE;
+		LOG_E("%s: rmdir failed: %s (%s)\n",__func__, TAdirpath, strerror(errno));
+	}
+	else
+	{
+		ret = TEE_SUCCESS;
+	}
+
+	return ret;
+}
+
+
+//------------------------------------------------------------------------------
+
+/** @} */
diff --git a/MobiCoreDriverLib/Daemon/FSD/public/FSD.h b/MobiCoreDriverLib/Daemon/FSD/public/FSD.h
new file mode 100755
index 0000000..9a44fa6
--- /dev/null
+++ b/MobiCoreDriverLib/Daemon/FSD/public/FSD.h
@@ -0,0 +1,169 @@
+/** @addtogroup MCD_MCDIMPL_DAEMON_SRV
+ * @{
+ * @file
+ *
+ * FSD server.
+ *
+ * Handles incoming storage requests from TA through STH
+ *
+ *
+ * Copyright (c) 2013 TRUSTONIC LIMITED
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the TRUSTONIC LIMITED nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef FSD_H_
+#define FSD_H_
+
+#include <sys/types.h>
+#include <string>
+#include <cstdio>
+#include "CThread.h"
+#include "MobiCoreDriverApi.h"
+#include "drSecureStorage_Api.h"
+#include <errno.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <android/log.h>
+
+
+#define max( a, b ) ( ((a) > (b)) ? (a) : (b) )
+#define DCI_BUFF_SIZE	1000*1024
+
+#define TEE_UUID_STRING_SIZE  	32
+#define FILENAMESIZE			20
+#define NEW_EXT					".new"
+
+#define TAG_LOG	"FSD"
+
+class FSD: public CThread
+{
+
+public:
+    /**
+     * FSD contructor.
+     *
+     * @param tbstoragepath Absolute path to the secure storage
+     */
+    FSD(
+        void
+    );
+
+    /**
+     * FSD destructor.
+     * Close the current session and resources will be freed.
+     */
+    virtual ~FSD(
+        void
+    );
+
+    /**
+     * Start server and listen for incoming request from STH.
+     */
+    virtual void run(void);
+
+    /*
+    *   FSD_Open
+    *
+    *   Open a session with the STH
+    *
+    */
+    virtual mcResult_t FSD_Open(void);
+
+
+    /*
+    *   FSD_Close
+    *
+    *   Close a session opened with the STH
+    *
+    */
+    virtual mcResult_t FSD_Close(void);
+
+
+    /*
+    *   FSD_listenDci
+    *
+    *   DCI listener function
+    *
+    */
+    virtual void FSD_listenDci(void);
+
+
+
+private:
+    mcSessionHandle_t   	sessionHandle; /**< current session */
+    dciMessage_t*       	dci; /**< dci buffer */
+
+
+    /** Private methods*/
+
+    /*
+    *   FSD_ExecuteCommand
+    *
+    *   Execute command received from the STH
+    *
+    */
+    mcResult_t FSD_ExecuteCommand(void);
+
+    /****************************  File operations  *******************************/
+
+    /*
+    *   FSD_LookFile
+    *
+    *   look for a file
+    */
+    mcResult_t FSD_LookFile(void);
+
+
+    /*
+    *   FSD_ReadFile
+    *
+    *   Read a file
+    */
+    mcResult_t FSD_ReadFile(void);
+
+
+    /*
+    *   FSD_WriteFile
+    *
+    *   Write a file
+    */
+    mcResult_t FSD_WriteFile(void);
+
+
+    /*
+    *   FSD_DeleteFile
+    *
+    *   Delete a file
+    */
+    mcResult_t FSD_DeleteFile(void);
+};
+
+#endif /* FSD_H_ */
+
+/** @} */
diff --git a/MobiCoreDriverLib/Daemon/FSD/public/dci.h b/MobiCoreDriverLib/Daemon/FSD/public/dci.h
new file mode 100755
index 0000000..cf0b8c2
--- /dev/null
+++ b/MobiCoreDriverLib/Daemon/FSD/public/dci.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2013 TRUSTONIC LIMITED
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the TRUSTONIC LIMITED nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file   dci.h
+ * @brief  Contains DCI (Driver Control
+ * Interface) definitions and data structures
+ *
+ */
+
+#ifndef __DCI_H__
+#define __DCI_H__
+
+
+typedef uint32_t dciCommandId_t;
+typedef uint32_t dciResponseId_t;
+typedef uint32_t dciReturnCode_t;
+
+/**< Responses have bit 31 set */
+#define RSP_ID_MASK (1U << 31)
+#define RSP_ID(cmdId) (((uint32_t)(cmdId)) | RSP_ID_MASK)
+#define IS_CMD(cmdId) ((((uint32_t)(cmdId)) & RSP_ID_MASK) == 0)
+#define IS_RSP(cmdId) ((((uint32_t)(cmdId)) & RSP_ID_MASK) == RSP_ID_MASK)
+
+/**
+ * Return codes of driver commands.
+ */
+#define RET_OK                    0
+#define RET_ERR_UNKNOWN_CMD       1
+#define RET_ERR_NOT_SUPPORTED     2
+#define RET_ERR_INTERNAL_ERROR    3
+/* ... add more error codes when needed */
+
+/**
+ * DCI command header.
+ */
+typedef struct{
+    dciCommandId_t commandId; /**< Command ID */
+} dciCommandHeader_t;
+
+/**
+ * DCI response header.
+ */
+typedef struct{
+    dciResponseId_t     responseId; /**< Response ID (must be command ID | RSP_ID_MASK )*/
+    dciReturnCode_t     returnCode; /**< Return code of command */
+} dciResponseHeader_t;
+
+#endif // __DCI_H__
diff --git a/MobiCoreDriverLib/Daemon/FSD/public/drSecureStorage_Api.h b/MobiCoreDriverLib/Daemon/FSD/public/drSecureStorage_Api.h
new file mode 100755
index 0000000..46da5ae
--- /dev/null
+++ b/MobiCoreDriverLib/Daemon/FSD/public/drSecureStorage_Api.h
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2013 TRUSTONIC LIMITED
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the TRUSTONIC LIMITED nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/**
+ * @file   drSecureStorage_Api.h
+ * @brief  Contains DCI command definitions and data structures
+ *
+ */
+
+#ifndef __DRTEMPLATEAPI_H__
+#define __DRTEMPLATEAPI_H__
+
+#include "dci.h"
+#include "tee_type.h"
+#include "tee_error.h"
+
+#define RW_DATA_SIZE 4096
+
+/**
+ * Command ID's for communication
+ * FSD <--> STH
+ */
+
+#define STH_MESSAGE_TYPE_LOOK		0
+#define STH_MESSAGE_TYPE_READ     	1
+#define STH_MESSAGE_TYPE_WRITE      2
+#define STH_MESSAGE_TYPE_DELETE     3
+
+#define CMD_ST_SYNC			5
+#define NOTIFY_DCIH			6
+#define NOTIFY_IPCH			7
+/*... add more command ids when needed */
+
+#define STH_PUBLIC_FILE_NAME_SIZE 20
+
+typedef struct {
+    uint32_t   status;
+	uint8_t    type;
+    uint8_t    reserved0;
+    uint16_t   flags;
+    uint32_t   payloadLen;
+    TEE_UUID     uuid;
+    unsigned char filename[STH_PUBLIC_FILE_NAME_SIZE];
+    unsigned char payload[];
+} STH_FSD_message_t;
+
+typedef struct
+{
+    char header[5];
+    unsigned char version;
+    uint16_t cryptoLen;
+    uint32_t dataLen;
+}FSD_plaintext;
+
+/**
+ * command message.
+ *
+ * @param len Lenght of the data to process.
+ * @param data Data to be processed
+ */
+typedef struct {
+    dciCommandHeader_t  header;     /**< Command header */
+    uint32_t            len;        /**< Length of data to process */
+} cmd_t;
+
+
+/**
+ * Response structure
+ */
+typedef struct {
+    dciResponseHeader_t header;     /**< Response header */
+    uint32_t            len;
+} rsp_t;
+
+/**
+ * DCI message data.
+ */
+typedef struct {
+    union {
+        cmd_t     command;
+        rsp_t     response;
+    };
+
+    STH_FSD_message_t   sth_request;
+} dciMessage_t;
+
+/**
+ * Driver UUID. Update accordingly after reserving UUID
+ */
+#define DRV_STH_UUID { { 0x07, 0x05, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
+
+
+#endif // __DRTEMPLATEAPI_H__
diff --git a/daemon/Daemon/MobiCoreDriverDaemon.cpp b/MobiCoreDriverLib/Daemon/MobiCoreDriverDaemon.cpp
old mode 100644
new mode 100755
similarity index 74%
rename from daemon/Daemon/MobiCoreDriverDaemon.cpp
rename to MobiCoreDriverLib/Daemon/MobiCoreDriverDaemon.cpp
index 913f9f7..d20ff8a
--- a/daemon/Daemon/MobiCoreDriverDaemon.cpp
+++ b/MobiCoreDriverLib/Daemon/MobiCoreDriverDaemon.cpp
@@ -5,31 +5,35 @@
  * Entry of the MobiCore Driver.
  */
 
-/* <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
+/*
+ * Copyright (c) 2013 TRUSTONIC LIMITED
+ * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- *    products derived from this software without specific prior
- *    written permission.
  *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 3. Neither the name of the TRUSTONIC LIMITED nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 #include <cstdlib>
@@ -49,6 +53,7 @@
 #include "PrivateRegistry.h"
 #include "MobiCoreDevice.h"
 #include "NetlinkServer.h"
+#include "FSD.h"
 
 #define DRIVER_TCI_LEN 4096
 
@@ -61,6 +66,10 @@
 
 #define LOG_I_RELEASE(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
 
+pthread_mutex_t         syncMutex = PTHREAD_MUTEX_INITIALIZER;
+pthread_cond_t          syncCondition = PTHREAD_COND_INITIALIZER;
+bool 					Th_sync=false;
+
 //------------------------------------------------------------------------------
 MobiCoreDriverDaemon::MobiCoreDriverDaemon(
     bool enableScheduler,
@@ -118,21 +127,21 @@
 
     mobiCoreDevice = getDeviceInstance();
 
-    LOG_I("Initializing Device, Daemon sheduler is %s", 
-          enableScheduler?"enabled" : "disabled");
+    LOG_I("Initializing Device, Daemon sheduler is %s",
+          enableScheduler ? "enabled" : "disabled");
 
-    // initialize device (setup MCI)
+    // initialize device (setupo MCI)
     if (!mobiCoreDevice->initDevice(
                 "/dev/" MC_ADMIN_DEVNODE,
                 enableScheduler)) {
-        LOG_E("Could not initialize MobiCore!");
+        LOG_E("Could not initialize <t-base!");
         return;
     }
 
     // start device (scheduler)
     mobiCoreDevice->start();
 
-    LOG_I_RELEASE("Checking version of MobiCore");
+    LOG_I_RELEASE("Checking version of <t-base");
     checkMobiCoreVersion(mobiCoreDevice);
 
     // Load device driver if requested
@@ -141,6 +150,45 @@
             loadDeviceDriver(drivers[i]);
     }
 
+    /* Look for tokens in the registry and pass them to <t-base for endorsement
+     * purposes.
+     */
+    LOG_I("Looking for suitable tokens");
+
+    mcSoAuthTokenCont_t authtoken;
+    mcSoRootCont_t rootcont;
+    uint32_t sosize;
+    uint8_t *p = NULL;
+
+    mcResult_t ret = mcRegistryReadAuthToken(&authtoken);
+    if (ret != MC_DRV_OK) {
+        LOG_I("Failed to read AuthToken (ret=%u). Trying Root Container", ret);
+
+        sosize = sizeof(rootcont);
+        ret = mcRegistryReadRoot(&rootcont, &sosize);
+        if (ret != MC_DRV_OK) {
+            LOG_I("Failed to read Root Cont, (ret=%u)", ret);
+            LOG_W("Device endorsements not supported!");
+            sosize = 0;
+        }
+        else {
+            LOG_I("Found Root Cont.");
+            p = (uint8_t *) &rootcont;
+        }
+    } else {
+        LOG_I("Found AuthToken.");
+        p = (uint8_t *) &authtoken;
+        sosize = sizeof(authtoken);
+    }
+
+    if (sosize) {
+        LOG_I("Found token of size: %u", sosize);
+        if (!loadToken(p, sosize)) {
+            LOG_E("Failed to pass token to <t-base. "
+                  "Device endorsements disabled");
+        }
+    }
+
     LOG_I("Creating socket servers");
     // Start listening for incoming TLC connections
     servers[0] = new NetlinkServer(this);
@@ -149,13 +197,21 @@
 
     // Start all the servers
     for (i = 0; i < MAX_SERVERS; i++) {
-        servers[i]->start();
+        servers[i]->start(i ? "McDaemon.Server" : "NetlinkServer");
     }
 
+    // Create the <t-base File Storage Daemon
+    FSD *FileStorageDaemon = new FSD();
+    // Start File Storage Daemon
+    FileStorageDaemon->start("McDaemon.FSD");
+
     // then wait for them to exit
     for (i = 0; i < MAX_SERVERS; i++) {
         servers[i]->join();
     }
+    //Wait for File Storage Daemon to exit
+	FileStorageDaemon->join();
+	delete FileStorageDaemon;
 }
 
 //------------------------------------------------------------------------------
@@ -176,7 +232,7 @@
             return true;
         }
         return false;
-        
+
     }
     return false;
 #else
@@ -205,9 +261,13 @@
     MobiCoreDevice *device = (MobiCoreDevice *) (connection->connectionData);
 
     if (device != NULL) {
-        LOG_I("dropConnection(): closing still open device.");
         // A connection has been found and has to be closed
+        LOG_I("dropConnection(): closing still open device.");
+
+        // Make sure nobody else writes the MCP, e.g. netlink/socket server, cleanup of TAs
+        device->mutex_mcp.lock();
         device->close(connection);
+        device->mutex_mcp.unlock();
     }
 }
 
@@ -233,7 +293,6 @@
     CWsm_ptr pWsm = NULL, pTciWsm = NULL;
     regObject_t *regObj = NULL;
     Connection *conn = NULL;
-    uint8_t *tci = NULL;
     mcDrvRspOpenSession_t rspOpenSession;
 
     do {
@@ -261,7 +320,6 @@
         loadDataOpenSession.len = regObj->len;
         loadDataOpenSession.tlHeader = (mclfHeader_ptr) (regObj->value + regObj->tlStartOffset);
 
-        tci = (uint8_t *)malloc(DRIVER_TCI_LEN);
         pTciWsm = mobiCoreDevice->allocateContiguousPersistentWsm(DRIVER_TCI_LEN);
         if (pTciWsm == NULL) {
             LOG_E("allocating WSM TCI for Trustlet failed");
@@ -310,7 +368,7 @@
         }
     } else if (conn != NULL) {
         driverResources.push_back(new MobicoreDriverResources(
-                                      conn, tci, pTciWsm, rspOpenSession.payload.sessionId));
+                                      conn, pTciWsm, rspOpenSession.payload.sessionId));
     }
 
     return ret;
@@ -320,14 +378,14 @@
 { \
     void *payload = (void*)((uint32_t)CMD_BUFFER + sizeof(mcDrvCommandHeader_t)); \
     uint32_t payload_len = sizeof(*CMD_BUFFER) - sizeof(mcDrvCommandHeader_t); \
-    uint32_t rlen = CONNECTION->readData(payload, payload_len); \
+    int32_t rlen = CONNECTION->readData(payload, payload_len); \
     if (rlen < 0) { \
         LOG_E("reading from Client failed"); \
         /* it is questionable, if writing to broken socket has any effect here. */ \
         writeResult(CONNECTION, MC_DRV_ERR_DAEMON_SOCKET); \
         return; \
     } \
-    if (rlen != payload_len) {\
+    if ((uint32_t)rlen != payload_len) {\
         LOG_E("wrong buffer length %i received from Client", rlen); \
         writeResult(CONNECTION, MC_DRV_ERR_DAEMON_SOCKET); \
         return; \
@@ -346,7 +404,7 @@
 inline bool getData(Connection *con, void *buf, uint32_t len)
 {
     uint32_t rlen = con->readData(buf, len);
-    if (rlen < len || rlen < 0) {
+    if (rlen < len || (int32_t)rlen < 0) {
         LOG_E("reading from Client failed");
         return false;
     }
@@ -408,7 +466,7 @@
 
 
 //------------------------------------------------------------------------------
-void MobiCoreDriverDaemon::processOpenSession(Connection *connection)
+void MobiCoreDriverDaemon::processOpenSession(Connection *connection, bool isGpUuid)
 {
     MC_DRV_CMD_OPEN_SESSION_struct cmdOpenSession;
     RECV_PAYLOAD_FROM_CLIENT(connection, &cmdOpenSession);
@@ -418,7 +476,7 @@
     CHECK_DEVICE(device, connection);
 
     // Get service blob from registry
-    regObject_t *regObj = mcRegistryGetServiceBlob(&cmdOpenSession.uuid);
+    regObject_t *regObj = mcRegistryGetServiceBlob(&cmdOpenSession.uuid, isGpUuid);
     if (NULL == regObj) {
         writeResult(connection, MC_DRV_ERR_TRUSTLET_NOT_FOUND);
         return;
@@ -432,6 +490,8 @@
 
     CWsm_ptr pWsm = device->registerWsmL2((addr_t)(regObj->value), regObj->len, 0);
     if (pWsm == NULL) {
+        // Free memory occupied by Trustlet data
+        free(regObj);
         LOG_E("allocating WSM for Trustlet failed");
         writeResult(connection, MC_DRV_ERR_DAEMON_KMOD_ERROR);
         return;
@@ -458,6 +518,7 @@
     // This will also destroy the WSM object.
     if (!device->unregisterWsmL2(pWsm)) {
         // TODO-2012-07-02-haenellu: Can this ever happen? And if so, we should assert(), also TL might still be running.
+        free(regObj);
         writeResult(connection, MC_DRV_ERR_DAEMON_KMOD_ERROR);
         return;
     }
@@ -477,6 +538,73 @@
 }
 
 //------------------------------------------------------------------------------
+mcResult_t MobiCoreDriverDaemon::processLoadCheck(mcSpid_t spid, void *blob, uint32_t size)
+{
+
+    // Device required
+    MobiCoreDevice  *device = getDevice(MC_DEVICE_ID_DEFAULT);
+
+    if (device == NULL) {
+        LOG_E(" No device found");
+        return MC_DRV_ERR_DAEMON_DEVICE_NOT_OPEN;
+    }
+
+    // Get service blob from registry
+    regObject_t *regObj = mcRegistryMemGetServiceBlob(spid, blob, size);
+    if (NULL == regObj) {
+        LOG_E(" mcRegistryMemGetServiceBlob failed");
+        return MC_DRV_ERR_TRUSTLET_NOT_FOUND;
+    }
+    if (regObj->len == 0) {
+        free(regObj);
+        LOG_E("mcRegistryMemGetServiceBlob returned registry object with length equal to zero");
+        return MC_DRV_ERR_TRUSTLET_NOT_FOUND;
+    }
+    LOG_I(" Sharing Service loaded at %p with Secure World", (addr_t)(regObj->value));
+
+    CWsm_ptr pWsm = device->registerWsmL2((addr_t)(regObj->value), regObj->len, 0);
+    if (pWsm == NULL) {
+        // Free memory occupied by Trustlet data
+        free(regObj);
+        LOG_E("allocating WSM for Trustlet failed");
+        return MC_DRV_ERR_DAEMON_KMOD_ERROR;
+    }
+    // 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 + regObj->tlStartOffset);
+
+    mcDrvRspOpenSession_t rspOpenSession;
+    mcResult_t ret = device->checkLoad(
+                         &loadDataOpenSession,
+                         &rspOpenSession.payload);
+
+    // Unregister physical memory from kernel module.
+    LOG_I(" Service buffer was copied to Secure world and processed. Stop sharing of buffer.");
+
+    // This will also destroy the WSM object.
+    if (!device->unregisterWsmL2(pWsm)) {
+        // Free memory occupied by Trustlet data
+        free(regObj);
+        LOG_E("deallocating WSM for Trustlet failed");
+        return MC_DRV_ERR_DAEMON_KMOD_ERROR;
+    }
+
+    // Free memory occupied by Trustlet data
+    free(regObj);
+
+    if (ret != MC_DRV_OK) {
+        LOG_E("TA could not be loaded.");
+        return ret;
+    } else {
+        return MC_DRV_OK;
+    }
+}
+
+
+//------------------------------------------------------------------------------
 void MobiCoreDriverDaemon::processOpenTrustlet(Connection *connection)
 {
     MC_DRV_CMD_OPEN_TRUSTLET_struct cmdOpenTrustlet;
@@ -488,28 +616,28 @@
 
     uint32_t total_len, rlen, len = cmdOpenTrustlet.trustlet_len;
     uint8_t *payload = (uint8_t *)malloc(len);
-    uint8_t *p=payload;
-    if(payload == NULL) {
+    uint8_t *p = payload;
+    if (payload == NULL) {
         LOG_E("failed to allocate payload buffer");
         writeResult(connection, MC_DRV_ERR_DAEMON_SOCKET);
         return;
     }
     total_len = 0;
-    while(total_len < len) {
+    while (total_len < len) {
         rlen = connection->readData(p, len - total_len);
-        if (rlen < 0) {
-                LOG_E("reading from Client failed");
-                /* it is questionable, if writing to broken socket has any effect here. */
-                writeResult(connection, MC_DRV_ERR_DAEMON_SOCKET);
-                free(payload);
-                return;
+        if ((int32_t)rlen < 0) {
+            LOG_E("reading from Client failed");
+            /* it is questionable, if writing to broken socket has any effect here. */
+            writeResult(connection, MC_DRV_ERR_DAEMON_SOCKET);
+            free(payload);
+            return;
         }
         total_len += rlen;
         p += rlen;
     }
 
     // Get service blob from registry
-    regObject_t *regObj = mcRegistryMemGetServiceBlob(cmdOpenTrustlet.spid, (uint8_t*)payload, len);
+    regObject_t *regObj = mcRegistryMemGetServiceBlob(cmdOpenTrustlet.spid, (uint8_t *)payload, len);
 
     // Free the payload object no matter what
     free(payload);
@@ -527,6 +655,7 @@
 
     CWsm_ptr pWsm = device->registerWsmL2((addr_t)(regObj->value), regObj->len, 0);
     if (pWsm == NULL) {
+        free(regObj);
         LOG_E("allocating WSM for Trustlet failed");
         writeResult(connection, MC_DRV_ERR_DAEMON_KMOD_ERROR);
         return;
@@ -552,6 +681,7 @@
 
     // This will also destroy the WSM object.
     if (!device->unregisterWsmL2(pWsm)) {
+        free(regObj);
         // TODO-2012-07-02-haenellu: Can this ever happen? And if so, we should assert(), also TL might still be running.
         writeResult(connection, MC_DRV_ERR_DAEMON_KMOD_ERROR);
         return;
@@ -571,7 +701,6 @@
     }
 }
 
-
 //------------------------------------------------------------------------------
 void MobiCoreDriverDaemon::processCloseSession(Connection *connection)
 {
@@ -645,7 +774,7 @@
     void *payload = (void *)((uint32_t)&cmd + sizeof(mcDrvCommandHeader_t));
     uint32_t payload_len = sizeof(cmd) - sizeof(mcDrvCommandHeader_t);
     uint32_t rlen = connection->readData(payload, payload_len);
-    if (rlen < 0) {
+    if ((int) rlen < 0) {
         LOG_E("reading from Client failed");
         /* it is questionable, if writing to broken socket has any effect here. */
         // NOTE: notify fails silently
@@ -690,8 +819,8 @@
         return;
     }
 
-    uint32_t secureVirtualAdr = NULL;
-    uint32_t pAddrL2 = (uint32_t)device->findWsmL2(cmd.handle, connection->socketDescriptor);
+    uint32_t secureVirtualAdr = (uint32_t)NULL;
+    uint64_t pAddrL2 = device->findWsmL2(cmd.handle, connection->socketDescriptor);
 
     if (pAddrL2 == 0) {
         LOG_E("Failed to resolve WSM with handle %u", cmd.handle);
@@ -728,7 +857,7 @@
 
     // Unmap bulk memory from secure world
     uint32_t mcResult = device->unmapBulk(connection, cmd.sessionId, cmd.handle,
-                                        cmd.secureVirtualAdr, cmd.lenBulkMem);
+                                          cmd.secureVirtualAdr, cmd.lenBulkMem);
 
     if (mcResult != MC_DRV_OK) {
         LOG_V("MCP UNMAP returned code %d", mcResult);
@@ -768,7 +897,7 @@
     MobiCoreDevice *device = (MobiCoreDevice *) (connection->connectionData);
     CHECK_DEVICE(device, connection);
 
-    // Get MobiCore version info from secure world.
+    // Get <t-base version info from secure world.
     mcDrvRspGetMobiCoreVersion_t rspGetMobiCoreVersion;
 
     mcResult_t mcResult = device->getMobiCoreVersion(&rspGetMobiCoreVersion.payload);
@@ -788,9 +917,11 @@
 //------------------------------------------------------------------------------
 void MobiCoreDriverDaemon::processRegistryReadData(uint32_t commandId, Connection  *connection)
 {
-    #define MAX_DATA_SIZE 512
-    mcDrvResponseHeader_t rspRegistry = { responseId : MC_DRV_ERR_INVALID_OPERATION };
-    void *buf = alloca(MAX_DATA_SIZE); 
+#define MAX_DATA_SIZE 512
+mcDrvResponseHeader_t rspRegistry = { responseId :
+                                          MC_DRV_ERR_INVALID_OPERATION
+                                        };
+    void *buf = alloca(MAX_DATA_SIZE);
     uint32_t len = MAX_DATA_SIZE;
     mcSoAuthTokenCont_t auth;
     mcSpid_t spid;
@@ -801,7 +932,7 @@
         return;
     }
 
-    switch(commandId) {
+    switch (commandId) {
     case MC_DRV_REG_READ_AUTH_TOKEN:
         rspRegistry.responseId = mcRegistryReadAuthToken(&auth);
         buf = &auth;
@@ -826,14 +957,16 @@
         break;
     }
     connection->writeData(&rspRegistry, sizeof(rspRegistry));
-    if(rspRegistry.responseId != MC_DRV_ERR_INVALID_OPERATION)
+    if (rspRegistry.responseId != MC_DRV_ERR_INVALID_OPERATION)
         connection->writeData(buf, len);
 }
 
 //------------------------------------------------------------------------------
 void MobiCoreDriverDaemon::processRegistryWriteData(uint32_t commandId, Connection *connection)
 {
-    mcDrvResponseHeader_t rspRegistry = { responseId : MC_DRV_ERR_INVALID_OPERATION };
+mcDrvResponseHeader_t rspRegistry = { responseId :
+                                          MC_DRV_ERR_INVALID_OPERATION
+                                        };
     uint32_t soSize;
     void *so;
 
@@ -843,14 +976,20 @@
     }
 
     // First read the SO data size
-    if(!getData(connection, &soSize, sizeof(soSize))){
+    if (!getData(connection, &soSize, sizeof(soSize))) {
         LOG_E("Failed to read SO data size");
         connection->writeData(&rspRegistry, sizeof(rspRegistry));
-        return;    
+        return;
     }
     so = malloc(soSize);
+    if (so == NULL) {
+        LOG_E("Allocation failure");
+        rspRegistry.responseId = MC_DRV_ERR_NO_FREE_MEMORY;
+        connection->writeData(&rspRegistry, sizeof(rspRegistry));
+        return;
+    }
 
-    switch(commandId) {
+    switch (commandId) {
     case MC_DRV_REG_STORE_AUTH_TOKEN: {
         if (!getData(connection, so, soSize))
             break;
@@ -890,6 +1029,34 @@
         rspRegistry.responseId = mcRegistryStoreData(so, soSize);
         break;
     }
+    case MC_DRV_REG_STORE_TA_BLOB: {
+        uint32_t blobSize = soSize;
+        mcSpid_t spid;
+        void     *blob;
+        if (!getData(connection, &spid, sizeof(spid)))
+            break;
+        blob = malloc(blobSize);
+        if (blob == NULL) {
+            LOG_E("Allocation failure");
+            rspRegistry.responseId = MC_DRV_ERR_NO_FREE_MEMORY;
+            break;
+        }
+        if (!getData(connection, blob, blobSize)) {
+            free(blob);
+            break;
+        }
+        //LOG_I("processLoadCheck");
+        rspRegistry.responseId = processLoadCheck(spid, blob, blobSize);
+        if (rspRegistry.responseId != MC_DRV_OK){
+            LOG_I("processLoadCheck failed");
+            free(blob);
+            break;
+        }
+        //LOG_I("mcRegistryStoreTABlob");
+        rspRegistry.responseId = mcRegistryStoreTABlob(spid, blob, blobSize);
+        free(blob);
+        break;
+    }
     default:
         break;
     }
@@ -900,7 +1067,9 @@
 //------------------------------------------------------------------------------
 void MobiCoreDriverDaemon::processRegistryDeleteData(uint32_t commandId, Connection *connection)
 {
-    mcDrvResponseHeader_t rspRegistry = { responseId : MC_DRV_ERR_INVALID_OPERATION };
+mcDrvResponseHeader_t rspRegistry = { responseId :
+                                          MC_DRV_ERR_INVALID_OPERATION
+                                        };
     mcSpid_t spid;
 
     if (!checkPermission(connection)) {
@@ -908,7 +1077,7 @@
         return;
     }
 
-    switch(commandId) {
+    switch (commandId) {
     case MC_DRV_REG_DELETE_AUTH_TOKEN:
         rspRegistry.responseId = mcRegistryDeleteAuthToken();
         break;
@@ -941,16 +1110,18 @@
 )
 {
     bool ret = false;
-    static CMutex mutex;
+
+    // This is the big lock around everything the Daemon does, including socket and MCI access
+    static CMutex reg_mutex;
+    static CMutex siq_mutex;
 
     /* In case of RTM fault do not try to signal anything to MobiCore
      * just answer NO to all incoming connections! */
     if (mobiCoreDevice->getMcFault()) {
-        LOG_I("Ignore request, MobiCore has faulted before.");
+        LOG_I("Ignore request, <t-base has faulted before.");
         return false;
     }
-
-    mutex.lock();
+   
     LOG_I("handleConnection()==== %p", connection);
     do {
         // Read header
@@ -976,39 +1147,63 @@
         switch (mcDrvCommandHeader.commandId) {
             //-----------------------------------------
         case MC_DRV_CMD_OPEN_DEVICE:
+            mobiCoreDevice->mutex_mcp.lock();
             processOpenDevice(connection);
+            mobiCoreDevice->mutex_mcp.unlock();
             break;
             //-----------------------------------------
         case MC_DRV_CMD_CLOSE_DEVICE:
+            mobiCoreDevice->mutex_mcp.lock();
             processCloseDevice(connection);
+            mobiCoreDevice->mutex_mcp.unlock();
             break;
             //-----------------------------------------
         case MC_DRV_CMD_OPEN_SESSION:
-            processOpenSession(connection);
+            mobiCoreDevice->mutex_mcp.lock();
+            processOpenSession(connection, false);
+            mobiCoreDevice->mutex_mcp.unlock();
             break;
             //-----------------------------------------
         case MC_DRV_CMD_OPEN_TRUSTLET:
+            mobiCoreDevice->mutex_mcp.lock();
             processOpenTrustlet(connection);
+            mobiCoreDevice->mutex_mcp.unlock();
+            break;
+            //-----------------------------------------
+        case MC_DRV_CMD_OPEN_TRUSTED_APP:
+            mobiCoreDevice->mutex_mcp.lock();
+            processOpenSession(connection, true);
+            mobiCoreDevice->mutex_mcp.unlock();
             break;
             //-----------------------------------------
         case MC_DRV_CMD_CLOSE_SESSION:
+            mobiCoreDevice->mutex_mcp.lock();
             processCloseSession(connection);
+            mobiCoreDevice->mutex_mcp.unlock();
             break;
             //-----------------------------------------
         case MC_DRV_CMD_NQ_CONNECT:
+            siq_mutex.lock();
             processNqConnect(connection);
+            siq_mutex.unlock();
             break;
             //-----------------------------------------
         case MC_DRV_CMD_NOTIFY:
+            siq_mutex.lock();
             processNotify(connection);
+            siq_mutex.unlock();
             break;
             //-----------------------------------------
         case MC_DRV_CMD_MAP_BULK_BUF:
+            mobiCoreDevice->mutex_mcp.lock();
             processMapBulkBuf(connection);
+            mobiCoreDevice->mutex_mcp.unlock();
             break;
             //-----------------------------------------
         case MC_DRV_CMD_UNMAP_BULK_BUF:
+            mobiCoreDevice->mutex_mcp.lock();
             processUnmapBulkBuf(connection);
+            mobiCoreDevice->mutex_mcp.unlock();
             break;
             //-----------------------------------------
         case MC_DRV_CMD_GET_VERSION:
@@ -1016,33 +1211,42 @@
             break;
             //-----------------------------------------
         case MC_DRV_CMD_GET_MOBICORE_VERSION:
+            mobiCoreDevice->mutex_mcp.lock();
             processGetMobiCoreVersion(connection);
+            mobiCoreDevice->mutex_mcp.unlock();
             break;
             //-----------------------------------------
-        /* Registry functionality */
-        // Write Registry Data
+            /* Registry functionality */
+            // Write Registry Data
         case MC_DRV_REG_STORE_AUTH_TOKEN:
         case MC_DRV_REG_WRITE_ROOT_CONT:
         case MC_DRV_REG_WRITE_SP_CONT:
         case MC_DRV_REG_WRITE_TL_CONT:
         case MC_DRV_REG_WRITE_SO_DATA:
+        case MC_DRV_REG_STORE_TA_BLOB:
+            reg_mutex.lock();
             processRegistryWriteData(mcDrvCommandHeader.commandId, connection);
+            reg_mutex.unlock();
             break;
             //-----------------------------------------
-        // Read Registry Data
+            // Read Registry Data
         case MC_DRV_REG_READ_AUTH_TOKEN:
         case MC_DRV_REG_READ_ROOT_CONT:
         case MC_DRV_REG_READ_SP_CONT:
         case MC_DRV_REG_READ_TL_CONT:
+            reg_mutex.lock();
             processRegistryReadData(mcDrvCommandHeader.commandId, connection);
+            reg_mutex.unlock();
             break;
             //-----------------------------------------
-        // Delete registry data
+            // Delete registry data
         case MC_DRV_REG_DELETE_AUTH_TOKEN:
         case MC_DRV_REG_DELETE_ROOT_CONT:
         case MC_DRV_REG_DELETE_SP_CONT:
         case MC_DRV_REG_DELETE_TL_CONT:
+            reg_mutex.lock();
             processRegistryDeleteData(mcDrvCommandHeader.commandId, connection);
+            reg_mutex.unlock();
             break;
             //-----------------------------------------
         default:
@@ -1053,7 +1257,7 @@
             break;
         }
     } while (0);
-    mutex.unlock();
+    
     LOG_I("handleConnection()<-------");
 
     return ret;
@@ -1070,17 +1274,17 @@
 )
 {
 #ifdef MOBICORE_COMPONENT_BUILD_TAG
-    fprintf(stderr, "MobiCore Driver Daemon %u.%u. \"%s\" %s %s\n", DAEMON_VERSION_MAJOR, DAEMON_VERSION_MINOR, MOBICORE_COMPONENT_BUILD_TAG, __DATE__, __TIME__);
+    fprintf(stderr, "<t-base Driver Daemon %u.%u. \"%s\" %s %s\n", DAEMON_VERSION_MAJOR, DAEMON_VERSION_MINOR, MOBICORE_COMPONENT_BUILD_TAG, __DATE__, __TIME__);
 #else
 #warning "MOBICORE_COMPONENT_BUILD_TAG is not defined!"
 #endif
 
-    fprintf(stderr, "usage: %s [-mdsbh]\n", args[0]);
-    fprintf(stderr, "Start MobiCore Daemon\n\n");
+    fprintf(stderr, "usage: %s [-mdsbhp]\n", args[0]);
+    fprintf(stderr, "Start <t-base Daemon\n\n");
     fprintf(stderr, "-h\t\tshow this help\n");
     fprintf(stderr, "-b\t\tfork to background\n");
     fprintf(stderr, "-s\t\tdisable daemon scheduler(default enabled)\n");
-    fprintf(stderr, "-r DRIVER\tMobiCore driver to load at start-up\n");
+    fprintf(stderr, "-r DRIVER\t<t-base driver to load at start-up\n");
 }
 
 //------------------------------------------------------------------------------
@@ -1098,11 +1302,11 @@
 
 //------------------------------------------------------------------------------
 /**
- * Main entry of the MobiCore Driver Daemon.
+ * Main entry of the <t-base Driver Daemon.
  */
 int main(int argc, char *args[])
 {
-    // Create the MobiCore Driver Singleton
+    // Create the <t-base Driver Singleton
     MobiCoreDriverDaemon *mobiCoreDriverDaemon = NULL;
     // Process signal action
     struct sigaction action;
@@ -1118,7 +1322,12 @@
     std::vector<std::string> drivers;
     // By default don't fork
     bool forkDaemon = false;
-    while ((c = getopt(argc, args, "r:sbh")) != -1) {
+
+    /* Initialize mutex and condition variable objects */
+    pthread_mutex_init(&syncMutex, NULL);
+    pthread_cond_init (&syncCondition, NULL);
+
+    while ((c = getopt(argc, args, "r:sbhp:")) != -1) {
         switch (c) {
         case 'h': /* Help */
             errFlag++;
@@ -1129,7 +1338,7 @@
         case 'b': /* Fork to background */
             forkDaemon = true;
             break;
-        case 'r': /* Load mobicore driver at start-up */
+        case 'r': /* Load <t-base driver at start-up */
             driverLoadFlag = 1;
             drivers.push_back(optarg);
             break;
@@ -1149,6 +1358,10 @@
 
     // We should fork the daemon to background
     if (forkDaemon == true) {
+
+        /* ignore terminal has been closed signal */
+        signal(SIGHUP, SIG_IGN);
+
         int i = fork();
         if (i < 0) {
             exit(1);
@@ -1179,7 +1392,6 @@
     sigemptyset (&action.sa_mask);
     action.sa_flags = 0;
     sigaction (SIGINT, &action, NULL);
-    sigaction (SIGHUP, &action, NULL);
     sigaction (SIGTERM, &action, NULL);
     signal(SIGPIPE, SIG_IGN);
 
@@ -1195,8 +1407,11 @@
 
     delete mobiCoreDriverDaemon;
 
+    pthread_mutex_destroy(&syncMutex);
+    pthread_cond_destroy(&syncCondition);
+
     // This should not happen
-    LOG_E("Exiting MobiCoreDaemon");
+    LOG_E("Exiting <t-base Daemon");
 
     return EXIT_FAILURE;
 }
@@ -1213,12 +1428,12 @@
     mcResult_t mcResult = mobiCoreDevice->getMobiCoreVersion(&versionPayload);
 
     if (mcResult != MC_DRV_OK) {
-        LOG_E("Failed to obtain MobiCore version info. MCP return code: %u", mcResult);
+        LOG_E("Failed to obtain <t-base version info. MCP return code: %u", mcResult);
         failed = true;
     } else {
-    	LOG_I_RELEASE("Product ID is %s", versionPayload.versionInfo.productId);
+        LOG_I_RELEASE("Product ID is %s", versionPayload.versionInfo.productId);
 
-        // Check MobiCore version info.
+        // Check <t-base version info.
         char *msg;
         if (!checkVersionOkMCI(versionPayload.versionInfo.versionMci, &msg)) {
             LOG_E("%s", msg);
@@ -1247,4 +1462,49 @@
     }
 }
 
+//------------------------------------------------------------------------------
+bool MobiCoreDriverDaemon::loadToken(uint8_t *token, uint32_t sosize)
+{
+    bool ret = false;
+    CWsm_ptr pWsm = NULL;
+    Connection *conn = NULL;
+
+    do {
+        LOG_I("registering L2 in kmod, p=%p, len=%i", token, sosize);
+
+        pWsm = mobiCoreDevice->registerWsmL2((addr_t) (token), sosize, 0);
+        if (pWsm == NULL) {
+            LOG_E("allocating WSM for Token failed");
+            break;
+        }
+
+        /* Initialize information data of LOAD_TOKEN command */
+        loadTokenData_t loadTokenData;
+        loadTokenData.addr = pWsm->physAddr;
+        loadTokenData.offs = ((uint32_t) token) & 0xFFF;
+        loadTokenData.len = sosize;
+
+        conn = new Connection();
+        uint32_t mcRet = mobiCoreDevice->loadToken(conn, &loadTokenData);
+
+        /* Unregister physical memory from kernel module. This will also destroy
+         * the WSM object.
+         */
+        mobiCoreDevice->unregisterWsmL2(pWsm);
+        pWsm = NULL;
+
+        if (mcRet != MC_MCP_RET_OK) {
+            LOG_E("LOAD_TOKEN error 0x%x", mcRet);
+            break;
+        }
+        ret = true;
+
+    } while (false);
+
+    delete pWsm;
+    delete conn;
+
+    return ret;
+}
+
 /** @} */
diff --git a/daemon/Daemon/MobiCoreDriverDaemon.h b/MobiCoreDriverLib/Daemon/MobiCoreDriverDaemon.h
old mode 100644
new mode 100755
similarity index 70%
rename from daemon/Daemon/MobiCoreDriverDaemon.h
rename to MobiCoreDriverLib/Daemon/MobiCoreDriverDaemon.h
index 497ac50..148d457
--- a/daemon/Daemon/MobiCoreDriverDaemon.h
+++ b/MobiCoreDriverLib/Daemon/MobiCoreDriverDaemon.h
@@ -2,34 +2,38 @@
  * @{
  * @file
  *
- * MobiCore driver class.
- * The MobiCore driver class implements the ConnectionHandler interface.
+ * <t-base driver class.
+ * The <t-base driver class implements the ConnectionHandler interface.
  *
- * <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
+ *
+ * Copyright (c) 2013 TRUSTONIC LIMITED
+ * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- *    products derived from this software without specific prior
- *    written permission.
  *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 3. Neither the name of the TRUSTONIC LIMITED nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 #ifndef MOBICOREDRIVER_H_
 #define MOBICOREDRIVER_H_
@@ -44,17 +48,17 @@
 
 #define MAX_SERVERS 2
 
+extern string getTlRegistryPath();
+
 class MobicoreDriverResources
 {
 public:
     Connection *conn;
     CWsm *pTciWsm;
-    uint8_t *tci;
     uint32_t sessionId;
 
     MobicoreDriverResources(
         Connection *conn,
-        uint8_t *tci,
         CWsm *pTciWsm,
         uint32_t sessionId
     ) {
@@ -81,7 +85,7 @@
     MobiCoreDriverDaemon(
         bool enableScheduler,
 
-        /**< Mobicore driver loading at start-up */
+        /**< <t-base driver loading at start-up */
         bool loadDriver,
         std::vector<std::string> drivers
     );
@@ -151,7 +155,18 @@
      *
      * @param connection Connection object
      */
-    void processOpenSession(Connection *connection);
+    void processOpenSession(Connection *connection, bool isGpUuid);
+
+    /**
+     * Check Load TA command
+     *
+     * @param spid claimed
+     * @param blob TA blob pointer
+     * @param size TA blob pointer size
+     * @return true in case of success, false in case of failure
+     */
+
+    mcResult_t processLoadCheck(mcSpid_t spid, void *blob, uint32_t size);
 
     /**
      * Open Trustlet command
@@ -239,6 +254,16 @@
      * @param connection Connection object
      */
     void processRegistryDeleteData(uint32_t commandId, Connection *connection);
+
+    /**
+     * Load Token
+     * This function loads a token (if found) from the registry and uses it as
+     * the basis for the device attestation functionality
+     *
+     * @param token the token to base the attestation on (raw format)
+     * @param sosize the size of the token
+     */
+    bool loadToken(uint8_t *token, uint32_t sosize);
 };
 
 #endif /* MOBICOREDRIVER_H_ */
diff --git a/daemon/Daemon/Server/Android.mk b/MobiCoreDriverLib/Daemon/Server/Android.mk
old mode 100644
new mode 100755
similarity index 100%
rename from daemon/Daemon/Server/Android.mk
rename to MobiCoreDriverLib/Daemon/Server/Android.mk
diff --git a/daemon/Daemon/Server/NetlinkServer.cpp b/MobiCoreDriverLib/Daemon/Server/NetlinkServer.cpp
old mode 100644
new mode 100755
similarity index 82%
rename from daemon/Daemon/Server/NetlinkServer.cpp
rename to MobiCoreDriverLib/Daemon/Server/NetlinkServer.cpp
index 8ed10dd..e890877
--- a/daemon/Daemon/Server/NetlinkServer.cpp
+++ b/MobiCoreDriverLib/Daemon/Server/NetlinkServer.cpp
@@ -6,31 +6,35 @@
  *
  * Handles incoming socket connections from clients using the MobiCore driver.
  */
-/* <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
+/*
+ * Copyright (c) 2013 TRUSTONIC LIMITED
+ * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- *    products derived from this software without specific prior
- *    written permission.
  *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 3. Neither the name of the TRUSTONIC LIMITED nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 #include "public/NetlinkServer.h"
 #include <unistd.h>
@@ -81,6 +85,7 @@
         if (bind(serverSock, (struct sockaddr *)&src_addr, sizeof(src_addr)) < 0) {
             LOG_ERRNO("Binding to server socket failed, because bind");
             close(serverSock);
+            serverSock = -1;
             break;
         }
 
@@ -90,6 +95,10 @@
         for (;;) {
             // This buffer will be taken over by the connection it was routed to
             nlh = (struct nlmsghdr *)malloc(NLMSG_SPACE(MAX_PAYLOAD));
+            if (nlh == NULL) {
+                LOG_E("Allocation failure");
+                break;
+            }
             memset(&msg, 0, sizeof(msg));
             iov.iov_base = (void *)nlh;
             iov.iov_len = NLMSG_SPACE(MAX_PAYLOAD);
@@ -100,9 +109,9 @@
 
             memset(nlh, 0, NLMSG_SPACE(MAX_PAYLOAD));
 
-            // Read the incomming message and route it to the connection based
-            // on the incomming PID
-            if ((len = recvmsg(serverSock, &msg, 0)) < 0) {
+            // Read the incoming message and route it to the connection based
+            // on the incoming PID
+            if ((int) (len = recvmsg(serverSock, &msg, 0)) < 0) {
                 LOG_ERRNO("recvmsg");
                 break;
             }
@@ -113,6 +122,8 @@
                 break;
             }
         }
+        close(serverSock);
+        serverSock = -1;
     } while (false);
 
     LOG_W("Could not open netlink socket. KernelAPI disabled");
@@ -180,7 +191,10 @@
 {
     connectionMap_t::iterator i;
     // Shut down the server socket
-    close(serverSock);
+    if(serverSock != -1) {
+        close(serverSock);
+        serverSock = -1;
+    }
 
     // Destroy all client connections
     for (i = peerConnections.begin(); i != peerConnections.end(); i++) {
diff --git a/daemon/Daemon/Server/Server.cpp b/MobiCoreDriverLib/Daemon/Server/Server.cpp
old mode 100644
new mode 100755
similarity index 82%
rename from daemon/Daemon/Server/Server.cpp
rename to MobiCoreDriverLib/Daemon/Server/Server.cpp
index ae08fe8..540e666
--- a/daemon/Daemon/Server/Server.cpp
+++ b/MobiCoreDriverLib/Daemon/Server/Server.cpp
@@ -6,31 +6,35 @@
  *
  * Handles incoming socket connections from clients using the MobiCore driver.
  */
-/* <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
+/*
+ * Copyright (c) 2013 TRUSTONIC LIMITED
+ * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- *    products derived from this software without specific prior
- *    written permission.
  *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 3. Neither the name of the TRUSTONIC LIMITED nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 #include "public/Server.h"
 #include <unistd.h>
@@ -40,6 +44,10 @@
 //#define LOG_VERBOSE
 #include "log.h"
 
+extern pthread_mutex_t         syncMutex;
+extern pthread_cond_t          syncCondition;
+extern bool Th_sync;
+
 //------------------------------------------------------------------------------
 Server::Server(
     ConnectionHandler *connectionHandler,
@@ -47,6 +55,7 @@
 ) : socketAddr(localAddr)
 {
     this->connectionHandler = connectionHandler;
+    this->serverSock = -1;
 }
 
 
@@ -56,6 +65,8 @@
 )
 {
     do {
+        pthread_mutex_lock(&syncMutex);
+
         LOG_I("Server: start listening on socket %s", socketAddr.c_str());
 
         // Open a socket (a UNIX domain stream socket)
@@ -85,6 +96,8 @@
 
         LOG_I("\n********* successfully initialized Daemon *********\n");
 
+
+
         for (;;) {
             fd_set fdReadSockets;
 
@@ -107,6 +120,10 @@
                 }
             }
 
+            pthread_cond_signal(&syncCondition);
+            Th_sync=true;
+            pthread_mutex_unlock(&syncMutex);
+
             // Wait for activities, select() returns the number of sockets
             // which require processing
             LOG_V(" Server: waiting on sockets");
@@ -221,7 +238,10 @@
 )
 {
     // Shut down the server socket
-    close(serverSock);
+    if(serverSock != -1) {
+        close(serverSock);
+        serverSock = -1;
+    }
 
     // Destroy all client connections
     connectionIterator_t iterator = peerConnections.begin();
diff --git a/MobiCoreDriverLib/Daemon/Server/public/ConnectionHandler.h b/MobiCoreDriverLib/Daemon/Server/public/ConnectionHandler.h
new file mode 100755
index 0000000..f647398
--- /dev/null
+++ b/MobiCoreDriverLib/Daemon/Server/public/ConnectionHandler.h
@@ -0,0 +1,73 @@
+/** @addtogroup MCD_MCDIMPL_DAEMON_SRV
+ * @{
+ * @file
+ *
+ * Interface for connection handlers used by Server.
+ *
+ *
+ * Copyright (c) 2013 TRUSTONIC LIMITED
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the TRUSTONIC LIMITED nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef CONNECTIONHANDLER_H_
+#define CONNECTIONHANDLER_H_
+
+#include "Connection.h"
+
+
+class ConnectionHandler
+{
+
+public:
+    virtual ~ConnectionHandler() {};
+
+    /**
+     * Handle connection activities.
+     * The connection handler shall process pending connection activities.
+     *
+     * @param [in] connection Reference to the connection which has data to process.
+     */
+    virtual bool handleConnection(
+        Connection *connection
+    ) = 0;
+
+    /**
+     * Connection has been closed.
+     * The connection handler shall clean up all resources associated with the given connection.
+     * After the method has been executed the connection object will be deleted.
+     *
+     * @param [in] connection Reference to the connection which will be deleted.
+     */
+    virtual void dropConnection(
+        Connection *connection
+    ) = 0;
+};
+
+#endif /* CONNECTIONHANDLER_H_ */
+
+/** @} */
diff --git a/daemon/Daemon/Server/public/NetlinkServer.h b/MobiCoreDriverLib/Daemon/Server/public/NetlinkServer.h
old mode 100644
new mode 100755
similarity index 76%
rename from daemon/Daemon/Server/public/NetlinkServer.h
rename to MobiCoreDriverLib/Daemon/Server/public/NetlinkServer.h
index 035d108..14e8b85
--- a/daemon/Daemon/Server/public/NetlinkServer.h
+++ b/MobiCoreDriverLib/Daemon/Server/public/NetlinkServer.h
@@ -8,31 +8,35 @@
  *
  * Iterative socket server using Netlink dgram protocol.
  *
- * <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
+ *
+ * Copyright (c) 2013 TRUSTONIC LIMITED
+ * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- *    products derived from this software without specific prior
- *    written permission.
  *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 3. Neither the name of the TRUSTONIC LIMITED nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 #ifndef NETLINKSERVER_H_
 #define NETLINKSERVER_H_
diff --git a/daemon/Daemon/Server/public/Server.h b/MobiCoreDriverLib/Daemon/Server/public/Server.h
old mode 100644
new mode 100755
similarity index 67%
rename from daemon/Daemon/Server/public/Server.h
rename to MobiCoreDriverLib/Daemon/Server/public/Server.h
index 7924978..fb09f23
--- a/daemon/Daemon/Server/public/Server.h
+++ b/MobiCoreDriverLib/Daemon/Server/public/Server.h
@@ -8,31 +8,35 @@
  *
  * Iterative socket server using UNIX domain stream protocol.
  *
- * <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
+ *
+ * Copyright (c) 2013 TRUSTONIC LIMITED
+ * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- *    products derived from this software without specific prior
- *    written permission.
  *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 3. Neither the name of the TRUSTONIC LIMITED nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 #ifndef SERVER_H_
 #define SERVER_H_
diff --git a/daemon/Daemon/public/MobiCoreDriverCmd.h b/MobiCoreDriverLib/Daemon/public/MobiCoreDriverCmd.h
old mode 100644
new mode 100755
similarity index 81%
rename from daemon/Daemon/public/MobiCoreDriverCmd.h
rename to MobiCoreDriverLib/Daemon/public/MobiCoreDriverCmd.h
index b9f73b6..4ec72b5
--- a/daemon/Daemon/public/MobiCoreDriverCmd.h
+++ b/MobiCoreDriverLib/Daemon/public/MobiCoreDriverCmd.h
@@ -2,31 +2,35 @@
  * @{
  * @file
  *
- * <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
+ *
+ * Copyright (c) 2013 TRUSTONIC LIMITED
+ * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- *    products derived from this software without specific prior
- *    written permission.
  *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 3. Neither the name of the TRUSTONIC LIMITED nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 #ifndef MCDAEMON_H_
 #define MCDAEMON_H_
@@ -52,6 +56,7 @@
     MC_DRV_CMD_GET_VERSION          = 10,
     MC_DRV_CMD_GET_MOBICORE_VERSION = 11,
     MC_DRV_CMD_OPEN_TRUSTLET        = 12,
+    MC_DRV_CMD_OPEN_TRUSTED_APP     = 13,
 
     // Registry Commands
 
@@ -73,14 +78,17 @@
     MC_DRV_REG_DELETE_TL_CONT       = 0x10000B,
     // Shared Object Data write
     MC_DRV_REG_WRITE_SO_DATA        = 0x10000C,
+    // TA Blob store
+    MC_DRV_REG_STORE_TA_BLOB        = 0x10000D,
+
 } mcDrvCmd_t;
 
 typedef struct {
-    uint32_t  commandId;
+    mcDrvCmd_t  commandId;
 } mcDrvCommandHeader_t;
 
 typedef struct {
-    /* MobiCore Daemon uses Client API return codes also in commands between Daemon and Client Library. */
+    /* <t-base Daemon uses Client API return codes also in commands between Daemon and Client Library. */
     uint32_t  responseId;
 } mcDrvResponseHeader_t;
 
@@ -150,6 +158,16 @@
 } mcDrvRspOpenTrustlet_t;
 
 //--------------------------------------------------------------
+struct MC_DRV_CMD_OPEN_TRUSTED_APP_struct {
+    uint32_t  commandId;
+    uint32_t  deviceId;
+    mcUuid_t  uuid;
+    uint32_t  tci;
+    uint32_t  handle;
+    uint32_t  len;
+};
+
+//--------------------------------------------------------------
 struct MC_DRV_CMD_CLOSE_SESSION_struct {
     uint32_t  commandId;
     uint32_t  sessionId;
@@ -172,7 +190,7 @@
     uint32_t  commandId;
     uint32_t  sessionId;
     uint32_t  handle;
-    uint32_t  pAddrL2;
+    uint32_t  rfu;
     uint32_t  offsetPayload;
     uint32_t  lenBulkMem;
 };
@@ -246,6 +264,7 @@
     MC_DRV_CMD_CLOSE_DEVICE_struct      mcDrvCmdCloseDevice;
     MC_DRV_CMD_OPEN_SESSION_struct      mcDrvCmdOpenSession;
     MC_DRV_CMD_OPEN_TRUSTLET_struct     mcDrvCmdOpenTrustlet;
+    MC_DRV_CMD_OPEN_TRUSTED_APP_struct  mcDrvCmdOpenTrustedApp;
     MC_DRV_CMD_CLOSE_SESSION_struct     mcDrvCmdCloseSession;
     MC_DRV_CMD_NQ_CONNECT_struct        mcDrvCmdNqConnect;
     MC_DRV_CMD_NOTIFY_struct            mcDrvCmdNotify;
diff --git a/MobiCoreDriverLib/Daemon/public/mcVersion.h b/MobiCoreDriverLib/Daemon/public/mcVersion.h
new file mode 100755
index 0000000..a6cd02d
--- /dev/null
+++ b/MobiCoreDriverLib/Daemon/public/mcVersion.h
@@ -0,0 +1,39 @@
+/**
+ *
+ * Copyright (c) 2013 TRUSTONIC LIMITED
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the TRUSTONIC LIMITED nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef DAEMON_VERSION_H_
+#define DAEMON_VERSION_H_
+
+#define DAEMON_VERSION_MAJOR 0
+#define DAEMON_VERSION_MINOR 2
+
+#endif /** DAEMON_VERSION_H_ */
+
diff --git a/daemon/Kernel/Android.mk b/MobiCoreDriverLib/Kernel/Android.mk
old mode 100644
new mode 100755
similarity index 100%
rename from daemon/Kernel/Android.mk
rename to MobiCoreDriverLib/Kernel/Android.mk
diff --git a/daemon/Kernel/CKMod.cpp b/MobiCoreDriverLib/Kernel/CKMod.cpp
old mode 100644
new mode 100755
similarity index 63%
rename from daemon/Kernel/CKMod.cpp
rename to MobiCoreDriverLib/Kernel/CKMod.cpp
index 030089d..a2fe40f
--- a/daemon/Kernel/CKMod.cpp
+++ b/MobiCoreDriverLib/Kernel/CKMod.cpp
@@ -4,31 +4,35 @@
  *
  * Kernel Module Interface.
  *
- * <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
+ *
+ * Copyright (c) 2013 TRUSTONIC LIMITED
+ * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- *    products derived from this software without specific prior
- *    written permission.
  *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 3. Neither the name of the TRUSTONIC LIMITED nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 #include <cstdlib>
 
diff --git a/MobiCoreDriverLib/Kernel/CKMod.h b/MobiCoreDriverLib/Kernel/CKMod.h
new file mode 100755
index 0000000..d0022e2
--- /dev/null
+++ b/MobiCoreDriverLib/Kernel/CKMod.h
@@ -0,0 +1,81 @@
+/** @addtogroup MCD_MCDIMPL_DAEMON_KERNEL
+ * @{
+ * @file
+ *
+ * Kernel Module Interface.
+ *
+ *
+ * Copyright (c) 2013 TRUSTONIC LIMITED
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the TRUSTONIC LIMITED nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef CKMOD_H_
+#define CKMOD_H_
+
+#include <stdint.h>
+#include "ClientLib/public/MobiCoreDriverApi.h"
+
+
+/**
+ * Base class for accessing a kernel module.
+ */
+class CKMod
+{
+
+protected:
+
+    int  fdKMod;
+
+    /**
+     * Helper function to check if connected to kernel module.
+     */
+    bool isOpen(
+        void
+    );
+
+public:
+
+    CKMod(
+        void
+    );
+
+    virtual ~CKMod(
+        void
+    );
+
+    mcResult_t open(
+        const char *deviceName
+    );
+
+    void close(
+        void
+    );
+
+};
+
+#endif // CKMOD_H_
diff --git a/daemon/Kernel/Platforms/Generic/Android.mk b/MobiCoreDriverLib/Kernel/Platforms/Generic/Android.mk
old mode 100644
new mode 100755
similarity index 100%
rename from daemon/Kernel/Platforms/Generic/Android.mk
rename to MobiCoreDriverLib/Kernel/Platforms/Generic/Android.mk
diff --git a/daemon/Kernel/Platforms/Generic/CMcKMod.cpp b/MobiCoreDriverLib/Kernel/Platforms/Generic/CMcKMod.cpp
old mode 100644
new mode 100755
similarity index 80%
rename from daemon/Kernel/Platforms/Generic/CMcKMod.cpp
rename to MobiCoreDriverLib/Kernel/Platforms/Generic/CMcKMod.cpp
index 06e1e5c..9bee65f
--- a/daemon/Kernel/Platforms/Generic/CMcKMod.cpp
+++ b/MobiCoreDriverLib/Kernel/Platforms/Generic/CMcKMod.cpp
@@ -2,34 +2,37 @@
  * @{
  * @file
  *
- * MobiCore Driver Kernel Module Interface.
+ * <t-base Driver Kernel Module Interface.
  */
 /*
- * <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
+ * Copyright (c) 2013 TRUSTONIC LIMITED
+ * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- *    products derived from this software without specific prior
- *    written permission.
  *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 3. Neither the name of the TRUSTONIC LIMITED nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 #include <cstdlib>
 
@@ -55,7 +58,7 @@
     uint32_t    len,
     uint32_t    *pHandle,
     addr_t      *pVirtAddr,
-    addr_t      *pPhysAddr)
+    uint64_t      *pPhysAddr)
 {
     int ret = 0;
     LOG_V(" mapWsm(): len=%d", len);
@@ -82,8 +85,8 @@
     }
 
 
-    LOG_V(" mapped to %p, handle=%d, phys=%p ", virtAddr,
-          mapParams.handle, (addr_t) (mapParams.phys_addr));
+    LOG_V(" mapped to %p, handle=%d, phys=0x%llX ", virtAddr,
+          mapParams.handle, mapParams.phys_addr);
 
     if (pVirtAddr != NULL) {
         *pVirtAddr = virtAddr;
@@ -94,7 +97,7 @@
     }
 
     if (pPhysAddr != NULL) {
-        *pPhysAddr = (addr_t) (mapParams.phys_addr);
+        *pPhysAddr = mapParams.phys_addr;
     }
 
     return 0;
@@ -105,7 +108,7 @@
     uint32_t    len,
     uint32_t    *pHandle,
     addr_t      *pVirtAddr,
-    addr_t      *pPhysAddr,
+    uint64_t      *pPhysAddr,
     bool        *pReuse)
 {
     LOG_I("Mapping MCI: len=%d", len);
@@ -132,8 +135,8 @@
     mapParams.addr = (unsigned long)virtAddr;
     *pReuse = mapParams.reused;
 
-    LOG_V(" MCI mapped to %p, handle=%d, phys=%p, reused=%s",
-          (void *)mapParams.addr, mapParams.handle, (addr_t) (mapParams.phys_addr),
+    LOG_V(" MCI mapped to %p, handle=%d, phys=0x%llx, reused=%s",
+          (void *)mapParams.addr, mapParams.handle, mapParams.phys_addr,
           mapParams.reused ? "true" : "false");
 
     if (pVirtAddr != NULL) {
@@ -145,7 +148,7 @@
     }
 
     if (pPhysAddr != NULL) {
-        *pPhysAddr = (addr_t) (mapParams.phys_addr);
+        *pPhysAddr = mapParams.phys_addr;
     }
 
     // clean memory
@@ -162,7 +165,7 @@
     addr_t      *pPhysAddr)
 {
     // Not currently supported by the driver
-    LOG_E("MobiCore Driver does't support persistent buffers");
+    LOG_E("<t-base Driver doesn't support persistent buffers");
     return MC_DRV_ERR_NOT_IMPLEMENTED;
 }
 
@@ -202,8 +205,7 @@
 
 
 //------------------------------------------------------------------------------
-int CMcKMod::fcInit(uint32_t nqOffset, uint32_t nqLength, uint32_t mcpOffset,
-                    uint32_t mcpLength)
+int CMcKMod::fcInit(uint32_t nqLength, uint32_t mcpOffset, uint32_t mcpLength)
 {
     int ret = 0;
 
@@ -213,8 +215,6 @@
 
     // Init MC with NQ and MCP buffer addresses
     struct mc_ioctl_init fcInitParams = {
-nq_offset :
-        nqOffset,
 nq_length :
         nqLength,
 mcp_offset :
@@ -332,7 +332,7 @@
     uint32_t    len,
     uint32_t    pid,
     uint32_t    *pHandle,
-    addr_t      *pPhysWsmL2)
+    uint64_t      *pPhysWsmL2)
 {
     LOG_I(" Registering virtual buffer at %p, len=%d as World Shared Memory", buffer, len);
 
@@ -356,14 +356,14 @@
         return MAKE_MC_DRV_KMOD_WITH_ERRNO(errno);
     }
 
-    LOG_I(" Registered, handle=%d, L2 phys=0x%x ", params.handle, params.table_phys);
+    LOG_I(" Registered, handle=%d, L2 phys=0x%llx ", params.handle, params.table_phys);
 
     if (pHandle != NULL) {
         *pHandle = params.handle;
     }
 
     if (pPhysWsmL2 != NULL) {
-        *pPhysWsmL2 = (addr_t) params.table_phys;
+        *pPhysWsmL2 = params.table_phys;
     }
 
     return MC_DRV_OK;
@@ -433,10 +433,10 @@
 
 
 //------------------------------------------------------------------------------
-addr_t CMcKMod::findWsmL2(uint32_t handle, int fd)
+uint64_t CMcKMod::findWsmL2(uint32_t handle, int fd)
 {
     int ret = 0;
-    
+
     struct mc_ioctl_resolv_wsm wsm;
 
     wsm.handle = handle;
@@ -447,7 +447,7 @@
 
     if (!isOpen()) {
         LOG_E("no connection to kmod");
-        return NULL;
+        return 0;
     }
 
     ret = ioctl(fdKMod, MC_IO_RESOLVE_WSM, &wsm);
@@ -457,11 +457,11 @@
         return 0;
     }
 
-    return (addr_t)wsm.phys;
+    return wsm.phys;
 }
 
 //------------------------------------------------------------------------------
-mcResult_t CMcKMod::findContiguousWsm(uint32_t handle, int fd, addr_t *phys, uint32_t *len)
+mcResult_t CMcKMod::findContiguousWsm(uint32_t handle, int fd, uint64_t *phys, uint32_t *len)
 {
     mcResult_t ret = MC_DRV_OK;
     struct mc_ioctl_resolv_cont_wsm wsm;
@@ -480,9 +480,9 @@
 
     ret = ioctl(fdKMod, MC_IO_RESOLVE_CONT_WSM, &wsm);
     if (ret != 0) {
-        LOG_ERRNO("ioctl MC_IO_RESOLVE_CONT_WSM");
+        LOG_W("ioctl MC_IO_RESOLVE_CONT_WSM failed with \"%s\"(errno %i)", strerror(errno), errno);
     } else {
-        *phys = (addr_t)wsm.phys;
+        *phys = wsm.phys;
         *len = wsm.length;
     }
 
@@ -524,37 +524,13 @@
 
     ret = ioctl(fdKMod, MC_IO_LOG_SETUP, 0);
     if (ret != 0) {
-        LOG_ERRNO("ioctl MC_IO_LOG_SETUP");
-        LOG_E("ret = %d", ret);
+        LOG_W("ioctl MC_IO_LOG_SETUP failed with \"%s\"(errno %i)", strerror(errno), errno);
     }
 
     return ret;
 }
 
 //------------------------------------------------------------------------------
-int CMcKMod::fcExecute(addr_t startAddr, uint32_t areaLength)
-{
-    int ret = 0;
-    struct mc_ioctl_execute params = {
-phys_start_addr :
-        (uint32_t)startAddr,
-length :
-        areaLength
-    };
-
-    if (!isOpen()) {
-        LOG_E("no connection to kmod");
-        return MC_DRV_ERR_KMOD_NOT_OPEN;
-    }
-
-    ret = ioctl(fdKMod, MC_IO_EXECUTE, &params);
-    if (ret != 0) {
-        LOG_ERRNO("ioctl MC_IO_EXECUTE");
-    }
-
-    return ret;
-}
-//------------------------------------------------------------------------------
 bool CMcKMod::checkVersion(void)
 {
     uint32_t version;
diff --git a/daemon/Kernel/Platforms/Generic/CMcKMod.h b/MobiCoreDriverLib/Kernel/Platforms/Generic/CMcKMod.h
old mode 100644
new mode 100755
similarity index 63%
rename from daemon/Kernel/Platforms/Generic/CMcKMod.h
rename to MobiCoreDriverLib/Kernel/Platforms/Generic/CMcKMod.h
index c69e1e2..a326468
--- a/daemon/Kernel/Platforms/Generic/CMcKMod.h
+++ b/MobiCoreDriverLib/Kernel/Platforms/Generic/CMcKMod.h
@@ -2,33 +2,37 @@
  * @{
  * @file
  *
- * MobiCore Driver Kernel Module Interface.
+ * <t-base Driver Kernel Module Interface.
  *
- * <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
+ *
+ * Copyright (c) 2013 TRUSTONIC LIMITED
+ * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- *    products derived from this software without specific prior
- *    written permission.
  *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 3. Neither the name of the TRUSTONIC LIMITED nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 #ifndef CMCKMOD_H_
 #define CMCKMOD_H_
@@ -60,7 +64,7 @@
     mcResult_t mapWsm(uint32_t  len,
                       uint32_t    *pHandle,
                       addr_t      *pVirtAddr,
-                      addr_t      *pPhysAddr);
+                      uint64_t      *pPhysAddr);
     /**
     * Map data.
     *
@@ -78,7 +82,7 @@
         uint32_t    len,
         uint32_t    *pHandle,
         addr_t      *pVirtAddr,
-        addr_t      *pPhysAddr,
+        uint64_t    *pPhysAddr,
         bool        *pReuse);
 
     /**
@@ -94,8 +98,7 @@
 
     bool waitSSIQ(uint32_t *pCnt);
 
-    int fcInit(uint32_t nqOffset,
-               uint32_t    nqLength,
+    int fcInit(uint32_t    nqLength,
                uint32_t    mcpOffset,
                uint32_t    mcpLength);
 
@@ -115,7 +118,7 @@
         uint32_t    len,
         uint32_t    pid,
         uint32_t    *pHandle,
-        addr_t      *pPhysWsmL2);
+        uint64_t      *pPhysWsmL2);
 
     mcResult_t unregisterWsmL2(uint32_t handle);
 
@@ -125,17 +128,12 @@
 
     mcResult_t cleanupWsmL2(void);
 
-    addr_t findWsmL2(uint32_t handle, int fd);
+    uint64_t findWsmL2(uint32_t handle, int fd);
 
-    mcResult_t findContiguousWsm(uint32_t handle, int fd, addr_t *phys, uint32_t *len);
+    mcResult_t findContiguousWsm(uint32_t handle, int fd, uint64_t *phys, uint32_t *len);
 
     mcResult_t setupLog(void);
 
-    /**
-    * Tell stub to start MobiCore from given physical address
-    */
-    int fcExecute(addr_t startAddr, uint32_t areaLength);
-
     bool checkVersion(void);
 };
 
diff --git a/daemon/Registry/Android.mk b/MobiCoreDriverLib/Registry/Android.mk
similarity index 100%
rename from daemon/Registry/Android.mk
rename to MobiCoreDriverLib/Registry/Android.mk
diff --git a/daemon/Registry/PrivateRegistry.cpp b/MobiCoreDriverLib/Registry/PrivateRegistry.cpp
similarity index 63%
rename from daemon/Registry/PrivateRegistry.cpp
rename to MobiCoreDriverLib/Registry/PrivateRegistry.cpp
index b8a306c..0b2293a 100755
--- a/daemon/Registry/PrivateRegistry.cpp
+++ b/MobiCoreDriverLib/Registry/PrivateRegistry.cpp
@@ -6,31 +6,35 @@
  * @ingroup MCD_MCDIMPL_DAEMON_REG
  */
 
-/* <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
+/*
+ * Copyright (c) 2013 TRUSTONIC LIMITED
+ * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- *    products derived from this software without specific prior
- *    written permission.
  *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 3. Neither the name of the TRUSTONIC LIMITED nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 #include <stdlib.h>
@@ -45,6 +49,7 @@
 #include <sys/mman.h>
 #include <errno.h>
 #include <fcntl.h>
+#include <libgen.h>
 
 #include "mcLoadFormat.h"
 #include "mcSpid.h"
@@ -53,6 +58,8 @@
 #include "PrivateRegistry.h"
 #include "MobiCoreRegistry.h"
 
+#include "uuid_attestation.h"
+
 #include "log.h"
 
 /** Maximum size of a trustlet in bytes. */
@@ -73,6 +80,8 @@
 #define TL_CONT_FILE_EXT ".tlcont"
 #define DATA_CONT_FILE_EXT ".datacont"
 #define TL_BIN_FILE_EXT ".tlbin"
+#define GP_TA_BIN_FILE_EXT ".tabin"
+#define GP_TA_SPID_FILE_EXT ".spid"
 
 using namespace std;
 
@@ -90,8 +99,8 @@
 //------------------------------------------------------------------------------
 static string uint32ToString(uint32_t value)
 {
-    char hx[4 * 2 + 1];
-    sprintf(hx, "%08X", value);
+    char hx[8 + 1];
+    snprintf(hx, sizeof(hx), "%08X", value);
     string str(hx);
     return string(str.rbegin(), str.rend());
 }
@@ -113,26 +122,31 @@
 
     // use the default registry path.
     registryPath = MC_REGISTRY_CONTAINER_PATH;
-    LOG_I(" Using default registry path %s", registryPath.c_str());
+    LOG_I("  Using default registry path %s", registryPath.c_str());
 
     assert(registryPath.length() != 0);
 
     return registryPath;
 }
 
+string getTbStoragePath()
+{
+    return getRegistryPath()+"/TbStorage";
+}
+
 //------------------------------------------------------------------------------
-static string getTlRegistryPath()
+string getTlRegistryPath()
 {
     string registryPath;
 
     // First, attempt to use regular registry environment variable.
     if (doesDirExist(MC_REGISTRY_DEFAULT_PATH)) {
         registryPath = MC_REGISTRY_DEFAULT_PATH;
-        LOG_I("getTlRegistryPath(): Using MC_REGISTRY_PATH %s", registryPath.c_str());
+        LOG_I(" Using MC_REGISTRY_PATH %s", registryPath.c_str());
     } else if (doesDirExist(MC_REGISTRY_FALLBACK_PATH)) {
         // Second, attempt to use fallback registry environment variable.
         registryPath = MC_REGISTRY_FALLBACK_PATH;
-        LOG_I("getTlRegistryPath(): Using MC_REGISTRY_FALLBACK_PATH %s", registryPath.c_str());
+        LOG_I(" Using MC_REGISTRY_FALLBACK_PATH %s", registryPath.c_str());
     }
 
     // As a last resort, use the default registry path.
@@ -187,7 +201,7 @@
 static string getTlContFilePath(const mcUuid_t *uuid, const mcSpid_t spid)
 {
     return getRegistryPath() + "/" + byteArrayToString(uuid, sizeof(*uuid))
-                + "." + uint32ToString(spid) + TL_CONT_FILE_EXT;
+           + "." + uint32ToString(spid) + TL_CONT_FILE_EXT;
 }
 
 //------------------------------------------------------------------------------
@@ -209,6 +223,18 @@
 }
 
 //------------------------------------------------------------------------------
+static string getTABinFilePath(const mcUuid_t *uuid)
+{
+    return getTlRegistryPath() + "/" + byteArrayToString(uuid, sizeof(*uuid)) + GP_TA_BIN_FILE_EXT;
+}
+
+//------------------------------------------------------------------------------
+static string getTASpidFilePath(const mcUuid_t *uuid)
+{
+    return getTlRegistryPath() + "/" + byteArrayToString(uuid, sizeof(*uuid)) + GP_TA_SPID_FILE_EXT;
+}
+
+//------------------------------------------------------------------------------
 mcResult_t mcRegistryStoreAuthToken(void *so, uint32_t size)
 {
     if (so == NULL || size > 3 * MAX_SO_CONT_SIZE) {
@@ -244,18 +270,24 @@
 
     FILE *fs = fopen(authTokenFilePath.c_str(), "rb");
     if (!fs) {
-        LOG_E("mcRegistry read So.Soc failed: %d", MC_DRV_ERR_INVALID_DEVICE_FILE);
+        LOG_W("mcRegistry read So.Soc failed: %d", MC_DRV_ERR_INVALID_DEVICE_FILE);
         return MC_DRV_ERR_INVALID_DEVICE_FILE;
     }
     fseek(fs, 0, SEEK_END);
     int32_t filesize = ftell(fs);
     if (sizeof(mcSoAuthTokenCont_t) != filesize) {
         fclose(fs);
-        LOG_E("mcRegistry read So.Soc failed: %d", MC_DRV_ERR_OUT_OF_RESOURCES);
+        LOG_W("mcRegistry read So.Soc failed: %d", MC_DRV_ERR_OUT_OF_RESOURCES);
         return MC_DRV_ERR_OUT_OF_RESOURCES;
     }
     fseek(fs, 0, SEEK_SET);
-    fread((char *)so, 1, sizeof(mcSoAuthTokenCont_t), fs);
+    if (fread((char *)so, 1, sizeof(mcSoAuthTokenCont_t), fs) !=
+                sizeof(mcSoAuthTokenCont_t))
+    {
+        fclose(fs);
+        LOG_W("mcRegistry read So.Soc failed: %d", MC_DRV_ERR_INVALID_PARAMETER);
+        return MC_DRV_ERR_INVALID_PARAMETER;
+    }
     fclose(fs);
 
     return MC_DRV_OK;
@@ -264,11 +296,10 @@
 //------------------------------------------------------------------------------
 mcResult_t mcRegistryDeleteAuthToken(void)
 {
-    if(remove(getAuthTokenFilePath().c_str())) {
+    if (remove(getAuthTokenFilePath().c_str())) {
         LOG_ERRNO("Delete Auth token file!");
         return MC_DRV_ERR_UNKNOWN;
-    }
-    else
+    } else
         return MC_DRV_OK;
 }
 
@@ -303,16 +334,16 @@
 {
     const string &rootContFilePath = getRootContFilePath();
     size_t readBytes;
-    
+
     if (so == NULL) {
         LOG_E("mcRegistry read So.Root failed: %d", MC_DRV_ERR_INVALID_PARAMETER);
         return MC_DRV_ERR_INVALID_PARAMETER;
     }
-    LOG_I("read Root: %s", rootContFilePath.c_str());
+    LOG_I(" Opening %s", rootContFilePath.c_str());
 
     FILE *fs = fopen(rootContFilePath.c_str(), "rb");
     if (!fs) {
-        LOG_E("mcRegistry read So.Root failed: %d", MC_DRV_ERR_INVALID_DEVICE_FILE);
+        LOG_W("mcRegistry read So.Root failed: %d", MC_DRV_ERR_INVALID_DEVICE_FILE);
         return MC_DRV_ERR_INVALID_DEVICE_FILE;
     }
     readBytes = fread((char *)so, 1, *size, fs);
@@ -359,10 +390,10 @@
     const string &spContFilePath = getSpContFilePath(spid);
     size_t readBytes;
     if ((spid == 0) || (so == NULL)) {
-        LOG_E("mcRegistry read So.Sp(SpId) failed: %d", MC_DRV_ERR_INVALID_PARAMETER);
+        LOG_E("mcRegistry read So.Sp(SpId=0x%x) failed", spid);
         return MC_DRV_ERR_INVALID_PARAMETER;
     }
-    LOG_I("read SP: %s", spContFilePath.c_str());
+    LOG_I(" Reading %s", spContFilePath.c_str());
 
     FILE *fs = fopen(spContFilePath.c_str(), "rb");
     if (!fs) {
@@ -406,6 +437,123 @@
     return MC_DRV_OK;
 }
 
+static uint32_t getAsUint32BE(
+    void *pValueUnaligned
+)
+{
+    uint8_t *p = (uint8_t *)pValueUnaligned;
+    uint32_t val = p[3] | (p[2] << 8) | (p[1] << 16) | (p[0] << 24);
+    return val;
+}
+
+mcResult_t mcRegistryStoreTABlob(mcSpid_t spid, void *blob, uint32_t size)
+{
+
+    LOG_I("mcRegistryStoreTABlob started");
+
+    // Check blob size
+    if (size < sizeof(mclfHeaderV24_t)) {
+        LOG_E("RegistryStoreTABlob failed - TA blob length is less then header size");
+        return MC_DRV_ERR_INVALID_PARAMETER;
+    }
+
+    mclfHeaderV24_t *header24 = (mclfHeaderV24_t *)blob;
+    mclfHeaderV2_t *header20 = (mclfHeaderV2_t *)blob;
+
+    // Check header version
+    if (header20->intro.version < MC_MAKE_VERSION(2, 4)) {
+        LOG_E("RegistryStoreTABlob failed - TA blob header version is less than 2.4");
+        return MC_DRV_ERR_TA_HEADER_ERROR;
+    }
+
+    //Check GP version
+    if (header24->gp_level != 1) {
+        LOG_E("RegistryStoreTABlob failed - TA blob header gp_level is not equal to 1");
+        return MC_DRV_ERR_TA_HEADER_ERROR;
+    }
+
+    TEEC_UUID uuid;
+    switch (header20->serviceType) {
+    case SERVICE_TYPE_SYSTEM_TRUSTLET: {
+        // Check spid
+        if (spid != MC_SPID_SYSTEM) {
+            LOG_E("RegistryStoreTABlob failed - SPID is not equal to %d for System TA", spid);
+            return MC_DRV_ERR_INVALID_PARAMETER;
+        }
+        memcpy(&uuid, &header20->uuid, sizeof(mcUuid_t));
+        break;
+    }
+    case SERVICE_TYPE_SP_TRUSTLET: {
+        // Check spid
+        if (spid >= MC_SPID_SYSTEM) {
+            LOG_E("RegistryStoreTABlob failed - SPID is equal to %u ", spid);
+            return MC_DRV_ERR_INVALID_PARAMETER;
+        }
+
+        uuid_attestation *pUa = (uuid_attestation *) & ((uint8_t *)blob)[header24->attestationOffset];
+        // Check attestation size
+        if ((header24->attestationOffset > size) && (header24->attestationOffset + getAsUint32BE(&pUa->size) > size)) {
+            LOG_E("RegistryStoreTABlob failed - Attestation size is not correct");
+            return MC_DRV_ERR_TA_HEADER_ERROR;
+        }
+
+        // Check attestation size
+        if (getAsUint32BE(&pUa->size) < sizeof(uuid_attestation)) {
+            LOG_E("RegistryStoreTABlob failed - Attestation size is equal to %d and is less then %d", getAsUint32BE(&pUa->size), sizeof(uuid_attestation));
+            return MC_DRV_ERR_TA_ATTESTATION_ERROR;
+        }
+
+        // Check magic word
+        if (memcmp(pUa->magic, MAGIC, AT_MAGIC_SIZE)) {
+            LOG_E("RegistryStoreTABlob failed - Attestation magic word is not correct");
+            return MC_DRV_ERR_TA_ATTESTATION_ERROR;
+        }
+
+        // Check version
+        if (getAsUint32BE(&pUa->version) != AT_VERSION) {
+            LOG_E("RegistryStoreTABlob failed - Attestation version is equal to %08X. It has to be equal to %08X", getAsUint32BE(&pUa->version), AT_VERSION);
+            return MC_DRV_ERR_TA_ATTESTATION_ERROR;
+        }
+
+        memcpy(&uuid, &pUa->uuid, sizeof(mcUuid_t));
+        break;
+    }
+    default: {
+        return MC_DRV_ERR_INVALID_PARAMETER;
+    }
+    }
+    const string tlBinFilePath = getTABinFilePath((mcUuid_t *)&uuid);
+
+    LOG_I("Store TA blob at: %s", tlBinFilePath.c_str());
+
+    FILE *fs = fopen(tlBinFilePath.c_str(), "wb");
+    if (!fs) {
+        LOG_E("RegistryStoreTABlob failed - TA blob file open error: %d", MC_DRV_ERR_INVALID_DEVICE_FILE);
+        return MC_DRV_ERR_INVALID_DEVICE_FILE;
+    }
+    fseek(fs, 0, SEEK_SET);
+    fwrite(blob, 1, size, fs);
+    fflush(fs);
+    fclose(fs);
+
+    if (header20->serviceType == SERVICE_TYPE_SP_TRUSTLET) {
+        const string taspidFilePath = getTASpidFilePath((mcUuid_t *)&uuid);
+
+        LOG_I("Store spid file at: %s", taspidFilePath.c_str());
+
+        FILE *fs = fopen(taspidFilePath.c_str(), "wb");
+        if (!fs) {
+            //TODO: shouldn't we delete TA blob file ?
+            LOG_E("RegistryStoreTABlob failed - TA blob file open error: %d", MC_DRV_ERR_INVALID_DEVICE_FILE);
+            return MC_DRV_ERR_INVALID_DEVICE_FILE;
+        }
+        fseek(fs, 0, SEEK_SET);
+        fwrite(&spid, 1, sizeof(mcSpid_t), fs);
+        fflush(fs);
+        fclose(fs);
+    }
+    return MC_DRV_OK;
+}
 
 //------------------------------------------------------------------------------
 mcResult_t mcRegistryReadTrustletCon(const mcUuid_t *uuid, const mcSpid_t spid, void *so, uint32_t *size)
@@ -427,7 +575,7 @@
     readBytes = fread((char *)so, 1, *size, fs);
     fclose(fs);
 
-    if(readBytes > 0) {
+    if (readBytes > 0) {
         *size = readBytes;
         return MC_DRV_OK;
     } else {
@@ -461,7 +609,11 @@
         LOG_E("mcRegistry store So.Data(cid/pid) failed: %d", MC_DRV_ERR_INVALID_PARAMETER);
         return MC_DRV_ERR_INVALID_PARAMETER;
     }
-    mkdir(pathname.c_str(), 0777);
+    if (mkdir(pathname.c_str(), 0777) < 0)
+    {
+        LOG_E("mcRegistry store So.Data(cid/pid) failed: %d", MC_DRV_ERR_INVALID_PARAMETER);
+        return MC_DRV_ERR_INVALID_PARAMETER;
+    }
 
     LOG_I("store DT: %s", filename.c_str());
 
@@ -481,8 +633,9 @@
 
 //------------------------------------------------------------------------------
 mcResult_t mcRegistryReadData(uint32_t context, const mcCid_t *cid, mcPid_t pid,
-    mcSoDataCont_t *so, uint32_t maxLen)
+                              mcSoDataCont_t *so, uint32_t maxLen)
 {
+
     if ((NULL == cid) || (NULL == so)) {
         LOG_E("mcRegistry read So.Data failed: %d", MC_DRV_ERR_INVALID_PARAMETER);
         return MC_DRV_ERR_INVALID_PARAMETER;
@@ -516,9 +669,23 @@
     }
     fseek(fs, 0, SEEK_SET);
     char *p = (char *) so;
-    fread(p, 1, sizeof(mcSoHeader_t), fs);
+    if (fread(p, 1, sizeof(mcSoHeader_t), fs) != sizeof(mcSoHeader_t))
+    {
+        fclose(fs);
+        LOG_E("mcRegistry read So.Data(cid/pid) failed: %d", MC_DRV_ERR_INVALID_PARAMETER);
+        return MC_DRV_ERR_INVALID_PARAMETER;
+    }
     p += sizeof(mcSoHeader_t);
-    fread(p, 1, MC_SO_SIZE(so->soHeader.plainLen, so->soHeader.encryptedLen) - sizeof(mcSoHeader_t), fs);
+    if (fread(p, 1, MC_SO_SIZE(so->soHeader.plainLen,
+                so->soHeader.encryptedLen)
+                - sizeof(mcSoHeader_t), fs) !=
+                MC_SO_SIZE(so->soHeader.plainLen, so->soHeader.encryptedLen)
+                - sizeof(mcSoHeader_t))
+    {
+        fclose(fs);
+        LOG_E("mcRegistry read So.Data(cid/pid) failed: %d", MC_DRV_ERR_INVALID_PARAMETER);
+        return MC_DRV_ERR_INVALID_PARAMETER;
+    }
     fclose(fs);
 
     return MC_DRV_OK;
@@ -526,6 +693,201 @@
 
 
 //------------------------------------------------------------------------------
+static size_t getFileContent(
+    const char *pPath,
+    uint8_t **ppContent)
+{
+    FILE   *pStream;
+    long    filesize;
+    uint8_t *content = NULL;
+
+    /* Open the file */
+    pStream = fopen(pPath, "rb");
+    if (pStream == NULL) {
+        LOG_E("Error: Cannot open file: %s.", pPath);
+        return 0;
+    }
+
+    if (fseek(pStream, 0L, SEEK_END) != 0) {
+        LOG_E("Error: Cannot read file: %s.", pPath);
+        goto error;
+    }
+
+    filesize = ftell(pStream);
+    if (filesize < 0) {
+        LOG_E("Error: Cannot get the file size: %s.", pPath);
+        goto error;
+    }
+
+    if (filesize == 0) {
+        LOG_E("Error: Empty file: %s.", pPath);
+        goto error;
+    }
+
+    /* Set the file pointer at the beginning of the file */
+    if (fseek(pStream, 0L, SEEK_SET) != 0) {
+        LOG_E("Error: Cannot read file: %s.", pPath);
+        goto error;
+    }
+
+    /* Allocate a buffer for the content */
+    content = (uint8_t *)malloc(filesize);
+    if (content == NULL) {
+        LOG_E("Error: Cannot read file: Out of memory.");
+        goto error;
+    }
+
+    /* Read data from the file into the buffer */
+    if (fread(content, (size_t)filesize, 1, pStream) != 1) {
+        LOG_E("Error: Cannot read file: %s.", pPath);
+        goto error;
+    }
+
+    /* Close the file */
+    fclose(pStream);
+    *ppContent = content;
+
+    /* Return number of bytes read */
+    return (size_t)filesize;
+
+error:
+    if (content  != NULL) {
+        free(content);
+    }
+    fclose(pStream);
+    return 0;
+}
+
+//------------------------------------------------------------------------------
+static bool mcCheckUuid(const mcUuid_t *uuid, const char *filename)
+{
+    uint8_t    *pTAData = NULL;
+    uint32_t    nTASize;
+    bool        res;
+
+    nTASize = getFileContent(filename, &pTAData);
+    if (nTASize == 0) {
+        LOG_E("err: Trusted Application not found.");
+        return false;
+    }
+
+    // Check blob size
+    if (nTASize < sizeof(mclfHeaderV24_t)) {
+        free(pTAData);
+        LOG_E("RegistryStoreTABlob failed - TA blob length is less then header size");
+        return false;
+    }
+
+    mclfHeaderV2_t *header20 = (mclfHeaderV2_t *)pTAData;
+
+    // Check header version
+    if (header20->intro.version < MC_MAKE_VERSION(2, 4)) {
+        free(pTAData);
+        LOG_E("RegistryStoreTABlob failed - TA blob header version is less than 2.4");
+        return false;
+    }
+
+    // Check blob size
+    if (memcmp(uuid, &header20->uuid, sizeof(mcUuid_t)) == 0) {
+        res = true;
+    } else {
+        res = false;
+    }
+
+    free(pTAData);
+
+    return res;
+}
+
+//this function deletes all the files owned by a GP TA and stored in the tbase secure storage dir.
+//then it deletes GP TA folder.
+static int CleanupGPTAStorage(const char *basename)
+{
+	DIR            *dp;
+	struct dirent  *de;
+	int             e;
+	string TAPath = getTlRegistryPath()+"/TbStorage/"+ basename;
+
+	if (NULL != (dp = opendir(TAPath.c_str()))) {
+		while (NULL != (de = readdir(dp))) {
+			if (de->d_name[0] != '.') {
+				string dname = TAPath + "/" + string (de->d_name);
+				LOG_I("delete DT: %s", dname.c_str());
+				if (0 != (e = remove(dname.c_str()))) {
+					LOG_E("remove UUID-files %s failed! error: %d", dname.c_str(), e);
+				}
+			}
+		}
+		if (dp) {
+			closedir(dp);
+		}
+		LOG_I("delete dir: %s", TAPath.c_str());
+		if (0 != (e = rmdir(TAPath.c_str()))) {
+			LOG_E("remove UUID-dir failed! errno: %d", e);
+			return e;
+		}
+	}
+	return MC_DRV_OK;
+}
+
+static void deleteSPTA(const mcUuid_t *uuid, const mcSpid_t spid, bool checkUuid)
+{
+    DIR            *dp;
+    struct dirent  *de;
+    int             e;
+
+    // Delete TABIN and SPID files - we loop searching required spid file
+    string pathname = getRegistryPath();
+    if (NULL != (dp = opendir(pathname.c_str()))) {
+        while (NULL != (de = readdir(dp))) {
+            string spidFile;
+            string tabinFile;
+            string tabinUuid;
+            size_t pch_dot, pch_slash;
+            spidFile = pathname + '/' + string(de->d_name);
+            pch_dot = spidFile.find_last_of('.');
+            if (pch_dot == string::npos) continue;
+            pch_slash = spidFile.find_last_of('/');
+            if ((pch_slash != string::npos) && (pch_slash > pch_dot))  continue;
+            if (spidFile.substr(pch_dot).compare(GP_TA_SPID_FILE_EXT) != 0) continue;
+
+            mcSpid_t curSpid = 0;
+
+            int fd = open(spidFile.c_str(), O_RDONLY);
+            if (fd != -1) {
+                if (read(fd, &curSpid, sizeof(mcSpid_t))!=sizeof(mcSpid_t)) {
+                    curSpid = 0;
+                }
+                close(fd);
+            }
+            if (spid == curSpid) {
+                tabinFile =  spidFile.substr(0, pch_dot) + GP_TA_BIN_FILE_EXT;
+                if ((!checkUuid)||(mcCheckUuid(uuid, tabinFile.c_str()))) {
+                	tabinUuid = spidFile.substr(0, pch_dot);
+                	if (0 != (e = CleanupGPTAStorage(tabinUuid.c_str()))){
+                		LOG_E("cleanup TA Storage dir failed! errno: %d", e);
+                		//return MC_DRV_ERR_UNKNOWN;
+                	}
+                    if (0 != (e = remove(tabinFile.c_str()))) {
+                        LOG_E("remove TA file failed! errno: %d", e);
+                        //return MC_DRV_ERR_UNKNOWN;
+                    }
+                    if (0 != (e = remove(spidFile.c_str()))) {
+                        LOG_E("remove SPID file failed! errno: %d", e);
+                        //return MC_DRV_ERR_UNKNOWN;
+                    }
+                    if (checkUuid) break;
+                }
+            }
+        }
+        if (dp) {
+            closedir(dp);
+        }
+
+    }
+}
+
+//------------------------------------------------------------------------------
 mcResult_t mcRegistryCleanupTrustlet(const mcUuid_t *uuid, const mcSpid_t spid)
 {
     DIR            *dp;
@@ -536,6 +898,8 @@
         LOG_E("mcRegistry cleanupTrustlet(uuid) failed: %d", MC_DRV_ERR_INVALID_PARAMETER);
         return MC_DRV_ERR_INVALID_PARAMETER;
     }
+
+    // Delete all TA related data
     string pathname = getTlDataPath(uuid);
     if (NULL != (dp = opendir(pathname.c_str()))) {
         while (NULL != (de = readdir(dp))) {
@@ -556,12 +920,18 @@
             return MC_DRV_ERR_UNKNOWN;
         }
     }
+
+    // Delete TA binary with the name uuid.tlbin
     string tlBinFilePath = getTlBinFilePath(uuid);
     LOG_I("delete Tlb: %s", tlBinFilePath.c_str());
     if (0 != (e = remove(tlBinFilePath.c_str()))) {
         LOG_E("remove Tlb failed! errno: %d", e);
 //        return MC_DRV_ERR_UNKNOWN;     // a trustlet-binary must not be present ! (registered but not usable)
     }
+
+    // Delete TABIN and SPID files - we loop searching required spid file
+    deleteSPTA(uuid,spid,true);
+
     string tlContFilePath = getTlContFilePath(uuid, spid);
     LOG_I("delete Tlc: %s", tlContFilePath.c_str());
     if (0 != (e = remove(tlContFilePath.c_str()))) {
@@ -601,6 +971,10 @@
         LOG_E("delete SP->UUID failed! Return code: %d", ret);
         return ret;
     }
+
+    // Delete remaining TABIN and SPID files
+    deleteSPTA(NULL,spid,false);
+
     string pathname = getSpDataPath(spid);
 
     if (NULL != (dp = opendir(pathname.c_str()))) {
@@ -701,7 +1075,7 @@
     }
 #endif
 
-    LOG_I("Trustlet text %u data %u ", pHeader->text.len, pHeader->data.len);
+    LOG_I(" Trustlet text %u data %u ", pHeader->text.len, pHeader->data.len);
 
     // If loadable driver or system trustlet.
     if (pHeader->serviceType == SERVICE_TYPE_DRIVER  || pHeader->serviceType == SERVICE_TYPE_SYSTEM_TRUSTLET) {
@@ -714,8 +1088,7 @@
         regobj->tlStartOffset = 0;
         memcpy((char *)regobj->value, trustlet, tlSize);
         // If user trustlet.
-    }
-    else if (pHeader->serviceType == SERVICE_TYPE_SP_TRUSTLET) {
+    } else if (pHeader->serviceType == SERVICE_TYPE_SP_TRUSTLET) {
         // Take trustlet blob and append root, sp, and tl container.
         size_t regObjValueSize = tlSize + sizeof(mcBlobLenInfo_t) + 3 * MAX_SO_CONT_SIZE;
 
@@ -750,7 +1123,7 @@
         do {
             uint32_t soTltContSize = MAX_SO_CONT_SIZE;
             uint32_t len;
-            
+
             // Fill in root container.
             len = sizeof(mcSoRootCont_t);
             if (MC_DRV_OK != (ret = mcRegistryReadRoot(p, &len))) {
@@ -766,25 +1139,23 @@
             }
             lenInfo->spContBlobSize = len;
             p += len;
-            
+
             // Fill in TLT Container
             // We know exactly how much space is left in the buffer
             soTltContSize = regObjValueSize - tlSize + sizeof(mcBlobLenInfo_t)
-                - lenInfo->spContBlobSize - lenInfo->rootContBlobSize;
+                            - lenInfo->spContBlobSize - lenInfo->rootContBlobSize;
             if (MC_DRV_OK != (ret = mcRegistryReadTrustletCon(&pHeader->uuid, spid, p, &soTltContSize))) {
                 break;
             }
             lenInfo->tlContBlobSize = soTltContSize;
-            LOG_I("Trustlet container %u bytes loaded", soTltContSize);
+            LOG_I(" Trustlet container %u bytes loaded", soTltContSize);
             // Depending on the trustlet container size we decide which structure to use
             // Unfortunate design but it should have to do for now
             if (soTltContSize == sizeof(mcSoTltCont_2_0_t)) {
-                LOG_I("Using 2.0 trustlet container");
-            }
-            else if (soTltContSize == sizeof(mcSoTltCont_2_1_t)) {
-                LOG_I("Using 2.1 trustlet container");
-            }
-            else {
+                LOG_I(" Using 2.0 trustlet container");
+            } else if (soTltContSize == sizeof(mcSoTltCont_2_1_t)) {
+                LOG_I(" Using 2.1 trustlet container");
+            } else {
                 LOG_E("Trustlet container has unknown size");
                 break;
             }
@@ -797,9 +1168,9 @@
         }
         // Now we know the sizes for all containers so set the correct size
         regobj->len = sizeof(mcBlobLenInfo_t) + tlSize +
-                        lenInfo->rootContBlobSize +
-                        lenInfo->spContBlobSize +
-                        lenInfo->tlContBlobSize;
+                      lenInfo->rootContBlobSize +
+                      lenInfo->spContBlobSize +
+                      lenInfo->tlContBlobSize;
         // Any other service type.
     } else {
         LOG_E("mcRegistryMemGetServiceBlob() failed: Unsupported service type %u", pHeader->serviceType);
@@ -809,7 +1180,7 @@
 
 
 //------------------------------------------------------------------------------
-regObject_t *mcRegistryFileGetServiceBlob(const char* trustlet)
+regObject_t *mcRegistryFileGetServiceBlob(const char *trustlet, mcSpid_t spid)
 {
     struct stat sb;
     regObject_t *regobj = NULL;
@@ -827,7 +1198,7 @@
         return NULL;
     }
 
-    if (fstat(fd, &sb) == -1){
+    if (fstat(fd, &sb) == -1) {
         LOG_E("mcRegistryFileGetServiceBlob() failed: Cound't get file size");
         goto error;
     }
@@ -838,7 +1209,7 @@
         goto error;
     }
 
-    regobj = mcRegistryMemGetServiceBlob(0, buffer, sb.st_size);
+    regobj = mcRegistryMemGetServiceBlob(spid, buffer, sb.st_size);
 
     // We don't actually care if either of them fails but should still print warnings
     if (munmap(buffer, sb.st_size)) {
@@ -855,7 +1226,7 @@
 
 
 //------------------------------------------------------------------------------
-regObject_t *mcRegistryGetServiceBlob(const mcUuid_t *uuid)
+regObject_t *mcRegistryGetServiceBlob(const mcUuid_t *uuid, bool isGpUuid)
 {
     // Ensure that a UUID is provided.
     if (NULL == uuid) {
@@ -864,17 +1235,39 @@
     }
 
     // Open service blob file.
-    string tlBinFilePath = getTlBinFilePath(uuid);
+    string tlBinFilePath;
+    if (isGpUuid) {
+        tlBinFilePath = getTABinFilePath(uuid);
+    } else {
+        tlBinFilePath = getTlBinFilePath(uuid);
+    }
     LOG_I("Loading %s", tlBinFilePath.c_str());
 
-    return mcRegistryFileGetServiceBlob(tlBinFilePath.c_str());
-}
+    mcSpid_t spid = 0;
+    if (isGpUuid) {
+        string taspidFilePath = getTASpidFilePath(uuid);
+        int fd = open(taspidFilePath.c_str(), O_RDONLY);
+        if (fd == -1) {
+            // This can be ok for System TAs
+            //LOG_ERRNO("open");
+            //LOG_E("Cannot open %s", taspidFilePath.c_str());
+            //return NULL;
+        } else {
+            if (read(fd, &spid, sizeof(mcSpid_t))!=sizeof(mcSpid_t)) {
+                close(fd);
+                return NULL;
+            }
+            close(fd);
+        }
+    }
 
+    return mcRegistryFileGetServiceBlob(tlBinFilePath.c_str(), spid);
+}
 
 //------------------------------------------------------------------------------
 regObject_t *mcRegistryGetDriverBlob(const char *filename)
 {
-    regObject_t *regobj = mcRegistryFileGetServiceBlob(filename);
+    regObject_t *regobj = mcRegistryFileGetServiceBlob(filename, 0);
 
     if (regobj == NULL) {
         LOG_E("mcRegistryGetDriverBlob() failed");
diff --git a/daemon/Registry/PrivateRegistry.h b/MobiCoreDriverLib/Registry/PrivateRegistry.h
similarity index 75%
rename from daemon/Registry/PrivateRegistry.h
rename to MobiCoreDriverLib/Registry/PrivateRegistry.h
index 59236cf..9404939 100755
--- a/daemon/Registry/PrivateRegistry.h
+++ b/MobiCoreDriverLib/Registry/PrivateRegistry.h
@@ -7,31 +7,35 @@
  * Mobicore Driver Registry.
  */
 
-/* <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
+/*
+ * Copyright (c) 2013 TRUSTONIC LIMITED
+ * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- *    products derived from this software without specific prior
- *    written permission.
  *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 3. Neither the name of the TRUSTONIC LIMITED nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 #ifndef MOBICORE_REGISTRY_H_
 #define MOBICORE_REGISTRY_H_
@@ -84,7 +88,7 @@
      * @param[out] size Root container secure object size
      * @return MC_DRV_OK if successful, otherwise error code.
      */
-     mcResult_t mcRegistryReadRoot(void *so, uint32_t *size);
+    mcResult_t mcRegistryReadRoot(void *so, uint32_t *size);
 
     /** Stores a service provider container secure object in the registry.
      * @param spid Service provider ID.
@@ -100,7 +104,7 @@
      * @param[out] size Service provider container secure object size
      * @return MC_DRV_OK if successful, otherwise error code.
      */
-     mcResult_t mcRegistryReadSp(mcSpid_t spid, void *so, uint32_t *size);
+    mcResult_t mcRegistryReadSp(mcSpid_t spid, void *so, uint32_t *size);
 
     /** Deletes a service provider recursively, including all trustlets and
      * data.
@@ -177,7 +181,15 @@
      * @note It is the responsibility of the caller to free the registry object
      * allocated by this function.
      */
-    regObject_t *mcRegistryGetServiceBlob(const mcUuid_t  *uuid);
+    regObject_t *mcRegistryGetServiceBlob(const mcUuid_t  *uuid, bool isGpUuid);
+
+    /** Returns a registry object for a given service.
+     * @param uuid service GP UUID as mc uuid
+     * @return Registry object.
+     * @note It is the responsibility of the caller to free the registry object
+     * allocated by this function.
+     */
+    regObject_t *mcRegistryGetServiceBlobGP(const mcUuid_t  *uuid);
 
     /** Returns a registry object for a given service.
      * @param driverFilename driver filename
@@ -187,6 +199,14 @@
      */
     regObject_t *mcRegistryGetDriverBlob(const char *filename);
 
+    /** Stores a Trustlet Application blob in the registry.
+     * @param spid SPID of the trustlet container.
+     * @param blob Trustlet Application blob.
+     * @param size Trustlet Application blob size.
+     * @return MC_DRV_OK if successful, otherwise error code.
+     */
+    mcResult_t mcRegistryStoreTABlob(mcSpid_t spid, void *blob, uint32_t size);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/daemon/Registry/Public/MobiCoreRegistry.h b/MobiCoreDriverLib/Registry/Public/MobiCoreRegistry.h
old mode 100644
new mode 100755
similarity index 70%
rename from daemon/Registry/Public/MobiCoreRegistry.h
rename to MobiCoreDriverLib/Registry/Public/MobiCoreRegistry.h
index e231702..c629b14
--- a/daemon/Registry/Public/MobiCoreRegistry.h
+++ b/MobiCoreDriverLib/Registry/Public/MobiCoreRegistry.h
@@ -6,32 +6,36 @@
  * @file
  * Mobicore Driver Registry.
  */
- 
-/* <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
+
+/*
+ * Copyright (c) 2013 TRUSTONIC LIMITED
+ * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- *    products derived from this software without specific prior
- *    written permission.
  *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 3. Neither the name of the TRUSTONIC LIMITED nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 #ifndef MOBICORE_REGISTRY_H_
 #define MOBICORE_REGISTRY_H_
@@ -74,7 +78,7 @@
      * @param[out] size Root container secure object size
      * @return MC_DRV_OK if successful, otherwise error code.
      */
-     mcResult_t mcRegistryReadRoot(void *so, uint32_t *size);
+    mcResult_t mcRegistryReadRoot(void *so, uint32_t *size);
 
     /** Stores a service provider container secure object in the registry.
      * @param spid Service provider ID.
@@ -89,7 +93,7 @@
      * @param[out] size Service provider container secure object size
      * @return MC_DRV_OK if successful, otherwise error code.
      */
-     mcResult_t mcRegistryReadSp(mcSpid_t spid, void *so, uint32_t *size);
+    mcResult_t mcRegistryReadSp(mcSpid_t spid, void *so, uint32_t *size);
 
     /** Deletes a service provider recursively, including all trustlets and
      * data.
@@ -100,8 +104,9 @@
 
     /** Stores a trustlet container secure object in the registry.
      * @param uuid Trustlet UUID.
+     * @param spid SPID of the trustlet container.
      * @param so Trustlet container secure object.
-     * @param size Trustlet container secure object size
+     * @param size Trustlet container secure object size.
      * @return MC_DRV_OK if successful, otherwise error code.
      */
     mcResult_t mcRegistryStoreTrustletCon(const mcUuid_t *uuid, const mcSpid_t spid, void *so, uint32_t size);
@@ -128,6 +133,14 @@
      */
     mcResult_t mcRegistryCleanupRoot(void);
 
+    /** Stores a Trustlet Application blob in the registry.
+     * @param spid SPID of the trustlet container.
+     * @param blob Trustlet Application blob.
+     * @param size Trustlet Application blob size.
+     * @return MC_DRV_OK if successful, otherwise error code.
+     */
+    mcResult_t mcRegistryStoreTABlob(mcSpid_t spid, void *blob, uint32_t size);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/daemon/Registry/Registry.cpp b/MobiCoreDriverLib/Registry/Registry.cpp
similarity index 68%
rename from daemon/Registry/Registry.cpp
rename to MobiCoreDriverLib/Registry/Registry.cpp
index a520f4e..a900529 100755
--- a/daemon/Registry/Registry.cpp
+++ b/MobiCoreDriverLib/Registry/Registry.cpp
@@ -6,31 +6,35 @@
  * @ingroup MCD_MCDIMPL_DAEMON_REG
  */
 
-/* <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
+/*
+ * Copyright (c) 2013 TRUSTONIC LIMITED
+ * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- *    products derived from this software without specific prior
- *    written permission.
  *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 3. Neither the name of the TRUSTONIC LIMITED nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 #include <stdlib.h>
@@ -60,7 +64,9 @@
 static mcResult_t writeBlobData(void *buff, uint32_t len)
 {
     Connection con;
-    mcDrvResponseHeader_t rsp = { responseId : MC_DRV_ERR_INVALID_PARAMETER };
+mcDrvResponseHeader_t rsp = { responseId :
+                                  MC_DRV_ERR_INVALID_PARAMETER
+                                };
     if (!con.connect(SOCK_PATH)) {
         LOG_E("Failed to connect to daemon!");
         return MC_DRV_ERR_DAEMON_SOCKET;
@@ -83,12 +89,14 @@
 {
     Connection con;
     int32_t size;
-    mcDrvResponseHeader_t rsp = { responseId : MC_DRV_ERR_INVALID_PARAMETER };
+mcDrvResponseHeader_t rsp = { responseId :
+                                  MC_DRV_ERR_INVALID_PARAMETER
+                                };
     if (*rlen == 0) {
         LOG_E("Invalid buffer length!");
         return MC_DRV_ERR_DAEMON_SOCKET;
     }
-    
+
     if (!con.connect(SOCK_PATH)) {
         LOG_E("Failed to connect to daemon!");
         return MC_DRV_ERR_DAEMON_SOCKET;
@@ -107,7 +115,7 @@
 
     //Then read the actual data
     size = con.readData(rbuff, *rlen, DAEMON_TIMEOUT);
-    if(size <= 0) {
+    if (size <= 0) {
         LOG_E("Failed to get answer from daemon!");
         return MC_DRV_ERR_DAEMON_SOCKET;
     }
@@ -127,7 +135,11 @@
     } storeCmd;
 
     mcResult_t ret;
-    storeCmd *cmd = (storeCmd*)malloc(sizeof(storeCmd) + size - 1);
+    storeCmd *cmd = (storeCmd *)malloc(sizeof(storeCmd) + size - 1);
+    if (cmd == NULL) {
+        LOG_E("Allocation failure");
+        return MC_DRV_ERR_NO_FREE_MEMORY;
+    }
 
     cmd->commandId = MC_DRV_REG_STORE_AUTH_TOKEN;
     cmd->soSize = size;
@@ -141,7 +153,9 @@
 //------------------------------------------------------------------------------
 mcResult_t mcRegistryReadAuthToken(void *so, uint32_t *size)
 {
-    mcDrvCommandHeader_t cmd = { commandId : MC_DRV_REG_READ_AUTH_TOKEN };
+mcDrvCommandHeader_t cmd = { commandId :
+                                 MC_DRV_REG_READ_AUTH_TOKEN
+                               };
     uint32_t rsize;
     mcResult_t ret;
     // we expect to max read what the user has allocated
@@ -155,7 +169,9 @@
 //------------------------------------------------------------------------------
 mcResult_t mcRegistryDeleteAuthToken(void)
 {
-    mcDrvCommandHeader_t cmd = { commandId : MC_DRV_REG_DELETE_AUTH_TOKEN };
+mcDrvCommandHeader_t cmd = { commandId :
+                                 MC_DRV_REG_DELETE_AUTH_TOKEN
+                               };
     return writeBlobData(&cmd, sizeof(cmd));
 }
 
@@ -169,7 +185,11 @@
         uint8_t so;
     } storeCmd;
     mcResult_t ret;
-    storeCmd *cmd = (storeCmd*)malloc(sizeof(storeCmd) + size - 1);
+    storeCmd *cmd = (storeCmd *)malloc(sizeof(storeCmd) + size - 1);
+    if (cmd == NULL) {
+        LOG_E("Allocation failure");
+        return MC_DRV_ERR_NO_FREE_MEMORY;
+    }
 
     cmd->commandId = MC_DRV_REG_WRITE_ROOT_CONT;
     cmd->soSize = size;
@@ -183,7 +203,9 @@
 //------------------------------------------------------------------------------
 mcResult_t mcRegistryReadRoot(void *so, uint32_t *size)
 {
-    mcDrvCommandHeader_t cmd = { commandId : MC_DRV_REG_READ_ROOT_CONT };
+mcDrvCommandHeader_t cmd = { commandId :
+                                 MC_DRV_REG_READ_ROOT_CONT
+                               };
     uint32_t rsize;
     mcResult_t ret;
 
@@ -196,7 +218,9 @@
 //------------------------------------------------------------------------------
 mcResult_t mcRegistryCleanupRoot(void)
 {
-    mcDrvCommandHeader_t cmd = { commandId : MC_DRV_REG_DELETE_ROOT_CONT };
+mcDrvCommandHeader_t cmd = { commandId :
+                                 MC_DRV_REG_DELETE_ROOT_CONT
+                               };
     return writeBlobData(&cmd, sizeof(cmd));
 }
 
@@ -209,9 +233,13 @@
         mcSpid_t spid;
         uint8_t so;
     } storeCmd;
-    
+
     mcResult_t ret;
-    storeCmd *cmd = (storeCmd*)malloc(sizeof(storeCmd) + size - 1);
+    storeCmd *cmd = (storeCmd *)malloc(sizeof(storeCmd) + size - 1);
+    if (cmd == NULL) {
+        LOG_E("Allocation failure");
+        return MC_DRV_ERR_NO_FREE_MEMORY;
+    }
 
     cmd->commandId = MC_DRV_REG_WRITE_SP_CONT;
     cmd->soSize = size;
@@ -220,7 +248,7 @@
 
     ret = writeBlobData(cmd, sizeof(storeCmd) + size - 1);
     free(cmd);
-    return ret; 
+    return ret;
 }
 
 
@@ -269,8 +297,12 @@
     } storeCmd;
 
     mcResult_t ret;
-    storeCmd *cmd = (storeCmd*)malloc(sizeof(storeCmd) + size - 1);
-    
+    storeCmd *cmd = (storeCmd *)malloc(sizeof(storeCmd) + size - 1);
+    if (cmd == NULL) {
+        LOG_E("Allocation failure");
+        return MC_DRV_ERR_NO_FREE_MEMORY;
+    }
+
     cmd->commandId = MC_DRV_REG_WRITE_TL_CONT;
     cmd->soSize = size;
     cmd->spid = spid;
@@ -282,6 +314,32 @@
     return ret;
 }
 
+//------------------------------------------------------------------------------
+mcResult_t mcRegistryStoreTABlob(mcSpid_t spid, void *blob, uint32_t size)
+{
+    typedef struct {
+        uint32_t commandId;
+        uint32_t blobSize;
+        mcSpid_t spid;
+        uint8_t blob[];
+    } storeCmd;
+
+    mcResult_t ret;
+    storeCmd *cmd = (storeCmd *)malloc(sizeof(storeCmd) + size);
+    if (cmd == NULL) {
+        LOG_E("Allocation failure");
+        return MC_DRV_ERR_NO_FREE_MEMORY;
+    }
+
+    cmd->commandId = MC_DRV_REG_STORE_TA_BLOB;
+    cmd->blobSize = size;
+    cmd->spid = spid;
+    memcpy(&cmd->blob, blob, size);
+
+    ret = writeBlobData(cmd, sizeof(storeCmd) + size);
+    free(cmd);
+    return ret;
+}
 
 //------------------------------------------------------------------------------
 mcResult_t mcRegistryReadTrustletCon(const mcUuid_t *uuid, mcSpid_t spid, void *so, uint32_t *size)
@@ -312,7 +370,7 @@
         mcSpid_t spid;
     } cmd;
 
-    if(uuid == NULL) {
+    if (uuid == NULL) {
         return MC_DRV_ERR_INVALID_PARAMETER;
     }
 
@@ -332,7 +390,7 @@
 
 //------------------------------------------------------------------------------
 mcResult_t mcRegistryReadData(uint32_t context, const mcCid_t *cid, mcPid_t pid,
-    mcSoDataCont_t *so, uint32_t maxLen)
+                              mcSoDataCont_t *so, uint32_t maxLen)
 {
     return MC_DRV_ERR_INVALID_PARAMETER;
 }
diff --git a/MobiCoreDriverLib/build.sh b/MobiCoreDriverLib/build.sh
new file mode 100755
index 0000000..55a1593
--- /dev/null
+++ b/MobiCoreDriverLib/build.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+
+source ../../../../setup.sh
+if [ $? -ne 0 ]; then
+	echo "Error: Could not source setup.sh!"
+	exit 1
+fi
+
+ROOT_PATH=$(dirname $(readlink -f $BASH_SOURCE))
+
+### 
+###   Android NDK path
+### 
+PLATFORM=Generic
+MODE=debug
+
+echo "Building <t-base Daemon..."
+   
+# run NDK build
+${NDK_BUILD} \
+	-B \
+	NDK_DEBUG=1 \
+	NDK_PROJECT_PATH=$ROOT_PATH \
+	NDK_APPLICATION_MK=$ROOT_PATH/Application.mk \
+	NDK_MODULE_PATH=. \
+	NDK_APP_OUT=$ROOT_PATH/Out/_build \
+	APP_BUILD_SCRIPT=$ROOT_PATH/Android.mk \
+	APP_OPTIM=$MODE
\ No newline at end of file
diff --git a/daemon/buildTag.h b/MobiCoreDriverLib/buildTag.h
old mode 100644
new mode 100755
similarity index 94%
rename from daemon/buildTag.h
rename to MobiCoreDriverLib/buildTag.h
index 3066eff..c494a37
--- a/daemon/buildTag.h
+++ b/MobiCoreDriverLib/buildTag.h
@@ -25,4 +25,4 @@
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-#define MOBICORE_COMPONENT_BUILD_TAG "*** t-base-202-MSM8974-Android-V002 ###"
+#define MOBICORE_COMPONENT_BUILD_TAG "*** t-base-300-QC-8974-Engineering-V001 ###"
diff --git a/README.android b/README.android
new file mode 100755
index 0000000..29edee1
--- /dev/null
+++ b/README.android
@@ -0,0 +1,64 @@
+MobiCore Daemon in Android
+---
+Command line
+--
+The MobiCore Daemon supports 4 command line options. It also displays them with the help option:
+
+# ./mcDriverDaemon -h
+usage: ./mcDriverDaemon [-mdsbh]
+Start MobiCore Daemon
+
+-h              show this help
+-b              fork to background
+-m IMAGE        load mobicore from IMAGE to DDR
+-s              disable daemon scheduler(default enabled)
+-r DRIVER       load dyamic driver
+
+-b Forks the daemon to background
+
+# ./mcDriverDaemon -b
+
+Makes the daemon run in background and returns immediate control to the shell. No need to use shell forking with &
+
+-m Loads a mobicore image to DDR
+
+# ./mcDriverDaemon -m /data/app/mobicore.img
+
+Loads the mobicore.img to DDR and starts executing it.
+
+-s Disables NQ IRQ scheduler
+
+# ./mcDriverDaemon -s
+
+-r Loads dynamic driver at startup. The full path of the driver binary must be given, eg. /data/app/driver.drbin
+
+# ./mcDriverDaemon -r /data/app/driver.drbin
+
+Custom registry locations
+--
+Registry fallback
+
+In case of a Device wipe in Android the /data/app/mcRegistry folder will be deleted with all it's contents. To overcome
+this the daemon supports a fallback location(eg /system/app/mcRegistry): it first tries to load the trustlet
+from /data/app/mcRegistry/[uuid].tlbin and if it fails then it tries to read the trustlet from /system/app/mcRegistry/[uuid].tlb
+
+Both paths are completely configurable for the Daemon using 2 environment variables:MC_REGISTRY_PATH and MC_REGISTRY_FALLBACK_PATH
+
+For example if you want to use /data/app/mcRegistry as the default path and /system/app/mcRegistry as the fallback path:
+
+$ export MC_REGISTRY_PATH=/data/app/mcRegistry
+$ export MC_REGISTRY_FALLBACK_PATH=/system/app/mcRegistry
+$ /data/app/mcDriverDaemon
+
+Custom authtoken path
+--
+
+The authtoken file is created at provisioning and is by default located in /data/app/mcRegistry/00000.authtoken
+
+Because a device wipe could delete this file and make MobiCore unusable a new environment variable has been added to change the
+default behaviour: MC_AUTH_TOKEN_PATH
+
+$ export MC_AUTH_TOKEN_PATH=/efs
+$ /data/app/mcDriverDaemon
+
+This would change the location of the authtoken file to /efs
diff --git a/common/LogWrapper/Android.mk b/common/LogWrapper/Android.mk
old mode 100644
new mode 100755
diff --git a/common/LogWrapper/log.h b/common/LogWrapper/log.h
old mode 100644
new mode 100755
index 313dcbb..c297845
--- a/common/LogWrapper/log.h
+++ b/common/LogWrapper/log.h
@@ -34,9 +34,17 @@
 #ifndef TLCWRAPPERANDROIDLOG_H_
 #define TLCWRAPPERANDROIDLOG_H_
 
+#ifndef WIN32
 #include <unistd.h>
+#define GETPID getpid
+#else
+#include <process.h>
+#define GETPID _getpid
+#endif
 #include <stdio.h>
+#ifndef WIN32
 #include <android/log.h>
+#endif
 
 /** LOG_I(fmt, args...)
  * Informative logging, only shown in debug version
@@ -88,21 +96,25 @@
     #define _LOG_x(_x_,...) \
                 do \
                 { \
-                    printf("%s/%s(%d): ",_x_,LOG_TAG,getpid()); \
+                    printf("%s/%s(%d): ",_x_,LOG_TAG,GETPID()); \
                     printf(__VA_ARGS__); \
                     printf(EOL); \
                 } while(1!=1)
 
 
 #ifdef NDEBUG // no logging in debug version
-    #define LOG_I(fmt, args...) DUMMY_FUNCTION()
-    #define LOG_W(fmt, args...) DUMMY_FUNCTION()
+    #define LOG_I(fmt, ...) DUMMY_FUNCTION()
+    #define LOG_W(fmt, ...) DUMMY_FUNCTION()
 #else
     #define LOG_I(...)  _LOG_x("I",__VA_ARGS__)
     #define LOG_W(...)  _LOG_x("W",__VA_ARGS__)
 #endif
     #define _LOG_E(...)  _LOG_x("E",__VA_ARGS__)
 
+    #define LOG_i(...) printf(__VA_ARGS__)
+	#define LOG_w(...) printf(__VA_ARGS__)
+	#define LOG_e(...) printf(__VA_ARGS__)
+
 #endif //defined(LOG_ANDROID)
 
 #if defined(LOG_VERBOSE)
@@ -118,7 +130,7 @@
             do \
             { \
                 _LOG_E("  *****************************"); \
-                _LOG_E("  *** ERROR: "__VA_ARGS__); \
+                _LOG_E("  *** ERROR: " __VA_ARGS__); \
                 _LOG_E("  *** Detected in %s/%u()", __FUNCTION__, __LINE__); \
                 _LOG_E("  *****************************"); \
             } while(1!=1)
@@ -128,7 +140,9 @@
 
 #define LOG_I_BUF   LOG_I_Buf
 
+#ifndef WIN32
 __attribute__ ((unused))
+#endif
 static void LOG_I_Buf(
 	const char *  szDescriptor,
 	const void *  blob,
diff --git a/common/MobiCore/inc/FwDrv/fastcall.h b/common/MobiCore/inc/FwDrv/fastcall.h
old mode 100644
new mode 100755
diff --git a/common/MobiCore/inc/McLib/GpTci.h b/common/MobiCore/inc/McLib/GpTci.h
new file mode 100755
index 0000000..d952dad
--- /dev/null
+++ b/common/MobiCore/inc/McLib/GpTci.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2013 TRUSTONIC LIMITED
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the TRUSTONIC LIMITED nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _GP_TCI_H_
+#define _GP_TCI_H_
+
+typedef struct {
+    uint32_t   a;
+    uint32_t   b;
+} TEE_Value;
+
+#if defined (TRUSTEDAPP)
+typedef struct {
+    void        *sVirtualAddr;         /**< The virtual address of the Bulk buffer regarding the address space of the Trustlet, already includes a possible offset! */
+    uint32_t    sVirtualLen;       /**< Length of the mapped Bulk buffer */
+} mcBulkMap_t;
+#endif
+
+typedef struct {
+    mcBulkMap_t mapInfo;
+    uint32_t    outputSize;
+} _TEEC_MemoryReferenceInternal;
+
+typedef union {
+    TEE_Value                      value;
+    _TEEC_MemoryReferenceInternal   memref;
+} _TEEC_ParameterInternal;
+
+typedef enum {
+    _TA_OPERATION_OPEN_SESSION =    1,
+    _TA_OPERATION_INVOKE_COMMAND =  2,
+    _TA_OPERATION_CLOSE_SESSION =   3,
+} _TEEC_TCI_type;
+
+typedef struct {
+    _TEEC_TCI_type          type;
+    uint32_t                commandId;
+    uint32_t                paramTypes;
+    _TEEC_ParameterInternal params[4];
+    bool                    isCancelled;
+} _TEEC_OperationInternal;
+
+typedef struct {
+    char header[8];// = "TCIGP000"`: version indicator (to support future format changes)
+    TEEC_UUID destination;
+    _TEEC_OperationInternal operation; //the data of the ongoing operation (if any)
+    uint32_t ready;     
+    // The following fields are set by the secure world (in a future version, they may also be set by the normal world communication layer):
+    uint32_t returnOrigin;
+    uint32_t returnStatus;
+} _TEEC_TCI;
+
+#define TEEC_MEMREF_WHOLE             0xC
+#define TEEC_MEMREF_PARTIAL_INPUT     0xD
+#define TEEC_MEMREF_PARTIAL_OUTPUT    0xE
+#define TEEC_MEMREF_PARTIAL_INOUT     0xF
+
+/**
+ * Termination codes
+ */
+#define TA_EXIT_CODE_PANIC  (300)
+#define TA_EXIT_CODE_TCI    (301)
+#define TA_EXIT_CODE_PARAMS (302)
+#define TA_EXIT_CODE_FINISHED       (303)
+#define TA_EXIT_CODE_SESSIONSTATE   (304)
+#define TA_EXIT_CODE_CREATEFAILED   (305)
+
+#endif // _GP_TCI_H_
diff --git a/common/MobiCore/inc/Mci/mci.h b/common/MobiCore/inc/Mci/mci.h
old mode 100644
new mode 100755
index 6bd6f10..b9011e5
--- a/common/MobiCore/inc/Mci/mci.h
+++ b/common/MobiCore/inc/Mci/mci.h
@@ -1,4 +1,31 @@
-/** @mainpage MobiCore Control Interface - MCI
+/*
+ * Copyright (c) 2013 TRUSTONIC LIMITED
+ * All rights reserved
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ *    products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
  *
  * <h2>Introduction</h2>
  * The MobiCore Control Interface (MCI) is the interface for integrating G&D MobiCore technology into the
@@ -56,32 +83,6 @@
  *
  * @defgroup MCP    MobiCore Control Protocol
  *
- *
- * <!-- Copyright Giesecke & Devrient GmbH 2009-2012 -->
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- *    products derived from this software without specific prior
- *    written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 #ifndef MCI_H_
 #define MCI_H_
diff --git a/common/MobiCore/inc/Mci/mcifc.h b/common/MobiCore/inc/Mci/mcifc.h
old mode 100644
new mode 100755
index 598fa40..12c34d6
--- a/common/MobiCore/inc/Mci/mcifc.h
+++ b/common/MobiCore/inc/Mci/mcifc.h
@@ -1,10 +1,6 @@
-/** @addtogroup FCI
- * @{
- * @file
- * FastCall declarations.
- *
- * Holds the functions for SIQ, YIELD and FastCall for switching to the secure world.
- * <!-- Copyright Giesecke & Devrient GmbH 2009-2012 -->
+/*
+ * Copyright (c) 2013 TRUSTONIC LIMITED
+ * All rights reserved
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -29,6 +25,16 @@
  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * @addtogroup FCI
+ * @{
+ * @file
+ * FastCall declarations.
+ *
+ * Holds the functions for SIQ, YIELD and FastCall for switching to the secure world.
+ *
+
  */
 #ifndef MCIFC_H_
 #define MCIFC_H_
@@ -61,7 +67,9 @@
 #define MC_FC_SW_RESET              ((uint32_t)(-26))  /**< SW Reset if DDR has leftover content */
 // --- MEM traces ---
 #define MC_FC_MEM_TRACE             ((uint32_t)(-31))  /**< Enable SWd tracing via memory */
-// --- write access to CP15 regs ---
+// --- system settings ---
+
+#define MC_FC_STAT_COUNTER          ((uint32_t)(-41))  /**< Require status counter */
 #define MC_FC_CP15_REG             ((uint32_t)(-101))  /**< general CP15/cache register update */
 // --- store value in sDDRRAM ---
 #define MC_FC_STORE_BINFO          ((uint32_t)(-201))  /**< write a 32bit value in secure DDRRAM in incremented art (max 2kB) */
@@ -69,9 +77,9 @@
 
 // Broadcom Specific Fastcalls
 #define MC_FC_BCM_VC_CORE_START    ((uint32_t)(-301)) /**<  Set the VC Core start address*/
-
 #define MC_FC_MAX_ID         ((uint32_t)(0xFFFF0000))  /**< Maximum allowed FastCall ID */
 
+#define MC_FC_SWAP_CPU              ((uint32_t)(0x84000005))  /**< Change new active Core */
 // r1 is requested status (0,1,2), on return r2 holds this status value
 
 /** @} */
diff --git a/common/MobiCore/inc/Mci/mcifcfunc.h b/common/MobiCore/inc/Mci/mcifcfunc.h
old mode 100644
new mode 100755
index 69fbbc1..895507e
--- a/common/MobiCore/inc/Mci/mcifcfunc.h
+++ b/common/MobiCore/inc/Mci/mcifcfunc.h
@@ -1,12 +1,6 @@
-/** @addtogroup FCI
- * @{
- * @file
- * Declaration of FastCall helper functions.
- *
- * @attention Helper functions are mostly RealView (ARM CC) specific.
- *
- * Holds the functions for SIQ, YIELD and FastCall for switching to the secure world.
- * <!-- Copyright Giesecke & Devrient GmbH 2009-2012 -->
+/*
+ * Copyright (c) 2013 TRUSTONIC LIMITED
+ * All rights reserved
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -31,6 +25,18 @@
  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * @addtogroup FCI
+ * @{
+ * @file
+ * Declaration of FastCall helper functions.
+ *
+ * @attention Helper functions are mostly RealView (ARM CC) specific.
+ *
+ * Holds the functions for SIQ, YIELD and FastCall for switching to the secure world.
+ * <!-- Copyright © Trustonic Limited 2013 -->
+ *
  */
 
 #ifndef MCIFCFUNC_H_
diff --git a/common/MobiCore/inc/Mci/mcimcp.h b/common/MobiCore/inc/Mci/mcimcp.h
old mode 100644
new mode 100755
index c590c5e..855d2d6
--- a/common/MobiCore/inc/Mci/mcimcp.h
+++ b/common/MobiCore/inc/Mci/mcimcp.h
@@ -1,15 +1,6 @@
-/** @addtogroup MCP
- * @{
- * The MCP defines commands and responses which are used to control the MobiCore system.
- * MCP information is exchanged in a world share memory buffer which has been established prior between NWd
- * and SWd using the FastCall interface. The buffer needs to be provided by the MobiCore driver and is utilized
- * to send MCP commands to the MobiCore as well as receiving responses from the MobiCore.
- * The command of the normal world will be overwritten with the response from the secure side.
- *
- * @file
- * MCP command interface definitions.
- *
- * <!-- Copyright Giesecke & Devrient GmbH 2009-2012 -->
+/*
+ * Copyright (c) 2013 TRUSTONIC LIMITED
+ * All rights reserved
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -34,14 +25,30 @@
  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * @addtogroup MCP
+ * @{
+ * The MCP defines commands and responses which are used to control the MobiCore system.
+ * MCP information is exchanged in a world share memory buffer which has been established prior between NWd
+ * and SWd using the FastCall interface. The buffer needs to be provided by the MobiCore driver and is utilized
+ * to send MCP commands to the MobiCore as well as receiving responses from the MobiCore.
+ * The command of the normal world will be overwritten with the response from the secure side.
+ *
+ * @file
+ * MCP command interface definitions.
+ *
  */
+ 
 #ifndef MCP_H_
 #define MCP_H_
 
+
 #include "mcUuid.h"
 #include "mcLoadFormat.h"
 #include "mcVersionInfo.h"
 
+
 /** MobiCore Return Code Defines.
  * List of the possible MobiCore return codes.
  */
@@ -74,6 +81,7 @@
     MC_MCP_RET_ERR_SP_TL_DECRYPTION_FAILED          = 25, /**< Decryption of service provider trustlet failed. */
     MC_MCP_RET_ERR_SP_TL_HASH_CHECK_FAILED          = 26, /**< Hash check of service provider trustlet failed. */
     MC_MCP_RET_ERR_LAUNCH_TASK_FAILED               = 27, /**< Activation/starting of task failed. */
+    MC_MCP_RET_ERR_CLOSE_TASK_FAILED                = 28, /**< Closing of task not yet possible, try again later. */
 
     // used for command verification
     MC_MCP_RET_ERR_UNKNOWN_COMMAND                  = 50, /**< The command is unknown. */
@@ -92,9 +100,11 @@
     MC_MCP_CMD_UNMAP                     = 0x00000005,   /**< Unmap a block of WSM from a session. */
     MC_MCP_CMD_SUSPEND                   = 0x00000006,   /**< Prepare MobiCore for suspend. */
     MC_MCP_CMD_RESUME                    = 0x00000007,   /**< Resume MobiCore from suspension. */
-    MC_MCP_CMD_DONATE_RAM                = 0x00000008,   /**< Donate RAM to MobiCore. */
+    // obsolete: MC_MCP_CMD_DONATE_RAM   = 0x00000008,
     MC_MCP_CMD_GET_MOBICORE_VERSION      = 0x00000009,   /**< Get MobiCore version information. */
     MC_MCP_CMD_CLOSE_MCP                 = 0x0000000A,   /**< Close MCP and unmap MCI. */
+    MC_MCP_CMD_LOAD_TOKEN                = 0x0000000B,   /**< Load token for device attestation */
+    MC_MCP_CMD_CHECK_LOAD_TA             = 0x0000000C,   /**< Check that TA can be loaded */
 } mcpCmdId_t;
 
 
@@ -113,13 +123,6 @@
 #define WSM_L2_UNCACHED     0x100   /**< Bitflag indicating that L2 table should be uncached */
 
 
-/** Types of RAM known to the MobiCore.
- */
-typedef enum {
-    RAM_INVALID     = 0,    /**< Invalid memory type */
-    RAM_GENERIC     = 1,    /**< Generic RAM of no special type. */
-}ramType_t;
-
 /** Command header.
  * It just contains the command ID. Only values specified in mcpCmdId_t are allowed as command IDs.
  * If the command ID is unspecified the MobiCore returns an empty response with the result set to MC_MCP_RET_ERR_UNKNOWN_COMMAND .
@@ -145,27 +148,6 @@
 /** @defgroup ASMCMD Administrative Commands
  * @{ */
 
-/** @defgroup MCPDONATERAM DONATE_RAM
- * Donate NWd RAM to MobiCore.
- * This is a debug feature that is not available in release version.
- *
- * @{ */
-
-/** Donate RAM Command */
-typedef struct {
-    commandHeader_t  cmdHeader; /**< Command header. */
-    ramType_t        ramType;            /**< Type of RAM used for memory pool */
-    uint32_t         adrBuffer;          /**< Physical address of the page range*/
-    uint32_t         numPages;          /**< Number of pages contained in the donation. */
-} mcpCmdDonateRam_t, *mcpCmdDonateRam_ptr;
-
-/** Donate RAM Command Response */
-typedef struct {
-    responseHeader_t  rspHeader; /**< Response header. */
-} mcpRspDonateRam_t, *mcpRspDonateRam_ptr;
-/** @} */// End MCPDONATERAM
-
-
 /** @defgroup MCPGETMOBICOREVERSION GET_MOBICORE_VERSION
  * Get MobiCore version info.
  *
@@ -246,12 +228,12 @@
 typedef struct {
     commandHeader_t   cmdHeader;        /**< Command header. */
     mcUuid_t            uuid;             /**< Byte array containing the service UUID. */
-    wsmType_t         wsmTypeTci;       /**< Type of WSM used for the TCI */
-    uint32_t          adrTciBuffer;     /**< Physical address of the TCI */
+    uint64_t          adrTciBuffer;     /**< Physical address of the TCI */
+    uint64_t          adrLoadData;      /**< Physical address of the data to load. */
     uint32_t          ofsTciBuffer;     /**< Offset to the data. */
     uint32_t          lenTciBuffer;     /**< Length of the TCI. */
+    wsmType_t         wsmTypeTci;       /**< Type of WSM used for the TCI */
     wsmType_t         wsmTypeLoadData;  /**< Type of the memory containing the data to load. */
-    uint32_t          adrLoadData;      /**< Physical address of the data to load. */
     uint32_t          ofsLoadData;      /**< Offset to the data. */
     uint32_t          lenLoadData;      /**< Length of the data to load. */
     mclfHeader_t      tlHeader;         /**< Service header. */
@@ -263,6 +245,23 @@
     uint32_t          sessionId; /**< Session ID used for further communication. */
 } mcpRspOpen_t, *mcpRspOpen_ptr;
 
+/** TA Load Check Command */
+typedef struct {
+    commandHeader_t   cmdHeader;        /**< Command header. */
+    mcUuid_t          uuid;             /**< Byte array containing the service UUID. */
+    uint64_t          adrLoadData;      /**< Physical address of the data to load. */
+    wsmType_t         wsmTypeLoadData;  /**< Type of the memory containing the data to load. */
+    uint32_t          ofsLoadData;      /**< Offset to the data. */
+    uint32_t          lenLoadData;      /**< Length of the data to load. */
+    mclfHeader_t      tlHeader;         /**< Service header. */
+} mcpCmdCheckLoad_t, *mcpCmdCheckLoad_ptr;
+
+/** TA Load Check Response */
+typedef struct {
+    responseHeader_t  rspHeader; /**< Response header. */
+} mcpRspCheckLoad_t, *mcpRspCheckLoad_ptr;
+
+
 /** @} */// End MCPOPEN
 
 
@@ -305,8 +304,8 @@
     commandHeader_t  cmdHeader;     /**< Command header. */
     uint32_t         sessionId;     /**< Session ID of a valid session */
     wsmType_t        wsmType;       /**< Type of WSM used of the memory*/
-    uint32_t         adrBuffer;     /**< Physical address of the memory */
     uint32_t         ofsBuffer;     /**< Offset to the payload. */
+    uint64_t         adrBuffer;     /**< Physical address of the memory */
     uint32_t         lenBuffer;     /**< Length of the buffer. */
 } mcpCmdMap_t, *mcpCmdMap_ptr;
 
@@ -348,6 +347,27 @@
 
 /** @} */// End SESSCMD
 
+/** @defgroup MCPLOADTOKEN
+ * Load a token from the normal world and share it with <t-base
+ * If something fails, the device attestation functionality will be disabled
+ * @{ */
+
+/** Load Token */
+typedef struct {
+    commandHeader_t   cmdHeader;        /**< Command header. */
+    wsmType_t         wsmTypeLoadData;  /**< Type of the memory containing the data to load. */
+    uint64_t          adrLoadData;      /**< Physical address of the data to load. */
+    uint64_t          ofsLoadData;      /**< Offset to the data to load. */
+    uint64_t          lenLoadData;      /**< Length of the data to load. */
+} mcpCmdLoadToken_t, *mcpCmdLoadToken_ptr;
+
+/** Load Token Command Response */
+typedef struct {
+    responseHeader_t  rspHeader; /**< Response header. */
+} mcpRspLoadToken_t, *mcpRspLoadToken_ptr;
+
+/** @} *///End MCPLOADTOKEN
+
 /** @} */// End CMD
 
 /** Structure of the MCP buffer. */
@@ -366,10 +386,13 @@
     mcpRspSuspend_t              rspSuspend;             /**< Response to SUSPEND command. */
     mcpCmdResume_t               cmdResume;              /**< Resume MobiCore. */
     mcpRspResume_t               rspResume;              /**< Response to RESUME command. */
-    mcpCmdDonateRam_t            cmdDonateRam;           /**< Donate RAM to MobiCore. */
-    mcpRspDonateRam_t            rspDonateRam;           /**< Response to DONATE_RAM command. */
     mcpCmdGetMobiCoreVersion_t   cmdGetMobiCoreVersion;  /**< Get MobiCore Version command. */
     mcpRspGetMobiCoreVersion_t   rspGetMobiCoreVersion;  /**< Response to GET_MOBICORE_VERSION command. */
+    mcpCmdLoadToken_t            cmdLoadToken;
+    mcpRspLoadToken_t            rspLoadToken;
+    mcpCmdCheckLoad_t            cmdCheckLoad;           /**< TA load check command. */
+    mcpRspCheckLoad_t            rspCheckLoad;           /**< Response to TA load check. */
+
 } mcpMessage_t, *mcpMessage_ptr;
 
 
diff --git a/common/MobiCore/inc/Mci/mcinq.h b/common/MobiCore/inc/Mci/mcinq.h
old mode 100644
new mode 100755
index ad2a763..a6f11ad
--- a/common/MobiCore/inc/Mci/mcinq.h
+++ b/common/MobiCore/inc/Mci/mcinq.h
@@ -1,20 +1,6 @@
-/** @addtogroup NQ
- * @{
- * Notifications inform the MobiCore runtime environment that information is pending in a WSM buffer.
- * The Trustlet Connector (TLC) and the corresponding trustlet also utilize this buffer to notify
- * each other about new data within the Trustlet Connector Interface (TCI).
- *
- * The buffer is set up as a queue, which means that more than one notification can be written to the buffer
- * before the switch to the other world is performed. Each side therefore facilitates an incoming and an
- * outgoing queue for communication with the other side.
- *
- * Notifications hold the session ID, which is used to reference the communication partner in the other world.
- * So if, e.g., the TLC in the normal world wants to notify his trustlet about new data in the TLC buffer
- *
- * @file
- * Notification queue declarations.
- *
- * <!-- Copyright Giesecke & Devrient GmbH 2009-2012 -->
+/*
+ * Copyright (c) 2013 TRUSTONIC LIMITED
+ * All rights reserved
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -39,7 +25,26 @@
  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * @addtogroup NQ
+ * @{
+ * Notifications inform the MobiCore runtime environment that information is pending in a WSM buffer.
+ * The Trustlet Connector (TLC) and the corresponding trustlet also utilize this buffer to notify
+ * each other about new data within the Trustlet Connector Interface (TCI).
+ *
+ * The buffer is set up as a queue, which means that more than one notification can be written to the buffer
+ * before the switch to the other world is performed. Each side therefore facilitates an incoming and an
+ * outgoing queue for communication with the other side.
+ *
+ * Notifications hold the session ID, which is used to reference the communication partner in the other world.
+ * So if, e.g., the TLC in the normal world wants to notify his trustlet about new data in the TLC buffer
+ *
+ * @file
+ * Notification queue declarations.
+ *
  */
+ 
 #ifndef NQ_H_
 #define NQ_H_
 
diff --git a/common/MobiCore/inc/Mci/version.h b/common/MobiCore/inc/Mci/version.h
old mode 100644
new mode 100755
index 0c59e49..5a0364b
--- a/common/MobiCore/inc/Mci/version.h
+++ b/common/MobiCore/inc/Mci/version.h
@@ -1,5 +1,6 @@
-/**
- * <!-- Copyright Giesecke & Devrient GmbH 2009-2012 -->
+/*
+ * Copyright (c) 2013 TRUSTONIC LIMITED
+ * All rights reserved
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -24,11 +25,13 @@
  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
  */
+ 
 #ifndef MCI_VERSION_H_
 #define MCI_VERSION_H_
 
 #define MCI_VERSION_MAJOR 0
-#define MCI_VERSION_MINOR 5
+#define MCI_VERSION_MINOR 6
 
 #endif /** MCI_VERSION_H_ */
diff --git a/common/MobiCore/inc/TlCm/cmp.h b/common/MobiCore/inc/TlCm/cmp.h
old mode 100644
new mode 100755
diff --git a/common/MobiCore/inc/TlCm/tlCmApi.h b/common/MobiCore/inc/TlCm/tlCmApi.h
old mode 100644
new mode 100755
diff --git a/common/MobiCore/inc/TlCm/tlCmError.h b/common/MobiCore/inc/TlCm/tlCmError.h
old mode 100644
new mode 100755
diff --git a/common/MobiCore/inc/TlCm/tlCmUuid.h b/common/MobiCore/inc/TlCm/tlCmUuid.h
old mode 100644
new mode 100755
diff --git a/common/MobiCore/inc/TlCm/version.h b/common/MobiCore/inc/TlCm/version.h
old mode 100644
new mode 100755
diff --git a/common/MobiCore/inc/mcContainer.h b/common/MobiCore/inc/mcContainer.h
old mode 100644
new mode 100755
index d3a2c66..91aadbb
--- a/common/MobiCore/inc/mcContainer.h
+++ b/common/MobiCore/inc/mcContainer.h
@@ -2,7 +2,6 @@
  * @ingroup  MC_DATA_TYPES
  * @{
  *
- *
  * Copyright (c) 2013 TRUSTONIC LIMITED
  * All rights reserved
  *
@@ -29,9 +28,9 @@
  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
  */
 
+
 #ifndef MC_CONTAINER_H_
 #define MC_CONTAINER_H_
 
diff --git a/common/MobiCore/inc/mcDriverId.h b/common/MobiCore/inc/mcDriverId.h
old mode 100644
new mode 100755
index 8643b5f..6c49098
--- a/common/MobiCore/inc/mcDriverId.h
+++ b/common/MobiCore/inc/mcDriverId.h
@@ -2,7 +2,6 @@
  * @file
  * Driver ID definition.
  *
- *
  * Copyright (c) 2013 TRUSTONIC LIMITED
  * All rights reserved
  *
@@ -29,7 +28,6 @@
  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
  */
 
 #ifndef RTMDRVID_H_
@@ -48,20 +46,22 @@
 typedef enum {
 	MC_DRV_NUMBER_INVALID = 0,
 	MC_DRV_NUMBER_CRYPTO  = 1,
-    MC_DRV_NUMBER_KEYPAD  = 2,
-    /** Last GD driver number reserved for pre-installed drivers. 
+    /** Last GD driver number reserved for pre-installed drivers.
      * GD driver numbers up to this constant may not be used for loadable drivers. */
     MC_DRV_NUMBER_LAST_PRE_INSTALLED = 100,
+    TB_DRV_NUMBER_TUI  = 0x101,
+    TB_DRV_NUMBER_TPLAY  = 0x600,
 } mcDrvNumber_t;
 
 /** MobiCore driver IDs for Trustlets. */
 typedef enum {
 	MC_DRV_ID_INVALID = MC_DRV_VENDOR_ID_GD | MC_DRV_NUMBER_INVALID,
 	MC_DRV_ID_CRYPTO  = MC_DRV_VENDOR_ID_GD | MC_DRV_NUMBER_CRYPTO,
-    MC_DRV_ID_KEYPAD  = MC_DRV_VENDOR_ID_GD | MC_DRV_NUMBER_KEYPAD,
-    /** Last GD driver ID reserved for pre-installed drivers. 
+    /** Last GD driver ID reserved for pre-installed drivers.
      * GD driver IDs up to this constant may not be used for loadable drivers. */
     MC_DRV_ID_LAST_PRE_INSTALLED = MC_DRV_VENDOR_ID_GD | MC_DRV_NUMBER_LAST_PRE_INSTALLED,
+    TB_DRV_ID_TUI  = MC_DRV_VENDOR_ID_GD | TB_DRV_NUMBER_TUI,
+    TB_DRV_ID_TPLAY  = MC_DRV_VENDOR_ID_GD | TB_DRV_NUMBER_TPLAY,
 } mcDriverId_t;
 
 #endif /* RTMDRVID_H_ */
diff --git a/common/MobiCore/inc/mcLoadFormat.h b/common/MobiCore/inc/mcLoadFormat.h
old mode 100644
new mode 100755
index b6c1c13..b88c1f6
--- a/common/MobiCore/inc/mcLoadFormat.h
+++ b/common/MobiCore/inc/mcLoadFormat.h
@@ -11,7 +11,6 @@
  *
  * Holds the definitions for the layout of MobiCore Trustlet Blob.
  *
- *
  * Copyright (c) 2013 TRUSTONIC LIMITED
  * All rights reserved
  *
@@ -38,9 +37,7 @@
  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
  */
-
 #ifndef MCLOADFORMAT_H_
 #define MCLOADFORMAT_H_
 
@@ -49,7 +46,7 @@
 #include "mcDriverId.h"
 
 #define MCLF_VERSION_MAJOR   2
-#define MCLF_VERSION_MINOR   3
+#define MCLF_VERSION_MINOR   4
 #define MCLF_VERSION_MINOR_CURRENT   3
 
 #define MC_SERVICE_HEADER_MAGIC_BE         ((uint32_t)('M'|('C'<<8)|('L'<<16)|('F'<<24))) /**< "MCLF" in big endian integer representation */
@@ -75,7 +72,8 @@
     SERVICE_TYPE_ILLEGAL    = 0,        /**< Service type is invalid. */
     SERVICE_TYPE_DRIVER     = 1,        /**< Service is a driver. */
     SERVICE_TYPE_SP_TRUSTLET   = 2,     /**< Service is a Trustlet. */
-    SERVICE_TYPE_SYSTEM_TRUSTLET = 3    /**< Service is a system Trustlet. */
+    SERVICE_TYPE_SYSTEM_TRUSTLET = 3,   /**< Service is a system Trustlet. */
+//    SERVICE_TYPE_SP_TA = 4,             /**< Service is a Trusted Application for t-base 300. */
 } serviceType_t;
 
 /**
@@ -161,6 +159,20 @@
 } mclfHeaderV23_t, *mclfHeaderV23_ptr;
 /** @} */
 
+
+/**
+ * Version 2.4 MCLF header.
+ */
+typedef struct {
+    mclfHeaderV23_t         mclfHeaderV2;
+    uint32_t                gp_level;           /**<Starting 2.4: 0 for legacy MobiCore trustlets and 1 for Potato TAs. */
+    uint32_t                attestationOffset;  /**<Starting 2.4: Offset of attestation data area. */
+ 
+} mclfHeaderV24_t, *mclfHeaderV24_ptr;
+/** @} */
+
+
+
 /**
  * Version 2 MCLF text segment header.
  * Required to be present in MobiCore 1.2 components at address (0x1080).
@@ -188,6 +200,7 @@
     uint32_t                drApiVers;      /**< DrApi version used when building trustlet.
                                                  Value set at compile time for drivers. 0 for trustlets.
                                                  Required always. */
+    addr_t                  ta_properties;  /**< address of _TA_Properties in the TA. */
 } mclfTextHeader_t, *mclfTextHeader_ptr;
 
 // Version 2 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/common/MobiCore/inc/mcRootid.h b/common/MobiCore/inc/mcRootid.h
old mode 100644
new mode 100755
index 4558414..0d3240d
--- a/common/MobiCore/inc/mcRootid.h
+++ b/common/MobiCore/inc/mcRootid.h
@@ -3,7 +3,6 @@
  *
  * Global definition of root ID.
  *
- *
  * Copyright (c) 2013 TRUSTONIC LIMITED
  * All rights reserved
  *
@@ -31,7 +30,6 @@
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- *
  * @ingroup  MC_DATA_TYPES
  * @{
  */
diff --git a/common/MobiCore/inc/mcSo.h b/common/MobiCore/inc/mcSo.h
old mode 100644
new mode 100755
index 2f28ddf..8ff2d5a
--- a/common/MobiCore/inc/mcSo.h
+++ b/common/MobiCore/inc/mcSo.h
@@ -3,7 +3,6 @@
  *
  * @addtogroup MC_SO mcSo - Secure objects definitions.
  *
- *
  * Copyright (c) 2013 TRUSTONIC LIMITED
  * All rights reserved
  *
@@ -31,7 +30,6 @@
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- *
  * @ingroup  MC_DATA_TYPES
  * @{
  *
diff --git a/common/MobiCore/inc/mcSpid.h b/common/MobiCore/inc/mcSpid.h
old mode 100644
new mode 100755
index 3287275..c55d10a
--- a/common/MobiCore/inc/mcSpid.h
+++ b/common/MobiCore/inc/mcSpid.h
@@ -1,7 +1,6 @@
 /**
  * @addtogroup MC_SPID mcSpid - service provider ID.
  *
-*
  * Copyright (c) 2013 TRUSTONIC LIMITED
  * All rights reserved
  *
@@ -29,7 +28,6 @@
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- *
  * @ingroup  MC_DATA_TYPES
  * @{
  */
@@ -51,6 +49,7 @@
 
 /** SPID reserved for tests only */
 static const mcSpid_t MC_SPID_RESERVED_TEST = 0xFFFFFFFD;
+static const mcSpid_t MC_SPID_TRUSTONIC_TEST = 0x4;
 
 #endif // MC_SPID_H_
 
diff --git a/common/MobiCore/inc/mcSuid.h b/common/MobiCore/inc/mcSuid.h
old mode 100644
new mode 100755
index f2bc030..fe78a57
--- a/common/MobiCore/inc/mcSuid.h
+++ b/common/MobiCore/inc/mcSuid.h
@@ -1,7 +1,6 @@
 /**
  * @addtogroup MC_SUID mcSuid - SoC unique ID.
  *
- *
  * Copyright (c) 2013 TRUSTONIC LIMITED
  * All rights reserved
  *
@@ -29,7 +28,6 @@
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- *
  * @ingroup  MC_DATA_TYPES
  * @{
  */
diff --git a/common/MobiCore/inc/mcUuid.h b/common/MobiCore/inc/mcUuid.h
old mode 100644
new mode 100755
index 16705a0..eee18be
--- a/common/MobiCore/inc/mcUuid.h
+++ b/common/MobiCore/inc/mcUuid.h
@@ -1,7 +1,6 @@
 /**
  * @addtogroup MC_UUID mcUuid - Universally Unique Identifier.
  *
- *
  * Copyright (c) 2013 TRUSTONIC LIMITED
  * All rights reserved
  *
@@ -29,7 +28,6 @@
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- *
  * @ingroup  MC_DATA_TYPES
  * @{
  */
@@ -39,9 +37,10 @@
 
 #define UUID_TYPE
 
+#define UUID_LENGTH 16
 /** Universally Unique Identifier (UUID) according to ISO/IEC 11578. */
 typedef struct {
-    uint8_t value[16]; /**< Value of the UUID. */
+    uint8_t value[UUID_LENGTH]; /**< Value of the UUID. */
 } mcUuid_t, *mcUuid_ptr;
 
 /** UUID value used as free marker in service provider containers. */
diff --git a/common/MobiCore/inc/mcVersionHelper.h b/common/MobiCore/inc/mcVersionHelper.h
old mode 100644
new mode 100755
index 0a8bba3..dbaba1c
--- a/common/MobiCore/inc/mcVersionHelper.h
+++ b/common/MobiCore/inc/mcVersionHelper.h
@@ -2,7 +2,6 @@
  * @{
  * MobiCore Version Helper Macros
  *
- *
  * Copyright (c) 2013 TRUSTONIC LIMITED
  * All rights reserved
  *
@@ -29,7 +28,6 @@
  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
  */
 #include <stdio.h>
 
diff --git a/common/MobiCore/inc/mcVersionInfo.h b/common/MobiCore/inc/mcVersionInfo.h
old mode 100644
new mode 100755
index b02284e..b290fbb
--- a/common/MobiCore/inc/mcVersionInfo.h
+++ b/common/MobiCore/inc/mcVersionInfo.h
@@ -2,7 +2,6 @@
  * @{
  * MobiCore Version Information
  *
- *
  * Copyright (c) 2013 TRUSTONIC LIMITED
  * All rights reserved
  *
@@ -29,7 +28,6 @@
  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
  */
 
 #ifndef MCVERSIONINFO_H_
diff --git a/daemon/Android.mk b/daemon/Android.mk
deleted file mode 100644
index b0a5ee5..0000000
--- a/daemon/Android.mk
+++ /dev/null
@@ -1,109 +0,0 @@
-# =============================================================================
-#
-# MobiCore Android build components
-#
-# =============================================================================
-
-LOCAL_PATH := $(call my-dir)
-
-# Client Library
-# =============================================================================
-include $(CLEAR_VARS)
-LOCAL_MODULE := libMcClient
-LOCAL_MODULE_TAGS := optional
-LOCAL_C_INCLUDES += $(GLOBAL_INCLUDES)
-LOCAL_SHARED_LIBRARIES += $(GLOBAL_LIBRARIES)
-
-LOCAL_CFLAGS := -fvisibility=hidden -fvisibility-inlines-hidden
-LOCAL_CFLAGS += -include buildTag.h
-LOCAL_CFLAGS += -DLOG_TAG=\"McClient\"
-
-# Add new source files here
-LOCAL_SRC_FILES += \
-	ClientLib/Device.cpp \
-	ClientLib/ClientLib.cpp \
-	ClientLib/Session.cpp \
-	Common/CMutex.cpp \
-	Common/Connection.cpp
-
-LOCAL_C_INCLUDES += $(LOCAL_PATH)/Common
-
-LOCAL_EXPORT_C_INCLUDE_DIRS +=\
-	$(COMP_PATH_MobiCore)/inc \
-	$(LOCAL_PATH)/ClientLib/public
-
-
-include $(LOCAL_PATH)/Kernel/Android.mk
-# Import logwrapper
-include $(LOG_WRAPPER)/Android.mk
-
-include $(BUILD_SHARED_LIBRARY)
-
-# Daemon Application
-# =============================================================================
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := mcDriverDaemon
-LOCAL_MODULE_TAGS := optional
-LOCAL_CFLAGS += -include buildTag.h
-LOCAL_CFLAGS += -DLOG_TAG=\"McDaemon\"
-LOCAL_C_INCLUDES += $(GLOBAL_INCLUDES)
-LOCAL_SHARED_LIBRARIES += $(GLOBAL_LIBRARIES)
-
-include $(LOCAL_PATH)/Daemon/Android.mk
-
-# Common Source files required for building the daemon
-LOCAL_SRC_FILES += Common/CMutex.cpp \
-	Common/Connection.cpp \
-	Common/NetlinkConnection.cpp \
-	Common/CSemaphore.cpp \
-	Common/CThread.cpp
-
-# Includes required for the Daemon
-LOCAL_C_INCLUDES += $(LOCAL_PATH)/ClientLib/public \
-	$(LOCAL_PATH)/Common
-
-
-# Private Registry components
-LOCAL_C_INCLUDES += $(LOCAL_PATH)/Registry/Public \
-	$(LOCAL_PATH)/Registry
-LOCAL_SRC_FILES  += Registry/PrivateRegistry.cpp
-
-# Common components
-include $(LOCAL_PATH)/Kernel/Android.mk
-# Logwrapper
-include $(LOG_WRAPPER)/Android.mk
-
-include $(BUILD_EXECUTABLE)
-
-# Registry Shared Library
-# =============================================================================
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libMcRegistry
-LOCAL_MODULE_TAGS := optional
-LOCAL_CFLAGS += -DLOG_TAG=\"McRegistry\"
-LOCAL_C_INCLUDES += $(GLOBAL_INCLUDES)
-LOCAL_SHARED_LIBRARIES += $(GLOBAL_LIBRARIES)
-
-LOCAL_C_INCLUDES += $(LOCAL_PATH)/Common \
-	$(LOCAL_PATH)/Daemon/public \
-	$(LOCAL_PATH)/ClientLib/public
-
-# Common Source files required for building the daemon
-LOCAL_SRC_FILES += Common/CMutex.cpp \
-	Common/Connection.cpp \
-	Common/CSemaphore.cpp \
-	Common/CThread.cpp
-
-include $(LOCAL_PATH)/Registry/Android.mk
-
-# Import logwrapper
-include $(LOG_WRAPPER)/Android.mk
-
-include $(BUILD_SHARED_LIBRARY)
-
-# =============================================================================
-ifneq ($(filter-out Generic,$(PLATFORM)),)
-  $(call import-module,$(COMP_PATH_QualcommQSEEComAPI))
-endif
diff --git a/daemon/Common/CMutex.cpp b/daemon/Common/CMutex.cpp
deleted file mode 100644
index 618ae99..0000000
--- a/daemon/Common/CMutex.cpp
+++ /dev/null
@@ -1,83 +0,0 @@
-/** @addtogroup MCD_MCDIMPL_DAEMON_SRV
- * @{
- * @file
- *
- * Mutex implementation (pthread wrapper).
- *
- * <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- *    products derived from this software without specific prior
- *    written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#include "CMutex.h"
-#include "log.h"
-
-
-//------------------------------------------------------------------------------
-CMutex::CMutex(
-    void
-)
-{
-    pthread_mutex_init(&m_mutex, NULL);
-    pthread_cond_init(&m_cond, NULL);
-}
-
-
-//------------------------------------------------------------------------------
-CMutex::~CMutex(
-    void
-)
-{
-    pthread_mutex_destroy(&m_mutex);
-    pthread_cond_destroy(&m_cond);
-}
-
-
-//------------------------------------------------------------------------------
-int32_t CMutex::lock(
-    void
-)
-{
-    return pthread_mutex_lock(&m_mutex);
-}
-
-
-//------------------------------------------------------------------------------
-int32_t CMutex::trylock(
-    void
-)
-{
-    return pthread_mutex_trylock(&m_mutex);
-}
-
-
-//------------------------------------------------------------------------------
-int32_t CMutex::unlock(
-    void
-)
-{
-    return pthread_mutex_unlock(&m_mutex);
-}
-
-/** @} */
diff --git a/daemon/Common/CMutex.h b/daemon/Common/CMutex.h
deleted file mode 100644
index 23c410b..0000000
--- a/daemon/Common/CMutex.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/** @addtogroup MCD_MCDIMPL_DAEMON_SRV
- * @{
- * @file
- *
- * Mutex implementation (pthread wrapper).
- *
- * <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- *    products derived from this software without specific prior
- *    written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#ifndef CMUTEX_H_
-#define CMUTEX_H_
-
-#include <inttypes.h>
-#include "pthread.h"
-
-
-class CMutex
-{
-
-public:
-
-    CMutex(void);
-
-    ~CMutex(void);
-
-    int32_t lock(void);
-
-    int32_t trylock(void);
-
-    int32_t unlock(void);
-
-private:
-
-    pthread_mutex_t m_mutex;
-    pthread_cond_t m_cond;
-
-};
-
-#endif /* CMUTEX_H_ */
-
-/** @} */
diff --git a/daemon/Common/CSemaphore.h b/daemon/Common/CSemaphore.h
deleted file mode 100644
index 1a8d5ac..0000000
--- a/daemon/Common/CSemaphore.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/** @addtogroup MCD_MCDIMPL_DAEMON_SRV
- * @{
- * @file
- *
- * Semaphore implementation (pthread wrapper).
- *
- * <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- *    products derived from this software without specific prior
- *    written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#ifndef CSEMAPHORE_H_
-#define CSEMAPHORE_H_
-
-#include "pthread.h"
-
-/**
- * Could inherit from CMutex, or use CMutex internally.
- * Semaphore is a mutex with a counter. Constructor and destructor
- * code is the same.
- */
-
-class CSemaphore
-{
-
-public:
-
-    CSemaphore(int size = 0);
-
-    ~CSemaphore(void);
-
-    void wait(void);
-    bool wait(int sec);
-
-    bool wouldWait(void);
-
-    void signal(void);
-
-private:
-
-    pthread_mutex_t m_mutex;
-    pthread_cond_t m_cond;
-    int m_waiters_count;
-    int m_count;
-
-};
-
-#endif /*CSEMAPHORE_H_*/
-
-/** @} */
diff --git a/daemon/Common/CThread.h b/daemon/Common/CThread.h
deleted file mode 100644
index f30a699..0000000
--- a/daemon/Common/CThread.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/** @addtogroup MCD_MCDIMPL_DAEMON_SRV
- * @{
- * @file
- *
- * Thread implementation (pthread abstraction).
- *
- * <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- *    products derived from this software without specific prior
- *    written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#ifndef CTHREAD_H_
-#define CTHREAD_H_
-
-#include <inttypes.h>
-#include "CSemaphore.h"
-#include "pthread.h"
-
-using namespace std;
-
-
-class CThread
-{
-
-public:
-
-    CThread(void);
-
-    virtual ~CThread(void);
-
-    virtual void run(void) = 0;
-
-    void start(void);
-
-    void join(void);
-
-    void sleep(void);
-
-    void wakeup(void);
-
-    void terminate(void);
-
-    bool isExiting(void);
-
-    void setExiting(void);
-
-protected:
-
-    bool shouldTerminate(void);
-
-    void exit(int32_t exitcode);
-
-private:
-
-    CSemaphore *m_sem;
-    pthread_t m_thread;
-    bool m_terminate;
-    bool m_isExiting;
-
-};
-
-extern "C" void *CThreadStartup(void *);
-
-#endif /*CTHREAD_H_*/
-
-/** @} */
diff --git a/daemon/Common/CWsm.h b/daemon/Common/CWsm.h
deleted file mode 100644
index bd2404e..0000000
--- a/daemon/Common/CWsm.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/** @addtogroup MCD_MCDIMPL_DAEMON_SRV
- * @{
- * @file
- *
- * World shared memory definitions.
- *
- * <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- *    products derived from this software without specific prior
- *    written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#ifndef CWSM_H_
-#define CWSM_H_
-
-#include <stdint.h>
-#include <list>
-#include "McTypes.h"
-
-
-class CWsm
-{
-public:
-    addr_t virtAddr;
-    uint32_t len;
-    uint32_t handle;
-    addr_t physAddr;
-
-    CWsm(addr_t virtAddr,
-         uint32_t  len,
-         uint32_t  handle,
-         // this may be unknown, so is can be omitted.
-         addr_t    physAddr = NULL) :
-        virtAddr(virtAddr),
-        len(len),
-        handle(handle),
-        physAddr(physAddr)
-    { };
-
-};
-
-typedef CWsm                   *CWsm_ptr;
-typedef std::list<CWsm_ptr>  wsmList_t;
-typedef wsmList_t::iterator  wsmIterator_t;
-
-#endif /* CWSM_H_ */
-
-/** @} */
diff --git a/daemon/Common/McTypes.h b/daemon/Common/McTypes.h
deleted file mode 100644
index 0ba0b76..0000000
--- a/daemon/Common/McTypes.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/** @addtogroup MCD_MCDIMPL_DAEMON_SRV
- * @{
- * @file
- *
- * MobiCore types redefinition.
- *
- * <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- *    products derived from this software without specific prior
- *    written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#ifndef MCTYPES_H_
-#define MCTYPES_H_
-
-typedef void    *addr_t;
-
-#endif /* MCTYPES_H_ */
-
-/** @} */
diff --git a/daemon/Daemon/Device/DeviceIrqHandler.cpp b/daemon/Daemon/Device/DeviceIrqHandler.cpp
deleted file mode 100644
index 1c4b104..0000000
--- a/daemon/Daemon/Device/DeviceIrqHandler.cpp
+++ /dev/null
@@ -1,45 +0,0 @@
-/** @addtogroup MCD_MCDIMPL_DAEMON_DEV
- * @{
- * @file
- *
- *
- * <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- *    products derived from this software without specific prior
- *    written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "DeviceIrqHandler.h"
-#include "log.h"
-
-//------------------------------------------------------------------------------
-void DeviceIrqHandler::run(
-    void
-)
-{
-    handleIrq();
-    this->exit(-1);
-}
-
-/** @} */
diff --git a/daemon/Daemon/Device/DeviceIrqHandler.h b/daemon/Daemon/Device/DeviceIrqHandler.h
deleted file mode 100644
index 817c2d2..0000000
--- a/daemon/Daemon/Device/DeviceIrqHandler.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/** @addtogroup MCD_MCDIMPL_DAEMON_DEV
- * @{
- * @file
- *
- * IRQ handler thread.
- *
- * <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- *    products derived from this software without specific prior
- *    written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef DEVICEIRQHANDLER_H_
-#define DEVICEIRQHANDLER_H_
-
-#include "CThread.h"
-
-
-class DeviceIrqHandler: public CThread
-{
-
-public:
-
-    virtual void handleIrq() = 0;
-
-    void run();
-};
-
-#endif /* DEVICEIRQHANDLER_H_ */
-
-/** @} */
diff --git a/daemon/Daemon/Device/DeviceScheduler.cpp b/daemon/Daemon/Device/DeviceScheduler.cpp
deleted file mode 100644
index b0ae904..0000000
--- a/daemon/Daemon/Device/DeviceScheduler.cpp
+++ /dev/null
@@ -1,45 +0,0 @@
-/** @addtogroup MCD_MCDIMPL_DAEMON_DEV
- * @{
- * @file
- *
- *
- * <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- *    products derived from this software without specific prior
- *    written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "DeviceScheduler.h"
-
-
-//------------------------------------------------------------------------------
-void DeviceScheduler::run(
-    void
-)
-{
-    schedule();
-    exit(-1);
-}
-
-/** @} */
diff --git a/daemon/Daemon/Device/DeviceScheduler.h b/daemon/Daemon/Device/DeviceScheduler.h
deleted file mode 100644
index 85a6383..0000000
--- a/daemon/Daemon/Device/DeviceScheduler.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/** @addtogroup MCD_MCDIMPL_DAEMON_DEV
- * @{
- * @file
- *
- * Scheduler thread
- *
- * <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- *    products derived from this software without specific prior
- *    written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef DEVICESCHEDULER_H_
-#define DEVICESCHEDULER_H_
-
-#include "CThread.h"
-
-
-class DeviceScheduler: public CThread
-{
-
-public:
-
-    virtual void schedule() = 0;
-
-    void run();
-
-};
-
-#endif /* DEVICESCHEDULER_H_ */
-
-/** @} */
diff --git a/daemon/Daemon/Device/NotificationQueue.cpp b/daemon/Daemon/Device/NotificationQueue.cpp
deleted file mode 100644
index ef827b3..0000000
--- a/daemon/Daemon/Device/NotificationQueue.cpp
+++ /dev/null
@@ -1,79 +0,0 @@
-/** @addtogroup MCD_MCDIMPL_DAEMON_DEV
- * @{
- * @file
- *
- *
- * <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- *    products derived from this software without specific prior
- *    written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#include "NotificationQueue.h"
-#include <stddef.h>
-
-#include "log.h"
-
-//------------------------------------------------------------------------------
-NotificationQueue::NotificationQueue(
-    notificationQueue_t *i,
-    notificationQueue_t *o,
-    uint32_t size
-) : in(i), out(o)
-{
-    in->hdr.queueSize = size;
-    out->hdr.queueSize = size;
-}
-
-
-//------------------------------------------------------------------------------
-void NotificationQueue::putNotification(
-    notification_t *notification
-)
-{
-    mutex.lock();
-    if ((out->hdr.writeCnt - out->hdr.readCnt) < out->hdr.queueSize) {
-        out->notification[out->hdr.writeCnt & (out->hdr.queueSize - 1)]
-        = *notification;
-        out->hdr.writeCnt++;
-    }
-    mutex.unlock();
-}
-
-
-//------------------------------------------------------------------------------
-notification_t *NotificationQueue::getNotification(
-    void
-)
-{
-    notification_t *ret = NULL;
-    mutex.lock();
-    if ((in->hdr.writeCnt - in->hdr.readCnt) > 0) {
-        ret = &(in->notification[in->hdr.readCnt & (in->hdr.queueSize - 1)]);
-        in->hdr.readCnt++;
-    }
-    mutex.unlock();
-    return ret;
-}
-
-/** @} */
diff --git a/daemon/Daemon/Device/NotificationQueue.h b/daemon/Daemon/Device/NotificationQueue.h
deleted file mode 100644
index 235e10d..0000000
--- a/daemon/Daemon/Device/NotificationQueue.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/** @addtogroup MCD_MCDIMPL_DAEMON_DEV
- * @{
- * @file
- *
- * MobiCore Notification Queue handling.
- *
- * <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- *    products derived from this software without specific prior
- *    written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#ifndef NOTIFICATIONQUEUE_H_
-#define NOTIFICATIONQUEUE_H_
-
-#include <inttypes.h> //C99 data
-#include "Mci/mcinq.h"
-#include "CMutex.h"
-
-
-class NotificationQueue
-{
-
-public:
-
-    /** NQ Constructor, initializes the NQ component.
-     *
-     * makes the given queue object usable with the queue<Command> type of functions
-     *
-     * @param in queue to initialize
-     * @param out beginning of queue header
-     * @param queueSize Size of the queue
-     */
-    NotificationQueue(
-        notificationQueue_t *in,
-        notificationQueue_t *out,
-        uint32_t size
-    );
-
-    /** Places an element to the outgoing queue.
-     *
-     * @param notification Data to be placed in queue.
-     */
-    void putNotification(
-        notification_t *notification
-    );
-
-    /** Retrieves the first element from the queue.
-     *
-     * @return first notification Queue element.
-     * @return NULL if the queue is empty.
-     */
-    notification_t *getNotification(
-        void
-    );
-
-private:
-
-    notificationQueue_t *in;
-    notificationQueue_t *out;
-    CMutex mutex;
-
-};
-
-#endif /* NOTIFICATIONQUEUE_H_ */
-
-/** @} */
diff --git a/daemon/Daemon/Device/TrustletSession.cpp b/daemon/Daemon/Device/TrustletSession.cpp
deleted file mode 100644
index 8eda1c8..0000000
--- a/daemon/Daemon/Device/TrustletSession.cpp
+++ /dev/null
@@ -1,124 +0,0 @@
-/** @addtogroup MCD_MCDIMPL_DAEMON_DEV
- * @{
- * @file
- *
- * <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- *    products derived from this software without specific prior
- *    written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "TrustletSession.h"
-#include <cstdlib>
-
-#include "log.h"
-
-using namespace std;
-
-//------------------------------------------------------------------------------
-TrustletSession::TrustletSession(Connection *deviceConnection, uint32_t sessionId)
-{
-    this->deviceConnection = deviceConnection;
-    this->notificationConnection = NULL;
-    this->sessionId = sessionId;
-    sessionMagic = rand();
-}
-
-
-//------------------------------------------------------------------------------
-TrustletSession::~TrustletSession(void)
-{
-    map<uint32_t, CWsm_ptr>::iterator it;
-    delete notificationConnection;
-
-    if (!buffers.empty()) {
-        LOG_W("%s: Mapped buffers still available %u", __func__, buffers.size());
-    }
-    for ( it = buffers.begin() ; it != buffers.end(); it++ )
-        delete (*it).second;
-
-    buffers.clear();
-}
-
-//------------------------------------------------------------------------------
-void TrustletSession::queueNotification(notification_t *notification)
-{
-    notifications.push(*notification);
-}
-
-//------------------------------------------------------------------------------
-void TrustletSession::processQueuedNotifications(void)
-{
-    // Nothing to do here!
-    if (notificationConnection == NULL)
-        return;
-
-    while (!notifications.empty()) {
-        // Forward session ID and additional payload of
-        // notification to the just established connection
-        notificationConnection->writeData((void *)&notifications.front(),
-                                          sizeof(notification_t));
-        notifications.pop();
-    }
-}
-
-//------------------------------------------------------------------------------
-bool TrustletSession::addBulkBuff(CWsm_ptr pWsm)
-{
-    if (!pWsm)
-        return false;
-    if (buffers.find(pWsm->handle) != buffers.end()) {
-        delete pWsm;
-        return false;
-    }
-    buffers[pWsm->handle] = pWsm;
-    return true;
-}
-
-//------------------------------------------------------------------------------
-bool TrustletSession::removeBulkBuff(uint32_t handle)
-{
-    if (buffers.find(handle) == buffers.end()) {
-        return false;
-    }
-    CWsm_ptr pWsm = buffers[handle];
-    delete pWsm;
-    buffers.erase(handle);
-    return true;
-}
-
-//------------------------------------------------------------------------------
-CWsm_ptr TrustletSession::popBulkBuff()
-{
-    if (buffers.empty()) {
-        return NULL;
-    }
-
-    CWsm_ptr pWsm = buffers.begin()->second;
-    // Remove it from the map
-    buffers.erase(pWsm->handle);
-    return pWsm;
-}
-
-/** @} */
diff --git a/daemon/Daemon/Device/TrustletSession.h b/daemon/Daemon/Device/TrustletSession.h
deleted file mode 100644
index 96199d7..0000000
--- a/daemon/Daemon/Device/TrustletSession.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/** @addtogroup MCD_MCDIMPL_DAEMON_DEV
- * @{
- * @file
- *
- * <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- *    products derived from this software without specific prior
- *    written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#ifndef TRUSTLETSESSION_H_
-#define TRUSTLETSESSION_H_
-
-#include "NotificationQueue.h"
-#include "CWsm.h"
-#include "Connection.h"
-#include <queue>
-#include <map>
-
-
-class TrustletSession
-{
-private:
-    std::queue<notification_t> notifications;
-    std::map<uint32_t, CWsm_ptr> buffers;
-
-public:
-    uint32_t sessionId;
-    uint32_t sessionMagic; // Random data
-    Connection *deviceConnection;
-    Connection *notificationConnection;
-
-    TrustletSession(Connection *deviceConnection, uint32_t sessionId);
-
-    ~TrustletSession(void);
-
-    void queueNotification(notification_t *notification);
-
-    void processQueuedNotifications(void);
-
-    bool addBulkBuff(CWsm_ptr pWsm);
-
-    bool removeBulkBuff(uint32_t handle);
-
-    CWsm_ptr popBulkBuff();
-
-};
-
-typedef std::list<TrustletSession *> trustletSessionList_t;
-typedef trustletSessionList_t::iterator trustletSessionIterator_t;
-
-#endif /* TRUSTLETSESSION_H_ */
-
-/** @} */
diff --git a/daemon/Daemon/Device/public/ExcDevice.h b/daemon/Daemon/Device/public/ExcDevice.h
deleted file mode 100644
index 3805c26..0000000
--- a/daemon/Daemon/Device/public/ExcDevice.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/** @addtogroup MCD_MCDIMPL_DAEMON_DEV
- * @{
- * @file
- *
- * Device exceptions.
- *
- * <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- *    products derived from this software without specific prior
- *    written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#ifndef EXCDEVICE_H_
-#define EXCDEVICE_H_
-
-#include <stdint.h>
-#include <exception>
-#include <cstdio>
-#include <cstdlib>
-
-#define ERROR_MCI_VERSION_MISMATCH  ((int)(-2))
-#define ERROR_KMOD_VERSION_MISMATCH  ((int)(-3))
-
-class ExcDevice: public std::exception
-{
-
-public:
-
-    ExcDevice(const char *description, int cause) :
-        cause(cause), description(description) {
-    }
-
-    virtual int getCause() const throw () {
-        return cause;
-    }
-
-    virtual const char *getDescription() const throw () {
-        return description;
-    }
-
-private:
-
-    int cause;
-    const char *description;
-};
-
-#endif /* EXCDEVICE_H_ */
-
-/** @} */
diff --git a/daemon/Daemon/Server/public/ConnectionHandler.h b/daemon/Daemon/Server/public/ConnectionHandler.h
deleted file mode 100644
index ed35fa0..0000000
--- a/daemon/Daemon/Server/public/ConnectionHandler.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/** @addtogroup MCD_MCDIMPL_DAEMON_SRV
- * @{
- * @file
- *
- * Interface for connection handlers used by Server.
- *
- * <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- *    products derived from this software without specific prior
- *    written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#ifndef CONNECTIONHANDLER_H_
-#define CONNECTIONHANDLER_H_
-
-#include "Connection.h"
-
-
-class ConnectionHandler
-{
-
-public:
-    virtual ~ConnectionHandler() {};
-
-    /**
-     * Handle connection activities.
-     * The connection handler shall process pending connection activities.
-     *
-     * @param [in] connection Reference to the connection which has data to process.
-     */
-    virtual bool handleConnection(
-        Connection *connection
-    ) = 0;
-
-    /**
-     * Connection has been closed.
-     * The connection handler shall clean up all resources associated with the given connection.
-     * After the method has been executed the connection object will be deleted.
-     *
-     * @param [in] connection Reference to the connection which will be deleted.
-     */
-    virtual void dropConnection(
-        Connection *connection
-    ) = 0;
-};
-
-#endif /* CONNECTIONHANDLER_H_ */
-
-/** @} */
diff --git a/daemon/Daemon/public/mcVersion.h b/daemon/Daemon/public/mcVersion.h
deleted file mode 100644
index 27f80d1..0000000
--- a/daemon/Daemon/public/mcVersion.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/**
- * <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- *    products derived from this software without specific prior
- *    written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#ifndef DAEMON_VERSION_H_
-#define DAEMON_VERSION_H_
-
-#define DAEMON_VERSION_MAJOR 0
-#define DAEMON_VERSION_MINOR 2
-
-#endif /** DAEMON_VERSION_H_ */
-
diff --git a/daemon/Kernel/CKMod.h b/daemon/Kernel/CKMod.h
deleted file mode 100644
index bdc4151..0000000
--- a/daemon/Kernel/CKMod.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/** @addtogroup MCD_MCDIMPL_DAEMON_KERNEL
- * @{
- * @file
- *
- * Kernel Module Interface.
- *
- * <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- *    products derived from this software without specific prior
- *    written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#ifndef CKMOD_H_
-#define CKMOD_H_
-
-#include <stdint.h>
-#include "ClientLib/public/MobiCoreDriverApi.h"
-
-
-/**
- * Base class for accessing a kernel module.
- */
-class CKMod
-{
-
-protected:
-
-    int  fdKMod;
-
-    /**
-     * Helper function to check if connected to kernel module.
-     */
-    bool isOpen(
-        void
-    );
-
-public:
-
-    CKMod(
-        void
-    );
-
-    virtual ~CKMod(
-        void
-    );
-
-    mcResult_t open(
-        const char *deviceName
-    );
-
-    void close(
-        void
-    );
-
-};
-
-#endif // CKMOD_H_
diff --git a/daemon/PaApi/Android.mk b/daemon/PaApi/Android.mk
deleted file mode 100644
index 614d021..0000000
--- a/daemon/PaApi/Android.mk
+++ /dev/null
@@ -1,11 +0,0 @@
-# =============================================================================
-#
-# Module: libPaApi
-#
-# =============================================================================
-
-# Add your folders with header files here (absolute paths)
-LOCAL_C_INCLUDES += $(LOCAL_PATH)/PaApi/Public
-
-# Add your source files here (relative paths)
-LOCAL_SRC_FILES	+= PaApi/tlcCmApi.cpp
diff --git a/daemon/PaApi/Public/paApi.h b/daemon/PaApi/Public/paApi.h
deleted file mode 100644
index e0c5725..0000000
--- a/daemon/PaApi/Public/paApi.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/**
- * @file
- * Proivisioning Agent API.
- *
- * This header file describes the Provisioning Agent API.
- *
- * <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- *    products derived from this software without specific prior
- *    written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @defgroup PA_API Provisioning Agent API
- * @defgroup TLC_CONTENT_MANAGER Content Manager API
- * @ingroup PA_API
- *
- * @defgroup MCD_MCDIMPL_DAEMON_REG Registry API
- * @ingroup PA_API
- */
-
-#include "tlcCmApi.h"
-#include "MobiCoreRegistry.h"
-
-
diff --git a/daemon/PaApi/Public/tlcCmApi.h b/daemon/PaApi/Public/tlcCmApi.h
deleted file mode 100644
index 0fb6f56..0000000
--- a/daemon/PaApi/Public/tlcCmApi.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/** @addtogroup TLC_CONTENT_MANAGER
- * @{
- * @file
- * Content Manager API.
- *
- * This header file describes the interface to the content management trustlet
- * connector (Content Manager).
- *
- * <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- *    products derived from this software without specific prior
- *    written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "MobiCoreDriverApi.h"
-#include "mcUuid.h"
-#include "TlCm/2.0/tlCmApi.h"
-#include "TlCm/tlCmError.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-    /** Opens a content management session.
-     *
-     * After opening a content management session the content manager is ready to
-     * accecpt content management requests. Upon successful execution, this function
-     * sets the cmp pointer to a content management protocol object that is to be
-     * used for subsequent content management operations.
-     *
-     * @param [out] cmp Content management protocol object.
-     *
-     * @return MC_DRV_OK or error code.
-     */
-    mcResult_t cmOpen(cmp_t **cmp);
-
-    /** Closes a content management session.
-     *
-     * @return MC_DRV_OK or error code.
-     */
-    mcResult_t cmClose(void);
-
-    /** Performs a content management operation.
-     *
-     * Executes the command contained in the content management protocol object
-     *
-     * returned from cmOpen. The result of the content management operation is also
-     * conveyed within the CMP object returned from cmOpen, unless the overall
-     * operation was aborted due to a low-level driver error, in which case the
-     * return value of this routine is different to MC_DRV_OK.
-     *
-     * @return Indication as to whether the content management operation was executed.
-     * MC_DRV_OK denotes that the operation was executed (see response contents of
-     * the cmp_t object for details about the result of the operation).
-     */
-    mcResult_t cmManage(void);
-
-#ifdef __cplusplus
-}
-#endif
-
-/** @} */
-
diff --git a/daemon/PaApi/tlcCmApi.cpp b/daemon/PaApi/tlcCmApi.cpp
deleted file mode 100644
index a8bc260..0000000
--- a/daemon/PaApi/tlcCmApi.cpp
+++ /dev/null
@@ -1,119 +0,0 @@
-/** @addtogroup TLC_CONTENT_MANAGER
- * @{
- * @file
- * Content Manager API (implementation).
- *
- * <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- *    products derived from this software without specific prior
- *    written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "tlcCmApi.h"
-#include "TlCm/tlCmUuid.h"
-
-#include "log.h"
-
-#include <assert.h>
-#include <stdlib.h>
-
-static mcSessionHandle_t m_sessionHandle = { 0, 0 };
-
-mcResult_t cmOpen(cmp_t **cmp)
-{
-    const mcUuid_t UUID = TL_CM_UUID;
-    mcResult_t result;
-
-    if (NULL == cmp) {
-        LOG_E("Parameter cmp is NULL");
-        return MC_DRV_ERR_INVALID_PARAMETER;
-    }
-
-    result = mcOpenDevice(MC_DEVICE_ID_DEFAULT);
-    if (MC_DRV_OK != result) {
-        LOG_E("Error opening device: %d", result);
-        return result;
-    }
-    result = mcMallocWsm(MC_DEVICE_ID_DEFAULT, 0, sizeof(cmp_t), (uint8_t **)cmp, 0);
-    if (MC_DRV_OK != result) {
-        LOG_E("Allocation of CMP WSM failed: %d", result);
-        return result;
-    }
-
-    result = mcOpenSession(&m_sessionHandle, &UUID, (uint8_t *) * cmp, (uint32_t) sizeof(cmp_t));
-    if (MC_DRV_OK != result) {
-        LOG_E("Open session failed: %d", result);
-    }
-
-    return result;
-}
-
-mcResult_t cmClose(void)
-{
-    mcResult_t result;
-
-    if (0 == m_sessionHandle.sessionId) {
-        LOG_E("No session to close!");
-    }
-    result = mcCloseSession(&m_sessionHandle);
-    if (MC_DRV_OK != result) {
-        LOG_E("Closing session failed: %d", result);
-    }
-    result = mcCloseDevice(MC_DEVICE_ID_DEFAULT);
-    if (MC_DRV_OK != result) {
-        LOG_E("Closing MobiCore device failed: %d", result);
-    }
-
-    return result;
-}
-
-mcResult_t cmManage(void)
-{
-    mcResult_t result;
-
-    if (0 == m_sessionHandle.sessionId) {
-        LOG_E("No session.");
-        return MC_DRV_ERR_INIT;
-    }
-
-    // Send CMP message to content management trustlet.
-    result = mcNotify(&m_sessionHandle);
-
-    if (MC_DRV_OK != result) {
-        LOG_E("Notify failed: %d", result);
-        return result;
-    }
-
-    // Wait for trustlet response.
-    result = mcWaitNotification(&m_sessionHandle, MC_INFINITE_TIMEOUT);
-
-    if (MC_DRV_OK != result) {
-        LOG_E("Wait for response notification failed: %d", result);
-        return result;
-    }
-
-    return MC_DRV_OK;
-}
-
-/** @} */
diff --git a/daemon/build.sh b/daemon/build.sh
deleted file mode 100755
index 465137f..0000000
--- a/daemon/build.sh
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/bash
-cd "$(dirname "$0")"
-./bootstrap.sh 2 Locals/Build/doBuild.sh "$@"
diff --git a/include/Public/mc_linux.h b/include/Public/mc_linux.h
old mode 100644
new mode 100755
index af027dc..98e7af1
--- a/include/Public/mc_linux.h
+++ b/include/Public/mc_linux.h
@@ -1,7 +1,7 @@
 /*
  * The MobiCore Driver Kernel Module is a Linux device driver, which represents
  * the command proxy on the lowest layer to the secure world (Swd). Additional
- * services like memory allocation via mmap and generation of a L2 tables for
+ * services like memory allocation via mmap and generation of a MMU tables for
  * given virtual memory are also supported. IRQ functionality receives
  * information from the SWd in the non secure world (NWd).
  * As customary the driver is handled as linux device driver with "open",
@@ -55,8 +55,6 @@
  * INIT request data to SWD
  */
 struct mc_ioctl_init {
-	/* notification buffer start/length [16:16] [start, length] */
-	uint32_t  nq_offset;
 	/* length of notification queue */
 	uint32_t  nq_length;
 	/* mcp buffer start/length [16:16] [start, length] */
@@ -76,8 +74,7 @@
 };
 
 /*
- * Data exchange structure of the MC_IO_MAP_WSM, MC_IO_MAP_MCI, and
- *				  MC_IO_MAP_PWSM commands.
+ * Data exchange structure of the MC_IO_MAP_WSM and MC_IO_MAP_MCI commands.
  *
  * Allocate a contiguous memory buffer for a process.
  * The physical address can be used as for later calls to mmap.
@@ -86,19 +83,19 @@
  * already. I.e. Daemon was restarted.
  */
 struct mc_ioctl_map {
-	size_t	      len;	/* Buffer length */
-	uint32_t      handle;	/* WSM handle */
-	unsigned long addr;	/* Virtual address */
-	unsigned long phys_addr;/* physical address of WSM (or NULL) */
-	bool	      reused;	/* if WSM memory was reused, or new allocated */
+	size_t		len;	/* Buffer length */
+	uint32_t	handle;	/* WSM handle */
+	uint64_t	phys_addr; /* physical address of WSM (or 0) */
+	unsigned long	addr;	/* Virtual address */
+	bool		reused;	/* if WSM memory was reused, or new allocated */
 };
 
 /*
  * Data exchange structure of the MC_IO_REG_WSM command.
  *
- * Allocates a physical L2 table and maps the buffer into this page.
- * Returns the physical address of the L2 table.
- * The page alignment will be created and the appropriated pSize and pOffsetL2
+ * Allocates a physical MMU table and maps the buffer into this page.
+ * Returns the physical address of the MMU table.
+ * The page alignment will be created and the appropriated pSize and pOffsetMMU
  * will be modified to the used values.
  */
 struct mc_ioctl_reg_wsm {
@@ -106,19 +103,7 @@
 	uint32_t len;		/* size of the virtual address space */
 	uint32_t pid;		/* process id */
 	uint32_t handle;	/* driver handle for locked memory */
-	uint32_t table_phys;	/* physical address of the L2 table */
-};
-
-
-/*
- * Data exchange structure of the MC_DRV_MODULE_FC_EXECUTE ioctl command.
- * internal, unsupported
- */
-struct mc_ioctl_execute {
-	/* base address of mobicore binary */
-	uint32_t phys_start_addr;
-	/* length of DDR area */
-	uint32_t length;
+	uint64_t table_phys;	/* physical address of the MMU table */
 };
 
 /*
@@ -127,10 +112,10 @@
 struct mc_ioctl_resolv_cont_wsm {
 	/* driver handle for buffer */
 	uint32_t handle;
-	/* base address of memory */
-	uint32_t phys;
 	/* length memory */
 	uint32_t length;
+	/* base address of memory */
+	uint64_t phys;
 	/* fd to owner of the buffer */
 	int32_t fd;
 };
@@ -144,7 +129,7 @@
 	/* fd to owner of the buffer */
 	int32_t fd;
 	/* base address of memory */
-	uint32_t phys;
+	uint64_t phys;
 };
 
 
@@ -180,28 +165,24 @@
  */
 #define MC_IO_FREE		_IO(MC_IOC_MAGIC, 5)
 /*
- * Creates a L2 Table of the given base address and the size of the
+ * Creates a MMU Table of the given base address and the size of the
  * data.
- * Parameter: mc_ioctl_app_reg_wsm_l2_params
+ * Parameter: mc_ioctl_reg_wsm
  */
 #define MC_IO_REG_WSM		_IOWR(MC_IOC_MAGIC, 6, struct mc_ioctl_reg_wsm)
 #define MC_IO_UNREG_WSM		_IO(MC_IOC_MAGIC, 7)
 #define MC_IO_LOCK_WSM		_IO(MC_IOC_MAGIC, 8)
 #define MC_IO_UNLOCK_WSM	_IO(MC_IOC_MAGIC, 9)
-#define MC_IO_EXECUTE		_IOWR(MC_IOC_MAGIC, 10, struct mc_ioctl_execute)
 
 /*
  * Allocate contiguous memory for a process for later mapping with mmap.
- * MC_DRV_KMOD_MMAP_WSM	usual operation, pages are registered in
+ * MC_IO_MAP_WSM	usual operation, pages are registered in
  *					device structure and freed later.
- * MC_DRV_KMOD_MMAP_MCI	get Instance of MCI, allocates or mmaps
+ * MC_IO_MAP_MCI	get Instance of MCI, allocates or mmaps
  *					the MCI to daemon
- * MC_DRV_KMOD_MMAP_PERSISTENTWSM	special operation, without
- *						registration of pages
  */
 #define MC_IO_MAP_WSM		_IOWR(MC_IOC_MAGIC, 11, struct mc_ioctl_map)
 #define MC_IO_MAP_MCI		_IOWR(MC_IOC_MAGIC, 12, struct mc_ioctl_map)
-#define MC_IO_MAP_PWSM		_IOWR(MC_IOC_MAGIC, 13, struct mc_ioctl_map)
 
 /*
  * Clean orphaned WSM buffers. Only available to the daemon and should
@@ -215,7 +196,7 @@
 #define MC_IO_CLEAN_WSM		_IO(MC_IOC_MAGIC, 14)
 
 /*
- * Get L2 phys address of a buffer handle allocated to the user.
+ * Get MMU phys address of a buffer handle allocated to the user.
  * Only available to the daemon.
  */
 #define MC_IO_RESOLVE_WSM	_IOWR(MC_IOC_MAGIC, 15, \
diff --git a/include/Public/version.h b/include/Public/version.h
old mode 100644
new mode 100755
diff --git a/rootpa/Code/Android/app/Android.mk b/rootpa/Code/Android/app/Android.mk
index 3e97ae5..90b9067 100755
--- a/rootpa/Code/Android/app/Android.mk
+++ b/rootpa/Code/Android/app/Android.mk
@@ -10,7 +10,7 @@
 LOCAL_JNI_SHARED_LIBRARIES := libcommonpawrapper
 
 LOCAL_PACKAGE_NAME := RootPA
-LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_TAGS := debug eng optional
 LOCAL_CERTIFICATE := platform
 
 LOCAL_PROGUARD_FLAGS := -include $(LOCAL_PATH)/proguard-project.txt
diff --git a/rootpa/Code/Android/app/AndroidManifest.xml b/rootpa/Code/Android/app/AndroidManifest.xml
index 04460bf..7ffb326 100755
--- a/rootpa/Code/Android/app/AndroidManifest.xml
+++ b/rootpa/Code/Android/app/AndroidManifest.xml
@@ -25,7 +25,8 @@
 
   <application 
     android:label="RootPA" 
-    android:debuggable="false">
+    android:debuggable="false"
+    android:theme="@android:style/Theme.NoDisplay">
     <service 
         android:name="com.gd.mobicore.pa.service.ProvisioningService" 
         android:enabled="true"
diff --git a/rootpa/Code/Android/app/jni/Common/Android.mk b/rootpa/Code/Android/app/jni/Common/Android.mk
index 7fbf94d..ceee2ac 100755
--- a/rootpa/Code/Android/app/jni/Common/Android.mk
+++ b/rootpa/Code/Android/app/jni/Common/Android.mk
@@ -77,6 +77,6 @@
     LOCAL_MODULE    := provisioningagent
 endif
 
-LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_TAGS := debug eng optional
 
 include $(BUILD_STATIC_LIBRARY)
diff --git a/rootpa/Code/Android/app/jni/CommonPAWrapper/Android.mk b/rootpa/Code/Android/app/jni/CommonPAWrapper/Android.mk
index 1bfefef..6c68ca8 100755
--- a/rootpa/Code/Android/app/jni/CommonPAWrapper/Android.mk
+++ b/rootpa/Code/Android/app/jni/CommonPAWrapper/Android.mk
@@ -58,7 +58,7 @@
 LOCAL_C_INCLUDES +=  $(LOCAL_PATH)/../../../../Common/include
 
 LOCAL_MODULE    := libcommonpawrapper
-LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_TAGS := debug eng optional
 
 ifeq ($(ROOTPA_MODULE_TEST), 1)
     LOCAL_STATIC_LIBRARIES += provisioningagent_test
diff --git a/rootpa/Code/Android/app/jni/CommonPAWrapper/CmpBase.cpp b/rootpa/Code/Android/app/jni/CommonPAWrapper/CmpBase.cpp
index 5ff328a..4a0b3e3 100755
--- a/rootpa/Code/Android/app/jni/CommonPAWrapper/CmpBase.cpp
+++ b/rootpa/Code/Android/app/jni/CommonPAWrapper/CmpBase.cpp
@@ -64,6 +64,15 @@
 */
 CmpBase::~CmpBase()
 {
+    if(cls_!=NULL)
+    {
+        env_->DeleteLocalRef(cls_);
+    }
+
+    if(objectCls_!=NULL)
+    {
+        env_->DeleteLocalRef(objectCls_);
+    }
 }
 
 /*
@@ -76,7 +85,7 @@
         jmethodID mid =  env_->GetMethodID(cls_, "size", "()I");
         if(mid !=0)
         {
-            numberOfElements_ = (int) env_->CallIntMethod(msgs_, mid);
+            numberOfElements_ = (int) env_->CallIntMethod(msgs_, mid);            
         }
         else
         {
@@ -88,3 +97,5 @@
 
 
 
+
+
diff --git a/rootpa/Code/Android/app/jni/CommonPAWrapper/CmpResponses.cpp b/rootpa/Code/Android/app/jni/CommonPAWrapper/CmpResponses.cpp
index db19396..4ab2557 100755
--- a/rootpa/Code/Android/app/jni/CommonPAWrapper/CmpResponses.cpp
+++ b/rootpa/Code/Android/app/jni/CommonPAWrapper/CmpResponses.cpp
@@ -78,6 +78,7 @@
                 ret=ROOTPA_ERROR_INTERNAL;
                 LOGE("adding cmp response object %d failed", i);                
             }
+            env_->DeleteLocalRef(responseObject);
         }
         else
         {
@@ -133,6 +134,12 @@
             {
                 LOGE("CmpResponses::createCmpResponseObject creating constructor failed");                
             }
+            
+            if(rsp != NULL)
+            {
+                env_->DeleteLocalRef(rsp);
+            }
+            
         }
         else
         {
@@ -140,6 +147,12 @@
         }
     }
     
+    if(objectCls_!=NULL)
+    {
+        env_->DeleteLocalRef(objectCls_);
+        objectCls_=NULL;
+    }
+
     return newObject;
 }
 
diff --git a/rootpa/Code/Android/app/jni/CommonPAWrapper/JniHelpers.cpp b/rootpa/Code/Android/app/jni/CommonPAWrapper/JniHelpers.cpp
index 5674e37..95f6642 100755
--- a/rootpa/Code/Android/app/jni/CommonPAWrapper/JniHelpers.cpp
+++ b/rootpa/Code/Android/app/jni/CommonPAWrapper/JniHelpers.cpp
@@ -44,6 +44,24 @@
                                      listAdd_(NULL)
 {}                                     
 
+JniHelpers::~JniHelpers()
+{
+    if(listCls_!=NULL)
+    {
+        envP_->DeleteLocalRef(listCls_);
+    }
+    
+    if(intCls_!=NULL)
+    {
+        envP_->DeleteLocalRef(intCls_);
+    }    
+    
+    if(stringCls_!=NULL)
+    {
+        envP_->DeleteLocalRef(stringCls_);
+    }    
+}
+
 
 JniHelpers::JniHelpers(JNIEnv* envP,jobject* keysP, jobject* valuesP, jbyteArray* productIdP):broken_(false), 
                                                                                               envP_(envP),
@@ -117,23 +135,25 @@
         broken_=true;
         return ROOTPA_ERROR_INTERNAL;
     }
-
     
     jobject newStringObject = envP_->NewObject(stringCls_, stringConstructur_, fName);
     if(NULL == newStringObject)
     {
         LOGE("JniHelpers::setVersion no newStringObject");    
         broken_=true;
+        envP_->DeleteLocalRef(fName);
         return ROOTPA_ERROR_INTERNAL;
     }
+    envP_->DeleteLocalRef(fName);
 
     if(envP_->CallBooleanMethod(*keysP_, listAdd_, newStringObject)==JNI_FALSE)
     {
         LOGE("JniHelpers::setVersion can not add key");    
         broken_=true;
+        envP_->DeleteLocalRef(newStringObject);
         return ROOTPA_ERROR_INTERNAL;        
     }
-
+    envP_->DeleteLocalRef(newStringObject);
 
     jobject newIntObject = envP_->NewObject(intCls_, intConstructor_, version);
     if(NULL == newIntObject)
@@ -147,8 +167,11 @@
     {
         LOGE("JniHelpers::setVersion can not add value");    
         broken_=true;
+        envP_->DeleteLocalRef(newIntObject);
         return ROOTPA_ERROR_INTERNAL;        
     }
+    envP_->DeleteLocalRef(newIntObject);
+    
     return ROOTPA_OK;   
 }
 
@@ -189,6 +212,7 @@
     jbyteArray jbArray = NULL;
     if (envP_->EnsureLocalCapacity(1) == JNI_OK) 
     {
+    
         if ((length > 0) && (dataP != NULL)) 
         {
             jbArray = envP_->NewByteArray(length);
@@ -196,8 +220,9 @@
             {
                 envP_->SetByteArrayRegion(jbArray, 0, length, (jbyte*) dataP);
             }
-        }
+        }       
     }
+
     return jbArray;
 }
 
diff --git a/rootpa/Code/Android/app/jni/CommonPAWrapper/JniHelpers.h b/rootpa/Code/Android/app/jni/CommonPAWrapper/JniHelpers.h
index 7a32bf4..2a93d80 100755
--- a/rootpa/Code/Android/app/jni/CommonPAWrapper/JniHelpers.h
+++ b/rootpa/Code/Android/app/jni/CommonPAWrapper/JniHelpers.h
@@ -42,6 +42,7 @@
     public:
         JniHelpers(JNIEnv* envP);
         JniHelpers(JNIEnv* envP, jobject* keysP, jobject* valuesP, jbyteArray* productIdP);
+        virtual ~JniHelpers();
         int setVersion(char* fieldName, int version);
         int setProductId(char* productId);
         int setByteArray(jbyteArray* targetArrayP, uint8_t* sourceArrayP , uint32_t length);
diff --git a/rootpa/Code/Android/app/jni/CommonPAWrapper/com_gd_mobicore_pa_jni_CommonPAWrapper.h b/rootpa/Code/Android/app/jni/CommonPAWrapper/com_gd_mobicore_pa_jni_CommonPAWrapper.h
index 8312793..c3aa05d 100755
--- a/rootpa/Code/Android/app/jni/CommonPAWrapper/com_gd_mobicore_pa_jni_CommonPAWrapper.h
+++ b/rootpa/Code/Android/app/jni/CommonPAWrapper/com_gd_mobicore_pa_jni_CommonPAWrapper.h
@@ -157,6 +157,11 @@
 JNIEXPORT void JNICALL Java_com_gd_mobicore_pa_jni_CommonPAWrapper_setEnvironmentVariable
   (JNIEnv *, jobject, jbyteArray, jbyteArray);
 
+
+JNIEXPORT jint JNICALL Java_com_gd_mobicore_pa_jni_CommonPAWrapper_storeTA
+  (JNIEnv *, jobject, jint, jbyteArray, jbyteArray);
+
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/rootpa/Code/Android/app/jni/CommonPAWrapper/commonwrapper.cpp b/rootpa/Code/Android/app/jni/CommonPAWrapper/commonwrapper.cpp
index 9867029..1c6d3a3 100755
--- a/rootpa/Code/Android/app/jni/CommonPAWrapper/commonwrapper.cpp
+++ b/rootpa/Code/Android/app/jni/CommonPAWrapper/commonwrapper.cpp
@@ -118,8 +118,8 @@
         delete [] commands[i].contentP;
         free(responses[i].contentP); // this is reserved with malloc
     }
-    delete commands;
-    delete responses;
+    delete [] commands;
+    delete [] responses;
     LOGD("<<Java_com_gd_mobicore_pa_jni_CommonPAWrapper_executeCmpCommands %d\n", ret);
 
     return ret;
@@ -140,7 +140,7 @@
 JNIEXPORT jint JNICALL Java_com_gd_mobicore_pa_jni_CommonPAWrapper_getVersion
   (JNIEnv* env, jobject, jbyteArray productId, jobject keys, jobject values)
 {
-
+    LOGD(">>Java_com_gd_mobicore_pa_jni_CommonPAWrapper_getVersion %x %x %x\n", productId, keys, values);
     int ret=ROOTPA_OK;
     int tag=0;
     mcVersionInfo_t version;
@@ -177,6 +177,7 @@
             }
         }
     }
+    LOGD("<<Java_com_gd_mobicore_pa_jni_CommonPAWrapper_getVersion %x %x %x\n", productId, keys, values);    
     return ret;
 }
 
@@ -268,9 +269,27 @@
             {
                 for(int i=0; i<spContainerStructure.nbrOfTlts;i++)
                 {
+                    LOGD("TLT %d/%d %.2x%.2x%.2x%.2x-%.2x%.2x-%.2x%.2x-%.2x%.2x-%.2x%.2x%.2x%.2x%.2x%.2x",i, spContainerStructure.nbrOfTlts, spContainerStructure.tltContainers[i].uuid.value[0],
+                                                                                                             spContainerStructure.tltContainers[i].uuid.value[1],
+                                                                                                             spContainerStructure.tltContainers[i].uuid.value[2],
+                                                                                                             spContainerStructure.tltContainers[i].uuid.value[3],
+                                                                                                             spContainerStructure.tltContainers[i].uuid.value[4],
+                                                                                                             spContainerStructure.tltContainers[i].uuid.value[5],
+                                                                                                             spContainerStructure.tltContainers[i].uuid.value[6],
+                                                                                                             spContainerStructure.tltContainers[i].uuid.value[7],
+                                                                                                             spContainerStructure.tltContainers[i].uuid.value[8],
+                                                                                                             spContainerStructure.tltContainers[i].uuid.value[9],
+                                                                                                             spContainerStructure.tltContainers[i].uuid.value[10],
+                                                                                                             spContainerStructure.tltContainers[i].uuid.value[11],
+                                                                                                             spContainerStructure.tltContainers[i].uuid.value[12],
+                                                                                                             spContainerStructure.tltContainers[i].uuid.value[13],
+                                                                                                             spContainerStructure.tltContainers[i].uuid.value[14],
+                                                                                                             spContainerStructure.tltContainers[i].uuid.value[15]);
+                    
                     ret=jniHelp.setIntToArray(&trustletStates, i, spContainerStructure.tltContainers[i].state);
                     jbyteArray uuid = jniHelp.byteArrayToJByteArray(spContainerStructure.tltContainers[i].uuid.value, UUID_LENGTH);
                     envP->SetObjectArrayElement(uuidArray, i, (jobject) uuid);
+                    envP->DeleteLocalRef(uuid);
                 }
             }
             else
@@ -334,8 +353,8 @@
 
     if( obj_!=NULL && (PROVISIONING_STATE_THREAD_EXITING == state) )
     {
-        LOGD("deleting global reference to obj_");
-        envP->DeleteGlobalRef(obj_);
+        LOGD("deleting global reference to obj_ (envP %ld)", envP);
+        if(envP!=NULL) envP->DeleteGlobalRef(obj_);
         obj_=NULL;
     }
 
@@ -378,6 +397,11 @@
         LOGE("storeCallbackMethodIds trustletInstallCallback_==NULL");
     }        
 
+    if(cls!=NULL)
+    {
+        envP->DeleteLocalRef(cls);
+    }
+    
     LOGD("<<storeCallbackMethodIds\n");
 }
 
@@ -403,7 +427,6 @@
         return;
     }
     
-    
     jobject jpath = envP->CallObjectMethod(obj, getFilesDirPath); 
     if(jpath!=NULL)
     {    
@@ -423,6 +446,11 @@
         setPaths(HARDCODED_STORAGEPATH, CERT_PATH);        
     }    
 
+    if(cls!=NULL)
+    {
+        envP->DeleteLocalRef(cls);
+    }    
+    
     LOGD("<<setFilesPath\n");
 }
 
@@ -487,8 +515,16 @@
             copyElement(envP, &osSpecificInfoP->hardwareP, hw);
             copyElement(envP, &osSpecificInfoP->modelP, model);
             copyElement(envP, &osSpecificInfoP->versionP, version);
-                        
-        }
+
+            envP->DeleteLocalRef(systemInfo);
+            if(imeiEsn!=NULL) envP->DeleteLocalRef(imeiEsn);
+            if(mno!=NULL) envP->DeleteLocalRef(mno);
+            if(brand!=NULL) envP->DeleteLocalRef(brand);
+            if(manufacturer!=NULL) envP->DeleteLocalRef(manufacturer);
+            if(hw!=NULL) envP->DeleteLocalRef(hw);
+            if(model!=NULL) envP->DeleteLocalRef(model);
+            if(version!=NULL) envP->DeleteLocalRef(version);        
+        }        
     }
 
     // doing this in every round in order to make sure what is attached will be detached and that 
@@ -673,3 +709,37 @@
     delete[] envValP;
     LOGD("<<Java_com_gd_mobicore_pa_jni_CommonPAWrapper_setEnvironmentVariable");
 }
+
+JNIEXPORT jint JNICALL Java_com_gd_mobicore_pa_jni_CommonPAWrapper_storeTA(JNIEnv* envP, jobject obj, jint spid, jbyteArray uuid, jbyteArray taBin)
+{
+    LOGD(">>Java_com_gd_mobicore_pa_jni_CommonPAWrapper_storeTA");
+    int ret=ROOTPA_OK;
+    JniHelpers jniHelp(envP);
+
+    uint32_t uuidLength=0;
+    uint8_t* uuidP=(uint8_t*) jniHelp.jByteArrayToCByteArray(uuid, &uuidLength);
+    
+    if(UUID_LENGTH != uuidLength){
+        LOGD("<<Java_com_gd_mobicore_pa_jni_CommonPAWrapper_storeTA, wrong uuidLength %d, not installing\n", uuidLength);
+        free(uuidP);
+        return ROOTPA_ERROR_ILLEGAL_ARGUMENT;
+    }
+    mcUuid_t mcUuid;
+    memcpy(mcUuid.value, uuidP, UUID_LENGTH);
+    free(uuidP);    
+    
+    uint32_t taBinLength=0;
+    uint8_t* taBinP=(uint8_t*) jniHelp.jByteArrayToCByteArray(taBin, &taBinLength);
+    if(0==taBinLength){
+        LOGD("<<Java_com_gd_mobicore_pa_jni_CommonPAWrapper_storeTA, no taBin\n", taBinLength);
+        free(taBinP);
+        return ROOTPA_ERROR_ILLEGAL_ARGUMENT;
+    }
+
+    ret=storeTA((mcSpid_t)spid, &mcUuid, taBinP, taBinLength);
+    free(taBinP);
+
+    LOGD("<<Java_com_gd_mobicore_pa_jni_CommonPAWrapper_storeTA %d", ret);
+    return ret;
+}
+
diff --git a/rootpa/Code/Android/app/res/values/version.xml b/rootpa/Code/Android/app/res/values/version.xml
old mode 100644
new mode 100755
index d91fbcb..054297f
--- a/rootpa/Code/Android/app/res/values/version.xml
+++ b/rootpa/Code/Android/app/res/values/version.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
 <resources>
-    <string name="name">2.0025 (37085)</string>
-    <integer name="code">0x20019</integer>
+    <string name="name">2.0071 (47817)</string>
+    <integer name="code">0x20047</integer>
 </resources>
diff --git a/rootpa/Code/Android/app/src/com/gd/mobicore/pa/jni/CommonPAWrapper.java b/rootpa/Code/Android/app/src/com/gd/mobicore/pa/jni/CommonPAWrapper.java
index 3f7e7aa..febaac9 100755
--- a/rootpa/Code/Android/app/src/com/gd/mobicore/pa/jni/CommonPAWrapper.java
+++ b/rootpa/Code/Android/app/src/com/gd/mobicore/pa/jni/CommonPAWrapper.java
@@ -77,6 +77,7 @@
                                       int flags, 
                                       byte[] seAddress);
     public native int unregisterRootContainer(byte[] seAddress);
+    public native int storeTA(int spid, byte[] uuid, byte[] taBinary);
     public native void setEnvironmentVariable(byte[] variable, byte[] value);    
 
     static{
@@ -114,9 +115,10 @@
         Log.d(TAG,">>CommonPAWrapper.getSystemInfo");
         String[] response= new String[RESPONSE_ARRAY_SIZE];
         TelephonyManager telephonyManager = (TelephonyManager)service_.getSystemService(Context.TELEPHONY_SERVICE);
-
-        response[IMEI_ESN_INDEX]=telephonyManager.getDeviceId();
-        response[MNO_INDEX]=telephonyManager.getSimOperatorName();
+        if(telephonyManager!=null){
+            response[IMEI_ESN_INDEX]=telephonyManager.getDeviceId();
+            response[MNO_INDEX]=telephonyManager.getSimOperatorName();
+        }
         response[BRAND_INDEX]=Build.BRAND;
         response[MANUFACTURER_INDEX]=Build.MANUFACTURER;
         response[HARDWARE_INDEX]=Build.HARDWARE;
diff --git a/rootpa/Code/Android/app/src/com/gd/mobicore/pa/service/DeveloperService.java b/rootpa/Code/Android/app/src/com/gd/mobicore/pa/service/DeveloperService.java
index 2f22828..718734f 100755
--- a/rootpa/Code/Android/app/src/com/gd/mobicore/pa/service/DeveloperService.java
+++ b/rootpa/Code/Android/app/src/com/gd/mobicore/pa/service/DeveloperService.java
@@ -44,6 +44,7 @@
 import com.gd.mobicore.pa.ifc.CommandResult;
 import com.gd.mobicore.pa.ifc.BooleanResult;
 import com.gd.mobicore.pa.ifc.TrustletContainer;
+import com.gd.mobicore.pa.ifc.IfcVersion;
 
 public class DeveloperService extends BaseService {
 
@@ -204,7 +205,7 @@
         }catch(Exception e){
             Log.i(TAG,"DeveloperService something wrong in the given logging level "+e );
         }
-        Log.i(TAG,"DeveloperService binding");
+        Log.i(TAG,"DeveloperService binding, IfcVersion: " +IfcVersion.ROOTPA_ANDROID_API_VERSION_MAJOR+"."+IfcVersion.ROOTPA_ANDROID_API_VERSION_MINOR);
         if(se_!=null) Log.d(TAG,new String(se_));
         return mBinder;
 
diff --git a/rootpa/Code/Android/app/src/com/gd/mobicore/pa/service/OemService.java b/rootpa/Code/Android/app/src/com/gd/mobicore/pa/service/OemService.java
index 04021ff..70ec091 100755
--- a/rootpa/Code/Android/app/src/com/gd/mobicore/pa/service/OemService.java
+++ b/rootpa/Code/Android/app/src/com/gd/mobicore/pa/service/OemService.java
@@ -45,6 +45,7 @@
 import com.gd.mobicore.pa.ifc.CommandResult;
 import com.gd.mobicore.pa.ifc.BooleanResult;
 import com.gd.mobicore.pa.ifc.TrustletContainer;
+import com.gd.mobicore.pa.ifc.IfcVersion;
 
 public class OemService extends BaseService {
     private static final String TAG = "RootPA-J";
@@ -73,7 +74,6 @@
             doProvisioningLockSuid_=tmpSuid;
             Log.d(TAG,"RootPAServiceIfc.Stub.unregisterRootContainer calling JNI");
             
-            boolean[] isRegistered = new boolean[1];
             int ret=CommandResult.ROOTPA_OK;
 
             try{
@@ -128,7 +128,7 @@
         }catch(Exception e){
             Log.i(TAG,"OemService something wrong in the given logging level "+e );
         }
-        Log.i(TAG,"OemService binding");
+        Log.i(TAG,"OemService binding, IfcVersion: " +IfcVersion.ROOTPA_ANDROID_API_VERSION_MAJOR+"."+IfcVersion.ROOTPA_ANDROID_API_VERSION_MINOR);
         if(se_!=null) Log.d(TAG,new String(se_));
         return mBinder;
     }
diff --git a/rootpa/Code/Android/app/src/com/gd/mobicore/pa/service/ProvisioningService.java b/rootpa/Code/Android/app/src/com/gd/mobicore/pa/service/ProvisioningService.java
index c29f8c1..0fa9cca 100755
--- a/rootpa/Code/Android/app/src/com/gd/mobicore/pa/service/ProvisioningService.java
+++ b/rootpa/Code/Android/app/src/com/gd/mobicore/pa/service/ProvisioningService.java
@@ -40,6 +40,7 @@
 import java.util.ArrayList;
 import java.util.UUID;
 import java.util.Random;
+import java.math.BigInteger;
 
 import com.gd.mobicore.pa.jni.CommonPAWrapper;
 
@@ -57,11 +58,13 @@
 import com.gd.mobicore.pa.ifc.SPContainerState;
 import com.gd.mobicore.pa.ifc.TrustletContainer;
 import com.gd.mobicore.pa.ifc.TrustletContainerState;
+import com.gd.mobicore.pa.ifc.IfcVersion;
 
 public class ProvisioningService extends BaseService {
 //    protected static final String TAG = "RootPA-J";
 
     private static final int PROVISIONING_UID_FOR_LOCK=0x11110000;
+    private static final int LONG_SIZE=8;
     private final RootPAServiceIfc.Stub mBinder = new ServiceIfc();   
     
     // using this instead of anonymous inner class in order to allow call to some of the private methods we define here   
@@ -267,6 +270,11 @@
             Log.d(TAG,">>RootPAServiceIfc.Stub.doProvisioning"); 
             int ret=CommandResult.ROOTPA_OK;
 
+            if(spid==null){  // having null out variable leads to null pointer exception in the client, however we still want to do checking so that there is not unncessary execution of the following code
+                Log.d(TAG,"RootPAServiceIfc.Stub.doProvisioning spid==null");
+                return new CommandResult(CommandResult.ROOTPA_ERROR_ILLEGAL_ARGUMENT);
+            }            
+            
             // we do not use uid here since we do not want to let the client to released the lock, it is done 
             // internally at CommonPAWrapper.java when sending Intents. 
             
@@ -338,29 +346,21 @@
                 }
                 
                 for(int i=0; i<ints[NUMBER_OF_TLTS_IDX]; i++){
-                    long mostSignificant = uuidArray[i][7];
-                    mostSignificant+= uuidArray[i][6]<<8;
-                    mostSignificant+= uuidArray[i][5]<<16;
-                    mostSignificant+= uuidArray[i][4]<<24;
-                    mostSignificant+= (long)uuidArray[i][3]<<32;
-                    mostSignificant+= (long)uuidArray[i][2]<<40;
-                    mostSignificant+= (long)uuidArray[i][1]<<48;
-                    mostSignificant+= (long)uuidArray[i][0]<<56;
+                    byte[] msBytes=new byte[LONG_SIZE]; 
+                    System.arraycopy(uuidArray[i], 0, msBytes, 0, LONG_SIZE);
+                    BigInteger mostSignificant=new BigInteger(msBytes);
 
-                    long leastSignificant = uuidArray[i][15];
-                    leastSignificant+= uuidArray[i][14]<<8;
-                    leastSignificant+= uuidArray[i][13]<<16;
-                    leastSignificant+= uuidArray[i][12]<<24;
-                    leastSignificant+= (long)uuidArray[i][11]<<32;
-                    leastSignificant+= (long)uuidArray[i][10]<<40;
-                    leastSignificant+= (long)uuidArray[i][9]<<48;
-                    leastSignificant+= (long)uuidArray[i][8]<<56;
+                    byte[] lsBytes=new byte[LONG_SIZE];
+                    System.arraycopy(uuidArray[i], LONG_SIZE, lsBytes, 0, LONG_SIZE);
+                    BigInteger leastSignificant=new BigInteger(lsBytes);
+
+                    Log.d(TAG,"UUID: ls ms"+leastSignificant+" "+mostSignificant);
                     
                     TrustletContainerState ts=mapTltContainerState(trustletStates[i]);
                     if (ts == TrustletContainerState.UNDEFINED){
                         ret=CommandResult.ROOTPA_ERROR_INTERNAL;                
                     }
-                    cs.add(new TrustletContainer(new UUID(mostSignificant, leastSignificant), ts));
+                    cs.add(new TrustletContainer(new UUID(mostSignificant.longValue(), leastSignificant.longValue()), ts));
                 }
                 
             }else if (ret==CommandResult.ROOTPA_ERROR_INTERNAL_NO_CONTAINER){
@@ -381,7 +381,7 @@
             return new CommandResult(ret);            
         }
 
-
+                
         public CommandResult getSPContainerState(SPID spid, SPContainerStateParcel state){
             Log.d(TAG,">>RootPAServiceIfc.Stub.getSPContainerState"); 
 
@@ -432,6 +432,24 @@
             return new CommandResult(ret);
         }
 
+        public CommandResult storeTA(SPID spid, byte[] uuid, byte[] taBinary){
+            Log.d(TAG,">>RootPAServiceIfc.Stub.storeTA");
+            if(spid==null||uuid==null||taBinary==null|| taBinary.length == 0 || spid.spid()==0){ // having null out variable leads to null pointer exception in the client, however we still want to do checking so that there is not unncessary execution of the following code
+                return new CommandResult(CommandResult.ROOTPA_ERROR_ILLEGAL_ARGUMENT);
+            }
+            
+            int ret=CommandResult.ROOTPA_OK;
+            try{
+                ret=commonPAWrapper().storeTA(spid.spid(), uuid, taBinary);
+            }catch(Exception e){
+                Log.e(TAG,"CommonPAWrapper().storeTA exception: ", e);
+                ret=CommandResult.ROOTPA_ERROR_INTERNAL;
+            }
+            
+            Log.d(TAG,"<<RootPAServiceIfc.Stub.storeTA");
+            return new CommandResult(ret);            
+        }        
+
         private final static int  MC_CONT_STATE_UNREGISTERED=0;
         private final static int  MC_CONT_STATE_REGISTERED=1;
         private final static int  MC_CONT_STATE_ACTIVATED=2;
@@ -519,7 +537,7 @@
         }catch(Exception e){
             Log.i(TAG,"ProvisioningService something wrong in the given logging level "+e );
         }
-        Log.i(TAG,"ProvisioningService binding");
+        Log.i(TAG,"ProvisioningService binding, IfcVersion: " +IfcVersion.ROOTPA_ANDROID_API_VERSION_MAJOR+"."+IfcVersion.ROOTPA_ANDROID_API_VERSION_MINOR);
         if(se_!=null) Log.d(TAG,new String(se_));
         return mBinder;
     }
diff --git a/rootpa/Code/Android/lib/Android.mk b/rootpa/Code/Android/lib/Android.mk
index dd7c260..4ad940b 100755
--- a/rootpa/Code/Android/lib/Android.mk
+++ b/rootpa/Code/Android/lib/Android.mk
@@ -12,6 +12,6 @@
 
 
 LOCAL_MODULE := rootpa_interface
-LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_TAGS := debug eng optional
 
 include $(BUILD_STATIC_JAVA_LIBRARY)
\ No newline at end of file
diff --git a/rootpa/Code/Android/lib/src/com/gd/mobicore/pa/ifc/CommandResult.java b/rootpa/Code/Android/lib/src/com/gd/mobicore/pa/ifc/CommandResult.java
index 4ba0237..34d4e8e 100755
--- a/rootpa/Code/Android/lib/src/com/gd/mobicore/pa/ifc/CommandResult.java
+++ b/rootpa/Code/Android/lib/src/com/gd/mobicore/pa/ifc/CommandResult.java
@@ -28,6 +28,7 @@
 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 
 OF THE POSSIBILITY OF SUCH DAMAGE.
 */
+
 package com.gd.mobicore.pa.ifc;
 
 import android.os.Parcel;
@@ -43,79 +44,88 @@
     */
 
     /**
-    no errors detected, successful execution  
+    No errors detected, successful execution  
     */
     public static final int ROOTPA_OK=0x00000000;
 
     /**
-    client has requested unsupported command or command that it can not execute via the used interface
+    Client has requested unsupported CMP command or command that it can not execute via the used interface.
+    Possible steps to recover: send only supported CMP commands or update to RootPA that supports handling the particular command in the used interface.
     */
     public static final int ROOTPA_COMMAND_NOT_SUPPORTED=0x00000001;
 
     /** 
-    either rootpa is locked by another client, or the client requests lock or unlock when it is not allowed to do that 
+    Either rootpa is locked by another client, or the client requests lock or unlock when it is not allowed to do that.
+    Possible steps to recover: wait until the lock is released
     */
     public static final int ROOTPA_ERROR_LOCK=0x00000002;
 
-
     /**
-    error in one of the cmp commands, see command specific response for more details
+    Error in one of the CMP commands, see command specific response for more details.
     */
     public static final int ROOTPA_ERROR_COMMAND_EXECUTION=0x00000003;
 
     /** 
-    mobicore registry returned an error 
+    Registry returned an error when trying to write a container.  mcDaemon could be dead or something seriously wrong in the file system.
+    Possible steps to recover: rebooting the device may help
     */
     public static final int ROOTPA_ERROR_REGISTRY=0x00000004;
 
     /**
-     error in communicating with mobicore 
+    Error in communicating with t-base secure side. This is returned when any of the mcDeamon API calls related to communication with secure side fails.
+    Possible steps to recover: rebooting the device may help
     */
     public static final int ROOTPA_ERROR_MOBICORE_CONNECTION=0x00000005;
 
     /** 
-    either NWd or SWd software is out of memory 
+    Either Nwd or Swd software is out of memory.
+    Possible steps to recover: release memory
     */
     public static final int ROOTPA_ERROR_OUT_OF_MEMORY=0x00000006;
 
     /** 
-    rootpa internal error 
+    Rootpa internal error. This error is returned in various situations when something unexpected went wrong e.g. message from CMTL can‘t be interpreted, SE returned an error indicating invalid data, bad request or similar or base64 decoding failed
+    Possible steps to recover: rebooting or updating the device may help
     */
     public static final int ROOTPA_ERROR_INTERNAL=0x00000007;
 
     /** 
-    given argument is not allowed (in many cases it is NULL) or e.g. the format oif xml is unsupported
+    Given argument is not allowed (in many cases it is NULL) or e.g. the format of xml is unsupported.
+    Possible steps to recover: give correct argument
     */
     public static final int ROOTPA_ERROR_ILLEGAL_ARGUMENT=0x00000008;
 
     /** 
-    error in network connection or use of networking library 
+    Error in network connection or use of networking library.
+    Possible steps to recover: create working network connection (avoid firewalls and proxies that require password)
     */
     public static final int ROOTPA_ERROR_NETWORK=0x00000009;
 
     /** 
-    error is parsing received XML command or creating new XML response
+    Error returned by XML library. Problems in parsing received XML command or creating new XML response.
     */
     public static final int ROOTPA_ERROR_XML=0x0000000A;
 
     /** 
-    mobicore registry error, requested object does not exists (or cannot be read for some other reason)
+    Registry returned an error when trying to read a container. Most likely the container does not exist.
     */
     public static final int ROOTPA_ERROR_REGISTRY_OBJECT_NOT_AVAILABLE=0x0000000B;
 
     /** 
-    CMP version of the device is not supported by SE
+    CMP version of the device is not supported by SE.
+    Possible steps to recover: use CMP version supported by SE (>=3.0)
     */
     public static final int ROOTPA_ERROR_SE_CMP_VERSION=0x0000000C;
 
     /** 
-    Precoditions for SP container installation are not met in SE
+    Precoditions for SP container installation are not met in SE. 
+    Possible steps to recover: register used SPID to SE
     */
     public static final int ROOTPA_ERROR_SE_PRECONDITION_NOT_MET=0x0000000D;
 
     /** 
-    requested container does not exist. This is not always considered an error 
-    but is used as an informative return code
+    Requested SP container does not exist. This is not always considered an error but is used as an informative return code. As this is internal return code, user of RootPA services should never see this.
+    Possible steps to recover: add SP container or request container with different SPID
     */
     public static final int ROOTPA_ERROR_INTERNAL_NO_CONTAINER=0x00000030;
 
diff --git a/rootpa/Code/Android/lib/src/com/gd/mobicore/pa/ifc/IfcVersion.java b/rootpa/Code/Android/lib/src/com/gd/mobicore/pa/ifc/IfcVersion.java
index dfc706f..1804b22 100755
--- a/rootpa/Code/Android/lib/src/com/gd/mobicore/pa/ifc/IfcVersion.java
+++ b/rootpa/Code/Android/lib/src/com/gd/mobicore/pa/ifc/IfcVersion.java
@@ -32,9 +32,11 @@
 /** @addtogroup ROOTPA
  */
 
-class IfcVersion{
+package com.gd.mobicore.pa.ifc;
 
-    final static int ROOTPA_ANDROID_API_VERSION_MAJOR = 1;
-    final static int ROOTPA_ANDROID_API_VERSION_MINOR=0;
+public class IfcVersion{
+
+    public final static int ROOTPA_ANDROID_API_VERSION_MAJOR = 1;
+    public final static int ROOTPA_ANDROID_API_VERSION_MINOR=1;
 };
 
diff --git a/rootpa/Code/Android/lib/src/com/gd/mobicore/pa/ifc/RootPADeveloperIfc.aidl b/rootpa/Code/Android/lib/src/com/gd/mobicore/pa/ifc/RootPADeveloperIfc.aidl
index e69a760..fd6a955 100755
--- a/rootpa/Code/Android/lib/src/com/gd/mobicore/pa/ifc/RootPADeveloperIfc.aidl
+++ b/rootpa/Code/Android/lib/src/com/gd/mobicore/pa/ifc/RootPADeveloperIfc.aidl
@@ -40,8 +40,8 @@
 
 /**
  * This API contains method(s) that are intended to be used for developer 
- * trustlet installation. Note that this API may be removed in the future when the
- * developer trustlet installation is handled by a service manager and installation of 
+ * TA installation. Note that this API may be removed in the future when the
+ * developer TA installation is handled by a service manager and installation of 
  * all trutlets follow the same architecture for RootPA point of view.
  *
  * The service is started by sending intent com.gd.mobicore.pa.service.DEVELOPER_SERVICE in binding. 
@@ -51,7 +51,7 @@
 interface RootPADeveloperIfc{
 
     /**
-     * This method can be used for installing "developer trustlet" that is not tied to any 
+     * This method can be used for installing "developer TA" that is not tied to any 
      * service provider and/or service manager. It contacts Service Enabler and asks it to 
      * perform the tasks, so the device has to be connected to network in order for this to
      * succeed.   
@@ -59,39 +59,39 @@
      * The service progress is informed with the same Intents as is progress of the 
      * @ref RootPAServiceIfc#doProvisioning, however there is an additional 
      * Intent com.gd.mobicore.pa.service.INSTALL_TRUSTLET for returning the encrypted 
-     * trustlet binary (in case of dynamic installation where trustletBinary is given 
+     * TA binary (in case of dynamic installation where taBinary is given 
      * as a parameter).
      *
      * There are constants related to the intents in @ref RootPAProvisioningIntents
      *
      * @param spid service provider id
-     * @param uuid uuid of the trustlet in hex, without dashes. Needs to be correct length.
-     * @param trustletBinary trustlet binary to be encrypted with and returned back. 
+     * @param uuid uuid of the TA in hex, without dashes. Needs to be correct length.
+     * @param taBinary TA binary to be encrypted with and returned back. 
      *        If the binary is already encrypted, this array must be empty. The binary 
-     *        has to be encrypted for transfer. Note that only either trustletBinary 
+     *        has to be encrypted for transfer. Note that only either taBinary 
      *        or key can be given. There are sperate instructions on how the binary is to 
-     *        be encrypted and packaged. Key and trustletBinary are exclusive, only one of 
+     *        be encrypted and packaged. Key and taBinary are exclusive, only one of 
      *        them can be given. This methods uses default values for memoryType (2), 
-     *        numberOfInstances (1) and flags (0) when trustlet binary is installed.
-     * @param key a key that has been used to encrypt the trustlet binary in case when 
-     *        the trustlet binary is not given as a parameter. This key has to be 
+     *        numberOfInstances (1) and flags (0) when TA binary is installed.
+     * @param key a key that has been used to encrypt the TA binary in case when 
+     *        the TA binary is not given as a parameter. This key has to be 
      *        encrypted for transfer. There are sperate instructions on how the key is to 
-     *        be encrypted and packaged. Key and trustletBinary are exclusive, only one of 
+     *        be encrypted and packaged. Key and taBinary are exclusive, only one of 
      *        them can be given.
-     * @param minTltVersion minimum version of the trustlet
+     * @param minTltVersion minimum version of the TA
      * @param tltPukHash this field is not used at the moment, null is fine here.
      *
      * @return indication of successful start of provisioning thread (ROOTPA_OK) or an error code
      */
     CommandResult installTrustletOrKey(in int spid, 
                                        in byte[] uuid, 
-                                       in byte[] trustletBinary, 
+                                       in byte[] taBinary, 
                                        in byte[] key,                                   
                                        in int minTltVersion, 
                                        in byte[] tltPukHash);
     
     /**
-     * This method can be used for installing "developer trustlet" that is not tied to any 
+     * This method can be used for installing "developer TA" that is not tied to any 
      * service provider and/or service manager. It contacts Service Enabler and asks it to 
      * perform the tasks, so the device has to be connected to network in order for this to
      * succeed.
@@ -99,30 +99,30 @@
      * The service progress is informed with the same Intents as is progress of the 
      * @ref RootPAServiceIfc#doProvisioning, however there is an additional 
      * Intent com.gd.mobicore.pa.service.INSTALL_TRUSTLET for returning the encrypted 
-     * trustlet binary.
+     * TA binary.
      *
      * There are constants related to the intents in @ref RootPAProvisioningIntents
      *
      * @param spid service provider id
-     * @param uuid uuid of the trustlet in hex, without dashes. Needs to be correct length.
-     * @param trustletBinary trustlet binary to be encrypted with and returned back. 
+     * @param uuid uuid of the TA in hex, without dashes. Needs to be correct length.
+     * @param taBinary TA binary to be encrypted with and returned back. 
      *        If the binary is already encrypted, this array must be empty. The binary 
-     *        has to be encrypted for transfer. Note that only either trustletBinary 
+     *        has to be encrypted for transfer. Note that only either taBinary 
      *        or key can be given. There are sperate instructions on how the binary is to 
      *        be encrypted and packaged.
-     * @param minTltVersion minimum version of the trustlet
+     * @param minTltVersion minimum version of the TA
      * @param tltPukHash this field is not used at the moment, null is fine here.
-     * @param memoryType memory where the trustlet is to be loaded and executed: 0 - if enough space is available, 
-              load the Trustlet into the internal memory, otherwise into the external memory, 1 - internal memory, 
+     * @param memoryType memory where the TA is to be loaded and executed: 0 - if enough space is available, 
+              load the TA into the internal memory, otherwise into the external memory, 1 - internal memory, 
               2 - external memory
-     * @param numberOfInstances indicates how many instances of a trustlet can be installed (run) in parallel
+     * @param numberOfInstances indicates how many instances of a TA can be installed (run) in parallel
      * @param flags current flags are: 1 - permanent, 2 - service has no WSW control interface,  4 - debuggable
      *
      * @return indication of successful start of provisioning thread (ROOTPA_OK) or an error code
      */
     CommandResult installTrustlet(in int spid, 
                                   in byte[] uuid, 
-                                  in byte[] trustletBinary, 
+                                  in byte[] taBinary, 
                                   in int minTltVersion, 
                                   in byte[] tltPukHash, 
                                   in int memoryType, 
diff --git a/rootpa/Code/Android/lib/src/com/gd/mobicore/pa/ifc/RootPAServiceIfc.aidl b/rootpa/Code/Android/lib/src/com/gd/mobicore/pa/ifc/RootPAServiceIfc.aidl
index fe575d6..9db4557 100755
--- a/rootpa/Code/Android/lib/src/com/gd/mobicore/pa/ifc/RootPAServiceIfc.aidl
+++ b/rootpa/Code/Android/lib/src/com/gd/mobicore/pa/ifc/RootPAServiceIfc.aidl
@@ -46,9 +46,9 @@
 import com.gd.mobicore.pa.ifc.SPContainerStateParcel;
 
 /** 
-* RootPAServiceIfc is intended for SP.PA use at the time of installing new trustlet. It provides means
-* to communicate with content management trustlet (using CMP version 3), request SE to perform provisioning
-* of root container and trustlet container and means to obtain some information on the MobiCore and its registry.
+* RootPAServiceIfc is intended for SP.PA use at the time of installing new TA. It provides means
+* to communicate with content management TA (using CMP version 3), request SE to perform provisioning
+* of root container and TA container and means to obtain some information on the MobiCore and its registry.
 *
 * The service is started by sending intent com.gd.mobicore.pa.service.PROVISIONING_SERVICE in binding.
 */
@@ -133,14 +133,16 @@
      CommandResult executeCmpCommands(int uid, in List<CmpCommand> commands, out List<CmpResponse> responses);
 
     /**
-     * Starts provisioning; creates Root Container and SP Container if not already available.
+     * Starts provisioning. What actually happens after calling this depends on the state of the system and the commands SE sends.
+     * In normal situation, SE sends commands to create root container and SP container (indicated by spid) if they do not already 
+     * exist. If given spid is 0, only root container is created (if it does not already exist).
      * Tasks are performed asynchronously. Method returns immediately.
      * Intents are broadcast to indicate the progress of the provisioning. The result is also
      * sent via broadcast.
      *
      * Cannot be executed if the acquireLock is called. Release any lock before calling this 
      * method. Also, this command acquires lock internally before executing and releases lock 
-     * when error occurs or provisioning is finished.
+     * when error occurs or provisioning is finished (just before sending FINISHED_ROOT_PROVISIONING intent) or after 1 minute timeout.
      *
      * The following intents are broadcast after calling doProvisioning:
      * <ul>
@@ -178,7 +180,7 @@
      * acquired while this method runs.
      *
      * @param spid provides [in] the id of the SP (SPCont)
-     * @param cs [out] state of the sp container and a list of installed trustlet containers for the given SP
+     * @param cs [out] state of the sp container and a list of installed TA containers for the given SP
      * @return indication of successful completion
      */
     CommandResult getSPContainerStructure(in SPID spid, out SPContainerStructure cs);
@@ -194,6 +196,16 @@
      */
     CommandResult getSPContainerState(in SPID spid, out SPContainerStateParcel state);
 
+
+    /**
+     * Stores the actual TA binary to registry.
+     *
+     * @param spid [in] service provider id
+     * @param uuid [in] unique UUID of the TA
+     * @param taBinary [in] the actual TA to be stored
+     * @return indication of successful completion
+     */
+    CommandResult storeTA(in SPID spid, in byte[] uuid, in byte[] taBinary);
 }
 
 /**@}*/
diff --git a/rootpa/Code/Android/lib/src/com/gd/mobicore/pa/ifc/SUID.java b/rootpa/Code/Android/lib/src/com/gd/mobicore/pa/ifc/SUID.java
index e23754c..8f872a1 100755
--- a/rootpa/Code/Android/lib/src/com/gd/mobicore/pa/ifc/SUID.java
+++ b/rootpa/Code/Android/lib/src/com/gd/mobicore/pa/ifc/SUID.java
@@ -77,8 +77,10 @@
     }

 

     public void readFromParcel(Parcel in) {

-        this.suid_ = new byte[SUID_LENGTH];

-        in.readByteArray(suid_);

+        if(in.dataAvail()>=SUID_LENGTH){

+            this.suid_ = new byte[SUID_LENGTH];

+            in.readByteArray(suid_);

+        }

     }

 

     @Override

@@ -89,8 +91,7 @@
     @Override

     public void writeToParcel(Parcel out, int flags) {

         if(suid_!=null){

-            out.writeByteArray(suid());

+            out.writeByteArray(suid_);

         }

     }

-

 }

diff --git a/rootpa/Code/Common/commandhandler.c b/rootpa/Code/Common/commandhandler.c
index a80ad7b..2df4b94 100755
--- a/rootpa/Code/Common/commandhandler.c
+++ b/rootpa/Code/Common/commandhandler.c
@@ -51,7 +51,6 @@
 /*
 See provisioningagent.h for description of this function.
 */
-
 rootpaerror_t executeCmpCommands(int numberOfCommands, CmpMessage* commandsP, CmpMessage* responsesP, uint32_t* internalError)
 {    
     LOGD(">>executeCmpCommands");
@@ -319,6 +318,38 @@
     return ret;
 }
 
+rootpaerror_t storeTA(mcSpid_t spid, const mcUuid_t* uuidP, const uint8_t* taBinP,  uint32_t taBinLength)
+{
+    rootpaerror_t ret=ROOTPA_OK;
+    mcResult_t result=0;
+    mcContainerState_t state;
+    
+    result=regGetTaState(spid, uuidP, &state);
+    LOGD("storeTA, TA state %d, result 0x%x", state, result);
+    if(MC_DRV_ERR_INVALID_DEVICE_FILE == result)
+    {
+        LOGW("storeTA, not storing, since TA container is missing");
+        ret=ROOTPA_ERROR_ILLEGAL_ARGUMENT;
+    }
+    else if (result!=MC_DRV_OK)
+    {
+        LOGW("storeTA, not storing, due to TA container read error 0x%x", result);
+        ret=ROOTPA_ERROR_REGISTRY;
+    }
+    else
+    {       
+        result =regStoreTA(spid, uuidP, taBinP, taBinLength);
+        
+        if(result != MC_DRV_OK)
+        {
+            LOGE("storeTA, storing TA failed, result from registry 0x%x", result);
+            ret=ROOTPA_ERROR_REGISTRY;
+        }        
+    }
+
+    return ret;
+}
+
 void dummyCallback(ProvisioningState state, rootpaerror_t error, tltInfo_t* tltInfoP)
 {
     LOGD("dummy callback %d %d %ld", state, error, (long int) tltInfoP);
@@ -370,7 +401,7 @@
         free((char*)((provisioningparams_t*)paramsP)->tltInstallationDataP->tltPukHashP);
         free(((provisioningparams_t*)paramsP)->tltInstallationDataP);
     }
-    free(paramsP);
+    free(paramsP);  // Coverity complains that paramsP allocated in "provisioning" is not freed. It is done here.
 
     LOGD("<<provisioningThreadFunction");
     pthread_exit(NULL);
@@ -394,6 +425,7 @@
     paramsP->spid=spid;
     if(tltDataP)
     {
+        // Coverity complains that paramsP allocated here is not freed. It is done in "provisioningThreadFunction"
         paramsP->tltInstallationDataP=malloc(sizeof(trustletInstallationData_t));
         if(!paramsP->tltInstallationDataP)
         {
@@ -463,6 +495,7 @@
             if(r)
             {
                 LOGE("unable to create thread %d",r);
+                free(paramsP);
                 ret=ROOTPA_ERROR_INTERNAL;
             }
             pthread_attr_destroy(&attributes);
diff --git a/rootpa/Code/Common/enrollmentservicexmlschema.h b/rootpa/Code/Common/enrollmentservicexmlschema.h
index 4e62c32..943f8ed 100755
--- a/rootpa/Code/Common/enrollmentservicexmlschema.h
+++ b/rootpa/Code/Common/enrollmentservicexmlschema.h
@@ -176,7 +176,7 @@
 		<xsd:sequence> \
 			<xsd:choice> \
 				<xsd:element name=\"trustletAxf\" type=\"mces:TrustletAXF\" /> \
-				<xsd:element name=\"tltEncryptionKey\" type=\"mces:TrustletEncryptionKey\" /> \
+				<xsd:element name=\"trustletEncryptionKey\" type=\"mces:TrustletEncryptionKey\" /> \
 			</xsd:choice> \
 		</xsd:sequence> \
 	</xsd:complexType> \
diff --git a/rootpa/Code/Common/include/provisioningagent.h b/rootpa/Code/Common/include/provisioningagent.h
index fb3b19d..7675f09 100755
--- a/rootpa/Code/Common/include/provisioningagent.h
+++ b/rootpa/Code/Common/include/provisioningagent.h
@@ -212,6 +212,19 @@
 */
 rootpaerror_t unregisterRootContainer(CallbackFunctionP callbackP, SystemInfoCallbackFunctionP systemInfoCallbackP);
 
+
+/**
+Store's the GP TA binary to the registry. The corresponding TA container has to exists and contain correct information for decrypting the TA.
+
+@param spid service provider ID
+@param uuidP pointer to the UUID of the TA binary. This is the UUID that all t-base TA's have, NOT the UUID specific to GP TA's
+@param taBinP pointer to the actual TA binary
+@param taBinLength size of the actual TA binary
+
+@return ROOTPA_OK is unregistering root container succeeds, an error code otherwise
+*/
+rootpaerror_t storeTA(mcSpid_t spid, const mcUuid_t* uuidP, const uint8_t* taBinP, uint32_t taBinLength);
+
 /**
 This is helper function for the platform dependent part to inform the platform independent part 
 on the file storage location
diff --git a/rootpa/Code/Common/include/rootpaErrors.h b/rootpa/Code/Common/include/rootpaErrors.h
index 1e1f937..7d98755 100755
--- a/rootpa/Code/Common/include/rootpaErrors.h
+++ b/rootpa/Code/Common/include/rootpaErrors.h
@@ -42,89 +42,99 @@
 
 
 /**
- no errors detected, successful execution  
+ No errors detected, successful execution.
 */
 #define ROOTPA_OK                               0x00000000
 
 /**
- client has requested unsupported command or command that it can not execute via the used interface
+ Client has requested unsupported CMP command or command that it can not execute via the used interface.
+ Possible steps to recover: send only supported CMP commands or update to RootPA that supports handling the particular command in the used interface.
 */
 #define ROOTPA_COMMAND_NOT_SUPPORTED            0x00000001
 #define STRING_ROOTPA_COMMAND_NOT_SUPPORTED    "COMMAND_NOT_SUPPORTED_ERROR"
 
 /** 
-either rootpa is locked by another client, or the client requests lock or unlock when it is not allowed to do that 
+Either rootpa is locked by another client, or the client requests lock or unlock when it is not allowed to do that.
+Possible steps to recover: wait until the lock is released
 */
 #define ROOTPA_ERROR_LOCK                       0x00000002
 #define STRING_ROOTPA_ERROR_LOCK                "BUSY_ERROR"
 
 /**
- error in one of the cmp commands, see command specific response for more details
-*/
+ Error in one of the CMP commands, see command specific response for more details.
+ */
 #define ROOTPA_ERROR_COMMAND_EXECUTION          0x00000003
 #define STRING_ROOTPA_ERROR_COMMAND_EXECUTION   "COMMAND_EXECUTION_ERROR"
 
 /** 
-mobicore registry returned an error 
+Registry returned an error when trying to write a container.  mcDaemon could be dead or something seriously wrong in the file system.
+Possible steps to recover: rebooting the device may help
 */
 #define ROOTPA_ERROR_REGISTRY                   0x00000004 
 #define STRING_ROOTPA_ERROR_REGISTRY            "REGISTRY_ERROR"
 
 /**
-error in communicating with mobicore 
+Error in communicating with t-base secure side. This is returned when any of the mcDeamon API calls related to communication with secure side fails.
+Possible steps to recover: rebooting the device may help
 */
 #define ROOTPA_ERROR_MOBICORE_CONNECTION        0x00000005
 #define STRING_ROOTPA_ERROR_MOBICORE_CONNECTION "MOBICORE_CONNECTION_ERROR"
 
 /** 
-out of memory 
+Either Nwd or Swd software is out of memory.
+Possible steps to recover: release memory
 */
 #define ROOTPA_ERROR_OUT_OF_MEMORY              0x00000006
 #define STRING_ROOTPA_ERROR_OUT_OF_MEMORY       "OUT_OF_MEMORY_ERROR"
 
 /** 
-rootpa internal error 
+Rootpa internal error. This error is returned in various situations when something unexpected went wrong e.g. message from CMTL can‘t be interpreted, SE returned an error indicating invalid data, bad request or similar or base64 decoding failed
+Possible steps to recover: rebooting or updating the device may help
 */
 #define ROOTPA_ERROR_INTERNAL                   0x00000007
 #define STRING_ROOTPA_ERROR_INTERNAL            "INTERNAL_ERROR"
 
 /** 
-given argument is not allowed (in many cases it is NULL) or e.g. the format of xml is unsupported
+Given argument is not allowed (in many cases it is NULL) or e.g. the format of xml is unsupported.
+Possible steps to recover: give correct argument
 */
 #define ROOTPA_ERROR_ILLEGAL_ARGUMENT           0x00000008
 
 
 /** 
-error in network connection or use of networking library 
+Error in network connection or use of networking library.
+Possible steps to recover: create working network connection (avoid firewalls and proxies that require password)
 */
 #define ROOTPA_ERROR_NETWORK                    0x00000009
 
 
 /** 
-error is parsing received XML command or creating new XML response
+Error returned by XML library. Problems in parsing received XML command or creating new XML response.
 */
 #define ROOTPA_ERROR_XML                        0x0000000A
 #define STRING_ROOTPA_ERROR_XML                 "XML_ERROR"
 
 /** 
-mobicore registry returned an error 
+Registry returned an error when trying to read a container. Most likely the container does not exist.
 */
 #define ROOTPA_ERROR_REGISTRY_OBJECT_NOT_AVAILABLE          0x0000000B
 #define STRING_ROOTPA_ERROR_REGISTRY_OBJECT_NOT_AVAILABLE   "REGISTRY_OBJECT_NOT_AVAILABLE"
 
 /** 
-CMP version of the device is not supported by SE
+CMP version of the device is not supported by SE.
+Possible steps to recover: use CMP version supported by SE (>=3.0)
 */
 #define ROOTPA_ERROR_SE_CMP_VERSION                0x0000000C
 
 /** 
-Precoditions for SP container installation are not met in SE
+Precoditions for SP container installation are not met in SE. 
+Possible steps to recover: register used SPID to SE
 */
 #define ROOTPA_ERROR_SE_PRECONDITION_NOT_MET        0x0000000D
 
 /** 
-requested container does not exist. This is not always considered an error 
-but is used as an informative return code
+Requested SP container does not exist. This is not always considered an error but is used as an informative return code. As this is internal return code, user of RootPA services should never see this.
+Possible steps to recover: add SP container or request container with different SPID
 */
 #define ROOTPA_ERROR_INTERNAL_NO_CONTAINER      0x00000030
 
diff --git a/rootpa/Code/Common/include/version.h b/rootpa/Code/Common/include/version.h
index b307caa..1485d8f 100755
--- a/rootpa/Code/Common/include/version.h
+++ b/rootpa/Code/Common/include/version.h
@@ -35,6 +35,6 @@
 #define ROOTPA_VERSION_H_
 
 #define ROOTPA_VERSION_MAJOR 2
-#define ROOTPA_VERSION_MINOR 25
+#define ROOTPA_VERSION_MINOR 71
 
 #endif /** ROOTPA_VERSION_H_ */
diff --git a/rootpa/Code/Common/pacmtl.c b/rootpa/Code/Common/pacmtl.c
index 1cbfbcb..7ed0252 100755
--- a/rootpa/Code/Common/pacmtl.c
+++ b/rootpa/Code/Common/pacmtl.c
@@ -89,19 +89,20 @@
         return false;
     }
     wsmP=handle->wsmP;
-    LOGD(">>pacmtl getRspElementInfo %x %x %d %d %d %d", ((cmpResponseHeaderTci_t*)wsmP)->version, 
-                                                         ((cmpResponseHeaderTci_t*)wsmP)->responseId, 
-                                                         ((cmpResponseHeaderTci_t*)wsmP)->len, 
-                                                         *((uint32_t*)(wsmP+12)), 
-                                                         *((uint32_t*)(wsmP+16)),                                                   
-                                                         *((uint32_t*)(wsmP+20)));
+
     if(NULL==elementNbrP || NULL == elementOffsetP || NULL == elementLengthP || NULL == handle->wsmP)
     {
         LOGE("pacmtl getRspElementInfo NULL's in input, not setting the element %ld %ld", (long int) elementNbrP, (long int) elementOffsetP);
         return false;
     }
 
-
+    LOGD(">>pacmtl getRspElementInfo %x %x %d %d %d %d", ((cmpResponseHeaderTci_t*)wsmP)->version, 
+                                                         ((cmpResponseHeaderTci_t*)wsmP)->responseId, 
+                                                         ((cmpResponseHeaderTci_t*)wsmP)->len, 
+                                                         *((uint32_t*)(wsmP+12)), 
+                                                         *((uint32_t*)(wsmP+16)),                                                   
+                                                         *((uint32_t*)(wsmP+20)));
+   
     if(ILLEGAL_ELEMENT==*elementNbrP)
     {
         LOGE("pacmtl getRspElementInfo error in input (illegal element), not getting the element %d", *elementNbrP);
diff --git a/rootpa/Code/Common/provisioningengine.c b/rootpa/Code/Common/provisioningengine.c
index 67d0547..f6fd764 100755
--- a/rootpa/Code/Common/provisioningengine.c
+++ b/rootpa/Code/Common/provisioningengine.c
@@ -43,7 +43,6 @@
 #include "provisioningengine.h"
 
 
-
 static const char* const SE_URL="https://se.cgbe.trustonic.com:8443/service-enabler/enrollment/"; // note that there has to be slash at the end since we are adding suid to it next
 
 
@@ -58,6 +57,7 @@
                                       // have any data to send to SE, this will need to be different in RootPA initiated trustet installation
 static const char* const RELATION_INITIAL_DELETE="initial_delete"; // this will make us to send HTTP DELETE
 
+#define INT_STRING_LENGTH 12 // (32 bit <= 10 decimal numbers) + "/" + trailing zero. 
 #define INITIAL_URL_BUFFER_LENGTH 255
 
 static char initialUrl_[INITIAL_URL_BUFFER_LENGTH];
@@ -96,11 +96,11 @@
 
 void addIntToUri(char* uriP, uint32_t addThis)
 {
-    char intInString[10];
-    memset(intInString, 0, 10);
+    char intInString[INT_STRING_LENGTH];
+    memset(intInString, 0, INT_STRING_LENGTH);
     // using signed integer since this is how SE wants it
-    sprintf(intInString, "/%d", addThis);
-    strcpy((uriP+strlen(uriP)), intInString);
+    snprintf(intInString, INT_STRING_LENGTH, "/%d", addThis);
+    strncpy((uriP+strlen(uriP)), intInString, INT_STRING_LENGTH); // we have earlier made sure there is enough room in uriP, using strncpy here instead strcpy is just to avoid static analysis comments
     LOGD("add int to URI %s %d", uriP, addThis);   
 }
 
@@ -155,11 +155,12 @@
     urlLength=strlen(initialUrl_) + (sizeof(mcSuid_t)*2) + (sizeof(mcSpid_t)*2) + (sizeof(mcUuid_t)*2)+6; //possible slash and end zero and four dashes
     tmpLinkP=malloc(urlLength);
     memset(tmpLinkP,0,urlLength);
-    strcpy(tmpLinkP, initialUrl_);
+    strncpy(tmpLinkP, initialUrl_, urlLength);
     addBytesToUri(tmpLinkP, (uint8_t*) &suid, sizeof(suid), false);
     return tmpLinkP;
 }
 
+
 void doProvisioningWithSe(
     mcSpid_t spid, 
     mcSuid_t suid, 
@@ -185,11 +186,7 @@
     const char* usedRelP=NULL;
     const char* usedCommandP=NULL;
 
-    callbackP_=callbackP;    
-    if(NULL==callbackP)
-    {
-        LOGE("No callbackP, can not respond to caller, this should not happen!");
-    } 
+    callbackP_=callbackP;
 
     if(empty(initialUrl_))
     {
@@ -238,16 +235,16 @@
         }
     }
 
-// recovery from factory reset    
-    if(factoryResetAssumed() && relP != RELATION_INITIAL_DELETE)
+// begin recovery from factory reset 1  
+    if(factoryResetAssumed() && relP != RELATION_INITIAL_DELETE && workToDo == true)
     {
         pendingLinkP=linkP;
         pendingRelP=relP;
         relP=RELATION_INITIAL_DELETE;
         linkP=createBasicLink(suid);
     }
-// recovery from factory reset    
-    
+// end recovery from factory reset 1 
+ 
     while(workToDo)
     {
         LOGD("in loop link: %s\nrel: %s\ncommand: %s\nresponse: %s\n", (linkP==NULL)?"null":linkP, 
@@ -257,10 +254,10 @@
     
         if(NULL==relP)
         {
-// recovery from factory reset                
+// begin recovery from factory reset 2                
             if(pendingLinkP!=NULL && pendingRelP!=NULL)
             {
-                free((char*)linkP);
+                free((void*)linkP);
                 linkP=pendingLinkP;
                 relP=pendingRelP;
                 pendingLinkP=NULL;
@@ -268,7 +265,7 @@
                 workToDo=true;
                 continue;
             }
-// recovery from factory reset                
+// end recovery from factory reset 2
             
             
             callbackP(FINISHED_PROVISIONING, ROOTPA_OK, NULL); // this is the only place where we can be sure 
@@ -282,15 +279,18 @@
         }
         else if(strstr(relP, RELATION_SELF))  // do it again. So we need to restore pointer to previous stuff.
         {
-            cleanup((char**) &linkP, (char**) &relP, (char**) &commandP);
-
-            relP=usedRelP;
-            linkP=usedLinkP;
-            commandP=usedCommandP;
+            if(relP!=usedRelP && linkP!=usedLinkP && commandP!=usedCommandP)
+            {
+                cleanup((char**) &linkP, (char**) &relP, (char**) &commandP);
+                relP=usedRelP;
+                linkP=usedLinkP;
+                commandP=usedCommandP;
+            }
         }
         else
         {
-            // store the current pointers to "used" pointers just before using them
+            // store the current pointers to "used" pointers just before using them, the current ones will then be updated
+            // this is to prepare for the case where we receive RELATION_SELF as next relation.
             usedLinkP=linkP;            // originally linkP
             usedRelP=relP;              // originally NULL
             usedCommandP=commandP;      // originally NULL
@@ -428,13 +428,14 @@
         }        
 
         // responseP can be freed at every round
-        free((char*)responseP);
+        free((void*)responseP);
         responseP=NULL;
         
     } // while
     closeSeClientAndCleanup();
 
-
+    if(responseP!=NULL) free((void*)responseP);
+    if(linkP!=NULL) free((void*)linkP);
     if(ROOTPA_OK != ret)  LOGE("doProvisioningWithSe had some problems: %d",ret );
     LOGD("<<doProvisioningWithSe ");
     return;
diff --git a/rootpa/Code/Common/registry.c b/rootpa/Code/Common/registry.c
index 471e999..755ecdc 100755
--- a/rootpa/Code/Common/registry.c
+++ b/rootpa/Code/Common/registry.c
@@ -129,3 +129,22 @@
 {
     return mcRegistryCleanupTrustlet(uuidP, spid);
 }
+
+int regStoreTA(mcSpid_t spid, const mcUuid_t* uuidP, const uint8_t* taBinary, uint32_t taBinLength)
+{
+    return mcRegistryStoreTABlob(spid, (void*) taBinary, taBinLength);
+}
+
+int regGetTaState(mcSpid_t spid, const mcUuid_t* uuidP, mcContainerState_t* stateP)
+{
+    TLTCONTAINERP taP=NULL;
+    uint32_t containerSize=0;
+    containerSize = CONTAINER_BUFFER_SIZE; // this will be updated to actual size with the registry call    
+    int ret=regReadTlt(uuidP, &taP, &containerSize, spid);
+    if(MC_DRV_OK==ret)
+    {
+        *stateP=taP->cont.common.attribs.state;
+    }
+    free(taP);
+    return ret;
+}
diff --git a/rootpa/Code/Common/registry.h b/rootpa/Code/Common/registry.h
index 093d90f..f81ff28 100755
--- a/rootpa/Code/Common/registry.h
+++ b/rootpa/Code/Common/registry.h
@@ -62,3 +62,6 @@
 int regReadTlt(const mcUuid_t* uuidP, TLTCONTAINERP* tltP, uint32_t* containerSize, mcSpid_t spid);
 int regWriteTlt(const mcUuid_t* uuidP, const TLTCONTAINERP tltP, uint32_t containerSize, mcSpid_t spid);
 int regCleanupTlt(const mcUuid_t* uuidP, mcSpid_t spid);
+
+int regStoreTA(mcSpid_t spid, const mcUuid_t* uuidP, const uint8_t* taBinary, uint32_t taBinLength);
+int regGetTaState(mcSpid_t spid, const mcUuid_t* uuidP, mcContainerState_t* stateP);
\ No newline at end of file
diff --git a/rootpa/Code/Common/seclient.c b/rootpa/Code/Common/seclient.c
index 0cb6600..207cde5 100755
--- a/rootpa/Code/Common/seclient.c
+++ b/rootpa/Code/Common/seclient.c
@@ -33,6 +33,7 @@
 #include <stdlib.h>
 #include <stdbool.h>
 #include <time.h>
+#include <math.h>
 
 #include <curl/curl.h>
 
@@ -66,7 +67,7 @@
 #define CECERT_FILENAME "cacert.pem"
 static char certificatePath_[CERT_PATH_MAX_LEN];
 static char certificateFilePath_[CERT_PATH_MAX_LEN];
-
+static long int SE_CONNECTION_DEFAULT_TIMEOUT=58L; // timeout after 58 seconds
 static int MAX_ATTEMPTS=30;  
 static const struct timespec SLEEPTIME={0,300*1000*1000}; // 0.3 seconds  --> 30x0.3 = 9 seconds
 
@@ -75,7 +76,6 @@
 rootpaerror_t httpPostAndReceiveCommand(const char* const inputP, const char** linkP, const char** relP, const char** commandP)
 {
     LOGD("httpPostAndReceiveCommand %ld", (long int) inputP);
-
     return httpCommunicate(inputP, linkP, relP, commandP, httpMethod_POST);
 }
 
@@ -94,7 +94,7 @@
 rootpaerror_t httpGetAndReceiveCommand(const char** linkP, const char** relP, const char** commandP)
 {
     LOGD("httpGetAndReceiveCommand");
-    return httpCommunicate(NULL, linkP, relP, commandP, false);
+    return httpCommunicate(NULL, linkP, relP, commandP, httpMethod_GET);
 }
 
 rootpaerror_t httpDeleteAndReceiveCommand(const char** linkP, const char** relP, const char** commandP)
@@ -384,7 +384,7 @@
         return false;
     }   
 
-    long int se_connection_timeout=120L; // timeout after 120 seconds
+    long int se_connection_timeout=SE_CONNECTION_DEFAULT_TIMEOUT;
 #ifdef __DEBUG
     curl_easy_setopt(curl_handle, CURLOPT_VERBOSE, 1L);
     curl_easy_setopt(curl_handle, CURLOPT_DEBUGFUNCTION, debug_function);   
@@ -505,13 +505,13 @@
 {
     if(curl_global_init(CURL_GLOBAL_ALL)!=CURLE_OK)
     {
-        LOGE("curl_gloabal_init failed");
+        LOGE("curl_global_init failed");
         return ROOTPA_ERROR_NETWORK;
     }
     curl_handle_=curl_easy_init();
     if(NULL==curl_handle_)
     {
-        LOGE("initialize failed");
+        LOGE("curl_easy_init failed");
         return ROOTPA_ERROR_NETWORK;
     }
 
@@ -535,6 +535,9 @@
     long int http_code = 0;
     int attempts=0;
     struct curl_slist* httpHeaderP = NULL;
+    time_t begintime=0;
+    time_t endtime=0;
+    int timediff=0;
     
     LOGD(">>httpCommunicate");
     if(NULL==linkP || NULL==relP || NULL==commandP || NULL==*linkP)
@@ -617,12 +620,21 @@
         return ROOTPA_ERROR_NETWORK;    
     }
 
+    begintime=time(NULL);    
     while(curlRet!=CURLE_OK && attempts++ < MAX_ATTEMPTS)
     {
         curlRet=curl_easy_perform(curl_handle_);
-        LOGD("curl_easy_perform %ld %d", curlRet, attempts);
+        LOGD("curl_easy_perform %ld %d", curlRet, attempts );
         if(CURLE_OK==curlRet) break;
         nanosleep(&SLEEPTIME,NULL);
+        endtime=time(NULL);
+        timediff=(int)ceil(difftime(endtime, begintime));
+        LOGD("timediff (ceil) %d", timediff);
+        if(timediff>(SE_CONNECTION_DEFAULT_TIMEOUT/2))
+        {
+            LOGE("No connection to SE. Exiting retry loop for curl_easy_perform due to timeout %d", timediff);
+            break;
+        }
     }
 
     curl_easy_getinfo (curl_handle_, CURLINFO_RESPONSE_CODE, &http_code);
@@ -636,7 +648,7 @@
         return ROOTPA_ERROR_NETWORK;
     }
     
-    LOGD("http return code from SE %ld", (long int) http_code);    
+    LOGD("http return code from SE %ld", (long int) http_code);
     if ((200 <= http_code &&  http_code < 300)) 
     {
         ret=ROOTPA_OK; 
@@ -652,25 +664,29 @@
              HTTP_CODE_INTERNAL_ERROR == http_code || 
              HTTP_CODE_HTTP_VERSION == http_code)
     {
+        LOGE("SE returned http error %ld", (long int) http_code);
         ret=ROOTPA_ERROR_INTERNAL;
     }
     else if(HTTP_CODE_MOVED == http_code ||  // new URL would be in Location: header but RootPA does not support in currently (unless libcurl supports it transparently)
             HTTP_CODE_REQUEST_TIMEOUT == http_code  || 
             HTTP_CODE_SERVICE_UNAVAILABLE == http_code)
     {
+        LOGE("SE returned http error %ld", (long int) http_code);
         ret=ROOTPA_ERROR_NETWORK;
     }
     else if (HTTP_CODE_CMP_VERSION == http_code)
     {
-
+        LOGE("SE returned http error %ld", (long int) http_code);
         ret=ROOTPA_ERROR_SE_CMP_VERSION;
     }    
     else if (HTTP_CODE_FAILED_DEPENDENCY == http_code)
     {
+        LOGE("SE returned http error %ld", (long int) http_code);
         ret=ROOTPA_ERROR_SE_PRECONDITION_NOT_MET;
     }
     else if (HTTP_CODE_NOT_FOUND == http_code)
     {
+        LOGE("SE returned http error %ld", (long int) http_code);
         ret=ROOTPA_ERROR_ILLEGAL_ARGUMENT; // since the arguments (spid, in some cases uuid) for the URL are received from the client, 
                                            // this can be returned. It is also possible that suid is wrong (corrupted in device or info 
                                            // from device binding missing from SE, but we can not detect that easily.
diff --git a/rootpa/Code/Common/trustletchannel.c b/rootpa/Code/Common/trustletchannel.c
index e47b207..636944c 100755
--- a/rootpa/Code/Common/trustletchannel.c
+++ b/rootpa/Code/Common/trustletchannel.c
@@ -45,10 +45,17 @@
 /*
 Open session to content management trustlet and allocate enough memory for communication
 */
-CMTHANDLE tltChannelOpen(int sizeOfWsmBuffer,  mcResult_t* result){
-    CMTHANDLE           handle = (CMTHANDLE)malloc(sizeof(CMTSTRUCT));
-    const mcUuid_t      UUID = TL_CM_UUID;
+CMTHANDLE tltChannelOpen(int sizeOfWsmBuffer,  mcResult_t* result)
+{
+    mcUuid_t      UUID = TL_CM_UUID;
+    return taChannelOpen(sizeOfWsmBuffer, result, &UUID, NULL, 0,0);
+}
 
+/*
+*/
+CMTHANDLE taChannelOpen(int sizeOfWsmBuffer,  mcResult_t* result, mcUuid_t* uuidP, uint8_t* taBinaryP, uint32_t taLength, mcSpid_t spid)
+{
+    CMTHANDLE           handle = (CMTHANDLE)malloc(sizeof(CMTSTRUCT));
 
     if (unlikely( NULL==handle ))
     {
@@ -64,7 +71,7 @@
 
     if (MC_DRV_OK != *result) 
     {
-      LOGE("tltChannelOpen: Unable to open device, error: %d", *result);
+      LOGE("taChannelOpen: Unable to open device, error: %d", *result);
       free(handle);
 
       return NULL;
@@ -75,16 +82,24 @@
     *result = mcMallocWsm(tltChannelDeviceId, 0, sizeOfWsmBuffer, &handle->wsmP, 0);
     if (MC_DRV_OK != *result) 
     {
-        LOGE("tltChannelOpen: Allocation of CMP WSM failed, error: %d", *result);
+        LOGE("taChannelOpen: Allocation of CMP WSM failed, error: %d", *result);
         mcCloseDevice(tltChannelDeviceId);
         free(handle);
         return NULL;
     }
 
-    *result = mcOpenSession(&handle->session,(const mcUuid_t *)&UUID,handle->wsmP,(uint32_t)sizeOfWsmBuffer);
+    if(taBinaryP!=NULL && taLength!=0)
+    {
+        *result = mcOpenTrustlet(&handle->session, spid, taBinaryP, taLength, handle->wsmP,(uint32_t)sizeOfWsmBuffer);
+    }
+    else
+    {
+        *result = mcOpenSession(&handle->session,uuidP, handle->wsmP,(uint32_t)sizeOfWsmBuffer);
+    }
+    
     if (MC_DRV_OK != *result)
     {
-        LOGE("tltChannelOpen: Open session failed, error: %d", *result);
+        LOGE("taChannelOpen: Open session failed, error: %d", *result);
         mcFreeWsm(tltChannelDeviceId,handle->wsmP);
         mcCloseDevice(tltChannelDeviceId);
         free(handle);
@@ -93,6 +108,7 @@
     return handle;
 }
 
+
 /*
 Close the communication channel and free resources
 */
diff --git a/rootpa/Code/Common/trustletchannel.h b/rootpa/Code/Common/trustletchannel.h
index 2fb1407..fc3eab1 100755
--- a/rootpa/Code/Common/trustletchannel.h
+++ b/rootpa/Code/Common/trustletchannel.h
@@ -55,6 +55,11 @@
 CMTHANDLE tltChannelOpen(int sizeOfWsmBuffer, mcResult_t* result);
 
 /**
+Open session to TA and allocate enough memory for communication. There are two way to do this, give TA uuid or TA binary, binary length and spid. 
+The former works with system TA's the latter with SP TA's.
+*/
+CMTHANDLE taChannelOpen(int sizeOfWsmBuffer,  mcResult_t* result, mcUuid_t* uuidP, uint8_t* taBinaryP, uint32_t taLength, mcSpid_t spid);
+/**
 */
 void tltChannelClose(CMTHANDLE handle);
 /**
diff --git a/rootpa/Code/Common/xmlmessagehandler.c b/rootpa/Code/Common/xmlmessagehandler.c
index 861fd6f..6f979bc 100755
--- a/rootpa/Code/Common/xmlmessagehandler.c
+++ b/rootpa/Code/Common/xmlmessagehandler.c
@@ -55,7 +55,7 @@
 #define PLATFORM_TYPES_NAMESPACE "http://www.mcore.gi-de.com/2012/02/schema/MCPlatformTypes"
 
 #define XSD_PATH_MAX_LEN 256
-
+#define INT_BUFFER_LENGTH 11
 #define UNKNOWN_ID 0xFFFFFFFF
 
 #define EXTERNAL_MEMORY 2
@@ -154,9 +154,9 @@
     if(NULL==commandResultNode) return false;
 
     bool retValue=true;    
-    char intBuffer[11];
+    char intBuffer[INT_BUFFER_LENGTH];
 
-    sprintf(intBuffer,"%u",(uint32_t) id);
+    snprintf(intBuffer,INT_BUFFER_LENGTH,"%u",(uint32_t) id);
     if(xmlNewProp(commandResultNode, BAD_CAST "id", BAD_CAST intBuffer)==NULL) return false;
 
     if(commandResultP==NULL)
@@ -170,7 +170,7 @@
         } 
         else if(errorDetail!=0)
         {
-            sprintf(intBuffer,"%u",errorDetail);
+            snprintf(intBuffer,INT_BUFFER_LENGTH,"%u",errorDetail);
             if(xmlNewProp(errorNode, BAD_CAST "errorDetail", BAD_CAST intBuffer)==NULL)
             { 
                 retValue=false;
@@ -353,7 +353,16 @@
     LOGD(">>handleCmpResponses %d", maxNumberOfCmpResponses);
     rootpaerror_t ret=ROOTPA_OK;
     uint32_t i;
-
+    if(cmpResponsesP == NULL)
+    {
+        if(maxNumberOfCmpResponses>0)
+        {
+            LOGE("maxNumberOfCmpResponses %d while pointer is NULL", maxNumberOfCmpResponses);
+            return ROOTPA_ERROR_INTERNAL;
+        }        
+        return ROOTPA_OK;
+    }
+    
     for(i=0; (i<maxNumberOfCmpResponses) && (ROOTPA_OK==ret); i++)
     {
         char* encodedResponseP=NULL;
@@ -459,6 +468,16 @@
     rootpaerror_t ret=ROOTPA_OK;
     char zero=0;
     uint32_t i;
+    if(uploadResponsesP == NULL)
+    {
+        if(numberOfUploadResponses>0)
+        {
+            LOGE("numberOfUploadResponses %d while pointer is NULL", numberOfUploadResponses);
+            return ROOTPA_ERROR_INTERNAL;
+        }
+        return ROOTPA_OK;
+    }
+
     for(i=0; (i < numberOfUploadResponses) && (ROOTPA_OK==ret); i++)
     {
         char* encodedResponseP=NULL;
@@ -543,6 +562,7 @@
         
         if(commandType != CMP && 
           false == ignoreError && 
+          uploadCommandsP &&
           uploadCommandsP[numberOfUploadCommands-1].ret != ROOTPA_OK) break; // since upload commands are already executed in this loop
     }
 
@@ -595,7 +615,7 @@
     int i;
     for(i=0; i<numberOfCmpCommands; i++)
     { 
-        free(cmpCommandsP[i].contentP);
+        if(cmpCommandsP) free(cmpCommandsP[i].contentP);
         if(cmpResponsesP) free(cmpResponsesP[i].contentP);
     }
     free(cmpCommandsP);
@@ -685,12 +705,15 @@
     if (parserCtxtP) xmlSchemaFreeParserCtxt(parserCtxtP);
     if (schemaP) xmlSchemaFree(schemaP);     
     if (validCtxtP) xmlSchemaFreeValidCtxt(validCtxtP);
- #else // !LIBXML_SCHEMAS_ENABLED 
-    result=0;
- #endif // LIBXML_SCHEMAS_ENABLED 
- 
+    
     LOGD("<<validXmlMessage %d", result);    
     return ((0==result)?true:false);
+    
+ #else // !LIBXML_SCHEMAS_ENABLED 
+    LOGD("<<validXmlMessage");
+    return true;
+ #endif // LIBXML_SCHEMAS_ENABLED 
+ 
 }
 
 uint8_t* validateDumpAndFree(xmlDocPtr xmlResponseP)
@@ -702,7 +725,8 @@
     }
     int size=0;
     xmlChar* dumpP;
-    xmlDocDumpMemory(xmlResponseP, &dumpP, &size);
+//    xmlDocDumpMemory(xmlResponseP, &dumpP, &size);
+      xmlDocDumpMemoryEnc(xmlResponseP, &dumpP, &size, "UTF-8");
     if(dumpP!=NULL)
     {
         // doing this copy only because libxml2 documentation tells to
@@ -712,7 +736,7 @@
         // be on the safe side
 
         dumpedP=malloc(size+1);
-        strcpy((char*) dumpedP, (char*) dumpP);
+        strncpy((char*) dumpedP, (char*) dumpP, size+1);
         xmlFree(dumpP);
     }
     xmlFreeDoc(xmlResponseP);
@@ -757,7 +781,7 @@
         // attempting to parse the message anyway.
     }
 
-    xmlDocPtr xmlResponseP=createXmlResponse(ret);
+    xmlDocPtr xmlResponseP=createXmlResponse();
     
 // parse received command
 
@@ -839,7 +863,7 @@
 rootpaerror_t fillMcVersion(xmlNodePtr mcVersionNode, int mcVersionTag, const mcVersionInfo_t* mcVersionP)
 {
     LOGD(">>fillMcVersion");
-    char intBuffer[11];
+    char intBuffer[INT_BUFFER_LENGTH];
 
     xmlSetStructuredErrorFunc(NULL, NULL);
     xmlSetGenericErrorFunc(NULL, handleError);
@@ -848,28 +872,28 @@
     
     if(xmlNewProp(mcVersionNode, BAD_CAST "productId", BAD_CAST mcVersionP->productId)==NULL) return ROOTPA_ERROR_XML;
 
-    sprintf(intBuffer,"%u",mcVersionP->versionMci);
+    snprintf(intBuffer,INT_BUFFER_LENGTH,"%u",mcVersionP->versionMci);
     if(xmlNewProp(mcVersionNode, BAD_CAST "versionMci", BAD_CAST intBuffer)==NULL) return ROOTPA_ERROR_XML;
 
-    sprintf(intBuffer,"%u",mcVersionP->versionSo);
+    snprintf(intBuffer,INT_BUFFER_LENGTH,"%u",mcVersionP->versionSo);
     if(xmlNewProp(mcVersionNode, BAD_CAST "versionSo", BAD_CAST intBuffer)==NULL) return ROOTPA_ERROR_XML;    
 
-    sprintf(intBuffer,"%u",mcVersionP->versionMclf);
+    snprintf(intBuffer,INT_BUFFER_LENGTH,"%u",mcVersionP->versionMclf);
     if(xmlNewProp(mcVersionNode, BAD_CAST "versionMclf", BAD_CAST intBuffer)==NULL) return ROOTPA_ERROR_XML;    
 
-    sprintf(intBuffer,"%u",mcVersionP->versionContainer);
+    snprintf(intBuffer,INT_BUFFER_LENGTH,"%u",mcVersionP->versionContainer);
     if(xmlNewProp(mcVersionNode, BAD_CAST "versionContainer", BAD_CAST intBuffer)==NULL) return ROOTPA_ERROR_XML;    
 
-    sprintf(intBuffer,"%u",mcVersionP->versionMcConfig);
+    snprintf(intBuffer,INT_BUFFER_LENGTH,"%u",mcVersionP->versionMcConfig);
     if(xmlNewProp(mcVersionNode, BAD_CAST "versionMcConfig", BAD_CAST intBuffer)==NULL) return ROOTPA_ERROR_XML;            
 
-    sprintf(intBuffer,"%u",mcVersionP->versionTlApi);
+    snprintf(intBuffer,INT_BUFFER_LENGTH,"%u",mcVersionP->versionTlApi);
     if(xmlNewProp(mcVersionNode, BAD_CAST "versionTlApi", BAD_CAST intBuffer)==NULL) return ROOTPA_ERROR_XML;    
 
-    sprintf(intBuffer,"%u",mcVersionP->versionDrApi);
+    snprintf(intBuffer,INT_BUFFER_LENGTH,"%u",mcVersionP->versionDrApi);
     if(xmlNewProp(mcVersionNode, BAD_CAST "versionDrApi", BAD_CAST intBuffer)==NULL) return ROOTPA_ERROR_XML;        
 
-    sprintf(intBuffer,"%u",mcVersionP->versionCmp);
+    snprintf(intBuffer,INT_BUFFER_LENGTH,"%u",mcVersionP->versionCmp);
     if(xmlNewProp(mcVersionNode, BAD_CAST "versionCmp", BAD_CAST intBuffer)==NULL) return ROOTPA_ERROR_XML;    
 
     LOGD("<<fillMcVersion");
@@ -878,12 +902,12 @@
 
 rootpaerror_t buildXmlTrustletInstallationRequest(const char** responseP, trustletInstallationData_t data )
 {
-    char intBuffer[11];
+    char intBuffer[INT_BUFFER_LENGTH];
     LOGD(">>buildXmlTrustletInstallationRequest %ld (%ld %d %d)", (long int) responseP, (long int) data.dataP, data.dataLength, data.dataType);
     rootpaerror_t ret=ROOTPA_OK;
     if(NULL ==  responseP) return ROOTPA_ERROR_ILLEGAL_ARGUMENT; // data content checked earlier in commandhandler.c
 
-    xmlDocPtr xmlResponseDocP=createXmlResponse(ret);    
+    xmlDocPtr xmlResponseDocP=createXmlResponse();    
     xmlNodePtr rspRootElementP = xmlDocGetRootElement(xmlResponseDocP);    
     if(NULL==rspRootElementP) return ROOTPA_ERROR_XML;
    
@@ -903,7 +927,7 @@
         mcDataNode = xmlNewChild(systemInfoNode, nameSpace_, BAD_CAST "trustletAxf", BAD_CAST encodedDataP);
         if(data.memoryType != DEFAULT_MEMORY_TYPE)
         {
-            sprintf(intBuffer,"%d",data.memoryType);
+            snprintf(intBuffer,INT_BUFFER_LENGTH,"%d",data.memoryType);
             if(xmlNewProp(mcDataNode, BAD_CAST "memoryType", BAD_CAST intBuffer)==NULL)
             {
                 free(encodedDataP);
@@ -913,7 +937,7 @@
 
         if(data.numberOfInstances != DEFAULT_NUMBER_OF_INSTANCES)
         {
-            sprintf(intBuffer,"%d",data.numberOfInstances);
+            snprintf(intBuffer,INT_BUFFER_LENGTH,"%d",data.numberOfInstances);
             if(xmlNewProp(mcDataNode, BAD_CAST "numberOfInstances", BAD_CAST intBuffer)==NULL)
             {
                 free(encodedDataP);
@@ -923,7 +947,7 @@
 
         if(data.flags != DEFAULT_FLAGS)
         {
-            sprintf(intBuffer,"%d",data.flags);                        
+            snprintf(intBuffer,INT_BUFFER_LENGTH,"%d",data.flags);                        
             if(xmlNewProp(mcDataNode, BAD_CAST "flags", BAD_CAST intBuffer)==NULL)
             {
                 free(encodedDataP);
@@ -936,7 +960,7 @@
         mcDataNode = xmlNewChild(systemInfoNode, nameSpace_, BAD_CAST "trustletEncryptionKey", BAD_CAST encodedDataP);        
     }
     
-    sprintf(intBuffer,"%d",data.minTltVersion);
+    snprintf(intBuffer,INT_BUFFER_LENGTH,"%d",data.minTltVersion);
     if(xmlNewProp(mcDataNode, BAD_CAST "minTltVersion", BAD_CAST intBuffer)==NULL)
     {
         free(encodedDataP);
@@ -950,7 +974,13 @@
         free(encodedDataP);        
         return ROOTPA_ERROR_INTERNAL;
     }
-    if(xmlNewProp(mcDataNode, BAD_CAST "tltPukHash", BAD_CAST pukHashStringP)==NULL) return ROOTPA_ERROR_XML;
+    if(xmlNewProp(mcDataNode, BAD_CAST "tltPukHash", BAD_CAST pukHashStringP)==NULL)
+    {   
+        LOGE("buildXmlTrustletInstallationRequest: xmlNewProp failed");        
+        free(pukHashStringP);
+        free(encodedDataP);      
+        return ROOTPA_ERROR_XML;
+    }
 
     free(pukHashStringP);
     free(encodedDataP);
@@ -980,7 +1010,7 @@
     xmlThrDefSetStructuredErrorFunc(NULL, NULL);
     xmlThrDefSetGenericErrorFunc(NULL, handleError);    
     
-    xmlDocPtr xmlResponseDocP=createXmlResponse(ret);    
+    xmlDocPtr xmlResponseDocP=createXmlResponse();    
     xmlNodePtr rspRootElementP = xmlDocGetRootElement(xmlResponseDocP);    
     if(NULL==rspRootElementP) return ROOTPA_ERROR_XML;
    
@@ -1023,13 +1053,13 @@
 
     if (xsdpathP!=NULL && strlen(xsdpathP)+1+sizeof(ENROLLMENT_SERVICE_XSD_NAME)<XSD_PATH_MAX_LEN) // ENROLLMENT_SERVICE_XSD_NAME is the longer of the two
     {
-        strcpy(enrollmentServiceFullPath_, xsdpathP);
-        strcpy(platformTypesFullPath_, xsdpathP);
+        strncpy(enrollmentServiceFullPath_, xsdpathP, XSD_PATH_MAX_LEN);
+        strncpy(platformTypesFullPath_, xsdpathP, XSD_PATH_MAX_LEN);
 
-        strcat(enrollmentServiceFullPath_, "/");
-        strcat(platformTypesFullPath_, "/");
+        strncat(enrollmentServiceFullPath_, "/", XSD_PATH_MAX_LEN-strlen(xsdpathP));
+        strncat(platformTypesFullPath_, "/", XSD_PATH_MAX_LEN-strlen(xsdpathP));
     }
 
-    strcat(enrollmentServiceFullPath_, ENROLLMENT_SERVICE_XSD_NAME);
-    strcat(platformTypesFullPath_, PLATFORM_TYPES_XSD_NAME);
+    strncat(enrollmentServiceFullPath_, ENROLLMENT_SERVICE_XSD_NAME, XSD_PATH_MAX_LEN-strlen(enrollmentServiceFullPath_));
+    strncat(platformTypesFullPath_, PLATFORM_TYPES_XSD_NAME, XSD_PATH_MAX_LEN-strlen(platformTypesFullPath_));
 }
diff --git a/rootpa/Test/Android/RootPAClient/res/values/version.xml b/rootpa/Test/Android/RootPAClient/res/values/version.xml
old mode 100644
new mode 100755