Skip to content

Commit

Permalink
nrf_rpc: Implement OT ned data APIs.
Browse files Browse the repository at this point in the history
APIs implemented:
- otNetDataGet
- otNetDataGetNextOnMeshPrefix
- otNetDataGetNextService

Signed-off-by: Przemyslaw Bida <przemyslaw.bida@nordicsemi.no>
  • Loading branch information
canisLupus1313 authored and rlubos committed Sep 5, 2024
1 parent f781fd5 commit 8255c7a
Show file tree
Hide file tree
Showing 7 changed files with 667 additions and 11 deletions.
53 changes: 53 additions & 0 deletions samples/nrf_rpc/protocols_serialization/client/src/ot_shell.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <openthread/link.h>
#include <openthread/thread.h>
#include <openthread/udp.h>
#include <openthread/netdata.h>
#include <openthread/message.h>

#include <string.h>
Expand Down Expand Up @@ -534,6 +535,53 @@ static int cmd_test_udp_close(const struct shell *sh, size_t argc, char *argv[])
return 0;
}

static int cmd_test_net_data(const struct shell *sh, size_t argc, char *argv[])
{
const size_t net_data_len = 255;
uint8_t buf[net_data_len];
uint8_t data_len = net_data_len;

if (otNetDataGet(NULL, false, buf, &data_len) == OT_ERROR_NONE) {
shell_print(sh, "Net dataget success.");
} else {
shell_print(sh, "Net dataget failed.");
}

if (otNetDataGet(NULL, true, buf, &data_len) == OT_ERROR_NONE) {
shell_print(sh, "Net dataget success.");
} else {
shell_print(sh, "Net dataget failed.");
}

return 0;
}

static int cmd_test_net_data_mesh_prefix(const struct shell *sh, size_t argc, char *argv[])
{
otNetworkDataIterator iterator = OT_NETWORK_DATA_ITERATOR_INIT;
otBorderRouterConfig config;
otError error;

while ((error = otNetDataGetNextOnMeshPrefix(NULL, &iterator, &config)) == OT_ERROR_NONE) {
shell_print(sh, "iterator %d", iterator);
}
shell_print(sh, "OT error: %d", error);
return 0;
}

static int cmd_test_net_data_next_service(const struct shell *sh, size_t argc, char *argv[])
{
otNetworkDataIterator iterator = OT_NETWORK_DATA_ITERATOR_INIT;
otServiceConfig config;
otError error;

while ((error = otNetDataGetNextService(NULL, &iterator, &config)) == OT_ERROR_NONE) {
shell_print(sh, "iterator %d", iterator);
}
shell_print(sh, "OT error: %d", error);
return 0;
}

static int cmd_ot(const struct shell *sh, size_t argc, char *argv[])
{
return ot_cli_command_send(sh, argc, argv);
Expand All @@ -552,6 +600,11 @@ SHELL_STATIC_SUBCMD_SET_CREATE(
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),
SHELL_CMD_ARG(test_udp_close, NULL, "Test udp close API", cmd_test_udp_close, 1, 0),
SHELL_CMD_ARG(test_net_data, NULL, "Test netdata API", cmd_test_net_data, 1, 0),
SHELL_CMD_ARG(test_net_data_mesh_prefix, NULL, "Test netdata msh prefix API",
cmd_test_net_data_mesh_prefix, 1, 0),
SHELL_CMD_ARG(test_net_data_next_service, NULL, "Test netdata next service API",
cmd_test_net_data_next_service, 1, 0),
SHELL_SUBCMD_SET_END);

SHELL_CMD_ARG_REGISTER(ot, &ot_cmds,
Expand Down
165 changes: 165 additions & 0 deletions subsys/net/openthread/rpc/client/ot_rpc_ctrl_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,16 @@
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
*/

#include "zcbor_common.h"
#include "zcbor_decode.h"
#include "zcbor_encode.h"
#include <ot_rpc_ids.h>
#include <ot_rpc_types.h>
#include <ot_rpc_common.h>

#include <nrf_rpc_cbor.h>

#include <openthread/netdata.h>
#include <openthread/ip6.h>
#include <openthread/link.h>
#include <openthread/thread.h>
Expand Down Expand Up @@ -481,3 +485,164 @@ void otLinkGetFactoryAssignedIeeeEui64(otInstance *aInstance, otExtAddress *aEui
nrf_rpc_cbor_cmd_no_err(&ot_group, OT_RPC_CMD_LINK_GET_FACTORY_ASSIGNED_EUI64, &ctx,
ot_rpc_decode_eui64, aEui64->m8);
}

otError otNetDataGet(otInstance *aInstance, bool aStable, uint8_t *aData, uint8_t *aDataLength)
{
struct zcbor_string zstr;
struct nrf_rpc_cbor_ctx ctx;
otError error = OT_ERROR_NONE;
bool decoded_ok = true;

NRF_RPC_CBOR_ALLOC(&ot_group, ctx, 5);

if (!zcbor_bool_put(ctx.zs, aStable)) {
NRF_RPC_CBOR_DISCARD(&ot_group, ctx);
error = OT_ERROR_INVALID_ARGS;
goto exit;
}

if (!zcbor_uint_encode(ctx.zs, aDataLength, sizeof(*aDataLength))) {
NRF_RPC_CBOR_DISCARD(&ot_group, ctx);
error = OT_ERROR_INVALID_ARGS;
goto exit;
}

nrf_rpc_cbor_cmd_rsp_no_err(&ot_group, OT_RPC_CMD_NETDATA_GET, &ctx);

decoded_ok = zcbor_nil_expect(ctx.zs, NULL);

if (decoded_ok) {
*aDataLength = 0;
goto decode_error;
}

if (ctx.zs->constant_state->error != ZCBOR_ERR_WRONG_TYPE) {
decoded_ok = false;
error = OT_ERROR_FAILED;
goto exit;
}

zcbor_pop_error(ctx.zs);

decoded_ok = zcbor_bstr_decode(ctx.zs, &zstr);

if (!decoded_ok) {
error = OT_ERROR_FAILED;
goto exit;
}

memcpy(aData, zstr.value, (zstr.len < *aDataLength ? zstr.len : *aDataLength));

decode_error:
if (!zcbor_uint_decode(ctx.zs, &error, sizeof(error))) {
error = OT_ERROR_FAILED;
}

nrf_rpc_cbor_decoding_done(&ot_group, &ctx);

exit:
if (!decoded_ok) {
nrf_rpc_cbor_decoding_done(&ot_group, &ctx);
ot_rpc_report_decoding_error(OT_RPC_CMD_NETDATA_GET);
}

return error;
}

otError otNetDataGetNextService(otInstance *aInstance, otNetworkDataIterator *aIterator,
otServiceConfig *aConfig)
{
struct nrf_rpc_cbor_ctx ctx;
otError error;
bool decoded_ok = true;

NRF_RPC_CBOR_ALLOC(&ot_group, ctx, sizeof(*aIterator) + 1);

if (!zcbor_uint_encode(ctx.zs, aIterator, sizeof(*aIterator))) {
NRF_RPC_CBOR_DISCARD(&ot_group, ctx);
error = OT_ERROR_INVALID_ARGS;
goto exit;
}

nrf_rpc_cbor_cmd_rsp_no_err(&ot_group, OT_RPC_CMD_NETDATA_GET_NEXT_SERVICE, &ctx);

decoded_ok = zcbor_uint_decode(ctx.zs, aIterator, sizeof(*aIterator));

if (!decoded_ok) {
error = OT_ERROR_FAILED;
goto exit;
}

decoded_ok = ot_rpc_decode_service_config(&ctx, aConfig);

if (!decoded_ok) {
error = OT_ERROR_FAILED;
goto exit;
}

decoded_ok = zcbor_uint_decode(ctx.zs, &error, sizeof(error));

if (!decoded_ok) {
error = OT_ERROR_FAILED;
goto exit;
}

nrf_rpc_cbor_decoding_done(&ot_group, &ctx);

exit:
if (!decoded_ok) {
nrf_rpc_cbor_decoding_done(&ot_group, &ctx);
ot_rpc_report_decoding_error(OT_RPC_CMD_NETDATA_GET_NEXT_SERVICE);
}

return error;
}

otError otNetDataGetNextOnMeshPrefix(otInstance *aInstance, otNetworkDataIterator *aIterator,
otBorderRouterConfig *aConfig)
{
struct nrf_rpc_cbor_ctx ctx;
otError error = OT_ERROR_NONE;
bool decoded_ok = true;

NRF_RPC_CBOR_ALLOC(&ot_group, ctx, sizeof(*aIterator) + 1);

if (!zcbor_uint_encode(ctx.zs, aIterator, sizeof(*aIterator))) {
NRF_RPC_CBOR_DISCARD(&ot_group, ctx);
error = OT_ERROR_INVALID_ARGS;
goto exit;
}

nrf_rpc_cbor_cmd_rsp_no_err(&ot_group, OT_RPC_CMD_NETDATA_GET_NEXT_ON_MESH_PREFIX, &ctx);

decoded_ok = zcbor_uint_decode(ctx.zs, aIterator, sizeof(*aIterator));

if (!decoded_ok) {
error = OT_ERROR_FAILED;
goto exit;
}

decoded_ok = ot_rpc_decode_border_router_config(&ctx, aConfig);

if (!decoded_ok) {
error = OT_ERROR_FAILED;
goto exit;
}

decoded_ok = zcbor_uint_decode(ctx.zs, &error, sizeof(error));

if (!decoded_ok) {
error = OT_ERROR_FAILED;
goto exit;
}

nrf_rpc_cbor_decoding_done(&ot_group, &ctx);

exit:
if (!decoded_ok) {
ot_rpc_report_decoding_error(OT_RPC_CMD_NETDATA_GET_NEXT_ON_MESH_PREFIX);
nrf_rpc_cbor_decoding_done(&ot_group, &ctx);
}

return error;
}
Loading

0 comments on commit 8255c7a

Please sign in to comment.