Skip to content

Commit

Permalink
nfc: rpc: initial nfc rpc implementation
Browse files Browse the repository at this point in the history
Commit adds the initial nfc rpc implementation.

Signed-off-by: Aleksandr Khromykh <aleksandr.khromykh@nordicsemi.no>
  • Loading branch information
alxelax authored and rlubos committed Aug 9, 2024
1 parent e117d41 commit 66d5c02
Show file tree
Hide file tree
Showing 15 changed files with 686 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -629,7 +629,7 @@ Libraries for networking
Libraries for NFC
-----------------

|no_changes_yet_note|
* Added an experimental serialization of NFC tag 2 APIs.

nRF RPC libraries
-----------------
Expand Down
3 changes: 2 additions & 1 deletion subsys/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ if (CONFIG_NFC_T2T_NRFXLIB OR
CONFIG_NFC_T4T_CC_FILE OR
CONFIG_NFC_T4T_HL_PROCEDURE OR
CONFIG_NFC_TNEP_TAG OR
CONFIG_NFC_TNEP_POLLER)
CONFIG_NFC_TNEP_POLLER OR
CONFIG_NFC_RPC)
add_subdirectory(nfc)
endif()
if(CONFIG_FW_INFO OR CONFIG_FW_INFO_API)
Expand Down
2 changes: 2 additions & 0 deletions subsys/nfc/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,5 @@ if (CONFIG_NFC_TNEP_TAG OR
CONFIG_NFC_TNEP_POLLER)
add_subdirectory(tnep)
endif()

add_subdirectory_ifdef(CONFIG_NFC_RPC rpc)
1 change: 1 addition & 0 deletions subsys/nfc/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,6 @@ rsource "t2t/Kconfig"
rsource "t4t/Kconfig"
rsource "lib/Kconfig"
rsource "tnep/Kconfig"
rsource "rpc/Kconfig"

endmenu
9 changes: 9 additions & 0 deletions subsys/nfc/rpc/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#
# Copyright (c) 2024 Nordic Semiconductor
#
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
#

add_subdirectory(common)
add_subdirectory_ifdef(CONFIG_NFC_RPC_CLIENT client)
add_subdirectory_ifdef(CONFIG_NFC_RPC_SERVER server)
47 changes: 47 additions & 0 deletions subsys/nfc/rpc/Kconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#
#
# Copyright (c) 2024 Nordic Semiconductor
#
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
#

menuconfig NFC_RPC
bool "NFC over RPC [EXPERIMENTAL]"
select NRF_RPC
select NRF_RPC_CBOR
select EXPERIMENTAL
help
Enables NFC serialization over RPC

if NFC_RPC

choice NFC_RPC_ROLE_CHOICE
prompt "NFC over RPC role selection"
default NFC_RPC_CLIENT
help
Selects the device role for NFC over RPC. The default role is
a client role.

config NFC_RPC_CLIENT
bool "NFC over RPC client"
help
Enables NFC over RPC client role that uses nRF RPC library to
invoke NFC functions on the remote core.

config NFC_RPC_SERVER
bool "NFC over RPC server"
help
Enables NFC over RPC server role that runs the full NFC
stack and exposes NFC functions using nRF RPC library to a client
running on the remote core.

endchoice

config NFC_RPC_INITIALIZE_NRF_RPC
bool "Automatically initialize nRF RPC library"
default n
help
Initialize nRF RPC library during the system startup. Disabling this
option allow user to initialize it in a different way.

endif # NFC_RPC
15 changes: 15 additions & 0 deletions subsys/nfc/rpc/client/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#
# Copyright (c) 2024 Nordic Semiconductor
#
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
#

zephyr_library()

zephyr_library_sources(
nfc_rpc_t2t_client.c
)

zephyr_library_include_directories(
${CMAKE_CURRENT_SOURCE_DIR}/../common
)
173 changes: 173 additions & 0 deletions subsys/nfc/rpc/client/nfc_rpc_t2t_client.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
/*
* Copyright (c) 2024 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
*/

#include <nrf_rpc/nrf_rpc_cbkproxy.h>
#include <nrf_rpc/nrf_rpc_serialize.h>

#include <nfc_rpc_ids.h>
#include <nfc_rpc_common.h>

#include <nfc_t2t_lib.h>

static void nfc_rpc_t2t_cb_rpc_handler(const struct nrf_rpc_group *group,
struct nrf_rpc_cbor_ctx *ctx, void *handler_data)
{
nfc_t2t_event_t event;
const uint8_t *data;
uint8_t *container = NULL;
size_t data_length;
void *context;
nfc_t2t_callback_t callback;

event = nrf_rpc_decode_uint(ctx);
data = nrf_rpc_decode_buffer_ptr_and_size(ctx, &data_length);
context = (void *)nrf_rpc_decode_uint(ctx);
callback = (nfc_t2t_callback_t)nrf_rpc_decode_callback_call(ctx);

if (data && data_length && callback) {
container = k_malloc(data_length);
}

if (container) {
memcpy(container, data, data_length);
}

if (!nrf_rpc_decoding_done_and_check(group, ctx)) {
nfc_rpc_report_decoding_error(NFC_RPC_CMD_T2T_CB);
k_free(container);
return;
}

if (container) {
callback(context, event, container, data_length);
k_free(container);
}

nrf_rpc_rsp_send_void(group);
}

NRF_RPC_CBOR_CMD_DECODER(nfc_group, nfc_rpc_t2t_cb, NFC_RPC_CMD_T2T_CB, nfc_rpc_t2t_cb_rpc_handler,
NULL);

int nfc_t2t_setup(nfc_t2t_callback_t callback, void *context)
{
struct nrf_rpc_cbor_ctx ctx;
size_t cbor_buffer_size = 0;
int error;

cbor_buffer_size += sizeof(uintptr_t) + 1; /* context */
cbor_buffer_size += sizeof(uint32_t) + 1; /* callback */

NRF_RPC_CBOR_ALLOC(&nfc_group, ctx, cbor_buffer_size);

nrf_rpc_encode_callback(&ctx, callback);
nrf_rpc_encode_uint(&ctx, (uintptr_t)context);

nrf_rpc_cbor_cmd_no_err(&nfc_group, NFC_RPC_CMD_T2T_SETUP, &ctx, nfc_rpc_decode_error,
&error);

return error;
}

int nfc_t2t_parameter_set(nfc_t2t_param_id_t id, void *data, size_t data_length)
{
struct nrf_rpc_cbor_ctx ctx;
size_t cbor_buffer_size = 1; /* nfc_t2t_param_id_t */
int error;

if (data == NULL) {
return -NRF_EINVAL;
}

cbor_buffer_size += data_length + 2;

NRF_RPC_CBOR_ALLOC(&nfc_group, ctx, cbor_buffer_size);

nrf_rpc_encode_uint(&ctx, id);
nrf_rpc_encode_buffer(&ctx, data, data_length);

nrf_rpc_cbor_cmd_no_err(&nfc_group, NFC_RPC_CMD_T2T_PARAMETER_SET, &ctx,
nfc_rpc_decode_error, &error);

return error;
}

int nfc_t2t_parameter_get(nfc_t2t_param_id_t id, void *data, size_t *max_data_length)
{
struct nrf_rpc_cbor_ctx ctx;
struct nfc_rpc_param_getter getter = {data, max_data_length};
size_t cbor_buffer_size = 2 + sizeof(nfc_t2t_param_id_t) + sizeof(size_t);

if (data == NULL || max_data_length == NULL) {
return -NRF_EINVAL;
}

NRF_RPC_CBOR_ALLOC(&nfc_group, ctx, cbor_buffer_size);

nrf_rpc_encode_uint(&ctx, id);
nrf_rpc_encode_uint(&ctx, *max_data_length);

nrf_rpc_cbor_cmd_no_err(&nfc_group, NFC_RPC_CMD_T2T_PARAMETER_GET, &ctx,
nfc_rpc_decode_parameter, &getter);

return getter.data ? 0 : -NRF_EINVAL;
}

static int send_payload(enum nfc_rpc_cmd_server cmd, const uint8_t *data, size_t data_length)
{
struct nrf_rpc_cbor_ctx ctx;
size_t cbor_buffer_size;
int error;

cbor_buffer_size = data_length + 3;
NRF_RPC_CBOR_ALLOC(&nfc_group, ctx, cbor_buffer_size);
nrf_rpc_encode_buffer(&ctx, data, data_length);
nrf_rpc_cbor_cmd_no_err(&nfc_group, cmd, &ctx, nfc_rpc_decode_error, &error);

return error;
}

int nfc_t2t_payload_set(const uint8_t *payload, size_t payload_length)
{
return send_payload(NFC_RPC_CMD_T2T_PAYLOAD_SET, payload, payload_length);
}

int nfc_t2t_payload_raw_set(const uint8_t *payload, size_t payload_length)
{
return send_payload(NFC_RPC_CMD_T2T_PAYLOAD_RAW_SET, payload, payload_length);
}

int nfc_t2t_internal_set(const uint8_t *data, size_t data_length)
{
return send_payload(NFC_RPC_CMD_T2T_INTERNAL_SET, data, data_length);
}

static int send_cmd(enum nfc_rpc_cmd_server cmd)
{
struct nrf_rpc_cbor_ctx ctx;
int error;

NRF_RPC_CBOR_ALLOC(&nfc_group, ctx, 0);

nrf_rpc_cbor_cmd_no_err(&nfc_group, cmd, &ctx, nfc_rpc_decode_error, &error);

return error;
}

int nfc_t2t_emulation_start(void)
{
return send_cmd(NFC_RPC_CMD_T2T_EMULATION_START);
}

int nfc_t2t_emulation_stop(void)
{
return send_cmd(NFC_RPC_CMD_T2T_EMULATION_STOP);
}

int nfc_t2t_done(void)
{
return send_cmd(NFC_RPC_CMD_T2T_DONE);
}
12 changes: 12 additions & 0 deletions subsys/nfc/rpc/common/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#
# Copyright (c) 2024 Nordic Semiconductor
#
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
#

zephyr_library()

zephyr_library_sources(
nfc_rpc_group.c
nfc_rpc_common.c
)
36 changes: 36 additions & 0 deletions subsys/nfc/rpc/common/nfc_rpc_common.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Copyright (c) 2024 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
*/

#include "nfc_rpc_common.h"

#include <nrf_rpc/nrf_rpc_serialize.h>

void nfc_rpc_decode_error(const struct nrf_rpc_group *group, struct nrf_rpc_cbor_ctx *ctx,
void *handler_data)
{
nrf_rpc_rsp_decode_i32(group, ctx, handler_data);
}

void nfc_rpc_report_decoding_error(uint8_t cmd_evt_id)
{
nrf_rpc_err(-EBADMSG, NRF_RPC_ERR_SRC_RECV, &nfc_group, cmd_evt_id,
NRF_RPC_PACKET_TYPE_CMD);
}

void nfc_rpc_decode_parameter(const struct nrf_rpc_group *group, struct nrf_rpc_cbor_ctx *ctx,
void *handler_data)
{
struct nfc_rpc_param_getter *getter = (struct nfc_rpc_param_getter *)handler_data;
const void *data;

data = nrf_rpc_decode_buffer_ptr_and_size(ctx, getter->length);

if (data == NULL) {
getter->data = NULL;
} else {
memcpy(getter->data, data, *getter->length);
}
}
26 changes: 26 additions & 0 deletions subsys/nfc/rpc/common/nfc_rpc_common.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Copyright (c) 2024 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
*/

#ifndef NFC_RPC_COMMON_H_
#define NFC_RPC_COMMON_H_

#include <nrf_rpc_cbor.h>

struct nfc_rpc_param_getter {
void *data;
size_t *length;
};

NRF_RPC_GROUP_DECLARE(nfc_group);

void nfc_rpc_decode_error(const struct nrf_rpc_group *group, struct nrf_rpc_cbor_ctx *ctx,
void *handler_data);
void nfc_rpc_decode_parameter(const struct nrf_rpc_group *group, struct nrf_rpc_cbor_ctx *ctx,
void *handler_data);
/* The function reports about command decoding error (not responses). */
void nfc_rpc_report_decoding_error(uint8_t cmd_evt_id);

#endif /* NFC_RPC_COMMON_H_ */
Loading

0 comments on commit 66d5c02

Please sign in to comment.