Sync while working on OT
All checks were successful
Deploy Docs / build-and-deploy (push) Successful in 13s

This commit is contained in:
2026-02-17 12:52:32 +01:00
parent 6b36435759
commit 8c15260166
9 changed files with 262 additions and 15 deletions

View File

@@ -1,10 +1,11 @@
menuconfig THREAD_MGMT
bool "Thread Management"
depends on BLE_MGMT
select LASERTAG_UTILS
select NETWORKING
select NET_L2_OPENTHREAD
select OPENTHREAD
select OPENTHREAD_SHELL
select OPENTHREAD_TIME_SYNC
help
Library for initializing and managing the OpenThread stack.
@@ -14,6 +15,13 @@ if THREAD_MGMT
module-str = thread_mgmt
source "subsys/logging/Kconfig.template.log_config"
config THREAD_MGMT_SHELL
bool "Enable shell commands for Thread management"
select SHELL
select OPENTHREAD_SHELL
default n
help
Enable shell commands for managing the Thread network, such as starting/stopping the Thread interface, checking status, etc.
# Openthread configuration options
config OPENTHREAD_DEFAULT_TX_POWER
default 8

View File

@@ -16,6 +16,10 @@
LOG_MODULE_REGISTER(thread_mgmt, CONFIG_THREAD_MGMT_LOG_LEVEL);
#if IS_ENABLED(CONFIG_THREAD_MGMT_SHELL)
void init_custom_ot_commands(void);
#endif
#if (CONFIG_THREAD_MGMT_LOG_LEVEL >= LOG_LEVEL_DBG)
static void thread_mgmt_state_notify_callback(otChangedFlags aFlags, void *aContext)
{
@@ -85,12 +89,12 @@ int thread_mgmt_init(void)
dataset.mComponents.mIsPanIdPresent = true;
dataset.mChannel = 15;
dataset.mComponents.mIsChannelPresent = true;
uint8_t ext_pan_id[8];
sys_csrand_get(ext_pan_id, sizeof(ext_pan_id));
uint8_t ext_pan_id[8] = {0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0xba, 0xbe}; // Example Extended PAN ID
// sys_csrand_get(ext_pan_id, sizeof(ext_pan_id));
memcpy(dataset.mExtendedPanId.m8, ext_pan_id, 8);
dataset.mComponents.mIsExtendedPanIdPresent = true;
uint8_t network_key[16];
sys_csrand_get(network_key, sizeof(network_key));
uint8_t network_key[16] = {0x00}; // Initialize with zeros
// sys_csrand_get(network_key, sizeof(network_key));
memcpy(dataset.mNetworkKey.m8, network_key, 16);
dataset.mComponents.mIsNetworkKeyPresent = true;
memset(dataset.mMeshLocalPrefix.m8, 0, 8);
@@ -109,6 +113,10 @@ int thread_mgmt_init(void)
LOG_DBG("Thread stack dataset after Thread stack initialization:");
thread_mgmt_print_dataset(&dataset);
#endif
#if IS_ENABLED(CONFIG_THREAD_MGMT_SHELL)
init_custom_ot_commands();
#endif
return 0;
}
@@ -170,8 +178,8 @@ void thread_mgmt_restart_thread_stack(device_config_payload_t *pending_config, b
if (changed)
{
LOG_DBG("Thread stack restart required; dataset changed.");
dataset.mActiveTimestamp.mSeconds++;
dataset.mActiveTimestamp.mSeconds++;
dataset.mComponents.mIsActiveTimestampPresent = true;
otThreadSetEnabled(instance, false);
@@ -180,12 +188,14 @@ void thread_mgmt_restart_thread_stack(device_config_payload_t *pending_config, b
// Set the network key BEFORE updating the dataset
// This ensures OpenThread's crypto layer has the correct key before we update the operational dataset
otNetworkKey stored_network_key;
if (dataset.mComponents.mIsNetworkKeyPresent) {
if (dataset.mComponents.mIsNetworkKeyPresent)
{
otError key_err = otThreadSetNetworkKey(instance, &dataset.mNetworkKey);
if (key_err != OT_ERROR_NONE) {
if (key_err != OT_ERROR_NONE)
{
LOG_ERR("Error setting network key: %d", key_err);
}
// Read the key back from the thread stack to ensure it's properly stored
otThreadGetNetworkKey(instance, &stored_network_key);
memcpy(dataset.mNetworkKey.m8, stored_network_key.m8, 16);
@@ -193,7 +203,8 @@ void thread_mgmt_restart_thread_stack(device_config_payload_t *pending_config, b
}
otError err = otDatasetSetActive(instance, &dataset);
if (err != OT_ERROR_NONE) {
if (err != OT_ERROR_NONE)
{
LOG_ERR("Error writing dataset: %d", err);
}
@@ -203,7 +214,8 @@ void thread_mgmt_restart_thread_stack(device_config_payload_t *pending_config, b
#if (CONFIG_THREAD_MGMT_LOG_LEVEL >= LOG_LEVEL_DBG)
otOperationalDataset new_active_dataset;
memset(&new_active_dataset, 0, sizeof(otOperationalDataset));
if (otDatasetGetActive(instance, &new_active_dataset) == OT_ERROR_NONE) {
if (otDatasetGetActive(instance, &new_active_dataset) == OT_ERROR_NONE)
{
LOG_DBG("Thread stack dataset after Thread stack update:");
thread_mgmt_print_dataset(&new_active_dataset);
}
@@ -245,7 +257,8 @@ void thread_mgmt_get_ext_pan_id(uint8_t *dest_8byte)
struct otInstance *instance = openthread_get_default_instance();
otOperationalDataset dataset;
if (otDatasetGetActive(instance, &dataset) == OT_ERROR_NONE) {
if (otDatasetGetActive(instance, &dataset) == OT_ERROR_NONE)
{
memcpy(dest_8byte, dataset.mExtendedPanId.m8, 8);
}
}
@@ -255,7 +268,8 @@ void thread_mgmt_get_network_key(uint8_t *dest_16byte)
struct otInstance *instance = openthread_get_default_instance();
otOperationalDataset dataset;
if (otDatasetGetActive(instance, &dataset) == OT_ERROR_NONE) {
if (otDatasetGetActive(instance, &dataset) == OT_ERROR_NONE)
{
memcpy(dest_16byte, dataset.mNetworkKey.m8, 16);
}
}
@@ -265,8 +279,61 @@ void thread_mgmt_get_network_name(char *dest_str, size_t max_len)
struct otInstance *instance = openthread_get_default_instance();
otOperationalDataset dataset;
if (otDatasetGetActive(instance, &dataset) == OT_ERROR_NONE) {
if (otDatasetGetActive(instance, &dataset) == OT_ERROR_NONE)
{
// Safe copy with forced null-termination
snprintf(dest_str, max_len, "%s", dataset.mNetworkName.m8);
}
}
/* --- Shell Commands --- */
#if IS_ENABLED(CONFIG_THREAD_MGMT_SHELL)
#include <zephyr/shell/shell.h>
#include <openthread/cli.h>
#include <openthread/network_time.h>
otError ot_time_handler(void *aContext, uint8_t aArgsLength, char **aArgs)
{
ARG_UNUSED(aContext);
ARG_UNUSED(aArgsLength);
ARG_UNUSED(aArgs);
uint64_t networkTime;
uint16_t syncPeriod;
otNetworkTimeStatus status;
otInstance *instance = openthread_get_default_instance();
status = otNetworkTimeGet(instance, &networkTime);
syncPeriod = otNetworkTimeGetSyncPeriod(instance);
switch (status) {
case OT_NETWORK_TIME_SYNCHRONIZED:
otCliOutputFormat("Synchronized: %llu us, Sync Period: %u ms\n", networkTime, syncPeriod);
break;
case OT_NETWORK_TIME_RESYNC_NEEDED:
otCliOutputFormat("Resync needed. Last time: %llu us, Sync Period: %u ms\n", networkTime, syncPeriod);
break;
case OT_NETWORK_TIME_UNSYNCHRONIZED:
otCliOutputFormat(FORMAT_RED_BOLD("Error: Network time not synchronized. Sync Period: %u ms\n"), syncPeriod);
break;
default:
otCliOutputFormat(FORMAT_RED_BOLD("Error: Unknown network time status. Sync Period: %u ms\n"), syncPeriod);
break;
}
return OT_ERROR_NONE;
}
static const otCliCommand ot_commands[] = {
{"time", ot_time_handler},
};
void init_custom_ot_commands(void)
{
struct otInstance *instance = openthread_get_default_instance();
if (instance)
{
otCliSetUserCommands(ot_commands, ARRAY_SIZE(ot_commands), instance);
}
}
#endif // CONFIG_THREAD_MGMT_SHELL