bleSDK_expansion_board/mesh/model/gen/gens/mm_gens_dtt.c

316 lines
11 KiB
C

/**
****************************************************************************************
* @file mm_gens_dtt.c
*
* @brief Mesh Model Generic Default Transition Time Server Module
*
****************************************************************************************
*/
/**
****************************************************************************************
* @addtogroup MM_GENS_DTT
* @{
****************************************************************************************
*/
/*
* INCLUDE FILES
****************************************************************************************
*/
#include "mm_itf.h"
#include "mm_gens.h"
/*
* TYPE DEFINITIONS
****************************************************************************************
*/
/// Structure for Generic Default Transition Time server model environment
typedef struct mm_gens_dtt_env
{
/// Basic model environment - Must be first element in the structure - DO NOT MOVE
mm_mdl_env_t env;
/// Timer for sending of publications
mesh_timer_t tmr_publi;
/// Publication period
uint32_t publi_period_ms;
/// Default Transition Time state value
uint8_t dft_trans_time;
} mm_gens_dtt_env_t;
/*
* LOCAL FUNCTIONS
****************************************************************************************
*/
/**
****************************************************************************************
* @brief Prepare and send a Generic Default Transition Time Status
*
* @param[in] p_env_dtt Pointer to Generic Default Transition Time Server model
* environment
****************************************************************************************
*/
__STATIC void mm_gens_dtt_send_status(mm_gens_dtt_env_t *p_env_dtt, mm_route_env_t *p_route_env)
{
// Pointer to the buffer that will contain the message
mesh_buf_t *p_buf_status = mm_route_buf_alloc(MM_GEN_DTT_STATUS_LEN);
if (p_buf_status)
{
// Get pointer to data
uint8_t *p_data = MESH_BUF_DATA(p_buf_status);
// Get pointer to environment
mm_route_env_t *p_env = (mm_route_env_t *)&p_buf_status->env[0];
// Prepare environment
if (p_route_env)
{
memcpy(p_env, p_route_env, sizeof(mm_route_env_t));
}
p_env->opcode = MM_MSG_GEN_DTT_STATUS;
p_env->mdl_lid = p_env_dtt->env.mdl_lid;
SETB(p_env->info, MM_ROUTE_INFO_PUBLISH, (p_route_env == NULL));
SETB(p_env->info, MM_ROUTE_INFO_RX, 0);
// Fill the message
*(p_data + MM_GEN_DDT_STATUS_DDT_POS) = p_env_dtt->dft_trans_time;
// Send the message
mm_route_send(p_buf_status);
}
}
/*
* MESSAGE HANDLERS
****************************************************************************************
*/
/**
****************************************************************************************
* @brief Handler for Generic Default Transition Time Set/Set Unacknowledged message
*
* @param[in] p_env_dtt Pointer to environment for Generic Default Transition Time model
* @param[in] p_buf Pointer to received message content
* @param[in] p_route_env Pointer to structure containing reception parameters provided
* by the Mesh Profile block
****************************************************************************************
*/
__STATIC void mm_gens_dtt_handler_set(mm_gens_dtt_env_t *p_env_dtt, mesh_buf_t *p_buf,
mm_route_env_t *p_route_env)
{
// Set pointer to received message
uint8_t *p_data = MESH_BUF_DATA(p_buf);
// Get received default transition time
uint8_t dft_trans_time = *(p_data + MM_GEN_DDT_SET_DDT_POS);
// Check received value
if (GETF(dft_trans_time, MM_TRANS_TIME_STEP_NB) <= MM_TRANS_TIME_STEPS_MAX)
{
// Check if state value has been changed
bool update = (dft_trans_time != p_env_dtt->dft_trans_time);
if (update)
{
// Keep the provided value
p_env_dtt->dft_trans_time = dft_trans_time;
// Inform the Binding Manager
mm_bind_set_dft_trans_time(p_env_dtt->env.elmt_idx, dft_trans_time);
// Inform application about received value
mm_srv_state_upd_ind_send(MM_STATE_GEN_DTT, p_env_dtt->env.elmt_idx,
dft_trans_time, 0);
}
// Send the response
if (p_route_env->opcode == MM_MSG_GEN_DTT_SET)
{
mm_gens_dtt_send_status(p_env_dtt, p_route_env);
}
// Send a publication if authorized
if (update
&& GETB(p_env_dtt->env.info, MM_INFO_PUBLI))
{
mm_gens_dtt_send_status(p_env_dtt, NULL);
}
}
}
/*
* INTERNAL CALLBACK FUNCTIONS
****************************************************************************************
*/
/**
****************************************************************************************
* @brief Callback function called when timer monitoring publication duration for
* Generic Default Transition Time Server model expires
*
* @param[in] p_env Pointer to model environment for Generic Default Transition Time Server
* model
****************************************************************************************
*/
__STATIC void mm_gens_dtt_cb_tmr_publi(void *p_tmr)
{
// Get allocated environment
mm_gens_dtt_env_t *p_env_dtt = MESH_TMR2ENV(p_tmr, mm_gens_dtt_env_t, tmr_publi);
if (p_env_dtt->publi_period_ms)
{
// Publish a Generic Default Transition Time Status message
mm_gens_dtt_send_status(p_env_dtt, NULL);
// Restart the timer
mesh_timer_set(&p_env_dtt->tmr_publi, p_env_dtt->publi_period_ms);
}
}
/**
****************************************************************************************
* @brief Inform Generic Default Transition Time Server model about a received message
*
* @param[in] p_env Pointer to the environment allocated for the Generic Default
* Transition Time Server model
* @param[in] p_buf Pointer to the buffer containing the received message
* @param[in] p_route_env Pointer to structure containing reception parameters provided
* by the Mesh Profile block
****************************************************************************************
*/
__STATIC void mm_gens_dtt_cb_rx(mm_mdl_env_t *p_env, mesh_buf_t *p_buf,
mm_route_env_t *p_route_env)
{
// Get environment for Generic Default Transition Time Server model
mm_gens_dtt_env_t *p_env_dtt = (mm_gens_dtt_env_t *)p_env;
if (p_route_env->opcode != MM_MSG_GEN_DTT_GET)
{
// Handle Generic Default Transition Time Set/Set Unacknowledged message
mm_gens_dtt_handler_set(p_env_dtt, p_buf, p_route_env);
}
else
{
// Send a Generic Default Transition Time Status message
mm_gens_dtt_send_status(p_env_dtt, p_route_env);
}
}
/**
****************************************************************************************
* @brief Check if a given opcode is handled by the Generic Default Transition Time Server model
*
* @param[in] p_env Pointer to the environment allocated for the Generic Default Transition
* Time Server model
* @param[in] opcode Opcode to check
*
* @return An error status (@see enum mesh_err)
****************************************************************************************
*/
__STATIC uint8_t mm_gens_dtt_cb_opcode_check(mm_mdl_env_t *p_env, uint32_t opcode)
{
uint8_t status;
if ((opcode == MM_MSG_GEN_DTT_GET)
|| (opcode == MM_MSG_GEN_DTT_SET)
|| (opcode == MM_MSG_GEN_DTT_SET_UNACK))
{
status = MESH_ERR_NO_ERROR;
}
else
{
status = MESH_ERR_MDL_INVALID_OPCODE;
}
return (status);
}
/**
****************************************************************************************
* @brief Set Generic Default Transition Time state value
*
* @param[in] p_env Pointer the the environment allocated for the Generic OnOff
* Server model
* @param[in] dtt Generic Default Transition Time state value
*
* @return An error status (@see enum mesh_err)
****************************************************************************************
*/
__STATIC uint8_t mm_gens_dtt_cb_set(mm_mdl_env_t *p_env, uint16_t state_id, uint32_t state)
{
// Returned status
uint8_t status = MESH_ERR_NO_ERROR;
// Generic Default Transition Time state value
uint8_t dft_trans_time = (uint8_t)state;
// Check provided value
if (GETF(dft_trans_time, MM_TRANS_TIME_STEP_NB) <= MM_TRANS_TIME_STEPS_MAX)
{
// Get environment for the Generic Default Transition Time Server model
mm_gens_dtt_env_t *p_env_dtt = (mm_gens_dtt_env_t *)p_env;
// Keep the provided value
p_env_dtt->dft_trans_time = dft_trans_time;
// Inform the Binding Manager
mm_bind_set_dft_trans_time(p_env_dtt->env.elmt_idx, dft_trans_time);
}
else
{
status = MESH_ERR_INVALID_PARAM;
}
return (status);
}
/*
* GLOBAL FUNCTIONS
****************************************************************************************
*/
uint8_t mm_gens_dtt_register(uint8_t elmt_idx)
{
//uint8_t status = MESH_ERR_COMMAND_DISALLOWED;
// Register the model
m_lid_t mdl_lid = ms_register_model(MM_ID_GENS_DTT, elmt_idx, MM_CFG_PUBLI_AUTH_BIT);
if (mdl_lid != MESH_INVALID_LID) //if (status == MESH_ERR_NO_ERROR)
{
// Inform the Model State Manager about registered model
mm_gens_dtt_env_t *p_env_dtt = (mm_gens_dtt_env_t *)mm_state_register(elmt_idx, MM_ID_GENS_DTT, mdl_lid,
MM_ROLE_SRV_PUBLI,
sizeof(mm_gens_dtt_env_t));
if (p_env_dtt)
{
// Get server-specific callback functions
//mm_srv_cb_t *p_cb_srv = p_env_dtt->env.cb.u.p_cb_srv;
// Prepare timer for publications
p_env_dtt->tmr_publi.cb = mm_gens_dtt_cb_tmr_publi;
//p_env_dtt->tmr_publi.p_env = (void *)p_env_dtt;
// Set internal callback functions
p_env_dtt->env.mdl_cb.cb_rx = mm_gens_dtt_cb_rx;
p_env_dtt->env.mdl_cb.cb_opcode_check = mm_gens_dtt_cb_opcode_check;
//p_env_dtt->env.mdl_cb.cb_publish_param = mm_gens_dtt_cb_publish_param;
//p_cb_srv->cb_set = mm_gens_dtt_cb_set;
p_env_dtt->env.mdl_cb.cb_srv_set = mm_gens_dtt_cb_set;
//status = MESH_ERR_NO_ERROR;
// Inform application about registered model
mm_register_ind_send(MM_ID_GENS_DTT, elmt_idx, mdl_lid);
}
}
return (mdl_lid);
}
/// @} end of group