Initial implementation of Telemetry service

Implemented main application of Telemetry service.
Added ReportManager interface. Added MaxReports and
PollRateResolution properties to ReportManager interface.
Implemented simple logger.

Tested:
 - Built without Yocto and ran on x86 platform with success
 - Added telemetry to romulus image using
   recipe-phosphor/telemetry from meta-phosphor repository
 - Started as service in romulus image in QEMU with success
 - Verified that all added properties are present in dbus

Change-Id: I26af7a19b1f9cac32e9e9da65523d72a36e13855
Signed-off-by: Wludzik, Jozef <jozef.wludzik@intel.com>
Signed-off-by: Krzysztof Grobelny <krzysztof.grobelny@intel.com>
diff --git a/.gitignore b/.gitignore
index b279dca..5fc91fd 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,24 +1,9 @@
-build
+build/
+telemetry
+xyz.openbmc_project.Telemetry.service
 
-# Created by https://www.toptal.com/developers/gitignore/api/visualstudiocode,vim,intellij,cmake
-# Edit at https://www.toptal.com/developers/gitignore?templates=visualstudiocode,vim,intellij,cmake
-
-### CMake ###
-CMakeLists.txt.user
-CMakeCache.txt
-CMakeFiles
-CMakeScripts
-Testing
-Makefile
-cmake_install.cmake
-install_manifest.txt
-compile_commands.json
-CTestTestfile.cmake
-_deps
-
-### CMake Patch ###
-# External projects
-*-prefix/
+# Created by https://www.toptal.com/developers/gitignore/api/vim,intellij,meson,visualstudiocode
+# Edit at https://www.toptal.com/developers/gitignore?templates=vim,intellij,meson,visualstudiocode
 
 ### Intellij ###
 # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
@@ -123,6 +108,29 @@
 # https://plugins.jetbrains.com/plugin/12206-codestream
 .idea/codestream.xml
 
+### Meson ###
+# subproject directories
+/subprojects/*
+!/subprojects/*.wrap
+
+# Meson Directories
+meson-logs
+meson-private
+
+# Meson Files
+meson_benchmark_setup.dat
+meson_test_setup.dat
+sanitycheckcpp.cc     # C++ specific
+sanitycheckcpp.exe    # C++ specific
+
+# Ninja
+build.ninja
+.ninja_deps
+.ninja_logs
+
+# Misc
+compile_commands.json
+
 ### Vim ###
 # Swap
 [._]*.s[a-v][a-z]
@@ -155,5 +163,6 @@
 ### VisualStudioCode Patch ###
 # Ignore all local history of files
 .history
+.ionide
 
-# End of https://www.toptal.com/developers/gitignore/api/visualstudiocode,vim,intellij,cmake
+# End of https://www.toptal.com/developers/gitignore/api/vim,intellij,meson,visualstudiocode
diff --git a/README.md b/README.md
index 97642b9..341be2b 100644
--- a/README.md
+++ b/README.md
@@ -1,9 +1,9 @@
-# MonitoringService #
+# Telemetry #
 This component implements middleware for sensors and metrics aggregation.
 
 
 ## Capabilities ##
-This application is implementation of MonitoringService proposed in design`[1]`.
+This application is implementation of Telemetry proposed in design`[1]`.
 
 It's responsible for:
 - on-demand creation of metric reports,
@@ -19,4 +19,4 @@
 1. [OpenBMC platform telemetry design](https://github.com/openbmc/docs/blob/master/designs/telemetry.md)
 2. [Sensor support for OpenBMC](https://github.com/openbmc/docs/blob/master/architecture/sensor-architecture.md)
 3. [dbus-sensors](https://github.com/openbmc/dbus-sensors)
-4. [Redfish TelemetryService](https://redfish.dmtf.org/schemas/v1/TelemetryService.json)
\ No newline at end of file
+4. [Redfish TelemetryService](https://redfish.dmtf.org/schemas/v1/TelemetryService.json)
diff --git a/meson.build b/meson.build
new file mode 100644
index 0000000..ba126e4
--- /dev/null
+++ b/meson.build
@@ -0,0 +1,77 @@
+project(
+    'Telemetry',
+    'cpp',
+    meson_version: '>=0.55.0',
+    default_options: [
+        'buildtype=debugoptimized',
+        'cpp_std=c++17',
+        'cpp_rtti=false',
+        'warning_level=3',
+        'werror=true',
+        'b_lto=true',
+    ],
+    license: 'Apache-2.0',
+)
+
+cpp = meson.get_compiler('cpp')
+add_project_arguments(
+    cpp.get_supported_arguments([
+        '-DBOOST_ASIO_DISABLE_THREADS',
+        '-DBOOST_ALL_NO_LIB',
+        '-DBOOST_SYSTEM_NO_DEPRECATED',
+        '-DBOOST_ASIO_NO_DEPRECATED',
+        '-DBOOST_NO_RTTI',
+        '-DBOOST_NO_TYPEID',
+        '-Wno-unused-parameter',
+    ]),
+    language: 'cpp'
+)
+
+boost = dependency('boost', version: '>=1.73.0', required: false)
+if not boost.found()
+    subproject('boost', required: false)
+    boost  = declare_dependency(include_directories: 'subprojects/boost_1_73_0')
+endif
+
+phosphor_logging = dependency('phosphor-logging', required: false)
+if not phosphor_logging.found()
+    subproject('phosphor-logging', required: false)
+    phosphor_logging = declare_dependency(
+        include_directories: 'subprojects/phosphor-logging'
+    )
+endif
+
+sdbusplus = dependency('sdbusplus',required : false)
+if not sdbusplus.found()
+  sdbusplus_proj = subproject('sdbusplus', required: true)
+  sdbusplus = sdbusplus_proj.get_variable('sdbusplus_dep')
+endif
+
+systemd = dependency('systemd')
+
+executable(
+    'telemetry',
+    [
+        'src/main.cpp',
+        'src/report_manager.cpp',
+    ],
+    dependencies: [
+        boost,
+        sdbusplus,
+        phosphor_logging,
+    ],
+    include_directories: 'src',
+    install: true,
+    install_dir: get_option('prefix') / get_option('bindir'),
+    pie: true,
+)
+
+configure_file(
+    input: 'xyz.openbmc_project.Telemetry.service.in',
+    output: 'xyz.openbmc_project.Telemetry.service',
+    configuration: {
+        'bindir': get_option('prefix') / get_option('bindir'),
+    },
+    install: true,
+    install_dir: systemd.get_pkgconfig_variable('systemdsystemunitdir'),
+)
diff --git a/src/main.cpp b/src/main.cpp
new file mode 100644
index 0000000..bea8a13
--- /dev/null
+++ b/src/main.cpp
@@ -0,0 +1,37 @@
+#include "telemetry.hpp"
+
+#include <boost/asio/io_context.hpp>
+#include <boost/asio/signal_set.hpp>
+#include <phosphor-logging/log.hpp>
+#include <sdbusplus/asio/connection.hpp>
+
+#include <memory>
+#include <stdexcept>
+
+int main()
+{
+    boost::asio::io_context ioc;
+    boost::asio::signal_set signals(ioc, SIGINT, SIGTERM);
+
+    auto bus = std::make_shared<sdbusplus::asio::connection>(ioc);
+
+    constexpr const char* serviceName = "xyz.openbmc_project.Telemetry";
+    bus->request_name(serviceName);
+
+    signals.async_wait(
+        [&ioc](const boost::system::error_code ec, const int& sig) {
+            if (ec)
+            {
+                throw std::runtime_error("Signal should not be canceled");
+            }
+
+            ioc.stop();
+        });
+
+    phosphor::logging::log<phosphor::logging::level::INFO>(
+        "Telemetry starting");
+    Telemetry app(bus);
+    ioc.run();
+
+    return 0;
+}
diff --git a/src/report_manager.cpp b/src/report_manager.cpp
new file mode 100644
index 0000000..9735abd
--- /dev/null
+++ b/src/report_manager.cpp
@@ -0,0 +1,30 @@
+#include "report_manager.hpp"
+
+#include <system_error>
+
+constexpr const char* reportManagerIfaceName =
+    "xyz.openbmc_project.Telemetry.ReportManager";
+constexpr const char* reportManagerPath =
+    "/xyz/openbmc_project/Telemetry/Reports";
+
+ReportManager::ReportManager(
+    const std::shared_ptr<sdbusplus::asio::object_server>& objServer) :
+    objServer(objServer)
+{
+    reportManagerIntf =
+        objServer->add_interface(reportManagerPath, reportManagerIfaceName);
+
+    reportManagerIntf->register_property_r(
+        "MaxReports", uint32_t{}, sdbusplus::vtable::property_::const_,
+        [](const auto&) { return maxReports; });
+    reportManagerIntf->register_property_r(
+        "MinInterval", uint64_t{}, sdbusplus::vtable::property_::const_,
+        [](const auto&) -> uint64_t { return minInterval.count(); });
+
+    reportManagerIntf->initialize();
+}
+
+ReportManager::~ReportManager()
+{
+    objServer->remove_interface(reportManagerIntf);
+}
diff --git a/src/report_manager.hpp b/src/report_manager.hpp
new file mode 100644
index 0000000..c01c34a
--- /dev/null
+++ b/src/report_manager.hpp
@@ -0,0 +1,25 @@
+#pragma once
+
+#include <sdbusplus/asio/object_server.hpp>
+
+#include <chrono>
+#include <memory>
+#include <vector>
+
+class ReportManager
+{
+  public:
+    ReportManager(
+        const std::shared_ptr<sdbusplus::asio::object_server>& objServer);
+    ~ReportManager();
+
+    ReportManager(const ReportManager&) = delete;
+    ReportManager& operator=(const ReportManager&) = delete;
+
+  private:
+    std::shared_ptr<sdbusplus::asio::object_server> objServer;
+    std::shared_ptr<sdbusplus::asio::dbus_interface> reportManagerIntf;
+
+    static constexpr uint32_t maxReports{20};
+    static constexpr std::chrono::milliseconds minInterval{1000};
+};
diff --git a/src/telemetry.hpp b/src/telemetry.hpp
new file mode 100644
index 0000000..0edcd2d
--- /dev/null
+++ b/src/telemetry.hpp
@@ -0,0 +1,21 @@
+#pragma once
+
+#include "report_manager.hpp"
+
+#include <sdbusplus/asio/connection.hpp>
+#include <sdbusplus/asio/object_server.hpp>
+
+#include <memory>
+
+class Telemetry
+{
+  public:
+    Telemetry(std::shared_ptr<sdbusplus::asio::connection> bus) :
+        objServer(std::make_shared<sdbusplus::asio::object_server>(bus)),
+        reportManager(objServer)
+    {}
+
+  private:
+    std::shared_ptr<sdbusplus::asio::object_server> objServer;
+    ReportManager reportManager;
+};
diff --git a/subprojects/boost.wrap b/subprojects/boost.wrap
new file mode 100644
index 0000000..fa19a76
--- /dev/null
+++ b/subprojects/boost.wrap
@@ -0,0 +1,4 @@
+[wrap-file]
+source_url = https://dl.bintray.com/boostorg/release/1.73.0/source/boost_1_73_0.tar.gz
+source_filename = boost_1_73_0.tar.gz
+source_hash = 9995e192e68528793755692917f9eb6422f3052a53c5e13ba278a228af6c7acf
diff --git a/subprojects/phosphor-logging.wrap b/subprojects/phosphor-logging.wrap
new file mode 100644
index 0000000..a039fcf
--- /dev/null
+++ b/subprojects/phosphor-logging.wrap
@@ -0,0 +1,3 @@
+[wrap-git]
+url = https://github.com/openbmc/phosphor-logging.git
+revision = HEAD
diff --git a/subprojects/sdbusplus.wrap b/subprojects/sdbusplus.wrap
new file mode 100644
index 0000000..d470130
--- /dev/null
+++ b/subprojects/sdbusplus.wrap
@@ -0,0 +1,3 @@
+[wrap-git]
+url = https://github.com/openbmc/sdbusplus.git
+revision = HEAD
diff --git a/xyz.openbmc_project.Telemetry.service.in b/xyz.openbmc_project.Telemetry.service.in
new file mode 100644
index 0000000..2bfde55
--- /dev/null
+++ b/xyz.openbmc_project.Telemetry.service.in
@@ -0,0 +1,12 @@
+[Unit]
+Description=Telemetry
+After=dbus.service
+
+[Service]
+ExecStart=@bindir@/telemetry
+Restart=always
+Type=dbus
+BusName=xyz.openbmc_project.Telemetry
+
+[Install]
+WantedBy=multi-user.target