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;
025import org.jivesoftware.smackx.bytestreams.BytestreamListener;
026import org.jivesoftware.smackx.bytestreams.BytestreamRequest;
027import org.jivesoftware.smackx.bytestreams.BytestreamSession;
028import org.jivesoftware.smackx.bytestreams.ibb.InBandBytestreamManager;
029import org.jivesoftware.smackx.jingle.JingleSession;
030import org.jivesoftware.smackx.jingle.element.Jingle;
031import org.jivesoftware.smackx.jingle.element.JingleContentTransport;
032import org.jivesoftware.smackx.jingle.transports.JingleTransportInitiationCallback;
033import org.jivesoftware.smackx.jingle.transports.JingleTransportManager;
034import org.jivesoftware.smackx.jingle.transports.JingleTransportSession;
035import org.jivesoftware.smackx.jingle.transports.jingle_ibb.element.JingleIBBTransport;
036
037public class JingleIBBTransportSession extends JingleTransportSession<JingleIBBTransport> {
038    private static final Logger LOGGER = Logger.getLogger(JingleIBBTransportSession.class.getName());
039
040    private final JingleIBBTransportManager transportManager;
041
042    public JingleIBBTransportSession(JingleSession session) {
043        super(session);
044        transportManager = JingleIBBTransportManager.getInstanceFor(session.getConnection());
045    }
046
047    @Override
048    public JingleIBBTransport createTransport() {
049
050        if (theirProposal == null) {
051            return new JingleIBBTransport();
052        } else {
053            return new JingleIBBTransport(theirProposal.getBlockSize(), theirProposal.getSessionId());
054        }
055
056    }
057
058    @Override
059    public void setTheirProposal(JingleContentTransport transport) {
060        theirProposal = (JingleIBBTransport) transport;
061    }
062
063    @Override
064    public void initiateOutgoingSession(JingleTransportInitiationCallback callback) {
065        LOGGER.log(Level.INFO, "Initiate Jingle InBandBytestream session.");
066
067        BytestreamSession session;
068        try {
069            session = InBandBytestreamManager.getByteStreamManager(jingleSession.getConnection())
070                    .establishSession(jingleSession.getRemote(), theirProposal.getSessionId());
071            callback.onSessionInitiated(session);
072        } catch (SmackException.NoResponseException | InterruptedException | SmackException.NotConnectedException | XMPPException.XMPPErrorException e) {
073            callback.onException(e);
074        }
075    }
076
077    @Override
078    public void initiateIncomingSession(final JingleTransportInitiationCallback callback) {
079        LOGGER.log(Level.INFO, "Await Jingle InBandBytestream session.");
080
081        InBandBytestreamManager.getByteStreamManager(jingleSession.getConnection()).addIncomingBytestreamListener(new BytestreamListener() {
082            @Override
083            public void incomingBytestreamRequest(BytestreamRequest request) {
084                if (request.getFrom().asFullJidIfPossible().equals(jingleSession.getRemote())
085                        && request.getSessionID().equals(theirProposal.getSessionId())) {
086                    BytestreamSession session;
087
088                    try {
089                        session = request.accept();
090                    } catch (InterruptedException | SmackException | XMPPException.XMPPErrorException e) {
091                        callback.onException(e);
092                        return;
093                    }
094                    callback.onSessionInitiated(session);
095                }
096            }
097        });
098    }
099
100    @Override
101    public String getNamespace() {
102        return transportManager.getNamespace();
103    }
104
105    @Override
106    public IQ handleTransportInfo(Jingle transportInfo) {
107        return IQ.createResultIQ(transportInfo);
108        // TODO
109    }
110
111    @Override
112    public JingleTransportManager<JingleIBBTransport> transportManager() {
113        return JingleIBBTransportManager.getInstanceFor(jingleSession.getConnection());
114    }
115}