From e5bd19f12dcbe2a88734688afc343fd71c65e500 Mon Sep 17 00:00:00 2001 From: NADAL Jean-Baptiste Date: Thu, 14 Nov 2019 15:15:31 +0100 Subject: [PATCH] update domo --- .vscode/settings.json | 15 ++++ CMakeLists.txt | 9 +++ build.local.sh | 2 +- src/CMakeLists.txt | 1 + src/broker/nats-broker.cpp | 82 ++++++++++++++++++++- src/broker/nats-broker.h | 5 +- src/main.cpp | 3 + src/server/domo-server.cpp | 29 ++++++-- src/tempo/domo-iot.nats.c | 123 ------------------------------- src/web/handler/exit-handler.cpp | 57 ++++++++++++++ src/web/handler/exit-handler.h | 47 ++++++++++++ src/web/web-server.cpp | 34 ++++++++- src/web/web-server.h | 8 ++ tools/static_analysis.sh | 17 +++++ 14 files changed, 298 insertions(+), 134 deletions(-) create mode 100644 .vscode/settings.json delete mode 100644 src/tempo/domo-iot.nats.c create mode 100644 src/web/handler/exit-handler.cpp create mode 100644 src/web/handler/exit-handler.h create mode 100755 tools/static_analysis.sh diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..55c779c --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,15 @@ +{ + "files.associations": { + "cmath": "cpp", + "cstdarg": "cpp", + "cstdint": "cpp", + "cstdio": "cpp", + "cstdlib": "cpp", + "cstring": "cpp", + "type_traits": "cpp", + "limits": "cpp", + "*.tcc": "cpp", + "cinttypes": "cpp", + "typeinfo": "cpp" + } +} \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 6a5609e..b4df9a0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,3 +13,12 @@ add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../nats.c ${CMAKE_CURRENT_BINARY_DI add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../json-c ${CMAKE_CURRENT_BINARY_DIR}/json-c) add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../civetweb ${CMAKE_CURRENT_BINARY_DIR}/civetweb) add_subdirectory (src) + +add_custom_target (static_analysis + COMMAND echo "Static Analysis ......" + COMMAND ${CMAKE_SOURCE_DIR}/tools/static_analysis.sh ${CMAKE_SOURCE_DIR}/build +) + +add_custom_target (valgrind + COMMAND valgrind --leak-check=full --trace-children=yes --malloc-fill=AE --free-fill=BD --track-origins=yes ${CMAKE_SOURCE_DIR}/build/bin/domo-iot +) diff --git a/build.local.sh b/build.local.sh index 4324035..711afd5 100755 --- a/build.local.sh +++ b/build.local.sh @@ -4,7 +4,7 @@ echo "Clean" rm -rf build/* fi -CMAKE_OPTS="" +CMAKE_OPTS="-DCMAKE_EXPORT_COMPILE_COMMANDS=On" # Options for CIVETWEB CMAKE_OPTS="$CMAKE_OPTS -DCIVETWEB_ENABLE_SERVER_EXECUTABLE=OFF" diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 40b657c..3dbef6c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -17,6 +17,7 @@ file( server/domo-server.cpp broker/nats-broker.cpp web/web-server.cpp + web/handler/exit-handler.cpp ) add_executable (domo-iot ${source_files}) diff --git a/src/broker/nats-broker.cpp b/src/broker/nats-broker.cpp index 35c96c6..270f037 100644 --- a/src/broker/nats-broker.cpp +++ b/src/broker/nats-broker.cpp @@ -23,6 +23,9 @@ * */ +// This is an independent project of an individual developer. Dear PVS-Studio, please check it. +// PVS-Studio Static Code Analyzer for C, C++, C#, and Java: http://www.viva64.com + /*------------------------------- INCLUDES ----------------------------------*/ #include @@ -31,6 +34,20 @@ #include +#define kNatsServerURL "nats.nadal-fr.com" + + +static void onMsg(natsConnection *nc, natsSubscription *sub, natsMsg *msg, void *closure) +{ + printf("Received msg: %s - %.*s\n", + natsMsg_GetSubject(msg), + natsMsg_GetDataLength(msg), + natsMsg_GetData(msg)); + + // Need to destroy the message! + natsMsg_Destroy(msg); +} + /*! ---------------------------------------------------------------------------- * @fn NatsBroker * @@ -54,7 +71,7 @@ NatsBroker::~NatsBroker(void) * * @brief Setup the Broker. */ -int NatsBroker::setup(void) +int NatsBroker::setup(struct event_base *an_event_loop) { natsStatus the_status; @@ -64,7 +81,70 @@ int NatsBroker::setup(void) natsLibevent_Init(); if (natsOptions_Create(&m_opts) != NATS_OK) + the_status = NATS_NO_MEMORY; + the_status = natsOptions_UseGlobalMessageDelivery(m_opts, true); + + // Indicate which loop and callbacks to use once connected. + if (the_status == NATS_OK) + the_status = natsOptions_SetEventLoop(m_opts, (void *)an_event_loop, + natsLibevent_Attach, + natsLibevent_Read, + natsLibevent_Write, + natsLibevent_Detach); + + the_status = natsOptions_SetURL(m_opts, kNatsServerURL); + + if (the_status == NATS_OK) + the_status = natsConnection_Connect(&m_conn, m_opts); + + if (the_status != NATS_OK) + { + nats_PrintLastErrorStack(stderr); + return -1; + } + + return 0; +} + +/*! ---------------------------------------------------------------------------- + * @fn terminate + * + * @brief terminate the connection with the Broker server. + */ +int NatsBroker::terminate(void) +{ + natsSubscription_Destroy(m_sub); + natsConnection_Destroy(m_conn); + natsOptions_Destroy(m_opts); + + nats_Close(); + return 0; +} + +/*! ---------------------------------------------------------------------------- + * @fn connect + * + * @brief connect to the Broker server. + */ +int NatsBroker::connect(void) +{ + natsStatus the_status; + the_status = natsConnection_Connect(&m_conn, m_opts); + + if (the_status == NATS_OK) + the_status = natsConnection_Subscribe(&m_sub, m_conn, "foo", onMsg, NULL); + + // For maximum performance, set no limit on the number of pending messages. + if (the_status == NATS_OK) + the_status = natsSubscription_SetPendingLimits(m_sub, -1, -1); + + // If there was an error, print a stack trace and exit + if (the_status != NATS_OK) + { + nats_PrintLastErrorStack(stderr); + return -1; + } return 0; } diff --git a/src/broker/nats-broker.h b/src/broker/nats-broker.h index 7d89df5..7361e31 100644 --- a/src/broker/nats-broker.h +++ b/src/broker/nats-broker.h @@ -40,7 +40,10 @@ public: NatsBroker(void); ~NatsBroker(void); - int setup(void); + int setup(struct event_base *); + int terminate(void); + + int connect(void); private: natsConnection *m_conn; diff --git a/src/main.cpp b/src/main.cpp index 6221551..4291b1d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -23,6 +23,9 @@ * */ +// This is an independent project of an individual developer. Dear PVS-Studio, please check it. +// PVS-Studio Static Code Analyzer for C, C++, C#, and Java: http://www.viva64.com + /*-------------------------------- INCLUDES ---------------------------------*/ #include diff --git a/src/server/domo-server.cpp b/src/server/domo-server.cpp index de395c7..555d871 100644 --- a/src/server/domo-server.cpp +++ b/src/server/domo-server.cpp @@ -23,12 +23,18 @@ * */ +// This is an independent project of an individual developer. Dear PVS-Studio, please check it. +// PVS-Studio Static Code Analyzer for C, C++, C#, and Java: http://www.viva64.com + /*-------------------------------- INCLUDES ---------------------------------*/ #include #include "domo-server.h" +#define kDocumentRoot "." +#define kPort "8081" + /*! ---------------------------------------------------------------------------- * @fn DomoServer * @@ -54,18 +60,23 @@ DomoServer::~DomoServer(void) */ bool DomoServer::setup(void) { - - if (m_broker.setup()) - { - return false; - } - m_evt_loop = event_base_new(); if (m_evt_loop == NULL) { return false; } + if (m_broker.setup(m_evt_loop)) + { + fprintf(stderr, "Failed to setup the Nats Broker.\n"); + return false; + } + + m_server.setup(kDocumentRoot, kPort, m_evt_loop); + + // TODO + m_broker.connect(); + return true; } @@ -76,6 +87,11 @@ bool DomoServer::setup(void) */ void DomoServer::terminate(void) { + m_broker.terminate(); + + if (m_evt_loop != NULL) + event_base_free(m_evt_loop); + libevent_global_shutdown(); } /*! ---------------------------------------------------------------------------- @@ -85,5 +101,6 @@ void DomoServer::terminate(void) */ int DomoServer::loop(void) { + event_base_dispatch(m_evt_loop); return 0; } diff --git a/src/tempo/domo-iot.nats.c b/src/tempo/domo-iot.nats.c deleted file mode 100644 index a780f9f..0000000 --- a/src/tempo/domo-iot.nats.c +++ /dev/null @@ -1,123 +0,0 @@ -/*! - * domi-iot.cpp - * - * Copyright (c) 2015-2019, NADAL Jean-Baptiste. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - * - * @Author: NADAL Jean-Baptiste - * @Date: 08/11/2019 - * - */ - -/*-------------------------------- INCLUDES ---------------------------------*/ - -#include - -#include - -#include - -static void onMsg(natsConnection *nc, natsSubscription *sub, natsMsg *msg, void *closure) -{ - printf("Received msg: %s - %.*s\n", - natsMsg_GetSubject(msg), - natsMsg_GetDataLength(msg), - natsMsg_GetData(msg)); - - // Need to destroy the message! - natsMsg_Destroy(msg); -} - -/*! ---------------------------------------------------------------------------- - * @fn main - * - * @brief Main function of domo-iot daemon. - */ -int main(int argc, char *argv[]) -{ -// natsConnection *conn = NULL; -// natsOptions *opts = NULL; -// natsSubscription *sub = NULL; -// natsStatus s; -// struct event_base *evLoop = NULL; -// nats_Open(-1); - - printf("Listening on subject 'foo'\n"); - - // One time initialization of things that we need. - //natsLibevent_Init(); - - // Create a loop. - // evLoop = event_base_new(); - // if (evLoop == NULL) - // s = NATS_ERR; - - // if (natsOptions_Create(&opts) != NATS_OK) - // s = NATS_NO_MEMORY; - - s = natsOptions_UseGlobalMessageDelivery(opts, true); - - // Indicate which loop and callbacks to use once connected. - if (s == NATS_OK) - s = natsOptions_SetEventLoop(opts, (void *)evLoop, - natsLibevent_Attach, - natsLibevent_Read, - natsLibevent_Write, - natsLibevent_Detach); - - s = natsOptions_SetURL(opts, "nats.nadal-fr.com"); - - if (s == NATS_OK) - s = natsConnection_Connect(&conn, opts); - - if (s == NATS_OK) - s = natsConnection_Subscribe(&sub, conn, "foo", onMsg, NULL); - - // For maximum performance, set no limit on the number of pending messages. - if (s == NATS_OK) - s = natsSubscription_SetPendingLimits(sub, -1, -1); - - // Run the event loop. - // This call will return when the connection is closed (either after - // receiving all messages, or disconnected and unable to reconnect). - if (s == NATS_OK) - { - event_base_dispatch(evLoop); - } - - // If there was an error, print a stack trace and exit - if (s != NATS_OK) - { - nats_PrintLastErrorStack(stderr); - exit(2); - } - - // Anything that is created need to be destroyed - natsSubscription_Destroy(sub); - natsConnection_Destroy(conn); - natsOptions_Destroy(opts); - - if (evLoop != NULL) - event_base_free(evLoop); - - // To silence reports of memory still in used with valgrind - nats_Close(); - libevent_global_shutdown(); - - printf("done\n"); - return 0; -} diff --git a/src/web/handler/exit-handler.cpp b/src/web/handler/exit-handler.cpp new file mode 100644 index 0000000..9d25bf2 --- /dev/null +++ b/src/web/handler/exit-handler.cpp @@ -0,0 +1,57 @@ +/*! + * web-server.cpp + * + * Copyright (c) 2015-2019, NADAL Jean-Baptiste. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + * + * @Author: NADAL Jean-Baptiste + * @Date: 14/11/2019 + * + */ + +// This is an independent project of an individual developer. Dear PVS-Studio, please check it. +// PVS-Studio Static Code Analyzer for C, C++, C#, and Java: http://www.viva64.com + +/*------------------------------- INCLUDES ----------------------------------*/ + +#include + +#include "exit-handler.h" + +/*! ---------------------------------------------------------------------------- + * @fn ExitHandler + * + * @brief Constructor of the Exit Handler + */ +ExitHandler::ExitHandler(struct event_base *an_evt_loop) : m_evt_loop(an_evt_loop) +{ +} + +/*! ---------------------------------------------------------------------------- + * @fn handleGet + * + * @brief Exit Handler HandleGet method + */ +bool ExitHandler::handleGet(CivetServer *a_server, struct mg_connection *a_conn) +{ + mg_printf(a_conn, + "HTTP/1.1 200 OK\r\nContent-Type: " + "text/plain\r\nConnection: close\r\n\r\n"); + mg_printf(a_conn, "Bye!\n"); + event_base_loopbreak(m_evt_loop); + return true; +} diff --git a/src/web/handler/exit-handler.h b/src/web/handler/exit-handler.h new file mode 100644 index 0000000..3efbc1f --- /dev/null +++ b/src/web/handler/exit-handler.h @@ -0,0 +1,47 @@ +/*! + * web-server.h + * + * Copyright (c) 2015-2019, NADAL Jean-Baptiste. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + * + * @Author: NADAL Jean-Baptiste + * @Date: 14/11/2019 + * + */ + +#ifndef _EXIT_HANDLER_H +#define _EXIT_HANDLER_H + +/*------------------------------- INCLUDES ----------------------------------*/ + +#include "CivetServer.h" + +/*---------------------------------- Deps -----------------------------------*/ + +/*--------------------------------- CLASS ----------------------------------*/ + +class ExitHandler : public CivetHandler +{ +public: + ExitHandler(struct event_base *an_evt_loop); + bool handleGet(CivetServer *a_server, struct mg_connection *a_conn); + +private: + struct event_base *m_evt_loop; +}; + +#endif /* _EXIT_HANDLER_H */ diff --git a/src/web/web-server.cpp b/src/web/web-server.cpp index 9481caa..e85af3a 100644 --- a/src/web/web-server.cpp +++ b/src/web/web-server.cpp @@ -23,17 +23,25 @@ * */ +// This is an independent project of an individual developer. Dear PVS-Studio, please check it. +// PVS-Studio Static Code Analyzer for C, C++, C#, and Java: http://www.viva64.com + /*------------------------------- INCLUDES ----------------------------------*/ +#include "CivetServer.h" + +#include "web/handler/exit-handler.h" + #include "web-server.h" +#define EXIT_URI "/exit" + /*! ---------------------------------------------------------------------------- * @fn WebServer * * @brief Constructor of the Web Server Object. */ - -WebServer::WebServer(void) +WebServer::WebServer(void) : m_server(NULL) { } @@ -45,4 +53,26 @@ WebServer::WebServer(void) WebServer::~WebServer(void) { + delete m_server; +} + +/*! ---------------------------------------------------------------------------- + * @fn setup + * + * @brief Setup the Web server + */ +int WebServer::setup(const char *a_document_root, const char *a_port, struct event_base *an_evt_loop) +{ + std::vector the_options; + + the_options.push_back("document_root"); + the_options.push_back(a_document_root); + the_options.push_back("listening_ports"); + the_options.push_back(a_port); + + m_server = new CivetServer(the_options); + + m_server->addHandler(EXIT_URI, new ExitHandler(an_evt_loop)); + + return 0; } diff --git a/src/web/web-server.h b/src/web/web-server.h index 46c1aa4..c01d545 100644 --- a/src/web/web-server.h +++ b/src/web/web-server.h @@ -28,8 +28,13 @@ /*------------------------------- INCLUDES ----------------------------------*/ +#include + /*---------------------------------- Deps -----------------------------------*/ +class CivetServer; +struct event_base; + /*--------------------------------- CLASS ----------------------------------*/ class WebServer @@ -38,7 +43,10 @@ public: WebServer(void); ~WebServer(void); + int setup(const char *a_document_root, const char *a_port, struct event_base *an_evt_loop); + private: + CivetServer *m_server; }; #endif /* __WEB_SERVER_H */ diff --git a/tools/static_analysis.sh b/tools/static_analysis.sh new file mode 100755 index 0000000..c33d8f4 --- /dev/null +++ b/tools/static_analysis.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash + +BUILD_DIR=$1 + +analyse_file () { + DIRNAME=`dirname $1` + echo "Analyse directory: $DIRNAME" + cd $DIRNAME + pvs-studio-analyzer analyze -o analyse.log --compiler gcc --compiler g++ + plog-converter -a GA:1,2 -t tasklist -o report.tasks analyse.log + echo -e "\n**********************************\n" + cat report.tasks + echo -e "\n**********************************\n" +} + +# Main +find ${BUILD_DIR} -name compile_commands.json | while read file; do analyse_file $file; done