예제 #1
0
        public void TestReceiveDump()
        {
            phy.SetPower(true);

            // page 0
            Status status;
            PibValue value = new PibValue();
            value.Int = 0;
            phy.SetRequest(PibAttribute.phyCurrentPage, value, out status);
            Assert(status == Status.Success);

            // channel 11
            value.Int = 11;
            phy.SetRequest(PibAttribute.phyCurrentChannel, value, out status);
            Assert(status == Status.Success);

            // sniff
            phy.DataIndication = phy_DataIndicationDump;
            phy.SetTrxStateRequest(State.RxOn, out status);
            Assert(status == Status.RxOn);

            for (; ; )
                Thread.Sleep(5000);
        }
예제 #2
0
        public void TestCommon()
        {
            // GetFrameHeaders
            {
                int mtu, head, tail;
                phy.GetMtuSize(out mtu, out head, out tail);
                Assert(mtu == 127);
                Assert(head == 2);
                Assert(tail == 0);
            }

            // Capabilities
            {
                bool res;
                phy.IsCapabilitySupported(Capabilities.AddressFilter, out res);
                Assert(res == true);
                phy.IsCapabilitySupported(Capabilities.AutoAck, out res);
                Assert(res == true);
                phy.IsCapabilitySupported(Capabilities.AutoFcs, out res);
                Assert(res == true);
                phy.IsCapabilitySupported(Capabilities.PowerOff, out res);
                Assert(res == true);
            }

            phy.SetPower(true);

            // GetDeviceAddress
            {
                UInt64 mac;
                phy.GetDeviceAddress(out mac);
                String s = String.Empty;
                for (int i = 0; i < 8; i++)
                {
                    if (i > 0)
                        s += ":";
                    s += HexConverter.ConvertUintToHex((UInt32)((mac >> i * 8) & 0xFF), 2);
                }

                Debug.Print(s);
            }

            // GetRequest
            {
                Status status;
                PibValue value;

                // constants
                phy.GetRequest(PibAttribute.phyChannelsSupported, out status, out value);
                Assert(status == Status.Success);
                int[] res = value.IntArray;
                Assert(res != null);
                Assert(res.Length == 1);
                Assert((res[0] & 0xF8000000) == 0); // page 0
                for (int i = 0; i <= 27; i++)
                {
                    bool val = (res[0] & (1 << i)) != 0;
                    bool expected = (i >= 11 && i <= 26);
                    Assert(val == expected);
                }

                phy.GetRequest(PibAttribute.phyCCAMode, out status, out value);
                Assert(status == Status.Success);
                Assert(value.Int == 3);

                phy.GetRequest(PibAttribute.phyCurrentPage, out status, out value);
                Assert(status == Status.Success);
                Assert(value.Int == 0);

                phy.GetRequest(PibAttribute.phyMaxFrameDuration, out status, out value);
                Assert(status == Status.Success);
                Assert(value.Int == 1064);

                phy.GetRequest(PibAttribute.phySHRDuration, out status, out value);
                Assert(status == Status.Success);
                Assert(value.Int == 40);

                phy.GetRequest(PibAttribute.phySymbolsPerOctet, out status, out value);
                Assert(status == Status.Success);
                Assert(value.Float == 8);

                // defaults
                phy.GetRequest(PibAttribute.phyCurrentChannel, out status, out value);
                Assert(status == Status.Success);
                Assert(value.Int == 11);

                phy.GetRequest(PibAttribute.phyTransmitPower, out status, out value);
                Assert(status == Status.Success);
                Assert(value.Int == -1);
            }

            // SetRequest
            {
                // constants
                Status status;
                PibValue value = new PibValue();

                int[] res = new int[1];
                res[0] = 256;
                value.IntArray = res;
                phy.SetRequest(PibAttribute.phyChannelsSupported, value, out status);
                Assert(status == Status.ReadOnly);

                value.Int = 0;
                phy.SetRequest(PibAttribute.phyCCAMode, value, out status);
                Assert(status == Status.ReadOnly);

                phy.SetRequest(PibAttribute.phyMaxFrameDuration, value, out status);
                Assert(status == Status.ReadOnly);

                phy.SetRequest(PibAttribute.phySHRDuration, value, out status);
                Assert(status == Status.ReadOnly);

                phy.SetRequest(PibAttribute.phySymbolsPerOctet, value, out status);
                Assert(status == Status.ReadOnly);

                // page
                phy.SetRequest(PibAttribute.phyCurrentPage, value, out status);
                Assert(status == Status.Success);

                value.Int = 1;
                phy.SetRequest(PibAttribute.phyCurrentPage, value, out status);
                Assert(status == Status.InvalidParam);

                // channel
                for (int i = 0; i < 27; i++)
                {
                    value.Int = i;
                    phy.SetRequest(PibAttribute.phyCurrentChannel, value, out status);
                    if (i >= 11 && i <= 26)
                    {
                        Assert(status == Status.Success);
                        phy.GetRequest(PibAttribute.phyCurrentChannel, out status, out value);
                        Assert(status == Status.Success);
                        Assert(value.Int == i);
                    }
                    else
                    {
                        Assert(status == Status.InvalidParam);
                    }
                }

                // power
                value.Int = -100;
                phy.SetRequest(PibAttribute.phyTransmitPower, value, out status);
                Assert(status == Status.InvalidParam);

                value.Int = -32;
                phy.SetRequest(PibAttribute.phyTransmitPower, value, out status);
                Assert(status == Status.Success);
                phy.GetRequest(PibAttribute.phyTransmitPower, out status, out value);
                Assert(status == Status.Success);
                value.Int = 1;
                phy.SetRequest(PibAttribute.phyTransmitPower, value, out status);
                Assert(status == Status.Success);
                phy.GetRequest(PibAttribute.phyTransmitPower, out status, out value);
                Assert(status == Status.Success);
                Assert(value.Int == 0); // max CC tx power

                value.Int = 64;
                phy.SetRequest(PibAttribute.phyTransmitPower, value, out status);
                Assert(status == Status.InvalidParam);
            }

            phy.SetPower(false);
        }
예제 #3
0
        public void TestSend(bool bSendData)
        {
            phy.SetPower(true);
            phy.SetAutoFCS(true);
            int mtu, head, tail;
            phy.GetMtuSize(out mtu, out head, out tail);

            PibValue value = new PibValue();
            Status status;
            value.Int = 11;
            phy.SetRequest(PibAttribute.phyCurrentChannel, value, out status);
            Assert(status == Status.Success);

            value.Int = 0;
            phy.SetRequest(PibAttribute.phyTransmitPower, value, out status);
            Assert(status == Status.Success);

            if (bSendData)
            {   // Sends data continously. Dummy processing.
                phy.DataIndication = phy_DataIndicationDummy;
            }
            else
            {   // Does not send data. During receive pings data back.
                phy.DataIndication = phy_DataIndicationAqc;
            }

            phy.SetTrxStateRequest(State.RxOn, out status);
            byte[] packetData = new byte[100];

            DateTime prevTime = DateTime.Now;
            byte[] b = new byte[128];

            Thread.Sleep(10);

            if (!bSendData)
            {
                return;
            }

            for (int i = 0; ; ++i)
            {
                // build custom frame

                m_frame.ReserveHeader(head);
                int cInd = -1;

                ushort u = (ushort)(1 << 0) | // m_frame type: data
                    (0 << 3) | // security: none
                    (0 << 4) | // m_frame pending: none
                    (1 << 5) | // ack request: true
                    (1 << 6) | // pan id compression: true
                    (2 << 10) | // dst addr: short addr
                    (2 << 14);  // src addr: short addr
                b[++cInd] = (byte)(u & 0xFF);
                b[++cInd] = (byte)(u >> 8);
                // Append sequence number.
                b[++cInd] = (byte)i;    // seq no
                u = 1; // pan id
                b[++cInd] = (byte)(u & 0xFF);
                b[++cInd] = (byte)(u >> 8);
                u = 2;
                b[++cInd] = (byte)(u & 0xFF);
                b[++cInd] = (byte)(u >> 8);
                u = 3;
                b[++cInd] = (byte)(u & 0xFF);
                b[++cInd] = (byte)(u >> 8);
                b[++cInd] = 0xDE;
                b[++cInd] = 0xAD;
                b[++cInd] = 0xBE;
                b[++cInd] = 0xEF; // dead beef
                m_frame.AppendToBack(b, 0, cInd + 1 + 100); // payload
                do
                {
                    phy.DataRequest(m_frame, out status);
                } while (status != Status.Success);
                DateTime curTime = DateTime.Now;
                Debug.Print("Frame " + (byte)i + " is sent at " + curTime.Second + ":" + curTime.Millisecond);

                Thread.Sleep(2000);
            }
        }
예제 #4
0
        public void TestReceive()
        {
            phy.SetPower(true);

            phy.DataIndication = phy_DataIndicationDummy;

            // EDRequest
            {
                Debug.Print("EDRequest");
                Status status;
                Byte energyLevel;

                phy.SetTrxStateRequest(State.TRxOff, out status);
                Assert(status == Status.TRxOff);

                phy.EDRequest(out status, out energyLevel);
                Assert(status == Status.TRxOff);

                phy.SetTrxStateRequest(State.RxOn, out status);
                Assert(status == Status.RxOn);
                for (int i = 0; i < 5; i++)
                {
                    leds.color = Leds.Color.Blue;
                    for (int channel = 11; channel <= 26; channel++)
                    {
                        PibValue value = new PibValue();
                        value.Int = channel;
                        phy.SetRequest(PibAttribute.phyCurrentChannel, value, out status);
                        Assert(status == Status.Success);

                        phy.EDRequest(out status, out energyLevel);
                        if (status == Status.Success)
                        {
                            String s = String.Empty;
                            s += "ED: " + energyLevel + " on " + channel;
                            Debug.Print(s);
                        }
                    }

                    leds.color = Leds.Color.Off;
                    System.Threading.Thread.Sleep(100);
                }
            }

            // CCARequest
            {
                Debug.Print("CCA");
                PibValue value = new PibValue();
                value.Int = 11;
                Status status;
                phy.SetRequest(PibAttribute.phyCurrentChannel, value, out status);
                Assert(status == Status.Success);

                phy.SetTrxStateRequest(State.RxOn, out status);
                Assert(status == Status.RxOn);

                DateTime start = DateTime.Now;
                TimeSpan duration = new TimeSpan(0, 0, 5);
                while (DateTime.Now - start < duration)
                {
                    phy.CCARequest(out status);
                    if (status == Status.Busy)
                        leds.color = Leds.Color.Yellow;
                    else
                        leds.color = Leds.Color.Off;
                }

                leds.color = Leds.Color.Off;
            }

            // DataIndication
            phy.SetAutoFCS(true);
            phy.SetAddressFilter(true, 2, 1, false); // ok, no recv for other short addr/pan id
            phy.SetAutoAck(true);

            phy.DataIndication = phy_DataIndicationFlash;
            {
                Status status;
                phy.SetTrxStateRequest(State.RxOn, out status);
                Assert(status == Status.RxOn);

                Thread.Sleep(5000);
            }
        }
예제 #5
0
        private void SetRequest(TaskSetRequest task)
        {
            if (task == null)
                return;

            MacEnum status = MacEnum.Success;
            lock (_state)
            {
                switch (task.attribute)
                {
                    case PibAttribute.phyCurrentChannel:
                    case PibAttribute.phyChannelsSupported:
                    case PibAttribute.phyTransmitPower:
                    case PibAttribute.phyCCAMode:
                    case PibAttribute.phyCurrentPage:
                    case PibAttribute.phyMaxFrameDuration:
                    case PibAttribute.phySHRDuration:
                    case PibAttribute.phySymbolsPerOctet:
                        {
                            Phy.Status statusPhy;
                            Phy.PibValue value = new Phy.PibValue();
                            switch (task.value.Type)
                            {
                                case PibValue.ValueType.Int:
                                    value.Int = task.value.Int;
                                    break;
                                case PibValue.ValueType.IntArray:
                                    value.IntArray = task.value.IntArray;
                                    break;
                                case PibValue.ValueType.Float:
                                    value.Float = task.value.Float;
                                    break;
                            }

                            _phy.SetRequest((Phy.PibAttribute)task.attribute, value, out statusPhy);

                            if (statusPhy != Phy.Status.Success)
                            {
                                if (statusPhy == Phy.Status.InvalidParam)
                                    status = MacEnum.InvalidParameter;
                                else
                                    status = MacEnum.UnsupportedAttribute;
                            }
                            break;
                        }
                    case PibAttribute.macBeaconPayload:
                        if (task.value.Type == PibValue.ValueType.Frame)
                        {
                            Frame.Release(ref _state.macBeaconPayload);
                            _state.macBeaconPayload = task.value.Frame;
                        }
                        else
                        {
                            status = MacEnum.InvalidParameter;
                        }
                        break;
                    case PibAttribute.macPanId:
                        if (task.value.Type == PibValue.ValueType.Int)
                        {
                            _state.macPanId = (UInt16)task.value.Int;
                        }
                        else
                        {
                            status = MacEnum.InvalidParameter;
                        }
                        break;
                    case PibAttribute.macPromiscuousMode:
                        if (task.value.Type == PibValue.ValueType.Bool)
                        {
                            _state.macPromiscousMode = task.value.Bool;
                        }
                        else
                        {
                            status = MacEnum.InvalidParameter;
                        }
                        break;
                    case PibAttribute.macShortAddress:
                        if (task.value.Type == PibValue.ValueType.Int)
                        {
                            _state.macShortAddr = (UInt16)task.value.Int;
                        }
                        else
                        {
                            status = MacEnum.InvalidParameter;
                        }
                        break;
                    case PibAttribute.macBeaconOrder:
                        if (task.value.Type == PibValue.ValueType.Int)
                        {
                            _state.macBeaconOrder = FixParameter((byte)task.value.Int, 0, 15);
                        }
                        else
                        {
                            status = MacEnum.InvalidParameter;
                        }
                        break;
                    case PibAttribute.macSuperframeOrder:
                        if (task.value.Type == PibValue.ValueType.Int)
                        {
                            _state.macSuperframeOrder = FixParameter((byte)task.value.Int, 0, 15);
                        }
                        else
                        {
                            status = MacEnum.InvalidParameter;
                        }
                        break;
                    case PibAttribute.macMinBE:
                        if (task.value.Type == PibValue.ValueType.Int)
                        {
                            _state.macMinBE = FixParameter((byte)task.value.Int, 0, _state.macMaxBE);
                        }
                        else
                        {
                            status = MacEnum.InvalidParameter;
                        }
                        break;
                    case PibAttribute.macMaxBE:
                        if (task.value.Type == PibValue.ValueType.Int)
                        {
                            _state.macMaxBE = FixParameter((byte)task.value.Int, 3, 8);
                            if (_state.macMinBE > _state.macMaxBE)
                                _state.macMinBE = _state.macMaxBE;
                        }
                        else
                        {
                            status = MacEnum.InvalidParameter;
                        }
                        break;
                    case PibAttribute.macMaxCSMABackoffs:
                        if (task.value.Type == PibValue.ValueType.Int)
                        {
                            _state.macMaxCSMABackoffs = FixParameter((byte)task.value.Int, 0, 5);
                        }
                        else
                        {
                            status = MacEnum.InvalidParameter;
                        }
                        break;
                    case PibAttribute.macMaxFrameRetries:
                        if (task.value.Type == PibValue.ValueType.Int)
                        {
                            _state.macMaxFrameRetries = FixParameter((byte)task.value.Int, 0, 7);
                        }
                        else
                        {
                            status = MacEnum.InvalidParameter;
                        }
                        break;
                    case PibAttribute.macAckWaitDuration:
                    case PibAttribute.macAssociatedPANCoord:
                    case PibAttribute.macAssociationPermit:
                    case PibAttribute.macAutoRequest:
                    case PibAttribute.macBattLifeExt:
                    case PibAttribute.macBattLifeExtPeriods:
                    case PibAttribute.macBeaconTxTime:
                    case PibAttribute.macBSN:
                    case PibAttribute.macCoordExtendedAddress:
                    case PibAttribute.macCoordShortAddress:
                    case PibAttribute.macDSN:
                    case PibAttribute.macGTSPermit:
                    case PibAttribute.macMaxFrameTotalWaitTime:
                    case PibAttribute.macResponseWaitTime:
                    case PibAttribute.macRxOnWhenIdle:
                    case PibAttribute.macSecurityEnabled:
                    case PibAttribute.macSyncSymbolOffset:
                    case PibAttribute.macTimestampSupported:
                    case PibAttribute.macTransactionPersistenceTime:
                        status = MacEnum.UnsupportedAttribute;
                        Trace.Print("Mac: SetRequest: unsupported attribute");
                        break;
                }
            }

            if (task.handler != null)
            {
                task.handler.Invoke(this, status, task.attribute, task.index);
            }
        }
예제 #6
0
        private void StartRequest(TaskStartRequest task)
        {
            if (task == null)
                return;

            MacEnum status = MacEnum.Success;
            lock (_state)
            {
                // test short addr
                if (status == MacEnum.Success)
                {
                    if (_state.macShortAddr == State.cReservedShortAddr)
                    {
                        status = MacEnum.NoShortAddress;
                    }
                }

                // test beacon
                if (status == MacEnum.Success)
                {
                    // need to check if beacon does not exceed size when applying given security.
                    // as security is not yet implemented, nothing to do here
                    //MacEnum.FrameTooLong
                }

                // set page
                if (status == MacEnum.Success)
                {
                    if (_state.phyChannelPage != task.channelPage)
                    {
                        int channelPage = task.channelPage;
                        Phy.Status statusPhy;
                        Phy.PibValue value = new Phy.PibValue();
                        value.Int = channelPage;
                        _phy.SetRequest(Phy.PibAttribute.phyCurrentPage, value, out statusPhy);
                        if (statusPhy == Phy.Status.Success)
                        {
                            _state.phyChannelPage = task.channelPage;
                        }
                        else
                        {
                            status = MacEnum.InvalidParameter;
                        }
                    }
                }

                // set channel
                if (status == MacEnum.Success)
                {
                    if (_state.phyChannelNumber != task.logicalChannel)
                    {
                        Phy.Status statusPhy;
                        Phy.PibValue value = new Phy.PibValue();
                        value.Int = task.logicalChannel;
                        _phy.SetRequest(Phy.PibAttribute.phyCurrentChannel, value, out statusPhy);
                        if (statusPhy == Phy.Status.Success)
                        {
                            _state.phyChannelNumber = task.logicalChannel;
                        }
                        else
                        {
                            status = MacEnum.InvalidParameter;
                        }
                    }
                }

                // FIXME: ignoring various parameters for now
                //UInt16 startTime;
                //byte beaconOrder;
                //byte superframeOrder;
                //bool batteryLifeExtension;
                //bool coordRealignment;
                //SecurityOptions coordRealignSecutiryOptions;
                //SecurityOptions beaconSecurityOptions;

                if (status == MacEnum.Success)
                {
                    _state.macPanId = task.panId;
                    _state.panCoordinator = task.panCoordinator;
                    _state.autoBeacon = true;
                    _sendReceive.Start();
                }
            }

            if (task.handler != null)
                task.handler.Invoke(this, status);
        }
예제 #7
0
        private void ScanRequest(TaskScanRequest task)
        {
            if (task == null)
                return;
            if (task.handler == null)
                return;

            UInt16 oldPanId;
            lock (_state)
            { // recv thread is holding lock while processing frames. this ensures consistency
                _state.scanning = true;
                oldPanId = _state.macPanId;
                _state.macPanId = State.cBroadcastPanId;
            }

            bool wasRunning = _sendReceive.Running;
            if (!wasRunning)
                _sendReceive.Start();

            // calculate scan duration
            UInt32 durationSymbols = task.scanDuration;
            if (durationSymbols > 14)
                durationSymbols = 14;
            durationSymbols = (UInt32)(State.aBaseSuperframeDuration * ((1 << (int)durationSymbols) + 1));

            // result
            UInt32 unscannedChannels = 0; // bitmap
            byte[] energyDetectList = null;
            PanDescriptor[] panDescriptorList = null;

            // set page
            Phy.Status status;
            Phy.PibValue pibValue = new Phy.PibValue();
            pibValue.Int = task.channelPage;
            _phy.SetRequest(Phy.PibAttribute.phyCurrentPage, pibValue, out status);
            if (status != Phy.Status.Success)
            {
                unscannedChannels = task.scanChannels;
            }
            else
            {
                _state.phyChannelPage = task.channelPage;

                // energyDetectList
                int channelCount = 0;
                if (task.scanType == ScanType.ED)
                {
                    for (int channel = 0; channel < 27; channel++)
                    {
                        if (((1 << channel) & task.scanChannels) != 0)
                        {
                            channelCount++;
                        }
                    }

                    energyDetectList = new byte[channelCount];
                    channelCount = 0;
                }

                // Note: there can be a race between switching the channels here and getting the current channel when
                // receiving beacons in MacReceive. This is solved through thread priorities: recv thread has higher
                // priority and should not be blocked from this thread. There is still a small chance that we switch
                // channel and recv assigns the new (wrong) channel, but this is by design and cannot be changed.

                // iterate through all channels
                for (int channel = 0; channel < 27; channel++)
                {
                    if (((1 << channel) & task.scanChannels) != 0)
                    {
                        // set channel
                        pibValue.Int = channel;
                        _phy.SetRequest(Phy.PibAttribute.phyCurrentChannel, pibValue, out status);
                        if (status != Phy.Status.Success)
                        {
                            unscannedChannels |= (UInt32)(1 << channel);
                            channelCount++;
                        }
                        else
                        {
                            _state.phyChannelNumber = (Byte)channel;
                            // max value of durationSymb is 2^24, correct would be: dur*1000/rate, however this exceeds int range
                            // as symbolrate is multiple of 100, this works:
                            int durationMS = (int)(durationSymbols * 10) / (_state.phySymbolrate / 100); // symbolrate is non-zero

                            // perform the actual channel request
                            switch (task.scanType)
                            {
                                case ScanType.ED:
                                    {
                                        // Continuously read ED values in software for given amount of time.
#if MICROFRAMEWORK
                                        ThreadPriority oldPriority = Thread.CurrentThread.Priority;
                                        Thread.CurrentThread.Priority = ThreadPriority.Highest; // RT thread
#endif
                                        Byte result = 0;
                                        bool resultValid = false;
                                        DateTime dtStart = System.DateTime.Now;
                                        for (; ; )
                                        {
                                            Byte b;
                                            _phy.EDRequest(out status, out b);
                                            if (status == Phy.Status.Success)
                                            {
                                                resultValid = true;
                                                if (b > result)
                                                    result = b;
                                            }

                                            //Thread.Sleep(1);
                                            DateTime dtNow = System.DateTime.Now;
                                            TimeSpan ts = dtNow - dtStart;
                                            int elapsedMS = ts.Milliseconds + 1000 * (ts.Seconds + 60 * ts.Minutes);
                                            if (elapsedMS >= durationMS)
                                                break;
                                        }

#if MICROFRAMEWORK
                                        Thread.CurrentThread.Priority = oldPriority;
#endif
                                        if (resultValid)
                                        {
                                            energyDetectList[channelCount] = result;
                                        }
                                        else
                                        {
                                            unscannedChannels |= (UInt32)(1 << channel);
                                        }

                                        channelCount++;
                                        Thread.Sleep(0); // reschedule
                                        break;
                                    }
                                case ScanType.ActiveScan:
                                case ScanType.PassiveScan:
                                    {
                                        // clear any old beacon
                                        lock (_scannedBeacons)
                                        {
                                            _scannedBeacons.Clear();
                                        }

                                        // send beacon request
                                        if (task.scanType == ScanType.ActiveScan)
                                        {
                                            Header hdr = new Header();
                                            Command.BeaconRequest cmd = new Command.BeaconRequest();
                                            hdr.fcs.Type = Microsoft.SPOT.Wireless.IEEE_802_15_4.Mac.Frames.Type.Cmd;
                                            hdr.fcs.DstAddrMode = AddressingMode.Short;
                                            hdr.dstAddrShort = State.cBroadcastShortAddr;
                                            hdr.dstPanId = State.cBroadcastPanId;
                                            hdr.fcs.SrcAddrMode = AddressingMode.None;
                                            hdr.seqNo = _state.macDSN++;

                                            Frame frame = Encode(hdr, cmd);
                                            if (frame != null)
                                                _sendReceive.SendFrame(ref frame, false, hdr.seqNo);
                                            Frame.Release(ref frame);
                                        }

                                        // wait
                                        Thread.Sleep(durationMS);

                                        // create result list
                                        lock (_scannedBeacons)
                                        {
                                            if (_scannedBeacons.Count > 0)
                                            {
                                                int cntOld = 0;
                                                int cntNew = _scannedBeacons.Count;
                                                if (panDescriptorList == null)
                                                {
                                                    panDescriptorList = new PanDescriptor[cntNew];
                                                }
                                                else
                                                {
                                                    cntOld = panDescriptorList.Length;
                                                    PanDescriptor[] tmp = new PanDescriptor[cntOld + cntNew];
                                                    for (int i = 0; i < cntOld; i++)
                                                        tmp[i] = panDescriptorList[i];
                                                    panDescriptorList = tmp;
                                                }

                                                for (int i = 0; i < cntNew; i++)
                                                    panDescriptorList[i + cntOld] = (PanDescriptor)_scannedBeacons[i];
                                                _scannedBeacons.Clear();
                                            }
                                        }
                                        break;
                                    }
                                case ScanType.OrphanScan:
                                    // FIXME: not implemented
                                    Trace.Print("Mac: ScanRequest: OrphanScan not implemented");
                                    unscannedChannels |= (UInt32)(1 << channel);
                                    break;
                            }
                        }
                    }
                }
            }

            if (!wasRunning)
                _sendReceive.Stop();

            lock (_state)
            {
                _state.scanning = false;
                _state.macPanId = oldPanId;
            }

            task.handler.Invoke(this, MacEnum.Success,
                task.scanType, task.channelPage, unscannedChannels, energyDetectList, panDescriptorList);
        }
예제 #8
0
 /// <summary>
 /// (6.2.2.9-10) The PLME-SET.request primitive attempts to set the indicated PHY PIB attribute to the given value.
 /// </summary>
 /// <param name="attribute">The identifier of the PIB attribute to set.</param>
 /// <param name="attributeValue">The value of the indicated PIB attribute to set.</param>
 /// <param name="status">The status of the attempt to set the requested PIB attribute.</param>
 public void SetRequest(
     PibAttribute attribute,
     PibValue attributeValue,
     out Status status)
 {
     switch (attribute)
     {
         case PibAttribute.phyCurrentChannel:
             {
                 if (attributeValue.Type != PibValue.ValueType.Int)
                 {
                     status = Status.InvalidParam;
                 }
                 else
                 {
                     int value = attributeValue.Int;
                     if (value < HALCC2420.MinChannel || value > HALCC2420.MaxChannel)
                     {
                         status = Status.InvalidParam;
                     }
                     else
                     {
                         Channel = (byte)value;
                         status = Status.Success;
                     }
                 }
                 break;
             }
         case PibAttribute.phyTransmitPower:
             {
                 if (attributeValue.Type != PibValue.ValueType.Int)
                 {
                     status = Status.InvalidParam;
                 }
                 else
                 {
                     int value = attributeValue.Int;
                     if (value < -32 || value > 31) // dBm
                     {
                         status = Status.InvalidParam;
                     }
                     else
                     {
                         Power = value;
                         status = Status.Success;
                     }
                 }
                 break;
             }
         case PibAttribute.phyCurrentPage:
             {
                 if (attributeValue.Type != PibValue.ValueType.Int)
                 {
                     status = Status.InvalidParam;
                 }
                 else
                 {
                     int value = attributeValue.Int;
                     if (value == 0)
                         status = Status.Success;
                     else
                         status = Status.InvalidParam;
                 }
                 break;
             }
         case PibAttribute.phyChannelsSupported:
         case PibAttribute.phyCCAMode:
         case PibAttribute.phyMaxFrameDuration:
         case PibAttribute.phySHRDuration:
         case PibAttribute.phySymbolsPerOctet:
             status = Status.ReadOnly;
             break;
         default:
             status = Status.InvalidParam;
             break;
     }
 }
예제 #9
0
 /// <summary>
 /// (6.2.2.5-6) The PLME-GET.request primitive requests information about a given PHY PIB attribute.
 /// </summary>
 /// <param name="attribute">The identifier of the PHY PIB attribute to get.</param>
 /// <param name="status">The result of the request for PHY PIB attribute information.</param>
 /// <param name="attributeValue">The value of the indicated PHY PIB attribute that was requested. This
 /// parameter has zero length when the status parameter is set to UNSUPPORTED_ATTRIBUTE.</param>
 public void GetRequest(
     PibAttribute attribute,
     out Status status,
     out PibValue attributeValue)
 {
     attributeValue = new PibValue();
     switch (attribute)
     {
         case PibAttribute.phyCurrentChannel:
             status = Status.Success;
             attributeValue.Int = Channel;
             break;
         case PibAttribute.phyChannelsSupported:
             {
                 int res = 0;
                 for (int i = HALCC2420.MinChannel; i <= HALCC2420.MaxChannel; i++)
                     res |= (1 << i);
                 // CC2420 only supports channel page 0
                 int[] channels = new int[1];
                 channels[0] = res;
                 status = Status.Success;
                 attributeValue.IntArray = channels;
                 break;
             }
         case PibAttribute.phyTransmitPower:
             status = Status.Success;
             attributeValue.Int = Power;
             break;
         case PibAttribute.phyCCAMode:
             status = Status.Success;
             attributeValue.Int = 3; // hard-coded in hal, could be changed
             break;
         case PibAttribute.phyCurrentPage:
             status = Status.Success;
             attributeValue.Int = 0;
             break;
         case PibAttribute.phyMaxFrameDuration:
             // see 6.4.2 and below
             status = Status.Success;
             attributeValue.Int = 1064;
             break;
         case PibAttribute.phySHRDuration:
             // SHR is 4+1 byte, BPSK (5*8)
             status = Status.Success;
             attributeValue.Int = 40;
             break;
         case PibAttribute.phySymbolsPerOctet:
             status = Status.Success;
             attributeValue.Float = 8; // BPSK only
             break;
         default:
             status = Status.UnsupportedAttr;
             break;
     }
 }
예제 #10
0
        /// <summary>
        /// (6.2.2.5-6) The PLME-GET.request primitive requests information about a given PHY PIB attribute.
        /// </summary>
        /// <param name="attribute">The identifier of the PHY PIB attribute to get.</param>
        /// <param name="status">The result of the request for PHY PIB attribute information.</param>
        /// <param name="attributeValue">The value of the indicated PHY PIB attribute that was requested. This
        /// parameter has zero length when the status parameter is set to UNSUPPORTED_ATTRIBUTE.</param>
        public void GetRequest(
            PibAttribute attribute,
            out Status status,
            out PibValue attributeValue)
        {
            attributeValue = new PibValue();
            switch (attribute)
            {
            case PibAttribute.phyCurrentChannel:
                status             = Status.Success;
                attributeValue.Int = Channel;
                break;

            case PibAttribute.phyChannelsSupported:
            {
                int res = 0;
                for (int i = HALCC2420.MinChannel; i <= HALCC2420.MaxChannel; i++)
                {
                    res |= (1 << i);
                }
                // CC2420 only supports channel page 0
                int[] channels = new int[1];
                channels[0]             = res;
                status                  = Status.Success;
                attributeValue.IntArray = channels;
                break;
            }

            case PibAttribute.phyTransmitPower:
                status             = Status.Success;
                attributeValue.Int = Power;
                break;

            case PibAttribute.phyCCAMode:
                status             = Status.Success;
                attributeValue.Int = 3;     // hard-coded in hal, could be changed
                break;

            case PibAttribute.phyCurrentPage:
                status             = Status.Success;
                attributeValue.Int = 0;
                break;

            case PibAttribute.phyMaxFrameDuration:
                // see 6.4.2 and below
                status             = Status.Success;
                attributeValue.Int = 1064;
                break;

            case PibAttribute.phySHRDuration:
                // SHR is 4+1 byte, BPSK (5*8)
                status             = Status.Success;
                attributeValue.Int = 40;
                break;

            case PibAttribute.phySymbolsPerOctet:
                status = Status.Success;
                attributeValue.Float = 8;     // BPSK only
                break;

            default:
                status = Status.UnsupportedAttr;
                break;
            }
        }
예제 #11
0
        /// <summary>
        /// (6.2.2.9-10) The PLME-SET.request primitive attempts to set the indicated PHY PIB attribute to the given value.
        /// </summary>
        /// <param name="attribute">The identifier of the PIB attribute to set.</param>
        /// <param name="attributeValue">The value of the indicated PIB attribute to set.</param>
        /// <param name="status">The status of the attempt to set the requested PIB attribute.</param>
        public void SetRequest(
            PibAttribute attribute,
            PibValue attributeValue,
            out Status status)
        {
            switch (attribute)
            {
            case PibAttribute.phyCurrentChannel:
            {
                if (attributeValue.Type != PibValue.ValueType.Int)
                {
                    status = Status.InvalidParam;
                }
                else
                {
                    int value = attributeValue.Int;
                    if (value < HALCC2420.MinChannel || value > HALCC2420.MaxChannel)
                    {
                        status = Status.InvalidParam;
                    }
                    else
                    {
                        Channel = (byte)value;
                        status  = Status.Success;
                    }
                }
                break;
            }

            case PibAttribute.phyTransmitPower:
            {
                if (attributeValue.Type != PibValue.ValueType.Int)
                {
                    status = Status.InvalidParam;
                }
                else
                {
                    int value = attributeValue.Int;
                    if (value < -32 || value > 31)         // dBm
                    {
                        status = Status.InvalidParam;
                    }
                    else
                    {
                        Power  = value;
                        status = Status.Success;
                    }
                }
                break;
            }

            case PibAttribute.phyCurrentPage:
            {
                if (attributeValue.Type != PibValue.ValueType.Int)
                {
                    status = Status.InvalidParam;
                }
                else
                {
                    int value = attributeValue.Int;
                    if (value == 0)
                    {
                        status = Status.Success;
                    }
                    else
                    {
                        status = Status.InvalidParam;
                    }
                }
                break;
            }

            case PibAttribute.phyChannelsSupported:
            case PibAttribute.phyCCAMode:
            case PibAttribute.phyMaxFrameDuration:
            case PibAttribute.phySHRDuration:
            case PibAttribute.phySymbolsPerOctet:
                status = Status.ReadOnly;
                break;

            default:
                status = Status.InvalidParam;
                break;
            }
        }