private void SendRoutingMessage(Message.RoutingMessage rm) { Frame frame = Frame.GetFrame(_macHeader + Message.RoutingMessage.cLength + _macTailer); if (frame == null) return; frame.ReserveHeader(_macHeader); if (!rm.WriteToFrame(frame)) { Frame.Release(ref frame); return; } bool ok; UInt16 nextHop; if (rm.IsRequest) { ok = true; nextHop = cBroadcastShortAddr; } else { ok = _routingTable.GetRoute(rm.TargetAddr, out nextHop); } if (ok) { Trace.Print("Sending " + rm.ToString()); MacDataRequest(nextHop, ref frame); } Frame.Release(ref frame); }
private void HandleRoutingMessage( MacAddress srcAddr, MacAddress dstAddr, ref Frame sdu, byte lqi) { Message.RoutingMessage rm = new Message.RoutingMessage(); if (srcAddr.Mode == MacAddressingMode.ShortAddress && rm.ReadFromFrame(sdu)) { Trace.Print("Received: " + rm.ToString()); rm.HopCount++; _neighbourTable.UpdateLqi(srcAddr.ShortAddress, lqi); if (rm.OriginatorAddr == _addrShort) // ignore message originating from us return; // use bidirectional quality indicator if (!_neighbourTable.IsNeighbor(srcAddr.ShortAddress, out lqi)) lqi = 0; if (lqi < rm.MinLQI) rm.MinLQI = lqi; bool usefull = _routingTable.UpdateRoute(rm.OriginatorAddr, srcAddr.ShortAddress, rm.SeqNo, rm.HopCount, rm.MinLQI); bool send = false; if (rm.TargetAddr == _addrShort) { // message directed to us if (usefull && rm.IsRequest) { // respond to message Message.RoutingMessage rrep = new Message.RoutingMessage(); rrep.IsRequest = false; rrep.HopsLeft = cDefaultHopLimit; rrep.HopCount = 0; rrep.MinLQI = 0xFF; rrep.SeqNo = _seqNoDYMO; rrep.TargetAddr = rm.OriginatorAddr; rrep.OriginatorAddr = _addrShort; rm = rrep; send = true; } } else { // message directed to someone else. // alays forward route response, forward route request when usefull if (!rm.IsRequest) usefull = true; if (usefull && rm.HopsLeft > 0) { rm.HopsLeft--; send = true; } } if (send) { if (rm.IsRequest) { SendRoutingMessage(rm); // RReq is broadcast } else { // RRep is unicast UInt16 nextHop; if (_routingTable.GetRoute(rm.TargetAddr, out nextHop)) { SendRoutingMessage(rm); } else { // no route to forward this message. someone has a stale routing table! SendRouteError(rm.OriginatorAddr, rm.TargetAddr, true /*fatal*/); } } } } }