Functionality of OTA.Update

I am using the folllowing RPC loopback call, which successfully updates firmware:

RPC.call (RPC.LOCAL, ‘OTA.Update’, {url:“192.168.1.9/fw/fw.zip”,ignore_same_version:true}, function (resp,ud){print(‘Response:’,JSON.stringify(resp));},null);

However, when the RPC is called when the version to be updated is the same as the currently operating version, the RPC issues a message indicating that the app will not be written, but still loads the file system, switches partitions and reboots.

The desired operation would be to ignore everything and do nothing if the firmware versions are the same. How can I achieve this functionality?

Thanks for your help as always,

JSW

1 Like

I don’t have an answer for you but I am very interested in the answer. If you find a solution please let us know.

Have you considered writing some code that queries your server to see what version is posted, and then downloading it or not based on that?

I eventually developed a scheme to do this function as follows:

I created a file with the contents "X.Y"and uploaded it to the remote http server, along with the new firmware upgrade file (fw.zip) I then wrote some code to download the revision info file and parse it into 2 integers.

As a part of the system config, I created new parameters in the config.schema of mos.yml which indicate the current firmware rev number (in this case, it’s 1.3). (By doing it this way, I must manage the update number continuously by updating the config.schema of each newly published firmware revision.)

  • [“frevmajor”, “i”, 1,{title: “Major Firmware Rev”}]
  • [“frevminor”, “i”, 3,{title: “Minor Firmware Rev”}]

Then, I use the build created APIs mgos_sys_config_get_frevmajor() and mgos_sys_config_get_frevminor() to retrieve the current version’s major and minor rev integers. Comparing these numbers with the web site retrieved number, I then call the loopback RPC OTA.Update if required.

More work than I hoped, but it works

JSW

I use another approach using the group event handler for MGOS_EVENT_OTA_BASE. When MGOS_EVENT_OTA_BEGIN is issued, I compare the current fw_id with the new one and if they are the same I abort the update.

static const char *ota_event_string(enum mgos_event_ota ev) {
  const char *str = "Unknown";
  switch (ev) {
    case MGOS_EVENT_OTA_BEGIN:
      str = "BEGIN";
      break;
    case MGOS_EVENT_OTA_STATUS:
      str = "STATUS";
      break;
    default:
      break;
  }
  return str;
}

static void ota_event_handler(int ev, void *evd, void *arg) {
  bool ignore_same_version = 0 != (int) arg;
  const char *event_string = ota_event_string((enum mgos_event_ota)ev);
  switch (ev) {
    case MGOS_EVENT_OTA_BEGIN: {
      struct mgos_ota_begin_arg *info = (struct mgos_ota_begin_arg *) evd;
      const char *local_build_id = mgos_sys_ro_vars_get_fw_id();
      bool is_same = strncmp(local_build_id, info->mi.build_id.p,
                             info->mi.build_id.len) == 0;
      const char *fmt = "Update %s, remote=%.*s, local=%s (is_same=%d)";
      LOG(LL_INFO, (fmt, event_string, (int) info->mi.build_id.len,
                    info->mi.build_id.p, local_build_id, is_same));
      if (is_same && ignore_same_version) {
        info->result = MGOS_UPD_ABORT;
      }
      break;
    }
    case MGOS_EVENT_OTA_STATUS: {
      const struct mgos_ota_status *status =
          (const struct mgos_ota_status *) evd;
      (void) status;
      break;
    }
  }
}
mgos_event_add_group_handler(MGOS_EVENT_OTA_BASE, ota_event_handler,
                               (void *) ignore_same_version);
1 Like