diff --git a/Tools/ardupilotwaf/boards.py b/Tools/ardupilotwaf/boards.py
index b1a54e45e346e8..4630f9a967b6f4 100644
--- a/Tools/ardupilotwaf/boards.py
+++ b/Tools/ardupilotwaf/boards.py
@@ -178,6 +178,25 @@ def srcpath(path):
if cfg.options.enable_networking_tests:
env.CXXFLAGS += ['-DAP_NETWORKING_TESTS_ENABLED=1']
+ if cfg.options.enable_custom_storage:
+ # Set environment variable to make the flag globally available
+ env.ENABLE_CUSTOM_STORAGE = True
+
+ # Add necessary libraries to compile when the flag is present
+ env.AP_LIBRARIES += [
+ 'AP_CustomStorage',
+ 'AP_CustomMavlinkHandler'
+ ]
+
+ # Define a preprocessor macro that can be checked in C/C++ code
+ env.DEFINES.update(AP_ENABLE_CUSTOM_STORAGE = 1)
+ else:
+ # Ensure the environment variable is set to False when the flag is not present
+ env.ENABLE_CUSTOM_STORAGE = False
+
+ # Set the preprocessor macro to 0 when disabled
+ env.DEFINES.update(AP_ENABLE_CUSTOM_STORAGE = 0)
+
d = env.get_merged_dict()
# Always prepend so that arguments passed in the command line get
# the priority.
diff --git a/Tools/ardupilotwaf/custom_dialect_tool.py b/Tools/ardupilotwaf/custom_dialect_tool.py
new file mode 100644
index 00000000000000..6a85a6537d96ea
--- /dev/null
+++ b/Tools/ardupilotwaf/custom_dialect_tool.py
@@ -0,0 +1,67 @@
+import os
+
+# All Waf tools must have a 'configure' function that Waf can call.
+def configure(conf):
+ """
+ This function is automatically run by Waf when 'cfg.load("custom_dialect_tool")'
+ is called in the main wscript.
+ """
+ # Use 'conf' which is the configuration context passed into this tool.
+ conf.to_log("Running custom_dialect_tool to manage MAVLink dialect...")
+
+ # Dynamically get the absolute path to the ardupilot root directory
+ ardupilot_root = conf.srcnode.abspath()
+
+ # Construct the full path to your custom dialect file
+ custom_dialect_path = os.path.join(ardupilot_root, 'libraries/AP_CustomMavlinkHandler/custom_dialect.xml')
+
+ # The path to the all.xml file within the ArduPilot source tree
+ all_xml_path = os.path.join(ardupilot_root, 'modules/mavlink/message_definitions/v1.0/all.xml')
+
+ try:
+ with open(all_xml_path, 'r') as f:
+ original_lines = f.readlines()
+ except FileNotFoundError:
+ conf.fatal(f"Could not find {all_xml_path}. Make sure submodules are updated.")
+ except Exception as e:
+ conf.fatal(f"An error occurred while reading {all_xml_path}: {e}")
+
+ # Check if the custom line currently exists
+ line_exists = any(custom_dialect_path in line for line in original_lines)
+ needs_write = False
+
+ if conf.options.enable_custom_storage:
+ # Flag is ON: We want the line to EXIST
+ if not line_exists:
+ insert_index = -1
+ for i, line in enumerate(original_lines):
+ if '' in line:
+ insert_index = i
+ break
+
+ if insert_index == -1:
+ conf.fatal(f"Could not find insertion point () in {all_xml_path}")
+
+ include_line_to_add = f' {custom_dialect_path}\n'
+ original_lines.insert(insert_index, include_line_to_add)
+ needs_write = True
+ conf.to_log(f"-> Adding custom dialect to {all_xml_path}")
+ print('Custom Storage Setting : Enabled')
+
+ else:
+ # Flag is OFF: We want the line to be REMOVED
+ if line_exists:
+ original_lines = [line for line in original_lines if custom_dialect_path not in line]
+ needs_write = True
+ conf.to_log(f"-> Removing custom dialect from {all_xml_path}")
+ print('Custom Storage Setting : Disabled')
+
+ # If a change was made, write the new content back to the file
+ if needs_write:
+ try:
+ with open(all_xml_path, 'w') as f:
+ f.writelines(original_lines)
+ except Exception as e:
+ conf.fatal(f"An error occurred while writing to {all_xml_path}: {e}")
+ else:
+ conf.to_log(f"-> Custom dialect in {all_xml_path} is already in the correct state.")
\ No newline at end of file
diff --git a/Tools/autotest/sim_vehicle.py b/Tools/autotest/sim_vehicle.py
index 19dbbb5ee7cd3a..bf13c19e578012 100755
--- a/Tools/autotest/sim_vehicle.py
+++ b/Tools/autotest/sim_vehicle.py
@@ -420,6 +420,9 @@ def do_build(opts, frame_options):
if opts.enable_networking_tests:
cmd_configure.append("--enable-networking-tests")
+ if opts.enable_custom_storage:
+ cmd_configure.append("--enable-custom-storage")
+
pieces = [shlex.split(x) for x in opts.waf_configure_args]
for piece in pieces:
cmd_configure.extend(piece)
@@ -1355,6 +1358,8 @@ def generate_frame_help():
help="Enable networking tests")
group_sim.add_option("--enable-fgview", action='store_true',
help="Enable FlightGear output")
+group_sim.add_option("--enable-custom-storage", action='store_true',
+ help="Enable custom storage for uuid and password along with custom mavlink message handler.")
parser.add_option_group(group_sim)
diff --git a/libraries/AP_CustomMavlinkHandler/AP_CustomMavlinkHandler.cpp b/libraries/AP_CustomMavlinkHandler/AP_CustomMavlinkHandler.cpp
new file mode 100644
index 00000000000000..d7688354e4580e
--- /dev/null
+++ b/libraries/AP_CustomMavlinkHandler/AP_CustomMavlinkHandler.cpp
@@ -0,0 +1,87 @@
+#if defined(AP_ENABLE_CUSTOM_STORAGE) && AP_ENABLE_CUSTOM_STORAGE==1
+
+#include "AP_CustomMavlinkHandler.h"
+#include
+#include
+
+void AP_CustomMavlinkHandler::init(void){
+ g_custom_storage.init();
+}
+void AP_CustomMavlinkHandler::handle_custom_message(mavlink_channel_t chan, const mavlink_message_t &msg)
+{
+ // printf("AP_CustomMavlinkHandler: %s\n", "got message");
+ if (msg.msgid != CUSTOM_MSG_ID)
+ return;
+
+ // Manual message decoding
+ uuid_update_t packet;
+ memcpy(&packet, msg.payload64, sizeof(packet));
+ packet.value[36] = '\0'; // Ensure null termination
+ // printf("payload64: %s\n", packet.value);
+
+ switch (packet.param)
+ {
+ case AIRBOUND_PARAMETER_PARAM_ID_UUID:
+ switch (packet.action)
+ {
+ case AIRBOUND_PARAMETER_ACTION_GET: // read
+ {
+ char uuid[37] = {0};
+ g_custom_storage.get_uuid(uuid, sizeof(uuid));
+ gcs().send_text(MAV_SEVERITY_INFO, "uuid:%s", uuid);
+ mavlink_msg_airbound_parameter_status_send(chan, AIRBOUND_PARAMETER_PARAM_ID_UUID, (const char *)uuid, AIRBOUND_PARAMETER_RESULT_OK);
+ break;
+ }
+ case AIRBOUND_PARAMETER_ACTION_SET: // write
+ {
+ char uuid[37] = {0};
+ g_custom_storage.set_uuid(packet.value);
+ g_custom_storage.get_uuid(uuid, sizeof(uuid));
+ gcs().send_text(MAV_SEVERITY_INFO, "uuid updated : %s", uuid);
+ mavlink_msg_airbound_parameter_status_send(chan, AIRBOUND_PARAMETER_PARAM_ID_UUID, (const char *)uuid, AIRBOUND_PARAMETER_RESULT_OK);
+
+ break;
+ }
+ default:
+ char buf[37] = {0};
+ mavlink_msg_airbound_parameter_status_send(chan, AIRBOUND_PARAMETER_PARAM_ID_UUID, (const char *)buf, AIRBOUND_PARAMETER_RESULT_UNSUPPORTED);
+ break;
+ }
+ break;
+
+ case AIRBOUND_PARAMETER_PARAM_ID_PASS:
+ switch (packet.action)
+ {
+ case AIRBOUND_PARAMETER_ACTION_GET: // read
+ {
+ char pass[37] = {0};
+ g_custom_storage.get_password(pass, sizeof(pass));
+ mavlink_msg_airbound_parameter_status_send(chan, AIRBOUND_PARAMETER_PARAM_ID_PASS, (const char *)pass, AIRBOUND_PARAMETER_RESULT_OK);
+ break;
+ }
+ case AIRBOUND_PARAMETER_ACTION_SET: // write
+ {
+ char pass[37] = {0};
+ g_custom_storage.set_password(packet.value);
+ g_custom_storage.get_password(pass, sizeof(pass));
+ mavlink_msg_airbound_parameter_status_send(chan, AIRBOUND_PARAMETER_PARAM_ID_PASS, (const char *)pass, AIRBOUND_PARAMETER_RESULT_OK);
+ break;
+ }
+ default:
+ {
+ char buf[37] = {0};
+ mavlink_msg_airbound_parameter_status_send(chan, AIRBOUND_PARAMETER_PARAM_ID_PASS, (const char *)buf, AIRBOUND_PARAMETER_RESULT_UNSUPPORTED);
+ break;
+ }
+ }
+ break;
+
+ default:
+ {
+ char buf[37] = {0};
+ mavlink_msg_airbound_parameter_status_send(chan, AIRBOUND_PARAMETER_PARAM_ID_PASS, (const char *)buf, AIRBOUND_PARAMETER_RESULT_UNSUPPORTED);
+ break;
+ }
+ }
+}
+#endif
\ No newline at end of file
diff --git a/libraries/AP_CustomMavlinkHandler/AP_CustomMavlinkHandler.h b/libraries/AP_CustomMavlinkHandler/AP_CustomMavlinkHandler.h
new file mode 100644
index 00000000000000..6944bed17062cc
--- /dev/null
+++ b/libraries/AP_CustomMavlinkHandler/AP_CustomMavlinkHandler.h
@@ -0,0 +1,24 @@
+#if defined(AP_ENABLE_CUSTOM_STORAGE) && AP_ENABLE_CUSTOM_STORAGE==1
+
+#pragma once
+#include
+#include "AP_CustomStorage/AP_CustomStorage.h"
+
+class AP_CustomMavlinkHandler
+{
+public:
+ static void handle_custom_message(mavlink_channel_t chan, const mavlink_message_t &msg);
+ static void init(void);
+// Manually define our message structure
+#pragma pack(push, 1)
+ typedef struct
+ {
+ uint8_t param;
+ uint8_t action;
+ char value[37];
+ } uuid_update_t;
+#pragma pack(pop)
+ static const uint16_t CUSTOM_MSG_ID = 15222;
+};
+
+#endif
\ No newline at end of file
diff --git a/libraries/AP_CustomMavlinkHandler/custom_dialect.xml b/libraries/AP_CustomMavlinkHandler/custom_dialect.xml
new file mode 100644
index 00000000000000..b7114a960dea96
--- /dev/null
+++ b/libraries/AP_CustomMavlinkHandler/custom_dialect.xml
@@ -0,0 +1,37 @@
+
+
+ 2
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Custom Airbound Parameter GET SET API for setting or getting a simple parameter.
+ Identifier for the custom parameter.
+ Action to perform (GET or SET).
+ Value to set (ignored for GET action).
+
+
+ Status and value feedback for a custom Airbound parameter.
+ Identifier for the custom parameter from the request.
+ The current value of the parameter.
+ Result of the operation.
+
+
+
+
\ No newline at end of file
diff --git a/libraries/AP_CustomStorage/AP_CustomStorage.cpp b/libraries/AP_CustomStorage/AP_CustomStorage.cpp
new file mode 100644
index 00000000000000..9a421ed832c180
--- /dev/null
+++ b/libraries/AP_CustomStorage/AP_CustomStorage.cpp
@@ -0,0 +1,174 @@
+#if defined(AP_ENABLE_CUSTOM_STORAGE) && AP_ENABLE_CUSTOM_STORAGE==1
+#include "AP_CustomStorage.h"
+#include
+#include
+
+// Note: StorageManager handles flash memory access
+
+StorageAccess AP_CustomStorage::_storage(StorageManager::StorageCustom);
+AP_CustomStorage g_custom_storage; // Global singleton instance
+
+AP_CustomStorage::AP_CustomStorage()
+{
+ // Safety: Clear buffer to prevent stale data leaks
+ memset(_data, 0, sizeof(_data));
+}
+
+void AP_CustomStorage::init()
+{
+ if (_initialized)
+ {
+ return;
+ }
+ printf("CustomStorage: Initializing...%d\n", _storage.size()); // Debug log
+
+ // Critical check - must match hwdef.dat storage allocation
+ if (_storage.size() < sizeof(_data))
+ {
+ printf("CustomStorage ERROR: Allocated size (%u) is less than buffer size (%u)!\n",
+ (unsigned int)_storage.size(), (unsigned int)sizeof(_data));
+ _initialized = true; // Prevent repeated initialization attempts
+ return;
+ }
+
+ if (load_from_flash())
+ {
+ StorageHeader header;
+ memcpy(&header, _data, sizeof(header));
+
+ // Initialize header if missing/corrupt (first boot)
+ if (header.magic != HEADER_MAGIC)
+ {
+ header.magic = HEADER_MAGIC;
+ header.version = 1;
+ memset(_data, 0, CUSTOM_PARAM_DATA_SIZE);
+ memcpy(_data, &header.magic, sizeof(header.magic));
+ save_to_flash();
+ load_from_flash();
+ memcpy(&header, _data, sizeof(header));
+ }
+ printf("CustomStorage: Loaded: '%s'\n", _data); // Show loaded data
+ printf("magic : %d\n", header.magic == HEADER_MAGIC); // Header validation debug
+ }
+ else
+ {
+ printf("CustomStorage: No Storage found, initializing default.\n"); // First-run case
+ memset(_data, 0, sizeof(_data));
+ save_to_flash();
+ }
+
+ _initialized = true;
+}
+
+//--------------------------------------------------
+// Safety-Critical Methods (all include validation)
+//--------------------------------------------------
+
+bool AP_CustomStorage::set_uuid(const char *uuid)
+{
+ if (!_initialized || uuid == nullptr)
+ {
+ return false; // Prevents operations on uninitialized storage
+ }
+
+ if (strlen(uuid) > _layout.uuid_length)
+ {
+ return false; // Length enforcement
+ }
+
+ strncpy(&_data[_layout.uuid_offset], uuid, _layout.uuid_length);
+ return save_to_flash(); // Auto-persist
+}
+
+bool AP_CustomStorage::get_uuid(char *buf, uint8_t len) const
+{
+ if (!_initialized || buf == nullptr || len <= _layout.uuid_length)
+ {
+ return false; // Buffer safety check
+ }
+
+ strncpy(buf, &_data[_layout.uuid_offset], _layout.uuid_length);
+ buf[_layout.uuid_length] = '\0'; // Guaranteed termination
+ return true;
+}
+
+bool AP_CustomStorage::set_password(const char *pass)
+{
+ if (!_initialized || pass == nullptr)
+ {
+ return false;
+ }
+
+ if (strlen(pass) > _layout.pass_length)
+ {
+ return false;
+ }
+
+ strncpy(&_data[_layout.pass_offset], pass, _layout.pass_length);
+ return save_to_flash();
+}
+
+bool AP_CustomStorage::get_password(char *buf, uint8_t len) const
+{
+ if (!_initialized || buf == nullptr || len <= _layout.pass_length)
+ {
+ return false;
+ }
+
+ strncpy(buf, &_data[_layout.pass_offset], _layout.pass_length);
+ buf[_layout.pass_length] = '\0';
+ return true;
+}
+
+//--------------------------------------------------
+// Flash Operations (atomic read/write)
+//--------------------------------------------------
+
+bool AP_CustomStorage::load_from_flash()
+{
+ // Note: Atomic read prevents partial state loading
+ return _storage.read_block(_data, 0, sizeof(_data));
+}
+
+bool AP_CustomStorage::save_to_flash()
+{
+
+ if (_storage.write_block(0, _data, sizeof(_data)))
+ {
+ printf("CustomStorage: Storage saved successfully.\n"); // Debug confirmation
+ return true;
+ }
+ else
+ {
+ printf("CustomStorage ERROR: Failed to save Storage to flash!\n"); // Critical error
+ return false;
+ }
+}
+
+//--------------------------------------------------
+// Utility Methods
+//--------------------------------------------------
+
+const char *AP_CustomStorage::get_storage() const
+{
+ return _data; // Direct access - caller manages buffer size
+}
+
+void AP_CustomStorage::set_storage(const char *new_data)
+{
+ if (!_initialized)
+ {
+ printf("CustomStorage: Not initialized, cannot set string.\n"); // State warning
+ return;
+ }
+
+ strncpy(_data, new_data, DATA_BUFFER_SIZE);
+ printf("CustomStorage: Setting and saving: '%s'\n", _data); // Debug log
+ save_to_flash();
+}
+
+bool AP_CustomStorage::is_initialized()
+{
+ return _initialized;
+}
+#endif
\ No newline at end of file
diff --git a/libraries/AP_CustomStorage/AP_CustomStorage.h b/libraries/AP_CustomStorage/AP_CustomStorage.h
new file mode 100644
index 00000000000000..fd6d066e1f363c
--- /dev/null
+++ b/libraries/AP_CustomStorage/AP_CustomStorage.h
@@ -0,0 +1,139 @@
+#if defined(AP_ENABLE_CUSTOM_STORAGE) && AP_ENABLE_CUSTOM_STORAGE==1
+
+#pragma once
+#include
+#include
+
+// Constants for storage configuration
+#define DATA_BUFFER_SIZE 127 ///< Size of data buffer (excluding null terminator)
+#define CUSTOM_PARAM_UUID_LEN 36 ///< Standard UUID string length (36 chars for "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")
+#define CUSTOM_PARAM_PASS_LEN 32 ///< Maximum allowed password length
+#define CUSTOM_PARAM_DATA_SIZE 128 ///< Total allocated storage size in bytes
+
+/**
+ * @class AP_CustomStorage
+ * @brief Custom parameter storage system for ArduPilot
+ *
+ * Provides persistent storage for custom parameters including:
+ * - UUID (Universally Unique Identifier)
+ * - Password/authentication tokens
+ *
+ * Data is stored in flash memory with a header structure for validation.
+ */
+class AP_CustomStorage
+{
+public:
+ AP_CustomStorage();
+
+ bool _initialized = false; ///< Tracks whether storage system has been initialized
+
+ /**
+ * @brief Initialize the storage system
+ *
+ * Verifies storage allocation and loads existing data from flash.
+ * Initializes default header if none exists.
+ */
+ void init();
+
+ /**
+ * @brief Check initialization status
+ * @return true if initialized, false otherwise
+ */
+ bool is_initialized();
+
+ // Parameter operations
+
+ /**
+ * @brief Store a UUID string
+ * @param uuid Null-terminated UUID string (must be 36 chars or less)
+ * @return true if successful, false on error
+ */
+ bool set_uuid(const char *uuid);
+
+ /**
+ * @brief Retrieve stored UUID
+ * @param buf Buffer to receive UUID string
+ * @param len Length of provided buffer (must be > CUSTOM_PARAM_UUID_LEN)
+ * @return true if successful, false on error
+ */
+ bool get_uuid(char *buf, uint8_t len) const;
+
+ /**
+ * @brief Store a password string
+ * @param pass Null-terminated password string (32 chars or less)
+ * @return true if successful, false on error
+ */
+ bool set_password(const char *pass);
+
+ /**
+ * @brief Retrieve stored password
+ * @param buf Buffer to receive password string
+ * @param len Length of provided buffer (must be > CUSTOM_PARAM_PASS_LEN)
+ * @return true if successful, false on error
+ */
+ bool get_password(char *buf, uint8_t len) const;
+
+private:
+ static StorageAccess _storage; ///< Storage manager interface
+ char _data[DATA_BUFFER_SIZE + 1]; ///< Data buffer (+1 for null terminator)
+
+ /**
+ * @brief Storage header structure
+ *
+ * Packed to ensure consistent layout in flash memory
+ */
+ struct PACKED StorageHeader {
+ uint32_t magic; ///< Magic number for format identification
+ uint16_t version; ///< Format version number
+ };
+
+ // Storage configuration constants
+ enum {
+ MAX_STORAGE_SIZE = 128, ///< Total available storage space
+ HEADER_MAGIC = 0x52545343, ///< Magic number ('CSTR' in ASCII)
+ HEADER_SIZE = sizeof(StorageHeader) ///< Size of header structure
+ };
+
+ /**
+ * @brief Layout definition for parameter storage
+ *
+ * Defines the memory layout of parameters within the storage area
+ */
+ struct {
+ const uint8_t uuid_offset = HEADER_SIZE; ///< UUID storage offset from start
+ const uint8_t uuid_length = CUSTOM_PARAM_UUID_LEN; ///< Allocated UUID storage length
+ const uint8_t pass_offset = CUSTOM_PARAM_UUID_LEN + HEADER_SIZE; ///< Password storage offset
+ const uint8_t pass_length = CUSTOM_PARAM_PASS_LEN; ///< Allocated password storage length
+ } _layout;
+
+ /**
+ * @brief Get pointer to raw storage data
+ * @return const char* Pointer to internal data buffer
+ */
+ const char *get_storage() const; // Declaration only!
+
+ /**
+ * @brief Set new storage data
+ * @param new_string Data to store (will be truncated to DATA_BUFFER_SIZE)
+ */
+ void set_storage(const char *new_string);
+
+ // Helper methods
+
+ /**
+ * @brief Load data from flash storage
+ * @return true if successful, false on error
+ */
+ bool load_from_flash();
+
+ /**
+ * @brief Save current data to flash storage
+ * @return true if successful, false on error
+ */
+ bool save_to_flash();
+};
+
+// Global instance declaration
+extern AP_CustomStorage g_custom_storage;
+
+#endif
\ No newline at end of file
diff --git a/libraries/GCS_MAVLink/GCS_Common.cpp b/libraries/GCS_MAVLink/GCS_Common.cpp
index 950bacbb695850..a81685e710ec9b 100644
--- a/libraries/GCS_MAVLink/GCS_Common.cpp
+++ b/libraries/GCS_MAVLink/GCS_Common.cpp
@@ -77,6 +77,10 @@
#include
+#if defined(AP_ENABLE_CUSTOM_STORAGE) && AP_ENABLE_CUSTOM_STORAGE==1
+#include
+#endif
+
#if AP_RADIO_ENABLED
#include
#include
@@ -201,6 +205,9 @@ bool GCS_MAVLINK::init(uint8_t instance)
if (mavlink_protocol == AP_SerialManager::SerialProtocol_MAVLinkHL) {
is_high_latency_link = true;
}
+#endif
+#if defined(AP_ENABLE_CUSTOM_STORAGE) && AP_ENABLE_CUSTOM_STORAGE==1
+ AP_CustomMavlinkHandler::init();
#endif
return true;
}
@@ -4161,6 +4168,13 @@ void GCS_MAVLINK::handle_heartbeat(const mavlink_message_t &msg) const
void GCS_MAVLINK::handle_message(const mavlink_message_t &msg)
{
switch (msg.msgid) {
+
+#if defined(AP_ENABLE_CUSTOM_STORAGE) && AP_ENABLE_CUSTOM_STORAGE==1
+ case MAVLINK_MSG_ID_AIRBOUND_PARAMETER_GETSET: {
+ AP_CustomMavlinkHandler::handle_custom_message(chan,msg);
+ break;
+ }
+#endif
case MAVLINK_MSG_ID_HEARTBEAT: {
handle_heartbeat(msg);
diff --git a/libraries/StorageManager/StorageManager.cpp b/libraries/StorageManager/StorageManager.cpp
index c9bb13e3e834ab..0b5fee3e7fb87b 100644
--- a/libraries/StorageManager/StorageManager.cpp
+++ b/libraries/StorageManager/StorageManager.cpp
@@ -95,7 +95,11 @@ const StorageManager::StorageArea StorageManager::layout[STORAGE_NUM_AREAS] = {
{ StorageCANDNA, 15232, 1024},
// 128 byte gap at end of first 16k
#endif
-#if STORAGE_NUM_AREAS >= 18
+#if defined(AP_ENABLE_CUSTOM_STORAGE) && AP_ENABLE_CUSTOM_STORAGE==1 && (STORAGE_NUM_AREAS == 16 || STORAGE_NUM_AREAS == 19)
+ {StorageCustom, 16256, 128},
+#endif
+
+#if STORAGE_NUM_AREAS >= 18 || STORAGE_NUM_AREAS == 19
{ StorageParam, 16384, 1280},
{ StorageMission, 17664, 9842},
{ StorageParamBak, 27506, 5262},
diff --git a/libraries/StorageManager/StorageManager.h b/libraries/StorageManager/StorageManager.h
index 5332ff408ede22..9cd4aa862dd3cb 100644
--- a/libraries/StorageManager/StorageManager.h
+++ b/libraries/StorageManager/StorageManager.h
@@ -28,9 +28,17 @@
storage. Use larger areas for other boards
*/
#if HAL_STORAGE_SIZE >= 32768
+#if defined(AP_ENABLE_CUSTOM_STORAGE)
+#define STORAGE_NUM_AREAS 18+1 // 1 added for our custom storage
+#else
#define STORAGE_NUM_AREAS 18
+#endif
#elif HAL_STORAGE_SIZE >= 16384
+#if defined(AP_ENABLE_CUSTOM_STORAGE)
+#define STORAGE_NUM_AREAS 15+1 // 1 added for our custom storage
+#else
#define STORAGE_NUM_AREAS 15
+#endif
#elif HAL_STORAGE_SIZE >= 15360 && defined(HAL_NUM_CAN_IFACES)
#define STORAGE_NUM_AREAS 12
#elif HAL_STORAGE_SIZE >= 15360
@@ -51,6 +59,19 @@
class StorageManager {
friend class StorageAccess;
public:
+#if defined(AP_ENABLE_CUSTOM_STORAGE) && AP_ENABLE_CUSTOM_STORAGE==1
+ enum StorageType {
+ StorageParam = 0,
+ StorageFence = 1,
+ StorageRally = 2,
+ StorageMission = 3,
+ StorageKeys = 4,
+ StorageBindInfo= 5,
+ StorageCANDNA = 6,
+ StorageParamBak = 7,
+ StorageCustom = 8
+ };
+#else
enum StorageType {
StorageParam = 0,
StorageFence = 1,
@@ -61,6 +82,7 @@ class StorageManager {
StorageCANDNA = 6,
StorageParamBak = 7
};
+#endif
// erase whole of storage
static void erase(void);
diff --git a/wscript b/wscript
index f400c74cdb7ee3..96f8c4e95c100f 100644
--- a/wscript
+++ b/wscript
@@ -303,6 +303,12 @@ submodules at specific revisions.
g.add_option('--enable-dronecan-tests', action='store_true',
default=False,
help="Enables DroneCAN tests in sitl")
+
+ g.add_option('--enable-custom-storage',
+ action='store_true',
+ default=False,
+ help='Enable custom storage for uuid and password along with custom mavlink message handler.')
+
g = opt.ap_groups['linux']
linux_options = ('--prefix', '--destdir', '--bindir', '--libdir')
@@ -540,6 +546,11 @@ def configure(cfg):
cfg.msg('Setting board to', cfg.options.board)
cfg.get_board().configure(cfg)
+
+ # Manages the inclusion of the custom MAVLink dialect in the build.
+ # This logic adds the dialect if --enable-custom-storage is passed during configuration,
+ # and ensures it is removed otherwise.
+ cfg.load('custom_dialect_tool')
cfg.load('waf_unit_test')
cfg.load('mavgen')