src/net/java/sip/communicator/impl/protocol/jabber/JingleNodesHarvester.java
/**
     * Gathers Jingle Nodes candidates for all host <tt>Candidate</tt>s that are
     * already present in the specified <tt>component</tt>. This method relies
     * on the specified <tt>component</tt> to already contain all its host
     * candidates so that it would resolve them.
     *
     * @param component the {@link Component} that we'd like to gather candidate
     * Jingle Nodes <tt>Candidate</tt>s for
     * @return  the <tt>LocalCandidate</tt>s gathered by this
     * <tt>CandidateHarvester</tt>
     */
Gathers Jingle Nodes candidates for all host Candidates that are
already present in the specified component. This method relies
on the specified component to already contain all its host
candidates so that it would resolve them.

@param component the  Component that we'd like to gather candidate
Jingle Nodes Candidates for
@return  the LocalCandidates gathered by this
CandidateHarvester
Gathers Jingle Nodes candidates for all host Candidates that are already present in the specified component . This method relies on the specified component to already contain all its host candidates so that it would resolve them . @param component the Component that we ' d like to gather candidate Jingle Nodes Candidates for @return the LocalCandidates gathered by this CandidateHarvester
@Override
    public synchronized Collection<LocalCandidate> harvest(Component component)
    {
        logger.info("harvest Jingle Nodes");
        Collection<LocalCandidate> candidates = new HashSet<LocalCandidate>();
        String ip = null;
        int port = -1;
        /* if we have already a candidate (RTCP) allocated, get it */
        if(localAddressSecond != null && relayedAddressSecond != null)
        {
            LocalCandidate candidate = createJingleNodesCandidate(
                    relayedAddressSecond, component, localAddressSecond);
            if( component.addLocalCandidate(candidate))
            {
                candidates.add(candidate);
            }
            localAddressSecond = null;
            relayedAddressSecond = null;
            return candidates;
        }
        XMPPConnection conn = serviceNode.getConnection();
        JingleChannelIQ ciq = null;
        if (serviceNode != null)
        {
            final TrackerEntry preferred = serviceNode.getPreferedRelay();
            if (preferred != null)
            {
                try
                {
                    ciq = SmackServiceNode.getChannel(conn, preferred.getJid());
                }
                catch (NotConnectedException | InterruptedException e)
                {
                    logger.error("Could not get JingleNodes channel", e);
                }
            }
        }
        if (ciq != null)
        {
            ip = ciq.getHost();
            port = ciq.getRemoteport();
            if(logger.isInfoEnabled())
            {
                logger.info("JN relay: " + ip + " remote port:" + port +
                        " local port: " + ciq.getLocalport());
            }
            if (ip == null || ciq.getRemoteport() == 0)
            {
                logger.warn("JN relay ignored because ip was null or port 0");
                return candidates;
            }
            int scopeIndex = ip.indexOf('%');
            if (scopeIndex > 0)
            {
                logger.warn("Dropping scope from assumed IPv6 address " + ip);
                ip = ip.substring(0, scopeIndex);
            }
            /* RTP */
            TransportAddress relayedAddress = new TransportAddress(ip, port,
                    Transport.UDP);
            TransportAddress localAddress = new TransportAddress(ip,
                    ciq.getLocalport(), Transport.UDP);
            LocalCandidate local = createJingleNodesCandidate(
                    relayedAddress, component, localAddress);
            /* RTCP */
            relayedAddressSecond
                = new TransportAddress(ip, port + 1,Transport.UDP);
            localAddressSecond
                = new TransportAddress(ip, ciq.getLocalport() + 1,
                        Transport.UDP);
            if( component.addLocalCandidate(local))
            {
                candidates.add(local);
            }
        }
        return candidates;
    }
@ Override public synchronized Collection < LocalCandidate > harvest ( Component component ) { logger . info ( "harvest Jingle Nodes" ) ; Collection < LocalCandidate > candidates = new HashSet < LocalCandidate > ( ) ; String ip = null ; int port = - 1 ; /* if we have already a candidate (RTCP) allocated, get it */ if ( localAddressSecond != null && relayedAddressSecond != null ) { LocalCandidate candidate = createJingleNodesCandidate ( relayedAddressSecond , component , localAddressSecond ) ; if ( component . addLocalCandidate ( candidate ) ) { candidates . add ( candidate ) ; } localAddressSecond = null ; relayedAddressSecond = null ; return candidates ; } XMPPConnection conn = serviceNode . getConnection ( ) ; JingleChannelIQ ciq = null ; if ( serviceNode != null ) { final TrackerEntry preferred = serviceNode . getPreferedRelay ( ) ; if ( preferred != null ) { try { ciq = SmackServiceNode . getChannel ( conn , preferred . getJid ( ) ) ; } catch ( NotConnectedException | InterruptedException e ) { logger . error ( "Could not get JingleNodes channel" , e ) ; } } } if ( ciq != null ) { ip = ciq . getHost ( ) ; port = ciq . getRemoteport ( ) ; if ( logger . isInfoEnabled ( ) ) { logger . info ( "JN relay: " + ip + " remote port:" + port + " local port: " + ciq . getLocalport ( ) ) ; } if ( ip == null || ciq . getRemoteport ( ) == 0 ) { logger . warn ( "JN relay ignored because ip was null or port 0" ) ; return candidates ; } int scopeIndex = ip . indexOf ( '%' ) ; if ( scopeIndex > 0 ) { logger . warn ( "Dropping scope from assumed IPv6 address " + ip ) ; ip = ip . substring ( 0 , scopeIndex ) ; } /* RTP */ TransportAddress relayedAddress = new TransportAddress ( ip , port , Transport . UDP ) ; TransportAddress localAddress = new TransportAddress ( ip , ciq . getLocalport ( ) , Transport . UDP ) ; LocalCandidate local = createJingleNodesCandidate ( relayedAddress , component , localAddress ) ; /* RTCP */ relayedAddressSecond = new TransportAddress ( ip , port + 1 , Transport . UDP ) ; localAddressSecond = new TransportAddress ( ip , ciq . getLocalport ( ) + 1 , Transport . UDP ) ; if ( component . addLocalCandidate ( local ) ) { candidates . add ( local ) ; } } return candidates ; }
Gathers Jingle Nodes candidates for all host <tt>Candidate</tt>s that are
 already present in the specified <tt>component</tt>.
Gathers Jingle Nodes candidates for all host <tt > Candidate< / tt > s that are already present in the specified <tt > component< / tt > .
//try to add the candidate to the component and then only add it to //the harvest not redundant (not sure how it could be red. but ...) // Drop the scope or interface name if the relay sends it // along in its IPv6 address. The scope/ifname is only valid on the // host that owns the IP and we don't need it here. //try to add the candidate to the component and then only add it to //the harvest not redundant (not sure how it could be red. but ...)