/** **************************************************************************************** * @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); }
void streamdatah_enable_cfm_send(struct streamdatah_env_tag *streamdatah_env, struct prf_con_info *con_info, uint8_t status) { //format response to app struct streamdatah_enable_cfm * cfm = KE_MSG_ALLOC(STREAMDATAH_ENABLE_CFM, con_info->appid, con_info->prf_id, streamdatah_enable_cfm); cfm->conhdl = gapc_get_conhdl(con_info->conidx); cfm->status = status; if (status == PRF_ERR_OK) { cfm->streamdatah = streamdatah_env->streamdatah; // Register STREAMDATAH task in gatt for indication/notifications prf_register_atthdl2gatt(&streamdatah_env->con_info, &streamdatah_env->streamdatah.svc); // Go to connected state ke_state_set(con_info->prf_id, STREAMDATAH_CONNECTED); } else { PRF_CLIENT_ENABLE_ERROR(streamdatah_envs, con_info->prf_id, STREAMDATAH); } ke_msg_send(cfm); }
void wechat_disable(void) { att_size_t length; uint8_t *alert_lvl; // Disable service in database attmdb_svc_set_permission(wechat_env.wechat_shdl, PERM_RIGHT_DISABLE); struct wechat_disable_ind *ind = KE_MSG_ALLOC(WECHAT_DISABLE_IND, wechat_env.con_info.appid, TASK_WECHAT, wechat_disable_ind); //Get value stored in DB attmdb_att_get_value(wechat_env.wechat_shdl + WECHAT_1_IDX_VAL, &length, &alert_lvl); // Fill in the parameter structure ind->conhdl = gapc_get_conhdl(wechat_env.con_info.conidx); // Send the message ke_msg_send(ind); // Go to idle state ke_state_set(TASK_WECHAT, WECHAT_IDLE); }
void blpc_enable_cfm_send(struct blpc_env_tag *blpc_env, struct prf_con_info *con_info, uint8_t status) { // Send to APP the details of the discovered attributes on BLPS struct blpc_enable_cfm * rsp = KE_MSG_ALLOC(BLPC_ENABLE_CFM, con_info->appid, con_info->prf_id, blpc_enable_cfm); rsp->conhdl = gapc_get_conhdl(con_info->conidx); rsp->status = status; if (status == PRF_ERR_OK) { rsp->bps = blpc_env->bps; prf_register_atthdl2gatt(&blpc_env->con_info, &blpc_env->bps.svc); // Go to connected state ke_state_set(blpc_env->con_info.prf_id, BLPC_CONNECTED); } else { PRF_CLIENT_ENABLE_ERROR(blpc_envs, con_info->prf_id, BLPC); } ke_msg_send(rsp); }
/** **************************************************************************************** * @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); }
void hogpbh_enable_cfm_send(struct hogpbh_env_tag *hogpbh_env, struct prf_con_info *con_info, uint8_t status) { // Counter uint8_t i; // Send APP the details of the discovered attributes on HOGPBH struct hogpbh_enable_cfm * rsp = KE_MSG_ALLOC(HOGPBH_ENABLE_CFM, con_info->appid, con_info->prf_id, hogpbh_enable_cfm); rsp->conhdl = gapc_get_conhdl(con_info->conidx); rsp->status = status; if (status == PRF_ERR_OK) { rsp->hids_nb = hogpbh_env->hids_nb; for (i = 0; i < hogpbh_env->hids_nb; i++) { rsp->hids[i] = hogpbh_env->hids[i]; // Register HOGPBH task in gatt for indication/notifications prf_register_atthdl2gatt(&hogpbh_env->con_info, &hogpbh_env->hids[i].svc); } // Go to connected state ke_state_set(con_info->prf_id, HOGPBH_CONNECTED); } else { PRF_CLIENT_ENABLE_ERROR(hogpbh_envs, con_info->prf_id, HOGPBH); } ke_msg_send(rsp); }
void glpc_enable_cfm_send(struct glpc_env_tag *glpc_env, struct prf_con_info *con_info, uint8_t status) { // Send to APP the details of the discovered attributes on GLPS struct glpc_enable_cfm * rsp = KE_MSG_ALLOC(GLPC_ENABLE_CFM, con_info->appid, con_info->prf_id, glpc_enable_cfm); rsp->conhdl = gapc_get_conhdl(con_info->conidx); rsp->status = status; if (status == PRF_ERR_OK) { rsp->gls = glpc_env->gls; // Register GLPC task in gatt for indication/notifications prf_register_atthdl2gatt(&glpc_env->con_info, &glpc_env->gls.svc); // Go to connected state ke_state_set(con_info->prf_id, GLPC_CONNECTED); } else { PRF_CLIENT_ENABLE_ERROR(glpc_envs, con_info->prf_id, GLPC); } ke_msg_send(rsp); }
void basc_enable_cfm_send(struct basc_env_tag *basc_env, struct prf_con_info *con_info, uint8_t status) { // Counter uint8_t svc_inst; // Send APP the details of the discovered attributes on BASC struct basc_enable_cfm * rsp = KE_MSG_ALLOC(BASC_ENABLE_CFM, con_info->appid, con_info->prf_id, basc_enable_cfm); rsp->conhdl = gapc_get_conhdl(con_info->conidx); rsp->status = status; if (status == PRF_ERR_OK) { rsp->bas_nb = basc_env->bas_nb; for (svc_inst = 0; svc_inst < basc_env->bas_nb; svc_inst++) { rsp->bas[svc_inst] = basc_env->bas[svc_inst]; // Register BASC task in gatt for indication/notifications prf_register_atthdl2gatt(&basc_env->con_info, &basc_env->bas[svc_inst].svc); } // Go to connected state ke_state_set(con_info->prf_id, BASC_CONNECTED); } else { PRF_CLIENT_ENABLE_ERROR(basc_envs, con_info->prf_id, BASC); } ke_msg_send(rsp); }
/** **************************************************************************************** * @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 htpc_env_tag *htpc_env = PRF_CLIENT_GET_ENV(dest_id, htpc); // Temperature Measurement Char. if((param->handle == htpc_env->hts.chars[HTPC_CHAR_HTS_TEMP_MEAS].val_hdl) || (param->handle == htpc_env->hts.chars[HTPC_CHAR_HTS_INTM_TEMP].val_hdl)) { htpc_unpack_temp(htpc_env, (uint8_t *)&(param->value), param->length, ((param->type == GATTC_NOTIFY) ? HTPC_TEMP_MEAS_INTM : HTPC_TEMP_MEAS_STABLE)); } // Measurement Interval Char. else if (param->handle == 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 = gapc_get_conhdl(htpc_env->con_info.conidx); memcpy(&ind->intv, ¶m->value[0], sizeof(uint16_t)); ke_msg_send(ind); } return (KE_MSG_CONSUMED); }
void scppc_enable_cfm_send(struct scppc_env_tag *scppc_env, struct prf_con_info *con_info, uint8_t status) { //send APP the details of the discovered attributes on SCPPC struct scppc_enable_cfm * rsp = KE_MSG_ALLOC(SCPPC_ENABLE_CFM, con_info->appid, con_info->prf_id, scppc_enable_cfm); rsp->conhdl = gapc_get_conhdl(con_info->conidx); rsp->status = status; if (status == PRF_ERR_OK) { rsp->scps = scppc_env->scps; // Go to connected state ke_state_set(con_info->prf_id, SCPPC_CONNECTED); // If Scan Refresh Char. has been discovered if (scppc_env->scps.chars[SCPPC_CHAR_SCAN_REFRESH].char_hdl != ATT_INVALID_HANDLE) { // Register SCPPC task in gatt for notifications prf_register_atthdl2gatt(con_info, &scppc_env->scps.svc); } } else { PRF_CLIENT_ENABLE_ERROR(scppc_envs, con_info->prf_id, SCPPC); } ke_msg_send(rsp); }
void proxm_enable_cfm_send(struct proxm_env_tag *proxm_env, struct prf_con_info *con_info, uint8_t status) { //format response to app struct proxm_enable_cfm * cfm = KE_MSG_ALLOC(PROXM_ENABLE_CFM, con_info->appid, con_info->prf_id, proxm_enable_cfm); cfm->conhdl = gapc_get_conhdl(con_info->conidx); cfm->status = status; if (status == PRF_ERR_OK) { cfm->ias = proxm_env->ias; cfm->lls = proxm_env->lls; cfm->txps = proxm_env->txps; // Go to connected state ke_state_set(con_info->prf_id, PROXM_CONNECTED); } else { PRF_CLIENT_ENABLE_ERROR(proxm_envs, con_info->prf_id, PROXM); } ke_msg_send(cfm); }
/** **************************************************************************************** * @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); }
void wptc_enable_cfm_send(struct wptc_env_tag *wptc_env, struct prf_con_info *con_info, uint8_t status) { //format response to app struct wptc_enable_cfm * cfm = KE_MSG_ALLOC(WPTC_ENABLE_CFM, con_info->appid, con_info->prf_id, wptc_enable_cfm); cfm->conhdl = gapc_get_conhdl(con_info->conidx); cfm->status = status; if (status == PRF_ERR_OK) { cfm->wpts = wptc_env->wpts; // Register WPT Client task in gatt for indication/notifications prf_register_atthdl2gatt(&wptc_env->con_info, &wptc_env->wpts.svc); // Go to connected state ke_state_set(con_info->prf_id, WPTC_CONNECTED); } else { PRF_CLIENT_ENABLE_ERROR(wptc_envs, con_info->prf_id, WPTC); } ke_msg_send(cfm); }
/** **************************************************************************************** * @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); }
void rscpc_send_cmp_evt(struct rscpc_env_tag *rscpc_env, uint8_t operation, uint8_t status) { // Free the stored operation if needed if (rscpc_env->operation != NULL) { ke_msg_free(ke_param2msg(rscpc_env->operation)); rscpc_env->operation = NULL; } // Go back to the CONNECTED state if the state is busy if (ke_state_get(rscpc_env->con_info.prf_id) == RSCPC_BUSY) { ke_state_set(rscpc_env->con_info.prf_id, RSCPC_CONNECTED); } // Send the message struct rscpc_cmp_evt *evt = KE_MSG_ALLOC(RSCPC_CMP_EVT, rscpc_env->con_info.appid, rscpc_env->con_info.prf_id, rscpc_cmp_evt); evt->conhdl = gapc_get_conhdl(rscpc_env->con_info.conidx); evt->operation = operation; evt->status = status; ke_msg_send(evt); }
/** **************************************************************************************** * @brief Request to update Measurement Interval Value * @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 htpt_meas_intv_upd_req_handler(ke_msg_id_t const msgid, struct htpt_meas_intv_upd_req const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { uint16_t handle; //Check if Measurement Interval is supported if (htpt_env.att_tbl[HTPT_MEAS_INTV_CHAR] != 0x00) { //Check Connection Handle if(param->conhdl == gapc_get_conhdl(htpt_env.con_info.conidx)) { handle = htpt_env.shdl + htpt_env.att_tbl[HTPT_MEAS_INTV_CHAR] + 1; //Update saved value in database attmdb_att_set_value(handle, sizeof(param->meas_intv), (uint8_t *)¶m->meas_intv); //Must be indicated if enabled if((htpt_env.features & HTPT_MASK_MEAS_INTV_CFG) == HTPT_MASK_MEAS_INTV_CFG) { prf_server_send_event((prf_env_struct *)&htpt_env, true, handle); } } else { //Wrong Connection Handle prf_server_error_ind_send((prf_env_struct *)&htpt_env, PRF_ERR_INVALID_PARAM, HTPT_ERROR_IND, HTPT_MEAS_INTV_UPD_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 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 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 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 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 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 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); }
void prf_client_att_info_rsp(prf_env_struct *p_env, uint16_t msg_id, uint8_t status, struct gattc_read_ind const* read_ind) { // retrieve value length uint16_t length = 0; if(status == GATT_ERR_NO_ERROR) { length = read_ind->length; } // prepare response struct prf_att_info *rsp = KE_MSG_ALLOC_DYN(msg_id, p_env->con_info.appid, p_env->con_info.prf_id, prf_att_info, length); rsp->conhdl = gapc_get_conhdl(p_env->con_info.conidx); rsp->status = status; rsp->handle = ATT_INVALID_HDL; rsp->length = length; // set value array if (read_ind != NULL) { rsp->handle = read_ind->handle; memcpy(&(rsp->value[0]), &(read_ind->value[0]), length); } ke_msg_send(rsp); }
static int sample128_upd_char2_req_handler(ke_msg_id_t const msgid, struct sample128_upd_char2_req const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { uint8_t status = PRF_ERR_OK; // Check provided values if(param->conhdl == gapc_get_conhdl(sample128_env.con_info.conidx)) { // Update value in DB attmdb_att_set_value(sample128_env.sample128_shdl + SAMPLE128_2_IDX_VAL, sizeof(uint8_t), (uint8_t *)¶m->val); if((sample128_env.feature & PRF_CLI_START_NTF)) // Send notification through GATT prf_server_send_event((prf_env_struct *)&sample128_env, false, sample128_env.sample128_shdl + SAMPLE128_2_IDX_VAL); } else { status = PRF_ERR_INVALID_PARAM; } if (status != PRF_ERR_OK) { sample128_upd_char2_cfm_send(status); } return (KE_MSG_CONSUMED); }
void htpc_enable_cfm_send(struct htpc_env_tag *htpc_env, struct prf_con_info *con_info, uint8_t status) { // Inform the APP about the status of the enabling of the Health Thermometer Profile Collector role 5awk struct htpc_enable_cfm *cfm = KE_MSG_ALLOC(HTPC_ENABLE_CFM, con_info->appid, con_info->prf_id, htpc_enable_cfm); // Connection Handle cfm->conhdl = gapc_get_conhdl(con_info->conidx); // Status cfm->status = status; // If status is PRF_ERR_OK, hts is non NULL if (status == PRF_ERR_OK) { // Attributes discovered in the peer device database cfm->hts = htpc_env->hts; // Register the profile task in GATT in order to receive notifications/indications prf_register_atthdl2gatt(con_info, &htpc_env->hts.svc); // Go to connected state ke_state_set(con_info->prf_id, HTPC_CONNECTED); } else { PRF_CLIENT_ENABLE_ERROR(htpc_envs, con_info->prf_id, HTPC); } // Send the confirmation to the application ke_msg_send(cfm); }
/** **************************************************************************************** * @brief Handles reception of the @ref GATT_WRITE_CMD_IND message. * The handler checks if the stream needs to be turned on. * @param[in] msgid Id of the message received (probably unused). * @param[in] param Pointer to the parameters of the message. * @param[in] dest_id ID of the receiving task instance (probably unused). * @param[in] src_id ID of the sending task instance. * @return If the message was consumed or not. **************************************************************************************** */ static int gattc_write_cmd_ind_handler(ke_msg_id_t const msgid, struct gattc_write_cmd_ind const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { // Update the attribute value attmdb_att_update_value(param->handle, param->length, param->offset, (uint8_t*)&(param->value[0])); switch (STREAMDATAD_IDX(param->handle)) { case STREAMDATAD_IDX_ENABLE_VAL: streamdatad_streamonoff(); atts_write_rsp_send(streamdatad_env.conhdl, param->handle, PRF_ERR_OK); break; case STREAMDATAD_IDX_STREAMDATAD_D0_EN: case STREAMDATAD_IDX_STREAMDATAD_D1_EN: case STREAMDATAD_IDX_STREAMDATAD_D2_EN: case STREAMDATAD_IDX_STREAMDATAD_D3_EN: case STREAMDATAD_IDX_STREAMDATAD_D4_EN: case STREAMDATAD_IDX_STREAMDATAD_D5_EN: case STREAMDATAD_IDX_STREAMDATAD_D6_EN: case STREAMDATAD_IDX_STREAMDATAD_D7_EN: case STREAMDATAD_IDX_STREAMDATAD_D8_EN: case STREAMDATAD_IDX_STREAMDATAD_D9_EN: atts_write_rsp_send(streamdatad_env.conhdl, param->handle, PRF_ERR_OK); break; case STREAMDATAD_IDX_STREAMDATAD_D0_VAL: case STREAMDATAD_IDX_STREAMDATAD_D1_VAL: case STREAMDATAD_IDX_STREAMDATAD_D2_VAL: case STREAMDATAD_IDX_STREAMDATAD_D3_VAL: case STREAMDATAD_IDX_STREAMDATAD_D4_VAL: case STREAMDATAD_IDX_STREAMDATAD_D5_VAL: case STREAMDATAD_IDX_STREAMDATAD_D6_VAL: case STREAMDATAD_IDX_STREAMDATAD_D7_VAL: case STREAMDATAD_IDX_STREAMDATAD_D8_VAL: case STREAMDATAD_IDX_STREAMDATAD_D9_VAL: { struct streamdatad_rcv_data_packet_ind * ind = KE_MSG_ALLOC(STREAMDATAD_RCV_DATA_PACKET_IND, streamdatad_env.con_info.appid, dest_id, streamdatad_rcv_data_packet_ind); ind->conhdl = gapc_get_conhdl(streamdatad_env.con_info.conidx); ind->handle = param->handle; ind->seq = param->value[0]; // is already incrementing (with the dummy data of the test) ind->size = param->length; memcpy(&(ind->value[0]), &(param->value[0]), param->length); // Forward Received packet data to APP with the sequence number to indicate lost packets ke_msg_send(ind); } break; } return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @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 PROXM_SET_ALERT_LVL_REQ message. * Request to write either the LLS or IAS alert levels. * @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_wr_alert_lvl_req_handler(ke_msg_id_t const msgid, struct proxm_wr_alert_lvl_req const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { uint8_t req_type = 0x00; uint16_t val_hdl = 0x0000; // Get the address of the environment struct proxm_env_tag *proxm_env = PRF_CLIENT_GET_ENV(dest_id, proxm); if(param->conhdl == gapc_get_conhdl(proxm_env->con_info.conidx)) { // Alert level only has 3 values, other not useful if(param->lvl <= PROXM_ALERT_HIGH) { // Get the request type and handle value for this type of write switch(param->svc_code) { case PROXM_SET_LK_LOSS_ALERT: req_type = GATTC_WRITE; val_hdl = proxm_env->lls.charact.val_hdl; break; case PROXM_SET_IMMDT_ALERT: req_type = GATTC_WRITE_NO_RESPONSE; val_hdl = proxm_env->ias.charact.val_hdl; break; default: proxm_write_char_rsp_send(proxm_env, PRF_ERR_INVALID_PARAM); return (KE_MSG_CONSUMED); } // Check if attribute handle is OK if (val_hdl == ATT_INVALID_HANDLE) { proxm_write_char_rsp_send(proxm_env, PRF_ERR_INEXISTENT_HDL); } else { // Send GATT Write Request prf_gatt_write(&proxm_env->con_info, val_hdl, (uint8_t *)¶m->lvl, sizeof(uint8_t), req_type); } } else { proxm_write_char_rsp_send(proxm_env, PRF_ERR_INVALID_PARAM); } } else { // Wrong Connection Handle proxm_write_char_rsp_send(proxm_env, PRF_ERR_INVALID_PARAM); } return (KE_MSG_CONSUMED); }
void bass_batt_level_upd_cfm_send(uint8_t status) { struct bass_batt_level_upd_cfm * cfm = KE_MSG_ALLOC(BASS_BATT_LEVEL_UPD_CFM, bass_env.con_info.appid, TASK_BASS, bass_batt_level_upd_cfm); cfm->conhdl = gapc_get_conhdl(bass_env.con_info.conidx); cfm->status = status; ke_msg_send(cfm); }
void htpt_temp_send_cfm_send(uint8_t status, uint8_t cfm_type) { struct htpt_temp_send_cfm *cfm = KE_MSG_ALLOC(HTPT_TEMP_SEND_CFM, htpt_env.con_info.appid, TASK_HTPT, htpt_temp_send_cfm); cfm->conhdl = gapc_get_conhdl(htpt_env.con_info.conidx); cfm->status = status; cfm->cfm_type = HTPT_CENTRAL_IND_CFM; ke_msg_send(cfm); }