You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I have a small problem with this function. If there was no error while the transmission, the last parameter is still empty. To fix this problem, I have to do something like this: err = correct_reed_solomon_decode(rs->encoder, rs->encoded, rs->block_length, rs->recvmsg); if (rs->recvmsg[0] == 0) memcpy(rs->recvmsg, rs->encoded, rs->block_length);
I think this behavior is quite confusing, especially while the parameter is modified, if there was an error!
The one thing I can think of here is that it won't copy the received message when there are too many errors. Is err -1 when you're seeing an empty recvMsg? I didn't think it'd be useful to copy back a corrupted message, so it doesn't do that, but maybe it should.
Unfortunately I still don't have quite enough code here to see what's going on. Can you come up with a short example that demonstrates this behavior and then provide me with the whole thing? I've reviewed the code in the decoder and can't find a likely explanation for how it could return a positive value but not write to the received message pointer.
If the message is cut off at the end, the byte for the redundancy are missing (aka zeros). I would assume, that the decoder return -1, because it can not decode anything. But unfortunately it returns the message length.
This is a pretty fascinating bug report, but ultimately I've decided this is actually the correct behavior.
The first oddity to notice here is that a message that's all 0s has a parity section that's also all 0s (this may not be true for other primitive polynomials/FCR/root gaps, but is true for CCSDS/1/1). That means that a block with all 0s is actually a valid block, and it decodes to a message containing all 0s.
The second issue is that your message is less than 16 characters long. For a block with 32 roots, up to 16 of the 255 bytes can be corrupted entirely and the message can still be recovered. By removing the last 32 bytes of the message and replacing them with 0, it would seem that decode should indeed error out, since 32 is more than the allowable 16.
Instead, decode succeeds but gives you back a payload of all 0s. That's because the block you gave to decode is actually less than 16 bytes away from the valid, all-0s block, and with the bytes repaired, it seems to be a successful decode from Reed-Solomon's point of view.
Unfortunately, with enough bytes replaced, this can happen. I have tried to make a note of this in the comments in correct.h:
In most cases, if the block is too corrupted, this function
will return -1 and not perform decoding. It is possible but
unlikely that the payload written to msg will contain
errors when this function returns a positive value.
It seems you hit one of these unfortunate but possible cases. If you want to reduce the likelihood that this can happen, you may want to add a CRC32 checksum to your message. Reed-Solomon can reject some message failures but not as well a good checksum can.
Activity
brian-armstrong commentedon May 28, 2018
Hi @Hiffi
Can you provide a larger code sample/more context? I'm fairly certain the tests test this exact case, and it seems to suggest otherwise https://github.com/quiet/libcorrect/blob/master/tests/rs_tester.c#L99
brian-armstrong commentedon May 28, 2018
See also https://github.com/quiet/libcorrect/blob/master/src/reed-solomon/decode.c#L336
Hiffi commentedon May 28, 2018
That's why Im really confused. I couldn't locate, why this is happening. Don't know if this is just a C++ problem?!
I use this as a helper:
And then use it like that:
Overall I have to say, that it works really nice for me. Thanks for that 👍
brian-armstrong commentedon May 28, 2018
Thanks, I hope it works well for you.
The one thing I can think of here is that it won't copy the received message when there are too many errors. Is err -1 when you're seeing an empty recvMsg? I didn't think it'd be useful to copy back a corrupted message, so it doesn't do that, but maybe it should.
Hiffi commentedon May 28, 2018
Code:
Output:
Now comes the crazy part...
Code:
Output:
The only diffrence is, that getReceivedValue() delivers a char* as return. The recvfrom_inet_dgram_socket() wants a void* as a parameter.
brian-armstrong commentedon May 29, 2018
Unfortunately I still don't have quite enough code here to see what's going on. Can you come up with a short example that demonstrates this behavior and then provide me with the whole thing? I've reviewed the code in the decoder and can't find a likely explanation for how it could return a positive value but not write to the received message pointer.
Hiffi commentedon May 29, 2018
Okay, it took me some hours, but I think I found the bug.
Code:
Output:
If the message is cut off at the end, the byte for the redundancy are missing (aka zeros). I would assume, that the decoder return -1, because it can not decode anything. But unfortunately it returns the message length.
brian-armstrong commentedon May 30, 2018
This is a pretty fascinating bug report, but ultimately I've decided this is actually the correct behavior.
The first oddity to notice here is that a message that's all 0s has a parity section that's also all 0s (this may not be true for other primitive polynomials/FCR/root gaps, but is true for CCSDS/1/1). That means that a block with all 0s is actually a valid block, and it decodes to a message containing all 0s.
The second issue is that your message is less than 16 characters long. For a block with 32 roots, up to 16 of the 255 bytes can be corrupted entirely and the message can still be recovered. By removing the last 32 bytes of the message and replacing them with 0, it would seem that decode should indeed error out, since 32 is more than the allowable 16.
Instead, decode succeeds but gives you back a payload of all 0s. That's because the block you gave to decode is actually less than 16 bytes away from the valid, all-0s block, and with the bytes repaired, it seems to be a successful decode from Reed-Solomon's point of view.
Unfortunately, with enough bytes replaced, this can happen. I have tried to make a note of this in the comments in
correct.h:It seems you hit one of these unfortunate but possible cases. If you want to reduce the likelihood that this can happen, you may want to add a CRC32 checksum to your message. Reed-Solomon can reject some message failures but not as well a good checksum can.