From d2fe4c8e69f01b9aa7580d8a9a9ab959decc1751 Mon Sep 17 00:00:00 2001 From: ldab Date: Fri, 17 Nov 2023 07:52:39 +0100 Subject: [PATCH] Apple Notification Center Service - iOS --- .github/workflows/build.yml | 2 +- app/CMakeLists.txt | 3 +- app/Kconfig | 6 +- .../music_control/music_control_app.c | 6 +- app/src/ble/ble_ancs.c | 593 ++++++++++++++++++ app/src/ble/ble_ancs.h | 9 + app/src/ble/ble_comm.c | 3 +- app/src/main.c | 6 +- 8 files changed, 618 insertions(+), 10 deletions(-) create mode 100644 app/src/ble/ble_ancs.c create mode 100644 app/src/ble/ble_ancs.h diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 761ed491..cd38b9d8 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -47,7 +47,7 @@ jobs: - name: Build firmware for iOS working-directory: ZSWatch run: | - west build app --build-dir ${{ matrix.board }}_${{ matrix.built_type }}_ios -p -b ${{ matrix.board }} -- -DOVERLAY_CONFIG=boards/${{ matrix.built_type }}.conf -DCONFIG_BLE_USES_AMS="y" + west build app --build-dir ${{ matrix.board }}_${{ matrix.built_type }}_ios -p -b ${{ matrix.board }} -- -DOVERLAY_CONFIG=boards/${{ matrix.built_type }}.conf -DCONFIG_BLE_USES_IOS="y" cd ${{ matrix.board }}_${{ matrix.built_type }}/zephyr mv zephyr.hex ${{ matrix.board }}_${{ matrix.built_type }}.hex || true diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index 12e03bc9..4f69b0d4 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -60,7 +60,8 @@ target_sources(app PRIVATE src/ble/ble_aoa.c) target_sources(app PRIVATE src/ble/ble_comm.c) target_sources(app PRIVATE src/ble/ble_transport.c) target_sources(app PRIVATE src/ble/zsw_gatt_sensor_server.c) -target_sources_ifdef(CONFIG_BLE_USES_AMS app PRIVATE src/ble/ble_ams.c) +target_sources_ifdef(CONFIG_BLE_USES_IOS app PRIVATE src/ble/ble_ams.c) +target_sources_ifdef(CONFIG_BLE_USES_IOS app PRIVATE src/ble/ble_ancs.c) target_sources(app PRIVATE src/sensors/zsw_imu.c) target_sources(app PRIVATE src/sensors/zsw_pressure_sensor.c) diff --git a/app/Kconfig b/app/Kconfig index 8bcef118..de68a339 100644 --- a/app/Kconfig +++ b/app/Kconfig @@ -170,10 +170,12 @@ menu "ZSWatch" config BLE_USES_GADGETBRIDGE prompt "Smartphone interaction and notifications uses Gadgetbridge" - config BLE_USES_AMS - prompt "Smartphone uses Apple Media Service Client" + config BLE_USES_IOS + prompt "Smartphone uses Apple Services Client" + select BT_GATTP select BT_GATT_DM select BT_AMS_CLIENT + select BT_ANCS_CLIENT endchoice endmenu diff --git a/app/src/applications/music_control/music_control_app.c b/app/src/applications/music_control/music_control_app.c index 92df7660..b0c3ddc2 100644 --- a/app/src/applications/music_control/music_control_app.c +++ b/app/src/applications/music_control/music_control_app.c @@ -3,7 +3,7 @@ #include #include -#ifdef CONFIG_BLE_USES_AMS +#ifdef CONFIG_BLE_USES_IOS #include "ble/ble_ams.h" #endif @@ -85,7 +85,7 @@ static void on_music_ui_evt_music(music_control_ui_evt_type_t evt_type) ble_comm_send(buf, msg_len); } -#elif defined(CONFIG_BLE_USES_AMS) +#elif defined(CONFIG_BLE_USES_IOS) switch (evt_type) { case MUSIC_CONTROL_UI_CLOSE: @@ -105,7 +105,7 @@ static void on_music_ui_evt_music(music_control_ui_evt_type_t evt_type) break; } -#endif // CONFIG_BLE_USES_AMS +#endif // CONFIG_BLE_USES_IOS } static void zbus_ble_comm_data_callback(const struct zbus_channel *chan) diff --git a/app/src/ble/ble_ancs.c b/app/src/ble/ble_ancs.c new file mode 100644 index 00000000..6e5b9a54 --- /dev/null +++ b/app/src/ble/ble_ancs.c @@ -0,0 +1,593 @@ +/** + * @file ble_ancs.c + * @author Leonardo Bispo + * + * @brief Implements Apple Notification Center Service (ANCS), the native iOS GATT server allows the client + * to receive notifications and retrieve information from Apps. + * + * NC - Notification Source + * CP - Control Point + * DS - Data Source + * + * @see https://developer.apple.com/library/archive/documentation/CoreBluetooth/Reference/AppleNotificationCenterServiceSpecification/Specification/Specification.html + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "ble/ble_comm.h" +#include "events/ble_data_event.h" + +LOG_MODULE_REGISTER(ble_ancs, LOG_LEVEL_INF); + +enum { + DISCOVERY_ANCS_ONGOING, + DISCOVERY_ANCS_SUCCEEDED, + SERVICE_CHANGED_INDICATED +}; + +static struct bt_ancs_client ancs_c; + +static struct bt_gattp gattp; + +static atomic_t discovery_flags; + +static on_data_cb_t data_parsed_cb; + +/* Local copy to keep track of the newest arriving notifications. */ +static struct bt_ancs_evt_notif notification_latest; +/* Local copy of the newest notification attribute. */ +static struct bt_ancs_attr notif_attr_latest; +/* Local copy of the newest app attribute. */ +static struct bt_ancs_attr notif_attr_app_id_latest; +/* Local copy of the current connection. */ +static struct bt_conn *current_conn; +/* Buffers to store attribute data. */ +static uint8_t attr_appid[BT_ANCS_ATTR_DATA_MAX]; +static uint8_t attr_title[BT_ANCS_ATTR_DATA_MAX]; +static uint8_t attr_subtitle[BT_ANCS_ATTR_DATA_MAX]; +static uint8_t attr_message[BT_ANCS_ATTR_DATA_MAX]; +static uint8_t attr_message_size[BT_ANCS_ATTR_DATA_MAX]; +static uint8_t attr_date[BT_ANCS_ATTR_DATA_MAX]; +static uint8_t attr_posaction[BT_ANCS_ATTR_DATA_MAX]; +static uint8_t attr_negaction[BT_ANCS_ATTR_DATA_MAX]; +static uint8_t attr_disp_name[BT_ANCS_ATTR_DATA_MAX]; + +/* String literals for the iOS notification categories. + * Used then printing to UART. + */ +static const char *lit_catid[BT_ANCS_CATEGORY_ID_COUNT] = { + "Other", + "Incoming Call", + "Missed Call", + "Voice Mail", + "Social", + "Schedule", + "Email", + "News", + "Health And Fitness", + "Business And Finance", + "Location", + "Entertainment" +}; + +/* String literals for the iOS notification event types. + * Used then printing to UART. + */ +static const char *lit_eventid[BT_ANCS_EVT_ID_COUNT] = {"Added", + "Modified", + "Removed" + }; + +/* String literals for the iOS notification attribute types. + * Used when printing to UART. + */ +static const char *lit_attrid[BT_ANCS_NOTIF_ATTR_COUNT] = { + "App Identifier", + "Title", + "Subtitle", + "Message", + "Message Size", + "Date", + "Positive Action Label", + "Negative Action Label" +}; + +enum { + ATTR_ID_APP_ID = 0, + ATTR_ID_TITLE, + ATTR_ID_SUBTITLE, + ATTR_ID_MESSAGE, + ATTR_ID_MESSAGE_SIZE, + ATTR_ID_DATE, + ATTR_ID_POSITIVE_ACTION_LABEL, + ATTR_ID_NEGATIVE_ACTION_LABEL, +}; + +/* String literals for the iOS notification attribute types. + * Used When printing to UART. + */ +static const char *lit_appid[BT_ANCS_APP_ATTR_COUNT] = {"Display Name"}; + +static void discover_ancs_first(struct bt_conn *conn); +static void discover_ancs_again(struct bt_conn *conn); +static void bt_ancs_notification_source_handler(struct bt_ancs_client *ancs_c, int err, + const struct bt_ancs_evt_notif *notif); +static void bt_ancs_data_source_handler(struct bt_ancs_client *ancs_c, const struct bt_ancs_attr_response *response); +static void bt_ancs_write_response_handler(struct bt_ancs_client *ancs_c, uint8_t err); +static void gatt_discover_retry_handle(struct k_work *item); + +K_WORK_DELAYABLE_DEFINE(gatt_discover_retry, gatt_discover_retry_handle); + +static void enable_ancs_notifications(struct bt_ancs_client *ancs_c) +{ + int err; + + err = bt_ancs_subscribe_notification_source(ancs_c, bt_ancs_notification_source_handler); + if (err) { + LOG_ERR("Failed to enable Notification Source notification (err %d)", err); + } + + err = bt_ancs_subscribe_data_source(ancs_c, bt_ancs_data_source_handler); + if (err) { + LOG_ERR("Failed to enable Data Source notification (err %d)", err); + } +} + +static void discover_ancs_completed_cb(struct bt_gatt_dm *dm, void *ctx) +{ + struct bt_ancs_client *ancs_c = (struct bt_ancs_client *)ctx; + struct bt_conn *conn = bt_gatt_dm_conn_get(dm); + + LOG_INF("The discovery procedure for ANCS succeeded"); + + bt_gatt_dm_data_print(dm); + + int err = bt_ancs_handles_assign(dm, ancs_c); + if (err) { + LOG_ERR("Could not init ANCS client object, error: %d", err); + } else { + atomic_set_bit(&discovery_flags, DISCOVERY_ANCS_SUCCEEDED); + enable_ancs_notifications(ancs_c); + } + + err = bt_gatt_dm_data_release(dm); + if (err) { + LOG_ERR("Could not release the discovery data, error code: %d", err); + } + + atomic_clear_bit(&discovery_flags, DISCOVERY_ANCS_ONGOING); + discover_ancs_again(conn); +} + +static void discover_ancs_not_found_cb(struct bt_conn *conn, void *ctx) +{ + LOG_WRN("ANCS could not be found during the discovery"); + + atomic_clear_bit(&discovery_flags, DISCOVERY_ANCS_ONGOING); + discover_ancs_again(conn); +} + +static void discover_ancs_error_found_cb(struct bt_conn *conn, int err, void *ctx) +{ + LOG_WRN("The discovery procedure for ANCS failed, err %d", err); + + atomic_clear_bit(&discovery_flags, DISCOVERY_ANCS_ONGOING); + discover_ancs_again(conn); +} + +static const struct bt_gatt_dm_cb discover_ancs_cb = { + .completed = discover_ancs_completed_cb, + .service_not_found = discover_ancs_not_found_cb, + .error_found = discover_ancs_error_found_cb, +}; + +static void indicate_sc_cb(struct bt_gattp *gattp, + const struct bt_gattp_handle_range *handle_range, + int err) +{ + if (!err) { + atomic_set_bit(&discovery_flags, SERVICE_CHANGED_INDICATED); + discover_ancs_again(gattp->conn); + } +} + +static void enable_gattp_indications(struct bt_gattp *gattp) +{ + int err = bt_gattp_subscribe_service_changed(gattp, indicate_sc_cb); + if (err) { + LOG_ERR("Cannot subscribe to Service Changed indication (err %d)", err); + } +} + +static void discover_gattp_completed_cb(struct bt_gatt_dm *dm, void *ctx) +{ + int err; + struct bt_gattp *gattp = (struct bt_gattp *)ctx; + struct bt_conn *conn = bt_gatt_dm_conn_get(dm); + + /* Checks if the service is empty. + * Discovery Manager handles empty services. + */ + if (bt_gatt_dm_attr_cnt(dm) > 1) { + LOG_INF("The discovery procedure for GATT Service succeeded"); + + bt_gatt_dm_data_print(dm); + + err = bt_gattp_handles_assign(dm, gattp); + if (err) { + LOG_ERR("Could not init GATT Service client object, error: %d", err); + } else { + enable_gattp_indications(gattp); + } + } else { + LOG_WRN("GATT Service could not be found during the discovery"); + } + + err = bt_gatt_dm_data_release(dm); + if (err) { + LOG_ERR("Could not release the discovery data, error code: %d", err); + } + + discover_ancs_first(conn); +} + +static void discover_gattp_not_found_cb(struct bt_conn *conn, void *ctx) +{ + LOG_DBG("GATT Service could not be found during the discovery"); + + discover_ancs_first(conn); +} + +static void discover_gattp_error_found_cb(struct bt_conn *conn, int err, void *ctx) +{ + LOG_ERR("The discovery procedure for GATT Service failed, err %d", err); + + discover_ancs_first(conn); +} + +static const struct bt_gatt_dm_cb discover_gattp_cb = { + .completed = discover_gattp_completed_cb, + .service_not_found = discover_gattp_not_found_cb, + .error_found = discover_gattp_error_found_cb, +}; + +static void discover_gattp(struct bt_conn *conn) +{ + int err = bt_gatt_dm_start(conn, BT_UUID_GATT, &discover_gattp_cb, &gattp); + if (err) { + + // Only one DM discovery can happen at a time, AMS may be running, so queue it + if (err == -EALREADY) { + k_work_schedule(&gatt_discover_retry, K_MSEC(500)); + return; + } + + LOG_ERR("Failed to start discovery for GATT Service (err %d)", err); + } +} + +static void gatt_discover_retry_handle(struct k_work *item) +{ + discover_gattp(current_conn); +} + +static void discover_ancs(struct bt_conn *conn, bool retry) +{ + int err; + + /* 1 Service Discovery at a time */ + if (atomic_test_and_set_bit(&discovery_flags, DISCOVERY_ANCS_ONGOING)) { + return; + } + + /* If ANCS is found, do not discover again. */ + if (atomic_test_bit(&discovery_flags, DISCOVERY_ANCS_SUCCEEDED)) { + atomic_clear_bit(&discovery_flags, DISCOVERY_ANCS_ONGOING); + return; + } + + /* Check that Service Changed indication is received before discovering ANCS again. */ + if (retry) { + if (!atomic_test_and_clear_bit(&discovery_flags, SERVICE_CHANGED_INDICATED)) { + atomic_clear_bit(&discovery_flags, DISCOVERY_ANCS_ONGOING); + return; + } + } + + err = bt_gatt_dm_start(conn, BT_UUID_ANCS, &discover_ancs_cb, &ancs_c); + if (err) { + LOG_ERR("Failed to start discovery for ANCS (err %d)", err); + atomic_clear_bit(&discovery_flags, DISCOVERY_ANCS_ONGOING); + } +} + +static void discover_ancs_first(struct bt_conn *conn) +{ + discover_ancs(conn, false); +} + +static void discover_ancs_again(struct bt_conn *conn) +{ + discover_ancs(conn, true); +} + +static void security_changed(struct bt_conn *conn, bt_security_t level, + enum bt_security_err err) +{ + char addr[BT_ADDR_LE_STR_LEN]; + + bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr)); + + if (!err) { + LOG_INF("Security changed: %s level %u", addr, level); + + if (bt_conn_get_security(conn) >= BT_SECURITY_L2) { + discovery_flags = ATOMIC_INIT(0); + discover_gattp(conn); + } + } else { + LOG_ERR("Security failed: %s level %u err %d", addr, level, err); + } +} + +static void connected(struct bt_conn *conn, uint8_t err) +{ + if (err) { + LOG_ERR("Connection failed (err 0x%02x)\n", err); + return; + } + + current_conn = bt_conn_ref(conn); +} + +BT_CONN_CB_DEFINE(conn_callbacks) = { + .connected = connected, + .security_changed = security_changed, +}; + +/**@brief Function for printing iOS notification attribute data. + * + * @param[in] attr Pointer to an iOS App attribute. + */ +static void app_attr_print(const struct bt_ancs_attr *attr) +{ + if (attr->attr_len != 0) { + LOG_DBG("%s: %s", lit_appid[attr->attr_id], + (char *)attr->attr_data); + } else if (attr->attr_len == 0) { + LOG_DBG("%s: (N/A)", lit_appid[attr->attr_id]); + } +} + +/**@brief Function for printing out errors that originated from the Notification Provider (iOS). + * + * @param[in] err_code_np Error code received from NP. + */ +static void err_code_print(uint8_t err_code_np) +{ + switch (err_code_np) { + case BT_ATT_ERR_ANCS_NP_UNKNOWN_COMMAND: + LOG_DBG("Error: Command ID was not recognized by the Notification Provider."); + break; + + case BT_ATT_ERR_ANCS_NP_INVALID_COMMAND: + LOG_DBG("Error: Command failed to be parsed on the Notification Provider."); + break; + + case BT_ATT_ERR_ANCS_NP_INVALID_PARAMETER: + LOG_DBG("Error: Parameter does not refer to an existing object on the Notification Provider."); + break; + + case BT_ATT_ERR_ANCS_NP_ACTION_FAILED: + LOG_DBG("Error: Perform Notification Action Failed on the Notification Provider."); + break; + + default: + break; + } +} + +/**@brief Function for printing iOS notification attribute data. + * + * @param[in] attr Pointer to an iOS notification attribute. + */ +static void notif_attr_print(const struct bt_ancs_attr *attr) +{ + if (attr->attr_len != 0) { + LOG_DBG("%s: %s", lit_attrid[attr->attr_id], + (char *)attr->attr_data); + } else if (attr->attr_len == 0) { + LOG_DBG("%s: (N/A)", lit_attrid[attr->attr_id]); + } +} + +static int parse_notify(const struct bt_ancs_attr *attr) +{ + static ble_comm_cb_data_t cb = { '\0' }; + + switch (attr->attr_id) { + case ATTR_ID_TITLE: + cb.data.notify.title = attr->attr_data; + cb.data.notify.title_len = attr->attr_len; + break; + + case ATTR_ID_MESSAGE: + cb.data.notify.body = (char *)attr->attr_data; + cb.data.notify.body_len = attr->attr_len; + break; + + case ATTR_ID_APP_ID: + // This comes as example com.facebook.Messenger, so use length as id + cb.data.notify.src = (char *)attr->attr_data; + cb.data.notify.src_len = attr->attr_len; + cb.data.notify.id = attr->attr_len; + break; + + // the last message is Negative action label, send only when all data is received; + case ATTR_ID_NEGATIVE_ACTION_LABEL: + cb.type = BLE_COMM_DATA_TYPE_NOTIFY; + data_parsed_cb(&cb); + memset(&cb, 0, sizeof(cb)); + break; + + case ATTR_ID_DATE: + case ATTR_ID_MESSAGE_SIZE: + case ATTR_ID_SUBTITLE: + case ATTR_ID_POSITIVE_ACTION_LABEL: + default: + // @todo + break; + } + + return 0; +} + +static void bt_ancs_notification_source_handler(struct bt_ancs_client *ancs_c, + int err, const struct bt_ancs_evt_notif *notif) +{ + if (!err) { + notification_latest = *notif; + bt_ancs_request_attrs(ancs_c, ¬ification_latest, bt_ancs_write_response_handler); + } +} + +static void bt_ancs_data_source_handler(struct bt_ancs_client *ancs_c, + const struct bt_ancs_attr_response *response) +{ + switch (response->command_id) { + case BT_ANCS_COMMAND_ID_GET_NOTIF_ATTRIBUTES: + notif_attr_latest = response->attr; + notif_attr_print(¬if_attr_latest); + parse_notify(¬if_attr_latest); + if (response->attr.attr_id == + BT_ANCS_NOTIF_ATTR_ID_APP_IDENTIFIER) { + notif_attr_app_id_latest = response->attr; + } + break; + + case BT_ANCS_COMMAND_ID_GET_APP_ATTRIBUTES: + app_attr_print(&response->attr); + break; + + default: + /* No implementation needed. */ + break; + } +} + +static void bt_ancs_write_response_handler(struct bt_ancs_client *ancs_c, + uint8_t err) +{ + err_code_print(err); +} + +static int gattp_init(void) +{ + return bt_gattp_init(&gattp); +} + + +int ble_ancs_init(on_data_cb_t data_cb) +{ + int err = bt_ancs_client_init(&ancs_c); + if (err) { + LOG_ERR("Failed to start ANCS: 0x%x", err); + return err; + } + + err = bt_ancs_register_attr(&ancs_c, + BT_ANCS_NOTIF_ATTR_ID_APP_IDENTIFIER, + attr_appid, BT_ANCS_ATTR_DATA_MAX); + if (err) { + LOG_ERR("Failed to start ANCS: 0x%x", err); + return err; + } + + err = bt_ancs_register_app_attr(&ancs_c, + BT_ANCS_APP_ATTR_ID_DISPLAY_NAME, + attr_disp_name, sizeof(attr_disp_name)); + if (err) { + LOG_ERR("Failed to start ANCS: 0x%x", err); + return err; + } + + err = bt_ancs_register_attr(&ancs_c, + BT_ANCS_NOTIF_ATTR_ID_TITLE, + attr_title, BT_ANCS_ATTR_DATA_MAX); + if (err) { + LOG_ERR("Failed to start ANCS: 0x%x", err); + return err; + } + + err = bt_ancs_register_attr(&ancs_c, + BT_ANCS_NOTIF_ATTR_ID_MESSAGE, + attr_message, BT_ANCS_ATTR_DATA_MAX); + if (err) { + LOG_ERR("Failed to start ANCS: 0x%x", err); + return err; + } + + err = bt_ancs_register_attr(&ancs_c, + BT_ANCS_NOTIF_ATTR_ID_SUBTITLE, + attr_subtitle, BT_ANCS_ATTR_DATA_MAX); + if (err) { + LOG_ERR("Failed to start ANCS: 0x%x", err); + return err; + } + + err = bt_ancs_register_attr(&ancs_c, + BT_ANCS_NOTIF_ATTR_ID_MESSAGE_SIZE, + attr_message_size, BT_ANCS_ATTR_DATA_MAX); + if (err) { + LOG_ERR("Failed to start ANCS: 0x%x", err); + return err; + } + + err = bt_ancs_register_attr(&ancs_c, + BT_ANCS_NOTIF_ATTR_ID_DATE, + attr_date, BT_ANCS_ATTR_DATA_MAX); + if (err) { + LOG_ERR("Failed to start ANCS: 0x%x", err); + return err; + } + + err = bt_ancs_register_attr(&ancs_c, + BT_ANCS_NOTIF_ATTR_ID_POSITIVE_ACTION_LABEL, + attr_posaction, BT_ANCS_ATTR_DATA_MAX); + if (err) { + LOG_ERR("Failed to start ANCS: 0x%x", err); + return err; + } + + err = bt_ancs_register_attr(&ancs_c, + BT_ANCS_NOTIF_ATTR_ID_NEGATIVE_ACTION_LABEL, + attr_negaction, BT_ANCS_ATTR_DATA_MAX); + if (err) { + LOG_ERR("Failed to start ANCS: 0x%x", err); + return err; + } + + err = gattp_init(); + if (err) { + LOG_ERR("Failed to start ANCS: 0x%x", err); + return err; + } + + data_parsed_cb = data_cb; + + LOG_INF("Started Apple Notification Center Service client"); + + return err; +} diff --git a/app/src/ble/ble_ancs.h b/app/src/ble/ble_ancs.h new file mode 100644 index 00000000..1896cc0f --- /dev/null +++ b/app/src/ble/ble_ancs.h @@ -0,0 +1,9 @@ +#ifndef __BLE_ANCS_H +#define __BLE_ANCS_H + +#include +#include "ble/ble_comm.h" + +int ble_ancs_init(on_data_cb_t data_cb); + +#endif \ No newline at end of file diff --git a/app/src/ble/ble_comm.c b/app/src/ble/ble_comm.c index 52387f2a..1838b15a 100644 --- a/app/src/ble/ble_comm.c +++ b/app/src/ble/ble_comm.c @@ -34,6 +34,7 @@ #ifdef CONFIG_BT_AMS_CLIENT #include +#include #endif LOG_MODULE_REGISTER(ble_comm, LOG_LEVEL_DBG); @@ -79,7 +80,7 @@ static const struct bt_data ad[] = { BT_DATA_BYTES(BT_DATA_UUID16_ALL, BT_UUID_16_ENCODE(BT_UUID_DIS_VAL)), #ifdef CONFIG_BT_AMS_CLIENT - BT_DATA_BYTES(BT_DATA_SOLICIT128, BT_UUID_AMS_VAL) + BT_DATA_BYTES(BT_DATA_SOLICIT128, BT_UUID_ANCS_VAL), #endif }; diff --git a/app/src/main.c b/app/src/main.c index 3bc4583e..303b64f1 100644 --- a/app/src/main.c +++ b/app/src/main.c @@ -54,8 +54,9 @@ #include "applications/watchface/watchface_app.h" #include -#ifdef CONFIG_BLE_USES_AMS +#ifdef CONFIG_BLE_USES_IOS #include "ble/ble_ams.h" +#include "ble/ble_ancs.h" #endif LOG_MODULE_REGISTER(main, LOG_LEVEL_WRN); @@ -319,8 +320,9 @@ static void enable_bluetoth(void) __ASSERT_NO_MSG(ble_comm_init(on_ble_data_callback) == 0); bleAoaInit(); -#ifdef CONFIG_BLE_USES_AMS +#ifdef CONFIG_BLE_USES_IOS ble_ams_init(); + ble_ancs_init(on_ble_data_callback); #endif }