diff --git a/Makefile b/Makefile
index d3c0a80..5e38f30 100644
--- a/Makefile
+++ b/Makefile
@@ -22,7 +22,7 @@
 SHELL = bash -e -o pipefail
 
 # tool containers
-VOLTHA_TOOLS_VERSION ?= 2.0.0
+VOLTHA_TOOLS_VERSION ?= 2.5.0
 
 PROTOC    = docker run --rm --user $$(id -u):$$(id -g) -v ${CURDIR}:/app $(shell test -t 0 && echo "-it") voltha/voltha-ci-tools:${VOLTHA_TOOLS_VERSION}-protoc protoc
 PROTOC_SH = docker run --rm --user $$(id -u):$$(id -g) -v ${CURDIR}:/go/src/github.com/opencord/device-management-interface/v3 $(shell test -t 0 && echo "-it") --workdir=/go/src/github.com/opencord/device-management-interface/v3 voltha/voltha-ci-tools:${VOLTHA_TOOLS_VERSION}-protoc sh -c
@@ -103,7 +103,8 @@
       set -e -o pipefail; \
       for x in ${PROTO_FILES}; do \
 		echo \$$x; \
-		protoc --cpp_out=\$(PROTO_CPP_DEST_DIR) --plugin=protoc-gen-grpc=`which grpc_cpp_plugin` -I protos \$$x; \
+		protoc --cpp_out=\$(PROTO_CPP_DEST_DIR) -I protos \$$x; \
+		protoc --grpc_out=\$(PROTO_CPP_DEST_DIR) --plugin=protoc-gen-grpc=/usr/local/bin/grpc_cpp_plugin -I protos \$$x; \
 	  done"
 
 go-test:
diff --git a/VERSION b/VERSION
index a803cc2..930e300 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-0.14.0
+0.14.1
diff --git a/cpp/dmi/commons.grpc.pb.cc b/cpp/dmi/commons.grpc.pb.cc
new file mode 100644
index 0000000..3ef0aea
--- /dev/null
+++ b/cpp/dmi/commons.grpc.pb.cc
@@ -0,0 +1,25 @@
+// Generated by the gRPC C++ plugin.
+// If you make any local change, they will be lost.
+// source: dmi/commons.proto
+
+#include "dmi/commons.pb.h"
+#include "dmi/commons.grpc.pb.h"
+
+#include <functional>
+#include <grpcpp/impl/codegen/async_stream.h>
+#include <grpcpp/impl/codegen/async_unary_call.h>
+#include <grpcpp/impl/codegen/channel_interface.h>
+#include <grpcpp/impl/codegen/client_unary_call.h>
+#include <grpcpp/impl/codegen/client_callback.h>
+#include <grpcpp/impl/codegen/message_allocator.h>
+#include <grpcpp/impl/codegen/method_handler.h>
+#include <grpcpp/impl/codegen/rpc_service_method.h>
+#include <grpcpp/impl/codegen/server_callback.h>
+#include <grpcpp/impl/codegen/server_callback_handlers.h>
+#include <grpcpp/impl/codegen/server_context.h>
+#include <grpcpp/impl/codegen/service_type.h>
+#include <grpcpp/impl/codegen/sync_stream.h>
+namespace dmi {
+
+}  // namespace dmi
+
diff --git a/cpp/dmi/commons.grpc.pb.h b/cpp/dmi/commons.grpc.pb.h
new file mode 100644
index 0000000..9b6a00f
--- /dev/null
+++ b/cpp/dmi/commons.grpc.pb.h
@@ -0,0 +1,34 @@
+// Generated by the gRPC C++ plugin.
+// If you make any local change, they will be lost.
+// source: dmi/commons.proto
+#ifndef GRPC_dmi_2fcommons_2eproto__INCLUDED
+#define GRPC_dmi_2fcommons_2eproto__INCLUDED
+
+#include "dmi/commons.pb.h"
+
+#include <functional>
+#include <grpc/impl/codegen/port_platform.h>
+#include <grpcpp/impl/codegen/async_generic_service.h>
+#include <grpcpp/impl/codegen/async_stream.h>
+#include <grpcpp/impl/codegen/async_unary_call.h>
+#include <grpcpp/impl/codegen/client_callback.h>
+#include <grpcpp/impl/codegen/client_context.h>
+#include <grpcpp/impl/codegen/completion_queue.h>
+#include <grpcpp/impl/codegen/message_allocator.h>
+#include <grpcpp/impl/codegen/method_handler.h>
+#include <grpcpp/impl/codegen/proto_utils.h>
+#include <grpcpp/impl/codegen/rpc_method.h>
+#include <grpcpp/impl/codegen/server_callback.h>
+#include <grpcpp/impl/codegen/server_callback_handlers.h>
+#include <grpcpp/impl/codegen/server_context.h>
+#include <grpcpp/impl/codegen/service_type.h>
+#include <grpcpp/impl/codegen/status.h>
+#include <grpcpp/impl/codegen/stub_options.h>
+#include <grpcpp/impl/codegen/sync_stream.h>
+
+namespace dmi {
+
+}  // namespace dmi
+
+
+#endif  // GRPC_dmi_2fcommons_2eproto__INCLUDED
diff --git a/cpp/dmi/hw.grpc.pb.cc b/cpp/dmi/hw.grpc.pb.cc
new file mode 100644
index 0000000..99096fc
--- /dev/null
+++ b/cpp/dmi/hw.grpc.pb.cc
@@ -0,0 +1,25 @@
+// Generated by the gRPC C++ plugin.
+// If you make any local change, they will be lost.
+// source: dmi/hw.proto
+
+#include "dmi/hw.pb.h"
+#include "dmi/hw.grpc.pb.h"
+
+#include <functional>
+#include <grpcpp/impl/codegen/async_stream.h>
+#include <grpcpp/impl/codegen/async_unary_call.h>
+#include <grpcpp/impl/codegen/channel_interface.h>
+#include <grpcpp/impl/codegen/client_unary_call.h>
+#include <grpcpp/impl/codegen/client_callback.h>
+#include <grpcpp/impl/codegen/message_allocator.h>
+#include <grpcpp/impl/codegen/method_handler.h>
+#include <grpcpp/impl/codegen/rpc_service_method.h>
+#include <grpcpp/impl/codegen/server_callback.h>
+#include <grpcpp/impl/codegen/server_callback_handlers.h>
+#include <grpcpp/impl/codegen/server_context.h>
+#include <grpcpp/impl/codegen/service_type.h>
+#include <grpcpp/impl/codegen/sync_stream.h>
+namespace dmi {
+
+}  // namespace dmi
+
diff --git a/cpp/dmi/hw.grpc.pb.h b/cpp/dmi/hw.grpc.pb.h
new file mode 100644
index 0000000..632ea9d
--- /dev/null
+++ b/cpp/dmi/hw.grpc.pb.h
@@ -0,0 +1,34 @@
+// Generated by the gRPC C++ plugin.
+// If you make any local change, they will be lost.
+// source: dmi/hw.proto
+#ifndef GRPC_dmi_2fhw_2eproto__INCLUDED
+#define GRPC_dmi_2fhw_2eproto__INCLUDED
+
+#include "dmi/hw.pb.h"
+
+#include <functional>
+#include <grpc/impl/codegen/port_platform.h>
+#include <grpcpp/impl/codegen/async_generic_service.h>
+#include <grpcpp/impl/codegen/async_stream.h>
+#include <grpcpp/impl/codegen/async_unary_call.h>
+#include <grpcpp/impl/codegen/client_callback.h>
+#include <grpcpp/impl/codegen/client_context.h>
+#include <grpcpp/impl/codegen/completion_queue.h>
+#include <grpcpp/impl/codegen/message_allocator.h>
+#include <grpcpp/impl/codegen/method_handler.h>
+#include <grpcpp/impl/codegen/proto_utils.h>
+#include <grpcpp/impl/codegen/rpc_method.h>
+#include <grpcpp/impl/codegen/server_callback.h>
+#include <grpcpp/impl/codegen/server_callback_handlers.h>
+#include <grpcpp/impl/codegen/server_context.h>
+#include <grpcpp/impl/codegen/service_type.h>
+#include <grpcpp/impl/codegen/status.h>
+#include <grpcpp/impl/codegen/stub_options.h>
+#include <grpcpp/impl/codegen/sync_stream.h>
+
+namespace dmi {
+
+}  // namespace dmi
+
+
+#endif  // GRPC_dmi_2fhw_2eproto__INCLUDED
diff --git a/cpp/dmi/hw_events_mgmt_service.grpc.pb.cc b/cpp/dmi/hw_events_mgmt_service.grpc.pb.cc
new file mode 100644
index 0000000..450a295
--- /dev/null
+++ b/cpp/dmi/hw_events_mgmt_service.grpc.pb.cc
@@ -0,0 +1,138 @@
+// Generated by the gRPC C++ plugin.
+// If you make any local change, they will be lost.
+// source: dmi/hw_events_mgmt_service.proto
+
+#include "dmi/hw_events_mgmt_service.pb.h"
+#include "dmi/hw_events_mgmt_service.grpc.pb.h"
+
+#include <functional>
+#include <grpcpp/impl/codegen/async_stream.h>
+#include <grpcpp/impl/codegen/async_unary_call.h>
+#include <grpcpp/impl/codegen/channel_interface.h>
+#include <grpcpp/impl/codegen/client_unary_call.h>
+#include <grpcpp/impl/codegen/client_callback.h>
+#include <grpcpp/impl/codegen/message_allocator.h>
+#include <grpcpp/impl/codegen/method_handler.h>
+#include <grpcpp/impl/codegen/rpc_service_method.h>
+#include <grpcpp/impl/codegen/server_callback.h>
+#include <grpcpp/impl/codegen/server_callback_handlers.h>
+#include <grpcpp/impl/codegen/server_context.h>
+#include <grpcpp/impl/codegen/service_type.h>
+#include <grpcpp/impl/codegen/sync_stream.h>
+namespace dmi {
+
+static const char* NativeEventsManagementService_method_names[] = {
+  "/dmi.NativeEventsManagementService/ListEvents",
+  "/dmi.NativeEventsManagementService/UpdateEventsConfiguration",
+};
+
+std::unique_ptr< NativeEventsManagementService::Stub> NativeEventsManagementService::NewStub(const std::shared_ptr< ::grpc::ChannelInterface>& channel, const ::grpc::StubOptions& options) {
+  (void)options;
+  std::unique_ptr< NativeEventsManagementService::Stub> stub(new NativeEventsManagementService::Stub(channel));
+  return stub;
+}
+
+NativeEventsManagementService::Stub::Stub(const std::shared_ptr< ::grpc::ChannelInterface>& channel)
+  : channel_(channel), rpcmethod_ListEvents_(NativeEventsManagementService_method_names[0], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
+  , rpcmethod_UpdateEventsConfiguration_(NativeEventsManagementService_method_names[1], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
+  {}
+
+::grpc::Status NativeEventsManagementService::Stub::ListEvents(::grpc::ClientContext* context, const ::dmi::HardwareID& request, ::dmi::ListEventsResponse* response) {
+  return ::grpc::internal::BlockingUnaryCall(channel_.get(), rpcmethod_ListEvents_, context, request, response);
+}
+
+void NativeEventsManagementService::Stub::experimental_async::ListEvents(::grpc::ClientContext* context, const ::dmi::HardwareID* request, ::dmi::ListEventsResponse* response, std::function<void(::grpc::Status)> f) {
+  ::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_ListEvents_, context, request, response, std::move(f));
+}
+
+void NativeEventsManagementService::Stub::experimental_async::ListEvents(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::ListEventsResponse* response, std::function<void(::grpc::Status)> f) {
+  ::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_ListEvents_, context, request, response, std::move(f));
+}
+
+void NativeEventsManagementService::Stub::experimental_async::ListEvents(::grpc::ClientContext* context, const ::dmi::HardwareID* request, ::dmi::ListEventsResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
+  ::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_ListEvents_, context, request, response, reactor);
+}
+
+void NativeEventsManagementService::Stub::experimental_async::ListEvents(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::ListEventsResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
+  ::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_ListEvents_, context, request, response, reactor);
+}
+
+::grpc::ClientAsyncResponseReader< ::dmi::ListEventsResponse>* NativeEventsManagementService::Stub::AsyncListEventsRaw(::grpc::ClientContext* context, const ::dmi::HardwareID& request, ::grpc::CompletionQueue* cq) {
+  return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::dmi::ListEventsResponse>::Create(channel_.get(), cq, rpcmethod_ListEvents_, context, request, true);
+}
+
+::grpc::ClientAsyncResponseReader< ::dmi::ListEventsResponse>* NativeEventsManagementService::Stub::PrepareAsyncListEventsRaw(::grpc::ClientContext* context, const ::dmi::HardwareID& request, ::grpc::CompletionQueue* cq) {
+  return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::dmi::ListEventsResponse>::Create(channel_.get(), cq, rpcmethod_ListEvents_, context, request, false);
+}
+
+::grpc::Status NativeEventsManagementService::Stub::UpdateEventsConfiguration(::grpc::ClientContext* context, const ::dmi::EventsConfigurationRequest& request, ::dmi::EventsConfigurationResponse* response) {
+  return ::grpc::internal::BlockingUnaryCall(channel_.get(), rpcmethod_UpdateEventsConfiguration_, context, request, response);
+}
+
+void NativeEventsManagementService::Stub::experimental_async::UpdateEventsConfiguration(::grpc::ClientContext* context, const ::dmi::EventsConfigurationRequest* request, ::dmi::EventsConfigurationResponse* response, std::function<void(::grpc::Status)> f) {
+  ::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_UpdateEventsConfiguration_, context, request, response, std::move(f));
+}
+
+void NativeEventsManagementService::Stub::experimental_async::UpdateEventsConfiguration(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::EventsConfigurationResponse* response, std::function<void(::grpc::Status)> f) {
+  ::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_UpdateEventsConfiguration_, context, request, response, std::move(f));
+}
+
+void NativeEventsManagementService::Stub::experimental_async::UpdateEventsConfiguration(::grpc::ClientContext* context, const ::dmi::EventsConfigurationRequest* request, ::dmi::EventsConfigurationResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
+  ::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_UpdateEventsConfiguration_, context, request, response, reactor);
+}
+
+void NativeEventsManagementService::Stub::experimental_async::UpdateEventsConfiguration(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::EventsConfigurationResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
+  ::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_UpdateEventsConfiguration_, context, request, response, reactor);
+}
+
+::grpc::ClientAsyncResponseReader< ::dmi::EventsConfigurationResponse>* NativeEventsManagementService::Stub::AsyncUpdateEventsConfigurationRaw(::grpc::ClientContext* context, const ::dmi::EventsConfigurationRequest& request, ::grpc::CompletionQueue* cq) {
+  return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::dmi::EventsConfigurationResponse>::Create(channel_.get(), cq, rpcmethod_UpdateEventsConfiguration_, context, request, true);
+}
+
+::grpc::ClientAsyncResponseReader< ::dmi::EventsConfigurationResponse>* NativeEventsManagementService::Stub::PrepareAsyncUpdateEventsConfigurationRaw(::grpc::ClientContext* context, const ::dmi::EventsConfigurationRequest& request, ::grpc::CompletionQueue* cq) {
+  return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::dmi::EventsConfigurationResponse>::Create(channel_.get(), cq, rpcmethod_UpdateEventsConfiguration_, context, request, false);
+}
+
+NativeEventsManagementService::Service::Service() {
+  AddMethod(new ::grpc::internal::RpcServiceMethod(
+      NativeEventsManagementService_method_names[0],
+      ::grpc::internal::RpcMethod::NORMAL_RPC,
+      new ::grpc::internal::RpcMethodHandler< NativeEventsManagementService::Service, ::dmi::HardwareID, ::dmi::ListEventsResponse>(
+          [](NativeEventsManagementService::Service* service,
+             ::grpc_impl::ServerContext* ctx,
+             const ::dmi::HardwareID* req,
+             ::dmi::ListEventsResponse* resp) {
+               return service->ListEvents(ctx, req, resp);
+             }, this)));
+  AddMethod(new ::grpc::internal::RpcServiceMethod(
+      NativeEventsManagementService_method_names[1],
+      ::grpc::internal::RpcMethod::NORMAL_RPC,
+      new ::grpc::internal::RpcMethodHandler< NativeEventsManagementService::Service, ::dmi::EventsConfigurationRequest, ::dmi::EventsConfigurationResponse>(
+          [](NativeEventsManagementService::Service* service,
+             ::grpc_impl::ServerContext* ctx,
+             const ::dmi::EventsConfigurationRequest* req,
+             ::dmi::EventsConfigurationResponse* resp) {
+               return service->UpdateEventsConfiguration(ctx, req, resp);
+             }, this)));
+}
+
+NativeEventsManagementService::Service::~Service() {
+}
+
+::grpc::Status NativeEventsManagementService::Service::ListEvents(::grpc::ServerContext* context, const ::dmi::HardwareID* request, ::dmi::ListEventsResponse* response) {
+  (void) context;
+  (void) request;
+  (void) response;
+  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+}
+
+::grpc::Status NativeEventsManagementService::Service::UpdateEventsConfiguration(::grpc::ServerContext* context, const ::dmi::EventsConfigurationRequest* request, ::dmi::EventsConfigurationResponse* response) {
+  (void) context;
+  (void) request;
+  (void) response;
+  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+}
+
+
+}  // namespace dmi
+
diff --git a/cpp/dmi/hw_events_mgmt_service.grpc.pb.h b/cpp/dmi/hw_events_mgmt_service.grpc.pb.h
new file mode 100644
index 0000000..b6877d1
--- /dev/null
+++ b/cpp/dmi/hw_events_mgmt_service.grpc.pb.h
@@ -0,0 +1,529 @@
+// Generated by the gRPC C++ plugin.
+// If you make any local change, they will be lost.
+// source: dmi/hw_events_mgmt_service.proto
+#ifndef GRPC_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto__INCLUDED
+#define GRPC_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto__INCLUDED
+
+#include "dmi/hw_events_mgmt_service.pb.h"
+
+#include <functional>
+#include <grpc/impl/codegen/port_platform.h>
+#include <grpcpp/impl/codegen/async_generic_service.h>
+#include <grpcpp/impl/codegen/async_stream.h>
+#include <grpcpp/impl/codegen/async_unary_call.h>
+#include <grpcpp/impl/codegen/client_callback.h>
+#include <grpcpp/impl/codegen/client_context.h>
+#include <grpcpp/impl/codegen/completion_queue.h>
+#include <grpcpp/impl/codegen/message_allocator.h>
+#include <grpcpp/impl/codegen/method_handler.h>
+#include <grpcpp/impl/codegen/proto_utils.h>
+#include <grpcpp/impl/codegen/rpc_method.h>
+#include <grpcpp/impl/codegen/server_callback.h>
+#include <grpcpp/impl/codegen/server_callback_handlers.h>
+#include <grpcpp/impl/codegen/server_context.h>
+#include <grpcpp/impl/codegen/service_type.h>
+#include <grpcpp/impl/codegen/status.h>
+#include <grpcpp/impl/codegen/stub_options.h>
+#include <grpcpp/impl/codegen/sync_stream.h>
+
+namespace dmi {
+
+class NativeEventsManagementService final {
+ public:
+  static constexpr char const* service_full_name() {
+    return "dmi.NativeEventsManagementService";
+  }
+  class StubInterface {
+   public:
+    virtual ~StubInterface() {}
+    // List the supported events for the passed device
+    virtual ::grpc::Status ListEvents(::grpc::ClientContext* context, const ::dmi::HardwareID& request, ::dmi::ListEventsResponse* response) = 0;
+    std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::ListEventsResponse>> AsyncListEvents(::grpc::ClientContext* context, const ::dmi::HardwareID& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::ListEventsResponse>>(AsyncListEventsRaw(context, request, cq));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::ListEventsResponse>> PrepareAsyncListEvents(::grpc::ClientContext* context, const ::dmi::HardwareID& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::ListEventsResponse>>(PrepareAsyncListEventsRaw(context, request, cq));
+    }
+    // Updates the configuration of the list of events in the request
+    // The default behavior of the device is to report all the supported events
+    // This configuration is persisted across reboots of the device or the device manager
+    virtual ::grpc::Status UpdateEventsConfiguration(::grpc::ClientContext* context, const ::dmi::EventsConfigurationRequest& request, ::dmi::EventsConfigurationResponse* response) = 0;
+    std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::EventsConfigurationResponse>> AsyncUpdateEventsConfiguration(::grpc::ClientContext* context, const ::dmi::EventsConfigurationRequest& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::EventsConfigurationResponse>>(AsyncUpdateEventsConfigurationRaw(context, request, cq));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::EventsConfigurationResponse>> PrepareAsyncUpdateEventsConfiguration(::grpc::ClientContext* context, const ::dmi::EventsConfigurationRequest& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::EventsConfigurationResponse>>(PrepareAsyncUpdateEventsConfigurationRaw(context, request, cq));
+    }
+    class experimental_async_interface {
+     public:
+      virtual ~experimental_async_interface() {}
+      // List the supported events for the passed device
+      virtual void ListEvents(::grpc::ClientContext* context, const ::dmi::HardwareID* request, ::dmi::ListEventsResponse* response, std::function<void(::grpc::Status)>) = 0;
+      virtual void ListEvents(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::ListEventsResponse* response, std::function<void(::grpc::Status)>) = 0;
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      virtual void ListEvents(::grpc::ClientContext* context, const ::dmi::HardwareID* request, ::dmi::ListEventsResponse* response, ::grpc::ClientUnaryReactor* reactor) = 0;
+      #else
+      virtual void ListEvents(::grpc::ClientContext* context, const ::dmi::HardwareID* request, ::dmi::ListEventsResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) = 0;
+      #endif
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      virtual void ListEvents(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::ListEventsResponse* response, ::grpc::ClientUnaryReactor* reactor) = 0;
+      #else
+      virtual void ListEvents(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::ListEventsResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) = 0;
+      #endif
+      // Updates the configuration of the list of events in the request
+      // The default behavior of the device is to report all the supported events
+      // This configuration is persisted across reboots of the device or the device manager
+      virtual void UpdateEventsConfiguration(::grpc::ClientContext* context, const ::dmi::EventsConfigurationRequest* request, ::dmi::EventsConfigurationResponse* response, std::function<void(::grpc::Status)>) = 0;
+      virtual void UpdateEventsConfiguration(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::EventsConfigurationResponse* response, std::function<void(::grpc::Status)>) = 0;
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      virtual void UpdateEventsConfiguration(::grpc::ClientContext* context, const ::dmi::EventsConfigurationRequest* request, ::dmi::EventsConfigurationResponse* response, ::grpc::ClientUnaryReactor* reactor) = 0;
+      #else
+      virtual void UpdateEventsConfiguration(::grpc::ClientContext* context, const ::dmi::EventsConfigurationRequest* request, ::dmi::EventsConfigurationResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) = 0;
+      #endif
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      virtual void UpdateEventsConfiguration(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::EventsConfigurationResponse* response, ::grpc::ClientUnaryReactor* reactor) = 0;
+      #else
+      virtual void UpdateEventsConfiguration(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::EventsConfigurationResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) = 0;
+      #endif
+    };
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+    typedef class experimental_async_interface async_interface;
+    #endif
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+    async_interface* async() { return experimental_async(); }
+    #endif
+    virtual class experimental_async_interface* experimental_async() { return nullptr; }
+  private:
+    virtual ::grpc::ClientAsyncResponseReaderInterface< ::dmi::ListEventsResponse>* AsyncListEventsRaw(::grpc::ClientContext* context, const ::dmi::HardwareID& request, ::grpc::CompletionQueue* cq) = 0;
+    virtual ::grpc::ClientAsyncResponseReaderInterface< ::dmi::ListEventsResponse>* PrepareAsyncListEventsRaw(::grpc::ClientContext* context, const ::dmi::HardwareID& request, ::grpc::CompletionQueue* cq) = 0;
+    virtual ::grpc::ClientAsyncResponseReaderInterface< ::dmi::EventsConfigurationResponse>* AsyncUpdateEventsConfigurationRaw(::grpc::ClientContext* context, const ::dmi::EventsConfigurationRequest& request, ::grpc::CompletionQueue* cq) = 0;
+    virtual ::grpc::ClientAsyncResponseReaderInterface< ::dmi::EventsConfigurationResponse>* PrepareAsyncUpdateEventsConfigurationRaw(::grpc::ClientContext* context, const ::dmi::EventsConfigurationRequest& request, ::grpc::CompletionQueue* cq) = 0;
+  };
+  class Stub final : public StubInterface {
+   public:
+    Stub(const std::shared_ptr< ::grpc::ChannelInterface>& channel);
+    ::grpc::Status ListEvents(::grpc::ClientContext* context, const ::dmi::HardwareID& request, ::dmi::ListEventsResponse* response) override;
+    std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::ListEventsResponse>> AsyncListEvents(::grpc::ClientContext* context, const ::dmi::HardwareID& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::ListEventsResponse>>(AsyncListEventsRaw(context, request, cq));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::ListEventsResponse>> PrepareAsyncListEvents(::grpc::ClientContext* context, const ::dmi::HardwareID& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::ListEventsResponse>>(PrepareAsyncListEventsRaw(context, request, cq));
+    }
+    ::grpc::Status UpdateEventsConfiguration(::grpc::ClientContext* context, const ::dmi::EventsConfigurationRequest& request, ::dmi::EventsConfigurationResponse* response) override;
+    std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::EventsConfigurationResponse>> AsyncUpdateEventsConfiguration(::grpc::ClientContext* context, const ::dmi::EventsConfigurationRequest& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::EventsConfigurationResponse>>(AsyncUpdateEventsConfigurationRaw(context, request, cq));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::EventsConfigurationResponse>> PrepareAsyncUpdateEventsConfiguration(::grpc::ClientContext* context, const ::dmi::EventsConfigurationRequest& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::EventsConfigurationResponse>>(PrepareAsyncUpdateEventsConfigurationRaw(context, request, cq));
+    }
+    class experimental_async final :
+      public StubInterface::experimental_async_interface {
+     public:
+      void ListEvents(::grpc::ClientContext* context, const ::dmi::HardwareID* request, ::dmi::ListEventsResponse* response, std::function<void(::grpc::Status)>) override;
+      void ListEvents(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::ListEventsResponse* response, std::function<void(::grpc::Status)>) override;
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      void ListEvents(::grpc::ClientContext* context, const ::dmi::HardwareID* request, ::dmi::ListEventsResponse* response, ::grpc::ClientUnaryReactor* reactor) override;
+      #else
+      void ListEvents(::grpc::ClientContext* context, const ::dmi::HardwareID* request, ::dmi::ListEventsResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) override;
+      #endif
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      void ListEvents(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::ListEventsResponse* response, ::grpc::ClientUnaryReactor* reactor) override;
+      #else
+      void ListEvents(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::ListEventsResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) override;
+      #endif
+      void UpdateEventsConfiguration(::grpc::ClientContext* context, const ::dmi::EventsConfigurationRequest* request, ::dmi::EventsConfigurationResponse* response, std::function<void(::grpc::Status)>) override;
+      void UpdateEventsConfiguration(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::EventsConfigurationResponse* response, std::function<void(::grpc::Status)>) override;
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      void UpdateEventsConfiguration(::grpc::ClientContext* context, const ::dmi::EventsConfigurationRequest* request, ::dmi::EventsConfigurationResponse* response, ::grpc::ClientUnaryReactor* reactor) override;
+      #else
+      void UpdateEventsConfiguration(::grpc::ClientContext* context, const ::dmi::EventsConfigurationRequest* request, ::dmi::EventsConfigurationResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) override;
+      #endif
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      void UpdateEventsConfiguration(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::EventsConfigurationResponse* response, ::grpc::ClientUnaryReactor* reactor) override;
+      #else
+      void UpdateEventsConfiguration(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::EventsConfigurationResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) override;
+      #endif
+     private:
+      friend class Stub;
+      explicit experimental_async(Stub* stub): stub_(stub) { }
+      Stub* stub() { return stub_; }
+      Stub* stub_;
+    };
+    class experimental_async_interface* experimental_async() override { return &async_stub_; }
+
+   private:
+    std::shared_ptr< ::grpc::ChannelInterface> channel_;
+    class experimental_async async_stub_{this};
+    ::grpc::ClientAsyncResponseReader< ::dmi::ListEventsResponse>* AsyncListEventsRaw(::grpc::ClientContext* context, const ::dmi::HardwareID& request, ::grpc::CompletionQueue* cq) override;
+    ::grpc::ClientAsyncResponseReader< ::dmi::ListEventsResponse>* PrepareAsyncListEventsRaw(::grpc::ClientContext* context, const ::dmi::HardwareID& request, ::grpc::CompletionQueue* cq) override;
+    ::grpc::ClientAsyncResponseReader< ::dmi::EventsConfigurationResponse>* AsyncUpdateEventsConfigurationRaw(::grpc::ClientContext* context, const ::dmi::EventsConfigurationRequest& request, ::grpc::CompletionQueue* cq) override;
+    ::grpc::ClientAsyncResponseReader< ::dmi::EventsConfigurationResponse>* PrepareAsyncUpdateEventsConfigurationRaw(::grpc::ClientContext* context, const ::dmi::EventsConfigurationRequest& request, ::grpc::CompletionQueue* cq) override;
+    const ::grpc::internal::RpcMethod rpcmethod_ListEvents_;
+    const ::grpc::internal::RpcMethod rpcmethod_UpdateEventsConfiguration_;
+  };
+  static std::unique_ptr<Stub> NewStub(const std::shared_ptr< ::grpc::ChannelInterface>& channel, const ::grpc::StubOptions& options = ::grpc::StubOptions());
+
+  class Service : public ::grpc::Service {
+   public:
+    Service();
+    virtual ~Service();
+    // List the supported events for the passed device
+    virtual ::grpc::Status ListEvents(::grpc::ServerContext* context, const ::dmi::HardwareID* request, ::dmi::ListEventsResponse* response);
+    // Updates the configuration of the list of events in the request
+    // The default behavior of the device is to report all the supported events
+    // This configuration is persisted across reboots of the device or the device manager
+    virtual ::grpc::Status UpdateEventsConfiguration(::grpc::ServerContext* context, const ::dmi::EventsConfigurationRequest* request, ::dmi::EventsConfigurationResponse* response);
+  };
+  template <class BaseClass>
+  class WithAsyncMethod_ListEvents : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithAsyncMethod_ListEvents() {
+      ::grpc::Service::MarkMethodAsync(0);
+    }
+    ~WithAsyncMethod_ListEvents() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status ListEvents(::grpc::ServerContext* /*context*/, const ::dmi::HardwareID* /*request*/, ::dmi::ListEventsResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    void RequestListEvents(::grpc::ServerContext* context, ::dmi::HardwareID* request, ::grpc::ServerAsyncResponseWriter< ::dmi::ListEventsResponse>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+      ::grpc::Service::RequestAsyncUnary(0, context, request, response, new_call_cq, notification_cq, tag);
+    }
+  };
+  template <class BaseClass>
+  class WithAsyncMethod_UpdateEventsConfiguration : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithAsyncMethod_UpdateEventsConfiguration() {
+      ::grpc::Service::MarkMethodAsync(1);
+    }
+    ~WithAsyncMethod_UpdateEventsConfiguration() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status UpdateEventsConfiguration(::grpc::ServerContext* /*context*/, const ::dmi::EventsConfigurationRequest* /*request*/, ::dmi::EventsConfigurationResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    void RequestUpdateEventsConfiguration(::grpc::ServerContext* context, ::dmi::EventsConfigurationRequest* request, ::grpc::ServerAsyncResponseWriter< ::dmi::EventsConfigurationResponse>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+      ::grpc::Service::RequestAsyncUnary(1, context, request, response, new_call_cq, notification_cq, tag);
+    }
+  };
+  typedef WithAsyncMethod_ListEvents<WithAsyncMethod_UpdateEventsConfiguration<Service > > AsyncService;
+  template <class BaseClass>
+  class ExperimentalWithCallbackMethod_ListEvents : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    ExperimentalWithCallbackMethod_ListEvents() {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::Service::
+    #else
+      ::grpc::Service::experimental().
+    #endif
+        MarkMethodCallback(0,
+          new ::grpc_impl::internal::CallbackUnaryHandler< ::dmi::HardwareID, ::dmi::ListEventsResponse>(
+            [this](
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+                   ::grpc::CallbackServerContext*
+    #else
+                   ::grpc::experimental::CallbackServerContext*
+    #endif
+                     context, const ::dmi::HardwareID* request, ::dmi::ListEventsResponse* response) { return this->ListEvents(context, request, response); }));}
+    void SetMessageAllocatorFor_ListEvents(
+        ::grpc::experimental::MessageAllocator< ::dmi::HardwareID, ::dmi::ListEventsResponse>* allocator) {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(0);
+    #else
+      ::grpc::internal::MethodHandler* const handler = ::grpc::Service::experimental().GetHandler(0);
+    #endif
+      static_cast<::grpc_impl::internal::CallbackUnaryHandler< ::dmi::HardwareID, ::dmi::ListEventsResponse>*>(handler)
+              ->SetMessageAllocator(allocator);
+    }
+    ~ExperimentalWithCallbackMethod_ListEvents() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status ListEvents(::grpc::ServerContext* /*context*/, const ::dmi::HardwareID* /*request*/, ::dmi::ListEventsResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+    virtual ::grpc::ServerUnaryReactor* ListEvents(
+      ::grpc::CallbackServerContext* /*context*/, const ::dmi::HardwareID* /*request*/, ::dmi::ListEventsResponse* /*response*/)
+    #else
+    virtual ::grpc::experimental::ServerUnaryReactor* ListEvents(
+      ::grpc::experimental::CallbackServerContext* /*context*/, const ::dmi::HardwareID* /*request*/, ::dmi::ListEventsResponse* /*response*/)
+    #endif
+      { return nullptr; }
+  };
+  template <class BaseClass>
+  class ExperimentalWithCallbackMethod_UpdateEventsConfiguration : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    ExperimentalWithCallbackMethod_UpdateEventsConfiguration() {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::Service::
+    #else
+      ::grpc::Service::experimental().
+    #endif
+        MarkMethodCallback(1,
+          new ::grpc_impl::internal::CallbackUnaryHandler< ::dmi::EventsConfigurationRequest, ::dmi::EventsConfigurationResponse>(
+            [this](
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+                   ::grpc::CallbackServerContext*
+    #else
+                   ::grpc::experimental::CallbackServerContext*
+    #endif
+                     context, const ::dmi::EventsConfigurationRequest* request, ::dmi::EventsConfigurationResponse* response) { return this->UpdateEventsConfiguration(context, request, response); }));}
+    void SetMessageAllocatorFor_UpdateEventsConfiguration(
+        ::grpc::experimental::MessageAllocator< ::dmi::EventsConfigurationRequest, ::dmi::EventsConfigurationResponse>* allocator) {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(1);
+    #else
+      ::grpc::internal::MethodHandler* const handler = ::grpc::Service::experimental().GetHandler(1);
+    #endif
+      static_cast<::grpc_impl::internal::CallbackUnaryHandler< ::dmi::EventsConfigurationRequest, ::dmi::EventsConfigurationResponse>*>(handler)
+              ->SetMessageAllocator(allocator);
+    }
+    ~ExperimentalWithCallbackMethod_UpdateEventsConfiguration() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status UpdateEventsConfiguration(::grpc::ServerContext* /*context*/, const ::dmi::EventsConfigurationRequest* /*request*/, ::dmi::EventsConfigurationResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+    virtual ::grpc::ServerUnaryReactor* UpdateEventsConfiguration(
+      ::grpc::CallbackServerContext* /*context*/, const ::dmi::EventsConfigurationRequest* /*request*/, ::dmi::EventsConfigurationResponse* /*response*/)
+    #else
+    virtual ::grpc::experimental::ServerUnaryReactor* UpdateEventsConfiguration(
+      ::grpc::experimental::CallbackServerContext* /*context*/, const ::dmi::EventsConfigurationRequest* /*request*/, ::dmi::EventsConfigurationResponse* /*response*/)
+    #endif
+      { return nullptr; }
+  };
+  #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+  typedef ExperimentalWithCallbackMethod_ListEvents<ExperimentalWithCallbackMethod_UpdateEventsConfiguration<Service > > CallbackService;
+  #endif
+
+  typedef ExperimentalWithCallbackMethod_ListEvents<ExperimentalWithCallbackMethod_UpdateEventsConfiguration<Service > > ExperimentalCallbackService;
+  template <class BaseClass>
+  class WithGenericMethod_ListEvents : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithGenericMethod_ListEvents() {
+      ::grpc::Service::MarkMethodGeneric(0);
+    }
+    ~WithGenericMethod_ListEvents() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status ListEvents(::grpc::ServerContext* /*context*/, const ::dmi::HardwareID* /*request*/, ::dmi::ListEventsResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+  };
+  template <class BaseClass>
+  class WithGenericMethod_UpdateEventsConfiguration : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithGenericMethod_UpdateEventsConfiguration() {
+      ::grpc::Service::MarkMethodGeneric(1);
+    }
+    ~WithGenericMethod_UpdateEventsConfiguration() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status UpdateEventsConfiguration(::grpc::ServerContext* /*context*/, const ::dmi::EventsConfigurationRequest* /*request*/, ::dmi::EventsConfigurationResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+  };
+  template <class BaseClass>
+  class WithRawMethod_ListEvents : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithRawMethod_ListEvents() {
+      ::grpc::Service::MarkMethodRaw(0);
+    }
+    ~WithRawMethod_ListEvents() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status ListEvents(::grpc::ServerContext* /*context*/, const ::dmi::HardwareID* /*request*/, ::dmi::ListEventsResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    void RequestListEvents(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+      ::grpc::Service::RequestAsyncUnary(0, context, request, response, new_call_cq, notification_cq, tag);
+    }
+  };
+  template <class BaseClass>
+  class WithRawMethod_UpdateEventsConfiguration : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithRawMethod_UpdateEventsConfiguration() {
+      ::grpc::Service::MarkMethodRaw(1);
+    }
+    ~WithRawMethod_UpdateEventsConfiguration() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status UpdateEventsConfiguration(::grpc::ServerContext* /*context*/, const ::dmi::EventsConfigurationRequest* /*request*/, ::dmi::EventsConfigurationResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    void RequestUpdateEventsConfiguration(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+      ::grpc::Service::RequestAsyncUnary(1, context, request, response, new_call_cq, notification_cq, tag);
+    }
+  };
+  template <class BaseClass>
+  class ExperimentalWithRawCallbackMethod_ListEvents : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    ExperimentalWithRawCallbackMethod_ListEvents() {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::Service::
+    #else
+      ::grpc::Service::experimental().
+    #endif
+        MarkMethodRawCallback(0,
+          new ::grpc_impl::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>(
+            [this](
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+                   ::grpc::CallbackServerContext*
+    #else
+                   ::grpc::experimental::CallbackServerContext*
+    #endif
+                     context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response) { return this->ListEvents(context, request, response); }));
+    }
+    ~ExperimentalWithRawCallbackMethod_ListEvents() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status ListEvents(::grpc::ServerContext* /*context*/, const ::dmi::HardwareID* /*request*/, ::dmi::ListEventsResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+    virtual ::grpc::ServerUnaryReactor* ListEvents(
+      ::grpc::CallbackServerContext* /*context*/, const ::grpc::ByteBuffer* /*request*/, ::grpc::ByteBuffer* /*response*/)
+    #else
+    virtual ::grpc::experimental::ServerUnaryReactor* ListEvents(
+      ::grpc::experimental::CallbackServerContext* /*context*/, const ::grpc::ByteBuffer* /*request*/, ::grpc::ByteBuffer* /*response*/)
+    #endif
+      { return nullptr; }
+  };
+  template <class BaseClass>
+  class ExperimentalWithRawCallbackMethod_UpdateEventsConfiguration : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    ExperimentalWithRawCallbackMethod_UpdateEventsConfiguration() {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::Service::
+    #else
+      ::grpc::Service::experimental().
+    #endif
+        MarkMethodRawCallback(1,
+          new ::grpc_impl::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>(
+            [this](
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+                   ::grpc::CallbackServerContext*
+    #else
+                   ::grpc::experimental::CallbackServerContext*
+    #endif
+                     context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response) { return this->UpdateEventsConfiguration(context, request, response); }));
+    }
+    ~ExperimentalWithRawCallbackMethod_UpdateEventsConfiguration() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status UpdateEventsConfiguration(::grpc::ServerContext* /*context*/, const ::dmi::EventsConfigurationRequest* /*request*/, ::dmi::EventsConfigurationResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+    virtual ::grpc::ServerUnaryReactor* UpdateEventsConfiguration(
+      ::grpc::CallbackServerContext* /*context*/, const ::grpc::ByteBuffer* /*request*/, ::grpc::ByteBuffer* /*response*/)
+    #else
+    virtual ::grpc::experimental::ServerUnaryReactor* UpdateEventsConfiguration(
+      ::grpc::experimental::CallbackServerContext* /*context*/, const ::grpc::ByteBuffer* /*request*/, ::grpc::ByteBuffer* /*response*/)
+    #endif
+      { return nullptr; }
+  };
+  template <class BaseClass>
+  class WithStreamedUnaryMethod_ListEvents : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithStreamedUnaryMethod_ListEvents() {
+      ::grpc::Service::MarkMethodStreamed(0,
+        new ::grpc::internal::StreamedUnaryHandler<
+          ::dmi::HardwareID, ::dmi::ListEventsResponse>(
+            [this](::grpc_impl::ServerContext* context,
+                   ::grpc_impl::ServerUnaryStreamer<
+                     ::dmi::HardwareID, ::dmi::ListEventsResponse>* streamer) {
+                       return this->StreamedListEvents(context,
+                         streamer);
+                  }));
+    }
+    ~WithStreamedUnaryMethod_ListEvents() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable regular version of this method
+    ::grpc::Status ListEvents(::grpc::ServerContext* /*context*/, const ::dmi::HardwareID* /*request*/, ::dmi::ListEventsResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    // replace default version of method with streamed unary
+    virtual ::grpc::Status StreamedListEvents(::grpc::ServerContext* context, ::grpc::ServerUnaryStreamer< ::dmi::HardwareID,::dmi::ListEventsResponse>* server_unary_streamer) = 0;
+  };
+  template <class BaseClass>
+  class WithStreamedUnaryMethod_UpdateEventsConfiguration : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithStreamedUnaryMethod_UpdateEventsConfiguration() {
+      ::grpc::Service::MarkMethodStreamed(1,
+        new ::grpc::internal::StreamedUnaryHandler<
+          ::dmi::EventsConfigurationRequest, ::dmi::EventsConfigurationResponse>(
+            [this](::grpc_impl::ServerContext* context,
+                   ::grpc_impl::ServerUnaryStreamer<
+                     ::dmi::EventsConfigurationRequest, ::dmi::EventsConfigurationResponse>* streamer) {
+                       return this->StreamedUpdateEventsConfiguration(context,
+                         streamer);
+                  }));
+    }
+    ~WithStreamedUnaryMethod_UpdateEventsConfiguration() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable regular version of this method
+    ::grpc::Status UpdateEventsConfiguration(::grpc::ServerContext* /*context*/, const ::dmi::EventsConfigurationRequest* /*request*/, ::dmi::EventsConfigurationResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    // replace default version of method with streamed unary
+    virtual ::grpc::Status StreamedUpdateEventsConfiguration(::grpc::ServerContext* context, ::grpc::ServerUnaryStreamer< ::dmi::EventsConfigurationRequest,::dmi::EventsConfigurationResponse>* server_unary_streamer) = 0;
+  };
+  typedef WithStreamedUnaryMethod_ListEvents<WithStreamedUnaryMethod_UpdateEventsConfiguration<Service > > StreamedUnaryService;
+  typedef Service SplitStreamedService;
+  typedef WithStreamedUnaryMethod_ListEvents<WithStreamedUnaryMethod_UpdateEventsConfiguration<Service > > StreamedService;
+};
+
+}  // namespace dmi
+
+
+#endif  // GRPC_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto__INCLUDED
diff --git a/cpp/dmi/hw_management_service.grpc.pb.cc b/cpp/dmi/hw_management_service.grpc.pb.cc
new file mode 100644
index 0000000..94ca677
--- /dev/null
+++ b/cpp/dmi/hw_management_service.grpc.pb.cc
@@ -0,0 +1,619 @@
+// Generated by the gRPC C++ plugin.
+// If you make any local change, they will be lost.
+// source: dmi/hw_management_service.proto
+
+#include "dmi/hw_management_service.pb.h"
+#include "dmi/hw_management_service.grpc.pb.h"
+
+#include <functional>
+#include <grpcpp/impl/codegen/async_stream.h>
+#include <grpcpp/impl/codegen/async_unary_call.h>
+#include <grpcpp/impl/codegen/channel_interface.h>
+#include <grpcpp/impl/codegen/client_unary_call.h>
+#include <grpcpp/impl/codegen/client_callback.h>
+#include <grpcpp/impl/codegen/message_allocator.h>
+#include <grpcpp/impl/codegen/method_handler.h>
+#include <grpcpp/impl/codegen/rpc_service_method.h>
+#include <grpcpp/impl/codegen/server_callback.h>
+#include <grpcpp/impl/codegen/server_callback_handlers.h>
+#include <grpcpp/impl/codegen/server_context.h>
+#include <grpcpp/impl/codegen/service_type.h>
+#include <grpcpp/impl/codegen/sync_stream.h>
+namespace dmi {
+
+static const char* NativeHWManagementService_method_names[] = {
+  "/dmi.NativeHWManagementService/StartManagingDevice",
+  "/dmi.NativeHWManagementService/StopManagingDevice",
+  "/dmi.NativeHWManagementService/GetManagedDevices",
+  "/dmi.NativeHWManagementService/GetPhysicalInventory",
+  "/dmi.NativeHWManagementService/GetHWComponentInfo",
+  "/dmi.NativeHWManagementService/SetHWComponentInfo",
+  "/dmi.NativeHWManagementService/SetLoggingEndpoint",
+  "/dmi.NativeHWManagementService/GetLoggingEndpoint",
+  "/dmi.NativeHWManagementService/SetMsgBusEndpoint",
+  "/dmi.NativeHWManagementService/GetMsgBusEndpoint",
+  "/dmi.NativeHWManagementService/GetLoggableEntities",
+  "/dmi.NativeHWManagementService/SetLogLevel",
+  "/dmi.NativeHWManagementService/GetLogLevel",
+};
+
+std::unique_ptr< NativeHWManagementService::Stub> NativeHWManagementService::NewStub(const std::shared_ptr< ::grpc::ChannelInterface>& channel, const ::grpc::StubOptions& options) {
+  (void)options;
+  std::unique_ptr< NativeHWManagementService::Stub> stub(new NativeHWManagementService::Stub(channel));
+  return stub;
+}
+
+NativeHWManagementService::Stub::Stub(const std::shared_ptr< ::grpc::ChannelInterface>& channel)
+  : channel_(channel), rpcmethod_StartManagingDevice_(NativeHWManagementService_method_names[0], ::grpc::internal::RpcMethod::SERVER_STREAMING, channel)
+  , rpcmethod_StopManagingDevice_(NativeHWManagementService_method_names[1], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
+  , rpcmethod_GetManagedDevices_(NativeHWManagementService_method_names[2], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
+  , rpcmethod_GetPhysicalInventory_(NativeHWManagementService_method_names[3], ::grpc::internal::RpcMethod::SERVER_STREAMING, channel)
+  , rpcmethod_GetHWComponentInfo_(NativeHWManagementService_method_names[4], ::grpc::internal::RpcMethod::SERVER_STREAMING, channel)
+  , rpcmethod_SetHWComponentInfo_(NativeHWManagementService_method_names[5], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
+  , rpcmethod_SetLoggingEndpoint_(NativeHWManagementService_method_names[6], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
+  , rpcmethod_GetLoggingEndpoint_(NativeHWManagementService_method_names[7], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
+  , rpcmethod_SetMsgBusEndpoint_(NativeHWManagementService_method_names[8], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
+  , rpcmethod_GetMsgBusEndpoint_(NativeHWManagementService_method_names[9], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
+  , rpcmethod_GetLoggableEntities_(NativeHWManagementService_method_names[10], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
+  , rpcmethod_SetLogLevel_(NativeHWManagementService_method_names[11], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
+  , rpcmethod_GetLogLevel_(NativeHWManagementService_method_names[12], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
+  {}
+
+::grpc::ClientReader< ::dmi::StartManagingDeviceResponse>* NativeHWManagementService::Stub::StartManagingDeviceRaw(::grpc::ClientContext* context, const ::dmi::ModifiableComponent& request) {
+  return ::grpc_impl::internal::ClientReaderFactory< ::dmi::StartManagingDeviceResponse>::Create(channel_.get(), rpcmethod_StartManagingDevice_, context, request);
+}
+
+void NativeHWManagementService::Stub::experimental_async::StartManagingDevice(::grpc::ClientContext* context, ::dmi::ModifiableComponent* request, ::grpc::experimental::ClientReadReactor< ::dmi::StartManagingDeviceResponse>* reactor) {
+  ::grpc_impl::internal::ClientCallbackReaderFactory< ::dmi::StartManagingDeviceResponse>::Create(stub_->channel_.get(), stub_->rpcmethod_StartManagingDevice_, context, request, reactor);
+}
+
+::grpc::ClientAsyncReader< ::dmi::StartManagingDeviceResponse>* NativeHWManagementService::Stub::AsyncStartManagingDeviceRaw(::grpc::ClientContext* context, const ::dmi::ModifiableComponent& request, ::grpc::CompletionQueue* cq, void* tag) {
+  return ::grpc_impl::internal::ClientAsyncReaderFactory< ::dmi::StartManagingDeviceResponse>::Create(channel_.get(), cq, rpcmethod_StartManagingDevice_, context, request, true, tag);
+}
+
+::grpc::ClientAsyncReader< ::dmi::StartManagingDeviceResponse>* NativeHWManagementService::Stub::PrepareAsyncStartManagingDeviceRaw(::grpc::ClientContext* context, const ::dmi::ModifiableComponent& request, ::grpc::CompletionQueue* cq) {
+  return ::grpc_impl::internal::ClientAsyncReaderFactory< ::dmi::StartManagingDeviceResponse>::Create(channel_.get(), cq, rpcmethod_StartManagingDevice_, context, request, false, nullptr);
+}
+
+::grpc::Status NativeHWManagementService::Stub::StopManagingDevice(::grpc::ClientContext* context, const ::dmi::StopManagingDeviceRequest& request, ::dmi::StopManagingDeviceResponse* response) {
+  return ::grpc::internal::BlockingUnaryCall(channel_.get(), rpcmethod_StopManagingDevice_, context, request, response);
+}
+
+void NativeHWManagementService::Stub::experimental_async::StopManagingDevice(::grpc::ClientContext* context, const ::dmi::StopManagingDeviceRequest* request, ::dmi::StopManagingDeviceResponse* response, std::function<void(::grpc::Status)> f) {
+  ::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_StopManagingDevice_, context, request, response, std::move(f));
+}
+
+void NativeHWManagementService::Stub::experimental_async::StopManagingDevice(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::StopManagingDeviceResponse* response, std::function<void(::grpc::Status)> f) {
+  ::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_StopManagingDevice_, context, request, response, std::move(f));
+}
+
+void NativeHWManagementService::Stub::experimental_async::StopManagingDevice(::grpc::ClientContext* context, const ::dmi::StopManagingDeviceRequest* request, ::dmi::StopManagingDeviceResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
+  ::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_StopManagingDevice_, context, request, response, reactor);
+}
+
+void NativeHWManagementService::Stub::experimental_async::StopManagingDevice(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::StopManagingDeviceResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
+  ::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_StopManagingDevice_, context, request, response, reactor);
+}
+
+::grpc::ClientAsyncResponseReader< ::dmi::StopManagingDeviceResponse>* NativeHWManagementService::Stub::AsyncStopManagingDeviceRaw(::grpc::ClientContext* context, const ::dmi::StopManagingDeviceRequest& request, ::grpc::CompletionQueue* cq) {
+  return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::dmi::StopManagingDeviceResponse>::Create(channel_.get(), cq, rpcmethod_StopManagingDevice_, context, request, true);
+}
+
+::grpc::ClientAsyncResponseReader< ::dmi::StopManagingDeviceResponse>* NativeHWManagementService::Stub::PrepareAsyncStopManagingDeviceRaw(::grpc::ClientContext* context, const ::dmi::StopManagingDeviceRequest& request, ::grpc::CompletionQueue* cq) {
+  return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::dmi::StopManagingDeviceResponse>::Create(channel_.get(), cq, rpcmethod_StopManagingDevice_, context, request, false);
+}
+
+::grpc::Status NativeHWManagementService::Stub::GetManagedDevices(::grpc::ClientContext* context, const ::google::protobuf::Empty& request, ::dmi::ManagedDevicesResponse* response) {
+  return ::grpc::internal::BlockingUnaryCall(channel_.get(), rpcmethod_GetManagedDevices_, context, request, response);
+}
+
+void NativeHWManagementService::Stub::experimental_async::GetManagedDevices(::grpc::ClientContext* context, const ::google::protobuf::Empty* request, ::dmi::ManagedDevicesResponse* response, std::function<void(::grpc::Status)> f) {
+  ::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_GetManagedDevices_, context, request, response, std::move(f));
+}
+
+void NativeHWManagementService::Stub::experimental_async::GetManagedDevices(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::ManagedDevicesResponse* response, std::function<void(::grpc::Status)> f) {
+  ::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_GetManagedDevices_, context, request, response, std::move(f));
+}
+
+void NativeHWManagementService::Stub::experimental_async::GetManagedDevices(::grpc::ClientContext* context, const ::google::protobuf::Empty* request, ::dmi::ManagedDevicesResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
+  ::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_GetManagedDevices_, context, request, response, reactor);
+}
+
+void NativeHWManagementService::Stub::experimental_async::GetManagedDevices(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::ManagedDevicesResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
+  ::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_GetManagedDevices_, context, request, response, reactor);
+}
+
+::grpc::ClientAsyncResponseReader< ::dmi::ManagedDevicesResponse>* NativeHWManagementService::Stub::AsyncGetManagedDevicesRaw(::grpc::ClientContext* context, const ::google::protobuf::Empty& request, ::grpc::CompletionQueue* cq) {
+  return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::dmi::ManagedDevicesResponse>::Create(channel_.get(), cq, rpcmethod_GetManagedDevices_, context, request, true);
+}
+
+::grpc::ClientAsyncResponseReader< ::dmi::ManagedDevicesResponse>* NativeHWManagementService::Stub::PrepareAsyncGetManagedDevicesRaw(::grpc::ClientContext* context, const ::google::protobuf::Empty& request, ::grpc::CompletionQueue* cq) {
+  return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::dmi::ManagedDevicesResponse>::Create(channel_.get(), cq, rpcmethod_GetManagedDevices_, context, request, false);
+}
+
+::grpc::ClientReader< ::dmi::PhysicalInventoryResponse>* NativeHWManagementService::Stub::GetPhysicalInventoryRaw(::grpc::ClientContext* context, const ::dmi::PhysicalInventoryRequest& request) {
+  return ::grpc_impl::internal::ClientReaderFactory< ::dmi::PhysicalInventoryResponse>::Create(channel_.get(), rpcmethod_GetPhysicalInventory_, context, request);
+}
+
+void NativeHWManagementService::Stub::experimental_async::GetPhysicalInventory(::grpc::ClientContext* context, ::dmi::PhysicalInventoryRequest* request, ::grpc::experimental::ClientReadReactor< ::dmi::PhysicalInventoryResponse>* reactor) {
+  ::grpc_impl::internal::ClientCallbackReaderFactory< ::dmi::PhysicalInventoryResponse>::Create(stub_->channel_.get(), stub_->rpcmethod_GetPhysicalInventory_, context, request, reactor);
+}
+
+::grpc::ClientAsyncReader< ::dmi::PhysicalInventoryResponse>* NativeHWManagementService::Stub::AsyncGetPhysicalInventoryRaw(::grpc::ClientContext* context, const ::dmi::PhysicalInventoryRequest& request, ::grpc::CompletionQueue* cq, void* tag) {
+  return ::grpc_impl::internal::ClientAsyncReaderFactory< ::dmi::PhysicalInventoryResponse>::Create(channel_.get(), cq, rpcmethod_GetPhysicalInventory_, context, request, true, tag);
+}
+
+::grpc::ClientAsyncReader< ::dmi::PhysicalInventoryResponse>* NativeHWManagementService::Stub::PrepareAsyncGetPhysicalInventoryRaw(::grpc::ClientContext* context, const ::dmi::PhysicalInventoryRequest& request, ::grpc::CompletionQueue* cq) {
+  return ::grpc_impl::internal::ClientAsyncReaderFactory< ::dmi::PhysicalInventoryResponse>::Create(channel_.get(), cq, rpcmethod_GetPhysicalInventory_, context, request, false, nullptr);
+}
+
+::grpc::ClientReader< ::dmi::HWComponentInfoGetResponse>* NativeHWManagementService::Stub::GetHWComponentInfoRaw(::grpc::ClientContext* context, const ::dmi::HWComponentInfoGetRequest& request) {
+  return ::grpc_impl::internal::ClientReaderFactory< ::dmi::HWComponentInfoGetResponse>::Create(channel_.get(), rpcmethod_GetHWComponentInfo_, context, request);
+}
+
+void NativeHWManagementService::Stub::experimental_async::GetHWComponentInfo(::grpc::ClientContext* context, ::dmi::HWComponentInfoGetRequest* request, ::grpc::experimental::ClientReadReactor< ::dmi::HWComponentInfoGetResponse>* reactor) {
+  ::grpc_impl::internal::ClientCallbackReaderFactory< ::dmi::HWComponentInfoGetResponse>::Create(stub_->channel_.get(), stub_->rpcmethod_GetHWComponentInfo_, context, request, reactor);
+}
+
+::grpc::ClientAsyncReader< ::dmi::HWComponentInfoGetResponse>* NativeHWManagementService::Stub::AsyncGetHWComponentInfoRaw(::grpc::ClientContext* context, const ::dmi::HWComponentInfoGetRequest& request, ::grpc::CompletionQueue* cq, void* tag) {
+  return ::grpc_impl::internal::ClientAsyncReaderFactory< ::dmi::HWComponentInfoGetResponse>::Create(channel_.get(), cq, rpcmethod_GetHWComponentInfo_, context, request, true, tag);
+}
+
+::grpc::ClientAsyncReader< ::dmi::HWComponentInfoGetResponse>* NativeHWManagementService::Stub::PrepareAsyncGetHWComponentInfoRaw(::grpc::ClientContext* context, const ::dmi::HWComponentInfoGetRequest& request, ::grpc::CompletionQueue* cq) {
+  return ::grpc_impl::internal::ClientAsyncReaderFactory< ::dmi::HWComponentInfoGetResponse>::Create(channel_.get(), cq, rpcmethod_GetHWComponentInfo_, context, request, false, nullptr);
+}
+
+::grpc::Status NativeHWManagementService::Stub::SetHWComponentInfo(::grpc::ClientContext* context, const ::dmi::HWComponentInfoSetRequest& request, ::dmi::HWComponentInfoSetResponse* response) {
+  return ::grpc::internal::BlockingUnaryCall(channel_.get(), rpcmethod_SetHWComponentInfo_, context, request, response);
+}
+
+void NativeHWManagementService::Stub::experimental_async::SetHWComponentInfo(::grpc::ClientContext* context, const ::dmi::HWComponentInfoSetRequest* request, ::dmi::HWComponentInfoSetResponse* response, std::function<void(::grpc::Status)> f) {
+  ::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_SetHWComponentInfo_, context, request, response, std::move(f));
+}
+
+void NativeHWManagementService::Stub::experimental_async::SetHWComponentInfo(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::HWComponentInfoSetResponse* response, std::function<void(::grpc::Status)> f) {
+  ::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_SetHWComponentInfo_, context, request, response, std::move(f));
+}
+
+void NativeHWManagementService::Stub::experimental_async::SetHWComponentInfo(::grpc::ClientContext* context, const ::dmi::HWComponentInfoSetRequest* request, ::dmi::HWComponentInfoSetResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
+  ::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_SetHWComponentInfo_, context, request, response, reactor);
+}
+
+void NativeHWManagementService::Stub::experimental_async::SetHWComponentInfo(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::HWComponentInfoSetResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
+  ::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_SetHWComponentInfo_, context, request, response, reactor);
+}
+
+::grpc::ClientAsyncResponseReader< ::dmi::HWComponentInfoSetResponse>* NativeHWManagementService::Stub::AsyncSetHWComponentInfoRaw(::grpc::ClientContext* context, const ::dmi::HWComponentInfoSetRequest& request, ::grpc::CompletionQueue* cq) {
+  return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::dmi::HWComponentInfoSetResponse>::Create(channel_.get(), cq, rpcmethod_SetHWComponentInfo_, context, request, true);
+}
+
+::grpc::ClientAsyncResponseReader< ::dmi::HWComponentInfoSetResponse>* NativeHWManagementService::Stub::PrepareAsyncSetHWComponentInfoRaw(::grpc::ClientContext* context, const ::dmi::HWComponentInfoSetRequest& request, ::grpc::CompletionQueue* cq) {
+  return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::dmi::HWComponentInfoSetResponse>::Create(channel_.get(), cq, rpcmethod_SetHWComponentInfo_, context, request, false);
+}
+
+::grpc::Status NativeHWManagementService::Stub::SetLoggingEndpoint(::grpc::ClientContext* context, const ::dmi::SetLoggingEndpointRequest& request, ::dmi::SetRemoteEndpointResponse* response) {
+  return ::grpc::internal::BlockingUnaryCall(channel_.get(), rpcmethod_SetLoggingEndpoint_, context, request, response);
+}
+
+void NativeHWManagementService::Stub::experimental_async::SetLoggingEndpoint(::grpc::ClientContext* context, const ::dmi::SetLoggingEndpointRequest* request, ::dmi::SetRemoteEndpointResponse* response, std::function<void(::grpc::Status)> f) {
+  ::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_SetLoggingEndpoint_, context, request, response, std::move(f));
+}
+
+void NativeHWManagementService::Stub::experimental_async::SetLoggingEndpoint(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::SetRemoteEndpointResponse* response, std::function<void(::grpc::Status)> f) {
+  ::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_SetLoggingEndpoint_, context, request, response, std::move(f));
+}
+
+void NativeHWManagementService::Stub::experimental_async::SetLoggingEndpoint(::grpc::ClientContext* context, const ::dmi::SetLoggingEndpointRequest* request, ::dmi::SetRemoteEndpointResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
+  ::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_SetLoggingEndpoint_, context, request, response, reactor);
+}
+
+void NativeHWManagementService::Stub::experimental_async::SetLoggingEndpoint(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::SetRemoteEndpointResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
+  ::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_SetLoggingEndpoint_, context, request, response, reactor);
+}
+
+::grpc::ClientAsyncResponseReader< ::dmi::SetRemoteEndpointResponse>* NativeHWManagementService::Stub::AsyncSetLoggingEndpointRaw(::grpc::ClientContext* context, const ::dmi::SetLoggingEndpointRequest& request, ::grpc::CompletionQueue* cq) {
+  return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::dmi::SetRemoteEndpointResponse>::Create(channel_.get(), cq, rpcmethod_SetLoggingEndpoint_, context, request, true);
+}
+
+::grpc::ClientAsyncResponseReader< ::dmi::SetRemoteEndpointResponse>* NativeHWManagementService::Stub::PrepareAsyncSetLoggingEndpointRaw(::grpc::ClientContext* context, const ::dmi::SetLoggingEndpointRequest& request, ::grpc::CompletionQueue* cq) {
+  return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::dmi::SetRemoteEndpointResponse>::Create(channel_.get(), cq, rpcmethod_SetLoggingEndpoint_, context, request, false);
+}
+
+::grpc::Status NativeHWManagementService::Stub::GetLoggingEndpoint(::grpc::ClientContext* context, const ::dmi::HardwareID& request, ::dmi::GetLoggingEndpointResponse* response) {
+  return ::grpc::internal::BlockingUnaryCall(channel_.get(), rpcmethod_GetLoggingEndpoint_, context, request, response);
+}
+
+void NativeHWManagementService::Stub::experimental_async::GetLoggingEndpoint(::grpc::ClientContext* context, const ::dmi::HardwareID* request, ::dmi::GetLoggingEndpointResponse* response, std::function<void(::grpc::Status)> f) {
+  ::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_GetLoggingEndpoint_, context, request, response, std::move(f));
+}
+
+void NativeHWManagementService::Stub::experimental_async::GetLoggingEndpoint(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::GetLoggingEndpointResponse* response, std::function<void(::grpc::Status)> f) {
+  ::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_GetLoggingEndpoint_, context, request, response, std::move(f));
+}
+
+void NativeHWManagementService::Stub::experimental_async::GetLoggingEndpoint(::grpc::ClientContext* context, const ::dmi::HardwareID* request, ::dmi::GetLoggingEndpointResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
+  ::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_GetLoggingEndpoint_, context, request, response, reactor);
+}
+
+void NativeHWManagementService::Stub::experimental_async::GetLoggingEndpoint(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::GetLoggingEndpointResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
+  ::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_GetLoggingEndpoint_, context, request, response, reactor);
+}
+
+::grpc::ClientAsyncResponseReader< ::dmi::GetLoggingEndpointResponse>* NativeHWManagementService::Stub::AsyncGetLoggingEndpointRaw(::grpc::ClientContext* context, const ::dmi::HardwareID& request, ::grpc::CompletionQueue* cq) {
+  return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::dmi::GetLoggingEndpointResponse>::Create(channel_.get(), cq, rpcmethod_GetLoggingEndpoint_, context, request, true);
+}
+
+::grpc::ClientAsyncResponseReader< ::dmi::GetLoggingEndpointResponse>* NativeHWManagementService::Stub::PrepareAsyncGetLoggingEndpointRaw(::grpc::ClientContext* context, const ::dmi::HardwareID& request, ::grpc::CompletionQueue* cq) {
+  return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::dmi::GetLoggingEndpointResponse>::Create(channel_.get(), cq, rpcmethod_GetLoggingEndpoint_, context, request, false);
+}
+
+::grpc::Status NativeHWManagementService::Stub::SetMsgBusEndpoint(::grpc::ClientContext* context, const ::dmi::SetMsgBusEndpointRequest& request, ::dmi::SetRemoteEndpointResponse* response) {
+  return ::grpc::internal::BlockingUnaryCall(channel_.get(), rpcmethod_SetMsgBusEndpoint_, context, request, response);
+}
+
+void NativeHWManagementService::Stub::experimental_async::SetMsgBusEndpoint(::grpc::ClientContext* context, const ::dmi::SetMsgBusEndpointRequest* request, ::dmi::SetRemoteEndpointResponse* response, std::function<void(::grpc::Status)> f) {
+  ::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_SetMsgBusEndpoint_, context, request, response, std::move(f));
+}
+
+void NativeHWManagementService::Stub::experimental_async::SetMsgBusEndpoint(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::SetRemoteEndpointResponse* response, std::function<void(::grpc::Status)> f) {
+  ::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_SetMsgBusEndpoint_, context, request, response, std::move(f));
+}
+
+void NativeHWManagementService::Stub::experimental_async::SetMsgBusEndpoint(::grpc::ClientContext* context, const ::dmi::SetMsgBusEndpointRequest* request, ::dmi::SetRemoteEndpointResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
+  ::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_SetMsgBusEndpoint_, context, request, response, reactor);
+}
+
+void NativeHWManagementService::Stub::experimental_async::SetMsgBusEndpoint(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::SetRemoteEndpointResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
+  ::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_SetMsgBusEndpoint_, context, request, response, reactor);
+}
+
+::grpc::ClientAsyncResponseReader< ::dmi::SetRemoteEndpointResponse>* NativeHWManagementService::Stub::AsyncSetMsgBusEndpointRaw(::grpc::ClientContext* context, const ::dmi::SetMsgBusEndpointRequest& request, ::grpc::CompletionQueue* cq) {
+  return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::dmi::SetRemoteEndpointResponse>::Create(channel_.get(), cq, rpcmethod_SetMsgBusEndpoint_, context, request, true);
+}
+
+::grpc::ClientAsyncResponseReader< ::dmi::SetRemoteEndpointResponse>* NativeHWManagementService::Stub::PrepareAsyncSetMsgBusEndpointRaw(::grpc::ClientContext* context, const ::dmi::SetMsgBusEndpointRequest& request, ::grpc::CompletionQueue* cq) {
+  return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::dmi::SetRemoteEndpointResponse>::Create(channel_.get(), cq, rpcmethod_SetMsgBusEndpoint_, context, request, false);
+}
+
+::grpc::Status NativeHWManagementService::Stub::GetMsgBusEndpoint(::grpc::ClientContext* context, const ::google::protobuf::Empty& request, ::dmi::GetMsgBusEndpointResponse* response) {
+  return ::grpc::internal::BlockingUnaryCall(channel_.get(), rpcmethod_GetMsgBusEndpoint_, context, request, response);
+}
+
+void NativeHWManagementService::Stub::experimental_async::GetMsgBusEndpoint(::grpc::ClientContext* context, const ::google::protobuf::Empty* request, ::dmi::GetMsgBusEndpointResponse* response, std::function<void(::grpc::Status)> f) {
+  ::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_GetMsgBusEndpoint_, context, request, response, std::move(f));
+}
+
+void NativeHWManagementService::Stub::experimental_async::GetMsgBusEndpoint(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::GetMsgBusEndpointResponse* response, std::function<void(::grpc::Status)> f) {
+  ::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_GetMsgBusEndpoint_, context, request, response, std::move(f));
+}
+
+void NativeHWManagementService::Stub::experimental_async::GetMsgBusEndpoint(::grpc::ClientContext* context, const ::google::protobuf::Empty* request, ::dmi::GetMsgBusEndpointResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
+  ::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_GetMsgBusEndpoint_, context, request, response, reactor);
+}
+
+void NativeHWManagementService::Stub::experimental_async::GetMsgBusEndpoint(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::GetMsgBusEndpointResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
+  ::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_GetMsgBusEndpoint_, context, request, response, reactor);
+}
+
+::grpc::ClientAsyncResponseReader< ::dmi::GetMsgBusEndpointResponse>* NativeHWManagementService::Stub::AsyncGetMsgBusEndpointRaw(::grpc::ClientContext* context, const ::google::protobuf::Empty& request, ::grpc::CompletionQueue* cq) {
+  return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::dmi::GetMsgBusEndpointResponse>::Create(channel_.get(), cq, rpcmethod_GetMsgBusEndpoint_, context, request, true);
+}
+
+::grpc::ClientAsyncResponseReader< ::dmi::GetMsgBusEndpointResponse>* NativeHWManagementService::Stub::PrepareAsyncGetMsgBusEndpointRaw(::grpc::ClientContext* context, const ::google::protobuf::Empty& request, ::grpc::CompletionQueue* cq) {
+  return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::dmi::GetMsgBusEndpointResponse>::Create(channel_.get(), cq, rpcmethod_GetMsgBusEndpoint_, context, request, false);
+}
+
+::grpc::Status NativeHWManagementService::Stub::GetLoggableEntities(::grpc::ClientContext* context, const ::dmi::GetLoggableEntitiesRequest& request, ::dmi::GetLogLevelResponse* response) {
+  return ::grpc::internal::BlockingUnaryCall(channel_.get(), rpcmethod_GetLoggableEntities_, context, request, response);
+}
+
+void NativeHWManagementService::Stub::experimental_async::GetLoggableEntities(::grpc::ClientContext* context, const ::dmi::GetLoggableEntitiesRequest* request, ::dmi::GetLogLevelResponse* response, std::function<void(::grpc::Status)> f) {
+  ::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_GetLoggableEntities_, context, request, response, std::move(f));
+}
+
+void NativeHWManagementService::Stub::experimental_async::GetLoggableEntities(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::GetLogLevelResponse* response, std::function<void(::grpc::Status)> f) {
+  ::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_GetLoggableEntities_, context, request, response, std::move(f));
+}
+
+void NativeHWManagementService::Stub::experimental_async::GetLoggableEntities(::grpc::ClientContext* context, const ::dmi::GetLoggableEntitiesRequest* request, ::dmi::GetLogLevelResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
+  ::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_GetLoggableEntities_, context, request, response, reactor);
+}
+
+void NativeHWManagementService::Stub::experimental_async::GetLoggableEntities(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::GetLogLevelResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
+  ::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_GetLoggableEntities_, context, request, response, reactor);
+}
+
+::grpc::ClientAsyncResponseReader< ::dmi::GetLogLevelResponse>* NativeHWManagementService::Stub::AsyncGetLoggableEntitiesRaw(::grpc::ClientContext* context, const ::dmi::GetLoggableEntitiesRequest& request, ::grpc::CompletionQueue* cq) {
+  return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::dmi::GetLogLevelResponse>::Create(channel_.get(), cq, rpcmethod_GetLoggableEntities_, context, request, true);
+}
+
+::grpc::ClientAsyncResponseReader< ::dmi::GetLogLevelResponse>* NativeHWManagementService::Stub::PrepareAsyncGetLoggableEntitiesRaw(::grpc::ClientContext* context, const ::dmi::GetLoggableEntitiesRequest& request, ::grpc::CompletionQueue* cq) {
+  return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::dmi::GetLogLevelResponse>::Create(channel_.get(), cq, rpcmethod_GetLoggableEntities_, context, request, false);
+}
+
+::grpc::Status NativeHWManagementService::Stub::SetLogLevel(::grpc::ClientContext* context, const ::dmi::SetLogLevelRequest& request, ::dmi::SetLogLevelResponse* response) {
+  return ::grpc::internal::BlockingUnaryCall(channel_.get(), rpcmethod_SetLogLevel_, context, request, response);
+}
+
+void NativeHWManagementService::Stub::experimental_async::SetLogLevel(::grpc::ClientContext* context, const ::dmi::SetLogLevelRequest* request, ::dmi::SetLogLevelResponse* response, std::function<void(::grpc::Status)> f) {
+  ::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_SetLogLevel_, context, request, response, std::move(f));
+}
+
+void NativeHWManagementService::Stub::experimental_async::SetLogLevel(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::SetLogLevelResponse* response, std::function<void(::grpc::Status)> f) {
+  ::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_SetLogLevel_, context, request, response, std::move(f));
+}
+
+void NativeHWManagementService::Stub::experimental_async::SetLogLevel(::grpc::ClientContext* context, const ::dmi::SetLogLevelRequest* request, ::dmi::SetLogLevelResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
+  ::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_SetLogLevel_, context, request, response, reactor);
+}
+
+void NativeHWManagementService::Stub::experimental_async::SetLogLevel(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::SetLogLevelResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
+  ::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_SetLogLevel_, context, request, response, reactor);
+}
+
+::grpc::ClientAsyncResponseReader< ::dmi::SetLogLevelResponse>* NativeHWManagementService::Stub::AsyncSetLogLevelRaw(::grpc::ClientContext* context, const ::dmi::SetLogLevelRequest& request, ::grpc::CompletionQueue* cq) {
+  return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::dmi::SetLogLevelResponse>::Create(channel_.get(), cq, rpcmethod_SetLogLevel_, context, request, true);
+}
+
+::grpc::ClientAsyncResponseReader< ::dmi::SetLogLevelResponse>* NativeHWManagementService::Stub::PrepareAsyncSetLogLevelRaw(::grpc::ClientContext* context, const ::dmi::SetLogLevelRequest& request, ::grpc::CompletionQueue* cq) {
+  return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::dmi::SetLogLevelResponse>::Create(channel_.get(), cq, rpcmethod_SetLogLevel_, context, request, false);
+}
+
+::grpc::Status NativeHWManagementService::Stub::GetLogLevel(::grpc::ClientContext* context, const ::dmi::GetLogLevelRequest& request, ::dmi::GetLogLevelResponse* response) {
+  return ::grpc::internal::BlockingUnaryCall(channel_.get(), rpcmethod_GetLogLevel_, context, request, response);
+}
+
+void NativeHWManagementService::Stub::experimental_async::GetLogLevel(::grpc::ClientContext* context, const ::dmi::GetLogLevelRequest* request, ::dmi::GetLogLevelResponse* response, std::function<void(::grpc::Status)> f) {
+  ::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_GetLogLevel_, context, request, response, std::move(f));
+}
+
+void NativeHWManagementService::Stub::experimental_async::GetLogLevel(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::GetLogLevelResponse* response, std::function<void(::grpc::Status)> f) {
+  ::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_GetLogLevel_, context, request, response, std::move(f));
+}
+
+void NativeHWManagementService::Stub::experimental_async::GetLogLevel(::grpc::ClientContext* context, const ::dmi::GetLogLevelRequest* request, ::dmi::GetLogLevelResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
+  ::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_GetLogLevel_, context, request, response, reactor);
+}
+
+void NativeHWManagementService::Stub::experimental_async::GetLogLevel(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::GetLogLevelResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
+  ::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_GetLogLevel_, context, request, response, reactor);
+}
+
+::grpc::ClientAsyncResponseReader< ::dmi::GetLogLevelResponse>* NativeHWManagementService::Stub::AsyncGetLogLevelRaw(::grpc::ClientContext* context, const ::dmi::GetLogLevelRequest& request, ::grpc::CompletionQueue* cq) {
+  return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::dmi::GetLogLevelResponse>::Create(channel_.get(), cq, rpcmethod_GetLogLevel_, context, request, true);
+}
+
+::grpc::ClientAsyncResponseReader< ::dmi::GetLogLevelResponse>* NativeHWManagementService::Stub::PrepareAsyncGetLogLevelRaw(::grpc::ClientContext* context, const ::dmi::GetLogLevelRequest& request, ::grpc::CompletionQueue* cq) {
+  return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::dmi::GetLogLevelResponse>::Create(channel_.get(), cq, rpcmethod_GetLogLevel_, context, request, false);
+}
+
+NativeHWManagementService::Service::Service() {
+  AddMethod(new ::grpc::internal::RpcServiceMethod(
+      NativeHWManagementService_method_names[0],
+      ::grpc::internal::RpcMethod::SERVER_STREAMING,
+      new ::grpc::internal::ServerStreamingHandler< NativeHWManagementService::Service, ::dmi::ModifiableComponent, ::dmi::StartManagingDeviceResponse>(
+          [](NativeHWManagementService::Service* service,
+             ::grpc_impl::ServerContext* ctx,
+             const ::dmi::ModifiableComponent* req,
+             ::grpc_impl::ServerWriter<::dmi::StartManagingDeviceResponse>* writer) {
+               return service->StartManagingDevice(ctx, req, writer);
+             }, this)));
+  AddMethod(new ::grpc::internal::RpcServiceMethod(
+      NativeHWManagementService_method_names[1],
+      ::grpc::internal::RpcMethod::NORMAL_RPC,
+      new ::grpc::internal::RpcMethodHandler< NativeHWManagementService::Service, ::dmi::StopManagingDeviceRequest, ::dmi::StopManagingDeviceResponse>(
+          [](NativeHWManagementService::Service* service,
+             ::grpc_impl::ServerContext* ctx,
+             const ::dmi::StopManagingDeviceRequest* req,
+             ::dmi::StopManagingDeviceResponse* resp) {
+               return service->StopManagingDevice(ctx, req, resp);
+             }, this)));
+  AddMethod(new ::grpc::internal::RpcServiceMethod(
+      NativeHWManagementService_method_names[2],
+      ::grpc::internal::RpcMethod::NORMAL_RPC,
+      new ::grpc::internal::RpcMethodHandler< NativeHWManagementService::Service, ::google::protobuf::Empty, ::dmi::ManagedDevicesResponse>(
+          [](NativeHWManagementService::Service* service,
+             ::grpc_impl::ServerContext* ctx,
+             const ::google::protobuf::Empty* req,
+             ::dmi::ManagedDevicesResponse* resp) {
+               return service->GetManagedDevices(ctx, req, resp);
+             }, this)));
+  AddMethod(new ::grpc::internal::RpcServiceMethod(
+      NativeHWManagementService_method_names[3],
+      ::grpc::internal::RpcMethod::SERVER_STREAMING,
+      new ::grpc::internal::ServerStreamingHandler< NativeHWManagementService::Service, ::dmi::PhysicalInventoryRequest, ::dmi::PhysicalInventoryResponse>(
+          [](NativeHWManagementService::Service* service,
+             ::grpc_impl::ServerContext* ctx,
+             const ::dmi::PhysicalInventoryRequest* req,
+             ::grpc_impl::ServerWriter<::dmi::PhysicalInventoryResponse>* writer) {
+               return service->GetPhysicalInventory(ctx, req, writer);
+             }, this)));
+  AddMethod(new ::grpc::internal::RpcServiceMethod(
+      NativeHWManagementService_method_names[4],
+      ::grpc::internal::RpcMethod::SERVER_STREAMING,
+      new ::grpc::internal::ServerStreamingHandler< NativeHWManagementService::Service, ::dmi::HWComponentInfoGetRequest, ::dmi::HWComponentInfoGetResponse>(
+          [](NativeHWManagementService::Service* service,
+             ::grpc_impl::ServerContext* ctx,
+             const ::dmi::HWComponentInfoGetRequest* req,
+             ::grpc_impl::ServerWriter<::dmi::HWComponentInfoGetResponse>* writer) {
+               return service->GetHWComponentInfo(ctx, req, writer);
+             }, this)));
+  AddMethod(new ::grpc::internal::RpcServiceMethod(
+      NativeHWManagementService_method_names[5],
+      ::grpc::internal::RpcMethod::NORMAL_RPC,
+      new ::grpc::internal::RpcMethodHandler< NativeHWManagementService::Service, ::dmi::HWComponentInfoSetRequest, ::dmi::HWComponentInfoSetResponse>(
+          [](NativeHWManagementService::Service* service,
+             ::grpc_impl::ServerContext* ctx,
+             const ::dmi::HWComponentInfoSetRequest* req,
+             ::dmi::HWComponentInfoSetResponse* resp) {
+               return service->SetHWComponentInfo(ctx, req, resp);
+             }, this)));
+  AddMethod(new ::grpc::internal::RpcServiceMethod(
+      NativeHWManagementService_method_names[6],
+      ::grpc::internal::RpcMethod::NORMAL_RPC,
+      new ::grpc::internal::RpcMethodHandler< NativeHWManagementService::Service, ::dmi::SetLoggingEndpointRequest, ::dmi::SetRemoteEndpointResponse>(
+          [](NativeHWManagementService::Service* service,
+             ::grpc_impl::ServerContext* ctx,
+             const ::dmi::SetLoggingEndpointRequest* req,
+             ::dmi::SetRemoteEndpointResponse* resp) {
+               return service->SetLoggingEndpoint(ctx, req, resp);
+             }, this)));
+  AddMethod(new ::grpc::internal::RpcServiceMethod(
+      NativeHWManagementService_method_names[7],
+      ::grpc::internal::RpcMethod::NORMAL_RPC,
+      new ::grpc::internal::RpcMethodHandler< NativeHWManagementService::Service, ::dmi::HardwareID, ::dmi::GetLoggingEndpointResponse>(
+          [](NativeHWManagementService::Service* service,
+             ::grpc_impl::ServerContext* ctx,
+             const ::dmi::HardwareID* req,
+             ::dmi::GetLoggingEndpointResponse* resp) {
+               return service->GetLoggingEndpoint(ctx, req, resp);
+             }, this)));
+  AddMethod(new ::grpc::internal::RpcServiceMethod(
+      NativeHWManagementService_method_names[8],
+      ::grpc::internal::RpcMethod::NORMAL_RPC,
+      new ::grpc::internal::RpcMethodHandler< NativeHWManagementService::Service, ::dmi::SetMsgBusEndpointRequest, ::dmi::SetRemoteEndpointResponse>(
+          [](NativeHWManagementService::Service* service,
+             ::grpc_impl::ServerContext* ctx,
+             const ::dmi::SetMsgBusEndpointRequest* req,
+             ::dmi::SetRemoteEndpointResponse* resp) {
+               return service->SetMsgBusEndpoint(ctx, req, resp);
+             }, this)));
+  AddMethod(new ::grpc::internal::RpcServiceMethod(
+      NativeHWManagementService_method_names[9],
+      ::grpc::internal::RpcMethod::NORMAL_RPC,
+      new ::grpc::internal::RpcMethodHandler< NativeHWManagementService::Service, ::google::protobuf::Empty, ::dmi::GetMsgBusEndpointResponse>(
+          [](NativeHWManagementService::Service* service,
+             ::grpc_impl::ServerContext* ctx,
+             const ::google::protobuf::Empty* req,
+             ::dmi::GetMsgBusEndpointResponse* resp) {
+               return service->GetMsgBusEndpoint(ctx, req, resp);
+             }, this)));
+  AddMethod(new ::grpc::internal::RpcServiceMethod(
+      NativeHWManagementService_method_names[10],
+      ::grpc::internal::RpcMethod::NORMAL_RPC,
+      new ::grpc::internal::RpcMethodHandler< NativeHWManagementService::Service, ::dmi::GetLoggableEntitiesRequest, ::dmi::GetLogLevelResponse>(
+          [](NativeHWManagementService::Service* service,
+             ::grpc_impl::ServerContext* ctx,
+             const ::dmi::GetLoggableEntitiesRequest* req,
+             ::dmi::GetLogLevelResponse* resp) {
+               return service->GetLoggableEntities(ctx, req, resp);
+             }, this)));
+  AddMethod(new ::grpc::internal::RpcServiceMethod(
+      NativeHWManagementService_method_names[11],
+      ::grpc::internal::RpcMethod::NORMAL_RPC,
+      new ::grpc::internal::RpcMethodHandler< NativeHWManagementService::Service, ::dmi::SetLogLevelRequest, ::dmi::SetLogLevelResponse>(
+          [](NativeHWManagementService::Service* service,
+             ::grpc_impl::ServerContext* ctx,
+             const ::dmi::SetLogLevelRequest* req,
+             ::dmi::SetLogLevelResponse* resp) {
+               return service->SetLogLevel(ctx, req, resp);
+             }, this)));
+  AddMethod(new ::grpc::internal::RpcServiceMethod(
+      NativeHWManagementService_method_names[12],
+      ::grpc::internal::RpcMethod::NORMAL_RPC,
+      new ::grpc::internal::RpcMethodHandler< NativeHWManagementService::Service, ::dmi::GetLogLevelRequest, ::dmi::GetLogLevelResponse>(
+          [](NativeHWManagementService::Service* service,
+             ::grpc_impl::ServerContext* ctx,
+             const ::dmi::GetLogLevelRequest* req,
+             ::dmi::GetLogLevelResponse* resp) {
+               return service->GetLogLevel(ctx, req, resp);
+             }, this)));
+}
+
+NativeHWManagementService::Service::~Service() {
+}
+
+::grpc::Status NativeHWManagementService::Service::StartManagingDevice(::grpc::ServerContext* context, const ::dmi::ModifiableComponent* request, ::grpc::ServerWriter< ::dmi::StartManagingDeviceResponse>* writer) {
+  (void) context;
+  (void) request;
+  (void) writer;
+  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+}
+
+::grpc::Status NativeHWManagementService::Service::StopManagingDevice(::grpc::ServerContext* context, const ::dmi::StopManagingDeviceRequest* request, ::dmi::StopManagingDeviceResponse* response) {
+  (void) context;
+  (void) request;
+  (void) response;
+  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+}
+
+::grpc::Status NativeHWManagementService::Service::GetManagedDevices(::grpc::ServerContext* context, const ::google::protobuf::Empty* request, ::dmi::ManagedDevicesResponse* response) {
+  (void) context;
+  (void) request;
+  (void) response;
+  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+}
+
+::grpc::Status NativeHWManagementService::Service::GetPhysicalInventory(::grpc::ServerContext* context, const ::dmi::PhysicalInventoryRequest* request, ::grpc::ServerWriter< ::dmi::PhysicalInventoryResponse>* writer) {
+  (void) context;
+  (void) request;
+  (void) writer;
+  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+}
+
+::grpc::Status NativeHWManagementService::Service::GetHWComponentInfo(::grpc::ServerContext* context, const ::dmi::HWComponentInfoGetRequest* request, ::grpc::ServerWriter< ::dmi::HWComponentInfoGetResponse>* writer) {
+  (void) context;
+  (void) request;
+  (void) writer;
+  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+}
+
+::grpc::Status NativeHWManagementService::Service::SetHWComponentInfo(::grpc::ServerContext* context, const ::dmi::HWComponentInfoSetRequest* request, ::dmi::HWComponentInfoSetResponse* response) {
+  (void) context;
+  (void) request;
+  (void) response;
+  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+}
+
+::grpc::Status NativeHWManagementService::Service::SetLoggingEndpoint(::grpc::ServerContext* context, const ::dmi::SetLoggingEndpointRequest* request, ::dmi::SetRemoteEndpointResponse* response) {
+  (void) context;
+  (void) request;
+  (void) response;
+  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+}
+
+::grpc::Status NativeHWManagementService::Service::GetLoggingEndpoint(::grpc::ServerContext* context, const ::dmi::HardwareID* request, ::dmi::GetLoggingEndpointResponse* response) {
+  (void) context;
+  (void) request;
+  (void) response;
+  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+}
+
+::grpc::Status NativeHWManagementService::Service::SetMsgBusEndpoint(::grpc::ServerContext* context, const ::dmi::SetMsgBusEndpointRequest* request, ::dmi::SetRemoteEndpointResponse* response) {
+  (void) context;
+  (void) request;
+  (void) response;
+  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+}
+
+::grpc::Status NativeHWManagementService::Service::GetMsgBusEndpoint(::grpc::ServerContext* context, const ::google::protobuf::Empty* request, ::dmi::GetMsgBusEndpointResponse* response) {
+  (void) context;
+  (void) request;
+  (void) response;
+  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+}
+
+::grpc::Status NativeHWManagementService::Service::GetLoggableEntities(::grpc::ServerContext* context, const ::dmi::GetLoggableEntitiesRequest* request, ::dmi::GetLogLevelResponse* response) {
+  (void) context;
+  (void) request;
+  (void) response;
+  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+}
+
+::grpc::Status NativeHWManagementService::Service::SetLogLevel(::grpc::ServerContext* context, const ::dmi::SetLogLevelRequest* request, ::dmi::SetLogLevelResponse* response) {
+  (void) context;
+  (void) request;
+  (void) response;
+  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+}
+
+::grpc::Status NativeHWManagementService::Service::GetLogLevel(::grpc::ServerContext* context, const ::dmi::GetLogLevelRequest* request, ::dmi::GetLogLevelResponse* response) {
+  (void) context;
+  (void) request;
+  (void) response;
+  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+}
+
+
+}  // namespace dmi
+
diff --git a/cpp/dmi/hw_management_service.grpc.pb.h b/cpp/dmi/hw_management_service.grpc.pb.h
new file mode 100644
index 0000000..db23956
--- /dev/null
+++ b/cpp/dmi/hw_management_service.grpc.pb.h
@@ -0,0 +1,2893 @@
+// Generated by the gRPC C++ plugin.
+// If you make any local change, they will be lost.
+// source: dmi/hw_management_service.proto
+#ifndef GRPC_dmi_2fhw_5fmanagement_5fservice_2eproto__INCLUDED
+#define GRPC_dmi_2fhw_5fmanagement_5fservice_2eproto__INCLUDED
+
+#include "dmi/hw_management_service.pb.h"
+
+#include <functional>
+#include <grpc/impl/codegen/port_platform.h>
+#include <grpcpp/impl/codegen/async_generic_service.h>
+#include <grpcpp/impl/codegen/async_stream.h>
+#include <grpcpp/impl/codegen/async_unary_call.h>
+#include <grpcpp/impl/codegen/client_callback.h>
+#include <grpcpp/impl/codegen/client_context.h>
+#include <grpcpp/impl/codegen/completion_queue.h>
+#include <grpcpp/impl/codegen/message_allocator.h>
+#include <grpcpp/impl/codegen/method_handler.h>
+#include <grpcpp/impl/codegen/proto_utils.h>
+#include <grpcpp/impl/codegen/rpc_method.h>
+#include <grpcpp/impl/codegen/server_callback.h>
+#include <grpcpp/impl/codegen/server_callback_handlers.h>
+#include <grpcpp/impl/codegen/server_context.h>
+#include <grpcpp/impl/codegen/service_type.h>
+#include <grpcpp/impl/codegen/status.h>
+#include <grpcpp/impl/codegen/stub_options.h>
+#include <grpcpp/impl/codegen/sync_stream.h>
+
+namespace dmi {
+
+class NativeHWManagementService final {
+ public:
+  static constexpr char const* service_full_name() {
+    return "dmi.NativeHWManagementService";
+  }
+  class StubInterface {
+   public:
+    virtual ~StubInterface() {}
+    // Initializes context for a device and sets up required states
+    // In the call to StartManagingDevice, the fields of ModifiableComponent which are relevant
+    // and their meanings in this context is mentioned below:
+    // name = The unique name that needs to be assigned to this hardware;
+    // class = COMPONENT_TYPE_UNDEFINED;
+    // parent = nil;
+    // alias = Optional;
+    // asset_id = Optional;
+    // uri = IP Address of the Hardware;
+    std::unique_ptr< ::grpc::ClientReaderInterface< ::dmi::StartManagingDeviceResponse>> StartManagingDevice(::grpc::ClientContext* context, const ::dmi::ModifiableComponent& request) {
+      return std::unique_ptr< ::grpc::ClientReaderInterface< ::dmi::StartManagingDeviceResponse>>(StartManagingDeviceRaw(context, request));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncReaderInterface< ::dmi::StartManagingDeviceResponse>> AsyncStartManagingDevice(::grpc::ClientContext* context, const ::dmi::ModifiableComponent& request, ::grpc::CompletionQueue* cq, void* tag) {
+      return std::unique_ptr< ::grpc::ClientAsyncReaderInterface< ::dmi::StartManagingDeviceResponse>>(AsyncStartManagingDeviceRaw(context, request, cq, tag));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncReaderInterface< ::dmi::StartManagingDeviceResponse>> PrepareAsyncStartManagingDevice(::grpc::ClientContext* context, const ::dmi::ModifiableComponent& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncReaderInterface< ::dmi::StartManagingDeviceResponse>>(PrepareAsyncStartManagingDeviceRaw(context, request, cq));
+    }
+    // Stop management of a device and clean up any context and caches for that device
+    // This rpc can be called at any time, even before the StartManagingDevice operation
+    // has completed, and should be able to cleanup.
+    virtual ::grpc::Status StopManagingDevice(::grpc::ClientContext* context, const ::dmi::StopManagingDeviceRequest& request, ::dmi::StopManagingDeviceResponse* response) = 0;
+    std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::StopManagingDeviceResponse>> AsyncStopManagingDevice(::grpc::ClientContext* context, const ::dmi::StopManagingDeviceRequest& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::StopManagingDeviceResponse>>(AsyncStopManagingDeviceRaw(context, request, cq));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::StopManagingDeviceResponse>> PrepareAsyncStopManagingDevice(::grpc::ClientContext* context, const ::dmi::StopManagingDeviceRequest& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::StopManagingDeviceResponse>>(PrepareAsyncStopManagingDeviceRaw(context, request, cq));
+    }
+    // Returns an object containing a list of devices managed by this entity
+    virtual ::grpc::Status GetManagedDevices(::grpc::ClientContext* context, const ::google::protobuf::Empty& request, ::dmi::ManagedDevicesResponse* response) = 0;
+    std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::ManagedDevicesResponse>> AsyncGetManagedDevices(::grpc::ClientContext* context, const ::google::protobuf::Empty& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::ManagedDevicesResponse>>(AsyncGetManagedDevicesRaw(context, request, cq));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::ManagedDevicesResponse>> PrepareAsyncGetManagedDevices(::grpc::ClientContext* context, const ::google::protobuf::Empty& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::ManagedDevicesResponse>>(PrepareAsyncGetManagedDevicesRaw(context, request, cq));
+    }
+    // Get the HW inventory details of the Device
+    std::unique_ptr< ::grpc::ClientReaderInterface< ::dmi::PhysicalInventoryResponse>> GetPhysicalInventory(::grpc::ClientContext* context, const ::dmi::PhysicalInventoryRequest& request) {
+      return std::unique_ptr< ::grpc::ClientReaderInterface< ::dmi::PhysicalInventoryResponse>>(GetPhysicalInventoryRaw(context, request));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncReaderInterface< ::dmi::PhysicalInventoryResponse>> AsyncGetPhysicalInventory(::grpc::ClientContext* context, const ::dmi::PhysicalInventoryRequest& request, ::grpc::CompletionQueue* cq, void* tag) {
+      return std::unique_ptr< ::grpc::ClientAsyncReaderInterface< ::dmi::PhysicalInventoryResponse>>(AsyncGetPhysicalInventoryRaw(context, request, cq, tag));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncReaderInterface< ::dmi::PhysicalInventoryResponse>> PrepareAsyncGetPhysicalInventory(::grpc::ClientContext* context, const ::dmi::PhysicalInventoryRequest& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncReaderInterface< ::dmi::PhysicalInventoryResponse>>(PrepareAsyncGetPhysicalInventoryRaw(context, request, cq));
+    }
+    // Get the details of a particular HW component
+    std::unique_ptr< ::grpc::ClientReaderInterface< ::dmi::HWComponentInfoGetResponse>> GetHWComponentInfo(::grpc::ClientContext* context, const ::dmi::HWComponentInfoGetRequest& request) {
+      return std::unique_ptr< ::grpc::ClientReaderInterface< ::dmi::HWComponentInfoGetResponse>>(GetHWComponentInfoRaw(context, request));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncReaderInterface< ::dmi::HWComponentInfoGetResponse>> AsyncGetHWComponentInfo(::grpc::ClientContext* context, const ::dmi::HWComponentInfoGetRequest& request, ::grpc::CompletionQueue* cq, void* tag) {
+      return std::unique_ptr< ::grpc::ClientAsyncReaderInterface< ::dmi::HWComponentInfoGetResponse>>(AsyncGetHWComponentInfoRaw(context, request, cq, tag));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncReaderInterface< ::dmi::HWComponentInfoGetResponse>> PrepareAsyncGetHWComponentInfo(::grpc::ClientContext* context, const ::dmi::HWComponentInfoGetRequest& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncReaderInterface< ::dmi::HWComponentInfoGetResponse>>(PrepareAsyncGetHWComponentInfoRaw(context, request, cq));
+    }
+    // Sets the permissible attributes of a HW component
+    virtual ::grpc::Status SetHWComponentInfo(::grpc::ClientContext* context, const ::dmi::HWComponentInfoSetRequest& request, ::dmi::HWComponentInfoSetResponse* response) = 0;
+    std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::HWComponentInfoSetResponse>> AsyncSetHWComponentInfo(::grpc::ClientContext* context, const ::dmi::HWComponentInfoSetRequest& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::HWComponentInfoSetResponse>>(AsyncSetHWComponentInfoRaw(context, request, cq));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::HWComponentInfoSetResponse>> PrepareAsyncSetHWComponentInfo(::grpc::ClientContext* context, const ::dmi::HWComponentInfoSetRequest& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::HWComponentInfoSetResponse>>(PrepareAsyncSetHWComponentInfoRaw(context, request, cq));
+    }
+    // Sets the location to which logs need to be shipped
+    virtual ::grpc::Status SetLoggingEndpoint(::grpc::ClientContext* context, const ::dmi::SetLoggingEndpointRequest& request, ::dmi::SetRemoteEndpointResponse* response) = 0;
+    std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::SetRemoteEndpointResponse>> AsyncSetLoggingEndpoint(::grpc::ClientContext* context, const ::dmi::SetLoggingEndpointRequest& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::SetRemoteEndpointResponse>>(AsyncSetLoggingEndpointRaw(context, request, cq));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::SetRemoteEndpointResponse>> PrepareAsyncSetLoggingEndpoint(::grpc::ClientContext* context, const ::dmi::SetLoggingEndpointRequest& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::SetRemoteEndpointResponse>>(PrepareAsyncSetLoggingEndpointRaw(context, request, cq));
+    }
+    // Gets the configured location to which the logs are being shipped
+    virtual ::grpc::Status GetLoggingEndpoint(::grpc::ClientContext* context, const ::dmi::HardwareID& request, ::dmi::GetLoggingEndpointResponse* response) = 0;
+    std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::GetLoggingEndpointResponse>> AsyncGetLoggingEndpoint(::grpc::ClientContext* context, const ::dmi::HardwareID& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::GetLoggingEndpointResponse>>(AsyncGetLoggingEndpointRaw(context, request, cq));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::GetLoggingEndpointResponse>> PrepareAsyncGetLoggingEndpoint(::grpc::ClientContext* context, const ::dmi::HardwareID& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::GetLoggingEndpointResponse>>(PrepareAsyncGetLoggingEndpointRaw(context, request, cq));
+    }
+    // Sets the location of the Message Bus to which events and metrics are shipped
+    virtual ::grpc::Status SetMsgBusEndpoint(::grpc::ClientContext* context, const ::dmi::SetMsgBusEndpointRequest& request, ::dmi::SetRemoteEndpointResponse* response) = 0;
+    std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::SetRemoteEndpointResponse>> AsyncSetMsgBusEndpoint(::grpc::ClientContext* context, const ::dmi::SetMsgBusEndpointRequest& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::SetRemoteEndpointResponse>>(AsyncSetMsgBusEndpointRaw(context, request, cq));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::SetRemoteEndpointResponse>> PrepareAsyncSetMsgBusEndpoint(::grpc::ClientContext* context, const ::dmi::SetMsgBusEndpointRequest& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::SetRemoteEndpointResponse>>(PrepareAsyncSetMsgBusEndpointRaw(context, request, cq));
+    }
+    // Gets the configured location to which the events and metrics are being shipped
+    virtual ::grpc::Status GetMsgBusEndpoint(::grpc::ClientContext* context, const ::google::protobuf::Empty& request, ::dmi::GetMsgBusEndpointResponse* response) = 0;
+    std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::GetMsgBusEndpointResponse>> AsyncGetMsgBusEndpoint(::grpc::ClientContext* context, const ::google::protobuf::Empty& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::GetMsgBusEndpointResponse>>(AsyncGetMsgBusEndpointRaw(context, request, cq));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::GetMsgBusEndpointResponse>> PrepareAsyncGetMsgBusEndpoint(::grpc::ClientContext* context, const ::google::protobuf::Empty& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::GetMsgBusEndpointResponse>>(PrepareAsyncGetMsgBusEndpointRaw(context, request, cq));
+    }
+    // Gets the entities of a device on which log can be configured. A few are expected, like OS, PON Management etc.
+    // In general an entity is any item within an hardware system that can emit logs, e.g. service, process, subsystem,
+    // interface, package etc.
+    virtual ::grpc::Status GetLoggableEntities(::grpc::ClientContext* context, const ::dmi::GetLoggableEntitiesRequest& request, ::dmi::GetLogLevelResponse* response) = 0;
+    std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::GetLogLevelResponse>> AsyncGetLoggableEntities(::grpc::ClientContext* context, const ::dmi::GetLoggableEntitiesRequest& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::GetLogLevelResponse>>(AsyncGetLoggableEntitiesRaw(context, request, cq));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::GetLogLevelResponse>> PrepareAsyncGetLoggableEntities(::grpc::ClientContext* context, const ::dmi::GetLoggableEntitiesRequest& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::GetLogLevelResponse>>(PrepareAsyncGetLoggableEntitiesRaw(context, request, cq));
+    }
+    // Sets the log level of the device, for each given entity to a certain level.
+    // If only one EntitiesLogLevel is provided for the device and that request contains only a log level with
+    // no entity in the list it's assumed that the caller wants to set that level for all the entities.
+    virtual ::grpc::Status SetLogLevel(::grpc::ClientContext* context, const ::dmi::SetLogLevelRequest& request, ::dmi::SetLogLevelResponse* response) = 0;
+    std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::SetLogLevelResponse>> AsyncSetLogLevel(::grpc::ClientContext* context, const ::dmi::SetLogLevelRequest& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::SetLogLevelResponse>>(AsyncSetLogLevelRaw(context, request, cq));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::SetLogLevelResponse>> PrepareAsyncSetLogLevel(::grpc::ClientContext* context, const ::dmi::SetLogLevelRequest& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::SetLogLevelResponse>>(PrepareAsyncSetLogLevelRaw(context, request, cq));
+    }
+    // Gets the configured log level for a certain entity on a certain device.
+    // If no entity is specified in the request all the entities with their log level should be returned.
+    virtual ::grpc::Status GetLogLevel(::grpc::ClientContext* context, const ::dmi::GetLogLevelRequest& request, ::dmi::GetLogLevelResponse* response) = 0;
+    std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::GetLogLevelResponse>> AsyncGetLogLevel(::grpc::ClientContext* context, const ::dmi::GetLogLevelRequest& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::GetLogLevelResponse>>(AsyncGetLogLevelRaw(context, request, cq));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::GetLogLevelResponse>> PrepareAsyncGetLogLevel(::grpc::ClientContext* context, const ::dmi::GetLogLevelRequest& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::GetLogLevelResponse>>(PrepareAsyncGetLogLevelRaw(context, request, cq));
+    }
+    class experimental_async_interface {
+     public:
+      virtual ~experimental_async_interface() {}
+      // Initializes context for a device and sets up required states
+      // In the call to StartManagingDevice, the fields of ModifiableComponent which are relevant
+      // and their meanings in this context is mentioned below:
+      // name = The unique name that needs to be assigned to this hardware;
+      // class = COMPONENT_TYPE_UNDEFINED;
+      // parent = nil;
+      // alias = Optional;
+      // asset_id = Optional;
+      // uri = IP Address of the Hardware;
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      virtual void StartManagingDevice(::grpc::ClientContext* context, ::dmi::ModifiableComponent* request, ::grpc::ClientReadReactor< ::dmi::StartManagingDeviceResponse>* reactor) = 0;
+      #else
+      virtual void StartManagingDevice(::grpc::ClientContext* context, ::dmi::ModifiableComponent* request, ::grpc::experimental::ClientReadReactor< ::dmi::StartManagingDeviceResponse>* reactor) = 0;
+      #endif
+      // Stop management of a device and clean up any context and caches for that device
+      // This rpc can be called at any time, even before the StartManagingDevice operation
+      // has completed, and should be able to cleanup.
+      virtual void StopManagingDevice(::grpc::ClientContext* context, const ::dmi::StopManagingDeviceRequest* request, ::dmi::StopManagingDeviceResponse* response, std::function<void(::grpc::Status)>) = 0;
+      virtual void StopManagingDevice(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::StopManagingDeviceResponse* response, std::function<void(::grpc::Status)>) = 0;
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      virtual void StopManagingDevice(::grpc::ClientContext* context, const ::dmi::StopManagingDeviceRequest* request, ::dmi::StopManagingDeviceResponse* response, ::grpc::ClientUnaryReactor* reactor) = 0;
+      #else
+      virtual void StopManagingDevice(::grpc::ClientContext* context, const ::dmi::StopManagingDeviceRequest* request, ::dmi::StopManagingDeviceResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) = 0;
+      #endif
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      virtual void StopManagingDevice(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::StopManagingDeviceResponse* response, ::grpc::ClientUnaryReactor* reactor) = 0;
+      #else
+      virtual void StopManagingDevice(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::StopManagingDeviceResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) = 0;
+      #endif
+      // Returns an object containing a list of devices managed by this entity
+      virtual void GetManagedDevices(::grpc::ClientContext* context, const ::google::protobuf::Empty* request, ::dmi::ManagedDevicesResponse* response, std::function<void(::grpc::Status)>) = 0;
+      virtual void GetManagedDevices(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::ManagedDevicesResponse* response, std::function<void(::grpc::Status)>) = 0;
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      virtual void GetManagedDevices(::grpc::ClientContext* context, const ::google::protobuf::Empty* request, ::dmi::ManagedDevicesResponse* response, ::grpc::ClientUnaryReactor* reactor) = 0;
+      #else
+      virtual void GetManagedDevices(::grpc::ClientContext* context, const ::google::protobuf::Empty* request, ::dmi::ManagedDevicesResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) = 0;
+      #endif
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      virtual void GetManagedDevices(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::ManagedDevicesResponse* response, ::grpc::ClientUnaryReactor* reactor) = 0;
+      #else
+      virtual void GetManagedDevices(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::ManagedDevicesResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) = 0;
+      #endif
+      // Get the HW inventory details of the Device
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      virtual void GetPhysicalInventory(::grpc::ClientContext* context, ::dmi::PhysicalInventoryRequest* request, ::grpc::ClientReadReactor< ::dmi::PhysicalInventoryResponse>* reactor) = 0;
+      #else
+      virtual void GetPhysicalInventory(::grpc::ClientContext* context, ::dmi::PhysicalInventoryRequest* request, ::grpc::experimental::ClientReadReactor< ::dmi::PhysicalInventoryResponse>* reactor) = 0;
+      #endif
+      // Get the details of a particular HW component
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      virtual void GetHWComponentInfo(::grpc::ClientContext* context, ::dmi::HWComponentInfoGetRequest* request, ::grpc::ClientReadReactor< ::dmi::HWComponentInfoGetResponse>* reactor) = 0;
+      #else
+      virtual void GetHWComponentInfo(::grpc::ClientContext* context, ::dmi::HWComponentInfoGetRequest* request, ::grpc::experimental::ClientReadReactor< ::dmi::HWComponentInfoGetResponse>* reactor) = 0;
+      #endif
+      // Sets the permissible attributes of a HW component
+      virtual void SetHWComponentInfo(::grpc::ClientContext* context, const ::dmi::HWComponentInfoSetRequest* request, ::dmi::HWComponentInfoSetResponse* response, std::function<void(::grpc::Status)>) = 0;
+      virtual void SetHWComponentInfo(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::HWComponentInfoSetResponse* response, std::function<void(::grpc::Status)>) = 0;
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      virtual void SetHWComponentInfo(::grpc::ClientContext* context, const ::dmi::HWComponentInfoSetRequest* request, ::dmi::HWComponentInfoSetResponse* response, ::grpc::ClientUnaryReactor* reactor) = 0;
+      #else
+      virtual void SetHWComponentInfo(::grpc::ClientContext* context, const ::dmi::HWComponentInfoSetRequest* request, ::dmi::HWComponentInfoSetResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) = 0;
+      #endif
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      virtual void SetHWComponentInfo(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::HWComponentInfoSetResponse* response, ::grpc::ClientUnaryReactor* reactor) = 0;
+      #else
+      virtual void SetHWComponentInfo(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::HWComponentInfoSetResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) = 0;
+      #endif
+      // Sets the location to which logs need to be shipped
+      virtual void SetLoggingEndpoint(::grpc::ClientContext* context, const ::dmi::SetLoggingEndpointRequest* request, ::dmi::SetRemoteEndpointResponse* response, std::function<void(::grpc::Status)>) = 0;
+      virtual void SetLoggingEndpoint(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::SetRemoteEndpointResponse* response, std::function<void(::grpc::Status)>) = 0;
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      virtual void SetLoggingEndpoint(::grpc::ClientContext* context, const ::dmi::SetLoggingEndpointRequest* request, ::dmi::SetRemoteEndpointResponse* response, ::grpc::ClientUnaryReactor* reactor) = 0;
+      #else
+      virtual void SetLoggingEndpoint(::grpc::ClientContext* context, const ::dmi::SetLoggingEndpointRequest* request, ::dmi::SetRemoteEndpointResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) = 0;
+      #endif
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      virtual void SetLoggingEndpoint(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::SetRemoteEndpointResponse* response, ::grpc::ClientUnaryReactor* reactor) = 0;
+      #else
+      virtual void SetLoggingEndpoint(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::SetRemoteEndpointResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) = 0;
+      #endif
+      // Gets the configured location to which the logs are being shipped
+      virtual void GetLoggingEndpoint(::grpc::ClientContext* context, const ::dmi::HardwareID* request, ::dmi::GetLoggingEndpointResponse* response, std::function<void(::grpc::Status)>) = 0;
+      virtual void GetLoggingEndpoint(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::GetLoggingEndpointResponse* response, std::function<void(::grpc::Status)>) = 0;
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      virtual void GetLoggingEndpoint(::grpc::ClientContext* context, const ::dmi::HardwareID* request, ::dmi::GetLoggingEndpointResponse* response, ::grpc::ClientUnaryReactor* reactor) = 0;
+      #else
+      virtual void GetLoggingEndpoint(::grpc::ClientContext* context, const ::dmi::HardwareID* request, ::dmi::GetLoggingEndpointResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) = 0;
+      #endif
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      virtual void GetLoggingEndpoint(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::GetLoggingEndpointResponse* response, ::grpc::ClientUnaryReactor* reactor) = 0;
+      #else
+      virtual void GetLoggingEndpoint(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::GetLoggingEndpointResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) = 0;
+      #endif
+      // Sets the location of the Message Bus to which events and metrics are shipped
+      virtual void SetMsgBusEndpoint(::grpc::ClientContext* context, const ::dmi::SetMsgBusEndpointRequest* request, ::dmi::SetRemoteEndpointResponse* response, std::function<void(::grpc::Status)>) = 0;
+      virtual void SetMsgBusEndpoint(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::SetRemoteEndpointResponse* response, std::function<void(::grpc::Status)>) = 0;
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      virtual void SetMsgBusEndpoint(::grpc::ClientContext* context, const ::dmi::SetMsgBusEndpointRequest* request, ::dmi::SetRemoteEndpointResponse* response, ::grpc::ClientUnaryReactor* reactor) = 0;
+      #else
+      virtual void SetMsgBusEndpoint(::grpc::ClientContext* context, const ::dmi::SetMsgBusEndpointRequest* request, ::dmi::SetRemoteEndpointResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) = 0;
+      #endif
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      virtual void SetMsgBusEndpoint(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::SetRemoteEndpointResponse* response, ::grpc::ClientUnaryReactor* reactor) = 0;
+      #else
+      virtual void SetMsgBusEndpoint(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::SetRemoteEndpointResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) = 0;
+      #endif
+      // Gets the configured location to which the events and metrics are being shipped
+      virtual void GetMsgBusEndpoint(::grpc::ClientContext* context, const ::google::protobuf::Empty* request, ::dmi::GetMsgBusEndpointResponse* response, std::function<void(::grpc::Status)>) = 0;
+      virtual void GetMsgBusEndpoint(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::GetMsgBusEndpointResponse* response, std::function<void(::grpc::Status)>) = 0;
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      virtual void GetMsgBusEndpoint(::grpc::ClientContext* context, const ::google::protobuf::Empty* request, ::dmi::GetMsgBusEndpointResponse* response, ::grpc::ClientUnaryReactor* reactor) = 0;
+      #else
+      virtual void GetMsgBusEndpoint(::grpc::ClientContext* context, const ::google::protobuf::Empty* request, ::dmi::GetMsgBusEndpointResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) = 0;
+      #endif
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      virtual void GetMsgBusEndpoint(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::GetMsgBusEndpointResponse* response, ::grpc::ClientUnaryReactor* reactor) = 0;
+      #else
+      virtual void GetMsgBusEndpoint(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::GetMsgBusEndpointResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) = 0;
+      #endif
+      // Gets the entities of a device on which log can be configured. A few are expected, like OS, PON Management etc.
+      // In general an entity is any item within an hardware system that can emit logs, e.g. service, process, subsystem,
+      // interface, package etc.
+      virtual void GetLoggableEntities(::grpc::ClientContext* context, const ::dmi::GetLoggableEntitiesRequest* request, ::dmi::GetLogLevelResponse* response, std::function<void(::grpc::Status)>) = 0;
+      virtual void GetLoggableEntities(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::GetLogLevelResponse* response, std::function<void(::grpc::Status)>) = 0;
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      virtual void GetLoggableEntities(::grpc::ClientContext* context, const ::dmi::GetLoggableEntitiesRequest* request, ::dmi::GetLogLevelResponse* response, ::grpc::ClientUnaryReactor* reactor) = 0;
+      #else
+      virtual void GetLoggableEntities(::grpc::ClientContext* context, const ::dmi::GetLoggableEntitiesRequest* request, ::dmi::GetLogLevelResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) = 0;
+      #endif
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      virtual void GetLoggableEntities(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::GetLogLevelResponse* response, ::grpc::ClientUnaryReactor* reactor) = 0;
+      #else
+      virtual void GetLoggableEntities(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::GetLogLevelResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) = 0;
+      #endif
+      // Sets the log level of the device, for each given entity to a certain level.
+      // If only one EntitiesLogLevel is provided for the device and that request contains only a log level with
+      // no entity in the list it's assumed that the caller wants to set that level for all the entities.
+      virtual void SetLogLevel(::grpc::ClientContext* context, const ::dmi::SetLogLevelRequest* request, ::dmi::SetLogLevelResponse* response, std::function<void(::grpc::Status)>) = 0;
+      virtual void SetLogLevel(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::SetLogLevelResponse* response, std::function<void(::grpc::Status)>) = 0;
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      virtual void SetLogLevel(::grpc::ClientContext* context, const ::dmi::SetLogLevelRequest* request, ::dmi::SetLogLevelResponse* response, ::grpc::ClientUnaryReactor* reactor) = 0;
+      #else
+      virtual void SetLogLevel(::grpc::ClientContext* context, const ::dmi::SetLogLevelRequest* request, ::dmi::SetLogLevelResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) = 0;
+      #endif
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      virtual void SetLogLevel(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::SetLogLevelResponse* response, ::grpc::ClientUnaryReactor* reactor) = 0;
+      #else
+      virtual void SetLogLevel(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::SetLogLevelResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) = 0;
+      #endif
+      // Gets the configured log level for a certain entity on a certain device.
+      // If no entity is specified in the request all the entities with their log level should be returned.
+      virtual void GetLogLevel(::grpc::ClientContext* context, const ::dmi::GetLogLevelRequest* request, ::dmi::GetLogLevelResponse* response, std::function<void(::grpc::Status)>) = 0;
+      virtual void GetLogLevel(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::GetLogLevelResponse* response, std::function<void(::grpc::Status)>) = 0;
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      virtual void GetLogLevel(::grpc::ClientContext* context, const ::dmi::GetLogLevelRequest* request, ::dmi::GetLogLevelResponse* response, ::grpc::ClientUnaryReactor* reactor) = 0;
+      #else
+      virtual void GetLogLevel(::grpc::ClientContext* context, const ::dmi::GetLogLevelRequest* request, ::dmi::GetLogLevelResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) = 0;
+      #endif
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      virtual void GetLogLevel(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::GetLogLevelResponse* response, ::grpc::ClientUnaryReactor* reactor) = 0;
+      #else
+      virtual void GetLogLevel(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::GetLogLevelResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) = 0;
+      #endif
+    };
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+    typedef class experimental_async_interface async_interface;
+    #endif
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+    async_interface* async() { return experimental_async(); }
+    #endif
+    virtual class experimental_async_interface* experimental_async() { return nullptr; }
+  private:
+    virtual ::grpc::ClientReaderInterface< ::dmi::StartManagingDeviceResponse>* StartManagingDeviceRaw(::grpc::ClientContext* context, const ::dmi::ModifiableComponent& request) = 0;
+    virtual ::grpc::ClientAsyncReaderInterface< ::dmi::StartManagingDeviceResponse>* AsyncStartManagingDeviceRaw(::grpc::ClientContext* context, const ::dmi::ModifiableComponent& request, ::grpc::CompletionQueue* cq, void* tag) = 0;
+    virtual ::grpc::ClientAsyncReaderInterface< ::dmi::StartManagingDeviceResponse>* PrepareAsyncStartManagingDeviceRaw(::grpc::ClientContext* context, const ::dmi::ModifiableComponent& request, ::grpc::CompletionQueue* cq) = 0;
+    virtual ::grpc::ClientAsyncResponseReaderInterface< ::dmi::StopManagingDeviceResponse>* AsyncStopManagingDeviceRaw(::grpc::ClientContext* context, const ::dmi::StopManagingDeviceRequest& request, ::grpc::CompletionQueue* cq) = 0;
+    virtual ::grpc::ClientAsyncResponseReaderInterface< ::dmi::StopManagingDeviceResponse>* PrepareAsyncStopManagingDeviceRaw(::grpc::ClientContext* context, const ::dmi::StopManagingDeviceRequest& request, ::grpc::CompletionQueue* cq) = 0;
+    virtual ::grpc::ClientAsyncResponseReaderInterface< ::dmi::ManagedDevicesResponse>* AsyncGetManagedDevicesRaw(::grpc::ClientContext* context, const ::google::protobuf::Empty& request, ::grpc::CompletionQueue* cq) = 0;
+    virtual ::grpc::ClientAsyncResponseReaderInterface< ::dmi::ManagedDevicesResponse>* PrepareAsyncGetManagedDevicesRaw(::grpc::ClientContext* context, const ::google::protobuf::Empty& request, ::grpc::CompletionQueue* cq) = 0;
+    virtual ::grpc::ClientReaderInterface< ::dmi::PhysicalInventoryResponse>* GetPhysicalInventoryRaw(::grpc::ClientContext* context, const ::dmi::PhysicalInventoryRequest& request) = 0;
+    virtual ::grpc::ClientAsyncReaderInterface< ::dmi::PhysicalInventoryResponse>* AsyncGetPhysicalInventoryRaw(::grpc::ClientContext* context, const ::dmi::PhysicalInventoryRequest& request, ::grpc::CompletionQueue* cq, void* tag) = 0;
+    virtual ::grpc::ClientAsyncReaderInterface< ::dmi::PhysicalInventoryResponse>* PrepareAsyncGetPhysicalInventoryRaw(::grpc::ClientContext* context, const ::dmi::PhysicalInventoryRequest& request, ::grpc::CompletionQueue* cq) = 0;
+    virtual ::grpc::ClientReaderInterface< ::dmi::HWComponentInfoGetResponse>* GetHWComponentInfoRaw(::grpc::ClientContext* context, const ::dmi::HWComponentInfoGetRequest& request) = 0;
+    virtual ::grpc::ClientAsyncReaderInterface< ::dmi::HWComponentInfoGetResponse>* AsyncGetHWComponentInfoRaw(::grpc::ClientContext* context, const ::dmi::HWComponentInfoGetRequest& request, ::grpc::CompletionQueue* cq, void* tag) = 0;
+    virtual ::grpc::ClientAsyncReaderInterface< ::dmi::HWComponentInfoGetResponse>* PrepareAsyncGetHWComponentInfoRaw(::grpc::ClientContext* context, const ::dmi::HWComponentInfoGetRequest& request, ::grpc::CompletionQueue* cq) = 0;
+    virtual ::grpc::ClientAsyncResponseReaderInterface< ::dmi::HWComponentInfoSetResponse>* AsyncSetHWComponentInfoRaw(::grpc::ClientContext* context, const ::dmi::HWComponentInfoSetRequest& request, ::grpc::CompletionQueue* cq) = 0;
+    virtual ::grpc::ClientAsyncResponseReaderInterface< ::dmi::HWComponentInfoSetResponse>* PrepareAsyncSetHWComponentInfoRaw(::grpc::ClientContext* context, const ::dmi::HWComponentInfoSetRequest& request, ::grpc::CompletionQueue* cq) = 0;
+    virtual ::grpc::ClientAsyncResponseReaderInterface< ::dmi::SetRemoteEndpointResponse>* AsyncSetLoggingEndpointRaw(::grpc::ClientContext* context, const ::dmi::SetLoggingEndpointRequest& request, ::grpc::CompletionQueue* cq) = 0;
+    virtual ::grpc::ClientAsyncResponseReaderInterface< ::dmi::SetRemoteEndpointResponse>* PrepareAsyncSetLoggingEndpointRaw(::grpc::ClientContext* context, const ::dmi::SetLoggingEndpointRequest& request, ::grpc::CompletionQueue* cq) = 0;
+    virtual ::grpc::ClientAsyncResponseReaderInterface< ::dmi::GetLoggingEndpointResponse>* AsyncGetLoggingEndpointRaw(::grpc::ClientContext* context, const ::dmi::HardwareID& request, ::grpc::CompletionQueue* cq) = 0;
+    virtual ::grpc::ClientAsyncResponseReaderInterface< ::dmi::GetLoggingEndpointResponse>* PrepareAsyncGetLoggingEndpointRaw(::grpc::ClientContext* context, const ::dmi::HardwareID& request, ::grpc::CompletionQueue* cq) = 0;
+    virtual ::grpc::ClientAsyncResponseReaderInterface< ::dmi::SetRemoteEndpointResponse>* AsyncSetMsgBusEndpointRaw(::grpc::ClientContext* context, const ::dmi::SetMsgBusEndpointRequest& request, ::grpc::CompletionQueue* cq) = 0;
+    virtual ::grpc::ClientAsyncResponseReaderInterface< ::dmi::SetRemoteEndpointResponse>* PrepareAsyncSetMsgBusEndpointRaw(::grpc::ClientContext* context, const ::dmi::SetMsgBusEndpointRequest& request, ::grpc::CompletionQueue* cq) = 0;
+    virtual ::grpc::ClientAsyncResponseReaderInterface< ::dmi::GetMsgBusEndpointResponse>* AsyncGetMsgBusEndpointRaw(::grpc::ClientContext* context, const ::google::protobuf::Empty& request, ::grpc::CompletionQueue* cq) = 0;
+    virtual ::grpc::ClientAsyncResponseReaderInterface< ::dmi::GetMsgBusEndpointResponse>* PrepareAsyncGetMsgBusEndpointRaw(::grpc::ClientContext* context, const ::google::protobuf::Empty& request, ::grpc::CompletionQueue* cq) = 0;
+    virtual ::grpc::ClientAsyncResponseReaderInterface< ::dmi::GetLogLevelResponse>* AsyncGetLoggableEntitiesRaw(::grpc::ClientContext* context, const ::dmi::GetLoggableEntitiesRequest& request, ::grpc::CompletionQueue* cq) = 0;
+    virtual ::grpc::ClientAsyncResponseReaderInterface< ::dmi::GetLogLevelResponse>* PrepareAsyncGetLoggableEntitiesRaw(::grpc::ClientContext* context, const ::dmi::GetLoggableEntitiesRequest& request, ::grpc::CompletionQueue* cq) = 0;
+    virtual ::grpc::ClientAsyncResponseReaderInterface< ::dmi::SetLogLevelResponse>* AsyncSetLogLevelRaw(::grpc::ClientContext* context, const ::dmi::SetLogLevelRequest& request, ::grpc::CompletionQueue* cq) = 0;
+    virtual ::grpc::ClientAsyncResponseReaderInterface< ::dmi::SetLogLevelResponse>* PrepareAsyncSetLogLevelRaw(::grpc::ClientContext* context, const ::dmi::SetLogLevelRequest& request, ::grpc::CompletionQueue* cq) = 0;
+    virtual ::grpc::ClientAsyncResponseReaderInterface< ::dmi::GetLogLevelResponse>* AsyncGetLogLevelRaw(::grpc::ClientContext* context, const ::dmi::GetLogLevelRequest& request, ::grpc::CompletionQueue* cq) = 0;
+    virtual ::grpc::ClientAsyncResponseReaderInterface< ::dmi::GetLogLevelResponse>* PrepareAsyncGetLogLevelRaw(::grpc::ClientContext* context, const ::dmi::GetLogLevelRequest& request, ::grpc::CompletionQueue* cq) = 0;
+  };
+  class Stub final : public StubInterface {
+   public:
+    Stub(const std::shared_ptr< ::grpc::ChannelInterface>& channel);
+    std::unique_ptr< ::grpc::ClientReader< ::dmi::StartManagingDeviceResponse>> StartManagingDevice(::grpc::ClientContext* context, const ::dmi::ModifiableComponent& request) {
+      return std::unique_ptr< ::grpc::ClientReader< ::dmi::StartManagingDeviceResponse>>(StartManagingDeviceRaw(context, request));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncReader< ::dmi::StartManagingDeviceResponse>> AsyncStartManagingDevice(::grpc::ClientContext* context, const ::dmi::ModifiableComponent& request, ::grpc::CompletionQueue* cq, void* tag) {
+      return std::unique_ptr< ::grpc::ClientAsyncReader< ::dmi::StartManagingDeviceResponse>>(AsyncStartManagingDeviceRaw(context, request, cq, tag));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncReader< ::dmi::StartManagingDeviceResponse>> PrepareAsyncStartManagingDevice(::grpc::ClientContext* context, const ::dmi::ModifiableComponent& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncReader< ::dmi::StartManagingDeviceResponse>>(PrepareAsyncStartManagingDeviceRaw(context, request, cq));
+    }
+    ::grpc::Status StopManagingDevice(::grpc::ClientContext* context, const ::dmi::StopManagingDeviceRequest& request, ::dmi::StopManagingDeviceResponse* response) override;
+    std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::StopManagingDeviceResponse>> AsyncStopManagingDevice(::grpc::ClientContext* context, const ::dmi::StopManagingDeviceRequest& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::StopManagingDeviceResponse>>(AsyncStopManagingDeviceRaw(context, request, cq));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::StopManagingDeviceResponse>> PrepareAsyncStopManagingDevice(::grpc::ClientContext* context, const ::dmi::StopManagingDeviceRequest& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::StopManagingDeviceResponse>>(PrepareAsyncStopManagingDeviceRaw(context, request, cq));
+    }
+    ::grpc::Status GetManagedDevices(::grpc::ClientContext* context, const ::google::protobuf::Empty& request, ::dmi::ManagedDevicesResponse* response) override;
+    std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::ManagedDevicesResponse>> AsyncGetManagedDevices(::grpc::ClientContext* context, const ::google::protobuf::Empty& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::ManagedDevicesResponse>>(AsyncGetManagedDevicesRaw(context, request, cq));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::ManagedDevicesResponse>> PrepareAsyncGetManagedDevices(::grpc::ClientContext* context, const ::google::protobuf::Empty& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::ManagedDevicesResponse>>(PrepareAsyncGetManagedDevicesRaw(context, request, cq));
+    }
+    std::unique_ptr< ::grpc::ClientReader< ::dmi::PhysicalInventoryResponse>> GetPhysicalInventory(::grpc::ClientContext* context, const ::dmi::PhysicalInventoryRequest& request) {
+      return std::unique_ptr< ::grpc::ClientReader< ::dmi::PhysicalInventoryResponse>>(GetPhysicalInventoryRaw(context, request));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncReader< ::dmi::PhysicalInventoryResponse>> AsyncGetPhysicalInventory(::grpc::ClientContext* context, const ::dmi::PhysicalInventoryRequest& request, ::grpc::CompletionQueue* cq, void* tag) {
+      return std::unique_ptr< ::grpc::ClientAsyncReader< ::dmi::PhysicalInventoryResponse>>(AsyncGetPhysicalInventoryRaw(context, request, cq, tag));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncReader< ::dmi::PhysicalInventoryResponse>> PrepareAsyncGetPhysicalInventory(::grpc::ClientContext* context, const ::dmi::PhysicalInventoryRequest& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncReader< ::dmi::PhysicalInventoryResponse>>(PrepareAsyncGetPhysicalInventoryRaw(context, request, cq));
+    }
+    std::unique_ptr< ::grpc::ClientReader< ::dmi::HWComponentInfoGetResponse>> GetHWComponentInfo(::grpc::ClientContext* context, const ::dmi::HWComponentInfoGetRequest& request) {
+      return std::unique_ptr< ::grpc::ClientReader< ::dmi::HWComponentInfoGetResponse>>(GetHWComponentInfoRaw(context, request));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncReader< ::dmi::HWComponentInfoGetResponse>> AsyncGetHWComponentInfo(::grpc::ClientContext* context, const ::dmi::HWComponentInfoGetRequest& request, ::grpc::CompletionQueue* cq, void* tag) {
+      return std::unique_ptr< ::grpc::ClientAsyncReader< ::dmi::HWComponentInfoGetResponse>>(AsyncGetHWComponentInfoRaw(context, request, cq, tag));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncReader< ::dmi::HWComponentInfoGetResponse>> PrepareAsyncGetHWComponentInfo(::grpc::ClientContext* context, const ::dmi::HWComponentInfoGetRequest& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncReader< ::dmi::HWComponentInfoGetResponse>>(PrepareAsyncGetHWComponentInfoRaw(context, request, cq));
+    }
+    ::grpc::Status SetHWComponentInfo(::grpc::ClientContext* context, const ::dmi::HWComponentInfoSetRequest& request, ::dmi::HWComponentInfoSetResponse* response) override;
+    std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::HWComponentInfoSetResponse>> AsyncSetHWComponentInfo(::grpc::ClientContext* context, const ::dmi::HWComponentInfoSetRequest& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::HWComponentInfoSetResponse>>(AsyncSetHWComponentInfoRaw(context, request, cq));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::HWComponentInfoSetResponse>> PrepareAsyncSetHWComponentInfo(::grpc::ClientContext* context, const ::dmi::HWComponentInfoSetRequest& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::HWComponentInfoSetResponse>>(PrepareAsyncSetHWComponentInfoRaw(context, request, cq));
+    }
+    ::grpc::Status SetLoggingEndpoint(::grpc::ClientContext* context, const ::dmi::SetLoggingEndpointRequest& request, ::dmi::SetRemoteEndpointResponse* response) override;
+    std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::SetRemoteEndpointResponse>> AsyncSetLoggingEndpoint(::grpc::ClientContext* context, const ::dmi::SetLoggingEndpointRequest& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::SetRemoteEndpointResponse>>(AsyncSetLoggingEndpointRaw(context, request, cq));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::SetRemoteEndpointResponse>> PrepareAsyncSetLoggingEndpoint(::grpc::ClientContext* context, const ::dmi::SetLoggingEndpointRequest& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::SetRemoteEndpointResponse>>(PrepareAsyncSetLoggingEndpointRaw(context, request, cq));
+    }
+    ::grpc::Status GetLoggingEndpoint(::grpc::ClientContext* context, const ::dmi::HardwareID& request, ::dmi::GetLoggingEndpointResponse* response) override;
+    std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::GetLoggingEndpointResponse>> AsyncGetLoggingEndpoint(::grpc::ClientContext* context, const ::dmi::HardwareID& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::GetLoggingEndpointResponse>>(AsyncGetLoggingEndpointRaw(context, request, cq));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::GetLoggingEndpointResponse>> PrepareAsyncGetLoggingEndpoint(::grpc::ClientContext* context, const ::dmi::HardwareID& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::GetLoggingEndpointResponse>>(PrepareAsyncGetLoggingEndpointRaw(context, request, cq));
+    }
+    ::grpc::Status SetMsgBusEndpoint(::grpc::ClientContext* context, const ::dmi::SetMsgBusEndpointRequest& request, ::dmi::SetRemoteEndpointResponse* response) override;
+    std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::SetRemoteEndpointResponse>> AsyncSetMsgBusEndpoint(::grpc::ClientContext* context, const ::dmi::SetMsgBusEndpointRequest& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::SetRemoteEndpointResponse>>(AsyncSetMsgBusEndpointRaw(context, request, cq));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::SetRemoteEndpointResponse>> PrepareAsyncSetMsgBusEndpoint(::grpc::ClientContext* context, const ::dmi::SetMsgBusEndpointRequest& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::SetRemoteEndpointResponse>>(PrepareAsyncSetMsgBusEndpointRaw(context, request, cq));
+    }
+    ::grpc::Status GetMsgBusEndpoint(::grpc::ClientContext* context, const ::google::protobuf::Empty& request, ::dmi::GetMsgBusEndpointResponse* response) override;
+    std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::GetMsgBusEndpointResponse>> AsyncGetMsgBusEndpoint(::grpc::ClientContext* context, const ::google::protobuf::Empty& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::GetMsgBusEndpointResponse>>(AsyncGetMsgBusEndpointRaw(context, request, cq));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::GetMsgBusEndpointResponse>> PrepareAsyncGetMsgBusEndpoint(::grpc::ClientContext* context, const ::google::protobuf::Empty& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::GetMsgBusEndpointResponse>>(PrepareAsyncGetMsgBusEndpointRaw(context, request, cq));
+    }
+    ::grpc::Status GetLoggableEntities(::grpc::ClientContext* context, const ::dmi::GetLoggableEntitiesRequest& request, ::dmi::GetLogLevelResponse* response) override;
+    std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::GetLogLevelResponse>> AsyncGetLoggableEntities(::grpc::ClientContext* context, const ::dmi::GetLoggableEntitiesRequest& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::GetLogLevelResponse>>(AsyncGetLoggableEntitiesRaw(context, request, cq));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::GetLogLevelResponse>> PrepareAsyncGetLoggableEntities(::grpc::ClientContext* context, const ::dmi::GetLoggableEntitiesRequest& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::GetLogLevelResponse>>(PrepareAsyncGetLoggableEntitiesRaw(context, request, cq));
+    }
+    ::grpc::Status SetLogLevel(::grpc::ClientContext* context, const ::dmi::SetLogLevelRequest& request, ::dmi::SetLogLevelResponse* response) override;
+    std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::SetLogLevelResponse>> AsyncSetLogLevel(::grpc::ClientContext* context, const ::dmi::SetLogLevelRequest& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::SetLogLevelResponse>>(AsyncSetLogLevelRaw(context, request, cq));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::SetLogLevelResponse>> PrepareAsyncSetLogLevel(::grpc::ClientContext* context, const ::dmi::SetLogLevelRequest& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::SetLogLevelResponse>>(PrepareAsyncSetLogLevelRaw(context, request, cq));
+    }
+    ::grpc::Status GetLogLevel(::grpc::ClientContext* context, const ::dmi::GetLogLevelRequest& request, ::dmi::GetLogLevelResponse* response) override;
+    std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::GetLogLevelResponse>> AsyncGetLogLevel(::grpc::ClientContext* context, const ::dmi::GetLogLevelRequest& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::GetLogLevelResponse>>(AsyncGetLogLevelRaw(context, request, cq));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::GetLogLevelResponse>> PrepareAsyncGetLogLevel(::grpc::ClientContext* context, const ::dmi::GetLogLevelRequest& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::GetLogLevelResponse>>(PrepareAsyncGetLogLevelRaw(context, request, cq));
+    }
+    class experimental_async final :
+      public StubInterface::experimental_async_interface {
+     public:
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      void StartManagingDevice(::grpc::ClientContext* context, ::dmi::ModifiableComponent* request, ::grpc::ClientReadReactor< ::dmi::StartManagingDeviceResponse>* reactor) override;
+      #else
+      void StartManagingDevice(::grpc::ClientContext* context, ::dmi::ModifiableComponent* request, ::grpc::experimental::ClientReadReactor< ::dmi::StartManagingDeviceResponse>* reactor) override;
+      #endif
+      void StopManagingDevice(::grpc::ClientContext* context, const ::dmi::StopManagingDeviceRequest* request, ::dmi::StopManagingDeviceResponse* response, std::function<void(::grpc::Status)>) override;
+      void StopManagingDevice(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::StopManagingDeviceResponse* response, std::function<void(::grpc::Status)>) override;
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      void StopManagingDevice(::grpc::ClientContext* context, const ::dmi::StopManagingDeviceRequest* request, ::dmi::StopManagingDeviceResponse* response, ::grpc::ClientUnaryReactor* reactor) override;
+      #else
+      void StopManagingDevice(::grpc::ClientContext* context, const ::dmi::StopManagingDeviceRequest* request, ::dmi::StopManagingDeviceResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) override;
+      #endif
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      void StopManagingDevice(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::StopManagingDeviceResponse* response, ::grpc::ClientUnaryReactor* reactor) override;
+      #else
+      void StopManagingDevice(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::StopManagingDeviceResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) override;
+      #endif
+      void GetManagedDevices(::grpc::ClientContext* context, const ::google::protobuf::Empty* request, ::dmi::ManagedDevicesResponse* response, std::function<void(::grpc::Status)>) override;
+      void GetManagedDevices(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::ManagedDevicesResponse* response, std::function<void(::grpc::Status)>) override;
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      void GetManagedDevices(::grpc::ClientContext* context, const ::google::protobuf::Empty* request, ::dmi::ManagedDevicesResponse* response, ::grpc::ClientUnaryReactor* reactor) override;
+      #else
+      void GetManagedDevices(::grpc::ClientContext* context, const ::google::protobuf::Empty* request, ::dmi::ManagedDevicesResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) override;
+      #endif
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      void GetManagedDevices(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::ManagedDevicesResponse* response, ::grpc::ClientUnaryReactor* reactor) override;
+      #else
+      void GetManagedDevices(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::ManagedDevicesResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) override;
+      #endif
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      void GetPhysicalInventory(::grpc::ClientContext* context, ::dmi::PhysicalInventoryRequest* request, ::grpc::ClientReadReactor< ::dmi::PhysicalInventoryResponse>* reactor) override;
+      #else
+      void GetPhysicalInventory(::grpc::ClientContext* context, ::dmi::PhysicalInventoryRequest* request, ::grpc::experimental::ClientReadReactor< ::dmi::PhysicalInventoryResponse>* reactor) override;
+      #endif
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      void GetHWComponentInfo(::grpc::ClientContext* context, ::dmi::HWComponentInfoGetRequest* request, ::grpc::ClientReadReactor< ::dmi::HWComponentInfoGetResponse>* reactor) override;
+      #else
+      void GetHWComponentInfo(::grpc::ClientContext* context, ::dmi::HWComponentInfoGetRequest* request, ::grpc::experimental::ClientReadReactor< ::dmi::HWComponentInfoGetResponse>* reactor) override;
+      #endif
+      void SetHWComponentInfo(::grpc::ClientContext* context, const ::dmi::HWComponentInfoSetRequest* request, ::dmi::HWComponentInfoSetResponse* response, std::function<void(::grpc::Status)>) override;
+      void SetHWComponentInfo(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::HWComponentInfoSetResponse* response, std::function<void(::grpc::Status)>) override;
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      void SetHWComponentInfo(::grpc::ClientContext* context, const ::dmi::HWComponentInfoSetRequest* request, ::dmi::HWComponentInfoSetResponse* response, ::grpc::ClientUnaryReactor* reactor) override;
+      #else
+      void SetHWComponentInfo(::grpc::ClientContext* context, const ::dmi::HWComponentInfoSetRequest* request, ::dmi::HWComponentInfoSetResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) override;
+      #endif
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      void SetHWComponentInfo(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::HWComponentInfoSetResponse* response, ::grpc::ClientUnaryReactor* reactor) override;
+      #else
+      void SetHWComponentInfo(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::HWComponentInfoSetResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) override;
+      #endif
+      void SetLoggingEndpoint(::grpc::ClientContext* context, const ::dmi::SetLoggingEndpointRequest* request, ::dmi::SetRemoteEndpointResponse* response, std::function<void(::grpc::Status)>) override;
+      void SetLoggingEndpoint(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::SetRemoteEndpointResponse* response, std::function<void(::grpc::Status)>) override;
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      void SetLoggingEndpoint(::grpc::ClientContext* context, const ::dmi::SetLoggingEndpointRequest* request, ::dmi::SetRemoteEndpointResponse* response, ::grpc::ClientUnaryReactor* reactor) override;
+      #else
+      void SetLoggingEndpoint(::grpc::ClientContext* context, const ::dmi::SetLoggingEndpointRequest* request, ::dmi::SetRemoteEndpointResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) override;
+      #endif
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      void SetLoggingEndpoint(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::SetRemoteEndpointResponse* response, ::grpc::ClientUnaryReactor* reactor) override;
+      #else
+      void SetLoggingEndpoint(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::SetRemoteEndpointResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) override;
+      #endif
+      void GetLoggingEndpoint(::grpc::ClientContext* context, const ::dmi::HardwareID* request, ::dmi::GetLoggingEndpointResponse* response, std::function<void(::grpc::Status)>) override;
+      void GetLoggingEndpoint(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::GetLoggingEndpointResponse* response, std::function<void(::grpc::Status)>) override;
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      void GetLoggingEndpoint(::grpc::ClientContext* context, const ::dmi::HardwareID* request, ::dmi::GetLoggingEndpointResponse* response, ::grpc::ClientUnaryReactor* reactor) override;
+      #else
+      void GetLoggingEndpoint(::grpc::ClientContext* context, const ::dmi::HardwareID* request, ::dmi::GetLoggingEndpointResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) override;
+      #endif
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      void GetLoggingEndpoint(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::GetLoggingEndpointResponse* response, ::grpc::ClientUnaryReactor* reactor) override;
+      #else
+      void GetLoggingEndpoint(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::GetLoggingEndpointResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) override;
+      #endif
+      void SetMsgBusEndpoint(::grpc::ClientContext* context, const ::dmi::SetMsgBusEndpointRequest* request, ::dmi::SetRemoteEndpointResponse* response, std::function<void(::grpc::Status)>) override;
+      void SetMsgBusEndpoint(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::SetRemoteEndpointResponse* response, std::function<void(::grpc::Status)>) override;
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      void SetMsgBusEndpoint(::grpc::ClientContext* context, const ::dmi::SetMsgBusEndpointRequest* request, ::dmi::SetRemoteEndpointResponse* response, ::grpc::ClientUnaryReactor* reactor) override;
+      #else
+      void SetMsgBusEndpoint(::grpc::ClientContext* context, const ::dmi::SetMsgBusEndpointRequest* request, ::dmi::SetRemoteEndpointResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) override;
+      #endif
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      void SetMsgBusEndpoint(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::SetRemoteEndpointResponse* response, ::grpc::ClientUnaryReactor* reactor) override;
+      #else
+      void SetMsgBusEndpoint(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::SetRemoteEndpointResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) override;
+      #endif
+      void GetMsgBusEndpoint(::grpc::ClientContext* context, const ::google::protobuf::Empty* request, ::dmi::GetMsgBusEndpointResponse* response, std::function<void(::grpc::Status)>) override;
+      void GetMsgBusEndpoint(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::GetMsgBusEndpointResponse* response, std::function<void(::grpc::Status)>) override;
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      void GetMsgBusEndpoint(::grpc::ClientContext* context, const ::google::protobuf::Empty* request, ::dmi::GetMsgBusEndpointResponse* response, ::grpc::ClientUnaryReactor* reactor) override;
+      #else
+      void GetMsgBusEndpoint(::grpc::ClientContext* context, const ::google::protobuf::Empty* request, ::dmi::GetMsgBusEndpointResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) override;
+      #endif
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      void GetMsgBusEndpoint(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::GetMsgBusEndpointResponse* response, ::grpc::ClientUnaryReactor* reactor) override;
+      #else
+      void GetMsgBusEndpoint(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::GetMsgBusEndpointResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) override;
+      #endif
+      void GetLoggableEntities(::grpc::ClientContext* context, const ::dmi::GetLoggableEntitiesRequest* request, ::dmi::GetLogLevelResponse* response, std::function<void(::grpc::Status)>) override;
+      void GetLoggableEntities(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::GetLogLevelResponse* response, std::function<void(::grpc::Status)>) override;
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      void GetLoggableEntities(::grpc::ClientContext* context, const ::dmi::GetLoggableEntitiesRequest* request, ::dmi::GetLogLevelResponse* response, ::grpc::ClientUnaryReactor* reactor) override;
+      #else
+      void GetLoggableEntities(::grpc::ClientContext* context, const ::dmi::GetLoggableEntitiesRequest* request, ::dmi::GetLogLevelResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) override;
+      #endif
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      void GetLoggableEntities(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::GetLogLevelResponse* response, ::grpc::ClientUnaryReactor* reactor) override;
+      #else
+      void GetLoggableEntities(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::GetLogLevelResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) override;
+      #endif
+      void SetLogLevel(::grpc::ClientContext* context, const ::dmi::SetLogLevelRequest* request, ::dmi::SetLogLevelResponse* response, std::function<void(::grpc::Status)>) override;
+      void SetLogLevel(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::SetLogLevelResponse* response, std::function<void(::grpc::Status)>) override;
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      void SetLogLevel(::grpc::ClientContext* context, const ::dmi::SetLogLevelRequest* request, ::dmi::SetLogLevelResponse* response, ::grpc::ClientUnaryReactor* reactor) override;
+      #else
+      void SetLogLevel(::grpc::ClientContext* context, const ::dmi::SetLogLevelRequest* request, ::dmi::SetLogLevelResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) override;
+      #endif
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      void SetLogLevel(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::SetLogLevelResponse* response, ::grpc::ClientUnaryReactor* reactor) override;
+      #else
+      void SetLogLevel(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::SetLogLevelResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) override;
+      #endif
+      void GetLogLevel(::grpc::ClientContext* context, const ::dmi::GetLogLevelRequest* request, ::dmi::GetLogLevelResponse* response, std::function<void(::grpc::Status)>) override;
+      void GetLogLevel(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::GetLogLevelResponse* response, std::function<void(::grpc::Status)>) override;
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      void GetLogLevel(::grpc::ClientContext* context, const ::dmi::GetLogLevelRequest* request, ::dmi::GetLogLevelResponse* response, ::grpc::ClientUnaryReactor* reactor) override;
+      #else
+      void GetLogLevel(::grpc::ClientContext* context, const ::dmi::GetLogLevelRequest* request, ::dmi::GetLogLevelResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) override;
+      #endif
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      void GetLogLevel(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::GetLogLevelResponse* response, ::grpc::ClientUnaryReactor* reactor) override;
+      #else
+      void GetLogLevel(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::GetLogLevelResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) override;
+      #endif
+     private:
+      friend class Stub;
+      explicit experimental_async(Stub* stub): stub_(stub) { }
+      Stub* stub() { return stub_; }
+      Stub* stub_;
+    };
+    class experimental_async_interface* experimental_async() override { return &async_stub_; }
+
+   private:
+    std::shared_ptr< ::grpc::ChannelInterface> channel_;
+    class experimental_async async_stub_{this};
+    ::grpc::ClientReader< ::dmi::StartManagingDeviceResponse>* StartManagingDeviceRaw(::grpc::ClientContext* context, const ::dmi::ModifiableComponent& request) override;
+    ::grpc::ClientAsyncReader< ::dmi::StartManagingDeviceResponse>* AsyncStartManagingDeviceRaw(::grpc::ClientContext* context, const ::dmi::ModifiableComponent& request, ::grpc::CompletionQueue* cq, void* tag) override;
+    ::grpc::ClientAsyncReader< ::dmi::StartManagingDeviceResponse>* PrepareAsyncStartManagingDeviceRaw(::grpc::ClientContext* context, const ::dmi::ModifiableComponent& request, ::grpc::CompletionQueue* cq) override;
+    ::grpc::ClientAsyncResponseReader< ::dmi::StopManagingDeviceResponse>* AsyncStopManagingDeviceRaw(::grpc::ClientContext* context, const ::dmi::StopManagingDeviceRequest& request, ::grpc::CompletionQueue* cq) override;
+    ::grpc::ClientAsyncResponseReader< ::dmi::StopManagingDeviceResponse>* PrepareAsyncStopManagingDeviceRaw(::grpc::ClientContext* context, const ::dmi::StopManagingDeviceRequest& request, ::grpc::CompletionQueue* cq) override;
+    ::grpc::ClientAsyncResponseReader< ::dmi::ManagedDevicesResponse>* AsyncGetManagedDevicesRaw(::grpc::ClientContext* context, const ::google::protobuf::Empty& request, ::grpc::CompletionQueue* cq) override;
+    ::grpc::ClientAsyncResponseReader< ::dmi::ManagedDevicesResponse>* PrepareAsyncGetManagedDevicesRaw(::grpc::ClientContext* context, const ::google::protobuf::Empty& request, ::grpc::CompletionQueue* cq) override;
+    ::grpc::ClientReader< ::dmi::PhysicalInventoryResponse>* GetPhysicalInventoryRaw(::grpc::ClientContext* context, const ::dmi::PhysicalInventoryRequest& request) override;
+    ::grpc::ClientAsyncReader< ::dmi::PhysicalInventoryResponse>* AsyncGetPhysicalInventoryRaw(::grpc::ClientContext* context, const ::dmi::PhysicalInventoryRequest& request, ::grpc::CompletionQueue* cq, void* tag) override;
+    ::grpc::ClientAsyncReader< ::dmi::PhysicalInventoryResponse>* PrepareAsyncGetPhysicalInventoryRaw(::grpc::ClientContext* context, const ::dmi::PhysicalInventoryRequest& request, ::grpc::CompletionQueue* cq) override;
+    ::grpc::ClientReader< ::dmi::HWComponentInfoGetResponse>* GetHWComponentInfoRaw(::grpc::ClientContext* context, const ::dmi::HWComponentInfoGetRequest& request) override;
+    ::grpc::ClientAsyncReader< ::dmi::HWComponentInfoGetResponse>* AsyncGetHWComponentInfoRaw(::grpc::ClientContext* context, const ::dmi::HWComponentInfoGetRequest& request, ::grpc::CompletionQueue* cq, void* tag) override;
+    ::grpc::ClientAsyncReader< ::dmi::HWComponentInfoGetResponse>* PrepareAsyncGetHWComponentInfoRaw(::grpc::ClientContext* context, const ::dmi::HWComponentInfoGetRequest& request, ::grpc::CompletionQueue* cq) override;
+    ::grpc::ClientAsyncResponseReader< ::dmi::HWComponentInfoSetResponse>* AsyncSetHWComponentInfoRaw(::grpc::ClientContext* context, const ::dmi::HWComponentInfoSetRequest& request, ::grpc::CompletionQueue* cq) override;
+    ::grpc::ClientAsyncResponseReader< ::dmi::HWComponentInfoSetResponse>* PrepareAsyncSetHWComponentInfoRaw(::grpc::ClientContext* context, const ::dmi::HWComponentInfoSetRequest& request, ::grpc::CompletionQueue* cq) override;
+    ::grpc::ClientAsyncResponseReader< ::dmi::SetRemoteEndpointResponse>* AsyncSetLoggingEndpointRaw(::grpc::ClientContext* context, const ::dmi::SetLoggingEndpointRequest& request, ::grpc::CompletionQueue* cq) override;
+    ::grpc::ClientAsyncResponseReader< ::dmi::SetRemoteEndpointResponse>* PrepareAsyncSetLoggingEndpointRaw(::grpc::ClientContext* context, const ::dmi::SetLoggingEndpointRequest& request, ::grpc::CompletionQueue* cq) override;
+    ::grpc::ClientAsyncResponseReader< ::dmi::GetLoggingEndpointResponse>* AsyncGetLoggingEndpointRaw(::grpc::ClientContext* context, const ::dmi::HardwareID& request, ::grpc::CompletionQueue* cq) override;
+    ::grpc::ClientAsyncResponseReader< ::dmi::GetLoggingEndpointResponse>* PrepareAsyncGetLoggingEndpointRaw(::grpc::ClientContext* context, const ::dmi::HardwareID& request, ::grpc::CompletionQueue* cq) override;
+    ::grpc::ClientAsyncResponseReader< ::dmi::SetRemoteEndpointResponse>* AsyncSetMsgBusEndpointRaw(::grpc::ClientContext* context, const ::dmi::SetMsgBusEndpointRequest& request, ::grpc::CompletionQueue* cq) override;
+    ::grpc::ClientAsyncResponseReader< ::dmi::SetRemoteEndpointResponse>* PrepareAsyncSetMsgBusEndpointRaw(::grpc::ClientContext* context, const ::dmi::SetMsgBusEndpointRequest& request, ::grpc::CompletionQueue* cq) override;
+    ::grpc::ClientAsyncResponseReader< ::dmi::GetMsgBusEndpointResponse>* AsyncGetMsgBusEndpointRaw(::grpc::ClientContext* context, const ::google::protobuf::Empty& request, ::grpc::CompletionQueue* cq) override;
+    ::grpc::ClientAsyncResponseReader< ::dmi::GetMsgBusEndpointResponse>* PrepareAsyncGetMsgBusEndpointRaw(::grpc::ClientContext* context, const ::google::protobuf::Empty& request, ::grpc::CompletionQueue* cq) override;
+    ::grpc::ClientAsyncResponseReader< ::dmi::GetLogLevelResponse>* AsyncGetLoggableEntitiesRaw(::grpc::ClientContext* context, const ::dmi::GetLoggableEntitiesRequest& request, ::grpc::CompletionQueue* cq) override;
+    ::grpc::ClientAsyncResponseReader< ::dmi::GetLogLevelResponse>* PrepareAsyncGetLoggableEntitiesRaw(::grpc::ClientContext* context, const ::dmi::GetLoggableEntitiesRequest& request, ::grpc::CompletionQueue* cq) override;
+    ::grpc::ClientAsyncResponseReader< ::dmi::SetLogLevelResponse>* AsyncSetLogLevelRaw(::grpc::ClientContext* context, const ::dmi::SetLogLevelRequest& request, ::grpc::CompletionQueue* cq) override;
+    ::grpc::ClientAsyncResponseReader< ::dmi::SetLogLevelResponse>* PrepareAsyncSetLogLevelRaw(::grpc::ClientContext* context, const ::dmi::SetLogLevelRequest& request, ::grpc::CompletionQueue* cq) override;
+    ::grpc::ClientAsyncResponseReader< ::dmi::GetLogLevelResponse>* AsyncGetLogLevelRaw(::grpc::ClientContext* context, const ::dmi::GetLogLevelRequest& request, ::grpc::CompletionQueue* cq) override;
+    ::grpc::ClientAsyncResponseReader< ::dmi::GetLogLevelResponse>* PrepareAsyncGetLogLevelRaw(::grpc::ClientContext* context, const ::dmi::GetLogLevelRequest& request, ::grpc::CompletionQueue* cq) override;
+    const ::grpc::internal::RpcMethod rpcmethod_StartManagingDevice_;
+    const ::grpc::internal::RpcMethod rpcmethod_StopManagingDevice_;
+    const ::grpc::internal::RpcMethod rpcmethod_GetManagedDevices_;
+    const ::grpc::internal::RpcMethod rpcmethod_GetPhysicalInventory_;
+    const ::grpc::internal::RpcMethod rpcmethod_GetHWComponentInfo_;
+    const ::grpc::internal::RpcMethod rpcmethod_SetHWComponentInfo_;
+    const ::grpc::internal::RpcMethod rpcmethod_SetLoggingEndpoint_;
+    const ::grpc::internal::RpcMethod rpcmethod_GetLoggingEndpoint_;
+    const ::grpc::internal::RpcMethod rpcmethod_SetMsgBusEndpoint_;
+    const ::grpc::internal::RpcMethod rpcmethod_GetMsgBusEndpoint_;
+    const ::grpc::internal::RpcMethod rpcmethod_GetLoggableEntities_;
+    const ::grpc::internal::RpcMethod rpcmethod_SetLogLevel_;
+    const ::grpc::internal::RpcMethod rpcmethod_GetLogLevel_;
+  };
+  static std::unique_ptr<Stub> NewStub(const std::shared_ptr< ::grpc::ChannelInterface>& channel, const ::grpc::StubOptions& options = ::grpc::StubOptions());
+
+  class Service : public ::grpc::Service {
+   public:
+    Service();
+    virtual ~Service();
+    // Initializes context for a device and sets up required states
+    // In the call to StartManagingDevice, the fields of ModifiableComponent which are relevant
+    // and their meanings in this context is mentioned below:
+    // name = The unique name that needs to be assigned to this hardware;
+    // class = COMPONENT_TYPE_UNDEFINED;
+    // parent = nil;
+    // alias = Optional;
+    // asset_id = Optional;
+    // uri = IP Address of the Hardware;
+    virtual ::grpc::Status StartManagingDevice(::grpc::ServerContext* context, const ::dmi::ModifiableComponent* request, ::grpc::ServerWriter< ::dmi::StartManagingDeviceResponse>* writer);
+    // Stop management of a device and clean up any context and caches for that device
+    // This rpc can be called at any time, even before the StartManagingDevice operation
+    // has completed, and should be able to cleanup.
+    virtual ::grpc::Status StopManagingDevice(::grpc::ServerContext* context, const ::dmi::StopManagingDeviceRequest* request, ::dmi::StopManagingDeviceResponse* response);
+    // Returns an object containing a list of devices managed by this entity
+    virtual ::grpc::Status GetManagedDevices(::grpc::ServerContext* context, const ::google::protobuf::Empty* request, ::dmi::ManagedDevicesResponse* response);
+    // Get the HW inventory details of the Device
+    virtual ::grpc::Status GetPhysicalInventory(::grpc::ServerContext* context, const ::dmi::PhysicalInventoryRequest* request, ::grpc::ServerWriter< ::dmi::PhysicalInventoryResponse>* writer);
+    // Get the details of a particular HW component
+    virtual ::grpc::Status GetHWComponentInfo(::grpc::ServerContext* context, const ::dmi::HWComponentInfoGetRequest* request, ::grpc::ServerWriter< ::dmi::HWComponentInfoGetResponse>* writer);
+    // Sets the permissible attributes of a HW component
+    virtual ::grpc::Status SetHWComponentInfo(::grpc::ServerContext* context, const ::dmi::HWComponentInfoSetRequest* request, ::dmi::HWComponentInfoSetResponse* response);
+    // Sets the location to which logs need to be shipped
+    virtual ::grpc::Status SetLoggingEndpoint(::grpc::ServerContext* context, const ::dmi::SetLoggingEndpointRequest* request, ::dmi::SetRemoteEndpointResponse* response);
+    // Gets the configured location to which the logs are being shipped
+    virtual ::grpc::Status GetLoggingEndpoint(::grpc::ServerContext* context, const ::dmi::HardwareID* request, ::dmi::GetLoggingEndpointResponse* response);
+    // Sets the location of the Message Bus to which events and metrics are shipped
+    virtual ::grpc::Status SetMsgBusEndpoint(::grpc::ServerContext* context, const ::dmi::SetMsgBusEndpointRequest* request, ::dmi::SetRemoteEndpointResponse* response);
+    // Gets the configured location to which the events and metrics are being shipped
+    virtual ::grpc::Status GetMsgBusEndpoint(::grpc::ServerContext* context, const ::google::protobuf::Empty* request, ::dmi::GetMsgBusEndpointResponse* response);
+    // Gets the entities of a device on which log can be configured. A few are expected, like OS, PON Management etc.
+    // In general an entity is any item within an hardware system that can emit logs, e.g. service, process, subsystem,
+    // interface, package etc.
+    virtual ::grpc::Status GetLoggableEntities(::grpc::ServerContext* context, const ::dmi::GetLoggableEntitiesRequest* request, ::dmi::GetLogLevelResponse* response);
+    // Sets the log level of the device, for each given entity to a certain level.
+    // If only one EntitiesLogLevel is provided for the device and that request contains only a log level with
+    // no entity in the list it's assumed that the caller wants to set that level for all the entities.
+    virtual ::grpc::Status SetLogLevel(::grpc::ServerContext* context, const ::dmi::SetLogLevelRequest* request, ::dmi::SetLogLevelResponse* response);
+    // Gets the configured log level for a certain entity on a certain device.
+    // If no entity is specified in the request all the entities with their log level should be returned.
+    virtual ::grpc::Status GetLogLevel(::grpc::ServerContext* context, const ::dmi::GetLogLevelRequest* request, ::dmi::GetLogLevelResponse* response);
+  };
+  template <class BaseClass>
+  class WithAsyncMethod_StartManagingDevice : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithAsyncMethod_StartManagingDevice() {
+      ::grpc::Service::MarkMethodAsync(0);
+    }
+    ~WithAsyncMethod_StartManagingDevice() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status StartManagingDevice(::grpc::ServerContext* /*context*/, const ::dmi::ModifiableComponent* /*request*/, ::grpc::ServerWriter< ::dmi::StartManagingDeviceResponse>* /*writer*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    void RequestStartManagingDevice(::grpc::ServerContext* context, ::dmi::ModifiableComponent* request, ::grpc::ServerAsyncWriter< ::dmi::StartManagingDeviceResponse>* writer, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+      ::grpc::Service::RequestAsyncServerStreaming(0, context, request, writer, new_call_cq, notification_cq, tag);
+    }
+  };
+  template <class BaseClass>
+  class WithAsyncMethod_StopManagingDevice : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithAsyncMethod_StopManagingDevice() {
+      ::grpc::Service::MarkMethodAsync(1);
+    }
+    ~WithAsyncMethod_StopManagingDevice() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status StopManagingDevice(::grpc::ServerContext* /*context*/, const ::dmi::StopManagingDeviceRequest* /*request*/, ::dmi::StopManagingDeviceResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    void RequestStopManagingDevice(::grpc::ServerContext* context, ::dmi::StopManagingDeviceRequest* request, ::grpc::ServerAsyncResponseWriter< ::dmi::StopManagingDeviceResponse>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+      ::grpc::Service::RequestAsyncUnary(1, context, request, response, new_call_cq, notification_cq, tag);
+    }
+  };
+  template <class BaseClass>
+  class WithAsyncMethod_GetManagedDevices : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithAsyncMethod_GetManagedDevices() {
+      ::grpc::Service::MarkMethodAsync(2);
+    }
+    ~WithAsyncMethod_GetManagedDevices() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status GetManagedDevices(::grpc::ServerContext* /*context*/, const ::google::protobuf::Empty* /*request*/, ::dmi::ManagedDevicesResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    void RequestGetManagedDevices(::grpc::ServerContext* context, ::google::protobuf::Empty* request, ::grpc::ServerAsyncResponseWriter< ::dmi::ManagedDevicesResponse>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+      ::grpc::Service::RequestAsyncUnary(2, context, request, response, new_call_cq, notification_cq, tag);
+    }
+  };
+  template <class BaseClass>
+  class WithAsyncMethod_GetPhysicalInventory : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithAsyncMethod_GetPhysicalInventory() {
+      ::grpc::Service::MarkMethodAsync(3);
+    }
+    ~WithAsyncMethod_GetPhysicalInventory() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status GetPhysicalInventory(::grpc::ServerContext* /*context*/, const ::dmi::PhysicalInventoryRequest* /*request*/, ::grpc::ServerWriter< ::dmi::PhysicalInventoryResponse>* /*writer*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    void RequestGetPhysicalInventory(::grpc::ServerContext* context, ::dmi::PhysicalInventoryRequest* request, ::grpc::ServerAsyncWriter< ::dmi::PhysicalInventoryResponse>* writer, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+      ::grpc::Service::RequestAsyncServerStreaming(3, context, request, writer, new_call_cq, notification_cq, tag);
+    }
+  };
+  template <class BaseClass>
+  class WithAsyncMethod_GetHWComponentInfo : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithAsyncMethod_GetHWComponentInfo() {
+      ::grpc::Service::MarkMethodAsync(4);
+    }
+    ~WithAsyncMethod_GetHWComponentInfo() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status GetHWComponentInfo(::grpc::ServerContext* /*context*/, const ::dmi::HWComponentInfoGetRequest* /*request*/, ::grpc::ServerWriter< ::dmi::HWComponentInfoGetResponse>* /*writer*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    void RequestGetHWComponentInfo(::grpc::ServerContext* context, ::dmi::HWComponentInfoGetRequest* request, ::grpc::ServerAsyncWriter< ::dmi::HWComponentInfoGetResponse>* writer, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+      ::grpc::Service::RequestAsyncServerStreaming(4, context, request, writer, new_call_cq, notification_cq, tag);
+    }
+  };
+  template <class BaseClass>
+  class WithAsyncMethod_SetHWComponentInfo : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithAsyncMethod_SetHWComponentInfo() {
+      ::grpc::Service::MarkMethodAsync(5);
+    }
+    ~WithAsyncMethod_SetHWComponentInfo() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status SetHWComponentInfo(::grpc::ServerContext* /*context*/, const ::dmi::HWComponentInfoSetRequest* /*request*/, ::dmi::HWComponentInfoSetResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    void RequestSetHWComponentInfo(::grpc::ServerContext* context, ::dmi::HWComponentInfoSetRequest* request, ::grpc::ServerAsyncResponseWriter< ::dmi::HWComponentInfoSetResponse>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+      ::grpc::Service::RequestAsyncUnary(5, context, request, response, new_call_cq, notification_cq, tag);
+    }
+  };
+  template <class BaseClass>
+  class WithAsyncMethod_SetLoggingEndpoint : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithAsyncMethod_SetLoggingEndpoint() {
+      ::grpc::Service::MarkMethodAsync(6);
+    }
+    ~WithAsyncMethod_SetLoggingEndpoint() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status SetLoggingEndpoint(::grpc::ServerContext* /*context*/, const ::dmi::SetLoggingEndpointRequest* /*request*/, ::dmi::SetRemoteEndpointResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    void RequestSetLoggingEndpoint(::grpc::ServerContext* context, ::dmi::SetLoggingEndpointRequest* request, ::grpc::ServerAsyncResponseWriter< ::dmi::SetRemoteEndpointResponse>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+      ::grpc::Service::RequestAsyncUnary(6, context, request, response, new_call_cq, notification_cq, tag);
+    }
+  };
+  template <class BaseClass>
+  class WithAsyncMethod_GetLoggingEndpoint : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithAsyncMethod_GetLoggingEndpoint() {
+      ::grpc::Service::MarkMethodAsync(7);
+    }
+    ~WithAsyncMethod_GetLoggingEndpoint() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status GetLoggingEndpoint(::grpc::ServerContext* /*context*/, const ::dmi::HardwareID* /*request*/, ::dmi::GetLoggingEndpointResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    void RequestGetLoggingEndpoint(::grpc::ServerContext* context, ::dmi::HardwareID* request, ::grpc::ServerAsyncResponseWriter< ::dmi::GetLoggingEndpointResponse>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+      ::grpc::Service::RequestAsyncUnary(7, context, request, response, new_call_cq, notification_cq, tag);
+    }
+  };
+  template <class BaseClass>
+  class WithAsyncMethod_SetMsgBusEndpoint : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithAsyncMethod_SetMsgBusEndpoint() {
+      ::grpc::Service::MarkMethodAsync(8);
+    }
+    ~WithAsyncMethod_SetMsgBusEndpoint() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status SetMsgBusEndpoint(::grpc::ServerContext* /*context*/, const ::dmi::SetMsgBusEndpointRequest* /*request*/, ::dmi::SetRemoteEndpointResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    void RequestSetMsgBusEndpoint(::grpc::ServerContext* context, ::dmi::SetMsgBusEndpointRequest* request, ::grpc::ServerAsyncResponseWriter< ::dmi::SetRemoteEndpointResponse>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+      ::grpc::Service::RequestAsyncUnary(8, context, request, response, new_call_cq, notification_cq, tag);
+    }
+  };
+  template <class BaseClass>
+  class WithAsyncMethod_GetMsgBusEndpoint : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithAsyncMethod_GetMsgBusEndpoint() {
+      ::grpc::Service::MarkMethodAsync(9);
+    }
+    ~WithAsyncMethod_GetMsgBusEndpoint() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status GetMsgBusEndpoint(::grpc::ServerContext* /*context*/, const ::google::protobuf::Empty* /*request*/, ::dmi::GetMsgBusEndpointResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    void RequestGetMsgBusEndpoint(::grpc::ServerContext* context, ::google::protobuf::Empty* request, ::grpc::ServerAsyncResponseWriter< ::dmi::GetMsgBusEndpointResponse>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+      ::grpc::Service::RequestAsyncUnary(9, context, request, response, new_call_cq, notification_cq, tag);
+    }
+  };
+  template <class BaseClass>
+  class WithAsyncMethod_GetLoggableEntities : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithAsyncMethod_GetLoggableEntities() {
+      ::grpc::Service::MarkMethodAsync(10);
+    }
+    ~WithAsyncMethod_GetLoggableEntities() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status GetLoggableEntities(::grpc::ServerContext* /*context*/, const ::dmi::GetLoggableEntitiesRequest* /*request*/, ::dmi::GetLogLevelResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    void RequestGetLoggableEntities(::grpc::ServerContext* context, ::dmi::GetLoggableEntitiesRequest* request, ::grpc::ServerAsyncResponseWriter< ::dmi::GetLogLevelResponse>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+      ::grpc::Service::RequestAsyncUnary(10, context, request, response, new_call_cq, notification_cq, tag);
+    }
+  };
+  template <class BaseClass>
+  class WithAsyncMethod_SetLogLevel : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithAsyncMethod_SetLogLevel() {
+      ::grpc::Service::MarkMethodAsync(11);
+    }
+    ~WithAsyncMethod_SetLogLevel() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status SetLogLevel(::grpc::ServerContext* /*context*/, const ::dmi::SetLogLevelRequest* /*request*/, ::dmi::SetLogLevelResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    void RequestSetLogLevel(::grpc::ServerContext* context, ::dmi::SetLogLevelRequest* request, ::grpc::ServerAsyncResponseWriter< ::dmi::SetLogLevelResponse>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+      ::grpc::Service::RequestAsyncUnary(11, context, request, response, new_call_cq, notification_cq, tag);
+    }
+  };
+  template <class BaseClass>
+  class WithAsyncMethod_GetLogLevel : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithAsyncMethod_GetLogLevel() {
+      ::grpc::Service::MarkMethodAsync(12);
+    }
+    ~WithAsyncMethod_GetLogLevel() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status GetLogLevel(::grpc::ServerContext* /*context*/, const ::dmi::GetLogLevelRequest* /*request*/, ::dmi::GetLogLevelResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    void RequestGetLogLevel(::grpc::ServerContext* context, ::dmi::GetLogLevelRequest* request, ::grpc::ServerAsyncResponseWriter< ::dmi::GetLogLevelResponse>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+      ::grpc::Service::RequestAsyncUnary(12, context, request, response, new_call_cq, notification_cq, tag);
+    }
+  };
+  typedef WithAsyncMethod_StartManagingDevice<WithAsyncMethod_StopManagingDevice<WithAsyncMethod_GetManagedDevices<WithAsyncMethod_GetPhysicalInventory<WithAsyncMethod_GetHWComponentInfo<WithAsyncMethod_SetHWComponentInfo<WithAsyncMethod_SetLoggingEndpoint<WithAsyncMethod_GetLoggingEndpoint<WithAsyncMethod_SetMsgBusEndpoint<WithAsyncMethod_GetMsgBusEndpoint<WithAsyncMethod_GetLoggableEntities<WithAsyncMethod_SetLogLevel<WithAsyncMethod_GetLogLevel<Service > > > > > > > > > > > > > AsyncService;
+  template <class BaseClass>
+  class ExperimentalWithCallbackMethod_StartManagingDevice : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    ExperimentalWithCallbackMethod_StartManagingDevice() {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::Service::
+    #else
+      ::grpc::Service::experimental().
+    #endif
+        MarkMethodCallback(0,
+          new ::grpc_impl::internal::CallbackServerStreamingHandler< ::dmi::ModifiableComponent, ::dmi::StartManagingDeviceResponse>(
+            [this](
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+                   ::grpc::CallbackServerContext*
+    #else
+                   ::grpc::experimental::CallbackServerContext*
+    #endif
+                     context, const ::dmi::ModifiableComponent* request) { return this->StartManagingDevice(context, request); }));
+    }
+    ~ExperimentalWithCallbackMethod_StartManagingDevice() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status StartManagingDevice(::grpc::ServerContext* /*context*/, const ::dmi::ModifiableComponent* /*request*/, ::grpc::ServerWriter< ::dmi::StartManagingDeviceResponse>* /*writer*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+    virtual ::grpc::ServerWriteReactor< ::dmi::StartManagingDeviceResponse>* StartManagingDevice(
+      ::grpc::CallbackServerContext* /*context*/, const ::dmi::ModifiableComponent* /*request*/)
+    #else
+    virtual ::grpc::experimental::ServerWriteReactor< ::dmi::StartManagingDeviceResponse>* StartManagingDevice(
+      ::grpc::experimental::CallbackServerContext* /*context*/, const ::dmi::ModifiableComponent* /*request*/)
+    #endif
+      { return nullptr; }
+  };
+  template <class BaseClass>
+  class ExperimentalWithCallbackMethod_StopManagingDevice : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    ExperimentalWithCallbackMethod_StopManagingDevice() {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::Service::
+    #else
+      ::grpc::Service::experimental().
+    #endif
+        MarkMethodCallback(1,
+          new ::grpc_impl::internal::CallbackUnaryHandler< ::dmi::StopManagingDeviceRequest, ::dmi::StopManagingDeviceResponse>(
+            [this](
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+                   ::grpc::CallbackServerContext*
+    #else
+                   ::grpc::experimental::CallbackServerContext*
+    #endif
+                     context, const ::dmi::StopManagingDeviceRequest* request, ::dmi::StopManagingDeviceResponse* response) { return this->StopManagingDevice(context, request, response); }));}
+    void SetMessageAllocatorFor_StopManagingDevice(
+        ::grpc::experimental::MessageAllocator< ::dmi::StopManagingDeviceRequest, ::dmi::StopManagingDeviceResponse>* allocator) {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(1);
+    #else
+      ::grpc::internal::MethodHandler* const handler = ::grpc::Service::experimental().GetHandler(1);
+    #endif
+      static_cast<::grpc_impl::internal::CallbackUnaryHandler< ::dmi::StopManagingDeviceRequest, ::dmi::StopManagingDeviceResponse>*>(handler)
+              ->SetMessageAllocator(allocator);
+    }
+    ~ExperimentalWithCallbackMethod_StopManagingDevice() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status StopManagingDevice(::grpc::ServerContext* /*context*/, const ::dmi::StopManagingDeviceRequest* /*request*/, ::dmi::StopManagingDeviceResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+    virtual ::grpc::ServerUnaryReactor* StopManagingDevice(
+      ::grpc::CallbackServerContext* /*context*/, const ::dmi::StopManagingDeviceRequest* /*request*/, ::dmi::StopManagingDeviceResponse* /*response*/)
+    #else
+    virtual ::grpc::experimental::ServerUnaryReactor* StopManagingDevice(
+      ::grpc::experimental::CallbackServerContext* /*context*/, const ::dmi::StopManagingDeviceRequest* /*request*/, ::dmi::StopManagingDeviceResponse* /*response*/)
+    #endif
+      { return nullptr; }
+  };
+  template <class BaseClass>
+  class ExperimentalWithCallbackMethod_GetManagedDevices : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    ExperimentalWithCallbackMethod_GetManagedDevices() {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::Service::
+    #else
+      ::grpc::Service::experimental().
+    #endif
+        MarkMethodCallback(2,
+          new ::grpc_impl::internal::CallbackUnaryHandler< ::google::protobuf::Empty, ::dmi::ManagedDevicesResponse>(
+            [this](
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+                   ::grpc::CallbackServerContext*
+    #else
+                   ::grpc::experimental::CallbackServerContext*
+    #endif
+                     context, const ::google::protobuf::Empty* request, ::dmi::ManagedDevicesResponse* response) { return this->GetManagedDevices(context, request, response); }));}
+    void SetMessageAllocatorFor_GetManagedDevices(
+        ::grpc::experimental::MessageAllocator< ::google::protobuf::Empty, ::dmi::ManagedDevicesResponse>* allocator) {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(2);
+    #else
+      ::grpc::internal::MethodHandler* const handler = ::grpc::Service::experimental().GetHandler(2);
+    #endif
+      static_cast<::grpc_impl::internal::CallbackUnaryHandler< ::google::protobuf::Empty, ::dmi::ManagedDevicesResponse>*>(handler)
+              ->SetMessageAllocator(allocator);
+    }
+    ~ExperimentalWithCallbackMethod_GetManagedDevices() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status GetManagedDevices(::grpc::ServerContext* /*context*/, const ::google::protobuf::Empty* /*request*/, ::dmi::ManagedDevicesResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+    virtual ::grpc::ServerUnaryReactor* GetManagedDevices(
+      ::grpc::CallbackServerContext* /*context*/, const ::google::protobuf::Empty* /*request*/, ::dmi::ManagedDevicesResponse* /*response*/)
+    #else
+    virtual ::grpc::experimental::ServerUnaryReactor* GetManagedDevices(
+      ::grpc::experimental::CallbackServerContext* /*context*/, const ::google::protobuf::Empty* /*request*/, ::dmi::ManagedDevicesResponse* /*response*/)
+    #endif
+      { return nullptr; }
+  };
+  template <class BaseClass>
+  class ExperimentalWithCallbackMethod_GetPhysicalInventory : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    ExperimentalWithCallbackMethod_GetPhysicalInventory() {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::Service::
+    #else
+      ::grpc::Service::experimental().
+    #endif
+        MarkMethodCallback(3,
+          new ::grpc_impl::internal::CallbackServerStreamingHandler< ::dmi::PhysicalInventoryRequest, ::dmi::PhysicalInventoryResponse>(
+            [this](
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+                   ::grpc::CallbackServerContext*
+    #else
+                   ::grpc::experimental::CallbackServerContext*
+    #endif
+                     context, const ::dmi::PhysicalInventoryRequest* request) { return this->GetPhysicalInventory(context, request); }));
+    }
+    ~ExperimentalWithCallbackMethod_GetPhysicalInventory() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status GetPhysicalInventory(::grpc::ServerContext* /*context*/, const ::dmi::PhysicalInventoryRequest* /*request*/, ::grpc::ServerWriter< ::dmi::PhysicalInventoryResponse>* /*writer*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+    virtual ::grpc::ServerWriteReactor< ::dmi::PhysicalInventoryResponse>* GetPhysicalInventory(
+      ::grpc::CallbackServerContext* /*context*/, const ::dmi::PhysicalInventoryRequest* /*request*/)
+    #else
+    virtual ::grpc::experimental::ServerWriteReactor< ::dmi::PhysicalInventoryResponse>* GetPhysicalInventory(
+      ::grpc::experimental::CallbackServerContext* /*context*/, const ::dmi::PhysicalInventoryRequest* /*request*/)
+    #endif
+      { return nullptr; }
+  };
+  template <class BaseClass>
+  class ExperimentalWithCallbackMethod_GetHWComponentInfo : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    ExperimentalWithCallbackMethod_GetHWComponentInfo() {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::Service::
+    #else
+      ::grpc::Service::experimental().
+    #endif
+        MarkMethodCallback(4,
+          new ::grpc_impl::internal::CallbackServerStreamingHandler< ::dmi::HWComponentInfoGetRequest, ::dmi::HWComponentInfoGetResponse>(
+            [this](
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+                   ::grpc::CallbackServerContext*
+    #else
+                   ::grpc::experimental::CallbackServerContext*
+    #endif
+                     context, const ::dmi::HWComponentInfoGetRequest* request) { return this->GetHWComponentInfo(context, request); }));
+    }
+    ~ExperimentalWithCallbackMethod_GetHWComponentInfo() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status GetHWComponentInfo(::grpc::ServerContext* /*context*/, const ::dmi::HWComponentInfoGetRequest* /*request*/, ::grpc::ServerWriter< ::dmi::HWComponentInfoGetResponse>* /*writer*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+    virtual ::grpc::ServerWriteReactor< ::dmi::HWComponentInfoGetResponse>* GetHWComponentInfo(
+      ::grpc::CallbackServerContext* /*context*/, const ::dmi::HWComponentInfoGetRequest* /*request*/)
+    #else
+    virtual ::grpc::experimental::ServerWriteReactor< ::dmi::HWComponentInfoGetResponse>* GetHWComponentInfo(
+      ::grpc::experimental::CallbackServerContext* /*context*/, const ::dmi::HWComponentInfoGetRequest* /*request*/)
+    #endif
+      { return nullptr; }
+  };
+  template <class BaseClass>
+  class ExperimentalWithCallbackMethod_SetHWComponentInfo : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    ExperimentalWithCallbackMethod_SetHWComponentInfo() {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::Service::
+    #else
+      ::grpc::Service::experimental().
+    #endif
+        MarkMethodCallback(5,
+          new ::grpc_impl::internal::CallbackUnaryHandler< ::dmi::HWComponentInfoSetRequest, ::dmi::HWComponentInfoSetResponse>(
+            [this](
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+                   ::grpc::CallbackServerContext*
+    #else
+                   ::grpc::experimental::CallbackServerContext*
+    #endif
+                     context, const ::dmi::HWComponentInfoSetRequest* request, ::dmi::HWComponentInfoSetResponse* response) { return this->SetHWComponentInfo(context, request, response); }));}
+    void SetMessageAllocatorFor_SetHWComponentInfo(
+        ::grpc::experimental::MessageAllocator< ::dmi::HWComponentInfoSetRequest, ::dmi::HWComponentInfoSetResponse>* allocator) {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(5);
+    #else
+      ::grpc::internal::MethodHandler* const handler = ::grpc::Service::experimental().GetHandler(5);
+    #endif
+      static_cast<::grpc_impl::internal::CallbackUnaryHandler< ::dmi::HWComponentInfoSetRequest, ::dmi::HWComponentInfoSetResponse>*>(handler)
+              ->SetMessageAllocator(allocator);
+    }
+    ~ExperimentalWithCallbackMethod_SetHWComponentInfo() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status SetHWComponentInfo(::grpc::ServerContext* /*context*/, const ::dmi::HWComponentInfoSetRequest* /*request*/, ::dmi::HWComponentInfoSetResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+    virtual ::grpc::ServerUnaryReactor* SetHWComponentInfo(
+      ::grpc::CallbackServerContext* /*context*/, const ::dmi::HWComponentInfoSetRequest* /*request*/, ::dmi::HWComponentInfoSetResponse* /*response*/)
+    #else
+    virtual ::grpc::experimental::ServerUnaryReactor* SetHWComponentInfo(
+      ::grpc::experimental::CallbackServerContext* /*context*/, const ::dmi::HWComponentInfoSetRequest* /*request*/, ::dmi::HWComponentInfoSetResponse* /*response*/)
+    #endif
+      { return nullptr; }
+  };
+  template <class BaseClass>
+  class ExperimentalWithCallbackMethod_SetLoggingEndpoint : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    ExperimentalWithCallbackMethod_SetLoggingEndpoint() {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::Service::
+    #else
+      ::grpc::Service::experimental().
+    #endif
+        MarkMethodCallback(6,
+          new ::grpc_impl::internal::CallbackUnaryHandler< ::dmi::SetLoggingEndpointRequest, ::dmi::SetRemoteEndpointResponse>(
+            [this](
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+                   ::grpc::CallbackServerContext*
+    #else
+                   ::grpc::experimental::CallbackServerContext*
+    #endif
+                     context, const ::dmi::SetLoggingEndpointRequest* request, ::dmi::SetRemoteEndpointResponse* response) { return this->SetLoggingEndpoint(context, request, response); }));}
+    void SetMessageAllocatorFor_SetLoggingEndpoint(
+        ::grpc::experimental::MessageAllocator< ::dmi::SetLoggingEndpointRequest, ::dmi::SetRemoteEndpointResponse>* allocator) {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(6);
+    #else
+      ::grpc::internal::MethodHandler* const handler = ::grpc::Service::experimental().GetHandler(6);
+    #endif
+      static_cast<::grpc_impl::internal::CallbackUnaryHandler< ::dmi::SetLoggingEndpointRequest, ::dmi::SetRemoteEndpointResponse>*>(handler)
+              ->SetMessageAllocator(allocator);
+    }
+    ~ExperimentalWithCallbackMethod_SetLoggingEndpoint() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status SetLoggingEndpoint(::grpc::ServerContext* /*context*/, const ::dmi::SetLoggingEndpointRequest* /*request*/, ::dmi::SetRemoteEndpointResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+    virtual ::grpc::ServerUnaryReactor* SetLoggingEndpoint(
+      ::grpc::CallbackServerContext* /*context*/, const ::dmi::SetLoggingEndpointRequest* /*request*/, ::dmi::SetRemoteEndpointResponse* /*response*/)
+    #else
+    virtual ::grpc::experimental::ServerUnaryReactor* SetLoggingEndpoint(
+      ::grpc::experimental::CallbackServerContext* /*context*/, const ::dmi::SetLoggingEndpointRequest* /*request*/, ::dmi::SetRemoteEndpointResponse* /*response*/)
+    #endif
+      { return nullptr; }
+  };
+  template <class BaseClass>
+  class ExperimentalWithCallbackMethod_GetLoggingEndpoint : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    ExperimentalWithCallbackMethod_GetLoggingEndpoint() {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::Service::
+    #else
+      ::grpc::Service::experimental().
+    #endif
+        MarkMethodCallback(7,
+          new ::grpc_impl::internal::CallbackUnaryHandler< ::dmi::HardwareID, ::dmi::GetLoggingEndpointResponse>(
+            [this](
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+                   ::grpc::CallbackServerContext*
+    #else
+                   ::grpc::experimental::CallbackServerContext*
+    #endif
+                     context, const ::dmi::HardwareID* request, ::dmi::GetLoggingEndpointResponse* response) { return this->GetLoggingEndpoint(context, request, response); }));}
+    void SetMessageAllocatorFor_GetLoggingEndpoint(
+        ::grpc::experimental::MessageAllocator< ::dmi::HardwareID, ::dmi::GetLoggingEndpointResponse>* allocator) {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(7);
+    #else
+      ::grpc::internal::MethodHandler* const handler = ::grpc::Service::experimental().GetHandler(7);
+    #endif
+      static_cast<::grpc_impl::internal::CallbackUnaryHandler< ::dmi::HardwareID, ::dmi::GetLoggingEndpointResponse>*>(handler)
+              ->SetMessageAllocator(allocator);
+    }
+    ~ExperimentalWithCallbackMethod_GetLoggingEndpoint() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status GetLoggingEndpoint(::grpc::ServerContext* /*context*/, const ::dmi::HardwareID* /*request*/, ::dmi::GetLoggingEndpointResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+    virtual ::grpc::ServerUnaryReactor* GetLoggingEndpoint(
+      ::grpc::CallbackServerContext* /*context*/, const ::dmi::HardwareID* /*request*/, ::dmi::GetLoggingEndpointResponse* /*response*/)
+    #else
+    virtual ::grpc::experimental::ServerUnaryReactor* GetLoggingEndpoint(
+      ::grpc::experimental::CallbackServerContext* /*context*/, const ::dmi::HardwareID* /*request*/, ::dmi::GetLoggingEndpointResponse* /*response*/)
+    #endif
+      { return nullptr; }
+  };
+  template <class BaseClass>
+  class ExperimentalWithCallbackMethod_SetMsgBusEndpoint : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    ExperimentalWithCallbackMethod_SetMsgBusEndpoint() {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::Service::
+    #else
+      ::grpc::Service::experimental().
+    #endif
+        MarkMethodCallback(8,
+          new ::grpc_impl::internal::CallbackUnaryHandler< ::dmi::SetMsgBusEndpointRequest, ::dmi::SetRemoteEndpointResponse>(
+            [this](
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+                   ::grpc::CallbackServerContext*
+    #else
+                   ::grpc::experimental::CallbackServerContext*
+    #endif
+                     context, const ::dmi::SetMsgBusEndpointRequest* request, ::dmi::SetRemoteEndpointResponse* response) { return this->SetMsgBusEndpoint(context, request, response); }));}
+    void SetMessageAllocatorFor_SetMsgBusEndpoint(
+        ::grpc::experimental::MessageAllocator< ::dmi::SetMsgBusEndpointRequest, ::dmi::SetRemoteEndpointResponse>* allocator) {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(8);
+    #else
+      ::grpc::internal::MethodHandler* const handler = ::grpc::Service::experimental().GetHandler(8);
+    #endif
+      static_cast<::grpc_impl::internal::CallbackUnaryHandler< ::dmi::SetMsgBusEndpointRequest, ::dmi::SetRemoteEndpointResponse>*>(handler)
+              ->SetMessageAllocator(allocator);
+    }
+    ~ExperimentalWithCallbackMethod_SetMsgBusEndpoint() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status SetMsgBusEndpoint(::grpc::ServerContext* /*context*/, const ::dmi::SetMsgBusEndpointRequest* /*request*/, ::dmi::SetRemoteEndpointResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+    virtual ::grpc::ServerUnaryReactor* SetMsgBusEndpoint(
+      ::grpc::CallbackServerContext* /*context*/, const ::dmi::SetMsgBusEndpointRequest* /*request*/, ::dmi::SetRemoteEndpointResponse* /*response*/)
+    #else
+    virtual ::grpc::experimental::ServerUnaryReactor* SetMsgBusEndpoint(
+      ::grpc::experimental::CallbackServerContext* /*context*/, const ::dmi::SetMsgBusEndpointRequest* /*request*/, ::dmi::SetRemoteEndpointResponse* /*response*/)
+    #endif
+      { return nullptr; }
+  };
+  template <class BaseClass>
+  class ExperimentalWithCallbackMethod_GetMsgBusEndpoint : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    ExperimentalWithCallbackMethod_GetMsgBusEndpoint() {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::Service::
+    #else
+      ::grpc::Service::experimental().
+    #endif
+        MarkMethodCallback(9,
+          new ::grpc_impl::internal::CallbackUnaryHandler< ::google::protobuf::Empty, ::dmi::GetMsgBusEndpointResponse>(
+            [this](
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+                   ::grpc::CallbackServerContext*
+    #else
+                   ::grpc::experimental::CallbackServerContext*
+    #endif
+                     context, const ::google::protobuf::Empty* request, ::dmi::GetMsgBusEndpointResponse* response) { return this->GetMsgBusEndpoint(context, request, response); }));}
+    void SetMessageAllocatorFor_GetMsgBusEndpoint(
+        ::grpc::experimental::MessageAllocator< ::google::protobuf::Empty, ::dmi::GetMsgBusEndpointResponse>* allocator) {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(9);
+    #else
+      ::grpc::internal::MethodHandler* const handler = ::grpc::Service::experimental().GetHandler(9);
+    #endif
+      static_cast<::grpc_impl::internal::CallbackUnaryHandler< ::google::protobuf::Empty, ::dmi::GetMsgBusEndpointResponse>*>(handler)
+              ->SetMessageAllocator(allocator);
+    }
+    ~ExperimentalWithCallbackMethod_GetMsgBusEndpoint() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status GetMsgBusEndpoint(::grpc::ServerContext* /*context*/, const ::google::protobuf::Empty* /*request*/, ::dmi::GetMsgBusEndpointResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+    virtual ::grpc::ServerUnaryReactor* GetMsgBusEndpoint(
+      ::grpc::CallbackServerContext* /*context*/, const ::google::protobuf::Empty* /*request*/, ::dmi::GetMsgBusEndpointResponse* /*response*/)
+    #else
+    virtual ::grpc::experimental::ServerUnaryReactor* GetMsgBusEndpoint(
+      ::grpc::experimental::CallbackServerContext* /*context*/, const ::google::protobuf::Empty* /*request*/, ::dmi::GetMsgBusEndpointResponse* /*response*/)
+    #endif
+      { return nullptr; }
+  };
+  template <class BaseClass>
+  class ExperimentalWithCallbackMethod_GetLoggableEntities : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    ExperimentalWithCallbackMethod_GetLoggableEntities() {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::Service::
+    #else
+      ::grpc::Service::experimental().
+    #endif
+        MarkMethodCallback(10,
+          new ::grpc_impl::internal::CallbackUnaryHandler< ::dmi::GetLoggableEntitiesRequest, ::dmi::GetLogLevelResponse>(
+            [this](
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+                   ::grpc::CallbackServerContext*
+    #else
+                   ::grpc::experimental::CallbackServerContext*
+    #endif
+                     context, const ::dmi::GetLoggableEntitiesRequest* request, ::dmi::GetLogLevelResponse* response) { return this->GetLoggableEntities(context, request, response); }));}
+    void SetMessageAllocatorFor_GetLoggableEntities(
+        ::grpc::experimental::MessageAllocator< ::dmi::GetLoggableEntitiesRequest, ::dmi::GetLogLevelResponse>* allocator) {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(10);
+    #else
+      ::grpc::internal::MethodHandler* const handler = ::grpc::Service::experimental().GetHandler(10);
+    #endif
+      static_cast<::grpc_impl::internal::CallbackUnaryHandler< ::dmi::GetLoggableEntitiesRequest, ::dmi::GetLogLevelResponse>*>(handler)
+              ->SetMessageAllocator(allocator);
+    }
+    ~ExperimentalWithCallbackMethod_GetLoggableEntities() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status GetLoggableEntities(::grpc::ServerContext* /*context*/, const ::dmi::GetLoggableEntitiesRequest* /*request*/, ::dmi::GetLogLevelResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+    virtual ::grpc::ServerUnaryReactor* GetLoggableEntities(
+      ::grpc::CallbackServerContext* /*context*/, const ::dmi::GetLoggableEntitiesRequest* /*request*/, ::dmi::GetLogLevelResponse* /*response*/)
+    #else
+    virtual ::grpc::experimental::ServerUnaryReactor* GetLoggableEntities(
+      ::grpc::experimental::CallbackServerContext* /*context*/, const ::dmi::GetLoggableEntitiesRequest* /*request*/, ::dmi::GetLogLevelResponse* /*response*/)
+    #endif
+      { return nullptr; }
+  };
+  template <class BaseClass>
+  class ExperimentalWithCallbackMethod_SetLogLevel : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    ExperimentalWithCallbackMethod_SetLogLevel() {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::Service::
+    #else
+      ::grpc::Service::experimental().
+    #endif
+        MarkMethodCallback(11,
+          new ::grpc_impl::internal::CallbackUnaryHandler< ::dmi::SetLogLevelRequest, ::dmi::SetLogLevelResponse>(
+            [this](
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+                   ::grpc::CallbackServerContext*
+    #else
+                   ::grpc::experimental::CallbackServerContext*
+    #endif
+                     context, const ::dmi::SetLogLevelRequest* request, ::dmi::SetLogLevelResponse* response) { return this->SetLogLevel(context, request, response); }));}
+    void SetMessageAllocatorFor_SetLogLevel(
+        ::grpc::experimental::MessageAllocator< ::dmi::SetLogLevelRequest, ::dmi::SetLogLevelResponse>* allocator) {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(11);
+    #else
+      ::grpc::internal::MethodHandler* const handler = ::grpc::Service::experimental().GetHandler(11);
+    #endif
+      static_cast<::grpc_impl::internal::CallbackUnaryHandler< ::dmi::SetLogLevelRequest, ::dmi::SetLogLevelResponse>*>(handler)
+              ->SetMessageAllocator(allocator);
+    }
+    ~ExperimentalWithCallbackMethod_SetLogLevel() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status SetLogLevel(::grpc::ServerContext* /*context*/, const ::dmi::SetLogLevelRequest* /*request*/, ::dmi::SetLogLevelResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+    virtual ::grpc::ServerUnaryReactor* SetLogLevel(
+      ::grpc::CallbackServerContext* /*context*/, const ::dmi::SetLogLevelRequest* /*request*/, ::dmi::SetLogLevelResponse* /*response*/)
+    #else
+    virtual ::grpc::experimental::ServerUnaryReactor* SetLogLevel(
+      ::grpc::experimental::CallbackServerContext* /*context*/, const ::dmi::SetLogLevelRequest* /*request*/, ::dmi::SetLogLevelResponse* /*response*/)
+    #endif
+      { return nullptr; }
+  };
+  template <class BaseClass>
+  class ExperimentalWithCallbackMethod_GetLogLevel : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    ExperimentalWithCallbackMethod_GetLogLevel() {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::Service::
+    #else
+      ::grpc::Service::experimental().
+    #endif
+        MarkMethodCallback(12,
+          new ::grpc_impl::internal::CallbackUnaryHandler< ::dmi::GetLogLevelRequest, ::dmi::GetLogLevelResponse>(
+            [this](
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+                   ::grpc::CallbackServerContext*
+    #else
+                   ::grpc::experimental::CallbackServerContext*
+    #endif
+                     context, const ::dmi::GetLogLevelRequest* request, ::dmi::GetLogLevelResponse* response) { return this->GetLogLevel(context, request, response); }));}
+    void SetMessageAllocatorFor_GetLogLevel(
+        ::grpc::experimental::MessageAllocator< ::dmi::GetLogLevelRequest, ::dmi::GetLogLevelResponse>* allocator) {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(12);
+    #else
+      ::grpc::internal::MethodHandler* const handler = ::grpc::Service::experimental().GetHandler(12);
+    #endif
+      static_cast<::grpc_impl::internal::CallbackUnaryHandler< ::dmi::GetLogLevelRequest, ::dmi::GetLogLevelResponse>*>(handler)
+              ->SetMessageAllocator(allocator);
+    }
+    ~ExperimentalWithCallbackMethod_GetLogLevel() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status GetLogLevel(::grpc::ServerContext* /*context*/, const ::dmi::GetLogLevelRequest* /*request*/, ::dmi::GetLogLevelResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+    virtual ::grpc::ServerUnaryReactor* GetLogLevel(
+      ::grpc::CallbackServerContext* /*context*/, const ::dmi::GetLogLevelRequest* /*request*/, ::dmi::GetLogLevelResponse* /*response*/)
+    #else
+    virtual ::grpc::experimental::ServerUnaryReactor* GetLogLevel(
+      ::grpc::experimental::CallbackServerContext* /*context*/, const ::dmi::GetLogLevelRequest* /*request*/, ::dmi::GetLogLevelResponse* /*response*/)
+    #endif
+      { return nullptr; }
+  };
+  #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+  typedef ExperimentalWithCallbackMethod_StartManagingDevice<ExperimentalWithCallbackMethod_StopManagingDevice<ExperimentalWithCallbackMethod_GetManagedDevices<ExperimentalWithCallbackMethod_GetPhysicalInventory<ExperimentalWithCallbackMethod_GetHWComponentInfo<ExperimentalWithCallbackMethod_SetHWComponentInfo<ExperimentalWithCallbackMethod_SetLoggingEndpoint<ExperimentalWithCallbackMethod_GetLoggingEndpoint<ExperimentalWithCallbackMethod_SetMsgBusEndpoint<ExperimentalWithCallbackMethod_GetMsgBusEndpoint<ExperimentalWithCallbackMethod_GetLoggableEntities<ExperimentalWithCallbackMethod_SetLogLevel<ExperimentalWithCallbackMethod_GetLogLevel<Service > > > > > > > > > > > > > CallbackService;
+  #endif
+
+  typedef ExperimentalWithCallbackMethod_StartManagingDevice<ExperimentalWithCallbackMethod_StopManagingDevice<ExperimentalWithCallbackMethod_GetManagedDevices<ExperimentalWithCallbackMethod_GetPhysicalInventory<ExperimentalWithCallbackMethod_GetHWComponentInfo<ExperimentalWithCallbackMethod_SetHWComponentInfo<ExperimentalWithCallbackMethod_SetLoggingEndpoint<ExperimentalWithCallbackMethod_GetLoggingEndpoint<ExperimentalWithCallbackMethod_SetMsgBusEndpoint<ExperimentalWithCallbackMethod_GetMsgBusEndpoint<ExperimentalWithCallbackMethod_GetLoggableEntities<ExperimentalWithCallbackMethod_SetLogLevel<ExperimentalWithCallbackMethod_GetLogLevel<Service > > > > > > > > > > > > > ExperimentalCallbackService;
+  template <class BaseClass>
+  class WithGenericMethod_StartManagingDevice : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithGenericMethod_StartManagingDevice() {
+      ::grpc::Service::MarkMethodGeneric(0);
+    }
+    ~WithGenericMethod_StartManagingDevice() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status StartManagingDevice(::grpc::ServerContext* /*context*/, const ::dmi::ModifiableComponent* /*request*/, ::grpc::ServerWriter< ::dmi::StartManagingDeviceResponse>* /*writer*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+  };
+  template <class BaseClass>
+  class WithGenericMethod_StopManagingDevice : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithGenericMethod_StopManagingDevice() {
+      ::grpc::Service::MarkMethodGeneric(1);
+    }
+    ~WithGenericMethod_StopManagingDevice() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status StopManagingDevice(::grpc::ServerContext* /*context*/, const ::dmi::StopManagingDeviceRequest* /*request*/, ::dmi::StopManagingDeviceResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+  };
+  template <class BaseClass>
+  class WithGenericMethod_GetManagedDevices : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithGenericMethod_GetManagedDevices() {
+      ::grpc::Service::MarkMethodGeneric(2);
+    }
+    ~WithGenericMethod_GetManagedDevices() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status GetManagedDevices(::grpc::ServerContext* /*context*/, const ::google::protobuf::Empty* /*request*/, ::dmi::ManagedDevicesResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+  };
+  template <class BaseClass>
+  class WithGenericMethod_GetPhysicalInventory : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithGenericMethod_GetPhysicalInventory() {
+      ::grpc::Service::MarkMethodGeneric(3);
+    }
+    ~WithGenericMethod_GetPhysicalInventory() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status GetPhysicalInventory(::grpc::ServerContext* /*context*/, const ::dmi::PhysicalInventoryRequest* /*request*/, ::grpc::ServerWriter< ::dmi::PhysicalInventoryResponse>* /*writer*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+  };
+  template <class BaseClass>
+  class WithGenericMethod_GetHWComponentInfo : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithGenericMethod_GetHWComponentInfo() {
+      ::grpc::Service::MarkMethodGeneric(4);
+    }
+    ~WithGenericMethod_GetHWComponentInfo() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status GetHWComponentInfo(::grpc::ServerContext* /*context*/, const ::dmi::HWComponentInfoGetRequest* /*request*/, ::grpc::ServerWriter< ::dmi::HWComponentInfoGetResponse>* /*writer*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+  };
+  template <class BaseClass>
+  class WithGenericMethod_SetHWComponentInfo : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithGenericMethod_SetHWComponentInfo() {
+      ::grpc::Service::MarkMethodGeneric(5);
+    }
+    ~WithGenericMethod_SetHWComponentInfo() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status SetHWComponentInfo(::grpc::ServerContext* /*context*/, const ::dmi::HWComponentInfoSetRequest* /*request*/, ::dmi::HWComponentInfoSetResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+  };
+  template <class BaseClass>
+  class WithGenericMethod_SetLoggingEndpoint : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithGenericMethod_SetLoggingEndpoint() {
+      ::grpc::Service::MarkMethodGeneric(6);
+    }
+    ~WithGenericMethod_SetLoggingEndpoint() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status SetLoggingEndpoint(::grpc::ServerContext* /*context*/, const ::dmi::SetLoggingEndpointRequest* /*request*/, ::dmi::SetRemoteEndpointResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+  };
+  template <class BaseClass>
+  class WithGenericMethod_GetLoggingEndpoint : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithGenericMethod_GetLoggingEndpoint() {
+      ::grpc::Service::MarkMethodGeneric(7);
+    }
+    ~WithGenericMethod_GetLoggingEndpoint() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status GetLoggingEndpoint(::grpc::ServerContext* /*context*/, const ::dmi::HardwareID* /*request*/, ::dmi::GetLoggingEndpointResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+  };
+  template <class BaseClass>
+  class WithGenericMethod_SetMsgBusEndpoint : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithGenericMethod_SetMsgBusEndpoint() {
+      ::grpc::Service::MarkMethodGeneric(8);
+    }
+    ~WithGenericMethod_SetMsgBusEndpoint() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status SetMsgBusEndpoint(::grpc::ServerContext* /*context*/, const ::dmi::SetMsgBusEndpointRequest* /*request*/, ::dmi::SetRemoteEndpointResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+  };
+  template <class BaseClass>
+  class WithGenericMethod_GetMsgBusEndpoint : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithGenericMethod_GetMsgBusEndpoint() {
+      ::grpc::Service::MarkMethodGeneric(9);
+    }
+    ~WithGenericMethod_GetMsgBusEndpoint() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status GetMsgBusEndpoint(::grpc::ServerContext* /*context*/, const ::google::protobuf::Empty* /*request*/, ::dmi::GetMsgBusEndpointResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+  };
+  template <class BaseClass>
+  class WithGenericMethod_GetLoggableEntities : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithGenericMethod_GetLoggableEntities() {
+      ::grpc::Service::MarkMethodGeneric(10);
+    }
+    ~WithGenericMethod_GetLoggableEntities() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status GetLoggableEntities(::grpc::ServerContext* /*context*/, const ::dmi::GetLoggableEntitiesRequest* /*request*/, ::dmi::GetLogLevelResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+  };
+  template <class BaseClass>
+  class WithGenericMethod_SetLogLevel : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithGenericMethod_SetLogLevel() {
+      ::grpc::Service::MarkMethodGeneric(11);
+    }
+    ~WithGenericMethod_SetLogLevel() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status SetLogLevel(::grpc::ServerContext* /*context*/, const ::dmi::SetLogLevelRequest* /*request*/, ::dmi::SetLogLevelResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+  };
+  template <class BaseClass>
+  class WithGenericMethod_GetLogLevel : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithGenericMethod_GetLogLevel() {
+      ::grpc::Service::MarkMethodGeneric(12);
+    }
+    ~WithGenericMethod_GetLogLevel() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status GetLogLevel(::grpc::ServerContext* /*context*/, const ::dmi::GetLogLevelRequest* /*request*/, ::dmi::GetLogLevelResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+  };
+  template <class BaseClass>
+  class WithRawMethod_StartManagingDevice : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithRawMethod_StartManagingDevice() {
+      ::grpc::Service::MarkMethodRaw(0);
+    }
+    ~WithRawMethod_StartManagingDevice() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status StartManagingDevice(::grpc::ServerContext* /*context*/, const ::dmi::ModifiableComponent* /*request*/, ::grpc::ServerWriter< ::dmi::StartManagingDeviceResponse>* /*writer*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    void RequestStartManagingDevice(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncWriter< ::grpc::ByteBuffer>* writer, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+      ::grpc::Service::RequestAsyncServerStreaming(0, context, request, writer, new_call_cq, notification_cq, tag);
+    }
+  };
+  template <class BaseClass>
+  class WithRawMethod_StopManagingDevice : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithRawMethod_StopManagingDevice() {
+      ::grpc::Service::MarkMethodRaw(1);
+    }
+    ~WithRawMethod_StopManagingDevice() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status StopManagingDevice(::grpc::ServerContext* /*context*/, const ::dmi::StopManagingDeviceRequest* /*request*/, ::dmi::StopManagingDeviceResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    void RequestStopManagingDevice(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+      ::grpc::Service::RequestAsyncUnary(1, context, request, response, new_call_cq, notification_cq, tag);
+    }
+  };
+  template <class BaseClass>
+  class WithRawMethod_GetManagedDevices : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithRawMethod_GetManagedDevices() {
+      ::grpc::Service::MarkMethodRaw(2);
+    }
+    ~WithRawMethod_GetManagedDevices() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status GetManagedDevices(::grpc::ServerContext* /*context*/, const ::google::protobuf::Empty* /*request*/, ::dmi::ManagedDevicesResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    void RequestGetManagedDevices(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+      ::grpc::Service::RequestAsyncUnary(2, context, request, response, new_call_cq, notification_cq, tag);
+    }
+  };
+  template <class BaseClass>
+  class WithRawMethod_GetPhysicalInventory : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithRawMethod_GetPhysicalInventory() {
+      ::grpc::Service::MarkMethodRaw(3);
+    }
+    ~WithRawMethod_GetPhysicalInventory() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status GetPhysicalInventory(::grpc::ServerContext* /*context*/, const ::dmi::PhysicalInventoryRequest* /*request*/, ::grpc::ServerWriter< ::dmi::PhysicalInventoryResponse>* /*writer*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    void RequestGetPhysicalInventory(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncWriter< ::grpc::ByteBuffer>* writer, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+      ::grpc::Service::RequestAsyncServerStreaming(3, context, request, writer, new_call_cq, notification_cq, tag);
+    }
+  };
+  template <class BaseClass>
+  class WithRawMethod_GetHWComponentInfo : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithRawMethod_GetHWComponentInfo() {
+      ::grpc::Service::MarkMethodRaw(4);
+    }
+    ~WithRawMethod_GetHWComponentInfo() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status GetHWComponentInfo(::grpc::ServerContext* /*context*/, const ::dmi::HWComponentInfoGetRequest* /*request*/, ::grpc::ServerWriter< ::dmi::HWComponentInfoGetResponse>* /*writer*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    void RequestGetHWComponentInfo(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncWriter< ::grpc::ByteBuffer>* writer, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+      ::grpc::Service::RequestAsyncServerStreaming(4, context, request, writer, new_call_cq, notification_cq, tag);
+    }
+  };
+  template <class BaseClass>
+  class WithRawMethod_SetHWComponentInfo : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithRawMethod_SetHWComponentInfo() {
+      ::grpc::Service::MarkMethodRaw(5);
+    }
+    ~WithRawMethod_SetHWComponentInfo() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status SetHWComponentInfo(::grpc::ServerContext* /*context*/, const ::dmi::HWComponentInfoSetRequest* /*request*/, ::dmi::HWComponentInfoSetResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    void RequestSetHWComponentInfo(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+      ::grpc::Service::RequestAsyncUnary(5, context, request, response, new_call_cq, notification_cq, tag);
+    }
+  };
+  template <class BaseClass>
+  class WithRawMethod_SetLoggingEndpoint : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithRawMethod_SetLoggingEndpoint() {
+      ::grpc::Service::MarkMethodRaw(6);
+    }
+    ~WithRawMethod_SetLoggingEndpoint() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status SetLoggingEndpoint(::grpc::ServerContext* /*context*/, const ::dmi::SetLoggingEndpointRequest* /*request*/, ::dmi::SetRemoteEndpointResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    void RequestSetLoggingEndpoint(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+      ::grpc::Service::RequestAsyncUnary(6, context, request, response, new_call_cq, notification_cq, tag);
+    }
+  };
+  template <class BaseClass>
+  class WithRawMethod_GetLoggingEndpoint : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithRawMethod_GetLoggingEndpoint() {
+      ::grpc::Service::MarkMethodRaw(7);
+    }
+    ~WithRawMethod_GetLoggingEndpoint() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status GetLoggingEndpoint(::grpc::ServerContext* /*context*/, const ::dmi::HardwareID* /*request*/, ::dmi::GetLoggingEndpointResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    void RequestGetLoggingEndpoint(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+      ::grpc::Service::RequestAsyncUnary(7, context, request, response, new_call_cq, notification_cq, tag);
+    }
+  };
+  template <class BaseClass>
+  class WithRawMethod_SetMsgBusEndpoint : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithRawMethod_SetMsgBusEndpoint() {
+      ::grpc::Service::MarkMethodRaw(8);
+    }
+    ~WithRawMethod_SetMsgBusEndpoint() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status SetMsgBusEndpoint(::grpc::ServerContext* /*context*/, const ::dmi::SetMsgBusEndpointRequest* /*request*/, ::dmi::SetRemoteEndpointResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    void RequestSetMsgBusEndpoint(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+      ::grpc::Service::RequestAsyncUnary(8, context, request, response, new_call_cq, notification_cq, tag);
+    }
+  };
+  template <class BaseClass>
+  class WithRawMethod_GetMsgBusEndpoint : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithRawMethod_GetMsgBusEndpoint() {
+      ::grpc::Service::MarkMethodRaw(9);
+    }
+    ~WithRawMethod_GetMsgBusEndpoint() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status GetMsgBusEndpoint(::grpc::ServerContext* /*context*/, const ::google::protobuf::Empty* /*request*/, ::dmi::GetMsgBusEndpointResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    void RequestGetMsgBusEndpoint(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+      ::grpc::Service::RequestAsyncUnary(9, context, request, response, new_call_cq, notification_cq, tag);
+    }
+  };
+  template <class BaseClass>
+  class WithRawMethod_GetLoggableEntities : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithRawMethod_GetLoggableEntities() {
+      ::grpc::Service::MarkMethodRaw(10);
+    }
+    ~WithRawMethod_GetLoggableEntities() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status GetLoggableEntities(::grpc::ServerContext* /*context*/, const ::dmi::GetLoggableEntitiesRequest* /*request*/, ::dmi::GetLogLevelResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    void RequestGetLoggableEntities(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+      ::grpc::Service::RequestAsyncUnary(10, context, request, response, new_call_cq, notification_cq, tag);
+    }
+  };
+  template <class BaseClass>
+  class WithRawMethod_SetLogLevel : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithRawMethod_SetLogLevel() {
+      ::grpc::Service::MarkMethodRaw(11);
+    }
+    ~WithRawMethod_SetLogLevel() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status SetLogLevel(::grpc::ServerContext* /*context*/, const ::dmi::SetLogLevelRequest* /*request*/, ::dmi::SetLogLevelResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    void RequestSetLogLevel(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+      ::grpc::Service::RequestAsyncUnary(11, context, request, response, new_call_cq, notification_cq, tag);
+    }
+  };
+  template <class BaseClass>
+  class WithRawMethod_GetLogLevel : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithRawMethod_GetLogLevel() {
+      ::grpc::Service::MarkMethodRaw(12);
+    }
+    ~WithRawMethod_GetLogLevel() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status GetLogLevel(::grpc::ServerContext* /*context*/, const ::dmi::GetLogLevelRequest* /*request*/, ::dmi::GetLogLevelResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    void RequestGetLogLevel(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+      ::grpc::Service::RequestAsyncUnary(12, context, request, response, new_call_cq, notification_cq, tag);
+    }
+  };
+  template <class BaseClass>
+  class ExperimentalWithRawCallbackMethod_StartManagingDevice : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    ExperimentalWithRawCallbackMethod_StartManagingDevice() {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::Service::
+    #else
+      ::grpc::Service::experimental().
+    #endif
+        MarkMethodRawCallback(0,
+          new ::grpc_impl::internal::CallbackServerStreamingHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>(
+            [this](
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+                   ::grpc::CallbackServerContext*
+    #else
+                   ::grpc::experimental::CallbackServerContext*
+    #endif
+                     context, const::grpc::ByteBuffer* request) { return this->StartManagingDevice(context, request); }));
+    }
+    ~ExperimentalWithRawCallbackMethod_StartManagingDevice() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status StartManagingDevice(::grpc::ServerContext* /*context*/, const ::dmi::ModifiableComponent* /*request*/, ::grpc::ServerWriter< ::dmi::StartManagingDeviceResponse>* /*writer*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+    virtual ::grpc::ServerWriteReactor< ::grpc::ByteBuffer>* StartManagingDevice(
+      ::grpc::CallbackServerContext* /*context*/, const ::grpc::ByteBuffer* /*request*/)
+    #else
+    virtual ::grpc::experimental::ServerWriteReactor< ::grpc::ByteBuffer>* StartManagingDevice(
+      ::grpc::experimental::CallbackServerContext* /*context*/, const ::grpc::ByteBuffer* /*request*/)
+    #endif
+      { return nullptr; }
+  };
+  template <class BaseClass>
+  class ExperimentalWithRawCallbackMethod_StopManagingDevice : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    ExperimentalWithRawCallbackMethod_StopManagingDevice() {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::Service::
+    #else
+      ::grpc::Service::experimental().
+    #endif
+        MarkMethodRawCallback(1,
+          new ::grpc_impl::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>(
+            [this](
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+                   ::grpc::CallbackServerContext*
+    #else
+                   ::grpc::experimental::CallbackServerContext*
+    #endif
+                     context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response) { return this->StopManagingDevice(context, request, response); }));
+    }
+    ~ExperimentalWithRawCallbackMethod_StopManagingDevice() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status StopManagingDevice(::grpc::ServerContext* /*context*/, const ::dmi::StopManagingDeviceRequest* /*request*/, ::dmi::StopManagingDeviceResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+    virtual ::grpc::ServerUnaryReactor* StopManagingDevice(
+      ::grpc::CallbackServerContext* /*context*/, const ::grpc::ByteBuffer* /*request*/, ::grpc::ByteBuffer* /*response*/)
+    #else
+    virtual ::grpc::experimental::ServerUnaryReactor* StopManagingDevice(
+      ::grpc::experimental::CallbackServerContext* /*context*/, const ::grpc::ByteBuffer* /*request*/, ::grpc::ByteBuffer* /*response*/)
+    #endif
+      { return nullptr; }
+  };
+  template <class BaseClass>
+  class ExperimentalWithRawCallbackMethod_GetManagedDevices : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    ExperimentalWithRawCallbackMethod_GetManagedDevices() {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::Service::
+    #else
+      ::grpc::Service::experimental().
+    #endif
+        MarkMethodRawCallback(2,
+          new ::grpc_impl::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>(
+            [this](
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+                   ::grpc::CallbackServerContext*
+    #else
+                   ::grpc::experimental::CallbackServerContext*
+    #endif
+                     context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response) { return this->GetManagedDevices(context, request, response); }));
+    }
+    ~ExperimentalWithRawCallbackMethod_GetManagedDevices() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status GetManagedDevices(::grpc::ServerContext* /*context*/, const ::google::protobuf::Empty* /*request*/, ::dmi::ManagedDevicesResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+    virtual ::grpc::ServerUnaryReactor* GetManagedDevices(
+      ::grpc::CallbackServerContext* /*context*/, const ::grpc::ByteBuffer* /*request*/, ::grpc::ByteBuffer* /*response*/)
+    #else
+    virtual ::grpc::experimental::ServerUnaryReactor* GetManagedDevices(
+      ::grpc::experimental::CallbackServerContext* /*context*/, const ::grpc::ByteBuffer* /*request*/, ::grpc::ByteBuffer* /*response*/)
+    #endif
+      { return nullptr; }
+  };
+  template <class BaseClass>
+  class ExperimentalWithRawCallbackMethod_GetPhysicalInventory : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    ExperimentalWithRawCallbackMethod_GetPhysicalInventory() {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::Service::
+    #else
+      ::grpc::Service::experimental().
+    #endif
+        MarkMethodRawCallback(3,
+          new ::grpc_impl::internal::CallbackServerStreamingHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>(
+            [this](
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+                   ::grpc::CallbackServerContext*
+    #else
+                   ::grpc::experimental::CallbackServerContext*
+    #endif
+                     context, const::grpc::ByteBuffer* request) { return this->GetPhysicalInventory(context, request); }));
+    }
+    ~ExperimentalWithRawCallbackMethod_GetPhysicalInventory() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status GetPhysicalInventory(::grpc::ServerContext* /*context*/, const ::dmi::PhysicalInventoryRequest* /*request*/, ::grpc::ServerWriter< ::dmi::PhysicalInventoryResponse>* /*writer*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+    virtual ::grpc::ServerWriteReactor< ::grpc::ByteBuffer>* GetPhysicalInventory(
+      ::grpc::CallbackServerContext* /*context*/, const ::grpc::ByteBuffer* /*request*/)
+    #else
+    virtual ::grpc::experimental::ServerWriteReactor< ::grpc::ByteBuffer>* GetPhysicalInventory(
+      ::grpc::experimental::CallbackServerContext* /*context*/, const ::grpc::ByteBuffer* /*request*/)
+    #endif
+      { return nullptr; }
+  };
+  template <class BaseClass>
+  class ExperimentalWithRawCallbackMethod_GetHWComponentInfo : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    ExperimentalWithRawCallbackMethod_GetHWComponentInfo() {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::Service::
+    #else
+      ::grpc::Service::experimental().
+    #endif
+        MarkMethodRawCallback(4,
+          new ::grpc_impl::internal::CallbackServerStreamingHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>(
+            [this](
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+                   ::grpc::CallbackServerContext*
+    #else
+                   ::grpc::experimental::CallbackServerContext*
+    #endif
+                     context, const::grpc::ByteBuffer* request) { return this->GetHWComponentInfo(context, request); }));
+    }
+    ~ExperimentalWithRawCallbackMethod_GetHWComponentInfo() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status GetHWComponentInfo(::grpc::ServerContext* /*context*/, const ::dmi::HWComponentInfoGetRequest* /*request*/, ::grpc::ServerWriter< ::dmi::HWComponentInfoGetResponse>* /*writer*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+    virtual ::grpc::ServerWriteReactor< ::grpc::ByteBuffer>* GetHWComponentInfo(
+      ::grpc::CallbackServerContext* /*context*/, const ::grpc::ByteBuffer* /*request*/)
+    #else
+    virtual ::grpc::experimental::ServerWriteReactor< ::grpc::ByteBuffer>* GetHWComponentInfo(
+      ::grpc::experimental::CallbackServerContext* /*context*/, const ::grpc::ByteBuffer* /*request*/)
+    #endif
+      { return nullptr; }
+  };
+  template <class BaseClass>
+  class ExperimentalWithRawCallbackMethod_SetHWComponentInfo : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    ExperimentalWithRawCallbackMethod_SetHWComponentInfo() {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::Service::
+    #else
+      ::grpc::Service::experimental().
+    #endif
+        MarkMethodRawCallback(5,
+          new ::grpc_impl::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>(
+            [this](
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+                   ::grpc::CallbackServerContext*
+    #else
+                   ::grpc::experimental::CallbackServerContext*
+    #endif
+                     context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response) { return this->SetHWComponentInfo(context, request, response); }));
+    }
+    ~ExperimentalWithRawCallbackMethod_SetHWComponentInfo() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status SetHWComponentInfo(::grpc::ServerContext* /*context*/, const ::dmi::HWComponentInfoSetRequest* /*request*/, ::dmi::HWComponentInfoSetResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+    virtual ::grpc::ServerUnaryReactor* SetHWComponentInfo(
+      ::grpc::CallbackServerContext* /*context*/, const ::grpc::ByteBuffer* /*request*/, ::grpc::ByteBuffer* /*response*/)
+    #else
+    virtual ::grpc::experimental::ServerUnaryReactor* SetHWComponentInfo(
+      ::grpc::experimental::CallbackServerContext* /*context*/, const ::grpc::ByteBuffer* /*request*/, ::grpc::ByteBuffer* /*response*/)
+    #endif
+      { return nullptr; }
+  };
+  template <class BaseClass>
+  class ExperimentalWithRawCallbackMethod_SetLoggingEndpoint : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    ExperimentalWithRawCallbackMethod_SetLoggingEndpoint() {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::Service::
+    #else
+      ::grpc::Service::experimental().
+    #endif
+        MarkMethodRawCallback(6,
+          new ::grpc_impl::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>(
+            [this](
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+                   ::grpc::CallbackServerContext*
+    #else
+                   ::grpc::experimental::CallbackServerContext*
+    #endif
+                     context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response) { return this->SetLoggingEndpoint(context, request, response); }));
+    }
+    ~ExperimentalWithRawCallbackMethod_SetLoggingEndpoint() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status SetLoggingEndpoint(::grpc::ServerContext* /*context*/, const ::dmi::SetLoggingEndpointRequest* /*request*/, ::dmi::SetRemoteEndpointResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+    virtual ::grpc::ServerUnaryReactor* SetLoggingEndpoint(
+      ::grpc::CallbackServerContext* /*context*/, const ::grpc::ByteBuffer* /*request*/, ::grpc::ByteBuffer* /*response*/)
+    #else
+    virtual ::grpc::experimental::ServerUnaryReactor* SetLoggingEndpoint(
+      ::grpc::experimental::CallbackServerContext* /*context*/, const ::grpc::ByteBuffer* /*request*/, ::grpc::ByteBuffer* /*response*/)
+    #endif
+      { return nullptr; }
+  };
+  template <class BaseClass>
+  class ExperimentalWithRawCallbackMethod_GetLoggingEndpoint : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    ExperimentalWithRawCallbackMethod_GetLoggingEndpoint() {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::Service::
+    #else
+      ::grpc::Service::experimental().
+    #endif
+        MarkMethodRawCallback(7,
+          new ::grpc_impl::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>(
+            [this](
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+                   ::grpc::CallbackServerContext*
+    #else
+                   ::grpc::experimental::CallbackServerContext*
+    #endif
+                     context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response) { return this->GetLoggingEndpoint(context, request, response); }));
+    }
+    ~ExperimentalWithRawCallbackMethod_GetLoggingEndpoint() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status GetLoggingEndpoint(::grpc::ServerContext* /*context*/, const ::dmi::HardwareID* /*request*/, ::dmi::GetLoggingEndpointResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+    virtual ::grpc::ServerUnaryReactor* GetLoggingEndpoint(
+      ::grpc::CallbackServerContext* /*context*/, const ::grpc::ByteBuffer* /*request*/, ::grpc::ByteBuffer* /*response*/)
+    #else
+    virtual ::grpc::experimental::ServerUnaryReactor* GetLoggingEndpoint(
+      ::grpc::experimental::CallbackServerContext* /*context*/, const ::grpc::ByteBuffer* /*request*/, ::grpc::ByteBuffer* /*response*/)
+    #endif
+      { return nullptr; }
+  };
+  template <class BaseClass>
+  class ExperimentalWithRawCallbackMethod_SetMsgBusEndpoint : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    ExperimentalWithRawCallbackMethod_SetMsgBusEndpoint() {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::Service::
+    #else
+      ::grpc::Service::experimental().
+    #endif
+        MarkMethodRawCallback(8,
+          new ::grpc_impl::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>(
+            [this](
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+                   ::grpc::CallbackServerContext*
+    #else
+                   ::grpc::experimental::CallbackServerContext*
+    #endif
+                     context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response) { return this->SetMsgBusEndpoint(context, request, response); }));
+    }
+    ~ExperimentalWithRawCallbackMethod_SetMsgBusEndpoint() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status SetMsgBusEndpoint(::grpc::ServerContext* /*context*/, const ::dmi::SetMsgBusEndpointRequest* /*request*/, ::dmi::SetRemoteEndpointResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+    virtual ::grpc::ServerUnaryReactor* SetMsgBusEndpoint(
+      ::grpc::CallbackServerContext* /*context*/, const ::grpc::ByteBuffer* /*request*/, ::grpc::ByteBuffer* /*response*/)
+    #else
+    virtual ::grpc::experimental::ServerUnaryReactor* SetMsgBusEndpoint(
+      ::grpc::experimental::CallbackServerContext* /*context*/, const ::grpc::ByteBuffer* /*request*/, ::grpc::ByteBuffer* /*response*/)
+    #endif
+      { return nullptr; }
+  };
+  template <class BaseClass>
+  class ExperimentalWithRawCallbackMethod_GetMsgBusEndpoint : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    ExperimentalWithRawCallbackMethod_GetMsgBusEndpoint() {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::Service::
+    #else
+      ::grpc::Service::experimental().
+    #endif
+        MarkMethodRawCallback(9,
+          new ::grpc_impl::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>(
+            [this](
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+                   ::grpc::CallbackServerContext*
+    #else
+                   ::grpc::experimental::CallbackServerContext*
+    #endif
+                     context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response) { return this->GetMsgBusEndpoint(context, request, response); }));
+    }
+    ~ExperimentalWithRawCallbackMethod_GetMsgBusEndpoint() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status GetMsgBusEndpoint(::grpc::ServerContext* /*context*/, const ::google::protobuf::Empty* /*request*/, ::dmi::GetMsgBusEndpointResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+    virtual ::grpc::ServerUnaryReactor* GetMsgBusEndpoint(
+      ::grpc::CallbackServerContext* /*context*/, const ::grpc::ByteBuffer* /*request*/, ::grpc::ByteBuffer* /*response*/)
+    #else
+    virtual ::grpc::experimental::ServerUnaryReactor* GetMsgBusEndpoint(
+      ::grpc::experimental::CallbackServerContext* /*context*/, const ::grpc::ByteBuffer* /*request*/, ::grpc::ByteBuffer* /*response*/)
+    #endif
+      { return nullptr; }
+  };
+  template <class BaseClass>
+  class ExperimentalWithRawCallbackMethod_GetLoggableEntities : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    ExperimentalWithRawCallbackMethod_GetLoggableEntities() {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::Service::
+    #else
+      ::grpc::Service::experimental().
+    #endif
+        MarkMethodRawCallback(10,
+          new ::grpc_impl::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>(
+            [this](
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+                   ::grpc::CallbackServerContext*
+    #else
+                   ::grpc::experimental::CallbackServerContext*
+    #endif
+                     context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response) { return this->GetLoggableEntities(context, request, response); }));
+    }
+    ~ExperimentalWithRawCallbackMethod_GetLoggableEntities() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status GetLoggableEntities(::grpc::ServerContext* /*context*/, const ::dmi::GetLoggableEntitiesRequest* /*request*/, ::dmi::GetLogLevelResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+    virtual ::grpc::ServerUnaryReactor* GetLoggableEntities(
+      ::grpc::CallbackServerContext* /*context*/, const ::grpc::ByteBuffer* /*request*/, ::grpc::ByteBuffer* /*response*/)
+    #else
+    virtual ::grpc::experimental::ServerUnaryReactor* GetLoggableEntities(
+      ::grpc::experimental::CallbackServerContext* /*context*/, const ::grpc::ByteBuffer* /*request*/, ::grpc::ByteBuffer* /*response*/)
+    #endif
+      { return nullptr; }
+  };
+  template <class BaseClass>
+  class ExperimentalWithRawCallbackMethod_SetLogLevel : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    ExperimentalWithRawCallbackMethod_SetLogLevel() {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::Service::
+    #else
+      ::grpc::Service::experimental().
+    #endif
+        MarkMethodRawCallback(11,
+          new ::grpc_impl::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>(
+            [this](
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+                   ::grpc::CallbackServerContext*
+    #else
+                   ::grpc::experimental::CallbackServerContext*
+    #endif
+                     context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response) { return this->SetLogLevel(context, request, response); }));
+    }
+    ~ExperimentalWithRawCallbackMethod_SetLogLevel() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status SetLogLevel(::grpc::ServerContext* /*context*/, const ::dmi::SetLogLevelRequest* /*request*/, ::dmi::SetLogLevelResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+    virtual ::grpc::ServerUnaryReactor* SetLogLevel(
+      ::grpc::CallbackServerContext* /*context*/, const ::grpc::ByteBuffer* /*request*/, ::grpc::ByteBuffer* /*response*/)
+    #else
+    virtual ::grpc::experimental::ServerUnaryReactor* SetLogLevel(
+      ::grpc::experimental::CallbackServerContext* /*context*/, const ::grpc::ByteBuffer* /*request*/, ::grpc::ByteBuffer* /*response*/)
+    #endif
+      { return nullptr; }
+  };
+  template <class BaseClass>
+  class ExperimentalWithRawCallbackMethod_GetLogLevel : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    ExperimentalWithRawCallbackMethod_GetLogLevel() {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::Service::
+    #else
+      ::grpc::Service::experimental().
+    #endif
+        MarkMethodRawCallback(12,
+          new ::grpc_impl::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>(
+            [this](
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+                   ::grpc::CallbackServerContext*
+    #else
+                   ::grpc::experimental::CallbackServerContext*
+    #endif
+                     context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response) { return this->GetLogLevel(context, request, response); }));
+    }
+    ~ExperimentalWithRawCallbackMethod_GetLogLevel() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status GetLogLevel(::grpc::ServerContext* /*context*/, const ::dmi::GetLogLevelRequest* /*request*/, ::dmi::GetLogLevelResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+    virtual ::grpc::ServerUnaryReactor* GetLogLevel(
+      ::grpc::CallbackServerContext* /*context*/, const ::grpc::ByteBuffer* /*request*/, ::grpc::ByteBuffer* /*response*/)
+    #else
+    virtual ::grpc::experimental::ServerUnaryReactor* GetLogLevel(
+      ::grpc::experimental::CallbackServerContext* /*context*/, const ::grpc::ByteBuffer* /*request*/, ::grpc::ByteBuffer* /*response*/)
+    #endif
+      { return nullptr; }
+  };
+  template <class BaseClass>
+  class WithStreamedUnaryMethod_StopManagingDevice : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithStreamedUnaryMethod_StopManagingDevice() {
+      ::grpc::Service::MarkMethodStreamed(1,
+        new ::grpc::internal::StreamedUnaryHandler<
+          ::dmi::StopManagingDeviceRequest, ::dmi::StopManagingDeviceResponse>(
+            [this](::grpc_impl::ServerContext* context,
+                   ::grpc_impl::ServerUnaryStreamer<
+                     ::dmi::StopManagingDeviceRequest, ::dmi::StopManagingDeviceResponse>* streamer) {
+                       return this->StreamedStopManagingDevice(context,
+                         streamer);
+                  }));
+    }
+    ~WithStreamedUnaryMethod_StopManagingDevice() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable regular version of this method
+    ::grpc::Status StopManagingDevice(::grpc::ServerContext* /*context*/, const ::dmi::StopManagingDeviceRequest* /*request*/, ::dmi::StopManagingDeviceResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    // replace default version of method with streamed unary
+    virtual ::grpc::Status StreamedStopManagingDevice(::grpc::ServerContext* context, ::grpc::ServerUnaryStreamer< ::dmi::StopManagingDeviceRequest,::dmi::StopManagingDeviceResponse>* server_unary_streamer) = 0;
+  };
+  template <class BaseClass>
+  class WithStreamedUnaryMethod_GetManagedDevices : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithStreamedUnaryMethod_GetManagedDevices() {
+      ::grpc::Service::MarkMethodStreamed(2,
+        new ::grpc::internal::StreamedUnaryHandler<
+          ::google::protobuf::Empty, ::dmi::ManagedDevicesResponse>(
+            [this](::grpc_impl::ServerContext* context,
+                   ::grpc_impl::ServerUnaryStreamer<
+                     ::google::protobuf::Empty, ::dmi::ManagedDevicesResponse>* streamer) {
+                       return this->StreamedGetManagedDevices(context,
+                         streamer);
+                  }));
+    }
+    ~WithStreamedUnaryMethod_GetManagedDevices() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable regular version of this method
+    ::grpc::Status GetManagedDevices(::grpc::ServerContext* /*context*/, const ::google::protobuf::Empty* /*request*/, ::dmi::ManagedDevicesResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    // replace default version of method with streamed unary
+    virtual ::grpc::Status StreamedGetManagedDevices(::grpc::ServerContext* context, ::grpc::ServerUnaryStreamer< ::google::protobuf::Empty,::dmi::ManagedDevicesResponse>* server_unary_streamer) = 0;
+  };
+  template <class BaseClass>
+  class WithStreamedUnaryMethod_SetHWComponentInfo : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithStreamedUnaryMethod_SetHWComponentInfo() {
+      ::grpc::Service::MarkMethodStreamed(5,
+        new ::grpc::internal::StreamedUnaryHandler<
+          ::dmi::HWComponentInfoSetRequest, ::dmi::HWComponentInfoSetResponse>(
+            [this](::grpc_impl::ServerContext* context,
+                   ::grpc_impl::ServerUnaryStreamer<
+                     ::dmi::HWComponentInfoSetRequest, ::dmi::HWComponentInfoSetResponse>* streamer) {
+                       return this->StreamedSetHWComponentInfo(context,
+                         streamer);
+                  }));
+    }
+    ~WithStreamedUnaryMethod_SetHWComponentInfo() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable regular version of this method
+    ::grpc::Status SetHWComponentInfo(::grpc::ServerContext* /*context*/, const ::dmi::HWComponentInfoSetRequest* /*request*/, ::dmi::HWComponentInfoSetResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    // replace default version of method with streamed unary
+    virtual ::grpc::Status StreamedSetHWComponentInfo(::grpc::ServerContext* context, ::grpc::ServerUnaryStreamer< ::dmi::HWComponentInfoSetRequest,::dmi::HWComponentInfoSetResponse>* server_unary_streamer) = 0;
+  };
+  template <class BaseClass>
+  class WithStreamedUnaryMethod_SetLoggingEndpoint : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithStreamedUnaryMethod_SetLoggingEndpoint() {
+      ::grpc::Service::MarkMethodStreamed(6,
+        new ::grpc::internal::StreamedUnaryHandler<
+          ::dmi::SetLoggingEndpointRequest, ::dmi::SetRemoteEndpointResponse>(
+            [this](::grpc_impl::ServerContext* context,
+                   ::grpc_impl::ServerUnaryStreamer<
+                     ::dmi::SetLoggingEndpointRequest, ::dmi::SetRemoteEndpointResponse>* streamer) {
+                       return this->StreamedSetLoggingEndpoint(context,
+                         streamer);
+                  }));
+    }
+    ~WithStreamedUnaryMethod_SetLoggingEndpoint() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable regular version of this method
+    ::grpc::Status SetLoggingEndpoint(::grpc::ServerContext* /*context*/, const ::dmi::SetLoggingEndpointRequest* /*request*/, ::dmi::SetRemoteEndpointResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    // replace default version of method with streamed unary
+    virtual ::grpc::Status StreamedSetLoggingEndpoint(::grpc::ServerContext* context, ::grpc::ServerUnaryStreamer< ::dmi::SetLoggingEndpointRequest,::dmi::SetRemoteEndpointResponse>* server_unary_streamer) = 0;
+  };
+  template <class BaseClass>
+  class WithStreamedUnaryMethod_GetLoggingEndpoint : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithStreamedUnaryMethod_GetLoggingEndpoint() {
+      ::grpc::Service::MarkMethodStreamed(7,
+        new ::grpc::internal::StreamedUnaryHandler<
+          ::dmi::HardwareID, ::dmi::GetLoggingEndpointResponse>(
+            [this](::grpc_impl::ServerContext* context,
+                   ::grpc_impl::ServerUnaryStreamer<
+                     ::dmi::HardwareID, ::dmi::GetLoggingEndpointResponse>* streamer) {
+                       return this->StreamedGetLoggingEndpoint(context,
+                         streamer);
+                  }));
+    }
+    ~WithStreamedUnaryMethod_GetLoggingEndpoint() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable regular version of this method
+    ::grpc::Status GetLoggingEndpoint(::grpc::ServerContext* /*context*/, const ::dmi::HardwareID* /*request*/, ::dmi::GetLoggingEndpointResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    // replace default version of method with streamed unary
+    virtual ::grpc::Status StreamedGetLoggingEndpoint(::grpc::ServerContext* context, ::grpc::ServerUnaryStreamer< ::dmi::HardwareID,::dmi::GetLoggingEndpointResponse>* server_unary_streamer) = 0;
+  };
+  template <class BaseClass>
+  class WithStreamedUnaryMethod_SetMsgBusEndpoint : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithStreamedUnaryMethod_SetMsgBusEndpoint() {
+      ::grpc::Service::MarkMethodStreamed(8,
+        new ::grpc::internal::StreamedUnaryHandler<
+          ::dmi::SetMsgBusEndpointRequest, ::dmi::SetRemoteEndpointResponse>(
+            [this](::grpc_impl::ServerContext* context,
+                   ::grpc_impl::ServerUnaryStreamer<
+                     ::dmi::SetMsgBusEndpointRequest, ::dmi::SetRemoteEndpointResponse>* streamer) {
+                       return this->StreamedSetMsgBusEndpoint(context,
+                         streamer);
+                  }));
+    }
+    ~WithStreamedUnaryMethod_SetMsgBusEndpoint() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable regular version of this method
+    ::grpc::Status SetMsgBusEndpoint(::grpc::ServerContext* /*context*/, const ::dmi::SetMsgBusEndpointRequest* /*request*/, ::dmi::SetRemoteEndpointResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    // replace default version of method with streamed unary
+    virtual ::grpc::Status StreamedSetMsgBusEndpoint(::grpc::ServerContext* context, ::grpc::ServerUnaryStreamer< ::dmi::SetMsgBusEndpointRequest,::dmi::SetRemoteEndpointResponse>* server_unary_streamer) = 0;
+  };
+  template <class BaseClass>
+  class WithStreamedUnaryMethod_GetMsgBusEndpoint : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithStreamedUnaryMethod_GetMsgBusEndpoint() {
+      ::grpc::Service::MarkMethodStreamed(9,
+        new ::grpc::internal::StreamedUnaryHandler<
+          ::google::protobuf::Empty, ::dmi::GetMsgBusEndpointResponse>(
+            [this](::grpc_impl::ServerContext* context,
+                   ::grpc_impl::ServerUnaryStreamer<
+                     ::google::protobuf::Empty, ::dmi::GetMsgBusEndpointResponse>* streamer) {
+                       return this->StreamedGetMsgBusEndpoint(context,
+                         streamer);
+                  }));
+    }
+    ~WithStreamedUnaryMethod_GetMsgBusEndpoint() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable regular version of this method
+    ::grpc::Status GetMsgBusEndpoint(::grpc::ServerContext* /*context*/, const ::google::protobuf::Empty* /*request*/, ::dmi::GetMsgBusEndpointResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    // replace default version of method with streamed unary
+    virtual ::grpc::Status StreamedGetMsgBusEndpoint(::grpc::ServerContext* context, ::grpc::ServerUnaryStreamer< ::google::protobuf::Empty,::dmi::GetMsgBusEndpointResponse>* server_unary_streamer) = 0;
+  };
+  template <class BaseClass>
+  class WithStreamedUnaryMethod_GetLoggableEntities : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithStreamedUnaryMethod_GetLoggableEntities() {
+      ::grpc::Service::MarkMethodStreamed(10,
+        new ::grpc::internal::StreamedUnaryHandler<
+          ::dmi::GetLoggableEntitiesRequest, ::dmi::GetLogLevelResponse>(
+            [this](::grpc_impl::ServerContext* context,
+                   ::grpc_impl::ServerUnaryStreamer<
+                     ::dmi::GetLoggableEntitiesRequest, ::dmi::GetLogLevelResponse>* streamer) {
+                       return this->StreamedGetLoggableEntities(context,
+                         streamer);
+                  }));
+    }
+    ~WithStreamedUnaryMethod_GetLoggableEntities() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable regular version of this method
+    ::grpc::Status GetLoggableEntities(::grpc::ServerContext* /*context*/, const ::dmi::GetLoggableEntitiesRequest* /*request*/, ::dmi::GetLogLevelResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    // replace default version of method with streamed unary
+    virtual ::grpc::Status StreamedGetLoggableEntities(::grpc::ServerContext* context, ::grpc::ServerUnaryStreamer< ::dmi::GetLoggableEntitiesRequest,::dmi::GetLogLevelResponse>* server_unary_streamer) = 0;
+  };
+  template <class BaseClass>
+  class WithStreamedUnaryMethod_SetLogLevel : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithStreamedUnaryMethod_SetLogLevel() {
+      ::grpc::Service::MarkMethodStreamed(11,
+        new ::grpc::internal::StreamedUnaryHandler<
+          ::dmi::SetLogLevelRequest, ::dmi::SetLogLevelResponse>(
+            [this](::grpc_impl::ServerContext* context,
+                   ::grpc_impl::ServerUnaryStreamer<
+                     ::dmi::SetLogLevelRequest, ::dmi::SetLogLevelResponse>* streamer) {
+                       return this->StreamedSetLogLevel(context,
+                         streamer);
+                  }));
+    }
+    ~WithStreamedUnaryMethod_SetLogLevel() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable regular version of this method
+    ::grpc::Status SetLogLevel(::grpc::ServerContext* /*context*/, const ::dmi::SetLogLevelRequest* /*request*/, ::dmi::SetLogLevelResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    // replace default version of method with streamed unary
+    virtual ::grpc::Status StreamedSetLogLevel(::grpc::ServerContext* context, ::grpc::ServerUnaryStreamer< ::dmi::SetLogLevelRequest,::dmi::SetLogLevelResponse>* server_unary_streamer) = 0;
+  };
+  template <class BaseClass>
+  class WithStreamedUnaryMethod_GetLogLevel : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithStreamedUnaryMethod_GetLogLevel() {
+      ::grpc::Service::MarkMethodStreamed(12,
+        new ::grpc::internal::StreamedUnaryHandler<
+          ::dmi::GetLogLevelRequest, ::dmi::GetLogLevelResponse>(
+            [this](::grpc_impl::ServerContext* context,
+                   ::grpc_impl::ServerUnaryStreamer<
+                     ::dmi::GetLogLevelRequest, ::dmi::GetLogLevelResponse>* streamer) {
+                       return this->StreamedGetLogLevel(context,
+                         streamer);
+                  }));
+    }
+    ~WithStreamedUnaryMethod_GetLogLevel() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable regular version of this method
+    ::grpc::Status GetLogLevel(::grpc::ServerContext* /*context*/, const ::dmi::GetLogLevelRequest* /*request*/, ::dmi::GetLogLevelResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    // replace default version of method with streamed unary
+    virtual ::grpc::Status StreamedGetLogLevel(::grpc::ServerContext* context, ::grpc::ServerUnaryStreamer< ::dmi::GetLogLevelRequest,::dmi::GetLogLevelResponse>* server_unary_streamer) = 0;
+  };
+  typedef WithStreamedUnaryMethod_StopManagingDevice<WithStreamedUnaryMethod_GetManagedDevices<WithStreamedUnaryMethod_SetHWComponentInfo<WithStreamedUnaryMethod_SetLoggingEndpoint<WithStreamedUnaryMethod_GetLoggingEndpoint<WithStreamedUnaryMethod_SetMsgBusEndpoint<WithStreamedUnaryMethod_GetMsgBusEndpoint<WithStreamedUnaryMethod_GetLoggableEntities<WithStreamedUnaryMethod_SetLogLevel<WithStreamedUnaryMethod_GetLogLevel<Service > > > > > > > > > > StreamedUnaryService;
+  template <class BaseClass>
+  class WithSplitStreamingMethod_StartManagingDevice : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithSplitStreamingMethod_StartManagingDevice() {
+      ::grpc::Service::MarkMethodStreamed(0,
+        new ::grpc::internal::SplitServerStreamingHandler<
+          ::dmi::ModifiableComponent, ::dmi::StartManagingDeviceResponse>(
+            [this](::grpc_impl::ServerContext* context,
+                   ::grpc_impl::ServerSplitStreamer<
+                     ::dmi::ModifiableComponent, ::dmi::StartManagingDeviceResponse>* streamer) {
+                       return this->StreamedStartManagingDevice(context,
+                         streamer);
+                  }));
+    }
+    ~WithSplitStreamingMethod_StartManagingDevice() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable regular version of this method
+    ::grpc::Status StartManagingDevice(::grpc::ServerContext* /*context*/, const ::dmi::ModifiableComponent* /*request*/, ::grpc::ServerWriter< ::dmi::StartManagingDeviceResponse>* /*writer*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    // replace default version of method with split streamed
+    virtual ::grpc::Status StreamedStartManagingDevice(::grpc::ServerContext* context, ::grpc::ServerSplitStreamer< ::dmi::ModifiableComponent,::dmi::StartManagingDeviceResponse>* server_split_streamer) = 0;
+  };
+  template <class BaseClass>
+  class WithSplitStreamingMethod_GetPhysicalInventory : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithSplitStreamingMethod_GetPhysicalInventory() {
+      ::grpc::Service::MarkMethodStreamed(3,
+        new ::grpc::internal::SplitServerStreamingHandler<
+          ::dmi::PhysicalInventoryRequest, ::dmi::PhysicalInventoryResponse>(
+            [this](::grpc_impl::ServerContext* context,
+                   ::grpc_impl::ServerSplitStreamer<
+                     ::dmi::PhysicalInventoryRequest, ::dmi::PhysicalInventoryResponse>* streamer) {
+                       return this->StreamedGetPhysicalInventory(context,
+                         streamer);
+                  }));
+    }
+    ~WithSplitStreamingMethod_GetPhysicalInventory() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable regular version of this method
+    ::grpc::Status GetPhysicalInventory(::grpc::ServerContext* /*context*/, const ::dmi::PhysicalInventoryRequest* /*request*/, ::grpc::ServerWriter< ::dmi::PhysicalInventoryResponse>* /*writer*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    // replace default version of method with split streamed
+    virtual ::grpc::Status StreamedGetPhysicalInventory(::grpc::ServerContext* context, ::grpc::ServerSplitStreamer< ::dmi::PhysicalInventoryRequest,::dmi::PhysicalInventoryResponse>* server_split_streamer) = 0;
+  };
+  template <class BaseClass>
+  class WithSplitStreamingMethod_GetHWComponentInfo : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithSplitStreamingMethod_GetHWComponentInfo() {
+      ::grpc::Service::MarkMethodStreamed(4,
+        new ::grpc::internal::SplitServerStreamingHandler<
+          ::dmi::HWComponentInfoGetRequest, ::dmi::HWComponentInfoGetResponse>(
+            [this](::grpc_impl::ServerContext* context,
+                   ::grpc_impl::ServerSplitStreamer<
+                     ::dmi::HWComponentInfoGetRequest, ::dmi::HWComponentInfoGetResponse>* streamer) {
+                       return this->StreamedGetHWComponentInfo(context,
+                         streamer);
+                  }));
+    }
+    ~WithSplitStreamingMethod_GetHWComponentInfo() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable regular version of this method
+    ::grpc::Status GetHWComponentInfo(::grpc::ServerContext* /*context*/, const ::dmi::HWComponentInfoGetRequest* /*request*/, ::grpc::ServerWriter< ::dmi::HWComponentInfoGetResponse>* /*writer*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    // replace default version of method with split streamed
+    virtual ::grpc::Status StreamedGetHWComponentInfo(::grpc::ServerContext* context, ::grpc::ServerSplitStreamer< ::dmi::HWComponentInfoGetRequest,::dmi::HWComponentInfoGetResponse>* server_split_streamer) = 0;
+  };
+  typedef WithSplitStreamingMethod_StartManagingDevice<WithSplitStreamingMethod_GetPhysicalInventory<WithSplitStreamingMethod_GetHWComponentInfo<Service > > > SplitStreamedService;
+  typedef WithSplitStreamingMethod_StartManagingDevice<WithStreamedUnaryMethod_StopManagingDevice<WithStreamedUnaryMethod_GetManagedDevices<WithSplitStreamingMethod_GetPhysicalInventory<WithSplitStreamingMethod_GetHWComponentInfo<WithStreamedUnaryMethod_SetHWComponentInfo<WithStreamedUnaryMethod_SetLoggingEndpoint<WithStreamedUnaryMethod_GetLoggingEndpoint<WithStreamedUnaryMethod_SetMsgBusEndpoint<WithStreamedUnaryMethod_GetMsgBusEndpoint<WithStreamedUnaryMethod_GetLoggableEntities<WithStreamedUnaryMethod_SetLogLevel<WithStreamedUnaryMethod_GetLogLevel<Service > > > > > > > > > > > > > StreamedService;
+};
+
+}  // namespace dmi
+
+
+#endif  // GRPC_dmi_2fhw_5fmanagement_5fservice_2eproto__INCLUDED
diff --git a/cpp/dmi/hw_metrics_mgmt_service.grpc.pb.cc b/cpp/dmi/hw_metrics_mgmt_service.grpc.pb.cc
new file mode 100644
index 0000000..1c674c4
--- /dev/null
+++ b/cpp/dmi/hw_metrics_mgmt_service.grpc.pb.cc
@@ -0,0 +1,185 @@
+// Generated by the gRPC C++ plugin.
+// If you make any local change, they will be lost.
+// source: dmi/hw_metrics_mgmt_service.proto
+
+#include "dmi/hw_metrics_mgmt_service.pb.h"
+#include "dmi/hw_metrics_mgmt_service.grpc.pb.h"
+
+#include <functional>
+#include <grpcpp/impl/codegen/async_stream.h>
+#include <grpcpp/impl/codegen/async_unary_call.h>
+#include <grpcpp/impl/codegen/channel_interface.h>
+#include <grpcpp/impl/codegen/client_unary_call.h>
+#include <grpcpp/impl/codegen/client_callback.h>
+#include <grpcpp/impl/codegen/message_allocator.h>
+#include <grpcpp/impl/codegen/method_handler.h>
+#include <grpcpp/impl/codegen/rpc_service_method.h>
+#include <grpcpp/impl/codegen/server_callback.h>
+#include <grpcpp/impl/codegen/server_callback_handlers.h>
+#include <grpcpp/impl/codegen/server_context.h>
+#include <grpcpp/impl/codegen/service_type.h>
+#include <grpcpp/impl/codegen/sync_stream.h>
+namespace dmi {
+
+static const char* NativeMetricsManagementService_method_names[] = {
+  "/dmi.NativeMetricsManagementService/ListMetrics",
+  "/dmi.NativeMetricsManagementService/UpdateMetricsConfiguration",
+  "/dmi.NativeMetricsManagementService/GetMetric",
+};
+
+std::unique_ptr< NativeMetricsManagementService::Stub> NativeMetricsManagementService::NewStub(const std::shared_ptr< ::grpc::ChannelInterface>& channel, const ::grpc::StubOptions& options) {
+  (void)options;
+  std::unique_ptr< NativeMetricsManagementService::Stub> stub(new NativeMetricsManagementService::Stub(channel));
+  return stub;
+}
+
+NativeMetricsManagementService::Stub::Stub(const std::shared_ptr< ::grpc::ChannelInterface>& channel)
+  : channel_(channel), rpcmethod_ListMetrics_(NativeMetricsManagementService_method_names[0], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
+  , rpcmethod_UpdateMetricsConfiguration_(NativeMetricsManagementService_method_names[1], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
+  , rpcmethod_GetMetric_(NativeMetricsManagementService_method_names[2], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
+  {}
+
+::grpc::Status NativeMetricsManagementService::Stub::ListMetrics(::grpc::ClientContext* context, const ::dmi::HardwareID& request, ::dmi::ListMetricsResponse* response) {
+  return ::grpc::internal::BlockingUnaryCall(channel_.get(), rpcmethod_ListMetrics_, context, request, response);
+}
+
+void NativeMetricsManagementService::Stub::experimental_async::ListMetrics(::grpc::ClientContext* context, const ::dmi::HardwareID* request, ::dmi::ListMetricsResponse* response, std::function<void(::grpc::Status)> f) {
+  ::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_ListMetrics_, context, request, response, std::move(f));
+}
+
+void NativeMetricsManagementService::Stub::experimental_async::ListMetrics(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::ListMetricsResponse* response, std::function<void(::grpc::Status)> f) {
+  ::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_ListMetrics_, context, request, response, std::move(f));
+}
+
+void NativeMetricsManagementService::Stub::experimental_async::ListMetrics(::grpc::ClientContext* context, const ::dmi::HardwareID* request, ::dmi::ListMetricsResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
+  ::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_ListMetrics_, context, request, response, reactor);
+}
+
+void NativeMetricsManagementService::Stub::experimental_async::ListMetrics(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::ListMetricsResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
+  ::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_ListMetrics_, context, request, response, reactor);
+}
+
+::grpc::ClientAsyncResponseReader< ::dmi::ListMetricsResponse>* NativeMetricsManagementService::Stub::AsyncListMetricsRaw(::grpc::ClientContext* context, const ::dmi::HardwareID& request, ::grpc::CompletionQueue* cq) {
+  return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::dmi::ListMetricsResponse>::Create(channel_.get(), cq, rpcmethod_ListMetrics_, context, request, true);
+}
+
+::grpc::ClientAsyncResponseReader< ::dmi::ListMetricsResponse>* NativeMetricsManagementService::Stub::PrepareAsyncListMetricsRaw(::grpc::ClientContext* context, const ::dmi::HardwareID& request, ::grpc::CompletionQueue* cq) {
+  return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::dmi::ListMetricsResponse>::Create(channel_.get(), cq, rpcmethod_ListMetrics_, context, request, false);
+}
+
+::grpc::Status NativeMetricsManagementService::Stub::UpdateMetricsConfiguration(::grpc::ClientContext* context, const ::dmi::MetricsConfigurationRequest& request, ::dmi::MetricsConfigurationResponse* response) {
+  return ::grpc::internal::BlockingUnaryCall(channel_.get(), rpcmethod_UpdateMetricsConfiguration_, context, request, response);
+}
+
+void NativeMetricsManagementService::Stub::experimental_async::UpdateMetricsConfiguration(::grpc::ClientContext* context, const ::dmi::MetricsConfigurationRequest* request, ::dmi::MetricsConfigurationResponse* response, std::function<void(::grpc::Status)> f) {
+  ::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_UpdateMetricsConfiguration_, context, request, response, std::move(f));
+}
+
+void NativeMetricsManagementService::Stub::experimental_async::UpdateMetricsConfiguration(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::MetricsConfigurationResponse* response, std::function<void(::grpc::Status)> f) {
+  ::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_UpdateMetricsConfiguration_, context, request, response, std::move(f));
+}
+
+void NativeMetricsManagementService::Stub::experimental_async::UpdateMetricsConfiguration(::grpc::ClientContext* context, const ::dmi::MetricsConfigurationRequest* request, ::dmi::MetricsConfigurationResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
+  ::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_UpdateMetricsConfiguration_, context, request, response, reactor);
+}
+
+void NativeMetricsManagementService::Stub::experimental_async::UpdateMetricsConfiguration(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::MetricsConfigurationResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
+  ::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_UpdateMetricsConfiguration_, context, request, response, reactor);
+}
+
+::grpc::ClientAsyncResponseReader< ::dmi::MetricsConfigurationResponse>* NativeMetricsManagementService::Stub::AsyncUpdateMetricsConfigurationRaw(::grpc::ClientContext* context, const ::dmi::MetricsConfigurationRequest& request, ::grpc::CompletionQueue* cq) {
+  return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::dmi::MetricsConfigurationResponse>::Create(channel_.get(), cq, rpcmethod_UpdateMetricsConfiguration_, context, request, true);
+}
+
+::grpc::ClientAsyncResponseReader< ::dmi::MetricsConfigurationResponse>* NativeMetricsManagementService::Stub::PrepareAsyncUpdateMetricsConfigurationRaw(::grpc::ClientContext* context, const ::dmi::MetricsConfigurationRequest& request, ::grpc::CompletionQueue* cq) {
+  return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::dmi::MetricsConfigurationResponse>::Create(channel_.get(), cq, rpcmethod_UpdateMetricsConfiguration_, context, request, false);
+}
+
+::grpc::Status NativeMetricsManagementService::Stub::GetMetric(::grpc::ClientContext* context, const ::dmi::GetMetricRequest& request, ::dmi::GetMetricResponse* response) {
+  return ::grpc::internal::BlockingUnaryCall(channel_.get(), rpcmethod_GetMetric_, context, request, response);
+}
+
+void NativeMetricsManagementService::Stub::experimental_async::GetMetric(::grpc::ClientContext* context, const ::dmi::GetMetricRequest* request, ::dmi::GetMetricResponse* response, std::function<void(::grpc::Status)> f) {
+  ::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_GetMetric_, context, request, response, std::move(f));
+}
+
+void NativeMetricsManagementService::Stub::experimental_async::GetMetric(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::GetMetricResponse* response, std::function<void(::grpc::Status)> f) {
+  ::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_GetMetric_, context, request, response, std::move(f));
+}
+
+void NativeMetricsManagementService::Stub::experimental_async::GetMetric(::grpc::ClientContext* context, const ::dmi::GetMetricRequest* request, ::dmi::GetMetricResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
+  ::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_GetMetric_, context, request, response, reactor);
+}
+
+void NativeMetricsManagementService::Stub::experimental_async::GetMetric(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::GetMetricResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
+  ::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_GetMetric_, context, request, response, reactor);
+}
+
+::grpc::ClientAsyncResponseReader< ::dmi::GetMetricResponse>* NativeMetricsManagementService::Stub::AsyncGetMetricRaw(::grpc::ClientContext* context, const ::dmi::GetMetricRequest& request, ::grpc::CompletionQueue* cq) {
+  return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::dmi::GetMetricResponse>::Create(channel_.get(), cq, rpcmethod_GetMetric_, context, request, true);
+}
+
+::grpc::ClientAsyncResponseReader< ::dmi::GetMetricResponse>* NativeMetricsManagementService::Stub::PrepareAsyncGetMetricRaw(::grpc::ClientContext* context, const ::dmi::GetMetricRequest& request, ::grpc::CompletionQueue* cq) {
+  return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::dmi::GetMetricResponse>::Create(channel_.get(), cq, rpcmethod_GetMetric_, context, request, false);
+}
+
+NativeMetricsManagementService::Service::Service() {
+  AddMethod(new ::grpc::internal::RpcServiceMethod(
+      NativeMetricsManagementService_method_names[0],
+      ::grpc::internal::RpcMethod::NORMAL_RPC,
+      new ::grpc::internal::RpcMethodHandler< NativeMetricsManagementService::Service, ::dmi::HardwareID, ::dmi::ListMetricsResponse>(
+          [](NativeMetricsManagementService::Service* service,
+             ::grpc_impl::ServerContext* ctx,
+             const ::dmi::HardwareID* req,
+             ::dmi::ListMetricsResponse* resp) {
+               return service->ListMetrics(ctx, req, resp);
+             }, this)));
+  AddMethod(new ::grpc::internal::RpcServiceMethod(
+      NativeMetricsManagementService_method_names[1],
+      ::grpc::internal::RpcMethod::NORMAL_RPC,
+      new ::grpc::internal::RpcMethodHandler< NativeMetricsManagementService::Service, ::dmi::MetricsConfigurationRequest, ::dmi::MetricsConfigurationResponse>(
+          [](NativeMetricsManagementService::Service* service,
+             ::grpc_impl::ServerContext* ctx,
+             const ::dmi::MetricsConfigurationRequest* req,
+             ::dmi::MetricsConfigurationResponse* resp) {
+               return service->UpdateMetricsConfiguration(ctx, req, resp);
+             }, this)));
+  AddMethod(new ::grpc::internal::RpcServiceMethod(
+      NativeMetricsManagementService_method_names[2],
+      ::grpc::internal::RpcMethod::NORMAL_RPC,
+      new ::grpc::internal::RpcMethodHandler< NativeMetricsManagementService::Service, ::dmi::GetMetricRequest, ::dmi::GetMetricResponse>(
+          [](NativeMetricsManagementService::Service* service,
+             ::grpc_impl::ServerContext* ctx,
+             const ::dmi::GetMetricRequest* req,
+             ::dmi::GetMetricResponse* resp) {
+               return service->GetMetric(ctx, req, resp);
+             }, this)));
+}
+
+NativeMetricsManagementService::Service::~Service() {
+}
+
+::grpc::Status NativeMetricsManagementService::Service::ListMetrics(::grpc::ServerContext* context, const ::dmi::HardwareID* request, ::dmi::ListMetricsResponse* response) {
+  (void) context;
+  (void) request;
+  (void) response;
+  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+}
+
+::grpc::Status NativeMetricsManagementService::Service::UpdateMetricsConfiguration(::grpc::ServerContext* context, const ::dmi::MetricsConfigurationRequest* request, ::dmi::MetricsConfigurationResponse* response) {
+  (void) context;
+  (void) request;
+  (void) response;
+  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+}
+
+::grpc::Status NativeMetricsManagementService::Service::GetMetric(::grpc::ServerContext* context, const ::dmi::GetMetricRequest* request, ::dmi::GetMetricResponse* response) {
+  (void) context;
+  (void) request;
+  (void) response;
+  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+}
+
+
+}  // namespace dmi
+
diff --git a/cpp/dmi/hw_metrics_mgmt_service.grpc.pb.h b/cpp/dmi/hw_metrics_mgmt_service.grpc.pb.h
new file mode 100644
index 0000000..560b350
--- /dev/null
+++ b/cpp/dmi/hw_metrics_mgmt_service.grpc.pb.h
@@ -0,0 +1,757 @@
+// Generated by the gRPC C++ plugin.
+// If you make any local change, they will be lost.
+// source: dmi/hw_metrics_mgmt_service.proto
+#ifndef GRPC_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto__INCLUDED
+#define GRPC_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto__INCLUDED
+
+#include "dmi/hw_metrics_mgmt_service.pb.h"
+
+#include <functional>
+#include <grpc/impl/codegen/port_platform.h>
+#include <grpcpp/impl/codegen/async_generic_service.h>
+#include <grpcpp/impl/codegen/async_stream.h>
+#include <grpcpp/impl/codegen/async_unary_call.h>
+#include <grpcpp/impl/codegen/client_callback.h>
+#include <grpcpp/impl/codegen/client_context.h>
+#include <grpcpp/impl/codegen/completion_queue.h>
+#include <grpcpp/impl/codegen/message_allocator.h>
+#include <grpcpp/impl/codegen/method_handler.h>
+#include <grpcpp/impl/codegen/proto_utils.h>
+#include <grpcpp/impl/codegen/rpc_method.h>
+#include <grpcpp/impl/codegen/server_callback.h>
+#include <grpcpp/impl/codegen/server_callback_handlers.h>
+#include <grpcpp/impl/codegen/server_context.h>
+#include <grpcpp/impl/codegen/service_type.h>
+#include <grpcpp/impl/codegen/status.h>
+#include <grpcpp/impl/codegen/stub_options.h>
+#include <grpcpp/impl/codegen/sync_stream.h>
+
+namespace dmi {
+
+class NativeMetricsManagementService final {
+ public:
+  static constexpr char const* service_full_name() {
+    return "dmi.NativeMetricsManagementService";
+  }
+  class StubInterface {
+   public:
+    virtual ~StubInterface() {}
+    // List the supported metrics for the passed device.
+    // This would be the first call that you make to know about the metrics that a particular device supports and
+    // then use the UpdateMetricsConfiguration API to monitor only the required metrics.
+    virtual ::grpc::Status ListMetrics(::grpc::ClientContext* context, const ::dmi::HardwareID& request, ::dmi::ListMetricsResponse* response) = 0;
+    std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::ListMetricsResponse>> AsyncListMetrics(::grpc::ClientContext* context, const ::dmi::HardwareID& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::ListMetricsResponse>>(AsyncListMetricsRaw(context, request, cq));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::ListMetricsResponse>> PrepareAsyncListMetrics(::grpc::ClientContext* context, const ::dmi::HardwareID& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::ListMetricsResponse>>(PrepareAsyncListMetricsRaw(context, request, cq));
+    }
+    // Updates the configuration of the list of metrics in the request
+    // Acts upon single metric configuration, collection of a single metric can be started/stopped
+    // by changing its configuration.
+    // 
+    // This configuration is persisted across restart of the device or the device manager
+    virtual ::grpc::Status UpdateMetricsConfiguration(::grpc::ClientContext* context, const ::dmi::MetricsConfigurationRequest& request, ::dmi::MetricsConfigurationResponse* response) = 0;
+    std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::MetricsConfigurationResponse>> AsyncUpdateMetricsConfiguration(::grpc::ClientContext* context, const ::dmi::MetricsConfigurationRequest& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::MetricsConfigurationResponse>>(AsyncUpdateMetricsConfigurationRaw(context, request, cq));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::MetricsConfigurationResponse>> PrepareAsyncUpdateMetricsConfiguration(::grpc::ClientContext* context, const ::dmi::MetricsConfigurationRequest& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::MetricsConfigurationResponse>>(PrepareAsyncUpdateMetricsConfigurationRaw(context, request, cq));
+    }
+    // Get the instantenous value of a metric
+    virtual ::grpc::Status GetMetric(::grpc::ClientContext* context, const ::dmi::GetMetricRequest& request, ::dmi::GetMetricResponse* response) = 0;
+    std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::GetMetricResponse>> AsyncGetMetric(::grpc::ClientContext* context, const ::dmi::GetMetricRequest& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::GetMetricResponse>>(AsyncGetMetricRaw(context, request, cq));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::GetMetricResponse>> PrepareAsyncGetMetric(::grpc::ClientContext* context, const ::dmi::GetMetricRequest& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::GetMetricResponse>>(PrepareAsyncGetMetricRaw(context, request, cq));
+    }
+    class experimental_async_interface {
+     public:
+      virtual ~experimental_async_interface() {}
+      // List the supported metrics for the passed device.
+      // This would be the first call that you make to know about the metrics that a particular device supports and
+      // then use the UpdateMetricsConfiguration API to monitor only the required metrics.
+      virtual void ListMetrics(::grpc::ClientContext* context, const ::dmi::HardwareID* request, ::dmi::ListMetricsResponse* response, std::function<void(::grpc::Status)>) = 0;
+      virtual void ListMetrics(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::ListMetricsResponse* response, std::function<void(::grpc::Status)>) = 0;
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      virtual void ListMetrics(::grpc::ClientContext* context, const ::dmi::HardwareID* request, ::dmi::ListMetricsResponse* response, ::grpc::ClientUnaryReactor* reactor) = 0;
+      #else
+      virtual void ListMetrics(::grpc::ClientContext* context, const ::dmi::HardwareID* request, ::dmi::ListMetricsResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) = 0;
+      #endif
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      virtual void ListMetrics(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::ListMetricsResponse* response, ::grpc::ClientUnaryReactor* reactor) = 0;
+      #else
+      virtual void ListMetrics(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::ListMetricsResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) = 0;
+      #endif
+      // Updates the configuration of the list of metrics in the request
+      // Acts upon single metric configuration, collection of a single metric can be started/stopped
+      // by changing its configuration.
+      // 
+      // This configuration is persisted across restart of the device or the device manager
+      virtual void UpdateMetricsConfiguration(::grpc::ClientContext* context, const ::dmi::MetricsConfigurationRequest* request, ::dmi::MetricsConfigurationResponse* response, std::function<void(::grpc::Status)>) = 0;
+      virtual void UpdateMetricsConfiguration(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::MetricsConfigurationResponse* response, std::function<void(::grpc::Status)>) = 0;
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      virtual void UpdateMetricsConfiguration(::grpc::ClientContext* context, const ::dmi::MetricsConfigurationRequest* request, ::dmi::MetricsConfigurationResponse* response, ::grpc::ClientUnaryReactor* reactor) = 0;
+      #else
+      virtual void UpdateMetricsConfiguration(::grpc::ClientContext* context, const ::dmi::MetricsConfigurationRequest* request, ::dmi::MetricsConfigurationResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) = 0;
+      #endif
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      virtual void UpdateMetricsConfiguration(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::MetricsConfigurationResponse* response, ::grpc::ClientUnaryReactor* reactor) = 0;
+      #else
+      virtual void UpdateMetricsConfiguration(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::MetricsConfigurationResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) = 0;
+      #endif
+      // Get the instantenous value of a metric
+      virtual void GetMetric(::grpc::ClientContext* context, const ::dmi::GetMetricRequest* request, ::dmi::GetMetricResponse* response, std::function<void(::grpc::Status)>) = 0;
+      virtual void GetMetric(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::GetMetricResponse* response, std::function<void(::grpc::Status)>) = 0;
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      virtual void GetMetric(::grpc::ClientContext* context, const ::dmi::GetMetricRequest* request, ::dmi::GetMetricResponse* response, ::grpc::ClientUnaryReactor* reactor) = 0;
+      #else
+      virtual void GetMetric(::grpc::ClientContext* context, const ::dmi::GetMetricRequest* request, ::dmi::GetMetricResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) = 0;
+      #endif
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      virtual void GetMetric(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::GetMetricResponse* response, ::grpc::ClientUnaryReactor* reactor) = 0;
+      #else
+      virtual void GetMetric(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::GetMetricResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) = 0;
+      #endif
+    };
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+    typedef class experimental_async_interface async_interface;
+    #endif
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+    async_interface* async() { return experimental_async(); }
+    #endif
+    virtual class experimental_async_interface* experimental_async() { return nullptr; }
+  private:
+    virtual ::grpc::ClientAsyncResponseReaderInterface< ::dmi::ListMetricsResponse>* AsyncListMetricsRaw(::grpc::ClientContext* context, const ::dmi::HardwareID& request, ::grpc::CompletionQueue* cq) = 0;
+    virtual ::grpc::ClientAsyncResponseReaderInterface< ::dmi::ListMetricsResponse>* PrepareAsyncListMetricsRaw(::grpc::ClientContext* context, const ::dmi::HardwareID& request, ::grpc::CompletionQueue* cq) = 0;
+    virtual ::grpc::ClientAsyncResponseReaderInterface< ::dmi::MetricsConfigurationResponse>* AsyncUpdateMetricsConfigurationRaw(::grpc::ClientContext* context, const ::dmi::MetricsConfigurationRequest& request, ::grpc::CompletionQueue* cq) = 0;
+    virtual ::grpc::ClientAsyncResponseReaderInterface< ::dmi::MetricsConfigurationResponse>* PrepareAsyncUpdateMetricsConfigurationRaw(::grpc::ClientContext* context, const ::dmi::MetricsConfigurationRequest& request, ::grpc::CompletionQueue* cq) = 0;
+    virtual ::grpc::ClientAsyncResponseReaderInterface< ::dmi::GetMetricResponse>* AsyncGetMetricRaw(::grpc::ClientContext* context, const ::dmi::GetMetricRequest& request, ::grpc::CompletionQueue* cq) = 0;
+    virtual ::grpc::ClientAsyncResponseReaderInterface< ::dmi::GetMetricResponse>* PrepareAsyncGetMetricRaw(::grpc::ClientContext* context, const ::dmi::GetMetricRequest& request, ::grpc::CompletionQueue* cq) = 0;
+  };
+  class Stub final : public StubInterface {
+   public:
+    Stub(const std::shared_ptr< ::grpc::ChannelInterface>& channel);
+    ::grpc::Status ListMetrics(::grpc::ClientContext* context, const ::dmi::HardwareID& request, ::dmi::ListMetricsResponse* response) override;
+    std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::ListMetricsResponse>> AsyncListMetrics(::grpc::ClientContext* context, const ::dmi::HardwareID& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::ListMetricsResponse>>(AsyncListMetricsRaw(context, request, cq));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::ListMetricsResponse>> PrepareAsyncListMetrics(::grpc::ClientContext* context, const ::dmi::HardwareID& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::ListMetricsResponse>>(PrepareAsyncListMetricsRaw(context, request, cq));
+    }
+    ::grpc::Status UpdateMetricsConfiguration(::grpc::ClientContext* context, const ::dmi::MetricsConfigurationRequest& request, ::dmi::MetricsConfigurationResponse* response) override;
+    std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::MetricsConfigurationResponse>> AsyncUpdateMetricsConfiguration(::grpc::ClientContext* context, const ::dmi::MetricsConfigurationRequest& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::MetricsConfigurationResponse>>(AsyncUpdateMetricsConfigurationRaw(context, request, cq));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::MetricsConfigurationResponse>> PrepareAsyncUpdateMetricsConfiguration(::grpc::ClientContext* context, const ::dmi::MetricsConfigurationRequest& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::MetricsConfigurationResponse>>(PrepareAsyncUpdateMetricsConfigurationRaw(context, request, cq));
+    }
+    ::grpc::Status GetMetric(::grpc::ClientContext* context, const ::dmi::GetMetricRequest& request, ::dmi::GetMetricResponse* response) override;
+    std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::GetMetricResponse>> AsyncGetMetric(::grpc::ClientContext* context, const ::dmi::GetMetricRequest& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::GetMetricResponse>>(AsyncGetMetricRaw(context, request, cq));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::GetMetricResponse>> PrepareAsyncGetMetric(::grpc::ClientContext* context, const ::dmi::GetMetricRequest& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::GetMetricResponse>>(PrepareAsyncGetMetricRaw(context, request, cq));
+    }
+    class experimental_async final :
+      public StubInterface::experimental_async_interface {
+     public:
+      void ListMetrics(::grpc::ClientContext* context, const ::dmi::HardwareID* request, ::dmi::ListMetricsResponse* response, std::function<void(::grpc::Status)>) override;
+      void ListMetrics(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::ListMetricsResponse* response, std::function<void(::grpc::Status)>) override;
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      void ListMetrics(::grpc::ClientContext* context, const ::dmi::HardwareID* request, ::dmi::ListMetricsResponse* response, ::grpc::ClientUnaryReactor* reactor) override;
+      #else
+      void ListMetrics(::grpc::ClientContext* context, const ::dmi::HardwareID* request, ::dmi::ListMetricsResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) override;
+      #endif
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      void ListMetrics(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::ListMetricsResponse* response, ::grpc::ClientUnaryReactor* reactor) override;
+      #else
+      void ListMetrics(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::ListMetricsResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) override;
+      #endif
+      void UpdateMetricsConfiguration(::grpc::ClientContext* context, const ::dmi::MetricsConfigurationRequest* request, ::dmi::MetricsConfigurationResponse* response, std::function<void(::grpc::Status)>) override;
+      void UpdateMetricsConfiguration(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::MetricsConfigurationResponse* response, std::function<void(::grpc::Status)>) override;
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      void UpdateMetricsConfiguration(::grpc::ClientContext* context, const ::dmi::MetricsConfigurationRequest* request, ::dmi::MetricsConfigurationResponse* response, ::grpc::ClientUnaryReactor* reactor) override;
+      #else
+      void UpdateMetricsConfiguration(::grpc::ClientContext* context, const ::dmi::MetricsConfigurationRequest* request, ::dmi::MetricsConfigurationResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) override;
+      #endif
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      void UpdateMetricsConfiguration(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::MetricsConfigurationResponse* response, ::grpc::ClientUnaryReactor* reactor) override;
+      #else
+      void UpdateMetricsConfiguration(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::MetricsConfigurationResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) override;
+      #endif
+      void GetMetric(::grpc::ClientContext* context, const ::dmi::GetMetricRequest* request, ::dmi::GetMetricResponse* response, std::function<void(::grpc::Status)>) override;
+      void GetMetric(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::GetMetricResponse* response, std::function<void(::grpc::Status)>) override;
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      void GetMetric(::grpc::ClientContext* context, const ::dmi::GetMetricRequest* request, ::dmi::GetMetricResponse* response, ::grpc::ClientUnaryReactor* reactor) override;
+      #else
+      void GetMetric(::grpc::ClientContext* context, const ::dmi::GetMetricRequest* request, ::dmi::GetMetricResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) override;
+      #endif
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      void GetMetric(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::GetMetricResponse* response, ::grpc::ClientUnaryReactor* reactor) override;
+      #else
+      void GetMetric(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::GetMetricResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) override;
+      #endif
+     private:
+      friend class Stub;
+      explicit experimental_async(Stub* stub): stub_(stub) { }
+      Stub* stub() { return stub_; }
+      Stub* stub_;
+    };
+    class experimental_async_interface* experimental_async() override { return &async_stub_; }
+
+   private:
+    std::shared_ptr< ::grpc::ChannelInterface> channel_;
+    class experimental_async async_stub_{this};
+    ::grpc::ClientAsyncResponseReader< ::dmi::ListMetricsResponse>* AsyncListMetricsRaw(::grpc::ClientContext* context, const ::dmi::HardwareID& request, ::grpc::CompletionQueue* cq) override;
+    ::grpc::ClientAsyncResponseReader< ::dmi::ListMetricsResponse>* PrepareAsyncListMetricsRaw(::grpc::ClientContext* context, const ::dmi::HardwareID& request, ::grpc::CompletionQueue* cq) override;
+    ::grpc::ClientAsyncResponseReader< ::dmi::MetricsConfigurationResponse>* AsyncUpdateMetricsConfigurationRaw(::grpc::ClientContext* context, const ::dmi::MetricsConfigurationRequest& request, ::grpc::CompletionQueue* cq) override;
+    ::grpc::ClientAsyncResponseReader< ::dmi::MetricsConfigurationResponse>* PrepareAsyncUpdateMetricsConfigurationRaw(::grpc::ClientContext* context, const ::dmi::MetricsConfigurationRequest& request, ::grpc::CompletionQueue* cq) override;
+    ::grpc::ClientAsyncResponseReader< ::dmi::GetMetricResponse>* AsyncGetMetricRaw(::grpc::ClientContext* context, const ::dmi::GetMetricRequest& request, ::grpc::CompletionQueue* cq) override;
+    ::grpc::ClientAsyncResponseReader< ::dmi::GetMetricResponse>* PrepareAsyncGetMetricRaw(::grpc::ClientContext* context, const ::dmi::GetMetricRequest& request, ::grpc::CompletionQueue* cq) override;
+    const ::grpc::internal::RpcMethod rpcmethod_ListMetrics_;
+    const ::grpc::internal::RpcMethod rpcmethod_UpdateMetricsConfiguration_;
+    const ::grpc::internal::RpcMethod rpcmethod_GetMetric_;
+  };
+  static std::unique_ptr<Stub> NewStub(const std::shared_ptr< ::grpc::ChannelInterface>& channel, const ::grpc::StubOptions& options = ::grpc::StubOptions());
+
+  class Service : public ::grpc::Service {
+   public:
+    Service();
+    virtual ~Service();
+    // List the supported metrics for the passed device.
+    // This would be the first call that you make to know about the metrics that a particular device supports and
+    // then use the UpdateMetricsConfiguration API to monitor only the required metrics.
+    virtual ::grpc::Status ListMetrics(::grpc::ServerContext* context, const ::dmi::HardwareID* request, ::dmi::ListMetricsResponse* response);
+    // Updates the configuration of the list of metrics in the request
+    // Acts upon single metric configuration, collection of a single metric can be started/stopped
+    // by changing its configuration.
+    // 
+    // This configuration is persisted across restart of the device or the device manager
+    virtual ::grpc::Status UpdateMetricsConfiguration(::grpc::ServerContext* context, const ::dmi::MetricsConfigurationRequest* request, ::dmi::MetricsConfigurationResponse* response);
+    // Get the instantenous value of a metric
+    virtual ::grpc::Status GetMetric(::grpc::ServerContext* context, const ::dmi::GetMetricRequest* request, ::dmi::GetMetricResponse* response);
+  };
+  template <class BaseClass>
+  class WithAsyncMethod_ListMetrics : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithAsyncMethod_ListMetrics() {
+      ::grpc::Service::MarkMethodAsync(0);
+    }
+    ~WithAsyncMethod_ListMetrics() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status ListMetrics(::grpc::ServerContext* /*context*/, const ::dmi::HardwareID* /*request*/, ::dmi::ListMetricsResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    void RequestListMetrics(::grpc::ServerContext* context, ::dmi::HardwareID* request, ::grpc::ServerAsyncResponseWriter< ::dmi::ListMetricsResponse>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+      ::grpc::Service::RequestAsyncUnary(0, context, request, response, new_call_cq, notification_cq, tag);
+    }
+  };
+  template <class BaseClass>
+  class WithAsyncMethod_UpdateMetricsConfiguration : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithAsyncMethod_UpdateMetricsConfiguration() {
+      ::grpc::Service::MarkMethodAsync(1);
+    }
+    ~WithAsyncMethod_UpdateMetricsConfiguration() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status UpdateMetricsConfiguration(::grpc::ServerContext* /*context*/, const ::dmi::MetricsConfigurationRequest* /*request*/, ::dmi::MetricsConfigurationResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    void RequestUpdateMetricsConfiguration(::grpc::ServerContext* context, ::dmi::MetricsConfigurationRequest* request, ::grpc::ServerAsyncResponseWriter< ::dmi::MetricsConfigurationResponse>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+      ::grpc::Service::RequestAsyncUnary(1, context, request, response, new_call_cq, notification_cq, tag);
+    }
+  };
+  template <class BaseClass>
+  class WithAsyncMethod_GetMetric : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithAsyncMethod_GetMetric() {
+      ::grpc::Service::MarkMethodAsync(2);
+    }
+    ~WithAsyncMethod_GetMetric() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status GetMetric(::grpc::ServerContext* /*context*/, const ::dmi::GetMetricRequest* /*request*/, ::dmi::GetMetricResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    void RequestGetMetric(::grpc::ServerContext* context, ::dmi::GetMetricRequest* request, ::grpc::ServerAsyncResponseWriter< ::dmi::GetMetricResponse>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+      ::grpc::Service::RequestAsyncUnary(2, context, request, response, new_call_cq, notification_cq, tag);
+    }
+  };
+  typedef WithAsyncMethod_ListMetrics<WithAsyncMethod_UpdateMetricsConfiguration<WithAsyncMethod_GetMetric<Service > > > AsyncService;
+  template <class BaseClass>
+  class ExperimentalWithCallbackMethod_ListMetrics : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    ExperimentalWithCallbackMethod_ListMetrics() {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::Service::
+    #else
+      ::grpc::Service::experimental().
+    #endif
+        MarkMethodCallback(0,
+          new ::grpc_impl::internal::CallbackUnaryHandler< ::dmi::HardwareID, ::dmi::ListMetricsResponse>(
+            [this](
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+                   ::grpc::CallbackServerContext*
+    #else
+                   ::grpc::experimental::CallbackServerContext*
+    #endif
+                     context, const ::dmi::HardwareID* request, ::dmi::ListMetricsResponse* response) { return this->ListMetrics(context, request, response); }));}
+    void SetMessageAllocatorFor_ListMetrics(
+        ::grpc::experimental::MessageAllocator< ::dmi::HardwareID, ::dmi::ListMetricsResponse>* allocator) {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(0);
+    #else
+      ::grpc::internal::MethodHandler* const handler = ::grpc::Service::experimental().GetHandler(0);
+    #endif
+      static_cast<::grpc_impl::internal::CallbackUnaryHandler< ::dmi::HardwareID, ::dmi::ListMetricsResponse>*>(handler)
+              ->SetMessageAllocator(allocator);
+    }
+    ~ExperimentalWithCallbackMethod_ListMetrics() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status ListMetrics(::grpc::ServerContext* /*context*/, const ::dmi::HardwareID* /*request*/, ::dmi::ListMetricsResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+    virtual ::grpc::ServerUnaryReactor* ListMetrics(
+      ::grpc::CallbackServerContext* /*context*/, const ::dmi::HardwareID* /*request*/, ::dmi::ListMetricsResponse* /*response*/)
+    #else
+    virtual ::grpc::experimental::ServerUnaryReactor* ListMetrics(
+      ::grpc::experimental::CallbackServerContext* /*context*/, const ::dmi::HardwareID* /*request*/, ::dmi::ListMetricsResponse* /*response*/)
+    #endif
+      { return nullptr; }
+  };
+  template <class BaseClass>
+  class ExperimentalWithCallbackMethod_UpdateMetricsConfiguration : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    ExperimentalWithCallbackMethod_UpdateMetricsConfiguration() {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::Service::
+    #else
+      ::grpc::Service::experimental().
+    #endif
+        MarkMethodCallback(1,
+          new ::grpc_impl::internal::CallbackUnaryHandler< ::dmi::MetricsConfigurationRequest, ::dmi::MetricsConfigurationResponse>(
+            [this](
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+                   ::grpc::CallbackServerContext*
+    #else
+                   ::grpc::experimental::CallbackServerContext*
+    #endif
+                     context, const ::dmi::MetricsConfigurationRequest* request, ::dmi::MetricsConfigurationResponse* response) { return this->UpdateMetricsConfiguration(context, request, response); }));}
+    void SetMessageAllocatorFor_UpdateMetricsConfiguration(
+        ::grpc::experimental::MessageAllocator< ::dmi::MetricsConfigurationRequest, ::dmi::MetricsConfigurationResponse>* allocator) {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(1);
+    #else
+      ::grpc::internal::MethodHandler* const handler = ::grpc::Service::experimental().GetHandler(1);
+    #endif
+      static_cast<::grpc_impl::internal::CallbackUnaryHandler< ::dmi::MetricsConfigurationRequest, ::dmi::MetricsConfigurationResponse>*>(handler)
+              ->SetMessageAllocator(allocator);
+    }
+    ~ExperimentalWithCallbackMethod_UpdateMetricsConfiguration() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status UpdateMetricsConfiguration(::grpc::ServerContext* /*context*/, const ::dmi::MetricsConfigurationRequest* /*request*/, ::dmi::MetricsConfigurationResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+    virtual ::grpc::ServerUnaryReactor* UpdateMetricsConfiguration(
+      ::grpc::CallbackServerContext* /*context*/, const ::dmi::MetricsConfigurationRequest* /*request*/, ::dmi::MetricsConfigurationResponse* /*response*/)
+    #else
+    virtual ::grpc::experimental::ServerUnaryReactor* UpdateMetricsConfiguration(
+      ::grpc::experimental::CallbackServerContext* /*context*/, const ::dmi::MetricsConfigurationRequest* /*request*/, ::dmi::MetricsConfigurationResponse* /*response*/)
+    #endif
+      { return nullptr; }
+  };
+  template <class BaseClass>
+  class ExperimentalWithCallbackMethod_GetMetric : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    ExperimentalWithCallbackMethod_GetMetric() {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::Service::
+    #else
+      ::grpc::Service::experimental().
+    #endif
+        MarkMethodCallback(2,
+          new ::grpc_impl::internal::CallbackUnaryHandler< ::dmi::GetMetricRequest, ::dmi::GetMetricResponse>(
+            [this](
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+                   ::grpc::CallbackServerContext*
+    #else
+                   ::grpc::experimental::CallbackServerContext*
+    #endif
+                     context, const ::dmi::GetMetricRequest* request, ::dmi::GetMetricResponse* response) { return this->GetMetric(context, request, response); }));}
+    void SetMessageAllocatorFor_GetMetric(
+        ::grpc::experimental::MessageAllocator< ::dmi::GetMetricRequest, ::dmi::GetMetricResponse>* allocator) {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(2);
+    #else
+      ::grpc::internal::MethodHandler* const handler = ::grpc::Service::experimental().GetHandler(2);
+    #endif
+      static_cast<::grpc_impl::internal::CallbackUnaryHandler< ::dmi::GetMetricRequest, ::dmi::GetMetricResponse>*>(handler)
+              ->SetMessageAllocator(allocator);
+    }
+    ~ExperimentalWithCallbackMethod_GetMetric() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status GetMetric(::grpc::ServerContext* /*context*/, const ::dmi::GetMetricRequest* /*request*/, ::dmi::GetMetricResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+    virtual ::grpc::ServerUnaryReactor* GetMetric(
+      ::grpc::CallbackServerContext* /*context*/, const ::dmi::GetMetricRequest* /*request*/, ::dmi::GetMetricResponse* /*response*/)
+    #else
+    virtual ::grpc::experimental::ServerUnaryReactor* GetMetric(
+      ::grpc::experimental::CallbackServerContext* /*context*/, const ::dmi::GetMetricRequest* /*request*/, ::dmi::GetMetricResponse* /*response*/)
+    #endif
+      { return nullptr; }
+  };
+  #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+  typedef ExperimentalWithCallbackMethod_ListMetrics<ExperimentalWithCallbackMethod_UpdateMetricsConfiguration<ExperimentalWithCallbackMethod_GetMetric<Service > > > CallbackService;
+  #endif
+
+  typedef ExperimentalWithCallbackMethod_ListMetrics<ExperimentalWithCallbackMethod_UpdateMetricsConfiguration<ExperimentalWithCallbackMethod_GetMetric<Service > > > ExperimentalCallbackService;
+  template <class BaseClass>
+  class WithGenericMethod_ListMetrics : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithGenericMethod_ListMetrics() {
+      ::grpc::Service::MarkMethodGeneric(0);
+    }
+    ~WithGenericMethod_ListMetrics() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status ListMetrics(::grpc::ServerContext* /*context*/, const ::dmi::HardwareID* /*request*/, ::dmi::ListMetricsResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+  };
+  template <class BaseClass>
+  class WithGenericMethod_UpdateMetricsConfiguration : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithGenericMethod_UpdateMetricsConfiguration() {
+      ::grpc::Service::MarkMethodGeneric(1);
+    }
+    ~WithGenericMethod_UpdateMetricsConfiguration() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status UpdateMetricsConfiguration(::grpc::ServerContext* /*context*/, const ::dmi::MetricsConfigurationRequest* /*request*/, ::dmi::MetricsConfigurationResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+  };
+  template <class BaseClass>
+  class WithGenericMethod_GetMetric : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithGenericMethod_GetMetric() {
+      ::grpc::Service::MarkMethodGeneric(2);
+    }
+    ~WithGenericMethod_GetMetric() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status GetMetric(::grpc::ServerContext* /*context*/, const ::dmi::GetMetricRequest* /*request*/, ::dmi::GetMetricResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+  };
+  template <class BaseClass>
+  class WithRawMethod_ListMetrics : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithRawMethod_ListMetrics() {
+      ::grpc::Service::MarkMethodRaw(0);
+    }
+    ~WithRawMethod_ListMetrics() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status ListMetrics(::grpc::ServerContext* /*context*/, const ::dmi::HardwareID* /*request*/, ::dmi::ListMetricsResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    void RequestListMetrics(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+      ::grpc::Service::RequestAsyncUnary(0, context, request, response, new_call_cq, notification_cq, tag);
+    }
+  };
+  template <class BaseClass>
+  class WithRawMethod_UpdateMetricsConfiguration : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithRawMethod_UpdateMetricsConfiguration() {
+      ::grpc::Service::MarkMethodRaw(1);
+    }
+    ~WithRawMethod_UpdateMetricsConfiguration() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status UpdateMetricsConfiguration(::grpc::ServerContext* /*context*/, const ::dmi::MetricsConfigurationRequest* /*request*/, ::dmi::MetricsConfigurationResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    void RequestUpdateMetricsConfiguration(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+      ::grpc::Service::RequestAsyncUnary(1, context, request, response, new_call_cq, notification_cq, tag);
+    }
+  };
+  template <class BaseClass>
+  class WithRawMethod_GetMetric : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithRawMethod_GetMetric() {
+      ::grpc::Service::MarkMethodRaw(2);
+    }
+    ~WithRawMethod_GetMetric() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status GetMetric(::grpc::ServerContext* /*context*/, const ::dmi::GetMetricRequest* /*request*/, ::dmi::GetMetricResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    void RequestGetMetric(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+      ::grpc::Service::RequestAsyncUnary(2, context, request, response, new_call_cq, notification_cq, tag);
+    }
+  };
+  template <class BaseClass>
+  class ExperimentalWithRawCallbackMethod_ListMetrics : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    ExperimentalWithRawCallbackMethod_ListMetrics() {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::Service::
+    #else
+      ::grpc::Service::experimental().
+    #endif
+        MarkMethodRawCallback(0,
+          new ::grpc_impl::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>(
+            [this](
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+                   ::grpc::CallbackServerContext*
+    #else
+                   ::grpc::experimental::CallbackServerContext*
+    #endif
+                     context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response) { return this->ListMetrics(context, request, response); }));
+    }
+    ~ExperimentalWithRawCallbackMethod_ListMetrics() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status ListMetrics(::grpc::ServerContext* /*context*/, const ::dmi::HardwareID* /*request*/, ::dmi::ListMetricsResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+    virtual ::grpc::ServerUnaryReactor* ListMetrics(
+      ::grpc::CallbackServerContext* /*context*/, const ::grpc::ByteBuffer* /*request*/, ::grpc::ByteBuffer* /*response*/)
+    #else
+    virtual ::grpc::experimental::ServerUnaryReactor* ListMetrics(
+      ::grpc::experimental::CallbackServerContext* /*context*/, const ::grpc::ByteBuffer* /*request*/, ::grpc::ByteBuffer* /*response*/)
+    #endif
+      { return nullptr; }
+  };
+  template <class BaseClass>
+  class ExperimentalWithRawCallbackMethod_UpdateMetricsConfiguration : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    ExperimentalWithRawCallbackMethod_UpdateMetricsConfiguration() {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::Service::
+    #else
+      ::grpc::Service::experimental().
+    #endif
+        MarkMethodRawCallback(1,
+          new ::grpc_impl::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>(
+            [this](
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+                   ::grpc::CallbackServerContext*
+    #else
+                   ::grpc::experimental::CallbackServerContext*
+    #endif
+                     context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response) { return this->UpdateMetricsConfiguration(context, request, response); }));
+    }
+    ~ExperimentalWithRawCallbackMethod_UpdateMetricsConfiguration() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status UpdateMetricsConfiguration(::grpc::ServerContext* /*context*/, const ::dmi::MetricsConfigurationRequest* /*request*/, ::dmi::MetricsConfigurationResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+    virtual ::grpc::ServerUnaryReactor* UpdateMetricsConfiguration(
+      ::grpc::CallbackServerContext* /*context*/, const ::grpc::ByteBuffer* /*request*/, ::grpc::ByteBuffer* /*response*/)
+    #else
+    virtual ::grpc::experimental::ServerUnaryReactor* UpdateMetricsConfiguration(
+      ::grpc::experimental::CallbackServerContext* /*context*/, const ::grpc::ByteBuffer* /*request*/, ::grpc::ByteBuffer* /*response*/)
+    #endif
+      { return nullptr; }
+  };
+  template <class BaseClass>
+  class ExperimentalWithRawCallbackMethod_GetMetric : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    ExperimentalWithRawCallbackMethod_GetMetric() {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::Service::
+    #else
+      ::grpc::Service::experimental().
+    #endif
+        MarkMethodRawCallback(2,
+          new ::grpc_impl::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>(
+            [this](
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+                   ::grpc::CallbackServerContext*
+    #else
+                   ::grpc::experimental::CallbackServerContext*
+    #endif
+                     context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response) { return this->GetMetric(context, request, response); }));
+    }
+    ~ExperimentalWithRawCallbackMethod_GetMetric() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status GetMetric(::grpc::ServerContext* /*context*/, const ::dmi::GetMetricRequest* /*request*/, ::dmi::GetMetricResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+    virtual ::grpc::ServerUnaryReactor* GetMetric(
+      ::grpc::CallbackServerContext* /*context*/, const ::grpc::ByteBuffer* /*request*/, ::grpc::ByteBuffer* /*response*/)
+    #else
+    virtual ::grpc::experimental::ServerUnaryReactor* GetMetric(
+      ::grpc::experimental::CallbackServerContext* /*context*/, const ::grpc::ByteBuffer* /*request*/, ::grpc::ByteBuffer* /*response*/)
+    #endif
+      { return nullptr; }
+  };
+  template <class BaseClass>
+  class WithStreamedUnaryMethod_ListMetrics : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithStreamedUnaryMethod_ListMetrics() {
+      ::grpc::Service::MarkMethodStreamed(0,
+        new ::grpc::internal::StreamedUnaryHandler<
+          ::dmi::HardwareID, ::dmi::ListMetricsResponse>(
+            [this](::grpc_impl::ServerContext* context,
+                   ::grpc_impl::ServerUnaryStreamer<
+                     ::dmi::HardwareID, ::dmi::ListMetricsResponse>* streamer) {
+                       return this->StreamedListMetrics(context,
+                         streamer);
+                  }));
+    }
+    ~WithStreamedUnaryMethod_ListMetrics() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable regular version of this method
+    ::grpc::Status ListMetrics(::grpc::ServerContext* /*context*/, const ::dmi::HardwareID* /*request*/, ::dmi::ListMetricsResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    // replace default version of method with streamed unary
+    virtual ::grpc::Status StreamedListMetrics(::grpc::ServerContext* context, ::grpc::ServerUnaryStreamer< ::dmi::HardwareID,::dmi::ListMetricsResponse>* server_unary_streamer) = 0;
+  };
+  template <class BaseClass>
+  class WithStreamedUnaryMethod_UpdateMetricsConfiguration : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithStreamedUnaryMethod_UpdateMetricsConfiguration() {
+      ::grpc::Service::MarkMethodStreamed(1,
+        new ::grpc::internal::StreamedUnaryHandler<
+          ::dmi::MetricsConfigurationRequest, ::dmi::MetricsConfigurationResponse>(
+            [this](::grpc_impl::ServerContext* context,
+                   ::grpc_impl::ServerUnaryStreamer<
+                     ::dmi::MetricsConfigurationRequest, ::dmi::MetricsConfigurationResponse>* streamer) {
+                       return this->StreamedUpdateMetricsConfiguration(context,
+                         streamer);
+                  }));
+    }
+    ~WithStreamedUnaryMethod_UpdateMetricsConfiguration() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable regular version of this method
+    ::grpc::Status UpdateMetricsConfiguration(::grpc::ServerContext* /*context*/, const ::dmi::MetricsConfigurationRequest* /*request*/, ::dmi::MetricsConfigurationResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    // replace default version of method with streamed unary
+    virtual ::grpc::Status StreamedUpdateMetricsConfiguration(::grpc::ServerContext* context, ::grpc::ServerUnaryStreamer< ::dmi::MetricsConfigurationRequest,::dmi::MetricsConfigurationResponse>* server_unary_streamer) = 0;
+  };
+  template <class BaseClass>
+  class WithStreamedUnaryMethod_GetMetric : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithStreamedUnaryMethod_GetMetric() {
+      ::grpc::Service::MarkMethodStreamed(2,
+        new ::grpc::internal::StreamedUnaryHandler<
+          ::dmi::GetMetricRequest, ::dmi::GetMetricResponse>(
+            [this](::grpc_impl::ServerContext* context,
+                   ::grpc_impl::ServerUnaryStreamer<
+                     ::dmi::GetMetricRequest, ::dmi::GetMetricResponse>* streamer) {
+                       return this->StreamedGetMetric(context,
+                         streamer);
+                  }));
+    }
+    ~WithStreamedUnaryMethod_GetMetric() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable regular version of this method
+    ::grpc::Status GetMetric(::grpc::ServerContext* /*context*/, const ::dmi::GetMetricRequest* /*request*/, ::dmi::GetMetricResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    // replace default version of method with streamed unary
+    virtual ::grpc::Status StreamedGetMetric(::grpc::ServerContext* context, ::grpc::ServerUnaryStreamer< ::dmi::GetMetricRequest,::dmi::GetMetricResponse>* server_unary_streamer) = 0;
+  };
+  typedef WithStreamedUnaryMethod_ListMetrics<WithStreamedUnaryMethod_UpdateMetricsConfiguration<WithStreamedUnaryMethod_GetMetric<Service > > > StreamedUnaryService;
+  typedef Service SplitStreamedService;
+  typedef WithStreamedUnaryMethod_ListMetrics<WithStreamedUnaryMethod_UpdateMetricsConfiguration<WithStreamedUnaryMethod_GetMetric<Service > > > StreamedService;
+};
+
+}  // namespace dmi
+
+
+#endif  // GRPC_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto__INCLUDED
diff --git a/cpp/dmi/sw_image.grpc.pb.cc b/cpp/dmi/sw_image.grpc.pb.cc
new file mode 100644
index 0000000..fc722bc
--- /dev/null
+++ b/cpp/dmi/sw_image.grpc.pb.cc
@@ -0,0 +1,25 @@
+// Generated by the gRPC C++ plugin.
+// If you make any local change, they will be lost.
+// source: dmi/sw_image.proto
+
+#include "dmi/sw_image.pb.h"
+#include "dmi/sw_image.grpc.pb.h"
+
+#include <functional>
+#include <grpcpp/impl/codegen/async_stream.h>
+#include <grpcpp/impl/codegen/async_unary_call.h>
+#include <grpcpp/impl/codegen/channel_interface.h>
+#include <grpcpp/impl/codegen/client_unary_call.h>
+#include <grpcpp/impl/codegen/client_callback.h>
+#include <grpcpp/impl/codegen/message_allocator.h>
+#include <grpcpp/impl/codegen/method_handler.h>
+#include <grpcpp/impl/codegen/rpc_service_method.h>
+#include <grpcpp/impl/codegen/server_callback.h>
+#include <grpcpp/impl/codegen/server_callback_handlers.h>
+#include <grpcpp/impl/codegen/server_context.h>
+#include <grpcpp/impl/codegen/service_type.h>
+#include <grpcpp/impl/codegen/sync_stream.h>
+namespace dmi {
+
+}  // namespace dmi
+
diff --git a/cpp/dmi/sw_image.grpc.pb.h b/cpp/dmi/sw_image.grpc.pb.h
new file mode 100644
index 0000000..9946afe
--- /dev/null
+++ b/cpp/dmi/sw_image.grpc.pb.h
@@ -0,0 +1,34 @@
+// Generated by the gRPC C++ plugin.
+// If you make any local change, they will be lost.
+// source: dmi/sw_image.proto
+#ifndef GRPC_dmi_2fsw_5fimage_2eproto__INCLUDED
+#define GRPC_dmi_2fsw_5fimage_2eproto__INCLUDED
+
+#include "dmi/sw_image.pb.h"
+
+#include <functional>
+#include <grpc/impl/codegen/port_platform.h>
+#include <grpcpp/impl/codegen/async_generic_service.h>
+#include <grpcpp/impl/codegen/async_stream.h>
+#include <grpcpp/impl/codegen/async_unary_call.h>
+#include <grpcpp/impl/codegen/client_callback.h>
+#include <grpcpp/impl/codegen/client_context.h>
+#include <grpcpp/impl/codegen/completion_queue.h>
+#include <grpcpp/impl/codegen/message_allocator.h>
+#include <grpcpp/impl/codegen/method_handler.h>
+#include <grpcpp/impl/codegen/proto_utils.h>
+#include <grpcpp/impl/codegen/rpc_method.h>
+#include <grpcpp/impl/codegen/server_callback.h>
+#include <grpcpp/impl/codegen/server_callback_handlers.h>
+#include <grpcpp/impl/codegen/server_context.h>
+#include <grpcpp/impl/codegen/service_type.h>
+#include <grpcpp/impl/codegen/status.h>
+#include <grpcpp/impl/codegen/stub_options.h>
+#include <grpcpp/impl/codegen/sync_stream.h>
+
+namespace dmi {
+
+}  // namespace dmi
+
+
+#endif  // GRPC_dmi_2fsw_5fimage_2eproto__INCLUDED
diff --git a/cpp/dmi/sw_management_service.grpc.pb.cc b/cpp/dmi/sw_management_service.grpc.pb.cc
new file mode 100644
index 0000000..975b684
--- /dev/null
+++ b/cpp/dmi/sw_management_service.grpc.pb.cc
@@ -0,0 +1,278 @@
+// Generated by the gRPC C++ plugin.
+// If you make any local change, they will be lost.
+// source: dmi/sw_management_service.proto
+
+#include "dmi/sw_management_service.pb.h"
+#include "dmi/sw_management_service.grpc.pb.h"
+
+#include <functional>
+#include <grpcpp/impl/codegen/async_stream.h>
+#include <grpcpp/impl/codegen/async_unary_call.h>
+#include <grpcpp/impl/codegen/channel_interface.h>
+#include <grpcpp/impl/codegen/client_unary_call.h>
+#include <grpcpp/impl/codegen/client_callback.h>
+#include <grpcpp/impl/codegen/message_allocator.h>
+#include <grpcpp/impl/codegen/method_handler.h>
+#include <grpcpp/impl/codegen/rpc_service_method.h>
+#include <grpcpp/impl/codegen/server_callback.h>
+#include <grpcpp/impl/codegen/server_callback_handlers.h>
+#include <grpcpp/impl/codegen/server_context.h>
+#include <grpcpp/impl/codegen/service_type.h>
+#include <grpcpp/impl/codegen/sync_stream.h>
+namespace dmi {
+
+static const char* NativeSoftwareManagementService_method_names[] = {
+  "/dmi.NativeSoftwareManagementService/GetSoftwareVersion",
+  "/dmi.NativeSoftwareManagementService/DownloadImage",
+  "/dmi.NativeSoftwareManagementService/ActivateImage",
+  "/dmi.NativeSoftwareManagementService/RevertToStandbyImage",
+  "/dmi.NativeSoftwareManagementService/UpdateStartupConfiguration",
+  "/dmi.NativeSoftwareManagementService/GetStartupConfigurationInfo",
+};
+
+std::unique_ptr< NativeSoftwareManagementService::Stub> NativeSoftwareManagementService::NewStub(const std::shared_ptr< ::grpc::ChannelInterface>& channel, const ::grpc::StubOptions& options) {
+  (void)options;
+  std::unique_ptr< NativeSoftwareManagementService::Stub> stub(new NativeSoftwareManagementService::Stub(channel));
+  return stub;
+}
+
+NativeSoftwareManagementService::Stub::Stub(const std::shared_ptr< ::grpc::ChannelInterface>& channel)
+  : channel_(channel), rpcmethod_GetSoftwareVersion_(NativeSoftwareManagementService_method_names[0], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
+  , rpcmethod_DownloadImage_(NativeSoftwareManagementService_method_names[1], ::grpc::internal::RpcMethod::SERVER_STREAMING, channel)
+  , rpcmethod_ActivateImage_(NativeSoftwareManagementService_method_names[2], ::grpc::internal::RpcMethod::SERVER_STREAMING, channel)
+  , rpcmethod_RevertToStandbyImage_(NativeSoftwareManagementService_method_names[3], ::grpc::internal::RpcMethod::SERVER_STREAMING, channel)
+  , rpcmethod_UpdateStartupConfiguration_(NativeSoftwareManagementService_method_names[4], ::grpc::internal::RpcMethod::SERVER_STREAMING, channel)
+  , rpcmethod_GetStartupConfigurationInfo_(NativeSoftwareManagementService_method_names[5], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
+  {}
+
+::grpc::Status NativeSoftwareManagementService::Stub::GetSoftwareVersion(::grpc::ClientContext* context, const ::dmi::HardwareID& request, ::dmi::GetSoftwareVersionInformationResponse* response) {
+  return ::grpc::internal::BlockingUnaryCall(channel_.get(), rpcmethod_GetSoftwareVersion_, context, request, response);
+}
+
+void NativeSoftwareManagementService::Stub::experimental_async::GetSoftwareVersion(::grpc::ClientContext* context, const ::dmi::HardwareID* request, ::dmi::GetSoftwareVersionInformationResponse* response, std::function<void(::grpc::Status)> f) {
+  ::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_GetSoftwareVersion_, context, request, response, std::move(f));
+}
+
+void NativeSoftwareManagementService::Stub::experimental_async::GetSoftwareVersion(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::GetSoftwareVersionInformationResponse* response, std::function<void(::grpc::Status)> f) {
+  ::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_GetSoftwareVersion_, context, request, response, std::move(f));
+}
+
+void NativeSoftwareManagementService::Stub::experimental_async::GetSoftwareVersion(::grpc::ClientContext* context, const ::dmi::HardwareID* request, ::dmi::GetSoftwareVersionInformationResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
+  ::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_GetSoftwareVersion_, context, request, response, reactor);
+}
+
+void NativeSoftwareManagementService::Stub::experimental_async::GetSoftwareVersion(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::GetSoftwareVersionInformationResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
+  ::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_GetSoftwareVersion_, context, request, response, reactor);
+}
+
+::grpc::ClientAsyncResponseReader< ::dmi::GetSoftwareVersionInformationResponse>* NativeSoftwareManagementService::Stub::AsyncGetSoftwareVersionRaw(::grpc::ClientContext* context, const ::dmi::HardwareID& request, ::grpc::CompletionQueue* cq) {
+  return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::dmi::GetSoftwareVersionInformationResponse>::Create(channel_.get(), cq, rpcmethod_GetSoftwareVersion_, context, request, true);
+}
+
+::grpc::ClientAsyncResponseReader< ::dmi::GetSoftwareVersionInformationResponse>* NativeSoftwareManagementService::Stub::PrepareAsyncGetSoftwareVersionRaw(::grpc::ClientContext* context, const ::dmi::HardwareID& request, ::grpc::CompletionQueue* cq) {
+  return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::dmi::GetSoftwareVersionInformationResponse>::Create(channel_.get(), cq, rpcmethod_GetSoftwareVersion_, context, request, false);
+}
+
+::grpc::ClientReader< ::dmi::ImageStatus>* NativeSoftwareManagementService::Stub::DownloadImageRaw(::grpc::ClientContext* context, const ::dmi::DownloadImageRequest& request) {
+  return ::grpc_impl::internal::ClientReaderFactory< ::dmi::ImageStatus>::Create(channel_.get(), rpcmethod_DownloadImage_, context, request);
+}
+
+void NativeSoftwareManagementService::Stub::experimental_async::DownloadImage(::grpc::ClientContext* context, ::dmi::DownloadImageRequest* request, ::grpc::experimental::ClientReadReactor< ::dmi::ImageStatus>* reactor) {
+  ::grpc_impl::internal::ClientCallbackReaderFactory< ::dmi::ImageStatus>::Create(stub_->channel_.get(), stub_->rpcmethod_DownloadImage_, context, request, reactor);
+}
+
+::grpc::ClientAsyncReader< ::dmi::ImageStatus>* NativeSoftwareManagementService::Stub::AsyncDownloadImageRaw(::grpc::ClientContext* context, const ::dmi::DownloadImageRequest& request, ::grpc::CompletionQueue* cq, void* tag) {
+  return ::grpc_impl::internal::ClientAsyncReaderFactory< ::dmi::ImageStatus>::Create(channel_.get(), cq, rpcmethod_DownloadImage_, context, request, true, tag);
+}
+
+::grpc::ClientAsyncReader< ::dmi::ImageStatus>* NativeSoftwareManagementService::Stub::PrepareAsyncDownloadImageRaw(::grpc::ClientContext* context, const ::dmi::DownloadImageRequest& request, ::grpc::CompletionQueue* cq) {
+  return ::grpc_impl::internal::ClientAsyncReaderFactory< ::dmi::ImageStatus>::Create(channel_.get(), cq, rpcmethod_DownloadImage_, context, request, false, nullptr);
+}
+
+::grpc::ClientReader< ::dmi::ImageStatus>* NativeSoftwareManagementService::Stub::ActivateImageRaw(::grpc::ClientContext* context, const ::dmi::HardwareID& request) {
+  return ::grpc_impl::internal::ClientReaderFactory< ::dmi::ImageStatus>::Create(channel_.get(), rpcmethod_ActivateImage_, context, request);
+}
+
+void NativeSoftwareManagementService::Stub::experimental_async::ActivateImage(::grpc::ClientContext* context, ::dmi::HardwareID* request, ::grpc::experimental::ClientReadReactor< ::dmi::ImageStatus>* reactor) {
+  ::grpc_impl::internal::ClientCallbackReaderFactory< ::dmi::ImageStatus>::Create(stub_->channel_.get(), stub_->rpcmethod_ActivateImage_, context, request, reactor);
+}
+
+::grpc::ClientAsyncReader< ::dmi::ImageStatus>* NativeSoftwareManagementService::Stub::AsyncActivateImageRaw(::grpc::ClientContext* context, const ::dmi::HardwareID& request, ::grpc::CompletionQueue* cq, void* tag) {
+  return ::grpc_impl::internal::ClientAsyncReaderFactory< ::dmi::ImageStatus>::Create(channel_.get(), cq, rpcmethod_ActivateImage_, context, request, true, tag);
+}
+
+::grpc::ClientAsyncReader< ::dmi::ImageStatus>* NativeSoftwareManagementService::Stub::PrepareAsyncActivateImageRaw(::grpc::ClientContext* context, const ::dmi::HardwareID& request, ::grpc::CompletionQueue* cq) {
+  return ::grpc_impl::internal::ClientAsyncReaderFactory< ::dmi::ImageStatus>::Create(channel_.get(), cq, rpcmethod_ActivateImage_, context, request, false, nullptr);
+}
+
+::grpc::ClientReader< ::dmi::ImageStatus>* NativeSoftwareManagementService::Stub::RevertToStandbyImageRaw(::grpc::ClientContext* context, const ::dmi::HardwareID& request) {
+  return ::grpc_impl::internal::ClientReaderFactory< ::dmi::ImageStatus>::Create(channel_.get(), rpcmethod_RevertToStandbyImage_, context, request);
+}
+
+void NativeSoftwareManagementService::Stub::experimental_async::RevertToStandbyImage(::grpc::ClientContext* context, ::dmi::HardwareID* request, ::grpc::experimental::ClientReadReactor< ::dmi::ImageStatus>* reactor) {
+  ::grpc_impl::internal::ClientCallbackReaderFactory< ::dmi::ImageStatus>::Create(stub_->channel_.get(), stub_->rpcmethod_RevertToStandbyImage_, context, request, reactor);
+}
+
+::grpc::ClientAsyncReader< ::dmi::ImageStatus>* NativeSoftwareManagementService::Stub::AsyncRevertToStandbyImageRaw(::grpc::ClientContext* context, const ::dmi::HardwareID& request, ::grpc::CompletionQueue* cq, void* tag) {
+  return ::grpc_impl::internal::ClientAsyncReaderFactory< ::dmi::ImageStatus>::Create(channel_.get(), cq, rpcmethod_RevertToStandbyImage_, context, request, true, tag);
+}
+
+::grpc::ClientAsyncReader< ::dmi::ImageStatus>* NativeSoftwareManagementService::Stub::PrepareAsyncRevertToStandbyImageRaw(::grpc::ClientContext* context, const ::dmi::HardwareID& request, ::grpc::CompletionQueue* cq) {
+  return ::grpc_impl::internal::ClientAsyncReaderFactory< ::dmi::ImageStatus>::Create(channel_.get(), cq, rpcmethod_RevertToStandbyImage_, context, request, false, nullptr);
+}
+
+::grpc::ClientReader< ::dmi::ConfigResponse>* NativeSoftwareManagementService::Stub::UpdateStartupConfigurationRaw(::grpc::ClientContext* context, const ::dmi::ConfigRequest& request) {
+  return ::grpc_impl::internal::ClientReaderFactory< ::dmi::ConfigResponse>::Create(channel_.get(), rpcmethod_UpdateStartupConfiguration_, context, request);
+}
+
+void NativeSoftwareManagementService::Stub::experimental_async::UpdateStartupConfiguration(::grpc::ClientContext* context, ::dmi::ConfigRequest* request, ::grpc::experimental::ClientReadReactor< ::dmi::ConfigResponse>* reactor) {
+  ::grpc_impl::internal::ClientCallbackReaderFactory< ::dmi::ConfigResponse>::Create(stub_->channel_.get(), stub_->rpcmethod_UpdateStartupConfiguration_, context, request, reactor);
+}
+
+::grpc::ClientAsyncReader< ::dmi::ConfigResponse>* NativeSoftwareManagementService::Stub::AsyncUpdateStartupConfigurationRaw(::grpc::ClientContext* context, const ::dmi::ConfigRequest& request, ::grpc::CompletionQueue* cq, void* tag) {
+  return ::grpc_impl::internal::ClientAsyncReaderFactory< ::dmi::ConfigResponse>::Create(channel_.get(), cq, rpcmethod_UpdateStartupConfiguration_, context, request, true, tag);
+}
+
+::grpc::ClientAsyncReader< ::dmi::ConfigResponse>* NativeSoftwareManagementService::Stub::PrepareAsyncUpdateStartupConfigurationRaw(::grpc::ClientContext* context, const ::dmi::ConfigRequest& request, ::grpc::CompletionQueue* cq) {
+  return ::grpc_impl::internal::ClientAsyncReaderFactory< ::dmi::ConfigResponse>::Create(channel_.get(), cq, rpcmethod_UpdateStartupConfiguration_, context, request, false, nullptr);
+}
+
+::grpc::Status NativeSoftwareManagementService::Stub::GetStartupConfigurationInfo(::grpc::ClientContext* context, const ::dmi::StartupConfigInfoRequest& request, ::dmi::StartupConfigInfoResponse* response) {
+  return ::grpc::internal::BlockingUnaryCall(channel_.get(), rpcmethod_GetStartupConfigurationInfo_, context, request, response);
+}
+
+void NativeSoftwareManagementService::Stub::experimental_async::GetStartupConfigurationInfo(::grpc::ClientContext* context, const ::dmi::StartupConfigInfoRequest* request, ::dmi::StartupConfigInfoResponse* response, std::function<void(::grpc::Status)> f) {
+  ::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_GetStartupConfigurationInfo_, context, request, response, std::move(f));
+}
+
+void NativeSoftwareManagementService::Stub::experimental_async::GetStartupConfigurationInfo(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::StartupConfigInfoResponse* response, std::function<void(::grpc::Status)> f) {
+  ::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_GetStartupConfigurationInfo_, context, request, response, std::move(f));
+}
+
+void NativeSoftwareManagementService::Stub::experimental_async::GetStartupConfigurationInfo(::grpc::ClientContext* context, const ::dmi::StartupConfigInfoRequest* request, ::dmi::StartupConfigInfoResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
+  ::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_GetStartupConfigurationInfo_, context, request, response, reactor);
+}
+
+void NativeSoftwareManagementService::Stub::experimental_async::GetStartupConfigurationInfo(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::StartupConfigInfoResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
+  ::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_GetStartupConfigurationInfo_, context, request, response, reactor);
+}
+
+::grpc::ClientAsyncResponseReader< ::dmi::StartupConfigInfoResponse>* NativeSoftwareManagementService::Stub::AsyncGetStartupConfigurationInfoRaw(::grpc::ClientContext* context, const ::dmi::StartupConfigInfoRequest& request, ::grpc::CompletionQueue* cq) {
+  return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::dmi::StartupConfigInfoResponse>::Create(channel_.get(), cq, rpcmethod_GetStartupConfigurationInfo_, context, request, true);
+}
+
+::grpc::ClientAsyncResponseReader< ::dmi::StartupConfigInfoResponse>* NativeSoftwareManagementService::Stub::PrepareAsyncGetStartupConfigurationInfoRaw(::grpc::ClientContext* context, const ::dmi::StartupConfigInfoRequest& request, ::grpc::CompletionQueue* cq) {
+  return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::dmi::StartupConfigInfoResponse>::Create(channel_.get(), cq, rpcmethod_GetStartupConfigurationInfo_, context, request, false);
+}
+
+NativeSoftwareManagementService::Service::Service() {
+  AddMethod(new ::grpc::internal::RpcServiceMethod(
+      NativeSoftwareManagementService_method_names[0],
+      ::grpc::internal::RpcMethod::NORMAL_RPC,
+      new ::grpc::internal::RpcMethodHandler< NativeSoftwareManagementService::Service, ::dmi::HardwareID, ::dmi::GetSoftwareVersionInformationResponse>(
+          [](NativeSoftwareManagementService::Service* service,
+             ::grpc_impl::ServerContext* ctx,
+             const ::dmi::HardwareID* req,
+             ::dmi::GetSoftwareVersionInformationResponse* resp) {
+               return service->GetSoftwareVersion(ctx, req, resp);
+             }, this)));
+  AddMethod(new ::grpc::internal::RpcServiceMethod(
+      NativeSoftwareManagementService_method_names[1],
+      ::grpc::internal::RpcMethod::SERVER_STREAMING,
+      new ::grpc::internal::ServerStreamingHandler< NativeSoftwareManagementService::Service, ::dmi::DownloadImageRequest, ::dmi::ImageStatus>(
+          [](NativeSoftwareManagementService::Service* service,
+             ::grpc_impl::ServerContext* ctx,
+             const ::dmi::DownloadImageRequest* req,
+             ::grpc_impl::ServerWriter<::dmi::ImageStatus>* writer) {
+               return service->DownloadImage(ctx, req, writer);
+             }, this)));
+  AddMethod(new ::grpc::internal::RpcServiceMethod(
+      NativeSoftwareManagementService_method_names[2],
+      ::grpc::internal::RpcMethod::SERVER_STREAMING,
+      new ::grpc::internal::ServerStreamingHandler< NativeSoftwareManagementService::Service, ::dmi::HardwareID, ::dmi::ImageStatus>(
+          [](NativeSoftwareManagementService::Service* service,
+             ::grpc_impl::ServerContext* ctx,
+             const ::dmi::HardwareID* req,
+             ::grpc_impl::ServerWriter<::dmi::ImageStatus>* writer) {
+               return service->ActivateImage(ctx, req, writer);
+             }, this)));
+  AddMethod(new ::grpc::internal::RpcServiceMethod(
+      NativeSoftwareManagementService_method_names[3],
+      ::grpc::internal::RpcMethod::SERVER_STREAMING,
+      new ::grpc::internal::ServerStreamingHandler< NativeSoftwareManagementService::Service, ::dmi::HardwareID, ::dmi::ImageStatus>(
+          [](NativeSoftwareManagementService::Service* service,
+             ::grpc_impl::ServerContext* ctx,
+             const ::dmi::HardwareID* req,
+             ::grpc_impl::ServerWriter<::dmi::ImageStatus>* writer) {
+               return service->RevertToStandbyImage(ctx, req, writer);
+             }, this)));
+  AddMethod(new ::grpc::internal::RpcServiceMethod(
+      NativeSoftwareManagementService_method_names[4],
+      ::grpc::internal::RpcMethod::SERVER_STREAMING,
+      new ::grpc::internal::ServerStreamingHandler< NativeSoftwareManagementService::Service, ::dmi::ConfigRequest, ::dmi::ConfigResponse>(
+          [](NativeSoftwareManagementService::Service* service,
+             ::grpc_impl::ServerContext* ctx,
+             const ::dmi::ConfigRequest* req,
+             ::grpc_impl::ServerWriter<::dmi::ConfigResponse>* writer) {
+               return service->UpdateStartupConfiguration(ctx, req, writer);
+             }, this)));
+  AddMethod(new ::grpc::internal::RpcServiceMethod(
+      NativeSoftwareManagementService_method_names[5],
+      ::grpc::internal::RpcMethod::NORMAL_RPC,
+      new ::grpc::internal::RpcMethodHandler< NativeSoftwareManagementService::Service, ::dmi::StartupConfigInfoRequest, ::dmi::StartupConfigInfoResponse>(
+          [](NativeSoftwareManagementService::Service* service,
+             ::grpc_impl::ServerContext* ctx,
+             const ::dmi::StartupConfigInfoRequest* req,
+             ::dmi::StartupConfigInfoResponse* resp) {
+               return service->GetStartupConfigurationInfo(ctx, req, resp);
+             }, this)));
+}
+
+NativeSoftwareManagementService::Service::~Service() {
+}
+
+::grpc::Status NativeSoftwareManagementService::Service::GetSoftwareVersion(::grpc::ServerContext* context, const ::dmi::HardwareID* request, ::dmi::GetSoftwareVersionInformationResponse* response) {
+  (void) context;
+  (void) request;
+  (void) response;
+  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+}
+
+::grpc::Status NativeSoftwareManagementService::Service::DownloadImage(::grpc::ServerContext* context, const ::dmi::DownloadImageRequest* request, ::grpc::ServerWriter< ::dmi::ImageStatus>* writer) {
+  (void) context;
+  (void) request;
+  (void) writer;
+  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+}
+
+::grpc::Status NativeSoftwareManagementService::Service::ActivateImage(::grpc::ServerContext* context, const ::dmi::HardwareID* request, ::grpc::ServerWriter< ::dmi::ImageStatus>* writer) {
+  (void) context;
+  (void) request;
+  (void) writer;
+  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+}
+
+::grpc::Status NativeSoftwareManagementService::Service::RevertToStandbyImage(::grpc::ServerContext* context, const ::dmi::HardwareID* request, ::grpc::ServerWriter< ::dmi::ImageStatus>* writer) {
+  (void) context;
+  (void) request;
+  (void) writer;
+  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+}
+
+::grpc::Status NativeSoftwareManagementService::Service::UpdateStartupConfiguration(::grpc::ServerContext* context, const ::dmi::ConfigRequest* request, ::grpc::ServerWriter< ::dmi::ConfigResponse>* writer) {
+  (void) context;
+  (void) request;
+  (void) writer;
+  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+}
+
+::grpc::Status NativeSoftwareManagementService::Service::GetStartupConfigurationInfo(::grpc::ServerContext* context, const ::dmi::StartupConfigInfoRequest* request, ::dmi::StartupConfigInfoResponse* response) {
+  (void) context;
+  (void) request;
+  (void) response;
+  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+}
+
+
+}  // namespace dmi
+
diff --git a/cpp/dmi/sw_management_service.grpc.pb.h b/cpp/dmi/sw_management_service.grpc.pb.h
new file mode 100644
index 0000000..870e714
--- /dev/null
+++ b/cpp/dmi/sw_management_service.grpc.pb.h
@@ -0,0 +1,1328 @@
+// Generated by the gRPC C++ plugin.
+// If you make any local change, they will be lost.
+// source: dmi/sw_management_service.proto
+#ifndef GRPC_dmi_2fsw_5fmanagement_5fservice_2eproto__INCLUDED
+#define GRPC_dmi_2fsw_5fmanagement_5fservice_2eproto__INCLUDED
+
+#include "dmi/sw_management_service.pb.h"
+
+#include <functional>
+#include <grpc/impl/codegen/port_platform.h>
+#include <grpcpp/impl/codegen/async_generic_service.h>
+#include <grpcpp/impl/codegen/async_stream.h>
+#include <grpcpp/impl/codegen/async_unary_call.h>
+#include <grpcpp/impl/codegen/client_callback.h>
+#include <grpcpp/impl/codegen/client_context.h>
+#include <grpcpp/impl/codegen/completion_queue.h>
+#include <grpcpp/impl/codegen/message_allocator.h>
+#include <grpcpp/impl/codegen/method_handler.h>
+#include <grpcpp/impl/codegen/proto_utils.h>
+#include <grpcpp/impl/codegen/rpc_method.h>
+#include <grpcpp/impl/codegen/server_callback.h>
+#include <grpcpp/impl/codegen/server_callback_handlers.h>
+#include <grpcpp/impl/codegen/server_context.h>
+#include <grpcpp/impl/codegen/service_type.h>
+#include <grpcpp/impl/codegen/status.h>
+#include <grpcpp/impl/codegen/stub_options.h>
+#include <grpcpp/impl/codegen/sync_stream.h>
+
+namespace dmi {
+
+class NativeSoftwareManagementService final {
+ public:
+  static constexpr char const* service_full_name() {
+    return "dmi.NativeSoftwareManagementService";
+  }
+  class StubInterface {
+   public:
+    virtual ~StubInterface() {}
+    // Get the software version information of the Active and Standby images
+    virtual ::grpc::Status GetSoftwareVersion(::grpc::ClientContext* context, const ::dmi::HardwareID& request, ::dmi::GetSoftwareVersionInformationResponse* response) = 0;
+    std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::GetSoftwareVersionInformationResponse>> AsyncGetSoftwareVersion(::grpc::ClientContext* context, const ::dmi::HardwareID& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::GetSoftwareVersionInformationResponse>>(AsyncGetSoftwareVersionRaw(context, request, cq));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::GetSoftwareVersionInformationResponse>> PrepareAsyncGetSoftwareVersion(::grpc::ClientContext* context, const ::dmi::HardwareID& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::GetSoftwareVersionInformationResponse>>(PrepareAsyncGetSoftwareVersionRaw(context, request, cq));
+    }
+    // Downloads and installs the image in the standby partition, returns the status/progress of the Install
+    std::unique_ptr< ::grpc::ClientReaderInterface< ::dmi::ImageStatus>> DownloadImage(::grpc::ClientContext* context, const ::dmi::DownloadImageRequest& request) {
+      return std::unique_ptr< ::grpc::ClientReaderInterface< ::dmi::ImageStatus>>(DownloadImageRaw(context, request));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncReaderInterface< ::dmi::ImageStatus>> AsyncDownloadImage(::grpc::ClientContext* context, const ::dmi::DownloadImageRequest& request, ::grpc::CompletionQueue* cq, void* tag) {
+      return std::unique_ptr< ::grpc::ClientAsyncReaderInterface< ::dmi::ImageStatus>>(AsyncDownloadImageRaw(context, request, cq, tag));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncReaderInterface< ::dmi::ImageStatus>> PrepareAsyncDownloadImage(::grpc::ClientContext* context, const ::dmi::DownloadImageRequest& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncReaderInterface< ::dmi::ImageStatus>>(PrepareAsyncDownloadImageRaw(context, request, cq));
+    }
+    // Activates and runs the OLT with the image in the standby partition. If things are fine this image will
+    // henceforth be marked as the Active Partition. The old working image would remain on the Standby partition.
+    // Any possibly required (sub-)steps like "commit" are left to the "Device Manager"
+    std::unique_ptr< ::grpc::ClientReaderInterface< ::dmi::ImageStatus>> ActivateImage(::grpc::ClientContext* context, const ::dmi::HardwareID& request) {
+      return std::unique_ptr< ::grpc::ClientReaderInterface< ::dmi::ImageStatus>>(ActivateImageRaw(context, request));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncReaderInterface< ::dmi::ImageStatus>> AsyncActivateImage(::grpc::ClientContext* context, const ::dmi::HardwareID& request, ::grpc::CompletionQueue* cq, void* tag) {
+      return std::unique_ptr< ::grpc::ClientAsyncReaderInterface< ::dmi::ImageStatus>>(AsyncActivateImageRaw(context, request, cq, tag));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncReaderInterface< ::dmi::ImageStatus>> PrepareAsyncActivateImage(::grpc::ClientContext* context, const ::dmi::HardwareID& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncReaderInterface< ::dmi::ImageStatus>>(PrepareAsyncActivateImageRaw(context, request, cq));
+    }
+    // Marks the image in the Standby as Active and reboots the device, so that it boots from that image which was in the standby.
+    // This API is to be used if operator wants to go back to the previous software
+    std::unique_ptr< ::grpc::ClientReaderInterface< ::dmi::ImageStatus>> RevertToStandbyImage(::grpc::ClientContext* context, const ::dmi::HardwareID& request) {
+      return std::unique_ptr< ::grpc::ClientReaderInterface< ::dmi::ImageStatus>>(RevertToStandbyImageRaw(context, request));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncReaderInterface< ::dmi::ImageStatus>> AsyncRevertToStandbyImage(::grpc::ClientContext* context, const ::dmi::HardwareID& request, ::grpc::CompletionQueue* cq, void* tag) {
+      return std::unique_ptr< ::grpc::ClientAsyncReaderInterface< ::dmi::ImageStatus>>(AsyncRevertToStandbyImageRaw(context, request, cq, tag));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncReaderInterface< ::dmi::ImageStatus>> PrepareAsyncRevertToStandbyImage(::grpc::ClientContext* context, const ::dmi::HardwareID& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncReaderInterface< ::dmi::ImageStatus>>(PrepareAsyncRevertToStandbyImageRaw(context, request, cq));
+    }
+    // This API can be used to let the devices pickup their properitary configuration which they need at startup.
+    std::unique_ptr< ::grpc::ClientReaderInterface< ::dmi::ConfigResponse>> UpdateStartupConfiguration(::grpc::ClientContext* context, const ::dmi::ConfigRequest& request) {
+      return std::unique_ptr< ::grpc::ClientReaderInterface< ::dmi::ConfigResponse>>(UpdateStartupConfigurationRaw(context, request));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncReaderInterface< ::dmi::ConfigResponse>> AsyncUpdateStartupConfiguration(::grpc::ClientContext* context, const ::dmi::ConfigRequest& request, ::grpc::CompletionQueue* cq, void* tag) {
+      return std::unique_ptr< ::grpc::ClientAsyncReaderInterface< ::dmi::ConfigResponse>>(AsyncUpdateStartupConfigurationRaw(context, request, cq, tag));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncReaderInterface< ::dmi::ConfigResponse>> PrepareAsyncUpdateStartupConfiguration(::grpc::ClientContext* context, const ::dmi::ConfigRequest& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncReaderInterface< ::dmi::ConfigResponse>>(PrepareAsyncUpdateStartupConfigurationRaw(context, request, cq));
+    }
+    // This API can be used to retrieve information about the current startup configuration that a device is using
+    virtual ::grpc::Status GetStartupConfigurationInfo(::grpc::ClientContext* context, const ::dmi::StartupConfigInfoRequest& request, ::dmi::StartupConfigInfoResponse* response) = 0;
+    std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::StartupConfigInfoResponse>> AsyncGetStartupConfigurationInfo(::grpc::ClientContext* context, const ::dmi::StartupConfigInfoRequest& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::StartupConfigInfoResponse>>(AsyncGetStartupConfigurationInfoRaw(context, request, cq));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::StartupConfigInfoResponse>> PrepareAsyncGetStartupConfigurationInfo(::grpc::ClientContext* context, const ::dmi::StartupConfigInfoRequest& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::StartupConfigInfoResponse>>(PrepareAsyncGetStartupConfigurationInfoRaw(context, request, cq));
+    }
+    class experimental_async_interface {
+     public:
+      virtual ~experimental_async_interface() {}
+      // Get the software version information of the Active and Standby images
+      virtual void GetSoftwareVersion(::grpc::ClientContext* context, const ::dmi::HardwareID* request, ::dmi::GetSoftwareVersionInformationResponse* response, std::function<void(::grpc::Status)>) = 0;
+      virtual void GetSoftwareVersion(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::GetSoftwareVersionInformationResponse* response, std::function<void(::grpc::Status)>) = 0;
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      virtual void GetSoftwareVersion(::grpc::ClientContext* context, const ::dmi::HardwareID* request, ::dmi::GetSoftwareVersionInformationResponse* response, ::grpc::ClientUnaryReactor* reactor) = 0;
+      #else
+      virtual void GetSoftwareVersion(::grpc::ClientContext* context, const ::dmi::HardwareID* request, ::dmi::GetSoftwareVersionInformationResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) = 0;
+      #endif
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      virtual void GetSoftwareVersion(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::GetSoftwareVersionInformationResponse* response, ::grpc::ClientUnaryReactor* reactor) = 0;
+      #else
+      virtual void GetSoftwareVersion(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::GetSoftwareVersionInformationResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) = 0;
+      #endif
+      // Downloads and installs the image in the standby partition, returns the status/progress of the Install
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      virtual void DownloadImage(::grpc::ClientContext* context, ::dmi::DownloadImageRequest* request, ::grpc::ClientReadReactor< ::dmi::ImageStatus>* reactor) = 0;
+      #else
+      virtual void DownloadImage(::grpc::ClientContext* context, ::dmi::DownloadImageRequest* request, ::grpc::experimental::ClientReadReactor< ::dmi::ImageStatus>* reactor) = 0;
+      #endif
+      // Activates and runs the OLT with the image in the standby partition. If things are fine this image will
+      // henceforth be marked as the Active Partition. The old working image would remain on the Standby partition.
+      // Any possibly required (sub-)steps like "commit" are left to the "Device Manager"
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      virtual void ActivateImage(::grpc::ClientContext* context, ::dmi::HardwareID* request, ::grpc::ClientReadReactor< ::dmi::ImageStatus>* reactor) = 0;
+      #else
+      virtual void ActivateImage(::grpc::ClientContext* context, ::dmi::HardwareID* request, ::grpc::experimental::ClientReadReactor< ::dmi::ImageStatus>* reactor) = 0;
+      #endif
+      // Marks the image in the Standby as Active and reboots the device, so that it boots from that image which was in the standby.
+      // This API is to be used if operator wants to go back to the previous software
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      virtual void RevertToStandbyImage(::grpc::ClientContext* context, ::dmi::HardwareID* request, ::grpc::ClientReadReactor< ::dmi::ImageStatus>* reactor) = 0;
+      #else
+      virtual void RevertToStandbyImage(::grpc::ClientContext* context, ::dmi::HardwareID* request, ::grpc::experimental::ClientReadReactor< ::dmi::ImageStatus>* reactor) = 0;
+      #endif
+      // This API can be used to let the devices pickup their properitary configuration which they need at startup.
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      virtual void UpdateStartupConfiguration(::grpc::ClientContext* context, ::dmi::ConfigRequest* request, ::grpc::ClientReadReactor< ::dmi::ConfigResponse>* reactor) = 0;
+      #else
+      virtual void UpdateStartupConfiguration(::grpc::ClientContext* context, ::dmi::ConfigRequest* request, ::grpc::experimental::ClientReadReactor< ::dmi::ConfigResponse>* reactor) = 0;
+      #endif
+      // This API can be used to retrieve information about the current startup configuration that a device is using
+      virtual void GetStartupConfigurationInfo(::grpc::ClientContext* context, const ::dmi::StartupConfigInfoRequest* request, ::dmi::StartupConfigInfoResponse* response, std::function<void(::grpc::Status)>) = 0;
+      virtual void GetStartupConfigurationInfo(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::StartupConfigInfoResponse* response, std::function<void(::grpc::Status)>) = 0;
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      virtual void GetStartupConfigurationInfo(::grpc::ClientContext* context, const ::dmi::StartupConfigInfoRequest* request, ::dmi::StartupConfigInfoResponse* response, ::grpc::ClientUnaryReactor* reactor) = 0;
+      #else
+      virtual void GetStartupConfigurationInfo(::grpc::ClientContext* context, const ::dmi::StartupConfigInfoRequest* request, ::dmi::StartupConfigInfoResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) = 0;
+      #endif
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      virtual void GetStartupConfigurationInfo(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::StartupConfigInfoResponse* response, ::grpc::ClientUnaryReactor* reactor) = 0;
+      #else
+      virtual void GetStartupConfigurationInfo(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::StartupConfigInfoResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) = 0;
+      #endif
+    };
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+    typedef class experimental_async_interface async_interface;
+    #endif
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+    async_interface* async() { return experimental_async(); }
+    #endif
+    virtual class experimental_async_interface* experimental_async() { return nullptr; }
+  private:
+    virtual ::grpc::ClientAsyncResponseReaderInterface< ::dmi::GetSoftwareVersionInformationResponse>* AsyncGetSoftwareVersionRaw(::grpc::ClientContext* context, const ::dmi::HardwareID& request, ::grpc::CompletionQueue* cq) = 0;
+    virtual ::grpc::ClientAsyncResponseReaderInterface< ::dmi::GetSoftwareVersionInformationResponse>* PrepareAsyncGetSoftwareVersionRaw(::grpc::ClientContext* context, const ::dmi::HardwareID& request, ::grpc::CompletionQueue* cq) = 0;
+    virtual ::grpc::ClientReaderInterface< ::dmi::ImageStatus>* DownloadImageRaw(::grpc::ClientContext* context, const ::dmi::DownloadImageRequest& request) = 0;
+    virtual ::grpc::ClientAsyncReaderInterface< ::dmi::ImageStatus>* AsyncDownloadImageRaw(::grpc::ClientContext* context, const ::dmi::DownloadImageRequest& request, ::grpc::CompletionQueue* cq, void* tag) = 0;
+    virtual ::grpc::ClientAsyncReaderInterface< ::dmi::ImageStatus>* PrepareAsyncDownloadImageRaw(::grpc::ClientContext* context, const ::dmi::DownloadImageRequest& request, ::grpc::CompletionQueue* cq) = 0;
+    virtual ::grpc::ClientReaderInterface< ::dmi::ImageStatus>* ActivateImageRaw(::grpc::ClientContext* context, const ::dmi::HardwareID& request) = 0;
+    virtual ::grpc::ClientAsyncReaderInterface< ::dmi::ImageStatus>* AsyncActivateImageRaw(::grpc::ClientContext* context, const ::dmi::HardwareID& request, ::grpc::CompletionQueue* cq, void* tag) = 0;
+    virtual ::grpc::ClientAsyncReaderInterface< ::dmi::ImageStatus>* PrepareAsyncActivateImageRaw(::grpc::ClientContext* context, const ::dmi::HardwareID& request, ::grpc::CompletionQueue* cq) = 0;
+    virtual ::grpc::ClientReaderInterface< ::dmi::ImageStatus>* RevertToStandbyImageRaw(::grpc::ClientContext* context, const ::dmi::HardwareID& request) = 0;
+    virtual ::grpc::ClientAsyncReaderInterface< ::dmi::ImageStatus>* AsyncRevertToStandbyImageRaw(::grpc::ClientContext* context, const ::dmi::HardwareID& request, ::grpc::CompletionQueue* cq, void* tag) = 0;
+    virtual ::grpc::ClientAsyncReaderInterface< ::dmi::ImageStatus>* PrepareAsyncRevertToStandbyImageRaw(::grpc::ClientContext* context, const ::dmi::HardwareID& request, ::grpc::CompletionQueue* cq) = 0;
+    virtual ::grpc::ClientReaderInterface< ::dmi::ConfigResponse>* UpdateStartupConfigurationRaw(::grpc::ClientContext* context, const ::dmi::ConfigRequest& request) = 0;
+    virtual ::grpc::ClientAsyncReaderInterface< ::dmi::ConfigResponse>* AsyncUpdateStartupConfigurationRaw(::grpc::ClientContext* context, const ::dmi::ConfigRequest& request, ::grpc::CompletionQueue* cq, void* tag) = 0;
+    virtual ::grpc::ClientAsyncReaderInterface< ::dmi::ConfigResponse>* PrepareAsyncUpdateStartupConfigurationRaw(::grpc::ClientContext* context, const ::dmi::ConfigRequest& request, ::grpc::CompletionQueue* cq) = 0;
+    virtual ::grpc::ClientAsyncResponseReaderInterface< ::dmi::StartupConfigInfoResponse>* AsyncGetStartupConfigurationInfoRaw(::grpc::ClientContext* context, const ::dmi::StartupConfigInfoRequest& request, ::grpc::CompletionQueue* cq) = 0;
+    virtual ::grpc::ClientAsyncResponseReaderInterface< ::dmi::StartupConfigInfoResponse>* PrepareAsyncGetStartupConfigurationInfoRaw(::grpc::ClientContext* context, const ::dmi::StartupConfigInfoRequest& request, ::grpc::CompletionQueue* cq) = 0;
+  };
+  class Stub final : public StubInterface {
+   public:
+    Stub(const std::shared_ptr< ::grpc::ChannelInterface>& channel);
+    ::grpc::Status GetSoftwareVersion(::grpc::ClientContext* context, const ::dmi::HardwareID& request, ::dmi::GetSoftwareVersionInformationResponse* response) override;
+    std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::GetSoftwareVersionInformationResponse>> AsyncGetSoftwareVersion(::grpc::ClientContext* context, const ::dmi::HardwareID& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::GetSoftwareVersionInformationResponse>>(AsyncGetSoftwareVersionRaw(context, request, cq));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::GetSoftwareVersionInformationResponse>> PrepareAsyncGetSoftwareVersion(::grpc::ClientContext* context, const ::dmi::HardwareID& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::GetSoftwareVersionInformationResponse>>(PrepareAsyncGetSoftwareVersionRaw(context, request, cq));
+    }
+    std::unique_ptr< ::grpc::ClientReader< ::dmi::ImageStatus>> DownloadImage(::grpc::ClientContext* context, const ::dmi::DownloadImageRequest& request) {
+      return std::unique_ptr< ::grpc::ClientReader< ::dmi::ImageStatus>>(DownloadImageRaw(context, request));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncReader< ::dmi::ImageStatus>> AsyncDownloadImage(::grpc::ClientContext* context, const ::dmi::DownloadImageRequest& request, ::grpc::CompletionQueue* cq, void* tag) {
+      return std::unique_ptr< ::grpc::ClientAsyncReader< ::dmi::ImageStatus>>(AsyncDownloadImageRaw(context, request, cq, tag));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncReader< ::dmi::ImageStatus>> PrepareAsyncDownloadImage(::grpc::ClientContext* context, const ::dmi::DownloadImageRequest& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncReader< ::dmi::ImageStatus>>(PrepareAsyncDownloadImageRaw(context, request, cq));
+    }
+    std::unique_ptr< ::grpc::ClientReader< ::dmi::ImageStatus>> ActivateImage(::grpc::ClientContext* context, const ::dmi::HardwareID& request) {
+      return std::unique_ptr< ::grpc::ClientReader< ::dmi::ImageStatus>>(ActivateImageRaw(context, request));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncReader< ::dmi::ImageStatus>> AsyncActivateImage(::grpc::ClientContext* context, const ::dmi::HardwareID& request, ::grpc::CompletionQueue* cq, void* tag) {
+      return std::unique_ptr< ::grpc::ClientAsyncReader< ::dmi::ImageStatus>>(AsyncActivateImageRaw(context, request, cq, tag));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncReader< ::dmi::ImageStatus>> PrepareAsyncActivateImage(::grpc::ClientContext* context, const ::dmi::HardwareID& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncReader< ::dmi::ImageStatus>>(PrepareAsyncActivateImageRaw(context, request, cq));
+    }
+    std::unique_ptr< ::grpc::ClientReader< ::dmi::ImageStatus>> RevertToStandbyImage(::grpc::ClientContext* context, const ::dmi::HardwareID& request) {
+      return std::unique_ptr< ::grpc::ClientReader< ::dmi::ImageStatus>>(RevertToStandbyImageRaw(context, request));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncReader< ::dmi::ImageStatus>> AsyncRevertToStandbyImage(::grpc::ClientContext* context, const ::dmi::HardwareID& request, ::grpc::CompletionQueue* cq, void* tag) {
+      return std::unique_ptr< ::grpc::ClientAsyncReader< ::dmi::ImageStatus>>(AsyncRevertToStandbyImageRaw(context, request, cq, tag));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncReader< ::dmi::ImageStatus>> PrepareAsyncRevertToStandbyImage(::grpc::ClientContext* context, const ::dmi::HardwareID& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncReader< ::dmi::ImageStatus>>(PrepareAsyncRevertToStandbyImageRaw(context, request, cq));
+    }
+    std::unique_ptr< ::grpc::ClientReader< ::dmi::ConfigResponse>> UpdateStartupConfiguration(::grpc::ClientContext* context, const ::dmi::ConfigRequest& request) {
+      return std::unique_ptr< ::grpc::ClientReader< ::dmi::ConfigResponse>>(UpdateStartupConfigurationRaw(context, request));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncReader< ::dmi::ConfigResponse>> AsyncUpdateStartupConfiguration(::grpc::ClientContext* context, const ::dmi::ConfigRequest& request, ::grpc::CompletionQueue* cq, void* tag) {
+      return std::unique_ptr< ::grpc::ClientAsyncReader< ::dmi::ConfigResponse>>(AsyncUpdateStartupConfigurationRaw(context, request, cq, tag));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncReader< ::dmi::ConfigResponse>> PrepareAsyncUpdateStartupConfiguration(::grpc::ClientContext* context, const ::dmi::ConfigRequest& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncReader< ::dmi::ConfigResponse>>(PrepareAsyncUpdateStartupConfigurationRaw(context, request, cq));
+    }
+    ::grpc::Status GetStartupConfigurationInfo(::grpc::ClientContext* context, const ::dmi::StartupConfigInfoRequest& request, ::dmi::StartupConfigInfoResponse* response) override;
+    std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::StartupConfigInfoResponse>> AsyncGetStartupConfigurationInfo(::grpc::ClientContext* context, const ::dmi::StartupConfigInfoRequest& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::StartupConfigInfoResponse>>(AsyncGetStartupConfigurationInfoRaw(context, request, cq));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::StartupConfigInfoResponse>> PrepareAsyncGetStartupConfigurationInfo(::grpc::ClientContext* context, const ::dmi::StartupConfigInfoRequest& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::StartupConfigInfoResponse>>(PrepareAsyncGetStartupConfigurationInfoRaw(context, request, cq));
+    }
+    class experimental_async final :
+      public StubInterface::experimental_async_interface {
+     public:
+      void GetSoftwareVersion(::grpc::ClientContext* context, const ::dmi::HardwareID* request, ::dmi::GetSoftwareVersionInformationResponse* response, std::function<void(::grpc::Status)>) override;
+      void GetSoftwareVersion(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::GetSoftwareVersionInformationResponse* response, std::function<void(::grpc::Status)>) override;
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      void GetSoftwareVersion(::grpc::ClientContext* context, const ::dmi::HardwareID* request, ::dmi::GetSoftwareVersionInformationResponse* response, ::grpc::ClientUnaryReactor* reactor) override;
+      #else
+      void GetSoftwareVersion(::grpc::ClientContext* context, const ::dmi::HardwareID* request, ::dmi::GetSoftwareVersionInformationResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) override;
+      #endif
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      void GetSoftwareVersion(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::GetSoftwareVersionInformationResponse* response, ::grpc::ClientUnaryReactor* reactor) override;
+      #else
+      void GetSoftwareVersion(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::GetSoftwareVersionInformationResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) override;
+      #endif
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      void DownloadImage(::grpc::ClientContext* context, ::dmi::DownloadImageRequest* request, ::grpc::ClientReadReactor< ::dmi::ImageStatus>* reactor) override;
+      #else
+      void DownloadImage(::grpc::ClientContext* context, ::dmi::DownloadImageRequest* request, ::grpc::experimental::ClientReadReactor< ::dmi::ImageStatus>* reactor) override;
+      #endif
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      void ActivateImage(::grpc::ClientContext* context, ::dmi::HardwareID* request, ::grpc::ClientReadReactor< ::dmi::ImageStatus>* reactor) override;
+      #else
+      void ActivateImage(::grpc::ClientContext* context, ::dmi::HardwareID* request, ::grpc::experimental::ClientReadReactor< ::dmi::ImageStatus>* reactor) override;
+      #endif
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      void RevertToStandbyImage(::grpc::ClientContext* context, ::dmi::HardwareID* request, ::grpc::ClientReadReactor< ::dmi::ImageStatus>* reactor) override;
+      #else
+      void RevertToStandbyImage(::grpc::ClientContext* context, ::dmi::HardwareID* request, ::grpc::experimental::ClientReadReactor< ::dmi::ImageStatus>* reactor) override;
+      #endif
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      void UpdateStartupConfiguration(::grpc::ClientContext* context, ::dmi::ConfigRequest* request, ::grpc::ClientReadReactor< ::dmi::ConfigResponse>* reactor) override;
+      #else
+      void UpdateStartupConfiguration(::grpc::ClientContext* context, ::dmi::ConfigRequest* request, ::grpc::experimental::ClientReadReactor< ::dmi::ConfigResponse>* reactor) override;
+      #endif
+      void GetStartupConfigurationInfo(::grpc::ClientContext* context, const ::dmi::StartupConfigInfoRequest* request, ::dmi::StartupConfigInfoResponse* response, std::function<void(::grpc::Status)>) override;
+      void GetStartupConfigurationInfo(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::StartupConfigInfoResponse* response, std::function<void(::grpc::Status)>) override;
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      void GetStartupConfigurationInfo(::grpc::ClientContext* context, const ::dmi::StartupConfigInfoRequest* request, ::dmi::StartupConfigInfoResponse* response, ::grpc::ClientUnaryReactor* reactor) override;
+      #else
+      void GetStartupConfigurationInfo(::grpc::ClientContext* context, const ::dmi::StartupConfigInfoRequest* request, ::dmi::StartupConfigInfoResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) override;
+      #endif
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      void GetStartupConfigurationInfo(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::StartupConfigInfoResponse* response, ::grpc::ClientUnaryReactor* reactor) override;
+      #else
+      void GetStartupConfigurationInfo(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::StartupConfigInfoResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) override;
+      #endif
+     private:
+      friend class Stub;
+      explicit experimental_async(Stub* stub): stub_(stub) { }
+      Stub* stub() { return stub_; }
+      Stub* stub_;
+    };
+    class experimental_async_interface* experimental_async() override { return &async_stub_; }
+
+   private:
+    std::shared_ptr< ::grpc::ChannelInterface> channel_;
+    class experimental_async async_stub_{this};
+    ::grpc::ClientAsyncResponseReader< ::dmi::GetSoftwareVersionInformationResponse>* AsyncGetSoftwareVersionRaw(::grpc::ClientContext* context, const ::dmi::HardwareID& request, ::grpc::CompletionQueue* cq) override;
+    ::grpc::ClientAsyncResponseReader< ::dmi::GetSoftwareVersionInformationResponse>* PrepareAsyncGetSoftwareVersionRaw(::grpc::ClientContext* context, const ::dmi::HardwareID& request, ::grpc::CompletionQueue* cq) override;
+    ::grpc::ClientReader< ::dmi::ImageStatus>* DownloadImageRaw(::grpc::ClientContext* context, const ::dmi::DownloadImageRequest& request) override;
+    ::grpc::ClientAsyncReader< ::dmi::ImageStatus>* AsyncDownloadImageRaw(::grpc::ClientContext* context, const ::dmi::DownloadImageRequest& request, ::grpc::CompletionQueue* cq, void* tag) override;
+    ::grpc::ClientAsyncReader< ::dmi::ImageStatus>* PrepareAsyncDownloadImageRaw(::grpc::ClientContext* context, const ::dmi::DownloadImageRequest& request, ::grpc::CompletionQueue* cq) override;
+    ::grpc::ClientReader< ::dmi::ImageStatus>* ActivateImageRaw(::grpc::ClientContext* context, const ::dmi::HardwareID& request) override;
+    ::grpc::ClientAsyncReader< ::dmi::ImageStatus>* AsyncActivateImageRaw(::grpc::ClientContext* context, const ::dmi::HardwareID& request, ::grpc::CompletionQueue* cq, void* tag) override;
+    ::grpc::ClientAsyncReader< ::dmi::ImageStatus>* PrepareAsyncActivateImageRaw(::grpc::ClientContext* context, const ::dmi::HardwareID& request, ::grpc::CompletionQueue* cq) override;
+    ::grpc::ClientReader< ::dmi::ImageStatus>* RevertToStandbyImageRaw(::grpc::ClientContext* context, const ::dmi::HardwareID& request) override;
+    ::grpc::ClientAsyncReader< ::dmi::ImageStatus>* AsyncRevertToStandbyImageRaw(::grpc::ClientContext* context, const ::dmi::HardwareID& request, ::grpc::CompletionQueue* cq, void* tag) override;
+    ::grpc::ClientAsyncReader< ::dmi::ImageStatus>* PrepareAsyncRevertToStandbyImageRaw(::grpc::ClientContext* context, const ::dmi::HardwareID& request, ::grpc::CompletionQueue* cq) override;
+    ::grpc::ClientReader< ::dmi::ConfigResponse>* UpdateStartupConfigurationRaw(::grpc::ClientContext* context, const ::dmi::ConfigRequest& request) override;
+    ::grpc::ClientAsyncReader< ::dmi::ConfigResponse>* AsyncUpdateStartupConfigurationRaw(::grpc::ClientContext* context, const ::dmi::ConfigRequest& request, ::grpc::CompletionQueue* cq, void* tag) override;
+    ::grpc::ClientAsyncReader< ::dmi::ConfigResponse>* PrepareAsyncUpdateStartupConfigurationRaw(::grpc::ClientContext* context, const ::dmi::ConfigRequest& request, ::grpc::CompletionQueue* cq) override;
+    ::grpc::ClientAsyncResponseReader< ::dmi::StartupConfigInfoResponse>* AsyncGetStartupConfigurationInfoRaw(::grpc::ClientContext* context, const ::dmi::StartupConfigInfoRequest& request, ::grpc::CompletionQueue* cq) override;
+    ::grpc::ClientAsyncResponseReader< ::dmi::StartupConfigInfoResponse>* PrepareAsyncGetStartupConfigurationInfoRaw(::grpc::ClientContext* context, const ::dmi::StartupConfigInfoRequest& request, ::grpc::CompletionQueue* cq) override;
+    const ::grpc::internal::RpcMethod rpcmethod_GetSoftwareVersion_;
+    const ::grpc::internal::RpcMethod rpcmethod_DownloadImage_;
+    const ::grpc::internal::RpcMethod rpcmethod_ActivateImage_;
+    const ::grpc::internal::RpcMethod rpcmethod_RevertToStandbyImage_;
+    const ::grpc::internal::RpcMethod rpcmethod_UpdateStartupConfiguration_;
+    const ::grpc::internal::RpcMethod rpcmethod_GetStartupConfigurationInfo_;
+  };
+  static std::unique_ptr<Stub> NewStub(const std::shared_ptr< ::grpc::ChannelInterface>& channel, const ::grpc::StubOptions& options = ::grpc::StubOptions());
+
+  class Service : public ::grpc::Service {
+   public:
+    Service();
+    virtual ~Service();
+    // Get the software version information of the Active and Standby images
+    virtual ::grpc::Status GetSoftwareVersion(::grpc::ServerContext* context, const ::dmi::HardwareID* request, ::dmi::GetSoftwareVersionInformationResponse* response);
+    // Downloads and installs the image in the standby partition, returns the status/progress of the Install
+    virtual ::grpc::Status DownloadImage(::grpc::ServerContext* context, const ::dmi::DownloadImageRequest* request, ::grpc::ServerWriter< ::dmi::ImageStatus>* writer);
+    // Activates and runs the OLT with the image in the standby partition. If things are fine this image will
+    // henceforth be marked as the Active Partition. The old working image would remain on the Standby partition.
+    // Any possibly required (sub-)steps like "commit" are left to the "Device Manager"
+    virtual ::grpc::Status ActivateImage(::grpc::ServerContext* context, const ::dmi::HardwareID* request, ::grpc::ServerWriter< ::dmi::ImageStatus>* writer);
+    // Marks the image in the Standby as Active and reboots the device, so that it boots from that image which was in the standby.
+    // This API is to be used if operator wants to go back to the previous software
+    virtual ::grpc::Status RevertToStandbyImage(::grpc::ServerContext* context, const ::dmi::HardwareID* request, ::grpc::ServerWriter< ::dmi::ImageStatus>* writer);
+    // This API can be used to let the devices pickup their properitary configuration which they need at startup.
+    virtual ::grpc::Status UpdateStartupConfiguration(::grpc::ServerContext* context, const ::dmi::ConfigRequest* request, ::grpc::ServerWriter< ::dmi::ConfigResponse>* writer);
+    // This API can be used to retrieve information about the current startup configuration that a device is using
+    virtual ::grpc::Status GetStartupConfigurationInfo(::grpc::ServerContext* context, const ::dmi::StartupConfigInfoRequest* request, ::dmi::StartupConfigInfoResponse* response);
+  };
+  template <class BaseClass>
+  class WithAsyncMethod_GetSoftwareVersion : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithAsyncMethod_GetSoftwareVersion() {
+      ::grpc::Service::MarkMethodAsync(0);
+    }
+    ~WithAsyncMethod_GetSoftwareVersion() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status GetSoftwareVersion(::grpc::ServerContext* /*context*/, const ::dmi::HardwareID* /*request*/, ::dmi::GetSoftwareVersionInformationResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    void RequestGetSoftwareVersion(::grpc::ServerContext* context, ::dmi::HardwareID* request, ::grpc::ServerAsyncResponseWriter< ::dmi::GetSoftwareVersionInformationResponse>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+      ::grpc::Service::RequestAsyncUnary(0, context, request, response, new_call_cq, notification_cq, tag);
+    }
+  };
+  template <class BaseClass>
+  class WithAsyncMethod_DownloadImage : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithAsyncMethod_DownloadImage() {
+      ::grpc::Service::MarkMethodAsync(1);
+    }
+    ~WithAsyncMethod_DownloadImage() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status DownloadImage(::grpc::ServerContext* /*context*/, const ::dmi::DownloadImageRequest* /*request*/, ::grpc::ServerWriter< ::dmi::ImageStatus>* /*writer*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    void RequestDownloadImage(::grpc::ServerContext* context, ::dmi::DownloadImageRequest* request, ::grpc::ServerAsyncWriter< ::dmi::ImageStatus>* writer, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+      ::grpc::Service::RequestAsyncServerStreaming(1, context, request, writer, new_call_cq, notification_cq, tag);
+    }
+  };
+  template <class BaseClass>
+  class WithAsyncMethod_ActivateImage : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithAsyncMethod_ActivateImage() {
+      ::grpc::Service::MarkMethodAsync(2);
+    }
+    ~WithAsyncMethod_ActivateImage() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status ActivateImage(::grpc::ServerContext* /*context*/, const ::dmi::HardwareID* /*request*/, ::grpc::ServerWriter< ::dmi::ImageStatus>* /*writer*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    void RequestActivateImage(::grpc::ServerContext* context, ::dmi::HardwareID* request, ::grpc::ServerAsyncWriter< ::dmi::ImageStatus>* writer, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+      ::grpc::Service::RequestAsyncServerStreaming(2, context, request, writer, new_call_cq, notification_cq, tag);
+    }
+  };
+  template <class BaseClass>
+  class WithAsyncMethod_RevertToStandbyImage : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithAsyncMethod_RevertToStandbyImage() {
+      ::grpc::Service::MarkMethodAsync(3);
+    }
+    ~WithAsyncMethod_RevertToStandbyImage() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status RevertToStandbyImage(::grpc::ServerContext* /*context*/, const ::dmi::HardwareID* /*request*/, ::grpc::ServerWriter< ::dmi::ImageStatus>* /*writer*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    void RequestRevertToStandbyImage(::grpc::ServerContext* context, ::dmi::HardwareID* request, ::grpc::ServerAsyncWriter< ::dmi::ImageStatus>* writer, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+      ::grpc::Service::RequestAsyncServerStreaming(3, context, request, writer, new_call_cq, notification_cq, tag);
+    }
+  };
+  template <class BaseClass>
+  class WithAsyncMethod_UpdateStartupConfiguration : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithAsyncMethod_UpdateStartupConfiguration() {
+      ::grpc::Service::MarkMethodAsync(4);
+    }
+    ~WithAsyncMethod_UpdateStartupConfiguration() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status UpdateStartupConfiguration(::grpc::ServerContext* /*context*/, const ::dmi::ConfigRequest* /*request*/, ::grpc::ServerWriter< ::dmi::ConfigResponse>* /*writer*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    void RequestUpdateStartupConfiguration(::grpc::ServerContext* context, ::dmi::ConfigRequest* request, ::grpc::ServerAsyncWriter< ::dmi::ConfigResponse>* writer, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+      ::grpc::Service::RequestAsyncServerStreaming(4, context, request, writer, new_call_cq, notification_cq, tag);
+    }
+  };
+  template <class BaseClass>
+  class WithAsyncMethod_GetStartupConfigurationInfo : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithAsyncMethod_GetStartupConfigurationInfo() {
+      ::grpc::Service::MarkMethodAsync(5);
+    }
+    ~WithAsyncMethod_GetStartupConfigurationInfo() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status GetStartupConfigurationInfo(::grpc::ServerContext* /*context*/, const ::dmi::StartupConfigInfoRequest* /*request*/, ::dmi::StartupConfigInfoResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    void RequestGetStartupConfigurationInfo(::grpc::ServerContext* context, ::dmi::StartupConfigInfoRequest* request, ::grpc::ServerAsyncResponseWriter< ::dmi::StartupConfigInfoResponse>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+      ::grpc::Service::RequestAsyncUnary(5, context, request, response, new_call_cq, notification_cq, tag);
+    }
+  };
+  typedef WithAsyncMethod_GetSoftwareVersion<WithAsyncMethod_DownloadImage<WithAsyncMethod_ActivateImage<WithAsyncMethod_RevertToStandbyImage<WithAsyncMethod_UpdateStartupConfiguration<WithAsyncMethod_GetStartupConfigurationInfo<Service > > > > > > AsyncService;
+  template <class BaseClass>
+  class ExperimentalWithCallbackMethod_GetSoftwareVersion : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    ExperimentalWithCallbackMethod_GetSoftwareVersion() {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::Service::
+    #else
+      ::grpc::Service::experimental().
+    #endif
+        MarkMethodCallback(0,
+          new ::grpc_impl::internal::CallbackUnaryHandler< ::dmi::HardwareID, ::dmi::GetSoftwareVersionInformationResponse>(
+            [this](
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+                   ::grpc::CallbackServerContext*
+    #else
+                   ::grpc::experimental::CallbackServerContext*
+    #endif
+                     context, const ::dmi::HardwareID* request, ::dmi::GetSoftwareVersionInformationResponse* response) { return this->GetSoftwareVersion(context, request, response); }));}
+    void SetMessageAllocatorFor_GetSoftwareVersion(
+        ::grpc::experimental::MessageAllocator< ::dmi::HardwareID, ::dmi::GetSoftwareVersionInformationResponse>* allocator) {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(0);
+    #else
+      ::grpc::internal::MethodHandler* const handler = ::grpc::Service::experimental().GetHandler(0);
+    #endif
+      static_cast<::grpc_impl::internal::CallbackUnaryHandler< ::dmi::HardwareID, ::dmi::GetSoftwareVersionInformationResponse>*>(handler)
+              ->SetMessageAllocator(allocator);
+    }
+    ~ExperimentalWithCallbackMethod_GetSoftwareVersion() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status GetSoftwareVersion(::grpc::ServerContext* /*context*/, const ::dmi::HardwareID* /*request*/, ::dmi::GetSoftwareVersionInformationResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+    virtual ::grpc::ServerUnaryReactor* GetSoftwareVersion(
+      ::grpc::CallbackServerContext* /*context*/, const ::dmi::HardwareID* /*request*/, ::dmi::GetSoftwareVersionInformationResponse* /*response*/)
+    #else
+    virtual ::grpc::experimental::ServerUnaryReactor* GetSoftwareVersion(
+      ::grpc::experimental::CallbackServerContext* /*context*/, const ::dmi::HardwareID* /*request*/, ::dmi::GetSoftwareVersionInformationResponse* /*response*/)
+    #endif
+      { return nullptr; }
+  };
+  template <class BaseClass>
+  class ExperimentalWithCallbackMethod_DownloadImage : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    ExperimentalWithCallbackMethod_DownloadImage() {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::Service::
+    #else
+      ::grpc::Service::experimental().
+    #endif
+        MarkMethodCallback(1,
+          new ::grpc_impl::internal::CallbackServerStreamingHandler< ::dmi::DownloadImageRequest, ::dmi::ImageStatus>(
+            [this](
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+                   ::grpc::CallbackServerContext*
+    #else
+                   ::grpc::experimental::CallbackServerContext*
+    #endif
+                     context, const ::dmi::DownloadImageRequest* request) { return this->DownloadImage(context, request); }));
+    }
+    ~ExperimentalWithCallbackMethod_DownloadImage() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status DownloadImage(::grpc::ServerContext* /*context*/, const ::dmi::DownloadImageRequest* /*request*/, ::grpc::ServerWriter< ::dmi::ImageStatus>* /*writer*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+    virtual ::grpc::ServerWriteReactor< ::dmi::ImageStatus>* DownloadImage(
+      ::grpc::CallbackServerContext* /*context*/, const ::dmi::DownloadImageRequest* /*request*/)
+    #else
+    virtual ::grpc::experimental::ServerWriteReactor< ::dmi::ImageStatus>* DownloadImage(
+      ::grpc::experimental::CallbackServerContext* /*context*/, const ::dmi::DownloadImageRequest* /*request*/)
+    #endif
+      { return nullptr; }
+  };
+  template <class BaseClass>
+  class ExperimentalWithCallbackMethod_ActivateImage : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    ExperimentalWithCallbackMethod_ActivateImage() {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::Service::
+    #else
+      ::grpc::Service::experimental().
+    #endif
+        MarkMethodCallback(2,
+          new ::grpc_impl::internal::CallbackServerStreamingHandler< ::dmi::HardwareID, ::dmi::ImageStatus>(
+            [this](
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+                   ::grpc::CallbackServerContext*
+    #else
+                   ::grpc::experimental::CallbackServerContext*
+    #endif
+                     context, const ::dmi::HardwareID* request) { return this->ActivateImage(context, request); }));
+    }
+    ~ExperimentalWithCallbackMethod_ActivateImage() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status ActivateImage(::grpc::ServerContext* /*context*/, const ::dmi::HardwareID* /*request*/, ::grpc::ServerWriter< ::dmi::ImageStatus>* /*writer*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+    virtual ::grpc::ServerWriteReactor< ::dmi::ImageStatus>* ActivateImage(
+      ::grpc::CallbackServerContext* /*context*/, const ::dmi::HardwareID* /*request*/)
+    #else
+    virtual ::grpc::experimental::ServerWriteReactor< ::dmi::ImageStatus>* ActivateImage(
+      ::grpc::experimental::CallbackServerContext* /*context*/, const ::dmi::HardwareID* /*request*/)
+    #endif
+      { return nullptr; }
+  };
+  template <class BaseClass>
+  class ExperimentalWithCallbackMethod_RevertToStandbyImage : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    ExperimentalWithCallbackMethod_RevertToStandbyImage() {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::Service::
+    #else
+      ::grpc::Service::experimental().
+    #endif
+        MarkMethodCallback(3,
+          new ::grpc_impl::internal::CallbackServerStreamingHandler< ::dmi::HardwareID, ::dmi::ImageStatus>(
+            [this](
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+                   ::grpc::CallbackServerContext*
+    #else
+                   ::grpc::experimental::CallbackServerContext*
+    #endif
+                     context, const ::dmi::HardwareID* request) { return this->RevertToStandbyImage(context, request); }));
+    }
+    ~ExperimentalWithCallbackMethod_RevertToStandbyImage() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status RevertToStandbyImage(::grpc::ServerContext* /*context*/, const ::dmi::HardwareID* /*request*/, ::grpc::ServerWriter< ::dmi::ImageStatus>* /*writer*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+    virtual ::grpc::ServerWriteReactor< ::dmi::ImageStatus>* RevertToStandbyImage(
+      ::grpc::CallbackServerContext* /*context*/, const ::dmi::HardwareID* /*request*/)
+    #else
+    virtual ::grpc::experimental::ServerWriteReactor< ::dmi::ImageStatus>* RevertToStandbyImage(
+      ::grpc::experimental::CallbackServerContext* /*context*/, const ::dmi::HardwareID* /*request*/)
+    #endif
+      { return nullptr; }
+  };
+  template <class BaseClass>
+  class ExperimentalWithCallbackMethod_UpdateStartupConfiguration : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    ExperimentalWithCallbackMethod_UpdateStartupConfiguration() {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::Service::
+    #else
+      ::grpc::Service::experimental().
+    #endif
+        MarkMethodCallback(4,
+          new ::grpc_impl::internal::CallbackServerStreamingHandler< ::dmi::ConfigRequest, ::dmi::ConfigResponse>(
+            [this](
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+                   ::grpc::CallbackServerContext*
+    #else
+                   ::grpc::experimental::CallbackServerContext*
+    #endif
+                     context, const ::dmi::ConfigRequest* request) { return this->UpdateStartupConfiguration(context, request); }));
+    }
+    ~ExperimentalWithCallbackMethod_UpdateStartupConfiguration() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status UpdateStartupConfiguration(::grpc::ServerContext* /*context*/, const ::dmi::ConfigRequest* /*request*/, ::grpc::ServerWriter< ::dmi::ConfigResponse>* /*writer*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+    virtual ::grpc::ServerWriteReactor< ::dmi::ConfigResponse>* UpdateStartupConfiguration(
+      ::grpc::CallbackServerContext* /*context*/, const ::dmi::ConfigRequest* /*request*/)
+    #else
+    virtual ::grpc::experimental::ServerWriteReactor< ::dmi::ConfigResponse>* UpdateStartupConfiguration(
+      ::grpc::experimental::CallbackServerContext* /*context*/, const ::dmi::ConfigRequest* /*request*/)
+    #endif
+      { return nullptr; }
+  };
+  template <class BaseClass>
+  class ExperimentalWithCallbackMethod_GetStartupConfigurationInfo : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    ExperimentalWithCallbackMethod_GetStartupConfigurationInfo() {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::Service::
+    #else
+      ::grpc::Service::experimental().
+    #endif
+        MarkMethodCallback(5,
+          new ::grpc_impl::internal::CallbackUnaryHandler< ::dmi::StartupConfigInfoRequest, ::dmi::StartupConfigInfoResponse>(
+            [this](
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+                   ::grpc::CallbackServerContext*
+    #else
+                   ::grpc::experimental::CallbackServerContext*
+    #endif
+                     context, const ::dmi::StartupConfigInfoRequest* request, ::dmi::StartupConfigInfoResponse* response) { return this->GetStartupConfigurationInfo(context, request, response); }));}
+    void SetMessageAllocatorFor_GetStartupConfigurationInfo(
+        ::grpc::experimental::MessageAllocator< ::dmi::StartupConfigInfoRequest, ::dmi::StartupConfigInfoResponse>* allocator) {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(5);
+    #else
+      ::grpc::internal::MethodHandler* const handler = ::grpc::Service::experimental().GetHandler(5);
+    #endif
+      static_cast<::grpc_impl::internal::CallbackUnaryHandler< ::dmi::StartupConfigInfoRequest, ::dmi::StartupConfigInfoResponse>*>(handler)
+              ->SetMessageAllocator(allocator);
+    }
+    ~ExperimentalWithCallbackMethod_GetStartupConfigurationInfo() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status GetStartupConfigurationInfo(::grpc::ServerContext* /*context*/, const ::dmi::StartupConfigInfoRequest* /*request*/, ::dmi::StartupConfigInfoResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+    virtual ::grpc::ServerUnaryReactor* GetStartupConfigurationInfo(
+      ::grpc::CallbackServerContext* /*context*/, const ::dmi::StartupConfigInfoRequest* /*request*/, ::dmi::StartupConfigInfoResponse* /*response*/)
+    #else
+    virtual ::grpc::experimental::ServerUnaryReactor* GetStartupConfigurationInfo(
+      ::grpc::experimental::CallbackServerContext* /*context*/, const ::dmi::StartupConfigInfoRequest* /*request*/, ::dmi::StartupConfigInfoResponse* /*response*/)
+    #endif
+      { return nullptr; }
+  };
+  #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+  typedef ExperimentalWithCallbackMethod_GetSoftwareVersion<ExperimentalWithCallbackMethod_DownloadImage<ExperimentalWithCallbackMethod_ActivateImage<ExperimentalWithCallbackMethod_RevertToStandbyImage<ExperimentalWithCallbackMethod_UpdateStartupConfiguration<ExperimentalWithCallbackMethod_GetStartupConfigurationInfo<Service > > > > > > CallbackService;
+  #endif
+
+  typedef ExperimentalWithCallbackMethod_GetSoftwareVersion<ExperimentalWithCallbackMethod_DownloadImage<ExperimentalWithCallbackMethod_ActivateImage<ExperimentalWithCallbackMethod_RevertToStandbyImage<ExperimentalWithCallbackMethod_UpdateStartupConfiguration<ExperimentalWithCallbackMethod_GetStartupConfigurationInfo<Service > > > > > > ExperimentalCallbackService;
+  template <class BaseClass>
+  class WithGenericMethod_GetSoftwareVersion : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithGenericMethod_GetSoftwareVersion() {
+      ::grpc::Service::MarkMethodGeneric(0);
+    }
+    ~WithGenericMethod_GetSoftwareVersion() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status GetSoftwareVersion(::grpc::ServerContext* /*context*/, const ::dmi::HardwareID* /*request*/, ::dmi::GetSoftwareVersionInformationResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+  };
+  template <class BaseClass>
+  class WithGenericMethod_DownloadImage : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithGenericMethod_DownloadImage() {
+      ::grpc::Service::MarkMethodGeneric(1);
+    }
+    ~WithGenericMethod_DownloadImage() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status DownloadImage(::grpc::ServerContext* /*context*/, const ::dmi::DownloadImageRequest* /*request*/, ::grpc::ServerWriter< ::dmi::ImageStatus>* /*writer*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+  };
+  template <class BaseClass>
+  class WithGenericMethod_ActivateImage : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithGenericMethod_ActivateImage() {
+      ::grpc::Service::MarkMethodGeneric(2);
+    }
+    ~WithGenericMethod_ActivateImage() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status ActivateImage(::grpc::ServerContext* /*context*/, const ::dmi::HardwareID* /*request*/, ::grpc::ServerWriter< ::dmi::ImageStatus>* /*writer*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+  };
+  template <class BaseClass>
+  class WithGenericMethod_RevertToStandbyImage : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithGenericMethod_RevertToStandbyImage() {
+      ::grpc::Service::MarkMethodGeneric(3);
+    }
+    ~WithGenericMethod_RevertToStandbyImage() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status RevertToStandbyImage(::grpc::ServerContext* /*context*/, const ::dmi::HardwareID* /*request*/, ::grpc::ServerWriter< ::dmi::ImageStatus>* /*writer*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+  };
+  template <class BaseClass>
+  class WithGenericMethod_UpdateStartupConfiguration : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithGenericMethod_UpdateStartupConfiguration() {
+      ::grpc::Service::MarkMethodGeneric(4);
+    }
+    ~WithGenericMethod_UpdateStartupConfiguration() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status UpdateStartupConfiguration(::grpc::ServerContext* /*context*/, const ::dmi::ConfigRequest* /*request*/, ::grpc::ServerWriter< ::dmi::ConfigResponse>* /*writer*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+  };
+  template <class BaseClass>
+  class WithGenericMethod_GetStartupConfigurationInfo : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithGenericMethod_GetStartupConfigurationInfo() {
+      ::grpc::Service::MarkMethodGeneric(5);
+    }
+    ~WithGenericMethod_GetStartupConfigurationInfo() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status GetStartupConfigurationInfo(::grpc::ServerContext* /*context*/, const ::dmi::StartupConfigInfoRequest* /*request*/, ::dmi::StartupConfigInfoResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+  };
+  template <class BaseClass>
+  class WithRawMethod_GetSoftwareVersion : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithRawMethod_GetSoftwareVersion() {
+      ::grpc::Service::MarkMethodRaw(0);
+    }
+    ~WithRawMethod_GetSoftwareVersion() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status GetSoftwareVersion(::grpc::ServerContext* /*context*/, const ::dmi::HardwareID* /*request*/, ::dmi::GetSoftwareVersionInformationResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    void RequestGetSoftwareVersion(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+      ::grpc::Service::RequestAsyncUnary(0, context, request, response, new_call_cq, notification_cq, tag);
+    }
+  };
+  template <class BaseClass>
+  class WithRawMethod_DownloadImage : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithRawMethod_DownloadImage() {
+      ::grpc::Service::MarkMethodRaw(1);
+    }
+    ~WithRawMethod_DownloadImage() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status DownloadImage(::grpc::ServerContext* /*context*/, const ::dmi::DownloadImageRequest* /*request*/, ::grpc::ServerWriter< ::dmi::ImageStatus>* /*writer*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    void RequestDownloadImage(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncWriter< ::grpc::ByteBuffer>* writer, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+      ::grpc::Service::RequestAsyncServerStreaming(1, context, request, writer, new_call_cq, notification_cq, tag);
+    }
+  };
+  template <class BaseClass>
+  class WithRawMethod_ActivateImage : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithRawMethod_ActivateImage() {
+      ::grpc::Service::MarkMethodRaw(2);
+    }
+    ~WithRawMethod_ActivateImage() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status ActivateImage(::grpc::ServerContext* /*context*/, const ::dmi::HardwareID* /*request*/, ::grpc::ServerWriter< ::dmi::ImageStatus>* /*writer*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    void RequestActivateImage(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncWriter< ::grpc::ByteBuffer>* writer, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+      ::grpc::Service::RequestAsyncServerStreaming(2, context, request, writer, new_call_cq, notification_cq, tag);
+    }
+  };
+  template <class BaseClass>
+  class WithRawMethod_RevertToStandbyImage : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithRawMethod_RevertToStandbyImage() {
+      ::grpc::Service::MarkMethodRaw(3);
+    }
+    ~WithRawMethod_RevertToStandbyImage() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status RevertToStandbyImage(::grpc::ServerContext* /*context*/, const ::dmi::HardwareID* /*request*/, ::grpc::ServerWriter< ::dmi::ImageStatus>* /*writer*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    void RequestRevertToStandbyImage(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncWriter< ::grpc::ByteBuffer>* writer, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+      ::grpc::Service::RequestAsyncServerStreaming(3, context, request, writer, new_call_cq, notification_cq, tag);
+    }
+  };
+  template <class BaseClass>
+  class WithRawMethod_UpdateStartupConfiguration : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithRawMethod_UpdateStartupConfiguration() {
+      ::grpc::Service::MarkMethodRaw(4);
+    }
+    ~WithRawMethod_UpdateStartupConfiguration() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status UpdateStartupConfiguration(::grpc::ServerContext* /*context*/, const ::dmi::ConfigRequest* /*request*/, ::grpc::ServerWriter< ::dmi::ConfigResponse>* /*writer*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    void RequestUpdateStartupConfiguration(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncWriter< ::grpc::ByteBuffer>* writer, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+      ::grpc::Service::RequestAsyncServerStreaming(4, context, request, writer, new_call_cq, notification_cq, tag);
+    }
+  };
+  template <class BaseClass>
+  class WithRawMethod_GetStartupConfigurationInfo : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithRawMethod_GetStartupConfigurationInfo() {
+      ::grpc::Service::MarkMethodRaw(5);
+    }
+    ~WithRawMethod_GetStartupConfigurationInfo() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status GetStartupConfigurationInfo(::grpc::ServerContext* /*context*/, const ::dmi::StartupConfigInfoRequest* /*request*/, ::dmi::StartupConfigInfoResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    void RequestGetStartupConfigurationInfo(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+      ::grpc::Service::RequestAsyncUnary(5, context, request, response, new_call_cq, notification_cq, tag);
+    }
+  };
+  template <class BaseClass>
+  class ExperimentalWithRawCallbackMethod_GetSoftwareVersion : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    ExperimentalWithRawCallbackMethod_GetSoftwareVersion() {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::Service::
+    #else
+      ::grpc::Service::experimental().
+    #endif
+        MarkMethodRawCallback(0,
+          new ::grpc_impl::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>(
+            [this](
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+                   ::grpc::CallbackServerContext*
+    #else
+                   ::grpc::experimental::CallbackServerContext*
+    #endif
+                     context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response) { return this->GetSoftwareVersion(context, request, response); }));
+    }
+    ~ExperimentalWithRawCallbackMethod_GetSoftwareVersion() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status GetSoftwareVersion(::grpc::ServerContext* /*context*/, const ::dmi::HardwareID* /*request*/, ::dmi::GetSoftwareVersionInformationResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+    virtual ::grpc::ServerUnaryReactor* GetSoftwareVersion(
+      ::grpc::CallbackServerContext* /*context*/, const ::grpc::ByteBuffer* /*request*/, ::grpc::ByteBuffer* /*response*/)
+    #else
+    virtual ::grpc::experimental::ServerUnaryReactor* GetSoftwareVersion(
+      ::grpc::experimental::CallbackServerContext* /*context*/, const ::grpc::ByteBuffer* /*request*/, ::grpc::ByteBuffer* /*response*/)
+    #endif
+      { return nullptr; }
+  };
+  template <class BaseClass>
+  class ExperimentalWithRawCallbackMethod_DownloadImage : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    ExperimentalWithRawCallbackMethod_DownloadImage() {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::Service::
+    #else
+      ::grpc::Service::experimental().
+    #endif
+        MarkMethodRawCallback(1,
+          new ::grpc_impl::internal::CallbackServerStreamingHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>(
+            [this](
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+                   ::grpc::CallbackServerContext*
+    #else
+                   ::grpc::experimental::CallbackServerContext*
+    #endif
+                     context, const::grpc::ByteBuffer* request) { return this->DownloadImage(context, request); }));
+    }
+    ~ExperimentalWithRawCallbackMethod_DownloadImage() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status DownloadImage(::grpc::ServerContext* /*context*/, const ::dmi::DownloadImageRequest* /*request*/, ::grpc::ServerWriter< ::dmi::ImageStatus>* /*writer*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+    virtual ::grpc::ServerWriteReactor< ::grpc::ByteBuffer>* DownloadImage(
+      ::grpc::CallbackServerContext* /*context*/, const ::grpc::ByteBuffer* /*request*/)
+    #else
+    virtual ::grpc::experimental::ServerWriteReactor< ::grpc::ByteBuffer>* DownloadImage(
+      ::grpc::experimental::CallbackServerContext* /*context*/, const ::grpc::ByteBuffer* /*request*/)
+    #endif
+      { return nullptr; }
+  };
+  template <class BaseClass>
+  class ExperimentalWithRawCallbackMethod_ActivateImage : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    ExperimentalWithRawCallbackMethod_ActivateImage() {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::Service::
+    #else
+      ::grpc::Service::experimental().
+    #endif
+        MarkMethodRawCallback(2,
+          new ::grpc_impl::internal::CallbackServerStreamingHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>(
+            [this](
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+                   ::grpc::CallbackServerContext*
+    #else
+                   ::grpc::experimental::CallbackServerContext*
+    #endif
+                     context, const::grpc::ByteBuffer* request) { return this->ActivateImage(context, request); }));
+    }
+    ~ExperimentalWithRawCallbackMethod_ActivateImage() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status ActivateImage(::grpc::ServerContext* /*context*/, const ::dmi::HardwareID* /*request*/, ::grpc::ServerWriter< ::dmi::ImageStatus>* /*writer*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+    virtual ::grpc::ServerWriteReactor< ::grpc::ByteBuffer>* ActivateImage(
+      ::grpc::CallbackServerContext* /*context*/, const ::grpc::ByteBuffer* /*request*/)
+    #else
+    virtual ::grpc::experimental::ServerWriteReactor< ::grpc::ByteBuffer>* ActivateImage(
+      ::grpc::experimental::CallbackServerContext* /*context*/, const ::grpc::ByteBuffer* /*request*/)
+    #endif
+      { return nullptr; }
+  };
+  template <class BaseClass>
+  class ExperimentalWithRawCallbackMethod_RevertToStandbyImage : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    ExperimentalWithRawCallbackMethod_RevertToStandbyImage() {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::Service::
+    #else
+      ::grpc::Service::experimental().
+    #endif
+        MarkMethodRawCallback(3,
+          new ::grpc_impl::internal::CallbackServerStreamingHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>(
+            [this](
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+                   ::grpc::CallbackServerContext*
+    #else
+                   ::grpc::experimental::CallbackServerContext*
+    #endif
+                     context, const::grpc::ByteBuffer* request) { return this->RevertToStandbyImage(context, request); }));
+    }
+    ~ExperimentalWithRawCallbackMethod_RevertToStandbyImage() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status RevertToStandbyImage(::grpc::ServerContext* /*context*/, const ::dmi::HardwareID* /*request*/, ::grpc::ServerWriter< ::dmi::ImageStatus>* /*writer*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+    virtual ::grpc::ServerWriteReactor< ::grpc::ByteBuffer>* RevertToStandbyImage(
+      ::grpc::CallbackServerContext* /*context*/, const ::grpc::ByteBuffer* /*request*/)
+    #else
+    virtual ::grpc::experimental::ServerWriteReactor< ::grpc::ByteBuffer>* RevertToStandbyImage(
+      ::grpc::experimental::CallbackServerContext* /*context*/, const ::grpc::ByteBuffer* /*request*/)
+    #endif
+      { return nullptr; }
+  };
+  template <class BaseClass>
+  class ExperimentalWithRawCallbackMethod_UpdateStartupConfiguration : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    ExperimentalWithRawCallbackMethod_UpdateStartupConfiguration() {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::Service::
+    #else
+      ::grpc::Service::experimental().
+    #endif
+        MarkMethodRawCallback(4,
+          new ::grpc_impl::internal::CallbackServerStreamingHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>(
+            [this](
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+                   ::grpc::CallbackServerContext*
+    #else
+                   ::grpc::experimental::CallbackServerContext*
+    #endif
+                     context, const::grpc::ByteBuffer* request) { return this->UpdateStartupConfiguration(context, request); }));
+    }
+    ~ExperimentalWithRawCallbackMethod_UpdateStartupConfiguration() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status UpdateStartupConfiguration(::grpc::ServerContext* /*context*/, const ::dmi::ConfigRequest* /*request*/, ::grpc::ServerWriter< ::dmi::ConfigResponse>* /*writer*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+    virtual ::grpc::ServerWriteReactor< ::grpc::ByteBuffer>* UpdateStartupConfiguration(
+      ::grpc::CallbackServerContext* /*context*/, const ::grpc::ByteBuffer* /*request*/)
+    #else
+    virtual ::grpc::experimental::ServerWriteReactor< ::grpc::ByteBuffer>* UpdateStartupConfiguration(
+      ::grpc::experimental::CallbackServerContext* /*context*/, const ::grpc::ByteBuffer* /*request*/)
+    #endif
+      { return nullptr; }
+  };
+  template <class BaseClass>
+  class ExperimentalWithRawCallbackMethod_GetStartupConfigurationInfo : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    ExperimentalWithRawCallbackMethod_GetStartupConfigurationInfo() {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::Service::
+    #else
+      ::grpc::Service::experimental().
+    #endif
+        MarkMethodRawCallback(5,
+          new ::grpc_impl::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>(
+            [this](
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+                   ::grpc::CallbackServerContext*
+    #else
+                   ::grpc::experimental::CallbackServerContext*
+    #endif
+                     context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response) { return this->GetStartupConfigurationInfo(context, request, response); }));
+    }
+    ~ExperimentalWithRawCallbackMethod_GetStartupConfigurationInfo() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status GetStartupConfigurationInfo(::grpc::ServerContext* /*context*/, const ::dmi::StartupConfigInfoRequest* /*request*/, ::dmi::StartupConfigInfoResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+    virtual ::grpc::ServerUnaryReactor* GetStartupConfigurationInfo(
+      ::grpc::CallbackServerContext* /*context*/, const ::grpc::ByteBuffer* /*request*/, ::grpc::ByteBuffer* /*response*/)
+    #else
+    virtual ::grpc::experimental::ServerUnaryReactor* GetStartupConfigurationInfo(
+      ::grpc::experimental::CallbackServerContext* /*context*/, const ::grpc::ByteBuffer* /*request*/, ::grpc::ByteBuffer* /*response*/)
+    #endif
+      { return nullptr; }
+  };
+  template <class BaseClass>
+  class WithStreamedUnaryMethod_GetSoftwareVersion : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithStreamedUnaryMethod_GetSoftwareVersion() {
+      ::grpc::Service::MarkMethodStreamed(0,
+        new ::grpc::internal::StreamedUnaryHandler<
+          ::dmi::HardwareID, ::dmi::GetSoftwareVersionInformationResponse>(
+            [this](::grpc_impl::ServerContext* context,
+                   ::grpc_impl::ServerUnaryStreamer<
+                     ::dmi::HardwareID, ::dmi::GetSoftwareVersionInformationResponse>* streamer) {
+                       return this->StreamedGetSoftwareVersion(context,
+                         streamer);
+                  }));
+    }
+    ~WithStreamedUnaryMethod_GetSoftwareVersion() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable regular version of this method
+    ::grpc::Status GetSoftwareVersion(::grpc::ServerContext* /*context*/, const ::dmi::HardwareID* /*request*/, ::dmi::GetSoftwareVersionInformationResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    // replace default version of method with streamed unary
+    virtual ::grpc::Status StreamedGetSoftwareVersion(::grpc::ServerContext* context, ::grpc::ServerUnaryStreamer< ::dmi::HardwareID,::dmi::GetSoftwareVersionInformationResponse>* server_unary_streamer) = 0;
+  };
+  template <class BaseClass>
+  class WithStreamedUnaryMethod_GetStartupConfigurationInfo : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithStreamedUnaryMethod_GetStartupConfigurationInfo() {
+      ::grpc::Service::MarkMethodStreamed(5,
+        new ::grpc::internal::StreamedUnaryHandler<
+          ::dmi::StartupConfigInfoRequest, ::dmi::StartupConfigInfoResponse>(
+            [this](::grpc_impl::ServerContext* context,
+                   ::grpc_impl::ServerUnaryStreamer<
+                     ::dmi::StartupConfigInfoRequest, ::dmi::StartupConfigInfoResponse>* streamer) {
+                       return this->StreamedGetStartupConfigurationInfo(context,
+                         streamer);
+                  }));
+    }
+    ~WithStreamedUnaryMethod_GetStartupConfigurationInfo() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable regular version of this method
+    ::grpc::Status GetStartupConfigurationInfo(::grpc::ServerContext* /*context*/, const ::dmi::StartupConfigInfoRequest* /*request*/, ::dmi::StartupConfigInfoResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    // replace default version of method with streamed unary
+    virtual ::grpc::Status StreamedGetStartupConfigurationInfo(::grpc::ServerContext* context, ::grpc::ServerUnaryStreamer< ::dmi::StartupConfigInfoRequest,::dmi::StartupConfigInfoResponse>* server_unary_streamer) = 0;
+  };
+  typedef WithStreamedUnaryMethod_GetSoftwareVersion<WithStreamedUnaryMethod_GetStartupConfigurationInfo<Service > > StreamedUnaryService;
+  template <class BaseClass>
+  class WithSplitStreamingMethod_DownloadImage : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithSplitStreamingMethod_DownloadImage() {
+      ::grpc::Service::MarkMethodStreamed(1,
+        new ::grpc::internal::SplitServerStreamingHandler<
+          ::dmi::DownloadImageRequest, ::dmi::ImageStatus>(
+            [this](::grpc_impl::ServerContext* context,
+                   ::grpc_impl::ServerSplitStreamer<
+                     ::dmi::DownloadImageRequest, ::dmi::ImageStatus>* streamer) {
+                       return this->StreamedDownloadImage(context,
+                         streamer);
+                  }));
+    }
+    ~WithSplitStreamingMethod_DownloadImage() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable regular version of this method
+    ::grpc::Status DownloadImage(::grpc::ServerContext* /*context*/, const ::dmi::DownloadImageRequest* /*request*/, ::grpc::ServerWriter< ::dmi::ImageStatus>* /*writer*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    // replace default version of method with split streamed
+    virtual ::grpc::Status StreamedDownloadImage(::grpc::ServerContext* context, ::grpc::ServerSplitStreamer< ::dmi::DownloadImageRequest,::dmi::ImageStatus>* server_split_streamer) = 0;
+  };
+  template <class BaseClass>
+  class WithSplitStreamingMethod_ActivateImage : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithSplitStreamingMethod_ActivateImage() {
+      ::grpc::Service::MarkMethodStreamed(2,
+        new ::grpc::internal::SplitServerStreamingHandler<
+          ::dmi::HardwareID, ::dmi::ImageStatus>(
+            [this](::grpc_impl::ServerContext* context,
+                   ::grpc_impl::ServerSplitStreamer<
+                     ::dmi::HardwareID, ::dmi::ImageStatus>* streamer) {
+                       return this->StreamedActivateImage(context,
+                         streamer);
+                  }));
+    }
+    ~WithSplitStreamingMethod_ActivateImage() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable regular version of this method
+    ::grpc::Status ActivateImage(::grpc::ServerContext* /*context*/, const ::dmi::HardwareID* /*request*/, ::grpc::ServerWriter< ::dmi::ImageStatus>* /*writer*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    // replace default version of method with split streamed
+    virtual ::grpc::Status StreamedActivateImage(::grpc::ServerContext* context, ::grpc::ServerSplitStreamer< ::dmi::HardwareID,::dmi::ImageStatus>* server_split_streamer) = 0;
+  };
+  template <class BaseClass>
+  class WithSplitStreamingMethod_RevertToStandbyImage : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithSplitStreamingMethod_RevertToStandbyImage() {
+      ::grpc::Service::MarkMethodStreamed(3,
+        new ::grpc::internal::SplitServerStreamingHandler<
+          ::dmi::HardwareID, ::dmi::ImageStatus>(
+            [this](::grpc_impl::ServerContext* context,
+                   ::grpc_impl::ServerSplitStreamer<
+                     ::dmi::HardwareID, ::dmi::ImageStatus>* streamer) {
+                       return this->StreamedRevertToStandbyImage(context,
+                         streamer);
+                  }));
+    }
+    ~WithSplitStreamingMethod_RevertToStandbyImage() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable regular version of this method
+    ::grpc::Status RevertToStandbyImage(::grpc::ServerContext* /*context*/, const ::dmi::HardwareID* /*request*/, ::grpc::ServerWriter< ::dmi::ImageStatus>* /*writer*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    // replace default version of method with split streamed
+    virtual ::grpc::Status StreamedRevertToStandbyImage(::grpc::ServerContext* context, ::grpc::ServerSplitStreamer< ::dmi::HardwareID,::dmi::ImageStatus>* server_split_streamer) = 0;
+  };
+  template <class BaseClass>
+  class WithSplitStreamingMethod_UpdateStartupConfiguration : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithSplitStreamingMethod_UpdateStartupConfiguration() {
+      ::grpc::Service::MarkMethodStreamed(4,
+        new ::grpc::internal::SplitServerStreamingHandler<
+          ::dmi::ConfigRequest, ::dmi::ConfigResponse>(
+            [this](::grpc_impl::ServerContext* context,
+                   ::grpc_impl::ServerSplitStreamer<
+                     ::dmi::ConfigRequest, ::dmi::ConfigResponse>* streamer) {
+                       return this->StreamedUpdateStartupConfiguration(context,
+                         streamer);
+                  }));
+    }
+    ~WithSplitStreamingMethod_UpdateStartupConfiguration() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable regular version of this method
+    ::grpc::Status UpdateStartupConfiguration(::grpc::ServerContext* /*context*/, const ::dmi::ConfigRequest* /*request*/, ::grpc::ServerWriter< ::dmi::ConfigResponse>* /*writer*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    // replace default version of method with split streamed
+    virtual ::grpc::Status StreamedUpdateStartupConfiguration(::grpc::ServerContext* context, ::grpc::ServerSplitStreamer< ::dmi::ConfigRequest,::dmi::ConfigResponse>* server_split_streamer) = 0;
+  };
+  typedef WithSplitStreamingMethod_DownloadImage<WithSplitStreamingMethod_ActivateImage<WithSplitStreamingMethod_RevertToStandbyImage<WithSplitStreamingMethod_UpdateStartupConfiguration<Service > > > > SplitStreamedService;
+  typedef WithStreamedUnaryMethod_GetSoftwareVersion<WithSplitStreamingMethod_DownloadImage<WithSplitStreamingMethod_ActivateImage<WithSplitStreamingMethod_RevertToStandbyImage<WithSplitStreamingMethod_UpdateStartupConfiguration<WithStreamedUnaryMethod_GetStartupConfigurationInfo<Service > > > > > > StreamedService;
+};
+
+}  // namespace dmi
+
+
+#endif  // GRPC_dmi_2fsw_5fmanagement_5fservice_2eproto__INCLUDED
diff --git a/go/dmi/hw_events_mgmt_service.pb.go b/go/dmi/hw_events_mgmt_service.pb.go
index 2b5dc6e..ba213a6 100644
--- a/go/dmi/hw_events_mgmt_service.pb.go
+++ b/go/dmi/hw_events_mgmt_service.pb.go
@@ -9,6 +9,8 @@
 	proto "github.com/golang/protobuf/proto"
 	timestamp "github.com/golang/protobuf/ptypes/timestamp"
 	grpc "google.golang.org/grpc"
+	codes "google.golang.org/grpc/codes"
+	status "google.golang.org/grpc/status"
 	math "math"
 )
 
@@ -1107,6 +1109,17 @@
 	UpdateEventsConfiguration(context.Context, *EventsConfigurationRequest) (*EventsConfigurationResponse, error)
 }
 
+// UnimplementedNativeEventsManagementServiceServer can be embedded to have forward compatible implementations.
+type UnimplementedNativeEventsManagementServiceServer struct {
+}
+
+func (*UnimplementedNativeEventsManagementServiceServer) ListEvents(ctx context.Context, req *HardwareID) (*ListEventsResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method ListEvents not implemented")
+}
+func (*UnimplementedNativeEventsManagementServiceServer) UpdateEventsConfiguration(ctx context.Context, req *EventsConfigurationRequest) (*EventsConfigurationResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method UpdateEventsConfiguration not implemented")
+}
+
 func RegisterNativeEventsManagementServiceServer(s *grpc.Server, srv NativeEventsManagementServiceServer) {
 	s.RegisterService(&_NativeEventsManagementService_serviceDesc, srv)
 }
diff --git a/go/dmi/hw_management_service.pb.go b/go/dmi/hw_management_service.pb.go
index 251ab43..861755f 100644
--- a/go/dmi/hw_management_service.pb.go
+++ b/go/dmi/hw_management_service.pb.go
@@ -9,6 +9,8 @@
 	proto "github.com/golang/protobuf/proto"
 	empty "github.com/golang/protobuf/ptypes/empty"
 	grpc "google.golang.org/grpc"
+	codes "google.golang.org/grpc/codes"
+	status "google.golang.org/grpc/status"
 	math "math"
 )
 
@@ -2005,6 +2007,50 @@
 	GetLogLevel(context.Context, *GetLogLevelRequest) (*GetLogLevelResponse, error)
 }
 
+// UnimplementedNativeHWManagementServiceServer can be embedded to have forward compatible implementations.
+type UnimplementedNativeHWManagementServiceServer struct {
+}
+
+func (*UnimplementedNativeHWManagementServiceServer) StartManagingDevice(req *ModifiableComponent, srv NativeHWManagementService_StartManagingDeviceServer) error {
+	return status.Errorf(codes.Unimplemented, "method StartManagingDevice not implemented")
+}
+func (*UnimplementedNativeHWManagementServiceServer) StopManagingDevice(ctx context.Context, req *StopManagingDeviceRequest) (*StopManagingDeviceResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method StopManagingDevice not implemented")
+}
+func (*UnimplementedNativeHWManagementServiceServer) GetManagedDevices(ctx context.Context, req *empty.Empty) (*ManagedDevicesResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method GetManagedDevices not implemented")
+}
+func (*UnimplementedNativeHWManagementServiceServer) GetPhysicalInventory(req *PhysicalInventoryRequest, srv NativeHWManagementService_GetPhysicalInventoryServer) error {
+	return status.Errorf(codes.Unimplemented, "method GetPhysicalInventory not implemented")
+}
+func (*UnimplementedNativeHWManagementServiceServer) GetHWComponentInfo(req *HWComponentInfoGetRequest, srv NativeHWManagementService_GetHWComponentInfoServer) error {
+	return status.Errorf(codes.Unimplemented, "method GetHWComponentInfo not implemented")
+}
+func (*UnimplementedNativeHWManagementServiceServer) SetHWComponentInfo(ctx context.Context, req *HWComponentInfoSetRequest) (*HWComponentInfoSetResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method SetHWComponentInfo not implemented")
+}
+func (*UnimplementedNativeHWManagementServiceServer) SetLoggingEndpoint(ctx context.Context, req *SetLoggingEndpointRequest) (*SetRemoteEndpointResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method SetLoggingEndpoint not implemented")
+}
+func (*UnimplementedNativeHWManagementServiceServer) GetLoggingEndpoint(ctx context.Context, req *HardwareID) (*GetLoggingEndpointResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method GetLoggingEndpoint not implemented")
+}
+func (*UnimplementedNativeHWManagementServiceServer) SetMsgBusEndpoint(ctx context.Context, req *SetMsgBusEndpointRequest) (*SetRemoteEndpointResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method SetMsgBusEndpoint not implemented")
+}
+func (*UnimplementedNativeHWManagementServiceServer) GetMsgBusEndpoint(ctx context.Context, req *empty.Empty) (*GetMsgBusEndpointResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method GetMsgBusEndpoint not implemented")
+}
+func (*UnimplementedNativeHWManagementServiceServer) GetLoggableEntities(ctx context.Context, req *GetLoggableEntitiesRequest) (*GetLogLevelResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method GetLoggableEntities not implemented")
+}
+func (*UnimplementedNativeHWManagementServiceServer) SetLogLevel(ctx context.Context, req *SetLogLevelRequest) (*SetLogLevelResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method SetLogLevel not implemented")
+}
+func (*UnimplementedNativeHWManagementServiceServer) GetLogLevel(ctx context.Context, req *GetLogLevelRequest) (*GetLogLevelResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method GetLogLevel not implemented")
+}
+
 func RegisterNativeHWManagementServiceServer(s *grpc.Server, srv NativeHWManagementServiceServer) {
 	s.RegisterService(&_NativeHWManagementService_serviceDesc, srv)
 }
diff --git a/go/dmi/hw_metrics_mgmt_service.pb.go b/go/dmi/hw_metrics_mgmt_service.pb.go
index b812950..e3d211f 100644
--- a/go/dmi/hw_metrics_mgmt_service.pb.go
+++ b/go/dmi/hw_metrics_mgmt_service.pb.go
@@ -8,6 +8,8 @@
 	fmt "fmt"
 	proto "github.com/golang/protobuf/proto"
 	grpc "google.golang.org/grpc"
+	codes "google.golang.org/grpc/codes"
+	status "google.golang.org/grpc/status"
 	math "math"
 )
 
@@ -927,6 +929,20 @@
 	GetMetric(context.Context, *GetMetricRequest) (*GetMetricResponse, error)
 }
 
+// UnimplementedNativeMetricsManagementServiceServer can be embedded to have forward compatible implementations.
+type UnimplementedNativeMetricsManagementServiceServer struct {
+}
+
+func (*UnimplementedNativeMetricsManagementServiceServer) ListMetrics(ctx context.Context, req *HardwareID) (*ListMetricsResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method ListMetrics not implemented")
+}
+func (*UnimplementedNativeMetricsManagementServiceServer) UpdateMetricsConfiguration(ctx context.Context, req *MetricsConfigurationRequest) (*MetricsConfigurationResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method UpdateMetricsConfiguration not implemented")
+}
+func (*UnimplementedNativeMetricsManagementServiceServer) GetMetric(ctx context.Context, req *GetMetricRequest) (*GetMetricResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method GetMetric not implemented")
+}
+
 func RegisterNativeMetricsManagementServiceServer(s *grpc.Server, srv NativeMetricsManagementServiceServer) {
 	s.RegisterService(&_NativeMetricsManagementService_serviceDesc, srv)
 }
diff --git a/go/dmi/sw_management_service.pb.go b/go/dmi/sw_management_service.pb.go
index 7dbb089..db176be 100644
--- a/go/dmi/sw_management_service.pb.go
+++ b/go/dmi/sw_management_service.pb.go
@@ -8,6 +8,8 @@
 	fmt "fmt"
 	proto "github.com/golang/protobuf/proto"
 	grpc "google.golang.org/grpc"
+	codes "google.golang.org/grpc/codes"
+	status "google.golang.org/grpc/status"
 	math "math"
 )
 
@@ -773,6 +775,29 @@
 	GetStartupConfigurationInfo(context.Context, *StartupConfigInfoRequest) (*StartupConfigInfoResponse, error)
 }
 
+// UnimplementedNativeSoftwareManagementServiceServer can be embedded to have forward compatible implementations.
+type UnimplementedNativeSoftwareManagementServiceServer struct {
+}
+
+func (*UnimplementedNativeSoftwareManagementServiceServer) GetSoftwareVersion(ctx context.Context, req *HardwareID) (*GetSoftwareVersionInformationResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method GetSoftwareVersion not implemented")
+}
+func (*UnimplementedNativeSoftwareManagementServiceServer) DownloadImage(req *DownloadImageRequest, srv NativeSoftwareManagementService_DownloadImageServer) error {
+	return status.Errorf(codes.Unimplemented, "method DownloadImage not implemented")
+}
+func (*UnimplementedNativeSoftwareManagementServiceServer) ActivateImage(req *HardwareID, srv NativeSoftwareManagementService_ActivateImageServer) error {
+	return status.Errorf(codes.Unimplemented, "method ActivateImage not implemented")
+}
+func (*UnimplementedNativeSoftwareManagementServiceServer) RevertToStandbyImage(req *HardwareID, srv NativeSoftwareManagementService_RevertToStandbyImageServer) error {
+	return status.Errorf(codes.Unimplemented, "method RevertToStandbyImage not implemented")
+}
+func (*UnimplementedNativeSoftwareManagementServiceServer) UpdateStartupConfiguration(req *ConfigRequest, srv NativeSoftwareManagementService_UpdateStartupConfigurationServer) error {
+	return status.Errorf(codes.Unimplemented, "method UpdateStartupConfiguration not implemented")
+}
+func (*UnimplementedNativeSoftwareManagementServiceServer) GetStartupConfigurationInfo(ctx context.Context, req *StartupConfigInfoRequest) (*StartupConfigInfoResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method GetStartupConfigurationInfo not implemented")
+}
+
 func RegisterNativeSoftwareManagementServiceServer(s *grpc.Server, srv NativeSoftwareManagementServiceServer) {
 	s.RegisterService(&_NativeSoftwareManagementService_serviceDesc, srv)
 }
