libuav original
Dependents: UAVCAN UAVCAN_Subscriber
transfer_receiver.cpp
00001 /* 00002 * Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com> 00003 */ 00004 00005 #include <algorithm> 00006 #include <gtest/gtest.h> 00007 #include <uavcan/transport/transfer_receiver.hpp> 00008 #include "../clock.hpp" 00009 #include "transfer_test_helpers.hpp" 00010 00011 /* 00012 * Beware! 00013 * The code you're about to look at desperately needs some cleaning. 00014 */ 00015 00016 enum SotEotToggle 00017 { 00018 SET000 = 0, 00019 SET001 = 1, 00020 SET010 = 2, 00021 SET011 = 3, 00022 SET100 = 4, 00023 SET101 = 5, // Illegal 00024 SET110 = 6, 00025 SET111 = 7 // Illegal 00026 }; 00027 00028 struct RxFrameGenerator 00029 { 00030 static const uavcan::TransferBufferManagerKey DEFAULT_KEY; 00031 enum { TARGET_NODE_ID = 126 }; 00032 00033 uint16_t data_type_id; 00034 uavcan::TransferBufferManagerKey bufmgr_key; 00035 00036 RxFrameGenerator(uint16_t data_type_id, const uavcan::TransferBufferManagerKey& bufmgr_key = DEFAULT_KEY) 00037 : data_type_id(data_type_id) 00038 , bufmgr_key(bufmgr_key) 00039 { } 00040 00041 /// iface_index, data, set, transfer_id, ts_monotonic [, ts_utc] 00042 uavcan::RxFrame operator()(uint8_t iface_index, const std::string& data, SotEotToggle set, 00043 uint8_t transfer_id, uint64_t ts_monotonic, uint64_t ts_utc = 0) 00044 { 00045 const uavcan::NodeID dst_nid = 00046 (bufmgr_key.getTransferType() == uavcan::TransferTypeMessageBroadcast) ? 00047 uavcan::NodeID::Broadcast : TARGET_NODE_ID; 00048 00049 uavcan::Frame frame(data_type_id, bufmgr_key.getTransferType(), bufmgr_key.getNodeID(), 00050 dst_nid, transfer_id); 00051 00052 frame.setStartOfTransfer((set & (1 << 2)) != 0); 00053 frame.setEndOfTransfer((set & (1 << 1)) != 0); 00054 00055 if ((set & (1 << 0)) != 0) 00056 { 00057 frame.flipToggle(); 00058 } 00059 00060 EXPECT_EQ(data.length(), 00061 frame.setPayload(reinterpret_cast<const uint8_t*>(data.c_str()), unsigned(data.length()))); 00062 00063 uavcan::RxFrame output(frame, uavcan::MonotonicTime::fromUSec(ts_monotonic), 00064 uavcan::UtcTime::fromUSec(ts_utc), iface_index); 00065 //std::cout << "Generated frame: " << output.toString() << std::endl; 00066 00067 return output; 00068 } 00069 }; 00070 00071 const uavcan::TransferBufferManagerKey RxFrameGenerator::DEFAULT_KEY(42, uavcan::TransferTypeMessageBroadcast); 00072 00073 00074 template <unsigned BufSize> 00075 struct Context 00076 { 00077 uavcan::PoolAllocator<uavcan::MemPoolBlockSize * 100, uavcan::MemPoolBlockSize> pool; 00078 uavcan::TransferReceiver receiver; // Must be default constructible and copyable 00079 uavcan::TransferBufferManager bufmgr; 00080 00081 Context() : 00082 bufmgr(BufSize, pool) 00083 { } 00084 00085 ~Context() 00086 { 00087 // We need to destroy the receiver before its buffer manager 00088 receiver = uavcan::TransferReceiver(); 00089 } 00090 }; 00091 00092 00093 static bool matchBufferContent(const uavcan::ITransferBuffer* tbb, const std::string& content) 00094 { 00095 uint8_t data[1024]; 00096 std::fill(data, data + sizeof(data), 0); 00097 if (content.length() > sizeof(data)) 00098 { 00099 std::cerr << "matchBufferContent(): Content is too long" << std::endl; 00100 std::exit(1); 00101 } 00102 tbb->read(0, data, unsigned(content.length())); 00103 if (std::equal(content.begin(), content.end(), data)) 00104 { 00105 return true; 00106 } 00107 std::cout << "Buffer content mismatch:" 00108 << "\n\tExpected: " << content 00109 << "\n\tActually: " << reinterpret_cast<const char*>(data) 00110 << std::endl; 00111 return false; 00112 } 00113 00114 00115 #define CHECK_NOT_COMPLETE(x) ASSERT_EQ(uavcan::TransferReceiver::ResultNotComplete, (x)) 00116 #define CHECK_COMPLETE(x) ASSERT_EQ(uavcan::TransferReceiver::ResultComplete, (x)) 00117 #define CHECK_SINGLE_FRAME(x) ASSERT_EQ(uavcan::TransferReceiver::ResultSingleFrame, (x)) 00118 00119 TEST(TransferReceiver, Basic) 00120 { 00121 using uavcan::TransferReceiver; 00122 Context<32> context; 00123 RxFrameGenerator gen(789); 00124 uavcan::TransferReceiver& rcv = context.receiver; 00125 uavcan::TransferBufferManager& bufmgr = context.bufmgr; 00126 uavcan::TransferBufferAccessor bk(context.bufmgr, RxFrameGenerator::DEFAULT_KEY); 00127 00128 std::cout << "sizeof(TransferReceiver): " << sizeof(TransferReceiver) << std::endl; 00129 00130 /* 00131 * Empty 00132 */ 00133 ASSERT_EQ(TransferReceiver::getDefaultTransferInterval(), rcv.getInterval()); 00134 ASSERT_EQ(0, rcv.getLastTransferTimestampMonotonic().toUSec()); 00135 00136 /* 00137 * Single frame transfer with zero ts, must be ignored 00138 */ 00139 CHECK_NOT_COMPLETE(rcv.addFrame(gen(0, "Foo", SET110, 0, 0), bk)); 00140 ASSERT_EQ(TransferReceiver::getDefaultTransferInterval(), rcv.getInterval()); 00141 ASSERT_EQ(0, rcv.getLastTransferTimestampMonotonic().toUSec()); 00142 00143 /* 00144 * Valid compound transfer 00145 * Args: iface_index, data, set, transfer_id, ts_monotonic 00146 */ 00147 CHECK_NOT_COMPLETE(rcv.addFrame(gen(0, "\x34\x12" "34567", SET100, 0, 100), bk)); 00148 CHECK_COMPLETE( rcv.addFrame(gen(0, "foo", SET011, 0, 200), bk)); 00149 00150 ASSERT_TRUE(matchBufferContent(bufmgr.access(gen.bufmgr_key), "34567foo")); 00151 ASSERT_EQ(0x1234, rcv.getLastTransferCrc()); 00152 ASSERT_EQ(TransferReceiver::getDefaultTransferInterval(), rcv.getInterval()); // Not initialized yet 00153 ASSERT_EQ(100, rcv.getLastTransferTimestampMonotonic().toUSec()); 00154 00155 /* 00156 * Compound transfer mixed with invalid frames; buffer was not released explicitly 00157 * Args: iface_index, data, set, transfer_id, ts_monotonic 00158 */ 00159 CHECK_NOT_COMPLETE(rcv.addFrame(gen(0, "qwe", SET100, 0, 300), bk)); // Previous TID, rejected 00160 CHECK_NOT_COMPLETE(rcv.addFrame(gen(1, "rty", SET100, 0, 300), bk)); // Previous TID, wrong iface 00161 CHECK_NOT_COMPLETE(rcv.addFrame(gen(0, "\x9a\x78" "34567", SET100, 1, 1000), bk)); 00162 CHECK_NOT_COMPLETE(rcv.addFrame(gen(0, "qwertyu", SET100, 1, 1100), bk)); // Old toggle 00163 CHECK_NOT_COMPLETE(rcv.addFrame(gen(0, "qwertyu", SET000, 1, 1100), bk)); // Old toggle 00164 CHECK_NOT_COMPLETE(rcv.addFrame(gen(0, "abcdefg", SET001, 1, 1200), bk)); 00165 CHECK_NOT_COMPLETE(rcv.addFrame(gen(0, "4567891", SET001, 2, 1300), bk)); // Next TID, but not SOT 00166 CHECK_NOT_COMPLETE(rcv.addFrame(gen(1, "", SET010, 1, 1300), bk)); // Wrong iface 00167 CHECK_NOT_COMPLETE(rcv.addFrame(gen(0, "", SET001, 1, 1300), bk)); // Unexpected toggle 00168 CHECK_COMPLETE( rcv.addFrame(gen(0, "", SET010, 1, 1300), bk)); 00169 00170 ASSERT_TRUE(matchBufferContent(bufmgr.access(gen.bufmgr_key), "34567abcdefg")); 00171 ASSERT_EQ(0x789A, rcv.getLastTransferCrc()); 00172 ASSERT_GE(TransferReceiver::getDefaultTransferInterval(), rcv.getInterval()); 00173 ASSERT_LE(TransferReceiver::getMinTransferInterval(), rcv.getInterval()); 00174 ASSERT_EQ(1000, rcv.getLastTransferTimestampMonotonic().toUSec()); 00175 ASSERT_FALSE(rcv.isTimedOut(tsMono(1000))); 00176 ASSERT_FALSE(rcv.isTimedOut(tsMono(5000))); 00177 ASSERT_TRUE(rcv.isTimedOut(tsMono(60000000))); 00178 00179 /* 00180 * Single-frame transfers 00181 * Args: iface_index, data, set, transfer_id, ts_monotonic 00182 */ 00183 CHECK_NOT_COMPLETE(rcv.addFrame(gen(0, "qwe", SET110, 1, 2000), bk)); // Previous TID 00184 CHECK_NOT_COMPLETE(rcv.addFrame(gen(1, "qwe", SET110, 2, 2100), bk)); // Wrong iface 00185 CHECK_SINGLE_FRAME(rcv.addFrame(gen(0, "qwe", SET110, 2, 2200), bk)); 00186 00187 ASSERT_FALSE(bufmgr.access(gen.bufmgr_key)); // Buffer must be removed 00188 ASSERT_GT(TransferReceiver::getDefaultTransferInterval(), rcv.getInterval()); 00189 ASSERT_EQ(2200, rcv.getLastTransferTimestampMonotonic().toUSec()); 00190 00191 CHECK_SINGLE_FRAME(rcv.addFrame(gen(0, "", SET110, 3, 2500), bk)); 00192 ASSERT_EQ(2500, rcv.getLastTransferTimestampMonotonic().toUSec()); 00193 00194 CHECK_SINGLE_FRAME(rcv.addFrame(gen(0, "", SET110, 0, 3000), bk)); 00195 CHECK_SINGLE_FRAME(rcv.addFrame(gen(0, "", SET110, 1, 3100), bk)); 00196 CHECK_SINGLE_FRAME(rcv.addFrame(gen(0, "", SET110, 3, 3200), bk)); 00197 CHECK_NOT_COMPLETE(rcv.addFrame(gen(1, "", SET110, 0, 3300), bk)); // Old TID, wrong iface 00198 CHECK_NOT_COMPLETE(rcv.addFrame(gen(1, "", SET110, 2, 3400), bk)); // Old TID, wrong iface 00199 CHECK_NOT_COMPLETE(rcv.addFrame(gen(1, "", SET110, 3, 3500), bk)); // Old TID, wrong iface 00200 CHECK_SINGLE_FRAME(rcv.addFrame(gen(0, "", SET110, 4, 3600), bk)); 00201 ASSERT_EQ(3600, rcv.getLastTransferTimestampMonotonic().toUSec()); 00202 00203 std::cout << "Interval: " << rcv.getInterval().toString() << std::endl; 00204 00205 /* 00206 * Timeouts 00207 */ 00208 CHECK_NOT_COMPLETE(rcv.addFrame(gen(1, "qwe", SET110, 1, 5000), bk)); // Wrong iface - ignored 00209 CHECK_SINGLE_FRAME(rcv.addFrame(gen(1, "qwe", SET110, 6, 1500000), bk)); // Accepted due to iface timeout 00210 ASSERT_EQ(1500000, rcv.getLastTransferTimestampMonotonic().toUSec()); 00211 00212 std::cout << "Interval: " << rcv.getInterval().toString() << std::endl; 00213 00214 CHECK_NOT_COMPLETE(rcv.addFrame(gen(0, "qwe", SET110, 7, 1500100), bk)); // Ignored - old iface 0 00215 CHECK_SINGLE_FRAME(rcv.addFrame(gen(1, "qwe", SET110, 7, 1500100), bk)); 00216 ASSERT_EQ(1500100, rcv.getLastTransferTimestampMonotonic().toUSec()); 00217 00218 std::cout << "Interval: " << rcv.getInterval().toString() << std::endl; 00219 00220 CHECK_NOT_COMPLETE(rcv.addFrame(gen(1, "qwe", SET110, 7, 1500100), bk)); // Old TID 00221 CHECK_SINGLE_FRAME(rcv.addFrame(gen(0, "qwe", SET110, 7, 100000000), bk)); // Accepted - global timeout 00222 ASSERT_EQ(100000000, rcv.getLastTransferTimestampMonotonic().toUSec()); 00223 00224 std::cout << "Interval: " << rcv.getInterval().toString() << std::endl; 00225 00226 CHECK_SINGLE_FRAME(rcv.addFrame(gen(0, "qwe", SET110, 8, 100000100), bk)); 00227 ASSERT_EQ(100000100, rcv.getLastTransferTimestampMonotonic().toUSec()); 00228 00229 std::cout << "Interval: " << rcv.getInterval().toString() << std::endl; 00230 00231 ASSERT_TRUE(rcv.isTimedOut(tsMono(900000000))); 00232 CHECK_NOT_COMPLETE(rcv.addFrame(gen(1, "\x78\x56" "34567", SET100, 0, 900000000), bk)); // Global timeout 00233 CHECK_NOT_COMPLETE(rcv.addFrame(gen(0, "1234567", SET100, 0, 900000100), bk)); // Wrong iface 00234 CHECK_NOT_COMPLETE(rcv.addFrame(gen(0, "qwe", SET011, 0, 900000200), bk)); // Wrong iface 00235 CHECK_COMPLETE( rcv.addFrame(gen(1, "qwe", SET011, 0, 900000200), bk)); 00236 00237 ASSERT_EQ(900000000, rcv.getLastTransferTimestampMonotonic().toUSec()); 00238 std::cout << "Interval: " << rcv.getInterval().toString() << std::endl; 00239 00240 ASSERT_FALSE(rcv.isTimedOut(tsMono(1000))); 00241 ASSERT_FALSE(rcv.isTimedOut(tsMono(900000300))); 00242 ASSERT_TRUE(rcv.isTimedOut(tsMono(9990000000))); 00243 00244 ASSERT_LT(TransferReceiver::getDefaultTransferInterval(), rcv.getInterval()); 00245 ASSERT_LE(TransferReceiver::getMinTransferInterval(), rcv.getInterval()); 00246 ASSERT_GE(TransferReceiver::getMaxTransferInterval(), rcv.getInterval()); 00247 ASSERT_TRUE(matchBufferContent(bufmgr.access(gen.bufmgr_key), "34567qwe")); 00248 ASSERT_EQ(0x5678, rcv.getLastTransferCrc()); 00249 00250 /* 00251 * Destruction 00252 */ 00253 ASSERT_TRUE(bufmgr.access(gen.bufmgr_key)); 00254 context.receiver.~TransferReceiver(); // TransferReceiver does not own the buffer, it must not be released! 00255 ASSERT_TRUE(bufmgr.access(gen.bufmgr_key)); // Making sure that the buffer is still there 00256 } 00257 00258 00259 TEST(TransferReceiver, OutOfBufferSpace_32bytes) 00260 { 00261 Context<32> context; 00262 RxFrameGenerator gen(789); 00263 uavcan::TransferReceiver& rcv = context.receiver; 00264 uavcan::TransferBufferManager& bufmgr = context.bufmgr; 00265 uavcan::TransferBufferAccessor bk(context.bufmgr, RxFrameGenerator::DEFAULT_KEY); 00266 00267 /* 00268 * Simple transfer, maximum buffer length 00269 */ 00270 CHECK_NOT_COMPLETE(rcv.addFrame(gen(1, "1234567", SET100, 1, 100000000), bk)); // 5 00271 CHECK_NOT_COMPLETE(rcv.addFrame(gen(1, "1234567", SET001, 1, 100000100), bk)); // 12 00272 CHECK_NOT_COMPLETE(rcv.addFrame(gen(1, "1234567", SET000, 1, 100000200), bk)); // 19 00273 CHECK_NOT_COMPLETE(rcv.addFrame(gen(1, "1234567", SET001, 1, 100000300), bk)); // 26 00274 CHECK_COMPLETE( rcv.addFrame(gen(1, "123456", SET010, 1, 100000400), bk)); // 32 00275 00276 ASSERT_EQ(100000000, rcv.getLastTransferTimestampMonotonic().toUSec()); 00277 ASSERT_TRUE(matchBufferContent(bufmgr.access(gen.bufmgr_key), "34567123456712345671234567123456")); 00278 ASSERT_EQ(0x3231, rcv.getLastTransferCrc()); // CRC from "12", which is 0x3231 in little endian 00279 00280 /* 00281 * Transfer longer than available buffer space 00282 */ 00283 CHECK_NOT_COMPLETE(rcv.addFrame(gen(1, "1234567", SET100, 2, 100001000), bk)); // 5 00284 CHECK_NOT_COMPLETE(rcv.addFrame(gen(1, "1234567", SET001, 2, 100001100), bk)); // 12 00285 CHECK_NOT_COMPLETE(rcv.addFrame(gen(1, "1234567", SET000, 2, 100001200), bk)); // 19 00286 CHECK_NOT_COMPLETE(rcv.addFrame(gen(1, "1234567", SET001, 2, 100001200), bk)); // 26 00287 CHECK_NOT_COMPLETE(rcv.addFrame(gen(1, "1234567", SET010, 2, 100001300), bk)); // 33 // EOT, ignored - lost sync 00288 00289 ASSERT_EQ(100000000, rcv.getLastTransferTimestampMonotonic().toUSec()); // Timestamp will not be overriden 00290 ASSERT_FALSE(bufmgr.access(gen.bufmgr_key)); // Buffer should be removed 00291 00292 ASSERT_EQ(1, rcv.yieldErrorCount()); 00293 ASSERT_EQ(0, rcv.yieldErrorCount()); 00294 } 00295 00296 00297 TEST(TransferReceiver, OutOfOrderFrames) 00298 { 00299 Context<32> context; 00300 RxFrameGenerator gen(789); 00301 uavcan::TransferReceiver& rcv = context.receiver; 00302 uavcan::TransferBufferManager& bufmgr = context.bufmgr; 00303 uavcan::TransferBufferAccessor bk(context.bufmgr, RxFrameGenerator::DEFAULT_KEY); 00304 00305 CHECK_NOT_COMPLETE(rcv.addFrame(gen(1, "1234567", SET100, 7, 100000000), bk)); 00306 CHECK_NOT_COMPLETE(rcv.addFrame(gen(1, "-------", SET000, 7, 100000100), bk)); // Out of order 00307 CHECK_NOT_COMPLETE(rcv.addFrame(gen(1, "-------", SET010, 7, 100000200), bk)); // Out of order 00308 CHECK_NOT_COMPLETE(rcv.addFrame(gen(1, "qwertyu", SET001, 7, 100000300), bk)); 00309 CHECK_NOT_COMPLETE(rcv.addFrame(gen(1, "-------", SET011, 7, 100000200), bk)); // Out of order 00310 CHECK_COMPLETE( rcv.addFrame(gen(1, "abcd", SET010, 7, 100000400), bk)); 00311 00312 ASSERT_EQ(100000000, rcv.getLastTransferTimestampMonotonic().toUSec()); 00313 ASSERT_TRUE(matchBufferContent(bufmgr.access(gen.bufmgr_key), "34567qwertyuabcd")); 00314 ASSERT_EQ(0x3231, rcv.getLastTransferCrc()); 00315 00316 ASSERT_EQ(3, rcv.yieldErrorCount()); 00317 ASSERT_EQ(0, rcv.yieldErrorCount()); 00318 } 00319 00320 00321 TEST(TransferReceiver, IntervalMeasurement) 00322 { 00323 Context<32> context; 00324 RxFrameGenerator gen(789); 00325 uavcan::TransferReceiver& rcv = context.receiver; 00326 uavcan::TransferBufferManager& bufmgr = context.bufmgr; 00327 uavcan::TransferBufferAccessor bk(context.bufmgr, RxFrameGenerator::DEFAULT_KEY); 00328 00329 static const int INTERVAL = 1000; 00330 uavcan::TransferID tid; 00331 uint64_t timestamp = 100000000; 00332 00333 for (int i = 0; i < 1000; i++) 00334 { 00335 CHECK_NOT_COMPLETE(rcv.addFrame(gen(1, "1234567", SET100, tid.get(), timestamp), bk)); 00336 CHECK_NOT_COMPLETE(rcv.addFrame(gen(1, "qwertyu", SET001, tid.get(), timestamp), bk)); 00337 CHECK_COMPLETE( rcv.addFrame(gen(1, "abcd", SET010, tid.get(), timestamp), bk)); 00338 00339 ASSERT_TRUE(matchBufferContent(bufmgr.access(gen.bufmgr_key), "34567qwertyuabcd")); 00340 ASSERT_EQ(0x3231, rcv.getLastTransferCrc()); 00341 ASSERT_EQ(timestamp, rcv.getLastTransferTimestampMonotonic().toUSec()); 00342 00343 timestamp += uint64_t(INTERVAL); 00344 tid.increment(); 00345 } 00346 00347 ASSERT_EQ(INTERVAL, rcv.getInterval().toUSec()); 00348 } 00349 00350 00351 TEST(TransferReceiver, Restart) 00352 { 00353 Context<32> context; 00354 RxFrameGenerator gen(789); 00355 uavcan::TransferReceiver& rcv = context.receiver; 00356 uavcan::TransferBufferManager& bufmgr = context.bufmgr; 00357 uavcan::TransferBufferAccessor bk(context.bufmgr, RxFrameGenerator::DEFAULT_KEY); 00358 00359 /* 00360 * This transfer looks complete, but must be ignored because of large delay after the first frame 00361 * Args: iface_index, data, set, transfer_id, ts_monotonic [, ts_utc] 00362 */ 00363 CHECK_NOT_COMPLETE(rcv.addFrame(gen(0, "-------", SET100, 0, 100), bk)); // Begin 00364 CHECK_NOT_COMPLETE(rcv.addFrame(gen(0, "-------", SET001, 0, 100000100), bk)); // Continue 100 sec later, expired 00365 CHECK_NOT_COMPLETE(rcv.addFrame(gen(0, "-------", SET010, 0, 100000200), bk)); // Ignored 00366 00367 /* 00368 * Begins immediately after, encounters a delay 0.9 sec but completes OK 00369 */ 00370 CHECK_NOT_COMPLETE(rcv.addFrame(gen(1, "1234567", SET100, 0, 100000300), bk)); // Begin 00371 CHECK_NOT_COMPLETE(rcv.addFrame(gen(1, "1234567", SET001, 0, 100900300), bk)); // 0.9 sec later 00372 CHECK_COMPLETE( rcv.addFrame(gen(1, "1234567", SET010, 0, 100900400), bk)); // OK nevertheless 00373 00374 ASSERT_TRUE(matchBufferContent(bufmgr.access(gen.bufmgr_key), "3456712345671234567")); 00375 ASSERT_EQ(0x3231, rcv.getLastTransferCrc()); 00376 00377 std::cout << "Interval: " << rcv.getInterval().toString() << std::endl; 00378 00379 /* 00380 * Begins OK, gets a timeout, switches to another iface 00381 */ 00382 CHECK_NOT_COMPLETE(rcv.addFrame(gen(1, "-------", SET100, 1, 103000500), bk)); // Begin 00383 CHECK_NOT_COMPLETE(rcv.addFrame(gen(1, "-------", SET001, 1, 105000500), bk)); // 2 sec later, timeout 00384 CHECK_NOT_COMPLETE(rcv.addFrame(gen(0, "-------", SET001, 1, 105000600), bk)); // Same TID, another iface - ignore 00385 CHECK_NOT_COMPLETE(rcv.addFrame(gen(0, "-------", SET001, 2, 105000700), bk)); // Not first frame - ignore 00386 CHECK_NOT_COMPLETE(rcv.addFrame(gen(0, "1234567", SET100, 2, 105000800), bk)); // First, another iface - restart 00387 CHECK_NOT_COMPLETE(rcv.addFrame(gen(1, "-------", SET010, 1, 105000600), bk)); // Old iface - ignore 00388 CHECK_NOT_COMPLETE(rcv.addFrame(gen(0, "1234567", SET001, 2, 105000900), bk)); // Continuing 00389 CHECK_COMPLETE( rcv.addFrame(gen(0, "1234567", SET010, 2, 105000910), bk)); // Done 00390 00391 ASSERT_TRUE(matchBufferContent(bufmgr.access(gen.bufmgr_key), "3456712345671234567")); 00392 ASSERT_EQ(0x3231, rcv.getLastTransferCrc()); 00393 00394 ASSERT_EQ(4, rcv.yieldErrorCount()); 00395 ASSERT_EQ(0, rcv.yieldErrorCount()); 00396 } 00397 00398 00399 TEST(TransferReceiver, UtcTransferTimestamping) 00400 { 00401 Context<32> context; 00402 RxFrameGenerator gen(789); 00403 uavcan::TransferReceiver& rcv = context.receiver; 00404 uavcan::TransferBufferManager& bufmgr = context.bufmgr; 00405 uavcan::TransferBufferAccessor bk(context.bufmgr, RxFrameGenerator::DEFAULT_KEY); 00406 00407 /* 00408 * Zero UTC timestamp must be preserved 00409 */ 00410 CHECK_NOT_COMPLETE(rcv.addFrame(gen(1, "1234567", SET100, 0, 1, 0), bk)); 00411 CHECK_NOT_COMPLETE(rcv.addFrame(gen(1, "qwertyu", SET001, 0, 2, 0), bk)); 00412 CHECK_COMPLETE( rcv.addFrame(gen(1, "abcd", SET010, 0, 3, 0), bk)); 00413 00414 ASSERT_TRUE(matchBufferContent(bufmgr.access(gen.bufmgr_key), "34567qwertyuabcd")); 00415 ASSERT_EQ(1, rcv.getLastTransferTimestampMonotonic().toUSec()); 00416 ASSERT_EQ(0, rcv.getLastTransferTimestampUtc().toUSec()); 00417 00418 /* 00419 * Non-zero UTC timestamp 00420 */ 00421 CHECK_NOT_COMPLETE(rcv.addFrame(gen(1, "1234567", SET100, 1, 4, 123), bk)); // This UTC is going to be preserved 00422 CHECK_NOT_COMPLETE(rcv.addFrame(gen(1, "qwertyu", SET001, 1, 5, 0), bk)); // Following are ignored 00423 CHECK_COMPLETE( rcv.addFrame(gen(1, "abcd", SET010, 1, 6, 42), bk)); 00424 00425 ASSERT_TRUE(matchBufferContent(bufmgr.access(gen.bufmgr_key), "34567qwertyuabcd")); 00426 ASSERT_EQ(4, rcv.getLastTransferTimestampMonotonic().toUSec()); 00427 ASSERT_EQ(123, rcv.getLastTransferTimestampUtc().toUSec()); 00428 00429 /* 00430 * Single-frame transfers 00431 * iface_index, data, set, transfer_id, ts_monotonic 00432 */ 00433 CHECK_SINGLE_FRAME(rcv.addFrame(gen(1, "abc", SET110, 2, 10, 100000000), bk)); // Exact value is irrelevant 00434 ASSERT_EQ(10, rcv.getLastTransferTimestampMonotonic().toUSec()); 00435 ASSERT_EQ(100000000, rcv.getLastTransferTimestampUtc().toUSec()); 00436 00437 /* 00438 * Restart recovery 00439 */ 00440 CHECK_NOT_COMPLETE(rcv.addFrame(gen(0, "1234567", SET100, 1, 100000000, 800000000), bk)); 00441 CHECK_NOT_COMPLETE(rcv.addFrame(gen(0, "qwertyu", SET001, 1, 100000001, 300000000), bk)); 00442 CHECK_COMPLETE( rcv.addFrame(gen(0, "abcd", SET010, 1, 100000002, 900000000), bk)); 00443 00444 ASSERT_TRUE(matchBufferContent(bufmgr.access(gen.bufmgr_key), "34567qwertyuabcd")); 00445 ASSERT_EQ(100000000, rcv.getLastTransferTimestampMonotonic().toUSec()); 00446 ASSERT_EQ(800000000, rcv.getLastTransferTimestampUtc().toUSec()); 00447 } 00448 00449 00450 TEST(TransferReceiver, HeaderParsing) 00451 { 00452 static const std::string SFT_PAYLOAD = "1234567"; 00453 00454 uavcan::TransferID tid; 00455 00456 /* 00457 * Broadcast 00458 */ 00459 { 00460 Context<32> context; 00461 RxFrameGenerator gen(123); 00462 uavcan::TransferReceiver& rcv = context.receiver; 00463 uavcan::TransferBufferManager& bufmgr = context.bufmgr; 00464 00465 /* 00466 * MFT, message broadcasting 00467 */ 00468 { 00469 gen.bufmgr_key = 00470 uavcan::TransferBufferManagerKey(gen.bufmgr_key.getNodeID(), uavcan::TransferTypeMessageBroadcast); 00471 uavcan::TransferBufferAccessor bk1(context.bufmgr, gen.bufmgr_key); 00472 00473 CHECK_NOT_COMPLETE(rcv.addFrame(gen(0, "1234567", SET100, tid.get(), 1), bk1)); 00474 CHECK_COMPLETE( rcv.addFrame(gen(0, "abcd", SET011, tid.get(), 2), bk1)); 00475 00476 ASSERT_TRUE(matchBufferContent(bufmgr.access(gen.bufmgr_key), "34567abcd")); 00477 ASSERT_EQ(0x3231, rcv.getLastTransferCrc()); 00478 00479 tid.increment(); 00480 bk1.remove(); 00481 } 00482 00483 /* 00484 * SFT, message broadcasting 00485 */ 00486 { 00487 gen.bufmgr_key = 00488 uavcan::TransferBufferManagerKey(gen.bufmgr_key.getNodeID(), uavcan::TransferTypeMessageBroadcast); 00489 uavcan::TransferBufferAccessor bk(context.bufmgr, gen.bufmgr_key); 00490 00491 const uavcan::RxFrame frame = gen(0, SFT_PAYLOAD, SET110, tid.get(), 1000); 00492 00493 CHECK_SINGLE_FRAME(rcv.addFrame(frame, bk)); 00494 ASSERT_EQ(0x0000, rcv.getLastTransferCrc()); // Default value - zero 00495 00496 // All bytes are payload, zero overhead 00497 ASSERT_TRUE(std::equal(SFT_PAYLOAD.begin(), SFT_PAYLOAD.end(), frame.getPayloadPtr())); 00498 00499 tid.increment(); 00500 } 00501 } 00502 00503 /* 00504 * Unicast 00505 */ 00506 { 00507 Context<32> context; 00508 RxFrameGenerator gen(123); 00509 uavcan::TransferReceiver& rcv = context.receiver; 00510 uavcan::TransferBufferManager& bufmgr = context.bufmgr; 00511 00512 static const uavcan::TransferType ADDRESSED_TRANSFER_TYPES[2] = 00513 { 00514 uavcan::TransferTypeServiceRequest, 00515 uavcan::TransferTypeServiceResponse 00516 }; 00517 00518 /* 00519 * MFT, service request/response 00520 */ 00521 for (unsigned i = 0; i < (sizeof(ADDRESSED_TRANSFER_TYPES) / sizeof(ADDRESSED_TRANSFER_TYPES[0])); i++) 00522 { 00523 gen.bufmgr_key = 00524 uavcan::TransferBufferManagerKey(gen.bufmgr_key.getNodeID(), ADDRESSED_TRANSFER_TYPES[i]); 00525 uavcan::TransferBufferAccessor bk2(context.bufmgr, gen.bufmgr_key); 00526 00527 const uint64_t ts_monotonic = i + 10; 00528 00529 CHECK_NOT_COMPLETE(rcv.addFrame(gen(0, "1234567", SET100, tid.get(), ts_monotonic), bk2)); 00530 CHECK_COMPLETE( rcv.addFrame(gen(0, "abcd", SET011, tid.get(), ts_monotonic), bk2)); 00531 00532 ASSERT_TRUE(matchBufferContent(bufmgr.access(gen.bufmgr_key), "34567abcd")); 00533 ASSERT_EQ(0x3231, rcv.getLastTransferCrc()); 00534 00535 tid.increment(); 00536 bk2.remove(); 00537 } 00538 00539 /* 00540 * SFT, message unicast, service request/response 00541 */ 00542 for (unsigned i = 0; i < int(sizeof(ADDRESSED_TRANSFER_TYPES) / sizeof(ADDRESSED_TRANSFER_TYPES[0])); i++) 00543 { 00544 gen.bufmgr_key = 00545 uavcan::TransferBufferManagerKey(gen.bufmgr_key.getNodeID(), ADDRESSED_TRANSFER_TYPES[i]); 00546 uavcan::TransferBufferAccessor bk(context.bufmgr, gen.bufmgr_key); 00547 00548 const uavcan::RxFrame frame = gen(0, SFT_PAYLOAD, SET110, tid.get(), i + 10000U); 00549 00550 CHECK_SINGLE_FRAME(rcv.addFrame(frame, bk)); 00551 ASSERT_EQ(0x0000, rcv.getLastTransferCrc()); // Default value - zero 00552 00553 // First byte must be ignored 00554 ASSERT_TRUE(std::equal(SFT_PAYLOAD.begin(), SFT_PAYLOAD.end(), frame.getPayloadPtr())); 00555 00556 tid.increment(); 00557 } 00558 } 00559 00560 00561 }
Generated on Tue Jul 12 2022 17:17:35 by 1.7.2