pinebuds/services/ble_profiles/hogp/hogpd/src/hogpd_task.c

785 lines
29 KiB
C

/**
****************************************************************************************
* @addtogroup HOGPDTASK
* @{
****************************************************************************************
*/
/*
* INCLUDE FILES
****************************************************************************************
*/
#include "rwip_config.h"
#if (BLE_HID_DEVICE)
#include "gap.h"
#include "gattc_task.h"
//HID Over GATT Profile Device Role Functions
#include "hogpd.h"
#include "hogpd_task.h"
#include "prf_utils.h"
#include "co_utils.h"
/*
* DEFINES
****************************************************************************************
*/
/*
* GLOBAL VARIABLE DEFINITIONS
****************************************************************************************
*/
/**
****************************************************************************************
* @brief Handles reception of the @ref HOGPD_ENABLE_REQ message.
* The handler enables the HID Over GATT Profile Device Role.
* @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 hogpd_enable_req_handler(ke_msg_id_t const msgid,
struct hogpd_enable_req const *param,
ke_task_id_t const dest_id,
ke_task_id_t const src_id)
{
// Counter for HIDS instance
uint8_t svc_idx;
uint8_t status = GAP_ERR_NO_ERROR;
struct hogpd_env_tag* hogpd_env = PRF_ENV_GET(HOGPD, hogpd);
ASSERT_ERR(hogpd_env!=NULL);
// Check provided values and check if connection exists
if((param->conidx > BLE_CONNECTION_MAX)
|| (gapc_get_conhdl(param->conidx) == GAP_INVALID_CONHDL))
{
// an error occurs, trigg it.
status = (param->conidx > BLE_CONNECTION_MAX) ? GAP_ERR_INVALID_PARAM : PRF_ERR_REQ_DISALLOWED;
}
else
{
for (svc_idx = 0; svc_idx < hogpd_env->hids_nb; svc_idx++)
{
// Retrieve notification configuration
hogpd_env->svcs[svc_idx].ntf_cfg[param->conidx] = param->ntf_cfg[svc_idx];
}
}
// Send back response
struct hogpd_enable_rsp* rsp = KE_MSG_ALLOC(HOGPD_ENABLE_RSP, src_id, dest_id, hogpd_enable_rsp);
rsp->conidx = param->conidx;
rsp->status = status;
ke_msg_send(rsp);
return (KE_MSG_CONSUMED);
}
/**
****************************************************************************************
* @brief Handles reception of the @ref HOGPD_REPORT_UPD_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.
****************************************************************************************
*/
__STATIC int hogpd_report_upd_req_handler(ke_msg_id_t const msgid,
struct hogpd_report_upd_req const *param,
ke_task_id_t const dest_id,
ke_task_id_t const src_id)
{
int msg_status = KE_MSG_CONSUMED;
uint8_t state = ke_state_get(dest_id);
// check that task is in idle state
if((state & HOGPD_REQ_BUSY) == HOGPD_IDLE)
{
// Status
uint8_t status = PRF_ERR_INVALID_PARAM;
// Check provided values and check if connection exists
if((param->conidx > BLE_CONNECTION_MAX)
|| (gapc_get_conhdl(param->conidx) == GAP_INVALID_CONHDL))
{
status = (param->conidx > BLE_CONNECTION_MAX) ? GAP_ERR_INVALID_PARAM : PRF_ERR_REQ_DISALLOWED;
}
else
{
status = hogpd_ntf_send(param->conidx, &(param->report));
}
// an error occurs inform application
if (status != GAP_ERR_NO_ERROR)
{
// send report update response
struct hogpd_report_upd_rsp *rsp = KE_MSG_ALLOC(HOGPD_REPORT_UPD_RSP,
src_id, dest_id, hogpd_report_upd_rsp);
rsp->conidx = param->conidx;
rsp->status = status;
ke_msg_send(rsp);
}
// go in a busy state
else
{
ke_state_set(dest_id, state | HOGPD_REQ_BUSY);
}
}
// else process it later
else
{
msg_status = KE_MSG_SAVED;
}
return (msg_status);
}
/**
****************************************************************************************
* @brief Handles reception of the @ref HOGPD_REPORT_CFM 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.
****************************************************************************************
*/
__STATIC int hogpd_report_cfm_handler(ke_msg_id_t const msgid,
struct hogpd_report_cfm const *param,
ke_task_id_t const dest_id,
ke_task_id_t const src_id)
{
uint8_t state = ke_state_get(dest_id);
// check that an operation is ongoing
if((state & HOGPD_OP_BUSY) == HOGPD_OP_BUSY)
{
uint16_t handle = ATT_INVALID_HANDLE;
uint8_t status = PRF_APP_ERROR;
struct hogpd_env_tag* hogpd_env = PRF_ENV_GET(HOGPD, hogpd);
// check received status
if(param->status != GAP_ERR_NO_ERROR)
{
status = param->status;
}
// perform operation sanity check
else if((param->operation == hogpd_env->op.operation) && (param->conidx == hogpd_env->op.conidx))
{
// retrieve attribute index.
uint8_t att_idx = 0;
switch(param->report.type)
{
case HOGPD_REPORT:
{
att_idx = HOGPD_IDX_REPORT_VAL;
}break;
case HOGPD_REPORT_MAP:
{
att_idx = HOGPD_IDX_REPORT_MAP_VAL;
}break;
case HOGPD_BOOT_KEYBOARD_INPUT_REPORT:
{
att_idx = HOGPD_IDX_BOOT_KB_IN_REPORT_VAL;
}break;
case HOGPD_BOOT_KEYBOARD_OUTPUT_REPORT:
{
att_idx = HOGPD_IDX_BOOT_KB_OUT_REPORT_VAL;
}break;
case HOGPD_BOOT_MOUSE_INPUT_REPORT:
{
att_idx = HOGPD_IDX_BOOT_MOUSE_IN_REPORT_VAL;
}break;
default: /* Nothing to do */ break;
}
// retrieve handle
handle = hogpd_get_att_handle(hogpd_env, param->report.hid_idx, att_idx, param->report.idx);
// check if answer correspond to expected one
if(handle == hogpd_env->op.handle)
{
status = GAP_ERR_NO_ERROR;
}
}
// read operation
if(hogpd_env->op.operation == HOGPD_OP_REPORT_READ)
{
uint16_t length = (status == GAP_ERR_NO_ERROR) ? param->report.length : 0;
//Send read response
struct gattc_read_cfm * rd_cfm = KE_MSG_ALLOC_DYN(GATTC_READ_CFM,
KE_BUILD_ID(TASK_GATTC, hogpd_env->op.conidx), dest_id, gattc_read_cfm, length);
rd_cfm->handle = hogpd_env->op.handle;
rd_cfm->status = status;
rd_cfm->length = length;
if(status == GAP_ERR_NO_ERROR)
{
memcpy(rd_cfm->value, param->report.value, length);
}
ke_msg_send(rd_cfm);
}
// write operation
else
{
//Send write response
struct gattc_write_cfm * wr_cfm = KE_MSG_ALLOC(GATTC_WRITE_CFM,
KE_BUILD_ID(TASK_GATTC, hogpd_env->op.conidx), dest_id, gattc_write_cfm);
wr_cfm->handle = hogpd_env->op.handle;
wr_cfm->status = status;
ke_msg_send(wr_cfm);
}
// cleanup environment
hogpd_env->op.operation = HOGPD_OP_NO;
hogpd_env->op.handle = ATT_INVALID_HDL;
hogpd_env->op.conidx = 0xFF;
// go back in idle state
ke_state_set(dest_id, state & ~HOGPD_OP_BUSY);
}
return (KE_MSG_CONSUMED);
}
/**
****************************************************************************************
* @brief Handles reception of the @ref HOGPD_PROTO_MODE_CFM 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.
****************************************************************************************
*/
__STATIC int hogpd_proto_mode_cfm_handler(ke_msg_id_t const msgid,
struct hogpd_proto_mode_cfm const *param,
ke_task_id_t const dest_id,
ke_task_id_t const src_id)
{
uint8_t state = ke_state_get(dest_id);
// check that an operation is ongoing
if((state & HOGPD_OP_BUSY) == HOGPD_OP_BUSY)
{
uint16_t handle = ATT_INVALID_HANDLE;
uint8_t status = PRF_APP_ERROR;
struct hogpd_env_tag* hogpd_env = PRF_ENV_GET(HOGPD, hogpd);
// check received status
if(param->status != GAP_ERR_NO_ERROR)
{
status = param->status;
}
// perform operation sanity check
else if((hogpd_env->op.operation == HOGPD_OP_PROT_UPDATE) && (param->conidx == hogpd_env->op.conidx))
{
// retrieve handle
handle = hogpd_get_att_handle(hogpd_env, param->hid_idx, HOGPD_IDX_PROTO_MODE_VAL, 0);
// check if answer correspond to expected one
if(handle == hogpd_env->op.handle)
{
status = GAP_ERR_NO_ERROR;
hogpd_env->svcs[param->hid_idx].proto_mode = param->proto_mode;
}
}
// read operation/something failed
if(hogpd_env->op.operation == HOGPD_OP_REPORT_READ)
{
//Send read response
struct gattc_read_cfm * rd_cfm = KE_MSG_ALLOC(GATTC_READ_CFM,
KE_BUILD_ID(TASK_GATTC, hogpd_env->op.conidx), dest_id, gattc_read_cfm);
rd_cfm->handle = hogpd_env->op.handle;
rd_cfm->status = status;
ke_msg_send(rd_cfm);
}
// write operation
else
{
//Send write response
struct gattc_write_cfm * wr_cfm = KE_MSG_ALLOC(GATTC_WRITE_CFM,
KE_BUILD_ID(TASK_GATTC, hogpd_env->op.conidx), dest_id, gattc_write_cfm);
wr_cfm->handle = hogpd_env->op.handle;
wr_cfm->status = status;
ke_msg_send(wr_cfm);
}
// cleanup environment
hogpd_env->op.operation = HOGPD_OP_NO;
hogpd_env->op.handle = ATT_INVALID_HDL;
hogpd_env->op.conidx = 0xFF;
// go back in idle state
ke_state_set(dest_id, state & ~HOGPD_OP_BUSY);
}
return (KE_MSG_CONSUMED);
}
/**
****************************************************************************************
* @brief Handles reception of the @ref GATTC_ATT_INFO_REQ_IND 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.
****************************************************************************************
*/
__STATIC int gattc_att_info_req_ind_handler(ke_msg_id_t const msgid,
struct gattc_att_info_req_ind const *param,
ke_task_id_t const dest_id,
ke_task_id_t const src_id)
{
uint8_t hid_idx, att_idx, report_idx;
struct gattc_att_info_cfm * cfm;
struct hogpd_env_tag* hogpd_env = PRF_ENV_GET(HOGPD, hogpd);
// retrieve attribute requested
uint8_t status = hogpd_get_att_idx(hogpd_env, param->handle, &hid_idx, &att_idx, &report_idx);
//Send write response
cfm = KE_MSG_ALLOC(GATTC_ATT_INFO_CFM, src_id, dest_id, gattc_att_info_cfm);
cfm->handle = param->handle;
if(status == GAP_ERR_NO_ERROR)
{
// check which attribute is requested by peer device
switch(att_idx)
{
case HOGPD_IDX_BOOT_KB_IN_REPORT_VAL:
case HOGPD_IDX_BOOT_KB_OUT_REPORT_VAL:
case HOGPD_IDX_BOOT_MOUSE_IN_REPORT_VAL:
case HOGPD_IDX_REPORT_VAL:
{
cfm->length = 0;
}break;
// Notification configuration
case HOGPD_IDX_BOOT_KB_IN_REPORT_NTF_CFG:
case HOGPD_IDX_BOOT_MOUSE_IN_REPORT_NTF_CFG:
case HOGPD_IDX_REPORT_NTF_CFG:
{
cfm->length = 2;
}break;
default:
{
cfm->length = 0;
status = ATT_ERR_WRITE_NOT_PERMITTED;
} break;
}
}
cfm->status = status;
ke_msg_send(cfm);
return (KE_MSG_CONSUMED);
}
/**
****************************************************************************************
* @brief Handles reception of the @ref GATTC_WRITE_REQ_IND 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.
****************************************************************************************
*/
__STATIC int gattc_write_req_ind_handler(ke_msg_id_t const msgid,
struct gattc_write_req_ind const *param,
ke_task_id_t const dest_id,
ke_task_id_t const src_id)
{
int msg_status = KE_MSG_CONSUMED;
uint8_t state = ke_state_get(dest_id);
// check that task is in idle state
if((state & HOGPD_OP_BUSY) == HOGPD_IDLE)
{
uint8_t hid_idx, att_idx, report_idx;
// used to know if gatt_write confirmation should be sent immediately
uint8_t conidx = KE_IDX_GET(src_id);
struct hogpd_env_tag* hogpd_env = PRF_ENV_GET(HOGPD, hogpd);
// retrieve attribute requested
uint8_t status = hogpd_get_att_idx(hogpd_env, param->handle, &hid_idx, &att_idx, &report_idx);
// prepare operation info
hogpd_env->op.conidx = conidx;
hogpd_env->op.operation = HOGPD_OP_NO;
hogpd_env->op.handle = param->handle;
if(status == GAP_ERR_NO_ERROR)
{
// check which attribute is requested by peer device
switch(att_idx)
{
// Control point value updated
case HOGPD_IDX_HID_CTNL_PT_VAL:
{
// send control point indication
struct hogpd_ctnl_pt_ind *cp_ind = KE_MSG_ALLOC(HOGPD_CTNL_PT_IND,
prf_dst_task_get(&(hogpd_env->prf_env), conidx), dest_id,
hogpd_ctnl_pt_ind);
cp_ind->conidx = conidx;
cp_ind->hid_idx = hid_idx;
cp_ind->hid_ctnl_pt = param->value[0];
ke_msg_send(cp_ind);
}break;
// Modification of protocol mode requested
case HOGPD_IDX_PROTO_MODE_VAL:
{
// send control point indication
struct hogpd_proto_mode_req_ind *prot_ind = KE_MSG_ALLOC(HOGPD_PROTO_MODE_REQ_IND,
prf_dst_task_get(&(hogpd_env->prf_env), conidx), dest_id,
hogpd_proto_mode_req_ind);
prot_ind->conidx = conidx;
prot_ind->operation = HOGPD_OP_PROT_UPDATE;
prot_ind->hid_idx = hid_idx;
prot_ind->proto_mode = param->value[0];
ke_msg_send(prot_ind);
hogpd_env->op.operation = HOGPD_OP_PROT_UPDATE;
}break;
// Modification of report value requested
case HOGPD_IDX_BOOT_KB_IN_REPORT_VAL:
case HOGPD_IDX_BOOT_KB_OUT_REPORT_VAL:
case HOGPD_IDX_BOOT_MOUSE_IN_REPORT_VAL:
case HOGPD_IDX_REPORT_VAL:
{
// send report indication
struct hogpd_report_req_ind *report_ind = KE_MSG_ALLOC_DYN(HOGPD_REPORT_REQ_IND,
prf_dst_task_get(&(hogpd_env->prf_env), conidx), dest_id,
hogpd_report_req_ind, param->length);
report_ind->conidx = conidx;
report_ind->operation = HOGPD_OP_REPORT_WRITE;
report_ind->report.length = param->length;
report_ind->report.hid_idx = hid_idx;
report_ind->report.idx = report_idx;
memcpy(report_ind->report.value, param->value, param->length);
// retrieve report type
switch(att_idx)
{
// An Input Report
case HOGPD_IDX_BOOT_KB_IN_REPORT_VAL:
{
report_ind->report.type = HOGPD_BOOT_KEYBOARD_INPUT_REPORT;
}break;
// Boot Keyboard input report
case HOGPD_IDX_BOOT_KB_OUT_REPORT_VAL:
{
report_ind->report.type = HOGPD_BOOT_KEYBOARD_OUTPUT_REPORT;
}break;
// Boot Mouse input report
case HOGPD_IDX_BOOT_MOUSE_IN_REPORT_VAL:
{
report_ind->report.type = HOGPD_BOOT_MOUSE_INPUT_REPORT;
}break;
// Normal report
case HOGPD_IDX_REPORT_VAL:
{
report_ind->report.type = HOGPD_REPORT;
}break;
default:
{
ASSERT_ERR(0);
}break;
}
ke_msg_send(report_ind);
hogpd_env->op.operation = HOGPD_OP_REPORT_WRITE;
}break;
// Notification configuration update
case HOGPD_IDX_BOOT_KB_IN_REPORT_NTF_CFG:
case HOGPD_IDX_BOOT_MOUSE_IN_REPORT_NTF_CFG:
case HOGPD_IDX_REPORT_NTF_CFG:
{
uint16_t ntf_cfg = co_read16p(param->value);
status = hogpd_ntf_cfg_ind_send(conidx, hid_idx, att_idx, report_idx, ntf_cfg);
}break;
default:
{
status = PRF_APP_ERROR;
} break;
}
}
// check if peer operation is over
if(hogpd_env->op.operation == HOGPD_OP_NO)
{
//Send write response
struct gattc_write_cfm * 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);
}
else
{
// go into operation busy state
ke_state_set(dest_id, state | HOGPD_OP_BUSY);
}
}
// else process it later
else
{
msg_status = KE_MSG_SAVED;
}
return (msg_status);
}
/**
****************************************************************************************
* @brief Handles reception of the @ref GATTC_READ_REQ_IND 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.
****************************************************************************************
*/
__STATIC int gattc_read_req_ind_handler(ke_msg_id_t const msgid,
struct gattc_read_req_ind const *param,
ke_task_id_t const dest_id,
ke_task_id_t const src_id)
{
int msg_status = KE_MSG_CONSUMED;
uint8_t state = ke_state_get(dest_id);
// check that task is in idle state
if((state & HOGPD_OP_BUSY) == HOGPD_IDLE)
{
uint8_t hid_idx, att_idx, report_idx;
bool finished = true;
uint8_t report_type = 0;
uint16_t value = 0;
uint16_t length = 0;
struct hogpd_env_tag* hogpd_env = PRF_ENV_GET(HOGPD, hogpd);
// used to know if gatt_write confirmation should be sent immediately
uint8_t conidx = KE_IDX_GET(src_id);
// retrieve attribute requested
uint8_t status = hogpd_get_att_idx(hogpd_env, param->handle, &hid_idx, &att_idx, &report_idx);
if(status == GAP_ERR_NO_ERROR)
{
// check which attribute is requested by peer device
switch(att_idx)
{
// ------------ READ report value requested
case HOGPD_IDX_BOOT_KB_IN_REPORT_VAL:
{
report_type = HOGPD_BOOT_KEYBOARD_INPUT_REPORT;
finished = false;
}break;
case HOGPD_IDX_BOOT_KB_OUT_REPORT_VAL:
{
report_type = HOGPD_BOOT_KEYBOARD_OUTPUT_REPORT;
finished = false;
}break;
case HOGPD_IDX_BOOT_MOUSE_IN_REPORT_VAL:
{
report_type = HOGPD_BOOT_MOUSE_INPUT_REPORT;
finished = false;
}break;
case HOGPD_IDX_REPORT_VAL:
{
report_type = HOGPD_REPORT;
finished = false;
}break;
case HOGPD_IDX_REPORT_MAP_VAL:
{
report_type = HOGPD_REPORT_MAP;
finished = false;
}break;
// ------------ READ active protocol mode
case HOGPD_IDX_PROTO_MODE_VAL:
{
value = hogpd_env->svcs[hid_idx].proto_mode;
length = sizeof(uint8_t);
}break;
// ------------ READ Notification configuration
case HOGPD_IDX_BOOT_KB_IN_REPORT_NTF_CFG:
{
value = ((hogpd_env->svcs[hid_idx].ntf_cfg[conidx] & HOGPD_CFG_KEYBOARD) != 0)
? PRF_CLI_START_NTF : PRF_CLI_STOP_NTFIND;
length = sizeof(uint16_t);
}break;
case HOGPD_IDX_BOOT_MOUSE_IN_REPORT_NTF_CFG:
{
value = ((hogpd_env->svcs[hid_idx].ntf_cfg[conidx] & HOGPD_CFG_MOUSE) != 0)
? PRF_CLI_START_NTF : PRF_CLI_STOP_NTFIND;
length = sizeof(uint16_t);
}break;
case HOGPD_IDX_REPORT_NTF_CFG:
{
value = ((hogpd_env->svcs[hid_idx].ntf_cfg[conidx] & (HOGPD_CFG_REPORT_NTF_EN << report_idx)) != 0)
? PRF_CLI_START_NTF : PRF_CLI_STOP_NTFIND;
length = sizeof(uint16_t);
}break;
default:
{
status = PRF_APP_ERROR;
} break;
}
}
// check if peer operation is over
if(finished)
{
//Send write response
struct gattc_read_cfm * cfm = KE_MSG_ALLOC_DYN(GATTC_READ_CFM, src_id, dest_id, gattc_read_cfm, length);
cfm->handle = param->handle;
cfm->status = status;
cfm->length = length;
memcpy(cfm->value, &value, length);
ke_msg_send(cfm);
}
else
{
// send report indication
struct hogpd_report_req_ind *report_ind = KE_MSG_ALLOC(HOGPD_REPORT_REQ_IND,
prf_dst_task_get(&(hogpd_env->prf_env), conidx), dest_id,
hogpd_report_req_ind);
report_ind->conidx = conidx;
report_ind->operation = HOGPD_OP_REPORT_READ;
report_ind->report.length = 0;
report_ind->report.hid_idx = hid_idx;
report_ind->report.type = report_type;
report_ind->report.idx = report_idx;
ke_msg_send(report_ind);
hogpd_env->op.conidx = conidx;
hogpd_env->op.operation = HOGPD_OP_REPORT_READ;
hogpd_env->op.handle = param->handle;
// go into operation busy state
ke_state_set(dest_id, state | HOGPD_OP_BUSY);
}
}
// else process it later
else
{
msg_status = KE_MSG_SAVED;
}
return (msg_status);
}
/**
****************************************************************************************
* @brief Handles @ref GATT_NOTIFY_CMP_EVT message meaning that Report notification
* has been correctly sent to peer device (but not confirmed by peer device).
*
* @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.
****************************************************************************************
*/
__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)
{
if(param->operation == GATTC_NOTIFY)
{
uint8_t conidx = KE_IDX_GET(src_id);
struct hogpd_env_tag* hogpd_env = PRF_ENV_GET(HOGPD, hogpd);
// send report update response
struct hogpd_report_upd_rsp *rsp = KE_MSG_ALLOC(HOGPD_REPORT_UPD_RSP,
prf_dst_task_get(&(hogpd_env->prf_env), conidx),
dest_id, hogpd_report_upd_rsp);
rsp->conidx = conidx;
rsp->status = param->status;
ke_msg_send(rsp);
// go back in to idle mode
ke_state_set(dest_id, ke_state_get(dest_id) & ~HOGPD_REQ_BUSY);
} // else ignore the message
return (KE_MSG_CONSUMED);
}
/*
* GLOBAL VARIABLE DEFINITIONS
****************************************************************************************
*/
/// Default State handlers definition
KE_MSG_HANDLER_TAB(hogpd)
{
{ HOGPD_ENABLE_REQ, (ke_msg_func_t) hogpd_enable_req_handler },
{ HOGPD_REPORT_UPD_REQ, (ke_msg_func_t) hogpd_report_upd_req_handler },
{ HOGPD_REPORT_CFM, (ke_msg_func_t) hogpd_report_cfm_handler },
{ HOGPD_PROTO_MODE_CFM, (ke_msg_func_t) hogpd_proto_mode_cfm_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 },
{ GATTC_CMP_EVT, (ke_msg_func_t) gattc_cmp_evt_handler },
};
void hogpd_task_init(struct ke_task_desc *task_desc)
{
// Get the address of the environment
struct hogpd_env_tag *hogpd_env = PRF_ENV_GET(HOGPD, hogpd);
task_desc->msg_handler_tab = hogpd_msg_handler_tab;
task_desc->msg_cnt = ARRAY_LEN(hogpd_msg_handler_tab);
task_desc->state = hogpd_env->state;
task_desc->idx_max = HOGPD_IDX_MAX;
}
#endif /* #if (BLE_HID_DEVICE) */
/// @} HOGPDTASK