PageRenderTime 115ms CodeModel.GetById 36ms app.highlight 68ms RepoModel.GetById 1ms app.codeStats 1ms

/protocols/ss7/isup/isup-impl/src/main/java/org/mobicents/protocols/ss7/isup/impl/Circuit.java

http://mobicents.googlecode.com/
Java | 1409 lines | 886 code | 193 blank | 330 comment | 74 complexity | 30784c4b82bfeceed5ef35fcf7258b93 MD5 | raw file
   1/*
   2 * JBoss, Home of Professional Open Source
   3 * Copyright 2011, Red Hat, Inc. and individual contributors
   4 * by the @authors tag. See the copyright.txt in the distribution for a
   5 * full listing of individual contributors.
   6 *
   7 * This is free software; you can redistribute it and/or modify it
   8 * under the terms of the GNU Lesser General Public License as
   9 * published by the Free Software Foundation; either version 2.1 of
  10 * the License, or (at your option) any later version.
  11 *
  12 * This software is distributed in the hope that it will be useful,
  13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15 * Lesser General Public License for more details.
  16 *
  17 * You should have received a copy of the GNU Lesser General Public
  18 * License along with this software; if not, write to the Free
  19 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  20 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
  21 */
  22
  23package org.mobicents.protocols.ss7.isup.impl;
  24
  25import java.io.ByteArrayOutputStream;
  26import java.io.IOException;
  27import java.util.List;
  28import java.util.concurrent.Future;
  29import java.util.concurrent.ScheduledExecutorService;
  30import java.util.concurrent.TimeUnit;
  31
  32import javolution.util.FastList;
  33import javolution.util.ReentrantLock;
  34
  35import org.mobicents.protocols.ss7.isup.ISUPEvent;
  36import org.mobicents.protocols.ss7.isup.ISUPTimeoutEvent;
  37import org.mobicents.protocols.ss7.isup.ParameterException;
  38import org.mobicents.protocols.ss7.isup.impl.message.AbstractISUPMessage;
  39import org.mobicents.protocols.ss7.isup.message.AddressCompleteMessage;
  40import org.mobicents.protocols.ss7.isup.message.BlockingAckMessage;
  41import org.mobicents.protocols.ss7.isup.message.BlockingMessage;
  42import org.mobicents.protocols.ss7.isup.message.CircuitGroupBlockingMessage;
  43import org.mobicents.protocols.ss7.isup.message.CircuitGroupQueryMessage;
  44import org.mobicents.protocols.ss7.isup.message.CircuitGroupQueryResponseMessage;
  45import org.mobicents.protocols.ss7.isup.message.CircuitGroupResetAckMessage;
  46import org.mobicents.protocols.ss7.isup.message.CircuitGroupResetMessage;
  47import org.mobicents.protocols.ss7.isup.message.CircuitGroupUnblockingAckMessage;
  48import org.mobicents.protocols.ss7.isup.message.CircuitGroupUnblockingMessage;
  49import org.mobicents.protocols.ss7.isup.message.ConnectMessage;
  50import org.mobicents.protocols.ss7.isup.message.ISUPMessage;
  51import org.mobicents.protocols.ss7.isup.message.InformationMessage;
  52import org.mobicents.protocols.ss7.isup.message.InformationRequestMessage;
  53import org.mobicents.protocols.ss7.isup.message.InitialAddressMessage;
  54import org.mobicents.protocols.ss7.isup.message.ReleaseCompleteMessage;
  55import org.mobicents.protocols.ss7.isup.message.ReleaseMessage;
  56import org.mobicents.protocols.ss7.isup.message.ResetCircuitMessage;
  57import org.mobicents.protocols.ss7.isup.message.SubsequentAddressMessage;
  58import org.mobicents.protocols.ss7.isup.message.UnblockingAckMessage;
  59import org.mobicents.protocols.ss7.isup.message.UnblockingMessage;
  60import org.mobicents.protocols.ss7.isup.message.parameter.CauseIndicators;
  61import org.mobicents.protocols.ss7.mtp.Mtp3;
  62import org.mobicents.protocols.ss7.mtp.Mtp3TransferPrimitive;
  63
  64/**
  65 *
  66 * @author baranowb
  67 * 
  68 */
  69@SuppressWarnings("rawtypes")
  70class Circuit implements Runnable {
  71	private final int cic;
  72	private final int dpc;
  73	private final ISUPProviderImpl provider;
  74
  75	private ReentrantLock lock = new ReentrantLock();
  76	private ScheduledExecutorService executor;
  77	private List<ISUPMessage> incoming = new FastList<ISUPMessage>(); // use
  78																		// linked
  79																		// list
  80																		// ?
  81	private ByteArrayOutputStream bos = new ByteArrayOutputStream(300);
  82
  83	/**
  84	 * @param cic
  85	 */
  86	public Circuit(int cic, int dpc,ISUPProviderImpl provider) {
  87		this.cic = cic;
  88		this.dpc = dpc;
  89		this.provider = provider;
  90		this.executor = provider.getExecutor(cic);
  91	}
  92
  93	/**
  94	 * @param timerId
  95	 * @return
  96	 */
  97	public boolean cancelTimer(int timerId) {
  98		try {
  99
 100			lock.lock();
 101			switch (timerId) {
 102			case ISUPTimeoutEvent.T1:
 103				return cancelT1();
 104			case ISUPTimeoutEvent.T5:
 105				return cancelT5();
 106			case ISUPTimeoutEvent.T7:
 107				return cancelT7();
 108			case ISUPTimeoutEvent.T12:
 109				return cancelT12();
 110			case ISUPTimeoutEvent.T13:
 111				return cancelT13();
 112			case ISUPTimeoutEvent.T14:
 113				return cancelT14();
 114			case ISUPTimeoutEvent.T15:
 115				return cancelT15();
 116			case ISUPTimeoutEvent.T16:
 117				return cancelT16();
 118			case ISUPTimeoutEvent.T17:
 119				return cancelT17();
 120			case ISUPTimeoutEvent.T18:
 121				return cancelT18();
 122			case ISUPTimeoutEvent.T19:
 123				return cancelT19();
 124			case ISUPTimeoutEvent.T20:
 125				return cancelT20();
 126			case ISUPTimeoutEvent.T21:
 127				return cancelT21();
 128			case ISUPTimeoutEvent.T22:
 129				return cancelT22();
 130			case ISUPTimeoutEvent.T23:
 131				return cancelT23();
 132			case ISUPTimeoutEvent.T28:
 133				return cancelT28();
 134			case ISUPTimeoutEvent.T33:
 135				return cancelT33();
 136			default:
 137				return false;
 138			}
 139		} finally {
 140			lock.unlock();
 141		}
 142	}
 143
 144	/**
 145	 * @param message
 146	 */
 147	public void receive(ISUPMessage message) {
 148		incoming.add(message);
 149		this.executor.execute(this);
 150	}
 151
 152	/**
 153	 * @param message
 154	 * @throws ParameterException
 155	 * @throws IOException 
 156	 */
 157	public void send(ISUPMessage message) throws ParameterException, IOException {
 158		try {
 159			lock.lock();
 160			bos.reset();
 161			// FIXME: add SEG creation?
 162			Mtp3TransferPrimitive msg = decorate(message);
 163			// process timers
 164			switch (message.getMessageType().getCode()) {
 165			case ReleaseMessage.MESSAGE_CODE:
 166				startRELTimers(msg, (ReleaseMessage) message);
 167				break;
 168			case SubsequentAddressMessage.MESSAGE_CODE:
 169			case InitialAddressMessage.MESSAGE_CODE:
 170				startXAMTimers(message);
 171				break;
 172			case BlockingMessage.MESSAGE_CODE:
 173				startBLOTimers(msg, (BlockingMessage) message);
 174				break;
 175			case UnblockingMessage.MESSAGE_CODE:
 176				startUBLTimers(msg, (UnblockingMessage) message);
 177				break;
 178
 179			case ResetCircuitMessage.MESSAGE_CODE:
 180				startRSCTimers(msg, (ResetCircuitMessage) message);
 181				break;
 182
 183			case CircuitGroupBlockingMessage.MESSAGE_CODE:
 184				startCGBTimers(msg, (CircuitGroupBlockingMessage) message);
 185				break;
 186
 187			case CircuitGroupUnblockingMessage.MESSAGE_CODE:
 188				startCGUTimers(msg, (CircuitGroupUnblockingMessage) message);
 189				break;
 190			case CircuitGroupResetMessage.MESSAGE_CODE:
 191				startGRSTimers(msg, (CircuitGroupResetMessage) message);
 192				break;
 193			case CircuitGroupQueryMessage.MESSAGE_CODE:
 194				startCQMTimers((CircuitGroupQueryMessage) message);
 195				break;
 196			case InformationRequestMessage.MESSAGE_CODE:
 197				startINRTimers((InformationRequestMessage) message);
 198				break;
 199			}
 200			// send
 201			provider.send(msg);
 202		} finally {
 203			lock.unlock();
 204		}
 205
 206	}
 207	
 208	/**
 209	 * @param message
 210	 * @return
 211	 * @throws ParameterException 
 212	 * @throws IOException 
 213	 */
 214	private Mtp3TransferPrimitive decorate(ISUPMessage message) throws ParameterException, IOException {
 215		((AbstractISUPMessage) message).encode(bos);
 216		byte[] encoded = bos.toByteArray();
 217		int opc = this.provider.getLocalSpc();
 218		int dpc = this.dpc;
 219		int si = Mtp3._SI_SERVICE_ISUP;
 220		int ni = this.provider.getNi();
 221		int sls = message.getSls() & 0x0F; //promote
 222//		int ssi = ni << 2;
 223
 224	
 225//		ByteArrayOutputStream bout = new ByteArrayOutputStream();
 226//		// encoding routing label
 227//		bout.write((byte) (((ssi & 0x0F) << 4) | (si & 0x0F)));
 228//		bout.write((byte) dpc);
 229//		bout.write((byte) (((dpc >> 8) & 0x3F) | ((opc & 0x03) << 6)));
 230//		bout.write((byte) (opc >> 2));
 231//		bout.write((byte) (((opc >> 10) & 0x0F) | ((sls & 0x0F) << 4)));
 232//		bout.write(encoded);
 233//		byte[] msg = bout.toByteArray();
 234
 235		
 236		Mtp3TransferPrimitive msg = new Mtp3TransferPrimitive(si, ni, 0, opc, dpc, sls, encoded);
 237		return msg;
 238	}
 239
 240	public void run() {
 241		try {
 242			lock.lock();
 243			ISUPMessage message = this.incoming.remove(0);
 244
 245			// process timers
 246			switch (message.getMessageType().getCode()) {
 247			// FIXME: add check for SEG
 248			case ReleaseCompleteMessage.MESSAGE_CODE:
 249				// this is tricy BS.... its REL and RSC are answered with RLC
 250
 251				if (!stopRELTimers()) {
 252					stopRSCTimers();
 253				}
 254				break;
 255			case AddressCompleteMessage.MESSAGE_CODE:
 256			case ConnectMessage.MESSAGE_CODE:
 257				stoptXAMTimers();
 258				break;
 259			case BlockingAckMessage.MESSAGE_CODE:
 260				stoptBLOTimers();
 261				break;
 262			case UnblockingAckMessage.MESSAGE_CODE:
 263				stoptUBLTimers();
 264				break;
 265			case CircuitGroupBlockingMessage.MESSAGE_CODE:
 266				stoptCGBTimers();
 267				break;
 268
 269			case CircuitGroupUnblockingAckMessage.MESSAGE_CODE:
 270				stoptCGUTimers();
 271				break;
 272			case CircuitGroupResetAckMessage.MESSAGE_CODE:
 273				stoptGRSTimers();
 274				break;
 275			case CircuitGroupQueryResponseMessage.MESSAGE_CODE:
 276				stoptCQMTimers();
 277				break;
 278			case InformationMessage.MESSAGE_CODE:
 279				stoptINRTimers();
 280				break;
 281			}
 282
 283			// deliver
 284			ISUPEvent event = new ISUPEvent(provider, message);
 285			this.provider.deliver(event);
 286		} catch (Exception e) {
 287			// catch exception, so thread dont die.
 288			e.printStackTrace();
 289		} finally {
 290			lock.unlock();
 291		}
 292	}
 293
 294	// ----------------- timer handlers ----------------------
 295
 296	// FIXME: check how t3 works....
 297
 298	private Future t1;
 299	private Future t5;
 300	private Mtp3TransferPrimitive t1t5encodedREL; // keep encoded value, so we can simply send,
 301									// without spending CPU on encoding.
 302	private ReleaseMessage t1t5REL; // keep for timers.
 303	private Future t7;
 304	private ISUPMessage t7AddressMessage; // IAM/SAM
 305
 306	// FIXME: t8 - receive IAM with contuuity check ind.
 307	// FIXME: t11
 308	// FIXME: t11
 309	private Future t12;
 310	private Future t13;
 311	private Mtp3TransferPrimitive t12t13encodedBLO; // keep encoded value, so we can simply
 312										// send, without spending CPU on
 313										// encoding.
 314	private BlockingMessage t12t13BLO; // keep for timers.
 315
 316	private Future t14;
 317	private Future t15;
 318	private Mtp3TransferPrimitive t14t15encodedUBL; // keep encoded value, so we can simply
 319										// send, without spending CPU on
 320										// encoding.
 321	private UnblockingMessage t14t15UBL; // keep for timers.
 322
 323	private Future t16;
 324	private Future t17;
 325	private Mtp3TransferPrimitive t16t17encodedRSC; // keep encoded value, so we can simply
 326										// send, without spending CPU on
 327										// encoding.
 328	private ResetCircuitMessage t16t17RSC; // keep for timers.
 329
 330	private Future t18;
 331	private Future t19;
 332	private Mtp3TransferPrimitive t18t19encodedCGB; // keep encoded value, so we can simply
 333										// send, without spending CPU on
 334										// encoding.
 335	private CircuitGroupBlockingMessage t18t19CGB; // keep for timers.
 336
 337	private Future t20;
 338	private Future t21;
 339	private Mtp3TransferPrimitive t20t21encodedCGU; // keep encoded value, so we can simply
 340										// send, without spending CPU on
 341										// encoding.
 342	private CircuitGroupUnblockingMessage t20t21CGU; // keep for timers.
 343
 344	private Future t22;
 345	private Future t23;
 346	private Mtp3TransferPrimitive t22t23encodedGRS; // keep encoded value, so we can simply
 347										// send, without spending CPU on
 348										// encoding.
 349	private CircuitGroupResetMessage t22t23GRS; // keep for timers.
 350
 351	private Future t28;
 352	private CircuitGroupQueryMessage t28CQM;
 353
 354	private Future t33;
 355	private InformationRequestMessage t33INR;
 356
 357	// FIXME: t34 - check how SEG works
 358
 359	private void startRELTimers(Mtp3TransferPrimitive encoded, ReleaseMessage rel) {
 360		// FIXME: add lock ?
 361		this.t1t5encodedREL = encoded;
 362		this.t1t5REL = rel;
 363
 364		// it is started always.
 365		startT1();
 366
 367		if (t5 == null) {
 368			startT5();
 369		}
 370	}
 371
 372	/**
 373	 * @return
 374	 */
 375	private boolean stopRELTimers() {
 376		if (this.t1 != null || this.t5 != null) {
 377			cancelT1();
 378			cancelT5();
 379			return true;
 380		} else {
 381			return false;
 382		}
 383	}
 384
 385	/**
 386	 * @param encoded
 387	 * @param message
 388	 */
 389	private void startXAMTimers(ISUPMessage message) {
 390		this.cancelT7();
 391		this.t7AddressMessage = message;
 392		this.startT7();
 393	}
 394
 395	/**
 396	 * @return
 397	 */
 398	private void stoptXAMTimers() {
 399		cancelT7();
 400	}
 401
 402	/**
 403	 * @param encoded
 404	 * @param message
 405	 */
 406	private void startBLOTimers(Mtp3TransferPrimitive encoded, BlockingMessage message) {
 407		this.t12t13BLO = message;
 408		this.t12t13encodedBLO = encoded;
 409		// it is started always.
 410		startT12();
 411
 412		if (this.t13 == null) {
 413			startT13();
 414		}
 415
 416	}
 417
 418	/**
 419	 * @return
 420	 */
 421	private void stoptBLOTimers() {
 422		cancelT12();
 423		cancelT13();
 424	}
 425
 426	/**
 427	 * @param encoded
 428	 * @param message
 429	 */
 430	private void startUBLTimers(Mtp3TransferPrimitive encoded, UnblockingMessage message) {
 431		this.t14t15UBL = message;
 432		this.t14t15encodedUBL = encoded;
 433		// it is started always.
 434		startT14();
 435
 436		if (this.t15 == null) {
 437			startT15();
 438		}
 439
 440	}
 441
 442	/**
 443	 * @return
 444	 */
 445	private void stoptUBLTimers() {
 446		cancelT14();
 447		cancelT15();
 448
 449	}
 450
 451	/**
 452	 * @param encoded
 453	 * @param message
 454	 */
 455	private void startRSCTimers(Mtp3TransferPrimitive encoded, ResetCircuitMessage message) {
 456		this.t16t17RSC = message;
 457		this.t16t17encodedRSC = encoded;
 458		// it is started always.
 459		startT16();
 460
 461		if (this.t17 == null) {
 462			startT17();
 463		}
 464
 465	}
 466
 467	/**
 468	 * @return
 469	 */
 470	private void stopRSCTimers() {
 471		cancelT16();
 472		cancelT17();
 473	}
 474
 475	/**
 476	 * @param encoded
 477	 * @param message
 478	 */
 479	private void startINRTimers(InformationRequestMessage message) {
 480		this.t33INR = message;
 481		startT33();
 482	}
 483
 484	/**
 485	 * @return
 486	 */
 487	private void stoptINRTimers() {
 488		cancelT33();
 489	}
 490
 491	/**
 492	 * @param encoded
 493	 * @param message
 494	 */
 495	private void startCQMTimers(CircuitGroupQueryMessage message) {
 496		this.t28CQM = message;
 497
 498		// it is started always.
 499		startT28();
 500		// FIXME: can we send more than one?
 501	}
 502
 503	/**
 504	 * @return
 505	 */
 506	private void stoptCQMTimers() {
 507		cancelT28();
 508	}
 509
 510	/**
 511	 * @param encoded
 512	 * @param message
 513	 */
 514	private void startGRSTimers(Mtp3TransferPrimitive encoded, CircuitGroupResetMessage message) {
 515		this.t22t23GRS = message;
 516		this.t22t23encodedGRS = encoded;
 517		// it is started always.
 518		startT22();
 519
 520		if (this.t23 == null) {
 521			startT23();
 522		}
 523	}
 524
 525	/**
 526	 * @return
 527	 */
 528	private void stoptGRSTimers() {
 529		cancelT22();
 530		cancelT23();
 531	}
 532
 533	/**
 534	 * @param encoded
 535	 * @param message
 536	 */
 537	private void startCGUTimers(Mtp3TransferPrimitive encoded, CircuitGroupUnblockingMessage message) {
 538		this.t20t21CGU = message;
 539		this.t20t21encodedCGU = encoded;
 540		// it is started always.
 541		startT20();
 542
 543		if (this.t21 == null) {
 544			startT21();
 545		}
 546
 547	}
 548
 549	/**
 550	 * @return
 551	 */
 552	private void stoptCGUTimers() {
 553		cancelT20();
 554		cancelT21();
 555	}
 556
 557	/**
 558	 * @param encoded
 559	 * @param message
 560	 */
 561	private void startCGBTimers(Mtp3TransferPrimitive encoded, CircuitGroupBlockingMessage message) {
 562		this.t18t19CGB = message;
 563		this.t18t19encodedCGB = encoded;
 564		// it is started always.
 565		startT18();
 566
 567		if (this.t19 == null) {
 568			startT19();
 569		}
 570
 571	}
 572
 573	/**
 574	 * @return
 575	 */
 576	private void stoptCGBTimers() {
 577		cancelT18();
 578		cancelT19();
 579	}
 580
 581	private void startT1() {
 582		cancelT1();
 583		this.t1 = this.executor.schedule(new TimerT1(), this.provider.getT1Timeout(), TimeUnit.MILLISECONDS);
 584	}
 585
 586	private boolean cancelT1() {
 587		if (this.t1 != null) {
 588			this.t1.cancel(false);
 589			this.t1 = null;
 590			return true;
 591		} else {
 592			return false;
 593		}
 594	}
 595
 596	private void startT5() {
 597		cancelT5();
 598		this.t5 = this.executor.schedule(new TimerT5(), this.provider.getT5Timeout(), TimeUnit.MILLISECONDS);
 599	}
 600
 601	private boolean cancelT5() {
 602		if (this.t5 != null) {
 603			this.t5.cancel(false);
 604			this.t5 = null;
 605			return true;
 606		} else {
 607			return false;
 608		}
 609
 610	}
 611
 612	private void startT7() {
 613		cancelT7();
 614		this.t7 = this.executor.schedule(new TimerT7(), this.provider.getT7Timeout(), TimeUnit.MILLISECONDS);
 615	}
 616
 617	private boolean cancelT7() {
 618		if (this.t7 != null) {
 619			this.t7.cancel(false);
 620			this.t7 = null;
 621			return true;
 622		} else {
 623			return false;
 624		}
 625
 626	}
 627
 628	private void startT12() {
 629		cancelT12();
 630		this.t12 = this.executor.schedule(new TimerT12(), this.provider.getT12Timeout(), TimeUnit.MILLISECONDS);
 631	}
 632
 633	private boolean cancelT12() {
 634		if (this.t12 != null) {
 635			this.t12.cancel(false);
 636			this.t12 = null;
 637			return true;
 638		} else {
 639			return false;
 640		}
 641	}
 642
 643	private void startT13() {
 644		cancelT13();
 645		this.t13 = this.executor.schedule(new TimerT13(), this.provider.getT13Timeout(), TimeUnit.MILLISECONDS);
 646	}
 647
 648	private boolean cancelT13() {
 649		if (this.t13 != null) {
 650			this.t13.cancel(false);
 651			this.t13 = null;
 652			return true;
 653		} else {
 654			return false;
 655		}
 656
 657	}
 658
 659	private void startT14() {
 660		cancelT14();
 661		this.t14 = this.executor.schedule(new TimerT14(), this.provider.getT14Timeout(), TimeUnit.MILLISECONDS);
 662	}
 663
 664	private boolean cancelT14() {
 665		if (this.t14 != null) {
 666			this.t14.cancel(false);
 667			this.t14 = null;
 668			return true;
 669		} else {
 670			return false;
 671		}
 672	}
 673
 674	private void startT15() {
 675		cancelT15();
 676		this.t15 = this.executor.schedule(new TimerT15(), this.provider.getT15Timeout(), TimeUnit.MILLISECONDS);
 677	}
 678
 679	private boolean cancelT15() {
 680		if (this.t15 != null) {
 681			this.t15.cancel(false);
 682			this.t15 = null;
 683			return true;
 684		} else {
 685			return false;
 686		}
 687
 688	}
 689
 690	private void startT16() {
 691		cancelT16();
 692		this.t16 = this.executor.schedule(new TimerT16(), this.provider.getT16Timeout(), TimeUnit.MILLISECONDS);
 693	}
 694
 695	private boolean cancelT16() {
 696		if (this.t16 != null) {
 697			this.t16.cancel(false);
 698			this.t16 = null;
 699			return true;
 700		} else {
 701			return false;
 702		}
 703	}
 704
 705	private void startT17() {
 706		cancelT17();
 707		this.t17 = this.executor.schedule(new TimerT17(), this.provider.getT17Timeout(), TimeUnit.MILLISECONDS);
 708	}
 709
 710	private boolean cancelT17() {
 711		if (this.t17 != null) {
 712			this.t17.cancel(false);
 713			this.t17 = null;
 714			return true;
 715		} else {
 716			return false;
 717		}
 718
 719	}
 720
 721	private void startT18() {
 722		cancelT18();
 723		this.t18 = this.executor.schedule(new TimerT18(), this.provider.getT18Timeout(), TimeUnit.MILLISECONDS);
 724	}
 725
 726	private boolean cancelT18() {
 727		if (this.t18 != null) {
 728			this.t18.cancel(false);
 729			this.t18 = null;
 730			return true;
 731		} else {
 732			return false;
 733		}
 734	}
 735
 736	private void startT19() {
 737		cancelT19();
 738		this.t19 = this.executor.schedule(new TimerT19(), this.provider.getT19Timeout(), TimeUnit.MILLISECONDS);
 739	}
 740
 741	private boolean cancelT19() {
 742		if (this.t19 != null) {
 743			this.t19.cancel(false);
 744			this.t19 = null;
 745			return true;
 746		} else {
 747			return false;
 748		}
 749	}
 750
 751	private void startT20() {
 752		cancelT20();
 753		this.t20 = this.executor.schedule(new TimerT20(), this.provider.getT20Timeout(), TimeUnit.MILLISECONDS);
 754	}
 755
 756	private boolean cancelT20() {
 757		if (this.t20 != null) {
 758			this.t20.cancel(false);
 759			this.t20 = null;
 760			return true;
 761		} else {
 762			return false;
 763		}
 764	}
 765
 766	private void startT21() {
 767		cancelT21();
 768		this.t21 = this.executor.schedule(new TimerT21(), this.provider.getT21Timeout(), TimeUnit.MILLISECONDS);
 769	}
 770
 771	private boolean cancelT21() {
 772		if (this.t21 != null) {
 773			this.t21.cancel(false);
 774			this.t21 = null;
 775			return true;
 776		} else {
 777			return false;
 778		}
 779
 780	}
 781
 782	private void startT22() {
 783		cancelT22();
 784		this.t22 = this.executor.schedule(new TimerT22(), this.provider.getT22Timeout(), TimeUnit.MILLISECONDS);
 785	}
 786
 787	private boolean cancelT22() {
 788		if (this.t22 != null) {
 789			this.t22.cancel(false);
 790			this.t22 = null;
 791			return true;
 792		} else {
 793			return false;
 794		}
 795	}
 796
 797	private void startT23() {
 798		cancelT23();
 799		this.t23 = this.executor.schedule(new TimerT23(), this.provider.getT23Timeout(), TimeUnit.MILLISECONDS);
 800	}
 801
 802	private boolean cancelT23() {
 803		if (this.t23 != null) {
 804			this.t23.cancel(false);
 805			this.t23 = null;
 806			return true;
 807		} else {
 808			return false;
 809		}
 810
 811	}
 812
 813	private void startT28() {
 814		cancelT28();
 815		this.t28 = this.executor.schedule(new TimerT28(), this.provider.getT28Timeout(), TimeUnit.MILLISECONDS);
 816	}
 817
 818	private boolean cancelT28() {
 819		if (this.t28 != null) {
 820			this.t28.cancel(false);
 821			this.t28 = null;
 822			return true;
 823		} else {
 824			return false;
 825		}
 826	}
 827
 828	private void startT33() {
 829		cancelT33();
 830		this.t33 = this.executor.schedule(new TimerT33(), this.provider.getT33Timeout(), TimeUnit.MILLISECONDS);
 831	}
 832
 833	private boolean cancelT33() {
 834		if (this.t33 != null) {
 835			this.t33.cancel(false);
 836			this.t33 = null;
 837			return true;
 838		} else {
 839			return false;
 840		}
 841	}
 842
 843	private class TimerT1 implements Runnable {
 844
 845		/*
 846		 * (non-Javadoc)
 847		 * 
 848		 * @see java.lang.Runnable#run()
 849		 */
 850
 851		public void run() {
 852			try {
 853				lock.lock();
 854				// remove us
 855				t1 = null;
 856				// start T1
 857				startT1();
 858				// send
 859				provider.send(t1t5encodedREL);
 860				// notify user
 861				ISUPTimeoutEvent timeoutEvent = new ISUPTimeoutEvent(provider, t1t5REL, ISUPTimeoutEvent.T1);
 862				provider.deliver(timeoutEvent);
 863			} catch (Exception e) {
 864				e.printStackTrace();
 865			} finally {
 866				lock.unlock();
 867			}
 868		}
 869
 870	}
 871
 872	private class TimerT5 implements Runnable {
 873
 874		/*
 875		 * (non-Javadoc)
 876		 * 
 877		 * @see java.lang.Runnable#run()
 878		 */
 879
 880		public void run() {
 881			try {
 882				lock.lock();
 883				// remove t5, its current runnable.
 884				t5 = null;
 885				// cancel T1
 886				cancelT1();
 887				// restart T5
 888				startT5();
 889				// send
 890				ResetCircuitMessage rcm = provider.getMessageFactory().createRSC(cic);
 891				// avoid provider method, since we dont want other timer to be
 892				// setup.
 893				provider.sendMessage(rcm);
 894
 895				// notify user
 896				ISUPTimeoutEvent timeoutEvent = new ISUPTimeoutEvent(provider, t1t5REL, ISUPTimeoutEvent.T5);
 897				provider.deliver(timeoutEvent);
 898			} catch (Exception e) {
 899				e.printStackTrace();
 900			} finally {
 901				lock.unlock();
 902			}
 903		}
 904
 905	}
 906
 907	private class TimerT7 implements Runnable {
 908
 909		/*
 910		 * (non-Javadoc)
 911		 * 
 912		 * @see java.lang.Runnable#run()
 913		 */
 914
 915		public void run() {
 916			try {
 917				lock.lock();
 918				t7 = null;
 919				// send REL
 920				ReleaseMessage rel = provider.getMessageFactory().createREL(cic);
 921
 922				try {
 923					CauseIndicators ci = provider.getParameterFactory().createCauseIndicators();
 924					// TODO: add CI values
 925					rel.setCauseIndicators(ci);
 926					provider.sendMessage(rel);
 927				} catch (ParameterException e) {
 928					// TODO Auto-generated catch block
 929					e.printStackTrace();
 930				} catch (IOException e) {
 931					// TODO Auto-generated catch block
 932					e.printStackTrace();
 933				}
 934				// notify user
 935				ISUPTimeoutEvent timeoutEvent = new ISUPTimeoutEvent(provider, t7AddressMessage, ISUPTimeoutEvent.T7);
 936				t7AddressMessage = null;
 937				provider.deliver(timeoutEvent);
 938			} catch (Exception e) {
 939				e.printStackTrace();
 940			} finally {
 941				lock.unlock();
 942			}
 943		}
 944
 945	}
 946
 947	private class TimerT12 implements Runnable {
 948
 949		/*
 950		 * (non-Javadoc)
 951		 * 
 952		 * @see java.lang.Runnable#run()
 953		 */
 954
 955		public void run() {
 956			try {
 957				lock.lock();
 958				// remove us
 959				t12 = null;
 960				// start T12
 961				startT12();
 962				// send
 963				provider.send(t12t13encodedBLO);
 964				// notify user
 965				ISUPTimeoutEvent timeoutEvent = new ISUPTimeoutEvent(provider, t12t13BLO, ISUPTimeoutEvent.T12);
 966				provider.deliver(timeoutEvent);
 967			} catch (Exception e) {
 968				e.printStackTrace();
 969			} finally {
 970				lock.unlock();
 971			}
 972		}
 973
 974	}
 975
 976	private class TimerT13 implements Runnable {
 977
 978		/*
 979		 * (non-Javadoc)
 980		 * 
 981		 * @see java.lang.Runnable#run()
 982		 */
 983
 984		public void run() {
 985			try {
 986				lock.lock();
 987
 988				// remove t13, its current runnable.
 989				t13 = null;
 990				// cancel T12
 991				cancelT12();
 992				// restart T13
 993				startT13();
 994				// send
 995				provider.send(t12t13encodedBLO);
 996				// notify user
 997				ISUPTimeoutEvent timeoutEvent = new ISUPTimeoutEvent(provider, t12t13BLO, ISUPTimeoutEvent.T13);
 998				provider.deliver(timeoutEvent);
 999			} catch (Exception e) {
1000				e.printStackTrace();
1001			} finally {
1002				lock.unlock();
1003			}
1004		}
1005
1006	}
1007
1008	private class TimerT14 implements Runnable {
1009
1010		/*
1011		 * (non-Javadoc)
1012		 * 
1013		 * @see java.lang.Runnable#run()
1014		 */
1015
1016		public void run() {
1017			try {
1018				lock.lock();
1019				// remove us
1020				t14 = null;
1021				// start T14
1022				startT14();
1023				// send
1024				provider.send(t14t15encodedUBL);
1025				// notify user
1026				ISUPTimeoutEvent timeoutEvent = new ISUPTimeoutEvent(provider, t14t15UBL, ISUPTimeoutEvent.T14);
1027				provider.deliver(timeoutEvent);
1028			} catch (Exception e) {
1029				e.printStackTrace();
1030			} finally {
1031				lock.unlock();
1032			}
1033		}
1034
1035	}
1036
1037	private class TimerT15 implements Runnable {
1038
1039		/*
1040		 * (non-Javadoc)
1041		 * 
1042		 * @see java.lang.Runnable#run()
1043		 */
1044
1045		public void run() {
1046			try {
1047				lock.lock();
1048				// remove t15, its current runnable.
1049				t15 = null;
1050				// cancel T14
1051				cancelT14();
1052				// start
1053				startT15();
1054				// send
1055				provider.send(t14t15encodedUBL);
1056				// notify user
1057				ISUPTimeoutEvent timeoutEvent = new ISUPTimeoutEvent(provider, t14t15UBL, ISUPTimeoutEvent.T15);
1058				provider.deliver(timeoutEvent);
1059			} catch (Exception e) {
1060				e.printStackTrace();
1061			} finally {
1062				lock.unlock();
1063			}
1064		}
1065
1066	}
1067
1068	private class TimerT16 implements Runnable {
1069
1070		/*
1071		 * (non-Javadoc)
1072		 * 
1073		 * @see java.lang.Runnable#run()
1074		 */
1075
1076		public void run() {
1077			try {
1078				lock.lock();
1079				// remove us
1080				t16 = null;
1081				// start T14
1082				startT16();
1083				// send
1084				provider.send(t16t17encodedRSC);
1085				// notify user
1086				ISUPTimeoutEvent timeoutEvent = new ISUPTimeoutEvent(provider, t16t17RSC, ISUPTimeoutEvent.T16);
1087				provider.deliver(timeoutEvent);
1088			} catch (Exception e) {
1089				e.printStackTrace();
1090			} finally {
1091				lock.unlock();
1092			}
1093		}
1094
1095	}
1096
1097	private class TimerT17 implements Runnable {
1098
1099		/*
1100		 * (non-Javadoc)
1101		 * 
1102		 * @see java.lang.Runnable#run()
1103		 */
1104
1105		public void run() {
1106			try {
1107				lock.lock();
1108				// remove t17, its current runnable.
1109				t17 = null;
1110				// cancel T16
1111				cancelT16();
1112				// restart T17
1113				startT17();
1114				// send
1115				provider.send(t16t17encodedRSC);
1116				// notify user
1117				ISUPTimeoutEvent timeoutEvent = new ISUPTimeoutEvent(provider, t16t17RSC, ISUPTimeoutEvent.T17);
1118				provider.deliver(timeoutEvent);
1119			} catch (Exception e) {
1120				e.printStackTrace();
1121			} finally {
1122				lock.unlock();
1123			}
1124		}
1125
1126	}
1127
1128	private class TimerT18 implements Runnable {
1129
1130		/*
1131		 * (non-Javadoc)
1132		 * 
1133		 * @see java.lang.Runnable#run()
1134		 */
1135
1136		public void run() {
1137			try {
1138				lock.lock();
1139				// remove us
1140				t18 = null;
1141				// start T18
1142				startT18();
1143				// send
1144				provider.send(t18t19encodedCGB);
1145				// notify user
1146				ISUPTimeoutEvent timeoutEvent = new ISUPTimeoutEvent(provider, t18t19CGB, ISUPTimeoutEvent.T18);
1147				provider.deliver(timeoutEvent);
1148			} catch (Exception e) {
1149				e.printStackTrace();
1150			} finally {
1151				lock.unlock();
1152			}
1153		}
1154
1155	}
1156
1157	private class TimerT19 implements Runnable {
1158
1159		/*
1160		 * (non-Javadoc)
1161		 * 
1162		 * @see java.lang.Runnable#run()
1163		 */
1164
1165		public void run() {
1166			try {
1167				lock.lock();
1168				// remove t19, its current runnable.
1169				t19 = null;
1170				// cancel T18
1171				cancelT18();
1172				// restart T19
1173				startT19();
1174				// send
1175				provider.send(t18t19encodedCGB);
1176				// notify user
1177				ISUPTimeoutEvent timeoutEvent = new ISUPTimeoutEvent(provider, t18t19CGB, ISUPTimeoutEvent.T19);
1178				provider.deliver(timeoutEvent);
1179			} catch (Exception e) {
1180				e.printStackTrace();
1181			} finally {
1182				lock.unlock();
1183			}
1184		}
1185
1186	}
1187
1188	private class TimerT20 implements Runnable {
1189
1190		/*
1191		 * (non-Javadoc)
1192		 * 
1193		 * @see java.lang.Runnable#run()
1194		 */
1195
1196		public void run() {
1197			try {
1198				lock.lock();
1199				// remove us
1200				t20 = null;
1201				// start T20
1202				startT20();
1203				// send
1204				provider.send(t20t21encodedCGU);
1205				// notify user
1206				ISUPTimeoutEvent timeoutEvent = new ISUPTimeoutEvent(provider, t20t21CGU, ISUPTimeoutEvent.T20);
1207				provider.deliver(timeoutEvent);
1208			} catch (Exception e) {
1209				e.printStackTrace();
1210			} finally {
1211				lock.unlock();
1212			}
1213		}
1214
1215	}
1216
1217	private class TimerT21 implements Runnable {
1218
1219		/*
1220		 * (non-Javadoc)
1221		 * 
1222		 * @see java.lang.Runnable#run()
1223		 */
1224
1225		public void run() {
1226			try {
1227				lock.lock();
1228				// remove t21, its current runnable.
1229				t21 = null;
1230				// cancel T20
1231				cancelT20();
1232				// restart T21
1233				startT21();
1234				// send
1235				provider.send(t20t21encodedCGU);
1236				// notify user
1237				ISUPTimeoutEvent timeoutEvent = new ISUPTimeoutEvent(provider, t20t21CGU, ISUPTimeoutEvent.T21);
1238				provider.deliver(timeoutEvent);
1239			} catch (Exception e) {
1240				e.printStackTrace();
1241			} finally {
1242				lock.unlock();
1243			}
1244		}
1245
1246	}
1247
1248	private class TimerT22 implements Runnable {
1249
1250		/*
1251		 * (non-Javadoc)
1252		 * 
1253		 * @see java.lang.Runnable#run()
1254		 */
1255
1256		public void run() {
1257			try {
1258				lock.lock();
1259
1260				// remove us
1261				t22 = null;
1262				// start T22
1263				startT22();
1264				// send
1265				provider.send(t22t23encodedGRS);
1266				// notify user
1267				ISUPTimeoutEvent timeoutEvent = new ISUPTimeoutEvent(provider, t22t23GRS, ISUPTimeoutEvent.T22);
1268				provider.deliver(timeoutEvent);
1269			} catch (Exception e) {
1270				e.printStackTrace();
1271			} finally {
1272				lock.unlock();
1273			}
1274		}
1275
1276	}
1277
1278	private class TimerT23 implements Runnable {
1279
1280		/*
1281		 * (non-Javadoc)
1282		 * 
1283		 * @see java.lang.Runnable#run()
1284		 */
1285
1286		public void run() {
1287			try {
1288
1289				lock.lock();
1290				// remove t23, its current runnable.
1291				t23 = null;
1292				// cancel T22
1293				cancelT22();
1294				// restart T23
1295				startT23();
1296				// send
1297				provider.send(t22t23encodedGRS);
1298				// notify user
1299				ISUPTimeoutEvent timeoutEvent = new ISUPTimeoutEvent(provider, t22t23GRS, ISUPTimeoutEvent.T23);
1300				provider.deliver(timeoutEvent);
1301			} catch (Exception e) {
1302				e.printStackTrace();
1303			} finally {
1304				lock.unlock();
1305			}
1306		}
1307
1308	}
1309
1310	private class TimerT28 implements Runnable {
1311
1312		/*
1313		 * (non-Javadoc)
1314		 * 
1315		 * @see java.lang.Runnable#run()
1316		 */
1317
1318		public void run() {
1319			try {
1320				lock.lock();
1321				// remove us
1322				t28 = null;
1323
1324				// notify user
1325				ISUPTimeoutEvent timeoutEvent = new ISUPTimeoutEvent(provider, t28CQM, ISUPTimeoutEvent.T28);
1326				provider.deliver(timeoutEvent);
1327				t28CQM = null;
1328			} catch (Exception e) {
1329				e.printStackTrace();
1330			} finally {
1331				lock.unlock();
1332			}
1333		}
1334
1335	}
1336
1337	private class TimerT33 implements Runnable {
1338
1339		/*
1340		 * (non-Javadoc)
1341		 * 
1342		 * @see java.lang.Runnable#run()
1343		 */
1344
1345		public void run() {
1346			try {
1347				lock.lock();
1348				// remove us
1349				t33 = null;
1350
1351				// notify user
1352				ISUPTimeoutEvent timeoutEvent = new ISUPTimeoutEvent(provider, t33INR, ISUPTimeoutEvent.T33);
1353				provider.deliver(timeoutEvent);
1354				// FIXME: do this after call, to prevent send of another msg
1355				t33INR = null;
1356
1357				// send REL
1358				ReleaseMessage rel = provider.getMessageFactory().createREL(cic);
1359
1360				try {
1361					CauseIndicators ci = provider.getParameterFactory().createCauseIndicators();
1362					// TODO: add CI values
1363					rel.setCauseIndicators(ci);
1364					provider.sendMessage(rel);
1365				} catch (ParameterException e) {
1366					// TODO Auto-generated catch block
1367					e.printStackTrace();
1368				} catch (IOException e) {
1369					// TODO Auto-generated catch block
1370					e.printStackTrace();
1371				}
1372			} catch (Exception e) {
1373				e.printStackTrace();
1374			} finally {
1375				lock.unlock();
1376			}
1377		}
1378
1379	}
1380
1381	/**
1382	 * 
1383	 */
1384	public void onStop() {
1385		try {
1386			lock.lock();
1387			cancelT1();
1388			cancelT5();
1389			cancelT12();
1390			cancelT13();
1391			cancelT14();
1392			cancelT15();
1393			cancelT16();
1394			cancelT17();
1395			cancelT18();
1396			cancelT19();
1397			cancelT20();
1398			cancelT21();
1399			cancelT22();
1400			cancelT23();
1401			cancelT28();
1402			cancelT33();
1403			
1404		} finally {
1405			lock.unlock();
1406		}
1407	}
1408
1409}