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

BLE_GAP_EVT_CONNECTED event is not triggered

Hi all,

I have checked in Nordic Devzone for this query but no luck in finding solution for my query.

I am using nrf52832 and configured as central and peripheral.

my device will scan and store peer address in flash and then connect to stored address later.

when i connect to peer address using sd_ble_gap_connect it returns NRF_SUUCESS but BLE_GAP_EVT_CONNECTED  is not triggered.

this issue occurs only for some peripherals and some peripheral i can able to connect and it triggers event as well.

tested with one of the example code: when i try to connect  peripheral  device programmed with ble_app_uart code this issue occurs where  BLE_GAP_EVT_CONNECTED  is not triggered.

but the same peripheral connects successfully through my Android phone.

i am unable understand what is the issue.

Please guide...

Thanks

Rekha

Parents Reply Children
  • Hi i changed scan parameter timeout = 0x01 instead of 0. now i am getting ble gap event timeout error in BLE_GAP_EVT_TIMEOUT event.

    How to solve

    Thanks

  • I think you should get the connected event even if the connection hasn't been established yet, so I agree that you must be missing the event somehow.

  • Hi i changed scan parameter timeout = 0x01 instead of 0. now i am getting ble gap event timeout error in BLE_GAP_EVT_TIMEOUT event.

    How to solve

    Thanks

  • Hi attched files.

    in flash_write.c - void connect_to_devices(nrf_cli_t const *p_cli) is function where i am trying to connect peripheral device.

    Events are handled by ble_evt_hanlder in main.c

    #include "sdk_common.h"
    #include "flash_write.h"
    #include "ble.h"
    #include <stdio.h>
    #include <string.h>
    
    #define ADDR_STRING_LEN         (2 * (BLE_GAP_ADDR_LEN)+6)
    static volatile uint8_t write_flag=0;
    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 ;
    #define MAX_DEVICE 8
    known_list_t k_device[MAX_DEVICE];
    
    typedef struct 
    {
      uint8_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;
    }flash_list_t ;
    
    flash_list_t N_device[MAX_DEVICE];
    
    extern uint8_t k_count;
    void int_addr_to_hex_str(char * p_result, uint8_t result_len, uint8_t const * const p_addr);
    char id_buffer[ADDR_STRING_LEN];
    #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              0x01                                     /**< 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. */
    #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(900, 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 APP_BLE_CONN_CFG_TAG            1                                           /**< A tag identifying the SoftDevice BLE configuration. */
    
    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
    };
    
    
    
    void my_fds_evt_handler(fds_evt_t const * const p_fds_evt)
    {
      switch (p_fds_evt->id)
      {
      case FDS_EVT_INIT:
        if (p_fds_evt->result != FDS_SUCCESS)
        {
          // Initialization failed.
        }
        break;
      case FDS_EVT_WRITE:
        if (p_fds_evt->result == FDS_SUCCESS)
        {
          write_flag=1;
        }
        break;
      default:
        break;
      }
    }
    ret_code_t fds_test_write(nrf_cli_t const *p_cli)
    {		
      #define FILE_ID     0x1111		
      #define REC_KEY     0x2222
      //static uint16_t const m_deadbeef[2] = {0x9D,0xBA};
      fds_record_t        record;
      fds_record_desc_t   record_desc;
      fds_flash_record_t  flash_record;
      fds_find_token_t    ftok ={0};//Important, make sure you zero init the ftok token
      uint8_t *data;
      uint32_t err_code;
      uint8_t data_len =0;
      uint8_t id = 0;
      flash_list_t temp_device[MAX_DEVICE];
      // Set up record.
      record.file_id           = FILE_ID;
      record.key               = REC_KEY;        
      //read previously stored data
      while (fds_record_find(FILE_ID, REC_KEY, &record_desc, &ftok) == FDS_SUCCESS)               
      {
        err_code = fds_record_open(&record_desc, &flash_record);
        if ( err_code != FDS_SUCCESS)		
        {
          NRF_LOG_INFO("record open failed\n\r");
          return err_code;				
        }
        data =  (uint8_t *)flash_record.p_data;                            
        for (uint8_t i = 0;i< BLE_GAP_ADDR_LEN ;i++)                
        {
          memcpy(&temp_device[id].addr[i], &data[data_len+i], sizeof(data[i]));              
        }          
        id++;
        err_code = fds_record_close(&record_desc);
        if (err_code != FDS_SUCCESS)              
        {
          NRF_LOG_INFO("record close failed\n\r");
          return err_code;	        
        }                      
      }  
      uint8_t loop =  --id;
                
      for (uint8_t j = 0; j < k_count; j++)             
      {
        //Compare address if the address already exists in the flash record discard flash write
        bool id_found = false;
        if (!id_found)            
        {
          for (uint8_t l = 0; l <= loop; l++)           
          {
            if ( memcmp(temp_device[l].addr, k_device[j].addr, sizeof(temp_device[l].addr)) == 0)               
            {
              id_found = true;    
              break; //break inner loop
            }
                          
          }             
        }
        if (!id_found)            
        {
          record.data.p_data       = k_device[j].addr; 
          record.data.length_words = 2;
          ret_code_t ret = fds_record_write(&record_desc, &record);
          //if (ret != FDS_SUCCESS)
          if (ret == FDS_ERR_UNALIGNED_ADDR)             
          {
            NRF_LOG_INFO("writing to flash unsuccessful. \r\n"); 
            return ret;               
          }            
        }           
      }
      NRF_LOG_DEBUG("Writing Record ID = %d \r\n",record_desc.record_id);        
      return NRF_SUCCESS;
                   
    }
    
    ret_code_t fds_read(nrf_cli_t const *p_cli)
    {
      #define FILE_ID     0x1111
      #define REC_KEY     0x2222
      fds_flash_record_t  flash_record;
      fds_record_desc_t   record_desc;
      fds_find_token_t    ftok ={0};//Important, make sure you zero init the ftok token
      uint8_t *data;
      uint32_t err_code;
      
      uint8_t data_len =0;
      uint8_t id = 0;
      
      NRF_LOG_DEBUG("Start searching... \r\n");
      // Loop until all records with the given key and file ID have been found.
      while (fds_record_find(FILE_ID, REC_KEY, &record_desc, &ftok) == FDS_SUCCESS)
      {
        err_code = fds_record_open(&record_desc, &flash_record);
        if ( err_code != FDS_SUCCESS)
        {
          return err_code;		
        }
        
        NRF_LOG_DEBUG("Found Record ID = %d\r\n",record_desc.record_id);
        
        data =  (uint8_t *)flash_record.p_data;                            
        for (uint8_t i = 0;i< BLE_GAP_ADDR_LEN ;i++)
        {
          memcpy(&N_device[id].addr[i], &data[data_len+i], sizeof(data[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, N_device[id].addr);
        nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "%s\r\n", buffer);
        id++;
        
        // Access the record through the flash_record structure.
        // Close the record when done.
        err_code = fds_record_close(&record_desc);
        if (err_code != FDS_SUCCESS)
        {
          return err_code;	
        }
        
      }
      
      return NRF_SUCCESS;
    		
    }
    
    ret_code_t fds_test_find_and_delete(nrf_cli_t const *p_cli)
    {
                 
      #define FILE_ID     0x1111
      #define REC_KEY     0x2222
      fds_record_desc_t   record_desc;
      fds_find_token_t    ftok;
      ftok.page=0;
      ftok.p_addr=NULL;
      // Loop and find records with same ID and rec key and mark them as deleted. 
      while (fds_record_find(FILE_ID, REC_KEY, &record_desc, &ftok) == FDS_SUCCESS)		
      {
        fds_record_delete(&record_desc);
        nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL,"Deleted record ID: %d \r\n",record_desc.record_id);
      }
                    
      // call the garbage collector to empty them, don't need to do this all the time, this is just for demonstration
      ret_code_t ret = fds_gc();
      if (ret != FDS_SUCCESS)		
      {
        return ret;		
      }		
      return NRF_SUCCESS;
    }
    
    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;
    		
    }
    
    void connect_to_devices(nrf_cli_t const *p_cli)
    {
     
      
        #define FILE_ID     0x1111
        #define REC_KEY     0x2222
        fds_flash_record_t  flash_record;
        fds_record_desc_t   record_desc;
        fds_find_token_t    ftok ={0};//Important, make sure you zero init the ftok token
        uint8_t *data;
        uint32_t err_code;
        uint8_t data_len =0;      
              
        ble_gap_addr_t paddr;          
     
        uint8_t id = 0;
        flash_list_t temp_device[MAX_DEVICE]; 
        
        while (fds_record_find(FILE_ID, REC_KEY, &record_desc, &ftok) == FDS_SUCCESS)               
        {
        err_code = fds_record_open(&record_desc, &flash_record);
        if ( err_code != FDS_SUCCESS)		
        {
          NRF_LOG_INFO("record open failed\n\r");
          return ;				
        }
        data =  (uint8_t *)flash_record.p_data;                            
        for (uint8_t i = 0;i< BLE_GAP_ADDR_LEN ;i++)                
        {
          memcpy(&temp_device[id].addr[i], &data[data_len+i], sizeof(data[i]));              
        }          
        id++;
        err_code = fds_record_close(&record_desc);
        if (err_code != FDS_SUCCESS)              
        {
          NRF_LOG_INFO("record close failed\n\r");
          return;	        
        }                      
      }  
      uint8_t loop =  --id; 
    nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "loop = %d\n\r", loop);
                    
          for (uint8_t l = 0; l <= loop; l++)           
          {
        
            memset(&paddr, 0, sizeof(paddr));
            for (uint8_t i = 0;i< BLE_GAP_ADDR_LEN ;i++)               
            {
              paddr.addr[i] = temp_device[l].addr[i];                
            } 
           
            nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "connecting address - %2x:%2x:%2x:%2x:%2x:%2x\r\n", 
                            paddr.addr[5], paddr.addr[4], paddr.addr[3], paddr.addr[2], paddr.addr[1], paddr.addr[0] );
              
            ret_code_t err_code;
            // Establish connection.
            err_code = sd_ble_gap_connect(&paddr,
                                      &m_scan_param,
                                      &m_connection_param,
                                      APP_BLE_CONN_CFG_TAG);
          
            if(err_code == NRF_SUCCESS)
            {
              nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "NRF_SUCCESS\n\r");
    //          return;
            }
            else if(err_code == NRF_ERROR_INVALID_ADDR)
            {
              nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "NRF_ERROR_INVALID_ADDR failed\n\r");
            }
            else if(err_code == NRF_ERROR_INVALID_PARAM)
            {
              nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "NRF_ERROR_INVALID_PARAM failed\n\r");
            }
            else if(err_code == NRF_ERROR_NOT_FOUND)
            {
              nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "NRF_ERROR_NOT_FOUND failed\n\r");
            }
            else if (err_code == NRF_ERROR_INVALID_STATE)
            {
              nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "NRF_ERROR_INVALID_STATE failed\n\r");
            }
            else if (err_code == BLE_ERROR_GAP_INVALID_BLE_ADDR)
            {
              nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "BLE_ERROR_GAP_INVALID_BLE_ADDR failed\n\r");
            }
            else if (err_code == NRF_ERROR_CONN_COUNT)
            {
              nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "NRF_ERROR_CONN_COUNT failed\n\r");
            }
            else if (err_code == NRF_ERROR_RESOURCES)
            {
              nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "NRF_ERROR_RESOURCES failed\n\r");
            }
            else if (err_code == NRF_ERROR_NOT_SUPPORTED)
            {
              nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "NRF_ERROR_NOT_SUPPORTED failed\n\r");
            }   
          
          }       
                      
                   
        
    //    
    //    
    //    
    //    while (fds_record_find(FILE_ID, REC_KEY, &record_desc, &ftok) == FDS_SUCCESS)     
    //    {
    //      memset(&paddr, 0, sizeof(paddr));
    //      err_code = fds_record_open(&record_desc, &flash_record);
    //      if ( err_code != FDS_SUCCESS)		
    //      {                   
    //        NRF_LOG_INFO("record open failed\n\r");
    //        return ;		
    //      }                  
    //       
    //      data =  (uint8_t *)flash_record.p_data;                                                      
    //      for (uint8_t i = 0;i< BLE_GAP_ADDR_LEN ;i++)               
    //      {
    //        paddr.addr[i] = data[data_len+i];                
    //      }             
    //               
    //      nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "connecting address - %2x:%2x:%2x:%2x:%2x:%2x\r\n", paddr.addr[5], paddr.addr[4], paddr.addr[3], paddr.addr[2], paddr.addr[1], paddr.addr[0] );
    //                     
    //      // Establish connection.
    //      err_code = sd_ble_gap_connect(&paddr,
    //                                  &m_scan_param,
    //                                  &m_connection_param,
    //                                  APP_BLE_CONN_CFG_TAG);
    //      
    //   
    //      if(err_code == NRF_SUCCESS)
    //      {
    //        nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "NRF_SUCCESS\n\r");
    //
    //        err_code = fds_record_close(&record_desc);
    //        if (err_code != FDS_SUCCESS)              
    //        {
    //          nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "record close failed\n\r");         
    //          return;	                 
    //        }      
    //        return;
    //      }
    //      else if(err_code == NRF_ERROR_INVALID_ADDR)
    //      {
    //        nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "NRF_ERROR_INVALID_ADDR failed\n\r");
    //      }
    //      else if(err_code == NRF_ERROR_INVALID_PARAM)
    //      {
    //        nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "NRF_ERROR_INVALID_PARAM failed\n\r");
    //      }
    //      else if(err_code == NRF_ERROR_NOT_FOUND)
    //      {
    //        nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "NRF_ERROR_NOT_FOUND failed\n\r");
    //      }
    //      else if (err_code == NRF_ERROR_INVALID_STATE)
    //      {
    //        nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "NRF_ERROR_INVALID_STATE failed\n\r");
    //      }
    //      else if (err_code == BLE_ERROR_GAP_INVALID_BLE_ADDR)
    //      {
    //        nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "BLE_ERROR_GAP_INVALID_BLE_ADDR failed\n\r");
    //      }
    //      else if (err_code == NRF_ERROR_CONN_COUNT)
    //      {
    //        //    nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "NRF_ERROR_CONN_COUNT failed\n\r");
    //      }
    //      else if (err_code == NRF_ERROR_RESOURCES)
    //      {
    //        nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "NRF_ERROR_RESOURCES failed\n\r");
    //      }
    //      else if (err_code == NRF_ERROR_NOT_SUPPORTED)
    //      {
    //        nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "NRF_ERROR_NOT_SUPPORTED failed\n\r");
    //      }   
    //       
    //      err_code = fds_record_close(&record_desc);
    //      if (err_code != FDS_SUCCESS)              
    //      {
    //        nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "record close failed\n\r");         
    //        return;	                 
    //      }    
    //         
    //       
    //    } //end while loop
    }
    
    //connect to devices (Normal mode is on)
    static void connect_device_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;
            }
        }
    //  normal_mode_on = true;
      nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "Connect to devices...\r\n");
      connect_to_devices(p_cli);
      
    }
    
    
    void flashwrite_erase_cmd(nrf_cli_t const *p_cli, size_t argc, char **argv)
    {
        fds_test_find_and_delete(p_cli);
        nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "Erase flash...\r\n");
    }
    
    void flashwrite_read_cmd(nrf_cli_t const *p_cli, size_t argc, char **argv)
    {
        nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "\r\nknown devices \r\n");
        fds_read(p_cli);
        nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "Read from flash...\r\n");
    }
    
    void flashwrite_write_cmd(nrf_cli_t const *p_cli, size_t argc, char **argv)
    {
       fds_test_write(p_cli);
       nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "Writing to flash...\r\n");
    }
    
    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;
            }
        }
    }
    
    NRF_CLI_CREATE_STATIC_SUBCMD_SET(flash_commands)
    {
         NRF_CLI_CMD(erase, NULL, "Erase flash", flashwrite_erase_cmd),
         NRF_CLI_CMD(read, NULL, "Read from flash", flashwrite_read_cmd),
         NRF_CLI_CMD(write, NULL, "Write to flash", flashwrite_write_cmd),
         
         NRF_CLI_SUBCMD_SET_END
    };
    
    NRF_CLI_CMD_REGISTER(flash, &flash_commands, "Access Flash", default_cmd);
    NRF_CLI_CMD_REGISTER(connect, NULL, "Connect to peripheral", connect_device_cmd);
    /** 
    * 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 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
    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. */
      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 -70
    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);
    void ble_serv_on_db_disc_evt(ble_db_discovery_evt_t const * p_evt);
    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;
    #define MAX_DEVICE 8
    extern known_list_t k_device[MAX_DEVICE];
    
    known_list_t temp_device;
    
    extern uint8_t k_count = 0;
    
    /* Thermometer UUID = 0x1809 
      NUS UUID = {0x9E, 0xCA, 0xDC, 0x24, 0x0E, 0xE5, 0xA9, 0xE0, 0x93, 0xF3, 0xA3, 0xB5, 0x01, 0x00, 0x40, 0x6E};{0x6E400001B5A3F393E0A9E50E24DCCA9E} 
      NONIN UUID = {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;
    
    /* 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);
    
    bool normal_mode_on = true;
    
    
    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:
        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};
     
      // 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 = 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");
      }
    
      // 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");
      }
     
    }
    
    /**@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;
      
      switch (p_ble_evt->header.evt_id)
      {
      case BLE_GAP_EVT_ADV_REPORT:
        { 
          device_to_list_add(&p_gap_evt->params.adv_report);         
        } break;
        
      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);
          if (normal_mode_on == false)
          {
            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 status\n");
                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_INFO("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_INFO("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_GAP_EVT_TIMEOUT:
        NRF_LOG_INFO("Timeout error\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);
    }
    
    /**@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();
      
      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.
      
      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 &&
              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);
         
          // 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)
    {
      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();
      }
    }
    
    /**@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
            bool d_found = false;
            if (p_adv_report->type.connectable && connect == false )
            {
              for (idx = 0; idx <= k_count; idx++)
              {
                if (memcmp(p_adv_report->peer_addr.addr,k_device[idx].addr, sizeof(p_adv_report->peer_addr.addr)) == 0)
                {
                  NRF_LOG_INFO("device address matched\n\r");
                  d_found = true;
                }
                
              }
              if (!d_found)
              {
                connect_to_target(p_adv_report);
                /* 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.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);
      
    }
    
    
    /** @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();
      scan_init();
    }
    
    
    /**@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);
    
    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 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);
        }
        
      }
      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)
    {
      normal_mode_on = false;
      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)
    {
      normal_mode_on = true;
      scan_stop();
      nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "Scan stopped.\r\n");
    }
    
    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);
    
    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_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));
    }
    
    
    /**@brief Function for application main entry.
    */
    int main(void)
    
    {
      bool erase_bonds;
      
      core_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);
      }
      
    }
    

  • Hi please find attached file in reply to Andy

    Thanks

Related