Blind implementation of RTPS Writer

This commit is contained in:
Greek 2021-02-07 17:59:33 +01:00
parent f0cc1e5432
commit e8670aaf59
5 changed files with 3653 additions and 40 deletions

View File

@ -253,9 +253,9 @@ ENDPOINT MATCH FRAME
04| ENTITYID |
+-------------------------------------------------------------+
05| IPv4_ADDRESS |
+-----------------------------+-----------------------------+-+
06| UDP_PORT | UNUSED |Q|
+-----------------------------+-----------------------------+-+
+-----------------------------+---------------------------+-+-+
06| UDP_PORT | UNUSED |D|Q|
+-----------------------------+---------------------------+-+-+
ENDPOINT UNMATCH FRAME
======================
@ -347,26 +347,28 @@ WRITER
+ +
03| |
+-------------------------------------------------------------+
04| IPv4_ADDRESS | [Reliable Only]
+-----------------------------+---------------------------+-+-+
05| UDP_PORT | UNUSED |P|Q| [Reliable Only]
+-----------------------------+---------------------------+-+-+
04| IPv4_ADDRESS |
+-----------------------------+-------------------------+-+-+-+
05| UDP_PORT | UNUSED |B|H|Q|
+-----------------------------+-------------------------+-+-+-+
06| |
+ LEASE_DEADLINE +
+ LEASE_DEADLINE + [Reliable Only]
07| |
+-------------------------------------------------------------+
08| |
+ GAP_LOW_SEQ_NR + [Reliable Only]
08| |
+ RES_TIME + [Reliable Only]
09| |
+-------------------------------------------------------------+
10| |
+ GAP_HIGH_SEQ_NR + [Reliable Only]
+ ACK_SEQ_NR_BASE + [Reliable Only]
11| |
+-------------------------------------------------------------+
12| |
+ RES_TIME + [Reliable Only]
12| |
+ REQ_SEQ_NR_BASE + [Reliable Only]
13| |
+-------------------------------------------------------------+
14| REQ_BITMAP | [Reliable Only]
+-------------------------------------------------------------+
HISTORY CACHE
@ -377,29 +379,56 @@ READER
31............24..............16..............8...............0
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+-------------------------------------------------------------+
00| STATUS_INFO | {A/B}
00| STATUS_INFO |
+-------------------------------------------------------------+
01| |
+ TIMESTAMP + {A}
+ TIMESTAMP +
02| |
+-------------------------------------------------------------+
03| |
+ LIFESPAN_DEADLINE + {A}
+ LIFESPAN_DEADLINE +
04| |
+-------------------------------------------------------------+
05| PAYLOAD_ADDRESS | {A}
05| PAYLOAD_ADDRESS |
+-------------------------------------------------------------+
06| INSTANCE_ADDRESS | {A}
06| INSTANCE_ADDRESS |
+-------------------------------------------------------------+
07| DISPOSED_GENERATION_COUNT | {A}
07| DISPOSED_GENERATION_COUNT |
+-------------------------------------------------------------+
08| NO_WRITERS_GENERATION_COUNT | {A}
08| NO_WRITERS_GENERATION_COUNT |
+-------------------------------------------------------------+
09| PREV_ADDRESS | {A}
09| PREV_ADDRESS |
+-------------------------------------------------------------+
10| NEXT_ADDRESS | {A/B}
10| NEXT_ADDRESS |
+-------------------------------------------------------------+
WRITER
------
31............24..............16..............8...............0
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+-------------------------------------------------------------+
00| STATUS_INFO |
+-------------------------------------------------------------+
01| |
+ TIMESTAMP +
02| |
+-------------------------------------------------------------+
03| |
+ LIFESPAN_DEADLINE +
04| |
+-------------------------------------------------------------+
05| PAYLOAD_ADDRESS |
+-------------------------------------------------------------+
06| INSTANCE_ADDRESS |
+-------------------------------------------------------------+
07| |
~ ACK_BITMAP ~
**| |
+-------------------------------------------------------------+
**| PREV_ADDRESS |
+-------------------------------------------------------------+
**| NEXT_ADDRESS |
+-------------------------------------------------------------+
STATUS INFO
-----------
@ -461,35 +490,60 @@ HISTORY CACHE INPUT
INSTANCE MEMORY
===============
READER
------
31............24..............16..............8...............0
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+-------------------------------------------------------------+
00| NEXT_ADDRESS | {A/B}
00| NEXT_ADDRESS |
+-------------------------------------------------------------+
01| |
+ +
02| |
+ KEY_HASH + {A}
+ KEY_HASH +
03| |
+ +
04| |
+-------------------------------------------------------------+
05| STATUS_INFO | {A/B}
05| STATUS_INFO |
+-------------------------------------------------------------+
06| SAMPLE_COUNT | {A/B}
06| SAMPLE_COUNT |
+-------------------------------------------------------------+
07| DISPOSED_GENERATION_COUNT | {A}
07| DISPOSED_GENERATION_COUNT |
+-------------------------------------------------------------+
08| NO_WRITERS_GENERATION_COUNT | {A}
08| NO_WRITERS_GENERATION_COUNT |
+-------------------------------------------------------------+
09| |
+ IGNORE_DEADLINE + {A} [only TIME_BASED_FILTER]
+ IGNORE_DEADLINE + [only TIME_BASED_FILTER]
10| |
+-------------------------------------------------------------+
11| |
~ WRITER_BITMAP ~ {A}
~ WRITER_BITMAP ~
**| |
+-------------------------------------------------------------+
WRITER
------
31............24..............16..............8...............0
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+-------------------------------------------------------------+
00| NEXT_ADDRESS |
+-------------------------------------------------------------+
01| |
+ +
02| |
+ KEY_HASH +
03| |
+ +
04| |
+-------------------------------------------------------------+
05| STATUS_INFO |
+-------------------------------------------------------------+
06| SAMPLE_COUNT |
+-------------------------------------------------------------+
07| ACK_COUNT |
+-------------------------------------------------------------+
STATUS INFO

View File

@ -68,6 +68,10 @@
* Currently a RTPS Writer with DURABILITY TARNSIENT_LOCAL does send historical data to all matched readers, not depending if they are VOLATILE or TRANSIENT_LOCAL.
* Assert Heartbeat period > Heartbeat Suppression Period
* Can I request (NACK) SNs that were NOT announced by the writer (> last_sn in Heartbeat)?
* Does AUTOMATIC Liveliness QoS also update the lease on write/assert_liveliness operations?
* The Lease Duration is also updated if the Cache Change is not accepted by the DDS/HC. This in effect "skews" the "correctness" of the Writer Liveliness Protocol until the reader has no pending request from the Writer.
* If an Instance is DISPOSED, but later has no active writers, the Instance STAYS in the NOT_ALIVE_DISPOSED state.
* Is a Writer that is Disposing a Instance also Unregistering that instance? (Currently only Unregistering removes the remote Writer)
* Fast-RTPS doen not follow DDSI-RTPS Specification
- Open Github Issue
@ -85,6 +89,8 @@
Isn't Reader -> Writer also valid? Does it have a specific direction?
- 9.4.5.3 Data Submessage
writerSN is incorrectly shown as only 32 bits in width
- 8.2.3 The RTPS CacheChange
Add IDL Specification for CacheChange_t
- 8.3.4 The RTPS Message Receiver, Table 8.16 - Initial State of the Receiver
Port of UnicastReplyLocatorList should be initialized to Source Port.
- 8.3.7.4.3 Validity
@ -93,6 +99,9 @@
'This Submessage is invalid when the following is true:
submessageLength in the Submessage header is too small'
But if InvalidateFlag is set, Length can be Zero. Since the length is unsigned, there cannot be an invalid length.
- 8.7.2.2.1 DURABILITY
'While volatile and transient-local durability do not affect the RTPS protocol'
But in case of Durability TRANSIENT_LOCAL the writer has to send historical Data.
- 8.7.3.2 Indicating to a Reader that a Sample has been filtered
Text refs 8.3.7.2.2 for DataFlag, but shoudl also ref 8.7.4 for FilteredFlag
- 9.4.5.1.2 Flags

View File

@ -49,27 +49,31 @@ package rtps_config_package is
constant OPCODE_PARTICIPANT_UNMATCH : std_logic_vector(ENDPOINT_MATCH_OPCODE_WIDTH-1 downto 0) := x"55000002";
constant OPCODE_LIVELINESS_UPDATE : std_logic_vector(ENDPOINT_MATCH_OPCODE_WIDTH-1 downto 0) := x"55000003";
type HISTORY_CACHE_OPCODE_TYPE is (NOP, ADD_CACHE_CHANGE);
type HISTORY_CACHE_OPCODE_TYPE is (NOP, ADD_CACHE_CHANGE, GET_CACHE_CHANGE, ACK_CACHE_CHANGE, NACK_CACHE_CHANGE);
type KEY_GENERATOR_OPCODE_TYPE is (NOP, WRITE_PAYLOAD, READ_KEY, READ_SIZE);
type HISTORY_CACHE_RESPOSNE_TYPE is (UNDEFINED, ACK, ACCEPTED, REJECTED);
type INSTANCE_STATE_TYPE is (ALIVE, NOT_ALIVE_DISPOSED, NOT_ALIVE_NO_WRITERS);
type VIEW_STATE_TYPE is (NEW_INSTANCE, NOT_NEW_INSTANCE);
type SAMPLE_STATE is (READ, NOT_READ);
type HISTORY_CACHE_RESPONSE_TYPE is (UNDEFINED, ACK, ACCEPTED, REJECTED, INVALID);
-- TODO: Prefix the Flags with something that differntiates between them
-- Sample Status Info Flags
constant DISPOSED_FLAG : natural := 0;
constant UNREGISTERED_FLAG : natural := 1;
constant FILTERED_FLAG : natural := 2;
constant DISPOSED_FLAG : natural := STATUS_INFO_DISPOSED_FLAG;
constant UNREGISTERED_FLAG : natural := STATUS_INFO_UNREGISTERED_FLAG;
constant FILTERED_FLAG : natural := STATUS_INFO_FILTERED_FLAG;
constant KEY_HASH_FLAG : natural := 29;
constant PAYLOAD_FLAG : natural := 30;
constant READ_FLAG : natural := 31;
-- Instance Status Info Flags
constant NOT_ALIVE_DISPOSED_FLAG : natural := 0;
constant NOT_ALIVE_NO_WRITERS_FLAG : natural := 1;
constant LIVELINESS_FLAG : natural := 2;
constant VIEW_FLAG : natural := 3;
constant MARK_FLAG : natural := 4;
-- Remote Endpoint Flags
constant EXPECTS_INLINE_QOS_FLAG : natural := 0;
constant SEND_HISTORICAL_DATA_FLAG : natural := 1;
constant BEST_EFFORT_FLAG : natural := 2;
-- Marks the Reader Endpoint in the Endpoint Array
constant ENDPOINT_READERS : std_logic_vector(0 to NUM_ENDPOINTS-1) := (0 to NUM_READERS-1 => '1', others => '0');
@ -136,7 +140,9 @@ package rtps_config_package is
function check_qos_compatibility(src_is_reader : std_logic; direction : std_logic; remote : unsigned(WORD_WIDTH-1 downto 0); local : unsigned(WORD_WIDTH-1 downto 0)) return boolean;
function check_qos_compatibility(src_is_reader : std_logic; direction : std_logic; remote : DOUBLE_WORD_ARRAY; local : DOUBLE_WORD_ARRAY) return boolean;
function check_mask(flags : std_logic_vector, mask : std_logic_vector) return boolean;
function check_mask(flags : std_logic_vector; mask : std_logic_vector) return boolean;
function gen_inline_qos (id : natural) return OUTPUT_DATA_TYPE;
end package;
@ -723,6 +729,121 @@ package body rtps_config_package is
constant WRITER_ENDPOINT_DATA : OUTPUT_DATA_TYPE := gen_writer_endpoint_data;
function gen_inline_qos (id : natural) return OUTPUT_DATA_TYPE is
variable ret : OUTPUT_DATA_TYPE := (data => (others => (others => '0')), length => 0);
variable ind : natural := 0;
variable tmp : natural := 0;
begin
assert (id >= NUM_READERS) report "Inline Qos can only be generated for Writer Endpoints" severity FAILURE;
-- TOPIC NAME
tmp := string_len(ENDPOINT_TOPIC(id));
ret.data(ret.length) := PID_TOPIC_NAME & std_logic_vector(to_unsigned((round_div(tmp,4)+1)*4, 16));
ret.length := ret.length + 1;
ret.data(ret.length) := std_logic_vector(to_unsigned(tmp, 32));
for j in 0 to round_div(tmp,4)-1 loop
ret.length := ret.length + 1;
ret.data(ret.length) := ENDPOINT_TOPIC(id)(j);
end loop;
-- DURABILITY
if (ENDPOINT_DURABILITY_QOS(id) /= DEFAULT_DURABILITY_QOS) then
ret.length := ret.length + 1;
ret.data(ret.length) := PID_DURABILITY & std_logic_vector(to_unsigned(4, 16));
ret.length := ret.length + 1;
ret.data(ret.length) := ENDPOINT_DURABILITY_QOS(id);
end if;
-- PRESENTATION
if (ENDPOINT_PRESENTATION_QOS(id) /= DEFAULT_PRESENTATION_QOS or ENDPOINT_COHERENT_ACCESS(id) /= DEFAULT_COHERENT_ACCESS or ENDPOINT_ORDERED_ACCESS(id) /= DEFAULT_ORDERED_ACCESS) then
ret.length := ret.length + 1;
ret.data(ret.length) := PID_PRESENTATION & std_logic_vector(to_unsigned(8, 16));
ret.length := ret.length + 1;
ret.data(ret.length) := ENDPOINT_PRESENTATION_QOS(id);
ret.length := ret.length + 1;
ret.data(ret.length) := (24 => boolean_to_std_logic(ENDPOINT_COHERENT_ACCESS(id)), 16 => boolean_to_std_logic(ENDPOINT_ORDERED_ACCESS(id)), others => '0');
end if;
-- DEADLINE
if (ENDPOINT_DEADLINE_QOS(id) /= DEFAULT_DEADLINE_QOS) then
ret.length := ret.length + 1;
ret.data(ret.length) := PID_DEADLINE & std_logic_vector(to_unsigned(8, 16));
ret.length := ret.length + 1;
ret.data(ret.length) := std_logic_vector(ENDPOINT_DEADLINE_QOS(id)(0));
ret.length := ret.length + 1;
ret.data(ret.length) := std_logic_vector(ENDPOINT_DEADLINE_QOS(id)(1));
end if;
-- LATENCY_BUDGET
if (ENDPOINT_LATENCY_BUDGET_QOS(id) /= DEFAULT_LATENCY_BUDGET_QOS) then
ret.length := ret.length + 1;
ret.data(ret.length) := PID_LATENCY_BUDGET & std_logic_vector(to_unsigned(8, 16));
ret.length := ret.length + 1;
ret.data(ret.length) := std_logic_vector(ENDPOINT_LATENCY_BUDGET_QOS(id)(0));
ret.length := ret.length + 1;
ret.data(ret.length) := std_logic_vector(ENDPOINT_LATENCY_BUDGET_QOS(id)(1));
end if;
-- OWNERSHIP
if (ENDPOINT_OWNERSHIP_QOS(id) /= DEFAULT_OWNERSHIP_QOS) then
ret.length := ret.length + 1;
ret.data(ret.length) := PID_OWNERSHIP & std_logic_vector(to_unsigned(4, 16));
ret.length := ret.length + 1;
ret.data(ret.length) := ENDPOINT_OWNERSHIP_QOS(id);
end if;
-- OWNERSHIP STRENGTH
if (ENDPOINT_OWNERSHIP_STRENGTH_QOS(id) /= DEFAULT_OWNERSHIP_STRENGTH_QOS) then
ret.length := ret.length + 1;
ret.data(ret.length) := PID_OWNERSHIP_STRENGTH & std_logic_vector(to_unsigned(4, 16));
ret.length := ret.length + 1;
ret.data(ret.length) := ENDPOINT_OWNERSHIP_STRENGTH_QOS(id);
end if;
-- LIVELINESS
if (ENDPOINT_LIVELINESS_QOS(id) /= DEFAULT_LIVELINESS_QOS or ENDPOINT_LEASE_DURATION(id) /= DEFAULT_LEASE_DURATION) then
ret.length := ret.length + 1;
ret.data(ret.length) := PID_LIVELINESS & std_logic_vector(to_unsigned(12, 16));
ret.length := ret.length + 1;
ret.data(ret.length) := ENDPOINT_LIVELINESS_QOS(id);
ret.length := ret.length + 1;
ret.data(ret.length) := std_logic_vector(ENDPOINT_LEASE_DURATION(id)(0));
ret.length := ret.length + 1;
ret.data(ret.length) := std_logic_vector(ENDPOINT_LEASE_DURATION(id)(1));
end if;
-- RELIABILITY
if (ENDPOINT_RELIABILITY_QOS(id) /= DEFAULT_RELIABILTY_QOS or ENDPOINT_MAX_BLOCKING_TIME(id) /= DEFAULT_MAX_BLOCKING_TIME) then
ret.length := ret.length + 1;
ret.data(ret.length) := PID_RELIABILITY & std_logic_vector(to_unsigned(12, 16));
ret.length := ret.length + 1;
ret.data(ret.length) := ENDPOINT_RELIABILITY_QOS(id);
ret.length := ret.length + 1;
ret.data(ret.length) := std_logic_vector(ENDPOINT_MAX_BLOCKING_TIME(id)(0));
ret.length := ret.length + 1;
ret.data(ret.length) := std_logic_vector(ENDPOINT_MAX_BLOCKING_TIME(id)(1));
end if;
-- TRANSPORT PRIORITY
if (ENDPOINT_TRANSPORT_PRIORITY_QOS(id) /= DEFAULT_TRANSPORT_PRIORITY_QOS) then
ret.length := ret.length + 1;
ret.data(ret.length) := PID_TRANSPORT_PRIORITY & std_logic_vector(to_unsigned(4, 16));
ret.length := ret.length + 1;
ret.data(ret.length) := ENDPOINT_TRANSPORT_PRIORITY_QOS(id);
end if;
-- LIFESPAN
if (ENDPOINT_LIFESPAN_QOS(id) /= DEFAULT_LIFESPAN_QOS) then
ret.length := ret.length + 1;
ret.data(ret.length) := PID_LIFESPAN & std_logic_vector(to_unsigned(8, 16));
ret.length := ret.length + 1;
ret.data(ret.length) := std_logic_vector(ENDPOINT_LIFESPAN_QOS(id)(0));
ret.length := ret.length + 1;
ret.data(ret.length) := std_logic_vector(ENDPOINT_LIFESPAN_QOS(id)(1));
end if;
-- DESTINATION ORDER
if (ENDPOINT_DESTINATION_ORDER_QOS(id) /= DEFAULT_DESTINATION_ORDER_QOS) then
ret.length := ret.length + 1;
ret.data(ret.length) := PID_DESTINATION_ORDER & std_logic_vector(to_unsigned(4, 16));
ret.length := ret.length + 1;
ret.data(ret.length) := ENDPOINT_DESTINATION_ORDER_QOS(id);
end if;
-- SENTINEL
ret.length := ret.length + 1;
ret.data(ret.length) := PID_SENTINEL & std_logic_vector(to_unsigned(0, 16));
return ret;
end function;
function gen_participant_data return OUTPUT_DATA_TYPE is
variable ret : OUTPUT_DATA_TYPE := (data => (others => (others => '0')), length => 0);
variable len : natural := 0;
@ -1089,7 +1210,7 @@ package body rtps_config_package is
return ret;
end function;
function check_mask(flags : std_logic_vector, mask : std_logic_vector) return boolean is
function check_mask(flags : std_logic_vector; mask : std_logic_vector) return boolean is
begin
assert (flags'length = mask'length) report "Flag and mask Signal have unequal length" severity FAILURE;
if ((flags and mask) = mask) then

View File

@ -200,6 +200,11 @@ package rtps_package is
constant LIFESPAN_QOS_POLICY_ID : std_logic_vector(QOS_POLICY_ID_WIDTH-1 downto 0) := std_logic_vector(to_unsigned(21,QOS_POLICY_ID_WIDTH));
constant DURABILITYSERVICE_QOS_POLICY_ID : std_logic_vector(QOS_POLICY_ID_WIDTH-1 downto 0) := std_logic_vector(to_unsigned(22,QOS_POLICY_ID_WIDTH));
-- *STATUS INFO*
constant STATUS_INFO_DISPOSED_FLAG : natural := 0;
constant STATUS_INFO_UNREGISTERED_FLAG : natural := 1;
constant STATUS_INFO_FILTERED_FLAG : natural := 2;
-- *SUBMESSAGE IDs*
constant SID_PAD : std_logic_vector(SUBMESSAGE_ID_WIDTH-1 downto 0) := x"01";
constant SID_ACKNACK : std_logic_vector(SUBMESSAGE_ID_WIDTH-1 downto 0) := x"06";
@ -440,6 +445,7 @@ package rtps_package is
constant PARTICIPANT_MESSAGE_DATA_KIND_MANUAL_LIVELINESS_UPDATE : std_logic_vector(PARTICIPANT_MESSAGE_KIND_WIDTH-1 downto 0) := x"00000002";
--*CUSTOM TYPES*
type CACHE_CHANGE_KIND_TYPE is (ALIVE, ALIVE_FILTERED, NOT_ALIVE_DISPOSED, NOT_ALIVE_UNREGISTERED);
type USER_BOOLEAN_ARRAY_TYPE is array (natural range <>) of boolean;
subtype USER_STRING_TYPE is string(1 to 256);
type USER_STRING_ARRAY_TYPE is array (natural range <>) of USER_STRING_TYPE;

3423
src/rtps_writer.vhd Normal file

File diff suppressed because it is too large Load Diff