Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions include/net/ot_rpc.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Copyright (c) 2025 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
*/

#ifndef OT_RPC_H_
#define OT_RPC_H_

#include <openthread/link.h>

/**
* @file
* @defgroup ot_rpc OpenThread over RPC API additions
* @{
* @brief API additions for OpenThread over RPC.
*/

#ifdef __cplusplus
extern "C" {
#endif

/** @brief Set factory assigned IEEE EUI64 on the remote device.
*
* The function issues an nRF RPC command that configures the factory-assigned IEEE EUI64,
* which can then be retrieved using the @c otLinkGetFactoryAssignedIeeeEui64 API.
*
* @param eui64 IEEE EUI64 identifier.
*
* @retval OT_ERROR_NONE IEEE EUI64 saved successfully.
* @retval OT_ERROR_NOT_CAPABLE Setting IEEE EUI64 unsupported by the remote device.
* @retval OT_ERROR_FAILED Failed to save IEEE EUI64.
*/
otError ot_rpc_set_factory_assigned_ieee_eui64(const otExtAddress * eui64);

#ifdef __cplusplus
}
#endif

/**
* @}
*/

#endif /* OT_RPC_H_ */
34 changes: 32 additions & 2 deletions samples/nrf_rpc/protocols_serialization/client/src/ot_shell.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
*/

#include "ot_shell.h"
#include <net/ot_rpc.h>

#include <zephyr/shell/shell.h>
#include <zephyr/net/net_ip.h>
Expand Down Expand Up @@ -1978,6 +1979,33 @@ static int cmd_dns_client_browse(const struct shell *sh, size_t argc, char *argv
return 0;
}

static otError ot_cli_command_eui64(const struct shell *sh, size_t argc, char *argv[])
{
otExtAddress ext_addr;

if (argc == 1) {
/* Read current EUI64 */
otLinkGetFactoryAssignedIeeeEui64(NULL, &ext_addr);
shell_print(sh, "%02x%02x%02x%02x%02x%02x%02x%02x", ext_addr.m8[0], ext_addr.m8[1],
ext_addr.m8[2], ext_addr.m8[3], ext_addr.m8[4], ext_addr.m8[5],
ext_addr.m8[6], ext_addr.m8[7]);
return OT_ERROR_NONE;
}

/* Set new EUI64 */
if (hex2bin(argv[1], strlen(argv[1]), ext_addr.m8, sizeof(ext_addr.m8)) !=
sizeof(ext_addr.m8)) {
return OT_ERROR_INVALID_ARGS;
}

return ot_rpc_set_factory_assigned_ieee_eui64(&ext_addr);
}

static int cmd_eui64(const struct shell *sh, size_t argc, char *argv[])
{
return ot_cli_command_invoke(ot_cli_command_eui64, sh, argc, argv);
}

SHELL_STATIC_SUBCMD_SET_CREATE(
ot_cmds, SHELL_CMD_ARG(ifconfig, NULL, "Interface management", cmd_ifconfig, 1, 1),
SHELL_CMD_ARG(ipmaddr, NULL, "IPv6 multicast configuration", cmd_ipmaddr, 1, 2),
Expand All @@ -1987,6 +2015,7 @@ SHELL_STATIC_SUBCMD_SET_CREATE(
SHELL_CMD_ARG(thread, NULL, "Role management", cmd_thread, 2, 0),
SHELL_CMD_ARG(discover, NULL, "Thread discovery scan", cmd_discover, 1, 4),
SHELL_CMD_ARG(radio, NULL, "Radio configuration", cmd_radio, 1, 1),
SHELL_CMD_ARG(eui64, NULL, "EUI64 configuration", cmd_eui64, 1, 1),
SHELL_CMD_ARG(test_message, NULL, "Test message API", cmd_test_message, 1, 0),
SHELL_CMD_ARG(test_udp_init, NULL, "Test udp init API", cmd_test_udp_init, 1, 0),
SHELL_CMD_ARG(test_udp_send, NULL, "Test udp send API", cmd_test_udp_send, 1, 0),
Expand Down Expand Up @@ -2067,8 +2096,9 @@ SHELL_STATIC_SUBCMD_SET_CREATE(
"Network diag, args: <get|reset> <IPv6-address>"
" <tlv-type ...>",
cmd_test_net_diag, 4, 255),
SHELL_CMD_ARG(test_mesh_diag, NULL, "Mesh diag topology discovery, args: <start|cancel>"
"[ip6] [children]",
SHELL_CMD_ARG(test_mesh_diag, NULL,
"Mesh diag topology discovery, args: <start|cancel>"
"[ip6] [children]",
cmd_test_mesh_diag, 2, 2),
SHELL_SUBCMD_SET_END);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#
# Copyright (c) 2024 Nordic Semiconductor
#
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
#

CONFIG_IEEE802154_NRF5_UICR_EUI64_ENABLE=y
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ boards:
nrf54l15dk/nrf54l15/cpuapp:
append:
EXTRA_DTC_OVERLAY_FILE: boards/nrf54l15dk_nrf54l15_cpuapp.overlay
EXTRA_CONF_FILE: boards/nrf54l15dk_nrf54l15_cpuapp.conf
nrf52840dk/nrf52840:
append:
EXTRA_DTC_OVERLAY_FILE: boards/nrf52840dk_nrf52840.overlay
19 changes: 16 additions & 3 deletions subsys/net/openthread/rpc/client/ot_rpc_link.c
Original file line number Diff line number Diff line change
Expand Up @@ -97,11 +97,24 @@ void otLinkGetFactoryAssignedIeeeEui64(otInstance *aInstance, otExtAddress *aEui

ARG_UNUSED(aInstance);

if (aEui64 == NULL) {
return;
}
__ASSERT_NO_MSG(aEui64 != NULL);

NRF_RPC_CBOR_ALLOC(&ot_group, ctx, 0);
nrf_rpc_cbor_cmd_no_err(&ot_group, OT_RPC_CMD_LINK_GET_FACTORY_ASSIGNED_EUI64, &ctx,
ot_rpc_decode_eui64, aEui64->m8);
}

otError ot_rpc_set_factory_assigned_ieee_eui64(const otExtAddress *eui64)
{
struct nrf_rpc_cbor_ctx ctx;
otError error;

__ASSERT_NO_MSG(eui64 != NULL);

NRF_RPC_CBOR_ALLOC(&ot_group, ctx, 1 + OT_EXT_ADDRESS_SIZE);
nrf_rpc_encode_buffer(&ctx, &eui64->m8, OT_EXT_ADDRESS_SIZE);
nrf_rpc_cbor_cmd_no_err(&ot_group, OT_RPC_CMD_LINK_SET_FACTORY_ASSIGNED_EUI64, &ctx,
ot_rpc_decode_error, &error);

return error;
}
3 changes: 3 additions & 0 deletions subsys/net/openthread/rpc/common/ot_rpc_ids.h
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,9 @@ enum ot_rpc_cmd_server {
OT_RPC_CMD_DNS_SERVICE_RESP_GET_SERVICE_INFO,
OT_RPC_CMD_DNS_SERVICE_RESP_GET_HOST_ADDRESS,
OT_RPC_CMD_LINK_RAW_GET_RADIO_TIME,

/* OpenThread over RPC API additions */
OT_RPC_CMD_LINK_SET_FACTORY_ASSIGNED_EUI64,
};

#endif /* OT_RPC_IDS_H_ */
61 changes: 61 additions & 0 deletions subsys/net/openthread/rpc/server/ot_rpc_link.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,18 @@

#include <nrf_rpc_cbor.h>

#include <zephyr/net/net_if.h>
#include <zephyr/net/openthread.h>
#include <zephyr/sys/byteorder.h>

#include <openthread/link.h>

#ifdef CONFIG_IEEE802154_NRF5_UICR_EUI64_ENABLE
#ifdef CONFIG_NRFX_RRAMC
#include <nrfx_rramc.h>
#endif
#endif

static void ot_rpc_cmd_set_poll_period(const struct nrf_rpc_group *group,
struct nrf_rpc_cbor_ctx *ctx, void *handler_data)
{
Expand Down Expand Up @@ -123,6 +131,55 @@ static void ot_rpc_cmd_get_factory_assigned_eui64(const struct nrf_rpc_group *gr
nrf_rpc_cbor_rsp_no_err(group, &rsp_ctx);
}

static void ot_rpc_cmd_set_factory_assigned_eui64(const struct nrf_rpc_group *group,
struct nrf_rpc_cbor_ctx *ctx, void *handler_data)
{
otError error = OT_ERROR_NOT_CAPABLE;
otExtAddress ext_addr;

nrf_rpc_decode_buffer(ctx, ext_addr.m8, OT_EXT_ADDRESS_SIZE);

if (!nrf_rpc_decoding_done_and_check(group, ctx)) {
ot_rpc_report_cmd_decoding_error(OT_RPC_CMD_LINK_SET_FACTORY_ASSIGNED_EUI64);
return;
}

#ifdef CONFIG_IEEE802154_NRF5_UICR_EUI64_ENABLE
#ifdef CONFIG_NRFX_RRAMC
if (nrfx_rramc_otp_word_write(CONFIG_IEEE802154_NRF5_UICR_EUI64_REG + 1,
sys_get_le32(ext_addr.m8)) &&
nrfx_rramc_otp_word_write(CONFIG_IEEE802154_NRF5_UICR_EUI64_REG,
sys_get_le32(ext_addr.m8 + 4))) {
error = OT_ERROR_NONE;
} else {
error = OT_ERROR_FAILED;
}
#endif
#endif

/*
* The IEEE EUI64 is only copied from UICR to the network interface once, during
* the network interface initialization, so the network interface must also be
* updated after writing the new identifier to UICR.
*/
if (IS_ENABLED(CONFIG_NET_L2_OPENTHREAD) && error == OT_ERROR_NONE) {
struct net_if *iface = net_if_get_first_by_type(&NET_L2_GET_NAME(OPENTHREAD));
struct net_linkaddr *addr;

__ASSERT_NO_MSG(iface != NULL);

net_if_lock(iface);
addr = net_if_get_link_addr(iface);

__ASSERT_NO_MSG(addr != NULL && addr->len == OT_EXT_ADDRESS_SIZE);

memcpy(addr->addr, ext_addr.m8, OT_EXT_ADDRESS_SIZE);
net_if_unlock(iface);
}

nrf_rpc_rsp_send_uint(group, error);
}

NRF_RPC_CBOR_CMD_DECODER(ot_group, ot_rpc_cmd_set_poll_period, OT_RPC_CMD_LINK_SET_POLL_PERIOD,
ot_rpc_cmd_set_poll_period, NULL);

Expand All @@ -143,3 +200,7 @@ NRF_RPC_CBOR_CMD_DECODER(ot_group, ot_rpc_cmd_set_link_enabled, OT_RPC_CMD_LINK_
NRF_RPC_CBOR_CMD_DECODER(ot_group, ot_rpc_cmd_get_factory_assigned_eui64,
OT_RPC_CMD_LINK_GET_FACTORY_ASSIGNED_EUI64,
ot_rpc_cmd_get_factory_assigned_eui64, NULL);

NRF_RPC_CBOR_CMD_DECODER(ot_group, ot_rpc_cmd_set_factory_assigned_eui64,
OT_RPC_CMD_LINK_SET_FACTORY_ASSIGNED_EUI64,
ot_rpc_cmd_set_factory_assigned_eui64, NULL);