示例#1
0
        public void DataRequest(
            UInt16 targetAddr,
            ref Frame sdu,
            Byte sduHandle,
            DataConfirmHandler handler)
        {
            if (targetAddr == _addrShort)
            {
                // deliver frame to ourself
                if (handler != null)
                    handler.Invoke(_net, sduHandle, Status.Success);

                _data.HandleDataIndication(targetAddr, targetAddr, ref sdu);
            }
            else
            {
                // encapsulate and sent as 6LoWPAN
                Message.Data data = new Message.Data();
                if (data.WriteToFrameHeader(sdu))
                {
                    DataRequest6LoWPAN(targetAddr, ref sdu, sduHandle, handler);
                }
                else
                {
                    if (handler != null)
                        handler.Invoke(_net, sduHandle, Status.InvalidFrame);
                }
            }

            Frame.Release(ref sdu);
        }
示例#2
0
        public void DataRequest(
            MacAddressingMode srcAddrMode,
            MacAddress dstAddr,
            UInt16 dstPanId,
            ref Frame msdu,
            Byte msduHandle,
            TxOptions options,
            SecurityOptions securityOptions,
            DataConfirmHandler handler)
        {
            TaskDataRequest task = new TaskDataRequest(
                srcAddrMode,
                dstAddr,
                dstPanId,
                msdu,
                msduHandle,
                options,
                securityOptions,
                handler);

            if (!_taskQueue.Add(task))
            {
                Frame.Release(ref msdu);
                if (handler != null)
                {
                    handler.Invoke(this, msduHandle, MacEnum.Congested);
                }
            }

            msdu = null; // in any case, remove frame ownership from caller
        }
示例#3
0
 /// <summary>
 /// Send 6LoWPAN SDU to another device.
 /// SDU must begin with a valid dispatch value and not contain any mesh header or brodcast header.
 /// </summary>
 /// <param name="targetShortAddr">targetAddr node, use 0xFFFF for broadcasting</param>
 /// <param name="sdu">data to send. Must have sufficient space in head/tail as indicated by GetFrameHeaders.</param>
 /// <param name="sduHandle">user-defined handle that is provided in result handler to identify the sdu.</param>
 /// <param name="handler">handler for result</param>
 public void DataRequest6Low(
     UInt16 targetShortAddr,
     ref Frame sdu,
     Byte sduHandle,
     DataConfirmHandler handler)
 {
     _route.DataRequest6LoWPAN(targetShortAddr, ref sdu, sduHandle, handler);
 }
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="targetShortAddr">destination short address</param>
 /// <param name="sdu">data to send</param>
 /// <param name="sduHandle">handle associated to sdu</param>
 /// <param name="handler">handler used to notify when message transmission is finished</param>
 public DataRequestItem(ushort targetShortAddr, ref Frame sdu, byte sduHandle, DataConfirmHandler handler)
 {
     _targetShortAddress = targetShortAddr;
     _sdu = sdu;
     sdu = null; // take ownership of the frame
     _sduHandle = sduHandle;
     _handler = handler;
 }
示例#5
0
 private void MacDataRequest(
     UInt16 nextHopAddr,
     ref Frame sdu,
     Byte sduHandle,
     DataConfirmHandler handler)
 {
     MacDataRequestReal(false, nextHopAddr, 0, ref sdu, sduHandle, handler);
 }
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="targetShortAddr">destination short address</param>
 /// <param name="sdu">data to send</param>
 /// <param name="sduHandle">handle associated to sdu</param>
 /// <param name="handler">handler used to notify when message transmission is finished</param>
 public DataRequestItem(ushort targetShortAddr, ref Frame sdu, byte sduHandle, DataConfirmHandler handler)
 {
     _targetShortAddress = targetShortAddr;
     _sdu       = sdu;
     sdu        = null; // take ownership of the frame
     _sduHandle = sduHandle;
     _handler   = handler;
 }
示例#7
0
 /// <summary>
 /// discard queued data at local node
 /// </summary>
 /// <param name="target">target node of message</param>
 /// <param name="sduHandle">sdu handle of message</param>
 /// <param name="handler">confirmation handler provided for message</param>
 /// <param name="isControlMsg">true if message is control message</param>
 public void DataRequestTimeout(
     UInt16 target,
     Byte sduHandle,
     DataConfirmHandler handler,
     bool isControlMsg)
 {
     if (handler != null)
         handler.Invoke(_net, sduHandle, Status.NoRoute);
 }
示例#8
0
        /// <summary>
        /// Send SDU to another device.
        /// </summary>
        /// <param name="targetShortAddr">targetAddr node, use 0xFFFF for broadcasting</param>
        /// <param name="sdu">data to send. Must have sufficient space in head/tail as indicated by GetFrameHeaders.</param>
        /// <param name="sduHandle">user-defined handle that is provided in result handler to identify the sdu.</param>
        /// <param name="handler">handler for result</param>
        public void DataRequest(
            UInt16 targetShortAddr,
            ref Frame sdu,
            Byte sduHandle,
            DataConfirmHandler handler)
        {
#if USE_FRAG
            _frag.DataRequest(targetShortAddr, ref sdu, sduHandle, handler);
#else
            _route.DataRequest(targetShortAddr, ref sdu, sduHandle, handler);
#endif
        }
示例#9
0
        public void DataRequest6LoWPAN(
            UInt16 targetAddr,
            ref Frame sdu,
            Byte sduHandle,
            DataConfirmHandler handler)
        {
            Status result = Status.Success;
            if (sdu == null || sdu.LengthHeaderAvail < _netHeader6Low || sdu.LengthDataAvail < _netTailer6Low || sdu.LengthDataUsed > _netMtu6Low)
            {
                result = Status.InvalidFrame;
            }
            else if (!_isRunning)
            {
                result = Status.NotRunning;
            }
            else
            {
                if (targetAddr == _addrShort)
                {
                    // deliver frame to ourself
                    if (handler != null)
                        handler.Invoke(_net, sduHandle, Status.Success);

                    _data.HandleDataIndication(targetAddr, targetAddr, ref sdu);
                }
                else
                {
                    // send frame to another node
                    if (IsMulticast(targetAddr))
                    {
                        SendData(_addrShort, targetAddr, cBroadcastShortAddr, ref sdu, sduHandle, handler);
                    }
                    else
                    {
                        // unicast
                        _routingTable.DataRequest(targetAddr, ref sdu, sduHandle, handler, false);
                    }
                }
            }

            if (result != Status.Success)
            { // perform callback
                if (handler != null)
                    handler.Invoke(_net, sduHandle, result);
            }

            Frame.Release(ref sdu);
        }
示例#10
0
 /// <summary>
 /// trigger data transmission from local node
 /// </summary>
 /// <param name="targetAddr">target node</param>
 /// <param name="nextHopAddr">next hop address</param>
 /// <param name="sdu">data to send</param>
 /// <param name="sduHandle">handle to use in confirmation message</param>
 /// <param name="handler">confirmation handler</param>
 /// <param name="isControlMsg">true is message is control message, so no additional header will be added</param>
 public void DataRequest(
     UInt16 targetAddr,
     UInt16 nextHopAddr,
     ref Frame sdu,
     Byte sduHandle,
     DataConfirmHandler handler,
     bool isControlMsg)
 {
     if (isControlMsg)
     {
         MacDataRequest(nextHopAddr, ref sdu); // do not add any headers
     }
     else
     {
         SendData(_addrShort, targetAddr, nextHopAddr, ref sdu, sduHandle, handler);
     }
 }
示例#11
0
        /// <summary>
        /// Adds broadcast/mesh headers and sends SDU to MAC
        /// </summary>
        /// <returns>True on success</returns>
        private void SendData(
            UInt16 orgAddr,
            UInt16 tgtAddr,
            UInt16 nextHopAddr,
            ref Frame sdu,
            Byte sduHandle,
            DataConfirmHandler handler)
        {
            bool success = false;
            if (orgAddr != cInvalidShortAddr)
            {
                bool ok = true;
                bool multicast = false;
                if (IsMulticast(tgtAddr))
                {
                    multicast = true;
                    Messages6LoWPAN.BroadcastHeader bh = new Messages6LoWPAN.BroadcastHeader();
                    bh.seqNo = IncSeqNoBroadcast();
                    ok = bh.WriteToFrameHeader(sdu);
                }

                if (ok && (multicast || (tgtAddr != nextHopAddr)))
                {
                    // add mesh header
                    Messages6LoWPAN.MeshHeader mh = new Messages6LoWPAN.MeshHeader();
                    mh.originatorAddress = orgAddr;
                    mh.finalAddress = tgtAddr;
                    mh.HopsLeft = cDefaultHopLimit;
                    ok = mh.WriteToFrameHeader(sdu);
                }

                if (ok)
                {
                    MacDataRequest(nextHopAddr, ref sdu, sduHandle, handler);
                    success = true;
                }
            }

            Frame.Release(ref sdu);
            if (!success && handler != null)
                handler.Invoke(_net, sduHandle, Status.Busy);
        }
示例#12
0
 public TaskDataRequest(
     MacAddressingMode srcAddrMode,
     MacAddress dstAddr,
     UInt16 dstPANId,
     Frame msdu,
     Byte msduHandle,
     TxOptions options,
     SecurityOptions securityOptions,
     DataConfirmHandler handler)
     : base(TaskType.DataRequest)
 {
     this.srcAddrMode     = srcAddrMode;
     this.dstAddr         = dstAddr;
     this.dstPANId        = dstPANId;
     this.msdu            = msdu;
     this.msduHandle      = msduHandle;
     this.options         = options;
     this.securityOptions = securityOptions;
     this.handler         = handler;
 }
示例#13
0
 public TaskDataRequest(
     MacAddressingMode srcAddrMode,
     MacAddress dstAddr,
     UInt16 dstPANId,
     Frame msdu,
     Byte msduHandle,
     TxOptions options,
     SecurityOptions securityOptions,
     DataConfirmHandler handler)
     : base(TaskType.DataRequest)
 {
     this.srcAddrMode = srcAddrMode;
     this.dstAddr = dstAddr;
     this.dstPANId = dstPANId;
     this.msdu = msdu;
     this.msduHandle = msduHandle;
     this.options = options;
     this.securityOptions = securityOptions;
     this.handler = handler;
 }
示例#14
0
        public void DataRequest(ushort targetShortAddr, ref Frame sdu, byte sduHandle, DataConfirmHandler handler)
        {
            if (!_started)
            {
                if (handler != null)
                {
                    handler.Invoke(this, sduHandle, Status.NotRunning);
                }

                return;
            }

            if (targetShortAddr == _localShortAddress)
            {
                // deliver frame to ourself
                if (handler != null)
                {
                    handler.Invoke(this, sduHandle, Status.Success);
                }

                DataIndicationHandler ind = _dataIndicationHandler;
                if (ind != null)
                {
                    ind.Invoke(this, targetShortAddr, targetShortAddr, sdu);
                    sdu = null;
                }

                return;
            }

            DataRequestItem newItem = new DataRequestItem(targetShortAddr, ref sdu, sduHandle, handler);

            OutboundFragmentationMessage outMsg = null;
            bool queueFull = false;
            lock (_lock)
            {
                // check if one can send directly the message.
                if (null == _outboundAssociations.GetFragmentationMessage(_localShortAddress, targetShortAddr))
                {
                    outMsg = CreateNewOutboundMessage(newItem);
                }
                else
                {
                    // there is already a message being sent to this address. Store to queue.
                    if (!_dataRequestQueueSet.Add(newItem))
                    {
                        queueFull = true;

                    }
                }
            }

            // release the lock before calling method in FragmentMessage class
            if (outMsg != null)
            {
                outMsg.SendNextDataFragment(true);
            }
            else if (queueFull)
            {
                // queue is full.
                if (handler != null)
                {
                    handler.Invoke(this, sduHandle, Status.Busy);
                }

                newItem.Dispose();
            }
        }
示例#15
0
        /// <summary>
        /// Send SDU to another device.
        /// </summary>
        /// <param name="targetShortAddr">targetAddr node, use 0xFFFF for broadcasting</param>
        /// <param name="sdu">data to send. Must have sufficient space in head/tail as indicated by GetFrameHeaders.</param>
        /// <param name="sduHandle">user-defined handle that is provided in result handler to identify the sdu.</param>
        /// <param name="handler">handler for result</param>
        public void DataRequest(
            UInt16 targetShortAddr,
            ref Frame sdu,
            Byte sduHandle,
            DataConfirmHandler handler)
        {
#if USE_FRAG
            _frag.DataRequest(targetShortAddr, ref sdu, sduHandle, handler);
#else
            _route.DataRequest(targetShortAddr, ref sdu, sduHandle, handler);
#endif
        }
示例#16
0
        /// <summary>
        /// Send a Mac SDU using context information. SrcAddr is automatically choosen.
        /// </summary>
        /// <param name="msdu">The frame to sent.</param>
        /// <param name="context">Sent context. If null, frame is broadcasted</param>
        private void MacDataRequestReal(
            bool useExtAddr,
            UInt16 nextHopAddrShort,
            UInt64 nextHopAddrExt,
            ref Frame sdu,
            Byte sduHandle,
            DataConfirmHandler handler)
        {
            // srcAddr: always use short addr when available
            MacAddressingMode srcAddrMode = new MacAddressingMode();
            if (_addrShort == cUnallocatedShortAddr)
                srcAddrMode = MacAddressingMode.ExtendedAddress;
            else
                srcAddrMode = MacAddressingMode.ShortAddress;

            MacAddress dstAddr = new MacAddress();
            if (useExtAddr)
                dstAddr.ExtendedAddress = nextHopAddrExt;
            else
                dstAddr.ShortAddress = nextHopAddrShort;

            byte msduHandle;
            Mac.DataConfirmHandler macHandler;

            bool broadcast = (!useExtAddr) && IsMulticast(nextHopAddrShort);
            if (!broadcast || handler != null)
            { // need a send context
                MessageContext.Context context = _messageContext.GetFreeContext();
                if (context == null)
                { // busy
                    if (handler != null)
                        handler.Invoke(_net, sduHandle, Status.Busy);
                    Frame.Release(ref sdu);
                    return;
                }

                context.useExtAddr = useExtAddr;
                context.nextHopShort = nextHopAddrShort;
                context.nextHopExt = nextHopAddrExt;
                context.dataSduHandle = sduHandle;
                context.dataHandler = handler;

                macHandler = MacDataConfirmHandler;
                msduHandle = context.macSduHandle;
            }
            else
            {
                macHandler = null;
                msduHandle = MessageContext.cHandleDontCare;
            }

            TxOptions tx = new TxOptions();
            if (!broadcast)
                tx.AcknowledgedTransmission = true;

            _mac.DataRequest(
                srcAddrMode,
                dstAddr,
                _panId,
                ref sdu,
                msduHandle,
                tx,
                new SecurityOptions(),
                macHandler);
            Frame.Release(ref sdu);
        }
示例#17
0
        /// <summary>
        /// To send sdu from local node
        /// </summary>
        /// <param name="tgtAddrExt"></param>
        /// <param name="sduHandle"></param>
        /// <param name="sdu"></param>
        /// <param name="handler"></param>
        public void DataRequest(
            UInt16 targetAddr,
            ref Frame sdu,
            Byte sduHandle,
            DataConfirmHandler handler,
            bool isControlMsg)
        {
            lock (_lock)
            {
                int i = FindTargetAddr(targetAddr);
                Entry entry;
                if (i == -1)
                {
                    // create new entry
                    entry = AddEntry(targetAddr);
                }
                else
                {
                    entry = _table[i] as Entry;
                }

                bool doRouteRequest = false;

                if (entry.nextHopAddr == cInvalidAddr || entry.routeHasError)
                { // no route to targetAddr
                    // queue this message
                    if (entry.pendingMessages.Count == cMaxPendingMsg)
                    { // delete oldest waiting msg
                        PendingMessage pmOld = (PendingMessage)entry.pendingMessages[0];
                        entry.pendingMessages.RemoveAt(0);
                        _routing.DataRequestTimeout(targetAddr, pmOld.sduHandle, pmOld.handler, pmOld.isControlMsg);
                        Frame.Release(ref pmOld.sdu);
                    }

                    PendingMessage pm = new PendingMessage();
                    pm.sdu = sdu;
                    sdu = null;
                    pm.sduHandle = sduHandle;
                    pm.handler = handler;
                    pm.isControlMsg = isControlMsg;
                    entry.pendingMessages.Add(pm);

                    doRouteRequest = true;
                }
                else
                {
                    entry.routeInUse = true;
                    _routing.DataRequest(targetAddr, entry.nextHopAddr, ref sdu, sduHandle, handler, isControlMsg);

                    if (entry.routeHasError)
                    {
                        doRouteRequest = true;
                        entry.routeHasError = false;
                    }
                }

                if (doRouteRequest)
                {
                    // initiate route request
                    if (!entry.routePending)
                    {
                        // we haven't asked for a route yet, start now
                        entry.routePending = true;
                        entry.requestRetryCnt = cRouteRequestRetryCnt;
                        entry.timeOutSet = cRouteRequestWaitTime;
                        _timerEvent.Set();
                        Trace.Print("Sending route request for 0x" + HexConverter.ConvertUintToHex(entry.targetAddr, 4) + " for data");
                        _routing.RouteRequest(targetAddr);
                    } // else: wait for ongoing request
                }
            }
        }
示例#18
0
文件: Mac.cs 项目: prabby/miniclr
        public void DataRequest(
            MacAddressingMode srcAddrMode,
            MacAddress dstAddr,
            UInt16 dstPanId,
            ref Frame msdu,
            Byte msduHandle,
            TxOptions options,
            SecurityOptions securityOptions,
            DataConfirmHandler handler)
        {
            TaskDataRequest task = new TaskDataRequest(
                srcAddrMode,
                dstAddr,
                dstPanId,
                msdu,
                msduHandle,
                options,
                securityOptions,
                handler);
            if (!_taskQueue.Add(task))
            {
                Frame.Release(ref msdu);
                if (handler != null)
                    handler.Invoke(this, msduHandle, MacEnum.Congested);
            }

            msdu = null; // in any case, remove frame ownership from caller
        }
        internal OutboundFragmentationMessage(
            UInt16 source,
            UInt16 destination,
            byte messageSeqNumber,
            DataRequestHandler lowerLayerRequestHandler,
            ref Frame sdu,
            Byte sduHandle,
            DataConfirmHandler handler,
            int maxPduSize,
            int reservedHeaderSize,
            int reservedTailSize,
            FragmentationMessageTimer timer
            )
            : base(source, destination, messageSeqNumber, lowerLayerRequestHandler, maxPduSize, reservedHeaderSize, reservedTailSize, timer)
        {
            if (sdu.LengthDataUsed == 0)
            {
                Frame.Release(ref sdu);
                throw new ArgumentException("sdu is empty", "sdu");
            }

            int payloadSize = maxPduSize - 2 - 2; // 2 for our own header, 1 for nb fragment, 1 for fragment id

            if (payloadSize == 0)
            {
                Frame.Release(ref sdu);
                throw new ArgumentException("PDU is too small", "maxPduSize");
            }

            ushort flag = (ushort)(1 << 15);

            _isBroadcast = (destination & flag) > 0 ? true : false;

            _sdu                   = sdu;
            sdu                    = null;
            _sduHandle             = sduHandle;
            _dataConfirmHandler    = handler;
            _messageSeqNumber      = messageSeqNumber;
            _timeoutForResending   = c_defaultTimeoutForResending;
            _maxFragmentsBeforeAck = c_defaultMaxFragmentsBeforeAck;
            // compute required nb fragments and respective indices.

            int nbFragments = ((_sdu.LengthDataUsed % payloadSize) == 0) ? _sdu.LengthDataUsed / payloadSize : 1 + _sdu.LengthDataUsed / payloadSize;

            if (nbFragments > byte.MaxValue)
            {
                throw new ArgumentException("sdu is too large.");
            }
            _nbFragments   = (byte)nbFragments;
            _endingIndices = new int[_nbFragments];
            int lastIndex = -1;

            for (int i = 0; i + 1 < _nbFragments; i++)
            {
                lastIndex        += payloadSize;
                _endingIndices[i] = lastIndex;
            }

            lastIndex += ((_sdu.LengthDataUsed % payloadSize) == 0) ? payloadSize : _sdu.LengthDataUsed % payloadSize;
            _endingIndices[_nbFragments - 1]  = lastIndex;
            _successfullyTransmittedFragments = new BitArray(_nbFragments, false);
            _lastFragmentSent = new BitArray(_nbFragments, false);
        }
示例#20
0
        public void DataRequest(ushort targetShortAddr, ref Frame sdu, byte sduHandle, DataConfirmHandler handler)
        {
            if (!_started)
            {
                if (handler != null)
                {
                    handler.Invoke(this, sduHandle, Status.NotRunning);
                }

                return;
            }

            if (targetShortAddr == _localShortAddress)
            {
                // deliver frame to ourself
                if (handler != null)
                {
                    handler.Invoke(this, sduHandle, Status.Success);
                }

                DataIndicationHandler ind = _dataIndicationHandler;
                if (ind != null)
                {
                    ind.Invoke(this, targetShortAddr, targetShortAddr, sdu);
                    sdu = null;
                }

                return;
            }

            DataRequestItem newItem = new DataRequestItem(targetShortAddr, ref sdu, sduHandle, handler);

            OutboundFragmentationMessage outMsg = null;
            bool queueFull = false;

            lock (_lock)
            {
                // check if one can send directly the message.
                if (null == _outboundAssociations.GetFragmentationMessage(_localShortAddress, targetShortAddr))
                {
                    outMsg = CreateNewOutboundMessage(newItem);
                }
                else
                {
                    // there is already a message being sent to this address. Store to queue.
                    if (!_dataRequestQueueSet.Add(newItem))
                    {
                        queueFull = true;
                    }
                }
            }

            // release the lock before calling method in FragmentMessage class
            if (outMsg != null)
            {
                outMsg.SendNextDataFragment(true);
            }
            else if (queueFull)
            {
                // queue is full.
                if (handler != null)
                {
                    handler.Invoke(this, sduHandle, Status.Busy);
                }

                newItem.Dispose();
            }
        }
        internal OutboundFragmentationMessage(
            UInt16 source,
            UInt16 destination,
            byte messageSeqNumber,
            DataRequestHandler lowerLayerRequestHandler,
            ref Frame sdu,
            Byte sduHandle,
            DataConfirmHandler handler,
            int maxPduSize,
            int reservedHeaderSize,
            int reservedTailSize,
            FragmentationMessageTimer timer
            )
            : base(source, destination, messageSeqNumber, lowerLayerRequestHandler, maxPduSize, reservedHeaderSize, reservedTailSize, timer)
        {
            if (sdu.LengthDataUsed == 0)
            {
                Frame.Release(ref sdu);
                throw new ArgumentException("sdu is empty", "sdu");
            }

            int payloadSize = maxPduSize - 2 - 2; // 2 for our own header, 1 for nb fragment, 1 for fragment id
            if (payloadSize == 0)
            {
                Frame.Release(ref sdu);
                throw new ArgumentException("PDU is too small", "maxPduSize");
            }

            ushort flag = (ushort)(1 << 15);
            _isBroadcast = (destination & flag) > 0 ? true : false;

            _sdu = sdu;
            sdu = null;
            _sduHandle = sduHandle;
            _dataConfirmHandler = handler;
            _messageSeqNumber = messageSeqNumber;
            _timeoutForResending = c_defaultTimeoutForResending;
            _maxFragmentsBeforeAck = c_defaultMaxFragmentsBeforeAck;
            // compute required nb fragments and respective indices.

            int nbFragments = ((_sdu.LengthDataUsed % payloadSize) == 0) ? _sdu.LengthDataUsed / payloadSize : 1 + _sdu.LengthDataUsed / payloadSize;
            if (nbFragments > byte.MaxValue)
                throw new ArgumentException("sdu is too large.");
            _nbFragments = (byte)nbFragments;
            _endingIndices = new int[_nbFragments];
            int lastIndex = -1;
            for (int i = 0; i + 1 < _nbFragments; i++)
            {
                lastIndex += payloadSize;
                _endingIndices[i] = lastIndex;
            }

            lastIndex += ((_sdu.LengthDataUsed % payloadSize) == 0) ? payloadSize : _sdu.LengthDataUsed % payloadSize;
            _endingIndices[_nbFragments - 1] = lastIndex;
            _successfullyTransmittedFragments = new BitArray(_nbFragments, false);
            _lastFragmentSent = new BitArray(_nbFragments, false);
        }
示例#22
0
        /// <summary>
        /// To send sdu from local node
        /// </summary>
        /// <param name="tgtAddrExt"></param>
        /// <param name="sduHandle"></param>
        /// <param name="sdu"></param>
        /// <param name="handler"></param>
        public void DataRequest(
            UInt16 targetAddr,
            ref Frame sdu,
            Byte sduHandle,
            DataConfirmHandler handler,
            bool isControlMsg)
        {
            lock (_lock)
            {
                int   i = FindTargetAddr(targetAddr);
                Entry entry;
                if (i == -1)
                {
                    // create new entry
                    entry = AddEntry(targetAddr);
                }
                else
                {
                    entry = _table[i] as Entry;
                }

                bool doRouteRequest = false;

                if (entry.nextHopAddr == cInvalidAddr || entry.routeHasError)
                { // no route to targetAddr
                    // queue this message
                    if (entry.pendingMessages.Count == cMaxPendingMsg)
                    { // delete oldest waiting msg
                        PendingMessage pmOld = (PendingMessage)entry.pendingMessages[0];
                        entry.pendingMessages.RemoveAt(0);
                        _routing.DataRequestTimeout(targetAddr, pmOld.sduHandle, pmOld.handler, pmOld.isControlMsg);
                        Frame.Release(ref pmOld.sdu);
                    }

                    PendingMessage pm = new PendingMessage();
                    pm.sdu          = sdu;
                    sdu             = null;
                    pm.sduHandle    = sduHandle;
                    pm.handler      = handler;
                    pm.isControlMsg = isControlMsg;
                    entry.pendingMessages.Add(pm);

                    doRouteRequest = true;
                }
                else
                {
                    entry.routeInUse = true;
                    _routing.DataRequest(targetAddr, entry.nextHopAddr, ref sdu, sduHandle, handler, isControlMsg);

                    if (entry.routeHasError)
                    {
                        doRouteRequest      = true;
                        entry.routeHasError = false;
                    }
                }

                if (doRouteRequest)
                {
                    // initiate route request
                    if (!entry.routePending)
                    {
                        // we haven't asked for a route yet, start now
                        entry.routePending    = true;
                        entry.requestRetryCnt = cRouteRequestRetryCnt;
                        entry.timeOutSet      = cRouteRequestWaitTime;
                        _timerEvent.Set();
                        Trace.Print("Sending route request for 0x" + HexConverter.ConvertUintToHex(entry.targetAddr, 4) + " for data");
                        _routing.RouteRequest(targetAddr);
                    } // else: wait for ongoing request
                }
            }
        }
示例#23
0
 /// <summary>
 /// Send 6LoWPAN SDU to another device.
 /// SDU must begin with a valid dispatch value and not contain any mesh header or brodcast header.
 /// </summary>
 /// <param name="targetShortAddr">targetAddr node, use 0xFFFF for broadcasting</param>
 /// <param name="sdu">data to send. Must have sufficient space in head/tail as indicated by GetFrameHeaders.</param>
 /// <param name="sduHandle">user-defined handle that is provided in result handler to identify the sdu.</param>
 /// <param name="handler">handler for result</param>
 public void DataRequest6Low(
     UInt16 targetShortAddr,
     ref Frame sdu,
     Byte sduHandle,
     DataConfirmHandler handler)
 {
     _route.DataRequest6LoWPAN(targetShortAddr, ref sdu, sduHandle, handler);
 }