/**@brief Function for processing a REPORT NUM RECORDS request. * * @param[in] p_cgms Service instance. * @param[in] p_racp_request Request to be executed. */ static void report_num_records_request_execute(nrf_ble_cgms_t * p_cgms, ble_racp_value_t * p_racp_request) { uint16_t total_records; uint16_t num_records; total_records = cgms_db_num_records_get(); num_records = 0; if (p_racp_request->operator == RACP_OPERATOR_ALL) { num_records = total_records; } else if ((p_racp_request->operator == RACP_OPERATOR_FIRST) || (p_racp_request->operator == RACP_OPERATOR_LAST)) { if (total_records > 0) { num_records = 1; } } p_cgms->racp_data.pending_racp_response.opcode = RACP_OPCODE_NUM_RECS_RESPONSE; p_cgms->racp_data.pending_racp_response.operator = RACP_OPERATOR_NULL; p_cgms->racp_data.pending_racp_response.operand_len = sizeof(uint16_t); p_cgms->racp_data.pending_racp_response.p_operand = p_cgms->racp_data.pending_racp_response_operand; p_cgms->racp_data.pending_racp_response_operand[0] = num_records & 0xFF; p_cgms->racp_data.pending_racp_response_operand[1] = num_records >> 8; racp_send(p_cgms, &p_cgms->racp_data.pending_racp_response); }
/**@brief Function for adding a characteristic for the Continuous Glucose Meter Measurement. * * @param[in] p_cgms Service instance. * * @return NRF_SUCCESS if characteristic was successfully added, otherwise an error code. */ ret_code_t cgms_meas_char_add(nrf_ble_cgms_t * p_cgms) { uint8_t num_recs; uint8_t encoded_cgms_meas[NRF_BLE_CGMS_MEAS_LEN_MAX]; ble_add_char_params_t add_char_params; ble_cgms_rec_t initial_cgms_rec_value; memset(&add_char_params, 0, sizeof(add_char_params)); memset(&initial_cgms_rec_value, 0, sizeof(ble_cgms_rec_t)); num_recs = cgms_db_num_records_get(); if (num_recs > 0) { uint32_t err_code = cgms_db_record_get(num_recs - 1, &initial_cgms_rec_value); if (err_code != NRF_SUCCESS) { return err_code; } } add_char_params.uuid = BLE_UUID_CGM_MEASUREMENT; add_char_params.max_len = NRF_BLE_CGMS_MEAS_LEN_MAX; add_char_params.init_len = cgms_meas_encode(p_cgms, &initial_cgms_rec_value.meas, encoded_cgms_meas); add_char_params.p_init_value = encoded_cgms_meas; add_char_params.is_var_len = true; add_char_params.char_props.notify = true; add_char_params.cccd_write_access = SEC_JUST_WORKS; return characteristic_add(p_cgms->service_handle, &add_char_params, &p_cgms->char_handles.measurment); }
/**@brief Function for setting next sequence number by reading the last record in the data base. * * @return NRF_SUCCESS on successful initialization of service, otherwise an error code. */ static uint32_t next_sequence_number_set(void) { uint16_t num_records; ble_cgms_rec_t rec; num_records = cgms_db_num_records_get(); if (num_records > 0) { // Get last record uint32_t err_code = cgms_db_record_get(num_records - 1, &rec); if (err_code != NRF_SUCCESS) { return err_code; } } return NRF_SUCCESS; }
/**@brief Function for responding to the FIRST or the LAST operation. * * @param[in] p_cgms Service instance. * * @return NRF_SUCCESS on success, otherwise an error code. */ static uint32_t racp_report_records_first_last(nrf_ble_cgms_t * p_cgms) { uint32_t err_code; ble_cgms_rec_t rec; uint16_t total_records; uint8_t nb_rec_to_send = 1; total_records = cgms_db_num_records_get(); if ((p_cgms->racp_data.racp_proc_records_reported != 0) || (total_records == 0)) { p_cgms->cgms_com_state = STATE_NO_COMM; } else { if (p_cgms->racp_data.racp_proc_operator == RACP_OPERATOR_FIRST) { err_code = cgms_db_record_get(0, &rec); if (err_code != NRF_SUCCESS) { return err_code; } } else if (p_cgms->racp_data.racp_proc_operator == RACP_OPERATOR_LAST) { err_code = cgms_db_record_get(total_records - 1, &rec); if (err_code != NRF_SUCCESS) { return err_code; } } err_code = cgms_meas_send(p_cgms, &rec, &nb_rec_to_send); if (err_code != NRF_SUCCESS) { return err_code; } p_cgms->racp_data.racp_proc_record_ndx++; } return NRF_SUCCESS; }
/**@brief Function for responding to the ALL operation. * * @param[in] p_cgms Service instance. * * @return NRF_SUCCESS on success, otherwise an error code. */ static uint32_t racp_report_records_all(nrf_ble_cgms_t * p_cgms) { uint16_t total_records = cgms_db_num_records_get(); uint16_t cur_nb_rec; uint8_t i; uint8_t nb_rec_to_send; if (p_cgms->racp_data.racp_proc_record_ndx >= total_records) { p_cgms->cgms_com_state = STATE_NO_COMM; } else { uint32_t err_code; ble_cgms_rec_t rec[NRF_BLE_CGMS_MEAS_REC_PER_NOTIF_MAX]; cur_nb_rec = total_records - p_cgms->racp_data.racp_proc_record_ndx; if (cur_nb_rec > NRF_BLE_CGMS_MEAS_REC_PER_NOTIF_MAX) { cur_nb_rec = NRF_BLE_CGMS_MEAS_REC_PER_NOTIF_MAX; } nb_rec_to_send = (uint8_t)cur_nb_rec; for (i = 0; i < cur_nb_rec; i++) { err_code = cgms_db_record_get(p_cgms->racp_data.racp_proc_record_ndx + i, &(rec[i])); if (err_code != NRF_SUCCESS) { return err_code; } } err_code = cgms_meas_send(p_cgms, rec, &nb_rec_to_send); if (err_code != NRF_SUCCESS) { return err_code; } p_cgms->racp_data.racp_proc_record_ndx += nb_rec_to_send; } return NRF_SUCCESS; }
/**@brief Function for responding to the GREATER OR EQUAL operation. * * @param[in] p_cgms Service instance. * * @return NRF_SUCCESS on success, otherwise an error code. */ static ret_code_t racp_report_records_greater_equal(nrf_ble_cgms_t * p_cgms) { uint16_t total_rec_nb; uint16_t total_rec_nb_to_send; uint16_t rec_nb_left_to_send; uint8_t nb_rec_to_send; uint16_t offset; uint16_t i; if(p_cgms->racp_data.racp_request.operand_len != 2) { if (p_cgms->error_handler != NULL) { p_cgms->error_handler(NRF_ERROR_INVALID_LENGTH); } } total_rec_nb = cgms_db_num_records_get(); offset = uint16_decode(p_cgms->racp_data.racp_request.p_operand); if (offset >= total_rec_nb) { p_cgms->cgms_com_state = STATE_NO_COMM; return NRF_SUCCESS; } total_rec_nb_to_send = total_rec_nb - offset; if (p_cgms->racp_data.racp_proc_record_ndx >= total_rec_nb_to_send) { p_cgms->cgms_com_state = STATE_NO_COMM; } else { uint32_t err_code; ble_cgms_rec_t rec[NRF_BLE_CGMS_MEAS_REC_PER_NOTIF_MAX]; rec_nb_left_to_send = total_rec_nb_to_send - p_cgms->racp_data.racp_proc_records_reported; if (rec_nb_left_to_send > NRF_BLE_CGMS_MEAS_REC_PER_NOTIF_MAX) { nb_rec_to_send = NRF_BLE_CGMS_MEAS_REC_PER_NOTIF_MAX; } else { nb_rec_to_send = (uint8_t)rec_nb_left_to_send; } p_cgms->racp_data.racp_proc_record_ndx = offset; for (i = 0; i < nb_rec_to_send; i++) { err_code = cgms_db_record_get(p_cgms->racp_data.racp_proc_record_ndx + i, &(rec[i])); if (err_code != NRF_SUCCESS) { return err_code; } } err_code = cgms_meas_send(p_cgms, rec, &nb_rec_to_send); if (err_code != NRF_SUCCESS) { return err_code; } p_cgms->racp_data.racp_proc_record_ndx += nb_rec_to_send; } return NRF_SUCCESS; }