/** **************************************************************************************** * @brief Handles reception of the @ref BLPC_CFG_INDNTF_REQ message. * It allows configuration of the peer ind/ntf/stop characteristic for a specified characteristic. * Will return an error code if that cfg char does not exist. * @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 blpc_cfg_indntf_req_handler(ke_msg_id_t const msgid, struct blpc_cfg_indntf_req const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { uint16_t cfg_hdl = 0x0000; // Get the address of the environment struct blpc_env_tag *blpc_env = PRF_CLIENT_GET_ENV(dest_id, blpc); if(param->conhdl == gapc_get_conhdl(blpc_env->con_info.conidx)) { //get handle of the configuration characteristic to set and check if value matches property switch(param->char_code) { case BPS_BP_MEAS_CODE://can only IND cfg_hdl = blpc_env->bps.descs[BLPC_DESC_BP_MEAS_CLI_CFG].desc_hdl; if(!((param->cfg_val == PRF_CLI_STOP_NTFIND)|| (param->cfg_val == PRF_CLI_START_IND))) { blpc_error_ind_send(blpc_env, PRF_ERR_INVALID_PARAM); } break; case BPS_INTERM_CP_CODE://can only NTF cfg_hdl = blpc_env->bps.descs[BLPC_DESC_IC_MEAS_CLI_CFG].desc_hdl; if(!((param->cfg_val == PRF_CLI_STOP_NTFIND)|| (param->cfg_val == PRF_CLI_START_NTF))) { blpc_error_ind_send(blpc_env, PRF_ERR_INVALID_PARAM); } break; default: //let app know that one of the request params is incorrect blpc_error_ind_send(blpc_env, PRF_ERR_INVALID_PARAM); return (KE_MSG_CONSUMED); } //if we get here, then the APP request looks OK //check if the handle value exists if (cfg_hdl != ATT_INVALID_SEARCH_HANDLE) { // Send GATT Write Request prf_gatt_write_ntf_ind(&blpc_env->con_info, cfg_hdl, param->cfg_val); } else { blpc_error_ind_send(blpc_env, PRF_ERR_INEXISTENT_HDL); } } else { blpc_error_ind_send(blpc_env, PRF_ERR_INVALID_PARAM); } return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Handles reception of the @ref GLPC_REGISTER_REQ message. * When receiving this request, Glucose collector register to measurement notifications * and RACP indications. * * @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 glpc_register_req_handler(ke_msg_id_t const msgid, struct glpc_register_req const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { uint8_t status = PRF_ERR_OK; // Get the address of the environment struct glpc_env_tag *glpc_env = PRF_CLIENT_GET_ENV(dest_id, glpc); // check if collector enabled if(param->conhdl == gapc_get_conhdl(glpc_env->con_info.conidx)) { // check if client characteristics are present if ((glpc_env->gls.descs[GLPC_DESC_MEAS_CLI_CFG].desc_hdl == ATT_INVALID_HANDLE) || (glpc_env->gls.descs[GLPC_DESC_RACP_CLI_CFG].desc_hdl == ATT_INVALID_HANDLE) || ((param->meas_ctx_en) && (glpc_env->gls.descs[GLPC_DESC_MEAS_CTX_CLI_CFG].desc_hdl == ATT_INVALID_HANDLE))) { status = PRF_ERR_INEXISTENT_HDL; } } else { status = PRF_ERR_REQ_DISALLOWED; } if(status == PRF_ERR_OK) { // register to notification prf_gatt_write_ntf_ind(&(glpc_env->con_info), glpc_env->gls.descs[GLPC_DESC_MEAS_CLI_CFG].desc_hdl, PRF_CLI_START_NTF); glpc_env->last_uuid_req = GLPC_DESC_MEAS_CLI_CFG; // save if measurement context notification should be register in an unused variable glpc_env->last_char_code = param->meas_ctx_en; } // inform application that request cannot be performed else { struct glpc_register_cfm * cfm = KE_MSG_ALLOC(GLPC_REGISTER_CFM, glpc_env->con_info.appid, dest_id, glpc_register_cfm); // set error status cfm->conhdl = param->conhdl; cfm->status = status; ke_msg_send(cfm); } return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Handles reception of the @ref QPPC_CFG_INDNTF_REQ message. * It allows configuration of the peer ind/ntf/stop characteristic for a specified characteristic. * Will return an error code if that cfg char does not exist. * @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 qppc_cfg_indntf_req_handler(ke_msg_id_t const msgid, struct qppc_cfg_indntf_req const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { uint8_t status = PRF_ERR_OK; uint16_t cfg_hdl = 0x0000; // Get the address of the environment struct qppc_env_tag *qppc_env = PRF_CLIENT_GET_ENV(dest_id, qppc); do { if(param->conhdl != qppc_env->con_info.conhdl) { status = PRF_ERR_INVALID_PARAM; break; } if(!(param->char_code < qppc_env->nb_char)) { status = PRF_ERR_INVALID_PARAM; break; } if(!((param->cfg_val == PRF_CLI_STOP_NTFIND)|| (param->cfg_val == PRF_CLI_START_NTF))) { status = PRF_ERR_INVALID_PARAM; break; } //get handle of the configuration characteristic to set and check if value matches property cfg_hdl = qppc_env->qpps.descs[param->char_code].desc_hdl; if (cfg_hdl == ATT_INVALID_SEARCH_HANDLE) { status = PRF_ERR_INEXISTENT_HDL; break; } qppc_env->last_char_code = param->char_code; // Send GATT Write Request prf_gatt_write_ntf_ind(&qppc_env->con_info, cfg_hdl, param->cfg_val); } while(0); if (status != PRF_ERR_OK) { qppc_error_ind_send(qppc_env, status); } return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Handles reception of the @ref HOGPBH_CFG_INDNTF_REQ message. * It allows configuration of the peer ntf/stop characteristic for a specified characteristic. * Will return an error code if that cfg char does not exist. * @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 hogpbh_cfg_ntf_req_handler(ke_msg_id_t const msgid, struct hogpbh_cfg_ntf_req const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { // Descriptor handle uint16_t cfg_hdl; // Status uint8_t status = PRF_ERR_INVALID_PARAM; // Descriptor Code uint8_t desc_code = param->desc_code & ~HOGPBH_DESC_MASK; // Get the address of the environment struct hogpbh_env_tag *hogpbh_env = PRF_CLIENT_GET_ENV(dest_id, hogpbh); // Save the attribute read code hogpbh_env->last_char_code = param->desc_code; if((param->conhdl == hogpbh_env->con_info.conhdl) && (param->hids_nb < HOGPBH_NB_HIDS_INST_MAX) && (desc_code < HOGPBH_DESC_MAX)) { // Check value to write if((param->ntf_cfg == PRF_CLI_STOP_NTFIND) || (param->ntf_cfg == PRF_CLI_START_NTF)) { cfg_hdl = hogpbh_env->hids[param->hids_nb].descs[desc_code].desc_hdl; // Check if the handle value exists if (cfg_hdl != ATT_INVALID_SEARCH_HANDLE) { // Send GATT Write Request prf_gatt_write_ntf_ind(&hogpbh_env->con_info, cfg_hdl, param->ntf_cfg); status = PRF_ERR_OK; } else { status = PRF_ERR_INEXISTENT_HDL; } } } if (status != PRF_ERR_OK) { hogpbh_char_req_rsp_send(hogpbh_env, HOGPBH_WR_CHAR_RSP, status); } return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Handles reception of the @ref BASC_BATT_LEVEL_NTF_CFG_REQ message. * It allows configuration of the peer ntf/stop characteristic for Battery Level Characteristic. * Will return an error code if that cfg char does not exist. * @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 basc_batt_level_ntf_cfg_req_handler(ke_msg_id_t const msgid, struct basc_batt_level_ntf_cfg_req const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { // Descriptor handle uint16_t cfg_hdl; // Get the address of the environment struct basc_env_tag *basc_env = PRF_CLIENT_GET_ENV(dest_id, basc); if((param->conhdl == basc_env->con_info.conhdl) && (param->bas_nb < BASC_NB_BAS_INSTANCES_MAX)) { cfg_hdl = basc_env->bas[param->bas_nb].descs[BAS_DESC_BATT_LEVEL_CFG].desc_hdl; // Check value to write if(!((param->ntf_cfg == PRF_CLI_STOP_NTFIND) || (param->ntf_cfg == PRF_CLI_START_NTF))) { basc_error_ind_send(basc_env, PRF_ERR_INVALID_PARAM); } else { // Check if the handle value exists if (cfg_hdl != ATT_INVALID_SEARCH_HANDLE) { // Send GATT Write Request prf_gatt_write_ntf_ind(&basc_env->con_info, cfg_hdl, param->ntf_cfg); } else { basc_error_ind_send(basc_env, PRF_ERR_INEXISTENT_HDL); } } } else { basc_error_ind_send(basc_env, PRF_ERR_INVALID_PARAM); } return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Handles reception of the @ref TIPC_CT_NTF_CFG_REQ message. * It allows configuration of the peer ind/ntf/stop characteristic for a specified characteristic. * Will return an error code if that cfg char does not exist. * @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 tipc_ct_ntf_cfg_req_handler(ke_msg_id_t const msgid, struct tipc_ct_ntf_cfg_req const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { uint16_t cfg_hdl = 0x0000; // Get the address of the environment struct tipc_env_tag *tipc_env = PRF_CLIENT_GET_ENV(dest_id, tipc); if(param->conhdl == gapc_get_conhdl(tipc_env->con_info.conidx)) { cfg_hdl = tipc_env->cts.descs[TIPC_DESC_CTS_CURR_TIME_CLI_CFG].desc_hdl; //Only NTF if(!((param->cfg_val == PRF_CLI_STOP_NTFIND)||(param->cfg_val == PRF_CLI_START_NTF))) { tipc_error_ind_send(tipc_env, PRF_ERR_INVALID_PARAM); } else { //check if the handle value exists if (cfg_hdl != ATT_INVALID_SEARCH_HANDLE) { // Send GATT Write Request prf_gatt_write_ntf_ind(&tipc_env->con_info, cfg_hdl, param->cfg_val); } else { tipc_error_ind_send(tipc_env, PRF_ERR_INEXISTENT_HDL); } } } else { tipc_error_ind_send(tipc_env, PRF_ERR_INVALID_PARAM); } return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Handles reception of the @ref SCPPC_SCAN_REFRESH_NTF_CFG_REQ message. * It allows configuration of the peer ntf/stop characteristic for a specified characteristic. * Will return an error code if that cfg char does not exist. * @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 scppc_scan_refresh_ntf_cfg_req_handler(ke_msg_id_t const msgid, struct scppc_scan_refresh_ntf_cfg_req const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { uint16_t cfg_hdl = 0x0000; // Get the address of the environment struct scppc_env_tag *scppc_env = PRF_CLIENT_GET_ENV(dest_id, scppc); if(param->conhdl == gapc_get_conhdl(scppc_env->con_info.conidx)) { cfg_hdl = scppc_env->scps.descs[SCPPC_DESC_SCAN_REFRESH_CFG].desc_hdl; //check value to write if(!((param->ntf_cfg == PRF_CLI_STOP_NTFIND) || (param->ntf_cfg == PRF_CLI_START_NTF))) { scppc_error_ind_send(scppc_env, PRF_ERR_INVALID_PARAM); } else { //check if the handle value exists if (cfg_hdl != ATT_INVALID_SEARCH_HANDLE) { // Send GATT Write Request prf_gatt_write_ntf_ind(&scppc_env->con_info, cfg_hdl, param->ntf_cfg); } else { scppc_error_ind_send(scppc_env, PRF_ERR_INEXISTENT_HDL); } } } else { scppc_error_ind_send(scppc_env, PRF_ERR_INVALID_PARAM); } return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Handles reception of the @ref HRPC_CFG_INDNTF_REQ message. * It allows configuration of the peer ind/ntf/stop characteristic for a specified characteristic. * Will return an error code if that cfg char does not exist. * @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 hrpc_cfg_indntf_req_handler(ke_msg_id_t const msgid, struct hrpc_cfg_indntf_req const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { uint16_t cfg_hdl = 0x0000; // Get the address of the environment struct hrpc_env_tag *hrpc_env = PRF_CLIENT_GET_ENV(dest_id, hrpc); if(param->conhdl == hrpc_env->con_info.conhdl) { //get handle of the configuration characteristic to set and check if value matches property cfg_hdl = hrpc_env->hrs.descs[HRPC_DESC_HR_MEAS_CLI_CFG].desc_hdl; if(!((param->cfg_val == PRF_CLI_STOP_NTFIND)|| (param->cfg_val == PRF_CLI_START_NTF))) { hrpc_error_ind_send(hrpc_env, PRF_ERR_INVALID_PARAM); } //if we get here, then the APP request looks OK //check if the handle value exists if (cfg_hdl != ATT_INVALID_SEARCH_HANDLE) { // Send GATT Write Request prf_gatt_write_ntf_ind(&hrpc_env->con_info, cfg_hdl, param->cfg_val); } else { hrpc_error_ind_send(hrpc_env, PRF_ERR_INEXISTENT_HDL); } } else { hrpc_error_ind_send(hrpc_env, PRF_ERR_INVALID_PARAM); } return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Handles reception of the @ref HTPC_CFG_INDNTF_REQ message. * It allows configuration of the peer ind/ntf/stop characteristic for a specified characteristic. * Will return an error code if that cfg char does not exist. * @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 htpc_cfg_indntf_req_handler(ke_msg_id_t const msgid, struct htpc_cfg_indntf_req const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { // Client Characteristic Configuration Descriptor Handle uint16_t cfg_hdl = 0x0000; // Status uint8_t status = PRF_ERR_OK; // Get the address of the environment struct htpc_env_tag *htpc_env = PRF_CLIENT_GET_ENV(dest_id, htpc); if(param->conhdl == htpc_env->con_info.conhdl) { switch(param->char_code) { case HTPC_CHAR_HTS_TEMP_MEAS://can only IND cfg_hdl = htpc_env->hts.descs[HTPC_DESC_HTS_TEMP_MEAS_CLI_CFG].desc_hdl; if(!((param->cfg_val == PRF_CLI_STOP_NTFIND)|| (param->cfg_val == PRF_CLI_START_IND))) { status = PRF_ERR_INVALID_PARAM; } break; case HTPC_CHAR_HTS_MEAS_INTV://can only IND cfg_hdl = htpc_env->hts.descs[HTPC_DESC_HTS_MEAS_INTV_CLI_CFG].desc_hdl; if(!((param->cfg_val == PRF_CLI_STOP_NTFIND)|| (param->cfg_val == PRF_CLI_START_IND))) { status = PRF_ERR_INVALID_PARAM; } break; case HTPC_CHAR_HTS_INTM_TEMP://can only NTF cfg_hdl = htpc_env->hts.descs[HTPC_DESC_HTS_INTM_MEAS_CLI_CFG].desc_hdl; if(!((param->cfg_val == PRF_CLI_STOP_NTFIND)|| (param->cfg_val == PRF_CLI_START_NTF))) { status = PRF_ERR_INVALID_PARAM; } break; default: //Let app know that one of the request params is incorrect status = PRF_ERR_INVALID_PARAM; break; } if (status == PRF_ERR_OK) { //Check if the handle value exists if ((cfg_hdl == ATT_INVALID_SEARCH_HANDLE)) { status = PRF_ERR_INEXISTENT_HDL; } else { // Send GATT Write Request prf_gatt_write_ntf_ind(&htpc_env->con_info, cfg_hdl, param->cfg_val); } } } else { status = PRF_ERR_INVALID_PARAM; } if (status != PRF_ERR_OK) { htpc_error_ind_send(htpc_env, status); } return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Handles reception of the @ref CSCPC_CFG_NTFIND_CMD message. * @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 cscpc_cfg_ntfind_cmd_handler(ke_msg_id_t const msgid, struct cscpc_cfg_ntfind_cmd *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { // Message status uint8_t msg_status = KE_MSG_CONSUMED; // Get the address of the environment struct cscpc_env_tag *cscpc_env = PRF_CLIENT_GET_ENV(dest_id, cscpc); if (cscpc_env != NULL) { // Status uint8_t status = PRF_ERR_OK; // Handle uint16_t handle = ATT_INVALID_SEARCH_HANDLE; do { ASSERT_ERR(ke_state_get(dest_id) != CSCPC_IDLE); // Check the provided connection handle if (param->conhdl != cscpc_env->con_info.conhdl) { status = PRF_ERR_INVALID_PARAM; break; } if (ke_state_get(dest_id) == CSCPC_BUSY) { // Another procedure is pending, keep the command for later msg_status = KE_MSG_SAVED; // Status is PRF_ERR_OK, no message will be sent to the application break; } // state = CSCPC_CONNECTED ASSERT_ERR(cscpc_env->operation == NULL); switch(param->desc_code) { // Write CSC Measurement Characteristic Client Char. Cfg. Descriptor Value case (CSCPC_RD_WR_CSC_MEAS_CFG): { if (param->ntfind_cfg <= PRF_CLI_START_NTF) { handle = cscpc_env->cscs.descs[CSCPC_DESC_CSC_MEAS_CL_CFG].desc_hdl; // The descriptor is mandatory ASSERT_ERR(handle != ATT_INVALID_SEARCH_HANDLE); } else { status = PRF_ERR_INVALID_PARAM; } } break; // Write SC Control Point Characteristic Client Char. Cfg. Descriptor Value case (CSCPC_RD_WR_SC_CTNL_PT_CFG): { if ((param->ntfind_cfg == PRF_CLI_STOP_NTFIND) || (param->ntfind_cfg == PRF_CLI_START_IND)) { handle = cscpc_env->cscs.descs[CSCPC_DESC_SC_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; } } break; default: { status = PRF_ERR_INVALID_PARAM; } break; } } while (0); if (status == PRF_ERR_OK) { ASSERT_ERR(handle != ATT_INVALID_SEARCH_HANDLE); // Set the operation code param->operation = CSCPC_CFG_NTF_IND_OP_CODE; // Store the command structure cscpc_env->operation = param; msg_status = KE_MSG_NO_FREE; // Go to the Busy state ke_state_set(dest_id, CSCPC_BUSY); // Send GATT Write Request prf_gatt_write_ntf_ind(&cscpc_env->con_info, handle, param->ntfind_cfg); } else { cscpc_send_cmp_evt(cscpc_env, CSCPC_CFG_NTF_IND_OP_CODE, status); } } else { cscpc_send_no_conn_cmp_evt(dest_id, src_id, param->conhdl, CSCPC_CFG_NTF_IND_OP_CODE); } return (int)msg_status; }
/** **************************************************************************************** * @brief Handles reception of the @ref GATTC_CMP_EVT message. * This generic event is received for different requests, so need to keep track. * @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_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 state = ke_state_get(dest_id); uint8_t status; // Get the address of the environment struct glpc_env_tag *glpc_env = PRF_CLIENT_GET_ENV(dest_id, glpc); if(state == GLPC_DISCOVERING) { if ((param->status == ATT_ERR_ATTRIBUTE_NOT_FOUND)|| (param->status == ATT_ERR_NO_ERROR)) { // service start/end handles has been received if(glpc_env->last_uuid_req == ATT_SVC_GLUCOSE) { // check if service handles are not ok if(glpc_env->gls.svc.shdl == ATT_INVALID_HANDLE) { // stop discovery procedure. glpc_enable_cfm_send(glpc_env, &glpc_env->con_info, PRF_ERR_STOP_DISC_CHAR_MISSING); } //too many services found only one such service should exist else if(glpc_env->nb_svc != 1) { // stop discovery procedure. glpc_enable_cfm_send(glpc_env, &glpc_env->con_info, PRF_ERR_MULTIPLE_SVC); } else { //discover all GLS characteristics prf_disc_char_all_send(&(glpc_env->con_info), &(glpc_env->gls.svc)); glpc_env->last_uuid_req = ATT_DECL_CHARACTERISTIC; } } else if(glpc_env->last_uuid_req == ATT_DECL_CHARACTERISTIC) { status = prf_check_svc_char_validity(GLPC_CHAR_MAX, glpc_env->gls.chars, glpc_gls_char); // Check for characteristic properties. if(status == PRF_ERR_OK) { glpc_env->last_uuid_req = ATT_INVALID_HANDLE; glpc_env->last_char_code = glpc_gls_char_desc[GLPC_DESC_MEAS_CLI_CFG].char_code; //Discover Glucose Measurement Char. Descriptor - Mandatory prf_disc_char_desc_send(&(glpc_env->con_info), &(glpc_env->gls.chars[glpc_env->last_char_code])); } else { // Stop discovery procedure. glpc_enable_cfm_send(glpc_env, &glpc_env->con_info, status); } } else { //If Glucose Measurement Context Char. found, discover its descriptor if ((glpc_env->gls.chars[GLPC_CHAR_MEAS_CTX].char_hdl != ATT_INVALID_HANDLE) && (glpc_env->last_char_code == GLPC_CHAR_MEAS)) { glpc_env->last_char_code = GLPC_CHAR_MEAS_CTX; //Discover Intermediate Cuff Pressure Char. Descriptor - Mandatory prf_disc_char_desc_send(&(glpc_env->con_info), &(glpc_env->gls.chars[glpc_env->last_char_code])); } // discover Record access control point descriptor else if (glpc_env->last_char_code != GLPC_CHAR_RACP) { glpc_env->last_char_code = GLPC_CHAR_RACP; //Discover Intermediate Cuff Pressure Char. Descriptor - Mandatory prf_disc_char_desc_send(&(glpc_env->con_info), &(glpc_env->gls.chars[glpc_env->last_char_code])); } else { status = prf_check_svc_char_desc_validity(GLPC_DESC_MAX, glpc_env->gls.descs, glpc_gls_char_desc, glpc_env->gls.chars); glpc_enable_cfm_send(glpc_env, &glpc_env->con_info, status); } } } } else if (state == GLPC_CONNECTED) { switch(param->req_type) { case GATTC_WRITE: case GATTC_WRITE_NO_RESPONSE: { // RACP write done. if(glpc_env->last_uuid_req == ATT_CHAR_REC_ACCESS_CTRL_PT) { // an error occurs while writing RACP command if(param->status != PRF_ERR_OK) { struct glpc_racp_rsp * rsp = KE_MSG_ALLOC(GLPC_RACP_RSP, glpc_env->con_info.appid, dest_id, glpc_racp_rsp); // retrieve connection handle rsp->conhdl = gapc_get_conhdl(glpc_env->con_info.conidx); // set error status rsp->status = param->status; // stop timer. ke_timer_clear(GLPC_RACP_REQ_TIMEOUT, dest_id); ke_msg_send(rsp); glpc_env->last_uuid_req = 0; } } else { bool finished = false; // Restore if measurement context notification should be register in from // unused variable bool meas_ctx_en = glpc_env->last_char_code; // Registration succeed if(param->status == PRF_ERR_OK) { // Glucose measurement notification registration done if(glpc_env->last_uuid_req == GLPC_DESC_MEAS_CLI_CFG) { // register to RACP indications prf_gatt_write_ntf_ind(&(glpc_env->con_info), glpc_env->gls.descs[GLPC_DESC_RACP_CLI_CFG].desc_hdl, PRF_CLI_START_IND); glpc_env->last_uuid_req = GLPC_DESC_RACP_CLI_CFG; } // Record access control point indication registration done // Register to Glucose Measurement Context notifications if requested. else if((glpc_env->last_uuid_req == GLPC_DESC_RACP_CLI_CFG) && meas_ctx_en) { // register to Glucose Measurement Context notifications prf_gatt_write_ntf_ind(&(glpc_env->con_info), glpc_env->gls.descs[GLPC_DESC_MEAS_CTX_CLI_CFG].desc_hdl, PRF_CLI_START_NTF); glpc_env->last_uuid_req = GLPC_DESC_MEAS_CTX_CLI_CFG; } // All registration done else { // indication/notification registration finished finished = true; } } // send status if registration done or if an error occurs. if((param->status != PRF_ERR_OK) || (finished)) { struct glpc_register_cfm * cfm = KE_MSG_ALLOC(GLPC_REGISTER_CFM, glpc_env->con_info.appid, dest_id, glpc_register_cfm); // set error status cfm->conhdl = gapc_get_conhdl(glpc_env->con_info.conidx); cfm->status = param->status; ke_msg_send(cfm); } } } break; case GATTC_READ: { if(param->status != GATT_ERR_NO_ERROR) { struct glpc_read_features_rsp * rsp = KE_MSG_ALLOC(GLPC_READ_FEATURES_RSP, glpc_env->con_info.appid, dest_id, glpc_read_features_rsp); // set connection handle rsp->conhdl = gapc_get_conhdl(glpc_env->con_info.conidx); // set error status rsp->status = param->status; ke_msg_send(rsp); } } break; default: break; } } return (KE_MSG_CONSUMED); }