PageRenderTime 123ms CodeModel.GetById 11ms app.highlight 100ms RepoModel.GetById 1ms app.codeStats 0ms

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

http://mobicents.googlecode.com/
Java | 1852 lines | 1374 code | 248 blank | 230 comment | 396 complexity | 66af7af2990b7756932d4b0e8a0c8f1e MD5 | raw file

Large files files are truncated, but you can click here to view the full 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     : Utils.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 */
  38package org.mobicents.protocols.mgcp.parser;
  39
  40import jain.protocol.ip.mgcp.message.parms.Bandwidth;
  41import jain.protocol.ip.mgcp.message.parms.BearerInformation;
  42import jain.protocol.ip.mgcp.message.parms.CapabilityValue;
  43import jain.protocol.ip.mgcp.message.parms.CompressionAlgorithm;
  44import jain.protocol.ip.mgcp.message.parms.ConnectionIdentifier;
  45import jain.protocol.ip.mgcp.message.parms.ConnectionMode;
  46import jain.protocol.ip.mgcp.message.parms.ConnectionParm;
  47import jain.protocol.ip.mgcp.message.parms.DigitMap;
  48import jain.protocol.ip.mgcp.message.parms.EchoCancellation;
  49import jain.protocol.ip.mgcp.message.parms.EmbeddedRequest;
  50import jain.protocol.ip.mgcp.message.parms.EncryptionMethod;
  51import jain.protocol.ip.mgcp.message.parms.EndpointIdentifier;
  52import jain.protocol.ip.mgcp.message.parms.EventName;
  53import jain.protocol.ip.mgcp.message.parms.ExtendedConnectionParm;
  54import jain.protocol.ip.mgcp.message.parms.GainControl;
  55import jain.protocol.ip.mgcp.message.parms.InfoCode;
  56import jain.protocol.ip.mgcp.message.parms.LocalOptVal;
  57import jain.protocol.ip.mgcp.message.parms.LocalOptionExtension;
  58import jain.protocol.ip.mgcp.message.parms.LocalOptionValue;
  59import jain.protocol.ip.mgcp.message.parms.NotificationRequestParms;
  60import jain.protocol.ip.mgcp.message.parms.NotifiedEntity;
  61import jain.protocol.ip.mgcp.message.parms.PacketizationPeriod;
  62import jain.protocol.ip.mgcp.message.parms.ReasonCode;
  63import jain.protocol.ip.mgcp.message.parms.RegularConnectionParm;
  64import jain.protocol.ip.mgcp.message.parms.RequestedAction;
  65import jain.protocol.ip.mgcp.message.parms.RequestedEvent;
  66import jain.protocol.ip.mgcp.message.parms.ResourceReservation;
  67import jain.protocol.ip.mgcp.message.parms.RestartMethod;
  68import jain.protocol.ip.mgcp.message.parms.ReturnCode;
  69import jain.protocol.ip.mgcp.message.parms.SilenceSuppression;
  70import jain.protocol.ip.mgcp.message.parms.SupportedModes;
  71import jain.protocol.ip.mgcp.message.parms.SupportedPackages;
  72import jain.protocol.ip.mgcp.message.parms.TypeOfNetwork;
  73import jain.protocol.ip.mgcp.message.parms.TypeOfService;
  74import jain.protocol.ip.mgcp.pkg.MgcpEvent;
  75import jain.protocol.ip.mgcp.pkg.PackageName;
  76
  77import java.text.ParseException;
  78import java.util.ArrayList;
  79import java.util.List;
  80import java.util.regex.Matcher;
  81import java.util.regex.Pattern;
  82
  83import org.apache.log4j.Logger;
  84import org.mobicents.protocols.mgcp.jain.pkg.AUMgcpEvent;
  85import org.mobicents.protocols.mgcp.jain.pkg.AUPackage;
  86
  87/**
  88 * 
  89 * @author Oleg Kulikov
  90 * @author Pavel Mitrenko
  91 * @author Amit Bhayani
  92 */
  93public class Utils {
  94
  95	private static final Logger logger = Logger.getLogger(Utils.class);
  96	
  97	private static final char AMPERSAND = '@';
  98
  99	private static final String REGEX_EMBEDDED_COMMAND = "\\(E\\(.*\\)\\)";
 100	private static final Pattern pattern = Pattern.compile(REGEX_EMBEDDED_COMMAND);
 101
 102	private static final Pattern commaPattern = Pattern.compile(",");
 103
 104	private static final Pattern equalsPattern = Pattern.compile("=");
 105
 106	private static final Pattern colonPattern = Pattern.compile(":");
 107
 108	private static final Pattern semiColonPattern = Pattern.compile(";");
 109
 110	private static final Pattern dashPattern = Pattern.compile("-");
 111
 112	PackageName au = AUPackage.AU;
 113	MgcpEvent rfc2897pa = AUMgcpEvent.aupa;
 114
 115	StringBuilder decdReqEveStrBuilder = new StringBuilder();
 116
 117	List<String> list = new ArrayList<String>();
 118	List<String> decdEventName = new ArrayList<String>();
 119	List<String> decdReqtEventList = new ArrayList<String>();
 120
 121	/** Creates a new instance of Utils */
 122	public Utils() {
 123	}
 124
 125	public String[] splitStringBySpace(String value) {
 126		// return spacePattern.split(value, 0);
 127		try {
 128			String[] token = null;
 129			this.split(' ', value, decdEventName);
 130			token = new String[decdEventName.size()];
 131			decdEventName.toArray(token);
 132			return token;
 133		} finally {
 134			decdEventName.clear();
 135		}
 136	}
 137
 138	/**
 139	 * Create ConnectionMode object from given text value.
 140	 * 
 141	 * @param mode
 142	 *            the text value of the connection mode.
 143	 * @return the ConnectionMode object.
 144	 */
 145	public ConnectionMode decodeConnectionMode(String mode) {
 146		if (mode.equals("sendrecv")) {
 147			return ConnectionMode.SendRecv;
 148		} else if (mode.equalsIgnoreCase("sendonly")) {
 149			return ConnectionMode.SendOnly;
 150		} else if (mode.equalsIgnoreCase("recvonly")) {
 151			return ConnectionMode.RecvOnly;
 152		} else if (mode.equalsIgnoreCase("confrnce")) {
 153			return ConnectionMode.Confrnce;
 154		} else if (mode.equalsIgnoreCase("conttest")) {
 155			return ConnectionMode.Conttest;
 156		} else if (mode.equalsIgnoreCase("data")) {
 157			return ConnectionMode.Data;
 158		} else if (mode.equalsIgnoreCase("loopback")) {
 159			return ConnectionMode.Loopback;
 160		} else if (mode.equalsIgnoreCase("netwloop")) {
 161			return ConnectionMode.Netwloop;
 162		} else if (mode.equalsIgnoreCase("netwtest")) {
 163			return ConnectionMode.Netwtest;
 164		}
 165		return ConnectionMode.Inactive;
 166	}
 167
 168	public String encodeBearerInformation(BearerInformation bearerInformation) {
 169		StringBuffer s = new StringBuffer("e:");
 170
 171		if (BearerInformation.ENC_METHOD_A_LAW == bearerInformation.getEncodingMethod()) {
 172			s.append("A");
 173		} else if (BearerInformation.ENC_METHOD_MU_LAW == bearerInformation.getEncodingMethod()) {
 174			s.append("mu");
 175		}
 176		return s.toString();
 177	}
 178
 179	/**
 180	 * Create BearerInformation object from given text.
 181	 * 
 182	 * @param text
 183	 *            the text value of the object.
 184	 * @return BearerInformation object.
 185	 */
 186	public BearerInformation decodeBearerInformation(String text) throws ParseException {
 187		// BearerInformation =BearerAttribute 0*(","0*(WSP)BearerAttribute)
 188		// BearerAttribute =("e"":"BearerEncoding)
 189		// (BearerExtensionName [":"BearerExtensionValue ])
 190		// BearerExtensionName =PackageLCOExtensionName
 191		// BearerExtensionValue =LocalOptionExtensionValue
 192		// BearerEncoding ="A"/"mu"
 193
 194		text = text.toLowerCase();
 195		if (!text.startsWith("e:")) {
 196			throw new ParseException("Bearer extensions not supported", 0);
 197		}
 198
 199		text = text.substring(text.indexOf(":") + 1).trim();
 200
 201		if (text.equals("a")) {
 202			return BearerInformation.EncMethod_A_Law;
 203		} else if (text.equals("mu")) {
 204			return BearerInformation.EncMethod_mu_Law;
 205		} else {
 206			throw new ParseException("Unknown value for BearerInformation: " + text, 0);
 207		}
 208	}
 209
 210	/**
 211	 * Create local connection options from given text.
 212	 * 
 213	 * @param text
 214	 *            the text value.
 215	 * @return array of LocalOptionValue objects.
 216	 */
 217	public LocalOptionValue[] decodeLocalOptionValueList(String text) throws ParseException {
 218		// LocalConnectionOptions =LocalOptionValue 0*(WSP)
 219		// 0*(","0*(WSP)LocalOptionValue 0*(WSP))
 220
 221		String[] tokens = commaPattern.split(text, 0);
 222		LocalOptionValue[] options = new LocalOptionValue[tokens.length];
 223
 224		for (int i = 0; i < tokens.length; i++) {
 225			options[i] = decodeLocalOptionValue(tokens[i]);
 226		}
 227
 228		return options;
 229	}
 230
 231	/**
 232	 * Create local connection object from given text.
 233	 * 
 234	 * @param text
 235	 *            the text value of the LocalOptionValue object.
 236	 * @return LocalOption object.
 237	 */
 238	public LocalOptionValue decodeLocalOptionValue(String text) throws ParseException {
 239		// LocalOptionValue =("p"":"packetizationPeriod)
 240		// /("a"":"compressionAlgorithm)
 241		// /("b"":"bandwidth)
 242		// /("e"":"echoCancellation)
 243		// /("gc"":"gainControl)
 244		// /("s"":"silenceSuppression)
 245		// /("t"":"typeOfService)
 246		// /("r"":"resourceReservation)
 247		// /("k"":"encryptiondata)
 248		// /("nt"":"(typeOfNetwork /
 249		// supportedTypeOfNetwork))
 250		// /(LocalOptionExtensionName
 251		// [":"LocalOptionExtensionValue ])
 252
 253		int pos = text.indexOf(':');
 254		if (pos < 0) {
 255			throw new ParseException("Could not parse local connection option: " + text, 0);
 256		}
 257
 258		String name = text.substring(0, pos).trim();
 259		String value = text.substring(pos + 1).trim();
 260
 261		if (name.equalsIgnoreCase("a")) {
 262			return decodeCompressionAlgorithm(value);
 263		} else if (name.equalsIgnoreCase("p")) {
 264			return decodePacketizationPeriod(value);
 265		} else if (name.equalsIgnoreCase("b")) {
 266			return decodeBandwidth(value);
 267		} else if (name.equalsIgnoreCase("e")) {
 268			return decodeEchoCancellation(value);
 269		} else if (name.equalsIgnoreCase("gc")) {
 270			return decodeGainControl(value);
 271		} else if (name.equalsIgnoreCase("s")) {
 272			return decodeSilenceSuppression(value);
 273		} else if (name.equalsIgnoreCase("t")) {
 274			return decodeTypeOfService(value);
 275		} else if (name.equalsIgnoreCase("r")) {
 276			return decodeResourceReservation(value);
 277		} else if (name.equalsIgnoreCase("k")) {
 278			return decodeEncryptionMethod(value);
 279		} else if (name.equalsIgnoreCase("nt")) {
 280			return decodeTypeOfNetwork(value);
 281		} else {
 282			return new LocalOptionExtension(name, value);
 283		}
 284
 285	}
 286
 287	public String encodeLocalOptionVale(LocalOptionValue localOptionValue) {
 288		StringBuffer s = new StringBuffer("");
 289		switch (localOptionValue.getLocalOptionValueType()) {
 290		case LocalOptionValue.BANDWIDTH:
 291			Bandwidth b = (Bandwidth) localOptionValue;
 292			s.append("b:").append(encodeBandwidth(b));
 293			break;
 294
 295		case LocalOptionValue.COMPRESSION_ALGORITHM:
 296			CompressionAlgorithm compressionAlgorithm = (CompressionAlgorithm) localOptionValue;
 297			s.append("a:").append(encodeCompressionAlgorithm(compressionAlgorithm));
 298			break;
 299
 300		case LocalOptionValue.ECHO_CANCELLATION:
 301			EchoCancellation echoCancellation = (EchoCancellation) localOptionValue;
 302			s.append("e:").append(encodeEchoCancellation(echoCancellation));
 303			break;
 304
 305		case LocalOptionValue.ENCRYPTION_METHOD:
 306			EncryptionMethod encryptionMethod = (EncryptionMethod) localOptionValue;
 307			s.append("k:").append(encodeEncryptionMethod(encryptionMethod));
 308			break;
 309
 310		case LocalOptionValue.GAIN_CONTROL:
 311			GainControl gainControl = (GainControl) localOptionValue;
 312			s.append("gc:").append(encodeGainControl(gainControl));
 313			break;
 314
 315		case LocalOptionValue.LOCAL_OPTION_EXTENSION:
 316			LocalOptionExtension localOptionExtension = (LocalOptionExtension) localOptionValue;
 317			s.append(localOptionExtension.getLocalOptionExtensionName()).append(":").append(
 318					localOptionExtension.getLocalOptionExtensionValue());
 319			break;
 320
 321		case LocalOptionValue.PACKETIZATION_PERIOD:
 322			PacketizationPeriod packetizationPeriod = (PacketizationPeriod) localOptionValue;
 323			s.append("p:").append(encodePacketizationPeriod(packetizationPeriod));
 324			break;
 325
 326		case LocalOptionValue.RESOURCE_RESERVATION:
 327			s.append("r:");
 328			ResourceReservation resourceReservation = (ResourceReservation) localOptionValue;
 329			s.append(encodeResourceReservation(resourceReservation));
 330			break;
 331
 332		case LocalOptionValue.SILENCE_SUPPRESSION:
 333			s.append("s:");
 334			SilenceSuppression silenceSuppression = (SilenceSuppression) localOptionValue;
 335			s.append(encodeSilenceSuppression(silenceSuppression));
 336			break;
 337
 338		case LocalOptionValue.TYPE_OF_NETWORK:
 339			s.append("nt:");
 340			TypeOfNetwork typeOfNetwork = (TypeOfNetwork) localOptionValue;
 341			s.append(encodeTypeOfNetwork(typeOfNetwork));
 342			break;
 343
 344		case LocalOptionValue.TYPE_OF_SERVICE:
 345			TypeOfService typeOfService = (TypeOfService) localOptionValue;
 346			s.append("t:").append(encodeTypeOfService(typeOfService));
 347			break;
 348
 349		default:
 350			logger.error("LocalOptionValue " + localOptionValue + " not identified");
 351			break;
 352		}
 353
 354		return s.toString();
 355	}
 356
 357	/**
 358	 * Create CompressionAlgorithm object from given text.
 359	 * 
 360	 * @param text
 361	 *            the text value of the compression algoritm.
 362	 * @return CompressionAlgorithm object.
 363	 */
 364	public CompressionAlgorithm decodeCompressionAlgorithm(String value) throws ParseException {
 365		// compressionAlgorithm =algorithmName 0*(";"algorithmName)
 366		return new CompressionAlgorithm(semiColonPattern.split(value, 0));
 367	}
 368
 369	public String encodeCompressionAlgorithm(CompressionAlgorithm compressionAlgorithm) {
 370		StringBuffer s = new StringBuffer("");
 371		String[] names = compressionAlgorithm.getCompressionAlgorithmNames();
 372		boolean first = true;
 373		for (int i = 0; i < names.length; i++) {
 374			if (first) {
 375				first = false;
 376			} else {
 377				s.append(";");
 378			}
 379			s.append(names[i]);
 380		}
 381		return s.toString();
 382	}
 383
 384	/**
 385	 * Create PacketizationPeriod object from given text.
 386	 * 
 387	 * @param text
 388	 *            the text view of the PacketizationPeriod object.
 389	 * @return PacketizationPeriod object.
 390	 */
 391	public PacketizationPeriod decodePacketizationPeriod(String value) throws ParseException {
 392		// packetizationPeriod =1*4(DIGIT)["-"1*4(DIGIT)]
 393		int pos = value.indexOf('-');
 394		if (pos < 0) {
 395			try {
 396				return new PacketizationPeriod(Integer.parseInt(value));
 397			} catch (Exception e) {
 398				throw new ParseException("Invalid packetization period:" + value, 0);
 399			}
 400		} else {
 401			String low = value.substring(0, pos).trim();
 402			String hight = value.substring(pos + 1).trim();
 403
 404			try {
 405				return new PacketizationPeriod(Integer.parseInt(low), Integer.parseInt(hight));
 406			} catch (Exception e) {
 407				throw new ParseException("Invalid packetization period:" + value, 0);
 408			}
 409		}
 410	}
 411
 412	public String encodePacketizationPeriod(PacketizationPeriod packetizationPeriod) {
 413		StringBuffer s = new StringBuffer("");
 414		if (packetizationPeriod.getPacketizationPeriodLowerBound() != packetizationPeriod
 415				.getPacketizationPeriodUpperBound()) {
 416			s.append(packetizationPeriod.getPacketizationPeriodLowerBound()).append("-").append(
 417					packetizationPeriod.getPacketizationPeriodUpperBound());
 418		} else {
 419			s.append(packetizationPeriod.getPacketizationPeriodLowerBound());
 420		}
 421		return s.toString();
 422	}
 423
 424	/**
 425	 * Create Bandwidth object from given text.
 426	 * 
 427	 * @param text
 428	 *            the text view of the Bandwidth object.
 429	 * @return Bandwidth object.
 430	 */
 431	public Bandwidth decodeBandwidth(String value) throws ParseException {
 432		// bandwidth =1*4(DIGIT)["-"1*4(DIGIT)]
 433		int pos = value.indexOf('-');
 434		if (pos < 0) {
 435			try {
 436				return new Bandwidth(Integer.parseInt(value));
 437			} catch (Exception e) {
 438				throw new ParseException("Invalid packetization period:" + value, 0);
 439			}
 440		} else {
 441			String low = value.substring(0, pos).trim();
 442			String hight = value.substring(pos + 1).trim();
 443
 444			try {
 445				return new Bandwidth(Integer.parseInt(low), Integer.parseInt(hight));
 446			} catch (Exception e) {
 447				throw new ParseException("Invalid packetization period:" + value, 0);
 448			}
 449		}
 450	}
 451
 452	public String encodeBandwidth(Bandwidth bandwidth) {
 453		StringBuffer s = new StringBuffer("");
 454		if (bandwidth.getBandwidthLowerBound() != bandwidth.getBandwidthUpperBound()) {
 455			s.append(bandwidth.getBandwidthLowerBound()).append("-").append(bandwidth.getBandwidthUpperBound());
 456		} else {
 457			s.append(bandwidth.getBandwidthLowerBound());
 458		}
 459		return s.toString();
 460	}
 461
 462	/**
 463	 * Decode EchoCancellation object from given text.
 464	 * 
 465	 * @param text
 466	 *            the text value of the EchoCancellation.
 467	 * @return EchoCancellation object.
 468	 */
 469	public EchoCancellation decodeEchoCancellation(String value) throws ParseException {
 470		// echoCancellation ="on"/"off"
 471		if (value.equalsIgnoreCase("on")) {
 472			return EchoCancellation.EchoCancellationOn;
 473		} else if (value.equalsIgnoreCase("of")) {
 474			return EchoCancellation.EchoCancellationOff;
 475		} else {
 476			throw new ParseException("Invalid value for EchoCancellation :" + value, 0);
 477		}
 478	}
 479
 480	public String encodeEchoCancellation(EchoCancellation echoCancellation) {
 481		StringBuffer s = new StringBuffer("");
 482		if (echoCancellation.getEchoCancellation()) {
 483			s.append("on");
 484		} else {
 485			s.append("off");
 486		}
 487		return s.toString();
 488	}
 489
 490	/**
 491	 * Decode GainControl object from given text.
 492	 * 
 493	 * @param text
 494	 *            the text value of the GainControl.
 495	 * @return GainControl object.
 496	 */
 497	public GainControl decodeGainControl(String value) throws ParseException {
 498		// gainControl ="auto"/["-"] 1**4(DIGIT)
 499		if (value.equalsIgnoreCase("auto")) {
 500			return new GainControl();
 501		} else {
 502			try {
 503				return new GainControl(Integer.parseInt(value));
 504			} catch (Exception e) {
 505				throw new ParseException("Invalid value for EchoCancellation :" + value, 0);
 506			}
 507		}
 508	}
 509
 510	public String encodeGainControl(GainControl gainControl) {
 511		StringBuffer s = new StringBuffer("");
 512		if (gainControl.getGainControl() == 0) {
 513			s.append("auto");
 514		} else {
 515			s.append(gainControl.getGainControl());
 516		}
 517		return s.toString();
 518	}
 519
 520	/**
 521	 * Decode SilenceSuppression object from given text.
 522	 * 
 523	 * @param text
 524	 *            the text value of the SilenceSuppression.
 525	 * @return SilenceSuppression object.
 526	 */
 527	public SilenceSuppression decodeSilenceSuppression(String value) throws ParseException {
 528		// silenceSuppression ="on"/"off"
 529		if (value.equalsIgnoreCase("on")) {
 530			return SilenceSuppression.SilenceSuppressionOn;
 531		} else if (value.equalsIgnoreCase("off")) {
 532			return SilenceSuppression.SilenceSuppressionOff;
 533		} else {
 534			throw new ParseException("Invalid value for SilenceSuppression :" + value, 0);
 535		}
 536	}
 537
 538	public String encodeSilenceSuppression(SilenceSuppression silenceSuppression) {
 539		StringBuffer s = new StringBuffer("");
 540		if (silenceSuppression.getSilenceSuppression()) {
 541			s.append("on");
 542		} else {
 543			s.append("off");
 544		}
 545		return s.toString();
 546	}
 547
 548	/**
 549	 * Decode TypeOfService object from given text.
 550	 * 
 551	 * @param text
 552	 *            the text value of the TypeOfService.
 553	 * @return TypeOfService object.
 554	 */
 555	public TypeOfService decodeTypeOfService(String value) throws ParseException {
 556		// typeOfService =1*2(HEXDIG);1 hex only for capabilities
 557		try {
 558			return new TypeOfService((byte) Integer.parseInt(value));
 559		} catch (Exception e) {
 560			throw new ParseException("Invalid value for TypeOfService :" + value, 0);
 561		}
 562	}
 563
 564	public String encodeTypeOfService(TypeOfService typeOfService) {
 565		String s = Integer.toString(typeOfService.getTypeOfService(), 16).toUpperCase();
 566		return s;
 567	}
 568
 569	/**
 570	 * Decode ResourceReservation object from given text.
 571	 * 
 572	 * @param text
 573	 *            the text value of the ResourceReservation.
 574	 * @return ResourceReservation object.
 575	 */
 576	public ResourceReservation decodeResourceReservation(String value) throws ParseException {
 577		// resourceReservation ="g"/"cl"/"be"
 578		if (value.equalsIgnoreCase("g")) {
 579			return ResourceReservation.Guaranteed;
 580		} else if (value.equalsIgnoreCase("cl")) {
 581			return ResourceReservation.ControlledLoad;
 582		} else if (value.equalsIgnoreCase("be")) {
 583			return ResourceReservation.BestEffort;
 584		} else {
 585			throw new ParseException("Invalid value for EchoCancellation :" + value, 0);
 586		}
 587	}
 588
 589	public String encodeResourceReservation(ResourceReservation resourceReservation) {
 590		StringBuffer s = new StringBuffer("");
 591		switch (resourceReservation.getResourceReservation()) {
 592		case ResourceReservation.BEST_EFFORT:
 593			s.append("be");
 594			break;
 595
 596		case ResourceReservation.CONTROLLED_LOAD:
 597			s.append("cl");
 598			break;
 599
 600		case ResourceReservation.GUARANTEED:
 601			s.append("g");
 602			break;
 603		}
 604		return s.toString();
 605	}
 606
 607	/**
 608	 * Decode EncryptionMethod object from given text.
 609	 * 
 610	 * @param text
 611	 *            the text value of the EncryptionMethod.
 612	 * @return EncryptionMethod object.
 613	 */
 614	public EncryptionMethod decodeEncryptionMethod(String value) throws ParseException {
 615		// encryptiondata =("clear"":"encryptionKey )
 616		// /("base64"":"encodedEncryptionKey )
 617		// /("uri"":"URItoObtainKey )
 618		// /("prompt");defined in SDP,not usable in MGCP!
 619		int pos = value.indexOf(':');
 620		if (pos < 0) {
 621			throw new ParseException("Invalid value for EncryptionData: " + value, 0);
 622		}
 623
 624		String method = value.substring(0, pos).trim();
 625		String key = value.substring(pos + 1).trim();
 626
 627		if (method.equalsIgnoreCase("clear")) {
 628			return new EncryptionMethod(EncryptionMethod.CLEAR, key);
 629		} else if (method.equalsIgnoreCase("base64")) {
 630			return new EncryptionMethod(EncryptionMethod.BASE64, key);
 631		} else if (method.equalsIgnoreCase("uri")) {
 632			return new EncryptionMethod(EncryptionMethod.URI, key);
 633		} else {
 634			throw new ParseException("Invalid value for EncryptionData: " + method, 0);
 635		}
 636	}
 637
 638	public String encodeEncryptionMethod(EncryptionMethod encryptionMethod) {
 639		StringBuffer s = new StringBuffer("");
 640		switch (encryptionMethod.getEncryptionMethod()) {
 641		case EncryptionMethod.BASE64:
 642			s.append("base64:").append(encryptionMethod.getEncryptionKey());
 643			break;
 644
 645		case EncryptionMethod.CLEAR:
 646			s.append("clear:").append(encryptionMethod.getEncryptionKey());
 647			break;
 648
 649		case EncryptionMethod.URI:
 650			s.append("uri:").append(encryptionMethod.getEncryptionKey());
 651			break;
 652		}
 653		return s.toString();
 654	}
 655
 656	/**
 657	 * Decode TypeOfNetwork object from given text.
 658	 * 
 659	 * @param text
 660	 *            the text value of the TypeOfNetwork.
 661	 * @return TypeOfNetwork object.
 662	 */
 663	public TypeOfNetwork decodeTypeOfNetwork(String value) throws ParseException {
 664		// typeOfNetwork ="IN"/"ATM"/"LOCAL"/OtherTypeOfNetwork
 665		if (value.equalsIgnoreCase("in")) {
 666			return TypeOfNetwork.In;
 667		} else if (value.equalsIgnoreCase("atm")) {
 668			return TypeOfNetwork.Atm;
 669		} else if (value.equalsIgnoreCase("local")) {
 670			return TypeOfNetwork.Local;
 671		} else {
 672			throw new ParseException("Invalid value for TypeOfNetwork :" + value, 0);
 673		}
 674	}
 675
 676	public String encodeTypeOfNetwork(TypeOfNetwork typeOfNetwork) {
 677		StringBuffer s = new StringBuffer("");
 678		switch (typeOfNetwork.getTypeOfNetwork()) {
 679		case TypeOfNetwork.IN:
 680			s.append("in");
 681			break;
 682		case TypeOfNetwork.ATM:
 683			s.append("atm");
 684			break;
 685		case TypeOfNetwork.LOCAL:
 686			s.append("local");
 687			break;
 688		}
 689		return s.toString();
 690	}
 691
 692	public RestartMethod decodeRestartMethod(String value) throws ParseException {
 693		// RestartMethod = "graceful" / "forced" / "restart" / "disconnected"
 694		// / "cancel-graceful" / extensionRestartMethod
 695		// extensionRestartMethod = PackageExtensionRM
 696		// PackageExtensionRM = packageName "/" 1*32(ALPHA / DIGIT / HYPHEN)
 697
 698		if (value.equalsIgnoreCase("graceful")) {
 699			return RestartMethod.Graceful;
 700		} else if (value.equalsIgnoreCase("forced")) {
 701			return RestartMethod.Forced;
 702		} else if (value.equalsIgnoreCase("restart")) {
 703			return RestartMethod.Restart;
 704		} else if (value.equalsIgnoreCase("disconnected")) {
 705			return RestartMethod.Disconnected;
 706		} else if (value.equalsIgnoreCase("cancel-grateful")) {
 707			return RestartMethod.CancelGraceful;
 708		} else {
 709			// TODO: Add support for extension restart method.
 710			throw new ParseException("Extension restarts not (yet) supported:" + value, 0);
 711		}
 712	}
 713
 714	public RequestedEvent[] decodeRequestedEventList(String value) throws ParseException {
 715		// RequestedEvents =requestedEvent 0*(","0*(WSP)requestedEvent)
 716		// String[] tokens = commaPattern.split(value, 0);
 717
 718		this.split(',', value, this.decdReqtEventList);
 719		try {
 720			int size = decdReqtEventList.size();
 721
 722			RequestedEvent[] events = new RequestedEvent[size];
 723
 724			for (int i = 0; i < size; i++) {
 725				events[i] = decodeRequestedEvent(decdReqtEventList.get(i));
 726			}
 727
 728			return events;
 729		} finally {
 730			this.decdReqtEventList.clear();
 731		}
 732	}
 733
 734	public RequestedEvent decodeRequestedEvent(String value) throws ParseException {
 735		// requestedEvent =(eventName ["("requestedActions ")"])
 736		// /(eventName "("requestedActions ")" "("eventParameters ")")
 737
 738		// Replace all space, tabs
 739
 740		// value = value.replaceAll("\\s", "");
 741		// value = spacePattern.matcher(value).replaceAll("");
 742
 743		char[] valueChar = value.toCharArray();
 744
 745		for (char c : valueChar) {
 746			if (c != ' ') {
 747				decdReqEveStrBuilder.append(c);
 748			}
 749		}
 750
 751		value = decdReqEveStrBuilder.toString();
 752
 753		decdReqEveStrBuilder.delete(0, valueChar.length);
 754
 755		int pos1 = value.indexOf('(');
 756		// int pos2 = value.indexOf(')', pos1);
 757		// int pos3 = value.indexOf('(', pos2);
 758		// int pos4 = value.indexOf(')', pos3);
 759
 760		if (pos1 == -1) { // no actions, no parameters
 761			// TODO: RFC3435 : 3.2.2.16 :When no action is specified, the
 762			// default action is to notify the event. This should be taken care
 763			// by MGW or N action should be added here by default?
 764			return new RequestedEvent(decodeEventName(value, null), null);
 765		}
 766
 767		String evtName = value.substring(0, pos1);
 768		value = value.substring(pos1, value.length());
 769
 770		Matcher matcher = pattern.matcher(value);
 771
 772		if ((matcher.find())) {
 773			// This is Embedded Notification Request
 774
 775			// TODO : We assumed that Embedded Notification Request E will not
 776			// be
 777			// combined with any other Action N, A, D, S, I or K
 778			String embeddedNotificatonRequest = value.substring(3, value.length() - 2);
 779			EmbeddedRequest embeddedRequest = decodeEmbeddedRequest(embeddedNotificatonRequest);
 780			RequestedAction[] actions = new RequestedAction[] { new RequestedAction(embeddedRequest) };
 781			return new RequestedEvent(decodeEventName(evtName, null), actions);
 782		}
 783
 784		int pos2 = value.indexOf(')');
 785		int pos3 = value.indexOf('(', pos2);
 786
 787		if (pos3 == -1) {
 788			value = value.substring(1, pos2);
 789			return new RequestedEvent(decodeEventName(evtName, null), decodeRequestedActions(value));
 790		}
 791
 792		int pos4 = value.indexOf(')', pos3);
 793		String parms = value.substring(pos3 + 1, pos4);
 794		value = value.substring(1, pos2);
 795
 796		return new RequestedEvent(decodeEventName(evtName, parms), decodeRequestedActions(value));
 797
 798	}
 799
 800	private void split(char splitChar, String value, List<String> arryList) {
 801		char[] charValue = value.toCharArray();
 802		int count = 0;
 803		for (char c : charValue) {
 804			count++;
 805			if (c == splitChar) {
 806				arryList.add(decdReqEveStrBuilder.toString());
 807				decdReqEveStrBuilder.delete(0, count);
 808				count = 0;
 809			} else {
 810				decdReqEveStrBuilder.append(c);
 811			}
 812		}
 813
 814		arryList.add(decdReqEveStrBuilder.toString());
 815		decdReqEveStrBuilder.delete(0, count);
 816	}
 817
 818	public EventName decodeEventName(String value, String param) throws ParseException {
 819		// eventName =[(packageName /"*")"/"]
 820		// (eventId /"all"/eventRange
 821		// /"*"/"#");for DTMF
 822		// ["@"(ConnectionId /"$"/"*")]
 823		this.split('/', value, this.decdEventName);
 824
 825		// String tokens[] = forwardSlashPattern.split(value, 0);
 826		try {
 827			int size = decdEventName.size();
 828			if (size == 1) {
 829				return new EventName(PackageName.AllPackages, MgcpEvent.factory(decdEventName.get(0)).withParm(param));
 830			} else if (size == 2) {
 831				int pos = decdEventName.get(1).indexOf(AMPERSAND);
 832				if (pos > 0) {
 833					String cid = (decdEventName.get(1).substring(pos + 1)).trim();
 834					ConnectionIdentifier connectionIdentifier = null;
 835					if ((ConnectionIdentifier.AnyConnection).toString().equals(cid)) {
 836						connectionIdentifier = ConnectionIdentifier.AnyConnection;
 837					} else if ((ConnectionIdentifier.AllConnections).toString().equals(cid)) {
 838						connectionIdentifier = ConnectionIdentifier.AllConnections;
 839					} else {
 840						connectionIdentifier = new ConnectionIdentifier(cid);
 841					}
 842					return new EventName(PackageName.factory(decdEventName.get(0)), MgcpEvent.factory(
 843							(decdEventName.get(1)).substring(0, pos)).withParm(param), connectionIdentifier);
 844				} else {
 845					return new EventName(PackageName.factory(decdEventName.get(0)), MgcpEvent.factory(
 846							decdEventName.get(1)).withParm(param));
 847				}
 848			} else if (size == 3) {
 849				int pos = decdEventName.get(2).indexOf(AMPERSAND);
 850				if (pos < 0) {
 851					throw new ParseException("Invalid token " + decdEventName.get(2), 0);
 852				}
 853
 854				String cid = (decdEventName.get(1)).substring(pos + 1);
 855				return new EventName(PackageName.factory(decdEventName.get(0)), MgcpEvent.factory(
 856						(decdEventName.get(1)).substring(0, pos)).withParm(param), new ConnectionIdentifier(cid));
 857			} else {
 858				throw new ParseException("Unexpected event name " + value, 0);
 859			}
 860		} finally {
 861			decdEventName.clear();
 862		}
 863
 864	}
 865
 866	public String encodeInfoCodeList(InfoCode[] infoCodes) {
 867		StringBuffer msg = new StringBuffer("");
 868		boolean first = true;
 869		for (int i = 0; i < infoCodes.length; i++) {
 870
 871			if (first) {
 872				first = false;
 873			} else {
 874				msg.append(',');
 875			}
 876
 877			InfoCode infoCode = infoCodes[i];
 878			switch (infoCode.getInfoCode()) {
 879			case (InfoCode.BEARER_INFORMATION):
 880				msg.append("B");
 881				break;
 882
 883			case (InfoCode.CALL_IDENTIFIER):
 884				msg.append("C");
 885				break;
 886
 887			case (InfoCode.CONNECTION_IDENTIFIER):
 888				msg.append("I");
 889				break;
 890
 891			case (InfoCode.NOTIFIED_ENTITY):
 892				msg.append("N");
 893				break;
 894
 895			case (InfoCode.REQUEST_IDENTIFIER):
 896				msg.append("X");
 897				break;
 898
 899			case (InfoCode.LOCAL_CONNECTION_OPTIONS):
 900				msg.append("L");
 901				break;
 902
 903			case (InfoCode.CONNECTION_MODE):
 904				msg.append("M");
 905				break;
 906
 907			case (InfoCode.REQUESTED_EVENTS):
 908				msg.append("R");
 909				break;
 910
 911			case (InfoCode.SIGNAL_REQUESTS):
 912				msg.append("S");
 913				break;
 914
 915			case (InfoCode.DIGIT_MAP):
 916				msg.append("D");
 917				break;
 918
 919			case (InfoCode.OBSERVED_EVENTS):
 920				msg.append("O");
 921				break;
 922
 923			case (InfoCode.CONNECTION_PARAMETERS):
 924				msg.append("P");
 925				break;
 926
 927			case (InfoCode.REASON_CODE):
 928				msg.append("E");
 929				break;
 930
 931			case (InfoCode.SPECIFIC_ENDPOINT_ID):
 932				msg.append("Z");
 933				break;
 934
 935			case (InfoCode.QUARANTINE_HANDLING):
 936				msg.append("Q");
 937				break;
 938
 939			case (InfoCode.DETECT_EVENTS):
 940				msg.append("T");
 941				break;
 942
 943			case (InfoCode.REMOTE_CONNECTION_DESCRIPTOR):
 944				msg.append("RC");
 945				break;
 946
 947			case (InfoCode.LOCAL_CONNECTION_DESCRIPTOR):
 948				msg.append("LC");
 949				break;
 950
 951			case (InfoCode.CAPABILITIES):
 952				msg.append("A");
 953				break;
 954
 955			case (InfoCode.EVENT_STATES):
 956				msg.append("ES");
 957				break;
 958
 959			case (InfoCode.RESTART_METHOD):
 960				msg.append("RM");
 961				break;
 962
 963			case (InfoCode.RESTART_DELAY):
 964				msg.append("RD");
 965				break;
 966
 967			default:
 968				logger.error("The InfoCode " + infoCode + " is not supported");
 969				break;
 970			}
 971		}
 972		return msg.toString();
 973	}
 974
 975	public InfoCode[] decodeInfoCodeList(String value) throws ParseException {
 976		String tokens[] = commaPattern.split(value.trim(), 0);
 977		InfoCode[] infoCodes = new InfoCode[tokens.length];
 978		for (int i = 0; i < tokens.length; i++) {
 979			infoCodes[i] = decodeInfoCode(tokens[i]);
 980		}
 981		return infoCodes;
 982	}
 983
 984	private InfoCode decodeInfoCode(String value) throws ParseException {
 985		value = value.trim();
 986		if (value.equalsIgnoreCase("B")) {
 987			return InfoCode.BearerInformation;
 988		}
 989
 990		else if (value.equalsIgnoreCase("C")) {
 991			return InfoCode.CallIdentifier;
 992		}
 993
 994		else if (value.equalsIgnoreCase("I")) {
 995			return InfoCode.ConnectionIdentifier;
 996		}
 997
 998		else if (value.equalsIgnoreCase("N")) {
 999			return InfoCode.NotifiedEntity;
1000		}
1001
1002		else if (value.equalsIgnoreCase("X")) {
1003			return InfoCode.RequestIdentifier;
1004		}
1005
1006		else if (value.equalsIgnoreCase("L")) {
1007			return InfoCode.LocalConnectionOptions;
1008		}
1009
1010		else if (value.equalsIgnoreCase("M")) {
1011			return InfoCode.ConnectionMode;
1012		}
1013
1014		else if (value.equalsIgnoreCase("R")) {
1015			return InfoCode.RequestedEvents;
1016		}
1017
1018		else if (value.equalsIgnoreCase("S")) {
1019			return InfoCode.SignalRequests;
1020		}
1021
1022		else if (value.equalsIgnoreCase("D")) {
1023			return InfoCode.DigitMap;
1024		}
1025
1026		else if (value.equalsIgnoreCase("O")) {
1027			return InfoCode.ObservedEvents;
1028		}
1029
1030		else if (value.equalsIgnoreCase("P")) {
1031			return InfoCode.ConnectionParameters;
1032		}
1033
1034		else if (value.equalsIgnoreCase("E")) {
1035			return InfoCode.ReasonCode;
1036		}
1037
1038		else if (value.equalsIgnoreCase("Z")) {
1039			return InfoCode.SpecificEndpointID;
1040		}
1041
1042		else if (value.equalsIgnoreCase("Q")) {
1043			return InfoCode.QuarantineHandling;
1044		}
1045
1046		else if (value.equalsIgnoreCase("T")) {
1047			return InfoCode.DetectEvents;
1048		}
1049
1050		else if (value.equalsIgnoreCase("RC")) {
1051			return InfoCode.RemoteConnectionDescriptor;
1052		}
1053
1054		else if (value.equalsIgnoreCase("LC")) {
1055			return InfoCode.LocalConnectionDescriptor;
1056		}
1057
1058		else if (value.equalsIgnoreCase("A")) {
1059			return InfoCode.Capabilities;
1060		}
1061
1062		else if (value.equalsIgnoreCase("ES")) {
1063			return InfoCode.EventStates;
1064		}
1065
1066		else if (value.equalsIgnoreCase("RM")) {
1067			return InfoCode.RestartMethod;
1068		}
1069
1070		else if (value.equalsIgnoreCase("RD")) {
1071			return InfoCode.RestartDelay;
1072		}
1073
1074		else {
1075			throw new ParseException("Extension action not suported", 0);
1076		}
1077	}
1078
1079	public CapabilityValue[] decodeCapabilityList(String value) throws ParseException {
1080		String tokens[] = commaPattern.split(value.trim(), 0);
1081		CapabilityValue[] capabilityValues = new CapabilityValue[tokens.length];
1082		for (int i = 0; i < tokens.length; i++) {
1083			capabilityValues[i] = decodeCapability(tokens[i]);
1084		}
1085		return capabilityValues;
1086
1087	}
1088
1089	public String encodeCapabilityList(CapabilityValue[] c) {
1090		StringBuffer s = new StringBuffer("");
1091		boolean first = true;
1092		for (int i = 0; i < c.length; i++) {
1093			if (first) {
1094				first = false;
1095			} else {
1096				s.append(",");
1097			}
1098			s.append(encodeCapability(c[i]));
1099		}
1100		return s.toString();
1101	}
1102
1103	public String encodeCapability(CapabilityValue c) {
1104		StringBuffer s = new StringBuffer("");
1105
1106		switch (c.getCapabilityValueType()) {
1107		case CapabilityValue.LOCAL_OPTION_VALUE:
1108			LocalOptVal localOptVal = (LocalOptVal) c;
1109			LocalOptionValue localOptionValue = localOptVal.getLocalOptionValue();
1110			s.append(encodeLocalOptionVale(localOptionValue));
1111			break;
1112
1113		case CapabilityValue.SUPPORTED_PACKAGES:
1114			s.append("v:");
1115			SupportedPackages supportedPackages = (SupportedPackages) c;
1116			PackageName[] packageNameList = supportedPackages.getSupportedPackageNames();
1117			s.append(encodePackageNameList(packageNameList));
1118			break;
1119
1120		case CapabilityValue.SUPPORTED_MODES:
1121			s.append("m:");
1122			SupportedModes supportedModes = (SupportedModes) c;
1123			ConnectionMode[] connectionModeList = supportedModes.getSupportedModes();
1124			s.append(encodeConnectionModeList(connectionModeList));
1125			break;
1126		}
1127
1128		return s.toString();
1129	}
1130
1131	public String encodeConnectionModeList(ConnectionMode[] connectionModeList) {
1132		StringBuffer s = new StringBuffer("");
1133		boolean first = true;
1134		for (int i = 0; i < connectionModeList.length; i++) {
1135			if (first) {
1136				first = false;
1137			} else {
1138				s.append(";");
1139			}
1140			s.append(connectionModeList[i].toString());
1141
1142		}
1143		return s.toString();
1144	}
1145
1146	public String encodePackageNameList(PackageName[] packageNameList) {
1147		StringBuffer s = new StringBuffer("");
1148		boolean first = true;
1149		for (int i = 0; i < packageNameList.length; i++) {
1150			if (first) {
1151				first = false;
1152			} else {
1153				s.append(";");
1154			}
1155			s.append(packageNameList[i].toString());
1156
1157		}
1158		return s.toString();
1159	}
1160
1161	public PackageName[] decodePackageNameList(String value) {
1162		String[] packages = semiColonPattern.split(value, 0);
1163		PackageName[] supportedPackageNames = new PackageName[packages.length];
1164		for (int i = 0; i < packages.length; i++) {
1165			PackageName p = PackageName.factory(packages[i]);
1166			supportedPackageNames[i] = p;
1167		}
1168
1169		return supportedPackageNames;
1170	}
1171
1172	public CapabilityValue decodeCapability(String value) throws ParseException {
1173
1174		CapabilityValue capabilityValue = null;
1175		int pos = value.indexOf(':');
1176		if (pos < 0) {
1177			throw new ParseException("Invalid value for EncryptionData: " + value, 0);
1178		}
1179
1180		String key = value.substring(0, pos).trim();
1181		String capability = value.substring(pos + 1).trim();
1182
1183		if ("a".equals(key)) {
1184			String[] codecs = semiColonPattern.split(capability, 0);
1185			CompressionAlgorithm compressionAlgorithm = new CompressionAlgorithm(codecs);
1186			capabilityValue = new LocalOptVal(compressionAlgorithm);
1187
1188		} else if ("b".equals(key)) {
1189			String[] bandwidthRange = dashPattern.split(capability, 0);
1190			int lower = Integer.parseInt(bandwidthRange[0]);
1191			int upper = lower;
1192			if (bandwidthRange.length == 2) {
1193				upper = Integer.parseInt(bandwidthRange[1]);
1194			}
1195
1196			Bandwidth bandwidth = new Bandwidth(lower, upper);
1197			capabilityValue = new LocalOptVal(bandwidth);
1198
1199		} else if ("p".equals(key)) {
1200			String[] packetizationRange = dashPattern.split(capability, 0);
1201			int lower = Integer.parseInt(packetizationRange[0]);
1202			int upper = lower;
1203			if (packetizationRange.length == 2) {
1204				upper = Integer.parseInt(packetizationRange[1]);
1205			}
1206
1207			PacketizationPeriod packetizationPeriod = new PacketizationPeriod(lower, upper);
1208			capabilityValue = new LocalOptVal(packetizationPeriod);
1209		} else if ("e".equals(key)) {
1210			if ("on".equals(capability)) {
1211				capabilityValue = new LocalOptVal(EchoCancellation.EchoCancellationOn);
1212			} else {
1213				capabilityValue = new LocalOptVal(EchoCancellation.EchoCancellationOff);
1214			}
1215		} else if ("s".equals(key)) {
1216			if ("on".equals(capability)) {
1217				capabilityValue = new LocalOptVal(SilenceSuppression.SilenceSuppressionOn);
1218			} else {
1219				capabilityValue = new LocalOptVal(SilenceSuppression.SilenceSuppressionOff);
1220			}
1221		} else if ("gc".equals(key)) {
1222			int gainControl = 0;
1223
1224			try {
1225				gainControl = Integer.parseInt(capability);
1226			} catch (NumberFormatException ne) {
1227				// Ignore
1228			}
1229			capabilityValue = new LocalOptVal(new GainControl(gainControl));
1230
1231		} else if ("t".equals(key)) {
1232			byte typeOfService = 0;
1233
1234			try {
1235				typeOfService = Byte.parseByte(capability);
1236			} catch (NumberFormatException ne) {
1237				// Ignore
1238			}
1239			capabilityValue = new LocalOptVal(new TypeOfService(typeOfService));
1240		} else if ("r".equals(key)) {
1241			if ("g".equals(capability)) {
1242				capabilityValue = new LocalOptVal(ResourceReservation.Guaranteed);
1243			} else if ("cl".equals(capability)) {
1244				capabilityValue = new LocalOptVal(ResourceReservation.ControlledLoad);
1245			} else if ("be".equals(capability)) {
1246				capabilityValue = new LocalOptVal(ResourceReservation.BestEffort);
1247			}
1248		} else if ("k".equals(key)) {
1249			EncryptionMethod encryptionMethod = decodeEncryptionMethod(capability);
1250			capabilityValue = new LocalOptVal(encryptionMethod);
1251		} else if ("nt".equals(key)) {
1252			TypeOfNetwork typeOfNetwork = decodeTypeOfNetwork(capability);
1253			capabilityValue = new LocalOptVal(typeOfNetwork);
1254		} else if ("v".equals(key)) {
1255			PackageName[] supportedPackageNames = decodePackageNameList(capability);
1256			capabilityValue = new SupportedPackages(supportedPackageNames);
1257		} else if ("m".equals(key)) {
1258			String[] modes = semiColonPattern.split(capability, 0);
1259			ConnectionMode[] supportedConnectionModes = new ConnectionMode[modes.length];
1260			for (int i = 0; i < modes.length; i++) {
1261				ConnectionMode c = decodeConnectionMode(modes[i]);
1262				supportedConnectionModes[i] = c;
1263			}
1264			capabilityValue = new SupportedModes(supportedConnectionModes);
1265		}
1266
1267		return capabilityValue;
1268	}
1269
1270	public RequestedAction[] decodeRequestedActions(String value) throws ParseException {
1271		// requestedActions =requestedAction 0*(","0*(WSP)requestedAction)
1272		String tokens[] = commaPattern.split(value, 0);
1273		RequestedAction[] actions = new RequestedAction[tokens.length];
1274		for (int i = 0; i < tokens.length; i++) {
1275			actions[i] = decodeRequestedAction(tokens[i]);
1276		}
1277		return actions;
1278	}
1279
1280	public RequestedAction decodeRequestedAction(String value) throws ParseException {
1281		// requestedAction ="N"/"A"/"D"/"S"/"I"/"K"
1282		// /"E""("EmbeddedRequest ")"
1283		// /ExtensionAction
1284		value = value.trim();
1285		if (value.equalsIgnoreCase("N")) {
1286			return RequestedAction.NotifyImmediately;
1287		} else if (value.equalsIgnoreCase("A")) {
1288			return RequestedAction.Accumulate;
1289		} else if (value.equalsIgnoreCase("S")) {
1290			return RequestedAction.Swap;
1291		} else if (value.equalsIgnoreCase("I")) {
1292			return RequestedAction.Ignore;
1293		} else if (value.equalsIgnoreCase("K")) {
1294			return RequestedAction.KeepSignalsActive;
1295		} else if (value.equalsIgnoreCase("D")) {
1296			return RequestedAction.TreatAccordingToDigitMap;
1297		} else if (value.equalsIgnoreCase("E")) {
1298			return new RequestedAction(decodeEmbeddedRequest(value));
1299		} else if (value.equalsIgnoreCase("X")) {
1300			// X is RequestIdentifier and we have already taken care of this.
1301			// Ignore here
1302			return RequestedAction.Ignore;
1303		} else {
1304			throw new ParseException("Extension action not suported", 0);
1305		}
1306	}
1307
1308	private String getEvent(String s) {
1309		char[] c = s.toCharArray();
1310
1311		String command = "";
1312		int start = 0;
1313		int end = 0;
1314
1315		int paraenthisis = 0;
1316
1317		boolean first = true;
1318		for (int i = 0; i < c.length; i++) {
1319			if (c[i] == '(') {
1320				paraenthisis++;
1321				if (first) {
1322					first = false;
1323					start = i;
1324					command = String.valueOf(c[i - 1]);
1325				}
1326			} else if (c[i] == ')') {
1327				paraenthisis--;
1328			}
1329
1330			if (!first && paraenthisis == 0) {
1331				end = i + 1;
1332				break;
1333				// command ends
1334			}
1335		}
1336
1337		// System.out.println("Command = " + command + " Start = " + start + "
1338		// end = " + end);
1339		return s.substring(0, end);
1340	}
1341
1342	public String encodeEmbeddedRequest(EmbeddedRequest embeddedRequest) {
1343		StringBuffer s = new StringBuffer("");
1344		boolean first = true;
1345
1346		RequestedEvent[] requestedEventList = embeddedRequest.getEmbeddedRequestList();
1347		if (requestedEventList != null) {
1348			if (first) {
1349				first = false;
1350			} else {
1351				s.append(",");
1352			}
1353
1354			s.append("R(").append(encodeRequestedEvents(requestedEventList)).append(")");
1355		}
1356
1357		EventName[] eventNameList = embeddedRequest.getEmbeddedSignalRequest();
1358		if (eventNameList != null) {
1359			if (first) {
1360				first = false;
1361			} else {
1362				s.append(",");
1363			}
1364			s.append("S(").append(encodeEventNames(eventNameList)).append(")");
1365		}
1366		DigitMap digitMap = embeddedRequest.getEmbeddedDigitMap();
1367		if (digitMap != null) {
1368			if (first) {
1369				first = false;
1370			} else {
1371				s.append(",");
1372			}
1373			s.append("D(").append(digitMap.toString()).append(")");
1374		}
1375		return s.toString();
1376	}
1377
1378	public EmbeddedRequest decodeEmbeddedRequest(String value) throws ParseException {
1379		// EmbeddedRequest =("R""("EmbeddedRequestList ")"
1380		// [","0*(WSP)"S""("EmbeddedSignalRequest ")"]
1381		// [","0*(WSP)"D""("EmbeddedDigitMap ")"])
1382		// /("S""("EmbeddedSignalRequest ")"
1383		// [","0*(WSP)"D""("EmbeddedDigitMap ")"])
1384		// /("D""("EmbeddedDigitMap ")")
1385
1386		RequestedEvent[] requestedEvents = null;
1387		EventName[] signalEvents = null;
1388		DigitMap digitMap = null;
1389
1390		while (value.length() > 0) {
1391			String temp = this.getEvent(value);
1392			value = value.substring(temp.length(), value.length());
1393
1394			if (temp.startsWith(",")) {
1395				temp = temp.substring(1, temp.length());
1396			}
1397
1398			if (temp.startsWith("R")) {
1399				temp = temp.substring(2, temp.length() - 1);
1400				requestedEvents = decodeRequestedEventList(temp);
1401			} else if (temp.startsWith("S")) {
1402				temp = temp.substring(2, temp.length() - 1);
1403				signalEvents = decodeEventNames(temp);
1404			} else if (temp.startsWith("D")) {
1405				temp = temp.substring(2, temp.length() - 1);
1406				digitMap = new DigitMap(temp);
1407			}
1408		}
1409
1410		return new EmbeddedRequest(requestedEvents, signalEvents, digitMap);
1411	}
1412
1413	public EventName[] decodeEventNames(String value) throws ParseException {
1414		String tokens[] = commaPattern.split(value, 0);
1415		EventName[] events = new EventName[tokens.length];
1416		for (int i = 0; i < tokens.length; i++) {
1417			String name = null;
1418			String parm = null;
1419
1420			int pos = tokens[i].indexOf('(');
1421			if (pos > 0) {
1422				name = tokens[i].substring(0, pos);
1423				parm = tokens[i].substring(pos + 1, tokens[i].length() - 1);
1424			} else {
1425				name = tokens[i];
1426			}
1427			events[i] = decodeEventName(name, parm);
1428		}
1429		return events;
1430	}
1431
1432	public String encodeEventNames(EventName[] events) {
1433		StringBuffer s = new StringBuffer("");
1434		boolean first = true;
1435		for (EventName e : events) {
1436			if (first) {
1437				first = false;
1438			} else {
1439				s.append(',');
1440			}
1441			s.append(encodeEventName(e));
1442		}
1443		return s.toString();
1444	}
1445
1446	public String encodeEventName(EventName e) {
1447		StringBuffer s = new StringBuffer("");
1448		s.append(e.getPackageName().toString()).append('/').append(e.getEventIdentifier().getName());
1449		if (e.getConnectionIdentifier() != null) {
1450			s.append(AMPERSAND).append(e.getConnectionIdentifier().toString());
1451		}
1452		if (e.getEventIdentifier().getParms() != null) {
1453			s.append('(').append(e.getEventIdentifier().getParms()).append(')');
1454		}
1455		return s.toString();
1456	}
1457
1458	/**
1459	 * Creates EndpointIdentifier object from givent endpont's name.
1460	 * 
1461	 * @param name
1462	 *            the name of the given endpoint.
1463	 * @return EdnpointIdentifier object.
1464	 */
1465	public EndpointIdentifier decodeEndpointIdentifier(String name) {
1466		try {
1467			this.split(AMPERSAND, name, list);
1468			String[] s = new String[list.size()];
1469			list.toArray(s);
1470			return new EndpointIdentifier(s[0], s[1]);
1471		} finally {
1472			list.clear();
1473		}
1474	}
1475
1476	public String encodeEndpointIdentifier(EndpointIdentifier e) {
1477		String s = e.getLocalEndpointName();
1478		if (e.getDomainName() != null) {
1479			s += "@" + e.getDomainName();
1480		}
1481		return s;
1482	}
1483
1484	public EndpointIdentifier[] decodeEndpointIdentifiers(String name) {
1485		String[] s = commaPattern.split(name, 0);
1486		EndpointIdentifier[] endpointIdentifiers = new EndpointIdentifier[s.length];
1487		for (int i = 0; i < s.length; i++) {
1488			endpointIdentifiers[i] = decodeEndpointIdentifier(s[i]);
1489		}
1490
1491		return endpointIdentifiers;
1492	}
1493
1494	public String encodeEndpointIdentifiers(EndpointIdentifier[] endpointIdentifierList) {
1495		StringBuffer msg = new StringBuffer("");
1496		boolean first = true;
1497		for (int i = 0; i < endpointIdentifierList.length; i++) {
1498			if (first) {
1499				first = false;
1500			} else {
1501				msg.append(",");
1502			}
1503			msg.append(encodeEndpointIdentifier(endpointIdentifierList[i]));
1504		}
1505		return msg.toString();
1506
1507	}
1508
1509	public ReturnCode decodeReturnCode(int code) throws ParseException {
1510		switch (code) {
1511		case ReturnCode.CAS_SIGNALING_PROTOCOL_ERROR:
1512			return ReturnCode.CAS_Signaling_Protocol_Error;
1513		case ReturnCode.CONNECTION_WAS_DELETED:
1514			return ReturnCode.Connection_Was_Deleted;
1515		case ReturnCode.ENDPOINT_HAS_NO_DIGIT_MAP:
1516			return ReturnCode.Endpoint_Has_No_Digit_Map;
1517		case ReturnCode.ENDPOINT_INSUFFICIENT_RESOURCES:
1518			return ReturnCode.Endpoint_Insufficient_Resources;
1519		case ReturnCode.ENDPOINT_IS_RESTARTING:
1520			return ReturnCode.Endpoint_Is_Restarting;
1521		case ReturnCode.ENDPOINT_NOT_READY:
1522			return ReturnCode.Endpoint_Not_Ready;
1523		case ReturnCode.ENDPOINT_REDIRECTED:
1524			return ReturnCode.Endpoint_Redirected;
1525		case ReturnCode.ENDPOINT_UNKNOWN:
1526			return ReturnCode.Endpoint_Unknown;
1527		case ReturnCode.GATEWAY_CANNOT_DETECT_REQUESTED_EVENT:
1528			return ReturnCode.Gateway_Cannot_Detect_Requested_Event;
1529		case ReturnCode.GATEWAY_CANNOT_GENERATE_REQUESTED_SIGNAL:
1530			return ReturnCode.Gateway_Cannot_Generate_Requested_Signal;
1531		case ReturnCode.GATEWAY_CANNOT_SEND_SPECIFIED_ANNOUNCEMENT:
1532			return ReturnCode.Gateway_Cannot_Send_Specified_Announcement;
1533		case ReturnCode.INCOMPATIBLE_PROTOCOL_VERSION:
1534			return ReturnCode.Incompatible_Protocol_Version;
1535		case ReturnCode.INCORRECT_CONNECTION_ID:
1536			return ReturnCode.Incorrect_Connection_ID;
1537		case ReturnCode.INSUFFICIENT_BANDWIDTH:
1538			return ReturnCode.Insufficient_Bandwidth;
1539		case ReturnCode.INSUFFICIENT_BANDWIDTH_NOW:
1540			return ReturnCode.Insufficient_Bandwidth_Now;
1541		case ReturnCode.INSUFFICIENT_RESOURCES_NOW:
1542			return ReturnCode.Insufficient_Resources_Now;
1543		case ReturnCode.INTERNAL_HARDWARE_FAILURE:
1544			return ReturnCode.Internal_Hardware_Failure;
1545		case ReturnCode.INTERNAL_INCONSISTENCY_IN_LOCALCONNECTIONOPTIONS:
1546			return ReturnCode.Internal_Inconsistency_In_LocalConnectionOptions;
1547		case ReturnCode.MISSING_REMOTECONNECTIONDESCRIPTOR:
1548			return ReturnCode.Missing_RemoteConnectionDescriptor;
1549		case ReturnCode.NO_SUCH_EVENT_OR_SIGNAL:
1550			return ReturnCode.No_Such_Event_Or_Signal;
1551		case ReturnCode.PHONE_OFF_HOOK:
1552			return ReturnCode.Phone_Off_Hook;
1553		case ReturnCode.PHONE_ON_HOOK:
1554			return ReturnCode.Phone_On_Hook;
1555		case ReturnCode.PROTOCOL_ERROR:
1556			return ReturnCode.Protocol_Error;
1557		case ReturnCode.TRANSACTION_BEING_EXECUTED:
1558			return ReturnCode.Transaction_Being_Executed;
1559		case ReturnCode.TRANSACTION_EXECUTED_NORMALLY:
1560			return ReturnCode.Transaction_Executed_Normally;
1561		case ReturnCode.TRANSIENT_ERROR:
1562			return ReturnCode.Transient_Error;
1563		case ReturnCode.TRUNK_GROUP_FAILURE:
1564			return ReturnCode.Trunk_Group_Failure;
1565		case ReturnCode.UNKNOWN_CALL_ID:
1566			return ReturnCode.Unknown_Call_ID;
1567		case ReturnCode.UNKNOWN_EXTENSION_IN_LOCALCONNECTIONOPTIONS:
1568			return ReturnCode.Unknown_Extension_In_LocalConnectionOptions;
1569		case ReturnCode.UNKNOWN_OR_ILLEGAL_COMBINATION_OF_ACTIONS:
1570			return ReturnCode.Unknown_Or_Illegal_Combination_Of_Actions;
1571		case ReturnCode.UNRECOGNIZED_EXTENSION:
1572			return ReturnCode.Unrecognized_Extension;
1573		case ReturnCode.UNSUPPORTED_OR_INVALID_MODE:
1574			return ReturnCode.Unsupported_Or_Invalid_Mode;
1575		case ReturnCode.UNSUPPORTED_OR_UNKNOWN_PACKAGE:
1576			return ReturnCode.Unsupported_Or_Unknown_Package;
1577		default:
1578			// TODO: 0xx should be treated as response acknowledgement.
1579			if ((code > 99) && (code < 200))
1580				return (ReturnCode.Transaction_Being_Executed);
1581			else if ((code > 199) && code < 300)
1582				return (ReturnCode.Transaction_Executed_Normally);
1583			else if ((code > 299) && code < 400)
1584				return (R

Large files files are truncated, but you can click here to view the full file