private void FrameSentHandler(IRadio sender, byte[] packet) { var senderPosition = radios[sender]; var currentEmulation = EmulationManager.Instance.CurrentEmulation; currentEmulation.TryGetEmulationElementName(sender, out var senderName); FrameProcessed?.Invoke(this, sender, packet); if (!mediumFunction.CanTransmit(senderPosition)) { this.NoisyLog("Packet from {0} can't be transmitted, size {1}.", senderName, packet.Length); return; } foreach (var radioAndPosition in radios.Where(x => x.Key != sender)) { var receiver = radioAndPosition.Key; currentEmulation.TryGetEmulationElementName(receiver, out var receiverName); if (!mediumFunction.CanReach(senderPosition, radioAndPosition.Value) || receiver.Channel != sender.Channel) { this.NoisyLog("Packet {0} -> {1} NOT delivered, size {2}.", senderName, receiverName, packet.Length); return; } receiver.GetMachine().HandleTimeDomainEvent(receiver.ReceiveFrame, packet.ToArray(), TimeDomainsManager.Instance.VirtualTimeStamp, () => { this.NoisyLog("Packet {0} -> {1} delivered, size {2}.", senderName, receiverName, packet.Length); FrameTransmitted?.Invoke(this, sender, receiver, packet); }); } }
private void ForwardToReceiver(EthernetFrame frame, IMACInterface sender) { this.Log(LogLevel.Noisy, "Received frame from interface {0}", sender.MAC); if (!frame.DestinationMAC.HasValue) { this.Log(LogLevel.Warning, "Destination MAC not set, the frame has unsupported format."); return; } FrameProcessed?.Invoke(this, sender, frame.Bytes); if (!started) { return; } lock (innerLock) { var interestingIfaces = macMapping.TryGetValue(frame.DestinationMAC.Value, out var destIface) ? ifaces.Where(x => (x.PromiscuousMode && x.Interface != sender) || x.Interface == destIface) : ifaces.Where(x => x.Interface != sender); if (!TimeDomainsManager.Instance.TryGetVirtualTimeStamp(out var vts)) { // it happens when sending from tap interface vts = new TimeStamp(default(TimeInterval), EmulationManager.ExternalWorld); } foreach (var iface in interestingIfaces) { this.Log(LogLevel.Noisy, "Forwarding frame to interface {0}", iface.Interface.MAC); if (iface.AsTap != null) { iface.AsTap.ReceiveFrame(frame.Clone()); continue; } iface.Machine.HandleTimeDomainEvent(iface.Interface.ReceiveFrame, frame.Clone(), vts, () => { FrameTransmitted?.Invoke(this, sender, iface.Interface, frame.Bytes); }); } } // at the same we will potentially add current MAC address assigned to the source if (!frame.SourceMAC.HasValue) { this.Log(LogLevel.Warning, "Source MAC not set, cannot update switch cache."); return; } lock (innerLock) { macMapping[frame.SourceMAC.Value] = sender; } }
private void FrameSentHandler(IRadio sender, byte[] packet) { var senderPosition = radios[sender]; var currentEmulation = EmulationManager.Instance.CurrentEmulation; currentEmulation.TryGetEmulationElementName(sender, out var senderName); FrameProcessed?.Invoke(this, sender, packet); if (!mediumFunction.CanTransmit(senderPosition)) { this.NoisyLog("Packet from {0} can't be transmitted, size {1}.", senderName, packet.Length); return; } foreach (var radioAndPosition in radios.Where(x => x.Key != sender)) { var receiver = radioAndPosition.Key; currentEmulation.TryGetEmulationElementName(receiver, out var receiverName); if (!mediumFunction.CanReach(senderPosition, radioAndPosition.Value) || receiver.Channel != sender.Channel) { this.NoisyLog("Packet {0}:chan{1} -> {2}:chan{3} NOT delivered, size {4}.", senderName, sender.Channel, receiverName, receiver.Channel, packet.Length); continue; } if (!TimeDomainsManager.Instance.TryGetVirtualTimeStamp(out var vts)) { // e.g. when the sender is a SLIP radio vts = new TimeStamp(default(TimeInterval), EmulationManager.ExternalWorld); } var packetCopy = packet.ToArray(); if (radioHooks.TryGetValue(receiver, out var hook)) { hook(packetCopy); } if (receiver is ISlipRadio) { // send immediately receiver.ReceiveFrame(packetCopy); continue; } receiver.GetMachine().HandleTimeDomainEvent(receiver.ReceiveFrame, packetCopy, vts, () => { this.NoisyLog("Packet {0}:chan{1} -> {2}:chan{3} delivered, size {4}.", senderName, sender.Channel, receiverName, receiver.Channel, packet.Length); FrameTransmitted?.Invoke(this, sender, receiver, packetCopy); }); } }