Skip to content

Commit ea69181

Browse files
Allow ResourceLimitsQos serialization method compatibility (#5813)
* Refs #23183: Add vendor_id template methods to QosPoliciesSerializer Signed-off-by: cferreiragonz <[email protected]> * Refs #23183: Implement methods for Resource Limits Signed-off-by: cferreiragonz <[email protected]> * Refs #23183: Pass vendor_id to Resource Limits methods Signed-off-by: cferreiragonz <[email protected]> * Refs #23183: Apply suggestions Signed-off-by: cferreiragonz <[email protected]> * Refs #23183: Tests Signed-off-by: cferreiragonz <[email protected]> * Refs #23183: Apply Test suggestions Signed-off-by: cferreiragonz <[email protected]> * Refs #23183: Apply Test suggestions 2 Signed-off-by: cferreiragonz <[email protected]> --------- Signed-off-by: cferreiragonz <[email protected]>
1 parent a962cba commit ea69181

File tree

4 files changed

+252
-9
lines changed

4 files changed

+252
-9
lines changed

src/cpp/fastdds/core/policy/QosPoliciesSerializer.hpp

Lines changed: 86 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,30 @@ class QosPoliciesSerializer
4747
return valid;
4848
}
4949

50+
/**
51+
* @brief Fill a QosPolicy with the data found in a CDR message.
52+
* @param vendor_id VendorId to check if specific Fast DDS fields need to be read.
53+
* @param qos_policy QosPolicy to be filled.
54+
* @param cdr_message CDRMessage to read from.
55+
* @param parameter_length Length of the QosPolicy in the CDRMessage.
56+
* @return true if the CDR message reading was successful.
57+
*/
58+
static bool read_from_cdr_message(
59+
const fastdds::rtps::VendorId_t&,
60+
QosPolicy& qos_policy,
61+
rtps::CDRMessage_t* cdr_message,
62+
const uint16_t parameter_length)
63+
{
64+
return read_from_cdr_message(qos_policy, cdr_message, parameter_length);
65+
}
66+
67+
/**
68+
* @brief Fill a QosPolicy with the data found in a CDR message.
69+
* @param qos_policy QosPolicy to be filled.
70+
* @param cdr_message CDRMessage to read from.
71+
* @param parameter_length Length of the QosPolicy in the CDRMessage.
72+
* @return true if the CDR message reading was successful.
73+
*/
5074
static bool read_from_cdr_message(
5175
QosPolicy& qos_policy,
5276
rtps::CDRMessage_t* cdr_message,
@@ -64,7 +88,7 @@ class QosPoliciesSerializer
6488
}
6589

6690
/**
67-
* * @brief Check if the QosPolicy should be sent by checking if it is default.
91+
* @brief Check if the QosPolicy should be sent by checking if it is default.
6892
* @param qos_policy QosPolicy to check
6993
* @return true if the QosPolicy should be sent, false otherwise.
7094
*/
@@ -75,10 +99,10 @@ class QosPoliciesSerializer
7599
}
76100

77101
/**
78-
* * @brief Check if the QosPolicy should be sent. Default implementation checks if the QosPolicy is not default
102+
* @brief Check if the QosPolicy should be sent. Default implementation checks if the QosPolicy is not default
79103
* by calling the should_be_sent method.
80104
* @param qos_policy QosPolicy to check
81-
* @param is_writer Flag to indicate if the QosPolicy is for a writer. This flag is only used in overwrite methods
105+
* @param is_writer Flag to indicate if the QosPolicy is for a writer. This flag is only used in overwritten methods
82106
* of QosPolicies that have different default values for readers and writers.
83107
* @return true if the QosPolicy should be sent, false otherwise.
84108
*/
@@ -91,7 +115,7 @@ class QosPoliciesSerializer
91115
}
92116

93117
/**
94-
* * @brief Check if the QosPolicy should be sent. Default implementation checks if the QosPolicy is not default.
118+
* @brief Check if the QosPolicy should be sent. Default implementation checks if the QosPolicy is not default.
95119
* @param optional_qos_policy Optional QosPolicy to check.
96120
* @return true if the QosPolicy should be sent, false otherwise.
97121
*/
@@ -115,6 +139,13 @@ class QosPoliciesSerializer
115139
return false;
116140
}
117141

142+
/**
143+
* @brief Read the content of a CDR message and write it to a QosPolicy.
144+
* @param qos_policy QosPolicy to be filled.
145+
* @param cdr_message CDRMessage to read from.
146+
* @param parameter_length Length of the QosPolicy in the CDRMessage.
147+
* @return true if the CDR message reading was successful.
148+
*/
118149
static bool read_content_from_cdr_message(
119150
QosPolicy&,
120151
rtps::CDRMessage_t*,
@@ -124,6 +155,23 @@ class QosPoliciesSerializer
124155
return false;
125156
}
126157

158+
/**
159+
* @brief Read the content of a CDR message and write it to a QosPolicy.
160+
* @param vendor_id VendorId to check if specific Fast DDS fields need to be read.
161+
* @param qos_policy QosPolicy to be filled.
162+
* @param cdr_message CDRMessage to read from.
163+
* @param parameter_length Length of the QosPolicy in the CDRMessage.
164+
* @return true if the CDR message reading was successful.
165+
*/
166+
static bool read_content_from_cdr_message(
167+
const fastdds::rtps::VendorId_t&,
168+
QosPolicy& qos_policy,
169+
rtps::CDRMessage_t* cdr_message,
170+
const uint16_t parameter_length)
171+
{
172+
return read_content_from_cdr_message(qos_policy, cdr_message, parameter_length);
173+
}
174+
127175
};
128176

129177
template<>
@@ -392,11 +440,12 @@ inline bool QosPoliciesSerializer<ResourceLimitsQosPolicy>::add_content_to_cdr_m
392440

393441
template<>
394442
inline bool QosPoliciesSerializer<ResourceLimitsQosPolicy>::read_content_from_cdr_message(
443+
const fastdds::rtps::VendorId_t& vendor_id,
395444
ResourceLimitsQosPolicy& qos_policy,
396445
rtps::CDRMessage_t* cdr_message,
397446
const uint16_t parameter_length)
398447
{
399-
if (parameter_length < 20)
448+
if (parameter_length < 12)
400449
{
401450
return false;
402451
}
@@ -407,11 +456,41 @@ inline bool QosPoliciesSerializer<ResourceLimitsQosPolicy>::read_content_from_cd
407456
&qos_policy.max_instances);
408457
valid &= rtps::CDRMessage::readInt32(cdr_message,
409458
&qos_policy.max_samples_per_instance);
410-
valid &= rtps::CDRMessage::readInt32(cdr_message, &qos_policy.allocated_samples);
411-
valid &= rtps::CDRMessage::readInt32(cdr_message, &qos_policy.extra_samples);
459+
460+
if (vendor_id == rtps::c_VendorId_eProsima)
461+
{
462+
// The following two fields are not mandatory according the DDS specification
463+
if (parameter_length >= 20)
464+
{
465+
valid &= rtps::CDRMessage::readInt32(cdr_message, &qos_policy.allocated_samples);
466+
valid &= rtps::CDRMessage::readInt32(cdr_message, &qos_policy.extra_samples);
467+
}
468+
}
412469
return valid;
413470
}
414471

472+
template<>
473+
inline bool QosPoliciesSerializer<ResourceLimitsQosPolicy>::read_from_cdr_message(
474+
const fastdds::rtps::VendorId_t& vendor_id,
475+
ResourceLimitsQosPolicy& qos_policy,
476+
rtps::CDRMessage_t* cdr_message,
477+
const uint16_t parameter_length)
478+
{
479+
return read_content_from_cdr_message(vendor_id, qos_policy, cdr_message, parameter_length);
480+
}
481+
482+
template<>
483+
inline bool QosPoliciesSerializer<ResourceLimitsQosPolicy>::read_from_cdr_message(
484+
ResourceLimitsQosPolicy&,
485+
rtps::CDRMessage_t*,
486+
const uint16_t)
487+
{
488+
EPROSIMA_LOG_ERROR(QOS_POLICIES_SERIALIZER,
489+
"ResourceLimitsQosPolicy requires 'vendor_id' to be read from cdr message");
490+
assert(false);
491+
return false;
492+
}
493+
415494
template<>
416495
inline bool QosPoliciesSerializer<TimeBasedFilterQosPolicy>::add_content_to_cdr_message(
417496
const TimeBasedFilterQosPolicy& qos_policy,

src/cpp/rtps/builtin/data/ReaderProxyData.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1183,13 +1183,19 @@ bool ReaderProxyData::read_from_cdr_message(
11831183

11841184
case fastdds::dds::PID_RESOURCE_LIMITS:
11851185
{
1186+
VendorId_t local_vendor_id = source_vendor_id;
1187+
if (c_VendorId_Unknown == local_vendor_id)
1188+
{
1189+
local_vendor_id = ((c_VendorId_Unknown == vendor_id) ? c_VendorId_eProsima : vendor_id);
1190+
}
1191+
11861192
if (!resource_limits)
11871193
{
11881194
resource_limits.reset(true);
11891195
}
11901196

11911197
if (!dds::QosPoliciesSerializer<dds::ResourceLimitsQosPolicy>::read_from_cdr_message(
1192-
resource_limits.value(), msg, plength))
1198+
local_vendor_id, resource_limits.value(), msg, plength))
11931199
{
11941200
EPROSIMA_LOG_ERROR(RTPS_READER_PROXY_DATA,
11951201
"Received with error.");

src/cpp/rtps/builtin/data/WriterProxyData.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1184,13 +1184,19 @@ bool WriterProxyData::read_from_cdr_message(
11841184

11851185
case fastdds::dds::PID_RESOURCE_LIMITS:
11861186
{
1187+
VendorId_t local_vendor_id = source_vendor_id;
1188+
if (c_VendorId_Unknown == local_vendor_id)
1189+
{
1190+
local_vendor_id = ((c_VendorId_Unknown == vendor_id) ? c_VendorId_eProsima : vendor_id);
1191+
}
1192+
11871193
if (!resource_limits)
11881194
{
11891195
resource_limits.reset(true);
11901196
}
11911197

11921198
if (!dds::QosPoliciesSerializer<dds::ResourceLimitsQosPolicy>::read_from_cdr_message(
1193-
resource_limits.value(), msg, plength))
1199+
local_vendor_id, resource_limits.value(), msg, plength))
11941200
{
11951201
EPROSIMA_LOG_ERROR(RTPS_WRITER_PROXY_DATA,
11961202
"Received with error.");

test/unittest/rtps/builtin/BuiltinDataSerializationTests.cpp

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2186,6 +2186,88 @@ TEST(BuiltinDataSerializationTests, interoperability_with_intercomdds)
21862186
}
21872187
}
21882188

2189+
/*!
2190+
* This test checks that Fast DDS can properly serialize ResourceLimitsQos in DATA(w) when it has more fields than
2191+
* max_samples, max_instances and max_samples_per_instance. It also checks that those fields are not serialized
2192+
* into the allocated_samples and extra samples fields.
2193+
*/
2194+
TEST(BuiltinDataSerializationTests, interoperability_with_other_vendor_writer_resource_limits)
2195+
{
2196+
const VendorId_t other_vendor_id = { 0, 1 };
2197+
// DATA(w)
2198+
{
2199+
octet data_w_buffer[] =
2200+
{
2201+
// Encapsulation
2202+
0x00, 0x03, 0x00, 0x00,
2203+
// Resource limits
2204+
0x41, 0x00, 0x14, 0x00,
2205+
0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
2206+
0x05, 0x00, 0x00, 0x00,
2207+
// Sentinel
2208+
0x01, 0x00, 0x00, 0x00
2209+
};
2210+
2211+
CDRMessage_t msg(0);
2212+
msg.init(data_w_buffer, static_cast<uint32_t>(sizeof(data_w_buffer)));
2213+
msg.length = msg.max_size;
2214+
2215+
WriterProxyData wpd(max_unicast_locators, max_multicast_locators);
2216+
EXPECT_NO_THROW(EXPECT_TRUE(wpd.read_from_cdr_message(&msg, other_vendor_id)));
2217+
2218+
ASSERT_TRUE(wpd.resource_limits);
2219+
ASSERT_EQ(wpd.resource_limits->max_samples, 1);
2220+
ASSERT_EQ(wpd.resource_limits->max_instances, 2);
2221+
ASSERT_EQ(wpd.resource_limits->max_samples_per_instance, 3);
2222+
// Allocated samples and extra samples should have default values as they should not be read because
2223+
// they come from another vendor
2224+
dds::ResourceLimitsQosPolicy default_values {};
2225+
ASSERT_EQ(wpd.resource_limits->allocated_samples, default_values.allocated_samples);
2226+
ASSERT_EQ(wpd.resource_limits->extra_samples, default_values.extra_samples);
2227+
}
2228+
}
2229+
2230+
/*!
2231+
* This test checks that Fast DDS can properly serialize ResourceLimitsQos in DATA(r) when it has more fields than
2232+
* max_samples, max_instances and max_samples_per_instance. It also checks that those fields are not serialized
2233+
* into the allocated_samples and extra samples fields.
2234+
*/
2235+
TEST(BuiltinDataSerializationTests, interoperability_with_other_vendor_reader_resource_limits)
2236+
{
2237+
const VendorId_t other_vendor_id = { 0, 1 };
2238+
// DATA(r)
2239+
{
2240+
uint8_t data_r_buffer[] =
2241+
{
2242+
// Encapsulation
2243+
0x00, 0x03, 0x00, 0x00,
2244+
// Resource limits
2245+
0x41, 0x00, 0x14, 0x00,
2246+
0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
2247+
0x05, 0x00, 0x00, 0x00,
2248+
// Sentinel
2249+
0x01, 0x00, 0x00, 0x00
2250+
};
2251+
2252+
CDRMessage_t msg(0);
2253+
msg.init(data_r_buffer, static_cast<uint32_t>(sizeof(data_r_buffer)));
2254+
msg.length = msg.max_size;
2255+
2256+
ReaderProxyData rpd(max_unicast_locators, max_multicast_locators);
2257+
EXPECT_NO_THROW(EXPECT_TRUE(rpd.read_from_cdr_message(&msg, other_vendor_id)));
2258+
2259+
ASSERT_TRUE(rpd.resource_limits);
2260+
ASSERT_EQ(rpd.resource_limits->max_samples, 1);
2261+
ASSERT_EQ(rpd.resource_limits->max_instances, 2);
2262+
ASSERT_EQ(rpd.resource_limits->max_samples_per_instance, 3);
2263+
// Allocated samples and extra samples should have default values as they should not be read because
2264+
// they come from another vendor
2265+
dds::ResourceLimitsQosPolicy default_values {};
2266+
ASSERT_EQ(rpd.resource_limits->allocated_samples, default_values.allocated_samples);
2267+
ASSERT_EQ(rpd.resource_limits->extra_samples, default_values.extra_samples);
2268+
}
2269+
}
2270+
21892271
/*!
21902272
* This is a regression test for redmine issue #21537
21912273
*
@@ -2654,6 +2736,41 @@ TEST(BuiltinDataSerializationTests, optional_qos_extensions_reader)
26542736
ASSERT_EQ(rpd.reader_resource_limits->max_samples_per_read, 16);
26552737
}
26562738

2739+
/*!
2740+
* This test checks that a correct ReaderProxyData is obtained when sending only max_samples, max_instances
2741+
* and max_samples_per_instance in the ResourceLimits QoS policy
2742+
*/
2743+
TEST(BuiltinDataSerializationTests, optional_qos_extensions_reader_resource_limits)
2744+
{
2745+
// DATA(r)
2746+
uint8_t data_r_buffer[] =
2747+
{
2748+
// Encapsulation
2749+
0x00, 0x03, 0x00, 0x00,
2750+
// Resource limits (without allocated samples nor extra samples)
2751+
0x41, 0x00, 0x0c, 0x00,
2752+
0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
2753+
// Sentinel
2754+
0x01, 0x00, 0x00, 0x00
2755+
};
2756+
2757+
CDRMessage_t msg(0);
2758+
msg.init(data_r_buffer, static_cast<uint32_t>(sizeof(data_r_buffer)));
2759+
msg.length = msg.max_size;
2760+
2761+
ReaderProxyData rpd(max_unicast_locators, max_multicast_locators);
2762+
EXPECT_NO_THROW(EXPECT_TRUE(rpd.read_from_cdr_message(&msg, c_VendorId_eProsima)));
2763+
2764+
ASSERT_TRUE(rpd.resource_limits);
2765+
ASSERT_EQ(rpd.resource_limits->max_samples, 1);
2766+
ASSERT_EQ(rpd.resource_limits->max_instances, 2);
2767+
ASSERT_EQ(rpd.resource_limits->max_samples_per_instance, 3);
2768+
// Allocated samples and extra samples should have default values as they are not present in the data
2769+
dds::ResourceLimitsQosPolicy default_values {};
2770+
ASSERT_EQ(rpd.resource_limits->allocated_samples, default_values.allocated_samples);
2771+
ASSERT_EQ(rpd.resource_limits->extra_samples, default_values.extra_samples);
2772+
}
2773+
26572774
/*!
26582775
* This test checks that a correct WriterProxyData is obtained
26592776
* from eProsima's optional qos extensions in PublicationBuiltinTopicData
@@ -2773,6 +2890,41 @@ TEST(BuiltinDataSerializationTests, optional_qos_extensions_writer)
27732890
ASSERT_EQ(wpd.writer_resource_limits->reader_filters_allocation.increment, 6u);
27742891
}
27752892

2893+
/*!
2894+
* This test checks that a correct WriterProxyData is obtained when sending only max_samples, max_instances
2895+
* and max_samples_per_instance in the ResourceLimits QoS policy
2896+
*/
2897+
TEST(BuiltinDataSerializationTests, optional_qos_extensions_writer_resource_limits)
2898+
{
2899+
// DATA(w)
2900+
octet data_w_buffer[] =
2901+
{
2902+
// Encapsulation
2903+
0x00, 0x03, 0x00, 0x00,
2904+
// Resource limits (without allocated samples nor extra samples)
2905+
0x41, 0x00, 0x0c, 0x00,
2906+
0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
2907+
// Sentinel
2908+
0x01, 0x00, 0x00, 0x00
2909+
};
2910+
2911+
CDRMessage_t msg(0);
2912+
msg.init(data_w_buffer, static_cast<uint32_t>(sizeof(data_w_buffer)));
2913+
msg.length = msg.max_size;
2914+
2915+
WriterProxyData wpd(max_unicast_locators, max_multicast_locators);
2916+
EXPECT_NO_THROW(EXPECT_TRUE(wpd.read_from_cdr_message(&msg, c_VendorId_eProsima)));
2917+
2918+
ASSERT_TRUE(wpd.resource_limits);
2919+
ASSERT_EQ(wpd.resource_limits->max_samples, 1);
2920+
ASSERT_EQ(wpd.resource_limits->max_instances, 2);
2921+
ASSERT_EQ(wpd.resource_limits->max_samples_per_instance, 3);
2922+
// Allocated samples and extra samples should have default values as they are not present in the data
2923+
dds::ResourceLimitsQosPolicy default_values {};
2924+
ASSERT_EQ(wpd.resource_limits->allocated_samples, default_values.allocated_samples);
2925+
ASSERT_EQ(wpd.resource_limits->extra_samples, default_values.extra_samples);
2926+
}
2927+
27762928
/**
27772929
* This test checks that a correct serialization is obtained
27782930
* when non-default eProsima's optional qos extensions are used in ReaderProxyData.

0 commit comments

Comments
 (0)