Add early cynara service implementation
authorLukasz Wojciechowski <l.wojciechow@partner.samsung.com>
Mon, 16 Jun 2014 19:46:23 +0000 (21:46 +0200)
committerRafal Krypa <r.krypa@samsung.com>
Thu, 3 Jul 2014 12:19:09 +0000 (14:19 +0200)
Change-Id: I3007944f08f9c29cab6e6b755c4996f38db3ab0d

28 files changed:
src/common/common.h
src/common/containers/RawBuffer.h [new file with mode: 0644]
src/common/exceptions/InitException.h [new file with mode: 0644]
src/common/exceptions/UnexpectedErrorException.h [new file with mode: 0644]
src/service/CMakeLists.txt
src/service/logic/Logic.cpp [new file with mode: 0644]
src/service/logic/Logic.h [new file with mode: 0644]
src/service/main/Cynara.cpp [new file with mode: 0644]
src/service/main/Cynara.h [new file with mode: 0644]
src/service/main/main.cpp
src/service/protocol/Protocol.cpp [new file with mode: 0644]
src/service/protocol/Protocol.h [new file with mode: 0644]
src/service/protocol/ProtocolAdmin.cpp [new file with mode: 0644]
src/service/protocol/ProtocolAdmin.h [new file with mode: 0644]
src/service/protocol/ProtocolClient.cpp [new file with mode: 0644]
src/service/protocol/ProtocolClient.h [new file with mode: 0644]
src/service/protocol/ProtocolSignal.cpp [new file with mode: 0644]
src/service/protocol/ProtocolSignal.h [new file with mode: 0644]
src/service/request/Request.cpp [new file with mode: 0644]
src/service/request/Request.h [new file with mode: 0644]
src/service/request/RequestContext.cpp [new file with mode: 0644]
src/service/request/RequestContext.h [new file with mode: 0644]
src/service/sockets/Descriptor.cpp [new file with mode: 0644]
src/service/sockets/Descriptor.h [new file with mode: 0644]
src/service/sockets/SocketManager.cpp [new file with mode: 0644]
src/service/sockets/SocketManager.h [new file with mode: 0644]
systemd/cynara-admin.socket
systemd/cynara.socket

index f69a5b3..8637231 100644 (file)
@@ -27,6 +27,9 @@
 #include "attributes/attributes.h"
 #include "attributes/debug_attributes.h"
 
+#include "containers/BinaryQueue.h"
+#include "containers/RawBuffer.h"
+
 #include "result/Result.h"
 
 #include "types/PolicyTypeExtension.h"
diff --git a/src/common/containers/RawBuffer.h b/src/common/containers/RawBuffer.h
new file mode 100644 (file)
index 0000000..1e320de
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * 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        RawBuffer.h
+ * @author      Lukasz Wojciechowski <l.wojciechow@partner.samsung.com>
+ * @version     1.0
+ * @brief       This file defines binary raw buffer type
+ */
+
+#ifndef SRC_COMMON_CONTAINERS_RAWBUFFER_H_
+#define SRC_COMMON_CONTAINERS_RAWBUFFER_H_
+
+#include <vector>
+
+namespace Cynara {
+
+typedef std::vector<unsigned char> RawBuffer;
+
+} // namespace Cynara
+
+#endif /* SRC_COMMON_CONTAINERS_RAWBUFFER_H_ */
diff --git a/src/common/exceptions/InitException.h b/src/common/exceptions/InitException.h
new file mode 100644 (file)
index 0000000..f3f69fa
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * 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        UnexpectedErrorException.h
+ * @author      Lukasz Wojciechowski <l.wojciechow@partner.samsung.com>
+ * @version     1.0
+ * @brief       Implementation of InitException
+ */
+
+#ifndef SRC_COMMON_EXCEPTIONS_INITEXCEPTION_H_
+#define SRC_COMMON_EXCEPTIONS_INITEXCEPTION_H_
+
+#include "Exception.h"
+
+#include <exception>
+
+namespace Cynara {
+
+class InitException : public Exception {
+public:
+    InitException() = default;
+    virtual ~InitException() = default;
+};
+
+} /* namespace Cynara */
+
+#endif /* SRC_COMMON_EXCEPTIONS_INITEXCEPTION_H_ */
diff --git a/src/common/exceptions/UnexpectedErrorException.h b/src/common/exceptions/UnexpectedErrorException.h
new file mode 100644 (file)
index 0000000..9d858f4
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * 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        UnexpectedErrorException.h
+ * @author      Lukasz Wojciechowski <l.wojciechow@partner.samsung.com>
+ * @version     1.0
+ * @brief       Implementation of UnexpectedErrorException
+ */
+
+#ifndef SRC_COMMON_EXCEPTIONS_UNEXPECTEDERROREXCEPTION_H_
+#define SRC_COMMON_EXCEPTIONS_UNEXPECTEDERROREXCEPTION_H_
+
+#include <exception>
+#include <sstream>
+
+#include "Exception.h"
+
+namespace Cynara {
+
+class UnexpectedErrorException : public Exception {
+private:
+    std::string m_whatMessage;
+
+public:
+    UnexpectedErrorException() = delete;
+    UnexpectedErrorException(int errorCode, const char *errorMsg) {
+        std::ostringstream stream;
+        stream << "UnexpectedErrorException with errorCode =[" << errorCode << "] and message <";
+        stream << errorMsg << ">";
+        m_whatMessage = stream.str();
+    }
+
+    virtual ~UnexpectedErrorException() = default;
+
+    virtual const char* what() const noexcept {
+        return m_whatMessage.c_str();
+    }
+};
+
+} // namespace Cynara
+
+#endif /* SRC_COMMON_EXCEPTIONS_UNEXPECTEDERROREXCEPTION_H_ */
index a580554..206b64d 100644 (file)
 SET(CYNARA_SERVICE_PATH ${CYNARA_PATH}/service)
 
 SET(CYNARA_SOURCES
+    ${CYNARA_SERVICE_PATH}/logic/Logic.cpp
+    ${CYNARA_SERVICE_PATH}/main/Cynara.cpp
     ${CYNARA_SERVICE_PATH}/main/main.cpp
+    ${CYNARA_SERVICE_PATH}/protocol/Protocol.cpp
+    ${CYNARA_SERVICE_PATH}/protocol/ProtocolAdmin.cpp
+    ${CYNARA_SERVICE_PATH}/protocol/ProtocolClient.cpp
+    ${CYNARA_SERVICE_PATH}/protocol/ProtocolSignal.cpp
+    ${CYNARA_SERVICE_PATH}/request/Request.cpp
+    ${CYNARA_SERVICE_PATH}/request/RequestContext.cpp
+    ${CYNARA_SERVICE_PATH}/sockets/Descriptor.cpp
+    ${CYNARA_SERVICE_PATH}/sockets/SocketManager.cpp
     ${CYNARA_SERVICE_PATH}/storage/Storage.cpp
     )
 
@@ -29,7 +39,7 @@ SET_SOURCE_FILES_PROPERTIES(
         COMPILE_FLAGS "-D_GNU_SOURCE -fvisibility=hidden")
 
 INCLUDE_DIRECTORIES(
-    ${CYNARA_SERVICE_PATH}/main
+    ${CYNARA_SERVICE_PATH}
     )
 
 ADD_EXECUTABLE(${TARGET_CYNARA} ${CYNARA_SOURCES})
diff --git a/src/service/logic/Logic.cpp b/src/service/logic/Logic.cpp
new file mode 100644 (file)
index 0000000..0556c4f
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * 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        Logic.cpp
+ * @author      Lukasz Wojciechowski <l.wojciechow@partner.samsung.com>
+ * @version     1.0
+ * @brief       This file implements main class of logic layer in cynara service
+ */
+
+#include "Logic.h"
+
+namespace Cynara {
+Logic::Logic() {
+}
+
+Logic::~Logic() {
+}
+} // namespace Cynara
diff --git a/src/service/logic/Logic.h b/src/service/logic/Logic.h
new file mode 100644 (file)
index 0000000..e957196
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * 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        Logic.h
+ * @author      Lukasz Wojciechowski <l.wojciechow@partner.samsung.com>
+ * @version     1.0
+ * @brief       This file defines main class of logic layer in cynara service
+ */
+
+#ifndef SRC_SERVICE_LOGIC_LOGIC_H_
+#define SRC_SERVICE_LOGIC_LOGIC_H_
+
+namespace Cynara {
+
+class Logic {
+public:
+    Logic();
+    ~Logic();
+};
+
+} // namespace Cynara
+
+#endif /* SRC_SERVICE_LOGIC_LOGIC_H_ */
diff --git a/src/service/main/Cynara.cpp b/src/service/main/Cynara.cpp
new file mode 100644 (file)
index 0000000..2d4b1b9
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * 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        Cynara.cpp
+ * @author      Lukasz Wojciechowski <l.wojciechow@partner.samsung.com>
+ * @version     1.0
+ * @brief       This file implements main class of cynara service
+ */
+
+#include <stddef.h>
+#include "Cynara.h"
+
+namespace Cynara {
+
+Cynara::Cynara() : m_logic(nullptr), m_socketManager(nullptr) {
+}
+
+Cynara* Cynara::getInstance(void) {
+    static Cynara instance;
+    return &instance;
+}
+
+Cynara::~Cynara() {
+}
+
+void Cynara::init(void) {
+    getInstance()->m_logic = new Logic();
+    getInstance()->m_socketManager = new SocketManager();
+}
+
+void Cynara::run(void) {
+    getInstance()->m_socketManager->run();
+}
+
+void Cynara::finalize(void) {
+    delete getInstance()->m_socketManager;
+    delete getInstance()->m_logic;
+}
+
+Logic* Cynara::getLogic(void) {
+    return getInstance()->m_logic;
+}
+
+SocketManager* Cynara::getSocketManager(void) {
+    return getInstance()->m_socketManager;
+}
+
+} // namespace Cynara
diff --git a/src/service/main/Cynara.h b/src/service/main/Cynara.h
new file mode 100644 (file)
index 0000000..0d335ac
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * 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        Cynara.h
+ * @author      Lukasz Wojciechowski <l.wojciechow@partner.samsung.com>
+ * @version     1.0
+ * @brief       This file defines main class of cynara service
+ */
+
+#ifndef SRC_SERVICE_MAIN_CYNARA_H_
+#define SRC_SERVICE_MAIN_CYNARA_H_
+
+#include <logic/Logic.h>
+#include <sockets/SocketManager.h>
+
+namespace Cynara {
+
+class Cynara {
+private:
+    Logic *m_logic;
+    SocketManager *m_socketManager;
+
+    Cynara();
+
+    static Cynara* getInstance(void);
+
+public:
+    ~Cynara();
+
+    static void init(void);
+    static void run(void);
+    static void finalize(void);
+
+    static Logic* getLogic(void);
+    static SocketManager* getSocketManager(void);
+
+};
+
+} // namespace Cynara
+
+#endif /* SRC_SERVICE_MAIN_CYNARA_H_ */
index 7a6ffac..cfe17e7 100644 (file)
  * @brief       Main Cynara daemon file
  */
 
-#include <errno.h>
-#include <fcntl.h>
-#include <signal.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/prctl.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include <log/log.h>
+//#include <errno.h>
+#include <exception>
+//#include <fcntl.h>
+//#include <signal.h>
+//#include <stdio.h>
+#include <stdlib.h>
+//#include <string.h>
+//#include <sys/prctl.h>
+//#include <sys/stat.h>
+//#include <sys/types.h>
+//#include <unistd.h>
 
 #include <systemd/sd-journal.h>
 #include <systemd/sd-daemon.h>
 
-// Temporary "exit tool"
-// After implementing the real main we must provide better way to inform daemon
-// about our will.
-static int goodbye = 0;
-
-// Handle kill message from systemd
-// Typically signal SIGTERM is used - depends on configuration in service file
-void kill_handler(int sig) {
-    (void) sig;
-    LOGD("Cynara service is going down now");
-    // As said above, this exitting way should be changed
-    goodbye = 1;
-}
+#include <common.h>
+#include <log/log.h>
+#include "Cynara.h"
 
-int main(int argc, char **argv) {
-    (void) argc;
-    (void) argv;
+using namespace Cynara;
 
+int main(int argc UNUSED, char **argv UNUSED) {
     int ret;
-    struct sigaction act;
-    int it = 0; // TODO: remove me soon
-
-    LOGI("Cynara service is started");
-
-    // Install kill handler - TERM signal will be delivered form systemd to kill this service
-    memset(&act, 0, sizeof(act));
-    act.sa_handler = &kill_handler;
-    if ((ret = sigaction(SIGTERM, &act, NULL)) < 0) {
-        LOGE("sigaction failed [%d]", ret);
-        return 1;
-    }
 
     init_log();
 
-    // Do some initialization here
-    // Now notify systemd that cynara is ready to fulfil its destiny
-    ret = sd_notify(0, "READY=1");
-    if (ret == 0) {
-        LOGW("Cynara was not configured to notify its status");
-    } else if (ret < 0) {
-        LOGE("sd_notify failed [%d]", ret);
+    try {
+        LOGI("Cynara service is starting ...");
+        Cynara::Cynara::init();
+        LOGI("Cynara service is started");
+
+        ret = sd_notify(0, "READY=1");
+        if (ret == 0) {
+            LOGW("Cynara was not configured to notify its status");
+        } else if (ret < 0) {
+            LOGE("sd_notify failed [%d]", ret);
+        }
+
+        LOGD("Starting the real job");
+        Cynara::Cynara::run();
+
+        LOGD("Time to clean up.");
+        Cynara::Cynara::finalize();
+        LOGD("Cynara service is stopped");
+    } catch (std::exception &e) {
+        LOGC("Cynara stoped because of unhandled exception: %s", e.what());
+        return EXIT_FAILURE;
+    } catch (...) {
+        LOGC("Cynara stoped because of unknown unhanndled exception.");
+        return EXIT_FAILURE;
     }
 
-    LOGD("Starting the real job");
-
-    while (!goodbye) {
-        TEMP_FAILURE_RETRY(sleep(1));
-
-        LOGD("Iteration: % 5d", it++);
-        // TODO: remove me soon
-    }
-
-    LOGD("Cynara service is stopped");
-
-    return 0;
+    return EXIT_SUCCESS;
 }
-
diff --git a/src/service/protocol/Protocol.cpp b/src/service/protocol/Protocol.cpp
new file mode 100644 (file)
index 0000000..657dd7b
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * 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        Protocol.cpp
+ * @author      Lukasz Wojciechowski <l.wojciechow@partner.samsung.com>
+ * @version     1.0
+ * @brief       This file implements protocol base class
+ */
+
+#include "Protocol.h"
+
+namespace Cynara {
+
+Protocol::Protocol() {
+}
+
+Protocol::~Protocol() {
+}
+
+} // namespace Cynara
diff --git a/src/service/protocol/Protocol.h b/src/service/protocol/Protocol.h
new file mode 100644 (file)
index 0000000..e0fa8ef
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * 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        Protocol.h
+ * @author      Lukasz Wojciechowski <l.wojciechow@partner.samsung.com>
+ * @version     1.0
+ * @brief       This file defines protocol base class
+ */
+
+#ifndef SRC_SERVICE_PROTOCOL_PROTOCOL_H_
+#define SRC_SERVICE_PROTOCOL_PROTOCOL_H_
+
+#include <common.h>
+#include <request/Request.h>
+
+namespace Cynara {
+
+class Protocol {
+public:
+    Protocol();
+    virtual ~Protocol();
+
+    virtual Request *extractRequestFromBuffer(BinaryQueue &bufferQueue) = 0;
+};
+
+} // namespace Cynara
+
+#endif /* SRC_SERVICE_PROTOCOL_PROTOCOL_H_ */
diff --git a/src/service/protocol/ProtocolAdmin.cpp b/src/service/protocol/ProtocolAdmin.cpp
new file mode 100644 (file)
index 0000000..c130d8c
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * 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        ProtocolAdmin.cpp
+ * @author      Lukasz Wojciechowski <l.wojciechow@partner.samsung.com>
+ * @version     1.0
+ * @brief       This file implements protocol class for administration
+ */
+
+#include <common.h>
+#include "ProtocolAdmin.h"
+
+namespace Cynara {
+
+ProtocolAdmin::ProtocolAdmin() {
+}
+
+ProtocolAdmin::~ProtocolAdmin() {
+}
+
+Request *ProtocolAdmin::extractRequestFromBuffer(BinaryQueue& bufferQueue) {
+    TODO_USE_ME(bufferQueue);
+    return nullptr;
+}
+} // namespace Cynara
diff --git a/src/service/protocol/ProtocolAdmin.h b/src/service/protocol/ProtocolAdmin.h
new file mode 100644 (file)
index 0000000..3ca0769
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * 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        ProtocolAdmin.h
+ * @author      Lukasz Wojciechowski <l.wojciechow@partner.samsung.com>
+ * @version     1.0
+ * @brief       This file defines protocol class for administration
+ */
+
+#ifndef SRC_SERVICE_PROTOCOL_PROTOCOLADMIN_H_
+#define SRC_SERVICE_PROTOCOL_PROTOCOLADMIN_H_
+
+#include "Protocol.h"
+
+namespace Cynara {
+
+class ProtocolAdmin : public Protocol {
+public:
+    ProtocolAdmin();
+    virtual ~ProtocolAdmin();
+
+    virtual Request *extractRequestFromBuffer(BinaryQueue &bufferQueue);
+};
+
+} // namespace Cynara
+
+#endif /* SRC_SERVICE_PROTOCOL_PROTOCOLADMIN_H_ */
diff --git a/src/service/protocol/ProtocolClient.cpp b/src/service/protocol/ProtocolClient.cpp
new file mode 100644 (file)
index 0000000..12dd34f
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * 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        ProtocolClient.cpp
+ * @author      Lukasz Wojciechowski <l.wojciechow@partner.samsung.com>
+ * @version     1.0
+ * @brief       This file implements protocol class for communication with client
+ */
+
+#include <common.h>
+#include "ProtocolClient.h"
+
+namespace Cynara {
+
+ProtocolClient::ProtocolClient() {
+}
+
+ProtocolClient::~ProtocolClient() {
+}
+
+Request *ProtocolClient::extractRequestFromBuffer(BinaryQueue& bufferQueue) {
+    TODO_USE_ME(bufferQueue);
+    return nullptr;
+}
+
+} // namespace Cynara
diff --git a/src/service/protocol/ProtocolClient.h b/src/service/protocol/ProtocolClient.h
new file mode 100644 (file)
index 0000000..f4deae3
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * 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        ProtocolClient.h
+ * @author      Lukasz Wojciechowski <l.wojciechow@partner.samsung.com>
+ * @version     1.0
+ * @brief       This file defines protocol class for communication with client
+ */
+
+#ifndef SRC_SERVICE_PROTOCOL_PROTOCOLCLIENT_H_
+#define SRC_SERVICE_PROTOCOL_PROTOCOLCLIENT_H_
+
+#include "Protocol.h"
+
+namespace Cynara {
+
+class ProtocolClient : public Protocol {
+public:
+    ProtocolClient();
+    virtual ~ProtocolClient();
+
+    virtual Request *extractRequestFromBuffer(BinaryQueue &bufferQueue);
+};
+
+} // namespace Cynara
+
+#endif /* SRC_SERVICE_PROTOCOL_PROTOCOLCLIENT_H_ */
diff --git a/src/service/protocol/ProtocolSignal.cpp b/src/service/protocol/ProtocolSignal.cpp
new file mode 100644 (file)
index 0000000..e20d13f
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * 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        ProtocolSignal.cpp
+ * @author      Lukasz Wojciechowski <l.wojciechow@partner.samsung.com>
+ * @version     1.0
+ * @brief       This file implements protocol class for signals
+ */
+
+#include <common.h>
+#include "ProtocolSignal.h"
+
+namespace Cynara {
+
+ProtocolSignal::ProtocolSignal() {
+}
+
+ProtocolSignal::~ProtocolSignal() {
+}
+
+Request *ProtocolSignal::extractRequestFromBuffer(BinaryQueue& bufferQueue) {
+    TODO_USE_ME(bufferQueue);
+    return nullptr;
+}
+
+} // namespace Cynara
diff --git a/src/service/protocol/ProtocolSignal.h b/src/service/protocol/ProtocolSignal.h
new file mode 100644 (file)
index 0000000..a540052
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * 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        ProtocolSignal.h
+ * @author      Lukasz Wojciechowski <l.wojciechow@partner.samsung.com>
+ * @version     1.0
+ * @brief       This file defines protocol class for signals
+ */
+
+#ifndef SRC_SERVICE_PROTOCOL_PROTOCOLSIGNAL_H_
+#define SRC_SERVICE_PROTOCOL_PROTOCOLSIGNAL_H_
+
+#include "Protocol.h"
+
+namespace Cynara {
+
+class ProtocolSignal : public Protocol {
+public:
+    ProtocolSignal();
+    virtual ~ProtocolSignal();
+
+    virtual Request *extractRequestFromBuffer(BinaryQueue &bufferQueue);
+};
+
+} // namespace Cynara
+
+#endif /* SRC_SERVICE_PROTOCOL_PROTOCOLSIGNAL_H_ */
diff --git a/src/service/request/Request.cpp b/src/service/request/Request.cpp
new file mode 100644 (file)
index 0000000..152447f
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * 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        Request.cpp
+ * @author      Lukasz Wojciechowski <l.wojciechow@partner.samsung.com>
+ * @version     1.0
+ * @brief       This file implements request base class
+ */
+
+#include "Request.h"
+
+namespace Cynara {
+
+Request::Request() {
+}
+
+Request::~Request() {
+}
+
+} // namespace Cynara
diff --git a/src/service/request/Request.h b/src/service/request/Request.h
new file mode 100644 (file)
index 0000000..e0f4465
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * 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        Request.h
+ * @author      Lukasz Wojciechowski <l.wojciechow@partner.samsung.com>
+ * @version     1.0
+ * @brief       This file defines request base class
+ */
+
+#ifndef SRC_SERVICE_REQUEST_REQUEST_H_
+#define SRC_SERVICE_REQUEST_REQUEST_H_
+
+#include <logic/Logic.h>
+#include "RequestContext.h"
+
+namespace Cynara {
+
+class Request {
+public:
+    Request();
+    virtual ~Request();
+
+    virtual void execute(Logic *logic, const RequestContext &context) = 0;
+};
+
+} // namespace Cynara
+
+#endif /* SRC_SERVICE_REQUEST_REQUEST_H_ */
diff --git a/src/service/request/RequestContext.cpp b/src/service/request/RequestContext.cpp
new file mode 100644 (file)
index 0000000..38361ac
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * 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        RequestContext.cpp
+ * @author      Lukasz Wojciechowski <l.wojciechow@partner.samsung.com>
+ * @version     1.0
+ * @brief       This file implements request context class
+ */
+
+#include "RequestContext.h"
+
+namespace Cynara {
+
+RequestContext::RequestContext(int fd) : m_sourceFd(fd) {
+}
+
+} // namespace Cynara
diff --git a/src/service/request/RequestContext.h b/src/service/request/RequestContext.h
new file mode 100644 (file)
index 0000000..75824d2
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * 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        RequestContext.h
+ * @author      Lukasz Wojciechowski <l.wojciechow@partner.samsung.com>
+ * @version     1.0
+ * @brief       This file defines request context class
+ */
+
+#ifndef SRC_SERVICE_REQUEST_REQUESTCONTEXT_H_
+#define SRC_SERVICE_REQUEST_REQUESTCONTEXT_H_
+
+namespace Cynara {
+
+class RequestContext {
+public:
+    RequestContext(int fd);
+
+    int m_sourceFd;
+};
+
+} // namespace Cynara
+
+#endif /* SRC_SERVICE_REQUEST_REQUESTCONTEXT_H_ */
diff --git a/src/service/sockets/Descriptor.cpp b/src/service/sockets/Descriptor.cpp
new file mode 100644 (file)
index 0000000..ca72c71
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * 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        Descriptor.cpp
+ * @author      Lukasz Wojciechowski <l.wojciechow@partner.samsung.com>
+ * @version     1.0
+ * @brief       This file implements descriptor class
+ */
+
+#include "Descriptor.h"
+
+namespace Cynara {
+
+bool Descriptor::isDataToWrite(void) const {
+    return !(m_writeQueue.empty() && m_writeBuffer.empty());
+}
+
+void Descriptor::pushReadBuffer(const RawBuffer &readbuffer) {
+    m_readQueue.appendCopy(readbuffer.data(), readbuffer.size());
+}
+
+Request *Descriptor::extractRequest(void) {
+    return m_protocol->extractRequestFromBuffer(m_readQueue);
+}
+
+RawBuffer &Descriptor::prepareWriteBuffer(void) {
+    size_t queuedDataSize = m_writeQueue.size();
+    size_t bufferDataSize = m_writeBuffer.size();
+
+    m_writeBuffer.resize(queuedDataSize + bufferDataSize);
+    m_writeQueue.flattenConsume(m_writeBuffer.data() + bufferDataSize, queuedDataSize);
+
+    return m_writeBuffer;
+}
+
+void Descriptor::clear(void) {
+    m_readQueue.clear();
+    m_writeQueue.clear();
+    m_writeBuffer.clear();
+    m_protocol = nullptr;
+}
+
+} // namespace Cynara
diff --git a/src/service/sockets/Descriptor.h b/src/service/sockets/Descriptor.h
new file mode 100644 (file)
index 0000000..e3031ac
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * 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        Descriptor.h
+ * @author      Lukasz Wojciechowski <l.wojciechow@partner.samsung.com>
+ * @version     1.0
+ * @brief       This file defines descriptor class
+ */
+
+#ifndef SRC_SERVICE_SOCKETS_DESCRIPTOR_H_
+#define SRC_SERVICE_SOCKETS_DESCRIPTOR_H_
+
+#include <common.h>
+
+#include <protocol/Protocol.h>
+#include <request/Request.h>
+
+namespace Cynara {
+
+class Descriptor {
+private:
+    int m_fd;
+    bool m_listen;
+
+    BinaryQueue m_readQueue;
+    BinaryQueue m_writeQueue;
+    RawBuffer m_writeBuffer;
+
+    Protocol *m_protocol;
+
+public:
+    bool isListen(void) const {
+        return m_listen;
+    }
+
+    bool isDataToWrite(void) const;
+
+    Protocol *protocol(void) {
+        return m_protocol;
+    }
+
+    void setProtocol(Protocol *protocol) {
+        m_protocol = protocol;
+    }
+
+    void setListen(bool listen) {
+        m_listen = listen;
+    }
+
+    void pushReadBuffer(const RawBuffer &readbuffer);
+    Request *extractRequest(void);
+
+    RawBuffer &prepareWriteBuffer(void);
+
+    void clear(void);
+};
+
+} // namespace Cynara
+
+#endif /* SRC_SERVICE_SOCKETS_DESCRIPTOR_H_ */
diff --git a/src/service/sockets/SocketManager.cpp b/src/service/sockets/SocketManager.cpp
new file mode 100644 (file)
index 0000000..8df2586
--- /dev/null
@@ -0,0 +1,348 @@
+/*
+ * 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        SocketManager.cpp
+ * @author      Lukasz Wojciechowski <l.wojciechow@partner.samsung.com>
+ * @version     1.0
+ * @brief       This file implements socket layer manager for cynara
+ */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/select.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/un.h>
+#include <unistd.h>
+
+#include <systemd/sd-daemon.h>
+
+#include <log/log.h>
+#include <common.h>
+#include <exceptions/InitException.h>
+#include <exceptions/UnexpectedErrorException.h>
+
+#include <logic/Logic.h>
+#include <main/Cynara.h>
+#include <protocol/ProtocolAdmin.h>
+#include <protocol/ProtocolClient.h>
+#include <protocol/ProtocolSignal.h>
+
+#include "SocketManager.h"
+
+namespace Cynara {
+
+SocketManager::SocketManager() : m_working(false), m_maxDesc(-1) {
+    FD_ZERO(&m_readSet);
+    FD_ZERO(&m_writeSet);
+}
+
+SocketManager::~SocketManager() {
+}
+
+void SocketManager::run(void) {
+    init();
+    mainLoop();
+}
+
+void SocketManager::init(void) {
+    LOGI("SocketManger init start");
+    const std::string clientSocketPath("/run/cynara/cynara.socket");
+    const std::string adminSocketPath("/run/cynara/cynara-admin.socket");
+    const mode_t clientSocketUMask(0);
+    const mode_t adminSocketUMask(0077);
+
+    createDomainSocket(new ProtocolClient, clientSocketPath, clientSocketUMask);
+    createDomainSocket(new ProtocolAdmin, adminSocketPath, adminSocketUMask);
+    // todo create signal descriptor
+    LOGI("SocketManger init done");
+}
+
+void SocketManager::mainLoop(void) {
+    LOGI("SocketManger mainLoop start");
+    m_working  = true;
+    while (m_working) {
+        fd_set readSet = m_readSet;
+        fd_set writeSet = m_writeSet;
+
+        int ret = select(m_maxDesc + 1, &readSet, &writeSet, nullptr, nullptr);
+
+        if (ret < 0) {
+            switch (errno) {
+            case EINTR:
+                continue;
+            default:
+                int err = errno;
+                throw UnexpectedErrorException(err, strerror(err));
+            }
+        } else if (ret > 0) {
+            for (int i = 0; i < m_maxDesc + 1 && ret; ++i) {
+                if (FD_ISSET(i, &readSet)) {
+                    readyForRead(i);
+                    --ret;
+                }
+                if (FD_ISSET(i, &writeSet)) {
+                    readyForWrite(i);
+                    --ret;
+                }
+            }
+        }
+    }
+    LOGI("SocketManger mainLoop done");
+}
+
+void SocketManager::mainLoopStop(void) {
+    m_working = false;
+}
+
+void SocketManager::readyForRead(int fd) {
+    LOGD("SocketManger readyForRead on fd [%d] start", fd);
+    auto &desc = m_fds[fd];
+    if (desc.isListen()) {
+        readyForAccept(fd);
+        return;
+    }
+
+    RawBuffer readBuffer(DEFAULT_BUFFER_SIZE);
+    ssize_t size = read(fd, readBuffer.data(), DEFAULT_BUFFER_SIZE);
+
+    if (size > 0) {
+        LOGD("read [%zd] bytes", size);
+        readBuffer.resize(size);
+        if (handleRead(fd, readBuffer)) {
+            LOGD("SocketManger readyForRead on fd [%d] successfully done", fd);
+            return;
+        }
+        LOGI("interpreting buffer read from [%d] failed", fd);
+    } else if (size < 0) {
+        int err = errno;
+        switch (err) {
+            case EAGAIN:
+#if EWOULDBLOCK != EAGAIN
+            case EWOULDBLOCK:
+#endif
+            case EINTR:
+                return;
+            default:
+                LOGW("While reading from [%d] socket, error [%d]:<%s>",
+                     fd, err, strerror(err));
+        }
+    } else {
+        LOGN("Socket [%d] closed on other end", fd);
+    }
+    closeSocket(fd);
+    LOGD("SocketManger readyForRead on fd [%d] done", fd);
+}
+
+void SocketManager::readyForWrite(int fd) {
+    LOGD("SocketManger readyForWrite on fd [%d] start", fd);
+    auto &desc = m_fds[fd];
+    auto &buffer = desc.prepareWriteBuffer();
+    size_t size = buffer.size();
+    ssize_t result = write(fd, buffer.data(), 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:
+            LOGD("Error during write to fd [%d]:<%s> ", fd, strerror(err));
+            closeSocket(fd);
+            break;
+        }
+        return; // We do not want to propagate error to next layer
+    }
+
+    LOGD("written [%zd] bytes", result);
+    buffer.erase(buffer.begin(), buffer.begin() + result);
+
+    if (buffer.empty())
+        removeWriteSocket(fd);
+    LOGD("SocketManger readyForWrite on fd [%d] done", fd);
+}
+
+void SocketManager::readyForAccept(int fd) {
+    LOGD("SocketManger readyForAccept on fd [%d] start", fd);
+    struct sockaddr_un clientAddr;
+    unsigned int clientLen = sizeof(clientAddr);
+    int client = accept4(fd, (struct sockaddr*) &clientAddr, &clientLen, SOCK_NONBLOCK);
+    if (client == -1) {
+        int err = errno;
+        LOGW("Error in accept on socket [%d]: <%s>", fd, strerror(err));
+        return;
+    }
+    LOGD("Accept on sock [%d]. New client socket opened [%d]", fd, client);
+
+    auto &description = createDescriptor(client);
+    description.setListen(false);
+    description.setProtocol(m_fds[fd].protocol());
+    addReadSocket(client);
+    LOGD("SocketManger readyForAccept on fd [%d] done", fd);
+}
+
+void SocketManager::closeSocket(int fd) {
+    LOGD("SocketManger closeSocket fd [%d] start", fd);
+    removeReadSocket(fd);
+    removeWriteSocket(fd);
+    m_fds[fd].clear();
+    close(fd);
+    LOGD("SocketManger closeSocket fd [%d] done", fd);
+}
+
+bool SocketManager::handleRead(int fd, const RawBuffer &readbuffer) {
+    LOGD("SocketManger handleRead on fd [%d] start", fd);
+    auto &desc = m_fds[fd];
+    desc.pushReadBuffer(readbuffer);
+
+    try {
+        Request *req = nullptr;
+        for (;;) {
+            req = desc.extractRequest();
+            if (!req)
+                break;
+
+            LOGD("request extracted");
+            req->execute(Cynara::getLogic(), {fd});
+            delete req;
+
+            if (desc.isDataToWrite())
+                    addWriteSocket(fd);
+        }
+    } catch (const Exception &ex) {
+        LOGE("Error handling request <%s>. Closing socket", ex.what());
+        return false;
+    }
+    LOGD("SocketManger handleRead on fd [%d] done", fd);
+    return true;
+}
+
+void SocketManager::createDomainSocket(Protocol *protocol, const std::string &path, mode_t mask) {
+    int fd = getSocketFromSystemD(path);
+    if (fd == -1)
+        fd = createDomainSocketHelp(path, mask);
+
+    auto &desc = createDescriptor(fd);
+    desc.setListen(true);
+    desc.setProtocol(protocol);
+    addReadSocket(fd);
+
+    LOGD("Domain socket: [%d] added.", fd);
+}
+
+int SocketManager::createDomainSocketHelp(const std::string &path, mode_t mask) {
+    int fd;
+
+    if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
+        int err = errno;
+        LOGE("Error during UNIX socket creation: <%s>",  strerror(err));
+        throw InitException();
+    }
+
+    int flags;
+    if ((flags = fcntl(fd, F_GETFL, 0)) == -1)
+        flags = 0;
+    if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) {
+        int err = errno;
+        close(fd);
+        LOGE("Error setting \"O_NONBLOCK\" on descriptor [%d] with fcntl: <%s>",
+             fd, strerror(err));
+        throw InitException();
+    }
+
+    sockaddr_un serverAddress;
+    memset(&serverAddress, 0, sizeof(serverAddress));
+    serverAddress.sun_family = AF_UNIX;
+    if (path.length() > sizeof(serverAddress.sun_path)) {
+        LOGE("Path for unix domain socket <%s> is [%zu] bytes long, while it should be maximum "
+             "[%zu] bytes long", path.c_str(), path.length(), sizeof(serverAddress));
+        throw InitException();
+    }
+    strcpy(serverAddress.sun_path, path.c_str());
+    unlink(serverAddress.sun_path);
+
+    mode_t originalUmask;
+    originalUmask = umask(mask);
+
+    if (bind(fd, (struct sockaddr*)&serverAddress, sizeof(serverAddress)) == -1) {
+        int err = errno;
+        close(fd);
+        LOGE("Error in bind socket descriptor [%d] to path <%s>: <%s>",
+             fd, path.c_str(), strerror(err));
+        throw InitException();
+    }
+
+    umask(originalUmask);
+
+    if (listen(fd, 5) == -1) {
+        int err = errno;
+        close(fd);
+        LOGE("Error setting listen on file descriptor [%d], path <%s>: <%s>",
+             fd, path.c_str(), strerror(err));
+        throw InitException();
+    }
+
+    return fd;
+}
+
+int SocketManager::getSocketFromSystemD(const std::string &path) {
+    int n = sd_listen_fds(0);
+    LOGI("sd_listen_fds returns: [%d]", n);
+    if (n < 0) {
+        LOGE("Error in sd_listend_fds");
+        throw InitException();
+    }
+
+    for (int fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; ++fd) {
+        if (sd_is_socket_unix(fd, SOCK_STREAM, 1, path.c_str(), 0) > 0) {
+            LOGI("Useable socket <%s> was passed by SystemD under descriptor [%d]",
+                    path.c_str(), fd);
+            return fd;
+        }
+    }
+    LOGI("No useable sockets were passed by systemd.");
+    return -1;
+}
+
+Descriptor &SocketManager::createDescriptor(int fd) {
+    if (fd > m_maxDesc) {
+        m_maxDesc = fd;
+        if (fd >= static_cast<int>(m_fds.size()))
+            m_fds.resize(fd + 20);
+    }
+    return m_fds[fd];
+}
+
+void SocketManager::addReadSocket(int fd) {
+    FD_SET(fd, &m_readSet);
+}
+
+void SocketManager::removeReadSocket(int fd) {
+    FD_CLR(fd, &m_readSet);
+}
+
+void SocketManager::addWriteSocket(int fd) {
+    FD_SET(fd, &m_writeSet);
+}
+
+void SocketManager::removeWriteSocket(int fd) {
+    FD_CLR(fd, &m_writeSet);
+}
+
+} // namespace Cynara
diff --git a/src/service/sockets/SocketManager.h b/src/service/sockets/SocketManager.h
new file mode 100644 (file)
index 0000000..72e820a
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * 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        SocketManager.h
+ * @author      Lukasz Wojciechowski <l.wojciechow@partner.samsung.com>
+ * @version     1.0
+ * @brief       This file defines socket layer manager for cynara
+ */
+
+#ifndef SRC_SERVICE_SOCKETS_SOCKETMANAGER_H_
+#define SRC_SERVICE_SOCKETS_SOCKETMANAGER_H_
+
+#include <vector>
+#include <stdio.h>
+
+#include <common.h>
+
+#include "Descriptor.h"
+
+namespace Cynara {
+
+const size_t DEFAULT_BUFFER_SIZE = BUFSIZ;
+
+class SocketManager {
+public:
+    SocketManager();
+    ~SocketManager();
+
+    void run(void);
+    void mainLoopStop(void);
+
+private:
+    typedef std::vector<Descriptor> FDVector;
+    FDVector m_fds;
+
+    bool m_working;
+
+    fd_set m_readSet;
+    fd_set m_writeSet;
+    int m_maxDesc;
+
+    void init(void);
+    void mainLoop(void);
+
+    void readyForRead(int fd);
+    void readyForWrite(int fd);
+    void readyForAccept(int fd);
+    void closeSocket(int fd);
+    bool handleRead(int fd, const RawBuffer &readbuffer);
+
+    void createDomainSocket(Protocol *protocol, const std::string &path, mode_t mask);
+    int createDomainSocketHelp(const std::string &path, mode_t mask);
+    int getSocketFromSystemD(const std::string &path);
+
+    Descriptor &createDescriptor(int fd);
+
+    void addReadSocket(int fd);
+    void removeReadSocket(int fd);
+    void addWriteSocket(int fd);
+    void removeWriteSocket(int fd);
+};
+
+} // namespace Cynara
+
+#endif /* SRC_SERVICE_SOCKETS_SOCKETMANAGER_H_ */
index 050267e..2d1aea4 100644 (file)
@@ -1,5 +1,5 @@
 [Socket]
-ListenStream=/run/cynara/cynara-admin.sock
+ListenStream=/run/cynara/cynara-admin.socket
 SocketMode=0700
 SmackLabelIPIn=@
 SmackLabelIPOut=@
index 2162102..92f4f7f 100644 (file)
@@ -1,5 +1,5 @@
 [Socket]
-ListenStream=/run/cynara/cynara.sock
+ListenStream=/run/cynara/cynara.socket
 SocketMode=0777
 SmackLabelIPIn=@
 SmackLabelIPOut=@