Bluetooth Low Energy Remote Procedure Call

The Bluetooth® Low Energy Remote Procedure Call (RPC) solution is a set of libraries that allows using the Bluetooth Low Energy stack running entirely on a separate device or CPU.

Overview

The solution allows calling the Bluetooth Low Energy API on a different CPU or device. This is accomplished by running a full Bluetooth Low Energy stack on one device and serializing the API from another device. Use this solution when you do not want your firmware to include the Bluetooth stack, for example to offload the application CPU, save memory, or to be able to build your application in a different environment.

Implementation

The Bluetooth Low Energy RPC is a solution that consists of the following components:

  • Bluetooth RPC Client and common software libraries that serialize the Bluetooth Host API and enable RPC communication. These libraries need to be part of the user application.

  • IPC radio firmware application that includes the full configuration of the Bluetooth Low Energy stack, Bluetooth RPC Host and common libraries that enable communication with the Bluetooth RPC Client. This software includes the Controller and needs to run on a device or CPU that has the radio hardware peripheral, for example nRF5340 network core.

  • Build system files that automate building a Bluetooth LE application in the RPC variant with the additional image containing the Bluetooth LE stack.

You can add support for serializing Bluetooth-related custom APIs by implementing your own client and host procedures. You can use the following files as examples:

  • subsys/bluetooth/rpc/client/bt_rpc_conn_client.c

  • subsys/bluetooth/rpc/host/bt_rpc_conn_host.c

Supported backends

The library supports the following two Bluetooth Low Energy controllers:

Requirements

Some configuration options related to Bluetooth Low Energy must be the same on the host and client. Set the following options in the same way for the IPC radio firmware or Bluetooth: Host for nRF RPC Bluetooth Low Energy, and application core:

To keep all the above configuration options in sync, you can create a snippet with an overlay file that is shared between the application and network core. Then, you can invoke build command like this:

west build -b board_target -S my_snippet

For more details, see the Snippets documentation.

Configuration

To enable the Bluetooth Low Energy RPC library, use the sysbuild configuration SB_CONFIG_NETCORE_IPC_RADIO along with the SB_CONFIG_NETCORE_IPC_RADIO_BT_RPC option. Set the SNIPPET to nordic-bt-rpc to apply the necessary configuration for the Bluetooth Low Energy RPC library on both cores. If you use a custom board, you need to create a custom snippet with a similar configuration to the nordic-bt-rpc snippet.

Build the application using the following command:

west build -b *board_name* -S nordic-bt-rpc -- -DSB_CONFIG_NETCORE_IPC_RADIO=y -DSB_CONFIG_NETCORE_IPC_RADIO_BT_RPC=y

Note

The samples that support the Bluetooth Low Energy RPC use the FILE_SUFFIX variable along with SNIPPET to adjust the selection and configuration of the network and radio core firmware.

Samples using the library

The following nRF Connect SDK sample and application use this library:

The following nRF Connect SDK samples can optionally use this library:

The IPC radio firmware sample, is a configurable application, that exposes the Bluetooth LE stack functionality running on an MCU with radio (for example, the nRF5340 network core) to another CPU through the Remote procedure call library (nRF RPC). When using the IPC radio firmware as Bluetooth Low Energy over RPC, reconfigure it by setting the SB_CONFIG_NETCORE_IPC_RADIO_BT_RPC sysbuild Kconfig option to y to run the whole Bluetooth LE stack on the network core. For more details, see the Configuration section of the IPC radio firmware application guide.

The Bluetooth: Host for nRF RPC Bluetooth Low Energy application is an alternative to the IPC radio firmware sample.

Limitations

The library currently supports serialization of the following:

The behavior of the Bluetooth implementation is almost the same as Zephyr’s with the following exceptions:

  • The latency is longer because of the overhead for exchanging messages between cores. The Bluetooth LE API is not strictly real-time by design, so the additional latency introduced by the IPC communication should be acceptable in most applications. To reduce the latency, consider using a different transport backend for nRF RPC. See Architecture for details.

  • Using advanced Bluetooth LE configurations, such as multiple simultaneous connections or advanced security features can be a limitation, because the child image (Bluetooth: Host for nRF RPC Bluetooth Low Energy or IPC radio firmware) might require significantly more memory than the MCU it runs on has available. Typically, network or radio cores are more memory-constrained than the application MCU.

  • The bt_gatt_cancel() function is not implemented.

  • The flags field of the bt_gatt_subscribe_params structure is atomic, so it cannot be correctly handled by the nRF RPC. The library implements the following workaround for it:

Dependencies

The library has the following dependencies:

API documentation

This library does not define a new Bluetooth API except for flags modification. Instead, it uses Zephyr’s API.

Header file: include/bluetooth/bt_rpc.h
Source files: subsys/bluetooth/rpc/
group bt_rpc

API additions for the bluetooth over RPC.

Functions

int bt_rpc_gatt_subscribe_flag_set(struct bt_gatt_subscribe_params *params, uint32_t flags_bit)

Set flag in the flags field of the bt_gatt_subscribe_params structure.

This function must be used instead of atomic_set_bit() if you are using BLE API over RPC.

Parameters:
  • params – Subscribe parameters.

  • flags_bit – Index of bit to set.

Returns:

Previous flag value (retrieved non-atomically) in case of success or negative value in case of error.

int bt_rpc_gatt_subscribe_flag_clear(struct bt_gatt_subscribe_params *params, uint32_t flags_bit)

Clear flag in the flags field of the bt_gatt_subscribe_params structure.

This function must be used instead of atomic_clear_bit() if you are using BLE API over RPC.

Parameters:
  • params – Subscribe parameters.

  • flags_bit – Index of bit to clear.

Returns:

Previous flag value (retrieved non-atomically) in case of success or negative value in case of error.

int bt_rpc_gatt_subscribe_flag_get(struct bt_gatt_subscribe_params *params, uint32_t flags_bit)

Get flag value from the flags field of the bt_gatt_subscribe_params structure.

This function must be used instead of atomic_test_bit() if you are using BLE API over RPC.

Parameters:
  • params – Subscribe parameters.

  • flags_bit – Index of bit to test.

Returns:

Flag value in case of success or negative value in case of error.