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

Identifying unprovisioned mesh device

I'm struggling with how to properly identify an unprovisioned mesh device. Basically when i scan for unprovisioned devices from my iOS app, I'd like for only our devices to show up, not any random mesh device. I'm still struggling to understand all the terminology, but if I understand everything correctly, I should be checking the `p_device_uri` set in `mesh_provisionee_prov_start` against the advertised data, or something. According to the mesh spec, it seems like this data is hashed using the salt function `s1`, which I think corresponds to `OpenSSLHelper.calculateSalt` in the iOS SDK. However, what I'm not understanding is which data to actually check against and how. So far, when I discover unprovisioned proxy nodes, I can do this:

func centralManager(_ central: CBCentralManager,
                        didDiscover peripheral: CBPeripheral,
                        advertisementData: [String: Any],
                        rssi RSSI: NSNumber) {

  if let serviceData = advertisementData[CBAdvertisementDataServiceDataKey] as! [CBUUID: NSData]? {
    let provisioningData = serviceData[MeshServiceProvisioningUUID]
    print("service data: \(provisioningData)")
  }

}

`provisioningData` contains some bytes of data, for me it returned `E754E3DAAFFDEE419AC6AD32896107A80000`, Which is 18bytes. The mesh spec seems to define the beacon format as follows:

But this comes out to 23 bytes, so it can't really match the format of the data I received.

It seems that the nRF Connect application is able to decipher at least some of this data, since it shows the device UUID in its scan view, but since the source of this app is not available I can't check against it.

Any help would be appreciated!

  • HI Jnicklas, 

    cant you identify your devices by looking at the 16-byte Device UUID field in the Unprovisioned Device beacon advertisment packet?,(see section 3.9.2 Unprovisioned Device beacon in the v1.0.1 spec)

    Best regards

    Bjørn 

  • Hi Bjørn,

    Thanks for the response :) From what I understand, the device UUID is unique per device, but what I'm trying to do is identify a "class" of devices, not a specific device. I'm building a product and an accompanying iOS app, when a client purchases the product and downloads the iOS app, I want only this specific product to show up in the provisionable list, but I obviously don't know which exact device they have purchased, if that makes sense?

    Section 3.9.1 is exactly the part of the mesh spec that I screenshotet in my original question, where the unprovisioned device beacon comes out to 23 bytes according to the layout given in the screenshot. What I haven't been able to figure out is how to extract this information in iOS, and then how to use this infromation to identify a class of devices.

    All the best,

    /Jonas

  • Hi Jonas, 

    Yes, you are correct. The Device UUID will be unique per device, so placing a hash of a common identifier in the unprovisioned beacon packet may be the way to go. Have you added the URI data to the example? The pointer to the URI data is passed to mesh_provisionee_prov_start() in the start() function in main(). By defualt this is set to NULL. 

    static void start(void)
    {
        rtt_input_enable(app_rtt_input_handler, RTT_INPUT_POLL_PERIOD_MS);
    
        if (!m_device_provisioned)
        {
            static const uint8_t static_auth_data[NRF_MESH_KEY_SIZE] = STATIC_AUTH_DATA;
            mesh_provisionee_start_params_t prov_start_params =
            {
                .p_static_data    = static_auth_data,
                .prov_complete_cb = provisioning_complete_cb,
                .prov_device_identification_start_cb = device_identification_start_cb,
                .prov_device_identification_stop_cb = NULL,
                .prov_abort_cb = provisioning_aborted_cb,
                .p_device_uri = NULL
            };
            ERROR_CHECK(mesh_provisionee_prov_start(&prov_start_params));
        }
    
        const uint8_t *p_uuid = nrf_mesh_configure_device_uuid_get();
        UNUSED_VARIABLE(p_uuid);
        __LOG_XB(LOG_SRC_APP, LOG_LEVEL_INFO, "Device UUID ", p_uuid, NRF_MESH_UUID_SIZE);
    
        ERROR_CHECK(mesh_stack_start());
    
        hal_led_mask_set(LEDS_MASK, LED_MASK_STATE_OFF);
        hal_led_blink_ms(LEDS_MASK, LED_BLINK_INTERVAL_MS, LED_BLINK_CNT_START);
    }

    Best regards
    Bjørn

  • Hi Bjørn,

    Thanks for the reply, yes I've added a device URI (though I'm not quite sure if its content matters, or is supposed to have any specific format, I've just picked something random). So I think this is supposed to be included in the device beacon.

    What I don't know is how to extract and compare this information in iOS. In other words, when I have discovered a device via the CentralManager in iOS, I will need to do something to compare the data that I receive against the URI that I've set when I call `mesh_provisionee_prov_start`, but how do I do this? Since I just receive a random jumble of bytes, part of which *may* be the hashed URI, it's really hard to tell.

    As I wrote in the original post, the nRF Connect app does extract this information, but its source code is not open source, so I can't check how it does this, and I've been unable to find any documentation. But maybe you could check the source code for nRF Connect on how it does this. I've posted a screenshot from nRF where it shows Device UUID and OOB information below.

    Thank you for the help,

    /Jonas

    nRF Connect showing Device UUID etc

  • I am no iOS or Swift expert, but I would assume that you will get the content of the advertisment packet as an array of bytes. The advertisment packet will consist of several AD structures

    Each of these ad structures start with a byte indicating the length of the structure. The second byte is the type, which will be 0x16 for the Mesh beacon structure. So once youve foudn the correct structure you can fin the URI Hash which will be the the four last octets in that structure. 

Related