예제 #1
0
        private void ScanHandlerStartRequest(
            object sender,
            Status status,
            ScanResult[] networks)
        {
            _logicalChannel = 0;
            _channelPage = 0;
            if (status == Status.Success)
            {
                // first check if there are nodes of target network already -> use same channel
                UInt16[] neighborAddr;

                status = FindNetwork(out neighborAddr);
                if (status == Status.NoNeighbor)
                {
                    // perform ED scan
                    bool found = true;
                    byte energy = 0xff; // max
                    AutoResetEvent callbackEvent = new AutoResetEvent(false);

                    Trace.Print("Performing ED scan");

                    int length = _scanChannels.Length;
                    for (int i = 0; i < length; i++)
                    {
                        UInt32 channels = (UInt32)_scanChannels[i];
                        UInt32 page = (channels >> 27);
                        channels &= 0x07FFFFFF; // remove page
                        // FIXME: how to select scanDuration?
                        byte scanDuration = 5;
                        _net.Mac.ScanRequest(ScanType.ED, channels, scanDuration, (byte)page, new SecurityOptions(), delegate(
                            IMacMgmtSap senderDlgt,
                            MacEnum statusDlgt,
                            ScanType scanTypeDlgt,
                            Byte channelPageDlgt,
                            UInt32 unscannedChannelDlgt,
                            byte[] energyDetectListDlgt,
                            PanDescriptor[] panDescriptorListDlgt)
                            {
                                if (statusDlgt == MacEnum.Success && energyDetectListDlgt != null)
                                {
                                    int idx = 0;
                                    for (int c = 0; c < 27; c++)
                                    {
                                        if ((channels & (1 << c)) > 0)
                                        { // channel 'c' was requested
                                            if (((unscannedChannelDlgt & (1 << c)) == 0) && // channel was measured
                                                (idx < energyDetectListDlgt.Length))
                                            { // result is avaiable
                                                Trace.Print("channel " + c + ": energy level " + energyDetectListDlgt[idx]);
                                                if (energyDetectListDlgt[idx] < energy)
                                                { // result is better
                                                    found = true;
                                                    energy = energyDetectListDlgt[idx];
                                                    _logicalChannel = (byte)c;
                                                    _channelPage = channelPageDlgt;
                                                }
                                            }

                                            idx++;
                                        }
                                    }
                                }

                                callbackEvent.Set();
                            });
                        callbackEvent.WaitOne();
                    }

                    if (found)
                    {
                        status = Status.Success;
                        Trace.Print("Starting new network on channel " + _logicalChannel + ", page " + _channelPage);
                    }
                    else
                    {
                        status = Status.Error;
                        Trace.Print("ED scan failed");
                    }
                }

                if (status == Status.Success)
                {
                    Trace.Print("Using Pan Id=0x" + HexConverter.ConvertUintToHex(_panId, 4) +
                        ", logicalChannel=" + _logicalChannel + ", channelPage=" + _channelPage);
                    _net.Routing.Start(_panId, true, _logicalChannel, _channelPage, null, StartHandlerStartRequest);
                    return;
                }
            }

            // scanning failed
            StartHandlerStartRequest(null, status, 0);
        }
예제 #2
0
        private void ScanHandlerJoinRequest(
            object sender,
            Status status,
            ScanResult[] networks)
        {
            _logicalChannel = 0;
            _channelPage = 0;
            if (status == Status.Success)
            {
                // find properties of target network
                UInt16[] neighborAddr;

                status = FindNetwork(out neighborAddr);
                if (status == Status.Success)
                {
                    Trace.Print("Joining network on Pan Id=0x" + HexConverter.ConvertUintToHex(_panId, 4) +
                        ", logicalChannel=" + _logicalChannel + ", channelPage=" + _channelPage);
                    _net.Routing.Start(_panId, false, _logicalChannel, _channelPage, neighborAddr, StartHandlerJoinRequest);
                    return;
                }
            }

            StartHandlerJoinRequest(null, status, 0);
        }
예제 #3
0
        private void FinishScanningThread()
        {
            Status status = _scanStatus;
            ScanResult[] networks = null;

            if (status == Status.Success)
            {
                lock (_scanResults)
                {
                    int countMesh = 0;
                    int countAll = _scanResults.Count;
                    for (int i = 0; i < countAll; i++)
                    {
                        ScanResultInternal itemInt = (ScanResultInternal)_scanResults[i];
                        if (itemInt.isMeshProtocol)
                            countMesh++;
                    }

                    if (countMesh > 0)
                    {
                        networks = new ScanResult[countMesh];
                        countMesh = 0;
                        for (int i = 0; i < countAll; i++)
                        {
                            ScanResultInternal itemInt = (ScanResultInternal)_scanResults[i];
                            if (itemInt.isMeshProtocol)
                            {
                                ScanResult itemExt = new ScanResult();
                                itemExt.panId = itemInt.panDescriptor.coordPanId;
                                itemExt.linkQuality = itemInt.panDescriptor.linkQuality;
                                networks[countMesh++] = itemExt;
                            }
                        }
                    }
                }
            }

            ScanConfirmHandler handler = _scanConfirmHandler;
            _scanning = false; // when invoking handler, handler can start next scan
            handler.Invoke(_net, status, networks);
        }