/** * Start time:13:34:09 2009-09-04<br> * Project: mobicents-isup-stack<br> * * @author <a href="mailto:baranowb@gmail.com">Bartosz Baranowski </a> */ package org.mobicents.ss7.isup.impl; import java.io.IOException; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import org.mobicents.ss7.isup.ISUPClientTransaction; import org.mobicents.ss7.isup.ParameterRangeInvalidException; import org.mobicents.ss7.isup.message.ISUPMessage; /** * Start time:13:34:09 2009-09-04<br> * Project: mobicents-isup-stack<br> * * @author <a href="mailto:baranowb@gmail.com">Bartosz Baranowski </a> */ public class ISUPClientTransactionImpl extends ISUPTransactionImpl implements ISUPClientTransaction { protected Future receiveResponseTimeout; protected ISUPClientTransactionState state = ISUPClientTransactionState.CREATED; /** * * @param message * @param provider * @param stack */ public ISUPClientTransactionImpl(ISUPMessage message, ISUPProviderImpl provider, ISUPStackImpl stack) { super(message, provider, stack); } /* * (non-Javadoc) * * @see org.mobicents.ss7.isup.ISUPClientTransaction#sendRequest() */ public void sendRequest() throws ParameterRangeInvalidException, IOException { synchronized (this.state) { if (state != ISUPClientTransactionState.CREATED) { return; } this.provider.sendMessage(this.message); this.setState(ISUPClientTransactionState.MESSAGE_SENT); } } /** * @param timedout */ public void setState(ISUPClientTransactionState state) { if (state == this.state) return; this.state = state; switch (this.state) { case CREATED: break; case MESSAGE_SENT: this.receiveResponseTimeout = stack.getExecutors().schedule(new ISUPClientTransactionTimeoutTask(this), stack.getClientTransactionAnswerTimeout(), TimeUnit.MILLISECONDS); super.cancelGeneralTimer(); break; case TERMINATED: this.provider.onTransactionEnded(this); break; case TIMEDOUT: this.provider.onTransactionTimeout(this); break; default: break; } } /* * (non-Javadoc) * * @see org.mobicents.ss7.isup.ISUPTransactionImpl#doGeneralTimeout() */ @Override protected void doGeneralTimeout() { synchronized (this.state) { switch (this.state) { case CREATED: super.generalTimeoutFuture = null; this.setState(ISUPClientTransactionState.TIMEDOUT); break; default: // } } } /* * (non-Javadoc) * * @see org.mobicents.ss7.isup.ISUPTransaction#isTerminated() */ public boolean isTerminated() { return this.state == ISUPClientTransactionState.TERMINATED; } /* * (non-Javadoc) * * @see org.mobicents.ss7.isup.ISUPTransaction#isTimedout() */ public boolean isTimedout() { return this.state == ISUPClientTransactionState.TIMEDOUT; } public Object getState() { return this.state; } void answerReceived() { synchronized (this.state) { if (this.state != ISUPClientTransactionState.MESSAGE_SENT) { return; } this.cancelReceiveAnswerTimer(); } } /** * */ private void cancelReceiveAnswerTimer() { if (this.receiveResponseTimeout != null) { this.receiveResponseTimeout.cancel(false); this.receiveResponseTimeout = null; } } private enum ISUPClientTransactionState { CREATED, MESSAGE_SENT, TERMINATED, TIMEDOUT; } private class ISUPClientTransactionTimeoutTask implements Runnable { private ISUPClientTransactionImpl ctx; public ISUPClientTransactionTimeoutTask(ISUPClientTransactionImpl ctx) { super(); this.ctx = ctx; } public void run() { synchronized (ctx.state) { switch (ctx.state) { case MESSAGE_SENT: // ctx.receiveResponseTimeout = null; ctx.setState(ISUPClientTransactionState.TIMEDOUT); break; default: // do nothing. } } } } }