org.jivesoftware.openfire.mediaproxy.Channel Maven / Gradle / Ivy
The newest version!
/*
* Copyright (C) 2005-2008 Jive Software. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jivesoftware.openfire.mediaproxy;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Listen packets from defined dataSocket and send packets to the defined host.
*
* @author Thiago Camargo
*/
abstract class Channel implements Runnable {
private static final Logger Log = LoggerFactory.getLogger(Channel.class);
protected byte[] buf = new byte[5000];
protected DatagramSocket dataSocket;
protected DatagramPacket packet;
protected boolean enabled = true;
List listeners = new ArrayList<>();
protected InetAddress host;
protected int port;
/**
* Creates a Channel according to the parameters.
*
* @param dataSocket
* @param host
* @param port
*/
public Channel(DatagramSocket dataSocket, InetAddress host, int port) {
this.dataSocket = dataSocket;
this.host = host;
this.port = port;
}
/**
* Get the host that the packet will be sent to.
*
* @return remote host address
*/
public InetAddress getHost() {
return host;
}
/**
* Set the host that the packet will be sent to.
*/
protected void setHost(InetAddress host) {
this.host = host;
}
/**
* Get the port that the packet will be sent to.
*
* @return The remote port number
*/
public int getPort() {
return port;
}
/**
* Set the port that the packet will be sent to.
*
* @param port
*/
protected void setPort(int port) {
this.port = port;
}
/**
* Adds a DatagramListener to the Channel
*
* @param datagramListener
*/
public void addListener(DatagramListener datagramListener) {
listeners.add(datagramListener);
}
/**
* Remove a DatagramListener from the Channel
*
* @param datagramListener
*/
public void removeListener(DatagramListener datagramListener) {
listeners.remove(datagramListener);
}
/**
* Remove every Listeners
*/
public void removeListeners() {
listeners.removeAll(listeners);
}
public void cancel() {
this.enabled = false;
if (dataSocket != null){
dataSocket.close();
}
}
/**
* Thread override method
*/
@Override
public void run() {
try {
while (enabled) {
// Block until a datagram appears:
packet = new DatagramPacket(buf, buf.length);
dataSocket.receive(packet);
if (handle(packet)) {
boolean resend = true;
for (DatagramListener dl : listeners) {
boolean send = dl.datagramReceived(packet);
if (resend && !send) {
resend = false;
}
}
if (resend) {
relayPacket(packet);
}
}
}
}
catch (UnknownHostException uhe) {
if (enabled) {
Log.error("Unknown Host", uhe);
}
}
catch (SocketException se) {
if (enabled) {
Log.error("Socket closed", se);
}
}
catch (IOException ioe) {
if (enabled) {
Log.error("Communication error", ioe);
}
}
}
public void relayPacket(DatagramPacket packet) {
try {
DatagramPacket echo = new DatagramPacket(packet.getData(), packet.getLength(), host, port);
dataSocket.send(echo);
}
catch (IOException e) {
Log.error(e.getMessage(), e);
}
}
/**
* Handles received packet and returns true if the packet should be processed by the channel.
*
* @param packet received datagram packet
* @return true if listeners will be alerted that a new packet was received.
*/
abstract boolean handle(DatagramPacket packet);
}