Finished Fictitious Protocol Decoder
Here's the final version of the Fictitious Protocol Decoder in its full glory:
/* Decoder for FP (Fictitious Protocol) by Manuel Ryder */"FP" 0x7f000000
/*
** Table of FP command and response codes.
*/
{ 0x00 "Request Status" "Request Status"}
{ 0x01 "Set Actuator" "Set Actuator" 0 cmdSetActuator}
{ 0x02 "Read Sensor" "Read Sensor" 0 cmdReadSensor}
{ 0x80 "Status" "Status" 0 rspStatus}
{ 0x81 "Actuator Set" "Actuator Set" 0 rspActuatorSet}
{ 0x82 "Sensor Value" "Sensor Value" 0 rspSensorValue}
{ Default "???" "(unknown)" 0 Unknown}
/*
** Find the value of the first field, but don't display it and
** don't move the pointer.
*/
FIELD command_or_response (Fixed 1) (Hex) SUPPRESS_DETAIL NO_MOVE
/*
** If the value of the command_or_response field is between 0x00
** and 0x022, we know it's a command. If it's between 0x80 and
** 0x82, we know it's a response. The response has an extra
** field that commands don't have, so we create a group and put
** the IF test on the group as a whole. If the test fails, the
** entire group will be skipped.
**
** Unknown commands will fail both tests and branch to the
** Unknown group, which decodes the first byte as an Unknown
** Command or Response.
**
** The IN_SUMMARY puts the result of either field in the same
** Summary pane column.
*/
FIELD command (Fixed 1) IF (FieldIsBetween 0x00 0x02 command_or_response) (TABLE tableCommands) IN_SUMMARY "Command/Response" 120 "Command"
GROUP response_group IF (FieldIsBetween 0x80 0x82 command_or_response)
{
FIELD response (Fixed 1) (TABLE tableCommands) IN_SUMMARY "Command/Response" 120 "Response"
FIELD response_count (Fixed 1) (Decimal) "Data byte count" VERIFY (FieldIsBetween 1 3)
}
BRANCH (FromTable tableCommands command_or_response)
/*
** Display and verify what should be the checksum.
*/
FIELD checksum (Fixed 1) (Hex) IN_SUMMARY "C'sum" 40 "Checksum" VERIFY (FPChecksum)
/*
**
** Common fields. In this section we have FIELD statements for
** fields that are used in multiple places in the decoder.
**
** Actuator number. This is a one-byte field. We display it in
** decimal and verify that it is valid (i.e. in the range 0 to
** 32, where 0 means "all").
*/
FIELD actuator_number (Fixed 1) (Decimal) "Actuator Number"
VERIFY (FieldIsBetween 0 32)
/*
** Actuator value. This is a two-byte field.
*/
FIELD actuator_value (Fixed 2) (Decimal) "Value to set"
/*
** Sensor number. This is a one-byte field. We display it in
** decimal and verify that it is in the range 1 to 32).
*/
FIELD sensor_number (Fixed 1) (Decimal) "Sensor Number"
VERIFY (FieldIsBetween 1 32)
/*
** Sensor value. This is a two-byte field.
*/
FIELD sensor_value (Fixed 2) (Decimal) "Sensor Value"
/*
**
** Decode commands.
**
*/
{
FIELD sensor_number ;
}
{
/*
** We want to display something different if the actuator
** number is 0 (meaning "All Actuators"), so we need to
** process the field first, and then use that field as a
** test for the IF statement.
*/
FIELD actuator_id (Fixed 1) (Decimal) SUPPRESS_DETAIL NO_MOVE
FIELD all_actuators (Fixed 1) IF (FieldIs EqualTo 0 actuator_id) (Constant "All Actuators") "Actuator Number"
FIELD one_actuator (Fixed 1) IF (FieldIs NotEqualTo 0 actuator_id) (Decimal) "Actuator Number" VERIFY (FieldIsBetween 1 32)
FIELD actuator_value ;
}
/*
**
** Decode responses.
**
*/
GROUP FIELD rspStatus START_BIT (Move 5 Bits) (Fixed 3 Bits) (Hex) "Status" NO_MOVE
{
FIELD alarm_bit (Fixed 1 Bit) (Binary) "Alarm"
FIELD power_bit (Fixed 1 Bit) (Binary) "Power"
FIELD test_bit (Fixed 1 Bit) (Binary) "Test mode"
}
GROUP rspActuatorSet
{
FIELD actuator_number ;
}
GROUP rspSensorValue
{
FIELD sensor_number ;
FIELD sensor_value ;
}
GROUP Unknown
{
FIELD unknown_cmd_or_resp (Fixed 1) (Hex) IN_SUMMARY "Command/Response" 120 "Unknown Command/Response Code"
FIELD unknown_data (ToEndOfLayer 1) (StringOfHex) "Data"
}