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

Secure DFU from s130/s132

Hi, We're using a 51422 with s130 to perform OTA DFU.

Both bases for bootloader and central are from sdk 12.2.

We have already implemented the older DFU (non-secure) for nRF51, which was a 128bit UUID, and it is working fine.

We started implementing the nRF52 DFU (16bit - 0xFE59). The initial conenction is successful, but when reaching the on_db_disc_evt, we get 2 characteristics that have 0 in both UUID and type.

Is this correct? If so, how do you distinguish between the characteristics and assign them?

This is the code for registering the service:

uint32_t ble_sdfu_c_init(ble_sdfu_c_t * p_ble_sdfu_c, ble_sdfu_c_init_t * p_ble_sdfu_c_init)
{
    VERIFY_PARAM_NOT_NULL(p_ble_sdfu_c);
    VERIFY_PARAM_NOT_NULL(p_ble_sdfu_c_init);
    
    ble_uuid_t    sdfu_uuid = {
        .type = BLE_UUID_TYPE_BLE,
        .uuid = BLE_UUID_SDFU_SERVICE,  // 0xFE59
    };

    p_ble_sdfu_c->evt_handler                         = p_ble_sdfu_c_init->evt_handler;
    p_ble_sdfu_c->conn_handle                         = BLE_CONN_HANDLE_INVALID;
    p_ble_sdfu_c->handles.sdfu_control_point_handle   = BLE_GATT_HANDLE_INVALID;
    p_ble_sdfu_c->handles.sdfu_packet_handle          = BLE_GATT_HANDLE_INVALID;

    return ble_db_discovery_evt_register(&sdfu_uuid);
}

And this is the callback for the service discovery:

void ble_sdfu_c_on_db_disc_evt(ble_sdfu_c_t * p_ble_sdfu_c, ble_db_discovery_evt_t * p_evt)
{
    ble_sdfu_c_evt_t sdfu_c_evt;
    memset(&sdfu_c_evt,0,sizeof(ble_sdfu_c_evt_t));

    ble_gatt_db_char_t * p_chars = p_evt->params.discovered_db.charateristics;

    // Check if the DFU was discovered.
    if (p_evt->evt_type == BLE_DB_DISCOVERY_COMPLETE &&
        p_evt->params.discovered_db.srv_uuid.uuid == BLE_UUID_SDFU_SERVICE &&
        p_evt->params.discovered_db.srv_uuid.type == BLE_UUID_TYPE_BLE) //p_ble_sdfu_c->uuid_type)
    {
        for (uint32_t i = 0; i < p_evt->params.discovered_db.char_count; i++)
        {
            switch (p_chars[i].characteristic.uuid.uuid)   // <= THIS IS ALWAYS 0
            {
                case BLE_UUID_SDFU_CONTROL_POINT_CHARACTERISTIC:
                    sdfu_c_evt.handles.sdfu_control_point_handle = p_chars[i].characteristic.handle_value;
                    sdfu_c_evt.handles.sdfu_control_point_cccd_handle = p_chars[i].cccd_handle;
                    break;

                case BLE_UUID_SDFU_PACKET_CHARACTERISTIC:
                    sdfu_c_evt.handles.sdfu_packet_handle = p_chars[i].characteristic.handle_value;
                    break;

                default:
                    break;
            }
        }
        if (p_ble_sdfu_c->evt_handler != NULL)
        {
            sdfu_c_evt.conn_handle = p_evt->conn_handle;
            sdfu_c_evt.evt_type    = SDFU_C_EVT_DISCOVERY_COMPLETE;
            p_ble_sdfu_c->evt_handler(p_ble_sdfu_c, &sdfu_c_evt);
        }
    }
}
  • No, both the DFU Packet and DFU Control Point characteristics should have different 128-bit UUIDs. Would it be possible for you to share the project either here on DevZone or Mypage?

  • Unfortunately, I can't share the project at the moment. Is there any other specific part of code you'd like to see?

    How do I read the 128bit of the discovered characteristics? The ble_gattc_char_t struct that is passed to the event handler has only 16bit (or octets 12-13 of 128-bit UUID), but as I said, both handles has 0 in this parameter.

    For now, the only way I've managed to bypass this issue is to hard code char[0] as the packet handle and char[1] as the control point (I based this on the properties values). Obviously this is not ideal.

  • Hi Elias, is there the possibiliy that you could share your DFU-Central source code?

  • Hi all,

    I faced the same issue on my project. The DFU characteristics uuid returned by the db discovery were always 0x0000. I was able to solve it by registering the DFU service to the BLE stack before initiating the db discovery. This way, the BLE stack knows this custom service and can bisect it. At least, that is my understanding.

    Hope this could help others.

    Ben

    uint32_t ble_dfu_init (ble_dfu_t * p_dfu, ble_dfu_evt_handler_t evt_handler)
    {
        uint32_t        err_code;
        ble_uuid_t      service_uuid;
        ble_uuid128_t   nordic_base_uuid = { 0x50, 0xEA, 0xDA, 0x30, 0x88, 0x83, 0xB8, 0x9F,
                                             0x60, 0x4F, 0x15, 0xF3, 0x00, 0x00, 0xC9, 0x8E };
    
        VERIFY_PARAM_NOT_NULL(p_dfu);
    
        // Initialize the service structure
        p_dfu->conn_handle                  = BLE_CONN_HANDLE_INVALID;
        p_dfu->evt_handler                  = evt_handler;
    
        BLE_UUID_BLE_ASSIGN(service_uuid, BLE_DFU_SERVICE_UUID);
    
        // Add proprietary service
        err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY,
                                            &service_uuid,
                                            &(p_dfu->service_handle));
        VERIFY_SUCCESS(err_code);
    
        // Add vendor specific UUID to use with the DFU characteristic
        err_code = sd_ble_uuid_vs_add(&nordic_base_uuid, &p_dfu->uuid_type);
        VERIFY_SUCCESS(err_code);
    
        return (NRF_SUCCESS);
    }
    

Related