diff --git a/commands/service_monitor.go b/commands/service_monitor.go index 8297b1cf763..ae3763d64cf 100644 --- a/commands/service_monitor.go +++ b/commands/service_monitor.go @@ -20,6 +20,7 @@ import ( "errors" "fmt" "io" + "strconv" "sync/atomic" "github.com/arduino/arduino-cli/commands/cmderrors" @@ -95,6 +96,38 @@ func (s *monitorPipeClient) Close() error { return nil } +// configurer is the minimal subset of the monitor used to apply settings. +type configurer interface { + Configure(parameterName, value string) error +} + +// applyBufferConfig translates the gRPC buffer config into pluggable-monitor CONFIGURE calls. +func applyBufferConfig(c configurer, cfg *rpc.MonitorBufferConfig) { + if cfg == nil { + return + } + if v := cfg.GetHighWaterMarkBytes(); v > 0 { + _ = c.Configure("_buffer.hwm", strconv.Itoa(int(v))) + } + // Interval (0 disables) + _ = c.Configure("_buffer.interval_ms", strconv.Itoa(int(cfg.GetFlushIntervalMs()))) + // Line buffering + _ = c.Configure("_buffer.line", strconv.FormatBool(cfg.GetLineBuffering())) + // Queue capacity + if v := cfg.GetFlushQueueCapacity(); v > 0 { + _ = c.Configure("_buffer.queue", strconv.Itoa(int(v))) + } + // Overflow strategy (default to drop if unspecified) + switch cfg.GetOverflowStrategy() { + case rpc.BufferOverflowStrategy_BUFFER_OVERFLOW_STRATEGY_WAIT: + _ = c.Configure("_buffer.overflow", "wait") + default: // unspecified or drop + _ = c.Configure("_buffer.overflow", "drop") + } + // Bounded wait for overflow (ms) + _ = c.Configure("_buffer.overflow_wait_ms", strconv.Itoa(int(cfg.GetOverflowWaitMs()))) +} + // MonitorServerToReadWriteCloser creates a monitor server that proxies the data to a ReadWriteCloser. // The server is returned along with the ReadWriteCloser that can be used to send and receive data // to the server. The MonitorPortOpenRequest is used to configure the monitor. @@ -148,6 +181,7 @@ func (s *arduinoCoreServerImpl) Monitor(stream rpc.ArduinoCoreService_MonitorSer for setting, value := range boardSettings.AsMap() { monitor.Configure(setting, value) } + applyBufferConfig(monitor, openReq.GetBufferConfig()) monitorIO, err := monitor.Open(openReq.GetPort().GetAddress(), openReq.GetPort().GetProtocol()) if err != nil { monitor.Quit() @@ -165,7 +199,7 @@ func (s *arduinoCoreServerImpl) Monitor(stream rpc.ArduinoCoreService_MonitorSer ctx, cancel := context.WithCancel(stream.Context()) gracefulCloseInitiated := &atomic.Bool{} - gracefuleCloseCtx, gracefulCloseCancel := context.WithCancel(context.Background()) + gracefulCloseCtx, gracefulCloseCancel := context.WithCancel(context.Background()) // gRPC stream receiver (gRPC data -> monitor, config, close) go func() { @@ -230,7 +264,7 @@ func (s *arduinoCoreServerImpl) Monitor(stream rpc.ArduinoCoreService_MonitorSer <-ctx.Done() if gracefulCloseInitiated.Load() { // Port closing has been initiated in the receiver - <-gracefuleCloseCtx.Done() + <-gracefulCloseCtx.Done() } else { monitorClose() } diff --git a/commands/service_monitor_test.go b/commands/service_monitor_test.go new file mode 100644 index 00000000000..2ddad947499 --- /dev/null +++ b/commands/service_monitor_test.go @@ -0,0 +1,101 @@ +// This file is part of arduino-cli. +// +// Copyright 2025 ARDUINO SA (http://www.arduino.cc/) +// +// This software is released under the GNU General Public License version 3, +// which covers the main part of arduino-cli. +// The terms of this license can be found at: +// https://www.gnu.org/licenses/gpl-3.0.en.html +// +// You can be released from the requirements of the above licenses by purchasing +// a commercial license. Buying such a license is mandatory if you want to +// modify or otherwise use the software for commercial activities involving the +// Arduino software without disclosing the source code of your own applications. +// To purchase a commercial license, send an email to license@arduino.cc. + +package commands + +import ( + "testing" + + rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" +) + +type fakeConfigurer struct{ calls [][2]string } + +func (f *fakeConfigurer) Configure(k, v string) error { + f.calls = append(f.calls, [2]string{k, v}) + return nil +} + +func haveCall(calls [][2]string, k, v string) bool { + for _, kv := range calls { + if kv[0] == k && kv[1] == v { + return true + } + } + return false +} + +// Test that we correctly read all buffer_config fields from the gRPC request +// and emit the expected CONFIGURE _buffer.* key/value pairs. +func Test_applyBufferConfig_AllFields(t *testing.T) { + f := &fakeConfigurer{} + cfg := &rpc.MonitorBufferConfig{ + HighWaterMarkBytes: 64, + FlushIntervalMs: 16, + LineBuffering: true, + FlushQueueCapacity: 256, + OverflowStrategy: rpc.BufferOverflowStrategy_BUFFER_OVERFLOW_STRATEGY_WAIT, + OverflowWaitMs: 50, + } + applyBufferConfig(f, cfg) + + want := map[string]string{ + "_buffer.hwm": "64", + "_buffer.interval_ms": "16", + "_buffer.line": "true", + "_buffer.queue": "256", + "_buffer.overflow": "wait", + "_buffer.overflow_wait_ms": "50", + } + for k, v := range want { + if !haveCall(f.calls, k, v) { + t.Fatalf("missing or wrong CONFIGURE %s=%s; calls=%v", k, v, f.calls) + } + } +} + +// Test that zeros/defaults are handled as intended: we still emit interval/line/overflow, +// default overflow to 'drop', and omit hwm/queue when zero. +func Test_applyBufferConfig_DefaultsAndZeros(t *testing.T) { + f := &fakeConfigurer{} + cfg := &rpc.MonitorBufferConfig{ // zeros/unset + HighWaterMarkBytes: 0, + FlushIntervalMs: 0, + LineBuffering: false, + FlushQueueCapacity: 0, + OverflowStrategy: rpc.BufferOverflowStrategy_BUFFER_OVERFLOW_STRATEGY_UNSPECIFIED, + OverflowWaitMs: 0, + } + applyBufferConfig(f, cfg) + + expects := map[string]string{ + "_buffer.interval_ms": "0", + "_buffer.line": "false", + "_buffer.overflow": "drop", + "_buffer.overflow_wait_ms": "0", + } + for k, v := range expects { + if !haveCall(f.calls, k, v) { + t.Fatalf("expected CONFIGURE %s=%s not found; calls=%v", k, v, f.calls) + } + } + for _, dis := range []string{"_buffer.hwm", "_buffer.queue"} { + for _, kv := range f.calls { + if kv[0] == dis { + t.Fatalf("did not expect CONFIGURE for %s when value is zero", dis) + } + } + } +} diff --git a/internal/locales/locale.go b/internal/locales/locale.go index 646b44059f7..c678981ac7d 100644 --- a/internal/locales/locale.go +++ b/internal/locales/locale.go @@ -54,9 +54,9 @@ func findMatchingLanguage(language string, supportedLocales []string) string { } func findMatchingLocale(locale string, supportedLocales []string) string { - for _, suportedLocale := range supportedLocales { - if locale == suportedLocale { - return suportedLocale + for _, supportedLocale := range supportedLocales { + if locale == supportedLocale { + return supportedLocale } } diff --git a/rpc/cc/arduino/cli/commands/v1/commands.pb.go b/rpc/cc/arduino/cli/commands/v1/commands.pb.go index b17f636954c..73733316779 100644 --- a/rpc/cc/arduino/cli/commands/v1/commands.pb.go +++ b/rpc/cc/arduino/cli/commands/v1/commands.pb.go @@ -1001,7 +1001,7 @@ type NewSketchRequest struct { // Default Sketchbook directory "directories.User" is used if sketch_dir is // empty. SketchDir string `protobuf:"bytes,3,opt,name=sketch_dir,json=sketchDir,proto3" json:"sketch_dir,omitempty"` - // Specificies if an existing .ino sketch should be overwritten. + // Specifies if an existing .ino sketch should be overwritten. Overwrite bool `protobuf:"varint,4,opt,name=overwrite,proto3" json:"overwrite,omitempty"` } @@ -1405,7 +1405,7 @@ type SetSketchDefaultsResponse struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // The value of default_fqnn that has been written in project file + // The value of default_fqbn that has been written in project file // (sketch.yaml). DefaultFqbn string `protobuf:"bytes,1,opt,name=default_fqbn,json=defaultFqbn,proto3" json:"default_fqbn,omitempty"` // The value of default_port that has been written in project file diff --git a/rpc/cc/arduino/cli/commands/v1/commands.proto b/rpc/cc/arduino/cli/commands/v1/commands.proto index 4a55e0ded24..28a8da760b8 100644 --- a/rpc/cc/arduino/cli/commands/v1/commands.proto +++ b/rpc/cc/arduino/cli/commands/v1/commands.proto @@ -161,7 +161,7 @@ service ArduinoCoreService { // Start a debug session and communicate with the debugger tool. rpc Debug(stream DebugRequest) returns (stream DebugResponse) {} - // Determine if debugging is suported given a specific configuration. + // Determine if debugging is supported given a specific configuration. rpc IsDebugSupported(IsDebugSupportedRequest) returns (IsDebugSupportedResponse) {} // Query the debugger information given a specific configuration. @@ -336,7 +336,7 @@ message NewSketchRequest { // Default Sketchbook directory "directories.User" is used if sketch_dir is // empty. string sketch_dir = 3; - // Specificies if an existing .ino sketch should be overwritten. + // Specifies if an existing .ino sketch should be overwritten. bool overwrite = 4; reserved 1; @@ -387,7 +387,7 @@ message SetSketchDefaultsRequest { } message SetSketchDefaultsResponse { - // The value of default_fqnn that has been written in project file + // The value of default_fqbn that has been written in project file // (sketch.yaml). string default_fqbn = 1; // The value of default_port that has been written in project file diff --git a/rpc/cc/arduino/cli/commands/v1/commands_grpc.pb.go b/rpc/cc/arduino/cli/commands/v1/commands_grpc.pb.go index 1daf07db43b..eb19f2a9eb8 100644 --- a/rpc/cc/arduino/cli/commands/v1/commands_grpc.pb.go +++ b/rpc/cc/arduino/cli/commands/v1/commands_grpc.pb.go @@ -181,7 +181,7 @@ type ArduinoCoreServiceClient interface { EnumerateMonitorPortSettings(ctx context.Context, in *EnumerateMonitorPortSettingsRequest, opts ...grpc.CallOption) (*EnumerateMonitorPortSettingsResponse, error) // Start a debug session and communicate with the debugger tool. Debug(ctx context.Context, opts ...grpc.CallOption) (grpc.BidiStreamingClient[DebugRequest, DebugResponse], error) - // Determine if debugging is suported given a specific configuration. + // Determine if debugging is supported given a specific configuration. IsDebugSupported(ctx context.Context, in *IsDebugSupportedRequest, opts ...grpc.CallOption) (*IsDebugSupportedResponse, error) // Query the debugger information given a specific configuration. GetDebugConfig(ctx context.Context, in *GetDebugConfigRequest, opts ...grpc.CallOption) (*GetDebugConfigResponse, error) @@ -982,7 +982,7 @@ type ArduinoCoreServiceServer interface { EnumerateMonitorPortSettings(context.Context, *EnumerateMonitorPortSettingsRequest) (*EnumerateMonitorPortSettingsResponse, error) // Start a debug session and communicate with the debugger tool. Debug(grpc.BidiStreamingServer[DebugRequest, DebugResponse]) error - // Determine if debugging is suported given a specific configuration. + // Determine if debugging is supported given a specific configuration. IsDebugSupported(context.Context, *IsDebugSupportedRequest) (*IsDebugSupportedResponse, error) // Query the debugger information given a specific configuration. GetDebugConfig(context.Context, *GetDebugConfigRequest) (*GetDebugConfigResponse, error) diff --git a/rpc/cc/arduino/cli/commands/v1/lib.pb.go b/rpc/cc/arduino/cli/commands/v1/lib.pb.go index cff75c6a941..9eb212a8f64 100644 --- a/rpc/cc/arduino/cli/commands/v1/lib.pb.go +++ b/rpc/cc/arduino/cli/commands/v1/lib.pb.go @@ -1065,7 +1065,7 @@ type LibraryResolveDependenciesRequest struct { // The version of the library to check dependencies of. If no version is // specified, dependencies of the newest version will be listed. Version string `protobuf:"bytes,3,opt,name=version,proto3" json:"version,omitempty"` - // If true the computed solution will try to keep exising libraries + // If true the computed solution will try to keep existing libraries // at their current version. DoNotUpdateInstalledLibraries bool `protobuf:"varint,4,opt,name=do_not_update_installed_libraries,json=doNotUpdateInstalledLibraries,proto3" json:"do_not_update_installed_libraries,omitempty"` } diff --git a/rpc/cc/arduino/cli/commands/v1/lib.proto b/rpc/cc/arduino/cli/commands/v1/lib.proto index 9350440bb37..0e90aeacf5c 100644 --- a/rpc/cc/arduino/cli/commands/v1/lib.proto +++ b/rpc/cc/arduino/cli/commands/v1/lib.proto @@ -155,7 +155,7 @@ message LibraryResolveDependenciesRequest { // The version of the library to check dependencies of. If no version is // specified, dependencies of the newest version will be listed. string version = 3; - // If true the computed solution will try to keep exising libraries + // If true the computed solution will try to keep existing libraries // at their current version. bool do_not_update_installed_libraries = 4; } diff --git a/rpc/cc/arduino/cli/commands/v1/monitor.pb.go b/rpc/cc/arduino/cli/commands/v1/monitor.pb.go index 465ed17235e..1289b866639 100644 --- a/rpc/cc/arduino/cli/commands/v1/monitor.pb.go +++ b/rpc/cc/arduino/cli/commands/v1/monitor.pb.go @@ -36,6 +36,60 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) +// BufferOverflowStrategy defines how the pluggable monitor should behave +// when the port→TCP queue is full. +type BufferOverflowStrategy int32 + +const ( + // Unspecified; treated as DROP by the server/handler for backward compatibility. + BufferOverflowStrategy_BUFFER_OVERFLOW_STRATEGY_UNSPECIFIED BufferOverflowStrategy = 0 + // Drop the aggregated payload when the queue is full (do not block the port reader). + BufferOverflowStrategy_BUFFER_OVERFLOW_STRATEGY_DROP BufferOverflowStrategy = 1 + // Wait up to a bounded timeout for space in the queue before dropping. + BufferOverflowStrategy_BUFFER_OVERFLOW_STRATEGY_WAIT BufferOverflowStrategy = 2 +) + +// Enum value maps for BufferOverflowStrategy. +var ( + BufferOverflowStrategy_name = map[int32]string{ + 0: "BUFFER_OVERFLOW_STRATEGY_UNSPECIFIED", + 1: "BUFFER_OVERFLOW_STRATEGY_DROP", + 2: "BUFFER_OVERFLOW_STRATEGY_WAIT", + } + BufferOverflowStrategy_value = map[string]int32{ + "BUFFER_OVERFLOW_STRATEGY_UNSPECIFIED": 0, + "BUFFER_OVERFLOW_STRATEGY_DROP": 1, + "BUFFER_OVERFLOW_STRATEGY_WAIT": 2, + } +) + +func (x BufferOverflowStrategy) Enum() *BufferOverflowStrategy { + p := new(BufferOverflowStrategy) + *p = x + return p +} + +func (x BufferOverflowStrategy) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (BufferOverflowStrategy) Descriptor() protoreflect.EnumDescriptor { + return file_cc_arduino_cli_commands_v1_monitor_proto_enumTypes[0].Descriptor() +} + +func (BufferOverflowStrategy) Type() protoreflect.EnumType { + return &file_cc_arduino_cli_commands_v1_monitor_proto_enumTypes[0] +} + +func (x BufferOverflowStrategy) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use BufferOverflowStrategy.Descriptor instead. +func (BufferOverflowStrategy) EnumDescriptor() ([]byte, []int) { + return file_cc_arduino_cli_commands_v1_monitor_proto_rawDescGZIP(), []int{0} +} + type MonitorRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -166,6 +220,8 @@ type MonitorPortOpenRequest struct { Fqbn string `protobuf:"bytes,3,opt,name=fqbn,proto3" json:"fqbn,omitempty"` // Port configuration, optional, contains settings of the port to be applied. PortConfiguration *MonitorPortConfiguration `protobuf:"bytes,4,opt,name=port_configuration,json=portConfiguration,proto3" json:"port_configuration,omitempty"` + // Optional buffering configuration for the monitor stream. + BufferConfig *MonitorBufferConfig `protobuf:"bytes,5,opt,name=buffer_config,json=bufferConfig,proto3" json:"buffer_config,omitempty"` } func (x *MonitorPortOpenRequest) Reset() { @@ -228,6 +284,13 @@ func (x *MonitorPortOpenRequest) GetPortConfiguration() *MonitorPortConfiguratio return nil } +func (x *MonitorPortOpenRequest) GetBufferConfig() *MonitorBufferConfig { + if x != nil { + return x.BufferConfig + } + return nil +} + type MonitorResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -332,7 +395,7 @@ type MonitorResponse_AppliedSettings struct { type MonitorResponse_Success struct { // A message with this field set to true is sent as soon as the port is - // succesfully opened. + // successfully opened. Success bool `protobuf:"varint,4,opt,name=success,proto3,oneof"` } @@ -470,7 +533,7 @@ type MonitorPortSettingDescriptor struct { SettingId string `protobuf:"bytes,1,opt,name=setting_id,json=settingId,proto3" json:"setting_id,omitempty"` // A human-readable label of the setting (to be displayed on the GUI). Label string `protobuf:"bytes,2,opt,name=label,proto3" json:"label,omitempty"` - // The setting type (at the moment only "enum" is avaiable). + // The setting type (at the moment only "enum" is available). Type string `protobuf:"bytes,3,opt,name=type,proto3" json:"type,omitempty"` // The values allowed on "enum" types. EnumValues []string `protobuf:"bytes,4,rep,name=enum_values,json=enumValues,proto3" json:"enum_values,omitempty"` @@ -545,6 +608,99 @@ func (x *MonitorPortSettingDescriptor) GetValue() string { return "" } +type MonitorBufferConfig struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Size trigger (bytes). Example: 64. If unset or <= 0, treated as 1 ("unbuffered"). + HighWaterMarkBytes uint32 `protobuf:"varint,1,opt,name=high_water_mark_bytes,json=highWaterMarkBytes,proto3" json:"high_water_mark_bytes,omitempty"` + // Time trigger (ms). Example: 16. 0 disables interval-based flushing. + FlushIntervalMs uint32 `protobuf:"varint,2,opt,name=flush_interval_ms,json=flushIntervalMs,proto3" json:"flush_interval_ms,omitempty"` + // Flush on '\n'. + LineBuffering bool `protobuf:"varint,3,opt,name=line_buffering,json=lineBuffering,proto3" json:"line_buffering,omitempty"` + // Queue capacity between aggregator and TCP writer. If unset or 0, default to 32. + FlushQueueCapacity uint32 `protobuf:"varint,4,opt,name=flush_queue_capacity,json=flushQueueCapacity,proto3" json:"flush_queue_capacity,omitempty"` + // Overflow policy when queue is full. If not set, defaults to drop. + OverflowStrategy BufferOverflowStrategy `protobuf:"varint,5,opt,name=overflow_strategy,json=overflowStrategy,proto3,enum=cc.arduino.cli.commands.v1.BufferOverflowStrategy" json:"overflow_strategy,omitempty"` + // Bounded wait (ms) when overflow_strategy=WAIT. If unset/negative, treated as 0. + OverflowWaitMs uint32 `protobuf:"varint,6,opt,name=overflow_wait_ms,json=overflowWaitMs,proto3" json:"overflow_wait_ms,omitempty"` +} + +func (x *MonitorBufferConfig) Reset() { + *x = MonitorBufferConfig{} + if protoimpl.UnsafeEnabled { + mi := &file_cc_arduino_cli_commands_v1_monitor_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *MonitorBufferConfig) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MonitorBufferConfig) ProtoMessage() {} + +func (x *MonitorBufferConfig) ProtoReflect() protoreflect.Message { + mi := &file_cc_arduino_cli_commands_v1_monitor_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MonitorBufferConfig.ProtoReflect.Descriptor instead. +func (*MonitorBufferConfig) Descriptor() ([]byte, []int) { + return file_cc_arduino_cli_commands_v1_monitor_proto_rawDescGZIP(), []int{6} +} + +func (x *MonitorBufferConfig) GetHighWaterMarkBytes() uint32 { + if x != nil { + return x.HighWaterMarkBytes + } + return 0 +} + +func (x *MonitorBufferConfig) GetFlushIntervalMs() uint32 { + if x != nil { + return x.FlushIntervalMs + } + return 0 +} + +func (x *MonitorBufferConfig) GetLineBuffering() bool { + if x != nil { + return x.LineBuffering + } + return false +} + +func (x *MonitorBufferConfig) GetFlushQueueCapacity() uint32 { + if x != nil { + return x.FlushQueueCapacity + } + return 0 +} + +func (x *MonitorBufferConfig) GetOverflowStrategy() BufferOverflowStrategy { + if x != nil { + return x.OverflowStrategy + } + return BufferOverflowStrategy_BUFFER_OVERFLOW_STRATEGY_UNSPECIFIED +} + +func (x *MonitorBufferConfig) GetOverflowWaitMs() uint32 { + if x != nil { + return x.OverflowWaitMs + } + return 0 +} + var File_cc_arduino_cli_commands_v1_monitor_proto protoreflect.FileDescriptor var file_cc_arduino_cli_commands_v1_monitor_proto_rawDesc = []byte{ @@ -574,7 +730,7 @@ var file_cc_arduino_cli_commands_v1_monitor_proto_rawDesc = []byte{ 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x14, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x05, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x05, 0x63, 0x6c, 0x6f, - 0x73, 0x65, 0x42, 0x09, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x89, 0x02, + 0x73, 0x65, 0x42, 0x09, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0xdf, 0x02, 0x0a, 0x16, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x50, 0x6f, 0x72, 0x74, 0x4f, 0x70, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x40, 0x0a, 0x08, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x63, 0x63, 0x2e, @@ -591,53 +747,89 @@ var file_cc_arduino_cli_commands_v1_monitor_proto_rawDesc = []byte{ 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x50, 0x6f, 0x72, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x11, 0x70, 0x6f, 0x72, 0x74, 0x43, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xce, 0x01, 0x0a, 0x0f, 0x4d, 0x6f, - 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, - 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x05, - 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x19, 0x0a, 0x07, 0x72, 0x78, 0x5f, 0x64, 0x61, 0x74, 0x61, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x06, 0x72, 0x78, 0x44, 0x61, 0x74, 0x61, - 0x12, 0x61, 0x0a, 0x10, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x65, 0x64, 0x5f, 0x73, 0x65, 0x74, 0x74, - 0x69, 0x6e, 0x67, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x63, 0x63, 0x2e, + 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x54, 0x0a, 0x0d, 0x62, 0x75, 0x66, + 0x66, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x2f, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, + 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x6f, + 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x42, 0x75, 0x66, 0x66, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x52, 0x0c, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, + 0xce, 0x01, 0x0a, 0x0f, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x48, 0x00, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x19, 0x0a, 0x07, 0x72, + 0x78, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x06, + 0x72, 0x78, 0x44, 0x61, 0x74, 0x61, 0x12, 0x61, 0x0a, 0x10, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x65, + 0x64, 0x5f, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x34, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, + 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x6f, + 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x50, 0x6f, 0x72, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x0f, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x65, + 0x64, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x1a, 0x0a, 0x07, 0x73, 0x75, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x07, 0x73, 0x75, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x42, 0x09, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x22, 0xa0, 0x01, 0x0a, 0x23, 0x45, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x61, 0x74, 0x65, 0x4d, 0x6f, + 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x50, 0x6f, 0x72, 0x74, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x40, 0x0a, 0x08, 0x69, 0x6e, 0x73, 0x74, + 0x61, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, - 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x50, - 0x6f, 0x72, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x48, 0x00, 0x52, 0x0f, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x65, 0x64, 0x53, 0x65, 0x74, 0x74, 0x69, - 0x6e, 0x67, 0x73, 0x12, 0x1a, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x42, - 0x09, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0xa0, 0x01, 0x0a, 0x23, 0x45, - 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x61, 0x74, 0x65, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x50, - 0x6f, 0x72, 0x74, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x40, 0x0a, 0x08, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, - 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x76, - 0x31, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x08, 0x69, 0x6e, 0x73, 0x74, - 0x61, 0x6e, 0x63, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x70, 0x6f, 0x72, - 0x74, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x71, 0x62, - 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x71, 0x62, 0x6e, 0x22, 0x7c, 0x0a, - 0x24, 0x45, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x61, 0x74, 0x65, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, - 0x72, 0x50, 0x6f, 0x72, 0x74, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x54, 0x0a, 0x08, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, - 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x38, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, - 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, - 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x50, 0x6f, 0x72, 0x74, - 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, - 0x72, 0x52, 0x08, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x22, 0x9e, 0x01, 0x0a, 0x1c, + 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, + 0x52, 0x08, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x70, 0x6f, + 0x72, 0x74, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0c, 0x70, 0x6f, 0x72, 0x74, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, + 0x12, 0x0a, 0x04, 0x66, 0x71, 0x62, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, + 0x71, 0x62, 0x6e, 0x22, 0x7c, 0x0a, 0x24, 0x45, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x61, 0x74, 0x65, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x50, 0x6f, 0x72, 0x74, 0x53, 0x65, 0x74, 0x74, 0x69, - 0x6e, 0x67, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x12, 0x1d, 0x0a, 0x0a, - 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x09, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x6c, - 0x61, 0x62, 0x65, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6c, 0x61, 0x62, 0x65, - 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x65, 0x6e, 0x75, 0x6d, 0x5f, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x65, 0x6e, 0x75, 0x6d, - 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, - 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x48, 0x5a, 0x46, - 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x72, 0x64, 0x75, 0x69, - 0x6e, 0x6f, 0x2f, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2d, 0x63, 0x6c, 0x69, 0x2f, 0x72, - 0x70, 0x63, 0x2f, 0x63, 0x63, 0x2f, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2f, 0x63, 0x6c, - 0x69, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2f, 0x76, 0x31, 0x3b, 0x63, 0x6f, - 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6e, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x54, 0x0a, 0x08, 0x73, + 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x38, 0x2e, + 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, + 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x6f, 0x6e, 0x69, 0x74, + 0x6f, 0x72, 0x50, 0x6f, 0x72, 0x74, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x44, 0x65, 0x73, + 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x52, 0x08, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, + 0x73, 0x22, 0x9e, 0x01, 0x0a, 0x1c, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x50, 0x6f, 0x72, + 0x74, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x6f, 0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x49, + 0x64, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x65, + 0x6e, 0x75, 0x6d, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, + 0x52, 0x0a, 0x65, 0x6e, 0x75, 0x6d, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x14, 0x0a, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x22, 0xd8, 0x02, 0x0a, 0x13, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x42, 0x75, + 0x66, 0x66, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x31, 0x0a, 0x15, 0x68, 0x69, + 0x67, 0x68, 0x5f, 0x77, 0x61, 0x74, 0x65, 0x72, 0x5f, 0x6d, 0x61, 0x72, 0x6b, 0x5f, 0x62, 0x79, + 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x12, 0x68, 0x69, 0x67, 0x68, 0x57, + 0x61, 0x74, 0x65, 0x72, 0x4d, 0x61, 0x72, 0x6b, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x2a, 0x0a, + 0x11, 0x66, 0x6c, 0x75, 0x73, 0x68, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x5f, + 0x6d, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0f, 0x66, 0x6c, 0x75, 0x73, 0x68, 0x49, + 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x4d, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x6c, 0x69, 0x6e, + 0x65, 0x5f, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x0d, 0x6c, 0x69, 0x6e, 0x65, 0x42, 0x75, 0x66, 0x66, 0x65, 0x72, 0x69, 0x6e, 0x67, + 0x12, 0x30, 0x0a, 0x14, 0x66, 0x6c, 0x75, 0x73, 0x68, 0x5f, 0x71, 0x75, 0x65, 0x75, 0x65, 0x5f, + 0x63, 0x61, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x12, + 0x66, 0x6c, 0x75, 0x73, 0x68, 0x51, 0x75, 0x65, 0x75, 0x65, 0x43, 0x61, 0x70, 0x61, 0x63, 0x69, + 0x74, 0x79, 0x12, 0x5f, 0x0a, 0x11, 0x6f, 0x76, 0x65, 0x72, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x73, + 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x32, 0x2e, + 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, + 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x75, 0x66, 0x66, 0x65, + 0x72, 0x4f, 0x76, 0x65, 0x72, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, + 0x79, 0x52, 0x10, 0x6f, 0x76, 0x65, 0x72, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x74, 0x72, 0x61, 0x74, + 0x65, 0x67, 0x79, 0x12, 0x28, 0x0a, 0x10, 0x6f, 0x76, 0x65, 0x72, 0x66, 0x6c, 0x6f, 0x77, 0x5f, + 0x77, 0x61, 0x69, 0x74, 0x5f, 0x6d, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0e, 0x6f, + 0x76, 0x65, 0x72, 0x66, 0x6c, 0x6f, 0x77, 0x57, 0x61, 0x69, 0x74, 0x4d, 0x73, 0x2a, 0x88, 0x01, + 0x0a, 0x16, 0x42, 0x75, 0x66, 0x66, 0x65, 0x72, 0x4f, 0x76, 0x65, 0x72, 0x66, 0x6c, 0x6f, 0x77, + 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x12, 0x28, 0x0a, 0x24, 0x42, 0x55, 0x46, 0x46, + 0x45, 0x52, 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x46, 0x4c, 0x4f, 0x57, 0x5f, 0x53, 0x54, 0x52, 0x41, + 0x54, 0x45, 0x47, 0x59, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, + 0x10, 0x00, 0x12, 0x21, 0x0a, 0x1d, 0x42, 0x55, 0x46, 0x46, 0x45, 0x52, 0x5f, 0x4f, 0x56, 0x45, + 0x52, 0x46, 0x4c, 0x4f, 0x57, 0x5f, 0x53, 0x54, 0x52, 0x41, 0x54, 0x45, 0x47, 0x59, 0x5f, 0x44, + 0x52, 0x4f, 0x50, 0x10, 0x01, 0x12, 0x21, 0x0a, 0x1d, 0x42, 0x55, 0x46, 0x46, 0x45, 0x52, 0x5f, + 0x4f, 0x56, 0x45, 0x52, 0x46, 0x4c, 0x4f, 0x57, 0x5f, 0x53, 0x54, 0x52, 0x41, 0x54, 0x45, 0x47, + 0x59, 0x5f, 0x57, 0x41, 0x49, 0x54, 0x10, 0x02, 0x42, 0x48, 0x5a, 0x46, 0x67, 0x69, 0x74, 0x68, + 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2f, 0x61, + 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2d, 0x63, 0x6c, 0x69, 0x2f, 0x72, 0x70, 0x63, 0x2f, 0x63, + 0x63, 0x2f, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2f, 0x63, 0x6c, 0x69, 0x2f, 0x63, 0x6f, + 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2f, 0x76, 0x31, 0x3b, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, + 0x64, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -652,32 +844,37 @@ func file_cc_arduino_cli_commands_v1_monitor_proto_rawDescGZIP() []byte { return file_cc_arduino_cli_commands_v1_monitor_proto_rawDescData } -var file_cc_arduino_cli_commands_v1_monitor_proto_msgTypes = make([]protoimpl.MessageInfo, 6) +var file_cc_arduino_cli_commands_v1_monitor_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_cc_arduino_cli_commands_v1_monitor_proto_msgTypes = make([]protoimpl.MessageInfo, 7) var file_cc_arduino_cli_commands_v1_monitor_proto_goTypes = []any{ - (*MonitorRequest)(nil), // 0: cc.arduino.cli.commands.v1.MonitorRequest - (*MonitorPortOpenRequest)(nil), // 1: cc.arduino.cli.commands.v1.MonitorPortOpenRequest - (*MonitorResponse)(nil), // 2: cc.arduino.cli.commands.v1.MonitorResponse - (*EnumerateMonitorPortSettingsRequest)(nil), // 3: cc.arduino.cli.commands.v1.EnumerateMonitorPortSettingsRequest - (*EnumerateMonitorPortSettingsResponse)(nil), // 4: cc.arduino.cli.commands.v1.EnumerateMonitorPortSettingsResponse - (*MonitorPortSettingDescriptor)(nil), // 5: cc.arduino.cli.commands.v1.MonitorPortSettingDescriptor - (*MonitorPortConfiguration)(nil), // 6: cc.arduino.cli.commands.v1.MonitorPortConfiguration - (*Instance)(nil), // 7: cc.arduino.cli.commands.v1.Instance - (*Port)(nil), // 8: cc.arduino.cli.commands.v1.Port + (BufferOverflowStrategy)(0), // 0: cc.arduino.cli.commands.v1.BufferOverflowStrategy + (*MonitorRequest)(nil), // 1: cc.arduino.cli.commands.v1.MonitorRequest + (*MonitorPortOpenRequest)(nil), // 2: cc.arduino.cli.commands.v1.MonitorPortOpenRequest + (*MonitorResponse)(nil), // 3: cc.arduino.cli.commands.v1.MonitorResponse + (*EnumerateMonitorPortSettingsRequest)(nil), // 4: cc.arduino.cli.commands.v1.EnumerateMonitorPortSettingsRequest + (*EnumerateMonitorPortSettingsResponse)(nil), // 5: cc.arduino.cli.commands.v1.EnumerateMonitorPortSettingsResponse + (*MonitorPortSettingDescriptor)(nil), // 6: cc.arduino.cli.commands.v1.MonitorPortSettingDescriptor + (*MonitorBufferConfig)(nil), // 7: cc.arduino.cli.commands.v1.MonitorBufferConfig + (*MonitorPortConfiguration)(nil), // 8: cc.arduino.cli.commands.v1.MonitorPortConfiguration + (*Instance)(nil), // 9: cc.arduino.cli.commands.v1.Instance + (*Port)(nil), // 10: cc.arduino.cli.commands.v1.Port } var file_cc_arduino_cli_commands_v1_monitor_proto_depIdxs = []int32{ - 1, // 0: cc.arduino.cli.commands.v1.MonitorRequest.open_request:type_name -> cc.arduino.cli.commands.v1.MonitorPortOpenRequest - 6, // 1: cc.arduino.cli.commands.v1.MonitorRequest.updated_configuration:type_name -> cc.arduino.cli.commands.v1.MonitorPortConfiguration - 7, // 2: cc.arduino.cli.commands.v1.MonitorPortOpenRequest.instance:type_name -> cc.arduino.cli.commands.v1.Instance - 8, // 3: cc.arduino.cli.commands.v1.MonitorPortOpenRequest.port:type_name -> cc.arduino.cli.commands.v1.Port - 6, // 4: cc.arduino.cli.commands.v1.MonitorPortOpenRequest.port_configuration:type_name -> cc.arduino.cli.commands.v1.MonitorPortConfiguration - 6, // 5: cc.arduino.cli.commands.v1.MonitorResponse.applied_settings:type_name -> cc.arduino.cli.commands.v1.MonitorPortConfiguration - 7, // 6: cc.arduino.cli.commands.v1.EnumerateMonitorPortSettingsRequest.instance:type_name -> cc.arduino.cli.commands.v1.Instance - 5, // 7: cc.arduino.cli.commands.v1.EnumerateMonitorPortSettingsResponse.settings:type_name -> cc.arduino.cli.commands.v1.MonitorPortSettingDescriptor - 8, // [8:8] is the sub-list for method output_type - 8, // [8:8] is the sub-list for method input_type - 8, // [8:8] is the sub-list for extension type_name - 8, // [8:8] is the sub-list for extension extendee - 0, // [0:8] is the sub-list for field type_name + 2, // 0: cc.arduino.cli.commands.v1.MonitorRequest.open_request:type_name -> cc.arduino.cli.commands.v1.MonitorPortOpenRequest + 8, // 1: cc.arduino.cli.commands.v1.MonitorRequest.updated_configuration:type_name -> cc.arduino.cli.commands.v1.MonitorPortConfiguration + 9, // 2: cc.arduino.cli.commands.v1.MonitorPortOpenRequest.instance:type_name -> cc.arduino.cli.commands.v1.Instance + 10, // 3: cc.arduino.cli.commands.v1.MonitorPortOpenRequest.port:type_name -> cc.arduino.cli.commands.v1.Port + 8, // 4: cc.arduino.cli.commands.v1.MonitorPortOpenRequest.port_configuration:type_name -> cc.arduino.cli.commands.v1.MonitorPortConfiguration + 7, // 5: cc.arduino.cli.commands.v1.MonitorPortOpenRequest.buffer_config:type_name -> cc.arduino.cli.commands.v1.MonitorBufferConfig + 8, // 6: cc.arduino.cli.commands.v1.MonitorResponse.applied_settings:type_name -> cc.arduino.cli.commands.v1.MonitorPortConfiguration + 9, // 7: cc.arduino.cli.commands.v1.EnumerateMonitorPortSettingsRequest.instance:type_name -> cc.arduino.cli.commands.v1.Instance + 6, // 8: cc.arduino.cli.commands.v1.EnumerateMonitorPortSettingsResponse.settings:type_name -> cc.arduino.cli.commands.v1.MonitorPortSettingDescriptor + 0, // 9: cc.arduino.cli.commands.v1.MonitorBufferConfig.overflow_strategy:type_name -> cc.arduino.cli.commands.v1.BufferOverflowStrategy + 10, // [10:10] is the sub-list for method output_type + 10, // [10:10] is the sub-list for method input_type + 10, // [10:10] is the sub-list for extension type_name + 10, // [10:10] is the sub-list for extension extendee + 0, // [0:10] is the sub-list for field type_name } func init() { file_cc_arduino_cli_commands_v1_monitor_proto_init() } @@ -760,6 +957,18 @@ func file_cc_arduino_cli_commands_v1_monitor_proto_init() { return nil } } + file_cc_arduino_cli_commands_v1_monitor_proto_msgTypes[6].Exporter = func(v any, i int) any { + switch v := v.(*MonitorBufferConfig); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } file_cc_arduino_cli_commands_v1_monitor_proto_msgTypes[0].OneofWrappers = []any{ (*MonitorRequest_OpenRequest)(nil), @@ -778,13 +987,14 @@ func file_cc_arduino_cli_commands_v1_monitor_proto_init() { File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_cc_arduino_cli_commands_v1_monitor_proto_rawDesc, - NumEnums: 0, - NumMessages: 6, + NumEnums: 1, + NumMessages: 7, NumExtensions: 0, NumServices: 0, }, GoTypes: file_cc_arduino_cli_commands_v1_monitor_proto_goTypes, DependencyIndexes: file_cc_arduino_cli_commands_v1_monitor_proto_depIdxs, + EnumInfos: file_cc_arduino_cli_commands_v1_monitor_proto_enumTypes, MessageInfos: file_cc_arduino_cli_commands_v1_monitor_proto_msgTypes, }.Build() File_cc_arduino_cli_commands_v1_monitor_proto = out.File diff --git a/rpc/cc/arduino/cli/commands/v1/monitor.proto b/rpc/cc/arduino/cli/commands/v1/monitor.proto index 58acff0a78d..7b62e71f82b 100644 --- a/rpc/cc/arduino/cli/commands/v1/monitor.proto +++ b/rpc/cc/arduino/cli/commands/v1/monitor.proto @@ -49,6 +49,8 @@ message MonitorPortOpenRequest { string fqbn = 3; // Port configuration, optional, contains settings of the port to be applied. MonitorPortConfiguration port_configuration = 4; + // Optional buffering configuration for the monitor stream. + MonitorBufferConfig buffer_config = 5; } message MonitorResponse { @@ -62,7 +64,7 @@ message MonitorResponse { // (to report the new settings applied). MonitorPortConfiguration applied_settings = 3; // A message with this field set to true is sent as soon as the port is - // succesfully opened. + // successfully opened. bool success = 4; } } @@ -89,10 +91,41 @@ message MonitorPortSettingDescriptor { string setting_id = 1; // A human-readable label of the setting (to be displayed on the GUI). string label = 2; - // The setting type (at the moment only "enum" is avaiable). + // The setting type (at the moment only "enum" is available). string type = 3; // The values allowed on "enum" types. repeated string enum_values = 4; // The selected or default value. string value = 5; } + +message MonitorBufferConfig { + // Size trigger (bytes). Example: 64. If unset or <= 0, treated as 1 ("unbuffered"). + uint32 high_water_mark_bytes = 1; + + // Time trigger (ms). Example: 16. 0 disables interval-based flushing. + uint32 flush_interval_ms = 2; + + // Flush on '\n'. + bool line_buffering = 3; + + // Queue capacity between aggregator and TCP writer. If unset or 0, default to 32. + uint32 flush_queue_capacity = 4; + + // Overflow policy when queue is full. If not set, defaults to drop. + BufferOverflowStrategy overflow_strategy = 5; + + // Bounded wait (ms) when overflow_strategy=WAIT. If unset/negative, treated as 0. + uint32 overflow_wait_ms = 6; +} + +// BufferOverflowStrategy defines how the pluggable monitor should behave +// when the port→TCP queue is full. +enum BufferOverflowStrategy { + // Unspecified; treated as DROP by the server/handler for backward compatibility. + BUFFER_OVERFLOW_STRATEGY_UNSPECIFIED = 0; + // Drop the aggregated payload when the queue is full (do not block the port reader). + BUFFER_OVERFLOW_STRATEGY_DROP = 1; + // Wait up to a bounded timeout for space in the queue before dropping. + BUFFER_OVERFLOW_STRATEGY_WAIT = 2; +}