BLE failure to connect; pairDevice returns object but see no exception or onConnectedStateChange

I am scanning for a peripheral with a custom profile; this is found. But I am failing to connect with the device.

My function for connecting is.....

   function scanListener( ScanResult ){
    	Ble.setScanState( Ble.SCAN_STATE_OFF );
    	System.println( "AvailableConnectionCount is "+ Ble.getAvailableConnectionCount() );
    	try{
    		myDevice = Ble.pairDevice( ScanResult );
    		System.println( "paired device " + myDevice );
    		if( myDevice instanceof Ble.Device ){
    			System.println( "paired IS A DEVICE " + myDevice.getName() );
    			System.println( "AvailableConnectionCount is "+ Ble.getAvailableConnectionCount() );
    		}
    		if( myDevice.isConnected() ){
    			System.println( "reports Connected" );
    		}
    	}catch( exception ){
    		System.println( exception.getErrorMessage() );
    	}
    	
    }


My console output being....

initialising view
got scan result NOVA_31
AvailableConnectionCount is 3
paired device Obj: 164
paired IS A DEVICE null
AvailableConnectionCount is 3
profile registered 3F4E1400-D5C9-46C3-A2A5-090606023D85

I see no exception thrown; I see no calls of onConnectedStateChange(); the pairDevice() returns an object which is apparently a Ble.Device yet myDevice.Getname() returns null and myDevice.isConnected() returns false.



In my peripheral which is nordic based I see some debug output which kind of hints that a connection is made; but then dropped.

<info> app: systemProcessEvent SYSTEM_BLE_CONNECTED_EVT
<debug> nrf_ble_gatt: ATT MTU updated to 23 bytes on connection 0x0 (response).
<info> app: Data len is set to 0x14(20)
<debug> app: ATT MTU exchange completed. central 0xF7 peripheral 0xF7
<info> app: BLE event received. Event type = 58

<info> app: BLE event received. Event type = 18

<debug> app: Battery ADC event number: 12
<debug> app: Battery voltage: 4002
<debug> app: Battery percentage: 77%
<debug> app: Battery ADC event number: 13
<debug> app: Battery voltage: 4002
<debug> app: Battery percentage: 77%
<debug> app: Battery ADC event number: 14
<debug> app: Battery voltage: 4006
<debug> app: Battery percentage: 78%
<info> app: systemProcessEvent SYSTEM_BATTERY_DRAINING_EVT
<info> app: BLE event received. Event type = 18

<info> app: BLE_ADV_EVT_FAST event
<info> app: BLE event received. Event type = 17

<info> app: Disconnected

Going to have to get another Nordic dev kit to use as a BLE sniffer?
Is there anything else I can do?

This is my first attempt at programming using Monkey C; so I may be making some more basic mistakes. I tried to register a listener on the class that did the scan.
This passes the first ScanResult via the listener back to another class that does the connect.


class NovaApp extends Application.AppBase {

	var nble = new NovaBle();
	var myDevice = null;

    function initialize() {
        AppBase.initialize();
        
        Ble.setDelegate( nble );
        
        nble.registerProfiles();
        nble.registerScanResultListener( self );
        
        Ble.setScanState( Ble.SCAN_STATE_SCANNING );
        
    }
    
    function scanListener( ScanResult ){
    	Ble.setScanState( Ble.SCAN_STATE_OFF );
    	System.println( "AvailableConnectionCount is "+ Ble.getAvailableConnectionCount() );
    	try{
    		myDevice = Ble.pairDevice( ScanResult );
    		System.println( "paired device " + myDevice );
    		if( myDevice instanceof Ble.Device ){
    			System.println( "paired IS A DEVICE " + myDevice.getName() );
    			System.println( "AvailableConnectionCount is "+ Ble.getAvailableConnectionCount() );
    		}
    		if( myDevice.isConnected() ){
    			System.println( "reports Connected" );
    		}
    	}catch( exception ){
    		System.println( exception.getErrorMessage() );
    	}
    	
    }

class NovaBle extends Ble.BleDelegate {
  
    var listener = null;
  
    function initialize() {
        BleDelegate.initialize();
    }
    
    function registerScanResultListener( novaApp ){
    	listener = novaApp;
    }
    
    
    
    function onProfileRegister( uuid, status ) {
    	System.println( "profile registered " + uuid.toString() );
    }
    
    function onScanResults( scanResults ){
    	var item = scanResults.next();
    	while( item ){
    		if( item instanceof Ble.ScanResult ){
    			System.println( "got scan result " + item.getDeviceName() );
    			listener.scanListener( item );
    			break;
    		}
    		item = scanResults.next();
    	}
    }
    
    function onConnectedStateChange( device, state ){
    	System.println( device.getName() + " state " + state );
    }
    

Have hit a wall. So hopefully one of you has some ideas.

Regards,
Owain

  • When you call Ble.pairDevice(), it can take some time to connect, and to see when you're connect, it will be in the BLE delegate in the onConnectedStateChanged() callback. the pairDevice() call returns right away.

    In onConnectStateChanged() look for 

    state==Ble.CONNECTION_STATE_CONNECTED

  • Things I do, is when I'm communicating with a BLE device, I set a timeout, so if I don't hear back in x seconds,, I reset the connection and try again.  This includes when I'm pairing.

    Also, I check the RSSI in the scan result, and have found that if it's much worse than about -85, the connection might not be that stable due to the distance.

    When you see the scan result, that's using the radio on the ble device, but when you try to pair, it's using the radio on your end and the two might not be equal.

    You may also notice a deference based on which garmin device, as well as between a Garmin device and running in the sim.

  •     function onConnectedStateChange( device, state ){
        	System.println( device.getName() + " state " + state );
        }

    One of the issues is I am see no call of that method in the delegate. No printf or BP hit on this method; whereas onScanResults is being called.

  • got scan result NOVA_31 RSSI -58

    And I see in my peripheral device debug that indicates the connection is made. Then after a few seconds the connection is dropped.

    Also the Ble.pairDevice()  returns an object; which reports itself as a Device; yet  getName() on that object results in null. I think I am doing something more basically wrong is the way I am trying to use monkey c with the callback incorrect?

    I'll try making the connection from the deligate locally to see if any difference.

  • Are you using a device (which one?) or are you testing with the simulator?

    I wonder if the device is rejecting the connection if it's dropping right away, or if CIQ is trying to connect in a way the device doesn't like..

    Have you tried using nRFConnect from your phone?

  • Hi Jim,

    Am using the simulator and its nordic front end. My peripheralbis nordic based as well.

    The peripheral device i am using works fine with android app, ios ios app and from nrfconnect/nrfutil on android.

    All indicators at the peripheral seem to Indicate it is connected. The connection only gets dropped after 5 seconds or so as no other activity.

    I'll try with nrfutil on the pc.

    Maybe try connecting to something else, i have a ble heart strap floating around somewhere.

  • With the sim, you using the dongle or the nRF52-DK?  Have you tried it on a garmin device?

    Try don't doing anything until you get onConnectedStateChanged().  It could be that something your doing is happening in a "not quite connected" state. in your log you show

    AvailableConnectionCount is 3, which says to me you're not connected, as 3 is the may per app.  You can only register 3 profiles max.

    I've had real good luck with a Ble HRM, so that's worth a try.

    Another thing you can try is with the NordicThingy52 sample, change the service UUID to your device, but leave everything else the same and see if that connects. 

  • Hi Owain

    Did you ever resolve this? I'm having the same experience with a 3rd party device I'm trying to connect to.

    /anders

  • Solution was to use Nordic Thingy app as blueprint; rather than just trying to do a clean implementation just working from API documents. Initially  I went my own way and all worked fine scanning; starting to connect; but I just didn't get the expected callback.

  • I am currently facing exactly the same problem with a 3rd party device, which has a BLE stack based on HMSoft on a TI CC2251 chip. I can scan an pair, but don't get a device name after pairing, and no connection. I used the NordicThingy52 sample as template.

    Is there anything to prepare after a succesful scan and having a scan iterator for the target device, before pairing the device?