/protocols/ss7/m3ua/impl/src/main/java/org/mobicents/protocols/ss7/m3ua/impl/message/MessageFactoryImpl.java
http://mobicents.googlecode.com/ · Java · 251 lines · 159 code · 33 blank · 59 comment · 16 complexity · c822cf2243ec4a4d4cc0aedc108a8b2c MD5 · raw file
- /*
- * JBoss, Home of Professional Open Source
- * Copyright 2011, Red Hat, Inc. 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.m3ua.impl.message;
- import java.nio.ByteBuffer;
- import org.mobicents.protocols.ss7.m3ua.impl.message.aspsm.ASPDownAckImpl;
- import org.mobicents.protocols.ss7.m3ua.impl.message.aspsm.ASPDownImpl;
- import org.mobicents.protocols.ss7.m3ua.impl.message.aspsm.ASPUpAckImpl;
- import org.mobicents.protocols.ss7.m3ua.impl.message.aspsm.ASPUpImpl;
- import org.mobicents.protocols.ss7.m3ua.impl.message.aspsm.HeartbeatAckImpl;
- import org.mobicents.protocols.ss7.m3ua.impl.message.aspsm.HeartbeatImpl;
- import org.mobicents.protocols.ss7.m3ua.impl.message.asptm.ASPActiveAckImpl;
- import org.mobicents.protocols.ss7.m3ua.impl.message.asptm.ASPActiveImpl;
- import org.mobicents.protocols.ss7.m3ua.impl.message.asptm.ASPInactiveAckImpl;
- import org.mobicents.protocols.ss7.m3ua.impl.message.asptm.ASPInactiveImpl;
- import org.mobicents.protocols.ss7.m3ua.impl.message.mgmt.ErrorImpl;
- import org.mobicents.protocols.ss7.m3ua.impl.message.mgmt.NotifyImpl;
- import org.mobicents.protocols.ss7.m3ua.impl.message.rkm.DeregistrationRequestImpl;
- import org.mobicents.protocols.ss7.m3ua.impl.message.rkm.DeregistrationResponseImpl;
- import org.mobicents.protocols.ss7.m3ua.impl.message.rkm.RegistrationRequestImpl;
- import org.mobicents.protocols.ss7.m3ua.impl.message.rkm.RegistrationResponseImpl;
- import org.mobicents.protocols.ss7.m3ua.impl.message.ssnm.DestinationAvailableImpl;
- import org.mobicents.protocols.ss7.m3ua.impl.message.ssnm.DestinationRestrictedImpl;
- import org.mobicents.protocols.ss7.m3ua.impl.message.ssnm.DestinationStateAuditImpl;
- import org.mobicents.protocols.ss7.m3ua.impl.message.ssnm.DestinationUPUnavailableImpl;
- import org.mobicents.protocols.ss7.m3ua.impl.message.ssnm.DestinationUnavailableImpl;
- import org.mobicents.protocols.ss7.m3ua.impl.message.ssnm.SignallingCongestionImpl;
- import org.mobicents.protocols.ss7.m3ua.impl.message.transfer.PayloadDataImpl;
- import org.mobicents.protocols.ss7.m3ua.message.MessageClass;
- import org.mobicents.protocols.ss7.m3ua.message.MessageFactory;
- import org.mobicents.protocols.ss7.m3ua.message.MessageType;
- /**
- * @author amit bhayani
- * @author kulikov
- */
- public class MessageFactoryImpl implements MessageFactory {
- // header binary view
- private byte[] header = new byte[8];
- // variable length parameters
- private byte[] params;
- // current position either in header or in params
- private int pos = 0;
- // flag indicating that header is completely read
- private boolean isHeaderReady = false;
- // the length of message's parameters
- private int length;
- // message instance
- private M3UAMessageImpl message;
- public M3UAMessageImpl createMessage(int messageClass, int messageType) {
- switch (messageClass) {
- case MessageClass.TRANSFER_MESSAGES:
- switch (messageType) {
- case MessageType.PAYLOAD:
- return new PayloadDataImpl();
- }
- break;
- case MessageClass.SIGNALING_NETWORK_MANAGEMENT:
- switch (messageType) {
- case MessageType.DESTINATION_UNAVAILABLE:
- return new DestinationUnavailableImpl();
- case MessageType.DESTINATION_AVAILABLE:
- return new DestinationAvailableImpl();
- case MessageType.DESTINATION_STATE_AUDIT:
- return new DestinationStateAuditImpl();
- case MessageType.SIGNALING_CONGESTION:
- return new SignallingCongestionImpl();
- case MessageType.DESTINATION_USER_PART_UNAVAILABLE:
- return new DestinationUPUnavailableImpl();
- case MessageType.DESTINATION_RESTRICTED:
- return new DestinationRestrictedImpl();
- }
- break;
- case MessageClass.ASP_STATE_MAINTENANCE:
- switch (messageType) {
- case MessageType.ASP_UP:
- return new ASPUpImpl();
- case MessageType.ASP_UP_ACK:
- return new ASPUpAckImpl();
- case MessageType.ASP_DOWN:
- return new ASPDownImpl();
- case MessageType.ASP_DOWN_ACK:
- return new ASPDownAckImpl();
- case MessageType.HEARTBEAT:
- return new HeartbeatImpl();
- case MessageType.HEARTBEAT_ACK:
- return new HeartbeatAckImpl();
- }
- break;
- case MessageClass.ASP_TRAFFIC_MAINTENANCE:
- switch (messageType) {
- case MessageType.ASP_ACTIVE:
- return new ASPActiveImpl();
- case MessageType.ASP_ACTIVE_ACK:
- return new ASPActiveAckImpl();
- case MessageType.ASP_INACTIVE:
- return new ASPInactiveImpl();
- case MessageType.ASP_INACTIVE_ACK:
- return new ASPInactiveAckImpl();
- }
- break;
- case MessageClass.ROUTING_KEY_MANAGEMENT:
- switch (messageType) {
- case MessageType.REG_REQUEST:
- return new RegistrationRequestImpl();
- case MessageType.REG_RESPONSE:
- return new RegistrationResponseImpl();
- case MessageType.DEREG_REQUEST:
- return new DeregistrationRequestImpl();
- case MessageType.DEREG_RESPONSE:
- return new DeregistrationResponseImpl();
- }
- case MessageClass.MANAGEMENT:
- switch (messageType) {
- case MessageType.ERROR:
- return new ErrorImpl();
- case MessageType.NOTIFY:
- return new NotifyImpl();
- }
- }
- return null;
- }
- public M3UAMessageImpl createMessage(ByteBuffer buffer) {
- // fill header buffer completely before start parsing header
- if (!isHeaderReady) {
- // the amount of data possible to read is determined as
- // minimal remainder either of header buffer or of the input buffer
- int len = Math.min(header.length - pos, buffer.remaining());
- System.out.println(String.format("len=%d, pos=%d, buffer.remaining=%d", len, pos, buffer.remaining()));
- buffer.get(header, pos, len);
- // update cursor postion in the header's buffer
- pos += len;
- // header completed?
- isHeaderReady = pos == header.length;
- if (!isHeaderReady) {
- // no more data available
- return null;
- }
- // obtain message class and type from header
- int messageClass = header[2] & 0xff;
- int messageType = header[3] & 0xff;
- // construct new message instance
- message = this.createMessage(messageClass, messageType);
- // obtain remaining length of the message and prepare buffer
- length = (((header[4] & 0xff) << 24) | ((header[5] & 0xff) << 16) | ((header[6] & 0xff) << 8) | (header[7] & 0xff)) - 8;
- if (length == 0) {
- // This is only header message,no body
- this.pos = 0;
- this.isHeaderReady = false;
- return message;
- }
- params = new byte[length];
- // finally switch cursor position
- pos = 0;
- }
- // at this point we must recheck remainder of the input buffer
- // because possible case when input buffer fits exactly to the header
- if (!buffer.hasRemaining()) {
- return null;
- }
- // again, reading all parameters before parsing
- // compute available or required data
- int len = Math.min(params.length, buffer.remaining());
- buffer.get(params, pos, len);
- // update cursor position
- pos += len;
- // end of message not reached
- if (pos < params.length) {
- return null;
- }
- // end of message reached and most probably some data remains in buffer
- // do not touch remainder of the input buffer, next call to this method
- // will proceed remainder
- // parsing params of this message
- message.decode(params);
- // switch factory for receiving new message
- this.isHeaderReady = false;
- this.pos = 0;
- // return
- return message;
- }
- public M3UAMessageImpl createSctpMessage(byte[] buffer) {
- int dataLen;
- // fill header buffer completely before start parsing header
- if (buffer.length < 8) {
- return null;
- }
- // obtain message class and type from header
- int messageClass = buffer[2] & 0xff;
- int messageType = buffer[3] & 0xff;
- // construct new message instance
- M3UAMessageImpl messageTemp = this.createMessage(messageClass, messageType);
- // obtain remaining length of the message and prepare buffer
- dataLen = (((buffer[4] & 0xff) << 24) | ((buffer[5] & 0xff) << 16) | ((buffer[6] & 0xff) << 8) | (buffer[7] & 0xff)) - 8;
- if (buffer.length >= (dataLen - 8)) {
- // parsing params of this message
- messageTemp.decode(buffer, 8);
- }
- return messageTemp;
- }
- }