nrf52832 ble_peripheral dfu via ble_center

Hi,

I am trying to update the firmware from ble_center to ble_peripheral via BLE DFU(SDK version is "nRF5_SDK_17.0.2_d674dde"),

On the ble_peripheral side I can successfully update using the app(nRF Connect),but I have a problem when I want to update with the ble_center

first I created ble_dfu_c, after BLE_DFU_C_EVT_DISCOVERY_COMPLETE, I enable indication as follows

static uint32_t cccd_configure(ble_dfu_c_t * p_ble_dfu_c, bool enable)
{
    NRF_LOG_INFO("Configuring CCCD. CCCD Handle = %d, Connection Handle = %d",
                  p_ble_dfu_c->peer_dfu_db.hrm_cccd_handle,
                  p_ble_dfu_c->conn_handle);

    nrf_ble_gq_req_t dfu_c_req;
    uint8_t          cccd[BLE_CCCD_VALUE_LEN];
    uint16_t         cccd_val = enable ? BLE_GATT_HVX_INDICATION : 0;

    cccd[0] = LSB_16(cccd_val);
    cccd[1] = MSB_16(cccd_val);

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

    dfu_c_req.type                        = NRF_BLE_GQ_REQ_GATTC_WRITE;
    dfu_c_req.error_handler.cb            = gatt_error_handler;
    dfu_c_req.error_handler.p_ctx         = p_ble_dfu_c;
    dfu_c_req.params.gattc_write.handle   = p_ble_dfu_c->peer_dfu_db.hrm_cccd_handle;
    dfu_c_req.params.gattc_write.len      = BLE_CCCD_VALUE_LEN;
    dfu_c_req.params.gattc_write.p_value  = cccd;
    dfu_c_req.params.gattc_write.write_op = BLE_GATT_OP_WRITE_REQ;

    return nrf_ble_gq_item_add(p_ble_dfu_c->p_gatt_queue, &dfu_c_req, p_ble_dfu_c->conn_handle);
}


uint32_t ble_dfu_c_hrm_notif_enable(ble_dfu_c_t * p_ble_dfu_c)
{
    VERIFY_PARAM_NOT_NULL(p_ble_dfu_c);

    return cccd_configure(p_ble_dfu_c, true);
}

At present, no errors info are returned, and the value of reading cccd is 0x002,

Then I send 0x01 to let the ble_peripheral into dfu mode, it doesn't work.

//ble_dfu_c.c
uint32_t ble_dfu_c_string_send(ble_dfu_c_t * p_ble_dfu_c, uint8_t * p_string, uint16_t length)
{
    VERIFY_PARAM_NOT_NULL(p_ble_dfu_c);

    nrf_ble_gq_req_t write_req;

    memset(&write_req, 0, sizeof(nrf_ble_gq_req_t));

    if (length > NRF_SDH_BLE_GATT_MAX_MTU_SIZE - 3)
    {
        NRF_LOG_WARNING("Content too long.");
        return NRF_ERROR_INVALID_PARAM;
    }
    if (p_ble_dfu_c->conn_handle == BLE_CONN_HANDLE_INVALID)
    {
        NRF_LOG_WARNING("Connection handle invalid.");
        return NRF_ERROR_INVALID_STATE;
    }

    write_req.type                        = NRF_BLE_GQ_REQ_GATTC_WRITE;
    write_req.error_handler.cb            = gatt_error_handler;
    write_req.error_handler.p_ctx         = p_ble_dfu_c;
    write_req.params.gattc_write.handle   = p_ble_dfu_c->peer_dfu_db.hrm_handle;
    write_req.params.gattc_write.len      = length;
    write_req.params.gattc_write.offset   = 0;
    write_req.params.gattc_write.p_value  = p_string;
    write_req.params.gattc_write.write_op = BLE_GATT_OP_WRITE_CMD;
    write_req.params.gattc_write.flags    = BLE_GATT_EXEC_WRITE_FLAG_PREPARED_WRITE;

    NRF_LOG_INFO("%d ", strlen(p_string));
    NRF_LOG_INFO("%d ", strlen(write_req.params.gattc_write.p_value));
    for(int i=0;i<strlen(write_req.params.gattc_write.p_value);i++ )
          NRF_LOG_INFO("%02X ", write_req.params.gattc_write.p_value[i]);
      

    return nrf_ble_gq_item_add(p_ble_dfu_c->p_gatt_queue, &write_req, p_ble_dfu_c->conn_handle);
}

// main.c
uint8_t buff[1] = {0x01};
ble_dfu_c_string_send(&m_ble_dfu_c, buff, 1);

I tried to add some logs and found that BLE_GATTS_EVT_HVC is not triggered on the ble_peripheral side,

So the BLE_GATTC_EVT_HVX of the ble_center does not receive the return data

Is there something I forgot that caused the ble_peripheral doesn't receive the data()?

Parents Reply
  • Hi 

    after using sniffer log, the data sent on air as below

    I found [Service UUID: Generic Attribute Profile (0x1801)] is incorrect, it shound be 0xfe59

    1. how can i modify the service uuid to be 0xfe59

    #define BLE_DFU_SERVICE_UUID 0xFE59
    
    uint32_t ble_dfu_c_init(ble_dfu_c_t * p_ble_dfu_c, ble_dfu_c_init_t * p_ble_dfu_c_init)
    {
        VERIFY_PARAM_NOT_NULL(p_ble_dfu_c);
        VERIFY_PARAM_NOT_NULL(p_ble_dfu_c_init);
    
        ble_uuid_t dfu_uuid;
    
        dfu_uuid.type = BLE_UUID_TYPE_BLE;
        dfu_uuid.uuid = BLE_DFU_SERVICE_UUID;
    
        p_ble_dfu_c->evt_handler                 = p_ble_dfu_c_init->evt_handler;
        p_ble_dfu_c->error_handler               = p_ble_dfu_c_init->error_handler;
        p_ble_dfu_c->p_gatt_queue                = p_ble_dfu_c_init->p_gatt_queue;
        p_ble_dfu_c->conn_handle                 = BLE_CONN_HANDLE_INVALID;
        p_ble_dfu_c->peer_dfu_db.hrm_cccd_handle = BLE_GATT_HANDLE_INVALID;
        p_ble_dfu_c->peer_dfu_db.hrm_handle      = BLE_GATT_HANDLE_INVALID;
    
        return ble_db_discovery_evt_register(&dfu_uuid);
    }

    2. It's strange that I have another service(NUS) with the same situation([Service UUID: Generic Attribute Profile (0x1801)] ) but it can pass the value normally,how to explain this?

Children
Related