/** **************************************************************************************** * @brief Handles reception of the @ref HRPS_ENABLE_REQ message. * The handler enables the Heart Rate Sensor Profile. * @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_enable_req_handler(ke_msg_id_t const msgid, struct hrps_enable_req const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { uint16_t value = 0; // Save the application task id hrps_env.con_info.appid = src_id; // Save the connection handle associated to the profile hrps_env.con_info.conidx = gapc_get_conidx(param->conhdl); // Check if the provided connection exist if (hrps_env.con_info.conidx == GAP_INVALID_CONIDX) { // The connection doesn't exist, request disallowed prf_server_error_ind_send((prf_env_struct *)&hrps_env, PRF_ERR_REQ_DISALLOWED, HRPS_ERROR_IND, HRPS_ENABLE_REQ); } else { // If this connection is a not configuration one, apply config saved by app if(param->con_type == PRF_CON_NORMAL) { value = param->hr_meas_ntf_en; if (param->hr_meas_ntf_en == PRF_CLI_START_NTF) { hrps_env.features |= HRPS_HR_MEAS_NTF_CFG; } } //Set HR Meas. Char. NTF Configuration in DB attmdb_att_set_value(hrps_env.shdl + HRS_IDX_HR_MEAS_NTF_CFG, sizeof(uint16_t), (uint8_t *)&value); if (HRPS_IS_SUPPORTED(HRPS_BODY_SENSOR_LOC_CHAR_SUP)) { //Set Body Sensor Location Char Value in DB - Not supposed to change during connection attmdb_att_set_value(hrps_env.shdl + HRS_IDX_BOBY_SENSOR_LOC_VAL, sizeof(uint8_t), (uint8_t *)¶m->body_sensor_loc); } // Enable Service + Set Security Level attmdb_svc_set_permission(hrps_env.shdl, param->sec_lvl); // Go to connected state ke_state_set(TASK_HRPS, HRPS_CONNECTED); } return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Enable the Sample128 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 sample128_enable_req_handler(ke_msg_id_t const msgid, struct sample128_enable_req const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { uint16_t temp = 1; // Keep source of message, to respond to it further on sample128_env.con_info.appid = src_id; // Store the connection handle for which this profile is enabled sample128_env.con_info.conidx = gapc_get_conidx(param->conhdl); // Check if the provided connection exist if (sample128_env.con_info.conidx == GAP_INVALID_CONIDX) { // The connection doesn't exist, request disallowed prf_server_error_ind_send((prf_env_struct *)&sample128_env, PRF_ERR_REQ_DISALLOWED, SAMPLE128_ERROR_IND, SAMPLE128_ENABLE_REQ); } else { // Sample128 1 attmdb_svc_set_permission(sample128_env.sample128_shdl, param->sec_lvl); //set char 1 to specified value attmdb_att_set_value(sample128_env.sample128_shdl + SAMPLE128_1_IDX_VAL, sizeof(uint8_t), (uint8_t *)¶m->sample128_1_val); attmdb_att_set_value(sample128_env.sample128_shdl + SAMPLE128_2_IDX_VAL, sizeof(uint8_t), (uint8_t *)¶m->sample128_2_val); sample128_env.feature = param->feature; if (!sample128_env.feature) { temp = 0; } attmdb_att_set_value(sample128_env.sample128_shdl + SAMPLE128_2_IDX_CFG, sizeof(uint16_t), (uint8_t *)&temp); // Go to Connected state ke_state_set(TASK_SAMPLE128, SAMPLE128_CONNECTED); } 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 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); }
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 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 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 UDSS_ENABLE_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 udss_enable_req_handler(ke_msg_id_t const msgid, struct udss_enable_req const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { //Save the connection handle associated to the profile udss_env.con_info.conidx = gapc_get_conidx(param->conhdl); //Save the application id udss_env.con_info.appid = src_id; // Check if the provided connection exist if (udss_env.con_info.conidx == GAP_INVALID_CONIDX) { // The connection doesn't exist, request disallowed prf_server_error_ind_send((prf_env_struct *)&udss_env, PRF_ERR_REQ_DISALLOWED, UDSS_ERROR_IND, UDSS_ENABLE_REQ); } else { //Enable Attributes + Set Security Level attmdb_svc_set_permission(udss_env.shdl, param->sec_lvl); //Set User Height to specified value attmdb_att_set_value(udss_env.shdl + UDS_IDX_USER_HEIGHT_VAL, sizeof(uint8_t), (uint8_t *)¶m->user_height); //Set User Age to specified value attmdb_att_set_value(udss_env.shdl + UDS_IDX_USER_AGE_VAL, sizeof(uint8_t), (uint8_t *)¶m->user_age); //Set User Date of Birth to specified value attmdb_att_set_value(udss_env.shdl + UDS_IDX_USER_DATE_OF_BIRTH_VAL, sizeof(struct date), (uint8_t *)¶m->user_date_of_birth); //Set User DB Change Increment to specified value attmdb_att_set_value(udss_env.shdl + UDS_IDX_USER_DB_CHANGE_INCR_VAL, sizeof(uint8_t), (uint8_t *)¶m->user_db_change_incr); // Go to connected state ke_state_set(TASK_UDSS, UDSS_CONNECTED); } return (KE_MSG_CONSUMED); }
void streamdatad_streamonoff(void) { uint16_t len = 0; uint8_t* streamdatad_en = NULL; attmdb_att_get_value(STREAMDATAD_HANDLE(STREAMDATAD_IDX_ENABLE_VAL), &(len), &(streamdatad_en)); // Indicate to the application the state of the profile int on = ((len == 2) && (streamdatad_en && (*streamdatad_en))) ? 1 : 0; if (on) { // Allocate the start indication message struct streamdatad_start_ind *ind = KE_MSG_ALLOC(STREAMDATAD_START_IND, streamdatad_env.appid, TASK_STREAMDATAD, streamdatad_start_ind); streamdatad_env.stream_enabled = (*streamdatad_en); ind->status = PRF_ERR_OK; // Send the message ke_msg_send(ind); } else { streamdatad_env.next_attribute_idx = 0; streamdatad_env.stream_enabled = 0; // Send the stop indication ke_msg_send_basic(STREAMDATAD_STOP_IND, streamdatad_env.appid, TASK_STREAMDATAD); } uint16_t enable_val = streamdatad_en?(*streamdatad_en):0; // Enable or disable all data notifications streamdatad_env.nr_enabled_attributes = 0; int lastattr = enable_val?((STREAMDATAD_MAX>MAX_TRANSMIT_BUFFER_PACKETS)?MAX_TRANSMIT_BUFFER_PACKETS:STREAMDATAD_MAX):STREAMDATAD_MAX; attmdb_att_set_value(STREAMDATAD_IDX_ENABLE_EN, sizeof(uint16_t),(uint8_t*) &(enable_val)); for (int i = 0; i < lastattr; i++) { attmdb_att_set_value(STREAMDATAD_DIR_EN_HANDLE(i), sizeof(uint16_t),(uint8_t*) &(enable_val)); streamdatad_env.nr_enabled_attributes++; } if (!enable_val) streamdatad_env.nr_enabled_attributes = 0; }
/** **************************************************************************************** * @brief Handles reception of the @ref GATT_WRITE_CMD_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_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) { uint8_t char_code = ADC_NOTIFY_ERR_CHAR; uint8_t status = PRF_APP_ERROR; if (KE_IDX_GET(src_id) == adc_notify_env.con_info.conidx) { if (param->handle == adc_notify_env.adc_notify_shdl + ADC_NOTIFY_IDX_CFG) { char_code = ADC_NOTIFY_CFG; } if (char_code == ADC_NOTIFY_CFG) { // Written value uint16_t ntf_cfg; // Extract value before check ntf_cfg = co_read16p(¶m->value[0]); // Only update configuration if value for stop or notification enable if ((ntf_cfg == PRF_CLI_STOP_NTFIND) || (ntf_cfg == PRF_CLI_START_NTF)) { //Save value in DB attmdb_att_set_value(param->handle, sizeof(uint16_t), (uint8_t *)¶m->value[0]); // Conserve information in environment if (ntf_cfg == PRF_CLI_START_NTF) { // Ntf cfg bit set to 1 adc_notify_env.feature |= PRF_CLI_START_NTF; } else { // Ntf cfg bit set to 0 adc_notify_env.feature &= ~PRF_CLI_START_NTF; } adc_notify_send_cfg(ntf_cfg); status = PRF_ERR_OK; } } } // Send Write Response atts_write_rsp_send(adc_notify_env.con_info.conidx, param->handle, status); 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 UDSS_SET_CHAR_VAL_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 udss_set_char_val_req_handler(ke_msg_id_t const msgid, struct udss_set_char_val_req const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { // Request status uint8_t status; // Characteristic Declaration attribute handle uint16_t handle; //Save the application task id udss_env.con_info.appid = src_id; // Check Characteristic Code if (param->char_code <= 0)//UDS_PNP_ID_CHAR) { // Get Characteristic Declaration attribute handle handle = udss_env.shdl + udss_env.att_tbl[param->char_code]; // Check if the Characteristic exists in the database if (handle != PRF_ERR_INEXISTENT_HDL) { // Check the value length // status = udss_check_val_len(param->char_code, param->val_len); if (status == PRF_ERR_OK) { // Set value in the database attmdb_att_set_value(handle + 1, param->val_len, (uint8_t *)¶m->val[0]); } } else { status = PRF_ERR_INEXISTENT_HDL; } } else { status = PRF_ERR_INVALID_PARAM; } if (status != PRF_ERR_OK) { // Status is PRF_ERR_INVALID_PARAM or PRF_ERR_UNEXPECTED_LEN or PRF_ERR_INEXISTENT_HDL prf_server_error_ind_send((prf_env_struct *)&udss_env, status, UDSS_ERROR_IND, UDSS_SET_CHAR_VAL_REQ); } 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 HTPT_TEMP_TYPE_UPD_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 htpt_temp_type_upd_req_handler(ke_msg_id_t const msgid, struct htpt_temp_type_upd_req const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { if (htpt_env.att_tbl[HTPT_TEMP_TYPE_CHAR] != 0x00) { //Update value in database attmdb_att_set_value(htpt_env.shdl + htpt_env.att_tbl[HTPT_TEMP_TYPE_CHAR] + 1, sizeof(param->value), (uint8_t *)&(param->value)); } else { prf_server_error_ind_send((prf_env_struct *)&htpt_env, PRF_ERR_FEATURE_NOT_SUPPORTED, HTPT_ERROR_IND, HTPT_TEMP_TYPE_UPD_REQ); } 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); }
/** **************************************************************************************** * @brief Handles reception of the @ref TIPS_UPD_TIME_DST_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_dst_req_handler(ke_msg_id_t const msgid, struct tips_upd_time_dst_req const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { // Packed Time With DST value uint8_t pckd_time_dst[NDCS_TIME_DST_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); // Check the provided Connection Handle if (param->conhdl == gapc_get_conhdl(tips_idx_env->con_info.conidx)) { // Check if the Next DST Change Service is supported if (TIPS_IS_SUPPORTED(TIPS_NDCS_SUP)) { //Pack the Time with DST value and Save it into the DB tips_pack_time_dst_value(&pckd_time_dst[0], ¶m->time_with_dst); // Set the value in the database status = attmdb_att_set_value(tips_env.ndcs_shdl + NDCS_IDX_TIME_DST_VAL, NDCS_TIME_DST_VAL_LEN, (uint8_t *)&pckd_time_dst[0]); } 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_DST_REQ); } 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 GL2C_CODE_ATT_WR_CMD_IND message. * The message is redirected from TASK_SVC because at profile enable, the ATT handle is * register for TASK_FINDT. In the handler, an ATT Write Response/Error Response should * be sent for ATT protocol, but Alert Level Characteristic only supports WNR so no * response PDU is needed. * @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) { uint8_t alert_lvl = 0x0000; if (KE_IDX_GET(src_id) == findt_env.con_info.conidx) { if(param->handle == findt_env.shdl + FINDT_IAS_IDX_ALERT_LVL_VAL) { alert_lvl = param->value[0]; //Check if Alert Level is valid if ((param->value[0] <= FINDT_ALERT_HIGH)) { //Update the attribute value attmdb_att_set_value(param->handle, sizeof(uint8_t), (uint8_t *)&alert_lvl); if(param->last) { // Allocate the alert value change indication struct findt_alert_ind *ind = KE_MSG_ALLOC(FINDT_ALERT_IND, findt_env.con_info.appid, TASK_FINDT, findt_alert_ind); // Fill in the parameter structure ind->conhdl = gapc_get_conhdl(findt_env.con_info.conidx); ind->alert_lvl = alert_lvl; // Send the message ke_msg_send(ind); } // It was a Write Without Response so no RSP needed. } } } return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Enable the HPS Server 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 hpss_enable_req_handler(ke_msg_id_t const msgid, struct hpss_enable_req const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { uint16_t value = 0; // Keep source of message, to respond to it further on hpss_env.con_info.appid = src_id; // Store the connection handle for which this profile is enabled hpss_env.con_info.conidx = gapc_get_conidx(param->conhdl); // Check if the provided connection exist if (hpss_env.con_info.conidx == GAP_INVALID_CONIDX) { // The connection doesn't exist, request disallowed prf_server_error_ind_send((prf_env_struct *)&hpss_env, PRF_ERR_REQ_DISALLOWED, HPSS_ERROR_IND, HPSS_ENABLE_REQ); } else { // Enable HPS + Set Security Level attmdb_svc_set_permission(hpss_env.hps_shdl, param->sec_lvl); //Set HR Meas. Char. NTF Configuration in DB attmdb_att_set_value(hpss_env.hps_shdl + HPS_IDX_STATUS_CODE_CFG, sizeof(uint16_t), (uint8_t *)&value); //fix me? //Set LLS Alert Level to specified value // attmdb_att_set_value(hpss_env.hps_shdl + LLS_IDX_ALERT_LVL_VAL, // sizeof(uint8_t), (uint8_t *)¶m->lls_alert_lvl); // Go to Connected state ke_state_set(TASK_HPSS, HPSS_CONNECTED); } return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Handles reception of the @ref GATT_WRITE_CMD_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_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) { uint8_t char_code = SAMPLE128_ERR_CHAR; uint8_t status = PRF_APP_ERROR; if (KE_IDX_GET(src_id) == sample128_env.con_info.conidx) { if (param->handle == sample128_env.sample128_1_shdl + SAMPLE128_1_IDX_VAL) { char_code = SAMPLE128_1_CHAR; } if (char_code != SAMPLE128_ERR_CHAR) { //Save value in DB attmdb_att_set_value(param->handle, sizeof(uint8_t), (uint8_t *)¶m->value[0]); if(param->last) { sample128_send_val(param->value[0]); } status = PRF_ERR_OK; // Send Write Response atts_write_rsp_send(sample128_env.con_info.conidx, param->handle, status); } } return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Handles reception of the @ref TIPS_UPD_LOCAL_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_local_time_info_req_handler(ke_msg_id_t const msgid, struct tips_upd_local_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 Local Time Info Char. has been added in the database if (TIPS_IS_SUPPORTED(TIPS_CTS_LOC_TIME_INFO_SUP)) { // Set the value in the database status = attmdb_att_set_value(tips_env.cts_shdl + CTS_IDX_LOCAL_TIME_INFO_VAL, sizeof(struct tip_loc_time_info), (uint8_t *)&(param->loc_time_info)); } else { status = PRF_ERR_FEATURE_NOT_SUPPORTED; } } // Send a message to the application if an error has been raised. if (status != PRF_ERR_OK) { //Wrong Connection Handle tips_error_ind_send(&(tips_idx_env->con_info), status, TIPS_UPD_LOCAL_TIME_INFO_REQ); } return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Handles reception of the @ref ACCEL_ENABLE_REQ message. * The handler enables the accelerometer profile. * @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_enable_req_handler(ke_msg_id_t const msgid, struct accel_enable_req const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { uint16_t disable_val = 0x00; //Save Application ID accel_env.con_info.appid = src_id; accel_env.con_info.prf_id = dest_id; // Save the connection index associated to the profile accel_env.con_info.conidx = gapc_get_conidx(param->conhdl); attmdb_att_set_value(ACCEL_HANDLE(ACCEL_IDX_ENABLE_VAL), sizeof(uint8_t), (uint8_t*) &(disable_val)); attmdb_att_set_value(ACCEL_HANDLE(ACCEL_IDX_RANGE_VAL), sizeof(uint8_t), (uint8_t*) &(disable_val)); attmdb_att_set_value(ACCEL_HANDLE(ACCEL_IDX_ACCEL_X_EN), sizeof(uint16_t),(uint8_t*) &(disable_val)); attmdb_att_set_value(ACCEL_HANDLE(ACCEL_IDX_ACCEL_Y_EN), sizeof(uint16_t),(uint8_t*) &(disable_val)); attmdb_att_set_value(ACCEL_HANDLE(ACCEL_IDX_ACCEL_Z_EN), sizeof(uint16_t),(uint8_t*) &(disable_val)); { uint8_t tb; // tb = battery_get_lvl(BATT_CR2032); tb = battery_get_lvl(BATT_JPLUS);//gsx,jplus battery type. // Update the value in the attribute database attmdb_att_set_value(ACCEL_HANDLE(ACCEL_IDX_ENABLE_VAL), sizeof(uint8_t), (uint8_t*) &(tb)); } //Enable Service attmdb_svc_set_permission(accel_env.shdl, PERM(SVC, ENABLE)); // Go to active state ke_state_set(TASK_ACCEL, ACCEL_ACTIVE); return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Handles reception of the @ref SAMPLE128_CREATE_DB_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 sample128_create_db_req_handler(ke_msg_id_t const msgid, struct sample128_create_db_req const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { //Database Creation Status uint8_t status; uint8_t nb_att_16; uint8_t nb_att_128; uint8_t nb_att_32; uint16_t att_decl_svc = ATT_DECL_PRIMARY_SERVICE; uint16_t att_decl_char = ATT_DECL_CHARACTERISTIC; uint16_t att_decl_cfg = ATT_DESC_CLIENT_CHAR_CFG; uint16_t val_hdl; uint16_t char_hdl; //Save Profile ID sample128_env.con_info.prf_id = TASK_SAMPLE128; /*---------------------------------------------------* * Link Loss Service Creation *---------------------------------------------------*/ //Add Service Into Database nb_att_16 = 4; // 2 UUID16 atts nb_att_32 = 0;// No UUID32 att nb_att_128 = 2; //1 UUID128 att status = attmdb_add_service(&(sample128_env.sample128_shdl), TASK_SAMPLE128, nb_att_16, nb_att_32, nb_att_128, 58); //total attributte size = 36, 16 (svc) + 19 (desc_char) + 1 (att) if (status == ATT_ERR_NO_ERROR) { //add svc attribute status = attmdb_add_attribute(sample128_env.sample128_shdl, ATT_UUID_128_LEN, //Data size = 16 (ATT_UUID_128_LEN) ATT_UUID_16_LEN, (uint8_t*)&att_decl_svc, PERM(RD, ENABLE), &(sample128_env.sample128_shdl)); status = attmdb_att_set_value(sample128_env.sample128_shdl, ATT_UUID_128_LEN, (uint8_t *)sample128_svc.uuid); //char 1 //add char attribute status = attmdb_add_attribute(sample128_env.sample128_shdl, ATT_UUID_128_LEN + 3, //Data size = 19 (ATT_UUID_128_LEN + 3) ATT_UUID_16_LEN, (uint8_t*) &att_decl_char, PERM(RD, ENABLE), &(char_hdl)); //add val attribute status = attmdb_add_attribute(sample128_env.sample128_shdl, sizeof(uint8_t), //Data size = 1 ATT_UUID_128_LEN, (uint8_t*)&sample128_1_val.uuid, PERM(RD, ENABLE) | PERM(WR, ENABLE), &(val_hdl)); memcpy(sample128_1_char.attr_hdl, &val_hdl, sizeof(uint16_t)); status = attmdb_att_set_value(char_hdl, sizeof(sample128_1_char), (uint8_t *)&sample128_1_char); //////char 2 //add char attribute status = attmdb_add_attribute(sample128_env.sample128_shdl, ATT_UUID_128_LEN + 3, //Data size = 19 (ATT_UUID_128_LEN + 3) ATT_UUID_16_LEN, (uint8_t*) &att_decl_char, PERM(RD, ENABLE), &(char_hdl)); //add val attribute status = attmdb_add_attribute(sample128_env.sample128_shdl, sizeof(uint8_t), //Data size = 1 ATT_UUID_128_LEN, (uint8_t*)&sample128_2_val.uuid, PERM(RD, ENABLE) | PERM(NTF, ENABLE), &(val_hdl)); memcpy(sample128_2_char.attr_hdl, &val_hdl, sizeof(uint16_t)); status = attmdb_att_set_value(char_hdl, sizeof(sample128_2_char), (uint8_t *)&sample128_2_char); //add cfg attribute status = attmdb_add_attribute(sample128_env.sample128_shdl, sizeof(uint16_t), ATT_UUID_16_LEN, (uint8_t*) &att_decl_cfg, PERM(RD, ENABLE) | PERM(WR, ENABLE), &(val_hdl)); //Disable sample128 service attmdb_svc_set_permission(sample128_env.sample128_shdl, PERM(SVC, DISABLE)); //Go to Idle State //If we are here, database has been fulfilled with success, go to idle state ke_state_set(TASK_SAMPLE128, SAMPLE128_IDLE); } //Send CFM to application struct sample128_create_db_cfm * cfm = KE_MSG_ALLOC(SAMPLE128_CREATE_DB_CFM, src_id, TASK_SAMPLE128, sample128_create_db_cfm); cfm->status = status; ke_msg_send(cfm); return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Handles reception of the @ref GATT_WRITE_CMD_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_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) { uint8_t char_code = SAMPLE128_ERR_CHAR; uint8_t status = PRF_APP_ERROR; if (KE_IDX_GET(src_id) == sample128_env.con_info.conidx) { if (param->handle == sample128_env.sample128_shdl + SAMPLE128_1_IDX_VAL) { char_code = SAMPLE128_1_CHAR; } if (param->handle == sample128_env.sample128_shdl + SAMPLE128_2_IDX_CFG) { char_code = SAMPLE128_2_CFG; } if (char_code == SAMPLE128_1_CHAR) { //Save value in DB attmdb_att_set_value(param->handle, sizeof(uint8_t), (uint8_t *)¶m->value[0]); if(param->last) { sample128_send_val(param->value[0]); leds_state.flag = param->value[0]; //app_sample128_start_leds(); } status = PRF_ERR_OK; } else if (char_code == SAMPLE128_2_CFG) { // Written value uint16_t ntf_cfg; // Extract value before check ntf_cfg = co_read16p(¶m->value[0]); // Only update configuration if value for stop or notification enable if ((ntf_cfg == PRF_CLI_STOP_NTFIND) || (ntf_cfg == PRF_CLI_START_NTF)) { //Save value in DB attmdb_att_set_value(param->handle, sizeof(uint16_t), (uint8_t *)¶m->value[0]); // Conserve information in environment if (ntf_cfg == PRF_CLI_START_NTF) { // Ntf cfg bit set to 1 sample128_env.feature |= PRF_CLI_START_NTF; } else { // Ntf cfg bit set to 0 sample128_env.feature &= ~PRF_CLI_START_NTF; } status = PRF_ERR_OK; } } } // Send Write Response atts_write_rsp_send(sample128_env.con_info.conidx, param->handle, status); return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @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 GL2C_CODE_ATT_WR_CMD_IND 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 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) { uint8_t *meas_intv_range; uint16_t meas_intv_rge[2]; uint16_t value = 0x0000; uint8_t status = PRF_ERR_OK; uint8_t char_code = 0; if (KE_IDX_GET(src_id) == htpt_env.con_info.conidx) { //Extract value before check memcpy(&value, &(param->value), sizeof(uint16_t)); //Measurement Interval Char. - Value if (param->handle == (htpt_env.shdl + htpt_env.att_tbl[HTPT_MEAS_INTV_CHAR] + 1)) { /* * Get Measurement Interval range in database * Valid Range descriptor exists because measurement interval is writable */ attmdb_att_get_value(param->handle + htpt_get_valid_rge_offset(), &meas_intv_rge[0], &meas_intv_range); memcpy(&meas_intv_rge[0], meas_intv_range, sizeof(uint16_t)); memcpy(&meas_intv_rge[1], meas_intv_range + 2, sizeof(uint16_t)); //Check if value to write is in allowed range if (((value >= meas_intv_rge[0]) && (value <= meas_intv_rge[1])) || (value == 0)) { //Send APP the indication with the new value struct htpt_meas_intv_chg_ind * ind = KE_MSG_ALLOC(HTPT_MEAS_INTV_CHG_IND, htpt_env.con_info.appid, TASK_HTPT, htpt_meas_intv_chg_ind); memcpy(&ind->intv, &value, sizeof(uint16_t)); ke_msg_send(ind); } else { status = HTPT_OUT_OF_RANGE_ERR_CODE; } } else { //Temperature Measurement Char. - Client Char. Configuration if (param->handle == (htpt_env.shdl + HTS_IDX_TEMP_MEAS_IND_CFG)) { char_code = HTPT_TEMP_MEAS_CHAR; if (value == PRF_CLI_STOP_NTFIND) { htpt_env.features &= ~HTPT_MASK_TEMP_MEAS_CFG; } else if (value == PRF_CLI_START_IND) { htpt_env.features |= HTPT_MASK_TEMP_MEAS_CFG; } else { //Invalid value status = HTPT_OUT_OF_RANGE_ERR_CODE; } } //Measurement Interval Char. - Client Char. Configuration else if (param->handle == (htpt_env.shdl + htpt_env.att_tbl[HTPT_MEAS_INTV_CHAR] + 2)) { char_code = HTPT_MEAS_INTV_CHAR; if (value == PRF_CLI_STOP_NTFIND) { htpt_env.features &= ~HTPT_MASK_MEAS_INTV_CFG; } else if (value == PRF_CLI_START_IND) { htpt_env.features |= HTPT_MASK_MEAS_INTV_CFG; } else { //Invalid value status = HTPT_OUT_OF_RANGE_ERR_CODE; } } //Intermediate Measurement Char. - Client Char. Configuration else if (param->handle == (htpt_env.shdl + htpt_env.att_tbl[HTPT_INTERM_TEMP_CHAR] + 2)) { char_code = HTPT_INTERM_TEMP_CHAR; if (value == PRF_CLI_STOP_NTFIND) { htpt_env.features &= ~HTPT_MASK_INTM_MEAS_CFG; } else if (value == PRF_CLI_START_NTF) { htpt_env.features |= HTPT_MASK_INTM_MEAS_CFG; } else { //Invalid value status = HTPT_OUT_OF_RANGE_ERR_CODE; } } if (status == PRF_ERR_OK) { if(param->last) { //Inform APP of configuration change struct htpt_cfg_indntf_ind * ind = KE_MSG_ALLOC(HTPT_CFG_INDNTF_IND, htpt_env.con_info.appid, TASK_HTPT, htpt_cfg_indntf_ind); ind->conhdl = gapc_get_conhdl(htpt_env.con_info.conidx); ind->char_code = char_code; memcpy(&ind->cfg_val, &value, sizeof(uint16_t)); ke_msg_send(ind); } } } if (status == PRF_ERR_OK) { //Update the attribute value attmdb_att_set_value(param->handle, sizeof(uint16_t), (uint8_t *)&value); } //Send write response atts_write_rsp_send(htpt_env.con_info.conidx, param->handle, status); } return (KE_MSG_CONSUMED); }
static int htpt_create_db_req_handler(ke_msg_id_t const msgid, struct htpt_create_db_req const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { //Valid Range value uint32_t valid_range; //Service content flag uint16_t cfg_flag; uint16_t total_size = 0; uint8_t nb_att = 0; uint8_t status = ATT_ERR_NO_ERROR; uint8_t i; // Save profile ID htpt_env.con_info.prf_id = TASK_HTPT; //Save database configuration htpt_env.features = param->features; //Compute Attribute Table and save it in environment cfg_flag = htpt_compute_att_table(param->features); status = attm_svc_create_db(&htpt_env.shdl, (uint8_t *)&cfg_flag, HTS_IDX_NB, &htpt_env.att_tbl[0], dest_id, &htpt_att_db[0]); //Disable the service and set optional features if (status == ATT_ERR_NO_ERROR) { //Disable service status = attmdb_svc_set_permission(htpt_env.shdl, PERM(SVC, DISABLE)); //Set optional properties and permissions if (htpt_env.att_tbl[HTPT_MEAS_INTV_CHAR] != 0x00) { nb_att = ATT_CHAR_PROP_RD; total_size = PERM(RD, ENABLE); i = 1; if ((param->features & HTPT_MEAS_INTV_IND_SUP) == HTPT_MEAS_INTV_IND_SUP) { nb_att |= ATT_CHAR_PROP_IND; total_size |= PERM(IND, ENABLE); i++; } if ((param->features & HTPT_MEAS_INTV_WR_SUP) == HTPT_MEAS_INTV_WR_SUP) { nb_att |= ATT_CHAR_PROP_WR; total_size |= PERM(WR, UNAUTH); i++; //Set Measurement Interval Char. - Valid Range value if ((param->valid_range_min) < (param->valid_range_max)) { valid_range = param->valid_range_min | (param->valid_range_max << 16); } else { //If minimal and maximal values are the same or if maximal value is upper than minimal value valid_range = HTPT_MEAS_INTV_DFLT_MIN | (HTPT_MEAS_INTV_DFLT_MAX << 16); } status = attmdb_att_set_value(htpt_env.shdl + htpt_env.att_tbl[HTPT_MEAS_INTV_CHAR] + i, sizeof(uint32_t), (uint8_t *)&valid_range); } attmdb_att_partial_value_update(htpt_env.shdl + htpt_env.att_tbl[HTPT_MEAS_INTV_CHAR], 0, 1, &nb_att); attmdb_att_set_permission(htpt_env.shdl + htpt_env.att_tbl[HTPT_MEAS_INTV_CHAR] + 1, total_size); } //If we are here, database has been fulfilled with success, go to idle test ke_state_set(TASK_HTPT, HTPT_IDLE); } //Send response to application struct htpt_create_db_cfm * cfm = KE_MSG_ALLOC(HTPT_CREATE_DB_CFM, src_id, TASK_HTPT, htpt_create_db_cfm); cfm->status = status; ke_msg_send(cfm); return (KE_MSG_CONSUMED); }