All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.restcomm.media.ice.IceComponent Maven / Gradle / Ivy

/*
 * TeleStax, Open Source Cloud Communications
 * Copyright 2011-2014, Telestax Inc and individual contributors
 * by the @authors tag.
 *
 * This program is free software: you can redistribute it and/or modify
 * under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation; either version 3 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see 
 *
 */

package org.restcomm.media.ice;

import java.nio.channels.DatagramChannel;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * 
 * @author Henrique Rosa
 * 
 */
public class IceComponent {

	public static final short RTP_ID = 1;
	public static final short RTCP_ID = 2;

	private short componentId;

	private final List localCandidates;
	private LocalCandidateWrapper defaultLocalCandidate;
//	private final List remoteCandidates;
//	private IceCandidate defaultRemoteCandidate;

	private CandidatePair candidatePair;

	public IceComponent(short componentId) {
		setComponentId(componentId);
		this.localCandidates = new ArrayList(5);
//		this.remoteCandidates = new ArrayList(5);
	}

	/**
	 * Validates whether a value can be used as an ICE Component ID.
	 * 

* For RTP components, the ID must be 1.
* For RTCP components, the ID must be 2. *

* * @param componentId * The value to be evaluated. * @return true if its a valid Component ID. Returns * false otherwise. */ private boolean isValidComponentId(int componentId) { if (componentId != RTP_ID && componentId != RTCP_ID) { return false; } return true; } public short getComponentId() { return componentId; } public void setComponentId(short componentId) { if (!isValidComponentId(componentId)) { throw new IllegalArgumentException("Invalid Component ID: " + componentId); } this.componentId = componentId; } /** * Registers a collection of local candidates to the component. * * @param candidatesWrapper * The list of local candidates * * @see IceComponent#addLocalCandidate(LocalCandidateWrapper) */ public void addLocalCandidates(List candidatesWrapper) { for (LocalCandidateWrapper candidateWrapper : candidatesWrapper) { addLocalCandidate(candidateWrapper, false); } sortCandidates(); } /** * Attempts to registers a local candidate. * * @param candidateWrapper * The wrapper that contains the local ICE candidate */ public void addLocalCandidate(LocalCandidateWrapper candidateWrapper) { this.addLocalCandidate(candidateWrapper, true); } /** * Attempts to registers a local candidate. * * @param candidateWrapper * The wrapper that contains the local ICE candidate * @param sort * Decides whether the candidates list should be ordered after * insert */ private void addLocalCandidate(LocalCandidateWrapper candidateWrapper, boolean sort) { IceCandidate candidate = candidateWrapper.getCandidate(); // Configure the candidate before registration candidate.setPriority(calculatePriority(candidate)); synchronized (this.localCandidates) { if (!this.localCandidates.contains(candidateWrapper)) { this.localCandidates.add(candidateWrapper); sortCandidates(); } } } private void sortCandidates() { synchronized (localCandidates) { Collections.sort(this.localCandidates); } } /** * Calculates the priority of a candidate, using the following formula: *

* * p=(2^24 * candidate type preference) + (2^8 * IP precedence) + (2^0 * (256 - * component ID)) * *

*/ private long calculatePriority(IceCandidate candidate) { return (long) (candidate.getType().getPreference() << 24) + (long) (candidate.getAddressPrecedence() << 8) + (long) (256 - this.getComponentId()); } public LocalCandidateWrapper selectDefaultLocalCandidate() { // Choose the candidate with greatest priority // This is fine because this implementation only supports IPv4 addresses // That being said, it should only be one address. If there are more, // let priority decide. this.defaultLocalCandidate = this.localCandidates.get(0); return this.defaultLocalCandidate; } public List getLocalCandidates() { List copy; synchronized (this.localCandidates) { copy = new ArrayList(this.localCandidates); } return copy; } public LocalCandidateWrapper getDefaultLocalCandidate() { return defaultLocalCandidate; } public boolean isDefaultLocalCandidateSelected() { return this.defaultLocalCandidate != null; } public CandidatePair getSelectedCandidates() { return candidatePair; } public CandidatePair setCandidatePair(DatagramChannel channel) { for (LocalCandidateWrapper localCandidate : getLocalCandidates()) { if (channel.equals(localCandidate.getChannel())) { this.candidatePair = new CandidatePair(componentId, channel); return this.candidatePair; } } return null; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy