jpmens/homie-ota

Auto detection of firmware name and version

Closed this issue · 6 comments

It would be useful to be able to detect the firmware name and version when uploading a firmware, instead of having to put the information manually.

This would require some changes to the sketches to be compatible, here is a POC:

sketch.ino

#include <Homie.h>

#define FW_NAME "test-firmware"
#define FW_VERSION "1.2.3"

#define FLAGGED_FW_NAME "\xbf\x84\xe4\x13\x54" FW_NAME "\x93\x44\x6b\xa7\x75"
#define FLAGGED_FW_VERSION "\x6a\x3f\x3e\x0e\xe1" FW_VERSION "\xb0\x30\x48\xd4\x1a"

void setup() {
  Homie.setFirmware(FLAGGED_FW_NAME, FLAGGED_FW_VERSION);
  Homie.setup();
}

void loop() {
  Homie.loop();
}

parser.py

import re

regex_name = re.compile(b"\xbf\x84\xe4\x13\x54(.+)\x93\x44\x6b\xa7\x75")
regex_version = re.compile(b"\x6a\x3f\x3e\x0e\xe1(.+)\xb0\x30\x48\xd4\x1a")
firmware_file = open("./sketch.ino.nodemcu.bin", "rb")
firmware_binary = firmware_file.read()
firmware_file.close()

regex_name_result = regex_name.search(firmware_binary)
regex_version_result = regex_version.search(firmware_binary)

if not regex_name_result or not regex_version_result:
  print("Not a valid firmware")
  exit(1)

print("Name: " + regex_name_result.group(1))
print("Version: " + regex_version_result.group(1))

This would be a valuable addition;

Great project, by the way! 😄

Brilliant idea; I was hoping to be able to do something like that!

Works a treat: Firmware from ed-relay.ino.d1_mini.bin uploaded as firmwares/dual-relay/dual-relay-1.0.2.bin

We're not quite done here ...

jmbp-2709

@marvinroger do you have any bright ideas on how to embed the magic name / version? Creating two

static unsigned char _magic_fwname[] = FLAGGED_FW_NAME;
static unsigned char _magic_fwversion[] = FLAGGED_FW_VERSION;

isn't enough, because the compiler optimizes those out, and this is incredibly ugly:

void setup() {
  _magic_fwname[0] = '\xbf';
  _magic_fwversion[0] = '\x6a';

Other than having you embed that somewhere in Homie proper, I can't really think of how to do this cleanly, i.e. without having $fwname and $fwversion as shown in the previous screenshot.

Whoops, obviously it would not work! The following works fine for me:

#include <Homie.h>

#define FW_NAME "test-firmware"
#define FW_VERSION "1.2.3"

/* Magic sequence for Autodetectable Binary Upload */
#define _MAGIC_FW1 "\xbf\x84\xe4\x13\x54" FW_NAME "\x93\x44\x6b\xa7\x75"
const char* __MAGIC_FW1 = _MAGIC_FW1;
#define _MAGIC_FW2 "\x6a\x3f\x3e\x0e\xe1" FW_VERSION "\xb0\x30\x48\xd4\x1a"
const char* __MAGIC_FW2 = _MAGIC_FW2;
/* End of magic sequence for Autodetectable Binary Upload */

void setup() {
  Homie.setFirmware(FW_NAME, FW_VERSION);
  Homie.setup();
}

void loop() {
  Homie.loop();
}

Works, thanks.