nRF5340 LE disconnection Issue.

Hi,

We are using nRF5340 DK and the nRF Connect SDK Version 2.6.1.

We are experiencing an issue with disconnections. We use bt_conn_ref() when receiving the connected event and bt_conn_unref() when receiving the disconnection event.

However, sometimes after a disconnection, when we retry, we encounter the error: "bt_conn: bt_conn_exists_le: Found valid connection (0x20001a18) with address FF:F5:55:5A:D6:6A (random) in disconnected state".

Why does this issue occur even after the disconnection event has been processed?

If we call bt_conn_unref() twice during the disconnection event as shown in the below code (essentially incrementing once upon connection and decrementing twice upon disconnection), the issue does not occur.

void connected(struct bt_conn *conn, uint8_t conn_err){
	bt_conn_ref(conn);
}
void disconnected(struct bt_conn *conn, uint8_t reason){
 	bt_conn_unref(conn);
 	bt_conn_unref(conn);	
}

Could this behavior be due to an internal counter issue?

Parents Reply Children
  • Hi 

    Thanks for the response.

    Please find the attached connection make, connected event and disconnected event code portion

    int ConnectToPeripheral(bt_addr_le_t *addr, uint16_t nodeId){
    
    	int err;
    	static struct bt_le_conn_param *param;
    	static struct bt_conn_le_create_param *create_conn_param;
    	bt_addr_le_t *deviceAddr = addr;
    	param = BT_LE_CONN_PARAM_DEFAULT; 
    	param->interval_max = CONN_INTERVAL_MAX;
    	param->interval_min = CONN_INTERVAL_MIN;
    	param->timeout = SUPERVISION_TIMEOUT;
    	create_conn_param = BT_CONN_LE_CREATE_CONN;
    	create_conn_param->timeout = 150;
    
        err = bt_le_scan_stop();
        if (err) {
            LOGT(ERROR,"Stop LE scan failed before connection (err %d)", err);				
        }else{
    		scanActive=false;
    	}
    
    	err = bt_conn_le_create(deviceAddr, create_conn_param, param, &pending_central_conn);
    	return err;
    }
    
    static void connected(struct bt_conn *conn, uint8_t conn_err)
    {
    	struct bt_conn_info info;
    	char ConnectedAddr[BT_ADDR_LE_STR_LEN];
    	int ret=0;
    
    	bt_addr_le_to_str(bt_conn_get_dst(conn), ConnectedAddr, sizeof(ConnectedAddr));
    
    	if (conn_err) {
    		LOGT(ERROR,"Failed to connect to %s (%u)", ConnectedAddr, conn_err);
    		bt_conn_unref(conn);		
    
    		if(!scanActive){			 
            	discovery_State_Manage(SCANNING,FAST);    		
    		}
    		return;
    	}	
    
    	if (info.role == BT_CONN_ROLE_CENTRAL) {		
    		update_le_parame(conn);		
    	}
    
    	if(info.role == BT_CONN_ROLE_PERIPHERAL){
    		bt_conn_ref(conn);
    	}  
    
    }
    
    static void disconnected(struct bt_conn *conn, uint8_t reason)
    {	
    	LOGT(CONN,"####### DISCONNECTED Reason: %d #######",reason);	
    
    	if(conn){          
            bt_conn_unref(conn);
        }
    	
    }
    
    static void update_le_parame(struct bt_conn *conn){
    
    	int err;
    
    	exchange_params.func = exchange_func;
    	err = bt_gatt_exchange_mtu(conn, &exchange_params);
    	if (err) {
    		LOGT(ERROR,"MTU exchange failed (err %d)", err);
    	}	
    
    	err = bt_conn_le_phy_update(conn, conn_phy);
    	if (err) {
    		LOGT(ERROR,"PHY update failed: %d", err);
    	}
    
    }
    
    
    
    

  • Hi,

    Thanks for the code. In the connected callback, it seems that you are using the 'info' variable without initializing it. I would have expected to see a call to the bt_conn_get_info() function to assign the connection information to the variable.

  • Hi,

    Thanks for the response. 

    The bt_conn_get_info() function is I'm already using. It was accidentally removed when I sent you my reply.

    static void connected(struct bt_conn *conn, uint8_t conn_err)
    {
    	struct bt_conn_info info;
    	char ConnectedAddr[BT_ADDR_LE_STR_LEN];
    	int ret=0;
    
    	bt_addr_le_to_str(bt_conn_get_dst(conn), ConnectedAddr, sizeof(ConnectedAddr));
    
    	if (conn_err) {
    		LOGT(ERROR,"Failed to connect to %s (%u)", ConnectedAddr, conn_err);
    		bt_conn_unref(conn);		
    
    		if(!scanActive){			 
            	discovery_State_Manage(SCANNING,FAST);    		
    		}
    		return;
    	}	
    
        bt_conn_get_info(conn, &info);
        
    	if (info.role == BT_CONN_ROLE_CENTRAL) {		
    		update_le_parame(conn);		
    	}
    
    	if(info.role == BT_CONN_ROLE_PERIPHERAL){
    		bt_conn_ref(conn);
    	}  
    
    }
    

  • Hi,

    We encountered another critical disconnection issue during testing with just two devices.

    Device A and device B are both in use. If device B is turned off, device A does not receive any disconnection event, even though device B is no longer on. we have notice that device A still shows device B as connected, even though device B is actually off. I verified this by removing the battery from device B to confirm that it was indeed powered down.

    Could this be happening because a disconnection event is not being sent to the app core from net core?

  • Hi,

    I'm not able to spot any obvious problems in the code snippets you posted. Are you able to provide a minimal version of your project here or in a private that would allow me to reproduce the issue on a nRF5340 DK?

Related