private void GetAddressThread()
        {
            if (_getAddressNeighbors != null)
            {
                int length = _getAddressNeighbors.Length;
                for (int retry = 0; retry < 3; retry++)
                {
                    for (int i = 0; i < length; i++)
                    {
                        UInt16 addr = _getAddressNeighbors[i];
                        Message.AddressRequest areq = new Message.AddressRequest();
                        areq.HopsLeft = cDefaultHopLimit;
                        areq.BrokerAddr = cCoordinatorShortAddr;
                        areq.DeviceAddr = _addrExt;
                        Frame frame = Frame.GetFrame(_macHeader, Message.AddressRequest.cLength + _macTailer);
                        if (areq.WriteToFrame(frame))
                        {
                            MacDataRequest(addr, ref frame);
                            if (_getAddressEvent.WaitOne(cAddressRequestTimeout, false))
                            {
                                // success
                                FinalizeStartup(Status.Success);
                                return;
                            }

                            if (_getAddressCancel)
                                return; // abort thread
                        }

                        Frame.Release(ref frame);
                    }
                }
            }

            FinalizeStartup(Status.NoAddress);
        }
        private void HandleAddressRequest(
            MacAddress srcAddr,
            MacAddress dstAddr,
            ref Frame sdu)
        {
            Message.AddressRequest areq = new Message.AddressRequest();
            if (areq.ReadFromFrame(sdu))
            {
                if (_isAddrServer)
                {
                    // process message as address server
                    Message.AddressReply arep = new Message.AddressReply();
                    if (_addrServer.AllocateAddress(areq.DeviceAddr, out arep.ShortAddr))
                    {
                        // send address
                        arep.HopsLeft = cDefaultHopLimit;
                        arep.BrokerAddr = areq.BrokerAddr;
                        arep.DeviceAddr = areq.DeviceAddr;
                        arep.DiscoveryInterval = _addrServer.TimeInterval;

                        Frame frame = Frame.GetFrame(_macHeader, Message.AddressReply.cLength + _macTailer);
                        if (arep.WriteToFrame(frame))
                        {
                            if (areq.BrokerAddr == cCoordinatorShortAddr)
                            {
                                // direct response
                                if (srcAddr.Mode == MacAddressingMode.ExtendedAddress)
                                {
                                    MacDataRequest(srcAddr.ExtendedAddress, ref frame);
                                }
                            }
                            else
                            {
                                // send to broker
                                _routingTable.DataRequest(areq.BrokerAddr, ref frame, 0, null, true);
                            }
                        }

                        Frame.Release(ref frame);
                    }
                }
                else
                {
                    // forward towards address server
                    if (areq.HopsLeft > 0)
                    {
                        areq.HopsLeft--;
                        if (areq.BrokerAddr == cCoordinatorShortAddr)
                        {
                            areq.BrokerAddr = _addrShort;
                        }

                        Frame frame = Frame.GetFrame(_macHeader, Message.AddressRequest.cLength + _macTailer);
                        if (areq.WriteToFrame(frame))
                        {
                            // send to address server
                            _routingTable.DataRequest(cCoordinatorShortAddr, ref frame, 0, null, true);
                        }

                        Frame.Release(ref frame);
                    }
                }
            }
        }