/// <summary>
        /// Shutdown the network layer
        /// </summary>
        public void Stop()
        {
            if (!_isRunning)
                return;
            if (_getAddressThread != null)
            {
                _getAddressCancel = true;
                _getAddressEvent.Set();
                _getAddressThread.Join();
                _getAddressThread = null;
            }

            if (_discoverTimer != null)
            {
                _discoverTimer.Dispose();
                _discoverTimer = null;
                _discoverReplyInterval = 0;
            }

            if (_addrServer != null)
            {
                _addrServer.Dispose();
                _addrServer = null;
            }

            _data.StopData();

            _isRunning = false;
            _mac.DataIndication = null;
            _neighbourTable.Stop(true);
        }
        /// <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);
            }
        }