[PATCH] xyzModem: Correct xmodem blk verification conditions

Dan Carpenter dan.carpenter at linaro.org
Tue Feb 6 15:05:55 CET 2024


On Tue, Feb 06, 2024 at 09:05:33PM +0800, jihongbin wrote:
> It may be that there are relatively few people using this function, or the
> length of the transmitted data is less than 128byte * 255 byte, so the
> triggering conditions for the above problems are not encountered;
> 
> I actually discovered this problem during testing. Continuous transmission
> always fails at block 255.
> 
> The following is the protocol's definition of blk cblk, cblk = 255 - blk
> The original content of the agreement
> (https://www.menie.org/georges/embedded/xmodem_specification.html) is as
> follows:
> -------- 3. MESSAGE BLOCK LEVEL PROTOCOL
> Each block of the transfer looks like:
> <SOH><blk #><255-blk #><--128 data bytes--><cksum>
> in which:
> <SOH> = 01 hex
> <blk #> = binary number, starts at 01 increments by 1, and
> wraps 0FFH to 00H (not to 01)
> <255-blk #> = blk # after going thru 8080 "CMA" instr, i.e.
> each bit complemented in the 8-bit block number.
> Formally, this is the "ones complement".
> 
> <cksum> = the sum of the data bytes only. Toss any carry.
> 

Thanks, this is good information.  Unfortunately, your patch is not
correct.

Originally you wrote "When the blk sequence number is 255 and cblk is
0, the original XOR condition produces a result of 0, and the judgment
condition will be unsuccessful."

If blk is 255 the cblk should be zero as you say.

common/xyzModem.c
   375    /* Validate the message */
   376    if ((xyz.blk ^ xyz.cblk) != (unsigned char) 0xFF)
   377      {
   378        ZM_DEBUG (zm_dprintf
   379                  ("Framing error - blk: %x/%x/%x\n", xyz.blk, xyz.cblk,
   380                   (xyz.blk ^ xyz.cblk)));

0xff ^ 0 is equal to 0xFF so it won't print an error.  Good!

With your patch, there is an issue with type promotion so the condition
is always true and it will mark everything as a "Framming error".

-	if ((xyz.blk ^ xyz.cblk) != (unsigned char) 0xFF)
+	if (~xyz.blk != xyz.cblk)

Both xyz.blk and xyz.cblk are type unsigned char.  If you take the
~ of an unsigned char it's going to be 0xffffffXX where XX are the
a variable bits.  That's never going to be equal to xyz.cblk.

You could truncate it to char like this:

+	if ((unsigned char)~xyz.blk != xyz.cblk)

But then it works exactly the same as the original condition.

regards,
dan carpenter



More information about the U-Boot mailing list