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