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