Search in sources :

Example 1 with JingleContent

use of org.jivesoftware.smackx.jingleold.packet.JingleContent in project Smack by igniterealtime.

the class TransportNegotiator method delayedCheckBestCandidate.

/**
     * Launch a thread that checks, after some time, if any of the candidates
     * offered by the other endpoint is usable. The thread does not check the
     * candidates: it just checks if we have got a valid one and sends an Accept
     * in that case.
     */
private void delayedCheckBestCandidate(final JingleSession js, final Jingle jin) {
    //
    if (resultThread == null && !getRemoteCandidates().isEmpty()) {
        resultThread = new Thread(new Runnable() {

            @Override
            public void run() {
                // Sleep for some time, waiting for the candidates checks
                int totalTime = (CANDIDATES_ACCEPT_PERIOD + TransportResolver.CHECK_TIMEOUT);
                int tries = (int) Math.ceil(totalTime / 1000);
                for (int i = 0; i < tries - 1; i++) {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        LOGGER.log(Level.WARNING, "exception", e);
                    }
                    // Once we are in pending state, look for any valid remote
                    // candidate, and send an "accept" if we have one...
                    TransportCandidate bestRemote = getBestRemoteCandidate();
                    if ((bestRemote != null) && ((getNegotiatorState() == JingleNegotiatorState.PENDING))) {
                        // Accepting the remote candidate
                        if (!acceptedRemoteCandidates.contains(bestRemote)) {
                            Jingle jout = new Jingle(JingleActionEnum.CONTENT_ACCEPT);
                            JingleContent content = parentNegotiator.getJingleContent();
                            content.addJingleTransport(getJingleTransport(bestRemote));
                            jout.addContent(content);
                            // Send the packet
                            try {
                                js.sendFormattedJingle(jin, jout);
                            } catch (InterruptedException | NotConnectedException e) {
                                throw new IllegalStateException(e);
                            }
                            acceptedRemoteCandidates.add(bestRemote);
                        }
                        if ((isEstablished()) && (getNegotiatorState() == JingleNegotiatorState.PENDING)) {
                            setNegotiatorState(JingleNegotiatorState.SUCCEEDED);
                            try {
                                triggerTransportEstablished(getAcceptedLocalCandidate(), bestRemote);
                            } catch (InterruptedException | NotConnectedException e) {
                                throw new IllegalStateException(e);
                            }
                            break;
                        }
                    }
                }
                // Once we are in pending state, look for any valid remote
                // candidate, and send an "accept" if we have one...
                TransportCandidate bestRemote = getBestRemoteCandidate();
                if (bestRemote == null) {
                    boolean foundRemoteRelay = false;
                    for (TransportCandidate candidate : remoteCandidates) {
                        if (candidate instanceof ICECandidate) {
                            ICECandidate iceCandidate = (ICECandidate) candidate;
                            if (iceCandidate.getType().equals(Type.relay)) {
                                //TODO Check if the relay is reacheable
                                addValidRemoteCandidate(iceCandidate);
                                foundRemoteRelay = true;
                            }
                        }
                    }
                    // We should accept the Public One if we received it, otherwise, accepts any.
                    if (!foundRemoteRelay) {
                        boolean foundLocalRelay = false;
                        for (TransportCandidate candidate : offeredCandidates) {
                            if (candidate instanceof ICECandidate) {
                                ICECandidate iceCandidate = (ICECandidate) candidate;
                                if (iceCandidate.getType().equals(Type.relay)) {
                                    foundLocalRelay = true;
                                }
                            }
                        }
                        if (foundLocalRelay) {
                            boolean foundRemotePublic = false;
                            for (TransportCandidate candidate : remoteCandidates) {
                                if (candidate instanceof ICECandidate) {
                                    ICECandidate iceCandidate = (ICECandidate) candidate;
                                    if (iceCandidate.getType().equals(ICECandidate.Type.srflx)) {
                                        addValidRemoteCandidate(iceCandidate);
                                        foundRemotePublic = true;
                                    }
                                }
                            }
                            if (!foundRemotePublic) {
                                for (TransportCandidate candidate : remoteCandidates) {
                                    if (candidate instanceof ICECandidate) {
                                        ICECandidate iceCandidate = (ICECandidate) candidate;
                                        addValidRemoteCandidate(iceCandidate);
                                    }
                                }
                            }
                        }
                    }
                }
                for (int i = 0; i < 6; i++) {
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        LOGGER.log(Level.WARNING, "exception", e);
                    }
                    bestRemote = getBestRemoteCandidate();
                    //State state = getState();
                    if ((bestRemote != null) && ((getNegotiatorState() == JingleNegotiatorState.PENDING))) {
                        if (!acceptedRemoteCandidates.contains(bestRemote)) {
                            Jingle jout = new Jingle(JingleActionEnum.CONTENT_ACCEPT);
                            JingleContent content = parentNegotiator.getJingleContent();
                            content.addJingleTransport(getJingleTransport(bestRemote));
                            jout.addContent(content);
                            // Send the packet
                            try {
                                js.sendFormattedJingle(jin, jout);
                            } catch (InterruptedException | NotConnectedException e) {
                                throw new IllegalStateException(e);
                            }
                            acceptedRemoteCandidates.add(bestRemote);
                        }
                        if (isEstablished()) {
                            setNegotiatorState(JingleNegotiatorState.SUCCEEDED);
                            break;
                        }
                    }
                }
                if (getNegotiatorState() != JingleNegotiatorState.SUCCEEDED) {
                    try {
                        session.terminate("Unable to negotiate session. This may be caused by firewall configuration problems.");
                    } catch (Exception e) {
                        LOGGER.log(Level.WARNING, "exception", e);
                    }
                }
            }
        }, "Waiting for all the transport candidates checks...");
        resultThread.setName("Transport Resolver Result");
        resultThread.start();
    }
}
Also used : NotConnectedException(org.jivesoftware.smack.SmackException.NotConnectedException) SmackException(org.jivesoftware.smack.SmackException) NotConnectedException(org.jivesoftware.smack.SmackException.NotConnectedException) JingleException(org.jivesoftware.smackx.jingleold.JingleException) XMPPException(org.jivesoftware.smack.XMPPException) Jingle(org.jivesoftware.smackx.jingleold.packet.Jingle) JingleTransportCandidate(org.jivesoftware.smackx.jingleold.packet.JingleTransport.JingleTransportCandidate) JingleContent(org.jivesoftware.smackx.jingleold.packet.JingleContent)

Example 2 with JingleContent

use of org.jivesoftware.smackx.jingleold.packet.JingleContent in project Smack by igniterealtime.

the class JingleSessionStateUnknown method receiveSessionInitiateAction.

/**
     * In the UNKNOWN state we received a <session-initiate> action.
     * This method processes that action.
     * @throws SmackException 
     * @throws InterruptedException 
     */
private IQ receiveSessionInitiateAction(JingleSession session, Jingle inJingle) throws SmackException, InterruptedException {
    IQ response = null;
    boolean shouldAck = true;
    if (!shouldAck) {
        response = session.createJingleError(inJingle, JingleError.NEGOTIATION_ERROR);
    } else {
        // Create the Ack
        response = session.createAck(inJingle);
        session.setSessionState(JingleSessionStatePending.getInstance());
        // Now set up all of the initial content negotiators for the session.
        for (JingleContent jingleContent : inJingle.getContentsList()) {
            // First create the content negotiator for this <content> section.
            ContentNegotiator contentNeg = new ContentNegotiator(session, jingleContent.getCreator(), jingleContent.getName());
            // Get the media negotiator that goes with the <description> of this content.
            JingleDescription jingleDescription = jingleContent.getDescription();
            // Loop through each media manager looking for the ones that matches the incoming 
            // session-initiate <content> choices.
            // (Set the first media manager as the default, so that in case things don't match we can still negotiate.)
            JingleMediaManager chosenMediaManager = session.getMediaManagers().get(0);
            for (JingleMediaManager mediaManager : session.getMediaManagers()) {
                boolean matches = true;
                for (PayloadType mediaPayloadType : mediaManager.getPayloads()) {
                    for (PayloadType descPayloadType2 : jingleDescription.getPayloadTypesList()) {
                        if (mediaPayloadType.getId() != descPayloadType2.getId()) {
                            matches = false;
                        }
                    }
                    if (matches) {
                        chosenMediaManager = mediaManager;
                    }
                }
            }
            // Create the media negotiator for this content description.
            contentNeg.setMediaNegotiator(new MediaNegotiator(session, chosenMediaManager, jingleDescription.getPayloadTypesList(), contentNeg));
            // Then create a transport negotiator for that transport.
            for (JingleTransport jingleTransport : jingleContent.getJingleTransportsList()) {
                for (JingleMediaManager mediaManager : session.getMediaManagers()) {
                    JingleTransportManager transportManager = mediaManager.getTransportManager();
                    TransportResolver resolver = null;
                    try {
                        resolver = transportManager.getResolver(session);
                    } catch (XMPPException e) {
                        LOGGER.log(Level.WARNING, "exception", e);
                    }
                    if (resolver.getType().equals(TransportResolver.Type.rawupd)) {
                        contentNeg.setTransportNegotiator(new TransportNegotiator.RawUdp(session, resolver, contentNeg));
                    }
                    if (resolver.getType().equals(TransportResolver.Type.ice)) {
                        contentNeg.setTransportNegotiator(new TransportNegotiator.Ice(session, resolver, contentNeg));
                    }
                }
            }
            // Add the content negotiator to the session.
            session.addContentNegotiator(contentNeg);
        }
        // Now setup to track the media negotiators, so that we know when (if) to send a session-accept.
        session.setupListeners();
    }
    return response;
}
Also used : JingleDescription(org.jivesoftware.smackx.jingleold.packet.JingleDescription) IQ(org.jivesoftware.smack.packet.IQ) MediaNegotiator(org.jivesoftware.smackx.jingleold.media.MediaNegotiator) JingleTransport(org.jivesoftware.smackx.jingleold.packet.JingleTransport) PayloadType(org.jivesoftware.smackx.jingleold.media.PayloadType) TransportNegotiator(org.jivesoftware.smackx.jingleold.nat.TransportNegotiator) JingleMediaManager(org.jivesoftware.smackx.jingleold.media.JingleMediaManager) TransportResolver(org.jivesoftware.smackx.jingleold.nat.TransportResolver) JingleContent(org.jivesoftware.smackx.jingleold.packet.JingleContent) XMPPException(org.jivesoftware.smack.XMPPException) JingleTransportManager(org.jivesoftware.smackx.jingleold.nat.JingleTransportManager)

Example 3 with JingleContent

use of org.jivesoftware.smackx.jingleold.packet.JingleContent in project Smack by igniterealtime.

the class JingleProvider method parse.

/**
     * Parse a iq/jingle element.
     * @throws Exception 
     */
@Override
public Jingle parse(XmlPullParser parser, int intialDepth) throws Exception {
    Jingle jingle = new Jingle();
    String sid = "";
    JingleActionEnum action;
    Jid initiator = null;
    Jid responder = null;
    boolean done = false;
    JingleContent currentContent = null;
    // Sub-elements providers
    JingleContentProvider jcp = new JingleContentProvider();
    JingleDescriptionProvider jdpAudio = new JingleDescriptionProvider.Audio();
    JingleTransportProvider jtpRawUdp = new JingleTransportProvider.RawUdp();
    JingleTransportProvider jtpIce = new JingleTransportProvider.Ice();
    ExtensionElementProvider<?> jmipAudio = new JingleContentInfoProvider.Audio();
    int eventType;
    String elementName;
    String namespace;
    // Get some attributes for the <jingle> element
    sid = parser.getAttributeValue("", "sid");
    action = JingleActionEnum.getAction(parser.getAttributeValue("", "action"));
    initiator = ParserUtils.getJidAttribute(parser, "initiator");
    responder = ParserUtils.getJidAttribute(parser, "responder");
    jingle.setSid(sid);
    jingle.setAction(action);
    jingle.setInitiator(initiator);
    jingle.setResponder(responder);
    // Start processing sub-elements
    while (!done) {
        eventType = parser.next();
        elementName = parser.getName();
        namespace = parser.getNamespace();
        if (eventType == XmlPullParser.START_TAG) {
            if (elementName.equals(JingleContent.NODENAME)) {
                // Add a new <content> element to the jingle
                currentContent = jcp.parse(parser);
                jingle.addContent(currentContent);
            } else if (elementName.equals(JingleDescription.NODENAME) && namespace.equals(JingleDescription.Audio.NAMESPACE)) {
                // Set the <description> element of the <content>
                currentContent.setDescription(jdpAudio.parse(parser));
            } else if (elementName.equals(JingleTransport.NODENAME)) {
                // Parse the possible transport namespaces
                if (namespace.equals(JingleTransport.RawUdp.NAMESPACE)) {
                    currentContent.addJingleTransport(jtpRawUdp.parse(parser));
                } else if (namespace.equals(JingleTransport.Ice.NAMESPACE)) {
                    currentContent.addJingleTransport(jtpIce.parse(parser));
                } else {
                    throw new SmackException("Unknown transport namespace \"" + namespace + "\" in Jingle packet.");
                }
            } else if (namespace.equals(JingleContentInfo.Audio.NAMESPACE)) {
                jingle.setContentInfo((JingleContentInfo) jmipAudio.parse(parser));
            } else {
                throw new SmackException("Unknown combination of namespace \"" + namespace + "\" and element name \"" + elementName + "\" in Jingle packet.");
            }
        } else if (eventType == XmlPullParser.END_TAG) {
            if (parser.getName().equals(Jingle.getElementName())) {
                done = true;
            }
        }
    }
    return jingle;
}
Also used : Jid(org.jxmpp.jid.Jid) SmackException(org.jivesoftware.smack.SmackException) JingleActionEnum(org.jivesoftware.smackx.jingleold.JingleActionEnum) Jingle(org.jivesoftware.smackx.jingleold.packet.Jingle) JingleContentInfo(org.jivesoftware.smackx.jingleold.packet.JingleContentInfo) JingleContent(org.jivesoftware.smackx.jingleold.packet.JingleContent)

Example 4 with JingleContent

use of org.jivesoftware.smackx.jingleold.packet.JingleContent in project Smack by igniterealtime.

the class TransportNegotiator method obtainCandidatesList.

/**
     * Parse the list of transport candidates from a Jingle packet.
     *
     * @param jin The input jingle packet
     */
private List<TransportCandidate> obtainCandidatesList(Jingle jingle) {
    List<TransportCandidate> result = new ArrayList<TransportCandidate>();
    if (jingle != null) {
        // Get the list of candidates from the packet
        for (JingleContent jingleContent : jingle.getContentsList()) {
            if (jingleContent.getName().equals(parentNegotiator.getName())) {
                for (JingleTransport jingleTransport : jingleContent.getJingleTransportsList()) {
                    for (JingleTransportCandidate jingleTransportCandidate : jingleTransport.getCandidatesList()) {
                        TransportCandidate transCand = jingleTransportCandidate.getMediaTransport();
                        result.add(transCand);
                    }
                }
            }
        }
    }
    return result;
}
Also used : JingleTransportCandidate(org.jivesoftware.smackx.jingleold.packet.JingleTransport.JingleTransportCandidate) JingleTransportCandidate(org.jivesoftware.smackx.jingleold.packet.JingleTransport.JingleTransportCandidate) ArrayList(java.util.ArrayList) JingleContent(org.jivesoftware.smackx.jingleold.packet.JingleContent) JingleTransport(org.jivesoftware.smackx.jingleold.packet.JingleTransport)

Example 5 with JingleContent

use of org.jivesoftware.smackx.jingleold.packet.JingleContent in project Smack by igniterealtime.

the class TransportNegotiator method sendTransportCandidateOffer.

/**
     * Send an offer for a transport candidate
     *
     * @param cand
     * @throws NotConnectedException 
     * @throws InterruptedException 
     */
private synchronized void sendTransportCandidateOffer(TransportCandidate cand) throws NotConnectedException, InterruptedException {
    if (!cand.isNull()) {
        // Offer our new candidate...
        addOfferedCandidate(cand);
        JingleContent content = parentNegotiator.getJingleContent();
        content.addJingleTransport(getJingleTransport(cand));
        Jingle jingle = new Jingle(JingleActionEnum.TRANSPORT_INFO);
        jingle.addContent(content);
        // We SHOULD NOT be sending packets directly.
        // This circumvents the state machinery.
        // TODO - work this into the state machinery.
        session.sendFormattedJingle(jingle);
    }
}
Also used : Jingle(org.jivesoftware.smackx.jingleold.packet.Jingle) JingleContent(org.jivesoftware.smackx.jingleold.packet.JingleContent)

Aggregations

JingleContent (org.jivesoftware.smackx.jingleold.packet.JingleContent)6 Jingle (org.jivesoftware.smackx.jingleold.packet.Jingle)4 ArrayList (java.util.ArrayList)2 SmackException (org.jivesoftware.smack.SmackException)2 XMPPException (org.jivesoftware.smack.XMPPException)2 IQ (org.jivesoftware.smack.packet.IQ)2 JingleActionEnum (org.jivesoftware.smackx.jingleold.JingleActionEnum)2 JingleException (org.jivesoftware.smackx.jingleold.JingleException)2 JingleDescription (org.jivesoftware.smackx.jingleold.packet.JingleDescription)2 JingleTransport (org.jivesoftware.smackx.jingleold.packet.JingleTransport)2 JingleTransportCandidate (org.jivesoftware.smackx.jingleold.packet.JingleTransport.JingleTransportCandidate)2 NotConnectedException (org.jivesoftware.smack.SmackException.NotConnectedException)1 JingleMediaManager (org.jivesoftware.smackx.jingleold.media.JingleMediaManager)1 MediaNegotiator (org.jivesoftware.smackx.jingleold.media.MediaNegotiator)1 PayloadType (org.jivesoftware.smackx.jingleold.media.PayloadType)1 JingleTransportManager (org.jivesoftware.smackx.jingleold.nat.JingleTransportManager)1 TransportNegotiator (org.jivesoftware.smackx.jingleold.nat.TransportNegotiator)1 TransportResolver (org.jivesoftware.smackx.jingleold.nat.TransportResolver)1 JingleContentInfo (org.jivesoftware.smackx.jingleold.packet.JingleContentInfo)1 Jid (org.jxmpp.jid.Jid)1