private static void ReadNode(
XmlNode node, GXDLMSXmlSettings s)
{
int tag = 0;
String str;
if (s.OutputType == TranslatorOutputType.SimpleXml)
{
str = node.Name.ToLower();
}
else
{
str = node.Name;
}
if (s.command != Command.ConfirmedServiceError
|| s.tags.ContainsKey(str))
{
tag = s.tags[str];
}
ErrorCode err;
UInt32 value;
byte[] tmp;
GXByteBuffer preData = null;
if (s.command == Command.None)
{
if (!((s.settings.ClientAddress == 0 ||
s.settings.ServerAddress == 0) &&
GetFrame(node, s, tag) ||
tag == (int)TranslatorTags.PduDlms ||
tag == (int)TranslatorTags.PduCse))
{
GetCommand(node, s, tag);
}
}
else if (s.command == Command.Aarq ||
s.command == Command.Aare)
{
HandleAarqAare(node, s, tag);
}
else if (tag >= GXDLMS.DATA_TYPE_OFFSET)
{
if (tag == (int)DataType.DateTime + GXDLMS.DATA_TYPE_OFFSET)
{
preData = UpdateDateTime(node, s, preData);
}
else
{
preData = UpdateDataType(node, s, tag);
}
}
else if (s.command == Command.ConfirmedServiceError)
{
if (s.OutputType == TranslatorOutputType.StandardXml)
{
if (tag == (int)TranslatorTags.InitiateError)
{
s.attributeDescriptor.SetUInt8(1);
}
else
{
ServiceError se = TranslatorStandardTags.GetServiceError(str.Substring(2));
s.attributeDescriptor.SetUInt8(se);
s.attributeDescriptor.SetUInt8(TranslatorStandardTags.GetError(se, GetValue(node, s)));
}
}
else
{
if (tag == (int)TranslatorTags.ServiceError)
{
}
else
{
if (s.attributeDescriptor.Size == 0)
{
s.attributeDescriptor.SetUInt8((byte)s.ParseShort(GetValue(node, s)));
}
else
{
ServiceError se = TranslatorSimpleTags.GetServiceError(str);
s.attributeDescriptor.SetUInt8(se);
s.attributeDescriptor.SetUInt8(TranslatorSimpleTags.GetError(se, GetValue(node, s)));
}
}
}
}
else
{
switch (tag)
{
case (int)(Command.GetRequest) << 8 | (byte)GetCommandType.Normal:
case (int)(Command.GetRequest) << 8 | (byte)GetCommandType.NextDataBlock:
case (int)(Command.GetRequest) << 8 | (byte)GetCommandType.WithList:
case (int)(Command.SetRequest) << 8 | (byte)SetRequestType.Normal:
case (int)(Command.SetRequest) << 8 | (byte)SetRequestType.FirstDataBlock:
case (int)(Command.SetRequest) << 8 | (byte)SetRequestType.WithDataBlock:
case (int)(Command.SetRequest) << 8 | (byte)SetRequestType.WithList:
s.requestType = (byte)(tag & 0xF);
break;
case (int)(Command.GetResponse) << 8 | (byte)GetCommandType.Normal:
case (int)(Command.GetResponse) << 8 | (byte)GetCommandType.NextDataBlock:
case (int)(Command.GetResponse) << 8 | (byte)GetCommandType.WithList:
case (int)(Command.SetResponse) << 8 | (byte)SetResponseType.Normal:
case (int)(Command.SetResponse) << 8 | (byte)SetResponseType.DataBlock:
case (int)(Command.SetResponse) << 8 | (byte)SetResponseType.LastDataBlock:
case (int)(Command.SetResponse) << 8 | (byte)SetResponseType.WithList:
case (int)(Command.SetResponse) << 8 | (byte)SetResponseType.LastDataBlockWithList:
s.requestType = (byte)(tag & 0xF);
break;
case (int)(Command.ReadResponse) << 8 | (byte)SingleReadResponse.DataBlockResult:
++s.count;
s.requestType = (byte)(tag & 0xF);
break;
case (int)(Command.ReadRequest) << 8 | (byte)VariableAccessSpecification.ParameterisedAccess:
s.requestType = (byte)VariableAccessSpecification.ParameterisedAccess;
break;
case (int)(Command.ReadRequest) << 8 | (byte)VariableAccessSpecification.BlockNumberAccess:
s.requestType = (byte)VariableAccessSpecification.BlockNumberAccess;
++s.count;
break;
case (byte)(int)(Command.MethodRequest) << 8 | (byte)ActionRequestType.Normal:
s.requestType = (byte)(tag & 0xFF);
break;
case (byte)(int)(Command.MethodRequest) << 8 | (byte)ActionRequestType.NextBlock:
s.requestType = (byte)(tag & 0xFF);
break;
case (byte)(int)(Command.MethodRequest) << 8 | (byte)ActionRequestType.WithList:
s.requestType = (byte)(tag & 0xFF);
break;
case (byte)(int)(Command.MethodResponse) << 8 | (byte)ActionRequestType.Normal:
//MethodResponseNormal
s.requestType = (byte)(tag & 0xFF);
break;
case (int)(Command.ReadResponse) << 8 | (byte)SingleReadResponse.Data:
case (int)TranslatorTags.Data:
if (s.command == Command.ReadRequest
|| s.command == Command.ReadResponse
|| s.command == Command.GetRequest)
{
++s.count;
s.requestType = 0;
}
else if (s.command == Command.GetResponse ||
s.command == Command.MethodResponse)
{
s.data.SetUInt8(0); // Add status.
}
break;
case (int)TranslatorTags.Success:
++s.count;
s.attributeDescriptor.Add((byte)ErrorCode.Ok);
break;
case (int)TranslatorTags.DataAccessError:
++s.count;
s.attributeDescriptor.SetUInt8(1);
s.attributeDescriptor.SetUInt8(ValueOfErrorCode(s.OutputType, GetValue(node, s)));
break;
case (int)TranslatorTags.ListOfVariableAccessSpecification:
case (int)TranslatorTags.VariableAccessSpecification:
break;
case (int)TranslatorTags.ListOfData:
if (s.command == Command.AccessResponse
&& s.data.Size == 0)
{
// If access-request-specification is not given.
s.data.SetUInt8(0);
}
if (s.OutputType == TranslatorOutputType.SimpleXml
|| s.command != Command.WriteRequest)
{
GXCommon.SetObjectCount(node.ChildNodes.Count, s.data);
}
break;
case (int)Command.AccessResponse << 8 | (byte)AccessServiceCommandType.Get:
case (int)Command.AccessResponse << 8 | (byte)AccessServiceCommandType.Set:
case (int)Command.AccessResponse << 8 | (byte)AccessServiceCommandType.Action:
s.data.SetUInt8((byte)(0xFF & tag));
break;
case (int)TranslatorTags.DateTime:
preData = UpdateDateTime(node, s, preData);
break;
case (int)TranslatorTags.InvokeId:
value = (uint)s.ParseShort(GetValue(node, s));
if ((value & 0x80) != 0)
{
s.settings.Priority = Priority.High;
}
else
{
s.settings.Priority = Priority.Normal;
}
if ((value & 0x40) != 0)
{
s.settings.ServiceClass = ServiceClass.Confirmed;
}
else
{
s.settings.ServiceClass = ServiceClass.UnConfirmed;
}
s.settings.InvokeID = (byte)(value & 0xF);
break;
case (int)TranslatorTags.LongInvokeId:
value = (uint)s.ParseLong(GetValue(node, s));
if ((value & 0x80000000) != 0)
{
s.settings.Priority = Priority.High;
}
else
{
s.settings.Priority = Priority.Normal;
}
if ((value & 0x40000000) != 0)
{
s.settings.ServiceClass = ServiceClass.Confirmed;
}
else
{
s.settings.ServiceClass = ServiceClass.UnConfirmed;
}
s.settings.longInvokeID = (UInt16)(value & 0xFFFFFFF);
break;
case 0x88:
//ResponderACSERequirement
break;
case 0x80:
//RespondingAuthentication
s.settings.StoCChallenge = GXCommon.HexToBytes(GetValue(node, s));
break;
case (int)TranslatorTags.AttributeDescriptor:
break;
case (int)TranslatorTags.ClassId:
s.attributeDescriptor.SetUInt16((UInt16)s.ParseInt(GetValue(node, s)));
break;
case (int)TranslatorTags.InstanceId:
s.attributeDescriptor.Add(GXCommon.HexToBytes(GetValue(node, s)));
break;
case (int)TranslatorTags.AttributeId:
s.attributeDescriptor.SetUInt8((byte)s.ParseShort(GetValue(node, s)));
//Add AccessSelection.
if (s.command != Command.AccessRequest)
{
s.attributeDescriptor.SetUInt8(0);
}
break;
case (int)TranslatorTags.MethodInvocationParameters:
s.attributeDescriptor.SetUInt8(s.attributeDescriptor.Size - 1, 1);
break;
case (int)TranslatorTags.Selector:
s.attributeDescriptor.Set(GXCommon.HexToBytes(GetValue(node, s)));
break;
case (int)TranslatorTags.Parameter:
break;
case (int)TranslatorTags.LastBlock:
s.data.SetUInt8((byte)s.ParseShort(GetValue(node, s)));
break;
case (int)TranslatorTags.BlockNumber:
//BlockNumber
if (s.command == Command.GetRequest || s.command == Command.GetResponse)
{
s.data.SetUInt32((UInt32)s.ParseLong(GetValue(node, s)));
}
else
{
s.data.SetUInt16((UInt16)s.ParseInt(GetValue(node, s)));
}
break;
case (int)TranslatorTags.RawData:
//RawData
if (s.command == Command.GetResponse)
{
s.data.SetUInt8(0);
}
tmp = GXCommon.HexToBytes(GetValue(node, s));
GXCommon.SetObjectCount(tmp.Length, s.data);
s.data.Set(tmp);
break;
case (int)TranslatorTags.MethodDescriptor:
break;
case (int)TranslatorTags.MethodId:
s.attributeDescriptor.SetUInt8((byte)s.ParseShort(GetValue(node, s)));
//Add MethodInvocationParameters
s.attributeDescriptor.SetUInt8(0);
break;
case (int)TranslatorTags.Result:
case (int)TranslatorGeneralTags.AssociationResult:
//Result.
if (s.command == Command.GetRequest || s.requestType == 3)
{
GXCommon.SetObjectCount(node.ChildNodes.Count, s.attributeDescriptor);
}
else if (s.command == Command.MethodResponse || s.command == Command.SetResponse)
{
str = GetValue(node, s);
if (str != "")
{
s.attributeDescriptor.SetUInt8((byte)ValueOfErrorCode(s.OutputType, str));
}
}
else if (s.command == Command.AccessResponse)
{
str = GetValue(node, s);
if (str != "")
{
s.data.SetUInt8(ValueOfErrorCode(s.OutputType, str));
}
}
break;
case (int)TranslatorTags.Reason:
s.reason = (ReleaseRequestReason)Enum.Parse(typeof(ReleaseRequestReason), GetValue(node, s));
break;
case (int)TranslatorTags.ReturnParameters:
s.attributeDescriptor.SetUInt8(1);
break;
case (int)TranslatorTags.AccessSelection:
s.attributeDescriptor.SetUInt8(s.attributeDescriptor.Size - 1, 1);
break;
case (int)TranslatorTags.Value:
break;
case (int)TranslatorTags.AccessSelector:
s.data.SetUInt8((byte)s.ParseShort(GetValue(node, s)));
break;
case (int)TranslatorTags.AccessParameters:
break;
case (int)TranslatorTags.AttributeDescriptorList:
GXCommon.SetObjectCount(node.ChildNodes.Count, s.attributeDescriptor);
break;
case (int)TranslatorTags.AttributeDescriptorWithSelection:
case (int)Command.AccessRequest << 8 | (byte)AccessServiceCommandType.Get:
case (int)Command.AccessRequest << 8 | (byte)AccessServiceCommandType.Set:
case (int)Command.AccessRequest << 8 | (byte)AccessServiceCommandType.Action:
s.attributeDescriptor.SetUInt8((byte)(tag & 0xFF));
break;
case (int)Command.ReadRequest << 8 | (byte)VariableAccessSpecification.VariableName:
case (int)Command.WriteRequest << 8 | (byte)VariableAccessSpecification.VariableName:
case (int)Command.WriteRequest << 8 | (byte)SingleReadResponse.Data:
if (s.command != Command.AccessRequest
&& s.command != Command.AccessResponse)
{
if (!(s.OutputType == TranslatorOutputType.StandardXml
&& tag == ((int)Command.WriteRequest << 8
| (int)SingleReadResponse.Data)))
{
if (s.requestType == 0xFF)
{
s.attributeDescriptor.SetUInt8(
VariableAccessSpecification.VariableName);
}
else
{
s.attributeDescriptor.SetUInt8(s.requestType);
s.requestType = 0xFF;
}
++s.count;
}
else
{
s.attributeDescriptor.SetUInt8((byte)s.count);
}
if (s.OutputType == TranslatorOutputType.SimpleXml)
{
s.attributeDescriptor.SetUInt16((UInt16)s.ParseShort(GetValue(node, s)));
}
else
{
str = GetValue(node, s);
if (!String.IsNullOrEmpty(str))
{
s.attributeDescriptor.SetInt16(Int16.Parse(str));
}
}
}
break;
case (int)TranslatorTags.Choice:
break;
case (int)Command.ReadResponse << 8
| (int)SingleReadResponse.DataAccessError:
err =
ValueOfErrorCode(s.OutputType, GetValue(node, s));
++s.count;
s.data.SetUInt8(1);
s.data.SetUInt8(err);
break;
case (int)TranslatorTags.NotificationBody:
break;
case (int)TranslatorTags.DataValue:
break;
case (int)TranslatorTags.AccessRequestBody:
break;
case (int)TranslatorTags.PduDlms:
break;
case (int)TranslatorTags.ListOfAccessRequestSpecification:
s.attributeDescriptor.SetUInt8((byte)node.ChildNodes.Count);
break;
case (int)TranslatorTags.AccessRequestSpecification:
break;
case (int)TranslatorTags.AccessRequestListOfData:
s.attributeDescriptor.SetUInt8((byte)node.ChildNodes.Count);
break;
case (int)TranslatorTags.AccessResponseBody:
break;
case (int)TranslatorTags.ListOfAccessResponseSpecification:
s.data.SetUInt8((byte)node.ChildNodes.Count);
break;
case (int)TranslatorTags.AccessResponseSpecification:
break;
case (int)TranslatorTags.AccessResponseListOfData:
// Add access-response-list-of-data. Optional
s.data.SetUInt8(0);
s.data.SetUInt8((byte)node.ChildNodes.Count);
break;
case (int)TranslatorTags.SingleResponse:
break;
default:
throw new ArgumentException("Invalid node: " + node.Name);
}
}
foreach (XmlNode childNode in node.ChildNodes)
{
if (childNode.NodeType == XmlNodeType.Element)
{
ReadNode(childNode, s);
}
}
if (preData != null)
{
GXCommon.SetObjectCount(node.ChildNodes.Count, preData);
preData.Set(s.data);
s.data.Size = 0;
s.data.Set(preData);
}
}