github.com/arduino/arduino-cloud-cli@v0.0.0-20240517070944-e7a449561083/command/ota/generate.go (about) 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 "errors" 22 "fmt" 23 "os" 24 "strings" 25 26 inota "github.com/arduino/arduino-cloud-cli/internal/ota" 27 ) 28 29 // Generate takes a .bin file and generates a .ota file. 30 func Generate(binFile string, outFile string, fqbn string) error { 31 32 // We are going to put a magic number in the ota .bin file, the fw will check the magic number once the binary is received 33 var magicNumberPart1, magicNumberPart2 string 34 35 // The ota update is available for Arduino boards and ESP32 boards 36 37 // Esp32 boards have a wide range of vid and pid, we don't map all of them 38 // If the fqbn is the one of an ESP32 board, we force a default magic number that matches the same default expected on the fw side 39 if !strings.HasPrefix(fqbn, "arduino:esp32") && strings.HasPrefix(fqbn, "esp32") { 40 magicNumberPart1 = inota.Esp32MagicNumberPart1 41 magicNumberPart2 = inota.Esp32MagicNumberPart2 42 } else { 43 //For Arduino Boards we use vendorId and productID to form the magic number 44 magicNumberPart1 = inota.ArduinoVendorID 45 productID, ok := inota.ArduinoFqbnToPID[fqbn] 46 if !ok { 47 return errors.New("fqbn not valid") 48 } 49 magicNumberPart2 = productID 50 } 51 52 data, err := os.ReadFile(binFile) 53 if err != nil { 54 return err 55 } 56 57 out, err := os.Create(outFile) 58 if err != nil { 59 return err 60 } 61 defer out.Close() 62 63 enc := inota.NewEncoder(out, magicNumberPart1, magicNumberPart2) 64 err = enc.Encode(data) 65 if err != nil { 66 return fmt.Errorf("failed to encode binary file: %w", err) 67 } 68 69 return nil 70 }