PageRenderTime 63ms CodeModel.GetById 14ms app.highlight 44ms RepoModel.GetById 1ms app.codeStats 0ms

/protocols/ss7/m3ua/impl/src/main/java/org/mobicents/protocols/ss7/m3ua/impl/sg/ServerM3UAProcess.java

http://mobicents.googlecode.com/
Java | 281 lines | 192 code | 52 blank | 37 comment | 33 complexity | 3964045972d4c90caf63936e086a56e6 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.sg;
 24
 25import java.io.IOException;
 26import java.net.InetAddress;
 27import java.net.InetSocketAddress;
 28import java.net.SocketAddress;
 29import java.nio.ByteBuffer;
 30import java.nio.channels.SelectionKey;
 31import java.util.Set;
 32
 33import javolution.util.FastList;
 34
 35import org.apache.log4j.Logger;
 36import org.mobicents.protocols.ss7.m3ua.M3UAChannel;
 37import org.mobicents.protocols.ss7.m3ua.M3UAProcess;
 38import org.mobicents.protocols.ss7.m3ua.M3UAProvider;
 39import org.mobicents.protocols.ss7.m3ua.M3UASelectionKey;
 40import org.mobicents.protocols.ss7.m3ua.M3UASelector;
 41import org.mobicents.protocols.ss7.m3ua.M3UAServerChannel;
 42import org.mobicents.protocols.ss7.m3ua.impl.As;
 43import org.mobicents.protocols.ss7.m3ua.impl.AsState;
 44import org.mobicents.protocols.ss7.m3ua.impl.AspFactory;
 45import org.mobicents.protocols.ss7.m3ua.impl.CommunicationListener.CommunicationState;
 46import org.mobicents.protocols.ss7.m3ua.impl.sctp.SctpChannel;
 47import org.mobicents.protocols.ss7.m3ua.message.M3UAMessage;
 48import org.mobicents.protocols.ss7.m3ua.message.MessageClass;
 49import org.mobicents.protocols.ss7.m3ua.message.MessageType;
 50import org.mobicents.protocols.ss7.m3ua.message.transfer.PayloadData;
 51import org.mobicents.protocols.ss7.m3ua.parameter.ProtocolData;
 52
 53/**
 54 * 
 55 * @author amit bhayani
 56 * 
 57 */
 58public class ServerM3UAProcess implements M3UAProcess {
 59
 60	private static Logger logger = Logger.getLogger(ServerM3UAProcess.class);
 61
 62	private String address;
 63	private int port;
 64
 65	private M3UAServerChannel serverChannel;
 66	private M3UASelector selector;
 67	private ServerM3UAManagement serverM3UAManagement;
 68
 69	private boolean started = false;
 70
 71	public ServerM3UAProcess(String address, int port) {
 72		this.address = address;
 73		this.port = port;
 74	}
 75
 76	public ServerM3UAManagement getServerM3UAManagement() {
 77		return serverM3UAManagement;
 78	}
 79
 80	public void setServerM3UAManagement(ServerM3UAManagement serverM3UAManagement) {
 81		this.serverM3UAManagement = serverM3UAManagement;
 82	}
 83
 84	public int read(ByteBuffer b) throws IOException {
 85		if (!started) {
 86			throw new IOException("Client M3UAProcess is stopped");
 87		}
 88
 89		int initialPosition = b.position();
 90		FastList<As> appServers = serverM3UAManagement.getAppServers();
 91		for (FastList.Node<As> n = appServers.head(), end = appServers.tail(); (n = n.getNext()) != end;) {
 92			As as = n.getValue();
 93			byte[] msu = as.poll();
 94			if (msu != null) {
 95				b.put(msu);
 96				break; // Remember read is only for one message
 97			}
 98		}
 99		return (b.position() - initialPosition);
100	}
101
102	public int write(ByteBuffer b) throws IOException {
103
104		if (!started) {
105			throw new IOException("Client M3UAProcess is stopped");
106		}
107
108		int write = 0;
109
110		if (b.hasRemaining()) {
111			byte[] msu = new byte[b.limit() - b.position()];
112			write = msu.length;
113			b.get(msu);
114			M3UAProvider m3uaProvider = this.serverM3UAManagement.getM3uaProvider();
115			ProtocolData data = m3uaProvider.getParameterFactory().createProtocolData(0, msu);
116			PayloadData payload = (PayloadData) m3uaProvider.getMessageFactory().createMessage(
117					MessageClass.TRANSFER_MESSAGES, MessageType.PAYLOAD);
118			payload.setData(data);
119
120			As as = this.serverM3UAManagement.m3uaRouter.getAs(data.getDpc(), data.getOpc(), (short) data.getSI());
121			if (as != null && (as.getState() == AsState.ACTIVE || as.getState() == AsState.PENDING)) {
122				payload.setRoutingContext(as.getRoutingContext());
123				as.write(payload);
124			} else {
125				logger.error(String.format("No AS found for this message. Dropping message %s", payload));
126			}
127
128		}
129
130		return write;
131	}
132
133	public void start() throws IOException {
134		selector = this.serverM3UAManagement.getM3uaProvider().openSelector();
135		serverChannel = this.serverM3UAManagement.getM3uaProvider().openServerChannel();
136		serverChannel.bind(new InetSocketAddress(address, port));
137		serverChannel.register(selector, SelectionKey.OP_ACCEPT);
138
139		this.started = true;
140
141		logger.info(String.format("Signalling Gateway Started. M3UA Bound to %s:%d", address, port));
142	}
143
144	public void stop() {
145		// TODO : Process to bring down all ASP and AS
146		started = false;
147		try {
148			selector.close();
149			serverChannel.close();
150		} catch (IOException e) {
151			// TODO Auto-generated catch block
152			e.printStackTrace();
153		}
154
155	}
156
157	public void execute() throws IOException {
158		if (!started) {
159			return;
160		}
161
162		this.serverM3UAManagement.getM3uaScheduler().tick();
163
164		FastList<M3UASelectionKey> selections = selector.selectNow();
165
166		for (FastList.Node<M3UASelectionKey> n = selections.head(), end = selections.tail(); (n = n.getNext()) != end;) {
167
168			M3UASelectionKey key = n.getValue();
169			
170//			if(!key.isValid()){
171//				//If Key is not valid, lets go to next one
172//				continue;
173//			}
174			if (key.isAcceptable()) {
175				accept((M3UAServerChannel) key.channel());
176			} else {
177
178				if (key.isReadable()) {
179					if (logger.isTraceEnabled()) {
180						logger.trace("Transmitting data from SigGateway to M3UA channel");
181					}
182					read(key);
183				}
184
185				if (key.isWritable()) {
186					write(key);
187				}
188			}
189		}
190	}
191
192	private void accept(M3UAServerChannel serverChannel) throws IOException {
193
194		boolean provisioned = false;
195		int port = 0;
196		InetAddress inetAddress = null;
197
198		M3UAChannel channel = serverChannel.accept();
199		Set<SocketAddress> socAddresses = ((SctpChannel) channel).getRemoteAddresses();
200
201		for (SocketAddress sockAdd : socAddresses) {
202
203			inetAddress = ((InetSocketAddress) sockAdd).getAddress();
204			port = ((InetSocketAddress) sockAdd).getPort();
205
206			FastList<AspFactory> aspfactories = this.serverM3UAManagement.getAspfactories();
207			// accept connection only from provisioned IP and Port.
208			for (FastList.Node<AspFactory> n = aspfactories.head(), end = aspfactories.tail(); (n = n.getNext()) != end
209					&& !provisioned;) {
210				AspFactory aspFactory = n.getValue();
211
212				// compare port and ip of remote with provisioned
213				if ((port == aspFactory.getPort()) && (inetAddress.getHostAddress().compareTo(aspFactory.getIp()) == 0)) {
214					M3UASelectionKey key = channel.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE);
215					key.attach(aspFactory);
216					provisioned = true;
217					((SctpChannel) channel).setNotificationHandler(aspFactory.getAssociationHandler());
218					logger.info("Connected with " + channel);
219
220					aspFactory.onCommStateChange(CommunicationState.UP);
221					break;
222				}
223			}
224		}
225
226		if (!provisioned) {
227			logger.warn(String.format("Received connect request from non provisioned %s:%d address. Closing Channel",
228					inetAddress.getHostAddress(), port));
229			channel.close();
230
231		}
232	}
233
234	private void read(M3UASelectionKey key) {
235		M3UAChannel channel = null;
236		try {
237			channel = (M3UAChannel) key.channel();
238			M3UAMessage message = channel.receive();
239			((AspFactory) key.attachment()).read(message);
240		} catch (IOException e) {
241			logger.error(
242					String.format("IOException while reading for Aspfactory name=%s ",
243							((AspFactory) key.attachment()).getName()), e);
244
245			try {
246				channel.close();
247			} catch (Exception ex) {
248				// Ignore
249			}
250
251			((AspFactory) key.attachment()).onCommStateChange(CommunicationState.LOST);
252
253		}
254	}
255
256	private void write(M3UASelectionKey key) {
257		M3UAChannel channel = null;
258		try {
259			channel = (M3UAChannel) key.channel();
260			AspFactory factory = ((AspFactory) key.attachment());
261			M3UAMessage message = null;
262			while ((message = factory.txPoll()) != null) {
263				channel.send(message);
264			}
265		} catch (IOException e) {
266			logger.error(
267					String.format("IOException while writting for Aspfactory name=%s ",
268							((AspFactory) key.attachment()).getName()), e);
269
270			try {
271				channel.close();
272			} catch (Exception ex) {
273				// Ignore
274			}
275
276			// TODO Transition to COMM_DOWN
277			((AspFactory) key.attachment()).onCommStateChange(CommunicationState.LOST);
278
279		}
280	}
281}