text: 
  #include "ble/ble_events.h"
  #include "app/transfer_service.h"
  #include "hal/power_managment.h"
  #include "nordic_common.h"
  #include "settings.h"
  
  #include <ble_hci.h>
  #include <ble_conn_state.h>
  #include <peer_manager.h>
  #include <ble_conn_params.h>
  #include <ble_advertising.h>
  #include <bsp_btn_ble.h>
  #include <nrf_log.h>
  #include <fstorage.h>
  
  #define APP_FEATURE_NOT_SUPPORTED        BLE_GATT_STATUS_ATTERR_APP_BEGIN + 2        /**< Reply when unsupported features are requested. */
  
  static void on_ble_evt(ble_evt_t * p_ble_evt);
  
  /**@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_LOG_INFO("on_ble_evt id 0x%x \r\n", p_ble_evt->header.evt_id);
      switch (p_ble_evt->header.evt_id)
      {
          case BLE_GAP_EVT_CONNECTED:
              NRF_LOG_INFO("Connected\r\n");
              err_code = bsp_indication_set(BSP_INDICATE_CONNECTED);
              APP_ERROR_CHECK(err_code);
              m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
              led_on(LED0);
              break; // BLE_GAP_EVT_CONNECTED
  
          case BLE_GAP_EVT_DISCONNECTED:
              NRF_LOG_INFO("Disconnected, reason %d\r\n",
                            p_ble_evt->evt.gap_evt.params.disconnected.reason);
              m_conn_handle = BLE_CONN_HANDLE_INVALID;
              led_off(LED0);
              break; // BLE_GAP_EVT_DISCONNECTED
  
          case BLE_GATTC_EVT_TIMEOUT:
              // Disconnect on GATT Client timeout event.
              NRF_LOG_DEBUG("GATT Client Timeout.\r\n");
              err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gattc_evt.conn_handle,
                                               BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
              APP_ERROR_CHECK(err_code);
              break; // BLE_GATTC_EVT_TIMEOUT
  
          case BLE_GATTS_EVT_TIMEOUT:
              // Disconnect on GATT Server timeout event.
              NRF_LOG_DEBUG("GATT Server Timeout.\r\n");
              err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gatts_evt.conn_handle,
                                               BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
              APP_ERROR_CHECK(err_code);
              break; // BLE_GATTS_EVT_TIMEOUT
  
          case BLE_EVT_USER_MEM_REQUEST:
              err_code = sd_ble_user_mem_reply(m_conn_handle, NULL);
              APP_ERROR_CHECK(err_code);
              break; // BLE_EVT_USER_MEM_REQUEST
  
          case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST:
          {
              ble_gatts_evt_rw_authorize_request_t  req;
              ble_gatts_rw_authorize_reply_params_t auth_reply;
  
              req = p_ble_evt->evt.gatts_evt.params.authorize_request;
  
              if (req.type != BLE_GATTS_AUTHORIZE_TYPE_INVALID)
              {
                  if ((req.request.write.op == BLE_GATTS_OP_PREP_WRITE_REQ)     ||
                      (req.request.write.op == BLE_GATTS_OP_EXEC_WRITE_REQ_NOW) ||
                      (req.request.write.op == BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL))
                  {
                      if (req.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(p_ble_evt->evt.gatts_evt.conn_handle,
                                                                 &auth_reply);
                      APP_ERROR_CHECK(err_code);
                  }
              }
          } break; // BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST
  
  
          default:
              // No implementation needed.
              break;
      }
  }
  
  void on_adv_evt(ble_adv_evt_t ble_adv_evt)
  {
      NRF_LOG_DEBUG("%s:\r\n", (uint32_t)__FUNCTION__);
      uint32_t err_code;
  
      switch (ble_adv_evt)
      {
          case BLE_ADV_EVT_FAST:
              NRF_LOG_INFO("Fast Advertising\r\n");
              err_code = bsp_indication_set(BSP_INDICATE_ADVERTISING);
              APP_ERROR_CHECK(err_code);
              break;
  
          case BLE_ADV_EVT_IDLE:
              sleep_mode_enter();
              break;
  
          default:
              break;
      }
  }
  
  /**@brief Custom advertising BLE event handler.
   *
   * @details Custom advertising BLE event handler, for changes in disconnect event handling.
   *
   * @param[in] p_ble_evt Bluetooth stack event.
   */
  static void custom_ble_advertising_on_ble_evt(ble_evt_t const * p_ble_evt)
  {
  	uint32_t err_code;
  	switch (p_ble_evt->header.evt_id)
      {
          // Special handling is needed for some disconnects
          case BLE_GAP_EVT_DISCONNECTED:
  
          	err_code = ble_advertising_start(BLE_ADV_MODE_FAST);
          	if (err_code != NRF_SUCCESS)
  			{
  				APP_ERROR_CHECK(err_code);
  			}
          	break;
          // Let the advertising module handle all other events
          default:
              ble_advertising_on_ble_evt(p_ble_evt);
              break;
      }
  }
  
  void ble_evt_dispatch(ble_evt_t * p_ble_evt)
  {
      ble_conn_state_on_ble_evt(p_ble_evt);
      ble_conn_params_on_ble_evt(p_ble_evt);
      bsp_btn_ble_on_ble_evt(p_ble_evt);
      on_ble_evt(p_ble_evt);
      transfer_on_ble_evt(p_ble_evt);
      custom_ble_advertising_on_ble_evt(p_ble_evt);
   }
  
  
  void sys_evt_dispatch(uint32_t sys_evt)
  {
      NRF_LOG_DEBUG("%s:\r\n", (uint32_t)__FUNCTION__);
      // Dispatch the system event to the fstorage module, where it will be
      // dispatched to the Flash Data Storage (FDS) module.
      fs_sys_event_handler(sys_evt);
  
      // Dispatch to the Advertising module last, since it will check if there are any
      // pending flash operations in fstorage. Let fstorage process system events first,
      // so that it can report correctly to the Advertising module.
      ble_advertising_on_sys_evt(sys_evt);
  }
  
  void bsp_event_handler(bsp_event_t event)
  {
      NRF_LOG_DEBUG("%s:\r\n", (uint32_t)__FUNCTION__);
      uint32_t err_code;
  
      switch (event)
      {
          case BSP_EVENT_SLEEP:
              sleep_mode_enter();
              break;
  
          case BSP_EVENT_DISCONNECT:
              err_code = sd_ble_gap_disconnect(m_conn_handle,
                                               BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
              if (err_code != NRF_ERROR_INVALID_STATE)
              {
                  APP_ERROR_CHECK(err_code);
              }
              break;
  
          case BSP_EVENT_WHITELIST_OFF:
              if (m_conn_handle == BLE_CONN_HANDLE_INVALID)
              {
                  err_code = ble_advertising_restart_without_whitelist();
                  if (err_code != NRF_ERROR_INVALID_STATE)
                  {
                      APP_ERROR_CHECK(err_code);
                  }
              }
              break;
  
          default:
              break;
      }
  }
  