mgmt: mcumgr: Make Bluetooth and UDP transport init automatic

This moves the UDP and Bluetooth initialisation for MCUmgr to be
performed automatically with the new hander registration feature.

Signed-off-by: Jamie McCrae <jamie.mccrae@nordicsemi.no>
This commit is contained in:
Jamie McCrae 2022-12-09 14:54:54 +00:00 committed by Carles Cufí
commit b4b6346cdc
8 changed files with 149 additions and 45 deletions

View file

@ -87,4 +87,24 @@ config MCUMGR_SMP_BT_CONN_PARAM_CONTROL_RETRY_TIME
endif # MCUMGR_SMP_BT_CONN_PARAM_CONTROL
config MCUMGR_TRANSPORT_BT_AUTOMATIC_INIT
bool "Bluetooth SMP stack enable autostart/setup"
default y
help
If this option is enabled, then the Bluetooth stack will be enabled
when the Bluetooth SMP (MCUmgr) transport initialises. If another
system or the application does this, then this option should be
disabled. Note that Bluetooth will need to be enabled prior to the
Bluetooth SMP (MCUmgr) transport being initialised (by calling
``smp_bt_start()``) if this option is disabled.
config MCUMGR_TRANSPORT_BT_AUTOMATIC_INIT_WAIT
bool "Bluetooth SMP wait for autostart/setup completion"
default y
depends on MCUMGR_TRANSPORT_BT_AUTOMATIC_INIT
help
If this option is enabled, then the setup handler will wait for the
Bluetooth stack to become ready from the ``bt_enable()`` call,
otherwise will return instantly without waiting.
endif # MCUMGR_SMP_BT

View file

@ -56,4 +56,13 @@ config MCUMGR_SMP_UDP_MTU
MCUMGR_SMP_UDP_MTU <= MCUMGR_BUF_SIZE + SMP msg overhead - address size
where address size is determined by IPv4/IPv6 selection.
config MCUMGR_TRANSPORT_UDP_AUTOMATIC_INIT
bool "UDP SMP autostart/setup"
default y
help
Enable setting up the UDP SMP transport at boot time without needing
any code in the application to do this. Will automatically start the
UDP SMP service when the network interface is up and disable it when
it goes down (at layer 4).
endif # MCUMGR_SMP_UDP

View file

@ -9,7 +9,6 @@
* @brief Bluetooth transport for the mcumgr SMP protocol.
*/
#include <zephyr/kernel.h>
#include <zephyr/init.h>
#include <zephyr/bluetooth/bluetooth.h>
@ -24,6 +23,10 @@
#include <mgmt/mcumgr/transport/smp_internal.h>
#include <mgmt/mcumgr/transport/smp_reassembly.h>
#ifdef CONFIG_MCUMGR_TRANSPORT_BT_AUTOMATIC_INIT
#include <zephyr/mgmt/mcumgr/mgmt/handlers.h>
#endif
#include <zephyr/logging/log.h>
LOG_MODULE_DECLARE(mcumgr_smp, CONFIG_MCUMGR_SMP_LOG_LEVEL);
@ -87,6 +90,10 @@ static uint8_t next_id;
static struct smp_transport smp_bt_transport;
static struct conn_param_data conn_data[CONFIG_BT_MAX_CONN];
#ifdef CONFIG_MCUMGR_TRANSPORT_BT_AUTOMATIC_INIT
static K_SEM_DEFINE(bt_ready_sem, 0, 1);
#endif
/* SMP service.
* {8D53DC1D-1DB7-4CD3-868B-8A527460AA84}
*/
@ -627,10 +634,24 @@ static bool smp_bt_query_valid_check(struct net_buf *nb, void *arg)
return true;
}
static int smp_bt_init(const struct device *dev)
#ifdef CONFIG_MCUMGR_TRANSPORT_BT_AUTOMATIC_INIT_WAIT
static void bt_ready(int err)
{
if (err) {
LOG_ERR("Bluetooth init failed (err %d)", err);
return;
}
LOG_INF("Bluetooth initialised");
k_sem_give(&bt_ready_sem);
}
#endif
void smp_bt_start(void)
{
int rc;
uint8_t i = 0;
ARG_UNUSED(dev);
next_id = 1;
@ -639,6 +660,7 @@ static int smp_bt_init(const struct device *dev)
.connected = connected,
.disconnected = disconnected,
};
bt_conn_cb_register(&conn_callbacks);
if (IS_ENABLED(CONFIG_MCUMGR_SMP_BT_CONN_PARAM_CONTROL)) {
@ -653,7 +675,34 @@ static int smp_bt_init(const struct device *dev)
smp_transport_init(&smp_bt_transport, smp_bt_tx_pkt,
smp_bt_get_mtu, smp_bt_ud_copy,
smp_bt_ud_free, smp_bt_query_valid_check);
return 0;
rc = smp_bt_register();
if (rc != 0) {
LOG_ERR("Bluetooth SMP transport register failed (err %d)", rc);
}
}
SYS_INIT(smp_bt_init, APPLICATION, CONFIG_APPLICATION_INIT_PRIORITY);
#ifdef CONFIG_MCUMGR_TRANSPORT_BT_AUTOMATIC_INIT
static void smp_bt_setup(void)
{
/* Enable Bluetooth */
#ifdef CONFIG_MCUMGR_TRANSPORT_BT_AUTOMATIC_INIT_WAIT
int rc = bt_enable(bt_ready);
#else
int rc = bt_enable(NULL);
#endif
if (rc != 0) {
LOG_ERR("Bluetooth init failed (err %d)", rc);
} else {
#ifdef CONFIG_MCUMGR_TRANSPORT_BT_AUTOMATIC_INIT_WAIT
k_sem_take(&bt_ready_sem, K_FOREVER);
#endif
}
smp_bt_start();
}
MCUMGR_HANDLER_DEFINE(smp_bt, smp_bt_setup);
#endif

View file

@ -1,5 +1,6 @@
/*
* Copyright (c) 2019, Prevas A/S
* Copyright (c) 2019-2020, Prevas A/S
* Copyright (c) 2022 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -25,6 +26,13 @@
#include <mgmt/mcumgr/transport/smp_internal.h>
#ifdef CONFIG_MCUMGR_TRANSPORT_UDP_AUTOMATIC_INIT
#include <zephyr/mgmt/mcumgr/mgmt/handlers.h>
#include <zephyr/net/net_mgmt.h>
#include <zephyr/net/net_event.h>
#include <zephyr/net/net_conn_mgr.h>
#endif
#define LOG_LEVEL CONFIG_MCUMGR_LOG_LEVEL
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(smp_udp);
@ -64,6 +72,10 @@ static struct configs configs = {
#endif
};
#ifdef CONFIG_MCUMGR_TRANSPORT_UDP_AUTOMATIC_INIT
static struct net_mgmt_event_callback smp_udp_mgmt_cb;
#endif
#ifdef CONFIG_MCUMGR_SMP_UDP_IPV4
static int smp_udp4_tx(struct net_buf *nb)
{
@ -280,3 +292,33 @@ int smp_udp_close(void)
return MGMT_ERR_EOK;
}
#ifdef CONFIG_MCUMGR_TRANSPORT_UDP_AUTOMATIC_INIT
static void smp_udp_net_event_handler(struct net_mgmt_event_callback *cb, uint32_t mgmt_event,
struct net_if *iface)
{
ARG_UNUSED(cb);
ARG_UNUSED(iface);
if (mgmt_event == NET_EVENT_L4_CONNECTED) {
LOG_INF("Network connected");
if (smp_udp_open() < 0) {
LOG_ERR("Could not open SMP UDP");
}
} else if (mgmt_event == NET_EVENT_L4_DISCONNECTED) {
LOG_INF("Network disconnected");
smp_udp_close();
}
}
static void smp_udp_start(void)
{
net_mgmt_init_event_callback(&smp_udp_mgmt_cb, smp_udp_net_event_handler,
(NET_EVENT_L4_CONNECTED | NET_EVENT_L4_DISCONNECTED));
net_mgmt_add_event_callback(&smp_udp_mgmt_cb);
net_conn_mgr_resend_status();
}
MCUMGR_HANDLER_DEFINE(smp_udp, smp_udp_start);
#endif