DEV Import V008 into git
diff --git a/V008/Android/external/mobicore/Android.mk b/V008/Android/external/mobicore/Android.mk
new file mode 100644
index 0000000..256e682
--- /dev/null
+++ b/V008/Android/external/mobicore/Android.mk
@@ -0,0 +1,13 @@
+# =============================================================================
+#
+# Makefile pointing to all makefiles within the project.
+#
+# =============================================================================
+MOBICORE_PROJECT_PATH := $(call my-dir)
+# Setup common variables
+COMP_PATH_Logwrapper := $(MOBICORE_PROJECT_PATH)/common/LogWrapper
+COMP_PATH_MobiCore := $(MOBICORE_PROJECT_PATH)/common/MobiCore
+COMP_PATH_MobiCoreDriverMod := $(MOBICORE_PROJECT_PATH)/include
+
+# Include the Daemon
+include $(MOBICORE_PROJECT_PATH)/daemon/Android.mk
diff --git a/V008/Android/external/mobicore/common/LogWrapper/Android.mk b/V008/Android/external/mobicore/common/LogWrapper/Android.mk
new file mode 100644
index 0000000..b869c2b
--- /dev/null
+++ b/V008/Android/external/mobicore/common/LogWrapper/Android.mk
@@ -0,0 +1,15 @@
+# =============================================================================
+#
+# MobiCore log wrapper to be included by Android components / products
+#
+# =============================================================================
+
+# This is not a separate module.
+# Only for inclusion by other modules.
+
+LOCAL_SHARED_LIBRARIES += liblog
+
+# Enable logging to logcat per default
+LOCAL_CFLAGS += -DLOG_ANDROID
+
+LOCAL_C_INCLUDES += $(call my-dir)
\ No newline at end of file
diff --git a/V008/Android/external/mobicore/common/LogWrapper/log.h b/V008/Android/external/mobicore/common/LogWrapper/log.h
new file mode 100644
index 0000000..f289b73
--- /dev/null
+++ b/V008/Android/external/mobicore/common/LogWrapper/log.h
@@ -0,0 +1,191 @@
+/** Log wrapper for Android.
+ * @{
+ * @file
+ *
+ * Maps LOG_*() macros to __android_log_print() if LOG_ANDROID is defined.
+ * Adds some extra info to log output like LOG_TAG, file name and line number.
+ *
+ * <!-- Copyright Giesecke & Devrient GmbH 2010 - 2011 -->
+ *
+ * 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 TLCWRAPPERANDROIDLOG_H_
+#define TLCWRAPPERANDROIDLOG_H_
+
+#include <unistd.h>
+#include <stdio.h>
+#include <android/log.h>
+
+
+#define EOL "\n"
+#define DUMMY_FUNCTION()    do{}while(0)
+
+
+#ifdef LOG_ANDROID
+
+#ifdef NDEBUG
+    #define LOG_I(fmt, args...) DUMMY_FUNCTION()
+    #define LOG_W(fmt, args...) DUMMY_FUNCTION()
+#else
+    #define LOG_I(fmt, args...) LOG_i("%d : "fmt , __LINE__ , ## args)
+    #define LOG_W(fmt, args...) LOG_w("%d : "fmt , __LINE__ , ## args)
+#endif
+    #define _LOG_E(fmt, args...) LOG_e("%d : "fmt , __LINE__ , ## args)
+
+    #define LOG_i(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
+    #define LOG_w(...) __android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__)
+    #define LOG_e(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
+
+#else //!defined(LOG_ANDROID)
+
+    // #level / #LOG_TAG ( process_id): __VA_ARGS__
+    // Example:
+    // I/McDrvBasicTest_0_1( 4075): setUp
+    #define _LOG_x(_x_,...) \
+                do \
+                { \
+                    printf("%s/%s(%d): ",_x_,LOG_TAG,getpid()); \
+                    printf(__VA_ARGS__); \
+                    printf(EOL); \
+                } while(1!=1)
+
+
+#ifdef NDEBUG
+    #define LOG_I(fmt, args...) DUMMY_FUNCTION()
+    #define LOG_W(fmt, args...) 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__)
+
+#endif //defined(LOG_ANDROID)
+
+
+/** LOG_E() needs to be more prominent:
+ * Display "*********** ERROR ***********" before actual error message.
+ */
+#define LOG_E(...) \
+            do \
+            { \
+                _LOG_E("*****************************"); \
+                _LOG_E("*********   ERROR   *********"); \
+                _LOG_E(__VA_ARGS__); \
+            } while(1!=1)
+
+
+#define LOG_I_BUF   LOG_I_Buf
+
+__attribute__ ((unused))
+static void LOG_I_Buf(
+	const char *  szDescriptor,
+	const void *  blob,
+	size_t        sizeOfBlob
+) {
+
+	#define CPL         0x10  // chars per line
+	#define OVERHEAD    20
+
+	char buffer[CPL * 4 + OVERHEAD];
+
+	uint32_t index = 0;
+
+	uint32_t moreThanOneLine = (sizeOfBlob > CPL);
+	uint32_t blockLen = CPL;
+	uint32_t addr = 0;
+	uint32_t i = 0;
+
+	if (NULL != szDescriptor)
+	{
+		index += sprintf(&buffer[index], "%s", szDescriptor);
+	}
+
+	if (moreThanOneLine)
+	{
+		if (NULL == szDescriptor)
+		{
+			index += sprintf(&buffer[index], "memory dump");
+		}
+		index += sprintf(&buffer[index], " (0x%08x, %d bytes)", (uint32_t)blob,sizeOfBlob);
+		LOG_I("%s", buffer);
+		index = 0;
+	}
+	else if (NULL == szDescriptor)
+	{
+		index += sprintf(&buffer[index], "Data at 0x%08x: ", (uint32_t)blob);
+	}
+
+	if(sizeOfBlob == 0) {
+		LOG_I("%s", buffer);
+	}
+	else
+	{
+		while (sizeOfBlob > 0)
+		{
+			if (sizeOfBlob < blockLen)
+			{
+				blockLen = sizeOfBlob;
+			}
+
+			// address
+			if (moreThanOneLine)
+			{
+				index += sprintf(&buffer[index], "0x%08X | ",addr);
+				addr += CPL;
+			}
+			// bytes as hex
+			for (i=0; i<blockLen; ++i)
+			{
+				index += sprintf(&buffer[index], "%02x ", ((const char *)blob)[i] );
+			}
+			// spaces if necessary
+			if ((blockLen < CPL) && (moreThanOneLine))
+			{
+				// add spaces
+				for (i=0; i<(3*(CPL-blockLen)); ++i) {
+				index += sprintf(&buffer[index], " ");
+				}
+			}
+			// bytes as ASCII
+			index += sprintf(&buffer[index], "| ");
+			for (i=0; i<blockLen; ++i)
+			{
+				char c = ((const char *)blob)[i];
+				index += sprintf(&buffer[index], "%c",(c>32)?c:'.');
+			}
+
+			blob = &(((const char *)blob)[blockLen]);
+			sizeOfBlob -= blockLen;
+
+			// print line to logcat / stdout
+			LOG_I("%s", buffer);
+			index = 0;
+		}
+	}
+}
+
+#endif /** TLCWRAPPERANDROIDLOG_H_ */
+
+/** @} */
diff --git a/V008/Android/external/mobicore/common/MobiCore/inc/Mci/mci.h b/V008/Android/external/mobicore/common/MobiCore/inc/Mci/mci.h
new file mode 100644
index 0000000..99078c1
--- /dev/null
+++ b/V008/Android/external/mobicore/common/MobiCore/inc/Mci/mci.h
@@ -0,0 +1,96 @@
+/** @mainpage MobiCore Control Interface - MCI

+ *

+ * <h2>Introduction</h2>

+ * The MobiCore Control Interface (MCI) is the interface for integrating G&D MobiCore technology into the

+ * rich operating system running in the non-secure part of an ARM TrustZone enabled platform.

+ *

+ * <h2>Interface overview</h2>

+ * The Structure of the MobiCore control interface is depicted in the figure below:

+ * @image html DoxyOverviewMci500x.png "MobiCore control interface"

+ * @image latex DoxyOverviewMci500x.png "MobiCore control interface" width=12cm

+ *

+ * The MCI is composed of the following interfaces:

+ * <ul>

+ *

+ * <li><b>MobiCore control protocol (MCP) interface.</b></li><br>

+ * The MCP interface is responsible for the main communicating with the MobiCore. This involves sending commands for starting

+ * and stopping of Trustlets as well as checking their corresponding answers. MCP information is exchanged in a

+ * world shared memory buffer which needs to be initially established between NWd and SWd using the FastCall interface.<br>

+ *

+ * <li><b>Notification queue interface.</b></li><br>

+ * 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). Therefore the TLC writes

+ * a notification including the session ID to the buffer. The driver informs the MobiCore

+ * about the availability of a notification with the use of a SIQ. On the secure side the Runtime Management

+ * notifies the Trustlet, according to the given session ID, about the availability of new data.

+ * The same mechanism is used vice versa for writing data back to the None-secure world.

+ *

+ * <li><b>FastCall interface.</b></li><br>

+ * The FastCall interface of the MobiCore system is used to transfer control from the Non-secure World (NWd) to the

+ * Secure World (SWd) and back. There are three mechanisms the NWd shall use to interact with the MobiCore Monitor:

+ * FastCall, N-SIQ and NQ-IRQ (Notification IRQ). FastCall and N-SIQ operations are used to hand over control

+ * to the MobiCore. Both functions make use of the SMC [ARM11] operation.

+ *

+ * </ul>

+ *

+ * You can find more information about the interfaces in the respective modules description.

+ *

+ * <h2>Version history</h2>

+ * <table class="customtab">

+ * <tr><td width="100px"><b>Date</b></td><td width="80px"><b>Version</b></td><td><b>Changes</b></td></tr>

+ * <tr><td>2009-06-25</td><td>0.1</td><td>Initial Release</td></tr>

+ * <tr><td>2009-07-01</td><td>0.2</td><td>Major rewrite</td></tr>

+ * <tr><td>2009-08-06</td><td>0.3</td><td>Added documentation for FastCall helper functions</td></tr>

+ * <tr><td>2009-09-10</td><td>0.4</td><td>Update of constant naming. Modification of doxygen config.</td></tr>

+ * <tr><td>2010-03-09</td><td>0.5</td><td>Added fastCallPower() helper function for MC_FC_POWER.</td></tr> 

+ * <tr><td>2010-05-10</td><td>0.6</td><td>Restructuring of load format header.</td></tr>

+ * <tr><td>2011-07-19</td><td>0.7</td><td>update to reflect current code changes.</td></tr> 

+ * </table>

+ *

+ *

+ * @file

+ * @defgroup FCI    FastCall Interface

+ *

+ * @defgroup NQ     Notification Queue

+ *

+ * @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_

+

+#include "version.h"

+#include "mcifc.h"

+#include "mcinq.h"

+#include "mcimcp.h"

+

+#endif /** MCI_H_ */

+

+/** @} */

diff --git a/V008/Android/external/mobicore/common/MobiCore/inc/Mci/mcifc.h b/V008/Android/external/mobicore/common/MobiCore/inc/Mci/mcifc.h
new file mode 100644
index 0000000..e7dd424
--- /dev/null
+++ b/V008/Android/external/mobicore/common/MobiCore/inc/Mci/mcifc.h
@@ -0,0 +1,127 @@
+/** @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 -->

+ *

+ * 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 MCIFC_H_

+#define MCIFC_H_

+

+/** @name MobiCore FastCall Defines

+ * Defines for the two different FastCall's.

+ */

+/** @{ */

+

+// --- global ----

+#define MC_FC_INVALID                ((uint32_t)  0 )  /**< Invalid FastCall ID */

+#define MC_FC_INIT                   ((uint32_t)(-1))  /**< Initializing FastCall. */

+#define MC_FC_INFO                   ((uint32_t)(-2))  /**< Info FastCall. */

+

+// following defines are currently frozen, so they will candidate for later big-change

+// --- sleep modes ---

+#define MC_FC_SLEEP                  ((uint32_t)(-3))  /**< enter power-sleep */

+#define MC_FC_AFTR                   ((uint32_t)(-5))  /**< enter AFTR-sleep (called from core-0) */

+// --- wake-up access ---

+#define MC_FC_CORE_X_WAKEUP          ((uint32_t)(-4))  /**< wakeup/boot core-x (optional core-number in r1, not "0" ) */

+#define MC_FC_C15_RESUME            ((uint32_t)(-11))  /**< Write power control & diag registers */

+// --- L2 cache access ---

+#define MC_FC_L2X0_CTRL             ((uint32_t)(-21))  /**< Write to L2X0 control register */

+#define MC_FC_L2X0_SETUP1           ((uint32_t)(-22))  /**< Setup L2X0 register - part 1 */

+#define MC_FC_L2X0_SETUP2           ((uint32_t)(-23))  /**< Setup L2X0 register - part 2 */

+#define MC_FC_L2X0_INVALL           ((uint32_t)(-24))  /**< Invalidate all L2 cache */

+#define MC_FC_L2X0_DEBUG            ((uint32_t)(-25))  /**< Write L2X0 debug register */

+// --- MEM traces ---

+#define MC_FC_MEM_TRACE             ((uint32_t)(-31))  /**< Enable SWd tracing via memory */

+// --- write access to CP15 regs ---

+#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) */

+

+#define MC_FC_MAX_ID         ((uint32_t)(0xFFFF0000))  /**< Maximum allowed FastCall ID */

+

+// r1 is requested status (0,1,2), on return r2 holds this status value

+

+/** @} */

+

+/** @name MobiCore SMC Defines

+ * Defines the different secure monitor calls (SMC) for world switching.

+ * @{ */

+#define MC_SMC_N_YIELD     0x3     /**< Yield to switch from NWd to SWd. */

+#define MC_SMC_N_SIQ       0x4     /**< SIQ to switch from NWd to SWd. */

+/** @} */

+

+/** @name MobiCore status

+ *  MobiCore status information.

+ * @{ */

+#define MC_STATUS_NOT_INITIALIZED  0   /**< MobiCore is not yet initialized. FastCall FcInit() has to be used function to set up MobiCore.*/

+#define MC_STATUS_BAD_INIT         1   /**< Bad parameters have been passed in FcInit(). */

+#define MC_STATUS_INITIALIZED      2   /**< MobiCore did initialize properly. */

+#define MC_STATUS_HALT             3   /**< MobiCore kernel halted due to an unrecoverable exception. Further information is available extended info */

+/** @} */

+

+/** @name Extended Info Identifiers

+ *  Extended info parameters for MC_FC_INFO to obtain further information depending on MobiCore state.

+ * @{ */

+#define MC_EXT_INFO_ID_MCI_VERSION      0 /**< Version of the MobiCore Control Interface (MCI) */

+#define MC_EXT_INFO_ID_FLAGS            1 /**< MobiCore control flags */

+#define MC_EXT_INFO_ID_HALT_CODE        2 /**< MobiCore halt condition code */

+#define MC_EXT_INFO_ID_HALT_IP          3 /**< MobiCore halt condition instruction pointer */

+#define MC_EXT_INFO_ID_FAULT_CNT        4 /**< MobiCore fault counter */

+#define MC_EXT_INFO_ID_FAULT_CAUSE      5 /**< MobiCore last fault cause */

+#define MC_EXT_INFO_ID_FAULT_META       6 /**< MobiCore last fault meta */

+#define MC_EXT_INFO_ID_FAULT_THREAD     7 /**< MobiCore last fault threadid */

+#define MC_EXT_INFO_ID_FAULT_IP         8 /**< MobiCore last fault instruction pointer */

+#define MC_EXT_INFO_ID_FAULT_SP         9 /**< MobiCore last fault stack pointer */

+#define MC_EXT_INFO_ID_FAULT_ARCH_DFSR  10 /**< MobiCore last fault ARM arch information */

+#define MC_EXT_INFO_ID_FAULT_ARCH_ADFSR 11 /**< MobiCore last fault ARM arch information */

+#define MC_EXT_INFO_ID_FAULT_ARCH_DFAR  12 /**< MobiCore last fault ARM arch information */

+#define MC_EXT_INFO_ID_FAULT_ARCH_IFSR  13 /**< MobiCore last fault ARM arch information */

+#define MC_EXT_INFO_ID_FAULT_ARCH_AIFSR 14 /**< MobiCore last fault ARM arch information */

+#define MC_EXT_INFO_ID_FAULT_ARCH_IFAR  15 /**< MobiCore last fault ARM arch information */

+#define MC_EXT_INFO_ID_MC_CONFIGURED    16 /**< MobiCore configured by Daemon via fc_init flag */

+#define MC_EXT_INFO_ID_MC_SCHED_STATUS  17 /**< MobiCore scheduling status: idle/non-idle */

+#define MC_EXT_INFO_ID_MC_STATUS        18 /**< MobiCore runtime status: initialized, halted */

+#define MC_EXT_INFO_ID_MC_EXC_PARTNER   19 /**< MobiCore exception handler last partner */

+#define MC_EXT_INFO_ID_MC_EXC_IPCPEER   20 /**< MobiCore exception handler last peer */

+#define MC_EXT_INFO_ID_MC_EXC_IPCMSG    21 /**< MobiCore exception handler last IPC message */

+#define MC_EXT_INFO_ID_MC_EXC_IPCDATA   22 /**< MobiCore exception handler last IPC data */

+

+/** @} */

+

+/** @name FastCall return values

+ * Return values of the MobiCore FastCalls.

+ * @{ */

+#define MC_FC_RET_OK                       0     /**< No error. Everything worked fine. */

+#define MC_FC_RET_ERR_INVALID              1     /**< FastCall was not successful. */

+#define MC_FC_RET_ERR_ALREADY_INITIALIZED  5     /**< MobiCore has already been initialized. */

+/** @} */

+

+#endif /** MCIFC_H_ */

+

+/** @} */

diff --git a/V008/Android/external/mobicore/common/MobiCore/inc/Mci/mcifcfunc.h b/V008/Android/external/mobicore/common/MobiCore/inc/Mci/mcifcfunc.h
new file mode 100644
index 0000000..b261dc9
--- /dev/null
+++ b/V008/Android/external/mobicore/common/MobiCore/inc/Mci/mcifcfunc.h
@@ -0,0 +1,187 @@
+/** @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 -->

+ *

+ * 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 MCIFCFUNC_H_

+#define MCIFCFUNC_H_

+

+#include "mcifc.h"

+/**

+ * Execute a secure monitor call (SMC).

+ *

+ * @param mode SMC mode affects the way SMC is handled

+ *

+ * @attention This function shall not be used directly. Use N_Siq() or Yield() instead.

+ */

+__smc(0) void smc(int32_t mode);

+

+/**

+ * N-SIQ switch from NWd to SWd.

+ * Execution will continue in the SWd. The notification queue will be drained by the MC4 and MC4 system schedules its services.

+ */

+inline void N_Siq(void) { smc(MC_SMC_N_SIQ); }

+

+/**

+ * Yield switch from NWd to SWd.

+ * Execution will continue in the SWd without scheduling MC4 services.

+ */

+inline void Yield(void) { smc(MC_SMC_N_YIELD); }

+

+/** Wrapper structure for parameter passing in registers.

+ *  This structure is used as a "wrapper" return value for functions that

+ *  return data in the registers r0 to r3. With the RealView compiler such

+ *  function are declare as:  _value_in_regs reg_r0_r1_r2_r3_t foo()

+
+ */

+typedef struct {

+    uint32_t r0;

+    uint32_t r1;

+    uint32_t r2;

+    uint32_t r3;

+} reg_r0_r1_r2_r3_t;

+

+/** Parameterized SMC for FastCalls.

+ * @attention This function shall not be used directly.
+ */

+__smc(0) __value_in_regs  reg_r0_r1_r2_r3_t smcFc(

+        uint32_t r0,

+        uint32_t r1,

+        uint32_t r2,

+        uint32_t r3

+);

+

+/** FastCall helper function.

+ * @attention This function shall not be used directly.

+ */

+inline static __value_in_regs reg_r0_r1_r2_r3_t fastCall(

+        uint32_t r0,

+        uint32_t r1,

+        uint32_t r2,

+        uint32_t r3

+) {

+    return smcFc(r0,r1,r2,r3);

+}

+

+/**

+ * Initialize the MobiCore.

+ * The FcMc4init FastCall shall be used to set up the MCI. The function passes the message buffers used in the MCI to the MC4 system.

+ * As long as the buffers are not set up the MC4 message passing mechanisms (notifications, MCP commands) are not available.

+ * NQ buffer and MCP buffer as well as length calculations are described in the "MobiCore4 Driver Interface Specification".

+ * <br> The fastCallInit() will not check the parameters for validity. Instead the MC4 will perform a check on first usage of the parameters.

+ *

+ * @image html DoxyMciBuffer.png "MCI buffer"

+ * @image latex DoxyMciBuffer.png "MCI buffer" width=12cm

+ *

+ * @param base      Physical start address of the MCI buffer. Must be 4kB aligned.

+ * @param nqOffset  Offset in bytes  to the beginning of the NQ buffer.

+ * @param nqLength  Length of the NQ buffer in bytes.

+ * @param mcpOffset Offset in bytes to the beginning of the MCP buffer.

+ * @param mcpLength Length of the MCP buffer in bytes

+ *

+ */

+inline static uint32_t fastCallInit(

+        uint8_t *base,

+        uint32_t  nqOffset,

+        uint32_t  nqLength,

+        uint32_t  mcpOffset,

+        uint32_t  mcpLength

+) {

+

+    reg_r0_r1_r2_r3_t ret;

+

+    ret = fastCall(

+            MC_FC_INIT,

+            (uint32_t)base,

+            ((nqOffset << 16) | (nqLength & 0xFFFF)),

+            ((mcpOffset << 16) | (mcpLength & 0xFFFF)) );

+

+

+    return ret.r1;

+}

+

+

+/** Get status information about MobiCore.

+ * The FcMcGetInfo FastCall provides information about the current state of the MobiCore.

+ * In certain states extended information is provided.

+ *

+ * @param extInfoId Extended info word to be obtained.

+ * @param mc4state Current state of the MobiCore.

+ * @param extInfo Extended information depending on state.

+ */

+inline static uint32_t fastCallGetInfo(

+        uint32_t extInfoId,

+        uint32_t *mc4state,

+        uint32_t *extInfo

+) {

+    reg_r0_r1_r2_r3_t ret;

+

+    ret = fastCall(MC_FC_INFO,extInfoId,0,0);

+

+    if (MC_FC_RET_OK == ret.r1)

+    {

+        *mc4state = ret.r2;

+        *extInfo = ret.r3;

+    }

+

+    return ret.r1;

+}

+

+/**

+ * Power management.

+ * The power management FastCall is platform specific.

+ *

+ * @param param0  platform specific parameter.

+ * @param param1  platform specific parameter.

+ * @param param2  platform specific parameter.

+ */

+inline static uint32_t fastCallPower(

+        uint32_t param0,

+        uint32_t param1,

+        uint32_t param2

+) {

+

+    reg_r0_r1_r2_r3_t ret;

+

+    ret = fastCall(

+            MC_FC_POWER,

+            param0,

+            param1,

+            param2 );

+

+    return ret.r1;

+}

+

+#endif /* MCIFCFUNC_H_ */

+/**

+ * @}*/

diff --git a/V008/Android/external/mobicore/common/MobiCore/inc/Mci/mcimcp.h b/V008/Android/external/mobicore/common/MobiCore/inc/Mci/mcimcp.h
new file mode 100644
index 0000000..9dc78e9
--- /dev/null
+++ b/V008/Android/external/mobicore/common/MobiCore/inc/Mci/mcimcp.h
@@ -0,0 +1,404 @@
+/** @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 -->

+ *

+ * 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 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.

+ */

+typedef enum {

+    MC_MCP_RET_OK                                   =  0, /**< Memory has successfully been mapped. */

+    MC_MCP_RET_ERR_INVALID_SESSION                  =  1, /**< The session ID is invalid. */

+    MC_MCP_RET_ERR_UNKNOWN_UUID                     =  2, /**< The UUID of the Trustlet is unknown. */

+    MC_MCP_RET_ERR_UNKNOWN_DRIVER_ID                =  3, /**< The ID of the driver is unknown. */

+    MC_MCP_RET_ERR_NO_MORE_SESSIONS                 =  4, /**< No more session are allowed. */

+    MC_MCP_RET_ERR_CONTAINER_INVALID                =  5, /**< The container is invalid. */

+    MC_MCP_RET_ERR_TRUSTLET_INVALID                 =  6, /**< The Trustlet is invalid. */

+    MC_MCP_RET_ERR_ALREADY_MAPPED                   =  7, /**< The memory block has already been mapped before. */

+    MC_MCP_RET_ERR_INVALID_PARAM                    =  8, /**< Alignment or length error in the command parameters. */

+    MC_MCP_RET_ERR_OUT_OF_RESOURCES                 =  9, /**< No space left in the virtual address space of the session. */

+    MC_MCP_RET_ERR_INVALID_WSM                      = 10, /**< WSM type unknown or broken WSM */

+    MC_MCP_RET_ERR_UNKNOWN                          = 11, /**< unknown error. */

+    MC_MCP_RET_ERR_INVALID_MAPPING_LENGTH           = 12, /**< Lenght of map invalid */

+    MC_MCP_RET_ERR_MAPPING_TARGET                   = 13, /**< Map can only be applied to Trustlet session */

+    MC_MCP_RET_ERR_OUT_OF_CRYPTO_RESSOURCES         = 14, /**< Couldn't open crypto session. */

+    MC_MCP_RET_ERR_SIGNATURE_VERIFICATION_FAILED    = 15, /**< System Trustlet signature verification failed. */

+    MC_MCP_RET_ERR_WRONG_PUBLIC_KEY                 = 16, /**< System Trustlet public key is wrong. */

+    MC_MCP_RET_ERR_CONTAINER_TYPE_MISMATCH          = 17, /**< Wrong containter type(s). */

+    MC_MCP_RET_ERR_CONTAINER_LOCKED                 = 18, /**< Container is locked (or not activated). */

+    MC_MCP_RET_ERR_SP_NO_CHILD                      = 19, /**< SPID is not registered with root container. */

+    MC_MCP_RET_ERR_TL_NO_CHILD                      = 20, /**< UUID is not registered with sp container. */

+    MC_MCP_RET_ERR_UNWRAP_ROOT_FAILED               = 21, /**< Unwrapping of root container failed. */

+    MC_MCP_RET_ERR_UNWRAP_SP_FAILED                 = 22, /**< Unwrapping of service provider container failed. */

+    MC_MCP_RET_ERR_UNWRAP_TRUSTLET_FAILED           = 23, /**< Unwrapping of Trustlet container failed. */

+    MC_MCP_RET_ERR_CONTAINER_VERSION_MISMATCH       = 24, /**< Container version mismatch. */

+    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. */

+

+    // used for command verification

+    MC_MCP_RET_ERR_UNKNOWN_COMMAND                  = 50, /**< The command is unknown. */

+    MC_MCP_RET_ERR_INVALID_DATA                     = 51  /**< The command data is invalid. */

+} mcpResult_t;

+

+/** Possible MCP Command IDs

+ * Command ID must be between 0 and 0x7FFFFFFF.

+ */

+typedef enum {

+    MC_MCP_CMD_ID_INVALID                = 0x00000000,   /**< Invalid command ID. */

+    // Session commands

+    MC_MCP_CMD_OPEN_SESSION              = 0x00000001,   /**< Open a session to a service. */

+    MC_MCP_CMD_CLOSE_SESSION             = 0x00000003,   /**< Close an existing service session. */

+    MC_MCP_CMD_MAP                       = 0x00000004,   /**< Map a block of WSM to a session. */

+    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. */

+    MC_MCP_CMD_GET_MOBICORE_VERSION      = 0x00000009,   /**< Get MobiCore version information. */

+} mcpCmdId_t;

+

+

+#define FLAG_RESPONSE       (1U << 31)  /**< Flag to indicate that this is the response to a MCP command. */

+

+

+/** Types of WSM known to the MobiCore.

+ */

+typedef enum {

+    WSM_INVALID     = 0,    /**< Invalid memory type */

+    WSM_CONTIGUOUS  = 1,    /**< Reference to WSM points to a contiguous region of pages. */

+    WSM_L2          = 2,    /**< Reference to WSM points to an L2 table describing the memory region to share */

+}wsmType_t;

+

+/** 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 .

+ */

+typedef struct {

+    mcpCmdId_t cmdId; /**< Command ID of the command */

+} commandHeader_t, *commandHeader_ptr;

+

+/** Response header.

+ * MobiCore will reply to every MCP command with an MCP response. Like the MCP command the response consists of a

+ * header followed by response data. The response is written to the same memory location as the MCP command.

+ */

+typedef struct {

+    uint32_t rspId;  /**< Command ID | FLAG_RESPONSE. */

+    mcpResult_t result; /**< Result informs about the execution result of the command associated with the response. */

+} responseHeader_t, *responseHeader_ptr;

+

+

+

+/** @defgroup CMD MCP Commands

+ * @{ */

+

+/** @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.

+ *

+ * @{ */

+

+/** Get MobiCore Version Command. */

+typedef struct {

+    commandHeader_t cmdHeader;  /** Command header. */

+} mcpCmdGetMobiCoreVersion_t, *mcpCmdGetMobiCoreVersion_ptr;

+

+/** Get MobiCore Version Command Response. */

+typedef struct {

+    responseHeader_t rspHeader;   /** Response header. */

+    mcVersionInfo_t  versionInfo; /** MobiCore version info. */

+} mcpRspGetMobiCoreVersion_t, *mcpRspGetMobiCoreVersion_ptr;

+

+/** @} */// End MCPGETMOBICOREVERSION

+

+/** @} */// End ASMCMD

+

+

+/** @defgroup POWERCMD Power Management Commands

+ * @{ */

+

+/** @defgroup MCPSUSPEND SUSPEND

+ * Prepare MobiCore suspension.

+ * This command allows MobiCore and MobiCore drivers to release or clean resources and save device state.

+ *

+ * @{ */

+

+/** Suspend Command */

+typedef struct {

+    commandHeader_t  cmdHeader; /**< Command header. */

+} mcpCmdSuspend_t, *mcpCmdSuspend_ptr;

+

+/** Suspend Command Response */

+typedef struct {

+    responseHeader_t  rspHeader; /**< Response header. */

+} mcpRspSuspend_t, *mcpRspSuspend_ptr;

+/** @} */// End MCPSUSPEND

+

+

+/** @defgroup MCPRESUME RESUME

+ * Resume MobiCore from suspension.

+ * This command allows MobiCore and MobiCore drivers to reinitialize hardware affected by suspension.

+ *

+ * @{ */

+

+/** Resume Command */

+typedef struct {

+    commandHeader_t  cmdHeader; /**< Command header. */

+} mcpCmdResume_t, *mcpCmdResume_ptr;

+

+/** Resume Command Response */

+typedef struct {

+    responseHeader_t  rspHeader; /**< Response header. */

+} mcpRspResume_t, *mcpRspResume_ptr;

+

+/** @} */// End MCPRESUME

+

+/** @} */// End POWERCMD

+

+

+

+/** @defgroup SESSCMD Session Management Commands

+ * @{ */

+

+/** @defgroup MCPOPEN OPEN

+ * Load and open a session to a Trustlet.

+ * The OPEN command loads Trustlet data to the MobiCore context and opens a session to the Trustlet.

+ * If wsmTypeLoadData is WSM_INVALID MobiCore tries to start a pre-installed Trustlet

+ * associated with the uuid passed.

+ * The uuid passed must match the uuid contained in the load data (if available).

+ * On success, MobiCore returns the session ID which can be used for further communication.

+ * @{ */

+

+/** Open Command */

+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 */

+    uint32_t          ofsTciBuffer;     /**< Offset to the data. */

+    uint32_t          lenTciBuffer;     /**< Length of 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. */

+} mcpCmdOpen_t, *mcpCmdOpen_ptr;

+

+/** Open Command Response */

+typedef struct {

+    responseHeader_t  rspHeader; /**< Response header. */

+    uint32_t          sessionId; /**< Session ID used for further communication. */

+} mcpRspOpen_t, *mcpRspOpen_ptr;

+

+/** @} */// End MCPOPEN

+

+

+/** @defgroup MCPCLOSE CLOSE

+ * Close an existing session to a Trustlet.

+ * The CLOSE command terminates a session and frees all resources in the MobiCore system which

+ * are currently occupied by the session. Before closing the session, the MobiCore runtime

+ * management waits until all pending operations, like calls to drivers, invoked by the Trustlet

+ * have been terminated.

+ * Mapped memory will automatically be unmapped from the MobiCore context. The NWd is responsible for

+ * processing the freed memory according to the Rich-OS needs.

+ *

+ * @{ */

+

+/** Close Command */

+typedef struct {

+    commandHeader_t  cmdHeader;  /**< Command header. */

+    uint32_t         sessionId;  /**< Session ID. */

+} mcpCmdClose_t, *mcpCmdClose_ptr;

+

+/** Close Command Response */

+typedef struct {

+    responseHeader_t  rspHeader; /**< Response header. */

+} mcpRspClose_t, *mcpRspClose_ptr;

+

+/** @} */// End MCPCLOSE

+

+

+/** @defgroup MCPMAP MAP

+ * Map a portion of memory to a session.

+ * The MAP command provides a block of memory to the context of a service.

+ * The memory then becomes world-shared memory (WSM).

+ * The WSM can either be normal anonymous memory from malloc() or be a

+ * block of page aligned, contiguous memory.

+ * The only allowed memory type here is WSM_L2.

+ * @{ */

+

+/** Map Command */

+typedef struct {

+    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. */

+    uint32_t         lenBuffer;     /**< Length of the buffer. */

+} mcpCmdMap_t, *mcpCmdMap_ptr;

+

+#define MCP_MAP_MAX         0x100000    /**< Maximum allowed length for MCP map. */

+

+/** Map Command Response */

+typedef struct {

+    responseHeader_t  rspHeader;        /**< Response header. */

+    uint32_t          secureVirtualAdr; /**< Virtual address in the context of the service the WSM is mapped to, already includes a possible offset! */

+} mcpRspMap_t, *mcpRspMap_ptr;

+

+/** @} *///End MCPMAP

+

+

+/** @defgroup MCPUNMAP UNMAP

+ * Unmap a portion of world-shared memory from a session.

+ * The UNMAP command is used to unmap a previously mapped block of

+ * world shared memory from the context of a session.

+ *

+ * Attention: The memory block will be immediately unmapped from the specified session.

+ * If the service is still accessing the memory, the service will trigger a segmentation fault.

+ * @{ */

+

+/** Unmap Command */

+typedef struct {

+    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         secureVirtualAdr;  /**< Virtual address in the context of the service the WSM has been mapped to, already includes a possible offset! */

+    uint32_t         lenVirtualBuffer;  /**< Length of the virtual buffer. */

+} mcpCmdUnmap_t, *mcpCmdUnmap_ptr;

+

+/** Unmap Command Response */

+typedef struct {

+    responseHeader_t rspHeader; /**< Response header. */

+} mcpRspUnmap_t, *mcpRspUnmap_ptr;

+

+/** @} */// End MCPUNMAP

+

+/** @} */// End SESSCMD

+

+/** @} */// End CMD

+

+/** Structure of the MCP buffer. */

+typedef union {

+    commandHeader_t              cmdHeader;              /**< Command header. */

+    responseHeader_t             rspHeader;              /**< Response header. */

+    mcpCmdOpen_t                 cmdOpen;                /**< Load and open service. */

+    mcpRspOpen_t                 rspOpen;                /**< Response to load and open service. */

+    mcpCmdClose_t                cmdClose;               /**< Close command. */

+    mcpRspClose_t                rspClose;               /**< Response to close command. */

+    mcpCmdMap_t                  cmdMap;                 /**< Map WSM to service context. */

+    mcpRspMap_t                  rspMap;                 /**< Response to MAP command. */

+    mcpCmdUnmap_t                cmdUnmap;               /**< Unmap WSM from service context. */

+    mcpRspUnmap_t                rspUnmap;               /**< Response to UNMAP command. */

+    mcpCmdSuspend_t              cmdSuspend;             /**< Suspend MobiCore. */

+    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. */

+} mcpMessage_t, *mcpMessage_ptr;

+

+

+#define MIN_MCP_LEN         sizeof(mcpMessage_t)  /**< Minimum MCP buffer length (in bytes). */

+

+#define MC_FLAG_NO_SLEEP_REQ   0

+#define MC_FLAG_REQ_TO_SLEEP   1

+

+#define MC_STATE_NORMAL_EXECUTION 0

+#define MC_STATE_READY_TO_SLEEP   1

+

+typedef struct {

+    uint16_t  SleepReq;

+    uint16_t  ReadyToSleep;

+} mcSleepMod_t, *mcSleepMod_ptr;

+

+/** MobiCore status flags */

+typedef struct {

+    uint32_t      schedule;   /**< Scheduling hint: if <> MC_FLAG_SCHEDULE_IDLE, MobiCore should be scheduled by the NWd */

+    mcSleepMod_t  sleepMode;  /**<  */

+    uint32_t      RFU2;       /**< Reserved for future use: Must not be interpreted */

+    uint32_t      RFU3;       /**< Reserved for future use: Must not be interpreted */

+} mcFlags_t, *mcFlags_ptr;

+

+#define MC_FLAG_SCHEDULE_IDLE      0 /**< MobiCore is idle. No scheduling required. */

+#define MC_FLAG_SCHEDULE_NON_IDLE  1 /**< MobiCore is non idle, scheduling is required. */

+

+

+

+/** MCP buffer structure */

+typedef struct {

+    mcFlags_t     mcFlags;    /**< MobiCore Flags */

+    mcpMessage_t  mcpMessage; /**< MCP message buffer */

+} mcpBuffer_t, *mcpBuffer_ptr;

+

+/** @} */

+#endif /* MCP_H_ */

diff --git a/V008/Android/external/mobicore/common/MobiCore/inc/Mci/mcinq.h b/V008/Android/external/mobicore/common/MobiCore/inc/Mci/mcinq.h
new file mode 100644
index 0000000..ae9cc07
--- /dev/null
+++ b/V008/Android/external/mobicore/common/MobiCore/inc/Mci/mcinq.h
@@ -0,0 +1,108 @@
+/** @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 -->

+ *

+ * 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 NQ_H_

+#define NQ_H_

+

+/** \name NQ Size Defines

+ * Minimum and maximum count of elements in the notification queue.

+ * @{ */

+#define MIN_NQ_ELEM 1   /**< Minimum notification queue elements. */

+#define MAX_NQ_ELEM 64 /**< Maximum notification queue elements. */

+/** @} */

+

+/** \name NQ Length Defines

+ * Minimum and maximum notification queue length.

+ * @{ */

+#define MIN_NQ_LEN (MIN_NQ_ELEM * sizeof(notification_t))   /**< Minimum notification length (in bytes). */

+#define MAX_NQ_LEN (MAX_NQ_ELEM * sizeof(notification_t))   /**< Maximum notification length (in bytes). */

+/** @} */

+

+/** \name Session ID Defines

+ * Standard Session IDs.

+ * @{ */

+#define SID_MCP       0           /**< MCP session ID is used when directly communicating with the MobiCore (e.g. for starting and stopping of trustlets). */

+#define SID_INVALID   0xffffffff  /**< Invalid session id is returned in case of an error. */

+/** @} */

+

+/** Notification data structure. */

+typedef struct{

+    uint32_t sessionId; /**< Session ID. */

+    int32_t payload;    /**< Additional notification information. */

+} notification_t;

+

+/** Notification payload codes.

+ * 0 indicated a plain simple notification,

+ * a positive value is a termination reason from the task,

+ * a negative value is a termination reason from MobiCore.

+ * Possible negative values are given below.

+ */

+typedef enum {

+    ERR_INVALID_EXIT_CODE   = -1, /**< task terminated, but exit code is invalid */

+    ERR_SESSION_CLOSE       = -2, /**< task terminated due to session end, no exit code available */

+    ERR_INVALID_OPERATION   = -3, /**< task terminated due to invalid operation */

+    ERR_INVALID_SID         = -4, /**< session ID is unknown */

+    ERR_SID_NOT_ACTIVE      = -5 /**<  session is not active */

+} notificationPayload_t;

+

+/** Declaration of the notification queue header.

+ * layout as specified in the data structure specification.

+ */

+typedef struct {

+    uint32_t writeCnt;  /**< Write counter. */

+    uint32_t readCnt;   /**< Read counter. */

+    uint32_t queueSize; /**< Queue size. */

+} notificationQueueHeader_t;

+

+/** Queue struct which defines a queue object.

+ * The queue struct is accessed by the queue<operation> type of

+ * function. elementCnt must be a power of two and the power needs

+ * to be smaller than power of uint32_t (obviously 32).

+ */

+typedef struct {

+    notificationQueueHeader_t hdr;              /**< Queue header. */

+    notification_t notification[MIN_NQ_ELEM];   /**< Notification elements. */

+} notificationQueue_t;

+

+#endif /** NQ_H_ */

+

+/** @} */

diff --git a/V008/Android/external/mobicore/common/MobiCore/inc/Mci/version.h b/V008/Android/external/mobicore/common/MobiCore/inc/Mci/version.h
new file mode 100644
index 0000000..c1eab01
--- /dev/null
+++ b/V008/Android/external/mobicore/common/MobiCore/inc/Mci/version.h
@@ -0,0 +1,34 @@
+/**
+ * <!-- 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_VERSION_H_
+#define MCI_VERSION_H_
+
+#define MCI_VERSION_MAJOR 0
+#define MCI_VERSION_MINOR 4
+
+#endif /** MCI_VERSION_H_ */
diff --git a/V008/Android/external/mobicore/common/MobiCore/inc/TlCm/cmp.h b/V008/Android/external/mobicore/common/MobiCore/inc/TlCm/cmp.h
new file mode 100755
index 0000000..fa377c3
--- /dev/null
+++ b/V008/Android/external/mobicore/common/MobiCore/inc/TlCm/cmp.h
@@ -0,0 +1,1624 @@
+/** @addtogroup CMP

+ * Content Management Protocol Definitions.

+ *

+ * The CMP (Content Management Protocol) is based on the TCI (Trustlet Control

+ * Interface) and defines commands/responses between the content management

+ * trustlet (CMTL) and the content management trustlet connector (CMTLC) and/or

+ * the remote backend.

+ *

+ * @{

+ *

+ * @file

+ * CMP global definitions.

+ * Various components need access to (sub-)structures defined and used by CMP;

+ * these common definitions are made available through this header 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 CMP_H_

+#define CMP_H_

+

+#include "mcContainer.h"

+#include "mcUuid.h"

+#include "mcVersionInfo.h"

+#include "version.h"

+

+typedef uint32_t cmpCommandId_t;

+typedef uint32_t cmpResponseId_t;

+typedef uint32_t cmpReturnCode_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)

+

+/**

+ * CMP command header.

+ */

+typedef struct {

+    /** Command ID. */

+    cmpCommandId_t commandId; 

+} cmpCommandHeader_t;

+

+/**

+ * CMP response header.

+ */

+typedef struct{

+    /** Response ID (must be command ID | RSP_ID_MASK ). */

+    cmpResponseId_t     responseId; 

+    /** Return code of command. */

+    cmpReturnCode_t     returnCode; 

+} cmpResponseHeader_t;

+

+/** SHA256 checksum. */

+typedef struct {

+    uint8_t data[32];

+} cmpSha256_t;

+

+/** Key size of encryption algorithm used for secure messaging. */

+#define CMP_MSG_KEY_SIZE    32

+

+/** Block size of the encryption algorithm used for secure messaging. */

+#define CMP_MSG_CRYPTO_BLOCK_SIZE  16

+

+/** Total number of padding bytes required to encrypt data of given size. */

+#define CMP_ED_PADDING(netsize) (CMP_MSG_CRYPTO_BLOCK_SIZE - (netsize) % CMP_MSG_CRYPTO_BLOCK_SIZE)

+

+/** Total number of bytes used for message authentication code (MAC). */

+#define CMP_MAC_SIZE 32 // HMAC-SHA256

+

+/** Total number of bytes used for PSS signature in GENERATE AUTH TOKEN command. */

+#define CMP_GEN_AUTH_TOKEN_PSS_SIZE   256

+

+/** Message authentication code. */

+typedef struct {

+    uint8_t mac[CMP_MAC_SIZE];

+} cmpMac_t;

+

+/** 64-bit random number. */

+typedef struct {

+    uint8_t data[8];

+} cmpRnd8_t;

+

+/** 256-bit random number. */

+typedef struct {

+    uint8_t data[32];

+} cmpRnd32_t;

+

+/** Version tags. */

+typedef enum {

+    CMP_VERSION_TAG1 = 0x00000001, // Deprecated.

+    CMP_VERSION_TAG2 = 0x00000002,

+} cmpVersionTag_t;

+

+/** Version data for version tag 1. */

+typedef struct {

+    uint32_t number;

+} cmpVersionData1_t;

+

+/** Version data for version tag 2. */

+typedef struct {

+    mcVersionInfo_t versionInfo;

+} cmpVersionData2_t;

+

+/** Version data. */

+typedef union {

+    cmpVersionData1_t versionData1;

+    cmpVersionData2_t versionData2;

+} cmpVersionData_t;

+

+/** @defgroup MC_CMP_CMD_GET_VERSION

+* @{ */

+

+/** @defgroup MC_CMP_CMD_GET_VERSION_CMD Command

+* @{ */

+

+/** GetVersion command. */

+typedef struct {

+    cmpCommandHeader_t cmdHeader;

+} cmpCmdGetVersion_t;

+

+/** @} */ 

+

+/** @defgroup MC_CMP_CMD_GET_VERSION_RSP Response

+* @{ */

+

+/** GetSuid response. */

+typedef struct {

+cmpResponseHeader_t rspHeader;

+    cmpVersionTag_t tag;

+    cmpVersionData_t data;

+} cmpRspGetVersion_t;

+

+/** @} */

+

+/** @} */ 

+

+/** @defgroup MC_CMP_CMD_GENERATE_AUTH_TOKEN

+ * @{ */

+

+/** @defgroup MC_CMP_CMD_GENERATE_AUTH_TOKEN_CMD Command

+ * @{ */

+

+typedef struct {

+    cmpCommandHeader_t cmdHeader;

+    mcSuid_t suid;

+    mcSymmetricKey_t kSocAuth;

+    uint32_t kid;

+} cmpGenAuthTokenCmdSdata_t;

+

+typedef struct {

+    cmpGenAuthTokenCmdSdata_t sdata;

+    uint8_t pssSignature[CMP_GEN_AUTH_TOKEN_PSS_SIZE];

+} cmpGenAuthTokenCmd_t;

+

+/** GenAuthToken command. */

+typedef struct {

+    cmpGenAuthTokenCmd_t cmd;

+} cmpCmdGenAuthToken_t;

+

+/** @} */ 

+

+/** @defgroup MC_CMP_CMD_GENERATE_AUTH_TOKEN_RSP Response

+ * @{ */

+

+typedef struct {

+    cmpResponseHeader_t rspHeader;

+    // No MAC.

+} cmpGenAuthTokenRsp_t;

+

+/** GenAuthToken response. */

+typedef struct {

+    cmpGenAuthTokenRsp_t rsp;

+    mcSoAuthTokenCont_t soAuthCont;

+} cmpRspGenAuthToken_t;

+

+/** @} */ 

+

+/** @} */ 

+

+/** @defgroup MC_CMP_CMD_BEGIN_SOC_AUTHENTICATION

+ * @{ */

+

+/** @defgroup MC_CMP_CMD_BEGIN_SOC_AUTHENTICATION_CMD Command

+ * @{ */

+

+typedef struct {

+    cmpCommandHeader_t cmdHeader;

+} cmpBeginSocAuthenticationCmd_t;

+

+/** BeginSocAuthentication command. */

+typedef struct {

+    cmpBeginSocAuthenticationCmd_t cmd;

+    mcSoAuthTokenCont_t soAuthTokenCont;

+} cmpCmdBeginSocAuthentication_t;

+

+/** @} */ 

+

+/** @defgroup MC_CMP_CMD_BEGIN_SOC_AUTHENTICATION_RSP Response

+ * @{ */

+

+typedef struct {

+    cmpResponseHeader_t rspHeader;

+    mcSuid_t suid;

+    cmpRnd8_t rnd1;

+} cmpBeginSocAuthenticationRspSdata_t;

+

+typedef struct {

+    cmpBeginSocAuthenticationRspSdata_t sdata;

+    cmpMac_t mac;

+} cmpBeginSocAuthenticationRsp_t;

+

+/** BeginSocAuthentication response. */

+typedef struct {

+    cmpBeginSocAuthenticationRsp_t rsp;

+} cmpRspBeginSocAuthentication_t;

+

+/** @} */ 

+

+/** @} */ 

+

+/** @defgroup MC_CMP_CMD_BEGIN_ROOT_AUTHENTICATION

+ * @{ */

+

+/** @defgroup MC_CMP_CMD_BEGIN_ROOT_AUTHENTICATION_CMD Command

+ * @{ */

+

+typedef struct {

+    cmpCommandHeader_t cmdHeader;

+} cmpBeginRootAuthenticationCmd_t;

+

+/** BeginRootAuthentication command. */

+typedef struct {

+    cmpBeginRootAuthenticationCmd_t cmd;

+    mcSoRootCont_t soRootCont;

+} cmpCmdBeginRootAuthentication_t;

+

+/** @} */ 

+

+/** @defgroup MC_CMP_CMD_BEGIN_ROOT_AUTHENTICATION_RSP Response

+ * @{ */

+

+typedef struct {

+    cmpResponseHeader_t rspHeader;

+    mcSuid_t suid;

+    cmpRnd8_t rnd1;

+} cmpBeginRootAuthenticationRspSdata_t;

+

+typedef struct {

+    cmpBeginRootAuthenticationRspSdata_t sdata;

+    cmpMac_t mac;

+} cmpBeginRootAuthenticationRsp_t;

+

+/** BeginRootAuthentication response. */

+typedef struct {

+    cmpBeginRootAuthenticationRsp_t rsp;

+} cmpRspBeginRootAuthentication_t;

+

+/** @} */ 

+

+/** @} */ 

+

+/** @defgroup MC_CMP_CMD_BEGIN_SP_AUTHENTICATION

+ * @{ */

+

+/** @defgroup MC_CMP_CMD_BEGIN_SP_AUTHENTICATION_CMD Command

+ * @{ */

+typedef struct {

+    cmpCommandHeader_t cmdHeader;

+    mcSpid_t spid;

+} cmpBeginSpAuthenticationCmdSdata_t;

+

+typedef struct {

+    cmpBeginSpAuthenticationCmdSdata_t sdata;

+} cmpBeginSpAuthenticationCmd_t;

+

+/** BeginSpAuthentication command. */

+typedef struct {

+    cmpBeginSpAuthenticationCmd_t cmd;

+    mcSoRootCont_t soRootCont;

+    mcSoSpCont_t soSpCont;

+} cmpCmdBeginSpAuthentication_t;

+

+/** @} */

+

+/** @defgroup MC_CMP_CMD_BEGIN_SP_AUTHENTICATION_RSP Response

+ * @{ */

+typedef struct {

+    cmpResponseHeader_t rspHeader;

+    mcSuid_t suid;

+    mcSpid_t spid;

+    cmpRnd8_t rnd1;

+} cmpBeginSpAuthenticationRspSdata_t;

+

+typedef struct {

+    cmpBeginSpAuthenticationRspSdata_t sdata;

+    cmpMac_t mac;

+} cmpBeginSpAuthenticationRsp_t;

+

+/** BeginSpAuthentication response. */

+typedef struct {

+    cmpBeginSpAuthenticationRsp_t rsp;

+} cmpRspBeginSpAuthentication_t;

+

+/** @} */ 

+

+/** @} */ 

+

+/** @defgroup MC_CMP_CMD_AUTHENTICATE 

+ * @{ */

+

+/** @defgroup MC_CMP_CMD_AUTHENTICATE_CMD Command

+ * @{ */

+typedef struct {

+    mcSuid_t suid;

+    uint32_t entityId;

+    cmpRnd8_t rnd2;

+    cmpRnd8_t rnd1;

+    cmpRnd32_t k2;

+} cmpAuthMsgEdata_t;

+

+typedef struct {

+    cmpAuthMsgEdata_t edata;

+    uint8_t padding[CMP_ED_PADDING(sizeof(cmpAuthMsgEdata_t))];

+} cmpAuthCmdEd_t;

+

+typedef struct {

+    cmpCommandHeader_t cmdHeader;

+    cmpAuthCmdEd_t ed;

+} cmpAuthCmdSdata_t; 

+

+typedef struct {

+    cmpAuthCmdSdata_t sdata;

+    cmpMac_t mac;

+} cmpAuthenticateCmd_t;

+

+/** Authenticate command. */

+typedef struct {

+    cmpAuthenticateCmd_t cmd;

+} cmpCmdAuthenticate_t;

+

+/** @} */ 

+

+/** @defgroup MC_CMP_CMD_AUTHENTICATE_RSP Response

+ * @{ */

+typedef struct {

+    mcSuid_t suid;

+    uint32_t entityId;

+    cmpRnd8_t rnd1;

+    cmpRnd8_t rnd2;

+    cmpRnd32_t k1;

+} cmpAuthRspEdata_t;

+

+typedef struct {

+    cmpAuthRspEdata_t edata;

+    uint8_t padding[CMP_ED_PADDING(sizeof(cmpAuthRspEdata_t))];

+} cmpAuthRspEd_t;

+

+typedef struct {

+    cmpResponseHeader_t rspHeader;

+    cmpAuthRspEd_t ed;

+} cmpAuthRspSdata_t;

+

+typedef struct {

+    cmpAuthRspSdata_t sdata;

+    cmpMac_t mac;

+} cmpAuthenticateRsp_t;

+

+/** Authenticate response. */

+typedef struct {

+    cmpAuthenticateRsp_t rsp;

+} cmpRspAuthenticate_t;

+

+/** @} */ 

+

+/** @} */ 

+

+/** @defgroup MC_CMP_CMD_ROOT_CONT_REGISTER_ACTIVATE 

+ * @{ */

+ 

+/** @defgroup MC_CMP_CMD_ROOT_CONT_REGISTER_ACTIVATE_CMD Command

+ * @{ */

+ 

+typedef struct {

+    mcSymmetricKey_t kRootAuth;

+} cmpRootRegActMsgEdata_t;

+

+typedef struct {

+    cmpRootRegActMsgEdata_t edata;

+    uint8_t padding[CMP_ED_PADDING(sizeof(cmpRootRegActMsgEdata_t))];

+} cmpRootRegActCmdEd_t;

+

+typedef struct {

+    cmpCommandHeader_t cmdHeader;

+    mcRootid_t rootid;

+    cmpRootRegActCmdEd_t ed;

+} cmpRootRegActCmdSdata_t;

+

+typedef struct {

+    cmpRootRegActCmdSdata_t sdata;

+    cmpMac_t mac;

+} cmpRootContRegisterActivateCmd_t;

+

+/** RootContRegisterActivate command. */

+typedef struct {

+    cmpRootContRegisterActivateCmd_t cmd;

+} cmpCmdRootContRegisterActivate_t;

+

+/** @} */ 

+

+/** @defgroup MC_CMP_CMD_ROOT_CONT_REGISTER_ACTIVATE_RSP Response

+ * @{ */

+ 

+typedef struct {

+    mcSoRootCont_t soRootCont;

+} cmpRootRegActRspEdata_t;

+

+typedef struct {

+    cmpRootRegActRspEdata_t edata;

+    uint8_t padding[CMP_ED_PADDING(sizeof(cmpRootRegActRspEdata_t))];

+} cmpRootRegActRspEd_t;

+

+typedef struct {

+    cmpResponseHeader_t rspHeader;

+    cmpRootRegActRspEd_t ed;

+} cmpRootRegActRspSdata_t;

+

+typedef struct {

+    cmpRootRegActRspSdata_t sdata;

+    cmpMac_t mac;

+} cmpRootContRegisterActivateRsp_t;

+

+/** RooContRegisterActivate response. */

+typedef struct {

+    cmpRootContRegisterActivateRsp_t rsp;

+    mcSoRootCont_t soRootCont;

+} cmpRspRootContRegisterActivate_t;

+

+/** @} */

+

+/** @} */

+

+/** @defgroup MC_CMP_CMD_ROOT_CONT_UNREGISTER 

+ * @{ */

+

+/** @defgroup MC_CMP_CMD_ROOT_CONT_UNREGISTER_CMD Command

+ * @{ */

+

+typedef struct {

+    mcSuid_t suid;

+    mcSoAuthTokenCont_t soAuthTokenCont;

+} cmpRootUnregMsgEdata_t;

+

+typedef struct {

+    cmpRootUnregMsgEdata_t edata;

+    uint8_t padding[CMP_ED_PADDING(sizeof(cmpRootUnregMsgEdata_t))];

+} cmpRootUnregCmdEd_t;

+

+typedef struct {

+    cmpCommandHeader_t cmdHeader;

+    cmpRootUnregCmdEd_t ed;

+} cmpRootUnregCmdSdata_t;

+

+typedef struct {

+    cmpRootUnregCmdSdata_t sdata;

+    cmpMac_t mac;

+} cmpRootContUnregisterCmd_t;

+

+/** RootContUnregister command. */

+typedef struct {

+    cmpRootContUnregisterCmd_t cmd;

+} cmpCmdRootContUnregister_t;

+

+/** @} */ 

+

+/** @defgroup MC_CMP_CMD_ROOT_CONT_UNREGISTER_RSP Response

+ * @{ */

+

+typedef struct {

+    mcSuid_t suid;

+} cmpRootUnregRspEdata_t;

+

+typedef struct {

+    cmpRootUnregRspEdata_t edata;

+    uint8_t padding[CMP_ED_PADDING(sizeof(cmpRootUnregRspEdata_t))];

+} cmpRootUnregRspEd_t;

+

+typedef struct {

+    cmpResponseHeader_t rspHeader;

+    cmpRootUnregRspEd_t ed;

+} cmpRootUnregRspSdata_t;

+

+typedef struct {

+    cmpRootUnregRspSdata_t sdata;

+    cmpMac_t mac;

+} cmpRootContUnregisterRsp_t;

+

+/** RootContUnregister response. */

+typedef struct {

+    cmpRootContUnregisterRsp_t rsp;

+    mcSoAuthTokenCont_t soAuthTokenCont;

+} cmpRspRootContUnregister_t;

+

+/** @} */ 

+

+/** @} */ 

+

+/** @defgroup MC_CMP_CMD_ROOT_CONT_LOCK_BY_ROOT

+ * @{ */

+

+/** @defgroup MC_CMP_CMD_ROOT_CONT_LOCK_BY_ROOT_CMD Command

+ * @{ */

+

+typedef struct {

+    cmpCommandHeader_t cmdHeader;

+} cmpRootLockByRootCmdSdata_t;

+

+typedef struct {

+    cmpRootLockByRootCmdSdata_t sdata;

+    cmpMac_t mac;

+} cmpRootContLockByRootCmd_t;

+

+/** RootContLockByRoot command. */

+typedef struct {

+    cmpRootContLockByRootCmd_t cmd;

+} cmpCmdRootContLockByRoot_t;

+

+/** @} */ 

+

+/** @defgroup MC_CMP_CMD_ROOT_CONT_LOCK_BY_ROOT_RSP Response

+ * @{ */

+

+typedef struct {

+    mcSoRootCont_t soRootCont;

+} cmpRootLockByRootRspEdata_t;

+

+typedef struct {

+    cmpRootLockByRootRspEdata_t edata;

+    uint8_t padding[CMP_ED_PADDING(sizeof(cmpRootLockByRootRspEdata_t))];

+} cmpRootLockByRootRspEd_t;

+

+typedef struct {

+    cmpResponseHeader_t rspHeader;

+    cmpRootLockByRootRspEd_t ed;

+} cmpRootLockByRootRspSdata_t;

+

+typedef struct {

+    cmpRootLockByRootRspSdata_t sdata;

+    cmpMac_t mac;

+} cmpRootContLockByRootRsp_t;

+

+/** RootContLockByRoot response. */

+typedef struct {

+    cmpRootContLockByRootRsp_t rsp;

+    mcSoRootCont_t soRootCont;

+} cmpRspRootContLockByRoot_t;

+

+/** @} */ 

+

+/** @} */ 

+

+/** @defgroup MC_CMP_CMD_ROOT_CONT_UNLOCK_BY_ROOT

+ * @{ */

+

+/** @defgroup MC_CMP_CMD_ROOT_CONT_UNLOCK_BY_ROOT_CMD Command

+ * @{ */

+

+typedef struct {

+    cmpCommandHeader_t cmdHeader;

+} cmpRootUnlockByRootCmdSdata_t;

+

+typedef struct {

+    cmpRootUnlockByRootCmdSdata_t sdata;

+    cmpMac_t mac;

+} cmpRootContUnlockByRootCmd_t;

+

+/** RootContUnlockByRoot command. */

+typedef struct {

+    cmpRootContUnlockByRootCmd_t cmd;

+} cmpCmdRootContUnlockByRoot_t;

+

+/** @} */ 

+

+/** @defgroup MC_CMP_CMD_ROOT_CONT_UNLOCK_BY_ROOT_RSP Response

+ * @{ */

+

+typedef struct {

+    mcSoRootCont_t soRootCont;

+} cmpRootUnlockByRootRspEdata_t;

+

+typedef struct {

+    cmpRootUnlockByRootRspEdata_t edata;

+    uint8_t padding[CMP_ED_PADDING(sizeof(cmpRootUnlockByRootRspEdata_t))];

+} cmpRootUnlockByRootRspEd_t;

+

+typedef struct {

+    cmpResponseHeader_t rspHeader;

+    cmpRootUnlockByRootRspEd_t ed;

+} cmpRootUnlockByRootRspSdata_t;

+

+typedef struct {

+    cmpRootUnlockByRootRspSdata_t sdata;

+    cmpMac_t mac;

+} cmpRootContUnlockByRootRsp_t;

+

+/** RootContUnlockByRoot response. */

+typedef struct {

+    cmpRootContUnlockByRootRsp_t rsp;

+    mcSoRootCont_t soRootCont;

+} cmpRspRootContUnlockByRoot_t;

+

+/** @} */ 

+

+/** @} */ 

+

+/** @defgroup MC_CMP_CMD_SP_CONT_REGISTER_ACTIVATE

+ * @{ */

+

+/** @defgroup MC_CMP_CMD_SP_CONT_REGISTER_ACTIVATE_CMD Command

+ * @{ */

+

+typedef struct {

+    mcSymmetricKey_t kSpAuth;

+} cmpSpRegActMsgEdata_t;

+

+typedef struct {

+    cmpSpRegActMsgEdata_t edata;

+    uint8_t padding[CMP_ED_PADDING(sizeof(cmpSpRegActMsgEdata_t))];

+} cmpSpRegActCmdEd_t;

+

+typedef struct {

+    cmpCommandHeader_t cmdHeader;

+    mcSpid_t spid;

+    cmpSpRegActCmdEd_t ed;

+} cmpSpRegActCmdSdata_t;

+

+typedef struct {

+    cmpSpRegActCmdSdata_t sdata;

+    cmpMac_t mac;

+} cmpSpContRegisterActivateCmd_t;

+

+/** SpContRegisterActivate command. */

+typedef struct {

+    cmpSpContRegisterActivateCmd_t cmd;

+} cmpCmdSpContRegisterActivate_t;

+

+/** @} */ 

+

+/** @defgroup MC_CMP_CMD_SP_CONT_REGISTER_ACTIVATE_RSP Response

+ * @{ */

+

+typedef struct {

+    mcSoRootCont_t soRootCont;

+    mcSoSpCont_t soSpCont;

+} cmpSpRegActRspEdata_t;

+

+typedef struct {

+    cmpSpRegActRspEdata_t edata;

+    uint8_t padding[CMP_ED_PADDING(sizeof(cmpSpRegActRspEdata_t))];

+} cmpSpRegActRspEd_t;

+

+typedef struct {

+    cmpResponseHeader_t rspHeader;

+    cmpSpRegActRspEd_t ed;

+} cmpSpRegActRspSdata_t;

+

+typedef struct {

+    cmpSpRegActRspSdata_t sdata;

+    cmpMac_t mac;

+} cmpSpContRegisterActivateRsp_t;

+

+/** SpContRegisterActivate response. */

+typedef struct {

+    cmpSpContRegisterActivateRsp_t rsp;

+    mcSoRootCont_t soRootCont;

+    mcSoSpCont_t soSpCont;

+} cmpRspSpContRegisterActivate_t;

+

+/** @} */ 

+

+/** @} */ 

+

+/** @defgroup MC_CMP_CMD_SP_CONT_REGISTER

+ * @{ */

+

+/** @defgroup MC_CMP_CMD_SP_CONT_REGISTER_CMD Command

+ * @{ */

+

+typedef struct {

+    mcSymmetricKey_t kSpAuth;

+} cmpSpRegisterMsgEdata_t;

+

+typedef struct {

+    cmpSpRegisterMsgEdata_t edata;

+    uint8_t padding[CMP_ED_PADDING(sizeof(cmpSpRegisterMsgEdata_t))];

+} cmpSpRegisterCmdEd_t;

+

+typedef struct {

+    cmpCommandHeader_t cmdHeader;

+    mcSpid_t spid;

+    cmpSpRegisterCmdEd_t ed;

+} cmpSpRegisterCmdSdata_t;

+

+typedef struct {

+    cmpSpRegisterCmdSdata_t sdata;

+    cmpMac_t mac;

+} cmpSpContRegisterCmd_t;

+

+/** SpContRegister command. */

+typedef struct {

+    cmpSpContRegisterCmd_t cmd;

+} cmpCmdSpContRegister_t;

+

+/** @} */ 

+

+/** @defgroup MC_CMP_CMD_SP_CONT_REGISTER_RSP Response

+ * @{ */

+

+typedef struct {

+    mcSoRootCont_t soRootCont;

+    mcSoSpCont_t soSpCont;

+} cmpSpRegisterRspEdata_t;

+

+typedef struct {

+    cmpSpRegisterRspEdata_t edata;

+    uint8_t padding[CMP_ED_PADDING(sizeof(cmpSpRegisterRspEdata_t))];

+} cmpSpRegisterRspEd_t;

+

+typedef struct {

+    cmpResponseHeader_t rspHeader;

+    cmpSpRegisterRspEd_t ed;

+} cmpSpRegisterRspSdata_t;

+

+typedef struct {

+    cmpSpRegisterRspSdata_t sdata;

+    cmpMac_t mac;

+} cmpSpContRegisterRsp_t;

+

+/** SpContRegister response. */

+typedef struct {

+    cmpSpContRegisterRsp_t rsp;

+    mcSoRootCont_t soRootCont;

+    mcSoSpCont_t soSpCont;

+} cmpRspSpContRegister_t;

+

+/** @} */ 

+

+/** @} */ 

+

+/** @defgroup MC_CMP_CMD_SP_CONT_ACTIVATE

+ * @{ */

+

+/** @defgroup MC_CMP_CMD_SP_CONT_ACTIVATE_CMD Command

+ * @{ */

+

+typedef struct {

+    mcSymmetricKey_t kSpAuth;

+} cmpSpActivateMsgEdata_t;

+

+typedef struct {

+    cmpSpActivateMsgEdata_t edata;

+    uint8_t padding[CMP_ED_PADDING(sizeof(cmpSpActivateMsgEdata_t))];

+} cmpSpActivateCmdEd_t;

+

+typedef struct {

+    cmpCommandHeader_t cmdHeader;

+    mcSpid_t spid;

+    cmpSpActivateCmdEd_t ed;

+} cmpSpActivateCmdSdata_t;

+

+typedef struct {

+    cmpSpActivateCmdSdata_t sdata;

+    cmpMac_t mac;

+} cmpSpContActivateCmd_t;

+

+/** SpContActivate command. */

+typedef struct {

+    cmpSpContActivateCmd_t cmd;

+} cmpCmdSpContActivate_t;

+

+/** @} */ 

+

+/** @defgroup MC_CMP_CMD_SP_CONT_ACTIVATE_RSP Response

+ * @{ */

+

+typedef struct {

+    mcSoSpCont_t soSpCont;

+} cmpSpActivateRspEdata_t;

+

+typedef struct {

+    cmpSpActivateRspEdata_t edata;

+    uint8_t padding[CMP_ED_PADDING(sizeof(cmpSpActivateRspEdata_t))];

+} cmpSpActivateRspEd_t;

+

+typedef struct {

+    cmpResponseHeader_t rspHeader;

+    cmpSpActivateRspEd_t ed;

+} cmpSpActivateRspSdata_t;

+

+typedef struct {

+    cmpSpActivateRspSdata_t sdata;

+    cmpMac_t mac;

+} cmpSpContActivateRsp_t;

+

+/** SpContActivate response. */

+typedef struct {

+    cmpSpContActivateRsp_t rsp;

+    mcSoSpCont_t soSpCont;

+} cmpRspSpContActivate_t;

+

+/** @} */ 

+

+/** @} */ 

+

+/** @defgroup MC_CMP_CMD_SP_CONT_UNREGISTER 

+ * @{ */

+

+/** @defgroup MC_CMP_CMD_SP_CONT_UNREGISTER_CMD Command

+ * @{ */

+

+typedef struct {

+    cmpCommandHeader_t cmdHeader;

+    mcSpid_t spid;

+} cmpSpContUnregCmdSdata_t;

+

+typedef struct {

+    cmpSpContUnregCmdSdata_t sdata;

+    cmpMac_t mac;

+} cmpSpContUnregisterCmd_t;

+

+/** SpContUnregister command. */

+typedef struct {

+    cmpSpContUnregisterCmd_t cmd;

+} cmpCmdSpContUnregister_t;

+

+/** @} */ 

+

+/** @defgroup MC_CMP_CMD_SP_CONT_UNREGISTER_RSP Response

+ * @{ */

+

+typedef struct {

+    mcSoRootCont_t soRootCont;

+} cmpSpUnregRspEdata_t;

+

+typedef struct {

+    cmpSpUnregRspEdata_t edata;

+    uint8_t padding[CMP_ED_PADDING(sizeof(cmpSpUnregRspEdata_t))];

+} cmpSpUnregRspEd_t;

+

+typedef struct {

+    cmpResponseHeader_t rspHeader;

+    cmpSpUnregRspEd_t ed;

+} cmpSpContUnregRspSdata_t;

+

+typedef struct {

+    cmpSpContUnregRspSdata_t sdata;

+    cmpMac_t mac;

+} cmpSpContUnregisterRsp_t;

+

+/** SpContUnregister response. */

+typedef struct {

+    cmpSpContUnregisterRsp_t rsp;

+    mcSoRootCont_t soRootCont;

+} cmpRspSpContUnregister_t;

+

+/** @} */ 

+

+/** @} */ 

+

+/** @defgroup MC_CMP_CMD_SP_CONT_LOCK_BY_ROOT 

+ * @{ */

+

+/** @defgroup MC_CMP_CMD_SP_CONT_LOCK_BY_ROOT_CMD Command

+ * @{ */

+

+typedef struct {

+    cmpCommandHeader_t cmdHeader; 

+    mcSpid_t spid;

+} cmpSpLockByRootCmdSdata_t;

+

+typedef struct {

+    cmpSpLockByRootCmdSdata_t sdata;

+    cmpMac_t mac;

+} cmpSpContLockByRootCmd_t;

+

+/** SpContLockByRoot command. */

+typedef struct {

+    cmpSpContLockByRootCmd_t cmd;

+    mcSoSpCont_t soSpCont;

+} cmpCmdSpContLockByRoot_t;

+

+/** @} */ 

+

+/** @defgroup MC_CMP_CMD_SP_CONT_LOCK_BY_ROOT_RSP Response

+ * @{ */

+

+typedef struct {

+    mcSoSpCont_t soSpCont;

+} cmpSpLockByRootRspEdata_t;

+

+typedef struct {

+    cmpSpLockByRootRspEdata_t edata;

+    uint8_t padding[CMP_ED_PADDING(sizeof(cmpSpLockByRootRspEdata_t))];

+} cmpSpLockByRootRspEd_t;

+

+typedef struct {

+    cmpResponseHeader_t rspHeader;

+    cmpSpLockByRootRspEd_t ed;

+} cmpSpLockByRootRspSdata_t;

+

+typedef struct {

+    cmpSpLockByRootRspSdata_t sdata;

+    cmpMac_t mac;

+} cmpSpContLockByRootRsp_t;

+

+/** SpContLockByRoot response. */

+typedef struct {

+    cmpSpContLockByRootRsp_t rsp;

+    mcSoSpCont_t soSpCont;

+} cmpRspSpContLockByRoot_t;

+

+/** @} */ 

+

+/** @} */ 

+

+/** @defgroup MC_CMP_CMD_SP_CONT_UNLOCK_BY_ROOT 

+ * @{ */

+

+/** @defgroup MC_CMP_CMD_SP_CONT_UNLOCK_BY_ROOT_CMD Command

+ * @{ */

+

+typedef struct {

+    cmpCommandHeader_t cmdHeader; 

+    mcSpid_t spid;

+} cmpSpUnlockByRootCmdSdata_t;

+

+typedef struct {

+    cmpSpUnlockByRootCmdSdata_t sdata;

+    cmpMac_t mac;

+} cmpSpContUnlockByRootCmd_t;

+

+/** SpContUnlockByRoot command. */

+typedef struct {

+    cmpSpContUnlockByRootCmd_t cmd;

+    mcSoSpCont_t soSpCont;

+} cmpCmdSpContUnlockByRoot_t;

+

+/** @} */ 

+

+/** @defgroup MC_CMP_CMD_SP_CONT_UNLOCK_BY_ROOT_RSP Response

+ * @{ */

+

+typedef struct {

+    mcSoSpCont_t soSpCont;

+} cmpSpUnlockByRootRspEdata_t;

+

+typedef struct {

+    cmpSpUnlockByRootRspEdata_t edata;

+    uint8_t padding[CMP_ED_PADDING(sizeof(cmpSpUnlockByRootRspEdata_t))];

+} cmpSpUnlockByRootRspEd_t;

+

+typedef struct {

+    cmpResponseHeader_t rspHeader;

+    cmpSpUnlockByRootRspEd_t ed;

+} cmpSpUnlockByRootRspSdata_t;

+

+typedef struct {

+    cmpSpUnlockByRootRspSdata_t sdata;

+    cmpMac_t mac;

+} cmpSpContUnlockByRootRsp_t;

+

+/** SpContUnlockByRoot response. */

+typedef struct {

+    cmpSpContUnlockByRootRsp_t rsp;

+    mcSoSpCont_t soSpCont;

+} cmpRspSpContUnlockByRoot_t;

+

+/** @} */ 

+

+/** @} */ 

+

+/** @defgroup MC_CMP_CMD_SP_CONT_LOCK_BY_SP

+ * @{ */

+

+/** @defgroup MC_CMP_CMD_SP_CONT_LOCK_BY_SP_CMD Command

+ * @{ */

+

+typedef struct {

+    cmpCommandHeader_t cmdHeader; 

+    mcSpid_t spid;

+} cmpSpLockBySpCmdSdata_t;

+

+typedef struct {

+    cmpSpLockBySpCmdSdata_t sdata;

+    cmpMac_t mac;

+} cmpSpContLockBySpCmd_t;

+

+/** SpContLockBySp command. */

+typedef struct {

+    cmpSpContLockBySpCmd_t cmd;

+} cmpCmdSpContLockBySp_t;

+

+/** @} */ 

+

+/** @defgroup MC_CMP_CMD_SP_CONT_LOCK_BY_SP_RSP Respose

+ * @{ */

+

+typedef struct {

+    mcSoSpCont_t soSpCont;

+} cmpSpLockBySpRspEdata_t;

+

+typedef struct {

+    cmpSpLockBySpRspEdata_t edata;

+    uint8_t padding[CMP_ED_PADDING(sizeof(cmpSpLockBySpRspEdata_t))];

+} cmpSpLockBySpRspEd_t;

+

+typedef struct {

+    cmpResponseHeader_t rspHeader;

+    cmpSpLockBySpRspEd_t ed;

+} cmpSpLockBySpRspSdata_t;

+

+typedef struct {

+    cmpSpLockBySpRspSdata_t sdata;

+    cmpMac_t mac;

+} cmpSpContLockBySpRsp_t;

+

+/** SpContLockBySp response. */

+typedef struct {

+    cmpSpContLockBySpRsp_t rsp;

+    mcSoSpCont_t soSpCont;

+} cmpRspSpContLockBySp_t;

+

+/** @} */ 

+

+/** @} */ 

+

+/** @defgroup MC_CMP_CMD_SP_CONT_UNLOCK_BY_SP

+ * @{ */

+

+/** @defgroup MC_CMP_CMD_SP_CONT_UNLOCK_BY_SP_CMD Command

+ * @{ */

+

+typedef struct {

+    cmpCommandHeader_t cmdHeader; 

+    mcSpid_t spid;

+} cmpSpUnlockBySpCmdSdata_t;

+

+typedef struct {

+    cmpSpUnlockBySpCmdSdata_t sdata;

+    cmpMac_t mac;

+} cmpSpContUnlockBySpCmd_t;

+

+/** SpContUnlockBySp command. */

+typedef struct {

+    cmpSpContUnlockBySpCmd_t cmd;

+} cmpCmdSpContUnlockBySp_t;

+

+/** @} */ 

+

+/** @defgroup MC_CMP_CMD_SP_CONT_UNLOCK_BY_SP_RSP Response

+ * @{ */

+

+typedef struct {

+    mcSoSpCont_t soSpCont;

+} cmpSpUnlockBySpRspEdata_t;

+

+typedef struct {

+    cmpSpUnlockBySpRspEdata_t edata;

+    uint8_t padding[CMP_ED_PADDING(sizeof(cmpSpUnlockBySpRspEdata_t))];

+} cmpSpUnlockBySpRspEd_t;

+

+typedef struct {

+    cmpResponseHeader_t rspHeader;

+    cmpSpUnlockBySpRspEd_t ed;

+} cmpSpUnlockBySpRspSdata_t;

+

+typedef struct {

+    cmpSpUnlockBySpRspSdata_t sdata;

+    cmpMac_t mac;

+} cmpSpContUnlockBySpRsp_t;

+

+/** SpContUnlockBySp response. */

+typedef struct {

+    cmpSpContUnlockBySpRsp_t rsp;

+    mcSoSpCont_t soSpCont;

+} cmpRspSpContUnlockBySp_t;

+

+/** @} */ 

+

+/** @} */ 

+

+/** @defgroup MC_CMP_CMD_TLT_CONT_REGISTER 

+ * @{ */

+

+/** @defgroup MC_CMP_CMD_TLT_CONT_REGISTER_CMD Command

+ * @{ */

+

+typedef struct {

+    mcSymmetricKey_t kSpTltEnc;

+} cmpTltRegMsgEdata_t;

+

+typedef struct {

+    cmpTltRegMsgEdata_t edata;

+    uint8_t padding[CMP_ED_PADDING(sizeof(cmpTltRegMsgEdata_t))];

+} cmpTltRegCmdEd_t;

+

+typedef struct {

+    cmpCommandHeader_t cmdHeader;

+    mcSpid_t spid;

+    mcUuid_t uuid;

+    cmpTltRegCmdEd_t ed;

+} cmpTltRegCmdSdata_t;

+

+typedef struct {

+    cmpTltRegCmdSdata_t sdata;

+    cmpMac_t mac;

+} cmpTltContRegisterCmd_t;

+

+/** TltContRegister command. */

+typedef struct {

+    cmpTltContRegisterCmd_t cmd;

+} cmpCmdTltContRegister_t;

+

+/** @} */ 

+

+/** @defgroup MC_CMP_CMD_TLT_CONT_REGISTER_RSP Response

+ * @{ */

+

+typedef struct {

+    mcSoSpCont_t soSpCont;

+    mcSoTltCont_t soTltCont;

+} cmpTltRegRspEdata_t;

+

+typedef struct {

+    cmpTltRegRspEdata_t edata;

+    uint8_t padding[CMP_ED_PADDING(sizeof(cmpTltRegRspEdata_t))];

+} cmpTltRegRspEd_t;

+

+typedef struct {

+    cmpResponseHeader_t rspHeader;

+    cmpTltRegRspEd_t ed;

+} cmpTltRegRspSdata_t;

+

+typedef struct {

+    cmpTltRegRspSdata_t sdata;

+    cmpMac_t mac;

+} cmpTltContRegisterRsp_t;

+

+/** TltContRegister response. */

+typedef struct {

+    cmpTltContRegisterRsp_t rsp;

+    mcSoSpCont_t soSpCont;

+    mcSoTltCont_t soTltCont;

+} cmpRspTltContRegister_t;

+

+/** @} */ 

+

+/** @} */ 

+

+/** @defgroup MC_CMP_CMD_TLT_CONT_ACTIVATE 

+ * @{ */

+

+/** @defgroup MC_CMP_CMD_TLT_CONT_ACTIVATE_CMD Command

+ * @{ */

+

+typedef struct {

+    cmpCommandHeader_t cmdHeader;

+    mcSpid_t spid;

+    mcUuid_t uuid;

+} cmpTltActCmdSdata_t;

+

+typedef struct {

+    cmpTltActCmdSdata_t sdata;

+    cmpMac_t mac;

+} cmpTltContActivateCmd_t;

+

+/** TltContActivate command. */

+typedef struct {

+    cmpTltContActivateCmd_t cmd;

+    mcSoTltCont_t soTltCont;

+} cmpCmdTltContActivate_t;

+

+/** @} */ 

+

+/** @defgroup MC_CMP_CMD_TLT_CONT_ACTIVATE_RSP Response

+ * @{ */

+

+typedef struct {

+    mcSoTltCont_t soTltCont;

+} cmpTltActRspEdata_t;

+

+typedef struct {

+    cmpTltActRspEdata_t edata;

+    uint8_t padding[CMP_ED_PADDING(sizeof(cmpTltActRspEdata_t))];

+} cmpTltActRspEd_t;

+

+typedef struct {

+    cmpResponseHeader_t rspHeader;

+    cmpTltActRspEd_t ed;

+} cmpTltActRspSdata_t;

+

+typedef struct {

+    cmpTltActRspSdata_t sdata;

+    cmpMac_t mac;

+} cmpTltContActivateRsp_t;

+

+/** TltContActivate response. */

+typedef struct {

+    cmpTltContActivateRsp_t rsp;

+    mcSoTltCont_t soTltCont;

+} cmpRspTltContActivate_t;

+

+/** @} */ 

+

+/** @} */ 

+

+/** @defgroup MC_CMP_CMD_TLT_CONT_REGISTER_ACTIVATE 

+ * @{ */

+

+/** @defgroup MC_CMP_CMD_TLT_CONT_REGISTER_ACTIVATE_CMD Command

+ * @{ */

+

+typedef struct {

+    mcSymmetricKey_t kSpTltEnc;

+} cmpTltRegActMsgEdata_t;

+

+typedef struct {

+    cmpTltRegActMsgEdata_t edata;

+    uint8_t padding[CMP_ED_PADDING(sizeof(cmpTltRegActMsgEdata_t))];

+} cmpTltRegActCmdEd_t;

+

+typedef struct {

+    cmpCommandHeader_t cmdHeader;

+    mcSpid_t spid;

+    mcUuid_t uuid;

+    cmpTltRegActCmdEd_t ed;

+} cmpTltRegActCmdSdata_t;

+

+typedef struct {

+    cmpTltRegActCmdSdata_t sdata;

+    cmpMac_t mac;

+} cmpTltContRegisterActivateCmd_t;

+

+/** TltContRegisterActivate command. */

+typedef struct {

+    cmpTltContRegisterActivateCmd_t cmd;

+} cmpCmdTltContRegisterActivate_t;

+

+/** @} */ 

+

+/** @defgroup MC_CMP_CMD_TLT_CONT_REGISTER_ACTIVATE_RSP Response

+ * @{ */

+

+typedef struct {

+    mcSoSpCont_t soSpCont;

+    mcSoTltCont_t soTltCont;

+} cmpTltRegActRspEdata_t;

+

+typedef struct {

+    cmpTltRegActRspEdata_t edata;

+    uint8_t padding[CMP_ED_PADDING(sizeof(cmpTltRegActRspEdata_t))];

+} cmpTltRegActRspEd_t;

+

+typedef struct {

+    cmpResponseHeader_t rspHeader;

+    cmpTltRegActRspEd_t ed;

+} cmpTltRegActRspSdata_t;

+

+typedef struct {

+    cmpTltRegActRspSdata_t sdata;

+    cmpMac_t mac;

+} cmpTltContRegisterActivateRsp_t;

+

+/** TltContRegisterActivate response. */

+typedef struct {

+    cmpTltContRegisterActivateRsp_t rsp;

+    mcSoSpCont_t soSpCont;

+    mcSoTltCont_t soTltCont;

+} cmpRspTltContRegisterActivate_t;

+

+/** @} */ 

+

+/** @} */ 

+

+/** @defgroup MC_CMP_CMD_TLT_CONT_UNREGISTER

+ * @{ */

+

+/** @defgroup MC_CMP_CMD_TLT_CONT_UNREGISTER_CMD Command

+ * @{ */

+

+typedef struct {

+    cmpCommandHeader_t cmdHeader;

+    mcSpid_t spid;

+    mcUuid_t uuid;

+} cmpTltUnregCmdSdata_t;

+

+typedef struct {

+    cmpTltUnregCmdSdata_t sdata;

+    cmpMac_t mac;

+} cmpTltContUnregisterCmd_t;

+

+/** TltContUnregister command. */

+typedef struct {

+    cmpTltContUnregisterCmd_t cmd;

+} cmpCmdTltContUnregister_t;

+

+/** @} */ 

+

+/** @defgroup MC_CMP_CMD_TLT_CONT_UNREGISTER_RSP Response

+ * @{ */

+

+typedef struct {

+    mcSoSpCont_t soSpCont;

+} cmpTltUnregRspEdata_t;

+

+typedef struct {

+    cmpTltUnregRspEdata_t edata;

+    uint8_t padding[CMP_ED_PADDING(sizeof(cmpTltUnregRspEdata_t))];

+} cmpTltUnregRspEd_t;

+

+typedef struct {

+    cmpResponseHeader_t rspHeader;

+    cmpTltUnregRspEd_t ed;

+} cmpTltUnregRspSdata_t;

+

+typedef struct {

+    cmpTltUnregRspSdata_t sdata;

+    cmpMac_t mac;

+} cmpTltContUnregisterRsp_t;

+

+/** TltContUnregister response. */

+typedef struct {

+    cmpTltContUnregisterRsp_t rsp;

+    mcSoSpCont_t soSpCont;

+} cmpRspTltContUnregister_t;

+

+/** @} */ 

+

+/** @} */ 

+

+/** @defgroup MC_CMP_CMD_TLT_CONT_LOCK_BY_SP 

+ * @{ */

+

+/** @defgroup MC_CMP_CMD_TLT_CONT_LOCK_BY_SP_CMD Command

+ * @{ */

+

+typedef struct {

+    cmpCommandHeader_t cmdHeader;

+    mcSpid_t spid;

+    mcUuid_t uuid;

+} cmpTltLockBySpCmdSdata_t;

+

+typedef struct {

+    cmpTltLockBySpCmdSdata_t sdata;

+    cmpMac_t mac;

+} cmpTltContLockBySpCmd_t;

+

+/** TltContLockBySp command. */

+typedef struct {

+    cmpTltContLockBySpCmd_t cmd;

+    mcSoTltCont_t soTltCont;

+} cmpCmdTltContLockBySp_t;

+

+/** @} */ 

+

+/** @defgroup MC_CMP_CMD_TLT_CONT_LOCK_BY_SP_RSP Response

+ * @{ */

+

+typedef struct {

+    mcSoTltCont_t soTltCont;

+} cmpTltLockBySpRspEdata_t;

+

+typedef struct {

+    cmpTltLockBySpRspEdata_t edata;

+    uint8_t padding[CMP_ED_PADDING(sizeof(cmpTltLockBySpRspEdata_t))];

+} cmpTltLockBySpRspEd_t;

+

+typedef struct {

+    cmpResponseHeader_t rspHeader;

+    cmpTltLockBySpRspEd_t ed;

+} cmpTltLockBySpRspSdata_t;

+

+typedef struct {

+    cmpTltLockBySpRspSdata_t sdata;

+    cmpMac_t mac;

+} cmpTltContLockBySpRsp_t;

+

+/** TltContLockBySp response. */

+typedef struct {

+    cmpTltContLockBySpRsp_t rsp;

+    mcSoTltCont_t soTltCont;

+} cmpRspTltContLockBySp_t;

+

+/** @} */ 

+

+/** @} */ 

+

+/** @defgroup MC_CMP_CMD_TLT_CONT_UNLOCK_BY_SP 

+ * @{ */

+

+/** @defgroup MC_CMP_CMD_TLT_CONT_UNLOCK_BY_SP_CMD Command

+ * @{ */

+

+typedef struct {

+    cmpCommandHeader_t cmdHeader;

+    mcSpid_t spid;

+    mcUuid_t uuid;

+} cmpTltUnlockBySpCmdSdata_t;

+

+typedef struct {

+    cmpTltUnlockBySpCmdSdata_t sdata;

+    cmpMac_t mac;

+} cmpTltContUnlockBySpCmd_t;

+

+/** TltContUnlockBySp command. */

+typedef struct {

+    cmpTltContUnlockBySpCmd_t cmd;

+    mcSoTltCont_t soTltCont;

+} cmpCmdTltContUnlockBySp_t;

+

+/** @} */ 

+

+/** @defgroup MC_CMP_CMD_TLT_CONT_UNLOCK_BY_SP_RSP Response

+ * @{ */

+

+typedef struct {

+    mcSoTltCont_t soTltCont;

+} cmpTltUnlockBySpRspEdata_t;

+

+typedef struct {

+    cmpTltUnlockBySpRspEdata_t edata;

+    uint8_t padding[CMP_ED_PADDING(sizeof(cmpTltUnlockBySpRspEdata_t))];

+} cmpTltUnlockBySpRspEd_t;

+

+typedef struct {

+    cmpResponseHeader_t rspHeader;

+    cmpTltUnlockBySpRspEd_t ed;

+} cmpTltUnlockBySpRspSdata_t;

+

+typedef struct {

+    cmpTltUnlockBySpRspSdata_t sdata;

+    cmpMac_t mac;

+} cmpTltContUnlockBySpRsp_t;

+

+/** TltContUnlockBySp response. */

+typedef struct {

+    cmpTltContUnlockBySpRsp_t rsp;

+    mcSoTltCont_t soTltCont;

+} cmpRspTltContUnlockBySp_t;

+

+/** @} */

+

+/** @} */ 

+

+/** @defgroup MC_CMP_CMD_GET_SUID

+* @{ */

+

+/** @defgroup MC_CMP_CMD_GET_SUID_CMD Command

+* @{ */

+

+/** GetSuid command. */

+typedef struct {

+    cmpCommandHeader_t cmdHeader;

+} cmpCmdGetSuid_t;

+

+/** @} */ 

+

+/** @defgroup MC_CMP_CMD_GET_SUID_RSP Response

+* @{ */

+

+/** GetSuid response. */

+typedef struct {

+cmpResponseHeader_t rspHeader;

+    mcSuid_t suid;

+} cmpRspGetSuid_t;

+

+/** @} */

+

+/** @} */ 

+

+/** @defgroup MC_CMP_CMD_AUTHENTICATE_TERMINATE

+* @{ */

+

+/** @defgroup MC_CMP_CMD_AUTHENTICATE_TERMINATE_CMD Command

+* @{ */

+

+typedef struct {

+    cmpCommandHeader_t cmdHeader;

+} cmpAuthenticateTerminateCmdSdata_t;

+

+typedef struct {

+    cmpAuthenticateTerminateCmdSdata_t sdata;

+    cmpMac_t mac;

+} cmpAuthenticateTerminateCmd_t;

+

+/** AuthenticateTerminate command. */

+typedef struct {

+    cmpAuthenticateTerminateCmd_t cmd;

+} cmpCmdAuthenticateTerminate_t;

+

+/** @} */ 

+

+/** @defgroup MC_CMP_CMD_AUTHENTICATE_TERMINATE_RSP Response

+* @{ */

+

+typedef struct {

+    cmpResponseHeader_t rspHeader;

+} cmpAuthenticateTerminateRspSdata_t;

+

+typedef struct {

+    cmpAuthenticateTerminateRspSdata_t sdata;

+    cmpMac_t mac;

+} cmpTerminateAutenticateRsp_t;

+

+/** AuthenticateTerminate response. */

+typedef struct {

+    cmpTerminateAutenticateRsp_t rsp;

+} cmpRspAuthenticateTerminate_t;

+

+/** @} */

+

+/** @} */ 

+

+/** @defgroup MC_CMP_CMD_TLT_CONT_PERSONALIZE

+ * @{ */

+ 

+/** @defgroup MC_CMP_CMD_TLT_CONT_PERSONALIZE_CMD Command

+ * @{ */

+ 

+typedef struct {

+    mcPid_t pid;

+    mcCoDataCont_t persoData;

+} cmpTltContPersonalizeCmdEdata_t;

+

+typedef struct {

+    cmpTltContPersonalizeCmdEdata_t edata;

+    uint8_t padding_[CMP_ED_PADDING(sizeof(cmpTltContPersonalizeCmdEdata_t))];

+} cmpTltContPersonalizeCmdEd_t;

+

+typedef struct {

+    cmpCommandHeader_t cmdHeader;

+    mcSpid_t spid;

+    mcUuid_t uuid;

+    uint32_t edLen;

+    cmpTltContPersonalizeCmdEd_t ed;

+} cmpTltContPersonalizeCmdSdata_t;

+

+typedef struct {

+    cmpTltContPersonalizeCmdSdata_t sdata;

+    cmpMac_t mac_;

+} cmpTltContPersonalizeCmd_t;

+

+/** TltContPersonalize command. */

+typedef struct {

+    cmpTltContPersonalizeCmd_t cmd;

+    mcSoTltCont_t soTltCont_;

+} cmpCmdTltContPersonalize_t;

+

+/** @} */ 

+

+/** @defgroup MC_CMP_CMD_TLT_CONT_PERSONLIZE_RSP Response

+ * @{ */

+ 

+typedef struct {

+    mcSoDataCont_t soDataCont;

+} cmpTltContPersonalizeRspEdata_t;

+

+typedef struct {

+    cmpTltContPersonalizeRspEdata_t edata;

+    uint8_t padding_[CMP_ED_PADDING(sizeof(cmpTltContPersonalizeRspEdata_t))];

+} cmpTltContPersonalizeRspEd_t;

+

+typedef struct {

+    cmpResponseHeader_t rspHeader;

+    uint32_t edLen;

+    cmpTltContPersonalizeRspEd_t ed;

+} cmpTltContPersonalizeRspSdata_t;

+

+typedef struct {

+    cmpTltContPersonalizeRspSdata_t sdata;

+    cmpMac_t mac_;

+} cmpTltContPersonalizeRsp_t;

+

+/** TltContPersonalize response. */

+typedef struct {

+    cmpTltContPersonalizeRsp_t rsp;

+    mcSoDataCont_t soDataCont_;

+} cmpRspTltContPersonalize_t;

+

+

+/** @} */

+

+/** @} */

+

+

+#endif // CMP_H_

+

+/** @} */

+

diff --git a/V008/Android/external/mobicore/common/MobiCore/inc/TlCm/tlCmApi.h b/V008/Android/external/mobicore/common/MobiCore/inc/TlCm/tlCmApi.h
new file mode 100755
index 0000000..6428dd2
--- /dev/null
+++ b/V008/Android/external/mobicore/common/MobiCore/inc/TlCm/tlCmApi.h
@@ -0,0 +1,184 @@
+/** @addtogroup CMP
+ * @{
+ * @file
+ * Interface to content management trustlet definitions.
+ *
+ * The TlCm (Content Management Trustlet) is responsible for implementing
+ * CMP commands and generating approriate CMP responses.
+ *
+ * <!-- 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 TLCMAPI_H_
+#define TLCMAPI_H_
+
+#include "cmp.h"
+#include "tlCmError.h"
+
+/** TlCm command ids.
+ * List of all commands supported by TlCm.
+ * @note All command ids must be in range 0 to 0x7FFFFFFF.
+ */
+//lint -esym(756, cmpCommands_t) cmpCommands_t type by itself not used.
+typedef enum cmpCommands_t {
+    MC_CMP_CMD_AUTHENTICATE = 0,
+    MC_CMP_CMD_BEGIN_ROOT_AUTHENTICATION = 1,
+    MC_CMP_CMD_BEGIN_SOC_AUTHENTICATION = 2,
+    MC_CMP_CMD_BEGIN_SP_AUTHENTICATION = 3, 
+    MC_CMP_CMD_GENERATE_AUTH_TOKEN = 4,
+    MC_CMP_CMD_GET_VERSION = 5,
+//  MC_CMP_CMD_ROOT_CONT_ACTIVATE = 6,
+    MC_CMP_CMD_ROOT_CONT_LOCK_BY_ROOT = 7,
+//  MC_CMP_CMD_ROOT_CONT_REGISTER = 8,
+    MC_CMP_CMD_ROOT_CONT_REGISTER_ACTIVATE = 9,
+    MC_CMP_CMD_ROOT_CONT_UNLOCK_BY_ROOT = 10,
+    MC_CMP_CMD_ROOT_CONT_UNREGISTER = 11,
+    MC_CMP_CMD_SP_CONT_ACTIVATE = 12,
+    MC_CMP_CMD_SP_CONT_LOCK_BY_ROOT = 13,
+    MC_CMP_CMD_SP_CONT_LOCK_BY_SP = 14,
+    MC_CMP_CMD_SP_CONT_REGISTER = 15,
+    MC_CMP_CMD_SP_CONT_REGISTER_ACTIVATE = 16,
+    MC_CMP_CMD_SP_CONT_UNLOCK_BY_ROOT = 17,
+    MC_CMP_CMD_SP_CONT_UNLOCK_BY_SP = 18,
+    MC_CMP_CMD_SP_CONT_UNREGISTER = 19,
+    MC_CMP_CMD_TLT_CONT_ACTIVATE = 20,
+    MC_CMP_CMD_TLT_CONT_LOCK_BY_SP = 21,
+    MC_CMP_CMD_TLT_CONT_PERSONALIZE = 22,
+    MC_CMP_CMD_TLT_CONT_REGISTER = 23,
+    MC_CMP_CMD_TLT_CONT_REGISTER_ACTIVATE = 24,
+    MC_CMP_CMD_TLT_CONT_UNLOCK_BY_SP = 25,
+    MC_CMP_CMD_TLT_CONT_UNREGISTER = 26,
+    MC_CMP_CMD_GET_SUID = 27,
+    MC_CMP_CMD_AUTHENTICATE_TERMINATE = 28,
+    MC_CMP_CMD_LAST_ = MC_CMP_CMD_AUTHENTICATE_TERMINATE,
+} cmpCommands_t;
+
+/**
+ * CMP Content Manager message data.
+ */
+typedef union {
+    cmpCommandHeader_t commandHeader;
+    cmpResponseHeader_t responseHeader;
+
+    cmpCmdGetVersion_t cmpCmdGetVersion;
+    cmpRspGetVersion_t cmpRspGetVersion;
+
+    cmpCmdBeginSocAuthentication_t cmpCmdBeginSocAuthentication;
+    cmpRspBeginSocAuthentication_t cmpRspBeginSocAuthentication;
+
+    cmpCmdBeginRootAuthentication_t cmpCmdBeginRootAuthentication;
+    cmpRspBeginRootAuthentication_t cmpRspBeginRootAuthentication;
+
+    cmpCmdBeginSpAuthentication_t cmpCmdBeginSpAuthentication;
+    cmpRspBeginSpAuthentication_t cmpRspBeginSpAuthentication;
+
+    cmpCmdAuthenticate_t cmpCmdAuthenticate;
+    cmpRspAuthenticate_t cmpRspAuthenticate;
+
+    cmpCmdGenAuthToken_t cmpCmdGenAuthToken;
+    cmpRspGenAuthToken_t cmpRspGenAuthToken;
+
+    cmpCmdRootContRegisterActivate_t cmpCmdRootContRegisterActivate;
+    cmpRspRootContRegisterActivate_t cmpRspRootContRegisterActivate;
+
+    cmpCmdRootContUnregister_t cmpCmdRootContUnregister;
+    cmpRspRootContUnregister_t cmpRspRootContUnregister;
+
+    cmpCmdRootContLockByRoot_t cmpCmdRootContLockByRoot;
+    cmpRspRootContLockByRoot_t cmpRspRootContLockByRoot;
+
+    cmpCmdRootContUnlockByRoot_t cmpCmdRootContUnlockByRoot;
+    cmpRspRootContUnlockByRoot_t cmpRspRootContUnlockByRoot;
+
+    cmpCmdSpContRegisterActivate_t cmpCmdSpContRegisterActivate;
+    cmpRspSpContRegisterActivate_t cmpRspSpContRegisterActivate;
+
+    cmpCmdSpContUnregister_t cmpCmdSpContUnregister;
+    cmpRspSpContUnregister_t cmpRspSpContUnregister;
+
+    cmpCmdSpContLockByRoot_t cmpCmdSpContLockByRoot;
+    cmpRspSpContLockByRoot_t cmpRspSpContLockByRoot;
+
+    cmpCmdSpContUnlockByRoot_t cmpCmdSpContUnlockByRoot;
+    cmpRspSpContUnlockByRoot_t cmpRspSpContUnlockByRoot;
+
+    cmpCmdSpContLockBySp_t cmpCmdSpContLockBySp;
+    cmpRspSpContLockBySp_t cmpRspSpContLockBySp;
+
+    cmpCmdSpContUnlockBySp_t cmpCmdSpContUnlockBySp;
+    cmpRspSpContUnlockBySp_t cmpRspSpContUnlockBySp;
+
+    cmpCmdTltContRegister_t cmpCmdTltContRegister;
+    cmpRspTltContRegister_t cmpRspTltContRegister;
+
+    cmpCmdTltContActivate_t cmpCmdTltContActivate;
+    cmpRspTltContActivate_t cmpRspTltContActivate;
+
+    cmpCmdTltContRegisterActivate_t cmpCmdTltContRegisterActivate;
+    cmpRspTltContRegisterActivate_t cmpRspTltContRegisterActivate;
+
+    cmpCmdTltContLockBySp_t cmpCmdTltContLockBySp;
+    cmpRspTltContLockBySp_t cmpRspTltContLockBySp;
+
+    cmpCmdTltContUnlockBySp_t cmpCmdTltContUnlockBySp;
+    cmpRspTltContUnlockBySp_t cmpRspTltContUnlockBySp;
+
+    cmpCmdTltContUnregister_t cmpCmdTltContUnregister;
+    cmpRspTltContUnregister_t cmpRspTltContUnregister;
+
+    cmpCmdGetSuid_t cmpCmdGetSuid;
+    cmpRspGetSuid_t cmpRspGetSuid;
+
+    cmpCmdAuthenticateTerminate_t cmpCmdAuthenticateTerminate;
+    cmpRspAuthenticateTerminate_t cmpRspAuthenticateTerminate;
+
+    cmpCmdTltContPersonalize_t cmpCmdTltContPersonalize;
+    cmpRspTltContPersonalize_t cmpRspTltContPersonalize;
+
+    cmpCmdSpContRegister_t cmpCmdSpContRegister;
+    cmpRspSpContRegister_t cmpRspSpContRegister;
+
+    cmpCmdSpContActivate_t cmpCmdSpContActivate;
+    cmpRspSpContActivate_t cmpRspSpContActivate;
+} cmpMessage_t;
+
+/**
+ * Overall CMP structure.
+ */
+typedef struct {
+    /** CMP message. */
+    cmpMessage_t msg;
+} cmp_t;
+
+/**
+ * TlCm exit code: TlCm exited with error.
+ */
+#define EXIT_ERROR  ((uint32_t)(-1))
+
+#endif // TLCMAPI_H_
+
+/** @} */
diff --git a/V008/Android/external/mobicore/common/MobiCore/inc/TlCm/tlCmError.h b/V008/Android/external/mobicore/common/MobiCore/inc/TlCm/tlCmError.h
new file mode 100755
index 0000000..50ca41c
--- /dev/null
+++ b/V008/Android/external/mobicore/common/MobiCore/inc/TlCm/tlCmError.h
@@ -0,0 +1,62 @@
+/** @addtogroup CMP

+ * @{

+ *

+ * @file

+ * TlCm error return code definitions.

+ * Definition of all possible TlCm rror return codes.

+ *

+ * <!-- 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 TLCMERROR_H_

+#define TLCMERROR_H_

+

+#define  SUCCESSFUL                                  0x00000000

+

+#define RET_ERR_EXT_UNKNOWN_COMMAND                  0xE0000000

+#define RET_ERR_EXT_SECURITY_STATUS_NOT_SATISFIED    0xE0000010

+#define RET_ERR_EXT_SECURE_MESSAGING_FAILED          0xE0000020

+#define RET_ERR_EXT_INCORRECT_PARAMETERS             0xE0000030

+#define RET_ERR_EXT_REFERENCED_DATA_INVALID          0xE0000040

+#define RET_ERR_EXT_REFERENCED_DATA_NOT_FOUND        0xE0000050

+#define RET_ERR_EXT_METHOD_BLOCKED                   0xE0000060

+#define RET_ERR_EXT_CONDITIONS_OF_USE_NOT_SATISFIED  0xE0000070

+#define RET_ERR_EXT_DEVICE_ALREADY_BOUND             0xE0000080

+#define RET_ERR_EXT_ALREADY_REGISTERED               0xE0000090

+#define RET_ERR_EXT_ALREADY_ACTIVATED                0xE00000A0

+#define RET_ERR_EXT_NOT_REGISTERED                   0xE00000B0

+#define RET_ERR_EXT_NOT_ACTIVATED                    0xE00000C0

+#define RET_ERR_EXT_CONTAINER_FULL                   0xE00000D0

+#define RET_ERR_EXT_INTERNAL_ERROR                   0xE0001000

+

+#define RET_ERR_EXT_UNSPECIFIED                      0xEEEEEEEE

+

+#endif // TLCMERROR_H_

+

+/** @} */

+

+

diff --git a/V008/Android/external/mobicore/common/MobiCore/inc/TlCm/tlCmUuid.h b/V008/Android/external/mobicore/common/MobiCore/inc/TlCm/tlCmUuid.h
new file mode 100755
index 0000000..be5a27d
--- /dev/null
+++ b/V008/Android/external/mobicore/common/MobiCore/inc/TlCm/tlCmUuid.h
@@ -0,0 +1,42 @@
+/** @addtogroup CMP

+ * @{

+ * @file

+ * Content management trustlet UUID 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 TLCMUUID_H

+#define TLCMUUID_H

+

+/** UUID of content management trustlet. */

+#define TL_CM_UUID { { 7, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }

+

+#endif // TLCMUUID_H

+

+/** @} */

+

diff --git a/V008/Android/external/mobicore/common/MobiCore/inc/TlCm/version.h b/V008/Android/external/mobicore/common/MobiCore/inc/TlCm/version.h
new file mode 100644
index 0000000..0719dcb
--- /dev/null
+++ b/V008/Android/external/mobicore/common/MobiCore/inc/TlCm/version.h
@@ -0,0 +1,36 @@
+/** @addtogroup CMP
+ * <!-- 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 CMP_VERSION_H_
+#define CMP_VERSION_H_
+
+#define CMP_VERSION_MAJOR   2
+#define CMP_VERSION_MINOR   0
+
+#endif /** CMP_VERSION_H_ */
+
+
diff --git a/V008/Android/external/mobicore/common/MobiCore/inc/mcContainer.h b/V008/Android/external/mobicore/common/MobiCore/inc/mcContainer.h
new file mode 100755
index 0000000..82016cc
--- /dev/null
+++ b/V008/Android/external/mobicore/common/MobiCore/inc/mcContainer.h
@@ -0,0 +1,275 @@
+/** @addtogroup MC_CONTAINER mcContainer - Containers for MobiCore Content Management.

+ * @ingroup  MC_DATA_TYPES

+ * @{

+ *

+ * <!-- 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 MC_CONTAINER_H_

+#define MC_CONTAINER_H_

+

+#include <stdint.h>

+

+#include "mcRootid.h"

+#include "mcSpid.h"

+#include "mcUuid.h"

+#include "mcSo.h"

+#include "mcSuid.h"

+

+#define CONTAINER_VERSION_MAJOR   2

+#define CONTAINER_VERSION_MINOR   0

+

+#define MC_CONT_SYMMETRIC_KEY_SIZE      32 

+#define MC_CONT_PUBLIC_KEY_SIZE         320

+#define MC_CONT_CHILDREN_COUNT          16

+#define MC_DATA_CONT_MAX_DATA_SIZE      2048

+#define MC_TLT_CODE_HASH_SIZE           32

+

+#define MC_BYTES_TO_WORDS(bytes)       ( (bytes) / sizeof(uint32_t) )

+#define MC_ENUM_32BIT_SPACER           ((int32_t)-1)

+

+typedef uint32_t mcContVersion_t;

+

+/** Personalization Data ID. */

+typedef struct {

+    uint32_t data;

+} mcPid_t;

+

+typedef struct {

+    uint32_t keydata[MC_BYTES_TO_WORDS(MC_CONT_SYMMETRIC_KEY_SIZE)];

+} mcSymmetricKey_t;

+

+typedef struct {

+    uint32_t keydata[MC_BYTES_TO_WORDS(MC_CONT_PUBLIC_KEY_SIZE)];

+} mcPublicKey_t;

+

+typedef mcSpid_t spChild_t[MC_CONT_CHILDREN_COUNT];

+

+typedef mcUuid_t mcUuidChild_t[MC_CONT_CHILDREN_COUNT];

+

+/** Content management container states.

+ */

+typedef enum {

+     /** Container state unregistered. */

+     MC_CONT_STATE_UNREGISTERED = 0,

+     /** Container is registered. */

+     MC_CONT_STATE_REGISTERED = 1,

+     /** Container  is activated. */

+     MC_CONT_STATE_ACTIVATED = 2,

+     /** Container is locked by root. */

+     MC_CONT_STATE_ROOT_LOCKED = 3,

+     /** Container is locked by service provider. */

+     MC_CONT_STATE_SP_LOCKED = 4,

+     /** Container is locked by root and service provider. */

+     MC_CONT_STATE_ROOT_SP_LOCKED = 5,

+     /** Dummy: ensure that enum is 32 bits wide. */

+     MC_CONT_ATTRIB_SPACER = MC_ENUM_32BIT_SPACER

+} mcContainerState_t;

+

+/** Content management container attributes.

+ */

+typedef struct {

+    mcContainerState_t state;

+} mcContainerAttribs_t;

+

+/** Container types. */

+typedef enum {

+    /** SOC container. */

+    CONT_TYPE_SOC = 0,

+    /** Root container. */

+    CONT_TYPE_ROOT,

+    /** Service provider container. */

+    CONT_TYPE_SP,

+    /** Trustlet container. */

+    CONT_TYPE_TLCON,

+    /** Service provider data. */

+    CONT_TYPE_SPDATA,

+    /** Trustlet data. */

+    CONT_TYPE_TLDATA

+} contType_t;

+

+

+/** @defgroup MC_CONTAINER_CRYPTO_OBJECTS Container secrets.

+ * Data that is stored encrypted within the container.

+ * @{ */

+

+/** SoC secret */

+typedef struct {

+    mcSymmetricKey_t kSocAuth;

+} mcCoSocCont_t;

+

+/** */

+typedef struct {

+    mcSymmetricKey_t kRootAuth;

+} mcCoRootCont_t;

+

+/** */

+typedef struct {

+    mcSymmetricKey_t kSpAuth;

+} mcCoSpCont_t;

+

+/** */

+typedef struct {

+    mcSymmetricKey_t kTl;

+} mcCoTltCont_t;

+

+/** */

+typedef struct {

+    uint8_t data[MC_DATA_CONT_MAX_DATA_SIZE];

+} mcCoDataCont_t;

+

+/** */

+typedef union {

+    mcSpid_t spid;

+    mcUuid_t uuid;

+} mcCid_t;

+

+/** @} */

+

+/** @defgroup MC_CONTAINER_CONTAINER_OBJECTS Container definitions.

+ * Container type definitions.

+ * @{ */

+

+/** SoC Container */

+typedef struct {

+    contType_t type;

+    uint32_t version;

+    mcContainerAttribs_t attribs;

+    mcSuid_t suid;

+    // Secrets.

+    mcCoSocCont_t co;

+} mcSocCont_t;

+

+/** */

+typedef struct {

+    contType_t type;

+    uint32_t version;

+    mcContainerAttribs_t attribs;

+    mcSuid_t suid;

+    mcRootid_t rootid;

+    spChild_t children;

+    // Secrets.

+    mcCoRootCont_t co;

+} mcRootCont_t; 

+

+/** */

+typedef struct {

+    contType_t type;

+    uint32_t version;

+    mcContainerAttribs_t attribs;

+    mcSpid_t spid;

+    mcUuidChild_t children;

+    // Secrets.

+    mcCoSpCont_t co;

+} mcSpCont_t;

+

+/** */

+typedef struct {

+    contType_t type;

+    uint32_t version;

+    mcContainerAttribs_t attribs;

+    mcSpid_t parent;

+    mcUuid_t uuid;

+    // Secrets.

+    mcCoTltCont_t co;

+} mcTltCont_t;

+

+/** */

+typedef struct {

+    contType_t type;

+    uint32_t version;

+    mcUuid_t uuid;

+    mcPid_t pid;

+    // Secrets.

+    mcCoDataCont_t co;

+} mcDataCont_t;

+

+/** @} */

+

+/** Calculates the total size of the secure object hash and padding for a given

+ * container.

+ * @param contTotalSize Total size of the container (sum of plain and encrypted

+ * parts).

+ * @param contCoSize Size/length of the encrypted container part ("crypto

+ * object").

+ * @return Total size of hash and padding for given container.

+ */

+#define SO_CONT_HASH_AND_PAD_SIZE(contTotalSize, contCoSize) ( \

+    MC_SO_SIZE((contTotalSize) - (contCoSize), (contCoSize)) \

+        - sizeof(mcSoHeader_t) \

+        - (contTotalSize) )

+

+/** @defgroup MC_CONTAINER_SECURE_OBJECTS Containers in secure objects.

+ * Secure objects wrapping different containers.

+ * @{ */

+

+/** Authentication token */

+typedef struct {

+    mcSoHeader_t soHeader;

+    mcSocCont_t coSoc;

+    uint8_t hashAndPad[SO_CONT_HASH_AND_PAD_SIZE(sizeof(mcSocCont_t), sizeof(mcCoSocCont_t))];

+} mcSoAuthTokenCont_t;

+

+/** Root container */

+typedef struct {

+    mcSoHeader_t soHeader;

+    mcRootCont_t cont; 

+    uint8_t hashAndPad[SO_CONT_HASH_AND_PAD_SIZE(sizeof(mcRootCont_t), sizeof(mcCoRootCont_t))];

+} mcSoRootCont_t;

+

+/** */

+typedef struct {

+    mcSoHeader_t soHeader;

+    mcSpCont_t cont;

+    uint8_t hashAndPad[SO_CONT_HASH_AND_PAD_SIZE(sizeof(mcSpCont_t), sizeof(mcCoSpCont_t))];

+} mcSoSpCont_t;

+

+/** */

+typedef struct {

+    mcSoHeader_t soHeader;

+    mcTltCont_t cont;

+    uint8_t hashAndPad[SO_CONT_HASH_AND_PAD_SIZE(sizeof(mcTltCont_t), sizeof(mcCoTltCont_t))];

+} mcSoTltCont_t;

+

+/** */

+typedef struct {

+    mcSoHeader_t soHeader;

+    mcDataCont_t cont;

+    uint8_t hashAndPad[SO_CONT_HASH_AND_PAD_SIZE(sizeof(mcDataCont_t), sizeof(mcCoDataCont_t))];

+} mcSoDataCont_t; 

+

+/** */

+typedef struct {

+    mcSoRootCont_t soRoot;

+    mcSoSpCont_t soSp;

+    mcSoTltCont_t soTlt;

+} mcSoContainerPath_t;

+

+/** @} */

+

+#endif // MC_CONTAINER_H_

+

+/** @} */

diff --git a/V008/Android/external/mobicore/common/MobiCore/inc/mcDriverId.h b/V008/Android/external/mobicore/common/MobiCore/inc/mcDriverId.h
new file mode 100644
index 0000000..479e477
--- /dev/null
+++ b/V008/Android/external/mobicore/common/MobiCore/inc/mcDriverId.h
@@ -0,0 +1,64 @@
+/**

+ * @file

+ * Driver ID definition.

+ *

+ * <!-- Copyright Giesecke & Devrient GmbH 2011-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 RTMDRVID_H_

+#define RTMDRVID_H_

+

+#define MC_DRV_VENDOR_ID_SHIFT     (16)

+#define MC_DRV_VENDOR_ID_MASK      (0xFFFF << MC_DRV_VENDOR_ID_SHIFT)

+#define MC_DRV_NUMBER_MASK         (0x0000FFFF)

+

+/** MobiCore vendor IDs. */

+typedef enum {

+    MC_DRV_VENDOR_ID_GD   = 0 << MC_DRV_VENDOR_ID_SHIFT,

+} mcDrvVendorId_t;

+

+/** MobiCore GD driver numbers. */

+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. 

+     * GD driver numbers up to this constant may not be used for loadable drivers. */

+    MC_DRV_NUMBER_LAST_PRE_INSTALLED = 100,

+} 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. 

+     * 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,

+} mcDriverId_t;

+

+#endif /* RTMDRVID_H_ */

diff --git a/V008/Android/external/mobicore/common/MobiCore/inc/mcLoadFormat.h b/V008/Android/external/mobicore/common/MobiCore/inc/mcLoadFormat.h
new file mode 100644
index 0000000..76c22fb
--- /dev/null
+++ b/V008/Android/external/mobicore/common/MobiCore/inc/mcLoadFormat.h
@@ -0,0 +1,194 @@
+/**

+ * @defgroup MCLF   MobiCore Load Format

+ *

+ * @defgroup MCLF_VER    MCLF Versions

+ * @ingroup MCLF

+ *

+ * @addtogroup MCLF

+ * @{

+ *

+ * MobiCore Load Format declarations.

+ *

+ * Holds the definitions for the layout of MobiCore Trustlet Blob.

+ * <!-- 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 MCLOADFORMAT_H_

+#define MCLOADFORMAT_H_

+

+#include "mcUuid.h"

+#include "mcDriverId.h"

+

+#define MCLF_VERSION_MAJOR   2

+#define MCLF_VERSION_MINOR   1

+

+#define MC_SERVICE_HEADER_MAGIC_BE         ((uint32_t)('M'|('C'<<8)|('L'<<16)|('F'<<24))) /**< "MCLF" in big endian integer representation */

+#define MC_SERVICE_HEADER_MAGIC_LE         ((uint32_t)(('M'<<24)|('C'<<16)|('L'<<8)|'F')) /**< "MCLF" in little endian integer representation */

+#define MC_SERVICE_HEADER_MAGIC_STR         "MCLF"                                        /**< "MCLF" as string */

+

+/** @name MCLF flags */

+/*@{*/

+#define MC_SERVICE_HEADER_FLAGS_PERMANENT               (1U << 0) /**< Loaded service cannot be unloaded from MobiCore. */

+#define MC_SERVICE_HEADER_FLAGS_NO_CONTROL_INTERFACE    (1U << 1) /**< Service has no WSM control interface. */

+#define MC_SERVICE_HEADER_FLAGS_DEBUGGABLE              (1U << 2) /**< Service can be debugged. */

+/*@}*/

+

+#if !defined(ADDR_T_DEFINED)

+#define ADDR_T_DEFINED

+typedef void*    addr_t;                /**< an address, can be physical or virtual */

+#endif // !defined(ADDR_T_DEFINED)

+

+/** Service type.

+ * The service type defines the type of executable.

+ */

+typedef enum {

+    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. */

+} serviceType_t;

+

+/**

+ * Memory types.

+ */

+typedef enum {

+    MCLF_MEM_TYPE_INTERNAL_PREFERRED = 0, /**< If available use internal memory; otherwise external memory. */

+    MCLF_MEM_TYPE_INTERNAL = 1, /**< Internal memory must be used for executing the service. */

+    MCLF_MEM_TYPE_EXTERNAL = 2, /**< External memory must be used for executing the service. */

+} memType_t;

+

+/**

+ * Descriptor for a memory segment.

+ */

+typedef struct {

+    addr_t      start;  /**< Virtual start address. */

+    uint32_t    len;    /**< Length of the segment in bytes. */

+} segmentDescriptor_t, *segmentDescriptor_ptr;

+

+/**

+ * MCLF intro for data structure identification.

+ * Must be the first element of a valid MCLF file.

+ */

+typedef struct {

+    uint32_t        magic;      /**< Header magic value ASCII "MCLF". */

+    uint32_t        version;    /**< Version of the MCLF header structure. */

+} mclfIntro_t, *mclfIntro_ptr;

+

+/** @} */

+

+

+// Version 1 /////////////////////////////////////////////////////////////////////////////////////////////////////////

+/**

+ * @defgroup MCLF_VER_V1   MCLF Version 1

+ * @ingroup MCLF_VER

+ *

+ * @addtogroup MCLF_VER_V1

+ * @{

+ */

+

+/**

+ * Version 1 MCLF header.

+ */

+typedef struct {

+    mclfIntro_t             intro;           /**< MCLF header start with the mandatory intro. */

+    uint32_t                flags;           /**< Service flags. */

+    memType_t               memType;         /**< Type of memory the service must be executed from. */

+    serviceType_t           serviceType;     /**< Type of service. */

+

+    uint32_t                numInstances;    /**< Number of instances which can be run simultaneously. */

+    mcUuid_t                uuid;            /**< Loadable service unique identifier (UUID). */

+    mcDriverId_t            driverId;        /**< If the serviceType is SERVICE_TYPE_DRIVER the Driver ID is used. */

+    uint32_t                numThreads;      /**<

+                                              * <pre>

+                                              * <br>Number of threads (N) in a service depending on service type.<br>

+                                              *

+                                              *   SERVICE_TYPE_SP_TRUSTLET: N = 1

+                                              *   SERVICE_TYPE_SYSTEM_TRUSTLET: N = 1

+                                              *   SERVICE_TYPE_DRIVER: N >= 1

+                                              * </pre>

+                                              */

+    segmentDescriptor_t     text;           /**< Virtual text segment. */

+    segmentDescriptor_t     data;           /**< Virtual data segment. */

+    uint32_t                bssLen;         /**< Length of the BSS segment in bytes. MUST be at least 8 byte. */

+    addr_t                  entry;          /**< Virtual start address of service code. */

+} mclfHeaderV1_t, *mclfHeaderV1_ptr;

+/** @} */

+

+// Version 2 /////////////////////////////////////////////////////////////////////////////////////////////////////////

+/**

+ * @defgroup MCLF_VER_V2   MCLF Version 2

+ * @ingroup MCLF_VER

+ *

+ * @addtogroup MCLF_VER_V2

+ * @{

+ */

+

+/**

+ * Version 2 MCLF header.

+ */

+typedef struct {

+    mclfIntro_t             intro;           /**< MCLF header start with the mandatory intro. */

+    uint32_t                flags;           /**< Service flags. */

+    memType_t               memType;         /**< Type of memory the service must be executed from. */

+    serviceType_t           serviceType;     /**< Type of service. */

+

+    uint32_t                numInstances;    /**< Number of instances which can be run simultaneously. */

+    mcUuid_t                uuid;            /**< Loadable service unique identifier (UUID). */

+    mcDriverId_t            driverId;        /**< If the serviceType is SERVICE_TYPE_DRIVER the Driver ID is used. */

+    uint32_t                numThreads;      /**<

+                                              * <pre>

+                                              * <br>Number of threads (N) in a service depending on service type.<br>

+                                              *

+                                              *   SERVICE_TYPE_SP_TRUSTLET: N = 1

+                                              *   SERVICE_TYPE_SYSTEM_TRUSTLET: N = 1

+                                              *   SERVICE_TYPE_DRIVER: N >= 1

+                                              * </pre>

+                                              */

+    segmentDescriptor_t     text;           /**< Virtual text segment. */

+    segmentDescriptor_t     data;           /**< Virtual data segment. */

+    uint32_t                bssLen;         /**< Length of the BSS segment in bytes. MUST be at least 8 byte. */

+    addr_t                  entry;          /**< Virtual start address of service code. */

+    uint32_t                serviceVersion; /**< Version of the interface the driver exports. */

+} mclfHeaderV2_t, *mclfHeaderV2_ptr;

+/** @} */

+

+

+// Version 1 and 2 ///////////////////////////////////////////////////////////////////////////////////////////////////

+/**

+ * @addtogroup MCLF

+ * @{

+ */

+

+/** MCLF header */

+typedef union {

+    mclfIntro_t    intro;           /**< Intro for data structure identification. */

+    mclfHeaderV1_t mclfHeaderV1;    /**< Version 1 header */

+    mclfHeaderV2_t mclfHeaderV2;    /**< Version 2 header */

+} mclfHeader_t, *mclfHeader_ptr;

+

+#endif /* MCLOADFORMAT_H_ */

+

+/** @} */

diff --git a/V008/Android/external/mobicore/common/MobiCore/inc/mcRootid.h b/V008/Android/external/mobicore/common/MobiCore/inc/mcRootid.h
new file mode 100644
index 0000000..9b88e1d
--- /dev/null
+++ b/V008/Android/external/mobicore/common/MobiCore/inc/mcRootid.h
@@ -0,0 +1,54 @@
+/**
+ * @addtogroup MC_ROOTID mcRootid - Root container id.
+ *
+ * Global definition of root ID.
+ *
+ * <!-- Copyright Giesecke & Devrient GmbH 2011-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.
+ *
+ * @ingroup  MC_DATA_TYPES
+ * @{
+ */
+
+#ifndef MC_ROOTID_H_
+#define MC_ROOTID_H_
+
+/** Root Identifier type. */
+typedef uint32_t mcRootid_t;
+
+/** Reserved root id value 1. */
+static const mcRootid_t MC_ROOTID_RESERVED1 = 0;
+
+/** Reserved root id value 2. */
+static const mcRootid_t MC_ROOTID_RESERVED2 = 0xFFFFFFFF;
+
+/** Root id for system applications. */
+static const mcRootid_t MC_ROOTID_SYSTEM = 0xFFFFFFFE;
+
+#endif // MC_ROOTID_H_
+
+/** @} */
+
diff --git a/V008/Android/external/mobicore/common/MobiCore/inc/mcSo.h b/V008/Android/external/mobicore/common/MobiCore/inc/mcSo.h
new file mode 100755
index 0000000..7d1c595
--- /dev/null
+++ b/V008/Android/external/mobicore/common/MobiCore/inc/mcSo.h
@@ -0,0 +1,165 @@
+/**

+ * @defgroup MC_DATA_TYPES MobiCore generic data types

+ *

+ * @addtogroup MC_SO mcSo - Secure objects definitions.

+ * <!-- Copyright Giesecke & Devrient GmbH 2011-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.

+ *

+ * @ingroup  MC_DATA_TYPES

+ * @{

+ *

+ */

+

+#ifndef MC_SO_H_

+#define MC_SO_H_

+

+#include "mcUuid.h"

+#include "mcSpid.h"

+

+#define SO_VERSION_MAJOR   2

+#define SO_VERSION_MINOR   0

+

+#define MC_ENUM_32BIT_SPACER           ((int32_t)-1)

+

+/** Secure object type. */

+typedef enum {

+    /** Regular secure object. */

+    MC_SO_TYPE_REGULAR = 0x00000001,

+    /** Dummy to ensure that enum is 32 bit wide. */

+    MC_SO_TYPE_DUMMY = MC_ENUM_32BIT_SPACER,

+} mcSoType_t;

+

+

+/** Secure object context.

+ * A context defines which key to use to encrypt/decrypt a secure object.

+ */

+typedef enum {

+    /** Trustlet context. */

+    MC_SO_CONTEXT_TLT = 0x00000001,

+     /** Service provider context. */

+    MC_SO_CONTEXT_SP = 0x00000002,

+     /** Device context. */

+    MC_SO_CONTEXT_DEVICE = 0x00000003,

+    /** Dummy to ensure that enum is 32 bit wide. */

+    MC_SO_CONTEXT_DUMMY = MC_ENUM_32BIT_SPACER,

+} mcSoContext_t;

+

+/** Secure object lifetime.

+ * A lifetime defines how long a secure object is valid.

+ */

+typedef enum {

+    /** SO does not expire. */

+    MC_SO_LIFETIME_PERMANENT = 0x00000000,

+    /** SO expires on reboot (coldboot). */

+    MC_SO_LIFETIME_POWERCYCLE = 0x00000001,

+    /** SO expires when Trustlet is closed. */

+    MC_SO_LIFETIME_SESSION = 0x00000002,

+    /** Dummy to ensure that enum is 32 bit wide. */

+    MC_SO_LIFETIME_DUMMY = MC_ENUM_32BIT_SPACER,

+} mcSoLifeTime_t;

+

+/** Service provider Trustlet id.

+ * The combination of service provider id and Trustlet UUID forms a unique

+ * Trustlet identifier.

+ */

+typedef struct {

+    /** Service provider id. */

+    mcSpid_t spid;

+    /** Trustlet UUID. */

+    mcUuid_t uuid;

+} tlApiSpTrustletId_t;

+

+/** Secure object header.

+ * A secure object header introduces a secure object.

+ * Layout of a secure object:

+ * <pre>

+ * <code>

+ *

+ *     +--------+------------------+------------------+--------+---------+

+ *     | Header |   plain-data     |  encrypted-data  |  hash  | padding |

+ *     +--------+------------------+------------------+--------+---------+

+ *

+ *     /--------/---- plainLen ----/-- encryptedLen --/-- 32 --/- 1..16 -/

+ *

+ *     /----------------- toBeHashedLen --------------/

+ *

+ *                                 /---------- toBeEncryptedLen ---------/

+ *

+ *     /--------------------------- totalSoSize -------------------------/

+ *

+ * </code>

+ * </pre>

+ */

+typedef struct {

+    /** Type of secure object. */

+    uint32_t type;

+    /** Secure object version. */

+    uint32_t version;

+    /** Secure object context. */

+    mcSoContext_t context;

+    /** Secure object lifetime. */

+    mcSoLifeTime_t lifetime;

+    /** Producer Trustlet id. */

+    tlApiSpTrustletId_t producer;

+    /** Length of unencrypted user data (after the header). */

+    uint32_t plainLen;

+    /** Length of encrypted user data (after unencrypted data, excl. checksum

+     * and excl. padding bytes). */

+    uint32_t encryptedLen;

+} mcSoHeader_t;

+

+#endif // MC_SO_H_

+

+/** Maximum size of the payload (plain length + encrypted length) of a secure object. */

+#define MC_SO_PAYLOAD_MAX_SIZE      1000000

+

+/** Block size of encryption algorithm used for secure objects. */

+#define MC_SO_ENCRYPT_BLOCK_SIZE    16

+

+/** Maximum number of ISO padding bytes. */

+#define MC_SO_MAX_PADDING_SIZE (MC_SO_ENCRYPT_BLOCK_SIZE)

+

+/** Size of hash used for secure objects. */

+#define MC_SO_HASH_SIZE             32

+

+/** Calculates gross size of cryptogram within secure object including ISO padding bytes. */

+#define MC_SO_ENCRYPT_PADDED_SIZE(netsize) ( (netsize) + \

+    MC_SO_MAX_PADDING_SIZE - (netsize) % MC_SO_MAX_PADDING_SIZE )

+

+/** Calculates the total size of a secure object.

+ * @param plainLen Length of plain text part within secure object.

+ * @param encryptedLen Length of encrypted part within secure object (excl.

+ * hash, padding).

+ * @return Total (gross) size of the secure object or 0 if given parameters are

+ * illegal or would lead to a secure object of invalid size.

+ */

+#define MC_SO_SIZE(plainLen, encryptedLen) ( \

+    ((plainLen) + (encryptedLen) < (encryptedLen) || (plainLen) + (encryptedLen) > MC_SO_PAYLOAD_MAX_SIZE) ? 0 : \

+    sizeof(mcSoHeader_t) + (plainLen) + MC_SO_ENCRYPT_PADDED_SIZE((encryptedLen) + MC_SO_HASH_SIZE) \

+)

+

+/** @} */

+

diff --git a/V008/Android/external/mobicore/common/MobiCore/inc/mcSpid.h b/V008/Android/external/mobicore/common/MobiCore/inc/mcSpid.h
new file mode 100755
index 0000000..5ccf35e
--- /dev/null
+++ b/V008/Android/external/mobicore/common/MobiCore/inc/mcSpid.h
@@ -0,0 +1,53 @@
+/**

+ * @addtogroup MC_SPID mcSpid - service provider ID.

+ *

+ * <!-- Copyright Giesecke & Devrient GmbH 2011-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.

+ * @ingroup  MC_DATA_TYPES

+ * @{

+ */

+

+#ifndef MC_SPID_H_

+#define MC_SPID_H_

+

+/** Service provider Identifier type. */

+typedef uint32_t mcSpid_t;

+

+/** SPID value used as free marker in root containers. */

+static const mcSpid_t MC_SPID_FREE = 0xFFFFFFFF;

+

+/** Reserved SPID value. */

+static const mcSpid_t MC_SPID_RESERVED = 0;

+

+/** SPID for system applications. */

+static const mcSpid_t MC_SPID_SYSTEM = 0xFFFFFFFE;

+

+#endif // MC_SPID_H_

+

+/** @} */

+

+

+

diff --git a/V008/Android/external/mobicore/common/MobiCore/inc/mcSuid.h b/V008/Android/external/mobicore/common/MobiCore/inc/mcSuid.h
new file mode 100755
index 0000000..cddc993
--- /dev/null
+++ b/V008/Android/external/mobicore/common/MobiCore/inc/mcSuid.h
@@ -0,0 +1,53 @@
+/**

+ * @addtogroup MC_SUID mcSuid - SoC unique ID.

+ *

+ * <!-- Copyright Giesecke & Devrient GmbH 2011-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.

+ *

+ * @ingroup  MC_DATA_TYPES

+ * @{

+ */

+

+#ifndef MC_SUID_H_

+#define MC_SUID_H_

+

+/** Length of SUID. */

+#define MC_SUID_LEN    16

+

+/** Platform specific device identifier (serial number of the chip). */

+typedef struct {

+    uint8_t data[MC_SUID_LEN - sizeof(uint32_t)];

+} suidData_t;

+

+/** Soc unique identifier type. */

+typedef struct {

+    uint32_t    sipId;  /**< Silicon Provider ID to be set during build. */

+    suidData_t  suidData;

+} mcSuid_t;

+

+#endif // MC_SUID_H_

+

+/** @} */

diff --git a/V008/Android/external/mobicore/common/MobiCore/inc/mcUuid.h b/V008/Android/external/mobicore/common/MobiCore/inc/mcUuid.h
new file mode 100755
index 0000000..5d219bc
--- /dev/null
+++ b/V008/Android/external/mobicore/common/MobiCore/inc/mcUuid.h
@@ -0,0 +1,74 @@
+/**

+ * @addtogroup MC_UUID mcUuid - Universally Unique Identifier.

+ *

+ * <!-- Copyright Giesecke & Devrient GmbH 2011-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.

+ *

+ * @ingroup  MC_DATA_TYPES

+ * @{

+ */

+

+#ifndef MC_UUID_H_

+#define MC_UUID_H_

+

+#define UUID_TYPE

+

+/** Universally Unique Identifier (UUID) according to ISO/IEC 11578. */

+typedef struct {

+    uint8_t value[16]; /**< Value of the UUID. */

+} mcUuid_t, *mcUuid_ptr;

+

+/** UUID value used as free marker in service provider containers. */

+#define MC_UUID_FREE_DEFINE \

+    { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \

+      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }

+

+static const mcUuid_t MC_UUID_FREE = {

+    MC_UUID_FREE_DEFINE

+};

+

+/** Reserved UUID. */

+#define MC_UUID_RESERVED_DEFINE \

+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \

+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }

+

+static const mcUuid_t MC_UUID_RESERVED = {

+    MC_UUID_RESERVED_DEFINE

+};

+

+/** UUID for system applications. */

+#define MC_UUID_SYSTEM_DEFINE \

+    { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \

+      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE }

+

+static const mcUuid_t MC_UUID_SYSTEM = {

+    MC_UUID_SYSTEM_DEFINE

+};

+

+#endif // MC_UUID_H_

+

+/** @} */

+

diff --git a/V008/Android/external/mobicore/common/MobiCore/inc/mcVersionHelper.h b/V008/Android/external/mobicore/common/MobiCore/inc/mcVersionHelper.h
new file mode 100644
index 0000000..87e33b5
--- /dev/null
+++ b/V008/Android/external/mobicore/common/MobiCore/inc/mcVersionHelper.h
@@ -0,0 +1,194 @@
+/** @addtogroup MC_RTM
+ * @{
+ * MobiCore Version Helper Macros
+ *
+ * <!-- 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 <stdio.h>
+
+//lint -emacro(*,MC_CHECK_VERSION) Disable all warnings for this macro.
+//lint -emacro(*,MC_MAKE_VERSION) Disable all warnings for this macro.
+//lint -emacro(*,MC_GET_MAJOR_VERSION) Disable all warnings for this macro.
+//lint -emacro(*,MC_GET_MINOR_VERSION) Disable all warnings for this macro.
+//lint -emacro(*,MC_GET_MINOR_VERSION) Disable all warnings for this macro.
+//lint -emacro(*,ASSERT_VERSION_IMPLEMENTATION) Disable all warnings for this macro.
+//lint -esym(*,Actual_*) Disable all warnings for these functions.
+
+/** Create a version number given major and minor numbers. */
+#define MC_MAKE_VERSION(major,minor) \
+    (   (((major) & 0xffff) << 16) |\
+        ((minor) & 0xffff))
+
+/** Get major version number from complete version. */
+#define MC_GET_MAJOR_VERSION(version) ((version) >> 16)
+
+/** Get minor version number from complete version. */
+#define MC_GET_MINOR_VERSION(version) ((version) & 0xffff)
+
+// Asserts expression at compile-time (to be used outside a function body).
+#define ASSERT_VERSION_IMPLEMENTATION(comp, versionpart, requiredV, actualV, expression) \
+    extern int Actual_##comp##_##versionpart##_VERSION_##actualV##_does_not_match_required_version_##requiredV[(expression) ? 0:-1]
+
+#define ASSERT_VERSION_EVALUATOR(comp, versionpart, requiredV, actualV, expression) \
+        ASSERT_VERSION_IMPLEMENTATION(comp, versionpart, requiredV, actualV, expression)
+
+#define ASSERT_VERSION(required, comparator, comp, versionpart) \
+    ASSERT_VERSION_EVALUATOR(comp, versionpart, required, comp ##_VERSION_## versionpart, required comparator comp ##_VERSION_## versionpart)
+
+/** Checks at compile-time that an interface version provided by component
+ * 'comp' is identical to the required version of a component using this interface.
+ * Note! This check is useful for components that IMPLEMENT a particular
+ * interface to be alerted of changes to the interface which are likely to
+ * require adaptations in the implementation. */
+#define MC_CHECK_VERSION_EQUALS(comp, major, minor) \
+    ASSERT_VERSION(major, ==, comp, MAJOR); \
+    ASSERT_VERSION(minor, ==, comp, MINOR);
+
+/** Checks at compile-time that an interface version provided by component 'comp' meets the
+ * required version of a component using this interface. */
+#define MC_CHECK_VERSION_STATIC(comp, majorRequired, minorRequired) \
+    ASSERT_VERSION(majorRequired, ==, comp, MAJOR); \
+    ASSERT_VERSION(minorRequired, <=, comp, MINOR);
+
+/** Version check helper macro for an interface consumer against an interface
+ * provider.
+ * @param comp          Name of Interface to check.
+ * @param majorRequired Required major version of interface provider.
+ * @param minorRequired Required minor version of interface provider.
+ * Performs a compile-time interface version check that comp_VERSION_MAJOR
+ * equals majorRequired and that comp_VERSION_MINOR is at least minorRequired.
+ * On success, compilation goes through.
+ * On error, compilation breaks, telling the component that did not match in the
+ * error message.
+ *
+ * Additionally, a function is created:
+ *
+ * checkVersionOk##component(uint32_t version, char** errmsg)
+ *
+ * Compares version against majorRequired and minorRequired.
+ * Additionally, it creates a message string that can be printed out using printf("%s", errmsg).
+ * It returns either only the actual version, or on mismatch, actual and required version.
+ *
+ * @param version[in] component version as returned by layer-specific getVersion.
+ * @param errmsg[out] a message string that contains a log.
+ *
+ */
+#if !defined(NDEBUG)
+#define MC_CHECK_VERSION(comp, majorRequired, minorRequired) \
+    MC_CHECK_VERSION_STATIC(comp, majorRequired, minorRequired) \
+    static uint32_t checkVersionOk##comp(uint32_t version, char** errmsg) { \
+        static char msgBuf[100]; \
+        uint32_t major = MC_GET_MAJOR_VERSION(version); \
+        uint32_t minor = MC_GET_MINOR_VERSION(version); \
+        uint32_t ret = 0; \
+        *errmsg = msgBuf; \
+        if ((major == majorRequired) && (minor >= minorRequired)) { \
+            snprintf(msgBuf, sizeof(msgBuf), \
+                #comp " version is %u.%u", major, minor); \
+            ret = 1; \
+        } else { \
+            snprintf(msgBuf, sizeof(msgBuf), \
+                #comp " version error. Got: %u.%u, want >= %u.%u", major, minor, majorRequired, minorRequired); \
+        } \
+        msgBuf[sizeof(msgBuf) - 1] = '\0'; \
+        return ret; \
+    } 
+#else
+#define MC_CHECK_VERSION(comp, majorRequired, minorRequired) \
+    MC_CHECK_VERSION_STATIC(comp, majorRequired, minorRequired) \
+    static uint32_t checkVersionOk##comp(uint32_t version, char** errmsg) { \
+        uint32_t major = MC_GET_MAJOR_VERSION(version); \
+        uint32_t minor = MC_GET_MINOR_VERSION(version); \
+        *errmsg = NULL; \
+        if ((major == majorRequired) && (minor >= minorRequired)) { \
+            return 1; \
+        }; \
+        return 0; \
+    } 
+#endif
+
+/** Version check helper macro for version checks of a data object version
+ * against an data object consumer.
+ * 
+ * @param comp           Name of Interface to check.
+ * @param majorRequired Major data object version supported by component.
+ * @param minorRequired Minor data object version supported by component.
+ * Performs a compile-time interface version check that comp_VERSION_MAJOR
+ * equals majorRequired and that comp_VERSION_MINOR is at least minorRequired.
+ * On success, compilation goes through.
+ * On error, compilation breaks, telling the component that did not match in the
+ * error message.
+ *
+ * Additionally, the following function is created:
+ *
+ * checkVersionOkDataObject##component(uint32_t version, char** errmsg)
+ *
+ * This function checks that the data object version is compatible with the
+ * interface version; that is, the major version of the data object must match
+ * exactly and the minor version of the data object MUST BE LESS OR EQUAL to the
+ * required interface version.
+ * Additionally, it creates a message string that can be printed out using printf("%s", errmsg).
+ * It returns either only the actual version, or on mismatch, actual and
+ * provided version.
+ *
+ * @param version[in] Data object version of data object.
+ * @param errmsg[out] a message string that contains a log.
+ *
+ */
+#if !defined(NDEBUG)
+#define MC_CHECK_DATA_OBJECT_VERSION(comp, majorRequired, minorRequired) \
+    MC_CHECK_VERSION_STATIC(comp, majorRequired, minorRequired) \
+    static uint32_t checkVersionOkDataObject##comp(uint32_t version, char** errmsg) { \
+        static char msgBuf[100]; \
+        uint32_t major = MC_GET_MAJOR_VERSION(version); \
+        uint32_t minor = MC_GET_MINOR_VERSION(version); \
+        uint32_t ret = 0; \
+        *errmsg = msgBuf; \
+        if ((major == majorRequired) && (minor <= minorRequired)) { \
+            snprintf(msgBuf, sizeof(msgBuf), \
+                #comp " version is %u.%u", major, minor); \
+            ret = 1; \
+        } else { \
+            snprintf(msgBuf, sizeof(msgBuf), \
+                #comp " version error. Got: %u.%u, want <= %u.%u", major, minor, majorRequired, minorRequired); \
+        } \
+        msgBuf[sizeof(msgBuf) - 1] = '\0'; \
+        return ret; \
+    } 
+#else
+#define MC_CHECK_DATA_OBJECT_VERSION(comp, majorRequired, minorRequired) \
+    MC_CHECK_VERSION_STATIC(comp, majorRequired, minorRequired) \
+    static uint32_t checkVersionOkDataObject##comp(uint32_t version, char** errmsg) { \
+        uint32_t major = MC_GET_MAJOR_VERSION(version); \
+        uint32_t minor = MC_GET_MINOR_VERSION(version); \
+        *errmsg = NULL; \
+        if ((major == majorRequired) && (minor <= minorRequired)) { \
+            return 1; \
+        }; \
+        return 0; \
+    } 
+#endif
diff --git a/V008/Android/external/mobicore/common/MobiCore/inc/mcVersionInfo.h b/V008/Android/external/mobicore/common/MobiCore/inc/mcVersionInfo.h
new file mode 100644
index 0000000..1464e73
--- /dev/null
+++ b/V008/Android/external/mobicore/common/MobiCore/inc/mcVersionInfo.h
@@ -0,0 +1,52 @@
+/** @addtogroup MC_RTM
+ * @{
+ * MobiCore Version Information
+ *
+ * <!-- 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 MCVERSIONINFO_H_
+#define MCVERSIONINFO_H_
+
+/** Length of MobiCore product ID string. */
+#define MC_PRODUCT_ID_LEN 64
+
+/** Global MobiCore Version Information.
+ */
+typedef struct {
+    char productId[MC_PRODUCT_ID_LEN]; /** < Product ID of Mobicore; zero-terminated */
+    uint32_t versionMci;               /** < Version of Mobicore Control Interface */
+    uint32_t versionSo;                /** < Version of Secure Objects */
+    uint32_t versionMclf;              /** < Version of MobiCore Load Format */
+    uint32_t versionContainer;         /** < Version of MobiCore Container Format */
+    uint32_t versionMcConfig;          /** < Version of MobiCore Configuration Block Format */
+    uint32_t versionTlApi;             /** < Version of MobiCore Trustlet API Implementation */
+    uint32_t versionDrApi;             /** < Version of MobiCore Driver API Implementation */
+    uint32_t versionCmp;               /** < Version of Content Management Protocol */
+} mcVersionInfo_t;
+
+#endif /** MCVERSIONINFO_H_ */
diff --git a/V008/Android/external/mobicore/daemon/Android.mk b/V008/Android/external/mobicore/daemon/Android.mk
new file mode 100644
index 0000000..37a3fe3
--- /dev/null
+++ b/V008/Android/external/mobicore/daemon/Android.mk
@@ -0,0 +1,8 @@
+# =============================================================================
+#
+# Makefile pointing to all makefiles within the project.
+#
+# =============================================================================
+APP_PROJECT_PATH := $(call my-dir)
+# Including all Android.mk files from subdirectories
+include $(call all-subdir-makefiles)
diff --git a/V008/Android/external/mobicore/daemon/ClientLib/Android.mk b/V008/Android/external/mobicore/daemon/ClientLib/Android.mk
new file mode 100644
index 0000000..c2bf7e9
--- /dev/null
+++ b/V008/Android/external/mobicore/daemon/ClientLib/Android.mk
@@ -0,0 +1,47 @@
+# =============================================================================
+#
+# Module: libMcClient.so
+# 
+# C(version) Client Lib for Linux TLCs
+#
+# =============================================================================
+
+LOCAL_PATH	:= $(call my-dir)
+MY_CLIENTLIB_PATH	:= $(LOCAL_PATH)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE	:= libMcClient
+LOCAL_MODULE_TAGS := eng
+LOCAL_PRELINK_MODULE := false
+
+# External include files
+LOCAL_C_INCLUDES += bionic \
+	external/stlport/stlport
+
+# Add new folders with header files here
+LOCAL_C_INCLUDES +=\
+	$(LOCAL_PATH)/public \
+	$(APP_PROJECT_PATH) \
+	$(APP_PROJECT_PATH)/Daemon/public \
+	$(APP_PROJECT_PATH)/Kernel \
+	$(APP_PROJECT_PATH)/Kernel/Platforms/Generic \
+	$(APP_PROJECT_PATH)/Common
+
+# Add new folders with header files here
+LOCAL_C_INCLUDES +=\
+	$(COMP_PATH_MobiCore)/inc \
+	$(COMP_PATH_MobiCoreDriverMod)/Public
+
+# Add new source files here
+LOCAL_SRC_FILES +=\
+    Device.cpp\
+    ClientLib.cpp\
+    Session.cpp
+
+LOCAL_STATIC_LIBRARIES =  libstlport_static libMcKernel libMcCommon
+
+LOCAL_CPPFLAGS += -fno-rtti -fno-exceptions
+include $(COMP_PATH_Logwrapper)/Android.mk
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/V008/Android/external/mobicore/daemon/ClientLib/ClientLib.cpp b/V008/Android/external/mobicore/daemon/ClientLib/ClientLib.cpp
new file mode 100644
index 0000000..088169d
--- /dev/null
+++ b/V008/Android/external/mobicore/daemon/ClientLib/ClientLib.cpp
@@ -0,0 +1,1253 @@
+/** @addtogroup MCD_IMPL_LIB

+ * @{

+ * @file

+ *

+ * MobiCore Driver API.

+ *

+ * Functions for accessing MobiCore functionality from the normal world.

+ * Handles sessions and notifications via MCI buffer.

+ *

+ * <!-- 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 <stdint.h>

+#include <stdbool.h>

+#include <list>

+#include <cassert>

+

+#include "public/MobiCoreDriverApi.h"

+

+#include "mcDrvModuleApi.h"

+#include "Connection.h"

+#include "CMutex.h"

+#include "Device.h"

+#include "mcVersionHelper.h"

+

+#include "Daemon/public/MobiCoreDriverCmd.h"

+#include "Daemon/public/mcVersion.h"

+

+#define LOG_TAG	"McClient"

+#include "log.h"

+

+MC_CHECK_VERSION(DAEMON, 0, 2);

+

+/** Notification data structure. */

+typedef struct {

+	uint32_t sessionId; /**< Session ID. */

+	int32_t payload; /**< Additional notification information. */

+} notification_t;

+

+using namespace std;

+

+list<Device*> devices;

+

+// Forward declarations.

+static uint32_t getDaemonVersion(Connection* devCon);

+

+//------------------------------------------------------------------------------

+static Device *resolveDeviceId(

+    uint32_t deviceId

+) {

+    Device *ret = NULL;

+

+    // Get Session for sessionId

+    for (list<Device*>::iterator  iterator = devices.begin();

+         iterator != devices.end();

+         ++iterator)

+    {

+        Device  *device = (*iterator);

+

+        if (device->deviceId == deviceId)

+        {

+            ret = device;

+            break;

+        }

+    }

+    return ret;

+}

+

+

+//------------------------------------------------------------------------------

+static void addDevice(

+    Device *device

+) {

+    devices.push_back(device);

+}

+

+

+//------------------------------------------------------------------------------

+static bool removeDevice(

+    uint32_t deviceId

+) {

+    bool ret = false;

+

+    for (list<Device*>::iterator iterator = devices.begin();

+         iterator != devices.end();

+         ++iterator)

+    {

+        Device  *device = (*iterator);

+

+        if (device->deviceId == deviceId)

+        {

+            devices.erase(iterator);

+            delete device;

+            ret = true;

+            break;

+        }

+    }

+    return ret;

+}

+

+

+//------------------------------------------------------------------------------

+__MC_CLIENT_LIB_API mcResult_t mcOpenDevice(

+    uint32_t deviceId

+) {

+    mcResult_t mcResult = MC_DRV_OK;

+    static CMutex mutex;

+    Connection *devCon = NULL;

+

+    mutex.lock(); // Enter critical section

+

+    do

+    {

+        Device *device = resolveDeviceId(deviceId);

+        if (NULL != device)

+        {

+            LOG_E("mcOpenDevice(): Device %d already opened", deviceId);

+            mcResult = MC_DRV_ERR_INVALID_OPERATION;

+            break;

+        }

+

+        // Open new connection to device

+        devCon = new Connection();

+        if (!devCon->connect(SOCK_PATH))

+        {

+            LOG_E("mcOpenDevice(): Could not connect to %s", SOCK_PATH);

+            mcResult = MC_DRV_ERR_DAEMON_UNREACHABLE;

+            break;

+        }

+

+        // Runtime check of Daemon version.

+        char* errmsg;

+        if (!checkVersionOkDAEMON(getDaemonVersion(devCon), &errmsg)) {

+            LOG_E("%s", errmsg);

+            mcResult = MC_DRV_ERR_DAEMON_VERSION;

+            break;

+        }

+        LOG_I("%s", errmsg);

+

+        // Forward device open to the daemon and read result

+        mcDrvCmdOpenDevice_t mcDrvCmdOpenDevice = {

+            // C++ does not support C99 designated initializers

+                /* .header = */ {

+                    /* .commandId = */ MC_DRV_CMD_OPEN_DEVICE

+                },

+                /* .payload = */ {

+                    /* .deviceId = */ deviceId

+                }

+            };

+

+        int len = devCon->writeData(

+                            &mcDrvCmdOpenDevice,

+                            sizeof(mcDrvCmdOpenDevice));

+        if (len < 0)

+        {

+            LOG_E("mcOpenDevice(): CMD_OPEN_DEVICE writeCmd failed, ret=%d", len);

+            mcResult = MC_DRV_ERR_DAEMON_UNREACHABLE;

+            break;

+        }

+

+        mcDrvResponseHeader_t  rspHeader;

+        len = devCon->readData(

+                        &rspHeader,

+                        sizeof(rspHeader));

+        if (len != sizeof(rspHeader))

+        {

+            LOG_E("mcOpenDevice(): CMD_OPEN_DEVICE readRsp failed, ret=%d", len);

+            mcResult = MC_DRV_ERR_DAEMON_UNREACHABLE;

+            break;

+        }

+        if (MC_DRV_RSP_OK != rspHeader.responseId)

+        {

+            LOG_E("mcOpenDevice(): CMD_OPEN_DEVICE failed, respId=%d", rspHeader.responseId);

+            switch(rspHeader.responseId)

+            {

+            case MC_DRV_RSP_PAYLOAD_LENGTH_ERROR:

+            	mcResult = MC_DRV_ERR_DAEMON_UNREACHABLE;

+            	break;

+            case MC_DRV_INVALID_DEVICE_NAME:

+            	mcResult = MC_DRV_ERR_UNKNOWN_DEVICE;

+            	break;

+            case MC_DRV_RSP_DEVICE_ALREADY_OPENED:

+            default:

+            	mcResult = MC_DRV_ERR_INVALID_OPERATION;

+            	break;

+            }

+            break;

+        }

+

+        // there is no payload to read

+

+        device = new Device(deviceId, devCon);

+        if (!device->open(MC_DRV_MOD_DEVNODE_FULLPATH))

+        {

+            delete device;

+            // devCon is freed in the Device destructor

+            devCon = NULL;

+            LOG_E("mcOpenDevice(): could not open device file: %s", MC_DRV_MOD_DEVNODE_FULLPATH);

+            mcResult = MC_DRV_ERR_INVALID_DEVICE_FILE;

+            break;

+        }

+

+        addDevice(device);

+

+    } while (false);

+    

+    if (mcResult != MC_DRV_OK && devCon != NULL)

+    {

+        delete devCon;

+    }

+

+    mutex.unlock(); // Exit critical section

+

+    return mcResult;

+}

+

+

+//------------------------------------------------------------------------------

+__MC_CLIENT_LIB_API mcResult_t mcCloseDevice(

+    uint32_t deviceId

+) {

+    mcResult_t mcResult = MC_DRV_OK;

+    static CMutex mutex;

+

+    mutex.lock(); // Enter critical section

+    do

+    {

+        Device *device = resolveDeviceId(deviceId);

+        if (NULL == device)

+        {

+            LOG_E("mcCloseDevice(): Device not found");

+            mcResult = MC_DRV_ERR_UNKNOWN_DEVICE;

+            break;

+        }

+        Connection *devCon = device->connection;

+

+        // Return if not all sessions have been closed

+        if (device->hasSessions())

+        {

+            LOG_E("mcCloseDevice(): cannot close with sessions still pending");

+            mcResult = MC_DRV_ERR_SESSION_PENDING;

+            break;

+        }

+

+        mcDrvCmdCloseDevice_t mcDrvCmdCloseDevice = {

+            // C++ does not support C99 designated initializers

+                /* .header = */ {

+                    /* .commandId = */ MC_DRV_CMD_CLOSE_DEVICE

+                }

+            };

+        int len = devCon->writeData(

+                    &mcDrvCmdCloseDevice,

+                    sizeof(mcDrvCmdCloseDevice));

+        // ignore error, but log details

+        if (len < 0)

+        {

+            LOG_E("mcCloseDevice(): CMD_CLOSE_DEVICE writeCmd failed, ret=%d", len);

+            mcResult = MC_DRV_ERR_DAEMON_UNREACHABLE;

+        }

+

+        mcDrvResponseHeader_t  rspHeader;

+        len = devCon->readData(

+                        &rspHeader,

+                        sizeof(rspHeader));

+        if (len != sizeof(rspHeader))

+        {

+            LOG_E("mcCloseDevice(): CMD_CLOSE_DEVICE readResp failed, ret=%d", len);

+            mcResult = MC_DRV_ERR_DAEMON_UNREACHABLE;

+            break;

+        }

+

+        if (MC_DRV_RSP_OK != rspHeader.responseId)

+        {

+            LOG_E("mcCloseDevice(): CMD_CLOSE_DEVICE failed, respId=%d", rspHeader.responseId);

+            mcResult = MC_DRV_ERR_DAEMON_UNREACHABLE;

+            break;

+        }

+

+        removeDevice(deviceId);

+

+    } while (false);

+

+    mutex.unlock(); // Exit critical section

+

+    return mcResult;

+}

+

+

+//------------------------------------------------------------------------------

+__MC_CLIENT_LIB_API mcResult_t mcOpenSession(

+    mcSessionHandle_t  *session,

+    const mcUuid_t     *uuid,

+    uint8_t            *tci,

+    uint32_t           len

+) {

+    mcResult_t mcResult = MC_DRV_OK;

+    static CMutex mutex;

+

+    mutex.lock(); // Enter critical section

+

+    do

+    {

+        if (NULL == session)

+        {

+            LOG_E("mcOpenSession(): Session is null");

+            mcResult = MC_DRV_ERR_INVALID_PARAMETER;

+            break;

+        }

+        if (NULL == uuid)

+        {

+            LOG_E("mcOpenSession(): UUID is null");

+            mcResult = MC_DRV_ERR_INVALID_PARAMETER;

+            break;

+        }

+        if (NULL == tci)

+        {

+            LOG_E("mcOpenSession(): TCI is null");

+            mcResult = MC_DRV_ERR_INVALID_PARAMETER;

+            break;

+        }

+        if (len > MC_MAX_TCI_LEN)

+        {

+            LOG_E("mcOpenSession(): TCI length is longer than %d", MC_MAX_TCI_LEN);

+            mcResult = MC_DRV_ERR_INVALID_PARAMETER;

+            break;

+        }

+

+        // Get the device associated with the given session

+        Device *device = resolveDeviceId(session->deviceId);

+        if (NULL == device)

+        {

+            LOG_E("mcOpenSession(): Device not found");

+            mcResult = MC_DRV_ERR_UNKNOWN_DEVICE;

+            break;

+        }

+        Connection *devCon = device->connection;

+

+        // Get the physical address of the given TCI

+        CWsm_ptr pWsm = device->findContiguousWsm(tci);

+        if (NULL == pWsm)

+        {

+            LOG_E("mcOpenSession(): Could not resolve physical address of TCI");

+            mcResult = MC_DRV_ERR_INVALID_PARAMETER;

+            break;

+        }

+

+        if (pWsm->len < len)

+        {

+            LOG_E("mcOpenSession(): length is more than allocated TCI");

+            mcResult = MC_DRV_ERR_INVALID_PARAMETER;

+            break;

+        }

+

+        // Prepare open session command

+        mcDrvCmdOpenSession_t cmdOpenSession = {

+                // C++ does not support C99 designated initializers

+                    /* .header = */ {

+                        /* .commandId = */ MC_DRV_CMD_OPEN_SESSION

+                    },

+                    /* .payload = */ {

+                        /* .deviceId = */ session->deviceId,

+                        /* .uuid = */ *uuid,

+                        /* .tci = */ (uint32_t)pWsm->physAddr,

+                        /* .len = */ len

+                    }

+                };

+

+        // Transmit command data

+

+        int len = devCon->writeData(

+                            &cmdOpenSession,

+                            sizeof(cmdOpenSession));

+        if (sizeof(cmdOpenSession) != len)

+        {

+            LOG_E("mcOpenSession(): CMD_OPEN_SESSION writeData failed, ret=%d", len);

+            mcResult = MC_DRV_ERR_DAEMON_UNREACHABLE;

+            break;

+        }

+

+        // Read command response

+

+        // read header first

+        mcDrvResponseHeader_t rspHeader;

+        len = devCon->readData(

+                        &rspHeader,

+                        sizeof(rspHeader));

+        if (sizeof(rspHeader) != len)

+        {

+            LOG_E("mcOpenSession(): CMD_OPEN_SESSION readResp failed, ret=%d", len);

+            mcResult = MC_DRV_ERR_DAEMON_UNREACHABLE;

+            break;

+        }

+

+        if (MC_DRV_RSP_OK != rspHeader.responseId)

+        {

+            LOG_E("mcOpenSession(): CMD_OPEN_SESSION failed, respId=%d", rspHeader.responseId);

+            switch(rspHeader.responseId)

+            {

+            case MC_DRV_RSP_TRUSTLET_NOT_FOUND:

+            	mcResult = MC_DRV_ERR_INVALID_DEVICE_FILE;

+            	break;

+            case MC_DRV_RSP_PAYLOAD_LENGTH_ERROR:

+            case MC_DRV_RSP_DEVICE_NOT_OPENED:

+            case MC_DRV_RSP_FAILED:

+            default:

+            	mcResult = MC_DRV_ERR_DAEMON_UNREACHABLE;

+            	break;

+            }

+            break;

+        }

+

+        // read payload

+        mcDrvRspOpenSessionPayload_t rspOpenSessionPayload;

+        len = devCon->readData(

+                        &rspOpenSessionPayload,

+                        sizeof(rspOpenSessionPayload));

+        if (sizeof(rspOpenSessionPayload) != len)

+        {

+            LOG_E("mcOpenSession(): CMD_OPEN_SESSION readPayload failed, ret=%d", len);

+            mcResult = MC_DRV_ERR_DAEMON_UNREACHABLE;

+            break;

+        }

+

+        // Register session with handle

+        session->sessionId = rspOpenSessionPayload.sessionId;

+

+        // Set up second channel for notifications

+        Connection *sessionConnection = new Connection();

+        if (!sessionConnection->connect(SOCK_PATH))

+        {

+            LOG_E("mcOpenSession(): Could not connect to %s", SOCK_PATH);

+            delete sessionConnection;

+            mcResult = MC_DRV_ERR_DAEMON_UNREACHABLE;

+            break;

+        }

+

+        //TODO CONTINOUE HERE !!!! FIX RW RETURN HANDLING!!!!

+

+        // Write command to use channel for notifications

+        mcDrvCmdNqConnect_t cmdNqConnect = {

+                // C++ does not support C99 designated initializers

+                    /* .header = */ {

+                        /* .commandId = */ MC_DRV_CMD_NQ_CONNECT

+                    },

+                    /* .payload = */ {

+                            /* .deviceId =  */ session->deviceId,

+                            /* .sessionId = */ session->sessionId,

+                            /* .deviceSessionId = */ rspOpenSessionPayload.deviceSessionId,

+                            /* .sessionMagic = */ rspOpenSessionPayload.sessionMagic

+                    }

+                };

+        sessionConnection->writeData(

+                                &cmdNqConnect,

+                                sizeof(cmdNqConnect));

+

+

+        // Read command response, header first

+        len = sessionConnection->readData(

+                                    &rspHeader,

+                                    sizeof(rspHeader));

+        if (sizeof(rspHeader) != len)

+        {

+            LOG_E("mcOpenSession(): CMD_NQ_CONNECT readRsp failed, ret=%d", len);

+            delete sessionConnection;

+            mcResult = MC_DRV_ERR_DAEMON_UNREACHABLE;

+            break;

+        }

+

+        if (MC_DRV_RSP_OK != rspHeader.responseId)

+        {

+            LOG_E("mcOpenSession(): CMD_NQ_CONNECT failed, respId=%d", rspHeader.responseId);

+            delete sessionConnection;

+            mcResult = MC_DRV_ERR_NQ_FAILED;

+            break;

+        }

+

+        // there is no payload.

+

+        // Session has been established, new session object must be created

+        device->createNewSession(

+                    session->sessionId,

+                    sessionConnection);

+

+    } while (false);

+

+    mutex.unlock(); // Exit critical section

+

+    return mcResult;

+}

+

+

+//------------------------------------------------------------------------------

+__MC_CLIENT_LIB_API mcResult_t mcCloseSession(

+    mcSessionHandle_t *session

+) {

+    mcResult_t mcResult = MC_DRV_OK;

+    static CMutex mutex;

+

+    mutex.lock(); // Enter critical section

+

+    do

+    {

+        if (NULL == session)

+        {

+            LOG_E("mcCloseSession(): Session is null");

+            mcResult = MC_DRV_ERR_INVALID_PARAMETER;

+            break;

+        }

+

+        Device  *device = resolveDeviceId(session->deviceId);

+        if (NULL == device)

+        {

+            LOG_E("mcCloseSession(): Device not found");

+            mcResult = MC_DRV_ERR_UNKNOWN_DEVICE;

+            break;

+        }

+        Connection  *devCon = device->connection;

+

+        Session  *nqSession = device->resolveSessionId(session->sessionId);

+        if (NULL == nqSession)

+        {

+            LOG_E("mcCloseSession(): Session not found");

+            mcResult = MC_DRV_ERR_UNKNOWN_SESSION;

+            break;

+        }

+

+        // Write close session command

+        mcDrvCmdCloseSession_t cmdCloseSession = {

+                // C++ does not support C99 designated initializers

+                    /* .header = */ {

+                        /* .commandId = */ MC_DRV_CMD_CLOSE_SESSION

+                    },

+                    /* .payload = */ {

+                            /* .sessionId = */ session->sessionId,

+                    }

+                };

+        devCon->writeData(

+                            &cmdCloseSession,

+                            sizeof(cmdCloseSession));

+

+        // Read command response

+        mcDrvResponseHeader_t rspHeader;

+        int len = devCon->readData(

+                        &rspHeader,

+                        sizeof(rspHeader));

+        if (sizeof(rspHeader) != len)

+        {

+            LOG_E("mcCloseSession(): CMD_CLOSE_SESSION readRsp failed, ret=%d", len);

+            mcResult = MC_DRV_ERR_DAEMON_UNREACHABLE;

+            break;

+        }

+

+        if (MC_DRV_RSP_OK != rspHeader.responseId)

+        {

+            LOG_E("mcCloseSession(): CMD_CLOSE_SESSION failed, respId=%d", rspHeader.responseId);

+            mcResult = MC_DRV_ERR_UNKNOWN_DEVICE;

+            break;

+        }

+

+        bool r = device->removeSession(session->sessionId);

+        assert(r == true);

+        mcResult = MC_DRV_OK;

+

+    } while (false);

+

+    mutex.unlock(); // Exit critical section

+

+    return mcResult;

+}

+

+

+//------------------------------------------------------------------------------

+__MC_CLIENT_LIB_API mcResult_t mcNotify(

+    mcSessionHandle_t	*session

+) {

+    mcResult_t mcResult = MC_DRV_OK;

+    

+    LOG_I("===%s()===", __func__);

+

+    do

+    {

+        if (NULL == session)

+        {

+            LOG_E("mcNotify(): Session is null");

+            mcResult = MC_DRV_ERR_INVALID_PARAMETER;

+            break;

+        }

+

+        Device *device = resolveDeviceId(session->deviceId);

+        if (NULL == device)

+        {

+            LOG_E("mcNotify(): Device not found");

+            mcResult = MC_DRV_ERR_UNKNOWN_DEVICE;

+            break;

+        }

+        Connection  *devCon = device->connection;

+

+        Session  *nqsession = device->resolveSessionId(session->sessionId);

+        if (NULL == nqsession)

+        {

+            LOG_E("mcNotify(): Session not found");

+            mcResult = MC_DRV_ERR_UNKNOWN_SESSION;

+            break;

+        }

+

+        mcDrvCmdNotify_t cmdNotify = {

+                // C++ does not support C99 designated initializers

+                    /* .header = */ {

+                        /* .commandId = */ MC_DRV_CMD_NOTIFY

+                    },

+                    /* .payload = */ {

+                            /* .sessionId = */ session->sessionId,

+                    }

+                };

+

+        devCon->writeData(

+                    &cmdNotify,

+                    sizeof(cmdNotify));

+

+        // Daemon will not return a response

+

+    } while(false);

+

+    return mcResult;

+}

+

+

+//------------------------------------------------------------------------------

+__MC_CLIENT_LIB_API mcResult_t mcWaitNotification(

+    mcSessionHandle_t  *session,

+    int32_t            timeout

+) {

+    mcResult_t mcResult = MC_DRV_OK;

+    

+    LOG_I("===%s()===", __func__);

+

+    do

+    {

+        if (NULL == session)

+        {

+            mcResult = MC_DRV_ERR_INVALID_PARAMETER;

+            break;

+        }

+

+        Device  *device = resolveDeviceId(session->deviceId);

+        if (NULL == device)

+        {

+            LOG_E("mcWaitNotification(): Device not found");

+            mcResult = MC_DRV_ERR_UNKNOWN_DEVICE;

+            break;

+        }

+

+        Session  *nqSession = device->resolveSessionId(session->sessionId);

+        if (NULL == nqSession)

+        {

+            LOG_E("mcWaitNotification(): Session not found");

+            mcResult = MC_DRV_ERR_UNKNOWN_SESSION;

+            break;

+        }

+

+        Connection * nqconnection = nqSession->notificationConnection;

+        uint32_t count = 0;

+

+        // Read notification queue till it's empty

+        for(;;)

+        {

+            notification_t notification;

+            ssize_t numRead = nqconnection->readData(

+                                        &notification,

+                                        sizeof(notification_t),

+                                        timeout);

+            //Exit on timeout in first run

+            //Later runs have timeout set to 0. -2 means, there is no more data.

+            if (0 == count && -2 == numRead)

+            {

+                LOG_E("mcWaitNotification(): read timeout");

+                mcResult = MC_DRV_ERR_TIMEOUT;

+                break;

+            }

+            // After first notification the queue will be drained, Thus we set

+            // no timeout for the following reads

+            timeout = 0;

+

+            if (numRead != sizeof(notification_t))

+            {

+            	if (0 == count)

+                {

+                	//failure in first read, notify it

+                    mcResult = MC_DRV_ERR_NOTIFICATION;

+                    LOG_E("mcWaitNotification(): read notification failed, %i bytes received", (int)numRead);

+                    break;

+                }

+            	else

+            	{

+					// Read of the n-th notification failed/timeout. We don't tell the

+					// caller, as we got valid notifications before.

+					mcResult = MC_DRV_OK;

+					break;

+                }

+            }

+

+            count++;

+            LOG_I("mcWaitNotification(): readNq count=%d, SessionID=%d, Payload=%d",

+                   count, notification.sessionId, notification.payload);

+

+            if (0 != notification.payload)

+            {

+                // Session end point died -> store exit code

+                nqSession->setErrorInfo(notification.payload);

+

+                mcResult = MC_DRV_INFO_NOTIFICATION;

+                break;

+            }

+        } // for(;;)

+

+    } while (false);

+

+    return mcResult;

+}

+

+

+//------------------------------------------------------------------------------

+__MC_CLIENT_LIB_API mcResult_t mcMallocWsm(

+    uint32_t	deviceId,

+    uint32_t	align,

+    uint32_t	len,

+    uint8_t		**wsm,

+    uint32_t	wsmFlags

+) {

+    mcResult_t mcResult = MC_DRV_ERR_UNKNOWN;

+    static CMutex mutex;

+

+	LOG_I("===%s()===", __func__);

+

+    mutex.lock(); // Enter critical section

+

+    do

+    {

+        Device *device = resolveDeviceId(deviceId);

+        if (NULL == device)

+        {

+            LOG_E("mcMallocWsm(): Device not found");

+            mcResult = MC_DRV_ERR_UNKNOWN_DEVICE;

+            break;

+        }

+        if(NULL == wsm)

+        {

+        	mcResult = MC_DRV_ERR_INVALID_PARAMETER;

+        	break;

+        }

+

+        CWsm_ptr pWsm =  device->allocateContiguousWsm(len);

+        if (NULL == pWsm)

+        {

+            LOG_E("mcMallocWsm(): Allocation of WSM failed");

+            mcResult = MC_DRV_ERR_NO_FREE_MEMORY;

+            break;

+        }

+

+        *wsm = (uint8_t*)pWsm->virtAddr;

+        mcResult = MC_DRV_OK;

+

+    } while (false);

+

+    mutex.unlock(); // Exit critical section

+

+    return mcResult;

+}

+

+

+//------------------------------------------------------------------------------

+__MC_CLIENT_LIB_API mcResult_t mcFreeWsm(

+    uint32_t	deviceId,

+    uint8_t		*wsm

+) {

+    mcResult_t mcResult = MC_DRV_ERR_UNKNOWN;

+    Device *device;

+

+    static CMutex mutex;

+

+    LOG_I("===%s()===", __func__);

+

+    mutex.lock(); // Enter critical section

+

+    do {

+

+        // Get the device associated wit the given session

+        device = resolveDeviceId(deviceId);

+        if (NULL == device)

+        {

+            LOG_E("mcFreeWsm(): Device not found");

+            mcResult = MC_DRV_ERR_UNKNOWN_DEVICE;

+            break;

+        }

+

+        // find WSM object

+        CWsm_ptr pWsm = device->findContiguousWsm(wsm);

+        if (NULL == pWsm)

+        {

+            LOG_E("mcFreeWsm(): unknown address");

+            mcResult = MC_DRV_ERR_INVALID_PARAMETER;

+            break;

+        }

+

+        // Free the given virtual address

+        if (!device->freeContiguousWsm(pWsm))

+        {

+            LOG_E("mcFreeWsm(): Free of virtual address failed");

+            mcResult = MC_DRV_ERR_FREE_MEMORY_FAILED;

+            break;

+        }

+        mcResult = MC_DRV_OK;

+

+    } while (false);

+

+    mutex.unlock(); // Exit critical section

+

+    return mcResult;

+}

+

+//------------------------------------------------------------------------------

+__MC_CLIENT_LIB_API mcResult_t mcMap(

+    mcSessionHandle_t  *sessionHandle,

+    void               *buf,

+    uint32_t           bufLen,

+    mcBulkMap_t        *mapInfo

+) {

+    mcResult_t mcResult = MC_DRV_ERR_UNKNOWN;

+    static CMutex mutex;

+

+    mutex.lock(); // Enter critical section

+

+    do

+    {

+        if (NULL == sessionHandle)

+        {

+            LOG_E("mcMap(): sessionHandle is null");

+            mcResult = MC_DRV_ERR_INVALID_PARAMETER;

+            break;

+        }

+        if (NULL == mapInfo)

+        {

+            LOG_E("mcMap(): mapInfo is null");

+            mcResult = MC_DRV_ERR_INVALID_PARAMETER;

+            break;

+        }

+        if (NULL == buf)

+        {

+            LOG_E("mcMap(): buf is null");

+            mcResult = MC_DRV_ERR_INVALID_PARAMETER;

+            break;

+        }

+

+        // Determine device the session belongs to

+        Device  *device = resolveDeviceId(sessionHandle->deviceId);

+        if (NULL == device) {

+            LOG_E("mcMap(): Device not found");

+            mcResult = MC_DRV_ERR_UNKNOWN_DEVICE;

+            break;

+        }

+        Connection *devCon = device->connection;

+

+        // Get session

+        Session  *session = device->resolveSessionId(sessionHandle->sessionId);

+        if (NULL == session)

+        {

+            LOG_E("mcMap(): Session not found");

+            mcResult = MC_DRV_ERR_UNKNOWN_SESSION;

+            break;

+        }

+

+		// Workaround Linux memory handling

+		if (NULL != buf)

+		{

+			for (uint32_t i = 0; i < bufLen; i += 4096) {

+				volatile uint8_t x = ((uint8_t *) buf)[i]; x = x;

+			}

+		}

+

+        // Register mapped bulk buffer to Kernel Module and keep mapped bulk buffer in mind

+        BulkBufferDescriptor *bulkBuf = session->addBulkBuf(buf, bufLen);

+        if (NULL == bulkBuf)

+        {

+            LOG_E("mcMap(): Error mapping bulk buffer");

+            mcResult = MC_DRV_ERR_BULK_MAPPING;

+            break;

+        }

+

+

+        // Prepare map command

+        mcDrvCmdMapBulkMem_t mcDrvCmdMapBulkMem = {

+                // C++ does not support C99 designated initializers

+                    /* .header = */ {

+                        /* .commandId = */ MC_DRV_CMD_MAP_BULK_BUF

+                    },

+                    /* .payload = */ {

+                        /* .sessionId = */ session->sessionId,

+                        /* .pAddrL2 = */ (uint32_t)bulkBuf->physAddrWsmL2,

+                        /* .offsetPayload = */ (uint32_t)(bulkBuf->virtAddr) & 0xFFF,

+                        /* .lenBulkMem = */ bulkBuf->len

+                    }

+                };

+

+        // Transmit map command to MobiCore device

+        devCon->writeData(

+                    &mcDrvCmdMapBulkMem,

+                    sizeof(mcDrvCmdMapBulkMem));

+

+        // Read command response

+        mcDrvResponseHeader_t rspHeader;

+        int len = devCon->readData(

+                        &rspHeader,

+                        sizeof(rspHeader));

+        if (sizeof(rspHeader) != len)

+        {

+            LOG_E("mcMap(): CMD_MAP_BULK_BUF readRsp failed, ret=%d", len);

+            mcResult = MC_DRV_ERR_DAEMON_UNREACHABLE;

+            break;

+        }

+

+        if (MC_DRV_RSP_OK != rspHeader.responseId)

+        {

+            LOG_E("mcMap(): CMD_MAP_BULK_BUF failed, respId=%d", rspHeader.responseId);

+            // REV We ignore Daemon Error code because client cannot handle it anyhow.

+            mcResult = MC_DRV_ERR_DAEMON_UNREACHABLE;

+

+            // Unregister mapped bulk buffer from Kernel Module and remove mapped

+            // bulk buffer from session maintenance

+            if (!session->removeBulkBuf(buf))

+            {

+                // Removing of bulk buffer not possible

+                LOG_E("mcMap(): Unregistering of bulk memory from Kernel Module failed");

+            }

+            break;

+        }

+

+        mcDrvRspMapBulkMemPayload_t rspMapBulkMemPayload;

+        devCon->readData(

+                    &rspMapBulkMemPayload,

+                    sizeof(rspMapBulkMemPayload));

+

+        // Set mapping info for Trustlet

+        mapInfo->sVirtualAddr = (void *) (rspMapBulkMemPayload.secureVirtualAdr);

+        mapInfo->sVirtualLen = bufLen;

+        mcResult = MC_DRV_OK;

+

+    } while (false);

+

+    mutex.unlock(); // Exit critical section

+

+    return mcResult;

+}

+

+//------------------------------------------------------------------------------

+__MC_CLIENT_LIB_API mcResult_t mcUnmap(

+    mcSessionHandle_t  *sessionHandle,

+    void               *buf,

+    mcBulkMap_t        *mapInfo

+) {

+    mcResult_t mcResult = MC_DRV_ERR_UNKNOWN;

+    static CMutex mutex;

+

+    LOG_I("===%s()===", __func__);

+

+    mutex.lock(); // Enter critical section

+

+    do

+    {

+        if (NULL == sessionHandle)

+        {

+            LOG_E("mcUnmap(): sessionHandle is null");

+            mcResult = MC_DRV_ERR_INVALID_PARAMETER;

+            break;

+        }

+        if (NULL == mapInfo)

+        {

+            LOG_E("mcUnmap(): mapInfo is null");

+            mcResult = MC_DRV_ERR_INVALID_PARAMETER;

+            break;

+        }

+        if (NULL == buf)

+        {

+            LOG_E("mcUnmap(): buf is null");

+            mcResult = MC_DRV_ERR_INVALID_PARAMETER;

+            break;

+        }

+

+        // Determine device the session belongs to

+        Device  *device = resolveDeviceId(sessionHandle->deviceId);

+        if (NULL == device)

+        {

+            LOG_E("mcUnmap(): Device not found");

+            mcResult = MC_DRV_ERR_UNKNOWN_DEVICE;

+            break;

+        }

+        Connection  *devCon = device->connection;

+

+        // Get session

+        Session  *session = device->resolveSessionId(sessionHandle->sessionId);

+        if (NULL == session)

+        {

+            LOG_E("mcUnmap(): Session not found");

+            mcResult = MC_DRV_ERR_UNKNOWN_SESSION;

+            break;

+        }

+

+        // Prepare unmap command

+        mcDrvCmdUnmapBulkMem_t cmdUnmapBulkMem = {

+                // C++ does not support C99 designated initializers

+                    /* .header = */ {

+                        /* .commandId = */ MC_DRV_CMD_UNMAP_BULK_BUF

+                    },

+                    /* .payload = */ {

+                        /* .sessionId = */ session->sessionId,

+                        /* .secureVirtualAdr = */ (uint32_t)(mapInfo->sVirtualAddr),

+                        /* .lenBulkMem = mapInfo->sVirtualLen*/

+                    }

+                };

+

+        devCon->writeData(

+                    &cmdUnmapBulkMem,

+                    sizeof(cmdUnmapBulkMem));

+

+        // Read command response

+        mcDrvResponseHeader_t rspHeader;

+        int len = devCon->readData(

+                        &rspHeader,

+                        sizeof(rspHeader));

+        if (sizeof(rspHeader) != len)

+        {

+            LOG_E("mcUnmap(): CMD_UNMAP_BULK_BUF readRsp failed, ret=%d", len);

+            mcResult = MC_DRV_ERR_DAEMON_UNREACHABLE;

+            break;

+        }

+

+        if (MC_DRV_RSP_OK != rspHeader.responseId)

+        {

+            LOG_E("mcUnmap(): CMD_UNMAP_BULK_BUF failed, respId=%d", rspHeader.responseId);

+            // REV We ignore Daemon Error code because client cannot handle it anyhow.

+            mcResult = MC_DRV_ERR_DAEMON_UNREACHABLE;

+            break;

+        }

+

+        mcDrvRspUnmapBulkMemPayload_t rspUnmapBulkMemPayload;

+        devCon->readData(

+                    &rspUnmapBulkMemPayload,

+                    sizeof(rspUnmapBulkMemPayload));

+

+        // REV axh: what about check the payload?

+

+        // Unregister mapped bulk buffer from Kernel Module and remove mapped

+        // bulk buffer from session maintenance

+        if (!session->removeBulkBuf(buf))

+        {

+            // Removing of bulk buffer not possible

+            LOG_E("mcUnmap(): Unregistering of bulk memory from Kernel Module failed");

+            mcResult = MC_DRV_ERR_BULK_UNMAPPING;

+            break;

+        }

+

+        mcResult = MC_DRV_OK;

+

+    } while (false);

+

+    mutex.unlock(); // Exit critical section

+

+    return mcResult;

+}

+

+

+//------------------------------------------------------------------------------

+__MC_CLIENT_LIB_API mcResult_t mcGetSessionErrorCode(

+    mcSessionHandle_t	*session,

+    int32_t				*lastErr

+) {

+    mcResult_t mcResult = MC_DRV_OK;

+    

+    LOG_I("===%s()===", __func__);

+

+    do

+    {

+        if (NULL == session || NULL == lastErr)

+        {

+            mcResult = MC_DRV_ERR_INVALID_PARAMETER;

+            break;

+        }

+

+        // Get device

+        Device *device = resolveDeviceId(session->deviceId);

+        if (NULL == device)

+        {

+            LOG_E("mcGetSessionErrorCode(): Device not found");

+            mcResult = MC_DRV_ERR_UNKNOWN_DEVICE;

+            break;

+        }

+

+        // Get session

+        Session *nqsession = device->resolveSessionId(session->sessionId);

+        if (NULL == nqsession)

+        {

+            LOG_E("mcGetSessionErrorCode(): Session not found");

+            mcResult = MC_DRV_ERR_UNKNOWN_SESSION;

+            break;

+        }

+

+        // get session error code from session

+        *lastErr = nqsession->getLastErr();

+

+    } while (false);

+

+    return mcResult;

+}

+

+//------------------------------------------------------------------------------

+__MC_CLIENT_LIB_API mcResult_t mcDriverCtrl(

+    mcDriverCtrl_t  param,

+    uint8_t         *data,

+    uint32_t        len

+) {

+    LOG_W("mcDriverCtrl(): not implemented");

+    return MC_DRV_ERR_NOT_IMPLEMENTED;

+}

+

+//------------------------------------------------------------------------------

+__MC_CLIENT_LIB_API mcResult_t mcGetMobiCoreVersion(

+    uint32_t  deviceId,

+    mcVersionInfo_t* versionInfo

+) {

+    mcResult_t mcResult = MC_DRV_OK;

+

+    Device* device = resolveDeviceId(deviceId);

+    if (NULL == device) {

+        LOG_E("mcGetMobiCoreVersion(): Device not found");

+        return MC_DRV_ERR_UNKNOWN_DEVICE;

+    }

+

+    if (NULL == versionInfo) {

+        return MC_DRV_ERR_INVALID_PARAMETER;

+    }

+

+    Connection* devCon = device->connection;

+

+    mcDrvCmdGetMobiCoreVersion_t mcDrvCmdGetMobiCoreVersion = {

+        {

+            MC_DRV_CMD_GET_MOBICORE_VERSION,

+        }

+    };

+    int len = devCon->writeData(

+        &mcDrvCmdGetMobiCoreVersion,

+        sizeof(mcDrvCmdGetMobiCoreVersion));

+

+    if (len < 0) {

+        LOG_E("mcGetMobiCoreVersion(): MC_DRV_CMD_GET_MOBICORE_VERSION writeCmd failed, ret=%d", len);

+        return MC_DRV_ERR_DAEMON_UNREACHABLE;

+    }

+

+    // Read GET MOBICORE VERSION response.

+

+    // Read header first.

+    mcDrvResponseHeader_t rspHeader;

+    len = devCon->readData(&rspHeader, sizeof(rspHeader));

+    if (sizeof(rspHeader) != len) {

+        LOG_E("mcGetMobiCoreVersion(): MC_DRV_CMD_GET_MOBICORE_VERSION failed to respond, ret=%d", len);

+        return MC_DRV_ERR_DAEMON_UNREACHABLE;

+    }

+

+    if (MC_DRV_RSP_OK != rspHeader.responseId) {

+        LOG_E("mcGetMobiCoreVersion(): MC_DRV_CMD_GET_MOBICORE_VERSION bad response, respId=%d", rspHeader.responseId);

+        return MC_DRV_ERR_DAEMON_UNREACHABLE;

+    }

+

+    // Read payload.

+    mcDrvRspGetMobiCoreVersionPayload_t rspGetMobiCoreVersionPayload;

+    len = devCon->readData(&rspGetMobiCoreVersionPayload, sizeof(rspGetMobiCoreVersionPayload));

+    if (sizeof(rspGetMobiCoreVersionPayload) != len) {

+        LOG_E("mcGetMobiCoreVersion(): MC_DRV_CMD_GET_MOBICORE_VERSION readPayload failed, ret=%d", len);

+        return MC_DRV_ERR_DAEMON_UNREACHABLE;

+    }

+

+    *versionInfo = rspGetMobiCoreVersionPayload.versionInfo;

+

+    return mcResult;

+}

+

+

+//------------------------------------------------------------------------------

+static uint32_t getDaemonVersion(

+    Connection* devCon

+) {

+    assert(devCon != NULL);

+

+    // Send GET VERSION command to daemon.

+    mcDrvCmdGetVersion_t cmdGetVersion = {

+        {

+            MC_DRV_CMD_GET_VERSION,

+        },

+    };

+    int len = devCon->writeData(&cmdGetVersion, sizeof(cmdGetVersion));

+    if (sizeof(cmdGetVersion) != len) {

+        LOG_E("getDaemonVersion(): MC_DRV_CMD_GET_VERSION failed, ret=%d", len);

+        return 0;

+    }

+

+    // Read GET VERSION response.

+

+    // Read header first.

+    mcDrvResponseHeader_t rspHeader;

+    len = devCon->readData(&rspHeader, sizeof(rspHeader));

+    if (sizeof(rspHeader) != len) {

+        LOG_E("getDaemonVersion(): MC_DRV_CMD_GET_VERSION failed to respond, ret=%d", len);

+        return 0;

+    }

+

+    if (MC_DRV_RSP_OK != rspHeader.responseId) {

+        LOG_E("getDaemonVersion(): MC_DRV_CMD_GET_VERSION bad response, respId=%d", rspHeader.responseId);

+        return 0;

+    }

+

+    // Read payload.

+    mcDrvRspGetVersionPayload_t rspGetVersionPayload;

+    len = devCon->readData(&rspGetVersionPayload, sizeof(rspGetVersionPayload));

+    if (sizeof(rspGetVersionPayload) != len) {

+        LOG_E("getDaemonVersion(): MC_DRV_CMD_GET_VERSION readPayload failed, ret=%d", len);

+        return 0;

+    }

+

+    return rspGetVersionPayload.version;

+}

+

+/** @} */

diff --git a/V008/Android/external/mobicore/daemon/ClientLib/Device.cpp b/V008/Android/external/mobicore/daemon/ClientLib/Device.cpp
new file mode 100644
index 0000000..014c168
--- /dev/null
+++ b/V008/Android/external/mobicore/daemon/ClientLib/Device.cpp
@@ -0,0 +1,259 @@
+/** @addtogroup MCD_IMPL_LIB
+ * @{
+ * @file
+ *
+ * Client library device management.
+ *
+ * Device and Trustlet Session management Funtions.
+ *
+ * <!-- 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 <stdint.h>
+#include <vector>
+
+#include "mcDrvModuleApi.h"
+
+#include "Device.h"
+
+#define LOG_TAG	"McClientLib_Device"
+#include "log.h"
+
+
+//------------------------------------------------------------------------------
+Device::Device(
+    uint32_t    deviceId,
+    Connection  *connection
+) {
+	this->deviceId = deviceId;
+	this->connection = connection;
+
+	pMcKMod = new CMcKMod();
+}
+
+
+//------------------------------------------------------------------------------
+Device::~Device(
+    void
+) {
+	/* Delete all session objects. Usually this should not be needed as closeDevice()
+	 * requires that all sessions have been closed before.
+	 */
+	sessionIterator_t  sessionIterator = sessionList.begin();
+	while(sessionIterator != sessionList.end())
+	{
+		delete (*sessionIterator);
+		sessionIterator = sessionList.erase(sessionIterator);
+	}
+
+	// Free all allocated WSM descriptors
+	wsmIterator_t  wsmIterator = wsmL2List.begin();
+	while(wsmIterator != wsmL2List.end())
+	{
+	    CWsm_ptr pWsm = *wsmIterator;
+
+	    // ignore return code
+	    pMcKMod->free(pWsm->handle);
+
+	    delete (*wsmIterator);
+		wsmIterator = wsmL2List.erase(wsmIterator);
+	}
+	delete connection;
+	delete pMcKMod;
+}
+
+
+//------------------------------------------------------------------------------
+bool Device::open(
+    const char * deviceName
+) {
+	return pMcKMod->open(deviceName);
+}
+
+
+//------------------------------------------------------------------------------
+void Device::close(
+    void
+) {
+	pMcKMod->close();
+}
+
+
+//------------------------------------------------------------------------------
+bool Device::hasSessions(
+    void
+) {
+	return sessionList.size() > 0;
+}
+
+
+//------------------------------------------------------------------------------
+void Device::createNewSession(
+    uint32_t    sessionId,
+    Connection  *connection
+) {
+	Session *session = new Session(sessionId, pMcKMod, connection);
+	sessionList.push_back(session);
+}
+
+
+//------------------------------------------------------------------------------
+bool Device::removeSession(
+    uint32_t sessionId
+) {
+	bool ret = false;
+
+	sessionIterator_t interator = sessionList.begin();
+	while(interator != sessionList.end())
+	{
+		if ((*interator)->sessionId == sessionId)
+		{
+			delete (*interator);
+			interator = sessionList.erase(interator);
+			ret = true;
+			break;
+		}
+		else
+		{
+		    interator++;
+		}
+	}
+	return ret;
+}
+
+
+//------------------------------------------------------------------------------
+Session *Device::resolveSessionId(
+    uint32_t sessionId
+) {
+	Session  *ret = NULL;
+
+	// Get Session for sessionId
+	for ( sessionIterator_t interator = sessionList.begin();
+	      interator != sessionList.end();
+	      ++interator)
+    {
+		if ((*interator)->sessionId == sessionId) {
+			ret = (*interator);
+			break;
+		}
+	}
+	return ret;
+}
+
+
+//------------------------------------------------------------------------------
+CWsm_ptr Device::allocateContiguousWsm(
+    uint32_t len
+) {
+    CWsm_ptr  pWsm = NULL;
+	do
+	{
+	    if (0 == len)
+	    {
+		    break;
+	    }
+	    
+		// Allocate shared memory
+		addr_t    virtAddr;
+		uint32_t  handle;
+		addr_t    physAddr;
+		bool      mciReuse = false;
+		int ret = pMcKMod->mmap(
+							len,
+							&handle,
+							&virtAddr,
+							&physAddr,
+							&mciReuse);
+		if (0 != ret)
+		{
+			break;
+		}
+
+		// Register (vaddr,paddr) with device
+		pWsm = new CWsm(virtAddr,len,handle,physAddr);
+
+		wsmL2List.push_back(pWsm);
+		
+	} while(0);
+
+	// Return pointer to the allocated memory
+	return pWsm;
+}
+
+
+//------------------------------------------------------------------------------
+bool Device::freeContiguousWsm(
+    CWsm_ptr  pWsm
+) {
+	bool ret = false;
+	wsmIterator_t iterator;
+
+	for (iterator=wsmL2List.begin(); iterator!=wsmL2List.end(); ++iterator)
+	{
+	    if (pWsm == *iterator)
+	    {
+	        ret = true;
+	        break;
+	    }
+	}
+
+	if(ret) {
+		LOG_I("freeWsm virtAddr=0x%p, handle=%d",
+				pWsm->virtAddr,pWsm->handle);
+
+		// ignore return code
+		pMcKMod->free(pWsm->handle);
+
+		iterator = wsmL2List.erase(iterator);
+		delete pWsm;
+	}
+	return ret;
+}
+
+
+//------------------------------------------------------------------------------
+CWsm_ptr Device::findContiguousWsm(
+    addr_t  virtAddr
+) {
+    CWsm_ptr pWsm = NULL;
+
+	for( wsmIterator_t iterator=wsmL2List.begin();
+	     iterator!=wsmL2List.end();
+	     ++iterator)
+	{
+		CWsm_ptr pTmpWsm = *iterator;
+	    if (virtAddr == pTmpWsm->virtAddr)
+		{
+			pWsm = pTmpWsm;
+			break;
+		}
+	}
+
+	return pWsm;
+}
+
+/** @} */
diff --git a/V008/Android/external/mobicore/daemon/ClientLib/Device.h b/V008/Android/external/mobicore/daemon/ClientLib/Device.h
new file mode 100644
index 0000000..56d8fff
--- /dev/null
+++ b/V008/Android/external/mobicore/daemon/ClientLib/Device.h
@@ -0,0 +1,151 @@
+/** @addtogroup MCD_IMPL_LIB
+ * @{
+ * @file
+ *
+ * Client library device management.
+ *
+ * Device and Trustlet Session management Functions.
+ *
+ * <!-- 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 DEVICE_H_
+#define DEVICE_H_
+
+#include <stdint.h>
+#include <vector>
+
+#include "Session.h"
+#include "CWsm.h"
+
+
+class Device {
+
+private:
+	sessionList_t   sessionList; /**< MobiCore Trustlet session associated with the device */
+    wsmList_t       wsmL2List; /**< WSM L2 Table  */
+
+
+public:
+	uint32_t     deviceId; /**< Device identifier */
+	Connection   *connection; /**< The device connection */
+	CMcKMod_ptr  pMcKMod;
+
+	Device(
+	    uint32_t    deviceId,
+	    Connection  *connection
+	);
+
+	virtual ~Device(
+	    void
+	);
+
+	/**
+	 * Open the device.
+	 * @param deviceName Name of the kernel modules device file.
+	 * @return true if the device has been opened successfully
+	 */
+	bool open(
+	    const char * deviceName
+	);
+
+    /**
+     * Closes the device.
+     */
+    void close(
+        void
+    );
+
+	/**
+	 * Check if the device has open sessions.
+	 * @return true if the device has one or more open sessions.
+	 */
+	bool hasSessions(
+	    void
+	);
+
+	/**
+	 * Add a session to the device.
+	 * @param sessionId session ID
+	 * @param connection session connection
+	 */
+	void createNewSession(
+	    uint32_t    sessionId,
+	    Connection  *connection
+	);
+
+	/**
+	 * Remove the specified session from the device.
+	 * The session object will be destroyed and all resources associated with it will be freed.
+	 *
+	 * @param sessionId Session of the session to remove.
+	 * @return true if a session has been found and removed.
+	 */
+	bool removeSession(
+	    uint32_t sessionId
+	);
+
+	/**
+	 * Get as session object for a given session ID.
+	 * @param sessionId Identified of a previously opened session.
+	 * @return Session object if available or NULL if no session has been found.
+	 */
+	Session *resolveSessionId(
+	    uint32_t sessionId
+	);
+
+	/**
+	 * Allocate a block of contiguous WSM.
+	 * @param len The virtual address to be registered.
+	 * @return The virtual address of the allocated memory or NULL if no memory is available.
+	 */
+	CWsm_ptr allocateContiguousWsm(
+	    uint32_t len
+	);
+
+	/**
+	 * Unregister a vaddr from a device.
+	 * @param vaddr The virtual address to be registered.
+	 * @param paddr The physical address to be registered.
+	 */
+	bool freeContiguousWsm(
+	    CWsm_ptr  pWsm
+	);
+
+	/**
+	 * Get a WSM object for a given virtual address.
+	 * @param vaddr The virtual address which has been allocate with mcMallocWsm() in advance.
+	 * @return the WSM object or NULL if no address has been found.
+	 */
+	CWsm_ptr findContiguousWsm(
+	    addr_t  virtAddr
+	);
+
+};
+
+#endif /* DEVICE_H_ */
+
+/** @} */
diff --git a/V008/Android/external/mobicore/daemon/ClientLib/Session.cpp b/V008/Android/external/mobicore/daemon/ClientLib/Session.cpp
new file mode 100644
index 0000000..90425a6
--- /dev/null
+++ b/V008/Android/external/mobicore/daemon/ClientLib/Session.cpp
@@ -0,0 +1,207 @@
+/** @addtogroup MCD_IMPL_LIB
+ * @{
+ * @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 <stdint.h>
+#include <vector>
+
+#include "mcDrvModuleApi.h"
+
+#include "Session.h"
+
+#define LOG_TAG	"McClient"
+#include "log.h"
+
+
+//------------------------------------------------------------------------------
+Session::Session(
+    uint32_t    sessionId,
+    CMcKMod     *mcKMod,
+    Connection  *connection
+) {
+    this->sessionId = sessionId;
+    this->mcKMod = mcKMod;
+    this->notificationConnection = connection;
+
+    sessionInfo.lastErr = SESSION_ERR_NO;
+    sessionInfo.state = SESSION_STATE_INITIAL;
+}
+
+
+//------------------------------------------------------------------------------
+Session::~Session(
+    void
+) {
+    BulkBufferDescriptor  *pBlkBufDescr;
+
+    // Unmap still mapped buffers
+    for ( bulkBufferDescrIterator_t iterator = bulkBufferDescriptors.begin();
+          iterator != bulkBufferDescriptors.end();
+          ++iterator)
+    {
+        pBlkBufDescr = *iterator;
+
+        LOG_I("removeBulkBuf - Physical Address of L2 Table = 0x%X, handle= %d",
+                (unsigned int)pBlkBufDescr->physAddrWsmL2,
+                pBlkBufDescr->handle);
+
+        // ignore any error, as we cannot do anything in this case.
+        int ret = mcKMod->unregisterWsmL2(pBlkBufDescr->handle);
+        if (0 != ret)
+        {
+            LOG_E("removeBulkBuf(): mcKModUnregisterWsmL2 failed: %d",ret);
+        }
+
+        //iterator = bulkBufferDescriptors.erase(iterator);
+        delete(pBlkBufDescr);
+    }
+
+    // Finally delete notification connection
+    delete notificationConnection;
+}
+
+
+//------------------------------------------------------------------------------
+void Session::setErrorInfo(
+    int32_t err
+) {
+    sessionInfo.lastErr = err;
+}
+
+
+//------------------------------------------------------------------------------
+int32_t Session::getLastErr(
+    void
+) {
+    return sessionInfo.lastErr;
+}
+
+
+//------------------------------------------------------------------------------
+BulkBufferDescriptor* Session::addBulkBuf(
+    addr_t		buf,
+    uint32_t	len
+) {
+    BulkBufferDescriptor* blkBufDescr = NULL;
+
+    // Search bulk buffer descriptors for existing vAddr
+    // At the moment a virtual address can only be added one time
+    for ( bulkBufferDescrIterator_t iterator = bulkBufferDescriptors.begin();
+          iterator != bulkBufferDescriptors.end();
+          ++iterator
+    ) {
+        if ((*iterator)->virtAddr == buf)
+        {
+            return NULL;
+        }
+    }
+
+    do
+    {
+        // Prepare the interface structure for memory registration in Kernel Module
+        addr_t    pPhysWsmL2;
+        uint32_t  handle;
+
+        int ret = mcKMod->registerWsmL2(
+                    buf,
+                    len,
+                    0,
+                    &handle,
+                    &pPhysWsmL2);
+
+        if (0 != ret) {
+            LOG_E("mcKModRegisterWsmL2 failed, ret=%d",ret);
+            break;
+        }
+
+        LOG_I("addBulkBuf - Physical Address of L2 Table = 0x%X, handle=%d",
+                (unsigned int)pPhysWsmL2,
+                handle);
+
+        // Create new descriptor
+        blkBufDescr = new BulkBufferDescriptor(
+                            buf,
+                            len,
+                            handle,
+                            pPhysWsmL2);
+
+        // Add to vector of descriptors
+        bulkBufferDescriptors.push_back(blkBufDescr);
+    } while(0);
+
+    return blkBufDescr;
+}
+
+
+//------------------------------------------------------------------------------
+bool Session::removeBulkBuf(
+	addr_t	virtAddr
+) {
+    bool ret = true;
+    BulkBufferDescriptor  *pBlkBufDescr = NULL;
+
+    LOG_I("removeBulkBuf(): Virtual Address = 0x%X", (unsigned int) virtAddr);
+
+    // Search and remove bulk buffer descriptor
+    for ( bulkBufferDescrIterator_t iterator = bulkBufferDescriptors.begin();
+          iterator != bulkBufferDescriptors.end();
+          ++iterator
+    ) {
+
+        if ((*iterator)->virtAddr == virtAddr)
+        {
+            pBlkBufDescr = *iterator;
+            iterator = bulkBufferDescriptors.erase(iterator);
+            break;
+        }
+    }
+
+    if (NULL == pBlkBufDescr)
+    {
+        LOG_E("removeBulkBuf - Virtual Address not found");
+        ret = false;
+    }
+    else
+    {
+        LOG_I("removeBulkBuf(): WsmL2 phys=0x%X, handle=%d",
+        		(unsigned int)pBlkBufDescr->physAddrWsmL2, pBlkBufDescr->handle);
+
+        // ignore any error, as we cannot do anything
+        int ret = mcKMod->unregisterWsmL2(pBlkBufDescr->handle);
+        if (0 != ret)
+        {
+            LOG_E("removeBulkBuf(): mcKModUnregisterWsmL2 failed: %d",ret);
+        }
+
+        delete (pBlkBufDescr);
+    }
+
+    return ret;
+}
+
+/** @} */
diff --git a/V008/Android/external/mobicore/daemon/ClientLib/Session.h b/V008/Android/external/mobicore/daemon/ClientLib/Session.h
new file mode 100644
index 0000000..6b10d8f
--- /dev/null
+++ b/V008/Android/external/mobicore/daemon/ClientLib/Session.h
@@ -0,0 +1,167 @@
+/** @addtogroup MCD_IMPL_LIB
+ * @{
+ * @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 SESSION_H_
+#define SESSION_H_
+
+#include <stdint.h>
+#include <list>
+
+#include "mcDrvModuleApi.h"
+#include "Connection.h"
+#include "CMcKMod.h"
+
+
+class BulkBufferDescriptor{
+
+public:
+    addr_t    virtAddr; /**< The 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,
+        uint32_t  len,
+        uint32_t  handle,
+        addr_t    physAddrWsmL2
+    ) :
+        virtAddr(virtAddr),
+        len(len),
+        handle(handle),
+    physAddrWsmL2(physAddrWsmL2)
+    {};
+
+};
+
+typedef std::list<BulkBufferDescriptor*>  bulkBufferDescrList_t;
+typedef bulkBufferDescrList_t::iterator   bulkBufferDescrIterator_t;
+
+
+/** Session states.
+ * At the moment not used !!.
+ */
+typedef enum
+{
+	SESSION_STATE_INITIAL,
+	SESSION_STATE_OPEN,
+    SESSION_STATE_TRUSTLET_DEAD
+} sessionState_t;
+
+#define SESSION_ERR_NO      0 /**< No session error */
+
+/** Session information structure.
+ * The information structure is used to hold the state of the session, which will limit further actions for the session.
+ * Also the last error code will be stored till it's read.
+ */
+typedef struct {
+    sessionState_t state;       /**< Session state */
+	int32_t        lastErr;     /**< Last error of session */
+} sessionInformation_t;
+
+
+class Session {
+
+private:
+
+    CMcKMod                  *mcKMod;
+    bulkBufferDescrList_t    bulkBufferDescriptors; /**< Descriptors of additional bulk buffer of a session */
+	sessionInformation_t     sessionInfo; /**< Informations about session */
+
+public:
+
+	uint32_t    sessionId;
+	Connection  *notificationConnection;
+
+	Session(
+	    uint32_t     sessionId,
+	    CMcKMod      *mcKMod,
+	    Connection   *connection
+	);
+
+	virtual ~Session(
+	    void
+	);
+
+	/**
+	 * Add address information of additional bulk buffer memory to session and
+	 * register virtual memory in kernel module.
+	 *
+	 * @attention The virtual address can only be added one time. If the virtual address already exist, NULL is returned.
+	 *
+	 * @param buf The virtual address of bulk buffer.
+	 * @param len Length of bulk buffer.
+	 *
+	 * @return On success the actual Bulk buffer descriptor with all address information is retured, NULL if an error occurs.
+	 */
+	BulkBufferDescriptor * addBulkBuf(
+	    addr_t    buf,
+	    uint32_t  len
+	);
+
+	/**
+	 * Remove address information of additional bulk buffer memory from session and
+	 * unregister virtual memory in kernel module
+	 *
+	 * @param buf The virtual address of the bulk buffer.
+	 *
+	 * @return true on success.
+	 */
+	bool removeBulkBuf(
+	    addr_t	buf
+	);
+
+	/**
+	 * Set additional error information of the last error that occured.
+	 *
+	 * @param errorCode The actual error.
+	 */
+	void setErrorInfo(
+	    int32_t	err
+	);
+
+	/**
+	 * Get additional error information of the last error that occured.
+	 *
+	 * @attention After request the information is set to SESSION_ERR_NO.
+	 *
+	 * @return Last stored error code or SESSION_ERR_NO.
+	 */
+	int32_t getLastErr(
+	    void
+	);
+
+};
+
+typedef std::list<Session*>            sessionList_t;
+typedef sessionList_t::iterator        sessionIterator_t;
+
+#endif /* SESSION_H_ */
+
+/** @} */
diff --git a/V008/Android/external/mobicore/daemon/ClientLib/public/MobiCoreDriverApi.h b/V008/Android/external/mobicore/daemon/ClientLib/public/MobiCoreDriverApi.h
new file mode 100644
index 0000000..bb115ac
--- /dev/null
+++ b/V008/Android/external/mobicore/daemon/ClientLib/public/MobiCoreDriverApi.h
@@ -0,0 +1,420 @@
+/**

+ * @defgroup MCD_API                    MobiCore Driver API

+ * @addtogroup MCD_API

+ * @{

+ *

+ * @if DOXYGEN_MCDRV_API

+ *   @mainpage MobiCore Driver API.

+ * @endif

+ *

+ * MobiCore Driver API.

+ *

+ * The MobiCore (MC) Driver API provides access functions to the MobiCore runtime environment and the contained Trustlets.

+ *

+ * @image html DoxyOverviewDrvApi500x.png

+ * @image latex DoxyOverviewDrvApi500x.png "MobiCore Overview" width=12cm

+ *

+ * <!-- 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 MCDRIVER_H_

+#define MCDRIVER_H_

+

+#if (!defined(__MC_CLIENT_LIB_API)) && __cplusplus

+  #define __MC_CLIENT_LIB_API       extern "C"

+#else

+  #define __MC_CLIENT_LIB_API

+#endif // __cplusplus

+

+

+#include <stdint.h>

+#include <stdbool.h>

+

+#include "mcUuid.h"

+#include "mcVersionInfo.h"

+

+/**

+ * Return values of MobiCore driver functions.

+ */

+typedef enum

+{

+    MC_DRV_OK                       =  0, /**< Function call succeeded. */

+    MC_DRV_NO_NOTIFICATION          =  1, /**< No notification available. */

+    MC_DRV_ERR_NOTIFICATION         =  2, /**< Error during notification on communication level. */

+    MC_DRV_ERR_NOT_IMPLEMENTED      =  3, /**< Function not implemented. */

+    MC_DRV_ERR_OUT_OF_RESOURCES     =  4, /**< No more resources available. */

+    MC_DRV_ERR_INIT                 =  5, /**< Driver initialization failed. */

+    MC_DRV_ERR_UNKNOWN              =  6, /**< Unknown error. */

+    MC_DRV_ERR_UNKNOWN_DEVICE       =  7, /**< The specified device is unknown. */

+    MC_DRV_ERR_UNKNOWN_SESSION      =  8, /**< The specified session is unknown. */

+    MC_DRV_ERR_INVALID_OPERATION    =  9, /**< The specified operation is not allowed. */

+    MC_DRV_ERR_INVALID_RESPONSE     = 10, /**< The response header from the MC is invalid. */

+    MC_DRV_ERR_TIMEOUT              = 11, /**< Function call timed out. */

+    MC_DRV_ERR_NO_FREE_MEMORY       = 12, /**< Can not allocate additional memory. */

+    MC_DRV_ERR_FREE_MEMORY_FAILED   = 13, /**< Free memory failed. */

+    MC_DRV_ERR_SESSION_PENDING      = 14, /**< Still some open sessions pending. */

+    MC_DRV_ERR_DAEMON_UNREACHABLE   = 15, /**< MC daemon not reachable */

+    MC_DRV_ERR_INVALID_DEVICE_FILE  = 16, /**< The device file of the kernel module could not be opened. */

+    MC_DRV_ERR_INVALID_PARAMETER    = 17, /**< Invalid parameter. */

+    MC_DRV_ERR_KERNEL_MODULE        = 18, /**< Unspecified error from Kernel Module*/

+    MC_DRV_ERR_BULK_MAPPING         = 19, /**< Error during mapping of additional bulk memory to session. */

+    MC_DRV_ERR_BULK_UNMAPPING       = 20, /**< Error during unmapping of additional bulk memory to session. */

+    MC_DRV_INFO_NOTIFICATION        = 21, /**< Notification received, exit code available. */

+    MC_DRV_ERR_NQ_FAILED            = 22, /**< Set up of NWd connection failed. */

+    MC_DRV_ERR_DAEMON_VERSION       = 23, /**< Wrong daemon version. */

+    MC_DRV_ERR_CONTAINER_VERSION    = 24, /**< Wrong container version. */

+} mcResult_t;

+

+

+/**

+ * Driver control command.

+ */

+typedef enum {

+    MC_CTRL_DUMMY = 1 /**< Dummy. */

+} mcDriverCtrl_t;

+

+

+/** 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.

+ */

+typedef struct {

+	uint32_t sessionId; /**< MobiCore 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

+ * 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! */

+	uint32_t sVirtualLen;     	/**< Length of the mapped Bulk buffer */

+} mcBulkMap_t;

+

+

+#define MC_DEVICE_ID_DEFAULT       0 /**< The default device ID */

+#define MC_INFINITE_TIMEOUT        ((int32_t)(-1)) /**< Wait infinite for a response of the MC. */

+#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 */

+

+/* Mark only the following functions for export */

+#pragma GCC visibility push(default)

+

+/** Open a new connection to a MobiCore 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

+ * 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.

+ *

+ * @return MC_DRV_OK if operation has been successfully completed.

+ * @return MC_DRV_ERR_INVALID_OPERATION if device already opened.

+ * @return MC_DRV_ERR_DAEMON_UNREACHABLE when problems with daemon occur.

+ * @return MC_DRV_ERR_UNKNOWN_DEVICE when deviceId is unknown.

+ * @return MC_DRV_ERR_INVALID_DEVICE_FILE if kernel module under /dev/mobicore cannot be opened

+ *

+ * Uses a Mutex.

+ */

+__MC_CLIENT_LIB_API mcResult_t mcOpenDevice(

+    uint32_t deviceId

+);

+

+/** Close the connection to a MobiCore 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.

+ *

+ * @return MC_DRV_OK if operation has been successfully completed.

+ * @return MC_DRV_ERR_UNKNOWN_DEVICE when device id is invalid.

+ * @return MC_DRV_ERR_SESSION_PENDING when a session is still open.

+ * @return MC_DRV_ERR_DAEMON_UNREACHABLE when problems with daemon occur.

+ *

+ * Uses a Mutex.

+ */

+__MC_CLIENT_LIB_API mcResult_t mcCloseDevice(

+    uint32_t deviceId

+);

+

+/** Open a new session to a Trustlet. The trustlet 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).

+ *

+ * @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] tciLen Length of the TCI buffer. Maximum allowed value is MC_MAX_TCI_LEN.

+ *

+ * @return MC_DRV_OK if operation has been successfully completed.

+ * @return MC_DRV_INVALID_PARAMETER if session parameter is invalid.

+ * @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.

+ *

+ * Uses a Mutex.

+ */

+__MC_CLIENT_LIB_API mcResult_t mcOpenSession(

+    mcSessionHandle_t  *session,

+    const mcUuid_t       *uuid,

+    uint8_t            *tci,

+    uint32_t           tciLen

+);

+

+/** Close a Trustlet session.

+ *

+ * Closes the specified MobiCore session. The call will block until the session has been closed.

+ *

+ * @pre Device deviceId has to be opened in advance.

+ *

+ * @param [in] session Session to be closed.

+ *

+ * @return MC_DRV_OK if operation has been successfully completed.

+ * @return MC_DRV_INVALID_PARAMETER if session parameter is invalid.

+ * @return MC_DRV_ERR_UNKNOWN_SESSION when session id is invalid.

+ * @return MC_DRV_ERR_UNKNOWN_DEVICE when device id of session is invalid.

+ * @return MC_DRV_ERR_DAEMON_UNREACHABLE when problems with daemon occur.

+ * @return MC_DRV_ERR_INVALID_DEVICE_FILE when daemon cannot open trustlet file.

+ *

+ * Uses a Mutex.

+ */

+__MC_CLIENT_LIB_API mcResult_t mcCloseSession(

+    mcSessionHandle_t *session

+);

+

+/** Notify a session.

+ * Notifies the session end point about available message data.

+ * If the session parameter is correct, notify will always succeed.

+ * Corresponding errors can only be received by mcWaitNotification().

+ * @pre A session has to be opened in advance.

+ *

+ * @param session The session to be notified.

+ *

+ * @return MC_DRV_OK if operation has been successfully completed.

+ * @return MC_DRV_INVALID_PARAMETER if session parameter is invalid.

+ * @return MC_DRV_ERR_UNKNOWN_SESSION when session id is invalid.

+ * @return MC_DRV_ERR_UNKNOWN_DEVICE when device id of session is invalid.

+ */

+__MC_CLIENT_LIB_API mcResult_t mcNotify(

+    mcSessionHandle_t *session

+);

+

+/** Wait for a notification.

+ *

+ * Wait for a notification issued by the MobiCore 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.

+ *

+ * @attention if timeout is below 0, call will block:

+ * Caller has to trust the other side to send a notification to wake him up again.

+ *

+ * @param [in] session The session the notification should correspond to.

+ * @param [in] timeout Time in milliseconds to wait (MC_NO_TIMEOUT : direct return, > 0 : milliseconds, MC_INFINITE_TIMEOUT : wait infinitely)

+ *

+ * @return MC_DRV_OK if notification is available.

+ * @return MC_DRV_ERR_TIMEOUT if no notification arrived in time.

+ * @return MC_DRV_INFO_NOTIFICATION if a problem with the session was encountered. Get more details with mcGetSessionErrorCode().

+ * @return MC_DRV_ERR_NOTIFICATION if a problem with the socket occurred.

+ * @return MC_DRV_INVALID_PARAMETER if a parameter is invalid.

+ * @return MC_DRV_ERR_UNKNOWN_SESSION when session id is invalid.

+ * @return MC_DRV_ERR_UNKNOWN_DEVICE when device id of session is invalid.

+ */

+__MC_CLIENT_LIB_API mcResult_t mcWaitNotification(

+    mcSessionHandle_t  *session,

+    int32_t            timeout

+);

+

+/**

+ * Allocate a block of world shared memory (WSM).

+ * The MC driver allocates a contiguous block of memory which can be used as WSM.

+ * This implicates that the allocated memory is aligned according to the alignment parameter.

+ * 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]  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.

+ *

+ * @attention: align and wsmFlags are currently ignored

+ *

+ * @return MC_DRV_OK if operation has been successfully completed.

+ * @return MC_DRV_INVALID_PARAMETER if a parameter is invalid.

+ * @return MC_DRV_ERR_UNKNOWN_DEVICE when device id is invalid.

+ * @return MC_DRV_ERR_NO_FREE_MEMORY if no more contiguous memory is available in this size or for this process.

+ *

+ * Uses a Mutex.

+ */

+__MC_CLIENT_LIB_API mcResult_t mcMallocWsm(

+    uint32_t  deviceId,

+    uint32_t  align,

+    uint32_t  len,

+    uint8_t   **wsm,

+    uint32_t  wsmFlags

+);

+

+/**

+ * Free a block of world shared memory (WSM).

+ * The MC driver will free a block of world shared memory (WSM) previously allocated with

+ * mcMallocWsm(). The caller has to assure that the address handed over to the driver

+ * is a valid WSM address.

+ *

+ * @param [in] deviceId The ID to which the given address belongs.

+ * @param [in] wsm Address of WSM block to be freed.

+ *

+ * @return MC_DRV_OK if operation has been successfully completed.

+ * @return MC_DRV_INVALID_PARAMETER if a parameter is invalid.

+ * @return MC_DRV_ERR_UNKNOWN_DEVICE when device id is invalid.

+ * @return MC_DRV_ERR_FREE_MEMORY_FAILED on failures.

+ *

+ * Uses a Mutex.

+ */

+__MC_CLIENT_LIB_API mcResult_t mcFreeWsm(

+    uint32_t  deviceId,

+    uint8_t   *wsm

+);

+

+/**

+ * 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

+ * 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.

+ *

+ * @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] 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).

+ *

+ * @return MC_DRV_OK if operation has been successfully completed.

+ * @return MC_DRV_INVALID_PARAMETER if a parameter is invalid.

+ * @return MC_DRV_ERR_UNKNOWN_SESSION when session id is invalid.

+ * @return MC_DRV_ERR_UNKNOWN_DEVICE when device id of session is invalid.

+ * @return MC_DRV_ERR_DAEMON_UNREACHABLE when problems with daemon occur.

+ * @return MC_DRV_ERR_BULK_MAPPING when buf is already uses as bulk buffer or when registering the buffer failed.

+ *

+ * Uses a Mutex.

+ */

+__MC_CLIENT_LIB_API mcResult_t mcMap(

+    mcSessionHandle_t  *session,

+    void               *buf,

+    uint32_t           len,

+    mcBulkMap_t        *mapInfo

+);

+

+/**

+ * Remove additional mapped bulk buffer between Trustlet Connector (TLC) and the Trustlet (TL) 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!

+ *

+ * @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).

+ * @attention The clientlib currently ignores the len field in mapInfo.

+ *

+ * @return MC_DRV_OK if operation has been successfully completed.

+ * @return MC_DRV_INVALID_PARAMETER if a parameter is invalid.

+ * @return MC_DRV_ERR_UNKNOWN_SESSION when session id is invalid.

+ * @return MC_DRV_ERR_UNKNOWN_DEVICE when device id of session is invalid.

+ * @return MC_DRV_ERR_DAEMON_UNREACHABLE when problems with daemon occur.

+ * @return MC_DRV_ERR_BULK_UNMAPPING when buf was not registered earlier or when unregistering failed.

+ *

+ * Uses a Mutex.

+ */

+__MC_CLIENT_LIB_API mcResult_t mcUnmap(

+    mcSessionHandle_t  *session,

+    void               *buf,

+    mcBulkMap_t        *mapInfo

+);

+

+

+/**

+ * @attention: Not implemented.

+ * Execute driver specific command.

+ * mcDriverCtrl() can be used to execute driver specific commands.

+ * Besides the control command MC_CTRL_GET_VERSION commands are implementation specific.

+ * Please refer to the corresponding specification of the driver manufacturer.

+ *

+ * @param [in] param Command ID of the command to be executed.

+ * @param [in, out] data  Command data and response depending on command.

+ * @param [in] len Length of the data block.

+ *

+ * @return MC_DRV_ERR_NOT_IMPLEMENTED.

+ */

+__MC_CLIENT_LIB_API mcResult_t mcDriverCtrl(

+    mcDriverCtrl_t  param,

+    uint8_t         *data,

+    uint32_t        len

+);

+

+/**

+ * Get additional error information of the last error that occured 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).

+ * See also MCI definition.

+ *

+ * @return MC_DRV_OK if operation has been successfully completed.

+ * @return MC_DRV_INVALID_PARAMETER if a parameter is invalid.

+ * @return MC_DRV_ERR_UNKNOWN_SESSION when session id is invalid.

+ * @return MC_DRV_ERR_UNKNOWN_DEVICE when device id of session is invalid.

+ */

+__MC_CLIENT_LIB_API mcResult_t mcGetSessionErrorCode(

+    mcSessionHandle_t  *session,

+    int32_t            *lastErr

+);

+

+/**

+ * Get MobiCore version information of a device.

+ *

+ * @param [in] deviceId of an open device.

+ * @param [out] versionInfo MobiCore version info.

+ *

+ * @return MC_DRV_OK if operation has been successfully completed.

+ * @return MC_DRV_ERR_UNKNOWN_DEVICE when device is not open.

+ * @return MC_DRV_INVALID_PARAMETER if a parameter is invalid.

+ * @return MC_DRV_ERR_DAEMON_UNREACHABLE when problems with daemon occur.

+ */

+__MC_CLIENT_LIB_API mcResult_t mcGetMobiCoreVersion(

+    uint32_t  deviceId,

+    mcVersionInfo_t* versionInfo

+);

+#pragma GCC visibility pop

+#endif /** MCDRIVER_H_ */

+

+/** @} */

diff --git a/V008/Android/external/mobicore/daemon/Common/Android.mk b/V008/Android/external/mobicore/daemon/Common/Android.mk
new file mode 100644
index 0000000..1b6520c
--- /dev/null
+++ b/V008/Android/external/mobicore/daemon/Common/Android.mk
@@ -0,0 +1,33 @@
+# =============================================================================
+#
+# Module: libCommon.a - classes shared by various modules
+#
+# =============================================================================
+
+LOCAL_PATH	:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE	:= libMcCommon
+LOCAL_MODULE_TAGS := eng
+
+# Add new source files here
+LOCAL_SRC_FILES +=\
+	CMutex.cpp\
+	Connection.cpp\
+    NetlinkConnection.cpp\
+	CSemaphore.cpp\
+	CThread.cpp
+
+# Header files required by components including this module
+LOCAL_EXPORT_C_INCLUDES	:= $(LOCAL_PATH)
+LOCAL_EXPORT_CPPFLAGS += -fno-rtti -fno-exceptions
+
+LOCAL_C_INCLUDES += bionic \
+	external/stlport/stlport
+
+LOCAL_CPPFLAGS += -fno-rtti -fno-exceptions
+
+include $(COMP_PATH_Logwrapper)/Android.mk
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/V008/Android/external/mobicore/daemon/Common/CMutex.cpp b/V008/Android/external/mobicore/daemon/Common/CMutex.cpp
new file mode 100644
index 0000000..0ae95c8
--- /dev/null
+++ b/V008/Android/external/mobicore/daemon/Common/CMutex.cpp
@@ -0,0 +1,77 @@
+/** @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"
+
+
+//------------------------------------------------------------------------------
+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/V008/Android/external/mobicore/daemon/Common/CMutex.h b/V008/Android/external/mobicore/daemon/Common/CMutex.h
new file mode 100644
index 0000000..c6c1bc4
--- /dev/null
+++ b/V008/Android/external/mobicore/daemon/Common/CMutex.h
@@ -0,0 +1,63 @@
+/** @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/V008/Android/external/mobicore/daemon/Common/CSemaphore.cpp b/V008/Android/external/mobicore/daemon/Common/CSemaphore.cpp
new file mode 100644
index 0000000..2e7deea
--- /dev/null
+++ b/V008/Android/external/mobicore/daemon/Common/CSemaphore.cpp
@@ -0,0 +1,113 @@
+/** @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.
+ */
+#include <time.h>
+#include <limits.h>
+#include "CSemaphore.h"
+#include <stdio.h>
+
+//------------------------------------------------------------------------------
+CSemaphore::CSemaphore(int size) : m_waiters_count(0), m_count(size)  
+{
+	pthread_mutex_init(&m_mutex, NULL);
+	pthread_cond_init(&m_cond, NULL);
+}
+
+
+//------------------------------------------------------------------------------
+CSemaphore::~CSemaphore()
+{
+	pthread_mutex_destroy(&m_mutex);
+	pthread_cond_destroy(&m_cond);
+}
+
+
+//------------------------------------------------------------------------------
+void CSemaphore::wait()
+{
+	pthread_mutex_lock(&m_mutex);
+	m_waiters_count ++;
+	while( m_count == 0 )
+		pthread_cond_wait(&m_cond, &m_mutex);
+	m_waiters_count --;
+	m_count --;
+	pthread_mutex_unlock(&m_mutex);
+}
+
+//------------------------------------------------------------------------------
+bool CSemaphore::wait(int sec)
+{
+	int rc = 0;
+	struct timespec tm;
+	if(sec < 0)
+		sec = LONG_MAX;
+	clock_gettime(CLOCK_REALTIME, &tm);
+	tm.tv_sec += sec;
+	
+	pthread_mutex_lock(&m_mutex);
+	m_waiters_count ++;
+	if( m_count == 0 ) {
+		rc = pthread_cond_timedwait(&m_cond, &m_mutex, &tm);
+	}
+	m_waiters_count --;
+	// Decrement only if waiting actually succeeded, otherwise we
+	// just timed out
+	if (!rc)
+		m_count --;
+	pthread_mutex_unlock(&m_mutex);
+	return (rc == 0);
+}
+
+
+//------------------------------------------------------------------------------
+bool CSemaphore::wouldWait()
+{
+	bool ret = false;
+	pthread_mutex_lock(&m_mutex);
+	if( m_count == 0 )
+		ret = true;
+	pthread_mutex_unlock(&m_mutex);
+	return ret;
+}
+
+
+//------------------------------------------------------------------------------
+void CSemaphore::signal()
+{
+	pthread_mutex_lock(&m_mutex);
+	if( m_waiters_count > 0 )
+		pthread_cond_signal(&m_cond);
+	m_count ++;
+	pthread_mutex_unlock(&m_mutex);
+}
+
+/** @} */
diff --git a/V008/Android/external/mobicore/daemon/Common/CSemaphore.h b/V008/Android/external/mobicore/daemon/Common/CSemaphore.h
new file mode 100644
index 0000000..0739430
--- /dev/null
+++ b/V008/Android/external/mobicore/daemon/Common/CSemaphore.h
@@ -0,0 +1,70 @@
+/** @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/V008/Android/external/mobicore/daemon/Common/CThread.cpp b/V008/Android/external/mobicore/daemon/Common/CThread.cpp
new file mode 100644
index 0000000..1508c13
--- /dev/null
+++ b/V008/Android/external/mobicore/daemon/Common/CThread.cpp
@@ -0,0 +1,143 @@
+/** @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.
+ */
+#include "CThread.h"
+
+#define LOG_TAG	"McDaemon"
+#include "log.h"
+
+
+//------------------------------------------------------------------------------
+CThread::CThread(void) :
+	m_terminate(false), m_isExiting(false)
+{
+	m_sem = new CSemaphore();
+}
+
+
+//------------------------------------------------------------------------------
+CThread::~CThread(
+	void
+) {
+	delete m_sem;
+}
+
+
+//------------------------------------------------------------------------------
+void CThread::terminate(
+	void
+) {
+	m_terminate = true;
+}
+
+
+//------------------------------------------------------------------------------
+bool CThread::isExiting(
+	void
+) {
+    return m_isExiting;
+}
+
+
+//------------------------------------------------------------------------------
+void CThread::setExiting(
+	void
+) {
+    m_isExiting = true;
+}
+
+
+//------------------------------------------------------------------------------
+void CThread::exit(
+	int32_t exitcode
+) {
+    setExiting();
+    pthread_exit((void *)exitcode);
+}
+
+
+//------------------------------------------------------------------------------
+bool CThread::shouldTerminate(
+	void
+) {
+	return m_terminate;
+}
+
+
+//------------------------------------------------------------------------------
+void CThread::start(
+	void
+) {
+	int ret;
+	ret = pthread_create(&m_thread, NULL, CThreadStartup, this);
+	if (0 != ret)
+		LOG_E("pthread_create failed with error code %d", ret);
+}
+
+
+//------------------------------------------------------------------------------
+void CThread::join(
+	void
+) {
+	int ret;
+	ret = pthread_join(m_thread, NULL);
+	if (0 != ret)
+		LOG_E("pthread_join failed with error code %d", ret);
+}
+
+
+//------------------------------------------------------------------------------
+void CThread::sleep(
+	void
+) {
+	m_sem->wait();
+}
+
+
+//------------------------------------------------------------------------------
+void CThread::wakeup(
+	void
+) {
+	m_sem->signal();
+}
+
+
+//------------------------------------------------------------------------------
+void *CThreadStartup(
+	void *_tgtObject
+) {
+	CThread *tgtObject = (CThread *) _tgtObject;
+	tgtObject->run();
+	return NULL;
+}
+
+/** @} */
diff --git a/V008/Android/external/mobicore/daemon/Common/CThread.h b/V008/Android/external/mobicore/daemon/Common/CThread.h
new file mode 100644
index 0000000..be053bf
--- /dev/null
+++ b/V008/Android/external/mobicore/daemon/Common/CThread.h
@@ -0,0 +1,86 @@
+/** @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/V008/Android/external/mobicore/daemon/Common/CWsm.h b/V008/Android/external/mobicore/daemon/Common/CWsm.h
new file mode 100644
index 0000000..fca489f
--- /dev/null
+++ b/V008/Android/external/mobicore/daemon/Common/CWsm.h
@@ -0,0 +1,70 @@
+/** @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,

+        addr_t    physAddr = NULL // this may be unknown, so is can be omitted.

+    ) :

+        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/V008/Android/external/mobicore/daemon/Common/Connection.cpp b/V008/Android/external/mobicore/daemon/Common/Connection.cpp
new file mode 100644
index 0000000..d0a2746
--- /dev/null
+++ b/V008/Android/external/mobicore/daemon/Common/Connection.cpp
@@ -0,0 +1,200 @@
+/** @addtogroup MCD_MCDIMPL_DAEMON_SRV

+ * @{

+ * @file

+ *

+ * Connection data.

+ *

+ * <!-- 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 <unistd.h>

+#include <assert.h>

+#include <cstring>

+#include <errno.h>

+

+#include "Connection.h"

+

+#define LOG_TAG	"McClient"

+#include "log.h"

+

+

+//------------------------------------------------------------------------------

+Connection::Connection(

+    void

+) {

+	connectionData = NULL;

+	// Set invalid socketDescriptor

+	socketDescriptor = -1;

+}

+

+

+//------------------------------------------------------------------------------

+Connection::Connection(

+    int           socketDescriptor,

+    sockaddr_un   *remote

+) {

+	assert(NULL != remote);

+	assert(-1 != socketDescriptor);

+

+	this->socketDescriptor = socketDescriptor;

+	this->remote = *remote;

+	connectionData = NULL;

+}

+

+

+//------------------------------------------------------------------------------

+Connection::~Connection(

+    void

+) {

+	LOG_I("%s: Connection closed!", __func__);

+    if (socketDescriptor != -1)

+        close(socketDescriptor);

+}

+

+

+//------------------------------------------------------------------------------

+bool Connection::connect(

+    const char *dest

+) {

+	bool ret = false;

+	int32_t len;

+

+	assert(NULL != dest);

+

+	LOG_I("connect(): Connecting to %s", dest);

+	do {

+		remote.sun_family = AF_UNIX;

+		strncpy(remote.sun_path, dest, sizeof(remote.sun_path) - 1);

+		if ((socketDescriptor = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {

+			LOG_E("Can't open stream socket - errno: %d", errno);

+			break;

+		}

+		len = strlen(remote.sun_path) + sizeof(remote.sun_family);

+		// The Daemon socket is in the Abstract Domain(LINUX ONLY!)

+		remote.sun_path[0] = 0;

+		if (::connect(socketDescriptor, (struct sockaddr *) &remote, len) < 0) {

+			LOG_E("connect() failed - errno: %d", errno);

+			break;

+		}

+		ret = true;

+	} while (false);

+

+	return ret;

+}

+

+

+//------------------------------------------------------------------------------

+size_t Connection::readData(

+    void *buffer,

+    uint32_t len

+) {

+    return readData(buffer, len, -1);

+}

+

+

+//------------------------------------------------------------------------------

+size_t Connection::readData(

+    void      *buffer,

+    uint32_t  len,

+    int32_t   timeout

+) {

+	size_t ret;

+	struct timeval tv;

+	struct timeval *ptv = NULL;

+    fd_set readfds;

+

+    assert(NULL != buffer);

+	assert(-1 != socketDescriptor);

+

+    do{

+

+        if(timeout >= 0){

+            // Calculate timeout value

+            tv.tv_sec = timeout/1000;

+            tv.tv_usec = (timeout - (tv.tv_sec * 1000)) * 1000;

+            ptv = &tv;

+        }

+

+        FD_ZERO(&readfds);

+        FD_SET(socketDescriptor, &readfds);

+        ret = select(socketDescriptor + 1, &readfds, NULL, NULL, ptv);

+

+        // check for read error

+        if (-1 == (int)ret) {

+            LOG_E("readData(): select() failed, ret=%d, errno=%d", ret,errno);

+            break;

+        }

+

+        // Handle case of no descriptor ready

+        if (0 == ret) {

+            LOG_W("readData(): select() timed out");

+            ret = -2;

+            break;

+        }

+

+        // one or more descriptors are ready 

+

+        // finally check if fd has been selected -> must socketDescriptor

+        if (!FD_ISSET(socketDescriptor, &readfds))

+        {

+            LOG_E("readData(): failure, errno=%d", errno);

+            break;

+        }

+

+        ret = recv(socketDescriptor, buffer, len, MSG_WAITALL);

+        if(0 == ret)

+        {

+            LOG_I("readData(): peer orderly closed connection.");

+            break;

+        }

+

+    }while(false);

+

+	return ret;

+}

+

+

+//------------------------------------------------------------------------------

+size_t Connection::writeData(

+    void *buffer,

+    uint32_t len

+) {

+	size_t ret;

+

+	assert(NULL != buffer);

+	assert(-1 != socketDescriptor);

+

+    ret = send(socketDescriptor, buffer, len, 0);

+    if (ret != len)

+    {

+        LOG_E( "writeData(): could no send all data, ret=%d, errno: %d", ret,errno);

+        ret = -1;

+    }

+

+    return ret;

+}

+

+/** @} */

diff --git a/V008/Android/external/mobicore/daemon/Common/Connection.h b/V008/Android/external/mobicore/daemon/Common/Connection.h
new file mode 100644
index 0000000..3796238
--- /dev/null
+++ b/V008/Android/external/mobicore/daemon/Common/Connection.h
@@ -0,0 +1,125 @@
+/** @addtogroup MCD_MCDIMPL_DAEMON_SRV

+ * @{

+ * @file

+ *

+ * Connection data.

+ *

+ * <!-- 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 CONNECTION_H_

+#define CONNECTION_H_

+

+#include <list>

+#include <exception>

+

+#include <inttypes.h>

+

+#include <sys/types.h>

+#include <sys/socket.h>

+#include <sys/un.h>

+

+

+class Connection {

+

+public:

+    struct sockaddr_un remote; /**< Remote address */

+    int32_t socketDescriptor; /**< Local socket descriptor */

+    void *connectionData; /**< reference to data related with the connection */

+    bool detached; /**< Connection state */

+

+    Connection(

+        void

+    );

+

+    Connection(

+        int          socketDescriptor,

+        sockaddr_un  *remote

+    );

+

+    virtual ~Connection(

+        void

+    );

+

+    /**

+     * Connect to destination.

+     *

+     * @param Destination pointer.

+     * @return true on success.

+     */

+    virtual bool connect(

+        const char *dest

+    );

+

+    /**

+     * Read bytes from the connection.

+     *

+     * @param buffer	Pointer to destination buffer.

+     * @param len       Number of bytes to read.

+     * @param timeout   Timeout in milliseconds

+     * @return Number of bytes read.

+     * @return -1 if select() failed (returned -1)

+     * @return -2 if no data available, i.e. timeout

+     */

+    virtual size_t readData(

+        void      *buffer,

+        uint32_t  len,

+        int32_t   timeout

+    );

+

+    /**

+     * Read bytes from the connection.

+     *

+     * @param buffer    Pointer to destination buffer.

+     * @param len       Number of bytes to read.

+     * @return Number of bytes read.

+     */

+    virtual size_t readData(

+        void      * buffer,

+        uint32_t  len

+    );

+

+    /**

+     * Write bytes to the connection.

+     *

+     * @param buffer	Pointer to source buffer.

+     * @param len		Number of bytes to read.

+     * @return Number of bytes written.

+     */

+    virtual size_t writeData(

+        void      *buffer,

+        uint32_t  len

+    );

+

+};

+

+typedef std::list<Connection*>         connectionList_t;

+typedef connectionList_t::iterator     connectionIterator_t;

+

+

+#endif /* CONNECTION_H_ */

+

+/** @} */

diff --git a/V008/Android/external/mobicore/daemon/Common/McTypes.h b/V008/Android/external/mobicore/daemon/Common/McTypes.h
new file mode 100644
index 0000000..fb05c53
--- /dev/null
+++ b/V008/Android/external/mobicore/daemon/Common/McTypes.h
@@ -0,0 +1,40 @@
+/** @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/V008/Android/external/mobicore/daemon/Common/NetlinkConnection.cpp b/V008/Android/external/mobicore/daemon/Common/NetlinkConnection.cpp
new file mode 100644
index 0000000..447a411
--- /dev/null
+++ b/V008/Android/external/mobicore/daemon/Common/NetlinkConnection.cpp
@@ -0,0 +1,289 @@
+/** @addtogroup MCD_MCDIMPL_DAEMON_SRV

+ * @{

+ * @file

+ *

+ * Connection data.

+ *

+ * <!-- 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 <stdlib.h>

+#include <unistd.h>

+#include <assert.h>

+#include <cstring>

+#include <errno.h>

+#include <stdio.h>

+#include <sys/socket.h>

+#include <linux/netlink.h>

+

+#include "NetlinkConnection.h"

+

+#define LOG_TAG	"McDaemon"

+#include "log.h"

+

+

+uint64_t hashConnection(

+	pid_t pid,

+	uint32_t seq

+)

+{

+	return (((uint64_t)seq) << 32) | (uint64_t)pid;

+}

+

+

+//------------------------------------------------------------------------------

+NetlinkConnection::NetlinkConnection(

+    void

+) :Connection(), 

+    dataLeft(0),

+    manager(NULL)

+{

+	detached = false;

+	dataMsg = NULL;

+	dataStart = NULL;

+	dataLen = 0;

+    

+	

+	selfPid = getpid();

+	peerPid = 0;

+	sequenceMagic = 0;

+	hash = hashConnection(peerPid, sequenceMagic);

+}

+

+

+//------------------------------------------------------------------------------

+NetlinkConnection::NetlinkConnection(

+    NetlinkConnectionManager	*manager,

+    int							socketDescriptor,

+	uint32_t 					pid,

+    uint32_t					seq

+): Connection(), 

+    dataLeft(0),

+    manager(manager)

+{

+	detached = false;

+	dataMsg = NULL;

+	dataStart = NULL;

+	dataLen = 0;

+    

+	this->socketDescriptor = socketDescriptor;

+	selfPid = getpid();

+	peerPid = pid;

+	sequenceMagic = seq;

+	hash = hashConnection(pid, seq);

+}

+

+

+//------------------------------------------------------------------------------

+NetlinkConnection::~NetlinkConnection(

+    void

+) {

+    LOG_I("%s: destroy connection for PID 0x%X", __func__, peerPid);

+    socketDescriptor = -1;

+    free(dataMsg);

+    

+    if (manager) {

+		manager->removeConnection(hash);

+    }

+}

+

+

+//------------------------------------------------------------------------------

+bool NetlinkConnection::connect(

+    const char *dest

+) {

+    struct sockaddr_nl addr;

+    bool ret = false;

+

+	assert(NULL != dest);

+

+    LOG_I("%s: Connecting to SEQ 0x%X", __func__, MC_DAEMON_PID);

+    do {

+		if ((socketDescriptor = socket(PF_NETLINK, SOCK_DGRAM, MC_DAEMON_NETLINK)) < 0) {

+            LOG_E("%s: Can't open netlink socket - errno: %d(%s)", 

+                  __func__, errno, strerror(errno));

+            break;

+        }

+        memset(&addr, 0, sizeof(addr));

+        addr.nl_family = AF_NETLINK;

+        addr.nl_pid = selfPid;  /* self pid */

+        addr.nl_groups = 0;  /* not in mcast groups */

+        

+        if (bind(socketDescriptor, (struct sockaddr*)&addr, sizeof(addr)) < 0) {

+            LOG_E("%s: bind() failed - errno: %d(%s)", __func__, errno, strerror(errno));

+            close(socketDescriptor);

+            

+            // Set invalid socketDescriptor

+            socketDescriptor = -1;

+            break;

+        }

+        ret = true;

+    

+        

+    } while (false);

+

+	return ret;

+}

+

+

+//------------------------------------------------------------------------------

+void NetlinkConnection::handleMessage(

+    struct nlmsghdr *nlh

+) {

+	dataMutex.lock();

+    /* Takeover the buffer */

+    dataMsg = nlh;

+    dataLen = NLMSG_PAYLOAD(dataMsg, 0);

+	dataStart = static_cast<uint8_t *>(NLMSG_DATA(dataMsg));

+	dataMutex.unlock();

+	dataLeft.signal();

+}

+

+//------------------------------------------------------------------------------

+size_t NetlinkConnection::readData(

+    void *buffer,

+    uint32_t len

+) {

+    return readData(buffer, len, -1);

+}

+

+

+//------------------------------------------------------------------------------

+size_t NetlinkConnection::readData(

+    void      *buffer,

+    uint32_t  len,

+    int32_t   timeout

+) {

+    size_t ret = -1;

+    assert(NULL != buffer);

+

+	if(!dataLeft.wait(timeout)){

+		return -2;

+	}

+	dataMutex.lock();

+    // No data left?? Could we get this far?

+    if (dataLen <= 0)

+    {

+		dataMutex.unlock();

+		return -2;

+	}

+

+    //LOG_I("%s: reading connection data %u, connection data left %u", 

+    //      __func__, len, dataLen);

+    

+    assert(dataStart != NULL);

+    

+    // trying to read more than the left data

+    if (len > dataLen)

+    {

+        ret = dataLen;

+        memcpy(buffer, dataStart, dataLen);

+        dataLen = 0;

+    }

+    else

+    {

+        ret = len;

+        memcpy(buffer, dataStart, len);

+        dataLen -= len;

+        dataStart += len;

+    }

+    

+    if (dataLen == 0)

+    {

+        dataStart = NULL;

+        free(dataMsg);

+        dataMsg = NULL;

+    }

+    else{

+		// Still some data left

+		dataLeft.signal();

+	}

+    dataMutex.unlock();

+    

+    //LOG_I("%s: read %u", __func__, ret);

+    return ret;

+}

+

+//------------------------------------------------------------------------------

+size_t NetlinkConnection::writeData(

+    void *buffer,

+    uint32_t len

+) {

+    size_t ret;

+    struct sockaddr_nl dest_addr;

+    struct nlmsghdr *nlh = NULL;

+    struct iovec iov;

+    struct msghdr msg;

+

+    assert(NULL != buffer);

+    assert(-1 != socketDescriptor);

+    

+    //LOG_I("%s: send data %u to PID %u", __func__, len, sequenceMagic);

+

+    memset(&dest_addr, 0, sizeof(dest_addr));

+    dest_addr.nl_family = AF_NETLINK;

+    dest_addr.nl_pid = peerPid;

+    dest_addr.nl_groups = 0; /* unicast */

+    

+    nlh=(struct nlmsghdr *)malloc(

+        NLMSG_SPACE(len));

+    /* Fill the netlink message header */

+    nlh->nlmsg_len = NLMSG_SPACE(len);

+    nlh->nlmsg_pid = selfPid;

+    nlh->nlmsg_flags = NLM_F_REQUEST;

+    nlh->nlmsg_seq = sequenceMagic;

+    

+    /* Fill in the netlink message payload */

+    memcpy(NLMSG_DATA(nlh), buffer, len);

+    

+    iov.iov_base = (void *)nlh;

+    iov.iov_len = nlh->nlmsg_len;

+    msg.msg_name = (void *)&dest_addr;

+    msg.msg_namelen = sizeof(dest_addr);

+    msg.msg_iov = &iov;

+    msg.msg_iovlen = 1;

+    msg.msg_control = NULL;

+    msg.msg_controllen = 0;

+    

+    ret = sendmsg(socketDescriptor, &msg, 0);

+    if (ret != NLMSG_SPACE(len))

+    {

+        LOG_E( "%s: could no send all data, ret=%d, errno: %d(%s)", 

+               __func__, ret, errno, strerror(errno));

+        ret = -1;

+    }

+    else{

+        /* The whole message sent also includes the header, so make sure to 

+		 * return only the number of payload data sent, not everything */

+        ret = len;

+    }

+    

+    free(nlh);

+

+    return ret;

+}

+

+/** @} */

diff --git a/V008/Android/external/mobicore/daemon/Common/NetlinkConnection.h b/V008/Android/external/mobicore/daemon/Common/NetlinkConnection.h
new file mode 100644
index 0000000..069536e
--- /dev/null
+++ b/V008/Android/external/mobicore/daemon/Common/NetlinkConnection.h
@@ -0,0 +1,218 @@
+/** @addtogroup MCD_MCDIMPL_DAEMON_SRV

+ * @{

+ * @file

+ *

+ * Connection data.

+ *

+ * <!-- 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 NETLINKCONNECTION_H_

+#define NETLINKCONNECTION_H_

+

+#include <unistd.h>

+#include <map>

+#include <exception>

+#include <inttypes.h>

+

+#include <sys/types.h>

+#include <sys/socket.h>

+#include <sys/un.h>

+

+#include "Connection.h"

+#include "CMutex.h"

+#include "CSemaphore.h"

+

+/** PID(address) of MC daemon.  */

+#define MC_DAEMON_PID 0xFFFFFFFF

+/** Maximum Netlink payload size 

+ * TODO: figure out the best value for this */

+#define MAX_PAYLOAD 1024

+

+#define MC_DAEMON_NETLINK  17

+

+

+class NetlinkConnection;

+

+/**

+ * Hash function for unique ID of a connection.

+ *

+ * @param pid Connection PID

+ * @param seq Connection sequenceMagic

+ * 

+ * @return Unique identifier of the connection

+ */

+uint64_t hashConnection(pid_t pid, uint32_t seq);

+

+/** Netlink connection manager interface.

+ * This inteface has to be implemented by the handling server

+ * to ensure connection will be removed from accounting when destroied. */

+class NetlinkConnectionManager {

+public:

+    virtual ~NetlinkConnectionManager(){};

+    /**

+	 * Retreive connection based on a unique hash.

+	 * Search the peer connections hashmap for a hash and return 

+	 * the associated Connection object

+     *

+	 * @param hash The hash to search

+     * @return The NetlinkConnection object if found or NULL if not found

+     */

+    virtual NetlinkConnection* findConnection(

+		uint64_t hash

+    ) = 0;

+    

+    /**

+     * Insert a connection in connection lisst

+     * Insert a new connection in the peer connections list. If there 

+	 * is already such a connection

+     * it will be overriden!

+     *

+	 * @param hash The hash to use

+     * @param connection The connection object to insert

+     */

+    virtual void insertConnection(

+		uint64_t hash,

+        NetlinkConnection *connection

+    ) = 0;

+    

+    /**

+     * Remove a connection from the peer connections

+     * Remove the connection associated with seq from the peer list. 

+	 * This doesn't actually free the connection object!

+	 * If the hash is invalid nothing happens.

+     *

+	 * @param hash The hash hash use

+     */

+    virtual void removeConnection(

+		uint64_t hash

+    ) = 0;

+};

+

+class NetlinkConnection: public Connection {

+public:

+    pid_t selfPid; /**< Which PID to use to identify when writing data */

+    pid_t peerPid; /**< Destination PID for sending data */

+    uint32_t sequenceMagic; /**< Random? magic to match requests/answers */

+    uint64_t hash; /**< Unique connection ID, see hashConnection */

+    

+    NetlinkConnection(

+        void

+    );

+

+	/**

+	 * Connection main constructor

+	 *

+	 * @param manager Connection manager pointer.

+	 * @param socketDescriptor Socket descriptor to use for writing

+	 * @param pid Connection PID

+	 * @param seq Connection sequence magic number

+	 */

+    NetlinkConnection(

+        NetlinkConnectionManager *manager,

+        int   socketDescriptor,

+		uint32_t pid,

+		uint32_t seq

+    );

+

+    virtual ~NetlinkConnection(

+        void

+    );

+

+    /**

+     * Connect to destination.

+     *

+     * @param Destination pointer.

+     * @return true on success.

+     */

+    virtual bool connect(

+        const char *dest

+    );

+

+    /**

+     * Read bytes from the connection(compatiblity method).

+     *

+     * @param buffer	Pointer to destination buffer.

+     * @param len       Number of bytes to read.

+     * @param timeout   Timeout in milliseconds(ignored)

+     * @return Number of bytes read.

+     * @return -1 if select() failed (returned -1)

+     * @return -2 if no data available, i.e. timeout

+     */

+    virtual size_t readData(

+        void      *buffer,

+        uint32_t  len,

+        int32_t   timeout

+    );

+

+    /**

+     * Read bytes from the connection.

+     *

+     * @param buffer    Pointer to destination buffer.

+     * @param len       Number of bytes to read.

+     * @return Number of bytes read.

+     */

+    virtual size_t readData(

+        void      * buffer,

+        uint32_t  len

+    );

+

+    /**

+     * Write bytes to the connection.

+     *

+     * @param buffer	Pointer to source buffer.

+     * @param len		Number of bytes to read.

+     * @return Number of bytes written.

+     */

+    virtual size_t writeData(

+        void      *buffer,

+        uint32_t  len

+    );

+    

+    /**

+     * Set the internal data connection.

+     * This method is called by the 

+     *

+     * @param nlh    Netlink structure pointing to data.

+     */

+    void handleMessage(

+        struct nlmsghdr *nlh

+    );

+

+private:

+	CMutex dataMutex;

+	CSemaphore dataLeft;

+    struct nlmsghdr *dataMsg; /**< Last message received */

+    uint32_t dataLen; /**< How much connection data is left */

+    uint8_t *dataStart; /**< Start pointer of remaining data */

+    NetlinkConnectionManager *manager; /**< Netlink connection manager(eg. NetlinkServer) */

+};

+

+typedef std::map<uint64_t, NetlinkConnection*>  connectionMap_t;

+

+#endif /* NETLINKCONNECTION_H_ */

+

+/** @} */

diff --git a/V008/Android/external/mobicore/daemon/Daemon/Android.mk b/V008/Android/external/mobicore/daemon/Daemon/Android.mk
new file mode 100644
index 0000000..149305a
--- /dev/null
+++ b/V008/Android/external/mobicore/daemon/Daemon/Android.mk
@@ -0,0 +1,43 @@
+# =============================================================================
+#
+# Module: mcDriverDaemon
+#
+# =============================================================================
+LOCAL_PATH := $(call my-dir)
+MY_MCDRIVER_PATH := $(LOCAL_PATH)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE	:= mcDriverDaemon
+LOCAL_MODULE_TAGS := eng
+
+# Add new subdirectories containing code here
+include $(LOCAL_PATH)/Device/Android.mk
+include $(LOCAL_PATH)/Server/Android.mk
+
+LOCAL_C_INCLUDES += bionic \
+	external/stlport/stlport
+
+# Add new folders with header files here
+LOCAL_C_INCLUDES += \
+	$(COMP_PATH_MobiCore)/inc \
+	$(COMP_PATH_MobiCoreDriverMod)/Public \
+	$(APP_PROJECT_PATH)/ClientLib/public \
+	$(APP_PROJECT_PATH)/Kernel \
+	$(APP_PROJECT_PATH)/Kernel/Platforms/Generic \
+	$(APP_PROJECT_PATH)/Common \
+	$(APP_PROJECT_PATH)/Registry/Public \
+	$(MY_MCDRIVER_PATH)/public
+
+# Add new source files here
+LOCAL_SRC_FILES += \
+	MobiCoreDriverDaemon.cpp
+
+LOCAL_CPPFLAGS += -fno-rtti -fno-exceptions
+# Modules this one depnds on (depending ones first)
+LOCAL_STATIC_LIBRARIES = libstlport_static libMcKernel libMcCommon libMcRegistry
+
+include $(COMP_PATH_Logwrapper)/Android.mk
+
+include $(BUILD_EXECUTABLE)
+
diff --git a/V008/Android/external/mobicore/daemon/Daemon/Daemon/Android.mk b/V008/Android/external/mobicore/daemon/Daemon/Daemon/Android.mk
new file mode 100644
index 0000000..1e55d89
--- /dev/null
+++ b/V008/Android/external/mobicore/daemon/Daemon/Daemon/Android.mk
@@ -0,0 +1,34 @@
+# =============================================================================
+#
+# Module: mcDriverDaemon
+#
+# =============================================================================
+
+LOCAL_PATH	:= $(call my-dir)
+MY_MCDRIVER_PATH	:= $(LOCAL_PATH)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := mcDriverDaemon
+LOCAL_CFLAGS += -include buildTag.h
+# Add new subdirectories containing code here
+include $(LOCAL_PATH)/Device/Android.mk
+include $(LOCAL_PATH)/Server/Android.mk
+
+# Includes required for the Daemon
+LOCAL_C_INCLUDES +=\
+	$(MY_MCDRIVER_PATH)/public \
+	$(COMP_PATH_MobiCore)/inc \
+	$(LOCAL_PATH)/../
+
+# Add new source files here
+LOCAL_SRC_FILES +=\
+	MobiCoreDriverDaemon.cpp
+
+# Modules this one depends on (depending ones first)
+LOCAL_STATIC_LIBRARIES	+= Kernel Common McRegistryStatic PaApiStatic
+
+# Import logwrapper
+include $(COMP_PATH_Logwrapper)/Android.mk
+
+include $(BUILD_EXECUTABLE)
diff --git a/V008/Android/external/mobicore/daemon/Daemon/Device/Android.mk b/V008/Android/external/mobicore/daemon/Daemon/Device/Android.mk
new file mode 100644
index 0000000..5ae55d8
--- /dev/null
+++ b/V008/Android/external/mobicore/daemon/Daemon/Device/Android.mk
@@ -0,0 +1,26 @@
+# =============================================================================
+#
+# MC driver device files
+#
+# =============================================================================
+
+# This is not a separate module.
+# Only for inclusion by other modules.
+
+MY_MCDRV_DEVICE_PATH	:= $(call my-dir)
+MY_MCDRV_DEVICE_PATH_REL	:= Device
+
+include $(MY_MCDRV_DEVICE_PATH)/Platforms/Android.mk
+
+# Add new folders with header files here
+LOCAL_C_INCLUDES +=\
+	$(MY_MCDRV_DEVICE_PATH)\
+	$(MY_MCDRV_DEVICE_PATH)/public
+
+# Add new source files here
+LOCAL_SRC_FILES +=\
+	$(MY_MCDRV_DEVICE_PATH_REL)/DeviceIrqHandler.cpp\
+	$(MY_MCDRV_DEVICE_PATH_REL)/DeviceScheduler.cpp\
+	$(MY_MCDRV_DEVICE_PATH_REL)/MobiCoreDevice.cpp\
+	$(MY_MCDRV_DEVICE_PATH_REL)/NotificationQueue.cpp\
+	$(MY_MCDRV_DEVICE_PATH_REL)/TrustletSession.cpp\
diff --git a/V008/Android/external/mobicore/daemon/Daemon/Device/DeviceIrqHandler.cpp b/V008/Android/external/mobicore/daemon/Daemon/Device/DeviceIrqHandler.cpp
new file mode 100644
index 0000000..e941c88
--- /dev/null
+++ b/V008/Android/external/mobicore/daemon/Daemon/Device/DeviceIrqHandler.cpp
@@ -0,0 +1,44 @@
+/** @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"
+
+
+//------------------------------------------------------------------------------
+void DeviceIrqHandler::run(
+	void
+) {
+	handleIrq();
+	this->exit(-1);
+}
+
+/** @} */
diff --git a/V008/Android/external/mobicore/daemon/Daemon/Device/DeviceIrqHandler.h b/V008/Android/external/mobicore/daemon/Daemon/Device/DeviceIrqHandler.h
new file mode 100644
index 0000000..957db40
--- /dev/null
+++ b/V008/Android/external/mobicore/daemon/Daemon/Device/DeviceIrqHandler.h
@@ -0,0 +1,51 @@
+/** @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/V008/Android/external/mobicore/daemon/Daemon/Device/DeviceScheduler.cpp b/V008/Android/external/mobicore/daemon/Daemon/Device/DeviceScheduler.cpp
new file mode 100644
index 0000000..d50170b
--- /dev/null
+++ b/V008/Android/external/mobicore/daemon/Daemon/Device/DeviceScheduler.cpp
@@ -0,0 +1,44 @@
+/** @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/V008/Android/external/mobicore/daemon/Daemon/Device/DeviceScheduler.h b/V008/Android/external/mobicore/daemon/Daemon/Device/DeviceScheduler.h
new file mode 100644
index 0000000..329e05c
--- /dev/null
+++ b/V008/Android/external/mobicore/daemon/Daemon/Device/DeviceScheduler.h
@@ -0,0 +1,52 @@
+/** @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/V008/Android/external/mobicore/daemon/Daemon/Device/MobiCoreDevice.cpp b/V008/Android/external/mobicore/daemon/Daemon/Device/MobiCoreDevice.cpp
new file mode 100644
index 0000000..0cf6fc7
--- /dev/null
+++ b/V008/Android/external/mobicore/daemon/Daemon/Device/MobiCoreDevice.cpp
@@ -0,0 +1,626 @@
+/** @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 <cstdlib>

+#include <pthread.h>

+#include "McTypes.h"

+

+#include "DeviceScheduler.h"

+#include "DeviceIrqHandler.h"

+#include "ExcDevice.h"

+#include "Connection.h"

+#include "TrustletSession.h"

+

+#include "MobiCoreDevice.h"

+#include "Mci/mci.h"

+#include "mcLoadFormat.h"

+

+

+#define LOG_TAG	"McDaemon"

+#include "log.h"

+#include "public/MobiCoreDevice.h"

+

+

+//------------------------------------------------------------------------------

+MobiCoreDevice::MobiCoreDevice() {

+	mcFault = false;

+}

+

+//------------------------------------------------------------------------------

+MobiCoreDevice::~MobiCoreDevice() {

+	delete mcVersionInfo;

+	mcVersionInfo = NULL;

+}

+

+//------------------------------------------------------------------------------

+TrustletSession* MobiCoreDevice::getTrustletSession(

+    uint32_t sessionId

+) {

+	TrustletSession* ts = NULL;

+

+	for (trustletSessionIterator_t session = trustletSessions.begin();

+			session != trustletSessions.end();

+			++session) {

+		TrustletSession* tsTmp = *session;

+		if (tsTmp->sessionId == sessionId)

+		{

+			ts = tsTmp;

+			break;

+		}

+	}

+	return ts;

+}

+

+

+//------------------------------------------------------------------------------

+Connection * MobiCoreDevice::getSessionConnection(

+	uint32_t sessionId,

+	notification_t *notification	

+) {

+	Connection *con = NULL;

+	TrustletSession* ts = NULL;

+

+	ts = getTrustletSession(sessionId);

+	if (NULL == ts) {

+		return NULL;

+	}

+

+	con = ts->notificationConnection;

+	if(NULL == con) {

+		ts->queueNotification(notification);

+		return NULL;

+	}

+

+	return con;

+}

+

+

+//------------------------------------------------------------------------------

+bool MobiCoreDevice::open(

+    Connection *connection

+) {

+	// Link this device to the connection

+	connection->connectionData = this;

+	return true;

+}

+

+

+//------------------------------------------------------------------------------

+/**

+ * Close device.

+ *

+ * Removes all sessions to a connection. Though, clientLib rejects the closeDevice()

+ * command if still sessions connected to the device, this is needed to clean up all

+ * sessions if client dies.

+ */

+void MobiCoreDevice::close(

+    Connection *connection

+) {

+	trustletSessionList_t::reverse_iterator interator;

+	static CMutex mutex;

+	// 1. Iterate through device session to find connection

+	// 2. Decide what to do with open Trustlet sessions

+	// 3. Remove & delete deviceSession from vector

+

+	// Enter critical section

+	mutex.lock();

+	for (interator = trustletSessions.rbegin();

+		interator != trustletSessions.rend();

+		interator++) {

+		TrustletSession* ts = *interator;

+

+		if (ts->deviceConnection == connection) {

+			closeSession(connection, ts->sessionId);

+		}

+	}

+	// Leave critical section

+	mutex.unlock();

+

+	connection->connectionData = NULL;

+}

+

+

+//------------------------------------------------------------------------------

+void MobiCoreDevice::start(

+    void

+) {

+	// Call the device specific initialization

+	//	initDevice();

+

+	LOG_I("Starting DeviceIrqHandler...");

+	// Start the irq handling thread

+	DeviceIrqHandler::start();

+

+	if (schedulerAvailable()) {

+		LOG_I("Starting DeviceScheduler...");

+		// Start the scheduling handling thread

+		DeviceScheduler::start();

+	} else {

+		LOG_I("No DeviceScheduler available.");

+	}

+}

+

+

+//------------------------------------------------------------------------------

+void MobiCoreDevice::signalMcpNotification(

+    void

+) {

+	mcpSessionNotification.signal();

+}

+

+

+//------------------------------------------------------------------------------

+bool MobiCoreDevice::waitMcpNotification(

+    void

+) {

+	int counter = 5;

+	while (1) {

+		// In case of fault just return, nothing to do here

+		if (mcFault) {

+			return false;

+		}

+		// Wait 10 seconds for notification

+		if (mcpSessionNotification.wait(10) == false) {

+			// 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) {

+				dumpMobicoreStatus();

+				mcFault = true;

+				return false;

+			} else {

+				counter--;

+				if (counter < 1) {

+					mcFault = true;

+					return false;

+				} 

+			}

+		} else {

+				break;

+		}

+	}

+

+	// 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;

+	}

+	return true;

+}

+

+

+//------------------------------------------------------------------------------

+void MobiCoreDevice::openSession(

+	Connection                      *deviceConnection,

+	loadDataOpenSession_ptr         pLoadDataOpenSession,

+	mcDrvCmdOpenSessionPayload_ptr  pCmdOpenSessionPayload,

+	mcDrvRspOpenSessionPayload_ptr  pRspOpenSessionPayload

+) {

+

+	do {

+		// Write MCP open message to buffer

+		mcpMessage->cmdOpen.cmdHeader.cmdId = MC_MCP_CMD_OPEN_SESSION;

+		mcpMessage->cmdOpen.uuid = pCmdOpenSessionPayload->uuid;

+		mcpMessage->cmdOpen.wsmTypeTci = WSM_CONTIGUOUS;

+		mcpMessage->cmdOpen.adrTciBuffer = (uint32_t)(pCmdOpenSessionPayload->tci);

+		mcpMessage->cmdOpen.ofsTciBuffer = 0;

+		mcpMessage->cmdOpen.lenTciBuffer = pCmdOpenSessionPayload->len;

+

+		LOG_I("%s(): tciPhys=%p, len=%d,", __FUNCTION__,

+				(addr_t)(pCmdOpenSessionPayload->tci),

+				pCmdOpenSessionPayload->len);

+

+		// check if load data is provided

+		if(NULL == pLoadDataOpenSession)

+		{

+			// Preinstalled trustlet shall be loaded

+			mcpMessage->cmdOpen.wsmTypeLoadData = WSM_INVALID;

+		}

+		else

+		{

+			mcpMessage->cmdOpen.wsmTypeLoadData = WSM_L2;

+			mcpMessage->cmdOpen.adrLoadData = (uint32_t)pLoadDataOpenSession->baseAddr;

+			mcpMessage->cmdOpen.ofsLoadData = pLoadDataOpenSession->offs;

+			mcpMessage->cmdOpen.lenLoadData = pLoadDataOpenSession->len;

+			memcpy(&mcpMessage->cmdOpen.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>();

+		// 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_OPEN_SESSION | FLAG_RESPONSE) != mcpMessage->rspHeader.rspId)

+		{

+			LOG_E("%s(): CMD_OPEN_SESSION got invalid MCP command response(0x%X)",

+				  __FUNCTION__, mcpMessage->rspHeader.rspId);

+			break;

+		}

+

+		uint32_t mcRet = mcpMessage->rspOpen.rspHeader.result;

+		pRspOpenSessionPayload->mcResult = mcRet;

+

+		if(MC_MCP_RET_OK != mcRet)

+		{

+			LOG_E("%s: CMD_OPEN_SESSION error %d", __FUNCTION__, mcRet);

+			break;

+		}

+

+		LOG_I("%s: We have %d queued notifications after open session", 

+			  __FUNCTION__, notifications.size());

+		// Read MC answer from MCP buffer

+		TrustletSession *trustletSession = new TrustletSession(

+													deviceConnection,

+													mcpMessage->rspOpen.sessionId);

+

+		pRspOpenSessionPayload->deviceId = pCmdOpenSessionPayload->deviceId;

+		pRspOpenSessionPayload->sessionId = trustletSession->sessionId;

+		pRspOpenSessionPayload->deviceSessionId = (uint32_t)trustletSession;

+		pRspOpenSessionPayload->sessionMagic = trustletSession->sessionMagic;

+

+		trustletSessions.push_back(trustletSession);

+		// We have some queued notifications and we need to send them to them

+		// trustlet session

+		while (!notifications.empty()) {

+			trustletSession->queueNotification(&notifications.front());

+			notifications.pop();

+		}

+

+	} while(0);

+}

+

+

+//------------------------------------------------------------------------------

+TrustletSession *MobiCoreDevice::registerTrustletConnection(

+	Connection                    *connection,

+	mcDrvCmdNqConnectPayload_ptr  pCmdNqConnectPayload

+) {

+	LOG_I("%s(): searching sessionMagic %d and sessionId %d", __FUNCTION__,

+		pCmdNqConnectPayload->sessionMagic,

+		pCmdNqConnectPayload->sessionId);

+

+	for (trustletSessionIterator_t iterator = trustletSessions.begin();

+			iterator != trustletSessions.end();

+			++iterator) {

+		TrustletSession *ts = *iterator;

+

+		if (ts != (TrustletSession*) (pCmdNqConnectPayload->deviceSessionId)) {

+			continue;

+		}

+

+		if ( (ts->sessionMagic != pCmdNqConnectPayload->sessionMagic)

+				|| (ts->sessionId != pCmdNqConnectPayload->sessionId)) {

+			continue;

+		}

+

+		LOG_I("%s(): found connection", __FUNCTION__);

+

+		ts->notificationConnection = connection;

+		return ts;

+	}

+

+	LOG_I("registerTrustletConnection(): search failed");

+	return NULL;

+}

+

+

+//------------------------------------------------------------------------------

+/**

+ * Need connection as well as according session ID, so that a client can not

+ * close sessions not belonging to him.

+ */

+bool MobiCoreDevice::closeSession(

+    Connection  *deviceConnection,

+	uint32_t    sessionId

+) {

+	bool ret = true;

+

+	do {

+		TrustletSession *ts = NULL;

+		trustletSessionIterator_t iterator;

+

+		// Search object to session id

+		for (iterator = trustletSessions.begin();

+				iterator != trustletSessions.end();

+				++iterator)

+		{

+			TrustletSession  *tsTmp = *iterator;

+			if ( (tsTmp->sessionId == sessionId)

+					&& (tsTmp->deviceConnection == deviceConnection))

+			{

+				ts = tsTmp;

+				break;

+			}

+		}

+		if (NULL == ts)

+		{

+			LOG_I("closeSession(): no session found with id=%d",sessionId);

+			ret = false;

+			break;

+		}

+

+		LOG_I("closeSession(): Write MCP close message to buffer and notify, wait");

+

+		// Write MCP close message to buffer

+		mcpMessage->cmdClose.cmdHeader.cmdId = MC_MCP_CMD_CLOSE_SESSION;

+		mcpMessage->cmdClose.sessionId = sessionId;

+

+		// Notify MC about the availability of a new command inside the MCP buffer

+		notify(SID_MCP);

+

+		// Wait till response from MSH is available

+		if(!waitMcpNotification()) {

+			ret = false;

+			break;

+		}

+

+		// Check if the command response ID is correct

+		if ((MC_MCP_CMD_CLOSE_SESSION | FLAG_RESPONSE) != mcpMessage->rspHeader.rspId) {

+			LOG_E("closeSession(): CMD_CLOSE_SESSION got invalid MCP response");

+			ret = false;

+			break;

+		}

+

+		// Read MC answer from MCP buffer

+		uint32_t mcRet = mcpMessage->rspOpen.rspHeader.result;

+

+		if( MC_MCP_RET_OK != mcRet) {

+			LOG_E("closeSession(): CMD_CLOSE_SESSION error %d",mcRet);

+			ret = false;

+			break;

+		}

+

+		// remove objects

+		trustletSessions.erase(iterator);

+		delete ts;

+

+	} while(0);

+

+	return ret;

+}

+

+

+//------------------------------------------------------------------------------

+void MobiCoreDevice::mapBulk(

+    Connection                     *deviceConnection,

+    mcDrvCmdMapBulkMemPayload_ptr  pCmdMapBulkMemPayload,

+    mcDrvRspMapBulkMemPayload_ptr  pRspMapBulkMemPayload

+) {

+	do

+	{

+

+		// Write MCP map message to buffer

+		mcpMessage->cmdMap.cmdHeader.cmdId = MC_MCP_CMD_MAP;

+		mcpMessage->cmdMap.sessionId = pCmdMapBulkMemPayload->sessionId;

+		mcpMessage->cmdMap.wsmType = WSM_L2;

+		mcpMessage->cmdMap.adrBuffer = (uint32_t)(pCmdMapBulkMemPayload->pAddrL2);

+		mcpMessage->cmdMap.ofsBuffer = pCmdMapBulkMemPayload->offsetPayload;

+		mcpMessage->cmdMap.lenBuffer = pCmdMapBulkMemPayload->lenBulkMem;

+

+		// Notify MC about the availability of a new command inside the MCP buffer

+		notify(SID_MCP);

+

+		// Wait till response from MC is available

+		if(!waitMcpNotification()) {

+			break;

+		}

+

+		// Check if the command response ID is correct

+		if ((MC_MCP_CMD_MAP | FLAG_RESPONSE) != mcpMessage->rspHeader.rspId) {

+			LOG_E("mapBulk(): CMD_MAP got invalid MCP response");

+			break;

+		}

+

+		uint32_t mcRet = mcpMessage->rspMap.rspHeader.result;

+		pRspMapBulkMemPayload->mcResult = mcRet;

+		pRspMapBulkMemPayload->sessionId = pCmdMapBulkMemPayload->sessionId;

+

+		if(MC_MCP_RET_OK != mcRet) {

+			LOG_E("mapBulk(): CMD_MAP error %d",mcRet);

+			break;

+		}

+

+		pRspMapBulkMemPayload->secureVirtualAdr = mcpMessage->rspMap.secureVirtualAdr;

+

+	} while(0);

+}

+

+

+//------------------------------------------------------------------------------

+void MobiCoreDevice::unmapBulk(

+    Connection                       *deviceConnection,

+    mcDrvCmdUnmapBulkMemPayload_ptr  pCmdUnmapBulkMemPayload,

+    mcDrvRspUnmapBulkMemPayload_ptr  pRspUnmapBulkMemPayload

+) {

+	do {

+		// Write MCP unmap command to buffer

+		mcpMessage->cmdUnmap.cmdHeader.cmdId = MC_MCP_CMD_UNMAP;

+		mcpMessage->cmdUnmap.sessionId = pCmdUnmapBulkMemPayload->sessionId;

+		mcpMessage->cmdUnmap.wsmType = WSM_L2;

+		mcpMessage->cmdUnmap.secureVirtualAdr = pCmdUnmapBulkMemPayload->secureVirtualAdr;

+		mcpMessage->cmdUnmap.lenVirtualBuffer = pCmdUnmapBulkMemPayload->lenBulkMem;

+

+		// Notify MC about the availability of a new command inside the MCP buffer

+		notify(SID_MCP);

+

+		// Wait till response from MC is available

+		if(!waitMcpNotification()) {

+			break;

+		}

+

+		// Check if the command response ID is correct

+		if ((MC_MCP_CMD_UNMAP | FLAG_RESPONSE) != mcpMessage->rspHeader.rspId)

+		{

+			LOG_E("unmapBulk(): CMD_OPEN_SESSION got invalid MCP response");

+			break;

+		}

+

+		uint32_t  mcRet = mcpMessage->rspUnmap.rspHeader.result;

+		pRspUnmapBulkMemPayload->mcResult = mcRet;

+		pRspUnmapBulkMemPayload->sessionId = pCmdUnmapBulkMemPayload->sessionId;

+

+		if(MC_MCP_RET_OK != mcRet)

+		{

+			LOG_E("unmapBulk(): MC_MCP_CMD_UNMAP error %d",mcRet);

+			break;

+		}

+

+	} while(0);

+}

+

+

+//------------------------------------------------------------------------------

+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);

+}

+

+//------------------------------------------------------------------------------

+void MobiCoreDevice::getMobiCoreVersion(

+    mcDrvRspGetMobiCoreVersionPayload_ptr pRspGetMobiCoreVersionPayload

+) {

+	// If MobiCore version info already fetched.

+	if (mcVersionInfo != NULL) {

+		pRspGetMobiCoreVersionPayload->mcResult = MC_MCP_RET_OK;

+		pRspGetMobiCoreVersionPayload->versionInfo = *mcVersionInfo;

+	// Otherwise, fetch it via MCP.

+	} else {

+		pRspGetMobiCoreVersionPayload->mcResult = MC_MCP_RET_ERR_UNKNOWN;

+

+		// Write MCP unmap command to buffer

+		mcpMessage->cmdGetMobiCoreVersion.cmdHeader.cmdId = MC_MCP_CMD_GET_MOBICORE_VERSION;

+

+		// Notify MC about the availability of a new command inside the MCP buffer

+		notify(SID_MCP);

+

+		// Wait till response from MC is available

+		if(!waitMcpNotification()) {

+			return;

+		}

+

+		// Check if the command response ID is correct

+		if ((MC_MCP_CMD_GET_MOBICORE_VERSION | FLAG_RESPONSE) != mcpMessage->rspHeader.rspId) {

+			LOG_E("getMobiCoreVersion(): MC_MCP_CMD_GET_MOBICORE_VERSION got invalid MCP response");

+			return;

+		}

+

+		uint32_t  mcRet = mcpMessage->rspGetMobiCoreVersion.rspHeader.result;

+		pRspGetMobiCoreVersionPayload->mcResult = mcRet;

+

+		if(MC_MCP_RET_OK != mcRet) {

+			LOG_E("getMobiCoreVersion(): MC_MCP_CMD_GET_MOBICORE_VERSION error %d",mcRet);

+			return;

+		}

+

+		pRspGetMobiCoreVersionPayload->versionInfo = mcpMessage->rspGetMobiCoreVersion.versionInfo;

+

+		// Store MobiCore info for future reference.

+		mcVersionInfo = new mcVersionInfo_t();

+		*mcVersionInfo = pRspGetMobiCoreVersionPayload->versionInfo;

+	}

+}

+

+//------------------------------------------------------------------------------

+void MobiCoreDevice::queueUnknownNotification(

+	notification_t notification

+) {

+	notifications.push(notification);

+}

+

+/** @} */

diff --git a/V008/Android/external/mobicore/daemon/Daemon/Device/NotificationQueue.cpp b/V008/Android/external/mobicore/daemon/Daemon/Device/NotificationQueue.cpp
new file mode 100644
index 0000000..66eb3d6
--- /dev/null
+++ b/V008/Android/external/mobicore/daemon/Daemon/Device/NotificationQueue.cpp
@@ -0,0 +1,77 @@
+/** @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>

+

+#define LOG_TAG	"McDaemon"

+#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/V008/Android/external/mobicore/daemon/Daemon/Device/NotificationQueue.h b/V008/Android/external/mobicore/daemon/Daemon/Device/NotificationQueue.h
new file mode 100644
index 0000000..79476c6
--- /dev/null
+++ b/V008/Android/external/mobicore/daemon/Daemon/Device/NotificationQueue.h
@@ -0,0 +1,86 @@
+/** @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/V008/Android/external/mobicore/daemon/Daemon/Device/Platforms/Android.mk b/V008/Android/external/mobicore/daemon/Daemon/Device/Platforms/Android.mk
new file mode 100644
index 0000000..c367952
--- /dev/null
+++ b/V008/Android/external/mobicore/daemon/Daemon/Device/Platforms/Android.mk
@@ -0,0 +1,15 @@
+# =============================================================================
+#
+# Makefile pointing to the platform specific makefile.
+#
+# =============================================================================
+
+PLATFORMS_PATH := $(call my-dir)
+
+# Always include the Generic code
+include $(PLATFORMS_PATH)/Generic/Android.mk
+
+ifneq ($(filter-out Generic,$(PLATFORM)),)
+  $(info PLATFORM: $(PLATFORM))
+  include $(PLATFORMS_PATH)/$(PLATFORM)/Android.mk
+endif
diff --git a/V008/Android/external/mobicore/daemon/Daemon/Device/Platforms/Generic/Android.mk b/V008/Android/external/mobicore/daemon/Daemon/Device/Platforms/Generic/Android.mk
new file mode 100644
index 0000000..50cf589
--- /dev/null
+++ b/V008/Android/external/mobicore/daemon/Daemon/Device/Platforms/Generic/Android.mk
@@ -0,0 +1,17 @@
+# =============================================================================
+#
+# Generic TrustZone device includes
+#
+# =============================================================================
+
+# This is not a separate module.
+# Only for inclusion by other modules.
+
+GENERIC_PATH		:= $(call my-dir)
+GENERIC_PATH_REL	:= Device/Platforms/Generic
+
+# Add new source files here
+LOCAL_SRC_FILES +=$(GENERIC_PATH_REL)/TrustZoneDevice.cpp
+
+# Header files for components including this module
+LOCAL_C_INCLUDES += $(call my-dir)
diff --git a/V008/Android/external/mobicore/daemon/Daemon/Device/Platforms/Generic/TrustZoneDevice.cpp b/V008/Android/external/mobicore/daemon/Daemon/Device/Platforms/Generic/TrustZoneDevice.cpp
new file mode 100644
index 0000000..ba88bc5
--- /dev/null
+++ b/V008/Android/external/mobicore/daemon/Daemon/Device/Platforms/Generic/TrustZoneDevice.cpp
@@ -0,0 +1,698 @@
+/** @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 <cstdlib>

+#include <fstream>

+#include <inttypes.h>

+#include <list>

+

+#include "McTypes.h"

+#include "mcDrvModuleApi.h"

+#include "Mci/mci.h"

+#include "mcVersionHelper.h"

+

+#include "CSemaphore.h"

+#include "CMcKMod.h"

+

+#include "MobiCoreDevice.h"

+#include "TrustZoneDevice.h"

+#include "NotificationQueue.h"

+

+#define LOG_TAG	"McDaemon"

+#include "log.h"

+

+

+#define NQ_NUM_ELEMS      (16)

+#define NQ_BUFFER_SIZE    (2 * (sizeof(notificationQueueHeader_t)+  NQ_NUM_ELEMS * sizeof(notification_t)))

+#define MCP_BUFFER_SIZE   (sizeof(mcpBuffer_t))

+#define MCI_BUFFER_SIZE   (NQ_BUFFER_SIZE + MCP_BUFFER_SIZE)

+

+//------------------------------------------------------------------------------

+MC_CHECK_VERSION(MCI,0,2);

+

+//------------------------------------------------------------------------------

+__attribute__ ((weak)) MobiCoreDevice* getDeviceInstance(

+	void

+) {

+	return new TrustZoneDevice();

+}

+

+

+//------------------------------------------------------------------------------

+TrustZoneDevice::TrustZoneDevice(

+    void

+) {

+    // nothing to do

+}

+

+

+//------------------------------------------------------------------------------

+TrustZoneDevice::~TrustZoneDevice(

+    void

+) {

+    delete pMcKMod;

+	delete pWsmMcp;

+    delete nq;

+}

+

+

+//------------------------------------------------------------------------------

+static int loadMobiCoreImage(

+	addr_t	virtAddr,

+	int32_t size,

+	const char*	mobicorePath

+) {

+

+    LOG_I("MobiCore path: %s", mobicorePath);

+

+    int ret = 1;

+

+    do {

+        // Open MobiCore binary for reading only

+        fstream fs(mobicorePath, ios_base::in | ios_base::binary);

+        if (!fs) {

+            LOG_E("MobiCore not found: %s", mobicorePath);

+            break;

+        }

+

+        // Get the MobiCore file size

+        fs.seekg(0, ios::end);

+        int32_t fileSize = fs.tellg();

+        fs.seekg(0, ios::beg);

+        LOG_I("File size: %i", fileSize);

+        // Check if file is too big

+        if (fileSize > size) {

+            LOG_E("MobiCore size exceeds expectations. Size is: %i", fileSize);

+            break;

+        }

+

+        fs.read((char*)virtAddr, fileSize);

+

+        //Create an visible line with different content at the end

+        memset((void*)((uint32_t)virtAddr+fileSize),0xff,4096);

+

+        // Close file

+        fs.close();

+        ret = 0;

+    } while (false);

+

+    return ret;

+}

+

+

+#define SIZE_DDRAM              (256 * 1024)

+#define MOBICORE_BINARY_PATH    "/data/app/mobicore.img"

+//------------------------------------------------------------------------------

+/**

+ * Set up MCI and wait till MC is initialized

+ * @return true if mobicore is already initialized

+ */

+bool TrustZoneDevice::initDevice(

+	const char	*devFile,

+	bool		loadMobiCore,

+	const char  *mobicoreImage,

+	bool		enableScheduler

+) throw (ExcDevice) {

+

+    notificationQueue_t* nqStartOut;

+	notificationQueue_t* nqStartIn;

+	addr_t mciBuffer;

+

+    pMcKMod = new CMcKMod();

+    if (!pMcKMod->open(devFile))

+    {

+        LOG_E("open() kernel module device failed");

+        return false;

+    }

+    if (!pMcKMod->checkKmodVersionOk())

+    {

+        LOG_E("kernel module version mismatch");

+        return false;

+    }

+

+    // Start MobiCore from DDRAM

+    if (loadMobiCore) {

+        // 1. Allocate DDRAM as pseudo IRAM

+        mobicoreInDDR = allocateContiguousPersistentWsm(SIZE_DDRAM);

+        if (NULL == mobicoreInDDR) {

+            LOG_E("Allocation of additional RAM failed");

+            return false;

+        }

+        memset(mobicoreInDDR->virtAddr,0xCC,SIZE_DDRAM);

+

+        int ret = loadMobiCoreImage(mobicoreInDDR->virtAddr, SIZE_DDRAM,

+					mobicoreImage);

+        if (0 != ret) {

+            LOG_E("loading Mobicore file failed: %d", ret);

+            return false;

+        }

+

+        ret = pMcKMod->fcExecute(

+                mobicoreInDDR->physAddr,

+                MCP_BUFFER_SIZE);

+        if (0 != ret) {

+            LOG_E("pMcKMod->fcExecute() failed : %d", ret);

+            return false;

+        }

+    }

+    this->schedulerEnabled = enableScheduler;

+

+    // Init MC with NQ and MCP buffer addresses

+

+	// Set up MCI buffer

+	if(!getMciInstance(MCI_BUFFER_SIZE, &pWsmMcp, &mciReused)) {

+		return false;

+	}

+	mciBuffer = pWsmMcp->virtAddr;

+

+	if(!checkMciVersion()) {

+		return false;

+	}

+

+	// Only do a fastcall if MCI has not been reused (MC already initialized)

+	if (!mciReused)

+	{

+		// Wipe memory before first usage

+		bzero(mciBuffer, MCI_BUFFER_SIZE);

+

+		// Init MC with NQ and MCP buffer addresses

+		int ret = pMcKMod->fcInit(

+							pWsmMcp->physAddr,

+							0,

+							NQ_BUFFER_SIZE,

+							NQ_BUFFER_SIZE,

+							MCP_BUFFER_SIZE);

+		if (0 != ret)

+		{

+			LOG_E("pMcKMod->fcInit() failed");

+			return false;

+		}

+

+		// First empty N-SIQ which results in set up of the MCI structure

+		if(!nsiq()) {

+			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.

+		while(1)

+		{

+			uint32_t status = getMobicoreStatus();

+			

+			if (MC_STATUS_INITIALIZED == status)

+			{

+				break;

+			}

+			else if (MC_STATUS_NOT_INITIALIZED == status)

+			{

+				// Switch to MobiCore to give it more CPU time.

+				if(!yield()) {

+					return false;

+				}

+			}

+			else if (MC_STATUS_HALT == status)

+			{

+				dumpMobicoreStatus();

+				LOG_E("MobiCore halted during init !!!, state is 0x%x", status);

+				return false;

+			}

+			else // MC_STATUS_BAD_INIT or anything else

+			{

+				LOG_E("MCI buffer init failed, state is 0x%x", status);

+				return false;

+			}

+		}

+	}

+

+	nqStartOut = (notificationQueue_t *) mciBuffer;

+	nqStartIn = (notificationQueue_t *) ((uint8_t *) nqStartOut

+			+ sizeof(notificationQueueHeader_t) + NQ_NUM_ELEMS

+			* sizeof(notification_t));

+

+	// Set up the NWd NQ

+	nq = new NotificationQueue(nqStartIn, nqStartOut, NQ_NUM_ELEMS);

+

+	mcpBuffer_t *mcpBuf = (mcpBuffer_t*) ((uint8_t *) mciBuffer + NQ_BUFFER_SIZE);

+

+	// Set up the MC flags

+	mcFlags = &(mcpBuf->mcFlags);

+

+	// Set up the MCP message

+	mcpMessage = &(mcpBuf->mcpMessage);

+

+	// convert virtual address of mapping to physical address for the init.

+	LOG_I("MCP: virt=%p, phys=%p, reused=%s",

+			pWsmMcp->virtAddr,

+			pWsmMcp->physAddr,

+			mciReused ? "true" : "false");

+	return true;

+}

+

+

+//------------------------------------------------------------------------------

+void TrustZoneDevice::initDeviceStep2(

+    void

+) {

+	// not needed

+}

+

+

+//------------------------------------------------------------------------------

+bool TrustZoneDevice::yield(

+    void

+) {

+    int32_t ret = pMcKMod->fcYield();

+    if (ret != 0) {

+        LOG_E("pMcKMod->fcYield() failed: %d", ret);

+    }

+    return ret == 0;

+}

+

+

+//------------------------------------------------------------------------------

+bool TrustZoneDevice::nsiq(

+    void

+) {

+    // 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 

+    // set the flag itself. IRQs and FIQs are disbaled for this period, so 

+    // there is no way the NWd can interrupt here. 

+

+    // not needed: mcFlags->schedule = MC_FLAG_SCHEDULE_NON_IDLE;

+

+    int32_t ret = pMcKMod->fcNSIQ();

+    if (ret != 0) {

+        LOG_E("pMcKMod->fcNSIQ() failed : %d", ret);

+        return false;

+    }

+    // now we have to wake the scheduler, so MobiCore gets CPU time.

+    schedSync.signal();

+    return true;

+}

+

+

+//------------------------------------------------------------------------------

+void TrustZoneDevice::notify(

+    uint32_t sessionId

+) {

+	do

+	{

+        // Check if it is MCP session - handle openSession() command

+        if (SID_MCP != sessionId)

+        {

+            // Check if session ID exists to avoid flooding of nq by clients

+            TrustletSession* ts = getTrustletSession(sessionId);

+            if (NULL == ts)

+            {

+                LOG_E("notify(): no session with id=%d", sessionId);

+                break;

+            }

+        }

+

+		LOG_I("notify(): Send notification for id=%d", sessionId);

+        // Notify MobiCore about new data

+

+        notification_t notification = {

+                // C++ does not support C99 designated initializers

+                    /* .sessionId = */ sessionId,

+                    /* .payload = */ 0

+                };

+

+        nq->putNotification(&notification);

+        //IMPROVEMENT-2012-03-07-maneaval What happens when/if nsiq fails?

+        //In the old days an exception would be thrown but it was uncertain

+        //where it was handled, some server(sock or Netlink). In that case

+        //the server would just die but never actually signaled to the client

+        //any error condition

+		nsiq();

+

+	} while(0);

+}

+

+//------------------------------------------------------------------------------

+uint32_t TrustZoneDevice::getMobicoreStatus(

+	void

+) {

+	uint32_t status;

+	//IMPROVEMENT-2012-03-07-maneaval Can fcInfo ever fail? Before it threw an

+	//exception but the handler depended on the context.

+	pMcKMod->fcInfo(0, &status, NULL);

+	

+	return status;

+}

+

+//------------------------------------------------------------------------------

+bool TrustZoneDevice::checkMciVersion(

+    void

+) {

+    int ret;

+    uint32_t version = 0;

+

+    ret = pMcKMod->fcInfo(MC_EXT_INFO_ID_MCI_VERSION, NULL, &version);

+    if (ret != 0) {

+        LOG_E("pMcKMod->fcInfo() failed with %d", ret);

+        return false;

+    }

+

+    // Run-time check.

+    char* errmsg;

+    if (!checkVersionOkMCI(version, &errmsg)) {

+        LOG_E("%s", errmsg);

+        return false;

+    }

+    LOG_I("%s", errmsg);

+    return true;

+}

+

+//------------------------------------------------------------------------------

+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);

+}

+

+//------------------------------------------------------------------------------

+bool TrustZoneDevice::waitSsiq(

+    void

+) {

+    uint32_t cnt;

+    if (!pMcKMod->waitSSIQ(&cnt))

+    {

+        LOG_E("pMcKMod->SSIQ() failed");

+        return false;

+    }

+    LOG_I("SSIQ Received, COUNTER = %u", cnt);

+    return true;

+}

+

+

+//------------------------------------------------------------------------------

+bool TrustZoneDevice::getMciInstance(

+    uint32_t  len,

+    CWsm_ptr  *mci,

+    bool	  *reused

+) {

+    addr_t    virtAddr;

+    uint32_t  handle;

+    addr_t    physAddr;

+    bool	  isMci = true;

+    if (0 == len)

+    {

+        LOG_E("allocateWsm() length is 0");

+        return false;

+    }

+

+    int ret = pMcKMod->mmap(

+                        len,

+                        &handle,

+                        &virtAddr,

+                        &physAddr,

+                        &isMci);

+    if (0 != ret)

+    {

+        LOG_E("pMcKMod->mmap() failed: %d", ret);

+        return false;

+    }

+    *mci = new CWsm(virtAddr, len, handle, physAddr);

+    // isMci will be set to true if buffer has been reused

+    *reused = isMci;

+    return true;

+}

+

+

+//------------------------------------------------------------------------------

+bool TrustZoneDevice::freeWsm(

+    CWsm_ptr  pWsm

+) {

+

+    int ret = pMcKMod->free(pWsm->handle);

+    if (ret != 0)

+    {

+        LOG_E("pMcKMod->free() failed: %d", ret);

+        return false;

+    }

+    delete pWsm;

+    return true;

+}

+

+

+//------------------------------------------------------------------------------

+CWsm_ptr TrustZoneDevice::registerWsmL2(

+    addr_t    buffer,

+    uint32_t  len,

+    uint32_t  pid

+) {

+    addr_t    physAddr;

+    uint32_t  handle;

+

+    int ret = pMcKMod->registerWsmL2(

+                        buffer,

+                        len,

+                        pid,

+                        &handle,

+                        &physAddr);

+    if (ret != 0)

+    {

+        LOG_E("ipMcKMod->registerWsmL2() failed: %d", ret);

+        return NULL;

+    }

+

+    return new CWsm(buffer,len,handle,physAddr);

+}

+

+

+//------------------------------------------------------------------------------

+CWsm_ptr TrustZoneDevice::allocateContiguousPersistentWsm(

+    uint32_t len

+) {

+    CWsm_ptr  pWsm = NULL;

+	do

+	{

+	    if (0 == len)

+	    {

+		    break;

+	    }

+

+	    // Allocate shared memory

+	    addr_t    virtAddr;

+	    uint32_t  handle;

+	    addr_t    physAddr;

+	    int ret = pMcKMod->mapPersistent(

+	                     len,

+	                     &handle,

+	                     &virtAddr,

+	                     &physAddr);

+    	if (0 != ret)

+    	{

+    		break;

+    	}

+

+    	// Register (vaddr,paddr) with device

+        pWsm = new CWsm(virtAddr,len,handle,physAddr);

+

+    } while(0);

+

+	// Return pointer to the allocated memory

+	return pWsm;

+}

+

+

+//------------------------------------------------------------------------------

+bool TrustZoneDevice::unregisterWsmL2(

+    CWsm_ptr  pWsm

+) {

+    int ret = pMcKMod->unregisterWsmL2(pWsm->handle);

+    if (ret != 0) {

+        LOG_E("pMcKMod->unregisterWsmL2 failed: %d", ret);

+        //IMPROVEMENT-2012-03-07 maneaval Make sure we don't leak objects

+        return false;

+    }

+    delete pWsm;

+    return true;

+}

+

+// REV add unregister (used after OPEN_SESSION)

+

+//------------------------------------------------------------------------------

+bool TrustZoneDevice::schedulerAvailable(

+	void

+){

+    return schedulerEnabled;

+}

+

+//------------------------------------------------------------------------------

+//TODO Schedulerthread to be switched off if MC is idle. Will be woken up when

+//     driver is called again.

+void TrustZoneDevice::schedule(

+    void

+) {

+    uint32_t timeslice = SCHEDULING_FREQ;

+	// loop forever

+	for (;;)

+	{

+		// Scheduling decision

+		if (MC_FLAG_SCHEDULE_IDLE == mcFlags->schedule)

+		{

+			// MobiCore is IDLE

+

+			// Prevent unnecessary consumption of CPU cycles -> Wait until S-SIQ received

+			schedSync.wait();

+

+		} else {

+			// MobiCore is not IDLE (anymore)

+

+			// Check timeslice

+			if (0 == timeslice)

+			{

+				// Slice expired, so force MC internal scheduling decision

+				timeslice = SCHEDULING_FREQ;

+				if(!nsiq()) {

+					break;

+				}

+			} else {

+				// Slice not used up, simply hand over control to the MC

+				timeslice--;

+				if(!yield()) {

+					break;

+				}

+			}

+		}

+	}

+}

+//------------------------------------------------------------------------------

+void TrustZoneDevice::handleIrq(

+	void

+	) {

+	LOG_I("Starting NQ IRQ handler...");

+	for (;;)

+	{

+		LOG_I("NQ empty now");

+		if(!waitSsiq()) {

+			LOG_E("Waiting for SSIQ failed");

+			break;

+		}

+		LOG_I("S-SIQ received");

+

+		// Save all the

+		for (;;)

+		{

+			notification_t *notification = nq->getNotification();

+			if (NULL == notification) {

+				break;

+			}

+			LOG_I("Received notification, sessionId=%d, payload=%d",

+			notification->sessionId, notification->payload);

+			

+			// check if the notification belongs to the MCP session

+			if (notification->sessionId == SID_MCP) {

+				// Signal main thread of the driver to continue after MCP

+				// command has been processed by the MC

+				signalMcpNotification();

+			}

+			else

+			{

+				// Get the NQ connection for the session ID

+				Connection *connection = getSessionConnection(notification->sessionId, notification);

+				if (connection == 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

+				{

+					LOG_I("Write notification!");

+					// Forward session ID and additional payload of

+					// notification to the TLC/Application layer

+					connection->writeData((void *)notification,

+								sizeof(notification_t));

+				}

+			}

+		}

+

+		// Wake up scheduler

+		schedSync.signal();

+	}

+	LOG_E("S-SIQ exception");

+	// Tell main thread that "something happened"

+	// MSH thread MUST not block!

+	DeviceIrqHandler::setExiting();

+	signalMcpNotification();

+}

+/** @} */

diff --git a/V008/Android/external/mobicore/daemon/Daemon/Device/Platforms/Generic/TrustZoneDevice.h b/V008/Android/external/mobicore/daemon/Daemon/Device/Platforms/Generic/TrustZoneDevice.h
new file mode 100644
index 0000000..e29b611
--- /dev/null
+++ b/V008/Android/external/mobicore/daemon/Daemon/Device/Platforms/Generic/TrustZoneDevice.h
@@ -0,0 +1,172 @@
+/** @addtogroup MCD_MCDIMPL_DAEMON_DEV

+ * @{

+ * @file

+ *

+ * Class for TrustZone Devices.

+ * TrustZone device implements communication functions needed for

+ * accessing MobiCore located in an TrustZone environment.

+ *

+ * <!-- 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 TRUSTZONEDEVICE_H_

+#define TRUSTZONEDEVICE_H_

+

+

+#include <stdint.h>

+

+#include "McTypes.h"

+

+#include "CSemaphore.h"

+#include "CMcKMod.h"

+#include "CWsm.h"

+

+#include "ExcDevice.h"

+#include "MobiCoreDevice.h"

+

+

+#define SCHEDULING_FREQ     5   /**< N-SIQ every n-th time */

+

+class TrustZoneDevice : public MobiCoreDevice {

+

+protected:

+	bool         schedulerEnabled; /**< NQ IRQ Scheduler enabling */

+	CSemaphore   schedSync; /**< Semaphore to synchronize S-SIQs with scheduler thread */

+	CMcKMod_ptr  pMcKMod; /**< kernel module */

+    CWsm_ptr     pWsmMcp; /**< WSM use for MCP */

+    CWsm_ptr     mobicoreInDDR;  /**< WSM used for Mobicore binary */

+    bool         mciReused;

+

+	/** Access functions to the MC Linux kernel module

+	 */

+	bool yield(

+	    void

+	);

+

+	bool nsiq(

+	    void

+	);

+

+	bool waitSsiq(

+	    void

+	);

+

+public:

+

+	TrustZoneDevice(

+	    void

+	);

+

+	virtual ~TrustZoneDevice(

+	    void

+	);

+

+//	static MobiCoreDevice* getDeviceInstance(

+//		void

+//	);

+	/** Set up MCI and wait till MC is initialized

+	 * 

+	 * @param devFile the device node to speak to.

+	 * @param loadMobiCore

+	 * @param mobicoreImage

+	 * @param enableScheduler

+	 *

+	 * @return true if mobicore is initialized

+	 * @trows ExcDevice

+	 */

+	bool initDevice(

+		const char	*devFile,

+		bool		loadMobiCore,

+		const char  *mobicoreImage,

+		bool		enableScheduler

+	);

+

+	void initDeviceStep2(

+		void

+    );

+

+	void notify(

+	    uint32_t sessionId

+	);

+	

+	void dumpMobicoreStatus(

+		void

+	);

+	

+	uint32_t getMobicoreStatus(

+		void

+	);

+

+	bool checkMciVersion(

+	    void

+	);

+

+	/** Memory allocation functions

+	 */

+    // TODO xgal: move memory registration from TzDevice to Device class

+	bool getMciInstance(

+        uint32_t  len,

+        CWsm_ptr  *mci,

+        bool	  *reused

+    );

+

+    bool freeWsm(

+        CWsm_ptr  pWsm

+    );

+

+    CWsm_ptr registerWsmL2(

+        addr_t    buffer,

+        uint32_t  len,

+        uint32_t  pid

+    );

+

+    bool unregisterWsmL2(

+        CWsm_ptr  pWsm

+    );

+

+    /**

+     * Allocates persistent WSM memory for TL (won't be fried when TLC exits).

+     */

+    CWsm_ptr allocateContiguousPersistentWsm(

+        uint32_t len

+    );

+

+	bool schedulerAvailable(

+	    void

+	);

+

+	void schedule(

+	    void

+	);

+

+	void handleIrq(

+	    void

+	);

+};

+

+#endif /* TRUSTZONEDEVICE_H_ */

+

+/** @} */

diff --git a/V008/Android/external/mobicore/daemon/Daemon/Device/TrustletSession.cpp b/V008/Android/external/mobicore/daemon/Daemon/Device/TrustletSession.cpp
new file mode 100644
index 0000000..c0dfe4e
--- /dev/null
+++ b/V008/Android/external/mobicore/daemon/Daemon/Device/TrustletSession.cpp
@@ -0,0 +1,83 @@
+/** @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>
+
+#define LOG_TAG	"McDaemon"
+#include "log.h"
+
+
+//------------------------------------------------------------------------------
+TrustletSession::TrustletSession(
+	Connection *deviceConnection,
+	uint32_t sessionId
+) {
+	this->deviceConnection = deviceConnection;
+	this->notificationConnection = NULL;
+	this->sessionId = sessionId;
+	sessionMagic = rand();
+}
+
+
+//------------------------------------------------------------------------------
+TrustletSession::~TrustletSession(
+	void
+) {
+	delete notificationConnection;
+}
+
+//------------------------------------------------------------------------------
+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();
+	}
+}
+
+/** @} */
diff --git a/V008/Android/external/mobicore/daemon/Daemon/Device/TrustletSession.h b/V008/Android/external/mobicore/daemon/Daemon/Device/TrustletSession.h
new file mode 100644
index 0000000..026f78b
--- /dev/null
+++ b/V008/Android/external/mobicore/daemon/Daemon/Device/TrustletSession.h
@@ -0,0 +1,74 @@
+/** @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 "Connection.h"
+#include <queue>
+
+
+class TrustletSession {
+
+public:
+
+	TrustletSession(
+		Connection *deviceConnection,
+		uint32_t sessionId
+	);
+
+	~TrustletSession(
+		void
+	);
+	
+	void queueNotification(
+		notification_t *notification
+	);
+	
+	void processQueuedNotifications(
+		void
+	);
+
+	uint32_t sessionId;
+	uint32_t sessionMagic; // Random data
+	Connection *deviceConnection;
+	Connection *notificationConnection;
+private:
+	std::queue<notification_t> notifications;
+};
+
+typedef std::list<TrustletSession*> trustletSessionList_t;
+typedef trustletSessionList_t::iterator trustletSessionIterator_t;
+
+#endif /* TRUSTLETSESSION_H_ */
+
+/** @} */
diff --git a/V008/Android/external/mobicore/daemon/Daemon/Device/public/ExcDevice.h b/V008/Android/external/mobicore/daemon/Daemon/Device/public/ExcDevice.h
new file mode 100644
index 0000000..e0b5d76
--- /dev/null
+++ b/V008/Android/external/mobicore/daemon/Daemon/Device/public/ExcDevice.h
@@ -0,0 +1,68 @@
+/** @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/V008/Android/external/mobicore/daemon/Daemon/Device/public/MobiCoreDevice.h b/V008/Android/external/mobicore/daemon/Daemon/Device/public/MobiCoreDevice.h
new file mode 100644
index 0000000..02268c0
--- /dev/null
+++ b/V008/Android/external/mobicore/daemon/Daemon/Device/public/MobiCoreDevice.h
@@ -0,0 +1,259 @@
+/** @addtogroup MCD_MCDIMPL_DAEMON_DEV

+ * @{

+ * @file

+ *

+ * MobiCore device.

+ * The MobiCore device class handles the MCP processing within the driver.

+ * Concrete devices implementing the communication behavior for the platforms have to be derived

+ * from this.

+ *

+ * <!-- 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 MOBICOREDEVICE_H_

+#define MOBICOREDEVICE_H_

+

+#include <stdint.h>

+#include <vector>

+

+#include "McTypes.h"

+

+#include "Mci/mcimcp.h"

+#include "mcLoadFormat.h"

+#include "MobiCoreDriverCmd.h"

+

+#include "Connection.h"

+#include "CWsm.h"

+

+#include "ExcDevice.h"

+#include "DeviceScheduler.h"

+#include "DeviceIrqHandler.h"

+#include "NotificationQueue.h"

+#include "TrustletSession.h"

+#include "mcVersionInfo.h"

+

+

+class MobiCoreDevice;

+

+typedef struct {

+	addr_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;

+

+/**

+ * 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 {

+

+protected:

+

+	NotificationQueue	*nq;	/**< Pointer to the notification queue within the MCI buffer */

+	mcFlags_t			*mcFlags; /**< Pointer to the MC flags within the MCI buffer */

+	mcpMessage_t		*mcpMessage; /**< Pointer to the MCP message structure within the MCI buffer */

+	CSemaphore			mcpSessionNotification; /**< Semaphore to synchronize incoming notifications for the MCP session */

+

+	trustletSessionList_t trustletSessions; /**< Available Trustlet Sessions */

+	mcVersionInfo_t		*mcVersionInfo; /**< MobiCore version info. */

+	bool				mcFault; /**< Signal RTM fault */

+

+	/* 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

+	 * exit function before waiting for any notifications from NWD then the daemon

+	 * will receive the openSession notification from RTM and the error notification

+	 * from the trustlet at the same time but because the internal objects in

+	 * the daemon are not yet completely setup then the error notification will

+	 * never be sent to the TLC!

+	 * 

+	 * This queue holds notifications received between the time the daemon

+	 * puts the MCP command for open session until the internal session objects

+	 * are setup corectly.

+	 */

+	std::queue<notification_t> notifications; /**<  Notifications queue for open session notification */

+

+	MobiCoreDevice();

+

+	void signalMcpNotification(

+		void

+	);

+

+	bool waitMcpNotification(

+		void

+	);

+

+private:

+

+	virtual bool yield(

+		void

+	) =0;

+

+	virtual bool nsiq(

+		void

+	) =0;

+

+	virtual bool waitSsiq(

+		void

+	) =0;

+

+public:

+

+	virtual ~MobiCoreDevice();

+

+	TrustletSession* getTrustletSession(

+		uint32_t sessionId

+	);

+

+	Connection* getSessionConnection(

+		uint32_t  sessionId,

+		notification_t *notification

+	);

+

+	bool open(

+		Connection  *connection);

+

+	void close(

+		Connection  *connection);

+

+	void openSession(

+		Connection                      *deviceConnection,

+		loadDataOpenSession_ptr         pLoadDataOpenSession,

+		mcDrvCmdOpenSessionPayload_ptr  pCmdOpenSessionPayload,

+		mcDrvRspOpenSessionPayload_ptr  pRspOpenSessionPayload);

+

+	TrustletSession *registerTrustletConnection(

+		Connection                    *connection,

+		mcDrvCmdNqConnectPayload_ptr  pCmdNqConnectPayload);

+

+	bool closeSession(

+		Connection  *deviceConnection,

+		uint32_t    sessionId);

+

+	virtual void notify(

+		uint32_t  sessionId

+	) = 0;

+

+	void mapBulk(

+		Connection                     *deviceConnection,

+		mcDrvCmdMapBulkMemPayload_ptr  pCmdMapBulkMemPayload,

+		mcDrvRspMapBulkMemPayload_ptr  pRspMapBulkMemPayload);

+

+	void unmapBulk(

+		Connection                       *deviceConnection,

+		mcDrvCmdUnmapBulkMemPayload_ptr  pCmdUnmapBulkMemPayload,

+		mcDrvRspUnmapBulkMemPayload_ptr  pRspUnmapBulkMemPayload);

+

+	void start();

+

+	void donateRam(

+			const uint32_t	donationSize

+	);

+

+	void getMobiCoreVersion(

+		mcDrvRspGetMobiCoreVersionPayload_ptr pRspGetMobiCoreVersionPayload

+	);

+	

+	bool getMcFault() { return mcFault; }

+	

+	void queueUnknownNotification(

+		notification_t notification

+	);

+

+	virtual void dumpMobicoreStatus(

+			void

+	) = 0;

+

+	virtual uint32_t getMobicoreStatus(

+		void

+	) = 0;

+

+	virtual bool schedulerAvailable(

+		void

+	) = 0;

+

+	virtual void schedule(

+		void

+	) = 0;

+

+	virtual void handleIrq(

+		void

+	) = 0;

+

+	virtual bool freeWsm(

+		CWsm_ptr  pWsm

+	) = 0;

+

+	/**

+	 * Initialize MobiCore.

+	 *

+	 * @param devFile the device node to speak to.

+	 * @param loadMobiCore

+	 * @param mobicoreImage

+	 * @param enableScheduler

+	 *

+	 * @returns true if MobiCore is already initialized.

+	 * */

+	virtual bool initDevice(

+		const char	*devFile,

+		bool		loadMobiCore,

+		const char  *mobicoreImage,

+		bool		enableScheduler

+	) = 0;

+

+	virtual void initDeviceStep2(

+		void

+	) = 0;

+

+	virtual bool getMciInstance(

+		uint32_t  len,

+		CWsm_ptr  *mci,

+		bool	  *reused

+	) = 0;

+

+	virtual CWsm_ptr registerWsmL2(

+		addr_t    buffer,

+		uint32_t  len,

+		uint32_t  pid

+	) = 0;

+

+	virtual bool unregisterWsmL2(

+		CWsm_ptr  pWsm

+	) = 0;

+

+	/**

+		* Allocates persistent WSM memory for TL (won't be released when TLC exits).

+		*/

+	virtual CWsm_ptr allocateContiguousPersistentWsm(

+		uint32_t len

+	) = 0;

+};

+

+#endif /* MOBICOREDEVICE_H_ */

+

+/** @} */

diff --git a/V008/Android/external/mobicore/daemon/Daemon/MobiCoreDriverDaemon.cpp b/V008/Android/external/mobicore/daemon/Daemon/MobiCoreDriverDaemon.cpp
new file mode 100644
index 0000000..e77afc7
--- /dev/null
+++ b/V008/Android/external/mobicore/daemon/Daemon/MobiCoreDriverDaemon.cpp
@@ -0,0 +1,1076 @@
+/** @addtogroup MCD_MCDIMPL_DAEMON_CONHDLR

+ * @{

+ * @file

+ *

+ * Entry of the MobiCore Driver.

+ *

+ * <!-- 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 <cstdlib>

+#include <signal.h>

+#include <fcntl.h>

+#include <fstream>

+#include <cassert>

+

+#include "MobiCoreDriverCmd.h"

+#include "mcVersion.h"

+#include "mcVersionHelper.h"

+#include "mcDrvModuleApi.h"

+

+#include "MobiCoreDriverDaemon.h"

+#include "MobiCoreRegistry.h"

+#include "MobiCoreDevice.h"

+

+#include "NetlinkServer.h"

+

+#define LOG_TAG	"McDaemon"

+#include "log.h"

+

+#define DRIVER_TCI_LEN 100

+

+#include "Mci/mci.h"

+

+MC_CHECK_VERSION(MCI, 0, 2);

+MC_CHECK_VERSION(SO, 2, 0);

+MC_CHECK_VERSION(MCLF, 2, 0);

+MC_CHECK_VERSION(CONTAINER, 2, 0); 

+

+static void checkMobiCoreVersion(MobiCoreDevice* mobiCoreDevice);

+

+//------------------------------------------------------------------------------

+MobiCoreDriverDaemon::MobiCoreDriverDaemon(

+	bool enableScheduler,

+	bool loadMobicore,

+	std::string mobicoreImage,

+	unsigned int donateRamSize,

+	bool loadDriver,

+	std::string driverPath

+) {

+	mobiCoreDevice = NULL;

+

+	this->enableScheduler = enableScheduler;

+	this->loadMobicore = loadMobicore;

+	this->mobicoreImage = mobicoreImage;

+	this->donateRamSize = donateRamSize;

+	this->loadDriver = loadDriver;

+	this->driverPath = driverPath;

+

+	for (int i = 0; i < MAX_SERVERS; i++) {

+		servers[i] = NULL;

+	}

+}

+

+//------------------------------------------------------------------------------

+MobiCoreDriverDaemon::~MobiCoreDriverDaemon(

+    void

+) {

+	// Unload any device drivers might have been loaded

+	driverResourcesList_t::iterator it;

+	for(it = driverResources.begin(); it != driverResources.end(); it++) {

+		MobicoreDriverResources *res = *it;

+		mobiCoreDevice->closeSession(res->conn, res->sessionId);

+		mobiCoreDevice->unregisterWsmL2(res->pTciWsm);

+	}

+	delete mobiCoreDevice;

+	for (int i = 0; i < MAX_SERVERS; i++) {

+		delete servers[i];

+		servers[i] = NULL;

+	}

+}

+

+

+//------------------------------------------------------------------------------

+void MobiCoreDriverDaemon::run(

+	void

+) {

+	LOG_I("Daemon starting up...");

+	LOG_I("Socket interface version is %u.%u", DAEMON_VERSION_MAJOR, DAEMON_VERSION_MINOR);

+#ifdef MOBICORE_COMPONENT_BUILD_TAG

+	LOG_I("%s", MOBICORE_COMPONENT_BUILD_TAG);

+#else

+	#warning "MOBICORE_COMPONENT_BUILD_TAG is not defined!"

+#endif

+	LOG_I("Build timestamp is %s %s", __DATE__, __TIME__);

+

+	int i;

+

+	mobiCoreDevice = getDeviceInstance();

+

+	LOG_I("Daemon scheduler is %s", enableScheduler? "enabled" : "disabled");

+	if(!mobiCoreDevice->initDevice(

+		MC_DRV_MOD_DEVNODE_FULLPATH,

+		loadMobicore,

+		mobicoreImage.c_str(),

+		enableScheduler)) {

+		LOG_E("%s: Failed to initialize MobiCore!", __FUNCTION__);

+		return;

+	}

+	mobiCoreDevice->start();

+

+	checkMobiCoreVersion(mobiCoreDevice);

+

+	if (donateRamSize > 0) {

+		// Donate additional RAM to MC

+		LOG_I("Donating %u Kbytes to Mobicore", donateRamSize / 1024);

+		mobiCoreDevice->donateRam(donateRamSize);

+	}

+

+	// Load device driver if requested

+	if (loadDriver) {

+		loadDeviceDriver(driverPath);

+	}

+

+	LOG_I("Servers will be created!");

+	// Start listening for incoming TLC connections

+	servers[0] = new NetlinkServer(this);

+	servers[1] = new Server(this, SOCK_PATH);

+	LOG_I("Servers created!");

+

+	// Start all the servers

+	for (i = 0; i < MAX_SERVERS; i++) {

+		servers[i]->start();

+	}

+

+	// then wait for them to exit

+	for (i = 0; i < MAX_SERVERS; i++) {

+		servers[i]->join();

+	}

+}

+

+

+//------------------------------------------------------------------------------

+MobiCoreDevice *MobiCoreDriverDaemon::getDevice(

+    uint32_t deviceId

+) {

+	// Always return the trustZoneDevice as it is currently the only one supported

+	if(MC_DEVICE_ID_DEFAULT != deviceId)

+		return NULL;

+	return mobiCoreDevice;

+}

+

+

+//------------------------------------------------------------------------------

+void MobiCoreDriverDaemon::dropConnection(

+    Connection *connection

+) {

+	// Check if a Device has already been registered with the connection

+	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

+		device->close(connection);

+	}

+}

+

+

+//------------------------------------------------------------------------------

+size_t MobiCoreDriverDaemon::writeResult(

+    Connection	*connection,

+    mcDrvRsp_t  code

+) {

+	if (0 != code) {

+		LOG_E("writeResult(): set error code %d",code);

+	}

+	return connection->writeData(&code, sizeof(mcDrvRsp_t));

+}

+

+//------------------------------------------------------------------------------

+bool MobiCoreDriverDaemon::loadDeviceDriver(

+	std::string driverPath

+) {

+	bool ret = false;

+	CWsm_ptr pWsm = NULL, pTciWsm = NULL;

+	regObject_t *regObj = NULL;

+	Connection *conn = NULL;

+	uint8_t *tci = NULL;

+	mcDrvRspOpenSession_t rspOpenSession;

+	

+	do

+	{

+		//mobiCoreDevice

+		ifstream fs(driverPath.c_str(), ios_base::binary);

+		if (!fs) {

+			LOG_E("%s: failed: cannot open %s", __func__, driverPath.c_str());

+			break;

+		}

+		

+		LOG_I("%s: loading %s", __func__, driverPath.c_str());

+		

+		regObj = mcRegistryGetDriverBlob(driverPath.c_str());

+		if (regObj == NULL) {

+			break;;

+		}

+

+		LOG_I("registering L2 in kmod, p=%p, len=%i",

+				regObj->value, regObj->len);

+		

+		// Prepare the interface structure for memory registration, then

+		// register virtual memory in kernel module, create L2 table

+		// TODO xgal: refactor naming of datatypes and WSM handling

+		pWsm = mobiCoreDevice->registerWsmL2(

+			(addr_t)(regObj->value), regObj->len, 0);

+		if (pWsm == NULL)

+		{

+			LOG_E("allocating WSM for Trustlet failed");

+			break;

+		}

+		// Initialize information data of open session command

+		loadDataOpenSession_t loadDataOpenSession;

+		loadDataOpenSession.baseAddr = pWsm->physAddr;

+		loadDataOpenSession.offs = ((uint32_t) regObj->value) & 0xFFF;

+		loadDataOpenSession.len = regObj->len;

+		loadDataOpenSession.tlHeader = (mclfHeader_ptr) regObj->value;

+		

+		mcDrvCmdOpenSessionPayload_t  openSessionPayload;

+		tci = (uint8_t*)malloc(DRIVER_TCI_LEN);

+		pTciWsm = mobiCoreDevice->registerWsmL2(

+			(addr_t)tci, DRIVER_TCI_LEN, 0);

+		if (pTciWsm == NULL)

+		{

+			LOG_E("allocating WSM TCI for Trustlet failed");

+			break;

+		}

+		openSessionPayload.deviceId = MC_DEVICE_ID_DEFAULT;

+		openSessionPayload.tci = (uint32_t)pTciWsm->physAddr;

+		openSessionPayload.len = DRIVER_TCI_LEN;

+

+		conn = new Connection();

+		mobiCoreDevice->openSession(

+			conn,

+			&loadDataOpenSession,

+			&openSessionPayload,

+			&(rspOpenSession.payload));

+		

+		// Unregister physical memory from kernel module.

+		// This will also destroy the WSM object.

+		mobiCoreDevice->unregisterWsmL2(pWsm);

+		pWsm = NULL;

+		

+		// Free memory occupied by Trustlet data

+		free(regObj);

+		regObj = NULL;

+		

+		if (rspOpenSession.payload.mcResult != MC_MCP_RET_OK)

+		{

+			LOG_E("%s: rspOpenSession mcResult %d", __func__, 

+				  rspOpenSession.payload.mcResult);

+			break;

+		}

+		

+		ret = true;

+	} while (false);

+	// Free all allocated resources

+	if (ret == false) {

+		LOG_I("%s: Freeing previously allocated resources!", __func__);

+		if (pWsm != NULL) {

+			if(!mobiCoreDevice->unregisterWsmL2(pWsm)) {

+				// At least make sure we don't leak the WSM object

+				delete pWsm;

+			}

+		}

+		// No matter if we free NULL objects

+		free(regObj);

+		

+		if (conn != NULL) {

+			delete conn;

+		}

+	} else if (conn != NULL) {

+		driverResources.push_back(new MobicoreDriverResources(

+			conn, tci, pTciWsm, rspOpenSession.payload.sessionId));

+	}

+	

+	return ret;

+}

+

+//------------------------------------------------------------------------------

+void MobiCoreDriverDaemon::processOpenDevice(

+    Connection	*connection

+) {

+	do

+	{

+		// Read entire command data

+		mcDrvCmdOpenDevicePayload_t cmdOpenDevicePayload;

+		uint32_t rlen = connection->readData(

+							&(cmdOpenDevicePayload),

+							sizeof(cmdOpenDevicePayload));

+		if (rlen != sizeof(cmdOpenDevicePayload))

+		{

+			LOG_E("processOpenDevice(): OpenSession length error: %d", rlen);

+			writeResult(connection, MC_DRV_RSP_PAYLOAD_LENGTH_ERROR);

+			break;

+		}

+

+		// Check if device has been registered to the connection

+		MobiCoreDevice *device = (MobiCoreDevice *) (connection->connectionData);

+		if (NULL != device)

+		{

+			LOG_E("processOpenDevice(): device already set");

+			writeResult(connection, MC_DRV_RSP_DEVICE_ALREADY_OPENED);

+			break;

+		}

+

+		LOG_I("processOpenDevice(): deviceId is %d",

+				cmdOpenDevicePayload.deviceId);

+

+		// Get device for device ID

+		device = getDevice(cmdOpenDevicePayload.deviceId);

+

+		// Check if a device for the given name has been found

+		if (NULL == device)

+		{

+			LOG_E("invalid deviceId");

+			writeResult(connection, MC_DRV_INVALID_DEVICE_NAME);

+			break;

+		}

+

+		// Register device object with connection

+		if (false == device->open(connection))

+		{

+			LOG_E("processOpenDevice(): device->open() failed");

+			writeResult(connection, MC_DRV_RSP_FAILED);

+			break;

+		}

+

+		// Return result code to client lib (no payload)

+		writeResult(connection, MC_DRV_RSP_OK);

+

+	} while (false);

+}

+

+

+//------------------------------------------------------------------------------

+void MobiCoreDriverDaemon::processCloseDevice(

+    Connection  *connection

+) {

+	do

+	{

+		// there is no payload to read

+

+		// Device required

+		MobiCoreDevice *device = (MobiCoreDevice *) (connection->connectionData);

+		if (NULL == device)

+		{

+			LOG_E("processCloseDevice(): no device");

+			writeResult(connection, MC_DRV_RSP_DEVICE_NOT_OPENED);

+			break;

+		}

+

+		// No command data will be read

+		// Unregister device object with connection

+		device->close(connection);

+

+		// there is no payload

+		writeResult(connection, MC_DRV_RSP_OK);

+

+	} while (false);

+}

+

+

+//------------------------------------------------------------------------------

+void MobiCoreDriverDaemon::processOpenSession(

+    Connection  *connection

+) {

+	do

+	{

+		// Read entire command data

+		mcDrvCmdOpenSessionPayload_t  cmdOpenSessionPayload;

+		uint32_t rlen = connection->readData(

+							&cmdOpenSessionPayload,

+							sizeof(cmdOpenSessionPayload));

+		if (rlen != sizeof(cmdOpenSessionPayload))

+		{

+			LOG_E("processOpenSession(): OpenSession length error: %d", rlen);

+			writeResult(connection, MC_DRV_RSP_PAYLOAD_LENGTH_ERROR);

+			break;

+		}

+

+		// Device required

+		MobiCoreDevice  *device = (MobiCoreDevice *) (connection->connectionData);

+		if (NULL == device)

+		{

+			writeResult(connection, MC_DRV_RSP_DEVICE_NOT_OPENED);

+			break;

+		}

+

+		// Get service blob from registry

+		regObject_t *regObj = mcRegistryGetServiceBlob(

+				(mcUuid_t*) &(cmdOpenSessionPayload.uuid));

+

+		// Call preinstalled variant of method

+		mcDrvRspOpenSession_t rspOpenSession;

+		if (NULL == regObj)

+		{

+			writeResult(connection, MC_DRV_RSP_TRUSTLET_NOT_FOUND);

+			break;

+		}

+		if (0 == regObj->len)

+		{

+			free(regObj);

+			writeResult(connection, MC_DRV_RSP_TRUSTLET_NOT_FOUND);

+			break;

+		}

+		else

+		{

+			// Trustlet retrieved from registry

+

+			LOG_I("registering L2 in kmod, p=%p, len=%i",

+					regObj->value,

+					regObj->len);

+

+			// Prepare the interface structure for memory registration, then

+			// register virtual memory in kernel module, create L2 table

+			// TODO xgal: refactor naming of datatypes and WSM handling

+			CWsm_ptr pWsm = device->registerWsmL2(

+				(addr_t)(regObj->value),

+				regObj->len,

+				0);

+			if (NULL == pWsm)

+			{

+				LOG_E("allocating WSM for Trustlet failed");

+				writeResult(connection, MC_DRV_RSP_FAILED);

+				break;

+			}

+			// Initialize information data of open session command

+			loadDataOpenSession_t loadDataOpenSession;

+			loadDataOpenSession.baseAddr = pWsm->physAddr;

+			loadDataOpenSession.offs = ((uint32_t) regObj->value) & 0xFFF;

+			loadDataOpenSession.len = regObj->len;

+			loadDataOpenSession.tlHeader = (mclfHeader_ptr) regObj->value;

+			

+			device->openSession(

+						connection,

+						&loadDataOpenSession,

+						&cmdOpenSessionPayload,

+						&(rspOpenSession.payload));

+

+			// Unregister physical memory from kernel module.

+			// This will also destroy the WSM object.

+			if(!device->unregisterWsmL2(pWsm)) {

+				writeResult(connection, MC_DRV_RSP_FAILED);

+				break;

+			}

+

+			// Free memory occupied by Trustlet data

+			free(regObj);

+		}

+

+		uint32_t mcResult = rspOpenSession.payload.mcResult;

+		if (MC_MCP_RET_OK != mcResult)

+		{

+			LOG_E("rspOpenSession mcResult %d", mcResult);

+			writeResult(connection, MC_DRV_RSP_FAILED);

+			break;

+		}

+

+		rspOpenSession.header.responseId = MC_DRV_RSP_OK;

+		connection->writeData(

+						&rspOpenSession,

+						sizeof(rspOpenSession));

+

+	} while (false);

+}

+

+

+//------------------------------------------------------------------------------

+void MobiCoreDriverDaemon::processCloseSession(

+    Connection  *connection

+) {

+	do

+	{

+		// Read entire command data

+		mcDrvCmdCloseSessionPayload_t  cmdCloseSessionPayload;

+		uint32_t rlen = connection->readData(

+							&cmdCloseSessionPayload,

+							sizeof(cmdCloseSessionPayload));

+		if (rlen != sizeof(cmdCloseSessionPayload))

+		{

+			LOG_E("processCloseSession(): CloseSessionPayload length error: %d",rlen);

+			writeResult(connection, MC_DRV_RSP_PAYLOAD_LENGTH_ERROR);

+			break;

+		}

+

+		// Device required

+		MobiCoreDevice *device = (MobiCoreDevice *) (connection->connectionData);

+		if (NULL == device)

+		{

+			LOG_E("processCloseSession(): device is NULL");

+			writeResult(connection, MC_DRV_RSP_DEVICE_NOT_OPENED);

+			break;

+		}

+

+		device->closeSession(

+					connection,

+					cmdCloseSessionPayload.sessionId);

+

+		// there is no payload

+		writeResult(connection, MC_DRV_RSP_OK);

+

+	} while (false);

+}

+

+

+//------------------------------------------------------------------------------

+void MobiCoreDriverDaemon::processNqConnect(

+    Connection  *connection

+) {

+	do

+	{

+		// Set up the channel for sending SWd notifications to the client

+		// MC_DRV_CMD_NQ_CONNECT is only allowed on new connections not

+		// associated with a device. If a device is registered to the

+		// connection NQ_CONNECT is not allowed.

+

+		// Read entire command data

+		mcDrvCmdNqConnectPayload_t  cmdNqConnectPayload;

+		size_t rlen = connection->readData(

+										&(cmdNqConnectPayload),

+										sizeof(cmdNqConnectPayload));

+		if (rlen != sizeof(cmdNqConnectPayload))

+		{

+			LOG_E("processNqConnect(): NqConnect length error: %d",rlen);

+			writeResult(connection,MC_DRV_RSP_PAYLOAD_LENGTH_ERROR);

+			break;

+		}

+

+		// device must be empty

+		MobiCoreDevice *device = (MobiCoreDevice *)(connection->connectionData);

+		if (NULL != device)

+		{

+			LOG_E("processNqConnect(): device already set\n");

+			writeResult(connection,MC_DRV_RSP_COMMAND_NOT_ALLOWED);

+			break;

+		}

+

+		// Remove the connection from the list of known client connections

+		for (int i = 0; i < MAX_SERVERS; i++) {

+			servers[i]->detachConnection(connection);

+		}

+

+		device = getDevice(cmdNqConnectPayload.deviceId);

+		if (NULL == device)

+		{

+			//TODO xgal: how about ...NO_SUCH_DEVICE

+			LOG_E("processNqConnect(): no device found\n");

+			writeResult(connection, MC_DRV_RSP_FAILED);

+			break;

+		}

+

+		TrustletSession* ts = device->registerTrustletConnection(

+								connection,

+								&cmdNqConnectPayload);

+		if (!ts) {

+			LOG_E("processNqConnect(): registerTrustletConnection() failed!");

+			writeResult(connection, MC_DRV_RSP_FAILED);

+			break;

+		}

+

+		writeResult(connection, MC_DRV_RSP_OK);

+		ts->processQueuedNotifications();

+		

+

+	} while (false);

+}

+

+

+//------------------------------------------------------------------------------

+void MobiCoreDriverDaemon::processNotify(

+    Connection  *connection

+) {

+	do

+	{

+		// Read entire command data

+		mcDrvCmdNotifyPayload_t  cmdNotifyPayload;

+		uint32_t rlen = connection->readData(

+							&cmdNotifyPayload,

+							sizeof(cmdNotifyPayload));

+		if (sizeof(cmdNotifyPayload) != rlen)

+		{

+			LOG_E("processNotify(): NotifyPayload length error: %d", rlen);

+			// NOTE: notify fails silently

+			// writeResult(connection,MC_DRV_RSP_PAYLOAD_LENGTH_ERROR);

+			break;

+		}

+

+		// Device required

+		MobiCoreDevice *device = (MobiCoreDevice *) (connection->connectionData);

+		if (NULL == device)

+		{

+			LOG_E("processNotify(): device is NULL");

+			// NOTE: notify fails silently

+			// writeResult(connection,MC_DRV_RSP_DEVICE_NOT_OPENED);

+			break;

+		}

+

+		// REV axh: we cannot trust the clientLib to give us a valid

+		//          sessionId here. Thus we have to check that it belongs to

+		//          the clientLib's process.

+

+		device->notify(cmdNotifyPayload.sessionId);

+		// NOTE: for notifications there is no response at all

+	} while(0);

+}

+

+

+//------------------------------------------------------------------------------

+void MobiCoreDriverDaemon::processMapBulkBuf(

+    Connection  *connection

+) {

+	do

+	{

+		// Read entire command data

+		mcDrvCmdMapBulkMemPayload_t  cmdMapBulkMemPayload;

+		uint32_t rlen = connection->readData(

+								&cmdMapBulkMemPayload,

+								sizeof(cmdMapBulkMemPayload));

+		if (rlen != sizeof(cmdMapBulkMemPayload))

+		{

+			LOG_E("processMapBulkBuf(): MapBulkMemPayload length error: %d", rlen);

+			writeResult(connection, MC_DRV_RSP_PAYLOAD_LENGTH_ERROR);

+			break;

+		}

+

+		// Device required

+		MobiCoreDevice *device = (MobiCoreDevice *) (connection->connectionData);

+		if (NULL == device)

+		{

+			LOG_E("processMapBulkBuf(): device is NULL");

+			writeResult(connection, MC_DRV_RSP_DEVICE_NOT_OPENED);

+			break;

+		}

+

+		// Map bulk memory to secure world

+		mcDrvRspMapBulkMem_t rspMapBulk;

+		device->mapBulk(

+					connection,

+					&cmdMapBulkMemPayload,

+					&(rspMapBulk.payload));

+

+		uint32_t mcResult = rspMapBulk.payload.mcResult;

+		if (MC_MCP_RET_OK != mcResult)

+		{

+			LOG_E("processMapBulkBuf(): rspMapBulk.mcResult=%d", mcResult);

+			writeResult(connection, MC_DRV_RSP_FAILED);

+			break;

+		}

+

+		rspMapBulk.header.responseId = MC_DRV_RSP_OK;

+		connection->writeData(&rspMapBulk, sizeof(rspMapBulk));

+

+	} while (false);

+}

+

+

+//------------------------------------------------------------------------------

+void MobiCoreDriverDaemon::processUnmapBulkBuf(

+    Connection  *connection

+) {

+	do

+	{

+		// Read entire command data

+		mcDrvCmdUnmapBulkMemPayload_t cmdUnmapBulkMemPayload;

+		uint32_t rlen = connection->readData(

+							&cmdUnmapBulkMemPayload,

+							sizeof(cmdUnmapBulkMemPayload));

+		if (rlen != sizeof(cmdUnmapBulkMemPayload))

+		{

+			LOG_E("processMapBulkBuf(): UnmapBulkMem length error: %d", rlen);

+			writeResult(connection, MC_DRV_RSP_PAYLOAD_LENGTH_ERROR);

+			break;

+		}

+

+		// Device required

+		MobiCoreDevice *device = (MobiCoreDevice *) (connection->connectionData);

+		if (NULL == device)

+		{

+			writeResult(connection, MC_DRV_RSP_DEVICE_NOT_OPENED);

+			break;

+		}

+

+		// Unmap bulk memory from secure world

+		mcDrvRspUnmapBulkMem_t rspUnmpaBulk;

+

+		device->unmapBulk(

+					connection,

+					&cmdUnmapBulkMemPayload,

+					&(rspUnmpaBulk.payload));

+

+		uint32_t mcResult = rspUnmpaBulk.payload.mcResult;

+		if (MC_MCP_RET_OK != mcResult)

+		{

+			LOG_E("processUnmapBulkBuf(): rspUnmpaBulk mcResult %d", mcResult);

+			writeResult(connection, MC_DRV_RSP_FAILED);

+			break;

+		}

+

+		rspUnmpaBulk.header.responseId = MC_DRV_RSP_OK;

+		connection->writeData(

+						&rspUnmpaBulk,

+						sizeof(rspUnmpaBulk));

+

+	} while (false);

+}

+

+

+//------------------------------------------------------------------------------

+void MobiCoreDriverDaemon::processGetVersion(

+    Connection  *connection

+) {

+	mcDrvRspGetVersion_t rspGetVersion;

+	rspGetVersion.payload.version = MC_MAKE_VERSION(DAEMON_VERSION_MAJOR, DAEMON_VERSION_MINOR);

+

+	rspGetVersion.header.responseId = MC_DRV_RSP_OK;

+	connection->writeData(

+		&rspGetVersion,

+		sizeof(rspGetVersion));

+}

+

+//------------------------------------------------------------------------------

+void MobiCoreDriverDaemon::processGetMobiCoreVersion(

+    Connection  *connection

+) {

+	// Device required

+	MobiCoreDevice *device = (MobiCoreDevice *) (connection->connectionData);

+	if (NULL == device) {

+		writeResult(connection, MC_DRV_RSP_DEVICE_NOT_OPENED);

+		return;

+	}

+

+	// Get MobiCore version info from secure world.

+	mcDrvRspGetMobiCoreVersion_t rspGetMobiCoreVersion;

+

+	device->getMobiCoreVersion(

+		&rspGetMobiCoreVersion.payload);

+

+	uint32_t mcResult = rspGetMobiCoreVersion.payload.mcResult;

+	if (MC_MCP_RET_OK != mcResult) {

+		LOG_E("processGetMobiCoreVersion(): rspGetMobiCoreVersion mcResult %d", mcResult);

+		writeResult(connection, MC_DRV_RSP_FAILED);

+		return;

+	}

+

+	rspGetMobiCoreVersion.header.responseId = MC_DRV_RSP_OK;

+	connection->writeData(

+		&rspGetMobiCoreVersion,

+		sizeof(rspGetMobiCoreVersion));

+}

+

+

+//------------------------------------------------------------------------------

+bool MobiCoreDriverDaemon::handleConnection(

+    Connection *connection

+) {

+    bool ret = false;

+	static CMutex mutex;

+	

+	/* In case of RTM fault do not try to signal anything to MobiCore

+	 * just answer NO to all incoming connections! */

+	if (mobiCoreDevice->getMcFault()) {

+		return false;

+	}

+

+	mutex.lock();

+	do

+	{

+		// Read header

+		mcDrvCommandHeader_t mcDrvCommandHeader;

+		uint32_t rlen = connection->readData(

+							&(mcDrvCommandHeader),

+							sizeof(mcDrvCommandHeader));

+

+		if (0 == rlen)

+		{

+			LOG_I("handleConnection(): Connection closed.");

+			break;

+		}

+		if (sizeof(mcDrvCommandHeader) != rlen)

+		{

+			LOG_E("handleConnection(): Header length error: %d", rlen);

+			break;

+		}

+		ret = true;

+

+		switch (mcDrvCommandHeader.commandId)

+		{

+			//-----------------------------------------

+			case MC_DRV_CMD_OPEN_DEVICE:

+				processOpenDevice(connection);

+				break;

+			//-----------------------------------------

+			case MC_DRV_CMD_CLOSE_DEVICE:

+				processCloseDevice(connection);

+				break;

+			//-----------------------------------------

+			case MC_DRV_CMD_OPEN_SESSION:

+				processOpenSession(connection);

+				break;

+			//-----------------------------------------

+			case MC_DRV_CMD_CLOSE_SESSION:

+				processCloseSession(connection);

+				break;

+			//-----------------------------------------

+			case MC_DRV_CMD_NQ_CONNECT:

+				processNqConnect(connection);

+				break;

+			//-----------------------------------------

+			case MC_DRV_CMD_NOTIFY:

+				processNotify(connection);

+				break;

+			//-----------------------------------------

+			case MC_DRV_CMD_MAP_BULK_BUF:

+				processMapBulkBuf(connection);

+				break;

+			//-----------------------------------------

+			case MC_DRV_CMD_UNMAP_BULK_BUF:

+				processUnmapBulkBuf(connection);

+				break;

+			//-----------------------------------------

+			case MC_DRV_CMD_GET_VERSION:

+				processGetVersion(connection);

+				break;

+			//-----------------------------------------

+			case MC_DRV_CMD_GET_MOBICORE_VERSION:

+				processGetMobiCoreVersion(connection);

+				break;

+			//-----------------------------------------

+

+			default:

+				LOG_E("handleConnection(): unknown command: %d=0x%x",

+						mcDrvCommandHeader.commandId,

+						mcDrvCommandHeader.commandId);

+				ret = false;

+				break;

+		}

+	} while(0);

+	mutex.unlock();

+

+	return ret;

+}

+

+//------------------------------------------------------------------------------

+/**

+ * Print daemon command line options

+ */

+

+void printUsage(

+	int argc,

+	char *args[]

+) {

+	fprintf(stderr, "usage: %s [-mdsbh]\n", args[0]);

+	fprintf(stderr, "Start MobiCore Daemon\n\n");

+	fprintf(stderr, "-h\t\tshow this help\n");

+	fprintf(stderr, "-b\t\tfork to background\n");

+	fprintf(stderr, "-m IMAGE\tload mobicore from IMAGE to DDR\n");

+	fprintf(stderr, "-s\t\tdisable daemon scheduler(default enabled)\n");

+	fprintf(stderr, "-d SIZE\t\tdonate SIZE bytes to mobicore(disabled on most platforms)\n");

+	fprintf(stderr, "-r DRIVER\t\tMobiCore driver to load at start-up\n");

+}

+

+//------------------------------------------------------------------------------

+/**

+ * Signal handler for daemon termination

+ * Using this handler instead of the standard libc one ensures the daemon

+ * can cleanup everything -> read() on a FD will now return EINTR

+ */

+void terminateDaemon(

+	int signum

+) {

+	LOG_E("Signal %d received\n", signum);

+}

+

+//------------------------------------------------------------------------------

+/**

+ * Main entry of the MobiCore Driver Daemon.

+ */

+int main(

+    int argc,

+    char *args[]

+) {

+    // Create the MobiCore Driver Singleton

+    MobiCoreDriverDaemon *mobiCoreDriverDaemon = NULL;

+	// Process signal action

+    struct sigaction action;

+	

+	// Read the Command line options

+	extern char *optarg;

+	extern int optopt;

+	int c, errFlag = 0;

+	// Scheduler enabled by default

+	int schedulerFlag = 1;

+	// Mobicore loading disable by default

+	int mobicoreFlag = 0;

+	// Autoload driver at start-up

+	int driverLoadFlag = 0;

+	std::string mobicoreImage, driverPath;

+	// Ram donation disabled by default

+	int donationSize = 0;

+	// By default don't fork

+	bool forkDaemon = false;

+	while ((c = getopt(argc, args, "m:d:r:sbh")) != -1) {

+		switch(c) {

+			case 'h': /* Help */

+				errFlag++;

+				break;

+			case 's': /* Disable Scheduler */

+				schedulerFlag = 0;

+				break;

+			case 'd': /* Ram Donation size */

+				donationSize = atoi(optarg);

+				break;

+			case 'm': /* Load mobicore image */

+				mobicoreFlag = 1;

+				mobicoreImage = optarg;

+				break;

+			case 'b': /* Fork to background */

+				forkDaemon = true;

+				break;

+			case 'r': /* Load mobicore driver at start-up */

+				driverLoadFlag = 1;

+				driverPath = optarg;

+				break;

+			case ':':       /* -d or -m without operand */

+				fprintf(stderr, "Option -%c requires an operand\n", optopt);

+				errFlag++;

+				break;

+			case '?':

+				fprintf(stderr,

+						"Unrecognized option: -%c\n", optopt);

+				errFlag++;

+		}

+	}

+	if (errFlag) {

+		printUsage(argc, args);

+		exit(2);

+	}

+

+	// We should fork the daemon to background

+	if (forkDaemon == true) {

+		int i = fork();

+		if (i < 0) {

+			exit(1);

+		}

+		// Parent

+		else if (i > 0) {

+			exit(0);

+		}

+	

+		// obtain a new process group */

+		setsid();

+		/* close all descriptors */

+		for (i = getdtablesize();i >= 0; --i) {

+			close(i);

+		}

+		// STDIN, STDOUT and STDERR should all point to /dev/null */

+		i = open("/dev/null",O_RDWR); 

+		dup(i);

+		dup(i);

+		/* ignore tty signals */

+		signal(SIGTSTP,SIG_IGN);

+		signal(SIGTTOU,SIG_IGN);

+		signal(SIGTTIN,SIG_IGN);

+	}

+

+	// Set up the structure to specify the new action.

+	action.sa_handler = terminateDaemon;

+	sigemptyset (&action.sa_mask);

+	action.sa_flags = 0;

+	sigaction (SIGINT, &action, NULL);

+	sigaction (SIGHUP, &action, NULL);

+	sigaction (SIGTERM, &action, NULL);

+	signal(SIGPIPE, SIG_IGN);

+	

+	mobiCoreDriverDaemon = new MobiCoreDriverDaemon(

+		/* Scheduler status */

+		schedulerFlag,

+		/* Mobicore loading to DDR */

+		mobicoreFlag,

+		mobicoreImage,

+		/* Ram Donation */

+		donationSize,

+		/* Auto Driver loading */

+		driverLoadFlag,

+		driverPath);

+

+	// Start the driver

+	mobiCoreDriverDaemon->run();

+

+	delete mobiCoreDriverDaemon;

+

+	// This should not happen

+	LOG_E("Exiting MobiCoreDaemon");

+

+	return EXIT_FAILURE;

+}

+

+//------------------------------------------------------------------------------

+static void checkMobiCoreVersion(

+	MobiCoreDevice* mobiCoreDevice

+) {

+	bool failed = false;

+

+	// Get MobiCore version info.

+	mcDrvRspGetMobiCoreVersionPayload_t versionPayload;

+	mobiCoreDevice->getMobiCoreVersion(&versionPayload);

+

+	if (versionPayload.mcResult != MC_MCP_RET_OK) {

+		LOG_E("Failed to obtain MobiCore version info. MCP return code: %u", versionPayload.mcResult);

+		failed = true;

+

+	} else {

+		LOG_I("Product ID is %s", versionPayload.versionInfo.productId);

+

+		// Check MobiCore version info.

+		char* msg;

+		if (!checkVersionOkMCI(versionPayload.versionInfo.versionMci, &msg)) {

+			LOG_E("%s", msg);

+			failed = true;

+		}

+		LOG_I("%s", msg);

+		if (!checkVersionOkSO(versionPayload.versionInfo.versionSo, &msg)) {

+			LOG_E("%s", msg);

+			failed = true;

+		}

+		LOG_I("%s", msg);

+		if (!checkVersionOkMCLF(versionPayload.versionInfo.versionMclf, &msg)) {

+			LOG_E("%s", msg);

+			failed = true;

+		}

+		LOG_I("%s", msg);

+		if (!checkVersionOkCONTAINER(versionPayload.versionInfo.versionContainer, &msg)) {

+			LOG_E("%s", msg);

+			failed = true;

+		}

+		LOG_I("%s", msg);

+	}

+

+	if (failed) {

+		exit(1);

+	}

+}

+

+/** @} */

diff --git a/V008/Android/external/mobicore/daemon/Daemon/MobiCoreDriverDaemon.h b/V008/Android/external/mobicore/daemon/Daemon/MobiCoreDriverDaemon.h
new file mode 100644
index 0000000..a178767
--- /dev/null
+++ b/V008/Android/external/mobicore/daemon/Daemon/MobiCoreDriverDaemon.h
@@ -0,0 +1,193 @@
+/** @addtogroup MCD_MCDIMPL_DAEMON_CONHDLR

+ * @{

+ * @file

+ *

+ * MobiCore driver class.

+ * The MobiCore driver class implements the ConnectionHandler 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 MOBICOREDRIVER_H_

+#define MOBICOREDRIVER_H_

+

+#include "Server/public/ConnectionHandler.h"

+#include "Server/public/Server.h"

+

+#include "MobiCoreDevice.h"

+#include <string>

+#include <list>

+

+

+#define MAX_SERVERS 2

+

+class MobicoreDriverResources {

+public:

+	Connection *conn;

+	CWsm* pTciWsm;

+	uint8_t *tci;

+	uint32_t sessionId;

+	

+	MobicoreDriverResources(

+		Connection *conn,

+		uint8_t* tci,

+		CWsm* pTciWsm,

+		uint32_t sessionId

+	) {

+		this->conn = conn;

+		this->pTciWsm = pTciWsm;

+		this->sessionId = sessionId;

+	};

+};

+

+typedef std::list<MobicoreDriverResources*> driverResourcesList_t;

+

+class MobiCoreDriverDaemon : ConnectionHandler {

+

+public:

+

+	/**

+	 * Create daemon object

+	 *

+	 * @param enableScheduler Enable NQ IRQ scheduler

+	 * @param loadMobicore Load mobicore image to DDR

+	 * @param mobicoreImage Mobicore image path

+	 * @param donateRamSize Ram donation size in bytes

+	 */

+	MobiCoreDriverDaemon(

+		bool enableScheduler,

+		/**< Mobicore loading to DDR */

+		bool loadMobicore,

+		std::string mobicoreImage,

+		unsigned int donateRamSize,

+		/**< Mobicore driver loading at start-up */

+		bool loadDriver,

+		std::string driverPath

+	);

+

+	virtual ~MobiCoreDriverDaemon(

+	    void

+	);

+

+	void dropConnection(

+	    Connection *connection

+	);

+

+	bool handleConnection(

+	    Connection *connection

+	);

+

+	void run(

+		void

+	);

+

+private:

+

+	MobiCoreDevice *mobiCoreDevice;

+	/**< Flag to start/stop the scheduler */

+	bool enableScheduler;

+	/**< Flag to load mobicore image to DDR */

+	bool loadMobicore;

+	/**< Mobicore image location */

+	std::string mobicoreImage;

+	/**< Ram size to donate */

+	unsigned int donateRamSize;

+	bool loadDriver;

+	std::string driverPath;

+	/**< List of resources for the loaded drivers */

+	driverResourcesList_t driverResources;

+	/**< List of servers processing connections */	

+	Server *servers[MAX_SERVERS];

+

+	size_t writeResult(

+		Connection  *connection,

+		mcDrvRsp_t  code

+	);

+

+	/**

+		* Resolve a device ID to a MobiCore device.

+		*

+		* @param deviceId Device identifier of the device.

+		* @return Reference to the device or NULL if device could not be found.

+		*/

+	MobiCoreDevice *getDevice(

+		uint32_t deviceId

+	);

+	

+	/**

+	 * Load Device driver

+	 *

+	 * @param driverPath Path to the driver file

+	 * @return True for success/false for failure

+	 */

+	bool loadDeviceDriver(

+		std::string driverPath

+	);

+

+	void processOpenDevice(

+		Connection *connection

+	);

+

+	void processOpenSession(

+		Connection *connection

+	);

+

+	void processNqConnect(

+		Connection *connection

+	);

+

+	void processCloseDevice(

+		Connection *connection

+	);

+

+	void processNotify(

+		Connection *connection

+	);

+

+	void processCloseSession(

+		Connection *connection

+	);

+

+	void processMapBulkBuf(

+		Connection *connection

+	);

+

+	void processUnmapBulkBuf(

+		Connection *connection

+	);

+

+	void processGetVersion(

+		Connection *connection

+	);

+

+	void processGetMobiCoreVersion(

+		Connection *connection

+	);

+};

+

+#endif /* MOBICOREDRIVER_H_ */

+

+/** @} */

diff --git a/V008/Android/external/mobicore/daemon/Daemon/Server/Android.mk b/V008/Android/external/mobicore/daemon/Daemon/Server/Android.mk
new file mode 100644
index 0000000..1831793
--- /dev/null
+++ b/V008/Android/external/mobicore/daemon/Daemon/Server/Android.mk
@@ -0,0 +1,18 @@
+# =============================================================================
+#
+# MC driver server files
+#
+# =============================================================================
+
+# This is not a separate module.
+# Only for inclusion by other modules.
+
+MY_MCDRV_SERVER_PATH := $(call my-dir)
+MY_MCDRV_SERVER_PATH_REL := Server
+
+# Add new folders with header files here
+LOCAL_C_INCLUDES += $(MY_MCDRV_SERVER_PATH)/public
+
+# Add new source files here
+LOCAL_SRC_FILES += $(MY_MCDRV_SERVER_PATH_REL)/Server.cpp \
+		$(MY_MCDRV_SERVER_PATH_REL)/NetlinkServer.cpp
diff --git a/V008/Android/external/mobicore/daemon/Daemon/Server/NetlinkServer.cpp b/V008/Android/external/mobicore/daemon/Daemon/Server/NetlinkServer.cpp
new file mode 100644
index 0000000..bb6c0e2
--- /dev/null
+++ b/V008/Android/external/mobicore/daemon/Daemon/Server/NetlinkServer.cpp
@@ -0,0 +1,273 @@
+/** @addtogroup MCD_MCDIMPL_DAEMON_SRV

+ * @{

+ * @file

+ *

+ * Connection server.

+ *

+ * Handles incoming socket connections from clients using the MobiCore driver.

+ *

+ * <!-- 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 "public/NetlinkServer.h"

+#include <unistd.h>

+#include <string.h>

+#include <errno.h>

+#include <linux/netlink.h>

+

+#include <stdlib.h>

+#include "NetlinkConnection.h"

+#include <signal.h>

+

+#define LOG_TAG	"McDaemon"

+#include "log.h"

+

+//------------------------------------------------------------------------------

+NetlinkServer::NetlinkServer(

+    ConnectionHandler * connectionHandler

+):Server(connectionHandler, "dummy") {

+}

+

+

+//------------------------------------------------------------------------------

+void NetlinkServer::run(

+) {

+	do

+	{

+		LOG_I("%s: start listening on netlink bus", __func__);

+		

+		// Open a socket

+		serverSock = socket(PF_NETLINK, SOCK_DGRAM,  MC_DAEMON_NETLINK);

+		if (serverSock < 0)

+		{

+			LOG_E("run(): can't open socket, errno=%d", errno);

+			break;

+		}

+

+		// Fill in address structure and bind to socket

+		struct sockaddr_nl src_addr;

+		struct nlmsghdr *nlh = NULL;

+		struct iovec iov;

+		struct msghdr msg;

+		uint32_t len;

+		

+		memset(&src_addr, 0, sizeof(src_addr));

+		src_addr.nl_family = AF_NETLINK;

+		src_addr.nl_pid = MC_DAEMON_PID;  /* daemon pid */

+		src_addr.nl_groups = 0;  /* not in mcast groups */

+		if(bind(serverSock, (struct sockaddr*)&src_addr, sizeof(src_addr)) < 0){

+			LOG_E("bind() to server socket failed, errno=%d(%s)", 

+					errno, strerror(errno));

+			close(serverSock);

+			break;

+		}

+

+		// Start reading the socket

+		LOG_I("\n********* successfully initialized *********\n");

+

+		for (;;)

+		{

+			// This buffer will be taken over by the connection it was routed to

+			nlh=(struct nlmsghdr *)malloc(NLMSG_SPACE(MAX_PAYLOAD));

+			memset(&msg, 0, sizeof(msg));

+			iov.iov_base = (void *)nlh;

+			iov.iov_len = NLMSG_SPACE(MAX_PAYLOAD);

+			msg.msg_iov = &iov;

+			msg.msg_iovlen = 1;

+			msg.msg_name = &src_addr;

+			msg.msg_namelen = sizeof(src_addr);

+			

+			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) {

+				LOG_E("%s: recvmsg() failed, errno=%d(%s)", 

+						__func__, errno, strerror(errno));

+				break;

+			}

+			

+            if (NLMSG_OK(nlh, len)) {

+				handleMessage(nlh);

+			} else {

+				break;

+			}

+		}

+	} while(false);

+

+    LOG_E("%s: exiting due to error, errno=%d(%s)",

+		  __func__, errno, strerror(errno));

+}

+

+//------------------------------------------------------------------------------

+void NetlinkServer::handleMessage(

+    struct nlmsghdr *nlh

+) {

+	uint32_t seq = nlh->nlmsg_seq;

+	uint32_t pid = nlh->nlmsg_pid;

+	//LOG_I("%s: Handling NQ message for pid %u seq %u...", __func__, pid, seq);

+	uint64_t hash = hashConnection(pid, seq);

+	/* First cleanup the connection list */

+	cleanupConnections();

+

+	NetlinkConnection *connection = findConnection(hash);

+	// This is a message from a new client

+	if (connection == NULL) {

+		//LOG_I("%s: Cound't find the connection, creating a new one", __func__);

+		connection = new NetlinkConnection(this, serverSock, pid, seq);

+		// Add the new connection

+		insertConnection(hash, connection);

+	}

+

+	connection->handleMessage(nlh);

+

+	// Only handle connections which have not been detached

+	if(connection->detached == false)

+	{

+		if (!connectionHandler->handleConnection(connection))

+		{

+			LOG_I("%s: No command processed.", __func__);

+			connection->socketDescriptor = -1;

+			//Inform the driver

+			connectionHandler->dropConnection(connection);

+			

+			// Remove connection from list

+			removeConnection(hash);

+			connection->socketDescriptor = -1;

+			delete connection;

+		}

+		// If connection data is set to NULL then device close has been called 

+		// so we must remove all connections associated with this hash

+		else if (connection->connectionData == NULL && 

+			connection->detached == false)

+		{

+			delete connection;

+		}

+	}

+}

+

+

+//------------------------------------------------------------------------------

+void NetlinkServer::detachConnection(

+    Connection *connection

+) {

+	connection->detached = true;

+}

+

+

+//------------------------------------------------------------------------------

+NetlinkServer::~NetlinkServer(

+	void

+) {

+	connectionMap_t::iterator i;

+	// Shut down the server socket

+	close(serverSock);

+

+	// Destroy all client connections

+	for (i = peerConnections.begin(); i != peerConnections.end(); i++) {

+		if (i->second->detached == false) {

+			delete i->second;

+		}

+	}

+	peerConnections.clear();

+}

+

+

+//------------------------------------------------------------------------------

+NetlinkConnection* NetlinkServer::findConnection(

+    uint64_t hash

+) {

+	connectionMap_t::iterator i = peerConnections.find(hash);

+	if (i != peerConnections.end()) {

+		return i->second;

+	}

+

+	return NULL;

+}

+

+

+//------------------------------------------------------------------------------

+void NetlinkServer::insertConnection(

+	uint64_t hash,

+    NetlinkConnection *connection

+) {

+	peerConnections[hash] = connection;

+}

+

+/* This is called from multiple threads! */

+//------------------------------------------------------------------------------

+void NetlinkServer::removeConnection(

+	uint64_t hash

+) {

+	connectionMap_t::iterator i = peerConnections.find(hash);

+	if (i != peerConnections.end()){

+		peerConnections.erase(i);

+	}

+}

+

+//------------------------------------------------------------------------------

+void NetlinkServer::cleanupConnections(

+	void

+) {

+	connectionMap_t::reverse_iterator i;

+	pid_t pid;

+	NetlinkConnection *connection = NULL;

+	// Destroy all client connections

+	for (i = peerConnections.rbegin(); i != peerConnections.rend(); ++i) {

+		connection = i->second;

+		// Only 16 bits are for the actual PID, the rest is session magic

+		pid = connection->peerPid & 0xFFFF;

+		//LOG_I("%s: checking PID %u", __func__, pid);

+		// Check if the peer pid is still alive

+		if (pid == 0) {

+			continue;

+		}

+		if (kill(pid, 0)) {

+			bool detached = connection->detached;

+			LOG_I("%s: PID %u has died, cleaning up session 0x%X", 

+				  __func__, pid, connection->peerPid);

+			

+			connection->socketDescriptor = -1;

+			//Inform the driver

+			connectionHandler->dropConnection(connection);

+			

+			// We aren't handling this connection anymore no matter what

+			removeConnection(connection->hash);

+			

+			// Remove connection from list only if detached, the detached

+			// connections are managed by the device

+			if (detached == false) {

+				delete connection;

+			}

+			if (peerConnections.size() == 0) {

+				break;

+			}

+			i = peerConnections.rbegin();

+		}

+	}

+}

+

+/** @} */

diff --git a/V008/Android/external/mobicore/daemon/Daemon/Server/Server.cpp b/V008/Android/external/mobicore/daemon/Daemon/Server/Server.cpp
new file mode 100644
index 0000000..fecf4d1
--- /dev/null
+++ b/V008/Android/external/mobicore/daemon/Daemon/Server/Server.cpp
@@ -0,0 +1,251 @@
+/** @addtogroup MCD_MCDIMPL_DAEMON_SRV

+ * @{

+ * @file

+ *

+ * Connection server.

+ *

+ * Handles incoming socket connections from clients using the MobiCore driver.

+ *

+ * <!-- 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 "public/Server.h"

+#include <unistd.h>

+#include <string.h>

+#include <errno.h>

+

+#define LOG_TAG	"McDaemon"

+#include "log.h"

+

+

+//------------------------------------------------------------------------------

+Server::Server(

+    ConnectionHandler * connectionHandler,

+    const char *localAddr

+) :socketAddr(localAddr)

+{

+	this->connectionHandler = connectionHandler;

+}

+

+

+//------------------------------------------------------------------------------

+void Server::run(

+	void

+) {

+    do

+    {

+		LOG_I("run(): start listening on socket %s", socketAddr.c_str());

+

+		// Open a socket (a UNIX domain stream socket)

+		serverSock = socket(AF_UNIX, SOCK_STREAM, 0);

+		if (serverSock < 0)

+		{

+			LOG_E("run(): can't open stream socket, errno=%d", errno);

+			break;

+		}

+

+		// Fill in address structure and bind to socket

+		struct sockaddr_un  serverAddr;

+		serverAddr.sun_family = AF_UNIX;

+		strncpy(serverAddr.sun_path, socketAddr.c_str(), sizeof(serverAddr.sun_path) - 1);

+

+		uint32_t len = strlen(serverAddr.sun_path) + sizeof(serverAddr.sun_family);

+		// Make the socket in the Abstract Domain(no path but everyone can connect)

+		serverAddr.sun_path[0] = 0;

+		if (bind(serverSock, (struct sockaddr *) &serverAddr, len) < 0)

+		{

+			LOG_E("bind() to server socket failed, errno=%d", errno);

+		}

+

+		// Start listening on the socket

+		if (listen(serverSock, LISTEN_QUEUE_LEN) < 0)

+		{

+			LOG_E("run(): listen() failed, errno=%d", errno);

+			break;

+		}

+

+		LOG_I("\n********* successfully initialized *********\n");

+

+		for (;;)

+		{

+			fd_set fdReadSockets;

+

+		    // Clear FD for select()

+			FD_ZERO(&fdReadSockets);

+

+			// Select server socket descriptor

+			FD_SET(serverSock, &fdReadSockets);

+			int maxSocketDescriptor = serverSock;

+

+			// Select socket descriptor of all connections

+			for (connectionIterator_t iterator = peerConnections.begin();

+			     iterator != peerConnections.end();

+			     ++iterator)

+			{

+			    Connection *connection = (*iterator);

+			    int peerSocket = connection->socketDescriptor;

+				FD_SET(peerSocket, &fdReadSockets);

+				if (peerSocket > maxSocketDescriptor)

+				{

+					maxSocketDescriptor = peerSocket;

+				}

+			}

+

+			// Wait for activities, select() returns the number of sockets

+			// which require processing

+			LOG_I("run(): waiting on sockets");

+			int numSockets = select(

+			                    maxSocketDescriptor + 1,

+			                    &fdReadSockets,

+			                    NULL, NULL, NULL);

+

+			// Check if select failed

+			if (numSockets < 0)

+			{

+				LOG_E("run(): select() failed, errno=%d", errno);

+				break;

+			}

+

+            // actually, this should not happen.

+			if (0 == numSockets)

+            {

+			    LOG_W("run(): select() returned 0, spurious event?.");

+			    continue;

+            }

+

+			LOG_I("run(): events on %d socket(s).", numSockets);

+

+			// Check if a new client connected to the server socket

+			if (FD_ISSET(serverSock, &fdReadSockets))

+			{

+				do

+				{

+					LOG_I("run(): new connection");

+					numSockets--;

+

+					struct sockaddr_un clientAddr;

+					socklen_t clientSockLen = sizeof(clientAddr);

+					int clientSock = accept(

+										serverSock,

+										(struct sockaddr*) &clientAddr,

+										&clientSockLen);

+

+					if (clientSock <= 0)

+					{

+						LOG_E("run(): accept() failed, errno=%d", errno);

+						break;

+					}

+

+					Connection *connection = new Connection(clientSock, &clientAddr);

+					peerConnections.push_back(connection);

+					LOG_I("run(): added new connection");

+				} while (false);

+

+				// we can ignore any errors from accepting a new connection.

+				// If this fail, the client has to deal with it, we are done

+				// and nothing has changed.

+			}

+

+			// Handle traffic on existing client connections

+			connectionIterator_t iterator = peerConnections.begin();

+			while ( (iterator != peerConnections.end())

+			        && (numSockets > 0) )

+            {

+				Connection *connection = (*iterator);

+				int peerSocket = connection->socketDescriptor;

+

+				if (!FD_ISSET(peerSocket, &fdReadSockets))

+				{

+				    ++iterator;

+				    continue;

+				}

+

+				numSockets--;

+

+				// the connection will be terminated if command processing

+				// fails

+				if (!connectionHandler->handleConnection(connection))

+				{

+					LOG_I("run(): No command processed.");

+

+					//Inform the driver

+					connectionHandler->dropConnection(connection);

+

+					// Remove connection from list

+					delete connection;

+					iterator = peerConnections.erase(iterator);

+					continue;

+				}

+

+				++iterator;

+			}

+		}

+

+	} while (false);

+

+    LOG_E("run(): exiting due to error, errno=%d", errno);

+}

+

+

+//------------------------------------------------------------------------------

+void Server::detachConnection(

+    Connection *connection

+) {

+	LOG_I("Detaching NQ connection...");

+

+	for (connectionIterator_t iterator = peerConnections.begin();

+			iterator != peerConnections.end();

+			++iterator)

+	{

+		Connection *tmpConnection = (*iterator);

+		if (tmpConnection == connection)

+		{

+			peerConnections.erase(iterator);

+			LOG_I("NQ connection detached");

+			break;

+		}

+	}

+}

+

+

+//------------------------------------------------------------------------------

+Server::~Server(

+	void

+) {

+	// Shut down the server socket

+	close(serverSock);

+

+	// Destroy all client connections

+	connectionIterator_t iterator = peerConnections.begin();

+	while (iterator != peerConnections.end())

+	{

+		Connection *tmpConnection = (*iterator);

+		delete tmpConnection;

+		iterator = peerConnections.erase(iterator);

+	}

+}

+

+/** @} */

diff --git a/V008/Android/external/mobicore/daemon/Daemon/Server/public/ConnectionHandler.h b/V008/Android/external/mobicore/daemon/Daemon/Server/public/ConnectionHandler.h
new file mode 100644
index 0000000..fc96fdc
--- /dev/null
+++ b/V008/Android/external/mobicore/daemon/Daemon/Server/public/ConnectionHandler.h
@@ -0,0 +1,68 @@
+/** @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/V008/Android/external/mobicore/daemon/Daemon/Server/public/NetlinkServer.h b/V008/Android/external/mobicore/daemon/Daemon/Server/public/NetlinkServer.h
new file mode 100644
index 0000000..d53fb25
--- /dev/null
+++ b/V008/Android/external/mobicore/daemon/Daemon/Server/public/NetlinkServer.h
@@ -0,0 +1,156 @@
+/** @addtogroup MCD_MCDIMPL_DAEMON_SRV

+ * @{

+ * @file

+ *

+ * Connection server.

+ *

+ * Handles incoming socket connections from clients using the MobiCore driver.

+ *

+ * Iterative socket server using Netlink dgram 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 NETLINKSERVER_H_

+#define NETLINKSERVER_H_

+

+#include <sys/types.h>

+#include <sys/socket.h>

+#include <sys/un.h>

+#include <linux/netlink.h>

+#include <cstdio>

+#include <map>

+

+#include "NetlinkConnection.h"

+#include "ConnectionHandler.h"

+#include "Server.h"

+

+class NetlinkServer: public Server, public NetlinkConnectionManager {

+public:

+	/**

+	 * Server contructor.

+	 *

+	 * @param connectionHanler Connection handler to pass incoming connections to.

+	 */

+    NetlinkServer(

+		ConnectionHandler * connectionHandler

+	);

+

+	/**

+	 * Server destructor.

+	 * All available connections will be terminated. Resources will be freed.

+	 */

+    virtual ~NetlinkServer(

+		void

+	);

+

+	/**

+	 * Start server and listen for incoming connections.

+	 * Implements the central socket server loop. Incoming connections will be stored.

+	 */

+	virtual void run(

+		void

+	);

+

+	/**

+	 * Remove a connection object from the list of available connections.

+	 * Detaching is required for notification connections wich are never used to transfer command

+	 * data from TLCs to the driver. If the function succeeds, freeing the connection will no longer

+     * be the server's responsability.

+	 *

+	 * @param connection The connection object to remove.

+	 */

+	virtual void detachConnection(

+		Connection *connection

+	);

+

+private:

+    /**

+     * Handle incomming Netlink message.

+     * It routes the incomming packet to the apropriate connection based on the packet's

+     * session magic.

+     *

+     * @param nlh The netlink message's header + payload

+     */   

+    void handleMessage(

+        struct nlmsghdr *nlh

+    );

+    

+    /**

+	 * Retreive connection based on hash.

+	 * Search the peer connections hashmap for a hash and return 

+	 * the associated Connection object

+     *

+	 * @param seq The seq to search

+     * @return The NetlinkConnection object if found or NULL if not found

+     */

+    NetlinkConnection* findConnection(

+		uint64_t hash

+    );

+    

+    /**

+     * Insert a connection in the peer connection hashmap

+     * Insert a new connection in the peer connections hashmap. If there is 

+	 * already such a connection it will be overriden!

+     *

+	 * @param seq The seq to use

+     * @param connection The connection object to insert

+     */

+    void insertConnection(

+		uint64_t hash,

+        NetlinkConnection *connection

+    );

+    

+    /**

+     * Remove a connection from the peer connections

+     * Remove the connection associated with seq from the peer list. 

+	 * This doesn't actually free the connection object!

+     * If the seq is invalid nothing happens.

+     *

+     * @param seq The seq to use

+     */

+    void removeConnection(

+		uint64_t hash

+    );

+	

+	

+	/**

+	 * Check for sessions started by applications that died(exited)

+	 * Remove the connections to applications that are not active anymore

+	 * If the application has died then all the sessions associated with it

+	 * should be closed!

+	 *

+	 */

+	void cleanupConnections(

+		void

+	);

+

+	connectionMap_t peerConnections; /**< Hashmap with connections to clients */

+};

+

+#endif /* SERVER_H_ */

+

+/** @} */

diff --git a/V008/Android/external/mobicore/daemon/Daemon/Server/public/Server.h b/V008/Android/external/mobicore/daemon/Daemon/Server/public/Server.h
new file mode 100644
index 0000000..dd0f36a
--- /dev/null
+++ b/V008/Android/external/mobicore/daemon/Daemon/Server/public/Server.h
@@ -0,0 +1,107 @@
+/** @addtogroup MCD_MCDIMPL_DAEMON_SRV

+ * @{

+ * @file

+ *

+ * Connection server.

+ *

+ * Handles incoming socket connections from clients using the MobiCore driver.

+ *

+ * Iterative socket server using UNIX domain stream 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 SERVER_H_

+#define SERVER_H_

+

+#include <sys/types.h>

+#include <sys/socket.h>

+#include <sys/un.h>

+#include <string>

+#include <cstdio>

+#include <vector>

+#include "CThread.h"

+#include "ConnectionHandler.h"

+

+/** Number of incoming connections that can be queued.

+ * Additional clients will generate the error ECONNREFUSED. */

+#define LISTEN_QUEUE_LEN	(16)

+

+

+class Server: public CThread {

+

+public:

+	/**

+	 * Server contructor.

+	 *

+	 * @param connectionHanler Connection handler to pass incoming connections to.

+	 * @param localAdrerss Pointer to a zero terminated string containing the file to listen to.

+	 */

+	Server(

+		ConnectionHandler * connectionHandler,

+		const char *localAddr

+	);

+

+	/**

+	 * Server destructor.

+	 * All available connections will be terminated. Resources will be freed.

+	 */

+    virtual ~Server(

+		void

+	);

+

+	/**

+	 * Start server and listen for incoming connections.

+	 * Implements the central socket server loop. Incoming connections will be stored.

+	 */

+	virtual void run(

+	);

+

+	/**

+	 * Remove a connection object from the list of available connections.

+	 * Detaching is required for notification connections wich are never used to transfer command

+	 * data from TLCs to the driver. If the function succeeds, the connection object will no longer

+	 * be handled by the server.

+	 *

+	 * @param connection The connection object to remove.

+	 */

+    virtual void detachConnection(

+		Connection *connection

+	);

+

+protected:

+	int serverSock;

+	string socketAddr;

+	ConnectionHandler   *connectionHandler;	/**< Connection handler registered to the server */

+	

+private:

+	connectionList_t    peerConnections; /**< Connections to devices */

+

+};

+

+#endif /* SERVER_H_ */

+

+/** @} */

diff --git a/V008/Android/external/mobicore/daemon/Daemon/public/MobiCoreDriverCmd.h b/V008/Android/external/mobicore/daemon/Daemon/public/MobiCoreDriverCmd.h
new file mode 100644
index 0000000..0a7f669
--- /dev/null
+++ b/V008/Android/external/mobicore/daemon/Daemon/public/MobiCoreDriverCmd.h
@@ -0,0 +1,327 @@
+/** @addtogroup MCD_MCDIMPL_DAEMON
+ * @{
+ * @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 MCDAEMON_H_
+#define MCDAEMON_H_
+
+#include <inttypes.h>      // ANSI C99
+
+
+#define SOCK_PATH "#mcdaemon"
+#include "mcUuid.h"
+#include "mcVersionInfo.h"
+
+typedef enum {
+    MC_DRV_CMD_PING                 = 0,
+    MC_DRV_CMD_GET_INFO             = 1,
+    MC_DRV_CMD_OPEN_DEVICE          = 2,
+    MC_DRV_CMD_CLOSE_DEVICE         = 3,
+    MC_DRV_CMD_NQ_CONNECT           = 4,
+	MC_DRV_CMD_OPEN_SESSION         = 5,
+	MC_DRV_CMD_CLOSE_SESSION        = 6,
+    MC_DRV_CMD_NOTIFY               = 7,
+	MC_DRV_CMD_MAP_BULK_BUF         = 8,
+	MC_DRV_CMD_UNMAP_BULK_BUF       = 9,
+    MC_DRV_CMD_GET_VERSION          = 10,
+    MC_DRV_CMD_GET_MOBICORE_VERSION = 11,
+} mcDrvCmd_t;
+
+
+typedef enum {
+	MC_DRV_RSP_OK                     = 0,
+	MC_DRV_RSP_FAILED                 = 1,
+    MC_DRV_RSP_DEVICE_NOT_OPENED      = 2,
+    MC_DRV_RSP_DEVICE_ALREADY_OPENED  = 3,
+	MC_DRV_RSP_COMMAND_NOT_ALLOWED    = 4,
+	MC_DRV_INVALID_DEVICE_NAME        = 5,
+	MC_DRV_RSP_MAP_BULK_ERRO          = 6,
+	MC_DRV_RSP_TRUSTLET_NOT_FOUND     = 7,
+	MC_DRV_RSP_PAYLOAD_LENGTH_ERROR	  = 8,
+} mcDrvRsp_t;
+
+
+typedef struct {
+    uint32_t  commandId;
+} mcDrvCommandHeader_t, *mcDrvCommandHeader_ptr;
+
+typedef struct {
+    uint32_t  responseId;
+} mcDrvResponseHeader_t, *mcDrvResponseHeader_ptr;
+
+#define MC_DEVICE_ID_DEFAULT    0 /**< The default device ID */
+
+
+//--------------------------------------------------------------
+typedef struct{
+	uint32_t  deviceId;
+} mcDrvCmdOpenDevicePayload_t, *mcDrvCmdOpenDevicePayload_ptr;
+
+typedef struct{
+    mcDrvCommandHeader_t         header;
+    mcDrvCmdOpenDevicePayload_t  payload;
+} mcDrvCmdOpenDevice_t, *mcDrvCmdOpenDevice_ptr;
+
+
+typedef struct{
+    // empty
+} mcDrvRspOpenDevicePayload_t, *mcDrvRspOpenDevicePayload_ptr;
+
+typedef struct{
+    mcDrvResponseHeader_t        header;
+    mcDrvRspOpenDevicePayload_t  payload;
+} mcDrvRspOpenDevice_t, *mcDrvRspOpenDevice_ptr;
+
+
+//--------------------------------------------------------------
+typedef struct{
+    mcDrvCommandHeader_t          header;
+    // no payload here because close has none.
+    // If we use an empty struct, C++ will count it as 4 bytes.
+    // This will write too much into the socket at write(cmd,sizeof(cmd))
+} mcDrvCmdCloseDevice_t, *mcDrvCmdCloseDevice_ptr;
+
+
+typedef struct{
+    // empty
+} mcDrvRspCloseDevicePayload_t, *mcDrvRspCloseDevicePayload_ptr;
+
+typedef struct{
+    mcDrvResponseHeader_t         header;
+    mcDrvRspCloseDevicePayload_t  payload;
+} mcDrvRspCloseDevice_t, *mcDrvRspCloseDevice_ptr;
+
+
+//--------------------------------------------------------------
+typedef struct{
+	uint32_t  deviceId;
+	mcUuid_t    uuid;
+	uint32_t  tci;
+	uint32_t  len;
+} mcDrvCmdOpenSessionPayload_t, *mcDrvCmdOpenSessionPayload_ptr;
+
+typedef struct{
+    mcDrvCommandHeader_t          header;
+    mcDrvCmdOpenSessionPayload_t  payload;
+} mcDrvCmdOpenSession_t, *mcDrvCmdOpenSession_ptr;
+
+
+typedef struct{
+	uint32_t  deviceId;
+	uint32_t  sessionId;
+	uint32_t  deviceSessionId;
+	uint32_t  mcResult;
+	uint32_t  sessionMagic;
+} mcDrvRspOpenSessionPayload_t, *mcDrvRspOpenSessionPayload_ptr;
+
+typedef struct{
+    mcDrvResponseHeader_t         header;
+    mcDrvRspOpenSessionPayload_t  payload;
+} mcDrvRspOpenSession_t, *mcDrvRspOpenSession_ptr;
+
+
+//--------------------------------------------------------------
+typedef struct{
+	uint32_t  sessionId;
+} mcDrvCmdCloseSessionPayload_t, *mcDrvCmdCloseSessionPayload_ptr;
+
+typedef struct{
+    mcDrvCommandHeader_t           header;
+    mcDrvCmdCloseSessionPayload_t  payload;
+} mcDrvCmdCloseSession_t, *mcDrvCmdCloseSession_ptr;
+
+
+typedef struct{
+    // empty
+} mcDrvRspCloseSessionPayload_t, *mcDrvRspCloseSessionPayload_ptr;
+
+typedef struct{
+    mcDrvResponseHeader_t         header;
+    mcDrvRspCloseSessionPayload_t  payload;
+} mcDrvRspCloseSession_t, *mcDrvRspCloseSession_ptr;
+
+
+//--------------------------------------------------------------
+typedef struct{
+	uint32_t sessionId;
+} mcDrvCmdNotifyPayload_t, *mcDrvCmdNotifyPayload_ptr;
+
+typedef struct{
+    mcDrvCommandHeader_t     header;
+    mcDrvCmdNotifyPayload_t  payload;
+} mcDrvCmdNotify_t, *mcDrvCmdNotify_ptr;
+
+
+typedef struct{
+    // empty
+} mcDrvRspNotifyPayload_t, *mcDrvRspNotifyPayload_ptr;
+
+typedef struct{
+    mcDrvResponseHeader_t    header;
+    mcDrvRspNotifyPayload_t  payload;
+} mcDrvRspNotify_t, *mcDrvRspNotify_ptr;
+
+
+//--------------------------------------------------------------
+typedef struct{
+	uint32_t  sessionId;
+	uint32_t  pAddrL2;
+	uint32_t  offsetPayload;
+	uint32_t  lenBulkMem;
+} mcDrvCmdMapBulkMemPayload_t, *mcDrvCmdMapBulkMemPayload_ptr;
+
+typedef struct{
+    mcDrvCommandHeader_t         header;
+    mcDrvCmdMapBulkMemPayload_t  payload;
+} mcDrvCmdMapBulkMem_t, *mcDrvCmdMapBulkMem_ptr;
+
+
+typedef struct{
+	uint32_t  sessionId;
+	uint32_t  secureVirtualAdr;
+	uint32_t  mcResult;
+} mcDrvRspMapBulkMemPayload_t, *mcDrvRspMapBulkMemPayload_ptr;
+
+typedef struct{
+    mcDrvResponseHeader_t        header;
+    mcDrvRspMapBulkMemPayload_t  payload;
+} mcDrvRspMapBulkMem_t, *mcDrvRspMapBulkMem_ptr;
+
+
+//--------------------------------------------------------------
+typedef struct{
+	uint32_t  sessionId;
+	uint32_t  secureVirtualAdr;
+	uint32_t  lenBulkMem;
+} mcDrvCmdUnmapBulkMemPayload_t, *mcDrvCmdUnmapBulkMemPayload_ptr;
+
+typedef struct{
+    mcDrvCommandHeader_t           header;
+    mcDrvCmdUnmapBulkMemPayload_t  payload;
+} mcDrvCmdUnmapBulkMem_t, *mcDrvCmdUnmapBulkMem_ptr;
+
+
+typedef struct{
+    uint32_t  responseId;
+	uint32_t  sessionId;
+	uint32_t  mcResult;
+} mcDrvRspUnmapBulkMemPayload_t, *mcDrvRspUnmapBulkMemPayload_ptr;
+
+typedef struct{
+    mcDrvResponseHeader_t          header;
+    mcDrvRspUnmapBulkMemPayload_t  payload;
+} mcDrvRspUnmapBulkMem_t, *mcDrvRspUnmapBulkMem_ptr;
+
+
+//--------------------------------------------------------------
+typedef struct {
+    uint32_t  deviceId;
+    uint32_t  sessionId;
+    uint32_t  deviceSessionId;
+    uint32_t  sessionMagic; //Random data
+} mcDrvCmdNqConnectPayload_t, *mcDrvCmdNqConnectPayload_ptr;
+
+typedef struct {
+    mcDrvCommandHeader_t        header;
+    mcDrvCmdNqConnectPayload_t  payload;
+} mcDrvCmdNqConnect_t, *mcDrvCmdNqConnect_ptr;
+
+
+typedef struct {
+    // empty;
+} mcDrvRspNqConnectPayload_t, *mcDrvRspNqConnectPayload_ptr;
+
+typedef struct{
+    mcDrvResponseHeader_t       header;
+    mcDrvRspNqConnectPayload_t  payload;
+} mcDrvRspNqConnect_t, *mcDrvRspNqConnect_ptr;
+
+//--------------------------------------------------------------
+typedef struct {
+    mcDrvCommandHeader_t        header;
+} mcDrvCmdGetVersion_t, *mcDrvCmdGetVersion_ptr;
+
+
+typedef struct {
+    uint32_t version;
+} mcDrvRspGetVersionPayload_t, *mcDrvRspGetVersionPayload_ptr;
+
+typedef struct{
+    mcDrvResponseHeader_t       header;
+    mcDrvRspGetVersionPayload_t payload;
+} mcDrvRspGetVersion_t, mcDrvRspGetVersion_ptr;
+
+//--------------------------------------------------------------
+typedef struct {
+    mcDrvCommandHeader_t        header;
+} mcDrvCmdGetMobiCoreVersion_t, *mcDrvCmdGetMobiCoreVersion_ptr;
+
+
+typedef struct {
+    uint32_t        mcResult;
+    mcVersionInfo_t versionInfo;
+} mcDrvRspGetMobiCoreVersionPayload_t, *mcDrvRspGetMobiCoreVersionPayload_ptr;
+
+typedef struct{
+    mcDrvResponseHeader_t       header;
+    mcDrvRspGetMobiCoreVersionPayload_t payload;
+} mcDrvRspGetMobiCoreVersion_t, mcDrvRspGetMobiCoreVersion_ptr;
+
+//--------------------------------------------------------------
+typedef union {
+    mcDrvCommandHeader_t         header;
+    mcDrvCmdOpenDevice_t         mcDrvCmdOpenDevice;
+    mcDrvCmdCloseDevice_t        mcDrvCmdCloseDevice;
+    mcDrvCmdOpenSession_t        mcDrvCmdOpenSession;
+    mcDrvCmdCloseSession_t       mcDrvCmdCloseSession;
+    mcDrvCmdNqConnect_t          mcDrvCmdNqConnect;
+    mcDrvCmdNotify_t             mcDrvCmdNotify;
+    mcDrvCmdMapBulkMem_t         mcDrvCmdMapBulkMem;
+    mcDrvCmdUnmapBulkMem_t       mcDrvCmdUnmapBulkMem;
+    mcDrvCmdGetVersion_t         mcDrvCmdGetVersion;
+    mcDrvCmdGetMobiCoreVersion_t mcDrvCmdGetMobiCoreVersion;
+} mcDrvCommand_t, *mcDrvCommand_ptr;
+
+typedef union {
+    mcDrvResponseHeader_t        header;
+    mcDrvRspOpenDevice_t         mcDrvRspOpenDevice;
+    mcDrvRspCloseDevice_t        mcDrvRspCloseDevice;
+    mcDrvRspOpenSession_t        mcDrvRspOpenSession;
+    mcDrvRspCloseSession_t       mcDrvRspCloseSession;
+    mcDrvRspNqConnect_t          mcDrvRspNqConnect;
+    mcDrvRspNotify_t             mcDrvRspNotify;
+    mcDrvRspMapBulkMem_t         mcDrvRspMapBulkMem;
+    mcDrvRspUnmapBulkMem_t       mcDrvRspUnmapBulkMem;
+    mcDrvRspGetVersion_t         mcDrvRspGetVersion;
+    mcDrvRspGetMobiCoreVersion_t mcDrvRspGetMobiCoreVersion;
+} mcDrvResponse_t, *mcDrvResponse_ptr;
+
+#endif /* MCDAEMON_H_ */
+
+/** @} */
diff --git a/V008/Android/external/mobicore/daemon/Daemon/public/mcVersion.h b/V008/Android/external/mobicore/daemon/Daemon/public/mcVersion.h
new file mode 100644
index 0000000..e019562
--- /dev/null
+++ b/V008/Android/external/mobicore/daemon/Daemon/public/mcVersion.h
@@ -0,0 +1,35 @@
+/**
+ * <!-- 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/V008/Android/external/mobicore/daemon/Kernel/Android.mk b/V008/Android/external/mobicore/daemon/Kernel/Android.mk
new file mode 100644
index 0000000..9caae0e
--- /dev/null
+++ b/V008/Android/external/mobicore/daemon/Kernel/Android.mk
@@ -0,0 +1,38 @@
+# =============================================================================
+#
+# Module: libKernel.a - Kernel module access classes
+#
+# =============================================================================
+
+LOCAL_PATH	:= $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE	:= libMcKernel
+
+# Include platform specific sub-makefiles
+ifdef PLATFORM
+  include $(LOCAL_PATH)/Platforms/Generic/Android.mk
+  include $(LOCAL_PATH)/Platforms/$(PLATFORM)/Android.mk
+else 
+  include $(LOCAL_PATH)/Platforms/Generic/Android.mk
+endif
+
+# Add new folders with header files here
+LOCAL_C_INCLUDES +=\
+	$(COMP_PATH_MobiCoreDriverMod)/Public \
+	$(APP_PROJECT_PATH)/Common \
+	$(LOCAL_PATH) 
+
+# Add new source files here
+LOCAL_SRC_FILES +=\
+	CKMod.cpp
+
+# Header files for components including this module
+LOCAL_EXPORT_C_INCLUDES	+=\
+	$(LOCAL_PATH)
+
+LOCAL_CPPFLAGS += -fno-rtti -fno-exceptions
+
+include $(COMP_PATH_Logwrapper)/Android.mk
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/V008/Android/external/mobicore/daemon/Kernel/CKMod.cpp b/V008/Android/external/mobicore/daemon/Kernel/CKMod.cpp
new file mode 100644
index 0000000..bc6d6ca
--- /dev/null
+++ b/V008/Android/external/mobicore/daemon/Kernel/CKMod.cpp
@@ -0,0 +1,122 @@
+/** @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.

+ */

+#include <cstdlib>

+

+#include <fcntl.h>

+#include <sys/mman.h>

+#include <errno.h>

+

+#include "CKMod.h"

+

+#define LOG_TAG	"McDaemon"

+#include "log.h"

+

+

+//------------------------------------------------------------------------------

+CKMod::CKMod(

+    void

+) {

+	fdKMod = ERROR_KMOD_NOT_OPEN;

+}

+

+

+//------------------------------------------------------------------------------

+CKMod::~CKMod(

+    void

+) {

+	close();

+}

+

+

+//------------------------------------------------------------------------------

+bool CKMod::isOpen(

+    void

+) {

+	return (ERROR_KMOD_NOT_OPEN == fdKMod) ? false : true;

+}

+

+

+//------------------------------------------------------------------------------

+bool CKMod::open(

+    const char *deviceName

+) {

+	bool ret = true;

+

+	do

+	{

+		if (isOpen())

+		{

+			LOG_W("already open");

+			ret = false;

+			break;

+		}

+

+		// open return -1 on error, "errno" is set with details

+		int openRet = ::open(deviceName, O_RDWR);

+		if (-1 == openRet)

+		{

+			LOG_E("open failed with errno: %d", errno);

+			ret = false;

+			break;

+		}

+

+		fdKMod = openRet;

+

+	} while(0);

+

+	return ret;

+}

+

+

+//------------------------------------------------------------------------------

+void CKMod::close(

+    void

+) {

+	if (isOpen())

+	{

+		if (0 != ::close(fdKMod))

+		{

+			LOG_E("close failed with errno: %d", errno);

+		}

+		else

+		{

+			fdKMod = ERROR_KMOD_NOT_OPEN;

+		}

+	}

+	else

+	{

+		LOG_W("not open");

+	}

+}

+

+/** @} */

diff --git a/V008/Android/external/mobicore/daemon/Kernel/CKMod.h b/V008/Android/external/mobicore/daemon/Kernel/CKMod.h
new file mode 100644
index 0000000..73e64e4
--- /dev/null
+++ b/V008/Android/external/mobicore/daemon/Kernel/CKMod.h
@@ -0,0 +1,77 @@
+/** @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>

+

+

+#define ERROR_KMOD_NOT_OPEN          ((int)(-1))

+

+/**

+ * 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

+    );

+

+    bool open(

+        const char *deviceName

+    );

+

+    void close(

+        void

+    );

+

+};

+

+#endif // CKMOD_H_

diff --git a/V008/Android/external/mobicore/daemon/Kernel/Platforms/Generic/Android.mk b/V008/Android/external/mobicore/daemon/Kernel/Platforms/Generic/Android.mk
new file mode 100644
index 0000000..ac816f1
--- /dev/null
+++ b/V008/Android/external/mobicore/daemon/Kernel/Platforms/Generic/Android.mk
@@ -0,0 +1,27 @@
+# =============================================================================
+#
+# Generic  TrustZone device includes
+#
+# =============================================================================
+
+# This is not a separate module.
+# Only for inclusion by other modules.
+
+GENERIC_MODULE_PATH		:= $(call my-dir)
+GENERIC_MODULE_PATH_REL	:= Platforms/Generic
+
+# Add new source files here
+LOCAL_SRC_FILES +=\
+	$(GENERIC_MODULE_PATH_REL)/CMcKMod.cpp
+
+# Add new folders with header files here
+LOCAL_C_INCLUDES +=\
+	$(GENERIC_MODULE_PATH)\
+	$(COMP_PATH_MobiCore)/inc\
+	$(COMP_PATH_MobiCoreDriverMod)/Public
+
+# Header files for components including this module
+LOCAL_EXPORT_C_INCLUDES	+=\
+	$(GENERIC_MODULE_PATH)\
+	$(COMP_PATH_MobiCoreDriverMod)/Public
+	
\ No newline at end of file
diff --git a/V008/Android/external/mobicore/daemon/Kernel/Platforms/Generic/CMcKMod.cpp b/V008/Android/external/mobicore/daemon/Kernel/Platforms/Generic/CMcKMod.cpp
new file mode 100644
index 0000000..bda89b6
--- /dev/null
+++ b/V008/Android/external/mobicore/daemon/Kernel/Platforms/Generic/CMcKMod.cpp
@@ -0,0 +1,566 @@
+/** @addtogroup MCD_MCDIMPL_DAEMON_KERNEL

+ * @{

+ * @file

+ *

+ * MobiCore Driver 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.

+ */

+#include <cstdlib>

+

+#include <sys/mman.h>

+#include <sys/ioctl.h>

+#include <errno.h>

+#include <inttypes.h>

+#include <cstring>

+

+#include "McTypes.h"

+#include "mcDrvModuleApi.h"

+#include "mcVersionHelper.h"

+

+#include "CMcKMod.h"

+

+#define LOG_TAG	"McDaemon"

+#include "log.h"

+

+//------------------------------------------------------------------------------

+MC_CHECK_VERSION(MCDRVMODULEAPI,0,1);

+

+// TODO: rename this to mapWsm

+//------------------------------------------------------------------------------

+int CMcKMod::mmap(

+	uint32_t	len,

+	uint32_t	*pHandle,

+	addr_t		*pVirtAddr,

+	addr_t		*pPhysAddr,

+	bool		*pMciReuse

+) {

+	int ret = 0;

+	do

+	{

+		LOG_I("mmap(): len=%d, mci_reuse=%x", len, *pMciReuse);

+

+		if (!isOpen())

+		{

+	        LOG_E("no connection to kmod");

+	        ret = ERROR_KMOD_NOT_OPEN;

+			break;

+		}

+

+		// TODO: add type parameter to distinguish between non-freeing TCI, MCI and others

+		addr_t virtAddr = ::mmap(0, len, PROT_READ | PROT_WRITE, MAP_SHARED,

+				fdKMod, *pMciReuse ? MC_DRV_KMOD_MMAP_MCI

+						: MC_DRV_KMOD_MMAP_WSM);

+		if (MAP_FAILED == virtAddr)

+		{

+			LOG_E("mmap() failed with errno: %d", errno);

+			ret = ERROR_MAPPING_FAILED;

+			break;

+		}

+

+		// mapping response data is in the buffer

+		struct mcMmapResp *pMmapResp = (struct mcMmapResp *) virtAddr;

+

+		*pMciReuse = pMmapResp->isReused;

+

+		LOG_I("mmap(): virtAddr=%p, handle=%d, physAddr=%p, isReused=%s",

+				virtAddr, pMmapResp->handle, (addr_t) (pMmapResp->physAddr),

+				pMmapResp->isReused ? "true" : "false");

+

+		if (NULL != pVirtAddr)

+		{

+			*pVirtAddr = virtAddr;

+		}

+

+		if (NULL != pHandle)

+		{

+			*pHandle = pMmapResp->handle;

+		}

+

+		if (NULL != pPhysAddr)

+		{

+			*pPhysAddr = (addr_t) (pMmapResp->physAddr);

+		}

+

+		// clean memory

+		memset(pMmapResp, 0, sizeof(*pMmapResp));

+

+	} while (0);

+

+	return ret;

+}

+

+

+//------------------------------------------------------------------------------

+int CMcKMod::mapPersistent(

+	uint32_t	len,

+	uint32_t	*pHandle,

+	addr_t		*pVirtAddr,

+	addr_t		*pPhysAddr

+) {

+	int ret = 0;

+	do

+	{

+		LOG_I("mapPersistent(): len=%d", len);

+

+		if (!isOpen())

+		{

+	        LOG_E("no connection to kmod");

+			ret = ERROR_KMOD_NOT_OPEN;

+			break;

+		}

+

+		addr_t virtAddr = ::mmap(0, len, PROT_READ | PROT_WRITE, MAP_SHARED,

+				fdKMod, MC_DRV_KMOD_MMAP_PERSISTENTWSM);

+

+		if (MAP_FAILED == virtAddr)

+		{

+			LOG_E("mmap() failed with errno: %d", errno);

+			ret = ERROR_MAPPING_FAILED;

+			break;

+		}

+

+		// mapping response data is in the buffer

+		struct mcMmapResp *pMmapResp = (struct mcMmapResp *) virtAddr;

+

+		LOG_I("mapPersistent(): virtAddr=%p, handle=%d, physAddr=%p, isReused=%s",

+				virtAddr, pMmapResp->handle,

+				(addr_t) (pMmapResp->physAddr),

+				pMmapResp->isReused ? "true" : "false");

+

+		if (NULL != pVirtAddr)

+		{

+			*pVirtAddr = virtAddr;

+		}

+

+		if (NULL != pHandle)

+		{

+			*pHandle = pMmapResp->handle;

+		}

+

+		if (NULL != pPhysAddr)

+		{

+			*pPhysAddr = (addr_t) (pMmapResp->physAddr);

+		}

+

+		// clean memory

+		memset(pMmapResp, 0, sizeof(*pMmapResp));

+

+	} while (0);

+

+	return ret;

+}

+

+

+//------------------------------------------------------------------------------

+int CMcKMod::read(

+	addr_t		buffer,

+	uint32_t	len

+) {

+	int ret = 0;

+

+	do

+	{

+		if (!isOpen())

+		{

+	        LOG_E("no connection to kmod");

+			ret = ERROR_KMOD_NOT_OPEN;

+			break;

+		}

+

+		ret = ::read(fdKMod, buffer, len);

+		if(-1 == ret)

+		{

+			LOG_E("read() failed with errno: %d", errno);

+		}

+

+	} while (0);

+

+	return ret;

+}

+

+

+//------------------------------------------------------------------------------

+bool CMcKMod::waitSSIQ(

+	uint32_t *pCnt

+) {

+	int ret = true;

+

+	do

+	{

+		uint32_t cnt;

+		int ret = read(&cnt, sizeof(cnt));

+		if (sizeof(cnt) != ret)

+		{

+			ret = false;

+		}

+

+		if (NULL != pCnt)

+		{

+			*pCnt = cnt;

+		}

+

+	} while (0);

+

+	return ret;

+}

+

+

+//------------------------------------------------------------------------------

+int CMcKMod::fcInit(

+	addr_t		mciBuffer,

+	uint32_t	nqOffset,

+	uint32_t	nqLength,

+	uint32_t	mcpOffset,

+	uint32_t	mcpLength

+) {

+	int ret = 0;

+

+	do

+	{

+		if (!isOpen())

+		{

+			ret = ERROR_KMOD_NOT_OPEN;

+			break;

+		}

+

+		// Init MC with NQ and MCP buffer addresses

+		union mcIoCtlInitParams fcInitParams = {

+		// C++ does not support C99 designated initializers

+				/* .in = */{

+				/* .base = */(uint32_t) mciBuffer,

+				/* .nqOffset = */nqOffset,

+				/* .nqLength = */nqLength,

+				/* .mcpOffset = */mcpOffset,

+				/* .mcpLength = */mcpLength } };

+		ret = ioctl(fdKMod, MC_DRV_KMOD_IOCTL_FC_INIT, &fcInitParams);

+		if (ret != 0)

+		{

+			LOG_E("IOCTL_FC_INIT failed with ret = %d and errno = %d", ret, errno);

+			break;

+		}

+

+	} while (0);

+

+	return ret;

+}

+

+

+//------------------------------------------------------------------------------

+int CMcKMod::fcInfo(

+	uint32_t	extInfoId,

+	uint32_t	*pState,

+	uint32_t	*pExtInfo

+) {

+	int ret = 0;

+

+	do

+	{

+		if (!isOpen())

+		{

+	        LOG_E("no connection to kmod");

+			ret = ERROR_KMOD_NOT_OPEN;

+			break;

+		}

+

+		// Init MC with NQ and MCP buffer addresses

+		union mcIoCtlInfoParams fcInfoParams = {

+		// C++ does not support C99 designated initializers

+				/* .in = */{

+				/* .extInfoId = */extInfoId } };

+		ret = ioctl(fdKMod, MC_DRV_KMOD_IOCTL_FC_INFO, &fcInfoParams);

+		if (ret != 0)

+		{

+			LOG_E("IOCTL_FC_INFO failed with ret = %d and errno = %d", ret, errno);

+			break;

+		}

+

+		if (NULL != pState)

+		{

+			*pState = fcInfoParams.out.state;

+		}

+

+		if (NULL != pExtInfo)

+		{

+			*pExtInfo = fcInfoParams.out.extInfo;

+		}

+

+	} while (0);

+

+	return ret;

+}

+

+

+//------------------------------------------------------------------------------

+int CMcKMod::fcYield(

+	void

+) {

+	int ret = 0;

+

+	do

+	{

+		if (!isOpen())

+		{

+	        LOG_E("no connection to kmod");

+			ret = ERROR_KMOD_NOT_OPEN;

+			break;

+		}

+

+		ret = ioctl(fdKMod, MC_DRV_KMOD_IOCTL_FC_YIELD, NULL);

+		if (ret != 0)

+		{

+			LOG_E("IOCTL_FC_YIELD failed with ret = %d and errno = %d", ret, errno);

+			break;

+		}

+

+	} while (0);

+

+	return ret;

+}

+

+

+//------------------------------------------------------------------------------

+int CMcKMod::fcNSIQ(

+	void

+) {

+	int ret = 0;

+

+	do

+	{

+		if (!isOpen())

+		{

+	        LOG_E("no connection to kmod");

+			ret = ERROR_KMOD_NOT_OPEN;

+			break;

+		}

+

+		ret = ioctl(fdKMod, MC_DRV_KMOD_IOCTL_FC_NSIQ, NULL);

+		if (ret != 0)

+		{

+			LOG_E("IOCTL_FC_NSIQ failed with ret = %d and errno = %d", ret, errno);

+			break;

+		}

+

+	} while (0);

+

+	return ret;

+}

+

+

+//------------------------------------------------------------------------------

+int CMcKMod::free(

+	uint32_t handle

+) {

+	int ret = 0;

+

+	do

+	{

+		LOG_I("free(): handle=%d", handle);

+

+		if (!isOpen())

+		{

+	        LOG_E("no connection to kmod");

+			ret = ERROR_KMOD_NOT_OPEN;

+			break;

+		}

+

+		union mcIoCtltoFreeParams freeParams = {

+		// C++ does not support c99 designated initializers

+				/* .in = */{

+				/* .handle = */(uint32_t) handle } };

+

+		ret = ioctl(fdKMod, MC_DRV_KMOD_IOCTL_FREE, &freeParams);

+		if (0 != ret)

+		{

+			LOG_E("IOCTL_FREE failed with ret = %d and errno = %d", ret, errno);

+			break;

+		}

+

+	} while (0);

+

+	return ret;

+}

+

+

+//------------------------------------------------------------------------------

+int CMcKMod::registerWsmL2(

+	addr_t		buffer,

+	uint32_t	len,

+	uint32_t	pid,

+	uint32_t	*pHandle,

+	addr_t		*pPhysWsmL2

+) {

+	int ret = 0;

+

+	do

+	{

+		LOG_I("registerWsmL2(): buffer=%p, len=%d, pid=%d", buffer, len, pid);

+

+		if (!isOpen())

+		{

+	        LOG_E("no connection to kmod");

+			ret = ERROR_KMOD_NOT_OPEN;

+			break;

+		}

+

+		union mcIoCtlAppRegWsmL2Params params = {

+		// C++ does not support C99 designated initializers

+				/* .in = */{

+				/* .buffer = */(uint32_t) buffer,

+				/* .len = */len,

+				/* .pid = */pid } };

+

+		ret = ioctl(fdKMod, MC_DRV_KMOD_IOCTL_APP_REGISTER_WSM_L2, &params);

+		if (0 != ret)

+		{

+			LOG_E("IOCTL_APP_REGISTER_WSM_L2 failed with ret = %d and errno = %d", ret, errno);

+			break;

+		}

+

+		LOG_I("WSM L2 phys=%x, handle=%d", params.out.physWsmL2Table,

+				params.out.handle);

+

+		if (NULL != pHandle)

+		{

+			*pHandle = params.out.handle;

+		}

+

+		if (NULL != pPhysWsmL2)

+		{

+			*pPhysWsmL2 = (addr_t) params.out.physWsmL2Table;

+		}

+

+	} while (0);

+

+	return ret;

+}

+

+

+//------------------------------------------------------------------------------

+int CMcKMod::unregisterWsmL2(

+	uint32_t handle

+) {

+	int ret = 0;

+

+	do

+	{

+		LOG_I("unregisterWsmL2(): handle=%d", handle);

+

+		if (!isOpen())

+		{

+	        LOG_E("no connection to kmod");

+			ret = ERROR_KMOD_NOT_OPEN;

+			break;

+		}

+

+		struct mcIoCtlAppUnregWsmL2Params params = {

+		// C++ does not support c99 designated initializers

+				/* .in = */{

+				/* .handle = */handle } };

+

+		int ret = ioctl(fdKMod, MC_DRV_KMOD_IOCTL_APP_UNREGISTER_WSM_L2, &params);

+		if (0 != ret)

+		{

+			LOG_E("IOCTL_APP_UNREGISTER_WSM_L2 failed with ret = %d and errno = %d", ret, errno);

+			break;

+		}

+

+	} while (0);

+

+	return ret;

+}

+

+//------------------------------------------------------------------------------

+int CMcKMod::fcExecute(

+    addr_t    startAddr,

+    uint32_t  areaLength

+) {

+    int ret = 0;

+    union mcIoCtlFcExecuteParams params = {

+        /*.in =*/ {

+            /*.physStartAddr = */ (uint32_t)startAddr,

+            /*.length = */ areaLength

+        }

+    };

+    do

+    {

+        if (!isOpen())

+        {

+            LOG_E("no connection to kmod");

+            break;

+        }

+

+        ret = ioctl(fdKMod, MC_DRV_KMOD_IOCTL_FC_EXECUTE, &params);

+        if (ret != 0)

+        {

+            LOG_E("IOCTL_FC_EXECUTE failed with ret = %d and errno = %d", ret, errno);

+            break;

+        }

+

+    } while(0);

+

+    return ret;

+}

+//------------------------------------------------------------------------------

+bool CMcKMod::checkKmodVersionOk(

+    void

+) {

+    bool ret = false;

+

+    do

+    {

+        if (!isOpen())

+        {

+            LOG_E("no connection to kmod");

+            break;

+        }

+

+        struct mcIoCtlGetVersionParams params;

+

+        int ioret = ioctl(fdKMod, MC_DRV_KMOD_IOCTL_GET_VERSION, &params);

+        if (0 != ioret)

+        {

+            LOG_E("IOCTL_GET_VERSION failed with ret = %d and errno = %d", ret, errno);

+            break;

+        }

+

+        // Run-time check.

+        char* errmsg;

+        if (!checkVersionOkMCDRVMODULEAPI(params.out.kernelModuleVersion, &errmsg)) {

+            LOG_E("%s", errmsg);

+            break;

+        }

+        LOG_I("%s", errmsg);

+

+        ret = true;

+

+    } while (0);

+

+    return ret;

+}

+

+/** @} */

diff --git a/V008/Android/external/mobicore/daemon/Kernel/Platforms/Generic/CMcKMod.h b/V008/Android/external/mobicore/daemon/Kernel/Platforms/Generic/CMcKMod.h
new file mode 100644
index 0000000..20204d8
--- /dev/null
+++ b/V008/Android/external/mobicore/daemon/Kernel/Platforms/Generic/CMcKMod.h
@@ -0,0 +1,145 @@
+/** @addtogroup MCD_MCDIMPL_DAEMON_KERNEL

+ * @{

+ * @file

+ *

+ * MobiCore Driver 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 CMCKMOD_H_

+#define CMCKMOD_H_

+

+#include <stdint.h>

+

+#include "McTypes.h"

+#include "CKMod.h"

+

+

+#define ERROR_MAPPING_FAILED         ((int)(-2))

+

+/**

+ * As this is also used by the ClientLib, we do not use exceptions.

+ */

+class CMcKMod : public CKMod {

+

+public:

+

+    /**

+     * Map data.

+     *

+     * @param len

+     * @param pHandle

+     * @param pVirtAddr

+     * @param pPhysAddr

+     * @param pMciReuse [in|out] set to true [in] for reusing MCI buffer

+     *                 is set to true [out] if MCI buffer has been reused

+     * @return 0 if all went fine

+     * @return ERROR_KMOD_NOT_OPEN

+     * @return ERROR_MAPPING_FAILED

+     */

+    int mmap(

+        uint32_t  len,

+        uint32_t  *pHandle,

+        addr_t    *pVirtAddr,

+        addr_t    *pPhysAddr,

+        bool      *pMciReuse

+    );

+

+    /**

+     * Map persistent WSM which will not be freed up once the calling process dies.

+     */

+    int mapPersistent(

+        uint32_t  		len,

+        uint32_t  		*pHandle,

+        addr_t    		*pVirtAddr,

+        addr_t    		*pPhysAddr

+    );

+

+    int read(

+        addr_t    buffer,

+        uint32_t  len

+    );

+

+    bool waitSSIQ(

+        uint32_t  *pCnt

+    );

+

+    int fcInit(

+        addr_t    mciBuffer,

+        uint32_t  nqOffset,

+        uint32_t  nqLength,

+        uint32_t  mcpOffset,

+        uint32_t  mcpLength

+    );

+

+    int fcInfo(

+        uint32_t  extInfoId,

+        uint32_t  *pState,

+        uint32_t  *pExtInfo

+    );

+

+    int fcYield(

+        void

+    );

+

+    int fcNSIQ(

+        void

+    );

+

+    int free(

+        uint32_t  handle

+    );

+

+    int registerWsmL2(

+        addr_t    buffer,

+        uint32_t  len,

+        uint32_t  pid,

+        uint32_t  *pHandle,

+        addr_t    *pPhysWsmL2

+    );

+

+    int unregisterWsmL2(

+        uint32_t  handle

+    );

+

+    /**

+     * Tell stub to start MobiCore from given physical address

+     */

+    int fcExecute(

+        addr_t    startAddr,

+        uint32_t  areaLength

+    );

+

+    bool checkKmodVersionOk(

+        void

+    );

+

+};

+

+typedef CMcKMod  *CMcKMod_ptr;

+

+#endif // CMCKMOD_H_

diff --git a/V008/Android/external/mobicore/daemon/PaApi/Android.mk b/V008/Android/external/mobicore/daemon/PaApi/Android.mk
new file mode 100644
index 0000000..4630bbe
--- /dev/null
+++ b/V008/Android/external/mobicore/daemon/PaApi/Android.mk
@@ -0,0 +1,35 @@
+# =============================================================================
+#
+# Module: libPaApi(Static and Shared variant)
+#
+# =============================================================================
+
+LOCAL_PATH	:= $(call my-dir)
+
+#Now the Shared Object
+include $(CLEAR_VARS)
+
+LOCAL_MODULE	:= libPaApi
+LOCAL_MODULE_TAGS := eng
+LOCAL_PRELINK_MODULE := false
+
+LOCAL_C_INCLUDES += bionic \
+    external/stlport/stlport
+
+# Add your folders with header files here (absolute paths)
+LOCAL_C_INCLUDES += \
+	$(LOCAL_PATH)/Public \
+	$(COMP_PATH_MobiCore)/inc \
+	$(COMP_PATH_MobiCore)/inc/TlCm \
+	$(APP_PROJECT_PATH)/ClientLib/public
+
+# Add your source files here (relative paths)
+LOCAL_SRC_FILES	+= tlcCmApi.cpp
+
+LOCAL_SHARED_LIBRARIES	+= libMcRegistry libMcClient
+LOCAL_STATIC_LIBRARIES =  libstlport_static
+LOCAL_CPPFLAGS += -fno-rtti -fno-exceptions
+
+include $(COMP_PATH_Logwrapper)/Android.mk
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/V008/Android/external/mobicore/daemon/PaApi/Public/paApi.h b/V008/Android/external/mobicore/daemon/PaApi/Public/paApi.h
new file mode 100644
index 0000000..6c30026
--- /dev/null
+++ b/V008/Android/external/mobicore/daemon/PaApi/Public/paApi.h
@@ -0,0 +1,44 @@
+/**
+ * @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/V008/Android/external/mobicore/daemon/PaApi/Public/tlcCmApi.h b/V008/Android/external/mobicore/daemon/PaApi/Public/tlcCmApi.h
new file mode 100644
index 0000000..a91c9e5
--- /dev/null
+++ b/V008/Android/external/mobicore/daemon/PaApi/Public/tlcCmApi.h
@@ -0,0 +1,84 @@
+/** @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 "tlCmApi.h"

+#include "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/V008/Android/external/mobicore/daemon/PaApi/tlcCmApi.cpp b/V008/Android/external/mobicore/daemon/PaApi/tlcCmApi.cpp
new file mode 100644
index 0000000..86f213c
--- /dev/null
+++ b/V008/Android/external/mobicore/daemon/PaApi/tlcCmApi.cpp
@@ -0,0 +1,122 @@
+/** @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 "tlCmUuid.h"
+
+#define LOG_TAG "TlcCmApi"
+#include "log.h"
+
+#include <assert.h>
+#include <stdlib.h>
+
+
+static const uint32_t DEVICE_ID = MC_DEVICE_ID_DEFAULT;
+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(DEVICE_ID);
+    if (MC_DRV_OK != result) {
+        LOG_E("Error opening device: %d", result);
+        return result;
+    }
+    result = mcMallocWsm(DEVICE_ID, 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(DEVICE_ID);
+    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/V008/Android/external/mobicore/daemon/Registry/Android.mk b/V008/Android/external/mobicore/daemon/Registry/Android.mk
new file mode 100644
index 0000000..af396f7
--- /dev/null
+++ b/V008/Android/external/mobicore/daemon/Registry/Android.mk
@@ -0,0 +1,72 @@
+# =============================================================================
+#
+# Module: libMcRegistry.a - MobiCore driver registry
+#
+# =============================================================================
+
+LOCAL_PATH	:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE	:= libMcRegistry
+
+# Prevent not-yet-used functions of being ignored by linker
+LOCAL_LDLIBS	:= -Wl,-whole-archive
+
+LOCAL_C_INCLUDES += bionic \
+    external/stlport/stlport
+
+# Add new folders with header files here
+LOCAL_C_INCLUDES	+=\
+	$(LOCAL_PATH)/Public\
+	$(MY_CLIENTLIB_PATH)/public\
+	$(COMP_PATH_MobiCore)/inc
+
+# Add new source files here
+LOCAL_SRC_FILES		+= Registry.cpp
+
+# Header files for components including this module
+LOCAL_EXPORT_C_INCLUDES	+=\
+	$(LOCAL_PATH)/Public\
+	$(MY_CLIENTLIB_PATH)/public
+
+LOCAL_CPPFLAGS += -fno-rtti -fno-exceptions
+include $(COMP_PATH_Logwrapper)/Android.mk
+
+include $(BUILD_STATIC_LIBRARY)
+
+##################################################
+## Shared Object
+##################################################
+include $(CLEAR_VARS)
+
+LOCAL_MODULE	:= libMcRegistry
+LOCAL_MODULE_TAGS := eng
+LOCAL_PRELINK_MODULE := false
+
+# Prevent not-yet-used functions of being ignored by linker
+LOCAL_LDLIBS	:= -Wl,-whole-archive
+
+LOCAL_C_INCLUDES += bionic \
+    external/stlport/stlport
+
+# Add new folders with header files here
+LOCAL_C_INCLUDES	+=\
+	$(LOCAL_PATH)/Public\
+	$(MY_CLIENTLIB_PATH)/public\
+	$(COMP_PATH_MobiCore)/inc
+
+# Add new source files here
+LOCAL_SRC_FILES		+= Registry.cpp
+
+# Header files for components including this module
+LOCAL_EXPORT_C_INCLUDES	+=\
+	$(LOCAL_PATH)/Public\
+	$(MY_CLIENTLIB_PATH)/public
+
+LOCAL_STATIC_LIBRARIES = libstlport_static
+LOCAL_CPPFLAGS += -fno-rtti -fno-exceptions
+
+include $(COMP_PATH_Logwrapper)/Android.mk
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/V008/Android/external/mobicore/daemon/Registry/Public/MobiCoreRegistry.h b/V008/Android/external/mobicore/daemon/Registry/Public/MobiCoreRegistry.h
new file mode 100755
index 0000000..96ca810
--- /dev/null
+++ b/V008/Android/external/mobicore/daemon/Registry/Public/MobiCoreRegistry.h
@@ -0,0 +1,178 @@
+/**
+ * @addtogroup MCD_MCDIMPL_DAEMON_REG
+ * @{
+ * G&D MobiCore Registry
+ *
+ * @file
+ * Mobicore Driver Registry.
+ *
+ * <!-- 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 MOBICORE_REGISTRY_H_
+#define MOBICORE_REGISTRY_H_
+
+#include "MobiCoreDriverApi.h"
+#include "mcContainer.h"
+
+#ifdef __cplusplus
+extern "C" { 
+#endif 
+
+/**
+ * Registry object.
+ */
+typedef struct {
+    uint32_t len;
+    uint8_t value[];
+} regObject_t;
+
+/** Maximum size of a trustlet in bytes. */
+#define MAX_TL_SIZE     (1 * 1024 * 1024)   
+
+//-----------------------------------------------------------------
+
+/** Stores an authentication token in registry.
+ * @param  so Authentication token secure object.
+ * @return MC_DRV_OK if successful, otherwise error code.
+ */
+mcResult_t mcRegistryStoreAuthToken(const mcSoAuthTokenCont_t *so);
+
+/** Reads an authentication token from registry.
+ * @param[out] so Authentication token secure object.
+ * @return MC_DRV_OK if successful, otherwise error code.
+ */
+mcResult_t mcRegistryReadAuthToken(mcSoAuthTokenCont_t *so);
+
+/** Deletes the authentication token secure object from the registry.
+ * @return MC_DRV_OK if successful, otherwise error code.
+ */
+mcResult_t mcRegistryDeleteAuthToken(void);
+
+/** Stores a root container secure object in the registry.
+ * @param so Root container secure object.
+ * @return MC_DRV_OK if successful, otherwise error code.
+ */
+mcResult_t mcRegistryStoreRoot(const mcSoRootCont_t *so);
+
+/** Reads a root container secure object from the registry.
+ * @param[out] so Root container secure object.
+ * @return MC_DRV_OK if successful, otherwise error code.
+ */
+mcResult_t mcRegistryReadRoot(mcSoRootCont_t *so);
+
+/** Stores a service provider container secure object in the registry.
+ * @param spid Service provider ID.
+ * @param so Service provider container secure object.
+ * @return MC_DRV_OK if successful, otherwise error code.
+ */
+mcResult_t mcRegistryStoreSp(mcSpid_t spid, const mcSoSpCont_t *so);
+
+/** Reads a service provider container secure object from the registry.
+ * @param spid Service provider ID.
+ * @param[out] so Service provider container secure object.
+ * @return MC_DRV_OK if successful, otherwise error code.
+ */
+mcResult_t mcRegistryReadSp(mcSpid_t spid, mcSoSpCont_t *so);
+
+/** Deletes a service provider recursively, including all trustlets and
+ * data.
+ * @param spid Service provider ID.
+ * @return MC_DRV_OK if successful, otherwise error code.
+ */
+mcResult_t mcRegistryCleanupSp(mcSpid_t spid);
+
+/** Stores a trustlet container secure object in the registry.
+ * @param uuid Trustlet UUID.
+ * @param so Trustlet container secure object.
+ * @return MC_DRV_OK if successful, otherwise error code.
+ */
+mcResult_t mcRegistryStoreTrustletCon(const mcUuid_t *uuid, const mcSoTltCont_t *so);
+
+/** Reads a trustlet container secure object from the registry.
+ * @param uuid Trustlet UUID.
+ * @param[out] so Trustlet container secure object.
+ * @return MC_DRV_OK if successful, otherwise error code.
+ */
+mcResult_t mcRegistryReadTrustletCon(const mcUuid_t *uuid, mcSoTltCont_t *so);
+
+/** Deletes a trustlet container secure object and all of its associated data.
+ * @param uuid Trustlet UUID.
+ * @return MC_DRV_OK if successful, otherwise error code.
+ */
+mcResult_t mcRegistryCleanupTrustlet(const mcUuid_t *uuid);
+
+/** Stores a data container secure object in the registry.
+ * @param so Data container secure object.
+ * @return MC_DRV_OK if successful, otherwise error code.
+ */
+mcResult_t mcRegistryStoreData(const mcSoDataCont_t *so);
+
+/** Reads a data container secure object from the registry.
+ * @param context (service provider = 0; trustlet = 1).
+ * @param cid Service provider or UUID.
+ * @param pid Personalization data identifier.
+ * @param[out] so Data container secure object.
+ * @param maxLen Maximum size (in bytes) of the destination buffer (so).
+ * @return MC_DRV_OK if successful, otherwise error code.
+ */
+mcResult_t mcRegistryReadData(
+    uint32_t context,
+    const mcCid_t *cid,
+    mcPid_t pid,
+    mcSoDataCont_t *so,
+    uint32_t maxLen
+);
+
+/** Deletes the root container and all of its associated service provider
+ * containers.
+ * @return MC_DRV_OK if successful, otherwise error code.
+ */
+mcResult_t mcRegistryCleanupRoot(void);
+
+/** Returns a registry object for a given service.
+ * @param uuid service UUID
+ * @return Registry object.
+ * @note It is the responsibility of the caller to free the registry object
+ * allocated by this function.
+ */
+regObject_t *mcRegistryGetServiceBlob(const mcUuid_t  *uuid);
+
+/** Returns a registry object for a given service.
+ * @param driverFilename driver filename
+ * @return Registry object.
+ * @note It is the responsibility of the caller to free the registry object
+ * allocated by this function.
+ */
+regObject_t *mcRegistryGetDriverBlob(const char *driverFilename);
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif // MOBICORE_REGISTRY_H_
+
+/** @} */
diff --git a/V008/Android/external/mobicore/daemon/Registry/Registry.cpp b/V008/Android/external/mobicore/daemon/Registry/Registry.cpp
new file mode 100755
index 0000000..7275fe3
--- /dev/null
+++ b/V008/Android/external/mobicore/daemon/Registry/Registry.cpp
@@ -0,0 +1,894 @@
+/** Mobicore Driver Registry.
+ *
+ * Implements the MobiCore driver registry which maintains trustlets.
+ *
+ * @file
+ * @ingroup MCD_MCDIMPL_DAEMON_REG
+ * <!-- 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 "MobiCoreRegistry.h"
+#include <stdlib.h>
+#include <dirent.h>
+#include <fstream>
+#include <sys/stat.h>
+#include <assert.h>
+#include <string>
+#include <cstring>
+#include <cstddef>
+#include "mcLoadFormat.h"
+#include "mcSpid.h"
+#include "mcVersionHelper.h"
+
+#define LOG_TAG "McDaemon"
+#include "log.h"
+
+MC_CHECK_DATA_OBJECT_VERSION(MCLF, 2, 0);
+MC_CHECK_DATA_OBJECT_VERSION(CONTAINER, 2, 0);
+
+// Asserts expression at compile-time (to be used within a function body).
+#define ASSERT_STATIC(e) do { enum { assert_static__ = 1 / (e) }; } while (0)
+
+using namespace std;
+
+static const string MC_REGISTRY_DEFAULT_PATH = "/data/app/mcRegistry";
+static const string AUTH_TOKEN_FILE_NAME = "00000000.authtokcont";
+static const string ROOT_FILE_NAME = "00000000.rootcont";
+static const string SP_CONT_FILE_EXT = ".spcont";
+static const string TL_CONT_FILE_EXT = ".tlcont";
+static const string TL_BIN_FILE_EXT = ".tlbin";
+static const string DATA_CONT_FILE_EXT = ".datacont";
+
+static const string ENV_MC_REGISTRY_PATH = "MC_REGISTRY_PATH";
+static const string ENV_MC_REGISTRY_FALLBACK_PATH = "MC_REGISTRY_FALLBACK_PATH";
+static const string ENV_MC_AUTH_TOKEN_PATH = "MC_AUTH_TOKEN_PATH";
+
+static const string getRegistryPath();
+static const string getAuthTokenFilePath();
+static const string getRootContFilePath();
+static const string getSpDataPath(mcSpid_t spid);
+static const string getSpContFilePath(mcSpid_t spid);
+static const string getTlContFilePath(const mcUuid_t* uuid);
+static const string getTlDataPath(const mcUuid_t* uuid);
+static const string getTlDataFilePath(const mcUuid_t* uuid, mcPid_t pid);
+static const string getTlBinFilePath(const mcUuid_t* uuid);
+
+static const string uint32ToString(mcSpid_t spid);
+static const string byteArrayToString(const void* bytes, size_t elems);
+static bool doesDirExist(const char* path);
+
+//------------------------------------------------------------------------------
+mcResult_t mcRegistryStoreAuthToken(
+	const mcSoAuthTokenCont_t *so
+) {
+    if (NULL == so) {
+        LOG_E("mcRegistry store So.Soc failed: %d", MC_DRV_ERR_INVALID_PARAMETER);
+        return MC_DRV_ERR_INVALID_PARAMETER;
+    }
+    if (CONT_TYPE_SOC != so->coSoc.type) {
+        LOG_E("mcRegistry store So.Soc failed: %d", MC_DRV_ERR_INVALID_PARAMETER);
+        return MC_DRV_ERR_INVALID_PARAMETER;
+    }
+    const string& authTokenFilePath = getAuthTokenFilePath();
+    LOG_I("store AuthToken: %s", authTokenFilePath.c_str());
+    fstream fs(authTokenFilePath.c_str(), ios_base::out | ios_base::binary);
+    if (!fs) {
+        LOG_E("mcRegistry store So.Soc failed: %d", MC_DRV_ERR_INVALID_DEVICE_FILE);
+        return MC_DRV_ERR_INVALID_DEVICE_FILE;
+    }
+    fs.seekg(0, ios::beg);
+    fs.write((char *)so, sizeof(mcSoAuthTokenCont_t));
+    fs.flush();
+    fs.close();
+    return MC_DRV_OK;
+}
+
+
+//------------------------------------------------------------------------------
+mcResult_t mcRegistryReadAuthToken(
+	mcSoAuthTokenCont_t *so
+) {
+    if (NULL == so) {
+        LOG_E("mcRegistry read So.Soc failed: %d", MC_DRV_ERR_INVALID_PARAMETER);
+        return MC_DRV_ERR_INVALID_PARAMETER;
+    }
+    const string& authTokenFilePath = getAuthTokenFilePath();
+    LOG_I("read AuthToken: %s", authTokenFilePath.c_str());
+    fstream fs(authTokenFilePath.c_str(), ios_base::in | ios_base::binary);
+    if (!fs) {
+        LOG_E("mcRegistry read So.Soc failed: %d", MC_DRV_ERR_INVALID_DEVICE_FILE);
+        return MC_DRV_ERR_INVALID_DEVICE_FILE;
+    }
+    fs.seekg(0, ios::end);
+    int32_t filesize = fs.tellg();
+    if (sizeof(mcSoAuthTokenCont_t) != filesize) {
+        fs.close();
+        LOG_E("mcRegistry read So.Soc failed: %d", MC_DRV_ERR_OUT_OF_RESOURCES);
+        return MC_DRV_ERR_OUT_OF_RESOURCES;
+    }
+    fs.seekg(0, ios::beg);
+    fs.read((char *)so, sizeof(mcSoAuthTokenCont_t));
+    fs.close();
+    return MC_DRV_OK;
+}
+
+//------------------------------------------------------------------------------
+mcResult_t mcRegistryDeleteAuthToken(
+	void
+) {
+    remove(getAuthTokenFilePath().c_str());
+    // @TODO: is return to check ?
+    return MC_DRV_OK;
+}
+
+
+//------------------------------------------------------------------------------
+mcResult_t mcRegistryStoreRoot(
+	const mcSoRootCont_t *so
+) {
+    if (NULL == so) {
+        LOG_E("mcRegistry store So.Root failed: %d", MC_DRV_ERR_INVALID_PARAMETER);
+        return MC_DRV_ERR_INVALID_PARAMETER;
+    }
+    if(CONT_TYPE_ROOT != so->cont.type) {
+        LOG_E("mcRegistry store So.Root failed: %d", MC_DRV_ERR_INVALID_PARAMETER);
+        return MC_DRV_ERR_INVALID_PARAMETER;
+    }
+    const string& rootContFilePath = getRootContFilePath();
+    LOG_I("store Root: %s", rootContFilePath.c_str());
+    fstream fs(rootContFilePath.c_str(), ios_base::out | ios_base::binary);
+    if (!fs) {
+        LOG_E("mcRegistry store So.Root failed: %d", MC_DRV_ERR_INVALID_DEVICE_FILE);
+        return MC_DRV_ERR_INVALID_DEVICE_FILE;
+    }
+    fs.seekg(0, ios::beg);
+    fs.write((char *)so, sizeof(mcSoRootCont_t));
+    fs.flush();
+    fs.close();
+    return MC_DRV_OK;
+}
+
+
+//------------------------------------------------------------------------------
+mcResult_t mcRegistryReadRoot(
+	mcSoRootCont_t *so
+) {
+    if (NULL == so) {
+        LOG_E("mcRegistry read So.Root failed: %d", MC_DRV_ERR_INVALID_PARAMETER);
+        return MC_DRV_ERR_INVALID_PARAMETER;
+    }
+    const string& rootContFilePath = getRootContFilePath();
+    LOG_I("read Root: %s", rootContFilePath.c_str());
+    fstream fs(rootContFilePath.c_str(), ios_base::in | ios_base::binary);
+    if (!fs) {
+        LOG_E("mcRegistry read So.Root failed: %d", MC_DRV_ERR_INVALID_DEVICE_FILE);
+        return MC_DRV_ERR_INVALID_DEVICE_FILE;
+    }
+    fs.seekg(0, ios::end);
+    int32_t filesize = fs.tellg();
+    if (sizeof(mcSoRootCont_t) != filesize) {
+        fs.close();
+        LOG_E("mcRegistry read So.Root failed: %d", MC_DRV_ERR_OUT_OF_RESOURCES);
+        return MC_DRV_ERR_OUT_OF_RESOURCES;
+    }
+    fs.seekg(0, ios::beg);
+    fs.read((char *)so, sizeof(mcSoRootCont_t));
+    fs.close();
+    return MC_DRV_OK;
+}
+
+
+//------------------------------------------------------------------------------
+mcResult_t mcRegistryStoreSp(
+	mcSpid_t			spid,
+	const mcSoSpCont_t	*so
+) {
+    if ((0 == spid) || (NULL == so)) {
+        LOG_E("mcRegistry store So.Sp(SpId) failed: %d", MC_DRV_ERR_INVALID_PARAMETER);
+        return MC_DRV_ERR_INVALID_PARAMETER;
+    }
+    if(CONT_TYPE_SP != so->cont.type) {
+        LOG_E("mcRegistry store So.Sp(SpId) failed: %d", MC_DRV_ERR_INVALID_PARAMETER);
+        return MC_DRV_ERR_INVALID_PARAMETER;
+    }
+    const string& spContFilePath = getSpContFilePath(spid);
+    LOG_I("store SP: %s", spContFilePath.c_str());
+    fstream fs(spContFilePath.c_str(), ios_base::out | ios_base::binary);
+    if (!fs) {
+        LOG_E("mcRegistry store So.Sp(SpId) failed: %d", MC_DRV_ERR_INVALID_DEVICE_FILE);
+        return MC_DRV_ERR_INVALID_DEVICE_FILE;
+    }
+    fs.seekg(0, ios::beg);
+    fs.write((char *)so, sizeof(mcSoSpCont_t));
+    fs.flush();
+    fs.close();
+    return MC_DRV_OK;
+}
+
+
+//------------------------------------------------------------------------------
+mcResult_t mcRegistryReadSp(
+	mcSpid_t		spid,
+	mcSoSpCont_t	*so
+) {
+    if ((0 == spid) || (NULL == so)) {
+        LOG_E("mcRegistry read So.Sp(SpId) failed: %d", MC_DRV_ERR_INVALID_PARAMETER);
+        return MC_DRV_ERR_INVALID_PARAMETER;
+    }
+    const string& spContFilePath = getSpContFilePath(spid);
+    LOG_I("read SP: %s", spContFilePath.c_str());
+    fstream fs(spContFilePath.c_str(), ios_base::in | ios_base::binary);
+    if (!fs) {
+        LOG_E("mcRegistry read So.Sp(SpId) failed: %d", MC_DRV_ERR_INVALID_DEVICE_FILE);
+        return MC_DRV_ERR_INVALID_DEVICE_FILE;
+    }
+    fs.seekg(0, ios::end);
+    int32_t filesize = fs.tellg();
+    if (sizeof(mcSoSpCont_t) != filesize) {
+        fs.close();
+        LOG_E("mcRegistry read So.Sp(SpId) failed: %d", MC_DRV_ERR_OUT_OF_RESOURCES);
+        return MC_DRV_ERR_OUT_OF_RESOURCES;
+    }
+    fs.seekg(0, ios::beg);
+    fs.read((char *)so, sizeof(mcSoSpCont_t));
+    fs.close();
+    return MC_DRV_OK;
+}
+
+
+//------------------------------------------------------------------------------
+mcResult_t mcRegistryStoreTrustletCon(
+	const mcUuid_t		*uuid,
+	const mcSoTltCont_t	*so
+) {
+    if ((NULL == uuid) || (NULL == so)) {
+        LOG_E("mcRegistry store So.TrustletCont(uuid) failed: %d", MC_DRV_ERR_INVALID_PARAMETER);
+        return MC_DRV_ERR_INVALID_PARAMETER;
+    }
+    if(CONT_TYPE_TLCON != so->cont.type) {
+        LOG_E("mcRegistry store So.TrustletCont(uuid) failed: %d", MC_DRV_ERR_INVALID_PARAMETER);
+        return MC_DRV_ERR_INVALID_PARAMETER;
+    }
+    const string& tlContFilePath = getTlContFilePath(uuid);
+    LOG_I("store TLc: %s", tlContFilePath.c_str());
+    fstream fs(tlContFilePath.c_str(), ios_base::out | ios_base::binary);
+    if (!fs) {
+        LOG_E("mcRegistry store So.TrustletCont(uuid) failed: %d", MC_DRV_ERR_INVALID_DEVICE_FILE);
+        return MC_DRV_ERR_INVALID_DEVICE_FILE;
+    }
+    fs.seekg(0, ios::beg);
+    fs.write((char *)so, sizeof(mcSoTltCont_t));
+    fs.flush();
+    fs.close();
+    return MC_DRV_OK;
+}
+
+
+//------------------------------------------------------------------------------
+mcResult_t mcRegistryReadTrustletCon(
+	const mcUuid_t	*uuid,
+	mcSoTltCont_t	*so
+) {
+    if ((NULL == uuid) || (NULL == so)) {
+        LOG_E("mcRegistry read So.TrustletCont(uuid) failed: %d", MC_DRV_ERR_INVALID_PARAMETER);
+        return MC_DRV_ERR_INVALID_PARAMETER;
+    }
+    const string& tlContFilePath = getTlContFilePath(uuid);
+    LOG_I("read TLc: %s", tlContFilePath.c_str());
+    fstream fs(tlContFilePath.c_str(), ios_base::in | ios_base::binary);
+    if (!fs) {
+        LOG_E("mcRegistry read So.TrustletCont(uuid) failed: %d", MC_DRV_ERR_INVALID_DEVICE_FILE);
+        return MC_DRV_ERR_INVALID_DEVICE_FILE;
+    }
+    fs.seekg(0, ios::end);
+    int32_t filesize = fs.tellg();
+    if (sizeof(mcSoTltCont_t) != filesize) {
+        fs.close();
+        LOG_E("mcRegistry read So.TrustletCont(uuid) failed: %d. Size=%i, expected=%i", MC_DRV_ERR_OUT_OF_RESOURCES,filesize,sizeof(mcSoTltCont_t));
+        return MC_DRV_ERR_OUT_OF_RESOURCES;
+    }
+    fs.seekg(0, ios::beg);
+    fs.read((char *)so, sizeof(mcSoTltCont_t));
+    fs.close();
+    return MC_DRV_OK;
+}
+
+
+//------------------------------------------------------------------------------
+mcResult_t mcRegistryStoreData(
+	const mcSoDataCont_t *so
+) {
+    if (NULL == so) {
+        LOG_E("mcRegistry store So.Data failed: %d", MC_DRV_ERR_INVALID_PARAMETER);
+        return MC_DRV_ERR_INVALID_PARAMETER;
+    }
+    string pathname, filename;
+
+    switch (so->cont.type) {
+    case CONT_TYPE_SPDATA:
+        LOG_E("SPDATA not supported");
+        return MC_DRV_ERR_INVALID_PARAMETER;
+        break;
+    case CONT_TYPE_TLDATA:
+        pathname = getTlDataPath(&so->cont.uuid);
+        filename = getTlDataFilePath(&so->cont.uuid, so->cont.pid);
+        break;
+    default:
+        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);
+
+    LOG_I("store DT: %s", filename.c_str());
+    fstream fs(filename.c_str(), ios_base::out | ios_base::binary);
+    if (!fs) {
+        LOG_E("mcRegistry store So.Data(cid/pid) failed: %d", MC_DRV_ERR_INVALID_DEVICE_FILE);
+        return MC_DRV_ERR_INVALID_DEVICE_FILE;
+    }
+    fs.seekg(0, ios::beg);
+    fs.write((char *)so, MC_SO_SIZE(so->soHeader.plainLen, so->soHeader.encryptedLen));
+    fs.flush();
+    fs.close();
+    return MC_DRV_OK;
+}
+
+
+//------------------------------------------------------------------------------
+mcResult_t mcRegistryReadData(
+	uint32_t		context,
+	const mcCid_t	*cid,
+	mcPid_t 		pid,
+	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;
+    }
+    string filename;
+    switch (context) {
+    case 0:
+        LOG_E("SPDATA not supported");
+        return MC_DRV_ERR_INVALID_PARAMETER;
+        break;
+    case 1:
+        filename = getTlDataFilePath(&so->cont.uuid, so->cont.pid);
+        break;
+    default:
+        LOG_E("mcRegistry read So.Data(cid/pid) failed: %d", MC_DRV_ERR_INVALID_PARAMETER);
+        return MC_DRV_ERR_INVALID_PARAMETER;
+    }
+    LOG_I("read DT: %s", filename.c_str());
+    fstream fs(filename.c_str(), ios_base::in | ios_base::binary);
+    if (!fs) {
+        LOG_E("mcRegistry read So.Data(cid/pid) failed: %d", MC_DRV_ERR_INVALID_DEVICE_FILE);
+        return MC_DRV_ERR_INVALID_DEVICE_FILE;
+    }
+    fs.seekg(0, ios::end);
+    uint32_t filesize = fs.tellg();
+    if (maxLen < filesize) {
+        fs.close();
+        LOG_E("mcRegistry read So.Data(cid/pid) failed: %d", MC_DRV_ERR_OUT_OF_RESOURCES);
+        return MC_DRV_ERR_OUT_OF_RESOURCES;
+    }
+    fs.seekg(0, ios::beg);
+    char* p = (char*) so;
+    fs.read(p, sizeof(mcSoHeader_t));
+    p += sizeof(mcSoHeader_t);
+    fs.read(p, MC_SO_SIZE(so->soHeader.plainLen, so->soHeader.encryptedLen) - sizeof(mcSoHeader_t));
+    fs.close();
+    return MC_DRV_OK;
+}
+
+
+//------------------------------------------------------------------------------
+mcResult_t mcRegistryCleanupTrustlet(
+	const mcUuid_t *uuid
+) {
+    DIR            *dp;
+    struct dirent  *de;
+    int             e;
+
+    if (NULL == uuid) {
+        LOG_E("mcRegistry cleanupTrustlet(uuid) failed: %d", MC_DRV_ERR_INVALID_PARAMETER);
+        return MC_DRV_ERR_INVALID_PARAMETER;
+    }
+    string pathname = getTlDataPath(uuid);
+    if (NULL != (dp = opendir(pathname.c_str()))) {
+        while (NULL != (de = readdir(dp))) {
+            if (de->d_name[0] != '.') {
+                string dname = pathname + "/" + string (de->d_name);
+                LOG_I("delete DT: %s", dname.c_str());
+                if (0 != (e = remove(dname.c_str()))) {
+                    LOG_E("remove UUID-data %s failed! error: %d", dname.c_str(), e);
+                    return MC_DRV_ERR_UNKNOWN;
+                }
+            }
+        }
+        LOG_I("delete dir: %s", pathname.c_str());
+        if (0 != (e = rmdir(pathname.c_str()))) {
+            LOG_E("remove UUID-dir failed! errno: %d", e);
+            return MC_DRV_ERR_UNKNOWN;
+        }
+    }
+    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)
+    }
+    string tlContFilePath = getTlContFilePath(uuid);
+    LOG_I("delete Tlc: %s", tlContFilePath.c_str());
+    if (0 != (e = remove(tlContFilePath.c_str()))) {
+        LOG_E("remove Tlc failed! errno: %d", e);
+        return MC_DRV_ERR_UNKNOWN;
+    }
+    return MC_DRV_OK;
+}
+
+
+//------------------------------------------------------------------------------
+mcResult_t mcRegistryCleanupSp(
+	mcSpid_t spid
+) {
+    mcResult_t      ret;
+    mcSoSpCont_t    data;
+    uint32_t        i;
+    DIR            *dp;
+    struct dirent  *de;
+    int             e;
+
+    if (0 == spid) {
+        LOG_E("mcRegistry cleanupSP(SpId) failed: %d", MC_DRV_ERR_INVALID_PARAMETER);
+        return MC_DRV_ERR_INVALID_PARAMETER;
+    }
+    ret = mcRegistryReadSp(spid, &data);
+    if (MC_DRV_OK != ret) {
+        LOG_E("read SP->UUID aborted! Return code: %d", ret);
+        return ret;
+    }
+    for (i = 0; (i < MC_CONT_CHILDREN_COUNT) && (ret == MC_DRV_OK); i++) {
+        if (0 != strncmp((const char *)&(data.cont.children[i]), (const char *)&MC_UUID_FREE, sizeof(mcUuid_t))) {
+            ret = mcRegistryCleanupTrustlet(&(data.cont.children[i]));
+        }
+    }
+    if (MC_DRV_OK != ret) {
+        LOG_E("delete SP->UUID failed! Return code: %d", ret);
+        return ret;
+    }
+    string pathname = getSpDataPath(spid);
+
+    if (NULL != (dp = opendir(pathname.c_str()))) {
+        while (NULL != (de = readdir(dp))) {
+            if (de->d_name[0] != '.') {
+                string dname = pathname + "/" + string (de->d_name);
+                LOG_I("delete DT: %s", dname.c_str());
+                if (0 != (e = remove(dname.c_str()))) {
+                    LOG_E("remove SPID-data %s failed! error: %d", dname.c_str(), e);
+                    return MC_DRV_ERR_UNKNOWN;
+                }
+            }
+        }
+        LOG_I("delete dir: %s", pathname.c_str());
+        if (0 != (e = rmdir(pathname.c_str()))) {
+            LOG_E("remove SPID-dir failed! error: %d", e);
+            return MC_DRV_ERR_UNKNOWN;
+        }
+    }
+    string spContFilePath = getSpContFilePath(spid);
+    LOG_I("delete Sp: %s", spContFilePath.c_str());
+    if (0 != (e = remove(spContFilePath.c_str()))) {
+        LOG_E("remove SP failed! error: %d", e);
+        return MC_DRV_ERR_UNKNOWN;
+    }
+    return MC_DRV_OK;
+}
+
+
+//------------------------------------------------------------------------------
+mcResult_t mcRegistryCleanupRoot(void) {
+    mcResult_t ret;
+    mcSoRootCont_t data;
+    uint32_t i;
+    int e;
+
+    ret = mcRegistryReadRoot(&data);
+    if (MC_DRV_OK != ret) {
+        LOG_E("read Root aborted! Return code: %d", ret);
+        return ret;
+    }
+    for (i = 0; (i < MC_CONT_CHILDREN_COUNT) && (ret == MC_DRV_OK); i++) {
+        mcSpid_t spid = data.cont.children[i];
+        if (spid != MC_SPID_FREE) {
+            ret = mcRegistryCleanupSp(spid);
+            if (MC_DRV_OK != ret) {
+                LOG_E("Cleanup SP failed! Return code: %d", ret);
+                return ret;
+            }
+        }
+    }
+
+    string rootContFilePath = getRootContFilePath();
+    LOG_I("Delete root: %s", rootContFilePath.c_str());
+    if (0 != (e = remove(rootContFilePath.c_str()))) {
+        LOG_E("Delete root failed! error: %d", e);
+        return MC_DRV_ERR_UNKNOWN;
+    }
+    return MC_DRV_OK;
+}
+
+
+//------------------------------------------------------------------------------
+regObject_t *mcRegistryGetServiceBlob(
+	const mcUuid_t *uuid
+) {
+    regObject_t* regobj = NULL;
+
+    // Ensure that a UUID is provided.
+    if (NULL == uuid) {
+        LOG_E("mcRegistryGetServiceBlob() failed. No UUID given");
+        return NULL;
+    }
+
+    // Open service blob file.
+    string tlBinFilePath = getTlBinFilePath(uuid);
+    LOG_I("mcRegistryGetServiceBlob() Loading service: %s", tlBinFilePath.c_str());
+
+    ifstream fs(tlBinFilePath.c_str(), ios_base::binary);
+    if (!fs) {
+        LOG_E("mcRegistryGetServiceBlob() failed: cannot open %s", tlBinFilePath.c_str());
+        return NULL;
+    }
+
+    // Determine and check service blob size.
+    fs.seekg(0, ios::end);
+    int32_t tlSize = fs.tellg();
+    fs.seekg(0, ios::beg);
+    if (MAX_TL_SIZE < tlSize) {
+        LOG_E("mcRegistryGetServiceBlob() failed: service blob too big: %d", tlSize);
+        return NULL;
+    }
+
+    // Check TL magic value.
+    fs.seekg(offsetof(mclfIntro_t, magic), ios::beg);
+    uint32_t magic;
+    fs.read((char*)&magic, sizeof(magic));
+    if (magic != MC_SERVICE_HEADER_MAGIC_BE) {
+        LOG_E("mcRegistryGetServiceBlob() failed: wrong header magic value: %d", magic);
+        return NULL;
+    }
+
+    // Check header version.
+    fs.seekg(offsetof(mclfIntro_t, version), ios::beg);
+    uint32_t version;
+    fs.read((char*)&version, sizeof(version));
+
+    char* msg;
+    if (!checkVersionOkDataObjectMCLF(version, &msg)) {
+        LOG_E("%s", msg);
+        return NULL;
+    }
+
+    // Get service type.
+    fs.seekg(offsetof(mclfHeaderV1_t, serviceType), ios::beg);
+    serviceType_t serviceType;
+    fs.read((char*)&serviceType, sizeof(serviceType));
+    fs.seekg(0, ios::beg);
+
+    LOG_I("mcRegistryGetServiceBlob() Service is of type: %d", serviceType);
+
+    // If loadable driver or system trustlet.
+    if (SERVICE_TYPE_DRIVER == serviceType || SERVICE_TYPE_SYSTEM_TRUSTLET == serviceType) {
+        // Take trustlet blob 'as is'.
+        if (NULL == (regobj = (regObject_t*) (malloc(sizeof(regObject_t) + tlSize)))) {
+            LOG_E("mcRegistryGetServiceBlob() failed: Out of memory");
+            return NULL;
+        }
+        regobj->len = tlSize;
+        fs.read((char *)regobj->value, tlSize);
+        fs.close();
+    // If user trustlet.
+    } else if (SERVICE_TYPE_SP_TRUSTLET == serviceType) {
+        // Take trustlet blob and append root, sp, and tl container.
+        size_t regObjValueSize = tlSize + sizeof(mcSoContainerPath_t);
+
+        // Prepare registry object.
+        if (NULL == (regobj = (regObject_t*) malloc(sizeof(regObject_t) + regObjValueSize))) {
+            LOG_E("mcRegistryGetServiceBlob() failed: Out of memory");
+            return NULL;
+        }
+        regobj->len = regObjValueSize;
+
+        // Read and fill in trustlet blob at beginning.
+        fs.read((char*)regobj->value, tlSize);
+        fs.close();
+
+        // Goto end of allocated space and fill in tl container, sp container,
+        // and root container from back to front. Final registry object value
+        // looks like this:
+        // 
+        //    +---------------------------+-----------+---------+---------+
+        //    | TL-Header TL-Code TL-Data | Root Cont | SP Cont | TL Cont |
+        //    +---------------------------+-----------+-------------------+
+        //    /------ Trustlet BLOB ------/
+        //
+        //    /------------------ regobj->header.len ---------------------/
+
+        uint8_t* p = regobj->value + regobj->len;
+        mcResult_t ret;
+        do {
+            char* msg;
+
+            // Fill in TL container.
+            p -= sizeof(mcSoTltCont_t);
+            mcSoTltCont_t* soTlt = (mcSoTltCont_t*)p;
+            if (MC_DRV_OK != (ret = mcRegistryReadTrustletCon(uuid, soTlt))) {
+                break;
+            }
+            mcTltCont_t* tltCont = &soTlt->cont;
+            if (!checkVersionOkDataObjectCONTAINER(tltCont->version, &msg)) {
+                LOG_E("Tlt container %s", msg);
+                ret = MC_DRV_ERR_CONTAINER_VERSION;
+                break;
+            }
+
+            // Fill in SP container.
+            mcSpid_t spid = tltCont->parent;
+            p -= sizeof(mcSoSpCont_t);
+            mcSoSpCont_t* soSp = (mcSoSpCont_t*)p;
+            if (MC_DRV_OK != (ret = mcRegistryReadSp(spid, soSp))) {
+                break;
+            }
+            mcSpCont_t* spCont = &soSp->cont;
+            if (!checkVersionOkDataObjectCONTAINER(spCont->version, &msg)) {
+                LOG_E("SP container %s", msg);
+                ret = MC_DRV_ERR_CONTAINER_VERSION;
+                break;
+            }
+
+            // Fill in root container.
+            p -= sizeof(mcSoRootCont_t);
+            mcSoRootCont_t* soRoot = (mcSoRootCont_t*)p;
+            if (MC_DRV_OK != (ret = mcRegistryReadRoot(soRoot))) {
+                break;
+            }
+            mcRootCont_t* rootCont = &soRoot->cont;
+            if (!checkVersionOkDataObjectCONTAINER(rootCont->version, &msg)) {
+                LOG_E("Root container %s", msg);
+                ret = MC_DRV_ERR_CONTAINER_VERSION;
+                break;
+            }
+
+            // Ensure order of elements in registry object value.
+            assert(p - tlSize - sizeof(regObject_t) == (uint8_t*)regobj);
+        } while (false);
+
+        if (MC_DRV_OK != ret) {
+            LOG_E("mcRegistryGetServiceBlob() failed: Error code: %d", ret);
+            free(regobj);
+            return NULL;
+        }
+    // Any other service type.
+    } else {
+        LOG_E("mcRegistryGetServiceBlob() failed: Unsupported service type %u", serviceType);
+    }
+
+    return regobj;
+}
+
+//------------------------------------------------------------------------------
+regObject_t *mcRegistryGetDriverBlob(
+	const char *driverFilename
+) {
+	regObject_t* regobj = NULL;
+	
+	// Open service blob file.
+	ifstream fs(driverFilename, ios_base::binary);
+	if (!fs) {
+		LOG_E("mcRegistryGetDriverBlob() failed: cannot open %s", driverFilename);
+		return NULL;
+	}
+	
+	// Determine and check service blob size.
+	fs.seekg(0, ios::end);
+	int32_t tlSize = fs.tellg();
+	fs.seekg(0, ios::beg);
+	if (MAX_TL_SIZE < tlSize) {
+		LOG_E("mcRegistryGetDriverBlob() failed: service blob too big: %d", tlSize);
+		return NULL;
+	}
+	
+	// Check TL magic value.
+	fs.seekg(offsetof(mclfIntro_t, magic), ios::beg);
+	uint32_t magic;
+	fs.read((char*)&magic, sizeof(magic));
+	if (magic != MC_SERVICE_HEADER_MAGIC_BE) {
+		LOG_E("mcRegistryGetDriverBlob() failed: wrong header magic value: %d", magic);
+		return NULL;
+	}
+	
+	// Check header version.
+	fs.seekg(offsetof(mclfIntro_t, version), ios::beg);
+	uint32_t version;
+	fs.read((char*)&version, sizeof(version));
+
+    char* msg;
+    if (!checkVersionOkDataObjectMCLF(version, &msg)) {
+        LOG_E("%s", msg);
+        return NULL;
+    }
+	
+	// Get service type.
+	fs.seekg(offsetof(mclfHeaderV1_t, serviceType), ios::beg);
+	serviceType_t serviceType;
+	fs.read((char*)&serviceType, sizeof(serviceType));
+	fs.seekg(0, ios::beg);
+	
+	LOG_I("mcRegistryGetDriverBlob() Service is of type: %d", serviceType);
+	
+	// If loadable driver or system trustlet.
+	if (SERVICE_TYPE_DRIVER == serviceType) {
+		// Take trustlet blob 'as is'.
+		if (NULL == (regobj = (regObject_t*) (malloc(sizeof(regObject_t) + tlSize)))) {
+			LOG_E("mcRegistryGetDriverBlob() failed: Out of memory");
+			return NULL;
+		}
+		regobj->len = tlSize;
+		fs.read((char *)regobj->value, tlSize);
+		fs.close();
+		// Otherwise we are not interested
+	} else {
+		LOG_E("mcRegistryGetServiceBlob() failed: Unsupported service type %u", serviceType);
+	}
+	
+	return regobj;
+}
+
+//------------------------------------------------------------------------------
+static const string getRegistryPath() {
+    const char* path;
+    string registryPath;
+
+    // First, attempt to use regular registry environment variable.
+    path = getenv(ENV_MC_REGISTRY_PATH.c_str());
+    if (doesDirExist(path)) {
+        LOG_I("getRegistryPath(): Using MC_REGISTRY_PATH %s", path);
+        registryPath = path;
+    } else {
+        // Second, attempt to use fallback registry environment variable.
+        path = getenv(ENV_MC_REGISTRY_FALLBACK_PATH.c_str());
+        if (doesDirExist(path)) {
+            LOG_I("getRegistryPath(): Using MC_REGISTRY_FALLBACK_PATH %s", path);
+            registryPath = path;
+        }
+    }
+
+    // As a last resort, use the default registry path.
+    if (registryPath.length() == 0) {
+        registryPath = MC_REGISTRY_DEFAULT_PATH;
+        LOG_I("getRegistryPath(): Using default registry path %s", registryPath.c_str());
+    }
+
+    assert(registryPath.length() != 0);
+    
+    return registryPath;
+}
+
+//------------------------------------------------------------------------------
+static const string getAuthTokenFilePath() {
+    const char* path;
+    string authTokenPath;
+
+    // First, attempt to use regular auth token path environment variable.
+    path = getenv(ENV_MC_AUTH_TOKEN_PATH.c_str());
+    if (doesDirExist(path)) {
+        LOG_I("getAuthTokenFilePath(): Using MC_AUTH_TOKEN_PATH %s", path);
+        authTokenPath = path;
+    } else {
+        authTokenPath = getRegistryPath();
+        LOG_I("getAuthTokenFilePath(): Using path %s", authTokenPath.c_str());
+    }
+
+    return authTokenPath + "/" + AUTH_TOKEN_FILE_NAME;
+}
+
+//------------------------------------------------------------------------------
+static const string getRootContFilePath() {
+    return getRegistryPath() + "/" + ROOT_FILE_NAME;
+}
+
+//------------------------------------------------------------------------------
+static const string getSpDataPath(mcSpid_t spid) {
+    return getRegistryPath() + "/" + uint32ToString(spid);
+}
+
+//------------------------------------------------------------------------------
+static const string getSpContFilePath(mcSpid_t spid) {
+    return getRegistryPath() + "/" + uint32ToString(spid) + SP_CONT_FILE_EXT;
+}
+
+//------------------------------------------------------------------------------
+static const string getTlContFilePath(const mcUuid_t* uuid) {
+    return getRegistryPath() + "/" + byteArrayToString(uuid, sizeof(*uuid)) + TL_CONT_FILE_EXT;
+}
+
+//------------------------------------------------------------------------------
+static const string getTlDataPath(const mcUuid_t* uuid) {
+    return getRegistryPath() + "/" + byteArrayToString(uuid, sizeof(*uuid));
+}
+
+//------------------------------------------------------------------------------
+static const string getTlDataFilePath(const mcUuid_t* uuid, mcPid_t pid) {
+    return getTlDataPath(uuid) + "/" + uint32ToString(pid.data) + DATA_CONT_FILE_EXT;
+}
+
+//------------------------------------------------------------------------------
+static const string getTlBinFilePath(const mcUuid_t* uuid) {
+    return getRegistryPath() + "/" + byteArrayToString(uuid, sizeof(*uuid)) + TL_BIN_FILE_EXT;
+}
+
+//------------------------------------------------------------------------------
+static const string byteArrayToString(const void* bytes, size_t elems) {
+    char hx[elems * 2 + 1];
+
+    for (size_t i = 0; i < elems; i++) {
+		sprintf(&hx[i * 2], "%02x", ((uint8_t*)bytes)[i]);
+	}
+    return string(hx);
+}
+
+//------------------------------------------------------------------------------
+static const string uint32ToString(
+	uint32_t value
+) {
+    char hx[sizeof(uint32_t) * 2 + 1];
+    uint32_t i;
+
+    for (i = 0; i < (2 * sizeof(value)); i++) {
+		hx[i] = (value >> (28 - (i * 4))) & 0x0F;
+		if (hx[i] > 9) {
+			hx[i] = (hx[i] - 9) | 0x40;
+		} else {
+			hx[i] |= 0x30;
+		}
+	}
+    hx[i] = '\0';
+    return string(hx);
+}
+
+//------------------------------------------------------------------------------
+static bool doesDirExist(const char* path) {
+    struct stat ss;
+    if (path != NULL && stat(path, &ss) == 0 && S_ISDIR(ss.st_mode)) {
+        return true;
+    }
+    return false;
+}
+
+
+/** @} */
diff --git a/V008/Android/external/mobicore/daemon/buildTag.h b/V008/Android/external/mobicore/daemon/buildTag.h
new file mode 100644
index 0000000..57dda31
--- /dev/null
+++ b/V008/Android/external/mobicore/daemon/buildTag.h
@@ -0,0 +1,29 @@
+/** Build tag created during build by ./Out/_build/Scripts/trunk/00016967/Out/setBuildTag.sh.
+ *
+ * <!-- Copyright Giesecke & Devrient GmbH 2012-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.
+ */
+#define MOBICORE_COMPONENT_BUILD_TAG "*** GC_MSM8960_Release_V008 ###"
diff --git a/V008/Android/external/mobicore/include/Public/mcDrvModuleApi.h b/V008/Android/external/mobicore/include/Public/mcDrvModuleApi.h
new file mode 100644
index 0000000..9632822
--- /dev/null
+++ b/V008/Android/external/mobicore/include/Public/mcDrvModuleApi.h
@@ -0,0 +1,307 @@
+/** @addtogroup MCD_MCDIMPL_KMOD
+ * @{
+ * Interface to Mobicore Driver Kernel Module.
+ *
+ * <h2>Introduction</h2>
+ * 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
+ * given virtual memory are also supported. IRQ functionallity receives
+ * information from the SWd in the non secure world (NWd).
+ * As customary the driver is handled as linux device driver with "open",
+ * "close" and "ioctl" commands. Access to the driver is possible after the
+ * device "/dev/mobicore" has been opened.
+ * The MobiCore Driver Kernel Module must be installed via
+ * "insmod mcDrvModule.ko".
+ *
+ *
+ * <h2>Version history</h2>
+ * <table class="customtab">
+ * <tr><td width="100px"><b>Date</b></td><td width="80px"><b>Version</b></td>
+ * <td><b>Changes</b></td></tr>
+ * <tr><td>2010-05-25</td><td>0.1</td><td>Initial Release</td></tr>
+ * </table>
+ *
+ * <!-- Copyright Giesecke & Devrient GmbH 2010-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 _MC_DRV_MODULEAPI_H_
+#define _MC_DRV_MODULEAPI_H_
+
+#include "version.h"
+
+#define MC_DRV_MOD_DEVNODE		   "mobicore"
+#define MC_DRV_MOD_DEVNODE_FULLPATH  "/dev/" MC_DRV_MOD_DEVNODE
+
+/**
+ * Data exchange structure of the MC_DRV_MODULE_INIT ioctl command.
+ * INIT request data to SWD
+ */
+union mcIoCtlInitParams {
+	struct {
+		/** base address of mci buffer 4KB align */
+		uint32_t  base;
+		/** notification buffer start/length [16:16] [start, length] */
+		uint32_t  nqOffset;
+		/** length of notification queue */
+		uint32_t  nqLength;
+		/** mcp buffer start/length [16:16] [start, length] */
+		uint32_t  mcpOffset;
+		/** length of mcp buffer */
+		uint32_t  mcpLength;
+	} in;
+	struct {
+		/* nothing */
+	} out;
+};
+
+
+/**
+ * Data exchange structure of the MC_DRV_MODULE_INFO ioctl command.
+ * INFO request data to the SWD
+ */
+union mcIoCtlInfoParams {
+	struct {
+		uint32_t  extInfoId; /**< extended info ID */
+	} in;
+	struct {
+		uint32_t  state; /**< state */
+		uint32_t  extInfo; /**< extended info */
+	} out;
+};
+
+/**
+ * Mmap allocates and maps contiguous memory into a process.
+ * We use the third parameter, void *offset, to distinguish between some cases
+ * offset = MC_DRV_KMOD_MMAP_WSM	usual operation, pages are registered in
+					device structure and freed later.
+ * offset = MC_DRV_KMOD_MMAP_MCI	get Instance of MCI, allocates or mmaps
+					the MCI to daemon
+ * offset = MC_DRV_KMOD_MMAP_PERSISTENTWSM	special operation, without
+						registration of pages
+ *
+ * In mmap(), the offset specifies which of several device I/O pages is
+ *  requested. Linux only transfers the page number, i.e. the upper 20 bits to
+ *  kernel module. Therefore we define our special offsets as multiples of page
+ *  size.
+ */
+enum mcMmapMemtype {
+	MC_DRV_KMOD_MMAP_WSM		= 0,
+	MC_DRV_KMOD_MMAP_MCI		= 4096,
+	MC_DRV_KMOD_MMAP_PERSISTENTWSM	= 8192
+};
+
+struct mcMmapResp {
+	uint32_t  handle; /**< WSN handle */
+	uint32_t  physAddr; /**< physical address of WSM (or NULL) */
+	bool	  isReused; /**< if WSM memory was reused, or new allocated */
+};
+
+/**
+ * Data exchange structure of the MC_DRV_KMOD_IOCTL_FREE ioctl command.
+ */
+union mcIoCtltoFreeParams {
+	struct {
+		uint32_t  handle; /**< driver handle */
+		uint32_t  pid; /**< process id */
+	} in;
+	struct {
+		/* nothing */
+	} out;
+};
+
+
+/**
+ * Data exchange structure of the MC_DRV_KMOD_IOCTL_APP_REGISTER_WSM_L2 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
+ * will be modified to the used values.
+ */
+union mcIoCtlAppRegWsmL2Params {
+	struct {
+		uint32_t  buffer; /**< base address of the virtual address  */
+		uint32_t  len; /**< size of the virtual address space */
+		uint32_t  pid; /**< process id */
+	} in;
+	struct {
+		uint32_t  handle; /**< driver handle for locked memory */
+		uint32_t  physWsmL2Table; /* physical address of the L2 table */
+	} out;
+};
+
+
+/**
+ * Data exchange structure of the MC_DRV_KMOD_IOCTL_APP_UNREGISTER_WSM_L2
+ * command.
+ */
+struct mcIoCtlAppUnregWsmL2Params {
+	struct {
+		uint32_t  handle; /**< driver handle for locked memory */
+		uint32_t  pid; /**< process id */
+	} in;
+	struct {
+		/* nothing */
+	} out;
+};
+
+
+/**
+ * Data exchange structure of the MC_DRV_KMOD_IOCTL_DAEMON_LOCK_WSM_L2 command.
+ */
+struct mcIoCtlDaemonLockWsmL2Params {
+	struct {
+		uint32_t  handle; /**< driver handle for locked memory */
+	} in;
+	struct {
+		uint32_t physWsmL2Table;
+	} out;
+};
+
+
+/**
+ * Data exchange structure of the MC_DRV_KMOD_IOCTL_DAEMON_UNLOCK_WSM_L2
+ * command.
+ */
+struct mcIoCtlDaemonUnlockWsmL2Params {
+	struct {
+		uint32_t  handle; /**< driver handle for locked memory */
+	} in;
+	struct {
+		/* nothing */
+	} out;
+};
+
+/**
+ * Data exchange structure of the MC_DRV_MODULE_FC_EXECUTE ioctl command.
+ */
+union mcIoCtlFcExecuteParams {
+	struct {
+		uint32_t  physStartAddr;/**< base address of mobicore binary */
+		uint32_t  length;	/**< length of DDR area */
+	} in;
+	struct {
+		/* nothing */
+	} out;
+};
+
+/**
+ * Data exchange structure of the MC_DRV_MODULE_GET_VERSION ioctl command.
+ */
+struct mcIoCtlGetVersionParams {
+	struct {
+		uint32_t	kernelModuleVersion;
+	} out;
+};
+
+/* @defgroup Mobicore_Driver_Kernel_Module_Interface IOCTL */
+
+
+
+
+/* TODO: use IOCTL macros like _IOWR. See Documentation/ioctl/ioctl-number.txt,
+	Documentation/ioctl/ioctl-decoding.txt */
+/**
+ * defines for the ioctl mobicore driver module function call from user space.
+ */
+enum mcKModIoClt {
+
+	/*
+	 * get detailed MobiCore Status
+	 */
+	MC_DRV_KMOD_IOCTL_DUMP_STATUS  = 200,
+
+	/*
+	 * initialize MobiCore
+	 */
+	MC_DRV_KMOD_IOCTL_FC_INIT  = 201,
+
+	/*
+	 * get MobiCore status
+	 */
+	MC_DRV_KMOD_IOCTL_FC_INFO  = 202,
+
+	/**
+	 * ioctl parameter to send the YIELD command to the SWD.
+	 * Only possible in Privileged Mode.
+	 * ioctl(fd, MC_DRV_MODULE_YIELD)
+	 */
+	MC_DRV_KMOD_IOCTL_FC_YIELD =  203,
+	/**
+	 * ioctl parameter to send the NSIQ signal to the SWD.
+	 * Only possible in Privileged Mode
+	 * ioctl(fd, MC_DRV_MODULE_NSIQ)
+	 */
+	MC_DRV_KMOD_IOCTL_FC_NSIQ   =  204,
+	/**
+	 * ioctl parameter to tzbsp to start Mobicore binary from DDR.
+	 * Only possible in Privileged Mode
+	 * ioctl(fd, MC_DRV_KMOD_IOCTL_FC_EXECUTE)
+	 */
+	MC_DRV_KMOD_IOCTL_FC_EXECUTE =  205,
+
+	/**
+	 * Free's memory which is formerly allocated by the driver's mmap
+	 * command. The parameter must be this mmaped address.
+	 * The internal instance data regarding to this address are deleted as
+	 * well as each according memory page and its appropriated reserved bit
+	 * is cleared (ClearPageReserved).
+	 * Usage: ioctl(fd, MC_DRV_MODULE_FREE, &address) with address beeing of
+	 * type long address
+	 */
+	MC_DRV_KMOD_IOCTL_FREE = 218,
+
+	/**
+	 * Creates a L2 Table of the given base address and the size of the
+	 * data.
+	 * Parameter: mcIoCtlAppRegWsmL2Params
+	 */
+	MC_DRV_KMOD_IOCTL_APP_REGISTER_WSM_L2 = 220,
+
+	/**
+	 * Frees the L2 table created by a MC_DRV_KMOD_IOCTL_APP_REGISTER_WSM_L2
+	 * ioctl.
+	 * Parameter: mcIoCtlAppUnRegWsmL2Params
+	 */
+	MC_DRV_KMOD_IOCTL_APP_UNREGISTER_WSM_L2 = 221,
+
+
+	/* TODO: comment this. */
+	MC_DRV_KMOD_IOCTL_DAEMON_LOCK_WSM_L2 = 222,
+	MC_DRV_KMOD_IOCTL_DAEMON_UNLOCK_WSM_L2 = 223,
+
+	/**
+	 * Return kernel driver version.
+	 * Parameter: mcIoCtlGetVersionParams
+	 */
+	MC_DRV_KMOD_IOCTL_GET_VERSION = 224,
+};
+
+
+#endif /* _MC_DRV_MODULEAPI_H_ */
+/** @} */
diff --git a/V008/Android/external/mobicore/include/Public/version.h b/V008/Android/external/mobicore/include/Public/version.h
new file mode 100644
index 0000000..7779a1d
--- /dev/null
+++ b/V008/Android/external/mobicore/include/Public/version.h
@@ -0,0 +1,36 @@
+/** @addtogroup MCD_MCDIMPL_KMOD
+ * @{
+ * <!-- Copyright Giesecke & Devrient GmbH 2010-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 _MC_DRV_VERSION_H_
+#define _MC_DRV_VERSION_H_
+
+#define MCDRVMODULEAPI_VERSION_MAJOR 0
+#define MCDRVMODULEAPI_VERSION_MINOR 1
+
+#endif /* _MC_DRV_VERSION_H_ */
diff --git a/V008/Linux/drivers/gud/Kconfig b/V008/Linux/drivers/gud/Kconfig
new file mode 100644
index 0000000..0ae1c61
--- /dev/null
+++ b/V008/Linux/drivers/gud/Kconfig
@@ -0,0 +1,33 @@
+#
+# MobiCore configuration
+#
+config MOBICORE_SUPPORT
+	bool "Linux MobiCore Support"
+	#tristate "Linux MobiCore Support"
+	#depends on ARM_TRUSTZONE
+	---help---
+	  Enable Linux Kernel MobiCore Support
+
+config MOBICORE_DEBUG
+    bool "MobiCore Module debug mode"
+    depends on MOBICORE_SUPPORT
+    ---help---
+      Enable Debug mode in the MobiCore Driver.
+      It enables printing information about mobicore operations
+
+config MOBICORE_VERBOSE
+    bool "MobiCore Module verbose debug mode"
+    depends on MOBICORE_DEBUG
+    ---help---
+      Enable Verbose Debug mode in the MobiCore Driver.
+      It enables printing extra information about mobicore operations
+      Beware: this is only useful for debuging deep in the driver because
+      it prints too much logs
+
+
+config MOBICORE_API
+    tristate "Linux MobiCore API"
+    depends on MOBICORE_SUPPORT
+    ---help---
+      Enable Linux Kernel MobiCore API
+
diff --git a/V008/Linux/drivers/gud/Makefile b/V008/Linux/drivers/gud/Makefile
new file mode 100644
index 0000000..9e333d1
--- /dev/null
+++ b/V008/Linux/drivers/gud/Makefile
@@ -0,0 +1,31 @@
+#
+# Makefile for the kernel mobicore drivers
+#
+GUD_ROOT_FOLDER := drivers/gud
+# add our modules to kernel.
+obj-$(CONFIG_MOBICORE_API) += mcKernelApi.o
+obj-$(CONFIG_MOBICORE_SUPPORT) += mcDrvModule.o
+
+mcDrvModule-objs := MobiCoreDriver/mcDrvModule.o
+
+mcKernelApi-objs := MobiCoreKernelApi/main.o \
+		MobiCoreKernelApi/clientlib.o \
+		MobiCoreKernelApi/device.o \
+		MobiCoreKernelApi/session.o \
+		MobiCoreKernelApi/connection.o
+
+# Release mode by default
+ccflags-y := -DNDEBUG
+ccflags-y += -Wno-declaration-after-statement
+
+ccflags-$(CONFIG_MOBICORE_DEBUG) += -DDEBUG
+ccflags-$(CONFIG_MOBICORE_VERBOSE) += -DDEBUG_VERBOSE
+
+# Choose one platform from the folder
+MOBICORE_PLATFORM := $(shell (ls -1 $(PWD)/$(GUD_ROOT_FOLDER)/MobiCoreDriver/platforms | tail -1) )
+# Use the available platform folder
+ccflags-y += -I$(GUD_ROOT_FOLDER)/MobiCoreDriver/platforms/$(MOBICORE_PLATFORM)
+
+
+ccflags-y += -I$(GUD_ROOT_FOLDER)/MobiCoreDriver/public
+ccflags-y += -I$(GUD_ROOT_FOLDER)/MobiCoreKernelApi/include
diff --git a/V008/Linux/drivers/gud/MobiCoreDriver/buildTag.h b/V008/Linux/drivers/gud/MobiCoreDriver/buildTag.h
new file mode 100644
index 0000000..2e39c97
--- /dev/null
+++ b/V008/Linux/drivers/gud/MobiCoreDriver/buildTag.h
@@ -0,0 +1,29 @@
+/**
+ *
+ * <!-- Copyright Giesecke & Devrient GmbH 2012-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.
+ */
+#define MOBICORE_COMPONENT_BUILD_TAG "*** GC_MSM8960_Release_V008 ###"
diff --git a/V008/Linux/drivers/gud/MobiCoreDriver/mcDrvModule.c b/V008/Linux/drivers/gud/MobiCoreDriver/mcDrvModule.c
new file mode 100644
index 0000000..9575a34
--- /dev/null
+++ b/V008/Linux/drivers/gud/MobiCoreDriver/mcDrvModule.c
@@ -0,0 +1,2972 @@
+/** MobiCore driver module.(interface to the secure world SWD)
+ * @addtogroup MobiCore_Driver_Kernel_Module
+ * @{
+ * @file
+ * MobiCore Driver Kernel Module.
+ * This module is written as a Linux device driver.
+ * This driver represents the command proxy on the lowest layer, from the
+ * secure world to the non secure world, and vice versa.
+ * This driver is located in the non secure world (Linux).
+ * This driver offers IOCTL commands, for access to the secure world, and has
+ * the interface from the secure world to the normal world.
+ * The access to the driver is possible with a file descriptor,
+ * which has to be created by the fd = open(/dev/mobicore) command.
+ *
+ * <!-- Copyright Giesecke & Devrient GmbH 2009-2012 -->
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include "mcDrvModule.h"
+#include "mcDrvModuleLinuxApi.h"
+#include "mcDrvModuleAndroid.h"
+#include "mcDrvModuleFc.h"
+#include "public/mcKernelApi.h"
+#include "buildTag.h"
+
+/* Initial value for the daemon sempahore signaling */
+#define DAEMON_SEM_VAL 0
+
+/** MobiCore interrupt context data */
+static struct mcDrvKModCtx	mcDrvKModCtx;
+
+/** MobiCore MCI information */
+static uint32_t			  mciBase;
+/*
+#############################################################################
+##
+## Convenience functions for Linux API functions
+##
+#############################################################################*/
+static int gotoCpu0(void);
+static int gotoAllCpu(void) __attribute__ ((unused));
+
+
+/*----------------------------------------------------------------------------*/
+static void initAndAddToList(
+	struct list_head *pItem,
+	struct list_head *pListHead
+)
+{
+	INIT_LIST_HEAD(pItem);
+
+	list_add(pItem, pListHead);
+}
+
+/*----------------------------------------------------------------------------*/
+/** check if CPU supports the ARM TrustZone Security Extensions
+ *	@return int TRUE or FALSE */
+static int hasSecurityExtensions(
+	void
+)
+{
+	u32 fea = 0;
+	asm volatile(
+		"mrc p15, 0, %[fea], cr0, cr1, 0" :
+		[fea]"=r" (fea));
+
+	MCDRV_DBG_VERBOSE("CPU Features: 0x%X", fea);
+
+	/* If the CPU features ID has 0 for security features then the CPU
+	 * doesn't support TrustZone at all!
+	 */
+	if ((fea & ARM_SECURITY_EXTENSION_MASK) == 0)
+		return 0;
+
+	return 1;
+}
+
+/*----------------------------------------------------------------------------*/
+/** check if running in secure mode
+ *	@return int TRUE or FALSE */
+static int isSecureMode(
+	void
+)
+{
+	u32 cpsr = 0, nsacr = 0;
+	asm volatile(
+		"mrc	p15, 0, %[nsacr], cr1, cr1, 2\n"
+		"mrs %[cpsr], cpsr\n" :
+		[nsacr]"=r" (nsacr),
+		[cpsr]"=r"(cpsr));
+
+	MCDRV_DBG_VERBOSE("CPRS.M = set to 0x%X\n", cpsr & ARM_CPSR_MASK);
+	MCDRV_DBG_VERBOSE("SCR.NS = set to 0x%X\n", nsacr);
+
+	/* If the NSACR contains the reset value(=0) then most likely we are
+	 * running in Secure MODE.
+	 * If the cpsr mode is set to monitor mode then we cannot load!
+	 */
+	if (nsacr == 0 || ((cpsr & ARM_CPSR_MASK) == ARM_MONITOR_MODE))
+		return 1;
+
+	return 0;
+}
+
+/*----------------------------------------------------------------------------*/
+/** check if userland caller is privileged (aka has "root" access rights).
+	@return int TRUE or FALSE */
+static int isUserlandCallerPrivileged(
+	void
+) {
+	/* For some platforms we cannot run the Daemon as root - for Android
+	 * compliance tests it is not allowed, thus we assume the daemon is ran
+	 * as the system user.
+	 * In Android the system user for daemons has no particular capabilities
+	 * other than a fixed UID: AID_SYSTEM		1000
+	 * The actual number is guaranteed to be the same in all Android systems
+	 * so we will take it for granted: see android_filesystem_config.h in
+	 * the Android source tree for all UIDs and their meaning:
+	 * http://android-dls.com/wiki/index.php?title=Android_UIDs_and_GIDs
+	 */
+#ifdef MC_ANDROID_UID_CHECK
+	return current_euid() <= AID_SYSTEM;
+#else
+	/* capable should cover all possibilities, root or sudo, uid checking
+	 * was not very reliable */
+	return capable(CAP_SYS_ADMIN);
+#endif
+}
+
+
+
+/*----------------------------------------------------------------------------*/
+static void unlockPagefromWsmL2Table(
+	struct page *pPage
+){
+	/* REV axh: check if we should do this. */
+	SetPageDirty(pPage);
+
+	/* release page, old api was page_cache_release() */
+	ClearPageReserved(pPage);
+	put_page(pPage);
+}
+
+/*----------------------------------------------------------------------------*/
+/* convert L2 PTE to page pointer */
+static struct page *l2PteToPage(
+	pte_t pte
+) {
+	void *physPageAddr = (void *)((unsigned int)pte & PAGE_MASK);
+	unsigned int pfn  = addrToPfn(physPageAddr);
+	struct page  *pPage = pfn_to_page(pfn);
+	return pPage;
+}
+
+/*----------------------------------------------------------------------------*/
+/* convert page pointer to L2 PTE */
+static pte_t pageToL2Pte(
+	struct page *pPage
+)
+{
+	unsigned int pfn	  = page_to_pfn(pPage);
+	void		 *physAddr = pfnToAddr(pfn);
+	pte_t		pte	  = (pte_t)((unsigned int)physAddr & PAGE_MASK);
+	return pte;
+}
+
+
+/*----------------------------------------------------------------------------*/
+static inline int lockUserPages(
+	struct task_struct	*pTask,
+	void			*virtStartPageAddr,
+	int			nrOfPages,
+	struct page		**pages
+)
+{
+	int		ret = 0;
+	int		lockedPages = 0;
+	unsigned int	i;
+
+	do {
+
+		/* lock user pages, must hold the mmap_sem to do this. */
+		down_read(&(pTask->mm->mmap_sem));
+		lockedPages = get_user_pages(
+					  pTask,
+					  pTask->mm,
+					  (unsigned long)virtStartPageAddr,
+					  nrOfPages,
+					  1, /* write access */
+					  0, /* they say drivers should always
+						pass 0 here..... */
+					  pages,
+					  NULL); /* we don't need the VMAs */
+		up_read(&(pTask->mm->mmap_sem));
+
+		/* could as lock all pages? */
+		if (lockedPages != nrOfPages) {
+			MCDRV_DBG_ERROR(
+				"get_user_pages() failed, "
+				"lockedPages=%d\n",
+				lockedPages);
+			ret = -ENOMEM;
+			/* check if an error has been returned. */
+			if (lockedPages < 0) {
+				ret = lockedPages;
+				lockedPages = 0;
+			}
+			break;
+		}
+
+		/* do cache maintenance on locked pages. */
+		for (i = 0; i < nrOfPages; i++)
+			flush_dcache_page(pages[i]);
+
+	} while (FALSE);
+
+
+	if (0 != ret) {
+		/* release all locked pages. */
+		MCDRV_ASSERT(0 <= lockedPages);
+		for (i = 0; i < lockedPages; i++)
+			put_page(pages[i]);
+	}
+
+	return ret;
+
+}
+
+/*
+#############################################################################
+##
+## Driver implementation functions
+##
+#############################################################################*/
+
+#ifdef MC_MEM_TRACES
+/** MobiCore log previous char */
+static uint32_t mcLogPos; /* = 0 */;
+/** MobiCore log buffer structure */
+static struct mcTraceBuf *mcLogBuf; /* = NULL */;
+static DEFINE_MUTEX(log_mutex);
+/*----------------------------------------------------------------------------*/
+static void mobicore_read_log(
+	void
+) {
+	uint32_t write_pos;
+	char *buff, *last_char;
+
+	if (mcLogBuf == NULL)
+		return;
+
+	write_pos = mcLogBuf->write_pos;
+	buff = mcLogBuf->buff + mcLogPos;
+	last_char = mcLogBuf->buff + write_pos;
+
+	/* Nothing to do! */
+	if (write_pos == mcLogPos)
+		return;
+	mutex_lock(&log_mutex);
+#define LOG_CHAR printk
+	while (buff != last_char) {
+		LOG_CHAR("%c", *(buff++));
+		/* Wrap around */
+		if (buff >= (char *)mcLogBuf + PAGE_SIZE)
+			buff = mcLogBuf->buff;
+	}
+	mcLogPos = write_pos;
+	mutex_unlock(&log_mutex);
+}
+
+/*----------------------------------------------------------------------------*/
+/**
+ * Setup mobicore kernel log
+ */
+static void mcKernelModule_setupLog(
+	void
+) {
+	void *logPage;
+	unsigned long physLogPage;
+	union fcGeneric fcLog;
+	int ret;
+
+	/* We need to go to CPU0 because we are going to do some SMC calls and
+	 * they will otherwise fail because the Mobicore Monitor resides on
+	 * CPU0(for Cortex A9 and lower) */
+	ret = gotoCpu0();
+	if (0 != ret) {
+		MCDRV_DBG("changing core failed!\n");
+		return;
+	}
+
+	mcLogPos = 0;
+	do {
+		logPage = (void *)get_zeroed_page(GFP_KERNEL);
+		if (!logPage) {
+			MCDRV_DBG_ERROR("Failed to get page for logger!");
+			break;
+		}
+		physLogPage = virt_to_phys(logPage);
+		mcLogBuf = logPage;
+
+		memset(&fcLog, 0, sizeof(fcLog));
+		fcLog.asIn.cmd	  = MC_FC_NWD_TRACE;
+		fcLog.asIn.param[0] = physLogPage;
+		fcLog.asIn.param[1] = PAGE_SIZE;
+
+		MCDRV_DBG("fcLog virtPage=%p phyLogPage=%p ",
+			logPage, (void *)physLogPage);
+		mcFastCall(&fcLog);
+		MCDRV_DBG("fcInfo out ret=0x%08x", fcLog.asOut.ret);
+
+		if (fcLog.asOut.ret) {
+			MCDRV_DBG_ERROR("Mobicore shared traces setup failed!");
+			free_page((unsigned long)logPage);
+			mcLogBuf = NULL;
+			break;
+		}
+	} while (FALSE);
+
+	/* Reset the mask of the current process to All cpus */
+	gotoAllCpu();
+
+	MCDRV_DBG_VERBOSE("fcLog Logger version %u\n", mcLogBuf->version);
+}
+#endif /* #ifdef MC_MEM_TRACES */
+
+
+/*----------------------------------------------------------------------------*/
+/* check if caller is MobiCore Daemon */
+static unsigned int isCallerMcDaemon(
+	struct mcInstance *pInstance
+)
+{
+	return ((NULL != pInstance)
+		&& (mcDrvKModCtx.daemonInst == pInstance));
+}
+
+
+/*----------------------------------------------------------------------------*/
+static struct mcInstance *getInstance(
+	struct file *pFile
+) {
+	MCDRV_ASSERT(NULL != pFile);
+
+	return (struct mcInstance *)(pFile->private_data);
+}
+
+
+/*----------------------------------------------------------------------------*/
+/* get a unique ID */
+static unsigned int getMcKModUniqueId(
+	void
+)
+{
+	return (unsigned int)atomic_inc_return(
+			   &(mcDrvKModCtx.uniqueCounter));
+}
+
+
+/*----------------------------------------------------------------------------*/
+/* get a unique ID */
+static struct l2Table *getL2TableKernelVirt(
+	struct mcL2TablesDescr	*pDescr
+)
+{
+	MCDRV_ASSERT(NULL != pDescr);
+	MCDRV_ASSERT(NULL != pDescr->pChunk);
+	MCDRV_ASSERT(NULL != pDescr->pChunk->kernelVirt);
+	return &(pDescr->pChunk->kernelVirt->table[pDescr->idx]);
+}
+
+/*----------------------------------------------------------------------------*/
+/* get a unique ID */
+static struct l2Table *getL2TablePhys(
+	struct mcL2TablesDescr  *pDescr
+)
+{
+	MCDRV_ASSERT(NULL != pDescr);
+	MCDRV_ASSERT(NULL != pDescr->pChunk);
+	MCDRV_ASSERT(NULL != pDescr->pChunk->phys);
+	return &(pDescr->pChunk->phys->table[pDescr->idx]);
+}
+
+/*----------------------------------------------------------------------------*/
+/* get a unique ID */
+static unsigned int isWsmL2InUse(
+	struct mcL2TablesDescr	*pWsmL2Descr
+)
+{
+	return (0 != (pWsmL2Descr->flags &
+			  (MC_WSM_L2_CONTAINER_WSM_LOCKED_BY_APP
+			   | MC_WSM_L2_CONTAINER_WSM_LOCKED_BY_MC)));
+}
+
+
+
+/*----------------------------------------------------------------------------*/
+static struct mcL2TablesDescr *findWsmL2ByHandle(
+	unsigned int	handle
+) {
+	struct mcL2TablesDescr  *pTmpDescr;
+	struct mcL2TablesDescr  *pWsmL2TableDescr = NULL;
+
+	list_for_each_entry(
+		pTmpDescr,
+		&(mcDrvKModCtx.wsmL2Descriptors),
+		list
+	) {
+		if (handle == pTmpDescr->handle) {
+			pWsmL2TableDescr = pTmpDescr;
+			break;
+		}
+	}
+
+	return pWsmL2TableDescr;
+}
+
+/*
+#############################################################################
+##
+## L2 Table Pool
+##
+#############################################################################*/
+
+/*----------------------------------------------------------------------------*/
+static struct mcL2TablesDescr *allocateWsmL2TableContainer(
+	struct mcInstance	*pInstance
+) {
+	int			ret = 0;
+	struct mcL2TablesChunk	*pWsmL2TablesChunk = NULL;
+	struct mcL2Page		*pWsmL2Page = NULL;
+	struct mcL2TablesDescr  *pWsmL2TableDescr = NULL;
+	struct page		*pPage;
+	unsigned int		i = 0;
+
+	do {
+		/* allocate a WSM L2 descriptor */
+		pWsmL2TableDescr  = kmalloc(sizeof(*pWsmL2TableDescr),
+						GFP_KERNEL);
+		if (NULL == pWsmL2TableDescr) {
+			ret = -ENOMEM;
+			MCDRV_DBG_ERROR("out of memory\n");
+			break;
+		}
+		/* clean */
+		memset(pWsmL2TableDescr, 0, sizeof(*pWsmL2TableDescr));
+		pWsmL2TableDescr->handle	= getMcKModUniqueId();
+		pWsmL2TableDescr->pInstance = pInstance;
+
+		/* add to global list. */
+		initAndAddToList(
+			&(pWsmL2TableDescr->list),
+			&(mcDrvKModCtx.wsmL2Descriptors));
+
+		/* walk though list to find free chunk. */
+		list_for_each_entry(
+			pWsmL2TablesChunk,
+			&(mcDrvKModCtx.wsmL2Chunks),
+			list
+		) {
+			for (i = 0; i < MC_DRV_KMOD_L2_TABLE_PER_PAGES; i++) {
+				if (0 ==
+					(pWsmL2TablesChunk->usageBitmap
+					& (1U << i))
+				) {
+					/* found a chunk,
+						pL2TablesChunk and i are set. */
+					pWsmL2Page =
+						pWsmL2TablesChunk->kernelVirt;
+					break;
+				}
+			}
+			if (NULL != pWsmL2Page)
+				break;
+		} /* end while */
+
+		if (NULL == pWsmL2Page) {
+			pWsmL2Page =
+				(struct mcL2Page *)get_zeroed_page(GFP_KERNEL);
+			if (NULL == pWsmL2Page) {
+				ret = -ENOMEM;
+				break;
+			}
+
+			/* Actually, locking is not necessary, because kernel
+				memory is not supposed to get swapped out. But
+				we play safe.... */
+			pPage = virt_to_page(pWsmL2Page);
+			SetPageReserved(pPage);
+
+			/* allocate a descriptor */
+			pWsmL2TablesChunk = kmalloc(sizeof(*pWsmL2TablesChunk),
+							GFP_KERNEL);
+			if (NULL == pWsmL2TablesChunk) {
+				kfree(pWsmL2Page);
+				ret = -ENOMEM;
+				break;
+			}
+			/* initialize */
+			memset(pWsmL2TablesChunk, 0,
+				   sizeof(*pWsmL2TablesChunk));
+
+			pWsmL2TablesChunk->kernelVirt	= pWsmL2Page;
+			pWsmL2TablesChunk->pPage = pPage;
+			pWsmL2TablesChunk->phys =
+					(void *)virt_to_phys(pWsmL2Page);
+
+			/* init add to list. */
+			initAndAddToList(
+				&(pWsmL2TablesChunk->list),
+				&(mcDrvKModCtx.wsmL2Chunks));
+
+			/* use first table */
+			i = 0;
+		}
+
+		/* set chunk usage */
+		pWsmL2TablesChunk->usageBitmap |= (1U << i);
+
+
+		/* set chunk reference */
+		pWsmL2TableDescr->pChunk	= pWsmL2TablesChunk;
+		pWsmL2TableDescr->idx	   = i;
+
+		MCDRV_DBG_VERBOSE(
+			"allocateWsmL2TableContainer():chunkPhys=%p,idx=%d\n",
+			pWsmL2TablesChunk->phys, i);
+
+	} while (FALSE);
+
+	if (0 != ret) {
+		if (NULL != pWsmL2TableDescr) {
+			/* remove from list */
+			list_del(&(pWsmL2TablesChunk->list));
+			/* free memory */
+			kfree(pWsmL2TableDescr);
+			pWsmL2TableDescr = NULL;
+		}
+	}
+
+	return pWsmL2TableDescr;
+}
+
+/*----------------------------------------------------------------------------*/
+static void freeWsmL2TableContainer(
+	struct mcL2TablesDescr *pL2TableDescr
+)
+{
+	struct mcL2TablesChunk	*pWsmL2TablesChunk;
+	unsigned int		idx;
+
+	MCDRV_ASSERT(NULL != pL2TableDescr);
+
+	pWsmL2TablesChunk = pL2TableDescr->pChunk;
+	MCDRV_ASSERT(NULL != pWsmL2TablesChunk);
+
+	/* clean usage flag */
+	idx = pL2TableDescr->idx;
+	MCDRV_ASSERT(MC_DRV_KMOD_L2_TABLE_PER_PAGES > idx);
+	pWsmL2TablesChunk->usageBitmap &= ~(1U << idx);
+
+	/* if nobody uses this chunk, we can release it. */
+	if (0 == pWsmL2TablesChunk->usageBitmap) {
+		MCDRV_ASSERT(NULL != pWsmL2TablesChunk->pPage);
+		ClearPageReserved(pWsmL2TablesChunk->pPage);
+
+		MCDRV_ASSERT(NULL != pWsmL2TablesChunk->kernelVirt);
+		free_page((unsigned long)pWsmL2TablesChunk->kernelVirt);
+
+		/* remove from list */
+		list_del(&(pWsmL2TablesChunk->list));
+
+		/* free memory */
+		kfree(pWsmL2TablesChunk);
+	}
+
+	return;
+}
+
+
+
+/*----------------------------------------------------------------------------*/
+/**
+ * Create a L2 table in a WSM container that has been allocates previously.
+ *
+ * @param pTask		  pointer to task owning WSM
+ * @param wsmBuffer	  user space WSM start
+ * @param wsmLen		 WSM length
+ * @param pL2TableDescr  Pointer to L2 table details
+ */
+static int createWsmL2Table(
+	struct task_struct	*pTask,
+	void			*wsmBuffer,
+	unsigned int		wsmLen,
+	struct mcL2TablesDescr	*pL2TableDescr
+)
+{
+	int		ret = 0;
+	unsigned int	i, nrOfPages;
+	void		*virtAddrPage;
+	struct page	*pPage;
+	struct l2Table	*pL2Table;
+	struct page	**pL2TableAsArrayOfPointersToPage;
+
+	/* pTask can be null when called from kernel space
+	MCDRV_ASSERT(NULL != pTask); */
+	MCDRV_ASSERT(NULL != wsmBuffer);
+	MCDRV_ASSERT(0 != wsmLen);
+	MCDRV_ASSERT(NULL != pL2TableDescr);
+
+	MCDRV_DBG_VERBOSE("WSM addr=0x%p, len=0x%08x\n", wsmBuffer, wsmLen);
+
+	/* Check if called from kernel space wsmBuffer is actually
+	 * vmalloced or not */
+	if (pTask == NULL && !is_vmalloc_addr(wsmBuffer)) {
+		MCDRV_DBG_ERROR("WSM addr is not a vmalloc address");
+		return -EINVAL;
+	}
+
+	pL2Table = getL2TableKernelVirt(pL2TableDescr);
+	/* We use the memory for the L2 table to hold the pointer
+	and convert them later. This works, as everything comes
+	down to a 32 bit value. */
+	pL2TableAsArrayOfPointersToPage = (struct page **)pL2Table;
+
+	do {
+
+		/* no size > 1Mib supported */
+		if (wsmLen > SZ_1M) {
+			MCDRV_DBG_ERROR("size > 1 MiB\n");
+			ret = -EINVAL;
+			break;
+		}
+
+		/* calculate page usage */
+		virtAddrPage = getPageStart(wsmBuffer);
+		nrOfPages  = getNrOfPagesForBuffer(wsmBuffer, wsmLen);
+
+
+		MCDRV_DBG_VERBOSE("virtAddr pageStart=0x%p,pages=%d\n",
+				  virtAddrPage,
+				  nrOfPages);
+
+		/* L2 table can hold max 1MiB in 256 pages. */
+		if (SZ_1M < (nrOfPages*PAGE_SIZE)) {
+			MCDRV_DBG_ERROR("WSM paged exceed 1 MiB\n");
+			ret = -EINVAL;
+			break;
+		}
+
+		/* Request comes from user space */
+		if (pTask != NULL) {
+			/* lock user page in memory, so they do not get swapped
+			* out.
+			* REV axh:
+			* Kernel 2.6.27 added a new get_user_pages_fast()
+			* function, maybe it is called fast_gup() in some
+			* versions.
+			* handle user process doing a fork().
+			* Child should not get things.
+			* http://osdir.com/ml/linux-media/2009-07/msg00813.html
+			* http://lwn.net/Articles/275808/ */
+
+			ret = lockUserPages(
+					  pTask,
+					  virtAddrPage,
+					  nrOfPages,
+					  pL2TableAsArrayOfPointersToPage);
+			if (0 != ret) {
+				MCDRV_DBG_ERROR("lockUserPages() failed\n");
+				break;
+			}
+		}
+		/* Request comes from kernel space(vmalloc buffer) */
+		else {
+			void *uaddr = wsmBuffer;
+			for (i = 0; i < nrOfPages; i++) {
+				pPage = vmalloc_to_page(uaddr);
+				if (!pPage) {
+					MCDRV_DBG_ERROR(
+						"vmalloc_to_Page()"
+						" failed to map address\n");
+					ret = -EINVAL;
+					break;
+				}
+				get_page(pPage);
+				/* Lock the page in memory, it can't be swapped
+				 * out */
+				SetPageReserved(pPage);
+				pL2TableAsArrayOfPointersToPage[i] = pPage;
+				uaddr += PAGE_SIZE;
+			}
+		}
+
+		pL2TableDescr->nrOfPages = nrOfPages;
+		pL2TableDescr->flags |= MC_WSM_L2_CONTAINER_WSM_LOCKED_BY_APP;
+
+		/* create L2 Table entries. "pL2Page->table" contains a list of
+		page pointers here. For a proper cleanup we have to ensure that
+		the following code either works and "pL2table" contains a valid
+		L2 table - or fails and "pL2Page->table" contains the list of
+		page pointers. Any mixed contents will make cleanup difficult.*/
+
+		for (i = 0; i < nrOfPages; i++) {
+			pte_t pte;
+			pPage = pL2TableAsArrayOfPointersToPage[i];
+
+			/* create L2 table entry, see ARM MMU docu for details
+			about flags stored in the lowest 12 bits. As a side
+			reference, the Article "ARM's multiply-mapped memory
+			mess" found in the collection at at
+			http://lwn.net/Articles/409032/ is also worth reading.*/
+			pte = pageToL2Pte(pPage)
+					| L2_FLAG_AP1 | L2_FLAG_AP0
+					| L2_FLAG_C | L2_FLAG_B
+					| L2_FLAG_SMALL | L2_FLAG_SMALL_XN
+			/* Linux uses different mappings for SMP systems(the
+			 * sharing flag is set for the pte. In order not to
+			 * confuse things too much in Mobicore make sure the
+			 * shared buffers have the same flags.
+			 * This should also be done in SWD side
+			 */
+#ifdef CONFIG_SMP
+					| L2_FLAG_S | L2_FLAG_SMALL_TEX0
+#endif
+				  ;
+
+			pL2Table->tableEntries[i] = pte;
+			MCDRV_DBG_VERBOSE("L2 entry %d:  0x%08x\n", i,
+					  (unsigned int)(pte));
+		}
+
+		/* ensure rest of table is empty */
+		while (i < 255)
+			pL2Table->tableEntries[i++] = (pte_t)0;
+
+	} while (FALSE);
+
+	return ret;
+}
+
+
+/*----------------------------------------------------------------------------*/
+/**
+ * Remove a L2 table in a WSM container. Afterwards the container may be
+ * released.
+ *
+ * @param pL2TableDescr	Pointer to L2 table details
+ */
+
+static void destroyWsmL2Table(
+	struct mcL2TablesDescr	*pL2TableDescr
+)
+{
+	unsigned int	i;
+	struct l2Table	*pL2Table;
+
+	MCDRV_ASSERT(NULL != pL2TableDescr);
+	/* this should not happen, as we have no empty tables. */
+	MCDRV_ASSERT(!isWsmL2InUse(pL2TableDescr));
+
+	/* found the table, now release the resources. */
+	MCDRV_DBG_VERBOSE("clear L2 table, physBase=%p, nrOfPages=%d\n",
+			  getL2TablePhys(pL2TableDescr),
+			  pL2TableDescr->nrOfPages);
+
+	pL2Table = getL2TableKernelVirt(pL2TableDescr);
+
+	/* release all locked user space pages */
+	for (i = 0; i < pL2TableDescr->nrOfPages; i++) {
+		/* convert physical entries from L2 table to page pointers */
+		pte_t pte =
+			getL2TableKernelVirt(pL2TableDescr)->tableEntries[i];
+		struct page *pPage = l2PteToPage(pte);
+		unlockPagefromWsmL2Table(pPage);
+	}
+
+	/* remember that all pages have been freed */
+	pL2TableDescr->nrOfPages = 0;
+
+	return;
+}
+
+
+/*
+#############################################################################
+##
+## Helper functions
+##
+#############################################################################*/
+/*----------------------------------------------------------------------------*/
+#define FREE_FROM_SWD	TRUE
+#define FREE_FROM_NWD	FALSE
+static void freeWsmL2Table(
+	struct mcL2TablesDescr	*pWsmL2TableDescr,
+	unsigned int		isSwd
+)
+{
+	if (isSwd) {
+		pWsmL2TableDescr->flags &=
+			~MC_WSM_L2_CONTAINER_WSM_LOCKED_BY_MC;
+	} else {
+		pWsmL2TableDescr->flags &=
+			~MC_WSM_L2_CONTAINER_WSM_LOCKED_BY_APP;
+		pWsmL2TableDescr->pInstance = NULL;
+	}
+
+	/* release if Nwd and Swd/MC do no longer use it. */
+	if (isWsmL2InUse(pWsmL2TableDescr)) {
+		MCDRV_DBG_WARN(
+			"WSM L2 table still in use: physBase=%p, "
+			"nrOfPages=%d\n",
+			getL2TablePhys(pWsmL2TableDescr),
+			pWsmL2TableDescr->nrOfPages);
+	} else {
+		destroyWsmL2Table(pWsmL2TableDescr);
+		freeWsmL2TableContainer(pWsmL2TableDescr);
+
+		list_del(&(pWsmL2TableDescr->list));
+
+		kfree(pWsmL2TableDescr);
+	}
+	return;
+}
+
+/*----------------------------------------------------------------------------*/
+/** Allocate L2 table and map buffer into it. That is, create respective table
+	entries must hold Semaphore mcDrvKModCtx.wsmL2Sem */
+static struct mcL2TablesDescr *newWsmL2Table(
+	struct mcInstance	*pInstance,
+	struct task_struct	*pTask,
+	void			*wsmBuffer,
+	unsigned int		wsmLen
+) {
+	int			ret = 0;
+	struct mcL2TablesDescr	*pL2TableDescr;
+
+	do {
+		pL2TableDescr = allocateWsmL2TableContainer(pInstance);
+		if (NULL == pL2TableDescr) {
+			MCDRV_DBG_ERROR(
+				"allocateWsmL2TableContainer() failed\n");
+			break;
+		}
+
+		/* create the L2 page for the WSM */
+		ret = createWsmL2Table(
+				  pTask,
+				  wsmBuffer,
+				  wsmLen,
+				  pL2TableDescr);
+		if (0 != ret) {
+			MCDRV_DBG_ERROR("createWsmL2Table() failed\n");
+			freeWsmL2Table(pL2TableDescr, FREE_FROM_NWD);
+			pL2TableDescr = NULL;
+			break;
+		}
+
+	} while (FALSE);
+
+
+	return pL2TableDescr;
+}
+
+/*
+#############################################################################
+##
+## IoCtl handler
+##
+#############################################################################*/
+
+/**
+ * Map a virtual memory buffer structure to Mobicore
+ * @param pInstance
+ * @param addr		address of the buffer(NB it must be kernel virtual!)
+ * @param len		buffer length
+ * @param pHandle	pointer to handle
+ * @param physWsmL2Table	pointer to physical L2 table(?)
+ *
+ * @return 0 if no error
+ *
+ */
+/*----------------------------------------------------------------------------*/
+int mobicore_map_vmem(
+	struct mcInstance	*pInstance,
+	void			*addr,
+	uint32_t		len,
+	uint32_t		*pHandle,
+	void			**physWsmL2Table
+)
+{
+	int ret = 0;
+	struct mcL2TablesDescr *pWsmL2TableDescr = NULL;
+	MCDRV_ASSERT(NULL != pInstance);
+
+	MCDRV_DBG_VERBOSE("enter\n");
+
+	do {
+		if (0 == len) {
+			MCDRV_DBG_ERROR("len=0 is not supported!\n");
+			ret = -EINVAL;
+			break;
+		}
+
+		/* try to get the semaphore */
+		ret = down_interruptible(&(mcDrvKModCtx.wsmL2Sem));
+		if (0 != ret) {
+			MCDRV_DBG_ERROR("down_interruptible() failed with %d\n",
+					ret);
+			ret = -ERESTARTSYS;
+			break;
+		}
+
+		do {
+			pWsmL2TableDescr = newWsmL2Table(
+						   pInstance,
+						   NULL,
+						   addr,
+						   len);
+
+			if (NULL == pWsmL2TableDescr) {
+				MCDRV_DBG_ERROR("newWsmL2Table() failed\n");
+				ret = -EINVAL;
+				break;
+			}
+
+			/* set response */
+			*pHandle = pWsmL2TableDescr->handle;
+			*physWsmL2Table =
+				(void *)getL2TablePhys(pWsmL2TableDescr);
+			MCDRV_DBG_VERBOSE("handle: %d, phys=%p\n",
+					  *pHandle,
+					  (void *)(*physWsmL2Table));
+
+		} while (FALSE);
+
+		/* release semaphore */
+		up(&(mcDrvKModCtx.wsmL2Sem));
+
+	} while (FALSE);
+
+	MCDRV_DBG_VERBOSE("exit with %d/0x%08X\n", ret, ret);
+
+	return ret;
+}
+EXPORT_SYMBOL(mobicore_map_vmem);
+/*----------------------------------------------------------------------------*/
+/**
+ *
+ * @param pInstance
+ * @param arg
+ *
+ * @return 0 if no error
+ *
+ */
+static int handleIoCtlAppRegisterWsmL2(
+	struct mcInstance		*pInstance,
+	union mcIoCtlAppRegWsmL2Params	*pUserParams
+)
+{
+	int				ret = 0;
+	union mcIoCtlAppRegWsmL2Params	params;
+	struct mcL2TablesDescr		*pWsmL2TableDescr = NULL;
+	struct pid			*pPidStruct = NULL;
+	struct task_struct		*pTask = current;
+	MCDRV_ASSERT(NULL != pInstance);
+
+	MCDRV_DBG_VERBOSE("enter\n");
+
+	do {
+		/* get use parameters */
+		ret = copy_from_user(
+				  &(params.in),
+				  &(pUserParams->in),
+				  sizeof(params.in));
+		if (0 != ret) {
+			MCDRV_DBG_ERROR("copy_from_user() failed\n");
+			break;
+		}
+
+		/* daemon can do this for another task. */
+		if (0 != params.in.pid) {
+			MCDRV_DBG_ERROR("pid != 0 unsupported\n");
+			ret = -EINVAL;
+			break;
+			/*
+			MCDRV_DBG("PID=%d\n", params.in.pid);
+			if (isCallerMcDaemon(pInstance))
+			{
+				MCDRV_DBG_ERROR(
+				"pid != 0 only allowed fore daemon\n");
+				ret = -EFAULT;
+				break;
+			}
+
+			Don't use find_vpid(), as this requires holding some
+			locks. Better user find_get_pid(), which is take care of
+			the locks internally.
+			pPidStruct = find_get_pid(params.in.pid);
+			if (NULL != pPidStruct)
+			{
+				MCDRV_DBG_ERROR("find_get_pid() failed\n");
+				ret = -EFAULT;
+				break;
+			}
+			now we have a unique reference to another task. We must
+			release this reference using put_pid() when we are done
+			pTask = pid_task(pPidStruct, PIDTYPE_PID);
+			if (NULL != pTask)
+			{
+				MCDRV_DBG_ERROR("pid_task() failed\n");
+				ret = -EFAULT;
+				break;
+			}
+			*/
+		}
+		if (0 == params.in.len) {
+			MCDRV_DBG_ERROR("len=0 is not supported!\n");
+			ret = -EINVAL;
+			break;
+		}
+
+		/* try to get the semaphore */
+		ret = down_interruptible(&(mcDrvKModCtx.wsmL2Sem));
+		if (0 != ret) {
+			MCDRV_DBG_ERROR("down_interruptible() failed with %d\n",
+					ret);
+			ret = -ERESTARTSYS;
+			break;
+		}
+
+		do {
+			pWsmL2TableDescr = newWsmL2Table(
+						   pInstance,
+						   pTask,
+						   (void *)(params.in.buffer),
+						   params.in.len);
+
+			if (NULL == pWsmL2TableDescr) {
+				MCDRV_DBG_ERROR("newWsmL2Table() failed\n");
+				ret = -EINVAL;
+				break;
+			}
+
+			/* if the daemon does this, we set the MC lock */
+			if (isCallerMcDaemon(pInstance))
+				pWsmL2TableDescr->flags |=
+					MC_WSM_L2_CONTAINER_WSM_LOCKED_BY_MC;
+
+			/* set response */
+			memset(&params.out, 0, sizeof(params.out));
+			params.out.handle = pWsmL2TableDescr->handle;
+			/* TODO: return the physical address for daemon only,
+				otherwise set NULL */
+			/* if (isCallerMcDaemon(pInstance))... */
+			params.out.physWsmL2Table =
+				(uint32_t)getL2TablePhys(pWsmL2TableDescr);
+
+			MCDRV_DBG_VERBOSE("handle: %d, phys=%p\n",
+					  params.out.handle,
+					  (void *)(params.out.physWsmL2Table));
+
+
+			/* copy L2Table to user space */
+			ret = copy_to_user(
+					  &(pUserParams->out),
+					  &(params.out),
+					  sizeof(params.out));
+			if (0 != ret) {
+				MCDRV_DBG_ERROR("copy_to_user() failed\n");
+
+				/* free the table again, as app does not know
+					about anything. */
+				if (isCallerMcDaemon(pInstance)) {
+					pWsmL2TableDescr->flags &=
+					~MC_WSM_L2_CONTAINER_WSM_LOCKED_BY_MC;
+				}
+				freeWsmL2Table(pWsmL2TableDescr, FREE_FROM_NWD);
+				pWsmL2TableDescr = NULL;
+				break;
+			}
+
+		} while (FALSE);
+
+		/* release semaphore */
+		up(&(mcDrvKModCtx.wsmL2Sem));
+
+	} while (FALSE);
+
+
+
+	/* release PID struct reference */
+	if (NULL != pPidStruct)
+		put_pid(pPidStruct);
+
+
+	MCDRV_DBG_VERBOSE("exit with %d/0x%08X\n", ret, ret);
+
+	return ret;
+}
+
+
+/*----------------------------------------------------------------------------*/
+/**
+ * Unmap a virtual memory buffer from mobicore
+ * @param pInstance
+ * @param handle
+ *
+ * @return 0 if no error
+ *
+ */
+int mobicore_unmap_vmem(
+	struct mcInstance	*pInstance,
+	uint32_t		handle
+)
+{
+	int ret = 0;
+	struct mcL2TablesDescr *pWsmL2TableDescr = NULL;
+
+	MCDRV_ASSERT(NULL != pInstance);
+	MCDRV_DBG_VERBOSE("enter\n");
+
+	do {
+		/* try to get the semaphore */
+		ret = down_interruptible(&(mcDrvKModCtx.wsmL2Sem));
+		if (0 != ret) {
+			MCDRV_DBG_ERROR("processOpenSession() failed with %d\n",
+					ret);
+			ret = -ERESTARTSYS;
+			break;
+		}
+
+		do {
+			pWsmL2TableDescr = findWsmL2ByHandle(handle);
+			if (NULL == pWsmL2TableDescr) {
+				ret = -EINVAL;
+				MCDRV_DBG_ERROR("entry not found\n");
+				break;
+			}
+
+			if (pInstance != pWsmL2TableDescr->pInstance) {
+				ret = -EINVAL;
+				MCDRV_DBG_ERROR("instance does no own it\n");
+				break;
+			}
+
+			/* free table (if no further locks exist) */
+			freeWsmL2Table(pWsmL2TableDescr, FREE_FROM_NWD);
+			pWsmL2TableDescr = NULL;
+			/* there are no out parameters */
+		} while (FALSE);
+		/* release semaphore */
+		up(&(mcDrvKModCtx.wsmL2Sem));
+
+	} while (FALSE);
+
+	MCDRV_DBG_VERBOSE("exit with %d/0x%08X\n", ret, ret);
+
+	return ret;
+}
+EXPORT_SYMBOL(mobicore_unmap_vmem);
+/*----------------------------------------------------------------------------*/
+/**
+ *
+ * @param pInstance
+ * @param arg
+ *
+ * @return 0 if no error
+ *
+ */
+static int handleIoCtlAppUnregisterWsmL2(
+	struct mcInstance			*pInstance,
+	struct mcIoCtlAppUnregWsmL2Params	*pUserParams
+)
+{
+	int					ret = 0;
+	struct mcIoCtlAppUnregWsmL2Params	params;
+	struct mcL2TablesDescr			*pWsmL2TableDescr = NULL;
+
+	MCDRV_ASSERT(NULL != pInstance);
+	MCDRV_DBG_VERBOSE("enter\n");
+
+	do {
+		ret = copy_from_user(
+				  &(params.in),
+				  &(pUserParams->in),
+				  sizeof(params.in));
+
+		if (0 != ret) {
+			MCDRV_DBG_ERROR("copy_from_user\n");
+			break;
+		}
+
+		/* try to get the semaphore */
+		ret = down_interruptible(&(mcDrvKModCtx.wsmL2Sem));
+		if (0 != ret) {
+			MCDRV_DBG_ERROR("down_interruptible() failed with %d\n",
+					ret);
+			ret = -ERESTARTSYS;
+			break;
+		}
+
+		do {
+			/* daemon can do this for another task. */
+			if (0 != params.in.pid) {
+				MCDRV_DBG_ERROR("pid != 0 unsupported\n");
+				ret = -EINVAL;
+				break;
+			}
+
+			pWsmL2TableDescr = findWsmL2ByHandle(params.in.handle);
+			if (NULL == pWsmL2TableDescr) {
+				ret = -EINVAL;
+				MCDRV_DBG_ERROR("entry not found\n");
+				break;
+			}
+
+			if (isCallerMcDaemon(pInstance)) {
+				/* if daemon does this, we have to release the
+					MobiCore lock. */
+				pWsmL2TableDescr->flags &=
+					~MC_WSM_L2_CONTAINER_WSM_LOCKED_BY_MC;
+			} else if (pInstance != pWsmL2TableDescr->pInstance) {
+				ret = -EINVAL;
+				MCDRV_DBG_ERROR("instance does no own it\n");
+				break;
+			}
+
+			/* free table (if no further locks exist) */
+			freeWsmL2Table(pWsmL2TableDescr, FREE_FROM_NWD);
+			pWsmL2TableDescr = NULL;
+
+			/* there are no out parameters */
+
+		} while (FALSE);
+
+		/* release semaphore */
+		up(&(mcDrvKModCtx.wsmL2Sem));
+
+	} while (FALSE);
+
+	MCDRV_DBG_VERBOSE("exit with %d/0x%08X\n", ret, ret);
+
+	return ret;
+}
+
+
+/*----------------------------------------------------------------------------*/
+static int handleIoCtlDaemonLockWsmL2(
+	struct mcInstance			*pInstance,
+	struct mcIoCtlDaemonLockWsmL2Params	*pUserParams
+)
+{
+	int					ret = 0;
+	struct mcIoCtlDaemonLockWsmL2Params	params;
+	struct mcL2TablesDescr			*pWsmL2TableDescr = NULL;
+
+	MCDRV_ASSERT(NULL != pInstance);
+	MCDRV_DBG_VERBOSE("enter\n");
+
+	do {
+		if (!isCallerMcDaemon(pInstance)) {
+			MCDRV_DBG_ERROR("caller not MobiCore Daemon\n");
+			ret = -EFAULT;
+			break;
+		}
+
+		ret = copy_from_user(
+				  &(params.in),
+				  &(pUserParams->in),
+				  sizeof(params.in));
+
+		if (0 != ret) {
+			MCDRV_DBG_ERROR("copy_from_user\n");
+			break;
+		}
+		/* try to get the semaphore */
+		ret = down_interruptible(&(mcDrvKModCtx.wsmL2Sem));
+		if (0 != ret) {
+			MCDRV_DBG_ERROR("down_interruptible() failed with %d\n",
+					ret);
+			ret = -ERESTARTSYS;
+			break;
+		}
+
+		do {
+			pWsmL2TableDescr = findWsmL2ByHandle(params.in.handle);
+			if (NULL == pWsmL2TableDescr) {
+				ret = -EINVAL;
+				MCDRV_DBG_ERROR("entry not found\n");
+				break;
+			}
+			if (pInstance != pWsmL2TableDescr->pInstance) {
+				ret = -EINVAL;
+				MCDRV_DBG_ERROR("instance does no own it\n");
+				break;
+			}
+
+			/* lock entry */
+			if (0 != (pWsmL2TableDescr->flags &
+				  MC_WSM_L2_CONTAINER_WSM_LOCKED_BY_MC)) {
+				MCDRV_DBG_WARN("entry already locked\n");
+			}
+			pWsmL2TableDescr->flags |=
+				MC_WSM_L2_CONTAINER_WSM_LOCKED_BY_MC;
+
+			/* prepare response */
+			memset(&(params.out), 0, sizeof(params.out));
+			params.out.physWsmL2Table =
+				(uint32_t)getL2TablePhys(pWsmL2TableDescr);
+
+			/* copy to user space */
+			ret = copy_to_user(
+					  &(pUserParams->out),
+					  &(params.out),
+					  sizeof(params.out));
+			if (0 != ret) {
+				MCDRV_DBG_ERROR("copy_to_user() failed\n");
+
+				/* undo, as userspace did not get it. */
+				pWsmL2TableDescr->flags |=
+					MC_WSM_L2_CONTAINER_WSM_LOCKED_BY_MC;
+				break;
+			}
+
+		} while (FALSE);
+
+		/* release semaphore */
+		up(&(mcDrvKModCtx.wsmL2Sem));
+
+	} while (FALSE);
+
+	MCDRV_DBG_VERBOSE("exit with %d/0x%08X\n", ret, ret);
+
+	return ret;
+}
+
+
+/*----------------------------------------------------------------------------*/
+static int handleIoCtlDaemonUnlockWsmL2(
+	struct mcInstance			*pInstance,
+	struct mcIoCtlDaemonUnlockWsmL2Params	*pUserParams
+)
+{
+	int					ret = 0;
+	struct mcIoCtlDaemonUnlockWsmL2Params	params;
+	struct mcL2TablesDescr			*pWsmL2TableDescr = NULL;
+
+	MCDRV_ASSERT(NULL != pInstance);
+	MCDRV_DBG_VERBOSE("enter\n");
+
+	do {
+		if (!isCallerMcDaemon(pInstance)) {
+			MCDRV_DBG_ERROR("caller not MobiCore Daemon\n");
+			ret = -EFAULT;
+			break;
+		}
+
+		ret = copy_from_user(
+				  &(params.in),
+				  &(pUserParams->in),
+				  sizeof(params.in));
+
+		if (0 != ret) {
+			MCDRV_DBG_ERROR("copy_from_user\n");
+			break;
+		}
+		/* try to get the semaphore */
+		ret = down_interruptible(&(mcDrvKModCtx.wsmL2Sem));
+		if (0 != ret) {
+			MCDRV_DBG_ERROR("down_interruptible() failed with %d\n",
+						ret);
+			ret = -ERESTARTSYS;
+			break;
+		}
+
+		do {
+			pWsmL2TableDescr = findWsmL2ByHandle(params.in.handle);
+			if (NULL == pWsmL2TableDescr) {
+				ret = -EINVAL;
+				MCDRV_DBG_ERROR("entry not found\n");
+				break;
+			}
+			if (pInstance != pWsmL2TableDescr->pInstance) {
+				ret = -EINVAL;
+				MCDRV_DBG_ERROR("instance does no own it\n");
+				break;
+			}
+
+			/* lock entry */
+			if (0 == (pWsmL2TableDescr->flags &
+				  MC_WSM_L2_CONTAINER_WSM_LOCKED_BY_MC)) {
+				MCDRV_DBG_WARN("entry is not locked locked\n");
+			}
+
+			/* free table (if no further locks exist) */
+			freeWsmL2Table(pWsmL2TableDescr, FREE_FROM_SWD);
+			pWsmL2TableDescr = NULL;
+
+			/* there are no out parameters */
+
+		} while (FALSE);
+
+	} while (FALSE);
+
+
+	MCDRV_DBG_VERBOSE("exit with %d/0x%08X\n", ret, ret);
+
+	return ret;
+}
+
+/*----------------------------------------------------------------------------*/
+static inline void freeContinguousPages(
+	void		*addr,
+	unsigned int	size
+)
+{
+	/* clears the reserved bit of each page and frees this page */
+	struct page *pPage = virt_to_page(addr);
+	int i;
+	for (i = 0; i < size; i++) {
+		MCDRV_DBG_VERBOSE("free page at 0x%p\n", pPage);
+		ClearPageReserved(pPage);
+		pPage++;
+	}
+	/* REV luh: see man kmalloc */
+	free_pages((unsigned long)addr, sizeToOrder(size));
+}
+
+/*----------------------------------------------------------------------------*/
+/**
+ * Free a WSM buffer allocated with mobicore_allocate_wsm
+ * @param pInstance
+ * @param handle		handle of the buffer
+ *
+ * @return 0 if no error
+ *
+ */
+int mobicore_free(
+	struct mcInstance	*pInstance,
+	uint32_t		handle
+)
+{
+	int			ret = 0;
+	struct mc_tuple		*pTuple;
+	unsigned int		i;
+
+	do {
+		/* search for the given address in the tuple list */
+		for (i = 0; i < MC_DRV_KMOD_TUPLE_NR; i++) {
+			pTuple = &(pInstance->tuple[i]);
+			if (pTuple->handle == handle)
+				break;
+		}
+		if (MC_DRV_KMOD_TUPLE_NR == i) {
+			MCDRV_DBG_ERROR("tuple not found\n");
+			ret = -EFAULT;
+			break;
+		}
+
+		MCDRV_DBG_VERBOSE("physAddr=0x%p, virtAddr=0x%p\n",
+				  pTuple->physAddr, pTuple->virtKernelAddr);
+
+		freeContinguousPages(pTuple->virtKernelAddr, pTuple->numPages);
+
+		memset(pTuple, 0, sizeof(*pTuple));
+
+		/* there are no out parameters */
+
+	} while (FALSE);
+
+
+	return ret;
+}
+EXPORT_SYMBOL(mobicore_free);
+/*----------------------------------------------------------------------------*/
+
+/**
+ *
+ * @param pInstance
+ * @param arg
+ *
+ * @return 0 if no error
+ *
+ */
+static int handleIoCtlFree(
+	struct mcInstance		*pInstance,
+	union mcIoCtltoFreeParams	*pUserParams
+)
+{
+	int				ret = 0;
+	union mcIoCtltoFreeParams	params;
+
+
+	MCDRV_ASSERT(NULL != pInstance);
+	MCDRV_DBG_VERBOSE("enter\n");
+
+	do {
+		ret = copy_from_user(
+				  &(params.in),
+				  &(pUserParams->in),
+				  sizeof(params.in));
+
+		if (0 != ret) {
+			MCDRV_DBG_ERROR("copy_from_user\n");
+			break;
+		}
+
+		/* daemon can do this for another task. */
+		if (0 != params.in.pid) {
+			MCDRV_DBG_ERROR("pid != 0 unsupported\n");
+			ret = -EINVAL;
+			break;
+		}
+
+		ret = mobicore_free(pInstance, params.in.handle);
+
+		/* there are no out parameters */
+
+	} while (FALSE);
+
+	MCDRV_DBG_VERBOSE("exit with %d/0x%08X\n", ret, ret);
+
+	return ret;
+
+}
+
+
+/*----------------------------------------------------------------------------*/
+/**
+ *
+ * @param pInstance
+ * @param arg
+ *
+ * @return 0 if no error
+ *
+ */
+static int handleIoCtlInfo(
+	struct mcInstance	*pInstance,
+	union mcIoCtlInfoParams	*pUserParams
+)
+{
+	int			ret = 0;
+	union mcIoCtlInfoParams	params;
+	union mcFcInfo		fcInfo;
+
+
+	MCDRV_ASSERT(NULL != pInstance);
+	MCDRV_DBG_VERBOSE("enter\n");
+
+	do {
+		/* only the MobiCore Daemon is allowed to call this function */
+		if (!isCallerMcDaemon(pInstance)) {
+			MCDRV_DBG_ERROR("caller not MobiCore Daemon\n");
+			ret = -EFAULT;
+			break;
+		}
+
+		ret = copy_from_user(
+				  &(params.in),
+				  &(pUserParams->in),
+				  sizeof(params.in));
+
+		if (0 != ret) {
+			MCDRV_DBG_ERROR("copy_from_user\n");
+			break;
+		}
+
+
+		memset(&fcInfo, 0, sizeof(fcInfo));
+		fcInfo.asIn.cmd	   = MC_FC_INFO;
+		fcInfo.asIn.extInfoId = params.in.extInfoId;
+
+		MCDRV_DBG(
+			"fcInfo in cmd=0x%08x, extInfoid=0x%08x "
+			"rfu=(0x%08x, 0x%08x)\n",
+			fcInfo.asIn.cmd,
+			fcInfo.asIn.extInfoId,
+			fcInfo.asIn.rfu[0],
+			fcInfo.asIn.rfu[1]);
+
+		mcFastCall(&(fcInfo.asGeneric));
+
+		MCDRV_DBG(
+			"fcInfo out resp=0x%08x, ret=0x%08x "
+			"state=0x%08x, extInfo=0x%08x\n",
+			fcInfo.asOut.resp,
+			fcInfo.asOut.ret,
+			fcInfo.asOut.state,
+			fcInfo.asOut.extInfo);
+
+		ret = convertFcRet(fcInfo.asOut.ret);
+		if (0 != ret)
+			break;
+
+		memset(&(params.out), 0, sizeof(params.out));
+		params.out.state  = fcInfo.asOut.state;
+		params.out.extInfo = fcInfo.asOut.extInfo;
+
+		ret = copy_to_user(
+				  &(pUserParams->out),
+				  &(params.out),
+				  sizeof(params.out));
+
+		if (0 != ret) {
+			MCDRV_DBG_ERROR("copy_to_user\n");
+			break;
+		}
+	} while (FALSE);
+
+	MCDRV_DBG_VERBOSE("exit with %d/0x%08X\n", ret, ret);
+
+	return ret;
+}
+
+/*----------------------------------------------------------------------------*/
+/**
+ *
+ * @param pInstance
+ * @param arg
+ *
+ * @return 0 if no error
+ *
+ */
+static int handleIoCtlYield(
+	struct mcInstance	*pInstance
+)
+{
+	int			ret = 0;
+	union mcFcSYield	fcSYield;
+
+	MCDRV_ASSERT(NULL != pInstance);
+
+	/* avoid putting debug output here, as we do this very often */
+	/* MCDRV_DBG("enter\n"); */
+
+	do {
+		/* only the MobiCore Daemon is allowed to call this function */
+		if (!isCallerMcDaemon(pInstance)) {
+			MCDRV_DBG_ERROR("caller not MobiCore Daemon\n");
+			ret = -EFAULT;
+			break;
+		}
+
+		memset(&fcSYield, 0, sizeof(fcSYield));
+		fcSYield.asIn.cmd = MC_SMC_N_YIELD;
+		mcFastCall(&(fcSYield.asGeneric));
+		ret = convertFcRet(fcSYield.asOut.ret);
+		if (0 != ret)
+			break;
+
+	} while (FALSE);
+
+	/* MCDRV_DBG("exit with %d/0x%08X\n", ret, ret); */
+
+	return ret;
+}
+
+/*----------------------------------------------------------------------------*/
+/**
+ * handle ioctl and call common notify
+ *
+ * @param pInstance
+ * @param arg
+ *
+ * @return 0 if no error
+ *
+ */
+static int handleIoCtlNSIQ(
+	struct mcInstance	*pInstance,
+	unsigned long		arg
+)
+{
+	int		ret = 0;
+
+	MCDRV_ASSERT(NULL != pInstance);
+
+	/* avoid putting debug output here, as we do this very often */
+	/* MCDRV_DBG("enter\n"); */
+	/* only the MobiCore Daemon is allowed to call this function */
+	if (!isCallerMcDaemon(pInstance)) {
+		MCDRV_DBG_ERROR("caller not MobiCore Daemon\n");
+		return -EFAULT;
+	}
+
+	do {
+		union mcFcNSIQ fcNSIQ;
+		memset(&fcNSIQ, 0, sizeof(fcNSIQ));
+		fcNSIQ.asIn.cmd = MC_SMC_N_SIQ;
+		mcFastCall(&(fcNSIQ.asGeneric));
+		ret = convertFcRet(fcNSIQ.asOut.ret);
+		if (0 != ret)
+			break;
+	} while (FALSE);
+
+	/* MCDRV_DBG("exit with %d/0x%08X\n", ret, ret); */
+
+	return ret;
+}
+
+/*----------------------------------------------------------------------------*/
+/**
+ *
+ * @param pInstance
+ * @param arg
+ *
+ * @return 0 if no error
+ *
+ */
+static int handleIoCtlDumpStatus(
+	struct mcInstance	*pInstance,
+	unsigned long		arg
+)
+{
+	int		ret = 0;
+	int		i = 0;
+	union mcFcInfo	fcInfo;
+
+	MCDRV_ASSERT(NULL != pInstance);
+	MCDRV_DBG_VERBOSE("enter\n");
+
+	do {
+		/* anybody with root access can do this. */
+		if (!isUserlandCallerPrivileged()) {
+			MCDRV_DBG_ERROR("caller must have root privileges\n");
+			ret = -EFAULT;
+			break;
+		}
+
+		/* loop extInfo */
+		while (TRUE) {
+			memset(&fcInfo, 0, sizeof(fcInfo));
+			fcInfo.asIn.cmd	   = MC_FC_INFO;
+			fcInfo.asIn.extInfoId = i;
+
+			MCDRV_DBG(
+				"fcInfo in cmd=0x%08x, extInfoid=0x%08x "
+				"rfu=(0x%08x, 0x%08x)\n",
+				fcInfo.asIn.cmd,
+				fcInfo.asIn.extInfoId,
+				fcInfo.asIn.rfu[0],
+				fcInfo.asIn.rfu[1]);
+
+			mcFastCall(&(fcInfo.asGeneric));
+
+			MCDRV_DBG(
+				"fcInfo out resp=0x%08x, ret=0x%08x "
+				"state=0x%08x, extInfo=0x%08x\n",
+				fcInfo.asOut.resp,
+				fcInfo.asOut.ret,
+				fcInfo.asOut.state,
+				fcInfo.asOut.extInfo);
+
+			ret = convertFcRet(fcInfo.asOut.ret);
+			if (0 != ret)
+				break;
+
+			MCDRV_DBG("state=%08X, idx=%02d: extInfo=%08X\n",
+				  fcInfo.asOut.state, i, fcInfo.asOut.extInfo);
+			i++;
+		};
+
+		if (0 != ret)
+			break;
+
+
+	} while (FALSE);
+
+	MCDRV_DBG_VERBOSE("exit with %d/0x%08X\n", ret, ret);
+
+	return ret;
+}
+
+/*----------------------------------------------------------------------------*/
+/**
+ *
+ * @param pInstance
+ * @param arg
+ *
+ * @return 0 if no error
+ *
+ */
+static int handleIoCtlInit(
+	struct mcInstance	*pInstance,
+	union mcIoCtlInitParams	*pUserParams
+)
+{
+	int			ret = 0;
+	union mcIoCtlInitParams	params;
+	union mcFcInit		fcInit;
+
+	MCDRV_ASSERT(NULL != pInstance);
+	MCDRV_DBG_VERBOSE("enter\n");
+
+	do {
+		/* only the MobiCore Daemon is allowed to call this function */
+		if (!isCallerMcDaemon(pInstance)) {
+			MCDRV_DBG_ERROR("caller not MobiCore Daemon\n");
+			ret = -EFAULT;
+			break;
+		}
+
+		ret = copy_from_user(
+				  &(params.in),
+				  &(pUserParams->in),
+				  sizeof(params.in));
+		if (0 != ret) {
+			MCDRV_DBG_ERROR("copy_from_user failed\n");
+			break;
+		}
+
+		memset(&fcInit, 0, sizeof(fcInit));
+
+		fcInit.asIn.cmd	= MC_FC_INIT;
+		/* base address of mci buffer 4KB aligned */
+		fcInit.asIn.base   = (uint32_t)params.in.base;
+		/* notification buffer start/length [16:16] [start, length] */
+		fcInit.asIn.nqInfo  = (params.in.nqOffset << 16)
+					  | (params.in.nqLength & 0xFFFF);
+		/* mcp buffer start/length [16:16] [start, length] */
+		fcInit.asIn.mcpInfo = (params.in.mcpOffset << 16)
+					  | (params.in.mcpLength & 0xFFFF);
+
+		/* Set KMOD notification queue to start of MCI
+			mciInfo was already set up in mmap */
+		if (!mciBase) {
+			MCDRV_DBG_ERROR("No MCI set yet.\n");
+			return -EFAULT;
+		}
+		MCDRV_DBG("in cmd=0x%08x, base=0x%08x, "
+			  "nqInfo=0x%08x, mcpInfo=0x%08x\n",
+			  fcInit.asIn.cmd,
+			  fcInit.asIn.base,
+			  fcInit.asIn.nqInfo,
+			  fcInit.asIn.mcpInfo);
+
+		mcFastCall(&(fcInit.asGeneric));
+
+		MCDRV_DBG("out cmd=0x%08x, ret=0x%08x rfu=(0x%08x, 0x%08x)\n",
+			  fcInit.asOut.resp,
+			  fcInit.asOut.ret,
+			  fcInit.asOut.rfu[0],
+			  fcInit.asOut.rfu[1]);
+
+		ret = convertFcRet(fcInit.asOut.ret);
+		if (0 != ret)
+			break;
+
+		/* no ioctl response parameters */
+
+	} while (FALSE);
+
+	MCDRV_DBG_VERBOSE("exit with %d/0x%08X\n", ret, ret);
+
+	return ret;
+}
+
+/*----------------------------------------------------------------------------*/
+/**
+ *
+ * @param pInstance
+ * @param arg
+ *
+ * @return 0 if no error
+ *
+ */
+static int handleIoCtlFcExecute(
+	struct mcInstance		*pInstance,
+	union mcIoCtlFcExecuteParams	*pUserParams
+)
+{
+	int				ret = 0;
+	union mcIoCtlFcExecuteParams	params;
+	union fcGeneric			fcParams;
+
+	MCDRV_ASSERT(NULL != pInstance);
+	MCDRV_DBG_VERBOSE("enter\n");
+
+	do {
+		/* only the MobiCore Daemon is allowed to call this function */
+		if (!isCallerMcDaemon(pInstance)) {
+			MCDRV_DBG_ERROR("caller not MobiCore Daemon\n");
+			ret = -EFAULT;
+			break;
+		}
+
+		ret = copy_from_user(
+				  &(params.in),
+				  &(pUserParams->in),
+				  sizeof(params.in));
+		if (0 != ret) {
+			MCDRV_DBG_ERROR("copy_from_user failed\n");
+			break;
+		}
+
+		fcParams.asIn.cmd = -4;/*FC_EXECUTE */
+		fcParams.asIn.param[0] = params.in.physStartAddr;
+		fcParams.asIn.param[1] = params.in.length;
+		fcParams.asIn.param[2] = 0;
+
+		MCDRV_DBG("in cmd=0x%08x, startAddr=0x%08x, length=0x%08x\n",
+			  fcParams.asIn.cmd,
+			  fcParams.asIn.param[0],
+			  fcParams.asIn.param[1]);
+
+		mcFastCall(&fcParams);
+
+		MCDRV_DBG("out cmd=0x%08x, ret=0x%08x rfu=(0x%08x, 0x%08x)\n",
+			  fcParams.asOut.resp,
+			  fcParams.asOut.ret,
+			  fcParams.asOut.param[0],
+			  fcParams.asOut.param[1]);
+
+		ret = convertFcRet(fcParams.asOut.ret);
+		if (0 != ret)
+			break;
+
+		/* no ioctl response parameters */
+
+	} while (FALSE);
+
+	MCDRV_DBG_VERBOSE("exit with %d/0x%08X\n", ret, ret);
+
+	return ret;
+}
+
+/*----------------------------------------------------------------------------*/
+/**
+ *
+ * @param pInstance
+ * @param arg
+ *
+ * @return 0 if no error
+ *
+ */
+#define MC_MAKE_VERSION(major, minor) \
+		(((major & 0x0000ffff) << 16) | (minor & 0x0000ffff))
+
+static int handleIoCtlGetVersion(
+	struct mcInstance	   *pInstance,
+	struct mcIoCtlGetVersionParams	*pUserParams
+)
+{
+	int ret = 0;
+	struct mcIoCtlGetVersionParams  params = {
+		{
+			MC_MAKE_VERSION(MCDRVMODULEAPI_VERSION_MAJOR,
+					MCDRVMODULEAPI_VERSION_MINOR)
+		}
+	};
+
+	MCDRV_ASSERT(NULL != pInstance);
+	MCDRV_DBG_VERBOSE("enter\n");
+
+	do {
+		MCDRV_DBG("mcDrvModuleApi version is %i.%i\n",
+				MCDRVMODULEAPI_VERSION_MAJOR,
+				MCDRVMODULEAPI_VERSION_MINOR);
+
+		/* no ioctl response parameters */
+		ret = copy_to_user(
+					&(pUserParams->out),
+					&(params.out),
+					sizeof(params.out));
+		if (ret != 0)
+			MCDRV_DBG_ERROR("copy_to_user() failed\n");
+
+	} while (FALSE);
+
+	MCDRV_DBG_VERBOSE("exit with %d/0x%08X\n", ret, ret);
+
+	return ret;
+}
+
+/*----------------------------------------------------------------------------*/
+/**
+ * This function will be called from user space as ioctl(...).
+ * @param pInode   pointer to inode
+ * @param pFile	pointer to file
+ * @param cmd	  command
+ * @param arg
+ *
+ * @return int 0 for OK and an errno in case of error
+ */
+static long mcKernelModule_ioctl(
+	struct file	*pFile,
+	unsigned int	cmd,
+	unsigned long	arg
+)
+{
+	int			ret;
+	struct mcInstance	*pInstance = getInstance(pFile);
+
+	MCDRV_ASSERT(NULL != pInstance);
+
+	switch (cmd) {
+	/*--------------------------------------------------------------------*/
+	case MC_DRV_KMOD_IOCTL_DUMP_STATUS:
+		ret = handleIoCtlDumpStatus(
+				  pInstance,
+				  arg);
+		break;
+
+	/*--------------------------------------------------------------------*/
+	case MC_DRV_KMOD_IOCTL_FC_INIT:
+		ret = handleIoCtlInit(
+				  pInstance,
+				  (union mcIoCtlInitParams *)arg);
+		break;
+	/*--------------------------------------------------------------------*/
+	case MC_DRV_KMOD_IOCTL_FC_INFO:
+		ret = handleIoCtlInfo(
+				  pInstance,
+				  (union mcIoCtlInfoParams *)arg);
+		break;
+
+	/*--------------------------------------------------------------------*/
+	case MC_DRV_KMOD_IOCTL_FC_YIELD:
+		ret = handleIoCtlYield(
+				  pInstance);
+		break;
+
+	/*--------------------------------------------------------------------*/
+	case MC_DRV_KMOD_IOCTL_FC_NSIQ:
+		ret = handleIoCtlNSIQ(
+				  pInstance,
+				  arg);
+		break;
+
+	/*--------------------------------------------------------------------*/
+	case MC_DRV_KMOD_IOCTL_DAEMON_LOCK_WSM_L2:
+		ret = handleIoCtlDaemonLockWsmL2(
+				  pInstance,
+				  (struct mcIoCtlDaemonLockWsmL2Params *)arg);
+		break;
+
+	/*--------------------------------------------------------------------*/
+	case MC_DRV_KMOD_IOCTL_DAEMON_UNLOCK_WSM_L2:
+		ret = handleIoCtlDaemonUnlockWsmL2(
+				  pInstance,
+				  (struct mcIoCtlDaemonUnlockWsmL2Params *)arg);
+		break;
+
+	/*--------------------------------------------------------------------*/
+	case MC_DRV_KMOD_IOCTL_FREE:
+		/* called by ClientLib */
+		ret = handleIoCtlFree(
+				  pInstance,
+				  (union mcIoCtltoFreeParams *)arg);
+		break;
+
+	/*--------------------------------------------------------------------*/
+	case MC_DRV_KMOD_IOCTL_APP_REGISTER_WSM_L2:
+		/* called by ClientLib */
+		ret = handleIoCtlAppRegisterWsmL2(
+				pInstance,
+				(union mcIoCtlAppRegWsmL2Params *)arg);
+		break;
+
+	/*--------------------------------------------------------------------*/
+	case MC_DRV_KMOD_IOCTL_APP_UNREGISTER_WSM_L2:
+		/* called by ClientLib */
+		ret = handleIoCtlAppUnregisterWsmL2(
+				pInstance,
+				(struct mcIoCtlAppUnregWsmL2Params *)arg);
+		break;
+
+	/*--------------------------------------------------------------------*/
+	case MC_DRV_KMOD_IOCTL_FC_EXECUTE:
+		ret = handleIoCtlFcExecute(
+				pInstance,
+				(union mcIoCtlFcExecuteParams *)arg);
+		break;
+
+	/*--------------------------------------------------------------------*/
+	case MC_DRV_KMOD_IOCTL_GET_VERSION:
+		ret = handleIoCtlGetVersion(
+					pInstance,
+					(struct mcIoCtlGetVersionParams *)arg);
+		break;
+
+	/*--------------------------------------------------------------------*/
+	default:
+		MCDRV_DBG_ERROR("unsupported cmd=%d\n", cmd);
+		ret = -EFAULT;
+		break;
+
+	} /* end switch(cmd) */
+
+#ifdef MC_MEM_TRACES
+	mobicore_read_log();
+#endif
+
+	return (int)ret;
+}
+
+
+/*----------------------------------------------------------------------------*/
+/**
+ * This function will be called from user space as read(...).
+ * The read function is blocking until a interrupt occurs. In that case the
+ * event counter is copied into user space and the function is finished.
+ * @param *pFile
+ * @param *pBuffer  buffer where to copy to(userspace)
+ * @param count	 number of requested data
+ * @param *pPos	 not used
+ * @return ssize_t  ok case: number of copied data
+ *				  error case: return errno
+ */
+static ssize_t mcKernelModule_read(
+	struct file	*pFile,
+	char		*pBuffer,
+	size_t		bufferLen,
+	loff_t		*pPos
+)
+{
+	int ret = 0, ssiqCounter;
+	size_t retLen = 0;
+	struct mcInstance *pInstance = getInstance(pFile);
+
+	MCDRV_ASSERT(NULL != pInstance);
+
+	/* avoid debug output on non-error, because this is call quite often */
+	MCDRV_DBG_VERBOSE("enter\n");
+
+	do {
+		/* only the MobiCore Daemon is allowed to call this function */
+		if (!isCallerMcDaemon(pInstance)) {
+			MCDRV_DBG_ERROR("caller not MobiCore Daemon\n");
+			ret = -EFAULT;
+			break;
+		}
+
+		if (bufferLen < sizeof(unsigned int)) {
+			MCDRV_DBG_ERROR("invalid length\n");
+			ret = (ssize_t)(-EINVAL);
+			break;
+		}
+
+		for (;;) {
+			if (down_interruptible(&mcDrvKModCtx.daemonCtx.sem)) {
+				MCDRV_DBG_VERBOSE("read interrupted\n");
+				ret = (ssize_t)-ERESTARTSYS;
+				break;
+			}
+
+			ssiqCounter = atomic_read(
+					&(mcDrvKModCtx.ssiqCtx.counter));
+			MCDRV_DBG_VERBOSE("ssiqCounter=%i, ctx.counter=%i\n",
+					ssiqCounter,
+					mcDrvKModCtx.daemonCtx.ssiqCounter);
+
+			if (ssiqCounter != mcDrvKModCtx.daemonCtx.ssiqCounter) {
+				/* read data and exit loop without
+					error */
+				mcDrvKModCtx.daemonCtx.ssiqCounter =
+					ssiqCounter;
+				ret = 0;
+				break;
+			}
+
+			/* end loop if non-blocking */
+			if (0 != (pFile->f_flags & O_NONBLOCK)) {
+				MCDRV_DBG_ERROR("non-blocking read\n");
+				ret = (ssize_t)(-EAGAIN);
+				break;
+			}
+
+			if (0 != signal_pending(current)) {
+				MCDRV_DBG_VERBOSE("received signal.\n");
+				ret = (ssize_t)(-ERESTARTSYS);
+				break;
+			}
+
+		}
+
+		/* we are here if an event occurred or we had an
+			error.*/
+		if (0 != ret)
+			break;
+
+		/* read data and exit loop */
+		ret = copy_to_user(
+				  pBuffer,
+				  &(mcDrvKModCtx.daemonCtx.ssiqCounter),
+				  sizeof(unsigned int));
+
+
+		if (0 != ret) {
+			MCDRV_DBG_ERROR("copy_to_user failed\n");
+			ret = (ssize_t)(-EFAULT);
+			break;
+		}
+
+		retLen = sizeof(s32);
+
+	} while (FALSE);
+
+	/* avoid debug on non-error. */
+	if (0 == ret)
+		ret = (size_t)retLen;
+	else
+		MCDRV_DBG("exit with %d/0x%08X\n", ret, ret);
+
+	return (ssize_t)ret;
+}
+
+/*----------------------------------------------------------------------------*/
+/**
+ * Allocate WSM for given instance
+ *
+ * @param pInstance		instance
+ * @param requestedSize		size of the WSM
+ * @param pHandle		pointer where the handle will be saved
+ * @param pKernelVirtAddr	pointer for the kernel virtual address
+ * @param pPhysAddr		pointer for the physical address
+ *
+ * @return error code or 0 for success
+ */
+int mobicore_allocate_wsm(
+	struct mcInstance	*pInstance,
+	unsigned long		requestedSize,
+	uint32_t		*pHandle,
+	void			**pKernelVirtAddr,
+	void			**pPhysAddr
+)
+{
+	unsigned int	i;
+	unsigned int	order;
+	unsigned long	allocatedSize;
+	int		ret = 0;
+	struct mc_tuple	*pTuple = 0;
+	void		*kernelVirtAddr;
+	void		*physAddr;
+
+	MCDRV_ASSERT(NULL != pInstance);
+	MCDRV_DBG("%s (size=%ld)\n", __func__, requestedSize);
+
+	order = sizeToOrder(requestedSize);
+	if (INVALID_ORDER == order) {
+		MCDRV_DBG_ERROR(
+			"size to order converting failed for size %ld\n",
+			requestedSize);
+		return INVALID_ORDER;
+	}
+
+	allocatedSize = (1<<order)*PAGE_SIZE;
+
+	MCDRV_DBG("size %ld -> order %d --> %ld (2^n pages)\n",
+		  requestedSize, order, allocatedSize);
+
+	do {
+		/* Usual Wsm request, allocate tuple. */
+		/* search for a free entry in the tuple list
+		 * REV axh: serialize this over multiple instances. */
+		for (i = 0; i < MC_DRV_KMOD_TUPLE_NR; i++) {
+			pTuple = &(pInstance->tuple[i]);
+			if (0 == pTuple->handle) {
+				pTuple->handle = getMcKModUniqueId();
+				break;
+			}
+		}
+		if (MC_DRV_KMOD_TUPLE_NR == i) {
+			MCDRV_DBG_ERROR("no free tuple\n");
+			ret = -EFAULT;
+			break;
+		}
+
+		/* Common code for all allocation paths */
+		kernelVirtAddr = (void *)__get_free_pages(GFP_USER | __GFP_COMP,
+								order);
+		if (NULL == kernelVirtAddr) {
+			MCDRV_DBG_ERROR("get_free_pages failed\n");
+			ret = -ENOMEM;
+			break;
+		}
+
+		/* Get physical address to instance data */
+		physAddr = (void *)virt_to_phys(kernelVirtAddr);
+		/* TODO: check for INVALID_ADDRESS? */
+
+		MCDRV_DBG(
+			"allocated phys=0x%p - 0x%p, "
+			"size=%ld, kernelVirt=0x%p, handle=%d\n",
+			physAddr,
+			(void *)((unsigned int)physAddr+allocatedSize),
+				allocatedSize, kernelVirtAddr, pTuple->handle);
+
+		/* Usual Wsm request, allocate tuple.
+		 *		Also, we never free a persistent Tci */
+		pTuple->physAddr	   = physAddr;
+		pTuple->virtKernelAddr = kernelVirtAddr;
+		pTuple->virtUserAddr   = kernelVirtAddr;
+		pTuple->numPages	   = (1U << order);
+		*pHandle = pTuple->handle;
+		*pKernelVirtAddr = kernelVirtAddr;
+		*pPhysAddr = physAddr;
+
+	} while (FALSE);
+
+	MCDRV_DBG_VERBOSE("%s: exit with 0x%08X\n", __func__, ret);
+
+	return ret;
+}
+EXPORT_SYMBOL(mobicore_allocate_wsm);
+
+
+/*----------------------------------------------------------------------------*/
+/**
+ * This function will be called from user space as address = mmap(...).
+ *
+ * @param pFile
+ * @param pVmArea
+ * pVmArea.pg_offset != 0 is mapping of MCI is requested
+ *
+ * @return 0 if OK or -ENOMEM in case of error.
+ */
+static int mcKernelModule_mmap(
+	struct file		*pFile,
+	struct vm_area_struct	*pVmArea
+)
+{
+	unsigned int		i;
+	unsigned int		order;
+	void			*kernelVirtAddr = 0;
+	void			*physAddr = 0;
+	unsigned long		requestedSize =
+					pVmArea->vm_end - pVmArea->vm_start;
+	unsigned long		allocatedSize;
+	int			ret = 0;
+	struct mc_tuple		*pTuple = 0;
+	unsigned int		handle = 0;
+	struct mcInstance	*pInstance = getInstance(pFile);
+	unsigned int		request = pVmArea->vm_pgoff * 4096;
+#if defined(DEBUG)
+	bool release = false;
+#else
+	bool release = true;
+#endif
+
+	MCDRV_ASSERT(NULL != pInstance);
+	MCDRV_DBG("enter (vmaStart=0x%p, size=%ld, request=0x%x, mci=0x%x)\n",
+		  (void *)pVmArea->vm_start,
+		  requestedSize,
+		  request,
+		  mciBase);
+
+	order = sizeToOrder(requestedSize);
+	if (INVALID_ORDER == order) {
+		MCDRV_DBG_ERROR(
+			"size to order converting failed for size %ld\n",
+			requestedSize);
+		return -ENOMEM;
+	}
+
+	allocatedSize = (1<<order)*PAGE_SIZE;
+
+	MCDRV_DBG("size %ld -> order %d --> %ld (2^n pages)\n",
+		  requestedSize, order, allocatedSize);
+
+	do {
+		/* Daemon tries to get an existing MCI */
+		if ((MC_DRV_KMOD_MMAP_MCI == request) && (mciBase != 0)) {
+			MCDRV_DBG("Request MCI, it is at (%x)\n",
+				  mciBase);
+
+			if (!isCallerMcDaemon(pInstance)) {
+				ret = -EPERM;
+				break;
+			}
+			kernelVirtAddr = (void *)mciBase;
+			physAddr = (void *)virt_to_phys(kernelVirtAddr);
+		} else {
+			/* Usual Wsm request, allocate tuple. */
+			if (MC_DRV_KMOD_MMAP_WSM == request) {
+				/* search for a free entry in the tuple list
+				REV axh: serialize this over multiple instances.
+				*/
+				for (i = 0; i < MC_DRV_KMOD_TUPLE_NR; i++) {
+					pTuple = &(pInstance->tuple[i]);
+					if (0 == pTuple->handle) {
+						pTuple->handle =
+							getMcKModUniqueId();
+						break;
+					}
+				}
+				if (MC_DRV_KMOD_TUPLE_NR == i) {
+					MCDRV_DBG_ERROR("no free tuple\n");
+					ret = -EFAULT;
+					break;
+				}
+			} else {
+				if (request <= MC_DRV_KMOD_MMAP_PERSISTENTWSM
+					|| release) {
+					/* Special Wsm request
+						--> only Daemon is allowed */
+					if (!isCallerMcDaemon(pInstance)) {
+						ret = -EPERM;
+						break;
+					}
+				}
+			}
+			if (request <= MC_DRV_KMOD_MMAP_PERSISTENTWSM) {
+				/* Common code for all allocation paths
+					*  get physical address, */
+				kernelVirtAddr = (void *)__get_free_pages(
+							GFP_USER | __GFP_COMP,
+							order);
+				if (NULL == kernelVirtAddr) {
+					MCDRV_DBG_ERROR(
+						"get_free_pages failed\n");
+					ret = -ENOMEM;
+					break;
+				}
+				if (MC_DRV_KMOD_MMAP_WSM == request)
+					handle = pTuple->handle;
+				/* Get physical address to instance data */
+				/* TODO: check for INVALID_ADDRESS? */
+				physAddr = (void *)virt_to_phys(kernelVirtAddr);
+			} else {
+#if defined(DEBUG)
+				/*kernelVirtAddr = phys_to_virt(request);
+				kernelVirtAddr =
+					ioremap(request,requestedSize);*/
+				physAddr = (void *)request;
+				kernelVirtAddr = phys_to_virt(request);
+				/* NOTE: request !=
+					virt_to_phys(phys_to_virt(request))*/
+#endif
+			}
+		}
+		/* Common code for all mmap calls:
+		 * map page to user
+		 * store data in page */
+
+		MCDRV_DBG("allocated phys=0x%p - 0x%p, "
+			"size=%ld, kernelVirt=0x%p, handle=%d\n",
+			physAddr,
+			(void *)((unsigned int)physAddr+allocatedSize),
+			allocatedSize, kernelVirtAddr, handle);
+
+		pVmArea->vm_flags |= VM_RESERVED;
+		/* convert Kernel address to User Address. Kernel address begins
+			at PAGE_OFFSET, user Address range is below PAGE_OFFSET.
+			Remapping the area is always done, so multiple mappings
+			of one region are possible. Now remap kernel address
+			space into user space */
+		ret = (int)remap_pfn_range(
+				pVmArea,
+				(pVmArea->vm_start),
+				addrToPfn(physAddr),
+				requestedSize,
+				pVmArea->vm_page_prot);
+		if (0 != ret) {
+			MCDRV_DBG_ERROR("remapPfnRange failed\n");
+
+			/* free allocated pages when mmap fails, however, do not
+				do it, when daemon tried to get an MCI that
+				existed */
+			if (!((MC_DRV_KMOD_MMAP_MCI == request) &&
+				  (mciBase != 0)))
+				freeContinguousPages(
+					kernelVirtAddr,
+					(1U << order));
+			break;
+		}
+
+		/* Usual Wsm request, allocate tuple.
+			When requesting Mci, we do not associate the page with
+			the process.
+			Note: we also never free the Mci
+			Also, we never free a persistent Tci */
+		if (MC_DRV_KMOD_MMAP_WSM == request) {
+			pTuple->physAddr	   = physAddr;
+			pTuple->virtKernelAddr = kernelVirtAddr;
+			pTuple->virtUserAddr   = (void *)(pVmArea->vm_start);
+			pTuple->numPages	   = (1U << order);
+		}
+
+		/* set response in allocated buffer */
+		{
+			struct mcMmapResp *mmapResp =
+				(struct mcMmapResp *)kernelVirtAddr;
+			/* TODO: do this for daemon only, otherwise set NULL */
+			mmapResp->physAddr = (uint32_t)physAddr;
+			mmapResp->handle = handle;
+			if ((MC_DRV_KMOD_MMAP_MCI == request) &&
+				(0 != mciBase)) {
+				mmapResp->isReused = 1;
+			} else
+				mmapResp->isReused = 0;
+		}
+
+		/* store MCI pointer */
+		if ((MC_DRV_KMOD_MMAP_MCI == request) && (0 == mciBase)) {
+			mciBase = (uint32_t)kernelVirtAddr;
+			MCDRV_DBG("MCI base set to 0x%x\n", mciBase);
+		}
+	} while (FALSE);
+
+	MCDRV_DBG_VERBOSE("exit with %d/0x%08X\n", ret, ret);
+
+	return (int)ret;
+}
+
+/*----------------------------------------------------------------------------*/
+/**
+ * Force migration of current task to CPU0(where the monitor resides)
+ *
+ * @return Error code or 0 for success
+ */
+static int gotoCpu0(
+	void
+)
+{
+	int		ret = 0;
+	struct cpumask	mask =  CPU_MASK_CPU0;
+
+	MCDRV_DBG_VERBOSE("System has %d CPU's, we are on CPU #%d\n"
+		  "\tBinding this process to CPU #0.\n"
+		  "\tactive mask is %lx, setting it to mask=%lx\n",
+		  nr_cpu_ids,
+		  raw_smp_processor_id(),
+		  cpu_active_mask->bits[0],
+		  mask.bits[0]);
+	ret = set_cpus_allowed_ptr(current, &mask);
+	if (0 != ret)
+		MCDRV_DBG_ERROR("set_cpus_allowed_ptr=%d.\n", ret);
+	MCDRV_DBG_VERBOSE("And now we are on CPU #%d\n",
+				raw_smp_processor_id());
+
+	return ret;
+}
+
+/*----------------------------------------------------------------------------*/
+/**
+ * Restore CPU mask for current to ALL Cpus(reverse of gotoCpu0)
+ *
+ * @return Error code or 0 for success
+ */
+static int gotoAllCpu(
+	void
+)
+{
+	int		ret = 0;
+
+	struct cpumask	mask =  CPU_MASK_ALL;
+
+	MCDRV_DBG_VERBOSE("System has %d CPU's, we are on CPU #%d\n"
+		  "\tBinding this process to CPU #0.\n"
+		  "\tactive mask is %lx, setting it to mask=%lx\n",
+		  nr_cpu_ids,
+		  raw_smp_processor_id(),
+		  cpu_active_mask->bits[0],
+		  mask.bits[0]);
+	ret = set_cpus_allowed_ptr(current, &mask);
+	if (0 != ret)
+		MCDRV_DBG_ERROR("set_cpus_allowed_ptr=%d.\n", ret);
+	MCDRV_DBG_VERBOSE("And now we are on CPU #%d\n",
+				raw_smp_processor_id());
+
+	return ret;
+}
+
+/*----------------------------------------------------------------------------*/
+/**
+ * Initialize a new mobicore API instance object
+ *
+ * @return Instance or NULL if no allocation was possible.
+ */
+struct mcInstance *mobicore_open(
+	void
+) {
+	struct mcInstance	*pInstance;
+	pid_t			pidVnr;
+
+	pInstance = kzalloc(sizeof(*pInstance), GFP_KERNEL);
+	if (NULL == pInstance)
+		return NULL;
+
+	/* get a unique ID for this instance (PIDs are not unique) */
+	pInstance->handle = getMcKModUniqueId();
+
+	/* get the PID of the calling process. We avoid using
+	 *	current->pid directly, as 2.6.24 introduced PID
+	 *	namespaces. See also http://lwn.net/Articles/259217 */
+	pidVnr = task_pid_vnr(current);
+	pInstance->pidVnr = pidVnr;
+
+	return pInstance;
+}
+EXPORT_SYMBOL(mobicore_open);
+
+/*----------------------------------------------------------------------------*/
+/**
+ * This function will be called from user space as fd = open(...).
+ * A set of internal instance data are created and initialized.
+ *
+ * @param pInode
+ * @param pFile
+ * @return 0 if OK or -ENOMEM if no allocation was possible.
+ */
+static int mcKernelModule_open(
+	struct inode	*pInode,
+	struct file	*pFile
+)
+{
+	struct mcInstance	*pInstance;
+	int			ret = 0;
+
+	MCDRV_DBG_VERBOSE("enter\n");
+
+	do {
+		pInstance = mobicore_open();
+		if (pInstance == NULL)
+			return -ENOMEM;
+
+		/* check if Daemon. We simply assume that the first to open us
+			with root privileges must be the daemon. */
+		if ((isUserlandCallerPrivileged())
+			&& (NULL == mcDrvKModCtx.daemonInst)) {
+			MCDRV_DBG("accept this as MobiCore Daemon\n");
+
+			/* Set the caller's CPU mask to CPU0*/
+			ret = gotoCpu0();
+			if (ret != 0) {
+				mobicore_release(pInstance);
+				pFile->private_data = NULL;
+				MCDRV_DBG("changing core failed!\n");
+				break;
+			}
+
+			mcDrvKModCtx.daemonInst = pInstance;
+			sema_init(&mcDrvKModCtx.daemonCtx.sem, DAEMON_SEM_VAL);
+			/* init ssiq event counter */
+			mcDrvKModCtx.daemonCtx.ssiqCounter =
+				atomic_read(&(mcDrvKModCtx.ssiqCtx.counter));
+
+		}
+
+		/* store instance data reference */
+		pFile->private_data = pInstance;
+
+		/* TODO axh: link all instances to allow clean up? */
+
+	} while (FALSE);
+
+	MCDRV_DBG_VERBOSE("exit with %d/0x%08X\n", ret, ret);
+
+	return (int)ret;
+
+}
+
+/*----------------------------------------------------------------------------*/
+/**
+ * Release a mobicore instance object and all objects related to it
+ * @param pInstance instance
+ * @return 0 if Ok or -E ERROR
+ */
+int mobicore_release(
+	struct mcInstance	*pInstance
+)
+{
+	int			ret = 0;
+	unsigned int		idxTuple;
+	struct mcL2TablesDescr	*pWsmL2Descr, *pTemp;
+
+	do {
+		/* try to get the semaphore */
+		ret = down_interruptible(&(mcDrvKModCtx.wsmL2Sem));
+		if (0 != ret) {
+			MCDRV_DBG_ERROR(
+				"down_interruptible() failed with %d\n", ret);
+			/* TODO: can be block here? */
+			ret = -ERESTARTSYS;
+		} else {
+			/* Check if some WSM is still in use. */
+			list_for_each_entry_safe(
+				pWsmL2Descr,
+				pTemp,
+				&(mcDrvKModCtx.wsmL2Descriptors),
+				list
+			) {
+				if (pWsmL2Descr->pInstance == pInstance) {
+					MCDRV_DBG_WARN(
+						"trying to release WSM L2: "
+						"physBase=%p ,nrOfPages=%d\n",
+						getL2TablePhys(pWsmL2Descr),
+						pWsmL2Descr->nrOfPages);
+
+					/* unlock app usage and free if MobiCore
+					does not use it */
+					freeWsmL2Table(pWsmL2Descr,
+							FREE_FROM_NWD);
+				}
+			} /* end while */
+
+			/* release semaphore */
+			up(&(mcDrvKModCtx.wsmL2Sem));
+		}
+
+
+
+		/* release all mapped data */
+		for (idxTuple = 0;
+			 idxTuple < MC_DRV_KMOD_TUPLE_NR;
+			 idxTuple++) {
+			struct mc_tuple *pTuple = &(pInstance->tuple[idxTuple]);
+
+			if (0 != pTuple->virtUserAddr) {
+				freeContinguousPages(
+					pTuple->virtKernelAddr,
+					pTuple->numPages);
+			}
+		}
+
+		/* release instance context */
+		kfree(pInstance);
+	} while (FALSE);
+
+	return ret;
+}
+EXPORT_SYMBOL(mobicore_release);
+
+/*----------------------------------------------------------------------------*/
+/**
+ * This function will be called from user space as close(...).
+ * The instance data are freed and the associated memory pages are unreserved.
+ *
+ * @param pInode
+ * @param pFile
+ *
+ * @return 0
+ */
+static int mcKernelModule_release(
+	struct inode	*pInode,
+	struct file	*pFile
+)
+{
+	int			ret = 0;
+	struct mcInstance	*pInstance = getInstance(pFile);
+
+	MCDRV_DBG_VERBOSE("enter\n");
+
+
+	do {
+		/* check if daemon closes us. */
+		if (isCallerMcDaemon(pInstance)) {
+			/* TODO: cleanup?
+				* mcDrvKModCtx.wsmL2Descriptors remains */
+			MCDRV_DBG_WARN("WARNING: MobiCore Daemon died\n");
+			mcDrvKModCtx.daemonInst = NULL;
+		}
+
+		ret = mobicore_release(pInstance);
+
+	} while (FALSE);
+
+	MCDRV_DBG_VERBOSE("exit with %d/0x%08X\n", ret, ret);
+
+	return (int)ret;
+}
+
+
+/*----------------------------------------------------------------------------*/
+/**
+ * This function represents the interrupt function of the mcDrvModule.
+ * It signals by incrementing of an event counter and the start of the read
+ * waiting queue, the read function a interrupt has occurred.
+ *
+ * @param   intr
+ * @param   *pContext  pointer to registered device data
+ *
+ * @return  IRQ_HANDLED
+ */
+static irqreturn_t mcKernelModule_intrSSIQ(
+	int	intr,
+	void	*pContext
+)
+{
+	irqreturn_t	ret = IRQ_NONE;
+
+	/* we know the context. */
+	MCDRV_ASSERT(&mcDrvKModCtx == pContext);
+
+	do {
+		if (MC_INTR_SSIQ != intr) {
+			/* this should not happen, as we did no register for any
+				other interrupt. Fir debugging, we print a
+				message, but continue */
+			MCDRV_DBG_WARN(
+				"unknown interrupt %d, expecting only %d\n",
+				intr, MC_INTR_SSIQ);
+		}
+		MCDRV_DBG_VERBOSE("received interrupt %d\n",
+				  intr);
+
+		/* increment interrupt event counter */
+		atomic_inc(&(mcDrvKModCtx.ssiqCtx.counter));
+
+		/* signal the daemon */
+		up(&mcDrvKModCtx.daemonCtx.sem);
+
+
+		ret = IRQ_HANDLED;
+
+	} while (FALSE);
+
+	return ret;
+}
+
+/*----------------------------------------------------------------------------*/
+/** function table structure of this device driver. */
+static const struct file_operations mcKernelModule_fileOperations = {
+	.owner		= THIS_MODULE, /**< driver owner */
+	.open		= mcKernelModule_open, /**< driver open function */
+	.release	= mcKernelModule_release, /**< driver release function*/
+	.unlocked_ioctl	= mcKernelModule_ioctl, /**< driver ioctl function */
+	.mmap		= mcKernelModule_mmap, /**< driver mmap function */
+	.read		= mcKernelModule_read, /**< driver read function */
+};
+
+/*----------------------------------------------------------------------------*/
+/** registration structure as miscdevice. */
+static struct miscdevice mcKernelModule_device = {
+	.name	= MC_DRV_MOD_DEVNODE, /**< device name */
+	.minor	= MISC_DYNAMIC_MINOR, /**< device minor number */
+	/** device interface function structure */
+	.fops	= &mcKernelModule_fileOperations,
+};
+
+
+/*----------------------------------------------------------------------------*/
+/**
+ * This function is called the kernel during startup or by a insmod command.
+ * This device is installed and registered as miscdevice, then interrupt and
+ * queue handling is set up
+ *
+ * @return 0 for no error or -EIO if registration fails
+ */
+static int __init mcKernelModule_init(
+	void
+)
+{
+	int ret = 0;
+
+	MCDRV_DBG("enter (Build " __TIMESTAMP__ ")\n");
+	MCDRV_DBG("mcDrvModuleApi version is %i.%i\n",
+			MCDRVMODULEAPI_VERSION_MAJOR,
+			MCDRVMODULEAPI_VERSION_MINOR);
+	MCDRV_DBG("%s\n", MOBICORE_COMPONENT_BUILD_TAG);
+
+	do {
+		/* Hardware does not support ARM TrustZone
+			-> Cannot continue! */
+		if (!hasSecurityExtensions()) {
+			MCDRV_DBG_ERROR(
+				"Hardware does't support ARM TrustZone!\n");
+			ret = -ENODEV;
+			break;
+		}
+
+		/* Running in secure mode -> Cannot load the driver! */
+		if (isSecureMode()) {
+			MCDRV_DBG_ERROR("Running in secure MODE!\n");
+			ret = -ENODEV;
+			break;
+		}
+
+#ifdef MC_MEM_TRACES
+		/* setupLog won't fail, it eats up any errors */
+		mcKernelModule_setupLog();
+#endif
+
+		sema_init(&mcDrvKModCtx.daemonCtx.sem, DAEMON_SEM_VAL);
+		/* set up S-SIQ interrupt handler */
+		ret = request_irq(
+				  MC_INTR_SSIQ,
+				  mcKernelModule_intrSSIQ,
+				  IRQF_TRIGGER_RISING,
+				  MC_DRV_MOD_DEVNODE,
+				  &mcDrvKModCtx);
+		if (0 != ret) {
+			MCDRV_DBG_ERROR("interrupt request failed\n");
+			break;
+		}
+
+		ret = misc_register(&mcKernelModule_device);
+		if (0 != ret) {
+			MCDRV_DBG_ERROR("device register failed\n");
+			break;
+		}
+
+		/* initialize event counter for signaling of an IRQ to zero */
+		atomic_set(&(mcDrvKModCtx.ssiqCtx.counter), 0);
+
+		/* init list for WSM L2 chunks. */
+		INIT_LIST_HEAD(&(mcDrvKModCtx.wsmL2Chunks));
+
+		/* L2 table descriptor list. */
+		INIT_LIST_HEAD(&(mcDrvKModCtx.wsmL2Descriptors));
+
+		sema_init(&(mcDrvKModCtx.wsmL2Sem), 1);
+
+		/* initialize unique number counter which we can use for
+			handles. It is limited to 2^32, but this should be
+			enough to be roll-over safe for us. We start with 1
+			instead of 0. */
+		atomic_set(&(mcDrvKModCtx.uniqueCounter), 1);
+
+		mciBase = 0;
+		MCDRV_DBG("initialized\n");
+
+		ret = 0;
+
+	} while (FALSE);
+
+	MCDRV_DBG_VERBOSE("exit with %d/0x%08X\n", ret, ret);
+
+	return (int)ret;
+}
+
+
+
+/*----------------------------------------------------------------------------*/
+/**
+ * This function removes this device driver from the Linux device manager .
+ */
+static void __exit mcKernelModule_exit(
+	void
+)
+{
+	struct mcL2TablesDescr	*pWsmL2Descr;
+
+	MCDRV_DBG_VERBOSE("enter\n");
+
+	/* Check if some WSM is still in use. */
+	list_for_each_entry(
+		pWsmL2Descr,
+		&(mcDrvKModCtx.wsmL2Descriptors),
+		list
+	) {
+		MCDRV_DBG_WARN(
+			"WSM L2 still in use: physBase=%p ,nrOfPages=%d\n",
+			getL2TablePhys(pWsmL2Descr),
+			pWsmL2Descr->nrOfPages);
+	} /* end while */
+
+	free_irq(MC_INTR_SSIQ, &mcDrvKModCtx);
+
+	misc_deregister(&mcKernelModule_device);
+#ifdef MC_MEM_TRACES
+	if (mcLogBuf)
+		free_page((unsigned long)mcLogBuf);
+#endif
+	MCDRV_DBG_VERBOSE("exit");
+}
+
+
+/*----------------------------------------------------------------------------*/
+/* Linux Driver Module Macros */
+module_init(mcKernelModule_init);
+module_exit(mcKernelModule_exit);
+MODULE_AUTHOR("Giesecke & Devrient GmbH");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("MobiCore driver");
+
+/** @} */
+
diff --git a/V008/Linux/drivers/gud/MobiCoreDriver/mcDrvModule.h b/V008/Linux/drivers/gud/MobiCoreDriver/mcDrvModule.h
new file mode 100644
index 0000000..e0a9872
--- /dev/null
+++ b/V008/Linux/drivers/gud/MobiCoreDriver/mcDrvModule.h
@@ -0,0 +1,218 @@
+/**
+ * Header file of MobiCore Driver Kernel Module.
+ *
+ * @addtogroup MobiCore_Driver_Kernel_Module
+ * @{
+ * Internal structures of the McDrvModule
+ * @file
+ *
+ * Header file the MobiCore Driver Kernel Module,
+ * its internal structures and defines.
+ *
+ * <!-- Copyright Giesecke & Devrient GmbH 2009-2012 -->
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef _MC_DRV_KMOD_H_
+#define _MC_DRV_KMOD_H_
+
+#include "mcDrvModuleLinuxApi.h"
+#include "public/mcDrvModuleApi.h"
+/** Platform specific settings */
+#include "platform.h"
+
+/** ARM Specific masks and modes */
+#define ARM_CPSR_MASK 0x1F
+#define ARM_MONITOR_MODE 0b10110
+#define ARM_SECURITY_EXTENSION_MASK 0x30
+
+/** Number of page table entries in one L2 table. This is ARM specific, an
+ *  L2 table covers 1 MiB by using 256 entry referring to 4KiB pages each.
+ */
+#define MC_ARM_L2_TABLE_ENTRIES		256
+
+/** Number of address allocations for one driver instance. */
+#define MC_DRV_KMOD_TUPLE_NR		16
+
+/** Number of pages for L2 tables. There are 4 table in each page. */
+#define MC_DRV_KMOD_L2_TABLE_PER_PAGES	4
+#define MC_DRV_KMOD_L2_TABLE_PAGES	8
+
+struct l2Table {
+	pte_t	tableEntries[MC_ARM_L2_TABLE_ENTRIES];
+};
+
+#define INVALID_ADDRESS	 ((void *)(-1))
+
+/** ARM L2 PTE bits */
+#define L2_FLAG_SMALL_XN	(1U <<  0)
+#define L2_FLAG_SMALL	   (1U <<  1)
+#define L2_FLAG_B		   (1U <<  2)
+#define L2_FLAG_C		   (1U <<  3)
+#define L2_FLAG_AP0		 (1U <<  4)
+#define L2_FLAG_AP1		 (1U <<  5)
+#define L2_FLAG_SMALL_TEX0  (1U <<  6)
+#define L2_FLAG_SMALL_TEX1  (1U <<  7)
+#define L2_FLAG_SMALL_TEX2  (1U <<  8)
+#define L2_FLAG_APX		 (1U <<  9)
+#define L2_FLAG_S		   (1U << 10)
+#define L2_FLAG_NG		  (1U << 11)
+
+/**
+ * tuple list entry.
+ * It describes the tuple, physical Kernel start address to the virtual Client
+ * address. The virtual kernel address is added for a simpler search algorithm.
+ */
+struct mc_tuple {
+	unsigned int	handle; /* unique handle */
+	void		*virtUserAddr; /**< virtual User start address */
+	void		*virtKernelAddr; /**< virtual Kernel start address */
+	void		*physAddr; /**< physical start address */
+	unsigned int	numPages; /**< number of pages */
+};
+
+/**
+ * Driver instance data.
+ */
+struct mcInstance {
+	/** unique handle */
+	unsigned int	handle;
+	/** process that opened this instance */
+	pid_t		pidVnr;
+	struct {
+		/** number of pages */
+		unsigned int	numPages;
+		/** virtual start address kernel address space generated
+			by mmap command */
+		void		*virtAddr;
+		/** physical start address kernel address space generated
+			by mmap command */
+		void		*physAddr;
+	} map;
+	/** tuple list for mmap generated address space and
+		its virtual client address */
+	struct mc_tuple	tuple[MC_DRV_KMOD_TUPLE_NR];
+};
+
+
+
+/** data structure of 4 L2 tables within one 4kb page*/
+struct mcL2Page {
+	struct l2Table table[MC_DRV_KMOD_L2_TABLE_PER_PAGES];
+};
+
+
+/** bookkeeping data structure that manages 4 L2 tables in one page */
+struct mcL2TablesChunk {
+	struct list_head	list;
+	unsigned int		usageBitmap;	/**< usage bitmap */
+	struct mcL2Page		*kernelVirt;	/**< kernel virtual address */
+	struct mcL2Page		*phys;		/**< physical address */
+	struct page		*pPage;		/**< pointer to page struct */
+};
+
+/** bookkeeping data structure that binds one L2 table
+	to its chunk(page) and its user */
+struct mcL2TablesDescr {
+	struct list_head	list;
+	unsigned int		handle;
+	unsigned int		flags;
+	struct mcInstance	*pInstance;
+	struct mcL2TablesChunk	*pChunk;
+	unsigned int		idx;
+	unsigned int		nrOfPages;
+};
+
+#define MC_WSM_L2_CONTAINER_WSM_LOCKED_BY_APP   (1U << 0)
+#define MC_WSM_L2_CONTAINER_WSM_LOCKED_BY_MC	(1U << 1)
+
+
+/** MobiCore S-SIQ interrupt context data. */
+struct mcSSiqCtx {
+	atomic_t		counter; /**< S-SIQ interrupt counter */
+};
+
+
+/** MobiCore Daemon  context data. */
+struct mcDaemonCtx {
+	struct semaphore		sem; /**< event semaphore */
+	struct fasync_struct	*pAsyncQueue;
+	unsigned int			ssiqCounter; /**< event counter */
+};
+
+
+/** MobiCore Driver Kernel Module context data. */
+struct mcDrvKModCtx {
+	atomic_t		uniqueCounter; /**< ever incrementing counter */
+	struct mcSSiqCtx	ssiqCtx; /**< S-SIQ interrupt context */
+	struct mcDaemonCtx	daemonCtx; /**< MobiCore Daemon context */
+	struct mcInstance	*daemonInst; /**< pointer to instance of daemon */
+	struct list_head	wsmL2Chunks; /**< Backing store for L2 tables */
+	struct list_head	wsmL2Descriptors; /**< Bookkeeping for L2 tables */
+	struct semaphore	wsmL2Sem; /**< semaphore to synchronize access to
+								above lists */
+};
+
+/** MobiCore internal trace buffer structure. */
+struct mcTraceBuf {
+	uint32_t version; /**< version of trace buffer */
+	uint32_t length; /**< length of allocated buffer(includes header) */
+	uint32_t write_pos; /**< last write position */
+	char  buff[1]; /**< start of the log buffer */
+};
+
+#define MCDRV_DBG_ERROR(txt, ...) \
+	printk(KERN_ERR "mcDrvKMod [%d] %s() ### ERROR: " txt, \
+		task_pid_vnr(current), \
+		__func__, \
+		##__VA_ARGS__)
+
+/* dummy function helper macro. */
+#define DUMMY_FUNCTION()	do {} while (0)
+
+#if defined(DEBUG)
+
+/* #define DEBUG_VERBOSE */
+#if defined(DEBUG_VERBOSE)
+#define MCDRV_DBG_VERBOSE		  MCDRV_DBG
+#else
+#define MCDRV_DBG_VERBOSE(...)	 DUMMY_FUNCTION()
+#endif
+
+#define MCDRV_DBG(txt, ...) \
+	printk(KERN_INFO "mcDrvKMod [%d on CPU%d] %s(): " txt, \
+		task_pid_vnr(current), \
+		raw_smp_processor_id(), \
+		__func__, \
+		##__VA_ARGS__)
+
+#define MCDRV_DBG_WARN(txt, ...) \
+	printk(KERN_WARNING "mcDrvKMod [%d] %s() WARNING: " txt, \
+		task_pid_vnr(current), \
+		__func__, \
+		##__VA_ARGS__)
+
+#define MCDRV_ASSERT(cond) \
+	do { \
+		if (unlikely(!(cond))) { \
+			panic("mcDrvKMod Assertion failed: %s:%d\n", \
+				__FILE__, __LINE__); \
+		} \
+	} while (0)
+
+#else
+
+#define MCDRV_DBG_VERBOSE(...)	DUMMY_FUNCTION()
+#define MCDRV_DBG(...)		DUMMY_FUNCTION()
+#define MCDRV_DBG_WARN(...)	DUMMY_FUNCTION()
+
+#define MCDRV_ASSERT(...)	DUMMY_FUNCTION()
+
+#endif /* [not] defined(DEBUG) */
+
+
+#endif /* _MC_DRV_KMOD_H_ */
+/** @} */
diff --git a/V008/Linux/drivers/gud/MobiCoreDriver/mcDrvModuleAndroid.h b/V008/Linux/drivers/gud/MobiCoreDriver/mcDrvModuleAndroid.h
new file mode 100644
index 0000000..d49037d
--- /dev/null
+++ b/V008/Linux/drivers/gud/MobiCoreDriver/mcDrvModuleAndroid.h
@@ -0,0 +1,33 @@
+/**
+ * Header file of MobiCore Driver Kernel Module.
+ *
+ * @addtogroup MobiCore_Driver_Kernel_Module
+ * @{
+ * Android specific defines
+ * @file
+ *
+ * Android specific defines
+ *
+ * <!-- Copyright Giesecke & Devrient GmbH 2009-2012 -->
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef _MC_DRV_MODULE_ANDROID_H_
+#define _MC_DRV_MODULE_ANDROID_H_
+
+/* Defines needed to identify the Daemon in Android systems
+ * For the full list see:
+ * platform_system_core/include/private/android_filesystem_config.h in the
+ * Android source tree
+ */
+#define AID_ROOT	0	/* traditional unix root user */
+#define AID_SYSTEM	1000	/* system server */
+#define AID_MISC	9998	/* access to misc storage */
+#define AID_NOBODY	9999
+#define AID_APP		10000	/* first app user */
+
+#endif /* _MC_DRV_MODULE_ANDROID_H_ */
+/** @} */
diff --git a/V008/Linux/drivers/gud/MobiCoreDriver/mcDrvModuleFc.h b/V008/Linux/drivers/gud/MobiCoreDriver/mcDrvModuleFc.h
new file mode 100644
index 0000000..cb9f105
--- /dev/null
+++ b/V008/Linux/drivers/gud/MobiCoreDriver/mcDrvModuleFc.h
@@ -0,0 +1,227 @@
+/**
+ * Header file of MobiCore Driver Kernel Module.
+ *
+ * @addtogroup MobiCore_Driver_Kernel_Module
+ * @{
+ * Internal structures of the McDrvModule
+ * @file
+ *
+ * MobiCore Fast Call interface
+ *
+ * <!-- Copyright Giesecke & Devrient GmbH 2009-2012 -->
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef _MC_DRV_MODULE_FC_H_
+#define _MC_DRV_MODULE_FC_H_
+
+#include "mcDrvModule.h"
+
+/**
+ * MobiCore SMCs
+ */
+enum mcSmcCodes {
+	MC_SMC_N_YIELD  = 0x3, /**< Yield to switch from NWd to SWd. */
+	MC_SMC_N_SIQ	= 0x4  /**< SIQ to switch from NWd to SWd. */
+};
+
+/**
+ * MobiCore fast calls. See MCI documentation
+ */
+enum mcFastCallCodes {
+	MC_FC_INIT	  = -1,
+	MC_FC_INFO	  = -2,
+	MC_FC_POWER	 = -3,
+	MC_FC_DUMP	  = -4,
+	MC_FC_NWD_TRACE = -31 /**< Mem trace setup fastcall */
+};
+
+/**
+ * return code for fast calls
+ */
+enum mcFastCallsResult {
+	MC_FC_RET_OK					   = 0,
+	MC_FC_RET_ERR_INVALID			  = 1,
+	MC_FC_RET_ERR_ALREADY_INITIALIZED  = 5
+};
+
+
+
+/*------------------------------------------------------------------------------
+	structure wrappers for specific fastcalls
+------------------------------------------------------------------------------*/
+
+/** generic fast call parameters */
+union fcGeneric {
+	struct {
+		uint32_t cmd;
+		uint32_t param[3];
+	} asIn;
+	struct {
+		uint32_t resp;
+		uint32_t ret;
+		uint32_t param[2];
+	} asOut;
+};
+
+
+/** fast call init */
+union mcFcInit {
+	union fcGeneric asGeneric;
+	struct {
+		uint32_t cmd;
+		uint32_t base;
+		uint32_t nqInfo;
+		uint32_t mcpInfo;
+	} asIn;
+	struct {
+		uint32_t resp;
+		uint32_t ret;
+		uint32_t rfu[2];
+	} asOut;
+};
+
+
+/** fast call info parameters */
+union mcFcInfo {
+	union fcGeneric asGeneric;
+	struct {
+		uint32_t cmd;
+		uint32_t extInfoId;
+		uint32_t rfu[2];
+	} asIn;
+	struct {
+		uint32_t resp;
+		uint32_t ret;
+		uint32_t state;
+		uint32_t extInfo;
+	} asOut;
+};
+
+
+/** fast call S-Yield parameters */
+union mcFcSYield {
+	union fcGeneric asGeneric;
+	struct {
+		uint32_t cmd;
+		uint32_t rfu[3];
+	} asIn;
+	struct {
+		uint32_t resp;
+		uint32_t ret;
+		uint32_t rfu[2];
+	} asOut;
+};
+
+
+/** fast call N-SIQ parameters */
+union mcFcNSIQ {
+	union fcGeneric asGeneric;
+	struct {
+		uint32_t cmd;
+		uint32_t rfu[3];
+	} asIn;
+	struct {
+		uint32_t resp;
+		uint32_t ret;
+		uint32_t rfu[2];
+	} asOut;
+};
+
+
+/*----------------------------------------------------------------------------*/
+/**
+ * fast call to MobiCore
+ *
+ * @param pFcGeneric pointer to fast call data
+ */
+static inline void mcFastCall(
+	union fcGeneric *pFcGeneric
+)
+{
+	MCDRV_ASSERT(pFcGeneric != NULL);
+	/* We only expect to make smc calls on CPU0 otherwise something wrong
+	 * will happen */
+	MCDRV_ASSERT(raw_smp_processor_id() == 0);
+	mb();
+#ifdef MC_SMC_FASTCALL
+	{
+		int ret = 0;
+		MCDRV_DBG("Going into SCM()");
+		ret = smc_fastcall((void *)pFcGeneric, sizeof(*pFcGeneric));
+		MCDRV_DBG("Coming from SCM, scm_call=%i, resp=%d/0x%x\n",
+			ret,
+			pFcGeneric->asOut.resp, pFcGeneric->asOut.resp);
+	}
+#else
+	{
+		/* SVC expect values in r0-r3 */
+		register u32 reg0 __asm__("r0") = pFcGeneric->asIn.cmd;
+		register u32 reg1 __asm__("r1") = pFcGeneric->asIn.param[0];
+		register u32 reg2 __asm__("r2") = pFcGeneric->asIn.param[1];
+		register u32 reg3 __asm__("r3") = pFcGeneric->asIn.param[2];
+
+		/* one of the famous preprocessor hacks to stingitize things.*/
+#define __STR2(x)   #x
+#define __STR(x)	__STR2(x)
+
+		/* compiler does not support certain instructions
+		"SMC": secure monitor call.*/
+#define ASM_ARM_SMC		 0xE1600070
+		/*   "BPKT": debugging breakpoint. We keep this, as is comes
+				quite handy for debugging. */
+#define ASM_ARM_BPKT		0xE1200070
+#define ASM_THUMB_BPKT	  0xBE00
+
+
+		__asm__ volatile (
+			".word " __STR(ASM_ARM_SMC) "\n"
+			: "+r"(reg0), "+r"(reg1), "+r"(reg2), "+r"(reg3)
+		);
+
+		/* set response */
+		pFcGeneric->asOut.resp	 = reg0;
+		pFcGeneric->asOut.ret	  = reg1;
+		pFcGeneric->asOut.param[0] = reg2;
+		pFcGeneric->asOut.param[1] = reg3;
+	}
+#endif
+}
+
+
+/*----------------------------------------------------------------------------*/
+/**
+ * convert fast call return code to linux driver module error code
+ *
+ */
+static inline int convertFcRet(
+	uint32_t sret
+)
+{
+	int		 ret = -EFAULT;
+
+	switch (sret) {
+
+	case MC_FC_RET_OK:
+		ret = 0;
+		break;
+
+	case MC_FC_RET_ERR_INVALID:
+		ret = -EINVAL;
+		break;
+
+	case MC_FC_RET_ERR_ALREADY_INITIALIZED:
+		ret = -EBUSY;
+		break;
+
+	default:
+		break;
+	} /* end switch( sret ) */
+	return ret;
+}
+
+#endif /* _MC_DRV_MODULE_FC_H_ */
+/** @} */
diff --git a/V008/Linux/drivers/gud/MobiCoreDriver/mcDrvModuleLinuxApi.h b/V008/Linux/drivers/gud/MobiCoreDriver/mcDrvModuleLinuxApi.h
new file mode 100644
index 0000000..a352785
--- /dev/null
+++ b/V008/Linux/drivers/gud/MobiCoreDriver/mcDrvModuleLinuxApi.h
@@ -0,0 +1,186 @@
+/**
+ * Header file of MobiCore Driver Kernel Module.
+ *
+ * @addtogroup MobiCore_Driver_Kernel_Module
+ * @{
+ * Wrapper for Linux API
+ * @file
+ *
+ * Some convenient wrappers for memory functions
+ *
+ * <!-- Copyright Giesecke & Devrient GmbH 2009-2012 -->
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef _MC_DRV_MODULE_LINUX_API_H_
+#define _MC_DRV_MODULE_LINUX_API_H_
+
+#include <linux/version.h>
+#include <linux/miscdevice.h>
+#include <linux/interrupt.h>
+#include <linux/highmem.h>
+#include <linux/kthread.h>
+#include <linux/io.h>
+#include <linux/uaccess.h>
+#include <asm/sizes.h>
+#include <asm/pgtable.h>
+#include <linux/semaphore.h>
+#include <linux/slab.h>
+
+
+/* make some nice types */
+#if !defined(TRUE)
+#define TRUE (1 == 1)
+#endif
+
+#if !defined(FALSE)
+#define FALSE (1 != 1)
+#endif
+
+
+/* Linux GCC modifiers */
+#if !defined(__init)
+#warning "missing definition: __init"
+/* define a dummy */
+#define __init
+#endif
+
+
+#if !defined(__exit)
+#warning "missing definition: __exit"
+/* define a dummy */
+#define __exit
+#endif
+
+
+#if !defined(__must_check)
+#warning "missing definition: __must_check"
+/* define a dummy */
+#define __must_check
+#endif
+
+
+#if !defined(__user)
+#warning "missing definition: __user"
+/* define a dummy */
+#define __user
+#endif
+
+#define INVALID_ORDER	   ((unsigned int)(-1))
+
+/*----------------------------------------------------------------------------*/
+/* get start address of the 4 KiB page where the given addres is located in. */
+static inline void *getPageStart(
+	void *addr
+)
+{
+	return (void *)(((unsigned long)(addr)) & PAGE_MASK);
+}
+
+/*----------------------------------------------------------------------------*/
+/* get offset into the 4 KiB page where the given addres is located in. */
+static inline unsigned int getOffsetInPage(
+	void *addr
+)
+{
+	return (unsigned int)(((unsigned long)(addr)) & (~PAGE_MASK));
+}
+
+/*----------------------------------------------------------------------------*/
+/* get number of pages for a given buffer. */
+static inline unsigned int getNrOfPagesForBuffer(
+	void		*addrStart, /* may be null */
+	unsigned int	len
+)
+{
+	/* calculate used number of pages. Example:
+	offset+size	newSize+PAGE_SIZE-1	nrOfPages
+	   0			  4095				   0
+	   1			  4096				   1
+	  4095			8190				   1
+	  4096			8191				   1
+	  4097			8192				   2 */
+
+	return (getOffsetInPage(addrStart) + len + PAGE_SIZE-1) / PAGE_SIZE;
+}
+
+
+/*----------------------------------------------------------------------------*/
+/**
+ * convert a given size to page order, which is equivalent to finding log_2(x).
+ * The maximum for order was 5 in Linux 2.0 corresponding to 32 pages.
+ * Later versions allow 9 corresponding to 512 pages, which is 2 MB on
+ * most platforms). Anyway, the bigger order is, the more likely it is
+ * that the allocation will fail.
+ * Size	              0   1  4097  8193  12289  24577  28673   40961   61441
+ * Pages              -   1     2     3      4      7      8      15      16
+ * Order  INVALID_ORDER   0     1     1      2      2      3       3       4
+ *
+ * @param  size
+ * @return order
+ */
+static inline unsigned int sizeToOrder(
+	unsigned int size
+)
+{
+	unsigned int order = INVALID_ORDER;
+
+	if (0 != size) {
+		/* ARMv5 as a CLZ instruction which count the leading zeros of
+		the binary representation of a value. It return a value
+		between 0 and 32.
+		Value   0   1   2   3   4   5   6   7   8   9  10 ...
+		CLZ	32  31  30  30  29  29  29  29  28  28  28 ...
+
+		We have excluded Size==0 before, so this is safe. */
+		order = __builtin_clz(
+				getNrOfPagesForBuffer(NULL, size));
+
+		/* there is a size overflow in getNrOfPagesForBuffer when
+		 * the size is too large */
+		if (unlikely(order > 31))
+			return INVALID_ORDER;
+		order = 31 - order;
+
+		/* above algorithm rounds down: clz(5)=2 instead of 3 */
+		/* quick correction to fix it: */
+		if (((1<<order)*PAGE_SIZE) < size)
+			order++;
+	}
+	return order;
+}
+
+/* magic linux macro */
+#if !defined(list_for_each_entry)
+/* stop compiler */
+#error "missing macro: list_for_each_entry()"
+/* define a dummy */
+#define list_for_each_entry(a, b, c)	if (0)
+#endif
+
+/*----------------------------------------------------------------------------*/
+/* return the page frame number of an address */
+static inline unsigned int addrToPfn(
+	void *addr
+)
+{
+	/* there is no real API for this */
+	return ((unsigned int)(addr)) >> PAGE_SHIFT;
+}
+
+
+/*----------------------------------------------------------------------------*/
+/* return the address of a page frame number */
+static inline void *pfnToAddr(
+	unsigned int pfn
+)
+{
+	/* there is no real API for this */
+	return (void *)(pfn << PAGE_SHIFT);
+}
+
+#endif /* _MC_DRV_MODULE_LINUX_API_H_ */
+/** @} */
diff --git a/V008/Linux/drivers/gud/MobiCoreDriver/platforms/MSM8960_SURF_STD/platform.h b/V008/Linux/drivers/gud/MobiCoreDriver/platforms/MSM8960_SURF_STD/platform.h
new file mode 100644
index 0000000..3abd77c
--- /dev/null
+++ b/V008/Linux/drivers/gud/MobiCoreDriver/platforms/MSM8960_SURF_STD/platform.h
@@ -0,0 +1,47 @@
+/**
+ * Header file of MobiCore Driver Kernel Module Platform
+ * specific structures
+ *
+ * @addtogroup MobiCore_Driver_Kernel_Module
+ * @{
+ * Internal structures of the McDrvModule
+ * @file
+ *
+ * Header file the MobiCore Driver Kernel Module,
+ * its internal structures and defines.
+ *
+ * <!-- Copyright Giesecke & Devrient GmbH 2009-2012 -->
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef _MC_DRV_PLATFORM_H_
+#define _MC_DRV_PLATFORM_H_
+
+/** MobiCore Interrupt for Qualcomm */
+#define MC_INTR_SSIQ						218
+
+/** Use SMC for fastcalls */
+#define MC_SMC_FASTCALL
+
+
+/*--------------- Implementation -------------- */
+#include <mach/scm.h>
+/* from following file */
+#define SCM_SVC_MOBICORE		250
+#define SCM_CMD_MOBICORE		1
+
+extern int scm_call(u32 svc_id, u32 cmd_id, const void *cmd_buf, size_t cmd_len,
+			void *resp_buf, size_t resp_len);
+
+static inline int smc_fastcall(void *pFcGeneric, size_t size)
+{
+	return scm_call(SCM_SVC_MOBICORE, SCM_CMD_MOBICORE,
+			   pFcGeneric, size,
+			   pFcGeneric, size);
+}
+
+#endif /* _MC_DRV_PLATFORM_H_ */
+/** @} */
diff --git a/V008/Linux/drivers/gud/MobiCoreDriver/public/mcDrvModuleApi.h b/V008/Linux/drivers/gud/MobiCoreDriver/public/mcDrvModuleApi.h
new file mode 100644
index 0000000..9632822
--- /dev/null
+++ b/V008/Linux/drivers/gud/MobiCoreDriver/public/mcDrvModuleApi.h
@@ -0,0 +1,307 @@
+/** @addtogroup MCD_MCDIMPL_KMOD
+ * @{
+ * Interface to Mobicore Driver Kernel Module.
+ *
+ * <h2>Introduction</h2>
+ * 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
+ * given virtual memory are also supported. IRQ functionallity receives
+ * information from the SWd in the non secure world (NWd).
+ * As customary the driver is handled as linux device driver with "open",
+ * "close" and "ioctl" commands. Access to the driver is possible after the
+ * device "/dev/mobicore" has been opened.
+ * The MobiCore Driver Kernel Module must be installed via
+ * "insmod mcDrvModule.ko".
+ *
+ *
+ * <h2>Version history</h2>
+ * <table class="customtab">
+ * <tr><td width="100px"><b>Date</b></td><td width="80px"><b>Version</b></td>
+ * <td><b>Changes</b></td></tr>
+ * <tr><td>2010-05-25</td><td>0.1</td><td>Initial Release</td></tr>
+ * </table>
+ *
+ * <!-- Copyright Giesecke & Devrient GmbH 2010-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 _MC_DRV_MODULEAPI_H_
+#define _MC_DRV_MODULEAPI_H_
+
+#include "version.h"
+
+#define MC_DRV_MOD_DEVNODE		   "mobicore"
+#define MC_DRV_MOD_DEVNODE_FULLPATH  "/dev/" MC_DRV_MOD_DEVNODE
+
+/**
+ * Data exchange structure of the MC_DRV_MODULE_INIT ioctl command.
+ * INIT request data to SWD
+ */
+union mcIoCtlInitParams {
+	struct {
+		/** base address of mci buffer 4KB align */
+		uint32_t  base;
+		/** notification buffer start/length [16:16] [start, length] */
+		uint32_t  nqOffset;
+		/** length of notification queue */
+		uint32_t  nqLength;
+		/** mcp buffer start/length [16:16] [start, length] */
+		uint32_t  mcpOffset;
+		/** length of mcp buffer */
+		uint32_t  mcpLength;
+	} in;
+	struct {
+		/* nothing */
+	} out;
+};
+
+
+/**
+ * Data exchange structure of the MC_DRV_MODULE_INFO ioctl command.
+ * INFO request data to the SWD
+ */
+union mcIoCtlInfoParams {
+	struct {
+		uint32_t  extInfoId; /**< extended info ID */
+	} in;
+	struct {
+		uint32_t  state; /**< state */
+		uint32_t  extInfo; /**< extended info */
+	} out;
+};
+
+/**
+ * Mmap allocates and maps contiguous memory into a process.
+ * We use the third parameter, void *offset, to distinguish between some cases
+ * offset = MC_DRV_KMOD_MMAP_WSM	usual operation, pages are registered in
+					device structure and freed later.
+ * offset = MC_DRV_KMOD_MMAP_MCI	get Instance of MCI, allocates or mmaps
+					the MCI to daemon
+ * offset = MC_DRV_KMOD_MMAP_PERSISTENTWSM	special operation, without
+						registration of pages
+ *
+ * In mmap(), the offset specifies which of several device I/O pages is
+ *  requested. Linux only transfers the page number, i.e. the upper 20 bits to
+ *  kernel module. Therefore we define our special offsets as multiples of page
+ *  size.
+ */
+enum mcMmapMemtype {
+	MC_DRV_KMOD_MMAP_WSM		= 0,
+	MC_DRV_KMOD_MMAP_MCI		= 4096,
+	MC_DRV_KMOD_MMAP_PERSISTENTWSM	= 8192
+};
+
+struct mcMmapResp {
+	uint32_t  handle; /**< WSN handle */
+	uint32_t  physAddr; /**< physical address of WSM (or NULL) */
+	bool	  isReused; /**< if WSM memory was reused, or new allocated */
+};
+
+/**
+ * Data exchange structure of the MC_DRV_KMOD_IOCTL_FREE ioctl command.
+ */
+union mcIoCtltoFreeParams {
+	struct {
+		uint32_t  handle; /**< driver handle */
+		uint32_t  pid; /**< process id */
+	} in;
+	struct {
+		/* nothing */
+	} out;
+};
+
+
+/**
+ * Data exchange structure of the MC_DRV_KMOD_IOCTL_APP_REGISTER_WSM_L2 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
+ * will be modified to the used values.
+ */
+union mcIoCtlAppRegWsmL2Params {
+	struct {
+		uint32_t  buffer; /**< base address of the virtual address  */
+		uint32_t  len; /**< size of the virtual address space */
+		uint32_t  pid; /**< process id */
+	} in;
+	struct {
+		uint32_t  handle; /**< driver handle for locked memory */
+		uint32_t  physWsmL2Table; /* physical address of the L2 table */
+	} out;
+};
+
+
+/**
+ * Data exchange structure of the MC_DRV_KMOD_IOCTL_APP_UNREGISTER_WSM_L2
+ * command.
+ */
+struct mcIoCtlAppUnregWsmL2Params {
+	struct {
+		uint32_t  handle; /**< driver handle for locked memory */
+		uint32_t  pid; /**< process id */
+	} in;
+	struct {
+		/* nothing */
+	} out;
+};
+
+
+/**
+ * Data exchange structure of the MC_DRV_KMOD_IOCTL_DAEMON_LOCK_WSM_L2 command.
+ */
+struct mcIoCtlDaemonLockWsmL2Params {
+	struct {
+		uint32_t  handle; /**< driver handle for locked memory */
+	} in;
+	struct {
+		uint32_t physWsmL2Table;
+	} out;
+};
+
+
+/**
+ * Data exchange structure of the MC_DRV_KMOD_IOCTL_DAEMON_UNLOCK_WSM_L2
+ * command.
+ */
+struct mcIoCtlDaemonUnlockWsmL2Params {
+	struct {
+		uint32_t  handle; /**< driver handle for locked memory */
+	} in;
+	struct {
+		/* nothing */
+	} out;
+};
+
+/**
+ * Data exchange structure of the MC_DRV_MODULE_FC_EXECUTE ioctl command.
+ */
+union mcIoCtlFcExecuteParams {
+	struct {
+		uint32_t  physStartAddr;/**< base address of mobicore binary */
+		uint32_t  length;	/**< length of DDR area */
+	} in;
+	struct {
+		/* nothing */
+	} out;
+};
+
+/**
+ * Data exchange structure of the MC_DRV_MODULE_GET_VERSION ioctl command.
+ */
+struct mcIoCtlGetVersionParams {
+	struct {
+		uint32_t	kernelModuleVersion;
+	} out;
+};
+
+/* @defgroup Mobicore_Driver_Kernel_Module_Interface IOCTL */
+
+
+
+
+/* TODO: use IOCTL macros like _IOWR. See Documentation/ioctl/ioctl-number.txt,
+	Documentation/ioctl/ioctl-decoding.txt */
+/**
+ * defines for the ioctl mobicore driver module function call from user space.
+ */
+enum mcKModIoClt {
+
+	/*
+	 * get detailed MobiCore Status
+	 */
+	MC_DRV_KMOD_IOCTL_DUMP_STATUS  = 200,
+
+	/*
+	 * initialize MobiCore
+	 */
+	MC_DRV_KMOD_IOCTL_FC_INIT  = 201,
+
+	/*
+	 * get MobiCore status
+	 */
+	MC_DRV_KMOD_IOCTL_FC_INFO  = 202,
+
+	/**
+	 * ioctl parameter to send the YIELD command to the SWD.
+	 * Only possible in Privileged Mode.
+	 * ioctl(fd, MC_DRV_MODULE_YIELD)
+	 */
+	MC_DRV_KMOD_IOCTL_FC_YIELD =  203,
+	/**
+	 * ioctl parameter to send the NSIQ signal to the SWD.
+	 * Only possible in Privileged Mode
+	 * ioctl(fd, MC_DRV_MODULE_NSIQ)
+	 */
+	MC_DRV_KMOD_IOCTL_FC_NSIQ   =  204,
+	/**
+	 * ioctl parameter to tzbsp to start Mobicore binary from DDR.
+	 * Only possible in Privileged Mode
+	 * ioctl(fd, MC_DRV_KMOD_IOCTL_FC_EXECUTE)
+	 */
+	MC_DRV_KMOD_IOCTL_FC_EXECUTE =  205,
+
+	/**
+	 * Free's memory which is formerly allocated by the driver's mmap
+	 * command. The parameter must be this mmaped address.
+	 * The internal instance data regarding to this address are deleted as
+	 * well as each according memory page and its appropriated reserved bit
+	 * is cleared (ClearPageReserved).
+	 * Usage: ioctl(fd, MC_DRV_MODULE_FREE, &address) with address beeing of
+	 * type long address
+	 */
+	MC_DRV_KMOD_IOCTL_FREE = 218,
+
+	/**
+	 * Creates a L2 Table of the given base address and the size of the
+	 * data.
+	 * Parameter: mcIoCtlAppRegWsmL2Params
+	 */
+	MC_DRV_KMOD_IOCTL_APP_REGISTER_WSM_L2 = 220,
+
+	/**
+	 * Frees the L2 table created by a MC_DRV_KMOD_IOCTL_APP_REGISTER_WSM_L2
+	 * ioctl.
+	 * Parameter: mcIoCtlAppUnRegWsmL2Params
+	 */
+	MC_DRV_KMOD_IOCTL_APP_UNREGISTER_WSM_L2 = 221,
+
+
+	/* TODO: comment this. */
+	MC_DRV_KMOD_IOCTL_DAEMON_LOCK_WSM_L2 = 222,
+	MC_DRV_KMOD_IOCTL_DAEMON_UNLOCK_WSM_L2 = 223,
+
+	/**
+	 * Return kernel driver version.
+	 * Parameter: mcIoCtlGetVersionParams
+	 */
+	MC_DRV_KMOD_IOCTL_GET_VERSION = 224,
+};
+
+
+#endif /* _MC_DRV_MODULEAPI_H_ */
+/** @} */
diff --git a/V008/Linux/drivers/gud/MobiCoreDriver/public/mcKernelApi.h b/V008/Linux/drivers/gud/MobiCoreDriver/public/mcKernelApi.h
new file mode 100644
index 0000000..e496851
--- /dev/null
+++ b/V008/Linux/drivers/gud/MobiCoreDriver/public/mcKernelApi.h
@@ -0,0 +1,96 @@
+/** @addtogroup MCD_MCDIMPL_KMOD
+ * @{
+ * Interface to Mobicore Driver Kernel Module inside Kernel.
+ *
+ * <!-- Copyright Giesecke & Devrient GmbH 2010-2012 -->
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef _MOBICORE_KERNELMODULE_API_H_
+#define _MOBICORE_KERNELMODULE_API_H_
+
+struct mcInstance;
+
+/**
+ * Initialize a new mobicore API instance object
+ *
+ * @return Instance or NULL if no allocation was possible.
+ */
+struct mcInstance *mobicore_open(
+	void
+);
+
+/**
+ * Release a mobicore instance object and all objects related to it
+ * @param pInstance instance
+ * @return 0 if Ok or -E ERROR
+ */
+int mobicore_release(
+	struct mcInstance	*pInstance
+);
+
+/**
+ * Free a WSM buffer allocated with mobicore_allocate_wsm
+ * @param pInstance
+ * @param handle		handle of the buffer
+ *
+ * @return 0 if no error
+ *
+ */
+int mobicore_allocate_wsm(
+	struct mcInstance	*pInstance,
+	unsigned long		requestedSize,
+	uint32_t		*pHandle,
+	void			**pKernelVirtAddr,
+	void			**pPhysAddr
+);
+
+/**
+ * Free a WSM buffer allocated with mobicore_allocate_wsm
+ * @param pInstance
+ * @param handle		handle of the buffer
+ *
+ * @return 0 if no error
+ *
+ */
+int mobicore_free(
+	struct mcInstance	*pInstance,
+	uint32_t		handle
+);
+
+/**
+ * Map a virtual memory buffer structure to Mobicore
+ * @param pInstance
+ * @param addr		address of the buffer(NB it must be kernel virtual!)
+ * @param len		buffer length
+ * @param pHandle	pointer to handle
+ * @param physWsmL2Table	pointer to physical L2 table(?)
+ *
+ * @return 0 if no error
+ *
+ */
+int mobicore_map_vmem(
+	struct mcInstance	*pInstance,
+	void			*addr,
+	uint32_t		len,
+	uint32_t		*pHandle,
+	void			**physWsmL2Table
+);
+
+/**
+ * Unmap a virtual memory buffer from mobicore
+ * @param pInstance
+ * @param handle
+ *
+ * @return 0 if no error
+ *
+ */
+int mobicore_unmap_vmem(
+	struct mcInstance	*pInstance,
+	uint32_t		handle
+);
+#endif /* _MOBICORE_KERNELMODULE_API_H_ */
+/** @} */
diff --git a/V008/Linux/drivers/gud/MobiCoreDriver/public/version.h b/V008/Linux/drivers/gud/MobiCoreDriver/public/version.h
new file mode 100644
index 0000000..7779a1d
--- /dev/null
+++ b/V008/Linux/drivers/gud/MobiCoreDriver/public/version.h
@@ -0,0 +1,36 @@
+/** @addtogroup MCD_MCDIMPL_KMOD
+ * @{
+ * <!-- Copyright Giesecke & Devrient GmbH 2010-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 _MC_DRV_VERSION_H_
+#define _MC_DRV_VERSION_H_
+
+#define MCDRVMODULEAPI_VERSION_MAJOR 0
+#define MCDRVMODULEAPI_VERSION_MINOR 1
+
+#endif /* _MC_DRV_VERSION_H_ */
diff --git a/V008/Linux/drivers/gud/MobiCoreKernelApi/clientlib.c b/V008/Linux/drivers/gud/MobiCoreKernelApi/clientlib.c
new file mode 100644
index 0000000..3fc65ac
--- /dev/null
+++ b/V008/Linux/drivers/gud/MobiCoreKernelApi/clientlib.c
@@ -0,0 +1,1095 @@
+/**
+ * MobiCore KernelApi module
+ *
+ * <!-- Copyright Giesecke & Devrient GmbH 2009-2012 -->
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/netlink.h>
+#include <net/sock.h>
+#include <net/net_namespace.h>
+#include <linux/list.h>
+
+#include "public/MobiCoreDriverApi.h"
+#include "public/MobiCoreDriverCmd.h"
+#include "device.h"
+#include "session.h"
+
+/* device list */
+LIST_HEAD(devices);
+
+/*----------------------------------------------------------------------------*/
+static struct mcore_device_t *resolveDeviceId(
+	uint32_t deviceId
+) {
+	struct mcore_device_t *tmp;
+	struct list_head *pos;
+
+	/* Get mcore_device_t for deviceId */
+	list_for_each(pos, &devices) {
+		tmp = list_entry(pos, struct mcore_device_t, list);
+		if (tmp->deviceId == deviceId)
+			return tmp;
+	}
+	return NULL;
+}
+
+
+/*----------------------------------------------------------------------------*/
+static void addDevice(
+	struct mcore_device_t *device
+) {
+	list_add_tail(&(device->list), &devices);
+}
+
+
+/*----------------------------------------------------------------------------*/
+static bool removeDevice(
+	uint32_t deviceId
+) {
+	struct mcore_device_t *tmp;
+	struct list_head *pos, *q;
+
+	list_for_each_safe(pos, q, &devices) {
+		tmp = list_entry(pos, struct mcore_device_t, list);
+		if (tmp->deviceId == deviceId) {
+			list_del(pos);
+			mcore_device_cleanup(tmp);
+			return true;
+		}
+	}
+	return false;
+}
+
+
+/*----------------------------------------------------------------------------*/
+enum mcResult_t mcOpenDevice(
+	uint32_t deviceId
+) {
+	enum mcResult_t mcResult = MC_DRV_OK;
+	struct connection_t *devCon = NULL;
+	/* static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; */
+
+	MCDRV_DBG_VERBOSE("===%s()===", __func__);
+
+	/* pthread_mutex_lock(&mutex); // Enter critical section */
+
+	do {
+		struct mcore_device_t *device = resolveDeviceId(deviceId);
+		if (NULL != device) {
+			MCDRV_DBG_ERROR("Device %d already opened", deviceId);
+			mcResult = MC_DRV_ERR_INVALID_OPERATION;
+			break;
+		}
+
+		/* Open new connection to device */
+		devCon = connection_new();
+		if (!connection_connect(devCon, MC_DAEMON_PID)) {
+			MCDRV_DBG_ERROR(
+				"Could not setup netlink connection to PID %u",
+				MC_DAEMON_PID);
+			mcResult = MC_DRV_ERR_DAEMON_UNREACHABLE;
+			break;
+		}
+
+		/* Forward device open to the daemon and read result */
+		struct mcDrvCmdOpenDevice_t mcDrvCmdOpenDevice = {
+			/* C++ does not support C99 designated initializers */
+			/* .header = */ {
+			/* .commandId = */ MC_DRV_CMD_OPEN_DEVICE
+			},
+		/* .payload = */ {
+		/* .deviceId = */ deviceId
+			}
+		};
+
+		int len = connection_writeData(
+					devCon,
+					&mcDrvCmdOpenDevice,
+					sizeof(struct mcDrvCmdOpenDevice_t));
+		if (len < 0) {
+			MCDRV_DBG_ERROR("CMD_OPEN_DEVICE writeCmd failed "
+				"ret=%d", len);
+			mcResult = MC_DRV_ERR_DAEMON_UNREACHABLE;
+			break;
+		}
+
+		struct mcDrvResponseHeader_t  rspHeader;
+		len = connection_readDataBlock(
+					devCon,
+					&rspHeader,
+					sizeof(rspHeader));
+		if (len != sizeof(rspHeader)) {
+			MCDRV_DBG_ERROR("CMD_OPEN_DEVICE readRsp failed "
+				"ret=%d", len);
+			mcResult = MC_DRV_ERR_DAEMON_UNREACHABLE;
+			break;
+		}
+		if (MC_DRV_RSP_OK != rspHeader.responseId) {
+			MCDRV_DBG_ERROR("CMD_OPEN_DEVICE failed, respId=%d",
+							rspHeader.responseId);
+			switch (rspHeader.responseId) {
+			case MC_DRV_RSP_PAYLOAD_LENGTH_ERROR:
+				mcResult = MC_DRV_ERR_DAEMON_UNREACHABLE;
+				break;
+			case MC_DRV_INVALID_DEVICE_NAME:
+				mcResult = MC_DRV_ERR_UNKNOWN_DEVICE;
+				break;
+			case MC_DRV_RSP_DEVICE_ALREADY_OPENED:
+			default:
+				mcResult = MC_DRV_ERR_INVALID_OPERATION;
+				break;
+			}
+			break;
+		}
+
+		/* there is no payload to read */
+
+		device = mcore_device_create(deviceId, devCon);
+		if (!mcore_device_open(device, MC_DRV_MOD_DEVNODE_FULLPATH)) {
+			mcore_device_cleanup(device);
+			MCDRV_DBG_ERROR("could not open device file: %s",
+				MC_DRV_MOD_DEVNODE_FULLPATH);
+			mcResult = MC_DRV_ERR_INVALID_DEVICE_FILE;
+			break;
+		}
+
+		addDevice(device);
+
+	} while (false);
+
+	if (mcResult != MC_DRV_OK)
+		connection_cleanup(devCon);
+
+	/* pthread_mutex_unlock(&mutex); // Exit critical section */
+
+	return mcResult;
+}
+EXPORT_SYMBOL(mcOpenDevice);
+
+/*----------------------------------------------------------------------------*/
+enum mcResult_t mcCloseDevice(
+	uint32_t deviceId
+) {
+	enum mcResult_t mcResult = MC_DRV_OK;
+	/* static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; */
+
+	MCDRV_DBG_VERBOSE("===%s()===", __func__);
+
+	/* pthread_mutex_lock(&mutex); // Enter critical section */
+	do {
+		struct mcore_device_t *device = resolveDeviceId(deviceId);
+		if (NULL == device) {
+			MCDRV_DBG_ERROR("Device not found");
+			mcResult = MC_DRV_ERR_UNKNOWN_DEVICE;
+			break;
+		}
+		struct connection_t *devCon = device->connection;
+
+		/* Return if not all sessions have been closed */
+		if (mcore_device_hasSessions(device)) {
+			MCDRV_DBG_ERROR("cannot close with sessions pending");
+			mcResult = MC_DRV_ERR_SESSION_PENDING;
+			break;
+		}
+
+		struct mcDrvCmdCloseDevice_t mcDrvCmdCloseDevice = {
+			/* C++ does not support C99 designated initializers */
+			/* .header = */ {
+				/* .commandId = */ MC_DRV_CMD_CLOSE_DEVICE
+			}
+		};
+		int len = connection_writeData(
+					devCon,
+					&mcDrvCmdCloseDevice,
+					sizeof(struct mcDrvCmdCloseDevice_t));
+		/* ignore error, but log details */
+		if (len < 0) {
+			MCDRV_DBG_ERROR("CMD_CLOSE_DEVICE writeCmd failed "
+				"ret=%d", len);
+			mcResult = MC_DRV_ERR_DAEMON_UNREACHABLE;
+		}
+
+		struct mcDrvResponseHeader_t  rspHeader;
+		len = connection_readDataBlock(
+					devCon,
+					&rspHeader,
+					sizeof(rspHeader));
+		if (len != sizeof(rspHeader)) {
+			MCDRV_DBG_ERROR("CMD_CLOSE_DEVICE readResp failed "
+				" ret=%d", len);
+			mcResult = MC_DRV_ERR_DAEMON_UNREACHABLE;
+			break;
+		}
+
+		if (MC_DRV_RSP_OK != rspHeader.responseId) {
+			MCDRV_DBG_ERROR("CMD_CLOSE_DEVICE failed, respId=%d",
+							rspHeader.responseId);
+			mcResult = MC_DRV_ERR_DAEMON_UNREACHABLE;
+			break;
+		}
+
+		removeDevice(deviceId);
+
+	} while (false);
+
+	/* pthread_mutex_unlock(&mutex); // Exit critical section */
+
+	return mcResult;
+}
+EXPORT_SYMBOL(mcCloseDevice);
+
+/*----------------------------------------------------------------------------*/
+enum mcResult_t mcOpenSession(
+	struct mcSessionHandle_t  *session,
+	const struct mcUuid_t	 *uuid,
+	uint8_t			*tci,
+	uint32_t		   len
+) {
+	enum mcResult_t mcResult = MC_DRV_OK;
+	/* static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; */
+
+	MCDRV_DBG_VERBOSE("===%s()===", __func__);
+
+	/* pthread_mutex_lock(&mutex); // Enter critical section */
+
+	do {
+		if (NULL == session) {
+			MCDRV_DBG_ERROR("Session is null");
+			mcResult = MC_DRV_ERR_INVALID_PARAMETER;
+			break;
+		}
+		if (NULL == uuid) {
+			MCDRV_DBG_ERROR("UUID is null");
+			mcResult = MC_DRV_ERR_INVALID_PARAMETER;
+			break;
+		}
+		if (NULL == tci) {
+			MCDRV_DBG_ERROR("TCI is null");
+			mcResult = MC_DRV_ERR_INVALID_PARAMETER;
+			break;
+		}
+		if (len > MC_MAX_TCI_LEN) {
+			MCDRV_DBG_ERROR("TCI length is longer than %d",
+				MC_MAX_TCI_LEN);
+			mcResult = MC_DRV_ERR_INVALID_PARAMETER;
+			break;
+		}
+
+		/* Get the device associated with the given session */
+		struct mcore_device_t *device =
+				resolveDeviceId(session->deviceId);
+		if (NULL == device) {
+			MCDRV_DBG_ERROR("Device not found");
+			mcResult = MC_DRV_ERR_UNKNOWN_DEVICE;
+			break;
+		}
+		struct connection_t *devCon = device->connection;
+
+		/* Get the physical address of the given TCI */
+		struct wsm_t *pWsm =
+			mcore_device_findContiguousWsm(device, tci);
+		if (NULL == pWsm) {
+			MCDRV_DBG_ERROR("Could not resolve TCI phy address ");
+			mcResult = MC_DRV_ERR_INVALID_PARAMETER;
+			break;
+		}
+
+		if (pWsm->len < len) {
+			MCDRV_DBG_ERROR("length is more than allocated TCI");
+			mcResult = MC_DRV_ERR_INVALID_PARAMETER;
+			break;
+		}
+
+		/* Prepare open session command */
+		struct mcDrvCmdOpenSession_t cmdOpenSession = {
+			/* C++ does not support C99 designated initializers */
+			/* .header = */ {
+				/* .commandId = */ MC_DRV_CMD_OPEN_SESSION
+			},
+			/* .payload = */ {
+				/* .deviceId = */ session->deviceId,
+				/* .uuid = */ *uuid,
+				/* .tci = */ (uint32_t)pWsm->physAddr,
+				/* .len = */ len
+			}
+		};
+
+		/* Transmit command data */
+
+		int len = connection_writeData(
+						devCon,
+						&cmdOpenSession,
+						sizeof(cmdOpenSession));
+		if (sizeof(cmdOpenSession) != len) {
+			MCDRV_DBG_ERROR("CMD_OPEN_SESSION writeData failed "
+				"ret=%d", len);
+			mcResult = MC_DRV_ERR_DAEMON_UNREACHABLE;
+			break;
+		}
+
+		/* Read command response */
+
+		/* read header first */
+		struct mcDrvResponseHeader_t rspHeader;
+		len = connection_readDataBlock(
+					devCon,
+					&rspHeader,
+					sizeof(rspHeader));
+		if (sizeof(rspHeader) != len) {
+			MCDRV_DBG_ERROR("CMD_OPEN_SESSION readResp failed "
+				" ret=%d", len);
+			mcResult = MC_DRV_ERR_DAEMON_UNREACHABLE;
+			break;
+		}
+
+		if (MC_DRV_RSP_OK != rspHeader.responseId) {
+			MCDRV_DBG_ERROR("CMD_OPEN_SESSION failed, respId=%d",
+							rspHeader.responseId);
+			switch (rspHeader.responseId) {
+			case MC_DRV_RSP_TRUSTLET_NOT_FOUND:
+				mcResult = MC_DRV_ERR_INVALID_DEVICE_FILE;
+				break;
+			case MC_DRV_RSP_PAYLOAD_LENGTH_ERROR:
+			case MC_DRV_RSP_DEVICE_NOT_OPENED:
+			case MC_DRV_RSP_FAILED:
+			default:
+				mcResult = MC_DRV_ERR_DAEMON_UNREACHABLE;
+				break;
+			}
+			break;
+		}
+
+		/* read payload */
+		struct mcDrvRspOpenSessionPayload_t rspOpenSessionPayload;
+		len = connection_readDataBlock(
+					devCon,
+					&rspOpenSessionPayload,
+					sizeof(rspOpenSessionPayload));
+		if (sizeof(rspOpenSessionPayload) != len) {
+			MCDRV_DBG_ERROR("CMD_OPEN_SESSION readPayload failed "
+				"ret=%d", len);
+			mcResult = MC_DRV_ERR_DAEMON_UNREACHABLE;
+			break;
+		}
+
+		/* Register session with handle */
+		session->sessionId = rspOpenSessionPayload.sessionId;
+
+		/* Set up second channel for notifications */
+		struct connection_t *sessionConnection = connection_new();
+		/*TODO: no real need to connect here? */
+		if (!connection_connect(sessionConnection, MC_DAEMON_PID)) {
+			MCDRV_DBG_ERROR(
+				"Could not setup netlink connection to PID %u",
+				MC_DAEMON_PID);
+			connection_cleanup(sessionConnection);
+			mcResult = MC_DRV_ERR_DAEMON_UNREACHABLE;
+			break;
+		}
+
+		/*TODO CONTINOUE HERE !!!! FIX RW RETURN HANDLING!!!! */
+
+		/* Write command to use channel for notifications */
+		struct mcDrvCmdNqConnect_t cmdNqConnect = {
+			/* C++ does not support C99 designated initializers */
+			/* .header = */ {
+				/* .commandId = */ MC_DRV_CMD_NQ_CONNECT
+			},
+			/* .payload = */ {
+				/* .deviceId =  */ session->deviceId,
+				/* .sessionId = */ session->sessionId,
+				/* .deviceSessionId = */
+					rspOpenSessionPayload.deviceSessionId,
+				/* .sessionMagic = */
+					rspOpenSessionPayload.sessionMagic
+			}
+		};
+		connection_writeData(sessionConnection,
+			&cmdNqConnect,
+			sizeof(cmdNqConnect));
+
+		/* Read command response, header first */
+		len = connection_readDataBlock(
+					sessionConnection,
+					&rspHeader,
+					sizeof(rspHeader));
+		if (sizeof(rspHeader) != len) {
+			MCDRV_DBG_ERROR("CMD_NQ_CONNECT readRsp failed "
+				"ret=%d", len);
+			connection_cleanup(sessionConnection);
+			mcResult = MC_DRV_ERR_DAEMON_UNREACHABLE;
+			break;
+		}
+
+		if (MC_DRV_RSP_OK != rspHeader.responseId) {
+			MCDRV_DBG_ERROR("CMD_NQ_CONNECT failed, respId=%d",
+					rspHeader.responseId);
+			connection_cleanup(sessionConnection);
+			mcResult = MC_DRV_ERR_NQ_FAILED;
+			break;
+		}
+
+		/* there is no payload. */
+
+		/* Session established, new session object must be created */
+		mcore_device_createNewSession(
+			device,
+			session->sessionId,
+			sessionConnection);
+
+	} while (false);
+
+	/*pthread_mutex_unlock(&mutex); // Exit critical section */
+
+	return mcResult;
+}
+EXPORT_SYMBOL(mcOpenSession);
+
+/*----------------------------------------------------------------------------*/
+enum mcResult_t mcCloseSession(
+	struct mcSessionHandle_t *session
+) {
+	enum mcResult_t mcResult = MC_DRV_OK;
+	/* static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; */
+
+	MCDRV_DBG_VERBOSE("===%s()===", __func__);
+
+	/* pthread_mutex_lock(&mutex); // Enter critical section */
+
+	do {
+		if (NULL == session) {
+			MCDRV_DBG_ERROR("Session is null");
+			mcResult = MC_DRV_ERR_INVALID_PARAMETER;
+			break;
+		}
+
+		struct mcore_device_t  *device =
+					resolveDeviceId(session->deviceId);
+		if (NULL == device) {
+			MCDRV_DBG_ERROR("Device not found");
+			mcResult = MC_DRV_ERR_UNKNOWN_DEVICE;
+			break;
+		}
+		struct connection_t  *devCon = device->connection;
+
+		struct session_t  *nqSession =
+		 mcore_device_resolveSessionId(device, session->sessionId);
+		if (NULL == nqSession) {
+			MCDRV_DBG_ERROR("Session not found");
+			mcResult = MC_DRV_ERR_UNKNOWN_SESSION;
+			break;
+		}
+
+		/* Write close session command */
+		struct mcDrvCmdCloseSession_t cmdCloseSession = {
+			/* C++ does not support C99 designated initializers */
+			/* .header = */ {
+				/* .commandId = */ MC_DRV_CMD_CLOSE_SESSION
+			},
+			/* .payload = */ {
+				/* .sessionId = */ session->sessionId,
+			}
+		};
+		connection_writeData(
+			devCon,
+			&cmdCloseSession,
+			sizeof(cmdCloseSession));
+
+		/* Read command response */
+		struct mcDrvResponseHeader_t rspHeader;
+		int len = connection_readDataBlock(
+						devCon,
+						&rspHeader,
+						sizeof(rspHeader));
+		if (sizeof(rspHeader) != len) {
+			MCDRV_DBG_ERROR("CMD_CLOSE_SESSION readRsp failed "
+				"ret=%d", len);
+			mcResult = MC_DRV_ERR_DAEMON_UNREACHABLE;
+			break;
+		}
+
+		if (MC_DRV_RSP_OK != rspHeader.responseId) {
+			MCDRV_DBG_ERROR("CMD_CLOSE_SESSION failed, respId=%d",
+							rspHeader.responseId);
+			mcResult = MC_DRV_ERR_UNKNOWN_DEVICE;
+			break;
+		}
+
+		mcore_device_removeSession(device, session->sessionId);
+		mcResult = MC_DRV_OK;
+
+	} while (false);
+
+	/* pthread_mutex_unlock(&mutex); // Exit critical section */
+
+	return mcResult;
+}
+EXPORT_SYMBOL(mcCloseSession);
+
+/*----------------------------------------------------------------------------*/
+enum mcResult_t mcNotify(
+	struct mcSessionHandle_t   *session
+) {
+	enum mcResult_t mcResult = MC_DRV_OK;
+
+	MCDRV_DBG_VERBOSE("===%s()===", __func__);
+
+	do {
+		if (NULL == session) {
+			MCDRV_DBG_ERROR("Session is null");
+			mcResult = MC_DRV_ERR_INVALID_PARAMETER;
+			break;
+		}
+
+		struct mcore_device_t *device =
+					resolveDeviceId(session->deviceId);
+		if (NULL == device) {
+			MCDRV_DBG_ERROR("Device not found");
+			mcResult = MC_DRV_ERR_UNKNOWN_DEVICE;
+			break;
+		}
+		struct connection_t *devCon = device->connection;
+
+		struct session_t  *nqsession =
+		 mcore_device_resolveSessionId(device, session->sessionId);
+		if (NULL == nqsession) {
+			MCDRV_DBG_ERROR("Session not found");
+			mcResult = MC_DRV_ERR_UNKNOWN_SESSION;
+			break;
+		}
+
+		struct mcDrvCmdNotify_t cmdNotify = {
+			/* C++ does not support C99 designated initializers */
+			/* .header = */ {
+				/* .commandId = */ MC_DRV_CMD_NOTIFY
+			},
+			/* .payload = */ {
+				/* .sessionId = */ session->sessionId,
+			}
+		};
+
+		connection_writeData(
+			devCon,
+			&cmdNotify,
+			sizeof(cmdNotify));
+
+		/* Daemon will not return a response */
+
+	} while (false);
+
+	return mcResult;
+}
+EXPORT_SYMBOL(mcNotify);
+
+/*----------------------------------------------------------------------------*/
+enum mcResult_t mcWaitNotification(
+	struct mcSessionHandle_t  *session,
+	int32_t			timeout
+) {
+	enum mcResult_t mcResult = MC_DRV_OK;
+
+	MCDRV_DBG_VERBOSE("===%s()===", __func__);
+
+	do {
+		if (NULL == session) {
+			mcResult = MC_DRV_ERR_INVALID_PARAMETER;
+			break;
+		}
+
+		struct mcore_device_t  *device =
+					resolveDeviceId(session->deviceId);
+		if (NULL == device) {
+			MCDRV_DBG_ERROR("Device not found");
+			mcResult = MC_DRV_ERR_UNKNOWN_DEVICE;
+			break;
+		}
+
+		struct session_t  *nqSession =
+		 mcore_device_resolveSessionId(device, session->sessionId);
+		if (NULL == nqSession) {
+			MCDRV_DBG_ERROR("Session not found");
+			mcResult = MC_DRV_ERR_UNKNOWN_SESSION;
+			break;
+		}
+
+		struct connection_t *nqconnection =
+					nqSession->notificationConnection;
+		uint32_t count = 0;
+
+		/* Read notification queue till it's empty */
+		for (;;) {
+			struct notification_t notification;
+			ssize_t numRead = connection_readData(
+				nqconnection,
+				&notification,
+				sizeof(notification),
+				timeout);
+			/* Exit on timeout in first run. Later runs have
+			 * timeout set to 0.
+			 * -2 means, there is no more data. */
+			if (0 == count && -2 == numRead) {
+				MCDRV_DBG_ERROR("read timeout");
+				mcResult = MC_DRV_ERR_TIMEOUT;
+				break;
+			}
+			/* After first notification the queue will be
+			 * drained, Thus we set no timeout for the
+			 * following reads */
+			timeout = 0;
+
+			if (numRead != sizeof(struct notification_t)) {
+				if (0 == count) {
+					/* failure in first read, notify it */
+					mcResult = MC_DRV_ERR_NOTIFICATION;
+					MCDRV_DBG_ERROR(
+					"read notification failed, "
+					"%i bytes received", (int)numRead);
+					break;
+				} else {
+					/* Read of the n-th notification
+					   failed/timeout. We don't tell the
+					   caller, as we got valid notifications
+					   before. */
+					mcResult = MC_DRV_OK;
+					break;
+				}
+			}
+
+			count++;
+			MCDRV_DBG_VERBOSE("readNq count=%d, SessionID=%d, "
+				"Payload=%d", count,
+				notification.sessionId, notification.payload);
+
+			if (0 != notification.payload) {
+				/* Session end point died -> store exit code */
+				session_setErrorInfo(nqSession,
+					notification.payload);
+
+				mcResult = MC_DRV_INFO_NOTIFICATION;
+				break;
+			}
+		} /* for(;;) */
+
+	} while (false);
+
+	return mcResult;
+}
+EXPORT_SYMBOL(mcWaitNotification);
+
+/*----------------------------------------------------------------------------*/
+enum mcResult_t mcMallocWsm(
+	uint32_t	deviceId,
+	uint32_t	align,
+	uint32_t	len,
+	uint8_t	 **wsm,
+	uint32_t	wsmFlags
+) {
+	enum mcResult_t mcResult = MC_DRV_ERR_UNKNOWN;
+	/* static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; */
+
+	MCDRV_DBG_VERBOSE("===%s()===", __func__);
+
+	/* pthread_mutex_lock(&mutex); */
+
+	do {
+		struct mcore_device_t *device = resolveDeviceId(deviceId);
+		if (NULL == device) {
+			MCDRV_DBG_ERROR("Device not found");
+			mcResult = MC_DRV_ERR_UNKNOWN_DEVICE;
+			break;
+		}
+		if (NULL == wsm) {
+			mcResult = MC_DRV_ERR_INVALID_PARAMETER;
+			break;
+		}
+
+		struct wsm_t *pWsm =
+			mcore_device_allocateContiguousWsm(device, len);
+		if (NULL == pWsm) {
+			MCDRV_DBG_ERROR("Allocation of WSM failed");
+			mcResult = MC_DRV_ERR_NO_FREE_MEMORY;
+			break;
+		}
+
+		*wsm = (uint8_t *)pWsm->virtAddr;
+		mcResult = MC_DRV_OK;
+
+	} while (false);
+
+	/* pthread_mutex_unlock(&mutex); // Exit critical section */
+
+	return mcResult;
+}
+EXPORT_SYMBOL(mcMallocWsm);
+
+/*----------------------------------------------------------------------------*/
+enum mcResult_t mcFreeWsm(
+	uint32_t	deviceId,
+	uint8_t	 *wsm
+) {
+	enum mcResult_t mcResult = MC_DRV_ERR_UNKNOWN;
+	struct mcore_device_t *device;
+
+	/* static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; */
+
+	MCDRV_DBG_VERBOSE("===%s()===", __func__);
+
+	/* pthread_mutex_lock(&mutex); // Enter critical section */
+
+	do {
+
+		/* Get the device associated wit the given session */
+		device = resolveDeviceId(deviceId);
+		if (NULL == device) {
+			MCDRV_DBG_ERROR("Device not found");
+			mcResult = MC_DRV_ERR_UNKNOWN_DEVICE;
+			break;
+		}
+
+		/* find WSM object */
+		struct wsm_t *pWsm =
+			mcore_device_findContiguousWsm(device, wsm);
+		if (NULL == pWsm) {
+			MCDRV_DBG_ERROR("unknown address");
+			mcResult = MC_DRV_ERR_INVALID_PARAMETER;
+			break;
+		}
+
+		/* Free the given virtual address */
+		if (!mcore_device_freeContiguousWsm(device, pWsm)) {
+			MCDRV_DBG_ERROR("Free of virtual address failed");
+			mcResult = MC_DRV_ERR_FREE_MEMORY_FAILED;
+			break;
+		}
+		mcResult = MC_DRV_OK;
+
+	} while (false);
+
+	/* pthread_mutex_unlock(&mutex); // Exit critical section */
+
+	return mcResult;
+}
+EXPORT_SYMBOL(mcFreeWsm);
+
+/*----------------------------------------------------------------------------*/
+enum mcResult_t mcMap(
+	struct mcSessionHandle_t  *sessionHandle,
+	void			   *buf,
+	uint32_t		   bufLen,
+	struct mcBulkMap_t		*mapInfo
+) {
+	enum mcResult_t mcResult = MC_DRV_ERR_UNKNOWN;
+	/* static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; */
+
+	MCDRV_DBG_VERBOSE("===%s()===", __func__);
+
+	/* pthread_mutex_lock(&mutex); // Enter critical section */
+
+	do {
+		if (NULL == sessionHandle) {
+			MCDRV_DBG_ERROR("sessionHandle is null");
+			mcResult = MC_DRV_ERR_INVALID_PARAMETER;
+			break;
+		}
+		if (NULL == mapInfo) {
+			MCDRV_DBG_ERROR("mapInfo is null");
+			mcResult = MC_DRV_ERR_INVALID_PARAMETER;
+			break;
+		}
+		if (NULL == buf) {
+			MCDRV_DBG_ERROR("buf is null");
+			mcResult = MC_DRV_ERR_INVALID_PARAMETER;
+			break;
+		}
+
+		/* Determine device the session belongs to */
+		struct mcore_device_t  *device = resolveDeviceId(
+						sessionHandle->deviceId);
+		if (NULL == device) {
+			MCDRV_DBG_ERROR("Device not found");
+			mcResult = MC_DRV_ERR_UNKNOWN_DEVICE;
+			break;
+		}
+		struct connection_t *devCon = device->connection;
+
+		/* Get session */
+		struct session_t  *session =
+		mcore_device_resolveSessionId(device, sessionHandle->sessionId);
+		if (NULL == session) {
+			MCDRV_DBG_ERROR("Session not found");
+			mcResult = MC_DRV_ERR_UNKNOWN_SESSION;
+			break;
+		}
+
+		/* Register mapped bulk buffer to Kernel Module and keep mapped
+		   bulk buffer in mind */
+		struct bulkBufferDescriptor_t *bulkBuf = session_addBulkBuf(
+			session, buf, bufLen);
+		if (NULL == bulkBuf) {
+			MCDRV_DBG_ERROR("Error mapping bulk buffer");
+			mcResult = MC_DRV_ERR_BULK_MAPPING;
+			break;
+		}
+
+		/* Prepare map command */
+		struct mcDrvCmdMapBulkMem_t mcDrvCmdMapBulkMem = {
+			/* C++ does not support C99 designated initializers */
+			/* .header = */ {
+				/* .commandId = */ MC_DRV_CMD_MAP_BULK_BUF
+			},
+			/* .payload = */ {
+				/* .sessionId = */ session->sessionId,
+				/* .pAddrL2 = */
+					(uint32_t)bulkBuf->physAddrWsmL2,
+				/* .offsetPayload = */
+					(uint32_t)(bulkBuf->virtAddr) & 0xFFF,
+				/* .lenBulkMem = */ bulkBuf->len
+			}
+		};
+
+		/* Transmit map command to MobiCore device */
+		connection_writeData(
+			devCon,
+			&mcDrvCmdMapBulkMem,
+			sizeof(mcDrvCmdMapBulkMem));
+
+		/* Read command response */
+		struct mcDrvResponseHeader_t rspHeader;
+		int len = connection_readDataBlock(
+						devCon,
+						&rspHeader,
+						sizeof(rspHeader));
+		if (sizeof(rspHeader) != len) {
+			MCDRV_DBG_ERROR("CMD_MAP_BULK_BUF readRsp failed, "
+				"ret=%d", len);
+			mcResult = MC_DRV_ERR_DAEMON_UNREACHABLE;
+			break;
+		}
+
+		if (MC_DRV_RSP_OK != rspHeader.responseId) {
+			MCDRV_DBG_ERROR("CMD_MAP_BULK_BUF failed, respId=%d",
+							rspHeader.responseId);
+			/* REV We ignore Daemon Error code because client cannot
+			   handle it anyhow. */
+			mcResult = MC_DRV_ERR_DAEMON_UNREACHABLE;
+
+			/* Unregister mapped bulk buffer from Kernel Module and
+			   remove mapped bulk buffer from session maintenance */
+			if (!session_removeBulkBuf(session, buf)) {
+				/* Removing of bulk buffer not possible */
+				MCDRV_DBG_ERROR("Unregistering of bulk memory"
+					"from Kernel Module failed");
+			}
+			break;
+		}
+
+		struct mcDrvRspMapBulkMemPayload_t rspMapBulkMemPayload;
+		connection_readDataBlock(
+			devCon,
+			&rspMapBulkMemPayload,
+			sizeof(rspMapBulkMemPayload));
+
+		/* Set mapping info for Trustlet */
+		mapInfo->sVirtualAddr =
+			(void *)(rspMapBulkMemPayload.secureVirtualAdr);
+		mapInfo->sVirtualLen = bufLen;
+		mcResult = MC_DRV_OK;
+
+	} while (false);
+
+	/* pthread_mutex_unlock(&mutex); // Exit critical section */
+
+	return mcResult;
+}
+EXPORT_SYMBOL(mcMap);
+
+/*----------------------------------------------------------------------------*/
+enum mcResult_t mcUnmap(
+	struct mcSessionHandle_t  *sessionHandle,
+	void			   *buf,
+	struct mcBulkMap_t		*mapInfo
+) {
+	enum mcResult_t mcResult = MC_DRV_ERR_UNKNOWN;
+	/* static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; */
+
+	MCDRV_DBG_VERBOSE("===%s()===", __func__);
+
+	/* pthread_mutex_lock(&mutex); // Enter critical section */
+
+	do {
+		if (NULL == sessionHandle) {
+			MCDRV_DBG_ERROR("sessionHandle is null");
+			mcResult = MC_DRV_ERR_INVALID_PARAMETER;
+			break;
+		}
+		if (NULL == mapInfo) {
+			MCDRV_DBG_ERROR("mapInfo is null");
+			mcResult = MC_DRV_ERR_INVALID_PARAMETER;
+			break;
+		}
+		if (NULL == buf) {
+			MCDRV_DBG_ERROR("buf is null");
+			mcResult = MC_DRV_ERR_INVALID_PARAMETER;
+			break;
+		}
+
+		/* Determine device the session belongs to */
+		struct mcore_device_t  *device =
+			resolveDeviceId(sessionHandle->deviceId);
+		if (NULL == device) {
+			MCDRV_DBG_ERROR("Device not found");
+			mcResult = MC_DRV_ERR_UNKNOWN_DEVICE;
+			break;
+		}
+		struct connection_t  *devCon = device->connection;
+
+		/* Get session */
+		struct session_t  *session =
+		mcore_device_resolveSessionId(device, sessionHandle->sessionId);
+		if (NULL == session) {
+			MCDRV_DBG_ERROR("Session not found");
+			mcResult = MC_DRV_ERR_UNKNOWN_SESSION;
+			break;
+		}
+
+		/* Prepare unmap command */
+		struct mcDrvCmdUnmapBulkMem_t cmdUnmapBulkMem = {
+				/* .header = */ {
+					/* .commandId = */
+						MC_DRV_CMD_UNMAP_BULK_BUF
+				},
+				/* .payload = */ {
+					/* .sessionId = */ session->sessionId,
+					/* .secureVirtualAdr = */
+					(uint32_t)(mapInfo->sVirtualAddr),
+					/* .lenBulkMem = mapInfo->sVirtualLen*/
+				}
+			};
+
+		connection_writeData(
+			devCon,
+			&cmdUnmapBulkMem,
+			sizeof(cmdUnmapBulkMem));
+
+		/* Read command response */
+		struct mcDrvResponseHeader_t rspHeader;
+		int len = connection_readDataBlock(
+						devCon,
+						&rspHeader,
+						sizeof(rspHeader));
+		if (sizeof(rspHeader) != len) {
+			MCDRV_DBG_ERROR("CMD_UNMAP_BULK_BUF readRsp failed, "
+				"ret=%d", len);
+			mcResult = MC_DRV_ERR_DAEMON_UNREACHABLE;
+			break;
+		}
+
+		if (MC_DRV_RSP_OK != rspHeader.responseId) {
+			MCDRV_DBG_ERROR("CMD_UNMAP_BULK_BUF failed, respId=%d",
+							rspHeader.responseId);
+			/* REV We ignore Daemon Error code because client
+			   cannot handle it anyhow. */
+			mcResult = MC_DRV_ERR_DAEMON_UNREACHABLE;
+			break;
+		}
+
+		struct mcDrvRspUnmapBulkMemPayload_t rspUnmapBulkMemPayload;
+		connection_readDataBlock(
+			devCon,
+			&rspUnmapBulkMemPayload,
+			sizeof(rspUnmapBulkMemPayload));
+
+		/* REV axh: what about check the payload? */
+
+		/* Unregister mapped bulk buffer from Kernel Module and
+		 * remove mapped bulk buffer from session maintenance */
+		if (!session_removeBulkBuf(session, buf)) {
+			/* Removing of bulk buffer not possible */
+			MCDRV_DBG_ERROR("Unregistering of bulk memory from "
+							"Kernel Module failed");
+			mcResult = MC_DRV_ERR_BULK_UNMAPPING;
+			break;
+		}
+
+		mcResult = MC_DRV_OK;
+
+	} while (false);
+
+	/* pthread_mutex_unlock(&mutex); // Exit critical section */
+
+	return mcResult;
+}
+EXPORT_SYMBOL(mcUnmap);
+
+/*----------------------------------------------------------------------------*/
+enum mcResult_t mcGetSessionErrorCode(
+	struct mcSessionHandle_t   *session,
+	int32_t			 *lastErr
+) {
+	enum mcResult_t mcResult = MC_DRV_OK;
+
+	MCDRV_DBG_VERBOSE("===%s()===", __func__);
+
+	do {
+		if (NULL == session || NULL == lastErr) {
+			mcResult = MC_DRV_ERR_INVALID_PARAMETER;
+			break;
+		}
+
+		/* Get device */
+		struct mcore_device_t *device =
+					resolveDeviceId(session->deviceId);
+		if (NULL == device) {
+			MCDRV_DBG_ERROR("Device not found");
+			mcResult = MC_DRV_ERR_UNKNOWN_DEVICE;
+			break;
+		}
+
+		/* Get session */
+		struct session_t *nqsession =
+		 mcore_device_resolveSessionId(device, session->sessionId);
+		if (NULL == nqsession) {
+			MCDRV_DBG_ERROR("Session not found");
+			mcResult = MC_DRV_ERR_UNKNOWN_SESSION;
+			break;
+		}
+
+		/* get session error code from session */
+		*lastErr = session_getLastErr(nqsession);
+
+	} while (false);
+
+	return mcResult;
+}
+EXPORT_SYMBOL(mcGetSessionErrorCode);
+
+/*----------------------------------------------------------------------------*/
+enum mcResult_t mcDriverCtrl(
+	enum mcDriverCtrl_t  param,
+	uint8_t		 *data,
+	uint32_t		len
+) {
+	MCDRV_DBG_WARN("not implemented");
+	return MC_DRV_ERR_NOT_IMPLEMENTED;
+}
+EXPORT_SYMBOL(mcDriverCtrl);
+
+/*----------------------------------------------------------------------------*/
+enum mcResult_t mcManage(
+	uint32_t  deviceId,
+	uint8_t   *data,
+	uint32_t  len
+) {
+	MCDRV_DBG_WARN("not implemented");
+	return MC_DRV_ERR_NOT_IMPLEMENTED;
+}
+EXPORT_SYMBOL(mcManage);
+
diff --git a/V008/Linux/drivers/gud/MobiCoreKernelApi/common.h b/V008/Linux/drivers/gud/MobiCoreKernelApi/common.h
new file mode 100644
index 0000000..4e1e170
--- /dev/null
+++ b/V008/Linux/drivers/gud/MobiCoreKernelApi/common.h
@@ -0,0 +1,97 @@
+/**
+ *
+ * Common data types
+ *
+ * <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef COMMON_H
+#define COMMON_H
+
+#include "connection.h"
+#include "mcinq.h"
+
+void mcapi_insert_connection(
+	struct connection_t *connection
+);
+
+void mcapi_remove_connection(
+	uint32_t seq
+);
+
+unsigned int mcapi_unique_id(
+	void
+);
+
+
+#define MC_DAEMON_PID 0xFFFFFFFF
+#define MC_DRV_MOD_DEVNODE_FULLPATH "/dev/mobicore"
+
+/* dummy function helper macro. */
+#define DUMMY_FUNCTION()	do {} while (0)
+
+#define MCDRV_ERROR(txt, ...) \
+	printk(KERN_ERR "mcKernelApi %s() ### ERROR: " txt, \
+		__func__, \
+		##__VA_ARGS__)
+
+#if defined(DEBUG)
+
+/* #define DEBUG_VERBOSE */
+#if defined(DEBUG_VERBOSE)
+#define MCDRV_DBG_VERBOSE		  MCDRV_DBG
+#else
+#define MCDRV_DBG_VERBOSE(...)	 DUMMY_FUNCTION()
+#endif
+
+#define MCDRV_DBG(txt, ...) \
+	printk(KERN_INFO "mcKernelApi %s(): " txt, \
+		__func__, \
+		##__VA_ARGS__)
+
+#define MCDRV_DBG_WARN(txt, ...) \
+	printk(KERN_WARNING "mcKernelApi %s() WARNING: " txt, \
+		__func__, \
+		##__VA_ARGS__)
+
+#define MCDRV_DBG_ERROR(txt, ...) \
+	printk(KERN_ERR "mcKernelApi %s() ### ERROR: " txt, \
+		__func__, \
+		##__VA_ARGS__)
+
+
+#define MCDRV_ASSERT(cond) \
+	do { \
+		if (unlikely(!(cond))) { \
+			panic("mcKernelApi Assertion failed: %s:%d\n", \
+				__FILE__, __LINE__); \
+		} \
+	} while (0)
+
+#elif defined(NDEBUG)
+
+#define MCDRV_DBG_VERBOSE(...)	DUMMY_FUNCTION()
+#define MCDRV_DBG(...)		DUMMY_FUNCTION()
+#define MCDRV_DBG_WARN(...)	DUMMY_FUNCTION()
+#define MCDRV_DBG_ERROR(...)	DUMMY_FUNCTION()
+
+#define MCDRV_ASSERT(...)	DUMMY_FUNCTION()
+
+#else
+#error "Define DEBUG or NDEBUG"
+#endif /* [not] defined(DEBUG_MCMODULE) */
+
+
+#define LOG_I MCDRV_DBG_VERBOSE
+#define LOG_W MCDRV_DBG_WARN
+#define LOG_E MCDRV_DBG_ERROR
+
+
+#define assert(expr) MCDRV_ASSERT(expr)
+
+#endif /* COMMON_H */
+
+/** @} */
diff --git a/V008/Linux/drivers/gud/MobiCoreKernelApi/connection.c b/V008/Linux/drivers/gud/MobiCoreKernelApi/connection.c
new file mode 100644
index 0000000..79b641c
--- /dev/null
+++ b/V008/Linux/drivers/gud/MobiCoreKernelApi/connection.c
@@ -0,0 +1,229 @@
+/** @addtogroup MCD_MCDIMPL_DAEMON_SRV
+ * @{
+ * @file
+ *
+ * Connection data.
+ *
+ * <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/netlink.h>
+#include <linux/skbuff.h>
+#include <linux/netlink.h>
+#include <linux/semaphore.h>
+#include <linux/time.h>
+#include <net/sock.h>
+#include <net/net_namespace.h>
+
+#include "connection.h"
+#include "common.h"
+
+/* Define the initial state of the Data Available Semaphore */
+#define SEM_NO_DATA_AVAILABLE 0
+
+/*----------------------------------------------------------------------------*/
+struct connection_t *connection_new(
+	void
+) {
+	struct connection_t *conn = kzalloc(sizeof(struct connection_t),
+					GFP_KERNEL);
+	conn->sequenceMagic = mcapi_unique_id();
+	mutex_init(&conn->dataLock);
+	/* No data available */
+	sema_init(&conn->dataAvailableSem, SEM_NO_DATA_AVAILABLE);
+
+	mcapi_insert_connection(conn);
+	return conn;
+}
+
+/*----------------------------------------------------------------------------*/
+struct connection_t *connection_create(
+	int	 socketDescriptor,
+	pid_t   dest
+) {
+	struct connection_t *conn = connection_new();
+
+	conn->peerPid = dest;
+	return conn;
+}
+
+
+/*----------------------------------------------------------------------------*/
+void connection_cleanup(
+	struct connection_t *conn
+) {
+	if (!conn)
+		return;
+
+	kfree_skb(conn->skb);
+
+	mcapi_remove_connection(conn->sequenceMagic);
+	kfree(conn);
+}
+
+
+/*----------------------------------------------------------------------------*/
+bool connection_connect(
+	struct connection_t *conn,
+	pid_t		dest
+) {
+	/* Nothing to connect */
+	conn->peerPid = dest;
+	return true;
+}
+
+/*----------------------------------------------------------------------------*/
+size_t connection_readDataMsg(
+	struct connection_t *conn,
+	void *buffer,
+	uint32_t len
+) {
+	size_t ret = -1;
+	MCDRV_DBG_VERBOSE("reading connection data %u, connection data left %u",
+			len, conn->dataLen);
+	/* trying to read more than the left data */
+	if (len > conn->dataLen) {
+		ret = conn->dataLen;
+		memcpy(buffer, conn->dataStart, conn->dataLen);
+		conn->dataLen = 0;
+	} else {
+		ret = len;
+		memcpy(buffer, conn->dataStart, len);
+		conn->dataLen -= len;
+		conn->dataStart += len;
+	}
+
+	if (conn->dataLen == 0)	{
+		conn->dataStart = NULL;
+		kfree_skb(conn->skb);
+		conn->skb = NULL;
+	}
+	MCDRV_DBG_VERBOSE("read %u",  ret);
+	return ret;
+}
+
+/*----------------------------------------------------------------------------*/
+size_t connection_readDataBlock(
+	struct connection_t *conn,
+	void		 *buffer,
+	uint32_t	 len
+) {
+	return connection_readData(conn, buffer, len, -1);
+}
+
+
+/*----------------------------------------------------------------------------*/
+size_t connection_readData(
+	struct connection_t *conn,
+	void		 *buffer,
+	uint32_t	 len,
+	int32_t	  timeout
+) {
+	size_t ret = 0;
+
+	MCDRV_ASSERT(NULL != buffer);
+	MCDRV_ASSERT(NULL != conn->socketDescriptor);
+
+	MCDRV_DBG_VERBOSE("read data len = %u for PID = %u",
+						len, conn->sequenceMagic);
+	do {
+		/* Wait until data is available or timeout
+		   msecs_to_jiffies(-1) -> wait forever for the sem */
+		if (down_timeout(&(conn->dataAvailableSem),
+				  msecs_to_jiffies(timeout))) {
+			MCDRV_DBG_VERBOSE("Timeout reading the data sem");
+			ret = -2;
+			break;
+		}
+
+		if (mutex_lock_interruptible(&(conn->dataLock))) {
+			MCDRV_DBG_ERROR("interrupted reading the data sem");
+			ret = -1;
+			break;
+		}
+		/* Have data, use it */
+		if (conn->dataLen > 0)
+			ret = connection_readDataMsg(conn, buffer, len);
+
+			mutex_unlock(&(conn->dataLock));
+
+		/* There is still some data left */
+		if (conn->dataLen > 0)
+			up(&conn->dataAvailableSem);
+	} while (0);
+
+	return ret;
+}
+
+/*----------------------------------------------------------------------------*/
+size_t connection_writeData(
+	struct connection_t *conn,
+	void		 *buffer,
+	uint32_t	 len
+) {
+	struct sk_buff *skb = NULL;
+	struct nlmsghdr *nlh;
+	int ret = 0;
+
+	MCDRV_DBG_VERBOSE("buffer length %u from pid %u\n",
+		  len,  conn->sequenceMagic);
+	do {
+		skb = nlmsg_new(NLMSG_SPACE(len), GFP_KERNEL);
+		if (!skb) {
+			ret = -1;
+			break;
+		}
+
+		nlh = nlmsg_put(skb, 0, conn->sequenceMagic, 2,
+					  NLMSG_LENGTH(len), NLM_F_REQUEST);
+		if (!nlh) {
+			ret = -1;
+			break;
+		}
+		memcpy(NLMSG_DATA(nlh), buffer, len);
+
+		netlink_unicast(conn->socketDescriptor, skb,
+						conn->peerPid, MSG_DONTWAIT);
+		ret = len;
+	} while (0);
+
+	if (!ret && skb != NULL)
+		kfree_skb(skb);
+
+	return ret;
+}
+
+int connection_process(
+	struct connection_t *conn,
+	struct sk_buff *skb
+)
+{
+	int ret = 0;
+	do {
+		if (mutex_lock_interruptible(&(conn->dataLock))) {
+			MCDRV_DBG_ERROR("Interrupted getting data semaphore!");
+			ret = -1;
+			break;
+		}
+
+		kfree_skb(conn->skb);
+
+		/* Get a reference to the incomming skb */
+		conn->skb = skb_get(skb);
+		if (conn->skb) {
+			conn->dataMsg = nlmsg_hdr(conn->skb);
+			conn->dataLen = NLMSG_PAYLOAD(conn->dataMsg, 0);
+			conn->dataStart = NLMSG_DATA(conn->dataMsg);
+			up(&(conn->dataAvailableSem));
+		}
+		mutex_unlock(&(conn->dataLock));
+		ret = 0;
+	} while (0);
+	return ret;
+}
+/** @} */
diff --git a/V008/Linux/drivers/gud/MobiCoreKernelApi/connection.h b/V008/Linux/drivers/gud/MobiCoreKernelApi/connection.h
new file mode 100644
index 0000000..5a5dcb1
--- /dev/null
+++ b/V008/Linux/drivers/gud/MobiCoreKernelApi/connection.h
@@ -0,0 +1,122 @@
+/** @addtogroup MCD_MCDIMPL_DAEMON_SRV
+ * @{
+ * @file
+ *
+ * Connection data.
+ *
+ * <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef CONNECTION_H_
+#define CONNECTION_H_
+
+#include <linux/semaphore.h>
+
+#include <stddef.h>
+#include <stdbool.h>
+
+#define MAX_PAYLOAD_SIZE 128
+
+struct connection_t {
+	struct sock *socketDescriptor; /**< Netlink socket */
+	uint32_t sequenceMagic; /**< Random? magic to match requests/answers */
+
+	struct nlmsghdr *dataMsg;
+	uint32_t dataLen; /**< How much connection data is left */
+	void *dataStart; /**< Start pointer of remaining data */
+	struct sk_buff *skb;
+
+	struct mutex dataLock; /**< Data protection lock */
+	struct semaphore dataAvailableSem; /**< Data protection semaphore */
+
+	pid_t selfPid; /**< PID address used for local connection */
+	pid_t peerPid; /**< Remote PID for connection */
+
+	struct list_head list; /**< The list param for using the kernel lists*/
+};
+
+struct connection_t *connection_new(
+	void
+);
+
+struct connection_t *connection_create(
+	int		  socketDescriptor,
+	pid_t		dest
+);
+
+void connection_cleanup(
+	struct connection_t *conn
+);
+
+/**
+  * Connect to destination.
+  *
+  * @param Destination pointer.
+  * @return true on success.
+  */
+bool connection_connect(
+	struct connection_t *conn,
+	pid_t		dest
+);
+
+
+/**
+  * Read bytes from the connection.
+  *
+  * @param buffer	Pointer to destination buffer.
+  * @param len	   Number of bytes to read.
+  * @return Number of bytes read.
+  */
+size_t connection_readDataBlock(
+	struct connection_t *conn,
+	void		 *buffer,
+	uint32_t	 len
+);
+/**
+  * Read bytes from the connection.
+  *
+  * @param buffer	Pointer to destination buffer.
+  * @param len	   Number of bytes to read.
+  * @param timeout   Timeout in milliseconds
+  * @return Number of bytes read.
+  * @return -1 if select() failed (returned -1)
+  * @return -2 if no data available, i.e. timeout
+  */
+size_t connection_readData(
+	struct connection_t *conn,
+	void		 *buffer,
+	uint32_t	 len,
+	int32_t	  timeout
+);
+
+/**
+  * Write bytes to the connection.
+  *
+  * @param buffer	Pointer to source buffer.
+  * @param len		Number of bytes to read.
+  * @return Number of bytes written.
+  */
+size_t connection_writeData(
+	struct connection_t *conn,
+	void		 *buffer,
+	uint32_t	  len
+);
+
+/**
+ * Write bytes to the connection.
+ *
+ * @param buffer	Pointer to source buffer.
+ * @param len		Number of bytes to read.
+ * @return Number of bytes written.
+ */
+int connection_process(
+	struct connection_t *conn,
+	struct sk_buff *skb
+);
+
+#endif /* CONNECTION_H_ */
+
+/** @} */
diff --git a/V008/Linux/drivers/gud/MobiCoreKernelApi/device.c b/V008/Linux/drivers/gud/MobiCoreKernelApi/device.c
new file mode 100644
index 0000000..dd3c4ae
--- /dev/null
+++ b/V008/Linux/drivers/gud/MobiCoreKernelApi/device.c
@@ -0,0 +1,257 @@
+/** @addtogroup MCD_IMPL_LIB
+ * @{
+ * @file
+ *
+ * Client library device management.
+ *
+ * Device and Trustlet Session management Funtions.
+ *
+ * <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/list.h>
+#include <linux/slab.h>
+#include "mcKernelApi.h"
+#include "public/MobiCoreDriverApi.h"
+
+#include "device.h"
+#include "common.h"
+
+/*----------------------------------------------------------------------------*/
+struct wsm_t *wsm_create(
+	void	*virtAddr,
+	uint32_t  len,
+	uint32_t  handle,
+	void	*physAddr /*= NULL this may be unknown, so is can be omitted.*/
+	)
+{
+	struct wsm_t *pWsm = kzalloc(sizeof(struct wsm_t), GFP_KERNEL);
+	pWsm->virtAddr = virtAddr;
+	pWsm->len = len;
+	pWsm->handle = handle;
+	pWsm->physAddr = physAddr;
+	return pWsm;
+}
+
+
+/*----------------------------------------------------------------------------*/
+struct mcore_device_t *mcore_device_create(
+	uint32_t  deviceId,
+	struct connection_t  *connection
+) {
+	struct mcore_device_t *dev =
+			kzalloc(sizeof(struct mcore_device_t), GFP_KERNEL);
+	dev->deviceId = deviceId;
+	dev->connection = connection;
+
+	INIT_LIST_HEAD(&dev->sessionVector);
+	INIT_LIST_HEAD(&dev->wsmL2Vector);
+
+	return dev;
+}
+
+
+/*----------------------------------------------------------------------------*/
+void mcore_device_cleanup(
+	struct mcore_device_t *dev
+) {
+	struct session_t *tmp;
+	struct wsm_t *pWsm;
+	struct list_head *pos, *q;
+
+	/* Delete all session objects. Usually this should not be needed
+	 * as closeDevice()requires that all sessions have been closed before.*/
+	list_for_each_safe(pos, q, &dev->sessionVector) {
+		tmp = list_entry(pos, struct session_t, list);
+		list_del(pos);
+		session_cleanup(tmp);
+	}
+
+	/* Free all allocated WSM descriptors */
+	list_for_each_safe(pos, q, &dev->wsmL2Vector) {
+		pWsm = list_entry(pos, struct wsm_t, list);
+		/* mcKMod_free(dev->pInstance, pWsm->handle); */
+		list_del(pos);
+		kfree(pWsm);
+	}
+	connection_cleanup(dev->connection);
+
+	mcore_device_close(dev);
+	kfree(dev);
+}
+
+
+/*----------------------------------------------------------------------------*/
+bool mcore_device_open(
+	struct mcore_device_t   *dev,
+	const char *deviceName
+) {
+	dev->pInstance = mobicore_open();
+	return (dev->pInstance != NULL);
+}
+
+
+/*----------------------------------------------------------------------------*/
+void mcore_device_close(
+	struct mcore_device_t *dev
+) {
+	mobicore_release(dev->pInstance);
+}
+
+
+/*----------------------------------------------------------------------------*/
+bool mcore_device_hasSessions(
+	struct mcore_device_t *dev
+) {
+	return !list_empty(&dev->sessionVector);
+}
+
+
+/*----------------------------------------------------------------------------*/
+bool mcore_device_createNewSession(
+	struct mcore_device_t	  *dev,
+	uint32_t	  sessionId,
+	struct connection_t  *connection
+) {
+	/* Check if sessionId already exists */
+	if (mcore_device_resolveSessionId(dev, sessionId)) {
+		MCDRV_DBG_ERROR(" session %u already exists", sessionId);
+		return false;
+	}
+	struct session_t *session = session_create(sessionId, dev->pInstance,
+				connection);
+	list_add_tail(&(session->list), &(dev->sessionVector));
+	return true;
+}
+
+
+/*----------------------------------------------------------------------------*/
+bool mcore_device_removeSession(
+	struct mcore_device_t *dev,
+	uint32_t sessionId
+) {
+	bool ret = false;
+	struct session_t *tmp;
+	struct list_head *pos, *q;
+
+	list_for_each_safe(pos, q, &dev->sessionVector) {
+		tmp = list_entry(pos, struct session_t, list);
+		if (tmp->sessionId == sessionId) {
+			list_del(pos);
+			session_cleanup(tmp);
+			ret = true;
+			break;
+		}
+	}
+	return ret;
+}
+
+
+/*----------------------------------------------------------------------------*/
+struct session_t *mcore_device_resolveSessionId(
+	struct mcore_device_t *dev,
+	uint32_t sessionId
+) {
+	struct session_t  *ret = NULL;
+	struct session_t *tmp;
+	struct list_head *pos;
+
+
+	/* Get session_t for sessionId */
+	list_for_each(pos, &dev->sessionVector) {
+		tmp = list_entry(pos, struct session_t, list);
+		if (tmp->sessionId == sessionId) {
+			ret = tmp;
+			break;
+		}
+	}
+	return ret;
+}
+
+
+/*----------------------------------------------------------------------------*/
+struct wsm_t *mcore_device_allocateContiguousWsm(
+	struct mcore_device_t *dev,
+	uint32_t len
+) {
+	struct wsm_t *pWsm = NULL;
+	do {
+		if (0 == len)
+			break;
+
+		/* Allocate shared memory */
+		void	*virtAddr;
+		uint32_t  handle;
+		void	*physAddr;
+		int ret = mobicore_allocate_wsm(dev->pInstance,
+								len,
+								&handle,
+								&virtAddr,
+								&physAddr);
+		if (0 != ret)
+			break;
+
+		/* Register (vaddr,paddr) with device */
+		pWsm = wsm_create(virtAddr, len, handle, physAddr);
+
+		list_add_tail(&(pWsm->list), &(dev->wsmL2Vector));
+
+	} while (0);
+
+	/* Return pointer to the allocated memory */
+	return pWsm;
+}
+
+
+/*----------------------------------------------------------------------------*/
+bool mcore_device_freeContiguousWsm(
+	struct mcore_device_t  *dev,
+	struct wsm_t   *pWsm
+) {
+	bool ret = false;
+	struct wsm_t *tmp;
+	struct list_head *pos;
+
+	list_for_each(pos, &dev->wsmL2Vector) {
+		tmp = list_entry(pos, struct wsm_t, list);
+		if (tmp == pWsm) {
+			ret = true;
+			break;
+		}
+	}
+
+	if (ret) {
+		MCDRV_DBG_VERBOSE("freeWsm virtAddr=0x%p, handle=%d",
+				pWsm->virtAddr, pWsm->handle);
+
+		/* ignore return code */
+		mobicore_free(dev->pInstance, pWsm->handle);
+
+		list_del(pos);
+		kfree(pWsm);
+	}
+	return ret;
+}
+
+
+/*----------------------------------------------------------------------------*/
+struct wsm_t *mcore_device_findContiguousWsm(
+	struct mcore_device_t *dev,
+	void   *virtAddr
+) {
+	struct wsm_t *pWsm;
+	struct list_head *pos;
+
+	list_for_each(pos, &dev->wsmL2Vector) {
+		pWsm = list_entry(pos, struct wsm_t, list);
+		if (virtAddr == pWsm->virtAddr)
+			return pWsm;
+	}
+
+	return NULL;
+}
+
+/** @} */
diff --git a/V008/Linux/drivers/gud/MobiCoreKernelApi/device.h b/V008/Linux/drivers/gud/MobiCoreKernelApi/device.h
new file mode 100644
index 0000000..a439814
--- /dev/null
+++ b/V008/Linux/drivers/gud/MobiCoreKernelApi/device.h
@@ -0,0 +1,139 @@
+/** @addtogroup MCD_IMPL_LIB
+ * @{
+ * @file
+ *
+ * Client library device management.
+ *
+ * Device and Trustlet Session management Functions.
+ *
+ * <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef DEVICE_H_
+#define DEVICE_H_
+
+#include <linux/list.h>
+
+#include "connection.h"
+#include "session.h"
+#include "wsm.h"
+
+
+struct mcore_device_t {
+	struct list_head sessionVector; /**< MobiCore Trustlet session
+				associated with the device */
+	struct list_head	 wsmL2Vector; /**< WSM L2 Table  */
+
+	uint32_t		deviceId; /**< Device identifier */
+	struct connection_t	*connection; /**< The device connection */
+	struct mcInstance  *pInstance; /**< MobiCore Driver instance */
+
+	struct list_head list; /**< The list param for using the kernel lists*/
+};
+
+struct mcore_device_t *mcore_device_create(
+	uint32_t	  deviceId,
+	struct connection_t  *connection
+);
+
+void mcore_device_cleanup(
+	struct mcore_device_t *dev
+);
+
+/**
+  * Open the device.
+  * @param deviceName Name of the kernel modules device file.
+  * @return true if the device has been opened successfully
+  */
+bool mcore_device_open(
+	struct mcore_device_t   *dev,
+	const char *deviceName
+);
+
+/**
+  * Closes the device.
+  */
+void mcore_device_close(
+	struct mcore_device_t *dev
+);
+
+/**
+  * Check if the device has open sessions.
+  * @return true if the device has one or more open sessions.
+  */
+bool mcore_device_hasSessions(
+	struct mcore_device_t *dev
+);
+
+/**
+  * Add a session to the device.
+  * @param sessionId session ID
+  * @param connection session connection
+  */
+bool mcore_device_createNewSession(
+	struct mcore_device_t	  *dev,
+	uint32_t	sessionId,
+	struct connection_t  *connection
+);
+
+/**
+  * Remove the specified session from the device.
+  * The session object will be destroyed and all resources associated with it
+  * will be freed.
+  *
+  * @param sessionId Session of the session to remove.
+  * @return true if a session has been found and removed.
+  */
+bool mcore_device_removeSession(
+	struct mcore_device_t *dev,
+	uint32_t sessionId
+);
+
+/**
+  * Get as session object for a given session ID.
+  * @param sessionId Identified of a previously opened session.
+  * @return Session object if available or NULL if no session has been found.
+  */
+struct session_t *mcore_device_resolveSessionId(
+	struct mcore_device_t *dev,
+	uint32_t sessionId
+);
+
+/**
+  * Allocate a block of contiguous WSM.
+  * @param len The virtual address to be registered.
+  * @return The virtual address of the allocated memory or NULL if no memory
+  * is available.
+  */
+struct wsm_t *mcore_device_allocateContiguousWsm(
+	struct mcore_device_t *dev,
+	uint32_t len
+);
+
+/**
+  * Unregister a vaddr from a device.
+  * @param vaddr The virtual address to be registered.
+  * @param paddr The physical address to be registered.
+  */
+bool mcore_device_freeContiguousWsm(
+	struct mcore_device_t  *dev,
+	struct wsm_t *pWsm
+);
+
+/**
+  * Get a WSM object for a given virtual address.
+  * @param vaddr The virtual address which has been allocate with mcMallocWsm()
+  * in advance.
+  * @return the WSM object or NULL if no address has been found.
+  */
+struct wsm_t *mcore_device_findContiguousWsm(
+	struct mcore_device_t *dev,
+	void   *virtAddr
+);
+
+#endif /* DEVICE_H_ */
+
+/** @} */
diff --git a/V008/Linux/drivers/gud/MobiCoreKernelApi/include/mcUuid.h b/V008/Linux/drivers/gud/MobiCoreKernelApi/include/mcUuid.h
new file mode 100644
index 0000000..9b393bf
--- /dev/null
+++ b/V008/Linux/drivers/gud/MobiCoreKernelApi/include/mcUuid.h
@@ -0,0 +1,74 @@
+/**
+ * @addtogroup MC_UUID mcUuid - Universally Unique Identifier.
+ *
+ * <!-- Copyright Giesecke & Devrient GmbH 2011-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.
+ *
+ * @ingroup  MC_DATA_TYPES
+ * @{
+ */
+
+#ifndef MC_UUID_H_
+#define MC_UUID_H_
+
+#define UUID_TYPE
+
+/** Universally Unique Identifier (UUID) according to ISO/IEC 11578. */
+struct mcUuid_t {
+	uint8_t value[16]; /**< Value of the UUID. */
+};
+
+/** UUID value used as free marker in service provider containers. */
+#define MC_UUID_FREE_DEFINE \
+	{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \
+	  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }
+
+static const struct mcUuid_t MC_UUID_FREE = {
+	MC_UUID_FREE_DEFINE
+};
+
+/** Reserved UUID. */
+#define MC_UUID_RESERVED_DEFINE \
+	{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
+	  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
+
+static const struct mcUuid_t MC_UUID_RESERVED = {
+	MC_UUID_RESERVED_DEFINE
+};
+
+/** UUID for system applications. */
+#define MC_UUID_SYSTEM_DEFINE \
+	{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \
+	  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE }
+
+static const struct mcUuid_t MC_UUID_SYSTEM = {
+	MC_UUID_SYSTEM_DEFINE
+};
+
+#endif /* MC_UUID_H_ */
+
+/** @} */
+
diff --git a/V008/Linux/drivers/gud/MobiCoreKernelApi/include/mcinq.h b/V008/Linux/drivers/gud/MobiCoreKernelApi/include/mcinq.h
new file mode 100644
index 0000000..8e7fd2d
--- /dev/null
+++ b/V008/Linux/drivers/gud/MobiCoreKernelApi/include/mcinq.h
@@ -0,0 +1,125 @@
+/** @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 -->
+ *
+ * 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 NQ_H_
+#define NQ_H_
+
+/** \name NQ Size Defines
+ * Minimum and maximum count of elements in the notification queue.
+ * @{ */
+#define MIN_NQ_ELEM 1   /**< Minimum notification queue elements. */
+#define MAX_NQ_ELEM 64 /**< Maximum notification queue elements. */
+/** @} */
+
+/** \name NQ Length Defines
+ * Minimum and maximum notification queue length.
+ * @{ */
+/**< Minimum notification length (in bytes). */
+#define MIN_NQ_LEN (MIN_NQ_ELEM * sizeof(notification_t))
+/**< Maximum notification length (in bytes). */
+#define MAX_NQ_LEN (MAX_NQ_ELEM * sizeof(notification_t))
+/** @} */
+
+/** \name Session ID Defines
+ * Standard Session IDs.
+ * @{ */
+/**< MCP session ID is used when directly communicating with the MobiCore
+ * (e.g. for starting and stopping of trustlets). */
+#define SID_MCP	   0
+/**< Invalid session id is returned in case of an error. */
+#define SID_INVALID   0xffffffff
+/** @} */
+
+/** Notification data structure. */
+struct notification_t {
+	uint32_t sessionId; /**< Session ID. */
+	int32_t payload;	/**< Additional notification information. */
+};
+
+/** Notification payload codes.
+ * 0 indicated a plain simple notification,
+ * a positive value is a termination reason from the task,
+ * a negative value is a termination reason from MobiCore.
+ * Possible negative values are given below.
+ */
+enum notificationPayload_t {
+	/**< task terminated, but exit code is invalid */
+	ERR_INVALID_EXIT_CODE   = -1,
+	/**< task terminated due to session end, no exit code available */
+	ERR_SESSION_CLOSE	   = -2,
+	/**< task terminated due to invalid operation */
+	ERR_INVALID_OPERATION   = -3,
+	/**< session ID is unknown */
+	ERR_INVALID_SID		 = -4,
+	/**<  session is not active */
+	ERR_SID_NOT_ACTIVE	  = -5
+};
+
+/** Declaration of the notification queue header.
+ * layout as specified in the data structure specification.
+ */
+struct notificationQueueHeader_t {
+	uint32_t writeCnt;  /**< Write counter. */
+	uint32_t readCnt;   /**< Read counter. */
+	uint32_t queueSize; /**< Queue size. */
+};
+
+/** Queue struct which defines a queue object.
+ * The queue struct is accessed by the queue<operation> type of
+ * function. elementCnt must be a power of two and the power needs
+ * to be smaller than power of uint32_t (obviously 32).
+ */
+struct notificationQueue_t {
+	/**< Queue header. */
+	struct notificationQueueHeader_t hdr;
+	/**< Notification elements. */
+	struct notification_t notification[MIN_NQ_ELEM];
+} ;
+
+#endif /** NQ_H_ */
+
+/** @} */
diff --git a/V008/Linux/drivers/gud/MobiCoreKernelApi/main.c b/V008/Linux/drivers/gud/MobiCoreKernelApi/main.c
new file mode 100644
index 0000000..38cc99d
--- /dev/null
+++ b/V008/Linux/drivers/gud/MobiCoreKernelApi/main.c
@@ -0,0 +1,181 @@
+/**
+ * MobiCore KernelApi module
+ *
+ * <!-- Copyright Giesecke & Devrient GmbH 2009-2012 -->
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/netlink.h>
+#include <linux/kthread.h>
+#include <net/sock.h>
+
+#include <linux/list.h>
+
+#include "connection.h"
+#include "common.h"
+
+#define MC_DAEMON_NETLINK  17
+
+struct mcKernelApiCtx {
+	struct sock *sk;
+	struct list_head peers;
+	atomic_t counter;
+};
+
+struct mcKernelApiCtx *modCtx; /* = NULL; */
+
+/*----------------------------------------------------------------------------*/
+/* get a unique ID */
+unsigned int mcapi_unique_id(
+	void
+)
+{
+	return (unsigned int)atomic_inc_return(
+		&(modCtx->counter));
+}
+
+
+/*----------------------------------------------------------------------------*/
+static struct connection_t *mcapi_find_connection(
+	uint32_t seq
+)
+{
+	struct connection_t *tmp;
+	struct list_head *pos;
+
+	/* Get session_t for sessionId */
+	list_for_each(pos, &modCtx->peers) {
+		tmp = list_entry(pos, struct connection_t, list);
+		if (tmp->sequenceMagic == seq)
+			return tmp;
+	}
+
+	return NULL;
+}
+
+/*----------------------------------------------------------------------------*/
+void mcapi_insert_connection(
+	struct connection_t *connection
+)
+{
+	list_add_tail(&(connection->list), &(modCtx->peers));
+	connection->socketDescriptor = modCtx->sk;
+}
+
+void mcapi_remove_connection(
+	uint32_t seq
+)
+{
+	struct connection_t *tmp;
+	struct list_head *pos, *q;
+
+	/* Delete all session objects. Usually this should not be needed as
+	   closeDevice() requires that all sessions have been closed before.*/
+	list_for_each_safe(pos, q, &modCtx->peers) {
+		tmp = list_entry(pos, struct connection_t, list);
+		if (tmp->sequenceMagic == seq) {
+			list_del(pos);
+			break;
+		}
+	}
+}
+
+/*----------------------------------------------------------------------------*/
+static int mcapi_process(
+	struct sk_buff *skb,
+	struct nlmsghdr *nlh
+)
+{
+	struct connection_t *c;
+	int length;
+	int seq;
+	pid_t pid;
+	int ret;
+
+	pid = nlh->nlmsg_pid;
+	length = nlh->nlmsg_len;
+	seq = nlh->nlmsg_seq;
+	MCDRV_DBG_VERBOSE("nlmsg len %d type %d pid 0x%X seq %d\n",
+		   length, nlh->nlmsg_type, pid, seq);
+	do {
+		c = mcapi_find_connection(seq);
+		if (!c) {
+			MCDRV_ERROR("Invalid incomming connection - seq=%u!",
+				seq);
+			ret = -1;
+			break;
+		}
+
+		/* Pass the buffer to the appropriate connection */
+		connection_process(c, skb);
+
+		ret = 0;
+	} while (false);
+	return ret;
+}
+
+/*----------------------------------------------------------------------------*/
+static void mcapi_callback(
+	struct sk_buff *skb
+)
+{
+	struct nlmsghdr *nlh = nlmsg_hdr(skb);
+	int len = skb->len;
+	int err = 0;
+
+	while (NLMSG_OK(nlh, len)) {
+		err = mcapi_process(skb, nlh);
+
+		/* if err or if this message says it wants a response */
+		if (err || (nlh->nlmsg_flags & NLM_F_ACK))
+			netlink_ack(skb, nlh, err);
+
+		nlh = NLMSG_NEXT(nlh, len);
+	}
+}
+
+/*----------------------------------------------------------------------------*/
+static int __init mcapi_init(void)
+{
+	printk(KERN_INFO "Mobicore API module initialized!\n");
+
+	modCtx = kzalloc(sizeof(struct mcKernelApiCtx), GFP_KERNEL);
+
+	/* start kernel thread */
+	modCtx->sk = netlink_kernel_create(&init_net, MC_DAEMON_NETLINK, 0,
+					mcapi_callback, NULL, THIS_MODULE);
+
+	if (!modCtx->sk) {
+		MCDRV_ERROR("register of recieve handler failed");
+		return -EFAULT;
+	}
+
+	INIT_LIST_HEAD(&modCtx->peers);
+	return 0;
+}
+
+static void __exit mcapi_exit(void)
+{
+	printk(KERN_INFO "Unloading Mobicore API module.\n");
+
+	if (modCtx->sk != NULL) {
+		netlink_kernel_release(modCtx->sk);
+		modCtx->sk = NULL;
+	}
+	kfree(modCtx);
+	modCtx = NULL;
+}
+
+module_init(mcapi_init);
+module_exit(mcapi_exit);
+
+MODULE_AUTHOR("Giesecke & Devrient GmbH");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("MobiCore API driver");
diff --git a/V008/Linux/drivers/gud/MobiCoreKernelApi/public/MobiCoreDriverApi.h b/V008/Linux/drivers/gud/MobiCoreKernelApi/public/MobiCoreDriverApi.h
new file mode 100644
index 0000000..e75d52a
--- /dev/null
+++ b/V008/Linux/drivers/gud/MobiCoreKernelApi/public/MobiCoreDriverApi.h
@@ -0,0 +1,483 @@
+/**
+ * @defgroup MCD_API					MobiCore Driver API
+ * @addtogroup MCD_API
+ * @{
+ *
+ * @if DOXYGEN_MCDRV_API
+ *   @mainpage MobiCore Driver API.
+ * @endif
+ *
+ * MobiCore Driver API.
+ *
+ * The MobiCore (MC) Driver API provides access functions to the MobiCore
+ * runtime environment and the contained Trustlets.
+ *
+ * @image html DoxyOverviewDrvApi500x.png
+ * @image latex DoxyOverviewDrvApi500x.png "MobiCore Overview" width=12cm
+ *
+ * <!-- 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 MCDRIVER_H_
+#define MCDRIVER_H_
+
+#define __MC_CLIENT_LIB_API
+
+#include "mcUuid.h"
+
+/**
+ * Return values of MobiCore driver functions.
+ */
+enum mcResult_t {
+	/**< Function call succeeded. */
+	MC_DRV_OK		= 0,
+	/**< No notification available. */
+	MC_DRV_NO_NOTIFICATION	= 1,
+	/**< Error during notification on communication level. */
+	MC_DRV_ERR_NOTIFICATION	= 2,
+	/**< Function not implemented. */
+	MC_DRV_ERR_NOT_IMPLEMENTED = 3,
+	/**< No more resources available. */
+	MC_DRV_ERR_OUT_OF_RESOURCES = 4,
+	/**< Driver initialization failed. */
+	MC_DRV_ERR_INIT = 5,
+	/**< Unknown error. */
+	MC_DRV_ERR_UNKNOWN	= 6,
+	/**< The specified device is unknown. */
+	MC_DRV_ERR_UNKNOWN_DEVICE = 7,
+	/**< The specified session is unknown.*/
+	MC_DRV_ERR_UNKNOWN_SESSION = 8,
+	/**< The specified operation is not allowed. */
+	MC_DRV_ERR_INVALID_OPERATION = 9,
+	/**< The response header from the MC is invalid. */
+	MC_DRV_ERR_INVALID_RESPONSE = 10,
+	/**< Function call timed out. */
+	MC_DRV_ERR_TIMEOUT = 11,
+	/**< Can not allocate additional memory. */
+	MC_DRV_ERR_NO_FREE_MEMORY = 12,
+	/**< Free memory failed. */
+	MC_DRV_ERR_FREE_MEMORY_FAILED = 13,
+	/**< Still some open sessions pending. */
+	MC_DRV_ERR_SESSION_PENDING = 14,
+	/**< MC daemon not reachable */
+	MC_DRV_ERR_DAEMON_UNREACHABLE = 15,
+	/**< The device file of the kernel module could not be opened. */
+	MC_DRV_ERR_INVALID_DEVICE_FILE = 16,
+	/**< Invalid parameter. */
+	MC_DRV_ERR_INVALID_PARAMETER	= 17,
+	/**< Unspecified error from Kernel Module*/
+	MC_DRV_ERR_KERNEL_MODULE = 18,
+	/**< Error during mapping of additional bulk memory to session. */
+	MC_DRV_ERR_BULK_MAPPING = 19,
+	/**< Error during unmapping of additional bulk memory to session. */
+	MC_DRV_ERR_BULK_UNMAPPING = 20,
+	/**< Notification received, exit code available. */
+	MC_DRV_INFO_NOTIFICATION = 21,
+	/**< Set up of NWd connection failed. */
+	MC_DRV_ERR_NQ_FAILED = 22
+};
+
+
+/**
+ * Driver control command.
+ */
+enum mcDriverCtrl_t {
+	MC_CTRL_GET_VERSION = 1 /**< Return the driver version */
+};
+
+
+/** 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.
+ */
+struct mcSessionHandle_t {
+	uint32_t sessionId; /**< MobiCore session ID */
+	uint32_t deviceId; /**< Device ID the session belongs to */
+};
+
+/** 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 the content of this structure via the TCI.
+ */
+struct mcBulkMap_t {
+	/**< The virtual address of the Bulk buffer regarding the address space
+	 * of the Trustlet, already includes a possible offset! */
+	void *sVirtualAddr;
+	uint32_t sVirtualLen; /**< Length of the mapped Bulk buffer */
+};
+
+
+/**< The default device ID */
+#define MC_DEVICE_ID_DEFAULT	0
+/**< Wait infinite for a response of the MC. */
+#define MC_INFINITE_TIMEOUT	((int32_t)(-1))
+/**< Do not wait for a response of the MC. */
+#define MC_NO_TIMEOUT		0
+/**< TCI/DCI must not exceed 1MiB */
+#define MC_MAX_TCI_LEN		0x100000
+
+
+
+/** Open a new connection to a MobiCore 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 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.
+ *
+ * @return MC_DRV_OK if operation has been successfully completed.
+ * @return MC_DRV_ERR_INVALID_OPERATION if device already opened.
+ * @return MC_DRV_ERR_DAEMON_UNREACHABLE when problems with daemon occur.
+ * @return MC_DRV_ERR_UNKNOWN_DEVICE when deviceId is unknown.
+ * @return MC_DRV_ERR_INVALID_DEVICE_FILE if kernel module under
+ * /dev/mobicore cannot be opened
+ *
+ * Uses a Mutex.
+ */
+__MC_CLIENT_LIB_API enum mcResult_t mcOpenDevice(
+	uint32_t deviceId
+);
+
+/** Close the connection to a MobiCore 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.
+ *
+ * @return MC_DRV_OK if operation has been successfully completed.
+ * @return MC_DRV_ERR_UNKNOWN_DEVICE when device id is invalid.
+ * @return MC_DRV_ERR_SESSION_PENDING when a session is still open.
+ * @return MC_DRV_ERR_DAEMON_UNREACHABLE when problems with daemon occur.
+ *
+ * Uses a Mutex.
+ */
+__MC_CLIENT_LIB_API enum mcResult_t mcCloseDevice(
+	uint32_t deviceId
+);
+
+/** Open a new session to a Trustlet. The trustlet 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).
+ *
+ * @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] tciLen Length of the TCI buffer. Maximum allowed value
+ * is MC_MAX_TCI_LEN.
+ *
+ * @return MC_DRV_OK if operation has been successfully completed.
+ * @return MC_DRV_INVALID_PARAMETER if session parameter is invalid.
+ * @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.
+ *
+ * Uses a Mutex.
+ */
+__MC_CLIENT_LIB_API enum mcResult_t mcOpenSession(
+	struct mcSessionHandle_t  *session,
+	const struct mcUuid_t *uuid,
+	uint8_t *tci,
+	uint32_t tciLen
+);
+
+/** Close a Trustlet session.
+ *
+ * Closes the specified MobiCore session. The call will block until the
+ * session has been closed.
+ *
+ * @pre Device deviceId has to be opened in advance.
+ *
+ * @param [in] session Session to be closed.
+ *
+ * @return MC_DRV_OK if operation has been successfully completed.
+ * @return MC_DRV_INVALID_PARAMETER if session parameter is invalid.
+ * @return MC_DRV_ERR_UNKNOWN_SESSION when session id is invalid.
+ * @return MC_DRV_ERR_UNKNOWN_DEVICE when device id of session is invalid.
+ * @return MC_DRV_ERR_DAEMON_UNREACHABLE when problems with daemon occur.
+ * @return MC_DRV_ERR_INVALID_DEVICE_FILE when daemon cannot open trustlet file.
+ *
+ * Uses a Mutex.
+ */
+__MC_CLIENT_LIB_API enum mcResult_t mcCloseSession(
+	struct mcSessionHandle_t *session
+);
+
+/** Notify a session.
+ * Notifies the session end point about available message data.
+ * If the session parameter is correct, notify will always succeed.
+ * Corresponding errors can only be received by mcWaitNotification().
+ * @pre A session has to be opened in advance.
+ *
+ * @param session The session to be notified.
+ *
+ * @return MC_DRV_OK if operation has been successfully completed.
+ * @return MC_DRV_INVALID_PARAMETER if session parameter is invalid.
+ * @return MC_DRV_ERR_UNKNOWN_SESSION when session id is invalid.
+ * @return MC_DRV_ERR_UNKNOWN_DEVICE when device id of session is invalid.
+ */
+__MC_CLIENT_LIB_API enum mcResult_t mcNotify(
+	struct mcSessionHandle_t *session
+);
+
+/** Wait for a notification.
+ *
+ * Wait for a notification issued by the MobiCore 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.
+ *
+ * @attention if timeout is below 0, call will block:
+ * Caller has to trust the other side to send a notification to wake him up
+ * again.
+ *
+ * @param [in] session The session the notification should correspond to.
+ * @param [in] timeout Time in milliseconds to wait
+ * (MC_NO_TIMEOUT : direct return, > 0 : milliseconds,
+ * MC_INFINITE_TIMEOUT : wait infinitely)
+ *
+ * @return MC_DRV_OK if notification is available.
+ * @return MC_DRV_ERR_TIMEOUT if no notification arrived in time.
+ * @return MC_DRV_INFO_NOTIFICATION if a problem with the session was
+ * encountered. Get more details with mcGetSessionErrorCode().
+ * @return MC_DRV_ERR_NOTIFICATION if a problem with the socket occurred.
+ * @return MC_DRV_INVALID_PARAMETER if a parameter is invalid.
+ * @return MC_DRV_ERR_UNKNOWN_SESSION when session id is invalid.
+ * @return MC_DRV_ERR_UNKNOWN_DEVICE when device id of session is invalid.
+ */
+__MC_CLIENT_LIB_API enum mcResult_t mcWaitNotification(
+	struct mcSessionHandle_t  *session,
+	int32_t			timeout
+);
+
+/**
+ * Allocate a block of world shared memory (WSM).
+ * The MC driver allocates a contiguous block of memory which can be used as
+ * WSM.
+ * This implicates that the allocated memory is aligned according to the
+ * alignment parameter.
+ * 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]  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.
+ *
+ * @attention: align and wsmFlags are currently ignored
+ *
+ * @return MC_DRV_OK if operation has been successfully completed.
+ * @return MC_DRV_INVALID_PARAMETER if a parameter is invalid.
+ * @return MC_DRV_ERR_UNKNOWN_DEVICE when device id is invalid.
+ * @return MC_DRV_ERR_NO_FREE_MEMORY if no more contiguous memory is available
+ * in this size or for this process.
+ *
+ * Uses a Mutex.
+ */
+__MC_CLIENT_LIB_API enum mcResult_t mcMallocWsm(
+	uint32_t  deviceId,
+	uint32_t  align,
+	uint32_t  len,
+	uint8_t   **wsm,
+	uint32_t  wsmFlags
+);
+
+/**
+ * Free a block of world shared memory (WSM).
+ * The MC driver will free a block of world shared memory (WSM) previously
+ * allocated with mcMallocWsm(). The caller has to assure that the address
+ * handed over to the driver is a valid WSM address.
+ *
+ * @param [in] deviceId The ID to which the given address belongs.
+ * @param [in] wsm Address of WSM block to be freed.
+ *
+ * @return MC_DRV_OK if operation has been successfully completed.
+ * @return MC_DRV_INVALID_PARAMETER if a parameter is invalid.
+ * @return MC_DRV_ERR_UNKNOWN_DEVICE when device id is invalid.
+ * @return MC_DRV_ERR_FREE_MEMORY_FAILED on failures.
+ *
+ * Uses a Mutex.
+ */
+__MC_CLIENT_LIB_API enum mcResult_t mcFreeWsm(
+	uint32_t  deviceId,
+	uint8_t   *wsm
+);
+
+/**
+ * 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 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.
+ *
+ * @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] 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).
+ *
+ * @return MC_DRV_OK if operation has been successfully completed.
+ * @return MC_DRV_INVALID_PARAMETER if a parameter is invalid.
+ * @return MC_DRV_ERR_UNKNOWN_SESSION when session id is invalid.
+ * @return MC_DRV_ERR_UNKNOWN_DEVICE when device id of session is invalid.
+ * @return MC_DRV_ERR_DAEMON_UNREACHABLE when problems with daemon occur.
+ * @return MC_DRV_ERR_BULK_MAPPING when buf is already uses as bulk buffer or
+ * when registering the buffer failed.
+ *
+ * Uses a Mutex.
+ */
+__MC_CLIENT_LIB_API enum mcResult_t mcMap(
+	struct mcSessionHandle_t  *session,
+	void			   *buf,
+	uint32_t		   len,
+	struct mcBulkMap_t		*mapInfo
+);
+
+/**
+ * Remove additional mapped bulk buffer between Trustlet Connector (TLC)
+ * and the Trustlet (TL) 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!
+ *
+ * @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).
+ * @attention The clientlib currently ignores the len field in mapInfo.
+ *
+ * @return MC_DRV_OK if operation has been successfully completed.
+ * @return MC_DRV_INVALID_PARAMETER if a parameter is invalid.
+ * @return MC_DRV_ERR_UNKNOWN_SESSION when session id is invalid.
+ * @return MC_DRV_ERR_UNKNOWN_DEVICE when device id of session is invalid.
+ * @return MC_DRV_ERR_DAEMON_UNREACHABLE when problems with daemon occur.
+ * @return MC_DRV_ERR_BULK_UNMAPPING when buf was not registered earlier
+ * or when unregistering failed.
+ *
+ * Uses a Mutex.
+ */
+__MC_CLIENT_LIB_API enum mcResult_t mcUnmap(
+	struct mcSessionHandle_t  *session,
+	void			   *buf,
+	struct mcBulkMap_t	*mapInfo
+);
+
+
+/**
+ * @attention: Not implemented.
+ * Execute driver specific command.
+ * mcDriverCtrl() can be used to execute driver specific commands.
+ * Besides the control command MC_CTRL_GET_VERSION commands are implementation
+ * specific.
+ * Please refer to the corresponding specification of the driver manufacturer.
+ *
+ * @param [in] param Command ID of the command to be executed.
+ * @param [in, out] data  Command data and response depending on command.
+ * @param [in] len Length of the data block.
+ *
+ * @return MC_DRV_ERR_NOT_IMPLEMENTED.
+ */
+__MC_CLIENT_LIB_API enum mcResult_t mcDriverCtrl(
+	enum mcDriverCtrl_t  param,
+	uint8_t		 *data,
+	uint32_t	len
+);
+
+/**
+ * @attention: Not implemented.
+ * Execute application management command.
+ * mcManage() shall be used to exchange application management commands with
+ * the MobiCore.
+ * The MobiCore Application Management Protocol is described in [MCAMP].
+ *
+ * @param [in] deviceId Identifier for the MobiCore device to be used.
+ * NULL refers to the default device.
+ * @param [in, out] data  Command data/response data depending on command.
+ * @param [in] len Length of the data block.
+ *
+ * @return MC_DRV_ERR_NOT_IMPLEMENTED.
+ */
+__MC_CLIENT_LIB_API enum mcResult_t mcManage(
+	uint32_t  deviceId,
+	uint8_t   *data,
+	uint32_t  len
+);
+
+/**
+ * Get additional error information of the last error that occured 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).
+ * See also MCI definition.
+ *
+ * @return MC_DRV_OK if operation has been successfully completed.
+ * @return MC_DRV_INVALID_PARAMETER if a parameter is invalid.
+ * @return MC_DRV_ERR_UNKNOWN_SESSION when session id is invalid.
+ * @return MC_DRV_ERR_UNKNOWN_DEVICE when device id of session is invalid.
+ */
+__MC_CLIENT_LIB_API enum mcResult_t mcGetSessionErrorCode(
+	struct mcSessionHandle_t  *session,
+	int32_t			*lastErr
+);
+
+#endif /** MCDRIVER_H_ */
+
+/** @} */
diff --git a/V008/Linux/drivers/gud/MobiCoreKernelApi/public/MobiCoreDriverCmd.h b/V008/Linux/drivers/gud/MobiCoreKernelApi/public/MobiCoreDriverCmd.h
new file mode 100644
index 0000000..5e3e008
--- /dev/null
+++ b/V008/Linux/drivers/gud/MobiCoreKernelApi/public/MobiCoreDriverCmd.h
@@ -0,0 +1,289 @@
+/** @addtogroup MCD_MCDIMPL_DAEMON
+ * @{
+ * @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 MCDAEMON_H_
+#define MCDAEMON_H_
+
+
+
+
+#include "mcUuid.h"
+
+enum mcDrvCmd_t {
+	MC_DRV_CMD_PING			= 0,
+	MC_DRV_CMD_GET_INFO		= 1,
+	MC_DRV_CMD_OPEN_DEVICE	 = 2,
+	MC_DRV_CMD_CLOSE_DEVICE	= 3,
+	MC_DRV_CMD_NQ_CONNECT	  = 4,
+	MC_DRV_CMD_OPEN_SESSION	= 5,
+	MC_DRV_CMD_CLOSE_SESSION   = 6,
+	MC_DRV_CMD_NOTIFY		  = 7,
+	MC_DRV_CMD_MAP_BULK_BUF	= 8,
+	MC_DRV_CMD_UNMAP_BULK_BUF  = 9
+};
+
+
+enum mcDrvRsp_t {
+	MC_DRV_RSP_OK					 = 0,
+	MC_DRV_RSP_FAILED				 = 1,
+	MC_DRV_RSP_DEVICE_NOT_OPENED	  = 2,
+	MC_DRV_RSP_DEVICE_ALREADY_OPENED  = 3,
+	MC_DRV_RSP_COMMAND_NOT_ALLOWED	= 4,
+	MC_DRV_INVALID_DEVICE_NAME		= 5,
+	MC_DRV_RSP_MAP_BULK_ERRO		  = 6,
+	MC_DRV_RSP_TRUSTLET_NOT_FOUND	 = 7,
+	MC_DRV_RSP_PAYLOAD_LENGTH_ERROR	  = 8,
+};
+
+
+struct mcDrvCommandHeader_t {
+	uint32_t  commandId;
+};
+
+struct mcDrvResponseHeader_t {
+	uint32_t  responseId;
+};
+
+#define MC_DEVICE_ID_DEFAULT	0 /**< The default device ID */
+
+
+/*****************************************************************************/
+struct mcDrvCmdOpenDevicePayload_t {
+	uint32_t  deviceId;
+};
+
+struct mcDrvCmdOpenDevice_t {
+	struct mcDrvCommandHeader_t header;
+	struct mcDrvCmdOpenDevicePayload_t payload;
+};
+
+
+struct mcDrvRspOpenDevicePayload_t {
+	/* empty */
+};
+
+struct mcDrvRspOpenDevice_t {
+	struct mcDrvResponseHeader_t header;
+	struct mcDrvRspOpenDevicePayload_t payload;
+};
+
+
+/*****************************************************************************/
+struct mcDrvCmdCloseDevice_t {
+	struct mcDrvCommandHeader_t header;
+	/* no payload here because close has none.
+	   If we use an empty struct, C++ will count it as 4 bytes.
+	   This will write too much into the socket at write(cmd,sizeof(cmd)) */
+};
+
+
+struct mcDrvRspCloseDevicePayload_t {
+	/* empty */
+};
+
+struct mcDrvRspCloseDevice_t {
+	struct mcDrvResponseHeader_t header;
+	struct mcDrvRspCloseDevicePayload_t payload;
+};
+
+
+/*****************************************************************************/
+struct mcDrvCmdOpenSessionPayload_t {
+	uint32_t deviceId;
+	struct mcUuid_t uuid;
+	uint32_t tci;
+	uint32_t len;
+};
+
+struct mcDrvCmdOpenSession_t {
+	struct mcDrvCommandHeader_t header;
+	struct mcDrvCmdOpenSessionPayload_t payload;
+};
+
+
+struct mcDrvRspOpenSessionPayload_t {
+	uint32_t deviceId;
+	uint32_t sessionId;
+	uint32_t deviceSessionId;
+	uint32_t mcResult;
+	uint32_t sessionMagic;
+};
+
+struct mcDrvRspOpenSession_t {
+	struct mcDrvResponseHeader_t header;
+	struct mcDrvRspOpenSessionPayload_t  payload;
+};
+
+
+/*****************************************************************************/
+struct mcDrvCmdCloseSessionPayload_t {
+	uint32_t  sessionId;
+};
+
+struct mcDrvCmdCloseSession_t {
+	struct mcDrvCommandHeader_t header;
+	struct mcDrvCmdCloseSessionPayload_t payload;
+};
+
+
+struct mcDrvRspCloseSessionPayload_t {
+	/* empty */
+};
+
+struct mcDrvRspCloseSession_t {
+	struct mcDrvResponseHeader_t header;
+	struct mcDrvRspCloseSessionPayload_t payload;
+};
+
+
+/*****************************************************************************/
+struct mcDrvCmdNotifyPayload_t {
+	uint32_t sessionId;
+};
+
+struct mcDrvCmdNotify_t {
+	struct mcDrvCommandHeader_t header;
+	struct mcDrvCmdNotifyPayload_t payload;
+};
+
+
+struct mcDrvRspNotifyPayload_t {
+	/* empty */
+};
+
+struct mcDrvRspNotify_t {
+	struct mcDrvResponseHeader_t header;
+	struct mcDrvRspNotifyPayload_t  payload;
+};
+
+
+/*****************************************************************************/
+struct mcDrvCmdMapBulkMemPayload_t {
+	uint32_t sessionId;
+	uint32_t pAddrL2;
+	uint32_t offsetPayload;
+	uint32_t lenBulkMem;
+};
+
+struct mcDrvCmdMapBulkMem_t {
+	struct mcDrvCommandHeader_t header;
+	struct mcDrvCmdMapBulkMemPayload_t  payload;
+};
+
+
+struct mcDrvRspMapBulkMemPayload_t {
+	uint32_t sessionId;
+	uint32_t secureVirtualAdr;
+	uint32_t mcResult;
+};
+
+struct mcDrvRspMapBulkMem_t {
+	struct mcDrvResponseHeader_t header;
+	struct mcDrvRspMapBulkMemPayload_t  payload;
+};
+
+
+/*****************************************************************************/
+struct mcDrvCmdUnmapBulkMemPayload_t {
+	uint32_t sessionId;
+	uint32_t secureVirtualAdr;
+	uint32_t lenBulkMem;
+};
+
+struct mcDrvCmdUnmapBulkMem_t {
+	struct mcDrvCommandHeader_t header;
+	struct mcDrvCmdUnmapBulkMemPayload_t payload;
+};
+
+
+struct mcDrvRspUnmapBulkMemPayload_t {
+	uint32_t responseId;
+	uint32_t sessionId;
+	uint32_t mcResult;
+};
+
+struct mcDrvRspUnmapBulkMem_t {
+	struct mcDrvResponseHeader_t header;
+	struct mcDrvRspUnmapBulkMemPayload_t payload;
+};
+
+
+/*****************************************************************************/
+struct mcDrvCmdNqConnectPayload_t {
+	uint32_t deviceId;
+	uint32_t sessionId;
+	uint32_t deviceSessionId;
+	uint32_t sessionMagic; /* Random data */
+};
+
+struct mcDrvCmdNqConnect_t {
+	struct mcDrvCommandHeader_t header;
+	struct mcDrvCmdNqConnectPayload_t  payload;
+};
+
+
+struct mcDrvRspNqConnectPayload_t {
+	/* empty; */
+};
+
+struct mcDrvRspNqConnect_t {
+	struct mcDrvResponseHeader_t header;
+	struct mcDrvRspNqConnectPayload_t payload;
+};
+
+
+/*****************************************************************************/
+union mcDrvCommand_t {
+	struct mcDrvCommandHeader_t	header;
+	struct mcDrvCmdOpenDevice_t	mcDrvCmdOpenDevice;
+	struct mcDrvCmdCloseDevice_t   mcDrvCmdCloseDevice;
+	struct mcDrvCmdOpenSession_t   mcDrvCmdOpenSession;
+	struct mcDrvCmdCloseSession_t  mcDrvCmdCloseSession;
+	struct mcDrvCmdNqConnect_t	 mcDrvCmdNqConnect;
+	struct mcDrvCmdNotify_t		mcDrvCmdNotify;
+	struct mcDrvCmdMapBulkMem_t	mcDrvCmdMapBulkMem;
+	struct mcDrvCmdUnmapBulkMem_t  mcDrvCmdUnmapBulkMem;
+};
+
+union mcDrvResponse_t {
+	struct mcDrvResponseHeader_t header;
+	struct mcDrvRspOpenDevice_t	mcDrvRspOpenDevice;
+	struct mcDrvRspCloseDevice_t   mcDrvRspCloseDevice;
+	struct mcDrvRspOpenSession_t   mcDrvRspOpenSession;
+	struct mcDrvRspCloseSession_t  mcDrvRspCloseSession;
+	struct mcDrvRspNqConnect_t	 mcDrvRspNqConnect;
+	struct mcDrvRspNotify_t		mcDrvRspNotify;
+	struct mcDrvRspMapBulkMem_t	mcDrvRspMapBulkMem;
+	struct mcDrvRspUnmapBulkMem_t  mcDrvRspUnmapBulkMem;
+};
+
+#endif /* MCDAEMON_H_ */
+
+/** @} */
diff --git a/V008/Linux/drivers/gud/MobiCoreKernelApi/session.c b/V008/Linux/drivers/gud/MobiCoreKernelApi/session.c
new file mode 100644
index 0000000..7b7f115
--- /dev/null
+++ b/V008/Linux/drivers/gud/MobiCoreKernelApi/session.c
@@ -0,0 +1,202 @@
+/** @addtogroup MCD_IMPL_LIB
+ * @{
+ * @file
+ * <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/types.h>
+#include <linux/slab.h>
+#include "mcKernelApi.h"
+#include "public/MobiCoreDriverApi.h"
+
+#include "session.h"
+
+/*****************************************************************************/
+struct bulkBufferDescriptor_t *bulkBufferDescriptor_create(
+	void	*virtAddr,
+	uint32_t  len,
+	uint32_t  handle,
+	void	*physAddrWsmL2
+) {
+	struct bulkBufferDescriptor_t *desc =
+		kzalloc(sizeof(struct bulkBufferDescriptor_t), GFP_KERNEL);
+	desc->virtAddr = virtAddr;
+	desc->len = len;
+	desc->handle = handle;
+	desc->physAddrWsmL2 = physAddrWsmL2;
+	return desc;
+}
+
+/*****************************************************************************/
+struct session_t *session_create(
+	uint32_t	 sessionId,
+	void	   *pInstance,
+	struct connection_t *connection
+) {
+	struct session_t *session =
+			kzalloc(sizeof(struct session_t), GFP_KERNEL);
+	session->sessionId = sessionId;
+	session->pInstance = pInstance;
+	session->notificationConnection = connection;
+
+	session->sessionInfo.lastErr = SESSION_ERR_NO;
+	session->sessionInfo.state = SESSION_STATE_INITIAL;
+
+	INIT_LIST_HEAD(&(session->bulkBufferDescriptors));
+	return session;
+}
+
+
+/*****************************************************************************/
+void session_cleanup(
+	struct session_t *session
+) {
+	struct bulkBufferDescriptor_t  *pBlkBufDescr;
+	struct list_head *pos, *q;
+
+	/* Unmap still mapped buffers */
+	list_for_each_safe(pos, q, &session->bulkBufferDescriptors) {
+		pBlkBufDescr =
+			list_entry(pos, struct bulkBufferDescriptor_t, list);
+
+		MCDRV_DBG_VERBOSE("Physical Address of L2 Table = 0x%X, "
+				"handle= %d",
+				(unsigned int)pBlkBufDescr->physAddrWsmL2,
+				pBlkBufDescr->handle);
+
+		/* ignore any error, as we cannot do anything in this case. */
+		int ret = mobicore_unmap_vmem(session->pInstance,
+						pBlkBufDescr->handle);
+		if (0 != ret)
+			MCDRV_DBG_ERROR("mobicore_unmap_vmem failed: %d", ret);
+
+		list_del(pos);
+		kfree(pBlkBufDescr);
+	}
+
+	/* Finally delete notification connection */
+	connection_cleanup(session->notificationConnection);
+	kfree(session);
+}
+
+
+/*****************************************************************************/
+void session_setErrorInfo(
+	struct session_t *session,
+	int32_t   err
+) {
+	session->sessionInfo.lastErr = err;
+}
+
+
+/*****************************************************************************/
+int32_t session_getLastErr(
+	struct session_t *session
+) {
+	return session->sessionInfo.lastErr;
+}
+
+
+/*****************************************************************************/
+struct bulkBufferDescriptor_t *session_addBulkBuf(
+	struct session_t	*session,
+	void		*buf,
+	uint32_t	len
+) {
+	struct bulkBufferDescriptor_t *blkBufDescr = NULL;
+	struct bulkBufferDescriptor_t  *tmp;
+	struct list_head *pos;
+
+	/* Search bulk buffer descriptors for existing vAddr
+	   At the moment a virtual address can only be added one time */
+	list_for_each(pos, &session->bulkBufferDescriptors) {
+		tmp = list_entry(pos, struct bulkBufferDescriptor_t, list);
+		if (tmp->virtAddr == buf)
+			return NULL;
+	}
+
+	do {
+		/* Prepare the interface structure for memory registration in
+		   Kernel Module */
+		void	*pPhysWsmL2;
+		uint32_t  handle;
+
+		int ret = mobicore_map_vmem(session->pInstance,
+					buf,
+					len,
+					&handle,
+					&pPhysWsmL2);
+
+		if (0 != ret) {
+			MCDRV_DBG_ERROR("mobicore_map_vmem failed, ret=%d",
+					ret);
+			break;
+		}
+
+		MCDRV_DBG_VERBOSE("Physical Address of L2 Table = 0x%X, "
+				"handle=%d",
+				(unsigned int)pPhysWsmL2,
+				handle);
+
+		/* Create new descriptor */
+		blkBufDescr = bulkBufferDescriptor_create(
+							buf,
+							len,
+							handle,
+							pPhysWsmL2);
+
+		/* Add to vector of descriptors */
+		list_add_tail(&(blkBufDescr->list),
+			&(session->bulkBufferDescriptors));
+	} while (0);
+
+	return blkBufDescr;
+}
+
+
+/*****************************************************************************/
+bool session_removeBulkBuf(
+	struct session_t *session,
+	void	*virtAddr
+) {
+	bool ret = true;
+	struct bulkBufferDescriptor_t  *pBlkBufDescr = NULL;
+	struct bulkBufferDescriptor_t  *tmp;
+	struct list_head *pos, *q;
+
+	MCDRV_DBG_VERBOSE("Virtual Address = 0x%X", (unsigned int) virtAddr);
+
+	/* Search and remove bulk buffer descriptor */
+	list_for_each_safe(pos, q, &session->bulkBufferDescriptors) {
+		tmp = list_entry(pos, struct bulkBufferDescriptor_t, list);
+		if (tmp->virtAddr == virtAddr) {
+			pBlkBufDescr = tmp;
+			list_del(pos);
+			break;
+		}
+	}
+
+	if (NULL == pBlkBufDescr) {
+		MCDRV_DBG_ERROR("Virtual Address not found");
+		ret = false;
+	} else {
+		MCDRV_DBG_VERBOSE("WsmL2 phys=0x%X, handle=%d",
+			(unsigned int)pBlkBufDescr->physAddrWsmL2,
+			pBlkBufDescr->handle);
+
+		/* ignore any error, as we cannot do anything */
+		int ret = mobicore_unmap_vmem(session->pInstance,
+						pBlkBufDescr->handle);
+		if (0 != ret)
+			MCDRV_DBG_ERROR("mobicore_unmap_vmem failed: %d", ret);
+
+		kfree(pBlkBufDescr);
+	}
+
+	return ret;
+}
+
+/** @} */
diff --git a/V008/Linux/drivers/gud/MobiCoreKernelApi/session.h b/V008/Linux/drivers/gud/MobiCoreKernelApi/session.h
new file mode 100644
index 0000000..1b40a1b
--- /dev/null
+++ b/V008/Linux/drivers/gud/MobiCoreKernelApi/session.h
@@ -0,0 +1,136 @@
+/** @addtogroup MCD_IMPL_LIB
+ * @{
+ * @file
+ * <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef SESSION_H_
+#define SESSION_H_
+
+#include "common.h"
+
+#include <linux/list.h>
+#include "connection.h"
+
+
+struct bulkBufferDescriptor_t {
+	void		*virtAddr; /**< The virtual address of the Bulk buffer*/
+	uint32_t	len;	  /**< Length of the Bulk buffer*/
+	uint32_t	handle;
+	void		*physAddrWsmL2; /**< The physical address of the
+				L2 table of the Bulk buffer*/
+	struct list_head list; /**< The list param for using the kernel lists*/
+};
+
+struct bulkBufferDescriptor_t *bulkBufferDescriptor_create(
+	void	*virtAddr,
+	uint32_t  len,
+	uint32_t  handle,
+	void	*physAddrWsmL2
+);
+
+/** Session states.
+ * At the moment not used !!.
+ */
+enum sessionState_t {
+	SESSION_STATE_INITIAL,
+	SESSION_STATE_OPEN,
+	SESSION_STATE_TRUSTLET_DEAD
+};
+
+#define SESSION_ERR_NO	  0 /**< No session error */
+
+/** Session information structure.
+ * The information structure is used to hold the state of the session, which
+ * will limit further actions for the session.
+ * Also the last error code will be stored till it's read.
+ */
+struct sessionInformation_t {
+	enum sessionState_t state;	   /**< Session state */
+	int32_t		lastErr;	 /**< Last error of session */
+};
+
+
+struct session_t {
+	struct mcInstance		*pInstance;
+	/**< Descriptors of additional bulk buffer of a session */
+	struct list_head	bulkBufferDescriptors;
+	/**< Informations about session */
+	struct sessionInformation_t	 sessionInfo;
+
+	uint32_t		 sessionId;
+	struct connection_t	 *notificationConnection;
+
+	/**< The list param for using the kernel lists*/
+	struct list_head list;
+};
+
+struct session_t *session_create(
+	uint32_t	 sessionId,
+	void		 *pInstance,
+	struct connection_t *connection
+);
+
+void session_cleanup(
+	struct session_t *session
+);
+
+/**
+  * Add address information of additional bulk buffer memory to session and
+  * register virtual memory in kernel module.
+  *
+  * @attention The virtual address can only be added one time. If the virtual
+  * address already exist, NULL is returned.
+  *
+  * @param buf The virtual address of bulk buffer.
+  * @param len Length of bulk buffer.
+  *
+  * @return On success the actual Bulk buffer descriptor with all address
+  * information is retured, NULL if an error occurs.
+  */
+struct bulkBufferDescriptor_t *session_addBulkBuf(
+	struct session_t *session,
+	void	*buf,
+	uint32_t  len
+);
+
+/**
+  * Remove address information of additional bulk buffer memory from session and
+  * unregister virtual memory in kernel module
+  *
+  * @param buf The virtual address of the bulk buffer.
+  *
+  * @return true on success.
+  */
+bool session_removeBulkBuf(
+	struct session_t *session,
+	void  *buf
+);
+
+/**
+  * Set additional error information of the last error that occured.
+  *
+  * @param errorCode The actual error.
+  */
+void session_setErrorInfo(
+	struct session_t *session,
+	int32_t err
+);
+
+/**
+  * Get additional error information of the last error that occured.
+  *
+  * @attention After request the information is set to SESSION_ERR_NO.
+  *
+  * @return Last stored error code or SESSION_ERR_NO.
+  */
+int32_t session_getLastErr(
+	struct session_t *session
+);
+
+#endif /* SESSION_H_ */
+
+/** @} */
diff --git a/V008/Linux/drivers/gud/MobiCoreKernelApi/wsm.h b/V008/Linux/drivers/gud/MobiCoreKernelApi/wsm.h
new file mode 100644
index 0000000..4e38132
--- /dev/null
+++ b/V008/Linux/drivers/gud/MobiCoreKernelApi/wsm.h
@@ -0,0 +1,35 @@
+/** @addtogroup MCD_MCDIMPL_DAEMON_SRV
+ * @{
+ * @file
+ *
+ * World shared memory definitions.
+ *
+ * <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef WSM_H_
+#define WSM_H_
+
+#include "common.h"
+#include <linux/list.h>
+
+struct wsm_t {
+	void *virtAddr;
+	uint32_t len;
+	uint32_t handle;
+	void *physAddr;
+	struct list_head list;
+};
+
+struct wsm_t *wsm_create(
+	void	*virtAddr,
+	uint32_t  len,
+	uint32_t  handle,
+	void	*physAddr /*= NULL this may be unknown, so is can be omitted.*/
+);
+#endif /* WSM_H_ */
+
+/** @} */
diff --git a/V008/README.TXT b/V008/README.TXT
new file mode 100644
index 0000000..9ae0e13
--- /dev/null
+++ b/V008/README.TXT
@@ -0,0 +1,58 @@
+G & D Android Linux release
+
+This package contains 2 parts:
+
+1) Mobicore Linux Daemon & client lib
+  All the components are in the *mobicore* folder.
+  To enable building the components all you need is to copy the mobicore folder
+to the Android source tree.
+
+  It has been tested with Android 2.3.6 and Android 4.0.1
+  The source tree tested has been:
+
+Android -
+ - external
+   - mobicore
+     - common
+     - daemon
+     - include
+
+Other places for the folder might work but have never been tested!    
+
+2) Mobicore Linux Driver
+
+  The Mobicore Linux drivers are located in the *gud* folder in this package.
+  The package is now designed to be dropped in the Linux source tree in the 
+drivers folder.
+
+  The source tree tested has been:
+
+Linux -
+ - drivers
+   - gud
+     - include
+     - Kconfig
+     - Makefile
+     - MobicoreDriver
+     - MobicoreKernelApi
+
+  Please note that dropping it in a different folder in the Linux source tree
+will *NOT* work!
+
+  To enable automatic building inside the kernel follow these steps:
+1) copy the gud folder from this package to linux/drivers folder
+2) add this line:
+source "drivers/gud/Kconfig" 
+to the file in linux/drivers/Kconfig just BEFORE the last endmenu line
+3) add this line:
+obj-y               += gud/
+at the end of the file linux/drivers/Makefile
+4) run make menuconfig and in the "Device Drivers" page please select 
+"Linux Mobicore Support" and also "Linux Mobicore API":
+
+<*> Linux Mobicore Support
+[ ]   Mobicore Module debug mode
+<*>   Linux Mobicore API
+
+5) Run make again and the mobicore components will be included in the kernel
+image
diff --git a/V008/Release_Notes.pdf b/V008/Release_Notes.pdf
new file mode 100644
index 0000000..415f751
--- /dev/null
+++ b/V008/Release_Notes.pdf
Binary files differ
diff --git a/V008/config b/V008/config
new file mode 100755
index 0000000..8a89e56
--- /dev/null
+++ b/V008/config
@@ -0,0 +1,6 @@
+MobiCore=r:16481
+MobiCoreDriverMod=b:GoogleCode-V004:16975
+MobiCoreDriverLib=t:IR-017
+MobiCoreDriverKernelApi=r:16982
+Logwrapper=r:16481
+Scripts=r:16967