Skip to content

Configurable cors #34

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 12 commits into from
Closed
Prev Previous commit
Next Next commit
rework network programming and add ssh ability
  • Loading branch information
facchinm committed Oct 22, 2015
commit 391a2d3b5beffdc2673cae26fa585396c2545108
6 changes: 5 additions & 1 deletion conn.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,11 @@ func uploadHandler(c *gin.Context) {
c.String(http.StatusBadRequest, err.Error())
}

go spProgramRW(port, board, board_rewrite, path, commandline, extraInfo)
if board_rewrite != "" {
board = board_rewrite
}

go spProgramRW(port, board, path, commandline, extraInfo)
}
}

Expand Down
167 changes: 120 additions & 47 deletions programmer.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
log "github.com/Sirupsen/logrus"
"github.com/facchinm/go-serial"
"github.com/mattn/go-shellwords"
"github.com/sfreiberg/simplessh"
"io"
"mime/multipart"
"net/http"
Expand Down Expand Up @@ -40,11 +41,105 @@ type boardExtraInfo struct {
authdata basicAuthData
}

// Scp uploads sourceFile to remote machine like native scp console app.
func Scp(client *simplessh.Client, sourceFile, targetFile string) error {

session, err := client.SSHClient.NewSession()
if err != nil {
return err
}
defer session.Close()

src, srcErr := os.Open(sourceFile)

if srcErr != nil {
return srcErr
}

srcStat, statErr := src.Stat()

if statErr != nil {
return statErr
}

go func() {
w, _ := session.StdinPipe()

fmt.Fprintln(w, "C0644", srcStat.Size(), filepath.Base(targetFile))

if srcStat.Size() > 0 {
io.Copy(w, src)
fmt.Fprint(w, "\x00")
w.Close()
} else {
fmt.Fprint(w, "\x00")
w.Close()
}

}()

if err := session.Run("scp -t " + targetFile); err != nil {
return err
}

return nil
}

func spProgramSSHNetwork(portname string, boardname string, filePath string, commandline string, authdata basicAuthData) error {
log.Println("Starting network upload")
log.Println("Board Name: " + boardname)

if authdata.UserName == "" {
authdata.UserName = "root"
}

if authdata.Password == "" {
authdata.Password = "arduino"
}

ssh_client, err := simplessh.ConnectWithPassword(portname+":22", authdata.UserName, authdata.Password)
if err != nil {
log.Println("Error connecting via ssh")
return err
}
defer ssh_client.Close()

err = Scp(ssh_client, filePath, "/tmp/sketch"+filepath.Ext(filePath))
if err != nil {
log.Printf("Upload: %s\n", err)
return err
}

if commandline == "" {
// very special case for Yun (remove once AVR boards.txt is fixed)
commandline = "merge-sketch-with-bootloader.lua /tmp/sketch.hex && /usr/bin/run-avrdude /tmp/sketch.hex"
}

fmt.Println(commandline)

ssh_output, err := ssh_client.Exec(commandline)
if err == nil {
log.Printf("Flash: %s\n", ssh_output)
mapD := map[string]string{"ProgrammerStatus": "Busy", "Msg": string(ssh_output)}
mapB, _ := json.Marshal(mapD)
h.broadcastSys <- mapB
}
return err
}

func spProgramNetwork(portname string, boardname string, filePath string, authdata basicAuthData) error {

log.Println("Starting network upload")
log.Println("Board Name: " + boardname)

if authdata.UserName == "" {
authdata.UserName = "root"
}

if authdata.Password == "" {
authdata.Password = "arduino"
}

// Prepare a form that you will submit to that URL.
_url := "http://" + portname + "/data/upload_sketch_silent"
var b bytes.Buffer
Expand Down Expand Up @@ -109,23 +204,10 @@ func spProgramNetwork(portname string, boardname string, filePath string, authda
log.Errorf("bad status: %s", res.Status)
err = fmt.Errorf("bad status: %s", res.Status)
}

if err != nil {
log.Printf("Command finished with error: %v ", err)
mapD := map[string]string{"ProgrammerStatus": "Error", "Msg": "Could not program the board", "Output": "", "Err": "Could not program the board"}
mapB, _ := json.Marshal(mapD)
h.broadcastSys <- mapB
} else {
log.Printf("Finished without error. Good stuff.")
mapD := map[string]string{"ProgrammerStatus": "Done", "Flash": "Ok", "Output": ""}
mapB, _ := json.Marshal(mapD)
h.broadcastSys <- mapB
// analyze stdin
}
return err
}

func spProgramLocal(portname string, boardname string, filePath string, commandline string, extraInfo boardExtraInfo) {
func spProgramLocal(portname string, boardname string, filePath string, commandline string, extraInfo boardExtraInfo) error {

var err error
if extraInfo.use_1200bps_touch {
Expand All @@ -134,7 +216,7 @@ func spProgramLocal(portname string, boardname string, filePath string, commandl

if err != nil {
log.Println("Could not touch the port")
return
return err
}

log.Printf("Received commandline (unresolved):" + commandline)
Expand All @@ -155,15 +237,10 @@ func spProgramLocal(portname string, boardname string, filePath string, commandl
}

z, _ := shellwords.Parse(commandline)
spHandlerProgram(z[0], z[1:])
}

func spProgram(portname string, boardname string, filePath string, commandline string, extraInfo boardExtraInfo) {

spProgramRW(portname, boardname, "", filePath, commandline, extraInfo)
return spHandlerProgram(z[0], z[1:])
}

func spProgramRW(portname string, boardname string, boardname_rewrite string, filePath string, commandline string, extraInfo boardExtraInfo) {
func spProgramRW(portname string, boardname string, filePath string, commandline string, extraInfo boardExtraInfo) {
compiling = true

defer func() {
Expand All @@ -174,24 +251,32 @@ func spProgramRW(portname string, boardname string, boardname_rewrite string, fi
var err error

if extraInfo.networkPort {
if boardname_rewrite != "" {
err = spProgramNetwork(portname, boardname_rewrite, filePath, extraInfo.authdata)
} else {
err = spProgramNetwork(portname, boardname, filePath, extraInfo.authdata)
}
err = spProgramNetwork(portname, boardname, filePath, extraInfo.authdata)
if err != nil {
mapD := map[string]string{"ProgrammerStatus": "Error", "Msg": "Could not program the board", "Output": "", "Err": err.Error()}
mapB, _ := json.Marshal(mapD)
h.broadcastSys <- mapB
// no http method available, try ssh upload
err = spProgramSSHNetwork(portname, boardname, filePath, commandline, extraInfo.authdata)
}
} else {
spProgramLocal(portname, boardname, filePath, commandline, extraInfo)
err = spProgramLocal(portname, boardname, filePath, commandline, extraInfo)
}

if err != nil {
log.Printf("Command finished with error: %v", err)
mapD := map[string]string{"ProgrammerStatus": "Error", "Msg": "Could not program the board"}
mapB, _ := json.Marshal(mapD)
h.broadcastSys <- mapB
} else {
log.Printf("Finished without error. Good stuff")
mapD := map[string]string{"ProgrammerStatus": "Done", "Flash": "Ok"}
mapB, _ := json.Marshal(mapD)
h.broadcastSys <- mapB
// analyze stdin
}
}

var oscmd *exec.Cmd

func spHandlerProgram(flasher string, cmdString []string) {
func spHandlerProgram(flasher string, cmdString []string) error {

// if runtime.GOOS == "darwin" {
// sh, _ := exec.LookPath("sh")
Expand All @@ -218,12 +303,12 @@ func spHandlerProgram(flasher string, cmdString []string) {

stdout, err := oscmd.StdoutPipe()
if err != nil {
return
return err
}

stderr, err := oscmd.StderrPipe()
if err != nil {
return
return err
}

multi := io.MultiReader(stderr, stdout)
Expand Down Expand Up @@ -252,19 +337,7 @@ func spHandlerProgram(flasher string, cmdString []string) {

err = oscmd.Wait()

if err != nil {
log.Printf("Command finished with error: %v", err)
mapD := map[string]string{"ProgrammerStatus": "Error", "Msg": "Could not program the board"}
mapB, _ := json.Marshal(mapD)
h.broadcastSys <- mapB
} else {
log.Printf("Finished without error. Good stuff")
mapD := map[string]string{"ProgrammerStatus": "Done", "Flash": "Ok"}
mapB, _ := json.Marshal(mapD)
h.broadcastSys <- mapB
// analyze stdin

}
return err
}

func spHandlerProgramKill() {
Expand Down