1 /*
2  * Copyright (c) 2022 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #ifndef ZEPHYR_INCLUDE_MGMT_SMP_REASSEMBLY_H_
8 #define ZEPHYR_INCLUDE_MGMT_SMP_REASSEMBLY_H_
9 
10 #ifdef __cplusplus
11 extern "C" {
12 #endif
13 
14 struct smp_transport;
15 
16 /**
17  * Initialize re-assembly context within smp_transport
18  *
19  * @param smpt	the SMP transport.
20  *
21  * Note: for efficiency there is no NULL check on @p smpt pointer and it is caller's responsibility
22  * to validate the pointer before passing it to this function.
23  */
24 void smp_reassembly_init(struct smp_transport *smpt);
25 
26 /**
27  * Collect data to re-assembly buffer
28  *
29  * The function adds data to the end of current re-assembly buffer; it will allocate new buffer
30  * if there isn't one allocated.
31  *
32  * Note: Currently the function is not able to concatenate buffers so re-assembled packet needs
33  * to fit into one buffer.
34  *
35  * @param smpt	the SMP transport;
36  * @param buf	buffer with data to add;
37  * @param len	length of data to add;
38  *
39  * Note: For efficiency there are ot NULL checks on @p smpt and @p buf pointers and it is caller's
40  * responsibility to make sure these are not NULL.  Also @p len should not be 0 as there is no
41  * point in passing an empty fragment for re-assembly.
42  *
43  * @return	number of expected bytes left to complete the packet, 0 means buffer is complete
44  *		and no more fragments are expected;
45  *		-ENOSR if a packet length, read from header, is bigger than
46  *              CONFIG_MCUMGR_TRANSPORT_NETBUF_SIZE, which means there is no way to fit it in
47  *              the configured buffer;
48  *		-EOVERFLOW if attempting to add a fragment that would make complete packet larger
49  *		than expected;
50  *		-ENOMEM if failed to allocate a new buffer for packet assembly;
51  *		-ENODATA if the first received fragment was not big enough to figure out a size
52  *		of the packet; MTU is set too low;
53  */
54 int smp_reassembly_collect(struct smp_transport *smpt, const void *buf, uint16_t len);
55 
56 /**
57  * Return number of expected bytes to complete the packet
58  *
59  * @param smpt	the SMP transport;
60  *
61  * Note: for efficiency there is no NULL check on @p smpt pointer and it is caller's responsibility
62  * to validate the pointer before passing it to this function.
63  *
64  * @return	number of bytes needed to complete the packet;
65  *		-EINVAL if there is no packet in re-assembly;
66  */
67 int smp_reassembly_expected(const struct smp_transport *smpt);
68 
69 /**
70  * Pass packet for further processing
71  *
72  * Checks if the packet has enough data to be re-assembled and passes it for further processing.
73  * If successful then the re-assembly context in @p smpt will indicate that there is no
74  * re-assembly in progress.
75  * The function can be forced to pass a data for processing even if the packet is not complete,
76  * in which case it is users responsibility to use the user data, passed with the packet, to notify
77  * receiving end of such case.
78  *
79  * @param smpt	the SMP transport;
80  * @param force	process anyway;
81  *
82  * Note: for efficiency there is no NULL check on @p smpt pointer and it is caller's responsibility
83  * to validate the pointer before passing it to this function.
84  *
85  * @return	0 on success and not forced;
86  *		expected number of bytes if forced to complete buffer with not enough data;
87  *		-EINVAL if there is no re-assembly in progress;
88  *		-ENODATA if there is not enough data to consider packet re-assembled, it has not
89  *		been passed further.
90  */
91 int smp_reassembly_complete(struct smp_transport *smpt, bool force);
92 
93 /**
94  * Drop packet and release buffer
95  *
96  * @param smpt	the SMP transport;
97  *
98  * Note: for efficiency there is no NULL check on @p smpt pointer and it is caller's responsibility
99  * to validate the pointer before passing it to this function.
100  *
101  * @return	0 on success;
102  *		-EINVAL if there is no re-assembly in progress.
103  */
104 int smp_reassembly_drop(struct smp_transport *smpt);
105 
106 /**
107  * Get "user data" pointer for current packet re-assembly
108  *
109  * @param smpt	the SMP transport;
110  *
111  * Note: for efficiency there is no NULL check on @p smpt pointer and it is caller's responsibility
112  * to validate the pointer before passing it to this function.
113  *
114  * @return	pointer to "user data" of CONFIG_MCUMGR_TRANSPORT_NETBUF_USER_DATA_SIZE size;
115  *		NULL if no re-assembly in progress.
116  */
117 void *smp_reassembly_get_ud(const struct smp_transport *smpt);
118 
119 #ifdef __cplusplus
120 }
121 #endif
122 
123 #endif /* ZEPHYR_INCLUDE_MGMT_SMP_REASSEMBLY_H_ */
124