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

connect a device and disconnect and try to connect another ,cannot connect

hi ,

   I'm a newer ,  using nRF5_SDK_15.3.0_59ac345. we are using nrf52832 to get about 100 of heart rate sensors.

so first we do a scan ,and get all of  there addrs. and than ,try to connect one ,get hrs value and disconnect this one, and connect next one .

but Unfortunately , when disconnected successfully, connect next one will no success.

  here is our code ,   <disconnect_current_addr> be called when events of BLE_HRS_C_EVT_HRM_NOTIFICATION happened.

and when BLE_GAP_EVT_DISCONNECTED happened, call <connect_current_addr> to connect next one.

void connect_current_addr(void)
{
int ret;
ret_code_t err_code;
scan_evt_t scan_evt;

// For readability.
ble_gap_addr_t peer_addr;

// Stop scanning.
nrf_ble_scan_stop();
DBGPRINT(DEBUG_TRACE,"connect_current_addr ++ \n");

ret = GetNextActiveAddr(&peer_addr);

if(ret != 0)
{
DBGPRINT(DEBUG_ERROR,"No active device !\n");
return;
}

memset(&scan_evt, 0, sizeof(scan_evt));

// Establish connection.
err_code = sd_ble_gap_connect(&peer_addr,
&m_scan_param,
&m_conn_params,
1);

// DBGPRINT(DEBUG_TRACE,"Connecting\n");
DBGPRINT(DEBUG_TRACE,"Connecting: %02X:%02X:%02X:%02X:%02X:%02X\n",
peer_addr.addr[5],
peer_addr.addr[4],
peer_addr.addr[3],
peer_addr.addr[2],
peer_addr.addr[1],
peer_addr.addr[0]);
}

void disconnect_current_addr(void)
{
ret_code_t err_code;
if(m_conn_handle != BLE_CONN_HANDLE_INVALID)
{
err_code = sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);

APP_ERROR_CHECK(err_code);
m_conn_handle = BLE_CONN_HANDLE_INVALID;
}
}

  

[21:04:11.522]收←◆K4\0 \0Bconnect_current_addr ++
Connecting: A0:9E:1A:17:40:F8

[21:04:11.636]收←◆Connected: A0:9E:1A:17:40:F8

[21:04:11.694]收←◆GATT ATT MTU on connection 0x0 changed to 232

[21:04:12.234]收←◆Data length for connection 0x0 updated to 236
Disconnected, reason 0x16
connect_current_addr ++
Connecting: A0:9E:1A:17:40:DC

  

Parents
  • #include <stdint.h>
    #include <stdio.h>
    #include <string.h>
    #include "nordic_common.h"
    #include "nrf_sdm.h"
    #include "ble.h"
    #include "ble_hci.h"
    #include "ble_db_discovery.h"
    #include "ble_srv_common.h"
    #include "nrf_sdh.h"
    #include "nrf_sdh_ble.h"
    #include "nrf_sdh_soc.h"
    #include "nrf_pwr_mgmt.h"
    #include "app_util.h"
    #include "app_error.h"
    #include "peer_manager.h"
    #include "peer_manager_handler.h"
    #include "ble_hrs_c.h"
    #include "ble_bas_c.h"
    #include "app_util.h"
    #include "app_timer.h"
    #include "fds.h"
    #include "nrf_fstorage.h"
    #include "ble_conn_state.h"
    #include "nrf_ble_gatt.h"
    #include "nrf_ble_lesc.h"
    #include "nrf_log.h"
    #include "nrf_log_ctrl.h"
    #include "nrf_log_default_backends.h"
    #include "nrf_ble_scan.h"
    #include "protocol.h"
    
    #define APP_BLE_CONN_CFG_TAG        1                                   /**< A tag identifying the SoftDevice BLE configuration. */
    
    #define APP_BLE_OBSERVER_PRIO       3                                   /**< Application's BLE observer priority. You shouldn't need to modify this value. */
    #define APP_SOC_OBSERVER_PRIO       1                                   /**< Applications' SoC observer priority. You shouldn't need to modify this value. */
    
    #define LESC_DEBUG_MODE             0                                   /**< Set to 1 to use LESC debug keys, allows you to use a sniffer to inspect traffic. */
    
    #define SEC_PARAM_BOND              1                                   /**< Perform bonding. */
    #define SEC_PARAM_MITM              0                                   /**< Man In The Middle protection not required. */
    #define SEC_PARAM_LESC              1                                   /**< LE Secure Connections 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 in octets. */
    #define SEC_PARAM_MAX_KEY_SIZE      16                                  /**< Maximum encryption key size in octets. */
    
    #define SCAN_DURATION_WITELIST      60000                     			/**< Duration of the scanning in units of 10 milliseconds. */
    
    #define MIN_CONNECTION_INTERVAL             MSEC_TO_UNITS(30, UNIT_1_25_MS)                         /**< Determines maximum connection interval in millisecond. */
    #define MAX_CONNECTION_INTERVAL             MSEC_TO_UNITS(60, UNIT_1_25_MS)                         /**< Determines maximum connection interval in millisecond. */
    #define SLAVE_LATENCY                       6                                                       /**< Determines slave latency in counts of connection events. */
    #define SUPERVISION_TIMEOUT                 MSEC_TO_UNITS(4000, UNIT_10_MS)                         /**< Determines supervision time-out in units of 10 millisecond. */
    
    
    
    #define TARGET_UUID                 BLE_UUID_HEART_RATE_SERVICE         /**< Target device uuid that application is looking for. */
    
    BLE_HRS_C_DEF(m_hrs_c);                                             /**< Structure used to identify the heart rate client module. */
    BLE_BAS_C_DEF(m_bas_c);                                             /**< Structure used to identify the Battery Service client module. */
    NRF_BLE_GATT_DEF(m_gatt);                                           /**< GATT module instance. */
    BLE_DB_DISCOVERY_DEF(m_db_disc);                                    /**< DB discovery module instance. */
    NRF_BLE_SCAN_DEF(m_scan);                                           /**< Scanning module instance. */
    
    static uint16_t m_conn_handle = BLE_CONN_HANDLE_INVALID;            /**< Current connection handle. */
    static bool     m_memory_access_in_progress;                        /**< Flag to keep track of ongoing operations on persistent memory. */
    
    /**< Scan parameters requested for scanning and connection. */
    static ble_gap_scan_params_t const m_scan_param =
    {
        .active        = 0x01,
        .interval      = NRF_BLE_SCAN_SCAN_INTERVAL,
        .window        = NRF_BLE_SCAN_SCAN_WINDOW,
        .filter_policy = BLE_GAP_SCAN_FP_ACCEPT_ALL,
        .timeout       = SCAN_DURATION_WITELIST,
        .scan_phys     = BLE_GAP_PHY_AUTO,
    };
    
    static ble_gap_conn_params_t const m_conn_params =
    {
    	.min_conn_interval = (uint16_t)MIN_CONNECTION_INTERVAL,   // Minimum connection
        .max_conn_interval = (uint16_t)MAX_CONNECTION_INTERVAL,   // Maximum connection
        .slave_latency     = SLAVE_LATENCY,                                   // Slave latency
        .conn_sup_timeout  = (uint16_t)SUPERVISION_TIMEOUT        // Supervision time-out
    };
    
    void connect_current_addr(void)
    {
    	 int ret;
    	ret_code_t err_code;
        scan_evt_t scan_evt;
    
        // For readability.
      	ble_gap_addr_t         peer_addr;
    	
    	// Stop scanning.
        nrf_ble_scan_stop();
    	DBGPRINT(DEBUG_TRACE,"connect_current_addr ++ \n");
    	
    	ret = GetNextActiveAddr(&peer_addr);
    	
    	if(ret != 0)
    	{
    		DBGPRINT(DEBUG_ERROR,"No active device !\n");
    		return;
    	}
    
        memset(&scan_evt, 0, sizeof(scan_evt));
    
        // Establish connection.
        err_code = sd_ble_gap_connect(&peer_addr,
                                      &m_scan_param,
                                      &m_conn_params,
                                      1);
    
     //   DBGPRINT(DEBUG_TRACE,"Connecting\n");
    	DBGPRINT(DEBUG_TRACE,"Connecting: %02X:%02X:%02X:%02X:%02X:%02X\n",
    				peer_addr.addr[5],
    				peer_addr.addr[4],
    				peer_addr.addr[3],
    				peer_addr.addr[2],
    				peer_addr.addr[1],
    				peer_addr.addr[0]);
     	SetCurBtState(BSP_INDICATE_BONDING);		//connectting ,just use bonding instand
    }
    
    void disconnect_current_addr(void)
    {
        ret_code_t            err_code;
    	if(m_conn_handle != BLE_CONN_HANDLE_INVALID)
    	{
    		err_code = sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
    
    	    APP_ERROR_CHECK(err_code);
    		m_conn_handle = BLE_CONN_HANDLE_INVALID;
    	}
    }
    
    void assert_nrf_callback(uint16_t line_num, const uint8_t * p_file_name)
    {
        app_error_handler(0xDEADBEEF, line_num, p_file_name);
    }
    
    static void db_disc_handler(ble_db_discovery_evt_t * p_evt)
    {
        ble_hrs_on_db_disc_evt(&m_hrs_c, p_evt);
        ble_bas_on_db_disc_evt(&m_bas_c, p_evt);
    }
    
    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:
                DBGPRINT(DEBUG_TRACE,"PM_EVT_PEERS_DELETE_SUCCEEDED\n");
                // Bonds are deleted. Start scanning.
       	        //  scan_start();
                break;
    
            default:
                break;
        }
    }
    
    static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
    {
        ret_code_t            err_code;
        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_CONNECTED:
            {
       //       DBGPRINT(DEBUG_TRACE,"Connected\n");
    			DBGPRINT(DEBUG_INFO,"Connected: %02X:%02X:%02X:%02X:%02X:%02X\n",
    				p_ble_evt->evt.gap_evt.params.connected.peer_addr.addr[5],
    				p_ble_evt->evt.gap_evt.params.connected.peer_addr.addr[4],
    				p_ble_evt->evt.gap_evt.params.connected.peer_addr.addr[3],
    				p_ble_evt->evt.gap_evt.params.connected.peer_addr.addr[2],
    				p_ble_evt->evt.gap_evt.params.connected.peer_addr.addr[1],
    				p_ble_evt->evt.gap_evt.params.connected.peer_addr.addr[0]);
    			
    			m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
    
                // Discover peer's services.
                err_code = ble_db_discovery_start(&m_db_disc, p_ble_evt->evt.gap_evt.conn_handle);
                APP_ERROR_CHECK(err_code);
    
    			SetCurBtState(BSP_INDICATE_CONNECTED);
    
                if (ble_conn_state_central_conn_count() < NRF_SDH_BLE_CENTRAL_LINK_COUNT)
                {
     //               scan_start();
                }
            } break;
    
            case BLE_GAP_EVT_DISCONNECTED:
            {
                DBGPRINT(DEBUG_TRACE,"Disconnected, reason 0x%x\n",
                             p_gap_evt->params.disconnected.reason);
    
    			SetCurBtState(BSP_INDICATE_IDLE);
    
                if (ble_conn_state_central_conn_count() < NRF_SDH_BLE_CENTRAL_LINK_COUNT)
                {
     //               scan_start();
                }
    			if(bRefreshStart)
    			{
    		//		connect_current_addr();
    			}
    
            } break;
    
            case BLE_GAP_EVT_TIMEOUT:
            {
                if (p_gap_evt->params.timeout.src == BLE_GAP_TIMEOUT_SRC_CONN)
                {
                    DBGPRINT(DEBUG_TRACE,"Connection Request timed out\n");
                }
    			if(bRefreshStart)
    			{
    	//			connect_current_addr();
    			}
    			SetCurBtState(BSP_INDICATE_IDLE);
            } break;
    
            case BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST:
                // Accepting parameters requested by peer.
                err_code = sd_ble_gap_conn_param_update(p_gap_evt->conn_handle,
                                                        &p_gap_evt->params.conn_param_update_request.conn_params);
                APP_ERROR_CHECK(err_code);
                break;
    
            case BLE_GAP_EVT_PHY_UPDATE_REQUEST:
            {
                DBGPRINT(DEBUG_TRACE,"PHY update request\n");
                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.
                DBGPRINT(DEBUG_TRACE,"GATT Client Timeout\n");
                err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gattc_evt.conn_handle,
                                                 BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
                APP_ERROR_CHECK(err_code);
                break;
    
            case BLE_GATTS_EVT_TIMEOUT:
                // Disconnect on GATT Server timeout event.
                DBGPRINT(DEBUG_TRACE,"GATT Server Timeout\n");
                err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gatts_evt.conn_handle,
                                                 BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
                APP_ERROR_CHECK(err_code);
                break;
        
            case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
                DBGPRINT(DEBUG_TRACE,"BLE_GAP_EVT_SEC_PARAMS_REQUEST\n");
                break;
    
            case BLE_GAP_EVT_AUTH_KEY_REQUEST:
                DBGPRINT(DEBUG_TRACE,"BLE_GAP_EVT_AUTH_KEY_REQUEST\n");
                break;
    
            case BLE_GAP_EVT_LESC_DHKEY_REQUEST:
                DBGPRINT(DEBUG_TRACE,"BLE_GAP_EVT_LESC_DHKEY_REQUEST\n");
                break;
    
             case BLE_GAP_EVT_AUTH_STATUS:
                 DBGPRINT(DEBUG_TRACE,"BLE_GAP_EVT_AUTH_STATUS: status=0x%x bond=0x%x lv4: %d kdist_own:0x%x kdist_peer:0x%x\n",
                              p_ble_evt->evt.gap_evt.params.auth_status.auth_status,
                              p_ble_evt->evt.gap_evt.params.auth_status.bonded,
                              p_ble_evt->evt.gap_evt.params.auth_status.sm1_levels.lv4,
                              *((uint8_t *)&p_ble_evt->evt.gap_evt.params.auth_status.kdist_own),
                              *((uint8_t *)&p_ble_evt->evt.gap_evt.params.auth_status.kdist_peer));
                break;
    
            default:
                break;
        }
    }
    
    static void soc_evt_handler(uint32_t evt_id, void * p_context)
    {
        switch (evt_id)
        {
            case NRF_EVT_FLASH_OPERATION_SUCCESS:
                /* fall through */
            case NRF_EVT_FLASH_OPERATION_ERROR:
    
                if (m_memory_access_in_progress)
                {
                    m_memory_access_in_progress = false;
      //              scan_start();
                }
                break;
    
            default:
                // No implementation needed.
                break;
        }
    }
    
    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 handlers for BLE and SoC events.
        NRF_SDH_BLE_OBSERVER(m_ble_observer, APP_BLE_OBSERVER_PRIO, ble_evt_handler, NULL);
        NRF_SDH_SOC_OBSERVER(m_soc_observer, APP_SOC_OBSERVER_PRIO, soc_evt_handler, NULL);
    }
    
    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.lesc           = SEC_PARAM_LESC;
        sec_param.keypress       = SEC_PARAM_KEYPRESS;
        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);
    }
    
    static void hrs_c_evt_handler(ble_hrs_c_t * p_hrs_c, ble_hrs_c_evt_t * p_hrs_c_evt)
    {
        ret_code_t err_code;
    
        switch (p_hrs_c_evt->evt_type)
        {
            case BLE_HRS_C_EVT_DISCOVERY_COMPLETE:
            {
                DBGPRINT(DEBUG_TRACE,"Heart rate service discovered\n");
    
                err_code = ble_hrs_c_handles_assign(p_hrs_c,
                                                    p_hrs_c_evt->conn_handle,
                                                    &p_hrs_c_evt->params.peer_db);
                APP_ERROR_CHECK(err_code);
    
                // Initiate bonding.
                err_code = pm_conn_secure(p_hrs_c_evt->conn_handle, false);
                if (err_code != NRF_ERROR_BUSY)
                {
                    APP_ERROR_CHECK(err_code);
                }
    
                // Heart rate service discovered. Enable notification of Heart Rate Measurement.
                err_code = ble_hrs_c_hrm_notif_enable(p_hrs_c);
                APP_ERROR_CHECK(err_code);
            } break;
    
            case BLE_HRS_C_EVT_HRM_NOTIFICATION:
            {
    			uint32_t rr_avg = 0;
                DBGPRINT(DEBUG_TRACE,"Heart Rate = %d\n", p_hrs_c_evt->params.hrm.hr_value);
    
                if (p_hrs_c_evt->params.hrm.rr_intervals_cnt != 0)
                {
                    for (uint32_t i = 0; i < p_hrs_c_evt->params.hrm.rr_intervals_cnt; i++)
                    {
                        rr_avg += p_hrs_c_evt->params.hrm.rr_intervals[i];
                    }
                    rr_avg = rr_avg / p_hrs_c_evt->params.hrm.rr_intervals_cnt;
                    DBGPRINT(DEBUG_TRACE,"rr_interval (avg) = %d\n", rr_avg);
                }
    			if(p_hrs_c_evt->params.hrm.hr_value != 0x00)
    			{
    				//we get the valid data ,and then try to store it and disconnect
    				UpdateCurrentSensorHst(p_hrs_c_evt->params.hrm.hr_value,rr_avg);
    				disconnect_current_addr();
    			}
            } break;
    
            default:
                break;
        }
    }
    
    static void bas_c_evt_handler(ble_bas_c_t * p_bas_c, ble_bas_c_evt_t * p_bas_c_evt)
    {
        ret_code_t err_code;
    
        switch (p_bas_c_evt->evt_type)
        {
            case BLE_BAS_C_EVT_DISCOVERY_COMPLETE:
            {
                err_code = ble_bas_c_handles_assign(p_bas_c,
                                                    p_bas_c_evt->conn_handle,
                                                    &p_bas_c_evt->params.bas_db);
                APP_ERROR_CHECK(err_code);
    
                // Battery service discovered. Enable notification of Battery Level.
                DBGPRINT(DEBUG_TRACE,"Battery Service discovered. Reading battery level\n");
    
                err_code = ble_bas_c_bl_read(p_bas_c);
                APP_ERROR_CHECK(err_code);
    
                DBGPRINT(DEBUG_TRACE,"Enabling Battery Level Notification\n");
                err_code = ble_bas_c_bl_notif_enable(p_bas_c);
                APP_ERROR_CHECK(err_code);
    
            } break;
    
            case BLE_BAS_C_EVT_BATT_NOTIFICATION:
                DBGPRINT(DEBUG_TRACE,"Battery Level received %d %%\n", p_bas_c_evt->params.battery_level);
    			UpdateCurrentSensorPower(p_bas_c_evt->params.battery_level);
                break;
    
            case BLE_BAS_C_EVT_BATT_READ_RESP:
                DBGPRINT(DEBUG_TRACE,"Battery Level Read as %d %%\n", p_bas_c_evt->params.battery_level);
    			UpdateCurrentSensorPower(p_bas_c_evt->params.battery_level);
    			break;
    
            default:
                break;
        }
    }
    
    static void hrs_c_init(void)
    {
        ble_hrs_c_init_t hrs_c_init_obj;
    
        hrs_c_init_obj.evt_handler = hrs_c_evt_handler;
    
        ret_code_t err_code = ble_hrs_c_init(&m_hrs_c, &hrs_c_init_obj);
        APP_ERROR_CHECK(err_code);
    }
    
    static void bas_c_init(void)
    {
        ble_bas_c_init_t bas_c_init_obj;
    
        bas_c_init_obj.evt_handler = bas_c_evt_handler;
    
        ret_code_t err_code = ble_bas_c_init(&m_bas_c, &bas_c_init_obj);
        APP_ERROR_CHECK(err_code);
    }
    
    static void db_discovery_init(void)
    {
        ret_code_t err_code = ble_db_discovery_init(db_disc_handler);
        APP_ERROR_CHECK(err_code);
    }
    
    void scan_start(void)
    {
        ret_code_t err_code;
    
        DBGPRINT(DEBUG_INFO,"Starting scan\n");
    
        err_code = nrf_ble_scan_start(&m_scan);
        APP_ERROR_CHECK(err_code);
    
     	SetCurBtState(BSP_INDICATE_SCANNING);
    }
    
    void scan_stop(void)
    {
    	DBGPRINT(DEBUG_INFO,"Stop scan\n");
    	nrf_ble_scan_stop();
    }
    
    static void log_init(void)
    {
        ret_code_t err_code = NRF_LOG_INIT(NULL);
        APP_ERROR_CHECK(err_code);
    
        NRF_LOG_DEFAULT_BACKENDS_INIT();
    }
    
    static void power_management_init(void)
    {
        ret_code_t err_code;
        err_code = nrf_pwr_mgmt_init();
        APP_ERROR_CHECK(err_code);
    }
    
    static void gatt_evt_handler(nrf_ble_gatt_t * p_gatt, nrf_ble_gatt_evt_t const * p_evt)
    {
        switch (p_evt->evt_id)
        {
            case NRF_BLE_GATT_EVT_ATT_MTU_UPDATED:
            {
                DBGPRINT(DEBUG_TRACE,"GATT ATT MTU on connection 0x%x changed to %d\n",
                             p_evt->conn_handle,
                             p_evt->params.att_mtu_effective);
            } break;
    
            case NRF_BLE_GATT_EVT_DATA_LENGTH_UPDATED:
            {
                DBGPRINT(DEBUG_TRACE,"Data length for connection 0x%x updated to %d\n",
                             p_evt->conn_handle,
                             p_evt->params.data_length);
            } break;
    
            default:
                break;
        }
    }
    
    
    static void scan_evt_handler(scan_evt_t const * p_scan_evt)
    {
    		uint8_t i;
    
        ret_code_t err_code;
        switch(p_scan_evt->scan_evt_id)
        {
            case NRF_BLE_SCAN_EVT_WHITELIST_REQUEST:
            {
    			DBGPRINT(DEBUG_TRACE,"NRF_BLE_SCAN_EVT_WHITELIST_REQUEST\n");
            } break;
    
            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_SCAN_TIMEOUT:
            {
              DBGPRINT(DEBUG_TRACE,"Scan timed out\n");
              scan_start();
            } break;
    
            case NRF_BLE_SCAN_EVT_FILTER_MATCH:
    //			DBGPRINT(DEBUG_TRACE,"NRF_BLE_SCAN_EVT_FILTER_MATCH\n");
    			
    			DBGPRINT(DEBUG_INFO,"%02X:%02X:%02X:%02X:%02X:%02X\n",
    				p_scan_evt->params.filter_match.p_adv_report->peer_addr.addr[5],
    				p_scan_evt->params.filter_match.p_adv_report->peer_addr.addr[4],
    				p_scan_evt->params.filter_match.p_adv_report->peer_addr.addr[3],
    				p_scan_evt->params.filter_match.p_adv_report->peer_addr.addr[2],
    				p_scan_evt->params.filter_match.p_adv_report->peer_addr.addr[1],
    				p_scan_evt->params.filter_match.p_adv_report->peer_addr.addr[0]);
    
    			//check the mac addr if match polar
    			for(i=0;i<user_sensor_list.totol_num;i++)
    			{
    				//mac addr is the same
    				if(compareArray((uint8_t *)p_scan_evt->params.filter_match.p_adv_report->peer_addr.addr,user_sensor_list.sensor_info[i].addr,6))
    				{
    					SetUserSensorState(i,1);
    				}
    			}
                break;
            case NRF_BLE_SCAN_EVT_WHITELIST_ADV_REPORT:
    			DBGPRINT(DEBUG_TRACE,"NRF_BLE_SCAN_EVT_WHITELIST_ADV_REPORT\n");
    			
                break;
    
            default:
              break;
        }
    }
    
    static void timer_init(void)
    {
        ret_code_t err_code = app_timer_init();
        APP_ERROR_CHECK(err_code);
    }
    
    static void gatt_init(void)
    {
        ret_code_t err_code = nrf_ble_gatt_init(&m_gatt, gatt_evt_handler);
        APP_ERROR_CHECK(err_code);
    }
    
    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.p_scan_param     = &m_scan_param;
        init_scan.connect_if_match = false;
        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);
    
        ble_uuid_t uuid =
        {
            .uuid = TARGET_UUID,
            .type = BLE_UUID_TYPE_BLE,
        };
    
        err_code = nrf_ble_scan_filter_set(&m_scan,
                                           SCAN_UUID_FILTER,
                                           &uuid);
        APP_ERROR_CHECK(err_code);
    
       
        err_code = nrf_ble_scan_filters_enable(&m_scan,
                                               NRF_BLE_SCAN_UUID_FILTER,//NRF_BLE_SCAN_ALL_FILTER,
                                               false);
        APP_ERROR_CHECK(err_code);
    
    }
    
    static void idle_state_handle(void)
    {
        ret_code_t err_code;
        
        err_code = nrf_ble_lesc_request_handler();
        APP_ERROR_CHECK(err_code);
        
        NRF_LOG_FLUSH();
        nrf_pwr_mgmt_run();
    }
    
    void bt_reset(void)
    {
    	 NVIC_SystemReset();
    }
    
    int main(void)
    {
        // Initialize.
        log_init();
    	timer_init();
    	protocol_init();
    	
    	DBGPRINT(DEBUG_INFO,"KinBird Hrs built : %s %s\n",__DATE__,__TIME__);
        power_management_init();
        ble_stack_init();
        gatt_init();
        peer_manager_init();
        db_discovery_init();
        hrs_c_init();
        bas_c_init();
        scan_init();
        // Enter main loop.
        for (;;)
        {
            idle_state_handle();
        }
    }

Reply
  • #include <stdint.h>
    #include <stdio.h>
    #include <string.h>
    #include "nordic_common.h"
    #include "nrf_sdm.h"
    #include "ble.h"
    #include "ble_hci.h"
    #include "ble_db_discovery.h"
    #include "ble_srv_common.h"
    #include "nrf_sdh.h"
    #include "nrf_sdh_ble.h"
    #include "nrf_sdh_soc.h"
    #include "nrf_pwr_mgmt.h"
    #include "app_util.h"
    #include "app_error.h"
    #include "peer_manager.h"
    #include "peer_manager_handler.h"
    #include "ble_hrs_c.h"
    #include "ble_bas_c.h"
    #include "app_util.h"
    #include "app_timer.h"
    #include "fds.h"
    #include "nrf_fstorage.h"
    #include "ble_conn_state.h"
    #include "nrf_ble_gatt.h"
    #include "nrf_ble_lesc.h"
    #include "nrf_log.h"
    #include "nrf_log_ctrl.h"
    #include "nrf_log_default_backends.h"
    #include "nrf_ble_scan.h"
    #include "protocol.h"
    
    #define APP_BLE_CONN_CFG_TAG        1                                   /**< A tag identifying the SoftDevice BLE configuration. */
    
    #define APP_BLE_OBSERVER_PRIO       3                                   /**< Application's BLE observer priority. You shouldn't need to modify this value. */
    #define APP_SOC_OBSERVER_PRIO       1                                   /**< Applications' SoC observer priority. You shouldn't need to modify this value. */
    
    #define LESC_DEBUG_MODE             0                                   /**< Set to 1 to use LESC debug keys, allows you to use a sniffer to inspect traffic. */
    
    #define SEC_PARAM_BOND              1                                   /**< Perform bonding. */
    #define SEC_PARAM_MITM              0                                   /**< Man In The Middle protection not required. */
    #define SEC_PARAM_LESC              1                                   /**< LE Secure Connections 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 in octets. */
    #define SEC_PARAM_MAX_KEY_SIZE      16                                  /**< Maximum encryption key size in octets. */
    
    #define SCAN_DURATION_WITELIST      60000                     			/**< Duration of the scanning in units of 10 milliseconds. */
    
    #define MIN_CONNECTION_INTERVAL             MSEC_TO_UNITS(30, UNIT_1_25_MS)                         /**< Determines maximum connection interval in millisecond. */
    #define MAX_CONNECTION_INTERVAL             MSEC_TO_UNITS(60, UNIT_1_25_MS)                         /**< Determines maximum connection interval in millisecond. */
    #define SLAVE_LATENCY                       6                                                       /**< Determines slave latency in counts of connection events. */
    #define SUPERVISION_TIMEOUT                 MSEC_TO_UNITS(4000, UNIT_10_MS)                         /**< Determines supervision time-out in units of 10 millisecond. */
    
    
    
    #define TARGET_UUID                 BLE_UUID_HEART_RATE_SERVICE         /**< Target device uuid that application is looking for. */
    
    BLE_HRS_C_DEF(m_hrs_c);                                             /**< Structure used to identify the heart rate client module. */
    BLE_BAS_C_DEF(m_bas_c);                                             /**< Structure used to identify the Battery Service client module. */
    NRF_BLE_GATT_DEF(m_gatt);                                           /**< GATT module instance. */
    BLE_DB_DISCOVERY_DEF(m_db_disc);                                    /**< DB discovery module instance. */
    NRF_BLE_SCAN_DEF(m_scan);                                           /**< Scanning module instance. */
    
    static uint16_t m_conn_handle = BLE_CONN_HANDLE_INVALID;            /**< Current connection handle. */
    static bool     m_memory_access_in_progress;                        /**< Flag to keep track of ongoing operations on persistent memory. */
    
    /**< Scan parameters requested for scanning and connection. */
    static ble_gap_scan_params_t const m_scan_param =
    {
        .active        = 0x01,
        .interval      = NRF_BLE_SCAN_SCAN_INTERVAL,
        .window        = NRF_BLE_SCAN_SCAN_WINDOW,
        .filter_policy = BLE_GAP_SCAN_FP_ACCEPT_ALL,
        .timeout       = SCAN_DURATION_WITELIST,
        .scan_phys     = BLE_GAP_PHY_AUTO,
    };
    
    static ble_gap_conn_params_t const m_conn_params =
    {
    	.min_conn_interval = (uint16_t)MIN_CONNECTION_INTERVAL,   // Minimum connection
        .max_conn_interval = (uint16_t)MAX_CONNECTION_INTERVAL,   // Maximum connection
        .slave_latency     = SLAVE_LATENCY,                                   // Slave latency
        .conn_sup_timeout  = (uint16_t)SUPERVISION_TIMEOUT        // Supervision time-out
    };
    
    void connect_current_addr(void)
    {
    	 int ret;
    	ret_code_t err_code;
        scan_evt_t scan_evt;
    
        // For readability.
      	ble_gap_addr_t         peer_addr;
    	
    	// Stop scanning.
        nrf_ble_scan_stop();
    	DBGPRINT(DEBUG_TRACE,"connect_current_addr ++ \n");
    	
    	ret = GetNextActiveAddr(&peer_addr);
    	
    	if(ret != 0)
    	{
    		DBGPRINT(DEBUG_ERROR,"No active device !\n");
    		return;
    	}
    
        memset(&scan_evt, 0, sizeof(scan_evt));
    
        // Establish connection.
        err_code = sd_ble_gap_connect(&peer_addr,
                                      &m_scan_param,
                                      &m_conn_params,
                                      1);
    
     //   DBGPRINT(DEBUG_TRACE,"Connecting\n");
    	DBGPRINT(DEBUG_TRACE,"Connecting: %02X:%02X:%02X:%02X:%02X:%02X\n",
    				peer_addr.addr[5],
    				peer_addr.addr[4],
    				peer_addr.addr[3],
    				peer_addr.addr[2],
    				peer_addr.addr[1],
    				peer_addr.addr[0]);
     	SetCurBtState(BSP_INDICATE_BONDING);		//connectting ,just use bonding instand
    }
    
    void disconnect_current_addr(void)
    {
        ret_code_t            err_code;
    	if(m_conn_handle != BLE_CONN_HANDLE_INVALID)
    	{
    		err_code = sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
    
    	    APP_ERROR_CHECK(err_code);
    		m_conn_handle = BLE_CONN_HANDLE_INVALID;
    	}
    }
    
    void assert_nrf_callback(uint16_t line_num, const uint8_t * p_file_name)
    {
        app_error_handler(0xDEADBEEF, line_num, p_file_name);
    }
    
    static void db_disc_handler(ble_db_discovery_evt_t * p_evt)
    {
        ble_hrs_on_db_disc_evt(&m_hrs_c, p_evt);
        ble_bas_on_db_disc_evt(&m_bas_c, p_evt);
    }
    
    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:
                DBGPRINT(DEBUG_TRACE,"PM_EVT_PEERS_DELETE_SUCCEEDED\n");
                // Bonds are deleted. Start scanning.
       	        //  scan_start();
                break;
    
            default:
                break;
        }
    }
    
    static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
    {
        ret_code_t            err_code;
        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_CONNECTED:
            {
       //       DBGPRINT(DEBUG_TRACE,"Connected\n");
    			DBGPRINT(DEBUG_INFO,"Connected: %02X:%02X:%02X:%02X:%02X:%02X\n",
    				p_ble_evt->evt.gap_evt.params.connected.peer_addr.addr[5],
    				p_ble_evt->evt.gap_evt.params.connected.peer_addr.addr[4],
    				p_ble_evt->evt.gap_evt.params.connected.peer_addr.addr[3],
    				p_ble_evt->evt.gap_evt.params.connected.peer_addr.addr[2],
    				p_ble_evt->evt.gap_evt.params.connected.peer_addr.addr[1],
    				p_ble_evt->evt.gap_evt.params.connected.peer_addr.addr[0]);
    			
    			m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
    
                // Discover peer's services.
                err_code = ble_db_discovery_start(&m_db_disc, p_ble_evt->evt.gap_evt.conn_handle);
                APP_ERROR_CHECK(err_code);
    
    			SetCurBtState(BSP_INDICATE_CONNECTED);
    
                if (ble_conn_state_central_conn_count() < NRF_SDH_BLE_CENTRAL_LINK_COUNT)
                {
     //               scan_start();
                }
            } break;
    
            case BLE_GAP_EVT_DISCONNECTED:
            {
                DBGPRINT(DEBUG_TRACE,"Disconnected, reason 0x%x\n",
                             p_gap_evt->params.disconnected.reason);
    
    			SetCurBtState(BSP_INDICATE_IDLE);
    
                if (ble_conn_state_central_conn_count() < NRF_SDH_BLE_CENTRAL_LINK_COUNT)
                {
     //               scan_start();
                }
    			if(bRefreshStart)
    			{
    		//		connect_current_addr();
    			}
    
            } break;
    
            case BLE_GAP_EVT_TIMEOUT:
            {
                if (p_gap_evt->params.timeout.src == BLE_GAP_TIMEOUT_SRC_CONN)
                {
                    DBGPRINT(DEBUG_TRACE,"Connection Request timed out\n");
                }
    			if(bRefreshStart)
    			{
    	//			connect_current_addr();
    			}
    			SetCurBtState(BSP_INDICATE_IDLE);
            } break;
    
            case BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST:
                // Accepting parameters requested by peer.
                err_code = sd_ble_gap_conn_param_update(p_gap_evt->conn_handle,
                                                        &p_gap_evt->params.conn_param_update_request.conn_params);
                APP_ERROR_CHECK(err_code);
                break;
    
            case BLE_GAP_EVT_PHY_UPDATE_REQUEST:
            {
                DBGPRINT(DEBUG_TRACE,"PHY update request\n");
                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.
                DBGPRINT(DEBUG_TRACE,"GATT Client Timeout\n");
                err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gattc_evt.conn_handle,
                                                 BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
                APP_ERROR_CHECK(err_code);
                break;
    
            case BLE_GATTS_EVT_TIMEOUT:
                // Disconnect on GATT Server timeout event.
                DBGPRINT(DEBUG_TRACE,"GATT Server Timeout\n");
                err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gatts_evt.conn_handle,
                                                 BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
                APP_ERROR_CHECK(err_code);
                break;
        
            case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
                DBGPRINT(DEBUG_TRACE,"BLE_GAP_EVT_SEC_PARAMS_REQUEST\n");
                break;
    
            case BLE_GAP_EVT_AUTH_KEY_REQUEST:
                DBGPRINT(DEBUG_TRACE,"BLE_GAP_EVT_AUTH_KEY_REQUEST\n");
                break;
    
            case BLE_GAP_EVT_LESC_DHKEY_REQUEST:
                DBGPRINT(DEBUG_TRACE,"BLE_GAP_EVT_LESC_DHKEY_REQUEST\n");
                break;
    
             case BLE_GAP_EVT_AUTH_STATUS:
                 DBGPRINT(DEBUG_TRACE,"BLE_GAP_EVT_AUTH_STATUS: status=0x%x bond=0x%x lv4: %d kdist_own:0x%x kdist_peer:0x%x\n",
                              p_ble_evt->evt.gap_evt.params.auth_status.auth_status,
                              p_ble_evt->evt.gap_evt.params.auth_status.bonded,
                              p_ble_evt->evt.gap_evt.params.auth_status.sm1_levels.lv4,
                              *((uint8_t *)&p_ble_evt->evt.gap_evt.params.auth_status.kdist_own),
                              *((uint8_t *)&p_ble_evt->evt.gap_evt.params.auth_status.kdist_peer));
                break;
    
            default:
                break;
        }
    }
    
    static void soc_evt_handler(uint32_t evt_id, void * p_context)
    {
        switch (evt_id)
        {
            case NRF_EVT_FLASH_OPERATION_SUCCESS:
                /* fall through */
            case NRF_EVT_FLASH_OPERATION_ERROR:
    
                if (m_memory_access_in_progress)
                {
                    m_memory_access_in_progress = false;
      //              scan_start();
                }
                break;
    
            default:
                // No implementation needed.
                break;
        }
    }
    
    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 handlers for BLE and SoC events.
        NRF_SDH_BLE_OBSERVER(m_ble_observer, APP_BLE_OBSERVER_PRIO, ble_evt_handler, NULL);
        NRF_SDH_SOC_OBSERVER(m_soc_observer, APP_SOC_OBSERVER_PRIO, soc_evt_handler, NULL);
    }
    
    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.lesc           = SEC_PARAM_LESC;
        sec_param.keypress       = SEC_PARAM_KEYPRESS;
        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);
    }
    
    static void hrs_c_evt_handler(ble_hrs_c_t * p_hrs_c, ble_hrs_c_evt_t * p_hrs_c_evt)
    {
        ret_code_t err_code;
    
        switch (p_hrs_c_evt->evt_type)
        {
            case BLE_HRS_C_EVT_DISCOVERY_COMPLETE:
            {
                DBGPRINT(DEBUG_TRACE,"Heart rate service discovered\n");
    
                err_code = ble_hrs_c_handles_assign(p_hrs_c,
                                                    p_hrs_c_evt->conn_handle,
                                                    &p_hrs_c_evt->params.peer_db);
                APP_ERROR_CHECK(err_code);
    
                // Initiate bonding.
                err_code = pm_conn_secure(p_hrs_c_evt->conn_handle, false);
                if (err_code != NRF_ERROR_BUSY)
                {
                    APP_ERROR_CHECK(err_code);
                }
    
                // Heart rate service discovered. Enable notification of Heart Rate Measurement.
                err_code = ble_hrs_c_hrm_notif_enable(p_hrs_c);
                APP_ERROR_CHECK(err_code);
            } break;
    
            case BLE_HRS_C_EVT_HRM_NOTIFICATION:
            {
    			uint32_t rr_avg = 0;
                DBGPRINT(DEBUG_TRACE,"Heart Rate = %d\n", p_hrs_c_evt->params.hrm.hr_value);
    
                if (p_hrs_c_evt->params.hrm.rr_intervals_cnt != 0)
                {
                    for (uint32_t i = 0; i < p_hrs_c_evt->params.hrm.rr_intervals_cnt; i++)
                    {
                        rr_avg += p_hrs_c_evt->params.hrm.rr_intervals[i];
                    }
                    rr_avg = rr_avg / p_hrs_c_evt->params.hrm.rr_intervals_cnt;
                    DBGPRINT(DEBUG_TRACE,"rr_interval (avg) = %d\n", rr_avg);
                }
    			if(p_hrs_c_evt->params.hrm.hr_value != 0x00)
    			{
    				//we get the valid data ,and then try to store it and disconnect
    				UpdateCurrentSensorHst(p_hrs_c_evt->params.hrm.hr_value,rr_avg);
    				disconnect_current_addr();
    			}
            } break;
    
            default:
                break;
        }
    }
    
    static void bas_c_evt_handler(ble_bas_c_t * p_bas_c, ble_bas_c_evt_t * p_bas_c_evt)
    {
        ret_code_t err_code;
    
        switch (p_bas_c_evt->evt_type)
        {
            case BLE_BAS_C_EVT_DISCOVERY_COMPLETE:
            {
                err_code = ble_bas_c_handles_assign(p_bas_c,
                                                    p_bas_c_evt->conn_handle,
                                                    &p_bas_c_evt->params.bas_db);
                APP_ERROR_CHECK(err_code);
    
                // Battery service discovered. Enable notification of Battery Level.
                DBGPRINT(DEBUG_TRACE,"Battery Service discovered. Reading battery level\n");
    
                err_code = ble_bas_c_bl_read(p_bas_c);
                APP_ERROR_CHECK(err_code);
    
                DBGPRINT(DEBUG_TRACE,"Enabling Battery Level Notification\n");
                err_code = ble_bas_c_bl_notif_enable(p_bas_c);
                APP_ERROR_CHECK(err_code);
    
            } break;
    
            case BLE_BAS_C_EVT_BATT_NOTIFICATION:
                DBGPRINT(DEBUG_TRACE,"Battery Level received %d %%\n", p_bas_c_evt->params.battery_level);
    			UpdateCurrentSensorPower(p_bas_c_evt->params.battery_level);
                break;
    
            case BLE_BAS_C_EVT_BATT_READ_RESP:
                DBGPRINT(DEBUG_TRACE,"Battery Level Read as %d %%\n", p_bas_c_evt->params.battery_level);
    			UpdateCurrentSensorPower(p_bas_c_evt->params.battery_level);
    			break;
    
            default:
                break;
        }
    }
    
    static void hrs_c_init(void)
    {
        ble_hrs_c_init_t hrs_c_init_obj;
    
        hrs_c_init_obj.evt_handler = hrs_c_evt_handler;
    
        ret_code_t err_code = ble_hrs_c_init(&m_hrs_c, &hrs_c_init_obj);
        APP_ERROR_CHECK(err_code);
    }
    
    static void bas_c_init(void)
    {
        ble_bas_c_init_t bas_c_init_obj;
    
        bas_c_init_obj.evt_handler = bas_c_evt_handler;
    
        ret_code_t err_code = ble_bas_c_init(&m_bas_c, &bas_c_init_obj);
        APP_ERROR_CHECK(err_code);
    }
    
    static void db_discovery_init(void)
    {
        ret_code_t err_code = ble_db_discovery_init(db_disc_handler);
        APP_ERROR_CHECK(err_code);
    }
    
    void scan_start(void)
    {
        ret_code_t err_code;
    
        DBGPRINT(DEBUG_INFO,"Starting scan\n");
    
        err_code = nrf_ble_scan_start(&m_scan);
        APP_ERROR_CHECK(err_code);
    
     	SetCurBtState(BSP_INDICATE_SCANNING);
    }
    
    void scan_stop(void)
    {
    	DBGPRINT(DEBUG_INFO,"Stop scan\n");
    	nrf_ble_scan_stop();
    }
    
    static void log_init(void)
    {
        ret_code_t err_code = NRF_LOG_INIT(NULL);
        APP_ERROR_CHECK(err_code);
    
        NRF_LOG_DEFAULT_BACKENDS_INIT();
    }
    
    static void power_management_init(void)
    {
        ret_code_t err_code;
        err_code = nrf_pwr_mgmt_init();
        APP_ERROR_CHECK(err_code);
    }
    
    static void gatt_evt_handler(nrf_ble_gatt_t * p_gatt, nrf_ble_gatt_evt_t const * p_evt)
    {
        switch (p_evt->evt_id)
        {
            case NRF_BLE_GATT_EVT_ATT_MTU_UPDATED:
            {
                DBGPRINT(DEBUG_TRACE,"GATT ATT MTU on connection 0x%x changed to %d\n",
                             p_evt->conn_handle,
                             p_evt->params.att_mtu_effective);
            } break;
    
            case NRF_BLE_GATT_EVT_DATA_LENGTH_UPDATED:
            {
                DBGPRINT(DEBUG_TRACE,"Data length for connection 0x%x updated to %d\n",
                             p_evt->conn_handle,
                             p_evt->params.data_length);
            } break;
    
            default:
                break;
        }
    }
    
    
    static void scan_evt_handler(scan_evt_t const * p_scan_evt)
    {
    		uint8_t i;
    
        ret_code_t err_code;
        switch(p_scan_evt->scan_evt_id)
        {
            case NRF_BLE_SCAN_EVT_WHITELIST_REQUEST:
            {
    			DBGPRINT(DEBUG_TRACE,"NRF_BLE_SCAN_EVT_WHITELIST_REQUEST\n");
            } break;
    
            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_SCAN_TIMEOUT:
            {
              DBGPRINT(DEBUG_TRACE,"Scan timed out\n");
              scan_start();
            } break;
    
            case NRF_BLE_SCAN_EVT_FILTER_MATCH:
    //			DBGPRINT(DEBUG_TRACE,"NRF_BLE_SCAN_EVT_FILTER_MATCH\n");
    			
    			DBGPRINT(DEBUG_INFO,"%02X:%02X:%02X:%02X:%02X:%02X\n",
    				p_scan_evt->params.filter_match.p_adv_report->peer_addr.addr[5],
    				p_scan_evt->params.filter_match.p_adv_report->peer_addr.addr[4],
    				p_scan_evt->params.filter_match.p_adv_report->peer_addr.addr[3],
    				p_scan_evt->params.filter_match.p_adv_report->peer_addr.addr[2],
    				p_scan_evt->params.filter_match.p_adv_report->peer_addr.addr[1],
    				p_scan_evt->params.filter_match.p_adv_report->peer_addr.addr[0]);
    
    			//check the mac addr if match polar
    			for(i=0;i<user_sensor_list.totol_num;i++)
    			{
    				//mac addr is the same
    				if(compareArray((uint8_t *)p_scan_evt->params.filter_match.p_adv_report->peer_addr.addr,user_sensor_list.sensor_info[i].addr,6))
    				{
    					SetUserSensorState(i,1);
    				}
    			}
                break;
            case NRF_BLE_SCAN_EVT_WHITELIST_ADV_REPORT:
    			DBGPRINT(DEBUG_TRACE,"NRF_BLE_SCAN_EVT_WHITELIST_ADV_REPORT\n");
    			
                break;
    
            default:
              break;
        }
    }
    
    static void timer_init(void)
    {
        ret_code_t err_code = app_timer_init();
        APP_ERROR_CHECK(err_code);
    }
    
    static void gatt_init(void)
    {
        ret_code_t err_code = nrf_ble_gatt_init(&m_gatt, gatt_evt_handler);
        APP_ERROR_CHECK(err_code);
    }
    
    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.p_scan_param     = &m_scan_param;
        init_scan.connect_if_match = false;
        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);
    
        ble_uuid_t uuid =
        {
            .uuid = TARGET_UUID,
            .type = BLE_UUID_TYPE_BLE,
        };
    
        err_code = nrf_ble_scan_filter_set(&m_scan,
                                           SCAN_UUID_FILTER,
                                           &uuid);
        APP_ERROR_CHECK(err_code);
    
       
        err_code = nrf_ble_scan_filters_enable(&m_scan,
                                               NRF_BLE_SCAN_UUID_FILTER,//NRF_BLE_SCAN_ALL_FILTER,
                                               false);
        APP_ERROR_CHECK(err_code);
    
    }
    
    static void idle_state_handle(void)
    {
        ret_code_t err_code;
        
        err_code = nrf_ble_lesc_request_handler();
        APP_ERROR_CHECK(err_code);
        
        NRF_LOG_FLUSH();
        nrf_pwr_mgmt_run();
    }
    
    void bt_reset(void)
    {
    	 NVIC_SystemReset();
    }
    
    int main(void)
    {
        // Initialize.
        log_init();
    	timer_init();
    	protocol_init();
    	
    	DBGPRINT(DEBUG_INFO,"KinBird Hrs built : %s %s\n",__DATE__,__TIME__);
        power_management_init();
        ble_stack_init();
        gatt_init();
        peer_manager_init();
        db_discovery_init();
        hrs_c_init();
        bas_c_init();
        scan_init();
        // Enter main loop.
        for (;;)
        {
            idle_state_handle();
        }
    }

Children
No Data
Related