Skip to content

Difficulty with packet descriptor #157

@JetForMe

Description

@JetForMe

Hi. I'm trying to parse packets that can either be one of four 1-byte packets, or a variable-length packet. That is, a byte at the start of a packet of 0x06 (ACK), 0x15 (NAK), 0x16 (SYN), or 0x18 (CAN) constitutes a complete message. A starting byte of 0x01 (SOF) means at least four more bytes are coming.

When I send a request, I get back an ACK byte, followed by a SOF frame. If my request was bad, I just get back a NAK byte.

The full set of bytes I get from the other end looks like this:

 0: 06 01 10 01   15 5a 2d 57   61 76 65 20   34 2e 35 34
10: 00 01 93

What that dump shows is the ACK, followed by a SOF frame of 18 bytes: SOF (0x01), length (0x10), type (0x01), some string data, 0x00, 0x01, and a checksum of 0x5D. Because I never ACK the response, it's repeated, so the 0x93 above is followed by 0x01, 0x10, 0x01, 0x15.

My packet descriptor evaluator looks like this. Unfortunately, it never makes it to the the checksum validation. Instead, it seems to decide the length is 0x93, which suggests to me the packet parser is calling my function after skipping some bytes. I would have thought it would keep sending me the same buffer, with new bytes appended to the end, so I could keep reevaluating them until I got a good packet.

let pd = ORSSerialPacketDescriptor(maximumPacketLength: 256, userInfo: nil)
{ (inData) -> Bool in
    
    //  Is there any data?
    
    guard
        let data = inData,
        data.count > 0
    else
    {
        return false
    }
    
    //  Is it one of the single-byte frames?
    
    let singles: [FrameStart] = [.ack, .nak, .syn, .can]
    if data.count == 1,
        let start = FrameStart(rawValue: data[0]),
        singles.contains(start)
    {
        return true
    }
    
    //  It’s not, see if it’s a SOF frame…
    
    if data.count < 5 { return false }                              //  These frames are at least 5 bytes
    if data[0] != FrameStart.sof.rawValue { return false }          //  Not a SOF frame
    if data[2] != 0x00 && data[2] != 0x01 { return false }          //  Not a request or response
    let length = data[1]
    if data.count != length + 2                                     //  Wrong length
    {
        return false
    }
    
    //  Validate the checksum…
    
    let checksum = data[1 ..< data.count - 1].reduce(0xff, ^)
    if checksum != data.last! { return false }
    
    return false
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions