2022-08-15 04:20:27 -05:00
|
|
|
/**
|
|
|
|
****************************************************************************************
|
|
|
|
* @addtogroup GLPSTASK
|
|
|
|
* @{
|
|
|
|
****************************************************************************************
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* INCLUDE FILES
|
|
|
|
****************************************************************************************
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "rwip_config.h"
|
|
|
|
|
|
|
|
#if (BLE_GL_SENSOR)
|
|
|
|
|
|
|
|
#include "gap.h"
|
|
|
|
#include "gattc_task.h"
|
|
|
|
#include "glps.h"
|
|
|
|
#include "glps_task.h"
|
|
|
|
#include "prf_utils.h"
|
|
|
|
|
|
|
|
#include "co_utils.h"
|
2023-02-01 14:52:54 -06:00
|
|
|
#include "ke_mem.h"
|
2022-08-15 04:20:27 -05:00
|
|
|
|
|
|
|
/*
|
|
|
|
* GLUCOSE PROFILE ATTRIBUTES
|
|
|
|
****************************************************************************************
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* LOCAL FUNCTIONS DEFINITIONS
|
|
|
|
****************************************************************************************
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
****************************************************************************************
|
|
|
|
* @brief Handles reception of the @ref GLPS_ENABLE_REQ message.
|
2023-02-01 14:52:54 -06:00
|
|
|
* The handler enables the Glucose Sensor Profile and initialize readable
|
|
|
|
*values.
|
2022-08-15 04:20:27 -05:00
|
|
|
* @param[in] msgid Id of the message received (probably unused).off
|
|
|
|
* @param[in] param Pointer to the parameters of the message.
|
|
|
|
* @param[in] dest_id ID of the receiving task instance (probably unused).
|
|
|
|
* @param[in] src_id ID of the sending task instance.
|
|
|
|
* @return If the message was consumed or not.
|
|
|
|
****************************************************************************************
|
|
|
|
*/
|
|
|
|
__STATIC int glps_enable_req_handler(ke_msg_id_t const msgid,
|
2023-02-01 14:52:54 -06:00
|
|
|
struct glps_enable_req const *param,
|
|
|
|
ke_task_id_t const dest_id,
|
|
|
|
ke_task_id_t const src_id) {
|
|
|
|
uint8_t state = ke_state_get(dest_id);
|
|
|
|
uint8_t status = PRF_ERR_REQ_DISALLOWED;
|
|
|
|
struct glps_enable_rsp *cmp_evt;
|
|
|
|
|
|
|
|
if (state == GLPS_IDLE) {
|
|
|
|
uint8_t conidx = KE_IDX_GET(dest_id);
|
|
|
|
// Get the address of the environment
|
|
|
|
struct glps_env_tag *glps_env = PRF_ENV_GET(GLPS, glps);
|
|
|
|
if (!GLPS_IS(conidx, BOND_DATA_PRESENT)) {
|
|
|
|
GLPS_SET(conidx, BOND_DATA_PRESENT);
|
|
|
|
status = GAP_ERR_NO_ERROR;
|
|
|
|
glps_env->env[conidx]->evt_cfg = param->evt_cfg;
|
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 completed information to APP task that contains error status
|
|
|
|
cmp_evt = KE_MSG_ALLOC(GLPS_ENABLE_RSP, src_id, dest_id, glps_enable_rsp);
|
|
|
|
cmp_evt->status = status;
|
|
|
|
ke_msg_send(cmp_evt);
|
2022-08-15 04:20:27 -05:00
|
|
|
|
2023-02-01 14:52:54 -06:00
|
|
|
return (KE_MSG_CONSUMED);
|
2022-08-15 04:20:27 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
****************************************************************************************
|
|
|
|
* @brief Handles reception of the @ref GLPS_MEAS_SEND_REQ message.
|
|
|
|
* @param[in] msgid Id of the message received (probably unused).
|
|
|
|
* @param[in] param Pointer to the parameters of the message.
|
|
|
|
* @param[in] dest_id ID of the receiving task instance (probably unused).
|
|
|
|
* @param[in] src_id ID of the sending task instance.
|
|
|
|
* @return If the message was consumed or not.
|
|
|
|
****************************************************************************************
|
|
|
|
*/
|
2023-02-01 14:52:54 -06:00
|
|
|
__STATIC int glps_meas_send_req_handler(
|
|
|
|
ke_msg_id_t const msgid, struct glps_send_meas_with_ctx_cmd const *param,
|
|
|
|
ke_task_id_t const dest_id, ke_task_id_t const src_id) {
|
|
|
|
uint8_t conidx = KE_IDX_GET(dest_id);
|
|
|
|
uint8_t state = ke_state_get(dest_id);
|
|
|
|
uint8_t status = PRF_ERR_REQ_DISALLOWED;
|
|
|
|
|
|
|
|
if (state == GLPS_IDLE) {
|
|
|
|
// Get the address of the environment
|
|
|
|
struct glps_env_tag *glps_env = PRF_ENV_GET(GLPS, glps);
|
|
|
|
|
|
|
|
// Cannot send another measurement in parallel
|
|
|
|
if (!GLPS_IS(conidx, SENDING_MEAS)) {
|
|
|
|
// inform that device is sending a measurement
|
|
|
|
GLPS_SET(conidx, SENDING_MEAS);
|
|
|
|
|
|
|
|
// check if context is supported
|
|
|
|
if ((msgid == GLPS_SEND_MEAS_WITH_CTX_CMD) &&
|
|
|
|
!(glps_env->meas_ctx_supported)) {
|
|
|
|
// Context not supported
|
|
|
|
status = (PRF_ERR_FEATURE_NOT_SUPPORTED);
|
|
|
|
}
|
|
|
|
// check if notifications enabled
|
|
|
|
else if (((glps_env->env[conidx]->evt_cfg & GLPS_MEAS_NTF_CFG) == 0) ||
|
|
|
|
(((glps_env->env[conidx]->evt_cfg & GLPS_MEAS_CTX_NTF_CFG) ==
|
|
|
|
0) &&
|
|
|
|
(msgid == GLPS_SEND_MEAS_WITH_CTX_CMD))) {
|
|
|
|
// Not allowed to send measurement if Notifications not enabled.
|
|
|
|
status = (PRF_ERR_NTF_DISABLED);
|
|
|
|
} else {
|
|
|
|
// Allocate the GATT notification message
|
|
|
|
struct gattc_send_evt_cmd *meas_val = KE_MSG_ALLOC_DYN(
|
|
|
|
GATTC_SEND_EVT_CMD, KE_BUILD_ID(TASK_GATTC, conidx), dest_id,
|
|
|
|
gattc_send_evt_cmd, GLP_MEAS_MAX_LEN);
|
|
|
|
|
|
|
|
// Fill in the parameter structure
|
|
|
|
meas_val->operation = GATTC_NOTIFY;
|
|
|
|
meas_val->handle = GLPS_HANDLE(GLS_IDX_MEAS_VAL);
|
|
|
|
// pack measured value in database
|
|
|
|
meas_val->length = glps_pack_meas_value(meas_val->value, &(param->meas),
|
|
|
|
param->seq_num);
|
|
|
|
|
|
|
|
// Measurement value notification not yet sent
|
|
|
|
GLPS_CLEAR(conidx, MEAS_SENT);
|
|
|
|
|
|
|
|
// Send the event
|
|
|
|
ke_msg_send(meas_val);
|
|
|
|
|
|
|
|
if (msgid == GLPS_SEND_MEAS_WITH_CTX_CMD) {
|
|
|
|
// Allocate the GATT notification message
|
|
|
|
struct gattc_send_evt_cmd *meas_ctx_val = KE_MSG_ALLOC_DYN(
|
|
|
|
GATTC_SEND_EVT_CMD, KE_BUILD_ID(TASK_GATTC, conidx), dest_id,
|
|
|
|
gattc_send_evt_cmd, GLP_MEAS_CTX_MAX_LEN);
|
|
|
|
|
|
|
|
// Fill in the parameter structure
|
|
|
|
meas_ctx_val->operation = GATTC_NOTIFY;
|
|
|
|
meas_ctx_val->handle = GLPS_HANDLE(GLS_IDX_MEAS_CTX_VAL);
|
|
|
|
// pack measured value in database
|
|
|
|
meas_ctx_val->length = glps_pack_meas_ctx_value(
|
|
|
|
meas_ctx_val->value, &(param->ctx), param->seq_num);
|
|
|
|
|
|
|
|
// 2 notification complete messages expected
|
|
|
|
GLPS_SET(conidx, MEAS_CTX_SENT);
|
|
|
|
|
|
|
|
// Send the event
|
|
|
|
ke_msg_send(meas_ctx_val);
|
|
|
|
} else {
|
|
|
|
// 1 notification complete messages expected
|
|
|
|
GLPS_CLEAR(conidx, MEAS_CTX_SENT);
|
2022-08-15 04:20:27 -05:00
|
|
|
}
|
2023-02-01 14:52:54 -06:00
|
|
|
|
|
|
|
status = (GAP_ERR_NO_ERROR);
|
|
|
|
}
|
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 command complete if an error occurs
|
|
|
|
if (status != GAP_ERR_NO_ERROR) {
|
|
|
|
// send completed information to APP task that contains error status
|
|
|
|
struct glps_cmp_evt *cmp_evt =
|
|
|
|
KE_MSG_ALLOC(GLPS_CMP_EVT, src_id, dest_id, glps_cmp_evt);
|
2022-08-15 04:20:27 -05:00
|
|
|
|
2023-02-01 14:52:54 -06:00
|
|
|
cmp_evt->request = GLPS_SEND_MEAS_REQ_NTF_CMP;
|
|
|
|
cmp_evt->status = status;
|
2022-08-15 04:20:27 -05:00
|
|
|
|
2023-02-01 14:52:54 -06:00
|
|
|
ke_msg_send(cmp_evt);
|
|
|
|
}
|
2022-08-15 04:20:27 -05:00
|
|
|
|
2023-02-01 14:52:54 -06:00
|
|
|
return (KE_MSG_CONSUMED);
|
2022-08-15 04:20:27 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
****************************************************************************************
|
|
|
|
* @brief Handles reception of the @ref GLPS_SEND_RACP_RSP_CMD message.
|
|
|
|
* Send when a RACP requests is finished
|
|
|
|
*
|
|
|
|
* @param[in] msgid Id of the message received (probably unused).
|
|
|
|
* @param[in] param Pointer to the parameters of the message.
|
|
|
|
* @param[in] dest_id ID of the receiving task instance (probably unused).
|
|
|
|
* @param[in] src_id ID of the sending task instance.
|
|
|
|
* @return If the message was consumed or not.
|
|
|
|
****************************************************************************************
|
|
|
|
*/
|
2023-02-01 14:52:54 -06:00
|
|
|
__STATIC int glps_send_racp_rsp_cmd_handler(
|
|
|
|
ke_msg_id_t const msgid, struct glps_send_racp_rsp_cmd const *param,
|
|
|
|
ke_task_id_t const dest_id, ke_task_id_t const src_id) {
|
|
|
|
// Status
|
|
|
|
uint8_t status = PRF_ERR_REQ_DISALLOWED;
|
|
|
|
uint8_t conidx = KE_IDX_GET(dest_id);
|
|
|
|
uint8_t state = ke_state_get(dest_id);
|
|
|
|
|
|
|
|
if (state == GLPS_IDLE) {
|
|
|
|
// Get the address of the environment
|
|
|
|
struct glps_env_tag *glps_env = PRF_ENV_GET(GLPS, glps);
|
2022-08-15 04:20:27 -05:00
|
|
|
|
2023-02-01 14:52:54 -06:00
|
|
|
// check if op code valid
|
|
|
|
if ((param->op_code < GLP_REQ_REP_STRD_RECS) ||
|
|
|
|
(param->op_code > GLP_REQ_REP_NUM_OF_STRD_RECS)) {
|
|
|
|
// Wrong op code
|
|
|
|
status = PRF_ERR_INVALID_PARAM;
|
|
|
|
}
|
|
|
|
// check if RACP on going
|
|
|
|
else if ((param->op_code != GLP_REQ_ABORT_OP) &&
|
|
|
|
!(GLPS_IS(conidx, RACP_ON_GOING))) {
|
|
|
|
// Cannot send response since no RACP on going
|
|
|
|
status = PRF_ERR_REQ_DISALLOWED;
|
|
|
|
}
|
|
|
|
// Indication not enabled on peer device
|
|
|
|
else if ((glps_env->env[conidx]->evt_cfg & GLPS_RACP_IND_CFG) == 0) {
|
|
|
|
status = PRF_ERR_IND_DISABLED;
|
|
|
|
// There is no more RACP on going
|
|
|
|
GLPS_CLEAR(conidx, RACP_ON_GOING);
|
|
|
|
} else {
|
|
|
|
struct glp_racp_rsp racp_rsp;
|
|
|
|
// Allocate the GATT indication message
|
|
|
|
struct gattc_send_evt_cmd *racp_rsp_val = KE_MSG_ALLOC_DYN(
|
|
|
|
GATTC_SEND_EVT_CMD, KE_BUILD_ID(TASK_GATTC, conidx), dest_id,
|
|
|
|
gattc_send_evt_cmd, GLP_REC_ACCESS_CTRL_MAX_LEN);
|
|
|
|
|
|
|
|
// Fill in the parameter structure
|
|
|
|
racp_rsp_val->operation = GATTC_INDICATE;
|
|
|
|
racp_rsp_val->handle = GLPS_HANDLE(GLS_IDX_REC_ACCESS_CTRL_VAL);
|
|
|
|
|
|
|
|
// Number of stored record calculation succeed.
|
|
|
|
if ((param->op_code == GLP_REQ_REP_NUM_OF_STRD_RECS) &&
|
|
|
|
(param->status == GLP_RSP_SUCCESS)) {
|
|
|
|
racp_rsp.op_code = GLP_REQ_NUM_OF_STRD_RECS_RSP;
|
|
|
|
racp_rsp.operand.num_of_record = param->num_of_record;
|
|
|
|
}
|
|
|
|
// Send back status information
|
|
|
|
else {
|
|
|
|
racp_rsp.op_code = GLP_REQ_RSP_CODE;
|
|
|
|
racp_rsp.operand.rsp.op_code_req = param->op_code;
|
|
|
|
racp_rsp.operand.rsp.status = param->status;
|
|
|
|
}
|
|
|
|
|
|
|
|
// pack measured value in database
|
|
|
|
racp_rsp_val->length = glps_pack_racp_rsp(racp_rsp_val->value, &racp_rsp);
|
|
|
|
|
|
|
|
// There is no more RACP on going
|
|
|
|
GLPS_CLEAR(conidx, RACP_ON_GOING);
|
|
|
|
status = GAP_ERR_NO_ERROR;
|
|
|
|
|
|
|
|
// Store that response sent by application
|
|
|
|
GLPS_SET(conidx, RACP_RSP_SENT_BY_APP);
|
|
|
|
|
|
|
|
// send RACP Response indication
|
|
|
|
ke_msg_send(racp_rsp_val);
|
2022-08-15 04:20:27 -05:00
|
|
|
}
|
2023-02-01 14:52:54 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
if (status != GAP_ERR_NO_ERROR) {
|
|
|
|
// send completed information about request failed
|
|
|
|
struct glps_cmp_evt *cmp_evt =
|
|
|
|
KE_MSG_ALLOC(GLPS_CMP_EVT, src_id, dest_id, glps_cmp_evt);
|
|
|
|
cmp_evt->request = GLPS_SEND_RACP_RSP_IND_CMP;
|
|
|
|
cmp_evt->status = status;
|
|
|
|
ke_msg_send(cmp_evt);
|
|
|
|
}
|
|
|
|
return (KE_MSG_CONSUMED);
|
2022-08-15 04:20:27 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
****************************************************************************************
|
|
|
|
* @brief Handles reception of the attribute info request message.
|
|
|
|
*
|
|
|
|
* @param[in] msgid Id of the message received (probably unused).
|
|
|
|
* @param[in] param Pointer to the parameters of the message.
|
|
|
|
* @param[in] dest_id ID of the receiving task instance (probably unused).
|
|
|
|
* @param[in] src_id ID of the sending task instance.
|
|
|
|
* @return If the message was consumed or not.
|
|
|
|
****************************************************************************************
|
|
|
|
*/
|
2023-02-01 14:52:54 -06:00
|
|
|
__STATIC int gattc_att_info_req_ind_handler(
|
|
|
|
ke_msg_id_t const msgid, struct gattc_att_info_req_ind *param,
|
|
|
|
ke_task_id_t const dest_id, ke_task_id_t const src_id) {
|
|
|
|
uint8_t state = ke_state_get(dest_id);
|
2022-08-15 04:20:27 -05:00
|
|
|
|
2023-02-01 14:52:54 -06:00
|
|
|
if (state == GLPS_IDLE) {
|
|
|
|
struct glps_env_tag *glps_env = PRF_ENV_GET(GLPS, glps);
|
|
|
|
uint8_t att_idx = GLPS_IDX(param->handle);
|
|
|
|
struct gattc_att_info_cfm *cfm;
|
|
|
|
|
|
|
|
// Send write response
|
|
|
|
cfm = KE_MSG_ALLOC(GATTC_ATT_INFO_CFM, src_id, dest_id, gattc_att_info_cfm);
|
|
|
|
cfm->handle = param->handle;
|
|
|
|
|
|
|
|
// check if it's a client configuration char
|
|
|
|
if ((att_idx == GLS_IDX_MEAS_NTF_CFG) ||
|
|
|
|
(att_idx == GLS_IDX_MEAS_CTX_NTF_CFG) ||
|
|
|
|
(att_idx == GLS_IDX_REC_ACCESS_CTRL_IND_CFG)) {
|
|
|
|
// CCC attribute length = 2
|
|
|
|
cfm->length = 2;
|
|
|
|
cfm->status = GAP_ERR_NO_ERROR;
|
|
|
|
} else if (att_idx == GLS_IDX_REC_ACCESS_CTRL_VAL) {
|
|
|
|
// force length to zero to reject any write starting from something != 0
|
|
|
|
cfm->length = 0;
|
|
|
|
cfm->status = GAP_ERR_NO_ERROR;
|
|
|
|
}
|
|
|
|
// not expected request
|
|
|
|
else {
|
|
|
|
cfm->length = 0;
|
|
|
|
cfm->status = ATT_ERR_WRITE_NOT_PERMITTED;
|
|
|
|
}
|
|
|
|
ke_msg_send(cfm);
|
|
|
|
}
|
2022-08-15 04:20:27 -05:00
|
|
|
|
2023-02-01 14:52:54 -06:00
|
|
|
return (KE_MSG_CONSUMED);
|
2022-08-15 04:20:27 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
****************************************************************************************
|
|
|
|
* @brief Handles reception of the @ref GATT_CODE_ATT_WR_CMD_IND message.
|
2023-02-01 14:52:54 -06:00
|
|
|
* The handler compares the new values with current ones and notifies them if
|
|
|
|
*they changed.
|
2022-08-15 04:20:27 -05:00
|
|
|
* @param[in] msgid Id of the message received (probably unused).
|
|
|
|
* @param[in] param Pointer to the parameters of the message.
|
|
|
|
* @param[in] dest_id ID of the receiving task instance (probably unused).
|
|
|
|
* @param[in] src_id ID of the sending task instance.
|
|
|
|
* @return If the message was consumed or not.
|
|
|
|
****************************************************************************************
|
|
|
|
*/
|
|
|
|
__STATIC int gattc_write_req_ind_handler(ke_msg_id_t const msgid,
|
2023-02-01 14:52:54 -06:00
|
|
|
struct gattc_write_req_ind *param,
|
|
|
|
ke_task_id_t const dest_id,
|
|
|
|
ke_task_id_t const src_id) {
|
|
|
|
uint8_t state = ke_state_get(dest_id);
|
|
|
|
struct glp_racp_rsp racp_rsp;
|
|
|
|
racp_rsp.op_code = 0;
|
|
|
|
|
|
|
|
if (state == GLPS_IDLE) {
|
|
|
|
uint8_t status = GAP_ERR_NO_ERROR;
|
|
|
|
struct gattc_write_cfm *cfm;
|
|
|
|
uint8_t conidx = KE_IDX_GET(dest_id);
|
|
|
|
// Get the address of the environment
|
|
|
|
struct glps_env_tag *glps_env = PRF_ENV_GET(GLPS, glps);
|
|
|
|
uint8_t att_idx = GLPS_IDX(param->handle);
|
2022-08-15 04:20:27 -05:00
|
|
|
|
2023-02-01 14:52:54 -06:00
|
|
|
if (param->offset != 0) {
|
|
|
|
status = ATT_ERR_UNLIKELY_ERR;
|
|
|
|
}
|
|
|
|
// check if it's a client configuration char
|
|
|
|
else if ((att_idx == GLS_IDX_MEAS_NTF_CFG) ||
|
|
|
|
(att_idx == GLS_IDX_MEAS_CTX_NTF_CFG) ||
|
|
|
|
(att_idx == GLS_IDX_REC_ACCESS_CTRL_IND_CFG)) {
|
|
|
|
uint16_t cli_cfg;
|
|
|
|
uint8_t evt_mask = GLPS_IND_NTF_EVT(att_idx);
|
|
|
|
|
|
|
|
// get client configuration
|
|
|
|
cli_cfg = co_read16(&(param->value));
|
|
|
|
|
|
|
|
// stop indication/notification
|
|
|
|
if (cli_cfg == PRF_CLI_STOP_NTFIND) {
|
|
|
|
glps_env->env[conidx]->evt_cfg &= ~evt_mask;
|
|
|
|
}
|
|
|
|
// start indication/notification (check that char value accept it)
|
|
|
|
else if (((att_idx == GLS_IDX_REC_ACCESS_CTRL_IND_CFG) &&
|
|
|
|
(cli_cfg == PRF_CLI_START_IND)) ||
|
|
|
|
((att_idx != GLS_IDX_REC_ACCESS_CTRL_IND_CFG) &&
|
|
|
|
(cli_cfg == PRF_CLI_START_NTF))) {
|
|
|
|
glps_env->env[conidx]->evt_cfg |= evt_mask;
|
|
|
|
}
|
|
|
|
// improper value
|
|
|
|
else {
|
|
|
|
status = GLP_ERR_IMPROPER_CLI_CHAR_CFG;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (status == GAP_ERR_NO_ERROR) {
|
|
|
|
// Inform APP of configuration change
|
|
|
|
struct glps_cfg_indntf_ind *ind = KE_MSG_ALLOC(
|
|
|
|
GLPS_CFG_INDNTF_IND, prf_dst_task_get(&(glps_env->prf_env), conidx),
|
|
|
|
dest_id, glps_cfg_indntf_ind);
|
|
|
|
ind->evt_cfg = glps_env->env[conidx]->evt_cfg;
|
|
|
|
ke_msg_send(ind);
|
|
|
|
}
|
|
|
|
}
|
2022-08-15 04:20:27 -05:00
|
|
|
|
2023-02-01 14:52:54 -06:00
|
|
|
else if (att_idx == GLS_IDX_REC_ACCESS_CTRL_VAL) {
|
|
|
|
if ((glps_env->env[conidx]->evt_cfg & GLPS_RACP_IND_CFG) == 0) {
|
|
|
|
// do nothing since indication not enabled for this characteristic
|
|
|
|
status = GLP_ERR_IMPROPER_CLI_CHAR_CFG;
|
|
|
|
}
|
|
|
|
// If a request is on going
|
|
|
|
else if (GLPS_IS(conidx, RACP_ON_GOING)) {
|
|
|
|
// if it's an abort command, execute it.
|
|
|
|
if ((param->offset == 0) && (param->value[0] == GLP_REQ_ABORT_OP)) {
|
|
|
|
// forward abort operation to application
|
|
|
|
struct glps_racp_req_rcv_ind *req =
|
|
|
|
KE_MSG_ALLOC(GLPS_RACP_REQ_RCV_IND,
|
|
|
|
prf_dst_task_get(&(glps_env->prf_env), conidx),
|
|
|
|
dest_id, glps_racp_req_rcv_ind);
|
|
|
|
req->racp_req.op_code = GLP_REQ_ABORT_OP;
|
|
|
|
req->racp_req.filter.operator= 0;
|
|
|
|
ke_msg_send(req);
|
|
|
|
} else {
|
|
|
|
// do nothing since a procedure already in progress
|
|
|
|
status = GLP_ERR_PROC_ALREADY_IN_PROGRESS;
|
2022-08-15 04:20:27 -05:00
|
|
|
}
|
2023-02-01 14:52:54 -06:00
|
|
|
} else {
|
|
|
|
struct glp_racp_req racp_req;
|
|
|
|
// unpack record access control point value
|
|
|
|
uint8_t reqstatus =
|
|
|
|
glps_unpack_racp_req(param->value, param->length, &racp_req);
|
|
|
|
|
|
|
|
// check unpacked status
|
|
|
|
switch (reqstatus) {
|
|
|
|
case PRF_APP_ERROR: {
|
|
|
|
/* Request failed */
|
|
|
|
status = ATT_ERR_UNLIKELY_ERR;
|
|
|
|
} break;
|
|
|
|
case GAP_ERR_NO_ERROR: {
|
|
|
|
// check wich request shall be send to api task
|
|
|
|
switch (racp_req.op_code) {
|
|
|
|
case GLP_REQ_REP_STRD_RECS:
|
|
|
|
case GLP_REQ_DEL_STRD_RECS:
|
|
|
|
case GLP_REQ_REP_NUM_OF_STRD_RECS: {
|
|
|
|
// forward request operation to application
|
|
|
|
struct glps_racp_req_rcv_ind *req =
|
|
|
|
KE_MSG_ALLOC(GLPS_RACP_REQ_RCV_IND,
|
|
|
|
prf_dst_task_get(&(glps_env->prf_env), conidx),
|
|
|
|
dest_id, glps_racp_req_rcv_ind);
|
|
|
|
req->racp_req = racp_req;
|
|
|
|
// RACP on going.
|
|
|
|
GLPS_SET(conidx, RACP_ON_GOING);
|
|
|
|
ke_msg_send(req);
|
|
|
|
} break;
|
|
|
|
case GLP_REQ_ABORT_OP: {
|
|
|
|
// nothing to abort, send an error message.
|
|
|
|
racp_rsp.op_code = GLP_REQ_RSP_CODE;
|
|
|
|
racp_rsp.operand.rsp.op_code_req = racp_req.op_code;
|
|
|
|
racp_rsp.operand.rsp.status = GLP_RSP_ABORT_UNSUCCESSFUL;
|
|
|
|
} break;
|
|
|
|
default: {
|
|
|
|
// nothing to do since it's handled during unpack
|
|
|
|
} break;
|
|
|
|
}
|
|
|
|
} break;
|
|
|
|
default: {
|
|
|
|
/* There is an error in record access control request, inform peer
|
|
|
|
* device that request is incorrect. */
|
|
|
|
racp_rsp.op_code = GLP_REQ_RSP_CODE;
|
|
|
|
racp_rsp.operand.rsp.op_code_req = racp_req.op_code;
|
|
|
|
racp_rsp.operand.rsp.status = reqstatus;
|
|
|
|
} break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// not expected request
|
|
|
|
else {
|
|
|
|
status = ATT_ERR_WRITE_NOT_PERMITTED;
|
2022-08-15 04:20:27 -05:00
|
|
|
}
|
|
|
|
|
2023-02-01 14:52:54 -06:00
|
|
|
// Send write response
|
|
|
|
cfm = KE_MSG_ALLOC(GATTC_WRITE_CFM, src_id, dest_id, gattc_write_cfm);
|
|
|
|
cfm->handle = param->handle;
|
|
|
|
cfm->status = status;
|
|
|
|
ke_msg_send(cfm);
|
|
|
|
|
|
|
|
/* The racp response has to be sent - after write confirm */
|
|
|
|
if (racp_rsp.op_code != 0) {
|
|
|
|
// Allocate the GATT indication message
|
|
|
|
struct gattc_send_evt_cmd *racp_rsp_val = KE_MSG_ALLOC_DYN(
|
|
|
|
GATTC_SEND_EVT_CMD, KE_BUILD_ID(TASK_GATTC, conidx), dest_id,
|
|
|
|
gattc_send_evt_cmd, GLP_REC_ACCESS_CTRL_MAX_LEN);
|
|
|
|
|
|
|
|
racp_rsp_val->operation = GATTC_INDICATE;
|
|
|
|
racp_rsp_val->handle = param->handle;
|
|
|
|
// pack measured value in database
|
|
|
|
racp_rsp_val->length = glps_pack_racp_rsp(racp_rsp_val->value, &racp_rsp);
|
|
|
|
|
|
|
|
// Store that response internally sent by profile
|
|
|
|
GLPS_CLEAR(conidx, RACP_RSP_SENT_BY_APP);
|
|
|
|
|
|
|
|
// send RACP Response indication
|
|
|
|
ke_msg_send(racp_rsp_val);
|
|
|
|
}
|
|
|
|
}
|
2022-08-15 04:20:27 -05:00
|
|
|
|
2023-02-01 14:52:54 -06:00
|
|
|
return (KE_MSG_CONSUMED);
|
2022-08-15 04:20:27 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
****************************************************************************************
|
|
|
|
* @brief Handles reception of the read request from peer device
|
|
|
|
*
|
|
|
|
* @param[in] msgid Id of the message received (probably unused).
|
|
|
|
* @param[in] param Pointer to the parameters of the message.
|
|
|
|
* @param[in] dest_id ID of the receiving task instance (probably unused).
|
|
|
|
* @param[in] src_id ID of the sending task instance.
|
|
|
|
* @return If the message was consumed or not.
|
|
|
|
****************************************************************************************
|
|
|
|
*/
|
|
|
|
__STATIC int gattc_read_req_ind_handler(ke_msg_id_t const msgid,
|
2023-02-01 14:52:54 -06:00
|
|
|
struct gattc_read_req_ind const *param,
|
|
|
|
ke_task_id_t const dest_id,
|
|
|
|
ke_task_id_t const src_id) {
|
|
|
|
ke_state_t state = ke_state_get(dest_id);
|
|
|
|
|
|
|
|
if (state == GLPS_IDLE) {
|
|
|
|
// Send value to peer device.
|
|
|
|
struct gattc_read_cfm *cfm = KE_MSG_ALLOC_DYN(
|
|
|
|
GATTC_READ_CFM, src_id, dest_id, gattc_read_cfm, sizeof(uint16_t));
|
|
|
|
cfm->handle = param->handle;
|
|
|
|
cfm->status = ATT_ERR_NO_ERROR;
|
|
|
|
cfm->length = sizeof(uint16_t);
|
|
|
|
|
|
|
|
// Get the address of the environment
|
|
|
|
struct glps_env_tag *glps_env = PRF_ENV_GET(GLPS, glps);
|
|
|
|
uint8_t att_idx = GLPS_IDX(param->handle);
|
|
|
|
uint8_t conidx = KE_IDX_GET(dest_id);
|
2022-08-15 04:20:27 -05:00
|
|
|
|
2023-02-01 14:52:54 -06:00
|
|
|
switch (att_idx) {
|
|
|
|
case GLS_IDX_MEAS_NTF_CFG: {
|
|
|
|
co_write16p(cfm->value,
|
|
|
|
(glps_env->env[conidx]->evt_cfg & GLPS_MEAS_NTF_CFG)
|
|
|
|
? PRF_CLI_START_NTF
|
|
|
|
: PRF_CLI_STOP_NTFIND);
|
|
|
|
} break;
|
|
|
|
case GLS_IDX_MEAS_CTX_NTF_CFG: {
|
|
|
|
co_write16p(cfm->value,
|
|
|
|
(glps_env->env[conidx]->evt_cfg & GLPS_MEAS_CTX_NTF_CFG)
|
|
|
|
? PRF_CLI_START_NTF
|
|
|
|
: PRF_CLI_STOP_NTFIND);
|
|
|
|
} break;
|
|
|
|
case GLS_IDX_REC_ACCESS_CTRL_IND_CFG: {
|
|
|
|
co_write16p(cfm->value,
|
|
|
|
(glps_env->env[conidx]->evt_cfg & GLPS_RACP_IND_CFG)
|
|
|
|
? PRF_CLI_START_IND
|
|
|
|
: PRF_CLI_STOP_NTFIND);
|
|
|
|
} break;
|
|
|
|
case GLS_IDX_FEATURE_VAL: {
|
|
|
|
co_write16p(cfm->value, glps_env->features);
|
|
|
|
} break;
|
|
|
|
default: {
|
|
|
|
cfm->status = ATT_ERR_INSUFF_AUTHOR;
|
|
|
|
} break;
|
2022-08-15 04:20:27 -05:00
|
|
|
}
|
|
|
|
|
2023-02-01 14:52:54 -06:00
|
|
|
ke_msg_send(cfm);
|
|
|
|
}
|
2022-08-15 04:20:27 -05:00
|
|
|
|
2023-02-01 14:52:54 -06:00
|
|
|
return (KE_MSG_CONSUMED);
|
|
|
|
}
|
2022-08-15 04:20:27 -05:00
|
|
|
|
|
|
|
/**
|
|
|
|
****************************************************************************************
|
2023-02-01 14:52:54 -06:00
|
|
|
* @brief Handles @ref GATTC_CMP_EVT for GATTC_NOTIFY and GATT_INDICATE message
|
|
|
|
*meaning that Measurement notification/indication has been correctly sent to
|
|
|
|
*peer device
|
2022-08-15 04:20:27 -05:00
|
|
|
*
|
|
|
|
*
|
|
|
|
* @param[in] msgid Id of the message received.
|
|
|
|
* @param[in] param Pointer to the parameters of the message.
|
|
|
|
* @param[in] dest_id ID of the receiving task instance
|
|
|
|
* @param[in] src_id ID of the sending task instance.
|
|
|
|
* @return If the message was consumed or not.
|
|
|
|
****************************************************************************************
|
|
|
|
*/
|
2023-02-01 14:52:54 -06:00
|
|
|
__STATIC int gattc_cmp_evt_handler(ke_msg_id_t const msgid,
|
|
|
|
struct gattc_cmp_evt const *param,
|
|
|
|
ke_task_id_t const dest_id,
|
|
|
|
ke_task_id_t const src_id) {
|
|
|
|
uint8_t conidx = KE_IDX_GET(dest_id);
|
|
|
|
uint8_t state = ke_state_get(dest_id);
|
|
|
|
|
|
|
|
if (state == GLPS_IDLE) {
|
|
|
|
// Get the address of the environment
|
|
|
|
struct glps_env_tag *glps_env = PRF_ENV_GET(GLPS, glps);
|
|
|
|
|
|
|
|
switch (param->operation) {
|
|
|
|
case GATTC_NOTIFY: {
|
|
|
|
/* send message indication if an error occurs,
|
|
|
|
* or if all notification complete event has been received
|
|
|
|
*/
|
|
|
|
if ((param->status != GAP_ERR_NO_ERROR) ||
|
|
|
|
(!(GLPS_IS(conidx, MEAS_CTX_SENT))) ||
|
|
|
|
(GLPS_IS(conidx, MEAS_CTX_SENT) && (GLPS_IS(conidx, MEAS_SENT)))) {
|
|
|
|
GLPS_CLEAR(conidx, SENDING_MEAS);
|
|
|
|
|
|
|
|
// send completed information to APP task
|
|
|
|
struct glps_cmp_evt *cmp_evt = KE_MSG_ALLOC(
|
|
|
|
GLPS_CMP_EVT, prf_dst_task_get(&(glps_env->prf_env), conidx),
|
|
|
|
dest_id, glps_cmp_evt);
|
|
|
|
|
|
|
|
cmp_evt->request = GLPS_SEND_MEAS_REQ_NTF_CMP;
|
|
|
|
cmp_evt->status = param->status;
|
|
|
|
|
|
|
|
ke_msg_send(cmp_evt);
|
|
|
|
} else {
|
|
|
|
// Measurement value notification sent
|
|
|
|
GLPS_SET(conidx, MEAS_SENT);
|
|
|
|
}
|
|
|
|
} break;
|
|
|
|
case GATTC_INDICATE: {
|
|
|
|
// verify if indication should be conveyed to application task
|
|
|
|
if (GLPS_IS(conidx, RACP_RSP_SENT_BY_APP)) {
|
|
|
|
// send completed information to APP task
|
|
|
|
struct glps_cmp_evt *cmp_evt = KE_MSG_ALLOC(
|
|
|
|
GLPS_CMP_EVT, prf_dst_task_get(&(glps_env->prf_env), conidx),
|
|
|
|
dest_id, glps_cmp_evt);
|
|
|
|
|
|
|
|
cmp_evt->request = GLPS_SEND_RACP_RSP_IND_CMP;
|
|
|
|
cmp_evt->status = param->status;
|
|
|
|
|
|
|
|
ke_msg_send(cmp_evt);
|
|
|
|
}
|
|
|
|
|
|
|
|
GLPS_CLEAR(conidx, RACP_RSP_SENT_BY_APP);
|
|
|
|
} 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
|
|
|
return (KE_MSG_CONSUMED);
|
2022-08-15 04:20:27 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* GLOBAL VARIABLE DEFINITIONS
|
|
|
|
****************************************************************************************
|
|
|
|
*/
|
|
|
|
|
|
|
|
/// Default State handlers definition
|
2023-02-01 14:52:54 -06:00
|
|
|
KE_MSG_HANDLER_TAB(glps){
|
|
|
|
{GLPS_ENABLE_REQ, (ke_msg_func_t)glps_enable_req_handler},
|
|
|
|
{GATTC_ATT_INFO_REQ_IND, (ke_msg_func_t)gattc_att_info_req_ind_handler},
|
|
|
|
{GATTC_WRITE_REQ_IND, (ke_msg_func_t)gattc_write_req_ind_handler},
|
|
|
|
{GATTC_READ_REQ_IND, (ke_msg_func_t)gattc_read_req_ind_handler},
|
|
|
|
{GLPS_SEND_MEAS_WITH_CTX_CMD, (ke_msg_func_t)glps_meas_send_req_handler},
|
|
|
|
{GLPS_SEND_MEAS_WITHOUT_CTX_CMD, (ke_msg_func_t)glps_meas_send_req_handler},
|
|
|
|
{GLPS_SEND_RACP_RSP_CMD, (ke_msg_func_t)glps_send_racp_rsp_cmd_handler},
|
|
|
|
{GATTC_CMP_EVT, (ke_msg_func_t)gattc_cmp_evt_handler},
|
2022-08-15 04:20:27 -05:00
|
|
|
};
|
|
|
|
|
2023-02-01 14:52:54 -06:00
|
|
|
void glps_task_init(struct ke_task_desc *task_desc) {
|
|
|
|
// Get the address of the environment
|
|
|
|
struct glps_env_tag *glps_env = PRF_ENV_GET(GLPS, glps);
|
2022-08-15 04:20:27 -05:00
|
|
|
|
2023-02-01 14:52:54 -06:00
|
|
|
task_desc->msg_handler_tab = glps_msg_handler_tab;
|
|
|
|
task_desc->msg_cnt = ARRAY_LEN(glps_msg_handler_tab);
|
|
|
|
task_desc->state = glps_env->state;
|
|
|
|
task_desc->idx_max = GLPS_IDX_MAX;
|
2022-08-15 04:20:27 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#endif /* #if (BLE_GL_SENSOR) */
|
|
|
|
|
|
|
|
/// @} GLPSTASK
|