-
-
Notifications
You must be signed in to change notification settings - Fork 187
Description
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
}