Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow temporarily disabling device protection #2770

Merged
merged 35 commits into from
Jun 19, 2024
Merged
Show file tree
Hide file tree
Changes from 27 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
122fb42
Allow temporarily disabling protected device mode via a backup register
sergeuz May 16, 2024
8f20dec
Add a control request for temporarily disabling device protection
sergeuz May 20, 2024
8241e99
Minor fixes
sergeuz May 21, 2024
dd232bf
Add timeout for confirmation request
sergeuz May 23, 2024
ad2609d
Minor bugfixes and refactoring
sergeuz May 23, 2024
92634b9
Use a fake server key for testing
sergeuz May 24, 2024
7527d73
Bugfixes
sergeuz May 24, 2024
fc1568d
Allow disabling device protection on the fly
sergeuz May 29, 2024
126ce4d
Include server nonce in device signature
sergeuz May 29, 2024
276ae45
Check if the device is protected on every log operation
sergeuz May 30, 2024
e6b0f95
Remove the test key
sergeuz Jun 7, 2024
6ef4697
Bugfixes
sergeuz Jun 7, 2024
5145cb2
Regenerate Protobuf definitions; update submodule refs
sergeuz Jun 10, 2024
d4f6c0e
Bugfix
sergeuz Jun 10, 2024
49cd770
Regenerate Protobuf definitions; update submodule refs
sergeuz Jun 10, 2024
06ed956
Add device/server key fingerprints; minor refactoring
sergeuz Jun 10, 2024
0ea7f26
Minor fix
sergeuz Jun 10, 2024
0d0b6a4
Regenerate Protobuf definitions; update submodule refs
sergeuz Jun 10, 2024
171a6de
Minor fixes
sergeuz Jun 10, 2024
6633aca
Bugfix
sergeuz Jun 11, 2024
dd2f50c
Refactoring
sergeuz Jun 12, 2024
4cac07d
Do not disable logging when the device is protected
sergeuz Jun 12, 2024
46d4e6d
Disable Serial if the device is protected
sergeuz Jun 12, 2024
0b0a07f
Allow unprotecting the device over BLE
sergeuz Jun 14, 2024
f314d64
Fix GCC build
sergeuz Jun 14, 2024
2e07037
Fix newhal build
sergeuz Jun 14, 2024
03b1275
Fix rtl872x builds
sergeuz Jun 14, 2024
c116ce7
Clear the device protection override if the bootloader is not protected
sergeuz Jun 14, 2024
3c92c5d
Minor refactoring
sergeuz Jun 14, 2024
2a023fc
[gen3] disable IP_FRAG and IP_REASSEMBLY to save flash space
avtolstoy Jun 18, 2024
13605e3
Add a custom DfuSe command for entring safe mode
sergeuz Jun 18, 2024
dcf2c8f
[tracker] enable -fipa-pta (interprocedural pointer analysis and inte…
avtolstoy Jun 18, 2024
700bfc9
[build] extra -fdevirtualize-at-ltrans optimization for tracker
avtolstoy Jun 19, 2024
ad6f4d5
[build] clean up LTO usage
avtolstoy Jun 19, 2024
edefb7e
[build] more optimizations
avtolstoy Jun 19, 2024
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
2 changes: 2 additions & 0 deletions bootloader/src/nRF52840/nrf_it.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "hw_config.h"
#include "button_hal.h"
#include "hal_platform_nrf52840_config.h"
#include "security_mode.h"

extern void Timing_Decrement(void);

Expand Down Expand Up @@ -120,6 +121,7 @@ void UsageFault_Handler(void)
void SysTick_Handler(void)
{
System1MsTick();
security_mode_notify_system_tick();
Timing_Decrement();

#if HAL_PLATFORM_BUTTON_DEBOUNCE_IN_SYSTICK
Expand Down
2 changes: 2 additions & 0 deletions bootloader/src/rtl872x/rtl_it.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "button_hal.h"
#include "hal_platform_config.h"
#include "interrupts_irq.h"
#include "security_mode.h"

extern void Timing_Decrement(void);

Expand Down Expand Up @@ -170,6 +171,7 @@ void SecureFault_Handler(void) {
void SysTick_Handler(void)
{
System1MsTick();
security_mode_notify_system_tick();
Timing_Decrement();

#if HAL_PLATFORM_BUTTON_DEBOUNCE_IN_SYSTICK
Expand Down
2 changes: 0 additions & 2 deletions hal/inc/bootloader.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,6 @@ int bootloader_update(const void* bootloader_image, unsigned length);
// Make sure we have only one function to retrieve the bootloader version going forward.
uint16_t bootloader_get_version(void);

int bootloader_init_security_mode(void* reserved);

#ifdef __cplusplus
}
#endif
Expand Down
10 changes: 5 additions & 5 deletions hal/inc/hal_dynalib_usb.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,11 @@ DYNALIB_FN(0, hal_usb, HAL_USB_USART_Init, void(HAL_USB_USART_Serial, const HAL_
DYNALIB_FN(1, hal_usb, HAL_USB_USART_Begin, void(HAL_USB_USART_Serial, uint32_t, void *))
DYNALIB_FN(2, hal_usb, HAL_USB_USART_End, void(HAL_USB_USART_Serial))
DYNALIB_FN(3, hal_usb, HAL_USB_USART_Baud_Rate, unsigned int(HAL_USB_USART_Serial))
DYNALIB_FN(4, hal_usb, HAL_USB_USART_Available_Data, int32_t(HAL_USB_USART_Serial))
DYNALIB_FN(5, hal_usb, HAL_USB_USART_Available_Data_For_Write, int32_t(HAL_USB_USART_Serial))
DYNALIB_FN(6, hal_usb, HAL_USB_USART_Receive_Data, int32_t(HAL_USB_USART_Serial, uint8_t))
DYNALIB_FN(7, hal_usb, HAL_USB_USART_Send_Data, int32_t(HAL_USB_USART_Serial, uint8_t))
DYNALIB_FN(8, hal_usb, HAL_USB_USART_Flush_Data, void(HAL_USB_USART_Serial))
DYNALIB_FN_WRAP(4, hal_usb, HAL_USB_USART_Available_Data, protected, int32_t(HAL_USB_USART_Serial))
DYNALIB_FN_WRAP(5, hal_usb, HAL_USB_USART_Available_Data_For_Write, protected, int32_t(HAL_USB_USART_Serial))
DYNALIB_FN_WRAP(6, hal_usb, HAL_USB_USART_Receive_Data, protected, int32_t(HAL_USB_USART_Serial, uint8_t))
DYNALIB_FN_WRAP(7, hal_usb, HAL_USB_USART_Send_Data, protected, int32_t(HAL_USB_USART_Serial, uint8_t))
DYNALIB_FN_WRAP(8, hal_usb, HAL_USB_USART_Flush_Data, protected, void(HAL_USB_USART_Serial))
DYNALIB_FN(9, hal_usb, HAL_USB_USART_Is_Enabled, bool(HAL_USB_USART_Serial))
DYNALIB_FN(10, hal_usb, HAL_USB_USART_Is_Connected, bool(HAL_USB_USART_Serial))
DYNALIB_FN(11, hal_usb, HAL_USB_USART_LineCoding_BitRate_Handler, int32_t(void (*handler)(uint32_t bitRate), void* reserved))
Expand Down
12 changes: 7 additions & 5 deletions hal/inc/usb_hal.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@
#include "hw_config.h"
#endif

#include "security_mode.h"

#ifdef __cplusplus
extern "C" {
#endif
Expand Down Expand Up @@ -204,11 +206,11 @@ void HAL_USB_USART_Init(HAL_USB_USART_Serial serial, const HAL_USB_USART_Config*
void HAL_USB_USART_Begin(HAL_USB_USART_Serial serial, uint32_t baud, void *reserved);
void HAL_USB_USART_End(HAL_USB_USART_Serial serial);
unsigned int HAL_USB_USART_Baud_Rate(HAL_USB_USART_Serial serial);
int32_t HAL_USB_USART_Available_Data(HAL_USB_USART_Serial serial);
int32_t HAL_USB_USART_Available_Data_For_Write(HAL_USB_USART_Serial serial);
int32_t HAL_USB_USART_Receive_Data(HAL_USB_USART_Serial serial, uint8_t peek);
int32_t HAL_USB_USART_Send_Data(HAL_USB_USART_Serial serial, uint8_t data);
void HAL_USB_USART_Flush_Data(HAL_USB_USART_Serial serial);
SECURITY_MODE_PROTECTED_FN(int32_t, HAL_USB_USART_Available_Data, (HAL_USB_USART_Serial serial));
SECURITY_MODE_PROTECTED_FN(int32_t, HAL_USB_USART_Available_Data_For_Write, (HAL_USB_USART_Serial serial));
SECURITY_MODE_PROTECTED_FN(int32_t, HAL_USB_USART_Receive_Data, (HAL_USB_USART_Serial serial, uint8_t peek));
SECURITY_MODE_PROTECTED_FN(int32_t, HAL_USB_USART_Send_Data, (HAL_USB_USART_Serial serial, uint8_t data));
SECURITY_MODE_PROTECTED_FN(void, HAL_USB_USART_Flush_Data, (HAL_USB_USART_Serial serial));
bool HAL_USB_USART_Is_Enabled(HAL_USB_USART_Serial serial);
bool HAL_USB_USART_Is_Connected(HAL_USB_USART_Serial serial);
int32_t HAL_USB_USART_LineCoding_BitRate_Handler(void (*handler)(uint32_t bitRate), void* reserved);
Expand Down
13 changes: 0 additions & 13 deletions hal/src/nRF52840/bootloader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,16 +87,3 @@ uint16_t bootloader_get_version(void)
}
return info.module_version;
}

int bootloader_init_security_mode(void* reserved) {
CHECK_TRUE(FLASH_VerifyCRC32(FLASH_INTERNAL, BOOTLOADER_ADDR, FLASH_ModuleLength(FLASH_INTERNAL, BOOTLOADER_ADDR)), SYSTEM_ERROR_BAD_DATA);
module_info_security_mode_ext_t ext = {};
ext.ext.length = sizeof(ext);
CHECK(security_mode_find_extension(HAL_STORAGE_ID_INTERNAL_FLASH, BOOTLOADER_ADDR, &ext));

if (ext.security_mode == MODULE_INFO_SECURITY_MODE_PROTECTED) {
security_mode_set(ext.security_mode, nullptr);
}

return 0;
}
27 changes: 27 additions & 0 deletions hal/src/nRF52840/usb_hal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,10 +92,20 @@ int32_t HAL_USB_USART_Available_Data(HAL_USB_USART_Serial serial) {
return usb_uart_available_rx_data();
}

int32_t HAL_USB_USART_Available_Data_protected(HAL_USB_USART_Serial serial) {
CHECK_SECURITY_MODE_PROTECTED();
return HAL_USB_USART_Available_Data(serial);
}

int32_t HAL_USB_USART_Available_Data_For_Write(HAL_USB_USART_Serial serial) {
return usb_uart_available_tx_data();
}

int32_t HAL_USB_USART_Available_Data_For_Write_protected(HAL_USB_USART_Serial serial) {
CHECK_SECURITY_MODE_PROTECTED();
return HAL_USB_USART_Available_Data_For_Write(serial);
}

int32_t HAL_USB_USART_Receive_Data(HAL_USB_USART_Serial serial, uint8_t peek) {
if (usb_uart_available_rx_data() == 0) {
return -1;
Expand All @@ -108,14 +118,31 @@ int32_t HAL_USB_USART_Receive_Data(HAL_USB_USART_Serial serial, uint8_t peek) {
}
}

int32_t HAL_USB_USART_Receive_Data_protected(HAL_USB_USART_Serial serial, uint8_t peek) {
CHECK_SECURITY_MODE_PROTECTED();
return HAL_USB_USART_Receive_Data(serial, peek);
}

int32_t HAL_USB_USART_Send_Data(HAL_USB_USART_Serial serial, uint8_t data) {
return usb_uart_send(&data, 1);
}

int32_t HAL_USB_USART_Send_Data_protected(HAL_USB_USART_Serial serial, uint8_t data) {
CHECK_SECURITY_MODE_PROTECTED();
return HAL_USB_USART_Send_Data(serial, data);
}

void HAL_USB_USART_Flush_Data(HAL_USB_USART_Serial serial) {
usb_uart_flush_tx_data();
}

void HAL_USB_USART_Flush_Data_protected(HAL_USB_USART_Serial serial) {
if (security_mode_get(NULL) == MODULE_INFO_SECURITY_MODE_PROTECTED) {
return;
}
HAL_USB_USART_Flush_Data(serial);
}

bool HAL_USB_USART_Is_Enabled(HAL_USB_USART_Serial serial) {
return usb_hal_is_enabled();
}
Expand Down
13 changes: 0 additions & 13 deletions hal/src/rtl872x/bootloader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,16 +88,3 @@ uint16_t bootloader_get_version(void)
// hard code to unblock porting work for now
return 1001;
}

int bootloader_init_security_mode(void* reserved) {
CHECK_TRUE(FLASH_VerifyCRC32(FLASH_INTERNAL, BOOTLOADER_ADDR, FLASH_ModuleLength(FLASH_INTERNAL, BOOTLOADER_ADDR)), SYSTEM_ERROR_BAD_DATA);
module_info_security_mode_ext_t ext = {};
ext.ext.length = sizeof(ext);
CHECK(security_mode_find_extension(HAL_STORAGE_ID_INTERNAL_FLASH, BOOTLOADER_ADDR, &ext));

if (ext.security_mode == MODULE_INFO_SECURITY_MODE_PROTECTED) {
security_mode_set(ext.security_mode, nullptr);
}

return 0;
}
27 changes: 27 additions & 0 deletions hal/src/rtl872x/usb_hal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,11 @@ int32_t HAL_USB_USART_Available_Data(HAL_USB_USART_Serial serial) {
return getCdcClassDriver().available();
}

int32_t HAL_USB_USART_Available_Data_protected(HAL_USB_USART_Serial serial) {
CHECK_SECURITY_MODE_PROTECTED();
return HAL_USB_USART_Available_Data(serial);
}

int32_t HAL_USB_USART_Available_Data_For_Write(HAL_USB_USART_Serial serial) {
if (serial != HAL_USB_USART_SERIAL) {
return SYSTEM_ERROR_INVALID_ARGUMENT;
Expand All @@ -180,6 +185,11 @@ int32_t HAL_USB_USART_Available_Data_For_Write(HAL_USB_USART_Serial serial) {
return getCdcClassDriver().availableForWrite();
}

int32_t HAL_USB_USART_Available_Data_For_Write_protected(HAL_USB_USART_Serial serial) {
CHECK_SECURITY_MODE_PROTECTED();
return HAL_USB_USART_Available_Data_For_Write(serial);
}

int32_t HAL_USB_USART_Receive_Data(HAL_USB_USART_Serial serial, uint8_t peek) {
if (serial != HAL_USB_USART_SERIAL) {
return SYSTEM_ERROR_INVALID_ARGUMENT;
Expand All @@ -197,6 +207,11 @@ int32_t HAL_USB_USART_Receive_Data(HAL_USB_USART_Serial serial, uint8_t peek) {
return r;
}

int32_t HAL_USB_USART_Receive_Data_protected(HAL_USB_USART_Serial serial, uint8_t peek) {
CHECK_SECURITY_MODE_PROTECTED();
return HAL_USB_USART_Receive_Data(serial, peek);
}

int32_t HAL_USB_USART_Send_Data(HAL_USB_USART_Serial serial, uint8_t data) {
if (serial != HAL_USB_USART_SERIAL) {
return SYSTEM_ERROR_INVALID_ARGUMENT;
Expand All @@ -220,13 +235,25 @@ int32_t HAL_USB_USART_Send_Data(HAL_USB_USART_Serial serial, uint8_t data) {
return -1;
}

int32_t HAL_USB_USART_Send_Data_protected(HAL_USB_USART_Serial serial, uint8_t data) {
CHECK_SECURITY_MODE_PROTECTED();
return HAL_USB_USART_Send_Data(serial, data);
}

void HAL_USB_USART_Flush_Data(HAL_USB_USART_Serial serial) {
if (serial != HAL_USB_USART_SERIAL) {
return;
}
return getCdcClassDriver().flush();
}

void HAL_USB_USART_Flush_Data_protected(HAL_USB_USART_Serial serial) {
if (security_mode_get(NULL) == MODULE_INFO_SECURITY_MODE_PROTECTED) {
return;
}
return HAL_USB_USART_Flush_Data(serial);
}

bool HAL_USB_USART_Is_Enabled(HAL_USB_USART_Serial serial) {
if (serial != HAL_USB_USART_SERIAL) {
return false;
Expand Down
2 changes: 1 addition & 1 deletion platform/MCU/nRF52840/inc/dct.h
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ STATIC_ASSERT_FLAGS_OFFSET(Factory_Reset_Done_SysFlag, 17);
STATIC_ASSERT_FLAGS_OFFSET(StartupMode_SysFlag, 18);
STATIC_ASSERT_FLAGS_OFFSET(FeaturesEnabled_SysFlag, 19);
STATIC_ASSERT_FLAGS_OFFSET(RCC_CSR_SysFlag, 20);
STATIC_ASSERT_FLAGS_OFFSET(reserved, 24);
STATIC_ASSERT_FLAGS_OFFSET(reserved, 30);


#ifdef __cplusplus
Expand Down
7 changes: 6 additions & 1 deletion platform/MCU/nRF52840/inc/platform_system_flags.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,12 @@ typedef struct __attribute__((packed)) platform_system_flags {
uint8_t FeaturesEnabled_SysFlag; // default is 0xFF all features enabled. If any bits are cleared in the bottom 4-bits, then the upper 4 bits should be the logical inverse of these.
// This is to prevent against corrupted data causing the bootloader to be unavailable.
uint32_t RCC_CSR_SysFlag;
uint16_t reserved[4];

uint8_t security_mode_override_value; // If not 0xff, specifies the temporary security mode that overrides the normal mode
uint8_t security_mode_override_reset_count; // Number of system resets after which the normal security mode will be restored
uint32_t security_mode_override_timeout; // Timeout, in seconds, after which the normal security mode will be restored

uint16_t reserved[1];
} platform_system_flags_t;

PARTICLE_STATIC_ASSERT(platform_system_flags_size_changed, sizeof(platform_system_flags_t) == 32);
Expand Down
9 changes: 6 additions & 3 deletions platform/MCU/nRF52840/src/hw_config.c
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,10 @@ void Set_System(void)
SPARK_ASSERT(!hal_flash_init());
SPARK_ASSERT(!hal_exflash_init());

bootloader_init_security_mode(NULL);
security_mode_init();
#if MODULE_FUNCTION == MOD_FUNC_BOOTLOADER
security_mode_notify_system_reset();
#endif

configure_uicr();

Expand Down Expand Up @@ -324,7 +327,7 @@ __attribute__((section(".retained_system_flags"))) platform_system_flags_t syste

#define SYSTEM_FLAGS_MAGIC_NUMBER 0x1ADEACC0u

void Load_SystemFlags()
void Load_SystemFlags() // TODO: Rename to Init_SystemFlags() and call once on startup
{
// if the header does not match the expected magic value, then initialize
if (system_flags.header!=SYSTEM_FLAGS_MAGIC_NUMBER) {
Expand All @@ -333,7 +336,7 @@ void Load_SystemFlags()
}
}

void Save_SystemFlags()
void Save_SystemFlags() // TODO: Remove
{
// nothing to do here
}
Expand Down
2 changes: 1 addition & 1 deletion platform/MCU/rtl872x/inc/dct.h
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ STATIC_ASSERT_FLAGS_OFFSET(StartupMode_SysFlag, 18);
STATIC_ASSERT_FLAGS_OFFSET(FeaturesEnabled_SysFlag, 19);
STATIC_ASSERT_FLAGS_OFFSET(RCC_CSR_SysFlag, 20);
STATIC_ASSERT_FLAGS_OFFSET(restore_backup_ram, 24);
STATIC_ASSERT_FLAGS_OFFSET(reserved, 26);
STATIC_ASSERT_FLAGS_OFFSET(reserved, 32);


#ifdef __cplusplus
Expand Down
7 changes: 6 additions & 1 deletion platform/MCU/rtl872x/inc/platform_system_flags.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,12 @@ typedef struct __attribute__((packed)) platform_system_flags {
// bit 0: 1: restore backup ram from flash
// bit 1: 1: session data in flash is stale
uint16_t restore_backup_ram;
uint16_t reserved[3];

uint8_t security_mode_override_value; // If not 0xff, specifies the temporary security mode that overrides the normal mode
uint8_t security_mode_override_reset_count; // Number of system resets after which the normal security mode will be restored
uint32_t security_mode_override_timeout; // Timeout, in seconds, after which the normal security mode will be restored

uint16_t reserved[0];
} platform_system_flags_t;

PARTICLE_STATIC_ASSERT(platform_system_flags_size_changed, sizeof(platform_system_flags_t) == 32);
Expand Down
9 changes: 6 additions & 3 deletions platform/MCU/rtl872x/src/hw_config.c
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,10 @@ void Set_System(void)
/* Configure flash */
SPARK_ASSERT(!hal_exflash_init());

bootloader_init_security_mode(NULL);
security_mode_init();
#if MODULE_FUNCTION == MOD_FUNC_BOOTLOADER
security_mode_notify_system_reset();
#endif

efuse_configure();
DWT_Init();
Expand Down Expand Up @@ -495,7 +498,7 @@ __attribute__((section(".retained_system_flags"))) platform_system_flags_t syste

#define SYSTEM_FLAGS_MAGIC_NUMBER 0x1ADEACC0u

void Load_SystemFlags()
void Load_SystemFlags() // TODO: Rename to Init_SystemFlags() and call once on startup
{
// if the header does not match the expected magic value, then initialize
if (system_flags.header!=SYSTEM_FLAGS_MAGIC_NUMBER) {
Expand All @@ -504,7 +507,7 @@ void Load_SystemFlags()
}
}

void Save_SystemFlags()
void Save_SystemFlags() // TODO: Remove
{
// nothing to do here
}
Expand Down
2 changes: 1 addition & 1 deletion proto_defs/shared
16 changes: 16 additions & 0 deletions proto_defs/src/control/config.pb.c
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,21 @@ PB_BIND(particle_ctrl_GetProtectedStateRequest, particle_ctrl_GetProtectedStateR
PB_BIND(particle_ctrl_GetProtectedStateReply, particle_ctrl_GetProtectedStateReply, AUTO)


PB_BIND(particle_ctrl_SetProtectedStateRequest, particle_ctrl_SetProtectedStateRequest, AUTO)


PB_BIND(particle_ctrl_SetProtectedStateRequest_Prepare, particle_ctrl_SetProtectedStateRequest_Prepare, AUTO)


PB_BIND(particle_ctrl_SetProtectedStateRequest_Confirm, particle_ctrl_SetProtectedStateRequest_Confirm, AUTO)


PB_BIND(particle_ctrl_SetProtectedStateReply, particle_ctrl_SetProtectedStateReply, AUTO)


PB_BIND(particle_ctrl_SetProtectedStateReply_Prepare, particle_ctrl_SetProtectedStateReply_Prepare, AUTO)


PB_BIND(particle_ctrl_SystemResetRequest, particle_ctrl_SystemResetRequest, AUTO)


Expand Down Expand Up @@ -168,3 +183,4 @@ PB_BIND(particle_ctrl_StopNyanSignalReply, particle_ctrl_StopNyanSignalReply, AU




Loading