/protocols/ss7/m3ua/impl/src/main/java/org/mobicents/protocols/ss7/m3ua/impl/AspFactory.java
Java | 641 lines | 503 code | 99 blank | 39 comment | 95 complexity | bdd7df16129929c2dacc161c66d74b38 MD5 | raw file
Possible License(s): LGPL-3.0, GPL-3.0, LGPL-2.1, GPL-2.0, CC-BY-SA-3.0, CC0-1.0, Apache-2.0, BSD-3-Clause
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.m3ua.impl; 24 25import java.nio.ByteBuffer; 26 27import javolution.util.FastList; 28import javolution.xml.XMLFormat; 29import javolution.xml.XMLSerializable; 30import javolution.xml.stream.XMLStreamException; 31 32import org.apache.log4j.Logger; 33import org.mobicents.protocols.api.Association; 34import org.mobicents.protocols.api.AssociationListener; 35import org.mobicents.protocols.api.IpChannelType; 36import org.mobicents.protocols.api.Management; 37import org.mobicents.protocols.ss7.m3ua.ExchangeType; 38import org.mobicents.protocols.ss7.m3ua.Functionality; 39import org.mobicents.protocols.ss7.m3ua.IPSPType; 40import org.mobicents.protocols.ss7.m3ua.impl.fsm.FSM; 41import org.mobicents.protocols.ss7.m3ua.impl.fsm.UnknownTransitionException; 42import org.mobicents.protocols.ss7.m3ua.impl.message.M3UAMessageImpl; 43import org.mobicents.protocols.ss7.m3ua.impl.message.MessageFactoryImpl; 44import org.mobicents.protocols.ss7.m3ua.impl.oam.M3UAOAMMessages; 45import org.mobicents.protocols.ss7.m3ua.impl.parameter.ParameterFactoryImpl; 46import org.mobicents.protocols.ss7.m3ua.message.M3UAMessage; 47import org.mobicents.protocols.ss7.m3ua.message.MessageClass; 48import org.mobicents.protocols.ss7.m3ua.message.MessageFactory; 49import org.mobicents.protocols.ss7.m3ua.message.MessageType; 50import org.mobicents.protocols.ss7.m3ua.message.aspsm.ASPDown; 51import org.mobicents.protocols.ss7.m3ua.message.aspsm.ASPDownAck; 52import org.mobicents.protocols.ss7.m3ua.message.aspsm.ASPUp; 53import org.mobicents.protocols.ss7.m3ua.message.aspsm.ASPUpAck; 54import org.mobicents.protocols.ss7.m3ua.message.aspsm.Heartbeat; 55import org.mobicents.protocols.ss7.m3ua.message.asptm.ASPActive; 56import org.mobicents.protocols.ss7.m3ua.message.asptm.ASPActiveAck; 57import org.mobicents.protocols.ss7.m3ua.message.asptm.ASPInactive; 58import org.mobicents.protocols.ss7.m3ua.message.asptm.ASPInactiveAck; 59import org.mobicents.protocols.ss7.m3ua.message.mgmt.Notify; 60import org.mobicents.protocols.ss7.m3ua.message.ssnm.DestinationAvailable; 61import org.mobicents.protocols.ss7.m3ua.message.ssnm.DestinationRestricted; 62import org.mobicents.protocols.ss7.m3ua.message.ssnm.DestinationStateAudit; 63import org.mobicents.protocols.ss7.m3ua.message.ssnm.DestinationUPUnavailable; 64import org.mobicents.protocols.ss7.m3ua.message.ssnm.DestinationUnavailable; 65import org.mobicents.protocols.ss7.m3ua.message.ssnm.SignallingCongestion; 66import org.mobicents.protocols.ss7.m3ua.message.transfer.PayloadData; 67import org.mobicents.protocols.ss7.m3ua.parameter.ASPIdentifier; 68import org.mobicents.protocols.ss7.m3ua.parameter.ParameterFactory; 69 70/** 71 * 72 * @author amit bhayani 73 * 74 */ 75public class AspFactory implements AssociationListener, XMLSerializable { 76 77 private static final Logger logger = Logger.getLogger(AspFactory.class); 78 79 private static long ASP_ID = 1l; 80 81 private static final String NAME = "name"; 82 private static final String STARTED = "started"; 83 private static final String ASSOCIATION_NAME = "assocName"; 84 85 private volatile boolean channelConnected = false; 86 87 protected String name; 88 89 protected boolean started = false; 90 91 protected Association association = null; 92 protected String associationName = null; 93 94 protected FastList<Asp> aspList = new FastList<Asp>(); 95 96 private ByteBuffer txBuffer = ByteBuffer.allocateDirect(8192); 97 98 protected Management transportManagement = null; 99 100 private ASPIdentifier aspid; 101 102 protected ParameterFactory parameterFactory = new ParameterFactoryImpl(); 103 protected MessageFactory messageFactory = new MessageFactoryImpl(); 104 105 private TransferMessageHandler transferMessageHandler = new TransferMessageHandler(this); 106 private SignalingNetworkManagementHandler signalingNetworkManagementHandler = new SignalingNetworkManagementHandler( 107 this); 108 private ManagementMessageHandler managementMessageHandler = new ManagementMessageHandler(this); 109 private AspStateMaintenanceHandler aspStateMaintenanceHandler = new AspStateMaintenanceHandler(this); 110 private AspTrafficMaintenanceHandler aspTrafficMaintenanceHandler = new AspTrafficMaintenanceHandler(this); 111 private RoutingKeyManagementHandler routingKeyManagementHandler = new RoutingKeyManagementHandler(this); 112 113 protected Functionality functionality = null; 114 protected IPSPType ipspType = null; 115 protected ExchangeType exchangeType = null; 116 117 private long aspupSentTime = 0l; 118 119 public AspFactory() { 120 121 this.aspid = parameterFactory.createASPIdentifier(this.generateId()); 122 123 // clean transmission buffer 124 txBuffer.clear(); 125 txBuffer.rewind(); 126 txBuffer.flip(); 127 } 128 129 public AspFactory(String name) { 130 this(); 131 this.name = name; 132 } 133 134 public void start() throws Exception { 135 this.transportManagement.startAssociation(this.association.getName()); 136 this.started = true; 137 } 138 139 public void stop() throws Exception { 140 this.started = false; 141 142 if (this.functionality == Functionality.AS 143 || (this.functionality == Functionality.SGW && this.exchangeType == ExchangeType.DE) 144 || (this.functionality == Functionality.IPSP && this.exchangeType == ExchangeType.DE) 145 || (this.functionality == Functionality.IPSP && this.exchangeType == ExchangeType.SE && this.ipspType == IPSPType.CLIENT)) { 146 147 if (this.channelConnected) { 148 ASPDown aspDown = (ASPDown) this.messageFactory.createMessage(MessageClass.ASP_STATE_MAINTENANCE, 149 MessageType.ASP_DOWN); 150 this.write(aspDown); 151 for (FastList.Node<Asp> n = aspList.head(), end = aspList.tail(); (n = n.getNext()) != end;) { 152 Asp asp = n.getValue(); 153 154 try { 155 FSM aspLocalFSM = asp.getLocalFSM(); 156 aspLocalFSM.signal(TransitionState.ASP_DOWN_SENT); 157 158 As peerAs = asp.getAs(); 159 FSM asPeerFSM = peerAs.getPeerFSM(); 160 161 asPeerFSM.setAttribute(As.ATTRIBUTE_ASP, asp); 162 asPeerFSM.signal(TransitionState.ASP_DOWN); 163 164 } catch (UnknownTransitionException e) { 165 logger.error(e.getMessage(), e); 166 } 167 } 168 } else { 169 for (FastList.Node<Asp> n = aspList.head(), end = aspList.tail(); (n = n.getNext()) != end;) { 170 Asp asp = n.getValue(); 171 172 try { 173 FSM aspLocalFSM = asp.getLocalFSM(); 174 aspLocalFSM.signal(TransitionState.COMM_DOWN); 175 176 As peerAs = asp.getAs(); 177 FSM asPeerFSM = peerAs.getPeerFSM(); 178 asPeerFSM.setAttribute(As.ATTRIBUTE_ASP, asp); 179 asPeerFSM.signal(TransitionState.ASP_DOWN); 180 } catch (UnknownTransitionException e) { 181 logger.error(e.getMessage(), e); 182 } 183 } 184 } 185 186 } else { 187 if (this.channelConnected) { 188 throw new Exception("Still few ASP's are connected. Bring down the ASP's first"); 189 } 190 191 this.transportManagement.stopAssociation(this.association.getName()); 192 } 193 } 194 195 public boolean getStatus() { 196 return this.started; 197 } 198 199 public Functionality getFunctionality() { 200 return functionality; 201 } 202 203 public void setFunctionality(Functionality functionality) { 204 this.functionality = functionality; 205 } 206 207 public IPSPType getIpspType() { 208 return ipspType; 209 } 210 211 public void setIpspType(IPSPType ipspType) { 212 this.ipspType = ipspType; 213 } 214 215 public ExchangeType getExchangeType() { 216 return exchangeType; 217 } 218 219 public void setExchangeType(ExchangeType exchangeType) { 220 this.exchangeType = exchangeType; 221 } 222 223 public void setTransportManagement(Management transportManagement) { 224 this.transportManagement = transportManagement; 225 } 226 227 public void setAssociation(Association association) { 228 // Unset the listener to previous association 229 if (this.association != null) { 230 this.association.setAssociationListener(null); 231 } 232 this.association = association; 233 this.associationName = this.association.getName(); 234 // Set the listener for new association 235 this.association.setAssociationListener(this); 236 } 237 238 public void unsetAssociation() throws Exception { 239 if (this.association != null) { 240 if (this.association.isStarted()) { 241 throw new Exception(String.format("Association=%s is still started. Stop first", 242 this.association.getName())); 243 } 244 this.association.setAssociationListener(null); 245 this.association = null; 246 } 247 } 248 249 public String getName() { 250 return this.name; 251 } 252 253 public void read(M3UAMessage message) { 254 switch (message.getMessageClass()) { 255 case MessageClass.MANAGEMENT: 256 switch (message.getMessageType()) { 257 case MessageType.ERROR: 258 this.managementMessageHandler 259 .handleError((org.mobicents.protocols.ss7.m3ua.message.mgmt.Error) message); 260 break; 261 case MessageType.NOTIFY: 262 Notify notify = (Notify) message; 263 this.managementMessageHandler.handleNotify(notify); 264 break; 265 default: 266 logger.error(String.format("Rx : MGMT with invalid MessageType=%d message=%s", 267 message.getMessageType(), message)); 268 break; 269 } 270 break; 271 272 case MessageClass.TRANSFER_MESSAGES: 273 switch (message.getMessageType()) { 274 case MessageType.PAYLOAD: 275 PayloadData payload = (PayloadData) message; 276 this.transferMessageHandler.handlePayload(payload); 277 break; 278 default: 279 logger.error(String.format("Rx : Transfer message with invalid MessageType=%d message=%s", 280 message.getMessageType(), message)); 281 break; 282 } 283 break; 284 285 case MessageClass.SIGNALING_NETWORK_MANAGEMENT: 286 switch (message.getMessageType()) { 287 case MessageType.DESTINATION_UNAVAILABLE: 288 DestinationUnavailable duna = (DestinationUnavailable) message; 289 this.signalingNetworkManagementHandler.handleDestinationUnavailable(duna); 290 break; 291 case MessageType.DESTINATION_AVAILABLE: 292 DestinationAvailable dava = (DestinationAvailable) message; 293 this.signalingNetworkManagementHandler.handleDestinationAvailable(dava); 294 break; 295 case MessageType.DESTINATION_STATE_AUDIT: 296 DestinationStateAudit daud = (DestinationStateAudit) message; 297 this.signalingNetworkManagementHandler.handleDestinationStateAudit(daud); 298 break; 299 case MessageType.SIGNALING_CONGESTION: 300 SignallingCongestion scon = (SignallingCongestion) message; 301 this.signalingNetworkManagementHandler.handleSignallingCongestion(scon); 302 break; 303 case MessageType.DESTINATION_USER_PART_UNAVAILABLE: 304 DestinationUPUnavailable dupu = (DestinationUPUnavailable) message; 305 this.signalingNetworkManagementHandler.handleDestinationUPUnavailable(dupu); 306 break; 307 case MessageType.DESTINATION_RESTRICTED: 308 DestinationRestricted drst = (DestinationRestricted) message; 309 this.signalingNetworkManagementHandler.handleDestinationRestricted(drst); 310 break; 311 default: 312 logger.error(String.format("Received SSNM with invalid MessageType=%d message=%s", 313 message.getMessageType(), message)); 314 break; 315 } 316 break; 317 318 case MessageClass.ASP_STATE_MAINTENANCE: 319 switch (message.getMessageType()) { 320 case MessageType.ASP_UP: 321 ASPUp aspUp = (ASPUp) message; 322 this.aspStateMaintenanceHandler.handleAspUp(aspUp); 323 break; 324 case MessageType.ASP_UP_ACK: 325 ASPUpAck aspUpAck = (ASPUpAck) message; 326 this.aspStateMaintenanceHandler.handleAspUpAck(aspUpAck); 327 break; 328 case MessageType.ASP_DOWN: 329 ASPDown aspDown = (ASPDown) message; 330 this.aspStateMaintenanceHandler.handleAspDown(aspDown); 331 break; 332 case MessageType.ASP_DOWN_ACK: 333 ASPDownAck aspDownAck = (ASPDownAck) message; 334 this.aspStateMaintenanceHandler.handleAspDownAck(aspDownAck); 335 break; 336 case MessageType.HEARTBEAT: 337 Heartbeat hrtBeat = (Heartbeat) message; 338 this.aspStateMaintenanceHandler.handleHeartbeat(hrtBeat); 339 break; 340 default: 341 logger.error(String.format("Received ASPSM with invalid MessageType=%d message=%s", 342 message.getMessageType(), message)); 343 break; 344 } 345 346 break; 347 348 case MessageClass.ASP_TRAFFIC_MAINTENANCE: 349 switch (message.getMessageType()) { 350 case MessageType.ASP_ACTIVE: 351 ASPActive aspActive = (ASPActive) message; 352 this.aspTrafficMaintenanceHandler.handleAspActive(aspActive); 353 break; 354 case MessageType.ASP_ACTIVE_ACK: 355 ASPActiveAck aspAciveAck = (ASPActiveAck) message; 356 this.aspTrafficMaintenanceHandler.handleAspActiveAck(aspAciveAck); 357 break; 358 case MessageType.ASP_INACTIVE: 359 ASPInactive aspInactive = (ASPInactive) message; 360 this.aspTrafficMaintenanceHandler.handleAspInactive(aspInactive); 361 break; 362 case MessageType.ASP_INACTIVE_ACK: 363 ASPInactiveAck aspInaciveAck = (ASPInactiveAck) message; 364 this.aspTrafficMaintenanceHandler.handleAspInactiveAck(aspInaciveAck); 365 break; 366 default: 367 logger.error(String.format("Received ASPTM with invalid MessageType=%d message=%s", 368 message.getMessageType(), message)); 369 break; 370 } 371 break; 372 373 case MessageClass.ROUTING_KEY_MANAGEMENT: 374 break; 375 default: 376 logger.error(String.format("Received message with invalid MessageClass=%d message=%s", 377 message.getMessageClass(), message)); 378 break; 379 } 380 } 381 382 public void write(M3UAMessage message) { 383 384 synchronized (txBuffer) { 385 try { 386 txBuffer.clear(); 387 ((M3UAMessageImpl) message).encode(txBuffer); 388 txBuffer.flip(); 389 390 byte[] data = new byte[txBuffer.limit()]; 391 txBuffer.get(data); 392 393 org.mobicents.protocols.api.PayloadData payloadData = null; 394 395 switch (message.getMessageClass()) { 396 case MessageClass.ASP_STATE_MAINTENANCE: 397 case MessageClass.MANAGEMENT: 398 case MessageClass.ROUTING_KEY_MANAGEMENT: 399 payloadData = new org.mobicents.protocols.api.PayloadData(data.length, data, true, true, 3, 0); 400 break; 401 case MessageClass.TRANSFER_MESSAGES: 402 PayloadData payload = (PayloadData) message; 403 payloadData = new org.mobicents.protocols.api.PayloadData(data.length, data, true, false, 3, 404 payload.getData().getSLS()); 405 break; 406 default: 407 payloadData = new org.mobicents.protocols.api.PayloadData(data.length, data, true, true, 3, 0); 408 break; 409 } 410 411 this.association.send(payloadData); 412 } catch (Exception e) { 413 e.printStackTrace(); 414 } 415 } 416 } 417 418 protected Asp createAsp() { 419 Asp remAsp = new Asp(this.name, this); 420 421 // We set ASP IP only if its AS or IPSP Client side 422 if (this.getFunctionality() == Functionality.AS 423 || (this.getFunctionality() == Functionality.IPSP && this.getIpspType() == IPSPType.CLIENT)) { 424 remAsp.setASPIdentifier(aspid); 425 } 426 427 this.aspList.add(remAsp); 428 return remAsp; 429 } 430 431 public boolean destroyAsp(Asp asp) { 432 asp.aspFactory = null; 433 return this.aspList.remove(asp); 434 } 435 436 public FastList<Asp> getAspList() { 437 return this.aspList; 438 } 439 440 protected Asp getAsp(long rc) { 441 for (FastList.Node<Asp> n = aspList.head(), end = aspList.tail(); (n = n.getNext()) != end;) { 442 Asp asp = n.getValue(); 443 if (asp.getAs().getRoutingContext().getRoutingContexts()[0] == rc) { 444 return asp; 445 } 446 } 447 return null; 448 } 449 450 protected void sendAspActive(As as) { 451 ASPActive aspActive = (ASPActive) this.messageFactory.createMessage(MessageClass.ASP_TRAFFIC_MAINTENANCE, 452 MessageType.ASP_ACTIVE); 453 aspActive.setRoutingContext(as.getRoutingContext()); 454 aspActive.setTrafficModeType(as.getTrafficModeType()); 455 this.write(aspActive); 456 } 457 458 private long generateId() { 459 ASP_ID++; 460 if (ASP_ID == 4294967295l) { 461 ASP_ID = 1l; 462 } 463 return ASP_ID; 464 } 465 466 private void handleCommDown() { 467 468 this.channelConnected = false; 469 for (FastList.Node<Asp> n = aspList.head(), end = aspList.tail(); (n = n.getNext()) != end;) { 470 Asp asp = n.getValue(); 471 try { 472 FSM aspLocalFSM = asp.getLocalFSM(); 473 if (aspLocalFSM != null) { 474 aspLocalFSM.signal(TransitionState.COMM_DOWN); 475 } 476 477 FSM aspPeerFSM = asp.getPeerFSM(); 478 if (aspPeerFSM != null) { 479 aspPeerFSM.signal(TransitionState.COMM_DOWN); 480 } 481 482 As as = asp.getAs(); 483 484 FSM asLocalFSM = as.getLocalFSM(); 485 if (asLocalFSM != null) { 486 asLocalFSM.setAttribute(As.ATTRIBUTE_ASP, asp); 487 asLocalFSM.signal(TransitionState.ASP_DOWN); 488 } 489 490 FSM asPeerFSM = as.getPeerFSM(); 491 if (asPeerFSM != null) { 492 asPeerFSM.setAttribute(As.ATTRIBUTE_ASP, asp); 493 asPeerFSM.signal(TransitionState.ASP_DOWN); 494 } 495 } catch (UnknownTransitionException e) { 496 logger.error(e.getMessage(), e); 497 } 498 } 499 } 500 501 protected void sendAspUp() { 502 // TODO : Possibility of race condition? 503 long now = System.currentTimeMillis(); 504 if ((now - aspupSentTime) > 2000) { 505 ASPUp aspUp = (ASPUp) this.messageFactory.createMessage(MessageClass.ASP_STATE_MAINTENANCE, 506 MessageType.ASP_UP); 507 aspUp.setASPIdentifier(this.aspid); 508 this.write(aspUp); 509 aspupSentTime = now; 510 } 511 } 512 513 private void handleCommUp() { 514 this.channelConnected = true; 515 if (this.functionality == Functionality.AS 516 || (this.functionality == Functionality.SGW && this.exchangeType == ExchangeType.DE) 517 || (this.functionality == Functionality.IPSP && this.exchangeType == ExchangeType.DE) 518 || (this.functionality == Functionality.IPSP && this.exchangeType == ExchangeType.SE && this.ipspType == IPSPType.CLIENT)) { 519 this.aspupSentTime = 0l; 520 this.sendAspUp(); 521 } 522 523 for (FastList.Node<Asp> n = aspList.head(), end = aspList.tail(); (n = n.getNext()) != end;) { 524 Asp asp = n.getValue(); 525 try { 526 FSM aspLocalFSM = asp.getLocalFSM(); 527 if (aspLocalFSM != null) { 528 aspLocalFSM.signal(TransitionState.COMM_UP); 529 } 530 531 FSM aspPeerFSM = asp.getPeerFSM(); 532 if (aspPeerFSM != null) { 533 aspPeerFSM.signal(TransitionState.COMM_UP); 534 } 535 536 } catch (UnknownTransitionException e) { 537 logger.error(e.getMessage(), e); 538 } 539 } 540 } 541 542 /** 543 * XML Serialization/Deserialization 544 */ 545 protected static final XMLFormat<AspFactory> ASP_FACTORY_XML = new XMLFormat<AspFactory>(AspFactory.class) { 546 547 @Override 548 public void read(javolution.xml.XMLFormat.InputElement xml, AspFactory aspFactory) throws XMLStreamException { 549 aspFactory.name = xml.getAttribute(NAME, ""); 550 aspFactory.associationName = xml.getAttribute(ASSOCIATION_NAME, ""); 551 aspFactory.started = xml.getAttribute(STARTED).toBoolean(); 552 } 553 554 @Override 555 public void write(AspFactory aspFactory, javolution.xml.XMLFormat.OutputElement xml) throws XMLStreamException { 556 xml.setAttribute(NAME, aspFactory.name); 557 xml.setAttribute(ASSOCIATION_NAME, aspFactory.associationName); 558 xml.setAttribute(STARTED, aspFactory.started); 559 } 560 }; 561 562 /** 563 * AssociationListener methods 564 */ 565 566 @Override 567 public void onCommunicationLost(Association association) { 568 logger.warn(String.format("Communication channel lost for AspFactroy=%s Association=%s", this.name, 569 association.getName())); 570 this.handleCommDown(); 571 } 572 573 @Override 574 public void onCommunicationRestart(Association association) { 575 // TODO Auto-generated method stub 576 577 } 578 579 @Override 580 public void onCommunicationShutdown(Association association) { 581 logger.warn(String.format("Communication channel shutdown for AspFactroy=%s Association=%s", this.name, 582 association.getName())); 583 this.handleCommDown(); 584 585 } 586 587 @Override 588 public void onCommunicationUp(Association association) { 589 this.handleCommUp(); 590 } 591 592 @Override 593 public void onPayload(Association association, org.mobicents.protocols.api.PayloadData payloadData) { 594 595 byte[] m3uadata = payloadData.getData(); 596 M3UAMessage m3UAMessage; 597 if (association.getIpChannelType() == IpChannelType.SCTP) { 598 // TODO where is streamNumber stored? 599 m3UAMessage = this.messageFactory.createSctpMessage(m3uadata); 600 this.read(m3UAMessage); 601 } else { 602 ByteBuffer buffer = ByteBuffer.wrap(m3uadata); 603 while (true) { 604 m3UAMessage = this.messageFactory.createMessage(buffer); 605 if (m3UAMessage == null) 606 break; 607 this.read(m3UAMessage); 608 } 609 } 610 } 611 612 public void show(StringBuffer sb) { 613 sb.append(M3UAOAMMessages.SHOW_ASP_NAME).append(this.name).append(M3UAOAMMessages.SHOW_SCTP_ASSOC) 614 .append(this.associationName).append(M3UAOAMMessages.SHOW_STARTED).append(this.started); 615 616 sb.append(M3UAOAMMessages.NEW_LINE); 617 sb.append(M3UAOAMMessages.SHOW_ASSIGNED_TO); 618 619 for (FastList.Node<Asp> n = aspList.head(), end = aspList.tail(); (n = n.getNext()) != end;) { 620 Asp asp = n.getValue(); 621 sb.append(M3UAOAMMessages.TAB).append(M3UAOAMMessages.SHOW_AS_NAME).append(asp.getAs().getName()) 622 .append(M3UAOAMMessages.SHOW_FUNCTIONALITY).append(this.functionality) 623 .append(M3UAOAMMessages.SHOW_MODE).append(this.exchangeType); 624 625 if (this.functionality == Functionality.IPSP) { 626 sb.append(M3UAOAMMessages.SHOW_IPSP_TYPE).append(this.ipspType); 627 } 628 629 if (asp.getLocalFSM() != null) { 630 sb.append(M3UAOAMMessages.SHOW_LOCAL_FSM_STATE).append(asp.getLocalFSM().getState()); 631 } 632 633 if (asp.getPeerFSM() != null) { 634 sb.append(M3UAOAMMessages.SHOW_PEER_FSM_STATE).append(asp.getPeerFSM().getState()); 635 } 636 637 sb.append(M3UAOAMMessages.NEW_LINE); 638 } 639 } 640} 641