/*
* TurnServer, the OpenSource Java Solution for TURN protocol. Maintained by the
* Jitsi community (http://jitsi.org).
*
* Copyright @ 2015 Atlassian Pty Ltd
*
* 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.jitsi.turnserver.listeners;
import java.io.*;
import java.net.*;
import java.util.logging.*;
import org.ice4j.*;
import org.ice4j.attribute.*;
import org.ice4j.message.*;
import org.ice4j.socket.*;
import org.ice4j.stack.*;
import org.ice4j.stunclient.*;
import org.jitsi.turnserver.*;
import org.jitsi.turnserver.stack.*;
/**
* Class to handle events when a Connection Attempt Indication is received on
* CLient Side.
*
* @author Aakash Garg
*
*/
public class ConnectionAttemptIndicationListener
extends IndicationListener
{
/**
* The <tt>Logger</tt> used by the <tt>DataIndicationListener</tt> class and
* its instances for logging output.
*/
private static final Logger logger = Logger
.getLogger(ConnectionAttemptIndicationListener.class.getName());
/**
* The request sender to use to send request to Turn server.
*/
private BlockingRequestSender requestSender;
/**
* Constructor to create a ConnectionAttemptIndicationListener with
* specified turnStack to use the requestSender will be null and a new
* {@link BlockingRequestSender} will be created with new TCP socket to send
* request to server.
*
* @param turnStack the turnStack to use for processing.
*/
public ConnectionAttemptIndicationListener(TurnStack turnStack)
{
super(turnStack);
}
/**
* Constructor to create a ConnectionAttemptIndicationListener with
* specified turnStack to use.
*
* @param turnStack the turnStack to use for processing.
* @param requestSender the requestSender to use to send request to server.
*/
public ConnectionAttemptIndicationListener(TurnStack turnStack,
BlockingRequestSender requestSender)
{
super(turnStack);
this.requestSender = requestSender;
}
/**
* The method to handle the incoming ConnectionAttempt Indications from Turn
* Server.
*/
@Override
public void handleIndication(Indication ind, Allocation alloc)
{
if (ind.getMessageType() == Message.CONNECTION_ATTEMPT_INDICATION)
{
logger.finest("Received a connection attempt indication.");
byte[] tranId = ind.getTransactionID();
ConnectionIdAttribute connectionId =
(ConnectionIdAttribute) ind
.getAttribute(Attribute.CONNECTION_ID);
XorPeerAddressAttribute peerAddress =
(XorPeerAddressAttribute) ind
.getAttribute(Attribute.XOR_PEER_ADDRESS);
peerAddress.setAddress(
peerAddress.getAddress(), tranId);
logger
.finest("Received a Connection Attempt Indication with connectionId-"
+ connectionId.getConnectionIdValue()
+ ", for peerAddress-" + peerAddress.getAddress());
Socket socket;
try
{
socket =
new Socket(InetAddress.getLocalHost().getHostAddress(),
3478);
IceTcpSocketWrapper sockWrapper =
new IceTcpSocketWrapper(socket);
this.getTurnStack().addSocket(
sockWrapper);
TransportAddress localAddr =
new TransportAddress(sockWrapper.getLocalAddress(),
sockWrapper.getLocalPort(), Transport.TCP);
logger.finest("New Local TCP socket chosen - " + localAddr);
TransportAddress serverAddress =
new TransportAddress(InetAddress.getLocalHost(), 3478,
Transport.TCP);
StunMessageEvent evt = null;
try
{
Request connectionBindRequest =
MessageFactory.createConnectionBindRequest(connectionId
.getConnectionIdValue());
TransactionID tranID =
TransactionID.createNewTransactionID();
connectionBindRequest.setTransactionID(tranID.getBytes());
if (this.requestSender == null)
{
logger.finest("Setting RequestSender");
this.requestSender =
new BlockingRequestSender(this.getTurnStack(),
localAddr);
}
logger.finest("Sending ConnectionBind Request to "
+ serverAddress);
evt = requestSender.sendRequestAndWaitForResponse(
connectionBindRequest, serverAddress);
if (evt != null)
{
Message msg = evt.getMessage();
if (msg.getMessageType() == Message.CONNECTION_BIND_SUCCESS_RESPONSE)
{
logger
.finest("Received a ConnectionBind Sucess Response.");
String myMessage = "Aakash Garg";
RawMessage rawMessage =
RawMessage.build(myMessage.getBytes(),
myMessage.length(), serverAddress,
localAddr);
try
{
logger
.finest("--------------- Thread will now sleep for 20 sec.");
Thread.sleep(20 * 1000);
}
catch (InterruptedException e)
{
System.err.println("Unable to stop thread");
}
logger
.finest(">>>>>>>>>>>> Sending a Test message : ");
byte[] data = myMessage.getBytes();
for (int i = 0; i < data.length; i++)
{
System.out.print(String.format(
"%02X, ", data[i]));
}
this.getTurnStack().sendUdpMessage(
rawMessage, serverAddress,
requestSender.getLocalAddress());
}
else
{
logger
.finest("Received a ConnectionBind error Response - "
+ msg.getAttribute(Attribute.ERROR_CODE));
}
}
else
{
System.err
.println("No response received to ConnectionBind request");
}
}
catch (StunException e)
{
logger.finest("Unable to send ConnectionBind request");
}
}
catch (UnknownHostException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
}