Example #1
0
        /// <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);
            }
        }
Example #2
0
        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);
        }
Example #3
0
        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);
            }
        }
Example #5
0
        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);
        }
Example #6
0
        // 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();
        }
Example #7
0
 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;
 }