Skip to content

Commit

Permalink
Porting attach command(WIP)
Browse files Browse the repository at this point in the history
  • Loading branch information
Rocketct committed May 16, 2019
1 parent 6f90002 commit 6bb9425
Show file tree
Hide file tree
Showing 9 changed files with 455 additions and 238 deletions.
1 change: 1 addition & 0 deletions arduino/sketches/sketches.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ func NewSketchFromPath(path *paths.Path) (*Sketch, error) {
sketch := &Sketch{
FullPath: path,
Name: path.Base(),
Metadata: &Metadata{},
}
sketch.ImportMetadata()
return sketch, nil
Expand Down
146 changes: 14 additions & 132 deletions cli/board/attach.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,13 @@
package board

import (
"fmt"
"net/url"
"context"
"os"
"strings"
"time"

"github.com/arduino/arduino-cli/arduino/cores"
"github.com/arduino/arduino-cli/arduino/cores/packagemanager"
"github.com/arduino/arduino-cli/arduino/sketches"
"github.com/arduino/arduino-cli/cli"
"github.com/arduino/arduino-cli/commands/board"
"github.com/arduino/arduino-cli/common/formatter"
discovery "github.com/arduino/board-discovery"
paths "github.com/arduino/go-paths-helper"
"github.com/sirupsen/logrus"
"github.com/arduino/arduino-cli/rpc"
"github.com/spf13/cobra"
)

Expand Down Expand Up @@ -59,131 +52,20 @@ var attachFlags struct {
}

func runAttachCommand(cmd *cobra.Command, args []string) {
boardURI := args[0]

var path *paths.Path
instance := cli.CreateInstance()
var path string
if len(args) > 0 {
path = paths.New(args[0])
path = args[1]
}
sketchPath := cli.InitSketchPath(path)

sketch, err := sketches.NewSketchFromPath(sketchPath)
_, err := board.BoardAttach(context.Background(), &rpc.BoardAttachReq{
Instance: instance,
BoardURI: args[0],
SketchPath: path,
BoardFlavour: attachFlags.boardFlavour,
SearchTimeout: attachFlags.searchTimeout,
})
if err != nil {
formatter.PrintError(err, "Error opening sketch.")
formatter.PrintError(err, "attach board error")
os.Exit(cli.ErrGeneric)
}

logrus.WithField("fqbn", boardURI).Print("Parsing FQBN")
fqbn, err := cores.ParseFQBN(boardURI)
if err != nil && !strings.HasPrefix(boardURI, "serial") {
boardURI = "serial://" + boardURI
}

pm, _ := cli.InitPackageAndLibraryManager()

if fqbn != nil {
sketch.Metadata.CPU = sketches.BoardMetadata{
Fqbn: fqbn.String(),
}
} else {
deviceURI, err := url.Parse(boardURI)
if err != nil {
formatter.PrintError(err, "The provided Device URL is not in a valid format.")
os.Exit(cli.ErrBadCall)
}

var findBoardFunc func(*packagemanager.PackageManager, *discovery.Monitor, *url.URL) *cores.Board
switch deviceURI.Scheme {
case "serial", "tty":
findBoardFunc = findSerialConnectedBoard
case "http", "https", "tcp", "udp":
findBoardFunc = findNetworkConnectedBoard
default:
formatter.PrintErrorMessage("Invalid device port type provided. Accepted types are: serial://, tty://, http://, https://, tcp://, udp://.")
os.Exit(cli.ErrBadCall)
}

duration, err := time.ParseDuration(attachFlags.searchTimeout)
if err != nil {
logrus.WithError(err).Warnf("Invalid interval `%s` provided, using default (5s).", attachFlags.searchTimeout)
duration = time.Second * 5
}

monitor := discovery.New(time.Second)
monitor.Start()

time.Sleep(duration)

// TODO: Handle the case when no board is found.
board := findBoardFunc(pm, monitor, deviceURI)
if board == nil {
formatter.PrintErrorMessage("No supported board has been found at " + deviceURI.String() + ", try either install new cores or check your board URI.")
os.Exit(cli.ErrGeneric)
}
formatter.Print("Board found: " + board.Name())

sketch.Metadata.CPU = sketches.BoardMetadata{
Fqbn: board.FQBN(),
Name: board.Name(),
}
}

err = sketch.ExportMetadata()
if err != nil {
formatter.PrintError(err, "Cannot export sketch metadata.")
}
formatter.PrintResult("Selected fqbn: " + sketch.Metadata.CPU.Fqbn)
}

// FIXME: Those should probably go in a "BoardManager" pkg or something
// findSerialConnectedBoard find the board which is connected to the specified URI via serial port, using a monitor and a set of Boards
// for the matching.
func findSerialConnectedBoard(pm *packagemanager.PackageManager, monitor *discovery.Monitor, deviceURI *url.URL) *cores.Board {
found := false
location := deviceURI.Path
var serialDevice discovery.SerialDevice
for _, device := range monitor.Serial() {
if device.Port == location {
// Found the device !
found = true
serialDevice = *device
}
}
if !found {
return nil
}

boards := pm.FindBoardsWithVidPid(serialDevice.VendorID, serialDevice.ProductID)
if len(boards) == 0 {
os.Exit(cli.ErrGeneric)
}

return boards[0]
}

// findNetworkConnectedBoard find the board which is connected to the specified URI on the network, using a monitor and a set of Boards
// for the matching.
func findNetworkConnectedBoard(pm *packagemanager.PackageManager, monitor *discovery.Monitor, deviceURI *url.URL) *cores.Board {
found := false

var networkDevice discovery.NetworkDevice

for _, device := range monitor.Network() {
if device.Address == deviceURI.Host &&
fmt.Sprint(device.Port) == deviceURI.Port() {
// Found the device !
found = true
networkDevice = *device
}
}
if !found {
return nil
}

boards := pm.FindBoardsWithID(networkDevice.Name)
if len(boards) == 0 {
return nil
}

return boards[0]
}
164 changes: 164 additions & 0 deletions commands/board/attach.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
/*
* This file is part of arduino-cli.
*
* Copyright 2018 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 [email protected].
*/

package board

import (
"context"
"errors"
"fmt"
"net/url"
"strings"
"time"

"github.com/arduino/arduino-cli/arduino/cores"
"github.com/arduino/arduino-cli/arduino/cores/packagemanager"
"github.com/arduino/arduino-cli/arduino/sketches"
"github.com/arduino/arduino-cli/commands"
"github.com/arduino/arduino-cli/common/formatter"
"github.com/arduino/arduino-cli/rpc"
discovery "github.com/arduino/board-discovery"
paths "github.com/arduino/go-paths-helper"
)

func BoardAttach(ctx context.Context, req *rpc.BoardAttachReq) (*rpc.BoardAttachResp, error) {

pm := commands.GetPackageManager(req)
if pm == nil {
return nil, errors.New("invalid instance")
}
var sketchPath *paths.Path
if req.GetSketchPath() != "" {
sketchPath = paths.New(req.GetSketchPath())
}
sketch, err := sketches.NewSketchFromPath(sketchPath)
if err != nil {
return nil, fmt.Errorf("opening sketch: %s", err)
}
if sketch.Metadata == nil {
formatter.Print("sketch errrorrrerereererer")
}
boardURI := req.GetBoardURI()
fqbn, err := cores.ParseFQBN(boardURI)
if err != nil && !strings.HasPrefix(boardURI, "serial") {
boardURI = "serial://" + boardURI
}

if fqbn != nil {
sketch.Metadata.CPU = sketches.BoardMetadata{
Fqbn: fqbn.String(),
}
} else {
deviceURI, err := url.Parse(boardURI)
if err != nil {
return nil, fmt.Errorf("invalid Device URL format: %s", err)
}

var findBoardFunc func(*packagemanager.PackageManager, *discovery.Monitor, *url.URL) *cores.Board
switch deviceURI.Scheme {
case "serial", "tty":
findBoardFunc = findSerialConnectedBoard
case "http", "https", "tcp", "udp":
findBoardFunc = findNetworkConnectedBoard
default:
return nil, fmt.Errorf("invalid device port type provided")
}

duration, err := time.ParseDuration(req.GetSearchTimeout())
if err != nil {
//logrus.WithError(err).Warnf("Invalid interval `%s` provided, using default (5s).", req.GetSearchTimeout())
duration = time.Second * 5
}

monitor := discovery.New(time.Second)
monitor.Start()

time.Sleep(duration)

// TODO: Handle the case when no board is found.
board := findBoardFunc(pm, monitor, deviceURI)
if board == nil {
return nil, fmt.Errorf("no supported board found at %s", deviceURI.String())
}
formatter.Print("Board found: " + board.Name())

sketch.Metadata.CPU = sketches.BoardMetadata{
Fqbn: board.FQBN(),
Name: board.Name(),
}
}

err = sketch.ExportMetadata()
if err != nil {
return nil, fmt.Errorf("cannot export sketch metadata: %s", err)
}
formatter.PrintResult("Selected fqbn: " + sketch.Metadata.CPU.Fqbn)
return &rpc.BoardAttachResp{}, nil
}

// FIXME: Those should probably go in a "BoardManager" pkg or something
// findSerialConnectedBoard find the board which is connected to the specified URI via serial port, using a monitor and a set of Boards
// for the matching.
func findSerialConnectedBoard(pm *packagemanager.PackageManager, monitor *discovery.Monitor, deviceURI *url.URL) *cores.Board {
found := false
location := deviceURI.Path
var serialDevice discovery.SerialDevice
for _, device := range monitor.Serial() {
if device.Port == location {
// Found the device !
found = true
serialDevice = *device
}
}
if !found {
return nil
}

boards := pm.FindBoardsWithVidPid(serialDevice.VendorID, serialDevice.ProductID)
if len(boards) == 0 {
return nil
}

return boards[0]
}

// findNetworkConnectedBoard find the board which is connected to the specified URI on the network, using a monitor and a set of Boards
// for the matching.
func findNetworkConnectedBoard(pm *packagemanager.PackageManager, monitor *discovery.Monitor, deviceURI *url.URL) *cores.Board {
found := false

var networkDevice discovery.NetworkDevice

for _, device := range monitor.Network() {
if device.Address == deviceURI.Host &&
fmt.Sprint(device.Port) == deviceURI.Port() {
// Found the device !
found = true
networkDevice = *device
}
}
if !found {
return nil
}

boards := pm.FindBoardsWithID(networkDevice.Name)
if len(boards) == 0 {
return nil
}

return boards[0]
}
20 changes: 16 additions & 4 deletions daemon/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,10 @@ func main() {
}

// PLATFORM SEARCH
fmt.Println("=== calling PlatformSearch(uno)")
fmt.Println("=== calling PlatformSearch(samd)")
searchResp, err := client.PlatformSearch(context.Background(), &rpc.PlatformSearchReq{
Instance: instance,
SearchArgs: "uno",
SearchArgs: "samd",
})
if err != nil {
fmt.Printf("Search error: %s\n", err)
Expand Down Expand Up @@ -194,6 +194,18 @@ func main() {
fmt.Printf("---> %+v\n", details)
fmt.Println()

// BOARDS ATTACH
fmt.Println("=== calling BoardAttach(serial:///dev/ttyACM0)")
_, err = client.BoardAttach(context.Background(), &rpc.BoardAttachReq{
Instance: instance,
BoardURI: "serial:///dev/ttyACM0",
SketchPath: "/home/riccardo/Arduino/MyFirstSketch",
})
if err != nil {
fmt.Printf("attach error : %s\n", err)
os.Exit(1)
}

// COMPILE
fmt.Println("=== calling Compile(arduino:samd:mkr1000, VERBOSE, " + os.Args[2] + ")")
compRespStream, err := client.Compile(context.Background(), &rpc.CompileReq{
Expand Down Expand Up @@ -265,12 +277,12 @@ func main() {
}

// PLATFORM UNINSTALL
fmt.Println("=== calling PlatformUninstall(arduino:[email protected].21)")
fmt.Println("=== calling PlatformUninstall(arduino:[email protected].19)")
uninstallRespStream, err := client.PlatformUninstall(context.Background(), &rpc.PlatformUninstallReq{
Instance: instance,
PlatformPackage: "arduino",
Architecture: "samd",
Version: "1.6.21",
Version: "1.6.19",
})
if err != nil {
fmt.Printf("Uninstall error: %s\n", err)
Expand Down
4 changes: 4 additions & 0 deletions daemon/daemon.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ func (s *ArduinoCoreServerImpl) BoardDetails(ctx context.Context, req *rpc.Board
return board.BoardDetails(ctx, req)
}

func (s *ArduinoCoreServerImpl) BoardAttach(ctx context.Context, req *rpc.BoardAttachReq) (*rpc.BoardAttachResp, error) {
return board.BoardAttach(ctx, req)
}

func (s *ArduinoCoreServerImpl) Destroy(ctx context.Context, req *rpc.DestroyReq) (*rpc.DestroyResp, error) {
return commands.Destroy(ctx, req)
}
Expand Down
Loading

0 comments on commit 6bb9425

Please sign in to comment.