You are here: Overview > Structure of a Decoder > Finished Fiticitious Protocol Decoder

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

 

DECODE

 

/*

** Table of FP command and response codes.

*/

TABLE tableCommands

{ 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}

ENDTABLE

 

/*

** 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)

 

END_MAIN_PATH

 

/*

**

** 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.

**

*/

 

GROUP cmdReadSensor

{

FIELD sensor_number ;

}

 

GROUP cmdSetActuator

{

/*

** 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

{

RESERVED (Fixed 5 Bits)

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"

}