382 lines
11 KiB
C
382 lines
11 KiB
C
/**
|
|
****************************************************************************************
|
|
*
|
|
* @file mm_genc_prop.c
|
|
*
|
|
* @brief Mesh Model Generic Property Client Module
|
|
*
|
|
****************************************************************************************
|
|
*/
|
|
|
|
/**
|
|
****************************************************************************************
|
|
* @addtogroup MM_GENC_PROP
|
|
* @{
|
|
****************************************************************************************
|
|
*/
|
|
|
|
/*
|
|
* INCLUDE FILES
|
|
****************************************************************************************
|
|
*/
|
|
|
|
#include "mm_itf.h"
|
|
#include "mm_genc.h"
|
|
|
|
|
|
/*
|
|
* TYPE DEFINITIONS
|
|
****************************************************************************************
|
|
*/
|
|
|
|
/// Structure for Generic Property Client model environment
|
|
typedef struct mm_genc_prop_env
|
|
{
|
|
/// Basic model environment - Must be first element in the structure - DO NOT MOVE
|
|
mm_mdl_env_t env;
|
|
} mm_genc_prop_env_t;
|
|
|
|
/*
|
|
* INTERNAL CALLBACK FUNCTIONS
|
|
****************************************************************************************
|
|
*/
|
|
|
|
/**
|
|
****************************************************************************************
|
|
* @brief Inform Generic Property Client model about reception of a message
|
|
*
|
|
* @param[in] p_env Pointer to the environment allocated for the model
|
|
* @param[in] p_buf Pointer to buffer containing the received message
|
|
* @param[in] p_route_env Pointer to routing environment containing information about the
|
|
* received message
|
|
****************************************************************************************
|
|
*/
|
|
__STATIC void mm_genc_prop_cb_rx(mm_mdl_env_t *p_env, mesh_buf_t *p_buf,
|
|
mm_route_env_t *p_route_env)
|
|
{
|
|
// Get pointer to data
|
|
uint8_t *p_data = MESH_BUF_DATA(p_buf);
|
|
|
|
switch (p_route_env->opcode)
|
|
{
|
|
case (MM_MSG_GEN_UPROP_STATUS):
|
|
case (MM_MSG_GEN_APROP_STATUS):
|
|
case (MM_MSG_GEN_MPROP_STATUS):
|
|
{
|
|
// Extract Property ID
|
|
uint16_t prop_id = read16p(p_data + MM_GEN_PROP_STATUS_ID_POS);
|
|
// Extract User Access
|
|
uint8_t user_access = *(p_data + MM_GEN_PROP_STATUS_ACCESS_POS);
|
|
// Compute state value length
|
|
uint16_t length = p_buf->data_len - (MM_GEN_PROP_STATUS_MIN_LEN + 1);
|
|
|
|
// Send the received property state value to the application
|
|
mm_cli_prop_ind_send(p_route_env->u_addr.src, prop_id, user_access, length,
|
|
p_data + MM_GEN_PROP_STATUS_VALUE_POS);
|
|
} break;
|
|
|
|
default:
|
|
{
|
|
// Property type
|
|
uint8_t prop_type;
|
|
// Compute number of Property IDs
|
|
uint8_t nb_prop = p_buf->data_len >> 1;
|
|
|
|
switch (p_route_env->opcode)
|
|
{
|
|
case (MM_MSG_GEN_UPROPS_STATUS):
|
|
{
|
|
prop_type = MM_PROP_TYPE_USER;
|
|
} break;
|
|
|
|
case (MM_MSG_GEN_APROPS_STATUS):
|
|
{
|
|
prop_type = MM_PROP_TYPE_ADMIN;
|
|
} break;
|
|
|
|
case (MM_MSG_GEN_MPROPS_STATUS):
|
|
{
|
|
prop_type = MM_PROP_TYPE_MANUF;
|
|
} break;
|
|
|
|
default: // MM_MSG_GEN_CPROPS_STATUS
|
|
{
|
|
prop_type = MM_PROP_TYPE_CLI;
|
|
} break;
|
|
}
|
|
|
|
// Send the received list of properties to the application
|
|
mm_cli_prop_list_ind_send(p_route_env->u_addr.src, prop_type,
|
|
nb_prop, (uint16_t *)p_data);
|
|
} break;
|
|
}
|
|
}
|
|
|
|
/**
|
|
****************************************************************************************
|
|
* @brief Inform Generic Property Client model about a received opcode in order
|
|
* to check if the model is authorized to handle the associated message
|
|
*
|
|
* @param[in] p_env Pointer to the environment allocated for the model
|
|
* @param[in] opcode Opcode value to be checked
|
|
*
|
|
* @return An error status (@see enum mesh_err)
|
|
****************************************************************************************
|
|
*/
|
|
__STATIC uint8_t mm_genc_prop_cb_opcode_check(mm_mdl_env_t *p_env, uint32_t opcode)
|
|
{
|
|
uint8_t status;
|
|
|
|
if ((opcode == MM_MSG_GEN_UPROPS_STATUS)
|
|
|| (opcode == MM_MSG_GEN_UPROP_STATUS)
|
|
|| (opcode == MM_MSG_GEN_APROPS_STATUS)
|
|
|| (opcode == MM_MSG_GEN_APROP_STATUS)
|
|
|| (opcode == MM_MSG_GEN_MPROPS_STATUS)
|
|
|| (opcode == MM_MSG_GEN_MPROP_STATUS)
|
|
|| (opcode == MM_MSG_GEN_CPROPS_STATUS))
|
|
{
|
|
status = MESH_ERR_NO_ERROR;
|
|
}
|
|
else
|
|
{
|
|
status = MESH_ERR_MDL_INVALID_OPCODE;
|
|
}
|
|
|
|
return (status);
|
|
}
|
|
|
|
/*
|
|
* GLOBAL FUNCTIONS
|
|
****************************************************************************************
|
|
*/
|
|
|
|
uint8_t mm_genc_prop_register(void)
|
|
{
|
|
// Register the model
|
|
m_lid_t mdl_lid = ms_register_model(MM_ID_GENC_PROP, 0, MM_CFG_PUBLI_AUTH_BIT);
|
|
|
|
if (mdl_lid != MESH_INVALID_LID)
|
|
{
|
|
// Inform the Model State Manager about registered model
|
|
mm_genc_prop_env_t *p_env_prop = (mm_genc_prop_env_t *)mm_state_register(0, MM_ID_GENC_PROP, mdl_lid,
|
|
MM_ROLE_CLI, sizeof(mm_genc_prop_env_t));
|
|
|
|
if (p_env_prop)
|
|
{
|
|
// Set internal callback functions
|
|
p_env_prop->env.mdl_cb.cb_rx = mm_genc_prop_cb_rx;
|
|
p_env_prop->env.mdl_cb.cb_opcode_check = mm_genc_prop_cb_opcode_check;
|
|
|
|
// Inform application about registered model
|
|
mm_register_ind_send(MM_ID_GENC_PROP, 0, mdl_lid);
|
|
}
|
|
}
|
|
|
|
return (mdl_lid);
|
|
}
|
|
|
|
uint8_t mm_genc_prop_get(m_lid_t mdl_lid, m_lid_t app_key_lid, uint16_t dst,
|
|
uint8_t get_type, uint16_t prop_id)
|
|
{
|
|
// Allocate a new buffer for the message
|
|
uint8_t status = MESH_ERR_NO_ERROR;
|
|
mm_mdl_env_t *p_env = mm_state_get_env(mdl_lid);
|
|
|
|
if (p_env && (p_env->model_id == MM_ID_GENC_PROP) && (get_type <= MM_GET_TYPE_PROP_MAX))
|
|
{
|
|
// Pointer to the buffer that will contain the message
|
|
mesh_buf_t *p_buf_get;
|
|
// Opcode
|
|
uint32_t opcode = 0;
|
|
// Length
|
|
uint16_t length = 0;
|
|
|
|
switch (get_type)
|
|
{
|
|
case (MM_GET_TYPE_PROP_UPROPS):
|
|
{
|
|
opcode = MM_MSG_GEN_UPROPS_GET;
|
|
} break;
|
|
|
|
case (MM_GET_TYPE_PROP_UPROP):
|
|
{
|
|
opcode = MM_MSG_GEN_UPROP_GET;
|
|
length = 2;
|
|
} break;
|
|
|
|
case (MM_GET_TYPE_PROP_APROPS):
|
|
{
|
|
opcode = MM_MSG_GEN_APROPS_GET;
|
|
} break;
|
|
|
|
case (MM_GET_TYPE_PROP_APROP):
|
|
{
|
|
opcode = MM_MSG_GEN_APROP_GET;
|
|
length = 2;
|
|
} break;
|
|
|
|
case (MM_GET_TYPE_PROP_MPROPS):
|
|
{
|
|
opcode = MM_MSG_GEN_MPROPS_GET;
|
|
} break;
|
|
|
|
case (MM_GET_TYPE_PROP_MPROP):
|
|
{
|
|
opcode = MM_MSG_GEN_MPROP_GET;
|
|
length = 2;
|
|
} break;
|
|
|
|
case (MM_GET_TYPE_PROP_CPROPS):
|
|
{
|
|
opcode = MM_MSG_GEN_CPROPS_GET;
|
|
length = 2;
|
|
} break;
|
|
|
|
default:
|
|
{
|
|
} break;
|
|
}
|
|
|
|
p_buf_get = mm_route_buf_alloc(length);
|
|
|
|
if (p_buf_get)
|
|
{
|
|
// Get pointer to environment
|
|
mm_route_env_t *p_buf_env = (mm_route_env_t *)&p_buf_get->env;
|
|
// Get pointer to data
|
|
uint8_t *p_data = MESH_BUF_DATA(p_buf_get);
|
|
|
|
// Prepare environment
|
|
p_buf_env->app_key_lid = app_key_lid;
|
|
p_buf_env->u_addr.dst = dst;
|
|
p_buf_env->info = 0;
|
|
p_buf_env->mdl_lid = mdl_lid;
|
|
p_buf_env->opcode = opcode;
|
|
|
|
if (length != 0)
|
|
{
|
|
write16p(p_data, prop_id);
|
|
}
|
|
|
|
// Send the message
|
|
mm_route_send(p_buf_get);
|
|
}
|
|
else
|
|
{
|
|
status = MESH_ERR_INSUFFICIENT_RESOURCES;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
status = MESH_ERR_INVALID_PARAM;
|
|
}
|
|
|
|
return (status);
|
|
}
|
|
|
|
uint8_t mm_genc_prop_set(m_lid_t mdl_lid, m_lid_t app_key_lid, uint16_t dst, uint8_t set_info,
|
|
uint16_t prop_id, uint8_t user_access, uint16_t length, const uint8_t *p_val)
|
|
{
|
|
// Allocate a new buffer for the message
|
|
uint8_t status = MESH_ERR_NO_ERROR;
|
|
// Property type
|
|
uint8_t prop_type = GETF(set_info, MM_SET_INFO_TYPE);
|
|
mm_mdl_env_t *p_env = mm_state_get_env(mdl_lid);
|
|
|
|
if (p_env && (p_env->model_id == MM_ID_GENC_PROP) && (prop_type < MM_PROP_TYPE_CLI))
|
|
{
|
|
// Pointer to the buffer that will contain the message
|
|
mesh_buf_t *p_buf_get;
|
|
// Opcode
|
|
uint32_t opcode = 0;
|
|
// Length
|
|
uint16_t set_length = 0;
|
|
|
|
switch (prop_type)
|
|
{
|
|
case (MM_PROP_TYPE_USER):
|
|
{
|
|
opcode = (GETB(set_info, MM_SET_INFO_ACK))
|
|
? MM_MSG_GEN_UPROP_SET : MM_MSG_GEN_UPROP_SET_UNACK;
|
|
set_length = MM_GEN_PROP_USER_SET_MIN_LEN + length;
|
|
} break;
|
|
|
|
case (MM_PROP_TYPE_ADMIN):
|
|
{
|
|
opcode = (GETB(set_info, MM_SET_INFO_ACK))
|
|
? MM_MSG_GEN_APROP_SET : MM_MSG_GEN_APROP_SET_UNACK;
|
|
set_length = MM_GEN_PROP_ADMIN_SET_MIN_LEN + length;
|
|
} break;
|
|
|
|
case (MM_PROP_TYPE_MANUF):
|
|
{
|
|
opcode = (GETB(set_info, MM_SET_INFO_ACK))
|
|
? MM_MSG_GEN_MPROP_SET : MM_MSG_GEN_MPROP_SET_UNACK;
|
|
set_length = MM_GEN_PROP_MANUF_SET_LEN;
|
|
} break;
|
|
|
|
default:
|
|
{
|
|
} break;
|
|
}
|
|
|
|
p_buf_get = mm_route_buf_alloc(set_length);
|
|
|
|
if (p_buf_get)
|
|
{
|
|
// Get pointer to environment
|
|
mm_route_env_t *p_buf_env = (mm_route_env_t *)&p_buf_get->env;
|
|
// Get pointer to data
|
|
uint8_t *p_data = MESH_BUF_DATA(p_buf_get);
|
|
|
|
// Prepare environment
|
|
p_buf_env->app_key_lid = app_key_lid;
|
|
p_buf_env->u_addr.dst = dst;
|
|
p_buf_env->info = 0;
|
|
p_buf_env->mdl_lid = mdl_lid;
|
|
p_buf_env->opcode = opcode;
|
|
|
|
// Write Property ID
|
|
write16p(p_data, prop_id);
|
|
|
|
switch (prop_type)
|
|
{
|
|
case (MM_PROP_TYPE_USER):
|
|
{
|
|
memcpy(p_data + MM_GEN_PROP_SET_USER_VAL_POS, p_val, length);
|
|
} break;
|
|
|
|
case (MM_PROP_TYPE_ADMIN):
|
|
{
|
|
*(p_data + MM_GEN_PROP_SET_ADMIN_ACCESS_POS) = user_access;
|
|
memcpy(p_data + MM_GEN_PROP_SET_ADMIN_VAL_POS, p_val, length);
|
|
} break;
|
|
|
|
case (MM_PROP_TYPE_MANUF):
|
|
{
|
|
*(p_data + MM_GEN_PROP_SET_MANUF_ACCESS_POS) = user_access;
|
|
} break;
|
|
|
|
default:
|
|
{
|
|
} break;
|
|
}
|
|
|
|
// Send the message
|
|
mm_route_send(p_buf_get);
|
|
}
|
|
else
|
|
{
|
|
status = MESH_ERR_INSUFFICIENT_RESOURCES;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
status = MESH_ERR_INVALID_PARAM;
|
|
}
|
|
|
|
return (status);
|
|
}
|
|
|
|
/// @} end of group
|