From f6934f234ff859f8f026672bf8fa1ff87d4c2458 Mon Sep 17 00:00:00 2001 From: Kyle K Date: Fri, 6 Sep 2019 10:05:29 +0000 Subject: [PATCH 1/3] consider versions for unified targets --- src/js/tabs/firmware_flasher.js | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/src/js/tabs/firmware_flasher.js b/src/js/tabs/firmware_flasher.js index d10d6c9d..54ade1e9 100644 --- a/src/js/tabs/firmware_flasher.js +++ b/src/js/tabs/firmware_flasher.js @@ -206,11 +206,27 @@ TABS.firmware_flasher.initialize = function (callback) { loadUnifiedBuilds(releases); }; + function checkOneVersionForUnification(version) { + return semver.gte(version.split(' ')[0], '4.1.0-RC1'); + } + + function checkBuildsForUnification(builds) { + // Find a build that is newer than 4.1.0, return true if found + let foundSuitable = false; + Object.keys(builds).forEach(function (key) { + builds[key].forEach(function(target) { + if (checkOneVersionForUnification(target.version)) { + foundSuitable = true; + } + }); + }); + return foundSuitable; + } + function loadUnifiedBuilds(builds) { var expirationPeriod = 3600 * 2; // Two of your earth hours. var checkTime = Math.floor(Date.now() / 1000); // Lets deal in seconds. - // Come back to this, how to handle build type without unified targets? - if (builds && builds["STM32F411"]) { + if (builds && checkBuildsForUnification(builds)) { console.log('loaded some builds for later'); var storageTag = 'unifiedSourceCache'; chrome.storage.local.get(storageTag, function (result) { @@ -394,6 +410,9 @@ TABS.firmware_flasher.initialize = function (callback) { if (targetVersions) { versions_element.append($("".format(i18n.getMessage('firmwareFlasherOptionLabelSelectFirmwareVersionFor'), target))); targetVersions.forEach(function(descriptor) { + if (unifiedConfig && !checkOneVersionForUnification(descriptor.version)) { + return; + } var select_e = $("".format( descriptor.version, @@ -444,6 +463,7 @@ TABS.firmware_flasher.initialize = function (callback) { chrome.storage.local.get(storageTag, function (result) { let storageObj = result[storageTag]; let bareBoard = null; + // Check to see if the cached configuration is the one we want. if (!storageObj || !storageObj.target || storageObj.target != target) { // Have to go and try and get the unified config, and then do stuff $.get(TABS.firmware_flasher.unifiedConfigs[target], function(data) { @@ -473,6 +493,11 @@ TABS.firmware_flasher.initialize = function (callback) { isConfigLocal = false; unifiedConfig = data; bareBoard = data.split("\n")[0].split(' ')[3]; + if (bareBoard == target) { + // TODO test this, should skip a placeholder unified target + targetConfig = undefined; + unifiedConfig = undefined; + } populateVersions(versions_e, TABS.firmware_flasher.releases[bareBoard],target); } }); From 59d9832efa7bf3a3699b741df5986a68dd21aaf1 Mon Sep 17 00:00:00 2001 From: Kyle K Date: Fri, 6 Sep 2019 22:13:09 +0000 Subject: [PATCH 2/3] stop board selection from being dropped --- src/js/tabs/firmware_flasher.js | 50 ++++++++++++++++++++++----------- 1 file changed, 34 insertions(+), 16 deletions(-) diff --git a/src/js/tabs/firmware_flasher.js b/src/js/tabs/firmware_flasher.js index 54ade1e9..e3e0ed59 100644 --- a/src/js/tabs/firmware_flasher.js +++ b/src/js/tabs/firmware_flasher.js @@ -308,7 +308,8 @@ TABS.firmware_flasher.initialize = function (callback) { ConfigStorage.get('selected_board', function (result) { if (result.selected_board) { - var boardReleases = unifiedConfigs[result.selected_board] + var boardReleases = TABS.firmware_flasher.unifiedConfigs[result.selected_board] + || TABS.firmware_flasher.releases[result.selected_board]; $('select[name="board"]').val(boardReleases ? result.selected_board : 0).trigger('change'); } }); @@ -430,6 +431,26 @@ TABS.firmware_flasher.initialize = function (callback) { } } + function grabBuildNameFromConfig(config) { + return config.split("\n")[0].split(' ')[3]; + } + + function setUnifiedConfig(target, configText, bareBoard) { + if (bareBoard == target) { + console.log(bareBoard, '==', target); + if (!isConfigLocal) { + targetConfig = undefined; + unifiedConfig = undefined; + } else { + unifiedConfig = undefined; + } + } else { + targetConfig = configText; + isConfigLocal = false; + unifiedConfig = configText; + } + } + $('select[name="board"]').change(function() { $("a.load_remote_file").addClass('disabled'); var target = $(this).val(); @@ -468,15 +489,18 @@ TABS.firmware_flasher.initialize = function (callback) { // Have to go and try and get the unified config, and then do stuff $.get(TABS.firmware_flasher.unifiedConfigs[target], function(data) { console.log('got unified config'); + // cache it for later let tempObj = {}; tempObj['data'] = data; tempObj['target'] = target; tempObj['checkTime'] = checkTime; - targetConfig = data; - isConfigLocal = false; - unifiedConfig = data; - bareBoard = data.split("\n")[0].split(' ')[3]; - populateVersions(versions_e, TABS.firmware_flasher.releases[bareBoard],target); + let newStorageObj = {}; + newStorageObj[storageTag] = tempObj; + chrome.storage.local.set(newStorageObj); + + bareBoard = grabBuildNameFromConfig(data); + setUnifiedConfig(target, data, bareBoard); + populateVersions(versions_e, TABS.firmware_flasher.releases[bareBoard], target); }).fail(xhr => { //TODO error, populate nothing? targetConfig = undefined; @@ -489,16 +513,10 @@ TABS.firmware_flasher.initialize = function (callback) { } else { console.log('We have the config cached for', target); var data = storageObj.data; - targetConfig = data; - isConfigLocal = false; - unifiedConfig = data; - bareBoard = data.split("\n")[0].split(' ')[3]; - if (bareBoard == target) { - // TODO test this, should skip a placeholder unified target - targetConfig = undefined; - unifiedConfig = undefined; - } - populateVersions(versions_e, TABS.firmware_flasher.releases[bareBoard],target); + + bareBoard = grabBuildNameFromConfig(data); + setUnifiedConfig(target, data, bareBoard); + populateVersions(versions_e, TABS.firmware_flasher.releases[bareBoard], target); } }); } else { From 000e5372839b05cda1847c118ffe48e99c77dc64 Mon Sep 17 00:00:00 2001 From: Kyle K Date: Tue, 10 Sep 2019 08:20:01 +0000 Subject: [PATCH 3/3] Finish up work on unified targets --- locales/en/messages.json | 6 +- src/js/tabs/firmware_flasher.js | 110 ++++++++++++++++++++++++++------ src/tabs/firmware_flasher.html | 1 - 3 files changed, 94 insertions(+), 23 deletions(-) diff --git a/locales/en/messages.json b/locales/en/messages.json index 196ac70e..36fd2288 100644 --- a/locales/en/messages.json +++ b/locales/en/messages.json @@ -2582,9 +2582,6 @@ "firmwareFlasherReleaseDate": { "message": "Date:" }, - "firmwareFlasherReleaseStatus": { - "message": "State:" - }, "firmwareFlasherReleaseTarget": { "message": "Target:" }, @@ -2616,6 +2613,9 @@ "firmwareFlasherLoadFirmwareFile": { "message": "Please load firmware file" }, + "firmwareFlasherLoadedConfig": { + "message": "Loaded target, please load firmware file" + }, "firmwareFlasherNoReboot": { "message": "No reboot sequence" }, diff --git a/src/js/tabs/firmware_flasher.js b/src/js/tabs/firmware_flasher.js index e3e0ed59..cd16951e 100644 --- a/src/js/tabs/firmware_flasher.js +++ b/src/js/tabs/firmware_flasher.js @@ -4,7 +4,8 @@ TABS.firmware_flasher = { releases: null, releaseChecker: new ReleaseChecker('firmware', 'https://api.github.com/repos/betaflight/betaflight/releases'), jenkinsLoader: new JenkinsLoader('https://ci.betaflight.tech'), - localFileLoaded: false, + localFirmwareLoaded: false, + selectedBoard: undefined, }; TABS.firmware_flasher.initialize = function (callback) { @@ -14,19 +15,25 @@ TABS.firmware_flasher.initialize = function (callback) { GUI.active_tab = 'firmware_flasher'; } - + TABS.firmware_flasher.selectedBoard = undefined; + TABS.firmware_flasher.localFirmwareLoaded = false; var intel_hex = false; // standard intel hex in string format var parsed_hex = false; // parsed raw hex in array format var targetConfig; // the Unified Target configuration to be spliced into the configuration var isConfigLocal = false; // Set to true if the user loads one locally var unifiedConfig; // Unified target configuration loaded from the menu, used when throwing out a local config - self.peekTargetConfig = function () { // This maybe should get removed before merging. - return targetConfig; - } var unifiedSource = 'https://api.github.com/repos/betaflight/unified-targets/contents/configs/default'; + // These two functions are handy for peeking under the hood. Please don't call them in code. + self.peekTargetConfig = function () { + return targetConfig; + } + self.peekHex = function () { + return parsed_hex; + } + /** * Change boldness of firmware option depending on cache status * @@ -62,10 +69,9 @@ TABS.firmware_flasher.initialize = function (callback) { self.enableFlashing(true); - $('div.release_info .target').text(summary.target); + $('div.release_info .target').text(TABS.firmware_flasher.selectedBoard); $('div.release_info .name').text(summary.version).prop('href', summary.releaseUrl); $('div.release_info .date').text(summary.date); - $('div.release_info .status').text(summary.status); $('div.release_info .file').text(summary.file).prop('href', summary.url); var formattedNotes = summary.notes.replace(/#(\d+)/g, '[#$1](https://github.com/betaflight/betaflight/pull/$1)'); @@ -99,6 +105,7 @@ TABS.firmware_flasher.initialize = function (callback) { } function onLoadSuccess(data, summary) { + self.localFirmwareLoaded = false; // The path from getting a firmware doesn't fill in summary. summary = typeof summary === "object" ? summary @@ -146,7 +153,7 @@ TABS.firmware_flasher.initialize = function (callback) { ConfigStorage.get('selected_board', function (result) { if (result.selected_board) { - var boardBuilds = builds[result.selected_board] + var boardBuilds = builds[result.selected_board]; $('select[name="board"]').val(boardBuilds ? result.selected_board : 0).trigger('change'); } }); @@ -432,10 +439,18 @@ TABS.firmware_flasher.initialize = function (callback) { } function grabBuildNameFromConfig(config) { - return config.split("\n")[0].split(' ')[3]; + let bareBoard; + try { + bareBoard = config.split("\n")[0].split(' ')[3]; + } catch (e) { + bareBoard = undefined; + console.log('grabBuildNameFromConfig failed: ', e.message); + } + return bareBoard; } function setUnifiedConfig(target, configText, bareBoard) { + // a target might request a firmware with the same name, remove configuration in this case. if (bareBoard == target) { console.log(bareBoard, '==', target); if (!isConfigLocal) { @@ -450,26 +465,48 @@ TABS.firmware_flasher.initialize = function (callback) { unifiedConfig = configText; } } + function clearBufferedFirmware() { + isConfigLocal = false; + targetConfig = undefined; + unifiedConfig = undefined; + intel_hex = false; + parsed_hex = false; + self.localFirmwareLoaded = false; + } $('select[name="board"]').change(function() { $("a.load_remote_file").addClass('disabled'); var target = $(this).val(); - ConfigStorage.set({'selected_board': target}); - console.log('board changed to', target); if (!GUI.connect_lock) { + if (TABS.firmware_flasher.selectedBoard != target) { + // We're sure the board actually changed + if (isConfigLocal) { + console.log('Board changed, unloading local config'); + isConfigLocal = false; + targetConfig = undefined; + } + } + ConfigStorage.set({'selected_board': target}); + TABS.firmware_flasher.selectedBoard = target; + TABS.firmware_flasher.bareBoard = undefined; + console.log('board changed to', target); + self.flashingMessage('firmwareFlasherLoadFirmwareFile', self.FLASH_MESSAGE_TYPES.NEUTRAL) .flashProgress(0); $('div.git_info').slideUp(); $('div.release_info').slideUp(); - if (!self.localFileLoaded) { + if (!self.localFirmwareLoaded) { self.enableFlashing(false); } var versions_e = $('select[name="firmware_version"]'); if(target == 0) { + // target == 0 is the "Choose a Board" option. Throw out anything loaded + clearBufferedFirmware(); + versions_e.empty(); versions_e.append($("".format(i18n.getMessage('firmwareFlasherOptionLabelSelectFirmwareVersion')))); } else { @@ -499,6 +536,7 @@ TABS.firmware_flasher.initialize = function (callback) { chrome.storage.local.set(newStorageObj); bareBoard = grabBuildNameFromConfig(data); + TABS.firmware_flasher.bareBoard = bareBoard; setUnifiedConfig(target, data, bareBoard); populateVersions(versions_e, TABS.firmware_flasher.releases[bareBoard], target); }).fail(xhr => { @@ -515,6 +553,7 @@ TABS.firmware_flasher.initialize = function (callback) { var data = storageObj.data; bareBoard = grabBuildNameFromConfig(data); + TABS.firmware_flasher.bareBoard = bareBoard; setUnifiedConfig(target, data, bareBoard); populateVersions(versions_e, TABS.firmware_flasher.releases[bareBoard], target); } @@ -526,6 +565,7 @@ TABS.firmware_flasher.initialize = function (callback) { } else { unifiedConfig = undefined; } + TABS.firmware_flasher.bareBoard = target; populateVersions(versions_e, TABS.firmware_flasher.releases[target], target); } } @@ -533,10 +573,24 @@ TABS.firmware_flasher.initialize = function (callback) { } }); + function flashingMessageLocal() { + // used by the a.load_file hook, evaluate the loaded information, and enable flashing if suitable + if (isConfigLocal && !parsed_hex) { + self.flashingMessage(i18n.getMessage('firmwareFlasherLoadedConfig'), self.FLASH_MESSAGE_TYPES.NEUTRAL); + } + if (isConfigLocal && parsed_hex && !self.localFirmwareLoaded) { + self.enableFlashing(true); + self.flashingMessage(i18n.getMessage('firmwareFlasherFirmwareLocalLoaded', parsed_hex.bytes_total), self.FLASH_MESSAGE_TYPES.NEUTRAL); + } + if (self.localFirmwareLoaded) { + self.enableFlashing(true); + self.flashingMessage(i18n.getMessage('firmwareFlasherFirmwareLocalLoaded', parsed_hex.bytes_total), self.FLASH_MESSAGE_TYPES.NEUTRAL); + } + } // UI Hooks $('a.load_file').click(function () { self.enableFlashing(false); - self.localFileLoaded = true; + //self.localFileLoaded = true; analytics.setFirmwareData(analytics.DATA.FIRMWARE_CHANNEL, undefined); analytics.setFirmwareData(analytics.DATA.FIRMWARE_SOURCE, 'file'); @@ -580,16 +634,17 @@ TABS.firmware_flasher.initialize = function (callback) { if (parsed_hex) { analytics.setFirmwareData(analytics.DATA.FIRMWARE_SIZE, parsed_hex.bytes_total); - - self.enableFlashing(true); - - self.flashingMessage(i18n.getMessage('firmwareFlasherFirmwareLocalLoaded', parsed_hex.bytes_total), self.FLASH_MESSAGE_TYPES.NEUTRAL); + self.localFirmwareLoaded = true; + flashingMessageLocal(); } else { self.flashingMessage('firmwareFlasherHexCorrupted', self.FLASH_MESSAGE_TYPES.INVALID); } }); } else { + clearBufferedFirmware(); targetConfig = e.target.result; + isConfigLocal = true; + flashingMessageLocal(); } } }; @@ -606,8 +661,15 @@ TABS.firmware_flasher.initialize = function (callback) { $('select[name="firmware_version"]').change(function(evt){ $('div.release_info').slideUp(); - if (!self.localFileLoaded) { + if (!self.localFirmwareLoaded) { self.enableFlashing(false); + self.flashingMessage(i18n.getMessage('firmwareFlasherLoadFirmwareFile'), self.FLASH_MESSAGE_TYPES.NEUTRAL); + if(parsed_hex && parsed_hex.bytes_total) { + // Changing the board triggers a version change, so we need only dump it here. + console.log('throw out loaded hex'); + intel_hex = false; + parsed_hex = false; + } } let release = $("option:selected", evt.target).data("summary"); @@ -631,7 +693,7 @@ TABS.firmware_flasher.initialize = function (callback) { $('a.load_remote_file').click(function (evt) { self.enableFlashing(false); - self.localFileLoaded = false; + self.localFirmwareLoaded = false; analytics.setFirmwareData(analytics.DATA.FIRMWARE_SOURCE, 'http'); @@ -649,6 +711,16 @@ TABS.firmware_flasher.initialize = function (callback) { var summary = $('select[name="firmware_version"] option:selected').data('summary'); if (summary) { // undefined while list is loading or while running offline + if (isConfigLocal && FirmwareCache.has(summary)) { + // Load the .hex from Cache if available when the user is providing their own config. + analytics.setFirmwareData(analytics.DATA.FIRMWARE_SOURCE, 'cache'); + FirmwareCache.get(summary, cached => { + analytics.setFirmwareData(analytics.DATA.FIRMWARE_NAME, summary.file); + console.info("Release found in cache: " + summary.file); + onLoadSuccess(cached.hexdata, summary); + }); + return; + } analytics.setFirmwareData(analytics.DATA.FIRMWARE_NAME, summary.file); $("a.load_remote_file").text(i18n.getMessage('firmwareFlasherButtonDownloading')); $("a.load_remote_file").addClass('disabled'); diff --git a/src/tabs/firmware_flasher.html b/src/tabs/firmware_flasher.html index f1b0f5d4..3cfbb14d 100644 --- a/src/tabs/firmware_flasher.html +++ b/src/tabs/firmware_flasher.html @@ -93,7 +93,6 @@ href="#" target="_blank">