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