Skip to content

Commit 0ceb632

Browse files
committed
Initial support for OTA binary encoding
1 parent 1d70049 commit 0ceb632

File tree

4 files changed

+140
-2
lines changed

4 files changed

+140
-2
lines changed

cli/ota/encode.go

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
// This file is part of arduino-cloud-cli.
2+
//
3+
// Copyright (C) 2021 ARDUINO SA (http://www.arduino.cc/)
4+
//
5+
// This program is free software: you can redistribute it and/or modify
6+
// it under the terms of the GNU Affero General Public License as published
7+
// by the Free Software Foundation, either version 3 of the License, or
8+
// (at your option) any later version.
9+
//
10+
// This program is distributed in the hope that it will be useful,
11+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
// GNU Affero General Public License for more details.
14+
//
15+
// You should have received a copy of the GNU Affero General Public License
16+
// along with this program. If not, see <https://www.gnu.org/licenses/>.
17+
18+
package ota
19+
20+
import (
21+
"context"
22+
"fmt"
23+
"os"
24+
25+
"github.com/arduino/arduino-cli/cli/errorcodes"
26+
"github.com/arduino/arduino-cli/cli/feedback"
27+
"github.com/arduino/arduino-cloud-cli/command/ota"
28+
"github.com/arduino/arduino-cloud-cli/config"
29+
"github.com/sirupsen/logrus"
30+
"github.com/spf13/cobra"
31+
)
32+
33+
type encodeBinaryFlags struct {
34+
deviceID string
35+
file string
36+
}
37+
38+
func initEncodeBinaryCommand() *cobra.Command {
39+
flags := &encodeBinaryFlags{}
40+
uploadCommand := &cobra.Command{
41+
Use: "encode",
42+
Short: "OTA firmware encode",
43+
Long: "encode binary firmware to make it compatible with OTA",
44+
Run: func(cmd *cobra.Command, args []string) {
45+
if err := runEncodeCommand(flags); err != nil {
46+
feedback.Errorf("Error during firmware encoding: %v", err)
47+
os.Exit(errorcodes.ErrGeneric)
48+
}
49+
},
50+
}
51+
uploadCommand.Flags().StringVarP(&flags.deviceID, "device-id", "d", "", "Device ID")
52+
uploadCommand.Flags().StringVarP(&flags.file, "file", "", "", "Binary file (.bin) to be encoded")
53+
uploadCommand.MarkFlagRequired("device-id")
54+
uploadCommand.MarkFlagRequired("file")
55+
return uploadCommand
56+
}
57+
58+
func runEncodeCommand(flags *encodeBinaryFlags) error {
59+
logrus.Infof("Encoding binary %s", flags.file)
60+
61+
cred, err := config.RetrieveCredentials()
62+
if err != nil {
63+
return fmt.Errorf("retrieving credentials: %w", err)
64+
}
65+
66+
params := &ota.EncodeParams{
67+
DeviceID: flags.deviceID,
68+
File: flags.file,
69+
}
70+
otafile, err := ota.Encode(context.TODO(), params, cred)
71+
if err != nil {
72+
return err
73+
}
74+
75+
logrus.Info("Encode successfully performed. OTA file: ", *otafile)
76+
return nil
77+
}

cli/ota/ota.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ func NewCommand() *cobra.Command {
3030

3131
otaCommand.AddCommand(initUploadCommand())
3232
otaCommand.AddCommand(initMassUploadCommand())
33+
otaCommand.AddCommand(initEncodeBinaryCommand())
3334

3435
return otaCommand
3536
}

command/ota/encode.go

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// This file is part of arduino-cloud-cli.
2+
//
3+
// Copyright (C) 2021 ARDUINO SA (http://www.arduino.cc/)
4+
//
5+
// This program is free software: you can redistribute it and/or modify
6+
// it under the terms of the GNU Affero General Public License as published
7+
// by the Free Software Foundation, either version 3 of the License, or
8+
// (at your option) any later version.
9+
//
10+
// This program is distributed in the hope that it will be useful,
11+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
// GNU Affero General Public License for more details.
14+
//
15+
// You should have received a copy of the GNU Affero General Public License
16+
// along with this program. If not, see <https://www.gnu.org/licenses/>.
17+
18+
package ota
19+
20+
import (
21+
"context"
22+
"fmt"
23+
"os"
24+
25+
"github.com/arduino/arduino-cloud-cli/config"
26+
"github.com/arduino/arduino-cloud-cli/internal/iot"
27+
)
28+
29+
type EncodeParams struct {
30+
DeviceID string
31+
File string
32+
}
33+
34+
// Encode command is used to encode a firmware OTA
35+
func Encode(ctx context.Context, params *EncodeParams, cred *config.Credentials) (*string, error) {
36+
iotClient, err := iot.NewClient(cred)
37+
if err != nil {
38+
return nil, err
39+
}
40+
41+
dev, err := iotClient.DeviceShow(ctx, params.DeviceID)
42+
if err != nil {
43+
return nil, err
44+
}
45+
46+
otaFile := fmt.Sprintf("%s.ota", params.File)
47+
_, err = os.Stat(otaFile)
48+
if err == nil {
49+
// file already exists, we need to delete it
50+
if err = os.Remove(otaFile); err != nil {
51+
return nil, fmt.Errorf("%s: %w", "cannot remove .ota file", err)
52+
}
53+
}
54+
55+
err = Generate(params.File, otaFile, dev.Fqbn)
56+
if err != nil {
57+
return nil, fmt.Errorf("%s: %w", "cannot generate .ota file", err)
58+
}
59+
60+
return &otaFile, nil
61+
}

command/ota/generate.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ package ota
2020
import (
2121
"errors"
2222
"fmt"
23-
"io/ioutil"
2423
"os"
2524
"strings"
2625

@@ -68,7 +67,7 @@ func Generate(binFile string, outFile string, fqbn string) error {
6867
magicNumberPart2 = productID
6968
}
7069

71-
data, err := ioutil.ReadFile(binFile)
70+
data, err := os.ReadFile(binFile)
7271
if err != nil {
7372
return err
7473
}

0 commit comments

Comments
 (0)