This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Function responsible for Connection establishment between nrf52382 as peripheral and nrf connect as central.

Hi 

Am new to the nrf52382 , Am trying to establish connection between nrf52382 DK as peripheral and nrf connect app as central,

Am unable to connect it .Please debug the issue

/**
* Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
*    list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
*    Semiconductor ASA integrated circuit in a product or a software update for
*    such product, must reproduce the above copyright notice, this list of
*    conditions and the following disclaimer in the documentation and/or other
*    materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
*    contributors may be used to endorse or promote products derived from this
*    software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
*    Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
*    engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/** @example examples/ble_peripheral/ble_app_hrs/main.c
*
* @brief Heart Rate Service Sample Application main file.
*
* This file contains the source code for a sample application using the Heart Rate service
* (and also Battery and Device Information services). This application uses the
* @ref srvlib_conn_params module.
*/
#include <stdint.h>
#include <string.h>
#include "nordic_common.h"
#include "nrf.h"
#include "ble.h"
#include "ble_hci.h"
#include "ble_srv_common.h"
#include "ble_advdata.h"
#include "ble_advertising.h"
#include "ble_dis.h"
#include "boards.h"
#include "sensorsim.h"
#include "nrf_sdh.h"
#include "nrf_sdh_soc.h"
#include "nrf_sdh_ble.h"
#include "bsp.h"
#include "bsp_btn_ble.h"
#include "peer_manager.h"
#include "peer_manager_handler.h"
#include "fds.h"
#include "nrf_ble_gatt.h"
#include "nrf_ble_qwr.h"
#include "ble_conn_state.h"
#include "app_error.h"
#include "app_timer.h"
#include "task_manager.h"
#include "nrf_cli.h"
#include "nrf_cli_rtt.h"
#include "nrf_cli_uart.h"
#include "nrf_cli_ble_uart.h"
#include "nrf_pwr_mgmt.h"
#include "nrf_drv_clock.h"
#include "nrf_stack_guard.h"
#include "nrf_fstorage_sd.h"
#include "nrf_ble_scan.h"
#include "ble_db_discovery.h"
#include "ble_nus.h"
#include "ble_cus.h"
//#include "ble_hts.h"
#include "ble_conn_params.h"
#include "flash_write.h"
#include "nrf_log.h"
#include "nrf_log_ctrl.h"
#include "nrf_log_backend_flash.h"

#define DEVICE_NAME                     "Nordic_CLI"                                /**< Name of device. Will be included in the advertising data. */
#define MANUFACTURER_NAME               "NordicSemiconductor"                       /**< Manufacturer. Will be passed to Device Information Service. */
#define APP_ADV_INTERVAL                300                                         /**< The advertising interval (in units of 0.625 ms. This value corresponds to 187.5 ms). */
#define APP_ADV_DURATION                18000                                       /**< The advertising duration (180 seconds) in units of 10 milliseconds. */
#define APP_BLE_OBSERVER_PRIO           3                                           /**< Application's BLE observer priority. You shouldn't need to modify this value. */
#define APP_BLE_CONN_CFG_TAG            1                                           /**< A tag identifying the SoftDevice BLE configuration. */
#define BATTERY_LEVEL_MEAS_INTERVAL      APP_TIMER_TICKS(2000)                      /**< Battery level measurement interval (ticks). */
#define MIN_BATTERY_LEVEL                81                                         /**< Minimum simulated battery level. */
#define MAX_BATTERY_LEVEL                100                                        /**< Maximum simulated 7battery level. */
#define BATTERY_LEVEL_INCREMENT          1                                          /**< Increment between each simulated battery level measurement. */
#define MIN_CONN_INTERVAL                MSEC_TO_UNITS(400, UNIT_1_25_MS)           /**< Minimum acceptable connection interval (0.4 seconds). */
#define MAX_CONN_INTERVAL                MSEC_TO_UNITS(650, UNIT_1_25_MS)           /**< Maximum acceptable connection interval (0.65 second). */
#define SLAVE_LATENCY                    0                                          /**< Slave latency. */
#define CONN_SUP_TIMEOUT                 MSEC_TO_UNITS(4000, UNIT_10_MS)            /**< Connection supervisory timeout (4 seconds). */
#define FIRST_CONN_PARAMS_UPDATE_DELAY  APP_TIMER_TICKS(5000)                       /**< Time from initiating event (connect or start of notification) to first time sd_ble_gap_conn_param_update is called (5 seconds). */
#define NEXT_CONN_PARAMS_UPDATE_DELAY   APP_TIMER_TICKS(30000)                      /**< Time between each call to sd_ble_gap_conn_param_update after the first call (30 seconds). */
#define MAX_CONN_PARAMS_UPDATE_COUNT    3                                           /**< Number of attempts before giving up the connection parameter negotiation. */
#define SEC_PARAM_BOND                  1                                           /**< Perform bonding. */
#define SEC_PARAM_MITM                  0                                           /**< Man In The Middle protection not required. */
#define SEC_PARAM_LESC                  0                                           /**< LE Secure Connections not enabled. */
#define SEC_PARAM_KEYPRESS              0                                           /**< Keypress notifications not enabled. */
#define SEC_PARAM_IO_CAPABILITIES       BLE_GAP_IO_CAPS_NONE                        /**< No I/O capabilities. */
#define SEC_PARAM_OOB                   0                                           /**< Out Of Band data not available. */
#define SEC_PARAM_MIN_KEY_SIZE          7                                           /**< Minimum encryption key size. */
#define SEC_PARAM_MAX_KEY_SIZE          16                                          /**< Maximum encryption key size. */
#define DEAD_BEEF                       0xDEADBEEF                                  /**< Value used as error code on stack dump, can be used to identify stack location on stack unwind. */

#define SCHED_MAX_EVENT_DATA_SIZE           APP_TIMER_SCHED_EVENT_DATA_SIZE            /**< Maximum size of scheduler events. */
#ifdef SVCALL_AS_NORMAL_FUNCTION
#define SCHED_QUEUE_SIZE                    20                                         /**< Maximum number of events in the scheduler queue. More is needed in case of Serialization. */
#else
#define SCHED_QUEUE_SIZE                    10                                         /**< Maximum number of events in the scheduler queue. */
#endif
#ifdef RK_CLI
#define ADDR_STRING_LEN         (2 * (BLE_GAP_ADDR_LEN)+6)
#define BLE_UUID_NUS_SERVICE            0x0001                      /**< The UUID of the Nordic UART Service. */
#define NUS_SERVICE_UUID_TYPE   BLE_UUID_TYPE_VENDOR_BEGIN              /**< UUID type for the Nordic UART Service (vendor specific). */
NRF_BLE_SCAN_DEF(m_scan);
#define N_AD_TYPES 4
#define UUID128_SIZE    16  /**< Size of 128 bit UUID. */
#define UUID16_SIZE 2

#define APP_SCHED_EVENT_HEADER_SIZE 8       /**< Size of app_scheduler.event_header_t (only for use inside APP_SCHED_BUF_SIZE()). */
/**@brief Compute number of bytes required to hold the scheduler buffer.
 *
 * @param[in] EVENT_SIZE   Maximum size of events to be passed through the scheduler.
 * @param[in] QUEUE_SIZE   Number of entries in scheduler queue (i.e. the maximum number of events
 *                         that can be scheduled for execution).
 *
 * @return    Required scheduler buffer size (in bytes).
 */
#define APP_SCHED_BUF_SIZE(EVENT_SIZE, QUEUE_SIZE)                                                 \
            (((EVENT_SIZE) + APP_SCHED_EVENT_HEADER_SIZE) * ((QUEUE_SIZE) + 1))
/**@brief Scheduler event handler type. */
typedef void (*app_sched_event_handler_t)(void * p_event_data, uint16_t event_size);
/**@brief Macro for initializing the event scheduler.
 *
 * @details It will also handle dimensioning and allocation of the memory buffer required by the
 *          scheduler, making sure the buffer is correctly aligned.
 *
 * @param[in] EVENT_SIZE   Maximum size of events to be passed through the scheduler.
 * @param[in] QUEUE_SIZE   Number of entries in scheduler queue (i.e. the maximum number of events
 *                         that can be scheduled for execution).
 *
 * @note Since this macro allocates a buffer, it must only be called once (it is OK to call it
 *       several times as long as it is from the same location, e.g. to do a reinitialization).
 */
#define APP_SCHED_INIT(EVENT_SIZE, QUEUE_SIZE)                                                     \
    do                                                                                             \
    {                                                                                              \
        static uint32_t APP_SCHED_BUF[CEIL_DIV(APP_SCHED_BUF_SIZE((EVENT_SIZE), (QUEUE_SIZE)),     \
                                               sizeof(uint32_t))];                                 \
        uint32_t ERR_CODE = app_sched_init((EVENT_SIZE), (QUEUE_SIZE), APP_SCHED_BUF);             \
        APP_ERROR_CHECK(ERR_CODE);                                                                 \
    } while (0)
///**@brief Function for initializing the Scheduler.
// *
// * @details It must be called before entering the main loop.
// *
// * @param[in]   max_event_size   Maximum size of events to be passed through the scheduler.
// * @param[in]   queue_size       Number of entries in scheduler queue (i.e. the maximum number of
// *                               events that can be scheduled for execution).
// * @param[in]   p_evt_buffer   Pointer to memory buffer for holding the scheduler queue. It must
// *                               be dimensioned using the APP_SCHED_BUFFER_SIZE() macro. The buffer
// *                               must be aligned to a 4 byte boundary.
// *
// * @note Normally initialization should be done using the APP_SCHED_INIT() macro, as that will both
// *       allocate the scheduler buffer, and also align the buffer correctly.
// *
// * @retval      NRF_SUCCESS               Successful initialization.
// * @retval      NRF_ERROR_INVALID_PARAM   Invalid parameter (buffer not aligned to a 4 byte
// *                                        boundary).
// */
//uint32_t app_sched_init(uint16_t max_event_size, uint16_t queue_size, void * p_evt_buffer);
/**@brief Function for executing all scheduled events.
 *
 * @details This function must be called from within the main loop. It will execute all events
 *          scheduled since the last time it was called.
 */
void app_sched_execute(void);
/**@brief Function for scheduling an event.
 *
 * @details Puts an event into the event queue.
 *
 * @param[in]   p_event_data   Pointer to event data to be scheduled.
 * @param[in]   event_size     Size of event data to be scheduled.
 * @param[in]   handler        Event handler to receive the event.
 *
 * @return      NRF_SUCCESS on success, otherwise an error code.
 */
uint32_t app_sched_event_put(void const *              p_event_data,
                             uint16_t                  event_size,
                             app_sched_event_handler_t handler);
/**Buffer queue access macros
 *
 * @{ */
/** Initialization of buffer list */
#define BUFFER_LIST_INIT()     \
    do                         \
    {                          \
        buffer_list.rp    = 0; \
        buffer_list.wp    = 0; \
        buffer_list.count = 0; \
    } while (0)
/** Provide status of data list is full or not */
#define BUFFER_LIST_FULL() \
    ((MAX_BUFFER_ENTRIES == buffer_list.count - 1) ? true : false)
/** Provides status of buffer list is empty or not */
#define BUFFER_LIST_EMPTY() \
    ((0 == buffer_list.count) ? true : false)
#define BUFFER_ELEMENT_INIT(i)                 \
    do                                         \
    {                                          \
        buffer_list.buffer[(i)].p_data = NULL; \
    } while (0)

//Tabs end
typedef struct
{
  bool    is_not_empty;                   /**< Indicates that the structure is not empty. */
  uint8_t addr[BLE_GAP_ADDR_LEN];         /**< Device address. */
  char    dev_name[DEVICE_NAME_MAX_SIZE]; /**< Device name. */
  int8_t RSSI_value_RK;  
  uint8_t   uuid_buffer_1[UUID128_SIZE];        /**< Buffer for storing an  UUID128. */
  //    uint8_t   uuid_buffer_2[UUID16_SIZE];        /**< Buffer for storing an  UUID16. */
  //    uint8_t   uuid_buffer_3[UUID128_SIZE];        /**< Buffer for storing an  UUID128. */
  //    uint8_t   uuid_buffer_4[UUID128_SIZE];        /**< Buffer for storing an  UUID128. */
  //    uint8_t   uuid_buffer_5[UUID128_SIZE];        /**< Buffer for storing an  UUID128. */
  uint16_t uuid_len;
  uint8_t uuid_type;
 
}scanned_device_t;
typedef struct
{
  uint8_t * p_data;   /**< Pointer to data. */
  uint16_t  data_len; /**< Length of data. */
} data_t;
scanned_device_t   m_device[DEVICE_TO_FIND_MAX];                 /**< Stores device info from scan data. */
scanned_device_t * scan_device_info_get(void)
{
  return m_device;
}
void scan_device_info_clear(void)
{
  memset(m_device, 0, sizeof(m_device));
}
static void device_to_list_add(ble_gap_evt_adv_report_t const * p_adv_report);
void scan_start(void);
void int_addr_to_hex_str(char * p_result, uint8_t result_len, uint8_t const * const p_addr);
#define RSSI_THRESHOLD -80
static void adv_list_timer_handle(void * p_context);
static bool               m_scanning = false;                           /**< Variable that informs about the ongoing scanning. True when scan is ON. */
#define FOUND_DEVICE_REFRESH_TIME APP_TIMER_TICKS(SCAN_LIST_REFRESH_INTERVAL) /**< Time after which the device list is clean and refreshed. */
BLE_DB_DISCOVERY_ARRAY_DEF(m_db_disc, NRF_SDH_BLE_CENTRAL_LINK_COUNT);  /**< Database discovery module instances. */
#define CENTRAL_SCANNING_LED      BSP_BOARD_LED_0
#define CENTRAL_CONNECTED_LED     BSP_BOARD_LED_1
static void db_discovery_init(void);
static void db_disc_handler(ble_db_discovery_evt_t * p_evt);
//extern ble_nus_t m_nus;
void ble_serv_on_db_disc_evt(ble_db_discovery_evt_t const * p_evt);
//static bool device_uuid_search(ble_gap_evt_adv_report_t const * p_adv_report);
void print_uuid(char * p_result, uint8_t result_len, uint8_t const * const p_uuid, uint8_t size);
typedef struct
{
  uint32_t addr[BLE_GAP_ADDR_LEN];         /**< Device address. */
  char    dev_name[DEVICE_NAME_MAX_SIZE]; /**< Device name. */
  int8_t RSSI_value_RK;
  uint16_t uuid;
}known_list_t; __ALIGN(4)
#define MAX_DEVICE 8
extern known_list_t k_device[MAX_DEVICE];__ALIGN(4)
known_list_t temp_device;
//static bool service_flag = false;
extern uint8_t k_count = 0;
//static uint8_t k_idx = 0;
// Thermometer UUID = {0x1809};
// NUS UUID = {0x9E, 0xCA, 0xDC, 0x24, 0x0E, 0xE5, 0xA9, 0xE0, 0x93, 0xF3, 0xA3, 0xB5, 0x01, 0x00, 0x40, 0x6E};{0x6E400001B5A3F393E0A9E50E24DCCA9E} ;//  //{{0x9E, 0xCA, 0xDC, 0x24, 0x0E, 0xE5, 0xA9, 0xE0, 0x93, 0xF3, 0xA3, 0xB5, 0x00, 0x00, 0x40, 0x6E}}; /**< Used vendor specific UUID. */
//NONIN UUID = {0x1B, 0xC5, 0xD5, 0xA5, 0x02, 0x00, 0x5E, 0x8B, 0xE2, 0x11, 0x5F, 0x0D, 0x00, 0x00, 0xA9, 0x46}
//static ble_uuid128_t m_uuid128[] = {{0x9E, 0xCA, 0xDC, 0x24, 0x0E, 0xE5, 0xA9, 0xE0, 0x93, 0xF3, 0xA3, 0xB5, 0x01, 0x00, 0x40, 0x6E}, {0x1B, 0xC5, 0xD5, 0xA5, 0x02, 0x00, 0x5E, 0x8B, 0xE2, 0x11, 0x5F, 0x0D, 0x00, 0x00, 0xA9, 0x46}};      
//static ble_uuid_t m_uuid16[] = {{0x1809,BLE_UUID_TYPE_BLE }, {0xFEE0, BLE_UUID_TYPE_BLE}, {0x180A, BLE_UUID_TYPE_BLE}};
#define SCAN_INTERVAL             0x00A0                                     /**< Determines scan interval in units of 0.625 millisecond. */
#define SCAN_WINDOW               0x0050                                     /**< Determines scan window in units of 0.625 millisecond. */
#define SCAN_TIMEOUT              0x0000                                     /**< Timout when scanning. 0x0000 disables timeout. */
#define SCAN_REQUEST              0                                          /**< Active scannin is not set. */
#define SCAN_WHITELIST_ONLY       0                                          /**< We will not ignore unknown devices. */
static const ble_gap_scan_params_t m_scan_param =
{
  .extended = 1,
  .report_incomplete_evts = 1,
  .active = SCAN_REQUEST,
  .filter_policy = SCAN_WHITELIST_ONLY,
  .scan_phys = NULL,
  .interval = (uint16_t)SCAN_INTERVAL,
  .window = (uint16_t)SCAN_WINDOW,
  .timeout = SCAN_TIMEOUT
};
static const ble_gap_conn_params_t m_connection_param =
{
  (uint16_t)MIN_CONN_INTERVAL,
  (uint16_t)MAX_CONN_INTERVAL,
  (uint16_t)SLAVE_LATENCY,
  (uint16_t)CONN_SUP_TIMEOUT
};

//Added custom service
#define NOTIFICATION_INTERVAL           APP_TIMER_TICKS(1000)
static void on_cus_evt(ble_cus_t     * p_cus_service, ble_cus_evt_t * p_evt);
BLE_CUS_DEF(m_cus);
APP_TIMER_DEF(m_notification_timer_id);
ble_cus_init_t   cus_init;
////Added HTS service
//BLE_HTS_DEF(m_hts);
//static void on_hts_evt(ble_hts_t * p_hts, ble_hts_evt_t * p_evt);
//#define TEMP_TYPE_AS_CHARACTERISTIC     0                                           /**< Determines if temperature type is given as characteristic (1) or as a field of measurement (0). */
//static bool              m_hts_meas_ind_conf_pending = false;                       /**< Flag to keep track of when an indication confirmation is pending. */
//static sensorsim_cfg_t   m_temp_celcius_sim_cfg;                                    /**< Temperature simulator configuration. */
//static sensorsim_state_t m_temp_celcius_sim_state;                                  /**< Temperature simulator state. */
//static void temperature_measurement_send(void);
//static void hts_sim_measurement(ble_hts_meas_t * p_meas);
//#define BLE_UUID_NONIN_SENSOR_SERVICE 0x70E0 /**< The UUID of the Nordic UART Service. */
//#define BLE_UUID_NONIN_SENSOR_SERVICE_BASE      {{0x1B, 0xC5, 0xD5, 0xA5, 0x02, 0x00, 0x5E, 0x8B, 0xE2, 0x11, 0x5F, 0x0D, 0xE0, 0x70, 0xA9, 0x46}} //NONIN UUID
/* array of UUID to be filtered */
static ble_uuid_t const m_scan_uuid[] =  {{BLE_UUID_NUS_SERVICE,0x03},
{BLE_UUID_HEALTH_THERMOMETER_SERVICE,BLE_UUID_TYPE_BLE},
{BLE_UUID_NONIN_SENSOR_SERVICE,BLE_UUID_TYPE_VENDOR_BEGIN}};
static void connect_to_target(ble_gap_evt_adv_report_t const * p_adv_report);
static bool connect = false;
static void conn_params_init(void);
static void conn_params_error_handler(uint32_t nrf_error);
static void on_conn_params_evt(ble_conn_params_evt_t * p_evt);
#endif
NRF_BLE_GATT_DEF(m_gatt);                                                           /**< GATT module instance. */
NRF_BLE_QWR_DEF(m_qwr);                                                             /**< Context for the Queued Write module.*/
BLE_ADVERTISING_DEF(m_advertising);                                                 /**< Advertising module instance. */

NRF_CLI_UART_DEF(cli_uart,0 , 256, 16);
NRF_CLI_BLE_UART_DEF(cli_ble_uart, &m_gatt, 64, 32);
NRF_CLI_DEF(m_cli_uart, "uart_cli:~$ ", &cli_uart.transport,'\r', 4);
NRF_CLI_DEF(m_ble_cli, "ble_cli:~$ ", &cli_ble_uart.transport,'\r', 8);
static uint16_t  m_conn_handle = BLE_CONN_HANDLE_INVALID;                           /**< Handle of the current connection. */
task_id_t m_ble_console_task_id;
static ble_uuid_t m_adv_uuids[] =                                                   /**< Universally unique service identifiers. */
{
  {BLE_UUID_NUS_SERVICE,            BLE_UUID_TYPE_BLE},
  {BLE_UUID_DEVICE_INFORMATION_SERVICE, BLE_UUID_TYPE_BLE},
 
};
/**@brief Callback function for asserts in the SoftDevice.
*
* @details This function will be called in case of an assert in the SoftDevice.
*
* @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 Assert.
* @warning On assert from the SoftDevice, the system can only recover on reset.
*
* @param[in] line_num   Line number of the failing ASSERT call.
* @param[in] file_name  File name of the failing ASSERT call.
*/
void assert_nrf_callback(uint16_t line_num, const uint8_t * p_file_name)
{
  app_error_handler(DEAD_BEEF, line_num, p_file_name);
}

/**@brief Clear bond information from persistent storage.
*/
static void delete_bonds(void)
{
  ret_code_t err_code;
 
  NRF_LOG_INFO("Erase bonds!");
 
  err_code = pm_peers_delete();
  APP_ERROR_CHECK(err_code);
}

/**@brief Function for starting advertising.
*/
void advertising_start(bool erase_bonds)
{
  if (erase_bonds == true)
  {
    delete_bonds();
    // Advertising is started by PM_EVT_PEERS_DELETE_SUCCEEDED event.
  }
  else
  {
    ret_code_t err_code;
   
    err_code = ble_advertising_start(&m_advertising, BLE_ADV_MODE_FAST);
    APP_ERROR_CHECK(err_code);
  }
}

/**@brief Function for handling Peer Manager events.
*
* @param[in] p_evt  Peer Manager event.
*/
static void pm_evt_handler(pm_evt_t const * p_evt)
{
  pm_handler_on_pm_evt(p_evt);
  pm_handler_flash_clean(p_evt);
 
  switch (p_evt->evt_id)
  {
  case PM_EVT_PEERS_DELETE_SUCCEEDED:
    //If device is in scanning mode don't advertise
    advertising_start(false);
    break;
   
  default:
    break;
  }
}
/**@brief Function for the GAP initialization.
*
* @details This function sets up all the necessary GAP (Generic Access Profile) parameters of the
*          device including the device name, appearance, and the preferred connection parameters.
*/
static void gap_params_init(void)
{
  ret_code_t              err_code;
  ble_gap_conn_params_t   gap_conn_params;
  ble_gap_conn_sec_mode_t sec_mode;
 
  BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode);
 
  err_code = sd_ble_gap_device_name_set(&sec_mode,
                                        (const uint8_t *)DEVICE_NAME,
                                        strlen(DEVICE_NAME));
  APP_ERROR_CHECK(err_code);
 
  memset(&gap_conn_params, 0, sizeof(gap_conn_params));
 
  gap_conn_params.min_conn_interval = MIN_CONN_INTERVAL;
  gap_conn_params.max_conn_interval = MAX_CONN_INTERVAL;
  gap_conn_params.slave_latency     = SLAVE_LATENCY;
  gap_conn_params.conn_sup_timeout  = CONN_SUP_TIMEOUT;
 
  err_code = sd_ble_gap_ppcp_set(&gap_conn_params);
  APP_ERROR_CHECK(err_code);
}
/**@brief Function for handling events from the GATT library. */
void gatt_evt_handler(nrf_ble_gatt_t * p_gatt, nrf_ble_gatt_evt_t const * p_evt)
{
  NRF_LOG_DEBUG("ATT MTU exchange completed. central 0x%x peripheral 0x%x",
                p_gatt->att_mtu_desired_central,
                p_gatt->att_mtu_desired_periph);
}

/**@brief Function for initializing the GATT module.
*/
static void gatt_init(void)
{
  ret_code_t err_code = nrf_ble_gatt_init(&m_gatt, gatt_evt_handler);
  APP_ERROR_CHECK(err_code);
}

/**@brief Function for handling Queued Write Module errors.
*
* @details A pointer to this function will be passed to each service which may need to inform the
*          application about an error.
*
* @param[in]   nrf_error   Error code containing information about what went wrong.
*/
static void nrf_qwr_error_handler(uint32_t nrf_error)
{
  APP_ERROR_HANDLER(nrf_error);
}

/**@brief Function for initializing services that will be used by the application.
*
* @details Initialize the Heart Rate, Battery and Device Information services.
*/
static void services_init(void)
{
  ret_code_t         err_code;
  ble_dis_init_t     dis_init;
  nrf_ble_qwr_init_t qwr_init = {0};
  //   ble_hts_init_t     hts_init;
  // Initialize Queued Write Module.
  qwr_init.error_handler = nrf_qwr_error_handler;
 
  err_code = nrf_ble_qwr_init(&m_qwr, &qwr_init);
  APP_ERROR_CHECK(err_code);
 
  // Initialize Device Information Service.
  memset(&dis_init, 0, sizeof(dis_init));
 
  ble_srv_ascii_to_utf8(&dis_init.manufact_name_str, (char *)MANUFACTURER_NAME);
 
  dis_init.dis_char_rd_sec = SEC_OPEN;
 
  err_code = ble_dis_init(&dis_init);
  APP_ERROR_CHECK(err_code);
 
  /*  RK code to initialize the nonin services used by the application.*/
  ble_uuid_t            ble_uuid;
  BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_HEALTH_THERMOMETER_SERVICE);
 
  //    err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, &ble_uuid, &p_hts->service_handle);
  //    if (err_code != NRF_SUCCESS)
  //    {
  //        APP_ERROR_CHECK(err_code);
  //    }
  err_code = ble_db_discovery_evt_register(&ble_uuid);
  if (err_code == NRF_SUCCESS)
  {
    APP_ERROR_CHECK(err_code);
  }
  if(err_code == NRF_ERROR_NULL)
  {
    NRF_LOG_INFO("error null pointer supplied\n\r");
  }
  if(err_code == NRF_ERROR_INVALID_STATE)
  {
    NRF_LOG_INFO("error NRF_ERROR_INVALID_STATE\n\r");
  }
  if(err_code == NRF_ERROR_NO_MEM)
  {
    NRF_LOG_INFO("error NRF_ERROR_NO_MEM\n\r");
  }
 
 
  // Add Nonin Oxy sensor Service UUID BASE
  ble_uuid128_t base_uuid = BLE_UUID_NONIN_SENSOR_SERVICE_BASE;
 
  // Initialize CUS Service init structure to zero.
  memset(&cus_init, 0, sizeof(cus_init));
  cus_init.evt_handler = on_cus_evt;
 
  if (&m_cus == NULL || &cus_init == NULL)
  {
    NRF_LOG_INFO("NRF_ERROR_NULL");
  }
 
 
  //    ble_add_char_params_t add_char_params;
 
  // Initialize service structure
  m_cus.evt_handler               = cus_init.evt_handler;
  m_cus.conn_handle               = BLE_CONN_HANDLE_INVALID;
 
  err_code =  sd_ble_uuid_vs_add(&base_uuid,  &m_cus.uuid_type);
  if (err_code == NRF_ERROR_INVALID_ADDR)
  {
    NRF_LOG_INFO("error = NRF_ERROR_INVALID_ADDR\n\r");
  }
  if (err_code == NRF_ERROR_NO_MEM)
  {
    NRF_LOG_INFO("error = NRF_ERROR_NO_MEM\n\r");
  }
 
  ble_uuid.uuid = BLE_UUID_NONIN_SENSOR_SERVICE;
  ble_uuid.type = m_cus.uuid_type;
  err_code = ble_db_discovery_evt_register(&ble_uuid);
  if (err_code == NRF_SUCCESS)
  {
    APP_ERROR_CHECK(err_code);
  }
  if(err_code == NRF_ERROR_NULL)
  {
    NRF_LOG_INFO("error null pointer supplied\n\r");
  }
  if(err_code == NRF_ERROR_INVALID_STATE)
  {
    NRF_LOG_INFO("error NRF_ERROR_INVALID_STATE\n\r");
  }
  if(err_code == NRF_ERROR_NO_MEM)
  {
    NRF_LOG_INFO("error NRF_ERROR_NO_MEM\n\r");
  }
 
  // Add the Custom Service
  //    err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, &ble_uuid, &p_cus->service_handle);
  //    if (err_code != NRF_SUCCESS)
  //    {
  //       
  //        return err_code;
  //    }
  ////         // Initialize CUS Service init structure to zero.
  //        memset(&cus_init, 0, sizeof(cus_init));
  //        cus_init.evt_handler = on_cus_evt;
 
  //        BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cus_init.custom_value_char_attr_md.cccd_write_perm);
  //        BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cus_init.custom_value_char_attr_md.read_perm);
  //        BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cus_init.custom_value_char_attr_md.write_perm);
 
  //        err_code = ble_cus_init(&m_cus, &cus_init);
  //        APP_ERROR_CHECK(err_code);
  //     
  // APP_ERROR_CHECK(err_code);
 
  //         // Initialize Health Thermometer Service
  //    memset(&hts_init, 0, sizeof(hts_init));
  //
  //    hts_init.evt_handler                 = on_hts_evt;
  //    hts_init.temp_type_as_characteristic = TEMP_TYPE_AS_CHARACTERISTIC;
  //    hts_init.temp_type                   = BLE_HTS_TEMP_TYPE_BODY;
  //
  //    // Here the sec level for the Health Thermometer Service can be changed/increased.
  //    hts_init.ht_meas_cccd_wr_sec = SEC_JUST_WORKS;
  //    hts_init.ht_type_rd_sec      = SEC_OPEN;
  //
  //    err_code = ble_hts_init(&m_hts, &hts_init);
  //    APP_ERROR_CHECK(err_code);
  //   
 
}
/**@brief Function for handling advertising events.
*
* @details This function will be called for advertising events which are passed to the application.
*
* @param[in] ble_adv_evt  Advertising event.
*/
static void on_adv_evt(ble_adv_evt_t ble_adv_evt)
{
  ret_code_t err_code;
 
  switch (ble_adv_evt)
  {
  case BLE_ADV_EVT_FAST:
    //NRF_LOG_RAW_INFO("Fast advertising.\r");
    err_code = bsp_indication_set(BSP_INDICATE_ADVERTISING);
    APP_ERROR_CHECK(err_code);
    break;
   
  case BLE_ADV_EVT_IDLE:
    nrf_pwr_mgmt_run();
    break;
   
  default:
    break;
  }
}

/**@brief Function for handling BLE events.
*
* @param[in]   p_ble_evt   Bluetooth stack event.
* @param[in]   p_context   Unused.
*/
static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
{
  ret_code_t err_code;
 
  // For readability
  ble_gap_evt_t const        * p_gap_evt   = &p_ble_evt->evt.gap_evt;
  //    nrf_ble_scan_t                 * p_scan_ctx  = (nrf_ble_scan_t *)p_context;
  //    ble_gap_evt_adv_report_t const * p_adv_report = &p_ble_evt->evt.gap_evt.params.adv_report;
  //ble_db_discovery_t * p_db_discovery = (ble_db_discovery_t *)p_context;
 
  switch (p_ble_evt->header.evt_id)
  {
#ifdef RK_CLI
  case BLE_GAP_EVT_ADV_REPORT:
    {
     
      //bool res = device_uuid_search(&p_gap_evt->params.adv_report);
     
      device_to_list_add(&p_gap_evt->params.adv_report);       
     
    } break;
    //  case BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP:
    //      {
    //        //NRF_LOG_INFO("Discovered service for: %x %x %x\n",p_gap_evt->params.adv_report.peer_addr.addr[0], p_gap_evt->params.adv_report.peer_addr.addr[1], p_gap_evt->params.adv_report.peer_addr.addr[5] );
    //   //     on_primary_srv_discovery_rsp(p_db_discovery, &(p_ble_evt->evt.gattc_evt));
    //      }
    break;
#endif
  case BLE_GAP_EVT_CONNECTED:
    {
      NRF_LOG_INFO("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;
      err_code = nrf_ble_qwr_conn_handle_assign(&m_qwr, m_conn_handle);
      APP_ERROR_CHECK(err_code);
     
      nrf_cli_ble_uart_config_t config = { .conn_handle = m_conn_handle };
     
      err_code = nrf_cli_init(&m_ble_cli, &config, true, true, NRF_LOG_SEVERITY_INFO);
      APP_ERROR_CHECK(nrf_cli_task_create(&m_ble_cli));
      NRF_LOG_INFO("error code after connection = %d\n", err_code);
     
      APP_ERROR_CHECK(err_code);
     
     
      //  err_code =  sd_ble_gattc_primary_services_discover(conn_handle,0x0001,NULL);
      do
      {
        err_code = ble_db_discovery_start(&m_db_disc[p_gap_evt->conn_handle],
                                          p_gap_evt->conn_handle);
        if (err_code == NRF_SUCCESS)
        {
          NRF_LOG_INFO("discovery started :busy staus\n");
          //  NRF_LOG_INFO("service uuid found = %d\n\r", m_db_disc[p_gap_evt->conn_handle].srv_count );
          APP_ERROR_CHECK(err_code);
        }
       
      }while(err_code == NRF_ERROR_BUSY);
     
     
      // Update LEDs status and check whether it is needed to look for more
      // peripherals to connect to.
      bsp_board_led_on(CENTRAL_CONNECTED_LED);
      if (ble_conn_state_central_conn_count() == NRF_SDH_BLE_CENTRAL_LINK_COUNT)
      {
        bsp_board_led_off(CENTRAL_SCANNING_LED);
      }
      else
      {
        // Resume scanning.
        bsp_board_led_on(CENTRAL_SCANNING_LED);
        scan_start();
      }
     
    } break;
   
  case BLE_GAP_EVT_DISCONNECTED:
    {
      connect = false;
      NRF_LOG_INFO("Disconnected, reason %d.",
                   p_ble_evt->evt.gap_evt.params.disconnected.reason);
      m_conn_handle = BLE_CONN_HANDLE_INVALID;
      (void)nrf_cli_uninit(&m_ble_cli);
     
      if (ble_conn_state_central_conn_count() == 0)
      {
        // Turn off the LED that indicates the connection.
        bsp_board_led_off(CENTRAL_CONNECTED_LED);
      }
     
      // Start scanning.
      if (m_scanning)
      {
        scan_start();
      }
     
      // Turn on the LED for indicating scanning.
      bsp_board_led_on(CENTRAL_SCANNING_LED);
    }break;
   
  case BLE_GAP_EVT_PHY_UPDATE_REQUEST:
    {
      NRF_LOG_DEBUG("PHY update request.");
      ble_gap_phys_t const phys =
      {
        .rx_phys = BLE_GAP_PHY_AUTO,
        .tx_phys = BLE_GAP_PHY_AUTO,
      };
      err_code = sd_ble_gap_phy_update(p_ble_evt->evt.gap_evt.conn_handle, &phys);
      APP_ERROR_CHECK(err_code);
    } break;
   
  case BLE_GATTC_EVT_TIMEOUT:
    // Disconnect on GATT Client timeout event.
    NRF_LOG_DEBUG("GATT Client Timeout.");
    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;
   
  case BLE_GATTS_EVT_TIMEOUT:
    // Disconnect on GATT Server timeout event.
    NRF_LOG_DEBUG("GATT Server Timeout.");
    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;
   
   
    //    case BLE_DB_DISCOVERY_COMPLETE:
    //      {
    //            
    //           /* service available indication to known list*/
    //            memcpy(k_device[k_idx].addr,p_adv_report->peer_addr.addr,sizeof(p_adv_report->peer_addr.addr));
    //            k_device[k_idx].is_not_empty = true;
    //            k_idx++;
    //             if (connect == true)
    //            {
    //            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);
    //           }
    //            if (err_code == NRF_SUCCESS)
    //            {
    //              connect = false;
    //             // NRF_LOG_INFO("I Disconnected it\n\r");
    //            }
    //            }
    //      }
    //      break;
   
    //  
  default:
    // No implementation needed.
    break;
  }
}
/**@brief Function for the SoftDevice initialization.
*
* @details This function initializes the SoftDevice and the BLE event interrupt.
*/
static void ble_stack_init(void)
{
  ret_code_t err_code;
 
  err_code = nrf_sdh_enable_request();
  APP_ERROR_CHECK(err_code);
 
  // Configure the BLE stack using the default settings.
  // Fetch the start address of the application RAM.
  uint32_t ram_start = 0;
  err_code = nrf_sdh_ble_default_cfg_set(APP_BLE_CONN_CFG_TAG, &ram_start);
  APP_ERROR_CHECK(err_code);
 
  // Enable BLE stack.
  err_code = nrf_sdh_ble_enable(&ram_start);
  APP_ERROR_CHECK(err_code);
 
  // Register a handler for BLE events.
  NRF_SDH_BLE_OBSERVER(m_ble_observer, APP_BLE_OBSERVER_PRIO, ble_evt_handler, NULL);
}

/**@brief Function for handling events from the BSP module.
*
* @param[in]   event   Event generated by button press.
*/
void bsp_event_handler(bsp_event_t event)
{
  ret_code_t err_code;
 
  switch (event)
  {
  case BSP_EVENT_SLEEP:
    nrf_pwr_mgmt_shutdown(NRF_PWR_MGMT_SHUTDOWN_GOTO_SYSOFF);
    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(&m_advertising);
      if (err_code != NRF_ERROR_INVALID_STATE)
      {
        APP_ERROR_CHECK(err_code);
      }
    }
    break;
   
  default:
    break;
  }
}

/**@brief Function for the Peer Manager initialization.
*/
static void peer_manager_init(void)
{
  ble_gap_sec_params_t sec_param;
  ret_code_t           err_code;
 
  err_code = pm_init();
  APP_ERROR_CHECK(err_code);
 
  memset(&sec_param, 0, sizeof(ble_gap_sec_params_t));
 
  // Security parameters to be used for all security procedures.
  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;
  sec_param.kdist_own.enc  = 1;
  sec_param.kdist_own.id   = 1;
  sec_param.kdist_peer.enc = 1;
  sec_param.kdist_peer.id  = 1;
 
  err_code = pm_sec_params_set(&sec_param);
  APP_ERROR_CHECK(err_code);
 
  err_code = pm_register(pm_evt_handler);
  APP_ERROR_CHECK(err_code);
}

/**@brief Function for initializing the Advertising functionality.
*/
static void advertising_init(void)
{
  ret_code_t             err_code;
  ble_advertising_init_t init;
 
  memset(&init, 0, sizeof(init));
 
  init.advdata.name_type               = BLE_ADVDATA_FULL_NAME;
  init.advdata.include_appearance      = true;
  init.advdata.flags                   = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;
  init.advdata.uuids_complete.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]);
  init.advdata.uuids_complete.p_uuids  = m_adv_uuids;
 
  init.config.ble_adv_fast_enabled  = true;
  init.config.ble_adv_fast_interval = APP_ADV_INTERVAL;
  init.config.ble_adv_fast_timeout  = APP_ADV_DURATION;
 
  init.evt_handler = on_adv_evt;
 
  err_code = ble_advertising_init(&m_advertising, &init);
  APP_ERROR_CHECK(err_code);
 
  ble_advertising_conn_cfg_tag_set(&m_advertising, APP_BLE_CONN_CFG_TAG);
}
#ifdef RK_CLI
/**@brief Function for handling an event from the Connection Parameters Module.
*
* @details This function will be called for all events in the Connection Parameters Module
*          which are passed to the application.
*
* @note All this function does is to disconnect. This could have been done by simply setting
*       the disconnect_on_fail config parameter, but instead we use the event handler
*       mechanism to demonstrate its use.
*
* @param[in] p_evt  Event received from the Connection Parameters Module.
*/
static void on_conn_params_evt(ble_conn_params_evt_t * p_evt)
{
  uint32_t err_code;
 
  if (p_evt->evt_type == BLE_CONN_PARAMS_EVT_FAILED)
  {
    err_code = sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_CONN_INTERVAL_UNACCEPTABLE);
    APP_ERROR_CHECK(err_code);
  }
}

/**@brief Function for handling errors from the Connection Parameters module.
*
* @param[in] nrf_error  Error code containing information about what went wrong.
*/
static void conn_params_error_handler(uint32_t nrf_error)
{
  APP_ERROR_HANDLER(nrf_error);
}

/**@brief Function for initializing the Connection Parameters module.
*/
static void conn_params_init(void)
{
  uint32_t               err_code;
  ble_conn_params_init_t cp_init;
 
  memset(&cp_init, 0, sizeof(cp_init));
 
  cp_init.p_conn_params                  = NULL;
  cp_init.first_conn_params_update_delay = FIRST_CONN_PARAMS_UPDATE_DELAY;
  cp_init.next_conn_params_update_delay  = NEXT_CONN_PARAMS_UPDATE_DELAY;
  cp_init.max_conn_params_update_count   = MAX_CONN_PARAMS_UPDATE_COUNT;
  cp_init.start_on_notify_cccd_handle    = BLE_GATT_HANDLE_INVALID;
  cp_init.disconnect_on_fail             = false;
  cp_init.evt_handler                    = on_conn_params_evt;
  cp_init.error_handler                  = conn_params_error_handler;
 
  err_code = ble_conn_params_init(&cp_init);
  APP_ERROR_CHECK(err_code);
}
static void connect_to_target(ble_gap_evt_adv_report_t const * p_adv_report)
{
  // For readability.
  ble_gap_addr_t const        * p_addr        = &p_adv_report->peer_addr;
  ret_code_t             err_code;
  scan_evt_t scan_evt;
 
  nrf_ble_scan_stop();
  // NRF_LOG_INFO("addr = %x %x %x\n\r",p_addr->addr[0], p_addr->addr[1], p_addr->addr[5] );
  memset(&scan_evt, 0, sizeof(scan_evt));
 
  // Establish connection.
  err_code = sd_ble_gap_connect(p_addr,
                                &m_scan_param,
                                &m_connection_param,
                                APP_BLE_CONN_CFG_TAG);
 
  if (err_code == NRF_SUCCESS)
  {
    connect = true;
  }
  else if(err_code == NRF_ERROR_INVALID_ADDR)
  {
    NRF_LOG_INFO("NRF_ERROR_INVALID_ADDR failed\n\r");
  }
  else if(err_code == NRF_ERROR_INVALID_PARAM)
  {
    NRF_LOG_INFO("NRF_ERROR_INVALID_PARAM failed\n\r");
  }
  else if(err_code == NRF_ERROR_NOT_FOUND)
  {
    NRF_LOG_INFO("NRF_ERROR_NOT_FOUND failed\n\r");
  }
  else if (err_code == NRF_ERROR_INVALID_STATE)
  {
    NRF_LOG_INFO("NRF_ERROR_INVALID_STATE failed\n\r");
  }
  else if (err_code == BLE_ERROR_GAP_INVALID_BLE_ADDR)
  {
    NRF_LOG_INFO("BLE_ERROR_GAP_INVALID_BLE_ADDR failed\n\r");
  }
  else if (err_code == NRF_ERROR_CONN_COUNT)
  {
    //    NRF_LOG_INFO("NRF_ERROR_CONN_COUNT failed\n\r");
  }
  else if (err_code == NRF_ERROR_RESOURCES)
  {
    NRF_LOG_INFO("NRF_ERROR_RESOURCES failed\n\r");
  }
  else if (err_code == NRF_ERROR_NOT_SUPPORTED)
  {
    NRF_LOG_INFO("NRF_ERROR_NOT_SUPPORTED failed\n\r");
  }
 
  scan_evt.scan_evt_id                    = NRF_BLE_SCAN_EVT_CONNECTING_ERROR;
  scan_evt.params.connecting_err.err_code = err_code;
 
  NRF_LOG_DEBUG("Connection status: %d", err_code);
 
 
  nrf_ble_scan_start(&m_scan);   
}
/**@brief Function for handling the Custom Service Service events.
*
* @details This function will be called for all Custom Service events which are passed to
*          the application.
*
* @param[in]   p_cus_service  Custom Service structure.
* @param[in]   p_evt          Event received from the Custom Service.
*
*/
static void on_cus_evt(ble_cus_t     * p_cus_service,
                       ble_cus_evt_t * p_evt)
{
  ret_code_t err_code;
 
  switch(p_evt->evt_type)
  {
  case BLE_CUS_EVT_NOTIFICATION_ENABLED:
   
    err_code = app_timer_start(m_notification_timer_id, NOTIFICATION_INTERVAL, NULL);
    APP_ERROR_CHECK(err_code);
    break;
   
  case BLE_CUS_EVT_NOTIFICATION_DISABLED:
    // Stop the application timer that is triggering the notifications
    err_code = app_timer_stop(m_notification_timer_id);
    APP_ERROR_CHECK(err_code);
    break;
   
  case BLE_CUS_EVT_CONNECTED:
    break;
   
  case BLE_CUS_EVT_DISCONNECTED:
    break;
  case BLE_CUS_EVT_SERVO_CTR_VALUE_RECEIVED:
    break;   
   
  default:
    // No implementation needed.
    break;
  }
}
void ble_serv_on_db_disc_evt(ble_db_discovery_evt_t const * p_evt)
{
  // Check if the Led Button Service was discovered.
 
  //      if (p_evt->evt_type == BLE_DB_DISCOVERY_COMPLETE &&
  //        p_evt->params.discovered_db.srv_uuid.uuid == BLE_UUID_NUS_SERVICE)
  ret_code_t err_code;
 
  for (uint8_t i =0; i < sizeof(m_scan_uuid)/sizeof(m_scan_uuid[0]); i++)
  {
   
    //     if (p_evt->evt_type == BLE_DB_DISCOVERY_COMPLETE &&
    //        p_evt->params.discovered_db.srv_uuid.uuid == m_scan_uuid[i].uuid)
    if (p_evt->evt_type == BLE_DB_DISCOVERY_COMPLETE &&
        p_evt->params.discovered_db.srv_uuid.uuid == m_scan_uuid[i].uuid &&
          p_evt->params.discovered_db.srv_uuid.type == m_scan_uuid[i].type)
    {
      NRF_LOG_INFO("Service available:%x \n\r", p_evt->params.discovered_db.srv_uuid.uuid);
      //      service_flag = true;
     
      // move device to known device list - copy MAC ID and UUID
      if (k_count < DEVICE_TO_FIND_MAX)
      {
        for (uint8_t i = 0; i < k_count; i++)
        {
          if (memcmp(temp_device.addr,k_device[i].addr,sizeof(temp_device.addr)) == 0)
          {
            return;
          }
        }
        memcpy(k_device[k_count].addr, temp_device.addr, sizeof(temp_device.addr));
        memcpy(&k_device[k_count].RSSI_value_RK, &temp_device.RSSI_value_RK,sizeof(temp_device.RSSI_value_RK));
        k_device[k_count].uuid = p_evt->params.discovered_db.srv_uuid.uuid;
        k_count++;
      }
      break;
    }
   
   
  }
 
  if (connect == true)
  {
    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);
    }
    if (err_code == NRF_SUCCESS)
    {
      connect = false;
      NRF_LOG_INFO("Disconnected after discovery\n\r");
    }
  }
}
/**@brief Function for handling database discovery events.
*
* @details This function is a callback function to handle events from the database discovery module.
*          Depending on the UUIDs that are discovered, this function forwards the events
*          to their respective services.
*
* @param[in] p_event  Pointer to the database discovery event.
*/
static void db_disc_handler(ble_db_discovery_evt_t * p_evt)
{
  // NRF_LOG_INFO("call to ble_serv_on_db_disc_evt for instance %d and link 0x%x!",
  //                  p_evt->conn_handle,
  //                  p_evt->conn_handle);
 
 
  ble_serv_on_db_disc_evt( p_evt);
}

/** @brief Database discovery initialization.
*/
static void db_discovery_init(void)
{
  ret_code_t err_code = ble_db_discovery_init(db_disc_handler);
  APP_ERROR_CHECK(err_code);
}
bool is_scanning(void)
{
  return m_scanning;
}
/**@brief Function for handling the adv_list_timer event, which refreshes the connectable devices.
*/
static void adv_list_timer_handle(void * p_context)
{
  if (is_scanning())
  {
    scan_device_info_clear();
  }
}
#if 0
static bool device_uuid_search(ble_gap_evt_adv_report_t const * p_adv_report)
{
  uint8_t  idx             = 0;
  uint16_t dev_name_offset = 0;
  uint16_t field_len;
  data_t   adv_data;
  int8_t peripheral_rssi = p_adv_report->rssi;
 
  // Initialize advertisement report for parsing
  adv_data.p_data   = (uint8_t *)p_adv_report->data.p_data;
  adv_data.data_len = p_adv_report->data.len;
 
  for ( idx = 0; idx < DEVICE_TO_FIND_MAX; idx++)
  {
    // If address is duplicated(already in the list), then return.
    if (memcmp(p_adv_report->peer_addr.addr,
               m_device[idx].addr,
               sizeof(p_adv_report->peer_addr.addr)) == 0)
    {
      /* store rssi value */
      memcpy(&m_device[idx].RSSI_value_RK,
             &p_adv_report->rssi,
             sizeof(p_adv_report->rssi));
      return true;
    }
  }
 
  // Device is not in the list.
  for (idx = 0; idx < DEVICE_TO_FIND_MAX; idx++)
  {
    if (!m_device[idx].is_not_empty && (peripheral_rssi > RSSI_THRESHOLD)) // We find an empty entry in the list
    {
     
      uint16_t        data_offset = 0;
      uint8_t         ad_types[N_AD_TYPES];
      uint8_t       * p_parsed_uuid;
      uint16_t        parsed_uuid_len = adv_data.data_len;
      uint8_t uuid_type;
      uint8_t raw_uuid_len;
      ad_types[0] = BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_COMPLETE;
      ad_types[1] = BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_MORE_AVAILABLE;
      ad_types[2] = BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_COMPLETE;
      ad_types[3] = BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_MORE_AVAILABLE;
     
     
      for (uint8_t i = 0; (i < N_AD_TYPES) && (data_offset == 0); i++)
      {
        parsed_uuid_len = ble_advdata_search(adv_data.p_data, adv_data.data_len, &data_offset, ad_types[i]);
       
        if (data_offset != 0)
        {
          uuid_type = ad_types[i];
        }
      }
     
     
      if (data_offset == 0)
      {
       
        //           memcpy(k_device[0].addr,
        //            p_adv_report->peer_addr.addr,
        //            sizeof(p_adv_report->peer_addr.addr));
        //             /* store rssi value */
        //            memcpy(&m_device[idx].RSSI_value_RK,
        //                   &p_adv_report->rssi,
        //                   sizeof(p_adv_report->rssi));
        //             m_device[idx].is_not_empty = true; //Validating the list record
       
        return false;
      }
     
     
     
      p_parsed_uuid = &adv_data.p_data[data_offset]; //The UUID we found
      //  if (parsed_uuid_len != 0)
      //            // Verify if any UUID matches the given UUID.
      if (uuid_type == BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_COMPLETE || uuid_type == BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_MORE_AVAILABLE)
      {
        raw_uuid_len = UUID128_SIZE;
       
      }
      else if(uuid_type == BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_COMPLETE || uuid_type == BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_MORE_AVAILABLE)
      {
        raw_uuid_len = UUID16_SIZE;
       
      }
      //   for (uint16_t list_offset = 0; list_offset < parsed_uuid_len; lisraw_uuid_lent_offset += raw_uuid_len)
      //   {
     
      if (raw_uuid_len == UUID128_SIZE)
      {
       
        for (uint8_t ele = 0; ele < sizeof(m_uuid128); ele++)
        {              
          if ( memcmp(p_parsed_uuid,  &m_uuid128->uuid128[ele], raw_uuid_len) == 0)
          {
            NRF_LOG_INFO("matched uuid128 %x\r\n", m_uuid128->uuid128[ele]);
          }
        }
      }
      else
      {
        for (uint8_t ele = 0; ele < sizeof(m_uuid16); ele++)
        {
          //                  for (uint8_t id = 0; id <parsed_uuid_len; id =+ raw_uuid_len)
          //                  {
          // NRF_LOG_INFO("uuid addr %x\r\n", &p_parsed_uuid[ele]);
          if ( memcmp(&p_parsed_uuid[id],  &m_uuid16[ele], raw_uuid_len) == 0)
          {
            NRF_LOG_INFO("matched uuid16 %x\r\n", m_uuid16[ele].uuid);
          }
          //                  }
        }
      }
      //   }
      m_device[idx].is_not_empty = true; //Validating the list record
     
     
      //Copy the UUID to our list of devices
      memset(m_device[idx].uuid_buffer_1,0,UUID128_SIZE);
      memcpy(m_device[idx].uuid_buffer_1, p_parsed_uuid, parsed_uuid_len);
      // NRF_LOG_INFO("uuid - %x uuid_buff = %x \n", p_parsed_uuid[0], m_device[idx].uuid_buffer_1[0]);
      memcpy(&m_device[idx].uuid_len, &parsed_uuid_len, sizeof(parsed_uuid_len));
      memcpy(&m_device[idx].uuid_type, &uuid_type, sizeof(uuid_type));
     
      memcpy(m_device[idx].addr,
             p_adv_report->peer_addr.addr,
             sizeof(p_adv_report->peer_addr.addr));
      /* store rssi value */
      memcpy(&m_device[idx].RSSI_value_RK,
             &p_adv_report->rssi,
             sizeof(p_adv_report->rssi));
     
      // Search for advertising names.
      field_len = ble_advdata_search(adv_data.p_data,
                                     adv_data.data_len,
                                     &dev_name_offset,
                                     BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME);
     
      if (field_len == 0)
      {
        field_len = ble_advdata_search(adv_data.p_data,
                                       adv_data.data_len,
                                       &dev_name_offset,
                                       BLE_GAP_AD_TYPE_SHORT_LOCAL_NAME);
        // If name is not found, then return.
        if (field_len == 0)
        {
          return true;
        }
      }
     
      memcpy(m_device[idx].dev_name, &adv_data.p_data[dev_name_offset], field_len);        
      m_device[idx].dev_name[field_len] = 0;
     
     
     
      //        NRF_LOG_INFO("matched id = %x %x\n", raw_uuid->uuid128[0], m_device[idx].uuid_buffer_1[0] );
      //        if (m_device[idx].uuid_buffer_1[0] == raw_uuid->uuid128[0])
      //        {
      //            NRF_LOG_INFO("matched id = %.2x\n", m_device[idx].uuid_buffer_1[0] );
      //        }
      //    }
      // Verify if any UUID matches the given UUID.
      //           if (uuid_type == BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_COMPLETE || uuid_type == BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_MORE_AVAILABLE)
      //           {
      //             raw_uuid_len = UUID128_SIZE;
      //             raw_uuid = (uint8_t *)m_uuid128;
      //           }
      //           else if(uuid_type == BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_COMPLETE || uuid_type == BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_MORE_AVAILABLE)
      //           {
      //             raw_uuid_len = UUID16_SIZE;
      //             raw_uuid = (uint8_t *)m_uuid16;
      //           }
      //    for (uint16_t list_offset = 0; list_offset < parsed_uuid_len; list_offset += raw_uuid_len)
      //    {
      //       
      //        if ( memcmp(p_parsed_uuid, raw_uuid, raw_uuid_len))
      //        {
      //            NRF_LOG_INFO("matched uuid);
      //        }
      //    }
      //   
      return true;  
    }
   
   
  }
  return true;
}
#endif

/**@brief Function for searching for a device name and adding it to a dynamic command.
*
* @details Use this function to parse the received advertising data and to find a given
* name in them either as 'complete_local_name' or as 'short_local_name'.
*
* @param[in]   p_adv_report   Advertising data to parse.
*/
static void device_to_list_add(ble_gap_evt_adv_report_t const * p_adv_report)
{
  uint8_t  idx             = 0;
  uint16_t dev_name_offset = 0;
  uint16_t field_len;
  data_t   adv_data;
  int8_t peripheral_rssi = p_adv_report->rssi;
  // Initialize advertisement report for parsing
  adv_data.p_data   = (uint8_t *)p_adv_report->data.p_data;
  adv_data.data_len = p_adv_report->data.len;
 
 
  for ( idx = 0; idx < DEVICE_TO_FIND_MAX; idx++)
  {
    // If address is duplicated, then return.
    if (memcmp(p_adv_report->peer_addr.addr,
               m_device[idx].addr,
               sizeof(p_adv_report->peer_addr.addr)) == 0)
    {
      /* update rssi value */
      memcpy(&m_device[idx].RSSI_value_RK,
             &p_adv_report->rssi,
             sizeof(p_adv_report->rssi));
      return;
    }
  }
 
  // Add device data if an empty record is found.
  for (idx = 0; idx < DEVICE_TO_FIND_MAX; idx++)
  {
    if (!m_device[idx].is_not_empty)
    {
      if (peripheral_rssi > RSSI_THRESHOLD)
      {
        /* store peer address */
        memcpy(m_device[idx].addr,
               p_adv_report->peer_addr.addr,
               sizeof(p_adv_report->peer_addr.addr));
       
        /* store rssi value */
        memcpy(&m_device[idx].RSSI_value_RK,
               &p_adv_report->rssi,
               sizeof(p_adv_report->rssi));
       
        m_device[idx].is_not_empty = true;
       
        //connect to target
       
        //            if (p_adv_report->type.connectable && p_adv_report->peer_addr.addr[0] == 0xAB  )
        if (p_adv_report->type.connectable && connect == false )
        {
          connect_to_target(p_adv_report);
         
          //              /* store peer address */
          memcpy(m_device[idx].addr,
                 p_adv_report->peer_addr.addr,
                 sizeof(p_adv_report->peer_addr.addr));
         
          /* Copy MAC ID and RSSI to known device list */
          memcpy(temp_device.addr,
                 p_adv_report->peer_addr.addr,
                 sizeof(p_adv_report->peer_addr.addr));
         
          memcpy(&temp_device.RSSI_value_RK,
                 &p_adv_report->rssi,
                 sizeof(p_adv_report->rssi));
         
        }
        // Search for advertising names.
        field_len = ble_advdata_search(adv_data.p_data,
                                       adv_data.data_len,
                                       &dev_name_offset,
                                       BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME);
       
        if (field_len == 0)
        {
          field_len = ble_advdata_search(adv_data.p_data,
                                         adv_data.data_len,
                                         &dev_name_offset,
                                         BLE_GAP_AD_TYPE_SHORT_LOCAL_NAME);
          // If name is not found, then return.
          if (field_len == 0)
          {
            return;
          }
        }
       
        memcpy(m_device[idx].dev_name, &adv_data.p_data[dev_name_offset], field_len);        
        m_device[idx].dev_name[field_len] = 0;
       
      }
      return;
     
    }
   
  }
}

/**@brief Function for handling Scanning Module events.
*/
static void scan_evt_handler(scan_evt_t const * p_scan_evt)
{
  ret_code_t err_code;
 
  switch(p_scan_evt->scan_evt_id)
  {
  case NRF_BLE_SCAN_EVT_CONNECTING_ERROR:
    {
      err_code = p_scan_evt->params.connecting_err.err_code;
      APP_ERROR_CHECK(err_code);
    } break;
   
  case NRF_BLE_SCAN_EVT_CONNECTED:
    {
      ble_gap_evt_connected_t const * p_connected =
        p_scan_evt->params.connected.p_connected;
      // Scan is automatically stopped by the connection.
      NRF_LOG_INFO("Connecting to target %02x%02x%02x%02x%02x%02x",
                   p_connected->peer_addr.addr[0],
                   p_connected->peer_addr.addr[1],
                   p_connected->peer_addr.addr[2],
                   p_connected->peer_addr.addr[3],
                   p_connected->peer_addr.addr[4],
                   p_connected->peer_addr.addr[5]
                     );
    } break;
   
  case NRF_BLE_SCAN_EVT_SCAN_TIMEOUT:
    {
      NRF_LOG_INFO("Scan timed out.");
      scan_start();
      ret_code_t ret;
     
      ret = nrf_ble_scan_start(&m_scan);
      APP_ERROR_CHECK(ret);
     
      ret = bsp_indication_set(BSP_INDICATE_SCANNING);
      APP_ERROR_CHECK(ret);
    } break;
   
   
   
  default:
    break;
  }
}
/**@brief Function for initializing the scanning and setting the filters.
*/
static void scan_init(void)
{
 
  ret_code_t          err_code;
  nrf_ble_scan_init_t init_scan;
 
  memset(&init_scan, 0, sizeof(init_scan));
 
 
  //init_scan.connect_if_match = true;
  init_scan.conn_cfg_tag     = APP_BLE_CONN_CFG_TAG;
 
  err_code = nrf_ble_scan_init(&m_scan, &init_scan, scan_evt_handler);
  APP_ERROR_CHECK(err_code);
 
}
#endif
/** @brief Function for initializing BLE components.
*/
void ble_init(void)
{
  ble_stack_init();
  gap_params_init();
  gatt_init();
  db_discovery_init();
  services_init();
  advertising_init();
 
 
  peer_manager_init();
 
#ifdef RK_CLI
 
  scan_init();
#endif
}

/**@brief Function for initializing buttons and leds.
*
* @param[out] p_erase_bonds  Will be true if the clear bonding button was pressed to wake the application up.
*/
static void buttons_leds_init(bool * p_erase_bonds)
{
  ret_code_t err_code;
  bsp_event_t startup_event;
 
  err_code = bsp_init(BSP_INIT_LEDS | BSP_INIT_BUTTONS, bsp_event_handler);
  APP_ERROR_CHECK(err_code);
 
  err_code = bsp_btn_ble_init(NULL, &startup_event);
  APP_ERROR_CHECK(err_code);
 
  *p_erase_bonds = (startup_event == BSP_EVENT_CLEAR_BONDING_DATA);
}
/**
* @brief Function for shutdown events.
*
* @param[in]   event       Shutdown type.
*/
static bool shutdown_handler(nrf_pwr_mgmt_evt_t event)
{
  ret_code_t err_code;
 
  err_code = bsp_indication_set(BSP_INDICATE_IDLE);
  APP_ERROR_CHECK(err_code);
 
  switch (event)
  {
  case NRF_PWR_MGMT_EVT_PREPARE_WAKEUP:
    // Prepare wakeup buttons.
    err_code = bsp_btn_ble_sleep_mode_prepare();
    APP_ERROR_CHECK(err_code);
    break;
  default:
    break;
  }
 
  return true;
}
NRF_PWR_MGMT_HANDLER_REGISTER(shutdown_handler, 0);
#ifdef RK_CLI
void scan_start(void)
{
  ret_code_t ret;
  ret = nrf_ble_scan_start(&m_scan);
  APP_ERROR_CHECK(ret);
 
  ret = bsp_indication_set(BSP_INDICATE_SCANNING);
  APP_ERROR_CHECK(ret);
 
  m_scanning = true;
}
void scan_stop(void)
{
  ret_code_t ret;
 
  nrf_ble_scan_stop();
 
  ret = bsp_indication_set(BSP_INDICATE_SCANNING);
  APP_ERROR_CHECK(ret);
 
  m_scanning = false;
}
void int_addr_to_hex_str(char * p_result, uint8_t result_len, uint8_t const * const p_addr)
{
  ASSERT(p_result);
  ASSERT(p_addr);
 
  if (result_len > BLE_GAP_ADDR_LEN)
  {
    return;
  }
 
  // char buffer[BLE_GAP_ADDR_LEN] = {0};
  char tempbuffer = '\0';
 
  memset(p_result, 0, result_len);
 
  for (uint8_t i = 0; i < result_len; ++i)
  {
    sprintf(&tempbuffer, "%.2X", p_addr[result_len - (i+1)]);
    strcat(p_result, &tempbuffer);
   
    if (i < (result_len - 1))
    {
      strcat(p_result, ":");
    }
  }
}
void print_uuid(char * p_result, uint8_t result_len, uint8_t const * const p_uuid, uint8_t size)
{
  ASSERT(p_result);
  ASSERT(p_uuid);
 
  if (result_len > 100)
  {
    return;
  }   
  //Printing UUID in "8-4-4-4-12" format
  char buffer[100] = {0};
 
  memset(p_result, 0, result_len);
  memset(buffer, 0, 100);
 
  for (uint8_t j = size; j >= 1; --j)
  {
    sprintf(buffer, "%.2X", p_uuid[j-1]);
   
    strcat(p_result, buffer);
    if ( size < UUID128_SIZE && (j == 3 || j == 5 || j == 7))
    {
      strcat(p_result, ",");
    }
   
    if (j ==13 || j ==11 || j==9 || j==7)
    {
      strcat(p_result, "-");
    }
  }
 
}
/* Below funciton displays the scanned device list */
void device_list(nrf_cli_t const *p_cli, scanned_device_t * p_device )
{
  for (uint8_t i = 0; i < DEVICE_TO_FIND_MAX; i++)
  {
    if (p_device[i].is_not_empty)
    {
      nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "Device ");
     
      char buffer[ADDR_STRING_LEN];
      int_addr_to_hex_str(buffer, BLE_GAP_ADDR_LEN, p_device[i].addr);
      char ubuffer[100]={0};
      print_uuid(ubuffer, 100, p_device[i].uuid_buffer_1, p_device[i].uuid_len);
     
      nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "%s %s %ddB\r\n", buffer,  p_device[i].dev_name, p_device[i].RSSI_value_RK);
     
      //            switch (p_device[i].uuid_type)
      //            {
      //              case BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_COMPLETE:
      //                {
      //                  nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "Complete list of 128 bit UUID: %s \r\n\n", ubuffer);
      //                }break;
      //               
      //              case BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_MORE_AVAILABLE:
      //                {
      //                  nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "Incomplete list of 128 bit UUID: %s \r\n\n", ubuffer);
      //                 
      //                }break;
      //               
      //              case BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_COMPLETE:
      //                {
      //                    nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "Complete list of 16 bit UUID: %s \r\n\n", ubuffer);
      //             
      //                }break;
      //               
      //              case BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_MORE_AVAILABLE:
      //                {
      //                    nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "Incomplete list of 16 bit UUID: %s \r\n", ubuffer);
      //             
      //                }break;
      //            default:
      //              {
      //              //  nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "UUID Not found\r\n");
      //              }break;
      //             
      //            }//End switch
     
    }
   
  }
  nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "Known Device List:\n\r");
  //print known device list
  for (uint8_t i = 0; i < k_count; i++)
  {
    nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "K Device ");
   
    char buffer[ADDR_STRING_LEN];
    int_addr_to_hex_str(buffer, BLE_GAP_ADDR_LEN, (uint8_t *)k_device[i].addr);
   
   
    nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "%s %ddB uuid = %x\r\n", buffer, k_device[i].RSSI_value_RK, k_device[i].uuid);
  }
 
}
static void scan_on_cmd(nrf_cli_t const *p_cli, size_t argc, char **argv)
{
  scan_start();
  nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "Scanning...\r\n");
}
static void scan_off_cmd(nrf_cli_t const *p_cli, size_t argc, char **argv)
{
 
  scan_stop();
  nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "Scan stopped.\r\n");
}
static void display_device_list_cmd(nrf_cli_t const *p_cli, size_t argc, char **argv)
{
  if (argc >= 2)
  {
    if (nrf_cli_help_requested(p_cli))
    {
      nrf_cli_help_print(p_cli, NULL, 0);
      return;
    }
    else
    {
      nrf_cli_fprintf(p_cli,
                      NRF_CLI_ERROR,
                      "%s:%s%s\r\n",
                      argv[0],
                      " bad parameter ",
                      argv[1]);
      return;
    }
  }
  /* Print connectable devices from scan data.*/
  scanned_device_t * p_device_list = scan_device_info_get();
  device_list(p_cli, p_device_list);
}
static void default_cmd(nrf_cli_t const *p_cli, size_t argc, char **argv)
{
  if (argc >= 2)
  {
    if (nrf_cli_help_requested(p_cli))
    {
      nrf_cli_help_print(p_cli, NULL, 0);
      return;
    }
    else
    {
      nrf_cli_fprintf(p_cli,
                      NRF_CLI_ERROR,
                      "%s:%s%s\r\n",
                      argv[0],
                      " bad parameter ",
                      argv[1]);
      return;
    }
  }
}
// Register "mpu" command and it's subcommands in CLI.
NRF_CLI_CREATE_STATIC_SUBCMD_SET(scan_commands)
{
  NRF_CLI_CMD(on, NULL, "Scan on.", scan_on_cmd),
  NRF_CLI_CMD(off, NULL, "Scan off.", scan_off_cmd),
  NRF_CLI_SUBCMD_SET_END
};

NRF_CLI_CMD_REGISTER(scan, &scan_commands, "Commands for scan control", default_cmd);
NRF_CLI_CMD_REGISTER(devices, NULL, "print device list", display_device_list_cmd);

#endif
void idle_task(void * p_context)
{
 
  bool erase_bonds = (bool)p_context;
 
  advertising_start(erase_bonds);
 
 
  // Enter main loop.
  for (;;)
  {
    if (NRF_LOG_PROCESS() == false)
    {
      nrf_pwr_mgmt_run();
    }
    task_yield();
  }
 
}
static void core_init(void)
{
  APP_ERROR_CHECK(NRF_LOG_INIT(app_timer_cnt_get));
 
  nrf_drv_uart_config_t uart_config = NRF_DRV_UART_DEFAULT_CONFIG;
  uart_config.pseltxd = TX_PIN_NUMBER;
  uart_config.pselrxd = RX_PIN_NUMBER;
  uart_config.hwfc    = NRF_UART_HWFC_DISABLED;
  APP_ERROR_CHECK(nrf_cli_init(&m_cli_uart, &uart_config, true, true, NRF_LOG_SEVERITY_INFO));
  //APP_ERROR_CHECK(nrf_cli_start(&m_cli_uart));
 
 
  APP_ERROR_CHECK(nrf_drv_clock_init());
 
  nrf_drv_clock_lfclk_request(NULL);
 
  APP_ERROR_CHECK(app_timer_init());
  // Timer for refreshing scanned devices data.
  APP_TIMER_DEF(adv_list_timer);
  APP_ERROR_CHECK(app_timer_create(&adv_list_timer, APP_TIMER_MODE_REPEATED, adv_list_timer_handle));
  APP_ERROR_CHECK(app_timer_start(adv_list_timer, FOUND_DEVICE_REFRESH_TIME, NULL));
 
 
  APP_ERROR_CHECK(nrf_pwr_mgmt_init());
 
  APP_ERROR_CHECK(nrf_cli_task_create(&m_cli_uart));
}
ret_code_t fds_test_init (void)
{
 
  ret_code_t ret = fds_register(my_fds_evt_handler);
  if (ret != FDS_SUCCESS)
  {
    return ret;
   
  }
  ret = fds_init();
  if (ret != FDS_SUCCESS)
  {
    return ret;
  }
 
  return NRF_SUCCESS;
 
}

///**@brief Function for initializing the nrf log module.
//*/
//static void log_init(void)
//{
//  ret_code_t err_code = NRF_LOG_INIT(NULL);
//  APP_ERROR_CHECK(err_code);
// 
//  NRF_LOG_DEFAULT_BACKENDS_INIT();
//}
//
///**@brief Function for the Timer initialization.
// *
// * @details Initializes the timer module.
// */
//static void timers_init(void)
//{
//    ret_code_t err_code;
//
//    err_code = app_timer_init();
//    APP_ERROR_CHECK(err_code);
//
//    // Create battery timer.
//    err_code = app_timer_create(&m_battery_timer_id,
//                                APP_TIMER_MODE_REPEATED,
//                                battery_level_meas_timeout_handler);
//    APP_ERROR_CHECK(err_code);
//}
///**@brief Function for initializing power management.
// */
//static void power_management_init(void)
//{
//    ret_code_t err_code;
//    err_code = nrf_pwr_mgmt_init();
//    APP_ERROR_CHECK(err_code);
//}
///**@brief Function for the Event Scheduler initialization.
// */
//static void scheduler_init(void)
//{
//    APP_SCHED_INIT(SCHED_MAX_EVENT_DATA_SIZE, SCHED_QUEUE_SIZE);
//}

/**@brief Function for application main entry.
*/
int main(void)
{
 
  bool erase_bonds;
 
  core_init();
 
 // log_init();
  //timers_init();
//  power_management_init();
  //scheduler_init();
//  buffer_init();
    
  buttons_leds_init(&erase_bonds);
 
  ble_init();
  conn_params_init();
 
  fds_test_init();
 
  APP_ERROR_CHECK(nrf_cli_ble_uart_service_init());
 
  NRF_LOG_RAW_INFO("BLE Nordic Uart Service started\r\n");
  NRF_LOG_RAW_INFO("Press Tab to view all available commands.\r\n");
  task_manager_start(idle_task, (void *)erase_bonds);
 
  while (true)
  {
    UNUSED_RETURN_VALUE(NRF_LOG_PROCESS());
    nrf_cli_process(&m_cli_uart);
  }
 
}
Thanks
Tabassum
Related