/* * TeleStax, Open Source Cloud Communications Copyright 2012. * and individual contributors * by the @authors tag. See the copyright.txt in the distribution for a * full listing of individual contributors. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.mobicents.protocols.ss7.isup.impl.stack.timers; import static org.testng.Assert.assertEquals; import static org.testng.Assert.fail; import java.io.IOException; import java.util.ArrayList; import java.util.List; import org.mobicents.protocols.ss7.isup.ISUPEvent; import org.mobicents.protocols.ss7.isup.ISUPListener; import org.mobicents.protocols.ss7.isup.ISUPProvider; import org.mobicents.protocols.ss7.isup.ISUPStack; import org.mobicents.protocols.ss7.isup.ISUPTimeoutEvent; import org.mobicents.protocols.ss7.isup.ParameterException; import org.mobicents.protocols.ss7.isup.impl.CircuitManagerImpl; import org.mobicents.protocols.ss7.isup.impl.ISUPStackImpl; import org.mobicents.protocols.ss7.isup.impl.message.AbstractISUPMessage; import org.mobicents.protocols.ss7.isup.message.ISUPMessage; import org.mobicents.protocols.ss7.mtp.Mtp3; import org.mobicents.protocols.ss7.mtp.Mtp3TransferPrimitive; import org.mobicents.protocols.ss7.mtp.Mtp3TransferPrimitiveFactory; import org.mobicents.protocols.ss7.mtp.Mtp3UserPartBaseImpl; import org.mobicents.protocols.ss7.scheduler.Clock; import org.mobicents.protocols.ss7.scheduler.DefaultClock; import org.mobicents.protocols.ss7.scheduler.Scheduler; /** * @author baranowb * */ public abstract class EventTestHarness /* extends TestCase */implements ISUPListener { protected ISUPStack stack; protected ISUPProvider provider; protected Clock clock; protected Scheduler scheduler; protected TimerTestMtp3UserPart userPart; // events received by by this listener protected List<EventReceived> localEventsReceived; // events sent to remote ISUP peer. protected List<EventReceived> remoteEventsReceived; protected static final int dpc = 1; protected static final int localSpc = 2; protected static final int ni = 2; public void setUp() throws Exception { clock = new DefaultClock(); scheduler = new Scheduler(); scheduler.setClock(clock); scheduler.start(); this.userPart = new TimerTestMtp3UserPart(); this.userPart.start(); this.stack = new ISUPStackImpl(scheduler, localSpc, ni); this.provider = this.stack.getIsupProvider(); this.provider.addListener(this); this.stack.setMtp3UserPart(this.userPart); CircuitManagerImpl cm = new CircuitManagerImpl(); cm.addCircuit(1, dpc); this.stack.setCircuitManager(cm); this.stack.start(); localEventsReceived = new ArrayList<EventTestHarness.EventReceived>(); remoteEventsReceived = new ArrayList<EventTestHarness.EventReceived>(); } public void tearDown() throws Exception { // this is done in tests // this.stack.stop(); } protected void compareEvents(List<EventReceived> expectedLocalEvents, List<EventReceived> expectedRemoteEventsReceived) { if (expectedLocalEvents.size() != this.localEventsReceived.size()) { fail("Size of local events: " + this.localEventsReceived.size() + ", does not equal expected events: " + expectedLocalEvents.size() + "\n" + doStringCompare(localEventsReceived, expectedLocalEvents)); } if (expectedRemoteEventsReceived.size() != this.remoteEventsReceived.size()) { fail("Size of remote events: " + this.remoteEventsReceived.size() + ", does not equal expected events: " + expectedRemoteEventsReceived.size() + "\n" + doStringCompare(remoteEventsReceived, expectedRemoteEventsReceived)); } for (int index = 0; index < expectedLocalEvents.size(); index++) { assertEquals(localEventsReceived.get(index), expectedLocalEvents.get(index), "Local received event does not match, index[" + index + "]"); } for (int index = 0; index < expectedLocalEvents.size(); index++) { assertEquals(remoteEventsReceived.get(index), expectedRemoteEventsReceived.get(index), "Remote received event does not match, index[" + index + "]"); } } protected String doStringCompare(List lst1, List lst2) { StringBuilder sb = new StringBuilder(); int size1 = lst1.size(); int size2 = lst2.size(); int count = size1; if (count < size2) { count = size2; } for (int index = 0; count > index; index++) { String s1 = size1 > index ? lst1.get(index).toString() : "NOP"; String s2 = size2 > index ? lst2.get(index).toString() : "NOP"; sb.append(s1).append(" - ").append(s2).append("\n"); } return sb.toString(); } public void onEvent(ISUPEvent event) { this.localEventsReceived.add(new MessageEventReceived(System.currentTimeMillis(), event)); } public void onTimeout(ISUPTimeoutEvent event) { this.localEventsReceived.add(new TimeoutEventReceived(System.currentTimeMillis(), event)); } // method implemented by test, to answer stack. protected void doAnswer() { ISUPMessage answer = getAnswer(); int opc = 1; int dpc = 2; int si = Mtp3._SI_SERVICE_ISUP; int ni = 2; int sls = 3; // int ssi = ni << 2; // ByteArrayOutputStream bout = new ByteArrayOutputStream(); // // encoding routing label // bout.write((byte) (((ssi & 0x0F) << 4) | (si & 0x0F))); // bout.write((byte) dpc); // bout.write((byte) (((dpc >> 8) & 0x3F) | ((opc & 0x03) << 6))); // bout.write((byte) (opc >> 2)); // bout.write((byte) (((opc >> 10) & 0x0F) | ((sls & 0x0F) << 4))); try { byte[] message = ((AbstractISUPMessage) answer).encode(); // bout.write(message); // byte[] msg = bout.toByteArray(); // this.userPart.toRead.add(msg); Mtp3TransferPrimitiveFactory factory = stack.getMtp3UserPart().getMtp3TransferPrimitiveFactory(); Mtp3TransferPrimitive mtpMsg = factory.createMtp3TransferPrimitive(si, ni, 0, opc, dpc, sls, message); this.userPart.sendTransferMessageToLocalUser(mtpMsg, mtpMsg.getSls()); } catch (Exception e) { e.printStackTrace(); fail("Failed on receive message: " + e); } } protected void doWait(long t) throws InterruptedException { Thread.currentThread().sleep(t); } /** * return orignial request * * @return */ protected abstract ISUPMessage getRequest(); /** * return answer to be sent. * * @return */ protected abstract ISUPMessage getAnswer(); protected class EventReceived { private long tstamp; /** * @param tstamp */ public EventReceived(long tstamp) { super(); this.tstamp = tstamp; } public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; EventReceived other = (EventReceived) obj; if (tstamp != other.tstamp) { // we have some tolerance if (other.tstamp - 100 < tstamp || other.tstamp + 100 > tstamp) { return true; } else { return false; } } return true; } } protected class MessageEventReceived extends EventReceived { private ISUPEvent event; /** * @param tstamp */ public MessageEventReceived(long tstamp, ISUPEvent event) { super(tstamp); this.event = event; } public boolean equals(Object obj) { if (this == obj) return true; if (!super.equals(obj)) return false; if (getClass() != obj.getClass()) return false; MessageEventReceived other = (MessageEventReceived) obj; if (event == null) { if (other.event != null) return false; // FIXME: use event equal? } else if (event.getMessage().getMessageType().getCode() != other.event.getMessage().getMessageType().getCode()) return false; return true; } public String toString() { return "MessageEventReceived [event=" + event + ", tstamp= " + super.tstamp + "]"; } } protected class TimeoutEventReceived extends EventReceived { private ISUPTimeoutEvent event; public TimeoutEventReceived(long tstamp, ISUPTimeoutEvent event) { super(tstamp); this.event = event; } public boolean equals(Object obj) { if (this == obj) return true; if (!super.equals(obj)) return false; if (getClass() != obj.getClass()) return false; TimeoutEventReceived other = (TimeoutEventReceived) obj; if (event == null) { if (other.event != null) return false; // FIXME: use event equal? } else if (event.getMessage().getMessageType().getCode() != other.event.getMessage().getMessageType().getCode()) { return false; } else if (event.getTimerId() != other.event.getTimerId()) { return false; } return true; } public String toString() { return "TimeoutEventReceived [event=" + event + ", tstamp= " + super.tstamp + "]"; } } private class TimerTestMtp3UserPart extends Mtp3UserPartBaseImpl { public TimerTestMtp3UserPart() { super(null); } public void sendTransferMessageToLocalUser(Mtp3TransferPrimitive msg, int seqControl) { super.sendTransferMessageToLocalUser(msg, seqControl); } @Override public void sendMessage(Mtp3TransferPrimitive mtpMsg) throws IOException { // here we have to parse ISUPMsg and store in receivedRemote long tstamp = System.currentTimeMillis(); byte[] payload = mtpMsg.getData(); int commandCode = payload[2]; AbstractISUPMessage msg = (AbstractISUPMessage) provider.getMessageFactory().createCommand(commandCode); try { msg.decode(payload, provider.getMessageFactory(),provider.getParameterFactory()); MessageEventReceived event = new MessageEventReceived(tstamp, new ISUPEvent(provider, msg, dpc)); remoteEventsReceived.add(event); } catch (ParameterException e) { e.printStackTrace(); fail("Failed on message write: " + e); } } // private ArrayList<byte[]> toRead = new ArrayList(); // // /* (non-Javadoc) // // * @see org.mobicents.protocols.ss7.mtp.Mtp3UserPart#execute() // // */ // // @Override // // public void execute() throws IOException { // // // // // // } // // /* (non-Javadoc) // * @see org.mobicents.protocols.ss7.mtp.Mtp3UserPart#read(java.nio.ByteBuffer) // */ // @Override // public int read(ByteBuffer arg0) throws IOException { // if(toRead.size()>0) // { // byte[] data = toRead.remove(0); // arg0.put(data); // return data.length; // } // return 0; // } // // /* (non-Javadoc) // * @see org.mobicents.protocols.ss7.mtp.Mtp3UserPart#write(java.nio.ByteBuffer) // */ // @Override // public int write(ByteBuffer arg0) throws IOException { // // here we have to parse ISUPMsg and store in receivedRemote // long tstamp = System.currentTimeMillis(); // byte[] msu = new byte[arg0.limit()]; // arg0.get(msu); // //arg0.s // // FIXME: change this, dont copy over and over. // int commandCode = msu[7];// 3(RL) + 1(SI)+2(CIC) - // // http://pt.com/page/tutorials/ss7-tutorial/mtp // byte[] payload = new byte[msu.length - 5]; // System.arraycopy(msu, 5, payload, 0, payload.length); // // for post processing // AbstractISUPMessage msg = (AbstractISUPMessage) provider.getMessageFactory().createCommand(commandCode); // try { // msg.decode(payload, provider.getParameterFactory()); // MessageEventReceived event = new MessageEventReceived(tstamp, new ISUPEvent(provider, msg)); // remoteEventsReceived.add(event); // return msu.length; // } catch (ParameterException e) { // e.printStackTrace(); // fail("Failed on message write: " + e); // } // return 0; // } // // public void print(StringBuffer sb, int leftPad, int descPad) { // // left pad // FormatterHelp.createPad(sb, leftPad); // // // Add name // sb.append(this.linksetName); // // // check if length is less than Link.NAME_SIZE, add padding // if (this.linksetName.length() < Linkset.NAME_SIZE) { // FormatterHelp.createPad(sb, Linkset.NAME_SIZE - this.linksetName.length()); // } // // // add desc padding // FormatterHelp.createPad(sb, descPad); // // // type is dahdi // sb.append("dahdi"); // // // add desc padding // FormatterHelp.createPad(sb, descPad); // // // add opc // sb.append(LINKSET_OPC).append(FormatterHelp.EQUAL_SIGN).append(this.opc); // // // opc can be max 8 (ANSI is max 24bits) digits. Add padding if its not // int length = (Integer.toString(this.opc).length()); // if (length < 8) { // FormatterHelp.createPad(sb, 8 - length); // } // // // add desc padding // FormatterHelp.createPad(sb, descPad); // // // add apc // sb.append(LINKSET_APC).append(FormatterHelp.EQUAL_SIGN).append(this.apc); // // // opc can be max 8 (ANSI is max 24bits) digits. Add padding if its not // length = (Integer.toString(this.apc).length()); // if (length < 8) { // FormatterHelp.createPad(sb, 8 - length); // } // // // add desc padding // FormatterHelp.createPad(sb, descPad); // // // add NI // sb.append(LINKSET_NI).append(FormatterHelp.EQUAL_SIGN).append(this.ni); // // // add desc padding // FormatterHelp.createPad(sb, descPad); // // // add state // sb.append(LINKSET_STATE).append(FormatterHelp.EQUAL_SIGN).append(FormatterHelp.getLinksetState(this.state)); // // sb.append(FormatterHelp.NEW_LINE); // // for (FastMap.Entry<String, Link> e = this.links.head(), end = this.links.tail(); (e = e.getNext()) != end;) { // Link link = e.getValue(); // link.print(sb, 4, 2); // sb.append(FormatterHelp.NEW_LINE); // } // // } } }