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;