private void updateRoutingTable() { List<VarID> sinkList = new List<VarID>(); // ONE route to each sink... _tableRouting.Clear(); // Start fresh. This list is a factor of valid data elsewhere. // Get all valid sink IDs foreach (PEQTableEntrySubscription subEntry in _tableSubscription) { if (!sinkList.Contains(subEntry._SinkID)) sinkList.Add(subEntry._SinkID); } // Find the best route to each sink. foreach (VarID sinkID in sinkList) { Byte best_hop = 0xFF; // Ensure that the best subEntry is added to the route. double best_time = 0; // Ensure that the most recent entry is used PEQTableEntrySubscription best_hopEntry = null; foreach (PEQTableEntrySubscription subEntry in _tableSubscription) { if (subEntry._HopCount <= best_hop) { if (subEntry._Timestamp >= best_time) { best_hop = subEntry._HopCount; best_time = subEntry._Timestamp; best_hopEntry = subEntry; } } } if (best_hopEntry != null) { PEQTableEntryRouting newRoute = new PEQTableEntryRouting(_NUM_ID_BYTES); newRoute._DestinationID = best_hopEntry._DestinationID; newRoute._SinkID = best_hopEntry._SinkID; newRoute._nextHopCheat = best_hopEntry._nextHopCheat; newRoute._Valid = best_hopEntry._Valid; _tableRouting.Add(newRoute); IGraphicalReport newRouteReport; if (best_hopEntry._CriteriaType == 0x0000) newRouteReport = GenerateDirectionReport(GetMessageLevel(new PEQMessageBuildTree())); else newRouteReport = GenerateDirectionReport(GetMessageLevel(new PEQMessageSubscribe())); if (newRouteReport != null) { if (currentRouteReport != null) { newRouteReport.ReportAction = MNS_Reporting.Action.Modify; newRouteReport.PreviousStatic = currentRouteReport; currentRouteReport = newRouteReport; Notify(newRouteReport); } else { currentRouteReport = GenerateDirectionReport(); if (currentRouteReport != null) Notify(currentRouteReport); } } else if (currentRouteReport != null) { LineReport dirReport = new LineReport(_eventManager.CurrentClock, (XYDoubleLocation)_location, (XYDoubleLocation)newRoute._nextHopCheat, 0, -250, true, -_id.GetID()); dirReport.PreviousStatic = currentRouteReport; dirReport.ReportAction = MNS_Reporting.Action.Stop; Notify(dirReport); currentRouteReport = null; } } } }
private void completeSearch(PEQTableEntrySearch winner) { PEQTableEntryRouting outRoute = null; if (winner == null) return; // should perform completeSearch(sinkID) first! bool found = false; // End Search, Update Route foreach (PEQTableEntryRouting route in _tableRouting) { if ((route._SinkID == winner._SinkID) && (!route._Valid)) { found = true; route._Valid = true; route._DestinationID = winner._DestinationID; route._nextHopCheat = winner._nextHopCheat; outRoute = route; } } // Add route if (!found) { PEQTableEntryRouting route = new PEQTableEntryRouting(_NUM_ID_BYTES); route._DestinationID = winner._DestinationID; route._SinkID = winner._SinkID; route._nextHopCheat = winner._nextHopCheat; _tableRouting.Add(route); outRoute = route; } updateRoutingTable(); if (winner._DataMessage is PEQMessageNotify) sendNotify(outRoute, (PEQMessageNotify)winner._DataMessage); }
private void sendNotify(PEQTableEntryRouting Route, PEQMessageNotify msg) { PEQMessageNotify newMsg = (PEQMessageNotify)msg.Clone(); newMsg._SenderID = _id; newMsg._SequenceNumber = _sequenceNumber++; newMsg._DestinationID = Route._DestinationID; newMsg._nextHopCheat = _location; newMsg._Data._NumHops++; newMsg._Data._TotalDistance += _location.Distance(msg._nextHopCheat); PEQTimerMessage timerEvent = new PEQTimerMessage(newMsg, _eventManager.CurrentClock + _TIMER_WAIT_SEND, this); _eventManager.AddEvent(timerEvent); }