/** **************************************************************************************** * @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); }
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); }
/** **************************************************************************************** * @brief Handles reception of the @ref ACCEL_VALUE_REQ message. * The handler compares the new values with current ones and notifies them if they changed. * @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 accel_value_req_handler(ke_msg_id_t const msgid, struct accel_value_req const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { // uint16_t len; // uint16_t* axis_en; // uint8_t* axis_val; // Check if acceleration changed on each axis and notify it if required for (int i = 0; i < ACCEL_MAX; i++) { //attmdb_att_get_value(ACCEL_DIR_VAL_HANDLE(i), &(len), (uint8_t**)&(axis_val)); ////gsx //attmdb_att_get_value(ACCEL_DIR_EN_HANDLE(i), &(len), (uint8_t**)&(axis_en)); ////gsx //if ((*axis_en) && (param->accel[i] != *axis_val)) ////gsx { // Update the value in the attribute database attmdb_att_set_value(ACCEL_DIR_VAL_HANDLE(i), sizeof(uint16_t), (uint8_t*) &(param->accel[i]));//gsx sizeof(uint8_t), (uint8_t*) &(param->accel[i] // Send notification prf_server_send_event((prf_env_struct *)&accel_env, false, ACCEL_DIR_VAL_HANDLE(i)); } } return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Handles reception of the @ref TIPS_UPD_CURR_TIME_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_curr_time_req_handler(ke_msg_id_t const msgid, struct tips_upd_curr_time_req const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { // Packed Current Time value uint8_t pckd_time[CTS_CURRENT_TIME_VAL_LEN]; // 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); if (param->conhdl == gapc_get_conhdl(tips_idx_env->con_info.conidx)) { // Pack the Current Time value tips_pack_curr_time_value(&pckd_time[0], ¶m->current_time); // Set the value in the database status = attmdb_att_set_value(tips_env.cts_shdl + CTS_IDX_CURRENT_TIME_VAL, CTS_CURRENT_TIME_VAL_LEN, (uint8_t *)&pckd_time[0]); //Check if Notifications are enabled if ((tips_idx_env->ntf_state & TIPS_CTS_CURRENT_TIME_CFG) == TIPS_CTS_CURRENT_TIME_CFG) { //Check if notification can be sent if ((param->current_time.adjust_reason & TIPS_FLAG_EXT_TIME_UPDATE) == TIPS_FLAG_EXT_TIME_UPDATE) { if (param->enable_ntf_send == 0) { status = PRF_ERR_REQ_DISALLOWED; } } if (status == PRF_ERR_OK) { // The notification can be sent, send the notification prf_server_send_event((prf_env_struct *)tips_idx_env, false, tips_env.cts_shdl + CTS_IDX_CURRENT_TIME_VAL); } } else { status = PRF_ERR_NTF_DISABLED; } } if (status != PRF_ERR_OK) { // Wrong Connection Handle tips_error_ind_send(&(tips_idx_env->con_info), status, TIPS_UPD_CURR_TIME_REQ); } return (KE_MSG_CONSUMED); }
int streamdatad_send_data_packets_req_handler(ke_msg_id_t const msgid, struct streamdatad_send_data_packets_req const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { uint16_t next_packet; uint16_t nr_packets; uint16_t* packet_buffer_enabled; uint16_t len = 0; if (!streamdatad_env.stream_enabled) return KE_MSG_CONSUMED; next_packet = 0; nr_packets = param->nr_packets; nb_buf_av = l2cm_get_nb_buffer_available(); for (int li = 0; (li < STREAMDATAD_MAX) && (nr_packets > 0) && (nb_buf_av > 0); li++) { packet_buffer_enabled = NULL; attmdb_att_get_value(STREAMDATAD_DIR_EN_HANDLE(streamdatad_env.next_attribute_idx), &(len), (uint8_t**)&(packet_buffer_enabled)); if ((packet_buffer_enabled && (*packet_buffer_enabled))) { // Update the value in the attribute database attmdb_att_set_value(STREAMDATAD_DIR_VAL_HANDLE(streamdatad_env.next_attribute_idx), sizeof(uint8_t) * STREAMDATAD_PACKET_SIZE, (uint8_t*) &(param->packets[next_packet][0])); // Send notification prf_server_send_event((prf_env_struct *)&(streamdatad_env.con_info), false, STREAMDATAD_DIR_VAL_HANDLE(streamdatad_env.next_attribute_idx)); } else { len = 2; } //set_pxact_gpio(); next_packet++; nr_packets--; nb_buf_av--; streamdatad_env.next_attribute_idx++; if (streamdatad_env.next_attribute_idx >= STREAMDATAD_MAX) { streamdatad_env.next_attribute_idx = 0; break; // the for loop } // else notification at this index was not enabled; } //set_pxact_gpio(); return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Handles reception of the @ref HRPS_MEAS_SEND_REQ message. * @param[in] msgid Id of the message received (probably unused). * @param[in] param Pointer to the parameters of the message. * @param[in] dest_id ID of the receiving task instance (probably unused). * @param[in] src_id ID of the sending task instance. * @return If the message was consumed or not. **************************************************************************************** */ static int hrps_meas_send_req_handler(ke_msg_id_t const msgid, struct hrps_meas_send_req const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { // Status uint8_t status = PRF_ERR_OK; // Packed Heart Measurement Value uint8_t packed_hr[HRPS_HT_MEAS_MAX_LEN]; // Packet size uint8_t size; if((param->conhdl == gapc_get_conhdl(hrps_env.con_info.conidx)) && (param->meas_val.nb_rr_interval <= HRS_MAX_RR_INTERVAL)) { //Pack the HR Measurement value size = hrps_pack_meas_value(&packed_hr[0], ¶m->meas_val); // Check if notifications are enabled if(HRPS_IS_SUPPORTED(HRPS_HR_MEAS_NTF_CFG)) { //Update value in DB attmdb_att_set_value(hrps_env.shdl + HRS_IDX_HR_MEAS_VAL, size, &packed_hr[0]); //send notification through GATT prf_server_send_event((prf_env_struct *)&hrps_env, false, hrps_env.shdl + HRS_IDX_HR_MEAS_VAL); } //notification not enabled, simply don't send anything else { status = PRF_ERR_NTF_DISABLED; } } else { status = PRF_ERR_INVALID_PARAM; } if (status != PRF_ERR_OK) { // Value has not been sent hrps_meas_send_cfm_send(status); } return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Handles reception of the @ref BAPS_BATT_LEVEL_SEND_REQ message. * @param[in] msgid Id of the message received (probably unused). * @param[in] param Pointer to the parameters of the message. * @param[in] dest_id ID of the receiving task instance (probably unused). * @param[in] src_id ID of the sending task instance. * @return If the message was consumed or not. **************************************************************************************** */ static int bass_batt_level_upd_req_handler(ke_msg_id_t const msgid, struct bass_batt_level_upd_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(bass_env.con_info.conidx)) && (param->bas_instance < bass_env.bas_nb) && (param->batt_level <= BAS_BATTERY_LVL_MAX)) { // Update Battery Level value in DB attmdb_att_set_value(bass_env.shdl[param->bas_instance] + BAS_IDX_BATT_LVL_VAL, sizeof(uint8_t), (uint8_t *)¶m->batt_level); // Check if notifications are enabled if((bass_env.features[param->bas_instance] & BASS_FLAG_NTF_CFG_BIT) == BASS_FLAG_NTF_CFG_BIT) { // Send notification through GATT prf_server_send_event((prf_env_struct *)&bass_env, false, bass_env.shdl[param->bas_instance] + BAS_IDX_BATT_LVL_VAL); } else { status = PRF_ERR_NTF_DISABLED; } } else { status = PRF_ERR_INVALID_PARAM; } if (status != PRF_ERR_OK) { bass_batt_level_upd_cfm_send(status); } return (KE_MSG_CONSUMED); }
void cpps_send_rsp_ind(uint16_t handle, uint8_t req_op_code, uint8_t status) { // Error response uint8_t rsp[CPP_CP_CNTL_PT_RSP_MIN_LEN]; // Response Code rsp[0] = CPP_CTNL_PT_RSP_CODE; // Request Operation Code rsp[1] = req_op_code; // Response value rsp[2] = status; // Set the value in the database - If we are here the handle is valid attmdb_att_set_value(handle, 3, (uint8_t *)&rsp); // Send an indication prf_server_send_event((prf_env_struct *)&cpps_env, true, handle); // Wait for Confirm ke_state_set(TASK_CPPS, CPPS_WAIT_FOR_CFM); }
/** **************************************************************************************** * @brief Handles reception of the @ref HPSS_HTTP_SEND_STATUS_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 hpss_status_code_send_req_handler(ke_msg_id_t const msgid, struct hpss_status_code_send_req const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { // Status uint8_t status = PRF_ERR_OK; if(param->conhdl == gapc_get_conhdl(hpss_env.con_info.conidx)) { //fix me // Check if notifications are enabled if(HPSS_IS_SUPPORTED(HPSS_STATUS_CODE_NTF_CFG)) { //Update value in DB attmdb_att_set_value(hpss_env.hps_shdl + HPS_IDX_STATUS_CODE_VAL, HPS_STATUS_CODE_LEN, (uint8_t *)¶m->status_code);//fix me, LSB? //send notification through GATT prf_server_send_event((prf_env_struct *)&hpss_env, false, hpss_env.hps_shdl + HPS_IDX_STATUS_CODE_VAL); } //notification not enabled, simply don't send anything else { status = PRF_ERR_NTF_DISABLED; } } else { status = PRF_ERR_INVALID_PARAM; } if (status != PRF_ERR_OK) { // Value has not been sent hpss_status_code_send_cfm_send(status); } return (KE_MSG_CONSUMED); }
int streamdatad_send_data_packet(uint8_t *data) { uint16_t* packet_buffer_enabled; int retval = 0; uint16_t len = 0; packet_buffer_enabled = NULL; attmdb_att_get_value(STREAMDATAD_DIR_EN_HANDLE(streamdatad_env.next_attribute_idx), &(len), (uint8_t**)&(packet_buffer_enabled)); if ((packet_buffer_enabled && (*packet_buffer_enabled))) { // Update the value in the attribute database attmdb_att_set_value(STREAMDATAD_DIR_VAL_HANDLE(streamdatad_env.next_attribute_idx), sizeof(uint8_t) * STREAMDATAD_PACKET_SIZE, data); // Send notification prf_server_send_event((prf_env_struct *)&(streamdatad_env.con_info), false, STREAMDATAD_DIR_VAL_HANDLE(streamdatad_env.next_attribute_idx)); retval = 1; } streamdatad_env.next_attribute_idx++; if (streamdatad_env.next_attribute_idx >= STREAMDATAD_MAX) streamdatad_env.next_attribute_idx = 0; return retval; }
/** **************************************************************************************** * @brief Handles reception of the @ref HTPT_TEMP_UPD_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 htpt_temp_send_req_handler(ke_msg_id_t const msgid, struct htpt_temp_send_req const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { // Packed Temperature Measurement value uint8_t packed_temp[HTPT_TEMP_MEAS_MAX_LEN]; // Status uint8_t status = PRF_ERR_OK; // Packet size uint8_t size; if(param->conhdl == gapc_get_conhdl(htpt_env.con_info.conidx)) { //Pack the temperature measurement value size = htpt_pack_temp_value(&packed_temp[0], param->temp_meas); //Intermediate Measurement, must be notified if enabled if(param->flag_stable_meas == 0x00) { //Check if Intermediate Measurement Char. is supported if (htpt_env.att_tbl[HTPT_INTERM_TEMP_CHAR] != 0x00) { //Check if notifications are enabled if((htpt_env.features & HTPT_MASK_INTM_MEAS_CFG) == HTPT_MASK_INTM_MEAS_CFG) { attmdb_att_set_value(htpt_env.shdl + htpt_env.att_tbl[HTPT_INTERM_TEMP_CHAR] + 1, size, &packed_temp[0]); //Send notification through GATT prf_server_send_event((prf_env_struct *)&htpt_env, false, htpt_env.shdl + htpt_env.att_tbl[HTPT_INTERM_TEMP_CHAR] + 1); } else { status = PRF_ERR_NTF_DISABLED; } } else { status = PRF_ERR_FEATURE_NOT_SUPPORTED; } } //Temperature Measurement, must be indicated if enabled else { if((htpt_env.features & HTPT_MASK_TEMP_MEAS_CFG) == HTPT_MASK_TEMP_MEAS_CFG) { attmdb_att_set_value(htpt_env.shdl + HTS_IDX_TEMP_MEAS_VAL, size, &packed_temp[0]); prf_server_send_event((prf_env_struct *)&htpt_env, true, htpt_env.shdl + HTS_IDX_TEMP_MEAS_VAL); } else { status = PRF_ERR_IND_DISABLED; } } } else { //Wrong Connection Handle status = PRF_ERR_INVALID_PARAM; } if (status != PRF_ERR_OK) { /* * The cfm_type value is HTPT_CENTRAL_IND_CFM (1) if param->flag_stable_meas = 1, * HTPT_THERM_TEMP_SEND (0) if param->flag_stable_meas = 0 */ htpt_temp_send_cfm_send(status, param->flag_stable_meas); } return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Handles reception of the @ref PASPS_UPDATE_CHAR_VAL_REQ 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 pasps_update_char_val_cmd_handler(ke_msg_id_t const msgid, struct pasps_update_char_val_cmd *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { // Status uint8_t status = PRF_ERR_INVALID_PARAM; // Message status uint8_t msg_status = KE_MSG_CONSUMED; // Get the address of the environment struct pasps_idx_env_tag *pasps_idx_env = PRF_CLIENT_GET_ENV(dest_id, pasps_idx); if (pasps_idx_env != NULL) { // Check the provided connection handle value if (pasps_idx_env->con_info.conidx != gapc_get_conidx(param->conhdl)) { status = PRF_ERR_INVALID_PARAM; } else if (ke_state_get(dest_id) == PASPS_BUSY) { // Keep the message for later msg_status = KE_MSG_NO_FREE; } else { // Handle uint16_t handle; // Notification status flag uint8_t flag; ASSERT_ERR(ke_state_get(dest_id) == PASPS_CONNECTED); switch (param->operation) { // Alert Status Characteristic case (PASPS_UPD_ALERT_STATUS_OP_CODE): { // Check the provided value if (param->value <= PASP_ALERT_STATUS_VAL_MAX) { // Set the handle value handle = pasps_env.pass_shdl + PASS_IDX_ALERT_STATUS_VAL; // Set the flag flag = PASPS_FLAG_ALERT_STATUS_CFG; status = PRF_ERR_OK; } // else status is PRF_ERR_INVALID_PARAM } break; // Ringer Setting Characteristic case (PASPS_UPD_RINGER_SETTING_OP_CODE): { // Check the provided value if (param->value <= PASP_RINGER_NORMAL) { // Set the handle value handle = pasps_env.pass_shdl + PASS_IDX_RINGER_SETTING_VAL; // Set the flag flag = PASPS_FLAG_RINGER_SETTING_CFG; status = PRF_ERR_OK; // Update the ringer state value pasps_env.ringer_state = param->value; } // else status is PRF_ERR_INVALID_PARAM } break; default: { // Nothing more to do, status is PRF_ERR_INVALID_PARAM } break; } if (status == PRF_ERR_OK) { // Set the value of the characteristic attmdb_att_set_value(handle, sizeof(uint8_t), (uint8_t *)¶m->value); // Check if sending of notifications is enabled for this connection if (PASPS_IS_NTF_ENABLED(pasps_idx_env, flag)) { // Configure the environment for the operation pasps_idx_env->operation = param->operation; // Go to the Busy state ke_state_set(dest_id, PASPS_BUSY); // The notification can be sent, send the notification prf_server_send_event((prf_env_struct *)pasps_idx_env, false, handle); } else { status = PRF_ERR_NTF_DISABLED; } } } // If the status is not OK, no notification has been sent if (status != PRF_ERR_OK) { // Send response to application pasps_send_cmp_evt(pasps_idx_env->con_info.prf_id, pasps_idx_env->con_info.appid, param->conhdl, param->operation, status); } } else { // Send response to application pasps_send_cmp_evt(dest_id, src_id, param->conhdl, param->operation, PRF_ERR_REQ_DISALLOWED); } return (int)msg_status; }
/** **************************************************************************************** * @brief Handles reception of the @ref BAPS_ENABLE_REQ message. * The handler enables the Battery 'Profile' Server 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 bass_enable_req_handler(ke_msg_id_t const msgid, struct bass_enable_req const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { // Attribute offset - Used to retrieve Char. Pres. Format Descriptor handle uint8_t offset; // Packed Char. Presentation Format value uint8_t packed_char_pres[PRF_CHAR_PRES_FMT_SIZE]; // Counter uint8_t i; // Notification Configuration uint16_t ntf_cfg = 0; // Save the application task id bass_env.con_info.appid = src_id; // Save the connection handle associated to the profile bass_env.con_info.conidx = gapc_get_conidx(param->conhdl); // Check if the provided connection exist if (bass_env.con_info.conidx == GAP_INVALID_CONIDX) { // The connection doesn't exist, request disallowed prf_server_error_ind_send((prf_env_struct *)&bass_env, PRF_ERR_REQ_DISALLOWED, BASS_ERROR_IND, BASS_ENABLE_REQ); } else { // For each BAS instance for (i = 0; i < bass_env.bas_nb; i++) { // Reset Offset value offset = BAS_IDX_BATT_LVL_NTF_CFG; // Update Battery Level value in DB attmdb_att_set_value(bass_env.shdl[i] + BAS_IDX_BATT_LVL_VAL, sizeof(uint8_t), (uint8_t *)¶m->current_batt_lvl[i]); // Check if BAS supports notifications if (bass_env.features[i] == BAS_BATT_LVL_NTF_SUP) { // Increment offset (Client Char. Cfg is placed before Char. Pres Fmt. in DB) offset++; // If client is a bonded client if (param->con_type == PRF_CON_NORMAL) { ntf_cfg = param->batt_level_ntf_cfg[i]; /* * The server shall send a notification if value of the Battery Level characteristic * has changed while the service has been disconnected from a bonded client. */ if (param->batt_level_ntf_cfg[i] == PRF_CLI_START_NTF) { // Conserve information in environment bass_env.features[i] |= BASS_FLAG_NTF_CFG_BIT; // Check if old and previous battery level values are different if (param->old_batt_lvl[i] != param->current_batt_lvl[i]) { //Notify current battery level value prf_server_send_event((prf_env_struct *)&bass_env, false, bass_env.shdl[i] + BAS_IDX_BATT_LVL_VAL); } } } // Set NTF Cfg value in the DB attmdb_att_set_value(bass_env.shdl[i] + BAS_IDX_BATT_LVL_NTF_CFG, sizeof(uint16_t), (uint8_t *)&ntf_cfg); } // Check if Characteristic Presentation Format descriptor has been added if (bass_env.bas_nb > 1) { prf_pack_char_pres_fmt(&packed_char_pres[0], ¶m->batt_level_pres_format[i]); /* * Set Characteristic Presentation Format descriptor value * Not supposed to change during connection */ attmdb_att_set_value(bass_env.shdl[i] + offset, PRF_CHAR_PRES_FMT_SIZE, &packed_char_pres[0]); } // Enable Service + Set Security Level attmdb_svc_set_permission(bass_env.shdl[i], param->sec_lvl); } // Go to connected state ke_state_set(TASK_BASS, BASS_CONNECTED); } return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Handles reception of the @ref ANPS_NTF_ALERT_CMD message. * @param[in] msgid Id of the message received. * @param[in] param Pointer to the parameters of the message. * @param[in] dest_id ID of the receiving task instance. * @param[in] src_id ID of the sending task instance. * @return If the message was consumed or not. **************************************************************************************** */ static int anps_ntf_alert_cmd_handler(ke_msg_id_t const msgid, struct anps_ntf_alert_cmd const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { // Message Status uint8_t msg_status = KE_MSG_CONSUMED; // Task environment struct anps_idx_env_tag *anps_idx_env = PRF_CLIENT_GET_ENV(dest_id, anps_idx); if (anps_idx_env != NULL) { // Status uint8_t status = PRF_ERR_OK; // Category ID uint8_t cat_id; // Is the category supported ? bool cat_supported; // Handle uint16_t handle; do { // Check the provided connection handle value if (anps_idx_env->con_info.conidx != gapc_get_conidx(param->conhdl)) { status = PRF_ERR_INVALID_PARAM; break; } if (ke_state_get(dest_id) == ANPS_BUSY) { // The message will be handled once the current operation is over msg_status = KE_MSG_NO_FREE; break; } ASSERT_ERR(ke_state_get(dest_id) == ANPS_CONNECTED); // Check the operation code, get the category ID. if (param->operation == ANPS_UPD_NEW_ALERT_OP_CODE) { // Check the length of the string info value if (param->value.new_alert.info_str_len > ANS_NEW_ALERT_STRING_INFO_MAX_LEN) { status = PRF_ERR_INVALID_PARAM; break; } // Get the category ID cat_id = param->value.new_alert.cat_id; // Check if the category is supported cat_supported = ANPS_IS_NEW_ALERT_CATEGORY_SUPPORTED(cat_id); } else if (param->operation == ANPS_UPD_UNREAD_ALERT_STATUS_OP_CODE) { // Get the category ID cat_id = param->value.unread_alert_status.cat_id; // Check if the category is supported cat_supported = ANPS_IS_UNREAD_ALERT_CATEGORY_SUPPORTED(cat_id); } else { status = PRF_ERR_INVALID_PARAM; break; } // Check the category ID if ((cat_id >= CAT_ID_NB) || (!cat_supported)) { status = PRF_ERR_INVALID_PARAM; break; } if (param->operation == ANPS_UPD_NEW_ALERT_OP_CODE) { // Check if sending of notification is enabled for the provided category if (ANPS_IS_NEW_ALERT_CATEGORY_ENABLED(cat_id, anps_idx_env) && ANPS_IS_ALERT_ENABLED(anps_idx_env, ANP_NEW_ALERT)) { handle = anps_env.ans_shdl + ANS_IDX_NEW_ALERT_VAL; // Notification can be sent, set the value in the database attmdb_att_set_value(handle, 2 + param->value.new_alert.info_str_len, (uint8_t *)¶m->value.new_alert.cat_id); } else { status = PRF_ERR_NTF_DISABLED; break; } } else { if (ANPS_IS_UNREAD_ALERT_CATEGORY_ENABLED(cat_id, anps_idx_env) && ANPS_IS_ALERT_ENABLED(anps_idx_env, ANP_UNREAD_ALERT)) { handle = anps_env.ans_shdl + ANS_IDX_UNREAD_ALERT_STATUS_VAL; attmdb_att_set_value(handle, sizeof(struct anp_unread_alert), (uint8_t *)¶m->value.unread_alert_status); } else { status = PRF_ERR_NTF_DISABLED; break; } } // Configure the environment anps_idx_env->operation = param->operation; // The notification can be sent, send the notification prf_server_send_event((prf_env_struct *)anps_idx_env, false, handle); // Go to Busy state ke_state_set(dest_id, ANPS_BUSY); } while (0); if (status != PRF_ERR_OK) { // Send response to application anps_send_cmp_evt(anps_idx_env->con_info.prf_id, anps_idx_env->con_info.appid, gapc_get_conhdl(anps_idx_env->con_info.conidx), param->operation, status); } } else { // Send response to application anps_send_cmp_evt(dest_id, src_id, param->conhdl, param->operation, PRF_ERR_REQ_DISALLOWED); } return (int)msg_status; }
/** **************************************************************************************** * @brief Handles reception of the @ref GLPS_MEAS_SEND_REQ message. * @param[in] msgid Id of the message received (probably unused). * @param[in] param Pointer to the parameters of the message. * @param[in] dest_id ID of the receiving task instance (probably unused). * @param[in] src_id ID of the sending task instance. * @return If the message was consumed or not. **************************************************************************************** */ static int glps_meas_send_req_handler(ke_msg_id_t const msgid, struct glps_send_meas_with_ctx_req const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { uint8_t status = PRF_ERR_OK; if(param->conhdl == gapc_get_conhdl(glps_env.con_info.conidx)) { // device already sending a measurement if(GLPS_IS(SENDING_MEAS)) { //Cannot send another measurement in parallel status = (PRF_ERR_REQ_DISALLOWED); } else { // inform that device is sending a measurement GLPS_SET(SENDING_MEAS); // check if context is supported if((msgid == GLPS_SEND_MEAS_WITH_CTX_REQ) && !(GLPS_IS(MEAS_CTX_SUPPORTED))) { // Context not supported status = (PRF_ERR_FEATURE_NOT_SUPPORTED); } // check if notifications enabled else if(((glps_env.evt_cfg & GLPS_MEAS_NTF_CFG) == 0) || (((glps_env.evt_cfg & GLPS_MEAS_CTX_NTF_CFG) == 0) && (msgid == GLPS_SEND_MEAS_WITH_CTX_REQ))) { // Not allowed to send measurement if Notifications not enabled. status = (PRF_ERR_NTF_DISABLED); } else { struct attm_elmt * attm_elmt; // retrieve value pointer in database attm_elmt = attmdb_get_attribute(GLPS_HANDLE(GLS_IDX_MEAS_VAL)); // pack measured value in database attm_elmt->length = glps_pack_meas_value(attm_elmt->value, &(param->meas), param->seq_num); prf_server_send_event((prf_env_struct *)&glps_env, false, GLPS_HANDLE(GLS_IDX_MEAS_VAL)); // Measurement value notification not yet sent GLPS_CLEAR(MEAS_SENT); if(msgid == GLPS_SEND_MEAS_WITH_CTX_REQ) { // 2 notification complete messages expected GLPS_SET(MEAS_CTX_SENT); // retrieve value pointer in database attm_elmt = attmdb_get_attribute(GLPS_HANDLE(GLS_IDX_MEAS_CTX_VAL)); // pack measured value in database attm_elmt->length = glps_pack_meas_ctx_value(attm_elmt->value, &(param->ctx), param->seq_num); prf_server_send_event((prf_env_struct *)&glps_env, false, GLPS_HANDLE(GLS_IDX_MEAS_CTX_VAL)); } else { // 1 notification complete messages expected GLPS_CLEAR(MEAS_CTX_SENT); } } } } else { //Wrong Connection Handle status = (PRF_ERR_INVALID_PARAM); } // send command complete if an error occurs if(status != PRF_ERR_OK) { // allow to send other measurements GLPS_CLEAR(SENDING_MEAS); // send completed information to APP task that contains error status struct glps_req_cmp_evt * cmp_evt = KE_MSG_ALLOC(GLPS_REQ_CMP_EVT, glps_env.con_info.appid, TASK_GLPS, glps_req_cmp_evt); cmp_evt->conhdl = param->conhdl; cmp_evt->request = GLPS_SEND_MEAS_REQ_NTF_CMP; cmp_evt->status = status; ke_msg_send(cmp_evt); } return (KE_MSG_CONSUMED); }