Branching Information in Tables

Our original command table for FP looked like this:

TABLE tableCommands

{ 0 "Request Status" "Request Status"}

{ 1 "Set Actuator" "Set Actuator"}

{ 2 "Read Sensor" "Read Sensor"}

{ Default "???" "(unknown)"}

ENDTABLE

In order to use a BRANCH, we need to add some additional information to the table. Remember that the first item in each table entry is the field value to look up, and the second and third entries are the strings for display in the Summary and Decodes panes. Now we need to add the information for the BRANCH to extract. The resulting table looks like (changes are in bold):

TABLE tableCommands

{ 0 "Request Status" "Request Status"}

{ 1 "Set Actuator" "Set Actuator" 0 cmdSetActuator}

{ 2 "Read Sensor" "Read Sensor" 0 cmdReadSensor}

{ Default "???" "(unknown)" 0 Unknown}

ENDTABLE

The fourth item in each table entry contains a number which is called the extra table data. The extra table data can be used to hold any number that would be useful in the decoding process. In the FP decoder we do not make use of the extra data field but must include a value for it, as a place-holder, when we have another item following. The last item identifies a DecoderScript statement, either a FIELD or a GROUP, that performs decoding specific to the command. With our new table, the BRANCH (FromTable tableCommands command_code) instructs the protocol analyzer to look up the value of command_code in tableCommands and jump to the GROUP or FIELD named at the end of the table entry for that value.

Our FP decoder now looks like this:

"Fictitious Protocol" 0x7f000000

DECODE

TABLE tableCommands

{ 0 "Request Status" "Request Status"}

{ 1 "Set Actuator" "Set Actuator" 0 cmdSetActuator}

{ 2 "Read Sensor" "Read Sensor" 0 cmdReadSensor}

{ Default "???" "(unknown)" 0 Unknown}

ENDTABLE

FIELD command_code (Fixed 1 Byte) (Table tableCommands) IN_SUMMARY "Command/Response" 150 "Command"

BRANCH (FromTable tableCommands command_code)

FIELD checksum (Fixed 1 Byte) (Hex) IN_SUMMARY "C'sum" 40 "Checksum" VERIFY (FPChecksum)

END_MAIN_PATH

GROUP cmdSetActuator

{

FIELD actuator_number (Fixed 1 Byte) (Decimal) "Actuator Number" VERIFY (FieldIsBetween 1 32)

FIELD actuator_value (Fixed 2 Bytes) (Decimal) "Value to set"

}

GROUP cmdReadSensor

{

FIELD sensor_number (Fixed 1 Byte) (Decimal) "Sensor Number" VERIFY (FieldIsBetween 1 32)

}

The statements within the cmdSetActuator and cmdReadSensor GROUPs are grouped simply for the purpose of making them a suitable object of a BRANCH. The point is that the object of a BRANCH is always a statement - it cannot be an unconnected sequence of statements because there is nothing akin to a "return" statement such as one finds in most programming languages. It can be a single statement, that is a FIELD, or a compound statement, namely a GROUP. Once that statement has been processed, control is automatically returned to the statement following the BRANCH.

You may have noticed that Request Status doesn't have any branching information. This command consists solely of the Command Code and the checksum, so there is nothing to branch to. In this situation the BRANCH statement is ignored and decoding continues on to the next statement.