Skip to content
Open
22 changes: 15 additions & 7 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,34 @@ cmake_minimum_required(VERSION 3.12)

project(
clips_protobuf
VERSION 0.9.0
VERSION 1.0.0
DESCRIPTION "Read and write protobuf messages from within CLIPS")

include(GNUInstallDirs)

find_package(Protobuf REQUIRED)
find_package(ProtobufComm REQUIRED)
find_package(spdlog REQUIRED)
include(FindPkgConfig)
pkg_check_modules(clipsmm REQUIRED IMPORTED_TARGET clipsmm-1.0)
find_package(clips REQUIRED)
add_library(clips_protobuf SHARED src/communicator.cpp)
target_link_libraries(
clips_protobuf protobuf::libprotobuf ProtobufComm::protobuf_comm
PkgConfig::clipsmm spdlog::spdlog)
target_include_directories(
clips_protobuf PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
ClipsNS::libclips_ns spdlog::spdlog)
#target_include_directories(
# clips_protobuf PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
target_include_directories(clips_protobuf
PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include/>
$<INSTALL_INTERFACE:include/>)
target_include_directories(clips_protobuf
INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include/>
$<INSTALL_INTERFACE:include/>)
target_compile_definitions(
clips_protobuf PRIVATE SHAREDIR="${CMAKE_INSTALL_FULL_DATADIR}/clips")
set_target_properties(clips_protobuf PROPERTIES SOVERSION
${PROJECT_VERSION_MAJOR})
set_property(TARGET clips_protobuf PROPERTY CXX_STANDARD 20)

install(
TARGETS clips_protobuf
Expand Down Expand Up @@ -49,7 +57,7 @@ install(FILES cmake/ClipsProtobufConfig.cmake
${CMAKE_CURRENT_BINARY_DIR}/ClipsProtobufConfigVersion.cmake
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/ClipsProtobuf)

set(PKG_CONFIG_REQUIRES "protobuf protobuf_comm spdlog clipsmm-1.0")
set(PKG_CONFIG_REQUIRES "protobuf protobuf_comm spdlog")

configure_file(clips_protobuf.pc.in
${CMAKE_CURRENT_BINARY_DIR}/clips_protobuf.pc @ONLY)
Expand Down
3 changes: 1 addition & 2 deletions cmake/ClipsProtobufConfig.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,5 @@ include(CMakeFindDependencyMacro)
find_dependency(Protobuf)
find_dependency(ProtobufComm)
find_dependency(spdlog)
include(FindPkgConfig)
pkg_check_modules(clipsmm REQUIRED IMPORTED_TARGET clipsmm-1.0)
find_dependency(clips)
include("${CMAKE_CURRENT_LIST_DIR}/ClipsProtobufTargets.cmake")
304 changes: 146 additions & 158 deletions include/clips_protobuf/communicator.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@

#include <protobuf_comm/server.h>

#include <clipsmm.h>
#include <clips_ns/clips.h>
#include <list>
#include <map>
#include <mutex>
Expand All @@ -56,182 +56,170 @@ class Logger;

namespace protobuf_clips {

class ClipsProtobufCommunicator
{
class ClipsProtobufCommunicator {
public:
ClipsProtobufCommunicator(CLIPS::Environment *env, std::mutex &env_mutex);
ClipsProtobufCommunicator(CLIPS::Environment * env,
std::mutex & env_mutex,
std::vector<std::string> &proto_path);
~ClipsProtobufCommunicator();
ClipsProtobufCommunicator(clips::Environment *env, std::mutex &env_mutex);
ClipsProtobufCommunicator(clips::Environment *env, std::mutex &env_mutex,
std::vector<std::string> &proto_path);
~ClipsProtobufCommunicator();

void enable_server(int port);
void disable_server();
void enable_server(int port);
void disable_server();

/** Get Protobuf server.
/** Get Protobuf server.
* @return protobuf server */
protobuf_comm::ProtobufStreamServer *
server() const
{
return server_;
}
protobuf_comm::ProtobufStreamServer *server() const { return server_; }

/** Get protobuf_comm peers.
/** Get protobuf_comm peers.
* @return protobuf_comm peer */
const std::map<long int, protobuf_comm::ProtobufBroadcastPeer *> &
peers() const
{
return peers_;
}
const std::map<long int, protobuf_comm::ProtobufBroadcastPeer *> &
peers() const {
return peers_;
}

/** Get the communicator's message register.
/** Get the communicator's message register.
* @return message register */
protobuf_comm::MessageRegister &
message_register()
{
return *message_register_;
}
protobuf_comm::MessageRegister &message_register() {
return *message_register_;
}

/** Signal invoked for a message that has been sent to a server client.
/** Signal invoked for a message that has been sent to a server client.
* @return signal
*/
boost::signals2::signal<void(protobuf_comm::ProtobufStreamServer::ClientID,
std::shared_ptr<google::protobuf::Message>)> &
signal_server_sent()
{
return sig_server_sent_;
}

/** Signal invoked for a message that has been sent to a client.
boost::signals2::signal<void(protobuf_comm::ProtobufStreamServer::ClientID,
std::shared_ptr<google::protobuf::Message>)> &
signal_server_sent() {
return sig_server_sent_;
}

/** Signal invoked for a message that has been sent to a client.
* @return signal
*/
boost::signals2::signal<
void(std::string, unsigned short, std::shared_ptr<google::protobuf::Message>)> &
signal_client_sent()
{
return sig_client_sent_;
}

/** Signal invoked for a message that has been sent via broadcast.
boost::signals2::signal<void(std::string, unsigned short,
std::shared_ptr<google::protobuf::Message>)> &
signal_client_sent() {
return sig_client_sent_;
}

/** Signal invoked for a message that has been sent via broadcast.
* @return signal
*/
boost::signals2::signal<void(long, std::shared_ptr<google::protobuf::Message>)> &
signal_peer_sent()
{
return sig_peer_sent_;
}
boost::signals2::signal<void(long,
std::shared_ptr<google::protobuf::Message>)> &
signal_peer_sent() {
return sig_peer_sent_;
}

private:
void setup_clips();

CLIPS::Value clips_pb_register_type(std::string full_name);
CLIPS::Values clips_pb_field_names(void *msgptr);
CLIPS::Value clips_pb_has_field(void *msgptr, std::string field_name);
CLIPS::Value clips_pb_field_value(void *msgptr, std::string field_name);
CLIPS::Value clips_pb_field_type(void *msgptr, std::string field_name);
CLIPS::Value clips_pb_field_label(void *msgptr, std::string field_name);
CLIPS::Values clips_pb_field_list(void *msgptr, std::string field_name);
CLIPS::Value clips_pb_field_is_list(void *msgptr, std::string field_name);
CLIPS::Value clips_pb_create(std::string full_name);
CLIPS::Value clips_pb_ref(void *msgptr);
void clips_pb_destroy(void *msgptr);
void clips_pb_set_field(void *msgptr, std::string field_name, CLIPS::Value value);
void clips_pb_add_list(void *msgptr, std::string field_name, CLIPS::Value value);
void clips_pb_send(long int client_id, void *msgptr);
std::string clips_pb_tostring(void *msgptr);
long int clips_pb_client_connect(std::string host, int port);
void clips_pb_disconnect(long int client_id);
void clips_pb_broadcast(long int peer_id, void *msgptr);
void clips_pb_enable_server(int port);

long int clips_pb_peer_create(std::string host, int port);
long int clips_pb_peer_create_local(std::string host, int send_port, int recv_port);
long int clips_pb_peer_create_crypto(std::string host,
int port,
std::string crypto_key = "",
std::string cipher = "");
long int clips_pb_peer_create_local_crypto(std::string host,
int send_port,
int recv_port,
std::string crypto_key = "",
std::string cipher = "");
void clips_pb_peer_destroy(long int peer_id);
void clips_pb_peer_setup_crypto(long int peer_id, std::string crypto_key, std::string cipher);

typedef enum { CT_SERVER, CT_CLIENT, CT_PEER } ClientType;
void clips_assert_message(std::pair<std::string, unsigned short> & endpoint,
uint16_t comp_id,
uint16_t msg_type,
std::shared_ptr<google::protobuf::Message> &msg,
ClientType ct,
long int client_id = 0);
void handle_server_client_connected(protobuf_comm::ProtobufStreamServer::ClientID client,
boost::asio::ip::tcp::endpoint & endpoint);
void handle_server_client_disconnected(protobuf_comm::ProtobufStreamServer::ClientID client,
const boost::system::error_code & error);

void handle_server_client_msg(protobuf_comm::ProtobufStreamServer::ClientID client,
uint16_t component_id,
uint16_t msg_type,
std::shared_ptr<google::protobuf::Message> msg);

void handle_server_client_fail(protobuf_comm::ProtobufStreamServer::ClientID client,
uint16_t component_id,
uint16_t msg_type,
std::string msg);

void handle_peer_msg(long int peer_id,
boost::asio::ip::udp::endpoint & endpoint,
uint16_t component_id,
uint16_t msg_type,
std::shared_ptr<google::protobuf::Message> msg);
void handle_peer_recv_error(long int peer_id,
boost::asio::ip::udp::endpoint &endpoint,
std::string msg);
void handle_peer_send_error(long int peer_id, std::string msg);

void handle_client_connected(long int client_id);
void handle_client_disconnected(long int client_id, const boost::system::error_code &error);
void handle_client_msg(long int client_id,
uint16_t comp_id,
uint16_t msg_type,
std::shared_ptr<google::protobuf::Message> msg);
void handle_client_receive_fail(long int client_id,
uint16_t comp_id,
uint16_t msg_type,
std::string msg);

static std::string to_string(const CLIPS::Value &v);
void setup_clips();

clips::UDFValue clips_pb_register_type(std::string full_name);
clips::UDFValue clips_pb_field_names(void *msgptr);
clips::UDFValue clips_pb_has_field(void *msgptr, std::string field_name);
clips::UDFValue clips_pb_field_value(void *msgptr, std::string field_name);
clips::UDFValue clips_pb_field_type(void *msgptr, std::string field_name);
clips::UDFValue clips_pb_field_label(void *msgptr, std::string field_name);
clips::UDFValue clips_pb_field_list(void *msgptr, std::string field_name);
clips::UDFValue clips_pb_field_is_list(void *msgptr, std::string field_name);
clips::UDFValue clips_pb_create(std::string full_name);
clips::UDFValue clips_pb_ref(void *msgptr);
void clips_pb_destroy(void *msgptr);
void clips_pb_set_field(void *msgptr, std::string field_name,
clips::UDFValue value);
void clips_pb_add_list(void *msgptr, std::string field_name,
clips::UDFValue value);
void clips_pb_send(long int client_id, void *msgptr);
std::string clips_pb_tostring(void *msgptr);
long int clips_pb_client_connect(std::string host, int port);
void clips_pb_disconnect(long int client_id);
void clips_pb_broadcast(long int peer_id, void *msgptr);

long int clips_pb_peer_create(std::string host, int port);
long int clips_pb_peer_create_local(std::string host, int send_port,
int recv_port);
long int clips_pb_peer_create_crypto(std::string host, int port,
std::string crypto_key = "",
std::string cipher = "");
long int clips_pb_peer_create_local_crypto(std::string host, int send_port,
int recv_port,
std::string crypto_key = "",
std::string cipher = "");
void clips_pb_peer_destroy(long int peer_id);
void clips_pb_peer_setup_crypto(long int peer_id, std::string crypto_key,
std::string cipher);

typedef enum { CT_SERVER, CT_CLIENT, CT_PEER } ClientType;
void clips_assert_message(std::pair<std::string, unsigned short> &endpoint,
uint16_t comp_id, uint16_t msg_type,
std::shared_ptr<google::protobuf::Message> &msg,
ClientType ct, long int client_id = 0);
void handle_server_client_connected(
protobuf_comm::ProtobufStreamServer::ClientID client,
boost::asio::ip::tcp::endpoint &endpoint);
void handle_server_client_disconnected(
protobuf_comm::ProtobufStreamServer::ClientID client,
const boost::system::error_code &error);

void
handle_server_client_msg(protobuf_comm::ProtobufStreamServer::ClientID client,
uint16_t component_id, uint16_t msg_type,
std::shared_ptr<google::protobuf::Message> msg);

void handle_server_client_fail(
protobuf_comm::ProtobufStreamServer::ClientID client,
uint16_t component_id, uint16_t msg_type, std::string msg);

void handle_peer_msg(long int peer_id,
boost::asio::ip::udp::endpoint &endpoint,
uint16_t component_id, uint16_t msg_type,
std::shared_ptr<google::protobuf::Message> msg);
void handle_peer_recv_error(long int peer_id,
boost::asio::ip::udp::endpoint &endpoint,
std::string msg);
void handle_peer_send_error(long int peer_id, std::string msg);

void handle_client_connected(long int client_id);
void handle_client_disconnected(long int client_id,
const boost::system::error_code &error);
void handle_client_msg(long int client_id, uint16_t comp_id,
uint16_t msg_type,
std::shared_ptr<google::protobuf::Message> msg);
void handle_client_receive_fail(long int client_id, uint16_t comp_id,
uint16_t msg_type, std::string msg);

static std::string to_string(const clips::UDFValue &v);

private:
CLIPS::Environment *clips_;
std::mutex & clips_mutex_;

protobuf_comm::MessageRegister * message_register_;
protobuf_comm::ProtobufStreamServer *server_;

boost::signals2::signal<void(protobuf_comm::ProtobufStreamServer::ClientID,
std::shared_ptr<google::protobuf::Message>)>
sig_server_sent_;
boost::signals2::signal<
void(std::string, unsigned short, std::shared_ptr<google::protobuf::Message>)>
sig_client_sent_;
boost::signals2::signal<void(long int, std::shared_ptr<google::protobuf::Message>)>
sig_peer_sent_;

std::mutex map_mutex_;
long int next_client_id_;

std::map<long int, protobuf_comm::ProtobufStreamServer::ClientID> server_clients_;
typedef std::map<protobuf_comm::ProtobufStreamServer::ClientID, long int> RevServerClientMap;
RevServerClientMap rev_server_clients_;
std::map<long int, protobuf_comm::ProtobufStreamClient *> clients_;
std::map<long int, protobuf_comm::ProtobufBroadcastPeer *> peers_;

std::map<long int, std::pair<std::string, unsigned short>> client_endpoints_;

std::list<std::string> functions_;
CLIPS::Fact::pointer avail_fact_;
clips::Environment *clips_;
std::mutex &clips_mutex_;

protobuf_comm::MessageRegister *message_register_;
protobuf_comm::ProtobufStreamServer *server_;

boost::signals2::signal<void(protobuf_comm::ProtobufStreamServer::ClientID,
std::shared_ptr<google::protobuf::Message>)>
sig_server_sent_;
boost::signals2::signal<void(std::string, unsigned short,
std::shared_ptr<google::protobuf::Message>)>
sig_client_sent_;
boost::signals2::signal<void(long int,
std::shared_ptr<google::protobuf::Message>)>
sig_peer_sent_;

std::mutex map_mutex_;
long int next_client_id_;

std::map<long int, protobuf_comm::ProtobufStreamServer::ClientID>
server_clients_;
typedef std::map<protobuf_comm::ProtobufStreamServer::ClientID, long int>
RevServerClientMap;
RevServerClientMap rev_server_clients_;
std::map<long int, protobuf_comm::ProtobufStreamClient *> clients_;
std::map<long int, protobuf_comm::ProtobufBroadcastPeer *> peers_;

std::map<long int, std::pair<std::string, unsigned short>> client_endpoints_;

std::list<std::string> functions_;
};

} // end namespace protobuf_clips
Expand Down
Loading