/** **************************************************************************************** * @brief Handles reception of the @ref PROXM_RD_ALERT_LVL_REQ message. * Request to read the LLS alert level. * @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 proxm_rd_alert_lvl_req_handler(ke_msg_id_t const msgid, struct proxm_rd_alert_lvl_req const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { // Get the address of the environment struct proxm_env_tag *proxm_env = PRF_CLIENT_GET_ENV(dest_id, proxm); // Save the read characteristic code proxm_env->last_char_code = PROXM_RD_LL_ALERT_LVL; if(param->conhdl == gapc_get_conhdl(proxm_env->con_info.conidx)) { if(proxm_env->lls.charact.val_hdl != ATT_INVALID_HANDLE) { // Send Read Char. request prf_read_char_send(&proxm_env->con_info, proxm_env->lls.svc.shdl, proxm_env->lls.svc.ehdl, proxm_env->lls.charact.val_hdl); } else { prf_client_att_info_rsp((prf_env_struct*) proxm_env, PROXM_RD_CHAR_RSP, PRF_ERR_INEXISTENT_HDL, NULL); } } else { // Wrong connection handle prf_client_att_info_rsp((prf_env_struct*) proxm_env, PROXM_RD_CHAR_RSP, PRF_ERR_INVALID_PARAM, NULL); } return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Handles reception of the @ref HTPC_RD_DATETIME_REQ message. * Check if the handle exists in profile(already discovered) and send request, otherwise * error to APP. * @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_rd_char_req_handler(ke_msg_id_t const msgid, struct htpc_rd_char_req const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { // Attribute handle uint16_t search_hdl = ATT_INVALID_SEARCH_HANDLE; // Get the address of the environment struct htpc_env_tag *htpc_env = PRF_CLIENT_GET_ENV(dest_id, htpc); if(param->conhdl == gapc_get_conhdl(htpc_env->con_info.conidx)) { // Descriptors if(((param->char_code & HTPC_DESC_HTS_MASK) == HTPC_DESC_HTS_MASK) && ((param->char_code & ~HTPC_DESC_HTS_MASK) < HTPC_DESC_HTS_MAX)) { search_hdl = htpc_env->hts.descs[param->char_code & ~HTPC_DESC_HTS_MASK].desc_hdl; } // Characteristic else if (param->char_code < HTPC_CHAR_HTS_MAX) { search_hdl = htpc_env->hts.chars[param->char_code].val_hdl; } // Check if handle is viable if (search_hdl != ATT_INVALID_SEARCH_HANDLE) { htpc_env->last_char_code = param->char_code; prf_read_char_send(&(htpc_env->con_info), htpc_env->hts.svc.shdl, htpc_env->hts.svc.ehdl, search_hdl); } else { prf_client_att_info_rsp((prf_env_struct*) htpc_env, HTPC_RD_CHAR_RSP, PRF_ERR_INEXISTENT_HDL, NULL); } } else { prf_client_att_info_rsp((prf_env_struct*) htpc_env, HTPC_RD_CHAR_RSP, PRF_ERR_INVALID_PARAM, NULL); } return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Handles reception of the @ref BLPC_RD_DATETIME_REQ message. * Check if the handle exists in profile(already discovered) and send request, otherwise * error to APP. * @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_rd_char_req_handler(ke_msg_id_t const msgid, struct blpc_rd_char_req const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { uint16_t search_hdl = 0x0000; uint16_t shdl = 0x0000; uint16_t ehdl = 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)) { if((param->char_code & BLPC_DESC_MASK) == BLPC_DESC_MASK) { search_hdl = blpc_env->bps.descs[param->char_code & ~BLPC_DESC_MASK].desc_hdl; shdl = blpc_env->bps.svc.shdl; ehdl = blpc_env->bps.svc.ehdl; } else { search_hdl = blpc_env->bps.chars[param->char_code].val_hdl; shdl = blpc_env->bps.svc.shdl; ehdl = blpc_env->bps.svc.ehdl; } //check if handle is viable if (search_hdl != ATT_INVALID_SEARCH_HANDLE) { prf_read_char_send(&(blpc_env->con_info), shdl, ehdl, search_hdl); } else { prf_client_att_info_rsp((prf_env_struct*) blpc_env, BLPC_RD_CHAR_RSP, PRF_ERR_INEXISTENT_HDL, NULL); } } else { prf_client_att_info_rsp((prf_env_struct*) blpc_env, BLPC_RD_CHAR_RSP, PRF_ERR_INVALID_PARAM, NULL); } return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Handles reception of the @ref GATTC_READ_IND message. * Generic event received after every simple read command sent to peer server. * @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_ind_handler(ke_msg_id_t const msgid, struct gattc_read_ind const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { // Get the address of the environment struct proxm_env_tag *proxm_env = PRF_CLIENT_GET_ENV(dest_id, proxm); prf_client_att_info_rsp((prf_env_struct*) proxm_env, PROXM_RD_CHAR_RSP, GATT_ERR_NO_ERROR, param); return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Handles reception of the @ref GATTC_READ_IND message. * Generic event received after every simple read command sent to peer server. * @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_ind_handler(ke_msg_id_t const msgid, struct gattc_read_ind const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { // Get the address of the environment struct htpc_env_tag *htpc_env = PRF_CLIENT_GET_ENV(dest_id, htpc); // send attribute information prf_client_att_info_rsp((prf_env_struct*) htpc_env, HTPC_RD_CHAR_RSP, GATT_ERR_NO_ERROR, param); return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @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 = 0; // Get the address of the environment struct proxm_env_tag *proxm_env = PRF_CLIENT_GET_ENV(dest_id, proxm); if(state == PROXM_DISCOVERING) { if ((param->status == ATT_ERR_ATTRIBUTE_NOT_FOUND)|| (param->status == ATT_ERR_NO_ERROR)) { //Currently discovering Link Loss Service if (proxm_env->last_svc_req == ATT_SVC_LINK_LOSS) { if (proxm_env->last_uuid_req == ATT_SVC_LINK_LOSS) { if (proxm_env->lls.svc.shdl == ATT_INVALID_HANDLE) { proxm_enable_cfm_send(proxm_env, &proxm_env->con_info, PRF_ERR_STOP_DISC_CHAR_MISSING); } // Too many services found only one such service should exist else if(proxm_env->nb_svc > 1) { // stop discovery procedure. proxm_enable_cfm_send(proxm_env, &proxm_env->con_info, PRF_ERR_MULTIPLE_SVC); } else { // Discover LLS characteristics prf_disc_char_all_send(&(proxm_env->con_info), &(proxm_env->lls.svc)); // Keep last UUID requested and for which service in env proxm_env->last_uuid_req = ATT_DECL_CHARACTERISTIC; } } else if (proxm_env->last_uuid_req == ATT_DECL_CHARACTERISTIC) { status = prf_check_svc_char_validity(1, &proxm_env->lls.charact, &proxm_lls_char); if (status == PRF_ERR_OK) { proxm_env->nb_svc = 0; // Start discovering TXPS on peer prf_disc_svc_send(&(proxm_env->con_info), ATT_SVC_TX_POWER); proxm_env->last_uuid_req = ATT_SVC_TX_POWER; proxm_env->last_svc_req = ATT_SVC_TX_POWER; } else { // Stop discovery procedure. proxm_enable_cfm_send(proxm_env, &proxm_env->con_info, status); } } } //Currently discovering TX Power Service else if (proxm_env->last_svc_req == ATT_SVC_TX_POWER) { if (proxm_env->last_uuid_req == ATT_SVC_TX_POWER) { // TXPS is optional if (proxm_env->txps.svc.shdl == ATT_INVALID_HANDLE) { proxm_env->nb_svc = 0; // Start discovering IAS on peer prf_disc_svc_send(&(proxm_env->con_info), ATT_SVC_IMMEDIATE_ALERT); proxm_env->last_uuid_req = ATT_SVC_IMMEDIATE_ALERT; proxm_env->last_svc_req = ATT_SVC_IMMEDIATE_ALERT; } else { // Discover TXPS characteristics prf_disc_char_all_send(&(proxm_env->con_info), &(proxm_env->txps.svc)); // Keep last UUID requested and for which service in env proxm_env->last_uuid_req = ATT_DECL_CHARACTERISTIC; } } else if (proxm_env->last_uuid_req == ATT_DECL_CHARACTERISTIC) { status = prf_check_svc_char_validity(1, &proxm_env->txps.charact, &proxm_txps_char); if (status == PRF_ERR_OK) { proxm_env->nb_svc = 0; // Start discovering IAS on peer prf_disc_svc_send(&(proxm_env->con_info), ATT_SVC_IMMEDIATE_ALERT); proxm_env->last_uuid_req = ATT_SVC_IMMEDIATE_ALERT; proxm_env->last_svc_req = ATT_SVC_IMMEDIATE_ALERT; } else { // Stop discovery procedure. proxm_enable_cfm_send(proxm_env, &proxm_env->con_info, status); } } } //Currently discovering Immediate Alert Service else if (proxm_env->last_svc_req == ATT_SVC_IMMEDIATE_ALERT) { if (proxm_env->last_uuid_req == ATT_SVC_IMMEDIATE_ALERT) { // IAS is optional if (proxm_env->ias.svc.shdl == ATT_INVALID_HANDLE) { proxm_enable_cfm_send(proxm_env, &proxm_env->con_info, PRF_ERR_OK); } else { // Discover IAS characteristics prf_disc_char_all_send(&(proxm_env->con_info), &(proxm_env->ias.svc)); // Keep last UUID requested and for which service in env proxm_env->last_uuid_req = ATT_DECL_CHARACTERISTIC; } } else if (proxm_env->last_uuid_req == ATT_DECL_CHARACTERISTIC) { status = prf_check_svc_char_validity(1, &proxm_env->txps.charact, &proxm_txps_char); proxm_enable_cfm_send(proxm_env, &proxm_env->con_info, status); } } } } else if (state == PROXM_CONNECTED) { switch(param->req_type) { case GATTC_WRITE: case GATTC_WRITE_NO_RESPONSE: { proxm_write_char_rsp_send(proxm_env, param->status); } break; case GATTC_READ: { if(param->status != GATT_ERR_NO_ERROR) { // an error occurs while reading peer device attribute prf_client_att_info_rsp((prf_env_struct*) proxm_env, PROXM_RD_CHAR_RSP, param->status, NULL); } } break; default: break; } } return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @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); // Status uint8_t status; // Get the address of the environment struct htpc_env_tag *htpc_env = PRF_CLIENT_GET_ENV(dest_id, htpc); if(state == HTPC_DISCOVERING) { if ((param->status == ATT_ERR_ATTRIBUTE_NOT_FOUND)|| (param->status == ATT_ERR_NO_ERROR)) { // Service start/end handles has been received if(htpc_env->last_uuid_req == ATT_SVC_HEALTH_THERMOM) { // check if service handles are not ok if (htpc_env->hts.svc.shdl == ATT_INVALID_HANDLE) { // stop discovery procedure. htpc_enable_cfm_send(htpc_env, &htpc_env->con_info, PRF_ERR_STOP_DISC_CHAR_MISSING); } //too many services found only one such service should exist else if(htpc_env->nb_svc > 1) { // stop discovery procedure. htpc_enable_cfm_send(htpc_env, &htpc_env->con_info, PRF_ERR_MULTIPLE_SVC); } // check if service handles are ok else { //discover all HTS characteristics htpc_env->last_uuid_req = ATT_DECL_CHARACTERISTIC; prf_disc_char_all_send(&(htpc_env->con_info), &(htpc_env->hts.svc)); } } else if(htpc_env->last_uuid_req == ATT_DECL_CHARACTERISTIC) { status = prf_check_svc_char_validity(HTPC_CHAR_HTS_MAX, htpc_env->hts.chars, htpc_hts_char); // Check for characteristic properties. if(status == PRF_ERR_OK) { htpc_env->last_uuid_req = ATT_INVALID_HANDLE; htpc_env->last_char_code = htpc_hts_char_desc[HTPC_DESC_HTS_TEMP_MEAS_CLI_CFG].char_code; //Discover Temperature Measurement Char. Descriptor - Mandatory prf_disc_char_desc_send(&(htpc_env->con_info), &(htpc_env->hts.chars[htpc_env->last_char_code])); } else { // Stop discovery procedure. htpc_enable_cfm_send(htpc_env, &htpc_env->con_info, status); } } else //Descriptors { //Get code of next char. having descriptors htpc_env->last_char_code = htpc_get_next_desc_char_code(htpc_env, &htpc_hts_char_desc[0]); if (htpc_env->last_char_code != HTPC_DESC_HTS_MAX) { prf_disc_char_desc_send(&(htpc_env->con_info), &(htpc_env->hts.chars[htpc_env->last_char_code])); } else { status = prf_check_svc_char_desc_validity(HTPC_DESC_HTS_MAX, htpc_env->hts.descs, htpc_hts_char_desc, htpc_env->hts.chars); htpc_enable_cfm_send(htpc_env, &htpc_env->con_info, status); } } } else { htpc_enable_cfm_send(htpc_env, &htpc_env->con_info, param->status); } } else if(state == HTPC_CONNECTED) { switch(param->req_type) { case GATTC_WRITE: case GATTC_WRITE_NO_RESPONSE: { // Get the address of the environment struct htpc_wr_char_rsp *wr_cfm = KE_MSG_ALLOC(HTPC_WR_CHAR_RSP, htpc_env->con_info.appid, dest_id, htpc_wr_char_rsp); wr_cfm->conhdl = gapc_get_conhdl(htpc_env->con_info.conidx); //it will be a GATT status code wr_cfm->status = param->status; // send the message ke_msg_send(wr_cfm); } break; case GATTC_READ: { if(param->status != GATT_ERR_NO_ERROR) { prf_client_att_info_rsp((prf_env_struct*) htpc_env, HTPC_RD_CHAR_RSP, param->status, NULL); } } break; default: break; } } return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @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 blpc_env_tag *blpc_env = PRF_CLIENT_GET_ENV(dest_id, blpc); if(state == BLPC_DISCOVERING) { if ((param->status == ATT_ERR_ATTRIBUTE_NOT_FOUND)|| (param->status == ATT_ERR_NO_ERROR)) { // service start/end handles has been received if(blpc_env->last_uuid_req == ATT_SVC_BLOOD_PRESSURE) { // check if service handles are not ok if(blpc_env->bps.svc.shdl == ATT_INVALID_HANDLE) { // stop discovery procedure. blpc_enable_cfm_send(blpc_env, &blpc_env->con_info, PRF_ERR_STOP_DISC_CHAR_MISSING); } //too many services found only one such service should exist else if(blpc_env->nb_svc != 1) { // stop discovery procedure. blpc_enable_cfm_send(blpc_env, &blpc_env->con_info, PRF_ERR_MULTIPLE_SVC); } else { //discover all BPS characteristics prf_disc_char_all_send(&(blpc_env->con_info), &(blpc_env->bps.svc)); blpc_env->last_uuid_req = ATT_DECL_CHARACTERISTIC; } } else if(blpc_env->last_uuid_req == ATT_DECL_CHARACTERISTIC) { status = prf_check_svc_char_validity(BLPC_CHAR_MAX, blpc_env->bps.chars, blpc_bps_char); // Check for characteristic properties. if(status == PRF_ERR_OK) { blpc_env->last_uuid_req = ATT_INVALID_HANDLE; blpc_env->last_char_code = blpc_bps_char_desc[BLPC_DESC_BP_MEAS_CLI_CFG].char_code; //Discover Blood Pressure Measurement Char. Descriptor - Mandatory prf_disc_char_desc_send(&(blpc_env->con_info), &(blpc_env->bps.chars[blpc_env->last_char_code])); } else { // Stop discovery procedure. blpc_enable_cfm_send(blpc_env, &blpc_env->con_info, status); } } else { //If Intermediate Cuff Pressure Char. found, discover its descriptor if ((blpc_env->bps.chars[BLPC_CHAR_CP_MEAS].char_hdl != ATT_INVALID_HANDLE) && (blpc_env->last_char_code == BLPC_CHAR_BP_MEAS)) { blpc_env->last_char_code = BLPC_CHAR_CP_MEAS; //Discover Intermediate Cuff Pressure Char. Descriptor - Mandatory prf_disc_char_desc_send(&(blpc_env->con_info), &(blpc_env->bps.chars[blpc_env->last_char_code])); } else { status = prf_check_svc_char_desc_validity(BLPC_DESC_MAX, blpc_env->bps.descs, blpc_bps_char_desc, blpc_env->bps.chars); blpc_enable_cfm_send(blpc_env, &blpc_env->con_info, status); } } } } else if(state == BLPC_CONNECTED) { switch(param->req_type) { case GATTC_WRITE: case GATTC_WRITE_NO_RESPONSE: { struct blpc_wr_char_rsp *wr_cfm = KE_MSG_ALLOC(BLPC_WR_CHAR_RSP, blpc_env->con_info.appid, dest_id, blpc_wr_char_rsp); wr_cfm->conhdl = gapc_get_conhdl(blpc_env->con_info.conidx); //it will be a GATT status code wr_cfm->status = param->status; // send the message ke_msg_send(wr_cfm); } break; case GATTC_READ: { if(param->status != GATT_ERR_NO_ERROR) { prf_client_att_info_rsp((prf_env_struct*) blpc_env, BLPC_RD_CHAR_RSP, param->status, NULL); } } break; default: break; } } return (KE_MSG_CONSUMED); }