RSProtoMessage { 0x60 length u16 command u8 [ 0x2A => Cmd 0x33 => Req 0x66 => Data // we use RSProtoMessageResponse to deserialize the response // since even by checking the length you can't be 100% sure // you're deserializing a response // 0xAA if length == 11 => DblResponse 0xAA => Dbl ] crc u16 } RSProtoMessageDblResponse { 0x60 length u16 // Dbl identifier 0xAA data DblResponse crc 16 } Cmd { flag u8 [ 0x00 => Polling 0x01 => Ack 0x02 => Nack ] } Ack {} Polling {} Nack { error u16 } Req { // only allowed types are file_identifier variable_identifier ticket_identifier identifier GenericData } Data { ticket u32 [ 0xFFFFFFFF => DataInvalidTicketId 0xFFFFFFFE => DataUnconnectedTicketId ticket => DataValidTicket ] } DataInvalidTicketId { data GenericVariable } DataUnconnectedTicketId { // the first field of a data unconnected ticket response is fixed to 4 byte length element GenericVariable<4> // the second field can be any lenght data GenericVariable } DataValidTicket { ticket u32 = TicketId } DblResponse { // First block number 0x000000 size_recv u16 max_size_fin u16 } Dbl { block_n u8[3] [ 0x000000 => FirstBlockDbl 0xFFFFFF => LastBlockDbl block_n => BlockDbl ] } FirstBlockDbl { max_size u16 data GenericVariable } BlockDbl { block_n u32 = BlockNumber } LastBlockDbl { } #use MESSAGE_LENGTH GenericVariable { type u8 [ 0x01 => positive_int u32 0x02 => negative_int u32 // 4 byte + 1 byte decimal part (needs conversion) 0x03 => positive_dec u8[5] // 4 byte + 1 byte decimal part (needs conversion) 0x04 => negative_dec u8[5] 0x05 => file_identifier u16 0x06 => variable_identifier u32 0x07 => string u8[] 0x10 => buffer u8[] 0x11 => Void 0x80 => ticket_identifier u32 ] } Void {}