nrf52-dfu icon indicating copy to clipboard operation
nrf52-dfu copied to clipboard

Missing SLIP Escaping in command transfers

Open BatListener opened this issue 5 years ago • 0 comments

Thanks a lot for sharing, that helped me a lot! One topic I stumbled on: There is no SLIP escaping when sending commands to the nRF bootloader. This can create problems when a command parameter contains the EOM character (0xC0). The bootloader on the nRF side then prematurely cuts the commad block, leaving possibly invalid parameters for its upper levels. I had that problem with a specific payload length of a block to download. The last CREATE OBJECT command will use the remaining size of the block instead of the maximum block size. If that remainig blocksize generates a 0xC0 in the length parameter of the CREATE OBJECT command, the command will fail. I had that with a remaining block size of 2240 bytes, which results in a length encoding of 0xC0, 0x08, 0x00, 0x00. Correction is easy: Just add SLIP escaping in fwuPrepareSendBuffer(). I did it this way:

static void fwuPrepareSendBuffer(TFwu *fwu, uint8_t *data, uint8_t len)
{
    // TODO assert privateCommandState == FWU_CS_IDLE | _DONE | _FAIL
    // TODO assert len <= FWU_REQUEST_BUF_SIZE
    
    uint8_t i;
    uint8_t *p = &fwu->privateRequestBuf[0];

    fwu->privateRequestIx = 0;
    fwu->privateRequestLen = len + 1;
    fwu->privateResponseLen = 0;

    // Copy the data into our internal buffer.
    // Handle SLIP escaping.
    for (i = 0; i < len; i++) {
        // SLIP escape characters: C0->DBDC, DB->DBDD
        if ((*data == 0xC0) || (*data == 0xDB))  {
            *p++ = 0xDB;
            *p++ = (*data++ == 0xC0) ? 0xDC : 0xDD;
            fwu->privateRequestLen++;
        } else {
            *p++ = *data++;
        }
    }
    
    // Add the end-of-message marker.
    *p = FWU_EOM;
    
    // Ready to send!
    fwu->privateCommandRequest = FWU_CR_SEND;
}

Regards and many thanks for sharing! Michael

BatListener avatar Oct 01 '20 14:10 BatListener