diff --git a/CMakeLists.txt b/CMakeLists.txt index fce73d751..f83c1ecc0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -462,6 +462,10 @@ if (VIAMCPPSDK_GRPCXX_VERSION VERSION_LESS 1.32.0) set(VIAMCPPSDK_GRPCXX_LEGACY_FWD 1) endif() +if(VIAMCPPSDK_GRPCXX_VERSION VERSION_LESS 1.43.0) + set(VIAMCPPSDK_GRPCXX_NO_DIRECT_DIAL 1) +endif() + include(FetchContent) FetchContent_Declare( diff --git a/src/viam/api/CMakeLists.txt b/src/viam/api/CMakeLists.txt index 72f03567b..1d8a93d25 100644 --- a/src/viam/api/CMakeLists.txt +++ b/src/viam/api/CMakeLists.txt @@ -228,6 +228,10 @@ if (VIAMCPPSDK_USE_DYNAMIC_PROTOS) ${PROTO_GEN_DIR}/component/switch/v1/switch.grpc.pb.cc ${PROTO_GEN_DIR}/component/switch/v1/switch.grpc.pb.h ${PROTO_GEN_DIR}/component/switch/v1/switch.pb.cc + ${PROTO_GEN_DIR}/proto/rpc/v1/auth.pb.h + ${PROTO_GEN_DIR}/proto/rpc/v1/auth.pb.cc + ${PROTO_GEN_DIR}/proto/rpc/v1/auth.grpc.pb.h + ${PROTO_GEN_DIR}/proto/rpc/v1/auth.grpc.pb.cc ${PROTO_GEN_DIR}/component/switch/v1/switch.pb.h ${PROTO_GEN_DIR}/google/api/annotations.pb.cc ${PROTO_GEN_DIR}/google/api/annotations.pb.h @@ -361,6 +365,8 @@ target_sources(viamapi ${PROTO_GEN_DIR}/component/servo/v1/servo.pb.cc ${PROTO_GEN_DIR}/component/switch/v1/switch.grpc.pb.cc ${PROTO_GEN_DIR}/component/switch/v1/switch.pb.cc + ${PROTO_GEN_DIR}/proto/rpc/v1/auth.grpc.pb.cc + ${PROTO_GEN_DIR}/proto/rpc/v1/auth.pb.cc ${PROTO_GEN_DIR}/google/api/annotations.pb.cc ${PROTO_GEN_DIR}/google/api/http.pb.cc ${PROTO_GEN_DIR}/google/api/httpbody.pb.cc @@ -425,6 +431,8 @@ target_sources(viamapi ${PROTO_GEN_DIR}/../../viam/api/component/servo/v1/servo.pb.h ${PROTO_GEN_DIR}/../../viam/api/component/switch/v1/switch.grpc.pb.h ${PROTO_GEN_DIR}/../../viam/api/component/switch/v1/switch.pb.h + ${PROTO_GEN_DIR}/../../viam/api/proto/rpc/v1/auth.grpc.pb.h + ${PROTO_GEN_DIR}/../../viam/api/proto/rpc/v1/auth.pb.h ${PROTO_GEN_DIR}/../../viam/api/google/api/annotations.pb.h ${PROTO_GEN_DIR}/../../viam/api/google/api/http.pb.h ${PROTO_GEN_DIR}/../../viam/api/google/api/httpbody.pb.h diff --git a/src/viam/examples/camera/example_camera.cpp b/src/viam/examples/camera/example_camera.cpp index 3d7d3c615..03ddb2b59 100644 --- a/src/viam/examples/camera/example_camera.cpp +++ b/src/viam/examples/camera/example_camera.cpp @@ -28,14 +28,14 @@ int main() try { // dial_options.credentials = credentials; // This is for an example. Care should be taken before exercising this option in production. - dial_options.set_allow_insecure_downgrade( - (credentials.type().empty() && credentials.payload().empty())); + dial_options.allow_insecure_downgrade = + (credentials.type().empty() && credentials.payload().empty()); - // Set the refresh interval of the robot (in seconds) (0 = auto refresh) and the dial - // options - vs::Options options = vs::Options(1, dial_options); + // Pass the scheduled refresh interval of the robot (0 seconds = only on config update) and the + // dial options + std::shared_ptr robot = + vs::RobotClient::at_address(robot_address, std::chrono::seconds{1}, dial_options); - std::shared_ptr robot = vs::RobotClient::at_address(robot_address, options); VIAM_SDK_LOG(info) << "Successfully connected to the robot"; std::vector resource_names = robot->resource_names(); diff --git a/src/viam/examples/dial/example_dial.cpp b/src/viam/examples/dial/example_dial.cpp index f48aab7ce..5c9d84fe7 100644 --- a/src/viam/examples/dial/example_dial.cpp +++ b/src/viam/examples/dial/example_dial.cpp @@ -25,14 +25,12 @@ int main() { DialOptions dial_options; std::string type = ""; std::string payload = ""; - Credentials credentials(type, payload); - dial_options.set_credentials(credentials); - boost::optional opts(dial_options); + dial_options.credentials = Credentials(type, payload); std::string address(uri); - Options options(1, opts); // connect to robot, ensure we can refresh it - std::shared_ptr robot = RobotClient::at_address(address, options); + std::shared_ptr robot = + RobotClient::at_address(address, std::chrono::seconds{1}, dial_options); // ensure we can query resources std::vector resource_names = robot->resource_names(); diff --git a/src/viam/examples/dial_api_key/example_dial_api_key.cpp b/src/viam/examples/dial_api_key/example_dial_api_key.cpp index 90f881031..c4c795305 100644 --- a/src/viam/examples/dial_api_key/example_dial_api_key.cpp +++ b/src/viam/examples/dial_api_key/example_dial_api_key.cpp @@ -27,28 +27,30 @@ int main(int argc, char* argv[]) { "uri", po::value(), "URI of robot")( "entity", po::value(), "api key ID")( "api-key", po::value(), "api key secret"); + po::variables_map vm; po::store(po::parse_command_line(argc, argv, desc), vm); + if (vm.count("help")) { std::cout << desc << std::endl; return 0; } - boost::optional opts; + + DialOptions opts; + if (vm.count("entity") && vm.count("api-key")) { - DialOptions dial_options; - dial_options.set_entity(vm["entity"].as()); + opts.auth_entity = vm["entity"].as(); Credentials credentials("api-key", vm["api-key"].as()); - dial_options.set_credentials(credentials); - opts = dial_options; + opts.credentials = credentials; } - Options options(1, opts); // connect to robot, ensure we can refresh it std::shared_ptr robot = - RobotClient::at_address(vm["uri"].as(), options); + RobotClient::at_address(vm["uri"].as(), std::chrono::seconds{1}, opts); // ensure we can query resources std::vector resource_names = robot->resource_names(); + VIAM_SDK_LOG(info) << "Resources:"; for (const Name& resource : resource_names) { VIAM_SDK_LOG(info) << resource; diff --git a/src/viam/examples/mlmodel/example_audio_classification_client.cpp b/src/viam/examples/mlmodel/example_audio_classification_client.cpp index d528e0ab1..7e3b91829 100644 --- a/src/viam/examples/mlmodel/example_audio_classification_client.cpp +++ b/src/viam/examples/mlmodel/example_audio_classification_client.cpp @@ -243,11 +243,11 @@ int main(int argc, char* argv[]) try { // secret. Please see other examples for more details on // connecting to robots with the C++ SDK. viam::sdk::DialOptions dial_options; - dial_options.set_entity(opt_api_key_id.get()); - dial_options.set_credentials(viam::sdk::Credentials("api-key", opt_api_key.get())); + dial_options.auth_entity = opt_api_key_id.get(); + dial_options.credentials = viam::sdk::Credentials("api-key", opt_api_key.get()); - auto robot = - vsdk::RobotClient::at_address(opt_robot_host.get(), {0, {std::move(dial_options)}}); + auto robot = vsdk::RobotClient::at_address( + opt_robot_host.get(), std::chrono::seconds{0}, dial_options); // Obtain a handle to the MLModelService module on the robot. Note that the string // `yamnet_classification_tflite` is arbitrary. It just matches what was used to name the diff --git a/src/viam/examples/modules/complex/client.cpp b/src/viam/examples/modules/complex/client.cpp index 0a1fc102c..b37bb563b 100644 --- a/src/viam/examples/modules/complex/client.cpp +++ b/src/viam/examples/modules/complex/client.cpp @@ -26,9 +26,9 @@ int main() { // any other C++ SDK objects and stays alive until all Viam C++ SDK objects are destroyed. Instance inst; - const char* uri = "http://localhost:8080/"; // replace with your URI if connecting securely + std::string address = "http://localhost:8080/"; // replace with your URI if connecting securely DialOptions dial_options; - dial_options.set_allow_insecure_downgrade(true); // set to false if connecting securely + dial_options.allow_insecure_downgrade = true; // set to false if connecting securely // Uncomment and fill out your credentials details if connecting securely // std::string type = ""; @@ -36,17 +36,15 @@ int main() { // Credentials credentials(type, payload); // dial_options.set_credentials(credentials); - boost::optional opts(dial_options); - std::string address(uri); - Options options(1, opts); - // Register custom gizmo and summation clients so robot client can access resources // of that type from the server. Registry::get().register_resource_client(); Registry::get().register_resource_client(); // Connect to robot. - std::shared_ptr robot = RobotClient::at_address(address, options); + std::shared_ptr robot = + RobotClient::at_address(address, std::chrono::seconds{1}, dial_options); + // Print resources. VIAM_SDK_LOG(info) << "Resources:"; std::vector resource_names = robot->resource_names(); diff --git a/src/viam/examples/modules/complex/gizmo/api.cpp b/src/viam/examples/modules/complex/gizmo/api.cpp index 4059c9034..dbcd6bc1d 100644 --- a/src/viam/examples/modules/complex/gizmo/api.cpp +++ b/src/viam/examples/modules/complex/gizmo/api.cpp @@ -24,12 +24,12 @@ API API::traits::api() { return {"viam", "component", "gizmo"}; } -Gizmo::Gizmo(std::string name) : Component(std::move(name)){}; +Gizmo::Gizmo(std::string name) : Component(std::move(name)) {} /* Gizmo server methods */ GizmoServer::GizmoServer(std::shared_ptr manager) - : ResourceServer(std::move(manager)){}; + : ResourceServer(std::move(manager)) {} grpc::Status GizmoServer::DoOne(grpc::ServerContext* context, const DoOneRequest* request, @@ -169,8 +169,8 @@ grpc::Status GizmoServer::DoTwo(::grpc::ServerContext* context, /* Gizmo client methods */ -GizmoClient::GizmoClient(std::string name, std::shared_ptr channel) - : Gizmo(std::move(name)), stub_(GizmoService::NewStub(channel)), channel_(std::move(channel)){}; +GizmoClient::GizmoClient(std::string name, const ViamChannel& channel) + : Gizmo(std::move(name)), stub_(GizmoService::NewStub(channel.channel())), channel_(&channel) {} bool GizmoClient::do_one(std::string arg1) { return make_client_helper(this, *stub_, &StubType::DoOne) diff --git a/src/viam/examples/modules/complex/gizmo/api.hpp b/src/viam/examples/modules/complex/gizmo/api.hpp index cfebb52d5..82d0f1b0c 100644 --- a/src/viam/examples/modules/complex/gizmo/api.hpp +++ b/src/viam/examples/modules/complex/gizmo/api.hpp @@ -43,7 +43,11 @@ struct API::traits { class GizmoClient : public Gizmo { public: using interface_type = Gizmo; - GizmoClient(std::string name, std::shared_ptr channel); + GizmoClient(std::string name, const ViamChannel& channel); + + const ViamChannel& channel() const { + return *channel_; + } bool do_one(std::string arg1) override; bool do_one_client_stream(std::vector arg1) override; @@ -54,7 +58,7 @@ class GizmoClient : public Gizmo { private: using StubType = GizmoService::StubInterface; std::unique_ptr stub_; - std::shared_ptr channel_; + const ViamChannel* channel_; }; // `GizmoServer` is the gRPC server implementation of a `Gizmo` component. diff --git a/src/viam/examples/modules/complex/summation/api.cpp b/src/viam/examples/modules/complex/summation/api.cpp index cab868ad8..ee125f3cc 100644 --- a/src/viam/examples/modules/complex/summation/api.cpp +++ b/src/viam/examples/modules/complex/summation/api.cpp @@ -24,12 +24,12 @@ API API::traits::api() { return {"viam", "service", "summation"}; } -Summation::Summation(std::string name) : Service(std::move(name)){}; +Summation::Summation(std::string name) : Service(std::move(name)) {} /* Summation server methods */ SummationServer::SummationServer(std::shared_ptr manager) - : ResourceServer(std::move(manager)){}; + : ResourceServer(std::move(manager)) {} grpc::Status SummationServer::Sum(grpc::ServerContext* context, const SumRequest* request, @@ -55,10 +55,10 @@ grpc::Status SummationServer::Sum(grpc::ServerContext* context, /* Summation client methods */ -SummationClient::SummationClient(std::string name, std::shared_ptr channel) +SummationClient::SummationClient(std::string name, const ViamChannel& channel) : Summation(std::move(name)), - stub_(SummationService::NewStub(channel)), - channel_(std::move(channel)){}; + stub_(SummationService::NewStub(channel.channel())), + channel_(&channel) {} double SummationClient::sum(std::vector numbers) { return make_client_helper(this, *stub_, &StubType::Sum) diff --git a/src/viam/examples/modules/complex/summation/api.hpp b/src/viam/examples/modules/complex/summation/api.hpp index 3c4800899..c34a54000 100644 --- a/src/viam/examples/modules/complex/summation/api.hpp +++ b/src/viam/examples/modules/complex/summation/api.hpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include "summation.grpc.pb.h" @@ -43,14 +44,18 @@ struct API::traits { class SummationClient : public Summation { public: using interface_type = Summation; - SummationClient(std::string name, std::shared_ptr channel); + SummationClient(std::string name, const ViamChannel& channel); + + const ViamChannel& channel() const { + return *channel_; + } double sum(std::vector numbers) override; private: using StubType = SummationService::StubInterface; std::unique_ptr stub_; - std::shared_ptr channel_; + const ViamChannel* channel_; }; // `SummationServer` is the gRPC server implementation of a `Summation` diff --git a/src/viam/examples/modules/simple/client.cpp b/src/viam/examples/modules/simple/client.cpp index 75ca90e34..a2433307e 100644 --- a/src/viam/examples/modules/simple/client.cpp +++ b/src/viam/examples/modules/simple/client.cpp @@ -16,9 +16,11 @@ int main() { // any other C++ SDK objects and stays alive until all Viam C++ SDK objects are destroyed. Instance inst; - const char* uri = "http://localhost:8080/"; // replace with your URI if connecting securely + // replace with your URI if connecting securely + std::string address = "http://localhost:8080/"; + DialOptions dial_options; - dial_options.set_allow_insecure_downgrade(true); // set to false if connecting securely + dial_options.allow_insecure_downgrade = true; // set to false if connecting securely // Uncomment and fill out your credentials details if connecting securely // std::string type = ""; @@ -26,11 +28,8 @@ int main() { // Credentials credentials(type, payload); // dial_options.set_credentials(credentials); - boost::optional opts(dial_options); - std::string address(uri); - Options options(1, opts); - - std::shared_ptr robot = RobotClient::at_address(address, options); + std::shared_ptr robot = + RobotClient::at_address(address, std::chrono::seconds{1}, dial_options); // Print resources VIAM_SDK_LOG(info) << "Resources"; diff --git a/src/viam/examples/motor/example_motor.cpp b/src/viam/examples/motor/example_motor.cpp index 80f87dd65..9c9344a6f 100644 --- a/src/viam/examples/motor/example_motor.cpp +++ b/src/viam/examples/motor/example_motor.cpp @@ -41,14 +41,14 @@ int main() try { // dial_options.credentials = credentials; // This is for an example. Care should be taken before exercising this option in production. - dial_options.set_allow_insecure_downgrade( - (credentials.type().empty() && credentials.payload().empty())); + dial_options.allow_insecure_downgrade = + (credentials.type().empty() && credentials.payload().empty()); - // Set the refresh interval of the robot (in seconds) (0 = auto refresh) and the dial - // options - vs::Options options = vs::Options(1, dial_options); + // Pass the scheduled refresh interval of the robot (0 seconds = only on config update) and the + // dial options + std::shared_ptr robot = + vs::RobotClient::at_address(robot_address, std::chrono::seconds{1}, dial_options); - std::shared_ptr robot = vs::RobotClient::at_address(robot_address, options); VIAM_SDK_LOG(info) << "Successfully connected to the robot"; std::vector resource_names = robot->resource_names(); diff --git a/src/viam/sdk/common/client_helper.cpp b/src/viam/sdk/common/client_helper.cpp index dc38fd3e0..2da472121 100644 --- a/src/viam/sdk/common/client_helper.cpp +++ b/src/viam/sdk/common/client_helper.cpp @@ -5,6 +5,7 @@ #include #include +#include #include #include @@ -32,6 +33,12 @@ ClientContext::ClientContext() : wrapped_context_(std::make_uniqueAddMetadata("authorization", "Bearer " + *channel.auth_token()); + } +} + ClientContext::~ClientContext() = default; ClientContext::operator const GrpcClientContext*() const { diff --git a/src/viam/sdk/common/client_helper.hpp b/src/viam/sdk/common/client_helper.hpp index d5e3a8240..828c18691 100644 --- a/src/viam/sdk/common/client_helper.hpp +++ b/src/viam/sdk/common/client_helper.hpp @@ -4,6 +4,7 @@ #include #include #include +#include namespace viam { namespace sdk { @@ -38,6 +39,8 @@ void set_name(...); class ClientContext { public: ClientContext(); + ClientContext(const ViamChannel& channel); + ~ClientContext(); void try_cancel(); @@ -110,7 +113,7 @@ class ClientHelper { template auto invoke(ResponseHandlerCallable&& rhc, ErrorHandlerCallable&& ehc) { client_helper_details::set_name(&request_, client_); - ClientContext ctx; + ClientContext ctx(client_->channel()); if (debug_key_ != "") { ctx.set_debug_key(debug_key_); @@ -132,7 +135,7 @@ class ClientHelper { typename ErrorHandlerCallable = decltype(default_ehc_)> auto invoke_stream(ResponseHandlerCallable rhc, ErrorHandlerCallable&& ehc = default_ehc_) { *request_.mutable_name() = client_->name(); - ClientContext ctx; + ClientContext ctx(client_->channel()); auto reader = (stub_->*pfn_)(ctx, request_); diff --git a/src/viam/sdk/common/grpc_fwd.hpp.in b/src/viam/sdk/common/grpc_fwd.hpp.in index 39bafd3ac..970a9db7f 100644 --- a/src/viam/sdk/common/grpc_fwd.hpp.in +++ b/src/viam/sdk/common/grpc_fwd.hpp.in @@ -2,6 +2,16 @@ #cmakedefine VIAMCPPSDK_GRPCXX_LEGACY_FWD +// Preprocessor definition for direct dial support in grpc. +// For grpc >= 1.43.0 it is possible to dial directly over grpc. For older versions, +// `VIAMCPPSDK_GRPCXX_NO_DIRECT_DIAL` is defined. +// The default behavior is for the variable to be undefined, providing the behavior for recent +// versions. If you are experiencing compilation errors in an installed version of the SDK it may be +// due to a mismatch with the configured version of this header and the grpc version found by the +// compiler. You may wish to comment/uncomment the define below as needed, or add the definition +// with `-D` to the compiler. +#cmakedefine VIAMCPPSDK_GRPCXX_NO_DIRECT_DIAL + // Forward declaration file grpc client and server types. // This file provides includes for recent (>= 1.32.0) versions of grpc or older // versions, depending on if `VIAMCPPSDK_GRPCXX_LEGACY_FWD` is defined. diff --git a/src/viam/sdk/components/private/arm_client.cpp b/src/viam/sdk/components/private/arm_client.cpp index 619580ad4..a1a5d21a5 100644 --- a/src/viam/sdk/components/private/arm_client.cpp +++ b/src/viam/sdk/components/private/arm_client.cpp @@ -1,5 +1,7 @@ #include +#include + #include #include @@ -9,10 +11,10 @@ namespace viam { namespace sdk { namespace impl { -ArmClient::ArmClient(std::string name, std::shared_ptr channel) +ArmClient::ArmClient(std::string name, const ViamChannel& channel) : Arm(std::move(name)), - stub_(viam::component::arm::v1::ArmService::NewStub(channel)), - channel_(std::move(channel)) {} + stub_(viam::component::arm::v1::ArmService::NewStub(channel.channel())), + channel_(&channel) {} pose ArmClient::get_end_position(const ProtoStruct& extra) { return make_client_helper(this, *stub_, &StubType::GetEndPosition) diff --git a/src/viam/sdk/components/private/arm_client.hpp b/src/viam/sdk/components/private/arm_client.hpp index 6608a1340..426902ba4 100644 --- a/src/viam/sdk/components/private/arm_client.hpp +++ b/src/viam/sdk/components/private/arm_client.hpp @@ -3,11 +3,10 @@ /// @brief Implements a gRPC client for the `Arm` component #pragma once -#include - #include #include +#include namespace viam { namespace sdk { @@ -19,7 +18,11 @@ namespace impl { class ArmClient : public Arm { public: using interface_type = Arm; - ArmClient(std::string name, std::shared_ptr channel); + ArmClient(std::string name, const ViamChannel& channel); + + const ViamChannel& channel() const { + return *channel_; + } pose get_end_position(const ProtoStruct& extra) override; void move_to_position(const pose& pose, const ProtoStruct& extra) override; @@ -49,7 +52,7 @@ class ArmClient : public Arm { private: using StubType = viam::component::arm::v1::ArmService::StubInterface; std::unique_ptr stub_; - std::shared_ptr channel_; + const ViamChannel* channel_; }; } // namespace impl diff --git a/src/viam/sdk/components/private/base_client.cpp b/src/viam/sdk/components/private/base_client.cpp index 03be9d2cb..231fe6feb 100644 --- a/src/viam/sdk/components/private/base_client.cpp +++ b/src/viam/sdk/components/private/base_client.cpp @@ -1,5 +1,7 @@ #include +#include + #include #include #include @@ -22,10 +24,10 @@ namespace viam { namespace sdk { namespace impl { -BaseClient::BaseClient(std::string name, std::shared_ptr channel) +BaseClient::BaseClient(std::string name, const ViamChannel& channel) : Base(std::move(name)), - stub_(viam::component::base::v1::BaseService::NewStub(channel)), - channel_(std::move(channel)) {} + stub_(viam::component::base::v1::BaseService::NewStub(channel.channel())), + channel_(&channel) {} void BaseClient::move_straight(int64_t distance_mm, double mm_per_sec, const ProtoStruct& extra) { return make_client_helper(this, *stub_, &StubType::MoveStraight) diff --git a/src/viam/sdk/components/private/base_client.hpp b/src/viam/sdk/components/private/base_client.hpp index 7547e98fb..acf691239 100644 --- a/src/viam/sdk/components/private/base_client.hpp +++ b/src/viam/sdk/components/private/base_client.hpp @@ -3,8 +3,6 @@ /// @brief Implements a gRPC client for the `Base` component. #pragma once -#include - #include #include @@ -13,6 +11,7 @@ #include #include #include +#include namespace viam { namespace sdk { @@ -24,7 +23,11 @@ namespace impl { class BaseClient : public Base { public: using interface_type = Base; - BaseClient(std::string name, std::shared_ptr channel); + BaseClient(std::string name, const ViamChannel& channel); + + const ViamChannel& channel() const { + return *channel_; + } void move_straight(int64_t distance_mm, double mm_per_sec, const ProtoStruct& extra) override; void spin(double angle_deg, double degs_per_sec, const ProtoStruct& extra) override; void set_power(const Vector3& linear, @@ -59,7 +62,7 @@ class BaseClient : public Base { private: using StubType = viam::component::base::v1::BaseService::StubInterface; std::unique_ptr stub_; - std::shared_ptr channel_; + const ViamChannel* channel_; }; } // namespace impl diff --git a/src/viam/sdk/components/private/board_client.cpp b/src/viam/sdk/components/private/board_client.cpp index 7bd7a6935..486fd62b9 100644 --- a/src/viam/sdk/components/private/board_client.cpp +++ b/src/viam/sdk/components/private/board_client.cpp @@ -1,5 +1,7 @@ #include +#include + #include #include #include @@ -49,10 +51,10 @@ viam::component::board::v1::PowerMode to_proto(Board::power_mode power_mode) { } } -BoardClient::BoardClient(std::string name, std::shared_ptr channel) +BoardClient::BoardClient(std::string name, const ViamChannel& channel) : Board(std::move(name)), - stub_(viam::component::board::v1::BoardService::NewStub(channel)), - channel_(std::move(channel)) {} + stub_(viam::component::board::v1::BoardService::NewStub(channel.channel())), + channel_(&channel) {} void BoardClient::set_gpio(const std::string& pin, bool high, const ProtoStruct& extra) { return make_client_helper(this, *stub_, &StubType::SetGPIO) diff --git a/src/viam/sdk/components/private/board_client.hpp b/src/viam/sdk/components/private/board_client.hpp index c0c0a3161..123bfd04c 100644 --- a/src/viam/sdk/components/private/board_client.hpp +++ b/src/viam/sdk/components/private/board_client.hpp @@ -3,14 +3,13 @@ /// @brief Implements a gRPC client for the `Board` component. #pragma once -#include - #include #include #include #include #include +#include namespace viam { namespace sdk { @@ -22,7 +21,11 @@ namespace impl { class BoardClient : public Board { public: using interface_type = Board; - BoardClient(std::string name, std::shared_ptr channel); + BoardClient(std::string name, const ViamChannel& channel); + + const ViamChannel& channel() const { + return *channel_; + } ProtoStruct do_command(const ProtoStruct& command) override; void set_gpio(const std::string& pin, bool high, const ProtoStruct& extra) override; bool get_gpio(const std::string& pin, const ProtoStruct& extra) override; @@ -73,7 +76,7 @@ class BoardClient : public Board { private: using StubType = viam::component::board::v1::BoardService::StubInterface; std::unique_ptr stub_; - const std::shared_ptr channel_; + const ViamChannel* channel_; }; } // namespace impl diff --git a/src/viam/sdk/components/private/button_client.cpp b/src/viam/sdk/components/private/button_client.cpp index 4a5042c39..8de978b41 100644 --- a/src/viam/sdk/components/private/button_client.cpp +++ b/src/viam/sdk/components/private/button_client.cpp @@ -1,5 +1,7 @@ #include +#include + #include #include @@ -10,10 +12,10 @@ namespace viam { namespace sdk { namespace impl { -ButtonClient::ButtonClient(std::string name, std::shared_ptr channel) +ButtonClient::ButtonClient(std::string name, const ViamChannel& channel) : Button(std::move(name)), - stub_(viam::component::button::v1::ButtonService::NewStub(channel)), - channel_(std::move(channel)) {} + stub_(viam::component::button::v1::ButtonService::NewStub(channel.channel())), + channel_(&channel) {} void ButtonClient::push(const ProtoStruct& extra) { return make_client_helper(this, *stub_, &StubType::Push).with(extra).invoke(); diff --git a/src/viam/sdk/components/private/button_client.hpp b/src/viam/sdk/components/private/button_client.hpp index e0c58f0ab..dc6e7684d 100644 --- a/src/viam/sdk/components/private/button_client.hpp +++ b/src/viam/sdk/components/private/button_client.hpp @@ -5,11 +5,10 @@ #include -#include - #include #include +#include namespace viam { namespace sdk { @@ -21,7 +20,11 @@ namespace impl { class ButtonClient : public Button { public: using interface_type = Button; - ButtonClient(std::string name, std::shared_ptr channel); + ButtonClient(std::string name, const ViamChannel& channel); + + const ViamChannel& channel() const { + return *channel_; + } void push(const ProtoStruct& extra) override; ProtoStruct do_command(const ProtoStruct& command) override; @@ -31,7 +34,7 @@ class ButtonClient : public Button { private: using StubType = viam::component::button::v1::ButtonService::StubInterface; std::unique_ptr stub_; - std::shared_ptr channel_; + const ViamChannel* channel_; }; } // namespace impl diff --git a/src/viam/sdk/components/private/camera_client.cpp b/src/viam/sdk/components/private/camera_client.cpp index ec09856fc..4d03d772f 100644 --- a/src/viam/sdk/components/private/camera_client.cpp +++ b/src/viam/sdk/components/private/camera_client.cpp @@ -1,5 +1,7 @@ #include +#include + #include #include #include @@ -102,10 +104,10 @@ Camera::properties from_proto(const viam::component::camera::v1::GetPropertiesRe (proto.frame_rate())}; } -CameraClient::CameraClient(std::string name, std::shared_ptr channel) +CameraClient::CameraClient(std::string name, const ViamChannel& channel) : Camera(std::move(name)), - stub_(viam::component::camera::v1::CameraService::NewStub(channel)), - channel_(std::move(channel)) {} + stub_(viam::component::camera::v1::CameraService::NewStub(channel.channel())), + channel_(&channel) {} ProtoStruct CameraClient::do_command(const ProtoStruct& command) { return make_client_helper(this, *stub_, &StubType::DoCommand) diff --git a/src/viam/sdk/components/private/camera_client.hpp b/src/viam/sdk/components/private/camera_client.hpp index b61b593fb..ec30cd39f 100644 --- a/src/viam/sdk/components/private/camera_client.hpp +++ b/src/viam/sdk/components/private/camera_client.hpp @@ -3,8 +3,6 @@ /// @brief Implements a gRPC client for the `Camera` component. #pragma once -#include - #include #include @@ -12,6 +10,7 @@ #include #include #include +#include namespace viam { namespace sdk { @@ -23,7 +22,11 @@ namespace impl { class CameraClient : public Camera { public: using interface_type = Camera; - CameraClient(std::string name, std::shared_ptr channel); + CameraClient(std::string name, const ViamChannel& channel); + + const ViamChannel& channel() const { + return *channel_; + } ProtoStruct do_command(const ProtoStruct& command) override; raw_image get_image(std::string mime_type, const ProtoStruct& extra) override; image_collection get_images() override; @@ -50,12 +53,12 @@ class CameraClient : public Camera { // avoid use of this constructor outside of tests. CameraClient(std::string name, std::unique_ptr stub) - : Camera(std::move(name)), stub_(std::move(stub)){}; + : Camera(std::move(name)), stub_(std::move(stub)) {} private: using StubType = viam::component::camera::v1::CameraService::StubInterface; std::unique_ptr stub_; - std::shared_ptr channel_; + const ViamChannel* channel_; }; } // namespace impl diff --git a/src/viam/sdk/components/private/encoder_client.cpp b/src/viam/sdk/components/private/encoder_client.cpp index 7ccbc3fa9..5ee1a477c 100644 --- a/src/viam/sdk/components/private/encoder_client.cpp +++ b/src/viam/sdk/components/private/encoder_client.cpp @@ -1,5 +1,7 @@ #include +#include + #include #include #include @@ -45,10 +47,10 @@ Encoder::properties from_proto(const viam::component::encoder::v1::GetProperties return properties; } -EncoderClient::EncoderClient(std::string name, std::shared_ptr channel) +EncoderClient::EncoderClient(std::string name, const ViamChannel& channel) : Encoder(std::move(name)), - stub_(viam::component::encoder::v1::EncoderService::NewStub(channel)), - channel_(std::move(channel)) {} + stub_(viam::component::encoder::v1::EncoderService::NewStub(channel.channel())), + channel_(&channel) {} Encoder::position EncoderClient::get_position(const ProtoStruct& extra, position_type position_type) { diff --git a/src/viam/sdk/components/private/encoder_client.hpp b/src/viam/sdk/components/private/encoder_client.hpp index 73935401b..67868175e 100644 --- a/src/viam/sdk/components/private/encoder_client.hpp +++ b/src/viam/sdk/components/private/encoder_client.hpp @@ -3,12 +3,11 @@ /// @brief Implements a gRPC client for the `Encoder` component. #pragma once -#include - #include #include #include +#include namespace viam { namespace sdk { @@ -20,7 +19,11 @@ namespace impl { class EncoderClient : public Encoder { public: using interface_type = Encoder; - EncoderClient(std::string name, std::shared_ptr channel); + EncoderClient(std::string name, const ViamChannel& channel); + + const ViamChannel& channel() const { + return *channel_; + } position get_position(const ProtoStruct& extra, position_type position_type) override; void reset_position(const ProtoStruct& extra) override; properties get_properties(const ProtoStruct& extra) override; @@ -44,7 +47,7 @@ class EncoderClient : public Encoder { private: using StubType = viam::component::encoder::v1::EncoderService::StubInterface; std::unique_ptr stub_; - std::shared_ptr channel_; + const ViamChannel* channel_; }; } // namespace impl diff --git a/src/viam/sdk/components/private/gantry_client.cpp b/src/viam/sdk/components/private/gantry_client.cpp index 7021dd5bc..4d86227db 100644 --- a/src/viam/sdk/components/private/gantry_client.cpp +++ b/src/viam/sdk/components/private/gantry_client.cpp @@ -1,5 +1,7 @@ #include +#include + #include #include @@ -9,10 +11,10 @@ namespace viam { namespace sdk { namespace impl { -GantryClient::GantryClient(std::string name, std::shared_ptr channel) +GantryClient::GantryClient(std::string name, const ViamChannel& channel) : Gantry(std::move(name)), - stub_(viam::component::gantry::v1::GantryService::NewStub(channel)), - channel_(std::move(channel)) {} + stub_(viam::component::gantry::v1::GantryService::NewStub(channel.channel())), + channel_(&channel) {} std::vector GantryClient::get_position(const ProtoStruct& extra) { return make_client_helper(this, *stub_, &StubType::GetPosition) diff --git a/src/viam/sdk/components/private/gantry_client.hpp b/src/viam/sdk/components/private/gantry_client.hpp index b499baef4..75b73d21c 100644 --- a/src/viam/sdk/components/private/gantry_client.hpp +++ b/src/viam/sdk/components/private/gantry_client.hpp @@ -3,11 +3,10 @@ /// @brief Implements a gRPC client for the `Gantry` component #pragma once -#include - #include #include +#include namespace viam { namespace sdk { @@ -19,7 +18,11 @@ namespace impl { class GantryClient : public Gantry { public: using interface_type = Gantry; - GantryClient(std::string names, std::shared_ptr channel); + GantryClient(std::string name, const ViamChannel& channel); + + const ViamChannel& channel() const { + return *channel_; + } std::vector get_position(const ProtoStruct& extra) override; void move_to_position(const std::vector& coordinates, @@ -41,7 +44,7 @@ class GantryClient : public Gantry { private: using StubType = viam::component::gantry::v1::GantryService::StubInterface; std::unique_ptr stub_; - std::shared_ptr channel_; + const ViamChannel* channel_; }; } // namespace impl diff --git a/src/viam/sdk/components/private/generic_client.cpp b/src/viam/sdk/components/private/generic_client.cpp index 2bb654539..42917e228 100644 --- a/src/viam/sdk/components/private/generic_client.cpp +++ b/src/viam/sdk/components/private/generic_client.cpp @@ -1,5 +1,7 @@ #include +#include + #include #include @@ -15,11 +17,10 @@ namespace viam { namespace sdk { namespace impl { -GenericComponentClient::GenericComponentClient(std::string name, - std::shared_ptr channel) +GenericComponentClient::GenericComponentClient(std::string name, const ViamChannel& channel) : GenericComponent(std::move(name)), - stub_(viam::component::generic::v1::GenericService::NewStub(channel)), - channel_(std::move(channel)) {} + stub_(viam::component::generic::v1::GenericService::NewStub(channel.channel())), + channel_(&channel) {} ProtoStruct GenericComponentClient::do_command(const ProtoStruct& command) { return make_client_helper(this, *stub_, &StubType::DoCommand) diff --git a/src/viam/sdk/components/private/generic_client.hpp b/src/viam/sdk/components/private/generic_client.hpp index 1e76be23e..4a40fa3d9 100644 --- a/src/viam/sdk/components/private/generic_client.hpp +++ b/src/viam/sdk/components/private/generic_client.hpp @@ -3,12 +3,11 @@ /// @brief Implements a gRPC client for the `GenericComponent`. #pragma once -#include - #include #include #include +#include namespace viam { namespace sdk { @@ -20,7 +19,11 @@ namespace impl { class GenericComponentClient : public GenericComponent { public: using interface_type = GenericComponent; - GenericComponentClient(std::string name, std::shared_ptr channel); + GenericComponentClient(std::string name, const ViamChannel& channel); + + const ViamChannel& channel() const { + return *channel_; + } ProtoStruct do_command(const ProtoStruct& command) override; std::vector get_geometries(const ProtoStruct& extra) override; @@ -31,12 +34,12 @@ class GenericComponentClient : public GenericComponent { GenericComponentClient( std::string name, std::unique_ptr stub) - : GenericComponent(std::move(name)), stub_(std::move(stub)){}; + : GenericComponent(std::move(name)), stub_(std::move(stub)) {} private: using StubType = viam::component::generic::v1::GenericService::StubInterface; std::unique_ptr stub_; - std::shared_ptr channel_; + const ViamChannel* channel_; }; } // namespace impl diff --git a/src/viam/sdk/components/private/gripper_client.cpp b/src/viam/sdk/components/private/gripper_client.cpp index 439517bff..bf325402e 100644 --- a/src/viam/sdk/components/private/gripper_client.cpp +++ b/src/viam/sdk/components/private/gripper_client.cpp @@ -1,5 +1,7 @@ #include +#include + #include #include @@ -11,10 +13,10 @@ namespace viam { namespace sdk { namespace impl { -GripperClient::GripperClient(std::string name, std::shared_ptr channel) +GripperClient::GripperClient(std::string name, const ViamChannel& channel) : Gripper(std::move(name)), - stub_(viam::component::gripper::v1::GripperService::NewStub(channel)), - channel_(std::move(channel)) {} + stub_(viam::component::gripper::v1::GripperService::NewStub(channel.channel())), + channel_(&channel) {} void GripperClient::open(const ProtoStruct& extra) { return make_client_helper(this, *stub_, &StubType::Open).with(extra).invoke(); diff --git a/src/viam/sdk/components/private/gripper_client.hpp b/src/viam/sdk/components/private/gripper_client.hpp index 1d118eda9..10527414f 100644 --- a/src/viam/sdk/components/private/gripper_client.hpp +++ b/src/viam/sdk/components/private/gripper_client.hpp @@ -5,11 +5,10 @@ #include -#include - #include #include +#include namespace viam { namespace sdk { @@ -21,7 +20,11 @@ namespace impl { class GripperClient : public Gripper { public: using interface_type = Gripper; - GripperClient(std::string names, std::shared_ptr channel); + GripperClient(std::string name, const ViamChannel& channel); + + const ViamChannel& channel() const { + return *channel_; + } void open(const ProtoStruct& extra) override; bool grab(const ProtoStruct& extra) override; @@ -38,7 +41,7 @@ class GripperClient : public Gripper { private: using StubType = viam::component::gripper::v1::GripperService::StubInterface; std::unique_ptr stub_; - std::shared_ptr channel_; + const ViamChannel* channel_; }; } // namespace impl diff --git a/src/viam/sdk/components/private/motor_client.cpp b/src/viam/sdk/components/private/motor_client.cpp index e0f112b6a..466e0dada 100644 --- a/src/viam/sdk/components/private/motor_client.cpp +++ b/src/viam/sdk/components/private/motor_client.cpp @@ -1,5 +1,7 @@ #include +#include + #include #include #include @@ -37,10 +39,10 @@ Motor::properties from_proto(const viam::component::motor::v1::GetPropertiesResp return properties; } -MotorClient::MotorClient(std::string name, std::shared_ptr channel) +MotorClient::MotorClient(std::string name, const ViamChannel& channel) : Motor(std::move(name)), - stub_(viam::component::motor::v1::MotorService::NewStub(channel)), - channel_(std::move(channel)) {} + stub_(viam::component::motor::v1::MotorService::NewStub(channel.channel())), + channel_(&channel) {} void MotorClient::set_power(double power_pct, const ProtoStruct& extra) { return make_client_helper(this, *stub_, &StubType::SetPower) diff --git a/src/viam/sdk/components/private/motor_client.hpp b/src/viam/sdk/components/private/motor_client.hpp index 223b77190..4cff0088c 100644 --- a/src/viam/sdk/components/private/motor_client.hpp +++ b/src/viam/sdk/components/private/motor_client.hpp @@ -3,13 +3,12 @@ /// @brief Implements a gRPC client for the `Motor` component. #pragma once -#include - #include #include #include #include +#include namespace viam { namespace sdk { @@ -21,7 +20,11 @@ namespace impl { class MotorClient : public Motor { public: using interface_type = Motor; - MotorClient(std::string name, std::shared_ptr channel); + MotorClient(std::string name, const ViamChannel& channel); + + const ViamChannel& channel() const { + return *channel_; + } void set_power(double power_pct, const ProtoStruct& extra) override; void go_for(double rpm, double revolutions, const ProtoStruct& extra) override; void go_to(double rpm, double position_revolutions, const ProtoStruct& extra) override; @@ -58,7 +61,7 @@ class MotorClient : public Motor { private: using StubType = viam::component::motor::v1::MotorService::StubInterface; std::unique_ptr stub_; - std::shared_ptr channel_; + const ViamChannel* channel_; }; } // namespace impl diff --git a/src/viam/sdk/components/private/movement_sensor_client.cpp b/src/viam/sdk/components/private/movement_sensor_client.cpp index ec9b19ee0..39aad6c18 100644 --- a/src/viam/sdk/components/private/movement_sensor_client.cpp +++ b/src/viam/sdk/components/private/movement_sensor_client.cpp @@ -1,5 +1,7 @@ #include +#include + #include #include #include @@ -56,10 +58,10 @@ MovementSensor::properties from_proto( return properties; } -MovementSensorClient::MovementSensorClient(std::string name, std::shared_ptr channel) +MovementSensorClient::MovementSensorClient(std::string name, const ViamChannel& channel) : MovementSensor(std::move(name)), - stub_(viam::component::movementsensor::v1::MovementSensorService::NewStub(channel)), - channel_(std::move(channel)) {} + stub_(viam::component::movementsensor::v1::MovementSensorService::NewStub(channel.channel())), + channel_(&channel) {} using namespace viam::component::movementsensor::v1; diff --git a/src/viam/sdk/components/private/movement_sensor_client.hpp b/src/viam/sdk/components/private/movement_sensor_client.hpp index a64ae7c02..f5d62fc50 100644 --- a/src/viam/sdk/components/private/movement_sensor_client.hpp +++ b/src/viam/sdk/components/private/movement_sensor_client.hpp @@ -3,8 +3,6 @@ /// @brief Implements a gRPC client for the `MovementSensor` component. #pragma once -#include - #include #include @@ -12,6 +10,7 @@ #include #include #include +#include namespace viam { namespace sdk { @@ -23,7 +22,11 @@ namespace impl { class MovementSensorClient : public MovementSensor { public: using interface_type = MovementSensor; - MovementSensorClient(std::string name, std::shared_ptr channel); + MovementSensorClient(std::string name, const ViamChannel& channel); + + const ViamChannel& channel() const { + return *channel_; + } Vector3 get_linear_velocity(const ProtoStruct& extra) override; Vector3 get_angular_velocity(const ProtoStruct& extra) override; compassheading get_compass_heading(const ProtoStruct& extra) override; @@ -48,7 +51,7 @@ class MovementSensorClient : public MovementSensor { private: using StubType = viam::component::movementsensor::v1::MovementSensorService::StubInterface; std::unique_ptr stub_; - std::shared_ptr channel_; + const ViamChannel* channel_; }; } // namespace impl diff --git a/src/viam/sdk/components/private/pose_tracker_client.cpp b/src/viam/sdk/components/private/pose_tracker_client.cpp index 234244ef6..b183032e1 100644 --- a/src/viam/sdk/components/private/pose_tracker_client.cpp +++ b/src/viam/sdk/components/private/pose_tracker_client.cpp @@ -1,5 +1,7 @@ #include +#include + #include #include #include @@ -10,10 +12,10 @@ namespace viam { namespace sdk { namespace impl { -PoseTrackerClient::PoseTrackerClient(std::string name, std::shared_ptr channel) +PoseTrackerClient::PoseTrackerClient(std::string name, const ViamChannel& channel) : PoseTracker(std::move(name)), - stub_(viam::component::posetracker::v1::PoseTrackerService::NewStub(channel)), - channel_(std::move(channel)) {} + stub_(viam::component::posetracker::v1::PoseTrackerService::NewStub(channel.channel())), + channel_(&channel) {} PoseTracker::pose_map PoseTrackerClient::get_poses(const std::vector& body_names, const ProtoStruct&) { diff --git a/src/viam/sdk/components/private/pose_tracker_client.hpp b/src/viam/sdk/components/private/pose_tracker_client.hpp index 5c947ca20..0cba469b6 100644 --- a/src/viam/sdk/components/private/pose_tracker_client.hpp +++ b/src/viam/sdk/components/private/pose_tracker_client.hpp @@ -3,11 +3,10 @@ /// @brief Implements a gRPC client for the `PoseTracker` component #pragma once -#include - #include #include +#include namespace viam { namespace sdk { @@ -20,7 +19,11 @@ class PoseTrackerClient : public PoseTracker { public: using interface_type = PoseTracker; - PoseTrackerClient(std::string name, std::shared_ptr channel); + PoseTrackerClient(std::string name, const ViamChannel& channel); + + const ViamChannel& channel() const { + return *channel_; + } PoseTracker::pose_map get_poses(const std::vector& body_names, const ProtoStruct& extra) override; @@ -35,7 +38,7 @@ class PoseTrackerClient : public PoseTracker { private: using StubType = viam::component::posetracker::v1::PoseTrackerService::StubInterface; std::unique_ptr stub_; - std::shared_ptr channel_; + const ViamChannel* channel_; }; } // namespace impl diff --git a/src/viam/sdk/components/private/power_sensor_client.cpp b/src/viam/sdk/components/private/power_sensor_client.cpp index 556dbf1a3..d2fa23839 100644 --- a/src/viam/sdk/components/private/power_sensor_client.cpp +++ b/src/viam/sdk/components/private/power_sensor_client.cpp @@ -1,5 +1,7 @@ #include +#include + #include #include #include @@ -38,10 +40,10 @@ PowerSensor::current from_proto(const GetCurrentResponse& proto) { return c; } -PowerSensorClient::PowerSensorClient(std::string name, std::shared_ptr channel) +PowerSensorClient::PowerSensorClient(std::string name, const ViamChannel& channel) : PowerSensor(std::move(name)), - stub_(PowerSensorService::NewStub(channel)), - channel_(std::move(channel)) {} + stub_(PowerSensorService::NewStub(channel.channel())), + channel_(&channel) {} PowerSensor::voltage PowerSensorClient::get_voltage(const ProtoStruct& extra) { return make_client_helper(this, *stub_, &StubType::GetVoltage) diff --git a/src/viam/sdk/components/private/power_sensor_client.hpp b/src/viam/sdk/components/private/power_sensor_client.hpp index cf9927878..189e65828 100644 --- a/src/viam/sdk/components/private/power_sensor_client.hpp +++ b/src/viam/sdk/components/private/power_sensor_client.hpp @@ -3,14 +3,13 @@ /// @brief Implements a gRPC client for the `PowerSensor` component. #pragma once -#include - #include #include #include #include #include +#include namespace viam { namespace sdk { @@ -22,7 +21,11 @@ namespace impl { class PowerSensorClient : public PowerSensor { public: using interface_type = PowerSensor; - PowerSensorClient(std::string name, std::shared_ptr channel); + PowerSensorClient(std::string name, const ViamChannel& channel); + + const ViamChannel& channel() const { + return *channel_; + } voltage get_voltage(const ProtoStruct& extra) override; current get_current(const ProtoStruct& extra) override; double get_power(const ProtoStruct& extra) override; @@ -37,7 +40,7 @@ class PowerSensorClient : public PowerSensor { private: using StubType = viam::component::powersensor::v1::PowerSensorService::StubInterface; std::unique_ptr stub_; - std::shared_ptr channel_; + const ViamChannel* channel_; }; } // namespace impl diff --git a/src/viam/sdk/components/private/sensor_client.cpp b/src/viam/sdk/components/private/sensor_client.cpp index b1b7bce6c..5ea1cdea5 100644 --- a/src/viam/sdk/components/private/sensor_client.cpp +++ b/src/viam/sdk/components/private/sensor_client.cpp @@ -1,5 +1,7 @@ #include +#include + #include #include #include @@ -16,10 +18,10 @@ namespace viam { namespace sdk { namespace impl { -SensorClient::SensorClient(std::string name, std::shared_ptr channel) +SensorClient::SensorClient(std::string name, const ViamChannel& channel) : Sensor(std::move(name)), - stub_(viam::component::sensor::v1::SensorService::NewStub(channel)), - channel_(std::move(channel)) {} + stub_(viam::component::sensor::v1::SensorService::NewStub(channel.channel())), + channel_(&channel) {} using namespace viam::common::v1; diff --git a/src/viam/sdk/components/private/sensor_client.hpp b/src/viam/sdk/components/private/sensor_client.hpp index 048b29bb3..30460048f 100644 --- a/src/viam/sdk/components/private/sensor_client.hpp +++ b/src/viam/sdk/components/private/sensor_client.hpp @@ -3,13 +3,12 @@ /// @brief Implements a gRPC client for the `Sensor` component. #pragma once -#include - #include #include #include #include +#include namespace viam { namespace sdk { @@ -21,7 +20,11 @@ namespace impl { class SensorClient : public Sensor { public: using interface_type = Sensor; - SensorClient(std::string name, std::shared_ptr channel); + SensorClient(std::string name, const ViamChannel& channel); + + const ViamChannel& channel() const { + return *channel_; + } ProtoStruct get_readings(const ProtoStruct& extra) override; ProtoStruct do_command(const ProtoStruct& command) override; std::vector get_geometries(const ProtoStruct& extra) override; @@ -32,7 +35,7 @@ class SensorClient : public Sensor { private: using StubType = viam::component::sensor::v1::SensorService::StubInterface; std::unique_ptr stub_; - std::shared_ptr channel_; + const ViamChannel* channel_; }; } // namespace impl diff --git a/src/viam/sdk/components/private/servo_client.cpp b/src/viam/sdk/components/private/servo_client.cpp index 189e4d86a..fabb9945f 100644 --- a/src/viam/sdk/components/private/servo_client.cpp +++ b/src/viam/sdk/components/private/servo_client.cpp @@ -1,5 +1,7 @@ #include +#include + #include #include #include @@ -25,10 +27,10 @@ Servo::position from_proto(const viam::component::servo::v1::GetPositionResponse return proto.position_deg(); } -ServoClient::ServoClient(std::string name, std::shared_ptr channel) +ServoClient::ServoClient(std::string name, const ViamChannel& channel) : Servo(std::move(name)), - stub_(viam::component::servo::v1::ServoService::NewStub(channel)), - channel_(std::move(channel)) {} + stub_(viam::component::servo::v1::ServoService::NewStub(channel.channel())), + channel_(&channel) {} void ServoClient::move(uint32_t angle_deg, const ProtoStruct& extra) { return make_client_helper(this, *stub_, &StubType::Move) diff --git a/src/viam/sdk/components/private/servo_client.hpp b/src/viam/sdk/components/private/servo_client.hpp index e1a68dd7d..e478b9a4c 100644 --- a/src/viam/sdk/components/private/servo_client.hpp +++ b/src/viam/sdk/components/private/servo_client.hpp @@ -3,13 +3,12 @@ /// @brief Implements a gRPC client for the `Servo` component. #pragma once -#include - #include #include #include #include +#include namespace viam { namespace sdk { @@ -21,7 +20,11 @@ namespace impl { class ServoClient : public Servo { public: using interface_type = Servo; - ServoClient(std::string name, std::shared_ptr channel); + ServoClient(std::string name, const ViamChannel& channel); + + const ViamChannel& channel() const { + return *channel_; + } void move(uint32_t angle_deg, const ProtoStruct& extra) override; position get_position(const ProtoStruct& extra) override; void stop(const ProtoStruct& extra) override; @@ -36,7 +39,7 @@ class ServoClient : public Servo { using StubType = viam::component::servo::v1::ServoService::StubInterface; std::unique_ptr stub_; - std::shared_ptr channel_; + const ViamChannel* channel_; }; } // namespace impl diff --git a/src/viam/sdk/components/private/switch_client.cpp b/src/viam/sdk/components/private/switch_client.cpp index 081f54277..f4617fe18 100644 --- a/src/viam/sdk/components/private/switch_client.cpp +++ b/src/viam/sdk/components/private/switch_client.cpp @@ -1,5 +1,7 @@ #include +#include + #include #include @@ -9,10 +11,10 @@ namespace viam { namespace sdk { namespace impl { -SwitchClient::SwitchClient(std::string name, std::shared_ptr channel) +SwitchClient::SwitchClient(std::string name, const ViamChannel& channel) : Switch(std::move(name)), - stub_(viam::component::switch_::v1::SwitchService::NewStub(channel)), - channel_(std::move(channel)) {} + stub_(viam::component::switch_::v1::SwitchService::NewStub(channel.channel())), + channel_(&channel) {} void SwitchClient::set_position(uint32_t position, const ProtoStruct& extra) { make_client_helper(this, *stub_, &StubType::SetPosition) diff --git a/src/viam/sdk/components/private/switch_client.hpp b/src/viam/sdk/components/private/switch_client.hpp index ce93b1200..2177ff874 100644 --- a/src/viam/sdk/components/private/switch_client.hpp +++ b/src/viam/sdk/components/private/switch_client.hpp @@ -3,11 +3,10 @@ /// @brief Implements a gRPC client for the `Switch` component #pragma once -#include - #include #include +#include namespace viam { namespace sdk { @@ -19,7 +18,11 @@ namespace impl { class SwitchClient : public Switch { public: using interface_type = Switch; - SwitchClient(std::string name, std::shared_ptr channel); + SwitchClient(std::string name, const ViamChannel& channel); + + const ViamChannel& channel() const { + return *channel_; + } void set_position(uint32_t position, const ProtoStruct& extra) override; uint32_t get_position(const ProtoStruct& extra) override; @@ -35,7 +38,7 @@ class SwitchClient : public Switch { private: using StubType = viam::component::switch_::v1::SwitchService::StubInterface; std::unique_ptr stub_; - std::shared_ptr channel_; + const ViamChannel* channel_; }; } // namespace impl diff --git a/src/viam/sdk/module/service.cpp b/src/viam/sdk/module/service.cpp index 738ffae91..f51d26427 100644 --- a/src/viam/sdk/module/service.cpp +++ b/src/viam/sdk/module/service.cpp @@ -194,7 +194,8 @@ struct ModuleService::ServiceImpl : viam::module::v1::ModuleService::Service { auto new_parent_addr = request->parent_address(); if (parent.parent_addr_ != new_parent_addr) { parent.parent_addr_ = std::move(new_parent_addr); - parent.parent_ = RobotClient::at_local_socket(parent.parent_addr_, {0, boost::none}); + parent.parent_ = + RobotClient::at_local_socket(parent.parent_addr_, std::chrono::seconds{0}); parent.parent_->connect_logging(); } response->set_ready(parent.module_->ready()); @@ -223,7 +224,7 @@ Dependencies ModuleService::get_dependencies_( std::shared_ptr ModuleService::get_parent_resource_(const Name& name) { if (!parent_) { // LS: I think maybe this is never hit - parent_ = RobotClient::at_local_socket(parent_addr_, {0, boost::none}); + parent_ = RobotClient::at_local_socket(parent_addr_, std::chrono::seconds{0}); parent_->connect_logging(); } @@ -254,13 +255,12 @@ ModuleService::ModuleService(int argc, } ModuleService::~ModuleService() { - // TODO(RSDK-5509): Run registered cleanup functions here. - VIAM_SDK_LOG(info) << "Shutting down gracefully."; + VIAM_SDK_LOG(info) << "Shutting down gracefully.\n"; server_->shutdown(); if (parent_) { try { - parent_->close(); + parent_.reset(); } catch (const std::exception& exc) { VIAM_SDK_LOG(error) << exc.what(); } diff --git a/src/viam/sdk/module/service.hpp b/src/viam/sdk/module/service.hpp index 714d55051..03c35e6d3 100644 --- a/src/viam/sdk/module/service.hpp +++ b/src/viam/sdk/module/service.hpp @@ -68,7 +68,7 @@ class ModuleService { std::unique_ptr module_; - std::shared_ptr parent_; + std::unique_ptr parent_; std::string parent_addr_; std::unique_ptr server_; diff --git a/src/viam/sdk/registry/registry.hpp b/src/viam/sdk/registry/registry.hpp index c1a5055a3..8e8f5e6da 100644 --- a/src/viam/sdk/registry/registry.hpp +++ b/src/viam/sdk/registry/registry.hpp @@ -11,6 +11,7 @@ #include #include #include +#include #include namespace google { @@ -57,8 +58,8 @@ class ResourceClientRegistration { /// @param name The name of the resource. /// @param channel A channel connected to the client. /// @return A `shared_ptr` to the resource client. - virtual std::shared_ptr create_rpc_client( - std::string name, std::shared_ptr channel) const = 0; + virtual std::shared_ptr create_rpc_client(std::string name, + ViamChannel& channel) const = 0; }; // TODO(RSDK-6616): instead of std::functions, consider making these functions @@ -129,9 +130,9 @@ class Registry { public: using ResourceClientRegistration::ResourceClientRegistration; - std::shared_ptr create_rpc_client( - std::string name, std::shared_ptr chan) const override { - return std::make_shared(std::move(name), std::move(chan)); + std::shared_ptr create_rpc_client(std::string name, + ViamChannel& channel) const override { + return std::make_shared(std::move(name), channel); } }; diff --git a/src/viam/sdk/robot/client.cpp b/src/viam/sdk/robot/client.cpp index 6f4cd160f..6bfd9bc62 100644 --- a/src/viam/sdk/robot/client.cpp +++ b/src/viam/sdk/robot/client.cpp @@ -88,7 +88,8 @@ bool operator==(const RobotClient::operation& lhs, const RobotClient::operation& } struct RobotClient::impl { - impl(std::unique_ptr stub) : stub(std::move(stub)) {} + impl(std::unique_ptr stub, ViamChannel& channel) + : stub(std::move(stub)), channel_(&channel) {} ~impl() { if (log_sink) { @@ -106,7 +107,12 @@ struct RobotClient::impl { return make_client_helper(self.get(), *self->stub, m); } + const ViamChannel& channel() const { + return *channel_; + } + std::unique_ptr stub; + const ViamChannel* channel_; // See doc comment for RobotClient::connect_logging. This pointer is non-null and installed as a // sink only for apps being run by viam-server as a module. @@ -201,7 +207,7 @@ void RobotClient::refresh() { if (rs) { try { const std::shared_ptr rpc_client = - rs->create_rpc_client(name.name(), viam_channel_.channel()); + rs->create_rpc_client(name.name(), viam_channel_); const Name name_({name.namespace_(), name.type(), name.subtype()}, "", name.name()); new_resources.emplace(name_, rpc_client); } catch (const std::exception& exc) { @@ -233,7 +239,8 @@ void RobotClient::refresh_every() { RobotClient::RobotClient(ViamChannel channel) : viam_channel_(std::move(channel)), - impl_(std::make_unique(RobotService::NewStub(viam_channel_.channel()))) {} + impl_(std::make_unique(RobotService::NewStub(viam_channel_.channel()), viam_channel_)) { +} std::vector RobotClient::resource_names() const { const std::lock_guard lock(lock_); @@ -270,10 +277,10 @@ void RobotClient::log(const std::string& name, } } -std::shared_ptr RobotClient::with_channel(ViamChannel channel, - const Options& options) { - auto robot = std::make_shared(std::move(channel)); - robot->refresh_interval_ = std::chrono::seconds{options.refresh_interval()}; +std::unique_ptr RobotClient::with_channel(ViamChannel channel, + std::chrono::seconds refresh_interval) { + auto robot = std::make_unique(std::move(channel)); + robot->refresh_interval_ = refresh_interval; robot->should_refresh_ = (robot->refresh_interval_ > std::chrono::seconds{0}); if (robot->should_refresh_) { robot->refresh_thread_ = std::thread{&RobotClient::refresh_every, robot.get()}; @@ -283,21 +290,22 @@ std::shared_ptr RobotClient::with_channel(ViamChannel channel, return robot; }; -std::shared_ptr RobotClient::at_address(const std::string& address, - const Options& options) { +std::unique_ptr RobotClient::at_address(const std::string& address, + std::chrono::seconds refresh_interval, + const DialOptions& options) { const char* uri = address.c_str(); auto robot = - RobotClient::with_channel(ViamChannel::dial_initial(uri, options.dial_options()), options); + RobotClient::with_channel(ViamChannel::dial_initial(uri, options), refresh_interval); return robot; }; -std::shared_ptr RobotClient::at_local_socket(const std::string& address, - const Options& options) { +std::unique_ptr RobotClient::at_local_socket(const std::string& address, + std::chrono::seconds refresh_interval) { const std::string addr = "unix:" + address; auto robot = RobotClient::with_channel( - ViamChannel(sdk::impl::create_viam_channel(addr, grpc::InsecureChannelCredentials())), - options); + ViamChannel(sdk::impl::create_viam_grpc_channel(addr, grpc::InsecureChannelCredentials())), + refresh_interval); return robot; }; diff --git a/src/viam/sdk/robot/client.hpp b/src/viam/sdk/robot/client.hpp index b9dceddc9..c4dbc3b01 100644 --- a/src/viam/sdk/robot/client.hpp +++ b/src/viam/sdk/robot/client.hpp @@ -71,6 +71,11 @@ class RobotClient { friend bool operator==(const operation& lhs, const operation& rhs); }; + struct options { + std::chrono::seconds refresh_interval; + boost::optional dial_options; + }; + explicit RobotClient(ViamChannel channel); ~RobotClient(); @@ -90,22 +95,25 @@ class RobotClient { /// @brief Create a robot client connected to the robot at the provided address. /// @param address The address of the robot (IP address, URI, URL, etc.) - /// @param options Options for connecting and refreshing. - static std::shared_ptr at_address(const std::string& address, - const Options& options); + /// @param refresh_interval How often to call refresh. + /// @param options Options for dialing to the address. + static std::unique_ptr at_address(const std::string& address, + std::chrono::seconds refresh_interval, + const DialOptions& options); /// @brief Creates a robot client connected to the robot at the provided local socket. /// @param address The local socket of the robot (a .sock file, etc.). - /// @param options Options for connecting and refreshing. + /// @param refresh_interval How often to call refresh. /// Creates a direct connection to the robot using the `unix:` scheme. /// Only useful for connecting to robots across Unix sockets. - static std::shared_ptr at_local_socket(const std::string& address, - const Options& options); + static std::unique_ptr at_local_socket(const std::string& address, + std::chrono::seconds refresh_interval); /// @brief Creates a robot client connected to the provided channel. /// @param channel The channel to connect with. - /// @param options Options for connecting and refreshing. - static std::shared_ptr with_channel(ViamChannel channel, const Options& options); + /// @param refresh_interval How often to call refresh. + static std::unique_ptr with_channel(ViamChannel channel, + std::chrono::seconds refresh_interval); std::vector resource_names() const; diff --git a/src/viam/sdk/rpc/dial.cpp b/src/viam/sdk/rpc/dial.cpp index 22c2c7645..4063c705b 100644 --- a/src/viam/sdk/rpc/dial.cpp +++ b/src/viam/sdk/rpc/dial.cpp @@ -7,12 +7,21 @@ #include #include #include +#include +#include #include +#include +#include #include +#include +#include #include #include + +#include #include +#include #include #include @@ -20,30 +29,22 @@ namespace viam { namespace sdk { struct ViamChannel::impl { - impl(const char* path, void* runtime) : path(path), rust_runtime(runtime) {} - - impl(const impl&) = delete; - - impl(impl&& other) noexcept - : path(std::exchange(other.path, nullptr)), - rust_runtime(std::exchange(other.rust_runtime, nullptr)) {} - - impl& operator=(const impl&) = delete; - - impl& operator=(impl&& other) noexcept { - path = std::exchange(other.path, nullptr); - rust_runtime = std::exchange(other.rust_runtime, nullptr); + struct cstr_delete { + void operator()(const char* str) noexcept { + free_string(str); + } + }; - return *this; - } + struct rust_rt_delete { + void operator()(void* rt) noexcept { + free_rust_runtime(rt); + } + }; - ~impl() { - free_string(path); - free_rust_runtime(rust_runtime); - } + impl(const char* path, void* runtime) : path(path), rust_runtime(runtime) {} - const char* path; - void* rust_runtime; + std::unique_ptr path; + std::unique_ptr rust_runtime; }; ViamChannel::ViamChannel(std::shared_ptr channel, const char* path, void* runtime) @@ -67,83 +68,20 @@ const std::string& Credentials::payload() const { return payload_; } -DialOptions::DialOptions() = default; - -DialOptions& DialOptions::set_credentials(boost::optional creds) { - credentials_ = std::move(creds); - - return *this; -} - -DialOptions& DialOptions::set_entity(boost::optional entity) { - auth_entity_ = std::move(entity); - - return *this; -} - -DialOptions& DialOptions::set_initial_connection_attempts(int attempts) { - initial_connection_attempts_ = attempts; - - return *this; -} - -DialOptions& DialOptions::set_timeout(std::chrono::duration timeout) { - timeout_ = timeout; - - return *this; -} - -DialOptions& DialOptions::set_initial_connection_attempt_timeout( - std::chrono::duration timeout) { - initial_connection_attempt_timeout_ = timeout; - - return *this; -} - -const boost::optional& DialOptions::entity() const { - return auth_entity_; -} - -const boost::optional& DialOptions::credentials() const { - return credentials_; -} - -int DialOptions::initial_connection_attempts() const { - return initial_connection_attempts_; -} - -const std::chrono::duration& DialOptions::timeout() const { - return timeout_; -} - -std::chrono::duration DialOptions::initial_connection_attempt_timeout() const { - return initial_connection_attempt_timeout_; -} - -DialOptions& DialOptions::set_allow_insecure_downgrade(bool allow) { - allow_insecure_downgrade_ = allow; - - return *this; -} - -bool DialOptions::allows_insecure_downgrade() const { - return allow_insecure_downgrade_; -} - ViamChannel ViamChannel::dial_initial(const char* uri, const boost::optional& options) { DialOptions opts = options.get_value_or(DialOptions()); - auto timeout = opts.timeout(); - auto attempts_remaining = opts.initial_connection_attempts(); + auto timeout = opts.timeout; + auto attempts_remaining = opts.initial_connection_attempts; if (attempts_remaining == 0) { attempts_remaining = -1; } - opts.set_timeout(opts.initial_connection_attempt_timeout()); + opts.timeout = opts.initial_connection_attempt_timeout; while (attempts_remaining != 0) { try { auto connection = dial(uri, opts); - opts.set_timeout(timeout); + opts.timeout = timeout; return connection; } catch (const std::exception& e) { attempts_remaining -= 1; @@ -158,22 +96,37 @@ ViamChannel ViamChannel::dial_initial(const char* uri, } ViamChannel ViamChannel::dial(const char* uri, const boost::optional& options) { - void* ptr = init_rust_runtime(); const DialOptions opts = options.get_value_or(DialOptions()); - const std::chrono::duration float_timeout = opts.timeout(); + + // If this flag is passed, try to dial directly through grpc if possible. + // If grpc is too old to do a direct dial, we fall back to the rust version below even if + // disable_webrtc was pased. This is consistent with a hoped-for future semantic where rust + // would get the disable_webrtc flag as well rather than deducing it from the URI format, which + // is what it currently does. + if (opts.disable_webrtc) { +#ifndef VIAMCPPSDK_GRPCXX_NO_DIRECT_DIAL + return dial_direct(uri, opts); +#endif + } + + const std::chrono::duration float_timeout = opts.timeout; + void* ptr = init_rust_runtime(); const char* type = nullptr; const char* entity = nullptr; const char* payload = nullptr; - if (opts.credentials()) { - type = opts.credentials()->type().c_str(); - payload = opts.credentials()->payload().c_str(); + if (opts.credentials) { + type = opts.credentials->type().c_str(); + payload = opts.credentials->payload().c_str(); } - if (opts.entity()) { - entity = opts.entity()->c_str(); + + if (opts.auth_entity) { + entity = opts.auth_entity->c_str(); } + char* proxy_path = ::dial( - uri, entity, type, payload, opts.allows_insecure_downgrade(), float_timeout.count(), ptr); + uri, entity, type, payload, opts.allow_insecure_downgrade, float_timeout.count(), ptr); + if (!proxy_path) { free_rust_runtime(ptr); throw Exception(ErrorCondition::k_connection, "Unable to establish connecting path"); @@ -187,25 +140,63 @@ ViamChannel ViamChannel::dial(const char* uri, const boost::optional& ViamChannel::channel() const { - return channel_; +ViamChannel ViamChannel::dial_direct(const char* uri, const DialOptions& opts) { +#ifndef VIAMCPPSDK_GRPCXX_NO_DIRECT_DIAL + // TODO: if we ever drop older grpc support the logic below might make sense as a + // set_bearer_token helper function, but for now it just proliferates the ifdef messiness so + // we'll leave it inline + auto channel_for_auth = sdk::impl::create_viam_auth_channel(uri); + using namespace proto::rpc::v1; + + auto auth_stub = AuthService::NewStub(channel_for_auth); + ClientContext ctx; + AuthenticateRequest req; + + *req.mutable_entity() = opts.auth_entity.get(); + *req.mutable_credentials()->mutable_payload() = opts.credentials->payload(); + *req.mutable_credentials()->mutable_type() = opts.credentials->type(); + + AuthenticateResponse resp; + + auto status = auth_stub->Authenticate(ctx, req, &resp); + + if (!status.ok()) { + VIAM_SDK_LOG(error) << "Direct dial authentication request failed: " + << status.error_message(); + throw GRPCException(&status); + } + + grpc::experimental::TlsChannelCredentialsOptions c_opts; + c_opts.set_check_call_host(false); + auto creds = grpc::experimental::TlsCredentials(c_opts); + auto result = ViamChannel(sdk::impl::create_viam_grpc_channel(uri, creds)); + result.auth_token_ = resp.access_token(); + + return result; +#else + (void)uri; + (void)opts; + throw std::logic_error("Tried to call dial_direct on unsupported grpc version " + + grpc::Version()); +#endif } -void ViamChannel::close() { - pimpl_.reset(); +const std::shared_ptr& ViamChannel::channel() const { + return channel_; } -unsigned int Options::refresh_interval() const { - return refresh_interval_; +const boost::optional& ViamChannel::auth_token() const { + return auth_token_; } -const boost::optional& Options::dial_options() const { - return dial_options_; +void ViamChannel::close() { + pimpl_.reset(); } Credentials::Credentials(std::string payload) diff --git a/src/viam/sdk/rpc/dial.hpp b/src/viam/sdk/rpc/dial.hpp index c05b28d08..3b16f00c7 100644 --- a/src/viam/sdk/rpc/dial.hpp +++ b/src/viam/sdk/rpc/dial.hpp @@ -11,7 +11,8 @@ namespace viam { namespace sdk { -class DialOptions; +struct DialOptions; + class ViamChannel { ViamChannel(std::shared_ptr channel, const char* path, void* runtime); @@ -32,24 +33,36 @@ class ViamChannel { /// @throws Exception if it is unable to establish a connection to the provided URI static ViamChannel dial(const char* uri, const boost::optional& options); - // @brief Dials to a robot at the given URI address, using the provided dial options (or default - // options is none are provided). Additionally specifies that this dial is an initial connection - // attempt and so uses the initial connection options. - /// In general, use of this method is discouraged. `RobotClient::at_address(...)` is the - /// preferred method to connect to a robot, and creates the channel itself. + /// @brief Dials to a robot at the given URI address, using the provided dial options (or + /// default options is none are provided). + /// Additionally specifies that this dial is an initial + /// connection attempt and so uses the initial connection options. In general, use of this + /// method is discouraged. `RobotClient::at_address(...)` is the preferred method to connect to + /// a robot, and creates the channel itself. /// @throws Exception if it is unable to establish a connection to the provided URI within /// the given number of initial connection attempts static ViamChannel dial_initial(const char* uri, const boost::optional& options); const std::shared_ptr& channel() const; + /// @brief Returns the bearer token for connecting to the robot if one is needed; else returns + /// null. + /// @remark When dialing with disable_webrtc = true and grpc >= 1.43.0, a bearer token is needed + /// for all client requests. If you use ClientHelper for client requests this is handled + /// automatically, otherwise you will have to add this to the client context of a grpc call. + const boost::optional& auth_token() const; + void close(); private: struct impl; + static ViamChannel dial_direct(const char* uri, const DialOptions& opts); + std::shared_ptr channel_; + boost::optional auth_token_; + std::unique_ptr pimpl_; }; @@ -66,64 +79,34 @@ class Credentials { std::string payload_; }; -class DialOptions { - public: - DialOptions(); - - const boost::optional& credentials() const; - const boost::optional& entity() const; - bool allows_insecure_downgrade() const; - const std::chrono::duration& timeout() const; - int initial_connection_attempts() const; - std::chrono::duration initial_connection_attempt_timeout() const; - - DialOptions& set_entity(boost::optional entity); - DialOptions& set_credentials(boost::optional creds); - DialOptions& set_allow_insecure_downgrade(bool allow); - DialOptions& set_timeout(std::chrono::duration timeout); - DialOptions& set_initial_connection_attempts(int attempts); - DialOptions& set_initial_connection_attempt_timeout(std::chrono::duration timeout); - - private: - // TODO (RSDK-917): We currently don't provide a flag for disabling webRTC, instead relying on a - // `local` uri. We should update dial logic to consider such a flag. - +struct DialOptions { /// @brief the URL to authenticate against. - boost::optional auth_entity_; + boost::optional auth_entity; /// @brief Credentials for connecting to the robot. - boost::optional credentials_; + boost::optional credentials; /// @brief Allows the RPC connection to be downgraded to an insecure connection if detected. /// This is only used when credentials are not present. - bool allow_insecure_downgrade_ = false; + bool allow_insecure_downgrade = false; + + /// @brief Bypass WebRTC and connect directly to the robot. + /// This dials directly through grpc bypassing rust utils. + /// @remark Direct dialing should generally be done with a machine URI of the form + /// ..local.viam.cloud:8080 + bool disable_webrtc = false; /// @brief Duration before the dial connection times out /// Set to 20sec to match _defaultOfferDeadline in goutils/rpc/wrtc_call_queue.go - std::chrono::duration timeout_{20}; + std::chrono::duration timeout{20}; /// @brief Number of attempts to make when initially connecting to a robot /// If set to 0 or a negative integer, will attempt to reconnect forever. - int initial_connection_attempts_ = 3; + int initial_connection_attempts = 3; /// @brief Timeout of connection attempts when initially dialing a robot /// Defaults to 20sec to match the default timeout duration - std::chrono::duration initial_connection_attempt_timeout_{20}; -}; - -class Options { - public: - Options(unsigned int refresh_interval, boost::optional dial_options) - : refresh_interval_(std::move(refresh_interval)), dial_options_(std::move(dial_options)) {} - - unsigned int refresh_interval() const; - const boost::optional& dial_options() const; - - private: - /// @brief How often to refresh the status/parts of the robot, in seconds. If set to 0, the - /// robot will not automatically refresh. - unsigned int refresh_interval_; - boost::optional dial_options_; + std::chrono::duration initial_connection_attempt_timeout{20}; }; } // namespace sdk diff --git a/src/viam/sdk/rpc/private/viam_grpc_channel.cpp b/src/viam/sdk/rpc/private/viam_grpc_channel.cpp index 909ec6a55..fe44fa491 100644 --- a/src/viam/sdk/rpc/private/viam_grpc_channel.cpp +++ b/src/viam/sdk/rpc/private/viam_grpc_channel.cpp @@ -9,7 +9,17 @@ namespace viam { namespace sdk { namespace impl { -std::shared_ptr create_viam_channel( +#ifndef VIAMCPPSDK_GRPCXX_NO_DIRECT_DIAL +std::shared_ptr create_viam_auth_channel(const std::string& address) { + grpc::experimental::TlsChannelCredentialsOptions opts; + opts.set_check_call_host(false); + auto tls_creds = grpc::experimental::TlsCredentials(opts); + + return grpc::CreateChannel(address, tls_creds); +} +#endif + +std::shared_ptr create_viam_grpc_channel( const grpc::string& target, const std::shared_ptr& credentials) { grpc::ChannelArguments args; args.SetMaxSendMessageSize(kMaxMessageSize); diff --git a/src/viam/sdk/rpc/private/viam_grpc_channel.hpp b/src/viam/sdk/rpc/private/viam_grpc_channel.hpp index 1f6989317..570030ee6 100644 --- a/src/viam/sdk/rpc/private/viam_grpc_channel.hpp +++ b/src/viam/sdk/rpc/private/viam_grpc_channel.hpp @@ -5,15 +5,23 @@ #include #include +#include + namespace viam { namespace sdk { namespace impl { /// @brief Like grpc::CreateChannel, but returns a channel suitable for transmitting messages of /// size kMaxMessageSize. -std::shared_ptr create_viam_channel( +std::shared_ptr create_viam_grpc_channel( const grpc::string& target, const std::shared_ptr& credentials); +#ifndef VIAMCPPSDK_GRPCXX_NO_DIRECT_DIAL +/// @brief Like grpc::CreateChannel, but for the express purpose of returning a channel for making +/// an AuthService request. +std::shared_ptr create_viam_auth_channel(const std::string& address); +#endif + } // namespace impl } // namespace sdk } // namespace viam diff --git a/src/viam/sdk/services/private/discovery_client.cpp b/src/viam/sdk/services/private/discovery_client.cpp index 398cfe609..4dfc9362f 100644 --- a/src/viam/sdk/services/private/discovery_client.cpp +++ b/src/viam/sdk/services/private/discovery_client.cpp @@ -1,5 +1,7 @@ #include +#include + #include #include @@ -13,10 +15,10 @@ namespace viam { namespace sdk { namespace impl { -DiscoveryClient::DiscoveryClient(std::string name, std::shared_ptr channel) +DiscoveryClient::DiscoveryClient(std::string name, const ViamChannel& channel) : Discovery(std::move(name)), - stub_(viam::service::discovery::v1::DiscoveryService::NewStub(channel)), - channel_(std::move(channel)) {} + stub_(viam::service::discovery::v1::DiscoveryService::NewStub(channel.channel())), + channel_(&channel) {} std::vector DiscoveryClient::discover_resources(const ProtoStruct& extra) { return make_client_helper(this, *stub_, &StubType::DiscoverResources) diff --git a/src/viam/sdk/services/private/discovery_client.hpp b/src/viam/sdk/services/private/discovery_client.hpp index 4b47cd4cc..60d797ab4 100644 --- a/src/viam/sdk/services/private/discovery_client.hpp +++ b/src/viam/sdk/services/private/discovery_client.hpp @@ -3,10 +3,9 @@ /// @brief Implements a gRPC client for the `Discovery` service #pragma once -#include - #include +#include #include namespace viam { @@ -19,7 +18,11 @@ namespace impl { class DiscoveryClient : public Discovery { public: using interface_type = Discovery; - DiscoveryClient(std::string name, std::shared_ptr channel); + DiscoveryClient(std::string name, const ViamChannel& channel); + + const ViamChannel& channel() const { + return *channel_; + } std::vector discover_resources(const ProtoStruct& extra) override; ProtoStruct do_command(const ProtoStruct& command) override; @@ -27,7 +30,7 @@ class DiscoveryClient : public Discovery { private: using StubType = viam::service::discovery::v1::DiscoveryService::StubInterface; std::unique_ptr stub_; - std::shared_ptr channel_; + const ViamChannel* channel_; }; } // namespace impl diff --git a/src/viam/sdk/services/private/generic_client.cpp b/src/viam/sdk/services/private/generic_client.cpp index 50efa1a8b..5c6c97a22 100644 --- a/src/viam/sdk/services/private/generic_client.cpp +++ b/src/viam/sdk/services/private/generic_client.cpp @@ -2,6 +2,8 @@ #include +#include + #include #include @@ -15,10 +17,10 @@ namespace viam { namespace sdk { namespace impl { -GenericServiceClient::GenericServiceClient(std::string name, std::shared_ptr channel) +GenericServiceClient::GenericServiceClient(std::string name, const ViamChannel& channel) : GenericService(std::move(name)), - stub_(viam::service::generic::v1::GenericService::NewStub(channel)), - channel_(std::move(channel)) {} + stub_(viam::service::generic::v1::GenericService::NewStub(channel.channel())), + channel_(&channel) {} ProtoStruct GenericServiceClient::do_command(const ProtoStruct& command) { return make_client_helper(this, *stub_, &StubType::DoCommand) diff --git a/src/viam/sdk/services/private/generic_client.hpp b/src/viam/sdk/services/private/generic_client.hpp index e5e72cd99..e849da70a 100644 --- a/src/viam/sdk/services/private/generic_client.hpp +++ b/src/viam/sdk/services/private/generic_client.hpp @@ -3,11 +3,10 @@ /// @brief Implements a gRPC client for the `GenericService`. #pragma once -#include - #include #include +#include #include namespace viam { @@ -20,7 +19,12 @@ namespace impl { class GenericServiceClient : public GenericService { public: using interface_type = GenericService; - GenericServiceClient(std::string name, std::shared_ptr channel); + GenericServiceClient(std::string name, const ViamChannel& channel); + + const ViamChannel& channel() const { + return *channel_; + } + ProtoStruct do_command(const ProtoStruct& command) override; protected: @@ -30,12 +34,12 @@ class GenericServiceClient : public GenericService { GenericServiceClient( std::string name, std::unique_ptr stub) - : GenericService(std::move(name)), stub_(std::move(stub)){}; + : GenericService(std::move(name)), stub_(std::move(stub)) {} private: using StubType = viam::service::generic::v1::GenericService::StubInterface; std::unique_ptr stub_; - std::shared_ptr channel_; + const ViamChannel* channel_; }; } // namespace impl diff --git a/src/viam/sdk/services/private/mlmodel_client.cpp b/src/viam/sdk/services/private/mlmodel_client.cpp index be8cf40c1..4383010be 100644 --- a/src/viam/sdk/services/private/mlmodel_client.cpp +++ b/src/viam/sdk/services/private/mlmodel_client.cpp @@ -35,10 +35,10 @@ namespace viam { namespace sdk { namespace impl { -MLModelServiceClient::MLModelServiceClient(std::string name, std::shared_ptr channel) +MLModelServiceClient::MLModelServiceClient(std::string name, const ViamChannel& channel) : MLModelService(std::move(name)), - channel_(std::move(channel)), - stub_(service_type::NewStub(channel_)) {} + stub_(service_type::NewStub(channel.channel())), + channel_(&channel) {} std::shared_ptr MLModelServiceClient::infer( const named_tensor_views& inputs, const ProtoStruct& extra) { diff --git a/src/viam/sdk/services/private/mlmodel_client.hpp b/src/viam/sdk/services/private/mlmodel_client.hpp index 4cab6aa5d..93355c9f3 100644 --- a/src/viam/sdk/services/private/mlmodel_client.hpp +++ b/src/viam/sdk/services/private/mlmodel_client.hpp @@ -16,8 +16,7 @@ #include -#include - +#include #include namespace viam { @@ -34,7 +33,11 @@ class MLModelServiceClient : public MLModelService { using interface_type = MLModelService; using service_type = viam::service::mlmodel::v1::MLModelService; - MLModelServiceClient(std::string name, std::shared_ptr channel); + MLModelServiceClient(std::string name, const ViamChannel& channel); + + const ViamChannel& channel() const { + return *channel_; + } std::shared_ptr infer(const named_tensor_views& inputs, const ProtoStruct& extra) override; @@ -53,8 +56,8 @@ class MLModelServiceClient : public MLModelService { using MLModelService::metadata; private: - std::shared_ptr channel_; std::unique_ptr stub_; + const ViamChannel* channel_; }; } // namespace impl diff --git a/src/viam/sdk/services/private/motion_client.cpp b/src/viam/sdk/services/private/motion_client.cpp index eddcd959e..e62763cdc 100644 --- a/src/viam/sdk/services/private/motion_client.cpp +++ b/src/viam/sdk/services/private/motion_client.cpp @@ -2,6 +2,7 @@ #include +#include #include #include @@ -178,10 +179,10 @@ std::vector from_proto( return plans; } -MotionClient::MotionClient(std::string name, std::shared_ptr channel) +MotionClient::MotionClient(std::string name, const ViamChannel& channel) : Motion(std::move(name)), - stub_(service::motion::v1::MotionService::NewStub(channel)), - channel_(std::move(channel)) {} + stub_(service::motion::v1::MotionService::NewStub(channel.channel())), + channel_(&channel) {} bool MotionClient::move(const pose_in_frame& destination, const Name& component_name, diff --git a/src/viam/sdk/services/private/motion_client.hpp b/src/viam/sdk/services/private/motion_client.hpp index 1fc57141c..efb7f1995 100644 --- a/src/viam/sdk/services/private/motion_client.hpp +++ b/src/viam/sdk/services/private/motion_client.hpp @@ -3,10 +3,9 @@ /// @brief Implements a gRPC client for the `Motion` service. #pragma once -#include - #include +#include #include namespace viam { @@ -19,7 +18,12 @@ namespace impl { class MotionClient : public Motion { public: using interface_type = Motion; - MotionClient(std::string name, std::shared_ptr channel); + MotionClient(std::string name, const ViamChannel& channel); + + const ViamChannel& channel() const { + return *channel_; + } + bool move(const pose_in_frame& destination, const Name& component_name, const std::shared_ptr& world_state, @@ -104,7 +108,7 @@ class MotionClient : public Motion { bool last_plan_only, const ProtoStruct& extra); std::unique_ptr stub_; - std::shared_ptr channel_; + const ViamChannel* channel_; }; } // namespace impl diff --git a/src/viam/sdk/services/private/navigation_client.cpp b/src/viam/sdk/services/private/navigation_client.cpp index fdff15b9d..27914f1be 100644 --- a/src/viam/sdk/services/private/navigation_client.cpp +++ b/src/viam/sdk/services/private/navigation_client.cpp @@ -2,6 +2,7 @@ #include +#include #include #include @@ -38,10 +39,10 @@ namespace impl { using namespace viam::service::navigation::v1; -NavigationClient::NavigationClient(std::string name, std::shared_ptr channel) +NavigationClient::NavigationClient(std::string name, const ViamChannel& channel) : Navigation(std::move(name)), - stub_(service::navigation::v1::NavigationService::NewStub(channel)), - channel_(std::move(channel)) {} + stub_(service::navigation::v1::NavigationService::NewStub(channel.channel())), + channel_(&channel) {} Navigation::Mode NavigationClient::get_mode(const ProtoStruct& extra) { return make_client_helper(this, *stub_, &StubType::GetMode) diff --git a/src/viam/sdk/services/private/navigation_client.hpp b/src/viam/sdk/services/private/navigation_client.hpp index 8f32fb38f..106ddf16b 100644 --- a/src/viam/sdk/services/private/navigation_client.hpp +++ b/src/viam/sdk/services/private/navigation_client.hpp @@ -3,10 +3,9 @@ /// @brief Implements a gRPC client for the `Navigation` service. #pragma once -#include - #include +#include #include namespace viam { @@ -19,7 +18,11 @@ namespace impl { class NavigationClient : public Navigation { public: using interface_type = Navigation; - NavigationClient(std::string name, std::shared_ptr channel); + NavigationClient(std::string name, const ViamChannel& channel); + + const ViamChannel& channel() const { + return *channel_; + } Mode get_mode(const ProtoStruct& extra) override; void set_mode(const Mode mode, const ProtoStruct& extra) override; @@ -35,7 +38,7 @@ class NavigationClient : public Navigation { private: using StubType = service::navigation::v1::NavigationService::StubInterface; std::unique_ptr stub_; - std::shared_ptr channel_; + const ViamChannel* channel_; }; } // namespace impl diff --git a/src/viam/sdk/tests/test_robot.cpp b/src/viam/sdk/tests/test_robot.cpp index 18137d258..0ad57f1c2 100644 --- a/src/viam/sdk/tests/test_robot.cpp +++ b/src/viam/sdk/tests/test_robot.cpp @@ -50,11 +50,11 @@ void robot_client_to_mocks_pipeline(F&& test_case) { // in-process gRPC channel. auto test_server = TestServer(server); auto grpc_channel = test_server.grpc_in_process_channel(); - auto client = RobotClient::with_channel(ViamChannel(grpc_channel), Options(0, boost::none)); + auto client = RobotClient::with_channel(ViamChannel(grpc_channel), {}); // Run the passed-in test case on the created stack and give access to the // created RobotClient and MockRobotService. - std::forward(test_case)(client, service); + std::forward(test_case)(std::move(client), service); } BOOST_AUTO_TEST_CASE(test_registering_resources) { @@ -95,7 +95,7 @@ BOOST_AUTO_TEST_CASE(test_registering_resources) { BOOST_AUTO_TEST_CASE(test_resource_names) { robot_client_to_mocks_pipeline( - [](std::shared_ptr client, MockRobotService& service) -> void { + [](std::unique_ptr client, MockRobotService& service) -> void { std::vector names = client->resource_names(); auto mocks = mock_resource_names_response(); BOOST_TEST(names == mocks, boost::test_tools::per_element()); @@ -106,7 +106,7 @@ BOOST_AUTO_TEST_CASE(test_resource_names) { // the proto and custom type versions. BOOST_AUTO_TEST_CASE(test_frame_system_config) { robot_client_to_mocks_pipeline( - [](std::shared_ptr client, MockRobotService& service) -> void { + [](std::unique_ptr client, MockRobotService& service) -> void { auto configs = mock_config_response(); auto config1 = configs[0]; auto config2 = configs[1]; @@ -138,7 +138,7 @@ BOOST_AUTO_TEST_CASE(test_frame_system_config) { BOOST_AUTO_TEST_CASE(test_get_frame_system_config) { robot_client_to_mocks_pipeline( - [](std::shared_ptr client, MockRobotService& service) -> void { + [](std::unique_ptr client, MockRobotService& service) -> void { auto mock_fs_config = mock_config_response(); auto fs_config = client->get_frame_system_config(); @@ -150,7 +150,7 @@ BOOST_AUTO_TEST_CASE(test_get_frame_system_config) { // the proto and custom type versions. BOOST_AUTO_TEST_CASE(test_operation) { robot_client_to_mocks_pipeline( - [](std::shared_ptr client, MockRobotService& service) -> void { + [](std::unique_ptr client, MockRobotService& service) -> void { auto ops = mock_operations_response(); auto op1 = ops[0]; auto op2 = ops[1]; @@ -169,7 +169,7 @@ BOOST_AUTO_TEST_CASE(test_operation) { BOOST_AUTO_TEST_CASE(test_get_operations) { robot_client_to_mocks_pipeline( - [](std::shared_ptr client, MockRobotService& service) -> void { + [](std::unique_ptr client, MockRobotService& service) -> void { auto ops = client->get_operations(); auto mock_ops = mock_operations_response(); @@ -179,7 +179,7 @@ BOOST_AUTO_TEST_CASE(test_get_operations) { BOOST_AUTO_TEST_CASE(test_transform_pose) { robot_client_to_mocks_pipeline( - [](std::shared_ptr client, MockRobotService& service) -> void { + [](std::unique_ptr client, MockRobotService& service) -> void { pose_in_frame pif; auto pose = client->transform_pose(pif, "", {}); auto mock_pose = mock_transform_response(); @@ -190,7 +190,7 @@ BOOST_AUTO_TEST_CASE(test_transform_pose) { BOOST_AUTO_TEST_CASE(test_get_machine_status) { robot_client_to_mocks_pipeline( - [](std::shared_ptr client, MockRobotService& service) -> void { + [](std::unique_ptr client, MockRobotService& service) -> void { auto status = client->get_machine_status(); BOOST_CHECK_EQUAL(status, RobotClient::status::k_running); @@ -199,7 +199,7 @@ BOOST_AUTO_TEST_CASE(test_get_machine_status) { BOOST_AUTO_TEST_CASE(test_stop_all) { robot_client_to_mocks_pipeline( - [](std::shared_ptr client, MockRobotService& service) -> void { + [](std::unique_ptr client, MockRobotService& service) -> void { std::shared_ptr rb = service.resource_manager()->resource("mock_motor"); auto motor = std::dynamic_pointer_cast(rb); BOOST_CHECK(motor); @@ -215,7 +215,7 @@ BOOST_AUTO_TEST_CASE(test_stop_all) { BOOST_AUTO_TEST_CASE(test_get_resource) { robot_client_to_mocks_pipeline( - [](std::shared_ptr client, MockRobotService& service) -> void { + [](std::unique_ptr client, MockRobotService& service) -> void { auto mock_motor = client->resource_by_name("mock_motor"); BOOST_CHECK(mock_motor); diff --git a/src/viam/sdk/tests/test_utils.hpp b/src/viam/sdk/tests/test_utils.hpp index a06de3a30..9ba12976e 100644 --- a/src/viam/sdk/tests/test_utils.hpp +++ b/src/viam/sdk/tests/test_utils.hpp @@ -92,11 +92,11 @@ void client_to_mock_pipeline(std::shared_ptr mock, F&& test_case) { // Create a resource-specific client to the mock over an established // in-process gRPC channel. auto test_server = TestServer(server); - auto grpc_channel = test_server.grpc_in_process_channel(); + auto channel = sdk::ViamChannel(test_server.grpc_in_process_channel()); auto resource_client = sdk::Registry::get() .lookup_resource_client(API::get()) - ->create_rpc_client(mock->name(), std::move(grpc_channel)); + ->create_rpc_client(mock->name(), channel); // Run the passed-in test case on the created stack and give access to the // created resource-specific client.