001/**
002 *
003 * Copyright 2017 Paul Schaub
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * You may obtain a copy of the License at
008 *
009 *     http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.jivesoftware.smackx.jingle.transports.jingle_ibb;
018
019import java.util.logging.Level;
020import java.util.logging.Logger;
021
022import org.jivesoftware.smack.SmackException;
023import org.jivesoftware.smack.XMPPException;
024import org.jivesoftware.smack.packet.IQ;
025
026import org.jivesoftware.smackx.bytestreams.BytestreamListener;
027import org.jivesoftware.smackx.bytestreams.BytestreamRequest;
028import org.jivesoftware.smackx.bytestreams.BytestreamSession;
029import org.jivesoftware.smackx.bytestreams.ibb.InBandBytestreamManager;
030import org.jivesoftware.smackx.jingle.JingleSession;
031import org.jivesoftware.smackx.jingle.element.Jingle;
032import org.jivesoftware.smackx.jingle.element.JingleContentTransport;
033import org.jivesoftware.smackx.jingle.transports.JingleTransportInitiationCallback;
034import org.jivesoftware.smackx.jingle.transports.JingleTransportManager;
035import org.jivesoftware.smackx.jingle.transports.JingleTransportSession;
036import org.jivesoftware.smackx.jingle.transports.jingle_ibb.element.JingleIBBTransport;
037
038public class JingleIBBTransportSession extends JingleTransportSession<JingleIBBTransport> {
039    private static final Logger LOGGER = Logger.getLogger(JingleIBBTransportSession.class.getName());
040
041    private final JingleIBBTransportManager transportManager;
042
043    public JingleIBBTransportSession(JingleSession session) {
044        super(session);
045        transportManager = JingleIBBTransportManager.getInstanceFor(session.getConnection());
046    }
047
048    @Override
049    public JingleIBBTransport createTransport() {
050
051        if (theirProposal == null) {
052            return new JingleIBBTransport();
053        } else {
054            return new JingleIBBTransport(theirProposal.getBlockSize(), theirProposal.getSessionId());
055        }
056
057    }
058
059    @Override
060    public void setTheirProposal(JingleContentTransport transport) {
061        theirProposal = (JingleIBBTransport) transport;
062    }
063
064    @Override
065    public void initiateOutgoingSession(JingleTransportInitiationCallback callback) {
066        LOGGER.log(Level.INFO, "Initiate Jingle InBandBytestream session.");
067
068        BytestreamSession session;
069        try {
070            session = InBandBytestreamManager.getByteStreamManager(jingleSession.getConnection())
071                    .establishSession(jingleSession.getRemote(), theirProposal.getSessionId());
072            callback.onSessionInitiated(session);
073        } catch (SmackException.NoResponseException | InterruptedException | SmackException.NotConnectedException | XMPPException.XMPPErrorException e) {
074            callback.onException(e);
075        }
076    }
077
078    @Override
079    public void initiateIncomingSession(final JingleTransportInitiationCallback callback) {
080        LOGGER.log(Level.INFO, "Await Jingle InBandBytestream session.");
081
082        InBandBytestreamManager.getByteStreamManager(jingleSession.getConnection()).addIncomingBytestreamListener(new BytestreamListener() {
083            @Override
084            public void incomingBytestreamRequest(BytestreamRequest request) {
085                if (request.getFrom().asFullJidIfPossible().equals(jingleSession.getRemote())
086                        && request.getSessionID().equals(theirProposal.getSessionId())) {
087                    BytestreamSession session;
088
089                    try {
090                        session = request.accept();
091                    } catch (InterruptedException | SmackException | XMPPException.XMPPErrorException e) {
092                        callback.onException(e);
093                        return;
094                    }
095                    callback.onSessionInitiated(session);
096                }
097            }
098        });
099    }
100
101    @Override
102    public String getNamespace() {
103        return transportManager.getNamespace();
104    }
105
106    @Override
107    public IQ handleTransportInfo(Jingle transportInfo) {
108        return IQ.createResultIQ(transportInfo);
109        // TODO
110    }
111
112    @Override
113    public JingleTransportManager<JingleIBBTransport> transportManager() {
114        return JingleIBBTransportManager.getInstanceFor(jingleSession.getConnection());
115    }
116}