@@ -21,6 +21,7 @@ import (
21
21
"sync"
22
22
"time"
23
23
24
+ "github.com/arduino/arduino-cli/cli/globals"
24
25
"github.com/arduino/arduino-cli/executils"
25
26
"github.com/arduino/go-properties-orderedmap"
26
27
"github.com/pkg/errors"
@@ -30,7 +31,6 @@ import (
30
31
// with the boards.
31
32
type PluggableDiscovery struct {
32
33
id string
33
- args []string
34
34
process * executils.Process
35
35
outgoingCommandsPipe io.Writer
36
36
incomingMessagesChan <- chan * discoveryMessage
@@ -45,20 +45,21 @@ type PluggableDiscovery struct {
45
45
}
46
46
47
47
type discoveryMessage struct {
48
- EventType string `json:"eventType"`
49
- Message string `json:"message"`
50
- Ports []* Port `json:"ports"`
51
- Port * Port `json:"port"`
48
+ EventType string `json:"eventType"`
49
+ Message string `json:"message"`
50
+ Error bool `json:"error"`
51
+ ProtocolVersion int `json:"protocolVersion"` // Used in HELLO command
52
+ Ports []* Port `json:"ports"` // Used in LIST command
53
+ Port * Port `json:"port"` // Used in add and remove events
52
54
}
53
55
54
56
// Port containts metadata about a port to connect to a board.
55
57
type Port struct {
56
- Address string `json:"address"`
57
- AddressLabel string `json:"label"`
58
- Protocol string `json:"protocol"`
59
- ProtocolLabel string `json:"protocolLabel"`
60
- Properties * properties.Map `json:"prefs"`
61
- IdentificationProperties * properties.Map `json:"identificationPrefs"`
58
+ Address string `json:"address"`
59
+ AddressLabel string `json:"label"`
60
+ Protocol string `json:"protocol"`
61
+ ProtocolLabel string `json:"protocolLabel"`
62
+ Properties * properties.Map `json:"properties"`
62
63
}
63
64
64
65
func (p * Port ) String () string {
@@ -121,20 +122,20 @@ func (disc *PluggableDiscovery) jsonDecodeLoop(in io.Reader, outChan chan<- *dis
121
122
disc .statusMutex .Unlock ()
122
123
close (outChan )
123
124
}
125
+
124
126
for {
125
127
var msg discoveryMessage
126
128
if err := decoder .Decode (& msg ); err != nil {
127
129
closeAndReportError (err )
128
130
return
129
131
}
130
-
131
132
if msg .EventType == "add" {
132
133
if msg .Port == nil {
133
134
closeAndReportError (errors .New ("invalid 'add' message: missing port" ))
134
135
return
135
136
}
136
137
disc .statusMutex .Lock ()
137
- disc .cachedPorts [msg .Port .Address ] = msg .Port
138
+ disc .cachedPorts [msg .Port .Address + "|" + msg . Port . Protocol ] = msg .Port
138
139
if disc .eventChan != nil {
139
140
disc .eventChan <- & Event {"add" , msg .Port }
140
141
}
@@ -145,7 +146,7 @@ func (disc *PluggableDiscovery) jsonDecodeLoop(in io.Reader, outChan chan<- *dis
145
146
return
146
147
}
147
148
disc .statusMutex .Lock ()
148
- delete (disc .cachedPorts , msg .Port .Address )
149
+ delete (disc .cachedPorts , msg .Port .Address + "|" + msg . Port . Protocol )
149
150
if disc .eventChan != nil {
150
151
disc .eventChan <- & Event {"remove" , msg .Port }
151
152
}
@@ -187,13 +188,35 @@ func (disc *PluggableDiscovery) waitMessage(timeout time.Duration) (*discoveryMe
187
188
}
188
189
189
190
func (disc * PluggableDiscovery ) sendCommand (command string ) error {
190
- if n , err := disc .outgoingCommandsPipe .Write ([]byte (command )); err != nil {
191
+ data := []byte (command )
192
+ for {
193
+ n , err := disc .outgoingCommandsPipe .Write (data )
194
+ if err != nil {
195
+ return err
196
+ }
197
+ if n == len (data ) {
198
+ return nil
199
+ }
200
+ data = data [n :]
201
+ }
202
+ }
203
+
204
+ // Hello sends the HELLO command to the discovery to agree on the pluggable discovery protocol. This
205
+ // must be the first command to run in the communication with the discovery.
206
+ func (disc * PluggableDiscovery ) Hello () error {
207
+ if err := disc .sendCommand ("HELLO 1 \" arduino-cli " + globals .VersionInfo .VersionString + "\" \n " ); err != nil {
191
208
return err
192
- } else if n < len (command ) {
193
- return disc .sendCommand (command [n :])
194
- } else {
195
- return nil
196
209
}
210
+ if msg , err := disc .waitMessage (time .Second * 10 ); err != nil {
211
+ return err
212
+ } else if msg .EventType != "hello" {
213
+ return errors .Errorf ("communication out of sync, expected 'hello', received '%s'" , msg .EventType )
214
+ } else if msg .Message != "OK" || msg .Error {
215
+ return errors .Errorf ("command failed: %s" , msg .Message )
216
+ } else if msg .ProtocolVersion > 1 {
217
+ return errors .Errorf ("protocol version not supported: requested 1, got %d" , msg .ProtocolVersion )
218
+ }
219
+ return nil
197
220
}
198
221
199
222
// Start initializes and start the discovery internal subroutines. This command must be
@@ -206,7 +229,7 @@ func (disc *PluggableDiscovery) Start() error {
206
229
return err
207
230
} else if msg .EventType != "start" {
208
231
return errors .Errorf ("communication out of sync, expected 'start', received '%s'" , msg .EventType )
209
- } else if msg .Message != "OK" {
232
+ } else if msg .Message != "OK" || msg . Error {
210
233
return errors .Errorf ("command failed: %s" , msg .Message )
211
234
}
212
235
return nil
@@ -223,7 +246,7 @@ func (disc *PluggableDiscovery) Stop() error {
223
246
return err
224
247
} else if msg .EventType != "stop" {
225
248
return errors .Errorf ("communication out of sync, expected 'stop', received '%s'" , msg .EventType )
226
- } else if msg .Message != "OK" {
249
+ } else if msg .Message != "OK" || msg . Error {
227
250
return errors .Errorf ("command failed: %s" , msg .Message )
228
251
}
229
252
return nil
@@ -238,7 +261,7 @@ func (disc *PluggableDiscovery) Quit() error {
238
261
return err
239
262
} else if msg .EventType != "quit" {
240
263
return errors .Errorf ("communication out of sync, expected 'quit', received '%s'" , msg .EventType )
241
- } else if msg .Message != "OK" {
264
+ } else if msg .Message != "OK" || msg . Error {
242
265
return errors .Errorf ("command failed: %s" , msg .Message )
243
266
}
244
267
return nil
@@ -254,6 +277,8 @@ func (disc *PluggableDiscovery) List() ([]*Port, error) {
254
277
return nil , err
255
278
} else if msg .EventType != "list" {
256
279
return nil , errors .Errorf ("communication out of sync, expected 'list', received '%s'" , msg .EventType )
280
+ } else if msg .Error {
281
+ return nil , errors .Errorf ("command failed: %s" , msg .Message )
257
282
} else {
258
283
return msg .Ports , nil
259
284
}
@@ -285,7 +310,13 @@ func (disc *PluggableDiscovery) StartSync() error {
285
310
return err
286
311
}
287
312
288
- // START_SYNC does not give any response
313
+ if msg , err := disc .waitMessage (time .Second * 10 ); err != nil {
314
+ return err
315
+ } else if msg .EventType != "start_sync" {
316
+ return errors .Errorf ("communication out of sync, expected 'start_sync', received '%s'" , msg .EventType )
317
+ } else if msg .Message != "OK" || msg .Error {
318
+ return errors .Errorf ("command failed: %s" , msg .Message )
319
+ }
289
320
290
321
disc .eventsMode = true
291
322
disc .cachedPorts = map [string ]* Port {}
0 commit comments