/// <summary> /// To start the network layer /// </summary> /// <param name="panId">Pan ID of the network to set on Mac layer</param> /// <param name="panCoordinator">True if this node is the network coordinator</param> /// <param name="logicalChannel">Logical channel to use</param> /// <param name="channelPage">Channel page to use</param> /// <param name="neighours">Set of neighbors to bootstrap. Not used when started as network coordinator</param> /// <param name="handler">Handler for confirmation message</param> public void Start(UInt16 panId, bool netCoordinator, byte logicalChannel, byte channelPage, UInt16[] neighours, StartConfirmHandler handler) { if (_isRunning) { if (handler != null) handler.Invoke(this, Status.Busy, 0); return; } _isRunning = true; _panId = panId; _startConfirmHandler = handler; if (netCoordinator) { _addrShort = cCoordinatorShortAddr; _addrServer = new AddressAndDiscoveryServer(this); // always exists if isAddrServer is true } else { _addrShort = cUnallocatedShortAddr; _addrServer = null; } _isAddrServer = netCoordinator; _mac.DataIndication = MacDataIndHandler; _mac.GetDeviceAddress(out _addrExt); PibValue value = new PibValue(); value.Int = _addrShort; _mac.SetRequest(PibAttribute.macShortAddress, 0, value, null); AutoResetEvent startEvent = new AutoResetEvent(false); Status result = Status.Error; _mac.StartRequest(_panId, logicalChannel, channelPage, 0, 15, 0, netCoordinator, false, false, new SecurityOptions(), new SecurityOptions(), delegate( IMacMgmtSap sender, MacEnum status) { if (status == MacEnum.Success) result = Status.Success; startEvent.Set(); }); startEvent.WaitOne(); if (result == Status.Success && !_isAddrServer) { _getAddressNeighbors = neighours; _getAddressCancel = false; _getAddressEvent.Reset(); _getAddressThread = new Thread(GetAddressThread); #if !MICROFRAMEWORK _getAddressThread.IsBackground = true; #endif _getAddressThread.Start(); } else { FinalizeStartup(result); } }
private void FinalizeStartup(Status result) { if (result == Status.Success) { _data.StartData(_addrShort); _neighbourTable.Start(_addrShort); // tune MAC attributes PibValue value = new PibValue(); // set macMinBE (backoff exponent) to 1. SW-MAC is slow enough value.Int = 1; _mac.SetRequest(PibAttribute.macMinBE, 0, value, null); // set macMaxFrameRetries to 7. Agressive retries to avoid upper layer dealing with link errors value.Int = 7; _mac.SetRequest(PibAttribute.macMaxFrameRetries, 0, value, null); } else { _isRunning = false; } if (_startConfirmHandler != null) _startConfirmHandler.Invoke(this, result, _addrShort); }
private void HandleAddressReply( MacAddress srcAddr, MacAddress dstAddr, ref Frame sdu) { Message.AddressReply arep = new Message.AddressReply(); if (arep.ReadFromFrame(sdu)) { if (dstAddr.Mode == MacAddressingMode.ExtendedAddress && dstAddr.ExtendedAddress == _addrExt) { // address is for us if (_addrShort == cUnallocatedShortAddr) { _addrShort = arep.ShortAddr; PibValue value = new PibValue(); value.Int = _addrShort; _mac.SetRequest(PibAttribute.macShortAddress, 0, value, null); _getAddressEvent.Set(); SetDiscoveryTimer(arep.DiscoveryInterval); } } else { if (arep.HopsLeft > 0) { arep.HopsLeft--; Frame frame = Frame.GetFrame(_macHeader, Message.AddressRequest.cLength + _macTailer); if (arep.WriteToFrame(frame)) { if (arep.BrokerAddr == _addrShort) { // we are the broker MacDataRequest(arep.DeviceAddr, ref frame); } else { // forward to broker _routingTable.DataRequest(arep.BrokerAddr, ref frame, 0, null, true); } } Frame.Release(ref frame); } } } }
private void GetRequest(TaskGetRequest task) { if (task == null) return; if (task.handler == null) return; MacEnum status = MacEnum.Success; PibValue value = new PibValue(); 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 valPhy; _phy.GetRequest((Phy.PibAttribute)task.attribute, out statusPhy, out valPhy); if (statusPhy == Phy.Status.Success) { switch (valPhy.Type) { case Phy.PibValue.ValueType.Int: value.Int = valPhy.Int; break; case Phy.PibValue.ValueType.IntArray: value.IntArray = valPhy.IntArray; break; case Phy.PibValue.ValueType.Float: value.Float = valPhy.Float; break; } } else { status = MacEnum.UnsupportedAttribute; } break; } case PibAttribute.macBeaconPayload: { Frame frame = null; Frame payload = _state.macBeaconPayload; if (payload != null) { frame = Frame.GetFrame(payload.LengthDataUsed); frame.WriteToBack(payload); } value.Frame = frame; break; } case PibAttribute.macPanId: { value.Int = _state.macPanId; break; } case PibAttribute.macPromiscuousMode: { value.Bool = _state.macPromiscousMode; break; } case PibAttribute.macShortAddress: { value.Int = _state.macShortAddr; break; } case PibAttribute.macBeaconOrder: { value.Int = _state.macBeaconOrder; break; } case PibAttribute.macSuperframeOrder: { value.Int = _state.macBeaconOrder; break; } case PibAttribute.macMinBE: { value.Int = _state.macMinBE; break; } case PibAttribute.macMaxBE: { value.Int = _state.macMaxBE; break; } case PibAttribute.macMaxCSMABackoffs: { value.Int = _state.macMaxCSMABackoffs; break; } case PibAttribute.macMaxFrameRetries: { value.Int = _state.macMaxFrameRetries; 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("MacGetRequest: unsupported attribute"); break; } } if (task.handler != null) { task.handler.Invoke(this, status, task.attribute, task.attributeIndex, value); } }
private void SetBeaconPayload() { Frame frame = Frame.GetFrame(8); frame.AllocBack(8); frame.WriteCanonical(0, NetworkLayer.cMeshId); PibValue value = new PibValue(); value.Frame = frame; _net.Mac.SetRequest(PibAttribute.macBeaconPayload, 0, value, null); }
// handler for MacGetRequest for supported channels private void HandlerChannelsSupported( IMacMgmtSap sender, MacEnum status, PibAttribute attribute, int attributeIndex, PibValue value) { if (!_scanning || attribute != PibAttribute.phyChannelsSupported) return; if (status != MacEnum.Success) { FinishScanning(Status.Error); return; } _scanChannels = value.IntArray; _scanChannelsCurrent = 0; ScanNextPage(); }
public TaskSetRequest( PibAttribute attribute, int index, PibValue value, SetConfirmHandler handler) : base(TaskType.SetRequest) { this.attribute = attribute; this.index = index; this.value = value; this.handler = handler; }