Skip to content

Commit 45d2365

Browse files
committed
[SD] Refactor checksum validation out, dont require it to operate
1 parent 8bac2d7 commit 45d2365

11 files changed

+59
-11
lines changed

data.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"exportVersion": "1.0.0", "exportedBy": "wokwi", "exportedAt": "2024-10-28T18:58:23.976Z", "exportedFromDevice": {"board": "metroesp32s3", "firmwareVersion": "1.0.0-beta.93", "referenceVoltage": 2.6, "totalGPIOPins": 11, "totalAnalogPins": 6}, "components": [{"componentAPI": "digitalio", "name": "Button (D4)", "pinName": "D4", "type": "push_button", "mode": "DIGITAL", "sampleMode": "TIMER", "direction": "INPUT", "period": 5, "pull": "UP", "isPin": true}]}

generate_json_checksum.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,11 @@
99
print("Error: JSON file did not contain any data or path didn't match exactly, exiting...")
1010
exit(1)
1111

12-
# convert json dict->string and sum
13-
str_json_data = json.dumps(json_data)
14-
sum_json_data = sum(bytearray(str_json_data.encode()))
15-
print('Sum (hex): ', hex(sum_json_data))
12+
if 'checksum' in json_data:
13+
del json_data['checksum']
14+
15+
# NOTE: This is important to re-serialize json data to match ArduinoJSON's compact serialization format
16+
str_json_data = json.dumps(json_data, separators=(',', ':'), sort_keys=True)
1617

1718
# calculate checksum
1819
calculated_checksum = sum(bytearray(str_json_data.encode())) & 0xFF

src/provisioning/sdcard/ws_sdcard.cpp

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -441,6 +441,23 @@ bool ws_sdcard::CreateNewLogFile() {
441441
return true;
442442
}
443443

444+
bool ws_sdcard::ValidateChecksum(JsonDocument &doc) {
445+
int json_doc_checksum = doc["checksum"];
446+
// Calculate the checksum of the JSON document without the checksum field
447+
doc.remove("checksum");
448+
String doc_without_checksum;
449+
serializeJson(doc, doc_without_checksum);
450+
uint8_t calculated_checksum = 0;
451+
for (unsigned int i = 0; i < doc_without_checksum.length(); i++) {
452+
calculated_checksum += doc_without_checksum[i];
453+
}
454+
calculated_checksum &= 0xFF; // take lsb
455+
456+
if (json_doc_checksum != calculated_checksum)
457+
return false;
458+
return true;
459+
}
460+
444461
/**************************************************************************/
445462
/*!
446463
@brief Searches for and parses the JSON configuration file and sets up
@@ -476,7 +493,6 @@ bool ws_sdcard::parseConfigFile() {
476493
error = deserializeJson(doc, json_test_data, max_json_len);
477494
}
478495
#endif
479-
480496
// If the JSON document failed to deserialize - halt the running device and
481497
// print the error because it is not possible to continue running in offline
482498
// mode without a valid config file
@@ -485,11 +501,17 @@ bool ws_sdcard::parseConfigFile() {
485501
String(error.c_str()));
486502
return false;
487503
}
488-
489504
WS_DEBUG_PRINTLN("[SD] Successfully deserialized JSON config file!");
490505

506+
// Calculate the 8-bit checksum of the JSON file to ensure it is valid data
507+
if (! ValidateChecksum(doc)) {
508+
WS_DEBUG_PRINTLN("[SD] Checksum mismatch, file has been modified from its original state!");
509+
}
510+
WS_DEBUG_PRINTLN("[SD] JSON checksum OK!");
511+
491512
// NOTE: This is only used by the CI runner, production builds do not run
492513
// this!
514+
// TODO: Do we even need this anymore? We switched to a compile-time constant instead
493515
const char *exportedBy = doc["exportedBy"];
494516
if (strcmp(exportedBy, "wokwi") == 0) {
495517
_is_using_wokwi = true;

src/provisioning/sdcard/ws_sdcard.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ class ws_sdcard {
5252
bool LogDS18xSensorEventToSD(wippersnapper_ds18x20_Ds18x20Event *event_msg);
5353

5454
private:
55+
bool ValidateChecksum(JsonDocument &doc);
5556
bool ValidateJSON(const char *input);
5657
bool ValidateJSONKey(const char *key, const char *error_msg);
5758
void CheckIn(uint8_t max_digital_pins, uint8_t max_analog_pins,

tests/bin/offline/firmware.elf

46.8 KB
Binary file not shown.
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
name: Offline Mode - Invalid Checksum Value
2+
version: 1
3+
author: Brent Rubell for Adafruit Industries
4+
5+
steps:
6+
- wait-serial: '[SD] Waiting for incoming JSON string...'
7+
- write-serial: '{"exportVersion": "1.0.0", "exportedBy": "wokwi", "exportedAt": "2024-10-28T18:58:23.976Z", "exportedFromDevice": {"board": "metroesp32s3", "firmwareVersion": "1.0.0-beta.93", "referenceVoltage": 2.6, "totalGPIOPins": 11, "totalAnalogPins": 6}, "components": [{"componentAPI": "analogio", "name": "Analog Pin", "pinName": "D14", "type": "analog_pin", "mode": "ANALOG", "direction": "INPUT", "sampleMode": "TIMER", "analogReadMode": "PIN_VALUE", "period": 5, "isPin": true}], "checksum": 5}'
8+
- write-serial: '\n'
9+
- wait-serial: '[SD] Checksum mismatch, file has been modified from its original state!'

tests/scenarios/offline/test-log-analogin.scenario.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ author: Brent Rubell for Adafruit Industries
44

55
steps:
66
- wait-serial: '[SD] Waiting for incoming JSON string...'
7-
- write-serial: '{"exportVersion":"1.0.0","exportedBy":"wokwi","exportedAt":"2024-10-28T18:58:23.976Z","exportedFromDevice":{"board":"metroesp32s3","firmwareVersion":"1.0.0-beta.93","referenceVoltage":2.6,"totalGPIOPins":11,"totalAnalogPins":6},"components":[{"componentAPI":"analogio","name":"Analog Pin","pinName":"D14","type":"analog_pin","mode":"ANALOG","direction":"INPUT","sampleMode":"TIMER","analogReadMode":"PIN_VALUE","period":5,"isPin":true}]}'
7+
- write-serial: '{"exportVersion": "1.0.0", "exportedBy": "wokwi", "exportedAt": "2024-10-28T18:58:23.976Z", "exportedFromDevice": {"board": "metroesp32s3", "firmwareVersion": "1.0.0-beta.93", "referenceVoltage": 2.6, "totalGPIOPins": 11, "totalAnalogPins": 6}, "components": [{"componentAPI": "analogio", "name": "Analog Pin", "pinName": "D14", "type": "analog_pin", "mode": "ANALOG", "direction": "INPUT", "sampleMode": "TIMER", "analogReadMode": "PIN_VALUE", "period": 5, "isPin": true}], "checksum": 149}'
88
- write-serial: '\n'
99
- wait-serial: '[SD] Valid JSON string received!'
1010
- wait-serial: '[analogio] Added new pin:'

tests/scenarios/offline/test-log-digital-in.scenario.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ author: Brent Rubell for Adafruit Industries
44

55
steps:
66
- wait-serial: '[SD] Waiting for incoming JSON string...'
7-
- write-serial: '{"exportVersion":"1.0.0","exportedBy":"wokwi","exportedAt":"2024-10-28T18:58:23.976Z","exportedFromDevice":{"board":"metroesp32s3","firmwareVersion":"1.0.0-beta.93","referenceVoltage":2.6,"totalGPIOPins":11,"totalAnalogPins":6},"components":[{"componentAPI":"digitalio","name":"Button (D4)","pinName":"D4","type":"push_button","mode":"DIGITAL","sampleMode":"TIMER","direction":"INPUT","period":5,"pull":"UP","isPin":true}]}'
7+
- write-serial: '{"checksum":183,"components":[{"componentAPI":"digitalio","direction":"INPUT","isPin":true,"mode":"DIGITAL","name":"Button (D4)","period":5,"pinName":"D4","pull":"UP","sampleMode":"TIMER","type":"push_button"}],"exportVersion":"1.0.0","exportedAt":"2024-10-28T18:58:23.976Z","exportedBy":"wokwi","exportedFromDevice":{"board":"metroesp32s3","firmwareVersion":"1.0.0-beta.93","referenceVoltage":2.6,"totalAnalogPins":6,"totalGPIOPins":11}}'
88
- write-serial: '\n'
99
- wait-serial: '[SD] Valid JSON string received!'
1010
- wait-serial: '[digitalio] Added new pin:'

tests/scenarios/offline/test-log-ds18b20.scenario.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ author: Brent Rubell for Adafruit Industries
44

55
steps:
66
- wait-serial: '[SD] Waiting for incoming JSON string...'
7-
- write-serial: '{"exportVersion":"1.0.0","exportedBy":"wokwi","exportedAt":"2024-10-28T18:58:23.976Z","exportedFromDevice":{"board":"metroesp32s3","firmwareVersion":"1.0.0-beta.93","referenceVoltage":2.6,"totalGPIOPins":11,"totalAnalogPins":6},"components":[{"componentAPI":"ds18x20","name":"DS18B20: Temperature Sensor (°F)","sensorTypeCount":2,"sensorType1":"object-temp-fahrenheit","sensorType2":"object-temp","pinName":"D6","sensorResolution":12,"period":5}]}'
7+
- write-serial: '{"exportVersion": "1.0.0", "exportedBy": "wokwi", "exportedAt": "2024-10-28T18:58:23.976Z", "exportedFromDevice": {"board": "metroesp32s3", "firmwareVersion": "1.0.0-beta.93", "referenceVoltage": 2.6, "totalGPIOPins": 11, "totalAnalogPins": 6}, "components": [{"componentAPI": "ds18x20", "name": "DS18B20: Temperature Sensor", "sensorTypeCount": 2, "sensorType1": "object-temp-fahrenheit", "sensorType2": "object-temp", "pinName": "D6", "sensorResolution": 12, "period": 5}], "checksum": 34}'
88
- write-serial: '\n'
99
- wait-serial: '[SD] Valid JSON string received!'
1010
- wait-serial: '{"timestamp":0,"pin":"D6","value":0,"si_unit":"OBJECT_TEMPERATURE"}'
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
name: Offline Mode - Invalid Checksum Value
2+
version: 1
3+
author: Brent Rubell for Adafruit Industries
4+
5+
steps:
6+
- wait-serial: '[SD] Waiting for incoming JSON string...'
7+
- write-serial: '{"exportVersion": "1.0.0", "exportedBy": "wokwi", "exportedAt": "2024-10-28T18:58:23.976Z", "exportedFromDevice": {"board": "metroesp32s3", "firmwareVersion": "1.0.0-beta.93", "referenceVoltage": 2.6, "totalGPIOPins": 11, "totalAnalogPins": 6}, "components": [{"componentAPI": "analogio", "name": "Analog Pin", "pinName": "D14", "type": "analog_pin", "mode": "ANALOG", "direction": "INPUT", "sampleMode": "TIMER", "analogReadMode": "PIN_VALUE", "period": 5, "isPin": true}], "checksum": 149}'
8+
- write-serial: '\n'
9+
- wait-serial: '[SD] JSON checksum OK!'

0 commit comments

Comments
 (0)