2022-08-15 04:20:27 -05:00
|
|
|
/**
|
|
|
|
****************************************************************************************
|
|
|
|
* @addtogroup LANC
|
|
|
|
* @{
|
|
|
|
****************************************************************************************
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* INCLUDE FILES
|
|
|
|
****************************************************************************************
|
|
|
|
*/
|
|
|
|
#include "rwip_config.h"
|
|
|
|
|
|
|
|
#if (BLE_LN_COLLECTOR)
|
|
|
|
#include "lan_common.h"
|
|
|
|
|
|
|
|
#include "lanc.h"
|
|
|
|
#include "lanc_task.h"
|
|
|
|
|
|
|
|
#include "co_utils.h"
|
2023-02-01 14:52:54 -06:00
|
|
|
#include "ke_mem.h"
|
|
|
|
#include "ke_timer.h"
|
2022-08-15 04:20:27 -05:00
|
|
|
|
|
|
|
/*
|
|
|
|
* GLOBAL VARIABLES DECLARATION
|
|
|
|
****************************************************************************************
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* LOCAL FUNCTION DEFINITIONS
|
|
|
|
****************************************************************************************
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
****************************************************************************************
|
|
|
|
* @brief Initialization of the LANC module.
|
|
|
|
* This function performs all the initializations of the Profile module.
|
|
|
|
* - Creation of database (if it's a service)
|
|
|
|
* - Allocation of profile required memory
|
|
|
|
* - Initialization of task descriptor to register application
|
|
|
|
* - Task State array
|
|
|
|
* - Number of tasks
|
|
|
|
* - Default task handler
|
|
|
|
*
|
|
|
|
* @param[out] env Collector or Service allocated environment data.
|
2023-02-01 14:52:54 -06:00
|
|
|
* @param[in|out] start_hdl Service start handle (0 - dynamically allocated),
|
|
|
|
*only applies for services.
|
2022-08-15 04:20:27 -05:00
|
|
|
* @param[in] app_task Application task number.
|
2023-02-01 14:52:54 -06:00
|
|
|
* @param[in] sec_lvl Security level (AUTH, EKS and MI field of @see enum
|
|
|
|
*attm_value_perm_mask)
|
|
|
|
* @param[in] param Configuration parameters of profile collector or
|
|
|
|
*service (32 bits aligned)
|
2022-08-15 04:20:27 -05:00
|
|
|
*
|
|
|
|
* @return status code to know if profile initialization succeed or not.
|
|
|
|
****************************************************************************************
|
|
|
|
*/
|
|
|
|
|
2023-02-01 14:52:54 -06:00
|
|
|
static uint8_t lanc_init(struct prf_task_env *env, uint16_t *start_hdl,
|
|
|
|
uint16_t app_task, uint8_t sec_lvl, void *params) {
|
|
|
|
uint8_t idx;
|
|
|
|
//-------------------- allocate memory required for the profile
|
|
|
|
//---------------------
|
2022-08-15 04:20:27 -05:00
|
|
|
|
2023-02-01 14:52:54 -06:00
|
|
|
struct lanc_env_tag *lanc_env = (struct lanc_env_tag *)ke_malloc(
|
|
|
|
sizeof(struct lanc_env_tag), KE_MEM_ATT_DB);
|
2022-08-15 04:20:27 -05:00
|
|
|
|
2023-02-01 14:52:54 -06:00
|
|
|
// allocate LANC required environment variable
|
|
|
|
env->env = (prf_env_t *)lanc_env;
|
2022-08-15 04:20:27 -05:00
|
|
|
|
2023-02-01 14:52:54 -06:00
|
|
|
lanc_env->prf_env.app_task =
|
|
|
|
app_task | (PERM_GET(sec_lvl, SVC_MI) ? PERM(PRF_MI, ENABLE)
|
|
|
|
: PERM(PRF_MI, DISABLE));
|
|
|
|
lanc_env->prf_env.prf_task = env->task | PERM(PRF_MI, ENABLE);
|
2022-08-15 04:20:27 -05:00
|
|
|
|
2023-02-01 14:52:54 -06:00
|
|
|
// initialize environment variable
|
|
|
|
env->id = TASK_ID_LANC;
|
|
|
|
lanc_task_init(&(env->desc));
|
2022-08-15 04:20:27 -05:00
|
|
|
|
2023-02-01 14:52:54 -06:00
|
|
|
for (idx = 0; idx < LANC_IDX_MAX; idx++) {
|
|
|
|
lanc_env->env[idx] = NULL;
|
|
|
|
// service is ready, go into an Idle state
|
|
|
|
ke_state_set(KE_BUILD_ID(env->task, idx), LANC_FREE);
|
|
|
|
}
|
2022-08-15 04:20:27 -05:00
|
|
|
|
2023-02-01 14:52:54 -06:00
|
|
|
return GAP_ERR_NO_ERROR;
|
2022-08-15 04:20:27 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
****************************************************************************************
|
|
|
|
* @brief Clean-up connection dedicated environment parameters
|
|
|
|
* This function performs cleanup of ongoing operations
|
|
|
|
* @param[in|out] env Collector or Service allocated environment data.
|
|
|
|
* @param[in] conidx Connection index
|
|
|
|
* @param[in] reason Detach reason
|
|
|
|
****************************************************************************************
|
|
|
|
*/
|
2023-02-01 14:52:54 -06:00
|
|
|
static void lanc_cleanup(struct prf_task_env *env, uint8_t conidx,
|
|
|
|
uint8_t reason) {
|
|
|
|
struct lanc_env_tag *lanc_env = (struct lanc_env_tag *)env->env;
|
|
|
|
|
|
|
|
// clean-up environment variable allocated for task instance
|
|
|
|
if (lanc_env->env[conidx] != NULL) {
|
|
|
|
if (lanc_env->env[conidx]->operation != NULL) {
|
|
|
|
ke_free(ke_param2msg(lanc_env->env[conidx]->operation));
|
2022-08-15 04:20:27 -05:00
|
|
|
}
|
2023-02-01 14:52:54 -06:00
|
|
|
ke_timer_clear(LANC_TIMEOUT_TIMER_IND,
|
|
|
|
prf_src_task_get(&lanc_env->prf_env, conidx));
|
2022-08-15 04:20:27 -05:00
|
|
|
|
2023-02-01 14:52:54 -06:00
|
|
|
ke_free(lanc_env->env[conidx]);
|
|
|
|
lanc_env->env[conidx] = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Put LAN Client in Free state */
|
|
|
|
ke_state_set(KE_BUILD_ID(env->task, conidx), LANC_FREE);
|
2022-08-15 04:20:27 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
****************************************************************************************
|
|
|
|
* @brief Destruction of the LANC module - due to a reset for instance.
|
2023-02-01 14:52:54 -06:00
|
|
|
* This function clean-up allocated memory (attribute database is destroyed by
|
|
|
|
*another procedure)
|
2022-08-15 04:20:27 -05:00
|
|
|
*
|
|
|
|
* @param[in|out] env Collector or Service allocated environment data.
|
|
|
|
****************************************************************************************
|
|
|
|
*/
|
2023-02-01 14:52:54 -06:00
|
|
|
static void lanc_destroy(struct prf_task_env *env) {
|
|
|
|
uint8_t idx;
|
|
|
|
struct lanc_env_tag *lanc_env = (struct lanc_env_tag *)env->env;
|
|
|
|
|
|
|
|
// cleanup environment variable for each task instances
|
|
|
|
for (idx = 0; idx < LANC_IDX_MAX; idx++) {
|
|
|
|
lanc_cleanup(env, idx, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
// free profile environment variables
|
|
|
|
env->env = NULL;
|
|
|
|
ke_free(lanc_env);
|
2022-08-15 04:20:27 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
****************************************************************************************
|
|
|
|
* @brief Handles Connection creation
|
|
|
|
*
|
|
|
|
* @param[in|out] env Collector or Service allocated environment data.
|
|
|
|
* @param[in] conidx Connection index
|
|
|
|
****************************************************************************************
|
|
|
|
*/
|
2023-02-01 14:52:54 -06:00
|
|
|
static void lanc_create(struct prf_task_env *env, uint8_t conidx) {
|
|
|
|
/* Put LAN Client in Idle state */
|
|
|
|
ke_state_set(KE_BUILD_ID(env->task, conidx), LANC_IDLE);
|
2022-08-15 04:20:27 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/// LANC Task interface required by profile manager
|
2023-02-01 14:52:54 -06:00
|
|
|
const struct prf_task_cbs lanc_itf = {
|
|
|
|
lanc_init,
|
|
|
|
lanc_destroy,
|
|
|
|
lanc_create,
|
|
|
|
lanc_cleanup,
|
2022-08-15 04:20:27 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* GLOBAL FUNCTIONS DEFINITIONS
|
|
|
|
****************************************************************************************
|
|
|
|
*/
|
|
|
|
|
2023-02-01 14:52:54 -06:00
|
|
|
const struct prf_task_cbs *lanc_prf_itf_get(void) { return &lanc_itf; }
|
|
|
|
|
|
|
|
void lanc_enable_rsp_send(struct lanc_env_tag *lanc_env, uint8_t conidx,
|
|
|
|
uint8_t status) {
|
|
|
|
// Send to APP the details of the discovered attributes on LANS
|
|
|
|
struct lanc_enable_rsp *rsp = KE_MSG_ALLOC(
|
|
|
|
LANC_ENABLE_RSP, prf_dst_task_get(&(lanc_env->prf_env), conidx),
|
|
|
|
prf_src_task_get(&(lanc_env->prf_env), conidx), lanc_enable_rsp);
|
|
|
|
rsp->status = status;
|
|
|
|
|
|
|
|
if (status == GAP_ERR_NO_ERROR) {
|
|
|
|
rsp->lns = lanc_env->env[conidx]->lans;
|
|
|
|
// Register LANC task in gatt for indication/notifications
|
|
|
|
prf_register_atthdl2gatt(&(lanc_env->prf_env), conidx,
|
|
|
|
&(lanc_env->env[conidx]->lans.svc));
|
|
|
|
// Go to connected state
|
|
|
|
ke_state_set(prf_src_task_get(&(lanc_env->prf_env), conidx), LANC_IDLE);
|
|
|
|
}
|
|
|
|
|
|
|
|
ke_msg_send(rsp);
|
2022-08-15 04:20:27 -05:00
|
|
|
}
|
|
|
|
|
2023-02-01 14:52:54 -06:00
|
|
|
void lanc_send_no_conn_cmp_evt(uint8_t src_id, uint8_t dest_id,
|
|
|
|
uint8_t operation) {
|
|
|
|
// Send the message
|
|
|
|
struct lanc_cmp_evt *evt =
|
|
|
|
KE_MSG_ALLOC(LANC_CMP_EVT, dest_id, src_id, lanc_cmp_evt);
|
2022-08-15 04:20:27 -05:00
|
|
|
|
2023-02-01 14:52:54 -06:00
|
|
|
evt->operation = operation;
|
|
|
|
evt->status = PRF_ERR_REQ_DISALLOWED;
|
2022-08-15 04:20:27 -05:00
|
|
|
|
2023-02-01 14:52:54 -06:00
|
|
|
ke_msg_send(evt);
|
|
|
|
}
|
2022-08-15 04:20:27 -05:00
|
|
|
|
2023-02-01 14:52:54 -06:00
|
|
|
void lanc_send_cmp_evt(struct lanc_env_tag *lanc_env, uint8_t conidx,
|
|
|
|
uint8_t operation, uint8_t status) {
|
|
|
|
// Free the stored operation if needed
|
|
|
|
if (lanc_env->env[conidx]->operation != NULL) {
|
|
|
|
ke_msg_free(ke_param2msg(lanc_env->env[conidx]->operation));
|
|
|
|
lanc_env->env[conidx]->operation = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Go back to the CONNECTED state if the state is busy
|
|
|
|
if (ke_state_get(prf_src_task_get(&(lanc_env->prf_env), conidx)) ==
|
|
|
|
LANC_BUSY) {
|
|
|
|
ke_state_set(prf_src_task_get(&(lanc_env->prf_env), conidx), LANC_IDLE);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Send the message
|
|
|
|
struct lanc_cmp_evt *evt = KE_MSG_ALLOC(
|
|
|
|
LANC_CMP_EVT, prf_dst_task_get(&(lanc_env->prf_env), conidx),
|
|
|
|
prf_src_task_get(&(lanc_env->prf_env), conidx), lanc_cmp_evt);
|
|
|
|
|
|
|
|
evt->operation = operation;
|
|
|
|
evt->status = status;
|
|
|
|
|
|
|
|
ke_msg_send(evt);
|
|
|
|
}
|
2022-08-15 04:20:27 -05:00
|
|
|
|
2023-02-01 14:52:54 -06:00
|
|
|
uint16_t lanc_get_read_handle_req(struct lanc_env_tag *lanc_env, uint8_t conidx,
|
|
|
|
struct lanc_read_cmd *param) {
|
|
|
|
// Attribute Handle
|
|
|
|
uint16_t handle = ATT_INVALID_SEARCH_HANDLE;
|
|
|
|
|
|
|
|
switch (param->read_code) {
|
|
|
|
// Read LN Feature
|
|
|
|
case (LANC_RD_LN_FEAT): {
|
|
|
|
handle = lanc_env->env[conidx]->lans.chars[LANP_LANS_LN_FEAT_CHAR].val_hdl;
|
|
|
|
} break;
|
|
|
|
|
|
|
|
// Read Position Quality
|
|
|
|
case (LANC_RD_POS_Q): {
|
|
|
|
handle = lanc_env->env[conidx]->lans.chars[LANP_LANS_POS_Q_CHAR].val_hdl;
|
|
|
|
} break;
|
|
|
|
|
|
|
|
// Read Location and Speed Characteristic Client Char. Cfg. Descriptor Value
|
|
|
|
case (LANC_RD_WR_LOC_SPEED_CL_CFG): {
|
|
|
|
handle =
|
|
|
|
lanc_env->env[conidx]->lans.descs[LANC_DESC_LOC_SPEED_CL_CFG].desc_hdl;
|
|
|
|
} break;
|
|
|
|
|
|
|
|
// Read Unread Alert Characteristic Client Char. Cfg. Descriptor Value
|
|
|
|
case (LANC_RD_WR_LN_CTNL_PT_CFG): {
|
|
|
|
handle =
|
|
|
|
lanc_env->env[conidx]->lans.descs[LANC_DESC_LN_CTNL_PT_CL_CFG].desc_hdl;
|
|
|
|
} break;
|
|
|
|
|
|
|
|
// Read Navigation Characteristic Server Char. Cfg. Descriptor Value
|
|
|
|
case (LANC_RD_WR_NAVIGATION_CFG): {
|
|
|
|
handle =
|
|
|
|
lanc_env->env[conidx]->lans.descs[LANC_DESC_NAVIGATION_CL_CFG].desc_hdl;
|
|
|
|
} break;
|
|
|
|
|
|
|
|
default: {
|
|
|
|
handle = ATT_INVALID_SEARCH_HANDLE;
|
|
|
|
} break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return handle;
|
2022-08-15 04:20:27 -05:00
|
|
|
}
|
|
|
|
|
2023-02-01 14:52:54 -06:00
|
|
|
uint8_t lanc_get_write_desc_handle_req(uint8_t conidx,
|
|
|
|
struct lanc_cfg_ntfind_cmd *param,
|
|
|
|
struct lanc_env_tag *lanc_env,
|
|
|
|
uint16_t *handle) {
|
|
|
|
// Status
|
|
|
|
uint8_t status = GAP_ERR_NO_ERROR;
|
|
|
|
|
|
|
|
switch (param->desc_code) {
|
|
|
|
// Write Location and speed Characteristic Client Char. Cfg. Descriptor Value
|
|
|
|
case (LANC_RD_WR_LOC_SPEED_CL_CFG): {
|
|
|
|
if (param->ntfind_cfg <= PRF_CLI_START_NTF) {
|
|
|
|
*handle = lanc_env->env[conidx]
|
|
|
|
->lans.descs[LANC_DESC_LOC_SPEED_CL_CFG]
|
|
|
|
.desc_hdl;
|
|
|
|
|
|
|
|
// The descriptor is mandatory
|
|
|
|
ASSERT_ERR(*handle != ATT_INVALID_SEARCH_HANDLE);
|
|
|
|
} else {
|
|
|
|
status = PRF_ERR_INVALID_PARAM;
|
2022-08-15 04:20:27 -05:00
|
|
|
}
|
2023-02-01 14:52:54 -06:00
|
|
|
} break;
|
|
|
|
|
|
|
|
// Write LN Control Point Characteristic Client Char. Cfg. Descriptor Value
|
|
|
|
case (LANC_RD_WR_LN_CTNL_PT_CFG): {
|
|
|
|
if ((param->ntfind_cfg == PRF_CLI_STOP_NTFIND) ||
|
|
|
|
(param->ntfind_cfg == PRF_CLI_START_IND)) {
|
|
|
|
*handle = lanc_env->env[conidx]
|
|
|
|
->lans.descs[LANC_DESC_LN_CTNL_PT_CL_CFG]
|
|
|
|
.desc_hdl;
|
|
|
|
|
|
|
|
if (*handle == ATT_INVALID_SEARCH_HANDLE) {
|
|
|
|
// The descriptor has not been found.
|
|
|
|
status = PRF_ERR_INEXISTENT_HDL;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
status = PRF_ERR_INVALID_PARAM;
|
2022-08-15 04:20:27 -05:00
|
|
|
}
|
2023-02-01 14:52:54 -06:00
|
|
|
} break;
|
|
|
|
|
|
|
|
// Write Navigation Characteristic Client Char. Cfg. Descriptor Value
|
|
|
|
case (LANC_RD_WR_NAVIGATION_CFG): {
|
|
|
|
if (param->ntfind_cfg <= PRF_CLI_START_NTF) {
|
|
|
|
*handle = lanc_env->env[conidx]
|
|
|
|
->lans.descs[LANC_DESC_NAVIGATION_CL_CFG]
|
|
|
|
.desc_hdl;
|
|
|
|
|
|
|
|
if (*handle == ATT_INVALID_SEARCH_HANDLE) {
|
|
|
|
// The descriptor has not been found.
|
|
|
|
status = PRF_ERR_INEXISTENT_HDL;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
status = PRF_ERR_INVALID_PARAM;
|
|
|
|
}
|
|
|
|
} break;
|
2022-08-15 04:20:27 -05:00
|
|
|
|
2023-02-01 14:52:54 -06:00
|
|
|
default: {
|
|
|
|
status = PRF_ERR_INVALID_PARAM;
|
|
|
|
} break;
|
|
|
|
}
|
2022-08-15 04:20:27 -05:00
|
|
|
|
2023-02-01 14:52:54 -06:00
|
|
|
return (status);
|
2022-08-15 04:20:27 -05:00
|
|
|
}
|
|
|
|
|
2023-02-01 14:52:54 -06:00
|
|
|
uint8_t lanc_unpack_loc_speed_ind(uint8_t conidx,
|
|
|
|
struct gattc_event_ind const *param,
|
|
|
|
struct lanc_env_tag *lanc_env) {
|
|
|
|
// Offset
|
|
|
|
uint8_t offset = LANP_LAN_LOC_SPEED_MIN_LEN;
|
2022-08-15 04:20:27 -05:00
|
|
|
|
2023-02-01 14:52:54 -06:00
|
|
|
// LN Measurement value has been received
|
|
|
|
struct lanc_value_ind *ind = KE_MSG_ALLOC(
|
|
|
|
LANC_VALUE_IND, prf_dst_task_get(&(lanc_env->prf_env), conidx),
|
|
|
|
prf_src_task_get(&(lanc_env->prf_env), conidx), lanc_value_ind);
|
2022-08-15 04:20:27 -05:00
|
|
|
|
2023-02-01 14:52:54 -06:00
|
|
|
// Attribute code
|
|
|
|
ind->att_code = LANC_NTF_LOC_SPEED;
|
2022-08-15 04:20:27 -05:00
|
|
|
|
2023-02-01 14:52:54 -06:00
|
|
|
if ((param->length >= LANP_LAN_LOC_SPEED_MIN_LEN) &&
|
|
|
|
(param->length <= LANP_LAN_LOC_SPEED_MAX_LEN)) {
|
|
|
|
// Flags
|
|
|
|
ind->value.loc_speed.flags = co_read16p(¶m->value[0]);
|
2022-08-15 04:20:27 -05:00
|
|
|
|
2023-02-01 14:52:54 -06:00
|
|
|
if (ind->value.loc_speed.flags & LANP_LSPEED_INST_SPEED_PRESENT) {
|
|
|
|
// Unpack instantaneous speed
|
|
|
|
ind->value.loc_speed.inst_speed = co_read16p(¶m->value[offset]);
|
|
|
|
offset += 2;
|
2022-08-15 04:20:27 -05:00
|
|
|
}
|
|
|
|
|
2023-02-01 14:52:54 -06:00
|
|
|
if (ind->value.loc_speed.flags & LANP_LSPEED_TOTAL_DISTANCE_PRESENT) {
|
|
|
|
// Unpack Total distance (24 bits)
|
|
|
|
ind->value.loc_speed.total_dist = co_read24p(¶m->value[offset]);
|
|
|
|
offset += 3;
|
|
|
|
}
|
2022-08-15 04:20:27 -05:00
|
|
|
|
2023-02-01 14:52:54 -06:00
|
|
|
if (ind->value.loc_speed.flags & LANP_LSPEED_LOCATION_PRESENT) {
|
|
|
|
// Unpack Location
|
|
|
|
ind->value.loc_speed.latitude = co_read32p(¶m->value[offset]);
|
|
|
|
offset += 4;
|
|
|
|
ind->value.loc_speed.longitude = co_read32p(¶m->value[offset]);
|
|
|
|
offset += 4;
|
|
|
|
}
|
2022-08-15 04:20:27 -05:00
|
|
|
|
2023-02-01 14:52:54 -06:00
|
|
|
if (ind->value.loc_speed.flags & LANP_LSPEED_ELEVATION_PRESENT) {
|
|
|
|
// Unpack Elevation (24 bits)
|
|
|
|
ind->value.loc_speed.elevation = co_read24p(¶m->value[offset]);
|
|
|
|
offset += 3;
|
2022-08-15 04:20:27 -05:00
|
|
|
}
|
|
|
|
|
2023-02-01 14:52:54 -06:00
|
|
|
if (ind->value.loc_speed.flags & LANP_LSPEED_HEADING_PRESENT) {
|
|
|
|
// Unpack heading
|
|
|
|
ind->value.loc_speed.heading = co_read16p(¶m->value[offset]);
|
|
|
|
offset += 2;
|
|
|
|
}
|
2022-08-15 04:20:27 -05:00
|
|
|
|
2023-02-01 14:52:54 -06:00
|
|
|
if (ind->value.loc_speed.flags & LANP_LSPEED_ROLLING_TIME_PRESENT) {
|
|
|
|
// Unpack rolling time
|
|
|
|
ind->value.loc_speed.rolling_time = param->value[offset];
|
|
|
|
offset++;
|
|
|
|
}
|
2022-08-15 04:20:27 -05:00
|
|
|
|
2023-02-01 14:52:54 -06:00
|
|
|
if (ind->value.loc_speed.flags & LANP_LSPEED_UTC_TIME_PRESENT) {
|
|
|
|
// Unpack UTC time
|
|
|
|
offset += prf_unpack_date_time((uint8_t *)&(param->value[offset]),
|
|
|
|
&(ind->value.loc_speed.date_time));
|
|
|
|
}
|
|
|
|
}
|
2022-08-15 04:20:27 -05:00
|
|
|
|
2023-02-01 14:52:54 -06:00
|
|
|
// Send the message
|
|
|
|
ke_msg_send(ind);
|
2022-08-15 04:20:27 -05:00
|
|
|
|
2023-02-01 14:52:54 -06:00
|
|
|
return offset;
|
|
|
|
}
|
2022-08-15 04:20:27 -05:00
|
|
|
|
2023-02-01 14:52:54 -06:00
|
|
|
uint8_t lanc_unpack_navigation_ind(uint8_t conidx,
|
|
|
|
struct gattc_event_ind const *param,
|
|
|
|
struct lanc_env_tag *lanc_env) {
|
|
|
|
// Offset
|
|
|
|
uint8_t offset = LANP_LAN_NAVIGATION_MIN_LEN;
|
2022-08-15 04:20:27 -05:00
|
|
|
|
2023-02-01 14:52:54 -06:00
|
|
|
// LN Measurement value has been received
|
|
|
|
struct lanc_value_ind *ind = KE_MSG_ALLOC(
|
|
|
|
LANC_VALUE_IND, prf_dst_task_get(&(lanc_env->prf_env), conidx),
|
|
|
|
prf_src_task_get(&(lanc_env->prf_env), conidx), lanc_value_ind);
|
2022-08-15 04:20:27 -05:00
|
|
|
|
2023-02-01 14:52:54 -06:00
|
|
|
// Attribute code
|
|
|
|
ind->att_code = LANC_NTF_NAVIGATION;
|
2022-08-15 04:20:27 -05:00
|
|
|
|
2023-02-01 14:52:54 -06:00
|
|
|
if ((param->length >= LANP_LAN_NAVIGATION_MIN_LEN) &&
|
|
|
|
(param->length <= LANP_LAN_NAVIGATION_MAX_LEN)) {
|
|
|
|
// Flags
|
|
|
|
ind->value.navigation.flags = co_read16p(¶m->value[0]);
|
|
|
|
// Bearing
|
|
|
|
ind->value.navigation.bearing = co_read16p(¶m->value[2]);
|
|
|
|
// Heading
|
|
|
|
ind->value.navigation.heading = co_read16p(¶m->value[4]);
|
|
|
|
|
|
|
|
if (ind->value.navigation.flags & LANP_NAVI_REMAINING_DIS_PRESENT) {
|
|
|
|
// Unpack remaining distance (24 bits)
|
|
|
|
ind->value.navigation.remaining_distance =
|
|
|
|
co_read24p(¶m->value[offset]);
|
|
|
|
offset += 3;
|
2022-08-15 04:20:27 -05:00
|
|
|
}
|
|
|
|
|
2023-02-01 14:52:54 -06:00
|
|
|
if (ind->value.navigation.flags & LANP_NAVI_REMAINING_VER_DIS_PRESENT) {
|
|
|
|
// Unpack remaining vertical distance (24 bits)
|
|
|
|
ind->value.navigation.remaining_ver_distance =
|
|
|
|
co_read24p(¶m->value[offset]);
|
|
|
|
offset += 3;
|
2022-08-15 04:20:27 -05:00
|
|
|
}
|
|
|
|
|
2023-02-01 14:52:54 -06:00
|
|
|
if (ind->value.navigation.flags &
|
|
|
|
LANP_NAVI_ESTIMATED_TIME_OF_ARRIVAL_PRESENT) {
|
|
|
|
// Unpack time
|
|
|
|
offset +=
|
|
|
|
prf_unpack_date_time((uint8_t *)&(param->value[offset]),
|
|
|
|
&(ind->value.navigation.estimated_arrival_time));
|
2022-08-15 04:20:27 -05:00
|
|
|
}
|
2023-02-01 14:52:54 -06:00
|
|
|
}
|
2022-08-15 04:20:27 -05:00
|
|
|
|
2023-02-01 14:52:54 -06:00
|
|
|
// Send the message
|
|
|
|
ke_msg_send(ind);
|
2022-08-15 04:20:27 -05:00
|
|
|
|
2023-02-01 14:52:54 -06:00
|
|
|
return offset;
|
2022-08-15 04:20:27 -05:00
|
|
|
}
|
|
|
|
|
2023-02-01 14:52:54 -06:00
|
|
|
uint8_t lanc_unpack_pos_q_ind(struct gattc_read_ind const *param,
|
|
|
|
struct lanc_value_ind *ind) {
|
|
|
|
/*----------------------------------------------------
|
|
|
|
* Unpack Position Quality ---------------------------
|
|
|
|
*----------------------------------------------------*/
|
|
|
|
// Offset
|
|
|
|
uint8_t offset = LANP_LAN_POSQ_MIN_LEN;
|
|
|
|
|
|
|
|
// Flags
|
|
|
|
ind->value.pos_q.flags = co_read16p(¶m->value[0]);
|
|
|
|
|
|
|
|
if (ind->value.pos_q.flags &
|
|
|
|
LANP_POSQ_NUMBER_OF_BEACONS_IN_SOLUTION_PRESENT) {
|
|
|
|
// Unpack beacons in solution
|
|
|
|
ind->value.pos_q.n_beacons_solution = param->value[offset];
|
|
|
|
offset++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ind->value.pos_q.flags & LANP_POSQ_NUMBER_OF_BEACONS_IN_VIEW_PRESENT) {
|
|
|
|
// Unpack beacons in view
|
|
|
|
ind->value.pos_q.n_beacons_view = param->value[offset];
|
|
|
|
offset++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ind->value.pos_q.flags & LANP_POSQ_TIME_TO_FIRST_FIX_PRESENT) {
|
|
|
|
// Unpack time first fix
|
|
|
|
ind->value.pos_q.time_first_fix = co_read16p(¶m->value[offset]);
|
|
|
|
offset += 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ind->value.pos_q.flags & LANP_POSQ_EHPE_PRESENT) {
|
|
|
|
// Unpack ehpe
|
|
|
|
ind->value.pos_q.ehpe = co_read32p(¶m->value[offset]);
|
|
|
|
offset += 4;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ind->value.pos_q.flags & LANP_POSQ_EVPE_PRESENT) {
|
|
|
|
// Unpack evpe
|
|
|
|
ind->value.pos_q.evpe = co_read32p(¶m->value[offset]);
|
|
|
|
offset += 4;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ind->value.pos_q.flags & LANP_POSQ_HDOP_PRESENT) {
|
|
|
|
// Unpack hdop
|
|
|
|
ind->value.pos_q.hdop = param->value[offset];
|
|
|
|
offset++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ind->value.pos_q.flags & LANP_POSQ_VDOP_PRESENT) {
|
|
|
|
// Unpack vdop
|
|
|
|
ind->value.pos_q.vdop = param->value[offset];
|
|
|
|
offset++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return offset;
|
|
|
|
}
|
2022-08-15 04:20:27 -05:00
|
|
|
|
2023-02-01 14:52:54 -06:00
|
|
|
uint8_t lanc_pack_ln_ctnl_pt_req(struct lanc_ln_ctnl_pt_cfg_req *param,
|
|
|
|
uint8_t *req, uint8_t *status) {
|
|
|
|
// Request Length
|
|
|
|
uint8_t req_len = LANP_LAN_LN_CNTL_PT_REQ_MIN_LEN;
|
|
|
|
|
|
|
|
// Set the operation code
|
|
|
|
req[0] = param->ln_ctnl_pt.op_code;
|
|
|
|
|
|
|
|
// Fulfill the message according to the operation code
|
|
|
|
switch (param->ln_ctnl_pt.op_code) {
|
|
|
|
case (LANP_LN_CTNL_PT_SET_CUMUL_VALUE): {
|
|
|
|
// Set the cumulative value (24 bits)
|
|
|
|
co_write24p(&req[req_len], param->ln_ctnl_pt.value.cumul_val);
|
|
|
|
// Update length
|
|
|
|
req_len += 3;
|
|
|
|
} break;
|
|
|
|
|
|
|
|
case (LANP_LN_CTNL_PT_MASK_LSPEED_CHAR_CT): {
|
|
|
|
// Set mask content
|
|
|
|
co_write16p(&req[req_len], param->ln_ctnl_pt.value.mask_content);
|
|
|
|
// Update length
|
|
|
|
req_len += 2;
|
|
|
|
} break;
|
|
|
|
|
|
|
|
case (LANP_LN_CTNL_PT_NAVIGATION_CONTROL): {
|
|
|
|
// Set control value
|
|
|
|
req[req_len] = param->ln_ctnl_pt.value.control_value;
|
|
|
|
// Update length
|
|
|
|
req_len++;
|
|
|
|
} break;
|
|
|
|
|
|
|
|
case (LANP_LN_CTNL_PT_REQ_NAME_OF_ROUTE):
|
|
|
|
case (LANP_LN_CTNL_PT_SELECT_ROUTE): {
|
|
|
|
// Set route number
|
|
|
|
co_write16p(&req[req_len], param->ln_ctnl_pt.value.route_number);
|
|
|
|
// Update length
|
|
|
|
req_len += 2;
|
|
|
|
} break;
|
|
|
|
|
|
|
|
case (LANP_LN_CTNL_PT_SET_FIX_RATE): {
|
|
|
|
// Set the fix rate
|
|
|
|
req[req_len] = param->ln_ctnl_pt.value.fix_rate;
|
|
|
|
// Update length
|
|
|
|
req_len++;
|
|
|
|
} break;
|
|
|
|
|
|
|
|
case (LANP_LN_CTNL_PT_SET_ELEVATION): {
|
|
|
|
// Set elevation (24 bits)
|
|
|
|
co_write24p(&req[req_len], param->ln_ctnl_pt.value.elevation);
|
|
|
|
// Update length
|
|
|
|
req_len += 3;
|
|
|
|
} break;
|
|
|
|
|
|
|
|
case (LANP_LN_CTNL_PT_REQ_NUMBER_OF_ROUTES): {
|
|
|
|
// Nothing more to do
|
|
|
|
} break;
|
|
|
|
|
|
|
|
default: {
|
|
|
|
*status = PRF_ERR_INVALID_PARAM;
|
|
|
|
} break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return req_len;
|
2022-08-15 04:20:27 -05:00
|
|
|
}
|
|
|
|
|
2023-02-01 14:52:54 -06:00
|
|
|
uint8_t lanc_unpack_ln_ctln_pt_ind(struct gattc_event_ind const *param,
|
|
|
|
ke_task_id_t src, ke_task_id_t dest) {
|
|
|
|
// Offset
|
|
|
|
uint8_t offset = LANP_LAN_LN_CNTL_PT_RSP_MIN_LEN;
|
|
|
|
|
|
|
|
// Control Point value has been received
|
|
|
|
struct lanc_ln_ctnl_pt_rsp *ind = KE_MSG_ALLOC_DYN(
|
|
|
|
LANC_LN_CTNL_PT_RSP, dest, src, lanc_ln_ctnl_pt_rsp, param->length);
|
|
|
|
// Requested operation code
|
|
|
|
ind->rsp.req_op_code = param->value[1];
|
|
|
|
// Response value
|
|
|
|
ind->rsp.resp_value = param->value[2];
|
|
|
|
|
|
|
|
if ((ind->rsp.resp_value == LANP_LN_CTNL_PT_RESP_SUCCESS) &&
|
|
|
|
(param->length >= 3)) {
|
|
|
|
switch (ind->rsp.req_op_code) {
|
|
|
|
case (LANP_LN_CTNL_PT_REQ_NUMBER_OF_ROUTES): {
|
|
|
|
ind->rsp.value.number_of_routes = co_read16p(¶m->value[offset]);
|
|
|
|
offset += 2;
|
|
|
|
|
|
|
|
} break;
|
|
|
|
|
|
|
|
case (LANP_LN_CTNL_PT_REQ_NAME_OF_ROUTE): {
|
|
|
|
// Get the length of the route
|
|
|
|
ind->rsp.value.route.length = (param->length - 3);
|
|
|
|
for (int i = 0; i < ind->rsp.value.route.length; i++) {
|
|
|
|
ind->rsp.value.route.name[i] = param->value[i + 3];
|
|
|
|
offset++;
|
|
|
|
}
|
|
|
|
} break;
|
|
|
|
|
|
|
|
case (LANP_LN_CTNL_PT_SET_CUMUL_VALUE):
|
|
|
|
case (LANP_LN_CTNL_PT_MASK_LSPEED_CHAR_CT):
|
|
|
|
case (LANP_LN_CTNL_PT_NAVIGATION_CONTROL):
|
|
|
|
case (LANP_LN_CTNL_PT_SELECT_ROUTE):
|
|
|
|
case (LANP_LN_CTNL_PT_SET_FIX_RATE):
|
|
|
|
case (LANP_LN_CTNL_PT_SET_ELEVATION): {
|
|
|
|
// No parameters
|
|
|
|
} break;
|
|
|
|
|
|
|
|
default: {
|
|
|
|
|
|
|
|
} break;
|
2022-08-15 04:20:27 -05:00
|
|
|
}
|
2023-02-01 14:52:54 -06:00
|
|
|
}
|
2022-08-15 04:20:27 -05:00
|
|
|
|
2023-02-01 14:52:54 -06:00
|
|
|
// Send the message
|
|
|
|
ke_msg_send(ind);
|
2022-08-15 04:20:27 -05:00
|
|
|
|
2023-02-01 14:52:54 -06:00
|
|
|
return offset;
|
2022-08-15 04:20:27 -05:00
|
|
|
}
|
|
|
|
#endif //(BLE_LN_COLLECTOR)
|
|
|
|
|
|
|
|
/// @} LAN
|