Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,7 @@ endif()
project(up2date-cpp)

# Add sub directories
add_subdirectory(hawkbit)
add_subdirectory(modules)
add_subdirectory(dps)
add_subdirectory(ddi)
add_subdirectory(example)
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

[RITMS UP2DATE](https://ritms.online) is a cloud ready solution for unified software and firmware management. Use this for implementing lifecycle management for the full stack of drivers and firmware of connected devices.

RITMS UP2DATE is based on open and worldwide adopted building blocks, the most important is [Eclipse Hawkbit](https://www.eclipse.org/hawkbit/) which provides open and flexible Direct Device Integration (DDI) API and Management API.
RITMS UP2DATE is based on open and worldwide adopted building blocks, the most important is [Eclipse Hawkbit](https://www.eclipse.org/ddi/) which provides open and flexible Direct Device Integration (DDI) API and Management API.

RITMS UP2DATE extends Eclipse Hawkbit API with zero-cost maintenance device provisioning based on X509 certificates. The Public Key Infrastructure deployed to cloud governs digital certificates to secure end-to-end communications. Devices are automatically provisioned to connect the update service in a secure way.

Expand Down
21 changes: 21 additions & 0 deletions ddi/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
project (ddi LANGUAGES CXX)

set(VCPKG_FEATURE_FLAGS "manifests")
# Add a library with the above sources
file(GLOB SOURCES "src/*.cpp")
add_library(${PROJECT_NAME} ${SOURCES})
add_library(sub::ddi ALIAS ${PROJECT_NAME})

set_target_properties(${PROJECT_NAME} PROPERTIES LINKER_LANGUAGE CXX)

target_include_directories( ${PROJECT_NAME}
PUBLIC ${PROJECT_SOURCE_DIR}/include
)

find_package(RapidJSON CONFIG REQUIRED)

target_link_libraries( ${PROJECT_NAME} PRIVATE
sub::modules
rapidjson
)

4 changes: 4 additions & 0 deletions ddi/include/ddi.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#pragma once

#include "ddi/hawkbit_response.hpp"
#include "ddi/ddi_client.hpp"
76 changes: 76 additions & 0 deletions ddi/include/ddi/ddi_client.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
#pragma once

#include <string>
#include <memory>

#include "hawkbit_event_handler.hpp"

namespace ddi {
// Main class that used for communication with hawkBit
class Client {
public:

// infinity loop
virtual void run() = 0;

virtual ~Client() = default;
};

class AuthRestoreHandler {
public:

virtual void setTLS(const std::string &crt, const std::string &key) = 0;

// should be used full url which contains controllerId
virtual void setEndpoint(const std::string &endpoint) = 0;
// default value for tenant will be inherited for all child classes
virtual void setEndpoint(std::string &hawkbitEndpoint,
const std::string &controllerId, const std::string &tenant = "default") = 0;

virtual void setDeviceToken(const std::string &) = 0;

virtual void setGatewayToken(const std::string &) = 0;

virtual ~AuthRestoreHandler() = default;
};

class AuthErrorHandler {
public:
virtual void onAuthError(std::unique_ptr<AuthRestoreHandler>) = 0;

virtual ~AuthErrorHandler() = default;
};

class DDIClientBuilder {
public:
static std::unique_ptr<DDIClientBuilder> newInstance();

virtual DDIClientBuilder *setDefaultPollingTimeout(int pollingTimeout_) = 0;

virtual DDIClientBuilder *setEventHandler(std::shared_ptr<EventHandler> handler) = 0;

virtual DDIClientBuilder *addHeader(const std::string &, const std::string &) = 0;

virtual DDIClientBuilder *setGatewayToken(const std::string &) = 0;

virtual DDIClientBuilder *setDeviceToken(const std::string &) = 0;

virtual DDIClientBuilder *notVerifyServerCertificate() = 0;

virtual DDIClientBuilder *setHawkbitEndpoint(const std::string &) = 0;

virtual DDIClientBuilder *setAuthErrorHandler(std::shared_ptr<AuthErrorHandler>) = 0;

virtual DDIClientBuilder *setTLS(const std::string &, const std::string &) = 0;

// all child classes will have the same default tenant value
virtual DDIClientBuilder *setHawkbitEndpoint(const std::string &endpoint,
const std::string &controllerId_,
const std::string &tenant_ = "default") = 0;

virtual std::unique_ptr<Client> build() = 0;

virtual ~DDIClientBuilder() = default;
};

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#include <string>
#include <functional>

namespace hawkbit {
namespace ddi {
// This part contains actions that will be given to the EventHandler as callback params
// Do not copy or use these classes outside the handler class

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#include "hawkbit_response.hpp"
#include "hawkbit_actions.hpp"

namespace hawkbit {
namespace ddi {

// user defined event handler for hawkBit client
class EventHandler {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#pragma once

namespace hawkbit {
namespace ddi {
const int HTTP_UNAUTHORIZED = 401;
const int HTTP_OK = 200;
const int HTTP_CREATED = 201;
Expand Down Expand Up @@ -46,12 +46,26 @@ namespace hawkbit {
}
};

class http_lib_error: public std::exception {
class http_lib_error : public std::exception {
std::string message;
public:
http_lib_error(int error_num) {
explicit http_lib_error(int error_num) {
message = "HTTP request error. Error code " + std::to_string(error_num);
}

const char *what() const noexcept override {
return message.c_str();
}
};

// to catch and handle with on auth error handler
class client_initialize_error : public std::exception {
std::string message;
public:
explicit client_initialize_error(const std::string &msg) {
message = "Client not initialized properly: " + msg;
}

const char *what() const noexcept override {
return message.c_str();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#include <map>


namespace hawkbit {
namespace ddi {
class ResponseDeliveryListener {
public:
virtual void onSuccessfulDelivery() = 0;
Expand All @@ -33,7 +33,7 @@ namespace hawkbit {

static std::string executionToString(const Execution &);

virtual Finished getFinished() = 0;
virtual Finished getFinished() = 0;

virtual Execution getExecution() = 0;

Expand Down
27 changes: 13 additions & 14 deletions hawkbit/src/acions_impl.cpp → ddi/src/acions_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@

#include "actions_impl.hpp"
#include "rapidjson/document.h"
#include "hawkbit_client_impl.hpp"
#include "ddi_client_impl.hpp"
#include "utils.hpp"

namespace hawkbit {
namespace ddi {
int CancelAction_::getId() {
return id;
}
Expand All @@ -15,7 +15,7 @@ namespace hawkbit {
return stopId;
}

std::unique_ptr<CancelAction> CancelAction_::fromString(const std::string& body) {
std::unique_ptr<CancelAction> CancelAction_::fromString(const std::string &body) {
rapidjson::Document document;
document.Parse<0>(body.c_str());

Expand Down Expand Up @@ -48,8 +48,8 @@ namespace hawkbit {
throw unexpected_payload();

if (!document.HasMember("id") || !document.HasMember("deployment") ||
!document["deployment"].HasMember("update") || !document["deployment"].HasMember("download")
|| !document["deployment"].HasMember("chunks")) {
!document["deployment"].HasMember("update") || !document["deployment"].HasMember("download")
|| !document["deployment"].HasMember("chunks")) {
throw unexpected_payload();
}

Expand All @@ -68,9 +68,9 @@ namespace hawkbit {
deploymentBase->inMaintenanceWindow = true;
}

const rapidjson::Value& chunks_ = document["deployment"]["chunks"];
const rapidjson::Value &chunks_ = document["deployment"]["chunks"];
for (rapidjson::Value::ConstValueIterator itr = chunks_.Begin(); itr != chunks_.End(); ++itr) {
const rapidjson::Value& chunk = *itr;
const rapidjson::Value &chunk = *itr;
if (!chunk.HasMember("part") || !chunk.HasMember("version") || !chunk.HasMember("name")
|| !chunk.HasMember("artifacts")) {
throw unexpected_payload();
Expand All @@ -83,17 +83,17 @@ namespace hawkbit {
chunkR->version = chunk["version"].GetString();
chunkR->part = chunk["part"].GetString();

const rapidjson::Value& artifacts_ = chunk["artifacts"];
const rapidjson::Value &artifacts_ = chunk["artifacts"];
for (rapidjson::Value::ConstValueIterator itr_a = artifacts_.Begin(); itr_a != artifacts_.End(); ++itr_a) {
const rapidjson::Value& artifact = *itr_a;
const rapidjson::Value &artifact = *itr_a;
if (!artifact.HasMember("filename") || !artifact.HasMember("hashes") || !artifact.HasMember("size")
|| !artifact.HasMember("_links") || !artifact["hashes"].HasMember("sha256")
|| !artifact["hashes"].HasMember("sha1") || !artifact["hashes"].HasMember("md5")
|| !artifact["_links"].HasMember("download-http")) {
|| !artifact.HasMember("_links") || !artifact["hashes"].HasMember("sha256")
|| !artifact["hashes"].HasMember("sha1") || !artifact["hashes"].HasMember("md5")
|| !artifact["_links"].HasMember("download-http")) {
throw unexpected_payload();
}
Hashes hashesR;
auto artifactR = new Artifact_();
auto artifactR = new Artifact_();
auto artifactPtr = std::shared_ptr<Artifact>(artifactR);
artifactR->filename = artifact["filename"].GetString();
artifactR->fileSize = artifact["size"].GetInt();
Expand All @@ -113,7 +113,6 @@ namespace hawkbit {
}



int DeploymentBase_::getId() {
return id;
}
Expand Down
6 changes: 3 additions & 3 deletions hawkbit/src/actions_impl.hpp → ddi/src/actions_impl.hpp
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
#pragma once

#include <memory>
#include "hawkbit/hawkbit_actions.hpp"
#include "ddi/hawkbit_actions.hpp"
#include "uriparse.hpp"
#include "httplib.h"

namespace hawkbit {
namespace ddi {
// Define actions from hawkBit
enum Actions_ {
GET_CONFIG_DATA, CANCEL_ACTION, DEPLOYMENT_BASE,
Expand Down Expand Up @@ -49,7 +49,7 @@ namespace hawkbit {
// used for get httpClient and its Headers
class DownloadProvider {
public:
virtual void downloadTo(uri::URI, const std::string&) = 0;
virtual void downloadTo(uri::URI, const std::string &) = 0;

// get file as string
virtual std::string getBody(uri::URI) = 0;
Expand Down
Loading