Skip to content

Commit afad6f0

Browse files
committed
Merge branch 'beta' into develop
2 parents e4838f4 + f45e870 commit afad6f0

File tree

7 files changed

+233
-140
lines changed

7 files changed

+233
-140
lines changed

CHANGELOG.md

Lines changed: 93 additions & 84 deletions
Large diffs are not rendered by default.

frontend/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "frontend",
3-
"version": "1.5.0-rc.5",
3+
"version": "1.5.0",
44
"private": true,
55
"type": "module",
66
"scripts": {

scripts/embed_env_vars.py

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,17 @@
2121
# If we are running in CI and either building the master branch, beta branch, or a tag, then we are in RELEASE mode.
2222
is_ci = shorthands.is_github_ci()
2323
branch_name = shorthands.get_github_ref_name()
24-
is_release_build = is_ci and (
24+
is_stable = is_ci and (
2525
branch_name == 'master'
2626
or shorthands.is_github_pr_into('master')
27-
or branch_name == 'beta'
27+
)
28+
is_beta = is_ci and (
29+
branch_name == 'beta'
2830
or shorthands.is_github_pr_into('beta')
29-
or shorthands.is_github_tag()
3031
)
32+
is_tag = is_ci and shorthands.is_github_tag()
33+
34+
is_release_build = is_stable or is_beta or is_tag
3135

3236
# Get the build type string.
3337
pio_build_type = 'release' if is_release_build else 'debug'
@@ -146,8 +150,8 @@ def serialize_cpp_define(k: str, v: str | int | bool) -> str | int:
146150

147151

148152
def split_semver(version):
149-
# Match the semver pattern
150-
pattern = r'^(?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)(?:-(?P<prerelease>[0-9A-Za-z.-]+))?(?:\+(?P<build>[0-9A-Za-z.-]+))?$'
153+
# Match the semver pattern (with optional 'v' prefix)
154+
pattern = r'^v?(?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)(?:-(?P<prerelease>[0-9A-Za-z.-]+))?(?:\+(?P<build>[0-9A-Za-z.-]+))?$'
151155
match = re.match(pattern, version)
152156

153157
if not match:
@@ -210,8 +214,9 @@ def print_dump(name: str, map: Mapping[str, str | int | bool]) -> None:
210214
if is_ci:
211215
raise ValueError('OPENSHOCK_FW_VERSION must be set in environment variables for CI builds.')
212216

213-
# If latest_git_tag is set, use it, else use 0.0.0, assign to variable.
214-
version = (git_latest_clean_tag if git_latest_clean_tag is not None else '0.0.0') + '-local'
217+
# If latest_git_tag is set, use it (stripped of 'v' prefix), else use 0.0.0, assign to variable.
218+
clean_tag = git_latest_clean_tag.lstrip('v') if git_latest_clean_tag is not None else '0.0.0'
219+
version = clean_tag + '-local'
215220

216221
# If git_commit is set, append it to the version.
217222
if git_commit is not None:
@@ -228,23 +233,30 @@ def print_dump(name: str, map: Mapping[str, str | int | bool]) -> None:
228233
cpp_defines['OPENSHOCK_FW_VERSION_MAJOR'] = version_major
229234
cpp_defines['OPENSHOCK_FW_VERSION_MINOR'] = version_minor
230235
cpp_defines['OPENSHOCK_FW_VERSION_PATCH'] = version_patch
231-
cpp_defines['OPENSHOCK_FW_VERSION_PRERELEASE'] = version_prerelease
232-
cpp_defines['OPENSHOCK_FW_VERSION_BUILD'] = version_build
236+
if version_prerelease is not None:
237+
cpp_defines['OPENSHOCK_FW_VERSION_PRERELEASE'] = version_prerelease
238+
if version_build is not None:
239+
cpp_defines['OPENSHOCK_FW_VERSION_BUILD'] = version_build
233240

234241
# Gets the log level from environment variables.
235242
# TODO: Delete get_loglevel and use... something more generic.
236243
log_level_int = dot.get_loglevel('LOG_LEVEL')
237244
if log_level_int is None:
238245
raise ValueError('LOG_LEVEL must be set in environment variables.')
246+
247+
# Beta builds are release builds but with debug-level logging.
248+
if is_beta:
249+
log_level_int = 4 # Debug level.
250+
239251
cpp_defines['OPENSHOCK_LOG_LEVEL'] = log_level_int
240-
cpp_defines['CORE_DEBUG_LEVEL'] = 2 # Warning level. (FUCK Arduino)
252+
cpp_defines['CORE_DEBUG_LEVEL'] = log_level_int if not is_release_build or is_beta else 2 # Warning level for release, match log level for dev/beta.
241253

242254
# Serialize and inject CPP Defines.
243255
print_dump('CPP Defines', cpp_defines)
244256

245257
cpp_defines = serialize_cpp_defines(cpp_defines)
246258

247-
print('Build type: ' + pio_build_type)
259+
print('Build type: ' + pio_build_type + (' (beta, debug logging)' if is_beta else ''))
248260

249261
# Set PIO variables.
250262
env['BUILD_TYPE'] = pio_build_type
@@ -255,4 +267,4 @@ def print_dump(name: str, map: Mapping[str, str | int | bool]) -> None:
255267
# Rename the firmware.bin to app.bin.
256268
env.Replace(PROGNAME='app')
257269

258-
print(env.Dump())
270+
print(env.Dump())

src/OtaUpdateManager.cpp

Lines changed: 73 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -63,13 +63,28 @@ enum OtaTaskEventFlag : uint32_t {
6363

6464
static esp_ota_img_states_t _otaImageState;
6565
static OpenShock::FirmwareBootType _bootType;
66-
static TaskHandle_t _taskHandle;
66+
static TaskHandle_t _taskHandle = nullptr;
6767
static OpenShock::SemVer _requestedVersion;
6868
static OpenShock::SimpleMutex _requestedVersionMutex = {};
6969

7070
using namespace OpenShock;
7171

72-
static bool _tryQueueUpdateRequest(const OpenShock::SemVer& version)
72+
static bool otaum_try_notify_task(uint32_t eventFlag)
73+
{
74+
if (_taskHandle == nullptr) {
75+
OS_LOGW(TAG, "Unable to notify OTA task, task handle is null");
76+
return false;
77+
}
78+
79+
if (xTaskNotify(_taskHandle, eventFlag, eSetBits) != pdPASS) {
80+
OS_LOGE(TAG, "Failed to notify OTA task (event: 0x%08x)", eventFlag);
81+
return false;
82+
}
83+
84+
return true;
85+
}
86+
87+
static bool otaum_try_queue_update_request(const OpenShock::SemVer& version)
7388
{
7489
if (!_requestedVersionMutex.lock(pdMS_TO_TICKS(1000))) {
7590
OS_LOGE(TAG, "Failed to take requested version mutex");
@@ -80,7 +95,7 @@ static bool _tryQueueUpdateRequest(const OpenShock::SemVer& version)
8095

8196
_requestedVersionMutex.unlock();
8297

83-
xTaskNotify(_taskHandle, OTA_TASK_EVENT_UPDATE_REQUESTED, eSetBits);
98+
otaum_try_notify_task(OTA_TASK_EVENT_UPDATE_REQUESTED);
8499

85100
return true;
86101
}
@@ -106,7 +121,7 @@ static void otaum_evh_wifidisconnected(void* event_handler_arg, esp_event_base_t
106121
(void)event_id;
107122
(void)event_data;
108123

109-
xTaskNotify(_taskHandle, OTA_TASK_EVENT_WIFI_DISCONNECTED, eSetBits);
124+
otaum_try_notify_task(OTA_TASK_EVENT_WIFI_DISCONNECTED);
110125
}
111126

112127
static void otaum_evh_ipevent(void* event_handler_arg, esp_event_base_t event_base, int32_t event_id, void* event_data)
@@ -118,17 +133,17 @@ static void otaum_evh_ipevent(void* event_handler_arg, esp_event_base_t event_ba
118133
switch (event_id) {
119134
case IP_EVENT_GOT_IP6:
120135
case IP_EVENT_STA_GOT_IP:
121-
xTaskNotify(_taskHandle, OTA_TASK_EVENT_WIFI_CONNECTED, eSetBits);
136+
otaum_try_notify_task(OTA_TASK_EVENT_WIFI_CONNECTED);
122137
break;
123138
case IP_EVENT_STA_LOST_IP:
124-
xTaskNotify(_taskHandle, OTA_TASK_EVENT_WIFI_DISCONNECTED, eSetBits);
139+
otaum_try_notify_task(OTA_TASK_EVENT_WIFI_DISCONNECTED);
125140
break;
126141
default:
127142
return;
128143
}
129144
}
130145

131-
static bool _sendProgressMessage(Serialization::Types::OtaUpdateProgressTask task, float progress)
146+
static bool otaum_send_progress_msg(Serialization::Types::OtaUpdateProgressTask task, float progress)
132147
{
133148
int32_t updateId;
134149
if (!Config::GetOtaUpdateId(updateId)) {
@@ -159,18 +174,18 @@ static bool _sendFailureMessage(std::string_view message, bool fatal = false)
159174
return true;
160175
}
161176

162-
static bool _flashAppPartition(const esp_partition_t* partition, std::string_view remoteUrl, const uint8_t (&remoteHash)[32])
177+
static bool otaum_flash_app_partition(const esp_partition_t* partition, std::string_view remoteUrl, const uint8_t (&remoteHash)[32])
163178
{
164179
OS_LOGD(TAG, "Flashing app partition");
165180

166-
if (!_sendProgressMessage(Serialization::Types::OtaUpdateProgressTask::FlashingApplication, 0.0f)) {
181+
if (!otaum_send_progress_msg(Serialization::Types::OtaUpdateProgressTask::FlashingApplication, 0.0f)) {
167182
return false;
168183
}
169184

170185
auto onProgress = [](std::size_t current, std::size_t total, float progress) -> bool {
171186
OS_LOGD(TAG, "Flashing app partition: %u / %u (%.2f%%)", current, total, progress * 100.0f);
172187

173-
_sendProgressMessage(Serialization::Types::OtaUpdateProgressTask::FlashingApplication, progress);
188+
otaum_send_progress_msg(Serialization::Types::OtaUpdateProgressTask::FlashingApplication, progress);
174189

175190
return true;
176191
};
@@ -181,7 +196,7 @@ static bool _flashAppPartition(const esp_partition_t* partition, std::string_vie
181196
return false;
182197
}
183198

184-
if (!_sendProgressMessage(Serialization::Types::OtaUpdateProgressTask::MarkingApplicationBootable, 0.0f)) {
199+
if (!otaum_send_progress_msg(Serialization::Types::OtaUpdateProgressTask::MarkingApplicationBootable, 0.0f)) {
185200
return false;
186201
}
187202

@@ -195,9 +210,9 @@ static bool _flashAppPartition(const esp_partition_t* partition, std::string_vie
195210
return true;
196211
}
197212

198-
static bool _flashFilesystemPartition(const esp_partition_t* parition, std::string_view remoteUrl, const uint8_t (&remoteHash)[32])
213+
static bool otaum_flash_fs_partition(const esp_partition_t* parition, std::string_view remoteUrl, const uint8_t (&remoteHash)[32])
199214
{
200-
if (!_sendProgressMessage(Serialization::Types::OtaUpdateProgressTask::PreparingForUpdate, 0.0f)) {
215+
if (!otaum_send_progress_msg(Serialization::Types::OtaUpdateProgressTask::PreparingForUpdate, 0.0f)) {
201216
return false;
202217
}
203218

@@ -210,14 +225,14 @@ static bool _flashFilesystemPartition(const esp_partition_t* parition, std::stri
210225

211226
OS_LOGD(TAG, "Flashing filesystem partition");
212227

213-
if (!_sendProgressMessage(Serialization::Types::OtaUpdateProgressTask::FlashingFilesystem, 0.0f)) {
228+
if (!otaum_send_progress_msg(Serialization::Types::OtaUpdateProgressTask::FlashingFilesystem, 0.0f)) {
214229
return false;
215230
}
216231

217232
auto onProgress = [](std::size_t current, std::size_t total, float progress) -> bool {
218233
OS_LOGD(TAG, "Flashing filesystem partition: %u / %u (%.2f%%)", current, total, progress * 100.0f);
219234

220-
_sendProgressMessage(Serialization::Types::OtaUpdateProgressTask::FlashingFilesystem, progress);
235+
otaum_send_progress_msg(Serialization::Types::OtaUpdateProgressTask::FlashingFilesystem, progress);
221236

222237
return true;
223238
};
@@ -228,7 +243,7 @@ static bool _flashFilesystemPartition(const esp_partition_t* parition, std::stri
228243
return false;
229244
}
230245

231-
if (!_sendProgressMessage(Serialization::Types::OtaUpdateProgressTask::VerifyingFilesystem, 0.0f)) {
246+
if (!otaum_send_progress_msg(Serialization::Types::OtaUpdateProgressTask::VerifyingFilesystem, 0.0f)) {
232247
return false;
233248
}
234249

@@ -244,6 +259,13 @@ static bool _flashFilesystemPartition(const esp_partition_t* parition, std::stri
244259
return true;
245260
}
246261

262+
static void otaum_restore_wdt_timeout()
263+
{
264+
if (esp_task_wdt_init(5, true) != ESP_OK) {
265+
OS_LOGE(TAG, "Failed to restore task watchdog timeout");
266+
}
267+
};
268+
247269
static void otaum_updatetask(void* arg)
248270
{
249271
(void)arg;
@@ -355,7 +377,7 @@ static void otaum_updatetask(void* arg)
355377
continue;
356378
}
357379

358-
if (!_sendProgressMessage(Serialization::Types::OtaUpdateProgressTask::FetchingMetadata, 0.0f)) {
380+
if (!otaum_send_progress_msg(Serialization::Types::OtaUpdateProgressTask::FetchingMetadata, 0.0f)) {
359381
continue;
360382
}
361383

@@ -393,24 +415,36 @@ static void otaum_updatetask(void* arg)
393415

394416
// Increase task watchdog timeout.
395417
// Prevents panics on some ESP32s when clearing large partitions.
396-
esp_task_wdt_init(15, true);
418+
if (esp_task_wdt_init(15, true) != ESP_OK) {
419+
OS_LOGE(TAG, "Failed to increase task watchdog timeout");
420+
_sendFailureMessage("Failed to increase task watchdog timeout"sv);
421+
continue;
422+
}
423+
397424

398425
// Flash app and filesystem partitions.
399-
if (!_flashFilesystemPartition(filesystemPartition, release.filesystemBinaryUrl, release.filesystemBinaryHash)) continue;
400-
if (!_flashAppPartition(appPartition, release.appBinaryUrl, release.appBinaryHash)) continue;
426+
if (!otaum_flash_fs_partition(filesystemPartition, release.filesystemBinaryUrl, release.filesystemBinaryHash)) {
427+
otaum_restore_wdt_timeout();
428+
continue;
429+
}
430+
if (!otaum_flash_app_partition(appPartition, release.appBinaryUrl, release.appBinaryHash)) {
431+
otaum_restore_wdt_timeout();
432+
continue;
433+
}
401434

402435
// Set OTA boot type in config.
403436
if (!Config::SetOtaUpdateStep(OpenShock::OtaUpdateStep::Updated)) {
404437
OS_LOGE(TAG, "Failed to set OTA update step");
405438
_sendFailureMessage("Failed to set OTA update step"sv);
439+
otaum_restore_wdt_timeout();
406440
continue;
407441
}
408442

409443
// Set task watchdog timeout back to default.
410-
esp_task_wdt_init(5, true);
444+
otaum_restore_wdt_timeout();
411445

412446
// Send reboot message.
413-
_sendProgressMessage(Serialization::Types::OtaUpdateProgressTask::Rebooting, 0.0f);
447+
otaum_send_progress_msg(Serialization::Types::OtaUpdateProgressTask::Rebooting, 0.0f);
414448

415449
// Reboot into new firmware.
416450
OS_LOGI(TAG, "Restarting into new firmware...");
@@ -505,6 +539,12 @@ bool OtaUpdateManager::Init()
505539
}
506540
}
507541

542+
// Start OTA update task.
543+
if (TaskUtils::TaskCreateExpensive(otaum_updatetask, "OTA Update", 16'384, nullptr, 1, &_taskHandle) != pdPASS) { // PROFILED: 6.2KB stack usage
544+
OS_LOGE(TAG, "Failed to create OTA update task");
545+
return false;
546+
}
547+
508548
err = esp_event_handler_register(IP_EVENT, ESP_EVENT_ANY_ID, otaum_evh_ipevent, nullptr);
509549
if (err != ESP_OK) {
510550
OS_LOGE(TAG, "Failed to register event handler for IP_EVENT: %s", esp_err_to_name(err));
@@ -517,9 +557,6 @@ bool OtaUpdateManager::Init()
517557
return false;
518558
}
519559

520-
// Start OTA update task.
521-
TaskUtils::TaskCreateExpensive(otaum_updatetask, "OTA Update", 8192, nullptr, 1, &_taskHandle); // PROFILED: 6.2KB stack usage
522-
523560
return true;
524561
}
525562

@@ -671,14 +708,24 @@ bool OtaUpdateManager::TryGetFirmwareRelease(const OpenShock::SemVer& version, F
671708
}
672709
}
673710

711+
if (!foundAppHash) {
712+
OS_LOGE(TAG, "Missing hash for app.bin");
713+
return false;
714+
}
715+
716+
if (!foundFilesystemHash) {
717+
OS_LOGE(TAG, "Missing hash for staticfs.bin");
718+
return false;
719+
}
720+
674721
return true;
675722
}
676723

677724
bool OtaUpdateManager::TryStartFirmwareUpdate(const OpenShock::SemVer& version)
678725
{
679726
OS_LOGD(TAG, "Requesting firmware version %s", version.toString().c_str()); // TODO: This is abusing the SemVer::toString() method causing alot of string copies, fix this
680727

681-
return _tryQueueUpdateRequest(version);
728+
return otaum_try_queue_update_request(version);
682729
}
683730

684731
FirmwareBootType OtaUpdateManager::GetFirmwareBootType()

src/SemVer.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -334,8 +334,11 @@ bool OpenShock::TryParseSemVer(std::string_view semverStr, SemVer& semver)
334334
size_t plusIdx = patchStr.find('+');
335335
size_t dashIdx = patchStr.find('-');
336336

337-
std::string_view restStr = patchStr.substr(std::min(dashIdx, plusIdx));
338-
patchStr.remove_suffix(restStr.length());
337+
std::string_view restStr;
338+
if (dashIdx != std::string_view::npos || plusIdx != std::string_view::npos) {
339+
restStr = patchStr.substr(std::min(dashIdx, plusIdx));
340+
patchStr.remove_suffix(restStr.length());
341+
}
339342

340343
if (!Convert::ToUint16(majorStr, semver.major)) {
341344
OS_LOGE(TAG, "Invalid major version: %.*s", majorStr.length(), majorStr.data());

0 commit comments

Comments
 (0)