1616package commands
1717
1818import (
19+ "context"
1920 "errors"
2021 "os"
22+ "sync/atomic"
2123
2224 "github.com/arduino/arduino-cli/internal/i18n"
2325 rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1"
26+ "google.golang.org/grpc/metadata"
2427
2528 "fmt"
2629 "io"
@@ -32,9 +35,68 @@ import (
3235 "github.com/sirupsen/logrus"
3336)
3437
35- // Debug returns a stream response that can be used to fetch data from the
36- // target. The first message passed through the `Debug` request must
37- // contain DebugRequest configuration params, not data.
38+ type debugServer struct {
39+ ctx context.Context
40+ req atomic.Pointer [rpc.GetDebugConfigRequest ]
41+ in io.Reader
42+ out io.Writer
43+ resultCB func (* rpc.DebugResponse_Result )
44+ }
45+
46+ func (s * debugServer ) Send (resp * rpc.DebugResponse ) error {
47+ if len (resp .GetData ()) > 0 {
48+ if _ , err := s .out .Write (resp .GetData ()); err != nil {
49+ return err
50+ }
51+ }
52+ if res := resp .GetResult (); res != nil {
53+ s .resultCB (res )
54+ }
55+ return nil
56+ }
57+
58+ func (s * debugServer ) Recv () (r * rpc.DebugRequest , e error ) {
59+ if conf := s .req .Swap (nil ); conf != nil {
60+ return & rpc.DebugRequest {DebugRequest : s .req .Load ()}, nil
61+ }
62+ buff := make ([]byte , 4096 )
63+ n , err := s .in .Read (buff )
64+ if err != nil {
65+ return nil , err
66+ }
67+ return & rpc.DebugRequest {Data : buff [:n ]}, nil
68+ }
69+
70+ func (s * debugServer ) Context () context.Context { return s .ctx }
71+ func (s * debugServer ) RecvMsg (m any ) error { return nil }
72+ func (s * debugServer ) SendHeader (metadata.MD ) error { return nil }
73+ func (s * debugServer ) SendMsg (m any ) error { return nil }
74+ func (s * debugServer ) SetHeader (metadata.MD ) error { return nil }
75+ func (s * debugServer ) SetTrailer (metadata.MD ) {}
76+
77+ // DebugServerToStreams creates a debug server that proxies the data to the given io streams.
78+ // The GetDebugConfigRequest is used to configure the debbuger. sig is a channel that can be
79+ // used to send os.Interrupt to the debug process. resultCB is a callback function that will
80+ // receive the Debug result.
81+ func DebugServerToStreams (
82+ ctx context.Context ,
83+ req * rpc.GetDebugConfigRequest ,
84+ in io.Reader , out io.Writer ,
85+ sig chan os.Signal ,
86+ resultCB func (* rpc.DebugResponse_Result ),
87+ ) rpc.ArduinoCoreService_DebugServer {
88+ server := & debugServer {
89+ ctx : ctx ,
90+ in : in ,
91+ out : out ,
92+ resultCB : resultCB ,
93+ }
94+ server .req .Store (req )
95+ return server
96+ }
97+
98+ // Debug starts a debugging session. The first message passed through the `Debug` request must
99+ // contain DebugRequest configuration params and no data.
38100func (s * arduinoCoreServerImpl ) Debug (stream rpc.ArduinoCoreService_DebugServer ) error {
39101 // Utility functions
40102 syncSend := NewSynchronizedSend (stream .Send )
0 commit comments