changed low freq. clock source to IRC
Dependencies: BLE_API mbed nRF51822_IRC
Fork of BLE_ANCS_SDAPI by
main.cpp
00001 #include <stdbool.h> 00002 #include <stdint.h> 00003 #include <string.h> 00004 00005 #include "mbed.h" 00006 #include "nRF51822n.h" 00007 00008 #include "nordic_common.h" 00009 //#include "nrf.h" 00010 #include "app_error.h" 00011 #include "ble_hci.h" 00012 #include "ble_gap.h" 00013 #include "ble_advdata.h" 00014 #include "ble_error_log.h" 00015 #include "nrf_gpio.h" 00016 #include "ble_srv_common.h" 00017 #include "ble_conn_params.h" 00018 #include "nrf51_bitfields.h" 00019 #include "ble_bondmngr.h" 00020 #include "app_timer.h" 00021 #include "ble_radio_notification.h" 00022 #include "ble_flash.h" 00023 #include "ble_debug_assert_handler.h" 00024 #include "pstorage.h" 00025 #include "nrf_soc.h" 00026 #include "softdevice_handler.h" 00027 00028 #include "debug.h" 00029 00030 00031 #define DEVICE_NAME "ANCC" /**< Name of device. Will be included in the advertising data. */ 00032 #define APP_ADV_INTERVAL 40 /**< The advertising interval (in units of 0.625 ms. This value corresponds to 25 ms). */ 00033 #define APP_ADV_INTERVAL_SLOW 3200 /**< Slow advertising interval (in units of 0.625 ms. This value corresponds to 2 seconds). */ 00034 #define APP_ADV_TIMEOUT_IN_SECONDS 180 /**< The advertising timeout in units of seconds. */ 00035 #define ADV_INTERVAL_FAST_PERIOD 30 /**< The duration of the fast advertising period (in seconds). */ 00036 00037 #define APP_TIMER_PRESCALER 0 /**< Value of the RTC1 PRESCALER register. */ 00038 #define APP_TIMER_MAX_TIMERS 2 /**< Maximum number of simultaneously created timers. */ 00039 #define APP_TIMER_OP_QUEUE_SIZE 4 /**< Size of timer operation queues. */ 00040 00041 #define MIN_CONN_INTERVAL MSEC_TO_UNITS(500, UNIT_1_25_MS) /**< Minimum acceptable connection interval (0.5 seconds). */ 00042 #define MAX_CONN_INTERVAL MSEC_TO_UNITS(1000, UNIT_1_25_MS) /**< Maximum acceptable connection interval (1 second). */ 00043 #define SLAVE_LATENCY 0 /**< Slave latency. */ 00044 #define CONN_SUP_TIMEOUT MSEC_TO_UNITS(4000, UNIT_10_MS) /**< Connection supervisory timeout (4 seconds). */ 00045 00046 #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). */ 00047 #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). */ 00048 #define MAX_CONN_PARAMS_UPDATE_COUNT 3 /**< Number of attempts before giving up the connection parameter negotiation. */ 00049 00050 00051 #define SEC_PARAM_TIMEOUT 30 /**< Timeout for Pairing Request or Security Request (in seconds). */ 00052 #define SEC_PARAM_BOND 0 /**< Perform bonding. */ 00053 #define SEC_PARAM_MITM 0 /**< Man In The Middle protection not required. */ 00054 #define SEC_PARAM_IO_CAPABILITIES BLE_GAP_IO_CAPS_NONE /**< No I/O capabilities. */ 00055 #define SEC_PARAM_OOB 0 /**< Out Of Band data not available. */ 00056 #define SEC_PARAM_MIN_KEY_SIZE 7 /**< Minimum encryption key size. */ 00057 #define SEC_PARAM_MAX_KEY_SIZE 16 /**< Maximum encryption key size. */ 00058 00059 #define BLE_UUID_APPLE_NOTIFICATION_CENTER_SERVICE 0xf431 /*<< ANCS service UUID. */ 00060 #define BLE_UUID_ANCS_CONTROL_POINT_CHAR 0xd8f3 /*<< Control point UUID. */ 00061 #define BLE_UUID_ANCS_NOTIFICATION_SOURCE_CHAR 0x120d /*<< Notification source UUID. */ 00062 #define BLE_UUID_ANCS_DATA_SOURCE_CHAR 0xc6e9 /*<< Data source UUID. */ 00063 00064 #define BLE_CCCD_NOTIFY_BIT_MASK 0x0001 /**< Enable Notification bit. */ 00065 00066 00067 typedef enum 00068 { 00069 BLE_NO_ADVERTISING, /**< No advertising running. */ 00070 BLE_SLOW_ADVERTISING, /**< Slow advertising running. */ 00071 BLE_FAST_ADVERTISING /**< Fast advertising running. */ 00072 } ble_advertising_mode_t; 00073 00074 typedef enum 00075 { 00076 STATE_UNINITIALIZED, // Program start. 00077 STATE_ADVERTISING, // Advertising. See Settings>Bluetooth on iPhone then connect to "ANCC" 00078 STATE_CONNECTED, // iPhone connected to us. 00079 STATE_DISCOVERY_SERVICE, // Searching for ANCS Service. 00080 STATE_DISCOVERY_CHARACTERISTICS, // Searching for ANCS Characteristics. 00081 STATE_PAIRING, // Got all we need. Now pair before subscribe. Should see pairing dialog on iPhone 00082 STATE_SUBSCRIBING, // Subscribe to CCC, for notification. 00083 STATE_LISTENING, // Listening... 00084 STATE_NOTIFIED, // Got notification, now retrieve other info and print log out. back to listening. 00085 STATE_DISCONNECTED, // Disconnected? 00086 STATE_ERROR 00087 } state_t; 00088 00089 00090 00091 DigitalOut led_adv(LED1); 00092 DigitalOut led_conn(LED2); 00093 00094 Serial pc(USBTX, USBRX); 00095 00096 const ble_uuid128_t ble_ancs_base_uuid128 = 00097 { 00098 { 00099 // 7905F431-B5CE-4E99-A40F-4B1E122D00D0 00100 0xd0, 0x00, 0x2d, 0x12, 0x1e, 0x4b, 0x0f, 0xa4, 00101 0x99, 0x4e, 0xce, 0xb5, 0x31, 0xf4, 0x05, 0x79 00102 } 00103 }; 00104 00105 00106 const ble_uuid128_t ble_ancs_cp_base_uuid128 = 00107 { 00108 { 00109 // 69d1d8f3-45e1-49a8-9821-9bbdfdaad9d9 00110 0xd9, 0xd9, 0xaa, 0xfd, 0xbd, 0x9b, 0x21, 0x98, 00111 0xa8, 0x49, 0xe1, 0x45, 0xf3, 0xd8, 0xd1, 0x69 00112 00113 } 00114 }; 00115 00116 const ble_uuid128_t ble_ancs_ns_base_uuid128 = 00117 { 00118 { 00119 // 9FBF120D-6301-42D9-8C58-25E699A21DBD 00120 0xbd, 0x1d, 0xa2, 0x99, 0xe6, 0x25, 0x58, 0x8c, 00121 0xd9, 0x42, 0x01, 0x63, 0x0d, 0x12, 0xbf, 0x9f 00122 00123 } 00124 }; 00125 00126 const ble_uuid128_t ble_ancs_ds_base_uuid128 = 00127 { 00128 { 00129 // 22EAC6E9-24D6-4BB5-BE44-B36ACE7C7BFB 00130 0xfb, 0x7b, 0x7c, 0xce, 0x6a, 0xb3, 0x44, 0xbe, 00131 0xb5, 0x4b, 0xd6, 0x24, 0xe9, 0xc6, 0xea, 0x22 00132 00133 } 00134 }; 00135 00136 static state_t m_state = STATE_UNINITIALIZED; 00137 00138 static ble_gap_adv_params_t m_adv_params; /**< Parameters to be passed to the stack when starting advertising. */ 00139 static ble_advertising_mode_t m_advertising_mode; /**< Variable to keep track of when we are advertising. */ 00140 00141 static ble_gap_sec_params_t m_sec_params; /**< Security requirements for this application. */ 00142 00143 // ANCS Characteristic... 00144 static uint16_t m_notification_source_handle = 0; 00145 static uint16_t m_notification_source_handle_cccd = 0; 00146 static uint16_t m_control_point_handle = 0; 00147 static uint16_t m_data_source_handle = 0; 00148 static uint16_t m_data_source_handle_cccd = 0; 00149 00150 static void err_check(uint32_t error_code, char *method) 00151 { 00152 if(error_code != NRF_SUCCESS) { 00153 pc.printf("ERROR: %d (%s) on %s\r\n", error_code, error2string(error_code), method); 00154 // } else { 00155 // pc.printf("SUCCESS: %s\r\n", method); 00156 } 00157 APP_ERROR_CHECK(error_code); 00158 } 00159 00160 00161 static void advertising_start(void) 00162 { 00163 uint32_t err_code; 00164 00165 if (m_advertising_mode == BLE_NO_ADVERTISING) 00166 { 00167 m_advertising_mode = BLE_FAST_ADVERTISING; 00168 } 00169 else 00170 { 00171 m_advertising_mode = BLE_SLOW_ADVERTISING; 00172 } 00173 00174 memset(&m_adv_params, 0, sizeof(m_adv_params)); 00175 00176 m_adv_params.type = BLE_GAP_ADV_TYPE_ADV_IND; 00177 m_adv_params.p_peer_addr = NULL; // Undirected advertisement. 00178 m_adv_params.fp = BLE_GAP_ADV_FP_ANY; 00179 00180 if (m_advertising_mode == BLE_FAST_ADVERTISING) 00181 { 00182 m_adv_params.interval = APP_ADV_INTERVAL; 00183 m_adv_params.timeout = ADV_INTERVAL_FAST_PERIOD; 00184 } 00185 else 00186 { 00187 m_adv_params.interval = APP_ADV_INTERVAL_SLOW; 00188 m_adv_params.timeout = APP_ADV_TIMEOUT_IN_SECONDS; 00189 } 00190 00191 err_code = sd_ble_gap_adv_start(&m_adv_params); 00192 err_check(err_code, "sd_ble_gap_adv_start"); 00193 00194 led_adv = 1; 00195 m_state = STATE_ADVERTISING; 00196 } 00197 00198 00199 00200 00201 static void ble_event_handler(ble_evt_t * p_ble_evt) 00202 { 00203 uint32_t err_code = NRF_SUCCESS; 00204 static uint16_t m_conn_handle = BLE_CONN_HANDLE_INVALID; 00205 ble_uuid_t ancs_uuid; 00206 static ble_gattc_handle_range_t handle_range; 00207 00208 pc.printf("Event: %s\r\n", event2string(p_ble_evt)); 00209 // ble_bondmngr_on_ble_evt(p_ble_evt); 00210 // ble_conn_params_on_ble_evt(p_ble_evt); 00211 00212 switch (p_ble_evt->header.evt_id) 00213 { 00214 case BLE_GAP_EVT_CONNECTED: 00215 { 00216 m_state = STATE_CONNECTED; 00217 00218 m_advertising_mode = BLE_NO_ADVERTISING; 00219 m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle; 00220 led_conn = 1; 00221 00222 m_state = STATE_DISCOVERY_SERVICE; 00223 00224 BLE_UUID_BLE_ASSIGN(ancs_uuid, BLE_UUID_APPLE_NOTIFICATION_CENTER_SERVICE); 00225 ancs_uuid.type = BLE_UUID_TYPE_VENDOR_BEGIN; 00226 00227 err_code = sd_ble_gattc_primary_services_discover(m_conn_handle, 0x0001, &ancs_uuid); 00228 err_check(err_code, "sd_ble_gattc_primary_services_discover"); 00229 00230 00231 break; 00232 } 00233 case BLE_GAP_EVT_AUTH_STATUS: 00234 { 00235 m_state = STATE_SUBSCRIBING; 00236 00237 // Subscribe to NS 00238 uint16_t cccd_val = true ? BLE_CCCD_NOTIFY_BIT_MASK : 0; 00239 static ble_gattc_write_params_t m_write_params; 00240 uint8_t gattc_value[2]; 00241 00242 gattc_value[0] = LSB(cccd_val); 00243 gattc_value[1] = MSB(cccd_val); 00244 00245 m_write_params.handle = m_notification_source_handle_cccd; 00246 m_write_params.len = 2; 00247 m_write_params.p_value = &gattc_value[0]; 00248 m_write_params.offset = 0; 00249 m_write_params.write_op = BLE_GATT_OP_WRITE_REQ; 00250 00251 00252 err_code = sd_ble_gattc_write(m_conn_handle, &m_write_params); 00253 err_check(err_code, "sd_ble_gattc_write"); 00254 00255 break; 00256 } 00257 case BLE_GAP_EVT_DISCONNECTED: 00258 { 00259 m_conn_handle = BLE_CONN_HANDLE_INVALID; 00260 00261 advertising_start(); 00262 led_conn = 0; 00263 break; 00264 } 00265 case BLE_GAP_EVT_SEC_PARAMS_REQUEST: 00266 { 00267 err_code = sd_ble_gap_sec_params_reply(m_conn_handle, 00268 BLE_GAP_SEC_STATUS_SUCCESS, 00269 &m_sec_params); 00270 err_check(err_code, "sd_ble_gap_sec_params_reply"); 00271 break; 00272 } 00273 case BLE_GAP_EVT_TIMEOUT: 00274 { 00275 if (p_ble_evt->evt.gap_evt.params.timeout.src == BLE_GAP_TIMEOUT_SRC_ADVERTISEMENT) 00276 { 00277 if (m_advertising_mode == BLE_FAST_ADVERTISING) 00278 { 00279 advertising_start(); 00280 } 00281 else 00282 { 00283 err_code = sd_power_system_off(); 00284 } 00285 } 00286 break; 00287 } 00288 case BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP: 00289 { 00290 if (p_ble_evt->evt.gattc_evt.gatt_status != BLE_GATT_STATUS_SUCCESS) { 00291 // Error. 00292 pc.printf("Error: %s\r\n", "BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP"); 00293 } else { 00294 if (p_ble_evt->evt.gattc_evt.params.prim_srvc_disc_rsp.count > 0) { 00295 const ble_gattc_service_t * p_service; 00296 00297 p_service = &(p_ble_evt->evt.gattc_evt.params.prim_srvc_disc_rsp.services[0]); 00298 00299 pc.printf("Found ANCS service, start handle: %d, end handle: %d\r\n", 00300 p_service->handle_range.start_handle, p_service->handle_range.end_handle); 00301 00302 handle_range.start_handle = p_service->handle_range.start_handle; 00303 handle_range.end_handle = p_service->handle_range.end_handle; 00304 00305 err_code = sd_ble_gattc_characteristics_discover(m_conn_handle, &handle_range); 00306 err_check(err_code, "sd_ble_gattc_characteristics_discover"); 00307 00308 m_state = STATE_DISCOVERY_CHARACTERISTICS; 00309 00310 } else { 00311 pc.printf("Error: discovery failure, no ANCS\r\n"); 00312 } 00313 } 00314 00315 break; 00316 } 00317 case BLE_GATTC_EVT_CHAR_DISC_RSP: 00318 { 00319 // End of characteristics searching...no more attribute or no more handle. 00320 // We got error as response, but this is normal for gatt attribute searching. 00321 if (p_ble_evt->evt.gattc_evt.gatt_status == BLE_GATT_STATUS_ATTERR_ATTRIBUTE_NOT_FOUND || 00322 p_ble_evt->evt.gattc_evt.gatt_status == BLE_GATT_STATUS_ATTERR_INVALID_HANDLE) { 00323 00324 if(m_notification_source_handle == 0) { 00325 pc.printf("Error: NS not found.\r\n"); 00326 } else if(m_control_point_handle == 0) { 00327 pc.printf("Error: CP not found.\r\n"); 00328 } else if(m_data_source_handle == 0) { 00329 pc.printf("Error: DS not found.\r\n"); 00330 } 00331 // OK, we got all char handles. Next, find CCC. 00332 else { 00333 // Start with NS CCC 00334 handle_range.start_handle = m_notification_source_handle + 1; 00335 handle_range.end_handle = m_notification_source_handle + 1; 00336 00337 err_code = sd_ble_gattc_descriptors_discover(m_conn_handle, &handle_range); 00338 err_check(err_code, "sd_ble_gattc_descriptors_discover"); 00339 } 00340 00341 } else if (p_ble_evt->evt.gattc_evt.gatt_status != BLE_GATT_STATUS_SUCCESS) { 00342 pc.printf("Error: %s\r\n", "BLE_GATTC_EVT_CHAR_DISC_RSP"); 00343 } else { 00344 uint32_t i; 00345 const ble_gattc_char_t * p_char_resp = NULL; 00346 00347 // Iterate trough the characteristics and find the correct one. 00348 for (i = 0; i < p_ble_evt->evt.gattc_evt.params.char_disc_rsp.count; i++) { 00349 p_char_resp = &(p_ble_evt->evt.gattc_evt.params.char_disc_rsp.chars[i]); 00350 switch (p_char_resp->uuid.uuid) { 00351 case BLE_UUID_ANCS_CONTROL_POINT_CHAR: 00352 pc.printf("Found char: Control Point"); 00353 m_control_point_handle = p_char_resp->handle_value; 00354 break; 00355 00356 case BLE_UUID_ANCS_NOTIFICATION_SOURCE_CHAR: 00357 pc.printf("Found char: Notification Source"); 00358 m_notification_source_handle = p_char_resp->handle_value; 00359 break; 00360 00361 case BLE_UUID_ANCS_DATA_SOURCE_CHAR: 00362 pc.printf("Found char: Data Source"); 00363 m_data_source_handle = p_char_resp->handle_value; 00364 break; 00365 00366 default: 00367 break; 00368 } 00369 } 00370 00371 if(p_char_resp!=NULL) { 00372 00373 handle_range.start_handle = p_char_resp->handle_value + 1; 00374 00375 err_code = sd_ble_gattc_characteristics_discover(m_conn_handle, &handle_range); 00376 err_check(err_code, "sd_ble_gattc_characteristics_discover"); 00377 00378 } else { 00379 err_code = sd_ble_gattc_characteristics_discover(m_conn_handle, &handle_range); 00380 err_check(err_code, "sd_ble_gattc_characteristics_discover"); 00381 } 00382 00383 } 00384 00385 break; 00386 } 00387 case BLE_GATTC_EVT_DESC_DISC_RSP: 00388 { 00389 if (p_ble_evt->evt.gattc_evt.gatt_status != BLE_GATT_STATUS_SUCCESS) { 00390 pc.printf("Error: %s\r\n", "BLE_GATTC_EVT_DESC_DISC_RSP"); 00391 } else { 00392 if (p_ble_evt->evt.gattc_evt.params.desc_disc_rsp.count > 0) { 00393 const ble_gattc_desc_t * p_desc_resp = &(p_ble_evt->evt.gattc_evt.params.desc_disc_rsp.descs[0]); 00394 if (p_desc_resp->uuid.uuid == BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG) { 00395 if(p_desc_resp->handle == m_notification_source_handle + 1) { 00396 00397 m_notification_source_handle_cccd = p_desc_resp->handle; 00398 pc.printf("Found NS CCC\r\n"); 00399 00400 // Next, find CCC for data source. 00401 handle_range.start_handle = m_data_source_handle + 1; 00402 handle_range.end_handle = m_data_source_handle + 1; 00403 00404 err_code = sd_ble_gattc_descriptors_discover(m_conn_handle, &handle_range); 00405 err_check(err_code, "sd_ble_gattc_descriptors_discover"); 00406 00407 } else if(p_desc_resp->handle == m_data_source_handle + 1) { 00408 00409 m_data_source_handle_cccd = p_desc_resp->handle; 00410 pc.printf("Found DS CCC\r\n"); 00411 00412 // Got all we need, now before subscribing we'll do pairing. 00413 // request encryption...., we are in peripheral role. 00414 00415 m_state = STATE_PAIRING; 00416 00417 err_code = sd_ble_gap_authenticate(m_conn_handle, &m_sec_params); 00418 err_check(err_code, "sd_ble_gap_authenticate"); 00419 } 00420 } 00421 } 00422 } 00423 break; 00424 } 00425 case BLE_GATTC_EVT_WRITE_RSP: 00426 { 00427 if (p_ble_evt->evt.gattc_evt.gatt_status != BLE_GATT_STATUS_SUCCESS) { 00428 pc.printf("Error: %s\r\n", "BLE_GATTC_EVT_WRITE_RSP"); 00429 00430 if(p_ble_evt->evt.gattc_evt.params.write_rsp.handle == m_control_point_handle) { 00431 m_state = STATE_LISTENING; 00432 } 00433 } else { 00434 if(p_ble_evt->evt.gattc_evt.params.write_rsp.handle == m_notification_source_handle_cccd) { 00435 pc.printf("NS subscribe success.\r\n"); 00436 00437 // Next, subscribe to DS. 00438 uint16_t cccd_val = true ? BLE_CCCD_NOTIFY_BIT_MASK : 0; 00439 static ble_gattc_write_params_t m_write_params; 00440 uint8_t gattc_value[2]; 00441 00442 gattc_value[0] = LSB(cccd_val); 00443 gattc_value[1] = MSB(cccd_val); 00444 00445 m_write_params.handle = m_data_source_handle_cccd; 00446 m_write_params.len = 2; 00447 m_write_params.p_value = &gattc_value[0]; 00448 m_write_params.offset = 0; 00449 m_write_params.write_op = BLE_GATT_OP_WRITE_REQ; 00450 00451 err_code = sd_ble_gattc_write(m_conn_handle, &m_write_params); 00452 err_check(err_code, "sd_ble_gattc_write"); 00453 } 00454 00455 if(p_ble_evt->evt.gattc_evt.params.write_rsp.handle == m_data_source_handle_cccd) { 00456 pc.printf("DS subscribe success.\r\n"); 00457 00458 // Now, we just waiting for NS notification. 00459 m_state = STATE_LISTENING; 00460 } 00461 00462 if(p_ble_evt->evt.gattc_evt.params.write_rsp.handle == m_control_point_handle) { 00463 pc.printf("CP write success.\r\n"); 00464 // We'll receive data from DS notification 00465 } 00466 00467 } 00468 00469 break; 00470 } 00471 case BLE_GATTC_EVT_HVX: 00472 { 00473 if (p_ble_evt->evt.gattc_evt.gatt_status != BLE_GATT_STATUS_SUCCESS) { 00474 pc.printf("Error: %s\r\n", "BLE_GATTC_EVT_HVX"); 00475 } else { 00476 00477 // Got notification... 00478 if(p_ble_evt->evt.gattc_evt.params.hvx.handle == m_notification_source_handle) { 00479 ble_gattc_evt_hvx_t *p_hvx = &p_ble_evt->evt.gattc_evt.params.hvx; 00480 if(p_hvx->len == 8) { 00481 pc.printf("Event ID: %x (%s)\r\n", p_hvx->data[0], eventid2string(p_hvx->data[0])); 00482 pc.printf("Event Flags: %x (%s)\r\n", p_hvx->data[1], eventflags2string(p_hvx->data[1])); 00483 pc.printf("Category ID: %x (%s)\r\n", p_hvx->data[2], categoryid2string(p_hvx->data[2])); 00484 pc.printf("Category Count: %x\r\n", p_hvx->data[3]); 00485 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]); 00486 00487 // if we are still processing, we can not do another write 00488 // with soft device (limitation?). Real implementation should use 00489 // queue to synchronized operation. Since this is a POC... just ignore. 00490 if(m_state == STATE_NOTIFIED) { 00491 pc.printf("Still retrieving data for another notification. ignoring this one.\r\n"); 00492 } else if(p_hvx->data[0] == 0) { 00493 // we only retrieved data for added notification. 00494 m_state = STATE_NOTIFIED; 00495 // write control point to get another data. 00496 00497 // We only retrieve the title, with 16 bytes buffer... see ANCS spec for more 00498 static ble_gattc_write_params_t m_write_params; 00499 uint8_t gattc_value[8]; 00500 00501 gattc_value[0] = 0; // CommandIDGetNotificationAttributes 00502 gattc_value[1] = p_hvx->data[4]; 00503 gattc_value[2] = p_hvx->data[5]; 00504 gattc_value[3] = p_hvx->data[6]; 00505 gattc_value[4] = p_hvx->data[7]; 00506 gattc_value[5] = 1; // Title 00507 gattc_value[6] = 16; // Length, 2 bytes, MSB first. 00508 gattc_value[7] = 0; 00509 00510 m_write_params.handle = m_control_point_handle; 00511 m_write_params.len = 8; 00512 m_write_params.p_value = &gattc_value[0]; 00513 m_write_params.offset = 0; 00514 m_write_params.write_op = BLE_GATT_OP_WRITE_REQ; 00515 00516 err_code = sd_ble_gattc_write(m_conn_handle, &m_write_params); 00517 err_check(err_code, "sd_ble_gattc_write"); 00518 00519 } 00520 00521 } else { 00522 pc.printf("NS data len not 8\r\n"); 00523 } 00524 } 00525 00526 // Got data 00527 if(p_ble_evt->evt.gattc_evt.params.hvx.handle == m_data_source_handle) { 00528 ble_gattc_evt_hvx_t *p_hvx = &p_ble_evt->evt.gattc_evt.params.hvx; 00529 pc.printf("Title:"); 00530 // we only set size on MSB... 00531 uint16_t len = p_hvx->data[6]; 00532 pc.printf("(%d)", len); 00533 00534 // the data itself start from index 8 to 8+len; 00535 uint16_t pos; 00536 for(pos=8; pos<=8+len; pos++) { 00537 pc.printf("%c", p_hvx->data[pos]); 00538 } 00539 pc.printf("\r\n"); 00540 00541 // Back to listening... 00542 m_state = STATE_LISTENING; 00543 } 00544 00545 } 00546 break; 00547 } 00548 case BLE_GATTC_EVT_TIMEOUT: 00549 case BLE_GATTS_EVT_TIMEOUT: 00550 { 00551 // Disconnect on GATT Server and Client timeout events. 00552 err_code = sd_ble_gap_disconnect(m_conn_handle, 00553 BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION); 00554 err_check(err_code, "sd_ble_gap_disconnect"); 00555 break; 00556 } 00557 default: 00558 { 00559 //No implementation needed 00560 break; 00561 } 00562 } 00563 00564 } 00565 00566 00567 static void sys_event_handler(uint32_t sys_evt) 00568 { 00569 pc.printf("Event: system event\r\n"); 00570 pstorage_sys_event_handler(sys_evt); 00571 } 00572 00573 00574 static void timers_init(void) 00575 { 00576 // Initialize timer module. 00577 APP_TIMER_INIT(APP_TIMER_PRESCALER, APP_TIMER_MAX_TIMERS, APP_TIMER_OP_QUEUE_SIZE, false); 00578 } 00579 00580 00581 static void ble_stack_init(void) 00582 { 00583 uint32_t err_code; 00584 00585 // Initialize the SoftDevice handler module. 00586 // SOFTDEVICE_HANDLER_INIT(NRF_CLOCK_LFCLKSRC_XTAL_20_PPM, false); 00587 SOFTDEVICE_HANDLER_INIT(NRF_CLOCK_LFCLKSRC_RC_250_PPM_4000MS_CALIBRATION, false); 00588 00589 00590 // Register with the SoftDevice handler module for BLE events. 00591 err_code = softdevice_ble_evt_handler_set(ble_event_handler); 00592 err_check(err_code, "softdevice_ble_evt_handler_set"); 00593 00594 // Register with the SoftDevice handler module for System events. 00595 err_code = softdevice_sys_evt_handler_set(sys_event_handler); 00596 err_check(err_code, "softdevice_sys_evt_handler_set"); 00597 } 00598 00599 static void set_128_uuid() 00600 { 00601 uint32_t err_code; 00602 uint8_t temp_type; // All ANCS is vendor type... so we ignore this. 00603 00604 00605 err_code = sd_ble_uuid_vs_add(&ble_ancs_base_uuid128, &temp_type); 00606 err_check(err_code, "sd_ble_uuid_vs_add"); 00607 00608 err_code = sd_ble_uuid_vs_add(&ble_ancs_cp_base_uuid128, &temp_type); 00609 err_check(err_code, "sd_ble_uuid_vs_add"); 00610 00611 err_code = sd_ble_uuid_vs_add(&ble_ancs_ns_base_uuid128, &temp_type); 00612 err_check(err_code, "sd_ble_uuid_vs_add"); 00613 00614 err_code = sd_ble_uuid_vs_add(&ble_ancs_ds_base_uuid128, &temp_type); 00615 err_check(err_code, "sd_ble_uuid_vs_add"); 00616 } 00617 00618 00619 static void conn_params_error_handler(uint32_t nrf_error) 00620 { 00621 err_check(nrf_error, "Error: conn params error"); 00622 } 00623 00624 00625 static void conn_params_init(void) 00626 { 00627 uint32_t err_code; 00628 ble_conn_params_init_t cp_init; 00629 00630 memset(&cp_init, 0, sizeof(cp_init)); 00631 00632 cp_init.p_conn_params = NULL; 00633 cp_init.first_conn_params_update_delay = FIRST_CONN_PARAMS_UPDATE_DELAY; 00634 cp_init.next_conn_params_update_delay = NEXT_CONN_PARAMS_UPDATE_DELAY; 00635 cp_init.max_conn_params_update_count = MAX_CONN_PARAMS_UPDATE_COUNT; 00636 cp_init.start_on_notify_cccd_handle = BLE_GATT_HANDLE_INVALID; 00637 cp_init.disconnect_on_fail = true; 00638 cp_init.evt_handler = NULL; 00639 cp_init.error_handler = conn_params_error_handler; 00640 00641 err_code = ble_conn_params_init(&cp_init); 00642 err_check(err_code, "ble_conn_params_init"); 00643 } 00644 00645 00646 static void sec_params_init(void) 00647 { 00648 m_sec_params.timeout = SEC_PARAM_TIMEOUT; 00649 m_sec_params.bond = SEC_PARAM_BOND; 00650 m_sec_params.mitm = SEC_PARAM_MITM; 00651 m_sec_params.io_caps = SEC_PARAM_IO_CAPABILITIES; 00652 m_sec_params.oob = SEC_PARAM_OOB; 00653 m_sec_params.min_key_size = SEC_PARAM_MIN_KEY_SIZE; 00654 m_sec_params.max_key_size = SEC_PARAM_MAX_KEY_SIZE; 00655 } 00656 00657 00658 static void gap_params_init(void) 00659 { 00660 uint32_t err_code; 00661 ble_gap_conn_params_t gap_conn_params; 00662 ble_gap_conn_sec_mode_t sec_mode; 00663 00664 BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode); 00665 00666 err_code = sd_ble_gap_device_name_set(&sec_mode, 00667 (const uint8_t *)DEVICE_NAME, 00668 strlen(DEVICE_NAME)); 00669 err_check(err_code, "sd_ble_gap_device_name_set"); 00670 00671 memset(&gap_conn_params, 0, sizeof(gap_conn_params)); 00672 00673 gap_conn_params.min_conn_interval = MIN_CONN_INTERVAL; 00674 gap_conn_params.max_conn_interval = MAX_CONN_INTERVAL; 00675 gap_conn_params.slave_latency = SLAVE_LATENCY; 00676 gap_conn_params.conn_sup_timeout = CONN_SUP_TIMEOUT; 00677 00678 err_code = sd_ble_gap_ppcp_set(&gap_conn_params); 00679 err_check(err_code, "sd_ble_gap_ppcp_set"); 00680 } 00681 00682 00683 static void advertising_init(void) 00684 { 00685 uint32_t err_code; 00686 ble_advdata_t advdata; 00687 uint8_t flags = BLE_GAP_ADV_FLAGS_LE_ONLY_LIMITED_DISC_MODE; 00688 ble_uuid_t ancs_uuid; 00689 00690 // err_code = sd_ble_uuid_vs_add(&ble_ancs_base_uuid128, &m_ancs_uuid_type); 00691 // err_check(err_code, "sd_ble_uuid_vs_add"); 00692 00693 // ancs_uuid.uuid = ((ble_ancs_base_uuid128.uuid128[12]) | (ble_ancs_base_uuid128.uuid128[13] << 8)); 00694 // ancs_uuid.type = m_ancs_uuid_type; 00695 BLE_UUID_BLE_ASSIGN(ancs_uuid, BLE_UUID_APPLE_NOTIFICATION_CENTER_SERVICE); 00696 ancs_uuid.type = BLE_UUID_TYPE_VENDOR_BEGIN; 00697 00698 // Build and set advertising data. 00699 memset(&advdata, 0, sizeof(advdata)); 00700 00701 advdata.name_type = BLE_ADVDATA_FULL_NAME; 00702 advdata.include_appearance = true; 00703 advdata.flags.size = sizeof(flags); 00704 advdata.flags.p_data = &flags; 00705 advdata.uuids_complete.uuid_cnt = 0; 00706 advdata.uuids_complete.p_uuids = NULL; 00707 advdata.uuids_solicited.uuid_cnt = 1; 00708 advdata.uuids_solicited.p_uuids = &ancs_uuid; 00709 00710 err_code = ble_advdata_set(&advdata, NULL); 00711 err_check(err_code, "ble_advdata_set"); 00712 00713 } 00714 00715 00716 /**************************************************************************/ 00717 /*! 00718 @brief Program entry point 00719 */ 00720 /**************************************************************************/ 00721 int main(void) 00722 { 00723 uint32_t err_code; 00724 // uint32_t soc_event; 00725 // uint32_t evt_id; 00726 00727 pc.printf("Program started\n\r"); 00728 00729 led_adv = 0; 00730 led_conn = 0; 00731 00732 00733 pc.printf("timers_init()\r\n"); 00734 timers_init(); 00735 00736 pc.printf("ble_stack_init()\r\n"); 00737 ble_stack_init(); 00738 00739 /* Make sure we get a clean start */ 00740 wait(0.5); 00741 wait(1); 00742 00743 pc.printf("gap_params_init()\r\n"); 00744 gap_params_init(); 00745 00746 pc.printf("set_128_uuid()\r\n"); 00747 set_128_uuid(); 00748 00749 pc.printf("advertising_init()\r\n"); 00750 advertising_init(); 00751 00752 00753 pc.printf("conn_params_init()\r\n"); 00754 conn_params_init(); 00755 00756 pc.printf("sec_params_init()\r\n"); 00757 sec_params_init(); 00758 00759 pc.printf("advertising_start()\r\n"); 00760 advertising_start(); 00761 00762 00763 // while(1) { wait(1.0); }; 00764 00765 for (;;) 00766 { 00767 err_code = sd_app_evt_wait(); 00768 err_check(err_code, "sd_app_evt_wait"); 00769 00770 /* 00771 do { 00772 soc_event = sd_evt_get(&evt_id); 00773 pc.printf("soc_event: %d\r\n", evt_id); 00774 } while(soc_event != NRF_ERROR_NOT_FOUND); 00775 */ 00776 } 00777 00778 }
Generated on Tue Jul 12 2022 21:16:00 by 1.7.2