1. An INPUT instruction requests data that lies beyond the end of
the message. In this case, the dispatcher should not return any
data to the UDVM. Moreover, the message bytes held by the
dispatcher should still be available for retrieval by subsequent
INPUT instructions.
2. The INPUT-BYTES instruction is used after part of a byte has been
input (e.g., by the INPUT-BITS instruction). In this case, the
remaining partial byte must be discarded, even if the INPUT-BYTES
instruction requests data that lies beyond the end of the
message.
at (64)
:byte_copy_left pad (2)
:byte_copy_right pad (2)
:input_bit_order pad (2)
:result pad (1)
:result_lsb pad (6)
:right
at (128)
LOAD (byte_copy_left, result)
LOAD (byte_copy_right, right)
:start
; Input bits to ensure that the remaining message is not byte aligned
INPUT-BITS (9, result, decompression_failure1) ; Input 0x1FF (9 bits)
; Attempt to read 7 bytes
INPUT-BYTES (7, result, next_bytes) ; This should fail, throw away
; 7 bits with value Ox7a and
; jump to next_bytes
:decompression_failure1
DECOMPRESSION-FAILURE ; This instruction is never
; executed but is used to
; separate success and failure
; to input bytes.
:next_bytes
; Read 7 bits - this removes the byte alignment of the message
; If the bits have not been thrown away where they should be, then
; the message will be 1 byte longer than necessary and the output
; will be incorrect.
INPUT-BITS (7, result, decompression_failure1) ; Input 0x00 (7 bits)
; Read 2 bytes
INPUT-BYTES (2, result, decompression_failure1)
; Throw away 1 bit value 0
; Input 0x6869
OUTPUT (result, 2) ; Output 0x6869
; Attempt to read more bits than
INPUT-BITS (16, result, bits) ; there are to ensure they
; remain available
:decompression_failure2
DECOMPRESSION-FAILURE ; This instruction is never
; executed but is used to
; separate success and failure
; to input bits.
:bits
; Read 8 bits
INPUT-BITS (8, result, decompression_failure2) ; Input 0x21 or fail
OUTPUT (result_lsb, 1) ; Output 0x21
:end_message
END-MESSAGE (0, 0, 0, 0, 0, 0, 0)
If the compressed message is 0xfffa 0068 6921, then the code
terminates successfully with the output 0x6869 21, and a total of 23
UDVM cycles are used. However, if the compressed message is 0xfffa
0068 69, then decompression failure occurs (at the final INPUT-BITS).
4. Torture Tests for State Handler
The following sections give code to test the various functions of the
SigComp state handler.
4.1. SigComp Feedback Mechanism
This section gives assembly code to test the SigComp feedback
mechanism. The code is designed to test that the following boundary
cases have been correctly implemented:
1. Both the short and the long versions of the SigComp feedback item
are used.
2. The chain of returned SigComp parameters is terminated by a non-
zero value.
at (64)
:type pad (1)
:type_lsb pad (1)
:requested_feedback_location pad (1)
:requested_feedback_length pad (1)
:requested_feedback_bytes pad (127)
:returned_parameters_location pad (2)
:length_of_partial_state_id_a pad (1)
:partial_state_identifier_a pad (6)
:length_of_partial_state_id_b pad (1)
:partial_state_identifier_b pad (12)
:length_of_partial_state_id_c pad (1)
:partial_state_identifier_c pad (20)
:terminate_returned_parameters pad (1)
align (128)
set (q_bit, 1)
set (s_bit, 0)
set (i_bit, 0)
set (flags, (((4 * q_bit) + (2 * s_bit)) + i_bit))
INPUT-BYTES (1, type_lsb, decompression_failure)
COMPARE ($type, 1, short_feedback_item, long_feedback_item,
decompression_failure)
:short_feedback_item
set (requested_feedback_data, 127)
set (short_feedback_value, ((flags * 256) + requested_feedback_data))
LOAD (requested_feedback_location, short_feedback_value)
JUMP (return_sigcomp_parameters)
:long_feedback_item
set (requested_feedback_field, 255)
set (long_feedback_value, ((flags * 256) + requested_feedback_field))
LOAD (requested_feedback_location, long_feedback_value)
MEMSET (requested_feedback_bytes, 127, 1, 1)
:return_sigcomp_parameters
set (cpb, 0)
set (dms, 1)
set (sms, 0)
set (sigcomp_version, 1)
set (parameters_msb, (((64 * cpb) + (8 * dms)) + sms))
set (sigcomp_parameters, ((256 * parameters_msb) + sigcomp_version))
LOAD (returned_parameters_location, sigcomp_parameters)
LOAD (length_of_partial_state_id_a, 1536) ; length 6 first byte 0
LOAD (length_of_partial_state_id_b, 3072) ; length 12 first byte 0
LOAD (length_of_partial_state_id_c, 5120) ; length 20 first byte 0
LOAD (terminate_returned_parameters, 5376) ; length 21
; used to terminate the
; returned parameters
MEMSET (partial_state_identifier_a, 6, 0, 1)
MEMSET (partial_state_identifier_b, 12, 0, 1)
MEMSET (partial_state_identifier_c, 20, 0, 1)
END-MESSAGE (requested_feedback_location,
returned_parameters_location, 0, 0, 0, 0, 0)
:decompression_failure
DECOMPRESSION-FAILURE
When the above code is executed, it supplies a requested feedback
item to the state handler. If the compressed message is 0x00, then
the short (1-byte) version of the feedback is used. Executing the
bytecode in this case costs a total of 52 UDVM cycles. Assuming that
the feedback request is successful, the feedback item should be
returned in the first SigComp message to be sent in the reverse
direction. The SigComp message returning the feedback should begin
as follows:
+---+---+---+---+---+---+---+---+
| 1 1 1 1 1 1 | X | first header byte
+---+---+---+---+---+---+---+---+
| 0 | 127 | returned feedback field
+---+---+---+---+---+---+---+---+
So the first 2 bytes of the returning SigComp message should be
0xfn7f where n = c, d, e, or f (the choice of n is determined by the
compressor generating the returning SigComp message, which is not
under the control of the above code).
If the compressed message is 0x01, then the long version of the
feedback item is used. Executing the bytecode in this case costs a
total of 179 UDVM cycles and the SigComp message returning the
feedback should begin as follows:
+---+---+---+---+---+---+---+---+
| 1 1 1 1 1 1 | X | first header byte
+---+---+---+---+---+---+---+---+
| 1 | 127 | returned feedback length
+---+---+---+---+---+---+---+---+
| 1 | ^
+---+---+---+---+---+---+---+---+ |
| 2 | |
+---+---+---+---+---+---+---+---+
| 3 | returned feedback field
+---+---+---+---+---+---+---+---+
So the first 129 bytes of the SigComp message should be 0xfnff 0102
0304 ... 7e7f where n = c, d, e, or f as above.
As well as testing the requested and returned feedback items, the
above code also announces values for each of the SigComp parameters.
The supplied version of the code announces only the minimum possible
values for the cycles_per_bit, decompression_memory_size,
state_memory_size, and SigComp_version (although this can easily be
adjusted to test different values for these parameters).
The code should also announce the availability of state items with
the following partial state identifiers:
0x0001 0203 0405
0x0001 0203 0405 0607 0809 0a0b
0x0001 0203 0405 0607 0809 0a0b 0c0d 0e0f 1011 1213
Note that different implementations may make use of the announcement
information in different ways. It is a valid implementation choice
to simply ignore all of the announcement data and use only the
minimum resources that are guaranteed to be available to all
endpoints. However, the above code is useful for checking that an
endpoint interprets the announcement data correctly (in particular
ensuring that it does not mistakenly use resources that have not in
fact been announced).
4.2. State Memory Management
The following section gives assembly code to test the memory
management features of the state handler. The code checks that the
correct states are retained by the state handler when insufficient
memory is available to store all of the requested states.
The code is designed to test that the following boundary cases have
been correctly implemented:
1. A state item is created that exceeds the total state_memory_size
for the compartment.
2. States are created with a non-zero state_retention_priority.
3. A new state item is created that has a lower
state_retention_priority than existing state items in the
compartment.
For the duration of this test, it is assumed that all states will be
saved in a single compartment with a state_memory_size of 2048 bytes.
at (64)
:byte_copy_left pad (2)
:byte_copy_right pad (2)
:order pad (2)
:type pad (1)
:type_lsb pad (1)
:state_length pad (2)
:state_retention_priority pad (2)
at(127)
:decompression_failure
at (128)
MULTILOAD (byte_copy_left, 2, state_start, order_data)
INPUT-BYTES (1, type_lsb, decompression_failure)
COMPARE ($type, 5, general_test, large_state, verify_state)
:general_test
COMPARE ($type, 3, start, state_present, state_not_present)
:start
MULTIPLY ($type, 6)
ADD ($type, order_data)
LOAD (order, $type)
ADD ($type, 6)
; Finish with the value (order_data + 6*n) in order where
; n is the input value 0x00, 0x01, or 0x02
; type = order + 6
; These values are used to index into the ’order_data’
; that is used to work out state retention priorities and lengths
:loop
COPY ($order, 2, state_retention_priority)
COMPARE ($order, $type, continue, end, decompression_failure)
:continue
; Set up a state creation each time through the loop
LOAD (state_length, $state_retention_priority)
MULTIPLY ($state_length, 256)
STATE-CREATE ($state_length, state_start, 0, 6,
$state_retention_priority)
ADD ($order, 2)
JUMP (loop)
:state_present
; Access the states that should be present
STATE-ACCESS (state_identifier_a, 6, 0, 0, 0, 0)
STATE-ACCESS (state_identifier_b, 6, 0, 0, 0, 0)
STATE-ACCESS (state_identifier_c, 6, 0, 0, 0, 0)
STATE-ACCESS (state_identifier_e, 6, 0, 0, 0, 0)
JUMP (end)
:state_not_present
; Check that the state that shouldn’t be present is not present.
STATE-ACCESS (state_identifier_d, 6, 0, 0, 0, 0)
JUMP (end)
:large_state
STATE-CREATE (2048, state_start, 0, 6, 0)
JUMP (end)
:verify_state
STATE-ACCESS (large_state_identifier, 6, 0, 0, 0, 0)
JUMP (end)
:end
END-MESSAGE (0, 0, 0, 0, 0, 0, 0)
at (512)
:state_start
byte (116, 101, 115, 116)
:order_data
; This data is used to generate the retention priority
; and state length of each state creation.
word (0, 1, 2, 3, 4, 3, 2, 1, 0)
:state_identifier_a
byte (142, 234, 75, 67, 167, 135)
:state_identifier_b
byte (249, 1, 14, 239, 86, 123)
:state_identifier_c
byte (35, 154, 52, 107, 21, 166)
:state_identifier_d
byte (180, 15, 192, 228, 77, 44)
:state_identifier_e
byte (212, 162, 33, 71, 230, 10)
:large_state_identifier
byte (239, 242, 188, 15, 182, 175)
The above code must be executed a total of 7 times in order to
complete the test. Each time the code is executed, a 1-byte
compressed message should be provided as below. The effects of the
messages are given below. States are described in the form (name, x,
y) where name corresponds to the name of the identifier in the
mnemonic code, x is the length of the state, and y is the retention
priority of the state.
Message: Effect: #cycles:
0x00 create states: 811
(a,0,0),
(b,256,1),
(c,512,2)
0x01 create states: 2603
(d,768,3),
(e,1024,4) - deleting a, b, c
0x02 create states: 811
(c,512,2), - deleting d
(b,256,1),
(a,0,0)
0x03 access states a,b,c,e 1805
0x04 access state d - not present so decompression failure
0x05 create states: 2057
(large, 2048,0) - deleting a, b, c, e
0x06 access large state 1993
Note that as new states are created, some of the existing states will
be pushed out of the compartment due to lack of memory.
4.3. Multiple Compartments
This section gives assembly code to test the interaction between
multiple SigComp compartments. The code is designed to test that the
following boundary cases have been correctly implemented:
1. The same state item is saved in more than one compartment.
2. A state item stored in multiple compartments has the same state
identifier but a different state_retention_priority in each case.
3. A state item is deleted from one compartment but still belongs to
a different compartment.
4. A state item belonging to multiple compartments is deleted from
every compartment to which it belongs.
The test requires a total of three compartments to be available,
which will be referred to as Compartment 0, Compartment 1, and
Compartment 2. Each of the three compartments should have a
state_memory_size of 2048 bytes.
The assembly code for the test is given below:
at (64)
:byte_copy_left pad (2)
:byte_copy_right pad (2)
:type pad (1)
:type_lsb pad (1)
at (127)
:decompression_failure
at (128)
MULTILOAD (byte_copy_left, 2, state_start, state_end)
INPUT-BYTES (1, type_lsb, decompression_failure)
COMPARE ($type, 3, create_state, overwrite_state, temp)
:temp
COMPARE ($type, 5, overwrite_state, access_state, error_conditions)
:create_state
; starting byte identified by $type according to input:
; Input 0x00 0x01 0x02
; $type 512 513 514
ADD ($type, state_start)
STATE-CREATE (448, $type, 0, 6, 0)
; create state again, beginning in different place in buffer
; starting byte identified by $type according to input:
; Input 0x00 0x01 0x02
; $type 515 516 517
ADD ($type, 3)
STATE-CREATE (448, $type, 0, 6, 0)
; create a third time beginning in different place again
; starting byte identified by $type according to input:
; Input 0x00 0x01 0x02
; $type 516 517 515
SUBTRACT ($type, temp_one)
REMAINDER ($type, 3)
ADD ($type, temp_two)
STATE-CREATE (448, $type, 0, 6, 0)
:common_state
STATE-CREATE (448, temp_three, 0, 6, $type)
JUMP (end)
:overwrite_state
STATE-CREATE (1984, 32, 0, 6, 0)
JUMP (end)
:access_state
STATE-ACCESS (state_identifier_c, 6, 0, 0, 0, 0)
STATE-ACCESS (state_identifier_d, 6, 0, 0, 0, 0)
STATE-ACCESS (state_identifier_f, 6, 0, 0, 0, 0)
STATE-ACCESS (state_identifier_g, 6, 0, 0, 0, 0)
:end
END-MESSAGE (0, 0, 0, 0, 0, 0, 0)
:error_conditions
COMPARE ($type, 7, access_a, access_b, access_e)
:access_a
STATE-ACCESS (state_identifier_a, 6, 0, 0, 0, 0)
JUMP (end)
:access_b
STATE-ACCESS (state_identifier_b, 6, 0, 0, 0, 0)
JUMP (end)
:access_e
STATE-ACCESS (state_identifier_e, 6, 0, 0, 0, 0)
JUMP (end)
at (512)
:state_start
byte (0, 1, 2, 3, 4, 5, 6)
:state_end
set (temp_one, (state_start + 2)) ; = 514
set (temp_two, (state_start + 3)) ; = 515
set (temp_three, (state_end - 1)) ; = 518
:state_identifier_a ; start state at 512
byte (172, 166, 11, 142, 178, 131)
:state_identifier_b ; start state at 513
byte (157, 191, 175, 198, 61, 210)
:state_identifier_c ; start state at 514
byte (52, 197, 217, 29, 83, 97)
:state_identifier_d ; start state at 515
byte (189, 214, 186, 42, 198, 90)
:state_identifier_e ; start state at 516
byte (71, 194, 24, 20, 238, 7)
:state_identifier_f ; start state at 517
byte (194, 117, 148, 29, 215, 161)
:state_identifier_g ; start state at 518
byte (72, 135, 156, 141, 233, 14)
The above code must be executed a total of 9 times in order to
complete the test. Each time the code is executed, a 1-byte
compressed message N should be provided, taking the values 0x00 to
0x08 in ascending order (so the compressed message should be 0x00 the
first time the code is run, 0x01 the second, and so on).
If the code makes a state creation request, then the state must be
saved in Compartment (N modulo 3).
When the compressed message is 0x00, 0x01, or 0x02, the code makes
four state creation requests in compartments 0, 1, and 2,
respectively. This creates a total of seven distinct state items
referred to as State a through State g. The states should be
distributed among the three compartments as illustrated in Figure 1
(note that some states belong to more than one compartment).
When the compressed message is 0x03 or 0x04, the code overwrites all
of the states in Compartments 0 and 1, respectively. This means that
States a, b, and e will be unavailable because they are no longer
present in any of the three compartments.
When the compressed message is 0x05, the code checks that the States
c, d, f, and g are still available. Decompression should terminate
successfully in this case.
When the compressed message is 0x06, 0x07, or 0x08, the code attempts
to access States a, b, and e, respectively. Decompression failure
should occur in this case because the relevant states are no longer
available.
The cost in UDVM cycles for each compressed message is given below
(except for messages 0x06, 0x07, and 0x08 where decompression failure
should to occur):
Compressed message: 0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08
Cost in UDVM cycles: 1809 1809 1809 1993 1994 1804 N/A N/A N/A
+-----------------------------+
| Compartment 0 |
| |
| |
| State a |
| |
| +-------------------+---------+
| | | |
| | | |
| | State d | |
| | | |