/** **************************************************************************************** * @brief Handles @ref GATT_NOTIFY_CMP_EVT message meaning that Measurement notification * has been correctly sent to peer device (but not confirmed by peer device). * * Convey this information to appli task using @ref GLPS_MEAS_SEND_CFM * * @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 gatt_notify_cmp_evt_handler(ke_msg_id_t const msgid, struct gatt_notify_cmp_evt const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { /* send message indication if an error occurs, * or if all notification complete event has been received */ if((param->status != PRF_ERR_OK) || (!(GLPS_IS(MEAS_CTX_SENT))) || (GLPS_IS(MEAS_CTX_SENT) && (param->handle == GLPS_HANDLE(GLS_IDX_MEAS_CTX_VAL)))) { GLPS_CLEAR(SENDING_MEAS); // send completed information to APP task struct glps_req_cmp_evt * cmp_evt = KE_MSG_ALLOC(GLPS_REQ_CMP_EVT, glps_env.con_info.appid, TASK_GLPS, glps_req_cmp_evt); cmp_evt->conhdl = glps_env.con_info.conhdl; cmp_evt->request = GLPS_SEND_MEAS_REQ_NTF_CMP; cmp_evt->status = param->status; ke_msg_send(cmp_evt); } return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @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 * * * @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) { switch(param->req_type) { case GATTC_NOTIFY: { /* send message indication if an error occurs, * or if all notification complete event has been received */ if((param->status != PRF_ERR_OK) || (!(GLPS_IS(MEAS_CTX_SENT))) || (GLPS_IS(MEAS_CTX_SENT) && (GLPS_IS(MEAS_SENT)))) { GLPS_CLEAR(SENDING_MEAS); // send completed information to APP task struct glps_req_cmp_evt * cmp_evt = KE_MSG_ALLOC(GLPS_REQ_CMP_EVT, glps_env.con_info.appid, TASK_GLPS, glps_req_cmp_evt); cmp_evt->conhdl = gapc_get_conhdl(glps_env.con_info.conidx); 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(MEAS_SENT); } } break; case GATTC_INDICATE: { // verify if indication should be conveyed to application task if(glps_env.racp_ind_src == glps_env.con_info.appid) { // send completed information to APP task struct glps_req_cmp_evt * cmp_evt = KE_MSG_ALLOC(GLPS_REQ_CMP_EVT, glps_env.con_info.appid, TASK_GLPS, glps_req_cmp_evt); cmp_evt->conhdl = gapc_get_conhdl(glps_env.con_info.conidx); cmp_evt->request = GLPS_SEND_RACP_RSP_IND_CMP; cmp_evt->status = param->status; ke_msg_send(cmp_evt); } } break; default: break; } return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Handles reception of the @ref GLPS_RACP_RSP_REQ message. * Send by TASK_APP 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. **************************************************************************************** */ static int glps_racp_rsp_req_handler(ke_msg_id_t const msgid, struct glps_racp_rsp_req const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { struct glp_racp_rsp racp_rsp; // Status uint8_t status = PRF_ERR_OK; // check connection handle if(param->conhdl == glps_env.con_info.conhdl) { // 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(RACP_ON_GOING))) { //Cannot send response since no RACP on going status = PRF_ERR_REQ_DISALLOWED; } else { // 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; } // There is no more RACP on going GLPS_CLEAR(RACP_ON_GOING); // send RACP indication glps_send_racp_rsp(&(racp_rsp), glps_env.con_info.appid); } } else { //Wrong Connection Handle status = PRF_ERR_INVALID_PARAM; } if (status != PRF_ERR_OK) { prf_server_error_ind_send((prf_env_struct *)&glps_env, status, GLPS_ERROR_IND, GLPS_RACP_RSP_REQ); } return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @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. **************************************************************************************** */ static int glps_meas_send_req_handler(ke_msg_id_t const msgid, struct glps_send_meas_with_ctx_req const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { uint8_t status = PRF_ERR_OK; if(param->conhdl == glps_env.con_info.conhdl) { // device already sending a measurement if(GLPS_IS(SENDING_MEAS)) { //Cannot send another measurement in parallel status = (PRF_ERR_REQ_DISALLOWED); } else { // inform that device is sending a measurement GLPS_SET(SENDING_MEAS); // check if context is supported if((msgid == GLPS_SEND_MEAS_WITH_CTX_REQ) && !(GLPS_IS(MEAS_CTX_SUPPORTED))) { // Context not supported status = (PRF_ERR_FEATURE_NOT_SUPPORTED); } // check if notifications enabled else if(((glps_env.evt_cfg & GLPS_MEAS_NTF_CFG) == 0) || (((glps_env.evt_cfg & GLPS_MEAS_CTX_NTF_CFG) == 0) && (msgid == GLPS_SEND_MEAS_WITH_CTX_REQ))) { // Not allowed to send measurement if Notifications not enabled. status = (PRF_ERR_NTF_DISABLED); } else { struct atts_elmt * att_elmt; struct gatt_notify_req * ntf = KE_MSG_ALLOC(GATT_NOTIFY_REQ, TASK_GATT, TASK_GLPS, gatt_notify_req); // retrieve value pointer in database att_elmt = attsdb_get_attribute(GLPS_HANDLE(GLS_IDX_MEAS_VAL)); // pack measured value in database att_elmt->length = glps_pack_meas_value(att_elmt->value, &(param->meas), param->seq_num); //Send notification through GATT ntf->conhdl = glps_env.con_info.conhdl; ntf->charhdl = GLPS_HANDLE(GLS_IDX_MEAS_VAL); ke_msg_send(ntf); if(msgid == GLPS_SEND_MEAS_WITH_CTX_REQ) { // 2 notification complete messages expected GLPS_SET(MEAS_CTX_SENT); // retrieve value pointer in database att_elmt = attsdb_get_attribute(GLPS_HANDLE(GLS_IDX_MEAS_CTX_VAL)); // pack measured value in database att_elmt->length = glps_pack_meas_ctx_value(att_elmt->value, &(param->ctx), param->seq_num); ntf = KE_MSG_ALLOC(GATT_NOTIFY_REQ, TASK_GATT, TASK_GLPS, gatt_notify_req); //Send notification through GATT ntf->conhdl = glps_env.con_info.conhdl; ntf->charhdl = GLPS_HANDLE(GLS_IDX_MEAS_CTX_VAL); ke_msg_send(ntf); } else { // 1 notification complete messages expected GLPS_CLEAR(MEAS_CTX_SENT); } } } } else { //Wrong Connection Handle status = (PRF_ERR_INVALID_PARAM); } // send command complete if an error occurs if(status != PRF_ERR_OK) { // allow to send other measurements GLPS_CLEAR(SENDING_MEAS); // send completed information to APP task that contains error status struct glps_req_cmp_evt * cmp_evt = KE_MSG_ALLOC(GLPS_REQ_CMP_EVT, glps_env.con_info.appid, TASK_GLPS, glps_req_cmp_evt); cmp_evt->conhdl = param->conhdl; cmp_evt->request = GLPS_SEND_MEAS_REQ_NTF_CMP; cmp_evt->status = status; ke_msg_send(cmp_evt); } return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Handles reception of the @ref GLPS_ENABLE_REQ message. * The handler enables the Glucose Sensor Profile and initialize readable values. * @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, struct glps_enable_req const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { uint8_t status = PRF_ERR_REQ_DISALLOWED; if(!GLPS_IS(ENABLE)) { // Check if the provided connection exist if (gap_get_rec_idx(param->conhdl) != GAP_INVALID_CONIDX) { status = PRF_ERR_OK; GLPS_SET(ENABLE); //Value used to initialize all readable value in DB uint16_t indntf_cfg = PRF_CLI_STOP_NTFIND; // Save the application task id glps_env.con_info.appid = src_id; // Save the connection handle associated to the profile glps_env.con_info.conhdl = param->conhdl; // No RACP at service start. GLPS_CLEAR(RACP_ON_GOING); GLPS_CLEAR(SENDING_MEAS); // Configure Glucose Measuremment IND Cfg in DB if(param->con_type == PRF_CON_NORMAL) { glps_env.evt_cfg = param->evt_cfg; } else { glps_env.evt_cfg = 0; } if((glps_env.evt_cfg & GLPS_MEAS_NTF_CFG) != 0) { indntf_cfg = PRF_CLI_START_NTF; } //Set Glucose measurement notification configuration attsdb_att_set_value(GLPS_HANDLE(GLS_IDX_MEAS_NTF_CFG), sizeof(uint16_t), (uint8_t *)&indntf_cfg); // Configure Intermediate Cuff Pressure NTF Cfg in DB //Configure Glucose measurement context notification if (GLPS_IS(MEAS_CTX_SUPPORTED)) { indntf_cfg = PRF_CLI_STOP_NTFIND; if((glps_env.evt_cfg & GLPS_MEAS_CTX_NTF_CFG) != 0) { indntf_cfg = PRF_CLI_START_NTF; } //Set Glucose measurement context notification configuration attsdb_att_set_value(GLPS_HANDLE(GLS_IDX_MEAS_CTX_NTF_CFG), sizeof(uint16_t), (uint8_t *)&indntf_cfg); } indntf_cfg = PRF_CLI_STOP_NTFIND; if((glps_env.evt_cfg & GLPS_RACP_IND_CFG) != 0) { indntf_cfg = PRF_CLI_START_IND; } //Set record access control point indication configuration attsdb_att_set_value(GLPS_HANDLE(GLS_IDX_REC_ACCESS_CTRL_IND_CFG), sizeof(uint16_t), (uint8_t *)&indntf_cfg); //Set Glucose sensor features attsdb_att_set_value(GLPS_HANDLE(GLS_IDX_FEATURE_VAL), sizeof(uint16_t), (uint8_t *)¶m->features); // Enable Service + Set Security Level attsdb_svc_set_permission(glps_env.shdl, param->sec_lvl); // Go to connected state ke_state_set(TASK_GLPS, GLPS_CONNECTED); } } // send completed information to APP task that contains error status struct glps_enable_cfm * cmp_evt = KE_MSG_ALLOC(GLPS_ENABLE_CFM, src_id, TASK_GLPS, glps_enable_cfm); cmp_evt->conhdl = param->conhdl; cmp_evt->status = status; ke_msg_send(cmp_evt); return (KE_MSG_CONSUMED); }