Add core of ima-evm-service 40/26740/1
authorJanusz Kozerski <j.kozerski@samsung.com>
Thu, 28 Aug 2014 11:41:46 +0000 (13:41 +0200)
committerJanusz Kozerski <j.kozerski@samsung.com>
Thu, 28 Aug 2014 11:41:46 +0000 (13:41 +0200)
This is just copy of source from security-server (core stuff).
Code builds, but is non-functional. Some fix needs to be done.

Change-Id: I854e874a1586aa8349fce3ae4caa2d23af98007a
Signed-off-by: Janusz Kozerski <j.kozerski@samsung.com>
45 files changed:
CMakeLists.txt
packaging/im-ui.spec
src/CMakeLists.txt
src/include/ima-evm-server.h [new file with mode: 0644]
src/service/CMakeLists.txt [new file with mode: 0644]
src/service/client/client-common.cpp [new file with mode: 0644]
src/service/client/client-common.h [new file with mode: 0644]
src/service/common/protocols.cpp [new file with mode: 0644]
src/service/common/protocols.h [new file with mode: 0644]
src/service/common/socket-buffer.cpp [new file with mode: 0644]
src/service/common/socket-buffer.h [new file with mode: 0644]
src/service/dpl/core/include/dpl/assert.h [new file with mode: 0644]
src/service/dpl/core/include/dpl/binary_queue.h [new file with mode: 0644]
src/service/dpl/core/include/dpl/colors.h [new file with mode: 0644]
src/service/dpl/core/include/dpl/exception.h [new file with mode: 0644]
src/service/dpl/core/include/dpl/noncopyable.h [new file with mode: 0644]
src/service/dpl/core/include/dpl/noreturn.h [new file with mode: 0644]
src/service/dpl/core/include/dpl/serialization.h [new file with mode: 0644]
src/service/dpl/core/include/dpl/singleton.h [new file with mode: 0644]
src/service/dpl/core/include/dpl/singleton_impl.h [new file with mode: 0644]
src/service/dpl/core/include/dpl/singleton_safe_impl.h [new file with mode: 0644]
src/service/dpl/core/src/assert.cpp [new file with mode: 0644]
src/service/dpl/core/src/binary_queue.cpp [new file with mode: 0644]
src/service/dpl/core/src/colors.cpp [new file with mode: 0644]
src/service/dpl/core/src/exception.cpp [new file with mode: 0644]
src/service/dpl/core/src/noncopyable.cpp [new file with mode: 0644]
src/service/dpl/core/src/serialization.cpp [new file with mode: 0644]
src/service/dpl/core/src/singleton.cpp [new file with mode: 0644]
src/service/dpl/log/include/dpl/log/abstract_log_provider.h [new file with mode: 0644]
src/service/dpl/log/include/dpl/log/dlog_log_provider.h [new file with mode: 0644]
src/service/dpl/log/include/dpl/log/log.h [new file with mode: 0644]
src/service/dpl/log/include/dpl/log/old_style_log_provider.h [new file with mode: 0644]
src/service/dpl/log/src/abstract_log_provider.cpp [new file with mode: 0644]
src/service/dpl/log/src/dlog_log_provider.cpp [new file with mode: 0644]
src/service/dpl/log/src/log.cpp [new file with mode: 0644]
src/service/dpl/log/src/old_style_log_provider.cpp [new file with mode: 0644]
src/service/main/generic-event.h [new file with mode: 0644]
src/service/main/generic-socket-manager.h [new file with mode: 0644]
src/service/main/server2-main.cpp [new file with mode: 0644]
src/service/main/server2-main.h [new file with mode: 0644]
src/service/main/service-thread.h [new file with mode: 0644]
src/service/main/socket-manager.cpp [new file with mode: 0644]
src/service/main/socket-manager.h [new file with mode: 0644]
src/service/service/echo.cpp [new file with mode: 0644]
src/service/service/echo.h [new file with mode: 0644]

index 9bfdb67..a77b0ae 100644 (file)
@@ -1,5 +1,5 @@
 CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
-PROJECT(im-ui C)
+PROJECT(im-ui)
 
 INCLUDE(FindPkgConfig)
 
@@ -10,9 +10,10 @@ SET(BINDIR "${PREFIX}/bin")
 SET(RESDIR "${PREFIX}/res")
 SET(LOCALEDIR "${RESDIR}/locale")
 
-#SET(CMAKE_C_FLAGS_RELEASE "-g -O2")
-SET(CMAKE_C_FLAGS_DEBUG   "-g -O0 -ggdb")
-#SET(CMAKE_C_CFLAS_CCOV    "-g -O2 --coverage")
+SET(CMAKE_C_FLAGS_RELEASE     "-g -O2")
+SET(CMAKE_CXX_FLAGSi_RELEASE  "-g -O2 -std=c++0x")
+SET(CMAKE_C_FLAGS_DEBUG       "-g -O0 -ggdb")
+SET(CMAKE_CXX_FLAGS_DEBUG     "-g -O0 -ggdb -std=c++0x")
 
 # Set compiler warning flags
 #ADD_DEFINITIONS("-Werror")
@@ -34,6 +35,11 @@ ADD_DEFINITIONS("-DLOCALEDIR=\"${LOCALEDIR}\"")
 #SET(TARGET_IM_UIGADGET "ug-im-ui")
 SET(TARGET_IM_UIGADGET "im-ui")
 
+SET(TARGET_IMA_EVM_SERVER "ima-evm-server")
+SET(TARGET_IMA_EVM_CLIENT "ima-evm-server-client")
+SET(TARGET_SERVER_COMMON "ima-evm-server-commons")
+
+
 #${CMAKE_SOURCE_DIR}/packaging/im-ui.spec
 INSTALL(FILES
     ${CMAKE_SOURCE_DIR}/packaging/im-ui.manifest
@@ -49,4 +55,4 @@ install(FILES ${CMAKE_SOURCE_DIR}/org.tizen.im-ui.png DESTINATION /usr/share/ico
 # i18n
 ADD_SUBDIRECTORY(po)
 
-ADD_SUBDIRECTORY(src)
\ No newline at end of file
+ADD_SUBDIRECTORY(src)
index d5a52b0..b709644 100644 (file)
@@ -26,6 +26,7 @@ BuildRequires: pkgconfig(elementary)
 BuildRequires: pkgconfig(evas)
 BuildRequires: pkgconfig(glib-2.0)
 BuildRequires: pkgconfig(ui-gadget-1)
+BuildRequires: pkgconfig(libsmack)
 BuildRequires: ima-evm-utils
 BuildRequires: openssl-devel
 
@@ -36,9 +37,10 @@ Tizen Integrity Management UI
 %setup -q
 
 %define _usrdir /usr
+#%define _libdir /usr/lib
 
 %build
-%define build_type DEBUG 
+#%define build_type DEBUG 
 %{!?build_type:%define build_type "Release"}
 %cmake . -DVERSION=%{version} \
          -DCMAKE_INSTALL_PREFIX="%{_usrdir}" \
@@ -66,3 +68,6 @@ rm -rf %{buildroot}
 %{_usrdir}/bin/*
 /usr/share/icons/default/small/org.tizen.im-ui.png
 /usr/share/packages/org.tizen.im-ui.xml
+%{_usrdir}/lib/lib*
+%{_usrdir}/include/ima-evm-server/*.h
+
index 4217939..264a462 100644 (file)
@@ -4,6 +4,7 @@ pkg_check_modules(im-uigadget_pkgs
      ui-gadget-1
      evas
      #efl-assist
+     libsmack
      dlog
 )
 
@@ -36,8 +37,91 @@ TARGET_LINK_LIBRARIES(${TARGET_IM_UIGADGET}
     imaevm
 )
 
+
+###########################################################
+SET(IMA_EVM_SERVER_PATH ${PROJECT_SOURCE_DIR}/src)
+SET(SERVER2_PATH ${PROJECT_SOURCE_DIR}/src/service)
+
+SET(IMA_EVM_SERVER_SOURCES
+    ${SERVER2_PATH}/main/socket-manager.cpp
+    ${SERVER2_PATH}/main/server2-main.cpp
+    ${SERVER2_PATH}/service/echo.cpp
+)
+
+SET_SOURCE_FILES_PROPERTIES(
+    ${IMA_EVM_SERVER_SOURCES}
+    PROPERTIES
+        COMPILE_FLAGS "-D_GNU_SOURCE -fvisibility=hidden")
+
+INCLUDE_DIRECTORIES(SYSTEM
+    ${IMA_EVM_SERVER_DEP_INCLUDE_DIRS}
+    )
+
+INCLUDE_DIRECTORIES(
+    ${IMA_EVM_SERVER_PATH}/include
+    ${SERVER2_PATH}/main
+    ${SERVER2_PATH}/common
+    ${SERVER2_PATH}/service
+    ${SERVER2_PATH}/dpl/core/include
+    ${SERVER2_PATH}/dpl/log/include
+    )
+
+ADD_EXECUTABLE(${TARGET_IMA_EVM_SERVER} ${IMA_EVM_SERVER_SOURCES})
+
+TARGET_LINK_LIBRARIES(${TARGET_IMA_EVM_SERVER}
+    ${IMA_EVM_SERVER_DEP_LIBRARIES}
+    ${TARGET_SERVER_COMMON}
+#    -lcap
+    )
+
+###########################################################
+
+SET(IMA_EVM_CLIENT_VERSION_MAJOR 1)
+SET(IMA_EVM_CLIENT_VERSION ${IMA_EVM_CLIENT_VERSION_MAJOR}.0.1)
+
+INCLUDE_DIRECTORIES(
+    ${SERVER2_PATH}/client
+    ${SERVER2_PATH}/common
+    ${SERVER2_PATH}/dpl/core/include
+    ${SERVER2_PATH}/dpl/log/include
+    )
+
+SET(IMA_EVM_CLIENT_SOURCES
+    ${SERVER2_PATH}/client/client-common.cpp
+    )
+
+ADD_LIBRARY(${TARGET_IMA_EVM_CLIENT} SHARED ${IMA_EVM_CLIENT_SOURCES})
+
+SET_TARGET_PROPERTIES(
+    ${TARGET_IMA_EVM_CLIENT}
+    PROPERTIES
+        COMPILE_FLAGS "-D_GNU_SOURCE -fPIC -fvisibility=hidden" 
+        SOVERSION ${IMA_EVM_CLIENT_VERSION_MAJOR}
+        VERSION ${IMA_EVM_CLIENT_VERSION}
+    )
+
+TARGET_LINK_LIBRARIES(${TARGET_IMA_EVM_CLIENT}
+    ${IMA_EVM_SERVER_DEP_LIBRARIES}
+    ${TARGET_SERVER_COMMON}
+    )
+
+
+###########################################################
+
 INSTALL(TARGETS
     ${TARGET_IM_UIGADGET}
     DESTINATION
     ${BINDIR}
 )
+
+INSTALL(TARGETS ${TARGET_IMA_EVM_CLIENT} DESTINATION ${LIB_INSTALL_DIR})
+
+INSTALL(TARGETS ${TARGET_IMA_EVM_SERVER} DESTINATION bin)
+
+INSTALL(FILES
+    ${IMA_EVM_SERVER_PATH}/include/ima-evm-server.h
+    DESTINATION /usr/include/ima-evm-server
+    )
+
+###########################################################
+ADD_SUBDIRECTORY(service)
diff --git a/src/include/ima-evm-server.h b/src/include/ima-evm-server.h
new file mode 100644 (file)
index 0000000..43e9263
--- /dev/null
@@ -0,0 +1,1024 @@
+/*
+ *  ima-evm-server
+ *
+ *  Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Contact: Bumjin Im <bj.im@samsung.com>
+ *
+ *  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
+ *
+ */
+
+#ifndef IMA_EVM_SERVER_H
+#define IMA_EVM_SERVER_H
+
+#include <sys/types.h>
+
+/**
+ * @file    ima-evm-server.h
+ * @version 1.0
+ * @brief   This file contains APIs of the IMA-EVM Server
+*/
+
+/**
+ * @defgroup SecurityFW
+ * @{
+ *
+ * @defgroup IMA_EVM_SERVER IMA-EVM Server
+ * @version  1.0
+ * @brief    IMA-EVM Server client library functions
+ *
+*/
+
+/**
+ * @addtogroup IMA_EVM_SERVER
+ * @{
+*/
+
+/*
+ * ====================================================================================================
+ * <tt>
+ *
+ * Revision History:
+ *
+ *  -- Company Name -- | Modification Date | Description of Changes
+ *  -----------------------------------------------------------------------
+ *   --- Samsung ------ | --- 2014-08-06 -- | First created
+ *
+ *    </tt>
+ */
+
+/**
+ * \name Return Codes
+ * exported by the foundation API.
+ * result codes begin with the start error code and extend into negative direction.
+ * @{
+*/
+#define IMA_EVM_SERVER_API_SUCCESS 0
+/*! \brief   indicating the result of the one specific API is successful */
+#define IMA_EVM_SERVER_API_ERROR_SOCKET -1
+
+/*! \brief   indicating the socket between client and IMA-EVM Server has been failed  */
+#define IMA_EVM_SERVER_API_ERROR_BAD_REQUEST -2
+
+/*! \brief   indicating the response from IMA-EVM Server is malformed */
+#define IMA_EVM_SERVER_API_ERROR_BAD_RESPONSE -3
+
+/*! \brief   indicating the transmitting request has been failed */
+#define IMA_EVM_SERVER_API_ERROR_SEND_FAILED -4
+
+/*! \brief   indicating the receiving response has been failed */
+#define IMA_EVM_SERVER_API_ERROR_RECV_FAILED -5
+
+/*! \brief   indicating requesting object is not exist */
+#define IMA_EVM_SERVER_API_ERROR_NO_SUCH_OBJECT -6
+
+/*! \brief   indicating the authentication between client and server has been failed */
+#define IMA_EVM_SERVER_API_ERROR_AUTHENTICATION_FAILED -7
+
+/*! \brief   indicating the API's input parameter is malformed */
+#define IMA_EVM_SERVER_API_ERROR_INPUT_PARAM -8
+
+/*! \brief   indicating the output buffer size which is passed as parameter is too small */
+#define IMA_EVM_SERVER_API_ERROR_BUFFER_TOO_SMALL -9
+
+/*! \brief   indicating system  is running out of memory state */
+#define IMA_EVM_SERVER_API_ERROR_OUT_OF_MEMORY -10
+
+/*! \brief   indicating the access has been denied by IMA-EVM Server */
+#define IMA_EVM_SERVER_API_ERROR_ACCESS_DENIED -11
+
+/*! \brief   indicating IMA-EVM Server has been failed for some reason */
+#define IMA_EVM_SERVER_API_ERROR_SERVER_ERROR -12
+
+/*! \brief   indicating the error with unknown reason */
+#define IMA_EVM_SERVER_API_ERROR_UNKNOWN -255
+/** @}*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+
+/**
+ * \par Description:
+ * Retreives Linux group ID from object name which is passed by parameter
+ *
+ * \par Purpose:
+ * This API may be used before ima_evm_server_check_privilege() API by middleware daemon to get group ID of a specific object.
+ *
+ * \par Typical use case:
+ * In middleware daemon, before checking privilege of a service the daemon need to know the GID of the service. This API support the functionality.
+ *
+ * \par Method of function operation:
+ * Opens /etc/group file and searches the object name as group name. If there is matching result, returns GID as integer
+ *
+ * \par Sync (or) Async:
+ * This is a Synchronous API.
+ *
+ * \par Important notes:
+ * - This API is only allowed to be called by pre-defined middleware daemon
+ *
+ * \param[in] object Name of the object which is kwnown by the caller.
+ *
+ * \return matching gid (positive integer) on success, or negative error code on error.
+ *
+ * \par Prospective clients:
+ * Inhouse middleware
+ *
+ * \par Known issues/bugs:
+ * None
+ *
+ * \pre None
+ *
+ * \post None
+ *
+ * \see /etc/group,
+ * ima_evm_server_get_object_name(), ima_evm_server_check_privilege()
+ *
+ * \remarks None
+ *
+ * \par Sample code:
+ * \code
+ * #include <ima-evm-server.h>
+ * ...
+ * int retval;
+ *
+ * // You have to make sure that  the input param '*object' is defined in the platform
+ * retval = ima_evm_server_get_gid("telephony_makecall");
+ * if(retval < 0)
+ * {
+ *      printf("%s", "Error has occurred\n");
+ *      exit(0);
+ * }
+ * ...
+ * \endcode
+*/
+int ima_evm_server_get_gid(const char *object);
+
+
+
+/**
+ * \par Description:
+ * Retreives object name as mull terminated string from Linux group ID which is passed by parameter
+ *
+ * \par Purpose:
+ * This API may be used to get object name if the caller process only knows GID of the object.
+ *
+ * \par Typical use case:
+ * In middleware daemon, by some reason, need to know object name from the Linux group ID, then call this API to retrieve object name as string
+ *
+ * \par Method of function operation:
+ * Opens /etc/group file and searches matching gid. If there is matching result, returns name of the group as null terminated string
+ *
+ * \par Sync (or) Async:
+ * This is a Synchronous API.
+ *
+ * \par Important notes:
+ * - This API is only allowed to be called by pre-defined middleware daemon
+ *
+ * \param[in] gid Linux group ID which needed to be retrieved as object name.
+ * \param[out] object Place holder for matching object name for gid.
+ * \param[in] max_object_size Allocated byte size of parameter "object".
+ *
+ * \return 0 on success, or negative error code on error.
+ *
+ * \par Prospective clients:
+ * Inhouse middleware.
+ *
+ * \par Known issues/bugs:
+ * None
+ *
+ * \pre output parameter object must be malloced before calling this API not to make memory curruption
+ *
+ * \post None
+ *
+ * \see /etc/group,
+ * ima_evm_server_get_gid()
+ *
+ * \remarks None
+ *
+ * \par Sample code:
+ * \code
+ * #include <ima-evm-server.h>
+ * ...
+ * int retval;
+ * char objectname[20];
+ *
+ * // Call the API
+ * retval = ima_evm_server_get_object_name(6005, objectname, sizeof(objectname));
+ * if(retval < 0)
+ * {
+ *      printf("%s", "Error has occurred\n");
+ *      exit(0);
+ * }
+ * ...
+ * \endcode
+*/
+int ima_evm_server_get_object_name(gid_t gid, char *object, size_t max_object_size);
+
+
+
+/**
+ * \par Description:
+ * Request cookie to the IMA-EVM Server. Cookie is a random bit stream which is used as ticket for user space object.
+ *
+ * \par Purpose:
+ * This API may be used by application and client middleware process to get access to middleware daemons.
+ *
+ * \par Typical use case:
+ * When an application process wants to get access to some middleware object, first call this API to get cookie value. Then it calls the service API to get service with the cookie value.
+ *
+ * \par Method of function operation:
+ * Caller process just send request message. IMA-EVM Server checks proc file system to get list of gIDs the caller belongs, then create a random cookie and responds to caller.
+ *
+ * \par Sync (or) Async:
+ * This is a Synchronous API.
+ *
+ * \par Important notes:
+ * Cookie needs to be stored relatively secure.
+ *
+ * \param[out] cookie Place holder for cookie value.
+ * \param[in] max_cookie Allocated byte size of parameter "cookie".
+ *
+ * \return 0 on success, or negative error code on error.
+ *
+ * \par Prospective clients:
+ * Any process
+ *
+ * \par Known issues/bugs:
+ * None
+ *
+ * \pre output parameter cookie must be malloced before calling this API not to make memory curruption
+ * Size of the cookie can be retrieved by ima_evm_server_get_cookie_size() API.
+ *
+ * \post None
+ *
+ * \see ima_evm_server_check_privilege(), ima_evm_server_get_cookie_size()
+ *
+ * \remarks None
+ *
+ * \par Sample code:
+ * \code
+ * #include <ima-evm-server.h>
+ * ...
+ * int retval;
+ * size_t cookie_size;
+ * cookie_size = ima_evm_server_get_cookie_size();
+ * unsigned char cookie[cookie_size];
+ *
+ * // Call the API
+ * retval = ima_evm_server_request_cookie(cookie, cookie_size);
+ * if(retval < 0)
+ * {
+ *      printf("%s", "Error has occurred\n");
+ *      exit(0);
+ * }
+ * ...
+ * \endcode
+*/
+int ima_evm_server_request_cookie(char *cookie, size_t max_cookie);
+
+
+
+/**
+ * \par Description:
+ * This API gets the cookie's byte size which is issued by IMA-EVM Server.
+ *
+ * \par Purpose:
+ * This API may be used by application and middleware process to get size of cookie before getting and storing cookie value.
+ *
+ * \par Typical use case:
+ * When an application process wants to get access to some middleware object, first call this API to get cookie value. Then it calls the service API to get service with the cookie value.
+ *
+ * \par Method of function operation:
+ * This API just returns pre-defined integer value as cookie size.
+ *
+ * \par Sync (or) Async:
+ * This is a Synchronous API.
+ *
+ * \par Important notes:
+ * None
+ *
+ * \return Always returns byte size of the cookie.
+ *
+ * \par Prospective clients:
+ * Any process
+ *
+ * \par Known issues/bugs:
+ * None
+ *
+ * \pre None
+ *
+ * \post None
+ *
+ * \see ima_evm_server_request_cookie()
+
+ * \remarks None
+ *
+ * \par Sample code:
+ * \code
+ * #include <ima-evm-server.h>
+ * ...
+ * int retval;
+ * size_t cookie_size;
+ *
+ * // API calling
+ * cookie_size = ima_evm_server_get_cookie_size();
+ * unsigned char cookie[cookie_size];
+ *
+ * char objectname[20];
+ * retval = ima_evm_server_request_cookie(cookie, cookie_size);
+ * if(retval < 0)
+ * {
+ *      printf("%s", "Error has occurred\n");
+ *      exit(0);
+ * }
+ * ...
+ * \endcode
+*/
+int ima_evm_server_get_cookie_size(void);
+
+
+
+/**
+ * \par Description:
+ * This API checks the cookie is allowed to access to given object.
+ *
+ * \par Purpose:
+ * This API may be used by middleware process to ask the client application has privilege for the given object.
+ *
+ * \par Typical use case:
+ * When middleware server receives request message from client application process with cookie value, it calls this API to ask to IMA-EVM Server that the client application has privilege to access the service. If yes, then the middleware daemon can continue service, if not, it can return error to client application.
+ *
+ * \par Method of function operation:
+ * When IMA-EVM Server receives this request, it searches cookie database and check the cookie is there, if there is matching cookie, then it checks the cookie has the privilege. It returns success if there is match, if not, it returns error.
+ *
+ * \par Sync (or) Async:
+ * This is a Synchronous API.
+ *
+ * \par Important notes:
+ * Cookie value needs to be stored relatively secure\n
+ * Privilege should be pre-defined by Platform design.
+ *
+ * \param[in] cookie Received cookie value from client application
+ * \param[in] privilege Object group ID which the client application wants to access
+ *
+ * \return 0 on success, or negative error code on error.
+ *
+ * \par Prospective clients:
+ * Only pre-defiend middleware daemons
+ *
+ * \par Known issues/bugs:
+ * None
+ * \pre None
+ *
+ * \post None
+ *
+ * \see ima_evm_server_request_cookie(), ima_evm_server_get_gid(), ima_evm_server_get_cookie_size()
+ *
+ * \remarks None
+ *
+ * \par Sample code:
+ * \code
+ * #include <ima-evm-server.h>
+ * ...
+ * int retval;
+ * size_t cookie_size;
+ * int call_gid;
+ * cookie_size = ima_evm_server_get_cookie_size();
+ * unsigned char recved_cookie[cookie_size];
+ *
+ * ... // Receiving request with cookie
+ *
+ * call_gid = ima_evm_server_get_gid("telephony_makecall");
+ * retval = ima_evm_server_check_privilege(recved_cookie, (gid_t)call_gid);
+ * if(retval < 0)
+ * {
+ *      if(retval == IMA_EVM_SERVER_API_ERROR_ACCESS_DENIED)
+ *      {
+ *              printf("%s", "access has been denied\n");
+ *              return;
+ *      }
+ *      printf("%s", "Error has occurred\n");
+ * }
+ * ...
+ *
+ * \endcode
+*/
+int ima_evm_server_check_privilege(const char *cookie, gid_t privilege);
+
+int ima_evm_server_check_privilege_by_cookie(const char *cookie,
+                                              const char *object,
+                                              const char *access_rights);
+
+int ima_evm_server_check_privilege_by_sockfd(int sockfd,
+                                              const char *object,
+                                              const char *access_rights);
+
+/**
+ * \par Description:
+ * This API searchs a cookie value and returns PID of the given cookie.
+ *
+ * \par Purpose:
+ * This API may be used by middleware process to ask the client application has privilege for the given object.
+ *
+ * \par Typical use case:
+ * In some cases, a middleware server wants to know PID of the application process. But if the middleware server uses non-direct IPC such as dbus, it's nearly impossible to know and guarantee peer PID. By using this API, the middleware server can retrieve a PID of the requesting process.
+ *
+ * \par Method of function operation:
+ * When IMA-EVM Server receives this request, it searches cookie database and check the cookie is there, if there is matching cookie, then it returns corresponding PID for the cookie.
+ *
+ * \par Sync (or) Async:
+ * This is a Synchronous API.
+ *
+ * \par Important notes:
+ * Cookie value needs to be stored relatively secure\n
+ * This API is abled to be called only by pre-defined middleware servers.
+ *
+ * \param[in] cookie Received cookie value from client application. Cookie is not a null terminated human readable string. Make sure you're code doesn't have any string related process on the cookie.
+ *
+ * \return positive integer on success meaning the PID, 0 means the cookie is for root process, negative integer error code on error.
+ *
+ * \par Prospective clients:
+ * Only pre-defiend middleware daemons
+ *
+ * \par Known issues/bugs:
+ * None
+ *
+ * \pre None
+ *
+ * \post None
+ *
+ * \see ima_evm_server_request_cookie(), ima_evm_server_get_cookie_size()
+ *
+ * \remarks the cookie is not a null terminated string. Cookie is a BINARY byte stream of such length which can be retrieved by ima_evm_server_get_cookie_size() API.
+ * Therefore, please do not use strcpy() family to process cookie value. You MUST use memcpy() function to process cookie value.
+ * You also have to know that the cookie value doesn't carry any null terminator. So you don't need to allocate 1 more byte of the cookie size.
+ *
+ * \par Sample code:
+ * \code
+ * #include <ima-evm-server.h>
+ * ...
+ * int peerpid;
+ * size_t cookie_size;
+ * gid_t call_gid;
+ * cookie_size = ima_evm_server_get_cookie_size();
+ * unsigned char recved_cookie[cookie_size];
+ *
+ * ... // Receiving request with cookie
+ *
+ * peerpid = ima_evm_server_get_cookie_pid(recved_cookie);
+ * if(peerpid < 0)
+ * {
+ *      printf("%s", "Error has occurred\n");
+ * }
+ * ...
+ *
+ * \endcode
+*/
+int ima_evm_server_get_cookie_pid(const char *cookie);
+
+
+
+/**
+ * \par Description:
+ * This API checks phone validity of password, to check existance, expiration, remaining attempts.
+ *
+ * \par Purpose:
+ * This API should be used by applications which needs phone password check. Caller application should behave properly after this API call.
+ *
+ * \par Typical use case:
+ * Lock screen can call this API before it shows unlock screen, if there is password, lock screen can show password input UI, if not, lock screen can show just unlock screen
+ *
+ * \par Method of function operation:
+ * Sends a validate request to ima-evm server and ima-evm server replies with password information.
+ *
+ * \par Sync (or) Async:
+ * This is a Synchronous API.
+ *
+ * \par Important notes:
+ * Password file should be stored safely. The password file will be stored by ima-evm server and only allowed itself to read/write, and data is will be securely hashed\n
+ *
+ * \param[out] current_attempts Number of password check missed attempts.
+ * \param[out] max_attempts Number of maximum attempts that the password locks. 0 means infinite
+ * \param[out] valid_secs Remaining time in second which represents this password will be expired. 0xFFFFFFFF means infinite
+ *
+ * \return 0 if there is no password set, other negative integer error code on error.
+ *
+ * \par Prospective clients:
+ * Applications which can unlock UI
+ *
+ * \par Known issues/bugs:
+ * None
+ *
+ * \pre None
+ *
+ * \post None
+ *
+ * \see ima_evm_server_set_pwd(), ima_evm_server_chk_pwd()
+ *
+ * \remarks If password file is currupted or accitentally deleted, this API may not synchronized with ima-evm-server, but ima-evm-server will check file status on next request.
+ *
+ * \par Sample code:
+ * \code
+ * #include <ima-evm-server.h>
+ * ...
+ * int ret;
+ * unsigned int attempt, max_attempt, expire_sec;
+ *
+ * ret = ima_evm_server_is_pwd_valid(&attempt, &max_attempt, &expire_sec);
+ * if(is_pwd_set == IMA_EVM_SERVER_API_ERROR_NO_PASSWORD)
+ * {
+ *      printf("%s", "There is no password exists\n");
+ * }
+ * else if(is_pwd_set == IMA_EVM_SERVER_SUCCESS && expire_sec > 0 && attempt < max_attempts)
+ * {
+ *     printf("%s", "Password is valid by now\n");
+ * }
+ * else
+ * {
+ *     printf("%s", "Something wrong\n");
+ * }
+ * ...
+ *
+ * \endcode
+*/
+int ima_evm_server_is_pwd_valid(unsigned int *current_attempts,
+                                 unsigned int *max_attempts,
+                                 unsigned int *valid_secs);
+
+
+
+/**
+ * \par Description:
+ * This API sets phone password only if current password matches.
+ *
+ * \par Purpose:
+ * This API should be used by setting application when the user changes his/her phone password.
+ *
+ * \par Typical use case:
+ * Setting application calls this API to change phone password. Caller needs current password to grant the change.
+ *
+ * \par Method of function operation:
+ * Sends current password with new password to ima-evm-server, ima-evm-server checks current password and set new password to current only when current password is correct. Caller application can determine maximum number of attempts and expiration time in days
+ *
+ * \par Sync (or) Async:
+ * This is a Synchronous API.
+ *
+ * \par Important notes:
+ * There is retry timer on this API to limit replay attack. You will get error if you called this API too often.\n
+ *
+ * \param[in] cur_pwd Null terminated current password string. It can be NULL pointer if there is no password set yet - by calling ima_evm_server_is_pwd_empty()
+ * \param[in] new_pwd Null terminated new password string. It must not a NULL pointer.
+ * \param[in] max_challenge Maximum number of attempts that user can try to check the password without success in serial. 0 means infinity.
+ * \param[in] valid_period_in_days. Number of days that this password is valid. 0 means infinity
+ *
+ * \return 0 on seccuess, negative integer error code on error.
+ *
+ * \par Prospective clients:
+ * Platform's THE ONLY setting application and some dedicated privileged processes
+ *
+ * \par Known issues/bugs:
+ * None
+ *
+ * \pre None
+ *
+ * \post None
+ *
+ * \see ima_evm_server_is_pwd_valid(), ima_evm_server_chk_pwd(), ima_evm_server_reset_pwd()
+ *
+ * \remarks Only setting application can call this API. The password file will be acces controlled and securely hashed. IMA-EVM-server will remain previous password file to recover unexpected password file curruption.
+ * \remarks If current password exists and it's expired, or max attempts reached, you cannot call this API. You have to call ima_evm_server_reset_pwd() API.
+ *
+ * \par Sample code:
+ * \code
+ * #include <ima-evm-server.h>
+ * ...
+ * int ret;
+ * unsigned int attempt, max_attempt, expire_sec;
+ *
+ * ret = ima_evm_server_is_pwd_valid(&attempt, &max_attempt, &expire_sec);
+ * if(is_pwd_set == IMA_EVM_SERVER_API_ERROR_NO_PASSWORD)
+ * {
+ *      printf("%s", "There is no password exists\n");
+ *     ret = ima_evm_server_set_pwd(NULL, "this_is_new_pwd", 20, 365);
+ *      if(ret != IMA_EVM_SERVER_API_SUCCESS)
+ *      {
+ *              printf("%s", "we have error\n");
+ *              ...
+ *      }
+ * }
+ * else if(is_pwd_set == IMA_EVM_SERVER_SUCCESS && expire_sec > 0 && attempt < max_attempts)
+ * {
+ *     printf("%s", "Password is valid by now\n");
+ *      ret = ima_evm_server_set_pwd("this_is_current_pwd", "this_is_new_pwd", 20, 365);
+ *      if(ret != IMA_EVM_SERVER_API_SUCCESS)
+ *      {
+ *              printf("%s", "we have error\n");
+ *              ...
+ *      }
+ * }
+ * else
+ * {
+ *     printf("%s", "Something wrong\n");
+ * }
+ * ...
+ *
+ * \endcode
+*/
+int ima_evm_server_set_pwd(const char *cur_pwd,
+                            const char *new_pwd,
+                            const unsigned int max_challenge,
+                            const unsigned int valid_period_in_days);
+
+
+/**
+ * \par Description:
+ * This API sets validity period for currently setup password.
+ *
+ * \par Purpose:
+ * This API should be used by Enterprise authorities to modify password policy. To be used only with valid password setup.
+ *
+ * \par Typical use case:
+ * Authorized application calls this API to change current passwords validity when password policy needs to be changed.
+ *
+ * \par Method of function operation:
+ * Function attempts to find currently set password and changes its current validity to passed number of days. Retry counter for the password is reset to zero.
+ * If there is no password set, function returns proper error code.
+ *
+ * \par Sync (or) Async:
+ * This is a Synchronous API.
+ * \param[in] valid_period_in_days. Number of days that this password is valid. 0 means infinity
+ *
+ * \return 0 on success, negative integer error code on error.
+ *
+ * \par Prospective clients:
+ * Platform's THE ONLY setting application and some dedicated privileged processes
+ *
+ * \par Known issues/bugs:
+ * Identifying calling peer is not ready yet, should be based on SMACK somehow.
+ *
+ * \see ima_evm_server_is_pwd_valid(), ima_evm_server_chk_pwd(), ima_evm_server_reset_pwd()
+ */
+int ima_evm_server_set_pwd_validity(const unsigned int valid_period_in_days);
+
+
+/**
+ * \par Description:
+ * This API sets maximum number of attempts for currently setup password.
+ *
+ * \par Purpose:
+ * This API should be used by Enterprise authorities to modify password policy. To be used only with valid password setup.
+ *
+ * \par Typical use case:
+ * Authorized application calls this API to change current passwords max attempt number when password policy needs to be changed.
+ *
+ * \par Method of function operation:
+ * Function attempts to find currently set password and changes its max attempt number to passed one. Retry counter for the password is reset to zero.
+ * If there is no password set, function returns proper error code.
+ *
+ * \par Sync (or) Async:
+ * This is a Synchronous API.
+ * \param[in] max_challenge Maximum number of attempts that user can try to check the password without success in serial. 0 means infinity.
+ *
+ * \return 0 on success, negative integer error code on error.
+ *
+ * \par Prospective clients:
+ * Platform's THE ONLY setting application and some dedicated privileged processes
+ *
+ * \par Known issues/bugs:
+ * Identifying calling peer is not ready yet, should be based on SMACK somehow.
+ *
+ * \see ima_evm_server_is_pwd_valid(), ima_evm_server_chk_pwd(), ima_evm_server_reset_pwd()
+ */
+int ima_evm_server_set_pwd_max_challenge(const unsigned int max_challenge);
+
+/**
+ * \par Description:
+ * This API sets phone password only if current password is invalid or user forgot the password.
+ *
+ * \par Purpose:
+ * This API should be used by setting application or dedicated processes when the user changes his/her phone password.
+ *
+ * \par Typical use case:
+ * User forgots the password. He calls emergency manager(auto or manual)  for reset password. Emergency manager calls this API and reset phone password.
+ *
+ * \par Method of function operation:
+ * Resetting phone password with input string without any matching current password.
+ *
+ * \par Sync (or) Async:
+ * This is a Synchronous API.
+ *
+ * \par Important notes:
+ * There is retry timer on this API to limit replay attack. You will get error if you called this API too often.\n
+ *
+ * \param[in] new_pwd Null terminated new password string. It must not a NULL pointer.
+ * \param[in] max_challenge Maximum number of attempts that user can try to check the password without success in serial. 0 means infinity.
+ * \param[in] valid_period_in_days. Number of days that this password is valid. 0 means infinity
+ *
+ * \return 0 on seccuess, negative integer error code on error.
+ *
+ * \par Prospective clients:
+ * Platform's THE ONLY setting application and some dedicated privileged processes
+ *
+ * \par Known issues/bugs:
+ * None
+ *
+ * \pre None
+ *
+ * \post None
+ *
+ * \see ima_evm_server_is_pwd_valid(), ima_evm_server_chk_pwd(), ima_evm_server_set_pwd()
+ *
+ * \remarks Only dedicated applications can call this API. The password file will be acces controlled and securely hashed. IMA-EVM-server will remain previous password file to recover unexpected password file curruption.
+ *
+ * \par Sample code:
+ * \code
+ * #include <ima-evm-server.h>
+ * ...
+ * int ret;
+ * unsigned int attempt, max_attempt, expire_sec;
+ *
+ *      ret = ima_evm_server_set_pwd("this_is_new_pwd", 20, 365);
+ *      if(retval != IMA_EVM_SERVER_API_SUCCESS)
+ *      {
+ *              printf("%s", "we have error\n");
+ *              ...
+ *      }
+ * ...
+ *
+ * \endcode
+*/
+int ima_evm_server_reset_pwd(const char *new_pwd,
+                              const unsigned int max_challenge,
+                              const unsigned int valid_period_in_days);
+
+/**
+ * \par Description:
+ * This API compares stored phone password with challenged input value.
+ *
+ * \par Purpose:
+ * This API should be used by applications which has phone UI lock capability.
+ *
+ * \par Typical use case:
+ * Lock screen calls this API after user typed phone password and pressed okay.
+ *
+ * \par Method of function operation:
+ * Sends challenged password to ima-evm-server, ima-evm-server compares hashed current password and hashed challenged password.
+ *
+ * \par Sync (or) Async:
+ * This is a Synchronous API.
+ *
+ * \par Important notes:
+ * There is retry timer on this API to limit replay attack. You will get error if you called this API too often.\n
+ *
+ * \param[in] challenge Null terminated challenged password string. It must not a NULL pointer.
+ * \param[out] current_attempts Number of password check missed attempts.
+ * \param[out] max_attempts Number of maximum attempts that the password locks. 0 means infinite
+ * \param[out] valid_secs Remaining time in second which represents this password will be expired. 0xFFFFFFFF means infinite
+ *
+ * \return 0 on seccuess, negative integer error code on error.
+ *
+ * \par Prospective clients:
+ * Applications which has phone UI lock feature.
+ *
+ * \par Known issues/bugs:
+ * None
+ *
+ * \pre None
+ *
+ * \post None
+ *
+ * \see ima_evm_server_is_pwd_valid(), ima_evm_server_set_pwd()
+ *
+ * \remarks The password file will be acces controlled and securely hashed. IMA-EVM-server will remain previous password file to recover unexpected password file curruption.
+ *
+ * \par Sample code:
+ * \code
+ * #include <ima-evm-server.h>
+ * ...
+ * int retval;
+ * unsigned int attempt, max_attempt, expire_sec;
+ *
+ * retval = ima_evm_server_chk_pwd("is_this_password", &attmpt, &max_attempt, &expire_sec);
+ * if(retval == IMA_EVM_SERVER_API_ERROR_PASSWORD_MISMATCH)
+ * {
+ *      printf("%s", "Oh you typed wrong password\n");
+ *      ...
+ * }
+ * else if(retval == IMA_EVM_SERVER_API_SUCCESS)
+ * {
+ *      printf("%s", "You remember your password.\n");
+ *      ...
+ * }
+ * ...
+ *
+ * \endcode
+*/
+int ima_evm_server_chk_pwd(const char *challenge,
+                            unsigned int *current_attempt,
+                            unsigned int *max_attempt,
+                            unsigned int *valid_secs);
+
+
+/**
+ * \par Description:
+ * This API set the number of password history which should be maintained. Once this number set, user cannot reuse recent number of passwords which is described in this history value
+ *
+ * \par Purpose:
+ * This API should be used only by dedicated process in the platform.
+ *
+ * \par Typical use case:
+ * Enterprise manager calls this API when the enterprise wants to enforce harder password policy.
+ *
+ * \par Method of function operation:
+ * When enterprise manager (MDM) is trying to change the security policy for phone password, it calls this API background to change the history policy.
+ *
+ * \par Sync (or) Async:
+ * This is a Synchronous API.
+ *
+ * \par Important notes:
+ * There is retry timer on this API to limit replay attack. You will get error if you called this API too often.\n
+ *
+ * \param[in] number_of_history Number of history to be checked when user tries to change password. Maximum is currently 50
+ *
+ * \return 0 on seccuess, negative integer error code on error.
+ *
+ * \par Prospective clients:
+ * MDM client, Enterprise manager.
+ *
+ * \par Known issues/bugs:
+ * None
+ *
+ * \pre None
+ *
+ * \post None
+ *
+ * \see ima_evm_server_set_pwd()
+ *
+ * \remarks The password file will be acces controlled and securely hashed. Ima-evm-server will remain previous password file to recover unexpected password file curruption.
+ *
+ * \par Sample code:
+ * \code
+ * #include <ima-evm-server.h>
+ * ...
+ * int retval;
+ *
+ * ret = ima_evm_server_set_pwd_history(100);
+ *     if(ret != IMA_EVM_SERVER_API_SUCCESS)
+ *     {
+ *             printf("%s", "You have error\n");
+ *             ...
+ *     }
+ * ...
+ *
+ * \endcode
+*/
+int ima_evm_server_set_pwd_history(int number_of_history);
+
+
+
+/**
+ * \par Description:
+ * This API launches /usr/bin/debug-util as root privilege.
+ *
+ * \par Purpose:
+ * This API will be used only by SDK with developer privilege to launch debugging tool to debug as the developing applicaion's privilege.
+ *
+ * \par Typical use case:
+ * During appliation development, SDK opens a shell to install, launch, and debug the developing application. But the shell will not have any privilege to control platform. Therefore we need a special utility to manage debugging environement as same privilege level of the application. If this API is called, ima-evm server will launch the debug utility as root privilege and the utility will drop its privilege same as developing application
+ *
+ *
+ * \par Method of function operation:
+ * When IMA-EVM Server receives this request, it checks uid of the client, and launches /usr/bin/debug-util with given arguements.
+ *
+ * \par Sync (or) Async:
+ * This is a Synchronous API.
+ *
+ * \par Important notes:
+ * Caller process of this API must be owned by developer user.\n
+ * The caller process will be pre-defined.
+ * /usr/bin/debug-util itself must be omitted in the argv. IMA-EVM server will put this as first argv in the execution procedure
+ *
+ * \param[in] argc Number of arguements.
+ *
+ * \param[in] argv Arguements
+ *
+ * \return 0 on success, negative integer error code on error.
+ *
+ * \par Prospective clients:
+ * Only pre-defiend debugging utility.
+ *
+ * \par Known issues/bugs:
+ * None
+ *
+ * \pre None
+ *
+ * \post None
+ *
+ * \see None
+ *
+ * \remarks Calling this API, you have to put argv[1] of the debug-util as argv[0] of this API. IMA-EVM server will put argv[0] automatically
+ *
+ * \par Sample code:
+ * \code
+ * #include <ima-evm-server.h>
+ * #define DEVELOPER_UID 5500
+ *
+ * int main(int argc, char **argv)
+ * {
+ *      int my_uid, ret;
+ *      uid = getuid();
+ *      if(uid != DEVELOPER_UID)
+ *      {
+ *              // You must be developer user
+ *              exit(1);
+ *      }
+ *
+ *      ret = ima_evm_server_launch_debug_tool(argc -1, argv++)
+ *      if(ret != IMA_EVM_SERVER_SUCCESS)
+ *      {
+ *              // Some error occurred
+ *              exit(1);
+ *      }
+ *      ...
+ * }
+ *
+ * \endcode
+*/
+int ima_evm_server_launch_debug_tool(int argc, const char **argv);
+
+/*
+ * This function allows to get process SMACK label by passing cookie assigned
+ * to process. Function returns pointer to allocated buffer with label.
+ * User has to free the buffer after using.
+ *
+ * \param[in] Pointer to cookie
+ *
+ * \return Pointer to SMACK label or NULL
+ *
+ * \par For free label use free(), label allocated by calloc()
+ *      User responsibility is to free resource.
+ */
+char *ima_evm_server_get_smacklabel_cookie(const char *cookie);
+
+/*
+ * This function allows to get process SMACK label by passing socket descriptor.
+ * Function returns pointer to allocated buffer with label.
+ * User has to free the buffer after using.
+ *
+ * \param[in] Socket descriptor
+ *
+ * \return Pointer to SMACK label or NULL
+ *
+ * \par For free label use free(), label allocated by calloc().
+ *      User responsibility is to free resource.
+ */
+char *ima_evm_server_get_smacklabel_sockfd(int fd);
+
+/*
+ * This function will give permissions "rwxat" from
+ * (subject) customer_label to caller process (object).
+ * Object label will be extracted from socket.
+ * */
+int ima_evm_server_app_give_access(const char *customer_label, int customer_pid);
+
+/*
+ * This function allows middleware to check priviliges of process with specified PID.
+ * Service is able to check proces acces to the specified object label with specified
+ * access rights.
+ *
+ * \param[in] PID number of process to be checked
+ * \param[in] SMACK object label
+ * \param[in] SMACK access rights to be checked
+ *
+ * \return Privilege confirm or error code
+ * IMA_EVM_SERVER_SUCCESS - on succes
+ */
+int ima_evm_server_check_privilege_by_pid(int pid, const char *object, const char *access_rights);
+
+#ifdef __cplusplus
+}
+#endif
+
+/**
+ * @}
+*/
+
+/**
+ * @}
+*/
+
+#endif
diff --git a/src/service/CMakeLists.txt b/src/service/CMakeLists.txt
new file mode 100644 (file)
index 0000000..a5d6167
--- /dev/null
@@ -0,0 +1,49 @@
+PKG_CHECK_MODULES(COMMON_DEP
+    REQUIRED
+    dlog
+    libsmack
+    )
+
+SET(COMMON_PATH ${PROJECT_SOURCE_DIR}/src/service)
+
+SET(COMMON_SOURCES
+    ${COMMON_PATH}/common/protocols.cpp
+    ${COMMON_PATH}/common/socket-buffer.cpp
+    ${COMMON_PATH}/dpl/log/src/abstract_log_provider.cpp
+    ${COMMON_PATH}/dpl/log/src/dlog_log_provider.cpp
+    ${COMMON_PATH}/dpl/log/src/log.cpp
+    ${COMMON_PATH}/dpl/log/src/old_style_log_provider.cpp
+    ${COMMON_PATH}/dpl/core/src/assert.cpp
+    ${COMMON_PATH}/dpl/core/src/binary_queue.cpp
+    ${COMMON_PATH}/dpl/core/src/colors.cpp
+    ${COMMON_PATH}/dpl/core/src/exception.cpp
+    ${COMMON_PATH}/dpl/core/src/noncopyable.cpp
+    ${COMMON_PATH}/dpl/core/src/serialization.cpp
+    ${COMMON_PATH}/dpl/core/src/singleton.cpp
+    )
+
+INCLUDE_DIRECTORIES(
+    ${COMMON_PATH}/common
+    ${COMMON_PATH}/dpl/core/include
+    ${COMMON_PATH}/dpl/log/include
+    ${COMMON_DEP_INCLUDE_DIRS}
+    )
+
+ADD_LIBRARY(${TARGET_SERVER_COMMON} SHARED ${COMMON_SOURCES})
+
+SET_TARGET_PROPERTIES(
+    ${TARGET_SERVER_COMMON}
+    PROPERTIES
+        COMPILE_FLAGS "-D_GNU_SOURCE -fPIC -fvisibility=default"
+        SOVERSION 1.0.0
+        VERSION 1.0.0
+    )
+
+TARGET_LINK_LIBRARIES(${TARGET_SERVER_COMMON}
+    ${COMMON_DEP_LIBRARIES}
+    )
+
+################################################################################
+
+INSTALL(TARGETS ${TARGET_SERVER_COMMON} DESTINATION lib)
+
diff --git a/src/service/client/client-common.cpp b/src/service/client/client-common.cpp
new file mode 100644 (file)
index 0000000..2c7c973
--- /dev/null
@@ -0,0 +1,217 @@
+/*
+ *  Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Contact: Bumjin Im <bj.im@samsung.com>
+ *
+ *  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        client-common.cpp
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version     1.0
+ * @brief       This file is implementation of client-common functions.
+ */
+
+#include <fcntl.h>
+#include <poll.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+
+#include <dpl/log/log.h>
+#include <dpl/serialization.h>
+#include <dpl/singleton.h>
+#include <dpl/singleton_safe_impl.h>
+
+#include <socket-buffer.h>
+
+#include <ima-evm-server.h>
+
+IMPLEMENT_SAFE_SINGLETON(IMAEVMServer::Log::LogSystem);
+
+namespace {
+
+void securityClientEnableLogSystem(void) {
+    IMAEVMServer::Singleton<IMAEVMServer::Log::LogSystem>::Instance().SetTag("IMA_EVM_SERVER_CLIENT");
+}
+
+int waitForSocket(int sock, int event, int timeout) {
+    pollfd desc[1];
+    desc[0].fd = sock;
+    desc[0].events = event;
+    int retval = poll(desc, 1, timeout);
+    if (0 == retval) {
+        LogDebug("Poll timeout");
+    } else if (-1 == retval) {
+        int err = errno;
+        LogError("Error in poll: " << strerror(err));
+    }
+    return retval;
+}
+
+class SockRAII {
+public:
+    SockRAII()
+      : m_sock(-1)
+    {}
+
+    virtual ~SockRAII() {
+        if (m_sock > -1)
+            close(m_sock);
+    }
+
+    int Connect(char const * const interface) {
+        sockaddr_un clientAddr;
+        int flags;
+
+        if (m_sock != -1) // guard
+            close(m_sock);
+
+        m_sock = socket(AF_UNIX, SOCK_STREAM, 0);
+        if (m_sock < 0) {
+            int err = errno;
+            LogError("Error creating socket: " << strerror(err));
+            return IMA_EVM_SERVER_API_ERROR_SOCKET;
+        }
+
+        if ((flags = fcntl(m_sock, F_GETFL, 0)) < 0 ||
+            fcntl(m_sock, F_SETFL, flags | O_NONBLOCK) < 0)
+        {
+            int err = errno;
+            LogError("Error in fcntl: " << strerror(err));
+            return IMA_EVM_SERVER_API_ERROR_SOCKET;
+        }
+
+        memset(&clientAddr, 0, sizeof(clientAddr));
+
+        clientAddr.sun_family = AF_UNIX;
+
+        if (strlen(interface) >= sizeof(clientAddr.sun_path)) {
+            LogError("Error: interface name " << interface << "is too long. Max len is:" << sizeof(clientAddr.sun_path));
+            return IMA_EVM_SERVER_API_ERROR_SOCKET;
+        }
+
+        strcpy(clientAddr.sun_path, interface);
+
+        LogDebug("ClientAddr.sun_path = " << interface);
+
+        int retval = TEMP_FAILURE_RETRY(connect(m_sock, (struct sockaddr*)&clientAddr, SUN_LEN(&clientAddr)));
+        if ((retval == -1) && (errno == EINPROGRESS)) {
+            if (0 >= waitForSocket(m_sock, POLLIN, 1000)) {
+                LogError("Error in waitForSocket.");
+                return IMA_EVM_SERVER_API_ERROR_SOCKET;
+            }
+            int error = 0;
+            size_t len = sizeof(error);
+            retval = getsockopt(m_sock, SOL_SOCKET, SO_ERROR, &error, &len);
+
+            if (-1 == retval) {
+                int err = errno;
+                LogError("Error in getsockopt: " << strerror(err));
+                return IMA_EVM_SERVER_API_ERROR_SOCKET;
+            }
+
+            if (error == EACCES) {
+                LogError("Access denied");
+                return IMA_EVM_SERVER_API_ERROR_ACCESS_DENIED;
+            }
+
+            if (error != 0) {
+                LogError("Error in connect: " << strerror(error));
+                return IMA_EVM_SERVER_API_ERROR_SOCKET;
+            }
+
+            return IMA_EVM_SERVER_API_SUCCESS;
+        }
+
+        if (-1 == retval) {
+            int err = errno;
+            LogError("Error connecting socket: " << strerror(err));
+            if (err == EACCES)
+                return IMA_EVM_SERVER_API_ERROR_ACCESS_DENIED;
+            return IMA_EVM_SERVER_API_ERROR_SOCKET;
+        }
+
+        return IMA_EVM_SERVER_API_SUCCESS;
+    }
+
+    int Get() {
+        return m_sock;
+    }
+
+private:
+    int m_sock;
+};
+
+} // namespace anonymous
+
+namespace IMAEVMServer {
+
+
+int sendToServer(char const * const interface, const RawBuffer &send, SocketBuffer &recv) {
+    int ret;
+    SockRAII sock;
+    ssize_t done = 0;
+    char buffer[2048];
+
+    if (IMA_EVM_SERVER_API_SUCCESS != (ret = sock.Connect(interface))) {
+        LogError("Error in SockRAII");
+        return ret;
+    }
+
+    while ((send.size() - done) > 0) {
+        if (0 >= waitForSocket(sock.Get(), POLLOUT, 1000)) {
+            LogError("Error in poll(POLLOUT)");
+            return IMA_EVM_SERVER_API_ERROR_SOCKET;
+        }
+        ssize_t temp = TEMP_FAILURE_RETRY(write(sock.Get(), &send[done], send.size() - done));
+        if (-1 == temp) {
+            int err = errno;
+            LogError("Error in write: " << strerror(err));
+            return IMA_EVM_SERVER_API_ERROR_SOCKET;
+        }
+        done += temp;
+    }
+
+    do {
+        if (0 >= waitForSocket(sock.Get(), POLLIN, 1000)) {
+            LogError("Error in poll(POLLIN)");
+            return IMA_EVM_SERVER_API_ERROR_SOCKET;
+        }
+        ssize_t temp = TEMP_FAILURE_RETRY(read(sock.Get(), buffer, 2048));
+        if (-1 == temp) {
+            int err = errno;
+            LogError("Error in read: " << strerror(err));
+            return IMA_EVM_SERVER_API_ERROR_SOCKET;
+        }
+        RawBuffer raw(buffer, buffer+temp);
+        recv.Push(raw);
+    } while(!recv.Ready());
+    return IMA_EVM_SERVER_API_SUCCESS;
+}
+
+} // namespace IMAEVMServer
+
+static void init_lib(void) __attribute__ ((constructor));
+static void init_lib(void)
+{
+    securityClientEnableLogSystem();
+}
+
+static void fini_lib(void) __attribute__ ((destructor));
+static void fini_lib(void)
+{
+
+}
+
diff --git a/src/service/client/client-common.h b/src/service/client/client-common.h
new file mode 100644 (file)
index 0000000..f3a347f
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ *  Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Contact: Bumjin Im <bj.im@samsung.com>
+ *
+ *  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        client-common.h
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version     1.0
+ * @brief       This file constains implementation of common types
+ *              used in ima-evm server.
+ */
+
+#ifndef _IMA_EVM_SERVER_CLIENT_
+#define _IMA_EVM_SERVER_CLIENT_
+
+#include <vector>
+
+#include <socket-buffer.h>
+
+namespace IMAEVMServer {
+
+typedef std::vector<unsigned char> RawBuffer;
+
+int sendToServer(char const * const interface, const RawBuffer &send, SocketBuffer &recv);
+
+} // namespace IMAEVMSever
+
+#endif // _IMA_EVM_SERVER_CLIENT_
diff --git a/src/service/common/protocols.cpp b/src/service/common/protocols.cpp
new file mode 100644 (file)
index 0000000..d5b2fff
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ *  Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Contact: Bumjin Im <bj.im@samsung.com>
+ *
+ *  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        protocols.cpp
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version     1.0
+ * @brief       List of all protocols supported by ima-evm server.
+ */
+
+#include <protocols.h>
+
+namespace IMAEVMServer {
+
+char const * const SERVICE_SOCKET_SHARED_MEMORY =
+    "/tmp/ima-evm-server-api-data-share";
+char const * const SERVICE_SOCKET_ECHO =
+    "/tmp/ima-evm-server-api-echo";
+
+} // namespace IMAEVMServer
+
diff --git a/src/service/common/protocols.h b/src/service/common/protocols.h
new file mode 100644 (file)
index 0000000..0837580
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ *  Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Contact: Bumjin Im <bj.im@samsung.com>
+ *
+ *  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        protocols.h
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version     1.0
+ * @brief       This file contains list of all protocols suported by ima-evm-sever.
+ */
+
+#ifndef _IMA_EVM_SERVER_PROTOCOLS_
+#define _IMA_EVM_SERVER_PROTOCOLS_
+
+namespace IMAEVMServer {
+
+extern char const * const SERVICE_SOCKET_SHARED_MEMORY;
+extern char const * const SERVICE_SOCKET_ECHO;
+
+} // namespace IMAEVMServer
+
+#endif // _IMA_EVM_SERVER_PROTOCOLS_
+
diff --git a/src/service/common/socket-buffer.cpp b/src/service/common/socket-buffer.cpp
new file mode 100644 (file)
index 0000000..9db9625
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ *  Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Contact: Bumjin Im <bj.im@samsung.com>
+ *
+ *  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        socket-buffer.cpp
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version     1.0
+ * @brief       Implementation of SocketBuffer.
+ */
+
+#include <socket-buffer.h>
+
+#include <dpl/log/log.h>
+
+namespace IMAEVMServer {
+
+void SocketBuffer::Push(const RawBuffer &data) {
+    LogDebug("Push data: " << data.size());
+    m_buffer.AppendCopy(&data[0], data.size());
+}
+
+RawBuffer SocketBuffer::Pop() {
+    size_t size = m_buffer.Size();
+    RawBuffer buffer;
+    buffer.resize(size + sizeof(size_t));
+    memcpy(&buffer[0], &size, sizeof(size_t));
+    m_buffer.FlattenConsume(&buffer[sizeof(size_t)], size);
+    return buffer;
+}
+
+bool SocketBuffer::Ready() {
+    CountBytesLeft();
+    LogInfo("m_buffer.Size() == " << m_buffer.Size());
+    if (m_bytesLeft == 0)
+        return false;
+    if (m_bytesLeft > m_buffer.Size())
+        return false;
+    return true;
+}
+
+void SocketBuffer::Read(size_t num, void *bytes) {
+    CountBytesLeft();
+    if (num > m_bytesLeft) {
+        LogDebug("Protocol broken. OutOfData. Asked for: " << num << " Ready: " << m_bytesLeft << " Buffer.size(): " << m_buffer.Size());
+        Throw(Exception::OutOfData);
+    }
+
+    m_buffer.FlattenConsume(bytes, num);
+    m_bytesLeft -= num;
+}
+
+void SocketBuffer::Write(size_t num, const void *bytes) {
+    m_buffer.AppendCopy(bytes, num);
+}
+
+} // namespace IMAEVMServer
+
diff --git a/src/service/common/socket-buffer.h b/src/service/common/socket-buffer.h
new file mode 100644 (file)
index 0000000..a80ef76
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ *  Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Contact: Bumjin Im <bj.im@samsung.com>
+ *
+ *  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        secket-buffer.h
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version     1.0
+ * @brief       Implementatin of SocketBuffer.
+ */
+
+#ifndef _IMA_EVM_SERVER_SOCKET_BUFFER_
+#define _IMA_EVM_SERVER_SOCKET_BUFFER_
+
+#include <vector>
+
+#include <dpl/binary_queue.h>
+#include <dpl/exception.h>
+#include <dpl/serialization.h>
+
+namespace IMAEVMServer {
+
+typedef std::vector<unsigned char> RawBuffer;
+
+class SocketBuffer : public IMAEVMServer::IStream {
+public:
+    class Exception
+    {
+    public:
+        DECLARE_EXCEPTION_TYPE(IMAEVMServer::Exception, Base)
+        DECLARE_EXCEPTION_TYPE(Base, OutOfData)
+    };
+
+    SocketBuffer()
+      : m_bytesLeft(0)
+    {}
+
+    void Push(const RawBuffer &data);
+
+    RawBuffer Pop();
+
+    bool Ready();
+
+    virtual void Read(size_t num, void *bytes);
+
+    virtual void Write(size_t num, const void *bytes);
+
+protected:
+
+    inline void CountBytesLeft() {
+        if (m_bytesLeft > 0)
+            return;  // we already counted m_bytesLeft nothing to do
+
+        if (m_buffer.Size() < sizeof(size_t))
+            return;  // we cannot count m_bytesLeft because buffer is too small
+
+        m_buffer.FlattenConsume(&m_bytesLeft, sizeof(size_t));
+    }
+
+    size_t m_bytesLeft;
+    IMAEVMServer::BinaryQueue m_buffer;
+};
+
+} // namespace IMAEVMServer
+
+#endif // _IMA_EVM_SERVER_SOCKET_BUFFER_
diff --git a/src/service/dpl/core/include/dpl/assert.h b/src/service/dpl/core/include/dpl/assert.h
new file mode 100644 (file)
index 0000000..5a09c9f
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2011 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        assert.h
+ * @author      Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version     1.0
+ * @brief       This file is the implementation file of assert
+ */
+#ifndef IMA_EVM_SERVER_ASSERT_H
+#define IMA_EVM_SERVER_ASSERT_H
+
+#include <dpl/noreturn.h>
+
+namespace IMAEVMServer {
+// Assertion handler procedure
+// Do not call directly
+// Always use Assert macro
+IMA_EVMSERVER_NORETURN void AssertProc(const char *condition,
+                             const char *file,
+                             int line,
+                             const char *function);
+} // namespace IMAEVMServer
+
+#define Assert(Condition) do { if (!(Condition)) { IMAEVMServer::AssertProc(#Condition, \
+                                                                   __FILE__, \
+                                                                   __LINE__, \
+                                                                   __FUNCTION__); \
+                               } } while (0)
+
+#endif // IMA_EVM_SERVER_ASSERT_H
diff --git a/src/service/dpl/core/include/dpl/binary_queue.h b/src/service/dpl/core/include/dpl/binary_queue.h
new file mode 100644 (file)
index 0000000..056fc18
--- /dev/null
@@ -0,0 +1,298 @@
+/*
+ * Copyright (c) 2011 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        binary_queue.h
+ * @author      Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version     1.0
+ * @brief       This file is the header file of binary queue
+ */
+#ifndef IMA_EVM_SERVER_BINARY_QUEUE_H
+#define IMA_EVM_SERVER_BINARY_QUEUE_H
+
+//#include <dpl/abstract_input_output.h>
+#include <dpl/exception.h>
+#include <dpl/noncopyable.h>
+#include <memory>
+#include <list>
+
+namespace IMAEVMServer {
+/**
+ * Binary queue auto pointer
+ */
+class BinaryQueue;
+typedef std::auto_ptr<BinaryQueue> BinaryQueueAutoPtr;
+
+/**
+ * Binary stream implemented as constant size bucket list
+ *
+ * @todo Add optimized implementation for FlattenConsume
+ */
+class BinaryQueue
+//  : public AbstractInputOutput
+{
+  public:
+    class Exception
+    {
+      public:
+        DECLARE_EXCEPTION_TYPE(IMAEVMServer::Exception, Base)
+        DECLARE_EXCEPTION_TYPE(Base, OutOfData)
+    };
+
+    typedef void (*BufferDeleter)(const void *buffer, size_t bufferSize,
+                                  void *userParam);
+    static void BufferDeleterFree(const void *buffer,
+                                  size_t bufferSize,
+                                  void *userParam);
+
+    class BucketVisitor
+    {
+      public:
+        /**
+         * Destructor
+         */
+        virtual ~BucketVisitor();
+
+        /**
+         * Visit bucket
+         *
+         * @return none
+         * @param[in] buffer Constant pointer to bucket data buffer
+         * @param[in] bufferSize Number of bytes in bucket
+         */
+        virtual void OnVisitBucket(const void *buffer, size_t bufferSize) = 0;
+    };
+
+  private:
+    struct Bucket :
+        private Noncopyable
+    {
+        const void *buffer;
+        const void *ptr;
+        size_t size;
+        size_t left;
+
+        BufferDeleter deleter;
+        void *param;
+
+        Bucket(const void *buffer,
+               size_t bufferSize,
+               BufferDeleter deleter,
+               void *userParam);
+        virtual ~Bucket();
+    };
+
+    typedef std::list<Bucket *> BucketList;
+    BucketList m_buckets;
+    size_t m_size;
+
+    static void DeleteBucket(Bucket *bucket);
+
+    class BucketVisitorCall
+    {
+      private:
+        BucketVisitor *m_visitor;
+
+      public:
+        BucketVisitorCall(BucketVisitor *visitor);
+        virtual ~BucketVisitorCall();
+
+        void operator()(Bucket *bucket) const;
+    };
+
+  public:
+    /**
+     * Construct empty binary queue
+     */
+    BinaryQueue();
+
+    /**
+     * Construct binary queue via bare copy of other binary queue
+     *
+     * @param[in] other Other binary queue to copy from
+     * @warning One cannot assume that bucket structure is preserved during copy
+     */
+    BinaryQueue(const BinaryQueue &other);
+
+    /**
+     * Destructor
+     */
+    virtual ~BinaryQueue();
+
+    /**
+     * Construct binary queue via bare copy of other binary queue
+     *
+     * @param[in] other Other binary queue to copy from
+     * @warning One cannot assume that bucket structure is preserved during copy
+     */
+    const BinaryQueue &operator=(const BinaryQueue &other);
+
+    /**
+     * Append copy of @a bufferSize bytes from memory pointed by @a buffer
+     * to the end of binary queue. Uses default deleter based on free.
+     *
+     * @return none
+     * @param[in] buffer Pointer to buffer to copy data from
+     * @param[in] bufferSize Number of bytes to copy
+     * @exception std::bad_alloc Cannot allocate memory to hold additional data
+     * @see BinaryQueue::BufferDeleterFree
+     */
+    void AppendCopy(const void *buffer, size_t bufferSize);
+
+    /**
+     * Append @a bufferSize bytes from memory pointed by @a buffer
+     * to the end of binary queue. Uses custom provided deleter.
+     * Responsibility for deleting provided buffer is transfered to BinaryQueue.
+     *
+     * @return none
+     * @param[in] buffer Pointer to data buffer
+     * @param[in] bufferSize Number of bytes available in buffer
+     * @param[in] deleter Pointer to deleter procedure used to free provided
+     * buffer
+     * @param[in] userParam User parameter passed to deleter routine
+     * @exception std::bad_alloc Cannot allocate memory to hold additional data
+     */
+    void AppendUnmanaged(
+        const void *buffer,
+        size_t bufferSize,
+        BufferDeleter deleter =
+            &BinaryQueue::BufferDeleterFree,
+        void *userParam = NULL);
+
+    /**
+     * Append copy of other binary queue to the end of this binary queue
+     *
+     * @return none
+     * @param[in] other Constant reference to other binary queue to copy data
+     * from
+     * @exception std::bad_alloc Cannot allocate memory to hold additional data
+     * @warning One cannot assume that bucket structure is preserved during copy
+     */
+    void AppendCopyFrom(const BinaryQueue &other);
+
+    /**
+     * Move bytes from other binary queue to the end of this binary queue.
+     * This also removes all bytes from other binary queue.
+     * This method is designed to be as fast as possible (only pointer swaps)
+     * and is suggested over making copies of binary queues.
+     * Bucket structure is preserved after operation.
+     *
+     * @return none
+     * @param[in] other Reference to other binary queue to move data from
+     * @exception std::bad_alloc Cannot allocate memory to hold additional data
+     */
+    void AppendMoveFrom(BinaryQueue &other);
+
+    /**
+     * Append copy of binary queue to the end of other binary queue
+     *
+     * @return none
+     * @param[in] other Constant reference to other binary queue to copy data to
+     * @exception std::bad_alloc Cannot allocate memory to hold additional data
+     * @warning One cannot assume that bucket structure is preserved during copy
+     */
+    void AppendCopyTo(BinaryQueue &other) const;
+
+    /**
+     * Move bytes from binary queue to the end of other binary queue.
+     * This also removes all bytes from binary queue.
+     * This method is designed to be as fast as possible (only pointer swaps)
+     * and is suggested over making copies of binary queues.
+     * Bucket structure is preserved after operation.
+     *
+     * @return none
+     * @param[in] other Reference to other binary queue to move data to
+     * @exception std::bad_alloc Cannot allocate memory to hold additional data
+     */
+    void AppendMoveTo(BinaryQueue &other);
+
+    /**
+     * Retrieve total size of all data contained in binary queue
+     *
+     * @return Number of bytes in binary queue
+     */
+    size_t Size() const;
+
+    /**
+     * Remove all data from binary queue
+     *
+     * @return none
+     */
+    void Clear();
+
+    /**
+     * Check if binary queue is empty
+     *
+     * @return true if binary queue is empty, false otherwise
+     */
+    bool Empty() const;
+
+    /**
+     * Remove @a size bytes from beginning of binary queue
+     *
+     * @return none
+     * @param[in] size Number of bytes to remove
+     * @exception BinaryQueue::Exception::OutOfData Number of bytes is larger
+     *            than available bytes in binary queue
+     */
+    void Consume(size_t size);
+
+    /**
+     * Retrieve @a bufferSize bytes from beginning of binary queue and copy them
+     * to user supplied buffer
+     *
+     * @return none
+     * @param[in] buffer Pointer to user buffer to receive bytes
+     * @param[in] bufferSize Size of user buffer pointed by @a buffer
+     * @exception BinaryQueue::Exception::OutOfData Number of bytes to flatten
+     *            is larger than available bytes in binary queue
+     */
+    void Flatten(void *buffer, size_t bufferSize) const;
+
+    /**
+     * Retrieve @a bufferSize bytes from beginning of binary queue, copy them
+     * to user supplied buffer, and remove from binary queue
+     *
+     * @return none
+     * @param[in] buffer Pointer to user buffer to receive bytes
+     * @param[in] bufferSize Size of user buffer pointed by @a buffer
+     * @exception BinaryQueue::Exception::OutOfData Number of bytes to flatten
+     *            is larger than available bytes in binary queue
+     */
+    void FlattenConsume(void *buffer, size_t bufferSize);
+
+    /**
+     * Visit each buffer with data using visitor object
+     *
+     * @return none
+     * @param[in] visitor Pointer to bucket visitor
+     * @see BinaryQueue::BucketVisitor
+     */
+    void VisitBuckets(BucketVisitor *visitor) const;
+
+    /**
+     * IAbstractInput interface
+     */
+    virtual BinaryQueueAutoPtr Read(size_t size);
+
+    /**
+     * IAbstractOutput interface
+     */
+    virtual size_t Write(const BinaryQueue &buffer, size_t bufferSize);
+};
+
+} // namespace IMAEVMServer
+
+#endif // IMA_EVM_SERVER_BINARY_QUEUE_H
diff --git a/src/service/dpl/core/include/dpl/colors.h b/src/service/dpl/core/include/dpl/colors.h
new file mode 100644 (file)
index 0000000..dd6d28a
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2011 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        colors.h
+ * @author      Lukasz Wrzosek (l.wrzosek@samsung.com)
+ * @version     1.0
+ * @brief       Some constants with definition of colors for Console
+ *              and html output
+ */
+
+#ifndef IMA_EVM_SERVER_COLORS_H
+#define IMA_EVM_SERVER_COLORS_H
+
+namespace IMAEVMServer {
+namespace Colors {
+namespace Text {
+extern const char* BOLD_GREEN_BEGIN;
+extern const char* BOLD_GREEN_END;
+extern const char* PURPLE_BEGIN;
+extern const char* PURPLE_END;
+extern const char* RED_BEGIN;
+extern const char* RED_END;
+extern const char* GREEN_BEGIN;
+extern const char* GREEN_END;
+extern const char* CYAN_BEGIN;
+extern const char* CYAN_END;
+extern const char* BOLD_RED_BEGIN;
+extern const char* BOLD_RED_END;
+extern const char* BOLD_YELLOW_BEGIN;
+extern const char* BOLD_YELLOW_END;
+extern const char* BOLD_GOLD_BEGIN;
+extern const char* BOLD_GOLD_END;
+extern const char* BOLD_WHITE_BEGIN;
+extern const char* BOLD_WHITE_END;
+} //namespace Text
+
+namespace Html {
+extern const char* BOLD_GREEN_BEGIN;
+extern const char* BOLD_GREEN_END;
+extern const char* PURPLE_BEGIN;
+extern const char* PURPLE_END;
+extern const char* RED_BEGIN;
+extern const char* RED_END;
+extern const char* GREEN_BEGIN;
+extern const char* GREEN_END;
+extern const char* CYAN_BEGIN;
+extern const char* CYAN_END;
+extern const char* BOLD_RED_BEGIN;
+extern const char* BOLD_RED_END;
+extern const char* BOLD_YELLOW_BEGIN;
+extern const char* BOLD_YELLOW_END;
+extern const char* BOLD_GOLD_BEGIN;
+extern const char* BOLD_GOLD_END;
+extern const char* BOLD_WHITE_BEGIN;
+extern const char* BOLD_WHITE_END;
+} //namespace Html
+} //namespace Colors
+} //namespace IMAEVMServer
+
+#endif /* IMA_EVM_SERVER_COLORS_H */
diff --git a/src/service/dpl/core/include/dpl/exception.h b/src/service/dpl/core/include/dpl/exception.h
new file mode 100644 (file)
index 0000000..784ea1d
--- /dev/null
@@ -0,0 +1,385 @@
+/*
+ * Copyright (c) 2011 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    exception.h
+ * @author  Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version 1.0
+ * @brief   Header file for base exception
+ */
+#ifndef IMA_EVM_SERVER_EXCEPTION_H
+#define IMA_EVM_SERVER_EXCEPTION_H
+
+#include <string>
+#include <cstring>
+#include <cstdio>
+#include <exception>
+#include <cstdlib>
+#include <sstream>
+
+namespace IMAEVMServer {
+void LogUnhandledException(const std::string &str);
+void LogUnhandledException(const std::string &str,
+                           const char *filename,
+                           int line,
+                           const char *function);
+}
+
+namespace IMAEVMServer {
+class Exception
+{
+  private:
+    static unsigned int m_exceptionCount;
+    static Exception* m_lastException;
+    static void (*m_terminateHandler)();
+
+    static void AddRef(Exception* exception)
+    {
+        if (!m_exceptionCount) {
+            m_terminateHandler = std::set_terminate(&TerminateHandler);
+        }
+
+        ++m_exceptionCount;
+        m_lastException = exception;
+    }
+
+    static void UnRef(Exception* e)
+    {
+        if (m_lastException == e) {
+            m_lastException = NULL;
+        }
+
+        --m_exceptionCount;
+
+        if (!m_exceptionCount) {
+            std::set_terminate(m_terminateHandler);
+            m_terminateHandler = NULL;
+        }
+    }
+
+    static void TerminateHandler()
+    {
+        if (m_lastException != NULL) {
+            DisplayKnownException(*m_lastException);
+            abort();
+        } else {
+            DisplayUnknownException();
+            abort();
+        }
+    }
+
+    Exception *m_reason;
+    std::string m_path;
+    std::string m_function;
+    int m_line;
+
+  protected:
+    std::string m_message;
+    std::string m_className;
+
+  public:
+    static std::string KnownExceptionToString(const Exception &e)
+    {
+        std::ostringstream message;
+        message <<
+        "\033[1;5;31m\n=== Unhandled IMAEVMServer exception occurred ===\033[m\n\n";
+        message << "\033[1;33mException trace:\033[m\n\n";
+        message << e.DumpToString();
+        message << "\033[1;31m\n=== Will now abort ===\033[m\n";
+
+        return message.str();
+    }
+
+    static std::string UnknownExceptionToString()
+    {
+        std::ostringstream message;
+        message <<
+        "\033[1;5;31m\n=== Unhandled non-IMAEVMServer exception occurred ===\033[m\n\n";
+        message << "\033[1;31m\n=== Will now abort ===\033[m\n";
+
+        return message.str();
+    }
+
+    static void DisplayKnownException(const Exception& e)
+    {
+        LogUnhandledException(KnownExceptionToString(e).c_str());
+    }
+
+    static void DisplayUnknownException()
+    {
+        LogUnhandledException(UnknownExceptionToString().c_str());
+    }
+
+    Exception(const Exception &other)
+    {
+        // Deep copy
+        if (other.m_reason != NULL) {
+            m_reason = new Exception(*other.m_reason);
+        } else {
+            m_reason = NULL;
+        }
+
+        m_message = other.m_message;
+        m_path = other.m_path;
+        m_function = other.m_function;
+        m_line = other.m_line;
+
+        m_className = other.m_className;
+
+        AddRef(this);
+    }
+
+    const Exception &operator =(const Exception &other)
+    {
+        if (this == &other) {
+            return *this;
+        }
+
+        // Deep copy
+        if (other.m_reason != NULL) {
+            m_reason = new Exception(*other.m_reason);
+        } else {
+            m_reason = NULL;
+        }
+
+        m_message = other.m_message;
+        m_path = other.m_path;
+        m_function = other.m_function;
+        m_line = other.m_line;
+
+        m_className = other.m_className;
+
+        AddRef(this);
+
+        return *this;
+    }
+
+    Exception(const char *path,
+              const char *function,
+              int line,
+              const std::string &message) :
+        m_reason(NULL),
+        m_path(path),
+        m_function(function),
+        m_line(line),
+        m_message(message)
+    {
+        AddRef(this);
+    }
+
+    Exception(const char *path,
+              const char *function,
+              int line,
+              const Exception &reason,
+              const std::string &message) :
+        m_reason(new Exception(reason)),
+        m_path(path),
+        m_function(function),
+        m_line(line),
+        m_message(message)
+    {
+        AddRef(this);
+    }
+
+    virtual ~Exception() throw()
+    {
+        if (m_reason != NULL) {
+            delete m_reason;
+            m_reason = NULL;
+        }
+
+        UnRef(this);
+    }
+
+    void Dump() const
+    {
+        // Show reason first
+        if (m_reason != NULL) {
+            m_reason->Dump();
+        }
+
+        // Afterward, dump exception
+        const char *file = strchr(m_path.c_str(), '/');
+
+        if (file == NULL) {
+            file = m_path.c_str();
+        } else {
+            ++file;
+        }
+
+        printf("\033[0;36m[%s:%i]\033[m %s() \033[4;35m%s\033[m: %s\033[m\n",
+               file, m_line,
+               m_function.c_str(),
+               m_className.c_str(),
+               m_message.empty() ? "<EMPTY>" : m_message.c_str());
+    }
+
+    std::string DumpToString() const
+    {
+        std::string ret;
+        if (m_reason != NULL) {
+            ret = m_reason->DumpToString();
+        }
+
+        const char *file = strchr(m_path.c_str(), '/');
+
+        if (file == NULL) {
+            file = m_path.c_str();
+        } else {
+            ++file;
+        }
+
+        char buf[1024];
+        snprintf(buf,
+                 sizeof(buf),
+                 "\033[0;36m[%s:%i]\033[m %s() \033[4;35m%s\033[m: %s\033[m\n",
+                 file,
+                 m_line,
+                 m_function.c_str(),
+                 m_className.c_str(),
+                 m_message.empty() ? "<EMPTY>" : m_message.c_str());
+
+        buf[sizeof(buf) - 1] = '\n';
+        ret += buf;
+
+        return ret;
+    }
+
+    Exception *GetReason() const
+    {
+        return m_reason;
+    }
+
+    std::string GetPath() const
+    {
+        return m_path;
+    }
+
+    std::string GetFunction() const
+    {
+        return m_function;
+    }
+
+    int GetLine() const
+    {
+        return m_line;
+    }
+
+    std::string GetMessage() const
+    {
+        return m_message;
+    }
+
+    std::string GetClassName() const
+    {
+        return m_className;
+    }
+};
+} // namespace IMAEVMServer
+
+#define Try try
+
+#define Throw(ClassName) \
+    throw ClassName(__FILE__, __FUNCTION__, __LINE__)
+
+#define ThrowMsg(ClassName, Message)                                                 \
+    do                                                                               \
+    {                                                                                \
+        std::ostringstream dplLoggingStream;                                         \
+        dplLoggingStream << Message;                                                 \
+        throw ClassName(__FILE__, __FUNCTION__, __LINE__, dplLoggingStream.str());   \
+    } while (0)
+
+#define ReThrow(ClassName) \
+    throw ClassName(__FILE__, __FUNCTION__, __LINE__, _rethrown_exception)
+
+#define ReThrowMsg(ClassName, Message) \
+    throw ClassName(__FILE__, \
+                    __FUNCTION__, \
+                    __LINE__, \
+                    _rethrown_exception, \
+                    Message)
+
+#define Catch(ClassName) \
+    catch (const ClassName &_rethrown_exception)
+
+#define DECLARE_EXCEPTION_TYPE(BaseClass, Class)                                                                                          \
+    class Class :                                                                                                                                 \
+        public BaseClass                                                                                                                \
+    {                                                                                                                                     \
+      public:                                                                                                                               \
+        Class(const char *path, \
+              const char *function, \
+              int line, \
+              const std::string & message = std::string()) :                                                                                                                             \
+            BaseClass(path, function, line, message)                                                                                    \
+        {                                                                                                                                 \
+            BaseClass::m_className = #Class;                                                                                              \
+        }                                                                                                                                 \
+                                                                                                                                          \
+        Class(const char *path, \
+              const char *function, \
+              int line, \
+              const IMAEVMServer::Exception & reason, \
+              const std::string & message = std::string()) :                                                                                                                             \
+            BaseClass(path, function, line, reason, message)                                                                            \
+        {                                                                                                                                 \
+            BaseClass::m_className = #Class;                                                                                              \
+        }                                                                                                                                 \
+    };
+
+#define UNHANDLED_EXCEPTION_HANDLER_BEGIN try
+
+#define UNHANDLED_EXCEPTION_HANDLER_END                                                                   \
+    catch (const IMAEVMServer::Exception &exception)                                                               \
+    {                                                                                                     \
+        std::ostringstream msg;                                                                           \
+        msg << IMAEVMServer::Exception::KnownExceptionToString(exception);                                         \
+        IMAEVMServer::LogUnhandledException(msg.str(), __FILE__, __LINE__, __FUNCTION__);                          \
+        abort();                                                                                          \
+    }                                                                                                     \
+    catch (std::exception& e)                                                                             \
+    {                                                                                                     \
+        std::ostringstream msg;                                                                           \
+        msg << e.what();                                                                                  \
+        msg << "\n";                                                                                      \
+        msg << IMAEVMServer::Exception::UnknownExceptionToString();                                                \
+        IMAEVMServer::LogUnhandledException(msg.str(), __FILE__, __LINE__, __FUNCTION__);                          \
+        abort();                                                                                          \
+    }                                                                                                     \
+    catch (...)                                                                                           \
+    {                                                                                                     \
+        std::ostringstream msg;                                                                           \
+        msg << IMAEVMServer::Exception::UnknownExceptionToString();                                                \
+        IMAEVMServer::LogUnhandledException(msg.str(), __FILE__, __LINE__, __FUNCTION__);                          \
+        abort();                                                                                          \
+    }
+
+namespace IMAEVMServer {
+namespace CommonException {
+/**
+ * Internal exception definitions
+ *
+ * These should normally not happen.
+ * Usually, exception trace with internal error includes
+ * important messages.
+ */
+DECLARE_EXCEPTION_TYPE(Exception, InternalError) ///< Unexpected error from
+                                                 // underlying libraries or
+                                                 // kernel
+}
+}
+
+#endif // IMA_EVM_SERVER_EXCEPTION_H
diff --git a/src/service/dpl/core/include/dpl/noncopyable.h b/src/service/dpl/core/include/dpl/noncopyable.h
new file mode 100644 (file)
index 0000000..3abe95c
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2011 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        noncopyable
+ * @author      Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version     1.0
+ * @brief       This file is the implementation file of noncopyable
+ */
+#ifndef IMA_EVMSERVER_NONCOPYABLE_H
+#define IMA_EVMSERVER_NONCOPYABLE_H
+
+namespace IMAEVMServer {
+class Noncopyable
+{
+  private:
+    Noncopyable(const Noncopyable &);
+    const Noncopyable &operator=(const Noncopyable &);
+
+  public:
+    Noncopyable();
+    virtual ~Noncopyable();
+};
+} // namespace IMAEVMServer
+
+#endif // IMA_EVMSERVER_NONCOPYABLE_H
diff --git a/src/service/dpl/core/include/dpl/noreturn.h b/src/service/dpl/core/include/dpl/noreturn.h
new file mode 100644 (file)
index 0000000..df7d266
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2011 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        noreturn.h
+ * @author      Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version     1.0
+ * @brief       This file is the implementation file of noreturn
+ */
+#ifndef IMA_EVMSERVER_NORETURN_H
+#define IMA_EVMSERVER_NORETURN_H
+
+#define IMA_EVMSERVER_NORETURN __attribute__((__noreturn__))
+
+#endif // IMA_EVMSERVER_NORETURN_H
diff --git a/src/service/dpl/core/include/dpl/serialization.h b/src/service/dpl/core/include/dpl/serialization.h
new file mode 100644 (file)
index 0000000..daeb315
--- /dev/null
@@ -0,0 +1,327 @@
+/*
+ * Copyright (c) 2011 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    serialization.h
+ * @author  Tomasz Swierczek (t.swierczek@samsung.com)
+ * @version 1.0
+ * @brief   Interfaces and templates used for data serialization.
+ */
+#ifndef SERIALIZATION_H
+#define SERIALIZATION_H
+
+#include <string>
+#include <vector>
+#include <list>
+#include <map>
+
+namespace IMAEVMServer {
+// Abstract data stream buffer
+class IStream
+{
+  public:
+    virtual void Read(size_t num, void * bytes) = 0;
+    virtual void Write(size_t num, const void * bytes) = 0;
+    virtual ~IStream(){}
+};
+
+// Serializable interface
+class ISerializable
+{
+  public:
+    /*    ISerializable(){};
+     *    ISerializable(IStream&){}; */
+    virtual void Serialize(IStream &) const = 0;
+    virtual ~ISerializable(){}
+};
+
+struct Serialization {
+    // serialization
+    // normal functions
+
+    // ISerializable objects
+    static void Serialize(IStream& stream, const ISerializable& object)
+    {
+        object.Serialize(stream);
+    }
+    static void Serialize(IStream& stream, const ISerializable* const object)
+    {
+        object->Serialize(stream);
+    }
+
+    // unsigned int
+    static void Serialize(IStream& stream, const unsigned value)
+    {
+        stream.Write(sizeof(value), &value);
+    }
+    static void Serialize(IStream& stream, const unsigned* const value)
+    {
+        stream.Write(sizeof(*value), value);
+    }
+
+    // int
+    static void Serialize(IStream& stream, const int value)
+    {
+        stream.Write(sizeof(value), &value);
+    }
+    static void Serialize(IStream& stream, const int* const value)
+    {
+        stream.Write(sizeof(*value), value);
+    }
+
+    // bool
+    static void Serialize(IStream& stream, const bool value)
+    {
+        stream.Write(sizeof(value), &value);
+    }
+    static void Serialize(IStream& stream, const bool* const value)
+    {
+        stream.Write(sizeof(*value), value);
+    }
+
+    // std::string
+    static void Serialize(IStream& stream, const std::string& str)
+    {
+        int length = str.size();
+        stream.Write(sizeof(length), &length);
+        stream.Write(length, str.c_str());
+    }
+    static void Serialize(IStream& stream, const std::string* const str)
+    {
+        int length = str->size();
+        stream.Write(sizeof(length), &length);
+        stream.Write(length, str->c_str());
+    }
+
+    // STL templates
+
+    // std::list
+    template <typename T>
+    static void Serialize(IStream& stream, const std::list<T>& list)
+    {
+        int length = list.size();
+        stream.Write(sizeof(length), &length);
+        for (typename std::list<T>::const_iterator list_iter = list.begin();
+             list_iter != list.end(); list_iter++)
+        {
+            Serialize(stream, *list_iter);
+        }
+    }
+    template <typename T>
+    static void Serialize(IStream& stream, const std::list<T>* const list)
+    {
+        Serialize(stream, *list);
+    }
+
+    // std::vector
+    template <typename T>
+    static void Serialize(IStream& stream, const std::vector<T>& vec)
+    {
+        int length = vec.size();
+        stream.Write(sizeof(length), &length);
+        for (typename std::vector<T>::const_iterator vec_iter = vec.begin();
+             vec_iter != vec.end(); vec_iter++)
+        {
+            Serialize(stream, *vec_iter);
+        }
+    }
+    template <typename T>
+    static void Serialize(IStream& stream, const std::vector<T>* const vec)
+    {
+        Serialize(stream, *vec);
+    }
+
+    // std::pair
+    template <typename A, typename B>
+    static void Serialize(IStream& stream, const std::pair<A, B>& p)
+    {
+        Serialize(stream, p.first);
+        Serialize(stream, p.second);
+    }
+    template <typename A, typename B>
+    static void Serialize(IStream& stream, const std::pair<A, B>* const p)
+    {
+        Serialize(stream, *p);
+    }
+
+    // std::map
+    template <typename K, typename T>
+    static void Serialize(IStream& stream, const std::map<K, T>& map)
+    {
+        int length = map.size();
+        stream.Write(sizeof(length), &length);
+        typename std::map<K, T>::const_iterator it;
+        for (it = map.begin(); it != map.end(); ++it) {
+            Serialize(stream, (*it).first);
+            Serialize(stream, (*it).second);
+        }
+    }
+    template <typename K, typename T>
+    static void Serialize(IStream& stream, const std::map<K, T>* const map)
+    {
+        Serialize(stream, *map);
+    }
+}; // struct Serialization
+
+struct Deserialization {
+    // deserialization
+    // normal functions
+
+    // ISerializable objects
+    // T instead of ISerializable is needed to call proper constructor
+    template <typename T>
+    static void Deserialize(IStream& stream, T& object)
+    {
+        object = T(stream);
+    }
+    template <typename T>
+    static void Deserialize(IStream& stream, T*& object)
+    {
+        object = new T(stream);
+    }
+
+    // unsigned int
+    static void Deserialize(IStream& stream, unsigned& value)
+    {
+        stream.Read(sizeof(value), &value);
+    }
+    static void Deserialize(IStream& stream, unsigned*& value)
+    {
+        value = new unsigned;
+        stream.Read(sizeof(*value), value);
+    }
+
+    // int
+    static void Deserialize(IStream& stream, int& value)
+    {
+        stream.Read(sizeof(value), &value);
+    }
+    static void Deserialize(IStream& stream, int*& value)
+    {
+        value = new int;
+        stream.Read(sizeof(*value), value);
+    }
+
+    // bool
+    static void Deserialize(IStream& stream, bool& value)
+    {
+        stream.Read(sizeof(value), &value);
+    }
+    static void Deserialize(IStream& stream, bool*& value)
+    {
+        value = new bool;
+        stream.Read(sizeof(*value), value);
+    }
+
+    // std::string
+    static void Deserialize(IStream& stream, std::string& str)
+    {
+        int length;
+        stream.Read(sizeof(length), &length);
+        char * buf = new char[length + 1];
+        stream.Read(length, buf);
+        buf[length] = 0;
+        str = std::string(buf);
+        delete[] buf;
+    }
+    static void Deserialize(IStream& stream, std::string*& str)
+    {
+        int length;
+        stream.Read(sizeof(length), &length);
+        char * buf = new char[length + 1];
+        stream.Read(length, buf);
+        buf[length] = 0;
+        str = new std::string(buf);
+        delete[] buf;
+    }
+
+    // STL templates
+
+    // std::list
+    template <typename T>
+    static void Deserialize(IStream& stream, std::list<T>& list)
+    {
+        int length;
+        stream.Read(sizeof(length), &length);
+        for (int i = 0; i < length; ++i) {
+            T obj;
+            Deserialize(stream, obj);
+            list.push_back(obj);
+        }
+    }
+    template <typename T>
+    static void Deserialize(IStream& stream, std::list<T>*& list)
+    {
+        list = new std::list<T>;
+        Deserialize(stream, *list);
+    }
+
+    // std::vector
+    template <typename T>
+    static void Deserialize(IStream& stream, std::vector<T>& vec)
+    {
+        int length;
+        stream.Read(sizeof(length), &length);
+        for (int i = 0; i < length; ++i) {
+            T obj;
+            Deserialize(stream, obj);
+            vec.push_back(obj);
+        }
+    }
+    template <typename T>
+    static void Deserialize(IStream& stream, std::vector<T>*& vec)
+    {
+        vec = new std::vector<T>;
+        Deserialize(stream, *vec);
+    }
+
+    // std::pair
+    template <typename A, typename B>
+    static void Deserialize(IStream& stream, std::pair<A, B>& p)
+    {
+        Deserialize(stream, p.first);
+        Deserialize(stream, p.second);
+    }
+    template <typename A, typename B>
+    static void Deserialize(IStream& stream, std::pair<A, B>*& p)
+    {
+        p = new std::pair<A, B>;
+        Deserialize(stream, *p);
+    }
+
+    // std::map
+    template <typename K, typename T>
+    static void Deserialize(IStream& stream, std::map<K, T>& map)
+    {
+        int length;
+        stream.Read(sizeof(length), &length);
+        for (int i = 0; i < length; ++i) {
+            K key;
+            T obj;
+            Deserialize(stream, key);
+            Deserialize(stream, obj);
+            map[key] = obj;
+        }
+    }
+    template <typename K, typename T>
+    static void Deserialize(IStream& stream, std::map<K, T>*& map)
+    {
+        map = new std::map<K, T>;
+        Deserialize(stream, *map);
+    }
+}; // struct Deserialization
+} // namespace IMAEVMServer
+
+#endif // SERIALIZATION_H
diff --git a/src/service/dpl/core/include/dpl/singleton.h b/src/service/dpl/core/include/dpl/singleton.h
new file mode 100644 (file)
index 0000000..2756811
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2011 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        singleton.h
+ * @author      Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version     1.0
+ * @brief       This file is the implementation file of singleton
+ */
+#ifndef IMA_EVMSERVER_SINGLETON_H
+#define IMA_EVMSERVER_SINGLETON_H
+
+namespace IMAEVMServer {
+template<typename Class>
+class Singleton :
+    private Class
+{
+    //
+    // Note:
+    //
+    // To remove posibility of instantiating directly Class,
+    // make Class' default constructor protected
+    //
+
+  private:
+    Singleton()
+    {}
+
+    static Singleton &InternalInstance();
+
+  public:
+    virtual ~Singleton()
+    {}
+
+    static Class &Instance();
+};
+} // namespace IMAEVMServer
+
+#endif // IMA_EVMSERVER_SINGLETON_H
diff --git a/src/service/dpl/core/include/dpl/singleton_impl.h b/src/service/dpl/core/include/dpl/singleton_impl.h
new file mode 100644 (file)
index 0000000..04e7e01
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2011 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        singleton_impl.h
+ * @author      Lukasz Wrzosek (l.wrzosek@samsung.com)
+ * @version     1.0
+ * @brief       This file is the implementation file of singleton
+ */
+#ifndef IMA_EVMSERVER_SINGLETON_IMPL_H
+#define IMA_EVMSERVER_SINGLETON_IMPL_H
+
+/*
+ * WARNING!
+ *
+ * If some singleton's implementation uses another singletons implementation,
+ * those templates make the second singleton a dubleton. Be warned. Try to use
+ * singleton_safe_impl.h if possible.
+ */
+
+namespace IMAEVMServer {
+template<typename Class>
+Singleton<Class>& Singleton<Class>::InternalInstance()
+{
+    static Singleton<Class> instance;
+    return instance;
+}
+
+template<typename Class>
+Class &Singleton<Class>::Instance()
+{
+    Singleton<Class>& instance = Singleton<Class>::InternalInstance();
+    return instance;
+}
+} // namespace IMAEVMServer
+
+#define IMPLEMENT_SINGLETON(Type)                                           \
+    template IMAEVMServer::Singleton<Type>&IMAEVMServer::Singleton<Type>::InternalInstance();    \
+    template Type & IMAEVMServer::Singleton<Type>::Instance();                            \
+
+#endif // IMA_EVMSERVER_SINGLETON_IMPL_H
diff --git a/src/service/dpl/core/include/dpl/singleton_safe_impl.h b/src/service/dpl/core/include/dpl/singleton_safe_impl.h
new file mode 100644 (file)
index 0000000..e1723c1
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2011 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        singleton_safe_impl.h
+ * @author      Tomasz Swierczek (t.swierczek@samsung.com)
+ * @version     1.0
+ * @brief       This file is the implementation file of singleton
+ */
+#ifndef IMA_EVMSERVER_SINGLETON_SAFE_IMPL_H
+#define IMA_EVMSERVER_SINGLETON_SAFE_IMPL_H
+
+#define IMPLEMENT_SAFE_SINGLETON(Class)                                        \
+    namespace IMAEVMServer {                                                                \
+    template<>                                                                     \
+    Singleton<Class>&Singleton<Class>::InternalInstance()                         \
+    {                                                                              \
+        static Singleton<Class> instance;                                          \
+        return instance;                                                           \
+    }                                                                              \
+                                                                               \
+    template<>                                                                     \
+    Class & Singleton<Class>::Instance()                                            \
+    {                                                                              \
+        Singleton<Class>& instance = Singleton<Class>::InternalInstance();         \
+        return instance;                                                           \
+    }                                                                              \
+                                                                               \
+    template Singleton<Class>&Singleton<Class>::InternalInstance();               \
+    template Class & Singleton<Class>::Instance();                                  \
+    } // namespace IMAEVMServer
+
+#endif // IMA_EVMSERVER_SINGLETON_SAFE_IMPL_H
diff --git a/src/service/dpl/core/src/assert.cpp b/src/service/dpl/core/src/assert.cpp
new file mode 100644 (file)
index 0000000..10bf9b5
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2011 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        assert.cpp
+ * @author      Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version     1.0
+ * @brief       This file is the implementation file of assert
+ */
+#include <stddef.h>
+#include <dpl/assert.h>
+#include <dpl/colors.h>
+#include <dpl/log/log.h>
+#include <dpl/exception.h>
+#include <cstdlib>
+
+namespace IMAEVMServer {
+void AssertProc(const char *condition,
+                const char *file,
+                int line,
+                const char *function)
+{
+#define INTERNAL_LOG(message)                                          \
+    do                                                                 \
+    {                                                                  \
+        std::ostringstream platformLog;                                \
+        platformLog << message;                                        \
+        IMAEVMServer::Log::LogSystemSingleton::Instance().Pedantic(             \
+            platformLog.str().c_str(),                                 \
+            __FILE__, __LINE__, __FUNCTION__);                         \
+    } \
+    while (0)
+
+    // Try to log failed assertion to log system
+    Try
+    {
+        INTERNAL_LOG(
+            "################################################################################");
+        INTERNAL_LOG(
+            "###                          IMAEVMServer assertion failed!                           ###");
+        INTERNAL_LOG(
+            "################################################################################");
+        INTERNAL_LOG("### Condition: " << condition);
+        INTERNAL_LOG("### File: " << file);
+        INTERNAL_LOG("### Line: " << line);
+        INTERNAL_LOG("### Function: " << function);
+        INTERNAL_LOG(
+            "################################################################################");
+    } catch (Exception) {
+        // Just ignore possible double errors
+    }
+
+    // Fail with c-library abort
+    abort();
+}
+} // namespace IMAEVMServer
diff --git a/src/service/dpl/core/src/binary_queue.cpp b/src/service/dpl/core/src/binary_queue.cpp
new file mode 100644 (file)
index 0000000..851c8c3
--- /dev/null
@@ -0,0 +1,311 @@
+/*
+ * Copyright (c) 2011 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        binary_queue.cpp
+ * @author      Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version     1.0
+ * @brief       This file is the implementation file of binary queue
+ */
+#include <stddef.h>
+#include <dpl/binary_queue.h>
+#include <dpl/assert.h>
+#include <algorithm>
+#include <malloc.h>
+#include <cstring>
+#include <new>
+
+namespace IMAEVMServer {
+BinaryQueue::BinaryQueue() :
+    m_size(0)
+{}
+
+BinaryQueue::BinaryQueue(const BinaryQueue &other) :
+    m_size(0)
+{
+    AppendCopyFrom(other);
+}
+
+BinaryQueue::~BinaryQueue()
+{
+    // Remove all remainig buckets
+    Clear();
+}
+
+const BinaryQueue &BinaryQueue::operator=(const BinaryQueue &other)
+{
+    if (this != &other) {
+        Clear();
+        AppendCopyFrom(other);
+    }
+
+    return *this;
+}
+
+void BinaryQueue::AppendCopyFrom(const BinaryQueue &other)
+{
+    // To speed things up, always copy as one bucket
+    void *bufferCopy = malloc(other.m_size);
+
+    if (bufferCopy == NULL) {
+        throw std::bad_alloc();
+    }
+
+    try {
+        other.Flatten(bufferCopy, other.m_size);
+        AppendUnmanaged(bufferCopy, other.m_size, &BufferDeleterFree, NULL);
+    } catch (const std::bad_alloc &) {
+        // Free allocated memory
+        free(bufferCopy);
+        throw;
+    }
+}
+
+void BinaryQueue::AppendMoveFrom(BinaryQueue &other)
+{
+    // Copy all buckets
+    std::copy(other.m_buckets.begin(),
+              other.m_buckets.end(), std::back_inserter(m_buckets));
+    m_size += other.m_size;
+
+    // Clear other, but do not free memory
+    other.m_buckets.clear();
+    other.m_size = 0;
+}
+
+void BinaryQueue::AppendCopyTo(BinaryQueue &other) const
+{
+    other.AppendCopyFrom(*this);
+}
+
+void BinaryQueue::AppendMoveTo(BinaryQueue &other)
+{
+    other.AppendMoveFrom(*this);
+}
+
+void BinaryQueue::Clear()
+{
+    std::for_each(m_buckets.begin(), m_buckets.end(), &DeleteBucket);
+    m_buckets.clear();
+    m_size = 0;
+}
+
+void BinaryQueue::AppendCopy(const void* buffer, size_t bufferSize)
+{
+    // Create data copy with malloc/free
+    void *bufferCopy = malloc(bufferSize);
+
+    // Check if allocation succeded
+    if (bufferCopy == NULL) {
+        throw std::bad_alloc();
+    }
+
+    // Copy user data
+    memcpy(bufferCopy, buffer, bufferSize);
+
+    try {
+        // Try to append new bucket
+        AppendUnmanaged(bufferCopy, bufferSize, &BufferDeleterFree, NULL);
+    } catch (const std::bad_alloc &) {
+        // Free allocated memory
+        free(bufferCopy);
+        throw;
+    }
+}
+
+void BinaryQueue::AppendUnmanaged(const void* buffer,
+                                  size_t bufferSize,
+                                  BufferDeleter deleter,
+                                  void* userParam)
+{
+    // Do not attach empty buckets
+    if (bufferSize == 0) {
+        deleter(buffer, bufferSize, userParam);
+        return;
+    }
+
+    // Just add new bucket with selected deleter
+    m_buckets.push_back(new Bucket(buffer, bufferSize, deleter, userParam));
+
+    // Increase total queue size
+    m_size += bufferSize;
+}
+
+size_t BinaryQueue::Size() const
+{
+    return m_size;
+}
+
+bool BinaryQueue::Empty() const
+{
+    return m_size == 0;
+}
+
+void BinaryQueue::Consume(size_t size)
+{
+    // Check parameters
+    if (size > m_size) {
+        Throw(Exception::OutOfData);
+    }
+
+    size_t bytesLeft = size;
+
+    // Consume data and/or remove buckets
+    while (bytesLeft > 0) {
+        // Get consume size
+        size_t count = std::min(bytesLeft, m_buckets.front()->left);
+
+        m_buckets.front()->ptr =
+            static_cast<const char *>(m_buckets.front()->ptr) + count;
+        m_buckets.front()->left -= count;
+        bytesLeft -= count;
+        m_size -= count;
+
+        if (m_buckets.front()->left == 0) {
+            DeleteBucket(m_buckets.front());
+            m_buckets.pop_front();
+        }
+    }
+}
+
+void BinaryQueue::Flatten(void *buffer, size_t bufferSize) const
+{
+    // Check parameters
+    if (bufferSize == 0) {
+        return;
+    }
+
+    if (bufferSize > m_size) {
+        Throw(Exception::OutOfData);
+    }
+
+    size_t bytesLeft = bufferSize;
+    void *ptr = buffer;
+    BucketList::const_iterator bucketIterator = m_buckets.begin();
+    Assert(m_buckets.end() != bucketIterator);
+
+    // Flatten data
+    while (bytesLeft > 0) {
+        // Get consume size
+        size_t count = std::min(bytesLeft, (*bucketIterator)->left);
+
+        // Copy data to user pointer
+        memcpy(ptr, (*bucketIterator)->ptr, count);
+
+        // Update flattened bytes count
+        bytesLeft -= count;
+        ptr = static_cast<char *>(ptr) + count;
+
+        // Take next bucket
+        ++bucketIterator;
+    }
+}
+
+void BinaryQueue::FlattenConsume(void *buffer, size_t bufferSize)
+{
+    // FIXME: Optimize
+    Flatten(buffer, bufferSize);
+    Consume(bufferSize);
+}
+
+void BinaryQueue::DeleteBucket(BinaryQueue::Bucket *bucket)
+{
+    delete bucket;
+}
+
+void BinaryQueue::BufferDeleterFree(const void* data,
+                                    size_t dataSize,
+                                    void* userParam)
+{
+    (void)dataSize;
+    (void)userParam;
+
+    // Default free deleter
+    free(const_cast<void *>(data));
+}
+
+BinaryQueue::Bucket::Bucket(const void* data,
+                            size_t dataSize,
+                            BufferDeleter dataDeleter,
+                            void* userParam) :
+    buffer(data),
+    ptr(data),
+    size(dataSize),
+    left(dataSize),
+    deleter(dataDeleter),
+    param(userParam)
+{
+    Assert(data != NULL);
+    Assert(deleter != NULL);
+}
+
+BinaryQueue::Bucket::~Bucket()
+{
+    // Invoke deleter on bucket data
+    deleter(buffer, size, param);
+}
+
+BinaryQueue::BucketVisitor::~BucketVisitor()
+{}
+
+BinaryQueue::BucketVisitorCall::BucketVisitorCall(BucketVisitor *visitor) :
+    m_visitor(visitor)
+{}
+
+BinaryQueue::BucketVisitorCall::~BucketVisitorCall()
+{}
+
+void BinaryQueue::BucketVisitorCall::operator()(Bucket *bucket) const
+{
+    m_visitor->OnVisitBucket(bucket->ptr, bucket->left);
+}
+
+void BinaryQueue::VisitBuckets(BucketVisitor *visitor) const
+{
+    Assert(visitor != NULL);
+
+    // Visit all buckets
+    std::for_each(m_buckets.begin(), m_buckets.end(), BucketVisitorCall(visitor));
+}
+
+BinaryQueueAutoPtr BinaryQueue::Read(size_t size)
+{
+    // Simulate input stream
+    size_t available = std::min(size, m_size);
+
+    std::unique_ptr<void, std::function<void(void*)>>
+        bufferCopy(malloc(available), free);
+
+    if (!bufferCopy.get()) {
+        throw std::bad_alloc();
+    }
+
+    BinaryQueueAutoPtr result(new BinaryQueue());
+
+    Flatten(bufferCopy.get(), available);
+    result->AppendUnmanaged(
+        bufferCopy.release(), available, &BufferDeleterFree, NULL);
+    Consume(available);
+
+    return result;
+}
+
+size_t BinaryQueue::Write(const BinaryQueue &buffer, size_t bufferSize)
+{
+    // Simulate output stream
+    AppendCopyFrom(buffer);
+    return bufferSize;
+}
+} // namespace IMAEVMServer
diff --git a/src/service/dpl/core/src/colors.cpp b/src/service/dpl/core/src/colors.cpp
new file mode 100644 (file)
index 0000000..f1d757e
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2011 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        colors.cpp
+ * @author      Lukasz Wrzosek (l.wrzosek@samsung.com)
+ * @version     1.0
+ * @brief       Some constants with definition of colors for Console
+ *              and html output
+ */
+#include <stddef.h>
+#include <dpl/colors.h>
+
+namespace IMAEVMServer {
+namespace Colors {
+namespace Text {
+const char* BOLD_GREEN_BEGIN = "\033[1;32m";
+const char* BOLD_GREEN_END = "\033[m";
+const char* RED_BEGIN = "\033[0;31m";
+const char* RED_END = "\033[m";
+const char* PURPLE_BEGIN = "\033[0;35m";
+const char* PURPLE_END = "\033[m";
+const char* GREEN_BEGIN = "\033[0;32m";
+const char* GREEN_END = "\033[m";
+const char* CYAN_BEGIN = "\033[0;36m";
+const char* CYAN_END = "\033[m";
+const char* BOLD_RED_BEGIN = "\033[1;31m";
+const char* BOLD_RED_END = "\033[m";
+const char* BOLD_YELLOW_BEGIN = "\033[1;33m";
+const char* BOLD_YELLOW_END = "\033[m";
+const char* BOLD_GOLD_BEGIN = "\033[0;33m";
+const char* BOLD_GOLD_END = "\033[m";
+const char* BOLD_WHITE_BEGIN = "\033[1;37m";
+const char* BOLD_WHITE_END = "\033[m";
+} //namespace Text
+
+namespace Html {
+const char* BOLD_GREEN_BEGIN = "<font color=\"green\"><b>";
+const char* BOLD_GREEN_END = "</b></font>";
+const char* PURPLE_BEGIN = "<font color=\"purple\"><b>";
+const char* PURPLE_END = "</b></font>";
+const char* RED_BEGIN = "<font color=\"red\"><b>";
+const char* RED_END = "</b></font>";
+const char* GREEN_BEGIN = "<font color=\"green\">";
+const char* GREEN_END = "</font>";
+const char* CYAN_BEGIN = "<font color=\"cyan\">";
+const char* CYAN_END = "</font>";
+const char* BOLD_RED_BEGIN = "<font color=\"red\"><b>";
+const char* BOLD_RED_END = "</b></font>";
+const char* BOLD_YELLOW_BEGIN = "<font color=\"yellow\"><b>";
+const char* BOLD_YELLOW_END = "</b></font>";
+const char* BOLD_GOLD_BEGIN = "<font color=\"gold\"><b>";
+const char* BOLD_GOLD_END = "</b></font>";
+const char* BOLD_WHITE_BEGIN = "<font color=\"white\"><b>";
+const char* BOLD_WHITE_END = "</b></font>";
+} //namespace Html
+} //namespace Colors
+} //namespace IMAEVMServer
diff --git a/src/service/dpl/core/src/exception.cpp b/src/service/dpl/core/src/exception.cpp
new file mode 100644 (file)
index 0000000..7fbfc80
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2011 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        exception.cpp
+ * @author      Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version     1.0
+ * @brief       This file is the implementation of exception system
+ */
+#include <stddef.h>
+#include <dpl/exception.h>
+#include <dpl/log/log.h>
+#include <cstdio>
+
+namespace IMAEVMServer {
+Exception* Exception::m_lastException = NULL;
+unsigned int Exception::m_exceptionCount = 0;
+void (*Exception::m_terminateHandler)() = NULL;
+
+void LogUnhandledException(const std::string &str)
+{
+    // Logging to console
+    printf("%s\n", str.c_str());
+
+    // Logging to dlog
+    LogPedantic(str);
+}
+
+void LogUnhandledException(const std::string &str,
+                           const char *filename,
+                           int line,
+                           const char *function)
+{
+    // Logging to console
+    std::ostringstream msg;
+    msg << "\033[1;5;31m\n=== [" << filename << ":" << line << "] " <<
+    function << " ===\033[m";
+    msg << str;
+    printf("%s\n", msg.str().c_str());
+
+    // Logging to dlog
+    IMAEVMServer::Log::LogSystemSingleton::Instance().Error(
+        str.c_str(), filename, line, function);
+}
+} // namespace IMAEVMServer
diff --git a/src/service/dpl/core/src/noncopyable.cpp b/src/service/dpl/core/src/noncopyable.cpp
new file mode 100644 (file)
index 0000000..68ca71a
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2011 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        noncopyable.cpp
+ * @author      Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version     1.0
+ * @brief       This file is the implementation file of noncopyable
+ */
+#include <stddef.h>
+#include <dpl/noncopyable.h>
+
+namespace IMAEVMServer {
+Noncopyable::Noncopyable()
+{}
+
+Noncopyable::~Noncopyable()
+{}
+} // namespace IMAEVMServer
diff --git a/src/service/dpl/core/src/serialization.cpp b/src/service/dpl/core/src/serialization.cpp
new file mode 100644 (file)
index 0000000..f8f05ff
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2011 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        serialization.cpp
+ * @author      Tomasz Swierczek (t.swierczek@samsung.com)
+ * @version     1.0
+ * @brief       This file is the implementation file of data serialization.
+ */
+#include <stddef.h>
+#include <dpl/serialization.h>
+
+//
+// Note:
+//
+// The file here is left blank to enable precompilation
+// of templates in corresponding header file.
+// Do not remove this file.
+//
diff --git a/src/service/dpl/core/src/singleton.cpp b/src/service/dpl/core/src/singleton.cpp
new file mode 100644 (file)
index 0000000..a76e8ac
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2011 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        generic_event.cpp
+ * @author      Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version     1.0
+ * @brief       This file is the implementation file of singleton
+ */
+#include <stddef.h>
+#include <dpl/singleton.h>
+
+//
+// Note:
+//
+// The file here is left blank to enable precompilation
+// of templates in corresponding header file.
+// Do not remove this file.
+//
diff --git a/src/service/dpl/log/include/dpl/log/abstract_log_provider.h b/src/service/dpl/log/include/dpl/log/abstract_log_provider.h
new file mode 100644 (file)
index 0000000..b928fef
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2011 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        abstract_log_provider.h
+ * @author      Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version     1.0
+ * @brief       This file is the implementation file of abstract log provider
+ */
+#ifndef IMA_EVMSERVER_ABSTRACT_LOG_PROVIDER_H
+#define IMA_EVMSERVER_ABSTRACT_LOG_PROVIDER_H
+
+namespace IMAEVMServer {
+namespace Log {
+class AbstractLogProvider
+{
+  public:
+    virtual ~AbstractLogProvider() {}
+
+    virtual void Debug(const char *message,
+                       const char *fileName,
+                       int line,
+                       const char *function) = 0;
+    virtual void Info(const char *message,
+                      const char *fileName,
+                      int line,
+                      const char *function) = 0;
+    virtual void Warning(const char *message,
+                         const char *fileName,
+                         int line,
+                         const char *function) = 0;
+    virtual void Error(const char *message,
+                       const char *fileName,
+                       int line,
+                       const char *function) = 0;
+    virtual void Pedantic(const char *message,
+                          const char *fileName,
+                          int line,
+                          const char *function) = 0;
+
+  protected:
+    static const char *LocateSourceFileName(const char *filename);
+};
+}
+} // namespace IMAEVMServer
+
+#endif // IMA_EVMSERVER_ABSTRACT_LOG_PROVIDER_H
diff --git a/src/service/dpl/log/include/dpl/log/dlog_log_provider.h b/src/service/dpl/log/include/dpl/log/dlog_log_provider.h
new file mode 100644 (file)
index 0000000..98becca
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2011 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        dlog_log_provider.h
+ * @author      Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version     1.0
+ * @brief       This file is the implementation file of DLOG log provider
+ */
+#ifndef IMA_EVMSERVER_DLOG_LOG_PROVIDER_H
+#define IMA_EVMSERVER_DLOG_LOG_PROVIDER_H
+
+#include <dpl/log/abstract_log_provider.h>
+#include <memory>
+#include <string>
+
+namespace IMAEVMServer {
+namespace Log {
+class DLOGLogProvider :
+    public AbstractLogProvider
+{
+  private:
+    std::unique_ptr<char[]> m_tag;
+
+    static std::string FormatMessage(const char *message,
+                                     const char *filename,
+                                     int line,
+                                     const char *function);
+
+  public:
+    DLOGLogProvider();
+    virtual ~DLOGLogProvider();
+
+    virtual void Debug(const char *message,
+                       const char *fileName,
+                       int line,
+                       const char *function);
+    virtual void Info(const char *message,
+                      const char *fileName,
+                      int line,
+                      const char *function);
+    virtual void Warning(const char *message,
+                         const char *fileName,
+                         int line,
+                         const char *function);
+    virtual void Error(const char *message,
+                       const char *fileName,
+                       int line,
+                       const char *function);
+    virtual void Pedantic(const char *message,
+                          const char *fileName,
+                          int line,
+                          const char *function);
+
+    // Set global Tag according to DLOG
+    void SetTag(const char *tag);
+};
+}
+} // namespace IMAEVMServer
+
+#endif // IMA_EVMSERVER_DLOG_LOG_PROVIDER_H
diff --git a/src/service/dpl/log/include/dpl/log/log.h b/src/service/dpl/log/include/dpl/log/log.h
new file mode 100644 (file)
index 0000000..79b1419
--- /dev/null
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2011 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        log.h
+ * @author      Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version     1.0
+ * @brief       This file is the implementation file of log system
+ */
+#ifndef IMA_EVMSERVER_LOG_H
+#define IMA_EVMSERVER_LOG_H
+
+#include <dpl/singleton.h>
+#include <dpl/noncopyable.h>
+#include <dpl/log/abstract_log_provider.h>
+#include <dpl/log/dlog_log_provider.h>
+#include <dpl/log/old_style_log_provider.h>
+#include <sstream>
+#include <list>
+
+namespace IMAEVMServer {
+namespace Log {
+/**
+ * IMAEVMServer log system
+ *
+ * To switch logs into old style, export
+ * DPL_USE_OLD_STYLE_LOGS before application start
+ */
+class LogSystem :
+    private Noncopyable
+{
+  private:
+    typedef std::list<AbstractLogProvider *> AbstractLogProviderPtrList;
+    AbstractLogProviderPtrList m_providers;
+
+    DLOGLogProvider *m_dlogProvider;
+    OldStyleLogProvider *m_oldStyleProvider;
+
+    bool m_isLoggingEnabled;
+
+  public:
+    bool IsLoggingEnabled() const;
+    LogSystem();
+    virtual ~LogSystem();
+
+    /**
+     * Log debug message
+     */
+    void Debug(const char *message,
+               const char *filename,
+               int line,
+               const char *function);
+
+    /**
+     * Log info message
+     */
+    void Info(const char *message,
+              const char *filename,
+              int line,
+              const char *function);
+
+    /**
+     * Log warning message
+     */
+    void Warning(const char *message,
+                 const char *filename,
+                 int line,
+                 const char *function);
+
+    /**
+     * Log error message
+     */
+    void Error(const char *message,
+               const char *filename,
+               int line,
+               const char *function);
+
+    /**
+     * Log pedantic message
+     */
+    void Pedantic(const char *message,
+                  const char *filename,
+                  int line,
+                  const char *function);
+
+    /**
+     * Set default's DLOG provider Tag
+     */
+    void SetTag(const char *tag);
+
+    /**
+     * Add abstract provider to providers list
+     *
+     * @notice Ownership is transfered to LogSystem and deleted upon exit
+     */
+    void AddProvider(AbstractLogProvider *provider);
+
+    /**
+     * Remove abstract provider from providers list
+     */
+    void RemoveProvider(AbstractLogProvider *provider);
+};
+
+/*
+ * Replacement low overhead null logging class
+ */
+class NullStream
+{
+  public:
+    NullStream() {}
+
+    template <typename T>
+    NullStream& operator<<(const T&)
+    {
+        return *this;
+    }
+};
+
+/**
+ * Log system singleton
+ */
+typedef Singleton<LogSystem> LogSystemSingleton;
+}
+} // namespace IMAEVMServer
+
+//
+// Log support
+//
+//
+
+#ifdef DPL_LOGS_ENABLED
+    #define DPL_MACRO_FOR_LOGGING(message, function)                           \
+    do                                                                     \
+    {                                                                      \
+        if (IMAEVMServer::Log::LogSystemSingleton::Instance().IsLoggingEnabled())   \
+        {                                                                  \
+            std::ostringstream platformLog;                                \
+            platformLog << message;                                        \
+            IMAEVMServer::Log::LogSystemSingleton::Instance().function(             \
+                platformLog.str().c_str(),                                 \
+                __FILE__, __LINE__, __FUNCTION__);                         \
+        }                                                                  \
+    } while (0)
+#else
+/* avoid warnings about unused variables */
+    #define DPL_MACRO_FOR_LOGGING(message, function)                           \
+    do {                                                                   \
+        IMAEVMServer::Log::NullStream ns;                                           \
+        ns << message;                                                     \
+    } while (0)
+#endif
+
+#define  LogDebug(message) DPL_MACRO_FOR_LOGGING(message, Debug)
+#define  LogInfo(message) DPL_MACRO_FOR_LOGGING(message, Info)
+#define  LogWarning(message) DPL_MACRO_FOR_LOGGING(message, Warning)
+#define  LogError(message) DPL_MACRO_FOR_LOGGING(message, Error)
+#define  LogPedantic(message) DPL_MACRO_FOR_LOGGING(message, Pedantic)
+
+#endif // IMA_EVMSERVER_LOG_H
diff --git a/src/service/dpl/log/include/dpl/log/old_style_log_provider.h b/src/service/dpl/log/include/dpl/log/old_style_log_provider.h
new file mode 100644 (file)
index 0000000..ccb8cc5
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2011 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        old_style_log_provider.h
+ * @author      Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version     1.0
+ * @brief       This file is the implementation file of old style log provider
+ */
+#ifndef IMA_EVMSERVER_OLD_STYLE_LOG_PROVIDER_H
+#define IMA_EVMSERVER_OLD_STYLE_LOG_PROVIDER_H
+
+#include <dpl/log/abstract_log_provider.h>
+#include <string>
+
+namespace IMAEVMServer {
+namespace Log {
+class OldStyleLogProvider :
+    public AbstractLogProvider
+{
+  private:
+    bool m_showDebug;
+    bool m_showInfo;
+    bool m_showWarning;
+    bool m_showError;
+    bool m_showPedantic;
+    bool m_printStdErr;
+
+    static std::string FormatMessage(const char *message,
+                                     const char *filename,
+                                     int line,
+                                     const char *function);
+
+  public:
+    OldStyleLogProvider(bool showDebug,
+                        bool showInfo,
+                        bool showWarning,
+                        bool showError,
+                        bool showPedantic);
+    OldStyleLogProvider(bool showDebug,
+                        bool showInfo,
+                        bool showWarning,
+                        bool showError,
+                        bool showPedantic,
+                        bool printStdErr);
+    virtual ~OldStyleLogProvider() {}
+
+    virtual void Debug(const char *message,
+                       const char *fileName,
+                       int line,
+                       const char *function);
+    virtual void Info(const char *message,
+                      const char *fileName,
+                      int line,
+                      const char *function);
+    virtual void Warning(const char *message,
+                         const char *fileName,
+                         int line,
+                         const char *function);
+    virtual void Error(const char *message,
+                       const char *fileName,
+                       int line,
+                       const char *function);
+    virtual void Pedantic(const char *message,
+                          const char *fileName,
+                          int line,
+                          const char *function);
+};
+}
+} // namespace IMAEVMServer
+
+#endif // IMA_EVMSERVER_OLD_STYLE_LOG_PROVIDER_H
diff --git a/src/service/dpl/log/src/abstract_log_provider.cpp b/src/service/dpl/log/src/abstract_log_provider.cpp
new file mode 100644 (file)
index 0000000..06ccfa7
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2011 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        abstract_log_provider.cpp
+ * @author      Pawel Sikorski (p.sikorski@samsung.com)
+ * @version     1.0
+ * @brief       This file is the implementation file of abstract log provider
+ */
+#include <stddef.h>
+#include <dpl/log/abstract_log_provider.h>
+#include <cstring>
+
+namespace IMAEVMServer {
+namespace Log {
+const char *AbstractLogProvider::LocateSourceFileName(const char *filename)
+{
+    const char *ptr = strrchr(filename, '/');
+    return ptr != NULL ? ptr + 1 : filename;
+}
+}
+}
diff --git a/src/service/dpl/log/src/dlog_log_provider.cpp b/src/service/dpl/log/src/dlog_log_provider.cpp
new file mode 100644 (file)
index 0000000..bfcf623
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2011 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        dlog_log_provider.cpp
+ * @author      Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version     1.0
+ * @brief       This file is the implementation file of DLOG log provider
+ */
+#include <stddef.h>
+#include <dpl/log/dlog_log_provider.h>
+#include <cstring>
+#include <sstream>
+#include <dlog.h>
+
+namespace IMAEVMServer {
+namespace Log {
+std::string DLOGLogProvider::FormatMessage(const char *message,
+                                           const char *filename,
+                                           int line,
+                                           const char *function)
+{
+    std::ostringstream val;
+
+    val << std::string("[") <<
+    LocateSourceFileName(filename) << std::string(":") << line <<
+    std::string("] ") << function << std::string("(): ") << message;
+
+    return val.str();
+}
+
+DLOGLogProvider::DLOGLogProvider()
+{}
+
+DLOGLogProvider::~DLOGLogProvider()
+{}
+
+void DLOGLogProvider::SetTag(const char *tag)
+{
+    size_t size = strlen(tag)+1;
+    char *buff = new (std::nothrow) char[size];
+    if (buff)
+        memcpy(buff, tag, size);
+    m_tag.reset(buff);
+}
+
+void DLOGLogProvider::Debug(const char *message,
+                            const char *filename,
+                            int line,
+                            const char *function)
+{
+    LOG(LOG_DEBUG, m_tag.get(), "%s",
+        FormatMessage(message, filename, line, function).c_str());
+}
+
+void DLOGLogProvider::Info(const char *message,
+                           const char *filename,
+                           int line,
+                           const char *function)
+{
+    LOG(LOG_INFO, m_tag.get(), "%s",
+        FormatMessage(message, filename, line, function).c_str());
+}
+
+void DLOGLogProvider::Warning(const char *message,
+                              const char *filename,
+                              int line,
+                              const char *function)
+{
+    LOG(LOG_WARN, m_tag.get(), "%s",
+        FormatMessage(message, filename, line, function).c_str());
+}
+
+void DLOGLogProvider::Error(const char *message,
+                            const char *filename,
+                            int line,
+                            const char *function)
+{
+    LOG(LOG_ERROR, m_tag.get(), "%s",
+        FormatMessage(message, filename, line, function).c_str());
+}
+
+void DLOGLogProvider::Pedantic(const char *message,
+                               const char *filename,
+                               int line,
+                               const char *function)
+{
+    LOG(LOG_DEBUG, "IMAEVMServer", "%s", FormatMessage(message,
+                                              filename,
+                                              line,
+                                              function).c_str());
+}
+}
+} // namespace IMAEVMServer
diff --git a/src/service/dpl/log/src/log.cpp b/src/service/dpl/log/src/log.cpp
new file mode 100644 (file)
index 0000000..766e56a
--- /dev/null
@@ -0,0 +1,224 @@
+/*
+ * Copyright (c) 2011 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        log.cpp
+ * @author      Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version     1.0
+ * @brief       This file is the implementation file of log system
+ */
+#include <stddef.h>
+#include <string.h>
+
+#include <dpl/log/log.h>
+#include <dpl/singleton_impl.h>
+
+IMPLEMENT_SINGLETON(IMAEVMServer::Log::LogSystem)
+
+namespace IMAEVMServer {
+namespace Log {
+namespace // anonymous
+{
+const char *OLD_STYLE_LOGS_ENV_NAME = "DPL_USE_OLD_STYLE_LOGS";
+const char *OLD_STYLE_PEDANTIC_LOGS_ENV_NAME =
+    "DPL_USE_OLD_STYLE_PEDANTIC_LOGS";
+const char *OLD_STYLE_LOGS_MASK_ENV_NAME = "DPL_USE_OLD_STYLE_LOGS_MASK";
+const char *IMAEVMServer_LOG_OFF = "DPL_LOG_OFF";
+} // namespace anonymous
+
+bool LogSystem::IsLoggingEnabled() const
+{
+    return m_isLoggingEnabled;
+}
+
+LogSystem::LogSystem() :
+    m_dlogProvider(NULL),
+    m_oldStyleProvider(NULL),
+    m_isLoggingEnabled(!getenv(IMAEVMServer_LOG_OFF))
+{
+    bool oldStyleLogs = false;
+    bool oldStyleDebugLogs = true;
+    bool oldStyleInfoLogs = true;
+    bool oldStyleWarningLogs = true;
+    bool oldStyleErrorLogs = true;
+    bool oldStylePedanticLogs = false;
+
+    // Check environment settings about pedantic logs
+    const char *value = getenv(OLD_STYLE_LOGS_ENV_NAME);
+
+    if (value != NULL && !strcmp(value, "1")) {
+        oldStyleLogs = true;
+    }
+
+    value = getenv(OLD_STYLE_PEDANTIC_LOGS_ENV_NAME);
+
+    if (value != NULL && !strcmp(value, "1")) {
+        oldStylePedanticLogs = true;
+    }
+
+    value = getenv(OLD_STYLE_LOGS_MASK_ENV_NAME);
+
+    if (value != NULL) {
+        size_t len = strlen(value);
+
+        if (len >= 1) {
+            if (value[0] == '0') {
+                oldStyleDebugLogs = false;
+            } else if (value[0] == '1') {
+                oldStyleDebugLogs = true;
+            }
+        }
+
+        if (len >= 2) {
+            if (value[1] == '0') {
+                oldStyleInfoLogs = false;
+            } else if (value[1] == '1') {
+                oldStyleInfoLogs = true;
+            }
+        }
+
+        if (len >= 3) {
+            if (value[2] == '0') {
+                oldStyleWarningLogs = false;
+            } else if (value[2] == '1') {
+                oldStyleWarningLogs = true;
+            }
+        }
+
+        if (len >= 4) {
+            if (value[3] == '0') {
+                oldStyleErrorLogs = false;
+            } else if (value[3] == '1') {
+                oldStyleErrorLogs = true;
+            }
+        }
+    }
+
+    // Setup default DLOG and old style logging
+    if (oldStyleLogs) {
+        // Old style
+        m_oldStyleProvider = new OldStyleLogProvider(oldStyleDebugLogs,
+                                                     oldStyleInfoLogs,
+                                                     oldStyleWarningLogs,
+                                                     oldStyleErrorLogs,
+                                                     oldStylePedanticLogs);
+        AddProvider(m_oldStyleProvider);
+    } else {
+        // DLOG
+        m_dlogProvider = new DLOGLogProvider();
+        AddProvider(m_dlogProvider);
+    }
+}
+
+LogSystem::~LogSystem()
+{
+    // Delete all providers
+    for (AbstractLogProviderPtrList::iterator iterator = m_providers.begin();
+         iterator != m_providers.end();
+         ++iterator)
+    {
+        delete *iterator;
+    }
+
+    m_providers.clear();
+
+    // And even default providers
+    m_dlogProvider = NULL;
+    m_oldStyleProvider = NULL;
+}
+
+void LogSystem::SetTag(const char* tag)
+{
+    if (m_dlogProvider != NULL) {
+        m_dlogProvider->SetTag(tag);
+    }
+}
+
+void LogSystem::AddProvider(AbstractLogProvider *provider)
+{
+    m_providers.push_back(provider);
+}
+
+void LogSystem::RemoveProvider(AbstractLogProvider *provider)
+{
+    m_providers.remove(provider);
+}
+
+void LogSystem::Debug(const char *message,
+                      const char *filename,
+                      int line,
+                      const char *function)
+{
+    for (AbstractLogProviderPtrList::iterator iterator = m_providers.begin();
+         iterator != m_providers.end();
+         ++iterator)
+    {
+        (*iterator)->Debug(message, filename, line, function);
+    }
+}
+
+void LogSystem::Info(const char *message,
+                     const char *filename,
+                     int line,
+                     const char *function)
+{
+    for (AbstractLogProviderPtrList::iterator iterator = m_providers.begin();
+         iterator != m_providers.end();
+         ++iterator)
+    {
+        (*iterator)->Info(message, filename, line, function);
+    }
+}
+
+void LogSystem::Warning(const char *message,
+                        const char *filename,
+                        int line,
+                        const char *function)
+{
+    for (AbstractLogProviderPtrList::iterator iterator = m_providers.begin();
+         iterator != m_providers.end();
+         ++iterator)
+    {
+        (*iterator)->Warning(message, filename, line, function);
+    }
+}
+
+void LogSystem::Error(const char *message,
+                      const char *filename,
+                      int line,
+                      const char *function)
+{
+    for (AbstractLogProviderPtrList::iterator iterator = m_providers.begin();
+         iterator != m_providers.end();
+         ++iterator)
+    {
+        (*iterator)->Error(message, filename, line, function);
+    }
+}
+
+void LogSystem::Pedantic(const char *message,
+                         const char *filename,
+                         int line,
+                         const char *function)
+{
+    for (AbstractLogProviderPtrList::iterator iterator = m_providers.begin();
+         iterator != m_providers.end();
+         ++iterator)
+    {
+        (*iterator)->Pedantic(message, filename, line, function);
+    }
+}
+}
+} // namespace IMAEVMServer
diff --git a/src/service/dpl/log/src/old_style_log_provider.cpp b/src/service/dpl/log/src/old_style_log_provider.cpp
new file mode 100644 (file)
index 0000000..d36369e
--- /dev/null
@@ -0,0 +1,200 @@
+/*
+ * Copyright (c) 2011 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        old_style_log_provider.cpp
+ * @author      Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version     1.0
+ * @brief       This file is the implementation file of old style log provider
+ */
+#include <stddef.h>
+#include <dpl/log/old_style_log_provider.h>
+#include <dpl/colors.h>
+#include <cstdio>
+#include <cstring>
+#include <sstream>
+#include <sys/time.h>
+#include <unistd.h>
+
+namespace IMAEVMServer {
+namespace Log {
+namespace // anonymous
+{
+using namespace IMAEVMServer::Colors::Text;
+const char *DEBUG_BEGIN = GREEN_BEGIN;
+const char *DEBUG_END = GREEN_END;
+const char *INFO_BEGIN = CYAN_BEGIN;
+const char *INFO_END = CYAN_END;
+const char *ERROR_BEGIN = RED_BEGIN;
+const char *ERROR_END = RED_END;
+const char *WARNING_BEGIN = BOLD_GOLD_BEGIN;
+const char *WARNING_END = BOLD_GOLD_END;
+const char *PEDANTIC_BEGIN = PURPLE_BEGIN;
+const char *PEDANTIC_END = PURPLE_END;
+
+std::string GetFormattedTime()
+{
+    timeval tv;
+    tm localNowTime;
+
+    gettimeofday(&tv, NULL);
+    localtime_r(&tv.tv_sec, &localNowTime);
+
+    char format[64];
+    snprintf(format,
+             sizeof(format),
+             "%02i:%02i:%02i.%03i",
+             localNowTime.tm_hour,
+             localNowTime.tm_min,
+             localNowTime.tm_sec,
+             static_cast<int>(tv.tv_usec / 1000));
+    return format;
+}
+} // namespace anonymous
+
+std::string OldStyleLogProvider::FormatMessage(const char *message,
+                                               const char *filename,
+                                               int line,
+                                               const char *function)
+{
+    std::ostringstream val;
+
+    val << std::string("[") << GetFormattedTime() << std::string("] [") <<
+    static_cast<unsigned long>(pthread_self()) << "/" <<
+    static_cast<int>(getpid()) << std::string("] [") <<
+    LocateSourceFileName(filename) << std::string(":") << line <<
+    std::string("] ") << function << std::string("(): ") << message;
+
+    return val.str();
+}
+
+OldStyleLogProvider::OldStyleLogProvider(bool showDebug,
+                                         bool showInfo,
+                                         bool showWarning,
+                                         bool showError,
+                                         bool showPedantic) :
+    m_showDebug(showDebug),
+    m_showInfo(showInfo),
+    m_showWarning(showWarning),
+    m_showError(showError),
+    m_showPedantic(showPedantic),
+    m_printStdErr(false)
+{}
+
+OldStyleLogProvider::OldStyleLogProvider(bool showDebug,
+                                         bool showInfo,
+                                         bool showWarning,
+                                         bool showError,
+                                         bool showPedantic,
+                                         bool printStdErr) :
+    m_showDebug(showDebug),
+    m_showInfo(showInfo),
+    m_showWarning(showWarning),
+    m_showError(showError),
+    m_showPedantic(showPedantic),
+    m_printStdErr(printStdErr)
+{}
+
+void OldStyleLogProvider::Debug(const char *message,
+                                const char *filename,
+                                int line,
+                                const char *function)
+{
+    if (m_showDebug) {
+        if (m_printStdErr) {
+            fprintf(stderr, "%s%s%s\n", DEBUG_BEGIN,
+                    FormatMessage(message, filename, line,
+                        function).c_str(), DEBUG_END);
+        } else {
+            fprintf(stdout, "%s%s%s\n", DEBUG_BEGIN,
+                    FormatMessage(message, filename, line,
+                        function).c_str(), DEBUG_END);
+        }
+    }
+}
+
+void OldStyleLogProvider::Info(const char *message,
+                               const char *filename,
+                               int line,
+                               const char *function)
+{
+    if (m_showInfo) {
+        if (m_printStdErr) {
+            fprintf(stderr, "%s%s%s\n", INFO_BEGIN,
+                    FormatMessage(message, filename, line,
+                        function).c_str(), INFO_END);
+        } else {
+            fprintf(stdout, "%s%s%s\n", INFO_BEGIN,
+                    FormatMessage(message, filename, line,
+                        function).c_str(), INFO_END);
+        }
+    }
+}
+
+void OldStyleLogProvider::Warning(const char *message,
+                                  const char *filename,
+                                  int line,
+                                  const char *function)
+{
+    if (m_showWarning) {
+        if (m_printStdErr) {
+            fprintf(stderr, "%s%s%s\n", WARNING_BEGIN,
+                    FormatMessage(message, filename, line,
+                        function).c_str(), WARNING_END);
+        } else {
+            fprintf(stdout, "%s%s%s\n", WARNING_BEGIN,
+                    FormatMessage(message, filename, line,
+                        function).c_str(), WARNING_END);
+        }
+    }
+}
+
+void OldStyleLogProvider::Error(const char *message,
+                                const char *filename,
+                                int line,
+                                const char *function)
+{
+    if (m_showError) {
+        if (m_printStdErr) {
+            fprintf(stderr, "%s%s%s\n", ERROR_BEGIN,
+                    FormatMessage(message, filename, line,
+                        function).c_str(), ERROR_END);
+        } else {
+            fprintf(stdout, "%s%s%s\n", ERROR_BEGIN,
+                    FormatMessage(message, filename, line,
+                        function).c_str(), ERROR_END);
+        }
+    }
+}
+
+void OldStyleLogProvider::Pedantic(const char *message,
+                                   const char *filename,
+                                   int line,
+                                   const char *function)
+{
+    if (m_showPedantic) {
+        if (m_printStdErr) {
+            fprintf(stderr, "%s%s%s\n", PEDANTIC_BEGIN,
+                    FormatMessage(message, filename, line,
+                        function).c_str(), PEDANTIC_END);
+        } else {
+            fprintf(stdout, "%s%s%s\n", PEDANTIC_BEGIN,
+                    FormatMessage(message, filename, line,
+                        function).c_str(), PEDANTIC_END);
+        }
+    }
+}
+}
+} // namespace IMAEVMServer
diff --git a/src/service/main/generic-event.h b/src/service/main/generic-event.h
new file mode 100644 (file)
index 0000000..f1077b0
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ *  Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Contact: Bumjin Im <bj.im@samsung.com>
+ *
+ *  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        protocols.h
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version     1.0
+ * @brief       Implementation of GenericEvent.
+ */
+
+#ifndef _IMA_EVM_SERVER_GENERIC_EVENT_
+#define _IMA_EVM_SERVER_GENERIC_EVENT_
+
+namespace IMAEVMServer {
+
+struct GenericEvent {
+    virtual ~GenericEvent(){}
+};
+
+} // namespace IMAEVMServer
+
+#endif // _IMA_EVM_SERVER_GENERIC_EVENT_
diff --git a/src/service/main/generic-socket-manager.h b/src/service/main/generic-socket-manager.h
new file mode 100644 (file)
index 0000000..d7e66e8
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ *  Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Contact: Bumjin Im <bj.im@samsung.com>
+ *
+ *  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        generic-socket-manager.h
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version     1.0
+ * @brief       Implementation of GenericSocketService and GenericSocketManager.
+ */
+
+#ifndef _IMA_EVM_SERVER_GENERIC_SERVICE_MANAGER_
+#define _IMA_EVM_SERVER_GENERIC_SERVICE_MANAGER_
+
+#include <vector>
+#include <string>
+
+#include <dpl/exception.h>
+
+#include <generic-event.h>
+
+namespace IMAEVMServer {
+
+typedef int InterfaceID;
+
+struct ConnectionID {
+    int sock;                                 // This is decriptor used for connection
+    int counter;                              // Unique handler per socket
+    inline bool operator<(const ConnectionID &second) const {
+        return counter < second.counter;
+    }
+};
+
+typedef std::vector<unsigned char> RawBuffer;
+
+struct GenericSocketManager;
+
+struct GenericSocketService {
+    typedef std::string SmackLabel;
+    typedef std::string ServiceHandlerPath;
+    struct ServiceDescription {
+        SmackLabel smackLabel;                 // Smack label for socket
+        InterfaceID interfaceID;               // All data from serviceHandlerPath will be marked with this interfaceHandler
+        ServiceHandlerPath serviceHandlerPath; // Path to file
+    };
+
+    typedef std::vector<ServiceDescription> ServiceDescriptionVector;
+
+    struct AcceptEvent : public GenericEvent {
+        ConnectionID connectionID;
+        InterfaceID interfaceID;
+    };
+
+    struct WriteEvent : public GenericEvent {
+        ConnectionID connectionID;
+        size_t size;
+        size_t left;
+    };
+
+    struct ReadEvent : public GenericEvent {
+        ConnectionID connectionID;
+        RawBuffer rawBuffer;
+    };
+
+    struct CloseEvent : public GenericEvent {
+        ConnectionID connectionID;
+    };
+
+    struct ErrorEvent : public GenericEvent {
+        ConnectionID connectionID;
+    };
+
+    virtual void SetSocketManager(GenericSocketManager *manager) {
+        m_serviceManager = manager;
+    }
+
+    virtual ServiceDescriptionVector GetServiceDescription() = 0;
+    virtual void Event(const AcceptEvent &event) = 0;
+    virtual void Event(const WriteEvent &event) = 0;
+    virtual void Event(const ReadEvent &event) = 0;
+    virtual void Event(const CloseEvent &event) = 0;
+    virtual void Event(const ErrorEvent &event) = 0;
+    virtual ~GenericSocketService(){}
+protected:
+    GenericSocketManager *m_serviceManager;
+};
+
+struct GenericSocketManager {
+    virtual void MainLoop() = 0;
+    virtual void RegisterSocketService(GenericSocketService *ptr) = 0;
+    virtual void Close(ConnectionID connectionID) = 0;
+    virtual void Write(ConnectionID connectionID, const RawBuffer &rawBuffer) = 0;
+    virtual ~GenericSocketManager(){}
+};
+
+} // namespace IMAEVMServer
+
+#endif // _IMA_EVM_SERVER_GENERIC_SERVICE_MANAGER_
diff --git a/src/service/main/server2-main.cpp b/src/service/main/server2-main.cpp
new file mode 100644 (file)
index 0000000..94e2145
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ *  Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Contact: Bumjin Im <bj.im@samsung.com>
+ *
+ *  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        sever2-main.cpp
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version     1.0
+ * @brief       Implementation of ima-evm-server2
+ */
+
+#include <server2-main.h>
+
+#include <dpl/log/log.h>
+#include <dpl/singleton.h>
+#include <dpl/singleton_safe_impl.h>
+
+#include <service-thread.h>
+#include <socket-manager.h>
+
+#include <echo.h>
+
+IMPLEMENT_SAFE_SINGLETON(IMAEVMServer::Log::LogSystem);
+
+int main(void) {
+    UNHANDLED_EXCEPTION_HANDLER_BEGIN
+    {
+        IMAEVMServer::Singleton<IMAEVMServer::Log::LogSystem>::Instance().SetTag("IMA_EVM_SERVER2");
+        LogInfo("Start!");
+        IMAEVMServer::SocketManager manager;
+
+//        This will be used only by tests
+        IMAEVMServer::EchoService *echoService = new IMAEVMServer::EchoService;
+        echoService->Create();
+        manager.RegisterSocketService(echoService);
+
+        manager.MainLoop();
+    }
+    UNHANDLED_EXCEPTION_HANDLER_END
+    return 0;
+}
+
diff --git a/src/service/main/server2-main.h b/src/service/main/server2-main.h
new file mode 100644 (file)
index 0000000..6eedfce
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ *  Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Contact: Bumjin Im <bj.im@samsung.com>
+ *
+ *  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        server-main2.h
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version     1.0
+ * @brief       Implementation of ima-evm-server2.
+ */
+
+#ifndef _IMA_EVM_SERVER_SERVER2_
+#define _IMA_EVM_SERVER_SERVER2_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int server2(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _IMA_EVM_SERVER_SERVER2_
+
diff --git a/src/service/main/service-thread.h b/src/service/main/service-thread.h
new file mode 100644 (file)
index 0000000..5468917
--- /dev/null
@@ -0,0 +1,172 @@
+/*
+ *  Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Contact: Bumjin Im <bj.im@samsung.com>
+ *
+ *  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        service-thread.h
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version     1.0
+ * @brief       Implementation of threads.
+ */
+
+#ifndef _IMA_EVM_SERVER_SERVICE_THREAD_
+#define _IMA_EVM_SERVER_SERVICE_THREAD_
+
+#include <cassert>
+#include <queue>
+#include <mutex>
+#include <thread>
+#include <memory>
+#include <condition_variable>
+
+#include <cstdio>
+
+#include <dpl/exception.h>
+
+#include "generic-event.h"
+
+#define DEFINE_THREAD_EVENT(eventType)                                \
+    void Event(const eventType &event) {                              \
+        IMAEVMServer::ServiceThread<ParentClassName>::              \
+            Event(event,                                              \
+                  this,                                               \
+                  &ParentClassName::EventInternal##eventType);        \
+    }                                                                 \
+    void EventInternal##eventType(const eventType &event)
+
+#define DECLARE_THREAD_EVENT(eventType, methodName)                   \
+    void Event(const eventType &event) {                              \
+        IMAEVMServer::ServiceThread<ParentClassName>::              \
+            Event(event,                                              \
+                  this,                                               \
+                  &ParentClassName::methodName);                      \
+    }
+
+namespace IMAEVMServer {
+
+template <class Service>
+class ServiceThread {
+public:
+    typedef Service ParentClassName;
+    enum class State {
+        NoThread,
+        Work,
+    };
+
+    ServiceThread()
+      : m_state(State::NoThread)
+      , m_quit(false)
+    {}
+
+    void Create() {
+        assert(m_state == State::NoThread);
+        m_thread = std::thread(ThreadLoopStatic, this);
+        m_state = State::Work;
+    }
+
+    void Join() {
+        assert(m_state != State::NoThread);
+        m_quit = true;
+        m_waitCondition.notify_one();
+        m_thread.join();
+        m_state = State::NoThread;
+    }
+
+    virtual ~ServiceThread()
+    {
+        if (m_state != State::NoThread)
+            Join();
+        while (!m_eventQueue.empty()){
+            auto front = m_eventQueue.front();
+            delete front.eventPtr;
+            m_eventQueue.pop();
+        }
+    }
+
+    template <class T>
+    void Event(const T &event,
+               Service *servicePtr,
+               void (Service::*serviceFunction)(const T &))
+    {
+        EventDescription description;
+        description.serviceFunctionPtr =
+            reinterpret_cast<void (Service::*)(void*)>(serviceFunction);
+        description.servicePtr = servicePtr;
+        description.eventFunctionPtr = &ServiceThread::EventCall<T>;
+        description.eventPtr = new T(event);
+        {
+            std::lock_guard<std::mutex> lock(m_eventQueueMutex);
+            m_eventQueue.push(description);
+        }
+        m_waitCondition.notify_one();
+    }
+
+protected:
+
+    struct EventDescription {
+        void (Service::*serviceFunctionPtr)(void *);
+        Service *servicePtr;
+        void (ServiceThread::*eventFunctionPtr)(const EventDescription &event);
+        GenericEvent* eventPtr;
+    };
+
+    template <class T>
+    void EventCall(const EventDescription &desc) {
+        auto fun = reinterpret_cast<void (Service::*)(const T&)>(desc.serviceFunctionPtr);
+        const T& eventLocale = *(static_cast<T*>(desc.eventPtr));
+        (desc.servicePtr->*fun)(eventLocale);
+    }
+
+    static void ThreadLoopStatic(ServiceThread *ptr) {
+        ptr->ThreadLoop();
+    }
+
+    void ThreadLoop(){
+        while(m_quit == false) {
+            EventDescription description = {NULL, NULL, NULL, NULL};
+            {
+                std::unique_lock<std::mutex> ulock(m_eventQueueMutex);
+                if (!m_eventQueue.empty()) {
+                    description = m_eventQueue.front();
+                    m_eventQueue.pop();
+                } else {
+                    m_waitCondition.wait(ulock);
+                }
+            }
+
+            if (description.eventPtr != NULL) {
+                UNHANDLED_EXCEPTION_HANDLER_BEGIN
+                {
+                    (this->*description.eventFunctionPtr)(description);
+                    delete description.eventPtr;
+                }
+                UNHANDLED_EXCEPTION_HANDLER_END
+            }
+        }
+    }
+
+    std::thread m_thread;
+    std::mutex m_eventQueueMutex;
+    std::queue<EventDescription> m_eventQueue;
+    std::condition_variable m_waitCondition;
+
+    State m_state;
+    bool m_quit;
+};
+
+} // namespace IMAEVMServer
+
+#endif // _IMA_EVM_SERVER_SERVICE_THREAD_
diff --git a/src/service/main/socket-manager.cpp b/src/service/main/socket-manager.cpp
new file mode 100644 (file)
index 0000000..96bda94
--- /dev/null
@@ -0,0 +1,487 @@
+/*
+ *  Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Contact: Bumjin Im <bj.im@samsung.com>
+ *
+ *  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        socket-manager.cpp
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version     1.0
+ * @brief       Implementation of SocketManager.
+ */
+
+#include <sys/select.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/smack.h>
+#include <sys/un.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <errno.h>
+#include <time.h>
+
+#include <dpl/log/log.h>
+#include <dpl/assert.h>
+
+#include <socket-manager.h>
+
+namespace {
+
+const time_t SOCKET_TIMEOUT = 20;
+
+} // namespace anonymous
+
+namespace IMAEVMServer {
+
+struct DummyService : public GenericSocketService {
+    ServiceDescriptionVector GetServiceDescription() {
+        return ServiceDescriptionVector();
+    }
+    void Event(const AcceptEvent &event) { (void)event; }
+    void Event(const WriteEvent &event) { (void)event; }
+    void Event(const ReadEvent &event) { (void)event; }
+    void Event(const CloseEvent &event) { (void)event; }
+    void Event(const ErrorEvent &event) { (void)event; }
+};
+
+SocketManager::SocketDescription&
+SocketManager::CreateDefaultReadSocketDescription(int sock, bool timeout)
+{
+    if ((int)m_socketDescriptionVector.size() <= sock)
+        m_socketDescriptionVector.resize(sock+20);
+
+    auto &desc = m_socketDescriptionVector[sock];
+    desc.isListen = false;
+    desc.isOpen = true;
+    desc.interfaceID = 0;
+    desc.service = NULL;
+    desc.counter = ++m_counter;
+
+    if (timeout) {
+        desc.timeout = time(NULL) + SOCKET_TIMEOUT;
+        if (false == desc.isTimeout) {
+            Timeout tm;
+            tm.time = desc.timeout;
+            tm.sock = sock;
+            m_timeoutQueue.push(tm);
+        }
+    }
+
+    desc.isTimeout = timeout;
+
+    FD_SET(sock, &m_readSet);
+    m_maxDesc = sock > m_maxDesc ? sock : m_maxDesc;
+    return desc;
+}
+
+SocketManager::SocketManager()
+  : m_counter(0)
+{
+    FD_ZERO(&m_readSet);
+    FD_ZERO(&m_writeSet);
+    if (-1 == pipe(m_notifyMe)) {
+        int err = errno;
+        ThrowMsg(Exception::InitFailed, "Error in pipe: " << strerror(err));
+    }
+    LogInfo("Pipe: Read desc: " << m_notifyMe[0] << " Write desc: " << m_notifyMe[1]);
+
+    auto &desc = CreateDefaultReadSocketDescription(m_notifyMe[0], false);
+    desc.service = new DummyService;
+
+    // std::thread bases on pthread so this should work fine
+    sigset_t set;
+    sigemptyset(&set);
+    sigaddset(&set, SIGPIPE);
+    pthread_sigmask(SIG_BLOCK, &set, NULL);
+}
+
+SocketManager::~SocketManager() {
+
+}
+
+void SocketManager::ReadyForAccept(int sock) {
+    struct sockaddr_un clientAddr;
+    unsigned int clientLen = sizeof(clientAddr);
+    LogInfo("Accept on sock: " << sock);
+    int client = accept4(sock, (struct sockaddr*) &clientAddr, &clientLen, SOCK_NONBLOCK);
+    if (-1 == client) {
+        int err = errno;
+        LogDebug("Error in accept: " << strerror(err));
+        return;
+    }
+
+    auto &desc = CreateDefaultReadSocketDescription(client, true);
+    desc.interfaceID = m_socketDescriptionVector[sock].interfaceID;
+    desc.service = m_socketDescriptionVector[sock].service;
+
+    GenericSocketService::AcceptEvent event;
+    event.connectionID.sock = client;
+    event.connectionID.counter = desc.counter;
+    event.interfaceID = desc.interfaceID;
+    desc.service->Event(event);
+}
+
+void SocketManager::ReadyForRead(int sock) {
+    if (m_socketDescriptionVector[sock].isListen) {
+        ReadyForAccept(sock);
+        return;
+    }
+
+    GenericSocketService::ReadEvent event;
+    event.connectionID.sock = sock;
+    event.connectionID.counter = m_socketDescriptionVector[sock].counter;
+    event.rawBuffer.resize(4096);
+
+    auto &desc = m_socketDescriptionVector[sock];
+    desc.timeout = time(NULL) + SOCKET_TIMEOUT;
+
+    ssize_t size = read(sock, &event.rawBuffer[0], 4096);
+
+    if (size == 0) {
+        CloseSocket(sock);
+    } else if (size >= 0) {
+        event.rawBuffer.resize(size);
+        desc.service->Event(event);
+    } else if (size == -1) {
+        int err = errno;
+        switch(err) {
+            case EAGAIN:
+            case EINTR:
+                break;
+            default:
+                LogDebug("Reading sock error: " << strerror(err));
+                CloseSocket(sock);
+        }
+    }
+}
+
+void SocketManager::ReadyForWrite(int sock) {
+    auto &desc = m_socketDescriptionVector[sock];
+    size_t size = desc.rawBuffer.size();
+    ssize_t result = write(sock, &desc.rawBuffer[0], size);
+    if (result == -1) {
+        int err = errno;
+        switch(err) {
+        case EAGAIN:
+        case EINTR:
+            // select will trigger write once again, nothing to do
+            break;
+        case EPIPE:
+        default:
+            int i = errno;
+            LogDebug("Error during write: " << strerror(i));
+            CloseSocket(sock);
+            break;
+        }
+        return; // We do not want to propagate error to next layer
+    }
+
+    desc.rawBuffer.erase(desc.rawBuffer.begin(), desc.rawBuffer.begin()+result);
+
+    desc.timeout = time(NULL) + SOCKET_TIMEOUT;
+
+    if (desc.rawBuffer.empty())
+        FD_CLR(sock, &m_writeSet);
+
+    GenericSocketService::WriteEvent event;
+    event.connectionID.sock = sock;
+    event.connectionID.counter = desc.counter;
+    event.size = result;
+    event.left = desc.rawBuffer.size();
+
+    desc.service->Event(event);
+}
+
+void SocketManager::MainLoop() {
+    m_working = true;
+    while(m_working) {
+        fd_set readSet = m_readSet;
+        fd_set writeSet = m_writeSet;
+
+        timeval localTempTimeout;
+        timeval *ptrTimeout = &localTempTimeout;
+
+        // I need to extract timeout from priority_queue.
+        // Timeout in priority_queue may be deprecated.
+        // I need to find some actual one.
+        while(!m_timeoutQueue.empty()) {
+            auto &top = m_timeoutQueue.top();
+            auto &desc = m_socketDescriptionVector[top.sock];
+
+            if (top.time == desc.timeout) {
+                // This timeout matches timeout from socket.
+                // It can be used.
+                break;
+            } else {
+                // This socket was used after timeout in priority queue was set up.
+                // We need to update timeout and find some useable one.
+                Timeout tm = { desc.timeout , top.sock};
+                m_timeoutQueue.pop();
+                m_timeoutQueue.push(tm);
+            }
+        }
+
+        if (m_timeoutQueue.empty()) {
+            LogDebug("No usaable timeout found.");
+            ptrTimeout = NULL; // select will wait without timeout
+        } else {
+            time_t currentTime = time(NULL);
+            auto &pqTimeout = m_timeoutQueue.top();
+
+            // 0 means that select won't block and socket will be closed ;-)
+            ptrTimeout->tv_sec =
+              currentTime < pqTimeout.time ? pqTimeout.time - currentTime : 0;
+            ptrTimeout->tv_usec = 0;
+            LogDebug("Set up timeout: " << (int)ptrTimeout->tv_sec
+                << " seconds. Socket: " << pqTimeout.sock);
+        }
+
+        int ret = select(m_maxDesc+1, &readSet, &writeSet, NULL, ptrTimeout);
+
+        if (0 == ret) { // timeout
+            Assert(!m_timeoutQueue.empty());
+
+            Timeout pqTimeout = m_timeoutQueue.top();
+            m_timeoutQueue.pop();
+
+            auto &desc = m_socketDescriptionVector[pqTimeout.sock];
+
+            if (!desc.isTimeout || !desc.isOpen) {
+                // Connection was closed. Timeout is useless...
+                desc.isTimeout = false;
+                continue;
+            }
+
+            if (pqTimeout.time < desc.timeout) {
+                // Is it possible?
+                // This socket was used after timeout. We need to update timeout.
+                pqTimeout.time = desc.timeout;
+                m_timeoutQueue.push(pqTimeout);
+                continue;
+            }
+
+            // timeout from m_timeoutQueue matches with socket.timeout
+            // and connection is open. Time to close it!
+            // Putting new timeout in queue here is pointless.
+            desc.isTimeout = false;
+            CloseSocket(pqTimeout.sock);
+
+            // All done. Now we should process next select ;-)
+            continue;
+        }
+
+        if (-1 == ret) {
+            switch(errno) {
+            case EINTR:
+                LogDebug("EINTR in select");
+                break;
+            default:
+                int err = errno;
+                LogError("Error in select: " << strerror(err));
+                return;
+            }
+            continue;
+        }
+        for(int i = 0; i<m_maxDesc+1 && ret; ++i) {
+            if (FD_ISSET(i, &readSet)) {
+                ReadyForRead(i);
+                --ret;
+            }
+            if (FD_ISSET(i, &writeSet)) {
+                ReadyForWrite(i);
+                --ret;
+            }
+        }
+        ProcessQueue();
+    }
+}
+
+void SocketManager::CreateDomainSocket(
+    GenericSocketService *service,
+    const GenericSocketService::ServiceDescription &desc)
+{
+    int sockfd = -1;
+
+    if (-1 == (sockfd = socket(AF_UNIX, SOCK_STREAM, 0))) {
+        int err = errno;
+        LogError("Error in socket: " << strerror(err));
+        ThrowMsg(Exception::InitFailed, "Error in socket: " << strerror(err));
+    }
+
+    //LogInfo("TODO: Set up smack label: " << desc.smackLabel);
+
+    //if (0 != smack_fsetlabel(sockfd, desc.smackLabel.c_str(), SMACK_LABEL_IPIN)) {
+    //   LogError("Error in smack_fsetlabel");
+    //    ThrowMsg(Exception::InitFailed, "Error in smack_fsetlabel");
+    //}
+
+    int flags;
+    if (-1 == (flags = fcntl(sockfd, F_GETFL, 0)))
+        flags = 0;
+
+    if (-1 == fcntl(sockfd, F_SETFL, flags | O_NONBLOCK)) {
+        int err = errno;
+        close(sockfd);
+        LogError("Error in fcntl: " << strerror(err));
+        ThrowMsg(Exception::InitFailed, "Error in fcntl: " << strerror(err));
+    }
+
+    sockaddr_un serverAddress;
+    memset(&serverAddress, 0, sizeof(serverAddress));
+    serverAddress.sun_family = AF_UNIX;
+    strcpy(serverAddress.sun_path, desc.serviceHandlerPath.c_str());
+    unlink(serverAddress.sun_path);
+
+    mode_t originalUmask;
+    originalUmask = umask(0);
+
+    if (-1 == bind(sockfd, (struct sockaddr*)&serverAddress, sizeof(serverAddress))) {
+        int err = errno;
+        close(sockfd);
+        LogError("Error in bind: " << strerror(err));
+        ThrowMsg(Exception::InitFailed, "Error in bind: " << strerror(err));
+    }
+
+    umask(originalUmask);
+
+    if (-1 == listen(sockfd, 5)) {
+        int err = errno;
+        close(sockfd);
+        LogError("Error in listen: " << strerror(err));
+        ThrowMsg(Exception::InitFailed, "Error in listen: " << strerror(err));
+    }
+
+    auto &description = CreateDefaultReadSocketDescription(sockfd, false);
+
+    description.isListen = true;
+    description.interfaceID = desc.interfaceID;
+    description.service = service;
+
+    LogDebug("Listen on socket: " << sockfd <<
+        " Handler: " << desc.serviceHandlerPath.c_str());
+}
+
+void SocketManager::RegisterSocketService(GenericSocketService *service) {
+    LogDebug("Pointer to service " << (void*) service);
+    service->SetSocketManager(this);
+    auto serviceVector = service->GetServiceDescription();
+    Try {
+        for (auto iter = serviceVector.begin(); iter != serviceVector.end(); ++iter)
+            CreateDomainSocket(service, *iter);
+    } Catch (Exception::Base) {
+        for (int i =0; i < (int)m_socketDescriptionVector.size(); ++i)
+        {
+            auto &desc = m_socketDescriptionVector[i];
+            if (desc.service == service && desc.isOpen) {
+                close(i);
+                desc.isOpen = false;
+            }
+        }
+        ReThrow(Exception::Base);
+    }
+}
+
+void SocketManager::Close(ConnectionID connectionID) {
+    {
+        std::unique_lock<std::mutex> ulock(m_eventQueueMutex);
+        m_closeQueue.push(connectionID);
+    }
+    NotifyMe();
+}
+
+void SocketManager::Write(ConnectionID connectionID, const RawBuffer &rawBuffer) {
+    WriteBuffer buffer;
+    buffer.connectionID = connectionID;
+    buffer.rawBuffer = rawBuffer;
+    {
+        std::unique_lock<std::mutex> ulock(m_eventQueueMutex);
+        m_writeBufferQueue.push(buffer);
+    }
+    NotifyMe();
+}
+
+void SocketManager::NotifyMe() {
+    TEMP_FAILURE_RETRY(write(m_notifyMe[1], "You have message ;-)", 1));
+}
+
+void SocketManager::ProcessQueue() {
+    WriteBuffer buffer;
+    {
+        std::unique_lock<std::mutex> ulock(m_eventQueueMutex);
+        while (!m_writeBufferQueue.empty()) {
+            buffer = m_writeBufferQueue.front();
+            m_writeBufferQueue.pop();
+            if (!m_socketDescriptionVector[buffer.connectionID.sock].isOpen) {
+                LogDebug("Received packet for write but connection is closed. Packet ignored!");
+                continue;
+            }
+            if (m_socketDescriptionVector[buffer.connectionID.sock].counter !=
+                buffer.connectionID.counter)
+            {
+                LogDebug("Received packet for write but counter is broken. Packet ignored!");
+                continue;
+            }
+            std::copy(
+                buffer.rawBuffer.begin(),
+                buffer.rawBuffer.end(),
+                std::back_inserter(
+                    m_socketDescriptionVector[buffer.connectionID.sock].rawBuffer));
+
+            FD_SET(buffer.connectionID.sock, &m_writeSet);
+        }
+    }
+
+    while (1) {
+        ConnectionID connection;
+        {
+            std::unique_lock<std::mutex> ulock(m_eventQueueMutex);
+            if (m_closeQueue.empty())
+                return;
+            connection = m_closeQueue.front();
+            m_closeQueue.pop();
+        }
+
+        if (!m_socketDescriptionVector[connection.sock].isOpen)
+            continue;
+
+        if (connection.counter != m_socketDescriptionVector[connection.sock].counter)
+            continue;
+
+        CloseSocket(connection.sock);
+    }
+}
+
+void SocketManager::CloseSocket(int sock) {
+    auto &desc = m_socketDescriptionVector[sock];
+
+    GenericSocketService::CloseEvent event;
+    event.connectionID.sock = sock;
+    event.connectionID.counter = desc.counter;
+    auto service = desc.service;
+
+    desc.isOpen = false;
+    desc.service = NULL;
+    desc.interfaceID = -1;
+    desc.rawBuffer.clear();
+
+    service->Event(event);
+    TEMP_FAILURE_RETRY(close(sock));
+    FD_CLR(sock, &m_readSet);
+    FD_CLR(sock, &m_writeSet);
+}
+
+} // namespace IMAEVMServer
diff --git a/src/service/main/socket-manager.h b/src/service/main/socket-manager.h
new file mode 100644 (file)
index 0000000..f83a62e
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ *  Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Contact: Bumjin Im <bj.im@samsung.com>
+ *
+ *  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        socket-manager.h
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version     1.0
+ * @brief       SocketManager implementation.
+ */
+
+#ifndef _IMA_EVM_SERVER_SOCKET_MANAGER_
+#define _IMA_EVM_SERVER_SOCKET_MANAGER_
+
+#include <tuple>
+#include <vector>
+#include <queue>
+#include <string>
+#include <mutex>
+#include <thread>
+
+#include <dpl/exception.h>
+
+#include <generic-socket-manager.h>
+
+namespace IMAEVMServer {
+
+class SocketManager : public GenericSocketManager {
+public:
+    class Exception {
+    public:
+        DECLARE_EXCEPTION_TYPE(IMAEVMServer::Exception, Base)
+        DECLARE_EXCEPTION_TYPE(Base, InitFailed)
+    };
+    SocketManager();
+    virtual ~SocketManager();
+    virtual void MainLoop();
+
+    virtual void RegisterSocketService(GenericSocketService *service);
+    virtual void Close(ConnectionID connectionID);
+    virtual void Write(ConnectionID connectionID, const RawBuffer &rawBuffer);
+
+protected:
+    void CreateDomainSocket(
+        GenericSocketService *service,
+        const GenericSocketService::ServiceDescription &desc);
+    void ReadyForRead(int sock);
+    void ReadyForWrite(int sock);
+    void ReadyForAccept(int sock);
+    void ProcessQueue(void);
+    void NotifyMe(void);
+    void CloseSocket(int sock);
+
+    struct SocketDescription {
+        bool isListen;
+        bool isOpen;
+        bool isTimeout;
+        InterfaceID interfaceID;
+        GenericSocketService *service;
+        time_t timeout;
+        RawBuffer rawBuffer;
+        int counter;
+
+        SocketDescription()
+          : isListen(false)
+          , isOpen(false)
+          , isTimeout(false)
+          , interfaceID(-1)
+          , service(NULL)
+        {}
+    };
+
+    SocketDescription& CreateDefaultReadSocketDescription(int sock, bool timeout);
+
+    typedef std::vector<SocketDescription> SocketDescriptionVector;
+
+    struct WriteBuffer {
+        ConnectionID connectionID;
+        RawBuffer rawBuffer;
+    };
+
+    struct Timeout {
+        time_t time;
+        int sock;
+        bool operator<(const Timeout &second) const {
+            return time > second.time; // mininum first!
+        }
+    };
+
+    SocketDescriptionVector m_socketDescriptionVector;
+    fd_set m_readSet;
+    fd_set m_writeSet;
+    int m_maxDesc;
+    bool m_working;
+    std::mutex m_eventQueueMutex;
+    std::queue<WriteBuffer> m_writeBufferQueue;
+    std::queue<ConnectionID> m_closeQueue;
+    int m_notifyMe[2];
+    int m_counter;
+    std::priority_queue<Timeout> m_timeoutQueue;
+};
+
+} // namespace IMAEVMServer
+
+#endif // _IMA_EVM_SERVER_SOCKET_MANAGER_
diff --git a/src/service/service/echo.cpp b/src/service/service/echo.cpp
new file mode 100644 (file)
index 0000000..75939d7
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ *  Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Contact: Bumjin Im <bj.im@samsung.com>
+ *
+ *  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        server-main2.h
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version     1.0
+ * @brief       Implementation of sample service.
+ */
+
+#include <dpl/log/log.h>
+
+#include <protocols.h>
+#include <echo.h>
+
+namespace {
+// Service may open more than one socket.
+// This ID's will be assigned to sockets.
+// This ID's will be used only by service.
+// When new connection arrives, AcceptEvent
+// will be generated with proper ID to inform
+// service about input socket.
+//
+// Please note: SocketManaged does not use it and
+// does not check it in any way.
+//
+// If your service require only one socket
+// (uses only one socet labeled with smack)
+// you may ignore this ID (just pass 0)
+const int SERVICE_SOCKET_ID = 0;
+} // namespace anonymous
+
+namespace IMAEVMServer {
+
+GenericSocketService::ServiceDescriptionVector EchoService::GetServiceDescription() {
+    ServiceDescription sd = {
+        "ima-evm-server::api-echo",
+        SERVICE_SOCKET_ID,
+        SERVICE_SOCKET_ECHO
+    };
+    ServiceDescriptionVector v;
+    v.push_back(sd);
+    return v;
+}
+
+void EchoService::accept(const AcceptEvent &event) {
+    LogDebug("Accept event. ConnectionID: " << event.connectionID.sock
+        << " ServiceID: " << event.interfaceID);
+}
+
+void EchoService::write(const WriteEvent &event) {
+    LogDebug("WriteEvent. ConnectionID: " << event.connectionID.sock <<
+        " Size: " << event.size << " Left: " << event.left);
+    if (event.left == 0)
+        m_serviceManager->Close(event.connectionID);
+}
+
+void EchoService::read(const ReadEvent &event) {
+    LogDebug("ReadEvent. ConnectionID: " << event.connectionID.sock <<
+      " Buffer size: " << event.rawBuffer.size());
+    m_serviceManager->Write(event.connectionID, event.rawBuffer);
+    LogDebug("Write completed");
+}
+
+void EchoService::close(const CloseEvent &event) {
+    LogDebug("CloseEvent. ConnectionID: " << event.connectionID.sock);
+}
+
+void EchoService::error(const ErrorEvent &event) {
+    LogDebug("ErrorEvent. ConnectionID: " << event.connectionID.sock);
+    m_serviceManager->Close(event.connectionID);
+}
+
+} // namespace IMAEVMServer
+
diff --git a/src/service/service/echo.h b/src/service/service/echo.h
new file mode 100644 (file)
index 0000000..f243123
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ *  Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Contact: Bumjin Im <bj.im@samsung.com>
+ *
+ *  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        echo.h
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version     1.0
+ * @brief       Sample service implementation.
+ */
+
+#ifndef _IMA_EVM_SERVER_ECHO_
+#define _IMA_EVM_SERVER_ECHO_
+
+#include <service-thread.h>
+#include <generic-socket-manager.h>
+
+#include <dpl/serialization.h>
+
+#include <socket-buffer.h>
+
+namespace IMAEVMServer {
+
+class EchoService
+  : public IMAEVMServer::GenericSocketService
+  , public IMAEVMServer::ServiceThread<EchoService>
+{
+public:
+    ServiceDescriptionVector GetServiceDescription();
+
+    DECLARE_THREAD_EVENT(AcceptEvent, accept)
+    DECLARE_THREAD_EVENT(WriteEvent, write)
+    DECLARE_THREAD_EVENT(ReadEvent, read)
+    DECLARE_THREAD_EVENT(CloseEvent, close)
+    DECLARE_THREAD_EVENT(ErrorEvent, error)
+
+    void accept(const AcceptEvent &event);
+    void write(const WriteEvent &event);
+    void read(const ReadEvent &event);
+    void close(const CloseEvent &event);
+    void error(const ErrorEvent &event);
+};
+
+} // namespace IMAEVMServer
+
+#endif // _IMA_EVM_SERVER_ECHO_