Руслан Урядинский / libuavcan

Dependents:   UAVCAN UAVCAN_Subscriber

Committer:
RuslanUrya
Date:
Sat Apr 14 10:25:32 2018 +0000
Revision:
0:dfe6edabb8ec
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
RuslanUrya 0:dfe6edabb8ec 1 /*
RuslanUrya 0:dfe6edabb8ec 2 * Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com>
RuslanUrya 0:dfe6edabb8ec 3 */
RuslanUrya 0:dfe6edabb8ec 4
RuslanUrya 0:dfe6edabb8ec 5 #include <iostream>
RuslanUrya 0:dfe6edabb8ec 6 #include <vector>
RuslanUrya 0:dfe6edabb8ec 7 #include <cerrno>
RuslanUrya 0:dfe6edabb8ec 8 #include <uavcan_linux/uavcan_linux.hpp>
RuslanUrya 0:dfe6edabb8ec 9 #include "debug.hpp"
RuslanUrya 0:dfe6edabb8ec 10
RuslanUrya 0:dfe6edabb8ec 11 static uavcan::CanFrame makeFrame(std::uint32_t id, const std::string& data)
RuslanUrya 0:dfe6edabb8ec 12 {
RuslanUrya 0:dfe6edabb8ec 13 return uavcan::CanFrame(id, reinterpret_cast<const std::uint8_t*>(data.c_str()), data.length());
RuslanUrya 0:dfe6edabb8ec 14 }
RuslanUrya 0:dfe6edabb8ec 15
RuslanUrya 0:dfe6edabb8ec 16 static uavcan::MonotonicTime tsMonoOffsetMs(std::int64_t ms)
RuslanUrya 0:dfe6edabb8ec 17 {
RuslanUrya 0:dfe6edabb8ec 18 return uavcan_linux::SystemClock().getMonotonic() + uavcan::MonotonicDuration::fromMSec(ms);
RuslanUrya 0:dfe6edabb8ec 19 }
RuslanUrya 0:dfe6edabb8ec 20
RuslanUrya 0:dfe6edabb8ec 21 static void testNonexistentIface()
RuslanUrya 0:dfe6edabb8ec 22 {
RuslanUrya 0:dfe6edabb8ec 23 const int sock1 = uavcan_linux::SocketCanIface::openSocket("noif9");
RuslanUrya 0:dfe6edabb8ec 24 ENFORCE(sock1 < 0);
RuslanUrya 0:dfe6edabb8ec 25 const int sock2 = uavcan_linux::SocketCanIface::openSocket("verylongifacenameverylongifacenameverylongifacename");
RuslanUrya 0:dfe6edabb8ec 26 ENFORCE(sock2 < 0);
RuslanUrya 0:dfe6edabb8ec 27 }
RuslanUrya 0:dfe6edabb8ec 28
RuslanUrya 0:dfe6edabb8ec 29 static void testSocketRxTx(const std::string& iface_name)
RuslanUrya 0:dfe6edabb8ec 30 {
RuslanUrya 0:dfe6edabb8ec 31 const int sock1 = uavcan_linux::SocketCanIface::openSocket(iface_name);
RuslanUrya 0:dfe6edabb8ec 32 const int sock2 = uavcan_linux::SocketCanIface::openSocket(iface_name);
RuslanUrya 0:dfe6edabb8ec 33 ENFORCE(sock1 >= 0 && sock2 >= 0);
RuslanUrya 0:dfe6edabb8ec 34
RuslanUrya 0:dfe6edabb8ec 35 /*
RuslanUrya 0:dfe6edabb8ec 36 * Clocks will have some offset from the true system time
RuslanUrya 0:dfe6edabb8ec 37 * SocketCAN driver must handle this correctly
RuslanUrya 0:dfe6edabb8ec 38 */
RuslanUrya 0:dfe6edabb8ec 39 uavcan_linux::SystemClock clock_impl(uavcan_linux::ClockAdjustmentMode::PerDriverPrivate);
RuslanUrya 0:dfe6edabb8ec 40 clock_impl.adjustUtc(uavcan::UtcDuration::fromMSec(100000));
RuslanUrya 0:dfe6edabb8ec 41 const uavcan_linux::SystemClock& clock = clock_impl;
RuslanUrya 0:dfe6edabb8ec 42
RuslanUrya 0:dfe6edabb8ec 43 uavcan_linux::SocketCanIface if1(clock, sock1);
RuslanUrya 0:dfe6edabb8ec 44 uavcan_linux::SocketCanIface if2(clock, sock2);
RuslanUrya 0:dfe6edabb8ec 45
RuslanUrya 0:dfe6edabb8ec 46 /*
RuslanUrya 0:dfe6edabb8ec 47 * Sending two frames, one of which must be returned back
RuslanUrya 0:dfe6edabb8ec 48 */
RuslanUrya 0:dfe6edabb8ec 49 ENFORCE(1 == if1.send(makeFrame(123, "if1-1"), tsMonoOffsetMs(100), 0));
RuslanUrya 0:dfe6edabb8ec 50 ENFORCE(1 == if1.send(makeFrame(456, "if1-2"), tsMonoOffsetMs(100), uavcan::CanIOFlagLoopback));
RuslanUrya 0:dfe6edabb8ec 51 if1.poll(true, true);
RuslanUrya 0:dfe6edabb8ec 52 if1.poll(true, true);
RuslanUrya 0:dfe6edabb8ec 53 ENFORCE(0 == if1.getErrorCount());
RuslanUrya 0:dfe6edabb8ec 54 ENFORCE(!if1.hasReadyTx());
RuslanUrya 0:dfe6edabb8ec 55 ENFORCE(if1.hasReadyRx()); // Second loopback
RuslanUrya 0:dfe6edabb8ec 56
RuslanUrya 0:dfe6edabb8ec 57 /*
RuslanUrya 0:dfe6edabb8ec 58 * Second iface, same thing
RuslanUrya 0:dfe6edabb8ec 59 */
RuslanUrya 0:dfe6edabb8ec 60 ENFORCE(1 == if2.send(makeFrame(321, "if2-1"), tsMonoOffsetMs(100), 0));
RuslanUrya 0:dfe6edabb8ec 61 ENFORCE(1 == if2.send(makeFrame(654, "if2-2"), tsMonoOffsetMs(100), uavcan::CanIOFlagLoopback));
RuslanUrya 0:dfe6edabb8ec 62 ENFORCE(1 == if2.send(makeFrame(1, "discard"), tsMonoOffsetMs(-1), uavcan::CanIOFlagLoopback)); // Will timeout
RuslanUrya 0:dfe6edabb8ec 63 if2.poll(true, true);
RuslanUrya 0:dfe6edabb8ec 64 if2.poll(true, true);
RuslanUrya 0:dfe6edabb8ec 65 ENFORCE(1 == if2.getErrorCount()); // One timed out
RuslanUrya 0:dfe6edabb8ec 66 ENFORCE(!if2.hasReadyTx());
RuslanUrya 0:dfe6edabb8ec 67 ENFORCE(if2.hasReadyRx());
RuslanUrya 0:dfe6edabb8ec 68
RuslanUrya 0:dfe6edabb8ec 69 /*
RuslanUrya 0:dfe6edabb8ec 70 * No-op
RuslanUrya 0:dfe6edabb8ec 71 */
RuslanUrya 0:dfe6edabb8ec 72 if1.poll(true, true);
RuslanUrya 0:dfe6edabb8ec 73 if2.poll(true, true);
RuslanUrya 0:dfe6edabb8ec 74
RuslanUrya 0:dfe6edabb8ec 75 uavcan::CanFrame frame;
RuslanUrya 0:dfe6edabb8ec 76 uavcan::MonotonicTime ts_mono;
RuslanUrya 0:dfe6edabb8ec 77 uavcan::UtcTime ts_utc;
RuslanUrya 0:dfe6edabb8ec 78 uavcan::CanIOFlags flags = 0;
RuslanUrya 0:dfe6edabb8ec 79
RuslanUrya 0:dfe6edabb8ec 80 /*
RuslanUrya 0:dfe6edabb8ec 81 * Read first
RuslanUrya 0:dfe6edabb8ec 82 */
RuslanUrya 0:dfe6edabb8ec 83 ENFORCE(1 == if1.receive(frame, ts_mono, ts_utc, flags));
RuslanUrya 0:dfe6edabb8ec 84 ENFORCE(frame == makeFrame(456, "if1-2"));
RuslanUrya 0:dfe6edabb8ec 85 ENFORCE(flags == uavcan::CanIOFlagLoopback);
RuslanUrya 0:dfe6edabb8ec 86 ENFORCE((clock.getMonotonic() - ts_mono).getAbs().toMSec() < 10);
RuslanUrya 0:dfe6edabb8ec 87 ENFORCE((clock.getUtc() - ts_utc).getAbs().toMSec() < 10);
RuslanUrya 0:dfe6edabb8ec 88
RuslanUrya 0:dfe6edabb8ec 89 ENFORCE(1 == if1.receive(frame, ts_mono, ts_utc, flags));
RuslanUrya 0:dfe6edabb8ec 90 ENFORCE(frame == makeFrame(321, "if2-1"));
RuslanUrya 0:dfe6edabb8ec 91 ENFORCE(flags == 0);
RuslanUrya 0:dfe6edabb8ec 92 ENFORCE(!ts_mono.isZero());
RuslanUrya 0:dfe6edabb8ec 93 ENFORCE(!ts_utc.isZero());
RuslanUrya 0:dfe6edabb8ec 94 ENFORCE((clock.getMonotonic() - ts_mono).getAbs().toMSec() < 10);
RuslanUrya 0:dfe6edabb8ec 95 ENFORCE((clock.getUtc() - ts_utc).getAbs().toMSec() < 10);
RuslanUrya 0:dfe6edabb8ec 96
RuslanUrya 0:dfe6edabb8ec 97 ENFORCE(1 == if1.receive(frame, ts_mono, ts_utc, flags));
RuslanUrya 0:dfe6edabb8ec 98 ENFORCE(frame == makeFrame(654, "if2-2"));
RuslanUrya 0:dfe6edabb8ec 99 ENFORCE(flags == 0);
RuslanUrya 0:dfe6edabb8ec 100 ENFORCE((clock.getMonotonic() - ts_mono).getAbs().toMSec() < 10);
RuslanUrya 0:dfe6edabb8ec 101 ENFORCE((clock.getUtc() - ts_utc).getAbs().toMSec() < 10);
RuslanUrya 0:dfe6edabb8ec 102
RuslanUrya 0:dfe6edabb8ec 103 ENFORCE(0 == if1.receive(frame, ts_mono, ts_utc, flags));
RuslanUrya 0:dfe6edabb8ec 104 ENFORCE(!if1.hasReadyTx());
RuslanUrya 0:dfe6edabb8ec 105 ENFORCE(!if1.hasReadyRx());
RuslanUrya 0:dfe6edabb8ec 106
RuslanUrya 0:dfe6edabb8ec 107 /*
RuslanUrya 0:dfe6edabb8ec 108 * Read second
RuslanUrya 0:dfe6edabb8ec 109 */
RuslanUrya 0:dfe6edabb8ec 110 ENFORCE(1 == if2.receive(frame, ts_mono, ts_utc, flags));
RuslanUrya 0:dfe6edabb8ec 111 ENFORCE(frame == makeFrame(123, "if1-1"));
RuslanUrya 0:dfe6edabb8ec 112 ENFORCE(flags == 0);
RuslanUrya 0:dfe6edabb8ec 113 ENFORCE((clock.getMonotonic() - ts_mono).getAbs().toMSec() < 10);
RuslanUrya 0:dfe6edabb8ec 114 ENFORCE((clock.getUtc() - ts_utc).getAbs().toMSec() < 10);
RuslanUrya 0:dfe6edabb8ec 115
RuslanUrya 0:dfe6edabb8ec 116 ENFORCE(1 == if2.receive(frame, ts_mono, ts_utc, flags));
RuslanUrya 0:dfe6edabb8ec 117 ENFORCE(frame == makeFrame(456, "if1-2"));
RuslanUrya 0:dfe6edabb8ec 118 ENFORCE(flags == 0);
RuslanUrya 0:dfe6edabb8ec 119 ENFORCE((clock.getMonotonic() - ts_mono).getAbs().toMSec() < 10);
RuslanUrya 0:dfe6edabb8ec 120 ENFORCE((clock.getUtc() - ts_utc).getAbs().toMSec() < 10);
RuslanUrya 0:dfe6edabb8ec 121
RuslanUrya 0:dfe6edabb8ec 122 ENFORCE(1 == if2.receive(frame, ts_mono, ts_utc, flags));
RuslanUrya 0:dfe6edabb8ec 123 ENFORCE(frame == makeFrame(654, "if2-2"));
RuslanUrya 0:dfe6edabb8ec 124 ENFORCE(flags == uavcan::CanIOFlagLoopback);
RuslanUrya 0:dfe6edabb8ec 125 ENFORCE((clock.getMonotonic() - ts_mono).getAbs().toMSec() < 10);
RuslanUrya 0:dfe6edabb8ec 126 ENFORCE((clock.getUtc() - ts_utc).getAbs().toMSec() < 10);
RuslanUrya 0:dfe6edabb8ec 127
RuslanUrya 0:dfe6edabb8ec 128 ENFORCE(0 == if2.receive(frame, ts_mono, ts_utc, flags));
RuslanUrya 0:dfe6edabb8ec 129 ENFORCE(!if2.hasReadyTx());
RuslanUrya 0:dfe6edabb8ec 130 ENFORCE(!if2.hasReadyRx());
RuslanUrya 0:dfe6edabb8ec 131 }
RuslanUrya 0:dfe6edabb8ec 132
RuslanUrya 0:dfe6edabb8ec 133 static void testSocketFilters(const std::string& iface_name)
RuslanUrya 0:dfe6edabb8ec 134 {
RuslanUrya 0:dfe6edabb8ec 135 using uavcan::CanFrame;
RuslanUrya 0:dfe6edabb8ec 136
RuslanUrya 0:dfe6edabb8ec 137 const int sock1 = uavcan_linux::SocketCanIface::openSocket(iface_name);
RuslanUrya 0:dfe6edabb8ec 138 const int sock2 = uavcan_linux::SocketCanIface::openSocket(iface_name);
RuslanUrya 0:dfe6edabb8ec 139 ENFORCE(sock1 >= 0 && sock2 >= 0);
RuslanUrya 0:dfe6edabb8ec 140
RuslanUrya 0:dfe6edabb8ec 141 /*
RuslanUrya 0:dfe6edabb8ec 142 * Clocks will have some offset from the true system time
RuslanUrya 0:dfe6edabb8ec 143 * SocketCAN driver must handle this correctly
RuslanUrya 0:dfe6edabb8ec 144 */
RuslanUrya 0:dfe6edabb8ec 145 uavcan_linux::SystemClock clock_impl(uavcan_linux::ClockAdjustmentMode::PerDriverPrivate);
RuslanUrya 0:dfe6edabb8ec 146 clock_impl.adjustUtc(uavcan::UtcDuration::fromMSec(-1000));
RuslanUrya 0:dfe6edabb8ec 147 const uavcan_linux::SystemClock& clock = clock_impl;
RuslanUrya 0:dfe6edabb8ec 148
RuslanUrya 0:dfe6edabb8ec 149 uavcan_linux::SocketCanIface if1(clock, sock1);
RuslanUrya 0:dfe6edabb8ec 150 uavcan_linux::SocketCanIface if2(clock, sock2);
RuslanUrya 0:dfe6edabb8ec 151
RuslanUrya 0:dfe6edabb8ec 152 /*
RuslanUrya 0:dfe6edabb8ec 153 * Configuring filters
RuslanUrya 0:dfe6edabb8ec 154 */
RuslanUrya 0:dfe6edabb8ec 155 uavcan::CanFilterConfig fcs[3];
RuslanUrya 0:dfe6edabb8ec 156 // STD/EXT 123
RuslanUrya 0:dfe6edabb8ec 157 fcs[0].id = 123;
RuslanUrya 0:dfe6edabb8ec 158 fcs[0].mask = CanFrame::MaskExtID;
RuslanUrya 0:dfe6edabb8ec 159 // Only EXT 456789
RuslanUrya 0:dfe6edabb8ec 160 fcs[1].id = 456789 | CanFrame::FlagEFF;
RuslanUrya 0:dfe6edabb8ec 161 fcs[1].mask = CanFrame::MaskExtID | CanFrame::FlagEFF;
RuslanUrya 0:dfe6edabb8ec 162 // Only STD 0
RuslanUrya 0:dfe6edabb8ec 163 fcs[2].id = 0;
RuslanUrya 0:dfe6edabb8ec 164 fcs[2].mask = CanFrame::MaskExtID | CanFrame::FlagEFF;
RuslanUrya 0:dfe6edabb8ec 165
RuslanUrya 0:dfe6edabb8ec 166 ENFORCE(0 == if2.configureFilters(fcs, 3));
RuslanUrya 0:dfe6edabb8ec 167
RuslanUrya 0:dfe6edabb8ec 168 /*
RuslanUrya 0:dfe6edabb8ec 169 * Sending data from 1 to 2, making sure only filtered data will be accepted
RuslanUrya 0:dfe6edabb8ec 170 */
RuslanUrya 0:dfe6edabb8ec 171 const auto EFF = CanFrame::FlagEFF;
RuslanUrya 0:dfe6edabb8ec 172 ENFORCE(1 == if1.send(makeFrame(123, "1"), tsMonoOffsetMs(100), 0)); // Accept 0
RuslanUrya 0:dfe6edabb8ec 173 ENFORCE(1 == if1.send(makeFrame(123 | EFF, "2"), tsMonoOffsetMs(100), 0)); // Accept 0
RuslanUrya 0:dfe6edabb8ec 174 ENFORCE(1 == if1.send(makeFrame(456, "3"), tsMonoOffsetMs(100), 0)); // Drop
RuslanUrya 0:dfe6edabb8ec 175 ENFORCE(1 == if1.send(makeFrame(456789, "4"), tsMonoOffsetMs(100), 0)); // Drop
RuslanUrya 0:dfe6edabb8ec 176 ENFORCE(1 == if1.send(makeFrame(456789 | EFF, "5"), tsMonoOffsetMs(100), 0)); // Accept 1
RuslanUrya 0:dfe6edabb8ec 177 ENFORCE(1 == if1.send(makeFrame(0, "6"), tsMonoOffsetMs(100), 0)); // Accept 2
RuslanUrya 0:dfe6edabb8ec 178 ENFORCE(1 == if1.send(makeFrame(EFF, "7"), tsMonoOffsetMs(100), 0)); // Drop
RuslanUrya 0:dfe6edabb8ec 179
RuslanUrya 0:dfe6edabb8ec 180 for (int i = 0; i < 7; i++)
RuslanUrya 0:dfe6edabb8ec 181 {
RuslanUrya 0:dfe6edabb8ec 182 if1.poll(true, true);
RuslanUrya 0:dfe6edabb8ec 183 if2.poll(true, false);
RuslanUrya 0:dfe6edabb8ec 184 }
RuslanUrya 0:dfe6edabb8ec 185 ENFORCE(!if1.hasReadyTx());
RuslanUrya 0:dfe6edabb8ec 186 ENFORCE(!if1.hasReadyRx());
RuslanUrya 0:dfe6edabb8ec 187 ENFORCE(0 == if1.getErrorCount());
RuslanUrya 0:dfe6edabb8ec 188 ENFORCE(if2.hasReadyRx());
RuslanUrya 0:dfe6edabb8ec 189
RuslanUrya 0:dfe6edabb8ec 190 /*
RuslanUrya 0:dfe6edabb8ec 191 * Checking RX on 2
RuslanUrya 0:dfe6edabb8ec 192 */
RuslanUrya 0:dfe6edabb8ec 193 uavcan::CanFrame frame;
RuslanUrya 0:dfe6edabb8ec 194 uavcan::MonotonicTime ts_mono;
RuslanUrya 0:dfe6edabb8ec 195 uavcan::UtcTime ts_utc;
RuslanUrya 0:dfe6edabb8ec 196 uavcan::CanIOFlags flags = 0;
RuslanUrya 0:dfe6edabb8ec 197
RuslanUrya 0:dfe6edabb8ec 198 ENFORCE(1 == if2.receive(frame, ts_mono, ts_utc, flags));
RuslanUrya 0:dfe6edabb8ec 199 ENFORCE(frame == makeFrame(123, "1"));
RuslanUrya 0:dfe6edabb8ec 200
RuslanUrya 0:dfe6edabb8ec 201 ENFORCE(1 == if2.receive(frame, ts_mono, ts_utc, flags));
RuslanUrya 0:dfe6edabb8ec 202 ENFORCE(frame == makeFrame(123 | EFF, "2"));
RuslanUrya 0:dfe6edabb8ec 203
RuslanUrya 0:dfe6edabb8ec 204 ENFORCE(1 == if2.receive(frame, ts_mono, ts_utc, flags));
RuslanUrya 0:dfe6edabb8ec 205 ENFORCE(frame == makeFrame(456789 | EFF, "5"));
RuslanUrya 0:dfe6edabb8ec 206
RuslanUrya 0:dfe6edabb8ec 207 ENFORCE(1 == if2.receive(frame, ts_mono, ts_utc, flags));
RuslanUrya 0:dfe6edabb8ec 208 ENFORCE(frame == makeFrame(0, "6"));
RuslanUrya 0:dfe6edabb8ec 209 ENFORCE(flags == 0);
RuslanUrya 0:dfe6edabb8ec 210
RuslanUrya 0:dfe6edabb8ec 211 ENFORCE(!if2.hasReadyRx());
RuslanUrya 0:dfe6edabb8ec 212 }
RuslanUrya 0:dfe6edabb8ec 213
RuslanUrya 0:dfe6edabb8ec 214 static void testDriver(const std::vector<std::string>& iface_names)
RuslanUrya 0:dfe6edabb8ec 215 {
RuslanUrya 0:dfe6edabb8ec 216 /*
RuslanUrya 0:dfe6edabb8ec 217 * Clocks will have some offset from the true system time
RuslanUrya 0:dfe6edabb8ec 218 * SocketCAN driver must handle this correctly
RuslanUrya 0:dfe6edabb8ec 219 */
RuslanUrya 0:dfe6edabb8ec 220 uavcan_linux::SystemClock clock_impl(uavcan_linux::ClockAdjustmentMode::PerDriverPrivate);
RuslanUrya 0:dfe6edabb8ec 221 clock_impl.adjustUtc(uavcan::UtcDuration::fromMSec(9000000));
RuslanUrya 0:dfe6edabb8ec 222 const uavcan_linux::SystemClock& clock = clock_impl;
RuslanUrya 0:dfe6edabb8ec 223
RuslanUrya 0:dfe6edabb8ec 224 uavcan_linux::SocketCanDriver driver(clock);
RuslanUrya 0:dfe6edabb8ec 225 for (auto ifn : iface_names)
RuslanUrya 0:dfe6edabb8ec 226 {
RuslanUrya 0:dfe6edabb8ec 227 std::cout << "Adding iface " << ifn << std::endl;
RuslanUrya 0:dfe6edabb8ec 228 ENFORCE(0 == driver.addIface(ifn));
RuslanUrya 0:dfe6edabb8ec 229 }
RuslanUrya 0:dfe6edabb8ec 230
RuslanUrya 0:dfe6edabb8ec 231 ENFORCE(-1 == driver.addIface("noif9"));
RuslanUrya 0:dfe6edabb8ec 232 ENFORCE(-1 == driver.addIface("noif9"));
RuslanUrya 0:dfe6edabb8ec 233 ENFORCE(-1 == driver.addIface("noif9"));
RuslanUrya 0:dfe6edabb8ec 234
RuslanUrya 0:dfe6edabb8ec 235 ENFORCE(driver.getNumIfaces() == iface_names.size());
RuslanUrya 0:dfe6edabb8ec 236 ENFORCE(nullptr == driver.getIface(255));
RuslanUrya 0:dfe6edabb8ec 237 ENFORCE(nullptr == driver.getIface(driver.getNumIfaces()));
RuslanUrya 0:dfe6edabb8ec 238
RuslanUrya 0:dfe6edabb8ec 239 const uavcan::CanFrame* pending_tx[uavcan::MaxCanIfaces] = {};
RuslanUrya 0:dfe6edabb8ec 240
RuslanUrya 0:dfe6edabb8ec 241 const unsigned AllIfacesMask = (1 << driver.getNumIfaces()) - 1;
RuslanUrya 0:dfe6edabb8ec 242
RuslanUrya 0:dfe6edabb8ec 243 /*
RuslanUrya 0:dfe6edabb8ec 244 * Send, no loopback
RuslanUrya 0:dfe6edabb8ec 245 */
RuslanUrya 0:dfe6edabb8ec 246 std::cout << "select() 1" << std::endl;
RuslanUrya 0:dfe6edabb8ec 247 uavcan::CanSelectMasks masks; // Driver provides masks for all available events
RuslanUrya 0:dfe6edabb8ec 248 ENFORCE(driver.getNumIfaces() == driver.select(masks, pending_tx, tsMonoOffsetMs(1000)));
RuslanUrya 0:dfe6edabb8ec 249 ENFORCE(masks.read == 0);
RuslanUrya 0:dfe6edabb8ec 250 ENFORCE(masks.write == AllIfacesMask);
RuslanUrya 0:dfe6edabb8ec 251
RuslanUrya 0:dfe6edabb8ec 252 for (int i = 0; i < driver.getNumIfaces(); i++)
RuslanUrya 0:dfe6edabb8ec 253 {
RuslanUrya 0:dfe6edabb8ec 254 ENFORCE(1 == driver.getIface(i)->send(makeFrame(123, std::to_string(i)), tsMonoOffsetMs(10), 0));
RuslanUrya 0:dfe6edabb8ec 255 }
RuslanUrya 0:dfe6edabb8ec 256
RuslanUrya 0:dfe6edabb8ec 257 std::cout << "select() 2" << std::endl;
RuslanUrya 0:dfe6edabb8ec 258 ENFORCE(driver.getNumIfaces() == driver.select(masks, pending_tx, tsMonoOffsetMs(1000)));
RuslanUrya 0:dfe6edabb8ec 259 ENFORCE(masks.read == 0);
RuslanUrya 0:dfe6edabb8ec 260 ENFORCE(masks.write == AllIfacesMask);
RuslanUrya 0:dfe6edabb8ec 261
RuslanUrya 0:dfe6edabb8ec 262 /*
RuslanUrya 0:dfe6edabb8ec 263 * Send with loopback
RuslanUrya 0:dfe6edabb8ec 264 */
RuslanUrya 0:dfe6edabb8ec 265 for (int i = 0; i < driver.getNumIfaces(); i++)
RuslanUrya 0:dfe6edabb8ec 266 {
RuslanUrya 0:dfe6edabb8ec 267 ENFORCE(1 == driver.getIface(i)->send(makeFrame(456, std::to_string(i)), tsMonoOffsetMs(10),
RuslanUrya 0:dfe6edabb8ec 268 uavcan::CanIOFlagLoopback));
RuslanUrya 0:dfe6edabb8ec 269 ENFORCE(1 == driver.getIface(i)->send(makeFrame(789, std::to_string(i)), tsMonoOffsetMs(-1), // Will timeout
RuslanUrya 0:dfe6edabb8ec 270 uavcan::CanIOFlagLoopback));
RuslanUrya 0:dfe6edabb8ec 271 }
RuslanUrya 0:dfe6edabb8ec 272
RuslanUrya 0:dfe6edabb8ec 273 std::cout << "select() 3" << std::endl;
RuslanUrya 0:dfe6edabb8ec 274 ENFORCE(driver.getNumIfaces() == driver.select(masks, pending_tx, tsMonoOffsetMs(1000)));
RuslanUrya 0:dfe6edabb8ec 275 ENFORCE(masks.read == AllIfacesMask);
RuslanUrya 0:dfe6edabb8ec 276 ENFORCE(masks.write == AllIfacesMask);
RuslanUrya 0:dfe6edabb8ec 277
RuslanUrya 0:dfe6edabb8ec 278 /*
RuslanUrya 0:dfe6edabb8ec 279 * Receive loopback
RuslanUrya 0:dfe6edabb8ec 280 */
RuslanUrya 0:dfe6edabb8ec 281 for (int i = 0; i < driver.getNumIfaces(); i++)
RuslanUrya 0:dfe6edabb8ec 282 {
RuslanUrya 0:dfe6edabb8ec 283 uavcan::CanFrame frame;
RuslanUrya 0:dfe6edabb8ec 284 uavcan::MonotonicTime ts_mono;
RuslanUrya 0:dfe6edabb8ec 285 uavcan::UtcTime ts_utc;
RuslanUrya 0:dfe6edabb8ec 286 uavcan::CanIOFlags flags = 0;
RuslanUrya 0:dfe6edabb8ec 287 ENFORCE(1 == driver.getIface(i)->receive(frame, ts_mono, ts_utc, flags));
RuslanUrya 0:dfe6edabb8ec 288 ENFORCE(frame == makeFrame(456, std::to_string(i)));
RuslanUrya 0:dfe6edabb8ec 289 ENFORCE(flags == uavcan::CanIOFlagLoopback);
RuslanUrya 0:dfe6edabb8ec 290 ENFORCE((clock.getMonotonic() - ts_mono).getAbs().toMSec() < 10);
RuslanUrya 0:dfe6edabb8ec 291 ENFORCE((clock.getUtc() - ts_utc).getAbs().toMSec() < 10);
RuslanUrya 0:dfe6edabb8ec 292
RuslanUrya 0:dfe6edabb8ec 293 ENFORCE(!driver.getIface(i)->hasReadyTx());
RuslanUrya 0:dfe6edabb8ec 294 ENFORCE(!driver.getIface(i)->hasReadyRx());
RuslanUrya 0:dfe6edabb8ec 295 }
RuslanUrya 0:dfe6edabb8ec 296
RuslanUrya 0:dfe6edabb8ec 297 std::cout << "select() 4" << std::endl;
RuslanUrya 0:dfe6edabb8ec 298 masks.write = 0;
RuslanUrya 0:dfe6edabb8ec 299 ENFORCE(driver.getNumIfaces() == driver.select(masks, pending_tx, tsMonoOffsetMs(1000)));
RuslanUrya 0:dfe6edabb8ec 300 ENFORCE(masks.read == 0);
RuslanUrya 0:dfe6edabb8ec 301 ENFORCE(masks.write == AllIfacesMask);
RuslanUrya 0:dfe6edabb8ec 302
RuslanUrya 0:dfe6edabb8ec 303 std::cout << "exit" << std::endl;
RuslanUrya 0:dfe6edabb8ec 304
RuslanUrya 0:dfe6edabb8ec 305 /*
RuslanUrya 0:dfe6edabb8ec 306 * Error checks
RuslanUrya 0:dfe6edabb8ec 307 */
RuslanUrya 0:dfe6edabb8ec 308 for (int i = 0; i < driver.getNumIfaces(); i++)
RuslanUrya 0:dfe6edabb8ec 309 {
RuslanUrya 0:dfe6edabb8ec 310 for (auto kv : driver.getIface(i)->getErrors())
RuslanUrya 0:dfe6edabb8ec 311 {
RuslanUrya 0:dfe6edabb8ec 312 switch (kv.first)
RuslanUrya 0:dfe6edabb8ec 313 {
RuslanUrya 0:dfe6edabb8ec 314 case uavcan_linux::SocketCanError::SocketReadFailure:
RuslanUrya 0:dfe6edabb8ec 315 case uavcan_linux::SocketCanError::SocketWriteFailure:
RuslanUrya 0:dfe6edabb8ec 316 {
RuslanUrya 0:dfe6edabb8ec 317 ENFORCE(kv.second == 0);
RuslanUrya 0:dfe6edabb8ec 318 break;
RuslanUrya 0:dfe6edabb8ec 319 }
RuslanUrya 0:dfe6edabb8ec 320 case uavcan_linux::SocketCanError::TxTimeout:
RuslanUrya 0:dfe6edabb8ec 321 {
RuslanUrya 0:dfe6edabb8ec 322 ENFORCE(kv.second == 1); // One timed out frame from the above
RuslanUrya 0:dfe6edabb8ec 323 break;
RuslanUrya 0:dfe6edabb8ec 324 }
RuslanUrya 0:dfe6edabb8ec 325 default:
RuslanUrya 0:dfe6edabb8ec 326 {
RuslanUrya 0:dfe6edabb8ec 327 ENFORCE(false);
RuslanUrya 0:dfe6edabb8ec 328 break;
RuslanUrya 0:dfe6edabb8ec 329 }
RuslanUrya 0:dfe6edabb8ec 330 }
RuslanUrya 0:dfe6edabb8ec 331 }
RuslanUrya 0:dfe6edabb8ec 332 }
RuslanUrya 0:dfe6edabb8ec 333 }
RuslanUrya 0:dfe6edabb8ec 334
RuslanUrya 0:dfe6edabb8ec 335 int main(int argc, const char** argv)
RuslanUrya 0:dfe6edabb8ec 336 {
RuslanUrya 0:dfe6edabb8ec 337 try
RuslanUrya 0:dfe6edabb8ec 338 {
RuslanUrya 0:dfe6edabb8ec 339 if (argc < 2)
RuslanUrya 0:dfe6edabb8ec 340 {
RuslanUrya 0:dfe6edabb8ec 341 std::cerr << "Usage:\n\t" << argv[0] << " <can-iface-name-1> [can-iface-name-N...]" << std::endl;
RuslanUrya 0:dfe6edabb8ec 342 return 1;
RuslanUrya 0:dfe6edabb8ec 343 }
RuslanUrya 0:dfe6edabb8ec 344
RuslanUrya 0:dfe6edabb8ec 345 std::vector<std::string> iface_names;
RuslanUrya 0:dfe6edabb8ec 346 for (int i = 1; i < argc; i++)
RuslanUrya 0:dfe6edabb8ec 347 {
RuslanUrya 0:dfe6edabb8ec 348 iface_names.emplace_back(argv[i]);
RuslanUrya 0:dfe6edabb8ec 349 }
RuslanUrya 0:dfe6edabb8ec 350
RuslanUrya 0:dfe6edabb8ec 351 testNonexistentIface();
RuslanUrya 0:dfe6edabb8ec 352 testSocketRxTx(iface_names[0]);
RuslanUrya 0:dfe6edabb8ec 353 testSocketFilters(iface_names[0]);
RuslanUrya 0:dfe6edabb8ec 354
RuslanUrya 0:dfe6edabb8ec 355 testDriver(iface_names);
RuslanUrya 0:dfe6edabb8ec 356
RuslanUrya 0:dfe6edabb8ec 357 return 0;
RuslanUrya 0:dfe6edabb8ec 358 }
RuslanUrya 0:dfe6edabb8ec 359 catch (const std::exception& ex)
RuslanUrya 0:dfe6edabb8ec 360 {
RuslanUrya 0:dfe6edabb8ec 361 std::cerr << "Exception: " << ex.what() << std::endl;
RuslanUrya 0:dfe6edabb8ec 362 return 1;
RuslanUrya 0:dfe6edabb8ec 363 }
RuslanUrya 0:dfe6edabb8ec 364 }