Initial commit: HC900 Crawler
Honeywell HC900을 Modbus TCP로 직접 폴링 → gRPC → C# 크롤러 → PostgreSQL. 기존 Experion OPC UA 데이터 경로를 HC900 직접 통신으로 대체. - industrial-comm/cpp: C++ Modbus 게이트웨이 (gRPC 서버) - src: C# .NET 8 ASP.NET Core 크롤러 + 웹 UI (3-Layer) - mcp-server: Python FastMCP (RAG/NL2SQL/P&ID) - 다중 컨트롤러(N-Controller) 지원 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
96
industrial-comm/cpp/CMakeLists.txt
Normal file
96
industrial-comm/cpp/CMakeLists.txt
Normal file
@@ -0,0 +1,96 @@
|
||||
cmake_minimum_required(VERSION 3.20)
|
||||
project(comm_core)
|
||||
|
||||
add_library(comm_core SHARED)
|
||||
|
||||
target_sources(comm_core
|
||||
PRIVATE
|
||||
src/controller.cpp
|
||||
src/codec.cpp
|
||||
)
|
||||
|
||||
target_include_directories(comm_core
|
||||
PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include
|
||||
)
|
||||
|
||||
target_compile_options(comm_core
|
||||
PRIVATE
|
||||
-Wall -Wextra -Wpedantic
|
||||
)
|
||||
|
||||
# ─── HC900 Gateway ───
|
||||
|
||||
set(GRPC_DIR /tmp/grpc_local)
|
||||
set(ABSL_DIR /tmp/absl_local)
|
||||
set(PROTO_GEN_DIR ${CMAKE_CURRENT_SOURCE_DIR}/gen)
|
||||
|
||||
add_executable(hc900_gateway)
|
||||
|
||||
target_sources(hc900_gateway
|
||||
PRIVATE
|
||||
src/gateway.cpp
|
||||
src/modbus_tcp.cpp
|
||||
${PROTO_GEN_DIR}/modbus_gateway.pb.cc
|
||||
${PROTO_GEN_DIR}/modbus_gateway.grpc.pb.cc
|
||||
)
|
||||
|
||||
target_include_directories(hc900_gateway
|
||||
PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include
|
||||
${PROTO_GEN_DIR}
|
||||
${GRPC_DIR}/usr/include
|
||||
${ABSL_DIR}/usr/include
|
||||
)
|
||||
|
||||
target_link_directories(hc900_gateway
|
||||
PRIVATE
|
||||
${GRPC_DIR}/usr/lib/aarch64-linux-gnu
|
||||
${ABSL_DIR}/usr/lib/aarch64-linux-gnu
|
||||
/usr/lib/aarch64-linux-gnu
|
||||
/lib/aarch64-linux-gnu
|
||||
)
|
||||
|
||||
target_link_libraries(hc900_gateway
|
||||
PRIVATE
|
||||
comm_core
|
||||
grpc++
|
||||
grpc
|
||||
gpr
|
||||
upb
|
||||
address_sorting
|
||||
protobuf
|
||||
absl_synchronization
|
||||
absl_status
|
||||
absl_cord
|
||||
absl_cord_internal
|
||||
absl_cordz_info
|
||||
absl_cordz_handle
|
||||
absl_cordz_functions
|
||||
absl_cordz_sample_token
|
||||
absl_hashtablez_sampler
|
||||
absl_exponential_biased
|
||||
absl_raw_hash_set
|
||||
absl_hash
|
||||
absl_city
|
||||
absl_low_level_hash
|
||||
absl_int128
|
||||
absl_raw_logging_internal
|
||||
absl_log_severity
|
||||
absl_spinlock_wait
|
||||
absl_malloc_internal
|
||||
absl_throw_delegate
|
||||
absl_time
|
||||
absl_time_zone
|
||||
absl_strings
|
||||
absl_strings_internal
|
||||
absl_base
|
||||
pthread
|
||||
rt
|
||||
dl
|
||||
)
|
||||
|
||||
target_compile_options(hc900_gateway
|
||||
PRIVATE
|
||||
-Wall -Wextra -Wpedantic
|
||||
)
|
||||
247
industrial-comm/cpp/gen/modbus_gateway.grpc.pb.cc
Normal file
247
industrial-comm/cpp/gen/modbus_gateway.grpc.pb.cc
Normal file
@@ -0,0 +1,247 @@
|
||||
// Generated by the gRPC C++ plugin.
|
||||
// If you make any local change, they will be lost.
|
||||
// source: modbus_gateway.proto
|
||||
|
||||
#include "modbus_gateway.pb.h"
|
||||
#include "modbus_gateway.grpc.pb.h"
|
||||
|
||||
#include <functional>
|
||||
#include <grpcpp/support/async_stream.h>
|
||||
#include <grpcpp/support/async_unary_call.h>
|
||||
#include <grpcpp/impl/channel_interface.h>
|
||||
#include <grpcpp/impl/client_unary_call.h>
|
||||
#include <grpcpp/support/client_callback.h>
|
||||
#include <grpcpp/support/message_allocator.h>
|
||||
#include <grpcpp/support/method_handler.h>
|
||||
#include <grpcpp/impl/rpc_service_method.h>
|
||||
#include <grpcpp/support/server_callback.h>
|
||||
#include <grpcpp/impl/codegen/server_callback_handlers.h>
|
||||
#include <grpcpp/server_context.h>
|
||||
#include <grpcpp/impl/service_type.h>
|
||||
#include <grpcpp/support/sync_stream.h>
|
||||
namespace hc900 {
|
||||
|
||||
static const char* ModbusGateway_method_names[] = {
|
||||
"/hc900.ModbusGateway/ReadTags",
|
||||
"/hc900.ModbusGateway/WriteTag",
|
||||
"/hc900.ModbusGateway/StreamTags",
|
||||
"/hc900.ModbusGateway/ListTags",
|
||||
"/hc900.ModbusGateway/HealthCheck",
|
||||
};
|
||||
|
||||
std::unique_ptr< ModbusGateway::Stub> ModbusGateway::NewStub(const std::shared_ptr< ::grpc::ChannelInterface>& channel, const ::grpc::StubOptions& options) {
|
||||
(void)options;
|
||||
std::unique_ptr< ModbusGateway::Stub> stub(new ModbusGateway::Stub(channel, options));
|
||||
return stub;
|
||||
}
|
||||
|
||||
ModbusGateway::Stub::Stub(const std::shared_ptr< ::grpc::ChannelInterface>& channel, const ::grpc::StubOptions& options)
|
||||
: channel_(channel), rpcmethod_ReadTags_(ModbusGateway_method_names[0], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel)
|
||||
, rpcmethod_WriteTag_(ModbusGateway_method_names[1], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel)
|
||||
, rpcmethod_StreamTags_(ModbusGateway_method_names[2], options.suffix_for_stats(),::grpc::internal::RpcMethod::SERVER_STREAMING, channel)
|
||||
, rpcmethod_ListTags_(ModbusGateway_method_names[3], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel)
|
||||
, rpcmethod_HealthCheck_(ModbusGateway_method_names[4], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel)
|
||||
{}
|
||||
|
||||
::grpc::Status ModbusGateway::Stub::ReadTags(::grpc::ClientContext* context, const ::hc900::ReadTagsRequest& request, ::hc900::ReadTagsResponse* response) {
|
||||
return ::grpc::internal::BlockingUnaryCall< ::hc900::ReadTagsRequest, ::hc900::ReadTagsResponse, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(channel_.get(), rpcmethod_ReadTags_, context, request, response);
|
||||
}
|
||||
|
||||
void ModbusGateway::Stub::async::ReadTags(::grpc::ClientContext* context, const ::hc900::ReadTagsRequest* request, ::hc900::ReadTagsResponse* response, std::function<void(::grpc::Status)> f) {
|
||||
::grpc::internal::CallbackUnaryCall< ::hc900::ReadTagsRequest, ::hc900::ReadTagsResponse, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(stub_->channel_.get(), stub_->rpcmethod_ReadTags_, context, request, response, std::move(f));
|
||||
}
|
||||
|
||||
void ModbusGateway::Stub::async::ReadTags(::grpc::ClientContext* context, const ::hc900::ReadTagsRequest* request, ::hc900::ReadTagsResponse* response, ::grpc::ClientUnaryReactor* reactor) {
|
||||
::grpc::internal::ClientCallbackUnaryFactory::Create< ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(stub_->channel_.get(), stub_->rpcmethod_ReadTags_, context, request, response, reactor);
|
||||
}
|
||||
|
||||
::grpc::ClientAsyncResponseReader< ::hc900::ReadTagsResponse>* ModbusGateway::Stub::PrepareAsyncReadTagsRaw(::grpc::ClientContext* context, const ::hc900::ReadTagsRequest& request, ::grpc::CompletionQueue* cq) {
|
||||
return ::grpc::internal::ClientAsyncResponseReaderHelper::Create< ::hc900::ReadTagsResponse, ::hc900::ReadTagsRequest, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(channel_.get(), cq, rpcmethod_ReadTags_, context, request);
|
||||
}
|
||||
|
||||
::grpc::ClientAsyncResponseReader< ::hc900::ReadTagsResponse>* ModbusGateway::Stub::AsyncReadTagsRaw(::grpc::ClientContext* context, const ::hc900::ReadTagsRequest& request, ::grpc::CompletionQueue* cq) {
|
||||
auto* result =
|
||||
this->PrepareAsyncReadTagsRaw(context, request, cq);
|
||||
result->StartCall();
|
||||
return result;
|
||||
}
|
||||
|
||||
::grpc::Status ModbusGateway::Stub::WriteTag(::grpc::ClientContext* context, const ::hc900::WriteTagRequest& request, ::hc900::WriteTagResponse* response) {
|
||||
return ::grpc::internal::BlockingUnaryCall< ::hc900::WriteTagRequest, ::hc900::WriteTagResponse, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(channel_.get(), rpcmethod_WriteTag_, context, request, response);
|
||||
}
|
||||
|
||||
void ModbusGateway::Stub::async::WriteTag(::grpc::ClientContext* context, const ::hc900::WriteTagRequest* request, ::hc900::WriteTagResponse* response, std::function<void(::grpc::Status)> f) {
|
||||
::grpc::internal::CallbackUnaryCall< ::hc900::WriteTagRequest, ::hc900::WriteTagResponse, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(stub_->channel_.get(), stub_->rpcmethod_WriteTag_, context, request, response, std::move(f));
|
||||
}
|
||||
|
||||
void ModbusGateway::Stub::async::WriteTag(::grpc::ClientContext* context, const ::hc900::WriteTagRequest* request, ::hc900::WriteTagResponse* response, ::grpc::ClientUnaryReactor* reactor) {
|
||||
::grpc::internal::ClientCallbackUnaryFactory::Create< ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(stub_->channel_.get(), stub_->rpcmethod_WriteTag_, context, request, response, reactor);
|
||||
}
|
||||
|
||||
::grpc::ClientAsyncResponseReader< ::hc900::WriteTagResponse>* ModbusGateway::Stub::PrepareAsyncWriteTagRaw(::grpc::ClientContext* context, const ::hc900::WriteTagRequest& request, ::grpc::CompletionQueue* cq) {
|
||||
return ::grpc::internal::ClientAsyncResponseReaderHelper::Create< ::hc900::WriteTagResponse, ::hc900::WriteTagRequest, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(channel_.get(), cq, rpcmethod_WriteTag_, context, request);
|
||||
}
|
||||
|
||||
::grpc::ClientAsyncResponseReader< ::hc900::WriteTagResponse>* ModbusGateway::Stub::AsyncWriteTagRaw(::grpc::ClientContext* context, const ::hc900::WriteTagRequest& request, ::grpc::CompletionQueue* cq) {
|
||||
auto* result =
|
||||
this->PrepareAsyncWriteTagRaw(context, request, cq);
|
||||
result->StartCall();
|
||||
return result;
|
||||
}
|
||||
|
||||
::grpc::ClientReader< ::hc900::TagValue>* ModbusGateway::Stub::StreamTagsRaw(::grpc::ClientContext* context, const ::hc900::StreamTagsRequest& request) {
|
||||
return ::grpc::internal::ClientReaderFactory< ::hc900::TagValue>::Create(channel_.get(), rpcmethod_StreamTags_, context, request);
|
||||
}
|
||||
|
||||
void ModbusGateway::Stub::async::StreamTags(::grpc::ClientContext* context, const ::hc900::StreamTagsRequest* request, ::grpc::ClientReadReactor< ::hc900::TagValue>* reactor) {
|
||||
::grpc::internal::ClientCallbackReaderFactory< ::hc900::TagValue>::Create(stub_->channel_.get(), stub_->rpcmethod_StreamTags_, context, request, reactor);
|
||||
}
|
||||
|
||||
::grpc::ClientAsyncReader< ::hc900::TagValue>* ModbusGateway::Stub::AsyncStreamTagsRaw(::grpc::ClientContext* context, const ::hc900::StreamTagsRequest& request, ::grpc::CompletionQueue* cq, void* tag) {
|
||||
return ::grpc::internal::ClientAsyncReaderFactory< ::hc900::TagValue>::Create(channel_.get(), cq, rpcmethod_StreamTags_, context, request, true, tag);
|
||||
}
|
||||
|
||||
::grpc::ClientAsyncReader< ::hc900::TagValue>* ModbusGateway::Stub::PrepareAsyncStreamTagsRaw(::grpc::ClientContext* context, const ::hc900::StreamTagsRequest& request, ::grpc::CompletionQueue* cq) {
|
||||
return ::grpc::internal::ClientAsyncReaderFactory< ::hc900::TagValue>::Create(channel_.get(), cq, rpcmethod_StreamTags_, context, request, false, nullptr);
|
||||
}
|
||||
|
||||
::grpc::Status ModbusGateway::Stub::ListTags(::grpc::ClientContext* context, const ::hc900::ListTagsRequest& request, ::hc900::ListTagsResponse* response) {
|
||||
return ::grpc::internal::BlockingUnaryCall< ::hc900::ListTagsRequest, ::hc900::ListTagsResponse, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(channel_.get(), rpcmethod_ListTags_, context, request, response);
|
||||
}
|
||||
|
||||
void ModbusGateway::Stub::async::ListTags(::grpc::ClientContext* context, const ::hc900::ListTagsRequest* request, ::hc900::ListTagsResponse* response, std::function<void(::grpc::Status)> f) {
|
||||
::grpc::internal::CallbackUnaryCall< ::hc900::ListTagsRequest, ::hc900::ListTagsResponse, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(stub_->channel_.get(), stub_->rpcmethod_ListTags_, context, request, response, std::move(f));
|
||||
}
|
||||
|
||||
void ModbusGateway::Stub::async::ListTags(::grpc::ClientContext* context, const ::hc900::ListTagsRequest* request, ::hc900::ListTagsResponse* response, ::grpc::ClientUnaryReactor* reactor) {
|
||||
::grpc::internal::ClientCallbackUnaryFactory::Create< ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(stub_->channel_.get(), stub_->rpcmethod_ListTags_, context, request, response, reactor);
|
||||
}
|
||||
|
||||
::grpc::ClientAsyncResponseReader< ::hc900::ListTagsResponse>* ModbusGateway::Stub::PrepareAsyncListTagsRaw(::grpc::ClientContext* context, const ::hc900::ListTagsRequest& request, ::grpc::CompletionQueue* cq) {
|
||||
return ::grpc::internal::ClientAsyncResponseReaderHelper::Create< ::hc900::ListTagsResponse, ::hc900::ListTagsRequest, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(channel_.get(), cq, rpcmethod_ListTags_, context, request);
|
||||
}
|
||||
|
||||
::grpc::ClientAsyncResponseReader< ::hc900::ListTagsResponse>* ModbusGateway::Stub::AsyncListTagsRaw(::grpc::ClientContext* context, const ::hc900::ListTagsRequest& request, ::grpc::CompletionQueue* cq) {
|
||||
auto* result =
|
||||
this->PrepareAsyncListTagsRaw(context, request, cq);
|
||||
result->StartCall();
|
||||
return result;
|
||||
}
|
||||
|
||||
::grpc::Status ModbusGateway::Stub::HealthCheck(::grpc::ClientContext* context, const ::hc900::HealthCheckRequest& request, ::hc900::HealthCheckResponse* response) {
|
||||
return ::grpc::internal::BlockingUnaryCall< ::hc900::HealthCheckRequest, ::hc900::HealthCheckResponse, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(channel_.get(), rpcmethod_HealthCheck_, context, request, response);
|
||||
}
|
||||
|
||||
void ModbusGateway::Stub::async::HealthCheck(::grpc::ClientContext* context, const ::hc900::HealthCheckRequest* request, ::hc900::HealthCheckResponse* response, std::function<void(::grpc::Status)> f) {
|
||||
::grpc::internal::CallbackUnaryCall< ::hc900::HealthCheckRequest, ::hc900::HealthCheckResponse, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(stub_->channel_.get(), stub_->rpcmethod_HealthCheck_, context, request, response, std::move(f));
|
||||
}
|
||||
|
||||
void ModbusGateway::Stub::async::HealthCheck(::grpc::ClientContext* context, const ::hc900::HealthCheckRequest* request, ::hc900::HealthCheckResponse* response, ::grpc::ClientUnaryReactor* reactor) {
|
||||
::grpc::internal::ClientCallbackUnaryFactory::Create< ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(stub_->channel_.get(), stub_->rpcmethod_HealthCheck_, context, request, response, reactor);
|
||||
}
|
||||
|
||||
::grpc::ClientAsyncResponseReader< ::hc900::HealthCheckResponse>* ModbusGateway::Stub::PrepareAsyncHealthCheckRaw(::grpc::ClientContext* context, const ::hc900::HealthCheckRequest& request, ::grpc::CompletionQueue* cq) {
|
||||
return ::grpc::internal::ClientAsyncResponseReaderHelper::Create< ::hc900::HealthCheckResponse, ::hc900::HealthCheckRequest, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(channel_.get(), cq, rpcmethod_HealthCheck_, context, request);
|
||||
}
|
||||
|
||||
::grpc::ClientAsyncResponseReader< ::hc900::HealthCheckResponse>* ModbusGateway::Stub::AsyncHealthCheckRaw(::grpc::ClientContext* context, const ::hc900::HealthCheckRequest& request, ::grpc::CompletionQueue* cq) {
|
||||
auto* result =
|
||||
this->PrepareAsyncHealthCheckRaw(context, request, cq);
|
||||
result->StartCall();
|
||||
return result;
|
||||
}
|
||||
|
||||
ModbusGateway::Service::Service() {
|
||||
AddMethod(new ::grpc::internal::RpcServiceMethod(
|
||||
ModbusGateway_method_names[0],
|
||||
::grpc::internal::RpcMethod::NORMAL_RPC,
|
||||
new ::grpc::internal::RpcMethodHandler< ModbusGateway::Service, ::hc900::ReadTagsRequest, ::hc900::ReadTagsResponse, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(
|
||||
[](ModbusGateway::Service* service,
|
||||
::grpc::ServerContext* ctx,
|
||||
const ::hc900::ReadTagsRequest* req,
|
||||
::hc900::ReadTagsResponse* resp) {
|
||||
return service->ReadTags(ctx, req, resp);
|
||||
}, this)));
|
||||
AddMethod(new ::grpc::internal::RpcServiceMethod(
|
||||
ModbusGateway_method_names[1],
|
||||
::grpc::internal::RpcMethod::NORMAL_RPC,
|
||||
new ::grpc::internal::RpcMethodHandler< ModbusGateway::Service, ::hc900::WriteTagRequest, ::hc900::WriteTagResponse, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(
|
||||
[](ModbusGateway::Service* service,
|
||||
::grpc::ServerContext* ctx,
|
||||
const ::hc900::WriteTagRequest* req,
|
||||
::hc900::WriteTagResponse* resp) {
|
||||
return service->WriteTag(ctx, req, resp);
|
||||
}, this)));
|
||||
AddMethod(new ::grpc::internal::RpcServiceMethod(
|
||||
ModbusGateway_method_names[2],
|
||||
::grpc::internal::RpcMethod::SERVER_STREAMING,
|
||||
new ::grpc::internal::ServerStreamingHandler< ModbusGateway::Service, ::hc900::StreamTagsRequest, ::hc900::TagValue>(
|
||||
[](ModbusGateway::Service* service,
|
||||
::grpc::ServerContext* ctx,
|
||||
const ::hc900::StreamTagsRequest* req,
|
||||
::grpc::ServerWriter<::hc900::TagValue>* writer) {
|
||||
return service->StreamTags(ctx, req, writer);
|
||||
}, this)));
|
||||
AddMethod(new ::grpc::internal::RpcServiceMethod(
|
||||
ModbusGateway_method_names[3],
|
||||
::grpc::internal::RpcMethod::NORMAL_RPC,
|
||||
new ::grpc::internal::RpcMethodHandler< ModbusGateway::Service, ::hc900::ListTagsRequest, ::hc900::ListTagsResponse, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(
|
||||
[](ModbusGateway::Service* service,
|
||||
::grpc::ServerContext* ctx,
|
||||
const ::hc900::ListTagsRequest* req,
|
||||
::hc900::ListTagsResponse* resp) {
|
||||
return service->ListTags(ctx, req, resp);
|
||||
}, this)));
|
||||
AddMethod(new ::grpc::internal::RpcServiceMethod(
|
||||
ModbusGateway_method_names[4],
|
||||
::grpc::internal::RpcMethod::NORMAL_RPC,
|
||||
new ::grpc::internal::RpcMethodHandler< ModbusGateway::Service, ::hc900::HealthCheckRequest, ::hc900::HealthCheckResponse, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(
|
||||
[](ModbusGateway::Service* service,
|
||||
::grpc::ServerContext* ctx,
|
||||
const ::hc900::HealthCheckRequest* req,
|
||||
::hc900::HealthCheckResponse* resp) {
|
||||
return service->HealthCheck(ctx, req, resp);
|
||||
}, this)));
|
||||
}
|
||||
|
||||
ModbusGateway::Service::~Service() {
|
||||
}
|
||||
|
||||
::grpc::Status ModbusGateway::Service::ReadTags(::grpc::ServerContext* context, const ::hc900::ReadTagsRequest* request, ::hc900::ReadTagsResponse* response) {
|
||||
(void) context;
|
||||
(void) request;
|
||||
(void) response;
|
||||
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
|
||||
}
|
||||
|
||||
::grpc::Status ModbusGateway::Service::WriteTag(::grpc::ServerContext* context, const ::hc900::WriteTagRequest* request, ::hc900::WriteTagResponse* response) {
|
||||
(void) context;
|
||||
(void) request;
|
||||
(void) response;
|
||||
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
|
||||
}
|
||||
|
||||
::grpc::Status ModbusGateway::Service::StreamTags(::grpc::ServerContext* context, const ::hc900::StreamTagsRequest* request, ::grpc::ServerWriter< ::hc900::TagValue>* writer) {
|
||||
(void) context;
|
||||
(void) request;
|
||||
(void) writer;
|
||||
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
|
||||
}
|
||||
|
||||
::grpc::Status ModbusGateway::Service::ListTags(::grpc::ServerContext* context, const ::hc900::ListTagsRequest* request, ::hc900::ListTagsResponse* response) {
|
||||
(void) context;
|
||||
(void) request;
|
||||
(void) response;
|
||||
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
|
||||
}
|
||||
|
||||
::grpc::Status ModbusGateway::Service::HealthCheck(::grpc::ServerContext* context, const ::hc900::HealthCheckRequest* request, ::hc900::HealthCheckResponse* response) {
|
||||
(void) context;
|
||||
(void) request;
|
||||
(void) response;
|
||||
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
|
||||
}
|
||||
|
||||
|
||||
} // namespace hc900
|
||||
|
||||
869
industrial-comm/cpp/gen/modbus_gateway.grpc.pb.h
Normal file
869
industrial-comm/cpp/gen/modbus_gateway.grpc.pb.h
Normal file
@@ -0,0 +1,869 @@
|
||||
// Generated by the gRPC C++ plugin.
|
||||
// If you make any local change, they will be lost.
|
||||
// source: modbus_gateway.proto
|
||||
#ifndef GRPC_modbus_5fgateway_2eproto__INCLUDED
|
||||
#define GRPC_modbus_5fgateway_2eproto__INCLUDED
|
||||
|
||||
#include "modbus_gateway.pb.h"
|
||||
|
||||
#include <functional>
|
||||
#include <grpcpp/generic/async_generic_service.h>
|
||||
#include <grpcpp/support/async_stream.h>
|
||||
#include <grpcpp/support/async_unary_call.h>
|
||||
#include <grpcpp/support/client_callback.h>
|
||||
#include <grpcpp/client_context.h>
|
||||
#include <grpcpp/completion_queue.h>
|
||||
#include <grpcpp/support/message_allocator.h>
|
||||
#include <grpcpp/support/method_handler.h>
|
||||
#include <grpcpp/impl/codegen/proto_utils.h>
|
||||
#include <grpcpp/impl/rpc_method.h>
|
||||
#include <grpcpp/support/server_callback.h>
|
||||
#include <grpcpp/impl/codegen/server_callback_handlers.h>
|
||||
#include <grpcpp/server_context.h>
|
||||
#include <grpcpp/impl/service_type.h>
|
||||
#include <grpcpp/impl/codegen/status.h>
|
||||
#include <grpcpp/support/stub_options.h>
|
||||
#include <grpcpp/support/sync_stream.h>
|
||||
|
||||
namespace hc900 {
|
||||
|
||||
// ─── Service ───
|
||||
//
|
||||
class ModbusGateway final {
|
||||
public:
|
||||
static constexpr char const* service_full_name() {
|
||||
return "hc900.ModbusGateway";
|
||||
}
|
||||
class StubInterface {
|
||||
public:
|
||||
virtual ~StubInterface() {}
|
||||
virtual ::grpc::Status ReadTags(::grpc::ClientContext* context, const ::hc900::ReadTagsRequest& request, ::hc900::ReadTagsResponse* response) = 0;
|
||||
std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::hc900::ReadTagsResponse>> AsyncReadTags(::grpc::ClientContext* context, const ::hc900::ReadTagsRequest& request, ::grpc::CompletionQueue* cq) {
|
||||
return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::hc900::ReadTagsResponse>>(AsyncReadTagsRaw(context, request, cq));
|
||||
}
|
||||
std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::hc900::ReadTagsResponse>> PrepareAsyncReadTags(::grpc::ClientContext* context, const ::hc900::ReadTagsRequest& request, ::grpc::CompletionQueue* cq) {
|
||||
return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::hc900::ReadTagsResponse>>(PrepareAsyncReadTagsRaw(context, request, cq));
|
||||
}
|
||||
virtual ::grpc::Status WriteTag(::grpc::ClientContext* context, const ::hc900::WriteTagRequest& request, ::hc900::WriteTagResponse* response) = 0;
|
||||
std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::hc900::WriteTagResponse>> AsyncWriteTag(::grpc::ClientContext* context, const ::hc900::WriteTagRequest& request, ::grpc::CompletionQueue* cq) {
|
||||
return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::hc900::WriteTagResponse>>(AsyncWriteTagRaw(context, request, cq));
|
||||
}
|
||||
std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::hc900::WriteTagResponse>> PrepareAsyncWriteTag(::grpc::ClientContext* context, const ::hc900::WriteTagRequest& request, ::grpc::CompletionQueue* cq) {
|
||||
return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::hc900::WriteTagResponse>>(PrepareAsyncWriteTagRaw(context, request, cq));
|
||||
}
|
||||
std::unique_ptr< ::grpc::ClientReaderInterface< ::hc900::TagValue>> StreamTags(::grpc::ClientContext* context, const ::hc900::StreamTagsRequest& request) {
|
||||
return std::unique_ptr< ::grpc::ClientReaderInterface< ::hc900::TagValue>>(StreamTagsRaw(context, request));
|
||||
}
|
||||
std::unique_ptr< ::grpc::ClientAsyncReaderInterface< ::hc900::TagValue>> AsyncStreamTags(::grpc::ClientContext* context, const ::hc900::StreamTagsRequest& request, ::grpc::CompletionQueue* cq, void* tag) {
|
||||
return std::unique_ptr< ::grpc::ClientAsyncReaderInterface< ::hc900::TagValue>>(AsyncStreamTagsRaw(context, request, cq, tag));
|
||||
}
|
||||
std::unique_ptr< ::grpc::ClientAsyncReaderInterface< ::hc900::TagValue>> PrepareAsyncStreamTags(::grpc::ClientContext* context, const ::hc900::StreamTagsRequest& request, ::grpc::CompletionQueue* cq) {
|
||||
return std::unique_ptr< ::grpc::ClientAsyncReaderInterface< ::hc900::TagValue>>(PrepareAsyncStreamTagsRaw(context, request, cq));
|
||||
}
|
||||
virtual ::grpc::Status ListTags(::grpc::ClientContext* context, const ::hc900::ListTagsRequest& request, ::hc900::ListTagsResponse* response) = 0;
|
||||
std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::hc900::ListTagsResponse>> AsyncListTags(::grpc::ClientContext* context, const ::hc900::ListTagsRequest& request, ::grpc::CompletionQueue* cq) {
|
||||
return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::hc900::ListTagsResponse>>(AsyncListTagsRaw(context, request, cq));
|
||||
}
|
||||
std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::hc900::ListTagsResponse>> PrepareAsyncListTags(::grpc::ClientContext* context, const ::hc900::ListTagsRequest& request, ::grpc::CompletionQueue* cq) {
|
||||
return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::hc900::ListTagsResponse>>(PrepareAsyncListTagsRaw(context, request, cq));
|
||||
}
|
||||
virtual ::grpc::Status HealthCheck(::grpc::ClientContext* context, const ::hc900::HealthCheckRequest& request, ::hc900::HealthCheckResponse* response) = 0;
|
||||
std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::hc900::HealthCheckResponse>> AsyncHealthCheck(::grpc::ClientContext* context, const ::hc900::HealthCheckRequest& request, ::grpc::CompletionQueue* cq) {
|
||||
return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::hc900::HealthCheckResponse>>(AsyncHealthCheckRaw(context, request, cq));
|
||||
}
|
||||
std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::hc900::HealthCheckResponse>> PrepareAsyncHealthCheck(::grpc::ClientContext* context, const ::hc900::HealthCheckRequest& request, ::grpc::CompletionQueue* cq) {
|
||||
return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::hc900::HealthCheckResponse>>(PrepareAsyncHealthCheckRaw(context, request, cq));
|
||||
}
|
||||
class async_interface {
|
||||
public:
|
||||
virtual ~async_interface() {}
|
||||
virtual void ReadTags(::grpc::ClientContext* context, const ::hc900::ReadTagsRequest* request, ::hc900::ReadTagsResponse* response, std::function<void(::grpc::Status)>) = 0;
|
||||
virtual void ReadTags(::grpc::ClientContext* context, const ::hc900::ReadTagsRequest* request, ::hc900::ReadTagsResponse* response, ::grpc::ClientUnaryReactor* reactor) = 0;
|
||||
virtual void WriteTag(::grpc::ClientContext* context, const ::hc900::WriteTagRequest* request, ::hc900::WriteTagResponse* response, std::function<void(::grpc::Status)>) = 0;
|
||||
virtual void WriteTag(::grpc::ClientContext* context, const ::hc900::WriteTagRequest* request, ::hc900::WriteTagResponse* response, ::grpc::ClientUnaryReactor* reactor) = 0;
|
||||
virtual void StreamTags(::grpc::ClientContext* context, const ::hc900::StreamTagsRequest* request, ::grpc::ClientReadReactor< ::hc900::TagValue>* reactor) = 0;
|
||||
virtual void ListTags(::grpc::ClientContext* context, const ::hc900::ListTagsRequest* request, ::hc900::ListTagsResponse* response, std::function<void(::grpc::Status)>) = 0;
|
||||
virtual void ListTags(::grpc::ClientContext* context, const ::hc900::ListTagsRequest* request, ::hc900::ListTagsResponse* response, ::grpc::ClientUnaryReactor* reactor) = 0;
|
||||
virtual void HealthCheck(::grpc::ClientContext* context, const ::hc900::HealthCheckRequest* request, ::hc900::HealthCheckResponse* response, std::function<void(::grpc::Status)>) = 0;
|
||||
virtual void HealthCheck(::grpc::ClientContext* context, const ::hc900::HealthCheckRequest* request, ::hc900::HealthCheckResponse* response, ::grpc::ClientUnaryReactor* reactor) = 0;
|
||||
};
|
||||
typedef class async_interface experimental_async_interface;
|
||||
virtual class async_interface* async() { return nullptr; }
|
||||
class async_interface* experimental_async() { return async(); }
|
||||
private:
|
||||
virtual ::grpc::ClientAsyncResponseReaderInterface< ::hc900::ReadTagsResponse>* AsyncReadTagsRaw(::grpc::ClientContext* context, const ::hc900::ReadTagsRequest& request, ::grpc::CompletionQueue* cq) = 0;
|
||||
virtual ::grpc::ClientAsyncResponseReaderInterface< ::hc900::ReadTagsResponse>* PrepareAsyncReadTagsRaw(::grpc::ClientContext* context, const ::hc900::ReadTagsRequest& request, ::grpc::CompletionQueue* cq) = 0;
|
||||
virtual ::grpc::ClientAsyncResponseReaderInterface< ::hc900::WriteTagResponse>* AsyncWriteTagRaw(::grpc::ClientContext* context, const ::hc900::WriteTagRequest& request, ::grpc::CompletionQueue* cq) = 0;
|
||||
virtual ::grpc::ClientAsyncResponseReaderInterface< ::hc900::WriteTagResponse>* PrepareAsyncWriteTagRaw(::grpc::ClientContext* context, const ::hc900::WriteTagRequest& request, ::grpc::CompletionQueue* cq) = 0;
|
||||
virtual ::grpc::ClientReaderInterface< ::hc900::TagValue>* StreamTagsRaw(::grpc::ClientContext* context, const ::hc900::StreamTagsRequest& request) = 0;
|
||||
virtual ::grpc::ClientAsyncReaderInterface< ::hc900::TagValue>* AsyncStreamTagsRaw(::grpc::ClientContext* context, const ::hc900::StreamTagsRequest& request, ::grpc::CompletionQueue* cq, void* tag) = 0;
|
||||
virtual ::grpc::ClientAsyncReaderInterface< ::hc900::TagValue>* PrepareAsyncStreamTagsRaw(::grpc::ClientContext* context, const ::hc900::StreamTagsRequest& request, ::grpc::CompletionQueue* cq) = 0;
|
||||
virtual ::grpc::ClientAsyncResponseReaderInterface< ::hc900::ListTagsResponse>* AsyncListTagsRaw(::grpc::ClientContext* context, const ::hc900::ListTagsRequest& request, ::grpc::CompletionQueue* cq) = 0;
|
||||
virtual ::grpc::ClientAsyncResponseReaderInterface< ::hc900::ListTagsResponse>* PrepareAsyncListTagsRaw(::grpc::ClientContext* context, const ::hc900::ListTagsRequest& request, ::grpc::CompletionQueue* cq) = 0;
|
||||
virtual ::grpc::ClientAsyncResponseReaderInterface< ::hc900::HealthCheckResponse>* AsyncHealthCheckRaw(::grpc::ClientContext* context, const ::hc900::HealthCheckRequest& request, ::grpc::CompletionQueue* cq) = 0;
|
||||
virtual ::grpc::ClientAsyncResponseReaderInterface< ::hc900::HealthCheckResponse>* PrepareAsyncHealthCheckRaw(::grpc::ClientContext* context, const ::hc900::HealthCheckRequest& request, ::grpc::CompletionQueue* cq) = 0;
|
||||
};
|
||||
class Stub final : public StubInterface {
|
||||
public:
|
||||
Stub(const std::shared_ptr< ::grpc::ChannelInterface>& channel, const ::grpc::StubOptions& options = ::grpc::StubOptions());
|
||||
::grpc::Status ReadTags(::grpc::ClientContext* context, const ::hc900::ReadTagsRequest& request, ::hc900::ReadTagsResponse* response) override;
|
||||
std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::hc900::ReadTagsResponse>> AsyncReadTags(::grpc::ClientContext* context, const ::hc900::ReadTagsRequest& request, ::grpc::CompletionQueue* cq) {
|
||||
return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::hc900::ReadTagsResponse>>(AsyncReadTagsRaw(context, request, cq));
|
||||
}
|
||||
std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::hc900::ReadTagsResponse>> PrepareAsyncReadTags(::grpc::ClientContext* context, const ::hc900::ReadTagsRequest& request, ::grpc::CompletionQueue* cq) {
|
||||
return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::hc900::ReadTagsResponse>>(PrepareAsyncReadTagsRaw(context, request, cq));
|
||||
}
|
||||
::grpc::Status WriteTag(::grpc::ClientContext* context, const ::hc900::WriteTagRequest& request, ::hc900::WriteTagResponse* response) override;
|
||||
std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::hc900::WriteTagResponse>> AsyncWriteTag(::grpc::ClientContext* context, const ::hc900::WriteTagRequest& request, ::grpc::CompletionQueue* cq) {
|
||||
return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::hc900::WriteTagResponse>>(AsyncWriteTagRaw(context, request, cq));
|
||||
}
|
||||
std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::hc900::WriteTagResponse>> PrepareAsyncWriteTag(::grpc::ClientContext* context, const ::hc900::WriteTagRequest& request, ::grpc::CompletionQueue* cq) {
|
||||
return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::hc900::WriteTagResponse>>(PrepareAsyncWriteTagRaw(context, request, cq));
|
||||
}
|
||||
std::unique_ptr< ::grpc::ClientReader< ::hc900::TagValue>> StreamTags(::grpc::ClientContext* context, const ::hc900::StreamTagsRequest& request) {
|
||||
return std::unique_ptr< ::grpc::ClientReader< ::hc900::TagValue>>(StreamTagsRaw(context, request));
|
||||
}
|
||||
std::unique_ptr< ::grpc::ClientAsyncReader< ::hc900::TagValue>> AsyncStreamTags(::grpc::ClientContext* context, const ::hc900::StreamTagsRequest& request, ::grpc::CompletionQueue* cq, void* tag) {
|
||||
return std::unique_ptr< ::grpc::ClientAsyncReader< ::hc900::TagValue>>(AsyncStreamTagsRaw(context, request, cq, tag));
|
||||
}
|
||||
std::unique_ptr< ::grpc::ClientAsyncReader< ::hc900::TagValue>> PrepareAsyncStreamTags(::grpc::ClientContext* context, const ::hc900::StreamTagsRequest& request, ::grpc::CompletionQueue* cq) {
|
||||
return std::unique_ptr< ::grpc::ClientAsyncReader< ::hc900::TagValue>>(PrepareAsyncStreamTagsRaw(context, request, cq));
|
||||
}
|
||||
::grpc::Status ListTags(::grpc::ClientContext* context, const ::hc900::ListTagsRequest& request, ::hc900::ListTagsResponse* response) override;
|
||||
std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::hc900::ListTagsResponse>> AsyncListTags(::grpc::ClientContext* context, const ::hc900::ListTagsRequest& request, ::grpc::CompletionQueue* cq) {
|
||||
return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::hc900::ListTagsResponse>>(AsyncListTagsRaw(context, request, cq));
|
||||
}
|
||||
std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::hc900::ListTagsResponse>> PrepareAsyncListTags(::grpc::ClientContext* context, const ::hc900::ListTagsRequest& request, ::grpc::CompletionQueue* cq) {
|
||||
return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::hc900::ListTagsResponse>>(PrepareAsyncListTagsRaw(context, request, cq));
|
||||
}
|
||||
::grpc::Status HealthCheck(::grpc::ClientContext* context, const ::hc900::HealthCheckRequest& request, ::hc900::HealthCheckResponse* response) override;
|
||||
std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::hc900::HealthCheckResponse>> AsyncHealthCheck(::grpc::ClientContext* context, const ::hc900::HealthCheckRequest& request, ::grpc::CompletionQueue* cq) {
|
||||
return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::hc900::HealthCheckResponse>>(AsyncHealthCheckRaw(context, request, cq));
|
||||
}
|
||||
std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::hc900::HealthCheckResponse>> PrepareAsyncHealthCheck(::grpc::ClientContext* context, const ::hc900::HealthCheckRequest& request, ::grpc::CompletionQueue* cq) {
|
||||
return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::hc900::HealthCheckResponse>>(PrepareAsyncHealthCheckRaw(context, request, cq));
|
||||
}
|
||||
class async final :
|
||||
public StubInterface::async_interface {
|
||||
public:
|
||||
void ReadTags(::grpc::ClientContext* context, const ::hc900::ReadTagsRequest* request, ::hc900::ReadTagsResponse* response, std::function<void(::grpc::Status)>) override;
|
||||
void ReadTags(::grpc::ClientContext* context, const ::hc900::ReadTagsRequest* request, ::hc900::ReadTagsResponse* response, ::grpc::ClientUnaryReactor* reactor) override;
|
||||
void WriteTag(::grpc::ClientContext* context, const ::hc900::WriteTagRequest* request, ::hc900::WriteTagResponse* response, std::function<void(::grpc::Status)>) override;
|
||||
void WriteTag(::grpc::ClientContext* context, const ::hc900::WriteTagRequest* request, ::hc900::WriteTagResponse* response, ::grpc::ClientUnaryReactor* reactor) override;
|
||||
void StreamTags(::grpc::ClientContext* context, const ::hc900::StreamTagsRequest* request, ::grpc::ClientReadReactor< ::hc900::TagValue>* reactor) override;
|
||||
void ListTags(::grpc::ClientContext* context, const ::hc900::ListTagsRequest* request, ::hc900::ListTagsResponse* response, std::function<void(::grpc::Status)>) override;
|
||||
void ListTags(::grpc::ClientContext* context, const ::hc900::ListTagsRequest* request, ::hc900::ListTagsResponse* response, ::grpc::ClientUnaryReactor* reactor) override;
|
||||
void HealthCheck(::grpc::ClientContext* context, const ::hc900::HealthCheckRequest* request, ::hc900::HealthCheckResponse* response, std::function<void(::grpc::Status)>) override;
|
||||
void HealthCheck(::grpc::ClientContext* context, const ::hc900::HealthCheckRequest* request, ::hc900::HealthCheckResponse* response, ::grpc::ClientUnaryReactor* reactor) override;
|
||||
private:
|
||||
friend class Stub;
|
||||
explicit async(Stub* stub): stub_(stub) { }
|
||||
Stub* stub() { return stub_; }
|
||||
Stub* stub_;
|
||||
};
|
||||
class async* async() override { return &async_stub_; }
|
||||
|
||||
private:
|
||||
std::shared_ptr< ::grpc::ChannelInterface> channel_;
|
||||
class async async_stub_{this};
|
||||
::grpc::ClientAsyncResponseReader< ::hc900::ReadTagsResponse>* AsyncReadTagsRaw(::grpc::ClientContext* context, const ::hc900::ReadTagsRequest& request, ::grpc::CompletionQueue* cq) override;
|
||||
::grpc::ClientAsyncResponseReader< ::hc900::ReadTagsResponse>* PrepareAsyncReadTagsRaw(::grpc::ClientContext* context, const ::hc900::ReadTagsRequest& request, ::grpc::CompletionQueue* cq) override;
|
||||
::grpc::ClientAsyncResponseReader< ::hc900::WriteTagResponse>* AsyncWriteTagRaw(::grpc::ClientContext* context, const ::hc900::WriteTagRequest& request, ::grpc::CompletionQueue* cq) override;
|
||||
::grpc::ClientAsyncResponseReader< ::hc900::WriteTagResponse>* PrepareAsyncWriteTagRaw(::grpc::ClientContext* context, const ::hc900::WriteTagRequest& request, ::grpc::CompletionQueue* cq) override;
|
||||
::grpc::ClientReader< ::hc900::TagValue>* StreamTagsRaw(::grpc::ClientContext* context, const ::hc900::StreamTagsRequest& request) override;
|
||||
::grpc::ClientAsyncReader< ::hc900::TagValue>* AsyncStreamTagsRaw(::grpc::ClientContext* context, const ::hc900::StreamTagsRequest& request, ::grpc::CompletionQueue* cq, void* tag) override;
|
||||
::grpc::ClientAsyncReader< ::hc900::TagValue>* PrepareAsyncStreamTagsRaw(::grpc::ClientContext* context, const ::hc900::StreamTagsRequest& request, ::grpc::CompletionQueue* cq) override;
|
||||
::grpc::ClientAsyncResponseReader< ::hc900::ListTagsResponse>* AsyncListTagsRaw(::grpc::ClientContext* context, const ::hc900::ListTagsRequest& request, ::grpc::CompletionQueue* cq) override;
|
||||
::grpc::ClientAsyncResponseReader< ::hc900::ListTagsResponse>* PrepareAsyncListTagsRaw(::grpc::ClientContext* context, const ::hc900::ListTagsRequest& request, ::grpc::CompletionQueue* cq) override;
|
||||
::grpc::ClientAsyncResponseReader< ::hc900::HealthCheckResponse>* AsyncHealthCheckRaw(::grpc::ClientContext* context, const ::hc900::HealthCheckRequest& request, ::grpc::CompletionQueue* cq) override;
|
||||
::grpc::ClientAsyncResponseReader< ::hc900::HealthCheckResponse>* PrepareAsyncHealthCheckRaw(::grpc::ClientContext* context, const ::hc900::HealthCheckRequest& request, ::grpc::CompletionQueue* cq) override;
|
||||
const ::grpc::internal::RpcMethod rpcmethod_ReadTags_;
|
||||
const ::grpc::internal::RpcMethod rpcmethod_WriteTag_;
|
||||
const ::grpc::internal::RpcMethod rpcmethod_StreamTags_;
|
||||
const ::grpc::internal::RpcMethod rpcmethod_ListTags_;
|
||||
const ::grpc::internal::RpcMethod rpcmethod_HealthCheck_;
|
||||
};
|
||||
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();
|
||||
virtual ::grpc::Status ReadTags(::grpc::ServerContext* context, const ::hc900::ReadTagsRequest* request, ::hc900::ReadTagsResponse* response);
|
||||
virtual ::grpc::Status WriteTag(::grpc::ServerContext* context, const ::hc900::WriteTagRequest* request, ::hc900::WriteTagResponse* response);
|
||||
virtual ::grpc::Status StreamTags(::grpc::ServerContext* context, const ::hc900::StreamTagsRequest* request, ::grpc::ServerWriter< ::hc900::TagValue>* writer);
|
||||
virtual ::grpc::Status ListTags(::grpc::ServerContext* context, const ::hc900::ListTagsRequest* request, ::hc900::ListTagsResponse* response);
|
||||
virtual ::grpc::Status HealthCheck(::grpc::ServerContext* context, const ::hc900::HealthCheckRequest* request, ::hc900::HealthCheckResponse* response);
|
||||
};
|
||||
template <class BaseClass>
|
||||
class WithAsyncMethod_ReadTags : public BaseClass {
|
||||
private:
|
||||
void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
|
||||
public:
|
||||
WithAsyncMethod_ReadTags() {
|
||||
::grpc::Service::MarkMethodAsync(0);
|
||||
}
|
||||
~WithAsyncMethod_ReadTags() override {
|
||||
BaseClassMustBeDerivedFromService(this);
|
||||
}
|
||||
// disable synchronous version of this method
|
||||
::grpc::Status ReadTags(::grpc::ServerContext* /*context*/, const ::hc900::ReadTagsRequest* /*request*/, ::hc900::ReadTagsResponse* /*response*/) override {
|
||||
abort();
|
||||
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
|
||||
}
|
||||
void RequestReadTags(::grpc::ServerContext* context, ::hc900::ReadTagsRequest* request, ::grpc::ServerAsyncResponseWriter< ::hc900::ReadTagsResponse>* 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_WriteTag : public BaseClass {
|
||||
private:
|
||||
void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
|
||||
public:
|
||||
WithAsyncMethod_WriteTag() {
|
||||
::grpc::Service::MarkMethodAsync(1);
|
||||
}
|
||||
~WithAsyncMethod_WriteTag() override {
|
||||
BaseClassMustBeDerivedFromService(this);
|
||||
}
|
||||
// disable synchronous version of this method
|
||||
::grpc::Status WriteTag(::grpc::ServerContext* /*context*/, const ::hc900::WriteTagRequest* /*request*/, ::hc900::WriteTagResponse* /*response*/) override {
|
||||
abort();
|
||||
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
|
||||
}
|
||||
void RequestWriteTag(::grpc::ServerContext* context, ::hc900::WriteTagRequest* request, ::grpc::ServerAsyncResponseWriter< ::hc900::WriteTagResponse>* 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_StreamTags : public BaseClass {
|
||||
private:
|
||||
void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
|
||||
public:
|
||||
WithAsyncMethod_StreamTags() {
|
||||
::grpc::Service::MarkMethodAsync(2);
|
||||
}
|
||||
~WithAsyncMethod_StreamTags() override {
|
||||
BaseClassMustBeDerivedFromService(this);
|
||||
}
|
||||
// disable synchronous version of this method
|
||||
::grpc::Status StreamTags(::grpc::ServerContext* /*context*/, const ::hc900::StreamTagsRequest* /*request*/, ::grpc::ServerWriter< ::hc900::TagValue>* /*writer*/) override {
|
||||
abort();
|
||||
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
|
||||
}
|
||||
void RequestStreamTags(::grpc::ServerContext* context, ::hc900::StreamTagsRequest* request, ::grpc::ServerAsyncWriter< ::hc900::TagValue>* 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_ListTags : public BaseClass {
|
||||
private:
|
||||
void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
|
||||
public:
|
||||
WithAsyncMethod_ListTags() {
|
||||
::grpc::Service::MarkMethodAsync(3);
|
||||
}
|
||||
~WithAsyncMethod_ListTags() override {
|
||||
BaseClassMustBeDerivedFromService(this);
|
||||
}
|
||||
// disable synchronous version of this method
|
||||
::grpc::Status ListTags(::grpc::ServerContext* /*context*/, const ::hc900::ListTagsRequest* /*request*/, ::hc900::ListTagsResponse* /*response*/) override {
|
||||
abort();
|
||||
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
|
||||
}
|
||||
void RequestListTags(::grpc::ServerContext* context, ::hc900::ListTagsRequest* request, ::grpc::ServerAsyncResponseWriter< ::hc900::ListTagsResponse>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
|
||||
::grpc::Service::RequestAsyncUnary(3, context, request, response, new_call_cq, notification_cq, tag);
|
||||
}
|
||||
};
|
||||
template <class BaseClass>
|
||||
class WithAsyncMethod_HealthCheck : public BaseClass {
|
||||
private:
|
||||
void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
|
||||
public:
|
||||
WithAsyncMethod_HealthCheck() {
|
||||
::grpc::Service::MarkMethodAsync(4);
|
||||
}
|
||||
~WithAsyncMethod_HealthCheck() override {
|
||||
BaseClassMustBeDerivedFromService(this);
|
||||
}
|
||||
// disable synchronous version of this method
|
||||
::grpc::Status HealthCheck(::grpc::ServerContext* /*context*/, const ::hc900::HealthCheckRequest* /*request*/, ::hc900::HealthCheckResponse* /*response*/) override {
|
||||
abort();
|
||||
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
|
||||
}
|
||||
void RequestHealthCheck(::grpc::ServerContext* context, ::hc900::HealthCheckRequest* request, ::grpc::ServerAsyncResponseWriter< ::hc900::HealthCheckResponse>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
|
||||
::grpc::Service::RequestAsyncUnary(4, context, request, response, new_call_cq, notification_cq, tag);
|
||||
}
|
||||
};
|
||||
typedef WithAsyncMethod_ReadTags<WithAsyncMethod_WriteTag<WithAsyncMethod_StreamTags<WithAsyncMethod_ListTags<WithAsyncMethod_HealthCheck<Service > > > > > AsyncService;
|
||||
template <class BaseClass>
|
||||
class WithCallbackMethod_ReadTags : public BaseClass {
|
||||
private:
|
||||
void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
|
||||
public:
|
||||
WithCallbackMethod_ReadTags() {
|
||||
::grpc::Service::MarkMethodCallback(0,
|
||||
new ::grpc::internal::CallbackUnaryHandler< ::hc900::ReadTagsRequest, ::hc900::ReadTagsResponse>(
|
||||
[this](
|
||||
::grpc::CallbackServerContext* context, const ::hc900::ReadTagsRequest* request, ::hc900::ReadTagsResponse* response) { return this->ReadTags(context, request, response); }));}
|
||||
void SetMessageAllocatorFor_ReadTags(
|
||||
::grpc::MessageAllocator< ::hc900::ReadTagsRequest, ::hc900::ReadTagsResponse>* allocator) {
|
||||
::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(0);
|
||||
static_cast<::grpc::internal::CallbackUnaryHandler< ::hc900::ReadTagsRequest, ::hc900::ReadTagsResponse>*>(handler)
|
||||
->SetMessageAllocator(allocator);
|
||||
}
|
||||
~WithCallbackMethod_ReadTags() override {
|
||||
BaseClassMustBeDerivedFromService(this);
|
||||
}
|
||||
// disable synchronous version of this method
|
||||
::grpc::Status ReadTags(::grpc::ServerContext* /*context*/, const ::hc900::ReadTagsRequest* /*request*/, ::hc900::ReadTagsResponse* /*response*/) override {
|
||||
abort();
|
||||
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
|
||||
}
|
||||
virtual ::grpc::ServerUnaryReactor* ReadTags(
|
||||
::grpc::CallbackServerContext* /*context*/, const ::hc900::ReadTagsRequest* /*request*/, ::hc900::ReadTagsResponse* /*response*/) { return nullptr; }
|
||||
};
|
||||
template <class BaseClass>
|
||||
class WithCallbackMethod_WriteTag : public BaseClass {
|
||||
private:
|
||||
void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
|
||||
public:
|
||||
WithCallbackMethod_WriteTag() {
|
||||
::grpc::Service::MarkMethodCallback(1,
|
||||
new ::grpc::internal::CallbackUnaryHandler< ::hc900::WriteTagRequest, ::hc900::WriteTagResponse>(
|
||||
[this](
|
||||
::grpc::CallbackServerContext* context, const ::hc900::WriteTagRequest* request, ::hc900::WriteTagResponse* response) { return this->WriteTag(context, request, response); }));}
|
||||
void SetMessageAllocatorFor_WriteTag(
|
||||
::grpc::MessageAllocator< ::hc900::WriteTagRequest, ::hc900::WriteTagResponse>* allocator) {
|
||||
::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(1);
|
||||
static_cast<::grpc::internal::CallbackUnaryHandler< ::hc900::WriteTagRequest, ::hc900::WriteTagResponse>*>(handler)
|
||||
->SetMessageAllocator(allocator);
|
||||
}
|
||||
~WithCallbackMethod_WriteTag() override {
|
||||
BaseClassMustBeDerivedFromService(this);
|
||||
}
|
||||
// disable synchronous version of this method
|
||||
::grpc::Status WriteTag(::grpc::ServerContext* /*context*/, const ::hc900::WriteTagRequest* /*request*/, ::hc900::WriteTagResponse* /*response*/) override {
|
||||
abort();
|
||||
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
|
||||
}
|
||||
virtual ::grpc::ServerUnaryReactor* WriteTag(
|
||||
::grpc::CallbackServerContext* /*context*/, const ::hc900::WriteTagRequest* /*request*/, ::hc900::WriteTagResponse* /*response*/) { return nullptr; }
|
||||
};
|
||||
template <class BaseClass>
|
||||
class WithCallbackMethod_StreamTags : public BaseClass {
|
||||
private:
|
||||
void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
|
||||
public:
|
||||
WithCallbackMethod_StreamTags() {
|
||||
::grpc::Service::MarkMethodCallback(2,
|
||||
new ::grpc::internal::CallbackServerStreamingHandler< ::hc900::StreamTagsRequest, ::hc900::TagValue>(
|
||||
[this](
|
||||
::grpc::CallbackServerContext* context, const ::hc900::StreamTagsRequest* request) { return this->StreamTags(context, request); }));
|
||||
}
|
||||
~WithCallbackMethod_StreamTags() override {
|
||||
BaseClassMustBeDerivedFromService(this);
|
||||
}
|
||||
// disable synchronous version of this method
|
||||
::grpc::Status StreamTags(::grpc::ServerContext* /*context*/, const ::hc900::StreamTagsRequest* /*request*/, ::grpc::ServerWriter< ::hc900::TagValue>* /*writer*/) override {
|
||||
abort();
|
||||
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
|
||||
}
|
||||
virtual ::grpc::ServerWriteReactor< ::hc900::TagValue>* StreamTags(
|
||||
::grpc::CallbackServerContext* /*context*/, const ::hc900::StreamTagsRequest* /*request*/) { return nullptr; }
|
||||
};
|
||||
template <class BaseClass>
|
||||
class WithCallbackMethod_ListTags : public BaseClass {
|
||||
private:
|
||||
void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
|
||||
public:
|
||||
WithCallbackMethod_ListTags() {
|
||||
::grpc::Service::MarkMethodCallback(3,
|
||||
new ::grpc::internal::CallbackUnaryHandler< ::hc900::ListTagsRequest, ::hc900::ListTagsResponse>(
|
||||
[this](
|
||||
::grpc::CallbackServerContext* context, const ::hc900::ListTagsRequest* request, ::hc900::ListTagsResponse* response) { return this->ListTags(context, request, response); }));}
|
||||
void SetMessageAllocatorFor_ListTags(
|
||||
::grpc::MessageAllocator< ::hc900::ListTagsRequest, ::hc900::ListTagsResponse>* allocator) {
|
||||
::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(3);
|
||||
static_cast<::grpc::internal::CallbackUnaryHandler< ::hc900::ListTagsRequest, ::hc900::ListTagsResponse>*>(handler)
|
||||
->SetMessageAllocator(allocator);
|
||||
}
|
||||
~WithCallbackMethod_ListTags() override {
|
||||
BaseClassMustBeDerivedFromService(this);
|
||||
}
|
||||
// disable synchronous version of this method
|
||||
::grpc::Status ListTags(::grpc::ServerContext* /*context*/, const ::hc900::ListTagsRequest* /*request*/, ::hc900::ListTagsResponse* /*response*/) override {
|
||||
abort();
|
||||
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
|
||||
}
|
||||
virtual ::grpc::ServerUnaryReactor* ListTags(
|
||||
::grpc::CallbackServerContext* /*context*/, const ::hc900::ListTagsRequest* /*request*/, ::hc900::ListTagsResponse* /*response*/) { return nullptr; }
|
||||
};
|
||||
template <class BaseClass>
|
||||
class WithCallbackMethod_HealthCheck : public BaseClass {
|
||||
private:
|
||||
void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
|
||||
public:
|
||||
WithCallbackMethod_HealthCheck() {
|
||||
::grpc::Service::MarkMethodCallback(4,
|
||||
new ::grpc::internal::CallbackUnaryHandler< ::hc900::HealthCheckRequest, ::hc900::HealthCheckResponse>(
|
||||
[this](
|
||||
::grpc::CallbackServerContext* context, const ::hc900::HealthCheckRequest* request, ::hc900::HealthCheckResponse* response) { return this->HealthCheck(context, request, response); }));}
|
||||
void SetMessageAllocatorFor_HealthCheck(
|
||||
::grpc::MessageAllocator< ::hc900::HealthCheckRequest, ::hc900::HealthCheckResponse>* allocator) {
|
||||
::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(4);
|
||||
static_cast<::grpc::internal::CallbackUnaryHandler< ::hc900::HealthCheckRequest, ::hc900::HealthCheckResponse>*>(handler)
|
||||
->SetMessageAllocator(allocator);
|
||||
}
|
||||
~WithCallbackMethod_HealthCheck() override {
|
||||
BaseClassMustBeDerivedFromService(this);
|
||||
}
|
||||
// disable synchronous version of this method
|
||||
::grpc::Status HealthCheck(::grpc::ServerContext* /*context*/, const ::hc900::HealthCheckRequest* /*request*/, ::hc900::HealthCheckResponse* /*response*/) override {
|
||||
abort();
|
||||
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
|
||||
}
|
||||
virtual ::grpc::ServerUnaryReactor* HealthCheck(
|
||||
::grpc::CallbackServerContext* /*context*/, const ::hc900::HealthCheckRequest* /*request*/, ::hc900::HealthCheckResponse* /*response*/) { return nullptr; }
|
||||
};
|
||||
typedef WithCallbackMethod_ReadTags<WithCallbackMethod_WriteTag<WithCallbackMethod_StreamTags<WithCallbackMethod_ListTags<WithCallbackMethod_HealthCheck<Service > > > > > CallbackService;
|
||||
typedef CallbackService ExperimentalCallbackService;
|
||||
template <class BaseClass>
|
||||
class WithGenericMethod_ReadTags : public BaseClass {
|
||||
private:
|
||||
void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
|
||||
public:
|
||||
WithGenericMethod_ReadTags() {
|
||||
::grpc::Service::MarkMethodGeneric(0);
|
||||
}
|
||||
~WithGenericMethod_ReadTags() override {
|
||||
BaseClassMustBeDerivedFromService(this);
|
||||
}
|
||||
// disable synchronous version of this method
|
||||
::grpc::Status ReadTags(::grpc::ServerContext* /*context*/, const ::hc900::ReadTagsRequest* /*request*/, ::hc900::ReadTagsResponse* /*response*/) override {
|
||||
abort();
|
||||
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
|
||||
}
|
||||
};
|
||||
template <class BaseClass>
|
||||
class WithGenericMethod_WriteTag : public BaseClass {
|
||||
private:
|
||||
void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
|
||||
public:
|
||||
WithGenericMethod_WriteTag() {
|
||||
::grpc::Service::MarkMethodGeneric(1);
|
||||
}
|
||||
~WithGenericMethod_WriteTag() override {
|
||||
BaseClassMustBeDerivedFromService(this);
|
||||
}
|
||||
// disable synchronous version of this method
|
||||
::grpc::Status WriteTag(::grpc::ServerContext* /*context*/, const ::hc900::WriteTagRequest* /*request*/, ::hc900::WriteTagResponse* /*response*/) override {
|
||||
abort();
|
||||
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
|
||||
}
|
||||
};
|
||||
template <class BaseClass>
|
||||
class WithGenericMethod_StreamTags : public BaseClass {
|
||||
private:
|
||||
void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
|
||||
public:
|
||||
WithGenericMethod_StreamTags() {
|
||||
::grpc::Service::MarkMethodGeneric(2);
|
||||
}
|
||||
~WithGenericMethod_StreamTags() override {
|
||||
BaseClassMustBeDerivedFromService(this);
|
||||
}
|
||||
// disable synchronous version of this method
|
||||
::grpc::Status StreamTags(::grpc::ServerContext* /*context*/, const ::hc900::StreamTagsRequest* /*request*/, ::grpc::ServerWriter< ::hc900::TagValue>* /*writer*/) override {
|
||||
abort();
|
||||
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
|
||||
}
|
||||
};
|
||||
template <class BaseClass>
|
||||
class WithGenericMethod_ListTags : public BaseClass {
|
||||
private:
|
||||
void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
|
||||
public:
|
||||
WithGenericMethod_ListTags() {
|
||||
::grpc::Service::MarkMethodGeneric(3);
|
||||
}
|
||||
~WithGenericMethod_ListTags() override {
|
||||
BaseClassMustBeDerivedFromService(this);
|
||||
}
|
||||
// disable synchronous version of this method
|
||||
::grpc::Status ListTags(::grpc::ServerContext* /*context*/, const ::hc900::ListTagsRequest* /*request*/, ::hc900::ListTagsResponse* /*response*/) override {
|
||||
abort();
|
||||
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
|
||||
}
|
||||
};
|
||||
template <class BaseClass>
|
||||
class WithGenericMethod_HealthCheck : public BaseClass {
|
||||
private:
|
||||
void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
|
||||
public:
|
||||
WithGenericMethod_HealthCheck() {
|
||||
::grpc::Service::MarkMethodGeneric(4);
|
||||
}
|
||||
~WithGenericMethod_HealthCheck() override {
|
||||
BaseClassMustBeDerivedFromService(this);
|
||||
}
|
||||
// disable synchronous version of this method
|
||||
::grpc::Status HealthCheck(::grpc::ServerContext* /*context*/, const ::hc900::HealthCheckRequest* /*request*/, ::hc900::HealthCheckResponse* /*response*/) override {
|
||||
abort();
|
||||
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
|
||||
}
|
||||
};
|
||||
template <class BaseClass>
|
||||
class WithRawMethod_ReadTags : public BaseClass {
|
||||
private:
|
||||
void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
|
||||
public:
|
||||
WithRawMethod_ReadTags() {
|
||||
::grpc::Service::MarkMethodRaw(0);
|
||||
}
|
||||
~WithRawMethod_ReadTags() override {
|
||||
BaseClassMustBeDerivedFromService(this);
|
||||
}
|
||||
// disable synchronous version of this method
|
||||
::grpc::Status ReadTags(::grpc::ServerContext* /*context*/, const ::hc900::ReadTagsRequest* /*request*/, ::hc900::ReadTagsResponse* /*response*/) override {
|
||||
abort();
|
||||
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
|
||||
}
|
||||
void RequestReadTags(::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_WriteTag : public BaseClass {
|
||||
private:
|
||||
void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
|
||||
public:
|
||||
WithRawMethod_WriteTag() {
|
||||
::grpc::Service::MarkMethodRaw(1);
|
||||
}
|
||||
~WithRawMethod_WriteTag() override {
|
||||
BaseClassMustBeDerivedFromService(this);
|
||||
}
|
||||
// disable synchronous version of this method
|
||||
::grpc::Status WriteTag(::grpc::ServerContext* /*context*/, const ::hc900::WriteTagRequest* /*request*/, ::hc900::WriteTagResponse* /*response*/) override {
|
||||
abort();
|
||||
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
|
||||
}
|
||||
void RequestWriteTag(::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_StreamTags : public BaseClass {
|
||||
private:
|
||||
void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
|
||||
public:
|
||||
WithRawMethod_StreamTags() {
|
||||
::grpc::Service::MarkMethodRaw(2);
|
||||
}
|
||||
~WithRawMethod_StreamTags() override {
|
||||
BaseClassMustBeDerivedFromService(this);
|
||||
}
|
||||
// disable synchronous version of this method
|
||||
::grpc::Status StreamTags(::grpc::ServerContext* /*context*/, const ::hc900::StreamTagsRequest* /*request*/, ::grpc::ServerWriter< ::hc900::TagValue>* /*writer*/) override {
|
||||
abort();
|
||||
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
|
||||
}
|
||||
void RequestStreamTags(::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_ListTags : public BaseClass {
|
||||
private:
|
||||
void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
|
||||
public:
|
||||
WithRawMethod_ListTags() {
|
||||
::grpc::Service::MarkMethodRaw(3);
|
||||
}
|
||||
~WithRawMethod_ListTags() override {
|
||||
BaseClassMustBeDerivedFromService(this);
|
||||
}
|
||||
// disable synchronous version of this method
|
||||
::grpc::Status ListTags(::grpc::ServerContext* /*context*/, const ::hc900::ListTagsRequest* /*request*/, ::hc900::ListTagsResponse* /*response*/) override {
|
||||
abort();
|
||||
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
|
||||
}
|
||||
void RequestListTags(::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(3, context, request, response, new_call_cq, notification_cq, tag);
|
||||
}
|
||||
};
|
||||
template <class BaseClass>
|
||||
class WithRawMethod_HealthCheck : public BaseClass {
|
||||
private:
|
||||
void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
|
||||
public:
|
||||
WithRawMethod_HealthCheck() {
|
||||
::grpc::Service::MarkMethodRaw(4);
|
||||
}
|
||||
~WithRawMethod_HealthCheck() override {
|
||||
BaseClassMustBeDerivedFromService(this);
|
||||
}
|
||||
// disable synchronous version of this method
|
||||
::grpc::Status HealthCheck(::grpc::ServerContext* /*context*/, const ::hc900::HealthCheckRequest* /*request*/, ::hc900::HealthCheckResponse* /*response*/) override {
|
||||
abort();
|
||||
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
|
||||
}
|
||||
void RequestHealthCheck(::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(4, context, request, response, new_call_cq, notification_cq, tag);
|
||||
}
|
||||
};
|
||||
template <class BaseClass>
|
||||
class WithRawCallbackMethod_ReadTags : public BaseClass {
|
||||
private:
|
||||
void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
|
||||
public:
|
||||
WithRawCallbackMethod_ReadTags() {
|
||||
::grpc::Service::MarkMethodRawCallback(0,
|
||||
new ::grpc::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>(
|
||||
[this](
|
||||
::grpc::CallbackServerContext* context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response) { return this->ReadTags(context, request, response); }));
|
||||
}
|
||||
~WithRawCallbackMethod_ReadTags() override {
|
||||
BaseClassMustBeDerivedFromService(this);
|
||||
}
|
||||
// disable synchronous version of this method
|
||||
::grpc::Status ReadTags(::grpc::ServerContext* /*context*/, const ::hc900::ReadTagsRequest* /*request*/, ::hc900::ReadTagsResponse* /*response*/) override {
|
||||
abort();
|
||||
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
|
||||
}
|
||||
virtual ::grpc::ServerUnaryReactor* ReadTags(
|
||||
::grpc::CallbackServerContext* /*context*/, const ::grpc::ByteBuffer* /*request*/, ::grpc::ByteBuffer* /*response*/) { return nullptr; }
|
||||
};
|
||||
template <class BaseClass>
|
||||
class WithRawCallbackMethod_WriteTag : public BaseClass {
|
||||
private:
|
||||
void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
|
||||
public:
|
||||
WithRawCallbackMethod_WriteTag() {
|
||||
::grpc::Service::MarkMethodRawCallback(1,
|
||||
new ::grpc::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>(
|
||||
[this](
|
||||
::grpc::CallbackServerContext* context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response) { return this->WriteTag(context, request, response); }));
|
||||
}
|
||||
~WithRawCallbackMethod_WriteTag() override {
|
||||
BaseClassMustBeDerivedFromService(this);
|
||||
}
|
||||
// disable synchronous version of this method
|
||||
::grpc::Status WriteTag(::grpc::ServerContext* /*context*/, const ::hc900::WriteTagRequest* /*request*/, ::hc900::WriteTagResponse* /*response*/) override {
|
||||
abort();
|
||||
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
|
||||
}
|
||||
virtual ::grpc::ServerUnaryReactor* WriteTag(
|
||||
::grpc::CallbackServerContext* /*context*/, const ::grpc::ByteBuffer* /*request*/, ::grpc::ByteBuffer* /*response*/) { return nullptr; }
|
||||
};
|
||||
template <class BaseClass>
|
||||
class WithRawCallbackMethod_StreamTags : public BaseClass {
|
||||
private:
|
||||
void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
|
||||
public:
|
||||
WithRawCallbackMethod_StreamTags() {
|
||||
::grpc::Service::MarkMethodRawCallback(2,
|
||||
new ::grpc::internal::CallbackServerStreamingHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>(
|
||||
[this](
|
||||
::grpc::CallbackServerContext* context, const::grpc::ByteBuffer* request) { return this->StreamTags(context, request); }));
|
||||
}
|
||||
~WithRawCallbackMethod_StreamTags() override {
|
||||
BaseClassMustBeDerivedFromService(this);
|
||||
}
|
||||
// disable synchronous version of this method
|
||||
::grpc::Status StreamTags(::grpc::ServerContext* /*context*/, const ::hc900::StreamTagsRequest* /*request*/, ::grpc::ServerWriter< ::hc900::TagValue>* /*writer*/) override {
|
||||
abort();
|
||||
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
|
||||
}
|
||||
virtual ::grpc::ServerWriteReactor< ::grpc::ByteBuffer>* StreamTags(
|
||||
::grpc::CallbackServerContext* /*context*/, const ::grpc::ByteBuffer* /*request*/) { return nullptr; }
|
||||
};
|
||||
template <class BaseClass>
|
||||
class WithRawCallbackMethod_ListTags : public BaseClass {
|
||||
private:
|
||||
void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
|
||||
public:
|
||||
WithRawCallbackMethod_ListTags() {
|
||||
::grpc::Service::MarkMethodRawCallback(3,
|
||||
new ::grpc::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>(
|
||||
[this](
|
||||
::grpc::CallbackServerContext* context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response) { return this->ListTags(context, request, response); }));
|
||||
}
|
||||
~WithRawCallbackMethod_ListTags() override {
|
||||
BaseClassMustBeDerivedFromService(this);
|
||||
}
|
||||
// disable synchronous version of this method
|
||||
::grpc::Status ListTags(::grpc::ServerContext* /*context*/, const ::hc900::ListTagsRequest* /*request*/, ::hc900::ListTagsResponse* /*response*/) override {
|
||||
abort();
|
||||
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
|
||||
}
|
||||
virtual ::grpc::ServerUnaryReactor* ListTags(
|
||||
::grpc::CallbackServerContext* /*context*/, const ::grpc::ByteBuffer* /*request*/, ::grpc::ByteBuffer* /*response*/) { return nullptr; }
|
||||
};
|
||||
template <class BaseClass>
|
||||
class WithRawCallbackMethod_HealthCheck : public BaseClass {
|
||||
private:
|
||||
void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
|
||||
public:
|
||||
WithRawCallbackMethod_HealthCheck() {
|
||||
::grpc::Service::MarkMethodRawCallback(4,
|
||||
new ::grpc::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>(
|
||||
[this](
|
||||
::grpc::CallbackServerContext* context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response) { return this->HealthCheck(context, request, response); }));
|
||||
}
|
||||
~WithRawCallbackMethod_HealthCheck() override {
|
||||
BaseClassMustBeDerivedFromService(this);
|
||||
}
|
||||
// disable synchronous version of this method
|
||||
::grpc::Status HealthCheck(::grpc::ServerContext* /*context*/, const ::hc900::HealthCheckRequest* /*request*/, ::hc900::HealthCheckResponse* /*response*/) override {
|
||||
abort();
|
||||
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
|
||||
}
|
||||
virtual ::grpc::ServerUnaryReactor* HealthCheck(
|
||||
::grpc::CallbackServerContext* /*context*/, const ::grpc::ByteBuffer* /*request*/, ::grpc::ByteBuffer* /*response*/) { return nullptr; }
|
||||
};
|
||||
template <class BaseClass>
|
||||
class WithStreamedUnaryMethod_ReadTags : public BaseClass {
|
||||
private:
|
||||
void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
|
||||
public:
|
||||
WithStreamedUnaryMethod_ReadTags() {
|
||||
::grpc::Service::MarkMethodStreamed(0,
|
||||
new ::grpc::internal::StreamedUnaryHandler<
|
||||
::hc900::ReadTagsRequest, ::hc900::ReadTagsResponse>(
|
||||
[this](::grpc::ServerContext* context,
|
||||
::grpc::ServerUnaryStreamer<
|
||||
::hc900::ReadTagsRequest, ::hc900::ReadTagsResponse>* streamer) {
|
||||
return this->StreamedReadTags(context,
|
||||
streamer);
|
||||
}));
|
||||
}
|
||||
~WithStreamedUnaryMethod_ReadTags() override {
|
||||
BaseClassMustBeDerivedFromService(this);
|
||||
}
|
||||
// disable regular version of this method
|
||||
::grpc::Status ReadTags(::grpc::ServerContext* /*context*/, const ::hc900::ReadTagsRequest* /*request*/, ::hc900::ReadTagsResponse* /*response*/) override {
|
||||
abort();
|
||||
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
|
||||
}
|
||||
// replace default version of method with streamed unary
|
||||
virtual ::grpc::Status StreamedReadTags(::grpc::ServerContext* context, ::grpc::ServerUnaryStreamer< ::hc900::ReadTagsRequest,::hc900::ReadTagsResponse>* server_unary_streamer) = 0;
|
||||
};
|
||||
template <class BaseClass>
|
||||
class WithStreamedUnaryMethod_WriteTag : public BaseClass {
|
||||
private:
|
||||
void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
|
||||
public:
|
||||
WithStreamedUnaryMethod_WriteTag() {
|
||||
::grpc::Service::MarkMethodStreamed(1,
|
||||
new ::grpc::internal::StreamedUnaryHandler<
|
||||
::hc900::WriteTagRequest, ::hc900::WriteTagResponse>(
|
||||
[this](::grpc::ServerContext* context,
|
||||
::grpc::ServerUnaryStreamer<
|
||||
::hc900::WriteTagRequest, ::hc900::WriteTagResponse>* streamer) {
|
||||
return this->StreamedWriteTag(context,
|
||||
streamer);
|
||||
}));
|
||||
}
|
||||
~WithStreamedUnaryMethod_WriteTag() override {
|
||||
BaseClassMustBeDerivedFromService(this);
|
||||
}
|
||||
// disable regular version of this method
|
||||
::grpc::Status WriteTag(::grpc::ServerContext* /*context*/, const ::hc900::WriteTagRequest* /*request*/, ::hc900::WriteTagResponse* /*response*/) override {
|
||||
abort();
|
||||
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
|
||||
}
|
||||
// replace default version of method with streamed unary
|
||||
virtual ::grpc::Status StreamedWriteTag(::grpc::ServerContext* context, ::grpc::ServerUnaryStreamer< ::hc900::WriteTagRequest,::hc900::WriteTagResponse>* server_unary_streamer) = 0;
|
||||
};
|
||||
template <class BaseClass>
|
||||
class WithStreamedUnaryMethod_ListTags : public BaseClass {
|
||||
private:
|
||||
void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
|
||||
public:
|
||||
WithStreamedUnaryMethod_ListTags() {
|
||||
::grpc::Service::MarkMethodStreamed(3,
|
||||
new ::grpc::internal::StreamedUnaryHandler<
|
||||
::hc900::ListTagsRequest, ::hc900::ListTagsResponse>(
|
||||
[this](::grpc::ServerContext* context,
|
||||
::grpc::ServerUnaryStreamer<
|
||||
::hc900::ListTagsRequest, ::hc900::ListTagsResponse>* streamer) {
|
||||
return this->StreamedListTags(context,
|
||||
streamer);
|
||||
}));
|
||||
}
|
||||
~WithStreamedUnaryMethod_ListTags() override {
|
||||
BaseClassMustBeDerivedFromService(this);
|
||||
}
|
||||
// disable regular version of this method
|
||||
::grpc::Status ListTags(::grpc::ServerContext* /*context*/, const ::hc900::ListTagsRequest* /*request*/, ::hc900::ListTagsResponse* /*response*/) override {
|
||||
abort();
|
||||
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
|
||||
}
|
||||
// replace default version of method with streamed unary
|
||||
virtual ::grpc::Status StreamedListTags(::grpc::ServerContext* context, ::grpc::ServerUnaryStreamer< ::hc900::ListTagsRequest,::hc900::ListTagsResponse>* server_unary_streamer) = 0;
|
||||
};
|
||||
template <class BaseClass>
|
||||
class WithStreamedUnaryMethod_HealthCheck : public BaseClass {
|
||||
private:
|
||||
void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
|
||||
public:
|
||||
WithStreamedUnaryMethod_HealthCheck() {
|
||||
::grpc::Service::MarkMethodStreamed(4,
|
||||
new ::grpc::internal::StreamedUnaryHandler<
|
||||
::hc900::HealthCheckRequest, ::hc900::HealthCheckResponse>(
|
||||
[this](::grpc::ServerContext* context,
|
||||
::grpc::ServerUnaryStreamer<
|
||||
::hc900::HealthCheckRequest, ::hc900::HealthCheckResponse>* streamer) {
|
||||
return this->StreamedHealthCheck(context,
|
||||
streamer);
|
||||
}));
|
||||
}
|
||||
~WithStreamedUnaryMethod_HealthCheck() override {
|
||||
BaseClassMustBeDerivedFromService(this);
|
||||
}
|
||||
// disable regular version of this method
|
||||
::grpc::Status HealthCheck(::grpc::ServerContext* /*context*/, const ::hc900::HealthCheckRequest* /*request*/, ::hc900::HealthCheckResponse* /*response*/) override {
|
||||
abort();
|
||||
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
|
||||
}
|
||||
// replace default version of method with streamed unary
|
||||
virtual ::grpc::Status StreamedHealthCheck(::grpc::ServerContext* context, ::grpc::ServerUnaryStreamer< ::hc900::HealthCheckRequest,::hc900::HealthCheckResponse>* server_unary_streamer) = 0;
|
||||
};
|
||||
typedef WithStreamedUnaryMethod_ReadTags<WithStreamedUnaryMethod_WriteTag<WithStreamedUnaryMethod_ListTags<WithStreamedUnaryMethod_HealthCheck<Service > > > > StreamedUnaryService;
|
||||
template <class BaseClass>
|
||||
class WithSplitStreamingMethod_StreamTags : public BaseClass {
|
||||
private:
|
||||
void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
|
||||
public:
|
||||
WithSplitStreamingMethod_StreamTags() {
|
||||
::grpc::Service::MarkMethodStreamed(2,
|
||||
new ::grpc::internal::SplitServerStreamingHandler<
|
||||
::hc900::StreamTagsRequest, ::hc900::TagValue>(
|
||||
[this](::grpc::ServerContext* context,
|
||||
::grpc::ServerSplitStreamer<
|
||||
::hc900::StreamTagsRequest, ::hc900::TagValue>* streamer) {
|
||||
return this->StreamedStreamTags(context,
|
||||
streamer);
|
||||
}));
|
||||
}
|
||||
~WithSplitStreamingMethod_StreamTags() override {
|
||||
BaseClassMustBeDerivedFromService(this);
|
||||
}
|
||||
// disable regular version of this method
|
||||
::grpc::Status StreamTags(::grpc::ServerContext* /*context*/, const ::hc900::StreamTagsRequest* /*request*/, ::grpc::ServerWriter< ::hc900::TagValue>* /*writer*/) override {
|
||||
abort();
|
||||
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
|
||||
}
|
||||
// replace default version of method with split streamed
|
||||
virtual ::grpc::Status StreamedStreamTags(::grpc::ServerContext* context, ::grpc::ServerSplitStreamer< ::hc900::StreamTagsRequest,::hc900::TagValue>* server_split_streamer) = 0;
|
||||
};
|
||||
typedef WithSplitStreamingMethod_StreamTags<Service > SplitStreamedService;
|
||||
typedef WithStreamedUnaryMethod_ReadTags<WithStreamedUnaryMethod_WriteTag<WithSplitStreamingMethod_StreamTags<WithStreamedUnaryMethod_ListTags<WithStreamedUnaryMethod_HealthCheck<Service > > > > > StreamedService;
|
||||
};
|
||||
|
||||
} // namespace hc900
|
||||
|
||||
|
||||
#endif // GRPC_modbus_5fgateway_2eproto__INCLUDED
|
||||
3199
industrial-comm/cpp/gen/modbus_gateway.pb.cc
Normal file
3199
industrial-comm/cpp/gen/modbus_gateway.pb.cc
Normal file
File diff suppressed because it is too large
Load Diff
3362
industrial-comm/cpp/gen/modbus_gateway.pb.h
Normal file
3362
industrial-comm/cpp/gen/modbus_gateway.pb.h
Normal file
File diff suppressed because it is too large
Load Diff
6
industrial-comm/cpp/include/app_init.hpp
Normal file
6
industrial-comm/cpp/include/app_init.hpp
Normal file
@@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
#include <memory>
|
||||
|
||||
class Controller;
|
||||
|
||||
std::unique_ptr<Controller> init_system();
|
||||
76
industrial-comm/cpp/include/codec.hpp
Normal file
76
industrial-comm/cpp/include/codec.hpp
Normal file
@@ -0,0 +1,76 @@
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include "data_format.hpp"
|
||||
|
||||
//
|
||||
// ============================================================
|
||||
// 32-bit (float / int32 / uint32)
|
||||
// ============================================================
|
||||
|
||||
// float (IEEE-754, Modbus 2 registers)
|
||||
std::array<std::uint16_t, 2>
|
||||
encode_float(float value, const DataFormat& fmt);
|
||||
|
||||
float
|
||||
decode_float(std::uint16_t r0,
|
||||
std::uint16_t r1,
|
||||
const DataFormat& fmt);
|
||||
|
||||
// signed 32-bit
|
||||
std::array<std::uint16_t, 2>
|
||||
encode_int32(std::int32_t value, const DataFormat& fmt);
|
||||
|
||||
std::int32_t
|
||||
decode_int32(std::uint16_t r0,
|
||||
std::uint16_t r1,
|
||||
const DataFormat& fmt);
|
||||
|
||||
// unsigned 32-bit
|
||||
std::array<std::uint16_t, 2>
|
||||
encode_uint32(std::uint32_t value, const DataFormat& fmt);
|
||||
|
||||
std::uint32_t
|
||||
decode_uint32(std::uint16_t r0,
|
||||
std::uint16_t r1,
|
||||
const DataFormat& fmt);
|
||||
|
||||
|
||||
//
|
||||
// ============================================================
|
||||
// 64-bit (double / int64 / uint64)
|
||||
// ============================================================
|
||||
|
||||
// double (IEEE-754, Modbus 4 registers)
|
||||
std::array<std::uint16_t, 4>
|
||||
encode_double(double value, const DataFormat& fmt);
|
||||
|
||||
double
|
||||
decode_double(std::uint16_t r0,
|
||||
std::uint16_t r1,
|
||||
std::uint16_t r2,
|
||||
std::uint16_t r3,
|
||||
const DataFormat& fmt);
|
||||
|
||||
// signed 64-bit
|
||||
std::array<std::uint16_t, 4>
|
||||
encode_int64(std::int64_t value, const DataFormat& fmt);
|
||||
|
||||
std::int64_t
|
||||
decode_int64(std::uint16_t r0,
|
||||
std::uint16_t r1,
|
||||
std::uint16_t r2,
|
||||
std::uint16_t r3,
|
||||
const DataFormat& fmt);
|
||||
|
||||
// unsigned 64-bit
|
||||
std::array<std::uint16_t, 4>
|
||||
encode_uint64(std::uint64_t value, const DataFormat& fmt);
|
||||
|
||||
std::uint64_t
|
||||
decode_uint64(std::uint16_t r0,
|
||||
std::uint16_t r1,
|
||||
std::uint16_t r2,
|
||||
std::uint16_t r3,
|
||||
const DataFormat& fmt);
|
||||
47
industrial-comm/cpp/include/controller.hpp
Normal file
47
industrial-comm/cpp/include/controller.hpp
Normal file
@@ -0,0 +1,47 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include "itransport.hpp"
|
||||
#include "data_format.hpp"
|
||||
|
||||
class Controller {
|
||||
public:
|
||||
explicit Controller(std::unique_ptr<ITransport> transport);
|
||||
|
||||
// lifecycle
|
||||
void poll();
|
||||
bool connect(const char* host, std::uint16_t port);
|
||||
void disconnect();
|
||||
bool is_connected() const;
|
||||
|
||||
// raw register
|
||||
bool read_register(std::uint16_t addr, std::uint16_t& value);
|
||||
bool write_register(std::uint16_t addr, std::uint16_t value);
|
||||
bool read_raw(std::uint16_t addr, std::uint16_t count, std::vector<std::uint16_t>& out);
|
||||
|
||||
// 32-bit
|
||||
bool read_int32(std::uint16_t addr, std::int32_t& value, const DataFormat& fmt);
|
||||
bool write_int32(std::uint16_t addr, std::int32_t value, const DataFormat& fmt);
|
||||
|
||||
bool read_uint32(std::uint16_t addr, std::uint32_t& value, const DataFormat& fmt);
|
||||
bool write_uint32(std::uint16_t addr, std::uint32_t value, const DataFormat& fmt);
|
||||
|
||||
// float / double
|
||||
bool read_float(std::uint16_t addr, float& value, const DataFormat& fmt);
|
||||
bool write_float(std::uint16_t addr, float value, const DataFormat& fmt);
|
||||
|
||||
bool read_double(std::uint16_t addr, double& value, const DataFormat& fmt);
|
||||
bool write_double(std::uint16_t addr, double value, const DataFormat& fmt);
|
||||
|
||||
// 64-bit
|
||||
bool read_int64(std::uint16_t addr, std::int64_t& value, const DataFormat& fmt);
|
||||
bool write_int64(std::uint16_t addr, std::int64_t value, const DataFormat& fmt);
|
||||
|
||||
bool read_uint64(std::uint16_t addr, std::uint64_t& value, const DataFormat& fmt);
|
||||
bool write_uint64(std::uint16_t addr, std::uint64_t value, const DataFormat& fmt);
|
||||
|
||||
private:
|
||||
std::unique_ptr<ITransport> transport_;
|
||||
};
|
||||
27
industrial-comm/cpp/include/data_format.hpp
Normal file
27
industrial-comm/cpp/include/data_format.hpp
Normal file
@@ -0,0 +1,27 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
// Byte order inside a 16-bit Modbus register
|
||||
enum class ByteOrder {
|
||||
BigEndian, // AB
|
||||
LittleEndian // BA
|
||||
};
|
||||
|
||||
// Order of 16-bit registers
|
||||
enum class WordOrder {
|
||||
HighFirst, // Reg[N] = high word
|
||||
LowFirst // Reg[N] = low word
|
||||
};
|
||||
|
||||
// Order of register groups (for 64-bit+ types)
|
||||
enum class RegisterOrder {
|
||||
Normal, // ABCD EFGH
|
||||
Swapped // EFGH ABCD
|
||||
};
|
||||
|
||||
struct DataFormat {
|
||||
ByteOrder byte_order;
|
||||
WordOrder word_order;
|
||||
RegisterOrder register_order;
|
||||
};
|
||||
103
industrial-comm/cpp/include/gateway.h
Normal file
103
industrial-comm/cpp/include/gateway.h
Normal file
@@ -0,0 +1,103 @@
|
||||
#ifndef HC900_GATEWAY_H
|
||||
#define HC900_GATEWAY_H
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
#include <atomic>
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
#include <chrono>
|
||||
|
||||
#include "modbus_gateway.grpc.pb.h"
|
||||
#include "modbus_gateway.pb.h"
|
||||
|
||||
class Controller;
|
||||
|
||||
struct RegisterEntry {
|
||||
std::string tag;
|
||||
uint32_t addr;
|
||||
uint32_t count; // register count (1 or 2)
|
||||
std::string type; // "float32" or "uint16"
|
||||
std::string access; // "R" or "RW"
|
||||
};
|
||||
|
||||
struct CachedValue {
|
||||
float float32_val;
|
||||
uint32_t uint16_val;
|
||||
bool is_float;
|
||||
uint32_t quality; // 192=good, 0=bad
|
||||
std::chrono::system_clock::time_point timestamp;
|
||||
};
|
||||
|
||||
class Hc900Gateway final {
|
||||
public:
|
||||
Hc900Gateway(const std::string& host, uint16_t port,
|
||||
const std::string& map_path,
|
||||
int poll_interval_ms = 1000,
|
||||
int grpc_port = 50051);
|
||||
~Hc900Gateway();
|
||||
|
||||
bool Start();
|
||||
void Stop();
|
||||
|
||||
private:
|
||||
void PollLoop();
|
||||
void LoadRegisterMap(const std::string& path);
|
||||
void ReadAllRegisters();
|
||||
CachedValue ReadRegister(const RegisterEntry& entry);
|
||||
|
||||
// gRPC service implementation
|
||||
class GatewayServiceImpl final : public hc900::ModbusGateway::Service {
|
||||
public:
|
||||
GatewayServiceImpl(Hc900Gateway& gateway);
|
||||
grpc::Status ReadTags(grpc::ServerContext* ctx,
|
||||
const hc900::ReadTagsRequest* req,
|
||||
hc900::ReadTagsResponse* resp) override;
|
||||
grpc::Status WriteTag(grpc::ServerContext* ctx,
|
||||
const hc900::WriteTagRequest* req,
|
||||
hc900::WriteTagResponse* resp) override;
|
||||
grpc::Status ListTags(grpc::ServerContext* ctx,
|
||||
const hc900::ListTagsRequest* req,
|
||||
hc900::ListTagsResponse* resp) override;
|
||||
grpc::Status HealthCheck(grpc::ServerContext* ctx,
|
||||
const hc900::HealthCheckRequest* req,
|
||||
hc900::HealthCheckResponse* resp) override;
|
||||
grpc::Status StreamTags(grpc::ServerContext* ctx,
|
||||
const hc900::StreamTagsRequest* req,
|
||||
grpc::ServerWriter<hc900::TagValue>* writer) override;
|
||||
private:
|
||||
Hc900Gateway& gateway_;
|
||||
};
|
||||
|
||||
std::string host_;
|
||||
uint16_t port_;
|
||||
int poll_interval_ms_;
|
||||
std::unique_ptr<Controller> controller_;
|
||||
|
||||
// Register map
|
||||
std::vector<RegisterEntry> registers_;
|
||||
std::unordered_map<std::string, size_t> tag_index_;
|
||||
std::vector<size_t> sorted_indices_; // indices into registers_, sorted by address
|
||||
|
||||
// Cache
|
||||
std::unordered_map<std::string, CachedValue> cache_;
|
||||
mutable std::mutex cache_mutex_;
|
||||
|
||||
// Transport — shared between poll thread and gRPC handlers
|
||||
mutable std::mutex transport_mutex_;
|
||||
|
||||
// Poller
|
||||
std::atomic<bool> running_;
|
||||
std::thread poll_thread_;
|
||||
uint64_t poll_count_{0};
|
||||
std::chrono::milliseconds last_poll_duration_{0};
|
||||
|
||||
// gRPC server
|
||||
std::unique_ptr<grpc::Server> grpc_server_;
|
||||
std::unique_ptr<GatewayServiceImpl> grpc_service_;
|
||||
std::string grpc_listen_;
|
||||
};
|
||||
|
||||
#endif // HC900_GATEWAY_H
|
||||
47
industrial-comm/cpp/include/itransport.hpp
Normal file
47
industrial-comm/cpp/include/itransport.hpp
Normal file
@@ -0,0 +1,47 @@
|
||||
// ITransport 인터페이스 (🔥 최종본)
|
||||
// itransport.hpp
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
#include "transport_error.hpp"
|
||||
|
||||
// transport 상태관리
|
||||
enum class TransportState {
|
||||
Disconnected,
|
||||
Connecting,
|
||||
Connected,
|
||||
Reconnecting,
|
||||
Fault,
|
||||
};
|
||||
class ITransport {
|
||||
public:
|
||||
virtual ~ITransport() = default;
|
||||
|
||||
// connection
|
||||
virtual bool connect(const char* host, std::uint16_t port) = 0;
|
||||
virtual void disconnect() = 0;
|
||||
virtual bool is_connected() const = 0;
|
||||
|
||||
// state & error handling
|
||||
virtual TransportState state() const = 0;
|
||||
virtual TransportError last_error() const = 0;
|
||||
|
||||
// io policy
|
||||
virtual bool can_io() const = 0; // ⭐ 추가 (권장)
|
||||
|
||||
// watchdog / reconnect / state machine
|
||||
virtual void poll() = 0;
|
||||
virtual void reset() = 0; // ⭐ 추가
|
||||
|
||||
// register access
|
||||
virtual bool read_registers(std::uint16_t addr,
|
||||
std::uint16_t count,
|
||||
std::vector<std::uint16_t>& out) = 0;
|
||||
|
||||
virtual bool write_registers(std::uint16_t addr,
|
||||
const std::vector<std::uint16_t>& values) = 0;
|
||||
|
||||
};
|
||||
24765
industrial-comm/cpp/include/json.hpp
Normal file
24765
industrial-comm/cpp/include/json.hpp
Normal file
File diff suppressed because it is too large
Load Diff
12
industrial-comm/cpp/include/log_macros.hpp
Normal file
12
industrial-comm/cpp/include/log_macros.hpp
Normal file
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
#include "logger.hpp"
|
||||
|
||||
// 빌드 옵션으로 제어
|
||||
#ifndef ENABLE_DEBUG_LOG
|
||||
#define ENABLE_DEBUG_LOG 0
|
||||
#endif
|
||||
|
||||
#define LOG_INFO(msg) Logger::instance().log("INFO", msg)
|
||||
#define LOG_WARN(msg) Logger::instance().log("WARN", msg)
|
||||
#define LOG_ERROR(msg) Logger::instance().log("ERROR", msg)
|
||||
#define LOG_DEBUG(msg) Logger::instance().log("DEBUG", msg)
|
||||
53
industrial-comm/cpp/include/logger.hpp
Normal file
53
industrial-comm/cpp/include/logger.hpp
Normal file
@@ -0,0 +1,53 @@
|
||||
#pragma once
|
||||
|
||||
#include <fstream>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <chrono>
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
|
||||
class Logger {
|
||||
public:
|
||||
static Logger& instance() {
|
||||
static Logger inst;
|
||||
return inst;
|
||||
}
|
||||
|
||||
void set_file(const std::string& path) {
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
if (ofs_.is_open())
|
||||
ofs_.close();
|
||||
ofs_.open(path, std::ios::out | std::ios::app);
|
||||
}
|
||||
|
||||
void log(const char* level, const std::string& msg) {
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
if (!ofs_.is_open())
|
||||
return;
|
||||
|
||||
ofs_ << timestamp()
|
||||
<< " [" << level << "] "
|
||||
<< msg << "\n";
|
||||
ofs_.flush();
|
||||
}
|
||||
|
||||
private:
|
||||
Logger() = default;
|
||||
|
||||
std::string timestamp() {
|
||||
using namespace std::chrono;
|
||||
auto now = system_clock::now();
|
||||
auto t = system_clock::to_time_t(now);
|
||||
|
||||
std::tm tm{};
|
||||
localtime_r(&t, &tm);
|
||||
|
||||
std::ostringstream oss;
|
||||
oss << std::put_time(&tm, "%Y-%m-%d %H:%M:%S");
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
std::ofstream ofs_;
|
||||
std::mutex mutex_;
|
||||
};
|
||||
16
industrial-comm/cpp/include/modbus_exception.hpp
Normal file
16
industrial-comm/cpp/include/modbus_exception.hpp
Normal file
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
#include <cstdint>
|
||||
|
||||
enum class ModbusException : std::uint8_t {
|
||||
IllegalFunction = 0x01,
|
||||
IllegalDataAddress = 0x02,
|
||||
IllegalDataValue = 0x03,
|
||||
SlaveDeviceFailure = 0x04,
|
||||
|
||||
Acknowledge = 0x05, // ★ 중요
|
||||
SlaveDeviceBusy = 0x06, // ★ 중요
|
||||
|
||||
MemoryParityError = 0x08,
|
||||
GatewayPathUnavailable = 0x0A,
|
||||
GatewayTargetFailed = 0x0B
|
||||
};
|
||||
61
industrial-comm/cpp/include/modbus_tcp.hpp
Normal file
61
industrial-comm/cpp/include/modbus_tcp.hpp
Normal file
@@ -0,0 +1,61 @@
|
||||
#pragma once
|
||||
#include "modbus_exception.hpp"
|
||||
#include "itransport.hpp"
|
||||
#include "transport_error.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
#include <chrono>
|
||||
#include <string>
|
||||
|
||||
class ModbusTCP : public ITransport {
|
||||
public:
|
||||
ModbusTCP();
|
||||
~ModbusTCP() override;
|
||||
|
||||
bool connect(const char* host, std::uint16_t port) override;
|
||||
void disconnect() override;
|
||||
bool is_connected() const override;
|
||||
|
||||
TransportState state() const override { return state_; }
|
||||
TransportError last_error() const override { return last_error_; }
|
||||
|
||||
bool read_registers(std::uint16_t addr,
|
||||
std::uint16_t count,
|
||||
std::vector<std::uint16_t>& out) override;
|
||||
|
||||
bool write_registers(std::uint16_t addr,
|
||||
const std::vector<std::uint16_t>& values) override;
|
||||
|
||||
void poll() override; // watchdog
|
||||
|
||||
void reset() override;
|
||||
|
||||
private:
|
||||
bool reconnect();
|
||||
bool recv_all(void* buf, std::size_t len);
|
||||
|
||||
private:
|
||||
// socket
|
||||
int sock_;
|
||||
std::uint16_t transaction_id_{0};
|
||||
|
||||
// connection info
|
||||
std::string host_;
|
||||
std::uint16_t port_{0};
|
||||
|
||||
// state machine
|
||||
TransportState state_{TransportState::Disconnected};
|
||||
TransportError last_error_{TransportError::None};
|
||||
ModbusException exception_;
|
||||
|
||||
// watchdog
|
||||
static constexpr int WATCHDOG_SEC = 5;
|
||||
static constexpr int MAX_RETRY = 5;
|
||||
static constexpr int FAULT_RESET_SEC = 30; // Fault 후 자동 리셋 대기
|
||||
std::chrono::steady_clock::time_point last_ok_;
|
||||
std::chrono::steady_clock::time_point fault_since_;
|
||||
int retry_count_{0};
|
||||
bool can_io() const;
|
||||
|
||||
};
|
||||
47
industrial-comm/cpp/include/transport_error.hpp
Normal file
47
industrial-comm/cpp/include/transport_error.hpp
Normal file
@@ -0,0 +1,47 @@
|
||||
|
||||
// TransportError / ModbusException (공통 에러 계층)
|
||||
// transport_error.hpp
|
||||
//
|
||||
|
||||
// enum class TransportError {
|
||||
// None,
|
||||
// Disconnected,
|
||||
// Timeout,
|
||||
// ProtocolError,
|
||||
|
||||
// IllegalFunction,
|
||||
// IllegalDataAddress,
|
||||
// IllegalDataValue,
|
||||
// SlaveDeviceFailure,
|
||||
|
||||
// Acknowledge,
|
||||
// SlaveDeviceBusy,
|
||||
|
||||
// ModbusException
|
||||
// }; IlegalFunction, IllegalDataAddress, IllegalDataValue, SlaveDeviceFailure 는 ModbusException 으로 통합
|
||||
|
||||
#pragma once
|
||||
|
||||
enum class TransportError {
|
||||
None,
|
||||
|
||||
// connection / IO
|
||||
Disconnected,
|
||||
Timeout,
|
||||
|
||||
// framing / protocol
|
||||
ProtocolError,
|
||||
|
||||
// remote device reported error (Modbus exception)
|
||||
RemoteError,
|
||||
|
||||
// transient remote states
|
||||
InProgress, // Modbus Acknowledge (0x05)
|
||||
Busy, // Modbus SlaveDeviceBusy (0x06)
|
||||
|
||||
Fault,
|
||||
};
|
||||
|
||||
|
||||
|
||||
// 통신 오류 코드 열거형
|
||||
9
industrial-comm/cpp/include/transport_state.hpp
Normal file
9
industrial-comm/cpp/include/transport_state.hpp
Normal file
@@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
enum class TransportState {
|
||||
Disconnected,
|
||||
Connecting,
|
||||
Connected,
|
||||
Reconnecting,
|
||||
Fault
|
||||
};
|
||||
29
industrial-comm/cpp/include/vendor_formats.hpp
Normal file
29
industrial-comm/cpp/include/vendor_formats.hpp
Normal file
@@ -0,0 +1,29 @@
|
||||
#pragma once
|
||||
|
||||
#include "data_format.hpp"
|
||||
|
||||
namespace VendorFormat {
|
||||
|
||||
// Honeywell HC900 — FP B "Big Endian" (manual p.4, default)
|
||||
// Wire: r0=bytes[4,3], r1=bytes[2,1] (4-3-2-1 order)
|
||||
constexpr DataFormat HC900_FLOAT {
|
||||
ByteOrder::BigEndian,
|
||||
WordOrder::HighFirst,
|
||||
RegisterOrder::Normal
|
||||
};
|
||||
|
||||
// Standard Modbus big-endian float
|
||||
constexpr DataFormat MODBUS_FLOAT {
|
||||
ByteOrder::BigEndian,
|
||||
WordOrder::HighFirst,
|
||||
RegisterOrder::Normal
|
||||
};
|
||||
|
||||
// Fully reversed (rare but exists)
|
||||
constexpr DataFormat FULL_REVERSED {
|
||||
ByteOrder::LittleEndian,
|
||||
WordOrder::LowFirst,
|
||||
RegisterOrder::Swapped
|
||||
};
|
||||
|
||||
} // namespace VendorFormat
|
||||
29
industrial-comm/cpp/src/app_init.cpp
Normal file
29
industrial-comm/cpp/src/app_init.cpp
Normal file
@@ -0,0 +1,29 @@
|
||||
// app_init.cpp
|
||||
#include "controller.hpp"
|
||||
#include "modbus_tcp.hpp"
|
||||
#include "logger.hpp"
|
||||
#include "app_init.hpp"
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
|
||||
|
||||
// void init_system()
|
||||
// {
|
||||
// Logger::instance().set_file("/var/log/modbus/modbus_tcp.log");
|
||||
|
||||
// auto transport = std::make_unique<ModbusTCP>();
|
||||
// controller = std::make_unique<Controller>(std::move(transport));
|
||||
// }
|
||||
|
||||
// app_init.hpp 새로 만들고 반환 받는 구조로 새로 만듬
|
||||
|
||||
std::unique_ptr<Controller> init_system()
|
||||
{
|
||||
Logger::instance().set_file("/var/log/modbus/modbus_tcp.log");
|
||||
|
||||
auto transport = std::make_unique<ModbusTCP>();
|
||||
return std::make_unique<Controller>(std::move(transport));
|
||||
}
|
||||
|
||||
239
industrial-comm/cpp/src/codec.cpp
Normal file
239
industrial-comm/cpp/src/codec.cpp
Normal file
@@ -0,0 +1,239 @@
|
||||
#include "codec.hpp"
|
||||
#include <cstring>
|
||||
#include <endian.h>
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// helpers
|
||||
// ------------------------------------------------------------
|
||||
|
||||
static inline std::uint16_t make_word(std::uint8_t hi, std::uint8_t lo)
|
||||
{
|
||||
return static_cast<std::uint16_t>((hi << 8) | lo);
|
||||
}
|
||||
|
||||
static inline void split_word(std::uint16_t w,
|
||||
std::uint8_t& hi,
|
||||
std::uint8_t& lo)
|
||||
{
|
||||
hi = static_cast<std::uint8_t>((w >> 8) & 0xFF);
|
||||
lo = static_cast<std::uint8_t>(w & 0xFF);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// core generic helpers (N words)
|
||||
// ------------------------------------------------------------
|
||||
|
||||
template<std::size_t N>
|
||||
static std::array<std::uint16_t, N>
|
||||
encode_words(const std::uint8_t* bytes, const DataFormat& fmt)
|
||||
{
|
||||
std::array<std::uint16_t, N> words{};
|
||||
|
||||
// byte → word
|
||||
for (std::size_t i = 0; i < N; ++i) {
|
||||
std::uint8_t hi, lo;
|
||||
|
||||
if (fmt.byte_order == ByteOrder::BigEndian) {
|
||||
hi = bytes[i * 2];
|
||||
lo = bytes[i * 2 + 1];
|
||||
} else {
|
||||
hi = bytes[i * 2 + 1];
|
||||
lo = bytes[i * 2];
|
||||
}
|
||||
|
||||
words[i] = make_word(hi, lo);
|
||||
}
|
||||
|
||||
// word order
|
||||
if (fmt.word_order == WordOrder::LowFirst && N >= 2) {
|
||||
for (std::size_t i = 0; i < N / 2; ++i) {
|
||||
std::swap(words[i], words[N - 1 - i]);
|
||||
}
|
||||
}
|
||||
|
||||
return words;
|
||||
}
|
||||
|
||||
template<std::size_t N>
|
||||
static void
|
||||
decode_words(const std::array<std::uint16_t, N>& words,
|
||||
std::uint8_t* bytes,
|
||||
const DataFormat& fmt)
|
||||
{
|
||||
std::array<std::uint16_t, N> w = words;
|
||||
|
||||
// word order
|
||||
if (fmt.word_order == WordOrder::LowFirst && N >= 2) {
|
||||
for (std::size_t i = 0; i < N / 2; ++i) {
|
||||
std::swap(w[i], w[N - 1 - i]);
|
||||
}
|
||||
}
|
||||
|
||||
// word → byte
|
||||
for (std::size_t i = 0; i < N; ++i) {
|
||||
std::uint8_t hi, lo;
|
||||
split_word(w[i], hi, lo);
|
||||
|
||||
if (fmt.byte_order == ByteOrder::BigEndian) {
|
||||
bytes[i * 2] = hi;
|
||||
bytes[i * 2 + 1] = lo;
|
||||
} else {
|
||||
bytes[i * 2] = lo;
|
||||
bytes[i * 2 + 1] = hi;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// 32-bit signed / unsigned
|
||||
// ------------------------------------------------------------
|
||||
|
||||
std::array<std::uint16_t, 2>
|
||||
encode_int32(std::int32_t value, const DataFormat& fmt)
|
||||
{
|
||||
std::uint8_t b[4];
|
||||
std::memcpy(b, &value, 4);
|
||||
return encode_words<2>(b, fmt);
|
||||
}
|
||||
|
||||
std::int32_t
|
||||
decode_int32(std::uint16_t r0,
|
||||
std::uint16_t r1,
|
||||
const DataFormat& fmt)
|
||||
{
|
||||
std::uint8_t b[4];
|
||||
decode_words<2>({ r0, r1 }, b, fmt);
|
||||
|
||||
std::int32_t value;
|
||||
std::memcpy(&value, b, 4);
|
||||
return value;
|
||||
}
|
||||
|
||||
std::array<std::uint16_t, 2>
|
||||
encode_uint32(std::uint32_t value, const DataFormat& fmt)
|
||||
{
|
||||
std::uint8_t b[4];
|
||||
std::memcpy(b, &value, 4);
|
||||
return encode_words<2>(b, fmt);
|
||||
}
|
||||
|
||||
std::uint32_t
|
||||
decode_uint32(std::uint16_t r0,
|
||||
std::uint16_t r1,
|
||||
const DataFormat& fmt)
|
||||
{
|
||||
std::uint8_t b[4];
|
||||
decode_words<2>({ r0, r1 }, b, fmt);
|
||||
|
||||
std::uint32_t value;
|
||||
std::memcpy(&value, b, 4);
|
||||
return value;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// float / double
|
||||
// ------------------------------------------------------------
|
||||
|
||||
std::array<std::uint16_t, 2>
|
||||
encode_float(float value, const DataFormat& fmt)
|
||||
{
|
||||
std::uint32_t u;
|
||||
std::memcpy(&u, &value, 4);
|
||||
// Convert host byte order → big-endian bytes before encoding words.
|
||||
if (fmt.byte_order == ByteOrder::BigEndian)
|
||||
u = htobe32(u);
|
||||
std::uint8_t b[4];
|
||||
std::memcpy(b, &u, 4);
|
||||
return encode_words<2>(b, fmt);
|
||||
}
|
||||
|
||||
float
|
||||
decode_float(std::uint16_t r0,
|
||||
std::uint16_t r1,
|
||||
const DataFormat& fmt)
|
||||
{
|
||||
std::uint8_t b[4];
|
||||
decode_words<2>({ r0, r1 }, b, fmt);
|
||||
|
||||
std::uint32_t u;
|
||||
std::memcpy(&u, b, 4);
|
||||
// decode_words produces big-endian bytes; convert to host byte order.
|
||||
if (fmt.byte_order == ByteOrder::BigEndian)
|
||||
u = be32toh(u);
|
||||
float value;
|
||||
std::memcpy(&value, &u, 4);
|
||||
return value;
|
||||
}
|
||||
|
||||
std::array<std::uint16_t, 4>
|
||||
encode_double(double value, const DataFormat& fmt)
|
||||
{
|
||||
std::uint8_t b[8];
|
||||
std::memcpy(b, &value, 8);
|
||||
return encode_words<4>(b, fmt);
|
||||
}
|
||||
|
||||
double
|
||||
decode_double(std::uint16_t r0,
|
||||
std::uint16_t r1,
|
||||
std::uint16_t r2,
|
||||
std::uint16_t r3,
|
||||
const DataFormat& fmt)
|
||||
{
|
||||
std::uint8_t b[8];
|
||||
decode_words<4>({ r0, r1, r2, r3 }, b, fmt);
|
||||
|
||||
double value;
|
||||
std::memcpy(&value, b, 8);
|
||||
return value;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// 64-bit signed / unsigned
|
||||
// ------------------------------------------------------------
|
||||
|
||||
std::array<std::uint16_t, 4>
|
||||
encode_int64(std::int64_t value, const DataFormat& fmt)
|
||||
{
|
||||
std::uint8_t b[8];
|
||||
std::memcpy(b, &value, 8);
|
||||
return encode_words<4>(b, fmt);
|
||||
}
|
||||
|
||||
std::int64_t
|
||||
decode_int64(std::uint16_t r0,
|
||||
std::uint16_t r1,
|
||||
std::uint16_t r2,
|
||||
std::uint16_t r3,
|
||||
const DataFormat& fmt)
|
||||
{
|
||||
std::uint8_t b[8];
|
||||
decode_words<4>({ r0, r1, r2, r3 }, b, fmt);
|
||||
|
||||
std::int64_t value;
|
||||
std::memcpy(&value, b, 8);
|
||||
return value;
|
||||
}
|
||||
|
||||
std::array<std::uint16_t, 4>
|
||||
encode_uint64(std::uint64_t value, const DataFormat& fmt)
|
||||
{
|
||||
std::uint8_t b[8];
|
||||
std::memcpy(b, &value, 8);
|
||||
return encode_words<4>(b, fmt);
|
||||
}
|
||||
|
||||
std::uint64_t
|
||||
decode_uint64(std::uint16_t r0,
|
||||
std::uint16_t r1,
|
||||
std::uint16_t r2,
|
||||
std::uint16_t r3,
|
||||
const DataFormat& fmt)
|
||||
{
|
||||
std::uint8_t b[8];
|
||||
decode_words<4>({ r0, r1, r2, r3 }, b, fmt);
|
||||
|
||||
std::uint64_t value;
|
||||
std::memcpy(&value, b, 8);
|
||||
return value;
|
||||
}
|
||||
232
industrial-comm/cpp/src/controller.cpp
Normal file
232
industrial-comm/cpp/src/controller.cpp
Normal file
@@ -0,0 +1,232 @@
|
||||
#include "controller.hpp"
|
||||
#include "codec.hpp"
|
||||
|
||||
#include <vector>
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// lifecycle
|
||||
// ------------------------------------------------------------
|
||||
|
||||
Controller::Controller(std::unique_ptr<ITransport> transport)
|
||||
: transport_(std::move(transport))
|
||||
{
|
||||
}
|
||||
|
||||
bool Controller::connect(const char* host, std::uint16_t port)
|
||||
{
|
||||
return transport_ && transport_->connect(host, port);
|
||||
}
|
||||
|
||||
void Controller::disconnect()
|
||||
{
|
||||
if (transport_)
|
||||
transport_->disconnect();
|
||||
}
|
||||
|
||||
bool Controller::is_connected() const
|
||||
{
|
||||
return transport_ && transport_->is_connected();
|
||||
}
|
||||
|
||||
void Controller::poll()
|
||||
{
|
||||
if (transport_)
|
||||
transport_->poll();
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// raw register
|
||||
// ------------------------------------------------------------
|
||||
|
||||
bool Controller::read_register(std::uint16_t addr, std::uint16_t& value)
|
||||
{
|
||||
if (!transport_ || !transport_->can_io())
|
||||
return false;
|
||||
|
||||
std::vector<std::uint16_t> regs;
|
||||
if (!transport_->read_registers(addr, 1, regs) || regs.size() != 1)
|
||||
return false;
|
||||
|
||||
value = regs[0];
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Controller::read_raw(std::uint16_t addr, std::uint16_t count, std::vector<std::uint16_t>& out)
|
||||
{
|
||||
if (!transport_ || !transport_->can_io()) return false;
|
||||
return transport_->read_registers(addr, count, out);
|
||||
}
|
||||
|
||||
bool Controller::write_register(std::uint16_t addr, std::uint16_t value)
|
||||
{
|
||||
if (!is_connected()) return false;
|
||||
return transport_->write_registers(addr, { value });
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// 32-bit
|
||||
// ------------------------------------------------------------
|
||||
|
||||
bool Controller::read_int32(std::uint16_t addr,
|
||||
std::int32_t& value,
|
||||
const DataFormat& fmt)
|
||||
{
|
||||
if (!transport_ || !transport_->can_io())
|
||||
return false;
|
||||
|
||||
std::vector<std::uint16_t> regs;
|
||||
if (!transport_->read_registers(addr, 2, regs) || regs.size() != 2)
|
||||
return false;
|
||||
|
||||
value = decode_int32(regs[0], regs[1], fmt);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Controller::write_int32(std::uint16_t addr,
|
||||
std::int32_t value,
|
||||
const DataFormat& fmt)
|
||||
{
|
||||
if (!transport_ || !transport_->can_io())
|
||||
return false;
|
||||
|
||||
auto r = encode_int32(value, fmt);
|
||||
return transport_->write_registers(addr, { r[0], r[1] });
|
||||
}
|
||||
|
||||
bool Controller::read_uint32(std::uint16_t addr,
|
||||
std::uint32_t& value,
|
||||
const DataFormat& fmt)
|
||||
{
|
||||
if (!transport_ || !transport_->can_io())
|
||||
return false;
|
||||
|
||||
std::vector<std::uint16_t> regs;
|
||||
if (!transport_->read_registers(addr, 2, regs) || regs.size() != 2)
|
||||
return false;
|
||||
|
||||
value = decode_uint32(regs[0], regs[1], fmt);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Controller::write_uint32(std::uint16_t addr,
|
||||
std::uint32_t value,
|
||||
const DataFormat& fmt)
|
||||
{
|
||||
if (!transport_ || !transport_->can_io())
|
||||
return false;
|
||||
|
||||
auto r = encode_uint32(value, fmt);
|
||||
return transport_->write_registers(addr, { r[0], r[1] });
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// float / double
|
||||
// ------------------------------------------------------------
|
||||
|
||||
bool Controller::read_float(std::uint16_t addr,
|
||||
float& value,
|
||||
const DataFormat& fmt)
|
||||
{
|
||||
if (!transport_ || !transport_->can_io())
|
||||
return false;
|
||||
|
||||
std::vector<std::uint16_t> regs;
|
||||
if (!transport_->read_registers(addr, 2, regs) || regs.size() != 2)
|
||||
return false;
|
||||
|
||||
value = decode_float(regs[0], regs[1], fmt);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Controller::write_float(std::uint16_t addr,
|
||||
float value,
|
||||
const DataFormat& fmt)
|
||||
{
|
||||
if (!transport_ || !transport_->can_io())
|
||||
return false;
|
||||
auto r = encode_float(value, fmt);
|
||||
return transport_->write_registers(addr, { r[0], r[1] });
|
||||
}
|
||||
|
||||
bool Controller::read_double(std::uint16_t addr,
|
||||
double& value,
|
||||
const DataFormat& fmt)
|
||||
{
|
||||
if (!transport_ || !transport_->can_io())
|
||||
return false;
|
||||
|
||||
std::vector<std::uint16_t> regs;
|
||||
if (!transport_->read_registers(addr, 4, regs) || regs.size() != 4)
|
||||
return false;
|
||||
|
||||
value = decode_double(regs[0], regs[1], regs[2], regs[3], fmt);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Controller::write_double(std::uint16_t addr,
|
||||
double value,
|
||||
const DataFormat& fmt)
|
||||
{
|
||||
if (!transport_ || !transport_->can_io())
|
||||
return false;
|
||||
|
||||
auto r = encode_double(value, fmt);
|
||||
return transport_->write_registers(addr, { r[0], r[1], r[2], r[3] });
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// 64-bit
|
||||
// ------------------------------------------------------------
|
||||
|
||||
bool Controller::read_int64(std::uint16_t addr,
|
||||
std::int64_t& value,
|
||||
const DataFormat& fmt)
|
||||
{
|
||||
if (!transport_ || !transport_->can_io())
|
||||
return false;
|
||||
|
||||
std::vector<std::uint16_t> regs;
|
||||
if (!transport_->read_registers(addr, 4, regs) || regs.size() != 4)
|
||||
return false;
|
||||
|
||||
value = decode_int64(regs[0], regs[1], regs[2], regs[3], fmt);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Controller::write_int64(std::uint16_t addr,
|
||||
std::int64_t value,
|
||||
const DataFormat& fmt)
|
||||
{
|
||||
if (!transport_ || !transport_->can_io())
|
||||
return false;
|
||||
|
||||
auto r = encode_int64(value, fmt);
|
||||
return transport_->write_registers(addr, { r[0], r[1], r[2], r[3] });
|
||||
}
|
||||
|
||||
bool Controller::read_uint64(std::uint16_t addr,
|
||||
std::uint64_t& value,
|
||||
const DataFormat& fmt)
|
||||
{
|
||||
if (!transport_ || !transport_->can_io())
|
||||
return false;
|
||||
|
||||
std::vector<std::uint16_t> regs;
|
||||
if (!transport_->read_registers(addr, 4, regs) || regs.size() != 4)
|
||||
return false;
|
||||
|
||||
value = decode_uint64(regs[0], regs[1], regs[2], regs[3], fmt);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Controller::write_uint64(std::uint16_t addr,
|
||||
std::uint64_t value,
|
||||
const DataFormat& fmt)
|
||||
{
|
||||
if (!transport_ || !transport_->can_io())
|
||||
return false;
|
||||
|
||||
auto r = encode_uint64(value, fmt);
|
||||
return transport_->write_registers(addr, { r[0], r[1], r[2], r[3] });
|
||||
}
|
||||
417
industrial-comm/cpp/src/gateway.cpp
Normal file
417
industrial-comm/cpp/src/gateway.cpp
Normal file
@@ -0,0 +1,417 @@
|
||||
#include "gateway.h"
|
||||
#include "controller.hpp"
|
||||
#include "modbus_tcp.hpp"
|
||||
#include "vendor_formats.hpp"
|
||||
#include "codec.hpp"
|
||||
#include "logger.hpp"
|
||||
#include "json.hpp"
|
||||
|
||||
#include <fstream>
|
||||
#include <numeric>
|
||||
#include <unistd.h>
|
||||
#include <grpcpp/server.h>
|
||||
#include <grpcpp/server_builder.h>
|
||||
#include <grpcpp/server_context.h>
|
||||
#include <google/protobuf/timestamp.pb.h>
|
||||
|
||||
// ─── Constructor / Destructor ───
|
||||
|
||||
Hc900Gateway::Hc900Gateway(const std::string& host, uint16_t port,
|
||||
const std::string& map_path, int poll_interval_ms,
|
||||
int grpc_port)
|
||||
: host_(host), port_(port), poll_interval_ms_(poll_interval_ms),
|
||||
grpc_listen_("0.0.0.0:" + std::to_string(grpc_port))
|
||||
{
|
||||
LoadRegisterMap(map_path);
|
||||
auto transport = std::make_unique<ModbusTCP>();
|
||||
controller_ = std::make_unique<Controller>(std::move(transport));
|
||||
}
|
||||
|
||||
Hc900Gateway::~Hc900Gateway() { Stop(); }
|
||||
|
||||
// ─── Start / Stop ───
|
||||
|
||||
bool Hc900Gateway::Start()
|
||||
{
|
||||
Logger::instance().log("INFO", "[Gateway] Connecting to " + host_ + ":" + std::to_string(port_));
|
||||
if (!controller_->connect(host_.c_str(), port_)) {
|
||||
// 연결 실패해도 종료하지 않음 — 폴 루프에서 재접속 재시도
|
||||
Logger::instance().log("WARN", "[Gateway] Initial connection failed. Will retry in poll loop...");
|
||||
} else {
|
||||
Logger::instance().log("INFO", "[Gateway] Connected.");
|
||||
}
|
||||
Logger::instance().log("INFO", "[Gateway] Starting poll thread (interval=" + std::to_string(poll_interval_ms_) + "ms)");
|
||||
|
||||
grpc_service_ = std::make_unique<GatewayServiceImpl>(*this);
|
||||
grpc::ServerBuilder builder;
|
||||
builder.AddListeningPort(grpc_listen_, grpc::InsecureServerCredentials());
|
||||
builder.RegisterService(grpc_service_.get());
|
||||
grpc_server_ = builder.BuildAndStart();
|
||||
Logger::instance().log("INFO", "[Gateway] gRPC server listening on " + grpc_listen_);
|
||||
|
||||
running_ = true;
|
||||
poll_thread_ = std::thread(&Hc900Gateway::PollLoop, this);
|
||||
return true;
|
||||
}
|
||||
|
||||
void Hc900Gateway::Stop()
|
||||
{
|
||||
running_ = false;
|
||||
if (poll_thread_.joinable()) poll_thread_.join();
|
||||
if (grpc_server_) grpc_server_->Shutdown();
|
||||
controller_->disconnect();
|
||||
}
|
||||
|
||||
// ─── Register Map Loading ───
|
||||
|
||||
void Hc900Gateway::LoadRegisterMap(const std::string& path)
|
||||
{
|
||||
std::ifstream f(path);
|
||||
if (!f.is_open()) {
|
||||
Logger::instance().log("ERROR", "[Gateway] Cannot open register map: " + path);
|
||||
return;
|
||||
}
|
||||
|
||||
auto j = nlohmann::json::parse(f);
|
||||
for (const auto& item : j["registers"]) {
|
||||
RegisterEntry e;
|
||||
e.tag = item["tag"];
|
||||
e.addr = item["addr"];
|
||||
e.count = item.value("count", 2);
|
||||
e.type = item.value("type", "float32");
|
||||
e.access = item.value("access", "R");
|
||||
registers_.push_back(e);
|
||||
tag_index_[e.tag] = registers_.size() - 1;
|
||||
}
|
||||
|
||||
// Build address-sorted index for batch reads
|
||||
sorted_indices_.resize(registers_.size());
|
||||
std::iota(sorted_indices_.begin(), sorted_indices_.end(), 0);
|
||||
std::sort(sorted_indices_.begin(), sorted_indices_.end(),
|
||||
[this](size_t a, size_t b){ return registers_[a].addr < registers_[b].addr; });
|
||||
|
||||
Logger::instance().log("INFO", "[Gateway] Loaded " + std::to_string(registers_.size()) + " registers from " + path);
|
||||
}
|
||||
|
||||
// ─── Poll Loop ───
|
||||
|
||||
void Hc900Gateway::PollLoop()
|
||||
{
|
||||
while (running_) {
|
||||
auto t0 = std::chrono::steady_clock::now();
|
||||
|
||||
if (controller_->is_connected()) {
|
||||
ReadAllRegisters();
|
||||
poll_count_++;
|
||||
} else {
|
||||
controller_->poll();
|
||||
}
|
||||
|
||||
auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(
|
||||
std::chrono::steady_clock::now() - t0);
|
||||
last_poll_duration_ = elapsed;
|
||||
|
||||
auto sleep_for = std::chrono::milliseconds(poll_interval_ms_) - elapsed;
|
||||
if (sleep_for.count() > 0) {
|
||||
std::this_thread::sleep_for(sleep_for);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Hc900Gateway::ReadAllRegisters()
|
||||
{
|
||||
constexpr uint16_t MAX_BATCH = 120;
|
||||
decltype(cache_) fresh;
|
||||
|
||||
size_t i = 0;
|
||||
while (i < sorted_indices_.size()) {
|
||||
uint32_t batch_start = registers_[sorted_indices_[i]].addr;
|
||||
|
||||
// Collect all registers that fit within [batch_start, batch_start + MAX_BATCH)
|
||||
size_t j = i;
|
||||
while (j < sorted_indices_.size()) {
|
||||
const auto& e = registers_[sorted_indices_[j]];
|
||||
if (e.addr + e.count - batch_start > MAX_BATCH) break;
|
||||
++j;
|
||||
}
|
||||
|
||||
// Read count = up to end of last register in this batch
|
||||
const auto& last = registers_[sorted_indices_[j - 1]];
|
||||
uint16_t read_count = static_cast<uint16_t>(last.addr + last.count - batch_start);
|
||||
|
||||
std::vector<uint16_t> regs;
|
||||
bool ok;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(transport_mutex_);
|
||||
ok = controller_->read_raw(static_cast<uint16_t>(batch_start), read_count, regs);
|
||||
}
|
||||
|
||||
if (ok) {
|
||||
auto now = std::chrono::system_clock::now();
|
||||
for (size_t k = i; k < j; k++) {
|
||||
const auto& entry = registers_[sorted_indices_[k]];
|
||||
size_t off = entry.addr - batch_start;
|
||||
|
||||
CachedValue cv{};
|
||||
cv.timestamp = now;
|
||||
cv.quality = 192;
|
||||
|
||||
if (entry.type == "uint16") {
|
||||
cv.is_float = false;
|
||||
cv.uint16_val = regs[off];
|
||||
} else {
|
||||
cv.is_float = true;
|
||||
cv.float32_val = decode_float(regs[off], regs[off + 1], VendorFormat::HC900_FLOAT);
|
||||
}
|
||||
fresh[entry.tag] = cv;
|
||||
}
|
||||
}
|
||||
|
||||
i = j;
|
||||
}
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(cache_mutex_);
|
||||
cache_ = std::move(fresh);
|
||||
}
|
||||
}
|
||||
|
||||
CachedValue Hc900Gateway::ReadRegister(const RegisterEntry& entry)
|
||||
{
|
||||
CachedValue cv{};
|
||||
cv.is_float = (entry.type == "float32");
|
||||
cv.timestamp = std::chrono::system_clock::now();
|
||||
cv.quality = 0;
|
||||
|
||||
if (!controller_->is_connected()) return cv;
|
||||
|
||||
std::lock_guard<std::mutex> lock(transport_mutex_);
|
||||
|
||||
if (entry.type == "uint16" && entry.count == 1) {
|
||||
uint16_t v = 0;
|
||||
if (controller_->read_register(entry.addr, v)) {
|
||||
cv.uint16_val = v;
|
||||
cv.quality = 192;
|
||||
}
|
||||
} else if (entry.type == "float32") {
|
||||
float v = 0;
|
||||
if (controller_->read_float(entry.addr, v, VendorFormat::HC900_FLOAT)) {
|
||||
cv.float32_val = v;
|
||||
cv.quality = 192;
|
||||
}
|
||||
}
|
||||
return cv;
|
||||
}
|
||||
|
||||
// ─── gRPC Service Implementation ───
|
||||
|
||||
Hc900Gateway::GatewayServiceImpl::GatewayServiceImpl(Hc900Gateway& gateway)
|
||||
: gateway_(gateway) {}
|
||||
|
||||
namespace {
|
||||
void TagValueFromCache(hc900::TagValue* tv, const std::string& name, const CachedValue& cv) {
|
||||
tv->set_tag_name(name);
|
||||
tv->set_quality(cv.quality);
|
||||
auto ns = std::chrono::duration_cast<std::chrono::nanoseconds>(
|
||||
cv.timestamp.time_since_epoch()).count();
|
||||
tv->mutable_timestamp()->set_seconds(static_cast<int64_t>(ns / 1000000000));
|
||||
tv->mutable_timestamp()->set_nanos(static_cast<int32_t>(ns % 1000000000));
|
||||
if (cv.is_float) {
|
||||
tv->set_float32_val(cv.float32_val);
|
||||
} else {
|
||||
tv->set_uint16_val(cv.uint16_val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
grpc::Status Hc900Gateway::GatewayServiceImpl::ReadTags(
|
||||
grpc::ServerContext*,
|
||||
const hc900::ReadTagsRequest* req,
|
||||
hc900::ReadTagsResponse* resp)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(gateway_.cache_mutex_);
|
||||
|
||||
if (req->tag_names().empty()) {
|
||||
for (const auto& [tag, cv] : gateway_.cache_) {
|
||||
TagValueFromCache(resp->add_values(), tag, cv);
|
||||
}
|
||||
} else {
|
||||
for (const auto& name : req->tag_names()) {
|
||||
auto it = gateway_.cache_.find(name);
|
||||
if (it == gateway_.cache_.end()) {
|
||||
auto idx = gateway_.tag_index_.find(name);
|
||||
if (idx != gateway_.tag_index_.end()) {
|
||||
auto& entry = gateway_.registers_[idx->second];
|
||||
it = gateway_.cache_.find(entry.tag);
|
||||
}
|
||||
}
|
||||
if (it != gateway_.cache_.end()) {
|
||||
TagValueFromCache(resp->add_values(), it->first, it->second);
|
||||
}
|
||||
}
|
||||
}
|
||||
return grpc::Status::OK;
|
||||
}
|
||||
|
||||
grpc::Status Hc900Gateway::GatewayServiceImpl::WriteTag(
|
||||
grpc::ServerContext*,
|
||||
const hc900::WriteTagRequest* req,
|
||||
hc900::WriteTagResponse* resp)
|
||||
{
|
||||
auto it = gateway_.tag_index_.find(req->tag_name());
|
||||
if (it == gateway_.tag_index_.end()) {
|
||||
resp->set_success(false);
|
||||
resp->set_error("Tag not found");
|
||||
return grpc::Status::OK;
|
||||
}
|
||||
|
||||
auto& entry = gateway_.registers_[it->second];
|
||||
if (entry.access != "RW") {
|
||||
resp->set_success(false);
|
||||
resp->set_error("Read-only tag");
|
||||
return grpc::Status::OK;
|
||||
}
|
||||
|
||||
bool ok = false;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(gateway_.transport_mutex_);
|
||||
if (entry.type == "uint16") {
|
||||
ok = gateway_.controller_->write_register(entry.addr,
|
||||
static_cast<uint16_t>(req->value()));
|
||||
} else if (entry.type == "float32") {
|
||||
ok = gateway_.controller_->write_float(entry.addr,
|
||||
static_cast<float>(req->value()),
|
||||
VendorFormat::HC900_FLOAT);
|
||||
}
|
||||
}
|
||||
|
||||
resp->set_success(ok);
|
||||
if (!ok) resp->set_error("Modbus write failed");
|
||||
|
||||
if (ok) {
|
||||
std::lock_guard<std::mutex> lock(gateway_.cache_mutex_);
|
||||
CachedValue cv;
|
||||
cv.is_float = (entry.type == "float32");
|
||||
if (cv.is_float) cv.float32_val = static_cast<float>(req->value());
|
||||
else cv.uint16_val = static_cast<uint16_t>(req->value());
|
||||
cv.quality = 192;
|
||||
cv.timestamp = std::chrono::system_clock::now();
|
||||
gateway_.cache_[entry.tag] = cv;
|
||||
}
|
||||
|
||||
return grpc::Status::OK;
|
||||
}
|
||||
|
||||
grpc::Status Hc900Gateway::GatewayServiceImpl::ListTags(
|
||||
grpc::ServerContext*,
|
||||
const hc900::ListTagsRequest* req,
|
||||
hc900::ListTagsResponse* resp)
|
||||
{
|
||||
int count = 0;
|
||||
for (const auto& entry : gateway_.registers_) {
|
||||
if (!req->filter().empty()) {
|
||||
auto lower_tag = entry.tag;
|
||||
auto lower_filter = req->filter();
|
||||
std::transform(lower_tag.begin(), lower_tag.end(), lower_tag.begin(), ::tolower);
|
||||
std::transform(lower_filter.begin(), lower_filter.end(), lower_filter.begin(), ::tolower);
|
||||
if (lower_tag.find(lower_filter) == std::string::npos) continue;
|
||||
}
|
||||
auto* meta = resp->add_tags();
|
||||
meta->set_tag_name(entry.tag);
|
||||
meta->set_address(entry.addr);
|
||||
meta->set_count(entry.count);
|
||||
meta->set_type(entry.type);
|
||||
meta->set_access(entry.access);
|
||||
count++;
|
||||
if (req->limit() > 0 && count >= req->limit()) break;
|
||||
}
|
||||
return grpc::Status::OK;
|
||||
}
|
||||
|
||||
grpc::Status Hc900Gateway::GatewayServiceImpl::HealthCheck(
|
||||
grpc::ServerContext*,
|
||||
const hc900::HealthCheckRequest*,
|
||||
hc900::HealthCheckResponse* resp)
|
||||
{
|
||||
resp->set_status(gateway_.controller_->is_connected()
|
||||
? hc900::HealthCheckResponse::SERVING
|
||||
: hc900::HealthCheckResponse::NOT_SERVING);
|
||||
resp->set_uptime_sec(0);
|
||||
resp->set_poll_count(gateway_.poll_count_);
|
||||
resp->set_last_poll_ms(static_cast<int32_t>(gateway_.last_poll_duration_.count()));
|
||||
resp->set_controller_ip(gateway_.host_);
|
||||
resp->set_active_tags(static_cast<int32_t>(gateway_.registers_.size()));
|
||||
return grpc::Status::OK;
|
||||
}
|
||||
|
||||
grpc::Status Hc900Gateway::GatewayServiceImpl::StreamTags(
|
||||
grpc::ServerContext* ctx,
|
||||
const hc900::StreamTagsRequest* req,
|
||||
grpc::ServerWriter<hc900::TagValue>* writer)
|
||||
{
|
||||
int interval = req->interval_ms() > 0 ? req->interval_ms() : 1000;
|
||||
|
||||
std::vector<std::string> names;
|
||||
if (req->tag_names().empty()) {
|
||||
std::lock_guard<std::mutex> lock(gateway_.cache_mutex_);
|
||||
for (const auto& [tag, _] : gateway_.cache_) {
|
||||
names.push_back(tag);
|
||||
}
|
||||
} else {
|
||||
names.assign(req->tag_names().begin(), req->tag_names().end());
|
||||
}
|
||||
|
||||
while (!ctx->IsCancelled()) {
|
||||
auto t0 = std::chrono::steady_clock::now();
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(gateway_.cache_mutex_);
|
||||
for (const auto& name : names) {
|
||||
auto it = gateway_.cache_.find(name);
|
||||
if (it == gateway_.cache_.end()) continue;
|
||||
auto& cv = it->second;
|
||||
|
||||
hc900::TagValue tv;
|
||||
TagValueFromCache(&tv, name, cv);
|
||||
if (!writer->Write(tv)) return grpc::Status::CANCELLED;
|
||||
}
|
||||
}
|
||||
|
||||
auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(
|
||||
std::chrono::steady_clock::now() - t0);
|
||||
auto sleep_for = std::chrono::milliseconds(interval) - elapsed;
|
||||
if (sleep_for.count() > 0) {
|
||||
std::this_thread::sleep_for(sleep_for);
|
||||
}
|
||||
}
|
||||
return grpc::Status::OK;
|
||||
}
|
||||
|
||||
// ─── main ───
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
std::string host = "192.168.0.240";
|
||||
std::string map_path = "docs/register-map.json";
|
||||
int poll_ms = 1000;
|
||||
int grpc_port = 50051;
|
||||
uint16_t modbus_port = 502;
|
||||
|
||||
if (argc > 1) host = argv[1];
|
||||
if (argc > 2) map_path = argv[2];
|
||||
if (argc > 3) poll_ms = std::atoi(argv[3]);
|
||||
if (argc > 4) grpc_port = std::atoi(argv[4]);
|
||||
if (argc > 5) modbus_port = static_cast<uint16_t>(std::atoi(argv[5]));
|
||||
|
||||
Logger::instance().set_file("/tmp/hc900_gateway.log");
|
||||
|
||||
Hc900Gateway gateway(host, modbus_port, map_path, poll_ms, grpc_port);
|
||||
if (!gateway.Start()) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
Logger::instance().log("INFO", "[Gateway] Running. Press Ctrl+C to stop.");
|
||||
pause();
|
||||
gateway.Stop();
|
||||
return 0;
|
||||
}
|
||||
3
industrial-comm/cpp/src/main.cpp
Normal file
3
industrial-comm/cpp/src/main.cpp
Normal file
@@ -0,0 +1,3 @@
|
||||
// app_init.cpp
|
||||
#include "app_init.hpp"
|
||||
auto controller = init_system();
|
||||
389
industrial-comm/cpp/src/modbus_tcp.cpp
Normal file
389
industrial-comm/cpp/src/modbus_tcp.cpp
Normal file
@@ -0,0 +1,389 @@
|
||||
#include "modbus_tcp.hpp"
|
||||
#include "modbus_exception.hpp"
|
||||
#include "transport_error.hpp"
|
||||
#include "log_macros.hpp"
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <unistd.h>
|
||||
#include <cstring>
|
||||
#include <thread>
|
||||
|
||||
|
||||
namespace {
|
||||
constexpr std::uint8_t MODBUS_UNIT_ID = 1;
|
||||
constexpr int SOCKET_TIMEOUT_SEC = 2;
|
||||
constexpr int WATCHDOG_SEC = 5;
|
||||
constexpr int MAX_RETRY = 5;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Modbus exception → TransportError
|
||||
// ------------------------------------------------------------
|
||||
|
||||
static TransportError map_exception(ModbusException ex)
|
||||
{
|
||||
switch (ex) {
|
||||
case ModbusException::Acknowledge:
|
||||
return TransportError::InProgress;
|
||||
case ModbusException::SlaveDeviceBusy:
|
||||
return TransportError::Busy;
|
||||
default:
|
||||
return TransportError::RemoteError;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// ctor / dtor
|
||||
// ------------------------------------------------------------
|
||||
|
||||
ModbusTCP::ModbusTCP()
|
||||
: sock_(-1),
|
||||
transaction_id_(0),
|
||||
state_(TransportState::Disconnected),
|
||||
last_error_(TransportError::None),
|
||||
exception_(ModbusException::IllegalFunction),
|
||||
retry_count_(0)
|
||||
{
|
||||
}
|
||||
|
||||
ModbusTCP::~ModbusTCP()
|
||||
{
|
||||
disconnect();
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// connection
|
||||
// ------------------------------------------------------------
|
||||
|
||||
bool ModbusTCP::connect(const char* host, std::uint16_t port)
|
||||
{
|
||||
|
||||
host_ = host;
|
||||
port_ = port;
|
||||
|
||||
LOG_INFO("ModbusTCP: Connecting start: " + host_ + ":" + std::to_string(port_));
|
||||
|
||||
sock_ = ::socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (sock_ < 0)
|
||||
return false;
|
||||
|
||||
timeval tv{};
|
||||
tv.tv_sec = SOCKET_TIMEOUT_SEC;
|
||||
tv.tv_usec = 0;
|
||||
::setsockopt(sock_, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
|
||||
::setsockopt(sock_, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
|
||||
|
||||
sockaddr_in addr{};
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(port);
|
||||
::inet_pton(AF_INET, host, &addr.sin_addr);
|
||||
|
||||
if (::connect(sock_, reinterpret_cast<sockaddr*>(&addr), sizeof(addr)) < 0) {
|
||||
LOG_ERROR("ModbusTCP: Connecting failed: " + host_ + ":" + std::to_string(port_));
|
||||
disconnect();
|
||||
return false;
|
||||
}
|
||||
|
||||
state_ = TransportState::Connected;
|
||||
retry_count_ = 0;
|
||||
last_ok_ = std::chrono::steady_clock::now();
|
||||
last_error_ = TransportError::None;
|
||||
return true;
|
||||
}
|
||||
|
||||
void ModbusTCP::disconnect()
|
||||
{
|
||||
LOG_INFO("ModbusTCP: Disconnecting: " + host_ + ":" + std::to_string(port_));
|
||||
|
||||
if (sock_ >= 0) {
|
||||
::close(sock_);
|
||||
sock_ = -1;
|
||||
}
|
||||
state_ = TransportState::Disconnected;
|
||||
}
|
||||
|
||||
bool ModbusTCP::is_connected() const
|
||||
{
|
||||
return state_ == TransportState::Connected;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// TCP fragmentation safe recv
|
||||
// ------------------------------------------------------------
|
||||
|
||||
bool ModbusTCP::recv_all(void* buf, std::size_t len)
|
||||
{
|
||||
std::uint8_t* p = static_cast<std::uint8_t*>(buf);
|
||||
std::size_t total = 0;
|
||||
|
||||
while (total < len) {
|
||||
ssize_t n = ::recv(sock_, p + total, len - total, 0);
|
||||
if (n <= 0)
|
||||
return false;
|
||||
total += static_cast<std::size_t>(n);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// status to log string helper
|
||||
// ------------------------------------------------------------
|
||||
|
||||
static const char* to_string(TransportState s) {
|
||||
switch (s) {
|
||||
case TransportState::Disconnected: return "Disconnected";
|
||||
case TransportState::Connected: return "Connected";
|
||||
case TransportState::Reconnecting: return "Reconnecting";
|
||||
case TransportState::Fault: return "Fault";
|
||||
default: return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Read Holding Registers (0x03)
|
||||
// ------------------------------------------------------------
|
||||
|
||||
bool ModbusTCP::read_registers(std::uint16_t addr,
|
||||
std::uint16_t count,
|
||||
std::vector<std::uint16_t>& out)
|
||||
{
|
||||
if (!can_io()) {
|
||||
last_error_ = TransportError::Disconnected;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (count == 0) {
|
||||
last_error_ = TransportError::ProtocolError;
|
||||
return false;
|
||||
}
|
||||
|
||||
// MBAP(7) + PDU(5)
|
||||
std::uint8_t req[12]{};
|
||||
|
||||
req[0] = transaction_id_ >> 8;
|
||||
req[1] = transaction_id_ & 0xFF;
|
||||
req[2] = 0x00;
|
||||
req[3] = 0x00;
|
||||
req[4] = 0x00;
|
||||
req[5] = 0x06;
|
||||
req[6] = MODBUS_UNIT_ID;
|
||||
req[7] = 0x03;
|
||||
req[8] = addr >> 8;
|
||||
req[9] = addr & 0xFF;
|
||||
req[10] = count >> 8;
|
||||
req[11] = count & 0xFF;
|
||||
|
||||
if (::send(sock_, req, sizeof(req), 0) < 0) {
|
||||
last_error_ = TransportError::Disconnected;
|
||||
return false;
|
||||
}
|
||||
|
||||
std::uint8_t header[9];
|
||||
if (!recv_all(header, 9)) {
|
||||
last_error_ = TransportError::Timeout;
|
||||
return false;
|
||||
}
|
||||
|
||||
std::uint8_t func = header[7];
|
||||
if (func & 0x80) {
|
||||
exception_ = static_cast<ModbusException>(header[8]);
|
||||
last_error_ = map_exception(exception_);
|
||||
return false;
|
||||
}
|
||||
|
||||
std::uint8_t byte_count = header[8];
|
||||
std::vector<std::uint8_t> payload(byte_count);
|
||||
|
||||
if (!recv_all(payload.data(), byte_count)) {
|
||||
last_error_ = TransportError::Timeout;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (byte_count != count * 2) {
|
||||
last_error_ = TransportError::ProtocolError;
|
||||
return false;
|
||||
}
|
||||
|
||||
out.clear();
|
||||
out.reserve(count);
|
||||
for (std::size_t i = 0; i < count; ++i) {
|
||||
out.push_back((payload[i * 2] << 8) | payload[i * 2 + 1]);
|
||||
}
|
||||
|
||||
transaction_id_++;
|
||||
last_ok_ = std::chrono::steady_clock::now();
|
||||
last_error_ = TransportError::None;
|
||||
return true;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Write Multiple Registers (0x10)
|
||||
// ------------------------------------------------------------
|
||||
|
||||
bool ModbusTCP::write_registers(std::uint16_t addr,
|
||||
const std::vector<std::uint16_t>& values)
|
||||
{
|
||||
if (!can_io()) {
|
||||
last_error_ = TransportError::Disconnected;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (values.empty()) {
|
||||
last_error_ = TransportError::ProtocolError;
|
||||
return false;
|
||||
}
|
||||
|
||||
std::size_t count = values.size();
|
||||
std::size_t data_len = count * 2;
|
||||
std::size_t pdu_len = 6 + data_len;
|
||||
std::size_t length = 1 + pdu_len;
|
||||
|
||||
std::vector<std::uint8_t> req(7 + pdu_len);
|
||||
|
||||
req[0] = transaction_id_ >> 8;
|
||||
req[1] = transaction_id_ & 0xFF;
|
||||
req[2] = 0x00;
|
||||
req[3] = 0x00;
|
||||
req[4] = length >> 8;
|
||||
req[5] = length & 0xFF;
|
||||
req[6] = MODBUS_UNIT_ID;
|
||||
req[7] = 0x10;
|
||||
req[8] = addr >> 8;
|
||||
req[9] = addr & 0xFF;
|
||||
req[10] = count >> 8;
|
||||
req[11] = count & 0xFF;
|
||||
req[12] = static_cast<std::uint8_t>(data_len);
|
||||
|
||||
for (std::size_t i = 0; i < count; ++i) {
|
||||
req[13 + i * 2] = values[i] >> 8;
|
||||
req[14 + i * 2] = values[i] & 0xFF;
|
||||
}
|
||||
|
||||
if (::send(sock_, req.data(), req.size(), 0) < 0) {
|
||||
last_error_ = TransportError::Disconnected;
|
||||
return false;
|
||||
}
|
||||
|
||||
std::uint8_t resp[12];
|
||||
if (!recv_all(resp, sizeof(resp))) {
|
||||
last_error_ = TransportError::Timeout;
|
||||
return false;
|
||||
}
|
||||
|
||||
std::uint8_t func = resp[7];
|
||||
if (func & 0x80) {
|
||||
exception_ = static_cast<ModbusException>(resp[8]);
|
||||
last_error_ = map_exception(exception_);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (func != 0x10) {
|
||||
last_error_ = TransportError::ProtocolError;
|
||||
return false;
|
||||
}
|
||||
|
||||
transaction_id_++;
|
||||
last_ok_ = std::chrono::steady_clock::now();
|
||||
last_error_ = TransportError::None;
|
||||
return true;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// watchdog / reconnect / log state changes(added)
|
||||
// ------------------------------------------------------------
|
||||
|
||||
void ModbusTCP::poll()
|
||||
{
|
||||
using namespace std::chrono;
|
||||
|
||||
auto now = steady_clock::now();
|
||||
auto prev = state_;
|
||||
|
||||
switch (state_) {
|
||||
|
||||
case TransportState::Connected: {
|
||||
auto idle = duration_cast<seconds>(now - last_ok_);
|
||||
|
||||
if (idle.count() > WATCHDOG_SEC) {
|
||||
last_error_ = TransportError::Timeout;
|
||||
state_ = TransportState::Reconnecting;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case TransportState::Disconnected:
|
||||
case TransportState::Reconnecting:
|
||||
reconnect();
|
||||
break;
|
||||
|
||||
case TransportState::Fault: {
|
||||
// FAULT_RESET_SEC 후 자동 리셋 → Disconnected로 복귀해 재시도
|
||||
auto elapsed = std::chrono::duration_cast<std::chrono::seconds>(
|
||||
std::chrono::steady_clock::now() - fault_since_).count();
|
||||
if (elapsed >= FAULT_RESET_SEC) {
|
||||
LOG_WARN("[Transport] Fault 상태 리셋 — 재접속 시도");
|
||||
retry_count_ = 0;
|
||||
state_ = TransportState::Disconnected;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (prev != state_) {
|
||||
LOG_WARN(std::string("state: ") +
|
||||
to_string(prev) + " -> " +
|
||||
to_string(state_));
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// reset procedure
|
||||
// ------------------------------------------------------------
|
||||
|
||||
bool ModbusTCP::reconnect()
|
||||
{
|
||||
LOG_DEBUG("reconnect attempt " + std::to_string(retry_count_));
|
||||
|
||||
if (retry_count_++ >= MAX_RETRY) {
|
||||
state_ = TransportState::Fault;
|
||||
fault_since_ = std::chrono::steady_clock::now();
|
||||
LOG_ERROR("reconnect failed, entering Fault (will retry in " +
|
||||
std::to_string(FAULT_RESET_SEC) + "s)");
|
||||
return false;
|
||||
}
|
||||
|
||||
disconnect();
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(500));
|
||||
return connect(host_.c_str(), port_);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// reset procedure
|
||||
// ------------------------------------------------------------
|
||||
|
||||
void ModbusTCP::reset()
|
||||
{
|
||||
disconnect();
|
||||
|
||||
transaction_id_ = 0;
|
||||
retry_count_ = 0;
|
||||
last_error_ = TransportError::None;
|
||||
exception_ = ModbusException::IllegalFunction; // 의미 없는 초기값 OK
|
||||
|
||||
state_ = TransportState::Disconnected;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// read/write allowed check
|
||||
// ------------------------------------------------------------
|
||||
|
||||
inline bool ModbusTCP::can_io() const
|
||||
{
|
||||
return state_ == TransportState::Connected;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user