From 535d9f60e50404db84a3ac8eb3c6f06663a3de17 Mon Sep 17 00:00:00 2001 From: David Taylor Date: Wed, 4 Oct 2023 15:18:13 +1100 Subject: [PATCH] Added a second message carrying device & comms info. Removed support for sending MQTT messages from modem filesystem - that needs more work. Added constants for CLI command results. Fixed c1 pwr 0 command so it issues AT+CPWROFF before removing power. Added sd rm, c1 rm, c1 ls commands. Bumped version to 1.0.7. Moved voltage readings to 2nd message, simplified network registration wait loop and extended wait time to 90s. --- firmware/wombat/gen_version_h.py | 2 +- firmware/wombat/include/cli/CLI.h | 4 + firmware/wombat/src/CAT_M1.cpp | 2 +- firmware/wombat/src/SensorTask.cpp | 100 ++++++++++++------ firmware/wombat/src/Utils.cpp | 30 +++--- .../device_config/acquisition_intervals.cpp | 9 +- .../src/cli/device_config/cli_power.cpp | 3 +- .../src/cli/device_config/config_cli.cpp | 15 +-- .../wombat/src/cli/device_config/ftp_cli.cpp | 17 +-- .../wombat/src/cli/device_config/mqtt_cli.cpp | 19 ++-- .../wombat/src/cli/peripherals/cat-m1.cpp | 60 ++++++++--- .../wombat/src/cli/peripherals/sd_card.cpp | 36 ++++--- firmware/wombat/src/cli/peripherals/sdi12.cpp | 8 +- firmware/wombat/src/mqtt_stack.cpp | 45 +++----- firmware/wombat/src/uplinks.cpp | 2 +- 15 files changed, 215 insertions(+), 137 deletions(-) diff --git a/firmware/wombat/gen_version_h.py b/firmware/wombat/gen_version_h.py index 46053e6..dfee0f1 100644 --- a/firmware/wombat/gen_version_h.py +++ b/firmware/wombat/gen_version_h.py @@ -33,7 +33,7 @@ # NOTE: This is the canonical definition of the firmware version. This is baked into the firmware # and placed into the wombat.sha1 file. -_VERSION_NUM = '1.0.6' +_VERSION_NUM = '1.0.7' _VERSION_H = 'include/version.h' commit_const = 'const char* commit_id = "unknown";' diff --git a/firmware/wombat/include/cli/CLI.h b/firmware/wombat/include/cli/CLI.h index 5564237..242127c 100644 --- a/firmware/wombat/include/cli/CLI.h +++ b/firmware/wombat/include/cli/CLI.h @@ -23,6 +23,10 @@ #define CLI_TAG "cli" +const char OK_RESPONSE[] = "\r\nOK\r\n"; +const char ERROR_RESPONSE[] = "\r\nERROR\r\n"; +const char INVALID_CMD_RESPONSE[] = "\r\nERROR: Invalid command\r\n"; + /** * @brief FreeRTOS command line interface. * diff --git a/firmware/wombat/src/CAT_M1.cpp b/firmware/wombat/src/CAT_M1.cpp index d38e24a..7b10e8f 100644 --- a/firmware/wombat/src/CAT_M1.cpp +++ b/firmware/wombat/src/CAT_M1.cpp @@ -106,7 +106,7 @@ bool CAT_M1::make_ready() { r5.autoTimeZoneForBegin(true); r5.enableAtDebugging(); - //r5.enableDebugging(); + r5.enableDebugging(); // This is relatively benign - it enables the network indicator GPIO pin, set error message format, etc. // It does close all open sockets, but there should not be any open sockets at this point so that is ok. diff --git a/firmware/wombat/src/SensorTask.cpp b/firmware/wombat/src/SensorTask.cpp index 568a5cd..4a94997 100644 --- a/firmware/wombat/src/SensorTask.cpp +++ b/firmware/wombat/src/SensorTask.cpp @@ -170,55 +170,38 @@ void sensor_task(void) { const char *timestamp = iso8601(); msg["timestamp"] = timestamp; + + //--------------------- + // source_ids section + //--------------------- JsonObject source_ids = msg.createNestedObject("source_ids"); source_ids["serial_no"] = DeviceConfig::get().node_id; constexpr size_t buffer_sz = 48; char buffer[buffer_sz + 1]; memset(buffer, 0, sizeof(buffer)); - // This format helps keep the message under 1024 bytes when there are a lot of SDI-12 sensors attached. snprintf(buffer, buffer_sz, "%d.%d.%d %s %s %s", ver_major, ver_minor, ver_update, repo_branch, commit_id, repo_status); source_ids["firmware"] = buffer; - JsonArray timeseries_array = msg.createNestedArray("timeseries"); - - // - // Node sensors - // - JsonObject ts_entry = timeseries_array.createNestedObject(); - ts_entry["name"] = "battery (v)"; - ts_entry["value"] = BatteryMonitor::get_voltage(); - - ts_entry = timeseries_array.createNestedObject(); - ts_entry["name"] = "solar (v)"; - ts_entry["value"] = SolarMonitor::get_voltage(); if (r5_ok) { - signal_quality sq; - SARA_R5_error_t r5_err = r5.getExtSignalQuality(sq); - - if (!r5_err) { - ts_entry = timeseries_array.createNestedObject(); - ts_entry["name"] = "rsrq"; - ts_entry["value"] = sq.rsrq; - - ts_entry = timeseries_array.createNestedObject(); - ts_entry["name"] = "rsrp"; - ts_entry["value"] = sq.rsrp; - } - String ccid = r5.getCCID(); if (ccid.length() > 0) { source_ids["ccid"] = ccid; } } + //--------------------- + // timeseries section + //--------------------- + JsonArray timeseries_array = msg.createNestedArray("timeseries"); + // // Pulse counter // uint32_t pc = get_pulse_count(); uint32_t sp = get_shortest_pulse(); - ts_entry = timeseries_array.createNestedObject(); + JsonObject ts_entry = timeseries_array.createNestedObject(); ts_entry["name"] = "pulse_count"; ts_entry["value"] = pc; @@ -240,6 +223,61 @@ void sensor_task(void) { sdi12.end(); + String str; + serializeJson(msg, str); + ESP_LOGI(TAG, "Msg:\r\n%s\r\n", str.c_str()); + + if (spiffs_ok) { + // Write the message to a file so it can be sent on the next uplink cycle. + static const size_t MAX_FNAME = 32; + static char filename[MAX_FNAME + 1]; + + snprintf(filename, MAX_FNAME, "/%s%s.json", DeviceConfig::getMsgFilePrefix(), timestamp); + ESP_LOGI(TAG, "Creating unsent msg file [%s]", filename); + File f = SPIFFS.open(filename, FILE_WRITE); + serializeJson(msg, f); + f.close(); + } else { + log_to_sdcard("[E] spiffs_ok is false, no message stored"); + } + + // Append the message to a file on the SD card. + if (SDCardInterface::is_ready()) { + snprintf(g_buffer, MAX_G_BUFFER, "%s,\n", str.c_str()); + SDCardInterface::append_to_file(sd_card_datafile_name, g_buffer); + } + + //--------------------- + // Wombat status/info message + //--------------------- + + timeseries_array.clear(); + // + // Node sensors + // + ts_entry = timeseries_array.createNestedObject(); + ts_entry["name"] = "battery (v)"; + ts_entry["value"] = BatteryMonitor::get_voltage(); + + ts_entry = timeseries_array.createNestedObject(); + ts_entry["name"] = "solar (v)"; + ts_entry["value"] = SolarMonitor::get_voltage(); + + if (r5_ok) { + signal_quality sq; + SARA_R5_error_t r5_err = r5.getExtSignalQuality(sq); + + if (!r5_err) { + ts_entry = timeseries_array.createNestedObject(); + ts_entry["name"] = "rsrq"; + ts_entry["value"] = sq.rsrq; + + ts_entry = timeseries_array.createNestedObject(); + ts_entry["name"] = "rsrp"; + ts_entry["value"] = sq.rsrp; + } + } + if (SDCardInterface::is_ready()) { auto total_mb = SD.cardSize() / 1024 / 1024; auto used_mb = SD.usedBytes() / 1024 / 1024; @@ -253,7 +291,7 @@ void sensor_task(void) { ts_entry["value"] = total_mb - used_mb; } - String str; + str.clear(); serializeJson(msg, str); ESP_LOGI(TAG, "Msg:\r\n%s\r\n", str.c_str()); @@ -262,7 +300,7 @@ void sensor_task(void) { static const size_t MAX_FNAME = 32; static char filename[MAX_FNAME + 1]; - snprintf(filename, MAX_FNAME, "/%s%s.json", DeviceConfig::getMsgFilePrefix(), timestamp); + snprintf(filename, MAX_FNAME, "/%sinfo_%s.json", DeviceConfig::getMsgFilePrefix(), timestamp); ESP_LOGI(TAG, "Creating unsent msg file [%s]", filename); File f = SPIFFS.open(filename, FILE_WRITE); serializeJson(msg, f); @@ -273,7 +311,7 @@ void sensor_task(void) { // Append the message to a file on the SD card. if (SDCardInterface::is_ready()) { - snprintf(g_buffer, MAX_G_BUFFER, "%s,\n", str.c_str()); - SDCardInterface::append_to_file(sd_card_datafile_name, g_buffer); + str += ",\n"; + SDCardInterface::append_to_file(sd_card_datafile_name, str.c_str()); } } diff --git a/firmware/wombat/src/Utils.cpp b/firmware/wombat/src/Utils.cpp index 058a406..ac2f39c 100644 --- a/firmware/wombat/src/Utils.cpp +++ b/firmware/wombat/src/Utils.cpp @@ -402,22 +402,24 @@ bool connect_to_internet(void) { // Network registration takes 4 seconds at best. ESP_LOGI(TAG, "Waiting for network registration"); - for (int i = 0; i < 3; i++) { - int attempts = 0; - while (reg_status != SARA_R5_REGISTRATION_HOME && attempts < 4) { - reg_status = r5.registration(); - delay(20); - if (reg_status == SARA_R5_REGISTRATION_INVALID) { - ESP_LOGI(TAG, "ESP registration query failed"); - log_to_sdcard("[E] ESP registration query failed"); - return false; - } + int attempts = 0; + while (reg_status != SARA_R5_REGISTRATION_HOME && attempts < 45) { + reg_status = r5.registration(); + delay(20); + if (reg_status == SARA_R5_REGISTRATION_INVALID) { + ESP_LOGI(TAG, "ESP registration query failed"); + log_to_sdcard("[E] ESP registration query failed"); + return false; + } - ESP_LOGI(TAG, "ESP registration status = %d", reg_status); - r5.bufferedPoll(); - delay(2000); - attempts++; + ESP_LOGI(TAG, "ESP registration status = %d", reg_status); + r5.bufferedPoll(); + if (reg_status == SARA_R5_REGISTRATION_HOME) { + break; } + + delay(2000); + attempts++; } if (reg_status != SARA_R5_REGISTRATION_HOME) { diff --git a/firmware/wombat/src/cli/device_config/acquisition_intervals.cpp b/firmware/wombat/src/cli/device_config/acquisition_intervals.cpp index 7f632bb..010362d 100644 --- a/firmware/wombat/src/cli/device_config/acquisition_intervals.cpp +++ b/firmware/wombat/src/cli/device_config/acquisition_intervals.cpp @@ -10,6 +10,7 @@ #include "cli/device_config/acquisition_intervals.h" #include "globals.h" #include "Utils.h" +#include "cli/CLI.h" #define TAG "acquisition_intervals" @@ -126,7 +127,7 @@ BaseType_t CLIConfigIntervals::enter_cli(char *pcWriteBuffer, config.setMeasureInterval(i); if (i == config.getMeasureInterval()) { - strncpy(pcWriteBuffer, "OK\r\n", xWriteBufferLen - 1); + strncpy(pcWriteBuffer, OK_RESPONSE, xWriteBufferLen - 1); } else { strncpy(pcWriteBuffer, "ERROR: set measure interval " "failed\r\n", xWriteBufferLen - 1); @@ -152,7 +153,7 @@ BaseType_t CLIConfigIntervals::enter_cli(char *pcWriteBuffer, config.setUplinkInterval(i); if (i == config.getUplinkInterval()) { - strncpy(pcWriteBuffer, "OK\r\n", xWriteBufferLen - 1); + strncpy(pcWriteBuffer, OK_RESPONSE, xWriteBufferLen - 1); } else { strncpy(pcWriteBuffer, "ERROR: set uplink interval " "failed\r\n", xWriteBufferLen - 1); @@ -175,7 +176,7 @@ BaseType_t CLIConfigIntervals::enter_cli(char *pcWriteBuffer, config.setSleepAdjustment(sleepMultiplier); if (sleepMultiplier == config.getSleepAdjustment()) { - strncpy(pcWriteBuffer, "OK\r\n", xWriteBufferLen - 1); + strncpy(pcWriteBuffer, OK_RESPONSE, xWriteBufferLen - 1); } else { ESP_LOGE(TAG, "%f != %f", sleepMultiplier, config.getSleepAdjustment()); strncpy(pcWriteBuffer, "ERROR: set clock multiplier failed\r\n", xWriteBufferLen - 1); @@ -188,6 +189,6 @@ BaseType_t CLIConfigIntervals::enter_cli(char *pcWriteBuffer, } } - strncpy(pcWriteBuffer, "Syntax error\r\n", xWriteBufferLen - 1); + strncpy(pcWriteBuffer, INVALID_CMD_RESPONSE, xWriteBufferLen - 1); return pdFALSE; } diff --git a/firmware/wombat/src/cli/device_config/cli_power.cpp b/firmware/wombat/src/cli/device_config/cli_power.cpp index a0cf4f0..c6f5b41 100644 --- a/firmware/wombat/src/cli/device_config/cli_power.cpp +++ b/firmware/wombat/src/cli/device_config/cli_power.cpp @@ -10,6 +10,7 @@ #include #include "cli/FreeRTOS_CLI.h" +#include "cli/CLI.h" #include "power_monitoring/battery.h" #include "power_monitoring/solar.h" @@ -72,6 +73,6 @@ BaseType_t CLIPower::enter_cli(char *pcWriteBuffer, size_t xWriteBufferLen, } } - strncpy(pcWriteBuffer, "ERROR: Invalid command\r\n", xWriteBufferLen - 1); + strncpy(pcWriteBuffer, INVALID_CMD_RESPONSE, xWriteBufferLen - 1); return pdFALSE; } diff --git a/firmware/wombat/src/cli/device_config/config_cli.cpp b/firmware/wombat/src/cli/device_config/config_cli.cpp index ee6b42e..2d08868 100644 --- a/firmware/wombat/src/cli/device_config/config_cli.cpp +++ b/firmware/wombat/src/cli/device_config/config_cli.cpp @@ -10,6 +10,7 @@ #include #include "cli/FreeRTOS_CLI.h" +#include "cli/CLI.h" #include "cli/device_config/config_cli.h" #include "CAT_M1.h" #include "Utils.h" @@ -74,14 +75,14 @@ BaseType_t CLIConfig::enter_cli(char *pcWriteBuffer, size_t xWriteBufferLen, if (!strncmp("list", param, paramLen)) { response_buffer_.clear(); config.dumpConfig(response_buffer_); - response_buffer_.println("\r\nOK"); + response_buffer_.print(OK_RESPONSE); return pdTRUE; } if (!strncmp("load", param, paramLen)) { config.load(); config.dumpConfig(response_buffer_); - response_buffer_.println("\r\nOK"); + response_buffer_.print(OK_RESPONSE); return pdTRUE; } @@ -138,9 +139,9 @@ BaseType_t CLIConfig::enter_cli(char *pcWriteBuffer, size_t xWriteBufferLen, } if (success) { - strncpy(pcWriteBuffer, "\r\nOK\r\n", xWriteBufferLen - 1); + strncpy(pcWriteBuffer, OK_RESPONSE, xWriteBufferLen - 1); } else { - strncpy(pcWriteBuffer, "\r\nERROR\r\n", xWriteBufferLen - 1); + strncpy(pcWriteBuffer, ERROR_RESPONSE, xWriteBufferLen - 1); } return pdFALSE; } @@ -157,9 +158,9 @@ BaseType_t CLIConfig::enter_cli(char *pcWriteBuffer, size_t xWriteBufferLen, } if (success) { - strncpy(pcWriteBuffer, "\r\nOK\r\n", xWriteBufferLen - 1); + strncpy(pcWriteBuffer, OK_RESPONSE, xWriteBufferLen - 1); } else { - strncpy(pcWriteBuffer, "\r\nERROR\r\n", xWriteBufferLen - 1); + strncpy(pcWriteBuffer, ERROR_RESPONSE, xWriteBufferLen - 1); } return pdFALSE; } @@ -175,6 +176,6 @@ BaseType_t CLIConfig::enter_cli(char *pcWriteBuffer, size_t xWriteBufferLen, return pdTRUE; } - strncpy(pcWriteBuffer, "ERROR: Invalid command\r\n", xWriteBufferLen - 1); + strncpy(pcWriteBuffer, INVALID_CMD_RESPONSE, xWriteBufferLen - 1); return pdFALSE; } diff --git a/firmware/wombat/src/cli/device_config/ftp_cli.cpp b/firmware/wombat/src/cli/device_config/ftp_cli.cpp index 580859c..1b08dad 100644 --- a/firmware/wombat/src/cli/device_config/ftp_cli.cpp +++ b/firmware/wombat/src/cli/device_config/ftp_cli.cpp @@ -10,6 +10,7 @@ #include #include "cli/FreeRTOS_CLI.h" +#include "cli/CLI.h" #include "cli/device_config/ftp_cli.h" #include "ftp_stack.h" @@ -90,7 +91,7 @@ BaseType_t CLIFTP::enter_cli(char *pcWriteBuffer, size_t xWriteBufferLen, strncpy(pcWriteBuffer, param, paramLen); pcWriteBuffer[paramLen] = 0; config.setFtpHost(pcWriteBuffer); - strncpy(pcWriteBuffer, "OK\r\n", xWriteBufferLen - 1); + strncpy(pcWriteBuffer, OK_RESPONSE, xWriteBufferLen - 1); return pdFALSE; } @@ -106,7 +107,7 @@ BaseType_t CLIFTP::enter_cli(char *pcWriteBuffer, size_t xWriteBufferLen, strncpy(pcWriteBuffer, param, paramLen); pcWriteBuffer[paramLen] = 0; config.setFtpUser(pcWriteBuffer); - strncpy(pcWriteBuffer, "OK\r\n", xWriteBufferLen - 1); + strncpy(pcWriteBuffer, OK_RESPONSE, xWriteBufferLen - 1); return pdFALSE; } @@ -122,7 +123,7 @@ BaseType_t CLIFTP::enter_cli(char *pcWriteBuffer, size_t xWriteBufferLen, strncpy(pcWriteBuffer, param, paramLen); pcWriteBuffer[paramLen] = 0; config.setFtpPassword(pcWriteBuffer); - strncpy(pcWriteBuffer, "OK\r\n", xWriteBufferLen - 1); + strncpy(pcWriteBuffer, OK_RESPONSE, xWriteBufferLen - 1); return pdFALSE; } @@ -133,13 +134,13 @@ BaseType_t CLIFTP::enter_cli(char *pcWriteBuffer, size_t xWriteBufferLen, if (!strncmp("login", param, paramLen)) { bool rc = ftp_login(); - snprintf(pcWriteBuffer, xWriteBufferLen - 1, "\r\n%s\r\n", rc ? "OK" : "ERROR"); + snprintf(pcWriteBuffer, xWriteBufferLen - 1, "%s", rc ? OK_RESPONSE : ERROR_RESPONSE); return pdFALSE; } if (!strncmp("logout", param, paramLen)) { bool rc = ftp_logout(); - snprintf(pcWriteBuffer, xWriteBufferLen - 1, "\r\n%s\r\n", rc ? "OK" : "ERROR"); + snprintf(pcWriteBuffer, xWriteBufferLen - 1, "%s", rc ? OK_RESPONSE : ERROR_RESPONSE); return pdFALSE; } @@ -151,7 +152,7 @@ BaseType_t CLIFTP::enter_cli(char *pcWriteBuffer, size_t xWriteBufferLen, pcWriteBuffer[paramLen] = 0; bool rc = ftp_get(pcWriteBuffer); - snprintf(pcWriteBuffer, xWriteBufferLen - 1, "\r\n%s\r\n", rc ? "OK" : "XERROR"); + snprintf(pcWriteBuffer, xWriteBufferLen - 1, "%s", rc ? OK_RESPONSE : ERROR_RESPONSE); return pdFALSE; } @@ -168,7 +169,7 @@ BaseType_t CLIFTP::enter_cli(char *pcWriteBuffer, size_t xWriteBufferLen, pcWriteBuffer[paramLen] = 0; bool rc = ftp_upload_file(pcWriteBuffer); - snprintf(pcWriteBuffer, xWriteBufferLen - 1, "\r\n%s\r\n", rc ? "OK" : "ERROR"); + snprintf(pcWriteBuffer, xWriteBufferLen - 1, "%s", rc ? OK_RESPONSE : ERROR_RESPONSE); return pdFALSE; } @@ -178,6 +179,6 @@ BaseType_t CLIFTP::enter_cli(char *pcWriteBuffer, size_t xWriteBufferLen, } } - strncpy(pcWriteBuffer, "ERROR: Invalid command\r\n", xWriteBufferLen - 1); + strncpy(pcWriteBuffer, INVALID_CMD_RESPONSE, xWriteBufferLen - 1); return pdFALSE; } diff --git a/firmware/wombat/src/cli/device_config/mqtt_cli.cpp b/firmware/wombat/src/cli/device_config/mqtt_cli.cpp index b512aaa..8b3cc82 100644 --- a/firmware/wombat/src/cli/device_config/mqtt_cli.cpp +++ b/firmware/wombat/src/cli/device_config/mqtt_cli.cpp @@ -10,6 +10,7 @@ #include #include "cli/FreeRTOS_CLI.h" +#include "cli/CLI.h" #include "cli/device_config/mqtt_cli.h" #include "mqtt_stack.h" @@ -95,7 +96,7 @@ BaseType_t CLIMQTT::enter_cli(char *pcWriteBuffer, size_t xWriteBufferLen, strncpy(pcWriteBuffer, param, paramLen); pcWriteBuffer[paramLen] = 0; config.setMqttHost(pcWriteBuffer); - strncpy(pcWriteBuffer, "OK\r\n", xWriteBufferLen - 1); + strncpy(pcWriteBuffer, OK_RESPONSE, xWriteBufferLen - 1); return pdFALSE; } @@ -121,7 +122,7 @@ BaseType_t CLIMQTT::enter_cli(char *pcWriteBuffer, size_t xWriteBufferLen, } else { config.setMqttPort(i); if (i == config.getMqttPort()) { - strncpy(pcWriteBuffer, "OK\r\n", xWriteBufferLen - 1); + strncpy(pcWriteBuffer, OK_RESPONSE, xWriteBufferLen - 1); } else { strncpy(pcWriteBuffer, "ERROR: set MQTT port failed\r\n", xWriteBufferLen - 1); } @@ -137,7 +138,7 @@ BaseType_t CLIMQTT::enter_cli(char *pcWriteBuffer, size_t xWriteBufferLen, strncpy(pcWriteBuffer, param, paramLen); pcWriteBuffer[paramLen] = 0; config.setMqttUser(pcWriteBuffer); - strncpy(pcWriteBuffer, "OK\r\n", xWriteBufferLen - 1); + strncpy(pcWriteBuffer, OK_RESPONSE, xWriteBufferLen - 1); return pdFALSE; } @@ -153,7 +154,7 @@ BaseType_t CLIMQTT::enter_cli(char *pcWriteBuffer, size_t xWriteBufferLen, strncpy(pcWriteBuffer, param, paramLen); pcWriteBuffer[paramLen] = 0; config.setMqttPassword(pcWriteBuffer); - strncpy(pcWriteBuffer, "OK\r\n", xWriteBufferLen - 1); + strncpy(pcWriteBuffer, OK_RESPONSE, xWriteBufferLen - 1); return pdFALSE; } @@ -173,7 +174,7 @@ BaseType_t CLIMQTT::enter_cli(char *pcWriteBuffer, size_t xWriteBufferLen, strncpy(config.mqtt_topic_template, param, paramLen); config.mqtt_topic_template[paramLen] = 0; - strncpy(pcWriteBuffer, "OK\r\n", xWriteBufferLen - 1); + strncpy(pcWriteBuffer, OK_RESPONSE, xWriteBufferLen - 1); return pdFALSE; } @@ -184,23 +185,23 @@ BaseType_t CLIMQTT::enter_cli(char *pcWriteBuffer, size_t xWriteBufferLen, if (!strncmp("login", param, paramLen)) { bool rc = mqtt_login(); - snprintf(pcWriteBuffer, xWriteBufferLen-1, "\r\n%s\r\n", rc ? "OK" : "ERROR"); + snprintf(pcWriteBuffer, xWriteBufferLen-1, "%s", rc ? OK_RESPONSE : ERROR_RESPONSE); return pdFALSE; } if (!strncmp("logout", param, paramLen)) { bool rc = mqtt_logout(); - snprintf(pcWriteBuffer, xWriteBufferLen-1, "\r\n%s\r\n", rc ? "OK" : "ERROR"); + snprintf(pcWriteBuffer, xWriteBufferLen-1, "%s", rc ? OK_RESPONSE : ERROR_RESPONSE); return pdFALSE; } if (!strncmp("publish", param, paramLen)) { String topic(config.mqtt_topic_template); bool rc = mqtt_publish(topic, "ABCDEF", 6); - snprintf(pcWriteBuffer, xWriteBufferLen-1, "\r\n%s\r\n", rc ? "OK" : "ERROR"); + snprintf(pcWriteBuffer, xWriteBufferLen-1, "%s", rc ? OK_RESPONSE : ERROR_RESPONSE); return pdFALSE; } - strncpy(pcWriteBuffer, "ERROR: Invalid command\r\n", xWriteBufferLen - 1); + strncpy(pcWriteBuffer, INVALID_CMD_RESPONSE, xWriteBufferLen - 1); return pdFALSE; } diff --git a/firmware/wombat/src/cli/peripherals/cat-m1.cpp b/firmware/wombat/src/cli/peripherals/cat-m1.cpp index b63767b..4e3d392 100644 --- a/firmware/wombat/src/cli/peripherals/cat-m1.cpp +++ b/firmware/wombat/src/cli/peripherals/cat-m1.cpp @@ -134,36 +134,70 @@ static int get_response(uint32_t timeout = 500) { if (!strncmp("pwr", param, paramLen)) { const char* pwrState = FreeRTOS_CLIGetParameter(pcCommandString, 2, ¶mLen); if(pwrState != nullptr && paramLen > 0) { + if (*pwrState == '0') { + if (r5_ok) { + r5.modulePowerOff(); + } + } + cat_m1.power_supply(*pwrState == '1'); + + snprintf(pcWriteBuffer, xWriteBufferLen-1, OK_RESPONSE); + return pdFALSE; } + } - if (*pwrState == '0') { - if (r5_ok) { - r5.modulePowerOff(); - } + if (!strncmp("ls", param, paramLen)) { + if ( ! r5_ok) { + snprintf(pcWriteBuffer, xWriteBufferLen-1, "\r\nERROR: modem not ready\r\n"); + return pdFALSE; + } + + LTE_Serial.println("AT+ULSTFILE=0"); + memset(g_buffer, 0, MAX_G_BUFFER); + auto rc = get_response(2000); + if (rc < 0) { + snprintf(pcWriteBuffer, xWriteBufferLen-1, "\r\nERROR: timeout\r\n"); + return pdFALSE; + } + + response_buffer_.println(g_buffer); + return pdTRUE; + } + + if (!strncmp("rm", param, paramLen)) { + if ( ! r5_ok) { + snprintf(pcWriteBuffer, xWriteBufferLen-1, "\r\nERROR: modem not ready\r\n"); + return pdFALSE; + } + + const char *filename = FreeRTOS_CLIGetParameter(pcCommandString, 2, ¶mLen); + if (filename != nullptr && paramLen > 0) { + r5.deleteFile(filename); + + snprintf(pcWriteBuffer, xWriteBufferLen-1, OK_RESPONSE); + return pdFALSE; } - snprintf(pcWriteBuffer, xWriteBufferLen-1, "\r\nOK\r\n"); + snprintf(pcWriteBuffer, xWriteBufferLen-1, "\r\nERROR: missing filename\r\n"); return pdFALSE; } if (!strncmp("on", param, paramLen)) { - //cat_m1.device_on(); r5.modulePowerOn(); - snprintf(pcWriteBuffer, xWriteBufferLen-1, "\r\nOK\r\n"); + snprintf(pcWriteBuffer, xWriteBufferLen-1, OK_RESPONSE); return pdFALSE; } if (!strncmp("off", param, paramLen)) { - //cat_m1.device_off(); r5.modulePowerOff(); - snprintf(pcWriteBuffer, xWriteBufferLen-1, "\r\nOK\r\n"); + snprintf(pcWriteBuffer, xWriteBufferLen-1, OK_RESPONSE); return pdFALSE; } if (!strncmp("restart", param, paramLen)) { cat_m1.restart(); - snprintf(pcWriteBuffer, xWriteBufferLen-1, "\r\nOK\r\n"); + snprintf(pcWriteBuffer, xWriteBufferLen-1, OK_RESPONSE); return pdFALSE; } @@ -190,7 +224,7 @@ static int get_response(uint32_t timeout = 500) { response_buffer_.print("+CPRWOFF bad response"); } - snprintf(pcWriteBuffer, xWriteBufferLen-1, "\r\nOK\r\n"); + snprintf(pcWriteBuffer, xWriteBufferLen-1, OK_RESPONSE); return pdFALSE; } @@ -203,7 +237,7 @@ static int get_response(uint32_t timeout = 500) { while (LTE_Serial.available()) { response_buffer_.write(LTE_Serial.read()); } - response_buffer_.print("\r\nOK\r\n"); + response_buffer_.print(OK_RESPONSE); } return pdTRUE; } @@ -215,6 +249,6 @@ static int get_response(uint32_t timeout = 500) { } } - snprintf(pcWriteBuffer, xWriteBufferLen-1, "\r\nERROR: Invalid command\r\n"); + strncpy(pcWriteBuffer, INVALID_CMD_RESPONSE, xWriteBufferLen - 1); return pdFALSE; } diff --git a/firmware/wombat/src/cli/peripherals/sd_card.cpp b/firmware/wombat/src/cli/peripherals/sd_card.cpp index c851c6e..fc3e216 100644 --- a/firmware/wombat/src/cli/peripherals/sd_card.cpp +++ b/firmware/wombat/src/cli/peripherals/sd_card.cpp @@ -30,6 +30,12 @@ */ BaseType_t CLISDCard::enter_cli(char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString) { + + if (!SDCardInterface::is_ready()) { + snprintf(pcWriteBuffer, xWriteBufferLen - 1, "ERROR: SD card not found\r\n"); + return pdFALSE; + } + BaseType_t paramLen = 0; UBaseType_t paramNum = 1; const char *param; @@ -39,12 +45,25 @@ BaseType_t CLISDCard::enter_cli(char *pcWriteBuffer, size_t xWriteBufferLen, memset(pcWriteBuffer, 0, xWriteBufferLen); param = FreeRTOS_CLIGetParameter(pcCommandString, paramNum, ¶mLen); if (param != nullptr && paramLen > 0) { - if (!strncmp("data", param, paramLen)) { - if (!SDCardInterface::is_ready()) { - snprintf(pcWriteBuffer, xWriteBufferLen - 1, "ERROR: SD card not found\r\n"); + if (!strncmp("rm", param, paramLen)) { + const char *filename = FreeRTOS_CLIGetParameter(pcCommandString, 2, ¶mLen); + if (filename != nullptr && paramLen > 0) { + if (paramLen < (xWriteBufferLen - 1)) { + snprintf(pcWriteBuffer, xWriteBufferLen, "/%s", filename); + SDCardInterface::delete_file(pcWriteBuffer); + snprintf(pcWriteBuffer, xWriteBufferLen-1, OK_RESPONSE); + return pdFALSE; + } + + snprintf(pcWriteBuffer, xWriteBufferLen-1, "\r\nERROR: filename too long\r\n"); return pdFALSE; } + snprintf(pcWriteBuffer, xWriteBufferLen-1, "\r\nERROR: missing filename\r\n"); + return pdFALSE; + } + + if (!strncmp("data", param, paramLen)) { if (step < 1) { step++; snprintf(pcWriteBuffer, xWriteBufferLen - 1, "[\r\n"); @@ -61,20 +80,11 @@ BaseType_t CLISDCard::enter_cli(char *pcWriteBuffer, size_t xWriteBufferLen, } if (!strncmp("log", param, paramLen)) { - if (!SDCardInterface::is_ready()) { - snprintf(pcWriteBuffer, xWriteBufferLen - 1, "ERROR: SD card not found\r\n"); - return pdFALSE; - } - SDCardInterface::read_file(sd_card_logfile_name, *CLI::cliOutput); return pdFALSE; } if (!strncmp("read", param, paramLen)) { - if (!SDCardInterface::is_ready()) { - snprintf(pcWriteBuffer, xWriteBufferLen - 1, "ERROR: SD card not found\r\n"); - return pdFALSE; - } if (step < 1) { step++; snprintf(pcWriteBuffer, xWriteBufferLen - 1, "[\r\n"); @@ -104,6 +114,6 @@ BaseType_t CLISDCard::enter_cli(char *pcWriteBuffer, size_t xWriteBufferLen, } } - strncpy(pcWriteBuffer, "ERROR: Invalid command\r\n", xWriteBufferLen - 1); + strncpy(pcWriteBuffer, INVALID_CMD_RESPONSE, xWriteBufferLen - 1); return pdFALSE; } diff --git a/firmware/wombat/src/cli/peripherals/sdi12.cpp b/firmware/wombat/src/cli/peripherals/sdi12.cpp index 244f90e..0cc5eeb 100644 --- a/firmware/wombat/src/cli/peripherals/sdi12.cpp +++ b/firmware/wombat/src/cli/peripherals/sdi12.cpp @@ -91,7 +91,7 @@ BaseType_t CLISdi12::enter_cli(char *pcWriteBuffer, size_t xWriteBufferLen, response_buffer_.print("\r\n"); } - response_buffer_.print("OK\r\n"); + response_buffer_.print(OK_RESPONSE); sdi12.end(); return pdTRUE; @@ -119,7 +119,7 @@ BaseType_t CLISdi12::enter_cli(char *pcWriteBuffer, size_t xWriteBufferLen, String str; serializeJson(msg, response_buffer_); - response_buffer_.print("\r\nOK\r\n"); + response_buffer_.print(OK_RESPONSE); sdi12.end(); @@ -160,7 +160,7 @@ BaseType_t CLISdi12::enter_cli(char *pcWriteBuffer, size_t xWriteBufferLen, } if (ok) { - response_buffer_.print("OK\r\n"); + response_buffer_.print(OK_RESPONSE); } else { response_buffer_.print("ERROR: No response\r\n"); } @@ -216,6 +216,6 @@ BaseType_t CLISdi12::enter_cli(char *pcWriteBuffer, size_t xWriteBufferLen, } } - strncpy(pcWriteBuffer, "ERROR\r\n", xWriteBufferLen - 1); + strncpy(pcWriteBuffer, INVALID_CMD_RESPONSE, xWriteBufferLen - 1); return pdFALSE; } diff --git a/firmware/wombat/src/mqtt_stack.cpp b/firmware/wombat/src/mqtt_stack.cpp index ac9d3bb..6906f66 100644 --- a/firmware/wombat/src/mqtt_stack.cpp +++ b/firmware/wombat/src/mqtt_stack.cpp @@ -189,43 +189,28 @@ bool mqtt_logout(void) { bool mqtt_publish(String &topic, const char *const msg, size_t msg_len) { log_to_sdcard("mqtt_publish"); - SARA_R5_mqtt_command_opcode_t expected_cmd = SARA_R5_MQTT_COMMAND_INVALID; - SARA_R5_error_t err = SARA_R5_ERROR_INVALID; + int result = -1; if (msg_len < MAX_MQTT_DIRECT_MSG_LEN) { ESP_LOGD(TAG, "Direct publish message: %s/%s", topic.c_str(), msg); log_to_sdcard("using direct publish"); - err = r5.mqttPublishBinaryMsg(topic, msg, msg_len, 1); - expected_cmd = SARA_R5_MQTT_COMMAND_PUBLISHBINARY; - } else { - ESP_LOGD(TAG, "Publish from file: %s/%s", topic.c_str(), msg); - log_to_sdcard("using publish from file"); - static const String mqtt_msg_filename("mqtt.json"); - r5.deleteFile(mqtt_msg_filename); - r5.appendFileContents(mqtt_msg_filename, msg, static_cast(msg_len)); - memset(g_buffer, 0, sizeof(g_buffer)); - err = r5.mqttPublishFromFile(topic, mqtt_msg_filename); - expected_cmd = SARA_R5_MQTT_COMMAND_PUBLISHFILE; - -// err = r5.getFileContents(mqtt_msg_filename, g_buffer); -// if (err == SARA_R5_error_t::SARA_R5_ERROR_SUCCESS) { -// ESP_LOGD(TAG, "Msg content from modem:\n%s", g_buffer); -// } else { -// ESP_LOGE(TAG, "Failed to read file content from R5"); -// } - } + SARA_R5_error_t err = r5.mqttPublishBinaryMsg(topic, msg, msg_len, 1); + delay(20); - delay(20); + if (err != SARA_R5_error_t::SARA_R5_ERROR_SUCCESS) { + ESP_LOGE(TAG, "Publish failed"); + log_to_sdcardf("[E] pub failed, err: %d", err); + return false; + } - if (err != SARA_R5_error_t::SARA_R5_ERROR_SUCCESS) { - ESP_LOGE(TAG, "Publish failed"); - log_to_sdcardf("[E] pub failed, err: %d", err); + log_to_sdcard("waiting for pub urc"); + delay(20); + + urcs.waitForURC(SARA_R5_MQTT_COMMAND_PUBLISHBINARY, &result, 60, 500); + } else { + ESP_LOGE(TAG, "Message too long"); + log_to_sdcardf("[E] message too long"); return false; } - log_to_sdcard("waiting for pub urc"); - delay(20); - - int result = -1; - urcs.waitForURC(expected_cmd, &result, 60, 500); return result == 1; } diff --git a/firmware/wombat/src/uplinks.cpp b/firmware/wombat/src/uplinks.cpp index 658ed08..cc17551 100644 --- a/firmware/wombat/src/uplinks.cpp +++ b/firmware/wombat/src/uplinks.cpp @@ -19,7 +19,7 @@ static volatile mqtt_status_t mqtt_status = MQTT_UNINITIALISED; static String topic("wombat"); -static constexpr size_t MAX_MSG_LEN = 4096; +static constexpr size_t MAX_MSG_LEN = MAX_MQTT_DIRECT_MSG_LEN; static char msg_buf[MAX_MSG_LEN + 1]; /**