// Construct a new Exchange. public MessageExchange(string shellOrTitleId, string name, string masterSN) { Shell s = Shell.GetShell(shellOrTitleId); if (s == null) { s = Shell.GetShell(Shell.ConsoleShellId); } if (s != null) { Interrupter = s.Interrupter; ShellId = s.ShellId; } Id = name; IsClosing = false; ParameterTable = new DeviceParameterTable(); ParameterTabelInit(masterSN); Manager = new NetIfManager(ShellId, masterSN, Interrupter); Manager.AddDriver(new MediatorNetIf(Manager, this)); OutgoingQueue = new LinkedBlockingCollection <MessageBinder>(); IncomingQueue = new LinkedBlockingCollection <BabelMessage>(); IncomingListeners = new List <MessageBinder>(); WaitingForReply = new List <MessageBinder>(); DispatcherThread = new MessageDispatcherThread(this); DispatcherThread.Start(); ReceiverThread = new MessageReceiverThread(this); ReceiverThread.Start(); Manager.Start(); }
public SerialNumbers(NetIfManager manager, string masterSN) { int k; Manager = manager; if (!String.IsNullOrWhiteSpace(masterSN)) { MasterSNString = masterSN; if (!MasterSNString.EndsWith("\0")) { MasterSNString += "\0"; } } else { int n = Convert.ToInt32(Manager.ShellId); MasterSNString = Settings.SerialNumberFormatter(Lima.GetComputerCode(), (char)(Primitives.NibbleToHexChar((byte)n)), '0'); } MasterSN = Primitives.StringToByteArray(MasterSNString); UpdateProductCode(MasterSN); SerialNumbersFreeHeap = new TokenAllocator(SerialNumbersSize); IoSerialNumbers = new SerialNumber[SerialNumbersSize]; for (k = 0; k < SerialNumbersSize; k++) { IoSerialNumbers[k] = new SerialNumber(); } }
public LinkDriver(NetIfManager manager, ILinkNetIf netIfDevice, byte netIfIndex, bool mappingEnabled, bool threaded, bool doesIO, bool hasTasks) { Manager = manager; IoNetIfDevice = netIfDevice; NetIfIndex = netIfIndex; MappingEnabled = mappingEnabled; DoesIO = doesIO; HasTasks = hasTasks; NumTasks = 0; DeviceContextIndex = 0; duplexKind = (byte)LinkMonitor.LINK_DUPLEX_KIND.LINK_DUPLEX_KIND_NONE; duplexApply = 0; Monitor = (DoesIO ? new LinkMonitor(this) : null); Parser = (DoesIO ? new PacketParser(this) : null); IOThreads = (threaded ? new LinkIOThreads(this) : null); NotStale = false; HasRead = false; SerialIndex = -1; SchedulerInterval = SchedulerIntervalDefault; ResponseInterval = ResponseIntervalDefault; LinkWriteQueue = new DequeBlockingCollection <int>(LinkWriteQSize, -1); LinkVerifyQueue = new DequeBlockingCollection <int>(LinkVerifyQSize, -1); LinkMissingQueue = new DequeBlockingCollection <byte>(LinkMissingQSize, ProtocolConstants.VNO_NULL); OutputMapBuffer = (mappingEnabled ? new byte[LinkMappingBufferSize] : null); ClearLinkDriver(); manager.SerialNumberManager.NetIfSerialNumberSetup(NetIfIndex); }
// Push message on to RNetIfIndex's Write Q. // Messages that cannot be posted are freed. public static void PostMessage(NetIfManager manager, int ioIndex, byte rNetIfIndex) { String dbgmsg = null; if (ioIndex == -1) { return; } LinkDriver p = manager.GetLinkDriver(rNetIfIndex); if (p == null) { rNetIfIndex = ProtocolConstants.NETIF_UNSET; } if ((p != null) || !isMaster) // Check destination netIf was not detached. { if (p == null) { p = manager.GetLinkDriver(ProtocolConstants.NETIF_BRIDGE_LINK); } if (p != null) { PacketBuffer b = manager.IoBuffers[ioIndex]; // Check for circular routing: examine prior destination netIf. if ((b.dNetIf != ProtocolConstants.NETIF_UNSET) && (b.dNetIf == rNetIfIndex)) { // Ignore circular messages. dbgmsg = String.Format("Circular message on netIf [{0}]: ditching message.", rNetIfIndex); } else { b.dNetIf = rNetIfIndex; if (p.NetIfIndex == ProtocolConstants.NETIF_BRIDGE_LINK) { byte netIfs = (byte)((rNetIfIndex << 4) | b.iNetIf); // Use destination to pass netIfs across bridge. b.destination((ushort)(((256 - netIfs) << 8) | netIfs)); } if (p.LinkWriteQueue.Push(ioIndex) != -1) // Check post queue not full. { if (Settings.DebugLevel > 6) { Log.d(TAG, "Posting:" + ioIndex + " to " + p.NetIfIndex); } return; } dbgmsg = String.Format("Write Q full on netIf [{0}]: ditching message.", rNetIfIndex); } } } // Messages that were not posted are freed. if (Settings.DebugLevel > 1) { Log.w(TAG, dbgmsg); } manager.IoBuffersFreeHeap.Release(ioIndex); }
public PacketParser(LinkDriver ltx) { IoNetIf = ltx; Manager = ltx.Manager; HandshakePacket = new PacketBuffer(ProtocolConstants.HANDSHAKE_PACKET_SIZE); InputBuffer = null; CurrentPacket = null; IoIndex = -1; ResetParser(); }
public static byte GetDeviceStatus(NetIfManager manager, byte[] buffer) { DeviceCheck(manager); String s = String.Format("F={0:x4},U={1:x4},S={2:x4}.", NumFreeIOBuffers, NumInUseIOBuffers, manager.IoBuffersFreeHeap.Capacity()); byte[] tmp = Primitives.StringToByteArray(s); int len = tmp.Length; Array.Copy(tmp, 0, buffer, ProtocolConstants.GENERAL_DATA_ARRAY_OFFSET, len); return((byte)len); }
public MediatorNetIf(NetIfManager manager, MessageExchange exchange) : base(manager, new VirtualDevice("Mediator"), ProtocolConstants.NETIF_MEDIATOR_PORT, false, true, false, true) { Exchange = exchange; SchedulerInterval = 1; IsoTaskQueue = new int[IsoTaskSize]; IsoTasks = new IsoTask[IsoTaskSize]; for (int k = 0; k < IsoTaskSize; ++k) { IsoTasks[k] = new IsoTask(); } InitTasks(); }
// Debug aid: loops over message Q, showing messages in buffer. public static string DumpPacketQueue(NetIfManager manager, DequeBlockingCollection <int> q) { String s = ""; DequeBlockingCollection <int> tmp = new DequeBlockingCollection <int>(q); int n = 0; int idx, count = q.Size(); while ((idx = tmp.Pop()) != -1) { PacketBuffer b = manager.IoBuffers[idx]; s += String.Format("{0:d}/{1:d}:cmd={2:x2}", n, count, b.command()); s += DumpMessage(b); ++n; } return(s); }
// Used for diagnostics. public static void DeviceCheck(NetIfManager manager) { NumInUseIOBuffers = 0; NumFreeIOBuffers = manager.IoBuffersFreeHeap.RemainingCapacity(); foreach (LinkDriver p in manager.IoNetIfs.Values) { NumInUseIOBuffers += p.LinkWriteQueue.Size(); NumInUseIOBuffers += p.LinkVerifyQueue.Size(); } int diff = manager.IoBuffersFreeHeap.Capacity() - NumFreeIOBuffers - NumInUseIOBuffers; if (diff > 4) // Allow for pipe being 2 bigger than num buffers + 1 task. { ++DeviceCheckCount; } }
public void Close() { IsClosing = true; if (DispatcherThread != null) { Primitives.Interrupt(DispatcherThread.Task); DispatcherThread = null; } if (ReceiverThread != null) { Primitives.Interrupt(ReceiverThread.Task); ReceiverThread = null; } if (Manager != null) { Manager.Close(); Manager = null; } }
// Route a message received from one of the NetIfs. // Requires posting to write Q of receiver NetIf. // Routing rules: // 1) Test receiver address (RA) and receiver port (RP). // 2) If RA=BabelConstants.ADRS_LOCAL or RA=NodeAdrs: // a) route to RP NetIf WriteQ. // 3) Otherwise: // a) check for gateway. // b) otherwise discard. // TODO: add support for gateway NetIfs. // Discards unroutable messages. // Frees message buffer as necessary. public static void RouteMessage(NetIfManager manager, int ioIndex) { PacketBuffer b; ushort receiver; byte rNetIf; if (ioIndex == -1) { return; } b = manager.IoBuffers[ioIndex]; switch (b.flagsPid & ProtocolConstants.PID_MASK) { case ProtocolConstants.PID_GENERAL: case ProtocolConstants.PID_GENERAL_V: receiver = b.receiver(); if ((b.flagsRS() & (ProtocolConstants.PORT_MASK << 2)) == (ProtocolConstants.PORT_BRIDGE << 2)) { rNetIf = isMaster ? ProtocolConstants.NETIF_BRIDGE_LINK : ProtocolConstants.NETIF_BRIDGE_PORT; } else { rNetIf = isMaster ? ProtocolConstants.NETIF_MEDIATOR_PORT : ProtocolConstants.NETIF_UNSET; } break; default: receiver = ProtocolConstants.ADRS_LOCAL; rNetIf = isMaster ? ProtocolConstants.NETIF_MEDIATOR_PORT : ProtocolConstants.NETIF_UNSET; break; } if ((receiver != ProtocolConstants.ADRS_LOCAL) && (receiver != manager.NodeAdrs)) { // Message needs to be routed to a remote address. // TODO: Check for gateway. // For now, return to sender or send to bridge. rNetIf = isMaster ? b.iNetIf : ProtocolConstants.NETIF_UNSET; } PostMessage(manager, ioIndex, rNetIf); }
public MessageTransaction(NetIfManager manager) { Manager = manager; }
public PacketFactory(NetIfManager manager) { Manager = manager; }
public LinkMonitor(LinkDriver ltx) { IoNetIf = ltx; Manager = ltx.Manager; NumMessagesRead = 0; }