AntHocNet 2.6.1
Paper-faithful ant-colony ad hoc routing: the shared core and its adapters
Loading...
Searching...
No Matches
anthocnet-routing-protocol.h
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-2.0-only
2// Copyright (C) 2026 Daniel Henrique Joppi
3
4/*
5 * AntHocNet routing protocol for NS-3.
6 *
7 * An additive Ipv4RoutingProtocol (mirroring src/aodv) that delegates all
8 * routing decisions to the shared core::AntRouterLogic. Ant control packets
9 * travel over a dedicated UDP port; data packets are routed/queued via
10 * RouteOutput / RouteInput.
11 */
12#ifndef ANTHOCNET_ROUTING_PROTOCOL_H
13#define ANTHOCNET_ROUTING_PROTOCOL_H
14
15#include "ns3/ipv4-routing-protocol.h"
16#include "ns3/ipv4-interface-address.h"
17#include "ns3/ipv4-l3-protocol.h"
18#include "ns3/socket.h"
19#include "ns3/timer.h"
20#include "ns3/random-variable-stream.h"
21#include "ns3/traced-callback.h"
22#include "ns3/mac48-address.h"
23#include "ns3/queue.h"
24#include "ns3/wifi-mac.h"
25
26// ns-3 renamed WifiMacQueueItem -> WifiMpdu (and wifi-mac-queue-item.h ->
27// wifi-mpdu.h) in ns-3.37; the WifiMac "DroppedMpdu" trace carries this type.
28// ANTHOCNET_NS3_WIFI_QUEUE_ITEM is defined by the module's CMakeLists for
29// ns-3 <= 3.36; default to the modern name.
30#ifdef ANTHOCNET_NS3_WIFI_QUEUE_ITEM
31#include "ns3/wifi-mac-queue-item.h"
32#define AHN_WIFI_MPDU ns3::WifiMacQueueItem
33#else
34#include "ns3/wifi-mpdu.h"
35#define AHN_WIFI_MPDU ns3::WifiMpdu
36#endif
37
38#include <deque>
39#include <map>
40#include <memory>
41#include <set>
42#include <string>
43
46#include "anthocnet-adapters.h"
47#include "anthocnet-rqueue.h"
48
49// ns-3 changed Ipv4RoutingProtocol::RouteInput's forwarding-callback parameters
50// from by-value (<= ns-3.36) to const-reference (ns-3.37+). The override must
51// match exactly or the class stays abstract. ANTHOCNET_NS3_ROUTEINPUT_BYVALUE is
52// defined by the module's CMakeLists for ns-3 <= 3.36; default to const-ref.
53#ifdef ANTHOCNET_NS3_ROUTEINPUT_BYVALUE
54#define AHN_RI_CB(T) T
55#else
56#define AHN_RI_CB(T) const T&
57#endif
58
59namespace ns3 {
60namespace anthocnet {
61
62// The protocol is also a core IRouterObserver (item 15): it forwards the core's
63// ant/route events to ns-3 trace sources so users can Config::Connect and so the
64// comparison harness can read ant-level diagnostics. The interface is all
65// no-op-default virtuals, so this adds no state to the core.
72public:
73 static TypeId GetTypeId();
74 static const uint16_t ANT_PORT; ///< UDP port for ant control traffic.
75
77 ~RoutingProtocol() override;
78
79 // Trace-source callback signatures (introspection names used in GetTypeId).
80 typedef void (*AntTxCallback)(uint8_t type, uint8_t direction, bool broadcast);
81 typedef void (*AntRxCallback)(uint8_t type, uint8_t direction);
82 typedef void (*RouteChangedCallback)(uint32_t dest, uint32_t neighbor, bool added);
83 // #386: a MAC retry-limit-dropped data packet was re-injected into the
84 // pending queue (#46). `header` is the packet's Ipv4 header as captured off
85 // the failed MPDU; `packet` is the queued form (UDP header + payload, no IP
86 // header — RouteInput's convention). Fired once per re-injection, at the
87 // same site that increments MacReinjectedPackets(), so a listener's event
88 // count and that counter agree by construction.
89 typedef void (*MacReinjectCallback)(const Ipv4Header& header, Ptr<const Packet> packet);
90
91 // core::IRouterObserver
93 bool broadcast) override;
97 bool added) override;
98
99 // #216 diagnostic: read the current regular and virtual pheromone for
100 // (dest, neighbour), both given as canonical Ipv4 addresses. Zeroes when
101 // the routing logic is not yet constructed. Read-only — used by the
102 // isl-grid corridor cell's "# pher" sampler to watch whether a gradient
103 // toward the clean corridor ever forms at the probe source.
104 void GetPheromoneDiag(Ipv4Address dest, Ipv4Address neighbor, double& regular,
105 double& virt) const;
106
107 // core::ILinkState (item 10/A2): supply MAC congestion signals for the
108 // congestion-aware per-hop metric. Only meaningful when EnableMacMetric is
109 // set; the core queries these while stamping a forward ant, naming the
110 // next hop the cost is for (#206). This wifi implementation is the
111 // degenerate single-interface case — one radio, one MAC, one queue — so
112 // the parameter is ignored and per-next-hop collapses to per-node.
115
116 // core::ILinkQuality (#181): the SINR (dB) of the last ant received from
117 // `neighbor`, read from the wifi PHY's monitor trace and matched to the
118 // ant by packet UID. Only wired when the selected LinkMetric asks for it
119 // (the "sinr" metric); NaN when there is no sample.
120 double sinrDbFrom(::anthocnet::core::NodeAddress neighbor) const override;
121 /// Called by the PHY monitor hook for every received MPDU (#181).
122 void NotifyPhyRxSinr(Ptr<const Packet> packet, double sinrDb);
123
124 // core::IEnergy (#145): this node's residual energy fraction (0..1), from
125 // a probe the scenario sets, because energy accounting is the scenario's
126 // (anthocnet-compare integrates the PHY state trace, #256). NaN when no
127 // probe is set: the energy metric then degrades to hop count.
128 double residualEnergyFraction() const override;
129 /// Set the probe residualEnergyFraction() reads (#145).
130 void SetEnergyProbe(Callback<double> probe) { m_energyProbe = probe; }
131
132 // core::IKinematics (#573, ADR-0025): this node's position and velocity
133 // from its aggregated MobilityModel; false when it has none. Only read
134 // when ShareKinematics is on.
135 bool self(::anthocnet::core::Kinematics& out) const override;
136
137 // Ipv4RoutingProtocol
138 Ptr<Ipv4Route> RouteOutput(Ptr<Packet> p, const Ipv4Header& header, Ptr<NetDevice> oif,
139 Socket::SocketErrno& sockerr) override;
140 bool RouteInput(Ptr<const Packet> p, const Ipv4Header& header, Ptr<const NetDevice> idev,
141 AHN_RI_CB(UnicastForwardCallback) ucb, AHN_RI_CB(MulticastForwardCallback) mcb,
142 AHN_RI_CB(LocalDeliverCallback) lcb, AHN_RI_CB(ErrorCallback) ecb) override;
143 void NotifyInterfaceUp(uint32_t interface) override;
144 void NotifyInterfaceDown(uint32_t interface) override;
145 void NotifyAddAddress(uint32_t interface, Ipv4InterfaceAddress address) override;
146 void NotifyRemoveAddress(uint32_t interface, Ipv4InterfaceAddress address) override;
147 void SetIpv4(Ptr<Ipv4> ipv4) override;
148 void PrintRoutingTable(Ptr<OutputStreamWrapper> stream,
149 Time::Unit unit = Time::S) const override;
150
151 /// Seed the protocol's RNG; returns the number of streams used.
152 int64_t AssignStreams(int64_t stream);
153 /// #496: seed the hello/proactive timer-jitter stream (separate from the
154 /// core's decision stream, so jitter draws never shift the core's
155 /// sequence); returns the number of streams used. AntHocNetHelper assigns
156 /// these after every node's core stream, so the core streams keep their
157 /// pre-#496 indices.
158 int64_t AssignTimerStreams(int64_t stream);
159
160 /// Issue #20 diagnostics: LinkFail origin/propagation split from the core
161 /// (origins = antTx[linkfail] − propagations; budget drops = suppressed).
162 uint64_t LinkfailPropagations() const { return m_logic ? m_logic->linkfailPropagations() : 0; }
163 uint64_t LinkfailBudgetDrops() const { return m_logic ? m_logic->linkfailBudgetDrops() : 0; }
164 uint64_t LinkfailOriginsSuppressed() const {
165 return m_logic ? m_logic->linkfailOriginsSuppressed() : 0;
166 }
167
168 /// Directed reactive discovery diagnostics: reactive forward ants unicast
169 /// along the diffusion gradient instead of broadcast (EnableDirectedReactive).
170 /// Zero on an enabled run means the gradient never covered a destination the
171 /// regular table was missing, i.e. the switch was inert for this scenario.
172 uint64_t DirectedSteers() const { return m_logic ? m_logic->directedSteers() : 0; }
173
174 /// Issue #133 observability: per-node pheromone-table size gauge from the
175 /// core — current (neighbor, dest) entry counts, split regular vs virtual.
176 /// Read by the comparison harness under --diag to watch table growth.
177 uint64_t PtableEntriesRegular() const {
178 return m_logic ? m_logic->table().numEntriesRegular() : 0;
179 }
180 uint64_t PtableEntriesVirtual() const {
181 return m_logic ? m_logic->table().numEntriesVirtual() : 0;
182 }
183
184 /// #641 observability: the neighbour holding the most regular pheromone
185 /// toward `dest` -- the learn site's strongest-route rule -- or 0.0.0.0
186 /// when there is none. Read by the harnesses' --vizTrace; no routing
187 /// decision uses it (data still samples next hops from pheromone^beta).
188 Ipv4Address StrongestNextHop(Ipv4Address dest) const {
189 if (!m_logic) return Ipv4Address();
190 const auto& t = m_logic->table();
191 const ::anthocnet::core::NodeAddress d = ToCore(dest);
192 double best = 0.0;
194 for (::anthocnet::core::NodeAddress nb : t.neighbors()) {
195 const double tau = t.getPheromoneRegular(d, nb);
196 if (tau > best) {
197 best = tau;
198 next = nb;
199 }
200 }
201 return next ? ToIpv4(next) : Ipv4Address();
202 }
203
204 /// Issue #21 hold-time attribution: per-reason (setup / reconvergence /
205 /// repair) pending-queue hold-time stats accumulated over the run, read by
206 /// the comparison harness under --diag to locate the delay tail's dominant
207 /// hold path.
208 const HoldStats& HoldTimeStats() const { return m_queue.Stats(); }
209
210 /// Issue #215 drop-cause breakdown, the AntHocNet-specific causes. The
211 /// generic ones (channel, MAC, TTL, interface queue) are measured
212 /// simulator-side by the comparison harness for every protocol; these three
213 /// exist only here because only this protocol has a pending queue and a
214 /// local-repair discard.
215 ///
216 /// Data packets released by a failed local repair ([1] §3.5, D6) — the
217 /// *packet* count behind the core's DiscardPending events. This is expected
218 /// protocol behaviour, not a fault: the paper trades these packets for a
219 /// bounded delay tail.
220 uint64_t RepairDiscardedPackets() const { return m_repairDiscardedPackets; }
221 /// Expired local repairs (the core's event count; several packets may be
222 /// released per event).
223 uint64_t RepairDiscards() const { return m_logic ? m_logic->repairDiscards() : 0; }
224 /// Data packets a MAC retry-limit drop put *back* into the pending queue
225 /// (#46 re-injection). Such a packet is not lost yet — its terminal fate is
226 /// counted wherever it finally ends up — so the harness subtracts these from
227 /// the raw MAC-failure tally to avoid double-counting them (#215).
228 uint64_t MacReinjectedPackets() const { return m_macReinjectedPackets; }
229
230protected:
231 void DoInitialize() override;
232 void DoDispose() override;
233
234public:
235 // Address mapping between core (int32 NodeAddress == the IP, opaque) and
236 // ns-3 (ADR-0011). Broadcast is a RouteAction, never an identity, so the
237 // all-ones address must never reach the core as a peer; guard it so it
238 // cannot alias kInvalidAddress (-1 == 0xFFFFFFFF). MSB-set unicast IPs map
239 // to negative ints and round-trip fine — only the all-ones value collides.
240 // Public so the test suite can assert the round-trip / sentinel guard.
241 static ::anthocnet::core::NodeAddress ToCore(Ipv4Address a) {
242 const uint32_t raw = a.Get();
243 if (raw == 0xFFFFFFFFu) return 0; // limited broadcast: not an identity
244 return static_cast<::anthocnet::core::NodeAddress>(raw);
245 }
247 return Ipv4Address(static_cast<uint32_t>(a));
248 }
249
250private:
251 void Start();
252 Ptr<Ipv4Route> LoopbackRoute(const Ipv4Header& header, Ptr<NetDevice> oif) const;
253 bool IsMyOwnAddress(Ipv4Address src) const;
254 Ptr<Socket> FindSocketWithInterfaceAddress(Ipv4InterfaceAddress addr) const;
255
256 // ant I/O
257 void RecvAnt(Ptr<Socket> socket);
258 void SendAnt(const ::anthocnet::core::AntMessage& msg, Ipv4Address dest);
259 void ExecuteDecisions(const std::vector<::anthocnet::core::RouteDecision>& decisions,
261
262 // data path
263 void DeferredRouteOutput(Ptr<const Packet> p, const Ipv4Header& header,
264 UnicastForwardCallback ucb, ErrorCallback ecb);
265 void FlushQueue(::anthocnet::core::NodeAddress coreDest);
266 /// Repair wait expired ([1] §3.5, D6): drop the packets queued for
267 /// `coreDest`, firing their error callbacks.
268 void DiscardQueue(::anthocnet::core::NodeAddress coreDest);
269
270 // timers
271 void HelloTimerExpire();
272 void ProactiveTimerExpire();
273 /// Issue #21: re-flood a reactive forward ant for every destination with
274 /// data still waiting in the pending queue but no route. onDataPacket only
275 /// retries when a data packet arrives (~1 pkt/s at paper CBR), so a lost
276 /// first re-discovery attempt otherwise waits a full second; this timer
277 /// retries at a sub-second cadence, shortening the reconvergence hold that
278 /// dominates the delay/jitter tail.
279 void ReactiveRetryTimerExpire();
280
281 // ADR-0008 detector D: MAC transmit-failure hook. The WifiMac "DroppedMpdu"
282 // trace fires when a unicast frame is dropped after exhausting retries; we
283 // treat a retry-limit drop as a broken link to that next hop and drive the
284 // shared core reportTxFailure path (prune + bounded repair ant).
285 void NotifyTxError(WifiMacDropReason reason, Ptr<const AHN_WIFI_MPDU> mpdu);
286 /// Issue #68: successful-transmission hook — samples the measured
287 /// per-packet MAC service time for the A2 congestion metric.
288 void NotifyAckedMpdu(Ptr<const AHN_WIFI_MPDU> mpdu);
289 // Resolve a failed next-hop MAC to a core address via the ARP caches.
290 bool MapMacToCore(const Mac48Address& mac, ::anthocnet::core::NodeAddress& out) const;
291
292 /// Issue #203: resolve a core next-hop name to the concrete way of reaching
293 /// it — the gateway address to send to, the device to send it out of, and
294 /// that device's interface index.
295 ///
296 /// Necessary because the core names a node by ONE address (the first
297 /// interface's, fixed when the logic is constructed in NotifyInterfaceUp)
298 /// while a multi-interface node is reachable on a different subnet per
299 /// link. On single-interface topologies the two coincide and this resolves
300 /// to exactly the pre-#203 values.
301 ///
302 /// Never fails: an unresolvable hop falls back to the first interface, the
303 /// old behaviour, rather than dropping the packet.
304 void ResolveNextHop(::anthocnet::core::NodeAddress next, Ipv4Address& gateway,
305 Ptr<NetDevice>& dev, uint32_t& iface) const;
306
307 // state
308 Ptr<Ipv4> m_ipv4;
309 // Per-interface sockets: one bound to the unicast address (receives
310 // unicast ants), one bound to the subnet-broadcast address (receives
311 // broadcast hello/forward ants). A socket bound only to the unicast
312 // address does NOT receive broadcasts, so both are required.
313 //
314 // Issue #362: ordered by the index of the device each socket is bound to,
315 // NOT by Ptr<Socket> (whose operator< compares heap addresses). With more
316 // than one interface (the ISL mesh) the broadcast fan-out order and the
317 // `.begin()` "first interface" fallbacks otherwise depended on what the
318 // process had allocated earlier — i.e. on --protocols order.
319 struct SocketByBoundDevice {
320 bool operator()(const Ptr<Socket>& a, const Ptr<Socket>& b) const;
321 };
322 std::map<Ptr<Socket>, Ipv4InterfaceAddress, SocketByBoundDevice> m_socketAddresses;
323 std::map<Ptr<Socket>, Ipv4InterfaceAddress, SocketByBoundDevice> m_socketSubnetBroadcast;
324
325 /// Issue #203: where a peer the core named actually is. `iface` is the ns-3
326 /// interface index whose device shares a link with it; `linkLocal` is the
327 /// address to send to on that link.
328 struct PeerRoute {
329 uint32_t iface = 0;
330 Ipv4Address linkLocal;
331 };
332 /// Peer canonical address (how the core names it, i.e. how it appears in
333 /// pheromone tables and ant paths) -> how to reach it. Learned from hello
334 /// ants, the one message carrying both of a peer's names: `msg.src` is the
335 /// canonical one, the IP source is the link-local one. Only populated when
336 /// the two differ, so it stays empty on every single-interface topology.
337 std::map<Ipv4Address, PeerRoute> m_peerRoutes;
338
339 /// Issue #260: every core name a neighbour was heard under, per interface —
340 /// both the link-local sender (what learnNeighbor records as prevHop) and
341 /// the canonical `msg.src` a hello carries. Consulted only by the non-wifi
342 /// interface-down fast path in NotifyInterfaceDown so an ISL break can
343 /// attribute which next hop(s) it severed; an interface that never heard a
344 /// hello has no entry, and that path is then a no-op.
345 std::map<uint32_t, std::set<::anthocnet::core::NodeAddress>> m_ifaceNeighbors;
346
348 Ns3Clock m_clock;
349 Ns3Rng m_rng;
350 std::unique_ptr<::anthocnet::core::AntRouterLogic> m_logic;
351 bool m_started;
352
353 RequestQueue m_queue;
354
355 Timer m_helloTimer;
356 Timer m_proactiveTimer;
357 /// #496: relative per-period jitter on the hello and proactive timers
358 /// (0 = the pre-#496 fixed, phase-locked timers).
359 double m_timerJitter = 0.05;
360 Ptr<UniformRandomVariable> m_timerRng = CreateObject<UniformRandomVariable>();
361 /// Delay to the next firing of a periodic timer with period `base`: the
362 /// first firing is a uniform phase in [0, base), later ones base scaled by
363 /// U[1 - TimerJitter, 1 + TimerJitter]. Returns `base` unchanged (and draws
364 /// nothing) when TimerJitter is 0.
365 Time TimerDelay(Time base, bool first);
366 Timer m_reactiveRetryTimer; ///< issue #21: re-flood discovery for held data
367
368 // attribute-backed parameters
369 Time m_helloInterval;
370 Time m_proactiveInterval;
371 double m_alpha;
372 double m_betaAnts;
373 double m_betaData;
374 double m_gamma;
375 double m_hopCountAlpha; ///< #185: thesis alpha, eq. 4.2 (default 0 = off)
376 bool m_enableProactive;
377 bool m_enableDiffusion;
378 bool m_enableReactive; ///< reactive forward-ant gate (ablation)
379 bool m_enableRepair; ///< local-repair ant gate (ablation)
380 bool m_enableLinkFail; ///< link-failure notification gate (ablation)
381 bool m_enableDirectedReactive; ///< steer reactive ants by the virtual table
382 bool m_shareKinematics; ///< hellos carry position/velocity (ADR-0025)
383 bool m_enableLinkLifetime; ///< discount soon-to-break next hops (#574)
384 double m_linkLifetimeRange; ///< range (m) the LET prediction assumes
385 double m_linkLifetimeHorizon; ///< LET (s) at or above which no discount applies
386 double m_linkLifetimeFloor; ///< smallest weight a predicted-short link keeps
387 bool m_enableQuietMode; ///< back proactive ants off on stable routes (#571)
388 double m_quietTolerance; ///< relative pheromone change still "stable"
389 double m_quietBackoffFactor; ///< geometric back-off growth, in rounds
390 uint32_t m_quietMaxBackoff; ///< back-off cap, in proactive rounds
391 bool m_enableAdaptiveEvaporation; ///< #572
392 double m_adaptiveEvapRefChurn; ///< #572
393 double m_adaptiveEvapMin; ///< #572
394 double m_adaptiveEvapMax; ///< #572
395 double m_adaptiveEvapTau; ///< #572
396 Callback<double> m_energyProbe; ///< residual energy fraction source (#145)
397 double m_proactiveBroadcastProb;
398 double m_proactiveVirtualMargin;
399 uint32_t m_maxHelloAdverts; ///< #186: diffusion advert cap k (thesis: 10)
400 double m_sessionTtl;
401 uint32_t m_txFailureThreshold;
402 /// #204: on point-to-point interfaces, send a hello only every this many
403 /// hello ticks (1 = every tick, the default and the old behaviour); on
404 /// the ticks in between, an up interface vouches for its peers.
405 uint32_t m_p2pHelloEvery = 1;
406 uint64_t m_helloTicks = 0; ///< hello ticks so far (#204)
407 bool m_enableMacFailureDetector;
408 uint32_t m_maxReinjectPerPacket; ///< #386 remedy: path-global re-injection cap (0 = unlimited)
409 double m_repairWaitFactor;
410 double m_repairTimeout;
411 double m_hopTime; ///< T_hop unloaded-hop reference (s), #88
412 bool m_enableMultipath; ///< multipath reactive setup gate, #96
413 double m_antAcceptanceFactor; ///< multipath acceptance factor a1, #96/#177
414 double m_antAcceptanceFactorNewHop; ///< disjoint-first-hop factor a2, #177
415 double m_linkfailNotifyInterval; ///< issue #20 origin cooldown (s), 0 = off
416 Time m_queueTimeout; ///< issue #21 pending-queue hold before drop
417 Time m_reconvHoldCap; ///< issue #21 L2: cap on reconv holds (0 = off)
418 Time m_repairHoldCap; ///< issue #21 L2: cap on repair holds (0 = off)
419 Time m_reactiveRetryInterval; ///< issue #21 timer-driven re-discovery cadence (0 = off)
420 // Issue #68: measured per-packet MAC service time (EWMA of inter-ack
421 // spacing while the MAC queue stays backlogged — pure service time, no
422 // queue wait, so (Q+1)*T̂_mac does not double-count congestion).
423 double m_macServiceAlpha; ///< EWMA smoothing (old-value weight)
424 double m_macServiceEwmaSec = 0.0; ///< 0 = no sample yet (core falls back)
425 Time m_lastAckTime; ///< previous AckedMpdu timestamp
426 bool m_backlogAtLastAck = false; ///< queue was non-empty at previous ack
427 bool m_enableMacMetric; ///< item 10/A2 congestion-aware per-hop metric
428 std::string m_linkMetric; ///< #144: core metric registry name ("classic", "sinr")
429 double m_sinrCriticalDb; ///< #181: SINR_c (dB)
430 double m_sinrPenaltyCost; ///< #181: c_const
431 /// #181: SINR of recently received MPDUs by packet UID (bounded FIFO), and
432 /// the latest SINR per neighbour, set when an ant from it is received.
433 std::deque<std::pair<uint64_t, double>> m_rxSinrByUid;
434 std::map<::anthocnet::core::NodeAddress, double> m_neighborSinrDb;
435
436 // WifiMac handle for the item-10/A2 queue-occupancy signal (null on non-wifi
437 // devices, where the p2p/ISL transmit-queue reader below takes over, #206).
438 Ptr<WifiMac> m_wifiMac;
439
440 // #206 step 2: per-interface transmit-queue congestion for non-wifi
441 // devices — the p2p/ISL regime, where each interface is one ISL with its
442 // own queue and the useful signal is per-next-hop. `queue` is the device's
443 // "TxQueue" (PointToPointNetDevice, CsmaNetDevice and SimpleNetDevice all
444 // expose the attribute); the EWMA samples inter-dequeue spacing while the
445 // queue stays backlogged — the transmitter-side analogue of the wifi
446 // inter-ack EWMA (#68), which excludes propagation by construction (the
447 // sender never waits for it). Smoothing shares MacServiceAlpha.
448 struct TxQueueState {
449 Ptr<Queue<Packet>> queue;
450 double ewmaSec = 0.0; ///< 0 = no sample yet (core falls back)
451 Time lastDequeue; ///< previous Dequeue timestamp
452 bool backlogAtLastDequeue = false;
453 };
454 std::map<uint32_t, TxQueueState> m_txQueues; ///< iface index -> queue state
455 void NotifyTxDequeue(uint32_t interface, Ptr<const Packet> p);
456 static void TxDequeueTrace(RoutingProtocol* self, uint32_t interface, Ptr<const Packet> p);
457
458 // L3 forwarding callbacks cached from RouteInput (Ipv4L3Protocol passes the
459 // same bound callbacks on every call). NotifyTxError needs them to re-inject
460 // a MAC-dropped data packet it only sees as a raw MPDU (issue #46).
461 UnicastForwardCallback m_cachedUcb;
462 ErrorCallback m_cachedEcb;
463
464 // Destinations this node has ever had a usable next hop for (issue #21):
465 // separates a first-time reactive setup (never routed) from a
466 // reconvergence wait (route was known and lost) when a data packet is
467 // deferred, so the hold-time attribution can tell the two apart.
468 std::set<::anthocnet::core::NodeAddress> m_everRouted;
469
470 // Issue #215 drop-cause counters (see the accessors above).
471 uint64_t m_repairDiscardedPackets = 0;
472 uint64_t m_macReinjectedPackets = 0;
473
474 // trace sources (item 15): ant sent/received and route add/remove.
475 TracedCallback<uint8_t, uint8_t, bool> m_txAntTrace;
476 TracedCallback<uint8_t, uint8_t> m_rxAntTrace;
477 TracedCallback<uint32_t, uint32_t, bool> m_routeChangedTrace;
478 // #386: MAC-failure re-injection (see MacReinjectCallback above).
479 TracedCallback<const Ipv4Header&, Ptr<const Packet>> m_macReinjectTrace;
480 // #402: the cap counterpart — a MAC retry-limit-dropped data packet hit
481 // MaxReinjectPerPacket and was NOT re-injected, so its MAC drop stays
482 // terminal. Same signature and packet form as MacReinject (it reuses
483 // MacReinjectCallback); fired only inside the m_maxReinjectPerPacket != 0
484 // branch of NotifyTxError, so it can never fire at the default cap 0.
485 TracedCallback<const Ipv4Header&, Ptr<const Packet>> m_macReinjectSkipTrace;
486};
487
488} // namespace anthocnet
489} // namespace ns3
490
491#endif // ANTHOCNET_ROUTING_PROTOCOL_H
#define AHN_RI_CB(T)
This node's residual energy (#145): the fraction of its initial battery left, 0..1.
Definition ports.h:116
This node's own position and velocity (#573, ADR-0025).
Definition ports.h:105
Per-neighbour link quality (#181, ADR-0024).
Definition ports.h:90
Node-local MAC-layer signals for the congestion-aware per-hop metric (item 10/A2, [1] §3....
Definition ports.h:69
Optional observer the core notifies of routing events (item 15).
Definition ports.h:127
uint64_t LinkfailPropagations() const
Issue #20 diagnostics: LinkFail origin/propagation split from the core (origins = antTx[linkfail] − p...
void(* MacReinjectCallback)(const Ipv4Header &header, Ptr< const Packet > packet)
void NotifyAddAddress(uint32_t interface, Ipv4InterfaceAddress address) override
::anthocnet::core::NodeAddress ToCore(Ipv4Address a)
bool self(::anthocnet::core::Kinematics &out) const override
void onAntSent(::anthocnet::core::AntType type, ::anthocnet::core::AntDirection dir, bool broadcast) override
void NotifyRemoveAddress(uint32_t interface, Ipv4InterfaceAddress address) override
uint64_t RepairDiscards() const
Expired local repairs (the core's event count; several packets may be released per event).
::anthocnet::core::Time macServiceTime(::anthocnet::core::NodeAddress nextHop) const override
double residualEnergyFraction() const override
void SetEnergyProbe(Callback< double > probe)
Set the probe residualEnergyFraction() reads (#145).
void onRouteChanged(::anthocnet::core::NodeAddress dest, ::anthocnet::core::NodeAddress nb, bool added) override
void PrintRoutingTable(Ptr< OutputStreamWrapper > stream, Time::Unit unit=Time::S) const override
uint64_t MacReinjectedPackets() const
Data packets a MAC retry-limit drop put back into the pending queue (#46 re-injection).
double sinrDbFrom(::anthocnet::core::NodeAddress neighbor) const override
void GetPheromoneDiag(Ipv4Address dest, Ipv4Address neighbor, double &regular, double &virt) const
void(* AntRxCallback)(uint8_t type, uint8_t direction)
uint64_t RepairDiscardedPackets() const
Issue #215 drop-cause breakdown, the AntHocNet-specific causes.
void onAntReceived(::anthocnet::core::AntType type, ::anthocnet::core::AntDirection dir) override
const HoldStats & HoldTimeStats() const
Issue #21 hold-time attribution: per-reason (setup / reconvergence / repair) pending-queue hold-time ...
void SetIpv4(Ptr< Ipv4 > ipv4) override
void(* RouteChangedCallback)(uint32_t dest, uint32_t neighbor, bool added)
uint64_t PtableEntriesRegular() const
Issue #133 observability: per-node pheromone-table size gauge from the core — current (neighbor,...
uint64_t DirectedSteers() const
Directed reactive discovery diagnostics: reactive forward ants unicast along the diffusion gradient i...
void NotifyPhyRxSinr(Ptr< const Packet > packet, double sinrDb)
Called by the PHY monitor hook for every received MPDU (#181).
bool RouteInput(Ptr< const Packet > p, const Ipv4Header &header, Ptr< const NetDevice > idev, AHN_RI_CB(UnicastForwardCallback) ucb, AHN_RI_CB(MulticastForwardCallback) mcb, AHN_RI_CB(LocalDeliverCallback) lcb, AHN_RI_CB(ErrorCallback) ecb) override
void(* AntTxCallback)(uint8_t type, uint8_t direction, bool broadcast)
int macQueueLength(::anthocnet::core::NodeAddress nextHop) const override
Ptr< Ipv4Route > RouteOutput(Ptr< Packet > p, const Ipv4Header &header, Ptr< NetDevice > oif, Socket::SocketErrno &sockerr) override
void NotifyInterfaceUp(uint32_t interface) override
static const uint16_t ANT_PORT
UDP port for ant control traffic.
Ipv4Address StrongestNextHop(Ipv4Address dest) const
#641 observability: the neighbour holding the most regular pheromone toward dest – the learn site's s...
static Ipv4Address ToIpv4(::anthocnet::core::NodeAddress a)
int64_t AssignStreams(int64_t stream)
Seed the protocol's RNG; returns the number of streams used.
void NotifyInterfaceDown(uint32_t interface) override
int64_t AssignTimerStreams(int64_t stream)
#496: seed the hello/proactive timer-jitter stream (separate from the core's decision stream,...
double Time
Simulation time, in seconds.
Definition types.h:24
std::int32_t NodeAddress
Network-layer node address.
Definition types.h:21
AntDirection
Travel direction.
Definition ant_message.h:35
AntType
Ant role.
Definition ant_message.h:25
AntHistoryTracker: (src, seqNum) duplicate detection.
Definition ant_history.h:24
A node's position (m) and velocity (m/s) in the adapter's Cartesian frame (ADR-0025).
Definition types.h:32