1 /* 2 * Copyright Runtime.io 2018. All rights reserved. 3 * Copyright (c) 2022-2023 Nordic Semiconductor ASA 4 * 5 * SPDX-License-Identifier: Apache-2.0 6 */ 7 8 #ifndef ZEPHYR_INCLUDE_MGMT_SMP_H_ 9 #define ZEPHYR_INCLUDE_MGMT_SMP_H_ 10 11 #include <zephyr/kernel.h> 12 13 #ifdef __cplusplus 14 extern "C" { 15 #endif 16 17 /** 18 * @brief MCUmgr transport SMP API 19 * @defgroup mcumgr_transport_smp MCUmgr transport SMP API 20 * @ingroup mcumgr 21 * @{ 22 */ 23 24 struct smp_transport; 25 struct zephyr_smp_transport; 26 struct net_buf; 27 28 /** @typedef smp_transport_out_fn 29 * @brief SMP transmit callback for transport 30 * 31 * The supplied net_buf is always consumed, regardless of return code. 32 * 33 * @param nb The net_buf to transmit. 34 * 35 * @return 0 on success, #mcumgr_err_t code on failure. 36 */ 37 typedef int (*smp_transport_out_fn)(struct net_buf *nb); 38 39 /** @typedef smp_transport_get_mtu_fn 40 * @brief SMP MTU query callback for transport 41 * 42 * The supplied net_buf should contain a request received from the peer whose 43 * MTU is being queried. This function takes a net_buf parameter because some 44 * transports store connection-specific information in the net_buf user header 45 * (e.g., the BLE transport stores the peer address). 46 * 47 * @param nb Contains a request from the relevant peer. 48 * 49 * @return The transport's MTU; 50 * 0 if transmission is currently not possible. 51 */ 52 typedef uint16_t (*smp_transport_get_mtu_fn)(const struct net_buf *nb); 53 54 /** @typedef smp_transport_ud_copy_fn 55 * @brief SMP copy user_data callback 56 * 57 * The supplied src net_buf should contain a user_data that cannot be copied 58 * using regular memcpy function (e.g., the BLE transport net_buf user_data 59 * stores the connection reference that has to be incremented when is going 60 * to be used by another buffer). 61 * 62 * @param dst Source buffer user_data pointer. 63 * @param src Destination buffer user_data pointer. 64 * 65 * @return 0 on success, #mcumgr_err_t code on failure. 66 */ 67 typedef int (*smp_transport_ud_copy_fn)(struct net_buf *dst, 68 const struct net_buf *src); 69 70 /** @typedef smp_transport_ud_free_fn 71 * @brief SMP free user_data callback 72 * 73 * This function frees net_buf user data, because some transports store 74 * connection-specific information in the net_buf user data (e.g., the BLE 75 * transport stores the connection reference that has to be decreased). 76 * 77 * @param ud Contains a user_data pointer to be freed. 78 */ 79 typedef void (*smp_transport_ud_free_fn)(void *ud); 80 81 /** @typedef smp_transport_query_valid_check_fn 82 * @brief Function for checking if queued data is still valid. 83 * 84 * This function is used to check if queued SMP data is still valid e.g. on a remote device 85 * disconnecting, this is triggered when smp_rx_remove_invalid() is called. 86 * 87 * @param nb net buf containing queued request. 88 * @param arg Argument provided when calling smp_rx_remove_invalid() function. 89 * 90 * @return false if data is no longer valid/should be freed, true otherwise. 91 */ 92 typedef bool (*smp_transport_query_valid_check_fn)(struct net_buf *nb, void *arg); 93 94 /** 95 * @brief Function pointers of SMP transport functions, if a handler is NULL then it is not 96 * supported/implemented. 97 */ 98 struct smp_transport_api_t { 99 /** Transport's send function. */ 100 smp_transport_out_fn output; 101 102 /** Transport's get-MTU function. */ 103 smp_transport_get_mtu_fn get_mtu; 104 105 /** Transport buffer user_data copy function. */ 106 smp_transport_ud_copy_fn ud_copy; 107 108 /** Transport buffer user_data free function. */ 109 smp_transport_ud_free_fn ud_free; 110 111 /** Transport's check function for if a query is valid. */ 112 smp_transport_query_valid_check_fn query_valid_check; 113 }; 114 115 /** 116 * @brief SMP transport object for sending SMP responses. 117 */ 118 struct smp_transport { 119 /* Must be the first member. */ 120 struct k_work work; 121 122 /* FIFO containing incoming requests to be processed. */ 123 struct k_fifo fifo; 124 125 /* Function pointers */ 126 struct smp_transport_api_t functions; 127 128 #ifdef CONFIG_MCUMGR_TRANSPORT_REASSEMBLY 129 /* Packet reassembly internal data, API access only */ 130 struct { 131 struct net_buf *current; /* net_buf used for reassembly */ 132 uint16_t expected; /* expected bytes to come */ 133 } __reassembly; 134 #endif 135 }; 136 137 /** 138 * @brief SMP transport type for client registration 139 */ 140 enum smp_transport_type { 141 /** SMP serial */ 142 SMP_SERIAL_TRANSPORT = 0, 143 /** SMP bluetooth */ 144 SMP_BLUETOOTH_TRANSPORT, 145 /** SMP shell*/ 146 SMP_SHELL_TRANSPORT, 147 /** SMP UDP IPv4 */ 148 SMP_UDP_IPV4_TRANSPORT, 149 /** SMP UDP IPv6 */ 150 SMP_UDP_IPV6_TRANSPORT, 151 /** SMP user defined type */ 152 SMP_USER_DEFINED_TRANSPORT 153 }; 154 155 /** 156 * @brief SMP Client transport structure 157 */ 158 struct smp_client_transport_entry { 159 sys_snode_t node; 160 /** Transport structure pointer */ 161 struct smp_transport *smpt; 162 /** Transport type */ 163 int smpt_type; 164 }; 165 166 /** 167 * @brief Initializes a Zephyr SMP transport object. 168 * 169 * @param smpt The transport to construct. 170 * 171 * @return 0 If successful 172 * @return Negative errno code if failure. 173 */ 174 int smp_transport_init(struct smp_transport *smpt); 175 176 /** 177 * @brief Used to remove queued requests for an SMP transport that are no longer valid. A 178 * smp_transport_query_valid_check_fn() function must be registered for this to 179 * function. If the smp_transport_query_valid_check_fn() function returns false 180 * during a callback, the queried command will classed as invalid and dropped. 181 * 182 * @param zst The transport to use. 183 * @param arg Argument provided to callback smp_transport_query_valid_check_fn() function. 184 */ 185 void smp_rx_remove_invalid(struct smp_transport *zst, void *arg); 186 187 /** 188 * @brief Used to clear pending queued requests for an SMP transport. 189 * 190 * @param zst The transport to use. 191 */ 192 void smp_rx_clear(struct smp_transport *zst); 193 194 /** 195 * @brief Register a Zephyr SMP transport object for client. 196 * 197 * @param entry The transport to construct. 198 */ 199 void smp_client_transport_register(struct smp_client_transport_entry *entry); 200 201 /** 202 * @brief Discover a registered SMP transport client object. 203 * 204 * @param smpt_type Type of transport 205 * 206 * @return Pointer to registered object. Unknown type return NULL. 207 */ 208 struct smp_transport *smp_client_transport_get(int smpt_type); 209 210 /** 211 * @} 212 */ 213 214 #ifdef __cplusplus 215 } 216 #endif 217 218 #endif 219