A POC Code of doing ANCS with nrf51822-mKit. See README.txt for details.

Dependencies:   BLE_API mbed nRF51822

A sample code implementing ANCS client accessory with nRF51822-mKit. This is just a proof that this thing is indeed doable.

The code itself is complete mess. I'm not planing to furnish this, as the purpose (make sure it is doable) was achieved.

The next step possible step is (no timeline) 1. Implementing Gatt Client API in BLE API (forking?) 2. Do ANCS with that.

Please see README.txt for details.

Committer:
devsar
Date:
Tue Jun 03 04:25:33 2014 +0000
Revision:
0:1f985a7c0a8b
Working code!

Who changed what in which revision?

UserRevisionLine numberNew contents of line
devsar 0:1f985a7c0a8b 1 #include <stdbool.h>
devsar 0:1f985a7c0a8b 2 #include <stdint.h>
devsar 0:1f985a7c0a8b 3 #include <string.h>
devsar 0:1f985a7c0a8b 4
devsar 0:1f985a7c0a8b 5 #include "mbed.h"
devsar 0:1f985a7c0a8b 6 #include "nRF51822n.h"
devsar 0:1f985a7c0a8b 7
devsar 0:1f985a7c0a8b 8 #include "nordic_common.h"
devsar 0:1f985a7c0a8b 9 //#include "nrf.h"
devsar 0:1f985a7c0a8b 10 #include "app_error.h"
devsar 0:1f985a7c0a8b 11 #include "ble_hci.h"
devsar 0:1f985a7c0a8b 12 #include "ble_gap.h"
devsar 0:1f985a7c0a8b 13 #include "ble_advdata.h"
devsar 0:1f985a7c0a8b 14 #include "ble_error_log.h"
devsar 0:1f985a7c0a8b 15 #include "nrf_gpio.h"
devsar 0:1f985a7c0a8b 16 #include "ble_srv_common.h"
devsar 0:1f985a7c0a8b 17 #include "ble_conn_params.h"
devsar 0:1f985a7c0a8b 18 #include "nrf51_bitfields.h"
devsar 0:1f985a7c0a8b 19 #include "ble_bondmngr.h"
devsar 0:1f985a7c0a8b 20 #include "app_timer.h"
devsar 0:1f985a7c0a8b 21 #include "ble_radio_notification.h"
devsar 0:1f985a7c0a8b 22 #include "ble_flash.h"
devsar 0:1f985a7c0a8b 23 #include "ble_debug_assert_handler.h"
devsar 0:1f985a7c0a8b 24 #include "pstorage.h"
devsar 0:1f985a7c0a8b 25 #include "nrf_soc.h"
devsar 0:1f985a7c0a8b 26 #include "softdevice_handler.h"
devsar 0:1f985a7c0a8b 27
devsar 0:1f985a7c0a8b 28 #include "debug.h"
devsar 0:1f985a7c0a8b 29
devsar 0:1f985a7c0a8b 30
devsar 0:1f985a7c0a8b 31 #define DEVICE_NAME "ANCC" /**< Name of device. Will be included in the advertising data. */
devsar 0:1f985a7c0a8b 32 #define APP_ADV_INTERVAL 40 /**< The advertising interval (in units of 0.625 ms. This value corresponds to 25 ms). */
devsar 0:1f985a7c0a8b 33 #define APP_ADV_INTERVAL_SLOW 3200 /**< Slow advertising interval (in units of 0.625 ms. This value corresponds to 2 seconds). */
devsar 0:1f985a7c0a8b 34 #define APP_ADV_TIMEOUT_IN_SECONDS 180 /**< The advertising timeout in units of seconds. */
devsar 0:1f985a7c0a8b 35 #define ADV_INTERVAL_FAST_PERIOD 30 /**< The duration of the fast advertising period (in seconds). */
devsar 0:1f985a7c0a8b 36
devsar 0:1f985a7c0a8b 37 #define APP_TIMER_PRESCALER 0 /**< Value of the RTC1 PRESCALER register. */
devsar 0:1f985a7c0a8b 38 #define APP_TIMER_MAX_TIMERS 2 /**< Maximum number of simultaneously created timers. */
devsar 0:1f985a7c0a8b 39 #define APP_TIMER_OP_QUEUE_SIZE 4 /**< Size of timer operation queues. */
devsar 0:1f985a7c0a8b 40
devsar 0:1f985a7c0a8b 41 #define MIN_CONN_INTERVAL MSEC_TO_UNITS(500, UNIT_1_25_MS) /**< Minimum acceptable connection interval (0.5 seconds). */
devsar 0:1f985a7c0a8b 42 #define MAX_CONN_INTERVAL MSEC_TO_UNITS(1000, UNIT_1_25_MS) /**< Maximum acceptable connection interval (1 second). */
devsar 0:1f985a7c0a8b 43 #define SLAVE_LATENCY 0 /**< Slave latency. */
devsar 0:1f985a7c0a8b 44 #define CONN_SUP_TIMEOUT MSEC_TO_UNITS(4000, UNIT_10_MS) /**< Connection supervisory timeout (4 seconds). */
devsar 0:1f985a7c0a8b 45
devsar 0:1f985a7c0a8b 46 #define FIRST_CONN_PARAMS_UPDATE_DELAY APP_TIMER_TICKS(20 * 1000, APP_TIMER_PRESCALER) /**< Time from initiating event (connect or start of notification) to first time sd_ble_gap_conn_param_update is called (20 seconds). */
devsar 0:1f985a7c0a8b 47 #define NEXT_CONN_PARAMS_UPDATE_DELAY APP_TIMER_TICKS(5 * 1000, APP_TIMER_PRESCALER) /**< Time between each call to sd_ble_gap_conn_param_update after the first (5 seconds). */
devsar 0:1f985a7c0a8b 48 #define MAX_CONN_PARAMS_UPDATE_COUNT 3 /**< Number of attempts before giving up the connection parameter negotiation. */
devsar 0:1f985a7c0a8b 49
devsar 0:1f985a7c0a8b 50
devsar 0:1f985a7c0a8b 51 #define SEC_PARAM_TIMEOUT 30 /**< Timeout for Pairing Request or Security Request (in seconds). */
devsar 0:1f985a7c0a8b 52 #define SEC_PARAM_BOND 0 /**< Perform bonding. */
devsar 0:1f985a7c0a8b 53 #define SEC_PARAM_MITM 0 /**< Man In The Middle protection not required. */
devsar 0:1f985a7c0a8b 54 #define SEC_PARAM_IO_CAPABILITIES BLE_GAP_IO_CAPS_NONE /**< No I/O capabilities. */
devsar 0:1f985a7c0a8b 55 #define SEC_PARAM_OOB 0 /**< Out Of Band data not available. */
devsar 0:1f985a7c0a8b 56 #define SEC_PARAM_MIN_KEY_SIZE 7 /**< Minimum encryption key size. */
devsar 0:1f985a7c0a8b 57 #define SEC_PARAM_MAX_KEY_SIZE 16 /**< Maximum encryption key size. */
devsar 0:1f985a7c0a8b 58
devsar 0:1f985a7c0a8b 59 #define BLE_UUID_APPLE_NOTIFICATION_CENTER_SERVICE 0xf431 /*<< ANCS service UUID. */
devsar 0:1f985a7c0a8b 60 #define BLE_UUID_ANCS_CONTROL_POINT_CHAR 0xd8f3 /*<< Control point UUID. */
devsar 0:1f985a7c0a8b 61 #define BLE_UUID_ANCS_NOTIFICATION_SOURCE_CHAR 0x120d /*<< Notification source UUID. */
devsar 0:1f985a7c0a8b 62 #define BLE_UUID_ANCS_DATA_SOURCE_CHAR 0xc6e9 /*<< Data source UUID. */
devsar 0:1f985a7c0a8b 63
devsar 0:1f985a7c0a8b 64 #define BLE_CCCD_NOTIFY_BIT_MASK 0x0001 /**< Enable Notification bit. */
devsar 0:1f985a7c0a8b 65
devsar 0:1f985a7c0a8b 66
devsar 0:1f985a7c0a8b 67 typedef enum
devsar 0:1f985a7c0a8b 68 {
devsar 0:1f985a7c0a8b 69 BLE_NO_ADVERTISING, /**< No advertising running. */
devsar 0:1f985a7c0a8b 70 BLE_SLOW_ADVERTISING, /**< Slow advertising running. */
devsar 0:1f985a7c0a8b 71 BLE_FAST_ADVERTISING /**< Fast advertising running. */
devsar 0:1f985a7c0a8b 72 } ble_advertising_mode_t;
devsar 0:1f985a7c0a8b 73
devsar 0:1f985a7c0a8b 74 typedef enum
devsar 0:1f985a7c0a8b 75 {
devsar 0:1f985a7c0a8b 76 STATE_UNINITIALIZED, // Program start.
devsar 0:1f985a7c0a8b 77 STATE_ADVERTISING, // Advertising. See Settings>Bluetooth on iPhone then connect to "ANCC"
devsar 0:1f985a7c0a8b 78 STATE_CONNECTED, // iPhone connected to us.
devsar 0:1f985a7c0a8b 79 STATE_DISCOVERY_SERVICE, // Searching for ANCS Service.
devsar 0:1f985a7c0a8b 80 STATE_DISCOVERY_CHARACTERISTICS, // Searching for ANCS Characteristics.
devsar 0:1f985a7c0a8b 81 STATE_PAIRING, // Got all we need. Now pair before subscribe. Should see pairing dialog on iPhone
devsar 0:1f985a7c0a8b 82 STATE_SUBSCRIBING, // Subscribe to CCC, for notification.
devsar 0:1f985a7c0a8b 83 STATE_LISTENING, // Listening...
devsar 0:1f985a7c0a8b 84 STATE_NOTIFIED, // Got notification, now retrieve other info and print log out. back to listening.
devsar 0:1f985a7c0a8b 85 STATE_DISCONNECTED, // Disconnected?
devsar 0:1f985a7c0a8b 86 STATE_ERROR
devsar 0:1f985a7c0a8b 87 } state_t;
devsar 0:1f985a7c0a8b 88
devsar 0:1f985a7c0a8b 89
devsar 0:1f985a7c0a8b 90
devsar 0:1f985a7c0a8b 91 DigitalOut led_adv(LED1);
devsar 0:1f985a7c0a8b 92 DigitalOut led_conn(LED2);
devsar 0:1f985a7c0a8b 93
devsar 0:1f985a7c0a8b 94 Serial pc(USBTX, USBRX);
devsar 0:1f985a7c0a8b 95
devsar 0:1f985a7c0a8b 96 const ble_uuid128_t ble_ancs_base_uuid128 =
devsar 0:1f985a7c0a8b 97 {
devsar 0:1f985a7c0a8b 98 {
devsar 0:1f985a7c0a8b 99 // 7905F431-B5CE-4E99-A40F-4B1E122D00D0
devsar 0:1f985a7c0a8b 100 0xd0, 0x00, 0x2d, 0x12, 0x1e, 0x4b, 0x0f, 0xa4,
devsar 0:1f985a7c0a8b 101 0x99, 0x4e, 0xce, 0xb5, 0x31, 0xf4, 0x05, 0x79
devsar 0:1f985a7c0a8b 102 }
devsar 0:1f985a7c0a8b 103 };
devsar 0:1f985a7c0a8b 104
devsar 0:1f985a7c0a8b 105
devsar 0:1f985a7c0a8b 106 const ble_uuid128_t ble_ancs_cp_base_uuid128 =
devsar 0:1f985a7c0a8b 107 {
devsar 0:1f985a7c0a8b 108 {
devsar 0:1f985a7c0a8b 109 // 69d1d8f3-45e1-49a8-9821-9bbdfdaad9d9
devsar 0:1f985a7c0a8b 110 0xd9, 0xd9, 0xaa, 0xfd, 0xbd, 0x9b, 0x21, 0x98,
devsar 0:1f985a7c0a8b 111 0xa8, 0x49, 0xe1, 0x45, 0xf3, 0xd8, 0xd1, 0x69
devsar 0:1f985a7c0a8b 112
devsar 0:1f985a7c0a8b 113 }
devsar 0:1f985a7c0a8b 114 };
devsar 0:1f985a7c0a8b 115
devsar 0:1f985a7c0a8b 116 const ble_uuid128_t ble_ancs_ns_base_uuid128 =
devsar 0:1f985a7c0a8b 117 {
devsar 0:1f985a7c0a8b 118 {
devsar 0:1f985a7c0a8b 119 // 9FBF120D-6301-42D9-8C58-25E699A21DBD
devsar 0:1f985a7c0a8b 120 0xbd, 0x1d, 0xa2, 0x99, 0xe6, 0x25, 0x58, 0x8c,
devsar 0:1f985a7c0a8b 121 0xd9, 0x42, 0x01, 0x63, 0x0d, 0x12, 0xbf, 0x9f
devsar 0:1f985a7c0a8b 122
devsar 0:1f985a7c0a8b 123 }
devsar 0:1f985a7c0a8b 124 };
devsar 0:1f985a7c0a8b 125
devsar 0:1f985a7c0a8b 126 const ble_uuid128_t ble_ancs_ds_base_uuid128 =
devsar 0:1f985a7c0a8b 127 {
devsar 0:1f985a7c0a8b 128 {
devsar 0:1f985a7c0a8b 129 // 22EAC6E9-24D6-4BB5-BE44-B36ACE7C7BFB
devsar 0:1f985a7c0a8b 130 0xfb, 0x7b, 0x7c, 0xce, 0x6a, 0xb3, 0x44, 0xbe,
devsar 0:1f985a7c0a8b 131 0xb5, 0x4b, 0xd6, 0x24, 0xe9, 0xc6, 0xea, 0x22
devsar 0:1f985a7c0a8b 132
devsar 0:1f985a7c0a8b 133 }
devsar 0:1f985a7c0a8b 134 };
devsar 0:1f985a7c0a8b 135
devsar 0:1f985a7c0a8b 136 static state_t m_state = STATE_UNINITIALIZED;
devsar 0:1f985a7c0a8b 137
devsar 0:1f985a7c0a8b 138 static ble_gap_adv_params_t m_adv_params; /**< Parameters to be passed to the stack when starting advertising. */
devsar 0:1f985a7c0a8b 139 static ble_advertising_mode_t m_advertising_mode; /**< Variable to keep track of when we are advertising. */
devsar 0:1f985a7c0a8b 140
devsar 0:1f985a7c0a8b 141 static ble_gap_sec_params_t m_sec_params; /**< Security requirements for this application. */
devsar 0:1f985a7c0a8b 142
devsar 0:1f985a7c0a8b 143 // ANCS Characteristic...
devsar 0:1f985a7c0a8b 144 static uint16_t m_notification_source_handle = 0;
devsar 0:1f985a7c0a8b 145 static uint16_t m_notification_source_handle_cccd = 0;
devsar 0:1f985a7c0a8b 146 static uint16_t m_control_point_handle = 0;
devsar 0:1f985a7c0a8b 147 static uint16_t m_data_source_handle = 0;
devsar 0:1f985a7c0a8b 148 static uint16_t m_data_source_handle_cccd = 0;
devsar 0:1f985a7c0a8b 149
devsar 0:1f985a7c0a8b 150 static void err_check(uint32_t error_code, char *method)
devsar 0:1f985a7c0a8b 151 {
devsar 0:1f985a7c0a8b 152 if(error_code != NRF_SUCCESS) {
devsar 0:1f985a7c0a8b 153 pc.printf("ERROR: %d (%s) on %s\r\n", error_code, error2string(error_code), method);
devsar 0:1f985a7c0a8b 154 // } else {
devsar 0:1f985a7c0a8b 155 // pc.printf("SUCCESS: %s\r\n", method);
devsar 0:1f985a7c0a8b 156 }
devsar 0:1f985a7c0a8b 157 APP_ERROR_CHECK(error_code);
devsar 0:1f985a7c0a8b 158 }
devsar 0:1f985a7c0a8b 159
devsar 0:1f985a7c0a8b 160
devsar 0:1f985a7c0a8b 161 static void advertising_start(void)
devsar 0:1f985a7c0a8b 162 {
devsar 0:1f985a7c0a8b 163 uint32_t err_code;
devsar 0:1f985a7c0a8b 164
devsar 0:1f985a7c0a8b 165 if (m_advertising_mode == BLE_NO_ADVERTISING)
devsar 0:1f985a7c0a8b 166 {
devsar 0:1f985a7c0a8b 167 m_advertising_mode = BLE_FAST_ADVERTISING;
devsar 0:1f985a7c0a8b 168 }
devsar 0:1f985a7c0a8b 169 else
devsar 0:1f985a7c0a8b 170 {
devsar 0:1f985a7c0a8b 171 m_advertising_mode = BLE_SLOW_ADVERTISING;
devsar 0:1f985a7c0a8b 172 }
devsar 0:1f985a7c0a8b 173
devsar 0:1f985a7c0a8b 174 memset(&m_adv_params, 0, sizeof(m_adv_params));
devsar 0:1f985a7c0a8b 175
devsar 0:1f985a7c0a8b 176 m_adv_params.type = BLE_GAP_ADV_TYPE_ADV_IND;
devsar 0:1f985a7c0a8b 177 m_adv_params.p_peer_addr = NULL; // Undirected advertisement.
devsar 0:1f985a7c0a8b 178 m_adv_params.fp = BLE_GAP_ADV_FP_ANY;
devsar 0:1f985a7c0a8b 179
devsar 0:1f985a7c0a8b 180 if (m_advertising_mode == BLE_FAST_ADVERTISING)
devsar 0:1f985a7c0a8b 181 {
devsar 0:1f985a7c0a8b 182 m_adv_params.interval = APP_ADV_INTERVAL;
devsar 0:1f985a7c0a8b 183 m_adv_params.timeout = ADV_INTERVAL_FAST_PERIOD;
devsar 0:1f985a7c0a8b 184 }
devsar 0:1f985a7c0a8b 185 else
devsar 0:1f985a7c0a8b 186 {
devsar 0:1f985a7c0a8b 187 m_adv_params.interval = APP_ADV_INTERVAL_SLOW;
devsar 0:1f985a7c0a8b 188 m_adv_params.timeout = APP_ADV_TIMEOUT_IN_SECONDS;
devsar 0:1f985a7c0a8b 189 }
devsar 0:1f985a7c0a8b 190
devsar 0:1f985a7c0a8b 191 err_code = sd_ble_gap_adv_start(&m_adv_params);
devsar 0:1f985a7c0a8b 192 err_check(err_code, "sd_ble_gap_adv_start");
devsar 0:1f985a7c0a8b 193
devsar 0:1f985a7c0a8b 194 led_adv = 1;
devsar 0:1f985a7c0a8b 195 m_state = STATE_ADVERTISING;
devsar 0:1f985a7c0a8b 196 }
devsar 0:1f985a7c0a8b 197
devsar 0:1f985a7c0a8b 198
devsar 0:1f985a7c0a8b 199
devsar 0:1f985a7c0a8b 200
devsar 0:1f985a7c0a8b 201 static void ble_event_handler(ble_evt_t * p_ble_evt)
devsar 0:1f985a7c0a8b 202 {
devsar 0:1f985a7c0a8b 203 uint32_t err_code = NRF_SUCCESS;
devsar 0:1f985a7c0a8b 204 static uint16_t m_conn_handle = BLE_CONN_HANDLE_INVALID;
devsar 0:1f985a7c0a8b 205 ble_uuid_t ancs_uuid;
devsar 0:1f985a7c0a8b 206 static ble_gattc_handle_range_t handle_range;
devsar 0:1f985a7c0a8b 207
devsar 0:1f985a7c0a8b 208 pc.printf("Event: %s\r\n", event2string(p_ble_evt));
devsar 0:1f985a7c0a8b 209 // ble_bondmngr_on_ble_evt(p_ble_evt);
devsar 0:1f985a7c0a8b 210 // ble_conn_params_on_ble_evt(p_ble_evt);
devsar 0:1f985a7c0a8b 211
devsar 0:1f985a7c0a8b 212 switch (p_ble_evt->header.evt_id)
devsar 0:1f985a7c0a8b 213 {
devsar 0:1f985a7c0a8b 214 case BLE_GAP_EVT_CONNECTED:
devsar 0:1f985a7c0a8b 215 {
devsar 0:1f985a7c0a8b 216 m_state = STATE_CONNECTED;
devsar 0:1f985a7c0a8b 217
devsar 0:1f985a7c0a8b 218 m_advertising_mode = BLE_NO_ADVERTISING;
devsar 0:1f985a7c0a8b 219 m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
devsar 0:1f985a7c0a8b 220 led_conn = 1;
devsar 0:1f985a7c0a8b 221
devsar 0:1f985a7c0a8b 222 m_state = STATE_DISCOVERY_SERVICE;
devsar 0:1f985a7c0a8b 223
devsar 0:1f985a7c0a8b 224 BLE_UUID_BLE_ASSIGN(ancs_uuid, BLE_UUID_APPLE_NOTIFICATION_CENTER_SERVICE);
devsar 0:1f985a7c0a8b 225 ancs_uuid.type = BLE_UUID_TYPE_VENDOR_BEGIN;
devsar 0:1f985a7c0a8b 226
devsar 0:1f985a7c0a8b 227 err_code = sd_ble_gattc_primary_services_discover(m_conn_handle, 0x0001, &ancs_uuid);
devsar 0:1f985a7c0a8b 228 err_check(err_code, "sd_ble_gattc_primary_services_discover");
devsar 0:1f985a7c0a8b 229
devsar 0:1f985a7c0a8b 230
devsar 0:1f985a7c0a8b 231 break;
devsar 0:1f985a7c0a8b 232 }
devsar 0:1f985a7c0a8b 233 case BLE_GAP_EVT_AUTH_STATUS:
devsar 0:1f985a7c0a8b 234 {
devsar 0:1f985a7c0a8b 235 m_state = STATE_SUBSCRIBING;
devsar 0:1f985a7c0a8b 236
devsar 0:1f985a7c0a8b 237 // Subscribe to NS
devsar 0:1f985a7c0a8b 238 uint16_t cccd_val = true ? BLE_CCCD_NOTIFY_BIT_MASK : 0;
devsar 0:1f985a7c0a8b 239 static ble_gattc_write_params_t m_write_params;
devsar 0:1f985a7c0a8b 240 uint8_t gattc_value[2];
devsar 0:1f985a7c0a8b 241
devsar 0:1f985a7c0a8b 242 gattc_value[0] = LSB(cccd_val);
devsar 0:1f985a7c0a8b 243 gattc_value[1] = MSB(cccd_val);
devsar 0:1f985a7c0a8b 244
devsar 0:1f985a7c0a8b 245 m_write_params.handle = m_notification_source_handle_cccd;
devsar 0:1f985a7c0a8b 246 m_write_params.len = 2;
devsar 0:1f985a7c0a8b 247 m_write_params.p_value = &gattc_value[0];
devsar 0:1f985a7c0a8b 248 m_write_params.offset = 0;
devsar 0:1f985a7c0a8b 249 m_write_params.write_op = BLE_GATT_OP_WRITE_REQ;
devsar 0:1f985a7c0a8b 250
devsar 0:1f985a7c0a8b 251
devsar 0:1f985a7c0a8b 252 err_code = sd_ble_gattc_write(m_conn_handle, &m_write_params);
devsar 0:1f985a7c0a8b 253 err_check(err_code, "sd_ble_gattc_write");
devsar 0:1f985a7c0a8b 254
devsar 0:1f985a7c0a8b 255 break;
devsar 0:1f985a7c0a8b 256 }
devsar 0:1f985a7c0a8b 257 case BLE_GAP_EVT_DISCONNECTED:
devsar 0:1f985a7c0a8b 258 {
devsar 0:1f985a7c0a8b 259 m_conn_handle = BLE_CONN_HANDLE_INVALID;
devsar 0:1f985a7c0a8b 260
devsar 0:1f985a7c0a8b 261 advertising_start();
devsar 0:1f985a7c0a8b 262 led_conn = 0;
devsar 0:1f985a7c0a8b 263 break;
devsar 0:1f985a7c0a8b 264 }
devsar 0:1f985a7c0a8b 265 case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
devsar 0:1f985a7c0a8b 266 {
devsar 0:1f985a7c0a8b 267 err_code = sd_ble_gap_sec_params_reply(m_conn_handle,
devsar 0:1f985a7c0a8b 268 BLE_GAP_SEC_STATUS_SUCCESS,
devsar 0:1f985a7c0a8b 269 &m_sec_params);
devsar 0:1f985a7c0a8b 270 err_check(err_code, "sd_ble_gap_sec_params_reply");
devsar 0:1f985a7c0a8b 271 break;
devsar 0:1f985a7c0a8b 272 }
devsar 0:1f985a7c0a8b 273 case BLE_GAP_EVT_TIMEOUT:
devsar 0:1f985a7c0a8b 274 {
devsar 0:1f985a7c0a8b 275 if (p_ble_evt->evt.gap_evt.params.timeout.src == BLE_GAP_TIMEOUT_SRC_ADVERTISEMENT)
devsar 0:1f985a7c0a8b 276 {
devsar 0:1f985a7c0a8b 277 if (m_advertising_mode == BLE_FAST_ADVERTISING)
devsar 0:1f985a7c0a8b 278 {
devsar 0:1f985a7c0a8b 279 advertising_start();
devsar 0:1f985a7c0a8b 280 }
devsar 0:1f985a7c0a8b 281 else
devsar 0:1f985a7c0a8b 282 {
devsar 0:1f985a7c0a8b 283 err_code = sd_power_system_off();
devsar 0:1f985a7c0a8b 284 }
devsar 0:1f985a7c0a8b 285 }
devsar 0:1f985a7c0a8b 286 break;
devsar 0:1f985a7c0a8b 287 }
devsar 0:1f985a7c0a8b 288 case BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP:
devsar 0:1f985a7c0a8b 289 {
devsar 0:1f985a7c0a8b 290 if (p_ble_evt->evt.gattc_evt.gatt_status != BLE_GATT_STATUS_SUCCESS) {
devsar 0:1f985a7c0a8b 291 // Error.
devsar 0:1f985a7c0a8b 292 pc.printf("Error: %s\r\n", "BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP");
devsar 0:1f985a7c0a8b 293 } else {
devsar 0:1f985a7c0a8b 294 if (p_ble_evt->evt.gattc_evt.params.prim_srvc_disc_rsp.count > 0) {
devsar 0:1f985a7c0a8b 295 const ble_gattc_service_t * p_service;
devsar 0:1f985a7c0a8b 296
devsar 0:1f985a7c0a8b 297 p_service = &(p_ble_evt->evt.gattc_evt.params.prim_srvc_disc_rsp.services[0]);
devsar 0:1f985a7c0a8b 298
devsar 0:1f985a7c0a8b 299 pc.printf("Found ANCS service, start handle: %d, end handle: %d\r\n",
devsar 0:1f985a7c0a8b 300 p_service->handle_range.start_handle, p_service->handle_range.end_handle);
devsar 0:1f985a7c0a8b 301
devsar 0:1f985a7c0a8b 302 handle_range.start_handle = p_service->handle_range.start_handle;
devsar 0:1f985a7c0a8b 303 handle_range.end_handle = p_service->handle_range.end_handle;
devsar 0:1f985a7c0a8b 304
devsar 0:1f985a7c0a8b 305 err_code = sd_ble_gattc_characteristics_discover(m_conn_handle, &handle_range);
devsar 0:1f985a7c0a8b 306 err_check(err_code, "sd_ble_gattc_characteristics_discover");
devsar 0:1f985a7c0a8b 307
devsar 0:1f985a7c0a8b 308 m_state = STATE_DISCOVERY_CHARACTERISTICS;
devsar 0:1f985a7c0a8b 309
devsar 0:1f985a7c0a8b 310 } else {
devsar 0:1f985a7c0a8b 311 pc.printf("Error: discovery failure, no ANCS\r\n");
devsar 0:1f985a7c0a8b 312 }
devsar 0:1f985a7c0a8b 313 }
devsar 0:1f985a7c0a8b 314
devsar 0:1f985a7c0a8b 315 break;
devsar 0:1f985a7c0a8b 316 }
devsar 0:1f985a7c0a8b 317 case BLE_GATTC_EVT_CHAR_DISC_RSP:
devsar 0:1f985a7c0a8b 318 {
devsar 0:1f985a7c0a8b 319 // End of characteristics searching...no more attribute or no more handle.
devsar 0:1f985a7c0a8b 320 // We got error as response, but this is normal for gatt attribute searching.
devsar 0:1f985a7c0a8b 321 if (p_ble_evt->evt.gattc_evt.gatt_status == BLE_GATT_STATUS_ATTERR_ATTRIBUTE_NOT_FOUND ||
devsar 0:1f985a7c0a8b 322 p_ble_evt->evt.gattc_evt.gatt_status == BLE_GATT_STATUS_ATTERR_INVALID_HANDLE) {
devsar 0:1f985a7c0a8b 323
devsar 0:1f985a7c0a8b 324 if(m_notification_source_handle == 0) {
devsar 0:1f985a7c0a8b 325 pc.printf("Error: NS not found.\r\n");
devsar 0:1f985a7c0a8b 326 } else if(m_control_point_handle == 0) {
devsar 0:1f985a7c0a8b 327 pc.printf("Error: CP not found.\r\n");
devsar 0:1f985a7c0a8b 328 } else if(m_data_source_handle == 0) {
devsar 0:1f985a7c0a8b 329 pc.printf("Error: DS not found.\r\n");
devsar 0:1f985a7c0a8b 330 }
devsar 0:1f985a7c0a8b 331 // OK, we got all char handles. Next, find CCC.
devsar 0:1f985a7c0a8b 332 else {
devsar 0:1f985a7c0a8b 333 // Start with NS CCC
devsar 0:1f985a7c0a8b 334 handle_range.start_handle = m_notification_source_handle + 1;
devsar 0:1f985a7c0a8b 335 handle_range.end_handle = m_notification_source_handle + 1;
devsar 0:1f985a7c0a8b 336
devsar 0:1f985a7c0a8b 337 err_code = sd_ble_gattc_descriptors_discover(m_conn_handle, &handle_range);
devsar 0:1f985a7c0a8b 338 err_check(err_code, "sd_ble_gattc_descriptors_discover");
devsar 0:1f985a7c0a8b 339 }
devsar 0:1f985a7c0a8b 340
devsar 0:1f985a7c0a8b 341 } else if (p_ble_evt->evt.gattc_evt.gatt_status != BLE_GATT_STATUS_SUCCESS) {
devsar 0:1f985a7c0a8b 342 pc.printf("Error: %s\r\n", "BLE_GATTC_EVT_CHAR_DISC_RSP");
devsar 0:1f985a7c0a8b 343 } else {
devsar 0:1f985a7c0a8b 344 uint32_t i;
devsar 0:1f985a7c0a8b 345 const ble_gattc_char_t * p_char_resp = NULL;
devsar 0:1f985a7c0a8b 346
devsar 0:1f985a7c0a8b 347 // Iterate trough the characteristics and find the correct one.
devsar 0:1f985a7c0a8b 348 for (i = 0; i < p_ble_evt->evt.gattc_evt.params.char_disc_rsp.count; i++) {
devsar 0:1f985a7c0a8b 349 p_char_resp = &(p_ble_evt->evt.gattc_evt.params.char_disc_rsp.chars[i]);
devsar 0:1f985a7c0a8b 350 switch (p_char_resp->uuid.uuid) {
devsar 0:1f985a7c0a8b 351 case BLE_UUID_ANCS_CONTROL_POINT_CHAR:
devsar 0:1f985a7c0a8b 352 pc.printf("Found char: Control Point");
devsar 0:1f985a7c0a8b 353 m_control_point_handle = p_char_resp->handle_value;
devsar 0:1f985a7c0a8b 354 break;
devsar 0:1f985a7c0a8b 355
devsar 0:1f985a7c0a8b 356 case BLE_UUID_ANCS_NOTIFICATION_SOURCE_CHAR:
devsar 0:1f985a7c0a8b 357 pc.printf("Found char: Notification Source");
devsar 0:1f985a7c0a8b 358 m_notification_source_handle = p_char_resp->handle_value;
devsar 0:1f985a7c0a8b 359 break;
devsar 0:1f985a7c0a8b 360
devsar 0:1f985a7c0a8b 361 case BLE_UUID_ANCS_DATA_SOURCE_CHAR:
devsar 0:1f985a7c0a8b 362 pc.printf("Found char: Data Source");
devsar 0:1f985a7c0a8b 363 m_data_source_handle = p_char_resp->handle_value;
devsar 0:1f985a7c0a8b 364 break;
devsar 0:1f985a7c0a8b 365
devsar 0:1f985a7c0a8b 366 default:
devsar 0:1f985a7c0a8b 367 break;
devsar 0:1f985a7c0a8b 368 }
devsar 0:1f985a7c0a8b 369 }
devsar 0:1f985a7c0a8b 370
devsar 0:1f985a7c0a8b 371 if(p_char_resp!=NULL) {
devsar 0:1f985a7c0a8b 372
devsar 0:1f985a7c0a8b 373 handle_range.start_handle = p_char_resp->handle_value + 1;
devsar 0:1f985a7c0a8b 374
devsar 0:1f985a7c0a8b 375 err_code = sd_ble_gattc_characteristics_discover(m_conn_handle, &handle_range);
devsar 0:1f985a7c0a8b 376 err_check(err_code, "sd_ble_gattc_characteristics_discover");
devsar 0:1f985a7c0a8b 377
devsar 0:1f985a7c0a8b 378 } else {
devsar 0:1f985a7c0a8b 379 err_code = sd_ble_gattc_characteristics_discover(m_conn_handle, &handle_range);
devsar 0:1f985a7c0a8b 380 err_check(err_code, "sd_ble_gattc_characteristics_discover");
devsar 0:1f985a7c0a8b 381 }
devsar 0:1f985a7c0a8b 382
devsar 0:1f985a7c0a8b 383 }
devsar 0:1f985a7c0a8b 384
devsar 0:1f985a7c0a8b 385 break;
devsar 0:1f985a7c0a8b 386 }
devsar 0:1f985a7c0a8b 387 case BLE_GATTC_EVT_DESC_DISC_RSP:
devsar 0:1f985a7c0a8b 388 {
devsar 0:1f985a7c0a8b 389 if (p_ble_evt->evt.gattc_evt.gatt_status != BLE_GATT_STATUS_SUCCESS) {
devsar 0:1f985a7c0a8b 390 pc.printf("Error: %s\r\n", "BLE_GATTC_EVT_DESC_DISC_RSP");
devsar 0:1f985a7c0a8b 391 } else {
devsar 0:1f985a7c0a8b 392 if (p_ble_evt->evt.gattc_evt.params.desc_disc_rsp.count > 0) {
devsar 0:1f985a7c0a8b 393 const ble_gattc_desc_t * p_desc_resp = &(p_ble_evt->evt.gattc_evt.params.desc_disc_rsp.descs[0]);
devsar 0:1f985a7c0a8b 394 if (p_desc_resp->uuid.uuid == BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG) {
devsar 0:1f985a7c0a8b 395 if(p_desc_resp->handle == m_notification_source_handle + 1) {
devsar 0:1f985a7c0a8b 396
devsar 0:1f985a7c0a8b 397 m_notification_source_handle_cccd = p_desc_resp->handle;
devsar 0:1f985a7c0a8b 398 pc.printf("Found NS CCC\r\n");
devsar 0:1f985a7c0a8b 399
devsar 0:1f985a7c0a8b 400 // Next, find CCC for data source.
devsar 0:1f985a7c0a8b 401 handle_range.start_handle = m_data_source_handle + 1;
devsar 0:1f985a7c0a8b 402 handle_range.end_handle = m_data_source_handle + 1;
devsar 0:1f985a7c0a8b 403
devsar 0:1f985a7c0a8b 404 err_code = sd_ble_gattc_descriptors_discover(m_conn_handle, &handle_range);
devsar 0:1f985a7c0a8b 405 err_check(err_code, "sd_ble_gattc_descriptors_discover");
devsar 0:1f985a7c0a8b 406
devsar 0:1f985a7c0a8b 407 } else if(p_desc_resp->handle == m_data_source_handle + 1) {
devsar 0:1f985a7c0a8b 408
devsar 0:1f985a7c0a8b 409 m_data_source_handle_cccd = p_desc_resp->handle;
devsar 0:1f985a7c0a8b 410 pc.printf("Found DS CCC\r\n");
devsar 0:1f985a7c0a8b 411
devsar 0:1f985a7c0a8b 412 // Got all we need, now before subscribing we'll do pairing.
devsar 0:1f985a7c0a8b 413 // request encryption...., we are in peripheral role.
devsar 0:1f985a7c0a8b 414
devsar 0:1f985a7c0a8b 415 m_state = STATE_PAIRING;
devsar 0:1f985a7c0a8b 416
devsar 0:1f985a7c0a8b 417 err_code = sd_ble_gap_authenticate(m_conn_handle, &m_sec_params);
devsar 0:1f985a7c0a8b 418 err_check(err_code, "sd_ble_gap_authenticate");
devsar 0:1f985a7c0a8b 419 }
devsar 0:1f985a7c0a8b 420 }
devsar 0:1f985a7c0a8b 421 }
devsar 0:1f985a7c0a8b 422 }
devsar 0:1f985a7c0a8b 423 break;
devsar 0:1f985a7c0a8b 424 }
devsar 0:1f985a7c0a8b 425 case BLE_GATTC_EVT_WRITE_RSP:
devsar 0:1f985a7c0a8b 426 {
devsar 0:1f985a7c0a8b 427 if (p_ble_evt->evt.gattc_evt.gatt_status != BLE_GATT_STATUS_SUCCESS) {
devsar 0:1f985a7c0a8b 428 pc.printf("Error: %s\r\n", "BLE_GATTC_EVT_WRITE_RSP");
devsar 0:1f985a7c0a8b 429
devsar 0:1f985a7c0a8b 430 if(p_ble_evt->evt.gattc_evt.params.write_rsp.handle == m_control_point_handle) {
devsar 0:1f985a7c0a8b 431 m_state = STATE_LISTENING;
devsar 0:1f985a7c0a8b 432 }
devsar 0:1f985a7c0a8b 433 } else {
devsar 0:1f985a7c0a8b 434 if(p_ble_evt->evt.gattc_evt.params.write_rsp.handle == m_notification_source_handle_cccd) {
devsar 0:1f985a7c0a8b 435 pc.printf("NS subscribe success.\r\n");
devsar 0:1f985a7c0a8b 436
devsar 0:1f985a7c0a8b 437 // Next, subscribe to DS.
devsar 0:1f985a7c0a8b 438 uint16_t cccd_val = true ? BLE_CCCD_NOTIFY_BIT_MASK : 0;
devsar 0:1f985a7c0a8b 439 static ble_gattc_write_params_t m_write_params;
devsar 0:1f985a7c0a8b 440 uint8_t gattc_value[2];
devsar 0:1f985a7c0a8b 441
devsar 0:1f985a7c0a8b 442 gattc_value[0] = LSB(cccd_val);
devsar 0:1f985a7c0a8b 443 gattc_value[1] = MSB(cccd_val);
devsar 0:1f985a7c0a8b 444
devsar 0:1f985a7c0a8b 445 m_write_params.handle = m_data_source_handle_cccd;
devsar 0:1f985a7c0a8b 446 m_write_params.len = 2;
devsar 0:1f985a7c0a8b 447 m_write_params.p_value = &gattc_value[0];
devsar 0:1f985a7c0a8b 448 m_write_params.offset = 0;
devsar 0:1f985a7c0a8b 449 m_write_params.write_op = BLE_GATT_OP_WRITE_REQ;
devsar 0:1f985a7c0a8b 450
devsar 0:1f985a7c0a8b 451 err_code = sd_ble_gattc_write(m_conn_handle, &m_write_params);
devsar 0:1f985a7c0a8b 452 err_check(err_code, "sd_ble_gattc_write");
devsar 0:1f985a7c0a8b 453 }
devsar 0:1f985a7c0a8b 454
devsar 0:1f985a7c0a8b 455 if(p_ble_evt->evt.gattc_evt.params.write_rsp.handle == m_data_source_handle_cccd) {
devsar 0:1f985a7c0a8b 456 pc.printf("DS subscribe success.\r\n");
devsar 0:1f985a7c0a8b 457
devsar 0:1f985a7c0a8b 458 // Now, we just waiting for NS notification.
devsar 0:1f985a7c0a8b 459 m_state = STATE_LISTENING;
devsar 0:1f985a7c0a8b 460 }
devsar 0:1f985a7c0a8b 461
devsar 0:1f985a7c0a8b 462 if(p_ble_evt->evt.gattc_evt.params.write_rsp.handle == m_control_point_handle) {
devsar 0:1f985a7c0a8b 463 pc.printf("CP write success.\r\n");
devsar 0:1f985a7c0a8b 464 // We'll receive data from DS notification
devsar 0:1f985a7c0a8b 465 }
devsar 0:1f985a7c0a8b 466
devsar 0:1f985a7c0a8b 467 }
devsar 0:1f985a7c0a8b 468
devsar 0:1f985a7c0a8b 469 break;
devsar 0:1f985a7c0a8b 470 }
devsar 0:1f985a7c0a8b 471 case BLE_GATTC_EVT_HVX:
devsar 0:1f985a7c0a8b 472 {
devsar 0:1f985a7c0a8b 473 if (p_ble_evt->evt.gattc_evt.gatt_status != BLE_GATT_STATUS_SUCCESS) {
devsar 0:1f985a7c0a8b 474 pc.printf("Error: %s\r\n", "BLE_GATTC_EVT_HVX");
devsar 0:1f985a7c0a8b 475 } else {
devsar 0:1f985a7c0a8b 476
devsar 0:1f985a7c0a8b 477 // Got notification...
devsar 0:1f985a7c0a8b 478 if(p_ble_evt->evt.gattc_evt.params.hvx.handle == m_notification_source_handle) {
devsar 0:1f985a7c0a8b 479 ble_gattc_evt_hvx_t *p_hvx = &p_ble_evt->evt.gattc_evt.params.hvx;
devsar 0:1f985a7c0a8b 480 if(p_hvx->len == 8) {
devsar 0:1f985a7c0a8b 481 pc.printf("Event ID: %x (%s)\r\n", p_hvx->data[0], eventid2string(p_hvx->data[0]));
devsar 0:1f985a7c0a8b 482 pc.printf("Event Flags: %x (%s)\r\n", p_hvx->data[1], eventflags2string(p_hvx->data[1]));
devsar 0:1f985a7c0a8b 483 pc.printf("Category ID: %x (%s)\r\n", p_hvx->data[2], categoryid2string(p_hvx->data[2]));
devsar 0:1f985a7c0a8b 484 pc.printf("Category Count: %x\r\n", p_hvx->data[3]);
devsar 0:1f985a7c0a8b 485 pc.printf("Notification ID: %x %x %x %x\r\n", p_hvx->data[4], p_hvx->data[5], p_hvx->data[6], p_hvx->data[7]);
devsar 0:1f985a7c0a8b 486
devsar 0:1f985a7c0a8b 487 // if we are still processing, we can not do another write
devsar 0:1f985a7c0a8b 488 // with soft device (limitation?). Real implementation should use
devsar 0:1f985a7c0a8b 489 // queue to synchronized operation. Since this is a POC... just ignore.
devsar 0:1f985a7c0a8b 490 if(m_state == STATE_NOTIFIED) {
devsar 0:1f985a7c0a8b 491 pc.printf("Still retrieving data for another notification. ignoring this one.\r\n");
devsar 0:1f985a7c0a8b 492 } else if(p_hvx->data[0] == 0) {
devsar 0:1f985a7c0a8b 493 // we only retrieved data for added notification.
devsar 0:1f985a7c0a8b 494 m_state = STATE_NOTIFIED;
devsar 0:1f985a7c0a8b 495 // write control point to get another data.
devsar 0:1f985a7c0a8b 496
devsar 0:1f985a7c0a8b 497 // We only retrieve the title, with 16 bytes buffer... see ANCS spec for more
devsar 0:1f985a7c0a8b 498 static ble_gattc_write_params_t m_write_params;
devsar 0:1f985a7c0a8b 499 uint8_t gattc_value[8];
devsar 0:1f985a7c0a8b 500
devsar 0:1f985a7c0a8b 501 gattc_value[0] = 0; // CommandIDGetNotificationAttributes
devsar 0:1f985a7c0a8b 502 gattc_value[1] = p_hvx->data[4];
devsar 0:1f985a7c0a8b 503 gattc_value[2] = p_hvx->data[5];
devsar 0:1f985a7c0a8b 504 gattc_value[3] = p_hvx->data[6];
devsar 0:1f985a7c0a8b 505 gattc_value[4] = p_hvx->data[7];
devsar 0:1f985a7c0a8b 506 gattc_value[5] = 1; // Title
devsar 0:1f985a7c0a8b 507 gattc_value[6] = 16; // Length, 2 bytes, MSB first.
devsar 0:1f985a7c0a8b 508 gattc_value[7] = 0;
devsar 0:1f985a7c0a8b 509
devsar 0:1f985a7c0a8b 510 m_write_params.handle = m_control_point_handle;
devsar 0:1f985a7c0a8b 511 m_write_params.len = 8;
devsar 0:1f985a7c0a8b 512 m_write_params.p_value = &gattc_value[0];
devsar 0:1f985a7c0a8b 513 m_write_params.offset = 0;
devsar 0:1f985a7c0a8b 514 m_write_params.write_op = BLE_GATT_OP_WRITE_REQ;
devsar 0:1f985a7c0a8b 515
devsar 0:1f985a7c0a8b 516 err_code = sd_ble_gattc_write(m_conn_handle, &m_write_params);
devsar 0:1f985a7c0a8b 517 err_check(err_code, "sd_ble_gattc_write");
devsar 0:1f985a7c0a8b 518
devsar 0:1f985a7c0a8b 519 }
devsar 0:1f985a7c0a8b 520
devsar 0:1f985a7c0a8b 521 } else {
devsar 0:1f985a7c0a8b 522 pc.printf("NS data len not 8\r\n");
devsar 0:1f985a7c0a8b 523 }
devsar 0:1f985a7c0a8b 524 }
devsar 0:1f985a7c0a8b 525
devsar 0:1f985a7c0a8b 526 // Got data
devsar 0:1f985a7c0a8b 527 if(p_ble_evt->evt.gattc_evt.params.hvx.handle == m_data_source_handle) {
devsar 0:1f985a7c0a8b 528 ble_gattc_evt_hvx_t *p_hvx = &p_ble_evt->evt.gattc_evt.params.hvx;
devsar 0:1f985a7c0a8b 529 pc.printf("Title:");
devsar 0:1f985a7c0a8b 530 // we only set size on MSB...
devsar 0:1f985a7c0a8b 531 uint16_t len = p_hvx->data[6];
devsar 0:1f985a7c0a8b 532 pc.printf("(%d)", len);
devsar 0:1f985a7c0a8b 533
devsar 0:1f985a7c0a8b 534 // the data itself start from index 8 to 8+len;
devsar 0:1f985a7c0a8b 535 uint16_t pos;
devsar 0:1f985a7c0a8b 536 for(pos=8; pos<=8+len; pos++) {
devsar 0:1f985a7c0a8b 537 pc.printf("%c", p_hvx->data[pos]);
devsar 0:1f985a7c0a8b 538 }
devsar 0:1f985a7c0a8b 539 pc.printf("\r\n");
devsar 0:1f985a7c0a8b 540
devsar 0:1f985a7c0a8b 541 // Back to listening...
devsar 0:1f985a7c0a8b 542 m_state = STATE_LISTENING;
devsar 0:1f985a7c0a8b 543 }
devsar 0:1f985a7c0a8b 544
devsar 0:1f985a7c0a8b 545 }
devsar 0:1f985a7c0a8b 546 break;
devsar 0:1f985a7c0a8b 547 }
devsar 0:1f985a7c0a8b 548 case BLE_GATTC_EVT_TIMEOUT:
devsar 0:1f985a7c0a8b 549 case BLE_GATTS_EVT_TIMEOUT:
devsar 0:1f985a7c0a8b 550 {
devsar 0:1f985a7c0a8b 551 // Disconnect on GATT Server and Client timeout events.
devsar 0:1f985a7c0a8b 552 err_code = sd_ble_gap_disconnect(m_conn_handle,
devsar 0:1f985a7c0a8b 553 BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
devsar 0:1f985a7c0a8b 554 err_check(err_code, "sd_ble_gap_disconnect");
devsar 0:1f985a7c0a8b 555 break;
devsar 0:1f985a7c0a8b 556 }
devsar 0:1f985a7c0a8b 557 default:
devsar 0:1f985a7c0a8b 558 {
devsar 0:1f985a7c0a8b 559 //No implementation needed
devsar 0:1f985a7c0a8b 560 break;
devsar 0:1f985a7c0a8b 561 }
devsar 0:1f985a7c0a8b 562 }
devsar 0:1f985a7c0a8b 563
devsar 0:1f985a7c0a8b 564 }
devsar 0:1f985a7c0a8b 565
devsar 0:1f985a7c0a8b 566
devsar 0:1f985a7c0a8b 567 static void sys_event_handler(uint32_t sys_evt)
devsar 0:1f985a7c0a8b 568 {
devsar 0:1f985a7c0a8b 569 pc.printf("Event: system event\r\n");
devsar 0:1f985a7c0a8b 570 pstorage_sys_event_handler(sys_evt);
devsar 0:1f985a7c0a8b 571 }
devsar 0:1f985a7c0a8b 572
devsar 0:1f985a7c0a8b 573
devsar 0:1f985a7c0a8b 574 static void timers_init(void)
devsar 0:1f985a7c0a8b 575 {
devsar 0:1f985a7c0a8b 576 // Initialize timer module.
devsar 0:1f985a7c0a8b 577 APP_TIMER_INIT(APP_TIMER_PRESCALER, APP_TIMER_MAX_TIMERS, APP_TIMER_OP_QUEUE_SIZE, false);
devsar 0:1f985a7c0a8b 578 }
devsar 0:1f985a7c0a8b 579
devsar 0:1f985a7c0a8b 580
devsar 0:1f985a7c0a8b 581 static void ble_stack_init(void)
devsar 0:1f985a7c0a8b 582 {
devsar 0:1f985a7c0a8b 583 uint32_t err_code;
devsar 0:1f985a7c0a8b 584
devsar 0:1f985a7c0a8b 585 // Initialize the SoftDevice handler module.
devsar 0:1f985a7c0a8b 586 SOFTDEVICE_HANDLER_INIT(NRF_CLOCK_LFCLKSRC_XTAL_20_PPM, false);
devsar 0:1f985a7c0a8b 587
devsar 0:1f985a7c0a8b 588
devsar 0:1f985a7c0a8b 589 // Register with the SoftDevice handler module for BLE events.
devsar 0:1f985a7c0a8b 590 err_code = softdevice_ble_evt_handler_set(ble_event_handler);
devsar 0:1f985a7c0a8b 591 err_check(err_code, "softdevice_ble_evt_handler_set");
devsar 0:1f985a7c0a8b 592
devsar 0:1f985a7c0a8b 593 // Register with the SoftDevice handler module for System events.
devsar 0:1f985a7c0a8b 594 err_code = softdevice_sys_evt_handler_set(sys_event_handler);
devsar 0:1f985a7c0a8b 595 err_check(err_code, "softdevice_sys_evt_handler_set");
devsar 0:1f985a7c0a8b 596 }
devsar 0:1f985a7c0a8b 597
devsar 0:1f985a7c0a8b 598 static void set_128_uuid()
devsar 0:1f985a7c0a8b 599 {
devsar 0:1f985a7c0a8b 600 uint32_t err_code;
devsar 0:1f985a7c0a8b 601 uint8_t temp_type; // All ANCS is vendor type... so we ignore this.
devsar 0:1f985a7c0a8b 602
devsar 0:1f985a7c0a8b 603
devsar 0:1f985a7c0a8b 604 err_code = sd_ble_uuid_vs_add(&ble_ancs_base_uuid128, &temp_type);
devsar 0:1f985a7c0a8b 605 err_check(err_code, "sd_ble_uuid_vs_add");
devsar 0:1f985a7c0a8b 606
devsar 0:1f985a7c0a8b 607 err_code = sd_ble_uuid_vs_add(&ble_ancs_cp_base_uuid128, &temp_type);
devsar 0:1f985a7c0a8b 608 err_check(err_code, "sd_ble_uuid_vs_add");
devsar 0:1f985a7c0a8b 609
devsar 0:1f985a7c0a8b 610 err_code = sd_ble_uuid_vs_add(&ble_ancs_ns_base_uuid128, &temp_type);
devsar 0:1f985a7c0a8b 611 err_check(err_code, "sd_ble_uuid_vs_add");
devsar 0:1f985a7c0a8b 612
devsar 0:1f985a7c0a8b 613 err_code = sd_ble_uuid_vs_add(&ble_ancs_ds_base_uuid128, &temp_type);
devsar 0:1f985a7c0a8b 614 err_check(err_code, "sd_ble_uuid_vs_add");
devsar 0:1f985a7c0a8b 615 }
devsar 0:1f985a7c0a8b 616
devsar 0:1f985a7c0a8b 617
devsar 0:1f985a7c0a8b 618 static void conn_params_error_handler(uint32_t nrf_error)
devsar 0:1f985a7c0a8b 619 {
devsar 0:1f985a7c0a8b 620 err_check(nrf_error, "Error: conn params error");
devsar 0:1f985a7c0a8b 621 }
devsar 0:1f985a7c0a8b 622
devsar 0:1f985a7c0a8b 623
devsar 0:1f985a7c0a8b 624 static void conn_params_init(void)
devsar 0:1f985a7c0a8b 625 {
devsar 0:1f985a7c0a8b 626 uint32_t err_code;
devsar 0:1f985a7c0a8b 627 ble_conn_params_init_t cp_init;
devsar 0:1f985a7c0a8b 628
devsar 0:1f985a7c0a8b 629 memset(&cp_init, 0, sizeof(cp_init));
devsar 0:1f985a7c0a8b 630
devsar 0:1f985a7c0a8b 631 cp_init.p_conn_params = NULL;
devsar 0:1f985a7c0a8b 632 cp_init.first_conn_params_update_delay = FIRST_CONN_PARAMS_UPDATE_DELAY;
devsar 0:1f985a7c0a8b 633 cp_init.next_conn_params_update_delay = NEXT_CONN_PARAMS_UPDATE_DELAY;
devsar 0:1f985a7c0a8b 634 cp_init.max_conn_params_update_count = MAX_CONN_PARAMS_UPDATE_COUNT;
devsar 0:1f985a7c0a8b 635 cp_init.start_on_notify_cccd_handle = BLE_GATT_HANDLE_INVALID;
devsar 0:1f985a7c0a8b 636 cp_init.disconnect_on_fail = true;
devsar 0:1f985a7c0a8b 637 cp_init.evt_handler = NULL;
devsar 0:1f985a7c0a8b 638 cp_init.error_handler = conn_params_error_handler;
devsar 0:1f985a7c0a8b 639
devsar 0:1f985a7c0a8b 640 err_code = ble_conn_params_init(&cp_init);
devsar 0:1f985a7c0a8b 641 err_check(err_code, "ble_conn_params_init");
devsar 0:1f985a7c0a8b 642 }
devsar 0:1f985a7c0a8b 643
devsar 0:1f985a7c0a8b 644
devsar 0:1f985a7c0a8b 645 static void sec_params_init(void)
devsar 0:1f985a7c0a8b 646 {
devsar 0:1f985a7c0a8b 647 m_sec_params.timeout = SEC_PARAM_TIMEOUT;
devsar 0:1f985a7c0a8b 648 m_sec_params.bond = SEC_PARAM_BOND;
devsar 0:1f985a7c0a8b 649 m_sec_params.mitm = SEC_PARAM_MITM;
devsar 0:1f985a7c0a8b 650 m_sec_params.io_caps = SEC_PARAM_IO_CAPABILITIES;
devsar 0:1f985a7c0a8b 651 m_sec_params.oob = SEC_PARAM_OOB;
devsar 0:1f985a7c0a8b 652 m_sec_params.min_key_size = SEC_PARAM_MIN_KEY_SIZE;
devsar 0:1f985a7c0a8b 653 m_sec_params.max_key_size = SEC_PARAM_MAX_KEY_SIZE;
devsar 0:1f985a7c0a8b 654 }
devsar 0:1f985a7c0a8b 655
devsar 0:1f985a7c0a8b 656
devsar 0:1f985a7c0a8b 657 static void gap_params_init(void)
devsar 0:1f985a7c0a8b 658 {
devsar 0:1f985a7c0a8b 659 uint32_t err_code;
devsar 0:1f985a7c0a8b 660 ble_gap_conn_params_t gap_conn_params;
devsar 0:1f985a7c0a8b 661 ble_gap_conn_sec_mode_t sec_mode;
devsar 0:1f985a7c0a8b 662
devsar 0:1f985a7c0a8b 663 BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode);
devsar 0:1f985a7c0a8b 664
devsar 0:1f985a7c0a8b 665 err_code = sd_ble_gap_device_name_set(&sec_mode,
devsar 0:1f985a7c0a8b 666 (const uint8_t *)DEVICE_NAME,
devsar 0:1f985a7c0a8b 667 strlen(DEVICE_NAME));
devsar 0:1f985a7c0a8b 668 err_check(err_code, "sd_ble_gap_device_name_set");
devsar 0:1f985a7c0a8b 669
devsar 0:1f985a7c0a8b 670 memset(&gap_conn_params, 0, sizeof(gap_conn_params));
devsar 0:1f985a7c0a8b 671
devsar 0:1f985a7c0a8b 672 gap_conn_params.min_conn_interval = MIN_CONN_INTERVAL;
devsar 0:1f985a7c0a8b 673 gap_conn_params.max_conn_interval = MAX_CONN_INTERVAL;
devsar 0:1f985a7c0a8b 674 gap_conn_params.slave_latency = SLAVE_LATENCY;
devsar 0:1f985a7c0a8b 675 gap_conn_params.conn_sup_timeout = CONN_SUP_TIMEOUT;
devsar 0:1f985a7c0a8b 676
devsar 0:1f985a7c0a8b 677 err_code = sd_ble_gap_ppcp_set(&gap_conn_params);
devsar 0:1f985a7c0a8b 678 err_check(err_code, "sd_ble_gap_ppcp_set");
devsar 0:1f985a7c0a8b 679 }
devsar 0:1f985a7c0a8b 680
devsar 0:1f985a7c0a8b 681
devsar 0:1f985a7c0a8b 682 static void advertising_init(void)
devsar 0:1f985a7c0a8b 683 {
devsar 0:1f985a7c0a8b 684 uint32_t err_code;
devsar 0:1f985a7c0a8b 685 ble_advdata_t advdata;
devsar 0:1f985a7c0a8b 686 uint8_t flags = BLE_GAP_ADV_FLAGS_LE_ONLY_LIMITED_DISC_MODE;
devsar 0:1f985a7c0a8b 687 ble_uuid_t ancs_uuid;
devsar 0:1f985a7c0a8b 688
devsar 0:1f985a7c0a8b 689 // err_code = sd_ble_uuid_vs_add(&ble_ancs_base_uuid128, &m_ancs_uuid_type);
devsar 0:1f985a7c0a8b 690 // err_check(err_code, "sd_ble_uuid_vs_add");
devsar 0:1f985a7c0a8b 691
devsar 0:1f985a7c0a8b 692 // ancs_uuid.uuid = ((ble_ancs_base_uuid128.uuid128[12]) | (ble_ancs_base_uuid128.uuid128[13] << 8));
devsar 0:1f985a7c0a8b 693 // ancs_uuid.type = m_ancs_uuid_type;
devsar 0:1f985a7c0a8b 694 BLE_UUID_BLE_ASSIGN(ancs_uuid, BLE_UUID_APPLE_NOTIFICATION_CENTER_SERVICE);
devsar 0:1f985a7c0a8b 695 ancs_uuid.type = BLE_UUID_TYPE_VENDOR_BEGIN;
devsar 0:1f985a7c0a8b 696
devsar 0:1f985a7c0a8b 697 // Build and set advertising data.
devsar 0:1f985a7c0a8b 698 memset(&advdata, 0, sizeof(advdata));
devsar 0:1f985a7c0a8b 699
devsar 0:1f985a7c0a8b 700 advdata.name_type = BLE_ADVDATA_FULL_NAME;
devsar 0:1f985a7c0a8b 701 advdata.include_appearance = true;
devsar 0:1f985a7c0a8b 702 advdata.flags.size = sizeof(flags);
devsar 0:1f985a7c0a8b 703 advdata.flags.p_data = &flags;
devsar 0:1f985a7c0a8b 704 advdata.uuids_complete.uuid_cnt = 0;
devsar 0:1f985a7c0a8b 705 advdata.uuids_complete.p_uuids = NULL;
devsar 0:1f985a7c0a8b 706 advdata.uuids_solicited.uuid_cnt = 1;
devsar 0:1f985a7c0a8b 707 advdata.uuids_solicited.p_uuids = &ancs_uuid;
devsar 0:1f985a7c0a8b 708
devsar 0:1f985a7c0a8b 709 err_code = ble_advdata_set(&advdata, NULL);
devsar 0:1f985a7c0a8b 710 err_check(err_code, "ble_advdata_set");
devsar 0:1f985a7c0a8b 711
devsar 0:1f985a7c0a8b 712 }
devsar 0:1f985a7c0a8b 713
devsar 0:1f985a7c0a8b 714
devsar 0:1f985a7c0a8b 715 /**************************************************************************/
devsar 0:1f985a7c0a8b 716 /*!
devsar 0:1f985a7c0a8b 717 @brief Program entry point
devsar 0:1f985a7c0a8b 718 */
devsar 0:1f985a7c0a8b 719 /**************************************************************************/
devsar 0:1f985a7c0a8b 720 int main(void)
devsar 0:1f985a7c0a8b 721 {
devsar 0:1f985a7c0a8b 722 uint32_t err_code;
devsar 0:1f985a7c0a8b 723 // uint32_t soc_event;
devsar 0:1f985a7c0a8b 724 // uint32_t evt_id;
devsar 0:1f985a7c0a8b 725
devsar 0:1f985a7c0a8b 726 pc.printf("Program started\n\r");
devsar 0:1f985a7c0a8b 727
devsar 0:1f985a7c0a8b 728 led_adv = 0;
devsar 0:1f985a7c0a8b 729 led_conn = 0;
devsar 0:1f985a7c0a8b 730
devsar 0:1f985a7c0a8b 731
devsar 0:1f985a7c0a8b 732 pc.printf("timers_init()\r\n");
devsar 0:1f985a7c0a8b 733 timers_init();
devsar 0:1f985a7c0a8b 734
devsar 0:1f985a7c0a8b 735 pc.printf("ble_stack_init()\r\n");
devsar 0:1f985a7c0a8b 736 ble_stack_init();
devsar 0:1f985a7c0a8b 737
devsar 0:1f985a7c0a8b 738 pc.printf("gap_params_init()\r\n");
devsar 0:1f985a7c0a8b 739 gap_params_init();
devsar 0:1f985a7c0a8b 740
devsar 0:1f985a7c0a8b 741 pc.printf("set_128_uuid()\r\n");
devsar 0:1f985a7c0a8b 742 set_128_uuid();
devsar 0:1f985a7c0a8b 743
devsar 0:1f985a7c0a8b 744 pc.printf("advertising_init()\r\n");
devsar 0:1f985a7c0a8b 745 advertising_init();
devsar 0:1f985a7c0a8b 746
devsar 0:1f985a7c0a8b 747
devsar 0:1f985a7c0a8b 748 pc.printf("conn_params_init()\r\n");
devsar 0:1f985a7c0a8b 749 conn_params_init();
devsar 0:1f985a7c0a8b 750
devsar 0:1f985a7c0a8b 751 pc.printf("sec_params_init()\r\n");
devsar 0:1f985a7c0a8b 752 sec_params_init();
devsar 0:1f985a7c0a8b 753
devsar 0:1f985a7c0a8b 754 pc.printf("advertising_start()\r\n");
devsar 0:1f985a7c0a8b 755 advertising_start();
devsar 0:1f985a7c0a8b 756
devsar 0:1f985a7c0a8b 757
devsar 0:1f985a7c0a8b 758 // while(1) { wait(1.0); };
devsar 0:1f985a7c0a8b 759
devsar 0:1f985a7c0a8b 760 for (;;)
devsar 0:1f985a7c0a8b 761 {
devsar 0:1f985a7c0a8b 762 err_code = sd_app_evt_wait();
devsar 0:1f985a7c0a8b 763 err_check(err_code, "sd_app_evt_wait");
devsar 0:1f985a7c0a8b 764
devsar 0:1f985a7c0a8b 765 /*
devsar 0:1f985a7c0a8b 766 do {
devsar 0:1f985a7c0a8b 767 soc_event = sd_evt_get(&evt_id);
devsar 0:1f985a7c0a8b 768 pc.printf("soc_event: %d\r\n", evt_id);
devsar 0:1f985a7c0a8b 769 } while(soc_event != NRF_ERROR_NOT_FOUND);
devsar 0:1f985a7c0a8b 770 */
devsar 0:1f985a7c0a8b 771 }
devsar 0:1f985a7c0a8b 772
devsar 0:1f985a7c0a8b 773 }