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_SRV_H_ 8 #define ZEPHYR_INCLUDE_BLUETOOTH_MESH_BLOB_SRV_H_ 9 10 #include <zephyr/bluetooth/mesh/access.h> 11 #include <zephyr/bluetooth/mesh/blob.h> 12 13 #ifdef __cplusplus 14 extern "C" { 15 #endif 16 17 /** 18 * @defgroup bt_mesh_blob_srv Bluetooth Mesh BLOB Transfer Server model API 19 * @ingroup bt_mesh 20 * @{ 21 */ 22 23 struct bt_mesh_blob_srv; 24 25 /** 26 * 27 * @brief Max number of blocks in a single transfer. 28 */ 29 #if defined(CONFIG_BT_MESH_BLOB_SRV) 30 #define BT_MESH_BLOB_BLOCKS_MAX \ 31 (DIV_ROUND_UP(CONFIG_BT_MESH_BLOB_SIZE_MAX, \ 32 CONFIG_BT_MESH_BLOB_BLOCK_SIZE_MIN)) 33 #else 34 #define BT_MESH_BLOB_BLOCKS_MAX 1 35 #endif 36 37 /** 38 * 39 * @brief BLOB Transfer Server model composition data entry. 40 * 41 * @param _srv Pointer to a @ref bt_mesh_blob_srv instance. 42 */ 43 #define BT_MESH_MODEL_BLOB_SRV(_srv) \ 44 BT_MESH_MODEL_CB(BT_MESH_MODEL_ID_BLOB_SRV, _bt_mesh_blob_srv_op, \ 45 NULL, _srv, &_bt_mesh_blob_srv_cb) 46 47 /** @brief BLOB Transfer Server model event handlers. 48 * 49 * All callbacks are optional. 50 */ 51 struct bt_mesh_blob_srv_cb { 52 /** @brief Transfer start callback. 53 * 54 * Called when the transfer has started with the prepared BLOB ID. 55 * 56 * @param srv BLOB Transfer Server instance. 57 * @param ctx Message context for the incoming start message. The 58 * entire transfer will be sent from the same source 59 * address. 60 * @param xfer Transfer parameters. 61 * 62 * @return 0 on success, or (negative) error code to reject the 63 * transfer. 64 */ 65 int (*start)(struct bt_mesh_blob_srv *srv, struct bt_mesh_msg_ctx *ctx, 66 struct bt_mesh_blob_xfer *xfer); 67 68 /** @brief Transfer end callback. 69 * 70 * Called when the transfer ends, either because it was cancelled, or 71 * because it finished successfully. A new transfer may be prepared. 72 * 73 * @note The transfer may end before it's started if the start 74 * parameters are invalid. 75 * 76 * @param srv BLOB Transfer Server instance. 77 * @param id BLOB ID of the cancelled transfer. 78 * @param success Whether the transfer was successful. 79 */ 80 void (*end)(struct bt_mesh_blob_srv *srv, uint64_t id, bool success); 81 82 /** @brief Transfer suspended callback. 83 * 84 * Called if the Server timed out while waiting for a transfer packet. 85 * A suspended transfer may resume later from the start of the current 86 * block. Any received chunks in the current block should be discarded, 87 * they will be received again if the transfer resumes. 88 * 89 * The transfer will call @c resumed again when resuming. 90 * 91 * @note The BLOB Transfer Server does not run a timer in the suspended state, 92 * and it's up to the application to determine whether the 93 * transfer should be permanently cancelled. Without interaction, 94 * the transfer will be suspended indefinitely, and the BLOB Transfer 95 * Server will not accept any new transfers. 96 * 97 * @param srv BLOB Transfer Server instance. 98 */ 99 void (*suspended)(struct bt_mesh_blob_srv *srv); 100 101 /** @brief Transfer resume callback. 102 * 103 * Called if the transfer is resumed after being suspended. 104 * 105 * @param srv BLOB Transfer Server instance. 106 */ 107 void (*resume)(struct bt_mesh_blob_srv *srv); 108 109 /** @brief Transfer recovery callback. 110 * 111 * Called when the Bluetooth mesh subsystem is started if the device is rebooted 112 * in the middle of a transfer. 113 * 114 * Transfers will not be resumed after a reboot if this callback is not 115 * defined. 116 * 117 * @param srv BLOB Transfer Server instance. 118 * @param xfer Transfer to resume. 119 * @param io BLOB stream return parameter. Must be set to a valid 120 * BLOB stream by the callback. 121 * 122 * @return 0 on success, or (negative) error code to abandon the 123 * transfer. 124 */ 125 int (*recover)(struct bt_mesh_blob_srv *srv, 126 struct bt_mesh_blob_xfer *xfer, 127 const struct bt_mesh_blob_io **io); 128 }; 129 130 /** @brief BLOB Transfer Server instance. */ 131 struct bt_mesh_blob_srv { 132 /** Event handler callbacks. */ 133 const struct bt_mesh_blob_srv_cb *cb; 134 135 /* Runtime state: */ 136 const struct bt_mesh_blob_io *io; 137 struct k_work_delayable rx_timeout; 138 struct bt_mesh_blob_block block; 139 struct bt_mesh_model *mod; 140 enum bt_mesh_blob_xfer_phase phase; 141 142 struct bt_mesh_blob_srv_state { 143 struct bt_mesh_blob_xfer xfer; 144 uint16_t cli; 145 uint16_t app_idx; 146 uint16_t timeout_base; 147 uint16_t mtu_size; 148 uint8_t ttl; 149 150 /* Bitfield of pending blocks. */ 151 ATOMIC_DEFINE(blocks, BT_MESH_BLOB_BLOCKS_MAX); 152 } state; 153 154 /* Pull mode (Pull BLOB Transfer Mode) behavior. */ 155 struct { 156 uint16_t chunk_idx; 157 struct k_work_delayable report; 158 } pull; 159 }; 160 161 /** @brief Prepare BLOB Transfer Server for an incoming transfer. 162 * 163 * Before a BLOB Transfer Server can receive a transfer, the transfer must be prepared 164 * through some application level mechanism. The BLOB Transfer Server will only accept 165 * incoming transfers with a matching BLOB ID. 166 * 167 * @param srv BLOB Transfer Server instance. 168 * @param id BLOB ID to accept. 169 * @param io BLOB stream to write the incoming BLOB to. 170 * @param ttl Time to live value to use in responses to the BLOB Transfer Client. 171 * @param timeout_base Extra time for the Client to respond in addition to the 172 * base 10 seconds, in 10-second increments. 173 * 174 * @return 0 on success, or (negative) error code on failure. 175 */ 176 int bt_mesh_blob_srv_recv(struct bt_mesh_blob_srv *srv, uint64_t id, 177 const struct bt_mesh_blob_io *io, uint8_t ttl, 178 uint16_t timeout_base); 179 180 /** @brief Cancel the current BLOB transfer. 181 * 182 * Tells the BLOB Transfer Client to drop this device from the list of Targets for the 183 * current transfer. Note that the client may continue sending the transfer to 184 * other Targets. 185 * 186 * @param srv BLOB Transfer Server instance. 187 * 188 * @return 0 on success, or (negative) error code on failure. 189 */ 190 int bt_mesh_blob_srv_cancel(struct bt_mesh_blob_srv *srv); 191 192 /** @brief Get the current state of the BLOB Transfer Server. 193 * 194 * @param srv BLOB Transfer Server instance. 195 * 196 * @return true if the BLOB Transfer Server is currently participating in a transfer, 197 * false otherwise. 198 */ 199 bool bt_mesh_blob_srv_is_busy(const struct bt_mesh_blob_srv *srv); 200 201 /** @brief Get the current progress of the active transfer in percent. 202 * 203 * @param srv BLOB Transfer Server instance. 204 * 205 * @return The current transfer progress, or 0 if no transfer is active. 206 */ 207 uint8_t bt_mesh_blob_srv_progress(const struct bt_mesh_blob_srv *srv); 208 209 /** @cond INTERNAL_HIDDEN */ 210 extern const struct bt_mesh_model_op _bt_mesh_blob_srv_op[]; 211 extern const struct bt_mesh_model_cb _bt_mesh_blob_srv_cb; 212 /** @endcond */ 213 214 /** @} */ 215 216 #ifdef __cplusplus 217 } 218 #endif 219 220 #endif /* ZEPHYR_INCLUDE_BLUETOOTH_MESH_BLOB_SRV_H_ */ 221