lexus2k/tinyproto

Empty payload frame cannot be parsed as a Tiny::Packet

alieslam opened this issue ยท 5 comments

When I tried to parse a frame with no payload just the UID using the regular buffer (technique no.1) it seems working normally. While when I tried using Tiny's Packet class (technique no.2) it didn't seems to work, and it just ignores the whole frame. Am I missing any information?

Hint: I am using the following functions in both techniques to initialize hdlc instance

hdlc.beginToSerial(); /* using Arduino's Serial Instance to parse and send data */
hdlc.enableCrc16(); /* Enabling CRC16 to frames */
hdlc.enableUid(); / * Enabling Uid for Tiny::Packet */

Technique no. 1

char buff[100]={0};
Tiny::Proto hdlc;
int len = 0;
len = hdlc.read(buff,sizeof(buff),TINY_FLAG_NO_WAIT);
if (len > 0)
{
    /* Process the Data */
}

Technique no. 2

char buff[100]={0};
Tiny::Proto hdlc;
Tiny::Packet myPacket(buff,sizeof(buff));
int len = 0;
len = hdlc.read(myPacket, TINY_FLAG_NO_WAIT);
if (len > 0)
{
    /* Process the Data */
}

Hello,

Thank you very much for reporting the issue. I think read() method implementation is the answer to your question.

Technique no. 1
In this case, since read() method accepts only buffer and flags, Proto class doesn't have place to copy uid to. So, uid goes to payload, since second argument for tiny_read() is zero. And in this case I believe hdlc.read() returns 2.

int Proto::read(char *buf, int size, uint8_t flags)
{
    return tiny_read(&m_data, 0, (uint8_t*)buf, size, flags);
}

Technique no. 2
For the second case Tiny::Packet has special field to store uid to, so, uid does't go to payload, and in second case hdlc.read() returns 0, since uid support is enabled.

int Proto::read(Packet &pkt, uint8_t flags)
{
    int len = tiny_read(&m_data, m_uidEnabled ? &pkt.m_uid : 0, pkt.m_buf, pkt.m_size, flags);
    pkt.m_p = 0;
    pkt.m_len = len;
    return len;
}

I'm sorry for that. This is confusing behavior. Could you please check the fix in 00f2d08 commit, if it works for you. Now, in case of using Tiny::Packet the length of payload must be read from Tiny::Packet object

First of all thanks for your quick response&fix, really you did a great job in this library ๐Ÿ˜‰.

In this case, since read() method accepts only buffer and flags, Proto class doesn't have place to copy uid to. So, uid goes to payload, since second argument for tiny_read() is zero. And in this case I believe hdlc.read() returns 2.

You are right, but I didn't mention that in the case of using only buffers (Technique no.1), I was checking the so called "Uid" as the first two bytes from the payload. But for sure they don't have to do anything with enabling or disabling Uid option. So apologies for not being totally clear.

Finally the fix is working ๐Ÿ’ , adding the length if Uid as a payload length in Tiny's packet len variable is the right thing ๐Ÿ‘ , as sometimes you can generate frames just like the PING\PONG handshaking frames which doesn't have any payload but only an identifier which in ourcase just Uid.

Closing issue as it has been resolved

@lexus2k Should the fix also be supported with ProtoLight read packet function?
https://github.com/lexus2k/tinyproto/blob/master/src/TinyLightProtocol.cpp#L65

@alieslam I believe no, since ProtoLight version doesn't support UIDs. As for zero-length packets ProtoLight version tiny_light_send() and tiny_light_read() always run in blocking mode and return negaive value if they failed, in all other cases they return 0 or N depending on length data being sent or received. So, they should be OK.