Skip to content

Commit 30eb624

Browse files
committed
added monitor service implementation
1 parent 21926bc commit 30eb624

File tree

1 file changed

+111
-0
lines changed

1 file changed

+111
-0
lines changed

Diff for: commands/daemon/monitor.go

+111
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
// This file is part of arduino-cli.
2+
//
3+
// Copyright 2019 ARDUINO SA (http://www.arduino.cc/)
4+
//
5+
// This software is released under the GNU General Public License version 3,
6+
// which covers the main part of arduino-cli.
7+
// The terms of this license can be found at:
8+
// https://www.gnu.org/licenses/gpl-3.0.en.html
9+
//
10+
// You can be released from the requirements of the above licenses by purchasing
11+
// a commercial license. Buying such a license is mandatory if you want to
12+
// modify or otherwise use the software for commercial activities involving the
13+
// Arduino software without disclosing the source code of your own applications.
14+
// To purchase a commercial license, send an email to [email protected].
15+
16+
package daemon
17+
18+
import (
19+
"fmt"
20+
"io"
21+
"log"
22+
23+
"github.com/arduino/arduino-cli/arduino/monitors"
24+
rpc "github.com/arduino/arduino-cli/rpc/monitor"
25+
)
26+
27+
// MonitorService implements the `Monitor` service
28+
type MonitorService struct {
29+
}
30+
31+
// StreamingOpen returns a stream response that can be used to fetch data from the
32+
// monitor target. The first message passed through the `StreamingOpenReq` must
33+
// contain monitor configuration params, not data.
34+
func (s *MonitorService) StreamingOpen(stream rpc.Monitor_StreamingOpenServer) error {
35+
// grab the first message
36+
msg, err := stream.Recv()
37+
if err != nil {
38+
return err
39+
}
40+
41+
// ensure it's a config message and not data
42+
config := msg.GetMonitorConfig()
43+
if config == nil {
44+
return fmt.Errorf("first message must contain monitor configuration, not data")
45+
}
46+
47+
// select which type of monitor we need
48+
var mon monitors.Monitor
49+
switch config.GetType() {
50+
case rpc.MonitorConfig_SERIAL:
51+
// grab port speed from additional config data
52+
var baudRate float64
53+
addCfg := config.GetAdditionalConfig()
54+
for k, v := range addCfg.GetFields() {
55+
if k == "BaudRate" {
56+
baudRate = v.GetNumberValue()
57+
break
58+
}
59+
}
60+
61+
// default baud rate if not provided
62+
if baudRate == 0 {
63+
baudRate = 9600
64+
}
65+
66+
var err error
67+
if mon, err = monitors.OpenSerialMonitor(config.GetTarget(), int(baudRate)); err != nil {
68+
return err
69+
}
70+
}
71+
72+
// now we can stream the other messages and re-route to the monitor
73+
go func() {
74+
for {
75+
msg, err := stream.Recv()
76+
if err == io.EOF {
77+
// connection closed, exit
78+
break
79+
}
80+
81+
if err != nil {
82+
// error, exit
83+
log.Fatal(err)
84+
break
85+
}
86+
87+
mon.Write(msg.GetData())
88+
}
89+
}()
90+
91+
// read from the monitor and forward to the output stream
92+
93+
buf := make([]byte, 8)
94+
for {
95+
n, err := mon.Read(buf)
96+
if err != nil {
97+
return err
98+
}
99+
100+
if n == 0 {
101+
// port was closed
102+
return nil
103+
}
104+
105+
if err = stream.Send(&rpc.StreamingOpenResp{
106+
Data: buf[:n],
107+
}); err != nil {
108+
return err
109+
}
110+
}
111+
}

0 commit comments

Comments
 (0)