/** **************************************************************************************** * @brief Handles reception of the @ref GLPC_READ_FEATURES_REQ message. * Send by application task, it's used to retrieve Glucose Sensor features. * * @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_read_features_req_handler(ke_msg_id_t const msgid, struct glpc_read_features_req const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { // Get the address of the environment struct glpc_env_tag *glpc_env = PRF_CLIENT_GET_ENV(dest_id, glpc); uint8_t status = glpc_validate_request(glpc_env, param->conhdl, GLPC_CHAR_FEATURE); // request can be performed if(status == PRF_ERR_OK) { // read glucose sensor feature prf_read_char_send(&(glpc_env->con_info), glpc_env->gls.svc.shdl, glpc_env->gls.svc.ehdl, glpc_env->gls.chars[GLPC_CHAR_FEATURE].val_hdl); } // send command response with error code else { 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 error status rsp->conhdl = param->conhdl; rsp->status = status; ke_msg_send(rsp); } return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Handles reception of the @ref TIPC_WR_TIME_UPD_CTNL_PT_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 tipc_wr_time_upd_ctnl_pt_req_handler(ke_msg_id_t const msgid, struct tipc_wr_time_udp_ctnl_pt_req const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { // Get the address of the environment struct tipc_env_tag *tipc_env = PRF_CLIENT_GET_ENV(dest_id, tipc); // Check provided parameters if ((param->conhdl == gapc_get_conhdl(tipc_env->con_info.conidx)) && ((param->value == TIPS_TIME_UPD_CTNL_PT_GET) || (param->value == TIPS_TIME_UPD_CTNL_PT_CANCEL))) { if (tipc_env->cts.chars[TIPC_CHAR_RTUS_TIME_UPD_CTNL_PT].char_hdl != ATT_INVALID_SEARCH_HANDLE) { // Send GATT Write Request prf_gatt_write(&tipc_env->con_info, tipc_env->rtus.chars[TIPC_CHAR_RTUS_TIME_UPD_CTNL_PT].val_hdl, (uint8_t *)¶m->value, sizeof(uint8_t), GATTC_WRITE_NO_RESPONSE); } //send app error indication for inexistent handle for this characteristic 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 GATTC_DISC_CHAR_IND message. * Characteristics for the currently desired service handle range are obtained and kept. * @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_disc_char_ind_handler(ke_msg_id_t const msgid, struct gattc_disc_char_ind const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { // Get the address of the environment struct tipc_env_tag *tipc_env = PRF_CLIENT_GET_ENV(dest_id, tipc); if(tipc_env->last_svc_req == ATT_SVC_CURRENT_TIME) { // Retrieve CTS characteristics prf_search_chars(tipc_env->cts.svc.ehdl, TIPC_CHAR_CTS_MAX, &tipc_env->cts.chars[0], &tipc_cts_char[0], param, &tipc_env->last_char_code); } else if(tipc_env->last_svc_req == ATT_SVC_NEXT_DST_CHANGE) { // Retrieve NDCS characteristics prf_search_chars(tipc_env->ndcs.svc.ehdl, TIPC_CHAR_NDCS_MAX, &tipc_env->ndcs.chars[0], &tipc_ndcs_char[0], param, &tipc_env->last_char_code); } else if(tipc_env->last_svc_req == ATT_SVC_REF_TIME_UPDATE) { // Retrieve RTUS characteristics prf_search_chars(tipc_env->rtus.svc.ehdl, TIPC_CHAR_RTUS_MAX, &tipc_env->rtus.chars[0], &tipc_rtus_char[0], param, &tipc_env->last_char_code); } return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Handles reception of the @ref GATT_DISC_CHAR_DESC_CMP_EVT message. * This event can be received several times * @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 gatt_disc_char_desc_evt_handler(ke_msg_id_t const msgid, struct gatt_disc_char_desc_cmp_evt const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { //Counters uint8_t i; // Get the address of the environment struct hogpbh_env_tag *hogpbh_env = PRF_CLIENT_GET_ENV(dest_id, hogpbh); //Retrieve characteristic descriptor handle using UUID for(i = 0; i<(param->nb_entry); i++) { if (param->list[i].desc_hdl == ATT_DESC_CLIENT_CHAR_CFG) { if (hogpbh_env->last_char_code == HOGPBH_CHAR_BOOT_KB_IN_REPORT) { if ((hogpbh_env->hids[hogpbh_env->last_svc_inst_req].chars[HOGPBH_CHAR_BOOT_KB_IN_REPORT].char_hdl + 2) == param->list[i].attr_hdl) { hogpbh_env->hids[hogpbh_env->last_svc_inst_req].descs[HOGPBH_DESC_BOOT_KB_IN_REPORT_CFG].desc_hdl = param->list[i].attr_hdl; } } else if (hogpbh_env->last_char_code == HOGPBH_CHAR_BOOT_MOUSE_IN_REPORT) { if ((hogpbh_env->hids[hogpbh_env->last_svc_inst_req].chars[HOGPBH_CHAR_BOOT_MOUSE_IN_REPORT].char_hdl + 2) == param->list[i].attr_hdl) { hogpbh_env->hids[hogpbh_env->last_svc_inst_req].descs[HOGPBH_DESC_BOOT_MOUSE_IN_REPORT_CFG].desc_hdl = param->list[i].attr_hdl; } } } } return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Handles reception of the @ref GATT_HANDLE_VALUE_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 gatt_handle_value_ind_handler(ke_msg_id_t const msgid, struct gatt_handle_value_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); if(param->conhdl == htpc_env->con_info.conhdl) { // Temperature Measurement Char. if(param->charhdl == htpc_env->hts.chars[HTPC_CHAR_HTS_TEMP_MEAS].val_hdl) { htpc_unpack_temp(htpc_env, (uint8_t *)&(param->value), param->size, HTPC_TEMP_MEAS_STABLE); } // Measurement Interval Char. else if (param->charhdl == htpc_env->hts.chars[HTPC_CHAR_HTS_MEAS_INTV].val_hdl) { struct htpc_meas_intv_ind * ind = KE_MSG_ALLOC(HTPC_MEAS_INTV_IND, htpc_env->con_info.appid, dest_id, htpc_meas_intv_ind); ind->conhdl = htpc_env->con_info.conhdl; memcpy(&ind->intv, ¶m->value[0], sizeof(uint16_t)); ke_msg_send(ind); } } return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Handles reception of the @ref GATT_HANDLE_VALUE_NTF 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 gatt_handle_value_ntf_handler(ke_msg_id_t const msgid, struct gatt_handle_value_notif const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { uint8_t char_code = 0; // Get the address of the environment struct qppc_env_tag *qppc_env = PRF_CLIENT_GET_ENV(dest_id, qppc); if (param->conhdl == qppc_env->con_info.conhdl) { char_code = (param->charhdl - qppc_env->qpps.chars[QPPC_QPPS_FIRST_TX_CHAR_VALUE].val_hdl) / 3 + 1; if (qppc_env->qpps.chars[char_code].val_hdl == param->charhdl) { struct qppc_data_ind * ind = KE_MSG_ALLOC_DYN(QPPC_DATA_IND, qppc_env->con_info.appid, dest_id, qppc_data_ind, param->size); // retrieve connection handle ind->conhdl = qppc_env->con_info.conhdl; ind->char_code = char_code; ind->length = param->size; memcpy(ind->data, param->value, ind->length); ke_msg_send(ind); } } return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Handles reception of the @ref GATTC_EVENT_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_event_ind_handler(ke_msg_id_t const msgid, struct gattc_event_ind const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { // Get the address of the environment struct scppc_env_tag *scppc_env = PRF_CLIENT_GET_ENV(dest_id, scppc); if (KE_IDX_GET(src_id) == scppc_env->con_info.conidx) { //Scan Refresh if (param->handle == scppc_env->scps.chars[SCPPC_CHAR_SCAN_REFRESH].val_hdl) { if (param->value[0] == SCPP_SERVER_REQUIRES_REFRESH) { // Rewrite the most recent settings written on the server struct scppc_scan_intv_wd_wr_req * req = KE_MSG_ALLOC(SCPPC_SCAN_INTV_WD_WR_REQ, dest_id, dest_id, scppc_scan_intv_wd_wr_req); req->conhdl = gapc_get_conhdl(scppc_env->con_info.conidx); co_write16p(&req->scan_intv_wd.le_scan_intv, scppc_env->scan_intv_wd.le_scan_intv); co_write16p(&req->scan_intv_wd.le_scan_window, scppc_env->scan_intv_wd.le_scan_window); ke_msg_send(req); } } } 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 anpc_env_tag *anpc_env = PRF_CLIENT_GET_ENV(dest_id, anpc); if (anpc_env != NULL) { ASSERT_ERR(anpc_env->operation != NULL); // Prepare the indication to send to the application struct anpc_value_ind *ind = KE_MSG_ALLOC(ANPC_VALUE_IND, anpc_env->con_info.appid, anpc_env->con_info.prf_id, anpc_value_ind); ind->conhdl = gapc_get_conhdl(anpc_env->con_info.conidx); switch (((struct anpc_cmd *)anpc_env->operation)->operation) { // Read Supported New Alert Category Characteristic value case (ANPC_ENABLE_RD_NEW_ALERT_OP_CODE): { ind->att_code = ANPC_RD_SUP_NEW_ALERT_CAT; ind->value.supp_cat.cat_id_mask_0 = param->value[0]; // If cat_id_mask_1 not present, shall be considered as 0 ind->value.supp_cat.cat_id_mask_1 = (param->length > 1) ? param->value[1] : 0x00; } break; case (ANPC_ENABLE_RD_UNREAD_ALERT_OP_CODE): { ind->att_code = ANPC_RD_SUP_UNREAD_ALERT_CAT; ind->value.supp_cat.cat_id_mask_0 = param->value[0]; // If cat_id_mask_1 not present, shall be considered as 0 ind->value.supp_cat.cat_id_mask_1 = (param->length > 1) ? param->value[1] : 0; } break; case (ANPC_READ_OP_CODE): { ind->att_code = ((struct anpc_read_cmd *)anpc_env->operation)->read_code; ind->value.ntf_cfg = co_read16(¶m->value[0]); } break; default: { ASSERT_ERR(0); } break; } // Send the indication ke_msg_send(ind); } // else ignore the message return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Handles reception of the @ref TIPS_UPD_REF_TIME_INFO_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 tips_upd_ref_time_info_req_handler(ke_msg_id_t const msgid, struct tips_upd_ref_time_info_req const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { // Status uint8_t status = PRF_ERR_INVALID_PARAM; // Get the address of the environment struct tips_idx_env_tag *tips_idx_env = PRF_CLIENT_GET_ENV(dest_id, tips_idx); // Check the Connection Handle if (param->conhdl == gapc_get_conhdl(tips_idx_env->con_info.conidx)) { // Check if the Reference Time Info Char. has been added in the database if (TIPS_IS_SUPPORTED(TIPS_CTS_REF_TIME_INFO_SUP)) { status = attmdb_att_set_value(tips_env.cts_shdl + tips_env.cts_att_tbl[CTS_REF_TIME_INFO_CHAR] + 1, sizeof(struct tip_ref_time_info), (uint8_t *)&(param->ref_time_info)); } else { status = PRF_ERR_FEATURE_NOT_SUPPORTED; } } if (status != PRF_ERR_OK) { //Wrong Connection Handle tips_error_ind_send(&(tips_idx_env->con_info), status, TIPS_UPD_REF_TIME_INFO_REQ); } return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Handles reception of the @ref GATT_DISC_SVC_BY_UUID_CMP_EVT message. * The handler stores the found service details for service discovery. * @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 gatt_disc_svc_by_uuid_evt_handler(ke_msg_id_t const msgid, struct gatt_disc_svc_by_uuid_cmp_evt const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { // Counter uint8_t i = 0x00; // Get the address of the environment struct basc_env_tag *basc_env = PRF_CLIENT_GET_ENV(dest_id, basc); if (param->status == PRF_ERR_OK) { // We can have several instances of Battery Service for (i = 0; i < (param->nb_resp); i++) { if (basc_env->bas_nb < BASC_NB_BAS_INSTANCES_MAX) { basc_env->bas[basc_env->bas_nb].svc.shdl = param->list[i].start_hdl; basc_env->bas[basc_env->bas_nb].svc.ehdl = param->list[i].end_hdl; // Update number of found BAS instances basc_env->bas_nb++; } } } return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Handles reception of the @ref GATTC_DISC_SVC_IND message. * The handler stores the found service details for service discovery. * @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_disc_svc_ind_handler(ke_msg_id_t const msgid, struct gattc_disc_svc_ind const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { // Get the address of the environment struct anpc_env_tag *anpc_env = PRF_CLIENT_GET_ENV(dest_id, anpc); if (anpc_env != NULL) { ASSERT_ERR(anpc_env->operation != NULL); ASSERT_ERR(((struct anpc_cmd *)anpc_env->operation)->operation == ANPC_ENABLE_OP_CODE); // Keep only one instance of the service if (anpc_env->nb_svc == 0) { // Keep the start handle and the end handle of the service anpc_env->ans.svc.shdl = param->start_hdl; anpc_env->ans.svc.ehdl = param->end_hdl; anpc_env->nb_svc++; } } return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Handles reception of the @ref GATTC_EVENT_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_event_ind_handler(ke_msg_id_t const msgid, struct gattc_event_ind const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { // Get the address of the environment struct blpc_env_tag *blpc_env = PRF_CLIENT_GET_ENV(dest_id, blpc); if(KE_IDX_GET(src_id) == blpc_env->con_info.conidx) { if((param->handle == blpc_env->bps.chars[BLPC_CHAR_CP_MEAS].val_hdl) || ((param->handle == blpc_env->bps.chars[BLPC_CHAR_BP_MEAS].val_hdl))) { //build a BLPC_BP_MEAD_IND message with stable blood pressure value code. struct blpc_meas_ind * ind = KE_MSG_ALLOC(BLPC_BP_MEAS_IND, blpc_env->con_info.appid, dest_id, blpc_meas_ind); // retrieve connection handle ind->conhdl = gapc_get_conhdl(blpc_env->con_info.conidx); // Intermediate cuff pressure value ind->flag_interm_cp = ((param->type == GATTC_NOTIFY) ? 0x01 : 0x00); // unpack blood pressure measurement. blpc_unpack_meas_value(&(ind->meas_val), (uint8_t*) param->value); ke_msg_send(ind); } } return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Handles reception of the @ref GATT_HANDLE_VALUE_NTF 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 gatt_handle_value_ntf_handler(ke_msg_id_t const msgid, struct gatt_handle_value_notif const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { // 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) { if(param->charhdl == hrpc_env->hrs.chars[HRPC_CHAR_HR_MEAS].val_hdl) { //build a HRPC_HR_MEAS_IND message with stable heart rate value code. struct hrpc_meas_ind * ind = KE_MSG_ALLOC(HRPC_HR_MEAS_IND, hrpc_env->con_info.appid, dest_id, hrpc_meas_ind); // retrieve connection handle ind->conhdl = hrpc_env->con_info.conhdl; // unpack heart rate measurement. hrpc_unpack_meas_value(&(ind->meas_val), (uint8_t*) param->value, param->size); ke_msg_send(ind); } } return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Handles reception of the @ref GATT_READ_CHAR_RESP 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 gatt_rd_char_rsp_handler(ke_msg_id_t const msgid, struct gatt_read_char_resp const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { // Get the address of the environment struct hrpc_env_tag *hrpc_env = PRF_CLIENT_GET_ENV(dest_id, hrpc); struct hrpc_rd_char_rsp * rsp = KE_MSG_ALLOC_DYN(HRPC_RD_CHAR_RSP, hrpc_env->con_info.appid, dest_id, hrpc_rd_char_rsp, param->data.len); rsp->conhdl = hrpc_env->con_info.conhdl; /* Do not send body sensor location if it has reserved value */ if((hrpc_env->last_char_code == HRPC_RD_HRS_BODY_SENSOR_LOC) && (param->data.data[0] > HRS_LOC_MAX)) { rsp->status = PRF_ERR_FEATURE_NOT_SUPPORTED; } else { rsp->status = param->status; rsp->data.len = param->data.len; rsp->data.each_len = param->data.each_len; memcpy(&rsp->data.data[0], ¶m->data.data[0], param->data.len); } ke_msg_send(rsp); return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Handles reception of the @ref GATT_DISC_CHAR_DESC_CMP_EVT message. * This event can be received several times * @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 gatt_disc_char_desc_evt_handler(ke_msg_id_t const msgid, struct gatt_disc_char_desc_cmp_evt const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { // Get the address of the environment struct qppc_env_tag *qppc_env = PRF_CLIENT_GET_ENV(dest_id, qppc); if (qppc_env->last_uuid_req == ATT_DESC_CHAR_USER_DESCRIPTION) { qppc_env->qpps.descs[qppc_env->last_char_code].desc_hdl = param->list[0].attr_hdl; } else if (qppc_env->last_uuid_req == ATT_DESC_CLIENT_CHAR_CFG) { //Retrieve characteristic descriptor handle using UUID for (uint8_t i = 0; i < (param->nb_entry) && qppc_env->last_char_code < qppc_env->nb_char; i++) { if (param->list[i].desc_hdl == ATT_DESC_CLIENT_CHAR_CFG) { qppc_env->qpps.descs[qppc_env->last_char_code].desc_hdl = param->list[i].attr_hdl; } } } return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Handles reception of the @ref TIPS_UPD_TIME_UPD_STATE_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 tips_upd_time_upd_state_req_handler(ke_msg_id_t const msgid, struct tips_upd_time_upd_state_req const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { // Status uint8_t status = PRF_ERR_INVALID_PARAM; // Get the address of the environment struct tips_idx_env_tag *tips_idx_env = PRF_CLIENT_GET_ENV(dest_id, tips_idx); // Check the provided Connection Handle if (param->conhdl == gapc_get_conhdl(tips_idx_env->con_info.conidx)) { // Check if the Reference Time Update Service is supported if (TIPS_IS_SUPPORTED(TIPS_RTUS_SUP)) { status = attmdb_att_set_value(tips_env.rtus_shdl + RTUS_IDX_TIME_UPD_STATE_VAL, sizeof(struct tip_time_upd_state), (uint8_t *)&(param->time_upd_state)); } else { status = PRF_ERR_FEATURE_NOT_SUPPORTED; } } if (status != PRF_ERR_OK) { //Wrong Connection Handle tips_error_ind_send(&(tips_idx_env->con_info), status, TIPS_UPD_TIME_UPD_STATE_REQ); } return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Handles reception of the @ref QPPC_RD_CHAR_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 qppc_rd_char_req_handler(ke_msg_id_t const msgid, struct qppc_rd_char_req const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { uint16_t search_hdl = ATT_INVALID_SEARCH_HANDLE; // Get the address of the environment struct qppc_env_tag *qppc_env = PRF_CLIENT_GET_ENV(dest_id, qppc); if (param->conhdl == qppc_env->con_info.conhdl && param->char_code < qppc_env->nb_char) { qppc_env->last_char_code = param->char_code; search_hdl = qppc_env->qpps.descs[param->char_code].desc_hdl; //check if handle is variable if (search_hdl != ATT_INVALID_SEARCH_HANDLE) { prf_read_char_send(&(qppc_env->con_info), qppc_env->qpps.svc.shdl, qppc_env->qpps.svc.ehdl, search_hdl); } else { qppc_error_ind_send(qppc_env, PRF_ERR_INEXISTENT_HDL); } } else { qppc_error_ind_send(qppc_env, PRF_ERR_INVALID_PARAM); } return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @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 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 scppc_env_tag *scppc_env = PRF_CLIENT_GET_ENV(dest_id, scppc); if (scppc_env->last_char_code == SCPPC_DESC_SCAN_REFRESH_CFG) { struct scppc_scan_refresh_ntf_cfg_rd_rsp *rsp = KE_MSG_ALLOC(SCPPC_SCAN_REFRESH_NTF_CFG_RD_RSP, scppc_env->con_info.appid, dest_id, scppc_scan_refresh_ntf_cfg_rd_rsp); rsp->conhdl = gapc_get_conhdl(scppc_env->con_info.conidx); memcpy(&rsp->ntf_cfg, &(param->value[0]), sizeof(uint16_t)); ke_msg_send(rsp); } // Unsupported Characteristic else { scppc_error_ind_send(scppc_env, PRF_ERR_FEATURE_NOT_SUPPORTED); } return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Handles reception of the @ref GATTC_DISC_SVC_IND message. * The handler disables the Health Thermometer Profile Collector 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 gattc_disc_svc_ind_handler(ke_msg_id_t const msgid, struct gattc_disc_svc_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); // Even if we get multiple responses we only store 1 range if (proxm_env->last_uuid_req == ATT_SVC_LINK_LOSS) { proxm_env->lls.svc.shdl = param->start_hdl; proxm_env->lls.svc.ehdl = param->end_hdl; proxm_env->nb_svc++; } else if (proxm_env->last_uuid_req == ATT_SVC_IMMEDIATE_ALERT) { proxm_env->ias.svc.shdl = param->start_hdl; proxm_env->ias.svc.ehdl = param->end_hdl; proxm_env->nb_svc++; } else if (proxm_env->last_uuid_req == ATT_SVC_TX_POWER) { proxm_env->txps.svc.shdl = param->start_hdl; proxm_env->txps.svc.ehdl = param->end_hdl; proxm_env->nb_svc++; } return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Handles reception of the @ref GATT_DISC_SVC_BY_UUID_CMP_EVT message. * The handler stores the found service details for service discovery. * @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 gatt_disc_svc_by_uuid_evt_handler(ke_msg_id_t const msgid, struct gatt_disc_svc_by_uuid_cmp_evt const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { // Counter uint8_t i = 0x00; // Get the address of the environment struct hogpbh_env_tag *hogpbh_env = PRF_CLIENT_GET_ENV(dest_id, hogpbh); if (param->status == PRF_ERR_OK) { // We can have several instances of HID Service for (i = 0; i < (param->nb_resp); i++) { if (hogpbh_env->hids_nb < HOGPBH_NB_HIDS_INST_MAX) { hogpbh_env->hids[hogpbh_env->hids_nb].svc.shdl = param->list[i].start_hdl; hogpbh_env->hids[hogpbh_env->hids_nb].svc.ehdl = param->list[i].end_hdl; } // Update number of found HIDS instances hogpbh_env->hids_nb++; } } return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Handles reception of the @ref GATTC_DISC_CHAR_IND message. * Characteristics for the currently desired service handle range are obtained and kept. * @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_disc_char_ind_handler(ke_msg_id_t const msgid, struct gattc_disc_char_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); if(proxm_env->last_svc_req == ATT_SVC_LINK_LOSS) { // Retrieve LLS characteristics - Only 1 Char. prf_search_chars(proxm_env->lls.svc.ehdl, 1, &proxm_env->lls.charact, &proxm_lls_char, param, &proxm_env->last_char_code); } else if(proxm_env->last_svc_req == ATT_SVC_IMMEDIATE_ALERT) { // Retrieve IAS characteristics - Only 1 Char. prf_search_chars(proxm_env->ias.svc.ehdl, 1, &proxm_env->ias.charact, &proxm_ias_char, param, &proxm_env->last_char_code); } else if(proxm_env->last_svc_req == ATT_SVC_TX_POWER) { // Retrieve TXPS characteristics - Only 1 Char. prf_search_chars(proxm_env->txps.svc.ehdl, 1, &proxm_env->txps.charact, &proxm_txps_char, param, &proxm_env->last_char_code); } return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Handles reception of the @ref GATT_READ_CHAR_RESP 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 gatt_rd_char_rsp_handler(ke_msg_id_t const msgid, struct gatt_read_char_resp 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); struct htpc_rd_char_rsp * rsp = KE_MSG_ALLOC_DYN(HTPC_RD_CHAR_RSP, htpc_env->con_info.appid, dest_id, htpc_rd_char_rsp,param->data.len); rsp->conhdl = htpc_env->con_info.conhdl; rsp->status = param->status; rsp->att_code = htpc_env->last_char_code; rsp->data.len = param->data.len; rsp->data.each_len = param->data.each_len; memcpy(&rsp->data.data[0], ¶m->data.data[0], param->data.len); ke_msg_send(rsp); return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Enable the Proximity Monitor role, used after connection. * @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 proxm_enable_req_handler(ke_msg_id_t const msgid, struct proxm_enable_req const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { // Status uint8_t status; // Device Information Service Client Role Task Environment struct proxm_env_tag *proxm_env; // Connection Information struct prf_con_info con_info; // Fill the Connection Information structure con_info.conidx = gapc_get_conidx(param->conhdl); con_info.prf_id = dest_id; con_info.appid = src_id; // Add an environment for the provided device status = PRF_CLIENT_ENABLE(con_info, param, proxm); if (status == PRF_ERR_FEATURE_NOT_SUPPORTED) { // The message has been forwarded to another task id. return (KE_MSG_NO_FREE); } else if (status == PRF_ERR_OK) { proxm_env = PRF_CLIENT_GET_ENV(dest_id, proxm); // Discovery connection if (param->con_type == PRF_CON_DISCOVERY) { // Start discovering LLS on peer prf_disc_svc_send(&proxm_env->con_info, ATT_SVC_LINK_LOSS); proxm_env->last_uuid_req = ATT_SVC_LINK_LOSS; proxm_env->last_svc_req = ATT_SVC_LINK_LOSS; // Set state to discovering ke_state_set(dest_id, PROXM_DISCOVERING); } else { //copy over data that has been stored proxm_env->ias = param->ias; proxm_env->lls = param->lls; proxm_env->txps = param->txps; //send confirmation of enable request to application proxm_enable_cfm_send(proxm_env, &con_info, PRF_ERR_OK); } } else { proxm_enable_cfm_send(NULL, &con_info, status); } // message is consumed return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Handles reception of the @ref TIPC_ENABLE_REQ message. * The handler enables the Time Profile Client 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 tipc_enable_req_handler(ke_msg_id_t const msgid, struct tipc_enable_req const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { // Status uint8_t status; // Battery Service Client Role Task Environment struct tipc_env_tag *tipc_env; // Connection Information struct prf_con_info con_info; // Fill the Connection Information structure con_info.conidx = gapc_get_conidx(param->conhdl); con_info.prf_id = dest_id; con_info.appid = src_id; // Add an environment for the provided device status = PRF_CLIENT_ENABLE(con_info, param, tipc); if (status == PRF_ERR_FEATURE_NOT_SUPPORTED) { // The message has been forwarded to another task id. return (KE_MSG_NO_FREE); } else if (status == PRF_ERR_OK) { tipc_env = PRF_CLIENT_GET_ENV(dest_id, tipc); //config connection, start discovering if(param->con_type == PRF_CON_DISCOVERY) { //start discovering CTS on peer prf_disc_svc_send(&(tipc_env->con_info), ATT_SVC_CURRENT_TIME); tipc_env->last_uuid_req = ATT_SVC_CURRENT_TIME; tipc_env->last_svc_req = ATT_SVC_CURRENT_TIME; // Go to DISCOVERING state ke_state_set(dest_id, TIPC_DISCOVERING); } //normal connection, get saved att details else { tipc_env->cts = param->cts; tipc_env->ndcs = param->ndcs; tipc_env->rtus = param->rtus; //send APP confirmation that can start normal connection tipc_enable_cfm_send(tipc_env, &con_info, PRF_ERR_OK); } } else { // Send confirmation that can start normal connection tipc_enable_cfm_send(NULL, &con_info, status); } return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Disconnection indication to ANPC. * @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 gap_discon_cmp_evt_handler(ke_msg_id_t const msgid, struct gap_discon_cmp_evt const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { // Get the address of the environment struct cscpc_env_tag *cscpc_env = PRF_CLIENT_GET_ENV(dest_id, cscpc); ASSERT_ERR(cscpc_env != NULL); // Free the stored operation if needed if (cscpc_env->operation != NULL) { // Check if we were waiting for a SC Control Point indication if (((struct cscpc_cmd *)cscpc_env->operation)->operation == CSCPC_CTNL_PT_CFG_IND_OP_CODE) { // Stop the procedure timeout timer ke_timer_clear(CSCPC_TIMEOUT_TIMER_IND, dest_id); } ke_msg_free(ke_param2msg(cscpc_env->operation)); cscpc_env->operation = NULL; } PRF_CLIENT_DISABLE_IND_SEND(cscpc_envs, dest_id, CSCPC); return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Handles reception of the @ref GATTC_DISC_SVC_IND message. * The handler stores the found service details for service discovery. * @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_disc_svc_ind_handler(ke_msg_id_t const msgid, struct gattc_disc_svc_ind const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { // Get the address of the environment struct tipc_env_tag *tipc_env = PRF_CLIENT_GET_ENV(dest_id, tipc); //even if we get multiple responses we only store 1 range if (tipc_env->last_uuid_req == ATT_SVC_CURRENT_TIME) { tipc_env->cts.svc.shdl = param->start_hdl; tipc_env->cts.svc.ehdl = param->end_hdl; tipc_env->nb_svc++; } //should have just one range for this service - use first one only else if (tipc_env->last_uuid_req == ATT_SVC_NEXT_DST_CHANGE) { tipc_env->ndcs.svc.shdl = param->start_hdl; tipc_env->ndcs.svc.ehdl = param->end_hdl; tipc_env->nb_svc++; } //should have just one range for this service - use first one only else if (tipc_env->last_uuid_req == ATT_SVC_REF_TIME_UPDATE) { tipc_env->rtus.svc.shdl = param->start_hdl; tipc_env->rtus.svc.ehdl = param->end_hdl; tipc_env->nb_svc++; } return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Handles reception of the @ref GATT_DISC_SVC_BY_UUID_CMP_EVT 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 gatt_disc_svc_by_uuid_evt_handler(ke_msg_id_t const msgid, struct gatt_disc_svc_by_uuid_cmp_evt const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { // Get the address of the environment struct cscpc_env_tag *cscpc_env = PRF_CLIENT_GET_ENV(dest_id, cscpc); // Check if the environment exists if (cscpc_env != NULL) { ASSERT_ERR(cscpc_env->operation != NULL); ASSERT_ERR(((struct cscpc_cmd *)cscpc_env->operation)->operation == CSCPC_ENABLE_OP_CODE); // Keep only one instance of the service if (cscpc_env->nb_svc == 0) { // Keep the start handle and the end handle of the service cscpc_env->cscs.svc.shdl = param->list[0].start_hdl; cscpc_env->cscs.svc.ehdl = param->list[0].end_hdl; cscpc_env->nb_svc++; } } // else drop the message return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Handles reception of the @ref GATTC_EVENT_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_event_ind_handler(ke_msg_id_t const msgid, struct gattc_event_ind const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { // Get the address of the environment struct tipc_env_tag *tipc_env = PRF_CLIENT_GET_ENV(dest_id, tipc); if(KE_IDX_GET(src_id) == tipc_env->con_info.conidx) { if(param->handle == tipc_env->cts.chars[TIPC_CHAR_CTS_CURR_TIME].val_hdl) { //Build a TIPC_CT_IND message struct tipc_ct_ind * ind = KE_MSG_ALLOC(TIPC_CT_IND, tipc_env->con_info.appid, dest_id, tipc_ct_ind); // retrieve connection handle ind->conhdl = gapc_get_conhdl(tipc_env->con_info.conidx); // Unpack Current Time Value. tipc_unpack_curr_time_value(&(ind->ct_val), (uint8_t*) param->value); // Indication Type ind->ind_type = TIP_NTF; ke_msg_send(ind); } } return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Enable the StreamData client role, used after connection. * @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 sps_client_enable_req_handler(ke_msg_id_t const msgid, struct sps_client_enable_req const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { // Status uint8_t status; // Device Information Service Client Role Task Environment struct sps_client_env_tag *sps_client_env; // Connection Information struct prf_con_info con_info; // Fill the Connection Information structure con_info.conidx = gapc_get_conidx(param->conhdl); con_info.prf_id = dest_id; con_info.appid = src_id; // Add an environment for the provided device status = PRF_CLIENT_ENABLE(con_info, param, sps_client); if (status == PRF_ERR_FEATURE_NOT_SUPPORTED) { // The message has been forwarded to another task id. return (KE_MSG_NO_FREE); } else if (status == PRF_ERR_OK) { sps_client_env = PRF_CLIENT_GET_ENV(dest_id, sps_client); // Discovery connection if (param->con_type == PRF_CON_DISCOVERY) { // Start discovering LLS on peer uint8_t sps_data_service_uuid[]=SPS_SERVICE_UUID; sps_client_env->last_uuid_req = ATT_DECL_PRIMARY_SERVICE; memcpy(sps_client_env->last_svc_req, sps_data_service_uuid, ATT_UUID_128_LEN); prf_disc_svc_send_128(&sps_client_env->con_info, sps_client_env->last_svc_req); // Set state to discovering ke_state_set(dest_id, SPS_CLIENT_DISCOVERING); } else { //copy over data that has been stored sps_client_env->sps_server = param->sps_server; //send confirmation of enable request to application sps_client_enable_cfm_send(sps_client_env, &con_info, PRF_ERR_OK); } } else { sps_client_enable_cfm_send(NULL, &con_info, status); } // message is consumed return (KE_MSG_CONSUMED); }