Java tutorial
/* * Copyright 2012 Devoteam http://www.devoteam.com * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * * This file is part of Multi-Protocol Test Suite (MTS). * * Multi-Protocol Test Suite (MTS) is free software: you can redistribute * it and/or modify it under the terms of the GNU General Public License * as published by the Free Software Foundation, either version 3 of the * License. * * Multi-Protocol Test Suite (MTS) is distributed in the hope that it will * be useful, but WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Multi-Protocol Test Suite (MTS). * If not, see <http://www.gnu.org/licenses/>. * */ package com.devoteam.srit.xmlloader.diameter; import com.devoteam.srit.xmlloader.diameter.dictionary.AvpDef; import com.devoteam.srit.xmlloader.diameter.dictionary.Dictionary; import com.devoteam.srit.xmlloader.diameter.dictionary.TypeDef; import com.devoteam.srit.xmlloader.core.Parameter; import com.devoteam.srit.xmlloader.core.Runner; import com.devoteam.srit.xmlloader.core.exception.ExecutionException; import com.devoteam.srit.xmlloader.core.exception.ParsingException; import com.devoteam.srit.xmlloader.core.log.GlobalLogger; import com.devoteam.srit.xmlloader.core.log.TextEvent; import com.devoteam.srit.xmlloader.core.log.TextEvent.Topic; import com.devoteam.srit.xmlloader.core.protocol.Msg; import com.devoteam.srit.xmlloader.core.protocol.Stack; import com.devoteam.srit.xmlloader.core.utils.Utils; import dk.i1.diameter.AVP; import dk.i1.diameter.AVPInterface; import dk.i1.diameter.AVP_Float32; import dk.i1.diameter.AVP_Float64; import dk.i1.diameter.AVP_Grouped; import dk.i1.diameter.AVP_Integer32; import dk.i1.diameter.AVP_Integer64; import dk.i1.diameter.AVP_OctetString; import dk.i1.diameter.AVP_Time; import dk.i1.diameter.AVP_Unsigned32; import dk.i1.diameter.AVP_Unsigned64; import dk.i1.diameter.Message; import gp.utils.arrays.Array; import gp.utils.arrays.DefaultArray; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Iterator; import java.util.LinkedList; import org.dom4j.Element; /** * * @author gpasquiers */ public class MsgDiamCommon extends Msg { /** diameter message object */ private Message message; /** Creates a new instance */ public MsgDiamCommon(Stack stack) { super(stack); } /** Creates a new instance */ public MsgDiamCommon(Stack stack, Message aMessage) { this(stack); message = aMessage; setListenpoint(StackDiamCommon.listenpoint); } /** Returns the diameter message of MsgDiameter */ public Message getMessage() { return message; } //----------------------------------------------------------------------------------------- // generic methods for protocol request type result retransmission, transaction and session //----------------------------------------------------------------------------------------- /** * Return true if the message is a request else return false */ @Override public boolean isRequest() { return message.hdr.isRequest(); } /** * Get the type of the message * Used for message filtering with "type" attribute and for statistic counters */ @Override public String getType() { return getCodeString() + ":" + message.hdr.command_code + ""; } /** get the command as a label from the dictionary */ private String getCodeString() { /** commandCode */ String codeString; try { codeString = Dictionary.getInstance() .getCommandDefByCode(message.hdr.command_code, Integer.toString(message.hdr.application_id)) .get_name(); } catch (Exception e) { codeString = "Unknown"; } return codeString; } /** Get the complete type of this message*/ @Override public String getTypeComplete() throws Exception { return getType(); } /** * Get the result of the message (null if request) * Used for message filtering with "result" attribute and for statistic counters */ @Override public String getResult() throws Exception { // get Result-Code value Parameter var = getParameter("avp.268.value"); if (var.length() > 0) { return (String) var.get(0); } // get Experimental-Result:Experimental-Result-Code var = getParameter("avp.297.298.value"); if (var != null && var.length() > 0) { return (String) var.get(0); } return null; } /** Get the complete result of this answer (null if request) */ @Override public String getResultComplete() throws Exception { return getResult(); } /** * Tell whether the message shall begin a new session * (= false by default) */ @Override public boolean beginSession() throws Exception { String status = getResult(); if (status != null && (!status.equals(""))) { int pos = status.lastIndexOf(":"); if (pos > 0) { status = status.substring(pos + 1); } int statusCode = new Integer(status).intValue(); if (statusCode < 2000 && statusCode >= 3000) { return false; } } String type = getType(); if ("Session-Termination:275".equalsIgnoreCase(type)) { return false; } // get Session-Id:263 Parameter var = getParameter("avp.263.value"); if ((var != null) && (var.length() > 0)) { return true; } return false; } /** * Tell whether the message shall end a session * (= false by default) */ @Override public boolean endSession() throws Exception { String type = getType(); if ("Session-Termination:275".equalsIgnoreCase(type)) { return true; } if ("Accounting:271".equalsIgnoreCase(type)) { // get Accounting-Record-Type:480 AVP Parameter var = getParameter("avp.480.value"); if ((var != null) && (var.length() > 0)) { String strvalue = (String) var.get(0); int intVal = new Integer(strvalue).intValue(); // value STOP_RECORD:4 if (intVal == 4) { return true; } } } if ("Credit-Control:272".equalsIgnoreCase(type)) { // get CC-Request-Type:416 AVP Parameter var = getParameter("avp.416.value"); if ((var != null) && (var.length() > 0)) { String strvalue = (String) var.get(0); int intVal = new Integer(strvalue).intValue(); // value TERMINATION_REQUEST:3 if (intVal == 3) { return true; } } } return false; } //------------------------------------------------- // methods for the encoding / decoding of the message //------------------------------------------------- /** * encode the message to binary data */ @Override public byte[] encode() { return message.encode(); } /** decode the message from binary data */ @Override public void decode(byte[] data) throws Exception { Message message = new Message(); message.decode(data); this.message = message; } //--------------------------------------------------------------------- // methods for the XML display / parsing of the message //--------------------------------------------------------------------- /** Returns a short description of the message. Used for logging as INFO level */ /** This methods HAS TO be quick to execute for performance reason */ @Override public String toShortString() throws Exception { String ret = super.toShortString(); ret += "\n"; ret += "<HEADER "; String applicationId = Integer.toString(message.hdr.application_id); ret += "applicationId=\"" + getApplicationIdString(applicationId) + ":" + message.hdr.application_id + "\" "; ret += "hopByHop=\"" + message.hdr.hop_by_hop_identifier + "\" "; ret += "endToEnd=\"" + message.hdr.end_to_end_identifier + "\""; ret += "/>"; return ret; } /** get the applicationId as a label from the dictionary */ private String getApplicationIdString(String applicationId) { String applicationIdString; try { applicationIdString = Dictionary.getInstance().getApplication(applicationId).get_name(); } catch (Exception e) { applicationIdString = "Unknown"; } return applicationIdString; } /** * prints as String an avp and it's sub-avps (recursive) */ private String avpToXml(AVP avp, int indent, String applicationId) throws Exception { String ret = ""; // retrieve the vendorId code String vendorIdCode = Integer.toString(avp.vendor_id); // retrieve the AvpDef object from the dictionary AvpDef avpDef = Dictionary.getInstance().getAvpDefByCodeVendorIdORCode(avp.code, applicationId, vendorIdCode); // retrieve the dictionary type TypeDef typeDef = getAVPType(avpDef); String typeDico = null; if (typeDef != null) { typeDico = typeDef.get_type_name(); } if (avpDef != null && avpDef.getGroupedAvpNameList().size() > 0) { typeDico = "Grouped"; } // retrieve the base type (using top-parent recursively) String typeBase = getAVPTypeBase(typeDico, applicationId); ret += Utils.indent(indent) + "<avp"; // display the AVP label and code long code = avp.code & 0xFFFFFFFFL; String label = "Unknown"; if (avpDef != null) { label = avpDef.get_name(); } String name = label + ":" + Long.toString(code); ret += " code=\"" + name + "\""; // display the AVP value; try { String value = getAVPValue(avp, avpDef, applicationId, typeDico, typeBase); if (value != null) { ret += " value=\"" + value + "\""; } } catch (Exception e) { // case when there is an exception : we assume type=Binary byte[] val = new AVP_OctetString(avp).queryValue(); Array array = new DefaultArray(val); String value = Array.toHexString(array); if (value != null) { ret += " value=\"" + value + "\""; } typeDico = "Binary"; GlobalLogger.instance().getApplicationLogger().warn(TextEvent.Topic.PROTOCOL, e, "Decoding : error while trying to decode AVP : \"" + code + "\" because the AVP type in the dictionary is not correct."); } // display the AVP vendor Id if (avp.vendor_id != 0) { ret += " vendorId=\""; ret += getVendorIdString(avp.vendor_id, applicationId) + ":" + avp.vendor_id + "\""; } // display the AVP type and flags if (typeDico != null) { ret += " type=\"" + typeDico + "\""; } else { ret += " type=\"" + typeBase + "\""; } ret += " m=\"" + avp.isMandatory() + "\""; ret += " p=\"" + avp.isPrivate() + "\""; // managed the "Grouped" AVP : display recursively the list of sub-AVPs if (typeDico != null && typeDico.equalsIgnoreCase("grouped")) { ret += ">\n"; AVP_Grouped gavp = new AVP_Grouped(avp); AVP[] tavp = gavp.queryAVPs(); for (int i = 0; i < tavp.length; i++) { ret += avpToXml(tavp[i], indent + 1, applicationId); } ret += Utils.indent(indent) + "</avp>\n"; } else { ret += "/>\n"; } return ret; } /** get the enumeration value as a label from the dictionary */ private String getEnumerationString(AvpDef avpDef, long code) { String enumString = null; try { if (avpDef != null) { enumString = avpDef.getEnumNameByCode(Long.toString(code)); } } catch (Exception e) { enumString = "Unknown"; } return enumString; } /** get the vendor Id value as a label from the dictionary */ private String getVendorIdString(int code, String applicationId) { String vendorIdString; try { vendorIdString = Dictionary.getInstance().getVendorDefByCode(code, applicationId).get_name(); } catch (Exception e) { vendorIdString = "Unknown"; } return vendorIdString; } /** get the type for an AVP according to the dictionary */ private TypeDef getAVPType(AvpDef avpDef) throws Exception { TypeDef typeDef = null; if (avpDef != null) { typeDef = avpDef.get_type(); } return typeDef; } /** get the type base for an AVP according to the dictionary */ private String getAVPTypeBase(String typeDico, String applicationId) throws Exception { TypeDef typeDef = MsgDiameterParser.getInstance().parse_AVPType(typeDico, applicationId); String typeBase = "Binary"; while (typeDef != null && typeDef.get_type_parent() != null) { typeDef = typeDef.get_type_parent(); } if (typeDef != null) { typeBase = typeDef.get_type_name(); } return typeBase; } /** get the value for an AVP according to the dictionary */ private String getAVPValue(AVP avp, AvpDef avpDef, String applicationId, String typeDico, String typeBase) throws Exception { String label = null; String value = null; if ("Grouped".equalsIgnoreCase(typeDico) || "Grouped".equalsIgnoreCase(typeBase)) { return null; } else if ("IPAddress".equalsIgnoreCase(typeDico) || "IPAddress".equalsIgnoreCase(typeBase)) { byte[] val = new AVP_OctetString(avp).queryValue(); if (val.length == 4 || val.length == 16) { value = Utils.toIPAddress(val); } else { throw new ExecutionException("Decoding : bad value for the type \"IPAddress\" for the AVP."); } } else if ("Address".equalsIgnoreCase(typeDico) || "Address".equalsIgnoreCase(typeBase)) { byte[] val = new AVP_OctetString(avp).queryValue(); if (val.length == 4 || val.length == 16) { value = Utils.toIPAddress(val); } else { throw new ExecutionException("Decoding : bad value for the type \"Address\" for the AVP."); } } else if ("Time".equalsIgnoreCase(typeDico) || "Time".equalsIgnoreCase(typeBase)) { // this method is buggous ! //Date date = new AVP_Time(avp).queryDate(); long secondSince1970 = new AVP_Time(avp).querySecondsSince1970() & 0xFFFFFFFFL; Date date = new Date(secondSince1970 * 1000); SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss:SSS"); value = format.format(date); } else if ("UTF8String".equalsIgnoreCase(typeDico) || "UTF8String".equalsIgnoreCase(typeBase)) { byte[] val = (new AVP_OctetString(avp)).queryValue(); value = new String(val); } // base types else if ("OctetString".equalsIgnoreCase(typeBase)) { byte[] val = (new AVP_OctetString(avp)).queryValue(); value = new String(val); } else if ("Integer32".equalsIgnoreCase(typeBase)) { int val = (new AVP_Integer32(avp)).queryValue(); label = getEnumerationString(avpDef, val); value = Long.toString(val); } else if ("Integer64".equalsIgnoreCase(typeBase)) { long val = (new AVP_Integer64(avp)).queryValue(); label = getEnumerationString(avpDef, val); value = Long.toString(val); } else if ("Unsigned32".equalsIgnoreCase(typeBase)) { long val = new AVP_Unsigned32(avp).queryValue() & 0xFFFFFFFFL; label = getEnumerationString(avpDef, val); value = Long.toString(val); } else if ("Unsigned64".equalsIgnoreCase(typeBase)) { long val = new AVP_Unsigned64(avp).queryValue() & 0xFFFFFFFFFFFFFFFFL; label = getEnumerationString(avpDef, val); value = Long.toString(val); } else if ("Float32".equalsIgnoreCase(typeBase)) { float result = new AVP_Float32(avp).queryValue(); value = Float.toString(result); } else if ("Float64".equalsIgnoreCase(typeBase)) { double result = new AVP_Float64(avp).queryValue(); value = Double.toString(result); } else if ("Binary".equalsIgnoreCase(typeBase)) { byte[] val = new AVP_OctetString(avp).queryValue(); Array array = new DefaultArray(val); value = Array.toHexString(array); } else { // case when there is a decoding problem : we assume type=Binary byte[] val = new AVP_OctetString(avp).queryValue(); Array array = new DefaultArray(val); value = Array.toHexString(array); } if (typeDico != null) { // case of vendorId type : Auth-Application-Id: or Acct-Application-Id if (typeDico.equalsIgnoreCase("appId")) { label = this.getApplicationIdString(value); } // case of vendorId type : Vendor-Id: or Supported-Vendor-Id: if (typeDico.equalsIgnoreCase("vendorId")) { label = this.getVendorIdString(Integer.parseInt(value), applicationId); } } // display the value the not "Grouped" AVP String ret = ""; if (label != null) { ret += label + ":"; } ret += value; return ret; } private String headerToXml() throws Exception { String ret = "<header "; ret += "request=\"" + message.hdr.isRequest() + "\" "; ret += "command=\""; ret += getCodeString() + ":"; ret += message.hdr.command_code + "\" "; ret += "applicationId=\""; String applicationId = Integer.toString(message.hdr.application_id); ret += getApplicationIdString(applicationId) + ":"; ret += message.hdr.application_id + "\" "; ret += "hopByHop=\"" + message.hdr.hop_by_hop_identifier + "\" "; ret += "endToEnd=\"" + message.hdr.end_to_end_identifier + "\" "; ret += "p=\"" + message.hdr.isProxiable() + "\" "; ret += "e=\"" + message.hdr.isError() + "\" "; ret += "r=\"" + message.hdr.isRetransmit() + "\" "; ret += "/>\n"; return ret; } /** * Convert the message to XML document */ @Override public String toXml() throws Exception { String xml = headerToXml(); String applicationId = Integer.toString(message.hdr.application_id); Iterable<AVP> iterable = message.avps(); Iterator<AVP> iterator = iterable.iterator(); while (iterator.hasNext()) { AVP avp = iterator.next(); xml += avpToXml(avp, 0, applicationId); } return xml; } /** * Parse the message from XML element */ @Override public void parseFromXml(Boolean request, Element root, Runner runner) throws Exception { this.message = MsgDiameterParser.getInstance().parseMsgFromXml(request, root); // DEPRECATED begin String server = root.attributeValue("server"); if (server != null) { GlobalLogger.instance().logDeprecatedMessage(root.getName() + " server=\"xxx\" .../", "sendMessageDiameter remoteUrl=\"xxx\" .../"); this.setRemoteUrl(server); } // DEPRECATED end } //------------------------------------------------------ // method for the "setFromMessage" <parameter> operation //------------------------------------------------------ /** * Get a parameter from the message */ @Override public Parameter getParameter(String path) throws Exception { Parameter var = super.getParameter(path); if (var != null) { return var; } var = new Parameter(); path = path.trim(); String[] params = Utils.splitPath(path); if (params.length > 1 && params[0].equalsIgnoreCase("header")) { //----------------------------------------------------------- header:request - if (params[1].equalsIgnoreCase("request")) { var.add(Boolean.toString(message.hdr.isRequest())); } //----------------------------------------------------------- header:error - else if (params[1].equalsIgnoreCase("error")) { var.add(Boolean.toString(message.hdr.isError())); } //----------------------------------------------------------- header:proxiable - else if (params[1].equalsIgnoreCase("proxiable")) { var.add(Boolean.toString(message.hdr.isProxiable())); } //----------------------------------------------------------- header:retransmit - else if (params[1].equalsIgnoreCase("retransmit")) { var.add(Boolean.toString(message.hdr.isRetransmit())); } //----------------------------------------------------------------- header:command - else if (params[1].equalsIgnoreCase("command")) { String command = Integer.toString(message.hdr.command_code); command = getCodeString() + ":" + command; var.add(command); } //----------------------------------------------------------- header:applicationId - else if (params[1].equalsIgnoreCase("applicationId")) { String appliID = Integer.toString(message.hdr.application_id); appliID = getApplicationIdString(appliID) + ":" + appliID; var.add(appliID); } //---------------------------------------------------------------- header:endToEnd - else if (params[1].equalsIgnoreCase("endToEnd")) { var.add(Integer.toString(message.hdr.end_to_end_identifier)); } //---------------------------------------------------------------- header:hopByHop - else if (params[1].equalsIgnoreCase("hopByHop")) { var.add(Integer.toString(message.hdr.hop_by_hop_identifier)); } else { Parameter.throwBadPathKeywordException(path); } } // default case : //------------------------------------------------------------------- AVPs: xxx:yyy:value - else { int i = 1; if ((params.length > 0) && !("avp".equalsIgnoreCase(params[0]))) { i = 0; Parameter.throwBadPathKeywordException(path); GlobalLogger.instance().logDeprecatedMessage("setFromMessage value=xxx.yyy", "setFromMessage value=avp.xxx.yyy"); throw new Exception(); } LinkedList<AVP> baseAvps = null; LinkedList<AVP> tempAvps = null; Iterator<AVP> baseIterator = message.avps().iterator(); LinkedList<AVP> validAvps = new LinkedList<AVP>(); while (i < params.length - 1) { if (baseAvps != null) { baseAvps = new LinkedList<AVP>(); Iterator<AVP> tmpIterator = tempAvps.iterator(); while (tmpIterator.hasNext()) { AVP anAvp = tmpIterator.next(); if (getAvpStringValue(anAvp, null) == null) { AVP[] avpTab = (new AVP_Grouped(anAvp)).queryAVPs(); for (int j = 0; j < avpTab.length; j++) { baseAvps.add(avpTab[j]); } } } baseIterator = baseAvps.iterator(); } while (baseIterator.hasNext()) { AVP avp = baseIterator.next(); String applicationId = Integer.toString(message.hdr.application_id); if (matchAVP_Keyword(avp, params[i], applicationId)) { validAvps.add(avp); } } tempAvps = validAvps; baseAvps = validAvps; validAvps = new LinkedList<AVP>(); i++; } Iterator<AVP> iterator = baseAvps.iterator(); while (iterator.hasNext()) { AVP avp = iterator.next(); String applicationId = Integer.toString(message.hdr.application_id); String value = getParameterForKeyword(avp, params[params.length - 1], path, applicationId); var.add(value); } } return var; } // get the value the parameter from keyword (setFromMessage) private String getParameterForKeyword(AVP avp, String keyword, String path, String applicationId) throws Exception { String value = null; if (keyword.equalsIgnoreCase("code")) { long val = avp.code & 0xFFFFFFFFL; value = Long.toString(val); } else if (keyword.equalsIgnoreCase("value")) { value = getAvpStringValue(avp, null); } else if (keyword.equalsIgnoreCase("binary")) { byte[] binary = new AVP_OctetString(avp).queryValue(); Array array = new DefaultArray(binary); value = Array.toHexString(array); } else if (keyword.equalsIgnoreCase("type")) { String vendorIdCode = Long.toString(avp.vendor_id & 0xFFFFFFFFL); // retrieve the type of avp AvpDef avpDef = Dictionary.getInstance().getAvpDefByCodeVendorIdORCode(avp.code, applicationId, vendorIdCode); // retrieve the dictionary type TypeDef typeDef = getAVPType(avpDef); if (typeDef != null) { value = typeDef.get_type_name(); } if (avpDef != null && avpDef.getGroupedAvpNameList().size() > 0) { value = "Grouped"; } } else if (keyword.equalsIgnoreCase("vendorId")) { if (avp.vendor_id != 0) { value = getVendorIdString(avp.vendor_id, applicationId) + ":"; value += Integer.toString(avp.vendor_id); } } else if (keyword.equalsIgnoreCase("vendor")) { value = Boolean.toString(avp.isVendorSpecific()); } else if (keyword.equalsIgnoreCase("mandatory")) { value = Boolean.toString(avp.isMandatory()); } else if (keyword.equalsIgnoreCase("private")) { value = Boolean.toString(avp.isPrivate()); } else { // case keyword is a type (integer32, unsigned64, octetstring, utf8string, ....) value = getAvpStringValue(avp, keyword); } return value; } // test whether a AVP matches a given keyword private boolean matchAVP_Keyword(AVP avp, String keyword, String applicationId) throws Exception { String vendorId = Integer.toString(avp.vendor_id); int pos = keyword.lastIndexOf(":"); if (pos >= 0) { String codeLabel = keyword.substring(0, pos); String codeInt = keyword.substring(pos + 1); int code = Integer.parseInt(codeInt); AvpDef avpDef = Dictionary.getInstance().getAvpDefByCodeVendorIdORCode(code, applicationId, vendorId); if (code == avp.code) { if (avpDef != null && !codeLabel.equalsIgnoreCase(avpDef.get_name())) { GlobalLogger.instance().getApplicationLogger().warn(Topic.PROTOCOL, "SetFromMessage : For the AVP code, the label \"" + codeLabel + "\" does not match the code \"" + codeInt + "\" in the dictionary; " + "we assume the code is \"" + code + " and we are waiting the label \"" + avpDef.get_name() + "\"."); } return true; } } else { if (!Utils.isInteger(keyword)) { AvpDef avpDef = Dictionary.getInstance().getAvpDefByCodeVendorIdORCode(avp.code, applicationId, vendorId); if (avpDef != null) { String avpName = avpDef.get_name(); if (keyword.equals(avpName)) { return true; } } } else { long code = Long.parseLong(keyword) & 0xffffffffL; long avpCode = ((long) avp.code) & 0xffffffffL; if (code == avpCode) { return true; } } } return false; } /** returns the type of an AVP */ private String getAvpStringValue(AVP avp, String typeDico) throws Exception { String applicationId = Integer.toString(message.hdr.application_id); // retrieve the vendorId code String vendorIdCode = Integer.toString(avp.vendor_id); // retrieve the type of avp AvpDef avpDef = Dictionary.getInstance().getAvpDefByCodeVendorIdORCode(avp.code, applicationId, vendorIdCode); // retrieve the dictionary type TypeDef typeDef = getAVPType(avpDef); if (typeDico == null) { if (typeDef != null) { typeDico = typeDef.get_type_name(); } if (avpDef != null && avpDef.getGroupedAvpNameList().size() > 0) { typeDico = "Grouped"; } } // retrieve the base type (using top-parent recursively) String typeBase = getAVPTypeBase(typeDico, applicationId); // retrieve the value String value; try { value = getAVPValue(avp, avpDef, applicationId, typeDico, typeBase); } catch (Exception e) { // case when there is an exception : we assume type=Binary byte[] val = new AVP_OctetString(avp).queryValue(); Array array = new DefaultArray(val); value = Array.toHexString(array); GlobalLogger.instance().getApplicationLogger().warn(TextEvent.Topic.PROTOCOL, e, "Decoding : error for the AVP : \"" + avp.code + "\" because the AVP type in the dictionary is not compliant with the data : we display or return data as binary."); } return value; } }