PageRenderTime 146ms CodeModel.GetById 104ms app.highlight 36ms RepoModel.GetById 1ms app.codeStats 0ms

/protocols/ss7/hardware/dialogic/java/src/main/java/org/mobicents/ss7/hardware/dialogic/DialogicMtp3UserPart.java

http://mobicents.googlecode.com/
Java | 235 lines | 143 code | 44 blank | 48 comment | 17 complexity | a67f6065967735deb87fe3164891d901 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.ss7.hardware.dialogic;
 24
 25import java.io.ByteArrayInputStream;
 26import java.io.DataInputStream;
 27import java.io.IOException;
 28import java.util.concurrent.ExecutorService;
 29import java.util.concurrent.Executors;
 30
 31import org.apache.log4j.Logger;
 32import org.mobicents.protocols.ss7.mtp.Mtp3PausePrimitive;
 33import org.mobicents.protocols.ss7.mtp.Mtp3ResumePrimitive;
 34import org.mobicents.protocols.ss7.mtp.Mtp3StatusCause;
 35import org.mobicents.protocols.ss7.mtp.Mtp3StatusPrimitive;
 36import org.mobicents.protocols.ss7.mtp.Mtp3TransferPrimitive;
 37import org.mobicents.protocols.ss7.mtp.Mtp3UserPartBaseImpl;
 38
 39/**
 40 * @author amit bhayani
 41 * @author sergey vetyutnev
 42 * 
 43 */
 44public class DialogicMtp3UserPart extends Mtp3UserPartBaseImpl {
 45
 46	private static final Logger logger = Logger.getLogger(DialogicMtp3UserPart.class);
 47
 48	private static final int MTP3_PAUSE = 3;
 49	private static final int MTP3_RESUME = 4;
 50	private static final int MTP3_STATUS = 5;
 51
 52	private int sourceModuleId;
 53	private int destinationModuleId;
 54
 55	private InterProcessCommunicator ipc = null;
 56	private MtpStreamHandler streamHandler;
 57
 58	protected ExecutorService layer3exec;
 59
 60	
 61	public DialogicMtp3UserPart() {
 62	}
 63
 64
 65	public int getSourceModuleId() {
 66		return sourceModuleId;
 67	}
 68
 69	public void setSourceModuleId(int sourceModuleId) {
 70		this.sourceModuleId = sourceModuleId;
 71	}
 72
 73	public int getDestinationModuleId() {
 74		return destinationModuleId;
 75	}
 76
 77	public void setDestinationModuleId(int destinationModuleId) {
 78		this.destinationModuleId = destinationModuleId;
 79	}
 80
 81	@Override
 82	public void start() throws Exception {
 83		
 84		ipc = new InterProcessCommunicator(sourceModuleId, destinationModuleId);
 85		
 86		layer3exec = Executors.newFixedThreadPool(1);
 87		this.streamHandler = new MtpStreamHandler();
 88		layer3exec.execute(this.streamHandler);
 89		
 90		super.start();
 91	}	
 92
 93	@Override
 94	public void stop() throws Exception {
 95
 96		super.stop();
 97		
 98		this.streamHandler.stop();
 99		layer3exec.shutdown();
100	}	
101
102	@Override
103	public void sendMessage(Mtp3TransferPrimitive msg) throws IOException {
104		
105		if (this.isStarted) {
106			byte[] buf = msg.encodeMtp3();
107			this.ipc.write(buf);
108		}
109	}
110
111	private class MtpStreamHandler implements Runnable {
112
113		private boolean handlerIsStarted = true;
114		
115		public void run() {
116
117			// Execute only till state is Running
118			while (this.handlerIsStarted) {
119				try {
120					byte[] buf = ipc.read();
121					
122					if (!this.handlerIsStarted)
123						return;
124					
125					if (buf == null) {
126
127						// TODO: test if this event is regular we should remove the following warning
128						logger.warn("No data received while reading data from the Dialogic card");
129						
130						// return from GCT_receive() with no message - may be the error case: 
131						// make the delay to escape processor overloading
132						Thread.sleep(10);
133					} else {
134
135						if (buf.length >= 6) {
136							if (buf[0] == 0) {
137								this.parseMtp3Msg(buf);
138							} else {
139								Mtp3TransferPrimitive msg = new Mtp3TransferPrimitive();
140								msg.decodeMtp3(buf);
141								sendTransferMessageToLocalUser(msg, msg.getSls());
142							}
143						} else {
144							logger.error("Error while reading data from the Dialogic card: received the message with length less then 6 bytes");
145						}
146					}
147				} catch (Exception e) {
148					logger.error("Error while reading data from the Dialogic card", e);
149				}
150			}
151		}
152		
153		public void stop() {
154			this.handlerIsStarted = false;
155		}
156
157		/**
158		 * 
159		 * Parsing and delivering MTP-PAUSE, MTP-RESUME, MTP-STATUS primitives
160		 * 
161		 * The structure of <i>PAUSE</i> is SI=0 (byte), type=3 (byte), affected
162		 * dpc = int(4 bytes)</li> <li>
163		 * The structure of <i>RESUME</i> is SI=0 (byte), type=4 (byte),
164		 * affected dpc = int(4 bytes)</li> <li>
165		 * The structure of <i>STATUS</i> is SI=0 (byte), type=5 (byte),
166		 * status=1 or 2 (byte) where 1 = Remote User Unavailable and 2 =
167		 * Signaling Network Congestion, affected dpc = int(4 bytes), congestion
168		 * status = 2 bytes in range of 0 to 3 where 0 means no congestion and 3
169		 * means maximum congestion, Unavailabilty cause = 2 bytes (if status =
170		 * Remote User Unavailable(1)). The unavailabilty cause may be one of
171		 * the following: 0 = Unknown 1 = Unequipped User 2 = Inaccessible User
172		 * 
173		 * @param buf
174		 */
175		private void parseMtp3Msg(byte[] buf) {
176			
177			try {
178				DataInputStream in = new DataInputStream(new ByteArrayInputStream(buf));
179				in.readUnsignedByte(); // sio zero byte
180
181				int type = in.readUnsignedByte(); //
182				switch (type) {
183				case MTP3_PAUSE:
184					Mtp3PausePrimitive msgPause = new Mtp3PausePrimitive(in.readInt());
185					sendPauseMessageToLocalUser(msgPause);
186					break;
187
188				case MTP3_RESUME:
189					Mtp3ResumePrimitive msgResume = new Mtp3ResumePrimitive(in.readInt());
190					sendResumeMessageToLocalUser(msgResume);
191					break;
192
193				case MTP3_STATUS:
194					if (buf.length < 9) {
195						logger.error("Error while parsing data from the Dialogic card: unsufficient data length for message MTP3_STATUS");
196						return;
197					}
198
199					int status = in.readUnsignedByte();
200					int affectedDpc = in.readInt();
201					int congestionLevel = in.readShort();
202					int unavailabiltyCause = in.readShort();
203					Mtp3StatusCause cause;
204					if (status == 1) { // 1 = Remote User Unavailable
205						switch (unavailabiltyCause) {
206						case 1:
207							cause = Mtp3StatusCause.UserPartUnavailability_UnequippedRemoteUser;
208							break;
209						case 2:
210							cause = Mtp3StatusCause.UserPartUnavailability_InaccessibleRemoteUser;
211							break;
212						default:
213							cause = Mtp3StatusCause.UserPartUnavailability_Unknown;
214							break;
215						}
216						congestionLevel = 0;
217					} else { // 2 = Signaling Network Congestion
218						cause = Mtp3StatusCause.SignallingNetworkCongested;
219						congestionLevel = 0;
220					}
221					Mtp3StatusPrimitive msgStatus = new Mtp3StatusPrimitive(affectedDpc, cause, congestionLevel);
222					sendStatusMessageToLocalUser(msgStatus);
223					break;
224
225				default:
226					logger.error("Error while parsing system messages from the Dialogic card: unknown primitive type: " + type);
227				}
228				
229			} catch (IOException e) {
230				logger.error("IOException while parsing system messages from the Dialogic card: " + e.getMessage(), e);
231			}
232		}
233	}
234}
235