303 lines
10 KiB
C
303 lines
10 KiB
C
/**
|
|
****************************************************************************************
|
|
*
|
|
* @file mm_genc_loc.c
|
|
*
|
|
* @brief Mesh Model Generic Location Client Module
|
|
*
|
|
****************************************************************************************
|
|
*/
|
|
|
|
/**
|
|
****************************************************************************************
|
|
* @addtogroup MM_GENC_LOC
|
|
* @{
|
|
****************************************************************************************
|
|
*/
|
|
|
|
/*
|
|
* INCLUDE FILES
|
|
****************************************************************************************
|
|
*/
|
|
|
|
#include "mm_itf.h"
|
|
#include "mm_genc.h"
|
|
|
|
|
|
/*
|
|
* TYPE DEFINITIONS
|
|
****************************************************************************************
|
|
*/
|
|
|
|
/// Structure for Generic Location Client model environment
|
|
typedef struct mm_genc_loc_env
|
|
{
|
|
/// Basic model environment - Must be first element in the structure - DO NOT MOVE
|
|
mm_mdl_env_t env;
|
|
} mm_genc_loc_env_t;
|
|
|
|
/*
|
|
* INTERNAL CALLBACK FUNCTIONS
|
|
****************************************************************************************
|
|
*/
|
|
|
|
/**
|
|
****************************************************************************************
|
|
* @brief Inform Generic Location 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_loc_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);
|
|
|
|
if (p_route_env->opcode == MM_MSG_GEN_LOCG_STATUS)
|
|
{
|
|
// Global latitude value
|
|
int32_t latitude = (int32_t)read32p(p_data + MM_GEN_LOC_STATUS_GLOB_LAT_POS);
|
|
// Global longitude value
|
|
int32_t longitude = (int32_t)read32p(p_data + MM_GEN_LOC_STATUS_GLOB_LONG_POS);
|
|
// Global altitude value
|
|
int16_t altitude = (int16_t)read16p(p_data + MM_GEN_LOC_STATUS_GLOB_ALT_POS);
|
|
|
|
// Inform the application about the received Generic Location state value (global part)
|
|
mm_cli_locg_ind_send(p_route_env->u_addr.src, latitude, longitude, altitude);
|
|
}
|
|
else
|
|
{
|
|
// Local north value
|
|
int16_t north = (int16_t)read16p(p_data + MM_GEN_LOC_STATUS_LOC_NORTH_POS);
|
|
// Local east value
|
|
int16_t east = (int16_t)read16p(p_data + MM_GEN_LOC_STATUS_LOC_EAST_POS);
|
|
// Local altitude value
|
|
int16_t altitude = (int16_t)read16p(p_data + MM_GEN_LOC_STATUS_LOC_ALT_POS);
|
|
// Floor value
|
|
uint8_t floor = *(p_data + MM_GEN_LOC_STATUS_LOC_FLOOR_POS);
|
|
// Uncertainty value
|
|
uint16_t uncertainty = read16p(p_data + MM_GEN_LOC_STATUS_LOC_UNCERT_POS);
|
|
|
|
// Inform the application about the received Generic Location state value (local part)
|
|
mm_cli_locl_ind_send(p_route_env->u_addr.src, north, east, altitude,
|
|
floor, uncertainty);
|
|
}
|
|
}
|
|
|
|
/**
|
|
****************************************************************************************
|
|
* @brief Inform Generic Location 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_loc_cb_opcode_check(mm_mdl_env_t *p_env, uint32_t opcode)
|
|
{
|
|
uint8_t status;
|
|
|
|
if ((opcode == MM_MSG_GEN_LOCG_STATUS)
|
|
|| (opcode == MM_MSG_GEN_LOCL_STATUS))
|
|
{
|
|
status = MESH_ERR_NO_ERROR;
|
|
}
|
|
else
|
|
{
|
|
status = MESH_ERR_MDL_INVALID_OPCODE;
|
|
}
|
|
|
|
return (status);
|
|
}
|
|
|
|
/**
|
|
****************************************************************************************
|
|
* @brief Send a Generic Location Get message in order to retrieve Generic Location state
|
|
* value (either global or local part) of a given node's element.
|
|
*
|
|
* @param[in] p_env Pointer to the environment allocated for the model
|
|
* @param[in] dst Address of node's element from which Generic Location state value
|
|
* must be retrieved
|
|
* @param[in] get_info Get information
|
|
*
|
|
* @return An error status (@see enum mesh_err)
|
|
****************************************************************************************
|
|
*/
|
|
__STATIC uint8_t mm_genc_loc_cb_get(mm_mdl_env_t *p_env, m_lid_t app_key_lid, uint16_t dst,
|
|
uint16_t get_info)
|
|
{
|
|
uint8_t status = MESH_ERR_NO_ERROR;
|
|
// Pointer to the buffer that will contain the message
|
|
mesh_buf_t *p_buf_get = mm_route_buf_alloc(0);
|
|
|
|
if (p_buf_get)
|
|
{
|
|
// Get pointer to environment
|
|
mm_route_env_t *p_buf_env = (mm_route_env_t *)&p_buf_get->env;
|
|
|
|
// 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 = p_env->mdl_lid;
|
|
p_buf_env->opcode = (get_info == MM_GET_TYPE_LOC_GLOBAL)
|
|
? MM_MSG_GEN_LOCG_GET : MM_MSG_GEN_LOCL_GET;
|
|
|
|
// Send the message
|
|
mm_route_send(p_buf_get);
|
|
}
|
|
else
|
|
{
|
|
status = MESH_ERR_INSUFFICIENT_RESOURCES;
|
|
}
|
|
|
|
return (status);
|
|
}
|
|
|
|
/*
|
|
* GLOBAL FUNCTIONS
|
|
****************************************************************************************
|
|
*/
|
|
|
|
__STATIC mm_cli_cb_t mm_genc_loc_cb =
|
|
{
|
|
.cb_get = mm_genc_loc_cb_get,
|
|
.cb_set = NULL,
|
|
.cb_trans = NULL,
|
|
};
|
|
|
|
uint8_t mm_genc_loc_register(void)
|
|
{
|
|
// Model local index
|
|
m_lid_t mdl_lid = ms_register_model(MM_ID_GENC_LOC, 0, MM_CFG_PUBLI_AUTH_BIT);
|
|
|
|
if (mdl_lid != MESH_INVALID_LID)
|
|
{
|
|
// Inform the Model State Manager about registered model
|
|
mm_genc_loc_env_t *p_env_loc = (mm_genc_loc_env_t *)mm_state_register(0, MM_ID_GENC_LOC, mdl_lid,
|
|
MM_ROLE_CLI, sizeof(mm_genc_loc_env_t));
|
|
|
|
if (p_env_loc)
|
|
{
|
|
// Get client-specific callback functions
|
|
//mm_cli_cb_t *p_cb_cli = p_env_loc->env.cb.u.p_cb_cli;
|
|
|
|
// Set internal callback functions
|
|
p_env_loc->env.mdl_cb.cb_rx = mm_genc_loc_cb_rx;
|
|
p_env_loc->env.mdl_cb.cb_opcode_check = mm_genc_loc_cb_opcode_check;
|
|
//p_cb_cli->cb_get = mm_genc_loc_cb_get;
|
|
p_env_loc->env.mdl_cb.p_cb_cli = &mm_genc_loc_cb;
|
|
|
|
// Inform application about registered model
|
|
mm_register_ind_send(MM_ID_GENC_LOC, 0, mdl_lid);
|
|
}
|
|
}
|
|
|
|
return (mdl_lid);
|
|
}
|
|
|
|
uint8_t mm_genc_locg_set(m_lid_t mdl_lid, m_lid_t app_key_lid, uint16_t dst,
|
|
uint8_t set_info, int32_t latitude, int32_t longitude, int16_t altitude)
|
|
{
|
|
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_LOC)
|
|
{
|
|
// Pointer to the buffer that will contain the message
|
|
mesh_buf_t *p_buf_set = mm_route_buf_alloc(MM_GEN_LOC_SET_GLOB_LEN);
|
|
|
|
if (p_buf_set)
|
|
{
|
|
// Get pointer to data
|
|
uint8_t *p_data = MESH_BUF_DATA(p_buf_set);
|
|
// Get pointer to environment
|
|
mm_route_env_t *p_buf_env = (mm_route_env_t *)&p_buf_set->env;
|
|
|
|
// 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 = p_env->mdl_lid;
|
|
p_buf_env->opcode = GETB(set_info, MM_SET_INFO_ACK)
|
|
? MM_MSG_GEN_LOCG_SET : MM_MSG_GEN_LOCG_SET_UNACK;
|
|
|
|
// Fill the message
|
|
write32p(p_data + MM_GEN_LOC_SET_GLOB_LAT_POS, latitude);
|
|
write32p(p_data + MM_GEN_LOC_SET_GLOB_LONG_POS, longitude);
|
|
write16p(p_data + MM_GEN_LOC_SET_GLOB_ALT_POS, altitude);
|
|
|
|
// Send the message
|
|
mm_route_send(p_buf_set);
|
|
}
|
|
else
|
|
{
|
|
status = MESH_ERR_INSUFFICIENT_RESOURCES;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
status = MESH_ERR_INVALID_PARAM;
|
|
}
|
|
|
|
return (status);
|
|
}
|
|
|
|
uint8_t mm_genc_locl_set(m_lid_t mdl_lid, m_lid_t app_key_lid, uint16_t dst,
|
|
uint8_t set_info, int16_t north, int16_t east, int16_t altitude,
|
|
uint8_t floor, uint16_t uncertainty)
|
|
{
|
|
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_LOC)
|
|
{
|
|
// Pointer to the buffer that will contain the message
|
|
mesh_buf_t *p_buf_set = mm_route_buf_alloc(MM_GEN_LOC_SET_LOC_LEN);
|
|
|
|
if (p_buf_set)
|
|
{
|
|
// Get pointer to data
|
|
uint8_t *p_data = MESH_BUF_DATA(p_buf_set);
|
|
// Get pointer to environment
|
|
mm_route_env_t *p_buf_env = (mm_route_env_t *)&p_buf_set->env;
|
|
|
|
// 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 = p_env->mdl_lid;
|
|
p_buf_env->opcode = GETB(set_info, MM_SET_INFO_ACK)
|
|
? MM_MSG_GEN_LOCL_SET : MM_MSG_GEN_LOCL_SET_UNACK;
|
|
|
|
// Fill the message
|
|
write16p(p_data + MM_GEN_LOC_SET_LOC_NORTH_POS, north);
|
|
write16p(p_data + MM_GEN_LOC_SET_LOC_EAST_POS, east);
|
|
write16p(p_data + MM_GEN_LOC_SET_LOC_ALT_POS, altitude);
|
|
*(p_data + MM_GEN_LOC_SET_LOC_FLOOR_POS) = floor;
|
|
write16p(p_data + MM_GEN_LOC_SET_LOC_UNCERT_POS, uncertainty);
|
|
|
|
// Send the message
|
|
mm_route_send(p_buf_set);
|
|
}
|
|
else
|
|
{
|
|
status = MESH_ERR_INSUFFICIENT_RESOURCES;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
status = MESH_ERR_INVALID_PARAM;
|
|
}
|
|
|
|
return (status);
|
|
}
|
|
|
|
/// @} end of group
|