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

http://mobicents.googlecode.com/ · Java · 381 lines · 242 code · 59 blank · 80 comment · 63 complexity · a9bdda1f4abf2855830ebecf66743aa0 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.mgcp.stack;
  23. import jain.protocol.ip.mgcp.JainMgcpCommandEvent;
  24. import jain.protocol.ip.mgcp.JainMgcpResponseEvent;
  25. import jain.protocol.ip.mgcp.message.AuditConnection;
  26. import jain.protocol.ip.mgcp.message.AuditConnectionResponse;
  27. import jain.protocol.ip.mgcp.message.parms.CallIdentifier;
  28. import jain.protocol.ip.mgcp.message.parms.ConnectionDescriptor;
  29. import jain.protocol.ip.mgcp.message.parms.ConnectionIdentifier;
  30. import jain.protocol.ip.mgcp.message.parms.ConnectionMode;
  31. import jain.protocol.ip.mgcp.message.parms.ConnectionParm;
  32. import jain.protocol.ip.mgcp.message.parms.InfoCode;
  33. import jain.protocol.ip.mgcp.message.parms.LocalOptionValue;
  34. import jain.protocol.ip.mgcp.message.parms.NotifiedEntity;
  35. import jain.protocol.ip.mgcp.message.parms.ReturnCode;
  36. import java.io.BufferedReader;
  37. import java.io.IOException;
  38. import java.io.StringReader;
  39. import java.net.InetAddress;
  40. import java.text.ParseException;
  41. import org.apache.log4j.Logger;
  42. import org.mobicents.protocols.mgcp.parser.MgcpContentHandler;
  43. import org.mobicents.protocols.mgcp.parser.MgcpMessageParser;
  44. import org.mobicents.protocols.mgcp.parser.Utils;
  45. /**
  46. *
  47. * @author amit bhayani
  48. *
  49. */
  50. public class AuditConnectionHandler extends TransactionHandler {
  51. private static final Logger logger = Logger.getLogger(AuditConnectionHandler.class);
  52. private AuditConnection command;
  53. private AuditConnectionResponse response;
  54. private ConnectionIdentifier connectionIdentifier = null;
  55. private InfoCode[] requestedInfo = null;
  56. boolean RCfirst = false;
  57. public AuditConnectionHandler(JainMgcpStackImpl stack) {
  58. super(stack);
  59. }
  60. public AuditConnectionHandler(JainMgcpStackImpl stack, InetAddress address, int port) {
  61. super(stack, address, port);
  62. }
  63. @Override
  64. public JainMgcpCommandEvent decodeCommand(String message) throws ParseException {
  65. Utils utils = utilsFactory.allocate();
  66. MgcpMessageParser parser = new MgcpMessageParser(new CommandContentHandle(utils));
  67. try {
  68. parser.parse(message);
  69. command = new AuditConnection(source != null ? source : stack, endpoint, connectionIdentifier, requestedInfo);
  70. command.setTransactionHandle(remoteTID);
  71. } catch (Exception e) {
  72. throw new ParseException(e.getMessage(), -1);
  73. } finally {
  74. utilsFactory.deallocate(utils);
  75. }
  76. return command;
  77. }
  78. @Override
  79. public JainMgcpResponseEvent decodeResponse(String message) throws ParseException {
  80. Utils utils = utilsFactory.allocate();
  81. MgcpMessageParser parser = new MgcpMessageParser(new ResponseContentHandle(utils));
  82. try {
  83. parser.parse(message);
  84. } catch (IOException e) {
  85. logger.error("Parsing of AUCX Response failed ", e);
  86. } finally {
  87. utilsFactory.deallocate(utils);
  88. }
  89. return response;
  90. }
  91. @Override
  92. public String encode(JainMgcpCommandEvent event) {
  93. // encode message header
  94. Utils utils = utilsFactory.allocate();
  95. AuditConnection evt = (AuditConnection) event;
  96. StringBuffer s = new StringBuffer();
  97. s.append("AUCX ").append(evt.getTransactionHandle()).append(TransactionHandler.SINGLE_CHAR_SPACE).append(
  98. evt.getEndpointIdentifier()).append(MGCP_VERSION).append(NEW_LINE);
  99. // encode mandatory parameters
  100. if (evt.getConnectionIdentifier() != null) {
  101. s.append("I:").append(evt.getConnectionIdentifier()).append(NEW_LINE);
  102. }
  103. InfoCode[] requestedInfos = evt.getRequestedInfo();
  104. if (requestedInfos != null) {
  105. s.append("F: ").append(utils.encodeInfoCodeList(requestedInfos));
  106. int foundRC = 0;
  107. int foundLC = 0;
  108. // This is to determine which SDP is RemoteSDP and which one is
  109. // LocalSDP
  110. for (int count = 0; count < requestedInfos.length; count++) {
  111. InfoCode info = requestedInfos[count];
  112. switch (info.getInfoCode()) {
  113. case (InfoCode.REMOTE_CONNECTION_DESCRIPTOR):
  114. foundRC = count;
  115. if (foundLC != 0 && foundLC < count) {
  116. RCfirst = false;
  117. } else {
  118. RCfirst = true;
  119. }
  120. break;
  121. case (InfoCode.LOCAL_CONNECTION_DESCRIPTOR):
  122. foundLC = count;
  123. if (foundRC != 0 && foundRC < count) {
  124. RCfirst = true;
  125. } else {
  126. RCfirst = false;
  127. }
  128. break;
  129. }
  130. }
  131. }
  132. utilsFactory.deallocate(utils);
  133. // return msg;
  134. return s.toString();
  135. }
  136. @Override
  137. public String encode(JainMgcpResponseEvent event) {
  138. Utils utils = utilsFactory.allocate();
  139. AuditConnectionResponse response = (AuditConnectionResponse) event;
  140. ReturnCode returnCode = response.getReturnCode();
  141. StringBuffer s = new StringBuffer();
  142. s.append(returnCode.getValue()).append(SINGLE_CHAR_SPACE).append(response.getTransactionHandle()).append(
  143. SINGLE_CHAR_SPACE).append(returnCode.getComment()).append(NEW_LINE);
  144. if (response.getCallIdentifier() != null) {
  145. s.append("C:").append(response.getCallIdentifier()).append(NEW_LINE);
  146. }
  147. if (response.getNotifiedEntity() != null) {
  148. s.append("N:").append(utils.encodeNotifiedEntity(response.getNotifiedEntity())).append(NEW_LINE);
  149. }
  150. if (response.getLocalConnectionOptions() != null) {
  151. s.append("L:").append(utils.encodeLocalOptionValueList(response.getLocalConnectionOptions())).append(
  152. NEW_LINE);
  153. }
  154. if (response.getMode() != null) {
  155. s.append("M:").append(response.getMode()).append(NEW_LINE);
  156. }
  157. if (response.getConnectionParms() != null) {
  158. s.append("P:").append(utils.encodeConnectionParms(response.getConnectionParms())).append(NEW_LINE);
  159. }
  160. if (RCfirst && response.getRemoteConnectionDescriptor() != null) {
  161. s.append(NEW_LINE).append(response.getRemoteConnectionDescriptor()).append(NEW_LINE);
  162. }
  163. if (response.getLocalConnectionDescriptor() != null) {
  164. s.append(NEW_LINE).append(response.getLocalConnectionDescriptor()).append(NEW_LINE);
  165. }
  166. if (!RCfirst && response.getRemoteConnectionDescriptor() != null) {
  167. s.append(NEW_LINE).append(response.getRemoteConnectionDescriptor()).append(NEW_LINE);
  168. }
  169. utilsFactory.deallocate(utils);
  170. return s.toString();
  171. // return msg;
  172. }
  173. @Override
  174. public JainMgcpResponseEvent getProvisionalResponse() {
  175. AuditConnectionResponse provisionalResponse = null;
  176. if (!sent) {
  177. provisionalResponse = new AuditConnectionResponse(source != null ? source : stack,
  178. ReturnCode.Transaction_Being_Executed);
  179. provisionalResponse.setTransactionHandle(remoteTID);
  180. }
  181. return provisionalResponse;
  182. }
  183. private class CommandContentHandle implements MgcpContentHandler {
  184. Utils utils = null;
  185. public CommandContentHandle(Utils utils) {
  186. this.utils = utils;
  187. }
  188. /**
  189. * Receive notification of the header of a message. Parser will call
  190. * this method to report about header reading.
  191. *
  192. * @param header
  193. * the header from the message.
  194. */
  195. public void header(String header) throws ParseException {
  196. // Can't create the AuditConnection object here as
  197. // ConnectionIdentifier and InfoCode[] is required
  198. }
  199. /**
  200. * Receive notification of the parameter of a message. Parser will call
  201. * this method to report about parameter reading.
  202. *
  203. * @param name
  204. * the name of the parameter
  205. * @param value
  206. * the value of the parameter.
  207. */
  208. public void param(String name, String value) throws ParseException {
  209. if (name.equalsIgnoreCase("I")) {
  210. connectionIdentifier = new ConnectionIdentifier(value);
  211. } else if (name.equalsIgnoreCase("F")) {
  212. int RCindex = value.indexOf("RC");
  213. int LCindex = value.indexOf("LC");
  214. if (RCindex != -1 && RCindex < LCindex) {
  215. RCfirst = true;
  216. }
  217. requestedInfo = utils.decodeInfoCodeList(value);
  218. } else {
  219. logger.error("Unknown code while encoding AUCX Command name = " + name + " value = " + value);
  220. }
  221. }
  222. /**
  223. * Receive notification of the session description. Parser will call
  224. * this method to report about session descriptor reading.
  225. *
  226. * @param sd
  227. * the session description from message.
  228. */
  229. public void sessionDescription(String sd) throws ParseException {
  230. throw new ParseException("SessionDescription shouldn't have been included in AUCX command", 0);
  231. }
  232. }
  233. private class ResponseContentHandle implements MgcpContentHandler {
  234. Utils utils = null;
  235. public ResponseContentHandle(Utils utils) {
  236. this.utils = utils;
  237. }
  238. /**
  239. * Receive notification of the header of a message. Parser will call
  240. * this method to report about header reading.
  241. *
  242. * @param header
  243. * the header from the message.
  244. */
  245. public void header(String header) throws ParseException {
  246. String[] tokens = utils.splitStringBySpace(header);
  247. int tid = Integer.parseInt(tokens[1]);
  248. response = new AuditConnectionResponse(source != null ? source : stack, utils.decodeReturnCode(Integer
  249. .parseInt(tokens[0])));
  250. response.setTransactionHandle(tid);
  251. }
  252. /**
  253. * Receive notification of the parameter of a message. Parser will call
  254. * this method to report about parameter reading.
  255. *
  256. * @param name
  257. * the name of the paremeter
  258. * @param value
  259. * the value of the parameter.
  260. */
  261. public void param(String name, String value) throws ParseException {
  262. if (name.equalsIgnoreCase("C")) {
  263. response.setCallIdentifier(new CallIdentifier(value));
  264. } else if (name.equalsIgnoreCase("N")) {
  265. NotifiedEntity n = utils.decodeNotifiedEntity(value, true);
  266. response.setNotifiedEntity(n);
  267. } else if (name.equalsIgnoreCase("L")) {
  268. LocalOptionValue[] LocalOptionValueList = utils.decodeLocalOptionValueList(value);
  269. response.setLocalConnectionOptions(LocalOptionValueList);
  270. } else if (name.equalsIgnoreCase("M")) {
  271. ConnectionMode connectionMode = utils.decodeConnectionMode(value);
  272. response.setMode(connectionMode);
  273. } else if (name.equalsIgnoreCase("P")) {
  274. ConnectionParm[] connectionParms = utils.decodeConnectionParms(value);
  275. response.setConnectionParms(connectionParms);
  276. } else {
  277. logger.warn("Unidentified AUCX Response parameter " + name + " with value = " + value);
  278. }
  279. }
  280. /**
  281. * Receive notification of the session description. Parser will call
  282. * this method to report about session descriptor reading.
  283. *
  284. * @param sd
  285. * the session description from message.
  286. */
  287. public void sessionDescription(String sd) throws ParseException {
  288. StringReader stringReader = new StringReader(sd);
  289. BufferedReader reader = new BufferedReader(stringReader);
  290. String line = null;
  291. boolean sdpPresent = false;
  292. String sdp1 = "";
  293. String sdp2 = "";
  294. try {
  295. while ((line = reader.readLine()) != null) {
  296. line = line.trim();
  297. sdpPresent = line.length() == 0;
  298. if (sdpPresent)
  299. break;
  300. sdp1 = sdp1 + line.trim() + "\r\n";
  301. }
  302. while ((line = reader.readLine()) != null) {
  303. line = line.trim();
  304. sdp2 = sdp2 + line.trim() + "\r\n";
  305. }
  306. } catch (IOException e) {
  307. logger.error("Error while reading the SDP for AUCX Response and decoding to AUCX command ", e);
  308. }
  309. if (RCfirst) {
  310. response.setRemoteConnectionDescriptor(new ConnectionDescriptor(sdp1));
  311. if (!sdp2.equals("")) {
  312. response.setLocalConnectionDescriptor(new ConnectionDescriptor(sdp2));
  313. }
  314. } else {
  315. response.setLocalConnectionDescriptor(new ConnectionDescriptor(sdp1));
  316. if (!sdp2.equals("")) {
  317. response.setRemoteConnectionDescriptor(new ConnectionDescriptor(sdp2));
  318. }
  319. }
  320. }
  321. }
  322. }