Пример #1
0
        private void HandleFragmentationMessageTerminated(object sender, FragmentationMessageTerminatedEventArgs args)
        {
            if (sender is InboundFragmentationMessage)
            {
                if ((args.FinalState != FragmentationMessageState.Final) || (args.FinalStatus != Status.Success))
                {
                    // do nothing.
                    return;
                }

                InboundFragmentationMessage inMsg = sender as InboundFragmentationMessage;

                Frame receivedMessage = inMsg.RetrieveData();

                if (receivedMessage != null)
                {
                    DataIndicationHandler handler = _dataIndicationHandler;
                    if (handler != null)
                    {
                        handler.Invoke(this, inMsg.Source, inMsg.Destination, receivedMessage);
                    }
                    else
                    {
                        Frame.Release(ref receivedMessage);
                    }
                }
            }
            else if (sender is OutboundFragmentationMessage)
            {
                OutboundFragmentationMessage outMsg, newOutMsg;
                lock (_lock)
                {
                    outMsg = sender as OutboundFragmentationMessage;
                    ushort previousDestination = outMsg.Destination;
                    _transmissionCharacteristicStorage.UpdateTransmissionCharacteristic(outMsg.Destination, outMsg.TimeoutForResending,
                                                                                        outMsg.MaxFragmentsBeforeAck);
                    // remove active message from repository
                    _outboundAssociations.RemoveFragmentationMessage(outMsg);
                    // try to start new message (if possible)
                    DataRequestItem newItem;
                    newOutMsg = null;
                    if (_dataRequestQueueSet.Dequeue(previousDestination, out newItem))
                    {
                        newOutMsg = CreateNewOutboundMessage(newItem);
                    }
                }

                // after releasing the lock, call method in FragmentationMessage class.
                outMsg.NotifySender(args.FinalState, args.FinalStatus);
                outMsg.Dispose();

                if (newOutMsg != null)
                {
                    newOutMsg.SendNextDataFragment(true);
                }
            }
        }
 public void HandleDataIndication6Low(UInt16 origAddr, UInt16 targetAddr, ref Frame sdu)
 {
     DataIndicationHandler ind = _dataIndicationHandler6Low;
     if (ind != null)
     {
         ind.Invoke(this, origAddr, targetAddr, sdu);
         sdu = null;
     }
 }
Пример #3
0
        public void HandleDataIndication(UInt16 origAddr, UInt16 targetAddr, ref Frame sdu)
        {
#if USE_FRAG
            _frag.HandleLowerLayerDataIndication(this, origAddr, targetAddr, sdu);
            sdu = null;
#else
            DataIndicationHandler ind = _dataIndicationHandler;
            if (ind != null)
            {
                ind.Invoke(this, origAddr, targetAddr, sdu);
                sdu = null;
            }
#endif
        }
Пример #4
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();
            }
        }
Пример #5
0
        private void ReceiveData(
            Header hdr,
            ref Frame frame,
            Byte linkQuality)
        {
            MacAddress srcAddr  = new MacAddress(); // default: NoAddress
            MacAddress dstAddr  = new MacAddress(); // default: NoAddress
            UInt16     srcPanId = State.cBroadcastPanId;
            UInt16     dstPanId = State.cBroadcastPanId;

            bool drop = (hdr.fcs.Version != Microsoft.SPOT.Wireless.IEEE_802_15_4.Mac.Frames.Version.IEEE2003 &&
                         hdr.fcs.Version != Microsoft.SPOT.Wireless.IEEE_802_15_4.Mac.Frames.Version.IEEE2006);

            if (!drop)
            {
                switch (hdr.fcs.DstAddrMode)
                {
                case AddressingMode.None:
                    if (!_state.macPromiscousMode && !_state.panCoordinator)
                    {
                        drop = true;
                    }
                    break;

                case AddressingMode.Short:
                    if (!_state.macPromiscousMode &&
                        ((hdr.dstAddrShort != _state.macShortAddr && hdr.dstAddrShort != State.cBroadcastShortAddr) ||
                         (hdr.dstPanId != _state.macPanId && hdr.dstPanId != State.cBroadcastPanId)))
                    {
                        drop = true;
                    }
                    else
                    {
                        dstAddr.ShortAddress = hdr.dstAddrShort;
                        dstPanId             = hdr.dstPanId;
                    }
                    break;

                case AddressingMode.Extended:
                    if (!_state.macPromiscousMode &&
                        ((hdr.dstAddrExt != _state.aExtendedAddress ||
                          (hdr.dstPanId != _state.macPanId && hdr.dstPanId != State.cBroadcastPanId))))
                    {
                        drop = true;
                    }
                    else
                    {
                        dstAddr.ExtendedAddress = hdr.dstAddrExt;
                        dstPanId = hdr.dstPanId;
                    }
                    break;

                case AddressingMode.Reserved:
                    drop = true;
                    break;
                }
            }

            if (!drop)
            {
                bool havePanId = false;
                switch (hdr.fcs.SrcAddrMode)
                {
                case AddressingMode.None:
                    if (dstAddr.Mode == MacAddressingMode.NoAddress)
                    {
                        drop = true;     // at least one address must be valid
                    }
                    break;

                case AddressingMode.Short:
                    srcAddr.ShortAddress = hdr.srcAddrShort;
                    havePanId            = true;
                    break;

                case AddressingMode.Extended:
                    srcAddr.ExtendedAddress = hdr.srcAddrExt;
                    havePanId = true;
                    break;

                case AddressingMode.Reserved:
                    drop = true;
                    break;
                }

                if (havePanId)
                {
                    if (hdr.fcs.PanIdCompression)
                    {
                        if (dstAddr.Mode == MacAddressingMode.NoAddress)
                        {
                            drop = true;
                        }
                        else
                        {
                            srcPanId = dstPanId;
                        }
                    }
                    else
                    {
                        srcPanId = hdr.srcPanId;
                    }
                }
            }

            if (!drop)
            {
                DataIndicationHandler ind = _DataIndication;
                if (ind != null)
                {
                    // synchronous from dataIndicationThread
                    try
                    {
                        ind.Invoke(this, srcAddr, srcPanId, dstAddr, dstPanId,
                                   frame, linkQuality, hdr.seqNo, 0, new SecurityOptions());
                    }
                    catch (Exception) { }
                    frame = null;
                }
            }
        }
Пример #6
0
        private void ReceiveThread()
        {
            while (!_rxThreadStop)
            {
                _rxEvent.WaitOne();

                lock (_hal)
                {
                    if (_activityLeds)
                    {
                        _ledRx.enabled = true;
                    }

                    while (_hal._fifopInterrupt.Read())
                    {
                        if (_hal._fifoPort.Read())
                        {
                            // get frame length, rxFrame is single byte
                            _hal.WriteRead(_rxReadCmd, _rxFrame, 1);
                            byte len = _rxFrame[0];
                            if (len > 0 && len < HALCC2420.FIFOSize)
                            {
                                // get frame
                                byte[] buf = new byte[len];
                                _hal.WriteRead(_rxReadCmd, buf, 1);

                                Frame frame = Frame.GetFrame(2, len + 1); // len + LQI byte. Reserve 2 bytes for header in case this exact frame is resent later on.
                                frame.WriteToBack(buf);
                                // buf = null; // dispose

                                bool ok  = true;
                                int  lqi = 0;

                                if (_hal.AutoFCS)
                                {
                                    // since we are using AutoCRC, MAC FCS is replaced with:
                                    // - RSSI (first byte)
                                    // - LQI (7 bits, lsb)
                                    // - CRC ok (1 bit, msb)
                                    // LQI needs to be scaled from 50..110 to 0..255 [CC.24]
                                    int i = frame.ReadByte(len - 1);
                                    if ((i & 0x80) == 0 || len < 3)
                                    { // CRC error
                                        ok = false;
                                    }
                                    else
                                    {              // calculate LQI
                                        i &= 0x7f; // should be 50..110
                                        if (i < 50)
                                        {
                                            i = 50;
                                        }
                                        if (i > 110)
                                        {
                                            i = 110;
                                        }
                                        // is 50..110
                                        i -= 50;
                                        // 0..60
                                        lqi = (i * 255) / 60;
                                        // 0..255 (well, within that range at least)

                                        frame.DeleteFromBack(2); // remove FCS
                                    }
                                }
                                else
                                {
                                    lqi = GetNormalizedRSSI();
                                }

                                if (ok)
                                {
                                    DataIndicationHandler ind = _DataIndication;
                                    if (ind == null || frame.LengthDataUsed == 0)
                                    {
                                        Frame.Release(ref frame);
                                    }
                                    else
                                    {
                                        try
                                        {
                                            ind.Invoke(this, frame, (byte)lqi);

                                            //    if (buf[2] == 0)
                                            {
                                                DateTime curTime = DateTime.Now;
                                                Debug.Print("Get Frm " + buf[2] + " Len " + len.ToString() + " Data " + ":" + GetHex(buf, 16) + " at " + curTime.Second + ":" + curTime.Millisecond);
                                            }
                                        }
                                        catch (Exception) { }
                                    }
                                }
                                else
                                {
                                    Frame.Release(ref frame);
                                }
                            }
                            else
                            {
                                _hal.Command(HALCC2420.Cmd.SFlushRX);
                                _hal.Command(HALCC2420.Cmd.SFlushRX);
                            }
                        }
                        else // !m_hal.m_fifoPort.Read()
                        {
                            _hal.Command(HALCC2420.Cmd.SFlushRX);
                            _hal.Command(HALCC2420.Cmd.SFlushRX);
                        }
                    }

                    if (_activityLeds)
                    {
                        _ledRx.enabled = false;
                    }
                }
            }
        }