aboutsummaryrefslogtreecommitdiff
path: root/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ancs_c
diff options
context:
space:
mode:
Diffstat (limited to 'thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ancs_c')
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ancs_c/ancs_app_attr_get.c367
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ancs_c/ancs_app_attr_get.h66
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ancs_c/ancs_attr_parser.c392
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ancs_c/ancs_attr_parser.h77
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ancs_c/ancs_tx_buffer.c113
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ancs_c/ancs_tx_buffer.h103
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ancs_c/nrf_ble_ancs_c.c652
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ancs_c/nrf_ble_ancs_c.h604
8 files changed, 2374 insertions, 0 deletions
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ancs_c/ancs_app_attr_get.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ancs_c/ancs_app_attr_get.c
new file mode 100644
index 0000000..38ed510
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ancs_c/ancs_app_attr_get.c
@@ -0,0 +1,367 @@
+/**
+ * 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.
+ *
+ */
+/* Disclaimer: This client implementation of the Apple Notification Center Service can and will be changed at any time by Nordic Semiconductor ASA.
+ * Server implementations such as the ones found in iOS can be changed at any time by Apple and may cause this client implementation to stop working.
+ */
+
+#include "ancs_app_attr_get.h"
+#include "nrf_ble_ancs_c.h"
+#include "ancs_tx_buffer.h"
+#include "sdk_macros.h"
+#include "nrf_log.h"
+#include "string.h"
+
+#define GATTC_OPCODE_SIZE 1 /**< Size of the GATTC OPCODE. */
+#define GATTC_ATTR_HANDLE_SIZE 4 /**< Size of the Attribute handle Size. */
+
+
+#define ANCS_GATTC_WRITE_PAYLOAD_LEN_MAX (BLE_GATT_ATT_MTU_DEFAULT - GATTC_OPCODE_SIZE - GATTC_ATTR_HANDLE_SIZE) /**< Maximum Length of the data we can send in one write. */
+
+
+/**@brief Enum to keep track of the state based encoding while requesting App attributes. */
+typedef enum
+{
+ APP_ATTR_COMMAND_ID, /**< Currently encoding the Command ID. */
+ APP_ATTR_APP_ID, /**< Currently encoding the App ID. */
+ APP_ATTR_ATTR_ID, /**< Currently encoding the Attribute ID. */
+ APP_ATTR_DONE /**< Encoding done. */
+}encode_app_attr_t;
+
+
+/**@brief Function for determening if an attribute is desired to get.
+ *
+ * @param[in] p_ancs iOS notification structure. This structure must be supplied by
+ * the application. It identifies the particular client instance to use.
+ *
+ * @return True If it is requested
+ * @return False If it is not be requested.
+*/
+static bool app_attr_is_requested(ble_ancs_c_t * p_ancs, uint32_t attr_id)
+{
+ if (p_ancs->ancs_app_attr_list[attr_id].get == true)
+ {
+ return true;
+ }
+ return false;
+}
+
+/**@brief Function for counting the number of attributes that will be requested upon a Get App Attribute.
+ *
+ * @param[in] p_ancs iOS notification structure. This structure must be supplied by
+ * the application. It identifies the particular client instance to use.
+ *
+ * @return Number of attributes that will be requested upon a Get App Attribute.
+*/
+static uint32_t app_attr_nb_to_get(ble_ancs_c_t * p_ancs)
+{
+ uint32_t attr_nb_to_get = 0;
+ for (uint32_t i = 0; i < (sizeof(p_ancs->ancs_app_attr_list)/sizeof(ble_ancs_c_attr_list_t)); i++)
+ {
+ if (app_attr_is_requested(p_ancs,i))
+ {
+ attr_nb_to_get++;
+ }
+ }
+ return attr_nb_to_get;
+}
+
+
+/**@brief Function for encoding the Command ID as part of assembling a "Get App Attributes" command.
+ *
+ * @param[in] conn_handle Connection handle for where the prepared write will be executed.
+ * @param[in] handle_value The handle that will receive the execute command.
+ * @param[in] p_offset Pointer to the offset for the write.
+ * @param[in] p_index Pointer to the length encoded so far for the current write.
+ * @param[in,out] p_msg Pointer to the tx message that has been filled out and will be added to
+ * tx queue in this function.
+ */
+static void queued_write_tx_message(uint16_t conn_handle,
+ uint16_t handle_value,
+ uint16_t * p_offset,
+ uint32_t * p_index,
+ tx_message_t * p_msg)
+{
+ NRF_LOG_DEBUG("Starting new TX message.");
+
+ p_msg->conn_handle = conn_handle;
+ p_msg->type = WRITE_REQ;
+ p_msg->req.write_req.gattc_params.len = *p_index;
+ p_msg->req.write_req.gattc_params.handle = handle_value;
+ p_msg->req.write_req.gattc_params.p_value = p_msg->req.write_req.gattc_value;
+
+ p_msg->req.write_req.gattc_params.offset = *p_offset;
+
+ p_msg->req.write_req.gattc_params.write_op = BLE_GATT_OP_PREP_WRITE_REQ;
+
+ tx_buffer_insert(p_msg);
+}
+
+
+/**@brief Function for encoding the Command ID as part of assembling a "Get App Attributes" command.
+ *
+ * @param[in] p_ancs iOS notification structure. This structure must be supplied by
+ * the application. It identifies the particular client instance to use.
+ * @param[in] p_index Pointer to the length encoded so far for the current write.
+ * @param[in] p_offset Pointer to the accumulated offset for the next write.
+ * @param[in,out] p_msg Pointer to the tx message that will be filled out in this function.
+ */
+static encode_app_attr_t app_attr_encode_cmd_id(ble_ancs_c_t * p_ancs,
+ uint32_t * index,
+ tx_message_t * p_msg)
+{
+ NRF_LOG_DEBUG("Encoding Command ID");
+
+ // Encode Command ID.
+ p_msg->req.write_req.gattc_value[(*index)++] = BLE_ANCS_COMMAND_ID_GET_APP_ATTRIBUTES;
+ return APP_ATTR_APP_ID;
+}
+
+/**@brief Function for encoding the App Identifier as part of assembling a "Get App Attributes" command.
+ *
+ * @param[in] p_ancs iOS notification structure. This structure must be supplied by
+ * the application. It identifies the particular client instance to use.
+ * @param[in] p_app_id The App ID for the App which we will request App Attributes for.
+ * @param[in] app_id_len Length of the App ID.
+ * @param[in] p_index Pointer to the length encoded so far for the current write.
+ * @param[in] p_offset Pointer to the accumulated offset for the next write.
+ * @param[in] p_app_id_bytes_encoded_count Variable to keep count of the encoded APP ID bytes.
+ * As long as it is lower than the length of the App ID,
+ * parsing will continue.
+ */
+static encode_app_attr_t app_attr_encode_app_id(ble_ancs_c_t * p_ancs,
+ uint32_t * p_index,
+ uint16_t * p_offset,
+ tx_message_t * p_msg,
+ const uint8_t * p_app_id,
+ const uint32_t app_id_len,
+ uint32_t * p_app_id_bytes_encoded_count)
+{
+ NRF_LOG_DEBUG("Encoding APP ID");
+ if (*p_index >= ANCS_GATTC_WRITE_PAYLOAD_LEN_MAX)
+ {
+ queued_write_tx_message(p_ancs->conn_handle, p_ancs->service.control_point_char.handle_value, p_offset, p_index, p_msg);
+ *(p_offset) += *p_index;
+ *p_index = 0;
+ }
+
+ //Encode App Identifier.
+ if (*p_app_id_bytes_encoded_count == app_id_len)
+ {
+ p_msg->req.write_req.gattc_value[(*p_index)++] = '\0';
+ (*p_app_id_bytes_encoded_count)++;
+ }
+ NRF_LOG_DEBUG("%c", p_app_id[(*p_app_id_bytes_encoded_count)]);
+ if (*p_app_id_bytes_encoded_count < app_id_len)
+ {
+ p_msg->req.write_req.gattc_value[(*p_index)++] = p_app_id[(*p_app_id_bytes_encoded_count)++];
+ }
+ if (*p_app_id_bytes_encoded_count > app_id_len)
+ {
+ return APP_ATTR_ATTR_ID;
+ }
+ return APP_ATTR_APP_ID;
+}
+
+/**@brief Function for encoding the Attribute ID as part of assembling a "Get App Attributes" command.
+ *
+ * @param[in] p_ancs iOS notification structure. This structure must be supplied by
+ *
+ * @param[in] p_index Pointer to the length encoded so far for the current write.
+ * @param[in] p_offset Pointer to the accumulated offset for the next write.
+ * @param[in,out] p_msg Pointer to the tx message that will be filled out in this function.
+ * @param[in] p_attr_count Pointer to a variable that iterates the possible App Attributes.
+ */
+static encode_app_attr_t app_attr_encode_attr_id(ble_ancs_c_t * p_ancs,
+ uint32_t * p_index,
+ uint16_t * p_offset,
+ tx_message_t * p_msg,
+ uint32_t * p_attr_count,
+ uint32_t * attr_get_total_nb)
+{
+ NRF_LOG_DEBUG("Encoding Attribute ID");
+ if ((*p_index) >= ANCS_GATTC_WRITE_PAYLOAD_LEN_MAX)
+ {
+ queued_write_tx_message(p_ancs->conn_handle,
+ p_ancs->service.control_point_char.handle_value,
+ p_offset, p_index, p_msg);
+ *(p_offset) += *p_index;
+ *p_index = 0;
+ }
+ //Encode Attribute ID.
+ if (*p_attr_count < BLE_ANCS_NB_OF_APP_ATTR)
+ {
+ if (app_attr_is_requested(p_ancs, *p_attr_count))
+ {
+ p_msg->req.write_req.gattc_value[(*p_index)] = *p_attr_count;
+ p_ancs->number_of_requested_attr++;
+ (*p_index)++;
+ NRF_LOG_DEBUG("offset %i", *p_offset);
+ }
+ (*p_attr_count)++;
+ }
+ if (*p_attr_count == BLE_ANCS_NB_OF_APP_ATTR)
+ {
+ return APP_ATTR_DONE;
+ }
+ return APP_ATTR_APP_ID;
+}
+
+/**@brief Function for writing the execute write command to a handle for a given connection.
+ *
+ * @param[in] conn_handle Connection handle for where the prepared write will be executed.
+ * @param[in] handle_value The handle that will receive the execute command.
+ * @param[in] p_msg Pointer to the message that will be filled out in this function and then
+ * added to the tx queue.
+ */
+static void app_attr_execute_write(uint16_t conn_handle, uint16_t handle_value, tx_message_t * p_msg)
+{
+ NRF_LOG_DEBUG("Sending Execute Write.");
+ memset(p_msg,0,sizeof(tx_message_t));
+
+ p_msg->req.write_req.gattc_params.handle = handle_value;
+ p_msg->req.write_req.gattc_params.p_value = p_msg->req.write_req.gattc_value;
+ p_msg->req.write_req.gattc_params.offset = 0;
+ p_msg->req.write_req.gattc_params.write_op = BLE_GATT_OP_EXEC_WRITE_REQ;
+ p_msg->req.write_req.gattc_params.flags = BLE_GATT_EXEC_WRITE_FLAG_PREPARED_WRITE;
+
+ p_msg->req.write_req.gattc_params.len = 0;
+ p_msg->conn_handle = conn_handle;
+ p_msg->type = WRITE_REQ;
+
+ tx_buffer_insert(p_msg);
+}
+
+
+/**@brief Function for sending a get App Attributes request.
+ *
+ * @details Since the APP id may not fit in a single write, we use long write
+ * with a state machine to encode the Get App Attribute request.
+ *
+ * @param[in] p_ancs iOS notification structure. This structure must be supplied by
+ * the application. It identifies the particular client instance to use.
+ * @param[in] p_app_id The App ID for the App which we will request App Attributes for.
+ * @param[in] app_id_len Length of the App ID.
+ *
+*/
+static uint32_t app_attr_get(ble_ancs_c_t * p_ancs,
+ const uint8_t * p_app_id,
+ uint32_t app_id_len)
+{
+ uint32_t index = 0;
+ uint32_t attr_bytes_encoded_count = 0;
+ uint16_t offset = 0;
+ uint32_t app_id_bytes_encoded_count = 0;
+ encode_app_attr_t state = APP_ATTR_COMMAND_ID;
+ p_ancs->number_of_requested_attr = 0;
+
+ uint32_t attr_get_total_nb = app_attr_nb_to_get(p_ancs);
+ tx_message_t p_msg;
+
+ memset(&p_msg, 0, sizeof(tx_message_t));
+
+ while (state != APP_ATTR_DONE)
+ {
+ switch (state)
+ {
+ case APP_ATTR_COMMAND_ID:
+ state = app_attr_encode_cmd_id(p_ancs,
+ &index,
+ &p_msg);
+ break;
+ case APP_ATTR_APP_ID:
+ state = app_attr_encode_app_id(p_ancs,
+ &index,
+ &offset,
+ &p_msg,
+ p_app_id,
+ app_id_len,
+ &app_id_bytes_encoded_count);
+ break;
+ case APP_ATTR_ATTR_ID:
+ state = app_attr_encode_attr_id(p_ancs,
+ &index,
+ &offset,
+ &p_msg,
+ &attr_bytes_encoded_count,
+ &attr_get_total_nb);
+ break;
+ case APP_ATTR_DONE:
+ break;
+ default:
+ break;
+ }
+ }
+ queued_write_tx_message(p_ancs->conn_handle,
+ p_ancs->service.control_point_char.handle_value,
+ &offset,
+ &index,
+ &p_msg);
+
+ app_attr_execute_write(p_ancs->conn_handle,
+ p_ancs->service.control_point_char.handle_value,
+ &p_msg);
+
+ p_ancs->parse_info.expected_number_of_attrs = p_ancs->number_of_requested_attr;
+
+ tx_buffer_process();
+ return NRF_SUCCESS;
+}
+
+
+uint32_t ancs_c_app_attr_request(ble_ancs_c_t * p_ancs,
+ const uint8_t * p_app_id,
+ uint32_t len)
+{
+ uint32_t err_code;
+
+ if (len == 0)
+ {
+ return NRF_ERROR_DATA_SIZE;
+ }
+ if (p_app_id[len] != '\0') // App id to be requestes must be NULL terminated
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ p_ancs->parse_info.parse_state = COMMAND_ID;
+ err_code = app_attr_get(p_ancs, p_app_id, len);
+ VERIFY_SUCCESS(err_code);
+ return NRF_SUCCESS;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ancs_c/ancs_app_attr_get.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ancs_c/ancs_app_attr_get.h
new file mode 100644
index 0000000..c942f73
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ancs_c/ancs_app_attr_get.h
@@ -0,0 +1,66 @@
+/**
+ * Copyright (c) 2012 - 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.
+ *
+ */
+#ifndef ANCS_APP_ATTR_GET_H__
+#define ANCS_APP_ATTR_GET_H__
+
+#include "nrf_ble_ancs_c.h"
+/** @file
+ *
+ * @addtogroup ble_ancs_c
+ * @{
+ */
+
+/**@brief Function for requesting attributes for an app.
+ *
+ * @param[in] p_ancs iOS notification structure. This structure must be supplied by
+ * the application. It identifies the particular client instance to use.
+ * @param[in] app_id App identifier of the app for which to request app attributes.
+ * @param[in] len Length of the app identifier.
+ *
+ * @retval NRF_SUCCESS If all operations were successful. Otherwise, an error code is returned.
+ */
+uint32_t ancs_c_app_attr_request(ble_ancs_c_t * p_ancs,
+ const uint8_t * app_id,
+ uint32_t len);
+
+/** @} */
+
+#endif // ANCS_APP_ATTR_GET_H__
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ancs_c/ancs_attr_parser.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ancs_c/ancs_attr_parser.c
new file mode 100644
index 0000000..60f18e0
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ancs_c/ancs_attr_parser.c
@@ -0,0 +1,392 @@
+/**
+ * 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.
+ *
+ */
+/* Disclaimer: This client implementation of the Apple Notification Center Service can and will be changed at any time by Nordic Semiconductor ASA.
+ * Server implementations such as the ones found in iOS can be changed at any time by Apple and may cause this client implementation to stop working.
+ */
+
+ #include "nrf_ble_ancs_c.h"
+ #include "ancs_attr_parser.h"
+ #include "nrf_log.h"
+
+
+static bool all_req_attrs_parsed(ble_ancs_c_t * p_ancs)
+{
+ if (p_ancs->parse_info.expected_number_of_attrs == 0)
+ {
+ return true;
+ }
+ return false;
+}
+
+static bool attr_is_requested(ble_ancs_c_t * p_ancs, ble_ancs_c_attr_t attr)
+{
+ if (p_ancs->parse_info.p_attr_list[attr.attr_id].get == true)
+ {
+ return true;
+ }
+ return false;
+}
+
+
+/**@brief Function for parsing command id and notification id.
+ * Used in the @ref parse_get_notif_attrs_response state machine.
+ *
+ * @details UID and command ID will be received only once at the beginning of the first
+ * GATTC notification of a new attribute request for a given iOS notification.
+ *
+ * @param[in] p_ancs Pointer to an ANCS instance to which the event belongs.
+ * @param[in] p_data_src Pointer to data that was received from the Notification Provider.
+ * @param[in] index Pointer to an index that helps us keep track of the current data to be parsed.
+ *
+ * @return The next parse state.
+ */
+static ble_ancs_c_parse_state_t command_id_parse(ble_ancs_c_t * p_ancs,
+ const uint8_t * p_data_src,
+ uint32_t * index)
+{
+ ble_ancs_c_parse_state_t parse_state;
+
+ p_ancs->parse_info.command_id = (ble_ancs_c_cmd_id_val_t) p_data_src[(*index)++];
+
+ switch (p_ancs->parse_info.command_id)
+ {
+ case BLE_ANCS_COMMAND_ID_GET_NOTIF_ATTRIBUTES:
+ p_ancs->evt.evt_type = BLE_ANCS_C_EVT_NOTIF_ATTRIBUTE;
+ p_ancs->parse_info.p_attr_list = p_ancs->ancs_notif_attr_list;
+ p_ancs->parse_info.nb_of_attr = BLE_ANCS_NB_OF_NOTIF_ATTR;
+ parse_state = NOTIF_UID;
+ break;
+
+ case BLE_ANCS_COMMAND_ID_GET_APP_ATTRIBUTES:
+ p_ancs->evt.evt_type = BLE_ANCS_C_EVT_APP_ATTRIBUTE;
+ p_ancs->parse_info.p_attr_list = p_ancs->ancs_app_attr_list;
+ p_ancs->parse_info.nb_of_attr = BLE_ANCS_NB_OF_APP_ATTR;
+ parse_state = APP_ID;
+ break;
+
+ default:
+ //no valid command_id, abort the rest of the parsing procedure.
+ NRF_LOG_DEBUG("Invalid Command ID");
+ parse_state = DONE;
+ break;
+ }
+ return parse_state;
+}
+
+
+static ble_ancs_c_parse_state_t notif_uid_parse(ble_ancs_c_t * p_ancs,
+ const uint8_t * p_data_src,
+ uint32_t * index)
+{
+ p_ancs->evt.notif_uid = uint32_decode(&p_data_src[*index]);
+ *index += sizeof(uint32_t);
+ return ATTR_ID;
+}
+
+static ble_ancs_c_parse_state_t app_id_parse(ble_ancs_c_t * p_ancs,
+ const uint8_t * p_data_src,
+ uint32_t * index)
+{
+ p_ancs->evt.app_id[p_ancs->parse_info.current_app_id_index] = p_data_src[(*index)++];
+
+ if (p_ancs->evt.app_id[p_ancs->parse_info.current_app_id_index] != '\0')
+ {
+ p_ancs->parse_info.current_app_id_index++;
+ return APP_ID;
+ }
+ else
+ {
+ return ATTR_ID;
+ }
+}
+
+/**@brief Function for parsing the id of an iOS attribute.
+ * Used in the @ref parse_get_notif_attrs_response state machine.
+ *
+ * @details We only request attributes that are registered with @ref ble_ancs_c_attr_add
+ * once they have been reveiced we stop parsing.
+ *
+ * @param[in] p_ancs Pointer to an ANCS instance to which the event belongs.
+ * @param[in] p_data_src Pointer to data that was received from the Notification Provider.
+ * @param[in] index Pointer to an index that helps us keep track of the current data to be parsed.
+ *
+ * @return The next parse state.
+ */
+static ble_ancs_c_parse_state_t attr_id_parse(ble_ancs_c_t * p_ancs,
+ const uint8_t * p_data_src,
+ uint32_t * index)
+{
+ p_ancs->evt.attr.attr_id = p_data_src[(*index)++];
+
+ if (p_ancs->evt.attr.attr_id >= p_ancs->parse_info.nb_of_attr)
+ {
+ NRF_LOG_DEBUG("Attribute ID Invalid.");
+ return DONE;
+ }
+ p_ancs->evt.attr.p_attr_data = p_ancs->parse_info.p_attr_list[p_ancs->evt.attr.attr_id].p_attr_data;
+
+ if (all_req_attrs_parsed(p_ancs))
+ {
+ NRF_LOG_DEBUG("All requested attributes received. ");
+ return DONE;
+ }
+ else
+ {
+ if (attr_is_requested(p_ancs, p_ancs->evt.attr))
+ {
+ p_ancs->parse_info.expected_number_of_attrs--;
+ }
+ NRF_LOG_DEBUG("Attribute ID %i ", p_ancs->evt.attr.attr_id);
+ return ATTR_LEN1;
+ }
+}
+
+
+/**@brief Function for parsing the length of an iOS attribute.
+ * Used in the @ref parse_get_notif_attrs_response state machine.
+ *
+ * @details The Length is 2 bytes. Since there is a chance we reveice the bytes in two different
+ * GATTC notifications, we parse only the first byte here and then set the state machine
+ * ready to parse the next byte.
+ *
+ * @param[in] p_ancs Pointer to an ANCS instance to which the event belongs.
+ * @param[in] p_data_src Pointer to data that was received from the Notification Provider.
+ * @param[in] index Pointer to an index that helps us keep track of the current data to be parsed.
+ *
+ * @return The next parse state.
+ */
+static ble_ancs_c_parse_state_t attr_len1_parse(ble_ancs_c_t * p_ancs, const uint8_t * p_data_src, uint32_t * index)
+{
+ p_ancs->evt.attr.attr_len = p_data_src[(*index)++];
+ return ATTR_LEN2;
+}
+
+/**@brief Function for parsing the length of an iOS attribute.
+ * Used in the @ref parse_get_notif_attrs_response state machine.
+ *
+ * @details Second byte of the length field. If the length is zero, it means that the attribute is not
+ * present and the state machine is set to parse the next attribute.
+ *
+ * @param[in] p_ancs Pointer to an ANCS instance to which the event belongs.
+ * @param[in] p_data_src Pointer to data that was received from the Notification Provider.
+ * @param[in] index Pointer to an index that helps us keep track of the current data to be parsed.
+ *
+ * @return The next parse state.
+ */
+static ble_ancs_c_parse_state_t attr_len2_parse(ble_ancs_c_t * p_ancs, const uint8_t * p_data_src, uint32_t * index)
+{
+ p_ancs->evt.attr.attr_len |= (p_data_src[(*index)++] << 8);
+ p_ancs->parse_info.current_attr_index = 0;
+
+ if (p_ancs->evt.attr.attr_len != 0)
+ {
+ //If the attribute has a length but there is no allocated space for this attribute
+ if ((p_ancs->parse_info.p_attr_list[p_ancs->evt.attr.attr_id].attr_len == 0) ||
+ (p_ancs->parse_info.p_attr_list[p_ancs->evt.attr.attr_id].p_attr_data == NULL))
+ {
+ return ATTR_SKIP;
+ }
+ else
+ {
+ return ATTR_DATA;
+ }
+ }
+ else
+ {
+
+ NRF_LOG_DEBUG("Attribute LEN %i ", p_ancs->evt.attr.attr_len);
+ if (attr_is_requested(p_ancs, p_ancs->evt.attr))
+ {
+ p_ancs->evt_handler(&p_ancs->evt);
+ }
+ if (all_req_attrs_parsed(p_ancs))
+ {
+ return DONE;
+ }
+ else
+ {
+ return ATTR_ID;
+ }
+ }
+}
+
+
+/**@brief Function for parsing the data of an iOS attribute.
+ * Used in the @ref parse_get_notif_attrs_response state machine.
+ *
+ * @details Read the data of the attribute into our local buffer.
+ *
+ * @param[in] p_ancs Pointer to an ANCS instance to which the event belongs.
+ * @param[in] p_data_src Pointer to data that was received from the Notification Provider.
+ * @param[in] index Pointer to an index that helps us keep track of the current data to be parsed.
+ *
+ * @return The next parse state.
+ */
+static ble_ancs_c_parse_state_t attr_data_parse(ble_ancs_c_t * p_ancs,
+ const uint8_t * p_data_src,
+ uint32_t * index)
+{
+ // We have not reached the end of the attribute, nor our max allocated internal size.
+ // Proceed with copying data over to our buffer.
+ if ( (p_ancs->parse_info.current_attr_index < p_ancs->parse_info.p_attr_list[p_ancs->evt.attr.attr_id].attr_len)
+ && (p_ancs->parse_info.current_attr_index < p_ancs->evt.attr.attr_len))
+ {
+ //NRF_LOG_DEBUG("Byte copied to buffer: %c", p_data_src[(*index)]); // Un-comment this line to see every byte of an attribute as it is parsed. Commented out by default since it can overflow the uart buffer.
+ p_ancs->evt.attr.p_attr_data[p_ancs->parse_info.current_attr_index++] = p_data_src[(*index)++];
+ }
+
+ // We have reached the end of the attribute, or our max allocated internal size.
+ // Stop copying data over to our buffer. NUL-terminate at the current index.
+ if ( (p_ancs->parse_info.current_attr_index == p_ancs->evt.attr.attr_len) ||
+ (p_ancs->parse_info.current_attr_index == p_ancs->parse_info.p_attr_list[p_ancs->evt.attr.attr_id].attr_len - 1))
+ {
+ if (attr_is_requested(p_ancs, p_ancs->evt.attr))
+ {
+ p_ancs->evt.attr.p_attr_data[p_ancs->parse_info.current_attr_index] = '\0';
+ }
+
+ // If our max buffer size is smaller than the remaining attribute data, we must
+ // increase index to skip the data until the start of the next attribute.
+ if (p_ancs->parse_info.current_attr_index < p_ancs->evt.attr.attr_len)
+ {
+ return ATTR_SKIP;
+ }
+ NRF_LOG_DEBUG("Attribute finished!");
+ if (attr_is_requested(p_ancs, p_ancs->evt.attr))
+ {
+ p_ancs->evt_handler(&p_ancs->evt);
+ }
+ if (all_req_attrs_parsed(p_ancs))
+ {
+ return DONE;
+ }
+ else
+ {
+ return ATTR_ID;
+ }
+ }
+ return ATTR_DATA;
+}
+
+
+static ble_ancs_c_parse_state_t attr_skip(ble_ancs_c_t * p_ancs, const uint8_t * p_data_src, uint32_t * index)
+{
+ // We have not reached the end of the attribute, nor our max allocated internal size.
+ // Proceed with copying data over to our buffer.
+ if (p_ancs->parse_info.current_attr_index < p_ancs->evt.attr.attr_len)
+ {
+ p_ancs->parse_info.current_attr_index++;
+ (*index)++;
+ }
+ // At the end of the attribute, determine if it should be passed to event handler and
+ // continue parsing the next attribute ID if we are not done with all the attributes.
+ if (p_ancs->parse_info.current_attr_index == p_ancs->evt.attr.attr_len)
+ {
+ if (attr_is_requested(p_ancs, p_ancs->evt.attr))
+ {
+ p_ancs->evt_handler(&p_ancs->evt);
+ }
+ if (all_req_attrs_parsed(p_ancs))
+ {
+ return DONE;
+ }
+ else
+ {
+ return ATTR_ID;
+ }
+ }
+ return ATTR_SKIP;
+}
+
+
+void ancs_parse_get_attrs_response(ble_ancs_c_t * p_ancs,
+ const uint8_t * p_data_src,
+ const uint16_t hvx_data_len)
+{
+ uint32_t index;
+
+ for (index = 0; index < hvx_data_len;)
+ {
+ switch (p_ancs->parse_info.parse_state)
+ {
+ case COMMAND_ID:
+ p_ancs->parse_info.parse_state = command_id_parse(p_ancs, p_data_src, &index);
+ break;
+
+ case NOTIF_UID:
+ p_ancs->parse_info.parse_state = notif_uid_parse(p_ancs, p_data_src, &index);
+ break;
+
+ case APP_ID:
+ p_ancs->parse_info.parse_state = app_id_parse(p_ancs, p_data_src, &index);
+ break;
+
+ case ATTR_ID:
+ p_ancs->parse_info.parse_state = attr_id_parse(p_ancs, p_data_src, &index);
+ break;
+
+ case ATTR_LEN1:
+ p_ancs->parse_info.parse_state = attr_len1_parse(p_ancs, p_data_src, &index);
+ break;
+
+ case ATTR_LEN2:
+ p_ancs->parse_info.parse_state = attr_len2_parse(p_ancs, p_data_src, &index);
+ break;
+
+ case ATTR_DATA:
+ p_ancs->parse_info.parse_state = attr_data_parse(p_ancs, p_data_src, &index);
+ break;
+
+ case ATTR_SKIP:
+ p_ancs->parse_info.parse_state = attr_skip(p_ancs, p_data_src, &index);
+ break;
+
+ case DONE:
+ NRF_LOG_DEBUG("Parse state: Done ");
+ index = hvx_data_len;
+ break;
+
+ default:
+ // Default case will never trigger intentionally. Go to the DONE state to minimize the consequences.
+ p_ancs->parse_info.parse_state = DONE;
+ break;
+ }
+ }
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ancs_c/ancs_attr_parser.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ancs_c/ancs_attr_parser.h
new file mode 100644
index 0000000..92cea55
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ancs_c/ancs_attr_parser.h
@@ -0,0 +1,77 @@
+/**
+ * Copyright (c) 2012 - 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.
+ *
+ */
+#ifndef BLE_ANCS_ATTR_PARSER_H__
+#define BLE_ANCS_ATTR_PARSER_H__
+
+#include "nrf_ble_ancs_c.h"
+
+/** @file
+ *
+ * @addtogroup ble_ancs_c
+ * @{
+ */
+
+/**@brief Function for parsing notification or app attribute response data.
+ *
+ * @details The data that comes from the Notification Provider can be much longer than what
+ * would fit in a single GATTC notification. Therefore, this function relies on a
+ * state-oriented switch case.
+ * UID and command ID will be received only once at the beginning of the first
+ * GATTC notification of a new attribute request for a given iOS notification.
+ * After this, we can loop several ATTR_ID > LENGTH > DATA > ATTR_ID > LENGTH > DATA until
+ * we have received all attributes we wanted as a Notification Consumer.
+ * The Notification Provider can also simply stop sending attributes.
+ *
+ * 1 byte | 4 bytes |1 byte |2 bytes |... X bytes ... |1 bytes| 2 bytes| ... X bytes ...
+ * --------|-------------|-------|--------|----------------|-------|--------|----------------
+ * CMD_ID | NOTIF_UID |ATTR_ID| LENGTH | DATA |ATTR_ID| LENGTH | DATA
+ *
+ * @param[in] p_ancs Pointer to an ANCS instance to which the event belongs.
+ * @param[in] p_data_src Pointer to data that was received from the Notification Provider.
+ * @param[in] hvx_data_len Length of the data that was received from the Notification Provider.
+ */
+void ancs_parse_get_attrs_response(ble_ancs_c_t * p_ancs,
+ const uint8_t * p_data_src,
+ const uint16_t hvx_data_len);
+
+/** @} */
+
+#endif // BLE_ANCS_ATTR_PARSER_H__
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ancs_c/ancs_tx_buffer.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ancs_c/ancs_tx_buffer.c
new file mode 100644
index 0000000..91e6886
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ancs_c/ancs_tx_buffer.c
@@ -0,0 +1,113 @@
+/**
+ * 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.
+ *
+ */
+/* Disclaimer: This client implementation of the Apple Notification Center Service can and will be changed at any time by Nordic Semiconductor ASA.
+ * Server implementations such as the ones found in iOS can be changed at any time by Apple and may cause this client implementation to stop working.
+ */
+
+ #include "nrf_ble_ancs_c.h"
+ #include "ancs_tx_buffer.h"
+ #include "sdk_macros.h"
+ #include "nrf_log.h"
+ #include "string.h"
+
+
+static tx_message_t m_tx_buffer[TX_BUFFER_SIZE]; /**< Transmit buffer for messages to be transmitted to the Notification Provider. */
+static uint32_t m_tx_insert_index = 0; /**< Current index in the transmit buffer where the next message should be inserted. */
+static uint32_t m_tx_index = 0; /**< Current index in the transmit buffer from where the next message to be transmitted resides. */
+
+
+void tx_buffer_init(void)
+{
+ memset(m_tx_buffer, 0, sizeof(m_tx_buffer));
+}
+
+
+void tx_buffer_insert(tx_message_t * p_msg)
+{
+
+ memset(&(m_tx_buffer[m_tx_insert_index]), 0, sizeof(m_tx_buffer)/sizeof(tx_message_t));
+
+ m_tx_buffer[m_tx_insert_index].conn_handle = p_msg->conn_handle;
+ m_tx_buffer[m_tx_insert_index].type = p_msg->type;
+
+ m_tx_buffer[m_tx_insert_index].req.write_req.gattc_params.handle = p_msg->req.write_req.gattc_params.handle;
+ m_tx_buffer[m_tx_insert_index].req.write_req.gattc_params.len = p_msg->req.write_req.gattc_params.len;
+ m_tx_buffer[m_tx_insert_index].req.write_req.gattc_params.write_op = p_msg->req.write_req.gattc_params.write_op;
+ m_tx_buffer[m_tx_insert_index].req.write_req.gattc_params.flags = p_msg->req.write_req.gattc_params.flags;
+ m_tx_buffer[m_tx_insert_index].req.write_req.gattc_params.p_value = m_tx_buffer[m_tx_insert_index].req.write_req.gattc_value;
+ m_tx_buffer[m_tx_insert_index].req.write_req.gattc_params.offset = p_msg->req.write_req.gattc_params.offset;
+
+ if (p_msg->type == WRITE_REQ)
+ {
+ memcpy(m_tx_buffer[m_tx_insert_index].req.write_req.gattc_value,
+ p_msg->req.write_req.gattc_value,
+ WRITE_MESSAGE_LENGTH);
+ }
+
+ m_tx_insert_index++;
+ m_tx_insert_index &= TX_BUFFER_MASK;
+}
+
+
+
+void tx_buffer_process(void)
+{
+ if (m_tx_index != m_tx_insert_index)
+ {
+ uint32_t err_code;
+
+ if (m_tx_buffer[m_tx_index].type == READ_REQ)
+ {
+ err_code = sd_ble_gattc_read(m_tx_buffer[m_tx_index].conn_handle,
+ m_tx_buffer[m_tx_index].req.read_handle,
+ 0);
+ }
+ else
+ {
+ err_code = sd_ble_gattc_write(m_tx_buffer[m_tx_index].conn_handle,
+ &m_tx_buffer[m_tx_index].req.write_req.gattc_params);
+ }
+ if (err_code == NRF_SUCCESS)
+ {
+ ++m_tx_index;
+ m_tx_index &= TX_BUFFER_MASK;
+ }
+ }
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ancs_c/ancs_tx_buffer.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ancs_c/ancs_tx_buffer.h
new file mode 100644
index 0000000..6953438
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ancs_c/ancs_tx_buffer.h
@@ -0,0 +1,103 @@
+/**
+ * Copyright (c) 2012 - 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.
+ *
+ */
+#ifndef ANCS_TX_BUFFER_H__
+#define ANCS_TX_BUFFER_H__
+
+#include "nrf_ble_ancs_c.h"
+
+/** @file
+ *
+ * @addtogroup ble_ancs_c
+ * @{
+ */
+
+#define TX_BUFFER_MASK 0x07 //!< TX buffer mask. Must be a mask of contiguous zeroes followed by a contiguous sequence of ones: 000...111.
+#define TX_BUFFER_SIZE (TX_BUFFER_MASK + 1) //!< Size of the send buffer, which is 1 bigger than the mask.
+#define WRITE_MESSAGE_LENGTH 20 //!< Length of the write message for the CCCD/control point.
+
+/**@brief ANCS request types.
+ */
+typedef enum
+{
+ READ_REQ = 1, /**< Type identifying that this TX message is a read request. */
+ WRITE_REQ /**< Type identifying that this TX message is a write request. */
+} tx_request_t;
+
+
+/**@brief Structure for writing a message to the central, thus the Control Point or CCCD.
+ */
+typedef struct
+{
+ uint8_t gattc_value[WRITE_MESSAGE_LENGTH]; //!< The message to write.
+ ble_gattc_write_params_t gattc_params; //!< GATTC parameters for this message.
+} write_params_t;
+
+
+/**@brief Data to be transmitted to the connected master.
+ */
+typedef struct
+{
+ uint16_t conn_handle; //!< Connection handle to be used when transmitting this message.
+ tx_request_t type; //!< Type of this message (read or write message).
+ union
+ {
+ uint16_t read_handle; //!< Read request message.
+ write_params_t write_req; //!< Write request message.
+ } req;
+} tx_message_t;
+
+/**@brief Function for clearing the TX buffer.
+ *
+ * @details Always call this function before using the TX buffer.
+*/
+void tx_buffer_init(void);
+
+/**@brief Function for moving the pointer of the ring buffer to the next element.
+*/
+void tx_buffer_insert(tx_message_t * p_msg);
+
+/**@brief Function for passing any pending request from the buffer to the stack.
+*/
+void tx_buffer_process(void);
+
+/** @} */
+
+#endif // ANCS_TX_BUFFER_H__
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ancs_c/nrf_ble_ancs_c.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ancs_c/nrf_ble_ancs_c.c
new file mode 100644
index 0000000..0ba177f
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ancs_c/nrf_ble_ancs_c.c
@@ -0,0 +1,652 @@
+/**
+ * Copyright (c) 2012 - 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.
+ *
+ */
+/* Disclaimer: This client implementation of the Apple Notification Center Service can and will be changed at any time by Nordic Semiconductor ASA.
+ * Server implementations such as the ones found in iOS can be changed at any time by Apple and may cause this client implementation to stop working.
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(BLE_ANCS_C)
+#include "nrf_ble_ancs_c.h"
+#include "ancs_tx_buffer.h"
+#include "ancs_attr_parser.h"
+#include "ancs_app_attr_get.h"
+#include "ble_err.h"
+#include "ble_srv_common.h"
+#include "ble_db_discovery.h"
+#include "app_error.h"
+#define NRF_LOG_MODULE_NAME ble_ancs_c
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#define BLE_ANCS_NOTIF_EVT_ID_INDEX 0 /**< Index of the Event ID field when parsing notifications. */
+#define BLE_ANCS_NOTIF_FLAGS_INDEX 1 /**< Index of the Flags field when parsing notifications. */
+#define BLE_ANCS_NOTIF_CATEGORY_ID_INDEX 2 /**< Index of the Category ID field when parsing notifications. */
+#define BLE_ANCS_NOTIF_CATEGORY_CNT_INDEX 3 /**< Index of the Category Count field when parsing notifications. */
+#define BLE_ANCS_NOTIF_NOTIF_UID 4 /**< Index of the Notification UID field when patsin notifications. */
+
+#define BLE_CCCD_NOTIFY_BIT_MASK 0x0001 /**< Enable notification bit. */
+
+#define TIME_STRING_LEN 15 /**< Unicode Technical Standard (UTS) #35 date format pattern "yyyyMMdd'T'HHmmSS" + "'\0'". */
+
+
+/**@brief 128-bit service UUID for the Apple Notification Center Service. */
+ble_uuid128_t const ble_ancs_base_uuid128 =
+{
+ {
+ // 7905F431-B5CE-4E99-A40F-4B1E122D00D0
+ 0xd0, 0x00, 0x2d, 0x12, 0x1e, 0x4b, 0x0f, 0xa4,
+ 0x99, 0x4e, 0xce, 0xb5, 0x31, 0xf4, 0x05, 0x79
+ }
+};
+
+
+/**@brief 128-bit control point UUID. */
+ble_uuid128_t const ble_ancs_cp_base_uuid128 =
+{
+ {
+ // 69d1d8f3-45e1-49a8-9821-9BBDFDAAD9D9
+ 0xd9, 0xd9, 0xaa, 0xfd, 0xbd, 0x9b, 0x21, 0x98,
+ 0xa8, 0x49, 0xe1, 0x45, 0xf3, 0xd8, 0xd1, 0x69
+ }
+};
+
+/**@brief 128-bit notification source UUID. */
+ble_uuid128_t const ble_ancs_ns_base_uuid128 =
+{
+ {
+ // 9FBF120D-6301-42D9-8C58-25E699A21DBD
+ 0xbd, 0x1d, 0xa2, 0x99, 0xe6, 0x25, 0x58, 0x8c,
+ 0xd9, 0x42, 0x01, 0x63, 0x0d, 0x12, 0xbf, 0x9f
+
+ }
+};
+
+/**@brief 128-bit data source UUID. */
+ble_uuid128_t const ble_ancs_ds_base_uuid128 =
+{
+ {
+ // 22EAC6E9-24D6-4BB5-BE44-B36ACE7C7BFB
+ 0xfb, 0x7b, 0x7c, 0xce, 0x6a, 0xb3, 0x44, 0xbe,
+ 0xb5, 0x4b, 0xd6, 0x24, 0xe9, 0xc6, 0xea, 0x22
+ }
+};
+
+
+/**@brief Function for handling Disconnected event received from the SoftDevice.
+ *
+ * @details This function check if the disconnect event is happening on the link
+ * associated with the current instance of the module, if so it will set its
+ * conn_handle to invalid.
+ *
+ * @param[in] p_ancs Pointer to the ANCS client structure.
+ * @param[in] p_ble_evt Pointer to the BLE event received.
+ */
+static void on_disconnected(ble_ancs_c_t * p_ancs, ble_evt_t const * p_ble_evt)
+{
+ if (p_ancs->conn_handle == p_ble_evt->evt.gap_evt.conn_handle)
+ {
+ p_ancs->conn_handle = BLE_CONN_HANDLE_INVALID;
+ }
+}
+
+
+void ble_ancs_c_on_db_disc_evt(ble_ancs_c_t * p_ancs, ble_db_discovery_evt_t * p_evt)
+{
+ NRF_LOG_DEBUG("Database Discovery handler called with event 0x%x", p_evt->evt_type);
+
+ ble_ancs_c_evt_t evt;
+ ble_gatt_db_char_t * p_chars;
+
+ p_chars = p_evt->params.discovered_db.charateristics;
+
+ // Check if the ANCS Service was discovered.
+ if ( (p_evt->evt_type == BLE_DB_DISCOVERY_COMPLETE)
+ && (p_evt->params.discovered_db.srv_uuid.uuid == ANCS_UUID_SERVICE)
+ && (p_evt->params.discovered_db.srv_uuid.type == p_ancs->service.service.uuid.type))
+ {
+ // Find the handles of the ANCS characteristic.
+ for (uint32_t i = 0; i < p_evt->params.discovered_db.char_count; i++)
+ {
+ switch (p_chars[i].characteristic.uuid.uuid)
+ {
+ case ANCS_UUID_CHAR_CONTROL_POINT:
+ NRF_LOG_INFO("Control Point Characteristic found.");
+ memcpy(&evt.service.control_point_char,
+ &p_chars[i].characteristic,
+ sizeof(ble_gattc_char_t));
+ break;
+
+ case ANCS_UUID_CHAR_DATA_SOURCE:
+ NRF_LOG_INFO("Data Source Characteristic found.");
+ memcpy(&evt.service.data_source_char,
+ &p_chars[i].characteristic,
+ sizeof(ble_gattc_char_t));
+ evt.service.data_source_cccd.handle = p_chars[i].cccd_handle;
+ break;
+
+ case ANCS_UUID_CHAR_NOTIFICATION_SOURCE:
+ NRF_LOG_INFO("Notification point Characteristic found.");
+ memcpy(&evt.service.notif_source_char,
+ &p_chars[i].characteristic,
+ sizeof(ble_gattc_char_t));
+ evt.service.notif_source_cccd.handle = p_chars[i].cccd_handle;
+ break;
+
+ default:
+ break;
+ }
+ }
+ evt.evt_type = BLE_ANCS_C_EVT_DISCOVERY_COMPLETE;
+ evt.conn_handle = p_evt->conn_handle;
+ p_ancs->evt_handler(&evt);
+ }
+ else
+ {
+ evt.evt_type = BLE_ANCS_C_EVT_DISCOVERY_FAILED;
+ p_ancs->evt_handler(&evt);
+ }
+}
+
+
+/**@brief Function for checking if data in an iOS notification is out of bounds.
+ *
+ * @param[in] notif An iOS notification.
+ *
+ * @retval NRF_SUCCESS If the notification is within bounds.
+ * @retval NRF_ERROR_INVALID_PARAM If the notification is out of bounds.
+ */
+static uint32_t ble_ancs_verify_notification_format(ble_ancs_c_evt_notif_t const * notif)
+{
+ if ( (notif->evt_id >= BLE_ANCS_NB_OF_EVT_ID)
+ || (notif->category_id >= BLE_ANCS_NB_OF_CATEGORY_ID))
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+ return NRF_SUCCESS;
+}
+
+/**@brief Function for receiving and validating notifications received from the Notification Provider.
+ *
+ * @param[in] p_ancs Pointer to an ANCS instance to which the event belongs.
+ * @param[in] p_data_src Pointer to data that was received from the Notification Provider.
+ * @param[in] hvx_len Length of the data that was received by the Notification Provider.
+ */
+static void parse_notif(ble_ancs_c_t const * p_ancs,
+ uint8_t const * p_data_src,
+ uint16_t const hvx_data_len)
+{
+ ble_ancs_c_evt_t ancs_evt;
+ uint32_t err_code;
+ if (hvx_data_len != BLE_ANCS_NOTIFICATION_DATA_LENGTH)
+ {
+ ancs_evt.evt_type = BLE_ANCS_C_EVT_INVALID_NOTIF;
+ p_ancs->evt_handler(&ancs_evt);
+ }
+
+ /*lint --e{415} --e{416} -save suppress Warning 415: possible access out of bond */
+ ancs_evt.notif.evt_id =
+ (ble_ancs_c_evt_id_values_t) p_data_src[BLE_ANCS_NOTIF_EVT_ID_INDEX];
+
+ ancs_evt.notif.evt_flags.silent =
+ (p_data_src[BLE_ANCS_NOTIF_FLAGS_INDEX] >> BLE_ANCS_EVENT_FLAG_SILENT) & 0x01;
+
+ ancs_evt.notif.evt_flags.important =
+ (p_data_src[BLE_ANCS_NOTIF_FLAGS_INDEX] >> BLE_ANCS_EVENT_FLAG_IMPORTANT) & 0x01;
+
+ ancs_evt.notif.evt_flags.pre_existing =
+ (p_data_src[BLE_ANCS_NOTIF_FLAGS_INDEX] >> BLE_ANCS_EVENT_FLAG_PREEXISTING) & 0x01;
+
+ ancs_evt.notif.evt_flags.positive_action =
+ (p_data_src[BLE_ANCS_NOTIF_FLAGS_INDEX] >> BLE_ANCS_EVENT_FLAG_POSITIVE_ACTION) & 0x01;
+
+ ancs_evt.notif.evt_flags.negative_action =
+ (p_data_src[BLE_ANCS_NOTIF_FLAGS_INDEX] >> BLE_ANCS_EVENT_FLAG_NEGATIVE_ACTION) & 0x01;
+
+ ancs_evt.notif.category_id =
+ (ble_ancs_c_category_id_val_t) p_data_src[BLE_ANCS_NOTIF_CATEGORY_ID_INDEX];
+
+ ancs_evt.notif.category_count = p_data_src[BLE_ANCS_NOTIF_CATEGORY_CNT_INDEX];
+ ancs_evt.notif.notif_uid = uint32_decode(&p_data_src[BLE_ANCS_NOTIF_NOTIF_UID]);
+ /*lint -restore*/
+
+ err_code = ble_ancs_verify_notification_format(&ancs_evt.notif);
+ if (err_code == NRF_SUCCESS)
+ {
+ ancs_evt.evt_type = BLE_ANCS_C_EVT_NOTIF;
+ }
+ else
+ {
+ ancs_evt.evt_type = BLE_ANCS_C_EVT_INVALID_NOTIF;
+ }
+
+ p_ancs->evt_handler(&ancs_evt);
+}
+
+
+ret_code_t nrf_ble_ancs_c_app_attr_request(ble_ancs_c_t * p_ancs,
+ uint8_t const * p_app_id,
+ uint32_t len)
+{
+ return ancs_c_app_attr_request(p_ancs, p_app_id, len);
+}
+
+
+/**@brief Function for receiving and validating notifications received from the Notification Provider.
+ *
+ * @param[in] p_ancs Pointer to an ANCS instance to which the event belongs.
+ * @param[in] p_ble_evt Bluetooth stack event.
+ */
+static void on_evt_gattc_notif(ble_ancs_c_t * p_ancs, ble_evt_t const * p_ble_evt)
+{
+ ble_gattc_evt_hvx_t const * p_notif = &p_ble_evt->evt.gattc_evt.params.hvx;
+
+ if (p_ble_evt->evt.gattc_evt.conn_handle != p_ancs->conn_handle)
+ {
+ return;
+ }
+
+ if (p_notif->handle == p_ancs->service.notif_source_char.handle_value)
+ {
+ parse_notif(p_ancs, p_notif->data, p_notif->len);
+ }
+ else if (p_notif->handle == p_ancs->service.data_source_char.handle_value)
+ {
+ ancs_parse_get_attrs_response(p_ancs, p_notif->data, p_notif->len);
+ }
+ else
+ {
+ // No applicable action.
+ }
+}
+
+/**@brief Function for handling error response events.
+ *
+ * @param[in] p_ancs_c Pointer to the Battery Service Client Structure.
+ * @param[in] p_ble_evt Pointer to the SoftDevice event.
+ */
+static void on_ctrlpt_error_rsp(ble_ancs_c_t * p_ancs, ble_evt_t const * p_ble_evt)
+{
+ ble_ancs_c_evt_t ancs_evt;
+
+ ancs_evt.evt_type = BLE_ANCS_C_EVT_NP_ERROR;
+ ancs_evt.err_code_np = p_ble_evt->evt.gattc_evt.gatt_status;
+
+ p_ancs->evt_handler(&ancs_evt);
+}
+
+/**@brief Function for handling write response events.
+ *
+ * @param[in] p_ancs_c Pointer to the Battery Service Client Structure.
+ * @param[in] p_ble_evt Pointer to the SoftDevice event.
+ */
+static void on_write_rsp(ble_ancs_c_t * p_ancs, ble_evt_t const* p_ble_evt)
+{
+ // Check if the event if on the link for this instance
+ if (p_ancs->conn_handle != p_ble_evt->evt.gattc_evt.conn_handle)
+ {
+ return;
+ }
+ if ((p_ble_evt->evt.gattc_evt.error_handle != BLE_GATT_HANDLE_INVALID)
+ && (p_ble_evt->evt.gattc_evt.error_handle == p_ancs->service.control_point_char.handle_value))
+ {
+ on_ctrlpt_error_rsp(p_ancs,p_ble_evt);
+ }
+ // Check if there is any message to be sent across to the peer and send it.
+ tx_buffer_process();
+}
+
+
+void ble_ancs_c_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context)
+{
+ ble_ancs_c_t * p_ancs = (ble_ancs_c_t *)p_context;
+ uint16_t evt = p_ble_evt->header.evt_id;
+
+ switch (evt)
+ {
+ case BLE_GATTC_EVT_WRITE_RSP:
+ on_write_rsp(p_ancs, p_ble_evt);
+ break;
+
+ case BLE_GATTC_EVT_HVX:
+ on_evt_gattc_notif(p_ancs, p_ble_evt);
+ break;
+
+ case BLE_GAP_EVT_DISCONNECTED:
+ on_disconnected(p_ancs, p_ble_evt);
+ break;
+
+ default:
+ break;
+ }
+}
+
+
+ret_code_t ble_ancs_c_init(ble_ancs_c_t * p_ancs, ble_ancs_c_init_t const * p_ancs_init)
+{
+ uint32_t err_code;
+
+ //Verify that the parameters needed for to initialize this instance of ANCS are not NULL.
+ VERIFY_PARAM_NOT_NULL(p_ancs);
+ VERIFY_PARAM_NOT_NULL(p_ancs_init);
+ VERIFY_PARAM_NOT_NULL(p_ancs_init->evt_handler);
+
+ //Initialize state for the attribute parsing state machine.
+ p_ancs->parse_info.parse_state = COMMAND_ID;
+ p_ancs->parse_info.p_data_dest = NULL;
+ p_ancs->parse_info.current_attr_index = 0;
+ p_ancs->parse_info.current_app_id_index = 0;
+
+ p_ancs->evt_handler = p_ancs_init->evt_handler;
+ p_ancs->error_handler = p_ancs_init->error_handler;
+ p_ancs->conn_handle = BLE_CONN_HANDLE_INVALID;
+
+ p_ancs->service.data_source_cccd.uuid.uuid = BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG;
+ p_ancs->service.notif_source_cccd.uuid.uuid = BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG;
+
+ // Make sure instance of service is clear. GATT handles inside the service and characteristics are set to @ref BLE_GATT_HANDLE_INVALID.
+ memset(&p_ancs->service, 0, sizeof(ble_ancs_c_service_t));
+ tx_buffer_init();
+
+ // Assign UUID types.
+ err_code = sd_ble_uuid_vs_add(&ble_ancs_base_uuid128, &p_ancs->service.service.uuid.type);
+ VERIFY_SUCCESS(err_code);
+
+ err_code = sd_ble_uuid_vs_add(&ble_ancs_cp_base_uuid128, &p_ancs->service.control_point_char.uuid.type);
+ VERIFY_SUCCESS(err_code);
+
+ err_code = sd_ble_uuid_vs_add(&ble_ancs_ns_base_uuid128, &p_ancs->service.notif_source_char.uuid.type);
+ VERIFY_SUCCESS(err_code);
+
+ err_code = sd_ble_uuid_vs_add(&ble_ancs_ds_base_uuid128, &p_ancs->service.data_source_char.uuid.type);
+ VERIFY_SUCCESS(err_code);
+
+ // Assign UUID to the service.
+ p_ancs->service.service.uuid.uuid = ANCS_UUID_SERVICE;
+ p_ancs->service.service.uuid.type = p_ancs->service.service.uuid.type;
+
+ return ble_db_discovery_evt_register(&p_ancs->service.service.uuid);
+}
+
+
+/**@brief Function for creating a TX message for writing a CCCD.
+ *
+ * @param[in] conn_handle Connection handle on which to perform the configuration.
+ * @param[in] handle_cccd Handle of the CCCD.
+ * @param[in] enable Enable or disable GATTC notifications.
+ *
+ * @retval NRF_SUCCESS If the message was created successfully.
+ * @retval NRF_ERROR_INVALID_PARAM If one of the input parameters was invalid.
+ */
+static uint32_t cccd_configure(const uint16_t conn_handle, const uint16_t handle_cccd, bool enable)
+{
+ tx_message_t p_msg;
+ memset(&p_msg, 0, sizeof(tx_message_t));
+ uint16_t cccd_val = enable ? BLE_CCCD_NOTIFY_BIT_MASK : 0;
+
+ p_msg.req.write_req.gattc_params.handle = handle_cccd;
+ p_msg.req.write_req.gattc_params.len = 2;
+ p_msg.req.write_req.gattc_params.p_value = p_msg.req.write_req.gattc_value;
+ p_msg.req.write_req.gattc_params.offset = 0;
+ p_msg.req.write_req.gattc_params.write_op = BLE_GATT_OP_WRITE_REQ;
+ p_msg.req.write_req.gattc_value[0] = LSB_16(cccd_val);
+ p_msg.req.write_req.gattc_value[1] = MSB_16(cccd_val);
+ p_msg.conn_handle = conn_handle;
+ p_msg.type = WRITE_REQ;
+
+ tx_buffer_insert(&p_msg);
+
+ tx_buffer_process();
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t ble_ancs_c_notif_source_notif_enable(ble_ancs_c_t const * p_ancs)
+{
+ NRF_LOG_INFO("Enable Notification Source notifications. writing to handle: %i ",
+ p_ancs->service.notif_source_cccd.handle);
+ return cccd_configure(p_ancs->conn_handle, p_ancs->service.notif_source_cccd.handle, true);
+}
+
+
+ret_code_t ble_ancs_c_notif_source_notif_disable(ble_ancs_c_t const * p_ancs)
+{
+ return cccd_configure(p_ancs->conn_handle, p_ancs->service.notif_source_cccd.handle, false);
+}
+
+
+ret_code_t ble_ancs_c_data_source_notif_enable(ble_ancs_c_t const * p_ancs)
+{
+ NRF_LOG_INFO("Enable Data Source notifications. Writing to handle: %i ",
+ p_ancs->service.data_source_cccd.handle);
+ return cccd_configure(p_ancs->conn_handle, p_ancs->service.data_source_cccd.handle, true);
+}
+
+
+ret_code_t ble_ancs_c_data_source_notif_disable(ble_ancs_c_t const * p_ancs)
+{
+ return cccd_configure(p_ancs->conn_handle, p_ancs->service.data_source_cccd.handle, false);
+}
+
+
+uint32_t ble_ancs_get_notif_attrs(ble_ancs_c_t * p_ancs,
+ uint32_t const p_uid)
+{
+ tx_message_t p_msg;
+ memset(&p_msg, 0, sizeof(tx_message_t));
+
+ uint32_t index = 0;
+ p_ancs->number_of_requested_attr = 0;
+
+
+ p_msg.req.write_req.gattc_params.handle = p_ancs->service.control_point_char.handle_value;
+ p_msg.req.write_req.gattc_params.p_value = p_msg.req.write_req.gattc_value;
+ p_msg.req.write_req.gattc_params.offset = 0;
+ p_msg.req.write_req.gattc_params.write_op = BLE_GATT_OP_WRITE_REQ;
+
+ //Encode Command ID.
+ p_msg.req.write_req.gattc_value[index++] = BLE_ANCS_COMMAND_ID_GET_NOTIF_ATTRIBUTES;
+
+ //Encode Notification UID.
+ index += uint32_encode(p_uid, &(p_msg.req.write_req.gattc_value[index]));
+
+ //Encode Attribute ID.
+ for (uint32_t attr = 0; attr < BLE_ANCS_NB_OF_NOTIF_ATTR; attr++)
+ {
+ if (p_ancs->ancs_notif_attr_list[attr].get == true)
+ {
+ p_msg.req.write_req.gattc_value[index++] = attr;
+ if ((attr == BLE_ANCS_NOTIF_ATTR_ID_TITLE) ||
+ (attr == BLE_ANCS_NOTIF_ATTR_ID_SUBTITLE) ||
+ (attr == BLE_ANCS_NOTIF_ATTR_ID_MESSAGE))
+ {
+ //Encode Length field, only applicable for Title, Subtitle and Message
+ index += uint16_encode(p_ancs->ancs_notif_attr_list[attr].attr_len,
+ &(p_msg.req.write_req.gattc_value[index]));
+ }
+ p_ancs->number_of_requested_attr++;
+ }
+ }
+ p_msg.req.write_req.gattc_params.len = index;
+ p_msg.conn_handle = p_ancs->conn_handle;
+ p_msg.type = WRITE_REQ;
+ p_ancs->parse_info.expected_number_of_attrs = p_ancs->number_of_requested_attr;
+
+ tx_buffer_insert(&p_msg);
+ tx_buffer_process();
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_ble_ancs_c_attr_add(ble_ancs_c_t * p_ancs,
+ ble_ancs_c_notif_attr_id_val_t const id,
+ uint8_t * p_data,
+ uint16_t const len)
+{
+ VERIFY_PARAM_NOT_NULL(p_data);
+
+ if ((len == 0) || (len > BLE_ANCS_ATTR_DATA_MAX))
+ {
+ return NRF_ERROR_INVALID_LENGTH;
+ }
+
+ p_ancs->ancs_notif_attr_list[id].get = true;
+ p_ancs->ancs_notif_attr_list[id].attr_len = len;
+ p_ancs->ancs_notif_attr_list[id].p_attr_data = p_data;
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_ble_ancs_c_app_attr_add(ble_ancs_c_t * p_ancs,
+ ble_ancs_c_app_attr_id_val_t const id,
+ uint8_t * p_data,
+ uint16_t const len)
+{
+ VERIFY_PARAM_NOT_NULL(p_ancs);
+ VERIFY_PARAM_NOT_NULL(p_data);
+
+ if ((len == 0) || (len > BLE_ANCS_ATTR_DATA_MAX))
+ {
+ return NRF_ERROR_INVALID_LENGTH;
+ }
+
+ p_ancs->ancs_app_attr_list[id].get = true;
+ p_ancs->ancs_app_attr_list[id].attr_len = len;
+ p_ancs->ancs_app_attr_list[id].p_attr_data = p_data;
+
+ return NRF_SUCCESS;
+}
+
+ret_code_t ble_ancs_c_app_attr_remove(ble_ancs_c_t * p_ancs,
+ ble_ancs_c_app_attr_id_val_t const id)
+{
+ p_ancs->ancs_app_attr_list[id].get = false;
+ p_ancs->ancs_app_attr_list[id].attr_len = 0;
+ p_ancs->ancs_app_attr_list[id].p_attr_data = NULL;
+ return NRF_SUCCESS;
+}
+
+ret_code_t ble_ancs_c_notif_attr_remove(ble_ancs_c_t * p_ancs,
+ ble_ancs_c_notif_attr_id_val_t const id)
+{
+ p_ancs->ancs_notif_attr_list[id].get = false;
+ p_ancs->ancs_notif_attr_list[id].attr_len = 0;
+ p_ancs->ancs_notif_attr_list[id].p_attr_data = NULL;
+ return NRF_SUCCESS;
+}
+
+ret_code_t nrf_ble_ancs_c_attr_req_clear_all(ble_ancs_c_t * p_ancs)
+{
+ memset(p_ancs->ancs_notif_attr_list, 0 , sizeof(p_ancs->ancs_notif_attr_list));
+ memset(p_ancs->ancs_app_attr_list, 0 , sizeof(p_ancs->ancs_app_attr_list));
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_ble_ancs_c_request_attrs(ble_ancs_c_t * p_ancs,
+ ble_ancs_c_evt_notif_t const * p_notif)
+{
+ uint32_t err_code;
+ err_code = ble_ancs_verify_notification_format(p_notif);
+ VERIFY_SUCCESS(err_code);
+
+ err_code = ble_ancs_get_notif_attrs(p_ancs, p_notif->notif_uid);
+ p_ancs->parse_info.parse_state = COMMAND_ID;
+ VERIFY_SUCCESS(err_code);
+
+ return NRF_SUCCESS;
+}
+
+static uint16_t encode_notif_action(uint8_t * p_encoded_data, uint32_t uid, ble_ancs_c_action_id_values_t action_id)
+{
+ uint8_t index = 0;
+
+ p_encoded_data[index++] = BLE_ANCS_COMMAND_ID_GET_PERFORM_NOTIF_ACTION;
+ index += uint32_encode(uid, &p_encoded_data[index]);
+ p_encoded_data[index++] = (uint8_t)action_id;
+
+ return index;
+}
+
+ret_code_t nrf_ancs_perform_notif_action(ble_ancs_c_t * p_ancs, uint32_t uid, ble_ancs_c_action_id_values_t action_id)
+{
+ VERIFY_PARAM_NOT_NULL(p_ancs);
+
+ tx_message_t msg;
+ memset(&msg, 0, sizeof(tx_message_t));
+
+ uint16_t len = encode_notif_action(msg.req.write_req.gattc_value, uid, action_id);
+
+ msg.req.write_req.gattc_params.handle = p_ancs->service.control_point_char.handle_value;
+ msg.req.write_req.gattc_params.p_value = msg.req.write_req.gattc_value;
+ msg.req.write_req.gattc_params.offset = 0;
+ msg.req.write_req.gattc_params.write_op = BLE_GATT_OP_WRITE_REQ;
+
+ msg.req.write_req.gattc_params.len = len;
+ msg.conn_handle = p_ancs->conn_handle;
+ msg.type = WRITE_REQ;
+
+ tx_buffer_insert(&msg);
+ tx_buffer_process();
+
+ return NRF_SUCCESS;
+}
+
+ret_code_t nrf_ble_ancs_c_handles_assign(ble_ancs_c_t * p_ancs,
+ uint16_t const conn_handle,
+ ble_ancs_c_service_t const * p_peer_handles)
+{
+ VERIFY_PARAM_NOT_NULL(p_ancs);
+
+ p_ancs->conn_handle = conn_handle;
+
+ if (p_peer_handles != NULL)
+ {
+ p_ancs->service.control_point_char.handle_value = p_peer_handles->control_point_char.handle_value;
+ p_ancs->service.data_source_cccd.handle = p_peer_handles->data_source_cccd.handle;
+ p_ancs->service.data_source_char.handle_value = p_peer_handles->data_source_char.handle_value;
+ p_ancs->service.notif_source_cccd.handle = p_peer_handles->notif_source_cccd.handle;
+ p_ancs->service.notif_source_char.handle_value = p_peer_handles->notif_source_char.handle_value;
+ }
+
+ return NRF_SUCCESS;
+}
+
+#endif// NRF_MODULE_ENABLED(BLE_ANCS_C)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ancs_c/nrf_ble_ancs_c.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ancs_c/nrf_ble_ancs_c.h
new file mode 100644
index 0000000..550583e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ancs_c/nrf_ble_ancs_c.h
@@ -0,0 +1,604 @@
+/**
+ * Copyright (c) 2012 - 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.
+ *
+ */
+/** @file
+ *
+ * @defgroup ble_ancs_c Apple Notification Service client
+ * @{
+ * @ingroup ble_sdk_srv
+ *
+ * @brief Apple Notification Center Service Client Module.
+ *
+ * @details Disclaimer: This client implementation of the Apple Notification Center Service can
+ * be changed at any time by Nordic Semiconductor ASA. Server implementations such as the
+ * ones found in iOS can be changed at any time by Apple and may cause this client
+ * implementation to stop working.
+ *
+ * This module implements the Apple Notification Center Service (ANCS) client.
+ * This client can be used as a Notification Consumer (NC) that receives data
+ * notifications from a Notification Provider (NP). The NP is typically an iOS
+ * device acting as a server. For terminology and up-to-date specs, see
+ * http://developer.apple.com.
+ *
+ * The term "notification" is used in two different meanings:
+ * - An <i>iOS notification</i> is the data received from the Notification Provider.
+ * - A <i>GATTC notification</i> is a way to transfer data with <i>Bluetooth</i> Smart.
+ * In this module, we receive iOS notifications using GATTC notifications.
+ * We use the full term (iOS notification or GATTC notification) where required to avoid confusion.
+ *
+ * Upon initializing the module, you must add the different iOS notification attributes you
+ * would like to receive for iOS notifications (see @ref nrf_ble_ancs_c_attr_add).
+ *
+ * Once a connection is established with a central device, the module does a service discovery to
+ * discover the ANCS server handles. If this succeeds (@ref BLE_ANCS_C_EVT_DISCOVERY_COMPLETE),
+ * the handles for the ANCS server are part of the @ref ble_ancs_c_evt_t structure and must be
+ * assigned to an ANCS_C instance using the @ref nrf_ble_ancs_c_handles_assign function. For more
+ * information about service discovery, see the @ref lib_ble_db_discovery documentation.
+ *
+ * The application can now subscribe to iOS notifications using
+ * @ref ble_ancs_c_notif_source_notif_enable. They arrive in the @ref BLE_ANCS_C_EVT_NOTIF event.
+ * @ref nrf_ble_ancs_c_request_attrs can be used to request attributes for the notifications. They
+ * arrive in the @ref BLE_ANCS_C_EVT_NOTIF_ATTRIBUTE event.
+ * @ref nrf_ble_ancs_c_app_attr_request can be used to request attributes of the app that issued
+ * the notifications. They arrive in the @ref BLE_ANCS_C_EVT_APP_ATTRIBUTE event.
+ * @ref nrf_ancs_perform_notif_action can be used to make the Notification Provider perform an
+ * action based on the provided notification.
+ *
+ * @msc
+ * hscale = "1.5";
+ * Application, ANCS_C;
+ * |||;
+ * Application=>ANCS_C [label = "ble_ancs_c_attr_add(attribute)"];
+ * Application=>ANCS_C [label = "ble_ancs_c_init(ancs_instance, event_handler)"];
+ * ...;
+ * Application<<=ANCS_C [label = "BLE_ANCS_C_EVT_DISCOVERY_COMPLETE"];
+ * Application=>ANCS_C [label = "ble_ancs_c_handles_assign(ancs_instance, conn_handle, service_handles)"];
+ * Application=>ANCS_C [label = "ble_ancs_c_notif_source_notif_enable(ancs_instance)"];
+ * Application=>ANCS_C [label = "ble_ancs_c_data_source_notif_enable(ancs_instance)"];
+ * |||;
+ * ...;
+ * |||;
+ * Application<<=ANCS_C [label = "BLE_ANCS_C_EVT_NOTIF"];
+ * |||;
+ * ...;
+ * |||;
+ * Application=>ANCS_C [label = "ble_ancs_c_request_attrs(attr_id, buffer)"];
+ * Application<<=ANCS_C [label = "BLE_ANCS_C_EVT_NOTIF_ATTRIBUTE"];
+ * |||;
+ * @endmsc
+ *
+ * @note The application must register this module as BLE event observer using the
+ * NRF_SDH_BLE_OBSERVER macro. Example:
+ * @code
+ * ble_ancs_c_t instance;
+ * NRF_SDH_BLE_OBSERVER(anything, BLE_ANCS_C_BLE_OBSERVER_PRIO,
+ * ble_ancs_c_on_ble_evt, &instance);
+ * @endcode
+ */
+#ifndef BLE_ANCS_C_H__
+#define BLE_ANCS_C_H__
+
+#include "ble_types.h"
+#include "ble_srv_common.h"
+#include "sdk_errors.h"
+#include "ble_db_discovery.h"
+#include "nrf_sdh_ble.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Macro for defining a ble_ancs_c instance.
+ *
+ * @param _name Name of the instance.
+ * @hideinitializer
+ */
+#define BLE_ANCS_C_DEF(_name) \
+static ble_ancs_c_t _name; \
+NRF_SDH_BLE_OBSERVER(_name ## _obs, \
+ BLE_ANCS_C_BLE_OBSERVER_PRIO, \
+ ble_ancs_c_on_ble_evt, &_name)
+
+/** @brief Macro for defining multiple ble_ancs_c instances.
+ *
+ * @param _name Name of the array of instances.
+ * @param _cnt Number of instances to define.
+ * @hideinitializer
+ */
+#define BLE_ANCS_C_ARRAY_DEF(_name, _cnt) \
+sstatic ble_ancs_c_t _name[_cnt]; \
+NRF_SDH_BLE_OBSERVERS(_name ## _obs, \
+ BLE_ANCS_C_BLE_OBSERVER_PRIO, \
+ ble_ancs_c_on_ble_evt, &_name, _cnt)
+
+#define BLE_ANCS_ATTR_DATA_MAX 32 //!< Maximum data length of an iOS notification attribute.
+#define BLE_ANCS_NB_OF_CATEGORY_ID 12 //!< Number of iOS notification categories: Other, Incoming Call, Missed Call, Voice Mail, Social, Schedule, Email, News, Health And Fitness, Business And Finance, Location, Entertainment.
+#define BLE_ANCS_NB_OF_NOTIF_ATTR 8 //!< Number of iOS notification attributes: AppIdentifier, Title, Subtitle, Message, MessageSize, Date, PositiveActionLabel, NegativeActionLabel.
+#define BLE_ANCS_NB_OF_APP_ATTR 1 //!< Number of iOS application attributes: DisplayName.
+#define BLE_ANCS_NB_OF_EVT_ID 3 //!< Number of iOS notification events: Added, Modified, Removed.
+
+/** @brief Length of the iOS notification data.
+ *
+ * @details 8 bytes:
+ * Event ID |Event flags |Category ID |Category count|Notification UID
+ * ---------|------------|------------|--------------|----------------
+ * 1 byte | 1 byte | 1 byte | 1 byte | 4 bytes
+ */
+#define BLE_ANCS_NOTIFICATION_DATA_LENGTH 8
+
+#define ANCS_UUID_SERVICE 0xF431 //!< 16-bit service UUID for the Apple Notification Center Service.
+#define ANCS_UUID_CHAR_CONTROL_POINT 0xD8F3 //!< 16-bit control point UUID.
+#define ANCS_UUID_CHAR_DATA_SOURCE 0xC6E9 //!< 16-bit data source UUID.
+#define ANCS_UUID_CHAR_NOTIFICATION_SOURCE 0x120D //!< 16-bit notification source UUID.
+
+#define BLE_ANCS_EVENT_FLAG_SILENT 0 //!< 0b.......1 Silent: First (LSB) bit is set. All flags can be active at the same time.
+#define BLE_ANCS_EVENT_FLAG_IMPORTANT 1 //!< 0b......1. Important: Second (LSB) bit is set. All flags can be active at the same time.
+#define BLE_ANCS_EVENT_FLAG_PREEXISTING 2 //!< 0b.....1.. Pre-existing: Third (LSB) bit is set. All flags can be active at the same time.
+#define BLE_ANCS_EVENT_FLAG_POSITIVE_ACTION 3 //!< 0b....1... Positive action: Fourth (LSB) bit is set. All flags can be active at the same time.
+#define BLE_ANCS_EVENT_FLAG_NEGATIVE_ACTION 4 //!< 0b...1.... Negative action: Fifth (LSB) bit is set. All flags can be active at the same time.
+
+/** @defgroup BLE_ANCS_NP_ERROR_CODES Notification Provider (iOS) Error Codes
+ * @{ */
+#define BLE_ANCS_NP_UNKNOWN_COMMAND 0x01A0 //!< The command ID is unknown to the NP.
+#define BLE_ANCS_NP_INVALID_COMMAND 0x01A1 //!< The command format is invalid.
+#define BLE_ANCS_NP_INVALID_PARAMETER 0x01A2 //!< One or more parameters does not exist in the NP.
+#define BLE_ANCS_NP_ACTION_FAILED 0x01A3 //!< The action failed to be performed by the NP.
+/** @} */
+
+
+/**@brief Event types that are passed from client to application on an event. */
+typedef enum
+{
+ BLE_ANCS_C_EVT_DISCOVERY_COMPLETE, /**< A successful connection has been established and the service was found on the connected peer. */
+ BLE_ANCS_C_EVT_DISCOVERY_FAILED, /**< It was not possible to discover the service or characteristics of the connected peer. */
+ BLE_ANCS_C_EVT_NOTIF, /**< An iOS notification was received on the notification source control point. */
+ BLE_ANCS_C_EVT_INVALID_NOTIF, /**< An iOS notification was received on the notification source control point, but the format is invalid. */
+ BLE_ANCS_C_EVT_NOTIF_ATTRIBUTE, /**< A received iOS notification attribute has been parsed. */
+ BLE_ANCS_C_EVT_APP_ATTRIBUTE, /**< An iOS app attribute has been parsed. */
+ BLE_ANCS_C_EVT_NP_ERROR, /**< An error has been sent on the ANCS Control Point from the iOS Notification Provider. */
+} ble_ancs_c_evt_type_t;
+
+/**@brief Category IDs for iOS notifications. */
+typedef enum
+{
+ BLE_ANCS_CATEGORY_ID_OTHER, /**< The iOS notification belongs to the "other" category. */
+ BLE_ANCS_CATEGORY_ID_INCOMING_CALL, /**< The iOS notification belongs to the "Incoming Call" category. */
+ BLE_ANCS_CATEGORY_ID_MISSED_CALL, /**< The iOS notification belongs to the "Missed Call" category. */
+ BLE_ANCS_CATEGORY_ID_VOICE_MAIL, /**< The iOS notification belongs to the "Voice Mail" category. */
+ BLE_ANCS_CATEGORY_ID_SOCIAL, /**< The iOS notification belongs to the "Social" category. */
+ BLE_ANCS_CATEGORY_ID_SCHEDULE, /**< The iOS notification belongs to the "Schedule" category. */
+ BLE_ANCS_CATEGORY_ID_EMAIL, /**< The iOS notification belongs to the "E-mail" category. */
+ BLE_ANCS_CATEGORY_ID_NEWS, /**< The iOS notification belongs to the "News" category. */
+ BLE_ANCS_CATEGORY_ID_HEALTH_AND_FITNESS, /**< The iOS notification belongs to the "Health and Fitness" category. */
+ BLE_ANCS_CATEGORY_ID_BUSINESS_AND_FINANCE, /**< The iOS notification belongs to the "Buisness and Finance" category. */
+ BLE_ANCS_CATEGORY_ID_LOCATION, /**< The iOS notification belongs to the "Location" category. */
+ BLE_ANCS_CATEGORY_ID_ENTERTAINMENT /**< The iOS notification belongs to the "Entertainment" category. */
+} ble_ancs_c_category_id_val_t;
+
+/**@brief Event IDs for iOS notifications. */
+typedef enum
+{
+ BLE_ANCS_EVENT_ID_NOTIFICATION_ADDED, /**< The iOS notification was added. */
+ BLE_ANCS_EVENT_ID_NOTIFICATION_MODIFIED, /**< The iOS notification was modified. */
+ BLE_ANCS_EVENT_ID_NOTIFICATION_REMOVED /**< The iOS notification was removed. */
+} ble_ancs_c_evt_id_values_t;
+
+/**@brief Control point command IDs that the Notification Consumer can send to the Notification Provider. */
+typedef enum
+{
+ BLE_ANCS_COMMAND_ID_GET_NOTIF_ATTRIBUTES, /**< Requests attributes to be sent from the NP to the NC for a given notification. */
+ BLE_ANCS_COMMAND_ID_GET_APP_ATTRIBUTES, /**< Requests attributes to be sent from the NP to the NC for a given iOS app. */
+ BLE_ANCS_COMMAND_ID_GET_PERFORM_NOTIF_ACTION, /**< Requests an action to be performed on a given notification, for example, dismiss an alarm. */
+} ble_ancs_c_cmd_id_val_t;
+
+/**@brief IDs for actions that can be performed for iOS notifications. */
+typedef enum
+{
+ ACTION_ID_POSITIVE = 0, /**< Positive action. */
+ ACTION_ID_NEGATIVE /**< Negative action. */
+} ble_ancs_c_action_id_values_t;
+
+/**@brief App attribute ID values.
+ * @details Currently, only one value is defined. However, the number of app
+ * attributes might increase. Therefore, they are stored in an enumeration.
+ */
+typedef enum
+{
+ BLE_ANCS_APP_ATTR_ID_DISPLAY_NAME = 0 /**< Command used to get the display name for an app identifier. */
+} ble_ancs_c_app_attr_id_val_t;
+
+/**@brief IDs for iOS notification attributes. */
+typedef enum
+{
+ BLE_ANCS_NOTIF_ATTR_ID_APP_IDENTIFIER = 0, /**< Identifies that the attribute data is of an "App Identifier" type. */
+ BLE_ANCS_NOTIF_ATTR_ID_TITLE, /**< Identifies that the attribute data is a "Title". */
+ BLE_ANCS_NOTIF_ATTR_ID_SUBTITLE, /**< Identifies that the attribute data is a "Subtitle". */
+ BLE_ANCS_NOTIF_ATTR_ID_MESSAGE, /**< Identifies that the attribute data is a "Message". */
+ BLE_ANCS_NOTIF_ATTR_ID_MESSAGE_SIZE, /**< Identifies that the attribute data is a "Message Size". */
+ BLE_ANCS_NOTIF_ATTR_ID_DATE, /**< Identifies that the attribute data is a "Date". */
+ BLE_ANCS_NOTIF_ATTR_ID_POSITIVE_ACTION_LABEL, /**< The notification has a "Positive action" that can be executed associated with it. */
+ BLE_ANCS_NOTIF_ATTR_ID_NEGATIVE_ACTION_LABEL, /**< The notification has a "Negative action" that can be executed associated with it. */
+} ble_ancs_c_notif_attr_id_val_t;
+
+/**@brief Flags for iOS notifications. */
+typedef struct
+{
+ uint8_t silent : 1; //!< If this flag is set, the notification has a low priority.
+ uint8_t important : 1; //!< If this flag is set, the notification has a high priority.
+ uint8_t pre_existing : 1; //!< If this flag is set, the notification is pre-existing.
+ uint8_t positive_action : 1; //!< If this flag is set, the notification has a positive action that can be taken.
+ uint8_t negative_action : 1; //!< If this flag is set, the notification has a negative action that can be taken.
+} ble_ancs_c_notif_flags_t;
+
+/**@brief Parsing states for received iOS notification and app attributes. */
+typedef enum
+{
+ COMMAND_ID, /**< Parsing the command ID. */
+ NOTIF_UID, /**< Parsing the notification UID. */
+ APP_ID, /**< Parsing app ID. */
+ ATTR_ID, /**< Parsing attribute ID. */
+ ATTR_LEN1, /**< Parsing the LSB of the attribute length. */
+ ATTR_LEN2, /**< Parsing the MSB of the attribute length. */
+ ATTR_DATA, /**< Parsing the attribute data. */
+ ATTR_SKIP, /**< Parsing is skipped for the rest (or entire) of an attribute. */
+ DONE, /**< Parsing for one attribute is done. */
+} ble_ancs_c_parse_state_t;
+
+/**@brief iOS notification structure. */
+typedef struct
+{
+ uint32_t notif_uid; //!< Notification UID.
+ ble_ancs_c_evt_id_values_t evt_id; //!< Whether the notification was added, removed, or modified.
+ ble_ancs_c_notif_flags_t evt_flags; //!< Bitmask to signal if a special condition applies to the notification, for example, "Silent" or "Important".
+ ble_ancs_c_category_id_val_t category_id; //!< Classification of the notification type, for example, email or location.
+ uint8_t category_count; //!< Current number of active notifications for this category ID.
+} ble_ancs_c_evt_notif_t;
+
+/**@brief iOS attribute structure. This type is used for both notification attributes and app attributes. */
+typedef struct
+{
+ uint16_t attr_len; //!< Length of the received attribute data.
+ uint32_t attr_id; //!< Classification of the attribute type, for example, title or date.
+ uint8_t * p_attr_data; //!< Pointer to where the memory is allocated for storing incoming attributes.
+} ble_ancs_c_attr_t;
+
+/**@brief iOS notification attribute structure for incoming attributes. */
+typedef struct
+{
+ uint32_t notif_uid; //!< UID of the notification that the attribute belongs to.
+ ble_ancs_c_attr_t attrs; //!< A received attribute.
+} ble_ancs_c_evt_attr_t;
+
+typedef struct
+{
+ uint16_t attr_len; //!< Length of the received attribute data.
+ uint32_t attr_id; //!< Classification of the attribute type, for example, title or date.
+ uint8_t * p_attr_data; //!< Pointer to where the memory is allocated for storing incoming attributes.
+} ble_ancs_c_evt_app_attr_t;
+
+/**@brief iOS notification attribute content wanted by our application. */
+typedef struct
+{
+ bool get; //!< Boolean to determine if this attribute will be requested from the Notification Provider.
+ uint32_t attr_id; //!< Attribute ID: AppIdentifier(0), Title(1), Subtitle(2), Message(3), MessageSize(4), Date(5), PositiveActionLabel(6), NegativeActionLabel(7).
+ uint16_t attr_len; //!< Length of the attribute. If more data is received from the Notification Provider, all data beyond this length is discarded.
+ uint8_t * p_attr_data; //!< Pointer to where the memory is allocated for storing incoming attributes.
+} ble_ancs_c_attr_list_t;
+
+/**@brief Structure used for holding the Apple Notification Center Service found during the
+ discovery process.
+ */
+typedef struct
+{
+ ble_gattc_service_t service; //!< The GATT Service holding the discovered Apple Notification Center Service. (0xF431).
+ ble_gattc_char_t control_point_char; //!< ANCS Control Point Characteristic. Allows interaction with the peer (0xD8F3).
+ ble_gattc_char_t notif_source_char; //!< ANCS Notification Source Characteristic. Keeps track of arrival, modification, and removal of notifications (0x120D).
+ ble_gattc_desc_t notif_source_cccd; //!< ANCS Notification Source Characteristic Descriptor. Enables or disables GATT notifications.
+ ble_gattc_char_t data_source_char; //!< ANCS Data Source Characteristic, where attribute data for the notifications is received from peer (0xC6E9).
+ ble_gattc_desc_t data_source_cccd; //!< ANCS Data Source Characteristic Descriptor. Enables or disables GATT notifications.
+} ble_ancs_c_service_t;
+
+/**@brief ANCS client module event structure.
+ *
+ * @details The structure contains the event that should be handled by the main application.
+ */
+typedef struct
+{
+ ble_ancs_c_evt_type_t evt_type; //!< Type of event.
+ uint16_t conn_handle; //!< Connection handle on which the ANCS service was discovered on the peer device. This field will be filled if the @p evt_type is @ref BLE_ANCS_C_EVT_DISCOVERY_COMPLETE.
+ ble_ancs_c_evt_notif_t notif; //!< iOS notification. This field will be filled if @p evt_type is @ref BLE_ANCS_C_EVT_NOTIF.
+ uint16_t err_code_np; //!< An error coming from the Notification Provider. This field will be filled with @ref BLE_ANCS_NP_ERROR_CODES if @p evt_type is @ref BLE_ANCS_C_EVT_NP_ERROR.
+ ble_ancs_c_attr_t attr; //!< iOS notification attribute or app attribute, depending on the event type.
+ uint32_t notif_uid; //!< Notification UID.
+ uint8_t app_id[BLE_ANCS_ATTR_DATA_MAX]; //!< App identifier.
+ ble_ancs_c_service_t service; //!< Information on the discovered Alert Notification Service. This field will be filled if the @p evt_type is @ref BLE_ANCS_C_EVT_DISCOVERY_COMPLETE.
+} ble_ancs_c_evt_t;
+
+/**@brief iOS notification event handler type. */
+typedef void (*ble_ancs_c_evt_handler_t) (ble_ancs_c_evt_t * p_evt);
+
+typedef struct
+{
+ ble_ancs_c_attr_list_t * p_attr_list; //!< The current list of attributes being parsed. This field will point to either @ref ble_ancs_c_t::ancs_notif_attr_list or @ref ble_ancs_c_t::ancs_app_attr_list.
+ uint32_t nb_of_attr; //!< Number of possible attributes. When parsing begins, it is set to either @ref BLE_ANCS_NB_OF_NOTIF_ATTR or @ref BLE_ANCS_NB_OF_APP_ATTR.
+ uint32_t expected_number_of_attrs; //!< The number of attributes expected upon receiving attributes. Keeps track of when to stop reading incoming attributes.
+ ble_ancs_c_parse_state_t parse_state; //!< ANCS notification attribute parsing state.
+ ble_ancs_c_cmd_id_val_t command_id; //!< Variable to keep track of what command type we are currently parsing ( @ref BLE_ANCS_COMMAND_ID_GET_NOTIF_ATTRIBUTES or @ref BLE_ANCS_COMMAND_ID_GET_APP_ATTRIBUTES.
+ uint8_t * p_data_dest; //!< Attribute that the parsed data will be copied into.
+ uint16_t current_attr_index; //!< Variable to keep track of how much (for a given attribute) we are done parsing.
+ uint32_t current_app_id_index; //!< Variable to keep track of how much (for a given app identifier) we are done parsing.
+} ble_ancs_parse_sm_t;
+
+/**@brief iOS notification structure, which contains various status information for the client. */
+typedef struct
+{
+ ble_ancs_c_evt_handler_t evt_handler; //!< Event handler to be called for handling events in the Apple Notification client application.
+ ble_srv_error_handler_t error_handler; //!< Function to be called in case of an error.
+ uint16_t conn_handle; //!< Handle of the current connection. Set with @ref nrf_ble_ancs_c_handles_assign when connected.
+ ble_ancs_c_service_t service; //!< Structure to store the different handles and UUIDs related to the service.
+ ble_ancs_c_attr_list_t ancs_notif_attr_list[BLE_ANCS_NB_OF_NOTIF_ATTR]; //!< For all attributes; contains whether they should be requested upon attribute request and the length and buffer of where to store attribute data.
+ ble_ancs_c_attr_list_t ancs_app_attr_list[BLE_ANCS_NB_OF_APP_ATTR]; //!< For all app attributes; contains whether they should be requested upon attribute request and the length and buffer of where to store attribute data.
+ uint32_t number_of_requested_attr; //!< The number of attributes that will be requested when an iOS notification attribute request is made.
+ ble_ancs_parse_sm_t parse_info; //!< Structure containing different information used to parse incoming attributes (from data_source characteristic) correctly.
+ ble_ancs_c_evt_t evt; //!< The event is filled with several iterations of the @ref ancs_parse_get_attrs_response function when requesting iOS notification attributes. So we must allocate memory for it here.
+} ble_ancs_c_t;
+
+/**@brief Apple Notification client init structure, which contains all options and data needed for
+ * initialization of the client. */
+typedef struct
+{
+ ble_ancs_c_evt_handler_t evt_handler; //!< Event handler to be called for handling events in the Battery Service.
+ ble_srv_error_handler_t error_handler; //!< Function to be called in case of an error.
+} ble_ancs_c_init_t;
+
+
+/**@brief Apple Notification Center Service UUIDs. */
+extern const ble_uuid128_t ble_ancs_base_uuid128; //!< Service UUID.
+extern const ble_uuid128_t ble_ancs_cp_base_uuid128; //!< Control point UUID.
+extern const ble_uuid128_t ble_ancs_ns_base_uuid128; //!< Notification source UUID.
+extern const ble_uuid128_t ble_ancs_ds_base_uuid128; //!< Data source UUID.
+
+
+/**@brief Function for handling the application's BLE stack events.
+ *
+ * @details Handles all events from the BLE stack that are of interest to the ANCS client.
+ *
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ * @param[in] p_context ANCS client structure.
+ */
+void ble_ancs_c_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context);
+
+
+/**@brief Function for handling events from the database discovery module.
+ *
+ * @details This function will handle an event from the database discovery module and determine
+ * if it relates to the discovery of ANCS at the peer. If so, it will
+ * call the application's event handler indicating that ANCS has been
+ * discovered at the peer. It also populates the event with the service related
+ * information before providing it to the application.
+ *
+ * @param[in] p_ancs Pointer to the ANCS client structure.
+ * @param[in] p_evt Pointer to the event received from the database discovery module.
+ */
+ void ble_ancs_c_on_db_disc_evt(ble_ancs_c_t * p_ancs, ble_db_discovery_evt_t * p_evt);
+
+
+/**@brief Function for initializing the ANCS client.
+ *
+ * @param[out] p_ancs ANCS client structure. This structure must be
+ * supplied by the application. It is initialized by this function
+ * and will later be used to identify this particular client instance.
+ * @param[in] p_ancs_init Information needed to initialize the client.
+ *
+ * @retval NRF_SUCCESS If the client was initialized successfully. Otherwise, an error code is returned.
+ */
+ret_code_t ble_ancs_c_init(ble_ancs_c_t * p_ancs, ble_ancs_c_init_t const * p_ancs_init);
+
+
+/**@brief Function for writing to the CCCD to enable notifications from the Apple Notification Service.
+ *
+ * @param[in] p_ancs iOS notification structure. This structure must be supplied by
+ * the application. It identifies the particular client instance to use.
+ *
+ * @retval NRF_SUCCESS If writing to the CCCD was successful. Otherwise, an error code is returned.
+ */
+ret_code_t ble_ancs_c_notif_source_notif_enable(ble_ancs_c_t const * p_ancs);
+
+
+/**@brief Function for writing to the CCCD to enable data source notifications from the ANCS.
+ *
+ * @param[in] p_ancs iOS notification structure. This structure must be supplied by
+ * the application. It identifies the particular client instance to use.
+ *
+ * @retval NRF_SUCCESS If writing to the CCCD was successful. Otherwise, an error code is returned.
+ */
+ret_code_t ble_ancs_c_data_source_notif_enable(ble_ancs_c_t const * p_ancs);
+
+
+/**@brief Function for writing to the CCCD to disable notifications from the ANCS.
+ *
+ * @param[in] p_ancs iOS notification structure. This structure must be supplied by
+ * the application. It identifies the particular client instance to use.
+ *
+ * @retval NRF_SUCCESS If writing to the CCCD was successful. Otherwise, an error code is returned.
+ */
+ret_code_t ble_ancs_c_notif_source_notif_disable(ble_ancs_c_t const * p_ancs);
+
+
+/**@brief Function for writing to the CCCD to disable data source notifications from the ANCS.
+ *
+ * @param[in] p_ancs iOS notification structure. This structure must be supplied by
+ * the application. It identifies the particular client instance to use.
+ *
+ * @retval NRF_SUCCESS If writing to the CCCD was successful. Otherwise, an error code is returned.
+ */
+ret_code_t ble_ancs_c_data_source_notif_disable(ble_ancs_c_t const * p_ancs);
+
+
+/**@brief Function for registering attributes that will be requested when @ref nrf_ble_ancs_c_request_attrs
+ * is called.
+ *
+ * @param[in] p_ancs ANCS client instance on which the attribute will be registered.
+ * @param[in] id ID of the attribute that will be added.
+ * @param[in] p_data Pointer to a buffer where the data of the attribute can be stored.
+ * @param[in] len Length of the buffer where the data of the attribute can be stored.
+
+ * @retval NRF_SUCCESS If all operations were successful. Otherwise, an error code is returned.
+ */
+ret_code_t nrf_ble_ancs_c_attr_add(ble_ancs_c_t * p_ancs,
+ ble_ancs_c_notif_attr_id_val_t const id,
+ uint8_t * p_data,
+ uint16_t const len);
+
+
+/**@brief Function for removing attributes so that they will no longer be requested when
+ * @ref nrf_ble_ancs_c_request_attrs is called.
+ *
+ * @param[in] p_ancs ANCS client instance on which the attribute will be removed.
+ * @param[in] id ID of the attribute that will be removed.
+ *
+ * @retval NRF_SUCCESS If all operations were successful. Otherwise, an error code is returned.
+ */
+ret_code_t nrf_ble_ancs_c_attr_remove(ble_ancs_c_t * p_ancs,
+ ble_ancs_c_notif_attr_id_val_t const id);
+
+/**@brief Function for removing attributes so that they will no longer be requested when
+ * @ref nrf_ble_ancs_c_app_attr_request is called.
+ *
+ * @param[in] p_ancs ANCS client instance on which the attribute will be removed.
+ * @param[in] id ID of the attribute that will be removed.
+ *
+ * @retval NRF_SUCCESS If all operations were successful. Otherwise, an error code is returned.
+ */
+ret_code_t nrf_ble_ancs_c_app_attr_remove(ble_ancs_c_t * p_ancs,
+ ble_ancs_c_app_attr_id_val_t const id);
+
+
+/**@brief Function for registering attributes that will be requested when @ref nrf_ble_ancs_c_app_attr_request
+ * is called.
+ *
+ * @param[in] p_ancs ANCS client instance on which the attribute will be registered.
+ * @param[in] id ID of the attribute that will be added.
+ * @param[in] p_data Pointer to a buffer where the data of the attribute can be stored.
+ * @param[in] len Length of the buffer where the data of the attribute can be stored.
+ *
+ * @retval NRF_SUCCESS If all operations were successful. Otherwise, an error code is returned.
+ */
+ret_code_t nrf_ble_ancs_c_app_attr_add(ble_ancs_c_t * p_ancs,
+ ble_ancs_c_app_attr_id_val_t const id,
+ uint8_t * p_data,
+ uint16_t const len);
+
+/**@brief Function for clearing the list of notification attributes and app attributes that
+ * would be requested from NP.
+ *
+ * @param[in] p_ancs iOS notification structure. This structure must be supplied by
+ * the application. It identifies the particular client instance to use.
+**/
+ret_code_t nrf_ble_ancs_c_attr_req_clear_all(ble_ancs_c_t * p_ancs);
+
+/**@brief Function for requesting attributes for a notification.
+ *
+ * @param[in] p_ancs iOS notification structure. This structure must be supplied by
+ * the application. It identifies the particular client instance to use.
+ * @param[in] p_notif Pointer to the notification whose attributes will be requested from
+ * the Notification Provider.
+ *
+ * @retval NRF_SUCCESS If all operations were successful. Otherwise, an error code is returned.
+ */
+ret_code_t nrf_ble_ancs_c_request_attrs(ble_ancs_c_t * p_ancs,
+ ble_ancs_c_evt_notif_t const * p_notif);
+
+/**@brief Function for requesting attributes for a given app.
+ *
+ * @param[in] p_ancs iOS notification structure. This structure must be supplied by
+ * the application. It identifies the particular client instance to use.
+ * @param[in] p_app_id App identifier of the app for which the app attributes are requested.
+ * @param[in] len Length of the app identifier.
+ *
+ * @retval NRF_SUCCESS If all operations were successful. Otherwise, an error code is returned.
+ */
+ret_code_t nrf_ble_ancs_c_app_attr_request(ble_ancs_c_t * p_ancs,
+ uint8_t const * p_app_id,
+ uint32_t len);
+
+
+/**@brief Function for performing a notification action.
+ *
+ * @param[in] p_ancs iOS notification structure. This structure must be supplied by
+ * the application. It identifies the particular client instance to use.
+ * @param[in] uuid The UUID of the notification for which to perform the action.
+ * @param[in] action_id Perform a positive or negative action.
+ *
+ * @retval NRF_SUCCESS If the operation was successful.
+ * @retval NRF_ERROR_NULL If @p p_ancs was a NULL pointer.
+ */
+ret_code_t nrf_ancs_perform_notif_action(ble_ancs_c_t * p_ancs,
+ uint32_t uuid,
+ ble_ancs_c_action_id_values_t action_id);
+
+/**@brief Function for assigning a handle to this instance of ancs_c.
+ *
+ * @details Call this function when a link has been established with a peer to
+ * associate this link to this instance of the module. This makes it
+ * possible to handle several link and associate each link to a particular
+ * instance of this module. The connection handle and attribute handles will be
+ * provided from the discovery event @ref BLE_ANCS_C_EVT_DISCOVERY_COMPLETE.
+ *
+ * @param[in] p_ancs Pointer to the ANCS client structure instance to associate with these
+ * handles.
+ * @param[in] conn_handle Connection handle to associate with the given ANCS instance.
+ * @param[in] p_service Attribute handles on the ANCS server that you want this ANCS client to
+ * interact with.
+ *
+ * @retval NRF_SUCCESS If the operation was successful.
+ * @retval NRF_ERROR_NULL If @p p_ancs was a NULL pointer.
+ */
+ret_code_t nrf_ble_ancs_c_handles_assign(ble_ancs_c_t * p_ancs,
+ uint16_t const conn_handle,
+ ble_ancs_c_service_t const * p_service);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // BLE_ANCS_C_H__
+
+/** @} */
+