mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-07-20 16:52:10 +08:00
openpilot v0.7.8 release
This commit is contained in:
Binary file not shown.
+153
-124
@@ -10,6 +10,7 @@
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
|
||||
@@ -33,10 +34,10 @@
|
||||
|
||||
#define USER_AGENT "NEOSUpdater-0.2"
|
||||
|
||||
#define MANIFEST_URL_EON_STAGING "https://github.com/commaai/eon-neos/raw/master/update.staging.json"
|
||||
#define MANIFEST_URL_EON_LOCAL "http://192.168.5.1:8000/neosupdate/update.local.json"
|
||||
#define MANIFEST_URL_EON "https://github.com/commaai/eon-neos/raw/master/update.json"
|
||||
const char *manifest_url = MANIFEST_URL_EON;
|
||||
#define MANIFEST_URL_NEOS_STAGING "https://github.com/commaai/eon-neos/raw/master/update.staging.json"
|
||||
#define MANIFEST_URL_NEOS_LOCAL "http://192.168.5.1:8000/neosupdate/update.local.json"
|
||||
#define MANIFEST_URL_NEOS "https://github.com/commaai/eon-neos/raw/master/update.json"
|
||||
const char *manifest_url = MANIFEST_URL_NEOS;
|
||||
|
||||
#define RECOVERY_DEV "/dev/block/bootdevice/by-name/recovery"
|
||||
#define RECOVERY_COMMAND "/cache/recovery/command"
|
||||
@@ -96,7 +97,7 @@ std::string download_string(CURL *curl, std::string url) {
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
|
||||
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
|
||||
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
|
||||
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 0);
|
||||
curl_easy_setopt(curl, CURLOPT_USERAGENT, USER_AGENT);
|
||||
curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1);
|
||||
curl_easy_setopt(curl, CURLOPT_RESUME_FROM, 0);
|
||||
@@ -149,6 +150,32 @@ static void start_settings_activity(const char* name) {
|
||||
system(launch_cmd);
|
||||
}
|
||||
|
||||
bool is_settings_active() {
|
||||
FILE *fp;
|
||||
char sys_output[4096];
|
||||
|
||||
fp = popen("/bin/dumpsys window windows", "r");
|
||||
if (fp == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool active = false;
|
||||
while (fgets(sys_output, sizeof(sys_output), fp) != NULL) {
|
||||
if (strstr(sys_output, "mCurrentFocus=null") != NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (strstr(sys_output, "mCurrentFocus=Window") != NULL) {
|
||||
active = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pclose(fp);
|
||||
|
||||
return active;
|
||||
}
|
||||
|
||||
struct Updater {
|
||||
bool do_exit = false;
|
||||
|
||||
@@ -166,7 +193,6 @@ struct Updater {
|
||||
|
||||
std::mutex lock;
|
||||
|
||||
// i hate state machines give me coroutines already
|
||||
enum UpdateState {
|
||||
CONFIRMATION,
|
||||
LOW_BATTERY,
|
||||
@@ -190,9 +216,15 @@ struct Updater {
|
||||
int b_x, b_w, b_y, b_h;
|
||||
int balt_x;
|
||||
|
||||
// download stage writes these for the installation stage
|
||||
int recovery_len;
|
||||
std::string recovery_hash;
|
||||
std::string recovery_fn;
|
||||
std::string ota_fn;
|
||||
|
||||
CURL *curl = NULL;
|
||||
|
||||
Updater() {
|
||||
void ui_init() {
|
||||
touch_init(&touch);
|
||||
|
||||
fb = framebuffer_init("updater", 0x00001000, false,
|
||||
@@ -218,7 +250,6 @@ struct Updater {
|
||||
b_h = 220;
|
||||
|
||||
state = CONFIRMATION;
|
||||
|
||||
}
|
||||
|
||||
int download_file_xferinfo(curl_off_t dltotal, curl_off_t dlno,
|
||||
@@ -251,7 +282,7 @@ struct Updater {
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
|
||||
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
|
||||
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
|
||||
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 0);
|
||||
curl_easy_setopt(curl, CURLOPT_USERAGENT, USER_AGENT);
|
||||
curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1);
|
||||
curl_easy_setopt(curl, CURLOPT_RESUME_FROM, resume_from);
|
||||
@@ -319,32 +350,113 @@ struct Updater {
|
||||
state = RUNNING;
|
||||
}
|
||||
|
||||
std::string stage_download(std::string url, std::string hash, std::string name) {
|
||||
std::string download(std::string url, std::string hash, std::string name) {
|
||||
std::string out_fn = UPDATE_DIR "/" + util::base_name(url);
|
||||
|
||||
set_progress("Downloading " + name + "...");
|
||||
bool r = download_file(url, out_fn);
|
||||
if (!r) {
|
||||
set_error("failed to download " + name);
|
||||
return "";
|
||||
// start or resume downloading if hash doesn't match
|
||||
std::string fn_hash = sha256_file(out_fn);
|
||||
if (hash.compare(fn_hash) != 0) {
|
||||
set_progress("Downloading " + name + "...");
|
||||
bool r = download_file(url, out_fn);
|
||||
if (!r) {
|
||||
set_error("failed to download " + name);
|
||||
unlink(out_fn.c_str());
|
||||
return "";
|
||||
}
|
||||
fn_hash = sha256_file(out_fn);
|
||||
}
|
||||
|
||||
set_progress("Verifying " + name + "...");
|
||||
std::string fn_hash = sha256_file(out_fn);
|
||||
printf("got %s hash: %s\n", name.c_str(), hash.c_str());
|
||||
if (fn_hash != hash) {
|
||||
set_error(name + " was corrupt");
|
||||
unlink(out_fn.c_str());
|
||||
return "";
|
||||
}
|
||||
|
||||
return out_fn;
|
||||
}
|
||||
|
||||
void run_stages() {
|
||||
bool download_stage() {
|
||||
curl = curl_easy_init();
|
||||
assert(curl);
|
||||
|
||||
// ** quick checks before download **
|
||||
|
||||
if (!check_space()) {
|
||||
set_error("2GB of free space required to update");
|
||||
return false;
|
||||
}
|
||||
|
||||
mkdir(UPDATE_DIR, 0777);
|
||||
|
||||
set_progress("Finding latest version...");
|
||||
std::string manifest_s = download_string(curl, manifest_url);
|
||||
printf("manifest: %s\n", manifest_s.c_str());
|
||||
|
||||
std::string err;
|
||||
auto manifest = json11::Json::parse(manifest_s, err);
|
||||
if (manifest.is_null() || !err.empty()) {
|
||||
set_error("failed to load update manifest");
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string ota_url = manifest["ota_url"].string_value();
|
||||
std::string ota_hash = manifest["ota_hash"].string_value();
|
||||
|
||||
std::string recovery_url = manifest["recovery_url"].string_value();
|
||||
recovery_hash = manifest["recovery_hash"].string_value();
|
||||
recovery_len = manifest["recovery_len"].int_value();
|
||||
|
||||
// std::string installer_url = manifest["installer_url"].string_value();
|
||||
// std::string installer_hash = manifest["installer_hash"].string_value();
|
||||
|
||||
if (ota_url.empty() || ota_hash.empty()) {
|
||||
set_error("invalid update manifest");
|
||||
return false;
|
||||
}
|
||||
|
||||
// std::string installer_fn = download(installer_url, installer_hash, "installer");
|
||||
// if (installer_fn.empty()) {
|
||||
// //error'd
|
||||
// return;
|
||||
// }
|
||||
|
||||
// ** handle recovery download **
|
||||
if (recovery_url.empty() || recovery_hash.empty() || recovery_len == 0) {
|
||||
set_progress("Skipping recovery flash...");
|
||||
} else {
|
||||
// only download the recovery if it differs from what's flashed
|
||||
set_progress("Checking recovery...");
|
||||
std::string existing_recovery_hash = sha256_file(RECOVERY_DEV, recovery_len);
|
||||
printf("existing recovery hash: %s\n", existing_recovery_hash.c_str());
|
||||
|
||||
if (existing_recovery_hash != recovery_hash) {
|
||||
recovery_fn = download(recovery_url, recovery_hash, "recovery");
|
||||
if (recovery_fn.empty()) {
|
||||
// error'd
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ** handle ota download **
|
||||
ota_fn = download(ota_url, ota_hash, "update");
|
||||
if (ota_fn.empty()) {
|
||||
//error'd
|
||||
return false;
|
||||
}
|
||||
|
||||
// download sucessful
|
||||
return true;
|
||||
}
|
||||
|
||||
// thread that handles downloading and installing the update
|
||||
void run_stages() {
|
||||
printf("run_stages start\n");
|
||||
|
||||
|
||||
// ** download update **
|
||||
|
||||
if (!check_battery()) {
|
||||
set_battery_low();
|
||||
int battery_cap = battery_capacity();
|
||||
@@ -356,77 +468,12 @@ struct Updater {
|
||||
set_running();
|
||||
}
|
||||
|
||||
if (!check_space()) {
|
||||
set_error("2GB of free space required to update");
|
||||
bool sucess = download_stage();
|
||||
if (!sucess) {
|
||||
return;
|
||||
}
|
||||
|
||||
mkdir(UPDATE_DIR, 0777);
|
||||
|
||||
const int EON = (access("/EON", F_OK) != -1);
|
||||
|
||||
set_progress("Finding latest version...");
|
||||
std::string manifest_s;
|
||||
if (EON) {
|
||||
manifest_s = download_string(curl, manifest_url);
|
||||
} else {
|
||||
// don't update NEO
|
||||
exit(0);
|
||||
}
|
||||
|
||||
printf("manifest: %s\n", manifest_s.c_str());
|
||||
|
||||
std::string err;
|
||||
auto manifest = json11::Json::parse(manifest_s, err);
|
||||
if (manifest.is_null() || !err.empty()) {
|
||||
set_error("failed to load update manifest");
|
||||
return;
|
||||
}
|
||||
|
||||
std::string ota_url = manifest["ota_url"].string_value();
|
||||
std::string ota_hash = manifest["ota_hash"].string_value();
|
||||
|
||||
std::string recovery_url = manifest["recovery_url"].string_value();
|
||||
std::string recovery_hash = manifest["recovery_hash"].string_value();
|
||||
int recovery_len = manifest["recovery_len"].int_value();
|
||||
|
||||
// std::string installer_url = manifest["installer_url"].string_value();
|
||||
// std::string installer_hash = manifest["installer_hash"].string_value();
|
||||
|
||||
if (ota_url.empty() || ota_hash.empty()) {
|
||||
set_error("invalid update manifest");
|
||||
return;
|
||||
}
|
||||
|
||||
// std::string installer_fn = stage_download(installer_url, installer_hash, "installer");
|
||||
// if (installer_fn.empty()) {
|
||||
// //error'd
|
||||
// return;
|
||||
// }
|
||||
|
||||
std::string recovery_fn;
|
||||
if (recovery_url.empty() || recovery_hash.empty() || recovery_len == 0) {
|
||||
set_progress("Skipping recovery flash...");
|
||||
} else {
|
||||
// only download the recovery if it differs from what's flashed
|
||||
set_progress("Checking recovery...");
|
||||
std::string existing_recovery_hash = sha256_file(RECOVERY_DEV, recovery_len);
|
||||
printf("existing recovery hash: %s\n", existing_recovery_hash.c_str());
|
||||
|
||||
if (existing_recovery_hash != recovery_hash) {
|
||||
recovery_fn = stage_download(recovery_url, recovery_hash, "recovery");
|
||||
if (recovery_fn.empty()) {
|
||||
// error'd
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string ota_fn = stage_download(ota_url, ota_hash, "update");
|
||||
if (ota_fn.empty()) {
|
||||
//error'd
|
||||
return;
|
||||
}
|
||||
// ** install update **
|
||||
|
||||
if (!check_battery()) {
|
||||
set_battery_low();
|
||||
@@ -601,7 +648,7 @@ struct Updater {
|
||||
int powerprompt_y = 312;
|
||||
nvgFontFace(vg, "opensans_regular");
|
||||
nvgFontSize(vg, 64.0f);
|
||||
nvgText(vg, fb_w/2, 740, "Ensure EON is connected to power.", NULL);
|
||||
nvgText(vg, fb_w/2, 740, "Ensure your device remains connected to a power source.", NULL);
|
||||
|
||||
NVGpaint paint = nvgBoxGradient(
|
||||
vg, progress_x + 1, progress_y + 1,
|
||||
@@ -657,9 +704,7 @@ struct Updater {
|
||||
void ui_update() {
|
||||
std::lock_guard<std::mutex> guard(lock);
|
||||
|
||||
switch (state) {
|
||||
case ERROR:
|
||||
case CONFIRMATION: {
|
||||
if (state == ERROR || state == CONFIRMATION) {
|
||||
int touch_x = -1, touch_y = -1;
|
||||
int res = touch_poll(&touch, &touch_x, &touch_y, 0);
|
||||
if (res == 1 && !is_settings_active()) {
|
||||
@@ -678,13 +723,11 @@ struct Updater {
|
||||
}
|
||||
}
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void go() {
|
||||
ui_init();
|
||||
|
||||
while (!do_exit) {
|
||||
ui_update();
|
||||
|
||||
@@ -718,51 +761,37 @@ struct Updater {
|
||||
update_thread_handle.join();
|
||||
}
|
||||
|
||||
// reboot
|
||||
system("service call power 16 i32 0 i32 0 i32 1");
|
||||
}
|
||||
|
||||
bool is_settings_active() {
|
||||
FILE *fp;
|
||||
char sys_output[4096];
|
||||
|
||||
fp = popen("/bin/dumpsys window windows", "r");
|
||||
if (fp == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool active = false;
|
||||
while (fgets(sys_output, sizeof(sys_output), fp) != NULL) {
|
||||
if (strstr(sys_output, "mCurrentFocus=null") != NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (strstr(sys_output, "mCurrentFocus=Window") != NULL) {
|
||||
active = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pclose(fp);
|
||||
|
||||
return active;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
bool background_cache = false;
|
||||
if (argc > 1) {
|
||||
if (strcmp(argv[1], "local") == 0) {
|
||||
manifest_url = MANIFEST_URL_EON_LOCAL;
|
||||
manifest_url = MANIFEST_URL_NEOS_LOCAL;
|
||||
} else if (strcmp(argv[1], "staging") == 0) {
|
||||
manifest_url = MANIFEST_URL_EON_STAGING;
|
||||
manifest_url = MANIFEST_URL_NEOS_STAGING;
|
||||
} else if (strcmp(argv[1], "bgcache") == 0) {
|
||||
manifest_url = argv[2];
|
||||
background_cache = true;
|
||||
} else {
|
||||
manifest_url = argv[1];
|
||||
}
|
||||
}
|
||||
|
||||
printf("updating from %s\n", manifest_url);
|
||||
Updater updater;
|
||||
updater.go();
|
||||
|
||||
return 0;
|
||||
int err = 0;
|
||||
if (background_cache) {
|
||||
err = !updater.download_stage();
|
||||
} else {
|
||||
updater.go();
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user