This commit is contained in:
2026-09-03 13:08:01 +03:00
parent d5783423d6
commit 946c1beabf
41 changed files with 3558 additions and 103 deletions
+674
View File
@@ -0,0 +1,674 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.36.11
// protoc v4.25.3
// source: receiver.proto
package pb
import (
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
unsafe "unsafe"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
type ClientMessage struct {
state protoimpl.MessageState `protogen:"open.v1"`
RequestId string `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
// Types that are valid to be assigned to Payload:
//
// *ClientMessage_Av
// *ClientMessage_SetFrequency
// *ClientMessage_GetFrequency
Payload isClientMessage_Payload `protobuf_oneof:"payload"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *ClientMessage) Reset() {
*x = ClientMessage{}
mi := &file_receiver_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *ClientMessage) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ClientMessage) ProtoMessage() {}
func (x *ClientMessage) ProtoReflect() protoreflect.Message {
mi := &file_receiver_proto_msgTypes[0]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ClientMessage.ProtoReflect.Descriptor instead.
func (*ClientMessage) Descriptor() ([]byte, []int) {
return file_receiver_proto_rawDescGZIP(), []int{0}
}
func (x *ClientMessage) GetRequestId() string {
if x != nil {
return x.RequestId
}
return ""
}
func (x *ClientMessage) GetPayload() isClientMessage_Payload {
if x != nil {
return x.Payload
}
return nil
}
func (x *ClientMessage) GetAv() *AvCommand {
if x != nil {
if x, ok := x.Payload.(*ClientMessage_Av); ok {
return x.Av
}
}
return nil
}
func (x *ClientMessage) GetSetFrequency() *SetFrequencyCommand {
if x != nil {
if x, ok := x.Payload.(*ClientMessage_SetFrequency); ok {
return x.SetFrequency
}
}
return nil
}
func (x *ClientMessage) GetGetFrequency() *GetFrequencyCommand {
if x != nil {
if x, ok := x.Payload.(*ClientMessage_GetFrequency); ok {
return x.GetFrequency
}
}
return nil
}
type isClientMessage_Payload interface {
isClientMessage_Payload()
}
type ClientMessage_Av struct {
Av *AvCommand `protobuf:"bytes,10,opt,name=av,proto3,oneof"`
}
type ClientMessage_SetFrequency struct {
SetFrequency *SetFrequencyCommand `protobuf:"bytes,11,opt,name=set_frequency,json=setFrequency,proto3,oneof"`
}
type ClientMessage_GetFrequency struct {
GetFrequency *GetFrequencyCommand `protobuf:"bytes,12,opt,name=get_frequency,json=getFrequency,proto3,oneof"`
}
func (*ClientMessage_Av) isClientMessage_Payload() {}
func (*ClientMessage_SetFrequency) isClientMessage_Payload() {}
func (*ClientMessage_GetFrequency) isClientMessage_Payload() {}
type ServerMessage struct {
state protoimpl.MessageState `protogen:"open.v1"`
RequestId string `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
// Types that are valid to be assigned to Payload:
//
// *ServerMessage_Av
// *ServerMessage_SetFrequency
// *ServerMessage_GetFrequency
// *ServerMessage_Error
Payload isServerMessage_Payload `protobuf_oneof:"payload"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *ServerMessage) Reset() {
*x = ServerMessage{}
mi := &file_receiver_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *ServerMessage) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ServerMessage) ProtoMessage() {}
func (x *ServerMessage) ProtoReflect() protoreflect.Message {
mi := &file_receiver_proto_msgTypes[1]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ServerMessage.ProtoReflect.Descriptor instead.
func (*ServerMessage) Descriptor() ([]byte, []int) {
return file_receiver_proto_rawDescGZIP(), []int{1}
}
func (x *ServerMessage) GetRequestId() string {
if x != nil {
return x.RequestId
}
return ""
}
func (x *ServerMessage) GetPayload() isServerMessage_Payload {
if x != nil {
return x.Payload
}
return nil
}
func (x *ServerMessage) GetAv() *AvResponse {
if x != nil {
if x, ok := x.Payload.(*ServerMessage_Av); ok {
return x.Av
}
}
return nil
}
func (x *ServerMessage) GetSetFrequency() *SetFrequencyResponse {
if x != nil {
if x, ok := x.Payload.(*ServerMessage_SetFrequency); ok {
return x.SetFrequency
}
}
return nil
}
func (x *ServerMessage) GetGetFrequency() *GetFrequencyResponse {
if x != nil {
if x, ok := x.Payload.(*ServerMessage_GetFrequency); ok {
return x.GetFrequency
}
}
return nil
}
func (x *ServerMessage) GetError() *Error {
if x != nil {
if x, ok := x.Payload.(*ServerMessage_Error); ok {
return x.Error
}
}
return nil
}
type isServerMessage_Payload interface {
isServerMessage_Payload()
}
type ServerMessage_Av struct {
Av *AvResponse `protobuf:"bytes,10,opt,name=av,proto3,oneof"`
}
type ServerMessage_SetFrequency struct {
SetFrequency *SetFrequencyResponse `protobuf:"bytes,11,opt,name=set_frequency,json=setFrequency,proto3,oneof"`
}
type ServerMessage_GetFrequency struct {
GetFrequency *GetFrequencyResponse `protobuf:"bytes,12,opt,name=get_frequency,json=getFrequency,proto3,oneof"`
}
type ServerMessage_Error struct {
Error *Error `protobuf:"bytes,50,opt,name=error,proto3,oneof"`
}
func (*ServerMessage_Av) isServerMessage_Payload() {}
func (*ServerMessage_SetFrequency) isServerMessage_Payload() {}
func (*ServerMessage_GetFrequency) isServerMessage_Payload() {}
func (*ServerMessage_Error) isServerMessage_Payload() {}
type AvCommand struct {
state protoimpl.MessageState `protogen:"open.v1"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *AvCommand) Reset() {
*x = AvCommand{}
mi := &file_receiver_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *AvCommand) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*AvCommand) ProtoMessage() {}
func (x *AvCommand) ProtoReflect() protoreflect.Message {
mi := &file_receiver_proto_msgTypes[2]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use AvCommand.ProtoReflect.Descriptor instead.
func (*AvCommand) Descriptor() ([]byte, []int) {
return file_receiver_proto_rawDescGZIP(), []int{2}
}
type SetFrequencyCommand struct {
state protoimpl.MessageState `protogen:"open.v1"`
Frequency uint32 `protobuf:"varint,1,opt,name=frequency,proto3" json:"frequency,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *SetFrequencyCommand) Reset() {
*x = SetFrequencyCommand{}
mi := &file_receiver_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *SetFrequencyCommand) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*SetFrequencyCommand) ProtoMessage() {}
func (x *SetFrequencyCommand) ProtoReflect() protoreflect.Message {
mi := &file_receiver_proto_msgTypes[3]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use SetFrequencyCommand.ProtoReflect.Descriptor instead.
func (*SetFrequencyCommand) Descriptor() ([]byte, []int) {
return file_receiver_proto_rawDescGZIP(), []int{3}
}
func (x *SetFrequencyCommand) GetFrequency() uint32 {
if x != nil {
return x.Frequency
}
return 0
}
type GetFrequencyCommand struct {
state protoimpl.MessageState `protogen:"open.v1"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *GetFrequencyCommand) Reset() {
*x = GetFrequencyCommand{}
mi := &file_receiver_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *GetFrequencyCommand) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*GetFrequencyCommand) ProtoMessage() {}
func (x *GetFrequencyCommand) ProtoReflect() protoreflect.Message {
mi := &file_receiver_proto_msgTypes[4]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use GetFrequencyCommand.ProtoReflect.Descriptor instead.
func (*GetFrequencyCommand) Descriptor() ([]byte, []int) {
return file_receiver_proto_rawDescGZIP(), []int{4}
}
type AvResponse struct {
state protoimpl.MessageState `protogen:"open.v1"`
Ok bool `protobuf:"varint,1,opt,name=ok,proto3" json:"ok,omitempty"`
Hw string `protobuf:"bytes,2,opt,name=hw,proto3" json:"hw,omitempty"`
Sw string `protobuf:"bytes,3,opt,name=sw,proto3" json:"sw,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *AvResponse) Reset() {
*x = AvResponse{}
mi := &file_receiver_proto_msgTypes[5]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *AvResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*AvResponse) ProtoMessage() {}
func (x *AvResponse) ProtoReflect() protoreflect.Message {
mi := &file_receiver_proto_msgTypes[5]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use AvResponse.ProtoReflect.Descriptor instead.
func (*AvResponse) Descriptor() ([]byte, []int) {
return file_receiver_proto_rawDescGZIP(), []int{5}
}
func (x *AvResponse) GetOk() bool {
if x != nil {
return x.Ok
}
return false
}
func (x *AvResponse) GetHw() string {
if x != nil {
return x.Hw
}
return ""
}
func (x *AvResponse) GetSw() string {
if x != nil {
return x.Sw
}
return ""
}
type SetFrequencyResponse struct {
state protoimpl.MessageState `protogen:"open.v1"`
Ok bool `protobuf:"varint,1,opt,name=ok,proto3" json:"ok,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *SetFrequencyResponse) Reset() {
*x = SetFrequencyResponse{}
mi := &file_receiver_proto_msgTypes[6]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *SetFrequencyResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*SetFrequencyResponse) ProtoMessage() {}
func (x *SetFrequencyResponse) ProtoReflect() protoreflect.Message {
mi := &file_receiver_proto_msgTypes[6]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use SetFrequencyResponse.ProtoReflect.Descriptor instead.
func (*SetFrequencyResponse) Descriptor() ([]byte, []int) {
return file_receiver_proto_rawDescGZIP(), []int{6}
}
func (x *SetFrequencyResponse) GetOk() bool {
if x != nil {
return x.Ok
}
return false
}
type GetFrequencyResponse struct {
state protoimpl.MessageState `protogen:"open.v1"`
Frequency uint32 `protobuf:"varint,1,opt,name=frequency,proto3" json:"frequency,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *GetFrequencyResponse) Reset() {
*x = GetFrequencyResponse{}
mi := &file_receiver_proto_msgTypes[7]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *GetFrequencyResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*GetFrequencyResponse) ProtoMessage() {}
func (x *GetFrequencyResponse) ProtoReflect() protoreflect.Message {
mi := &file_receiver_proto_msgTypes[7]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use GetFrequencyResponse.ProtoReflect.Descriptor instead.
func (*GetFrequencyResponse) Descriptor() ([]byte, []int) {
return file_receiver_proto_rawDescGZIP(), []int{7}
}
func (x *GetFrequencyResponse) GetFrequency() uint32 {
if x != nil {
return x.Frequency
}
return 0
}
type Error struct {
state protoimpl.MessageState `protogen:"open.v1"`
Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *Error) Reset() {
*x = Error{}
mi := &file_receiver_proto_msgTypes[8]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *Error) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Error) ProtoMessage() {}
func (x *Error) ProtoReflect() protoreflect.Message {
mi := &file_receiver_proto_msgTypes[8]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Error.ProtoReflect.Descriptor instead.
func (*Error) Descriptor() ([]byte, []int) {
return file_receiver_proto_rawDescGZIP(), []int{8}
}
func (x *Error) GetMessage() string {
if x != nil {
return x.Message
}
return ""
}
var File_receiver_proto protoreflect.FileDescriptor
const file_receiver_proto_rawDesc = "" +
"\n" +
"\x0ereceiver.proto\x12\vreceiver.v1\"\xf5\x01\n" +
"\rClientMessage\x12\x1d\n" +
"\n" +
"request_id\x18\x01 \x01(\tR\trequestId\x12(\n" +
"\x02av\x18\n" +
" \x01(\v2\x16.receiver.v1.AvCommandH\x00R\x02av\x12G\n" +
"\rset_frequency\x18\v \x01(\v2 .receiver.v1.SetFrequencyCommandH\x00R\fsetFrequency\x12G\n" +
"\rget_frequency\x18\f \x01(\v2 .receiver.v1.GetFrequencyCommandH\x00R\fgetFrequencyB\t\n" +
"\apayload\"\xa4\x02\n" +
"\rServerMessage\x12\x1d\n" +
"\n" +
"request_id\x18\x01 \x01(\tR\trequestId\x12)\n" +
"\x02av\x18\n" +
" \x01(\v2\x17.receiver.v1.AvResponseH\x00R\x02av\x12H\n" +
"\rset_frequency\x18\v \x01(\v2!.receiver.v1.SetFrequencyResponseH\x00R\fsetFrequency\x12H\n" +
"\rget_frequency\x18\f \x01(\v2!.receiver.v1.GetFrequencyResponseH\x00R\fgetFrequency\x12*\n" +
"\x05error\x182 \x01(\v2\x12.receiver.v1.ErrorH\x00R\x05errorB\t\n" +
"\apayload\"\v\n" +
"\tAvCommand\"3\n" +
"\x13SetFrequencyCommand\x12\x1c\n" +
"\tfrequency\x18\x01 \x01(\rR\tfrequency\"\x15\n" +
"\x13GetFrequencyCommand\"<\n" +
"\n" +
"AvResponse\x12\x0e\n" +
"\x02ok\x18\x01 \x01(\bR\x02ok\x12\x0e\n" +
"\x02hw\x18\x02 \x01(\tR\x02hw\x12\x0e\n" +
"\x02sw\x18\x03 \x01(\tR\x02sw\"&\n" +
"\x14SetFrequencyResponse\x12\x0e\n" +
"\x02ok\x18\x01 \x01(\bR\x02ok\"4\n" +
"\x14GetFrequencyResponse\x12\x1c\n" +
"\tfrequency\x18\x01 \x01(\rR\tfrequency\"!\n" +
"\x05Error\x12\x18\n" +
"\amessage\x18\x01 \x01(\tR\amessage2X\n" +
"\x0fReceiverService\x12E\n" +
"\aConnect\x12\x1a.receiver.v1.ClientMessage\x1a\x1a.receiver.v1.ServerMessage(\x010\x01B\x1fZ\x1d../spectr/internal/grpc/pb;pbb\x06proto3"
var (
file_receiver_proto_rawDescOnce sync.Once
file_receiver_proto_rawDescData []byte
)
func file_receiver_proto_rawDescGZIP() []byte {
file_receiver_proto_rawDescOnce.Do(func() {
file_receiver_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_receiver_proto_rawDesc), len(file_receiver_proto_rawDesc)))
})
return file_receiver_proto_rawDescData
}
var file_receiver_proto_msgTypes = make([]protoimpl.MessageInfo, 9)
var file_receiver_proto_goTypes = []any{
(*ClientMessage)(nil), // 0: receiver.v1.ClientMessage
(*ServerMessage)(nil), // 1: receiver.v1.ServerMessage
(*AvCommand)(nil), // 2: receiver.v1.AvCommand
(*SetFrequencyCommand)(nil), // 3: receiver.v1.SetFrequencyCommand
(*GetFrequencyCommand)(nil), // 4: receiver.v1.GetFrequencyCommand
(*AvResponse)(nil), // 5: receiver.v1.AvResponse
(*SetFrequencyResponse)(nil), // 6: receiver.v1.SetFrequencyResponse
(*GetFrequencyResponse)(nil), // 7: receiver.v1.GetFrequencyResponse
(*Error)(nil), // 8: receiver.v1.Error
}
var file_receiver_proto_depIdxs = []int32{
2, // 0: receiver.v1.ClientMessage.av:type_name -> receiver.v1.AvCommand
3, // 1: receiver.v1.ClientMessage.set_frequency:type_name -> receiver.v1.SetFrequencyCommand
4, // 2: receiver.v1.ClientMessage.get_frequency:type_name -> receiver.v1.GetFrequencyCommand
5, // 3: receiver.v1.ServerMessage.av:type_name -> receiver.v1.AvResponse
6, // 4: receiver.v1.ServerMessage.set_frequency:type_name -> receiver.v1.SetFrequencyResponse
7, // 5: receiver.v1.ServerMessage.get_frequency:type_name -> receiver.v1.GetFrequencyResponse
8, // 6: receiver.v1.ServerMessage.error:type_name -> receiver.v1.Error
0, // 7: receiver.v1.ReceiverService.Connect:input_type -> receiver.v1.ClientMessage
1, // 8: receiver.v1.ReceiverService.Connect:output_type -> receiver.v1.ServerMessage
8, // [8:9] is the sub-list for method output_type
7, // [7:8] is the sub-list for method input_type
7, // [7:7] is the sub-list for extension type_name
7, // [7:7] is the sub-list for extension extendee
0, // [0:7] is the sub-list for field type_name
}
func init() { file_receiver_proto_init() }
func file_receiver_proto_init() {
if File_receiver_proto != nil {
return
}
file_receiver_proto_msgTypes[0].OneofWrappers = []any{
(*ClientMessage_Av)(nil),
(*ClientMessage_SetFrequency)(nil),
(*ClientMessage_GetFrequency)(nil),
}
file_receiver_proto_msgTypes[1].OneofWrappers = []any{
(*ServerMessage_Av)(nil),
(*ServerMessage_SetFrequency)(nil),
(*ServerMessage_GetFrequency)(nil),
(*ServerMessage_Error)(nil),
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: unsafe.Slice(unsafe.StringData(file_receiver_proto_rawDesc), len(file_receiver_proto_rawDesc)),
NumEnums: 0,
NumMessages: 9,
NumExtensions: 0,
NumServices: 1,
},
GoTypes: file_receiver_proto_goTypes,
DependencyIndexes: file_receiver_proto_depIdxs,
MessageInfos: file_receiver_proto_msgTypes,
}.Build()
File_receiver_proto = out.File
file_receiver_proto_goTypes = nil
file_receiver_proto_depIdxs = nil
}
+115
View File
@@ -0,0 +1,115 @@
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
// versions:
// - protoc-gen-go-grpc v1.6.2
// - protoc v4.25.3
// source: receiver.proto
package pb
import (
context "context"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
)
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
// Requires gRPC-Go v1.64.0 or later.
const _ = grpc.SupportPackageIsVersion9
const (
ReceiverService_Connect_FullMethodName = "/receiver.v1.ReceiverService/Connect"
)
// ReceiverServiceClient is the client API for ReceiverService service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
type ReceiverServiceClient interface {
Connect(ctx context.Context, opts ...grpc.CallOption) (grpc.BidiStreamingClient[ClientMessage, ServerMessage], error)
}
type receiverServiceClient struct {
cc grpc.ClientConnInterface
}
func NewReceiverServiceClient(cc grpc.ClientConnInterface) ReceiverServiceClient {
return &receiverServiceClient{cc}
}
func (c *receiverServiceClient) Connect(ctx context.Context, opts ...grpc.CallOption) (grpc.BidiStreamingClient[ClientMessage, ServerMessage], error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
stream, err := c.cc.NewStream(ctx, &ReceiverService_ServiceDesc.Streams[0], ReceiverService_Connect_FullMethodName, cOpts...)
if err != nil {
return nil, err
}
x := &grpc.GenericClientStream[ClientMessage, ServerMessage]{ClientStream: stream}
return x, nil
}
// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.
type ReceiverService_ConnectClient = grpc.BidiStreamingClient[ClientMessage, ServerMessage]
// ReceiverServiceServer is the server API for ReceiverService service.
// All implementations must embed UnimplementedReceiverServiceServer
// for forward compatibility.
type ReceiverServiceServer interface {
Connect(grpc.BidiStreamingServer[ClientMessage, ServerMessage]) error
mustEmbedUnimplementedReceiverServiceServer()
}
// UnimplementedReceiverServiceServer must be embedded to have
// forward compatible implementations.
//
// NOTE: this should be embedded by value instead of pointer to avoid a nil
// pointer dereference when methods are called.
type UnimplementedReceiverServiceServer struct{}
func (UnimplementedReceiverServiceServer) Connect(grpc.BidiStreamingServer[ClientMessage, ServerMessage]) error {
return status.Error(codes.Unimplemented, "method Connect not implemented")
}
func (UnimplementedReceiverServiceServer) mustEmbedUnimplementedReceiverServiceServer() {}
func (UnimplementedReceiverServiceServer) testEmbeddedByValue() {}
// UnsafeReceiverServiceServer may be embedded to opt out of forward compatibility for this service.
// Use of this interface is not recommended, as added methods to ReceiverServiceServer will
// result in compilation errors.
type UnsafeReceiverServiceServer interface {
mustEmbedUnimplementedReceiverServiceServer()
}
func RegisterReceiverServiceServer(s grpc.ServiceRegistrar, srv ReceiverServiceServer) {
// If the following call panics, it indicates UnimplementedReceiverServiceServer was
// embedded by pointer and is nil. This will cause panics if an
// unimplemented method is ever invoked, so we test this at initialization
// time to prevent it from happening at runtime later due to I/O.
if t, ok := srv.(interface{ testEmbeddedByValue() }); ok {
t.testEmbeddedByValue()
}
s.RegisterService(&ReceiverService_ServiceDesc, srv)
}
func _ReceiverService_Connect_Handler(srv interface{}, stream grpc.ServerStream) error {
return srv.(ReceiverServiceServer).Connect(&grpc.GenericServerStream[ClientMessage, ServerMessage]{ServerStream: stream})
}
// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.
type ReceiverService_ConnectServer = grpc.BidiStreamingServer[ClientMessage, ServerMessage]
// ReceiverService_ServiceDesc is the grpc.ServiceDesc for ReceiverService service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
var ReceiverService_ServiceDesc = grpc.ServiceDesc{
ServiceName: "receiver.v1.ReceiverService",
HandlerType: (*ReceiverServiceServer)(nil),
Methods: []grpc.MethodDesc{},
Streams: []grpc.StreamDesc{
{
StreamName: "Connect",
Handler: _ReceiverService_Connect_Handler,
ServerStreams: true,
ClientStreams: true,
},
},
Metadata: "receiver.proto",
}
+70
View File
@@ -0,0 +1,70 @@
// Package localuart находит и открывает USB-UART адаптер напрямую, без
// демона — для standalone-версии приложения (internal/localctl).
package localuart
import (
"fmt"
"sort"
"strings"
"go.bug.st/serial/enumerator"
)
// knownVID — VID распространённых чипов USB-UART мостов. Порты с таким VID
// считаются вероятным переходником "UART to USB" и предлагаются первыми.
var knownVID = map[string]bool{
"0403": true, // FTDI
"1A86": true, // WCH CH340 / CH341
"10C4": true, // Silicon Labs CP210x
"067B": true, // Prolific PL2303
}
// Candidate — один найденный USB-serial порт.
type Candidate struct {
Name string
VID string
PID string
}
// ListCandidates возвращает USB-serial порты, обнаруженные в системе;
// порты с известным VID переходника идут первыми.
func ListCandidates() ([]Candidate, error) {
ports, err := enumerator.GetDetailedPortsList()
if err != nil {
return nil, err
}
var known, other []Candidate
for _, p := range ports {
if !p.IsUSB {
continue
}
c := Candidate{
Name: p.Name,
VID: strings.ToUpper(p.VID),
PID: strings.ToUpper(p.PID),
}
if knownVID[c.VID] {
known = append(known, c)
} else {
other = append(other, c)
}
}
sort.Slice(known, func(i, j int) bool { return known[i].Name < known[j].Name })
sort.Slice(other, func(i, j int) bool { return other[i].Name < other[j].Name })
return append(known, other...), nil
}
// PickPort возвращает наиболее вероятный порт UART-to-USB переходника.
func PickPort() (string, error) {
candidates, err := ListCandidates()
if err != nil {
return "", fmt.Errorf("не удалось получить список портов: %w", err)
}
if len(candidates) == 0 {
return "", fmt.Errorf("USB-UART адаптер не найден")
}
return candidates[0].Name, nil
}
+91
View File
@@ -0,0 +1,91 @@
package localuart
import (
"bytes"
"io"
"strings"
"time"
"go.bug.st/serial"
)
const (
bufferSize = 4096
readTimeout = 50 * time.Millisecond
idle = 200 * time.Millisecond
silenceTimeout = 2 * time.Second // если вообще нет ответа — не виснуть
)
// Port — открытый напрямую USB-UART порт (без демона).
type Port struct {
name string
port serial.Port
}
// Open открывает порт по имени на заданной скорости.
func Open(name string, baud int) (*Port, error) {
mode := &serial.Mode{BaudRate: baud}
p, err := serial.Open(name, mode)
if err != nil {
return nil, err
}
if err := p.SetReadTimeout(readTimeout); err != nil {
_ = p.Close()
return nil, err
}
return &Port{name: name, port: p}, nil
}
// Name возвращает имя порта (например /dev/ttyUSB0 или COM3).
func (p *Port) Name() string { return p.name }
// Write отправляет команду устройству (как в internal/uart.UART).
func (p *Port) Write(cmd string) error {
_, err := p.port.Write([]byte(strings.TrimSpace(cmd) + "\r"))
return err
}
// ReadResponse читает ответ до паузы в потоке данных (idle), либо
// возвращает ошибку, если устройство вообще не ответило за silenceTimeout —
// это важно для standalone-режима: кнопка проверки не должна виснуть
// навсегда, если выбранный порт "не тот".
func (p *Port) ReadResponse() (string, error) {
buf := make([]byte, bufferSize)
var out bytes.Buffer
received := false
lastData := time.Now()
started := time.Now()
for {
n, err := p.port.Read(buf)
if err != nil && err != io.EOF {
return "", err
}
if n > 0 {
received = true
lastData = time.Now()
out.Write(buf[:n])
}
if received && time.Since(lastData) >= idle {
return strings.TrimSpace(out.String()), nil
}
if !received && time.Since(started) >= silenceTimeout {
return "", io.ErrNoProgress
}
}
}
// Exec отправляет команду и возвращает ответ устройства.
func (p *Port) Exec(cmd string) (string, error) {
if err := p.Write(cmd); err != nil {
return "", err
}
return p.ReadResponse()
}
// Close закрывает порт.
func (p *Port) Close() error {
return p.port.Close()
}
+45
View File
@@ -0,0 +1,45 @@
// Package protocol содержит кодирование/декодирование команд устройства
// (av/af/ar), вынесенное из internal/service, чтобы им мог пользоваться и
// демон (через internal/service), и standalone-приложение (internal/localctl)
// без зависимости друг от друга.
package protocol
import (
"fmt"
"regexp"
"strconv"
)
var (
versionRe = regexp.MustCompile(`(?i)HW[:=]\s*([^\s]+).*?(?:FW|SW)[:=]\s*([^\s]+)`)
freqRe = regexp.MustCompile(`(?i)\bf\d{7,9}\b`)
)
// ParseVersion извлекает HW/FW из сырого ответа на команду "av".
func ParseVersion(line string) (hw, sw string) {
match := versionRe.FindStringSubmatch(line)
if len(match) == 3 {
return match[1], match[2]
}
return "", ""
}
// EncodeFrequencyCommand формирует команду "af" для частоты в МГц.
func EncodeFrequencyCommand(frequency uint32) string {
return fmt.Sprintf("af%07d", frequency*100)
}
// DecodeFrequencyResponse разбирает ответ на команду "ar" в частоту в МГц.
func DecodeFrequencyResponse(line string) (uint32, error) {
match := freqRe.FindString(line)
if match == "" {
return 0, fmt.Errorf("invalid frequency response %q", line)
}
value, err := strconv.ParseUint(match[1:], 10, 32)
if err != nil {
return 0, fmt.Errorf("invalid frequency response %q: %w", line, err)
}
return uint32(value / 100), nil
}