package org.mobicents.smsc.tools.smppsimulator.testsmpp; import java.util.concurrent.ScheduledExecutorService; import org.jboss.netty.buffer.ChannelBuffer; import org.jboss.netty.channel.Channel; import org.jboss.netty.channel.ChannelFuture; import com.cloudhopper.commons.util.windowing.DuplicateKeyException; import com.cloudhopper.commons.util.windowing.OfferTimeoutException; import com.cloudhopper.commons.util.windowing.WindowFuture; import com.cloudhopper.smpp.SmppSessionConfiguration; import com.cloudhopper.smpp.SmppSessionHandler; import com.cloudhopper.smpp.SmppSessionListener; import com.cloudhopper.smpp.impl.DefaultSmppSession; import com.cloudhopper.smpp.pdu.PduRequest; import com.cloudhopper.smpp.pdu.PduResponse; import com.cloudhopper.smpp.pdu.SubmitSm; import com.cloudhopper.smpp.pdu.SubmitSmResp; import com.cloudhopper.smpp.transcoder.PduTranscoder; import com.cloudhopper.smpp.type.RecoverablePduException; import com.cloudhopper.smpp.type.SmppChannelException; import com.cloudhopper.smpp.type.SmppTimeoutException; import com.cloudhopper.smpp.type.UnrecoverablePduException; public class TestSmppSession extends DefaultSmppSession { public TestSmppSession(Type localType, SmppSessionConfiguration configuration, Channel channel, SmppSessionHandler sessionHandler, ScheduledExecutorService monitorExecutor) { super(localType, configuration, channel, sessionHandler, monitorExecutor); this.sessionHandler = sessionHandler; } SmppSessionHandler sessionHandler; TestPduTranscoder testPduTranscoder = new TestPduTranscoder(); boolean malformedPacket = false; public void setMalformedPacket() { malformedPacket = true; } protected PduTranscoder getTranscoder() { return super.getTranscoder(); } public SubmitSmResp submit(SubmitSm request, long timeoutMillis) throws RecoverablePduException, UnrecoverablePduException, SmppTimeoutException, SmppChannelException, InterruptedException { return super.submit(request, timeoutMillis); } public WindowFuture<Integer, PduRequest, PduResponse> sendRequestPdu(PduRequest pdu, long timeoutMillis, boolean synchronous) throws RecoverablePduException, UnrecoverablePduException, SmppTimeoutException, SmppChannelException, InterruptedException { // assign the next PDU sequence # if its not yet assigned if (!pdu.hasSequenceNumberAssigned()) { pdu.setSequenceNumber(this.getSequenceNumber().next()); } // encode the pdu into a buffer ChannelBuffer buffer; if (this.malformedPacket) { this.malformedPacket = false; buffer = this.testPduTranscoder.encode(pdu); } else { buffer = this.getTranscoder().encode(pdu); } WindowFuture<Integer, PduRequest, PduResponse> future = null; try { future = this.getSendWindow().offer(pdu.getSequenceNumber(), pdu, timeoutMillis, this.getConfiguration().getRequestExpiryTimeout(), synchronous); } catch (DuplicateKeyException e) { throw new UnrecoverablePduException(e.getMessage(), e); } catch (OfferTimeoutException e) { throw new SmppTimeoutException(e.getMessage(), e); } if (this.sessionHandler instanceof SmppSessionListener) { if (!((SmppSessionListener) this.sessionHandler).firePduDispatch(pdu)) { // logger.info("dispatched request PDU discarded: {}", pdu); future.cancel(); // @todo probably throwing exception here is better solution? return future; } } // we need to log the PDU after encoding since some things only happen // during the encoding process such as looking up the result message if (this.getConfiguration().getLoggingOptions().isLogPduEnabled()) { if (synchronous) { // logger.info("sync send PDU: {}", pdu); } else { // logger.info("async send PDU: {}", pdu); } } // write the pdu out & wait timeout amount of time ChannelFuture channelFuture = this.getChannel().write(buffer).await(); // check if the write was a success if (!channelFuture.isSuccess()) { // the write failed, make sure to throw an exception throw new SmppChannelException(channelFuture.getCause().getMessage(), channelFuture.getCause()); } // this.countSendRequestPdu(pdu); return future; } }