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); } }
private static GXByteBuffer UpdateDataType(XmlNode node, GXDLMSXmlSettings s, int tag) { GXByteBuffer preData = null; switch ((DataType)(tag - GXDLMS.DATA_TYPE_OFFSET)) { case DataType.Array: s.data.SetUInt8(DataType.Array); preData = new GXByteBuffer(s.data); s.data.Size = 0; break; case DataType.Bcd: GXCommon.SetData(s.settings, s.data, DataType.Bcd, s.ParseShort(GetValue(node, s))); break; case DataType.BitString: GXCommon.SetData(s.settings, s.data, DataType.BitString, GetValue(node, s)); break; case DataType.Boolean: GXCommon.SetData(s.settings, s.data, DataType.Boolean, s.ParseShort(GetValue(node, s))); break; case DataType.Date: GXCommon.SetData(s.settings, s.data, DataType.Date, GXDLMSClient.ChangeType(GXCommon.HexToBytes(GetValue(node, s)), DataType.DateTime)); break; case DataType.DateTime: GXCommon.SetData(s.settings, s.data, DataType.DateTime, GXDLMSClient.ChangeType(GXCommon.HexToBytes(GetValue(node, s)), DataType.DateTime)); break; case DataType.Enum: GXCommon.SetData(s.settings, s.data, DataType.Enum, s.ParseShort(GetValue(node, s))); break; case DataType.Float32: GetFloat32(node, s); break; case DataType.Float64: GetFloat64(node, s); break; case DataType.Int16: GXCommon.SetData(s.settings, s.data, DataType.Int16, s.ParseShort(GetValue(node, s))); break; case DataType.Int32: GXCommon.SetData(s.settings, s.data, DataType.Int32, s.ParseInt(GetValue(node, s))); break; case DataType.Int64: GXCommon.SetData(s.settings, s.data, DataType.Int64, s.ParseLong(GetValue(node, s))); break; case DataType.Int8: GXCommon.SetData(s.settings, s.data, DataType.Int8, s.ParseShort(GetValue(node, s))); break; case DataType.None: GXCommon.SetData(s.settings, s.data, DataType.None, null); break; case DataType.OctetString: GetOctetString(node, s); break; case DataType.String: if (s.showStringAsHex) { GXCommon.SetData(s.settings, s.data, DataType.String, GXCommon.HexToBytes(GetValue(node, s))); } else { GXCommon.SetData(s.settings, s.data, DataType.String, GetValue(node, s)); } break; case DataType.StringUTF8: if (s.showStringAsHex) { GXCommon.SetData(s.settings, s.data, DataType.StringUTF8, GXCommon.HexToBytes(GetValue(node, s))); } else { GXCommon.SetData(s.settings, s.data, DataType.StringUTF8, GetValue(node, s)); } break; case DataType.Structure: s.data.SetUInt8(DataType.Structure); preData = new GXByteBuffer(s.data); s.data.Size = 0; break; case DataType.Time: GXCommon.SetData(s.settings, s.data, DataType.Time, GXDLMSClient.ChangeType(GXCommon.HexToBytes(GetValue(node, s)), DataType.DateTime)); break; case DataType.UInt16: GXCommon.SetData(s.settings, s.data, DataType.UInt16, s.ParseInt(GetValue(node, s))); break; case DataType.UInt32: GXCommon.SetData(s.settings, s.data, DataType.UInt32, s.ParseLong(GetValue(node, s))); break; case DataType.UInt64: GXCommon.SetData(s.settings, s.data, DataType.UInt64, s.ParseULong(GetValue(node, s))); break; case DataType.UInt8: GXCommon.SetData(s.settings, s.data, DataType.UInt8, s.ParseShort(GetValue(node, s))); break; default: throw new ArgumentException("Invalid node: " + node.Name); } return preData; }