Skip to content

Commit

Permalink
Initial support for OTA binary encoding
Browse files Browse the repository at this point in the history
  • Loading branch information
rjtokenring committed Feb 2, 2024
1 parent 1d70049 commit 0ceb632
Show file tree
Hide file tree
Showing 4 changed files with 140 additions and 2 deletions.
77 changes: 77 additions & 0 deletions cli/ota/encode.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
// This file is part of arduino-cloud-cli.
//
// Copyright (C) 2021 ARDUINO SA (http://www.arduino.cc/)
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.

package ota

import (
"context"
"fmt"
"os"

"github.com/arduino/arduino-cli/cli/errorcodes"
"github.com/arduino/arduino-cli/cli/feedback"
"github.com/arduino/arduino-cloud-cli/command/ota"
"github.com/arduino/arduino-cloud-cli/config"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
)

type encodeBinaryFlags struct {
deviceID string
file string
}

func initEncodeBinaryCommand() *cobra.Command {
flags := &encodeBinaryFlags{}
uploadCommand := &cobra.Command{
Use: "encode",
Short: "OTA firmware encode",
Long: "encode binary firmware to make it compatible with OTA",
Run: func(cmd *cobra.Command, args []string) {
if err := runEncodeCommand(flags); err != nil {
feedback.Errorf("Error during firmware encoding: %v", err)
os.Exit(errorcodes.ErrGeneric)
}
},
}
uploadCommand.Flags().StringVarP(&flags.deviceID, "device-id", "d", "", "Device ID")
uploadCommand.Flags().StringVarP(&flags.file, "file", "", "", "Binary file (.bin) to be encoded")
uploadCommand.MarkFlagRequired("device-id")
uploadCommand.MarkFlagRequired("file")
return uploadCommand
}

func runEncodeCommand(flags *encodeBinaryFlags) error {
logrus.Infof("Encoding binary %s", flags.file)

cred, err := config.RetrieveCredentials()
if err != nil {
return fmt.Errorf("retrieving credentials: %w", err)
}

params := &ota.EncodeParams{
DeviceID: flags.deviceID,
File: flags.file,
}
otafile, err := ota.Encode(context.TODO(), params, cred)
if err != nil {
return err
}

logrus.Info("Encode successfully performed. OTA file: ", *otafile)
return nil
}
1 change: 1 addition & 0 deletions cli/ota/ota.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ func NewCommand() *cobra.Command {

otaCommand.AddCommand(initUploadCommand())
otaCommand.AddCommand(initMassUploadCommand())
otaCommand.AddCommand(initEncodeBinaryCommand())

return otaCommand
}
61 changes: 61 additions & 0 deletions command/ota/encode.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// This file is part of arduino-cloud-cli.
//
// Copyright (C) 2021 ARDUINO SA (http://www.arduino.cc/)
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.

package ota

import (
"context"
"fmt"
"os"

"github.com/arduino/arduino-cloud-cli/config"
"github.com/arduino/arduino-cloud-cli/internal/iot"
)

type EncodeParams struct {
DeviceID string
File string
}

// Encode command is used to encode a firmware OTA
func Encode(ctx context.Context, params *EncodeParams, cred *config.Credentials) (*string, error) {
iotClient, err := iot.NewClient(cred)
if err != nil {
return nil, err
}

dev, err := iotClient.DeviceShow(ctx, params.DeviceID)
if err != nil {
return nil, err
}

otaFile := fmt.Sprintf("%s.ota", params.File)
_, err = os.Stat(otaFile)
if err == nil {
// file already exists, we need to delete it
if err = os.Remove(otaFile); err != nil {
return nil, fmt.Errorf("%s: %w", "cannot remove .ota file", err)
}
}

err = Generate(params.File, otaFile, dev.Fqbn)
if err != nil {
return nil, fmt.Errorf("%s: %w", "cannot generate .ota file", err)
}

return &otaFile, nil
}
3 changes: 1 addition & 2 deletions command/ota/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ package ota
import (
"errors"
"fmt"
"io/ioutil"
"os"
"strings"

Expand Down Expand Up @@ -68,7 +67,7 @@ func Generate(binFile string, outFile string, fqbn string) error {
magicNumberPart2 = productID
}

data, err := ioutil.ReadFile(binFile)
data, err := os.ReadFile(binFile)
if err != nil {
return err
}
Expand Down

0 comments on commit 0ceb632

Please sign in to comment.