26 std::uint32_t senf::emu::EmulatedInterface::emuInterfaceIndex = 0;
31 prefix_ void senf::emu::detail::EmulatedInterfaceReceiveFilter::request()
36 Interface & iface (receiver_.EmulatedReceiver::basei::interface());
37 auto const & ifaceId (iface.id());
41 if (e->source() == ifaceId)
45 if (! iface.receiver().promisc() ) {
46 MACAddress dst (e->destination());
47 if (! dst.multicast() && dst != ifaceId)
60 if (w->sourceAddress() == ifaceId)
65 if (Interface::nodeId() == p->nodeId() && iface.index() == p->interfaceIndex())
67 << p->nodeId() <<
"," << p->interfaceIndex()));
69 p.annotation<annotations::Timestamp>().fromSocketProtocol(receiver_.EmulatedReceiver::emui::interface().emulationSocket().protocol());
70 p.annotation<annotations::Interface>().value = ifaceId;
78 prefix_ void senf::emu::detail::EmulatedInterfaceTransmitFilter::request()
82 Packet::size_type sz (transmitter_.v_emulatedPayloadSize(p));
85 "Dropping emulated packet: emulated packet size " << sz
86 <<
" exceeds device MTU " << mtu_));
92 gettimeofday( &tv, NULL);
94 ph->timestamp() = (tv.tv_sec * 1000000000ULL + tv.tv_usec * 1000ULL);
95 ph->sequenceNumber() = seqNr_++;
96 ph->nodeId() = Interface::nodeId();
97 ph->interfaceIndex() = transmitter_.basei::interface().index();
105 prefix_ senf::emu::detail::DroppedPacketChecker::DroppedPacketChecker()
106 : droppedPackets_ (0u), lastDroppedPackets_ (0u), factor_ (0.0f)
108 registerEvent(statisticsTimer_, &DroppedPacketChecker::statisticsUpdate);
111 prefix_ void senf::emu::detail::DroppedPacketChecker::v_handlePacket(
PacketHeader const & p)
113 boost::uint32_t seqNo (p->sequenceNumber());
114 SeqNoMap::iterator i (seqNos_.find(std::make_pair(p->nodeId(),p->interfaceIndex())));
115 if (i == seqNos_.end()) {
118 std::make_pair(p->nodeId().value(), p->interfaceIndex().value()),
122 if (seqNo > i->second+1) {
124 (
"Dropped packet from nodeId,ifIndex " <<
125 i->first.first <<
"," << i->first.second <<
" " 126 "detected at sequence number " << seqNo));
129 ++ lastDroppedPackets_;
131 else if (seqNo <= i->second ) {
133 (
"Packet reversal or duplicate packet from nodeId,ifIndex " <<
134 i->first.first <<
"," << i->first.second <<
" " 135 "detected at sequence number " << seqNo));
140 prefix_ void senf::emu::detail::DroppedPacketChecker::
141 startStatistics(ClockService::clock_type pollInterval)
143 statisticsTimer_.interval(pollInterval);
144 factor_ = double(ClockService::in_nanoseconds(pollInterval)) /
145 double(ClockService::in_nanoseconds(ClockService::seconds(1)));
148 prefix_ void senf::emu::detail::DroppedPacketChecker::statisticsUpdate()
150 signals.droppedPacketsPerSecond(lastDroppedPackets_/factor_);
151 signals.numPeers(seqNos_.size());
152 lastDroppedPackets_ = 0;
159 senf::emu::detail::DelayTimeChecker::DelayTimeChecker(ClockService::clock_type maxDelay)
160 : maxDelay_ (maxDelay), delayedPackets_ (0u), maxPacketDelay_ (0u), minDelayStat_ (0u),
161 totalDelayStat_ (0u), maxDelayStat_ (0u), nPackets_ (0u)
163 registerEvent(statisticsTimer_, &DelayTimeChecker::statisticsUpdate);
167 senf::emu::detail::DelayTimeChecker::startStatistics(ClockService::clock_type pollInterval)
169 statisticsTimer_.interval(pollInterval);
174 ClockService::clock_type sendTime (p->timestamp().value());
175 ClockService::clock_type recvTime (p.annotation<annotations::Timestamp>().as_clock_type());
176 ClockService::clock_type delay (recvTime - sendTime);
177 if (nPackets_ == 0 || delay < minDelayStat_)
178 minDelayStat_ = delay;
179 if (delay > maxDelayStat_)
180 maxDelayStat_ = delay;
181 totalDelayStat_ += delay;
183 if (delay > maxPacketDelay_)
184 maxPacketDelay_ = delay;
185 if (delay < ClockService::clock_type(0)) {
187 (
"Detected time reversal (\?\?) in packet from nodeId,ifIndex " <<
188 p->nodeId() <<
"," << p->interfaceIndex()));
191 else if (delay > maxDelay_) {
193 (
"Detected excessive packet delay of " 194 << ClockService::reltime(delay)
195 <<
" in packet from nodeId,ifIndex " 196 << p->nodeId() <<
"," << p->interfaceIndex()));
202 prefix_ void senf::emu::detail::DelayTimeChecker::statisticsUpdate()
207 double(ClockService::in_nanoseconds(minDelayStat_)) /
208 ClockService::in_nanoseconds(ClockService::seconds(1)),
209 double(ClockService::in_nanoseconds(totalDelayStat_)) /
210 nPackets_ / ClockService::in_nanoseconds(ClockService::seconds(1)),
211 double(ClockService::in_nanoseconds(maxDelayStat_)) /
212 ClockService::in_nanoseconds(ClockService::seconds(1)));
213 minDelayStat_ = totalDelayStat_ = maxDelayStat_ = ClockService::clock_type(0);
222 namespace fty = console::factory;
224 interface().consoleDir()
225 .add(
"emulationAddress",
228 .doc(
"The emulation address is the multicast address and port to which all emulated\n" 229 "Network traffic is sent. All emulated interfaces with the same emulation address\n" 230 "Are connected to the same network segment.")
231 .overloadDoc(
"Get current emulation address") );
232 interface().consoleDir()
233 .add(
"emulationInterface",
236 .arg(
"iface",
"name of interface for emulation network traffic")
237 .doc(
"All emulation traffic is sent and received on this interface.")
238 .overloadDoc(
"Set the emulation interface.") );
239 interface().consoleDir()
240 .add(
"emulationInterface",
243 .overloadDoc(
"Get current emulation interface.") );
248 if (address_ && ! enabled_)
255 if (address_ && enabled_)
263 if (address_ && enabled_)
266 if (address_ && enabled_)
270 prefix_ void senf::emu::EmulatedInterface::openSocket()
273 socket_.blocking(
false);
274 socket_.protocol().sndbuf( 48*1024);
275 socket_.protocol().rcvbuf( 128*1024);
279 prefix_ void senf::emu::EmulatedInterface::closeSocket()
290 : filter_ (*this), dropper_(0u), receiverJack (advance_.output), promisc_ (false), annotationMode_(false)
292 ppi::connect(source_, filter_);
293 ppi::connect(filter_, dropChecker_);
294 ppi::connect(dropChecker_, delayChecker_);
295 ppi::connect(delayChecker_, dropper_);
296 ppi::connect(dropper_, advance_);
303 namespace kw = console::kw;
304 namespace fty = console::factory;
309 .registerStatistics(
"in-droppedPacketsPerSecond", dropChecker_.signals.droppedPacketsPerSecond);
311 .registerStatistics(
"in-packetDelay", delayChecker_.signals.packetDelay);
313 .registerStatistics(
"in-numPeers", dropChecker_.signals.numPeers);
315 basei::interface().consoleDir()
319 .arg(
"delay",
"Maximum allowed packet delay",
320 kw::parser=senf::parseClockServiceInterval)
321 .doc(
"Get/set maximum allowed packet delay.\n" 322 "Packets which take longer to be delivered will be logged.") );
323 basei::interface().consoleDir()
327 .formatter(senf::formatClockServiceInterval) );
328 basei::interface().consoleDir()
330 .doc(
"Number of packets with delay > maxDelay.") );
331 basei::interface().consoleDir()
333 .doc(
"Maximum packet delay encountered.") );
334 basei::interface().consoleDir()
336 .doc(
"Number of dropped packets.") );
338 basei::interface().consoleDir()
342 .arg(
"lossRate",
"loss rate of packet dropper")
343 .doc(
"Get/set the loss rate of the packet dropper.") );
344 basei::interface().consoleDir()
369 : transmitterJack(delayer_.input), filter_(*this)
371 ppi::connect(delayer_, filter_);
372 ppi::connect(filter_, sink_);
377 namespace fty = console::factory;
379 basei::interface().consoleDir()
383 .arg(
"delay",
"transmitting delay",
384 console::kw::parser=senf::parseClockServiceInterval)
387 basei::interface().consoleDir()
391 .formatter(senf::formatClockServiceInterval) );
400 sink_.writer().target(emui::interface().emulationAddress());
409 return pp ? pp.
size() : 0u;
417 namespace fty = console::factory;
420 interface().consoleDir()
421 .add(
"emulationAddress",
423 emulationAddress, (UDPClientHandle::Address
const &)))
424 .arg(
"address",
"emulation multicast address")
425 .overloadDoc(
"Change emulation address.") );
void startStatistics(ClockService::clock_type pollInterval)
Start statistics generation or change interval.
config::time_type clock_type
ClockService::clock_type maxDelay() const
Get current maxDelay() value.
#define SENF_MEMBINDFNP(ret, cls, fn, args)
ConcretePacket< PacketHeaderType > PacketHeader
PacketHeader packet typedef.
Emulated interface base-class for transmit capable interfaces.
virtual void v_initEmulationInterface()=0
Called to initialize the emulated interface.
EmulatedInterface public header.
std::string const & emulationInterface() const
Get interface on which emulated traffic is sent/received.
boost::function< R(Args)> membind(R(T::*fn)(Args), T *ob)
Annotations public header.
Emulated interface base-class.
WLANPacket_MgtFrameType::packet WLANPacket_MgtFrame
virtual Packet::size_type v_emulatedPayloadSize(Packet packet)
Called to get size of payload.
senf::detail::packet::size_type size_type
Emulated interface base-class for receive capable interfaces.
void initEmulatedReceiver()
Initialize receiver.
unsigned delayedPackets() const
Number of packets with delay > maxDelay()
void disableEmulatedInterface()
Disable the interface.
void emulationInterface(std::string const &interface)
Set interface on which to send/receive emulated traffic.
void initEmulatedTransmitter()
Initialize transmitter.
senf::UDPv4ClientSocketHandle UDPClientHandle
UDPClientHandle emulationSocket() const
Get the emulation socket handle.
virtual void v_deinitEmulationInterface()=0
Called to shut down the emulated interface.
void enableEmulatedInterface()
Enable the interface.
Emulated interface base-class for wired interfaces.
ClockService::clock_type maxPacketDelay() const
Maximum packet delay encountered.
ConcretePacket< EthernetPacketType > EthernetPacket
UDPClientHandle::Address emulationAddress() const
Get current emulated traffic multicast address.
unsigned droppedPackets() const
Number of dropped packets.
ClockService::clock_type delay() const
get the sender delay