Split handling command off of ConnectionSession 93/174793/2
authorIgor Kotrasinski <i.kotrasinsk@partner.samsung.com>
Wed, 6 Dec 2017 10:07:00 +0000 (11:07 +0100)
committerIgor Kotrasinski <i.kotrasinsk@partner.samsung.com>
Fri, 6 Apr 2018 09:58:24 +0000 (11:58 +0200)
Split ConnectionSession into the part that handles socket I/O and
the part that handles actual commands. This way the socket I/O part can
be reused for control commands.

Change-Id: I4454c6b225505acf9b86120c22369c390068194b
Signed-off-by: Igor Kotrasinski <i.kotrasinsk@partner.samsung.com>
14 files changed:
include/include/tee_command.h
simulatordaemon/CMakeLists.txt
simulatordaemon/inc/ConnectionSession.h
simulatordaemon/inc/IConnectionHandler.h [new file with mode: 0644]
simulatordaemon/inc/IConnectionSession.h [deleted file]
simulatordaemon/inc/IConnectionWriter.h [new file with mode: 0644]
simulatordaemon/inc/SimulatorDaemonServer.h
simulatordaemon/inc/TEEConnectionHandler.h [new file with mode: 0644]
simulatordaemon/inc/TEEContext.h
simulatordaemon/src/ConnectionSession.cpp
simulatordaemon/src/Session.cpp
simulatordaemon/src/SimulatorDaemonServer.cpp
simulatordaemon/src/TEEConnectionHandler.cpp [new file with mode: 0644]
simulatordaemon/src/TEEContext.cpp

index f2197cd3282cfcb44ef5dc95c3cc5abf470821cc..38b8a8abe53bbbb3217b6a5649fc186eb9f3e968 100644 (file)
@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2015-2017 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2015-2018 Samsung Electronics Co., Ltd All Rights Reserved
  *
  *    Licensed under the Apache License, Version 2.0 (the "License");
  *    you may not use this file except in compliance with the License.
@@ -23,6 +23,8 @@
 #ifndef __TEE_COMMAND_H__
 #define __TEE_COMMAND_H__
 
+#include <stdint.h>
+
 typedef enum {
        INVALID = -1,
        INITIALIZE_CONTEXT = 0,
index f330065cc719f3784d56083ae62e47476972b35f..5efd4a0f1fc532fd0d8c96939005a50312448e9c 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+# Copyright (c) 2018 Samsung Electronics Co., Ltd All Rights Reserved
 #
 #    Licensed under the Apache License, Version 2.0 (the "License");
 #    you may not use this file except in compliance with the License.
@@ -43,6 +43,7 @@ SET(DAEMON_SOURCES
     ${DAEMON_PATH}/src/SimulatorDaemonServer.cpp
     ${DAEMON_PATH}/src/TAFactory.cpp
     ${DAEMON_PATH}/src/TAInstance.cpp
+    ${DAEMON_PATH}/src/TEEConnectionHandler.cpp
     ${DAEMON_PATH}/src/TEEContext.cpp
     ${DAEMON_PATH}/src/ClientCommands/CommandCloseSession.cpp
     ${DAEMON_PATH}/src/ClientCommands/CommandCloseTASession.cpp
index 055bfe807b3a6c89c555a1d3d9168475d7c42afd..a5e8c128316705e21c43c7e6ce3bbb90e0526774 100644 (file)
@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2015-2017 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2015-2018 Samsung Electronics Co., Ltd All Rights Reserved
  *
  *    Licensed under the Apache License, Version 2.0 (the "License");
  *    you may not use this file except in compliance with the License.
@@ -21,7 +21,7 @@
  */
 
 
-#if !defined(_CONNECTIONSESSION_H)
+#ifndef _CONNECTIONSESSION_H
 #define _CONNECTIONSESSION_H
 
 /*-----------------------------------------------------------------------------
@@ -37,7 +37,8 @@
 #include "ioService.h"
 #include "ClientCommands/MakeCommand.h"
 #include "TEEContext.h"
-#include "IConnectionSession.h"
+#include "IConnectionWriter.h"
+#include "IConnectionHandler.h"
 #include "SecurityContext.h"
 
 using namespace std;
@@ -49,44 +50,41 @@ using boost::asio::local::stream_protocol;
 /*-----------------------------------------------------------------------------
  *  Class definitions
  *-----------------------------------------------------------------------------*/
-class ConnectionSession: public boost::enable_shared_from_this<ConnectionSession>, public IConnectionSession
+template<typename header_t>
+class ConnectionSession:
+       public boost::enable_shared_from_this<ConnectionSession<header_t>>,
+       public IConnectionWriter<header_t>
 {
+private:
+       typedef boost::shared_ptr<IConnectionHandler<header_t>> handler_ptr;
 public:
        pthread_mutex_t connLock;
-       typedef boost::shared_ptr<ConnectionSession> session_ptr;
-       static session_ptr create(boost::asio::io_service& io_service)
-       {
-               return session_ptr(new ConnectionSession(io_service));
-       }
-       ConnectionSession(boost::asio::io_service& io_service):
-       clientSocket(io_service), clientData()
+       typedef boost::shared_ptr<ConnectionSession<header_t>> session_ptr;
+       static session_ptr create(boost::asio::io_service& io_service, handler_ptr handler)
        {
-               pthread_mutex_init(&connLock, NULL);
-               currentState = CMD_READ;
-               TEECtx = NULL;
-               command = INVALID;
+               return session_ptr(new ConnectionSession(io_service, handler));
        }
+       ConnectionSession(boost::asio::io_service& io_service, handler_ptr handler);
        stream_protocol::socket& socket()
        {
                return clientSocket;
        }
        void start();
-       TEEC_Result write(TEE_CMD command, char* data, size_t size);
+       boost::system::error_code write(header_t header, char* data, size_t size);
        SecurityContext getSecurityContext();
        ~ConnectionSession();
 private:
-       TEEContext *TEECtx;
-       void handleRead(const boost::system::error_code& error,
-                       size_t bytes_transferred);
+       handler_ptr m_handler;
        // The socket used to communicate with the client.
        stream_protocol::socket clientSocket;
-       // Security context of Connection.
-       SecurityContext secContext;
        // Buffer used to store data received from the client.
        boost::array<char, 1024> clientData;
        states currentState;
        vector<char> commandData;
-       TEE_CMD command;
+       header_t m_header{};
+       void handleRead(const boost::system::error_code& error,
+                       size_t bytes_transferred);
+       void scheduleRead(int32_t size);
 };
 
 #else // defined(BOOST_ASIO_HAS_LOCAL_SOCKETS)
diff --git a/simulatordaemon/inc/IConnectionHandler.h b/simulatordaemon/inc/IConnectionHandler.h
new file mode 100644 (file)
index 0000000..9099463
--- /dev/null
@@ -0,0 +1,44 @@
+/**
+ * Copyright (c) 2015-2018 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+
+/**
+ * @file
+ * @author Igor Kotrasinski (i.kotrasinsk@partner@samsung.com)
+ * @brief  Data handler interface plugged into the socket I/O handler
+ */
+
+#ifndef _ICONNECTIONHANDLER_H
+#define _ICONNECTIONHANDLER_H
+
+#include <vector>
+#include <boost/system/error_code.hpp>
+
+#include "tee_command.h"
+#include "IConnectionWriter.h"
+
+template <typename header_t>
+class IConnectionHandler
+{
+public:
+       virtual void setWriter(IConnectionWriter<header_t> &writer) = 0;
+       virtual void handleConnect(int sock) = 0;
+       virtual int32_t getDataSize(header_t header) = 0;
+       virtual void handleRead(header_t header, std::vector<char> &data) = 0;
+       virtual void handleReadError(boost::system::error_code e) = 0;
+       virtual void handleConnectionClosed() = 0;
+};
+
+#endif /* _ICONNECTIONHANDLER_H */
diff --git a/simulatordaemon/inc/IConnectionSession.h b/simulatordaemon/inc/IConnectionSession.h
deleted file mode 100644 (file)
index 0f2a2f6..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/**
- * Copyright (c) 2015-2017 Samsung Electronics Co., Ltd All Rights Reserved
- *
- *    Licensed under the Apache License, Version 2.0 (the "License");
- *    you may not use this file except in compliance with the License.
- *    You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *    Unless required by applicable law or agreed to in writing, software
- *    distributed under the License is distributed on an "AS IS" BASIS,
- *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *    See the License for the specific language governing permissions and
- *    limitations under the License.
- */
-
-/**
- * @file
- * @author CHERYL (cb) (cheryl.b@samsung.com)
- * @brief  Interface for Connection handler for Simulator Daemon server
- */
-
-
-#if !defined(_ICONNECTIONSESSION_H)
-#define _ICONNECTIONSESSION_H
-
-/*-----------------------------------------------------------------------------
- *  Include files
- *-----------------------------------------------------------------------------*/
-#include "tee_command.h"
-#include "SecurityContext.h"
-
-/*-----------------------------------------------------------------------------
- *  Class definitions
- *-----------------------------------------------------------------------------*/
-class IConnectionSession {
-public:
-       virtual TEEC_Result write(TEE_CMD command, char* data, size_t size) = 0;
-       virtual SecurityContext getSecurityContext() = 0;
-       virtual ~IConnectionSession() {}
-};
-
-#endif /* _ICONNECTIONSESSION_H */
-
diff --git a/simulatordaemon/inc/IConnectionWriter.h b/simulatordaemon/inc/IConnectionWriter.h
new file mode 100644 (file)
index 0000000..57143cb
--- /dev/null
@@ -0,0 +1,38 @@
+/**
+ * Copyright (c) 2015-2018 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+
+/**
+ * @file
+ * @author Igor Kotrasinski (i.kotrasinsk@partner@samsung.com)
+ * @brief  Writer interface for generic socket connection handler
+ */
+
+#ifndef _ICONNECTIONWRITER_H
+#define _ICONNECTIONWRITER_H
+
+#include <vector>
+#include <boost/system/error_code.hpp>
+
+#include "tee_command.h"
+
+template <typename header_t>
+class IConnectionWriter
+{
+public:
+       virtual boost::system::error_code write(header_t header, char *data, size_t size) = 0;
+};
+
+#endif /* _ICONNECTIONWRITER_H */
index 0991996dc11e2994817e1f9d2550e84d55b23b03..d5ebf2e03183a7404f70ecd2f8a78e3091f1e0e1 100644 (file)
@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2015-2017 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2015-2018 Samsung Electronics Co., Ltd All Rights Reserved
  *
  *    Licensed under the Apache License, Version 2.0 (the "License");
  *    you may not use this file except in compliance with the License.
@@ -21,7 +21,7 @@
  */
 
 
-#if !defined(_SIMULATORDAEMONSERVER_H)
+#ifndef _SIMULATORDAEMONSERVER_H
 #define _SIMULATORDAEMONSERVER_H
 
 /*-----------------------------------------------------------------------------
@@ -42,7 +42,7 @@ public:
 
 private:
        void startAccept();
-       void handleAccept(ConnectionSession::session_ptr session,
+       void handleAccept(ConnectionSession<int8_t>::session_ptr session,
                const boost::system::error_code& error);
        boost::asio::io_service& mem_io_service;
        stream_protocol::acceptor acceptor;
diff --git a/simulatordaemon/inc/TEEConnectionHandler.h b/simulatordaemon/inc/TEEConnectionHandler.h
new file mode 100644 (file)
index 0000000..0ad9abc
--- /dev/null
@@ -0,0 +1,54 @@
+/**
+ * Copyright (c) 2015-2018 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+
+/**
+ * @file
+ * @author Igor Kotrasinski (i.kotrasinsk@partner@samsung.com)
+ * @brief  Handler for data coming over TEEC socket
+ */
+
+#ifndef _TEECONNECTIONHANDLER_H
+#define _TEECONNECTIONHANDLER_H
+
+#include <cstdint>
+#include <boost/system/error_code.hpp>
+#include "IConnectionHandler.h"
+#include "TEEContext.h"
+
+
+class TEEConnectionHandler: public IConnectionHandler<int8_t>
+{
+public:
+       TEEConnectionHandler();
+       void setWriter(IConnectionWriter<int8_t> &writer) override;
+       void handleConnect(int sock) override;
+       int32_t getDataSize(int8_t cmd) override;
+       void handleRead(int8_t header, std::vector<char> &data) override;
+       void handleReadError(boost::system::error_code e) override;
+       void handleConnectionClosed() override;
+
+       TEEC_Result write(TEE_CMD cmd, char* data, size_t size);
+       SecurityContext getSecurityContext();
+       ~TEEConnectionHandler();
+private:
+       TEEContext *TEECtx = NULL;
+       SecurityContext secContext;
+       IConnectionWriter<int8_t> *m_writer = NULL;
+       TEE_CMD dataToCmd(int8_t cmd_data);
+       int8_t cmdToData(TEE_CMD cmd_data);
+};
+
+#endif /* _TEECONNECTIONHANDLER_H */
index ab6866501e8d501dd502038f8df2b6925fed029c..8f4b67d865a00242514b034a750faedddb9aec71 100644 (file)
@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2015-2017 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2015-2018 Samsung Electronics Co., Ltd All Rights Reserved
  *
  *    Licensed under the Apache License, Version 2.0 (the "License");
  *    you may not use this file except in compliance with the License.
@@ -21,7 +21,7 @@
  */
 
 
-#if !defined(_TEECONTEXT_H)
+#ifndef _TEECONTEXT_H
 #define _TEECONTEXT_H
 
 /*-----------------------------------------------------------------------------
@@ -35,7 +35,6 @@
 #include "log.h"
 #include "Session.h"
 #include "tee_command.h"
-#include "IConnectionSession.h"
 #include "SecurityContext.h"
 
 using namespace std;
@@ -48,6 +47,9 @@ using namespace std;
  *  Class definitions
  *-----------------------------------------------------------------------------*/
 
+class TEEConnectionHandler;
+
+
 class TEEContext {
 private:
        pthread_rwlock_t mShmListLock;
@@ -56,7 +58,7 @@ public:
        pthread_rwlock_t mSessionMapLock;
        map<uint32_t, ISession*> mSessionMap;
        // Connection session instance associated with the TEEContext instance
-       IConnectionSession* mConnSess;
+       TEEConnectionHandler* mConnSess;
        // ContextID assigned to the instance
        uint32_t mContextID;
        /* Security context wich stores info about low-level connection data*/
@@ -67,7 +69,7 @@ public:
         * the context as dummy isInternal member variable is used
         */
        bool isInternal;
-       TEEContext(uint32_t contextID, IConnectionSession* connSession);
+       TEEContext(uint32_t contextID, TEEConnectionHandler* connSession);
        TEEC_Result initContext(InitContextData* data);
        void finContext(FinalizeContextData data);
        TEEC_Result openSession(OpenSessionData data);
index 97d730491fbde547379ad2c77525742926401cc9..941f92bf8867858d37214fb6601eeddda60f014a 100644 (file)
@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2015-2017 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2015-2018 Samsung Electronics Co., Ltd All Rights Reserved
  *
  *    Licensed under the Apache License, Version 2.0 (the "License");
  *    you may not use this file except in compliance with the License.
 /*-----------------------------------------------------------------------------
  *  Include files
  *-----------------------------------------------------------------------------*/
+#include <cstring>
+#include <cstdint>
+#include <boost/asio.hpp>
 #include "ConnectionSession.h"
 
-/*-----------------------------------------------------------------------------
- *  Globals
- *-----------------------------------------------------------------------------*/
-// Lock for Context ID to be assigned to Context
-pthread_rwlock_t ctxIDLock = PTHREAD_RWLOCK_INITIALIZER;
-// Context ID to be assigned to Context
-uint32_t ctxID = 21;
-
 /*-----------------------------------------------------------------------------
  *  Member functions
  *-----------------------------------------------------------------------------*/
 
+template<typename header_t>
+ConnectionSession<header_t>::ConnectionSession(boost::asio::io_service& io_service,
+                                              handler_ptr handler):
+       m_handler(handler), clientSocket(io_service), clientData()
+       {
+               pthread_mutex_init(&connLock, NULL);
+               currentState = CMD_READ;
+               m_handler->setWriter(*this);
+       }
+
+
 /**
  * On starting the server and accepting a connection, read some data from the socket.
  * * @param none
  */
-void ConnectionSession::start() {
-       LOGD(SIM_DAEMON, "Entry");
-
-       // init SecurityContext of current session after initializing socket
-       this->secContext = SecurityContext(clientSocket.native());
-
-       // Create a new Context
-       pthread_rwlock_wrlock(&ctxIDLock);
-       TEECtx = new TEEContext(ctxID, this);
-       // Increment the Context ID to be assigned to next Context
-       ctxID++;
-       if (ctxID == 0) ctxID++;
-       pthread_rwlock_unlock(&ctxIDLock);
-
-#ifdef _CYNARA_INTEGRATION
-       /* Check if client has cynara permission */
-       const string privilege("http://tizen.org/privilege/tee.client");
-       if (!secContext.clientHasCynaraPermission(privilege)) {
-               LOGE(SIM_DAEMON, "Client has no permission to use TEE");
-               TEECtx->cynara_check_result = false;
-       }
-#endif /* _CYNARA_INTEGRATION */
-
+template<typename header_t>
+void ConnectionSession<header_t>::start() {
+       m_handler->handleConnect(clientSocket.native());
        currentState = CMD_READ;
 
-       // read exactly 1 byte to identify the command and execute callback when
+       // read bytes to identify the command and execute callback when
        // command is received
        boost::asio::async_read(clientSocket, boost::asio::buffer(clientData),
-           boost::asio::transfer_exactly(1),
-           boost::bind(&ConnectionSession::handleRead, shared_from_this(),
+           boost::asio::transfer_exactly(sizeof(header_t)),
+           boost::bind(&ConnectionSession<header_t>::handleRead, this->shared_from_this(),
                boost::asio::placeholders::error,
                boost::asio::placeholders::bytes_transferred));
 }
@@ -81,7 +67,8 @@ void ConnectionSession::start() {
  * @param error Boost error code and error message object
  * @param bytes_transferred Number of bytes read from the socket
  */
-void ConnectionSession::handleRead(const boost::system::error_code& error,
+template<typename header_t>
+void ConnectionSession<header_t>::handleRead(const boost::system::error_code& error,
     size_t bytes_transferred) {
        LOGD(SIM_DAEMON, "Entry");
 
@@ -98,130 +85,88 @@ void ConnectionSession::handleRead(const boost::system::error_code& error,
                switch (currentState) {
                        case CMD_READ: {
                                // Identify command
-                               command = (TEE_CMD)clientData.at(0);
-                               LOGD(SIM_DAEMON, "Command received: %d", (uint32_t)command);
+                               std::memcpy((void*) &m_header, clientData.data(),
+                                           sizeof(header_t));
 
-                               // Calculate pending numbers of bytes pending to be read only for commands
-                               int32_t data_size = MakeCommand::getDataSize(command);
+                               int32_t data_size = m_handler->getDataSize(m_header);
 
                                if (data_size > 0) {
                                        currentState = DATA_READ;
-                                       // read remaining bytes related to received valid command
-                                       boost::asio::async_read(clientSocket, boost::asio::buffer(clientData),
-                                           boost::asio::transfer_exactly(data_size),
-                                           boost::bind(&ConnectionSession::handleRead, shared_from_this(),
-                                               boost::asio::placeholders::error,
-                                               boost::asio::placeholders::bytes_transferred));
+                                       scheduleRead(data_size);
                                } else if (-1 == data_size) {
                                        // else case is invalid command
                                        // TODO: Identify the correct behavior; what to do when invalid command is received?
-                                       LOGE(SIM_DAEMON, "Invalid command received!");
                                } else if (0 == data_size) {
-                                       // reset state to read new command
                                        currentState = CMD_READ;
-                                       // read command and register callback to read data
-                                       boost::asio::async_read(clientSocket, boost::asio::buffer(clientData),
-                                           boost::asio::transfer_exactly(1),
-                                           boost::bind(&ConnectionSession::handleRead, shared_from_this(),
-                                               boost::asio::placeholders::error,
-                                               boost::asio::placeholders::bytes_transferred));
+                                       scheduleRead(sizeof(header_t));
                                }
                                break;
                        } //case
 
                        case DATA_READ: {
                                // At this pointer data is completely read
-                               // clear the vector for the first time and copy client data received
                                commandData.clear();
                                for (uint32_t i = 0; i < clientData.size(); i++) {
                                        commandData.push_back(clientData.at(i));
                                }
-                               string tempData(commandData.begin(), commandData.end());
-
-                               // Call the TEEContext object to handle commands
-                               CommandBasePtr ptr = MakeCommand::getCommand(command,
-                                   (void*)tempData.c_str(), TEECtx);
-
-                               if (!ptr == false) {
-                                       ptr->execute();
-                               } else {
-                                       LOGE(SIM_DAEMON, "Command not found");
-                               }
+                               m_handler->handleRead(m_header, commandData);
 
-                               // reset state to read new command
                                currentState = CMD_READ;
-                               // read command and register callback to read data
-                               boost::asio::async_read(clientSocket, boost::asio::buffer(clientData),
-                                   boost::asio::transfer_exactly(1),
-                                   boost::bind(&ConnectionSession::handleRead, shared_from_this(),
-                                       boost::asio::placeholders::error,
-                                       boost::asio::placeholders::bytes_transferred));
+                               scheduleRead(sizeof(header_t));
                                break;
                        } //case
                } //switch
+       } else if (error == boost::asio::error::eof ||
+                  error == boost::asio::error::connection_reset) {
+               m_handler->handleConnectionClosed();
        } else {
-               LOGE(SIM_DAEMON, "Error in reading from CA %s(%d)", error.category().name(), error.value());
-               // Call the TEEContext object to cleanup
-               FinalizeContextData data;
-               data.contextID = 0;
-               CommandBasePtr ptr = MakeCommand::getCommand(FINALIZE_CONTEXT,
-                                   (void*)&data, TEECtx);
-               if (!ptr == false) {
-                       ptr->execute();
-               } else {
-                       LOGE(SIM_DAEMON, "Command not found");
-               }
+               m_handler->handleReadError(error);
+               m_handler->handleConnectionClosed();
        }
 }
 
+template<typename header_t>
+void ConnectionSession<header_t>::scheduleRead(int32_t size)
+{
+       boost::asio::async_read(clientSocket, boost::asio::buffer(clientData),
+                               boost::asio::transfer_exactly(size),
+                               boost::bind(&ConnectionSession<header_t>::handleRead, this->shared_from_this(),
+                               boost::asio::placeholders::error,
+                               boost::asio::placeholders::bytes_transferred));
+}
+
 /**
  * Synchronous write to the socket.
  * @param command to be sent to TEECLib
  * @param data to be sent to TEECLib
  * @param size of data to be sent to TEECLib
  */
-TEEC_Result ConnectionSession::write(TEE_CMD cmd, char* data, size_t size) {
+template<typename header_t>
+boost::system::error_code ConnectionSession<header_t>::write(header_t header,
+                                                         char* data, size_t size)
+{
        LOGD(SIM_DAEMON, "Entry");
-       TEEC_Result result = TEEC_ERROR_COMMUNICATION;
        boost::system::error_code error = boost::asio::error::host_not_found;
        pthread_mutex_lock(&connLock);
-       // Send command to TEECLib for CA
+
        boost::asio::write(clientSocket,
-           boost::asio::buffer((char*)&cmd, sizeof(char)),
+           boost::asio::buffer((char*)&header, sizeof(header)),
            boost::asio::transfer_all(), error);
-
        if ((!error) && (size != 0)) {
-               // Send command data to TEECLib for CA
                boost::asio::write(clientSocket, boost::asio::buffer(data, size),
                    boost::asio::transfer_all(), error);
-               if (!error)
-                       result = TEEC_SUCCESS;
-               else
-               {
-                       LOGE(SIM_DAEMON, "Error in writing Data to CA");
-                       LOGE(SIM_DAEMON, "Response returned with error code %d", error.value());
-                       LOGE(SIM_DAEMON, "Response returned with error code %s",
-                           error.category().name());
-               }
-       } else {
-               LOGE(SIM_DAEMON, "Error in writing Command to CA");
-               LOGE(SIM_DAEMON, "Response returned with error code %d", error.value());
-               LOGE(SIM_DAEMON, "Response returned with error code %s",
-                   error.category().name());
        }
-       pthread_mutex_unlock(&connLock);
-       return result;
-}
 
-SecurityContext ConnectionSession::getSecurityContext(){
-       return secContext;
+       pthread_mutex_unlock(&connLock);
+       return error;
 }
 
-ConnectionSession::~ConnectionSession() {
-       LOGD(SIM_DAEMON, "Entry");
-       // Destory the lock for write (connLock)
+template<typename header_t>
+ConnectionSession<header_t>::~ConnectionSession() {
        pthread_mutex_destroy(&connLock);
-       // delete Context
-       delete TEECtx;
-       TEECtx = NULL;
 }
+
+/*-----------------------------------------------------------------------------
+ *  Template instantiation for external files
+ *-----------------------------------------------------------------------------*/
+template class ConnectionSession<int8_t>;
index adfd12e27fe75a12796ce7b9247fdea420113352..e57ee3d1ecb415770f5790935c063a1a6138b2b2 100644 (file)
@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2015-2017 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2015-2018 Samsung Electronics Co., Ltd All Rights Reserved
  *
  *    Licensed under the Apache License, Version 2.0 (the "License");
  *    you may not use this file except in compliance with the License.
@@ -27,6 +27,7 @@
 #include "Session.h"
 #include "TAFactory.h"
 #include "TEEContext.h"
+#include "TEEConnectionHandler.h"
 
 /*-----------------------------------------------------------------------------
  *  Member functions
index 47207180dff5e885462b107a0732a4e1037b8466..cf6d4ade2bfead6c6852a2424f90bba01612a253 100644 (file)
@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2015-2017 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2015-2018 Samsung Electronics Co., Ltd All Rights Reserved
  *
  *    Licensed under the Apache License, Version 2.0 (the "License");
  *    you may not use this file except in compliance with the License.
 /*-----------------------------------------------------------------------------
  *  Include files
  *-----------------------------------------------------------------------------*/
+#include <cstdint>
+#include <boost/shared_ptr.hpp>
 #include "SimulatorDaemonServer.h"
 #include "SecurityContext.h"
+#include "TEEConnectionHandler.h"
+#include "ConnectionSession.h"
 
 /*-----------------------------------------------------------------------------
  *  Member functions
@@ -57,7 +61,9 @@ SimulatorDaemonServer::SimulatorDaemonServer(boost::asio::io_service& io_service
 
 void SimulatorDaemonServer::startAccept()
 {
-       ConnectionSession::session_ptr newSession = ConnectionSession::create(acceptor.get_io_service());
+       boost::shared_ptr<TEEConnectionHandler> teeHandler(new TEEConnectionHandler());
+       ConnectionSession<int8_t>::session_ptr newSession = ConnectionSession<int8_t>::create(
+                       acceptor.get_io_service(), teeHandler);
 
        acceptor.async_accept(newSession->socket(),
                boost::bind(&SimulatorDaemonServer::handleAccept, this, newSession,
@@ -70,7 +76,7 @@ void SimulatorDaemonServer::startAccept()
  * @param error error code if any occurred
  */
 void SimulatorDaemonServer::handleAccept(
-       ConnectionSession::session_ptr session,
+       ConnectionSession<int8_t>::session_ptr session,
        const boost::system::error_code& error)
 {
        if (!error) {
diff --git a/simulatordaemon/src/TEEConnectionHandler.cpp b/simulatordaemon/src/TEEConnectionHandler.cpp
new file mode 100644 (file)
index 0000000..dfef9cb
--- /dev/null
@@ -0,0 +1,150 @@
+/**
+ * Copyright (c) 2015-2018 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+
+/**
+ * @file
+ * @author Igor Kotrasinski (i.kotrasinsk@partner@samsung.com)
+ * @brief  TEEConnectionHandler class
+ */
+
+#include <boost/asio.hpp>
+#include "TEEConnectionHandler.h"
+#include "ClientCommands/MakeCommand.h"
+#include "IConnectionWriter.h"
+
+
+// Lock for Context ID to be assigned to Context
+pthread_rwlock_t ctxIDLock = PTHREAD_RWLOCK_INITIALIZER;
+// Context ID to be assigned to Context
+uint32_t ctxID = 21;
+
+TEEConnectionHandler::TEEConnectionHandler() {};
+
+TEE_CMD TEEConnectionHandler::dataToCmd(int8_t cmd_data)
+{
+       return (TEE_CMD) cmd_data;
+}
+
+int8_t TEEConnectionHandler::cmdToData(TEE_CMD cmd)
+{
+       return (int8_t) cmd;
+}
+
+void TEEConnectionHandler::setWriter(IConnectionWriter<int8_t> &writer)
+{
+       this->m_writer = &writer;
+}
+
+void TEEConnectionHandler::handleConnect(int sock)
+{
+       LOGD(SIM_DAEMON, "Entry");
+
+       // init SecurityContext of current session after initializing socket
+       this->secContext = SecurityContext(sock);
+
+       // Create a new Context
+       pthread_rwlock_wrlock(&ctxIDLock);
+       TEECtx = new TEEContext(ctxID, this);
+       // Increment the Context ID to be assigned to next Context
+       ctxID++;
+       if (ctxID == 0) ctxID++;
+       pthread_rwlock_unlock(&ctxIDLock);
+
+#ifdef _CYNARA_INTEGRATION
+       /* Check if client has cynara permission */
+       const string privilege("http://tizen.org/privilege/tee.client");
+       if (!secContext.clientHasCynaraPermission(privilege)) {
+               LOGE(SIM_DAEMON, "Client has no permission to use TEE");
+               TEECtx->cynara_check_result = false;
+       }
+#endif /* _CYNARA_INTEGRATION */
+}
+
+
+int32_t TEEConnectionHandler::getDataSize(int8_t cmdData)
+{
+       TEE_CMD cmd = dataToCmd(cmdData);
+       int32_t data_size;
+
+       LOGD(SIM_DAEMON, "Command received: %d", (uint32_t)cmd);
+       data_size = MakeCommand::getDataSize(cmd);
+       if (data_size == -1)
+               LOGE(SIM_DAEMON, "Invalid command received!");
+       return data_size;
+}
+
+void TEEConnectionHandler::handleRead(int8_t headerData, std::vector<char> &data)
+{
+       TEE_CMD header = dataToCmd(headerData);
+       string tempData(data.begin(), data.end());
+
+       // Call the TEEContext object to handle commands
+       CommandBasePtr ptr = MakeCommand::getCommand(header,
+                   (void*)tempData.c_str(), TEECtx);
+
+       if (!ptr == false) {
+               ptr->execute();
+       } else {
+               LOGE(SIM_DAEMON, "Command not found");
+       }
+}
+
+void TEEConnectionHandler::handleReadError(boost::system::error_code e)
+{
+       LOGE(SIM_DAEMON, "Error in reading from CA");
+       LOGE(SIM_DAEMON, "Response returned with error code %d", e.value());
+       LOGE(SIM_DAEMON, "Response returned with error code %s",
+           e.category().name());
+}
+
+void TEEConnectionHandler::handleConnectionClosed()
+{
+       // Call the TEEContext object to cleanup
+       FinalizeContextData data;
+       data.contextID = 0;
+       CommandBasePtr ptr = MakeCommand::getCommand(FINALIZE_CONTEXT,
+                           (void*)&data, TEECtx);
+       if (!ptr == false) {
+               ptr->execute();
+       } else {
+               LOGE(SIM_DAEMON, "Command not found");
+       }
+}
+
+TEEC_Result TEEConnectionHandler::write(TEE_CMD cmd, char* data, size_t size)
+{
+       boost::system::error_code writeRet;
+       TEEC_Result result = TEEC_SUCCESS;
+
+       writeRet = m_writer->write(cmdToData(cmd), data, size);
+       if (writeRet) {
+               LOGE(SIM_DAEMON, "Error in writing Data to CA: response returned with error code %d, message '%s'",
+                                writeRet.value(),
+                                writeRet.category().name());
+               result = TEEC_ERROR_COMMUNICATION;
+       }
+       return result;
+}
+
+SecurityContext TEEConnectionHandler::getSecurityContext(){
+       return secContext;
+}
+
+TEEConnectionHandler::~TEEConnectionHandler() {
+       LOGD(SIM_DAEMON, "Entry");
+       delete TEECtx;
+       TEECtx = NULL;
+}
index c881ea251707bfd549029b7faa7720e3b1c2fe9e..bef3ed0aa7e1e5a12fe54ca77d75cee7f60009f0 100644 (file)
@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2015-2017 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2015-2018 Samsung Electronics Co., Ltd All Rights Reserved
  *
  *    Licensed under the Apache License, Version 2.0 (the "License");
  *    you may not use this file except in compliance with the License.
@@ -26,6 +26,7 @@
  *-----------------------------------------------------------------------------*/
 #include "TEEContext.h"
 #include "TABinaryManager.h"
+#include "TEEConnectionHandler.h"
 
 /*-----------------------------------------------------------------------------
  *  Globals
@@ -42,7 +43,7 @@ uint32_t sessID = 51;
  * @param contextID ID for Context reference
  * @param connSession ConnectionSession instance associated with the context
  */
-TEEContext::TEEContext(uint32_t contextID, IConnectionSession* connSession):
+TEEContext::TEEContext(uint32_t contextID, TEEConnectionHandler* connSession):
     secContext(connSession->getSecurityContext()) {
        LOGD(SIM_DAEMON, "ContextID: %d", contextID);