1 /* 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 #define CONFIG_BT_MESH_BLOB_CHUNK_COUNT_MAX 0 26 #endif 27 28 /** BLOB transfer mode. */ 29 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 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 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 struct bt_mesh_blob_block { 99 /** Block size in bytes */ 100 size_t size; 101 /** Offset in bytes from the start of the BLOB. */ 102 off_t offset; 103 /** Block number */ 104 uint16_t number; 105 /** Number of chunks in block. */ 106 uint16_t chunk_count; 107 /** Bitmap of missing chunks. */ 108 uint8_t missing[DIV_ROUND_UP(CONFIG_BT_MESH_BLOB_CHUNK_COUNT_MAX, 109 8)]; 110 }; 111 112 /** BLOB data chunk. */ 113 struct bt_mesh_blob_chunk { 114 /** Offset of the chunk data from the start of the block. */ 115 off_t offset; 116 /** Chunk data size. */ 117 size_t size; 118 /** Chunk data. */ 119 uint8_t *data; 120 }; 121 122 /** BLOB transfer. */ 123 struct bt_mesh_blob_xfer { 124 /** BLOB ID. */ 125 uint64_t id; 126 /** Total BLOB size in bytes. */ 127 size_t size; 128 /** BLOB transfer mode. */ 129 enum bt_mesh_blob_xfer_mode mode; 130 /* Logarithmic representation of the block size. */ 131 uint8_t block_size_log; 132 /** Base chunk size. May be smaller for the last chunk. */ 133 uint16_t chunk_size; 134 }; 135 136 /** BLOB stream interaction mode. */ 137 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 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 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 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 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 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 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 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__ */ 263