/protocols/jain-mgcp/stack/src/main/java/org/mobicents/protocols/mgcp/stack/CreateConnectionHandler.java

http://mobicents.googlecode.com/ · Java · 346 lines · 198 code · 53 blank · 95 comment · 55 complexity · 52333118888c5a85b01c4a9dc514972d 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. /*
  23. * File Name : CreateConnectionHandle.java
  24. *
  25. * The JAIN MGCP API implementaion.
  26. *
  27. * The source code contained in this file is in in the public domain.
  28. * It can be used in any project or product without prior permission,
  29. * license or royalty payments. There is NO WARRANTY OF ANY KIND,
  30. * EXPRESS, IMPLIED OR STATUTORY, INCLUDING, WITHOUT LIMITATION,
  31. * THE IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
  32. * AND DATA ACCURACY. We do not warrant or make any representations
  33. * regarding the use of the software or the results thereof, including
  34. * but not limited to the correctness, accuracy, reliability or
  35. * usefulness of the software.
  36. */
  37. package org.mobicents.protocols.mgcp.stack;
  38. import jain.protocol.ip.mgcp.JainMgcpCommandEvent;
  39. import jain.protocol.ip.mgcp.JainMgcpResponseEvent;
  40. import jain.protocol.ip.mgcp.message.CreateConnection;
  41. import jain.protocol.ip.mgcp.message.CreateConnectionResponse;
  42. import jain.protocol.ip.mgcp.message.parms.CallIdentifier;
  43. import jain.protocol.ip.mgcp.message.parms.ConflictingParameterException;
  44. import jain.protocol.ip.mgcp.message.parms.ConnectionDescriptor;
  45. import jain.protocol.ip.mgcp.message.parms.ConnectionIdentifier;
  46. import jain.protocol.ip.mgcp.message.parms.ConnectionMode;
  47. import jain.protocol.ip.mgcp.message.parms.DigitMap;
  48. import jain.protocol.ip.mgcp.message.parms.NotificationRequestParms;
  49. import jain.protocol.ip.mgcp.message.parms.NotifiedEntity;
  50. import jain.protocol.ip.mgcp.message.parms.RequestIdentifier;
  51. import jain.protocol.ip.mgcp.message.parms.ReturnCode;
  52. import java.io.IOException;
  53. import java.net.InetAddress;
  54. import java.text.ParseException;
  55. import org.apache.log4j.Logger;
  56. import org.mobicents.protocols.mgcp.parser.MgcpContentHandler;
  57. import org.mobicents.protocols.mgcp.parser.MgcpMessageParser;
  58. import org.mobicents.protocols.mgcp.parser.Utils;
  59. /**
  60. *
  61. * @author Oleg Kulikov
  62. * @author Pavel Mitrenko
  63. * @author amit bhayani
  64. */
  65. public class CreateConnectionHandler extends TransactionHandler {
  66. private static final Logger logger = Logger.getLogger(CreateConnectionHandler.class);
  67. private CreateConnection command;
  68. private CreateConnectionResponse response;
  69. /** Creates a new instance of CreateConnectionHandle */
  70. public CreateConnectionHandler(JainMgcpStackImpl stack) {
  71. super(stack);
  72. }
  73. public CreateConnectionHandler(JainMgcpStackImpl stack, InetAddress address, int port) {
  74. super(stack, address, port);
  75. }
  76. public JainMgcpCommandEvent decodeCommand(final String message) throws ParseException {
  77. Utils utils = utilsFactory.allocate();
  78. MgcpMessageParser parser = new MgcpMessageParser(new CommandContentHandle(utils));
  79. try {
  80. parser.parse(message);
  81. } catch (Exception e) {
  82. throw new ParseException(e.getMessage(), -1);
  83. } finally {
  84. utilsFactory.deallocate(utils);
  85. }
  86. NotifiedEntity notifiedEntity = command.getNotifiedEntity();
  87. if (command.getNotifiedEntity() != null) {
  88. this.stack.provider.setNotifiedEntity(notifiedEntity);
  89. }
  90. return command;
  91. }
  92. public JainMgcpResponseEvent decodeResponse(String message) throws ParseException {
  93. Utils utils = utilsFactory.allocate();
  94. MgcpMessageParser parser = new MgcpMessageParser(new ResponseContentHandle(utils));
  95. try {
  96. parser.parse(message);
  97. } catch (IOException e) {
  98. logger.error("Decode of CRCX Response failed ", e);
  99. } finally {
  100. utilsFactory.deallocate(utils);
  101. }
  102. return response;
  103. }
  104. public String encode(JainMgcpCommandEvent event) {
  105. // encode message header
  106. Utils utils = utilsFactory.allocate();
  107. CreateConnection evt = (CreateConnection) event;
  108. StringBuffer s = new StringBuffer();
  109. s.append("CRCX ").append(evt.getTransactionHandle()).append(SINGLE_CHAR_SPACE).append(
  110. evt.getEndpointIdentifier()).append(MGCP_VERSION).append(NEW_LINE);
  111. // encode mandatory parameters
  112. s.append("C: ").append(evt.getCallIdentifier()).append(NEW_LINE);
  113. s.append("M: ").append(evt.getMode()).append(NEW_LINE);
  114. // encode optional parameters
  115. if (evt.getBearerInformation() != null) {
  116. s.append("B:e:").append(evt.getBearerInformation()).append(NEW_LINE);
  117. }
  118. if (evt.getNotifiedEntity() != null) {
  119. s.append("N: ").append(evt.getNotifiedEntity()).append(NEW_LINE);
  120. }
  121. if (evt.getLocalConnectionOptions() != null) {
  122. s.append("L: ").append(utils.encodeLocalOptionValueList(evt.getLocalConnectionOptions())).append(NEW_LINE);;
  123. }
  124. if (evt.getSecondEndpointIdentifier() != null) {
  125. s.append("Z2: ").append(evt.getSecondEndpointIdentifier()).append(NEW_LINE);
  126. }
  127. if (evt.getNotificationRequestParms() != null) {
  128. s.append(utils.encodeNotificationRequestParms(evt.getNotificationRequestParms())).append(NEW_LINE);;
  129. }
  130. if (evt.getRemoteConnectionDescriptor() != null) {
  131. s.append(NEW_LINE).append(evt.getRemoteConnectionDescriptor());
  132. }
  133. utilsFactory.deallocate(utils);
  134. // return msg;
  135. return s.toString();
  136. }
  137. public String encode(JainMgcpResponseEvent event) {
  138. CreateConnectionResponse response = (CreateConnectionResponse) event;
  139. ReturnCode returnCode = response.getReturnCode();
  140. StringBuffer s = new StringBuffer();
  141. s.append(returnCode.getValue()).append(SINGLE_CHAR_SPACE).append(response.getTransactionHandle()).append(
  142. SINGLE_CHAR_SPACE).append(returnCode.getComment()).append(NEW_LINE);
  143. if (response.getConnectionIdentifier() != null) {
  144. s.append("I: ").append(response.getConnectionIdentifier()).append(NEW_LINE);
  145. }
  146. if (response.getSpecificEndpointIdentifier() != null) {
  147. s.append("Z: ").append(response.getSpecificEndpointIdentifier()).append(NEW_LINE);
  148. }
  149. if (response.getSecondConnectionIdentifier() != null) {
  150. s.append("I2: ").append(response.getSecondConnectionIdentifier()).append(NEW_LINE);
  151. }
  152. if (response.getSecondEndpointIdentifier() != null) {
  153. s.append("Z2: ").append(response.getSecondEndpointIdentifier()).append(NEW_LINE);
  154. }
  155. if (response.getLocalConnectionDescriptor() != null) {
  156. s.append(NEW_LINE).append(response.getLocalConnectionDescriptor());
  157. }
  158. return s.toString();
  159. }
  160. private class CommandContentHandle implements MgcpContentHandler {
  161. private Utils utils = null;
  162. public CommandContentHandle(Utils utils) {
  163. this.utils = utils;
  164. }
  165. /**
  166. * Receive notification of the header of a message. Parser will call
  167. * this method to report about header reading.
  168. *
  169. * @param header
  170. * the header from the message.
  171. */
  172. public void header(String header) throws ParseException {
  173. command = new CreateConnection(source != null ? source : stack, new CallIdentifier("0"), endpoint,
  174. ConnectionMode.Inactive);
  175. command.setTransactionHandle(remoteTID);
  176. }
  177. /**
  178. * Receive notification of the parameter of a message. Parser will call
  179. * this method to report about parameter reading.
  180. *
  181. * @param name
  182. * the name of the paremeter
  183. * @param value
  184. * the value of the parameter.
  185. */
  186. public void param(String name, String value) throws ParseException {
  187. if (name.equalsIgnoreCase("B")) {
  188. command.setBearerInformation(utils.decodeBearerInformation(value));
  189. } else if (name.equalsIgnoreCase("c")) {
  190. command.setCallIdentifier(new CallIdentifier(value));
  191. }
  192. if (name.equalsIgnoreCase("L")) {
  193. command.setLocalConnectionOptions(utils.decodeLocalOptionValueList(value));
  194. } else if (name.equalsIgnoreCase("m")) {
  195. command.setMode(utils.decodeConnectionMode(value));
  196. } else if (name.equalsIgnoreCase("N")) {
  197. command.setNotifiedEntity(utils.decodeNotifiedEntity(value, true));
  198. } else if (name.equalsIgnoreCase("X")) {
  199. command.setNotificationRequestParms(new NotificationRequestParms(new RequestIdentifier(value)));
  200. } else if (name.equalsIgnoreCase("D")) {
  201. command.getNotificationRequestParms().setDigitMap(new DigitMap(value));
  202. } else if (name.equalsIgnoreCase("R")) {
  203. command.getNotificationRequestParms().setRequestedEvents(utils.decodeRequestedEventList(value));
  204. } else if (name.equalsIgnoreCase("S")) {
  205. command.getNotificationRequestParms().setSignalRequests(utils.decodeEventNames(value));
  206. } else if (name.equalsIgnoreCase("T")) {
  207. command.getNotificationRequestParms().setDetectEvents(utils.decodeEventNames(value));
  208. } else if (name.equalsIgnoreCase("Z2")) {
  209. try {
  210. command.setSecondEndpointIdentifier(utils.decodeEndpointIdentifier(value));
  211. } catch (ConflictingParameterException e) {
  212. }
  213. }
  214. }
  215. /**
  216. * Receive notification of the session description. Parser will call
  217. * this method to report about session descriptor reading.
  218. *
  219. * @param sd
  220. * the session description from message.
  221. */
  222. public void sessionDescription(String sd) throws ParseException {
  223. try {
  224. command.setRemoteConnectionDescriptor(new ConnectionDescriptor(sd));
  225. } catch (Exception e) {
  226. logger.error("Unexpected error in session descriptor", e);
  227. }
  228. }
  229. }
  230. private class ResponseContentHandle implements MgcpContentHandler {
  231. private Utils utils = null;
  232. public ResponseContentHandle(Utils utils) {
  233. this.utils = utils;
  234. }
  235. /**
  236. * Receive notification of the header of a message. Parser will call
  237. * this method to report about header reading.
  238. *
  239. * @param header
  240. * the header from the message.
  241. */
  242. public void header(String header) throws ParseException {
  243. String[] tokens = utils.splitStringBySpace(header);
  244. int tid = Integer.parseInt(tokens[1]);
  245. response = new CreateConnectionResponse(source != null ? source : stack, utils.decodeReturnCode(Integer
  246. .parseInt(tokens[0])), new ConnectionIdentifier("00"));
  247. response.setTransactionHandle(tid);
  248. }
  249. /**
  250. * Receive notification of the parameter of a message. Parser will call
  251. * this method to report about parameter reading.
  252. *
  253. * @param name
  254. * the name of the paremeter
  255. * @param value
  256. * the value of the parameter.
  257. */
  258. public void param(String name, String value) throws ParseException {
  259. if (name.equalsIgnoreCase("I")) {
  260. response.setConnectionIdentifier(new ConnectionIdentifier(value));
  261. } else if (name.equalsIgnoreCase("I2")) {
  262. response.setSecondConnectionIdentifier(new ConnectionIdentifier(value));
  263. } else if (name.equalsIgnoreCase("Z")) {
  264. response.setSpecificEndpointIdentifier(utils.decodeEndpointIdentifier(value));
  265. } else if (name.equalsIgnoreCase("Z2")) {
  266. response.setSecondEndpointIdentifier(utils.decodeEndpointIdentifier(value));
  267. }
  268. }
  269. /**
  270. * Receive notification of the session description. Parser will call
  271. * this method to report about session descriptor reading.
  272. *
  273. * @param sd
  274. * the session description from message.
  275. */
  276. public void sessionDescription(String sd) throws ParseException {
  277. response.setLocalConnectionDescriptor(new ConnectionDescriptor(sd));
  278. }
  279. }
  280. @Override
  281. public JainMgcpResponseEvent getProvisionalResponse() {
  282. CreateConnectionResponse provisionalResponse = null;
  283. if (!sent) {
  284. // TODO We are hardcoding connectionIdentifier here. This would
  285. // differ from final response. Problem?
  286. ConnectionIdentifier connectionIdentifier = new ConnectionIdentifier("1");
  287. provisionalResponse = new CreateConnectionResponse(source != null ? source : stack,
  288. ReturnCode.Transaction_Being_Executed, connectionIdentifier);
  289. provisionalResponse.setTransactionHandle(remoteTID);
  290. }
  291. return provisionalResponse;
  292. }
  293. }