aboutsummaryrefslogtreecommitdiff
path: root/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_sst.c
diff options
context:
space:
mode:
Diffstat (limited to 'thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_sst.c')
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_sst.c235
1 files changed, 235 insertions, 0 deletions
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_sst.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_sst.c
new file mode 100644
index 0000000..b6b2fcd
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_sst.c
@@ -0,0 +1,235 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include <stdint.h>
+#include <string.h>
+#include <time.h>
+#include "ble.h"
+#include "ble_srv_common.h"
+#include "nrf_ble_cgms.h"
+#include "cgms_sst.h"
+
+
+void sst_decode(ble_cgms_sst_t * p_sst, const uint8_t * p_data, const uint16_t len)
+{
+ uint32_t index;
+
+ if (len != NRF_BLE_CGMS_SST_LEN)
+ {
+ return;
+ }
+
+ index = ble_date_time_decode(&p_sst->date_time, p_data);
+
+ p_sst->time_zone = p_data[index++];
+ p_sst->dst = p_data[index++];
+}
+
+
+void convert_ble_time_c_time(ble_cgms_sst_t * p_sst, struct tm * p_c_time_date)
+{
+ p_c_time_date->tm_sec = p_sst->date_time.seconds;
+ p_c_time_date->tm_min = p_sst->date_time.minutes;
+ p_c_time_date->tm_hour = p_sst->date_time.hours;
+ p_c_time_date->tm_mday = p_sst->date_time.day;
+ p_c_time_date->tm_mon = p_sst->date_time.month;
+ p_c_time_date->tm_year = p_sst->date_time.year - 1900;
+
+ // Ignore daylight saving for this conversion.
+ p_c_time_date->tm_isdst = 0;
+}
+
+
+void calc_sst(uint16_t offset, struct tm * p_c_time_date)
+{
+ time_t c_time_in_sec;
+
+ c_time_in_sec = mktime(p_c_time_date);
+ c_time_in_sec = c_time_in_sec - (offset * 60);
+ *p_c_time_date = *(localtime(&c_time_in_sec));
+
+ if (p_c_time_date->tm_isdst == 1)
+ {
+ // Daylight saving time is not used and must be removed.
+ p_c_time_date->tm_hour = p_c_time_date->tm_hour - 1;
+ p_c_time_date->tm_isdst = 0;
+ }
+}
+
+
+static void convert_c_time_ble_time(ble_cgms_sst_t * p_sst, struct tm * p_c_time_date)
+{
+ p_sst->date_time.seconds = p_c_time_date->tm_sec;
+ p_sst->date_time.minutes = p_c_time_date->tm_min;
+ p_sst->date_time.hours = p_c_time_date->tm_hour;
+ p_sst->date_time.day = p_c_time_date->tm_mday;
+ p_sst->date_time.month = p_c_time_date->tm_mon;
+ p_sst->date_time.year = p_c_time_date->tm_year + 1900;
+}
+
+
+static uint8_t sst_encode(ble_cgms_sst_t * p_sst, uint8_t * p_encoded_sst)
+{
+ uint8_t len;
+
+ len = ble_date_time_encode(&p_sst->date_time, p_encoded_sst);
+
+ p_encoded_sst[len++] = p_sst->time_zone;
+ p_encoded_sst[len++] = p_sst->dst;
+
+ return len;
+}
+
+
+static ret_code_t cgm_update_sst(nrf_ble_cgms_t * p_cgms, ble_gatts_evt_write_t const * p_evt_write)
+{
+ ble_cgms_sst_t sst;
+ struct tm c_time_and_date;
+
+ memset(&sst, 0, sizeof(ble_cgms_sst_t));
+
+ sst_decode(&sst, p_evt_write->data, p_evt_write->len);
+ convert_ble_time_c_time(&sst, &c_time_and_date);
+ calc_sst(p_cgms->sensor_status.time_offset, &c_time_and_date);
+ convert_c_time_ble_time(&sst, &c_time_and_date);
+
+ return cgms_sst_set(p_cgms, &sst);
+}
+
+
+/**@brief Function for handling the Glucose session start time write event.
+ *
+ * @param[in] p_cgms Service instance.
+ * @param[in] p_evt_write WRITE event to be handled.
+ */
+static void on_sst_value_write(nrf_ble_cgms_t * p_cgms, ble_gatts_evt_write_t const * p_evt_write)
+{
+ ble_gatts_rw_authorize_reply_params_t auth_reply;
+ uint32_t err_code;
+
+ memset(&auth_reply, 0, sizeof(auth_reply));
+
+ auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE;
+ auth_reply.params.write.update = 1;
+ auth_reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS;
+
+ err_code = sd_ble_gatts_rw_authorize_reply(p_cgms->conn_handle, &auth_reply);
+ if (err_code != NRF_SUCCESS)
+ {
+ if (p_cgms->error_handler != NULL)
+ {
+ p_cgms->error_handler(err_code);
+ }
+ }
+
+ err_code = cgm_update_sst(p_cgms, p_evt_write);
+ if (err_code != NRF_SUCCESS)
+ {
+ if (p_cgms->error_handler != NULL)
+ {
+ p_cgms->error_handler(err_code);
+ }
+ }
+}
+
+
+/**@brief Function for adding a characteristic for the Session Start Time.
+ *
+ * @param[in] p_cgms Service instance.
+ *
+ * @return NRF_SUCCESS if characteristic was successfully added, otherwise an error code.
+ */
+ret_code_t cgms_sst_char_add(nrf_ble_cgms_t * p_cgms)
+{
+ ble_add_char_params_t add_char_params;
+ uint8_t init_value[NRF_BLE_CGMS_SST_LEN] = {0};
+
+ memset(&add_char_params, 0, sizeof(add_char_params));
+
+ add_char_params.uuid = BLE_UUID_CGM_SESSION_START_TIME;
+ add_char_params.max_len = NRF_BLE_CGMS_SST_LEN;
+
+ add_char_params.init_len = NRF_BLE_CGMS_SST_LEN;
+ add_char_params.p_init_value = init_value;
+
+ add_char_params.read_access = SEC_JUST_WORKS;
+ add_char_params.write_access = SEC_JUST_WORKS;
+ add_char_params.is_defered_write = 1;
+ add_char_params.char_props.write = true;
+ add_char_params.char_props.read = true;
+
+ return characteristic_add(p_cgms->service_handle,
+ &add_char_params,
+ &p_cgms->char_handles.sst);
+}
+
+
+ret_code_t cgms_sst_set(nrf_ble_cgms_t * p_cgms, ble_cgms_sst_t * p_sst)
+{
+ uint16_t conn_handle;
+ uint16_t value_handle;
+ ble_gatts_value_t sst_val;
+ uint8_t encoded_start_session_time[NRF_BLE_CGMS_SST_LEN];
+ uint8_t gatts_value_set_len = 0;
+
+ gatts_value_set_len = sst_encode(p_sst, encoded_start_session_time);
+ conn_handle = p_cgms->conn_handle;
+ value_handle = p_cgms->char_handles.sst.value_handle;
+ memset(&sst_val, 0, sizeof(ble_gatts_value_t));
+ sst_val.len = gatts_value_set_len;
+ sst_val.p_value = encoded_start_session_time;
+ sst_val.offset = 0;
+
+ return (sd_ble_gatts_value_set(conn_handle, value_handle, &sst_val));
+}
+
+
+void cgms_sst_on_rw_auth_req(nrf_ble_cgms_t * p_cgms,
+ ble_gatts_evt_rw_authorize_request_t const * p_auth_req)
+{
+ if (p_auth_req->type == BLE_GATTS_AUTHORIZE_TYPE_WRITE)
+ {
+ if (p_auth_req->request.write.handle == p_cgms->char_handles.sst.value_handle)
+ {
+ on_sst_value_write(p_cgms, &p_auth_req->request.write);
+ }
+ }
+}
+
+