NordicSemiconductor / Android-nRF-Mesh-Library

The Bluetooth Mesh Provisioner and Configurator library.
https://www.nordicsemi.com/
BSD 3-Clause "New" or "Revised" License
414 stars 177 forks source link

How to map a BLE scan result to mesh node? #481

Closed FluffyBunniesTasteTheBest closed 2 years ago

FluffyBunniesTasteTheBest commented 2 years ago

Is there a way to tell to which mesh node a BLE scan result belongs to?

Is your feature request related to a problem? Please describe. When our app displays the firmware update UI, it should filter out all devices that are not part of the mesh network. Imagine, for example, multiple (isolated) mesh networks that are close to each other. When a user wants to do a DFU, it should not be possible to update a node that belongs to another mesh. Problem is, that the BLE scan delivers all devices in vicinity - including those that belong to another mesh.

roshanrajaratnam commented 2 years ago

@FluffyBunniesTasteTheBest So each provisioned node advertises with a Mesh Proxy Service and a Network ID. If you filter all provisioned nodes based only on the Proxy Service you will always see nodes belonging to the different mesh networks. This is where the Network ID comes in to the picture. Each provisioned node advertises with a Network ID based on it's primary network key. This allows you to identify nodes belonging to different networks.

Generally we should not rely on a bluetooth address in mesh as it may change after a device reboot or after firmware update depending on it's implementation. One way to identify a node is using Node Identity. If you have noticed in the sample app, right after provisioning the app reconnects to the same node using Node Identity. This is because soon after a node is provisioned it advertises with Node Identity for 60 seconds which allows you to reconnect to the same node. Therefore in my opinion you could send ConfigNodeIdentitySet message which will make the node particular node to advertise with it's Node Identity and you can filter your scan results for a node advertising with a matching Node Identity. Here's how filter a node based on it's Node Identity and check

https://github.com/NordicSemiconductor/Android-nRF-Mesh-Library/blob/d7b7e61ef5944bb986a9d2fc99145f59ecfaed56/app/src/main/java/no/nordicsemi/android/nrfmesh/viewmodels/ScannerRepository.java#L89

Check out advertising section in chapter 7 in Bluetooth Mesh Network specification 1.0.1 which has detailed explanation on both Network ID and Node Identity.

Let me know if this works for you.

FluffyBunniesTasteTheBest commented 2 years ago

@roshanrajaratnam Thank you very much for the detailed explanation! One more question though:

It's basically working with isAdvertisingWithNetworkIdentity(). Only problem is that if the proxy is switched off (a wanted feature of our device), then the node stops to advertise itself with network identity. Right now, I'm getting the service data from MESH_PROXY_UUID (same like in the librarie's scan.java):

final byte[] serviceData = Utils.getServiceData(result, MESH_PROXY_UUID);
if (meshManagerApi.isAdvertisingWithNetworkIdentity(serviceData)) {
    if (meshManagerApi.networkIdMatches(networkId, serviceData)) {
        ...
    }
}

Is there a way to get the network identity even if the proxy is disabled? Maybe through another uuid than MESH_PROXY_UUID? If somehow possible, I'd prefer not send a `ConfigNodeIdentitySet' (or any other mesh messages), because DFU should also work while the Android app is disconnected. Do you have any ideas?

roshanrajaratnam commented 2 years ago

Right. I guess in that case a Secure Network Beacon would be an option here, you can get the Network ID from a secure network beacon. Checkout section 3.9 and 3.9.1 and here https://github.com/NordicSemiconductor/Android-nRF-Mesh-Library/blob/d7b7e61ef5944bb986a9d2fc99145f59ecfaed56/app/src/main/java/no/nordicsemi/android/nrfmesh/viewmodels/ScannerRepository.java#L166

FluffyBunniesTasteTheBest commented 2 years ago

@roshanrajaratnam Thank you very much for your help!