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(
+ ¬ification,
+ 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(¬ifications.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(¬ification);
+ //IMPROVEMENT-2012-03-07-maneaval What happens when/if nsiq fails?
+ //In the old days an exception would be thrown but it was uncertain
+ //where it was handled, some server(sock or Netlink). In that case
+ //the server would just die but never actually signaled to the client
+ //any error condition
+ nsiq();
+
+ } while(0);
+}
+
+//------------------------------------------------------------------------------
+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 *)¬ifications.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, ¶ms);
+ 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, ¶ms);
+ 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, ¶ms);
+ 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, ¶ms);
+ 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(¶ms.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,
+ ¬ification,
+ 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