/* * Copyright (c) 2019 Nordic Semiconductor ASA * * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause */ /** * @file * @defgroup bt_mesh_model_utils Model utility functions. * @{ * @brief Internal utility functions for mesh model implementations. */ #ifndef MODEL_UTILS_H__ #define MODEL_UTILS_H__ #include "system/includes.h" #include "api/sig_mesh_api.h" #include "model_api.h" #include "model_types.h" #include "api/gen_dtt_srv.h" #if IS_ENABLED(CONFIG_EMDS) /** * @brief Create emds model id to identify the model, where @p mod is the model. */ #define EMDS_MODEL_ID(mod) (((uint16_t)mod->elem_idx << 8) | mod->mod_idx) #endif #ifndef CLAMP /** * @brief Clamp a value to a given range. * * @note Arguments are evaluated multiple times. Use Z_CLAMP for a GCC-only, * single evaluation version. * * @param val Value to be clamped. * @param low Lowest allowed value (inclusive). * @param high Highest allowed value (inclusive). * * @returns Clamped value. */ #define CLAMP(val, low, high) (((val) <= (low)) ? (low) : MIN(val, high)) #endif /** * @brief Returns rounded division of @p A divided by @p B. * @note Arguments are evaluated twice. */ #define ROUNDED_DIV(A, B) (((A) + ((B) / 2)) / (B)) /** @brief Compare the TID of an incoming message with the previous * transaction, and update it if it's new. * * @param prev_transaction Previous transaction. * @param tid Transaction ID of the incoming message. * @param ctx Message context of the incoming message. * * @retval 0 The TID is new, and the @p prev_transaction structure has been * updated. * @retval -EAGAIN The incoming message is of the same transaction. */ int tid_check_and_update(struct bt_mesh_tid_ctx *prev_transaction, uint8_t tid, const struct bt_mesh_msg_ctx *ctx); uint8_t model_delay_encode(uint32_t delay); int32_t model_delay_decode(uint8_t encoded_delay); int32_t model_transition_decode(uint8_t encoded_transition); uint8_t model_transition_encode(int32_t transition_time); static inline void model_transition_buf_add(struct net_buf_simple *buf, const struct bt_mesh_model_transition *transition) { net_buf_simple_add_u8(buf, model_transition_encode(transition->time)); net_buf_simple_add_u8(buf, model_delay_encode(transition->delay)); } static inline void model_transition_buf_pull(struct net_buf_simple *buf, struct bt_mesh_model_transition *transition) { transition->time = model_transition_decode(net_buf_simple_pull_u8(buf)); transition->delay = model_delay_decode(net_buf_simple_pull_u8(buf)); } static inline struct bt_mesh_model_transition * model_transition_get(struct bt_mesh_model *model, struct bt_mesh_model_transition *transition, struct net_buf_simple *buf) { if (buf->len == 2) { model_transition_buf_pull(buf, transition); return transition; } if (bt_mesh_dtt_srv_transition_get(model, transition)) { return transition; } return NULL; } static inline bool model_transition_is_invalid(const struct bt_mesh_model_transition *transition) { return (transition != NULL && (transition->time > BT_MESH_MODEL_TRANSITION_TIME_MAX_MS || transition->delay > BT_MESH_MODEL_DELAY_TIME_MAX_MS)); } s32_t model_ackd_timeout_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx); int tid_check_and_update(struct bt_mesh_tid_ctx *prev_transaction, uint8_t tid, const struct bt_mesh_msg_ctx *ctx); #endif /* MODEL_UTILS_H__ */ /** @} */