1 /*
2  * Copyright (c) 2018-2021 mcumgr authors
3  * Copyright (c) 2023 Nordic Semiconductor ASA
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 /**
9  * @file
10  * @brief SMP - Simple Management Protocol.
11  *
12  * SMP is a basic protocol that sits on top of the mgmt layer.  SMP requests
13  * and responses have the following format:
14  *
15  *	 [Offset 0]: Mgmt header
16  *	 [Offset 8]: CBOR map of command-specific key-value pairs.
17  *
18  * SMP request packets may contain multiple concatenated requests.  Each
19  * request must start at an offset that is a multiple of 4, so padding should
20  * be inserted between requests as necessary.  Requests are processed
21  * sequentially from the start of the packet to the end.  Each response is sent
22  * individually in its own packet.  If a request elicits an error response,
23  * processing of the packet is aborted.
24  */
25 
26 #ifndef H_SMP_
27 #define H_SMP_
28 
29 #include <zephyr/net/buf.h>
30 #include <zephyr/mgmt/mcumgr/transport/smp.h>
31 
32 #include <zcbor_common.h>
33 
34 #ifdef __cplusplus
35 extern "C" {
36 #endif
37 
38 /** SMP MCUmgr protocol version, part of the SMP header */
39 enum smp_mcumgr_version_t {
40 	/** Version 1: the original protocol */
41 	SMP_MCUMGR_VERSION_1 = 0,
42 
43 	/** Version 2: adds more detailed error reporting capabilities */
44 	SMP_MCUMGR_VERSION_2,
45 };
46 
47 struct cbor_nb_reader {
48 	struct net_buf *nb;
49 	/* CONFIG_MCUMGR_SMP_CBOR_MAX_DECODING_LEVELS + 2 translates to minimal
50 	 * zcbor backup states.
51 	 */
52 	zcbor_state_t zs[CONFIG_MCUMGR_SMP_CBOR_MAX_DECODING_LEVELS + 2];
53 };
54 
55 struct cbor_nb_writer {
56 	struct net_buf *nb;
57 	zcbor_state_t zs[CONFIG_MCUMGR_SMP_CBOR_MAX_ENCODING_LEVELS + 2];
58 
59 #if IS_ENABLED(CONFIG_MCUMGR_SMP_SUPPORT_ORIGINAL_PROTOCOL)
60 	uint16_t error_group;
61 	uint16_t error_ret;
62 #endif
63 };
64 
65 /**
66  * @brief Allocates a net_buf for holding an mcumgr request or response.
67  *
68  * @return      A newly-allocated buffer net_buf on success;
69  *              NULL on failure.
70  */
71 struct net_buf *smp_packet_alloc(void);
72 
73 /**
74  * @brief Frees an mcumgr net_buf
75  *
76  * @param nb    The net_buf to free.
77  */
78 void smp_packet_free(struct net_buf *nb);
79 
80 /**
81  * @brief Decodes, encodes, and transmits SMP packets.
82  */
83 struct smp_streamer {
84 	struct smp_transport *smpt;
85 	struct cbor_nb_reader *reader;
86 	struct cbor_nb_writer *writer;
87 
88 #ifdef CONFIG_MCUMGR_SMP_VERBOSE_ERR_RESPONSE
89 	const char *rc_rsn;
90 #endif
91 };
92 
93 /**
94  * @brief Processes a single SMP request packet and sends all corresponding responses.
95  *
96  * Processes all SMP requests in an incoming packet.  Requests are processed
97  * sequentially from the start of the packet to the end.  Each response is sent
98  * individually in its own packet.  If a request elicits an error response,
99  * processing of the packet is aborted.  This function consumes the supplied
100  * request buffer regardless of the outcome.
101  *
102  * @param streamer	The streamer providing the required SMP callbacks.
103  * @param req		The request packet to process.
104  *
105  * @return 0 on success, #mcumgr_err_t code on failure.
106  */
107 int smp_process_request_packet(struct smp_streamer *streamer, void *req);
108 
109 /**
110  * @brief Appends an "err" response
111  *
112  * This appends an err response to a pending outgoing response which contains a
113  * result code for a specific group. Note that error codes are specific to the
114  * command group they are emitted from).
115  *
116  * @param zse		The zcbor encoder to use.
117  * @param group		The group which emitted the error.
118  * @param ret		The command result code to add.
119  *
120  * @return true on success, false on failure (memory error).
121  */
122 bool smp_add_cmd_err(zcbor_state_t *zse, uint16_t group, uint16_t ret);
123 
124 /** @deprecated Deprecated after Zephyr 3.4, use smp_add_cmd_err() instead */
smp_add_cmd_ret(zcbor_state_t * zse,uint16_t group,uint16_t ret)125 __deprecated inline bool smp_add_cmd_ret(zcbor_state_t *zse, uint16_t group, uint16_t ret)
126 {
127 	return smp_add_cmd_err(zse, group, ret);
128 }
129 
130 #if IS_ENABLED(CONFIG_MCUMGR_SMP_SUPPORT_ORIGINAL_PROTOCOL)
131 /** @typedef	smp_translate_error_fn
132  * @brief	Translates a SMP version 2 error response to a legacy SMP version 1 error code.
133  *
134  * @param ret	The SMP version 2 group error value.
135  *
136  * @return	#enum mcumgr_err_t Legacy SMP version 1 error code to return to client.
137  */
138 typedef int (*smp_translate_error_fn)(uint16_t err);
139 #endif
140 
141 #ifdef __cplusplus
142 }
143 #endif
144 
145 #endif /* H_SMP_ */
146