/**@brief Function for putting the chip into sleep mode. * * @note This function will not return. */ static void sleep_mode_enter(void) { uint32_t err_code; // Prepare wakeup buttons. debug_printf("Cycle power to restart. Bye. \r\n"); // 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); }
/**@brief Function for putting the chip into sleep mode. * * @note This function will not return. */ void BSP_stop() { uint32_t new_cnf = NRF_GPIO->PIN_CNF[BTN_PIN]; uint32_t new_sense = GPIO_PIN_CNF_SENSE_Low; new_cnf &= ~GPIO_PIN_CNF_SENSE_Msk; new_cnf |= (new_sense << GPIO_PIN_CNF_SENSE_Pos); NRF_GPIO->PIN_CNF[BTN_PIN] = new_cnf; // Go to system-off mode (this function will not return; // wakeup will cause a reset). Q_ALLEGE(sd_power_system_off() == NRF_SUCCESS); }
/**@brief Function for putting the chip into sleep mode. * * @note This function will not return. */ static void sleep_mode_enter(void) { uint32_t err_code = bsp_indication_set(BSP_INDICATE_IDLE); APP_ERROR_CHECK(err_code); // Prepare wakeup buttons. err_code = bsp_btn_ble_sleep_mode_prepare(); APP_ERROR_CHECK(err_code); // Go to system-off mode (this function will not return; wakeup will cause a reset). (void) sd_power_system_off(); }
/**@brief Handler for doing post actions on storage access complete */ static void storage_access_complete_handler(void) { uint32_t err_code; m_storage_in_progress = false; if (m_sys_off_pending == true) { err_code = sd_power_system_off(); APP_ERROR_CHECK(err_code); } }
/**@brief Function for putting the chip into sleep mode. * * @note This function will not return. */ static void sleep_mode_enter(void) { uint32_t err_code = bsp_indication_set(BSP_INDICATE_IDLE); APP_ERROR_CHECK(err_code); // Prepare wakeup button. err_code = bsp_wakeup_buttons_set((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); }
/**@brief Function for putting the chip in System OFF Mode */ static void system_off_mode_enter(void) { uint32_t err_code; if (m_storage_in_progress) { m_sys_off_pending = true; } else { err_code = sd_power_system_off(); APP_ERROR_CHECK(err_code); } }
static void pmNrfPower(bool enable) { if (!enable) { //stop NRF LED_OFF(); nrf_gpio_cfg_input(PM_VBAT_SINK_PIN, NRF_GPIO_PIN_NOPULL); NRF_POWER->GPREGRET |= 0x01; // Workaround for not being able to determine reset reason... #ifdef BLE sd_power_system_off(); #else NRF_POWER->SYSTEMOFF = 1UL; #endif while(1); } }
/**@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; switch (p_ble_evt->header.evt_id) { case BLE_GAP_EVT_CONNECTED: nrf_gpio_pin_set(CONNECTED_LED_PIN_NO); nrf_gpio_pin_clear(ADVERTISING_LED_PIN_NO); m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle; break; case BLE_GAP_EVT_DISCONNECTED: nrf_gpio_pin_clear(CONNECTED_LED_PIN_NO); m_conn_handle = BLE_CONN_HANDLE_INVALID; advertising_start(); break; case BLE_GAP_EVT_PASSKEY_DISPLAY: // 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); break; case BLE_GAP_EVT_TIMEOUT: if (p_ble_evt->evt.gap_evt.params.timeout.src == BLE_GAP_TIMEOUT_SRC_ADVERTISEMENT) { nrf_gpio_pin_clear(ADVERTISING_LED_PIN_NO); // Configure buttons with sense level low as wakeup source. nrf_gpio_cfg_sense_input(WAKEUP_BUTTON_PIN, BUTTON_PULL, NRF_GPIO_PIN_SENSE_LOW); // 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; switch (p_ble_evt->header.evt_id) { case BLE_GAP_EVT_CONNECTED: nrf_gpio_pin_set(CONNECTED_LED_PIN_NO); nrf_gpio_pin_clear(ADVERTISING_LED_PIN_NO); m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle; break; case BLE_GAP_EVT_DISCONNECTED: nrf_gpio_pin_clear(CONNECTED_LED_PIN_NO); m_conn_handle = BLE_CONN_HANDLE_INVALID; // Since we are not in a connection and have not started advertising, store bonds. err_code = ble_bondmngr_bonded_centrals_store(); 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); 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_ADVERTISEMENT) { nrf_gpio_pin_clear(ADVERTISING_LED_PIN_NO); // 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; switch (p_ble_evt->header.evt_id) { case BLE_GAP_EVT_CONNECTED: app.conn_handle = p_ble_evt->evt.gap_evt.conn_handle; //advertising_stop(); break; case BLE_GAP_EVT_DISCONNECTED: app.conn_handle = BLE_CONN_HANDLE_INVALID; advertising_start(); break; case BLE_GATTS_EVT_WRITE: break; case BLE_GAP_EVT_SEC_PARAMS_REQUEST: err_code = sd_ble_gap_sec_params_reply(app.conn_handle, BLE_GAP_SEC_STATUS_SUCCESS, &m_sec_params, NULL); APP_ERROR_CHECK(err_code); break; case BLE_GATTS_EVT_SYS_ATTR_MISSING: err_code = sd_ble_gatts_sys_attr_set(app.conn_handle, NULL, 0, 0); APP_ERROR_CHECK(err_code); break; case BLE_GAP_EVT_AUTH_STATUS: break; case BLE_GAP_EVT_SEC_INFO_REQUEST: // No keys found for this device. err_code = sd_ble_gap_sec_info_reply(app.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 = sd_power_system_off(); 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; 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; } }
/**@brief Function runs the shutdown procedure. */ static void shutdown_process(void) { NRF_LOG_INFO("Shutdown started. Type %d\r\n", m_pwr_mgmt_evt); // Executing all callbacks. while (m_next_handler < PWR_MGMT_SECTION_VARS_COUNT) { if ((*PWR_MGMT_SECTION_VARS_GET(m_next_handler))(m_pwr_mgmt_evt)) { NRF_LOG_INFO("SysOff handler 0x%08X => ready\r\n", (unsigned int)*PWR_MGMT_SECTION_VARS_GET(m_next_handler)); } else { // One of the modules is not ready. NRF_LOG_INFO("SysOff handler 0x%08X => blocking\r\n", (unsigned int)*PWR_MGMT_SECTION_VARS_GET(m_next_handler)); return; } // Mark handler as executed. m_next_handler++; } #if NRF_PWR_MGMT_CONFIG_CPU_USAGE_MONITOR_ENABLED NRF_LOG_INFO("Maximum CPU usage: %u%%\r\n", m_max_cpu_usage); #endif // NRF_PWR_MGMT_CONFIG_CPU_USAGE_MONITOR_ENABLED NRF_LOG_WARNING("Shutdown\r\n"); NRF_LOG_FINAL_FLUSH(); // Enter System OFF. #ifdef SOFTDEVICE_PRESENT ret_code_t ret_code = sd_power_system_off(); if (ret_code == NRF_ERROR_SOFTDEVICE_NOT_ENABLED) { NRF_POWER->SYSTEMOFF = POWER_SYSTEMOFF_SYSTEMOFF_Enter; } else { APP_ERROR_CHECK(ret_code); } #else NRF_POWER->SYSTEMOFF = POWER_SYSTEMOFF_SYSTEMOFF_Enter; #endif // SOFTDEVICE_PRESENT }
/**@brief Function for putting the chip in System OFF Mode */ static void system_off_mode_enter(void) { uint32_t err_code; uint32_t count; // Verify if there is any flash access pending, if yes delay starting advertising until // it's complete. err_code = pstorage_access_status_get(&count); APP_ERROR_CHECK(err_code); if (count != 0) { m_memory_access_in_progress = true; return; } err_code = sd_power_system_off(); APP_ERROR_CHECK(err_code); }
uint32_t conn_mw_power_system_off(uint8_t const * const p_rx_buf, uint32_t rx_buf_len, uint8_t * const p_tx_buf, uint32_t * const p_tx_buf_len) { SER_ASSERT_NOT_NULL(p_rx_buf); SER_ASSERT_NOT_NULL(p_tx_buf); SER_ASSERT_NOT_NULL(p_tx_buf_len); uint32_t err_code = NRF_SUCCESS; err_code = power_system_off_req_dec(p_rx_buf, rx_buf_len); SER_ASSERT(err_code == NRF_SUCCESS, err_code); err_code = sd_power_system_off(); /* There should be no return from sd_power_system_off() */ return err_code; }
/**@brief Function for handling button presses. */ static void button_event_handler(uint8_t pin_no) { static uint8_t send_push = 1; uint32_t err_code; uart_tx_status_code("event pin #", pin_no, 0); switch (pin_no) { case LEDBUTTON_BUTTON_PIN_NO: err_code = ble_lbs_on_button_change(&m_lbs, send_push); //err_code = NRF_SUCCESS; if (err_code != NRF_SUCCESS && err_code != BLE_ERROR_INVALID_CONN_HANDLE && err_code != NRF_ERROR_INVALID_STATE) { uart_tx_status_code("reset @ err. code #:", err_code, 0); err_code = sd_power_system_off(); APP_ERROR_CHECK(err_code); } send_push = !send_push; 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; switch (p_ble_evt->header.evt_id) { case BLE_GAP_EVT_CONNECTED: nrf_gpio_pin_set(CONNECTED_LED_PIN_NO); nrf_gpio_pin_clear(ADVERTISING_LED_PIN_NO); m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle; // rsc_first_conn_flag = true; break; case BLE_GAP_EVT_DISCONNECTED: nrf_gpio_pin_clear(CONNECTED_LED_PIN_NO); m_conn_handle = BLE_CONN_HANDLE_INVALID; m_hts_meas_ind_conf_pending = false; // rsc_first_conn_flag = true; advertising_start(); break; case BLE_GAP_EVT_TIMEOUT: if (p_ble_evt->evt.gap_evt.params.timeout.src == BLE_GAP_TIMEOUT_SRC_ADVERTISEMENT) { nrf_gpio_pin_clear(ADVERTISING_LED_PIN_NO); xprintf("\r\nBle gap event timeout...\r\n"); // 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 error handling, which is called when an error has occurred. * * @warning This handler is an example only and does not fit a final product. You need to analyze * how your product is supposed to react in case of error. * * @param[in] error_code Error code supplied to the handler. * @param[in] line_num Line number where the handler is called. * @param[in] p_file_name Pointer to the file name. */ void app_error_handler(uint32_t error_code, uint32_t line_num, const uint8_t * p_file_name) { LEDS_ON((LED_ONE | LED_TWO)); APPL_LOG("[** ASSERT **]: Error 0x%08lX, Line %ld, File %s\r\n", \ error_code, line_num, p_file_name); // Variables used to retain function parameter values when debugging. static volatile uint8_t s_file_name[MAX_LENGTH_FILENAME]; static volatile uint16_t s_line_num; static volatile uint32_t s_error_code; strncpy((char *)s_file_name, (const char *)p_file_name, MAX_LENGTH_FILENAME - 1); s_file_name[MAX_LENGTH_FILENAME - 1] = '\0'; s_line_num = line_num; s_error_code = error_code; UNUSED_VARIABLE(s_file_name); UNUSED_VARIABLE(s_line_num); UNUSED_VARIABLE(s_error_code); #ifdef COMMISSIONING_ENABLED if (m_power_off_on_failure == true) { LEDS_OFF((LED_ONE | LED_TWO)); UNUSED_VARIABLE(sd_power_system_off()); } else { NVIC_SystemReset(); } #else // COMMISSIONING_ENABLED //NVIC_SystemReset(); for (;;) { } #endif // COMMISSIONING_ENABLED }
/**@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; switch (p_ble_evt->header.evt_id) { case BLE_GAP_EVT_CONNECTED: // continue advertising nonconnectably app.conn_handle = p_ble_evt->evt.gap_evt.conn_handle; m_adv_params.type = BLE_GAP_ADV_TYPE_ADV_NONCONN_IND; advertising_start(); break; case BLE_GAP_EVT_DISCONNECTED: app.conn_handle = BLE_CONN_HANDLE_INVALID; // advertise connectivity advertising_stop(); m_adv_params.type = BLE_GAP_ADV_TYPE_ADV_IND; advertising_start(); break; case BLE_GATTS_EVT_WRITE: { ble_gatts_evt_write_t* write_data = &(p_ble_evt->evt.gatts_evt.params.write); if (write_data->context.char_uuid.uuid == test_char_uuid16) { if (write_data->data[0] == 0x42) { //led_on(BLEES_LED_PIN); // enable higher connection interval. Only lasts for this connection ble_gap_conn_params_t gap_conn_params; memset(&gap_conn_params, 0, sizeof(gap_conn_params)); gap_conn_params.min_conn_interval = 0x06; // 7.5 ms gap_conn_params.max_conn_interval = MSEC_TO_UNITS(30, UNIT_1_25_MS); gap_conn_params.slave_latency = 0; gap_conn_params.conn_sup_timeout = CONN_SUP_TIMEOUT; err_code = sd_ble_gap_conn_param_update(app.conn_handle, &gap_conn_params); APP_ERROR_CHECK(err_code); } } } break; case BLE_GAP_EVT_SEC_PARAMS_REQUEST: err_code = sd_ble_gap_sec_params_reply(app.conn_handle, BLE_GAP_SEC_STATUS_SUCCESS, &m_sec_params, NULL); APP_ERROR_CHECK(err_code); break; case BLE_GATTS_EVT_SYS_ATTR_MISSING: err_code = sd_ble_gatts_sys_attr_set(app.conn_handle, NULL, 0, 0); APP_ERROR_CHECK(err_code); break; case BLE_GAP_EVT_AUTH_STATUS: break; case BLE_GAP_EVT_SEC_INFO_REQUEST: // No keys found for this device. err_code = sd_ble_gap_sec_info_reply(app.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 = sd_power_system_off(); APP_ERROR_CHECK(err_code); } break; default: break; } }
/**@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_evt_auth_status_t m_auth_status; ble_gap_enc_info_t * p_enc_info; switch (p_ble_evt->header.evt_id) { case BLE_GAP_EVT_CONNECTED: nrf_gpio_pin_set(CONNECTED_LED_PIN_NO); nrf_gpio_pin_clear(ADVERTISING_LED_PIN_NO); m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle; break; case BLE_GAP_EVT_DISCONNECTED: nrf_gpio_pin_clear(CONNECTED_LED_PIN_NO); m_conn_handle = BLE_CONN_HANDLE_INVALID; 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); 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); 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: p_enc_info = &m_auth_status.periph_keys.enc_info; if (p_enc_info->div == p_ble_evt->evt.gap_evt.params.sec_info_request.div) { err_code = sd_ble_gap_sec_info_reply(m_conn_handle, p_enc_info, 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); 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_ADVERTISEMENT) { nrf_gpio_pin_clear(ADVERTISING_LED_PIN_NO); // Configure buttons with sense level low as wakeup source. nrf_gpio_cfg_sense_input(WAKEUP_BUTTON_PIN, BUTTON_PULL, NRF_GPIO_PIN_SENSE_LOW); // 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_EVT_TX_COMPLETE: if(!ble_buffer_available) tx_complete = true; break; default: // No implementation needed. break; } }
/**@brief Application's BLE Stack event handler. * * @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; switch (p_ble_evt->header.evt_id) { case BLE_GAP_EVT_CONNECTED: nrf_gpio_pin_set(CONNECTED_LED_PIN_NO); nrf_gpio_pin_clear(ADVERTISING_LED_PIN_NO); // Start detecting button presses err_code = app_button_enable(); m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle; break; case BLE_GAP_EVT_DISCONNECTED: nrf_gpio_pin_clear(CONNECTED_LED_PIN_NO); m_conn_handle = BLE_CONN_HANDLE_INVALID; m_bps_meas_ind_conf_pending = false; // Stop detecting button presses when not connected err_code = app_button_disable(); APP_ERROR_CHECK(err_code); // Since we are not in a connection and have not started advertising, store bonds err_code = ble_bondmngr_bonded_masters_store(); 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); break; case BLE_GAP_EVT_TIMEOUT: if (p_ble_evt->evt.gap_evt.params.timeout.src == BLE_GAP_TIMEOUT_SRC_ADVERTISEMENT) { nrf_gpio_pin_clear(ADVERTISING_LED_PIN_NO); // Go to system-off mode (this function will not return; wakeup will cause a reset) GPIO_WAKEUP_BUTTON_CONFIG(SEND_MEAS_BUTTON_PIN_NO); err_code = sd_power_system_off(); } break; case BLE_GATTS_EVT_TIMEOUT: if (p_ble_evt->evt.gatts_evt.params.timeout.src == BLE_GATT_TIMEOUT_SRC_PROTOCOL) { err_code = sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION); } break; default: break; } 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 = 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 application main entry. */ int main(void) { uint32_t err_code; bool is_notification_mode = false; bool is_non_connectable_mode = false; timers_init(); APP_GPIOTE_INIT(1); err_code = bsp_init(BSP_INIT_LED | BSP_INIT_BUTTONS, APP_TIMER_TICKS(100, APP_TIMER_PRESCALER), NULL); APP_ERROR_CHECK(err_code); #if BUTTONS_NUMBER > 2 // Check button states. // Notification Start button. err_code = bsp_button_is_pressed(NOTIF_BUTTON_ID, &(is_notification_mode)); APP_ERROR_CHECK(err_code); // Non-connectable advertisement start button. if (!is_notification_mode) { err_code = bsp_button_is_pressed(NON_CONN_ADV_BUTTON_ID, &(is_non_connectable_mode)); APP_ERROR_CHECK(err_code); } // Un-configured button. else { } #else is_notification_mode = true; #endif // Initialize SoftDevice. ble_stack_init(); if (!is_notification_mode && !is_non_connectable_mode) { // The startup was not because of button presses. This is the first start. // Go into System-Off mode. Button presses will wake the chip up. err_code = sd_power_system_off(); APP_ERROR_CHECK(err_code); } // If we reach this point, the application was woken up by pressing one of the two configured // buttons. gap_params_init(); if (is_notification_mode) { // Notification button is pressed. Start connectable advertisement. connectable_adv_init(); service_add(); } else { non_connectable_adv_init(); } advertising_data_init(); advertising_start(); // Enter main loop. for (;;) { power_manage(); } }
/**@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; ble_gap_enc_info_t * p_enc_info; switch (p_ble_evt->header.evt_id) { case BLE_GAP_EVT_CONNECTED: nrf_gpio_pin_set(CONNECTED_LED_PIN_NO); nrf_gpio_pin_clear(ADVERTISING_LED_PIN_NO); 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: nrf_gpio_pin_clear(CONNECTED_LED_PIN_NO); 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); 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); 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: p_enc_info = &m_auth_status.periph_keys.enc_info; if (p_enc_info->div == p_ble_evt->evt.gap_evt.params.sec_info_request.div) { err_code = sd_ble_gap_sec_info_reply(m_conn_handle, p_enc_info, 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); 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_ADVERTISEMENT) { nrf_gpio_pin_clear(ADVERTISING_LED_PIN_NO); // Configure buttons with sense level low as wakeup source. nrf_gpio_cfg_sense_input(WAKEUP_BUTTON_PIN, BUTTON_PULL, NRF_GPIO_PIN_SENSE_LOW); // 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 RPC_SD_POWER_SYSTEM_OFF command. * * This function will decode the command, call the SOC API and put the chip into system off * mode. It will always return error code NRF_SUCCESS. * * @return NRF_SUCCESS */ static uint32_t sd_power_system_off_handle(void) { UNUSED_VARIABLE(sd_power_system_off()); return NRF_SUCCESS; }
*/ static void on_ble_evt(ble_evt_t * p_ble_evt) { uint32_t err_code; static uint16_t m_conn_handle = BLE_CONN_HANDLE_INVALID; switch (p_ble_evt->header.evt_id) { case BLE_GAP_EVT_CONNECTED: nrf_gpio_pin_set(CONNECTED_LED_PIN_NO); nrf_gpio_pin_clear(ADVERTISING_LED_PIN_NO); nrf_gpio_pin_clear(ADV_INTERVAL_SLOW_LED_PIN_NO); nrf_gpio_pin_clear(ADV_WHITELIST_LED_PIN_NO); // Start handling button presses err_code = app_button_enable(); 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: nrf_gpio_pin_clear(CONNECTED_LED_PIN_NO); if (!m_is_link_loss_alerting) { nrf_gpio_pin_clear(ALERT_LEVEL_MILD_LED_PIN_NO); nrf_gpio_pin_clear(ALERT_LEVEL_HIGH_LED_PIN_NO); } m_conn_handle = BLE_CONN_HANDLE_INVALID; // Since we are not in a connection and have not started advertising, store bonds. err_code = ble_bondmngr_bonded_centrals_store(); APP_ERROR_CHECK(err_code); // Stop detecting button presses when not connected. 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); 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_ADVERTISEMENT) { if (m_advertising_mode == BLE_SLEEP) { m_advertising_mode = BLE_NO_ADV; nrf_gpio_pin_clear(ADVERTISING_LED_PIN_NO); nrf_gpio_pin_clear(ADV_WHITELIST_LED_PIN_NO); nrf_gpio_pin_clear(ADV_INTERVAL_SLOW_LED_PIN_NO); // Configure buttons with sense level low as wakeup source. nrf_gpio_cfg_sense_input(SIGNAL_ALERT_BUTTON, BUTTON_PULL, NRF_GPIO_PIN_SENSE_LOW); nrf_gpio_cfg_sense_input(BONDMNGR_DELETE_BUTTON_PIN_NO, BUTTON_PULL, NRF_GPIO_PIN_SENSE_LOW); // 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 BLEスタックイベントハンドラ * * @param[in] p_ble_evt BLEスタックイベント */ static void ble_evt_handler(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 sec_key = {.keys_periph = {&m_enc_key, &m_id_key, &m_sign_key}}; switch (p_ble_evt->header.evt_id) { /************* * GAP event *************/ //接続が成立したとき case BLE_GAP_EVT_CONNECTED: app_trace_log("BLE_GAP_EVT_CONNECTED\r\n"); led_on(LED_PIN_NO_CONNECTED); led_off(LED_PIN_NO_ADVERTISING); m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle; break; //相手から切断されたとき //必要があればsd_ble_gatts_sys_attr_get()でSystem Attributeを取得し、保持しておく。 //保持したSystem Attributeは、EVT_SYS_ATTR_MISSINGで返すことになる。 case BLE_GAP_EVT_DISCONNECTED: app_trace_log("BLE_GAP_EVT_DISCONNECTED\r\n"); led_off(LED_PIN_NO_CONNECTED); m_conn_handle = BLE_CONN_HANDLE_INVALID; app_ble_start(); break; //SMP Paring要求を受信したとき //sd_ble_gap_sec_params_reply()で値を返したあと、SMP Paring Phase 2に状態遷移する case BLE_GAP_EVT_SEC_PARAMS_REQUEST: app_trace_log("BLE_GAP_EVT_SEC_PARAMS_REQUEST\r\n"); { ble_gap_sec_params_t sec_param; sec_param.bond = SEC_PARAM_BOND; sec_param.mitm = SEC_PARAM_MITM; sec_param.io_caps = SEC_PARAM_IO_CAPABILITIES; sec_param.oob = SEC_PARAM_OOB; sec_param.min_key_size = SEC_PARAM_MIN_KEY_SIZE; sec_param.max_key_size = SEC_PARAM_MAX_KEY_SIZE; err_code = sd_ble_gap_sec_params_reply(m_conn_handle, BLE_GAP_SEC_STATUS_SUCCESS, &sec_param, &sec_key); APP_ERROR_CHECK(err_code); } break; //Just Works(Bonding有り)の場合、SMP Paring Phase 3のあとでPeripheral Keyが渡される。 //ここではPeripheral Keyを保存だけしておき、次のBLE_GAP_EVT_SEC_INFO_REQUESTで処理する。 case BLE_GAP_EVT_AUTH_STATUS: app_trace_log("BLE_GAP_EVT_AUTH_STATUS\r\n"); m_auth_status = p_ble_evt->evt.gap_evt.params.auth_status; break; //SMP Paringが終わったとき? case BLE_GAP_EVT_SEC_INFO_REQUEST: app_trace_log("BLE_GAP_EVT_SEC_INFO_REQUEST\r\n"); 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; //Advertisingか認証のタイムアウト発生 case BLE_GAP_EVT_TIMEOUT: app_trace_log("BLE_GAP_EVT_TIMEOUT\r\n"); switch (p_ble_evt->evt.gap_evt.params.timeout.src) { case BLE_GAP_TIMEOUT_SRC_ADVERTISING: //Advertisingのタイムアウト /* Advertising LEDを消灯 */ led_off(LED_PIN_NO_ADVERTISING); /* System-OFFにする(もう戻ってこない) */ err_code = sd_power_system_off(); APP_ERROR_CHECK(err_code); break; case BLE_GAP_TIMEOUT_SRC_SECURITY_REQUEST: //Security requestのタイムアウト break; default: break; } break; /********************* * GATT Server event *********************/ //接続後、Bondingした相手からSystem Attribute要求を受信したとき //System Attributeは、EVT_DISCONNECTEDで保持するが、今回は保持しないのでNULLを返す。 case BLE_GATTS_EVT_SYS_ATTR_MISSING: app_trace_log("BLE_GATTS_EVT_SYS_ATTR_MISSING\r\n"); 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; default: // No implementation needed. break; } }
/**@brief Application's BLE Stack event handler. * * @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: nrf_gpio_pin_set(CONNECTED_LED_PIN_NO); nrf_gpio_pin_clear(ADVERTISING_LED_PIN_NO); err_code = app_button_enable(); m_advertising_mode = BLE_NO_ADVERTISING; m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle; break; case BLE_GAP_EVT_DISCONNECTED: nrf_gpio_pin_clear(CONNECTED_LED_PIN_NO); m_conn_handle = BLE_CONN_HANDLE_INVALID; // Since we are not in a connection and have not start to advertise either, store bonds. err_code = ble_bondmngr_bonded_masters_store(); APP_ERROR_CHECK(err_code); // Stop detecting button presses when not connected err_code = app_button_disable(); APP_ERROR_CHECK(err_code); // Stop detecting button presses when not connected err_code = app_button_disable(); APP_ERROR_CHECK(err_code); err_code = ble_ans_c_service_store(); 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); 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 { nrf_gpio_pin_clear(ADVERTISING_LED_PIN_NO); m_advertising_mode = BLE_NO_ADVERTISING; // Go to system-off mode (function will not return; wakeup will cause a reset) GPIO_WAKEUP_BUTTON_CONFIG(WAKEUP_BUTTON_PIN); err_code = sd_power_system_off(); } } 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); break; default: break; } APP_ERROR_CHECK(err_code); }