From: Jan Cybulski Date: Tue, 23 Jun 2015 09:22:20 +0000 (+0200) Subject: Add USB securty daemon (USD) implementation X-Git-Tag: submit/tizen_common/20160317.155115~69 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=c3b28072a81de52620fc3762b8594c2c6815295c;p=platform%2Fcore%2Fapi%2Fusb-host.git Add USB securty daemon (USD) implementation This commit is mostly code dump from security-server upstream repository. Some changes were made like: -change project name to USD -remove unnecassary files, rename files accordingly to new project name -packaging and cmakes adjusting Change-Id: I94de02983ce171508ade2ec126465cb6ccf4a9dc Signed-off-by: Jan Cybulski --- diff --git a/AUTHORS b/AUTHORS index e0f6a1b..ae94397 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,2 +1,2 @@ Stanislaw Wadas - +Jan Cybulski diff --git a/CMakeLists.txt b/CMakeLists.txt index bf77812..1f97b60 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -94,3 +94,6 @@ IF(BUILD_DOC) ) ENDIF(BUILD_DOC) + +ADD_SUBDIRECTORY(USD) +ADD_SUBDIRECTORY(pc) diff --git a/USD/CMakeLists.txt b/USD/CMakeLists.txt new file mode 100644 index 0000000..3935347 --- /dev/null +++ b/USD/CMakeLists.txt @@ -0,0 +1,66 @@ +# 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 CMakeLists.txt +# @author +# @brief +# + +############################# Check minimum CMake version ##################### + +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) +PROJECT("usb-security-daemon") + +############################# cmake packages ################################## + +INCLUDE(FindPkgConfig) + +############################# compiler flags ################################## + +SET(CMAKE_C_FLAGS_PROFILING "-g -O0 -pg -Wp,-U_FORTIFY_SOURCE") +SET(CMAKE_CXX_FLAGS_PROFILING "-g -std=c++0x -O0 -pg -Wp,-U_FORTIFY_SOURCE") +SET(CMAKE_C_FLAGS_DEBUG "-g -O0 -ggdb -Wp,-U_FORTIFY_SOURCE") +SET(CMAKE_CXX_FLAGS_DEBUG "-g -std=c++0x -O0 -ggdb -Wp,-U_FORTIFY_SOURCE") +SET(CMAKE_C_FLAGS_RELEASE "-g -O2") +SET(CMAKE_CXX_FLAGS_RELEASE "-g -std=c++0x -O2") +SET(CMAKE_C_FLAGS_CCOV "-g -O2 --coverage") +SET(CMAKE_CXX_FLAGS_CCOV "-g -std=c++0x -O2 --coverage") + +# If supported for the target machine, emit position-independent code,suitable +# for dynamic linking and avoiding any limit on the size of the global offset +# table. This option makes a difference on the m68k, PowerPC and SPARC. +# (BJ: our ARM too?) +ADD_DEFINITIONS("-fPIC") + +# Set compiler warning flags +ADD_DEFINITIONS("-Werror") # Make all warnings into errors. +ADD_DEFINITIONS("-Wall") # Generate all warnings +ADD_DEFINITIONS("-Wextra") # Generate even more extra warnings + +STRING(REGEX MATCH "([^.]*)" API_VERSION "${VERSION}") +ADD_DEFINITIONS("-DAPI_VERSION=\"$(API_VERSION)\"") + +ADD_DEFINITIONS("-DSMACK_ENABLED") + +IF (CMAKE_BUILD_TYPE MATCHES "DEBUG") + ADD_DEFINITIONS("-DTIZEN_DEBUG_ENABLE") + ADD_DEFINITIONS("-DBUILD_TYPE_DEBUG") +ENDIF (CMAKE_BUILD_TYPE MATCHES "DEBUG") + +SET(TARGET_USD "usd") +SET(TARGET_USD_CLIENT "usd-client") +SET(TARGET_USD_COMMON "usd-commons") + +ADD_SUBDIRECTORY(src) +ADD_SUBDIRECTORY(systemd) diff --git a/USD/src/CMakeLists.txt b/USD/src/CMakeLists.txt new file mode 100644 index 0000000..7857ccb --- /dev/null +++ b/USD/src/CMakeLists.txt @@ -0,0 +1,155 @@ +PKG_CHECK_MODULES(USD_DEP + dlog + openssl + libsmack + libprivilege-control + libsystemd-daemon + REQUIRED + ) + +SET(USD_PATH ${PROJECT_SOURCE_DIR}/src) +SET(SERVER2_PATH ${PROJECT_SOURCE_DIR}/src) + +SET(USD_SOURCES + ${SERVER2_PATH}/main/usd-util.cpp + ${SERVER2_PATH}/main/generic-socket-manager.cpp + ${SERVER2_PATH}/main/socket-manager.cpp + ${SERVER2_PATH}/main/server2-main.cpp + ) + +SET_SOURCE_FILES_PROPERTIES( + ${USD_SOURCES} + PROPERTIES + COMPILE_FLAGS "-D_GNU_SOURCE -fvisibility=hidden") + +INCLUDE_DIRECTORIES(SYSTEM + ${USD_DEP_INCLUDE_DIRS} + ) + +INCLUDE_DIRECTORIES( + ${USD_PATH}/include + ${SERVER2_PATH}/main + ${SERVER2_PATH}/common + ${SERVER2_PATH}/service + ${SERVER2_PATH}/dpl/core/include + ${SERVER2_PATH}/dpl/log/include + ) + +ADD_EXECUTABLE(${TARGET_USD} ${USD_SOURCES}) + +SET_TARGET_PROPERTIES(${TARGET_USD} + PROPERTIES + COMPILE_FLAGS "-pthread" + LINK_FLAGS "-pthread" +) + +TARGET_LINK_LIBRARIES(${TARGET_USD} + ${USD_DEP_LIBRARIES} + ${TARGET_USD_COMMON} + -lcap + ) + +################################################################################ + +SET(USD_CLIENT_VERSION_MAJOR 1) +SET(USD_CLIENT_VERSION ${USD_CLIENT_VERSION_MAJOR}.0.1) + +INCLUDE_DIRECTORIES( + ${SERVER2_PATH}/client + ${SERVER2_PATH}/common + ${SERVER2_PATH}/dpl/core/include + ${SERVER2_PATH}/dpl/log/include + ) + +SET(USD_CLIENT_SOURCES + ${SERVER2_PATH}/client/client-common.cpp + ) + +ADD_LIBRARY(${TARGET_USD_CLIENT} SHARED ${USD_CLIENT_SOURCES}) + +SET_TARGET_PROPERTIES( + ${TARGET_USD_CLIENT} + PROPERTIES + COMPILE_FLAGS "-D_GNU_SOURCE -fPIC -fvisibility=hidden" + SOVERSION ${USD_CLIENT_VERSION_MAJOR} + VERSION ${USD_CLIENT_VERSION} + ) + +TARGET_LINK_LIBRARIES(${TARGET_USD_CLIENT} + ${USD_DEP_LIBRARIES} + ${TARGET_USD_COMMON} + ) + +################################################################################ + +INSTALL(TARGETS ${TARGET_USD_CLIENT} DESTINATION ${LIB_INSTALL_DIR}) + +INSTALL(TARGETS ${TARGET_USD} DESTINATION bin) + +INSTALL(FILES + ${USD_PATH}/include/usb-security-daemon.h + DESTINATION /usr/include/usd + ) + +################################################################################ + +#CONFIGURE_FILE(security-server.pc.in security-server.pc @ONLY) +#INSTALL + +################################################################################ + + +PKG_CHECK_MODULES(COMMON_DEP + dlog + REQUIRED + ) + +SET(COMMON_PATH ${PROJECT_SOURCE_DIR}/src) + +SET(COMMON_SOURCES + ${COMMON_PATH}/common/protocols.cpp + ${COMMON_PATH}/common/message-buffer.cpp + ${COMMON_PATH}/common/smack-check.cpp + ${COMMON_PATH}/dpl/log/src/abstract_log_provider.cpp + ${COMMON_PATH}/dpl/log/src/dlog_log_provider.cpp + ${COMMON_PATH}/dpl/log/src/sd_journal_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(SYSTEM + ${COMMON_DEP_INCLUDE_DIRS} + ) + +INCLUDE_DIRECTORIES( + ${COMMON_PATH}/common + ${COMMON_PATH}/dpl/core/include + ${COMMON_PATH}/dpl/log/include + ) + +ADD_LIBRARY(${TARGET_USD_COMMON} SHARED ${COMMON_SOURCES}) + +SET_TARGET_PROPERTIES( + ${TARGET_USD_COMMON} + PROPERTIES + COMPILE_FLAGS "-D_GNU_SOURCE -fPIC -fvisibility=default" + SOVERSION 1.0.0 + VERSION 1.0.0 + ) + +TARGET_LINK_LIBRARIES(${TARGET_USD_COMMON} + ${COMMON_DEP_LIBRARIES} + ) + +################################################################################ + +INSTALL(TARGETS ${TARGET_USD_COMMON} DESTINATION ${LIB_INSTALL_DIR}) + + diff --git a/USD/src/client/client-common.cpp b/USD/src/client/client-common.cpp new file mode 100644 index 0000000..8d57fd8 --- /dev/null +++ b/USD/src/client/client-common.cpp @@ -0,0 +1,292 @@ +/* + * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Bumjin Im + * + * 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 +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include + +IMPLEMENT_SAFE_SINGLETON(USD::Log::LogSystem); + +namespace { + +const int POLL_TIMEOUT = 2000; + +void securityClientEnableLogSystem(void) { + USD::Singleton::Instance().SetTag("USD_CLIENT"); +} + +int waitForSocket(int sock, int event, int timeout) { + int retval; + pollfd desc[1]; + desc[0].fd = sock; + desc[0].events = event; + + while((-1 == (retval = poll(desc, 1, timeout))) && (errno == EINTR)) { + timeout >>= 1; + errno = 0; + } + + 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 USD_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 USD_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 USD_API_ERROR_NO_SUCH_SERVICE; + } + + 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, POLLOUT, POLL_TIMEOUT)) { + LogError("Error in waitForSocket."); + return USD_API_ERROR_SOCKET; + } + int error = 0; + socklen_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 USD_API_ERROR_SOCKET; + } + + if (error == EACCES) { + LogError("Access denied"); + return USD_API_ERROR_ACCESS_DENIED; + } + + if (error != 0) { + LogError("Error in connect: " << strerror(error)); + return USD_API_ERROR_SOCKET; + } + + return USD_API_SUCCESS; + } + + if (-1 == retval) { + int err = errno; + LogError("Error connecting socket: " << strerror(err)); + if (err == EACCES) + return USD_API_ERROR_ACCESS_DENIED; + if (err == ENOTSOCK) + return USD_API_ERROR_NO_SUCH_SERVICE; + return USD_API_ERROR_SOCKET; + } + + return USD_API_SUCCESS; + } + + int Get() { + return m_sock; + } + +private: + int m_sock; +}; + +} // namespace anonymous + +namespace USD { + + +int sendToServer(char const * const interface, const RawBuffer &send, MessageBuffer &recv) { + int ret; + SockRAII sock; + ssize_t done = 0; + char buffer[2048]; + + if (USD_API_SUCCESS != (ret = sock.Connect(interface))) { + LogError("Error in SockRAII"); + return ret; + } + + while ((send.size() - done) > 0) { + if (0 >= waitForSocket(sock.Get(), POLLOUT, POLL_TIMEOUT)) { + LogError("Error in poll(POLLOUT)"); + return USD_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 USD_API_ERROR_SOCKET; + } + done += temp; + } + + do { + if (0 >= waitForSocket(sock.Get(), POLLIN, POLL_TIMEOUT)) { + LogError("Error in poll(POLLIN)"); + return USD_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 USD_API_ERROR_SOCKET; + } + + if (0 == temp) { + LogError("Read return 0/Connection closed by server(?)"); + return USD_API_ERROR_SOCKET; + } + + RawBuffer raw(buffer, buffer+temp); + recv.Push(raw); + } while(!recv.Ready()); + return USD_API_SUCCESS; +} + +int sendToServerAncData(char const * const interface, const RawBuffer &send, struct msghdr &hdr) { + int ret; + SockRAII sock; + ssize_t done = 0; + + if (USD_API_SUCCESS != (ret = sock.Connect(interface))) { + LogError("Error in SockRAII"); + return ret; + } + + while ((send.size() - done) > 0) { + if (0 >= waitForSocket(sock.Get(), POLLOUT, POLL_TIMEOUT)) { + LogError("Error in poll(POLLOUT)"); + return USD_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 USD_API_ERROR_SOCKET; + } + done += temp; + } + + if (0 >= waitForSocket(sock.Get(), POLLIN, POLL_TIMEOUT)) { + LogError("Error in poll(POLLIN)"); + return USD_API_ERROR_SOCKET; + } + + ssize_t temp = TEMP_FAILURE_RETRY(recvmsg(sock.Get(), &hdr, MSG_CMSG_CLOEXEC)); + + if (temp < 0) { + int err = errno; + LogError("Error in recvmsg(): " << strerror(err) << " errno: " << err); + return USD_API_ERROR_SOCKET; + } + + if (0 == temp) { + LogError("Read return 0/Connection closed by server(?)"); + return USD_API_ERROR_SOCKET; + } + + return USD_API_SUCCESS; +} + +int try_catch(const std::function& func) +{ + try { + return func(); + } catch (MessageBuffer::Exception::Base &e) { + LogError("USD::MessageBuffer::Exception " << e.DumpToString()); + } catch (std::exception &e) { + LogError("STD exception " << e.what()); + } catch (...) { + LogError("Unknown exception occured"); + } + return USD_API_ERROR_UNKNOWN; +} + +} // namespace USD + +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/USD/src/client/client-common.h b/USD/src/client/client-common.h new file mode 100644 index 0000000..4094c7a --- /dev/null +++ b/USD/src/client/client-common.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Bumjin Im + * + * 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 USD. + */ + +#ifndef _USD_CLIENT_ +#define _USD_CLIENT_ + +#include +#include + +#include + +#define _USD_API_ __attribute__((visibility("default"))) +#define _USD_UNUSED_ __attribute__((unused)) + +extern "C" { + struct msghdr; +} + +namespace USD { + +typedef std::vector RawBuffer; + +int sendToServer(char const * const interface, const RawBuffer &send, MessageBuffer &recv); + +/* + * sendToServerAncData is special case when we want to receive file descriptor + * passed by USD on behalf of calling process. We can't get it with + * MessageBuffer. + * + * This function should be called _ONLY_ in this particular case. + * + */ +int sendToServerAncData(char const * const interface, const RawBuffer &send, struct msghdr &hdr); + +/* + * Decorator function that performs frequently repeated exception handling in + * SS client API functions. Accepts lambda expression as an argument. + */ +int try_catch(const std::function& func); + +} // namespace USD + +#endif // _USD_CLIENT_ diff --git a/USD/src/common/connection-info.h b/USD/src/common/connection-info.h new file mode 100644 index 0000000..8490493 --- /dev/null +++ b/USD/src/common/connection-info.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Bumjin Im + * + * 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 connection-info.h + * @author Lukasz Kostyra (l.kostyra@partner.samsung.com) + * @version 1.0 + * @brief Definition of ConnectionInfo structure and ConnectionInfoMap type. + */ + +#ifndef _CONNECTION_INFO_H_ +#define _CONNECTION_INFO_H_ + +#include +#include +#include + +namespace USD +{ + struct ConnectionInfo { + InterfaceID interfaceID; + MessageBuffer buffer; + }; + + typedef std::map ConnectionInfoMap; +} //namespace USD + +#endif //_CONNECTION_INFO_H_ diff --git a/USD/src/common/message-buffer.cpp b/USD/src/common/message-buffer.cpp new file mode 100644 index 0000000..da2bffc --- /dev/null +++ b/USD/src/common/message-buffer.cpp @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Bumjin Im + * + * 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 message-buffer.cpp + * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com) + * @version 1.0 + * @brief Implementation of MessageBuffer. + */ + +#include + +#include + +namespace USD { + +void MessageBuffer::Push(const RawBuffer &data) { + m_buffer.AppendCopy(&data[0], data.size()); +} + +RawBuffer MessageBuffer::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 MessageBuffer::Ready() { + CountBytesLeft(); + if (m_bytesLeft == 0) + return false; + if (m_bytesLeft > m_buffer.Size()) + return false; + return true; +} + +void MessageBuffer::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 MessageBuffer::Write(size_t num, const void *bytes) { + m_buffer.AppendCopy(bytes, num); +} + +} // namespace USD + diff --git a/USD/src/common/message-buffer.h b/USD/src/common/message-buffer.h new file mode 100644 index 0000000..b7fc94e --- /dev/null +++ b/USD/src/common/message-buffer.h @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Bumjin Im + * + * 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 MessageBuffer. + */ + +#ifndef _USD_SOCKET_BUFFER_ +#define _USD_SOCKET_BUFFER_ + +#include + +#include +#include +#include + +namespace USD { + +typedef std::vector RawBuffer; + +class MessageBuffer : public USD::IStream { +public: + class Exception + { + public: + DECLARE_EXCEPTION_TYPE(USD::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, OutOfData) + }; + + MessageBuffer() + : 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; + USD::BinaryQueue m_buffer; +}; + +} // namespace USD + +#endif // _USD_SOCKET_BUFFER_ diff --git a/USD/src/common/protocols.cpp b/USD/src/common/protocols.cpp new file mode 100644 index 0000000..09b420c --- /dev/null +++ b/USD/src/common/protocols.cpp @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Bumjin Im + * + * 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 USD. + */ + +#include +#include + + +namespace USD { + +#define SOCKET_PATH_PREFIX "/run/" +#define SOCKET_PATH_PREFIX_USD SOCKET_PATH_PREFIX "usd/" + +char const * const SERVICE_SOCKET_USB_ACCESS = + SOCKET_PATH_PREFIX_USD "usd-api-usb-access.socket"; + +} // namespace USD + diff --git a/USD/src/common/protocols.h b/USD/src/common/protocols.h new file mode 100644 index 0000000..f106598 --- /dev/null +++ b/USD/src/common/protocols.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Bumjin Im + * + * 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 USD. + */ + +#ifndef _USD_PROTOCOLS_ +#define _USD_PROTOCOLS_ + + +namespace USD { + +extern char const * const SERVICE_SOCKET_USB_ACCESS; + + + +enum class UsbAccessCall +{ + USB_CALL_TYPE_OPEN, + USB_CALL_TYPE_SETUP_POLICY +}; + +} // namespace USD + +#endif // _USD_PROTOCOLS_ + diff --git a/USD/src/common/smack-check.cpp b/USD/src/common/smack-check.cpp new file mode 100644 index 0000000..a68fb38 --- /dev/null +++ b/USD/src/common/smack-check.cpp @@ -0,0 +1,34 @@ +#include + +#include +#include + +#include + +namespace USD { + +int smack_runtime_check(void) +{ + static int smack_present = -1; + if (-1 == smack_present) { + if (NULL == smack_smackfs_path()) { + LogDebug("no smack found on device"); + smack_present = 0; + } else { + LogDebug("found smack on device"); + smack_present = 1; + } + } + return smack_present; +} + +int smack_check(void) +{ +#ifndef SMACK_ENABLED + return 0; +#else + return smack_runtime_check(); +#endif +} + +} // namespace USD diff --git a/USD/src/common/smack-check.h b/USD/src/common/smack-check.h new file mode 100644 index 0000000..5094844 --- /dev/null +++ b/USD/src/common/smack-check.h @@ -0,0 +1,42 @@ +/* + * USB security daemon + * + * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Bumjin Im + * + * 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 _SMACK_CHECK_H_ +#define _SMACK_CHECK_H_ + +namespace USD { + +/* + * A very simple runtime check for SMACK on the platform + * Returns 1 if SMACK is present, 0 otherwise + */ + +int smack_runtime_check(void); + +/* + * A very simple runtime check for SMACK on the platform + * Returns 1 if SMACK is present, 0 otherwise. If SMACK_ENABLED is not defined + * It returns 0. + */ +int smack_check(void); + +} // namespace USD + +#endif // _SMACK_CHECK_H_ diff --git a/USD/src/dpl/core/include/dpl/assert.h b/USD/src/dpl/core/include/dpl/assert.h new file mode 100644 index 0000000..53707d6 --- /dev/null +++ b/USD/src/dpl/core/include/dpl/assert.h @@ -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 USD_ASSERT_H +#define USD_ASSERT_H + +#include + +namespace USD { +// Assertion handler procedure +// Do not call directly +// Always use Assert macro +USD_NORETURN void AssertProc(const char *condition, + const char *file, + int line, + const char *function); +} // namespace USD + +#define Assert(Condition) do { if (!(Condition)) { USD::AssertProc(#Condition, \ + __FILE__, \ + __LINE__, \ + __FUNCTION__); \ + } } while (0) + +#endif // USD_ASSERT_H diff --git a/USD/src/dpl/core/include/dpl/binary_queue.h b/USD/src/dpl/core/include/dpl/binary_queue.h new file mode 100644 index 0000000..8447d4d --- /dev/null +++ b/USD/src/dpl/core/include/dpl/binary_queue.h @@ -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 USD_BINARY_QUEUE_H +#define USD_BINARY_QUEUE_H + +//#include +#include +#include +#include +#include + +namespace USD { +/** + * Binary queue auto pointer + */ +class BinaryQueue; +typedef std::auto_ptr 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(USD::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 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 USD + +#endif // USD_BINARY_QUEUE_H diff --git a/USD/src/dpl/core/include/dpl/colors.h b/USD/src/dpl/core/include/dpl/colors.h new file mode 100644 index 0000000..9fb30a2 --- /dev/null +++ b/USD/src/dpl/core/include/dpl/colors.h @@ -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 USD_COLORS_H +#define USD_COLORS_H + +namespace USD { +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 USD + +#endif /* USD_COLORS_H */ diff --git a/USD/src/dpl/core/include/dpl/exception.h b/USD/src/dpl/core/include/dpl/exception.h new file mode 100644 index 0000000..d76f989 --- /dev/null +++ b/USD/src/dpl/core/include/dpl/exception.h @@ -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 USD_EXCEPTION_H +#define USD_EXCEPTION_H + +#include +#include +#include +#include +#include +#include + +namespace USD { +void LogUnhandledException(const std::string &str); +void LogUnhandledException(const std::string &str, + const char *filename, + int line, + const char *function); +} + +namespace USD { +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 USD 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-USD 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() ? "" : 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() ? "" : 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 USD + +#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 USD::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 USD::Exception &exception) \ + { \ + std::ostringstream msg; \ + msg << USD::Exception::KnownExceptionToString(exception); \ + USD::LogUnhandledException(msg.str(), __FILE__, __LINE__, __FUNCTION__); \ + abort(); \ + } \ + catch (std::exception& e) \ + { \ + std::ostringstream msg; \ + msg << e.what(); \ + msg << "\n"; \ + msg << USD::Exception::UnknownExceptionToString(); \ + USD::LogUnhandledException(msg.str(), __FILE__, __LINE__, __FUNCTION__); \ + abort(); \ + } \ + catch (...) \ + { \ + std::ostringstream msg; \ + msg << USD::Exception::UnknownExceptionToString(); \ + USD::LogUnhandledException(msg.str(), __FILE__, __LINE__, __FUNCTION__); \ + abort(); \ + } + +namespace USD { +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 // USD_EXCEPTION_H diff --git a/USD/src/dpl/core/include/dpl/fstream_accessors.h b/USD/src/dpl/core/include/dpl/fstream_accessors.h new file mode 100644 index 0000000..e8c4310 --- /dev/null +++ b/USD/src/dpl/core/include/dpl/fstream_accessors.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Bumjin Im + * + * 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 fstream-helper.h + * @author Marek Smolinski (m.smolinski@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of fstream-helper + * + */ + +#ifndef USD_FSTREAM_ACCESSORS_H +#define USD_FSTREAM_ACCESSORS_H + +namespace DPL { + +/* + * Bypass lack of public member function to get file + * descriptor from fstream objects in std + * This feature is needed for flushing data from kernel space buffer to + * physical device [fsync(int fd) - syscall] on opened fstream object +*/ + +template +class FstreamAccessors : T::__filebuf_type { + typedef FstreamAccessors MyType; +public: + static int GetFd(T &strm) { + return static_cast(strm.rdbuf())->_M_file.fd(); + } +}; + +} // namespace DPL + +#endif // USD_FSTREAM_ACCESSORS_H diff --git a/USD/src/dpl/core/include/dpl/noncopyable.h b/USD/src/dpl/core/include/dpl/noncopyable.h new file mode 100644 index 0000000..32ef1f4 --- /dev/null +++ b/USD/src/dpl/core/include/dpl/noncopyable.h @@ -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 USD_NONCOPYABLE_H +#define USD_NONCOPYABLE_H + +namespace USD { +class Noncopyable +{ + private: + Noncopyable(const Noncopyable &); + const Noncopyable &operator=(const Noncopyable &); + + public: + Noncopyable(); + virtual ~Noncopyable(); +}; +} // namespace USD + +#endif // USD_NONCOPYABLE_H diff --git a/USD/src/dpl/core/include/dpl/noreturn.h b/USD/src/dpl/core/include/dpl/noreturn.h new file mode 100644 index 0000000..675e33f --- /dev/null +++ b/USD/src/dpl/core/include/dpl/noreturn.h @@ -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 USD_NORETURN_H +#define USD_NORETURN_H + +#define USD_NORETURN __attribute__((__noreturn__)) + +#endif // USD_NORETURN_H diff --git a/USD/src/dpl/core/include/dpl/serialization.h b/USD/src/dpl/core/include/dpl/serialization.h new file mode 100644 index 0000000..e39997d --- /dev/null +++ b/USD/src/dpl/core/include/dpl/serialization.h @@ -0,0 +1,398 @@ +/* + * 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 +#include +#include +#include +#include + +namespace USD { +// 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); + } + + // char + static void Serialize(IStream& stream, const char value) + { + stream.Write(sizeof(value), &value); + } + static void Serialize(IStream& stream, const char* const value) + { + stream.Write(sizeof(*value), value); + } + + // unsigned char + static void Serialize(IStream& stream, const unsigned char value) + { + stream.Write(sizeof(value), &value); + } + static void Serialize(IStream& stream, const unsigned char* const value) + { + stream.Write(sizeof(*value), value); + } + + // 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); + } + + // time_t + static void Serialize(IStream& stream, const time_t value) + { + stream.Write(sizeof(value), &value); + } + static void Serialize(IStream& stream, const time_t* 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 + static void Serialize(IStream& stream, const std::list& list) + { + int length = list.size(); + stream.Write(sizeof(length), &length); + for (typename std::list::const_iterator list_iter = list.begin(); + list_iter != list.end(); list_iter++) + { + Serialize(stream, *list_iter); + } + } + template + static void Serialize(IStream& stream, const std::list* const list) + { + Serialize(stream, *list); + } + + // std::vector + template + static void Serialize(IStream& stream, const std::vector& vec) + { + int length = vec.size(); + stream.Write(sizeof(length), &length); + for (typename std::vector::const_iterator vec_iter = vec.begin(); + vec_iter != vec.end(); vec_iter++) + { + Serialize(stream, *vec_iter); + } + } + template + static void Serialize(IStream& stream, const std::vector* const vec) + { + Serialize(stream, *vec); + } + + // std::pair + template + static void Serialize(IStream& stream, const std::pair& p) + { + Serialize(stream, p.first); + Serialize(stream, p.second); + } + template + static void Serialize(IStream& stream, const std::pair* const p) + { + Serialize(stream, *p); + } + + // std::map + template + static void Serialize(IStream& stream, const std::map& map) + { + int length = map.size(); + stream.Write(sizeof(length), &length); + typename std::map::const_iterator it; + for (it = map.begin(); it != map.end(); ++it) { + Serialize(stream, (*it).first); + Serialize(stream, (*it).second); + } + } + template + static void Serialize(IStream& stream, const std::map* const map) + { + Serialize(stream, *map); + } + + // std::unique_ptr + template + static void Serialize(IStream& stream, const std::unique_ptr& p) + { + Serialize(stream, *p); + } +}; // struct Serialization + +struct Deserialization { + // deserialization + // normal functions + + // ISerializable objects + // T instead of ISerializable is needed to call proper constructor + template + static void Deserialize(IStream& stream, T& object) + { + object = T(stream); + } + template + static void Deserialize(IStream& stream, T*& object) + { + object = new T(stream); + } + + // char + static void Deserialize(IStream& stream, char& value) + { + stream.Read(sizeof(value), &value); + } + static void Deserialize(IStream& stream, char*& value) + { + value = new char; + stream.Read(sizeof(*value), value); + } + + // unsigned char + static void Deserialize(IStream& stream, unsigned char& value) + { + stream.Read(sizeof(value), &value); + } + static void Deserialize(IStream& stream, unsigned char*& value) + { + value = new unsigned char; + stream.Read(sizeof(*value), value); + } + + // 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); + } + + // time_t + static void Deserialize(IStream& stream, time_t& value) + { + stream.Read(sizeof(value), &value); + } + static void Deserialize(IStream& stream, time_t*& value) + { + value = new time_t; + 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 + static void Deserialize(IStream& stream, std::list& list) + { + int length; + stream.Read(sizeof(length), &length); + for (int i = 0; i < length; ++i) { + T obj; + Deserialize(stream, obj); + list.push_back(std::move(obj)); + } + } + template + static void Deserialize(IStream& stream, std::list*& list) + { + list = new std::list; + Deserialize(stream, *list); + } + + // std::vector + template + static void Deserialize(IStream& stream, std::vector& vec) + { + int length; + stream.Read(sizeof(length), &length); + for (int i = 0; i < length; ++i) { + T obj; + Deserialize(stream, obj); + vec.push_back(std::move(obj)); + } + } + template + static void Deserialize(IStream& stream, std::vector*& vec) + { + vec = new std::vector; + Deserialize(stream, *vec); + } + + // std::pair + template + static void Deserialize(IStream& stream, std::pair& p) + { + Deserialize(stream, p.first); + Deserialize(stream, p.second); + } + template + static void Deserialize(IStream& stream, std::pair*& p) + { + p = new std::pair; + Deserialize(stream, *p); + } + + // std::map + template + static void Deserialize(IStream& stream, std::map& 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] = std::move(obj); + } + } + template + static void Deserialize(IStream& stream, std::map*& map) + { + map = new std::map; + Deserialize(stream, *map); + } +}; // struct Deserialization +} // namespace USD + +#endif // SERIALIZATION_H diff --git a/USD/src/dpl/core/include/dpl/singleton.h b/USD/src/dpl/core/include/dpl/singleton.h new file mode 100644 index 0000000..c2de5af --- /dev/null +++ b/USD/src/dpl/core/include/dpl/singleton.h @@ -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 USD_SINGLETON_H +#define USD_SINGLETON_H + +namespace USD { +template +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 USD + +#endif // USD_SINGLETON_H diff --git a/USD/src/dpl/core/include/dpl/singleton_impl.h b/USD/src/dpl/core/include/dpl/singleton_impl.h new file mode 100644 index 0000000..3347d5c --- /dev/null +++ b/USD/src/dpl/core/include/dpl/singleton_impl.h @@ -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 USD_SINGLETON_IMPL_H +#define USD_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 USD { +template +Singleton& Singleton::InternalInstance() +{ + static Singleton instance; + return instance; +} + +template +Class &Singleton::Instance() +{ + Singleton& instance = Singleton::InternalInstance(); + return instance; +} +} // namespace USD + +#define IMPLEMENT_SINGLETON(Type) \ + template USD::Singleton&USD::Singleton::InternalInstance(); \ + template Type & USD::Singleton::Instance(); \ + +#endif // USD_SINGLETON_IMPL_H diff --git a/USD/src/dpl/core/include/dpl/singleton_safe_impl.h b/USD/src/dpl/core/include/dpl/singleton_safe_impl.h new file mode 100644 index 0000000..4e80096 --- /dev/null +++ b/USD/src/dpl/core/include/dpl/singleton_safe_impl.h @@ -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 USD_SINGLETON_SAFE_IMPL_H +#define USD_SINGLETON_SAFE_IMPL_H + +#define IMPLEMENT_SAFE_SINGLETON(Class) \ + namespace USD { \ + template<> \ + Singleton&Singleton::InternalInstance() \ + { \ + static Singleton instance; \ + return instance; \ + } \ + \ + template<> \ + Class & Singleton::Instance() \ + { \ + Singleton& instance = Singleton::InternalInstance(); \ + return instance; \ + } \ + \ + template Singleton&Singleton::InternalInstance(); \ + template Class & Singleton::Instance(); \ + } // namespace USD + +#endif // USD_SINGLETON_SAFE_IMPL_H diff --git a/USD/src/dpl/core/src/assert.cpp b/USD/src/dpl/core/src/assert.cpp new file mode 100644 index 0000000..5661fc7 --- /dev/null +++ b/USD/src/dpl/core/src/assert.cpp @@ -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 +#include +#include +#include +#include +#include + +namespace USD { +void AssertProc(const char *condition, + const char *file, + int line, + const char *function) +{ +#define INTERNAL_LOG(message) \ + do \ + { \ + std::ostringstream platformLog; \ + platformLog << message; \ + USD::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( + "### USD 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 USD diff --git a/USD/src/dpl/core/src/binary_queue.cpp b/USD/src/dpl/core/src/binary_queue.cpp new file mode 100644 index 0000000..6bac603 --- /dev/null +++ b/USD/src/dpl/core/src/binary_queue.cpp @@ -0,0 +1,317 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include + +namespace USD { +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 + Bucket *bucket = new Bucket(buffer, bufferSize, deleter, userParam); + try { + m_buckets.push_back(bucket); + } catch (const std::bad_alloc &) { + delete bucket; + throw; + } + + // 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(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(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(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> + 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 USD diff --git a/USD/src/dpl/core/src/colors.cpp b/USD/src/dpl/core/src/colors.cpp new file mode 100644 index 0000000..5791c05 --- /dev/null +++ b/USD/src/dpl/core/src/colors.cpp @@ -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 +#include + +namespace USD { +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 = ""; +const char* BOLD_GREEN_END = ""; +const char* PURPLE_BEGIN = ""; +const char* PURPLE_END = ""; +const char* RED_BEGIN = ""; +const char* RED_END = ""; +const char* GREEN_BEGIN = ""; +const char* GREEN_END = ""; +const char* CYAN_BEGIN = ""; +const char* CYAN_END = ""; +const char* BOLD_RED_BEGIN = ""; +const char* BOLD_RED_END = ""; +const char* BOLD_YELLOW_BEGIN = ""; +const char* BOLD_YELLOW_END = ""; +const char* BOLD_GOLD_BEGIN = ""; +const char* BOLD_GOLD_END = ""; +const char* BOLD_WHITE_BEGIN = ""; +const char* BOLD_WHITE_END = ""; +} //namespace Html +} //namespace Colors +} //namespace USD diff --git a/USD/src/dpl/core/src/exception.cpp b/USD/src/dpl/core/src/exception.cpp new file mode 100644 index 0000000..e6f685f --- /dev/null +++ b/USD/src/dpl/core/src/exception.cpp @@ -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 +#include +#include +#include + +namespace USD { +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 + USD::Log::LogSystemSingleton::Instance().Error( + str.c_str(), filename, line, function); +} +} // namespace USD diff --git a/USD/src/dpl/core/src/noncopyable.cpp b/USD/src/dpl/core/src/noncopyable.cpp new file mode 100644 index 0000000..b0ae533 --- /dev/null +++ b/USD/src/dpl/core/src/noncopyable.cpp @@ -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 +#include + +namespace USD { +Noncopyable::Noncopyable() +{} + +Noncopyable::~Noncopyable() +{} +} // namespace USD diff --git a/USD/src/dpl/core/src/serialization.cpp b/USD/src/dpl/core/src/serialization.cpp new file mode 100644 index 0000000..f8f05ff --- /dev/null +++ b/USD/src/dpl/core/src/serialization.cpp @@ -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 +#include + +// +// Note: +// +// The file here is left blank to enable precompilation +// of templates in corresponding header file. +// Do not remove this file. +// diff --git a/USD/src/dpl/core/src/singleton.cpp b/USD/src/dpl/core/src/singleton.cpp new file mode 100644 index 0000000..a76e8ac --- /dev/null +++ b/USD/src/dpl/core/src/singleton.cpp @@ -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 +#include + +// +// Note: +// +// The file here is left blank to enable precompilation +// of templates in corresponding header file. +// Do not remove this file. +// diff --git a/USD/src/dpl/log/include/dpl/log/abstract_log_provider.h b/USD/src/dpl/log/include/dpl/log/abstract_log_provider.h new file mode 100644 index 0000000..d4802d1 --- /dev/null +++ b/USD/src/dpl/log/include/dpl/log/abstract_log_provider.h @@ -0,0 +1,61 @@ +/* + * 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 USD_ABSTRACT_LOG_PROVIDER_H +#define USD_ABSTRACT_LOG_PROVIDER_H + +namespace USD { +namespace Log { +class AbstractLogProvider +{ + public: + virtual ~AbstractLogProvider() {} + + virtual void SetTag(const char *tag); + + 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 USD + +#endif // USD_ABSTRACT_LOG_PROVIDER_H diff --git a/USD/src/dpl/log/include/dpl/log/dlog_log_provider.h b/USD/src/dpl/log/include/dpl/log/dlog_log_provider.h new file mode 100644 index 0000000..f657e24 --- /dev/null +++ b/USD/src/dpl/log/include/dpl/log/dlog_log_provider.h @@ -0,0 +1,94 @@ +/* + * 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 USD_DLOG_LOG_PROVIDER_H +#define USD_DLOG_LOG_PROVIDER_H + +#include +#include +#include + +namespace USD { +namespace Log { +class DLOGLogProvider : + public AbstractLogProvider +{ + private: + std::unique_ptr 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); + virtual void SecureDebug(const char *message, + const char *fileName, + int line, + const char *function); + virtual void SecureInfo(const char *message, + const char *fileName, + int line, + const char *function); + virtual void SecureWarning(const char *message, + const char *fileName, + int line, + const char *function); + virtual void SecureError(const char *message, + const char *fileName, + int line, + const char *function); + virtual void SmackAudit(const char *message, + const char *fileName, + int line, + const char *function); + + // Set global Tag according to DLOG + void SetTag(const char *tag); +}; + +} // namespace Log +} // namespace USD + +#endif // USD_DLOG_LOG_PROVIDER_H diff --git a/USD/src/dpl/log/include/dpl/log/log.h b/USD/src/dpl/log/include/dpl/log/log.h new file mode 100644 index 0000000..e7f93b1 --- /dev/null +++ b/USD/src/dpl/log/include/dpl/log/log.h @@ -0,0 +1,176 @@ +/* + * 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 USD_LOG_H +#define USD_LOG_H + +#include +#include +#include +#include +#include + +namespace USD { +namespace Log { +/** + * USD 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 AbstractLogProviderPtrList; + AbstractLogProviderPtrList m_providers; + + 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 + NullStream& operator<<(const T&) + { + return *this; + } +}; + +/** + * Log system singleton + */ +typedef Singleton LogSystemSingleton; +} +} // namespace USD + +// +// Log support +// +// + +/* avoid warnings about unused variables */ +#define DPL_MACRO_DUMMY_LOGGING(message, function) \ + do { \ + USD::Log::NullStream ns; \ + ns << message; \ + } while (0) + +#define DPL_MACRO_FOR_LOGGING(message, function) \ +do \ +{ \ + if (USD::Log::LogSystemSingleton::Instance().IsLoggingEnabled()) \ + { \ + std::ostringstream platformLog; \ + platformLog << message; \ + USD::Log::LogSystemSingleton::Instance().function( \ + platformLog.str().c_str(), \ + __FILE__, __LINE__, __FUNCTION__); \ + } \ +} while (0) + +/* Errors must be always logged. */ +#define LogError(message) DPL_MACRO_FOR_LOGGING(message, Error) +#define LogSecureError(message) DPL_MACRO_FOR_LOGGING(message, SecureError) + +#define LogSmackAudit(message) DPL_MACRO_FOR_LOGGING(message, SmackAudit) + +#ifdef BUILD_TYPE_DEBUG + #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 LogPedantic(message) DPL_MACRO_FOR_LOGGING(message, Pedantic) +#else + #define LogDebug(message) DPL_MACRO_DUMMY_LOGGING(message, Debug) + #define LogInfo(message) DPL_MACRO_DUMMY_LOGGING(message, Info) + #define LogWarning(message) DPL_MACRO_DUMMY_LOGGING(message, Warning) + #define LogPedantic(message) DPL_MACRO_DUMMY_LOGGING(message, Pedantic) +#endif // BUILD_TYPE_DEBUG + +#endif // USD_LOG_H diff --git a/USD/src/dpl/log/include/dpl/log/old_style_log_provider.h b/USD/src/dpl/log/include/dpl/log/old_style_log_provider.h new file mode 100644 index 0000000..042dae1 --- /dev/null +++ b/USD/src/dpl/log/include/dpl/log/old_style_log_provider.h @@ -0,0 +1,104 @@ +/* + * 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 USD_OLD_STYLE_LOG_PROVIDER_H +#define USD_OLD_STYLE_LOG_PROVIDER_H + +#include +#include + +namespace USD { +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); + virtual void SecureDebug(const char *message, + const char *fileName, + int line, + const char *function); + virtual void SecureInfo(const char *message, + const char *fileName, + int line, + const char *function); + virtual void SecureWarning(const char *message, + const char *fileName, + int line, + const char *function); + virtual void SecureError(const char *message, + const char *fileName, + int line, + const char *function); + virtual void SmackAudit(const char *message, + const char *fileName, + int line, + const char *function); +}; +} +} // namespace USD + +#endif // USD_OLD_STYLE_LOG_PROVIDER_H diff --git a/USD/src/dpl/log/include/dpl/log/sd_journal_provider.h b/USD/src/dpl/log/include/dpl/log/sd_journal_provider.h new file mode 100644 index 0000000..d3503ed --- /dev/null +++ b/USD/src/dpl/log/include/dpl/log/sd_journal_provider.h @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2014 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 sd_journal_provider.h + * @author Marcin Lis (m.lis@samsung.com) + * @version 1.0 + * @brief This file contains the implementation of systemd journal log provider + */ + +#ifndef USD_SD_JOURNAL_PROVIDER_H +#define USD_SD_JOURNAL_PROVIDER_H + +#include +#include +#include + +namespace USD { +namespace Log { +class SdJournalProvider : + public AbstractLogProvider +{ + private: + std::string m_tag; + + static std::string FormatMessage(const char *message, + const char *filename, + int line, + const char *function); + + public: + SdJournalProvider(); + virtual ~SdJournalProvider(); + + 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); + + // All Pedantic logs are translated to Debug + virtual void Pedantic(const char *message, + const char *fileName, + int line, + const char *function); + virtual void SecureDebug(const char *message, + const char *fileName, + int line, + const char *function); + virtual void SecureInfo(const char *message, + const char *fileName, + int line, + const char *function); + virtual void SecureWarning(const char *message, + const char *fileName, + int line, + const char *function); + virtual void SecureError(const char *message, + const char *fileName, + int line, + const char *function); + virtual void SmackAudit(const char *message, + const char *fileName, + int line, + const char *function); + + // Set global Tag for all USD Logs + void SetTag(const char *tag); + +}; // class SdJournalProvider + +} // namespace Log +} // namespace USD + +#endif // USD_SD_JOURNAL_PROVIDER_H diff --git a/USD/src/dpl/log/src/abstract_log_provider.cpp b/USD/src/dpl/log/src/abstract_log_provider.cpp new file mode 100644 index 0000000..5221ed8 --- /dev/null +++ b/USD/src/dpl/log/src/abstract_log_provider.cpp @@ -0,0 +1,39 @@ +/* + * 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 +#include +#include + +#define UNUSED __attribute__((unused)) + +namespace USD { +namespace Log { + +void AbstractLogProvider::SetTag(const char *tag UNUSED) {} + +const char *AbstractLogProvider::LocateSourceFileName(const char *filename) +{ + const char *ptr = strrchr(filename, '/'); + return ptr != NULL ? ptr + 1 : filename; +} +} +} diff --git a/USD/src/dpl/log/src/dlog_log_provider.cpp b/USD/src/dpl/log/src/dlog_log_provider.cpp new file mode 100644 index 0000000..78a3e52 --- /dev/null +++ b/USD/src/dpl/log/src/dlog_log_provider.cpp @@ -0,0 +1,152 @@ +/* + * 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 +#include +#include +#include +#include + +#define UNUSED __attribute__((unused)) + +namespace USD { +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) +{ + SLOG(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) +{ + SLOG(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) +{ + SLOG(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) +{ + SLOG(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) +{ + SLOG(LOG_DEBUG, "USD", "%s", FormatMessage(message, + filename, + line, + function).c_str()); +} + +void DLOGLogProvider::SecureDebug(const char *message UNUSED, + const char *filename UNUSED, + int line UNUSED, + const char *function UNUSED) +{ + SECURE_SLOG(LOG_DEBUG, m_tag.get(), "%s", + FormatMessage(message, filename, line, function).c_str()); +} + +void DLOGLogProvider::SecureInfo(const char *message UNUSED, + const char *filename UNUSED, + int line UNUSED, + const char *function UNUSED) +{ + SECURE_SLOG(LOG_INFO, m_tag.get(), "%s", + FormatMessage(message, filename, line, function).c_str()); +} + +void DLOGLogProvider::SecureWarning(const char *message UNUSED, + const char *filename UNUSED, + int line UNUSED, + const char *function UNUSED) +{ + SECURE_SLOG(LOG_WARN, m_tag.get(), "%s", + FormatMessage(message, filename, line, function).c_str()); +} + +void DLOGLogProvider::SecureError(const char *message UNUSED, + const char *filename UNUSED, + int line UNUSED, + const char *function UNUSED) +{ + SECURE_SLOG(LOG_ERROR, m_tag.get(), "%s", + FormatMessage(message, filename, line, function).c_str()); +} + +void DLOGLogProvider::SmackAudit(const char *message UNUSED, + const char *filename UNUSED, + int line UNUSED, + const char *function UNUSED) +{ +} + +} // nemespace Log +} // namespace USD diff --git a/USD/src/dpl/log/src/log.cpp b/USD/src/dpl/log/src/log.cpp new file mode 100644 index 0000000..2a9fadd --- /dev/null +++ b/USD/src/dpl/log/src/log.cpp @@ -0,0 +1,231 @@ +/* + * 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 +#include + +#include +#include +#include +#include +#include + +IMPLEMENT_SINGLETON(USD::Log::LogSystem) + +namespace USD { +namespace Log { +namespace // anonymous +{ +#ifdef BUILD_TYPE_DEBUG +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"; +#endif // BUILD_TYPE_DEBUG +const char *USD_LOG_OFF = "DPL_LOG_OFF"; +} // namespace anonymous + +bool LogSystem::IsLoggingEnabled() const +{ + return m_isLoggingEnabled; +} + +LogSystem::LogSystem() : + m_isLoggingEnabled(!getenv(USD_LOG_OFF)) +{ +#ifdef BUILD_TYPE_DEBUG + 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 + AddProvider(new OldStyleLogProvider(oldStyleDebugLogs, + oldStyleInfoLogs, + oldStyleWarningLogs, + oldStyleErrorLogs, + oldStylePedanticLogs)); + } else { + // DLOG + AddProvider(new DLOGLogProvider()); + AddProvider(new SdJournalProvider()); + } +#else // BUILD_TYPE_DEBUG + AddProvider(new DLOGLogProvider()); + AddProvider(new SdJournalProvider()); +#endif // BUILD_TYPE_DEBUG +} + +LogSystem::~LogSystem() +{ + // Delete all providers + for (AbstractLogProviderPtrList::iterator iterator = m_providers.begin(); + iterator != m_providers.end(); + ++iterator) + { + delete *iterator; + } + + m_providers.clear(); +} + +void LogSystem::SetTag(const char* tag) +{ + for (AbstractLogProviderPtrList::iterator iterator = m_providers.begin(); + iterator != m_providers.end(); + ++iterator) + { + (*iterator)->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 USD diff --git a/USD/src/dpl/log/src/old_style_log_provider.cpp b/USD/src/dpl/log/src/old_style_log_provider.cpp new file mode 100644 index 0000000..1efed24 --- /dev/null +++ b/USD/src/dpl/log/src/old_style_log_provider.cpp @@ -0,0 +1,313 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include +#include + +namespace USD { +namespace Log { +namespace // anonymous +{ +using namespace USD::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(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(pthread_self()) << "/" << + static_cast(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); + } + } +} + +void OldStyleLogProvider::SecureDebug(const char *message, + const char *filename, + int line, + const char *function) +{ +#ifdef _SECURE_LOG + 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); + } + } +#else + (void)message; + (void)filename; + (void)line; + (void)function; +#endif +} + +void OldStyleLogProvider::SecureInfo(const char *message, + const char *filename, + int line, + const char *function) +{ +#ifdef _SECURE_LOG + 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); + } + } +#else + (void)message; + (void)filename; + (void)line; + (void)function; +#endif +} + +void OldStyleLogProvider::SecureWarning(const char *message, + const char *filename, + int line, + const char *function) +{ +#ifdef _SECURE_LOG + 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); + } + } +#else + (void)message; + (void)filename; + (void)line; + (void)function; +#endif +} + +void OldStyleLogProvider::SecureError(const char *message, + const char *filename, + int line, + const char *function) +{ +#ifdef _SECURE_LOG + 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); + } + } +#else + (void)message; + (void)filename; + (void)line; + (void)function; +#endif +} + +void OldStyleLogProvider::SmackAudit(const char *message, + const char *fileName, + int line, + const char *function) +{ + (void)message; + (void)fileName; + (void)line; + (void)function; +} + +} +} // namespace USD diff --git a/USD/src/dpl/log/src/sd_journal_provider.cpp b/USD/src/dpl/log/src/sd_journal_provider.cpp new file mode 100644 index 0000000..95ef5dc --- /dev/null +++ b/USD/src/dpl/log/src/sd_journal_provider.cpp @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2014 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 sd_journal_provider.cpp + * @author Marcin Lis (m.lis@samsung.com) + * @version 1.0 + * @brief This file contains the implementation of systemd journal log provider + */ + +#include +#include +#include +#include + +#define UNUSED __attribute__((unused)) + +namespace USD { +namespace Log { +std::string SdJournalProvider::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(); +} + +SdJournalProvider::SdJournalProvider() +{} + +SdJournalProvider::~SdJournalProvider() +{} + +void SdJournalProvider::SetTag(const char *tag) +{ + m_tag = std::string(tag); +} + +void SdJournalProvider::Debug(const char *message, + const char *filename, + int line, + const char *function) +{ + // sd-journal imports LOG priorities from the syslog, see syslog(3) for details + sd_journal_print(LOG_DEBUG, "%s", + (FormatMessage(message, filename, line, function)).c_str()); +} + +void SdJournalProvider::Info(const char *message, + const char *filename, + int line, + const char *function) +{ + sd_journal_print(LOG_INFO, "%s", + (FormatMessage(message, filename, line, function)).c_str()); +} + +void SdJournalProvider::Warning(const char *message, + const char *filename, + int line, + const char *function) +{ + sd_journal_print(LOG_WARNING, "%s", + (FormatMessage(message, filename, line, function)).c_str()); +} + +void SdJournalProvider::Error(const char *message, + const char *filename, + int line, + const char *function) +{ + sd_journal_print(LOG_ERR, "%s", + (FormatMessage(message, filename, line, function)).c_str()); +} + +// All Pedantic logs are translated to Debug +void SdJournalProvider::Pedantic(const char *message, + const char *filename, + int line, + const char *function) +{ + Debug(message, filename, line, function); +} + + + +/** + * Log pedantic message with secure macro + */ +void SdJournalProvider::SecureDebug(const char *message, + const char *filename, + int line, + const char *function) +{ + Debug(message, filename, line, function); +} +/** + * Log info message with secure macro + */ +void SdJournalProvider::SecureInfo(const char *message, + const char *filename, + int line, + const char *function) +{ + Info(message, filename, line, function); +} +/** + * Log warning message with secure macro + */ +void SdJournalProvider::SecureWarning(const char *message, + const char *filename, + int line, + const char *function) +{ + Warning(message, filename, line, function); +} +/** + * Log error message with secure macro + */ +void SdJournalProvider::SecureError(const char *message, + const char *filename, + int line, + const char *function) +{ + Error(message, filename, line, function); +} +/** + * Log SS_SMACK into files + */ + void SdJournalProvider::SmackAudit(const char *message, + const char *fileName, + int line, + const char *function) + { + Debug(message, fileName, line, function); + } + + +} // namespace Log +} // namespace USD diff --git a/USD/src/include/usb-security-daemon.h b/USD/src/include/usb-security-daemon.h new file mode 100644 index 0000000..876fc79 --- /dev/null +++ b/USD/src/include/usb-security-daemon.h @@ -0,0 +1,219 @@ +/* + * USB security daemon + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Bumjin Im + * + * 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 USB_SECURITY_DAEMON_H +#define USB_SECURITY_DAEMON_H + +#include +#include + +/** + * @file usb-security-daemon.h + * @version 1.0 + * @brief This file contains APIs of the USD +*/ + +/** + * @defgroup SecurityFW + * @{ + * + * @defgroup USD Usb-security-daemon + * @version 1.0 + * @brief USD client library functions + * +*/ + +/** + * @addtogroup USD + * @{ +*/ + +/* + * ==================================================================================================== + * + * + * Revision History: + * + * -- Company Name -- | Modification Date | Description of Changes + * ----------------------------------------------------------------------- + * --- Samsung ------ | --- 2010-07-25 -- | First created + * + * + */ + +/** + * \name Return Codes + * exported by the foundation API. + * result codes begin with the start error code and extend into negative direction. + * @{ +*/ + +/*! \brief indicating the result of the one specific API is successful */ +#define USD_API_SUCCESS 0 + +/*! \brief indicating the socket between client and USB Security Daemon has been failed */ +#define USD_API_ERROR_SOCKET -1 + +/*! \brief indicating the response to server is malformed */ +#define USD_API_ERROR_BAD_REQUEST -2 + +/*! \brief indicating the response from USB Security Daemon is malformed */ +#define USD_API_ERROR_BAD_RESPONSE -3 + +/*! \brief indicating the requested service does not exist */ +#define USD_API_ERROR_NO_SUCH_SERVICE -4 + +/*! \brief indicating requesting object is not exist */ +#define USD_API_ERROR_NO_SUCH_OBJECT -6 + +/*! \brief indicating the authentication between client and server has been failed */ +#define USD_API_ERROR_AUTHENTICATION_FAILED -7 + +/*! \brief indicating the API's input parameter is malformed */ +#define USD_API_ERROR_INPUT_PARAM -8 + +/*! \brief indicating the output buffer size which is passed as parameter is too small */ +#define USD_API_ERROR_BUFFER_TOO_SMALL -9 + +/*! \brief indicating system is running out of memory state */ +#define USD_API_ERROR_OUT_OF_MEMORY -10 + +/*! \brief indicating the access has been denied by USB Security Daemon */ +#define USD_API_ERROR_ACCESS_DENIED -11 + +/*! \brief indicating USB Security Daemon has been failed for some reason */ +#define USD_API_ERROR_SERVER_ERROR -12 + +/*! \brief indicating given cookie is not exist in the database */ +#define USD_API_ERROR_NO_SUCH_COOKIE -13 + +/*! \brief indicating there is no phone password set */ +#define USD_API_ERROR_NO_PASSWORD -14 + +/*! \brief indicating password exists in system */ +#define USD_API_ERROR_PASSWORD_EXIST -15 + +/*! \brief indicating password mismatch */ +#define USD_API_ERROR_PASSWORD_MISMATCH -16 + +/*! \brief indicating password retry timeout is not occurred yet */ +#define USD_API_ERROR_PASSWORD_RETRY_TIMER -17 + +/*! \brief indicating password retry timeout is not occurred yet */ +#define USD_API_ERROR_PASSWORD_MAX_ATTEMPTS_EXCEEDED -18 + +/*! \brief indicating password retry timeout is not occurred yet */ +#define USD_API_ERROR_PASSWORD_EXPIRED -19 + +/*! \brief indicating password retry timeout is not occurred yet */ +#define USD_API_ERROR_PASSWORD_REUSED -20 + +/*! \brief indicating getting smack label from socket failed */ +#define USD_API_ERROR_GETTING_SOCKET_LABEL_FAILED -21 + +/*! \brief indicating getting smack label from file failed */ +#define USD_API_ERROR_GETTING_FILE_LABEL_FAILED -22 + +/*! \brief indicating setting smack label for file failed */ +#define USD_API_ERROR_SETTING_FILE_LABEL_FAILED -23 + +/*! \brief indicating file already exists */ +#define USD_API_ERROR_FILE_EXIST -24 + +/*! \brief indicating file does not exist */ +#define USD_API_ERROR_FILE_NOT_EXIST -25 + +/*! \brief indicating file open error */ +#define USD_API_ERROR_FILE_OPEN_FAILED -26 + +/*! \brief indicating file creation error */ +#define USD_API_ERROR_FILE_CREATION_FAILED -27 + +/*! \brief indicating file deletion error */ +#define USD_API_ERROR_FILE_DELETION_FAILED -28 + +/*! \brief indicating the error with unknown reason */ +#define USD_API_ERROR_UNKNOWN -255 +/** @}*/ + + +#ifdef __cplusplus +extern "C" { +#endif + + + +/** + * This function enables to obtain opened file descriptor to device node which + * allows to communicate with USB device using raw USB messages. + * + * \param[in] devpath - path to a usb device file. + * \param[out] fd - pointer to where file descriptor will be written to + * + * This function checks weather calling process is permitted to communicate with + * choosen USB device. If it is, USD opens file and passes file descriptor. + * + * The policy that gathers information which applications may open a file + * descriptor must be first injected to USD by function call + * @ref security_server_setup_usb_device_access. + * + * \return USD_API_SUCCESS on success or one of error codes on fail + * \return USD_API_ERROR_ACCESS_DENIED, when user denies access + * \return USD_API_ERROR_SOCKET, + * \return USD_API_ERROR_INPUT_PARAM, + * \return USD_API_ERROR_AUTHENTICATION_FAILED, + * \return USD_API_ERROR_FILE_NOT_EXIST. + * + */ +int usd_open_usb_device(const char *devpath, int *fd); + + +/** + * This function enables to add policy entries to a temporary database of USD. + * This database lasts only as long as USD process is running: it is kept in + * process' memory. + * + * \param[in] topology - topological path to USB device (bus-hub.port etc) + * (for more details please check /sys/bus/usb/devices) + * \param[in] smack - smack label that is used to distinguish application + * \parm[in] allow - bool that indicates weather to allow or deny access between + * app that has smack label 'smack' and device that is available under path + * 'filename' + * + * \return USD_API_SUCCESS on success or one of error codes on fail + * + */ +int usd_setup_usb_device_access(const char *topology, const char *smack, + bool allow); + +#ifdef __cplusplus +} +#endif + +/** + * @} +*/ + +/** + * @} +*/ + +#endif diff --git a/USD/src/main/generic-event.h b/USD/src/main/generic-event.h new file mode 100644 index 0000000..bad23ee --- /dev/null +++ b/USD/src/main/generic-event.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Bumjin Im + * + * 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 _USD_GENERIC_EVENT_ +#define _USD_GENERIC_EVENT_ + +namespace USD { + +struct GenericEvent { + virtual ~GenericEvent(){} +}; + +} // namespace USD + +#endif // _USD_GENERIC_EVENT_ diff --git a/USD/src/main/generic-socket-manager.cpp b/USD/src/main/generic-socket-manager.cpp new file mode 100644 index 0000000..38bdb0d --- /dev/null +++ b/USD/src/main/generic-socket-manager.cpp @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Bumjin Im + * + * 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.cpp + * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com) + * @version 1.0 + * @brief Implementation of GenericSocketService and GenericSocketManager. + */ + +#include +#include + +#include + +namespace USD { + +class SendMsgData::Internal { +public: + Internal(int resultCode, int fileDesc) + : m_resultCode(resultCode) + , m_fileDesc(fileDesc) + { + memset(&m_hdr, 0, sizeof(msghdr)); + memset(m_cmsgbuf, 0, CMSG_SPACE(sizeof(int))); + + m_iov.iov_base = &m_resultCode; + m_iov.iov_len = sizeof(m_resultCode); + + m_hdr.msg_iov = &m_iov; + m_hdr.msg_iovlen = 1; + + if (fileDesc != -1) { + m_hdr.msg_control = m_cmsgbuf; + m_hdr.msg_controllen = CMSG_SPACE(sizeof(int)); + + m_cmsg = CMSG_FIRSTHDR(&m_hdr); + m_cmsg->cmsg_len = CMSG_LEN(sizeof(int)); + m_cmsg->cmsg_level = SOL_SOCKET; + m_cmsg->cmsg_type = SCM_RIGHTS; + + memmove(CMSG_DATA(m_cmsg), &m_fileDesc, sizeof(int)); + } + } + + msghdr* data() { return &m_hdr; } + +private: + msghdr m_hdr; + iovec m_iov; + cmsghdr *m_cmsg; + unsigned char m_cmsgbuf[CMSG_SPACE(sizeof(int))]; + int m_resultCode; + int m_fileDesc; +}; + +SendMsgData::SendMsgData() + : m_resultCode(0) + , m_fileDesc(-1) + , m_flags(0) + , m_pimpl(NULL) +{} + +SendMsgData::SendMsgData(int resultCode, int fileDesc, int flags) + : m_resultCode(resultCode) + , m_fileDesc(fileDesc) + , m_flags(flags) + , m_pimpl(NULL) +{} + +SendMsgData::SendMsgData(const SendMsgData &second) + : m_resultCode(second.m_resultCode) + , m_fileDesc(second.m_fileDesc) + , m_flags(second.m_flags) + , m_pimpl(NULL) +{} + +SendMsgData::~SendMsgData() { + delete m_pimpl; +} + +SendMsgData& SendMsgData::operator=(const SendMsgData &second) { + m_resultCode = second.m_resultCode; + m_fileDesc = second.m_fileDesc; + m_flags = second.m_flags; + delete m_pimpl; + m_pimpl = NULL; + return *this; +} + +msghdr* SendMsgData::getMsghdr() { + if (!m_pimpl) + m_pimpl = new Internal(m_resultCode, m_fileDesc); + return m_pimpl->data(); +} + +int SendMsgData::flags() { + return m_flags; +} + +} // namespace USD + diff --git a/USD/src/main/generic-socket-manager.h b/USD/src/main/generic-socket-manager.h new file mode 100644 index 0000000..fb7d7e8 --- /dev/null +++ b/USD/src/main/generic-socket-manager.h @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Bumjin Im + * + * 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 _USD_GENERIC_SERVICE_MANAGER_ +#define _USD_GENERIC_SERVICE_MANAGER_ + +#include +#include + +#include + +#include + +extern "C" { +struct msghdr; +} // extern "C" + +namespace USD { + +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 RawBuffer; + +struct GenericSocketManager; + +struct GenericSocketService { + typedef std::string SmackLabel; + typedef std::string ServiceHandlerPath; + struct ServiceDescription { + ServiceDescription(const char *path, + const char *smackLabel, + InterfaceID interfaceID = 0, + bool useSendMsg = false) + : smackLabel(smackLabel) + , interfaceID(interfaceID) + , serviceHandlerPath(path) + , useSendMsg(useSendMsg) + {} + + SmackLabel smackLabel; // Smack label for socket + InterfaceID interfaceID; // All data from serviceHandlerPath will be marked with this interfaceHandler + ServiceHandlerPath serviceHandlerPath; // Path to file + bool useSendMsg; + }; + + typedef std::vector 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; + }; + + 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; + + GenericSocketService() : m_serviceManager(NULL) {} + virtual ~GenericSocketService(){} +protected: + GenericSocketManager *m_serviceManager; +}; + +class SendMsgData { +public: + class Internal; + + SendMsgData(); + SendMsgData(int resultCode, int fileDesc, int flags = 0); + SendMsgData(const SendMsgData &second); + SendMsgData& operator=(const SendMsgData &second); + virtual ~SendMsgData(); + + msghdr* getMsghdr(); + int flags(); +private: + int m_resultCode; + int m_fileDesc; + int m_flags; + Internal *m_pimpl; +}; + +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 void Write(ConnectionID connectionID, const SendMsgData &sendMsgData) = 0; + virtual ~GenericSocketManager(){} +}; + +} // namespace USD + +#endif // _USD_GENERIC_SERVICE_MANAGER_ diff --git a/USD/src/main/server2-main.cpp b/USD/src/main/server2-main.cpp new file mode 100644 index 0000000..da3eaa1 --- /dev/null +++ b/USD/src/main/server2-main.cpp @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Bumjin Im + * + * 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 USD + */ +#include +#include + +#include +#include +#include + +#include + + +IMPLEMENT_SAFE_SINGLETON(USD::Log::LogSystem); + +#define REGISTER_SOCKET_SERVICE(manager, service) \ + registerSocketService(manager, #service) + +template +void registerSocketService(USD::SocketManager &manager, const std::string& serviceName) +{ + T *service = NULL; + try { + service = new T(); + service->Create(); + manager.RegisterSocketService(service); + service = NULL; + } catch (const USD::Exception &exception) { + LogError("Error in creating service " << serviceName << + ", details:\n" << exception.DumpToString()); + } catch (const std::exception& e) { + LogError("Error in creating service " << serviceName << + ", details:\n" << e.what()); + } catch (...) { + LogError("Error in creating service " << serviceName << + ", unknown exception occured"); + } + if (service) + delete service; +} + +int main(void) { + + UNHANDLED_EXCEPTION_HANDLER_BEGIN + { + USD::Singleton::Instance().SetTag("USD"); + + sigset_t mask; + sigemptyset(&mask); + sigaddset(&mask, SIGTERM); + sigaddset(&mask, SIGPIPE); + if (-1 == pthread_sigmask(SIG_BLOCK, &mask, NULL)) { + LogError("Error in pthread_sigmask"); + return 1; + } + + LogInfo("Start!"); + USD::SocketManager manager; + + + manager.MainLoop(); + } + UNHANDLED_EXCEPTION_HANDLER_END + return 0; +} + diff --git a/USD/src/main/service-thread.h b/USD/src/main/service-thread.h new file mode 100644 index 0000000..d230d2f --- /dev/null +++ b/USD/src/main/service-thread.h @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Bumjin Im + * + * 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 _USD_SERVICE_THREAD_ +#define _USD_SERVICE_THREAD_ + +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include "generic-event.h" + +#define DEFINE_THREAD_EVENT(eventType) \ + void Event(const eventType &event) { \ + USD::ServiceThread:: \ + Event(event, \ + this, \ + &ParentClassName::EventInternal##eventType); \ + } \ + void EventInternal##eventType(const eventType &event) + +#define DECLARE_THREAD_EVENT(eventType, methodName) \ + void Event(const eventType &event) { \ + USD::ServiceThread:: \ + Event(event, \ + this, \ + &ParentClassName::methodName); \ + } + +namespace USD { + +template +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); + { + std::lock_guard lock(m_eventQueueMutex); + 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 + void Event(const T &event, + Service *servicePtr, + void (Service::*serviceFunction)(const T &)) + { + EventDescription description; + description.serviceFunctionPtr = + reinterpret_cast(serviceFunction); + description.servicePtr = servicePtr; + description.eventFunctionPtr = &ServiceThread::EventCall; + description.eventPtr = new T(event); + { + std::lock_guard 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 + void EventCall(const EventDescription &desc) { + auto fun = reinterpret_cast(desc.serviceFunctionPtr); + const T& eventLocale = *(static_cast(desc.eventPtr)); + (desc.servicePtr->*fun)(eventLocale); + } + + static void ThreadLoopStatic(ServiceThread *ptr) { + ptr->ThreadLoop(); + } + + void ThreadLoop(){ + for (;;) { + EventDescription description = {NULL, NULL, NULL, NULL}; + { + std::unique_lock ulock(m_eventQueueMutex); + if (m_quit) + return; + 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 m_eventQueue; + std::condition_variable m_waitCondition; + + State m_state; + bool m_quit; +}; + +} // namespace USD + +#endif // _USD_SERVICE_THREAD_ diff --git a/USD/src/main/socket-manager.cpp b/USD/src/main/socket-manager.cpp new file mode 100644 index 0000000..7a527f9 --- /dev/null +++ b/USD/src/main/socket-manager.cpp @@ -0,0 +1,737 @@ +/* + * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Bumjin Im + * + * 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 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include +#include + +namespace { + +const time_t SOCKET_TIMEOUT = 20; + +} // namespace anonymous + +namespace USD { + +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; } +}; + +struct SignalService : public GenericSocketService { + int GetDescriptor() { + LogInfo("set up"); + sigset_t mask; + sigemptyset(&mask); + sigaddset(&mask, SIGTERM); + if (-1 == pthread_sigmask(SIG_BLOCK, &mask, NULL)) + return -1; + return signalfd(-1, &mask, 0); + } + + ServiceDescriptionVector GetServiceDescription() { + return ServiceDescriptionVector(); + } + + void Event(const AcceptEvent &event) { (void)event; } // not supported + void Event(const WriteEvent &event) { (void)event; } // not supported + void Event(const CloseEvent &event) { (void)event; } // not supported + + void Event(const ReadEvent &event) { + LogDebug("Get signal information"); + + if(sizeof(struct signalfd_siginfo) != event.rawBuffer.size()) { + LogError("Wrong size of signalfd_siginfo struct. Expected: " + << sizeof(signalfd_siginfo) << " Get: " + << event.rawBuffer.size()); + return; + } + + signalfd_siginfo *siginfo = (signalfd_siginfo*)(&(event.rawBuffer[0])); + + if (siginfo->ssi_signo == SIGTERM) { + LogInfo("Got signal: SIGTERM"); + static_cast(m_serviceManager)->MainLoopStop(); + return; + } + + LogInfo("This should not happend. Got signal: " << siginfo->ssi_signo); + } +}; + +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_maxDesc(0) + , 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); + + // add support for TERM signal (passed from systemd) + auto *signalService = new SignalService; + signalService->SetSocketManager(this); + int filefd = signalService->GetDescriptor(); + if (-1 == filefd) { + LogError("Error in SignalService.GetDescriptor()"); + delete signalService; + } else { + auto &desc2 = CreateDefaultReadSocketDescription(filefd, false); + desc2.service = signalService; + LogInfo("SignalService mounted on " << filefd << " descriptor"); + } +} + +SocketManager::~SocketManager() { + std::set serviceMap; + + // Find all services. Set is used to remove duplicates. + // In this implementation, services are not able to react in any way. + for (size_t i=0; i < m_socketDescriptionVector.size(); ++i) + if (m_socketDescriptionVector[i].isOpen) + serviceMap.insert(m_socketDescriptionVector[i].service); + + // Time to destroy all services. + for(auto it = serviceMap.begin(); it != serviceMap.end(); ++it) { + LogDebug("delete " << (void*)(*it)); + delete *it; + } + + for (size_t i = 0; i < m_socketDescriptionVector.size(); ++i) + if (m_socketDescriptionVector[i].isOpen) + close(i); + + // All socket except one were closed. Now pipe input must be closed. + close(m_notifyMe[1]); +} + +void SocketManager::ReadyForAccept(int sock) { + struct sockaddr_un clientAddr; + unsigned int clientLen = sizeof(clientAddr); + int client = accept4(sock, (struct sockaddr*) &clientAddr, &clientLen, SOCK_NONBLOCK); +// LogInfo("Accept on sock: " << sock << " Socket opended: " << client); + 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; + desc.useSendMsg = m_socketDescriptionVector[sock].useSendMsg; + + 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::ReadyForSendMsg(int sock) { + auto &desc = m_socketDescriptionVector[sock]; + + if (desc.sendMsgDataQueue.empty()) { + FD_CLR(sock, &m_writeSet); + return; + } + + auto data = desc.sendMsgDataQueue.front(); + ssize_t result = sendmsg(sock, data.getMsghdr(), data.flags()); + + if (result == -1) { + int err = errno; + switch(err) { + case EAGAIN: + case EINTR: + break; + case EPIPE: + default: + LogDebug("Error during send: " << strerror(err)); + CloseSocket(sock); + break; + } + return; + } else { + desc.sendMsgDataQueue.pop(); + } + + if (desc.sendMsgDataQueue.empty()) { + FD_CLR(sock, &m_writeSet); + } + + desc.timeout = time(NULL) + SOCKET_TIMEOUT; + + GenericSocketService::WriteEvent event; + event.connectionID.sock = sock; + event.connectionID.counter = desc.counter; + event.size = result; + event.left = desc.sendMsgDataQueue.size(); + + desc.service->Event(event); +} + +void SocketManager::ReadyForWriteBuffer(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: + LogDebug("Error during write: " << strerror(err)); + 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::ReadyForWrite(int sock) { + m_socketDescriptionVector[sock].useSendMsg ? + ReadyForSendMsg(sock) : ReadyForWriteBuffer(sock); +} + +void SocketManager::MainLoop() { + + // Daemon is ready to work. + sd_notify(0, "READY=1"); + + 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; isockfd + int n = sd_listen_fds(0); + + LogInfo("sd_listen_fds returns: " << n); + + if (n < 0) { + LogError("Error in sd_listend_fds"); + ThrowMsg(Exception::InitFailed, "Error in sd_listend_fds"); + } + + for(fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START+n; ++fd) { + if (0 < sd_is_socket_unix(fd, SOCK_STREAM, 1, + desc.serviceHandlerPath.c_str(), 0)) + { + LogInfo("Useable socket " << desc.serviceHandlerPath << + " was passed by SystemD under descriptor " << fd); + return fd; + } + } + LogInfo("No useable sockets were passed by systemd."); + return -1; +} + +int SocketManager::CreateDomainSocketHelp( + const GenericSocketService::ServiceDescription &desc) +{ + int sockfd; + + if(desc.serviceHandlerPath.size() > sizeof(static_cast(0)->sun_path) / + sizeof(decltype(desc.serviceHandlerPath)::value_type)) { + LogError("Service handler path too long: " << desc.serviceHandlerPath.size()); + ThrowMsg(Exception::InitFailed, + "Service handler path too long: " << desc.serviceHandlerPath.size()); + } + + 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)); + } + + if (smack_check()) { + LogInfo("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"); + } + } else { + LogInfo("No smack on platform. Socket won't be securied with smack label!"); + } + + 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: " << desc.serviceHandlerPath.c_str() << 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)); + } + + return sockfd; +} + +void SocketManager::CreateDomainSocket( + GenericSocketService *service, + const GenericSocketService::ServiceDescription &desc) +{ + int sockfd = GetSocketFromSystemD(desc); + if (-1 == sockfd) + sockfd = CreateDomainSocketHelp(desc); + + auto &description = CreateDefaultReadSocketDescription(sockfd, false); + + description.isListen = true; + description.interfaceID = desc.interfaceID; + description.useSendMsg = desc.useSendMsg; + description.service = service; + + LogDebug("Listen on socket: " << sockfd << + " Handler: " << desc.serviceHandlerPath.c_str()); +} + +void SocketManager::RegisterSocketService(GenericSocketService *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::lock_guard 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::lock_guard ulock(m_eventQueueMutex); + m_writeBufferQueue.push(buffer); + } + NotifyMe(); +} + +void SocketManager::Write(ConnectionID connectionID, const SendMsgData &sendMsgData) { + WriteData data; + data.connectionID = connectionID; + data.sendMsgData = sendMsgData; + { + std::lock_guard ulock(m_eventQueueMutex); + m_writeDataQueue.push(data); + } + NotifyMe(); +} + +void SocketManager::NotifyMe() { + TEMP_FAILURE_RETRY(write(m_notifyMe[1], "You have message ;-)", 1)); +} + +void SocketManager::ProcessQueue() { + WriteBuffer buffer; + WriteData data; + { + std::lock_guard ulock(m_eventQueueMutex); + while (!m_writeBufferQueue.empty()) { + buffer = m_writeBufferQueue.front(); + m_writeBufferQueue.pop(); + + auto &desc = m_socketDescriptionVector[buffer.connectionID.sock]; + + if (!desc.isOpen) { + LogDebug("Received packet for write but connection is closed. Packet ignored!"); + continue; + } + + if (desc.counter != buffer.connectionID.counter) + { + LogDebug("Received packet for write but counter is broken. Packet ignored!"); + continue; + } + + if (desc.useSendMsg) { + LogError("Some service tried to push rawdata to socket that usees sendmsg!"); + continue; + } + + std::copy( + buffer.rawBuffer.begin(), + buffer.rawBuffer.end(), + std::back_inserter(desc.rawBuffer)); + + FD_SET(buffer.connectionID.sock, &m_writeSet); + } + + while(!m_writeDataQueue.empty()) { + data = m_writeDataQueue.front(); + m_writeDataQueue.pop(); + + auto &desc = m_socketDescriptionVector[data.connectionID.sock]; + + if (!desc.isOpen) { + LogDebug("Received packet for sendmsg but connection is closed. Packet ignored!"); + continue; + } + + if (desc.counter != data.connectionID.counter) + { + LogDebug("Received packet for write but counter is broken. Packet ignored!"); + continue; + } + + if (!desc.useSendMsg) { + LogError("Some service tries to push SendMsgData to socket that uses write!"); + continue; + } + + desc.sendMsgDataQueue.push(data.sendMsgData); + + FD_SET(data.connectionID.sock, &m_writeSet); + } + } + + while (1) { + ConnectionID connection; + { + std::lock_guard 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) { +// LogInfo("Closing socket: " << sock); + auto &desc = m_socketDescriptionVector[sock]; + + if (!(desc.isOpen)) { + // This may happend when some information was waiting for write to the + // socket and in the same time socket was closed by the client. + LogError("Socket " << sock << " is not open. Nothing to do!"); + return; + } + + 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(); + while(!desc.sendMsgDataQueue.empty()) + desc.sendMsgDataQueue.pop(); + + if (service) + service->Event(event); + else + LogError("Critical! Service is NULL! This should never happend!"); + + TEMP_FAILURE_RETRY(close(sock)); + FD_CLR(sock, &m_readSet); + FD_CLR(sock, &m_writeSet); +} + +} // namespace USD diff --git a/USD/src/main/socket-manager.h b/USD/src/main/socket-manager.h new file mode 100644 index 0000000..db61335 --- /dev/null +++ b/USD/src/main/socket-manager.h @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Bumjin Im + * + * 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 _USD_SOCKET_MANAGER_ +#define _USD_SOCKET_MANAGER_ + +#include +#include +#include +#include +#include + +#include + +#include + +namespace USD { + +class SocketManager : public GenericSocketManager { +public: + class Exception { + public: + DECLARE_EXCEPTION_TYPE(USD::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, InitFailed) + }; + SocketManager(); + virtual ~SocketManager(); + virtual void MainLoop(); + virtual void MainLoopStop(); + + virtual void RegisterSocketService(GenericSocketService *service); + virtual void Close(ConnectionID connectionID); + virtual void Write(ConnectionID connectionID, const RawBuffer &rawBuffer); + virtual void Write(ConnectionID connectionID, const SendMsgData &sendMsgData); + +protected: + void CreateDomainSocket( + GenericSocketService *service, + const GenericSocketService::ServiceDescription &desc); + int CreateDomainSocketHelp( + const GenericSocketService::ServiceDescription &desc); + int GetSocketFromSystemD( + const GenericSocketService::ServiceDescription &desc); + + void ReadyForRead(int sock); + void ReadyForWrite(int sock); + void ReadyForWriteBuffer(int sock); + void ReadyForSendMsg(int sock); + void ReadyForAccept(int sock); + void ProcessQueue(void); + void NotifyMe(void); + void CloseSocket(int sock); + + struct SocketDescription { + bool isListen; + bool isOpen; + bool isTimeout; + bool useSendMsg; + InterfaceID interfaceID; + GenericSocketService *service; + time_t timeout; + RawBuffer rawBuffer; + std::queue sendMsgDataQueue; + int counter; + + SocketDescription() + : isListen(false) + , isOpen(false) + , isTimeout(false) + , useSendMsg(false) + , interfaceID(-1) + , service(NULL) + {} + }; + + SocketDescription& CreateDefaultReadSocketDescription(int sock, bool timeout); + + typedef std::vector SocketDescriptionVector; + + struct WriteBuffer { + ConnectionID connectionID; + RawBuffer rawBuffer; + }; + + struct WriteData { + ConnectionID connectionID; + SendMsgData sendMsgData; + }; + + 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 m_writeBufferQueue; + std::queue m_writeDataQueue; + std::queue m_closeQueue; + int m_notifyMe[2]; + int m_counter; + std::priority_queue m_timeoutQueue; +}; + +} // namespace USD + +#endif // _USD_SOCKET_MANAGER_ diff --git a/USD/src/main/usd-util.cpp b/USD/src/main/usd-util.cpp new file mode 100644 index 0000000..858d5b1 --- /dev/null +++ b/USD/src/main/usd-util.cpp @@ -0,0 +1,116 @@ +/* + * USD security daemon + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Bumjin Im + * + * 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 + * + */ + +#include +#include +#include +#include + +#include + +#include +#include + +namespace { +const size_t SIZE_T_MAX = std::numeric_limits::max(); +} // namespace anonymous + +namespace USD { + +int util_smack_label_is_valid(const char *smack_label) +{ + int i; + + if (!smack_label || smack_label[0] == '\0' || smack_label[0] == '-') + goto err; + + for (i = 0; smack_label[i]; ++i) { + if (i >= SMACK_LABEL_LEN) + return 0; + switch (smack_label[i]) { + case '~': + case ' ': + case '/': + case '"': + case '\\': + case '\'': + goto err; + default: + break; + } + } + + return 1; +err: + LogError("Invalid Smack label: " << (smack_label ? smack_label : "")); + return 0; +} + +char *read_exe_path_from_proc(pid_t pid) +{ + char link[32]; + char *exe = NULL; + size_t size = 64; + ssize_t cnt = 0; + + // get link to executable + snprintf(link, sizeof(link), "/proc/%d/exe", pid); + + for (;;) + { + exe = (char*) malloc(size); + if (exe == NULL) + { + LogError("Out of memory"); + return NULL; + } + + // read link target + cnt = readlink(link, exe, size); + + // error + if (cnt < 0 || (size_t) cnt > size) + { + LogError("Can't locate process binary for pid=" << pid); + free(exe); + return NULL; + } + + // read less than requested + if ((size_t) cnt < size) + break; + + // read exactly the number of bytes requested + free(exe); + if (size > (SIZE_T_MAX >> 1)) + { + LogError("Exe path too long (more than " << size << " characters)"); + return NULL; + } + size <<= 1; + } + // readlink does not append null byte to buffer. + exe[cnt] = '\0'; + return exe; +} + +} // namespace USD + diff --git a/USD/src/main/usd-util.h b/USD/src/main/usd-util.h new file mode 100644 index 0000000..bc3ae49 --- /dev/null +++ b/USD/src/main/usd-util.h @@ -0,0 +1,34 @@ +/* + * USB security daemon + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Bumjin Im + * + * 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 USD_UTIL_H +#define USD_UTIL_H + +#include + +namespace USD { + +int util_smack_label_is_valid(const char *smack_label); +char *read_exe_path_from_proc(pid_t pid); + +} // namespace USD + +#endif /*USD_UTIL_H*/ diff --git a/USD/systemd/CMakeLists.txt b/USD/systemd/CMakeLists.txt new file mode 100644 index 0000000..5cd9ce8 --- /dev/null +++ b/USD/systemd/CMakeLists.txt @@ -0,0 +1,6 @@ +INSTALL(FILES + ${CMAKE_SOURCE_DIR}/USD/systemd/usd.service + DESTINATION + ${SYSTEMD_DIR} +) + diff --git a/USD/systemd/usd.service b/USD/systemd/usd.service new file mode 100644 index 0000000..b842e08 --- /dev/null +++ b/USD/systemd/usd.service @@ -0,0 +1,9 @@ +[Unit] +Description=USB security daemon + +[Service] +Type=notify +ExecStart=/usr/bin/usd + +[Install] +WantedBy=multi-user.target diff --git a/packaging/USD.manifest b/packaging/USD.manifest new file mode 100644 index 0000000..017d22d --- /dev/null +++ b/packaging/USD.manifest @@ -0,0 +1,5 @@ + + + + + diff --git a/packaging/capi-system-usbhost.spec b/packaging/capi-system-usbhost.spec index ea82068..08237fe 100644 --- a/packaging/capi-system-usbhost.spec +++ b/packaging/capi-system-usbhost.spec @@ -7,10 +7,23 @@ Group: Base/Device Management Source0: libhusb-%{version}.tar.gz Source1001: capi-system-usbhost.manifest +Source1002: libUSD-client.manifest +Source1003: USD.manifest BuildRequires: pkg-config BuildRequires: cmake BuildRequires: pkgconfig(libusb-1.0) +BuildRequires: zip +BuildRequires: pkgconfig(dlog) +BuildRequires: pkgconfig(openssl) +BuildRequires: libattr-devel +BuildRequires: libcap-devel +BuildRequires: pkgconfig(libsmack) +BuildRequires: pkgconfig(libprivilege-control) +BuildRequires: pkgconfig(libsystemd-daemon) +BuildRequires: pkgconfig(libsystemd-journal) +%{?systemd_requires} + %description Libhusb is a librarary for raw communication with USB devices. @@ -26,30 +39,145 @@ compilation of applications which use libhusb. %prep %setup -q cp %{SOURCE1001} . -cmake . +cp %{SOURCE1002} . +cp %{SOURCE1003} . + %build -make + +%if 0%{?sec_build_binary_debug_enable} +export CFLAGS="$CFLAGS -DTIZEN_DEBUG_ENABLE" +export CXXFLAGS="$CXXFLAGS -DTIZEN_DEBUG_ENABLE" +export FFLAGS="$FFLAGS -DTIZEN_DEBUG_ENABLE" +%endif + +export LDFLAGS="${LDFLAGS} -Wl,--rpath=%{_libdir}" + +%cmake . -DVERSION=%{version} \ + -DCMAKE_BUILD_TYPE=%{?build_type:%build_type}%{!?build_type:RELEASE} \ + -DCMAKE_VERBOSE_MAKEFILE=ON \ + -DLIB_INSTALL_DIR=%{_libdir} \ + -DSYSTEMD_DIR=%{_unitdir} + +%__make %{?_smp_mflags} + %install +rm -rf %{buildroot} +mkdir -p %{buildroot}%{_datadir}/license +cp LICENSE %{buildroot}%{_datadir}/license/%{name} +cp LICENSE %{buildroot}%{_datadir}/license/libusd-client +mkdir -p %{buildroot}%{_sysconfdir}/security/ %make_install +mkdir -p %{buildroot}%{_unitdir}/multi-user.target.wants +mkdir -p %{buildroot}%{_unitdir}/sockets.target.wants +ln -s ../usd.service %{buildroot}%{_unitdir}/multi-user.target.wants/usd.service + + %post -p /sbin/ldconfig %postun -p /sbin/ldconfig +%clean +rm -rf %{buildroot} + %files %manifest %{name}.manifest %defattr(-,root,root) %license LICENSE -/usr/local/lib/libhusb.so.* -/usr/local/lib/libhusb.so.*.*.* +%{_libdir}/libhusb.so.* +%{_libdir}/libhusb.so.*.*.* %files devel %manifest %{name}.manifest %defattr(-,root,root) -/usr/local/include/libhusb.h -/usr/local/lib/libhusb.so +%{_includedir}/libhusb.h +%{_libdir}/libhusb.so + +%package usd +Summary: Usb securit daemon and utilities + +%description usd +USB security Daemon + +%package libusd-client +Summary: USD (client) +Group: Security/Libraries +Requires: capi-system-usbhost-usd = %{version}-%{release} +Requires(post): /sbin/ldconfig +Requires(postun): /sbin/ldconfig + +%description libusd-client +USD client libraries +%package libusd-client-devel +Summary: USD (client-devel) +Group: Security/Development +Requires: capi-system-usbhost-libusd-client = %{version}-%{release} + +%description libusd-client-devel +Development files needed for using the security client + +%package usd-devel +Summary: USD (Development) +Group: Security/Development +Requires: capi-system-usbhost-usd = %{version}-%{release} + +%description usd-devel +Development files for the USB security daemon + +%post usd +ldconfig +systemctl daemon-reload +if [ $1 = 1 ]; then +# installation + systemctl start usd.service +fi + +if [ $1 = 2 ]; then +# update + systemctl restart usd.service +fi + +%preun usd +if [ $1 = 0 ]; then +# unistall + systemctl stop usd.service +fi + +%postun usd +ldconfig +if [ $1 = 0 ]; then +# unistall + systemctl daemon-reload +fi + +%post libusd-client -p /sbin/ldconfig + +%postun libusd-client -p /sbin/ldconfig + +%files usd +%manifest USD.manifest +%defattr(-,root,root,-) +%attr(755,root,root) %{_bindir}/usd +%{_libdir}/libusd-commons.so.* +%attr(-,root,root) %{_unitdir}/multi-user.target.wants/usd.service +%attr(-,root,root) %{_unitdir}/usd.service +%{_datadir}/license/%{name} + +%files libusd-client +%manifest libUSD-client.manifest +%defattr(-,root,root,-) +%{_libdir}/libusd-client.so.* +%{_datadir}/license/libusd-client + +%files libusd-client-devel +%manifest %{name}.manifest +%defattr(-,root,root,-) +%{_libdir}/libusd-client.so +%{_libdir}/libusd-commons.so +%{_includedir}/usd/usb-security-daemon.h +%{_libdir}/pkgconfig/*.pc %changelog diff --git a/packaging/libUSD-client.manifest b/packaging/libUSD-client.manifest new file mode 100644 index 0000000..a76fdba --- /dev/null +++ b/packaging/libUSD-client.manifest @@ -0,0 +1,5 @@ + + + + + diff --git a/pc/CMakeLists.txt b/pc/CMakeLists.txt new file mode 100644 index 0000000..62859b9 --- /dev/null +++ b/pc/CMakeLists.txt @@ -0,0 +1,19 @@ +# 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 CMakeLists.txt +# @author Tomasz Swierczek (t.swierczek@samsung.com) +# + +ADD_SUBDIRECTORY(USD) diff --git a/pc/USD/CMakeLists.txt b/pc/USD/CMakeLists.txt new file mode 100644 index 0000000..a50ebe1 --- /dev/null +++ b/pc/USD/CMakeLists.txt @@ -0,0 +1,26 @@ +# 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 CMakeLists.txt +# @author Bartlomiej Grzelewski (b.grzelewski@samsung.com) +# @brief +# + +CONFIGURE_FILE(capi-system-usbhost-usd.pc.in capi-system-usbhost-usd.pc @ONLY) + +INSTALL(FILES + ${CMAKE_BINARY_DIR}/pc/USD/capi-system-usbhost-usd.pc + DESTINATION + ${LIB_INSTALL_DIR}/pkgconfig + ) diff --git a/pc/USD/capi-system-usbhost-usd.pc.in b/pc/USD/capi-system-usbhost-usd.pc.in new file mode 100644 index 0000000..b41e2fe --- /dev/null +++ b/pc/USD/capi-system-usbhost-usd.pc.in @@ -0,0 +1,11 @@ +prefix=@CMAKE_INSTALL_PREFIX@ +exec_prefix=${prefix} +libdir=@LIB_INSTALL_DIR@ +includedir=${prefix}/include + +Name: capi-system-usbhost-usd +Description: USD Package +Version: 1.0.1 +Requires: openssl libsmack libprivilege-control +Libs: -L${libdir} -lusd-client +Cflags: -I${includedir}/usd