Skip to content

Commit

Permalink
dronecore_server: make a library out of the grpc server
Browse files Browse the repository at this point in the history
* Required for some platforms (e.g. iOS)
* Rename dronecore_server into libdronecore_backend and backend_bin
* Use smart pointers and references instead of pointers
  • Loading branch information
JonasVautherin committed Feb 28, 2018
1 parent 813224a commit f27110e
Show file tree
Hide file tree
Showing 13 changed files with 237 additions and 168 deletions.
2 changes: 1 addition & 1 deletion core/device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -387,7 +387,7 @@ void Device::set_disconnected()
_parent->notify_on_timeout(_target_uuid);

// Let's reset the flag hope again for the next time we see this target.
_target_uuid_initialized = 0;
_target_uuid_initialized = false;
}

{
Expand Down
2 changes: 1 addition & 1 deletion grpc/server/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 2.8.12)
cmake_minimum_required(VERSION 3.1)

project(dronecore-server)

Expand Down
94 changes: 32 additions & 62 deletions grpc/server/src/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,67 +1,33 @@
cmake_minimum_required(VERSION 2.8)
cmake_minimum_required(VERSION 3.1)

file(STRINGS ${PLUGINS_DIR}/plugins.conf PLUGINS_LIST)
set(COMPONENTS_LIST core action mission telemetry)

set(PROTOC_BINARY ${CMAKE_BINARY_DIR}/../default/third_party/protobuf/bin/protoc)
set(GRPC_CPP_PLUGIN_BINARY ${CMAKE_BINARY_DIR}/../default/third_party/grpc/bin/grpc_cpp_plugin)
include(cmake/compile_proto.cmake)

if(NOT EXISTS ${PROTOC_BINARY} OR NOT EXISTS ${GRPC_CPP_PLUGIN_BINARY})
message(FATAL_ERROR "Could not find 'protoc' or 'grpc_cpp_plugin' in the 'default' build folder. Please build for your host first (`make BUILD_DRONECORESERVER=YES default`).")
endif()
foreach(COMPONENT_NAME ${COMPONENTS_LIST})
compile_proto_pb(${COMPONENT_NAME} PB_COMPILED_SOURCE)
list(APPEND PB_COMPILED_SOURCES ${PB_COMPILED_SOURCE})

add_custom_command(OUTPUT core/core.grpc.pb.cc
COMMAND ${PROTOC_BINARY}
-I ${PROTO_DIR}
--grpc_out=.
--plugin=protoc-gen-grpc=${GRPC_CPP_PLUGIN_BINARY}
${PROTO_DIR}/core/core.proto;
)

add_custom_command(OUTPUT core/core.pb.cc
COMMAND ${PROTOC_BINARY}
-I ${PROTO_DIR}
--cpp_out=.
${PROTO_DIR}/core/core.proto
)

foreach(PLUGIN ${PLUGINS_LIST})
add_custom_command(OUTPUT ${PLUGIN}/${PLUGIN}.grpc.pb.cc
COMMAND ${PROTOC_BINARY}
-I ${PROTO_DIR}
--grpc_out=.
--plugin=protoc-gen-grpc=${GRPC_CPP_PLUGIN_BINARY}
--cpp_out=.
${PROTO_DIR}/${PLUGIN}/${PLUGIN}.proto
)
endforeach()

foreach(PLUGIN ${PLUGINS_LIST})
add_custom_command(OUTPUT ${PLUGIN}/${PLUGIN}.pb.cc
COMMAND ${PROTOC_BINARY}
-I ${PROTO_DIR}
--cpp_out=.
${PROTO_DIR}/${PLUGIN}/${PLUGIN}.proto
)
compile_proto_grpc(${COMPONENT_NAME} GRPC_COMPILED_SOURCE)
list(APPEND GRPC_COMPILED_SOURCES ${GRPC_COMPILED_SOURCE})
endforeach()

set(PLUGINS_SRC dronecore_server.cpp core/core.pb.cc core/core.grpc.pb.cc)
foreach(PLUGIN ${PLUGINS_LIST})
list(APPEND PLUGINS_SRC ${PLUGIN}/${PLUGIN}.pb.cc)
list(APPEND PLUGINS_SRC ${PLUGIN}/${PLUGIN}.grpc.pb.cc)
endforeach()

add_executable(dronecore_server ${PLUGINS_SRC})
add_library(backend
backend.cpp
${GRPC_COMPILED_SOURCES}
${PB_COMPILED_SOURCES}
)

target_compile_options(
dronecore_server
PUBLIC
-Wno-unused-parameter
-Wno-shadow
target_link_libraries(backend
dronecore
dronecore_action
dronecore_mission
dronecore_telemetry
gRPC::grpc++
)

target_include_directories(
dronecore_server
PUBLIC
target_include_directories(backend
PRIVATE
${CMAKE_SOURCE_DIR}/core
${CMAKE_SOURCE_DIR}/plugins/action
${CMAKE_SOURCE_DIR}/plugins/mission
Expand All @@ -70,12 +36,16 @@ target_include_directories(
${PLUGINS_DIR}
)

target_link_libraries(
dronecore_server
add_executable(backend_bin
dronecore_server.cpp
)

target_link_libraries(backend_bin
backend
dronecore
dronecore_action
dronecore_mission
dronecore_telemetry
gRPC::grpc++
dl
)

target_include_directories(backend_bin
PRIVATE
${CMAKE_SOURCE_DIR}/core
)
110 changes: 110 additions & 0 deletions grpc/server/src/backend.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
#include "backend.h"

#include <grpc/grpc.h>
#include <grpc++/server.h>
#include <grpc++/server_builder.h>
#include <grpc++/server_context.h>
#include <grpc++/security/server_credentials.h>

#include "action/actionrpc_impl.h"
#include "core/corerpc_impl.h"
#include "log.h"
#include "mission/missionrpc_impl.h"
#include "telemetry/telemetryrpc_impl.h"

namespace dronecore {
namespace backend {

bool DroneCoreBackend::run(const int mavlink_listen_port)
{
if (!connect_to_vehicle(mavlink_listen_port)) {
return false;
}

grpc::ServerBuilder builder;
setup_port(builder);

CoreServiceImpl core(dc);
builder.RegisterService(&core);

Action action(&dc.device());
ActionServiceImpl actionService(action);
builder.RegisterService(&actionService);

Mission mission(&dc.device());
MissionServiceImpl missionService(mission);
builder.RegisterService(&missionService);

Telemetry telemetry(&dc.device());
TelemetryServiceImpl telemetryService(telemetry);
builder.RegisterService(&telemetryService);

server = builder.BuildAndStart();
LogInfo() << "Server started";
server->Wait();

return true;
}

bool DroneCoreBackend::connect_to_vehicle(const int port)
{
if (!add_udp_connection(port)) {
return false;
}

log_uuid_on_timeout();
wait_for_discovery();

return true;
}

bool DroneCoreBackend::add_udp_connection(const int port)
{
dronecore::ConnectionResult connection_result = dc.add_udp_connection(port);

if (connection_result != ConnectionResult::SUCCESS) {
LogErr() << "Connection failed: " << connection_result_str(connection_result);
return false;
}

return true;
}

void DroneCoreBackend::log_uuid_on_timeout()
{
dc.register_on_timeout([](uint64_t uuid) {
LogInfo() << "Device timed out [UUID: " << uuid << "]";
});
}

void DroneCoreBackend::wait_for_discovery()
{
LogInfo() << "Waiting to discover device...";
auto discoveryFuture = wrapped_register_on_discover();
discoveryFuture.wait();
LogInfo() << "Device discovered [UUID: " << discoveryFuture.get() << "]";
}

std::future<uint64_t> DroneCoreBackend::wrapped_register_on_discover()
{
auto promise = std::make_shared<std::promise<uint64_t>>();
auto future = promise->get_future();

dc.register_on_discover([this, promise](uint64_t uuid) {
std::call_once(discovery_flag, [promise, uuid]() {
promise->set_value(uuid);
});
});

return future;
}

void DroneCoreBackend::setup_port(grpc::ServerBuilder &builder)
{
std::string server_address("0.0.0.0:50051");
builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
LogInfo() << "Server set to listen on " << server_address;
}

} // namespace backend
} //namespace dronecore
33 changes: 33 additions & 0 deletions grpc/server/src/backend.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#include <future>
#include <grpc++/server.h>
#include <memory>

#include "dronecore.h"

namespace dronecore {
namespace backend {

class DroneCoreBackend
{
public:
DroneCoreBackend() {}
~DroneCoreBackend() {}

bool run(const int mavlink_listen_port = 14540);

private:
bool connect_to_vehicle(int port);
bool add_udp_connection(int port);
void log_uuid_on_timeout();
void wait_for_discovery();
std::future<uint64_t> wrapped_register_on_discover();

bool run_server();
void setup_port(grpc::ServerBuilder &builder);

dronecore::DroneCore dc;
std::unique_ptr<grpc::Server> server;
};

} // namespace backend
} // namespace dronecore
30 changes: 30 additions & 0 deletions grpc/server/src/cmake/compile_proto.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
set(PROTOC_BINARY ${CMAKE_BINARY_DIR}/../default/third_party/protobuf/bin/protoc)
set(GRPC_CPP_PLUGIN_BINARY ${CMAKE_BINARY_DIR}/../default/third_party/grpc/bin/grpc_cpp_plugin)

if(NOT EXISTS ${PROTOC_BINARY} OR NOT EXISTS ${GRPC_CPP_PLUGIN_BINARY})
message(FATAL_ERROR "Could not find 'protoc' or 'grpc_cpp_plugin' in the 'default' build folder. Please build for your host first (`make BUILD_DRONECORESERVER=YES default`).")
endif()

function(compile_proto_pb COMPONENT_NAME PB_COMPILED_SOURCE)
add_custom_command(OUTPUT ${COMPONENT_NAME}/${COMPONENT_NAME}.pb.cc
COMMAND ${PROTOC_BINARY}
-I ${PROTO_DIR}
--cpp_out=.
${PROTO_DIR}/${COMPONENT_NAME}/${COMPONENT_NAME}.proto
)

set(PB_COMPILED_SOURCE ${COMPONENT_NAME}/${COMPONENT_NAME}.pb.cc PARENT_SCOPE)
endfunction()

function(compile_proto_grpc COMPONENT_NAME GRPC_COMPILED_SOURCES)
add_custom_command(OUTPUT ${COMPONENT_NAME}/${COMPONENT_NAME}.grpc.pb.cc
COMMAND ${PROTOC_BINARY}
-I ${PROTO_DIR}
--grpc_out=.
--plugin=protoc-gen-grpc=${GRPC_CPP_PLUGIN_BINARY}
--cpp_out=.
${PROTO_DIR}/${COMPONENT_NAME}/${COMPONENT_NAME}.proto
)

set(GRPC_COMPILED_SOURCE ${COMPONENT_NAME}/${COMPONENT_NAME}.grpc.pb.cc PARENT_SCOPE)
endfunction()
12 changes: 5 additions & 7 deletions grpc/server/src/core/corerpc_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,16 @@ using namespace dronecore;
class CoreServiceImpl final: public rpc::core::CoreService::Service
{
public:
CoreServiceImpl(DroneCore *dc_obj)
{
dc = dc_obj;
}
CoreServiceImpl(DroneCore &dc)
: dc(dc) {}

Status SubscribeDevices(ServerContext *context,
const rpc::core::SubscribeDevicesRequest *request,
ServerWriter<rpc::core::Device> *writer) override
{
std::vector<uint64_t> list = dc->device_uuids();
std::vector<uint64_t> list = dc.device_uuids();

for (auto uuid : dc->device_uuids()) {
for (auto uuid : dc.device_uuids()) {
auto *rpc_uuid = new rpc::core::UUID();
rpc_uuid->set_value(uuid);

Expand All @@ -34,5 +32,5 @@ class CoreServiceImpl final: public rpc::core::CoreService::Service
}

private:
DroneCore *dc;
DroneCore &dc;
};
Loading

0 comments on commit f27110e

Please sign in to comment.