PageRenderTime 65ms CodeModel.GetById 9ms app.highlight 50ms RepoModel.GetById 1ms app.codeStats 1ms

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