public function accessRequest($username = '', $password = '', $timeout = 0, $state = null)
    {
        $this->clearDataReceived()
             ->clearError()
             ->setPacketType(self::TYPE_ACCESS_REQUEST);

        if (0 < strlen($username)) {
            $this->setUsername($username);
        }

        if (0 < strlen($password)) {
            $this->setPassword($password);
        }

        if ($state !== null) {
            $this->setAttribute(24, $state);
        } else {
            $this->setAttribute(6, 1); // 1=Login
        }

        if (intval($timeout) > 0) {
            $this->setTimeout($timeout);
        }

        $packetData = $this->generateRadiusPacket();

        $conn = $this->sendRadiusRequest($packetData);
        if (!$conn) {
            $this->debugInfo(sprintf(
                'Failed to send packet to %s; error: %s',
                $this->server,
                $this->getErrorMessage())
            );

            return false;
        }

        $receivedPacket = $this->readRadiusResponse($conn);
        @fclose($conn);

        if (!$receivedPacket) {
            $this->debugInfo(sprintf(
                'Error receiving response packet from %s; error: %s',
                $this->server,
                $this->getErrorMessage())
            );

            return false;
        }

        if (!$this->parseRadiusResponsePacket($receivedPacket)) {
            $this->debugInfo(sprintf(
                'Bad RADIUS response from %s; error: %s',
                $this->server,
                $this->getErrorMessage())
            );

            return false;
        }

        if ($this->radiusPacketReceived == self::TYPE_ACCESS_REJECT) {
            $this->errorCode    = 3;
            $this->errorMessage = 'Access rejected';
        }

        return (self::TYPE_ACCESS_ACCEPT == ($this->radiusPacketReceived));
    }