Skip to content

Commit c2ea367

Browse files
committed
[SD] Handle error cases during parsing for DIOAdd
1 parent e795301 commit c2ea367

File tree

2 files changed

+67
-40
lines changed

2 files changed

+67
-40
lines changed

src/provisioning/sdcard/ws_sdcard.cpp

Lines changed: 60 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,9 @@ ws_sdcard::ws_sdcard() {
3232
*/
3333
/**************************************************************************/
3434
ws_sdcard::~ws_sdcard() {
35-
// TODO: Close any open files
36-
// Then, end the SD card (ends SPI transaction)
3735
if (is_mode_offline) {
38-
_sd.end();
39-
is_mode_offline = false;
36+
_sd.end(); // Close the SD card
37+
is_mode_offline = false; // Disable offline mode
4038
}
4139
}
4240

@@ -195,11 +193,25 @@ bool ws_sdcard::ParseDigitalIOAdd(
195193
float period, bool value, const char *sample_mode, const char *direction,
196194
const char *pull) {
197195
bool rc = true;
196+
if (!strcmp(pin, UNKNOWN_VALUE) == 0) {
197+
WS_DEBUG_PRINTLN("[SD] Parsing Error: Digital pin name not found!");
198+
return false;
199+
}
198200
strcpy(msg_DigitalIOAdd.pin_name, pin);
201+
202+
if (period == 0.0) {
203+
WS_DEBUG_PRINTLN("[SD] Parsing Error: Digital pin period not found!");
204+
return false;
205+
}
199206
msg_DigitalIOAdd.period = period;
200207
msg_DigitalIOAdd.value = value;
208+
201209
// Determine the sample mode
202-
if (strcmp(sample_mode, "TIMER") == 0) {
210+
if (strcmp(sample_mode, UNKNOWN_VALUE) == 0) {
211+
WS_DEBUG_PRINTLN(
212+
"[SD] Parsing Error: Digital pin's sample mode not found!");
213+
return false;
214+
} else if (strcmp(sample_mode, "TIMER") == 0) {
203215
msg_DigitalIOAdd.sample_mode =
204216
wippersnapper_digitalio_DigitalIOSampleMode_DIGITAL_IO_SAMPLE_MODE_TIMER;
205217
} else if (strcmp(sample_mode, "EVENT") == 0) {
@@ -211,7 +223,10 @@ bool ws_sdcard::ParseDigitalIOAdd(
211223
}
212224

213225
// Determine the pin direction and pull
214-
if (strcmp(direction, "INPUT") == 0) {
226+
if (strcmp(direction, UNKNOWN_VALUE) == 0) {
227+
WS_DEBUG_PRINTLN("[SD] Parsing Error: Digital pin's direction not found!");
228+
return false;
229+
} else if (strcmp(direction, "INPUT") == 0) {
215230
if (pull != nullptr) {
216231
msg_DigitalIOAdd.gpio_direction =
217232
wippersnapper_digitalio_DigitalIODirection_DIGITAL_IO_DIRECTION_INPUT_PULL_UP;
@@ -321,7 +336,7 @@ bool ws_sdcard::ParseDS18X20Add(
321336
bool ws_sdcard::PushSignalToSharedBuffer(
322337
wippersnapper_signal_BrokerToDevice &msg_signal) {
323338
// Create a temporary buffer to hold the encoded signal message
324-
std::vector<uint8_t> tempBuf(128);
339+
std::vector<uint8_t> tempBuf(512);
325340
size_t tempBufSz;
326341

327342
// Get the encoded size of the signal message first so we can resize the
@@ -357,8 +372,15 @@ bool ws_sdcard::PushSignalToSharedBuffer(
357372
/**************************************************************************/
358373
bool ws_sdcard::CreateNewLogFile() {
359374
File32 file;
375+
// Generate a name for the new log file using the RTC's timestamp
360376
String logFilename = "log_" + String(GetTimestamp()) + ".json";
361-
_log_filename = logFilename.c_str();
377+
static char log_filename_buffer[256];
378+
strncpy(log_filename_buffer, logFilename.c_str(),
379+
sizeof(log_filename_buffer) - 1);
380+
log_filename_buffer[sizeof(log_filename_buffer) - 1] = '\0';
381+
_log_filename = log_filename_buffer;
382+
383+
// Attempt to create the new log file
362384
if (!file.open(_log_filename, FILE_WRITE))
363385
return false;
364386
WS_DEBUG_PRINT("[SD] Created new log file on SD card: ");
@@ -375,18 +397,17 @@ bool ws_sdcard::CreateNewLogFile() {
375397
*/
376398
/**************************************************************************/
377399
bool ws_sdcard::parseConfigFile() {
378-
File32 file_config;
379-
JsonDocument doc;
380-
int max_json_len =
381-
2048; // TODO: It's possible this is too small - what's the max size?
400+
int max_json_len = 4096;
382401

383402
// Attempt to open and deserialize the JSON config file
403+
File32 file_config;
384404
DeserializationError error;
405+
JsonDocument doc;
385406
#ifndef OFFLINE_MODE_DEBUG
386-
WS_DEBUG_PRINTLN("[SD] Parsing config.json from SD card...");
407+
WS_DEBUG_PRINTLN("[SD] Parsing config.txt from SD card...");
387408
if (!_sd.exists("config.txt")) {
388409
WS_DEBUG_PRINTLN(
389-
"[SD] FATAL Error - config.json file not found on SD Card!");
410+
"[SD] FATAL Error - config.txt file not found on SD Card!");
390411
return false;
391412
}
392413
file_config = _sd.open("config.txt", O_RDONLY);
@@ -427,14 +448,14 @@ bool ws_sdcard::parseConfigFile() {
427448
}
428449

429450
// Mock the check-in process using the JSON's values
430-
CheckIn(exportedFromDevice["totalGPIOPins"],
431-
exportedFromDevice["totalAnalogPins"],
432-
exportedFromDevice["referenceVoltage"]);
451+
CheckIn(exportedFromDevice["totalGPIOPins"] | 0,
452+
exportedFromDevice["totalAnalogPins"] | 0,
453+
exportedFromDevice["referenceVoltage"] | 0.0);
433454

434-
setStatusLEDBrightness(exportedFromDevice["statusLEDBrightness"]);
455+
setStatusLEDBrightness(exportedFromDevice["statusLEDBrightness"] | 0.3);
435456

436457
// Initialize and configure RTC
437-
const char *json_rtc = exportedFromDevice["rtc"];
458+
const char *json_rtc = exportedFromDevice["rtc"] | "SOFT_RTC";
438459
if (json_rtc == nullptr) {
439460
WS_DEBUG_PRINTLN("[SD] FATAL Parsing error - rtc field not found in "
440461
"configuration JSON, unable to configure RTC!");
@@ -474,12 +495,13 @@ bool ws_sdcard::parseConfigFile() {
474495
"[SD] DigitalIO component found, decoding JSON to PB...");
475496
wippersnapper_digitalio_DigitalIOAdd msg_DigitalIOAdd =
476497
wippersnapper_digitalio_DigitalIOAdd_init_default;
477-
if (!ParseDigitalIOAdd(msg_DigitalIOAdd, component["pinName"],
478-
component["period"], component["value"],
479-
component["sampleMode"], component["direction"],
480-
component["pull"])) {
481-
WS_DEBUG_PRINTLN(
482-
"[SD] FATAL Parsing error - Unable to parse DigitalIO component!");
498+
if (!ParseDigitalIOAdd(
499+
msg_DigitalIOAdd, component["pinName"] | UNKNOWN_VALUE,
500+
component["period"] | 0.0, component["value"],
501+
component["sampleMode"] | UNKNOWN_VALUE,
502+
component["direction"] | UNKNOWN_VALUE, component["pull"])) {
503+
WS_DEBUG_PRINTLN("[SD] FATAL Parsing error - Unable to parse "
504+
"DigitalIO component!");
483505
return false;
484506
}
485507
msg_signal_b2d.which_payload =
@@ -693,6 +715,14 @@ bool ws_sdcard::LogJSONDoc(JsonDocument &doc) {
693715
Serial.print("\n"); // JSONL format specifier
694716
#endif
695717
_sz_log_file = szJson + 2; // +2 bytes for "\n"
718+
719+
if (_sz_log_file > MAX_LOG_FILE_SZ) {
720+
WS_DEBUG_PRINTLN("[SD] Log file size has exceeded maximum size, creating "
721+
"a new file...");
722+
CreateNewLogFile();
723+
return false;
724+
}
725+
696726
return true;
697727
}
698728

@@ -773,19 +803,15 @@ bool ws_sdcard::LogGPIOSensorEventToSD(
773803
/**************************************************************************/
774804
bool ws_sdcard::LogDS18xSensorEventToSD(
775805
wippersnapper_ds18x20_Ds18x20Event *event_msg) {
776-
// Get the RTC's timestamp
777-
uint32_t timestamp = GetTimestamp();
778-
779-
// Create the JSON document
780806
JsonDocument doc;
781807
// Iterate over the event message's sensor events
782808
for (int i = 0; i < event_msg->sensor_events_count; i++) {
809+
uint32_t timestamp = GetTimestamp();
783810
doc["timestamp"] = timestamp;
784811
doc["pin"] = event_msg->onewire_pin;
785812
doc["value"] = event_msg->sensor_events[i].value.float_value;
786813
doc["si_unit"] = SensorTypeToString(event_msg->sensor_events[i].type);
787-
serializeJson(doc, Serial);
788-
Serial.println("");
814+
LogJSONDoc(doc);
789815
}
790816
return true;
791817
}
@@ -799,7 +825,7 @@ bool ws_sdcard::LogDS18xSensorEventToSD(
799825
@returns True if the provided JSON string is valid, False otherwise.
800826
*/
801827
/**************************************************************************/
802-
bool ws_sdcard::validateJson(const char *input) {
828+
bool ws_sdcard::ValidateJSON(const char *input) {
803829
JsonDocument doc, filter;
804830

805831
DeserializationError error =
@@ -931,12 +957,12 @@ bool ws_sdcard::waitForSerialConfig() {
931957

932958
// Attempt to validate the string as JSON
933959
if (!_use_test_data) {
934-
if (!validateJson(_serialInput.c_str())) {
960+
if (!ValidateJSON(_serialInput.c_str())) {
935961
WS_DEBUG_PRINTLN("[SD] Invalid JSON string received!");
936962
return false;
937963
}
938964
} else {
939-
if (!validateJson(json_test_data)) {
965+
if (!ValidateJSON(json_test_data)) {
940966
WS_DEBUG_PRINTLN("[SD] Invalid JSON string received!");
941967
return false;
942968
}

src/provisioning/sdcard/ws_sdcard.h

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,9 @@
1919
#include "StreamUtils.h"
2020
#include "Wippersnapper_V2.h"
2121

22-
#define SD_FAT_TYPE 3 ///< SdFat type (3 = SdFs)
23-
#define MAX_LOG_FILE_SZ 500 ///< Maximum log file size of 500 bytes
22+
#define SD_FAT_TYPE 3 ///< SdFat type (3 = SdFs)
23+
#define MAX_LOG_FILE_SZ 500 ///< Maximum log file size of 500 bytes
24+
#define UNKNOWN_VALUE "unknown" ///< Unknown JSON field value
2425

2526
// forward decl.
2627
class Wippersnapper_V2;
@@ -42,7 +43,6 @@ class ws_sdcard {
4243
#endif
4344
bool CreateNewLogFile();
4445
bool isModeOffline() { return is_mode_offline; }
45-
4646
bool LogGPIOSensorEventToSD(uint8_t pin, float value,
4747
wippersnapper_sensor_SensorType read_type);
4848
bool LogGPIOSensorEventToSD(uint8_t pin, bool value,
@@ -52,15 +52,16 @@ class ws_sdcard {
5252
bool LogDS18xSensorEventToSD(wippersnapper_ds18x20_Ds18x20Event *event_msg);
5353

5454
private:
55+
bool ValidateJSON(const char *input);
56+
void CheckIn(uint8_t max_digital_pins, uint8_t max_analog_pins,
57+
float ref_voltage);
58+
5559
bool ConfigureRTC(const char *rtc_type);
5660
uint32_t GetTimestamp();
5761
bool InitDS1307();
5862
bool InitDS3231();
5963
bool InitPCF8523();
6064
bool InitSoftRTC();
61-
bool validateJson(const char *input);
62-
void CheckIn(uint8_t max_digital_pins, uint8_t max_analog_pins,
63-
float ref_voltage);
6465

6566
wippersnapper_sensor_SensorType ParseSensorType(const char *sensor_type);
6667
bool ParseDigitalIOAdd(wippersnapper_digitalio_DigitalIOAdd &msg_DigitalIOAdd,

0 commit comments

Comments
 (0)