LCOV - code coverage report
Current view: top level - zephyr/bluetooth/mesh - blob_cli.h Hit Total Coverage
Test: new.info Lines: 51 77 66.2 %
Date: 2024-12-21 18:13:37

          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_CLI_H_
       8             : #define ZEPHYR_INCLUDE_BLUETOOTH_MESH_BLOB_CLI_H_
       9             : 
      10             : #include <sys/types.h>
      11             : 
      12             : #include <zephyr/bluetooth/mesh/access.h>
      13             : #include <zephyr/bluetooth/mesh/blob.h>
      14             : 
      15             : #ifdef __cplusplus
      16             : extern "C" {
      17             : #endif
      18             : 
      19             : /**
      20             :  * @defgroup bt_mesh_blob_cli Bluetooth Mesh BLOB Transfer Client model API
      21             :  * @ingroup bt_mesh
      22             :  * @{
      23             :  */
      24             : 
      25             : struct bt_mesh_blob_cli;
      26             : 
      27             : /**
      28             :  *
      29             :  * @brief BLOB Transfer Client model Composition Data entry.
      30             :  *
      31             :  * @param _cli Pointer to a @ref bt_mesh_blob_cli instance.
      32             :  */
      33           1 : #define BT_MESH_MODEL_BLOB_CLI(_cli)                                           \
      34             :         BT_MESH_MODEL_CB(BT_MESH_MODEL_ID_BLOB_CLI, _bt_mesh_blob_cli_op,      \
      35             :                          NULL, _cli, &_bt_mesh_blob_cli_cb)
      36             : 
      37             : /** Target node's Pull mode (Pull BLOB Transfer Mode) context used
      38             :  *  while sending chunks to the Target node.
      39             :  */
      40           1 : struct bt_mesh_blob_target_pull {
      41             :         /** Timestamp when the Block Report Timeout Timer expires for this Target node. */
      42           1 :         int64_t block_report_timestamp;
      43             : 
      44             :         /** Missing chunks reported by this Target node. */
      45           1 :         uint8_t missing[DIV_ROUND_UP(CONFIG_BT_MESH_BLOB_CHUNK_COUNT_MAX, 8)];
      46             : };
      47             : 
      48             : /** BLOB Transfer Client Target node. */
      49           1 : struct bt_mesh_blob_target {
      50             :         /** Linked list node */
      51           1 :         sys_snode_t n;
      52             : 
      53             :         /** Target node address. */
      54           1 :         uint16_t addr;
      55             : 
      56             :     /** Target node's Pull mode context.
      57             :      *  Needs to be initialized when sending a BLOB in Pull mode.
      58             :      */
      59           1 :         struct bt_mesh_blob_target_pull *pull;
      60             : 
      61             :         /** BLOB transfer status, see @ref bt_mesh_blob_status. */
      62           1 :         uint8_t status;
      63             : 
      64           0 :         uint8_t procedure_complete:1, /* Procedure has been completed. */
      65           0 :                 acked:1,              /* Message has been acknowledged. Not used when sending. */
      66           0 :                 timedout:1,           /* Target node didn't respond after specified timeout. */
      67           0 :                 skip:1;               /* Skip Target node from broadcast. */
      68             : };
      69             : 
      70             : /** BLOB transfer information.
      71             :  *
      72             :  * If @c phase is @ref BT_MESH_BLOB_XFER_PHASE_INACTIVE,
      73             :  * the fields below @c phase are not initialized.
      74             :  * If @c phase is @ref BT_MESH_BLOB_XFER_PHASE_WAITING_FOR_START,
      75             :  * the fields below @c id are not initialized.
      76             :  */
      77           1 : struct bt_mesh_blob_xfer_info {
      78             :         /** BLOB transfer status. */
      79           1 :         enum bt_mesh_blob_status status;
      80             : 
      81             :         /** BLOB transfer mode. */
      82           1 :         enum bt_mesh_blob_xfer_mode mode;
      83             : 
      84             :         /** BLOB transfer phase. */
      85           1 :         enum bt_mesh_blob_xfer_phase phase;
      86             : 
      87             :         /** BLOB ID. */
      88           1 :         uint64_t id;
      89             : 
      90             :         /** BLOB size in octets. */
      91           1 :         uint32_t size;
      92             : 
      93             :         /** Logarithmic representation of the block size. */
      94           1 :         uint8_t block_size_log;
      95             : 
      96             :         /** MTU size in octets. */
      97           1 :         uint16_t mtu_size;
      98             : 
      99             :         /** Bit field indicating blocks that were not received.  */
     100           1 :         const uint8_t *missing_blocks;
     101             : };
     102             : 
     103             : /** BLOB Transfer Client transfer inputs. */
     104           1 : struct bt_mesh_blob_cli_inputs {
     105             :         /** Linked list of Target nodes. Each node should point to @ref
     106             :          *  bt_mesh_blob_target::n.
     107             :          */
     108           1 :         sys_slist_t targets;
     109             : 
     110             :         /** AppKey index to send with. */
     111           1 :         uint16_t app_idx;
     112             : 
     113             :         /** Group address destination for the BLOB transfer, or @ref
     114             :          *  BT_MESH_ADDR_UNASSIGNED to send every message to each Target
     115             :          *  node individually.
     116             :          */
     117           1 :         uint16_t group;
     118             : 
     119             :         /** Time to live value of BLOB transfer messages. */
     120           1 :         uint8_t ttl;
     121             : 
     122             :         /** Additional response time for the Target nodes, in 10-second increments.
     123             :          *
     124             :          *  The extra time can be used to give the Target nodes more time to respond
     125             :          *  to messages from the Client. The actual timeout will be calculated
     126             :          *  according to the following formula:
     127             :          *
     128             :          *  @verbatim
     129             :          *  timeout = 20 seconds + (10 seconds * timeout_base) + (100 ms * TTL)
     130             :          *  @endverbatim
     131             :          *
     132             :          *  If a Target node fails to respond to a message from the Client within the
     133             :          *  configured transfer timeout, the Target node is dropped.
     134             :          */
     135           1 :         uint16_t timeout_base;
     136             : };
     137             : 
     138             : /** Transfer capabilities of a Target node. */
     139           1 : struct bt_mesh_blob_cli_caps {
     140             :         /** Max BLOB size. */
     141           1 :         size_t max_size;
     142             : 
     143             :         /** Logarithmic representation of the minimum block size. */
     144           1 :         uint8_t min_block_size_log;
     145             : 
     146             :         /** Logarithmic representation of the maximum block size. */
     147           1 :         uint8_t max_block_size_log;
     148             : 
     149             :         /** Max number of chunks per block. */
     150           1 :         uint16_t max_chunks;
     151             : 
     152             :         /** Max chunk size. */
     153           1 :         uint16_t max_chunk_size;
     154             : 
     155             :         /** Max MTU size. */
     156           1 :         uint16_t mtu_size;
     157             : 
     158             :         /** Supported transfer modes. */
     159           1 :         enum bt_mesh_blob_xfer_mode modes;
     160             : };
     161             : 
     162             : /** BLOB Transfer Client state. */
     163           1 : enum bt_mesh_blob_cli_state {
     164             :         /** No transfer is active. */
     165             :         BT_MESH_BLOB_CLI_STATE_NONE,
     166             :         /** Retrieving transfer capabilities. */
     167             :         BT_MESH_BLOB_CLI_STATE_CAPS_GET,
     168             :         /** Sending transfer start. */
     169             :         BT_MESH_BLOB_CLI_STATE_START,
     170             :         /** Sending block start. */
     171             :         BT_MESH_BLOB_CLI_STATE_BLOCK_START,
     172             :         /** Sending block chunks. */
     173             :         BT_MESH_BLOB_CLI_STATE_BLOCK_SEND,
     174             :         /** Checking block status. */
     175             :         BT_MESH_BLOB_CLI_STATE_BLOCK_CHECK,
     176             :         /** Checking transfer status. */
     177             :         BT_MESH_BLOB_CLI_STATE_XFER_CHECK,
     178             :         /** Cancelling transfer. */
     179             :         BT_MESH_BLOB_CLI_STATE_CANCEL,
     180             :         /** Transfer is suspended. */
     181             :         BT_MESH_BLOB_CLI_STATE_SUSPENDED,
     182             :         /** Checking transfer progress. */
     183             :         BT_MESH_BLOB_CLI_STATE_XFER_PROGRESS_GET,
     184             : };
     185             : 
     186             : /** Event handler callbacks for the BLOB Transfer Client model.
     187             :  *
     188             :  *  All handlers are optional.
     189             :  */
     190           1 : struct bt_mesh_blob_cli_cb {
     191             :         /** @brief Capabilities retrieval completion callback.
     192             :          *
     193             :          *  Called when the capabilities retrieval procedure completes, indicating that
     194             :          *  a common set of acceptable transfer parameters have been established
     195             :          *  for the given list of Target nodes. All compatible Target nodes have
     196             :          *  status code @ref BT_MESH_BLOB_SUCCESS.
     197             :          *
     198             :          *  @param cli     BLOB Transfer Client instance.
     199             :          *  @param caps    Safe transfer capabilities if the transfer capabilities
     200             :          *                 of at least one Target node has satisfied the Client, or NULL otherwise.
     201             :          */
     202           1 :         void (*caps)(struct bt_mesh_blob_cli *cli,
     203             :                      const struct bt_mesh_blob_cli_caps *caps);
     204             : 
     205             :         /** @brief Target node loss callback.
     206             :          *
     207             :          *  Called whenever a Target node has been lost due to some error in the
     208             :          *  transfer. Losing a Target node is not considered a fatal error for
     209             :          *  the Client until all Target nodes have been lost.
     210             :          *
     211             :          *  @param cli    BLOB Transfer Client instance.
     212             :          *  @param target Target node that was lost.
     213             :          *  @param reason Reason for the Target node loss.
     214             :          */
     215           1 :         void (*lost_target)(struct bt_mesh_blob_cli *cli,
     216             :                             struct bt_mesh_blob_target *target,
     217             :                             enum bt_mesh_blob_status reason);
     218             : 
     219             :         /** @brief Transfer is suspended.
     220             :          *
     221             :          * Called when the transfer is suspended due to response timeout from all Target nodes.
     222             :          *
     223             :          * @param cli    BLOB Transfer Client instance.
     224             :          */
     225           1 :         void (*suspended)(struct bt_mesh_blob_cli *cli);
     226             : 
     227             :         /** @brief Transfer end callback.
     228             :          *
     229             :          *  Called when the transfer ends.
     230             :          *
     231             :          *  @param cli     BLOB Transfer Client instance.
     232             :          *  @param xfer    Completed transfer.
     233             :          *  @param success Status of the transfer.
     234             :          *                 Is @c true if at least one Target
     235             :          *                 node received the whole transfer.
     236             :          */
     237           1 :         void (*end)(struct bt_mesh_blob_cli *cli,
     238             :                     const struct bt_mesh_blob_xfer *xfer, bool success);
     239             : 
     240             :         /** @brief Transfer progress callback
     241             :          *
     242             :          * The content of @c info is invalidated upon exit from the callback.
     243             :          * Therefore it needs to be copied if it is planned to be used later.
     244             :          *
     245             :          *  @param cli      BLOB Transfer Client instance.
     246             :          *  @param target   Target node that responded to the request.
     247             :          *  @param info     BLOB transfer information.
     248             :          */
     249           1 :         void (*xfer_progress)(struct bt_mesh_blob_cli *cli,
     250             :                               struct bt_mesh_blob_target *target,
     251             :                               const struct bt_mesh_blob_xfer_info *info);
     252             : 
     253             :         /** @brief End of Get Transfer Progress procedure.
     254             :          *
     255             :          * Called when all Target nodes have responded or the procedure timed-out.
     256             :          *
     257             :          *  @param cli     BLOB Transfer Client instance.
     258             :          */
     259           1 :         void (*xfer_progress_complete)(struct bt_mesh_blob_cli *cli);
     260             : };
     261             : 
     262             : /** @cond INTERNAL_HIDDEN */
     263             : struct blob_cli_broadcast_ctx {
     264             :         /** Called for every Target node in unicast mode, or once in case of multicast mode. */
     265             :         void (*send)(struct bt_mesh_blob_cli *cli, uint16_t dst);
     266             :         /** Called after every @ref blob_cli_broadcast_ctx::send callback. */
     267             :         void (*send_complete)(struct bt_mesh_blob_cli *cli, uint16_t dst);
     268             :         /** If @ref blob_cli_broadcast_ctx::acked is true, called after all Target nodes
     269             :          *  have confirmed reception by @ref blob_cli_broadcast_rsp. Otherwise, called
     270             :          *  after transmission has been completed.
     271             :          */
     272             :         void (*next)(struct bt_mesh_blob_cli *cli);
     273             :         /** If true, every transmission needs to be confirmed by @ref blob_cli_broadcast_rsp before
     274             :          * @ref blob_cli_broadcast_ctx::next is called.
     275             :          */
     276             :         bool acked;
     277             :         /** If true, the message is always sent in a unicast way. */
     278             :         bool force_unicast;
     279             :         /** If true, non-responsive Target nodes won't be dropped after transfer has timed out. */
     280             :         bool optional;
     281             :         /** Set to true by the BLOB Transfer Client between blob_cli_broadcast
     282             :          *  and broadcast_complete calls.
     283             :          */
     284             :         bool is_inited;
     285             :         /* Defines a time in ms by which the broadcast API postpones sending the message to a next
     286             :          * target or completing the broadcast.
     287             :          */
     288             :         uint32_t post_send_delay_ms;
     289             : };
     290             : /** INTERNAL_HIDDEN @endcond */
     291             : 
     292             : /** BLOB Transfer Client model instance. */
     293           1 : struct bt_mesh_blob_cli {
     294             :         /** Event handler callbacks */
     295           1 :         const struct bt_mesh_blob_cli_cb *cb;
     296             : 
     297             :         /* Runtime state */
     298           0 :         const struct bt_mesh_model *mod;
     299             : 
     300             :         struct {
     301           0 :                 struct bt_mesh_blob_target *target;
     302           0 :                 struct blob_cli_broadcast_ctx ctx;
     303           0 :                 struct k_work_delayable retry;
     304             :                 /* Represents Client Timeout timer in a timestamp. Used in Pull mode only. */
     305           0 :                 int64_t cli_timestamp;
     306           0 :                 struct k_work_delayable complete;
     307           0 :                 uint16_t pending;
     308           0 :                 uint8_t retries;
     309           0 :                 uint8_t sending : 1,
     310           0 :                         cancelled : 1;
     311           0 :         } tx;
     312             : 
     313           0 :         const struct bt_mesh_blob_io *io;
     314           0 :         const struct bt_mesh_blob_cli_inputs *inputs;
     315           0 :         const struct bt_mesh_blob_xfer *xfer;
     316           0 :         uint32_t chunk_interval_ms;
     317           0 :         uint16_t block_count;
     318           0 :         uint16_t chunk_idx;
     319           0 :         uint16_t mtu_size;
     320           0 :         enum bt_mesh_blob_cli_state state;
     321           0 :         struct bt_mesh_blob_block block;
     322           0 :         struct bt_mesh_blob_cli_caps caps;
     323             : };
     324             : 
     325             : /** @brief Retrieve transfer capabilities for a list of Target nodes.
     326             :  *
     327             :  *  Queries the availability and capabilities of all Target nodes, producing a
     328             :  *  cumulative set of transfer capabilities for the Target nodes, and returning
     329             :  *  it through the @ref bt_mesh_blob_cli_cb::caps callback.
     330             :  *
     331             :  *  Retrieving the capabilities may take several seconds, depending on the
     332             :  *  number of Target nodes and mesh network performance. The end of the procedure
     333             :  *  is indicated through the @ref bt_mesh_blob_cli_cb::caps callback.
     334             :  *
     335             :  *  This procedure is not required, but strongly recommended as a
     336             :  *  preparation for a transfer to maximize performance and the chances of
     337             :  *  success.
     338             :  *
     339             :  *  @param cli     BLOB Transfer Client instance.
     340             :  *  @param inputs  Statically allocated BLOB Transfer Client transfer inputs.
     341             :  *
     342             :  *  @return 0 on success, or (negative) error code otherwise.
     343             :  */
     344           1 : int bt_mesh_blob_cli_caps_get(struct bt_mesh_blob_cli *cli,
     345             :                               const struct bt_mesh_blob_cli_inputs *inputs);
     346             : 
     347             : /** @brief Perform a BLOB transfer.
     348             :  *
     349             :  *  Starts sending the transfer to the Target nodes. Only Target nodes with a
     350             :  *  @c status of @ref BT_MESH_BLOB_SUCCESS will be considered.
     351             :  *
     352             :  *  The transfer will keep going either until all Target nodes have been dropped, or
     353             :  *  the full BLOB has been sent.
     354             :  *
     355             :  *  The BLOB transfer may take several minutes, depending on the number of
     356             :  *  Target nodes, size of the BLOB and mesh network performance. The end of the
     357             :  *  transfer is indicated through the @ref bt_mesh_blob_cli_cb::end callback.
     358             :  *
     359             :  *  A Client only supports one transfer at the time.
     360             :  *
     361             :  *  @param cli    BLOB Transfer Client instance.
     362             :  *  @param inputs Statically allocated BLOB Transfer Client transfer inputs.
     363             :  *  @param xfer   Statically allocated transfer parameters.
     364             :  *  @param io     BLOB stream to read the transfer from.
     365             :  *
     366             :  *  @return 0 on success, or (negative) error code otherwise.
     367             :  */
     368           1 : int bt_mesh_blob_cli_send(struct bt_mesh_blob_cli *cli,
     369             :                           const struct bt_mesh_blob_cli_inputs *inputs,
     370             :                           const struct bt_mesh_blob_xfer *xfer,
     371             :                           const struct bt_mesh_blob_io *io);
     372             : 
     373             : /** @brief Suspend the active transfer.
     374             :  *
     375             :  *  @param cli BLOB Transfer Client instance.
     376             :  *
     377             :  *  @return 0 on success, or (negative) error code otherwise.
     378             :  */
     379           1 : int bt_mesh_blob_cli_suspend(struct bt_mesh_blob_cli *cli);
     380             : 
     381             : /** @brief Resume the suspended transfer.
     382             :  *
     383             :  *  @param cli BLOB Transfer Client instance.
     384             :  *
     385             :  *  @return 0 on success, or (negative) error code otherwise.
     386             :  */
     387           1 : int bt_mesh_blob_cli_resume(struct bt_mesh_blob_cli *cli);
     388             : 
     389             : /** @brief Cancel an ongoing transfer.
     390             :  *
     391             :  *  @param cli BLOB Transfer Client instance.
     392             :  */
     393           1 : void bt_mesh_blob_cli_cancel(struct bt_mesh_blob_cli *cli);
     394             : 
     395             : /** @brief Get the progress of BLOB transfer.
     396             :  *
     397             :  *  This function can only be used if the BLOB Transfer Client is currently
     398             :  *  not performing a BLOB transfer.
     399             :  *  To get progress of the active BLOB transfer, use the
     400             :  *  @ref bt_mesh_blob_cli_xfer_progress_active_get function.
     401             :  *
     402             :  *  @param cli BLOB Transfer Client instance.
     403             :  *  @param inputs Statically allocated BLOB Transfer Client transfer inputs.
     404             :  *
     405             :  *  @return 0 on success, or (negative) error code otherwise.
     406             :  */
     407           1 : int bt_mesh_blob_cli_xfer_progress_get(struct bt_mesh_blob_cli *cli,
     408             :                                        const struct bt_mesh_blob_cli_inputs *inputs);
     409             : 
     410             : /** @brief Get the current progress of the active transfer in percent.
     411             :  *
     412             :  *  @param cli BLOB Transfer Client instance.
     413             :  *
     414             :  *  @return The current transfer progress, or 0 if no transfer is active.
     415             :  */
     416           1 : uint8_t bt_mesh_blob_cli_xfer_progress_active_get(struct bt_mesh_blob_cli *cli);
     417             : 
     418             : /** @brief Get the current state of the BLOB Transfer Client.
     419             :  *
     420             :  *  @param cli BLOB Transfer Client instance.
     421             :  *
     422             :  *  @return true if the BLOB Transfer Client is currently participating in a transfer or
     423             :  *          retrieving the capabilities and false otherwise.
     424             :  */
     425           1 : bool bt_mesh_blob_cli_is_busy(struct bt_mesh_blob_cli *cli);
     426             : 
     427             : /** @brief Set chunk sending interval in ms
     428             :  *
     429             :  *  This function is optional, and can be used to define how fast chunks are sent in the BLOB Client
     430             :  *  Model.
     431             :  *  Without an added delay, for example a Bluetooth Mesh DFU can cause network blockage by
     432             :  *  constantly sending the next chunks, especially if the chunks are sent to group addresses or
     433             :  *  multiple unicast addresses.
     434             :  *
     435             :  *  @note: Big intervals may cause timeouts. Increasing the @c timeout_base accordingly can
     436             :  *  circumvent this.
     437             :  *
     438             :  *  @param cli BLOB Transfer Client instance.
     439             :  *  @param interval_ms the delay before each chunk is sent out in ms.
     440             :  */
     441           1 : void bt_mesh_blob_cli_set_chunk_interval_ms(struct bt_mesh_blob_cli *cli, uint32_t interval_ms);
     442             : 
     443             : /** @cond INTERNAL_HIDDEN */
     444             : extern const struct bt_mesh_model_op _bt_mesh_blob_cli_op[];
     445             : extern const struct bt_mesh_model_cb _bt_mesh_blob_cli_cb;
     446             : /** @endcond */
     447             : 
     448             : /** @} */
     449             : 
     450             : #ifdef __cplusplus
     451             : }
     452             : #endif
     453             : 
     454             : #endif /* ZEPHYR_INCLUDE_BLUETOOTH_MESH_BLOB_CLI_H_ */

Generated by: LCOV version 1.14