思特奇智慧酒店云平台 v0.0.5版本的 MD5 值为:dedb172bb322639d79d7e0e26262fb5c

以下内容为反编译后的 XMPPTCPConnection.java 源代码,内容仅作参考


package org.jivesoftware.smack.tcp;

import com.taobao.weex.el.parse.Operators;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.Provider;
import java.security.SecureRandom;
import java.security.Security;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.net.SocketFactory;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.PasswordCallback;
import org.apache.commons.lang.CharUtils;
import org.jivesoftware.smack.AbstractConnectionListener;
import org.jivesoftware.smack.AbstractXMPPConnection;
import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.SmackConfiguration;
import org.jivesoftware.smack.SmackException;
import org.jivesoftware.smack.SmackFuture;
import org.jivesoftware.smack.StanzaListener;
import org.jivesoftware.smack.SynchronizationPoint;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.compress.packet.Compress;
import org.jivesoftware.smack.compress.packet.Compressed;
import org.jivesoftware.smack.compression.XMPPInputOutputStream;
import org.jivesoftware.smack.filter.StanzaFilter;
import org.jivesoftware.smack.packet.Element;
import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.packet.Nonza;
import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smack.packet.Stanza;
import org.jivesoftware.smack.packet.StartTls;
import org.jivesoftware.smack.packet.StreamError;
import org.jivesoftware.smack.packet.StreamOpen;
import org.jivesoftware.smack.proxy.ProxyInfo;
import org.jivesoftware.smack.sasl.packet.SaslStreamElements;
import org.jivesoftware.smack.sm.SMUtils;
import org.jivesoftware.smack.sm.StreamManagementException;
import org.jivesoftware.smack.sm.packet.StreamManagement;
import org.jivesoftware.smack.sm.predicates.Predicate;
import org.jivesoftware.smack.sm.provider.ParseStreamManagement;
import org.jivesoftware.smack.util.ArrayBlockingQueueWithShutdown;
import org.jivesoftware.smack.util.Async;
import org.jivesoftware.smack.util.DNSUtil;
import org.jivesoftware.smack.util.PacketParserUtils;
import org.jivesoftware.smack.util.StringUtils;
import org.jivesoftware.smack.util.TLSUtils;
import org.jivesoftware.smack.util.XmlStringBuilder;
import org.jivesoftware.smack.util.dns.HostAddress;
import org.jivesoftware.smack.util.dns.SmackDaneProvider;
import org.jivesoftware.smack.util.dns.SmackDaneVerifier;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
public class XMPPTCPConnection extends AbstractXMPPConnection {
    public static final boolean $assertionsDisabled = false;
    public static final int QUEUE_SIZE = 500;
    public static BundleAndDeferCallback defaultBundleAndDeferCallback;
    public BundleAndDeferCallback bundleAndDeferCallback;
    public long clientHandledStanzasCount;
    public final SynchronizationPoint<Exception> closingStreamReceived;
    public final SynchronizationPoint<SmackException> compressSyncPoint;
    public final XMPPTCPConnectionConfiguration config;
    public boolean disconnectedButResumeable;
    public final SynchronizationPoint<Exception> initialOpenStreamSend;
    public final SynchronizationPoint<XMPPException> maybeCompressFeaturesReceived;
    public final PacketReader packetReader;
    public final PacketWriter packetWriter;
    public final Semaphore readerWriterSemaphore;
    public final Set<StanzaFilter> requestAckPredicates;
    public SSLSocket secureSocket;
    public long serverHandledStanzasCount;
    public int smClientMaxResumptionTime;
    public final SynchronizationPoint<SmackException> smEnabledSyncPoint;
    public final SynchronizationPoint<XMPPException.FailedNonzaException> smResumedSyncPoint;
    public int smServerMaxResumptionTime;
    public String smSessionId;
    public boolean smWasEnabledAtLeastOnce;
    public Socket socket;
    public final Collection<StanzaListener> stanzaAcknowledgedListeners;
    public final Collection<StanzaListener> stanzaDroppedListeners;
    public final Map<String, StanzaListener> stanzaIdAcknowledgedListeners;
    public BlockingQueue<Stanza> unacknowledgedStanzas;
    public boolean useSm;
    public boolean useSmResumption;
    public static final Logger LOGGER = Logger.getLogger(XMPPTCPConnection.class.getName());
    public static boolean useSmDefault = true;
    public static boolean useSmResumptionDefault = true;

    public class PacketReader {
        public static final boolean $assertionsDisabled = false;
        public volatile boolean done;
        public XmlPullParser parser;
        public final String threadName;

        public PacketReader() {
            this.threadName = "Smack Reader (" + XMPPTCPConnection.this.getConnectionCounter() + Operators.BRACKET_END;
        }

        public void parsePackets() {
            char c;
            try {
                XMPPTCPConnection.this.initialOpenStreamSend.checkIfSuccessOrWait();
                int eventType = this.parser.getEventType();
                while (!this.done) {
                    if (eventType != 1) {
                        if (eventType != 2) {
                            if (eventType == 3 && "stream".equals(this.parser.getName())) {
                                if (!this.parser.getNamespace().equals("http://etherx.jabber.org/streams")) {
                                    Logger logger = XMPPTCPConnection.LOGGER;
                                    logger.warning(XMPPTCPConnection.this + " </stream> but different namespace " + this.parser.getNamespace());
                                } else {
                                    boolean isShutdown = XMPPTCPConnection.this.packetWriter.queue.isShutdown();
                                    XMPPTCPConnection.this.closingStreamReceived.reportSuccess();
                                    if (isShutdown) {
                                        return;
                                    }
                                    Logger logger2 = XMPPTCPConnection.LOGGER;
                                    logger2.info(XMPPTCPConnection.this + " received closing </stream> element. Server wants to terminate the connection, calling disconnect()");
                                    AbstractXMPPConnection.ASYNC_BUT_ORDERED.performAsyncButOrdered(XMPPTCPConnection.this, new Runnable() {
                                        @Override
                                        public void run() {
                                            XMPPTCPConnection.this.disconnect();
                                        }
                                    });
                                }
                            }
                        } else {
                            String name = this.parser.getName();
                            char c2 = 0;
                            switch (name.hashCode()) {
                                case -1867169789:
                                    if (name.equals("success")) {
                                        c = '\t';
                                        break;
                                    }
                                    c = 65535;
                                    break;
                                case -1609594047:
                                    if (name.equals(StreamManagement.Enabled.ELEMENT)) {
                                        c = 11;
                                        break;
                                    }
                                    c = 65535;
                                    break;
                                case -1281977283:
                                    if (name.equals("failed")) {
                                        c = '\f';
                                        break;
                                    }
                                    c = 65535;
                                    break;
                                case -1276666629:
                                    if (name.equals(Presence.ELEMENT)) {
                                        c = 2;
                                        break;
                                    }
                                    c = 65535;
                                    break;
                                case -1086574198:
                                    if (name.equals(SaslStreamElements.SASLFailure.ELEMENT)) {
                                        c = 7;
                                        break;
                                    }
                                    c = 65535;
                                    break;
                                case -891990144:
                                    if (name.equals("stream")) {
                                        c = 3;
                                        break;
                                    }
                                    c = 65535;
                                    break;
                                case -369449087:
                                    if (name.equals(Compressed.ELEMENT)) {
                                        c = '\n';
                                        break;
                                    }
                                    c = 65535;
                                    break;
                                case -309519186:
                                    if (name.equals("proceed")) {
                                        c = 6;
                                        break;
                                    }
                                    c = 65535;
                                    break;
                                case -290659267:
                                    if (name.equals("features")) {
                                        c = 5;
                                        break;
                                    }
                                    c = 65535;
                                    break;
                                case 97:
                                    if (name.equals("a")) {
                                        c = 14;
                                        break;
                                    }
                                    c = 65535;
                                    break;
                                case 114:
                                    if (name.equals("r")) {
                                        c = 15;
                                        break;
                                    }
                                    c = 65535;
                                    break;
                                case 3368:
                                    if (name.equals(IQ.IQ_ELEMENT)) {
                                        c = 1;
                                        break;
                                    }
                                    c = 65535;
                                    break;
                                case 96784904:
                                    if (name.equals("error")) {
                                        c = 4;
                                        break;
                                    }
                                    c = 65535;
                                    break;
                                case 954925063:
                                    if (name.equals("message")) {
                                        c = 0;
                                        break;
                                    }
                                    c = 65535;
                                    break;
                                case 1097547223:
                                    if (name.equals("resumed")) {
                                        c = CharUtils.CR;
                                        break;
                                    }
                                    c = 65535;
                                    break;
                                case 1402633315:
                                    if (name.equals(SaslStreamElements.Challenge.ELEMENT)) {
                                        c = '\b';
                                        break;
                                    }
                                    c = 65535;
                                    break;
                                default:
                                    c = 65535;
                                    break;
                            }
                            switch (c) {
                                case 0:
                                case 1:
                                case 2:
                                    XMPPTCPConnection.this.parseAndProcessStanza(this.parser);
                                    XMPPTCPConnection.this.clientHandledStanzasCount = SMUtils.incrementHeight(XMPPTCPConnection.this.clientHandledStanzasCount);
                                    continue;
                                case 3:
                                    if ("jabber:client".equals(this.parser.getNamespace(null))) {
                                        XMPPTCPConnection.this.streamId = this.parser.getAttributeValue("", "id");
                                        this.parser.getAttributeValue("", "from");
                                        break;
                                    } else {
                                        continue;
                                    }
                                case 4:
                                    StreamError parseStreamError = PacketParserUtils.parseStreamError(this.parser);
                                    XMPPTCPConnection.this.saslFeatureReceived.reportFailure(new XMPPException.StreamErrorException(parseStreamError));
                                    XMPPTCPConnection.this.tlsHandled.reportSuccess();
                                    throw new XMPPException.StreamErrorException(parseStreamError);
                                case 5:
                                    XMPPTCPConnection.this.parseFeatures(this.parser);
                                    continue;
                                case 6:
                                    try {
                                        XMPPTCPConnection.this.proceedTLSReceived();
                                        XMPPTCPConnection.this.openStream();
                                        continue;
                                    } catch (Exception e) {
                                        XMPPTCPConnection.this.tlsHandled.reportFailure(new SmackException(e));
                                        throw e;
                                    }
                                case 7:
                                    String namespace = this.parser.getNamespace(null);
                                    int hashCode = namespace.hashCode();
                                    if (hashCode == -1570142914) {
                                        if (namespace.equals("urn:ietf:params:xml:ns:xmpp-sasl")) {
                                            c2 = 2;
                                            if (c2 != 0) {
                                            }
                                        }
                                        c2 = 65535;
                                        if (c2 != 0) {
                                        }
                                    } else if (hashCode != 919182852) {
                                        if (hashCode == 2117926358 && namespace.equals("http://jabber.org/protocol/compress")) {
                                            c2 = 1;
                                            if (c2 != 0) {
                                                throw new SmackException("TLS negotiation has failed");
                                            }
                                            if (c2 == 1) {
                                                XMPPTCPConnection.this.compressSyncPoint.reportFailure(new SmackException("Could not establish compression"));
                                                break;
                                            } else if (c2 == 2) {
                                                XMPPTCPConnection.this.getSASLAuthentication().authenticationFailed(PacketParserUtils.parseSASLFailure(this.parser));
                                                break;
                                            } else {
                                                continue;
                                            }
                                        }
                                        c2 = 65535;
                                        if (c2 != 0) {
                                        }
                                    } else {
                                        if (namespace.equals(StartTls.NAMESPACE)) {
                                            if (c2 != 0) {
                                            }
                                        }
                                        c2 = 65535;
                                        if (c2 != 0) {
                                        }
                                    }
                                    break;
                                case '\b':
                                    XMPPTCPConnection.this.getSASLAuthentication().challengeReceived(this.parser.nextText());
                                    continue;
                                case '\t':
                                    SaslStreamElements.Success success = new SaslStreamElements.Success(this.parser.nextText());
                                    XMPPTCPConnection.this.openStream();
                                    XMPPTCPConnection.this.getSASLAuthentication().authenticated(success);
                                    continue;
                                case '\n':
                                    XMPPTCPConnection.this.initReaderAndWriter();
                                    XMPPTCPConnection.this.openStream();
                                    XMPPTCPConnection.this.compressSyncPoint.reportSuccess();
                                    continue;
                                case 11:
                                    StreamManagement.Enabled enabled = ParseStreamManagement.enabled(this.parser);
                                    if (!enabled.isResumeSet()) {
                                        XMPPTCPConnection.this.smSessionId = null;
                                    } else {
                                        XMPPTCPConnection.this.smSessionId = enabled.getId();
                                        if (!StringUtils.isNullOrEmpty(XMPPTCPConnection.this.smSessionId)) {
                                            XMPPTCPConnection.this.smServerMaxResumptionTime = enabled.getMaxResumptionTime();
                                        } else {
                                            SmackException smackException = new SmackException("Stream Management 'enabled' element with resume attribute but without session id received");
                                            XMPPTCPConnection.this.smEnabledSyncPoint.reportFailure(smackException);
                                            throw smackException;
                                        }
                                    }
                                    XMPPTCPConnection.this.clientHandledStanzasCount = 0L;
                                    XMPPTCPConnection.this.smWasEnabledAtLeastOnce = true;
                                    XMPPTCPConnection.this.smEnabledSyncPoint.reportSuccess();
                                    XMPPTCPConnection.LOGGER.fine("Stream Management (XEP-198): successfully enabled");
                                    continue;
                                case '\f':
                                    StreamManagement.Failed failed = ParseStreamManagement.failed(this.parser);
                                    XMPPException.FailedNonzaException failedNonzaException = new XMPPException.FailedNonzaException(failed, failed.getStanzaErrorCondition());
                                    if (XMPPTCPConnection.this.smResumedSyncPoint.requestSent()) {
                                        XMPPTCPConnection.this.smResumedSyncPoint.reportFailure(failedNonzaException);
                                        continue;
                                    } else if (XMPPTCPConnection.this.smEnabledSyncPoint.requestSent()) {
                                        XMPPTCPConnection.this.smEnabledSyncPoint.reportFailure(new SmackException(failedNonzaException));
                                        XMPPTCPConnection.this.lastFeaturesReceived.reportSuccess();
                                        break;
                                    } else {
                                        throw new IllegalStateException("Failed element received but SM was not previously enabled");
                                    }
                                case '\r':
                                    StreamManagement.Resumed resumed = ParseStreamManagement.resumed(this.parser);
                                    if (XMPPTCPConnection.this.smSessionId.equals(resumed.getPrevId())) {
                                        XMPPTCPConnection.this.smEnabledSyncPoint.reportSuccess();
                                        XMPPTCPConnection.this.processHandledCount(resumed.getHandledCount());
                                        ArrayList<Stanza> arrayList = new ArrayList(XMPPTCPConnection.this.unacknowledgedStanzas.size());
                                        XMPPTCPConnection.this.unacknowledgedStanzas.drainTo(arrayList);
                                        for (Stanza stanza : arrayList) {
                                            XMPPTCPConnection.this.sendStanzaInternal(stanza);
                                        }
                                        if (!arrayList.isEmpty()) {
                                            XMPPTCPConnection.this.requestSmAcknowledgementInternal();
                                        }
                                        XMPPTCPConnection.this.smResumedSyncPoint.reportSuccess();
                                        XMPPTCPConnection.LOGGER.fine("Stream Management (XEP-198): Stream resumed");
                                        continue;
                                    } else {
                                        throw new StreamManagementException.StreamIdDoesNotMatchException(XMPPTCPConnection.this.smSessionId, resumed.getPrevId());
                                    }
                                case 14:
                                    XMPPTCPConnection.this.processHandledCount(ParseStreamManagement.ackAnswer(this.parser).getHandledCount());
                                    continue;
                                case 15:
                                    ParseStreamManagement.ackRequest(this.parser);
                                    if (XMPPTCPConnection.this.smEnabledSyncPoint.wasSuccessful()) {
                                        XMPPTCPConnection.this.sendSmAcknowledgementInternal();
                                        continue;
                                    } else {
                                        XMPPTCPConnection.LOGGER.warning("SM Ack Request received while SM is not enabled");
                                        break;
                                    }
                                default:
                                    Logger logger3 = XMPPTCPConnection.LOGGER;
                                    logger3.warning("Unknown top level stream element: " + name);
                                    continue;
                            }
                        }
                        eventType = this.parser.next();
                    } else {
                        throw new SmackException("Parser got END_DOCUMENT event. This could happen e.g. if the server closed the connection without sending a closing stream element");
                    }
                }
            } catch (Exception e2) {
                XMPPTCPConnection.this.closingStreamReceived.reportFailure(e2);
                if (this.done || XMPPTCPConnection.this.packetWriter.queue.isShutdown()) {
                    return;
                }
                XMPPTCPConnection.this.notifyConnectionError(e2);
            }
        }

        public void init() {
            this.done = false;
            Async.go(new Runnable() {
                @Override
                public void run() {
                    Logger logger = XMPPTCPConnection.LOGGER;
                    logger.finer(PacketReader.this.threadName + " start");
                    try {
                        PacketReader.this.parsePackets();
                    } finally {
                        Logger logger2 = XMPPTCPConnection.LOGGER;
                        logger2.finer(PacketReader.this.threadName + " exit");
                        XMPPTCPConnection.this.readerWriterSemaphore.release();
                    }
                }
            }, this.threadName);
        }

        public void shutdown() {
            this.done = true;
        }
    }

    public class PacketWriter {
        public static final int QUEUE_SIZE = 500;
        public volatile boolean instantShutdown;
        public boolean shouldBundleAndDefer;
        public SynchronizationPoint<SmackException.NoResponseException> shutdownDone;
        public final String threadName;
        public final ArrayBlockingQueueWithShutdown<Element> queue = new ArrayBlockingQueueWithShutdown<>(500, true);
        public volatile Long shutdownTimestamp = null;

        public PacketWriter() {
            this.threadName = "Smack Writer (" + XMPPTCPConnection.this.getConnectionCounter() + Operators.BRACKET_END;
            this.shutdownDone = new SynchronizationPoint<>(XMPPTCPConnection.this, "shutdown completed");
        }

        public boolean done() {
            return this.shutdownTimestamp != null;
        }

        private void drainWriterQueueToUnacknowledgedStanzas() {
            ArrayList arrayList = new ArrayList(this.queue.size());
            this.queue.drainTo(arrayList);
            for (int i = 0; i < arrayList.size(); i++) {
                Element element = (Element) arrayList.get(i);
                if (XMPPTCPConnection.this.unacknowledgedStanzas.remainingCapacity() == 0) {
                    XMPPTCPConnection.LOGGER.log(Level.WARNING, "Some stanzas may be lost as not all could be drained to the unacknowledged stanzas queue", (Throwable) StreamManagementException.UnacknowledgedQueueFullException.newWith(i, arrayList, XMPPTCPConnection.this.unacknowledgedStanzas));
                    return;
                }
                if (element instanceof Stanza) {
                    XMPPTCPConnection.this.unacknowledgedStanzas.add((Stanza) element);
                }
            }
        }

        private void maybeAddToUnacknowledgedStanzas(Stanza stanza) throws IOException {
            if (XMPPTCPConnection.this.unacknowledgedStanzas == null || stanza == null) {
                return;
            }
            if (XMPPTCPConnection.this.unacknowledgedStanzas.size() == 400.0d) {
                XMPPTCPConnection.this.writer.write(StreamManagement.AckRequest.INSTANCE.toXML(null).toString());
                XMPPTCPConnection.this.writer.flush();
            }
            try {
                XMPPTCPConnection.this.unacknowledgedStanzas.put(stanza);
            } catch (InterruptedException e) {
                throw new IllegalStateException(e);
            }
        }

        private Element nextStreamElement() {
            if (this.queue.isEmpty()) {
                this.shouldBundleAndDefer = true;
            }
            try {
                return this.queue.take();
            } catch (InterruptedException e) {
                if (this.queue.isShutdown()) {
                    return null;
                }
                XMPPTCPConnection.LOGGER.log(Level.WARNING, "Writer thread was interrupted. Don't do that. Use disconnect() instead.", (Throwable) e);
                return null;
            }
        }

        public void writePackets() {
            Stanza stanza;
            Exception exc = null;
            try {
                try {
                    XMPPTCPConnection.this.openStream();
                    XMPPTCPConnection.this.initialOpenStreamSend.reportSuccess();
                    while (!done()) {
                        Element nextStreamElement = nextStreamElement();
                        if (nextStreamElement != null) {
                            BundleAndDeferCallback bundleAndDeferCallback = XMPPTCPConnection.this.bundleAndDeferCallback;
                            if (bundleAndDeferCallback != null && XMPPTCPConnection.this.isAuthenticated() && this.shouldBundleAndDefer) {
                                this.shouldBundleAndDefer = false;
                                AtomicBoolean atomicBoolean = new AtomicBoolean();
                                int bundleAndDeferMillis = bundleAndDeferCallback.getBundleAndDeferMillis(new BundleAndDefer(atomicBoolean));
                                if (bundleAndDeferMillis > 0) {
                                    long j = bundleAndDeferMillis;
                                    long currentTimeMillis = System.currentTimeMillis();
                                    synchronized (atomicBoolean) {
                                        for (long j2 = j; !atomicBoolean.get() && j2 > 0; j2 = j - (System.currentTimeMillis() - currentTimeMillis)) {
                                            atomicBoolean.wait(j2);
                                        }
                                    }
                                }
                            }
                            if (nextStreamElement instanceof Stanza) {
                                stanza = (Stanza) nextStreamElement;
                            } else {
                                if (nextStreamElement instanceof StreamManagement.Enable) {
                                    XMPPTCPConnection.this.unacknowledgedStanzas = new ArrayBlockingQueue(500);
                                }
                                stanza = null;
                            }
                            maybeAddToUnacknowledgedStanzas(stanza);
                            CharSequence xml = nextStreamElement.toXML("jabber:client");
                            if (xml instanceof XmlStringBuilder) {
                                ((XmlStringBuilder) xml).write(XMPPTCPConnection.this.writer, "jabber:client");
                            } else {
                                XMPPTCPConnection.this.writer.write(xml.toString());
                            }
                            if (this.queue.isEmpty()) {
                                XMPPTCPConnection.this.writer.flush();
                            }
                            if (stanza != null) {
                                XMPPTCPConnection.this.firePacketSendingListeners(stanza);
                            }
                        }
                    }
                    if (!this.instantShutdown) {
                        while (!this.queue.isEmpty()) {
                            try {
                                Element remove = this.queue.remove();
                                if (remove instanceof Stanza) {
                                    maybeAddToUnacknowledgedStanzas((Stanza) remove);
                                }
                                XMPPTCPConnection.this.writer.write(remove.toXML(null).toString());
                            } catch (Exception e) {
                                XMPPTCPConnection.LOGGER.log(Level.WARNING, "Exception flushing queue during shutdown, ignore and continue", (Throwable) e);
                            }
                        }
                        XMPPTCPConnection.this.writer.flush();
                        try {
                            XMPPTCPConnection.this.writer.write("</stream:stream>");
                            XMPPTCPConnection.this.writer.flush();
                        } catch (Exception e2) {
                            XMPPTCPConnection.LOGGER.log(Level.WARNING, "Exception writing closing stream element", (Throwable) e2);
                        }
                        this.queue.clear();
                    } else if (this.instantShutdown && XMPPTCPConnection.this.isSmEnabled()) {
                        drainWriterQueueToUnacknowledgedStanzas();
                    }
                } catch (Exception e3) {
                    if (done() || this.queue.isShutdown()) {
                        XMPPTCPConnection.LOGGER.log(Level.FINE, "Ignoring Exception in writePackets()", (Throwable) e3);
                    } else {
                        exc = e3;
                    }
                }
                if (exc != null) {
                    XMPPTCPConnection.this.notifyConnectionError(exc);
                }
            } finally {
                XMPPTCPConnection.LOGGER.fine("Reporting shutdownDone success in writer thread");
                this.shutdownDone.reportSuccess();
            }
        }

        public void init() {
            this.shutdownDone.init();
            this.shutdownTimestamp = null;
            if (XMPPTCPConnection.this.unacknowledgedStanzas != null) {
                drainWriterQueueToUnacknowledgedStanzas();
            }
            this.queue.start();
            Async.go(new Runnable() {
                @Override
                public void run() {
                    Logger logger = XMPPTCPConnection.LOGGER;
                    logger.finer(PacketWriter.this.threadName + " start");
                    try {
                        PacketWriter.this.writePackets();
                    } finally {
                        Logger logger2 = XMPPTCPConnection.LOGGER;
                        logger2.finer(PacketWriter.this.threadName + " exit");
                        XMPPTCPConnection.this.readerWriterSemaphore.release();
                    }
                }
            }, this.threadName);
        }

        public void sendStreamElement(Element element) throws SmackException.NotConnectedException, InterruptedException {
            throwNotConnectedExceptionIfDoneAndResumptionNotPossible();
            try {
                this.queue.put(element);
            } catch (InterruptedException e) {
                throwNotConnectedExceptionIfDoneAndResumptionNotPossible();
                throw e;
            }
        }

        public void shutdown(boolean z) {
            this.instantShutdown = z;
            this.queue.shutdown();
            this.shutdownTimestamp = Long.valueOf(System.currentTimeMillis());
            if (this.shutdownDone.isNotInInitialState()) {
                try {
                    this.shutdownDone.checkIfSuccessOrWait();
                } catch (InterruptedException | SmackException.NoResponseException e) {
                    XMPPTCPConnection.LOGGER.log(Level.WARNING, "shutdownDone was not marked as successful by the writer thread", e);
                }
            }
        }

        public void throwNotConnectedExceptionIfDoneAndResumptionNotPossible() throws SmackException.NotConnectedException {
            boolean isSmResumptionPossible;
            boolean done = done();
            if (!done || (isSmResumptionPossible = XMPPTCPConnection.this.isSmResumptionPossible())) {
                return;
            }
            XMPPTCPConnection xMPPTCPConnection = XMPPTCPConnection.this;
            throw new SmackException.NotConnectedException(xMPPTCPConnection, "done=" + done + " smResumptionPossible=" + isSmResumptionPossible);
        }
    }

    public XMPPTCPConnection(XMPPTCPConnectionConfiguration xMPPTCPConnectionConfiguration) {
        super(xMPPTCPConnectionConfiguration);
        this.disconnectedButResumeable = false;
        this.readerWriterSemaphore = new Semaphore(2);
        this.packetWriter = new PacketWriter();
        this.packetReader = new PacketReader();
        this.initialOpenStreamSend = new SynchronizationPoint<>(this, "initial open stream element send to server");
        this.maybeCompressFeaturesReceived = new SynchronizationPoint<>(this, "stream compression feature");
        this.compressSyncPoint = new SynchronizationPoint<>(this, "stream compression");
        this.closingStreamReceived = new SynchronizationPoint<>(this, "stream closing element received");
        this.bundleAndDeferCallback = defaultBundleAndDeferCallback;
        this.smResumedSyncPoint = new SynchronizationPoint<>(this, "stream resumed element");
        this.smEnabledSyncPoint = new SynchronizationPoint<>(this, "stream enabled element");
        this.smClientMaxResumptionTime = -1;
        this.smServerMaxResumptionTime = -1;
        this.useSm = useSmDefault;
        this.useSmResumption = useSmResumptionDefault;
        this.serverHandledStanzasCount = 0L;
        this.clientHandledStanzasCount = 0L;
        this.smWasEnabledAtLeastOnce = false;
        this.stanzaAcknowledgedListeners = new ConcurrentLinkedQueue();
        this.stanzaDroppedListeners = new ConcurrentLinkedQueue();
        this.stanzaIdAcknowledgedListeners = new ConcurrentHashMap();
        this.requestAckPredicates = new LinkedHashSet();
        this.config = xMPPTCPConnectionConfiguration;
        addConnectionListener(new AbstractConnectionListener() {
            @Override
            public void connectionClosedOnError(Exception exc) {
                if ((exc instanceof XMPPException.StreamErrorException) || (exc instanceof StreamManagementException)) {
                    XMPPTCPConnection.this.dropSmState();
                }
            }
        });
    }

    private void connectUsingConfiguration() throws SmackException.ConnectionException, IOException, InterruptedException {
        Iterator<HostAddress> it;
        List<HostAddress> populateHostAddresses = populateHostAddresses();
        SocketFactory socketFactory = this.config.getSocketFactory();
        ProxyInfo proxyInfo = this.config.getProxyInfo();
        int connectTimeout = this.config.getConnectTimeout();
        if (socketFactory == null) {
            socketFactory = SocketFactory.getDefault();
        }
        SocketFactory socketFactory2 = socketFactory;
        Iterator<HostAddress> it2 = this.hostAddresses.iterator();
        while (it2.hasNext()) {
            HostAddress next = it2.next();
            String host = next.getHost();
            int port = next.getPort();
            if (proxyInfo == null) {
                Iterator<InetAddress> it3 = next.getInetAddresses().iterator();
                while (true) {
                    if (!it3.hasNext()) {
                        it = it2;
                        break;
                    }
                    SmackFuture.SocketFuture socketFuture = new SmackFuture.SocketFuture(socketFactory2);
                    InetAddress next2 = it3.next();
                    InetSocketAddress inetSocketAddress = new InetSocketAddress(next2, port);
                    Logger logger = LOGGER;
                    StringBuilder sb = new StringBuilder();
                    it = it2;
                    sb.append("Trying to establish TCP connection to ");
                    sb.append(inetSocketAddress);
                    logger.finer(sb.toString());
                    socketFuture.connectAsync(inetSocketAddress, connectTimeout);
                    try {
                        this.socket = socketFuture.getOrThrow();
                        LOGGER.finer("Established TCP connection to " + inetSocketAddress);
                        this.host = host;
                        this.port = port;
                        return;
                    } catch (IOException e) {
                        next.setException(next2, e);
                        if (!it3.hasNext()) {
                            break;
                        }
                        it2 = it;
                    }
                }
                populateHostAddresses.add(next);
            } else {
                it = it2;
                this.socket = socketFactory2.createSocket();
                StringUtils.requireNotNullOrEmpty(host, "Host of HostAddress " + next + " must not be null when using a Proxy");
                String str = host + " at port " + port;
                LOGGER.finer("Trying to establish TCP connection via Proxy to " + str);
                try {
                    proxyInfo.getProxySocketConnection().connect(this.socket, host, port, connectTimeout);
                    LOGGER.finer("Established TCP connection to " + str);
                    this.host = host;
                    this.port = port;
                    return;
                } catch (IOException e2) {
                    next.setException(e2);
                    populateHostAddresses.add(next);
                }
            }
            it2 = it;
        }
        throw SmackException.ConnectionException.from(populateHostAddresses);
    }

    public void dropSmState() {
        this.smSessionId = null;
        this.unacknowledgedStanzas = null;
    }

    private void initConnection() throws IOException, InterruptedException {
        this.compressionHandler = null;
        initReaderAndWriter();
        int availablePermits = this.readerWriterSemaphore.availablePermits();
        if (availablePermits < 2) {
            LOGGER.log(Level.FINE, "Not every reader/writer threads where terminated on connection re-initializtion of {0}. Available permits {1}", new Object[]{this, Integer.valueOf(availablePermits)});
        }
        this.readerWriterSemaphore.acquire(2);
        this.packetWriter.init();
        this.packetReader.init();
    }

    public void initReaderAndWriter() throws IOException {
        InputStream inputStream = this.socket.getInputStream();
        OutputStream outputStream = this.socket.getOutputStream();
        XMPPInputOutputStream xMPPInputOutputStream = this.compressionHandler;
        if (xMPPInputOutputStream != null) {
            inputStream = xMPPInputOutputStream.getInputStream(inputStream);
            outputStream = this.compressionHandler.getOutputStream(outputStream);
        }
        this.writer = new OutputStreamWriter(outputStream, "UTF-8");
        this.reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
        initDebugger();
    }

    private void maybeEnableCompression() throws SmackException, InterruptedException {
        Compress.Feature feature;
        if (this.config.isCompressionEnabled() && (feature = (Compress.Feature) getFeature(Compress.Feature.ELEMENT, "http://jabber.org/protocol/compress")) != null) {
            XMPPInputOutputStream maybeGetCompressionHandler = maybeGetCompressionHandler(feature);
            this.compressionHandler = maybeGetCompressionHandler;
            if (maybeGetCompressionHandler != null) {
                this.compressSyncPoint.sendAndWaitForResponseOrThrow(new Compress(this.compressionHandler.getCompressionMethod()));
            } else {
                LOGGER.warning("Could not enable compression because no matching handler/method pair was found");
            }
        }
    }

    public static XMPPInputOutputStream maybeGetCompressionHandler(Compress.Feature feature) {
        for (XMPPInputOutputStream xMPPInputOutputStream : SmackConfiguration.getCompressionHandlers()) {
            if (feature.getMethods().contains(xMPPInputOutputStream.getCompressionMethod())) {
                return xMPPInputOutputStream;
            }
        }
        return null;
    }

    public void notifyConnectionError(final Exception exc) {
        AbstractXMPPConnection.ASYNC_BUT_ORDERED.performAsyncButOrdered(this, new Runnable() {
            public static final boolean $assertionsDisabled = false;

            @Override
            public void run() {
                if (XMPPTCPConnection.this.packetReader.done || XMPPTCPConnection.this.packetWriter.done()) {
                    return;
                }
                SmackException.SmackWrappedException smackWrappedException = new SmackException.SmackWrappedException(exc);
                XMPPTCPConnection.this.tlsHandled.reportGenericFailure(smackWrappedException);
                XMPPTCPConnection.this.saslFeatureReceived.reportGenericFailure(smackWrappedException);
                XMPPTCPConnection.this.maybeCompressFeaturesReceived.reportGenericFailure(smackWrappedException);
                XMPPTCPConnection.this.lastFeaturesReceived.reportGenericFailure(smackWrappedException);
                synchronized (XMPPTCPConnection.this) {
                    XMPPTCPConnection.this.instantShutdown();
                }
                Runnable runnable = new Runnable() {
                    @Override
                    public void run() {
                        AnonymousClass2 anonymousClass2 = AnonymousClass2.this;
                        XMPPTCPConnection.this.callConnectionClosedOnErrorListener(exc);
                    }
                };
                Async.go(runnable, XMPPTCPConnection.this + " callConnectionClosedOnErrorListener()");
            }
        });
    }

    public void proceedTLSReceived() throws NoSuchAlgorithmException, CertificateException, IOException, KeyStoreException, NoSuchProviderException, UnrecoverableKeyException, KeyManagementException, SmackException {
        SmackDaneVerifier smackDaneVerifier;
        HostnameVerifier hostnameVerifier;
        String obj;
        KeyStore keyStore;
        PasswordCallback passwordCallback;
        PasswordCallback passwordCallback2;
        KeyManager[] keyManagerArr;
        KeyManagerFactory keyManagerFactory;
        if (this.config.getDnssecMode() == ConnectionConfiguration.DnssecMode.needsDnssecAndDane) {
            SmackDaneProvider daneProvider = DNSUtil.getDaneProvider();
            if (daneProvider != null) {
                smackDaneVerifier = daneProvider.newInstance();
                if (smackDaneVerifier == null) {
                    throw new IllegalStateException("DANE requested but DANE provider did not return a DANE verifier");
                }
            } else {
                throw new UnsupportedOperationException("DANE enabled but no SmackDaneProvider configured");
            }
        } else {
            smackDaneVerifier = null;
        }
        SSLContext customSSLContext = this.config.getCustomSSLContext();
        if (customSSLContext == null) {
            String keystoreType = this.config.getKeystoreType();
            CallbackHandler callbackHandler = this.config.getCallbackHandler();
            String keystorePath = this.config.getKeystorePath();
            if ("PKCS11".equals(keystoreType)) {
                try {
                    Provider provider = (Provider) Class.forName("sun.security.pkcs11.SunPKCS11").getConstructor(InputStream.class).newInstance(new ByteArrayInputStream(("name = SmartCard\nlibrary = " + this.config.getPKCS11Library()).getBytes("UTF-8")));
                    Security.addProvider(provider);
                    keyStore = KeyStore.getInstance("PKCS11", provider);
                    passwordCallback = new PasswordCallback("PKCS11 Password: ", false);
                } catch (Exception e) {
                    e = e;
                    passwordCallback = null;
                }
                try {
                    callbackHandler.handle(new Callback[]{passwordCallback});
                    keyStore.load(null, passwordCallback.getPassword());
                } catch (Exception e2) {
                    e = e2;
                    LOGGER.log(Level.WARNING, "Exception", (Throwable) e);
                    keyStore = null;
                    if (keyStore != null) {
                    }
                    keyManagerArr = null;
                    SSLContext sSLContext = SSLContext.getInstance("TLS");
                    SecureRandom secureRandom = new SecureRandom();
                    X509TrustManager customX509TrustManager = this.config.getCustomX509TrustManager();
                    if (smackDaneVerifier == null) {
                    }
                    customSSLContext = sSLContext;
                    Socket socket = this.socket;
                    this.socket = customSSLContext.getSocketFactory().createSocket(socket, this.config.getXMPPServiceDomain().toString(), socket.getPort(), true);
                    SSLSocket sSLSocket = (SSLSocket) this.socket;
                    TLSUtils.setEnabledProtocolsAndCiphers(sSLSocket, this.config.getEnabledSSLProtocols(), this.config.getEnabledSSLCiphers());
                    initReaderAndWriter();
                    sSLSocket.startHandshake();
                    if (smackDaneVerifier != null) {
                    }
                    hostnameVerifier = getConfiguration().getHostnameVerifier();
                    if (hostnameVerifier != null) {
                    }
                }
            } else {
                if ("Apple".equals(keystoreType)) {
                    keyStore = KeyStore.getInstance("KeychainStore", "Apple");
                    keyStore.load(null, null);
                } else if (keystoreType != null) {
                    keyStore = KeyStore.getInstance(keystoreType);
                    if (callbackHandler != null && StringUtils.isNotEmpty(keystorePath)) {
                        try {
                            passwordCallback2 = new PasswordCallback("Keystore Password: ", false);
                        } catch (Exception e3) {
                            e = e3;
                            passwordCallback2 = null;
                        }
                        try {
                            callbackHandler.handle(new Callback[]{passwordCallback2});
                            keyStore.load(new FileInputStream(keystorePath), passwordCallback2.getPassword());
                        } catch (Exception e4) {
                            e = e4;
                            LOGGER.log(Level.WARNING, "Exception", (Throwable) e);
                            keyStore = null;
                            passwordCallback = passwordCallback2;
                            if (keyStore != null) {
                            }
                            keyManagerArr = null;
                            SSLContext sSLContext2 = SSLContext.getInstance("TLS");
                            SecureRandom secureRandom2 = new SecureRandom();
                            X509TrustManager customX509TrustManager2 = this.config.getCustomX509TrustManager();
                            if (smackDaneVerifier == null) {
                            }
                            customSSLContext = sSLContext2;
                            Socket socket2 = this.socket;
                            this.socket = customSSLContext.getSocketFactory().createSocket(socket2, this.config.getXMPPServiceDomain().toString(), socket2.getPort(), true);
                            SSLSocket sSLSocket2 = (SSLSocket) this.socket;
                            TLSUtils.setEnabledProtocolsAndCiphers(sSLSocket2, this.config.getEnabledSSLProtocols(), this.config.getEnabledSSLCiphers());
                            initReaderAndWriter();
                            sSLSocket2.startHandshake();
                            if (smackDaneVerifier != null) {
                            }
                            hostnameVerifier = getConfiguration().getHostnameVerifier();
                            if (hostnameVerifier != null) {
                            }
                        }
                        passwordCallback = passwordCallback2;
                    } else {
                        keyStore.load(null, null);
                    }
                } else {
                    keyStore = null;
                    passwordCallback = null;
                }
                passwordCallback = null;
            }
            if (keyStore != null) {
                String defaultAlgorithm = KeyManagerFactory.getDefaultAlgorithm();
                try {
                    keyManagerFactory = KeyManagerFactory.getInstance(defaultAlgorithm);
                } catch (NoSuchAlgorithmException e5) {
                    LOGGER.log(Level.FINE, "Could get the default KeyManagerFactory for the '" + defaultAlgorithm + "' algorithm", (Throwable) e5);
                    keyManagerFactory = null;
                }
                if (keyManagerFactory != null) {
                    try {
                        if (passwordCallback == null) {
                            keyManagerFactory.init(keyStore, null);
                        } else {
                            keyManagerFactory.init(keyStore, passwordCallback.getPassword());
                            passwordCallback.clearPassword();
                        }
                        keyManagerArr = keyManagerFactory.getKeyManagers();
                    } catch (NullPointerException e6) {
                        LOGGER.log(Level.WARNING, "NullPointerException", (Throwable) e6);
                    }
                    SSLContext sSLContext22 = SSLContext.getInstance("TLS");
                    SecureRandom secureRandom22 = new SecureRandom();
                    X509TrustManager customX509TrustManager22 = this.config.getCustomX509TrustManager();
                    if (smackDaneVerifier == null) {
                        smackDaneVerifier.init(sSLContext22, keyManagerArr, customX509TrustManager22, secureRandom22);
                    } else {
                        sSLContext22.init(keyManagerArr, customX509TrustManager22 != null ? new TrustManager[]{customX509TrustManager22} : null, secureRandom22);
                    }
                    customSSLContext = sSLContext22;
                }
            }
            keyManagerArr = null;
            SSLContext sSLContext222 = SSLContext.getInstance("TLS");
            SecureRandom secureRandom222 = new SecureRandom();
            X509TrustManager customX509TrustManager222 = this.config.getCustomX509TrustManager();
            if (smackDaneVerifier == null) {
            }
            customSSLContext = sSLContext222;
        }
        Socket socket22 = this.socket;
        this.socket = customSSLContext.getSocketFactory().createSocket(socket22, this.config.getXMPPServiceDomain().toString(), socket22.getPort(), true);
        SSLSocket sSLSocket22 = (SSLSocket) this.socket;
        TLSUtils.setEnabledProtocolsAndCiphers(sSLSocket22, this.config.getEnabledSSLProtocols(), this.config.getEnabledSSLCiphers());
        initReaderAndWriter();
        sSLSocket22.startHandshake();
        if (smackDaneVerifier != null) {
            smackDaneVerifier.finish(sSLSocket22);
        }
        hostnameVerifier = getConfiguration().getHostnameVerifier();
        if (hostnameVerifier != null) {
            ez3 xmppServiceDomainAsDnsNameIfPossible = getConfiguration().getXmppServiceDomainAsDnsNameIfPossible();
            if (xmppServiceDomainAsDnsNameIfPossible != null) {
                obj = xmppServiceDomainAsDnsNameIfPossible.a;
            } else {
                LOGGER.log(Level.WARNING, "XMPP service domain name '" + ((Object) getXMPPServiceDomain()) + "' can not be represented as DNS name. TLS X.509 certificate validiation may fail.");
                obj = getXMPPServiceDomain().toString();
            }
            if (hostnameVerifier.verify(obj, sSLSocket22.getSession())) {
                this.secureSocket = sSLSocket22;
                return;
            }
            throw new CertificateException("Hostname verification of certificate failed. Certificate does not authenticate " + ((Object) getXMPPServiceDomain()));
        }
        throw new IllegalStateException("No HostnameVerifier set. Use connectionConfiguration.setHostnameVerifier() to configure.");
    }

    public void processHandledCount(long j) throws StreamManagementException.StreamManagementCounterError {
        long calculateDelta = SMUtils.calculateDelta(j, this.serverHandledStanzasCount);
        final ArrayList arrayList = new ArrayList(calculateDelta <= 2147483647L ? (int) calculateDelta : Integer.MAX_VALUE);
        for (long j2 = 0; j2 < calculateDelta; j2++) {
            Stanza poll = this.unacknowledgedStanzas.poll();
            if (poll != null) {
                arrayList.add(poll);
            } else {
                throw new StreamManagementException.StreamManagementCounterError(j, this.serverHandledStanzasCount, calculateDelta, arrayList);
            }
        }
        boolean z = true;
        if (this.stanzaAcknowledgedListeners.isEmpty()) {
            Iterator it = arrayList.iterator();
            while (true) {
                if (!it.hasNext()) {
                    z = false;
                    break;
                }
                String stanzaId = ((Stanza) it.next()).getStanzaId();
                if (stanzaId != null && this.stanzaIdAcknowledgedListeners.containsKey(stanzaId)) {
                    break;
                }
            }
        }
        if (z) {
            AbstractXMPPConnection.asyncGo(new Runnable() {
                @Override
                public void run() {
                    StanzaListener stanzaListener;
                    for (Stanza stanza : arrayList) {
                        for (StanzaListener stanzaListener2 : XMPPTCPConnection.this.stanzaAcknowledgedListeners) {
                            try {
                                stanzaListener2.processStanza(stanza);
                            } catch (InterruptedException | SmackException.NotConnectedException | SmackException.NotLoggedInException e) {
                                XMPPTCPConnection.LOGGER.log(Level.FINER, "Received exception", e);
                            }
                        }
                        String stanzaId2 = stanza.getStanzaId();
                        if (!StringUtils.isNullOrEmpty(stanzaId2) && (stanzaListener = (StanzaListener) XMPPTCPConnection.this.stanzaIdAcknowledgedListeners.remove(stanzaId2)) != null) {
                            try {
                                stanzaListener.processStanza(stanza);
                            } catch (InterruptedException | SmackException.NotConnectedException | SmackException.NotLoggedInException e2) {
                                XMPPTCPConnection.LOGGER.log(Level.FINER, "Received exception", e2);
                            }
                        }
                    }
                }
            });
        }
        this.serverHandledStanzasCount = j;
    }

    public void requestSmAcknowledgementInternal() throws SmackException.NotConnectedException, InterruptedException {
        this.packetWriter.sendStreamElement(StreamManagement.AckRequest.INSTANCE);
    }

    public void sendSmAcknowledgementInternal() throws SmackException.NotConnectedException, InterruptedException {
        this.packetWriter.sendStreamElement(new StreamManagement.AckAnswer(this.clientHandledStanzasCount));
    }

    public static void setDefaultBundleAndDeferCallback(BundleAndDeferCallback bundleAndDeferCallback) {
        defaultBundleAndDeferCallback = bundleAndDeferCallback;
    }

    public static void setUseStreamManagementDefault(boolean z) {
        useSmDefault = z;
    }

    @Deprecated
    public static void setUseStreamManagementResumptiodDefault(boolean z) {
        setUseStreamManagementResumptionDefault(z);
    }

    public static void setUseStreamManagementResumptionDefault(boolean z) {
        if (z) {
            setUseStreamManagementDefault(z);
        }
        useSmResumptionDefault = z;
    }

    public boolean addRequestAckPredicate(StanzaFilter stanzaFilter) {
        boolean add;
        synchronized (this.requestAckPredicates) {
            add = this.requestAckPredicates.add(stanzaFilter);
        }
        return add;
    }

    public void addStanzaAcknowledgedListener(StanzaListener stanzaListener) {
        this.stanzaAcknowledgedListeners.add(stanzaListener);
    }

    public void addStanzaDroppedListener(StanzaListener stanzaListener) {
        this.stanzaDroppedListeners.add(stanzaListener);
    }

    public StanzaListener addStanzaIdAcknowledgedListener(final String str, StanzaListener stanzaListener) throws StreamManagementException.StreamManagementNotEnabledException {
        if (this.smWasEnabledAtLeastOnce) {
            AbstractXMPPConnection.schedule(new Runnable() {
                @Override
                public void run() {
                    XMPPTCPConnection.this.stanzaIdAcknowledgedListeners.remove(str);
                }
            }, Math.min(getMaxSmResumptionTime(), 10800), TimeUnit.SECONDS);
            return this.stanzaIdAcknowledgedListeners.put(str, stanzaListener);
        }
        throw new StreamManagementException.StreamManagementNotEnabledException();
    }

    @Override
    public void afterFeaturesReceived() throws SmackException.NotConnectedException, InterruptedException, SmackException.SecurityRequiredByServerException {
        StartTls startTls = (StartTls) getFeature(StartTls.ELEMENT, StartTls.NAMESPACE);
        if (startTls != null) {
            if (startTls.required() && this.config.getSecurityMode() == ConnectionConfiguration.SecurityMode.disabled) {
                SmackException.SecurityRequiredByServerException securityRequiredByServerException = new SmackException.SecurityRequiredByServerException();
                this.tlsHandled.reportFailure(securityRequiredByServerException);
                throw securityRequiredByServerException;
            } else if (this.config.getSecurityMode() != ConnectionConfiguration.SecurityMode.disabled) {
                sendNonza(new StartTls());
            } else {
                this.tlsHandled.reportSuccess();
            }
        } else {
            this.tlsHandled.reportSuccess();
        }
        if (getSASLAuthentication().authenticationSuccessful()) {
            this.maybeCompressFeaturesReceived.reportSuccess();
        }
    }

    @Override
    public void afterSuccessfulLogin(boolean z) throws SmackException.NotConnectedException, InterruptedException {
        this.disconnectedButResumeable = false;
        super.afterSuccessfulLogin(z);
    }

    @Override
    public void connectInternal() throws SmackException, IOException, XMPPException, InterruptedException {
        this.closingStreamReceived.init();
        connectUsingConfiguration();
        initConnection();
        this.tlsHandled.checkIfSuccessOrWaitOrThrow();
        this.saslFeatureReceived.checkIfSuccessOrWaitOrThrow();
    }

    public int getMaxSmResumptionTime() {
        int i = this.smClientMaxResumptionTime;
        if (i <= 0) {
            i = Integer.MAX_VALUE;
        }
        int i2 = this.smServerMaxResumptionTime;
        return Math.min(i, i2 > 0 ? i2 : Integer.MAX_VALUE);
    }

    @Override
    public void initState() {
        super.initState();
        this.maybeCompressFeaturesReceived.init();
        this.compressSyncPoint.init();
        this.smResumedSyncPoint.init();
        this.smEnabledSyncPoint.init();
        this.initialOpenStreamSend.init();
    }

    @Override
    public synchronized void instantShutdown() {
        shutdown(true);
    }

    public boolean isDisconnectedButSmResumptionPossible() {
        return this.disconnectedButResumeable && isSmResumptionPossible();
    }

    @Override
    public boolean isSecureConnection() {
        return this.secureSocket != null;
    }

    public boolean isSmAvailable() {
        return hasFeature("sm", StreamManagement.NAMESPACE);
    }

    public boolean isSmEnabled() {
        return this.smEnabledSyncPoint.wasSuccessful();
    }

    public boolean isSmResumptionPossible() {
        if (this.smSessionId == null) {
            return false;
        }
        Long l = this.packetWriter.shutdownTimestamp;
        if (l == null) {
            return true;
        }
        return System.currentTimeMillis() <= l.longValue() + (((long) getMaxSmResumptionTime()) * 1000);
    }

    @Override
    public boolean isUsingCompression() {
        return this.compressionHandler != null && this.compressSyncPoint.wasSuccessful();
    }

    @Override
    public synchronized void loginInternal(String str, String str2, hx3 hx3Var) throws XMPPException, SmackException, IOException, InterruptedException {
        this.saslAuthentication.authenticate(str, str2, this.config.getAuthzid(), this.secureSocket != null ? this.secureSocket.getSession() : null);
        this.maybeCompressFeaturesReceived.checkIfSuccessOrWait();
        maybeEnableCompression();
        if (isSmResumptionPossible()) {
            this.smResumedSyncPoint.sendAndWaitForResponse(new StreamManagement.Resume(this.clientHandledStanzasCount, this.smSessionId));
            if (this.smResumedSyncPoint.wasSuccessful()) {
                afterSuccessfulLogin(true);
                return;
            }
            LOGGER.fine("Stream resumption failed, continuing with normal stream establishment process");
        }
        LinkedList<Stanza> linkedList = new LinkedList();
        if (this.unacknowledgedStanzas != null) {
            this.unacknowledgedStanzas.drainTo(linkedList);
            dropSmState();
        }
        bindResourceAndEstablishSession(hx3Var);
        if (isSmAvailable() && this.useSm) {
            this.serverHandledStanzasCount = 0L;
            this.smEnabledSyncPoint.sendAndWaitForResponseOrThrow(new StreamManagement.Enable(this.useSmResumption, this.smClientMaxResumptionTime));
            synchronized (this.requestAckPredicates) {
                if (this.requestAckPredicates.isEmpty()) {
                    this.requestAckPredicates.add(Predicate.forMessagesOrAfter5Stanzas());
                }
            }
        }
        if (!this.stanzaDroppedListeners.isEmpty()) {
            for (Stanza stanza : linkedList) {
                for (StanzaListener stanzaListener : this.stanzaDroppedListeners) {
                    try {
                        stanzaListener.processStanza(stanza);
                    } catch (InterruptedException | SmackException.NotConnectedException | SmackException.NotLoggedInException e) {
                        LOGGER.log(Level.FINER, "StanzaDroppedListener received exception", e);
                    }
                }
            }
        } else {
            for (Stanza stanza2 : linkedList) {
                sendStanzaInternal(stanza2);
            }
        }
        afterSuccessfulLogin(false);
    }

    public void openStream() throws SmackException, InterruptedException {
        qw3 xMPPServiceDomain = getXMPPServiceDomain();
        CharSequence username = this.config.getUsername();
        sendNonza(new StreamOpen(xMPPServiceDomain, username != null ? qx3.a(username, xMPPServiceDomain) : null, getStreamId()));
        try {
            this.packetReader.parser = PacketParserUtils.newXmppParser(this.reader);
        } catch (XmlPullParserException e) {
            throw new SmackException(e);
        }
    }

    public void removeAllRequestAckPredicates() {
        synchronized (this.requestAckPredicates) {
            this.requestAckPredicates.clear();
        }
    }

    public void removeAllStanzaAcknowledgedListeners() {
        this.stanzaAcknowledgedListeners.clear();
    }

    public void removeAllStanzaIdAcknowledgedListeners() {
        this.stanzaIdAcknowledgedListeners.clear();
    }

    public boolean removeRequestAckPredicate(StanzaFilter stanzaFilter) {
        boolean remove;
        synchronized (this.requestAckPredicates) {
            remove = this.requestAckPredicates.remove(stanzaFilter);
        }
        return remove;
    }

    public boolean removeStanzaAcknowledgedListener(StanzaListener stanzaListener) {
        return this.stanzaAcknowledgedListeners.remove(stanzaListener);
    }

    public boolean removeStanzaDroppedListener(StanzaListener stanzaListener) {
        return this.stanzaDroppedListeners.remove(stanzaListener);
    }

    public StanzaListener removeStanzaIdAcknowledgedListener(String str) {
        return this.stanzaIdAcknowledgedListeners.remove(str);
    }

    public void requestSmAcknowledgement() throws StreamManagementException.StreamManagementNotEnabledException, SmackException.NotConnectedException, InterruptedException {
        if (isSmEnabled()) {
            requestSmAcknowledgementInternal();
            return;
        }
        throw new StreamManagementException.StreamManagementNotEnabledException();
    }

    @Override
    public void sendNonza(Nonza nonza) throws SmackException.NotConnectedException, InterruptedException {
        this.packetWriter.sendStreamElement(nonza);
    }

    public void sendSmAcknowledgement() throws StreamManagementException.StreamManagementNotEnabledException, SmackException.NotConnectedException, InterruptedException {
        if (isSmEnabled()) {
            sendSmAcknowledgementInternal();
            return;
        }
        throw new StreamManagementException.StreamManagementNotEnabledException();
    }

    @Override
    public void sendStanzaInternal(Stanza stanza) throws SmackException.NotConnectedException, InterruptedException {
        this.packetWriter.sendStreamElement(stanza);
        if (isSmEnabled()) {
            for (StanzaFilter stanzaFilter : this.requestAckPredicates) {
                if (stanzaFilter.accept(stanza)) {
                    requestSmAcknowledgementInternal();
                    return;
                }
            }
        }
    }

    public void setBundleandDeferCallback(BundleAndDeferCallback bundleAndDeferCallback) {
        this.bundleAndDeferCallback = bundleAndDeferCallback;
    }

    public void setPreferredResumptionTime(int i) {
        this.smClientMaxResumptionTime = i;
    }

    public void setUseStreamManagement(boolean z) {
        this.useSm = z;
    }

    public void setUseStreamManagementResumption(boolean z) {
        if (z) {
            setUseStreamManagement(z);
        }
        this.useSmResumption = z;
    }

    public void setWriter(Writer writer) {
        this.writer = writer;
    }

    @Override
    public void shutdown() {
        if (isSmEnabled()) {
            try {
                sendSmAcknowledgementInternal();
            } catch (InterruptedException | SmackException.NotConnectedException e) {
                LOGGER.log(Level.FINE, "Can not send final SM ack as connection is not connected", e);
            }
        }
        shutdown(false);
    }

    public boolean streamWasResumed() {
        return this.smResumedSyncPoint.wasSuccessful();
    }

    @Override
    public void throwAlreadyConnectedExceptionIfAppropriate() throws SmackException.AlreadyConnectedException {
        if (isConnected() && !this.disconnectedButResumeable) {
            throw new SmackException.AlreadyConnectedException();
        }
    }

    @Override
    public void throwAlreadyLoggedInExceptionIfAppropriate() throws SmackException.AlreadyLoggedInException {
        if (isAuthenticated() && !this.disconnectedButResumeable) {
            throw new SmackException.AlreadyLoggedInException();
        }
    }

    @Override
    public void throwNotConnectedExceptionIfAppropriate() throws SmackException.NotConnectedException {
        PacketWriter packetWriter = this.packetWriter;
        if (packetWriter != null) {
            packetWriter.throwNotConnectedExceptionIfDoneAndResumptionNotPossible();
            return;
        }
        throw new SmackException.NotConnectedException();
    }

    private void shutdown(boolean z) {
        LOGGER.finer("PacketWriter shutdown()");
        this.packetWriter.shutdown(z);
        LOGGER.finer("PacketWriter has been shut down");
        if (!z) {
            try {
                this.closingStreamReceived.checkIfSuccessOrWait();
            } catch (InterruptedException | SmackException.NoResponseException e) {
                Logger logger = LOGGER;
                Level level = Level.INFO;
                logger.log(level, "Exception while waiting for closing stream element from the server " + this, e);
            }
        }
        LOGGER.finer("PacketReader shutdown()");
        this.packetReader.shutdown();
        LOGGER.finer("PacketReader has been shut down");
        Socket socket = this.socket;
        if (socket != null && socket.isConnected()) {
            try {
                socket.close();
            } catch (Exception e2) {
                LOGGER.log(Level.WARNING, "shutdown", (Throwable) e2);
            }
        }
        setWasAuthenticated();
        this.readerWriterSemaphore.acquireUninterruptibly(2);
        this.readerWriterSemaphore.release(2);
        if (this.disconnectedButResumeable) {
            return;
        }
        if (isSmResumptionPossible() && z) {
            this.disconnectedButResumeable = true;
        } else {
            this.disconnectedButResumeable = false;
            this.smSessionId = null;
        }
        this.authenticated = false;
        this.connected = false;
        this.secureSocket = null;
        this.reader = null;
        this.writer = null;
        initState();
    }

    public XMPPTCPConnection(CharSequence charSequence, String str) throws lx3 {
        this(qx3.f(charSequence.toString()), str, qx3.e(charSequence.toString()));
    }

    public XMPPTCPConnection(CharSequence charSequence, String str, String str2) throws lx3 {
        this(XMPPTCPConnectionConfiguration.builder().setUsernameAndPassword(charSequence, str).setXmppDomain(bx3.b(str2)).build());
    }
}