Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sync with eclipse-ecal #53

Merged
merged 1 commit into from
Apr 3, 2024
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
18 changes: 18 additions & 0 deletions ecal/core/include/ecal/ecal_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,14 @@ namespace eCAL
**/
ECAL_API explicit CServiceClient(const std::string& service_name_);

/**
* @brief Constructor.
*
* @param service_name_ Unique service name.
* @param method_information_map_ Map of method names and corresponding datatype information.
**/
ECAL_API explicit CServiceClient(const std::string& service_name_, const ServiceMethodInformationMapT& method_information_map_);

/**
* @brief Destructor.
**/
Expand All @@ -80,6 +88,16 @@ namespace eCAL
**/
ECAL_API bool Create(const std::string& service_name_);

/**
* @brief Creates this object.
*
* @param service_name_ Unique service name.
* @param method_information_map_ Map of method names and corresponding datatype information.
*
* @return True if successful.
**/
ECAL_API bool Create(const std::string& service_name_, const ServiceMethodInformationMapT& method_information_map_);

/**
* @brief Destroys this object.
*
Expand Down
4 changes: 4 additions & 0 deletions ecal/core/include/ecal/ecal_service_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,12 @@
#pragma once

#include <ecal/cimpl/ecal_service_info_cimpl.h>
#include <ecal/ecal_types.h>

#include <functional>
#include <string>
#include <vector>
#include <map>

namespace eCAL
{
Expand Down Expand Up @@ -70,4 +72,6 @@ namespace eCAL
* @param service_response_ Service response struct containing the (responding) server informations and the response itself.
**/
using ResponseCallbackT = std::function<void (const struct SServiceResponse &)>;

using ServiceMethodInformationMapT = std::map<std::string, SServiceMethodInformation>;
}
56 changes: 53 additions & 3 deletions ecal/core/include/ecal/msg/protobuf/client.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@

#include <ecal/ecal_deprecate.h>
#include <ecal/ecal_client.h>
#include <ecal/msg/protobuf/ecal_proto_hlp.h>
#include <ecal/msg/dynamic.h>
#include <ecal/msg/protobuf/ecal_proto_dyn.h>



// protobuf includes
#ifdef _MSC_VER
Expand All @@ -39,6 +42,8 @@

// stl includes
#include <string>
#include <functional>
#include <map>

namespace eCAL
{
Expand All @@ -57,7 +62,13 @@ namespace eCAL
**/
CServiceClient()
{
Create(T::descriptor()->full_name());
// As google::protobuf::Service::GetDescriptor() is defined in a protected class scope
// we need to inherit public from T in order to make the method accessible in our code.
struct U : T {};
std::shared_ptr<U> service = std::make_shared<U>();
const google::protobuf::ServiceDescriptor* service_descriptor = service->GetDescriptor();

Create(service_descriptor->full_name(), CreateMethodInformationMap());
}

/**
Expand All @@ -67,7 +78,7 @@ namespace eCAL
**/
explicit CServiceClient(const std::string& service_name_)
{
Create(service_name_);
Create(service_name_, CreateMethodInformationMap());
}

/**
Expand Down Expand Up @@ -189,6 +200,45 @@ namespace eCAL

using eCAL::CServiceClient::Call;
using eCAL::CServiceClient::CallAsync;
private:
ServiceMethodInformationMapT CreateMethodInformationMap()
{
// As google::protobuf::Service::GetDescriptor() is defined in a protected class scope
// we need to inherit public from T in order to make the method accessible in our code.
struct U : T {};
std::shared_ptr<U> service = std::make_shared<U>();
const google::protobuf::ServiceDescriptor* service_descriptor = service->GetDescriptor();

std::string error_s;
ServiceMethodInformationMapT method_information_map;
CProtoDynDecoder dyn_decoder;
for (int i = 0; i < service_descriptor->method_count(); ++i)
{
// get method name and descriptor
const google::protobuf::MethodDescriptor* method_descriptor = service_descriptor->method(i);
const std::string method_name = method_descriptor->name();

// get message type names
const std::string request_type_name = method_descriptor->input_type()->name();
const std::string response_type_name = method_descriptor->output_type()->name();

// get message type descriptors
std::string request_type_descriptor;
std::string response_type_descriptor;

dyn_decoder.GetServiceMessageDescFromType(service_descriptor, request_type_name, request_type_descriptor, error_s);
dyn_decoder.GetServiceMessageDescFromType(service_descriptor, response_type_name, response_type_descriptor, error_s);


method_information_map[method_name] = SServiceMethodInformation({
{request_type_name, "proto", request_type_descriptor} ,
{response_type_name, "proto", response_type_descriptor}
});

}

return method_information_map;
}
};
}
}
22 changes: 22 additions & 0 deletions ecal/core/include/ecal/msg/protobuf/ecal_proto_dyn.h
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,8 @@ namespace eCAL
**/
bool GetFileDescriptorFromString(const std::string& proto_string_, google::protobuf::FileDescriptorProto* file_desc_proto_, std::string& error_s_);

bool GetServiceMessageDescFromType(const google::protobuf::ServiceDescriptor* service_desc_, const std::string& type_name_, std::string& type_desc_, std::string& error_s_);

protected:
google::protobuf::DescriptorPool m_descriptor_pool;
google::protobuf::DynamicMessageFactory m_message_factory;
Expand Down Expand Up @@ -415,5 +417,25 @@ namespace eCAL

return (true);
}

inline bool CProtoDynDecoder::GetServiceMessageDescFromType(const google::protobuf::ServiceDescriptor* service_desc_, const std::string& type_name_, std::string& type_desc_, std::string& error_s_)
{
const google::protobuf::FileDescriptor* file_desc = service_desc_->file();
if (file_desc == nullptr) return false;

const std::string file_desc_s = file_desc->DebugString();
google::protobuf::FileDescriptorProto file_desc_proto;
if (!GetFileDescriptorFromString(file_desc_s, &file_desc_proto, error_s_)) return false;

google::protobuf::FileDescriptorSet pset;
google::protobuf::FileDescriptorProto* pdesc = pset.add_file();
pdesc->CopyFrom(file_desc_proto);

const std::shared_ptr<google::protobuf::Message> req_msg(GetProtoMessageFromDescriptorSet(pset, type_name_, error_s_));
if (!req_msg) return false;

type_desc_ = pset.SerializeAsString();
return true;
}
}
}
28 changes: 4 additions & 24 deletions ecal/core/include/ecal/msg/protobuf/server.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,8 @@ namespace eCAL
}

std::string error_s;
CProtoDynDecoder dyn_decoder;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: variable 'dyn_decoder' is not initialized [cppcoreguidelines-init-variables]

Suggested change
CProtoDynDecoder dyn_decoder;
CProtoDynDecoder dyn_decoder = 0;


for (int i = 0; i < service_descriptor->method_count(); ++i)
{
// get method name and descriptor
Expand All @@ -151,8 +153,8 @@ namespace eCAL
// get message type descriptors
std::string input_type_desc;
std::string output_type_desc;
GetServiceMessageDescFromType(service_descriptor, input_type_name, input_type_desc, error_s);
GetServiceMessageDescFromType(service_descriptor, output_type_name, output_type_desc, error_s);
dyn_decoder.GetServiceMessageDescFromType(service_descriptor, input_type_name, input_type_desc, error_s);
dyn_decoder.GetServiceMessageDescFromType(service_descriptor, output_type_name, output_type_desc, error_s);

// store descriptions
AddDescription(method_name, input_type_name, input_type_desc, output_type_name, output_type_desc);
Expand Down Expand Up @@ -212,28 +214,6 @@ namespace eCAL
return 0;
};

bool GetServiceMessageDescFromType(const google::protobuf::ServiceDescriptor* service_desc_, const std::string& type_name_, std::string& type_desc_, std::string& error_s_)
{
eCAL::protobuf::CProtoDynDecoder msg_decoder;

const google::protobuf::FileDescriptor* file_desc = service_desc_->file();
if (file_desc == nullptr) return false;

std::string file_desc_s = file_desc->DebugString();
google::protobuf::FileDescriptorProto file_desc_proto;
if (!msg_decoder.GetFileDescriptorFromString(file_desc_s, &file_desc_proto, error_s_)) return false;

google::protobuf::FileDescriptorSet pset;
google::protobuf::FileDescriptorProto* pdesc = pset.add_file();
pdesc->CopyFrom(file_desc_proto);

std::shared_ptr<google::protobuf::Message> req_msg(msg_decoder.GetProtoMessageFromDescriptorSet(pset, type_name_, error_s_));
if (!req_msg) return false;

type_desc_ = pset.SerializeAsString();
return true;
}

std::shared_ptr<T> m_service;
std::map<std::string, const google::protobuf::MethodDescriptor*> m_methods;

Expand Down
2 changes: 2 additions & 0 deletions ecal/core/include/ecal/types/monitoring.h
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,8 @@ namespace eCAL
std::string sname; //<! service name
std::string sid; //<! service id

std::vector<SMethodMon> methods; //<! list of methods

uint32_t version{0}; //<! client protocol version
};

Expand Down
1 change: 0 additions & 1 deletion ecal/core/src/ecal_process.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,6 @@ namespace eCAL
std::stringstream sstream;
sstream << "------------------------- SYSTEM ---------------------------------" << '\n';
sstream << "Version : " << ECAL_VERSION << " (" << ECAL_DATE << ")" << '\n';
sstream << "Runtime Version : " << eCAL::GetVersionString() << " (" << eCAL::GetVersionDateString() << ")" << '\n';
#ifdef ECAL_OS_WINDOWS
#ifdef _WIN64
sstream << "Platform : x64" << '\n';
Expand Down
12 changes: 12 additions & 0 deletions ecal/core/src/monitoring/ecal_monitoring_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -522,6 +522,18 @@ namespace eCAL

// update flexible content
ClientInfo.rclock++;
ClientInfo.methods.clear();
for (const auto& sample_client_method : sample_.client.methods)
{
struct Monitoring::SMethodMon method;
method.mname = sample_client_method.mname;
method.req_type = sample_client_method.req_type;
method.req_desc = sample_client_method.req_desc;
method.resp_type = sample_client_method.resp_type;
method.resp_desc = sample_client_method.resp_desc;
method.call_count = sample_client_method.call_count;
ClientInfo.methods.push_back(method);
}

return(true);
}
Expand Down
4 changes: 4 additions & 0 deletions ecal/core/src/serialization/ecal_serialize_monitoring.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,8 @@ namespace
eCAL::nanopb::encode_string(pb_client_.sname, client_.sname);
// sid
eCAL::nanopb::encode_string(pb_client_.sid, client_.sid);
// methods
encode_mon_service_methods(pb_client_.methods, client_.methods);
// version
pb_client_.version = client_.version;
}
Expand Down Expand Up @@ -805,6 +807,8 @@ namespace
eCAL::nanopb::decode_string(pb_client_.sname, client_.sname);
// sid
eCAL::nanopb::decode_string(pb_client_.sid, client_.sid);
// methods
decode_mon_service_methods(pb_client_.methods, client_.methods);
}

void AssignValues(const eCAL_pb_Client& pb_client_, eCAL::Monitoring::SClientMon& client_)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,8 @@ namespace
eCAL::nanopb::encode_string(pb_sample_.client.sname, registration_.client.sname);
// sid
eCAL::nanopb::encode_string(pb_sample_.client.sid, registration_.client.sid);
// methods
eCAL::nanopb::encode_service_methods(pb_sample_.client.methods, registration_.client.methods);
// version
pb_sample_.client.version = registration_.client.version;

Expand Down Expand Up @@ -304,6 +306,8 @@ namespace
eCAL::nanopb::decode_string(pb_sample_.client.sname, registration_.client.sname);
// sid
eCAL::nanopb::decode_string(pb_sample_.client.sid, registration_.client.sid);
// methods
eCAL::nanopb::decode_service_methods(pb_sample_.client.methods, registration_.client.methods);

///////////////////////////////////////////////
// topic information
Expand Down
1 change: 1 addition & 0 deletions ecal/core/src/serialization/ecal_struct_service.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ namespace eCAL
int32_t pid = 0; // Process id
std::string sname; // Service name
std::string sid; // Service id
std::vector<Method> methods; // List of methods
uint32_t version = 0; // Client protocol version
};
}
Expand Down
8 changes: 6 additions & 2 deletions ecal/core/src/serialization/nanopb/service.pb.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ typedef struct _eCAL_pb_Client {
pb_callback_t sid; /* service id */
/* transport specific parameter (for internal use) */
uint32_t version; /* client protocol version */
pb_callback_t methods; /* list of methods */
} eCAL_pb_Client;


Expand Down Expand Up @@ -106,7 +107,7 @@ extern "C" {
#define eCAL_pb_Response_init_zero {false, eCAL_pb_ServiceHeader_init_zero, {{NULL}, NULL}, 0}
#define eCAL_pb_Method_init_zero {{{NULL}, NULL}, {{NULL}, NULL}, {{NULL}, NULL}, 0, {{NULL}, NULL}, {{NULL}, NULL}}
#define eCAL_pb_Service_init_zero {0, {{NULL}, NULL}, {{NULL}, NULL}, {{NULL}, NULL}, 0, {{NULL}, NULL}, 0, {{NULL}, NULL}, {{NULL}, NULL}, 0, 0}
#define eCAL_pb_Client_init_zero {0, {{NULL}, NULL}, {{NULL}, NULL}, {{NULL}, NULL}, 0, {{NULL}, NULL}, {{NULL}, NULL}, 0}
#define eCAL_pb_Client_init_zero {0, {{NULL}, NULL}, {{NULL}, NULL}, {{NULL}, NULL}, 0, {{NULL}, NULL}, {{NULL}, NULL}, 0, {{NULL}, NULL}}

/* Field tags (for use in manual encoding/decoding) */
#define eCAL_pb_ServiceHeader_hname_tag 1
Expand Down Expand Up @@ -146,6 +147,7 @@ extern "C" {
#define eCAL_pb_Client_sname_tag 6
#define eCAL_pb_Client_sid_tag 7
#define eCAL_pb_Client_version_tag 8
#define eCAL_pb_Client_methods_tag 9

/* Struct field encoding specification for nanopb */
#define eCAL_pb_ServiceHeader_FIELDLIST(X, a) \
Expand Down Expand Up @@ -208,9 +210,11 @@ X(a, CALLBACK, SINGULAR, STRING, uname, 4) \
X(a, STATIC, SINGULAR, INT32, pid, 5) \
X(a, CALLBACK, SINGULAR, STRING, sname, 6) \
X(a, CALLBACK, SINGULAR, STRING, sid, 7) \
X(a, STATIC, SINGULAR, UINT32, version, 8)
X(a, STATIC, SINGULAR, UINT32, version, 8) \
X(a, CALLBACK, REPEATED, MESSAGE, methods, 9)
#define eCAL_pb_Client_CALLBACK pb_default_field_callback
#define eCAL_pb_Client_DEFAULT NULL
#define eCAL_pb_Client_methods_MSGTYPE eCAL_pb_Method

extern const pb_msgdesc_t eCAL_pb_ServiceHeader_msg;
extern const pb_msgdesc_t eCAL_pb_Request_msg;
Expand Down
31 changes: 28 additions & 3 deletions ecal/core/src/service/ecal_service_client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,19 @@ namespace eCAL
Create(service_name_);
}

/**
* @brief Constructor.
*
* @param service_name_ Service name.
* @param method_information_map_ Map of method names and corresponding datatype information.
**/
CServiceClient::CServiceClient(const std::string& service_name_, const ServiceMethodInformationMapT& method_information_map_) :
m_service_client_impl(nullptr),
m_created(false)
{
Create(service_name_, method_information_map_);
}

/**
* @brief Destructor.
**/
Expand All @@ -68,10 +81,22 @@ namespace eCAL
**/
bool CServiceClient::Create(const std::string& service_name_)
{
if(m_created) return(false);
return Create(service_name_, ServiceMethodInformationMapT());
}

/**
* @brief Creates this object.
*
* @param service_name_ Service name.
* @param method_information_map_ Map of method names and corresponding datatype information.
*
* @return True if successful.
**/
bool CServiceClient::Create(const std::string& service_name_, const ServiceMethodInformationMapT& method_information_map_)
{
if (m_created) return(false);

m_service_client_impl = CServiceClientImpl::CreateInstance(service_name_);
m_service_client_impl->Create(service_name_);
m_service_client_impl = CServiceClientImpl::CreateInstance(service_name_, method_information_map_);

// register this client
if (g_clientgate() != nullptr) g_clientgate()->Register(m_service_client_impl.get());
Expand Down
Loading
Loading