package sip;
import java.text.ParseException;
import javax.sip.ClientTransaction;
import javax.sip.Dialog;
import javax.sip.DialogTerminatedEvent;
import javax.sip.InvalidArgumentException;
import javax.sip.RequestEvent;
import javax.sip.ResponseEvent;
import javax.sip.SipException;
import javax.sip.message.Request;
import org.apache.log4j.Logger;
public class UAC implements IMessageProcessor {
private static final Logger LOGGER = Logger.getLogger("UAC");
private SIPLayer sipLayer;
private String inviteCallId = "";
private long cSeqInvite;
private Dialog dialog;
private Dialog clientDiag;
private ClientTransaction lastClientTrans;
private boolean canceled = false;
private boolean established = false;
public UAC(SIPLayer sipLayer) {
this.sipLayer = sipLayer;
sipLayer.registerObserver(this);
}
public void sendBye() throws ParseException, InvalidArgumentException, SipException {
LOGGER.debug("sendBye()");
Request bye = clientDiag.createRequest(Request.BYE);
ClientTransaction byeTrans = sipLayer.getNewClientTransaction(bye);
clientDiag.sendRequest(byeTrans);
}
public void sendCancel() throws ParseException, InvalidArgumentException, SipException {
LOGGER.debug("sendCancel()");
canceled = true;
Request cancel = lastClientTrans.createCancel();
ClientTransaction cancelTran = sipLayer.getNewClientTransaction(cancel);
cancelTran.sendRequest();
established = false;
}
public void sendInvite(String user, String host) throws ParseException, InvalidArgumentException, SipException {
LOGGER.debug("sendInvite(" + user + ", " + host + " )");
canceled = false;
lastClientTrans = sipLayer.sendInvite(user, host, Request.INVITE);
inviteCallId = lastClientTrans.getDialog().getCallId().getCallId();
cSeqInvite = sipLayer.INVITE_SEQUENCE_NUMBER;
LOGGER.info("inviteCallId: " + inviteCallId);
}
@Override
public void processDialogTerminated(DialogTerminatedEvent dte) {
LOGGER.debug("processDialogTerminated()");
}
@Override
public void processOK(ResponseEvent responseEvent) {
LOGGER.debug("processOK()");
String receivedDialogId = responseEvent.getDialog().getDialogId();
LOGGER.trace("receivedDialogId: " + receivedDialogId);
String callId = SIPLayer.getCallId(responseEvent);
LOGGER.trace("callId: " + callId);
try {
if (inviteCallId.equals(callId) && !canceled && !established) {
established = true;
// dialog = responseEvent.getDialog();
Request ack = responseEvent.getDialog().createAck(cSeqInvite);
LOGGER.info("Sending ACK: " + ack.toString());
responseEvent.getDialog().sendAck(ack);
clientDiag = responseEvent.getDialog();
} else {
established = false;
LOGGER.info("Received OK, not for me or canceled ");
}
} catch (Exception e) {
LOGGER.warn("Could not build/send ack: ", e);
throw new RuntimeException("Could not build/send ack: ", e);
}
}
@Override
public void processTrying() {
LOGGER.debug("processTrying()");
}
@Override
public void processRinging() {
LOGGER.debug("processRinging()");
}
@Override
public void processInvite(RequestEvent requestEvent) {
LOGGER.debug("processInvite()");
}
@Override
public void processBye(RequestEvent requestEvent) {
LOGGER.debug("processBye()");
}
@Override
public void processAck(RequestEvent requestEvent) {
LOGGER.debug("processAck()");
}
public boolean removeDialog() {
LOGGER.debug("removeDialog()");
try {
Request bye = dialog.createRequest(Request.BYE);
dialog.sendRequest(sipLayer.getNewClientTransaction(bye));
return true;
} catch (SipException e) {
LOGGER.error("Could not send BYE: ", e);
return false;
}
}
}