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 SendRouteRequest(UInt16 tgtAddrShort)
        {
            Message.RoutingMessage rm = new Message.RoutingMessage();
            rm.IsRequest = true;
            rm.HopsLeft = cDefaultHopLimit;
            rm.HopCount = 0; // counter from originator, initially set to zero
            rm.MinLQI = 0xFF; // initial value
            rm.SeqNo = IncSeqNoDYMO();
            rm.TargetAddr = tgtAddrShort;
            rm.OriginatorAddr = _addrShort;

            SendRoutingMessage(rm);
        }
        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*/);
                        }
                    }
                }
            }
        }