PageRenderTime 25ms CodeModel.GetById 7ms app.highlight 14ms RepoModel.GetById 1ms app.codeStats 0ms

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