/**@brief Function for handling IAS Client events. * * @details This function will be called for all IAS Client events which are passed to the * application. * * @param[in] p_ias_c IAS Client structure. * @param[in] p_evt Event received. */ static void on_ias_c_evt(ble_ias_c_t * p_ias_c, ble_ias_c_evt_t * p_evt) { uint32_t err_code; switch (p_evt->evt_type) { case BLE_IAS_C_EVT_SRV_DISCOVERED: // IAS is found on peer. The Find Me Locator functionality of this app will work. // Start handling button presses err_code = bsp_buttons_enable( (1 << SIGNAL_ALERT_BUTTON_ID) | ( 1 << STOP_ALERTING_BUTTON_ID)); APP_ERROR_CHECK(err_code); break; case BLE_IAS_C_EVT_SRV_NOT_FOUND: // IAS is not found on peer. The Find Me Locator functionality of this app will NOT work. break; case BLE_IAS_C_EVT_DISCONN_COMPLETE: // Disable alert buttons err_code = bsp_buttons_enable(BSP_BUTTONS_NONE); APP_ERROR_CHECK(err_code); break; default: break; } }
/**@brief Application main function. */ int main(void) { //printf("main"); uint8_t start_string[] = START_STRING; uint32_t err_code; // Initialize. APP_TIMER_INIT(APP_TIMER_PRESCALER, APP_TIMER_MAX_TIMERS, APP_TIMER_OP_QUEUE_SIZE, false); APP_GPIOTE_INIT(APP_GPIOTE_MAX_USERS); ble_stack_init(); //uart_init(); err_code = bsp_init(BSP_INIT_LED | BSP_INIT_BUTTONS, APP_TIMER_TICKS(100, APP_TIMER_PRESCALER), NULL); APP_ERROR_CHECK(err_code); err_code = bsp_buttons_enable(1 << WAKEUP_BUTTON_ID); APP_ERROR_CHECK(err_code); gap_params_init(); services_init(); advertising_init(); conn_params_init(); sec_params_init(); printf("%s",start_string); advertising_start(); init_leds(); for (;;) { power_manage(); } }
/**@brief Thread for handling the Application's BLE Stack events. * * @details This thread is responsible for handling BLE Stack events sended from on_ble_evt(). * * @param[in] arg Pointer used for passing some arbitrary information (context) from the * osThreadCreate() call to the thread. */ void ble_stack_thread(void const * arg) { uint32_t err_code; osEvent evt; ble_evt_t * p_ble_evt; UNUSED_PARAMETER(arg); while (1) { evt = osMessageGet(ble_stack_msg_box, osWaitForever); // wait for message if (evt.status == osEventMessage) { p_ble_evt = evt.value.p; switch (p_ble_evt->header.evt_id) { case BLE_GAP_EVT_CONNECTED: err_code = bsp_indication_set(BSP_INDICATE_CONNECTED); APP_ERROR_CHECK(err_code); m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle; break; case BLE_GAP_EVT_DISCONNECTED: err_code = bsp_indication_set(BSP_INDICATE_IDLE); APP_ERROR_CHECK(err_code); advertising_start(); break; case BLE_GAP_EVT_TIMEOUT: if (p_ble_evt->evt.gap_evt.params.timeout.src == BLE_GAP_TIMEOUT_SRC_ADVERTISING) { err_code = bsp_indication_set(BSP_INDICATE_IDLE); APP_ERROR_CHECK(err_code); // enable buttons to wake-up from power off bsp_buttons_enable( (1 << WAKEUP_BUTTON_ID) | (1 << BOND_DELETE_ALL_BUTTON_ID) ); // Go to system-off mode (this function will not return; wakeup will cause a reset). err_code = sd_power_system_off(); APP_ERROR_CHECK(err_code); } break; default: // No implementation needed. break; } (void)osPoolFree(ble_evt_pool, p_ble_evt); } } }
/**@brief Function for initializing the button handler module. */ static void buttons_init(void) { uint32_t err_code; // Note: Before start using buttons, assign events to buttons, as shown below. // err_code = bsp_event_to_button_assign(BUTTON_0_ID, BSP_EVENT_KEY_0); // APP_ERROR_CHECK(err_code); // Note: Enable buttons which you want to use. // err_code = bsp_buttons_enable((1 << WAKEUP_BUTTON_ID) | (1 << BUTTON_0_ID)); // APP_ERROR_CHECK(err_code); // Note: If the only use of buttons is to wake up, the bsp module can be omitted, and // the wakeup button can be configured by err_code = bsp_buttons_enable(1 << WAKEUP_BUTTON_ID); APP_ERROR_CHECK(err_code); }
/**@brief Function for handling the Application's BLE Stack events. * * @param[in] p_ble_evt Bluetooth stack event. */ static void on_ble_evt(ble_evt_t * p_ble_evt) { uint32_t err_code; switch (p_ble_evt->header.evt_id) { case BLE_GAP_EVT_CONNECTED: err_code = bsp_indication_set(BSP_INDICATE_CONNECTED); APP_ERROR_CHECK(err_code); m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle; break; case BLE_GAP_EVT_DISCONNECTED: err_code = bsp_indication_set(BSP_INDICATE_IDLE); APP_ERROR_CHECK(err_code); err_code = bsp_indication_set(BSP_INDICATE_ALERT_OFF); APP_ERROR_CHECK(err_code); advertising_start(); break; case BLE_GAP_EVT_TIMEOUT: if (p_ble_evt->evt.gap_evt.params.timeout.src == BLE_GAP_TIMEOUT_SRC_ADVERTISING) { err_code = bsp_indication_set(BSP_INDICATE_IDLE); APP_ERROR_CHECK(err_code); err_code = bsp_indication_set(BSP_INDICATE_ALERT_OFF); APP_ERROR_CHECK(err_code); err_code = bsp_buttons_enable(( 1 << WAKEUP_BUTTON_ID)); APP_ERROR_CHECK(err_code); // Go to system-off mode (this function will not return; wakeup will cause a reset). err_code = sd_power_system_off(); APP_ERROR_CHECK(err_code); } break; default: // No implementation needed. break; } }
static void bsp_configuration() { // Start oscillator for app_timer NRF_CLOCK->LFCLKSRC = (CLOCK_LFCLKSRC_SRC_Xtal << CLOCK_LFCLKSRC_SRC_Pos); NRF_CLOCK->EVENTS_LFCLKSTARTED = 0; NRF_CLOCK->TASKS_LFCLKSTART = 1; while (NRF_CLOCK->EVENTS_LFCLKSTARTED == 0) { // Do nothing. } APP_TIMER_INIT(APP_TIMER_PRESCALER, APP_TIMER_MAX_TIMERS, APP_TIMER_OP_QUEUE_SIZE, false); APP_GPIOTE_INIT(1); uint32_t err_code; err_code = bsp_init(BSP_INIT_BUTTONS, APP_TIMER_TICKS(100, APP_TIMER_PRESCALER), bsp_evt_handler); err_code = bsp_buttons_enable( (1 << BUTTON_PREV_ID) | (1 << BUTTON_NEXT_ID) ); APP_ERROR_CHECK(err_code); }
/** * @brief Function for main application entry. */ int main(void) { uint32_t err_code = NRF_SUCCESS; //BSP configuration for button support: button pushing will feed the dog. err_code = nrf_drv_clock_init(NULL); APP_ERROR_CHECK(err_code); nrf_drv_clock_lfclk_request(); APP_TIMER_INIT(APP_TIMER_PRESCALER, APP_TIMER_MAX_TIMERS, APP_TIMER_OP_QUEUE_SIZE, false); err_code = bsp_init(BSP_INIT_BUTTONS, APP_TIMER_TICKS(100, APP_TIMER_PRESCALER), bsp_event_callback); APP_ERROR_CHECK(err_code); //Configure all LEDs on board. LEDS_CONFIGURE(LEDS_MASK); LEDS_OFF(LEDS_MASK); //Indicate program start on LEDs. for(uint32_t i = 0; i < LEDS_NUMBER; i++) { nrf_delay_ms(200); LEDS_ON(BSP_LED_0_MASK << i); } err_code = bsp_buttons_enable(); APP_ERROR_CHECK(err_code); //Configure WDT. nrf_drv_wdt_config_t config = NRF_DRV_WDT_DEAFULT_CONFIG; err_code = nrf_drv_wdt_init(&config, wdt_event_handler); APP_ERROR_CHECK(err_code); err_code = nrf_drv_wdt_channel_alloc(&m_channel_id); APP_ERROR_CHECK(err_code); nrf_drv_wdt_enable(); while(1) { __SEV(); __WFE(); __WFE(); } }
/**@brief Function for handling IAS Client events. * * @details This function will be called for all IAS Client events which are passed to the * application. * * @param[in] p_ias_c IAS Client structure. * @param[in] p_evt Event received. */ static void on_ias_c_evt(ble_ias_c_t * p_ias_c, ble_ias_c_evt_t * p_evt) { uint32_t err_code; switch (p_evt->evt_type) { case BLE_IAS_C_EVT_SRV_DISCOVERED: // IAS is found on peer. The Find Me Locator functionality of this app will work. break; case BLE_IAS_C_EVT_SRV_NOT_FOUND: // IAS is not found on peer. The Find Me Locator functionality of this app will NOT work. break; case BLE_IAS_C_EVT_DISCONN_COMPLETE: // Stop detecting button presses when not connected err_code = bsp_buttons_enable(BSP_BUTTONS_NONE); APP_ERROR_CHECK(err_code); break; default: break; } }
/**@brief Function for handling the Application's BLE Stack events. * * @param[in] p_ble_evt Bluetooth stack event. */ static void on_ble_evt(ble_evt_t * p_ble_evt) { uint32_t err_code = NRF_SUCCESS; static uint16_t m_conn_handle = BLE_CONN_HANDLE_INVALID; switch (p_ble_evt->header.evt_id) { case BLE_GAP_EVT_CONNECTED: err_code = bsp_indication_set(BSP_INDICATE_CONNECTED); APP_ERROR_CHECK(err_code); err_code = bsp_buttons_enable((1<<DISPLAY_MESSAGE_BUTTON_ID)); APP_ERROR_CHECK(err_code); m_advertising_mode = BLE_NO_ADVERTISING; m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle; break; case BLE_GAP_EVT_AUTH_STATUS: apple_notification_setup(); break; case BLE_GAP_EVT_DISCONNECTED: err_code = bsp_indication_set(BSP_INDICATE_IDLE); APP_ERROR_CHECK(err_code); m_conn_handle = BLE_CONN_HANDLE_INVALID; // Stop detecting button presses when not connected. err_code = bsp_buttons_enable(BSP_BUTTONS_NONE); APP_ERROR_CHECK(err_code); err_code = ble_ans_c_service_store(); APP_ERROR_CHECK(err_code); advertising_start(); break; case BLE_GAP_EVT_TIMEOUT: if (p_ble_evt->evt.gap_evt.params.timeout.src == BLE_GAP_TIMEOUT_SRC_ADVERTISEMENT) { if (m_advertising_mode == BLE_FAST_ADVERTISING) { advertising_start(); } else { err_code = bsp_indication_set(BSP_INDICATE_IDLE); APP_ERROR_CHECK(err_code); m_advertising_mode = BLE_NO_ADVERTISING; err_code = bsp_buttons_enable( (1 << BOND_DELETE_ALL_WAKEUP_BUTTON_ID) ); APP_ERROR_CHECK(err_code); // Go to system-off mode (function will not return; wakeup will cause a reset). err_code = sd_power_system_off(); APP_ERROR_CHECK(err_code); } } break; case BLE_GATTC_EVT_TIMEOUT: case BLE_GATTS_EVT_TIMEOUT: // Disconnect on GATT Server and Client timeout events. err_code = sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION); APP_ERROR_CHECK(err_code); break; default: // No implementation needed. break; } APP_ERROR_CHECK(err_code); }
/**@brief Function for the Application's S110 SoftDevice event handler. * * @param[in] p_ble_evt S110 SoftDevice event. */ static void on_ble_evt(ble_evt_t * p_ble_evt) { uint32_t err_code; static ble_gap_sec_keyset_t s_sec_keyset; ble_gap_enc_info_t * p_enc_info; switch (p_ble_evt->header.evt_id) { case BLE_GAP_EVT_CONNECTED: err_code = bsp_indication_set(BSP_INDICATE_CONNECTED); APP_ERROR_CHECK(err_code); m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle; break; case BLE_GAP_EVT_DISCONNECTED: err_code = bsp_indication_set(BSP_INDICATE_IDLE); APP_ERROR_CHECK(err_code); m_conn_handle = BLE_CONN_HANDLE_INVALID; advertising_start(); break; case BLE_GAP_EVT_SEC_PARAMS_REQUEST: s_sec_keyset.keys_periph.p_enc_key = NULL; err_code = sd_ble_gap_sec_params_reply(m_conn_handle, BLE_GAP_SEC_STATUS_SUCCESS, &m_sec_params, &s_sec_keyset); APP_ERROR_CHECK(err_code); break; case BLE_GATTS_EVT_SYS_ATTR_MISSING: err_code = sd_ble_gatts_sys_attr_set(m_conn_handle, NULL, 0, 0); APP_ERROR_CHECK(err_code); break; case BLE_GAP_EVT_AUTH_STATUS: // TODO: Adoptation to s110v8.0.0, is this needed anymore ? break; case BLE_GAP_EVT_SEC_INFO_REQUEST: if (s_sec_keyset.keys_periph.p_enc_key != NULL) { p_enc_info = &s_sec_keyset.keys_periph.p_enc_key->enc_info; err_code = sd_ble_gap_sec_info_reply(m_conn_handle, p_enc_info, NULL, NULL); APP_ERROR_CHECK(err_code); } else { // No keys found for this device. err_code = sd_ble_gap_sec_info_reply(m_conn_handle, NULL, NULL, NULL); APP_ERROR_CHECK(err_code); } break; case BLE_GAP_EVT_TIMEOUT: if (p_ble_evt->evt.gap_evt.params.timeout.src == BLE_GAP_TIMEOUT_SRC_ADVERTISING) { err_code = bsp_indication_set(BSP_INDICATE_IDLE); APP_ERROR_CHECK(err_code); // Configure buttons with sense level low as wakeup source. err_code = bsp_buttons_enable(1 << WAKEUP_BUTTON_ID); APP_ERROR_CHECK(err_code); // Go to system-off mode (this function will not return; wakeup will cause a reset). err_code = sd_power_system_off(); APP_ERROR_CHECK(err_code); } break; default: // No implementation needed. break; } }
/**@brief Function for handling the Application's BLE Stack events. * * @param[in] p_ble_evt Bluetooth stack event. */ static void on_ble_evt(ble_evt_t * p_ble_evt) { uint32_t err_code; static ble_gap_evt_auth_status_t m_auth_status; bool master_id_matches; ble_gap_sec_kdist_t * p_distributed_keys; ble_gap_enc_info_t * p_enc_info; ble_gap_irk_t * p_id_info; ble_gap_sign_info_t * p_sign_info; static ble_gap_enc_key_t m_enc_key; /**< Encryption Key (Encryption Info and Master ID). */ static ble_gap_id_key_t m_id_key; /**< Identity Key (IRK and address). */ static ble_gap_sign_info_t m_sign_key; /**< Signing Key (Connection Signature Resolving Key). */ static ble_gap_sec_keyset_t m_keys = {.keys_periph = {&m_enc_key, &m_id_key, &m_sign_key}}; switch (p_ble_evt->header.evt_id) { case BLE_GAP_EVT_CONNECTED: err_code = bsp_indication_set(BSP_INDICATE_CONNECTED); APP_ERROR_CHECK(err_code); m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle; /* YOUR_JOB: Uncomment this part if you are using the app_button module to handle button events (assuming that the button events are only needed in connected state). If this is uncommented out here, 1. Make sure that app_button_disable() is called when handling BLE_GAP_EVT_DISCONNECTED below. 2. Make sure the app_button module is initialized. err_code = app_button_enable(); APP_ERROR_CHECK(err_code); */ break; case BLE_GAP_EVT_DISCONNECTED: err_code = bsp_indication_set(BSP_INDICATE_IDLE); APP_ERROR_CHECK(err_code); m_conn_handle = BLE_CONN_HANDLE_INVALID; /* YOUR_JOB: Uncomment this part if you are using the app_button module to handle button events. This should be done to save power when not connected to a peer. err_code = app_button_disable(); APP_ERROR_CHECK(err_code); */ advertising_start(); break; case BLE_GAP_EVT_SEC_PARAMS_REQUEST: err_code = sd_ble_gap_sec_params_reply(m_conn_handle, BLE_GAP_SEC_STATUS_SUCCESS, &m_sec_params, &m_keys); APP_ERROR_CHECK(err_code); break; case BLE_GATTS_EVT_SYS_ATTR_MISSING: err_code = sd_ble_gatts_sys_attr_set(m_conn_handle, NULL, 0, BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS | BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS); APP_ERROR_CHECK(err_code); break; case BLE_GAP_EVT_AUTH_STATUS: m_auth_status = p_ble_evt->evt.gap_evt.params.auth_status; break; case BLE_GAP_EVT_SEC_INFO_REQUEST: master_id_matches = memcmp(&p_ble_evt->evt.gap_evt.params.sec_info_request.master_id, &m_enc_key.master_id, sizeof(ble_gap_master_id_t)) == 0; p_distributed_keys = &m_auth_status.kdist_periph; p_enc_info = (p_distributed_keys->enc && master_id_matches) ? &m_enc_key.enc_info : NULL; p_id_info = (p_distributed_keys->id && master_id_matches) ? &m_id_key.id_info : NULL; p_sign_info = (p_distributed_keys->sign && master_id_matches) ? &m_sign_key : NULL; err_code = sd_ble_gap_sec_info_reply(m_conn_handle, p_enc_info, p_id_info, p_sign_info); APP_ERROR_CHECK(err_code); break; case BLE_GAP_EVT_TIMEOUT: if (p_ble_evt->evt.gap_evt.params.timeout.src == BLE_GAP_TIMEOUT_SRC_ADVERTISING) { err_code = bsp_indication_set(BSP_INDICATE_IDLE); APP_ERROR_CHECK(err_code); // Configure buttons with sense level low as wakeup source. err_code = bsp_buttons_enable(1 << WAKEUP_BUTTON_ID); APP_ERROR_CHECK(err_code); // Go to system-off mode (this function will not return; wakeup will cause a reset) err_code = sd_power_system_off(); APP_ERROR_CHECK(err_code); } break; default: // No implementation needed. break; } }
/**@brief Function for handling the Application's BLE Stack events. * * @param[in] p_ble_evt Bluetooth stack event. */ static void on_ble_evt(ble_evt_t * p_ble_evt) { uint32_t err_code = NRF_SUCCESS; static uint16_t m_conn_handle = BLE_CONN_HANDLE_INVALID; switch (p_ble_evt->header.evt_id) { case BLE_GAP_EVT_CONNECTED: err_code = bsp_indication_set(BSP_INDICATE_CONNECTED); APP_ERROR_CHECK(err_code); m_advertising_mode = BLE_NO_ADV; m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle; break; case BLE_GAP_EVT_DISCONNECTED: err_code = bsp_indication_set(BSP_INDICATE_IDLE); APP_ERROR_CHECK(err_code); m_conn_handle = BLE_CONN_HANDLE_INVALID; advertising_start(); break; case BLE_GAP_EVT_TIMEOUT: if (p_ble_evt->evt.gap_evt.params.timeout.src == BLE_GAP_TIMEOUT_SRC_ADVERTISING) { if (m_advertising_mode == BLE_SLEEP) { err_code = bsp_indication_set(BSP_INDICATE_IDLE); APP_ERROR_CHECK(err_code); m_advertising_mode = BLE_NO_ADV; // enable buttons to wake-up from power off err_code = bsp_buttons_enable( (1 << WAKEUP_BUTTON_ID) | (1 << BOND_DELETE_ALL_BUTTON_ID)); APP_ERROR_CHECK(err_code); // Go to system-off mode // (this function will not return; wakeup will cause a reset) err_code = sd_power_system_off(); APP_ERROR_CHECK(err_code); } else { advertising_start(); } } break; case BLE_GATTC_EVT_TIMEOUT: case BLE_GATTS_EVT_TIMEOUT: // Disconnect on GATT Server and Client timeout events. err_code = sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION); APP_ERROR_CHECK(err_code); break; default: // No implementation needed. break; } }
/**@brief Function for handling the Application's BLE Stack events. * * @param[in] p_ble_evt Bluetooth stack event. */ static void on_ble_evt(ble_evt_t * p_ble_evt) { uint32_t err_code = NRF_SUCCESS; ble_gatts_rw_authorize_reply_params_t auth_reply; switch (p_ble_evt->header.evt_id) { case BLE_GAP_EVT_CONNECTED: err_code = bsp_indication_set(BSP_INDICATE_CONNECTED); APP_ERROR_CHECK(err_code); m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle; break; case BLE_GAP_EVT_DISCONNECTED: err_code = bsp_indication_set(BSP_INDICATE_IDLE); APP_ERROR_CHECK(err_code); advertising_start(); break; case BLE_GAP_EVT_TIMEOUT: if (p_ble_evt->evt.gap_evt.params.timeout.src == BLE_GAP_TIMEOUT_SRC_ADVERTISING) { err_code = bsp_indication_set(BSP_INDICATE_IDLE); APP_ERROR_CHECK(err_code); // enable buttons to wake-up from power off err_code = bsp_buttons_enable( (1 << WAKEUP_BUTTON_ID) |(1 << BOND_DELETE_ALL_BUTTON_ID) ); APP_ERROR_CHECK(err_code); // Go to system-off mode (this function will not return; wakeup will cause a reset). err_code = sd_power_system_off(); APP_ERROR_CHECK(err_code); } break; case BLE_GAP_EVT_PASSKEY_DISPLAY: { char passkey[PASSKEY_LENGTH+1]; memcpy(passkey,p_ble_evt->evt.gap_evt.params.passkey_display.passkey,PASSKEY_LENGTH); passkey[PASSKEY_LENGTH] = 0; // Don't send delayed Security Request if security procedure is already in progress. err_code = app_timer_stop(m_sec_req_timer_id); APP_ERROR_CHECK(err_code); printf("Passkey: %s\n",passkey); break; } case BLE_EVT_USER_MEM_REQUEST: err_code = sd_ble_user_mem_reply(m_conn_handle, NULL); APP_ERROR_CHECK(err_code); break; case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST: if(p_ble_evt->evt.gatts_evt.params.authorize_request.type != BLE_GATTS_AUTHORIZE_TYPE_INVALID) { if ((p_ble_evt->evt.gatts_evt.params.authorize_request.request.write.op == BLE_GATTS_OP_PREP_WRITE_REQ) || (p_ble_evt->evt.gatts_evt.params.authorize_request.request.write.op == BLE_GATTS_OP_EXEC_WRITE_REQ_NOW) || (p_ble_evt->evt.gatts_evt.params.authorize_request.request.write.op == BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL)) { if (p_ble_evt->evt.gatts_evt.params.authorize_request.type == BLE_GATTS_AUTHORIZE_TYPE_WRITE) { auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE; } else { auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_READ; } auth_reply.params.write.gatt_status = APP_FEATURE_NOT_SUPPORTED; err_code = sd_ble_gatts_rw_authorize_reply(m_conn_handle,&auth_reply); APP_ERROR_CHECK(err_code); } } break; case BLE_GAP_EVT_AUTH_STATUS: case BLE_GAP_EVT_CONN_SEC_UPDATE: break; default: // No implementation needed. break; } }