object IGXDLMSBase.GetValue(GXDLMSSettings settings, int index, int selector, object parameters) { if (index == 1) { return(this.LogicalName); } if (index == 2) { return(CommunicationSpeed); } if (index == 3) { GXByteBuffer data = new GXByteBuffer(); data.SetUInt8((byte)DataType.Array); //Add count int cnt = 0; if (InitialisationStrings != null) { cnt = InitialisationStrings.Length; } GXCommon.SetObjectCount(cnt, data); if (cnt != 0) { foreach (GXDLMSModemInitialisation it in InitialisationStrings) { data.SetUInt8((byte)DataType.Structure); data.SetUInt8((byte)3); //Count GXCommon.SetData(data, DataType.OctetString, ASCIIEncoding.ASCII.GetBytes(it.Request)); GXCommon.SetData(data, DataType.OctetString, ASCIIEncoding.ASCII.GetBytes(it.Response)); GXCommon.SetData(data, DataType.UInt16, it.Delay); } } return(data.Array()); } if (index == 4) { GXByteBuffer data = new GXByteBuffer(); data.SetUInt8((byte)DataType.Array); //Add count int cnt = 0; if (ModemProfile != null) { cnt = ModemProfile.Length; } GXCommon.SetObjectCount(cnt, data); if (cnt != 0) { foreach (string it in ModemProfile) { GXCommon.SetData(data, DataType.OctetString, ASCIIEncoding.ASCII.GetBytes(it)); } } return(data.Array()); } throw new ArgumentException("GetValue failed. Invalid attribute index."); }
object IGXDLMSBase.GetValue(GXDLMSSettings settings, ValueEventArgs e) { if (e.Index == 1) { return(GXCommon.LogicalNameToBytes(LogicalName)); } if (e.Index == 2) { GXByteBuffer data = new GXByteBuffer(); data.SetUInt8((byte)DataType.Array); if (Entries == null) { data.SetUInt8(0); } else { int cnt = Entries.Length; //Add count GXCommon.SetObjectCount(cnt, data); if (cnt != 0) { foreach (GXDLMSSpecialDay it in Entries) { data.SetUInt8((byte)DataType.Structure); data.SetUInt8((byte)3); //Count GXCommon.SetData(settings, data, DataType.UInt16, it.Index); if (settings.Standard == Standard.SaudiArabia) { GXCommon.SetData(settings, data, DataType.Date, it.Date); } else { GXCommon.SetData(settings, data, DataType.OctetString, it.Date); } GXCommon.SetData(settings, data, DataType.UInt8, it.DayId); } } } return(data.Array()); } e.Error = ErrorCode.ReadWriteDenied; return(null); }
/// <summary> /// Agree on one or more symmetric keys using the key agreement algorithm. /// </summary> /// <param name="client"> DLMS client that is used to generate action.</param> /// <param name="list"> List of keys.</param> /// <returns>Generated action.</returns> public byte[][] keyAgreement(GXDLMSClient client, List <KeyValuePair <GlobalKeyType, byte[]> > list) { if (list == null || list.Count == 0) { throw new ArgumentException("Invalid list. It is empty."); } GXByteBuffer bb = new GXByteBuffer(); bb.SetUInt8(DataType.Array); bb.SetUInt8((byte)list.Count); foreach (KeyValuePair <GlobalKeyType, byte[]> it in list) { bb.SetUInt8(DataType.Structure); bb.SetUInt8(2); GXCommon.SetData(client.Settings, bb, DataType.Enum, it.Key); GXCommon.SetData(client.Settings, bb, DataType.OctetString, it.Value); } return(client.Method(this, 3, bb.Array(), DataType.Array)); }
object IGXDLMSBase.GetValue(GXDLMSSettings settings, ValueEventArgs e) { if (e.Index == 1) { return(GXCommon.LogicalNameToBytes(LogicalName)); } if (e.Index == 2) { //If client set new value. if (!settings.IsServer && Scaler != 1 && Value != null) { DataType dt = base.GetDataType(2); if (dt == DataType.None && Value != null) { dt = GXCommon.GetDLMSDataType(Value.GetType()); //If user has set initial value. if (dt == DataType.String) { dt = DataType.None; } } object tmp; tmp = Convert.ToDouble(Value) / Scaler; if (dt != DataType.None) { tmp = Convert.ChangeType(tmp, GXCommon.GetDataType(dt)); } return(tmp); } return(Value); } if (e.Index == 3) { GXByteBuffer data = new GXByteBuffer(); data.SetUInt8((byte)DataType.Structure); data.SetUInt8(2); GXCommon.SetData(settings, data, DataType.Int8, scaler); GXCommon.SetData(settings, data, DataType.Enum, Unit); return(data.Array()); } e.Error = ErrorCode.ReadWriteDenied; return(null); }
object IGXDLMSBase.GetValue(GXDLMSSettings settings, ValueEventArgs e) { if (e.Index == 1) { return(GXCommon.LogicalNameToBytes(LogicalName)); } if (e.Index == 2) { GXByteBuffer bb = new GXByteBuffer(); bb.SetUInt8(DataType.Structure); bb.SetUInt8(3); GXCommon.SetData(settings, bb, DataType.OctetString, SystemTitle); GXCommon.SetData(settings, bb, DataType.UInt16, MacAddress); GXCommon.SetData(settings, bb, DataType.UInt8, LSapSelector); return(bb.Array()); } e.Error = ErrorCode.ReadWriteDenied; return(null); }
object IGXDLMSBase.GetValue(GXDLMSSettings settings, int index, int selector, object parameters) { if (index == 1) { return(this.LogicalName); } if (index == 2) { GXByteBuffer data = new GXByteBuffer(); data.SetUInt8((byte)DataType.Structure); data.SetUInt8(2); GXCommon.SetData(data, DataType.OctetString, ASCIIEncoding.ASCII.GetBytes(ExecutedScriptLogicalName)); //Time GXCommon.SetData(data, DataType.UInt16, ExecutedScriptSelector); //Time return(data.Array()); } if (index == 3) { return(this.Type); } if (index == 4) { GXByteBuffer data = new GXByteBuffer(); data.SetUInt8((byte)DataType.Array); if (ExecutionTime == null) { GXCommon.SetObjectCount(0, data); } else { GXCommon.SetObjectCount(ExecutionTime.Length, data); foreach (GXDateTime it in ExecutionTime) { data.SetUInt8((byte)DataType.Structure); data.SetUInt8((byte)2); //Count GXCommon.SetData(data, DataType.Time, it.Value); //Time GXCommon.SetData(data, DataType.Date, it.Value); //Date } } return(data.Array()); } throw new ArgumentException("GetValue failed. Invalid attribute index."); }
/// <summary> /// Returns Association View. /// </summary> private GXByteBuffer GetObjects(GXDLMSSettings settings, ValueEventArgs e) { int cnt = ObjectList.Count; GXByteBuffer data = new GXByteBuffer(); //Add count only for first time. if (settings.Index == 0) { settings.Count = (UInt16)cnt; data.SetUInt8((byte)DataType.Array); GXCommon.SetObjectCount(cnt, data); } ushort pos = 0; foreach (GXDLMSObject it in ObjectList) { ++pos; if (!(pos <= settings.Index)) { data.SetUInt8((byte)DataType.Structure); //Count data.SetUInt8((byte)4); //base address. GXCommon.SetData(settings, data, DataType.Int16, it.ShortName); //ClassID GXCommon.SetData(settings, data, DataType.UInt16, it.ObjectType); //Version GXCommon.SetData(settings, data, DataType.UInt8, it.Version); GXCommon.SetData(settings, data, DataType.OctetString, GXCommon.LogicalNameToBytes(it.LogicalName)); ++settings.Index; if (settings.IsServer) { //If PDU is full. if (!e.SkipMaxPduSize && data.Size >= settings.MaxPduSize) { break; } } } } return(data); }
/// <summary> /// Generate GMAC password from given challenge. /// </summary> /// <param name="challenge"></param> /// <returns></returns> public byte[] GenerateGmacPassword(byte[] challenge) { AesGcmParameter p = new AesGcmParameter(0x10, Gurux.DLMS.Enums.Security.Authentication, InvocationCounter, systemTitle, BlockCipherKey, AuthenticationKey); GXByteBuffer bb = new GXByteBuffer(); GXDLMSChippering.EncryptAesGcm(p, challenge); bb.SetUInt8(0x10); bb.SetUInt32(InvocationCounter); bb.Set(p.CountTag); return(bb.Array()); }
object IGXDLMSBase.GetValue(GXDLMSSettings settings, int index, int selector, object parameters) { if (index == 1) { return(this.LogicalName); } if (index == 2) { return(Value); } if (index == 3) { GXByteBuffer data = new GXByteBuffer(); data.SetUInt8((byte)DataType.Structure); data.SetUInt8(2); GXCommon.SetData(data, DataType.Int8, _scaler); GXCommon.SetData(data, DataType.Enum, Unit); return(data.Array()); } throw new ArgumentException("GetValue failed. Invalid attribute index."); }
private void TemplateDescriptionTb_Leave(object sender, EventArgs e) { try { DataType v; GXByteBuffer bb = new GXByteBuffer(); GXDLMSCompactData target = Target as GXDLMSCompactData; bb.SetUInt8(2); bb.SetUInt8(0); foreach (string it in TemplateDescriptionTb.Text.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)) { if (!Enum.TryParse <DataType>(it, out v)) { bb.Clear(); break; } bb.SetUInt8((byte)v); } byte[] tmp; if (bb.Size != 0) { bb.SetUInt8(1, (byte)(bb.Size - 2)); tmp = bb.Array(); } else { tmp = GXDLMSTranslator.HexToBytes(TemplateDescriptionTb.Text); } if (GXDLMSTranslator.ToHex(tmp) != GXDLMSTranslator.ToHex(target.TemplateDescription)) { target.TemplateDescription = tmp; Target.UpdateDirty(5, target.TemplateDescription); errorProvider1.SetError(TemplateDescriptionTb, Properties.Resources.ValueChangedTxt); } } catch (Exception ex) { MessageBox.Show(this, ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } }
static Object GetDayProfileTable(GXDLMSSettings settings, GXDLMSDayProfile[] target) { GXByteBuffer data = new GXByteBuffer(); data.SetUInt8((byte)DataType.Array); if (target == null) { //Add count GXCommon.SetObjectCount(0, data); } else { int cnt = target.Length; //Add count GXCommon.SetObjectCount(cnt, data); foreach (GXDLMSDayProfile it in target) { data.SetUInt8((byte)DataType.Structure); data.SetUInt8(2); GXCommon.SetData(settings, data, DataType.UInt8, it.DayId); data.SetUInt8((byte)DataType.Array); //Add count GXCommon.SetObjectCount(it.DaySchedules.Length, data); foreach (GXDLMSDayProfileAction action in it.DaySchedules) { data.SetUInt8((byte)DataType.Structure); data.SetUInt8(3); GXCommon.SetData(settings, data, DataType.OctetString, action.StartTime); GXCommon.SetData(settings, data, DataType.OctetString, GXCommon.LogicalNameToBytes(action.ScriptLogicalName)); GXCommon.SetData(settings, data, DataType.UInt16, action.ScriptSelector); } } } return(data.Array()); }
/// <summary> /// Code application context name. /// </summary> /// <param name="settings">DLMS settings.</param> /// <param name="data">Byte buffer where data is saved.</param> /// <param name="cipher">Is ciphering settings.</param> private static void GenerateApplicationContextName(GXDLMSSettings settings, GXByteBuffer data, GXICipher cipher) { //Application context name tag data.SetUInt8(((byte)BerType.Context | (byte)BerType.Constructed | (byte)PduType.ApplicationContextName)); //Len data.SetUInt8(0x09); data.SetUInt8(BerType.ObjectIdentifier); //Len data.SetUInt8(0x07); bool ciphered = cipher != null && cipher.IsCiphered(); if (settings.UseLogicalNameReferencing) { if (ciphered) { data.Set(GXCommon.LogicalNameObjectIdWithCiphering); } else { data.Set(GXCommon.LogicalNameObjectID); } } else { if (ciphered) { data.Set(GXCommon.ShortNameObjectIdWithCiphering); } else { data.Set(GXCommon.ShortNameObjectID); } } //Add system title if cipher or GMAC authentication is used.. if (!settings.IsServer && (ciphered || settings.Authentication == Authentication.HighGMAC)) { if (cipher.SystemTitle == null || cipher.SystemTitle.Length == 0) { throw new ArgumentNullException("SystemTitle"); } //Add calling-AP-title data.SetUInt8(((byte)BerType.Context | (byte)BerType.Constructed | 6)); //LEN data.SetUInt8((byte)(2 + cipher.SystemTitle.Length)); data.SetUInt8((byte)BerType.OctetString); //LEN data.SetUInt8((byte)cipher.SystemTitle.Length); data.Set(cipher.SystemTitle); } }
object IGXDLMSBase.GetValue(GXDLMSSettings settings, ValueEventArgs e) { if (e.Index == 1) { return(this.LogicalName); } if (e.Index == 2) { return(Value); } if (e.Index == 3) { GXByteBuffer data = new GXByteBuffer(); data.SetUInt8((byte)DataType.Structure); data.SetUInt8(2); GXCommon.SetData(settings, data, DataType.Int8, scaler); GXCommon.SetData(settings, data, DataType.Enum, Unit); return(data.Array()); } e.Error = ErrorCode.ReadWriteDenied; return(null); }
/// <summary> /// Removes X.509 v3 certificate from the server using entity. /// </summary> /// <param name="client">DLMS client that is used to generate action.</param> /// <param name="entity">Certificate entity type.</param> /// <param name="type">Certificate type.</param> /// <param name="systemTitle">System title.</param> /// <returns>Generated action.</returns> public byte[][] RemoveCertificateByEntity(GXDLMSClient client, CertificateEntity entity, CertificateType type, byte[] systemTitle) { GXByteBuffer bb = new GXByteBuffer(); bb.SetUInt8(DataType.Structure); bb.SetUInt8(2); //Add enum bb.SetUInt8(DataType.Enum); bb.SetUInt8(0); //Add certificate_identification_by_entity bb.SetUInt8(DataType.Structure); bb.SetUInt8(3); //Add certificate_entity bb.SetUInt8(DataType.Enum); bb.SetUInt8(entity); //Add certificate_type bb.SetUInt8(DataType.Enum); bb.SetUInt8(type); //system_title GXCommon.SetData(client.Settings, bb, DataType.OctetString, systemTitle); return(client.Method(this, 8, bb.Array(), DataType.Structure)); }
byte[] GetMulticastEntries(GXDLMSSettings settings) { GXByteBuffer bb = new GXByteBuffer(); bb.SetUInt8((byte)DataType.Array); if (MulticastEntries == null) { GXCommon.SetObjectCount(0, bb); } else { GXCommon.SetObjectCount(MulticastEntries.Length, bb); foreach (GXMacMulticastEntry it in MulticastEntries) { bb.SetUInt8((byte)DataType.Structure); bb.SetUInt8(2); GXCommon.SetData(settings, bb, DataType.Int8, it.Id); GXCommon.SetData(settings, bb, DataType.Int16, it.Members); } } return(bb.Array()); }
/// <summary> /// Copies the values of the objects to capture /// into the buffer by reading capture objects. /// </summary> public void Capture(GXDLMSServer server) { lock (this) { GXByteBuffer bb = new GXByteBuffer(); ValueEventArgs[] args = new ValueEventArgs[] { new ValueEventArgs(server, this, 2, 0, null) }; Buffer = null; server.PreGet(args); if (!args[0].Handled) { foreach (GXKeyValuePair <GXDLMSObject, GXDLMSCaptureObject> it in CaptureObjects) { ValueEventArgs e = new ValueEventArgs(server, it.Key, it.Value.AttributeIndex, 0, null); object value = (it.Key as IGXDLMSBase).GetValue(server.Settings, e); DataType dt = (it.Key as IGXDLMSBase).GetDataType(it.Value.AttributeIndex); if ((value is byte[] || value is GXByteBuffer[]) && (dt == DataType.Structure || dt == DataType.Array)) { GXByteBuffer tmp; if (value is byte[]) { tmp = new GXByteBuffer((byte[])value); } else { tmp = (GXByteBuffer)value; } CaptureArray(server, tmp, bb, it.Value.DataIndex - 1); } else { GXByteBuffer tmp = new GXByteBuffer(); GXCommon.SetData(server.Settings, tmp, dt, value); //If data is empty. if (tmp.Size == 1) { bb.SetUInt8(0); } else { tmp.Position = 1; bb.Set(tmp); } } } Buffer = bb.Array(); } server.PostGet(args); server.NotifyAction(args); server.NotifyPostAction(args); } }
/// <summary> /// Returns Association View. /// </summary> private GXByteBuffer GetObjects(GXDLMSSettings settings, ValueEventArgs e) { GXByteBuffer data = new GXByteBuffer(); //Add count only for first time. if (settings.Index == 0) { settings.Count = (UInt16)ObjectList.Count; data.SetUInt8((byte)DataType.Array); GXCommon.SetObjectCount(ObjectList.Count, data); } ushort pos = 0; foreach (GXDLMSObject it in ObjectList) { ++pos; if (!(pos <= settings.Index)) { data.SetUInt8((byte)DataType.Structure); data.SetUInt8((byte)4); //Count GXCommon.SetData(settings, data, DataType.UInt16, it.ObjectType); //ClassID GXCommon.SetData(settings, data, DataType.UInt8, it.Version); //Version //LN GXCommon.SetData(settings, data, DataType.OctetString, GXCommon.LogicalNameToBytes(it.LogicalName)); GetAccessRights(settings, it, e.Server, data); //Access rights. ++settings.Index; if (settings.IsServer) { //If PDU is full. if ((settings.NegotiatedConformance & Conformance.GeneralBlockTransfer) == 0 && !e.SkipMaxPduSize && data.Size >= settings.MaxPduSize) { break; } } } } return(data); }
private object GetImageActivateInfo(GXDLMSSettings settings) { GXByteBuffer data = new GXByteBuffer(); data.SetUInt8((byte)DataType.Array); //ImageActivateInfo is returned only after verification is succeeded. if (ImageTransferStatus != ImageTransferStatus.VerificationSuccessful || ImageActivateInfo == null) { GXCommon.SetObjectCount(0, data); } else { GXCommon.SetObjectCount(ImageActivateInfo.Length, data); foreach (GXDLMSImageActivateInfo it in ImageActivateInfo) { data.SetUInt8((byte)DataType.Structure); data.SetUInt8(3); GXCommon.SetData(settings, data, DataType.UInt32, it.Size); if (it.Identification == null) { GXCommon.SetData(settings, data, DataType.OctetString, null); } else { GXCommon.SetData(settings, data, DataType.OctetString, it.Identification); } if (it.Signature == null || it.Signature.Length == 0) { GXCommon.SetData(settings, data, DataType.OctetString, null); } else { GXCommon.SetData(settings, data, DataType.OctetString, it.Signature); } } } return(data.Array()); }
/// <summary> /// Returns captured objects. /// </summary> /// <param name="settings">DLMS settings.</param> /// <returns></returns> byte[] GetCaptureObjects(GXDLMSSettings settings) { GXByteBuffer data = new GXByteBuffer(); data.SetUInt8((byte)DataType.Array); //Add count GXCommon.SetObjectCount(CaptureObjects.Count, data); foreach (var it in CaptureObjects) { data.SetUInt8((byte)DataType.Structure); //Count data.SetUInt8(4); //ClassID GXCommon.SetData(settings, data, DataType.UInt16, it.Key.ObjectType); //LN GXCommon.SetData(settings, data, DataType.OctetString, GXCommon.LogicalNameToBytes(it.Key.LogicalName)); //Selected Attribute Index GXCommon.SetData(settings, data, DataType.Int8, it.Value.AttributeIndex); //Selected Data Index GXCommon.SetData(settings, data, DataType.UInt16, it.Value.DataIndex); } return(data.Array()); }
object IGXDLMSBase.GetValue(GXDLMSSettings settings, ValueEventArgs e) { if (e.Index == 1) { return(this.LogicalName); } if (e.Index == 2) { return((byte)Mode); } if (e.Index == 3) { int cnt = ListeningWindow.Count; GXByteBuffer data = new GXByteBuffer(); data.SetUInt8((byte)DataType.Array); //Add count GXCommon.SetObjectCount(cnt, data); if (cnt != 0) { foreach (var it in ListeningWindow) { data.SetUInt8((byte)DataType.Structure); data.SetUInt8((byte)2); //Count GXCommon.SetData(settings, data, DataType.OctetString, it.Key); //start_time GXCommon.SetData(settings, data, DataType.OctetString, it.Value); //end_time } } return(data.Array()); } if (e.Index == 4) { return(Status); } if (e.Index == 5) { return(NumberOfCalls); } if (e.Index == 6) { GXByteBuffer data = new GXByteBuffer(); data.SetUInt8((byte)DataType.Structure); //Add count GXCommon.SetObjectCount(2, data); GXCommon.SetData(settings, data, DataType.UInt8, NumberOfRingsInListeningWindow); GXCommon.SetData(settings, data, DataType.UInt8, NumberOfRingsOutListeningWindow); return(data.Array()); } e.Error = ErrorCode.ReadWriteDenied; return(null); }
private object GetImageActivateInfo(GXDLMSSettings settings) { GXByteBuffer data = new GXByteBuffer(); data.SetUInt8((byte)DataType.Array); if (ImageActivateInfo == null) { GXCommon.SetObjectCount(0, data); } else { GXCommon.SetObjectCount(ImageActivateInfo.Length, data); foreach (GXDLMSImageActivateInfo it in ImageActivateInfo) { data.SetUInt8((byte)DataType.Structure); data.SetUInt8(3); GXCommon.SetData(settings, data, DataType.UInt32, it.Size); if (it.Identification == null) { GXCommon.SetData(settings, data, DataType.OctetString, null); } else { GXCommon.SetData(settings, data, DataType.OctetString, ASCIIEncoding.ASCII.GetBytes(it.Identification)); } if (it.Signature == null || it.Signature.Length == 0) { GXCommon.SetData(settings, data, DataType.OctetString, null); } else { GXCommon.SetData(settings, data, DataType.OctetString, ASCIIEncoding.ASCII.GetBytes(it.Signature)); } } } return(data.Array()); }
object IGXDLMSBase.GetValue(GXDLMSSettings settings, int index, int selector, object parameters) { if (index == 1) { return(this.LogicalName); } if (index == 2) { return((byte)Mode); } if (index == 3) { int cnt = ListeningWindow.Count; GXByteBuffer data = new GXByteBuffer(); data.SetUInt8((byte)DataType.Array); //Add count GXCommon.SetObjectCount(cnt, data); if (cnt != 0) { foreach (var it in ListeningWindow) { data.SetUInt8((byte)DataType.Structure); data.SetUInt8((byte)2); //Count GXCommon.SetData(data, DataType.OctetString, it.Key); //start_time GXCommon.SetData(data, DataType.OctetString, it.Value); //end_time } } return(data.Array()); } if (index == 4) { return(Status); } if (index == 5) { return(NumberOfCalls); } if (index == 6) { GXByteBuffer data = new GXByteBuffer(); data.SetUInt8((byte)DataType.Structure); //Add count GXCommon.SetObjectCount(2, data); GXCommon.SetData(data, DataType.UInt8, NumberOfRingsInListeningWindow); GXCommon.SetData(data, DataType.UInt8, NumberOfRingsOutListeningWindow); return(data.Array()); } throw new ArgumentException("GetValue failed. Invalid attribute index."); }
void OnShowDialog(GXActionArgs arg) { if (InvokeRequired) { BeginInvoke(new ShowDialogEventHandler(OnShowDialog), arg).AsyncWaitHandle.WaitOne(); } else { GXTextDlg dlg = new GXTextDlg("Transfer token", "Token", "", typeof(byte[])); if (dlg.ShowDialog(this) == DialogResult.OK) { GXByteBuffer bb = new GXByteBuffer(); bb.SetUInt8((byte)DataType.OctetString); byte[] str = GXDLMSTranslator.HexToBytes(dlg.GetValue()); bb.SetUInt8((byte)str.Length); bb.Set(str); arg.Value = bb.Array(); } else { arg.Handled = true; } } }
private void AddEntry(GXDLMSSettings settings, GXScheduleEntry it, GXByteBuffer data) { data.SetUInt8((byte)DataType.Structure); data.SetUInt8(10); //Add index. data.SetUInt8((byte)DataType.UInt16); data.SetUInt16(it.Index); //Add enable. data.SetUInt8((byte)DataType.Boolean); data.SetUInt8((byte)(it.Enable ? 1 : 0)); //Add logical Name. data.SetUInt8((byte)DataType.OctetString); data.SetUInt8(6); if (it.Script == null) { data.Set(new byte[] { 0, 0, 0, 0, 0, 0 }); } else { data.Set(GXCommon.LogicalNameToBytes(it.Script.LogicalName)); } //Add script selector. data.SetUInt8((byte)DataType.UInt16); data.SetUInt16(it.ScriptSelector); //Add switch time. GXCommon.SetData(settings, data, DataType.OctetString, it.SwitchTime); //Add validity window. data.SetUInt8((byte)DataType.UInt16); data.SetUInt16(it.ValidityWindow); //Add exec week days. GXCommon.SetData(settings, data, DataType.BitString, GXBitString.ToBitString((byte)it.ExecWeekdays, 7)); //Add exec spec days. GXCommon.SetData(settings, data, DataType.BitString, it.ExecSpecDays); //Add begin date. GXCommon.SetData(settings, data, DataType.OctetString, it.BeginDate); //Add end date. GXCommon.SetData(settings, data, DataType.OctetString, it.EndDate); }
object IGXDLMSBase.GetValue(GXDLMSSettings settings, ValueEventArgs e) { if (ObjectList == null) { ObjectList = new GXDLMSObjectCollection(); } if (e.Index == 1) { return(this.LogicalName); } else if (e.Index == 2) { return(GetObjects(settings, e).Array()); } else if (e.Index == 3) { bool lnExists = ObjectList.FindBySN(this.ShortName) != null; //Add count int cnt = ObjectList.Count; if (!lnExists) { ++cnt; } GXByteBuffer data = new GXByteBuffer(); data.SetUInt8((byte)DataType.Array); GXCommon.SetObjectCount(cnt, data); foreach (GXDLMSObject it in ObjectList) { GetAccessRights(settings, it, data); } if (!lnExists) { GetAccessRights(settings, this, data); } return(data.Array()); } else if (e.Index == 4) { GXByteBuffer data = new GXByteBuffer(); GXCommon.SetData(settings, data, DataType.OctetString, SecuritySetupReference); return(data.Array()); } e.Error = ErrorCode.ReadWriteDenied; return(null); }
/// <summary> /// Get public key from private key. /// </summary> /// <param name="scheme">Used scheme.</param> /// <param name="privateKey">Private key bytes.</param> /// <returns>Public key.</returns> public GXPublicKey GetPublicKey() { GXBigInteger secret = new GXBigInteger(RawValue); GXCurve curve = new GXCurve(Scheme); GXEccPoint p = new GXEccPoint(curve.G.x, curve.G.y, new GXBigInteger(1)); p = GXEcdsa.JacobianMultiply(p, secret, curve.N, curve.A, curve.P); GXEcdsa.FromJacobian(p, curve.P); GXByteBuffer key = new GXByteBuffer(65); //Public key is un-compressed format. key.SetUInt8(4); byte[] tmp = p.x.ToArray(); key.Set(tmp, tmp.Length % 32, 32); tmp = p.y.ToArray(); key.Set(tmp, tmp.Length % 32, 32); return(GXPublicKey.FromRawBytes(key.Array())); }
private static void CaptureValue(GXDLMSServer server, GXByteBuffer tmp, GXByteBuffer bb) { GXByteBuffer tmp2 = new GXByteBuffer(); GXDataInfo info = new GXDataInfo(); object value = GXCommon.GetData(server.Settings, tmp, info); GXCommon.SetData(server.Settings, tmp2, info.Type, value); //If data is empty. if (tmp2.Size == 1) { bb.SetUInt8(0); } else { tmp2.Position = 1; bb.Set(tmp2); } }
byte[] GetSwitchTable(GXDLMSSettings settings) { GXByteBuffer bb = new GXByteBuffer(); bb.SetUInt8((byte)DataType.Array); if (SwitchTable == null) { GXCommon.SetObjectCount(0, bb); } else { GXCommon.SetObjectCount(SwitchTable.Length, bb); foreach (Int16 it in SwitchTable) { GXCommon.SetData(settings, bb, DataType.Int16, it); } } return(bb.Array()); }
private static void UpdateInterval(GXDLMSInterval interval, object[] value) { GXByteBuffer bb = new GXByteBuffer(); foreach (byte it in value) { bb.SetUInt8(it); } byte b = bb.GetUInt8(); interval.StartHour = (byte)(b & 0x1F); interval.IntervalTariff = (DefaultTariffBand)((b >> 5) & 0x3); interval.UseInterval = (b >> 7) != 0; interval.WeeklyActivation = (WeeklyActivation)bb.GetUInt16(); UInt16 v = bb.GetUInt16(); interval.SpecialDayMonth = (byte)(v & 0xF); interval.SpecialDay = (byte)((v >> 8) & 0xF); interval.SpecialDayEnabled = (v >> 15) != 0; }
object IGXDLMSBase.GetValue(GXDLMSSettings settings, ValueEventArgs e) { if (e.Index == 1) { return(GXCommon.LogicalNameToBytes(LogicalName)); } if (e.Index == 2) { GXByteBuffer data = new GXByteBuffer(); data.SetUInt8((byte)DataType.Array); GXCommon.SetObjectCount(Entries.Count, data); foreach (GXScheduleEntry it in Entries) { AddEntry(settings, it, data); } return(data.Array()); } e.Error = ErrorCode.ReadWriteDenied; return(null); }
///<summary> ///Retrieves the string that indicates the level of authentication, if any. ///</summary> private static void GetAuthenticationString(GXDLMSSettings settings, GXByteBuffer data) { //If authentication is used. if (settings.Authentication != Authentication.None) { //Add sender ACSE-requirements field component. data.SetUInt8((byte)BerType.Context | (byte)PduType.SenderAcseRequirements); data.SetUInt8(2); data.SetUInt8(BerType.BitString | BerType.OctetString); data.SetUInt8(0x80); data.SetUInt8((byte)BerType.Context | (byte)PduType.MechanismName); //Len data.SetUInt8(7); // OBJECT IDENTIFIER byte[] p = { (byte)0x60, (byte)0x85, (byte)0x74, (byte)0x05, (byte)0x08, (byte)0x02, (byte)settings.Authentication }; data.Set(p); //Add Calling authentication information. int len = 0; byte[] callingAuthenticationValue = null; if (settings.Authentication == Authentication.Low) { if (settings.Password != null) { callingAuthenticationValue = settings.Password; len = callingAuthenticationValue.Length; } } else { callingAuthenticationValue = settings.CtoSChallenge; len = callingAuthenticationValue.Length; } //0xAC data.SetUInt8((byte)BerType.Context | (byte)BerType.Constructed | (byte)PduType.CallingAuthenticationValue); //Len data.SetUInt8((byte)(2 + len)); //Add authentication information. data.SetUInt8((byte)BerType.Context); //Len. data.SetUInt8((byte)len); if (len != 0) { data.Set(callingAuthenticationValue); } } }
object IGXDLMSBase.GetValue(GXDLMSSettings settings, ValueEventArgs e) { if (ObjectList == null) { ObjectList = new GXDLMSObjectCollection(); } if (e.Index == 1) { return this.LogicalName; } else if (e.Index == 2) { return GetObjects(settings, e).Array(); } else if (e.Index == 3) { bool lnExists = ObjectList.FindBySN(this.ShortName) != null; //Add count int cnt = ObjectList.Count; if (!lnExists) { ++cnt; } GXByteBuffer data = new GXByteBuffer(); data.SetUInt8((byte)DataType.Array); GXCommon.SetObjectCount(cnt, data); foreach (GXDLMSObject it in ObjectList) { GetAccessRights(settings, it, data); } if (!lnExists) { GetAccessRights(settings, this, data); } return data.Array(); } else if (e.Index == 4) { GXByteBuffer data = new GXByteBuffer(); GXCommon.SetData(settings, data, DataType.OctetString, SecuritySetupReference); return data.Array(); } e.Error = ErrorCode.ReadWriteDenied; return null; }
private void GetAccessRights(GXDLMSSettings settings, GXDLMSObject item, GXByteBuffer data) { data.SetUInt8((byte)DataType.Structure); data.SetUInt8((byte)3); GXCommon.SetData(settings, data, DataType.UInt16, item.ShortName); data.SetUInt8((byte)DataType.Array); data.SetUInt8((byte)item.Attributes.Count); foreach (GXDLMSAttributeSettings att in item.Attributes) { data.SetUInt8((byte)DataType.Structure); //attribute_access_item data.SetUInt8((byte)3); GXCommon.SetData(settings, data, DataType.Int8, att.Index); GXCommon.SetData(settings, data, DataType.Enum, att.Access); GXCommon.SetData(settings, data, DataType.None, null); } data.SetUInt8((byte)DataType.Array); data.SetUInt8((byte)item.MethodAttributes.Count); foreach (GXDLMSAttributeSettings it in item.MethodAttributes) { data.SetUInt8((byte)DataType.Structure); //attribute_access_item data.SetUInt8((byte)2); GXCommon.SetData(settings, data, DataType.Int8, it.Index); GXCommon.SetData(settings, data, DataType.Enum, it.MethodAccess); } }
/// <summary> /// Returns Association View. /// </summary> private GXByteBuffer GetObjects(GXDLMSSettings settings, ValueEventArgs e) { int cnt = ObjectList.Count; GXByteBuffer data = new GXByteBuffer(); //Add count only for first time. if (settings.Index == 0) { settings.Count = (UInt16)cnt; data.SetUInt8((byte)DataType.Array); GXCommon.SetObjectCount(cnt, data); } ushort pos = 0; foreach (GXDLMSObject it in ObjectList) { ++pos; if (!(pos <= settings.Index)) { data.SetUInt8((byte)DataType.Structure); //Count data.SetUInt8((byte)4); //base address. GXCommon.SetData(settings, data, DataType.Int16, it.ShortName); //ClassID GXCommon.SetData(settings, data, DataType.UInt16, it.ObjectType); //Version GXCommon.SetData(settings, data, DataType.UInt8, 0); //LN GXCommon.SetData(settings, data, DataType.OctetString, it.LogicalName); ++settings.Index; //If PDU is full. if (!e.SkipMaxPduSize && data.Size >= settings.MaxPduSize) { break; } } } return data; }
///<summary> ///Convert ASCII string to DLMS bytes. ///</summary> ///<param name="buff"> ///Byte buffer where data is write. ///</param> ///<param name="value"> ///Added value. ///</param> private static void SetString(GXByteBuffer buff, object value) { if (value != null) { string str = Convert.ToString(value); SetObjectCount(str.Length, buff); buff.Set(ASCIIEncoding.ASCII.GetBytes(str)); } else { buff.SetUInt8(0); } }
object IGXDLMSBase.GetValue(GXDLMSSettings settings, ValueEventArgs e) { if (e.Index == 1) { return this.LogicalName; } if (e.Index == 2) { return GetObjects(settings, e).Array(); } if (e.Index == 3) { GXByteBuffer data = new GXByteBuffer(); data.SetUInt8((byte)DataType.Array); //Add count data.SetUInt8(2); data.SetUInt8((byte)DataType.UInt8); data.SetUInt8(ClientSAP); data.SetUInt8((byte)DataType.UInt16); data.SetUInt16(ServerSAP); return data.Array(); } if (e.Index == 4) { GXByteBuffer data = new GXByteBuffer(); data.SetUInt8((byte)DataType.Structure); //Add count data.SetUInt8(0x7); GXCommon.SetData(settings, data, DataType.UInt8, ApplicationContextName.JointIsoCtt); GXCommon.SetData(settings, data, DataType.UInt8, ApplicationContextName.Country); GXCommon.SetData(settings, data, DataType.UInt16, ApplicationContextName.CountryName); GXCommon.SetData(settings, data, DataType.UInt8, ApplicationContextName.IdentifiedOrganization); GXCommon.SetData(settings, data, DataType.UInt8, ApplicationContextName.DlmsUA); GXCommon.SetData(settings, data, DataType.UInt8, ApplicationContextName.ApplicationContext); GXCommon.SetData(settings, data, DataType.UInt8, ApplicationContextName.ContextId); return data.Array(); } if (e.Index == 5) { GXByteBuffer data = new GXByteBuffer(); data.SetUInt8((byte)DataType.Structure); data.SetUInt8(6); GXCommon.SetData(settings, data, DataType.BitString, XDLMSContextInfo.Conformance); GXCommon.SetData(settings, data, DataType.UInt16, XDLMSContextInfo.MaxReceivePduSize); GXCommon.SetData(settings, data, DataType.UInt16, XDLMSContextInfo.MaxSendPpuSize); GXCommon.SetData(settings, data, DataType.UInt8, XDLMSContextInfo.DlmsVersionNumber); GXCommon.SetData(settings, data, DataType.Int8, XDLMSContextInfo.QualityOfService); GXCommon.SetData(settings, data, DataType.OctetString, XDLMSContextInfo.CypheringInfo); return data.Array(); } if (e.Index == 6) { GXByteBuffer data = new GXByteBuffer(); data.SetUInt8((byte)DataType.Structure); //Add count data.SetUInt8(0x7); GXCommon.SetData(settings, data, DataType.UInt8, AuthenticationMechanismMame.JointIsoCtt); GXCommon.SetData(settings, data, DataType.UInt8, AuthenticationMechanismMame.Country); GXCommon.SetData(settings, data, DataType.UInt16, AuthenticationMechanismMame.CountryName); GXCommon.SetData(settings, data, DataType.UInt8, AuthenticationMechanismMame.IdentifiedOrganization); GXCommon.SetData(settings, data, DataType.UInt8, AuthenticationMechanismMame.DlmsUA); GXCommon.SetData(settings, data, DataType.UInt8, AuthenticationMechanismMame.AuthenticationMechanismName); GXCommon.SetData(settings, data, DataType.UInt8, AuthenticationMechanismMame.MechanismId); return data.Array(); } if (e.Index == 7) { return Secret; } if (e.Index == 8) { return AssociationStatus; } if (e.Index == 9) { if (SecuritySetupReference == null) { return null; } return ASCIIEncoding.ASCII.GetBytes(SecuritySetupReference); } e.Error = ErrorCode.ReadWriteDenied; return null; }
private static byte[] GetUserInformation(GXDLMSSettings settings, GXICipher cipher) { GXByteBuffer data = new GXByteBuffer(); data.SetUInt8(Command.InitiateResponse); // Tag for xDLMS-Initiate response // NegotiatedQualityOfService (not used) data.SetUInt8(0x1); data.SetUInt8(0x00); // DLMS Version Number data.SetUInt8(06); data.SetUInt8(0x5F); data.SetUInt8(0x1F); data.SetUInt8(0x04);// length of the conformance block data.SetUInt8(0x00);// encoding the number of unused bits in the bit string if (settings.UseLogicalNameReferencing) { data.Set(settings.LnSettings.ConformanceBlock); } else { data.Set(settings.SnSettings.ConformanceBlock); } data.SetUInt16(settings.MaxPduSize); //VAA Name VAA name (0x0007 for LN referencing and 0xFA00 for SN) if (settings.UseLogicalNameReferencing) { data.SetUInt16(0x0007); } else { data.SetUInt16(0xFA00); } if (cipher != null && cipher.IsCiphered()) { return cipher.Encrypt((byte)Command.GloInitiateResponse, cipher.SystemTitle, data.Array()); } return data.Array(); }
object IGXDLMSBase.GetValue(GXDLMSSettings settings, ValueEventArgs e) { if (e.Index == 1) { return this.LogicalName; } if (e.Index == 2) { return (byte)Mode; } if (e.Index == 3) { int cnt = ListeningWindow.Count; GXByteBuffer data = new GXByteBuffer(); data.SetUInt8((byte)DataType.Array); //Add count GXCommon.SetObjectCount(cnt, data); if (cnt != 0) { foreach (var it in ListeningWindow) { data.SetUInt8((byte)DataType.Structure); data.SetUInt8((byte)2); //Count GXCommon.SetData(settings, data, DataType.OctetString, it.Key); //start_time GXCommon.SetData(settings, data, DataType.OctetString, it.Value); //end_time } } return data.Array(); } if (e.Index == 4) { return Status; } if (e.Index == 5) { return NumberOfCalls; } if (e.Index == 6) { GXByteBuffer data = new GXByteBuffer(); data.SetUInt8((byte)DataType.Structure); //Add count GXCommon.SetObjectCount(2, data); GXCommon.SetData(settings, data, DataType.UInt8, NumberOfRingsInListeningWindow); GXCommon.SetData(settings, data, DataType.UInt8, NumberOfRingsOutListeningWindow); return data.Array(); } e.Error = ErrorCode.ReadWriteDenied; return null; }
object IGXDLMSBase.GetValue(GXDLMSSettings settings, ValueEventArgs e) { if (e.Index == 1) { return this.LogicalName; } if (e.Index == 2) { return this.Thresholds; } if (e.Index == 3) { GXByteBuffer data = new GXByteBuffer(); data.SetUInt8((int)DataType.Structure); data.SetUInt8(3); GXCommon.SetData(settings, data, DataType.UInt16, MonitoredValue.ObjectType); //ClassID GXCommon.SetData(settings, data, DataType.OctetString, MonitoredValue.LogicalName); //Logical name. GXCommon.SetData(settings, data, DataType.Int8, MonitoredValue.AttributeIndex); //Attribute Index return data.Array(); } if (e.Index == 4) { GXByteBuffer data = new GXByteBuffer(); data.SetUInt8((int)DataType.Structure); if (Actions == null) { data.SetUInt8(0); } else { data.SetUInt8((byte)Actions.Length); foreach (GXDLMSActionSet it in Actions) { data.SetUInt8((int)DataType.Structure); data.SetUInt8(2); data.SetUInt8((int)DataType.Structure); data.SetUInt8(2); GXCommon.SetData(settings, data, DataType.OctetString, it.ActionUp.LogicalName); //Logical name. GXCommon.SetData(settings, data, DataType.UInt16, it.ActionUp.ScriptSelector); //ScriptSelector data.SetUInt8((int)DataType.Structure); data.SetUInt8(2); GXCommon.SetData(settings, data, DataType.OctetString, it.ActionDown.LogicalName); //Logical name. GXCommon.SetData(settings, data, DataType.UInt16, it.ActionDown.ScriptSelector); //ScriptSelector } } return data.Array(); } e.Error = ErrorCode.ReadWriteDenied; return null; }
/// <summary> /// Parse User Information from PDU. /// </summary> public static void ParseUserInformation(GXDLMSSettings settings, GXICipher cipher, GXByteBuffer data, GXDLMSTranslatorStructure xml) { byte len = data.GetUInt8(); GXByteBuffer tmp2 = new GXByteBuffer(); tmp2.SetUInt8(0); if (data.Size - data.Position < len) { throw new Exception("Not enough data."); } if (xml != null && xml.OutputType == TranslatorOutputType.StandardXml) { len = (byte)(data.Size - data.Position); xml.AppendLine(Command.InitiateRequest, null, GXCommon .ToHex(data.Data, false, data.Position, len)); data.Position = data.Position + len; return; } //Excoding the choice for user information int tag = data.GetUInt8(); if (tag != 0x4) { throw new Exception("Invalid tag."); } len = data.GetUInt8(); //Tag for xDLMS-Initate.response tag = data.GetUInt8(); if (tag == (byte)Command.GloInitiateResponse) { if (xml != null) { int cnt = GXCommon.GetObjectCount(data); byte[] tmp = new byte[cnt]; data.Get(tmp); //<glo_InitiateResponse> xml.AppendLine(Command.GloInitiateResponse, "Value", GXCommon.ToHex(tmp, false)); return; } --data.Position; cipher.Security = cipher.Decrypt(settings.SourceSystemTitle, data); tag = data.GetUInt8(); } else if (tag == (byte)Command.GloInitiateRequest) { if (xml != null) { int cnt = GXCommon.GetObjectCount(data); byte[] tmp = new byte[cnt]; data.Get(tmp); //<glo_InitiateRequest> xml.AppendLine(Command.GloInitiateRequest, "Value", GXCommon.ToHex(tmp, false)); return; } --data.Position; cipher.Security = cipher.Decrypt(settings.SourceSystemTitle, data); tag = data.GetUInt8(); } bool response = tag == (byte)Command.InitiateResponse; if (response) { if (xml != null) { //<InitiateResponse> xml.AppendStartTag(Command.InitiateResponse); } //Optional usage field of the negotiated quality of service component tag = data.GetUInt8(); len = 0; if (tag != 0)//Skip if used. { len = data.GetUInt8(); data.Position += len; if (len == 0 && xml != null) { //NegotiatedQualityOfService xml.AppendLine(TranslatorGeneralTags.NegotiatedQualityOfService, "Value", "00"); } } } else if (tag == (byte)Command.InitiateRequest) { if (xml != null) { //<InitiateRequest> xml.AppendStartTag(Command.InitiateRequest); } //Optional usage field of the negotiated quality of service component tag = data.GetUInt8(); //CtoS. if (tag != 0) { len = data.GetUInt8(); settings.CtoSChallenge = new byte[len]; data.Get(settings.CtoSChallenge); } //Optional usage field of the negotiated quality of service component tag = data.GetUInt8(); if (tag != 0)//Skip if used. { len = data.GetUInt8(); data.Position += len; } //Optional usage field of the proposed quality of service component tag = data.GetUInt8(); if (tag != 0)//Skip if used. { len = data.GetUInt8(); data.Position += len; } } else { throw new Exception("Invalid tag."); } //Get DLMS version number. if (!response) { if (data.GetUInt8() != 6) { throw new Exception("Invalid DLMS version number."); } //ProposedDlmsVersionNumber if (xml != null) { xml.AppendLine(TranslatorGeneralTags.ProposedDlmsVersionNumber, "Value", xml.IntegerToHex(settings.DLMSVersion, 2)); } } else { if (data.GetUInt8() != 6) { throw new Exception("Invalid DLMS version number."); } if (xml != null) { xml.AppendLine(TranslatorGeneralTags.NegotiatedDlmsVersionNumber, "Value", xml.IntegerToHex(settings.DLMSVersion, 2)); } } //Tag for conformance block tag = data.GetUInt8(); if (tag != 0x5F) { throw new Exception("Invalid tag."); } //Old Way... if (data.GetUInt8(data.Position) == 0x1F) { data.GetUInt8(); } len = data.GetUInt8(); //The number of unused bits in the bit string. tag = data.GetUInt8(); if (!response) { //ProposedConformance if (xml != null) { xml.AppendStartTag(TranslatorGeneralTags.ProposedConformance); } data.Get(settings.ConformanceBlock); tmp2.Set(settings.ConformanceBlock); } else { //NegotiatedConformance if (xml != null) { xml.AppendStartTag(TranslatorGeneralTags.NegotiatedConformance); } if (settings.UseLogicalNameReferencing) { data.Get(settings.LnSettings.ConformanceBlock); tmp2.Set(settings.LnSettings.ConformanceBlock); } else { data.Get(settings.SnSettings.ConformanceBlock); tmp2.Set(settings.SnSettings.ConformanceBlock); } } if (xml != null) { GetConformance(tmp2.GetUInt32(), xml); } if (!response) { //Proposed max PDU size. settings.MaxPduSize = data.GetUInt16(); if (xml != null) { //ProposedConformance closing xml.AppendEndTag(TranslatorGeneralTags.ProposedConformance); //ProposedMaxPduSize xml.AppendLine(TranslatorGeneralTags.ProposedMaxPduSize, "Value", xml.IntegerToHex(settings.MaxPduSize, 4)); } //If client asks too high PDU. if (settings.MaxPduSize > settings.MaxServerPDUSize) { settings.MaxPduSize = settings.MaxServerPDUSize; } } else { //Max PDU size. settings.MaxPduSize = data.GetUInt16(); if (xml != null) { //NegotiatedConformance closing xml.AppendEndTag(TranslatorGeneralTags.NegotiatedConformance); //NegotiatedMaxPduSize xml.AppendLine(TranslatorGeneralTags.NegotiatedMaxPduSize, "Value", xml.IntegerToHex(settings.MaxPduSize, 4)); } } if (response) { //VAA Name tag = data.GetUInt16(); if (xml != null) { xml.AppendLine(TranslatorGeneralTags.VaaName, "Value", xml.IntegerToHex(tag, 4)); } if (tag == 0x0007) { // If LN if (!settings.UseLogicalNameReferencing) { throw new ArgumentException("Invalid VAA."); } } else if (tag == 0xFA00) { // If SN if (settings.UseLogicalNameReferencing) { throw new ArgumentException("Invalid VAA."); } } else { // Unknown VAA. throw new ArgumentException("Invalid VAA."); } if (xml != null) { //<InitiateResponse> xml.AppendEndTag(Command.InitiateResponse); } } else if (xml != null) { //</InitiateRequest> xml.AppendEndTag(Command.InitiateRequest); } }
/// <summary> /// Generate user information. /// </summary> /// <param name="settings">DLMS settings.</param> /// <param name="cipher"></param> /// <param name="data">Generated user information.</param> static internal void GenerateUserInformation(GXDLMSSettings settings, GXICipher cipher, GXByteBuffer encryptedData, GXByteBuffer data) { data.SetUInt8((byte)BerType.Context | (byte)BerType.Constructed | (byte)PduType.UserInformation); if (cipher == null || !cipher.IsCiphered()) { //Length for AARQ user field data.SetUInt8(0x10); //Coding the choice for user-information (Octet STRING, universal) data.SetUInt8(BerType.OctetString); //Length data.SetUInt8(0x0E); GetInitiateRequest(settings, cipher, data); } else { if (encryptedData != null && encryptedData.Size != 0) { //Length for AARQ user field data.SetUInt8((byte)(4 + encryptedData.Size)); //Tag data.SetUInt8(BerType.OctetString); data.SetUInt8((byte)(2 + encryptedData.Size)); //Coding the choice for user-information (Octet STRING, universal) data.SetUInt8((byte)Command.GloInitiateRequest); data.SetUInt8((byte)encryptedData.Size); data.Set(encryptedData); } else { GXByteBuffer tmp = new GXByteBuffer(); GetInitiateRequest(settings, cipher, tmp); byte[] crypted = cipher.Encrypt((byte)Command.GloInitiateRequest, cipher.SystemTitle, tmp.Array()); //Length for AARQ user field data.SetUInt8((byte)(2 + crypted.Length)); //Coding the choice for user-information (Octet STRING, universal) data.SetUInt8(BerType.OctetString); data.SetUInt8((byte)crypted.Length); data.Set(crypted); } } }
private static byte[] GetAuthenticatedData(Gurux.DLMS.Enums.Security security, byte[] AuthenticationKey, byte[] plainText) { if (security == Gurux.DLMS.Enums.Security.Authentication) { GXByteBuffer tmp2 = new GXByteBuffer(); tmp2.SetUInt8((byte)security); tmp2.Set(AuthenticationKey); tmp2.Set(plainText); return tmp2.Array(); } else if (security == Gurux.DLMS.Enums.Security.Encryption) { return AuthenticationKey; } else if (security == Gurux.DLMS.Enums.Security.AuthenticationEncryption) { GXByteBuffer tmp2 = new GXByteBuffer(); tmp2.SetUInt8((byte)security); tmp2.Set(AuthenticationKey); return tmp2.Array(); } return null; }
///<summary> ///Convert BCD to DLMS bytes. ///</summary> ///<param name="buff"> ///Byte buffer where data is write. ///</param> ///<param name="value"> ///Added value. ///</param> private static void SetBcd(GXByteBuffer buff, object value) { //Standard supports only size of byte. buff.SetUInt8(Convert.ToByte(value)); }
///<summary> ///Convert Octet string to DLMS bytes. ///</summary> ///<param name="buff"> ///Byte buffer where data is write. ///</param> ///<param name="value"> ///Added value. ///</param> private static void SetOctetString(GXByteBuffer buff, object value) { // Example Logical name is octet string, so do not change to // string... if (value is string) { string[] items = ((string)value).Split('.'); // If data is string. if (items.Length == 1) { byte[] tmp = ASCIIEncoding.ASCII.GetBytes((string)value); SetObjectCount(tmp.Length, buff); buff.Set(tmp); } else { SetObjectCount(items.Length, buff); foreach (string it in items) { buff.SetUInt8(Convert.ToByte(it)); } } } else if (value is sbyte[]) { SetObjectCount(((byte[])value).Length, buff); buff.Set((byte[])value); } else if (value == null) { SetObjectCount(0, buff); } else { throw new Exception("Invalid data type."); } }
private void GetAccessRights(GXDLMSSettings settings, GXDLMSObject item, GXByteBuffer data) { data.SetUInt8((byte)DataType.Structure); data.SetUInt8((byte)2); data.SetUInt8((byte)DataType.Array); GXAttributeCollection attributes = item.Attributes; int cnt = (item as IGXDLMSBase).GetAttributeCount(); data.SetUInt8((byte)cnt); for (int pos = 0; pos != cnt; ++pos) { GXDLMSAttributeSettings att = attributes.Find(pos + 1); data.SetUInt8((byte)DataType.Structure); //attribute_access_item data.SetUInt8((byte)3); GXCommon.SetData(settings, data, DataType.Int8, pos + 1); //If attribute is not set return read only. if (att == null) { GXCommon.SetData(settings, data, DataType.Enum, AccessMode.Read); } else { GXCommon.SetData(settings, data, DataType.Enum, att.Access); } GXCommon.SetData(settings, data, DataType.None, null); } data.SetUInt8((byte)DataType.Array); attributes = item.MethodAttributes; cnt = (item as IGXDLMSBase).GetMethodCount(); data.SetUInt8((byte)cnt); for (int pos = 0; pos != cnt; ++pos) { GXDLMSAttributeSettings att = attributes.Find(pos + 1); data.SetUInt8((byte)DataType.Structure); //attribute_access_item data.SetUInt8((byte)2); GXCommon.SetData(settings, data, DataType.Int8, pos + 1); //If method attribute is not set return no access. if (att == null) { GXCommon.SetData(settings, data, DataType.Enum, MethodAccessMode.NoAccess); } else { GXCommon.SetData(settings, data, DataType.Enum, att.MethodAccess); } } }
/// <summary> /// Add string to byte buffer. /// </summary> /// <param name="value">String to add.</param> /// <param name="bb">Byte buffer where string is added.</param> public static void AddString(string value, GXByteBuffer bb) { bb.SetUInt8((byte)DataType.OctetString); if (value == null) { GXCommon.SetObjectCount(0, bb); } else { GXCommon.SetObjectCount(value.Length, bb); bb.Set(ASCIIEncoding.ASCII.GetBytes(value)); } }
/// <summary> /// Set item count. /// </summary> /// <param name="count"></param> /// <param name="buff"></param> internal static void SetObjectCount(int count, GXByteBuffer buff) { if (count < 0x80) { buff.SetUInt8((byte)count); } else if (count < 0x100) { buff.SetUInt8(0x81); buff.SetUInt8((byte)count); } else if (count < 0x10000) { buff.SetUInt8(0x82); buff.SetUInt16((UInt16)count); } else { buff.SetUInt8(0x84); buff.SetUInt32((UInt32)count); } }
///<summary> ///Convert object to DLMS bytes. ///</summary> ///<param name="settings">DLMS settings.</param> ///<param name="buff">Byte buffer where data is write.</param> ///<param name="dataType">Data type.</param> ///<param name="value">Added Value.</param> public static void SetData(GXDLMSSettings settings, GXByteBuffer buff, DataType type, object value) { if ((type == DataType.Array || type == DataType.Structure) && value is byte[]) { // If byte array is added do not add type. buff.Set((byte[])value); return; } buff.SetUInt8((byte)type); switch (type) { case DataType.None: break; case DataType.Boolean: if (Convert.ToBoolean(value)) { buff.SetUInt8(1); } else { buff.SetUInt8(0); } break; case DataType.Int8: buff.SetUInt8((byte)Convert.ToSByte(value)); break; case DataType.UInt8: case DataType.Enum: buff.SetUInt8(Convert.ToByte(value)); break; case DataType.Int16: if (value is UInt16) { buff.SetUInt16((UInt16)value); } else { buff.SetUInt16((UInt16)(Convert.ToInt16(value) & 0xFFFF)); } break; case DataType.UInt16: buff.SetUInt16(Convert.ToUInt16(value)); break; case DataType.Int32: buff.SetUInt32((UInt32)Convert.ToInt32(value)); break; case DataType.UInt32: buff.SetUInt32(Convert.ToUInt32(value)); break; case DataType.Int64: buff.SetUInt64((UInt64)Convert.ToInt64(value)); break; case DataType.UInt64: buff.SetUInt64(Convert.ToUInt64(value)); break; case DataType.Float32: buff.SetFloat((float)value); break; case DataType.Float64: buff.SetDouble((double)value); break; case DataType.BitString: SetBitString(buff, value); break; case DataType.String: SetString(buff, value); break; case DataType.StringUTF8: SetUtcString(buff, value); break; case DataType.OctetString: if (value is GXDate) { //Add size buff.SetUInt8(5); SetDate(buff, value); } else if (value is GXTime) { //Add size buff.SetUInt8(4); SetTime(buff, value); } else if (value is GXDateTime || value is DateTime) { //Add size buff.SetUInt8(12); SetDateTime(settings, buff, value); } else { SetOctetString(buff, value); } break; case DataType.Array: case DataType.Structure: SetArray(settings, buff, value); break; case DataType.Bcd: SetBcd(buff, value); break; case DataType.CompactArray: throw new Exception("Invalid data type."); case DataType.DateTime: SetDateTime(settings, buff, value); break; case DataType.Date: SetDate(buff, value); break; case DataType.Time: SetTime(buff, value); break; default: throw new Exception("Invalid data type."); } }
static internal byte[] EncryptAesGcm(AesGcmParameter param, byte[] plainText) { System.Diagnostics.Debug.WriteLine("Encrypt settings: " + param.ToString()); param.CountTag = null; GXByteBuffer data = new GXByteBuffer(); if (param.Type == CountType.Packet) { data.SetUInt8((byte)param.Security); } byte[] tmp = BitConverter.GetBytes(param.FrameCounter).Reverse().ToArray(); byte[] aad = GetAuthenticatedData(param.Security, param.AuthenticationKey, plainText); GXDLMSChipperingStream gcm = new GXDLMSChipperingStream(param.Security, true, param.BlockCipherKey, aad, GetNonse(param.FrameCounter, param.SystemTitle), null); // Encrypt the secret message if (param.Security != Gurux.DLMS.Enums.Security.Authentication) { gcm.Write(plainText); } byte[] ciphertext = gcm.FlushFinalBlock(); if (param.Security == Gurux.DLMS.Enums.Security.Authentication) { if (param.Type == CountType.Packet) { data.Set(tmp); } if ((param.Type & CountType.Data) != 0) { data.Set(plainText); } if ((param.Type & CountType.Tag) != 0) { param.CountTag = gcm.GetTag(); data.Set(param.CountTag); } } else if (param.Security == Gurux.DLMS.Enums.Security.Encryption) { if (param.Type == CountType.Packet) { data.Set(tmp); } data.Set(ciphertext); } else if (param.Security == Gurux.DLMS.Enums.Security.AuthenticationEncryption) { if (param.Type == CountType.Packet) { data.Set(tmp); } if ((param.Type & CountType.Data) != 0) { data.Set(ciphertext); } if ((param.Type & CountType.Tag) != 0) { param.CountTag = gcm.GetTag(); data.Set(param.CountTag); } } else { throw new ArgumentOutOfRangeException("security"); } if (param.Type == CountType.Packet) { GXByteBuffer tmp2 = new GXByteBuffer((ushort)(10 + data.Size)); tmp2.SetUInt8(param.Tag); GXCommon.SetObjectCount(data.Size, tmp2); tmp2.Set(data.Array()); return tmp2.Array(); } byte[] crypted = data.Array(); System.Diagnostics.Debug.WriteLine("Crypted: " + GXCommon.ToHex(crypted, true)); return crypted; }
///<summary> ///Convert UTC string to DLMS bytes. ///</summary> ///<param name="buff"> ///Byte buffer where data is write. ///</param> ///<param name="value"> ///Added value. ///</param> private static void SetUtcString(GXByteBuffer buff, object value) { if (value != null) { byte[] tmp = ASCIIEncoding.UTF8.GetBytes(Convert.ToString(value)); SetObjectCount(tmp.Length, buff); buff.Set(tmp); } else { buff.SetUInt8(0); } }
///<summary> /// Generates Aarq. ///</summary> static internal void GenerateAarq(GXDLMSSettings settings, GXICipher cipher, GXByteBuffer encryptedData, GXByteBuffer data) { //AARQ APDU Tag data.SetUInt8(BerType.Application | BerType.Constructed); //Length is updated later. int offset = data.Size; data.SetUInt8(0); /////////////////////////////////////////// // Add Application context name. GenerateApplicationContextName(settings, data, cipher); GetAuthenticationString(settings, data); GenerateUserInformation(settings, cipher, encryptedData, data); data.SetUInt8(offset, (byte)(data.Size - offset - 1)); }
///<summary> ///Convert date time to DLMS bytes. ///</summary> ///<param name="buff"> ///Byte buffer where data is write. ///</param> ///<param name="value"> ///Added value. ///</param> private static void SetDateTime(GXDLMSSettings settings, GXByteBuffer buff, object value) { GXDateTime dt; if (value is GXDateTime) { dt = (GXDateTime)value; } else if (value is DateTime) { dt = new GXDateTime((DateTime)value); dt.Skip = dt.Skip | DateTimeSkips.Ms; } else if (value is string) { dt = new GXDateTime(DateTime.Parse((string)value)); dt.Skip = dt.Skip | DateTimeSkips.Ms; } else { throw new Exception("Invalid date format."); } if (dt.Value.UtcDateTime == DateTime.MinValue) { dt.Value = DateTime.SpecifyKind(new DateTime(2000, 1, 1).Date, DateTimeKind.Utc); } else if (dt.Value.UtcDateTime == DateTime.MaxValue) { dt.Value = DateTime.SpecifyKind(DateTime.Now.AddYears(1).Date, DateTimeKind.Utc); } DateTimeOffset tm = dt.Value; if ((dt.Skip & DateTimeSkips.Year) == 0) { buff.SetUInt16((ushort)tm.Year); } else { buff.SetUInt16(0xFFFF); } if ((dt.Skip & DateTimeSkips.Month) == 0) { if (dt.DaylightSavingsBegin) { buff.SetUInt8(0xFE); } else if (dt.DaylightSavingsEnd) { buff.SetUInt8(0xFD); } else { buff.SetUInt8((byte)tm.Month); } } else { buff.SetUInt8(0xFF); } if ((dt.Skip & DateTimeSkips.Day) == 0) { buff.SetUInt8((byte)tm.Day); } else { buff.SetUInt8(0xFF); } // Add week day if ((dt.Skip & DateTimeSkips.DayOfWeek) != 0) { buff.SetUInt8(0xFF); } else { if (dt.Value.DayOfWeek == DayOfWeek.Sunday) { buff.SetUInt8(7); } else { buff.SetUInt8((byte)(dt.Value.DayOfWeek)); } } //Add time. if ((dt.Skip & DateTimeSkips.Hour) == 0) { buff.SetUInt8((byte)tm.Hour); } else { buff.SetUInt8(0xFF); } if ((dt.Skip & DateTimeSkips.Minute) == 0) { buff.SetUInt8((byte)tm.Minute); } else { buff.SetUInt8(0xFF); } if ((dt.Skip & DateTimeSkips.Second) == 0) { buff.SetUInt8((byte)tm.Second); } else { buff.SetUInt8(0xFF); } if ((dt.Skip & DateTimeSkips.Ms) == 0) { buff.SetUInt8((byte)(tm.Millisecond / 10)); } else { buff.SetUInt8((byte)0xFF); //Hundredths of second is not used. } //Add deviation. if ((dt.Skip & DateTimeSkips.Devitation) == 0) { if (settings != null && settings.UtcTimeZone) { buff.SetInt16((Int16)(dt.Value.Offset.TotalMinutes)); } else { buff.SetInt16((Int16)(-dt.Value.Offset.TotalMinutes)); } } else //deviation not used. { buff.SetUInt16(0x8000); } //Add clock_status if (dt.Value.LocalDateTime.IsDaylightSavingTime()) { buff.SetUInt8((byte)(dt.Status | ClockStatus.DaylightSavingActive)); } else { buff.SetUInt8((byte)dt.Status); } }
/// <summary> /// Generate User information initiate request. /// </summary> /// <param name="settings">DLMS settings.</param> /// <param name="cipher"></param> /// <param name="data"></param> private static void GetInitiateRequest(GXDLMSSettings settings, GXICipher cipher, GXByteBuffer data) { // Tag for xDLMS-Initiate request data.SetUInt8((byte)Command.InitiateRequest); // Usage field for dedicated-key component. Not used data.SetUInt8(0x00); //encoding of the response-allowed component (BOOLEAN DEFAULT TRUE) // usage flag (FALSE, default value TRUE conveyed) data.SetUInt8(0); // Usage field of the proposed-quality-of-service component. Not used data.SetUInt8(0x00); data.SetUInt8(settings.DLMSVersion); // Tag for conformance block data.SetUInt8(0x5F); data.SetUInt8(0x1F); // length of the conformance block data.SetUInt8(0x04); // encoding the number of unused bits in the bit string data.SetUInt8(0x00); if (settings.UseLogicalNameReferencing) { data.Set(settings.LnSettings.ConformanceBlock); } else { data.Set(settings.SnSettings.ConformanceBlock); } data.SetUInt16(settings.MaxPduSize); }
///<summary> ///Convert date to DLMS bytes. ///</summary> ///<param name="buff"> ///Byte buffer where data is write. ///</param> ///<param name="value"> ///Added value. ///</param> private static void SetDate(GXByteBuffer buff, object value) { GXDateTime dt; if (value is GXDateTime) { dt = (GXDateTime)value; } else if (value is DateTime) { dt = new GXDateTime((DateTime)value); } else if (value is DateTimeOffset) { dt = new GXDateTime((DateTimeOffset)value); } else if (value is string) { dt = DateTime.Parse((string)value); } else { throw new Exception("Invalid date format."); } // Add year. if ((dt.Skip & DateTimeSkips.Year) != 0) { buff.SetUInt16(0xFFFF); } else { buff.SetUInt16((UInt16)dt.Value.Year); } // Add month if (dt.DaylightSavingsBegin) { buff.SetUInt8(0xFE); } else if (dt.DaylightSavingsEnd) { buff.SetUInt8(0xFD); } else if ((dt.Skip & DateTimeSkips.Month) != 0) { buff.SetUInt8(0xFF); } else { buff.SetUInt8((byte)dt.Value.Month); } // Add day if ((dt.Skip & DateTimeSkips.Day) != 0) { buff.SetUInt8(0xFF); } else { buff.SetUInt8((byte)dt.Value.Day); } // Add week day if ((dt.Skip & DateTimeSkips.DayOfWeek) != 0) { buff.SetUInt8(0xFF); } else { if (dt.Value.DayOfWeek == DayOfWeek.Sunday) { buff.SetUInt8(7); } else { buff.SetUInt8((byte)(dt.Value.DayOfWeek)); } } }
///<summary> ///Server generates AARE message. ///</summary> internal static void GenerateAARE(GXDLMSSettings settings, GXByteBuffer data, AssociationResult result, SourceDiagnostic diagnostic, GXICipher cipher, GXByteBuffer encryptedData) { int offset = data.Size; // Set AARE tag and length data.SetUInt8(((byte)BerType.Application | (byte)BerType.Constructed | (byte)PduType.ApplicationContextName)); //0x61 // Length is updated later. data.SetUInt8(0); GenerateApplicationContextName(settings, data, cipher); //Result data.SetUInt8((byte)BerType.Context | (byte)BerType.Constructed | (byte)BerType.Integer);//0xA2 data.SetUInt8(3); //len data.SetUInt8(BerType.Integer); //Tag //Choice for result (INTEGER, universal) data.SetUInt8(1); //Len data.SetUInt8((byte)result); //ResultValue //SourceDiagnostic data.SetUInt8(0xA3); data.SetUInt8(5); //len data.SetUInt8(0xA1); //Tag data.SetUInt8(3); //len data.SetUInt8(2); //Tag //Choice for result (INTEGER, universal) data.SetUInt8(1); //Len data.SetUInt8((byte)diagnostic); //diagnostic //SystemTitle if (cipher != null && (cipher.IsCiphered() || settings.Authentication == Authentication.HighGMAC)) { data.SetUInt8((byte)BerType.Context | (byte)BerType.Constructed | (byte)PduType.CalledApInvocationId); data.SetUInt8((byte)(2 + cipher.SystemTitle.Length)); data.SetUInt8((byte)BerType.OctetString); data.SetUInt8((byte)cipher.SystemTitle.Length); data.Set(cipher.SystemTitle); } if (result != AssociationResult.PermanentRejected && diagnostic == SourceDiagnostic.AuthenticationRequired) { //Add server ACSE-requirenents field component. data.SetUInt8(0x88); data.SetUInt8(0x02); //Len. data.SetUInt16(0x0780); //Add tag. data.SetUInt8(0x89); data.SetUInt8(0x07);//Len data.SetUInt8(0x60); data.SetUInt8(0x85); data.SetUInt8(0x74); data.SetUInt8(0x05); data.SetUInt8(0x08); data.SetUInt8(0x02); data.SetUInt8((byte)settings.Authentication); //Add tag. data.SetUInt8(0xAA); data.SetUInt8((byte)(2 + settings.StoCChallenge.Length));//Len data.SetUInt8((byte)BerType.Context); data.SetUInt8((byte)settings.StoCChallenge.Length); data.Set(settings.StoCChallenge); } byte[] tmp; //Add User Information //Tag 0xBE data.SetUInt8((byte)BerType.Context | (byte)BerType.Constructed | (byte)PduType.UserInformation); if (encryptedData != null && encryptedData.Size != 0) { GXByteBuffer tmp2 = new GXByteBuffer((UInt16)(2 + encryptedData.Size)); tmp2.SetUInt8((byte)Command.GloInitiateResponse); GXCommon.SetObjectCount(encryptedData.Size, tmp2); tmp2.Set(encryptedData); tmp = tmp2.Array(); } else { tmp = GetUserInformation(settings, cipher); } data.SetUInt8((byte)(2 + tmp.Length)); //Coding the choice for user-information (Octet STRING, universal) data.SetUInt8(BerType.OctetString); //Length data.SetUInt8((byte)tmp.Length); data.Set(tmp); data.SetUInt8((UInt16)(offset + 1), (byte)(data.Size - offset - 2)); }
///<summary> /// Chipher text. ///</summary> ///<param name="settings"> ///DLMS settings. ///</param> ///<param name="cipher"> ///Cipher. ///</param> ///<param name="ic"> ///Invocation counter. ///</param> ///<param name="data"> ///Text to chipher. ///</param> ///<param name="secret"> ///Secret. ///</param> ///<returns> ///Chiphered text. ///</returns> public static byte[] Secure(GXDLMSSettings settings, GXICipher cipher, UInt32 ic, byte[] data, byte[] secret) { byte[] tmp; if (settings.Authentication == Authentication.High) { int len = secret.Length; if (len % 16 != 0) { len += 16 - (secret.Length % 16); } byte[] p = new byte[len]; byte[] s = new byte[16]; byte[] x = new byte[16]; int i; data.CopyTo(p, 0); secret.CopyTo(s, 0); for (i = 0; i < p.Length; i += 16) { Buffer.BlockCopy(p, i, x, 0, 16); GXAes128.Encrypt(x, s); Buffer.BlockCopy(x, 0, p, i, 16); } Buffer.BlockCopy(p, 0, x, 0, 16); return x; } // Get server Challenge. GXByteBuffer challenge = new GXByteBuffer(); // Get shared secret if (settings.Authentication == Authentication.HighGMAC) { challenge.Set(data); } else { challenge.Set(data); challenge.Set(secret); } tmp = challenge.Array(); if (settings.Authentication == Authentication.HighMD5) { using (MD5 md5Hash = MD5.Create()) { tmp = md5Hash.ComputeHash(tmp); return tmp; } } else if (settings.Authentication == Authentication.HighSHA1) { using (SHA1 sha = new SHA1CryptoServiceProvider()) { tmp = sha.ComputeHash(tmp); return tmp; } } else if (settings.Authentication == Authentication.HighGMAC) { //SC is always Security.Authentication. AesGcmParameter p = new AesGcmParameter(0, Security.Authentication, ic, secret, cipher.BlockCipherKey, cipher.AuthenticationKey); p.Type = CountType.Tag; challenge.Clear(); challenge.SetUInt8((byte)Security.Authentication); challenge.SetUInt32(p.FrameCounter); challenge.Set(GXDLMSChippering.EncryptAesGcm(p, tmp)); tmp = challenge.Array(); return tmp; } return data; }
///<summary> ///Convert time to DLMS bytes. ///</summary> ///<param name="buff"> ///Byte buffer where data is write. ///</param> ///<param name="value"> ///Added value. ///</param> private static void SetTime(GXByteBuffer buff, object value) { GXDateTime dt; if (value is GXDateTime) { dt = (GXDateTime)value; } else if (value is DateTime) { dt = new GXDateTime((DateTime)value); } else if (value is DateTimeOffset) { dt = new GXDateTime((DateTimeOffset)value); } else if (value is string) { dt = DateTime.Parse((string)value); } else { throw new Exception("Invalid date format."); } //Add time. if ((dt.Skip & DateTimeSkips.Hour) != 0) { buff.SetUInt8(0xFF); } else { buff.SetUInt8((byte)dt.Value.Hour); } if ((dt.Skip & DateTimeSkips.Minute) != 0) { buff.SetUInt8(0xFF); } else { buff.SetUInt8((byte)dt.Value.Minute); } if ((dt.Skip & DateTimeSkips.Second) != 0) { buff.SetUInt8(0xFF); } else { buff.SetUInt8((byte)dt.Value.Second); } //Hundredths of second is not used. if ((dt.Skip & DateTimeSkips.Ms) != 0) { buff.SetUInt8(0xFF); } else { buff.SetUInt8((byte)(dt.Value.Millisecond / 10)); } }
///<summary> ///Convert Bit string to DLMS bytes. ///</summary> ///<param name="buff"> ///Byte buffer where data is write. ///</param> ///<param name="value"> ///Added value. ///</param> private static void SetBitString(GXByteBuffer buff, object value) { if (value is string) { GXByteBuffer tmp = new GXByteBuffer(); byte val = 0; int index = 0; string str = ((string)value); SetObjectCount(str.Length, buff); foreach (char it in str.Reverse()) { if (it == '1') { val |= (byte)(1 << index); ++index; } else if (it == '0') { ++index; } else { throw new Exception("Not a bit string."); } if (index == 8) { index = 0; tmp.SetUInt8(val); val = 0; } } if (index != 0) { tmp.SetUInt8(val); } for (int pos = tmp.Size - 1; pos != -1; --pos) { buff.SetUInt8(tmp.GetUInt8(pos)); } } else if (value is sbyte[]) { byte[] arr = (byte[])value; SetObjectCount(arr.Length, buff); buff.Set(arr); } else if (value == null) { buff.SetUInt8(0); } else { throw new Exception("BitString must give as string."); } }