1% Real-Time Publish-Subscribe Protocol (RTPS) dissection 2% 3% Copyright (C) 2021 Trend Micro Incorporated 4% Copyright (C) 2021 Alias Robotics S.L. 5% 6% This program is free software; you can redistribute it and/or modify it under 7% the terms of the GNU General Public License as published by the Free Software 8% Foundation; either version 2 of the License, or (at your option) any later 9% version. 10% 11% This program is distributed in the hope that it will be useful, but WITHOUT ANY 12% WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 13% PARTICULAR PURPOSE. See the GNU General Public License for more details. 14% 15% You should have received a copy of the GNU General Public License along with 16% this program; if not, write to the Free Software Foundation, Inc., 51 Franklin 17% Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 19% RTPS layer test campaign 20 21+ Syntax check 22= Import the RTPS layer 23from scapy.contrib.rtps import * 24pkt = b"\x52\x54\x50\x53\x02\x01\x01\x10\x57\x63\x10\x01\xd6\xab\x40\x7f" \ 25 b"\x5b\xd9\xbb\x1c\x0e\x01\x0c\x00\x88\x2a\x10\x01\x5d\x8c\x97\x40" \ 26 b"\x78\xb6\x2d\xc2\x09\x01\x08\x00\xf4\x50\x81\x60\x51\xdd\x5c\x1c" \ 27 b"\x15\x05\x10\x01\x00\x00\x10\x00\x00\x01\x00\xc7\x00\x01\x00\xc2" \ 28 b"\x00\x00\x00\x00\x01\x00\x00\x00\x00\x03\x00\x00\x15\x00\x04\x00" \ 29 b"\x02\x01\x00\x00\x16\x00\x04\x00\x01\x10\x00\x00\x02\x00\x08\x00" \ 30 b"\x0a\x00\x00\x00\x00\x00\x00\x00\x50\x00\x10\x00\x57\x63\x10\x01" \ 31 b"\xd6\xab\x40\x7f\x5b\xd9\xbb\x1c\x00\x00\x01\xc1\x58\x00\x04\x00" \ 32 b"\x3f\x0c\x00\x00\x0f\x00\x04\x00\x00\x00\x00\x00\x31\x00\x18\x00" \ 33 b"\x01\x00\x00\x00\xbd\xeb\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" \ 34 b"\x00\x00\x00\x00\xac\x11\x00\x02\x48\x00\x18\x00\x01\x00\x00\x00" \ 35 b"\xe9\x1c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" \ 36 b"\xef\xff\x00\x01\x32\x00\x18\x00\x01\x00\x00\x00\xbd\xeb\x00\x00" \ 37 b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xac\x11\x00\x02" \ 38 b"\x33\x00\x18\x00\x01\x00\x00\x00\xe8\x1c\x00\x00\x00\x00\x00\x00" \ 39 b"\x00\x00\x00\x00\x00\x00\x00\x00\xef\xff\x00\x01\x07\x80\x38\x00" \ 40 b"\x00\x00\x00\x00\x2c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" \ 41 b"\x00\x00\x00\x00\x1d\x00\x00\x00\x74\x65\x73\x74\x2e\x6c\x6f\x63" \ 42 b"\x61\x6c\x2f\x30\x2e\x38\x2e\x30\x2f\x4c\x69\x6e\x75\x78\x2f\x4c" \ 43 b"\x69\x6e\x75\x78\x00\x00\x00\x00\x19\x80\x04\x00\x00\x80\x06\x00" \ 44 b"\x01\x00\x00\x00" 45 46+ Test endianness 47= PID_BUILTIN_ENDPOINT_QOS endianness 48assert raw(PID_BUILTIN_ENDPOINT_QOS(parameterId=119, parameterLength=0, parameterData=b"")) == b'w\x00\x00\x00' 49 50 51+ Test RTPS 52= RTPS default header values 53pkt2 = RTPS()/RTPSMessage(submessages=[ 54 RTPSSubMessage_HEARTBEAT(), 55 RTPSSubMessage_INFO_TS(), 56 RTPSSubMessage_DATA(), 57]) 58assert bytes(RTPS()) == b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' 59 60= RTPS packet declaration 61pkt3 = RTPS( 62 protocolVersion=ProtocolVersionPacket(major=2, minor=1), 63 vendorId=VendorIdPacket(vendor_id=0x0110), 64 guidPrefix=GUIDPrefixPacket( 65 hostId=1466109953, appId=3601547391, instanceId=1540995868 66 ), 67 magic=b"RTPS", 68) / RTPSMessage( 69 submessages=[ 70 RTPSSubMessage_INFO_DST( 71 submessageId=14, 72 submessageFlags=1, 73 octetsToNextHeader=12, 74 guidPrefix=GUIDPrefixPacket( 75 hostId=2284457985, appId=1569494848, instanceId=2025205186 76 ), 77 ), 78 RTPSSubMessage_INFO_TS( 79 submessageId=9, 80 submessageFlags=1, 81 octetsToNextHeader=8, 82 ts_seconds=1619087604, 83 ts_fraction=475848017, 84 ), 85 RTPSSubMessage_DATA( 86 submessageId=21, 87 submessageFlags=5, 88 octetsToNextHeader=272, 89 extraFlags=0, 90 octetsToInlineQoS=16, 91 readerEntityIdKey=256, 92 readerEntityIdKind=199, 93 writerEntityIdKey=256, 94 writerEntityIdKind=194, 95 writerSeqNumHi=0, 96 writerSeqNumLow=1, 97 data=DataPacket( 98 encapsulationKind=3, 99 encapsulationOptions=0, 100 parameterList=ParameterListPacket( 101 parameterValues=[ 102 PID_PROTOCOL_VERSION( 103 parameterId=21, 104 parameterLength=4, 105 protocolVersion=ProtocolVersionPacket(major=2, minor=1), 106 padding=b"\x00\x00", 107 ), 108 PID_VENDOR_ID( 109 parameterId=22, 110 parameterLength=4, 111 vendorId=VendorIdPacket(vendor_id=0x0110), 112 padding=b"\x00\x00", 113 ), 114 PID_PARTICIPANT_LEASE_DURATION( 115 parameterId=2, 116 parameterLength=8, 117 parameterData=b"\n\x00\x00\x00\x00\x00\x00\x00", 118 ), 119 PID_PARTICIPANT_GUID( 120 parameterId=80, 121 parameterLength=16, 122 guid=GUIDPacket( 123 hostId=1466109953, 124 appId=3601547391, 125 instanceId=1540995868, 126 entityId=449, 127 ), 128 ), 129 PID_BUILTIN_ENDPOINT_SET( 130 parameterId=88, 131 parameterLength=4, 132 parameterData=b"?\x0c\x00\x00", 133 ), 134 PID_DOMAIN_ID( 135 parameterId=15, 136 parameterLength=4, 137 parameterData=b"\x00\x00\x00\x00", 138 ), 139 PID_DEFAULT_UNICAST_LOCATOR( 140 parameterId=49, 141 parameterLength=24, 142 locator=LocatorPacket( 143 locatorKind=1, port=60349, address="172.17.0.2" 144 ), 145 ), 146 PID_DEFAULT_MULTICAST_LOCATOR( 147 parameterId=72, 148 parameterLength=24, 149 locator=LocatorPacket( 150 locatorKind=1, port=7401, address="239.255.0.1" 151 ), 152 ), 153 PID_METATRAFFIC_UNICAST_LOCATOR( 154 parameterId=50, 155 parameterLength=24, 156 locator=LocatorPacket( 157 locatorKind=1, port=60349, address="172.17.0.2" 158 ), 159 ), 160 PID_METATRAFFIC_MULTICAST_LOCATOR( 161 parameterId=51, 162 parameterLength=24, 163 locator=LocatorPacket( 164 locatorKind=1, port=7400, address="239.255.0.1" 165 ), 166 ), 167 PID_UNKNOWN( 168 parameterId=32775, 169 parameterLength=56, 170 parameterData=b"\x00\x00\x00\x00,\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1d\x00\x00\x00test.local/0.8.0/Linux/Linux\x00\x00\x00\x00", 171 ), 172 PID_UNKNOWN( 173 parameterId=32793, 174 parameterLength=4, 175 parameterData=b"\x00\x80\x06\x00", 176 ), 177 ], 178 sentinel=PID_SENTINEL(parameterId=1, parameterLength=0), 179 ), 180 ), 181 ), 182 ] 183) 184 185= RTPS header dissect 186assert pkt3.build() == pkt 187 188+ Test RTI RTPS 189= Test dissection 190d = b"\x52\x54\x50\x53\x02\x03\x01\x01\x01\x01\x30\xba\xa8\x7b\x1d\xce" \ 191 b"\xb3\x29\x1e\x43\x09\x01\x08\x00\xd6\x64\xa8\x61\x16\x09\x34\x7c" \ 192 b"\x15\x05\xdc\x02\x00\x00\x10\x00\x00\x00\x00\x00\x00\x01\x00\xc2" \ 193 b"\x00\x00\x00\x00\x01\x00\x00\x00\x00\x03\x00\x00\x50\x00\x10\x00" \ 194 b"\x01\x01\x30\xba\xa8\x7b\x1d\xce\xb3\x29\x1e\x43\x00\x00\x01\xc1" \ 195 b"\x58\x00\x04\x00\x3f\x0c\x00\x00\x77\x00\x04\x00\x01\x00\x00\x00" \ 196 b"\x15\x00\x04\x00\x02\x03\x00\x00\x16\x00\x04\x00\x01\x01\x00\x00" \ 197 b"\x00\x80\x04\x00\x06\x00\x01\x00\x59\x00\x78\x01\x06\x00\x00\x00" \ 198 b"\x16\x00\x00\x00\x64\x64\x73\x2e\x73\x79\x73\x5f\x69\x6e\x66\x6f" \ 199 b"\x2e\x68\x6f\x73\x74\x6e\x61\x6d\x65\x00\x00\x00\x0d\x00\x00\x00" \ 200 b"\x64\x66\x30\x62\x36\x64\x38\x33\x61\x62\x34\x36\x00\x00\x00\x00" \ 201 b"\x18\x00\x00\x00\x64\x64\x73\x2e\x73\x79\x73\x5f\x69\x6e\x66\x6f" \ 202 b"\x2e\x70\x72\x6f\x63\x65\x73\x73\x5f\x69\x64\x00\x05\x00\x00\x00" \ 203 b"\x34\x38\x33\x30\x00\x00\x00\x00\x21\x00\x00\x00\x64\x64\x73\x2e" \ 204 b"\x73\x79\x73\x5f\x69\x6e\x66\x6f\x2e\x65\x78\x65\x63\x75\x74\x61" \ 205 b"\x62\x6c\x65\x5f\x66\x69\x6c\x65\x70\x61\x74\x68\x00\x00\x00\x00" \ 206 b"\x42\x00\x00\x00\x2f\x75\x73\x72\x2f\x6c\x6f\x63\x61\x6c\x2f\x73" \ 207 b"\x72\x63\x2f\x72\x74\x69\x2f\x72\x65\x73\x6f\x75\x72\x63\x65\x2f" \ 208 b"\x61\x70\x70\x2f\x62\x69\x6e\x2f\x78\x36\x34\x4c\x69\x6e\x75\x78" \ 209 b"\x32\x2e\x36\x67\x63\x63\x34\x2e\x34\x2e\x35\x2f\x72\x74\x69\x64" \ 210 b"\x64\x73\x73\x70\x79\x00\x00\x00\x14\x00\x00\x00\x64\x64\x73\x2e" \ 211 b"\x73\x79\x73\x5f\x69\x6e\x66\x6f\x2e\x74\x61\x72\x67\x65\x74\x00" \ 212 b"\x14\x00\x00\x00\x78\x36\x34\x4c\x69\x6e\x75\x78\x32\x2e\x36\x67" \ 213 b"\x63\x63\x34\x2e\x34\x2e\x35\x00\x20\x00\x00\x00\x64\x64\x73\x2e" \ 214 b"\x73\x79\x73\x5f\x69\x6e\x66\x6f\x2e\x63\x72\x65\x61\x74\x69\x6f" \ 215 b"\x6e\x5f\x74\x69\x6d\x65\x73\x74\x61\x6d\x70\x00\x14\x00\x00\x00" \ 216 b"\x32\x30\x32\x31\x2d\x30\x36\x2d\x37\x20\x30\x34\x3a\x30\x39\x3a" \ 217 b"\x30\x32\x5a\x00\x21\x00\x00\x00\x64\x64\x73\x2e\x73\x79\x73\x5f" \ 218 b"\x69\x6e\x66\x6f\x2e\x65\x78\x65\x63\x75\x74\x69\x6f\x6e\x5f\x74" \ 219 b"\x69\x6d\x65\x73\x74\x61\x6d\x70\x00\x00\x00\x00\x14\x00\x00\x00" \ 220 b"\x32\x30\x32\x31\x2d\x31\x32\x2d\x31\x20\x30\x39\x3a\x31\x35\x3a" \ 221 b"\x32\x39\x5a\x00\x31\x00\x18\x00\x01\x00\x00\x00\xf3\x1c\x00\x00" \ 222 b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" \ 223 b"\x31\x00\x18\x00\x00\x00\x00\x01\xf3\x1c\x00\x00\x61\xab\xd9\x79" \ 224 b"\xb5\x7c\x13\xa5\x29\x49\x2c\xa3\x00\x00\x00\x00\x32\x00\x18\x00" \ 225 b"\x01\x00\x00\x00\xf2\x1c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" \ 226 b"\x00\x00\x00\x00\x00\x00\x00\x00\x32\x00\x18\x00\x00\x00\x00\x01" \ 227 b"\xf2\x1c\x00\x00\x61\xab\xd9\x79\xb5\x7c\x13\xa5\x29\x49\x2c\xa3" \ 228 b"\x00\x00\x00\x00\x33\x00\x18\x00\x01\x00\x00\x00\xe8\x1c\x00\x00" \ 229 b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xef\xff\x00\x01" \ 230 b"\x02\x00\x08\x00\x06\x00\x00\x00\xff\xff\xff\x7f\x01\x80\x04\x00" \ 231 b"\xff\xff\x00\x00\x62\x00\x28\x00\x22\x00\x00\x00\x52\x54\x49\x20" \ 232 b"\x44\x61\x74\x61\x20\x44\x69\x73\x74\x72\x69\x62\x75\x74\x69\x6f" \ 233 b"\x6e\x20\x53\x65\x72\x76\x69\x63\x65\x20\x53\x70\x79\x00\x00\x00" \ 234 b"\x0f\x00\x04\x00\x00\x00\x00\x00\x0f\x80\x04\x00\x00\x00\x00\x00" \ 235 b"\x10\x80\x14\x00\x02\x00\x00\x00\x01\x00\x00\x00\xe3\xff\x00\x00" \ 236 b"\x00\x00\x00\x01\x00\x00\x01\x00\x16\x80\x08\x00\x10\x00\x00\x00" \ 237 b"\x00\x00\x00\x00\x17\x80\x04\x00\x03\x00\x00\x00\x01\x00\x00\x00" 238 239p0 = RTPS(d) 240p1 = RTPS( 241 protocolVersion=ProtocolVersionPacket(major=2, minor=3), 242 vendorId=VendorIdPacket(vendor_id=0x0101), 243 guidPrefix=GUIDPrefixPacket( 244 hostId=16855226, appId=2826640846, instanceId=3005816387 245 ), 246 magic=b"RTPS", 247) / RTPSMessage( 248 submessages=[ 249 RTPSSubMessage_INFO_TS( 250 submessageId=9, 251 submessageFlags=1, 252 octetsToNextHeader=8, 253 ts_seconds=1638425814, 254 ts_fraction=2083784982, 255 ), 256 RTPSSubMessage_DATA( 257 submessageId=21, 258 submessageFlags=5, 259 octetsToNextHeader=732, 260 extraFlags=0, 261 octetsToInlineQoS=16, 262 readerEntityIdKey=0, 263 readerEntityIdKind=0, 264 writerEntityIdKey=256, 265 writerEntityIdKind=194, 266 writerSeqNumHi=0, 267 writerSeqNumLow=1, 268 data=DataPacket( 269 encapsulationKind=3, 270 encapsulationOptions=0, 271 parameterList=ParameterListPacket( 272 parameterValues=[ 273 PID_PARTICIPANT_GUID( 274 parameterId=80, 275 parameterLength=16, 276 guid=GUIDPacket( 277 hostId=16855226, 278 appId=2826640846, 279 instanceId=3005816387, 280 entityId=449, 281 ), 282 ), 283 PID_BUILTIN_ENDPOINT_SET( 284 parameterId=88, 285 parameterLength=4, 286 parameterData=b"?\x0c\x00\x00", 287 ), 288 PID_BUILTIN_ENDPOINT_QOS( 289 parameterId=119, 290 parameterLength=4, 291 parameterData=b"\x01\x00\x00\x00", 292 ), 293 PID_PROTOCOL_VERSION( 294 parameterId=21, 295 parameterLength=4, 296 protocolVersion=ProtocolVersionPacket(major=2, minor=3), 297 padding=b"\x00\x00", 298 ), 299 PID_VENDOR_ID( 300 parameterId=22, 301 parameterLength=4, 302 vendorId=VendorIdPacket(vendor_id=0x0101), 303 padding=b"\x00\x00", 304 ), 305 PID_PRODUCT_VERSION( 306 parameterId=32768, 307 parameterLength=4, 308 productVersion=ProductVersionPacket( 309 major=6, minor=0, release=1, revision=0 310 ), 311 ), 312 PID_PROPERTY_LIST( 313 parameterId=89, 314 parameterLength=376, 315 parameterData=b"\x06\x00\x00\x00\x16\x00\x00\x00dds.sys_info.hostname\x00\x00\x00\r\x00\x00\x00df0b6d83ab46\x00\x00\x00\x00\x18\x00\x00\x00dds.sys_info.process_id\x00\x05\x00\x00\x004830\x00\x00\x00\x00!\x00\x00\x00dds.sys_info.executable_filepath\x00\x00\x00\x00B\x00\x00\x00/usr/local/src/rti/resource/app/bin/x64Linux2.6gcc4.4.5/rtiddsspy\x00\x00\x00\x14\x00\x00\x00dds.sys_info.target\x00\x14\x00\x00\x00x64Linux2.6gcc4.4.5\x00 \x00\x00\x00dds.sys_info.creation_timestamp\x00\x14\x00\x00\x002021-06-7 04:09:02Z\x00!\x00\x00\x00dds.sys_info.execution_timestamp\x00\x00\x00\x00\x14\x00\x00\x002021-12-1 09:15:29Z\x00", 316 ), 317 PID_DEFAULT_UNICAST_LOCATOR( 318 parameterId=49, 319 parameterLength=24, 320 locator=LocatorPacket( 321 locatorKind=1, port=7411, address="0.0.0.0" 322 ), 323 ), 324 PID_DEFAULT_UNICAST_LOCATOR( 325 parameterId=49, 326 parameterLength=24, 327 locator=LocatorPacket( 328 locatorKind=16777216, 329 port=7411, 330 hostId=b"a\xab\xd9y\xb5|\x13\xa5)I,\xa3\x00\x00\x00\x00", 331 ), 332 ), 333 PID_METATRAFFIC_UNICAST_LOCATOR( 334 parameterId=50, 335 parameterLength=24, 336 locator=LocatorPacket( 337 locatorKind=1, port=7410, address="0.0.0.0" 338 ), 339 ), 340 PID_METATRAFFIC_UNICAST_LOCATOR( 341 parameterId=50, 342 parameterLength=24, 343 locator=LocatorPacket( 344 locatorKind=16777216, 345 port=7410, 346 hostId=b"a\xab\xd9y\xb5|\x13\xa5)I,\xa3\x00\x00\x00\x00", 347 ), 348 ), 349 PID_METATRAFFIC_MULTICAST_LOCATOR( 350 parameterId=51, 351 parameterLength=24, 352 locator=LocatorPacket( 353 locatorKind=1, port=7400, address="239.255.0.1" 354 ), 355 ), 356 PID_PARTICIPANT_LEASE_DURATION( 357 parameterId=2, 358 parameterLength=8, 359 parameterData=b"\x06\x00\x00\x00\xff\xff\xff\x7f", 360 ), 361 PID_PLUGIN_PROMISCUITY_KIND( 362 parameterId=32769, parameterLength=4, promiscuityKind=65535 363 ), 364 PID_ENTITY_NAME( 365 parameterId=98, 366 parameterLength=40, 367 parameterData=b'"\x00\x00\x00RTI Data Distribution Service Spy\x00\x00\x00', 368 ), 369 PID_DOMAIN_ID( 370 parameterId=15, 371 parameterLength=4, 372 parameterData=b"\x00\x00\x00\x00", 373 ), 374 PID_RTI_DOMAIN_ID( 375 parameterId=32783, parameterLength=4, domainId=0 376 ), 377 PID_TRANSPORT_INFO_LIST( 378 transportInfo=[ 379 TransportInfoPacket(classID=1, messageSizeMax=65507), 380 TransportInfoPacket( 381 classID=16777216, messageSizeMax=65536 382 ), 383 ], 384 parameterId=32784, 385 parameterLength=20, 386 padding=b"\x02\x00\x00\x00", 387 ), 388 PID_REACHABILITY_LEASE_DURATION( 389 parameterId=32790, 390 parameterLength=8, 391 lease_duration=LeaseDurationPacket( 392 seconds=268435456, fraction=0 393 ), 394 ), 395 PID_VENDOR_BUILTIN_ENDPOINT_SET( 396 parameterId=32791, parameterLength=4, flags=3 397 ), 398 ], 399 sentinel=PID_SENTINEL(parameterId=1, parameterLength=0), 400 ), 401 ), 402 ), 403 ] 404) 405assert p0.build() == d 406assert p1.build() == d 407assert p1 == p0 408 409+ Test for pr #3914 410= RTPS Heartbeat SequenceNumber_t packing and dissection 411 412d = b"\x52\x54\x50\x53\x02\x02\x01\x0f\x01\x0f\x45\xd2\xb3\xf5\x58\xb9" \ 413 b"\x01\x00\x00\x00\x07\x01\x1c\x00\x00\x00\x03\xc7\x00\x00\x03\xc2" \ 414 b"\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00" \ 415 b"\x01\x00\x00\x00" 416 417p0 = RTPS(d) 418 419p1 = RTPS( 420 protocolVersion=ProtocolVersionPacket(major=2, minor=2), 421 vendorId=VendorIdPacket(vendor_id=0x010f), 422 guidPrefix=GUIDPrefixPacket( 423 hostId=0x010f45d2, appId=0xb3f558b9, instanceId=0x01000000 424 ), 425 magic=b"RTPS", 426) / RTPSMessage( 427 submessages=[ 428 RTPSSubMessage_HEARTBEAT( 429 submessageId=0x07, 430 submessageFlags=0x01, 431 octetsToNextHeader=28, 432 reader_id=b"\x00\x00\x03\xc7", 433 writer_id=b"\x00\x00\x03\xc2", 434 firstAvailableSeqNumHi=0, 435 firstAvailableSeqNumLow=1, 436 lastSeqNumHi=0, 437 lastSeqNumLow=1, 438 count=1 439 ) 440 ] 441) 442 443assert p0.build() == d 444assert p1.build() == d 445assert p0 == p1 446 447+ Test for pr #3915 448= RTPS ACKNACK count packing and dissection 449 450d = b"\x52\x54\x50\x53\x02\x02\x01\x0f\x01\x0f\x45\xd2\xb3\xf5\x58\xb9" \ 451 b"\x01\x00\x00\x00\x06\x03\x18\x00\x00\x00\x03\xc7\x00\x00\x03\xc2" \ 452 b"\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00" 453p0 = RTPS(d) 454 455p1 = RTPS( 456 protocolVersion=ProtocolVersionPacket(major=2, minor=2), 457 vendorId=VendorIdPacket(vendor_id=0x010f), 458 guidPrefix=GUIDPrefixPacket( 459 hostId=0x010f45d2, appId=0xb3f558b9, instanceId=0x01000000 460 ), 461 magic=b"RTPS", 462) / RTPSMessage( 463 submessages=[ 464 RTPSSubMessage_ACKNACK( 465 submessageId=6, 466 submessageFlags=3, 467 octetsToNextHeader=0x18, 468 reader_id=b'\x00\x00\x03\xc7', 469 writer_id=b'\x00\x00\x03\xc2', 470 readerSNState=b'\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00', 471 count=1 472 ) 473 ] 474) 475 476assert p0.build() == d 477assert p1.build() == d 478assert p0 == p1 479