package net.java.sip.communicator.impl.netaddr;
import net.java.stun4j.*;
import net.java.stun4j.message.*;
import net.java.stun4j.stack.*;
import java.io.*;
/**
* A utility used to flatten the multithreaded architecture of the Stack
* and execute the discovery process in a synchronized manner. Roughly what
* happens here is:
*
* ApplicationThread:
* sendMessage()
* wait();
*
* StackThread:
* processMessage/Timeout()
* {
* saveMessage();
* notify();
* }
*
*
* <p>Organisation: <p> Louis Pasteur University, Strasbourg, France</p>
* <p>Network Research Team (http://www-r2.u-strasbg.fr)</p></p>
* @author Emil Ivov
* @version 0.1
*/
class BlockingRequestSender
implements ResponseCollector
{
private StunProvider stunProvider = null;
private NetAccessPointDescriptor apDescriptor = null;
StunMessageEvent responseEvent = null;
BlockingRequestSender(StunProvider stunProvider,
NetAccessPointDescriptor apDescriptor)
{
this.stunProvider = stunProvider;
this.apDescriptor = apDescriptor;
}
/**
* Saves the message event and notifies the discoverer thread so that
* it may resume.
* @param evt the newly arrived message event.
*/
public synchronized void processResponse(StunMessageEvent evt)
{
this.responseEvent = evt;
notifyAll();
}
/**
* Notifies the discoverer thread when a message has timeouted so that
* it may resume and consider it as unanswered.
*/
public synchronized void processTimeout()
{
notifyAll();
}
/**
* Sends the specified request and blocks until a response has been
* received or the request transaction has timed out.
* @param request the reuqest to send
* @param serverAddress the request destination address
* @return the event encapsulating the response or null if no response
* has been received.
* @throws StunException NETWORK_ERROR or other if we fail to send
* the message
*/
public synchronized StunMessageEvent sendRequestAndWaitForResponse(
Request request,
StunAddress serverAddress)
throws StunException, IOException, IllegalArgumentException
{
stunProvider.sendRequest(request, serverAddress, apDescriptor,
BlockingRequestSender.this);
try
{
wait();
}
catch (InterruptedException ex)
{ /** @todo log */
ex.printStackTrace();
}
StunMessageEvent res = responseEvent;
responseEvent = null; //prepare for next message
return res;
}
}