Line data Source code
1 0 : /*
2 : * Copyright (c) 2020 Nordic Semiconductor ASA
3 : *
4 : * SPDX-License-Identifier: Apache-2.0
5 : */
6 :
7 : #ifndef ZEPHYR_INCLUDE_BLUETOOTH_MESH_BLOB_H__
8 : #define ZEPHYR_INCLUDE_BLUETOOTH_MESH_BLOB_H__
9 :
10 : #include <sys/types.h>
11 :
12 : #include <zephyr/kernel.h>
13 :
14 : #ifdef __cplusplus
15 : extern "C" {
16 : #endif
17 :
18 : /**
19 : * @defgroup bt_mesh_blob Bluetooth Mesh BLOB model API
20 : * @ingroup bt_mesh
21 : * @{
22 : */
23 :
24 : #ifndef CONFIG_BT_MESH_BLOB_CHUNK_COUNT_MAX
25 0 : #define CONFIG_BT_MESH_BLOB_CHUNK_COUNT_MAX 0
26 : #endif
27 :
28 : /** BLOB transfer mode. */
29 1 : enum bt_mesh_blob_xfer_mode {
30 : /** No valid transfer mode. */
31 : BT_MESH_BLOB_XFER_MODE_NONE,
32 : /** Push mode (Push BLOB Transfer Mode). */
33 : BT_MESH_BLOB_XFER_MODE_PUSH,
34 : /** Pull mode (Pull BLOB Transfer Mode). */
35 : BT_MESH_BLOB_XFER_MODE_PULL,
36 : /** Both modes are valid. */
37 : BT_MESH_BLOB_XFER_MODE_ALL,
38 : };
39 :
40 : /** Transfer phase. */
41 1 : enum bt_mesh_blob_xfer_phase {
42 : /** The BLOB Transfer Server is awaiting configuration. */
43 : BT_MESH_BLOB_XFER_PHASE_INACTIVE,
44 : /** The BLOB Transfer Server is ready to receive a BLOB transfer. */
45 : BT_MESH_BLOB_XFER_PHASE_WAITING_FOR_START,
46 : /** The BLOB Transfer Server is waiting for the next block of data. */
47 : BT_MESH_BLOB_XFER_PHASE_WAITING_FOR_BLOCK,
48 : /** The BLOB Transfer Server is waiting for the next chunk of data. */
49 : BT_MESH_BLOB_XFER_PHASE_WAITING_FOR_CHUNK,
50 : /** The BLOB was transferred successfully. */
51 : BT_MESH_BLOB_XFER_PHASE_COMPLETE,
52 : /** The BLOB transfer is paused. */
53 : BT_MESH_BLOB_XFER_PHASE_SUSPENDED,
54 : };
55 :
56 : /** BLOB model status codes. */
57 1 : enum bt_mesh_blob_status {
58 : /** The message was processed successfully. */
59 : BT_MESH_BLOB_SUCCESS,
60 : /** The Block Number field value is not within the range of blocks being
61 : * transferred.
62 : */
63 : BT_MESH_BLOB_ERR_INVALID_BLOCK_NUM,
64 : /** The block size is smaller than the size indicated by the Min Block
65 : * Size Log state or is larger than the size indicated by the Max Block
66 : * Size Log state.
67 : */
68 : BT_MESH_BLOB_ERR_INVALID_BLOCK_SIZE,
69 : /** The chunk size exceeds the size indicated by the Max Chunk Size
70 : * state, or the number of chunks exceeds the number specified by the
71 : * Max Total Chunks state.
72 : */
73 : BT_MESH_BLOB_ERR_INVALID_CHUNK_SIZE,
74 : /** The operation cannot be performed while the server is in the current
75 : * phase.
76 : */
77 : BT_MESH_BLOB_ERR_WRONG_PHASE,
78 : /** A parameter value in the message cannot be accepted. */
79 : BT_MESH_BLOB_ERR_INVALID_PARAM,
80 : /** The message contains a BLOB ID value that is not expected. */
81 : BT_MESH_BLOB_ERR_WRONG_BLOB_ID,
82 : /** There is not enough space available in memory to receive the BLOB.
83 : */
84 : BT_MESH_BLOB_ERR_BLOB_TOO_LARGE,
85 : /** The transfer mode is not supported by the BLOB Transfer Server
86 : * model.
87 : */
88 : BT_MESH_BLOB_ERR_UNSUPPORTED_MODE,
89 : /** An internal error occurred on the node. */
90 : BT_MESH_BLOB_ERR_INTERNAL,
91 : /** The requested information cannot be provided while the server is in
92 : * the current phase.
93 : */
94 : BT_MESH_BLOB_ERR_INFO_UNAVAILABLE,
95 : };
96 :
97 : /** BLOB transfer data block. */
98 1 : struct bt_mesh_blob_block {
99 : /** Block size in bytes */
100 1 : size_t size;
101 : /** Offset in bytes from the start of the BLOB. */
102 1 : off_t offset;
103 : /** Block number */
104 1 : uint16_t number;
105 : /** Number of chunks in block. */
106 1 : uint16_t chunk_count;
107 : /** Bitmap of missing chunks. */
108 1 : uint8_t missing[DIV_ROUND_UP(CONFIG_BT_MESH_BLOB_CHUNK_COUNT_MAX,
109 : 8)];
110 : };
111 :
112 : /** BLOB data chunk. */
113 1 : struct bt_mesh_blob_chunk {
114 : /** Offset of the chunk data from the start of the block. */
115 1 : off_t offset;
116 : /** Chunk data size. */
117 1 : size_t size;
118 : /** Chunk data. */
119 1 : uint8_t *data;
120 : };
121 :
122 : /** BLOB transfer. */
123 1 : struct bt_mesh_blob_xfer {
124 : /** BLOB ID. */
125 1 : uint64_t id;
126 : /** Total BLOB size in bytes. */
127 1 : size_t size;
128 : /** BLOB transfer mode. */
129 1 : enum bt_mesh_blob_xfer_mode mode;
130 : /* Logarithmic representation of the block size. */
131 0 : uint8_t block_size_log;
132 : /** Base chunk size. May be smaller for the last chunk. */
133 1 : uint16_t chunk_size;
134 : };
135 :
136 : /** BLOB stream interaction mode. */
137 1 : enum bt_mesh_blob_io_mode {
138 : /** Read data from the stream. */
139 : BT_MESH_BLOB_READ,
140 : /** Write data to the stream. */
141 : BT_MESH_BLOB_WRITE,
142 : };
143 :
144 : /** BLOB stream. */
145 1 : struct bt_mesh_blob_io {
146 : /** @brief Open callback.
147 : *
148 : * Called when the reader is opened for reading.
149 : *
150 : * @param io BLOB stream.
151 : * @param xfer BLOB transfer.
152 : * @param mode Direction of the stream (read/write).
153 : *
154 : * @return 0 on success, or (negative) error code otherwise.
155 : */
156 1 : int (*open)(const struct bt_mesh_blob_io *io,
157 : const struct bt_mesh_blob_xfer *xfer,
158 : enum bt_mesh_blob_io_mode mode);
159 :
160 : /** @brief Close callback.
161 : *
162 : * Called when the reader is closed.
163 : *
164 : * @param io BLOB stream.
165 : * @param xfer BLOB transfer.
166 : */
167 1 : void (*close)(const struct bt_mesh_blob_io *io,
168 : const struct bt_mesh_blob_xfer *xfer);
169 :
170 : /** @brief Block start callback.
171 : *
172 : * Called when a new block is opened for sending. Each block is only
173 : * sent once, and are always sent in increasing order. The data chunks
174 : * inside a single block may be requested out of order and multiple
175 : * times.
176 : *
177 : * @param io BLOB stream.
178 : * @param xfer BLOB transfer.
179 : * @param block Block that was started.
180 : */
181 1 : int (*block_start)(const struct bt_mesh_blob_io *io,
182 : const struct bt_mesh_blob_xfer *xfer,
183 : const struct bt_mesh_blob_block *block);
184 :
185 : /** @brief Block end callback.
186 : *
187 : * Called when the current block has been transmitted in full.
188 : * No data from this block will be requested again, and the application
189 : * data associated with this block may be discarded.
190 : *
191 : * @param io BLOB stream.
192 : * @param xfer BLOB transfer.
193 : * @param block Block that finished sending.
194 : */
195 1 : void (*block_end)(const struct bt_mesh_blob_io *io,
196 : const struct bt_mesh_blob_xfer *xfer,
197 : const struct bt_mesh_blob_block *block);
198 :
199 : /** @brief Chunk data write callback.
200 : *
201 : * Used by the BLOB Transfer Server on incoming data.
202 : *
203 : * Each block is divided into chunks of data. This callback is called
204 : * when a new chunk of data is received. Chunks may be received in
205 : * any order within their block.
206 : *
207 : * If the callback returns successfully, this chunk will be marked as
208 : * received, and will not be received again unless the block is
209 : * restarted due to a transfer suspension. If the callback returns a
210 : * non-zero value, the chunk remains unreceived, and the BLOB Transfer
211 : * Client will attempt to resend it later.
212 : *
213 : * Note that the Client will only perform a limited number of attempts
214 : * at delivering a chunk before dropping a Target node from the transfer.
215 : * The number of retries performed by the Client is implementation
216 : * specific.
217 : *
218 : * @param io BLOB stream.
219 : * @param xfer BLOB transfer.
220 : * @param block Block the chunk is part of.
221 : * @param chunk Received chunk.
222 : *
223 : * @return 0 on success, or (negative) error code otherwise.
224 : */
225 1 : int (*wr)(const struct bt_mesh_blob_io *io,
226 : const struct bt_mesh_blob_xfer *xfer,
227 : const struct bt_mesh_blob_block *block,
228 : const struct bt_mesh_blob_chunk *chunk);
229 :
230 : /** @brief Chunk data read callback.
231 : *
232 : * Used by the BLOB Transfer Client to fetch outgoing data.
233 : *
234 : * The Client calls the chunk data request callback to populate a chunk
235 : * message going out to the Target nodes. The data request callback
236 : * may be called out of order and multiple times for each offset, and
237 : * cannot be used as an indication of progress.
238 : *
239 : * Returning a non-zero status code on the chunk data request callback
240 : * results in termination of the transfer.
241 : *
242 : * @param io BLOB stream.
243 : * @param xfer BLOB transfer.
244 : * @param block Block the chunk is part of.
245 : * @param chunk Chunk to get the data of. The buffer pointer to by the
246 : * @c data member should be filled by the callback.
247 : *
248 : * @return 0 on success, or (negative) error code otherwise.
249 : */
250 1 : int (*rd)(const struct bt_mesh_blob_io *io,
251 : const struct bt_mesh_blob_xfer *xfer,
252 : const struct bt_mesh_blob_block *block,
253 : const struct bt_mesh_blob_chunk *chunk);
254 : };
255 :
256 : /** @} */
257 :
258 : #ifdef __cplusplus
259 : }
260 : #endif
261 :
262 : #endif /* ZEPHYR_INCLUDE_BLUETOOTH_MESH_BLOB_H__ */
|