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); }
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); }
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); }