Skip to content

Commit 6c765ac

Browse files
Damian-Nordicrlubos
authored andcommitted
net: openthread: rpc: implement otInstanceFactoryReset
Add RPC serialization of the otInstanceFactoryReset() API. By default, the RPC server simply calls the same API from the OpenThread stack upon receiving this RPC call. However, if CONFIG_OPENTHREAD_RPC_ERASE_SETTINGS Kconfig option is enabled, the RPC server erases the entire settings partition instead. Signed-off-by: Damian Krolik <[email protected]>
1 parent 4452c55 commit 6c765ac

File tree

8 files changed

+111
-2
lines changed

8 files changed

+111
-2
lines changed

samples/nrf_rpc/protocols_serialization/client/src/ot_shell.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1908,6 +1908,18 @@ static int cmd_rloc16(const struct shell *sh, size_t argc, char *argv[])
19081908
return ot_cli_command_exec(cmd_rloc16_impl, sh, argc, argv);
19091909
}
19101910

1911+
static otError cmd_factoryreset_impl(const struct shell *sh, size_t argc, char *argv[])
1912+
{
1913+
otInstanceFactoryReset(NULL);
1914+
1915+
return OT_ERROR_NONE;
1916+
}
1917+
1918+
static int cmd_factoryreset(const struct shell *sh, size_t argc, char *argv[])
1919+
{
1920+
return ot_cli_command_exec(cmd_factoryreset_impl, sh, argc, argv);
1921+
}
1922+
19111923
static void handle_udp_receive(void *context, otMessage *msg, const otMessageInfo *msg_info)
19121924
{
19131925
uint16_t offset;
@@ -2089,6 +2101,7 @@ SHELL_STATIC_SUBCMD_SET_CREATE(
20892101
SHELL_CMD_ARG(eui64, NULL, "EUI64 configuration", cmd_eui64, 1, 1),
20902102
SHELL_CMD_ARG(rloc16, NULL, "Get RLOC16", cmd_rloc16, 1, 0),
20912103
SHELL_CMD_ARG(udp, &udp_cmds, "UDP subcommands", NULL, 1, 0),
2104+
SHELL_CMD_ARG(factoryreset, NULL, "Factory reset", cmd_factoryreset, 1, 0),
20922105
SHELL_CMD_ARG(test_message, NULL, "Test message API", cmd_test_message, 1, 0),
20932106
SHELL_CMD_ARG(test_net_data, NULL, "Test netdata API", cmd_test_net_data, 1, 0),
20942107
SHELL_CMD_ARG(test_net_data_mesh_prefix, NULL, "Test netdata msh prefix API",

samples/nrf_rpc/protocols_serialization/server/sample.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,4 @@ tests:
3131
SNIPPET="ble;openthread;debug;coex;log_rpc;ci-shell"
3232
extra_configs:
3333
- CONFIG_NRF_RPC_UTILS_CRASH_GEN=y
34+
- CONFIG_OPENTHREAD_RPC_ERASE_SETTINGS=y

subsys/net/openthread/rpc/Kconfig

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ config OPENTHREAD_RPC_CLIENT_RADIO_TIME_REFRESH_PERIOD
7777

7878
endmenu # "OpenThread over RPC client configuration"
7979

80-
menu "OpenThread over RPC client configuration"
80+
menu "OpenThread over RPC server configuration"
8181
depends on OPENTHREAD_RPC_SERVER
8282

8383
config OPENTHREAD_RPC_MESSAGE_POOL
@@ -87,7 +87,14 @@ config OPENTHREAD_RPC_MESSAGE_POOL
8787
Defines maximum number of messages key indentifiers that can be allocated on server at
8888
the same time.
8989

90-
endmenu
90+
config OPENTHREAD_RPC_ERASE_SETTINGS
91+
bool "Erase settings partition on factory reset"
92+
depends on SETTINGS_NVS || SETTINGS_ZMS
93+
help
94+
Erase the entire settings partition when otInstanceFactoryReset() is invoked
95+
using a remote procedure call.
96+
97+
endmenu # "OpenThread over RPC server configuration"
9198

9299
config OPENTHREAD_RPC_INITIALIZE_NRF_RPC
93100
bool "Automatically initialize nRF RPC library"

subsys/net/openthread/rpc/client/ot_rpc_instance.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,17 @@ otError otInstanceErasePersistentInfo(otInstance *aInstance)
8080
return error;
8181
}
8282

83+
void otInstanceFactoryReset(otInstance *aInstance)
84+
{
85+
struct nrf_rpc_cbor_ctx ctx;
86+
87+
ARG_UNUSED(aInstance);
88+
89+
NRF_RPC_CBOR_ALLOC(&ot_group, ctx, 0);
90+
nrf_rpc_cbor_cmd_no_err(&ot_group, OT_RPC_CMD_INSTANCE_FACTORY_RESET, &ctx,
91+
nrf_rpc_rsp_decode_void, NULL);
92+
}
93+
8394
otError otSetStateChangedCallback(otInstance *aInstance, otStateChangedCallback aCallback,
8495
void *aContext)
8596
{

subsys/net/openthread/rpc/common/ot_rpc_ids.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ enum ot_rpc_cmd_server {
3737
OT_RPC_CMD_INSTANCE_IS_INITIALIZED,
3838
OT_RPC_CMD_INSTANCE_FINALIZE,
3939
OT_RPC_CMD_INSTANCE_ERASE_PERSISTENT_INFO,
40+
OT_RPC_CMD_INSTANCE_FACTORY_RESET,
4041
OT_RPC_CMD_IP6_GET_UNICAST_ADDRESSES,
4142
OT_RPC_CMD_IP6_GET_MULTICAST_ADDRESSES,
4243
OT_RPC_CMD_SET_STATE_CHANGED_CALLBACK,

subsys/net/openthread/rpc/server/ot_rpc_instance.c

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,14 @@
1212
#include <nrf_rpc_cbor.h>
1313

1414
#include <openthread/instance.h>
15+
#include <openthread/platform/misc.h>
16+
#include <openthread/thread.h>
1517

18+
#include <zephyr/fs/nvs.h>
19+
#include <zephyr/fs/zms.h>
1620
#include <zephyr/net/openthread.h>
21+
#include <zephyr/settings/settings.h>
22+
#include <zephyr/sys/__assert.h>
1723

1824
/* TODO: move to common */
1925
typedef struct ot_rpc_callback {
@@ -198,6 +204,52 @@ NRF_RPC_CBOR_CMD_DECODER(ot_group, ot_rpc_cmd_instance_erase_persistent_info,
198204
OT_RPC_CMD_INSTANCE_ERASE_PERSISTENT_INFO,
199205
ot_rpc_cmd_instance_erase_persistent_info, NULL);
200206

207+
static void ot_rpc_cmd_instance_factory_reset(const struct nrf_rpc_group *group,
208+
struct nrf_rpc_cbor_ctx *ctx, void *handler_data)
209+
{
210+
struct otInstance *inst;
211+
212+
nrf_rpc_cbor_decoding_done(group, ctx);
213+
214+
/*
215+
* The factory reset procedure involves rebooting the device, so send the response before it
216+
* begins, until there is still a chance.
217+
*/
218+
nrf_rpc_rsp_send_void(group);
219+
220+
inst = openthread_get_default_instance();
221+
222+
if (IS_ENABLED(CONFIG_OPENTHREAD_RPC_ERASE_SETTINGS)) {
223+
int rc;
224+
void *storage;
225+
226+
/*
227+
* Lock the system scheduler to assure that no setting is written after the storage
228+
* has been cleared and before the device is reset.
229+
*/
230+
k_sched_lock();
231+
rc = settings_storage_get(&storage);
232+
__ASSERT_NO_MSG(rc == 0);
233+
234+
if (IS_ENABLED(CONFIG_SETTINGS_NVS)) {
235+
nvs_clear(storage);
236+
} else {
237+
zms_clear(storage);
238+
}
239+
240+
otPlatReset(inst);
241+
k_sched_unlock();
242+
} else {
243+
ot_rpc_mutex_lock();
244+
otInstanceFactoryReset(inst);
245+
ot_rpc_mutex_unlock();
246+
}
247+
}
248+
249+
NRF_RPC_CBOR_CMD_DECODER(ot_group, ot_rpc_cmd_instance_factory_reset,
250+
OT_RPC_CMD_INSTANCE_FACTORY_RESET, ot_rpc_cmd_instance_factory_reset,
251+
NULL);
252+
201253
static void ot_state_changed_callback(otChangedFlags aFlags, void *aContext)
202254
{
203255
struct nrf_rpc_cbor_ctx ctx;

tests/subsys/net/openthread/rpc/client/src/instance_suite.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,14 @@ ZTEST(ot_rpc_instance, test_otInstanceErasePersistentInfo_error)
152152
zassert_equal(error, OT_ERROR_INVALID_STATE);
153153
}
154154

155+
/* Test serialization of otInstanceFactoryReset() */
156+
ZTEST(ot_rpc_instance, test_otInstanceFactoryReset)
157+
{
158+
mock_nrf_rpc_tr_expect_add(RPC_CMD(OT_RPC_CMD_INSTANCE_FACTORY_RESET), RPC_RSP());
159+
otInstanceFactoryReset(NULL);
160+
mock_nrf_rpc_tr_expect_done();
161+
}
162+
155163
/* Test serialization of otGetVersionString() */
156164
ZTEST(ot_rpc_instance, test_otGetVersionString)
157165
{

tests/subsys/net/openthread/rpc/server/src/instance_suite.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ FAKE_VALUE_FUNC(uint32_t, otInstanceGetId, otInstance *);
2222
FAKE_VALUE_FUNC(bool, otInstanceIsInitialized, otInstance *);
2323
FAKE_VOID_FUNC(otInstanceFinalize, otInstance *);
2424
FAKE_VALUE_FUNC(otError, otInstanceErasePersistentInfo, otInstance *);
25+
FAKE_VOID_FUNC(otInstanceFactoryReset, otInstance *);
2526
FAKE_VALUE_FUNC(const char *, otGetVersionString);
2627
FAKE_VALUE_FUNC(otError, otSetStateChangedCallback, otInstance *, otStateChangedCallback, void *);
2728
FAKE_VOID_FUNC(otRemoveStateChangeCallback, otInstance *, otStateChangedCallback, void *);
@@ -205,6 +206,21 @@ ZTEST(ot_rpc_instance, test_otInstanceErasePersistentInfo_error)
205206
zassert_equal(otInstanceErasePersistentInfo_fake.arg0_val, (otInstance *)instance);
206207
}
207208

209+
/*
210+
* Test reception of otInstanceFactoryReset() command.
211+
*/
212+
ZTEST(ot_rpc_instance, test_otInstanceFactoryReset)
213+
{
214+
uintptr_t instance = (uintptr_t)openthread_get_default_instance();
215+
216+
mock_nrf_rpc_tr_expect_add(RPC_RSP(), NO_RSP);
217+
mock_nrf_rpc_tr_receive(RPC_CMD(OT_RPC_CMD_INSTANCE_FACTORY_RESET));
218+
mock_nrf_rpc_tr_expect_done();
219+
220+
zassert_equal(otInstanceFactoryReset_fake.call_count, 1);
221+
zassert_equal(otInstanceFactoryReset_fake.arg0_val, (otInstance *)instance);
222+
}
223+
208224
/*
209225
* Test reception of otGetVersionString() command.
210226
*/

0 commit comments

Comments
 (0)