Rebase private OTA libs on 2.7
This commit is contained in:
		
							
								
								
									
										14
									
								
								libs/ota-http-client/LICENSE
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								libs/ota-http-client/LICENSE
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,14 @@
 | 
			
		||||
Copyright (c) 2018 Cesanta Software Limited
 | 
			
		||||
All rights reserved
 | 
			
		||||
 | 
			
		||||
Licensed under the Apache License, Version 2.0 (the ""License"");
 | 
			
		||||
you may not use this file except in compliance with the License.
 | 
			
		||||
You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
    http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
distributed under the License is distributed on an ""AS IS"" BASIS,
 | 
			
		||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
See the License for the specific language governing permissions and
 | 
			
		||||
limitations under the License.
 | 
			
		||||
							
								
								
									
										26
									
								
								libs/ota-http-client/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								libs/ota-http-client/README.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,26 @@
 | 
			
		||||
# Implementation of Mongoose OS OTA HTTP client
 | 
			
		||||
 | 
			
		||||
This library adds a device configuration section called `update`, where
 | 
			
		||||
a device could be configured to poll a specified HTTP URL for a new
 | 
			
		||||
app firmware.
 | 
			
		||||
 | 
			
		||||
Also, this library adds a C API to fetch a new firmware from the given
 | 
			
		||||
URL and update programmatically.
 | 
			
		||||
 | 
			
		||||
## Configuration section
 | 
			
		||||
 | 
			
		||||
The library adds the following object to the device configuration:
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
```javascript
 | 
			
		||||
  "update": {
 | 
			
		||||
    "commit_timeout": 0,        // OTA commit timeout
 | 
			
		||||
    "url": "",                  // HTTP URL to poll
 | 
			
		||||
    "interval": 0,              // Polling interval
 | 
			
		||||
    "ssl_ca_file": "ca.pem",    // TLS CA cert file
 | 
			
		||||
    "ssl_client_cert_file": "", // TLS cert file
 | 
			
		||||
    "ssl_server_name": "",      // TLS server name
 | 
			
		||||
    "enable_post": true
 | 
			
		||||
  }
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
@@ -1,8 +1,18 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2014-2016 Cesanta Software Limited
 | 
			
		||||
 * Copyright (c) 2014-2018 Cesanta Software Limited
 | 
			
		||||
 * All rights reserved
 | 
			
		||||
 *
 | 
			
		||||
 * An updater implementation that fetches FW from the given URL.
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the ""License"");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an ""AS IS"" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef CS_MOS_LIBS_OTA_HTTP_CLIENT_SRC_MGOS_OTA_HTTP_CLIENT_H_
 | 
			
		||||
@@ -16,13 +26,9 @@
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif /* __cplusplus */
 | 
			
		||||
 | 
			
		||||
#if MGOS_ENABLE_UPDATER
 | 
			
		||||
bool mgos_ota_http_client_init(void);
 | 
			
		||||
 | 
			
		||||
/* Start OTA update by pulling the firmware from the given URL. */
 | 
			
		||||
void mgos_ota_http_start(struct update_context *ctx, const char *url);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif /* __cplusplus */
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										6
									
								
								libs/ota-http-client/mjs_fs/api_ota.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								libs/ota-http-client/mjs_fs/api_ota.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
			
		||||
let OTA = {
 | 
			
		||||
  // ## **`OTA.evdataOtaStatusMsg(evdata)`**
 | 
			
		||||
  // Getter function for the `evdata` given to the event callback for the event
 | 
			
		||||
  // `Event.OTA_STATUS`, see `Event.addHandler()` in `api_events.js`.
 | 
			
		||||
  evdataOtaStatusMsg: ffi('char *mgos_ota_status_get_msg(void *)'),
 | 
			
		||||
};
 | 
			
		||||
@@ -1,13 +1,17 @@
 | 
			
		||||
author: mongoose-os
 | 
			
		||||
description: Implements Mongoose OS OTA HTTP client
 | 
			
		||||
type: lib
 | 
			
		||||
version: 1.18
 | 
			
		||||
version: 1.0
 | 
			
		||||
 | 
			
		||||
sources:
 | 
			
		||||
  - src
 | 
			
		||||
 | 
			
		||||
includes:
 | 
			
		||||
  - include
 | 
			
		||||
 | 
			
		||||
libs:
 | 
			
		||||
  - origin: https://github.com/mongoose-os-libs/ota-common
 | 
			
		||||
 | 
			
		||||
config_schema:
 | 
			
		||||
  - ["update.url", "s", {title : "Fetch updates form here"}]
 | 
			
		||||
  - ["update.interval", "i", {title : "Check for updates this often"}]
 | 
			
		||||
@@ -21,8 +25,7 @@ tags:
 | 
			
		||||
  - c
 | 
			
		||||
  - ota
 | 
			
		||||
  - http
 | 
			
		||||
 | 
			
		||||
build_vars:
 | 
			
		||||
  MGOS_ENABLE_UPDATER: 1
 | 
			
		||||
  - rpc
 | 
			
		||||
  - docs:net:OTA via HTTP GET
 | 
			
		||||
 | 
			
		||||
manifest_version: 2017-09-29
 | 
			
		||||
 
 | 
			
		||||
@@ -1,140 +1,182 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2014-2016 Cesanta Software Limited
 | 
			
		||||
 * Copyright (c) 2014-2018 Cesanta Software Limited
 | 
			
		||||
 * All rights reserved
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the ""License"");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an ""AS IS"" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "mgos_ota_http_client.h"
 | 
			
		||||
 | 
			
		||||
#include "common/cs_dbg.h"
 | 
			
		||||
#include "mgos_event.h"
 | 
			
		||||
#include "mgos_hal.h"
 | 
			
		||||
#include "mgos_mongoose.h"
 | 
			
		||||
#include "mgos_config.h"
 | 
			
		||||
#include "mgos_ro_vars.h"
 | 
			
		||||
#include "mgos_sys_config.h"
 | 
			
		||||
#include "mgos_timers.h"
 | 
			
		||||
#include "mgos_utils.h"
 | 
			
		||||
 | 
			
		||||
#if MGOS_ENABLE_UPDATER
 | 
			
		||||
static void mgos_ota_http_start_internal(struct update_context *ctx,
 | 
			
		||||
                                         const char *url, bool restrict_url);
 | 
			
		||||
 | 
			
		||||
static void fw_download_handler(struct mg_connection *c, int ev, void *p,
 | 
			
		||||
                                void *user_data) {
 | 
			
		||||
  struct mbuf *          io  = &c->recv_mbuf;
 | 
			
		||||
  struct update_context *ctx = (struct update_context *)user_data;
 | 
			
		||||
  int            res         = 0;
 | 
			
		||||
  struct mbuf *io = &c->recv_mbuf;
 | 
			
		||||
  struct update_context *ctx = (struct update_context *) user_data;
 | 
			
		||||
  int res = 0;
 | 
			
		||||
  struct mg_str *loc;
 | 
			
		||||
 | 
			
		||||
  (void)p;
 | 
			
		||||
  (void) p;
 | 
			
		||||
 | 
			
		||||
  switch (ev) {
 | 
			
		||||
  case MG_EV_CONNECT: {
 | 
			
		||||
    int result = *((int *)p);
 | 
			
		||||
    if (result != 0) {
 | 
			
		||||
      LOG(LL_ERROR, ("connect error: %d", result));
 | 
			
		||||
    }
 | 
			
		||||
    break;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  case MG_EV_RECV: {
 | 
			
		||||
    if (ctx->file_size == 0) {
 | 
			
		||||
      LOG(LL_DEBUG, ("Looking for HTTP header"));
 | 
			
		||||
      struct http_message hm;
 | 
			
		||||
      int parsed = mg_parse_http(io->buf, io->len, &hm, 0);
 | 
			
		||||
      if (parsed <= 0) {
 | 
			
		||||
        return;
 | 
			
		||||
    case MG_EV_CONNECT: {
 | 
			
		||||
      int result = *((int *) p);
 | 
			
		||||
      if (result != 0) {
 | 
			
		||||
        LOG(LL_ERROR, ("Connect error: %d", result));
 | 
			
		||||
        ctx->status_msg = "Failed to connect";
 | 
			
		||||
        ctx->result = -10;
 | 
			
		||||
      }
 | 
			
		||||
      if (hm.resp_code != 200) {
 | 
			
		||||
        if (hm.resp_code == 304) {
 | 
			
		||||
          ctx->result      = 1;
 | 
			
		||||
          ctx->need_reboot = false;
 | 
			
		||||
          ctx->status_msg  = "Not Modified";
 | 
			
		||||
          updater_finish(ctx);
 | 
			
		||||
        } else if ((hm.resp_code == 301 || hm.resp_code == 302) &&
 | 
			
		||||
                   (loc = mg_get_http_header(&hm, "Location")) != NULL) {
 | 
			
		||||
          /* NUL-terminate the URL. Every header must be followed by \r\n,
 | 
			
		||||
           * so there is deifnitely space there. */
 | 
			
		||||
          ((char *)loc->p)[loc->len] = '\0';
 | 
			
		||||
 | 
			
		||||
          /* We were told to look elsewhere. Detach update context from this
 | 
			
		||||
          * connection so that it doesn't get finalized when it's closed. */
 | 
			
		||||
          mgos_ota_http_start(ctx, loc->p);
 | 
			
		||||
          c->user_data = NULL;
 | 
			
		||||
        } else {
 | 
			
		||||
          ctx->result      = -hm.resp_code;
 | 
			
		||||
          ctx->need_reboot = false;
 | 
			
		||||
          ctx->status_msg  = "Invalid HTTP response code";
 | 
			
		||||
          updater_finish(ctx);
 | 
			
		||||
        }
 | 
			
		||||
        c->flags |= MG_F_CLOSE_IMMEDIATELY;
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
      if (hm.body.len != 0) {
 | 
			
		||||
        LOG(LL_DEBUG, ("HTTP header: file size: %d", (int)hm.body.len));
 | 
			
		||||
        if (hm.body.len == (size_t) ~0) {
 | 
			
		||||
          LOG(LL_ERROR, ("Invalid content-length, perhaps chunked-encoding"));
 | 
			
		||||
          ctx->status_msg =
 | 
			
		||||
            "Invalid content-length, perhaps chunked-encoding";
 | 
			
		||||
          c->flags |= MG_F_CLOSE_IMMEDIATELY;
 | 
			
		||||
          break;
 | 
			
		||||
        } else {
 | 
			
		||||
          ctx->file_size = hm.body.len;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        mbuf_remove(io, parsed);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (io->len != 0) {
 | 
			
		||||
      res = updater_process(ctx, io->buf, io->len);
 | 
			
		||||
      mbuf_remove(io, io->len);
 | 
			
		||||
 | 
			
		||||
      if (res == 0) {
 | 
			
		||||
        if (is_write_finished(ctx)) {
 | 
			
		||||
          res = updater_finalize(ctx);
 | 
			
		||||
        }
 | 
			
		||||
        if (res == 0) {
 | 
			
		||||
          /* Need more data, everything is OK */
 | 
			
		||||
          break;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (res < 0) {
 | 
			
		||||
        /* Error */
 | 
			
		||||
        LOG(LL_ERROR, ("Update error: %d %s", ctx->result, ctx->status_msg));
 | 
			
		||||
      }
 | 
			
		||||
      c->flags |= MG_F_CLOSE_IMMEDIATELY;
 | 
			
		||||
    }
 | 
			
		||||
    break;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  case MG_EV_CLOSE: {
 | 
			
		||||
    if (ctx == NULL) {
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
    case MG_EV_RECV: {
 | 
			
		||||
      if (ctx->zip_file_size == 0) {
 | 
			
		||||
        LOG(LL_DEBUG, ("Looking for HTTP header"));
 | 
			
		||||
        struct http_message hm;
 | 
			
		||||
        int parsed = mg_parse_http(io->buf, io->len, &hm, 0);
 | 
			
		||||
        if (parsed <= 0) {
 | 
			
		||||
          return;
 | 
			
		||||
        }
 | 
			
		||||
        if (hm.resp_code != 200) {
 | 
			
		||||
          if (hm.resp_code == 304) {
 | 
			
		||||
            ctx->result = 1;
 | 
			
		||||
            ctx->need_reboot = false;
 | 
			
		||||
            ctx->status_msg = "Not Modified";
 | 
			
		||||
            updater_finish(ctx);
 | 
			
		||||
          } else if ((hm.resp_code == 301 || hm.resp_code == 302) &&
 | 
			
		||||
                     (loc = mg_get_http_header(&hm, "Location")) != NULL) {
 | 
			
		||||
            /* NUL-terminate the URL. Every header must be followed by \r\n,
 | 
			
		||||
             * so there is deifnitely space there. */
 | 
			
		||||
            ((char *) loc->p)[loc->len] = '\0';
 | 
			
		||||
            /* We were told to look elsewhere. Detach update context from this
 | 
			
		||||
             * connection so that it doesn't get finalized when it's closed. */
 | 
			
		||||
            LOG(LL_INFO, ("Got redirect: [%s]", loc->p));
 | 
			
		||||
            /* Do not restrict redirected URLs, cause Github redirects */
 | 
			
		||||
            mgos_ota_http_start_internal(ctx, loc->p, false);
 | 
			
		||||
            c->user_data = NULL;
 | 
			
		||||
          } else {
 | 
			
		||||
            ctx->result = -hm.resp_code;
 | 
			
		||||
            ctx->need_reboot = false;
 | 
			
		||||
            ctx->status_msg = "Invalid HTTP response code";
 | 
			
		||||
            LOG(LL_ERROR, ("%s: %d", ctx->status_msg, hm.resp_code));
 | 
			
		||||
            updater_finish(ctx);
 | 
			
		||||
          }
 | 
			
		||||
          c->flags |= MG_F_CLOSE_IMMEDIATELY;
 | 
			
		||||
          return;
 | 
			
		||||
        }
 | 
			
		||||
        if (hm.resp_code == 200 && hm.body.len != 0) {
 | 
			
		||||
          LOG(LL_DEBUG, ("HTTP header: file size: %d", (int) hm.body.len));
 | 
			
		||||
          if (hm.body.len == (size_t) ~0) {
 | 
			
		||||
            ctx->status_msg =
 | 
			
		||||
                "Invalid content-length, perhaps chunked-encoding";
 | 
			
		||||
            LOG(LL_ERROR, (ctx->status_msg));
 | 
			
		||||
            c->flags |= MG_F_CLOSE_IMMEDIATELY;
 | 
			
		||||
            break;
 | 
			
		||||
          } else {
 | 
			
		||||
            ctx->zip_file_size = hm.body.len;
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
    if (is_write_finished(ctx)) {
 | 
			
		||||
      updater_finalize(ctx);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!is_update_finished(ctx)) {
 | 
			
		||||
      /* Update failed or connection was terminated by server */
 | 
			
		||||
      if (ctx->status_msg == NULL) {
 | 
			
		||||
        ctx->status_msg = "Update failed";
 | 
			
		||||
          mbuf_remove(io, parsed);
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      ctx->result = -1;
 | 
			
		||||
    } else if (is_reboot_required(ctx)) {
 | 
			
		||||
      LOG(LL_INFO, ("Rebooting device"));
 | 
			
		||||
      mgos_system_restart_after(100);
 | 
			
		||||
 | 
			
		||||
      if (io->len != 0) {
 | 
			
		||||
        res = updater_process(ctx, io->buf, io->len);
 | 
			
		||||
        mbuf_remove(io, io->len);
 | 
			
		||||
 | 
			
		||||
        if (res == 0) {
 | 
			
		||||
          if (is_write_finished(ctx)) res = updater_finalize(ctx);
 | 
			
		||||
          if (res == 0) {
 | 
			
		||||
            /* Need more data, everything is OK */
 | 
			
		||||
            break;
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (res < 0) {
 | 
			
		||||
          /* Error */
 | 
			
		||||
          LOG(LL_ERROR, ("Update error: %d %s", ctx->result, ctx->status_msg));
 | 
			
		||||
        }
 | 
			
		||||
        c->flags |= MG_F_CLOSE_IMMEDIATELY;
 | 
			
		||||
      }
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
    case MG_EV_CLOSE: {
 | 
			
		||||
      if (ctx == NULL) break;
 | 
			
		||||
 | 
			
		||||
      if (is_write_finished(ctx)) updater_finalize(ctx);
 | 
			
		||||
 | 
			
		||||
      if (!is_update_finished(ctx)) {
 | 
			
		||||
        /* Update failed or connection was terminated by server */
 | 
			
		||||
        if (ctx->status_msg == NULL) ctx->status_msg = "Update failed";
 | 
			
		||||
        ctx->result = -5;
 | 
			
		||||
      } else if (is_reboot_required(ctx)) {
 | 
			
		||||
        LOG(LL_INFO, ("OTA finished, rebooting device"));
 | 
			
		||||
        /* Give it 3 seconds to drain any possible pending RPC calls */
 | 
			
		||||
        mgos_system_restart_after(3000);
 | 
			
		||||
      }
 | 
			
		||||
      updater_finish(ctx);
 | 
			
		||||
      updater_context_free(ctx);
 | 
			
		||||
      c->user_data = NULL;
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
    updater_finish(ctx);
 | 
			
		||||
    updater_context_free(ctx);
 | 
			
		||||
    c->user_data = NULL;
 | 
			
		||||
    break;
 | 
			
		||||
  }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void mgos_ota_http_start(struct update_context *ctx, const char *url) {
 | 
			
		||||
  LOG(LL_INFO, ("Update URL: %s, ct: %d, isv? %d", url,
 | 
			
		||||
                ctx->fctx.commit_timeout, ctx->ignore_same_version));
 | 
			
		||||
  mgos_ota_http_start_internal(ctx, url, true);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void mgos_ota_http_start_internal(struct update_context *ctx,
 | 
			
		||||
                                         const char *url, bool restrict_url) {
 | 
			
		||||
  LOG(LL_INFO,
 | 
			
		||||
      ("Update URL: %s, ct: %d, isv? %d %d", url, ctx->fctx.commit_timeout,
 | 
			
		||||
       ctx->ignore_same_version, restrict_url));
 | 
			
		||||
 | 
			
		||||
#if defined(MGOS_FREE_BUILD)
 | 
			
		||||
  if (restrict_url) {
 | 
			
		||||
    const char *allowed_url_prefixes[] = {
 | 
			
		||||
        "https://github.com/mongoose-os-apps/", "https://mongoose-os.com/",
 | 
			
		||||
        "http://mongoose-os.com/", "https://dash.mongoose-os.com/",
 | 
			
		||||
        "http://dash.mongoose-os.com/", NULL,
 | 
			
		||||
    };
 | 
			
		||||
    int i;
 | 
			
		||||
    for (i = 0; allowed_url_prefixes[i] != NULL; i++) {
 | 
			
		||||
      const char *s = allowed_url_prefixes[i];
 | 
			
		||||
      if (strncmp(s, url, strlen(s)) == 0) break;
 | 
			
		||||
    }
 | 
			
		||||
    if (allowed_url_prefixes[i] == NULL) {
 | 
			
		||||
      ctx->result = -10;
 | 
			
		||||
      ctx->need_reboot = false;
 | 
			
		||||
      ctx->status_msg =
 | 
			
		||||
          "Free version of OTA library can only perform OTA from "
 | 
			
		||||
          "github.com/mongoose-os-apps/. For  "
 | 
			
		||||
          "commercial version, please contact "
 | 
			
		||||
          "https://mongoose-os.com/contact.html";
 | 
			
		||||
      LOG(LL_ERROR, ("%s", ctx->status_msg));
 | 
			
		||||
      updater_finish(ctx);
 | 
			
		||||
      updater_context_free(ctx);
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  struct mg_connect_opts opts;
 | 
			
		||||
  memset(&opts, 0, sizeof(opts));
 | 
			
		||||
@@ -142,35 +184,34 @@ void mgos_ota_http_start(struct update_context *ctx, const char *url) {
 | 
			
		||||
#if MG_ENABLE_SSL
 | 
			
		||||
  if (strlen(url) > 8 && strncmp(url, "https://", 8) == 0) {
 | 
			
		||||
    opts.ssl_server_name = mgos_sys_config_get_update_ssl_server_name();
 | 
			
		||||
    opts.ssl_ca_cert     = mgos_sys_config_get_update_ssl_ca_file();
 | 
			
		||||
    opts.ssl_cert        = mgos_sys_config_get_update_ssl_client_cert_file();
 | 
			
		||||
    opts.ssl_ca_cert = mgos_sys_config_get_update_ssl_ca_file();
 | 
			
		||||
    opts.ssl_cert = mgos_sys_config_get_update_ssl_client_cert_file();
 | 
			
		||||
  }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  char  ehb[150];
 | 
			
		||||
  char ehb[150];
 | 
			
		||||
  char *extra_headers = ehb;
 | 
			
		||||
  mg_asprintf(&extra_headers, sizeof(ehb),
 | 
			
		||||
              "X-MGOS-Device-ID: %s %s\r\n"
 | 
			
		||||
              "X-MGOS-FW-Version: %s %s %s\r\n",
 | 
			
		||||
              (mgos_sys_config_get_device_id() ? mgos_sys_config_get_device_id() : "-"),
 | 
			
		||||
              mgos_sys_ro_vars_get_mac_address(),
 | 
			
		||||
              mgos_sys_ro_vars_get_arch(),
 | 
			
		||||
              mgos_sys_ro_vars_get_fw_version(),
 | 
			
		||||
              mgos_sys_ro_vars_get_fw_id());
 | 
			
		||||
  mg_asprintf(
 | 
			
		||||
      &extra_headers, sizeof(ehb),
 | 
			
		||||
      "Connection: close\r\n"
 | 
			
		||||
      "X-MGOS-Device-ID: %s %s\r\n"
 | 
			
		||||
      "X-MGOS-FW-Version: %s %s %s\r\n",
 | 
			
		||||
      (mgos_sys_config_get_device_id() ? mgos_sys_config_get_device_id() : "-"),
 | 
			
		||||
      mgos_sys_ro_vars_get_mac_address(), mgos_sys_ro_vars_get_arch(),
 | 
			
		||||
      mgos_sys_ro_vars_get_fw_version(), mgos_sys_ro_vars_get_fw_id());
 | 
			
		||||
 | 
			
		||||
  struct mg_connection *c = mg_connect_http_opt(
 | 
			
		||||
    mgos_get_mgr(), fw_download_handler, ctx, opts, url, extra_headers, NULL);
 | 
			
		||||
      mgos_get_mgr(), fw_download_handler, ctx, opts, url, extra_headers, NULL);
 | 
			
		||||
 | 
			
		||||
  if (extra_headers != ehb) {
 | 
			
		||||
    free(extra_headers);
 | 
			
		||||
  }
 | 
			
		||||
  if (extra_headers != ehb) free(extra_headers);
 | 
			
		||||
 | 
			
		||||
  if (c == NULL) {
 | 
			
		||||
    LOG(LL_ERROR, ("Failed to connect to %s", url));
 | 
			
		||||
    ctx->result      = -10;
 | 
			
		||||
    ctx->result = -11;
 | 
			
		||||
    ctx->need_reboot = false;
 | 
			
		||||
    ctx->status_msg  = "Failed to connect";
 | 
			
		||||
    ctx->status_msg = "Failed to connect";
 | 
			
		||||
    updater_finish(ctx);
 | 
			
		||||
    updater_context_free(ctx);
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -178,32 +219,42 @@ void mgos_ota_http_start(struct update_context *ctx, const char *url) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void mgos_ota_timer_cb(void *arg) {
 | 
			
		||||
  const struct mgos_config_update *mcu = mgos_sys_config_get_update();
 | 
			
		||||
 | 
			
		||||
  if (mcu->url == NULL) {
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
  struct update_context *ctx = updater_context_create();
 | 
			
		||||
  if (ctx == NULL) {
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
  if (mgos_sys_config_get_update_url() == NULL) return;
 | 
			
		||||
  struct update_context *ctx = updater_context_create(0);
 | 
			
		||||
  if (ctx == NULL) return;
 | 
			
		||||
  ctx->ignore_same_version = true;
 | 
			
		||||
  ctx->fctx.commit_timeout = mcu->commit_timeout;
 | 
			
		||||
  mgos_ota_http_start(ctx, mcu->url);
 | 
			
		||||
  ctx->fctx.commit_timeout = mgos_sys_config_get_update_commit_timeout();
 | 
			
		||||
  mgos_ota_http_start(ctx, mgos_sys_config_get_update_url());
 | 
			
		||||
 | 
			
		||||
  (void)arg;
 | 
			
		||||
  (void) arg;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void ota_request_cb(int ev, void *ev_data, void *userdata) {
 | 
			
		||||
  struct ota_request_param *p = (struct ota_request_param *) ev_data;
 | 
			
		||||
  mgos_ota_http_start(p->updater_context, p->location);
 | 
			
		||||
  (void) ev;
 | 
			
		||||
  (void) userdata;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool mgos_ota_http_client_init(void) {
 | 
			
		||||
  const struct mgos_config_update *mcu = mgos_sys_config_get_update();
 | 
			
		||||
 | 
			
		||||
  if (mcu->url != NULL && mcu->interval > 0) {
 | 
			
		||||
    LOG(LL_INFO,
 | 
			
		||||
        ("Updates from %s, every %d seconds", mcu->url, mcu->interval));
 | 
			
		||||
    mgos_set_timer(mcu->interval * 1000, true /* repeat */, mgos_ota_timer_cb,
 | 
			
		||||
                   mcu->url);
 | 
			
		||||
  const char *url = mgos_sys_config_get_update_url();
 | 
			
		||||
  int interval = mgos_sys_config_get_update_interval();
 | 
			
		||||
  if (url != NULL && interval > 0) {
 | 
			
		||||
    LOG(LL_INFO, ("Updates from %s, every %d seconds", url, interval));
 | 
			
		||||
    mgos_set_timer(interval * 1000, MGOS_TIMER_REPEAT, mgos_ota_timer_cb,
 | 
			
		||||
                   (void *) url);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const char *pref = mgos_sys_config_get_sys_pref_ota_lib();
 | 
			
		||||
  const char *me = "ota-http-client";
 | 
			
		||||
  bool ota_handler_set = false;
 | 
			
		||||
  if ((pref == NULL || strcmp(pref, me) == 0) &&
 | 
			
		||||
      mgos_event_register_base(MGOS_EVENT_OTA_REQUEST, me)) {
 | 
			
		||||
    mgos_event_add_handler(MGOS_EVENT_OTA_REQUEST, ota_request_cb, NULL);
 | 
			
		||||
    ota_handler_set = true;
 | 
			
		||||
  }
 | 
			
		||||
  LOG(LL_INFO, ("Init done, ota_lib=%s, ota handler %d",
 | 
			
		||||
                pref == NULL ? "(null)" : pref, ota_handler_set));
 | 
			
		||||
  (void) ota_handler_set;
 | 
			
		||||
  return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif /* MGOS_ENABLE_UPDATER */
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user