/protocols/ss7/m3ua/impl/src/main/java/org/mobicents/protocols/ss7/m3ua/impl/sg/ServerM3UAProcess.java
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}