Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs

nRF52840 DFU System

Hi, you all. 

I am working on the DFU system with my custom BLE service. I have successfully integrated DFU into my system. I structured a system with integrating DFU into my service by adding DFU as a characteristic of my service. But I do not want to show that DFU characteristic to the users. I want to hide the DFU characteristic. How can I do that? Is there any other structure for the hide DFU? 

These are my codes that create and handle the DFU system. 

characteristic attribute


static uint32_t dfu_control_char_add(ble_cus_t * p_cus, const ble_cus_init_t * p_cus_init)
{
    uint32_t err_code;
    ble_add_char_params_t dfu_control;

    memset(&dfu_control, 0, sizeof(dfu_control));

    dfu_control.uuid = CUSTOM_CHAR_DFU_CONTROL_UUID;
    dfu_control.uuid_type = p_cus->uuid_type;
    dfu_control.max_len = MAX_CTRL_POINT_RESP_PARAM_LEN;  // 3 bytes
    dfu_control.init_len = 0;
    dfu_control.char_props.write = 1;
    dfu_control.char_props.indicate = 1;
    dfu_control.write_access = SEC_OPEN;  // You may want to secure this
    dfu_control.cccd_write_access = SEC_OPEN;
    dfu_control.is_var_len = false;
    dfu_control.is_defered_write = true;  // Important for DFU control point

    err_code = characteristic_add(p_cus->service_handle, &dfu_control, &p_cus->dfu_control_handles);
    APP_ERROR_CHECK(err_code);

    return NRF_SUCCESS;
}

inside on_write function

    // Handle DFU Control Point CCCD writes (indication enable/disable)
    if (p_evt_write->handle == p_cus->dfu_control_handles.cccd_handle)
    {
        if (ble_srv_is_indication_enabled(p_evt_write->data))
        {
            NRF_LOG_INFO("DFU indications ENABLED");
        }
        else
        {
            NRF_LOG_INFO("DFU indications DISABLED");
        }
    }

    // Handle DFU Control Point value writes (actual commands)
    if (p_evt_write->handle == p_cus->dfu_control_handles.value_handle)
    {
        NRF_LOG_INFO("DFU Control Point command received");
    
        // Check if indications are enabled
        uint8_t cccd_val[2];
        ble_gatts_value_t value = {.p_value = cccd_val, .len = 2, .offset = 0};
        uint32_t err_code = sd_ble_gatts_value_get(p_cus->conn_handle, 
                                                    p_cus->dfu_control_handles.cccd_handle, 
                                                    &value);
    
        if (err_code == NRF_SUCCESS && ble_srv_is_indication_enabled(cccd_val))
        {
            // Process DFU command
            if (p_evt_write->len > 0 && p_evt_write->data[0] == DFU_OP_ENTER_BOOTLOADER)
            {
                NRF_LOG_INFO("Enter bootloader command received");
            
                // Send response
                err_code = ble_cus_dfu_response_send(p_cus, DFU_OP_ENTER_BOOTLOADER, DFU_RSP_SUCCESS);
                if (err_code != NRF_SUCCESS)
                {
                    NRF_LOG_ERROR("Failed to send DFU response: 0x%x", err_code);
                }
            
                // Set flag to enter bootloader after indication confirmation
                p_cus->is_waiting_for_reset = true;
            }
        }
        else
        {
            NRF_LOG_WARNING("DFU command received but indications not enabled");
        }
    }

inside ble_cus_on_ble_evt function

        case BLE_GATTS_EVT_HVC:
            ble_gatts_evt_hvc_t const * p_hvc = &p_ble_evt->evt.gatts_evt.params.hvc;
            
            if (p_hvc->handle == p_cus->dfu_control_handles.value_handle)
            {
                // Enter bootloader if we were waiting for reset after indication confirmation
                if (p_cus->is_waiting_for_reset)
                {
                    NRF_LOG_INFO("Entering bootloader...");
                    
                    // Prepare for bootloader
                    uint32_t err_code = sd_power_gpregret_clr(0, 0xffffffff);
                    APP_ERROR_CHECK(err_code);
                    
                    err_code = sd_power_gpregret_set(0, BOOTLOADER_DFU_START);
                    APP_ERROR_CHECK(err_code);
                    
                    // Signal DFU mode to power management
                    nrf_pwr_mgmt_shutdown(NRF_PWR_MGMT_SHUTDOWN_GOTO_DFU);
                }
            }
            break;

  • But I do not want to show that DFU characteristic to the users. I want to hide the DFU characteristic. How can I do that?

    Hi,

    There is no easy way of doing that no. The only thing I can think of is that you for instance send some arbitrary command from the central device, which will cause the peripheral to disconnect, then add the DFU characteristics, and start advertising again with the now implemented DFU characteristics.

    Kenneth

Related