Dfu Error "Unable to write Op Code 3 (error 133)"

Hi,

I have a custom board with nRF52840/SDK 16/Softdevice 7.3.0 using Secure Dfu Bootloader. On my Android device I use Nordic Dfu Library. I have tried all available Dfu lib versions from 1.11.0 to 2.0.2.
I've had Dfu up and running for a few months and it has been working fine for most Android devices I have tested so far. However I just recently bought a Samsung Galaxy Tab A8/Android 11 and the Dfu does not work on this device returning the error 'Unable to write Op Code 3 (error 133)'. Below I will show logs from Android Studio logcat and also from my Peripheral custom board for case 1 (Samsung Galaxy Tab A8/Android 11 ) where Dfu fails and case 2 (Samsung Galaxy S20 FE/Android 12) where Dfu succeeds. I also provide the relevant app code section I use for Dfu. In the app code I have tried different settings, for example setting the PRN value to 1 and increasing the 'preparDataObjectDelay' up to 400.
I am grateful for any tip.

Case 1: Ble Client Samsung TAB A8/Android 11: -------------------------------------------------------------------------------------------------------------

2022-05-23 13:38:23.964 25812-27662/com.prisma.ui I/DfuImpl: Enabling notifications...
2022-05-23 13:38:23.965 25812-27662/com.prisma.ui D/BluetoothGatt: setCharacteristicNotification() - uuid: 8ec90001-f315-4f60-9fb8-838830daea50 enable: true
2022-05-23 13:38:24.995 25812-27662/com.prisma.ui I/DfuImpl: Setting object to Command (Op Code = 6, Type = 1)
2022-05-23 13:38:25.056 25812-27662/com.prisma.ui I/DfuImpl: Command object info received (Max size = 512, Offset = 0, CRC = 00000000)
2022-05-23 13:38:25.062 25812-27662/com.prisma.ui I/DfuImpl: Sending the number of packets before notifications (Op Code = 2, Value = 0)
2022-05-23 13:38:25.093 25812-27662/com.prisma.ui I/DfuImpl: Creating Init packet object (Op Code = 1, Type = 1, Size = 141)
2022-05-23 13:38:25.123 25812-27662/com.prisma.ui I/DfuImpl: Sending 141 bytes of init packet...
2022-05-23 13:38:25.126 25812-27662/com.prisma.ui I/DfuImpl: Sending init packet (Value = 12-8A-01-0A-44-08-01-12-40-08-01-10-34-1A-02-A3-02-20-00-28-00-30-00-38-BC-F0-11-42-24-08-03-12-20-13-5B-83-CD-0F-EC-D5-26-36-5C-AE-0D-5D-71-E8-D5-BD-1B-AD-5E-F0-3C-0D-32-FA-32-07-6F-C0-C4-C5-DC-48-00-52-04-08-01-12-00-10-00-1A-40-00-37-1B-3B-A3-38-02-AA-65-BA-15-04-1A-13-86-C5-F7-2D-D6-87-A9-8E-7C-42-B1-A1-0B-C6-A1-8F-0D-6F-46-89-82-94-9D-17-11-57-4D-37-B9-01-1F-A3-B2-22-55-BA-98-D5-B0-58-01-9C-FD-3A-64-41-29-AA-3F-47)
2022-05-23 13:38:25.138 25812-27662/com.prisma.ui I/DfuImpl: Sending Calculate Checksum command (Op Code = 3)
2022-05-23 13:38:31.124 25812-27285/com.prisma.ui E/DfuImpl: Characteristic write error: 133
2022-05-23 13:38:31.125 25812-27285/com.prisma.ui D/BluetoothGatt: onClientConnectionState() - status=8 clientIf=10 device=C6:5D:74:1E:7D:29
2022-05-23 13:38:31.128 25812-27662/com.prisma.ui E/DfuBaseService: Unable to write Op Code 3 (error 133)
2022-05-23 13:38:31.133 25812-25812/com.prisma.ui D/BleFileTransferActivity: ----- FTBA  DfuProgress->onDeviceDisconnecting
2022-05-23 13:38:31.147 25812-25812/com.prisma.ui I/DfuBaseService: Action received: android.bluetooth.device.action.ACL_DISCONNECTED
2022-05-23 13:38:31.153 25812-27285/com.prisma.ui W/DfuBaseService: Target device disconnected with status: 8
2022-05-23 13:38:31.159 25812-27662/com.prisma.ui I/DfuBaseService: Disconnecting from the device...
2022-05-23 13:38:31.159 25812-27662/com.prisma.ui D/BluetoothGatt: cancelOpen() - device: C6:5D:74:1E:7D:29
2022-05-23 13:38:31.175 25812-27662/com.prisma.ui D/BluetoothGatt: refresh() - device: C6:5D:74:1E:7D:29


Ble Peripheral Custom Board nRF52840, SDK 16, softdevice 7.3.0:
main: SoftDevice Firmware Id: 0x123
PR Bootloader 2022.04.06.0
Bootloader start address: 0xF1000
dfu_observer: NRF_DFU_EVT_DFU_INITIALIZED
dfu_observer: NRF_DFU_EVT_TRANSPORT_ACTIVATED
dfu_observer: NRF_DFU_EVT_DFU_STARTED
dfu_observer: NRF_DFU_EVT_TRANSPORT_DEACTIVATED

Case 2: Samsung S20 Fe/Android 12: -------------------------------------------------------------------------------------------------------------------------------------

2022-05-23 13:27:07.244 13883-14153/com.prisma.ui I/DfuImpl: Sending 141 bytes of init packet...
2022-05-23 13:27:07.248 13883-14153/com.prisma.ui I/DfuImpl: Sending init packet (Value = 12-8A-01-0A-44-08-01-12-40-08-01-10-34-1A-02-A3-02-20-00-28-00-30-00-38-BC-F0-11-42-24-08-03-12-20-13-5B-83-CD-0F-EC-D5-26-36-5C-AE-0D-5D-71-E8-D5-BD-1B-AD-5E-F0-3C-0D-32-FA-32-07-6F-C0-C4-C5-DC-48-00-52-04-08-01-12-00-10-00-1A-40-00-37-1B-3B-A3-38-02-AA-65-BA-15-04-1A-13-86-C5-F7-2D-D6-87-A9-8E-7C-42-B1-A1-0B-C6-A1-8F-0D-6F-46-89-82-94-9D-17-11-57-4D-37-B9-01-1F-A3-B2-22-55-BA-98-D5-B0-58-01-9C-FD-3A-64-41-29-AA-3F-47)
2022-05-23 13:27:07.260 13883-14153/com.prisma.ui I/DfuImpl: Sending Calculate Checksum command (Op Code = 3)
2022-05-23 13:27:07.292 13883-14153/com.prisma.ui I/DfuImpl: Checksum received (Offset = 141, CRC = 742FABE1)
2022-05-23 13:27:07.292 13883-14153/com.prisma.ui I/DfuImpl: Executing init packet (Op Code = 4)


Ble Peripheral Custom Board nRF52840, SDK 16, softdevice 7.3.0:
main: SoftDevice Firmware Id: 0x123
PR Bootloader 2022.04.06.0
Bootloader start address: 0xF1000
dfu_observer: NRF_DFU_EVT_DFU_INITIALIZED
dfu_observer: NRF_DFU_EVT_TRANSPORT_ACTIVATED
dfu_observer: NRF_DFU_EVT_DFU_STARTED
dfu_observer: NRF_DFU_EVT_OBJECT_RECEIVED
dfu_observer: NRF_DFU_EVT_OBJECT_RECEIVED
dfu_observer: NRF_DFU_EVT_OBJECT_RECEIVED
dfu_observer: NRF_DFU_EVT_OBJECT_RECEIVED
dfu_observer: NRF_DFU_EVT_OBJECT_RECEIVED
dfu_observer: NRF_DFU_EVT_OBJECT_RECEIVED
dfu_observer: NRF_DFU_EVT_OBJECT_RECEIVED
dfu_observer: NRF_DFU_EVT_OBJECT_RECEIVED
dfu_observer: NRF_DFU_EVT_OBJECT_RECEIVED

Dfu app code section: ------------------------------------------------------------------------------------------------------------------

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
DfuServiceInitiator.createDfuNotificationChannel(this);
}
final DfuServiceInitiator starter = new DfuServiceInitiator(device.getAddress())
.setDeviceName(device.getName())
.setKeepBond(true)
.setPacketsReceiptNotificationsEnabled(true)
.setPacketsReceiptNotificationsValue(DfuServiceInitiator.DEFAULT_PRN_VALUE);

// If you want to have experimental buttonless DFU feature (DFU from SDK 12.x only!) supported call
// additionally:

starter.setUnsafeExperimentalButtonlessServiceInSecureDfuEnabled(true);
// but be aware of this: devzone.nordicsemi.com/.../
// and other issues related to this experimental service.

// For DFU bootloaders from SDK 15 and 16 it may be required to add a delay before sending each
// data packet. This delay gives the DFU target more time to perpare flash memory, causing less
// packets being dropped and more reliable transfer. Detection of packets being lost would cause
// automatic switch to PRN = 1, making the DFU very slow (but reliable).
starter.setPrepareDataObjectDelay(300L);

// Init packet is required by Bootloader/DFU from SDK 7.0+ if HEX or BIN file is given above.
// In case of a ZIP file, the init packet (a DAT file) must be included inside the ZIP file.
Uri mFileStreamUri = Uri.fromFile(new File(filePath));

starter.setZip(mFileStreamUri, filePath);
controller = starter.start(getApplicationContext(), DfuService.class);
// You may use the controller to pause, resume or abort the DFU process.

Parents
  • Hi,

    I notice that there is a lot of retransmissions in the failing trace. Do you by any chance have a log from the nRF side in this case (using the debug bootloader with RTT logging)?

    Other than that nothing sticks out, but I have asked our mobile developers to take a look.

    Edit: Does it always fail on the failing devices, or just from time to time?

  • Hi,

    I have tested not and looked at the results together with our BLE stack team. The issue here is that the tablet is violating the Bluetooth specification, by sending longer write commands than it itself stated that it supported (the MaxTx from the data length update). The SoftDevice will disconnect on spec violations by the peer. So this looks like a bug in the BLE controller on the tablet, and must be fixed there. You can work around it on the nRF side though, by not supporting long packets in the bootloader. The downside of this is that the DFU operation takes longer, but this may be acceptable as it is not done frequently.

    If you want to work around it in the bootloader, you can do this change (this is from SDH 17.1.0, but would be similar for older SDKs):

    diff --git a/components/libraries/bootloader/ble_dfu/nrf_dfu_ble.c b/components/libraries/bootloader/ble_dfu/nrf_dfu_ble.c
    index a2fdf5e..c59be83 100644
    --- a/components/libraries/bootloader/ble_dfu/nrf_dfu_ble.c
    +++ b/components/libraries/bootloader/ble_dfu/nrf_dfu_ble.c
    @@ -725,8 +725,8 @@ static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
     
                 ble_gap_data_length_params_t const dlp =
                 {
    -                .max_rx_octets = BLE_GAP_DATA_LENGTH_AUTO,
    -                .max_tx_octets = BLE_GAP_DATA_LENGTH_AUTO,
    +                .max_rx_octets = BLE_GAP_DATA_LENGTH_DEFAULT,
    +                .max_tx_octets = BLE_GAP_DATA_LENGTH_DEFAULT,
                 };
     
                 err_code = sd_ble_gap_data_length_update(p_ble_evt->evt.gatts_evt.conn_handle,
    

  • Thanks, 

    What is BLE_GAP_DATA_LENGTH_DEFAULT value ? 

    Best regards.

  • Hi,

    Ah, sorry, I forgot to copy the definition. That should be defined to 27 (which is the normal packet length without DLE).

  • Hi,
    Great, now dfu works on my Samsung Tab A8. I made the workaround on SDK16.
    I will try dfu on the Nokia T20 Tablet after the weekend.
    Time for Dfu increased with 20% roughly.
    This will work as a short time solution.

    Regarding a long time solution where Samsung will correct the problem in their BLE controller, I have a few questions.

    1. Will you notify them so that they become aware of the problem?

    2. If/when Samsung corrects the problem in their BLE controller, how can I be notified that the problem has been corrected?

    3. Would it be possible for me to upgrade Samsung device? How do I do that? I assume the BLE controller has firmware that could be replaced by a new, corrected version?

Reply
  • Hi,
    Great, now dfu works on my Samsung Tab A8. I made the workaround on SDK16.
    I will try dfu on the Nokia T20 Tablet after the weekend.
    Time for Dfu increased with 20% roughly.
    This will work as a short time solution.

    Regarding a long time solution where Samsung will correct the problem in their BLE controller, I have a few questions.

    1. Will you notify them so that they become aware of the problem?

    2. If/when Samsung corrects the problem in their BLE controller, how can I be notified that the problem has been corrected?

    3. Would it be possible for me to upgrade Samsung device? How do I do that? I assume the BLE controller has firmware that could be replaced by a new, corrected version?

Children
  • Hi,

    Roland B said:
    1. Will you notify them so that they become aware of the problem?

    Yes, we are contacting both Unisoc and Samsung.

    Roland B said:
    2. If/when Samsung corrects the problem in their BLE controller, how can I be notified that the problem has been corrected?

    You will have to ask Samsung about that. We do not have any insight into how/when Unisoc and/or Samsung fixes issues in their products.

    Roland B said:
    3. Would it be possible for me to upgrade Samsung device? How do I do that? I assume the BLE controller has firmware that could be replaced by a new, corrected version?

    You have to ask Samsung about that as well.

  • Ok, thanks.

    My Nokia T20 Tablet also works now with your suggested workaround.
    Regarding the required SDK modification, maybe this should be a setting in sdk_config.h to assign values to max_rx_octets/max_tx_octets used by ../components/libraries/bootloader/ble_dfu/nrf_dfu_ble.c?
    Otherwise one needs to remember to do this patch every time when switching to a new SDK version.

  • Roland B said:
    My Nokia T20 Tablet also works now with your suggested workaround.

    That makes sense, but it is good to get it confirmed.

    Roland B said:
    Regarding the required SDK modification, maybe this should be a setting in sdk_config.h to assign values to max_rx_octets/max_tx_octets used by ../components/libraries/bootloader/ble_dfu/nrf_dfu_ble.c?
    Otherwise one needs to remember to do this patch every time when switching to a new SDK version.

    Good point. However, the problem is that the bootloader implementation does not use the sdk_config.h for this (I cannot say why, most likely historic reasons). And the nRF5 SDK is now in maintenance mode (see nRF Connect SDK and nRF5 SDK statement) so I do not expect this will ever change.

    Also note that here we are just working around an issue in the peer device, and we do not fully know why it misbehaved or how/why this workaround works. As we effectively prevent long packets it is highly likely that it will be a effective workaround going forward, though. But to be 100% confident, this needs to be fixed in the Android devices.

  • Ok, thanks for info. I have no further comments on this case.

Related