PageRenderTime 55ms CodeModel.GetById 14ms app.highlight 36ms RepoModel.GetById 1ms app.codeStats 0ms

/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
  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.message;
 24
 25import java.nio.ByteBuffer;
 26
 27import org.mobicents.protocols.ss7.m3ua.impl.message.aspsm.ASPDownAckImpl;
 28import org.mobicents.protocols.ss7.m3ua.impl.message.aspsm.ASPDownImpl;
 29import org.mobicents.protocols.ss7.m3ua.impl.message.aspsm.ASPUpAckImpl;
 30import org.mobicents.protocols.ss7.m3ua.impl.message.aspsm.ASPUpImpl;
 31import org.mobicents.protocols.ss7.m3ua.impl.message.aspsm.HeartbeatAckImpl;
 32import org.mobicents.protocols.ss7.m3ua.impl.message.aspsm.HeartbeatImpl;
 33import org.mobicents.protocols.ss7.m3ua.impl.message.asptm.ASPActiveAckImpl;
 34import org.mobicents.protocols.ss7.m3ua.impl.message.asptm.ASPActiveImpl;
 35import org.mobicents.protocols.ss7.m3ua.impl.message.asptm.ASPInactiveAckImpl;
 36import org.mobicents.protocols.ss7.m3ua.impl.message.asptm.ASPInactiveImpl;
 37import org.mobicents.protocols.ss7.m3ua.impl.message.mgmt.ErrorImpl;
 38import org.mobicents.protocols.ss7.m3ua.impl.message.mgmt.NotifyImpl;
 39import org.mobicents.protocols.ss7.m3ua.impl.message.rkm.DeregistrationRequestImpl;
 40import org.mobicents.protocols.ss7.m3ua.impl.message.rkm.DeregistrationResponseImpl;
 41import org.mobicents.protocols.ss7.m3ua.impl.message.rkm.RegistrationRequestImpl;
 42import org.mobicents.protocols.ss7.m3ua.impl.message.rkm.RegistrationResponseImpl;
 43import org.mobicents.protocols.ss7.m3ua.impl.message.ssnm.DestinationAvailableImpl;
 44import org.mobicents.protocols.ss7.m3ua.impl.message.ssnm.DestinationRestrictedImpl;
 45import org.mobicents.protocols.ss7.m3ua.impl.message.ssnm.DestinationStateAuditImpl;
 46import org.mobicents.protocols.ss7.m3ua.impl.message.ssnm.DestinationUPUnavailableImpl;
 47import org.mobicents.protocols.ss7.m3ua.impl.message.ssnm.DestinationUnavailableImpl;
 48import org.mobicents.protocols.ss7.m3ua.impl.message.ssnm.SignallingCongestionImpl;
 49import org.mobicents.protocols.ss7.m3ua.impl.message.transfer.PayloadDataImpl;
 50import org.mobicents.protocols.ss7.m3ua.message.MessageClass;
 51import org.mobicents.protocols.ss7.m3ua.message.MessageFactory;
 52import org.mobicents.protocols.ss7.m3ua.message.MessageType;
 53
 54/**
 55 * @author amit bhayani
 56 * @author kulikov
 57 */
 58public class MessageFactoryImpl implements MessageFactory {
 59	// header binary view
 60	private byte[] header = new byte[8];
 61	// variable length parameters
 62	private byte[] params;
 63	// current position either in header or in params
 64	private int pos = 0;
 65	// flag indicating that header is completely read
 66	private boolean isHeaderReady = false;
 67
 68	// the length of message's parameters
 69	private int length;
 70	// message instance
 71	private M3UAMessageImpl message;
 72
 73	public M3UAMessageImpl createMessage(int messageClass, int messageType) {
 74		switch (messageClass) {
 75		case MessageClass.TRANSFER_MESSAGES:
 76			switch (messageType) {
 77			case MessageType.PAYLOAD:
 78				return new PayloadDataImpl();
 79			}
 80			break;
 81		case MessageClass.SIGNALING_NETWORK_MANAGEMENT:
 82			switch (messageType) {
 83			case MessageType.DESTINATION_UNAVAILABLE:
 84				return new DestinationUnavailableImpl();
 85			case MessageType.DESTINATION_AVAILABLE:
 86				return new DestinationAvailableImpl();
 87			case MessageType.DESTINATION_STATE_AUDIT:
 88				return new DestinationStateAuditImpl();
 89			case MessageType.SIGNALING_CONGESTION:
 90				return new SignallingCongestionImpl();
 91			case MessageType.DESTINATION_USER_PART_UNAVAILABLE:
 92				return new DestinationUPUnavailableImpl();
 93			case MessageType.DESTINATION_RESTRICTED:
 94				return new DestinationRestrictedImpl();
 95			}
 96			break;
 97		case MessageClass.ASP_STATE_MAINTENANCE:
 98			switch (messageType) {
 99			case MessageType.ASP_UP:
100				return new ASPUpImpl();
101			case MessageType.ASP_UP_ACK:
102				return new ASPUpAckImpl();
103			case MessageType.ASP_DOWN:
104				return new ASPDownImpl();
105			case MessageType.ASP_DOWN_ACK:
106				return new ASPDownAckImpl();
107			case MessageType.HEARTBEAT:
108				return new HeartbeatImpl();
109			case MessageType.HEARTBEAT_ACK:
110				return new HeartbeatAckImpl();
111			}
112			break;
113		case MessageClass.ASP_TRAFFIC_MAINTENANCE:
114			switch (messageType) {
115			case MessageType.ASP_ACTIVE:
116				return new ASPActiveImpl();
117			case MessageType.ASP_ACTIVE_ACK:
118				return new ASPActiveAckImpl();
119			case MessageType.ASP_INACTIVE:
120				return new ASPInactiveImpl();
121			case MessageType.ASP_INACTIVE_ACK:
122				return new ASPInactiveAckImpl();
123
124			}
125			break;
126		case MessageClass.ROUTING_KEY_MANAGEMENT:
127			switch (messageType) {
128			case MessageType.REG_REQUEST:
129				return new RegistrationRequestImpl();
130			case MessageType.REG_RESPONSE:
131				return new RegistrationResponseImpl();
132			case MessageType.DEREG_REQUEST:
133				return new DeregistrationRequestImpl();
134			case MessageType.DEREG_RESPONSE:
135				return new DeregistrationResponseImpl();
136			}
137
138		case MessageClass.MANAGEMENT:
139			switch (messageType) {
140			case MessageType.ERROR:
141				return new ErrorImpl();
142			case MessageType.NOTIFY:
143				return new NotifyImpl();
144			}
145
146		}
147		return null;
148	}
149
150	public M3UAMessageImpl createMessage(ByteBuffer buffer) {
151		// fill header buffer completely before start parsing header
152		if (!isHeaderReady) {
153			// the amount of data possible to read is determined as
154			// minimal remainder either of header buffer or of the input buffer
155			int len = Math.min(header.length - pos, buffer.remaining());
156
157			System.out.println(String.format("len=%d, pos=%d, buffer.remaining=%d", len, pos, buffer.remaining()));
158			buffer.get(header, pos, len);
159
160			// update cursor postion in the header's buffer
161			pos += len;
162
163			// header completed?
164			isHeaderReady = pos == header.length;
165
166			if (!isHeaderReady) {
167				// no more data available
168				return null;
169			}
170
171			// obtain message class and type from header
172			int messageClass = header[2] & 0xff;
173			int messageType = header[3] & 0xff;
174
175			// construct new message instance
176			message = this.createMessage(messageClass, messageType);
177
178			// obtain remaining length of the message and prepare buffer
179			length = (((header[4] & 0xff) << 24) | ((header[5] & 0xff) << 16) | ((header[6] & 0xff) << 8) | (header[7] & 0xff)) - 8;
180
181			if (length == 0) {
182				// This is only header message,no body
183				this.pos = 0;
184				this.isHeaderReady = false;
185				return message;
186			}
187			params = new byte[length];
188
189			// finally switch cursor position
190			pos = 0;
191		}
192
193		// at this point we must recheck remainder of the input buffer
194		// because possible case when input buffer fits exactly to the header
195		if (!buffer.hasRemaining()) {
196			return null;
197		}
198
199		// again, reading all parameters before parsing
200
201		// compute available or required data
202		int len = Math.min(params.length, buffer.remaining());
203		buffer.get(params, pos, len);
204
205		// update cursor position
206		pos += len;
207
208		// end of message not reached
209		if (pos < params.length) {
210			return null;
211		}
212
213		// end of message reached and most probably some data remains in buffer
214		// do not touch remainder of the input buffer, next call to this method
215		// will proceed remainder
216
217		// parsing params of this message
218		message.decode(params);
219
220		// switch factory for receiving new message
221		this.isHeaderReady = false;
222		this.pos = 0;
223
224		// return
225		return message;
226	}
227
228	public M3UAMessageImpl createSctpMessage(byte[] buffer) {
229		int dataLen;
230		// fill header buffer completely before start parsing header
231		if (buffer.length < 8) {
232			return null;
233		}
234
235		// obtain message class and type from header
236		int messageClass = buffer[2] & 0xff;
237		int messageType = buffer[3] & 0xff;
238
239		// construct new message instance
240		M3UAMessageImpl messageTemp = this.createMessage(messageClass, messageType);
241
242		// obtain remaining length of the message and prepare buffer
243		dataLen = (((buffer[4] & 0xff) << 24) | ((buffer[5] & 0xff) << 16) | ((buffer[6] & 0xff) << 8) | (buffer[7] & 0xff)) - 8;
244
245		if (buffer.length >= (dataLen - 8)) {
246			// parsing params of this message
247			messageTemp.decode(buffer, 8);
248		}
249		return messageTemp;
250	}
251}