ota: pull update binary from http server, write it to sd card, and factory reset

This commit is contained in:
decentclock
2022-09-16 21:47:55 -04:00
parent f208a5af5e
commit 79fea3092d
6 changed files with 100 additions and 5 deletions

View File

@@ -1,13 +1,13 @@
[workspace]
members = [
"signer",
"parser",
"signer",
"tester",
]
exclude = [
"sphinx-key",
"persister",
"broker",
"persister",
"sphinx-key",
]

View File

@@ -106,7 +106,7 @@ impl Controller {
ControlResponse::AllowlistUpdated(na)
}
ControlMessage::Ota(params) => {
// ...
// same as above comments, actually done in core/events.rs
ControlResponse::OtaConfirm(params)
}
};

View File

@@ -25,7 +25,7 @@ esp-idf-sys = { version = "0.31.6", features = ["binstart"] }
sphinx-key-signer = { path = "../signer", optional = true }
sphinx-crypter = { git = "https://github.com/stakwork/sphinx-rs.git" }
embedded-svc = "0.22.1"
esp-idf-svc = "0.42.1"
esp-idf-svc = { version = "0.42.1", features = ["experimental", "alloc"] }
esp-idf-hal = "0.38.0"
embedded-hal = "=1.0.0-alpha.8"
anyhow = {version = "1", features = ["backtrace"]}

View File

@@ -1,4 +1,5 @@
use crate::conn::mqtt::QOS;
use crate::ota::update_sphinx_key;
use sphinx_key_signer::control::{Config, ControlMessage, ControlResponse, Controller, Policy};
use sphinx_key_signer::lightning_signer::bitcoin::Network;
@@ -116,6 +117,9 @@ pub fn make_event_loop(
rmp_serde::to_vec(&res).expect("could not publish control response");
mqtt.publish(topics::CONTROL_RETURN, QOS, false, &res_data)
.expect("could not publish control response");
if let ControlResponse::OtaConfirm(_) = res {
unsafe { esp_idf_sys::esp_restart() };
}
}
}
}
@@ -159,6 +163,15 @@ fn handle_control_response(
}
}
}
ControlMessage::Ota(params) => {
if let Err(e) = update_sphinx_key(params.version, params.url.clone()) {
log::error!("OTA update failed {:?}", e.to_string());
control_res =
ControlResponse::Error(format!("OTA update failed {:?}", e))
} else {
log::info!("OTA update completed, about to restart the glyph...");
}
}
_ => (),
};
Some(control_res)

View File

@@ -1,6 +1,7 @@
#![feature(once_cell)]
mod conn;
mod core;
mod ota;
mod periph;
use crate::core::control::{controller_from_seed, FlashPersister};

81
sphinx-key/src/ota.rs Normal file
View File

@@ -0,0 +1,81 @@
use anyhow::{anyhow, Result};
use embedded_svc::http::client::Client;
use embedded_svc::http::client::Request;
use embedded_svc::http::client::Response;
use embedded_svc::io::Read;
use embedded_svc::ota::Ota;
use esp_idf_svc::http::client::EspHttpClient;
use esp_idf_svc::http::client::EspHttpClientConfiguration;
use esp_idf_svc::http::client::FollowRedirectsPolicy::FollowNone;
use esp_idf_svc::ota::EspOta;
use log::{error, info};
use std::fs::{remove_file, File};
use std::io::BufWriter;
use std::io::Write;
const BUFFER_LEN: usize = 3072;
const UPDATE_BIN_PATH: &str = "/sdcard/update.bin";
fn factory_reset() -> Result<()> {
let mut ota = EspOta::new()?;
if ota.is_factory_reset_supported()? {
info!("Factory reset supported, attempting reset...");
ota.factory_reset()?;
Ok(())
} else {
error!("FACTORY RESET CURRENTLY NOT SUPPORTED!");
error!("Only wrote the update binary to the sdcard");
Err(anyhow!("Factory reset not supported"))
}
}
fn get_update(version: u64, mut url: String) -> Result<()> {
let configuration = EspHttpClientConfiguration {
buffer_size: Some(BUFFER_LEN),
buffer_size_tx: Some(BUFFER_LEN / 3),
follow_redirects_policy: FollowNone,
use_global_ca_store: true,
crt_bundle_attach: None,
};
let mut client = EspHttpClient::new(&configuration)?;
url.push_str(&version.to_string());
let mut response = client.get(&url)?.submit()?;
let mut reader = response.reader();
let _ = remove_file(UPDATE_BIN_PATH);
let file = File::create(UPDATE_BIN_PATH)?;
let mut writer = BufWriter::new(file);
let mut buf = [0_u8; BUFFER_LEN];
let mut read_tot: usize = 0;
let mut write_tot: usize = 0;
let mut i = 0;
loop {
let r = reader.read(&mut buf)?;
if r == 0 {
break;
}
let w = writer.write(&buf[..r])?;
read_tot += r;
write_tot += w;
i += 1;
if i % 20 == 0 {
info!("Cumulative bytes read: {}", read_tot);
info!("Cumulative bytes written: {}", write_tot);
}
}
info!("TOTAL read: {}", read_tot);
info!("TOTAL written: {}", write_tot);
Ok(())
}
pub fn update_sphinx_key(version: u64, url: String) -> Result<()> {
info!("Getting the update...");
info!("Version: {}", version.to_string());
info!("URL: {}", url);
get_update(version, url)?;
info!("Update written to sd card, performing factory reset");
factory_reset()?;
info!("Factory reset completed!");
Ok(())
}