BLE_Nano nRF51 Central heart rate
main.c@0:2b9b5764efb5, 2016-05-26 (annotated)
- Committer:
- FranKP2138
- Date:
- Thu May 26 10:12:27 2016 +0000
- Revision:
- 0:2b9b5764efb5
RedBearLab BLE_Nano Central role for heart rate
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
FranKP2138 | 0:2b9b5764efb5 | 1 | /* |
FranKP2138 | 0:2b9b5764efb5 | 2 | * Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. |
FranKP2138 | 0:2b9b5764efb5 | 3 | * |
FranKP2138 | 0:2b9b5764efb5 | 4 | * The information contained herein is confidential property of Nordic Semiconductor. The use, |
FranKP2138 | 0:2b9b5764efb5 | 5 | * copying, transfer or disclosure of such information is prohibited except by express written |
FranKP2138 | 0:2b9b5764efb5 | 6 | * agreement with Nordic Semiconductor. |
FranKP2138 | 0:2b9b5764efb5 | 7 | * |
FranKP2138 | 0:2b9b5764efb5 | 8 | */ |
FranKP2138 | 0:2b9b5764efb5 | 9 | |
FranKP2138 | 0:2b9b5764efb5 | 10 | /** |
FranKP2138 | 0:2b9b5764efb5 | 11 | * @brief BLE Heart Rate Collector application main file. |
FranKP2138 | 0:2b9b5764efb5 | 12 | * |
FranKP2138 | 0:2b9b5764efb5 | 13 | * This file contains the source code for a sample heart rate collector. |
FranKP2138 | 0:2b9b5764efb5 | 14 | */ |
FranKP2138 | 0:2b9b5764efb5 | 15 | |
FranKP2138 | 0:2b9b5764efb5 | 16 | #include <stdint.h> |
FranKP2138 | 0:2b9b5764efb5 | 17 | #include <stdio.h> |
FranKP2138 | 0:2b9b5764efb5 | 18 | #include <string.h> |
FranKP2138 | 0:2b9b5764efb5 | 19 | #include "nordic_common.h" |
FranKP2138 | 0:2b9b5764efb5 | 20 | #include "nrf_sdm.h" |
FranKP2138 | 0:2b9b5764efb5 | 21 | #include "ble.h" |
FranKP2138 | 0:2b9b5764efb5 | 22 | #include "ble_hci.h" |
FranKP2138 | 0:2b9b5764efb5 | 23 | #include "ble_db_discovery.h" |
FranKP2138 | 0:2b9b5764efb5 | 24 | #include "softdevice_handler.h" |
FranKP2138 | 0:2b9b5764efb5 | 25 | #include "app_util.h" |
FranKP2138 | 0:2b9b5764efb5 | 26 | #include "app_error.h" |
FranKP2138 | 0:2b9b5764efb5 | 27 | #include "boards.h" |
FranKP2138 | 0:2b9b5764efb5 | 28 | #include "nrf_gpio.h" |
FranKP2138 | 0:2b9b5764efb5 | 29 | #include "pstorage.h" |
FranKP2138 | 0:2b9b5764efb5 | 30 | #include "device_manager.h" |
FranKP2138 | 0:2b9b5764efb5 | 31 | #include "ble_hrs_c.h" |
FranKP2138 | 0:2b9b5764efb5 | 32 | #include "ble_bas_c.h" |
FranKP2138 | 0:2b9b5764efb5 | 33 | #include "app_util.h" |
FranKP2138 | 0:2b9b5764efb5 | 34 | #include "app_timer.h" |
FranKP2138 | 0:2b9b5764efb5 | 35 | #include "bsp.h" |
FranKP2138 | 0:2b9b5764efb5 | 36 | #include "bsp_btn_ble.h" |
FranKP2138 | 0:2b9b5764efb5 | 37 | #include "nrf_log.h" |
FranKP2138 | 0:2b9b5764efb5 | 38 | |
FranKP2138 | 0:2b9b5764efb5 | 39 | #define CENTRAL_LINK_COUNT 1 /**< Number of central links used by the application. When changing this number remember to adjust the RAM settings*/ |
FranKP2138 | 0:2b9b5764efb5 | 40 | #define PERIPHERAL_LINK_COUNT 0 /**< Number of peripheral links used by the application. When changing this number remember to adjust the RAM settings*/ |
FranKP2138 | 0:2b9b5764efb5 | 41 | |
FranKP2138 | 0:2b9b5764efb5 | 42 | #define STRING_BUFFER_LEN 50 |
FranKP2138 | 0:2b9b5764efb5 | 43 | #define BOND_DELETE_ALL_BUTTON_ID 0 /**< Button used for deleting all bonded centrals during startup. */ |
FranKP2138 | 0:2b9b5764efb5 | 44 | |
FranKP2138 | 0:2b9b5764efb5 | 45 | #define APP_TIMER_PRESCALER 0 /**< Value of the RTC1 PRESCALER register. */ |
FranKP2138 | 0:2b9b5764efb5 | 46 | #define APP_TIMER_OP_QUEUE_SIZE 2 /**< Size of timer operation queues. */ |
FranKP2138 | 0:2b9b5764efb5 | 47 | |
FranKP2138 | 0:2b9b5764efb5 | 48 | #define APPL_LOG NRF_LOG_PRINTF /**< Logger macro that will be used in this file to do logging over UART or RTT based on nrf_log configuration. */ |
FranKP2138 | 0:2b9b5764efb5 | 49 | #define APPL_LOG_DEBUG NRF_LOG_PRINTF_DEBUG /**< Debug logger macro that will be used in this file to do logging of debug information over UART or RTT based on nrf_log configuration. This will only work if DEBUG is defined*/ |
FranKP2138 | 0:2b9b5764efb5 | 50 | |
FranKP2138 | 0:2b9b5764efb5 | 51 | #define SEC_PARAM_BOND 1 /**< Perform bonding. */ |
FranKP2138 | 0:2b9b5764efb5 | 52 | #define SEC_PARAM_MITM 1 /**< Man In The Middle protection not required. */ |
FranKP2138 | 0:2b9b5764efb5 | 53 | #define SEC_PARAM_LESC 0 /**< LE Secure Connections not enabled. */ |
FranKP2138 | 0:2b9b5764efb5 | 54 | #define SEC_PARAM_KEYPRESS 0 /**< Keypress notifications not enabled. */ |
FranKP2138 | 0:2b9b5764efb5 | 55 | #define SEC_PARAM_IO_CAPABILITIES BLE_GAP_IO_CAPS_NONE /**< No I/O capabilities. */ |
FranKP2138 | 0:2b9b5764efb5 | 56 | #define SEC_PARAM_OOB 0 /**< Out Of Band data not available. */ |
FranKP2138 | 0:2b9b5764efb5 | 57 | #define SEC_PARAM_MIN_KEY_SIZE 7 /**< Minimum encryption key size. */ |
FranKP2138 | 0:2b9b5764efb5 | 58 | #define SEC_PARAM_MAX_KEY_SIZE 16 /**< Maximum encryption key size. */ |
FranKP2138 | 0:2b9b5764efb5 | 59 | |
FranKP2138 | 0:2b9b5764efb5 | 60 | #define SCAN_INTERVAL 0x00A0 /**< Determines scan interval in units of 0.625 millisecond. */ |
FranKP2138 | 0:2b9b5764efb5 | 61 | #define SCAN_WINDOW 0x0050 /**< Determines scan window in units of 0.625 millisecond. */ |
FranKP2138 | 0:2b9b5764efb5 | 62 | |
FranKP2138 | 0:2b9b5764efb5 | 63 | #define MIN_CONNECTION_INTERVAL MSEC_TO_UNITS(7.5, UNIT_1_25_MS) /**< Determines minimum connection interval in millisecond. */ |
FranKP2138 | 0:2b9b5764efb5 | 64 | #define MAX_CONNECTION_INTERVAL MSEC_TO_UNITS(30, UNIT_1_25_MS) /**< Determines maximum connection interval in millisecond. */ |
FranKP2138 | 0:2b9b5764efb5 | 65 | #define SLAVE_LATENCY 0 /**< Determines slave latency in counts of connection events. */ |
FranKP2138 | 0:2b9b5764efb5 | 66 | #define SUPERVISION_TIMEOUT MSEC_TO_UNITS(4000, UNIT_10_MS) /**< Determines supervision time-out in units of 10 millisecond. */ |
FranKP2138 | 0:2b9b5764efb5 | 67 | |
FranKP2138 | 0:2b9b5764efb5 | 68 | #define TARGET_UUID 0x180D /**< Target device name that application is looking for. */ |
FranKP2138 | 0:2b9b5764efb5 | 69 | #define UUID16_SIZE 2 /**< Size of 16 bit UUID */ |
FranKP2138 | 0:2b9b5764efb5 | 70 | |
FranKP2138 | 0:2b9b5764efb5 | 71 | /**@breif Macro to unpack 16bit unsigned UUID from octet stream. */ |
FranKP2138 | 0:2b9b5764efb5 | 72 | #define UUID16_EXTRACT(DST, SRC) \ |
FranKP2138 | 0:2b9b5764efb5 | 73 | do \ |
FranKP2138 | 0:2b9b5764efb5 | 74 | { \ |
FranKP2138 | 0:2b9b5764efb5 | 75 | (*(DST)) = (SRC)[1]; \ |
FranKP2138 | 0:2b9b5764efb5 | 76 | (*(DST)) <<= 8; \ |
FranKP2138 | 0:2b9b5764efb5 | 77 | (*(DST)) |= (SRC)[0]; \ |
FranKP2138 | 0:2b9b5764efb5 | 78 | } while (0) |
FranKP2138 | 0:2b9b5764efb5 | 79 | |
FranKP2138 | 0:2b9b5764efb5 | 80 | /**@brief Variable length data encapsulation in terms of length and pointer to data */ |
FranKP2138 | 0:2b9b5764efb5 | 81 | typedef struct |
FranKP2138 | 0:2b9b5764efb5 | 82 | { |
FranKP2138 | 0:2b9b5764efb5 | 83 | uint8_t * p_data; /**< Pointer to data. */ |
FranKP2138 | 0:2b9b5764efb5 | 84 | uint16_t data_len; /**< Length of data. */ |
FranKP2138 | 0:2b9b5764efb5 | 85 | }data_t; |
FranKP2138 | 0:2b9b5764efb5 | 86 | |
FranKP2138 | 0:2b9b5764efb5 | 87 | typedef enum |
FranKP2138 | 0:2b9b5764efb5 | 88 | { |
FranKP2138 | 0:2b9b5764efb5 | 89 | BLE_NO_SCAN, /**< No advertising running. */ |
FranKP2138 | 0:2b9b5764efb5 | 90 | BLE_WHITELIST_SCAN, /**< Advertising with whitelist. */ |
FranKP2138 | 0:2b9b5764efb5 | 91 | BLE_FAST_SCAN, /**< Fast advertising running. */ |
FranKP2138 | 0:2b9b5764efb5 | 92 | } ble_scan_mode_t; |
FranKP2138 | 0:2b9b5764efb5 | 93 | |
FranKP2138 | 0:2b9b5764efb5 | 94 | static ble_db_discovery_t m_ble_db_discovery; /**< Structure used to identify the DB Discovery module. */ |
FranKP2138 | 0:2b9b5764efb5 | 95 | static ble_hrs_c_t m_ble_hrs_c; /**< Structure used to identify the heart rate client module. */ |
FranKP2138 | 0:2b9b5764efb5 | 96 | static ble_bas_c_t m_ble_bas_c; /**< Structure used to identify the Battery Service client module. */ |
FranKP2138 | 0:2b9b5764efb5 | 97 | static ble_gap_scan_params_t m_scan_param; /**< Scan parameters requested for scanning and connection. */ |
FranKP2138 | 0:2b9b5764efb5 | 98 | static dm_application_instance_t m_dm_app_id; /**< Application identifier. */ |
FranKP2138 | 0:2b9b5764efb5 | 99 | static dm_handle_t m_dm_device_handle; /**< Device Identifier identifier. */ |
FranKP2138 | 0:2b9b5764efb5 | 100 | static uint8_t m_peer_count = 0; /**< Number of peer's connected. */ |
FranKP2138 | 0:2b9b5764efb5 | 101 | static ble_scan_mode_t m_scan_mode = BLE_FAST_SCAN; /**< Scan mode used by application. */ |
FranKP2138 | 0:2b9b5764efb5 | 102 | static uint16_t m_conn_handle; /**< Current connection handle. */ |
FranKP2138 | 0:2b9b5764efb5 | 103 | static volatile bool m_whitelist_temporarily_disabled = false; /**< True if whitelist has been temporarily disabled. */ |
FranKP2138 | 0:2b9b5764efb5 | 104 | |
FranKP2138 | 0:2b9b5764efb5 | 105 | static bool m_memory_access_in_progress = false; /**< Flag to keep track of ongoing operations on persistent memory. */ |
FranKP2138 | 0:2b9b5764efb5 | 106 | |
FranKP2138 | 0:2b9b5764efb5 | 107 | /** |
FranKP2138 | 0:2b9b5764efb5 | 108 | * @brief Connection parameters requested for connection. |
FranKP2138 | 0:2b9b5764efb5 | 109 | */ |
FranKP2138 | 0:2b9b5764efb5 | 110 | static const ble_gap_conn_params_t m_connection_param = |
FranKP2138 | 0:2b9b5764efb5 | 111 | { |
FranKP2138 | 0:2b9b5764efb5 | 112 | (uint16_t)MIN_CONNECTION_INTERVAL, // Minimum connection |
FranKP2138 | 0:2b9b5764efb5 | 113 | (uint16_t)MAX_CONNECTION_INTERVAL, // Maximum connection |
FranKP2138 | 0:2b9b5764efb5 | 114 | 0, // Slave latency |
FranKP2138 | 0:2b9b5764efb5 | 115 | (uint16_t)SUPERVISION_TIMEOUT // Supervision time-out |
FranKP2138 | 0:2b9b5764efb5 | 116 | }; |
FranKP2138 | 0:2b9b5764efb5 | 117 | |
FranKP2138 | 0:2b9b5764efb5 | 118 | static void scan_start(void); |
FranKP2138 | 0:2b9b5764efb5 | 119 | |
FranKP2138 | 0:2b9b5764efb5 | 120 | |
FranKP2138 | 0:2b9b5764efb5 | 121 | /**@brief Function for asserts in the SoftDevice. |
FranKP2138 | 0:2b9b5764efb5 | 122 | * |
FranKP2138 | 0:2b9b5764efb5 | 123 | * @details This function will be called in case of an assert in the SoftDevice. |
FranKP2138 | 0:2b9b5764efb5 | 124 | * |
FranKP2138 | 0:2b9b5764efb5 | 125 | * @warning This handler is an example only and does not fit a final product. You need to analyze |
FranKP2138 | 0:2b9b5764efb5 | 126 | * how your product is supposed to react in case of Assert. |
FranKP2138 | 0:2b9b5764efb5 | 127 | * @warning On assert from the SoftDevice, the system can only recover on reset. |
FranKP2138 | 0:2b9b5764efb5 | 128 | * |
FranKP2138 | 0:2b9b5764efb5 | 129 | * @param[in] line_num Line number of the failing ASSERT call. |
FranKP2138 | 0:2b9b5764efb5 | 130 | * @param[in] p_file_name File name of the failing ASSERT call. |
FranKP2138 | 0:2b9b5764efb5 | 131 | */ |
FranKP2138 | 0:2b9b5764efb5 | 132 | void assert_nrf_callback(uint16_t line_num, const uint8_t * p_file_name) |
FranKP2138 | 0:2b9b5764efb5 | 133 | { |
FranKP2138 | 0:2b9b5764efb5 | 134 | app_error_handler(0xDEADBEEF, line_num, p_file_name); |
FranKP2138 | 0:2b9b5764efb5 | 135 | } |
FranKP2138 | 0:2b9b5764efb5 | 136 | |
FranKP2138 | 0:2b9b5764efb5 | 137 | void uart_error_handle(app_uart_evt_t * p_event) |
FranKP2138 | 0:2b9b5764efb5 | 138 | { |
FranKP2138 | 0:2b9b5764efb5 | 139 | if (p_event->evt_type == APP_UART_COMMUNICATION_ERROR) |
FranKP2138 | 0:2b9b5764efb5 | 140 | { |
FranKP2138 | 0:2b9b5764efb5 | 141 | APP_ERROR_HANDLER(p_event->data.error_communication); |
FranKP2138 | 0:2b9b5764efb5 | 142 | } |
FranKP2138 | 0:2b9b5764efb5 | 143 | else if (p_event->evt_type == APP_UART_FIFO_ERROR) |
FranKP2138 | 0:2b9b5764efb5 | 144 | { |
FranKP2138 | 0:2b9b5764efb5 | 145 | APP_ERROR_HANDLER(p_event->data.error_code); |
FranKP2138 | 0:2b9b5764efb5 | 146 | } |
FranKP2138 | 0:2b9b5764efb5 | 147 | } |
FranKP2138 | 0:2b9b5764efb5 | 148 | |
FranKP2138 | 0:2b9b5764efb5 | 149 | |
FranKP2138 | 0:2b9b5764efb5 | 150 | /**@brief Function for handling database discovery events. |
FranKP2138 | 0:2b9b5764efb5 | 151 | * |
FranKP2138 | 0:2b9b5764efb5 | 152 | * @details This function is callback function to handle events from the database discovery module. |
FranKP2138 | 0:2b9b5764efb5 | 153 | * Depending on the UUIDs that are discovered, this function should forward the events |
FranKP2138 | 0:2b9b5764efb5 | 154 | * to their respective services. |
FranKP2138 | 0:2b9b5764efb5 | 155 | * |
FranKP2138 | 0:2b9b5764efb5 | 156 | * @param[in] p_event Pointer to the database discovery event. |
FranKP2138 | 0:2b9b5764efb5 | 157 | */ |
FranKP2138 | 0:2b9b5764efb5 | 158 | static void db_disc_handler(ble_db_discovery_evt_t * p_evt) |
FranKP2138 | 0:2b9b5764efb5 | 159 | { |
FranKP2138 | 0:2b9b5764efb5 | 160 | ble_hrs_on_db_disc_evt(&m_ble_hrs_c, p_evt); |
FranKP2138 | 0:2b9b5764efb5 | 161 | ble_bas_on_db_disc_evt(&m_ble_bas_c, p_evt); |
FranKP2138 | 0:2b9b5764efb5 | 162 | } |
FranKP2138 | 0:2b9b5764efb5 | 163 | |
FranKP2138 | 0:2b9b5764efb5 | 164 | |
FranKP2138 | 0:2b9b5764efb5 | 165 | /**@brief Callback handling device manager events. |
FranKP2138 | 0:2b9b5764efb5 | 166 | * |
FranKP2138 | 0:2b9b5764efb5 | 167 | * @details This function is called to notify the application of device manager events. |
FranKP2138 | 0:2b9b5764efb5 | 168 | * |
FranKP2138 | 0:2b9b5764efb5 | 169 | * @param[in] p_handle Device Manager Handle. For link related events, this parameter |
FranKP2138 | 0:2b9b5764efb5 | 170 | * identifies the peer. |
FranKP2138 | 0:2b9b5764efb5 | 171 | * @param[in] p_event Pointer to the device manager event. |
FranKP2138 | 0:2b9b5764efb5 | 172 | * @param[in] event_status Status of the event. |
FranKP2138 | 0:2b9b5764efb5 | 173 | */ |
FranKP2138 | 0:2b9b5764efb5 | 174 | static ret_code_t device_manager_event_handler(const dm_handle_t * p_handle, |
FranKP2138 | 0:2b9b5764efb5 | 175 | const dm_event_t * p_event, |
FranKP2138 | 0:2b9b5764efb5 | 176 | const ret_code_t event_result) |
FranKP2138 | 0:2b9b5764efb5 | 177 | { |
FranKP2138 | 0:2b9b5764efb5 | 178 | uint32_t err_code; |
FranKP2138 | 0:2b9b5764efb5 | 179 | |
FranKP2138 | 0:2b9b5764efb5 | 180 | switch (p_event->event_id) |
FranKP2138 | 0:2b9b5764efb5 | 181 | { |
FranKP2138 | 0:2b9b5764efb5 | 182 | case DM_EVT_CONNECTION: |
FranKP2138 | 0:2b9b5764efb5 | 183 | { |
FranKP2138 | 0:2b9b5764efb5 | 184 | APPL_LOG_DEBUG("[APPL]: >> DM_EVT_CONNECTION\r\n"); |
FranKP2138 | 0:2b9b5764efb5 | 185 | #ifdef ENABLE_DEBUG_LOG_SUPPORT |
FranKP2138 | 0:2b9b5764efb5 | 186 | ble_gap_addr_t * peer_addr; |
FranKP2138 | 0:2b9b5764efb5 | 187 | peer_addr = &p_event->event_param.p_gap_param->params.connected.peer_addr; |
FranKP2138 | 0:2b9b5764efb5 | 188 | APPL_LOG_DEBUG("[APPL]:[%02X %02X %02X %02X %02X %02X]: Connection Established\r\n", |
FranKP2138 | 0:2b9b5764efb5 | 189 | peer_addr->addr[0], peer_addr->addr[1], peer_addr->addr[2], |
FranKP2138 | 0:2b9b5764efb5 | 190 | peer_addr->addr[3], peer_addr->addr[4], peer_addr->addr[5]); |
FranKP2138 | 0:2b9b5764efb5 | 191 | #endif // ENABLE_DEBUG_LOG_SUPPORT |
FranKP2138 | 0:2b9b5764efb5 | 192 | |
FranKP2138 | 0:2b9b5764efb5 | 193 | err_code = bsp_indication_set(BSP_INDICATE_CONNECTED); |
FranKP2138 | 0:2b9b5764efb5 | 194 | APP_ERROR_CHECK(err_code); |
FranKP2138 | 0:2b9b5764efb5 | 195 | |
FranKP2138 | 0:2b9b5764efb5 | 196 | m_conn_handle = p_event->event_param.p_gap_param->conn_handle; |
FranKP2138 | 0:2b9b5764efb5 | 197 | |
FranKP2138 | 0:2b9b5764efb5 | 198 | m_dm_device_handle = (*p_handle); |
FranKP2138 | 0:2b9b5764efb5 | 199 | |
FranKP2138 | 0:2b9b5764efb5 | 200 | // Initiate bonding. |
FranKP2138 | 0:2b9b5764efb5 | 201 | err_code = dm_security_setup_req(&m_dm_device_handle); |
FranKP2138 | 0:2b9b5764efb5 | 202 | APP_ERROR_CHECK(err_code); |
FranKP2138 | 0:2b9b5764efb5 | 203 | |
FranKP2138 | 0:2b9b5764efb5 | 204 | m_peer_count++; |
FranKP2138 | 0:2b9b5764efb5 | 205 | |
FranKP2138 | 0:2b9b5764efb5 | 206 | if (m_peer_count < CENTRAL_LINK_COUNT) |
FranKP2138 | 0:2b9b5764efb5 | 207 | { |
FranKP2138 | 0:2b9b5764efb5 | 208 | scan_start(); |
FranKP2138 | 0:2b9b5764efb5 | 209 | } |
FranKP2138 | 0:2b9b5764efb5 | 210 | APPL_LOG_DEBUG("[APPL]: << DM_EVT_CONNECTION\r\n"); |
FranKP2138 | 0:2b9b5764efb5 | 211 | break; |
FranKP2138 | 0:2b9b5764efb5 | 212 | } |
FranKP2138 | 0:2b9b5764efb5 | 213 | |
FranKP2138 | 0:2b9b5764efb5 | 214 | case DM_EVT_DISCONNECTION: |
FranKP2138 | 0:2b9b5764efb5 | 215 | { |
FranKP2138 | 0:2b9b5764efb5 | 216 | APPL_LOG_DEBUG("[APPL]: >> DM_EVT_DISCONNECTION\r\n"); |
FranKP2138 | 0:2b9b5764efb5 | 217 | memset(&m_ble_db_discovery, 0 , sizeof (m_ble_db_discovery)); |
FranKP2138 | 0:2b9b5764efb5 | 218 | |
FranKP2138 | 0:2b9b5764efb5 | 219 | err_code = bsp_indication_set(BSP_INDICATE_IDLE); |
FranKP2138 | 0:2b9b5764efb5 | 220 | APP_ERROR_CHECK(err_code); |
FranKP2138 | 0:2b9b5764efb5 | 221 | |
FranKP2138 | 0:2b9b5764efb5 | 222 | if (m_peer_count == CENTRAL_LINK_COUNT) |
FranKP2138 | 0:2b9b5764efb5 | 223 | { |
FranKP2138 | 0:2b9b5764efb5 | 224 | scan_start(); |
FranKP2138 | 0:2b9b5764efb5 | 225 | } |
FranKP2138 | 0:2b9b5764efb5 | 226 | m_peer_count--; |
FranKP2138 | 0:2b9b5764efb5 | 227 | APPL_LOG_DEBUG("[APPL]: << DM_EVT_DISCONNECTION\r\n"); |
FranKP2138 | 0:2b9b5764efb5 | 228 | break; |
FranKP2138 | 0:2b9b5764efb5 | 229 | } |
FranKP2138 | 0:2b9b5764efb5 | 230 | |
FranKP2138 | 0:2b9b5764efb5 | 231 | case DM_EVT_SECURITY_SETUP: |
FranKP2138 | 0:2b9b5764efb5 | 232 | { |
FranKP2138 | 0:2b9b5764efb5 | 233 | APPL_LOG_DEBUG("[APPL]:[0x%02X] >> DM_EVT_SECURITY_SETUP\r\n", p_handle->connection_id); |
FranKP2138 | 0:2b9b5764efb5 | 234 | // Slave securtiy request received from peer, if from a non bonded device, |
FranKP2138 | 0:2b9b5764efb5 | 235 | // initiate security setup, else, wait for encryption to complete. |
FranKP2138 | 0:2b9b5764efb5 | 236 | err_code = dm_security_setup_req(&m_dm_device_handle); |
FranKP2138 | 0:2b9b5764efb5 | 237 | APP_ERROR_CHECK(err_code); |
FranKP2138 | 0:2b9b5764efb5 | 238 | APPL_LOG_DEBUG("[APPL]:[0x%02X] << DM_EVT_SECURITY_SETUP\r\n", p_handle->connection_id); |
FranKP2138 | 0:2b9b5764efb5 | 239 | break; |
FranKP2138 | 0:2b9b5764efb5 | 240 | } |
FranKP2138 | 0:2b9b5764efb5 | 241 | |
FranKP2138 | 0:2b9b5764efb5 | 242 | case DM_EVT_SECURITY_SETUP_COMPLETE: |
FranKP2138 | 0:2b9b5764efb5 | 243 | { |
FranKP2138 | 0:2b9b5764efb5 | 244 | APPL_LOG_DEBUG("[APPL]: >> DM_EVT_SECURITY_SETUP_COMPLETE\r\n"); |
FranKP2138 | 0:2b9b5764efb5 | 245 | APPL_LOG_DEBUG("[APPL]: << DM_EVT_SECURITY_SETUP_COMPLETE\r\n"); |
FranKP2138 | 0:2b9b5764efb5 | 246 | break; |
FranKP2138 | 0:2b9b5764efb5 | 247 | } |
FranKP2138 | 0:2b9b5764efb5 | 248 | |
FranKP2138 | 0:2b9b5764efb5 | 249 | case DM_EVT_LINK_SECURED: |
FranKP2138 | 0:2b9b5764efb5 | 250 | APPL_LOG_DEBUG("[APPL]: >> DM_LINK_SECURED_IND\r\n"); |
FranKP2138 | 0:2b9b5764efb5 | 251 | // Discover peer's services. |
FranKP2138 | 0:2b9b5764efb5 | 252 | err_code = ble_db_discovery_start(&m_ble_db_discovery, |
FranKP2138 | 0:2b9b5764efb5 | 253 | p_event->event_param.p_gap_param->conn_handle); |
FranKP2138 | 0:2b9b5764efb5 | 254 | APP_ERROR_CHECK(err_code); |
FranKP2138 | 0:2b9b5764efb5 | 255 | APPL_LOG_DEBUG("[APPL]: << DM_LINK_SECURED_IND\r\n"); |
FranKP2138 | 0:2b9b5764efb5 | 256 | break; |
FranKP2138 | 0:2b9b5764efb5 | 257 | |
FranKP2138 | 0:2b9b5764efb5 | 258 | case DM_EVT_DEVICE_CONTEXT_LOADED: |
FranKP2138 | 0:2b9b5764efb5 | 259 | APPL_LOG_DEBUG("[APPL]: >> DM_EVT_LINK_SECURED\r\n"); |
FranKP2138 | 0:2b9b5764efb5 | 260 | APP_ERROR_CHECK(event_result); |
FranKP2138 | 0:2b9b5764efb5 | 261 | APPL_LOG_DEBUG("[APPL]: << DM_EVT_DEVICE_CONTEXT_LOADED\r\n"); |
FranKP2138 | 0:2b9b5764efb5 | 262 | break; |
FranKP2138 | 0:2b9b5764efb5 | 263 | |
FranKP2138 | 0:2b9b5764efb5 | 264 | case DM_EVT_DEVICE_CONTEXT_STORED: |
FranKP2138 | 0:2b9b5764efb5 | 265 | APPL_LOG_DEBUG("[APPL]: >> DM_EVT_DEVICE_CONTEXT_STORED\r\n"); |
FranKP2138 | 0:2b9b5764efb5 | 266 | APP_ERROR_CHECK(event_result); |
FranKP2138 | 0:2b9b5764efb5 | 267 | APPL_LOG_DEBUG("[APPL]: << DM_EVT_DEVICE_CONTEXT_STORED\r\n"); |
FranKP2138 | 0:2b9b5764efb5 | 268 | break; |
FranKP2138 | 0:2b9b5764efb5 | 269 | |
FranKP2138 | 0:2b9b5764efb5 | 270 | case DM_EVT_DEVICE_CONTEXT_DELETED: |
FranKP2138 | 0:2b9b5764efb5 | 271 | APPL_LOG_DEBUG("[APPL]: >> DM_EVT_DEVICE_CONTEXT_DELETED\r\n"); |
FranKP2138 | 0:2b9b5764efb5 | 272 | APP_ERROR_CHECK(event_result); |
FranKP2138 | 0:2b9b5764efb5 | 273 | APPL_LOG_DEBUG("[APPL]: << DM_EVT_DEVICE_CONTEXT_DELETED\r\n"); |
FranKP2138 | 0:2b9b5764efb5 | 274 | break; |
FranKP2138 | 0:2b9b5764efb5 | 275 | |
FranKP2138 | 0:2b9b5764efb5 | 276 | default: |
FranKP2138 | 0:2b9b5764efb5 | 277 | break; |
FranKP2138 | 0:2b9b5764efb5 | 278 | } |
FranKP2138 | 0:2b9b5764efb5 | 279 | |
FranKP2138 | 0:2b9b5764efb5 | 280 | return NRF_SUCCESS; |
FranKP2138 | 0:2b9b5764efb5 | 281 | } |
FranKP2138 | 0:2b9b5764efb5 | 282 | |
FranKP2138 | 0:2b9b5764efb5 | 283 | |
FranKP2138 | 0:2b9b5764efb5 | 284 | /** |
FranKP2138 | 0:2b9b5764efb5 | 285 | * @brief Parses advertisement data, providing length and location of the field in case |
FranKP2138 | 0:2b9b5764efb5 | 286 | * matching data is found. |
FranKP2138 | 0:2b9b5764efb5 | 287 | * |
FranKP2138 | 0:2b9b5764efb5 | 288 | * @param[in] Type of data to be looked for in advertisement data. |
FranKP2138 | 0:2b9b5764efb5 | 289 | * @param[in] Advertisement report length and pointer to report. |
FranKP2138 | 0:2b9b5764efb5 | 290 | * @param[out] If data type requested is found in the data report, type data length and |
FranKP2138 | 0:2b9b5764efb5 | 291 | * pointer to data will be populated here. |
FranKP2138 | 0:2b9b5764efb5 | 292 | * |
FranKP2138 | 0:2b9b5764efb5 | 293 | * @retval NRF_SUCCESS if the data type is found in the report. |
FranKP2138 | 0:2b9b5764efb5 | 294 | * @retval NRF_ERROR_NOT_FOUND if the data type could not be found. |
FranKP2138 | 0:2b9b5764efb5 | 295 | */ |
FranKP2138 | 0:2b9b5764efb5 | 296 | static uint32_t adv_report_parse(uint8_t type, data_t * p_advdata, data_t * p_typedata) |
FranKP2138 | 0:2b9b5764efb5 | 297 | { |
FranKP2138 | 0:2b9b5764efb5 | 298 | uint32_t index = 0; |
FranKP2138 | 0:2b9b5764efb5 | 299 | uint8_t * p_data; |
FranKP2138 | 0:2b9b5764efb5 | 300 | |
FranKP2138 | 0:2b9b5764efb5 | 301 | p_data = p_advdata->p_data; |
FranKP2138 | 0:2b9b5764efb5 | 302 | |
FranKP2138 | 0:2b9b5764efb5 | 303 | while (index < p_advdata->data_len) |
FranKP2138 | 0:2b9b5764efb5 | 304 | { |
FranKP2138 | 0:2b9b5764efb5 | 305 | uint8_t field_length = p_data[index]; |
FranKP2138 | 0:2b9b5764efb5 | 306 | uint8_t field_type = p_data[index+1]; |
FranKP2138 | 0:2b9b5764efb5 | 307 | |
FranKP2138 | 0:2b9b5764efb5 | 308 | if (field_type == type) |
FranKP2138 | 0:2b9b5764efb5 | 309 | { |
FranKP2138 | 0:2b9b5764efb5 | 310 | p_typedata->p_data = &p_data[index+2]; |
FranKP2138 | 0:2b9b5764efb5 | 311 | p_typedata->data_len = field_length-1; |
FranKP2138 | 0:2b9b5764efb5 | 312 | return NRF_SUCCESS; |
FranKP2138 | 0:2b9b5764efb5 | 313 | } |
FranKP2138 | 0:2b9b5764efb5 | 314 | index += field_length + 1; |
FranKP2138 | 0:2b9b5764efb5 | 315 | } |
FranKP2138 | 0:2b9b5764efb5 | 316 | return NRF_ERROR_NOT_FOUND; |
FranKP2138 | 0:2b9b5764efb5 | 317 | } |
FranKP2138 | 0:2b9b5764efb5 | 318 | |
FranKP2138 | 0:2b9b5764efb5 | 319 | |
FranKP2138 | 0:2b9b5764efb5 | 320 | /**@brief Function for putting the chip into sleep mode. |
FranKP2138 | 0:2b9b5764efb5 | 321 | * |
FranKP2138 | 0:2b9b5764efb5 | 322 | * @note This function will not return. |
FranKP2138 | 0:2b9b5764efb5 | 323 | */ |
FranKP2138 | 0:2b9b5764efb5 | 324 | static void sleep_mode_enter(void) |
FranKP2138 | 0:2b9b5764efb5 | 325 | { |
FranKP2138 | 0:2b9b5764efb5 | 326 | uint32_t err_code = bsp_indication_set(BSP_INDICATE_IDLE); |
FranKP2138 | 0:2b9b5764efb5 | 327 | APP_ERROR_CHECK(err_code); |
FranKP2138 | 0:2b9b5764efb5 | 328 | |
FranKP2138 | 0:2b9b5764efb5 | 329 | // Prepare wakeup buttons. |
FranKP2138 | 0:2b9b5764efb5 | 330 | err_code = bsp_btn_ble_sleep_mode_prepare(); |
FranKP2138 | 0:2b9b5764efb5 | 331 | APP_ERROR_CHECK(err_code); |
FranKP2138 | 0:2b9b5764efb5 | 332 | |
FranKP2138 | 0:2b9b5764efb5 | 333 | // Go to system-off mode (this function will not return; wakeup will cause a reset). |
FranKP2138 | 0:2b9b5764efb5 | 334 | err_code = sd_power_system_off(); |
FranKP2138 | 0:2b9b5764efb5 | 335 | APP_ERROR_CHECK(err_code); |
FranKP2138 | 0:2b9b5764efb5 | 336 | } |
FranKP2138 | 0:2b9b5764efb5 | 337 | |
FranKP2138 | 0:2b9b5764efb5 | 338 | |
FranKP2138 | 0:2b9b5764efb5 | 339 | /**@brief Function for handling the Application's BLE Stack events. |
FranKP2138 | 0:2b9b5764efb5 | 340 | * |
FranKP2138 | 0:2b9b5764efb5 | 341 | * @param[in] p_ble_evt Bluetooth stack event. |
FranKP2138 | 0:2b9b5764efb5 | 342 | */ |
FranKP2138 | 0:2b9b5764efb5 | 343 | static void on_ble_evt(ble_evt_t * p_ble_evt) |
FranKP2138 | 0:2b9b5764efb5 | 344 | { |
FranKP2138 | 0:2b9b5764efb5 | 345 | uint32_t err_code; |
FranKP2138 | 0:2b9b5764efb5 | 346 | const ble_gap_evt_t * p_gap_evt = &p_ble_evt->evt.gap_evt; |
FranKP2138 | 0:2b9b5764efb5 | 347 | |
FranKP2138 | 0:2b9b5764efb5 | 348 | switch (p_ble_evt->header.evt_id) |
FranKP2138 | 0:2b9b5764efb5 | 349 | { |
FranKP2138 | 0:2b9b5764efb5 | 350 | case BLE_GAP_EVT_ADV_REPORT: |
FranKP2138 | 0:2b9b5764efb5 | 351 | { |
FranKP2138 | 0:2b9b5764efb5 | 352 | data_t adv_data; |
FranKP2138 | 0:2b9b5764efb5 | 353 | data_t type_data; |
FranKP2138 | 0:2b9b5764efb5 | 354 | |
FranKP2138 | 0:2b9b5764efb5 | 355 | // Initialize advertisement report for parsing. |
FranKP2138 | 0:2b9b5764efb5 | 356 | adv_data.p_data = (uint8_t *)p_gap_evt->params.adv_report.data; |
FranKP2138 | 0:2b9b5764efb5 | 357 | adv_data.data_len = p_gap_evt->params.adv_report.dlen; |
FranKP2138 | 0:2b9b5764efb5 | 358 | |
FranKP2138 | 0:2b9b5764efb5 | 359 | err_code = adv_report_parse(BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_MORE_AVAILABLE, |
FranKP2138 | 0:2b9b5764efb5 | 360 | &adv_data, |
FranKP2138 | 0:2b9b5764efb5 | 361 | &type_data); |
FranKP2138 | 0:2b9b5764efb5 | 362 | |
FranKP2138 | 0:2b9b5764efb5 | 363 | if (err_code != NRF_SUCCESS) |
FranKP2138 | 0:2b9b5764efb5 | 364 | { |
FranKP2138 | 0:2b9b5764efb5 | 365 | // Compare short local name in case complete name does not match. |
FranKP2138 | 0:2b9b5764efb5 | 366 | err_code = adv_report_parse(BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_COMPLETE, |
FranKP2138 | 0:2b9b5764efb5 | 367 | &adv_data, |
FranKP2138 | 0:2b9b5764efb5 | 368 | &type_data); |
FranKP2138 | 0:2b9b5764efb5 | 369 | } |
FranKP2138 | 0:2b9b5764efb5 | 370 | |
FranKP2138 | 0:2b9b5764efb5 | 371 | // Verify if short or complete name matches target. |
FranKP2138 | 0:2b9b5764efb5 | 372 | if (err_code == NRF_SUCCESS) |
FranKP2138 | 0:2b9b5764efb5 | 373 | { |
FranKP2138 | 0:2b9b5764efb5 | 374 | uint16_t extracted_uuid; |
FranKP2138 | 0:2b9b5764efb5 | 375 | |
FranKP2138 | 0:2b9b5764efb5 | 376 | // UUIDs found, look for matching UUID |
FranKP2138 | 0:2b9b5764efb5 | 377 | for (uint32_t u_index = 0; u_index < (type_data.data_len/UUID16_SIZE); u_index++) |
FranKP2138 | 0:2b9b5764efb5 | 378 | { |
FranKP2138 | 0:2b9b5764efb5 | 379 | UUID16_EXTRACT(&extracted_uuid,&type_data.p_data[u_index * UUID16_SIZE]); |
FranKP2138 | 0:2b9b5764efb5 | 380 | |
FranKP2138 | 0:2b9b5764efb5 | 381 | APPL_LOG_DEBUG("\t[APPL]: %x\r\n",extracted_uuid); |
FranKP2138 | 0:2b9b5764efb5 | 382 | |
FranKP2138 | 0:2b9b5764efb5 | 383 | if(extracted_uuid == TARGET_UUID) |
FranKP2138 | 0:2b9b5764efb5 | 384 | { |
FranKP2138 | 0:2b9b5764efb5 | 385 | // Stop scanning. |
FranKP2138 | 0:2b9b5764efb5 | 386 | err_code = sd_ble_gap_scan_stop(); |
FranKP2138 | 0:2b9b5764efb5 | 387 | |
FranKP2138 | 0:2b9b5764efb5 | 388 | if (err_code != NRF_SUCCESS) |
FranKP2138 | 0:2b9b5764efb5 | 389 | { |
FranKP2138 | 0:2b9b5764efb5 | 390 | APPL_LOG_DEBUG("[APPL]: Scan stop failed, reason %d\r\n", err_code); |
FranKP2138 | 0:2b9b5764efb5 | 391 | } |
FranKP2138 | 0:2b9b5764efb5 | 392 | err_code = bsp_indication_set(BSP_INDICATE_IDLE); |
FranKP2138 | 0:2b9b5764efb5 | 393 | APP_ERROR_CHECK(err_code); |
FranKP2138 | 0:2b9b5764efb5 | 394 | |
FranKP2138 | 0:2b9b5764efb5 | 395 | m_scan_param.selective = 0; |
FranKP2138 | 0:2b9b5764efb5 | 396 | m_scan_param.p_whitelist = NULL; |
FranKP2138 | 0:2b9b5764efb5 | 397 | |
FranKP2138 | 0:2b9b5764efb5 | 398 | // Initiate connection. |
FranKP2138 | 0:2b9b5764efb5 | 399 | err_code = sd_ble_gap_connect(&p_gap_evt->params.adv_report.peer_addr, |
FranKP2138 | 0:2b9b5764efb5 | 400 | &m_scan_param, |
FranKP2138 | 0:2b9b5764efb5 | 401 | &m_connection_param); |
FranKP2138 | 0:2b9b5764efb5 | 402 | |
FranKP2138 | 0:2b9b5764efb5 | 403 | m_whitelist_temporarily_disabled = false; |
FranKP2138 | 0:2b9b5764efb5 | 404 | |
FranKP2138 | 0:2b9b5764efb5 | 405 | if (err_code != NRF_SUCCESS) |
FranKP2138 | 0:2b9b5764efb5 | 406 | { |
FranKP2138 | 0:2b9b5764efb5 | 407 | APPL_LOG_DEBUG("[APPL]: Connection Request Failed, reason %d\r\n", err_code); |
FranKP2138 | 0:2b9b5764efb5 | 408 | } |
FranKP2138 | 0:2b9b5764efb5 | 409 | break; |
FranKP2138 | 0:2b9b5764efb5 | 410 | } |
FranKP2138 | 0:2b9b5764efb5 | 411 | } |
FranKP2138 | 0:2b9b5764efb5 | 412 | } |
FranKP2138 | 0:2b9b5764efb5 | 413 | break; |
FranKP2138 | 0:2b9b5764efb5 | 414 | } |
FranKP2138 | 0:2b9b5764efb5 | 415 | |
FranKP2138 | 0:2b9b5764efb5 | 416 | case BLE_GAP_EVT_TIMEOUT: |
FranKP2138 | 0:2b9b5764efb5 | 417 | if (p_gap_evt->params.timeout.src == BLE_GAP_TIMEOUT_SRC_SCAN) |
FranKP2138 | 0:2b9b5764efb5 | 418 | { |
FranKP2138 | 0:2b9b5764efb5 | 419 | APPL_LOG_DEBUG("[APPL]: Scan timed out.\r\n"); |
FranKP2138 | 0:2b9b5764efb5 | 420 | scan_start(); |
FranKP2138 | 0:2b9b5764efb5 | 421 | } |
FranKP2138 | 0:2b9b5764efb5 | 422 | else if (p_gap_evt->params.timeout.src == BLE_GAP_TIMEOUT_SRC_CONN) |
FranKP2138 | 0:2b9b5764efb5 | 423 | { |
FranKP2138 | 0:2b9b5764efb5 | 424 | APPL_LOG_DEBUG("[APPL]: Connection Request timed out.\r\n"); |
FranKP2138 | 0:2b9b5764efb5 | 425 | } |
FranKP2138 | 0:2b9b5764efb5 | 426 | break; |
FranKP2138 | 0:2b9b5764efb5 | 427 | case BLE_GAP_EVT_CONNECTED: |
FranKP2138 | 0:2b9b5764efb5 | 428 | { |
FranKP2138 | 0:2b9b5764efb5 | 429 | err_code = ble_hrs_c_handles_assign(&m_ble_hrs_c, p_gap_evt->conn_handle, NULL); |
FranKP2138 | 0:2b9b5764efb5 | 430 | APP_ERROR_CHECK(err_code); |
FranKP2138 | 0:2b9b5764efb5 | 431 | err_code = ble_bas_c_handles_assign(&m_ble_bas_c, p_gap_evt->conn_handle, NULL); |
FranKP2138 | 0:2b9b5764efb5 | 432 | APP_ERROR_CHECK(err_code); |
FranKP2138 | 0:2b9b5764efb5 | 433 | break; |
FranKP2138 | 0:2b9b5764efb5 | 434 | } |
FranKP2138 | 0:2b9b5764efb5 | 435 | case BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST: |
FranKP2138 | 0:2b9b5764efb5 | 436 | // Accepting parameters requested by peer. |
FranKP2138 | 0:2b9b5764efb5 | 437 | err_code = sd_ble_gap_conn_param_update(p_gap_evt->conn_handle, |
FranKP2138 | 0:2b9b5764efb5 | 438 | &p_gap_evt->params.conn_param_update_request.conn_params); |
FranKP2138 | 0:2b9b5764efb5 | 439 | APP_ERROR_CHECK(err_code); |
FranKP2138 | 0:2b9b5764efb5 | 440 | break; |
FranKP2138 | 0:2b9b5764efb5 | 441 | |
FranKP2138 | 0:2b9b5764efb5 | 442 | default: |
FranKP2138 | 0:2b9b5764efb5 | 443 | break; |
FranKP2138 | 0:2b9b5764efb5 | 444 | } |
FranKP2138 | 0:2b9b5764efb5 | 445 | } |
FranKP2138 | 0:2b9b5764efb5 | 446 | |
FranKP2138 | 0:2b9b5764efb5 | 447 | |
FranKP2138 | 0:2b9b5764efb5 | 448 | /**@brief Function for handling the Application's system events. |
FranKP2138 | 0:2b9b5764efb5 | 449 | * |
FranKP2138 | 0:2b9b5764efb5 | 450 | * @param[in] sys_evt system event. |
FranKP2138 | 0:2b9b5764efb5 | 451 | */ |
FranKP2138 | 0:2b9b5764efb5 | 452 | static void on_sys_evt(uint32_t sys_evt) |
FranKP2138 | 0:2b9b5764efb5 | 453 | { |
FranKP2138 | 0:2b9b5764efb5 | 454 | switch (sys_evt) |
FranKP2138 | 0:2b9b5764efb5 | 455 | { |
FranKP2138 | 0:2b9b5764efb5 | 456 | case NRF_EVT_FLASH_OPERATION_SUCCESS: |
FranKP2138 | 0:2b9b5764efb5 | 457 | /* fall through */ |
FranKP2138 | 0:2b9b5764efb5 | 458 | case NRF_EVT_FLASH_OPERATION_ERROR: |
FranKP2138 | 0:2b9b5764efb5 | 459 | |
FranKP2138 | 0:2b9b5764efb5 | 460 | if (m_memory_access_in_progress) |
FranKP2138 | 0:2b9b5764efb5 | 461 | { |
FranKP2138 | 0:2b9b5764efb5 | 462 | m_memory_access_in_progress = false; |
FranKP2138 | 0:2b9b5764efb5 | 463 | scan_start(); |
FranKP2138 | 0:2b9b5764efb5 | 464 | } |
FranKP2138 | 0:2b9b5764efb5 | 465 | break; |
FranKP2138 | 0:2b9b5764efb5 | 466 | |
FranKP2138 | 0:2b9b5764efb5 | 467 | default: |
FranKP2138 | 0:2b9b5764efb5 | 468 | // No implementation needed. |
FranKP2138 | 0:2b9b5764efb5 | 469 | break; |
FranKP2138 | 0:2b9b5764efb5 | 470 | } |
FranKP2138 | 0:2b9b5764efb5 | 471 | } |
FranKP2138 | 0:2b9b5764efb5 | 472 | |
FranKP2138 | 0:2b9b5764efb5 | 473 | |
FranKP2138 | 0:2b9b5764efb5 | 474 | /**@brief Function for dispatching a BLE stack event to all modules with a BLE stack event handler. |
FranKP2138 | 0:2b9b5764efb5 | 475 | * |
FranKP2138 | 0:2b9b5764efb5 | 476 | * @details This function is called from the scheduler in the main loop after a BLE stack event has |
FranKP2138 | 0:2b9b5764efb5 | 477 | * been received. |
FranKP2138 | 0:2b9b5764efb5 | 478 | * |
FranKP2138 | 0:2b9b5764efb5 | 479 | * @param[in] p_ble_evt Bluetooth stack event. |
FranKP2138 | 0:2b9b5764efb5 | 480 | */ |
FranKP2138 | 0:2b9b5764efb5 | 481 | static void ble_evt_dispatch(ble_evt_t * p_ble_evt) |
FranKP2138 | 0:2b9b5764efb5 | 482 | { |
FranKP2138 | 0:2b9b5764efb5 | 483 | dm_ble_evt_handler(p_ble_evt); |
FranKP2138 | 0:2b9b5764efb5 | 484 | ble_db_discovery_on_ble_evt(&m_ble_db_discovery, p_ble_evt); |
FranKP2138 | 0:2b9b5764efb5 | 485 | ble_hrs_c_on_ble_evt(&m_ble_hrs_c, p_ble_evt); |
FranKP2138 | 0:2b9b5764efb5 | 486 | ble_bas_c_on_ble_evt(&m_ble_bas_c, p_ble_evt); |
FranKP2138 | 0:2b9b5764efb5 | 487 | bsp_btn_ble_on_ble_evt(p_ble_evt); |
FranKP2138 | 0:2b9b5764efb5 | 488 | on_ble_evt(p_ble_evt); |
FranKP2138 | 0:2b9b5764efb5 | 489 | } |
FranKP2138 | 0:2b9b5764efb5 | 490 | |
FranKP2138 | 0:2b9b5764efb5 | 491 | |
FranKP2138 | 0:2b9b5764efb5 | 492 | /**@brief Function for dispatching a system event to interested modules. |
FranKP2138 | 0:2b9b5764efb5 | 493 | * |
FranKP2138 | 0:2b9b5764efb5 | 494 | * @details This function is called from the System event interrupt handler after a system |
FranKP2138 | 0:2b9b5764efb5 | 495 | * event has been received. |
FranKP2138 | 0:2b9b5764efb5 | 496 | * |
FranKP2138 | 0:2b9b5764efb5 | 497 | * @param[in] sys_evt System stack event. |
FranKP2138 | 0:2b9b5764efb5 | 498 | */ |
FranKP2138 | 0:2b9b5764efb5 | 499 | static void sys_evt_dispatch(uint32_t sys_evt) |
FranKP2138 | 0:2b9b5764efb5 | 500 | { |
FranKP2138 | 0:2b9b5764efb5 | 501 | pstorage_sys_event_handler(sys_evt); |
FranKP2138 | 0:2b9b5764efb5 | 502 | on_sys_evt(sys_evt); |
FranKP2138 | 0:2b9b5764efb5 | 503 | } |
FranKP2138 | 0:2b9b5764efb5 | 504 | |
FranKP2138 | 0:2b9b5764efb5 | 505 | |
FranKP2138 | 0:2b9b5764efb5 | 506 | /**@brief Function for initializing the BLE stack. |
FranKP2138 | 0:2b9b5764efb5 | 507 | * |
FranKP2138 | 0:2b9b5764efb5 | 508 | * @details Initializes the SoftDevice and the BLE event interrupt. |
FranKP2138 | 0:2b9b5764efb5 | 509 | */ |
FranKP2138 | 0:2b9b5764efb5 | 510 | static void ble_stack_init(void) |
FranKP2138 | 0:2b9b5764efb5 | 511 | { |
FranKP2138 | 0:2b9b5764efb5 | 512 | uint32_t err_code; |
FranKP2138 | 0:2b9b5764efb5 | 513 | |
FranKP2138 | 0:2b9b5764efb5 | 514 | nrf_clock_lf_cfg_t clock_lf_cfg = NRF_CLOCK_LFCLKSRC; |
FranKP2138 | 0:2b9b5764efb5 | 515 | |
FranKP2138 | 0:2b9b5764efb5 | 516 | // Initialize the SoftDevice handler module. |
FranKP2138 | 0:2b9b5764efb5 | 517 | SOFTDEVICE_HANDLER_INIT(&clock_lf_cfg, NULL); |
FranKP2138 | 0:2b9b5764efb5 | 518 | |
FranKP2138 | 0:2b9b5764efb5 | 519 | ble_enable_params_t ble_enable_params; |
FranKP2138 | 0:2b9b5764efb5 | 520 | err_code = softdevice_enable_get_default_config(CENTRAL_LINK_COUNT, |
FranKP2138 | 0:2b9b5764efb5 | 521 | PERIPHERAL_LINK_COUNT, |
FranKP2138 | 0:2b9b5764efb5 | 522 | &ble_enable_params); |
FranKP2138 | 0:2b9b5764efb5 | 523 | APP_ERROR_CHECK(err_code); |
FranKP2138 | 0:2b9b5764efb5 | 524 | |
FranKP2138 | 0:2b9b5764efb5 | 525 | //Check the ram settings against the used number of links |
FranKP2138 | 0:2b9b5764efb5 | 526 | CHECK_RAM_START_ADDR(CENTRAL_LINK_COUNT,PERIPHERAL_LINK_COUNT); |
FranKP2138 | 0:2b9b5764efb5 | 527 | |
FranKP2138 | 0:2b9b5764efb5 | 528 | // Enable BLE stack. |
FranKP2138 | 0:2b9b5764efb5 | 529 | err_code = softdevice_enable(&ble_enable_params); |
FranKP2138 | 0:2b9b5764efb5 | 530 | APP_ERROR_CHECK(err_code); |
FranKP2138 | 0:2b9b5764efb5 | 531 | |
FranKP2138 | 0:2b9b5764efb5 | 532 | // Register with the SoftDevice handler module for BLE events. |
FranKP2138 | 0:2b9b5764efb5 | 533 | err_code = softdevice_ble_evt_handler_set(ble_evt_dispatch); |
FranKP2138 | 0:2b9b5764efb5 | 534 | APP_ERROR_CHECK(err_code); |
FranKP2138 | 0:2b9b5764efb5 | 535 | |
FranKP2138 | 0:2b9b5764efb5 | 536 | // Register with the SoftDevice handler module for System events. |
FranKP2138 | 0:2b9b5764efb5 | 537 | err_code = softdevice_sys_evt_handler_set(sys_evt_dispatch); |
FranKP2138 | 0:2b9b5764efb5 | 538 | APP_ERROR_CHECK(err_code); |
FranKP2138 | 0:2b9b5764efb5 | 539 | } |
FranKP2138 | 0:2b9b5764efb5 | 540 | |
FranKP2138 | 0:2b9b5764efb5 | 541 | |
FranKP2138 | 0:2b9b5764efb5 | 542 | /**@brief Function for the Device Manager initialization. |
FranKP2138 | 0:2b9b5764efb5 | 543 | * |
FranKP2138 | 0:2b9b5764efb5 | 544 | * @param[in] erase_bonds Indicates whether bonding information should be cleared from |
FranKP2138 | 0:2b9b5764efb5 | 545 | * persistent storage during initialization of the Device Manager. |
FranKP2138 | 0:2b9b5764efb5 | 546 | */ |
FranKP2138 | 0:2b9b5764efb5 | 547 | static void device_manager_init(bool erase_bonds) |
FranKP2138 | 0:2b9b5764efb5 | 548 | { |
FranKP2138 | 0:2b9b5764efb5 | 549 | uint32_t err_code; |
FranKP2138 | 0:2b9b5764efb5 | 550 | dm_init_param_t init_param = {.clear_persistent_data = erase_bonds}; |
FranKP2138 | 0:2b9b5764efb5 | 551 | dm_application_param_t register_param; |
FranKP2138 | 0:2b9b5764efb5 | 552 | |
FranKP2138 | 0:2b9b5764efb5 | 553 | err_code = pstorage_init(); |
FranKP2138 | 0:2b9b5764efb5 | 554 | APP_ERROR_CHECK(err_code); |
FranKP2138 | 0:2b9b5764efb5 | 555 | |
FranKP2138 | 0:2b9b5764efb5 | 556 | err_code = dm_init(&init_param); |
FranKP2138 | 0:2b9b5764efb5 | 557 | APP_ERROR_CHECK(err_code); |
FranKP2138 | 0:2b9b5764efb5 | 558 | |
FranKP2138 | 0:2b9b5764efb5 | 559 | memset(®ister_param.sec_param, 0, sizeof (ble_gap_sec_params_t)); |
FranKP2138 | 0:2b9b5764efb5 | 560 | |
FranKP2138 | 0:2b9b5764efb5 | 561 | // Event handler to be registered with the module. |
FranKP2138 | 0:2b9b5764efb5 | 562 | register_param.evt_handler = device_manager_event_handler; |
FranKP2138 | 0:2b9b5764efb5 | 563 | |
FranKP2138 | 0:2b9b5764efb5 | 564 | // Service or protocol context for device manager to load, store and apply on behalf of application. |
FranKP2138 | 0:2b9b5764efb5 | 565 | // Here set to client as application is a GATT client. |
FranKP2138 | 0:2b9b5764efb5 | 566 | register_param.service_type = DM_PROTOCOL_CNTXT_GATT_CLI_ID; |
FranKP2138 | 0:2b9b5764efb5 | 567 | |
FranKP2138 | 0:2b9b5764efb5 | 568 | // Secuirty parameters to be used for security procedures. |
FranKP2138 | 0:2b9b5764efb5 | 569 | register_param.sec_param.bond = SEC_PARAM_BOND; |
FranKP2138 | 0:2b9b5764efb5 | 570 | register_param.sec_param.mitm = SEC_PARAM_MITM; |
FranKP2138 | 0:2b9b5764efb5 | 571 | register_param.sec_param.lesc = SEC_PARAM_LESC; |
FranKP2138 | 0:2b9b5764efb5 | 572 | register_param.sec_param.keypress = SEC_PARAM_KEYPRESS; |
FranKP2138 | 0:2b9b5764efb5 | 573 | register_param.sec_param.io_caps = SEC_PARAM_IO_CAPABILITIES; |
FranKP2138 | 0:2b9b5764efb5 | 574 | register_param.sec_param.oob = SEC_PARAM_OOB; |
FranKP2138 | 0:2b9b5764efb5 | 575 | register_param.sec_param.min_key_size = SEC_PARAM_MIN_KEY_SIZE; |
FranKP2138 | 0:2b9b5764efb5 | 576 | register_param.sec_param.max_key_size = SEC_PARAM_MAX_KEY_SIZE; |
FranKP2138 | 0:2b9b5764efb5 | 577 | register_param.sec_param.kdist_peer.enc = 1; |
FranKP2138 | 0:2b9b5764efb5 | 578 | register_param.sec_param.kdist_peer.id = 1; |
FranKP2138 | 0:2b9b5764efb5 | 579 | |
FranKP2138 | 0:2b9b5764efb5 | 580 | err_code = dm_register(&m_dm_app_id, ®ister_param); |
FranKP2138 | 0:2b9b5764efb5 | 581 | APP_ERROR_CHECK(err_code); |
FranKP2138 | 0:2b9b5764efb5 | 582 | } |
FranKP2138 | 0:2b9b5764efb5 | 583 | |
FranKP2138 | 0:2b9b5764efb5 | 584 | |
FranKP2138 | 0:2b9b5764efb5 | 585 | /**@brief Function for disabling the use of whitelist for scanning. |
FranKP2138 | 0:2b9b5764efb5 | 586 | */ |
FranKP2138 | 0:2b9b5764efb5 | 587 | static void whitelist_disable(void) |
FranKP2138 | 0:2b9b5764efb5 | 588 | { |
FranKP2138 | 0:2b9b5764efb5 | 589 | uint32_t err_code; |
FranKP2138 | 0:2b9b5764efb5 | 590 | |
FranKP2138 | 0:2b9b5764efb5 | 591 | if ((m_scan_mode == BLE_WHITELIST_SCAN) && !m_whitelist_temporarily_disabled) |
FranKP2138 | 0:2b9b5764efb5 | 592 | { |
FranKP2138 | 0:2b9b5764efb5 | 593 | m_whitelist_temporarily_disabled = true; |
FranKP2138 | 0:2b9b5764efb5 | 594 | |
FranKP2138 | 0:2b9b5764efb5 | 595 | err_code = sd_ble_gap_scan_stop(); |
FranKP2138 | 0:2b9b5764efb5 | 596 | if (err_code == NRF_SUCCESS) |
FranKP2138 | 0:2b9b5764efb5 | 597 | { |
FranKP2138 | 0:2b9b5764efb5 | 598 | scan_start(); |
FranKP2138 | 0:2b9b5764efb5 | 599 | } |
FranKP2138 | 0:2b9b5764efb5 | 600 | else if (err_code != NRF_ERROR_INVALID_STATE) |
FranKP2138 | 0:2b9b5764efb5 | 601 | { |
FranKP2138 | 0:2b9b5764efb5 | 602 | APP_ERROR_CHECK(err_code); |
FranKP2138 | 0:2b9b5764efb5 | 603 | } |
FranKP2138 | 0:2b9b5764efb5 | 604 | } |
FranKP2138 | 0:2b9b5764efb5 | 605 | m_whitelist_temporarily_disabled = true; |
FranKP2138 | 0:2b9b5764efb5 | 606 | } |
FranKP2138 | 0:2b9b5764efb5 | 607 | |
FranKP2138 | 0:2b9b5764efb5 | 608 | |
FranKP2138 | 0:2b9b5764efb5 | 609 | /**@brief Function for handling events from the BSP module. |
FranKP2138 | 0:2b9b5764efb5 | 610 | * |
FranKP2138 | 0:2b9b5764efb5 | 611 | * @param[in] event Event generated by button press. |
FranKP2138 | 0:2b9b5764efb5 | 612 | */ |
FranKP2138 | 0:2b9b5764efb5 | 613 | void bsp_event_handler(bsp_event_t event) |
FranKP2138 | 0:2b9b5764efb5 | 614 | { |
FranKP2138 | 0:2b9b5764efb5 | 615 | uint32_t err_code; |
FranKP2138 | 0:2b9b5764efb5 | 616 | switch (event) |
FranKP2138 | 0:2b9b5764efb5 | 617 | { |
FranKP2138 | 0:2b9b5764efb5 | 618 | case BSP_EVENT_SLEEP: |
FranKP2138 | 0:2b9b5764efb5 | 619 | sleep_mode_enter(); |
FranKP2138 | 0:2b9b5764efb5 | 620 | break; |
FranKP2138 | 0:2b9b5764efb5 | 621 | |
FranKP2138 | 0:2b9b5764efb5 | 622 | case BSP_EVENT_DISCONNECT: |
FranKP2138 | 0:2b9b5764efb5 | 623 | err_code = sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION); |
FranKP2138 | 0:2b9b5764efb5 | 624 | if (err_code != NRF_ERROR_INVALID_STATE) |
FranKP2138 | 0:2b9b5764efb5 | 625 | { |
FranKP2138 | 0:2b9b5764efb5 | 626 | APP_ERROR_CHECK(err_code); |
FranKP2138 | 0:2b9b5764efb5 | 627 | } |
FranKP2138 | 0:2b9b5764efb5 | 628 | break; |
FranKP2138 | 0:2b9b5764efb5 | 629 | |
FranKP2138 | 0:2b9b5764efb5 | 630 | case BSP_EVENT_WHITELIST_OFF: |
FranKP2138 | 0:2b9b5764efb5 | 631 | whitelist_disable(); |
FranKP2138 | 0:2b9b5764efb5 | 632 | break; |
FranKP2138 | 0:2b9b5764efb5 | 633 | |
FranKP2138 | 0:2b9b5764efb5 | 634 | default: |
FranKP2138 | 0:2b9b5764efb5 | 635 | break; |
FranKP2138 | 0:2b9b5764efb5 | 636 | } |
FranKP2138 | 0:2b9b5764efb5 | 637 | } |
FranKP2138 | 0:2b9b5764efb5 | 638 | |
FranKP2138 | 0:2b9b5764efb5 | 639 | |
FranKP2138 | 0:2b9b5764efb5 | 640 | /**@brief Heart Rate Collector Handler. |
FranKP2138 | 0:2b9b5764efb5 | 641 | */ |
FranKP2138 | 0:2b9b5764efb5 | 642 | static void hrs_c_evt_handler(ble_hrs_c_t * p_hrs_c, ble_hrs_c_evt_t * p_hrs_c_evt) |
FranKP2138 | 0:2b9b5764efb5 | 643 | { |
FranKP2138 | 0:2b9b5764efb5 | 644 | uint32_t err_code; |
FranKP2138 | 0:2b9b5764efb5 | 645 | |
FranKP2138 | 0:2b9b5764efb5 | 646 | switch (p_hrs_c_evt->evt_type) |
FranKP2138 | 0:2b9b5764efb5 | 647 | { |
FranKP2138 | 0:2b9b5764efb5 | 648 | case BLE_HRS_C_EVT_DISCOVERY_COMPLETE: |
FranKP2138 | 0:2b9b5764efb5 | 649 | |
FranKP2138 | 0:2b9b5764efb5 | 650 | // Heart rate service discovered. Enable notification of Heart Rate Measurement. |
FranKP2138 | 0:2b9b5764efb5 | 651 | err_code = ble_hrs_c_hrm_notif_enable(p_hrs_c); |
FranKP2138 | 0:2b9b5764efb5 | 652 | APP_ERROR_CHECK(err_code); |
FranKP2138 | 0:2b9b5764efb5 | 653 | |
FranKP2138 | 0:2b9b5764efb5 | 654 | APPL_LOG_DEBUG("Heart rate service discovered \r\n"); |
FranKP2138 | 0:2b9b5764efb5 | 655 | break; |
FranKP2138 | 0:2b9b5764efb5 | 656 | |
FranKP2138 | 0:2b9b5764efb5 | 657 | case BLE_HRS_C_EVT_HRM_NOTIFICATION: |
FranKP2138 | 0:2b9b5764efb5 | 658 | { |
FranKP2138 | 0:2b9b5764efb5 | 659 | APPL_LOG_DEBUG("[APPL]: HR Measurement received %d \r\n", p_hrs_c_evt->params.hrm.hr_value); |
FranKP2138 | 0:2b9b5764efb5 | 660 | |
FranKP2138 | 0:2b9b5764efb5 | 661 | APPL_LOG("Heart Rate = %d\r\n", p_hrs_c_evt->params.hrm.hr_value); |
FranKP2138 | 0:2b9b5764efb5 | 662 | break; |
FranKP2138 | 0:2b9b5764efb5 | 663 | } |
FranKP2138 | 0:2b9b5764efb5 | 664 | |
FranKP2138 | 0:2b9b5764efb5 | 665 | default: |
FranKP2138 | 0:2b9b5764efb5 | 666 | break; |
FranKP2138 | 0:2b9b5764efb5 | 667 | } |
FranKP2138 | 0:2b9b5764efb5 | 668 | } |
FranKP2138 | 0:2b9b5764efb5 | 669 | |
FranKP2138 | 0:2b9b5764efb5 | 670 | |
FranKP2138 | 0:2b9b5764efb5 | 671 | /**@brief Battery levelCollector Handler. |
FranKP2138 | 0:2b9b5764efb5 | 672 | */ |
FranKP2138 | 0:2b9b5764efb5 | 673 | static void bas_c_evt_handler(ble_bas_c_t * p_bas_c, ble_bas_c_evt_t * p_bas_c_evt) |
FranKP2138 | 0:2b9b5764efb5 | 674 | { |
FranKP2138 | 0:2b9b5764efb5 | 675 | uint32_t err_code; |
FranKP2138 | 0:2b9b5764efb5 | 676 | |
FranKP2138 | 0:2b9b5764efb5 | 677 | switch (p_bas_c_evt->evt_type) |
FranKP2138 | 0:2b9b5764efb5 | 678 | { |
FranKP2138 | 0:2b9b5764efb5 | 679 | case BLE_BAS_C_EVT_DISCOVERY_COMPLETE: |
FranKP2138 | 0:2b9b5764efb5 | 680 | // Batttery service discovered. Enable notification of Battery Level. |
FranKP2138 | 0:2b9b5764efb5 | 681 | APPL_LOG_DEBUG("[APPL]: Battery Service discovered. \r\n"); |
FranKP2138 | 0:2b9b5764efb5 | 682 | |
FranKP2138 | 0:2b9b5764efb5 | 683 | APPL_LOG_DEBUG("[APPL]: Reading battery level. \r\n"); |
FranKP2138 | 0:2b9b5764efb5 | 684 | |
FranKP2138 | 0:2b9b5764efb5 | 685 | err_code = ble_bas_c_bl_read(p_bas_c); |
FranKP2138 | 0:2b9b5764efb5 | 686 | APP_ERROR_CHECK(err_code); |
FranKP2138 | 0:2b9b5764efb5 | 687 | |
FranKP2138 | 0:2b9b5764efb5 | 688 | |
FranKP2138 | 0:2b9b5764efb5 | 689 | APPL_LOG_DEBUG("[APPL]: Enabling Battery Level Notification. \r\n"); |
FranKP2138 | 0:2b9b5764efb5 | 690 | err_code = ble_bas_c_bl_notif_enable(p_bas_c); |
FranKP2138 | 0:2b9b5764efb5 | 691 | APP_ERROR_CHECK(err_code); |
FranKP2138 | 0:2b9b5764efb5 | 692 | |
FranKP2138 | 0:2b9b5764efb5 | 693 | break; |
FranKP2138 | 0:2b9b5764efb5 | 694 | |
FranKP2138 | 0:2b9b5764efb5 | 695 | case BLE_BAS_C_EVT_BATT_NOTIFICATION: |
FranKP2138 | 0:2b9b5764efb5 | 696 | { |
FranKP2138 | 0:2b9b5764efb5 | 697 | APPL_LOG_DEBUG("[APPL]: Battery Level received %d %%\r\n", p_bas_c_evt->params.battery_level); |
FranKP2138 | 0:2b9b5764efb5 | 698 | |
FranKP2138 | 0:2b9b5764efb5 | 699 | APPL_LOG_DEBUG("Battery = %d %%\r\n", p_bas_c_evt->params.battery_level); |
FranKP2138 | 0:2b9b5764efb5 | 700 | break; |
FranKP2138 | 0:2b9b5764efb5 | 701 | } |
FranKP2138 | 0:2b9b5764efb5 | 702 | |
FranKP2138 | 0:2b9b5764efb5 | 703 | case BLE_BAS_C_EVT_BATT_READ_RESP: |
FranKP2138 | 0:2b9b5764efb5 | 704 | { |
FranKP2138 | 0:2b9b5764efb5 | 705 | APPL_LOG_DEBUG("[APPL]: Battery Level Read as %d %%\r\n", p_bas_c_evt->params.battery_level); |
FranKP2138 | 0:2b9b5764efb5 | 706 | |
FranKP2138 | 0:2b9b5764efb5 | 707 | APPL_LOG_DEBUG("Battery = %d %%\r\n", p_bas_c_evt->params.battery_level); |
FranKP2138 | 0:2b9b5764efb5 | 708 | break; |
FranKP2138 | 0:2b9b5764efb5 | 709 | } |
FranKP2138 | 0:2b9b5764efb5 | 710 | |
FranKP2138 | 0:2b9b5764efb5 | 711 | default: |
FranKP2138 | 0:2b9b5764efb5 | 712 | break; |
FranKP2138 | 0:2b9b5764efb5 | 713 | } |
FranKP2138 | 0:2b9b5764efb5 | 714 | } |
FranKP2138 | 0:2b9b5764efb5 | 715 | |
FranKP2138 | 0:2b9b5764efb5 | 716 | |
FranKP2138 | 0:2b9b5764efb5 | 717 | /** |
FranKP2138 | 0:2b9b5764efb5 | 718 | * @brief Heart rate collector initialization. |
FranKP2138 | 0:2b9b5764efb5 | 719 | */ |
FranKP2138 | 0:2b9b5764efb5 | 720 | static void hrs_c_init(void) |
FranKP2138 | 0:2b9b5764efb5 | 721 | { |
FranKP2138 | 0:2b9b5764efb5 | 722 | ble_hrs_c_init_t hrs_c_init_obj; |
FranKP2138 | 0:2b9b5764efb5 | 723 | |
FranKP2138 | 0:2b9b5764efb5 | 724 | hrs_c_init_obj.evt_handler = hrs_c_evt_handler; |
FranKP2138 | 0:2b9b5764efb5 | 725 | |
FranKP2138 | 0:2b9b5764efb5 | 726 | uint32_t err_code = ble_hrs_c_init(&m_ble_hrs_c, &hrs_c_init_obj); |
FranKP2138 | 0:2b9b5764efb5 | 727 | APP_ERROR_CHECK(err_code); |
FranKP2138 | 0:2b9b5764efb5 | 728 | } |
FranKP2138 | 0:2b9b5764efb5 | 729 | |
FranKP2138 | 0:2b9b5764efb5 | 730 | |
FranKP2138 | 0:2b9b5764efb5 | 731 | /** |
FranKP2138 | 0:2b9b5764efb5 | 732 | * @brief Battery level collector initialization. |
FranKP2138 | 0:2b9b5764efb5 | 733 | */ |
FranKP2138 | 0:2b9b5764efb5 | 734 | static void bas_c_init(void) |
FranKP2138 | 0:2b9b5764efb5 | 735 | { |
FranKP2138 | 0:2b9b5764efb5 | 736 | ble_bas_c_init_t bas_c_init_obj; |
FranKP2138 | 0:2b9b5764efb5 | 737 | |
FranKP2138 | 0:2b9b5764efb5 | 738 | bas_c_init_obj.evt_handler = bas_c_evt_handler; |
FranKP2138 | 0:2b9b5764efb5 | 739 | |
FranKP2138 | 0:2b9b5764efb5 | 740 | uint32_t err_code = ble_bas_c_init(&m_ble_bas_c, &bas_c_init_obj); |
FranKP2138 | 0:2b9b5764efb5 | 741 | APP_ERROR_CHECK(err_code); |
FranKP2138 | 0:2b9b5764efb5 | 742 | } |
FranKP2138 | 0:2b9b5764efb5 | 743 | |
FranKP2138 | 0:2b9b5764efb5 | 744 | |
FranKP2138 | 0:2b9b5764efb5 | 745 | /** |
FranKP2138 | 0:2b9b5764efb5 | 746 | * @brief Database discovery collector initialization. |
FranKP2138 | 0:2b9b5764efb5 | 747 | */ |
FranKP2138 | 0:2b9b5764efb5 | 748 | static void db_discovery_init(void) |
FranKP2138 | 0:2b9b5764efb5 | 749 | { |
FranKP2138 | 0:2b9b5764efb5 | 750 | uint32_t err_code = ble_db_discovery_init(db_disc_handler); |
FranKP2138 | 0:2b9b5764efb5 | 751 | |
FranKP2138 | 0:2b9b5764efb5 | 752 | APP_ERROR_CHECK(err_code); |
FranKP2138 | 0:2b9b5764efb5 | 753 | } |
FranKP2138 | 0:2b9b5764efb5 | 754 | |
FranKP2138 | 0:2b9b5764efb5 | 755 | |
FranKP2138 | 0:2b9b5764efb5 | 756 | /**@brief Function to start scanning. |
FranKP2138 | 0:2b9b5764efb5 | 757 | */ |
FranKP2138 | 0:2b9b5764efb5 | 758 | static void scan_start(void) |
FranKP2138 | 0:2b9b5764efb5 | 759 | { |
FranKP2138 | 0:2b9b5764efb5 | 760 | ble_gap_whitelist_t whitelist; |
FranKP2138 | 0:2b9b5764efb5 | 761 | ble_gap_addr_t * p_whitelist_addr[BLE_GAP_WHITELIST_ADDR_MAX_COUNT]; |
FranKP2138 | 0:2b9b5764efb5 | 762 | ble_gap_irk_t * p_whitelist_irk[BLE_GAP_WHITELIST_IRK_MAX_COUNT]; |
FranKP2138 | 0:2b9b5764efb5 | 763 | uint32_t err_code; |
FranKP2138 | 0:2b9b5764efb5 | 764 | uint32_t count; |
FranKP2138 | 0:2b9b5764efb5 | 765 | |
FranKP2138 | 0:2b9b5764efb5 | 766 | // Verify if there is any flash access pending, if yes delay starting scanning until |
FranKP2138 | 0:2b9b5764efb5 | 767 | // it's complete. |
FranKP2138 | 0:2b9b5764efb5 | 768 | err_code = pstorage_access_status_get(&count); |
FranKP2138 | 0:2b9b5764efb5 | 769 | APP_ERROR_CHECK(err_code); |
FranKP2138 | 0:2b9b5764efb5 | 770 | |
FranKP2138 | 0:2b9b5764efb5 | 771 | if (count != 0) |
FranKP2138 | 0:2b9b5764efb5 | 772 | { |
FranKP2138 | 0:2b9b5764efb5 | 773 | m_memory_access_in_progress = true; |
FranKP2138 | 0:2b9b5764efb5 | 774 | return; |
FranKP2138 | 0:2b9b5764efb5 | 775 | } |
FranKP2138 | 0:2b9b5764efb5 | 776 | |
FranKP2138 | 0:2b9b5764efb5 | 777 | // Initialize whitelist parameters. |
FranKP2138 | 0:2b9b5764efb5 | 778 | whitelist.addr_count = BLE_GAP_WHITELIST_ADDR_MAX_COUNT; |
FranKP2138 | 0:2b9b5764efb5 | 779 | whitelist.irk_count = 0; |
FranKP2138 | 0:2b9b5764efb5 | 780 | whitelist.pp_addrs = p_whitelist_addr; |
FranKP2138 | 0:2b9b5764efb5 | 781 | whitelist.pp_irks = p_whitelist_irk; |
FranKP2138 | 0:2b9b5764efb5 | 782 | |
FranKP2138 | 0:2b9b5764efb5 | 783 | // Request creating of whitelist. |
FranKP2138 | 0:2b9b5764efb5 | 784 | err_code = dm_whitelist_create(&m_dm_app_id,&whitelist); |
FranKP2138 | 0:2b9b5764efb5 | 785 | APP_ERROR_CHECK(err_code); |
FranKP2138 | 0:2b9b5764efb5 | 786 | |
FranKP2138 | 0:2b9b5764efb5 | 787 | if (((whitelist.addr_count == 0) && (whitelist.irk_count == 0)) || |
FranKP2138 | 0:2b9b5764efb5 | 788 | (m_scan_mode != BLE_WHITELIST_SCAN) || |
FranKP2138 | 0:2b9b5764efb5 | 789 | (m_whitelist_temporarily_disabled)) |
FranKP2138 | 0:2b9b5764efb5 | 790 | { |
FranKP2138 | 0:2b9b5764efb5 | 791 | // No devices in whitelist, hence non selective performed. |
FranKP2138 | 0:2b9b5764efb5 | 792 | m_scan_param.active = 0; // Active scanning set. |
FranKP2138 | 0:2b9b5764efb5 | 793 | m_scan_param.selective = 0; // Selective scanning not set. |
FranKP2138 | 0:2b9b5764efb5 | 794 | m_scan_param.interval = SCAN_INTERVAL;// Scan interval. |
FranKP2138 | 0:2b9b5764efb5 | 795 | m_scan_param.window = SCAN_WINDOW; // Scan window. |
FranKP2138 | 0:2b9b5764efb5 | 796 | m_scan_param.p_whitelist = NULL; // No whitelist provided. |
FranKP2138 | 0:2b9b5764efb5 | 797 | m_scan_param.timeout = 0x0000; // No timeout. |
FranKP2138 | 0:2b9b5764efb5 | 798 | } |
FranKP2138 | 0:2b9b5764efb5 | 799 | else |
FranKP2138 | 0:2b9b5764efb5 | 800 | { |
FranKP2138 | 0:2b9b5764efb5 | 801 | // Selective scanning based on whitelist first. |
FranKP2138 | 0:2b9b5764efb5 | 802 | m_scan_param.active = 0; // Active scanning set. |
FranKP2138 | 0:2b9b5764efb5 | 803 | m_scan_param.selective = 1; // Selective scanning not set. |
FranKP2138 | 0:2b9b5764efb5 | 804 | m_scan_param.interval = SCAN_INTERVAL;// Scan interval. |
FranKP2138 | 0:2b9b5764efb5 | 805 | m_scan_param.window = SCAN_WINDOW; // Scan window. |
FranKP2138 | 0:2b9b5764efb5 | 806 | m_scan_param.p_whitelist = &whitelist; // Provide whitelist. |
FranKP2138 | 0:2b9b5764efb5 | 807 | m_scan_param.timeout = 0x001E; // 30 seconds timeout. |
FranKP2138 | 0:2b9b5764efb5 | 808 | } |
FranKP2138 | 0:2b9b5764efb5 | 809 | |
FranKP2138 | 0:2b9b5764efb5 | 810 | err_code = sd_ble_gap_scan_start(&m_scan_param); |
FranKP2138 | 0:2b9b5764efb5 | 811 | APP_ERROR_CHECK(err_code); |
FranKP2138 | 0:2b9b5764efb5 | 812 | |
FranKP2138 | 0:2b9b5764efb5 | 813 | err_code = bsp_indication_set(BSP_INDICATE_SCANNING); |
FranKP2138 | 0:2b9b5764efb5 | 814 | APP_ERROR_CHECK(err_code); |
FranKP2138 | 0:2b9b5764efb5 | 815 | } |
FranKP2138 | 0:2b9b5764efb5 | 816 | |
FranKP2138 | 0:2b9b5764efb5 | 817 | |
FranKP2138 | 0:2b9b5764efb5 | 818 | /**@brief Function for initializing buttons and leds. |
FranKP2138 | 0:2b9b5764efb5 | 819 | * |
FranKP2138 | 0:2b9b5764efb5 | 820 | * @param[out] p_erase_bonds Will be true if the clear bonding button was pressed to wake the application up. |
FranKP2138 | 0:2b9b5764efb5 | 821 | */ |
FranKP2138 | 0:2b9b5764efb5 | 822 | static void buttons_leds_init(bool * p_erase_bonds) |
FranKP2138 | 0:2b9b5764efb5 | 823 | { |
FranKP2138 | 0:2b9b5764efb5 | 824 | bsp_event_t startup_event; |
FranKP2138 | 0:2b9b5764efb5 | 825 | |
FranKP2138 | 0:2b9b5764efb5 | 826 | uint32_t err_code = bsp_init(BSP_INIT_LED | BSP_INIT_BUTTONS, |
FranKP2138 | 0:2b9b5764efb5 | 827 | APP_TIMER_TICKS(100, APP_TIMER_PRESCALER), |
FranKP2138 | 0:2b9b5764efb5 | 828 | bsp_event_handler); |
FranKP2138 | 0:2b9b5764efb5 | 829 | APP_ERROR_CHECK(err_code); |
FranKP2138 | 0:2b9b5764efb5 | 830 | |
FranKP2138 | 0:2b9b5764efb5 | 831 | err_code = bsp_btn_ble_init(NULL, &startup_event); |
FranKP2138 | 0:2b9b5764efb5 | 832 | APP_ERROR_CHECK(err_code); |
FranKP2138 | 0:2b9b5764efb5 | 833 | |
FranKP2138 | 0:2b9b5764efb5 | 834 | *p_erase_bonds = (startup_event == BSP_EVENT_CLEAR_BONDING_DATA); |
FranKP2138 | 0:2b9b5764efb5 | 835 | } |
FranKP2138 | 0:2b9b5764efb5 | 836 | |
FranKP2138 | 0:2b9b5764efb5 | 837 | |
FranKP2138 | 0:2b9b5764efb5 | 838 | /**@brief Function for initializing the nrf log module. |
FranKP2138 | 0:2b9b5764efb5 | 839 | */ |
FranKP2138 | 0:2b9b5764efb5 | 840 | static void nrf_log_init(void) |
FranKP2138 | 0:2b9b5764efb5 | 841 | { |
FranKP2138 | 0:2b9b5764efb5 | 842 | ret_code_t err_code = NRF_LOG_INIT(); |
FranKP2138 | 0:2b9b5764efb5 | 843 | APP_ERROR_CHECK(err_code); |
FranKP2138 | 0:2b9b5764efb5 | 844 | } |
FranKP2138 | 0:2b9b5764efb5 | 845 | |
FranKP2138 | 0:2b9b5764efb5 | 846 | |
FranKP2138 | 0:2b9b5764efb5 | 847 | /** @brief Function for the Power manager. |
FranKP2138 | 0:2b9b5764efb5 | 848 | */ |
FranKP2138 | 0:2b9b5764efb5 | 849 | static void power_manage(void) |
FranKP2138 | 0:2b9b5764efb5 | 850 | { |
FranKP2138 | 0:2b9b5764efb5 | 851 | uint32_t err_code = sd_app_evt_wait(); |
FranKP2138 | 0:2b9b5764efb5 | 852 | APP_ERROR_CHECK(err_code); |
FranKP2138 | 0:2b9b5764efb5 | 853 | } |
FranKP2138 | 0:2b9b5764efb5 | 854 | |
FranKP2138 | 0:2b9b5764efb5 | 855 | |
FranKP2138 | 0:2b9b5764efb5 | 856 | int main(void) |
FranKP2138 | 0:2b9b5764efb5 | 857 | { |
FranKP2138 | 0:2b9b5764efb5 | 858 | bool erase_bonds; |
FranKP2138 | 0:2b9b5764efb5 | 859 | |
FranKP2138 | 0:2b9b5764efb5 | 860 | // Initialize. |
FranKP2138 | 0:2b9b5764efb5 | 861 | APP_TIMER_INIT(APP_TIMER_PRESCALER, APP_TIMER_OP_QUEUE_SIZE, NULL); |
FranKP2138 | 0:2b9b5764efb5 | 862 | buttons_leds_init(&erase_bonds); |
FranKP2138 | 0:2b9b5764efb5 | 863 | nrf_log_init(); |
FranKP2138 | 0:2b9b5764efb5 | 864 | APPL_LOG("Heart rate collector example\r\n"); |
FranKP2138 | 0:2b9b5764efb5 | 865 | ble_stack_init(); |
FranKP2138 | 0:2b9b5764efb5 | 866 | device_manager_init(erase_bonds); |
FranKP2138 | 0:2b9b5764efb5 | 867 | db_discovery_init(); |
FranKP2138 | 0:2b9b5764efb5 | 868 | hrs_c_init(); |
FranKP2138 | 0:2b9b5764efb5 | 869 | bas_c_init(); |
FranKP2138 | 0:2b9b5764efb5 | 870 | |
FranKP2138 | 0:2b9b5764efb5 | 871 | // Start scanning for peripherals and initiate connection |
FranKP2138 | 0:2b9b5764efb5 | 872 | // with devices that advertise Heart Rate UUID. |
FranKP2138 | 0:2b9b5764efb5 | 873 | scan_start(); |
FranKP2138 | 0:2b9b5764efb5 | 874 | |
FranKP2138 | 0:2b9b5764efb5 | 875 | for (;; ) |
FranKP2138 | 0:2b9b5764efb5 | 876 | { |
FranKP2138 | 0:2b9b5764efb5 | 877 | power_manage(); |
FranKP2138 | 0:2b9b5764efb5 | 878 | } |
FranKP2138 | 0:2b9b5764efb5 | 879 | } |
FranKP2138 | 0:2b9b5764efb5 | 880 | |
FranKP2138 | 0:2b9b5764efb5 | 881 | |
FranKP2138 | 0:2b9b5764efb5 | 882 |