|
+++ ble_cts_c.c 2021-08-15 18:42:45.000000000 -0700 |
|
@@ -56,6 +56,8 @@ |
|
#define CTS_C_CURRENT_TIME_EXPECTED_LENGTH 10 /**< | Year |Month |Day |Hours |Minutes |Seconds |Weekday |Fraction|Reason | |
|
| 2 bytes |1 byte |1 byte |1 byte |1 byte |1 byte |1 byte |1 byte |1 byte | = 10 bytes. */ |
|
|
|
+static void current_time_read(ble_cts_c_t * p_cts, ble_evt_t const * p_ble_evt); |
|
+static void local_time_information_read(ble_cts_c_t * p_cts, ble_evt_t const * p_ble_evt); |
|
|
|
/**@brief Function for intercepting errors of GATTC and the BLE GATT Queue. |
|
* |
|
@@ -106,13 +108,17 @@ |
|
// Find the handles of the Current Time characteristic. |
|
for (uint32_t i = 0; i < p_evt->params.discovered_db.char_count; i++) |
|
{ |
|
- if (p_evt->params.discovered_db.charateristics[i].characteristic.uuid.uuid == |
|
- BLE_UUID_CURRENT_TIME_CHAR) |
|
- { |
|
- // Found Current Time characteristic. Store CCCD and value handle and break. |
|
- evt.params.char_handles.cts_handle = p_chars->characteristic.handle_value; |
|
- evt.params.char_handles.cts_cccd_handle = p_chars->cccd_handle; |
|
- break; |
|
+ switch(p_chars[i].characteristic.uuid.uuid) { |
|
+ case BLE_UUID_LOCAL_TIME_INFORMATION_CHAR: |
|
+ NRF_LOG_INFO("Local Time Information discovered at peer."); |
|
+ evt.params.char_handles.ltis_handle = p_chars[i].characteristic.handle_value; |
|
+ break; |
|
+ case BLE_UUID_CURRENT_TIME_CHAR: |
|
+ evt.params.char_handles.cts_handle = p_chars[i].characteristic.handle_value; |
|
+ evt.params.char_handles.cts_cccd_handle = p_chars[i].cccd_handle; |
|
+ break; |
|
+ default: |
|
+ break; |
|
} |
|
} |
|
|
|
@@ -151,6 +157,7 @@ |
|
p_cts->error_handler = p_cts_init->error_handler; |
|
p_cts->conn_handle = BLE_CONN_HANDLE_INVALID; |
|
p_cts->char_handles.cts_handle = BLE_GATT_HANDLE_INVALID; |
|
+ p_cts->char_handles.ltis_handle = BLE_GATT_HANDLE_INVALID; |
|
p_cts->char_handles.cts_cccd_handle = BLE_GATT_HANDLE_INVALID; |
|
p_cts->p_gatt_queue = p_cts_init->p_gatt_queue; |
|
|
|
@@ -261,6 +268,32 @@ |
|
} |
|
|
|
|
|
+ |
|
+static void on_read_rsp(ble_cts_c_t * p_cts, ble_evt_t const * p_ble_evt) { |
|
+ ret_code_t err_code; |
|
+ ble_gattc_evt_read_rsp_t const * p_response = &p_ble_evt->evt.gattc_evt.params.read_rsp; |
|
+ |
|
+ // Check if the event is on the link for this instance and the event handler is present. |
|
+ if ((p_cts->evt_handler == NULL) || |
|
+ (p_cts->conn_handle != p_ble_evt->evt.gattc_evt.conn_handle)) |
|
+ { |
|
+ return; |
|
+ } |
|
+ |
|
+ if ( (p_cts->char_handles.ltis_handle != BLE_GATT_HANDLE_INVALID) |
|
+ && (p_response->handle == p_cts->char_handles.ltis_handle) |
|
+ && (p_cts->evt_handler != NULL)) |
|
+ { |
|
+ local_time_information_read(p_cts, p_ble_evt); |
|
+ } else if ( (p_cts->char_handles.cts_handle != BLE_GATT_HANDLE_INVALID) |
|
+ && (p_response->handle == p_cts->char_handles.cts_handle) |
|
+ && (p_cts->evt_handler != NULL)) |
|
+ { |
|
+ current_time_read(p_cts, p_ble_evt); |
|
+ } |
|
+} |
|
+ |
|
+ |
|
/**@brief Function for reading the Current Time. The time is decoded, and then validated. |
|
* Depending on the outcome, the CTS event handler will be called with |
|
* the Current Time event or an invalid time event. |
|
@@ -310,6 +343,61 @@ |
|
} |
|
} |
|
|
|
+/** @brief Function for decoding a local_time_information payload |
|
+ * @param[in] p_local_time_info Local Time Info structure. |
|
+ * @param[in] p_data Pointer to the buffer containing the Local Time Information. |
|
+ * @param[in] length Length of the buffer containing the Local Time Information. |
|
+ * |
|
+ * @retval NRF_SUCCESS If the time struct is valid. |
|
+ * @retval NRF_ERROR_DATA_SIZE If the length does not match the expected size of the data. |
|
+ */ |
|
+static uint32_t local_time_information_decode(local_time_info_char_t *p_local_time_info, |
|
+ uint8_t const * p_data, |
|
+ uint32_t const length) |
|
+{ |
|
+ if (length != 2) |
|
+ { |
|
+ return NRF_ERROR_DATA_SIZE; |
|
+ } |
|
+ |
|
+ memcpy(p_local_time_info, p_data, sizeof(local_time_info_char_t)); |
|
+ |
|
+ return NRF_SUCCESS; |
|
+} |
|
+ |
|
+ |
|
+/**@brief Function for reading the Current Time. The time is decoded, and then validated. |
|
+ * Depending on the outcome, the CTS event handler will be called with |
|
+ * the Current Time event or an invalid time event. |
|
+ * |
|
+ * @param[in] p_cts Current Time Service client structure. |
|
+ * @param[in] p_ble_evt Event received from the BLE stack. |
|
+ */ |
|
+ |
|
+static void local_time_information_read(ble_cts_c_t * p_cts, ble_evt_t const * p_ble_evt) |
|
+{ |
|
+ ble_cts_c_evt_t evt; |
|
+ uint32_t err_code = NRF_SUCCESS; |
|
+ |
|
+ if (p_ble_evt->evt.gattc_evt.gatt_status == BLE_GATT_STATUS_SUCCESS) |
|
+ { |
|
+ err_code = local_time_information_decode(&evt.params.local_time_info, |
|
+ p_ble_evt->evt.gattc_evt.params.read_rsp.data, |
|
+ sizeof(local_time_info_char_t)); |
|
+ |
|
+ if (err_code != NRF_SUCCESS) |
|
+ { |
|
+ // The data length was invalid. Decoding was not completed. |
|
+ evt.evt_type = BLE_CTS_C_EVT_INVALID_LOCAL_TIME; |
|
+ } else { |
|
+ evt.evt_type = BLE_CTS_C_EVT_LOCAL_TIME_INFO; |
|
+ } |
|
+ p_cts->evt_handler(p_cts, &evt); |
|
+ } |
|
+} |
|
+ |
|
+ |
|
+ |
|
|
|
/**@brief Function for handling the Disconnect event. |
|
* |
|
@@ -333,6 +421,7 @@ |
|
|
|
p_cts->evt_handler(p_cts, &evt); |
|
p_cts->char_handles.cts_handle = BLE_GATT_HANDLE_INVALID; |
|
+ p_cts->char_handles.ltis_handle = BLE_GATT_HANDLE_INVALID; |
|
p_cts->char_handles.cts_cccd_handle = BLE_GATT_HANDLE_INVALID; |
|
} |
|
} |
|
@@ -346,7 +435,7 @@ |
|
switch (p_ble_evt->header.evt_id) |
|
{ |
|
case BLE_GATTC_EVT_READ_RSP: |
|
- current_time_read(p_cts, p_ble_evt); |
|
+ on_read_rsp(p_cts, p_ble_evt); |
|
break; |
|
|
|
case BLE_GAP_EVT_DISCONNECTED: |
|
@@ -380,6 +469,26 @@ |
|
return nrf_ble_gq_item_add(p_cts->p_gatt_queue, &read_req, p_cts->conn_handle); |
|
} |
|
|
|
+uint32_t ble_cts_c_local_time_information_read(ble_cts_c_t const * p_cts) |
|
+{ |
|
+ if (!ble_cts_c_is_cts_discovered(p_cts)) |
|
+ { |
|
+ return NRF_ERROR_NOT_FOUND; |
|
+ } |
|
+ |
|
+ nrf_ble_gq_req_t read_req; |
|
+ |
|
+ memset(&read_req, 0, sizeof(nrf_ble_gq_req_t)); |
|
+ |
|
+ read_req.type = NRF_BLE_GQ_REQ_GATTC_READ; |
|
+ read_req.error_handler.cb = gatt_error_handler; |
|
+ read_req.error_handler.p_ctx = (ble_cts_c_t *)p_cts; |
|
+ read_req.params.gattc_read.handle = p_cts->char_handles.ltis_handle; |
|
+ read_req.params.gattc_read.offset = 0; |
|
+ |
|
+ return nrf_ble_gq_item_add(p_cts->p_gatt_queue, &read_req, p_cts->conn_handle); |
|
+} |
|
+ |
|
|
|
uint32_t ble_cts_c_handles_assign(ble_cts_c_t * p_cts, |
|
const uint16_t conn_handle, |
|
@@ -392,6 +501,7 @@ |
|
{ |
|
p_cts->char_handles.cts_cccd_handle = p_peer_handles->cts_cccd_handle; |
|
p_cts->char_handles.cts_handle = p_peer_handles->cts_handle; |
|
+ p_cts->char_handles.ltis_handle = p_peer_handles->ltis_handle; |
|
} |
|
|
|
return nrf_ble_gq_conn_handle_register(p_cts->p_gatt_queue, conn_handle); |