Byte array class is used to save received bytes.
예제 #1
0
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="more">Is more data available.</param>
 /// <param name="cmd"> Received command.</param>
 /// <param name="buff">Received data.</param>
 /// <param name="complete">Is frame complete.</param>
 /// <param name="error">Received error ID.</param>
 internal GXReplyData(RequestTypes more, Command cmd, GXByteBuffer buff, bool complete, byte error)
 {
     Data = new GXByteBuffer();
     Clear();
     MoreData = more;
     Command = cmd;
     Data = buff;
     IsComplete = complete;
     Error = error;
 }
        public static void HandleGetRequest(GXDLMSSettings settings, GXDLMSServer server, GXByteBuffer data, GXByteBuffer replyData, GXDLMSTranslatorStructure xml)
        {
            //Return error if connection is not established.
            if (xml == null && !settings.Connected)
            {
                replyData.Set(GXDLMSServer.GenerateConfirmedServiceError(ConfirmedServiceError.InitiateError,
                              ServiceError.Service, (byte)Service.Unsupported));
                return;
            }

            GetCommandType type = (GetCommandType)data.GetUInt8();
            // Get invoke ID and priority.
            byte invokeID = data.GetUInt8();
            if (xml != null)
            {
                xml.AppendStartTag(Command.GetRequest);
                xml.AppendStartTag(Command.GetRequest, type);
                xml.AppendLine(TranslatorTags.InvokeId, "Value", xml.IntegerToHex(invokeID, 2));
            }

            // GetRequest normal
            if (type == GetCommandType.Normal)
            {
                GetRequestNormal(settings, server, data, replyData, xml);
            }
            else if (type == GetCommandType.NextDataBlock)
            {
                // Get request for next data block
                GetRequestNextDataBlock(settings, server, data, replyData, xml);
            }
            else if (type == GetCommandType.WithList)
            {
                // Get request with a list.
                GetRequestWithList(settings, server, data, replyData, xml);
            }
            else
            {
                Debug.WriteLine("HandleGetRequest failed. Invalid command type.");
                settings.ResetBlockIndex();
                GXByteBuffer bb = new GXByteBuffer();
                // Access Error : Device reports a hardware fault.
                bb.SetUInt8((byte)ErrorCode.HardwareFault);
                GXDLMS.GetLNPdu(new GXDLMSLNParameters(settings, Command.GetResponse, (byte)type, null, bb, (byte)ErrorCode.Ok), replyData);
            }
            if (xml != null)
            {
                xml.AppendEndTag(Command.GetRequest, type);
                xml.AppendEndTag(Command.GetRequest);
            }
        }
 public void ParseUAResponse(GXByteBuffer data)
 {
     client.ParseUAResponse(data);
 }
예제 #4
0
 object IGXDLMSBase.GetValue(GXDLMSSettings settings, ValueEventArgs e)
 {
     if (e.Index == 1)
     {
         return this.LogicalName;
     }
     if (e.Index == 2)
     {
         return MBusPortReference;
     }
     if (e.Index == 3)
     {
         GXByteBuffer buff = new GXByteBuffer();
         buff.Add((byte)DataType.Array);
         GXCommon.SetObjectCount(CaptureDefinition.Count, buff);
         foreach (KeyValuePair<string, string> it in CaptureDefinition)
         {
             buff.Add((byte)DataType.Structure);
             buff.Add(2);
             GXCommon.SetData(settings, buff, DataType.UInt8, it.Key);
             GXCommon.SetData(settings, buff, DataType.OctetString, ASCIIEncoding.ASCII.GetBytes(it.Value));
         }
         return buff.Array();
     }
     if (e.Index == 4)
     {
         return CapturePeriod;
     }
     if (e.Index == 5)
     {
         return PrimaryAddress;
     }
     if (e.Index == 6)
     {
         return IdentificationNumber;
     }
     if (e.Index == 7)
     {
         return ManufacturerID;
     }
     if (e.Index == 8)
     {
         return DataHeaderVersion;
     }
     if (e.Index == 9)
     {
         return DeviceType;
     }
     if (e.Index == 10)
     {
         return AccessNumber;
     }
     if (e.Index == 11)
     {
         return Status;
     }
     if (e.Index == 12)
     {
         return Alarm;
     }
     if (Version > 0)
     {
         if (e.Index == 13)
         {
             return Configuration;
         }
         if (e.Index == 14)
         {
             return EncryptionKeyStatus;
         }
     }
     e.Error = ErrorCode.ReadWriteDenied;
     return null;
 }
예제 #5
0
 /// <summary>
 /// Generates data notification message(s).
 /// </summary>
 /// <param name="time">Date time. Set To Min or Max if not added</param>
 /// <param name="data">Notification body.</param>
 /// <returns>Generated data notification message(s).</returns>
 public byte[][] GenerateDataNotificationMessages(DateTime time, GXByteBuffer data)
 {
     byte[][] reply;
     if (UseLogicalNameReferencing)
     {
         GXDLMSLNParameters p = new GXDLMSLNParameters(Settings, Command.DataNotification, 0, null, data, 0xff);
         p.time = time;
         p.time.Skip |= DateTimeSkips.Ms;
         reply = GXDLMS.GetLnMessages(p);
     }
     else
     {
         GXDLMSSNParameters p = new GXDLMSSNParameters(Settings, Command.DataNotification, 1, 0, data, null);
         reply = GXDLMS.GetSnMessages(p);
     }
     return reply;
 }
예제 #6
0
 /// <summary>
 /// Get sertificates as byte buffer.
 /// </summary>
 /// <returns></returns>
 private byte[] GetSertificates()
 {
     GXByteBuffer bb = new GXByteBuffer();
     bb.SetUInt8((byte)DataType.Array);
     GXCommon.SetObjectCount(Certificates.Count, bb);
     foreach (GXDLMSCertificateInfo it in Certificates)
     {
         bb.SetUInt8((byte)DataType.Structure);
         GXCommon.SetObjectCount(6, bb);
         bb.SetUInt8((byte)DataType.Enum);
         bb.SetUInt8((byte)it.Entity);
         bb.SetUInt8((byte)DataType.Enum);
         bb.SetUInt8((byte)it.Type);
         GXCommon.AddString(it.SerialNumber, bb);
         GXCommon.AddString(it.Issuer, bb);
         GXCommon.AddString(it.Subject, bb);
         GXCommon.AddString(it.SubjectAltName, bb);
     }
     return bb.Array();
 }
예제 #7
0
 object IGXDLMSBase.GetValue(GXDLMSSettings settings, ValueEventArgs e)
 {
     if (e.Index == 1)
     {
         return this.LogicalName;
     }
     if (e.Index == 2)
     {
         int cnt = 0;
         if (SapAssignmentList != null)
         {
             cnt = SapAssignmentList.Count;
         }
         GXByteBuffer data = new GXByteBuffer();
         data.SetUInt8((byte)DataType.Array);
         //Add count
         GXCommon.SetObjectCount(cnt, data);
         if (cnt != 0)
         {
             foreach (var it in SapAssignmentList)
             {
                 data.SetUInt8((byte)DataType.Structure);
                 data.SetUInt8((byte)2); //Count
                 GXCommon.SetData(settings, data, DataType.UInt16, it.Key);
                 GXCommon.SetData(settings, data, DataType.OctetString, ASCIIEncoding.ASCII.GetBytes(it.Value));
             }
         }
         return data.Array();
     }
     e.Error = ErrorCode.ReadWriteDenied;
     return null;
 }
예제 #8
0
 private byte[] ReportError(Command cmd, ErrorCode error)
 {
     switch (cmd)
     {
         case Command.ReadRequest:
             cmd = Command.ReadResponse;
             break;
         case Command.WriteRequest:
             cmd = Command.WriteResponse;
             break;
         case Command.GetRequest:
             cmd = Command.GetResponse;
             break;
         case Command.SetRequest:
             cmd = Command.SetResponse;
             break;
         case Command.MethodRequest:
             cmd = Command.MethodResponse;
             break;
         default:
             //Return HW error and close connection..
             break;
     }
     if (Settings.UseLogicalNameReferencing)
     {
         GXDLMS.GetLNPdu(new GXDLMSLNParameters(Settings, cmd, 1, null, null, (byte)error), replyData);
     }
     else
     {
         GXByteBuffer bb = new GXByteBuffer();
         bb.SetUInt8(error);
         GXDLMSSNParameters p = new GXDLMSSNParameters(Settings, cmd, 1, (byte)error, null, bb);
         GXDLMS.GetSNPdu(p, replyData);
     }
     if (this.InterfaceType == Enums.InterfaceType.WRAPPER)
     {
         return GXDLMS.GetWrapperFrame(Settings, replyData);
     }
     else
     {
         return GXDLMS.GetHdlcFrame(Settings, 0, replyData);
     }
 }
예제 #9
0
 ///<summary>
 ///Convert object to DLMS bytes.
 ///</summary>
 ///<param name="buff">
 ///Byte buffer where data is write.
 ///</param>
 ///<param name="type">
 ///Data type.
 ///</param>
 ///<param name="value">
 /// Added Value.
 ///</param>
 public static void SetData(GXByteBuffer buff, DataType type, object value)
 {
     GXCommon.SetData(null, buff, type, value);
 }
예제 #10
0
 /// <summary>
 /// Get object count. If first byte is 0x80 or higger it will tell bytes count.
 /// </summary>
 /// <param name="data">Received data.</param>
 /// <returns>Object count.</returns>
 public static int GetObjectCount(GXByteBuffer data)
 {
     return(GXCommon.GetObjectCount(data));
 }
예제 #11
0
 /// <summary>
 /// Set item count.
 /// </summary>
 /// <param name="count"></param>
 /// <param name="data"></param>
 internal static void SetObjectCount(int count, GXByteBuffer data)
 {
     GXCommon.SetObjectCount(count, data);
 }
예제 #12
0
        /// <summary>
        /// Load XML commands from the file.
        /// </summary>
        /// <param name="fileName"></param>
        /// <returns></returns>
        public byte[][] PduToMessages(GXDLMSXmlPdu pdu)
        {
            List <byte[]> messages = new List <byte[]>();

            if (pdu.Command == Command.Snrm)
            {
                messages.Add(pdu.Data);
            }
            else if (pdu.Command == Command.Ua)
            {
                messages.Add(pdu.Data);
            }
            else if (pdu.Command == Command.DisconnectRequest)
            {
                messages.Add(GXDLMS.GetHdlcFrame(Settings, (byte)Command.DisconnectRequest, new GXByteBuffer(pdu.Data)));
            }
            else
            {
                GXByteBuffer reply;
                if (Settings.InterfaceType == InterfaceType.WRAPPER)
                {
                    if (Ciphering.Security != Security.None)
                    {
                        GXDLMSLNParameters p = new GXDLMSLNParameters(this, Settings, 0, pdu.Command, 0x0, null, null, 0xff, Command.None);
                        reply = new GXByteBuffer(GXDLMS.Cipher0(p, pdu.Data));
                    }
                    else
                    {
                        reply = new GXByteBuffer(pdu.Data);
                    }
                }
                else
                {
                    if (Ciphering.Security != Security.None)
                    {
                        GXDLMSLNParameters p   = new GXDLMSLNParameters(this, Settings, 0, pdu.Command, 0x0, null, null, 0xff, Command.None);
                        byte[]             tmp = GXDLMS.Cipher0(p, pdu.Data);
                        reply = new GXByteBuffer((UInt16)(3 + tmp.Length));
                        reply.Set(GXCommon.LLCSendBytes);
                        reply.Set(tmp);
                    }
                    else
                    {
                        reply = new GXByteBuffer((UInt16)(3 + pdu.Data.Length));
                        reply.Set(GXCommon.LLCSendBytes);
                        reply.Set(pdu.Data);
                    }
                }
                byte frame = 0;
                while (reply.Position != reply.Size)
                {
                    if (Settings.InterfaceType == Enums.InterfaceType.WRAPPER)
                    {
                        messages.Add(GXDLMS.GetWrapperFrame(Settings, pdu.Command, reply));
                    }
                    else if (GXDLMS.UseHdlc(Settings.InterfaceType))
                    {
                        if (pdu.Command == Command.Aarq)
                        {
                            frame = 0x10;
                        }
                        else if (pdu.Command == Command.Aare)
                        {
                            frame = 0x30;
                        }
                        else if (pdu.Command == Command.EventNotification)
                        {
                            frame = 0x13;
                        }
                        messages.Add(GXDLMS.GetHdlcFrame(Settings, frame, reply));
                        if (reply.Position != reply.Size)
                        {
                            frame = Settings.NextSend(false);
                        }
                    }
                    else if (Settings.InterfaceType == Enums.InterfaceType.PDU)
                    {
                        messages.Add(reply.Array());
                        break;
                    }
                    else
                    {
                        throw new ArgumentOutOfRangeException("InterfaceType");
                    }
                }
            }
            return(messages.ToArray());
        }
예제 #13
0
        private List <GXDLMSXmlPdu> Load(XmlDocument doc, GXXmlLoadSettings settings)
        {
            //Remove comments.
            List <XmlNode> comments = new List <XmlNode>();

            foreach (XmlNode node in doc.SelectNodes("//comment()"))
            {
                comments.Add(node);
            }
            foreach (XmlNode node in comments)
            {
                node.ParentNode.RemoveChild(node);
            }
            List <GXDLMSXmlPdu> actions = new List <GXDLMSXmlPdu>();
            string description = null, error = null, errorUrl = null, sleep = null;

            foreach (XmlNode m1 in doc.ChildNodes)
            {
                if (m1.NodeType == XmlNodeType.Element)
                {
                    if (m1.Name == "AssociationRequest")
                    {
                        GXDLMSXmlSettings s = new GXDLMSXmlSettings(translator.OutputType, translator.Hex, translator.ShowStringAsHex, translator.tagsByName);
                        s.settings.ClientAddress = Settings.ClientAddress;
                        s.settings.ServerAddress = Settings.ServerAddress;
                        ((GXCiphering)s.settings.Cipher).TestMode = this.Ciphering.TestMode;
                        byte[]       reply = translator.XmlToPdu(m1.OuterXml, s);
                        GXDLMSXmlPdu p     = new GXDLMSXmlPdu(s.command, m1, reply);
                        actions.Add(p);
                        return(actions);
                    }
                    foreach (XmlNode node in m1.ChildNodes)
                    {
                        if (node.NodeType == XmlNodeType.Element)
                        {
                            if (node.Name == "Description")
                            {
                                description = node.Value;
                                continue;
                            }
                            if (node.Name == "Error")
                            {
                                error = node.Value;
                                continue;
                            }
                            if (node.Name == "ErrorUrl")
                            {
                                errorUrl = node.Value;
                                continue;
                            }
                            if (node.Name == "Sleep")
                            {
                                sleep = node.Value;
                                continue;
                            }
                            if (settings != null && node.Name == "GetRequest")
                            {
                                if (settings.Start != DateTime.MinValue && settings.End != DateTime.MinValue)
                                {
                                    foreach (XmlNode n1 in node.ChildNodes)
                                    {
                                        if (n1.Name == "GetRequestNormal")
                                        {
                                            foreach (XmlNode n2 in n1.ChildNodes)
                                            {
                                                if (n2.Name == "AccessSelection")
                                                {
                                                    foreach (XmlNode n3 in n2.ChildNodes)
                                                    {
                                                        if (n3.Name == "AccessSelector")
                                                        {
                                                            if (n3.Attributes["Value"].Value != "1")
                                                            {
                                                                break;
                                                            }
                                                        }
                                                        else if (n3.Name == "AccessParameters")
                                                        {
                                                            foreach (XmlNode n4 in n3.ChildNodes)
                                                            {
                                                                if (n4.Name == "Structure")
                                                                {
                                                                    bool start = true;
                                                                    foreach (XmlNode n5 in n4.ChildNodes)
                                                                    {
                                                                        if (n5.Name == "OctetString")
                                                                        {
                                                                            if (start)
                                                                            {
                                                                                GXByteBuffer bb = new GXByteBuffer();
                                                                                GXCommon.SetData(this.Settings, bb, DataType.OctetString, settings.Start);
                                                                                n5.Attributes["Value"].Value = bb.ToHex(false, 2);
                                                                                start = false;
                                                                            }
                                                                            else
                                                                            {
                                                                                GXByteBuffer bb = new GXByteBuffer();
                                                                                GXCommon.SetData(this.Settings, bb, DataType.OctetString, settings.End);
                                                                                n5.Attributes["Value"].Value = bb.ToHex(false, 2);
                                                                                break;
                                                                            }
                                                                        }
                                                                    }
                                                                }
                                                                break;
                                                            }
                                                            break;
                                                        }
                                                    }
                                                    break;
                                                }
                                            }
                                            break;
                                        }
                                    }
                                }
                            }

                            GXDLMSXmlSettings s = new GXDLMSXmlSettings(translator.OutputType, translator.ShowStringAsHex, translator.Hex, translator.tagsByName);;
                            s.settings.ClientAddress = Settings.ClientAddress;
                            s.settings.ServerAddress = Settings.ServerAddress;
                            byte[] reply = translator.XmlToPdu(node.OuterXml, s);
                            if (s.command == Command.Snrm && !s.settings.IsServer)
                            {
                                Settings.Hdlc.MaxInfoTX    = s.settings.Hdlc.MaxInfoTX;
                                Settings.Hdlc.MaxInfoRX    = s.settings.Hdlc.MaxInfoRX;
                                Settings.Hdlc.WindowSizeRX = s.settings.Hdlc.WindowSizeRX;
                                Settings.Hdlc.WindowSizeTX = s.settings.Hdlc.WindowSizeTX;
                            }
                            else if (s.command == Command.Ua && s.settings.IsServer)
                            {
                                Settings.Hdlc.MaxInfoTX    = s.settings.Hdlc.MaxInfoTX;
                                Settings.Hdlc.MaxInfoRX    = s.settings.Hdlc.MaxInfoRX;
                                Settings.Hdlc.WindowSizeRX = s.settings.Hdlc.WindowSizeRX;
                                Settings.Hdlc.WindowSizeTX = s.settings.Hdlc.WindowSizeTX;
                            }
                            if (s.template)
                            {
                                reply = null;
                            }
                            GXDLMSXmlPdu p = new GXDLMSXmlPdu(s.command, node, reply);
                            if (description != "")
                            {
                                p.Description = description;
                            }
                            if (error != "")
                            {
                                p.Error = error;
                            }
                            if (errorUrl != "")
                            {
                                p.ErrorUrl = errorUrl;
                            }
                            if (!string.IsNullOrEmpty(sleep))
                            {
                                p.Sleep = int.Parse(sleep);
                            }
                            actions.Add(p);
                        }
                    }
                }
            }
            return(actions);
        }
예제 #14
0
        ulong IConvertible.ToUInt64(IFormatProvider provider)
        {
            GXByteBuffer bb = GetByteBuffer(Value, 8);

            return(bb.GetUInt64());
        }
예제 #15
0
        uint IConvertible.ToUInt32(IFormatProvider provider)
        {
            GXByteBuffer bb = GetByteBuffer(Value, 4);

            return(bb.GetUInt32());
        }
예제 #16
0
        /// <summary>
        /// Get data for Read command.
        /// </summary>
        /// <param name="list">received objects.</param>
        /// <param name="data">Data as byte array.</param>
        /// <returns>Response type.</returns>
        private static SingleReadResponse GetReadData(GXDLMSSettings settings, ValueEventArgs[] list, GXByteBuffer data)
        {
            object             value;
            bool               first = true;
            SingleReadResponse type  = SingleReadResponse.Data;

            foreach (ValueEventArgs e in list)
            {
                if (e.Handled)
                {
                    value = e.Value;
                }
                else
                {
                    //If action.
                    if (e.action)
                    {
                        value = ((IGXDLMSBase)e.Target).Invoke(settings, e);
                    }
                    else
                    {
                        value = (e.Target as IGXDLMSBase).GetValue(settings, e);
                    }
                }
                if (e.Error == 0)
                {
                    if (!first && list.Length != 1)
                    {
                        data.SetUInt8(SingleReadResponse.Data);
                    }
                    //If action.
                    if (e.action)
                    {
                        GXCommon.SetData(settings, data, GXCommon.GetValueType(value), value);
                    }
                    else
                    {
                        GXDLMS.AppendData(settings, e.Target, e.Index, data, value);
                    }
                }
                else
                {
                    if (!first && list.Length != 1)
                    {
                        data.SetUInt8(SingleReadResponse.DataAccessError);
                    }
                    data.SetUInt8(e.Error);
                    type = SingleReadResponse.DataAccessError;
                }
                first = false;
            }
            return(type);
        }
예제 #17
0
 public GXByteBuffer(GXByteBuffer value)
 {
     Capacity = (value.Size - value.Position);
     Set(value);
 }
예제 #18
0
        /// <summary>
        /// Load XML commands from the file.
        /// </summary>
        /// <param name="fileName"></param>
        /// <returns></returns>
        public byte[][] PduToMessages(GXDLMSXmlPdu pdu)
        {
            List <byte[]> messages = new List <byte[]>();

            if (pdu.Command == Command.Snrm)
            {
                messages.Add(pdu.Data);
            }
            else if (pdu.Command == Command.Ua)
            {
                messages.Add(pdu.Data);
            }
            else if (pdu.Command == Command.DisconnectRequest)
            {
                messages.Add(GXDLMS.GetHdlcFrame(Settings, (byte)Command.DisconnectRequest, new GXByteBuffer(pdu.Data)));
            }
            else
            {
                GXByteBuffer reply;
                if (Settings.InterfaceType == Enums.InterfaceType.WRAPPER)
                {
                    reply = new GXByteBuffer(pdu.Data);
                }
                else
                {
                    reply = new GXByteBuffer((UInt16)(3 + pdu.Data.Length));
                    reply.Set(GXCommon.LLCSendBytes);
                    reply.Set(pdu.Data);
                }
                while (reply.Position != reply.Size)
                {
                    if (Settings.InterfaceType == Enums.InterfaceType.WRAPPER)
                    {
                        messages.Add(GXDLMS.GetWrapperFrame(Settings, reply));
                    }
                    else if (Settings.InterfaceType == Enums.InterfaceType.HDLC)
                    {
                        byte frame = 0;
                        if (pdu.Command == Command.Aarq)
                        {
                            frame = 0x10;
                        }
                        else if (pdu.Command == Command.Aare)
                        {
                            frame = 0x30;
                        }
                        else if (pdu.Command == Command.EventNotification)
                        {
                            frame = 0x13;
                        }
                        messages.Add(GXDLMS.GetHdlcFrame(Settings, frame, reply));
                        if (reply.Position != reply.Size)
                        {
                            if (Settings.IsServer || pdu.Command == Command.SetRequest ||
                                pdu.Command == Command.MethodRequest)
                            {
                                frame = 0;
                            }
                            else
                            {
                                frame = Settings.NextSend(false);
                            }
                        }
                    }
                    else if (Settings.InterfaceType == Enums.InterfaceType.PDU)
                    {
                        messages.Add(reply.Array());
                        break;
                    }
                    else
                    {
                        throw new ArgumentOutOfRangeException("InterfaceType");
                    }
                }
            }
            return(messages.ToArray());
        }
 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)
     {
         return (byte)Speed;
     }
     if (e.Index == 4)
     {
         GXByteBuffer data = new GXByteBuffer();
         data.SetUInt8((byte)DataType.Array);
         if (PrimaryAddresses == null)
         {
             data.SetUInt8(0);
         }
         else
         {
             data.SetUInt8((byte)PrimaryAddresses.Length);
             foreach (byte it in PrimaryAddresses)
             {
                 data.SetUInt8((byte)DataType.UInt8);
                 data.SetUInt8(it);
             }
         }
         return data.Array();
     }
     if (e.Index == 5)
     {
         GXByteBuffer data = new GXByteBuffer();
         data.SetUInt8((byte)DataType.Array);
         if (Tabis == null)
         {
             data.SetUInt8(0);
         }
         else
         {
             data.SetUInt8((byte)Tabis.Length);
             foreach (sbyte it in Tabis)
             {
                 data.SetUInt8((byte)DataType.UInt8);
                 data.SetUInt8((byte)it);
             }
         }
         return data.Array();
     }
     e.Error = ErrorCode.ReadWriteDenied;
     return null;
 }
예제 #20
0
 public byte[][] ImageBlockTransfer(GXDLMSClient client, byte[] imageBlockValue, out int ImageBlockCount)
 {
     ImageBlockCount = (int)(imageBlockValue.Length / ImageBlockSize);
     if (imageBlockValue.Length % ImageBlockSize != 0)
     {
         ++ImageBlockCount;
     }
     List<byte[]> packets = new List<byte[]>();
     for (int pos = 0; pos != ImageBlockCount; ++pos)
     {
         GXByteBuffer data = new GXByteBuffer();
         data.SetUInt8((byte)DataType.Structure);
         data.SetUInt8((byte)2);
         GXCommon.SetData(client.Settings, data, DataType.UInt32, pos);
         byte[] tmp;
         int bytes = (int)(imageBlockValue.Length - ((pos + 1) * ImageBlockSize));
         //If last packet
         if (bytes < 0)
         {
             bytes = (int)(imageBlockValue.Length - (pos * ImageBlockSize));
             tmp = new byte[bytes];
             Array.Copy(imageBlockValue, pos * ImageBlockSize, tmp, 0, bytes);
         }
         else
         {
             tmp = new byte[ImageBlockSize];
             Array.Copy(imageBlockValue, (pos * ImageBlockSize), tmp, 0, ImageBlockSize);
         }
         GXCommon.SetData(client.Settings, data, DataType.OctetString, tmp);
         packets.AddRange(client.Method(this, 2, data.Array(), DataType.Array));
     }
     return packets.ToArray();
 }
예제 #21
0
 /// <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.OctetString);
 }
예제 #22
0
 object IGXDLMSBase.GetValue(GXDLMSSettings settings, ValueEventArgs e)
 {
     if (e.Index == 1)
     {
         return this.LogicalName;
     }
     if (e.Index == 2)
     {
         return ImageBlockSize;
     }
     if (e.Index == 3)
     {
         return ImageTransferredBlocksStatus;
     }
     if (e.Index == 4)
     {
         return ImageFirstNotTransferredBlockNumber;
     }
     if (e.Index == 5)
     {
         return ImageTransferEnabled;
     }
     if (e.Index == 6)
     {
         return ImageTransferStatus;
     }
     if (e.Index == 7)
     {
         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);
                 GXCommon.SetData(settings, data, DataType.OctetString, ASCIIEncoding.ASCII.GetBytes(Convert.ToString(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();
     }
     e.Error = ErrorCode.ReadWriteDenied;
     return null;
 }
예제 #23
0
 /// <summary>
 /// Add value of COSEM object to byte buffer.
 /// </summary>
 /// <param name="obj">COSEM object.</param>
 /// <param name="index">Attribute index.</param>
 /// <param name="buff">Byte buffer.</param>
 /// <remarks>
 /// AddData method can be used with GetDataNotificationMessage -method.
 /// DLMS spesification do not specify the structure of Data-Notification body.
 /// So each manufacture can sent different data.
 /// </remarks>
 /// <seealso cref="GetDataNotificationMessages"/>
 internal static void AddData(GXDLMSSettings settings, GXDLMSObject obj, int index, GXByteBuffer buff)
 {
     DataType dt;
     object value = (obj as IGXDLMSBase).GetValue(settings, new ValueEventArgs(settings, obj, index, 0, null));
     dt = obj.GetDataType(index);
     if (dt == DataType.None && value != null)
     {
         dt = GXCommon.GetValueType(value);
     }
     GXCommon.SetData(settings, buff, dt, value);
 }
예제 #24
0
        private static void HanleSetRequestWithList(GXDLMSSettings settings, byte invokeID, GXDLMSServer server, GXByteBuffer data, GXDLMSLNParameters p, GXByteBuffer replyData, GXDLMSTranslatorStructure xml)
        {
            ValueEventArgs        e;
            int                   cnt  = GXCommon.GetObjectCount(data);
            List <ValueEventArgs> list = new List <ValueEventArgs>();

            if (xml != null)
            {
                xml.AppendStartTag(TranslatorTags.AttributeDescriptorList, "Qty", xml.IntegerToHex(cnt, 2));
            }
            try
            {
                for (int pos = 0; pos != cnt; ++pos)
                {
                    ObjectType ci = (ObjectType)data.GetUInt16();
                    byte[]     ln = new byte[6];
                    data.Get(ln);
                    short attributeIndex = data.GetUInt8();
                    // AccessSelection
                    int    selection  = data.GetUInt8();
                    int    selector   = 0;
                    object parameters = null;
                    if (selection != 0)
                    {
                        selector = data.GetUInt8();
                        GXDataInfo info = new GXDataInfo();
                        parameters = GXCommon.GetData(settings, data, info);
                    }
                    if (xml != null)
                    {
                        xml.AppendStartTag(TranslatorTags.AttributeDescriptorWithSelection);
                        xml.AppendStartTag(TranslatorTags.AttributeDescriptor);
                        xml.AppendComment(ci.ToString());
                        xml.AppendLine(TranslatorTags.ClassId, "Value", xml.IntegerToHex((int)ci, 4));
                        xml.AppendComment(GXCommon.ToLogicalName(ln));
                        xml.AppendLine(TranslatorTags.InstanceId, "Value", GXCommon.ToHex(ln, false));
                        xml.AppendLine(TranslatorTags.AttributeId, "Value", xml.IntegerToHex(attributeIndex, 2));
                        xml.AppendEndTag(TranslatorTags.AttributeDescriptor);
                        xml.AppendEndTag(TranslatorTags.AttributeDescriptorWithSelection);
                    }
                    else
                    {
                        GXDLMSObject obj = settings.Objects.FindByLN(ci, GXCommon.ToLogicalName(ln));
                        if (obj == null)
                        {
                            obj = server.NotifyFindObject(ci, 0, GXCommon.ToLogicalName(ln));
                        }
                        if (obj == null)
                        {
                            // "Access Error : Device reports a undefined object."
                            e       = new ValueEventArgs(server, obj, attributeIndex, 0, 0);
                            e.Error = ErrorCode.UndefinedObject;
                            list.Add(e);
                        }
                        else
                        {
                            ValueEventArgs arg = new ValueEventArgs(server, obj, attributeIndex, selector, parameters);
                            arg.InvokeId = invokeID;
                            if (server.NotifyGetAttributeAccess(arg) == AccessMode.NoAccess)
                            {
                                //Read Write denied.
                                arg.Error = ErrorCode.ReadWriteDenied;
                                list.Add(arg);
                            }
                            else
                            {
                                list.Add(arg);
                            }
                        }
                    }
                }
                cnt = GXCommon.GetObjectCount(data);
                if (xml != null)
                {
                    xml.AppendEndTag(TranslatorTags.AttributeDescriptorList);
                    xml.AppendStartTag(TranslatorTags.ValueList, "Qty", xml.IntegerToHex(cnt, 2));
                }
                for (int pos = 0; pos != cnt; ++pos)
                {
                    GXDataInfo di = new GXDataInfo();
                    di.xml = xml;
                    if (xml != null && xml.OutputType == TranslatorOutputType.StandardXml)
                    {
                        xml.AppendStartTag(Command.WriteRequest, SingleReadResponse.Data);
                    }
                    object value = GXCommon.GetData(settings, data, di);
                    if (!di.Complete)
                    {
                        value = GXCommon.ToHex(data.Data, false, data.Position, data.Size - data.Position);
                    }
                    else if (value is byte[])
                    {
                        value = GXCommon.ToHex((byte[])value, false);
                    }
                    if (xml != null && xml
                        .OutputType == TranslatorOutputType.StandardXml)
                    {
                        xml.AppendEndTag(Command.WriteRequest, SingleReadResponse.Data);
                    }
                }
                if (xml != null)
                {
                    xml.AppendEndTag(TranslatorTags.ValueList);
                }
            }
            catch (Exception ex)
            {
                if (xml == null)
                {
                    throw ex;
                }
            }
        }
예제 #25
0
 /// <summary>
 /// Generates push setup message.
 /// </summary>
 /// <param name="date"> Date time. Set To Min or Max if not added.</param>
 /// <param name="push">Target Push object.</param>
 /// <returns>Generated data notification message(s).</returns>
 public byte[][] GeneratePushSetupMessages(DateTime date, GXDLMSPushSetup push)
 {
     if (push == null)
     {
         throw new ArgumentNullException("push");
     }
     GXByteBuffer buff = new GXByteBuffer();
     buff.SetUInt8((byte)DataType.Structure);
     GXCommon.SetObjectCount(push.PushObjectList.Count, buff);
     foreach (KeyValuePair<GXDLMSObject, GXDLMSCaptureObject> it in push.PushObjectList)
     {
         AddData(it.Key, it.Value.AttributeIndex, buff);
     }
     return GenerateDataNotificationMessages(date, buff);
 }
예제 #26
0
        ///<summary>
        /// Handle received command.
        ///</summary>
        private byte[] HandleCommand(Command cmd, GXByteBuffer data, GXDLMSConnectionEventArgs connectionInfo)
        {
            byte frame = 0;

            switch (cmd)
            {
            case Command.AccessRequest:
                GXDLMSLNCommandHandler.HandleAccessRequest(Settings, this, data, replyData, null);
                break;

            case Command.SetRequest:
                GXDLMSLNCommandHandler.HandleSetRequest(Settings, this, data, replyData, null);
                break;

            case Command.WriteRequest:
                GXDLMSSNCommandHandler.HandleWriteRequest(Settings, this, data, replyData, null);
                break;

            case Command.GetRequest:
                if (data.Size != 0)
                {
                    GXDLMSLNCommandHandler.HandleGetRequest(Settings, this, data, replyData, null);
                }
                break;

            case Command.ReadRequest:
                GXDLMSSNCommandHandler.HandleReadRequest(Settings, this, data, replyData, null);
                break;

            case Command.MethodRequest:
                GXDLMSLNCommandHandler.HandleMethodRequest(Settings, this, data, connectionInfo, replyData, null);
                break;

            case Command.Snrm:
                HandleSnrmRequest();
                frame = (byte)Command.Ua;
                break;

            case Command.Aarq:
                HandleAarqRequest(data, connectionInfo);
                break;

            case Command.ReleaseRequest:
                HandleReleaseRequest(data, connectionInfo);
                break;

            case Command.DisconnectRequest:
                GenerateDisconnectRequest();
                Settings.Connected = false;
                Disconnected(connectionInfo);
                frame = (byte)Command.Ua;
                break;

            case Command.None:
                //Get next frame.
                break;

            default:
                Debug.WriteLine("Invalid command: " + (int)cmd);
                break;
            }
            byte[] reply;
            if (this.InterfaceType == Enums.InterfaceType.WRAPPER)
            {
                reply = GXDLMS.GetWrapperFrame(Settings, replyData);
            }
            else
            {
                reply = GXDLMS.GetHdlcFrame(Settings, frame, replyData);
            }
            return(reply);
        }
예제 #27
0
 object IGXDLMSBase.GetValue(GXDLMSSettings settings, ValueEventArgs e)
 {
     if (e.Index == 1)
     {
         return this.LogicalName;
     }
     if (e.Index == 2)
     {
         return this.CurrentAverageValue;
     }
     if (e.Index == 3)
     {
         return this.LastAverageValue;
     }
     if (e.Index == 4)
     {
         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();
     }
     if (e.Index == 5)
     {
         return this.Status;
     }
     if (e.Index == 6)
     {
         return CaptureTime;
     }
     if (e.Index == 7)
     {
         return StartTimeCurrent;
     }
     if (e.Index == 8)
     {
         return Period;
     }
     if (e.Index == 9)
     {
         return NumberOfPeriods;
     }
     e.Error = ErrorCode.ReadWriteDenied;
     return null;
 }
예제 #28
0
        ///<summary>
        ///Parse AARQ request that client send and returns AARE request.
        /// </summary>
        ///<returns>
        ///Reply to the client.
        ///</returns>
        private void HandleAarqRequest(GXByteBuffer data, GXDLMSConnectionEventArgs connectionInfo)
        {
            GXByteBuffer      error  = null;
            AssociationResult result = AssociationResult.Accepted;

            Settings.CtoSChallenge = null;
            if (!Settings.UseCustomChallenge)
            {
                Settings.StoCChallenge = null;
            }
            // Reset settings for wrapper.
            if (Settings.InterfaceType == InterfaceType.WRAPPER)
            {
                Reset(true);
            }
            SourceDiagnostic diagnostic = SourceDiagnostic.NoReasonGiven;

            try
            {
                diagnostic = GXAPDU.ParsePDU(Settings, Settings.Cipher, data, null);
                if (diagnostic != SourceDiagnostic.None)
                {
                    result     = AssociationResult.PermanentRejected;
                    diagnostic = SourceDiagnostic.ApplicationContextNameNotSupported;
                    InvalidConnection(connectionInfo);
                }
                else
                {
                    diagnostic = ValidateAuthentication(Settings.Authentication, Settings.Password);
                    if (diagnostic != SourceDiagnostic.None)
                    {
                        result = AssociationResult.PermanentRejected;
                        InvalidConnection(connectionInfo);
                    }
                    else if (Settings.Authentication > Authentication.Low)
                    {
                        // If High authentication is used.
                        if (!Settings.UseCustomChallenge)
                        {
                            Settings.StoCChallenge = GXSecure.GenerateChallenge(Settings.Authentication);
                        }
                        result     = AssociationResult.Accepted;
                        diagnostic = SourceDiagnostic.AuthenticationRequired;
                    }
                    else
                    {
                        Connected(connectionInfo);
                        Settings.Connected = true;
                    }
                }
                Settings.IsAuthenticationRequired = diagnostic == SourceDiagnostic.AuthenticationRequired;
            }
            catch (GXDLMSConfirmedServiceError e)
            {
                result     = AssociationResult.PermanentRejected;
                diagnostic = SourceDiagnostic.NoReasonGiven;
                error      = new GXByteBuffer();
                error.SetUInt8(0xE);
                error.SetUInt8(e.ConfirmedServiceError);
                error.SetUInt8(e.ServiceError);
                error.SetUInt8(e.ServiceErrorValue);
            }
            if (Settings.InterfaceType == Enums.InterfaceType.HDLC)
            {
                replyData.Set(GXCommon.LLCReplyBytes);
            }
            // Generate AARE packet.
            GXAPDU.GenerateAARE(Settings, replyData, result, diagnostic, Settings.Cipher, error, null);
        }
예제 #29
0
 /// <summary>
 /// Set new value to byte array.
 /// </summary>
 /// <param name="value">Byte array to add.</param>
 /// <param name="index">Byte index.</param>
 /// <param name="count">Byte count.</param>
 public void Set(GXByteBuffer value, int count)
 {
     if (Size + count > Capacity)
     {
         Capacity = (Size + count + ArrayCapacity);
     }
     if (count != 0)
     {
         Buffer.BlockCopy(value.Data, value.Position, Data, Size, count);
         Size += count;
         value.Position += (ushort)count;
     }
 }
        ///<summary>
        ///Handle set request.
        ///</summary>
        ///<returns>
        ///Reply to the client.
        ///</returns>
        public static void HandleSetRequest(GXDLMSSettings settings, GXDLMSServer server, GXByteBuffer data, GXByteBuffer replyData, GXDLMSTranslatorStructure xml)
        {
            //Return error if connection is not established.
            if (xml == null && !settings.Connected)
            {
                replyData.Set(GXDLMSServer.GenerateConfirmedServiceError(ConfirmedServiceError.InitiateError,
                                                                         ServiceError.Service, (byte)Service.Unsupported));
                return;
            }
            // Get type.
            SetRequestType type = (SetRequestType)data.GetUInt8();
            // Get invoke ID and priority.
            byte invoke = data.GetUInt8();
            // SetRequest normal or Set Request With First Data Block
            GXDLMSLNParameters p = new GXDLMSLNParameters(settings, invoke, Command.SetResponse, (byte)type, null, null, 0);

            if (xml != null)
            {
                xml.AppendStartTag(Command.SetRequest);
                xml.AppendStartTag(Command.SetRequest, type);
                //InvokeIdAndPriority
                xml.AppendLine(TranslatorTags.InvokeId, "Value", xml.IntegerToHex(invoke, 2));
            }
            switch (type)
            {
            case SetRequestType.Normal:
            case SetRequestType.FirstDataBlock:
                HandleSetRequestNormal(settings, server, data, (byte)type, p, replyData, xml);
                break;

            case SetRequestType.WithDataBlock:
                HanleSetRequestWithDataBlock(settings, server, data, p, replyData, xml);
                break;

            default:
                System.Diagnostics.Debug.WriteLine("HandleSetRequest failed. Unknown command.");
                settings.ResetBlockIndex();
                p.status = (byte)ErrorCode.HardwareFault;
                break;
            }
            if (xml != null)
            {
                xml.AppendEndTag(Command.SetRequest, type);
                xml.AppendEndTag(Command.SetRequest);
                return;
            }
            GXDLMS.GetLNPdu(p, replyData);
        }
예제 #31
0
        private static void ReturnSNError(GXDLMSSettings settings, GXDLMSServer server, Command cmd, ErrorCode error, GXByteBuffer replyData)
        {
            GXByteBuffer bb = new GXByteBuffer();

            bb.SetUInt8(error);
            GXDLMS.GetSNPdu(new GXDLMSSNParameters(settings, cmd, 1, (byte)SingleReadResponse.DataAccessError, bb, null), replyData);
            settings.ResetBlockIndex();
        }
        ///<summary>
        /// Handle action request.
        ///</summary>
        public static void HandleMethodRequest(GXDLMSSettings settings, GXDLMSServer server, GXByteBuffer data, GXDLMSConnectionEventArgs connectionInfo, GXByteBuffer replyData, GXDLMSTranslatorStructure xml)
        {
            ErrorCode    error = ErrorCode.Ok;
            GXByteBuffer bb    = new GXByteBuffer();
            // Get type.
            ActionRequestType type = (ActionRequestType)data.GetUInt8();
            // Get invoke ID and priority.
            byte invokeId = data.GetUInt8();
            // CI
            ObjectType ci = (ObjectType)data.GetUInt16();

            byte[] ln = new byte[6];
            data.Get(ln);
            // Attribute Id
            byte id = data.GetUInt8();
            // Get parameters.
            object parameters = null;
            byte   selection  = data.GetUInt8();

            if (xml != null)
            {
                xml.AppendStartTag(Command.MethodRequest);
                if (type == ActionRequestType.Normal)
                {
                    xml.AppendStartTag(Command.MethodRequest, ActionRequestType.Normal);
                    xml.AppendLine(TranslatorTags.InvokeId, "Value", xml.IntegerToHex(invokeId, 2));
                    AppendMethodDescriptor(xml, (int)ci, ln, id);
                    if (selection != 0)
                    {
                        //MethodInvocationParameters
                        xml.AppendStartTag(TranslatorTags.MethodInvocationParameters);
                        GXDataInfo di = new GXDataInfo();
                        di.xml = xml;
                        GXCommon.GetData(settings, data, di);
                        xml.AppendEndTag(TranslatorTags.MethodInvocationParameters);
                    }
                    xml.AppendEndTag(Command.MethodRequest, ActionRequestType.Normal);
                }
                xml.AppendEndTag(Command.MethodRequest);
                return;
            }
            if (selection != 0)
            {
                GXDataInfo info = new GXDataInfo();
                parameters = GXCommon.GetData(settings, data, info);
            }

            GXDLMSObject obj = settings.Objects.FindByLN(ci, GXCommon.ToLogicalName(ln));

            if (!settings.Connected && (ci != ObjectType.AssociationLogicalName || id != 1))
            {
                replyData.Set(GXDLMSServer.GenerateConfirmedServiceError(ConfirmedServiceError.InitiateError,
                                                                         ServiceError.Service, (byte)Service.Unsupported));
                return;
            }

            if (obj == null)
            {
                obj = server.NotifyFindObject(ci, 0, GXCommon.ToLogicalName(ln));
            }
            if (obj == null)
            {
                // Device reports a undefined object.
                error = ErrorCode.UndefinedObject;
            }
            else
            {
                ValueEventArgs e = new ValueEventArgs(server, obj, id, 0, parameters);
                e.InvokeId = invokeId;
                if (server.NotifyGetMethodAccess(e) == MethodAccessMode.NoAccess)
                {
                    error = ErrorCode.ReadWriteDenied;
                }
                else
                {
                    server.NotifyAction(new ValueEventArgs[] { e });
                    byte[] actionReply;
                    if (e.Handled)
                    {
                        actionReply = (byte[])e.Value;
                    }
                    else
                    {
                        actionReply = (obj as IGXDLMSBase).Invoke(settings, e);
                        server.NotifyPostAction(new ValueEventArgs[] { e });
                    }
                    //Set default action reply if not given.
                    if (actionReply != null && e.Error == 0)
                    {
                        //Add return parameters
                        bb.SetUInt8(1);
                        //Add parameters error code.
                        bb.SetUInt8(0);
                        GXCommon.SetData(settings, bb, GXCommon.GetValueType(actionReply), actionReply);
                    }
                    else
                    {
                        error = e.Error;
                        //Add return parameters
                        bb.SetUInt8(0);
                    }
                }
                invokeId = (byte)e.InvokeId;
            }

            GXDLMSLNParameters p = new GXDLMSLNParameters(settings, invokeId, Command.MethodResponse, 1, null, bb, (byte)error);

            GXDLMS.GetLNPdu(p, replyData);
            //If High level authentication fails.
            if (!settings.Connected && obj is GXDLMSAssociationLogicalName && id == 1)
            {
                server.NotifyInvalidConnection(connectionInfo);
            }
        }
예제 #33
0
 ///<summary>
 /// Constructor.
 ///</summary>
 public GXReplyData()
 {
     Data = new GXByteBuffer();
     Clear();
 }
        /// <summary>
        /// Handle get request normal command.
        /// </summary>
        /// <param name="data">Received data.</param>
        private static void GetRequestNormal(GXDLMSSettings settings, byte invokeID, GXDLMSServer server, GXByteBuffer data, GXByteBuffer replyData, GXDLMSTranslatorStructure xml)
        {
            ValueEventArgs e  = null;
            GXByteBuffer   bb = new GXByteBuffer();
            // Get type.
            ErrorCode status = ErrorCode.Ok;

            settings.Count = settings.Index = 0;
            settings.ResetBlockIndex();
            // CI
            ObjectType ci = (ObjectType)data.GetUInt16();

            byte[] ln = new byte[6];
            data.Get(ln);
            // Attribute Id
            byte attributeIndex = data.GetUInt8();

            // AccessSelection
            byte       selection  = data.GetUInt8();
            byte       selector   = 0;
            object     parameters = null;
            GXDataInfo info       = new GXDataInfo();

            if (selection != 0)
            {
                selector = data.GetUInt8();
            }
            if (xml != null)
            {
                AppendAttributeDescriptor(xml, (int)ci, ln, attributeIndex);
                if (selection != 0)
                {
                    info.xml = xml;
                    xml.AppendStartTag(TranslatorTags.AccessSelection);
                    xml.AppendLine(TranslatorTags.AccessSelector, "Value", xml.IntegerToHex(selector, 2));
                    xml.AppendStartTag(TranslatorTags.AccessParameters);
                    GXCommon.GetData(settings, data, info);
                    xml.AppendEndTag(TranslatorTags.AccessParameters);
                    xml.AppendEndTag(TranslatorTags.AccessSelection);
                }
                return;
            }
            if (selection != 0)
            {
                parameters = GXCommon.GetData(settings, data, info);
            }

            GXDLMSObject obj = settings.Objects.FindByLN(ci, GXCommon.ToLogicalName(ln));

            if (obj == null)
            {
                obj = server.NotifyFindObject(ci, 0, GXCommon.ToLogicalName(ln));
            }
            e = new ValueEventArgs(server, obj, attributeIndex, selector, parameters);
            if (obj == null)
            {
                // "Access Error : Device reports a undefined object."
                status = ErrorCode.UndefinedObject;
            }
            else
            {
                e.InvokeId = invokeID;
                if (server.NotifyGetAttributeAccess(e) == AccessMode.NoAccess)
                {
                    //Read Write denied.
                    status = ErrorCode.ReadWriteDenied;
                }
                else
                {
                    if (e.Target is GXDLMSProfileGeneric && attributeIndex == 2)
                    {
                        e.RowToPdu = GXDLMS.RowsToPdu(settings, (GXDLMSProfileGeneric)e.Target);
                    }
                    object value;
                    server.NotifyRead(new ValueEventArgs[] { e });
                    if (e.Handled)
                    {
                        value = e.Value;
                    }
                    else
                    {
                        settings.Count = e.RowEndIndex - e.RowBeginIndex;
                        value          = (obj as IGXDLMSBase).GetValue(settings, e);
                    }
                    if (e.ByteArray)
                    {
                        bb.Set((byte[])value);
                    }
                    else
                    {
                        GXDLMS.AppendData(settings, obj, attributeIndex, bb, value);
                    }
                    server.NotifyPostRead(new ValueEventArgs[] { e });
                    status = e.Error;
                }
            }
            GXDLMS.GetLNPdu(new GXDLMSLNParameters(settings, e.InvokeId, Command.GetResponse, 1, null, bb, (byte)status), replyData);
            if (settings.Count != settings.Index || bb.Size != bb.Position)
            {
                server.transaction = new GXDLMSLongTransaction(new ValueEventArgs[] { e }, Command.GetRequest, bb);
            }
        }
예제 #35
0
 ///<summary>
 /// Handle received command.
 ///</summary>
 private byte[] HandleCommand(Command cmd, GXByteBuffer data, GXDLMSConnectionEventArgs connectionInfo)
 {
     byte frame = 0;
     switch (cmd)
     {
         case Command.AccessRequest:
             GXDLMSLNCommandHandler.HandleAccessRequest(Settings, this, data, replyData, null);
             break;
         case Command.SetRequest:
             GXDLMSLNCommandHandler.HandleSetRequest(Settings, this, data, replyData, null);
             break;
         case Command.WriteRequest:
             GXDLMSSNCommandHandler.HandleWriteRequest(Settings, this, data, replyData, null);
             break;
         case Command.GetRequest:
             if (data.Size != 0)
             {
                 GXDLMSLNCommandHandler.HandleGetRequest(Settings, this, data, replyData, null);
             }
             break;
         case Command.ReadRequest:
             GXDLMSSNCommandHandler.HandleReadRequest(Settings, this, data, replyData, null);
             break;
         case Command.MethodRequest:
             GXDLMSLNCommandHandler.HandleMethodRequest(Settings, this, data, connectionInfo, replyData, null);
             break;
         case Command.Snrm:
             HandleSnrmRequest();
             frame = (byte)Command.Ua;
             break;
         case Command.Aarq:
             HandleAarqRequest(data, connectionInfo);
             break;
         case Command.ReleaseRequest:
         case Command.DisconnectRequest:
             GenerateDisconnectRequest();
             Settings.Connected = false;
             Disconnected(connectionInfo);
             frame = (byte)Command.Ua;
             break;
         case Command.None:
             //Get next frame.
             break;
         default:
             Debug.WriteLine("Invalid command: " + (int)cmd);
             break;
     }
     byte[] reply;
     if (this.InterfaceType == Enums.InterfaceType.WRAPPER)
     {
         reply = GXDLMS.GetWrapperFrame(Settings, replyData);
     }
     else
     {
         reply = GXDLMS.GetHdlcFrame(Settings, frame, replyData);
     }
     return reply;
 }
        /// <summary>
        /// Handle get request next data block command.
        /// </summary>
        /// <param name="data">Received data.</param>
        private static void GetRequestNextDataBlock(GXDLMSSettings settings, byte invokeID, GXDLMSServer server, GXByteBuffer data, GXByteBuffer replyData, GXDLMSTranslatorStructure xml)
        {
            GXByteBuffer bb = new GXByteBuffer();
            uint         index;

            // Get block index.
            index = data.GetUInt32();
            if (xml != null)
            {
                xml.AppendLine(TranslatorTags.BlockNumber, null, xml.IntegerToHex(index, 8));
                return;
            }
            if (index != settings.BlockIndex)
            {
                Debug.WriteLine("handleGetRequest failed. Invalid block number. " + settings.BlockIndex + "/" + index);
                GXDLMS.GetLNPdu(new GXDLMSLNParameters(settings, 0, Command.GetResponse, 2, null, bb, (byte)ErrorCode.DataBlockNumberInvalid), replyData);
            }
            else
            {
                settings.IncreaseBlockIndex();
                GXDLMSLNParameters p = new GXDLMSLNParameters(settings, invokeID, Command.GetResponse, 2, null, bb, (byte)ErrorCode.Ok);
                //If transaction is not in progress.
                if (server.transaction == null)
                {
                    p.status = (byte)ErrorCode.NoLongGetOrReadInProgress;
                }
                else
                {
                    bb.Set(server.transaction.data);
                    bool moreData = settings.Index != settings.Count;
                    if (moreData)
                    {
                        //If there is multiple blocks on the buffer.
                        //This might happen when Max PDU size is very small.
                        if (bb.Size < settings.MaxPduSize)
                        {
                            foreach (ValueEventArgs arg in server.transaction.targets)
                            {
                                object value;
                                server.NotifyRead(new ValueEventArgs[] { arg });
                                if (arg.Handled)
                                {
                                    value = arg.Value;
                                }
                                else
                                {
                                    value = (arg.Target as IGXDLMSBase).GetValue(settings, arg);
                                }
                                //Add data.
                                if (arg.ByteArray)
                                {
                                    bb.Set((byte[])value);
                                }
                                else
                                {
                                    GXDLMS.AppendData(settings, arg.Target, arg.Index, bb, value);
                                }
                            }
                            moreData = settings.Index != settings.Count;
                        }
                    }
                    p.multipleBlocks = true;
                    GXDLMS.GetLNPdu(p, replyData);
                    if (moreData || bb.Size - bb.Position != 0)
                    {
                        server.transaction.data = bb;
                    }
                    else
                    {
                        server.transaction = null;
                        settings.ResetBlockIndex();
                    }
                }
            }
        }
예제 #37
0
 ///<summary>
 ///Parse AARQ request that client send and returns AARE request.
 /// </summary>
 ///<returns>
 ///Reply to the client.
 ///</returns>
 private void HandleAarqRequest(GXByteBuffer data, GXDLMSConnectionEventArgs connectionInfo)
 {
     AssociationResult result = AssociationResult.Accepted;
     Settings.CtoSChallenge = null;
     if (!Settings.UseCustomChallenge)
     {
         Settings.StoCChallenge = null;
     }
     // Reset settings for wrapper.
     if (Settings.InterfaceType == InterfaceType.WRAPPER)
     {
         Reset(true);
     }
     SourceDiagnostic diagnostic = GXAPDU.ParsePDU(Settings, Settings.Cipher, data, null);
     if (diagnostic != SourceDiagnostic.None)
     {
         result = AssociationResult.PermanentRejected;
         diagnostic = SourceDiagnostic.ApplicationContextNameNotSupported;
         InvalidConnection(connectionInfo);
     }
     else
     {
         diagnostic = ValidateAuthentication(Settings.Authentication, Settings.Password);
         if (diagnostic != SourceDiagnostic.None)
         {
             result = AssociationResult.PermanentRejected;
             InvalidConnection(connectionInfo);
         }
         else if (Settings.Authentication > Authentication.Low)
         {
             // If High authentication is used.
             Settings.StoCChallenge = GXSecure.GenerateChallenge(Settings.Authentication);
             result = AssociationResult.Accepted;
             diagnostic = SourceDiagnostic.AuthenticationRequired;
         }
         else
         {
             Connected(connectionInfo);
             Settings.Connected = true;
         }
     }
     Settings.IsAuthenticationRequired = diagnostic == SourceDiagnostic.AuthenticationRequired;
     if (Settings.InterfaceType == Enums.InterfaceType.HDLC)
     {
         replyData.Set(GXCommon.LLCReplyBytes);
     }
     // Generate AARE packet.
     GXAPDU.GenerateAARE(Settings, replyData, result, diagnostic, Settings.Cipher, null);
 }
        /// <summary>
        /// Handle get request with list command.
        /// </summary>
        /// <param name="data">Received data.</param>
        private static void GetRequestWithList(GXDLMSSettings settings, byte invokeID, GXDLMSServer server, GXByteBuffer data, GXByteBuffer replyData, GXDLMSTranslatorStructure xml)
        {
            ValueEventArgs e;
            GXByteBuffer   bb = new GXByteBuffer();
            int            pos;
            int            cnt = GXCommon.GetObjectCount(data);

            GXCommon.SetObjectCount(cnt, bb);
            List <ValueEventArgs> list = new List <ValueEventArgs>();

            if (xml != null)
            {
                xml.AppendStartTag(TranslatorTags.AttributeDescriptorList, "Qty", xml.IntegerToHex(cnt, 2));
            }
            try
            {
                for (pos = 0; pos != cnt; ++pos)
                {
                    ObjectType ci = (ObjectType)data.GetUInt16();
                    byte[]     ln = new byte[6];
                    data.Get(ln);
                    short attributeIndex = data.GetUInt8();
                    // AccessSelection
                    int    selection  = data.GetUInt8();
                    int    selector   = 0;
                    object parameters = null;
                    if (selection != 0)
                    {
                        selector = data.GetUInt8();
                        GXDataInfo info = new GXDataInfo();
                        parameters = GXCommon.GetData(settings, data, info);
                    }
                    if (xml != null)
                    {
                        xml.AppendStartTag(TranslatorTags.AttributeDescriptorWithSelection);
                        xml.AppendStartTag(TranslatorTags.AttributeDescriptor);
                        xml.AppendComment(ci.ToString());
                        xml.AppendLine(TranslatorTags.ClassId, "Value", xml.IntegerToHex((int)ci, 4));
                        xml.AppendComment(GXCommon.ToLogicalName(ln));
                        xml.AppendLine(TranslatorTags.InstanceId, "Value", GXCommon.ToHex(ln, false));
                        xml.AppendLine(TranslatorTags.AttributeId, "Value", xml.IntegerToHex(attributeIndex, 2));
                        xml.AppendEndTag(TranslatorTags.AttributeDescriptor);
                        xml.AppendEndTag(TranslatorTags.AttributeDescriptorWithSelection);
                    }
                    else
                    {
                        GXDLMSObject obj = settings.Objects.FindByLN(ci, GXCommon.ToLogicalName(ln));
                        if (obj == null)
                        {
                            obj = server.NotifyFindObject(ci, 0, GXCommon.ToLogicalName(ln));
                        }
                        if (obj == null)
                        {
                            // "Access Error : Device reports a undefined object."
                            e       = new ValueEventArgs(server, obj, attributeIndex, 0, 0);
                            e.Error = ErrorCode.UndefinedObject;
                            list.Add(e);
                        }
                        else
                        {
                            ValueEventArgs arg = new ValueEventArgs(server, obj, attributeIndex, selector, parameters);
                            arg.InvokeId = invokeID;
                            if (server.NotifyGetAttributeAccess(arg) == AccessMode.NoAccess)
                            {
                                //Read Write denied.
                                arg.Error = ErrorCode.ReadWriteDenied;
                                list.Add(arg);
                            }
                            else
                            {
                                list.Add(arg);
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                if (xml == null)
                {
                    throw ex;
                }
            }
            if (xml != null)
            {
                xml.AppendEndTag(TranslatorTags.AttributeDescriptorList);
                return;
            }

            server.NotifyRead(list.ToArray());
            object value;

            pos = 0;
            foreach (ValueEventArgs it in list)
            {
                try
                {
                    if (it.Handled)
                    {
                        value = it.Value;
                    }
                    else
                    {
                        value = (it.Target as IGXDLMSBase).GetValue(settings, it);
                    }
                    bb.SetUInt8(it.Error);
                    if (it.ByteArray)
                    {
                        bb.Set((byte[])value);
                    }
                    else
                    {
                        GXDLMS.AppendData(settings, it.Target, it.Index, bb, value);
                    }
                    invokeID = (byte)it.InvokeId;
                }
                catch (Exception)
                {
                    bb.SetUInt8((byte)ErrorCode.HardwareFault);
                }
                if (settings.Index != settings.Count)
                {
                    server.transaction = new GXDLMSLongTransaction(list.ToArray(), Command.GetRequest, null);
                }
                ++pos;
            }
            server.NotifyPostRead(list.ToArray());
            GXDLMSLNParameters p = new GXDLMSLNParameters(settings, invokeID, Command.GetResponse, 3, null, bb, 0xFF);

            GXDLMS.GetLNPdu(p, replyData);
        }
 void IGXDLMSBase.SetValue(GXDLMSSettings settings, ValueEventArgs e)
 {
     if (e.Index == 1)
     {
         if (e.Value is string)
         {
             LogicalName = e.Value.ToString();
         }
         else
         {
             LogicalName = GXDLMSClient.ChangeType((byte[])e.Value, DataType.OctetString).ToString();
         }
     }
     else if (e.Index == 2)
     {
         Mode = (IecTwistedPairSetupMode)e.Value;
     }
     else if (e.Index == 3)
     {
         Speed = (BaudRate)e.Value;
     }
     else if (e.Index == 4)
     {
         GXByteBuffer list = new GXByteBuffer();
         foreach (object it in (object[])e.Value)
         {
             list.Add((byte)it);
         }
         PrimaryAddresses = list.Array();
     }
     else if (e.Index == 5)
     {
         List<sbyte> list = new List<sbyte>();
         foreach (object it in (object[])e.Value)
         {
             list.Add((sbyte)it);
         }
         Tabis = list.ToArray();
     }
     else
     {
         e.Error = ErrorCode.ReadWriteDenied;
     }
 }
        public static void HandleGetRequest(GXDLMSSettings settings, GXDLMSServer server, GXByteBuffer data, GXByteBuffer replyData, GXDLMSTranslatorStructure xml)
        {
            //Return error if connection is not established.
            if (xml == null && !settings.Connected)
            {
                replyData.Set(GXDLMSServer.GenerateConfirmedServiceError(ConfirmedServiceError.InitiateError,
                                                                         ServiceError.Service, (byte)Service.Unsupported));
                return;
            }

            GetCommandType type = (GetCommandType)data.GetUInt8();
            // Get invoke ID and priority.
            byte invokeID = data.GetUInt8();

            if (xml != null)
            {
                xml.AppendStartTag(Command.GetRequest);
                xml.AppendStartTag(Command.GetRequest, type);
                xml.AppendLine(TranslatorTags.InvokeId, "Value", xml.IntegerToHex(invokeID, 2));
            }

            // GetRequest normal
            if (type == GetCommandType.Normal)
            {
                GetRequestNormal(settings, invokeID, server, data, replyData, xml);
            }
            else if (type == GetCommandType.NextDataBlock)
            {
                // Get request for next data block
                GetRequestNextDataBlock(settings, invokeID, server, data, replyData, xml);
            }
            else if (type == GetCommandType.WithList)
            {
                // Get request with a list.
                GetRequestWithList(settings, invokeID, server, data, replyData, xml);
            }
            else
            {
                Debug.WriteLine("HandleGetRequest failed. Invalid command type.");
                settings.ResetBlockIndex();
                GXByteBuffer bb = new GXByteBuffer();
                // Access Error : Device reports a hardware fault.
                bb.SetUInt8((byte)ErrorCode.HardwareFault);
                GXDLMS.GetLNPdu(new GXDLMSLNParameters(settings, invokeID, Command.GetResponse, (byte)type, null, bb, (byte)ErrorCode.Ok), replyData);
            }
            if (xml != null)
            {
                xml.AppendEndTag(Command.GetRequest, type);
                xml.AppendEndTag(Command.GetRequest);
            }
        }
예제 #41
0
 /// <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);
 }
        private static void HandleSetRequestNormal(GXDLMSSettings settings, GXDLMSServer server, GXByteBuffer data, byte type, GXDLMSLNParameters p, GXByteBuffer replyData, GXDLMSTranslatorStructure xml)
        {
            object     value = null;
            GXDataInfo reply = new GXDataInfo();
            // CI
            ObjectType ci = (ObjectType)data.GetUInt16();

            byte[] ln = new byte[6];
            data.Get(ln);
            // Attribute index.
            byte index = data.GetUInt8();

            // Get Access Selection.
            data.GetUInt8();
            if (xml != null)
            {
                AppendAttributeDescriptor(xml, (int)ci, ln, index);
                xml.AppendStartTag(TranslatorTags.Value);
                GXDataInfo di = new GXDataInfo();
                di.xml = xml;
                value  = GXCommon.GetData(settings, data, di);
                if (!di.Complete)
                {
                    value = GXCommon.ToHex(data.Data, false, data.Position, data.Size - data.Position);
                }
                else if (value is byte[])
                {
                    value = GXCommon.ToHex((byte[])value, false);
                }
                xml.AppendEndTag(TranslatorTags.Value);
                return;
            }
            if (type == 2)
            {
                p.multipleBlocks = data.GetUInt8() == 0;
                uint blockNumber = data.GetUInt32();
                if (blockNumber != settings.BlockIndex)
                {
                    Debug.WriteLine("HandleSetRequest failed. Invalid block number. " + settings.BlockIndex + "/" + blockNumber);
                    p.status = (byte)ErrorCode.DataBlockNumberInvalid;
                    return;
                }
                settings.IncreaseBlockIndex();
                int size     = GXCommon.GetObjectCount(data);
                int realSize = data.Size - data.Position;
                if (size != realSize)
                {
                    Debug.WriteLine("HandleSetRequest failed. Invalid block size.");
                    p.status = (byte)ErrorCode.DataBlockUnavailable;
                    return;
                }
            }
            if (!p.multipleBlocks)
            {
                settings.ResetBlockIndex();
                value = GXCommon.GetData(settings, data, reply);
            }

            GXDLMSObject obj = settings.Objects.FindByLN(ci, GXCommon.ToLogicalName(ln));

            if (obj == null)
            {
                obj = server.NotifyFindObject(ci, 0, GXCommon.ToLogicalName(ln));
            }
            // If target is unknown.
            if (obj == null)
            {
                // Device reports a undefined object.
                p.status = (byte)ErrorCode.UndefinedObject;
            }
            else
            {
                ValueEventArgs e = new ValueEventArgs(server, obj, index, 0, null);
                e.InvokeId = p.InvokeId;
                AccessMode am = server.NotifyGetAttributeAccess(e);
                // If write is denied.
                if (am != AccessMode.Write && am != AccessMode.ReadWrite)
                {
                    //Read Write denied.
                    p.status = (byte)ErrorCode.ReadWriteDenied;
                }
                else
                {
                    try
                    {
                        if (value is byte[])
                        {
                            DataType dt = (obj as IGXDLMSBase).GetDataType(index);
                            if (dt != DataType.None && dt != DataType.OctetString && dt != DataType.Structure)
                            {
                                value = GXDLMSClient.ChangeType((byte[])value, dt, settings.UseUtc2NormalTime);
                            }
                        }
                        e.Value = value;
                        ValueEventArgs[] list = new ValueEventArgs[] { e };
                        if (p.multipleBlocks)
                        {
                            server.transaction = new GXDLMSLongTransaction(list, Command.GetRequest, data);
                        }
                        server.NotifyWrite(list);
                        if (e.Error != 0)
                        {
                            p.status = (byte)e.Error;
                        }
                        else if (!e.Handled && !p.multipleBlocks)
                        {
                            (obj as IGXDLMSBase).SetValue(settings, e);
                            server.NotifyPostWrite(list);
                            if (e.Error != 0)
                            {
                                p.status = (byte)e.Error;
                            }
                        }
                        p.InvokeId = e.InvokeId;
                    }
                    catch (Exception)
                    {
                        p.status = (byte)ErrorCode.HardwareFault;
                    }
                }
            }
        }
예제 #43
0
 /// <summary>
 /// Removes X.509 v3 certificate from the server using serial number.
 /// </summary>
 /// <param name="client">DLMS client that is used to generate action.</param>
 /// <param name="serialNumber">Serial number.</param>
 /// <param name="issuer">Issuer.</param>
 /// <returns>Generated action.</returns>
 public byte[][] RemoveCertificateBySerial(GXDLMSClient client, byte[] serialNumber, byte[] issuer)
 {
     GXByteBuffer bb = new GXByteBuffer();
     bb.SetUInt8(DataType.Structure);
     bb.SetUInt8(2);
     //Add enum
     bb.SetUInt8(DataType.Enum);
     bb.SetUInt8(1);
     //Add certificate_identification_by_entity
     bb.SetUInt8(DataType.Structure);
     bb.SetUInt8(2);
     //serialNumber
     GXCommon.SetData(client.Settings, bb, DataType.OctetString, serialNumber);
     //issuer
     GXCommon.SetData(client.Settings, bb, DataType.OctetString, issuer);
     return client.Method(this, 8, bb.Array(), DataType.OctetString);
 }
        private static void HanleSetRequestWithDataBlock(GXDLMSSettings settings, GXDLMSServer server, GXByteBuffer data, GXDLMSLNParameters p, GXByteBuffer replyData, GXDLMSTranslatorStructure xml)
        {
            GXDataInfo reply = new GXDataInfo();

            reply.xml = xml;
            byte lastBlock = data.GetUInt8();

            p.multipleBlocks = lastBlock == 0;
            uint blockNumber = data.GetUInt32();

            if (xml == null && blockNumber != settings.BlockIndex)
            {
                Debug.WriteLine("HanleSetRequestWithDataBlock failed. Invalid block number. " + settings.BlockIndex + "/" + blockNumber);
                p.status = (byte)ErrorCode.DataBlockNumberInvalid;
            }
            else
            {
                settings.IncreaseBlockIndex();
                int size     = GXCommon.GetObjectCount(data);
                int realSize = data.Size - data.Position;
                if (size != realSize)
                {
                    Debug.WriteLine("HanleSetRequestWithDataBlock failed. Invalid block size.");
                    p.status = (byte)ErrorCode.DataBlockUnavailable;
                }
                if (xml != null)
                {
                    xml.AppendStartTag(TranslatorTags.DataBlock);
                    xml.AppendLine(TranslatorTags.LastBlock, "Value", xml.IntegerToHex(lastBlock, 2));
                    xml.AppendLine(TranslatorTags.BlockNumber, "Value", xml.IntegerToHex(blockNumber, 8));
                    xml.AppendLine(TranslatorTags.RawData, "Value", data.RemainingHexString(false));
                    xml.AppendEndTag(TranslatorTags.DataBlock);
                    return;
                }
                server.transaction.data.Set(data);
                //If all data is received.
                if (!p.multipleBlocks)
                {
                    try
                    {
                        object value = GXCommon.GetData(settings, server.transaction.data, reply);
                        if (value is byte[])
                        {
                            DataType dt = (server.transaction.targets[0].Target as IGXDLMSBase).GetDataType(server.transaction.targets[0].Index);
                            if (dt != DataType.None && dt != DataType.OctetString)
                            {
                                value = GXDLMSClient.ChangeType((byte[])value, dt, settings.UseUtc2NormalTime);
                            }
                        }
                        server.transaction.targets[0].Value = value;
                        server.NotifyWrite(server.transaction.targets);
                        if (!server.transaction.targets[0].Handled && !p.multipleBlocks)
                        {
                            (server.transaction.targets[0].Target as IGXDLMSBase).SetValue(settings, server.transaction.targets[0]);
                            server.NotifyPostWrite(server.transaction.targets);
                        }
                    }
                    catch (Exception)
                    {
                        p.status = (byte)ErrorCode.HardwareFault;
                    }
                    finally
                    {
                        server.transaction = null;
                    }
                    settings.ResetBlockIndex();
                }
            }
            p.multipleBlocks = true;
        }
예제 #45
0
 ///<summary>
 /// Removes the HDLC frame from the packet, and returns COSEM data only.
 ///</summary>
 ///<param name="reply">
 /// The received data from the device. 
 ///</param>
 ///<param name="data">
 /// Information from the received data. 
 ///</param>
 ///<returns>
 /// Is frame complete.
 ///</returns>
 public bool GetData(GXByteBuffer reply, GXReplyData data)
 {
     return GXDLMS.GetData(Settings, reply, data);
 }
        ///<summary>
        /// Handle Access request.
        ///</summary>
        public static void HandleAccessRequest(GXDLMSSettings settings, GXDLMSServer server, GXByteBuffer data,
                                               GXByteBuffer reply, GXDLMSTranslatorStructure xml)
        {
            //Return error if connection is not established.
            if (xml == null && !settings.Connected)
            {
                reply.Set(GXDLMSServer.GenerateConfirmedServiceError(ConfirmedServiceError.InitiateError,
                                                                     ServiceError.Service, (byte)Service.Unsupported));
                return;
            }
            //Get long invoke id and priority.
            uint invokeId = data.GetUInt32();
            int  len      = GXCommon.GetObjectCount(data);

            byte[] tmp = null;
            // If date time is given.
            if (len != 0)
            {
                tmp = new byte[len];
                data.Get(tmp);
                if (xml == null)
                {
                    DataType dt = DataType.DateTime;
                    if (len == 4)
                    {
                        dt = DataType.Time;
                    }
                    else if (len == 5)
                    {
                        dt = DataType.Date;
                    }
                    GXDataInfo info = new GXDataInfo();
                    info.Type = dt;
                    GXCommon.GetData(settings, new GXByteBuffer(tmp), info);
                }
            }
            // Get object count.
            int cnt = GXCommon.GetObjectCount(data);

            if (xml != null)
            {
                xml.AppendStartTag(Command.AccessRequest);
                xml.AppendLine(TranslatorTags.LongInvokeId, "Value", xml.IntegerToHex(invokeId, 2));
                xml.AppendLine(TranslatorTags.DateTime, "Value", GXCommon.ToHex(tmp, false));
                xml.AppendStartTag(TranslatorTags.AccessRequestBody);
                xml.AppendStartTag(TranslatorTags.ListOfAccessRequestSpecification, "Qty",
                                   xml.IntegerToHex(cnt, 2));
            }
            AccessServiceCommandType type;

            for (int pos = 0; pos != cnt; ++pos)
            {
                type = (AccessServiceCommandType)data.GetUInt8();
                if (!(type == AccessServiceCommandType.Get ||
                      type == AccessServiceCommandType.Set ||
                      type == AccessServiceCommandType.Action))
                {
                    throw new ArgumentException("Invalid access service command type.");
                }
                // CI
                ObjectType ci = (ObjectType)data.GetUInt16();
                byte[]     ln = new byte[6];
                data.Get(ln);
                // Attribute Id
                byte attributeIndex = data.GetUInt8();
                if (xml != null)
                {
                    xml.AppendStartTag(TranslatorTags.AccessRequestSpecification);
                    xml.AppendStartTag(Command.AccessRequest, type);
                    AppendAttributeDescriptor(xml, (int)ci, ln, attributeIndex);
                    xml.AppendEndTag(Command.AccessRequest, type);
                    xml.AppendEndTag(TranslatorTags.AccessRequestSpecification);
                }
            }
            if (xml != null)
            {
                xml.AppendEndTag(TranslatorTags.ListOfAccessRequestSpecification);
                xml.AppendStartTag(TranslatorTags.AccessRequestListOfData, "Qty", xml.IntegerToHex(cnt, 2));
            }
            // Get data count.
            cnt = GXCommon.GetObjectCount(data);
            for (int pos = 0; pos != cnt; ++pos)
            {
                GXDataInfo di = new GXDataInfo();
                di.xml = xml;
                if (xml != null && xml.OutputType == TranslatorOutputType.StandardXml)
                {
                    xml.AppendStartTag(Command.WriteRequest, SingleReadResponse.Data);
                }
                object value = GXCommon.GetData(settings, data, di);
                if (!di.Complete)
                {
                    value = GXCommon.ToHex(data.Data, false, data.Position, data.Size - data.Position);
                }
                else if (value is byte[])
                {
                    value = GXCommon.ToHex((byte[])value, false);
                }
                if (xml != null && xml
                    .OutputType == TranslatorOutputType.StandardXml)
                {
                    xml.AppendEndTag(Command.WriteRequest, SingleReadResponse.Data);
                }
            }
            if (xml != null)
            {
                xml.AppendEndTag(TranslatorTags.AccessRequestListOfData);
                xml.AppendEndTag(TranslatorTags.AccessRequestBody);
                xml.AppendEndTag(Command.AccessRequest);
            }
        }
예제 #47
0
 /// <summary>
 /// Add value of COSEM object to byte buffer.
 /// </summary>
 /// <param name="obj">COSEM object.</param>
 /// <param name="index">Attribute index.</param>
 /// <param name="buff">Byte buffer.</param>
 /// <remarks>
 /// AddData method can be used with GetDataNotificationMessage -method.
 /// DLMS spesification do not specify the structure of Data-Notification body.
 /// So each manufacture can sent different data.
 /// </remarks>
 /// <seealso cref="GetDataNotificationMessages"/>
 public void AddData(GXDLMSObject obj, int index, GXByteBuffer buff)
 {
     AddData(Settings, obj, index, buff);
 }
예제 #48
0
 object IGXDLMSBase.GetValue(GXDLMSSettings settings, ValueEventArgs e)
 {
     if (e.Index == 1)
     {
         return this.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);
                     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;
 }
예제 #49
0
 /// <summary>
 /// Generates data notification message.
 /// </summary>
 /// <param name="time">Date time. Set To Min or Max if not added</param>
 /// <param name="objects">List of objects and attribute indexes to notify.</param>
 /// <returns>Generated data notification message(s).</returns>
 public byte[][] GenerateDataNotificationMessages(DateTime time, List<KeyValuePair<GXDLMSObject, int>> objects)
 {
     if (objects == null)
     {
         throw new ArgumentNullException("objects");
     }
     GXByteBuffer buff = new GXByteBuffer();
     buff.SetUInt8(DataType.Structure);
     GXCommon.SetObjectCount(objects.Count, buff);
     foreach (KeyValuePair<GXDLMSObject, int> it in objects)
     {
         AddData(it.Key, it.Value, buff);
     }
     byte[][] reply;
     if (UseLogicalNameReferencing)
     {
         GXDLMSLNParameters p = new GXDLMSLNParameters(Settings, Command.DataNotification, 0, null, buff, 0xff);
         p.time = time;
         reply = GXDLMS.GetLnMessages(p);
     }
     else
     {
         GXDLMSSNParameters p = new GXDLMSSNParameters(Settings, Command.DataNotification, 1, 0, buff, null);
         reply = GXDLMS.GetSnMessages(p);
     }
     return reply;
 }
예제 #50
0
        ///<summary>
        /// Handle write request.
        ///</summary>
        public static void HandleWriteRequest(GXDLMSSettings settings, GXDLMSServer server, GXByteBuffer data,
                                              GXByteBuffer replyData, GXDLMSTranslatorStructure xml)
        {
            //Return error if connection is not established.
            if (xml == null && !settings.Connected)
            {
                replyData.Add(GXDLMSServer.GenerateConfirmedServiceError(ConfirmedServiceError.InitiateError,
                                                                         ServiceError.Service, (byte)Service.Unsupported));
                return;
            }
            short  type;
            object value;
            // Get object count.
            List <GXSNInfo> targets = new List <GXSNInfo>();
            int             cnt     = GXCommon.GetObjectCount(data);

            if (xml != null)
            {
                xml.AppendStartTag(Command.WriteRequest);
                xml.AppendStartTag(
                    TranslatorTags.ListOfVariableAccessSpecification, "Qty",
                    xml.IntegerToHex(cnt, 2));
                if (xml.OutputType == TranslatorOutputType.StandardXml)
                {
                    xml.AppendStartTag(
                        TranslatorTags.VariableAccessSpecification);
                }
            }
            GXByteBuffer results = new GXByteBuffer((ushort)cnt);

            for (int pos = 0; pos != cnt; ++pos)
            {
                type = data.GetUInt8();
                if (type == (byte)VariableAccessSpecification.VariableName)
                {
                    int sn = data.GetUInt16();
                    if (xml != null)
                    {
                        xml.AppendLine(
                            (int)Command.WriteRequest << 8
                                | (int)VariableAccessSpecification.VariableName,
                                "Value", xml.IntegerToHex(sn, 4));
                    }
                    else
                    {
                        GXSNInfo info = FindSNObject(server, sn);
                        targets.Add(info);
                        // If target is unknown.
                        if (info == null)
                        {
                            // Device reports a undefined object.
                            results.SetUInt8(ErrorCode.UndefinedObject);
                        }
                        else
                        {
                            results.SetUInt8(ErrorCode.Ok);
                        }
                    }
                }
                else if (type == (byte)VariableAccessSpecification.WriteDataBlockAccess)
                {
                    HandleReadDataBlockAccess(settings, server, Command.WriteResponse, data, cnt, replyData, xml);
                    if (xml == null)
                    {
                        return;
                    }
                }
                else
                {
                    // Device reports a HW error.
                    results.SetUInt8(ErrorCode.HardwareFault);
                }
            }

            if (xml != null)
            {
                if (xml.OutputType == TranslatorOutputType.StandardXml)
                {
                    xml.AppendEndTag(TranslatorTags.VariableAccessSpecification);
                }
                xml.AppendEndTag(
                    TranslatorTags.ListOfVariableAccessSpecification);
            }
            // Get data count.
            cnt = GXCommon.GetObjectCount(data);
            GXDataInfo di = new GXDataInfo();

            di.xml = xml;
            if (xml != null)
            {
                xml.AppendStartTag(TranslatorTags.ListOfData, "Qty", xml.IntegerToHex(cnt, 2));
            }
            for (int pos = 0; pos != cnt; ++pos)
            {
                di.Clear();
                if (xml != null)
                {
                    if (xml.OutputType == TranslatorOutputType.StandardXml)
                    {
                        xml.AppendStartTag(Command.WriteRequest,
                                           SingleReadResponse.Data);
                    }
                    value = GXCommon.GetData(settings, data, di);
                    if (!di.Complete)
                    {
                        value = GXCommon.ToHex(data.Data, false,
                                               data.Position, data.Size - data.Position);
                        xml.AppendLine(
                            GXDLMS.DATA_TYPE_OFFSET + (int)di.Type,
                            "Value", value.ToString());
                    }
                    if (xml.OutputType == TranslatorOutputType.StandardXml)
                    {
                        xml.AppendEndTag(Command.WriteRequest, SingleReadResponse.Data);
                    }
                    GXCommon.GetData(settings, data, di);
                }
                else if (results.GetUInt8(pos) == 0)
                {
                    // If object has found.
                    GXSNInfo target = targets[pos];
                    value = GXCommon.GetData(settings, data, di);
                    if (value is byte[])
                    {
                        DataType dt = target.Item.GetDataType(target.Index);
                        if (dt != DataType.None && dt != DataType.OctetString)
                        {
                            value = GXDLMSClient.ChangeType((byte[])value, dt);
                        }
                    }
                    ValueEventArgs e  = new ValueEventArgs(server, target.Item, target.Index, 0, null);
                    AccessMode     am = server.NotifyGetAttributeAccess(e);
                    // If write is denied.
                    if (am != AccessMode.Write && am != AccessMode.ReadWrite)
                    {
                        results.SetUInt8((byte)pos, (byte)ErrorCode.ReadWriteDenied);
                    }
                    else
                    {
                        e.Value = value;
                        server.NotifyWrite(new ValueEventArgs[] { e });
                        if (e.Error != 0)
                        {
                            results.SetUInt8((byte)pos, (byte)e.Error);
                        }
                        else if (!e.Handled)
                        {
                            (target.Item as IGXDLMSBase).SetValue(settings, e);
                            server.NotifyPostWrite(new ValueEventArgs[] { e });
                        }
                    }
                }
            }
            if (xml != null)
            {
                xml.AppendEndTag(TranslatorTags.ListOfData);
                xml.AppendEndTag(Command.WriteRequest);
                return;
            }
            GenerateWriteResponse(settings, results, replyData);
        }
예제 #51
0
 object IGXDLMSBase.GetValue(GXDLMSSettings settings, ValueEventArgs e)
 {
     if (e.Index == 1)
     {
         return this.LogicalName;
     }
     if (e.Index == 2)
     {
         return PHYReference;
     }
     if (e.Index == 3)
     {
         GXByteBuffer data = new GXByteBuffer();
         data.SetUInt8((byte)DataType.Array);
         if (LCPOptions == null)
         {
             data.SetUInt8(0);
         }
         else
         {
             data.SetUInt8((byte)IPCPOptions.Length);
             foreach (GXDLMSPppSetupLcpOption it in LCPOptions)
             {
                 data.SetUInt8((byte)DataType.Structure);
                 data.SetUInt8((byte)3);
                 GXCommon.SetData(settings, data, DataType.UInt8, it.Type);
                 GXCommon.SetData(settings, data, DataType.UInt8, it.Length);
                 GXCommon.SetData(settings, data, GXCommon.GetValueType(it.Data), it.Data);
             }
         }
         return data.Array();
     }
     if (e.Index == 4)
     {
         GXByteBuffer data = new GXByteBuffer();
         data.SetUInt8((byte)DataType.Array);
         if (IPCPOptions == null)
         {
             data.SetUInt8(0);
         }
         else
         {
             data.SetUInt8((byte)IPCPOptions.Length);
             foreach (GXDLMSPppSetupIPCPOption it in IPCPOptions)
             {
                 data.SetUInt8((byte)DataType.Structure);
                 data.SetUInt8((byte)3);
                 GXCommon.SetData(settings, data, DataType.UInt8, it.Type);
                 GXCommon.SetData(settings, data, DataType.UInt8, it.Length);
                 GXCommon.SetData(settings, data, GXCommon.GetValueType(it.Data), it.Data);
             }
         }
         return data.Array();
     }
     else if (e.Index == 5)
     {
         GXByteBuffer data = new GXByteBuffer();
         data.SetUInt8((byte)DataType.Structure);
         data.SetUInt8(2);
         GXCommon.SetData(settings, data, DataType.OctetString, UserName);
         GXCommon.SetData(settings, data, DataType.OctetString, Password);
         return data.Array();
     }
     e.Error = ErrorCode.ReadWriteDenied;
     return null;
 }
예제 #52
0
        /// <summary>
        /// Generate write reply.
        /// </summary>
        /// <param name="settings"></param>
        /// <param name="results"></param>
        /// <param name="replyData"></param>
        internal static void GenerateWriteResponse(GXDLMSSettings settings, GXByteBuffer results, GXByteBuffer replyData)
        {
            GXByteBuffer bb = new GXByteBuffer((UInt16)(2 * results.Size));
            byte         ret;

            for (int pos = 0; pos != results.Size; ++pos)
            {
                ret = results.GetUInt8(pos);
                // If meter returns error.
                if (ret != 0)
                {
                    bb.SetUInt8(1);
                }
                bb.SetUInt8(ret);
            }
            GXDLMSSNParameters p = new GXDLMSSNParameters(settings, Command.WriteResponse, results.Size, 0xFF, null, bb);

            GXDLMS.GetSNPdu(p, replyData);
        }
예제 #53
0
 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;
 }
예제 #54
0
        private static void HandleRead(GXDLMSSettings settings, GXDLMSServer server, byte type, GXByteBuffer data,
                                       List <ValueEventArgs> list, List <ValueEventArgs> reads, List <ValueEventArgs> actions,
                                       GXByteBuffer replyData, GXDLMSTranslatorStructure xml)
        {
            int sn = data.GetInt16();

            if (xml != null)
            {
                if (xml.OutputType == TranslatorOutputType.StandardXml)
                {
                    xml.AppendStartTag(
                        TranslatorTags.VariableAccessSpecification);
                }
                else
                {
                    sn &= 0xFFFF;
                }
                if (type == (byte)VariableAccessSpecification.ParameterisedAccess)
                {
                    xml.AppendStartTag(Command.ReadRequest,
                                       VariableAccessSpecification.ParameterisedAccess);
                    xml.AppendLine(
                        (int)Command.ReadRequest << 8
                            | (int)VariableAccessSpecification.VariableName,
                            "Value", xml.IntegerToHex(sn, 4));
                    xml.AppendLine(TranslatorTags.Selector, "Value",
                                   xml.IntegerToHex(data.GetUInt8(), 2));
                    GXDataInfo di = new GXDataInfo();
                    di.xml = xml;
                    xml.AppendStartTag(TranslatorTags.Parameter);
                    GXCommon.GetData(settings, data, di);
                    xml.AppendEndTag(TranslatorTags.Parameter);
                    xml.AppendEndTag(Command.ReadRequest,
                                     VariableAccessSpecification.ParameterisedAccess);
                }
                else
                {
                    xml.AppendLine(
                        (int)Command.ReadRequest << 8
                            | (int)VariableAccessSpecification.VariableName,
                            "Value", xml.IntegerToHex(sn, 4));
                }
                if (xml.OutputType == TranslatorOutputType.StandardXml)
                {
                    xml.AppendEndTag(TranslatorTags.VariableAccessSpecification);
                }
                return;
            }

            GXSNInfo       info = FindSNObject(server, sn & 0xFFFF);
            ValueEventArgs e    = new ValueEventArgs(server, info.Item, info.Index, 0, null);

            e.action = info.IsAction;
            if (type == (byte)VariableAccessSpecification.ParameterisedAccess)
            {
                e.Selector = data.GetUInt8();
                GXDataInfo di = new GXDataInfo();
                e.Parameters = GXCommon.GetData(settings, data, di);
            }
            //Return error if connection is not established.
            if (!settings.Connected && (!e.action || e.Target.ShortName != 0xFA00 || e.Index != 8))
            {
                replyData.Add(GXDLMSServer.GenerateConfirmedServiceError(ConfirmedServiceError.InitiateError,
                                                                         ServiceError.Service, (byte)Service.Unsupported));
                return;
            }
            if (e.Target is GXDLMSProfileGeneric && info.Index == 2)
            {
                e.RowToPdu = GXDLMS.RowsToPdu(settings, (GXDLMSProfileGeneric)e.Target);
            }
            list.Add(e);
            if (!e.action && server.NotifyGetAttributeAccess(e) == AccessMode.NoAccess)
            {
                e.Error = ErrorCode.ReadWriteDenied;
            }
            else if (e.action && server.NotifyGetMethodAccess(e) == MethodAccessMode.NoAccess)
            {
                e.Error = ErrorCode.ReadWriteDenied;
            }
            else
            {
                if (e.action)
                {
                    actions.Add(e);
                }
                else
                {
                    reads.Add(e);
                }
            }
        }
예제 #55
0
 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)
     {
         return Repetitions;
     }
     if (e.Index == 4)
     {
         return RepetitionDelay;
     }
     if (e.Index == 5)
     {
         int cnt = CallingWindow.Count;
         GXByteBuffer data = new GXByteBuffer();
         data.SetUInt8((byte)DataType.Array);
         //Add count
         GXCommon.SetObjectCount(cnt, data);
         if (cnt != 0)
         {
             foreach (var it in CallingWindow)
             {
                 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 == 6)
     {
         GXByteBuffer data = new GXByteBuffer();
         data.SetUInt8((byte)DataType.Array);
         if (Destinations == null)
         {
             //Add count
             GXCommon.SetObjectCount(0, data);
         }
         else
         {
             int cnt = Destinations.Length;
             //Add count
             GXCommon.SetObjectCount(cnt, data);
             foreach (string it in Destinations)
             {
                 GXCommon.SetData(settings, data, DataType.OctetString, ASCIIEncoding.ASCII.GetBytes(it)); //destination
             }
         }
         return data.Array();
     }
     e.Error = ErrorCode.ReadWriteDenied;
     return null;
 }
예제 #56
0
        /// <summary>
        /// Handle read Block in blocks.
        /// </summary>
        /// <param name="data">Received data.</param>
        private static void HandleReadBlockNumberAccess(GXDLMSSettings settings, GXDLMSServer server, GXByteBuffer data, GXByteBuffer replyData, GXDLMSTranslatorStructure xml)
        {
            UInt16 blockNumber = data.GetUInt16();

            if (xml != null)
            {
                xml.AppendStartTag(Command.ReadRequest, VariableAccessSpecification.BlockNumberAccess);
                xml.AppendLine("<BlockNumber Value=\"" + xml.IntegerToHex(blockNumber, 4) + "\" />");
                xml.AppendEndTag(Command.ReadRequest, VariableAccessSpecification.BlockNumberAccess);
                return;
            }

            if (blockNumber != settings.BlockIndex)
            {
                GXByteBuffer bb = new GXByteBuffer();
                Debug.WriteLine("handleReadRequest failed. Invalid block number. " + settings.BlockIndex + "/" + blockNumber);
                bb.SetUInt8(ErrorCode.DataBlockNumberInvalid);
                GXDLMS.GetSNPdu(new GXDLMSSNParameters(settings, Command.ReadResponse, 1, (byte)SingleReadResponse.DataAccessError, bb, null), replyData);
                settings.ResetBlockIndex();
                return;
            }
            if (settings.Index != settings.Count && server.transaction.data.Size < settings.MaxPduSize)
            {
                List <ValueEventArgs> reads   = new List <ValueEventArgs>();
                List <ValueEventArgs> actions = new List <ValueEventArgs>();
                foreach (ValueEventArgs it in server.transaction.targets)
                {
                    if (it.action)
                    {
                        actions.Add(it);
                    }
                    else
                    {
                        reads.Add(it);
                    }
                }
                if (reads.Count != 0)
                {
                    server.NotifyRead(reads.ToArray());
                }

                if (actions.Count != 0)
                {
                    server.NotifyAction(actions.ToArray());
                }
                GetReadData(settings, server.transaction.targets, server.transaction.data);
                if (reads.Count != 0)
                {
                    server.NotifyPostRead(reads.ToArray());
                }

                if (actions.Count != 0)
                {
                    server.NotifyPostAction(actions.ToArray());
                }
            }
            settings.IncreaseBlockIndex();
            GXDLMSSNParameters p = new GXDLMSSNParameters(settings, Command.ReadResponse, 1,
                                                          (byte)SingleReadResponse.DataBlockResult, null, server.transaction.data);

            p.multipleBlocks = true;
            GXDLMS.GetSNPdu(p, replyData);
            //If all data is sent.
            if (server.transaction.data.Size == server.transaction.data.Position)
            {
                server.transaction = null;
                settings.ResetBlockIndex();
            }
            else
            {
                server.transaction.data.Trim();
            }
        }
예제 #57
0
 public void Set(GXByteBuffer value)
 {
     if (value != null)
     {
         Set(value, value.Size - value.Position);
     }
 }
예제 #58
0
        private static void HandleReadDataBlockAccess(
            GXDLMSSettings settings, GXDLMSServer server,
            Command command, GXByteBuffer data, int cnt, GXByteBuffer replyData, GXDLMSTranslatorStructure xml)
        {
            GXByteBuffer bb          = new GXByteBuffer();
            byte         lastBlock   = data.GetUInt8();
            UInt16       blockNumber = data.GetUInt16();

            if (xml != null)
            {
                if (command == Command.WriteResponse)
                {
                    xml.AppendStartTag(TranslatorTags.WriteDataBlockAccess);
                }
                else
                {
                    xml.AppendStartTag(TranslatorTags.ReadDataBlockAccess);
                }
                xml.AppendLine("<LastBlock Value=\"" + xml.IntegerToHex(lastBlock, 2) + "\" />");
                xml.AppendLine("<BlockNumber Value=\"" + xml.IntegerToHex(blockNumber, 4) + "\" />");
                if (command == Command.WriteResponse)
                {
                    xml.AppendEndTag(TranslatorTags.WriteDataBlockAccess);
                }
                else
                {
                    xml.AppendEndTag(TranslatorTags.ReadDataBlockAccess);
                }
                return;
            }
            if (blockNumber != settings.BlockIndex)
            {
                Debug.WriteLine("handleReadRequest failed. Invalid block number. " + settings.BlockIndex + "/" + blockNumber);
                bb.SetUInt8(ErrorCode.DataBlockNumberInvalid);
                GXDLMS.GetSNPdu(new GXDLMSSNParameters(settings, command, 1, (byte)SingleReadResponse.DataAccessError, bb, null), replyData);
                settings.ResetBlockIndex();
                return;
            }
            int  count = 1;
            byte type  = (byte)DataType.OctetString;

            if (command == Command.WriteResponse)
            {
                count = GXCommon.GetObjectCount(data);
                type  = data.GetUInt8();
            }
            int size     = GXCommon.GetObjectCount(data);
            int realSize = data.Size - data.Position;

            if (count != 1 || type != (byte)DataType.OctetString || size != realSize)
            {
                Debug.WriteLine("handleGetRequest failed. Invalid block size.");
                bb.SetUInt8(ErrorCode.DataBlockUnavailable);
                GXDLMS.GetSNPdu(new GXDLMSSNParameters(settings, command, cnt, (byte)SingleReadResponse.DataAccessError, bb, null), replyData);
                settings.ResetBlockIndex();
                return;
            }
            if (server.transaction == null)
            {
                server.transaction = new GXDLMSLongTransaction(null, command, data);
            }
            else
            {
                server.transaction.data.Set(data);
            }
            if (lastBlock == 0)
            {
                bb.SetUInt16(blockNumber);
                settings.IncreaseBlockIndex();
                if (command == Command.ReadResponse)
                {
                    type = (byte)SingleReadResponse.BlockNumber;
                }
                else
                {
                    type = (byte)SingleWriteResponse.BlockNumber;
                }
                GXDLMS.GetSNPdu(new GXDLMSSNParameters(settings, command, cnt, type, null, bb), replyData);
                return;
            }
            else
            {
                if (server.transaction != null)
                {
                    data.Size = 0;
                    data.Set(server.transaction.data);
                    server.transaction = null;
                }
                if (command == Command.ReadResponse)
                {
                    HandleReadRequest(settings, server, data, replyData, xml);
                }
                else
                {
                    HandleWriteRequest(settings, server, data, replyData, xml);
                }
                settings.ResetBlockIndex();
            }
        }
예제 #59
0
 public GXByteBuffer(GXByteBuffer value)
 {
     Capacity = (value.Size - value.Position);
     Set(value);
 }
예제 #60
0
        /// <summary>
        /// Handle read request.
        /// </summary>
        /// <param name="settings">DLMS settings.</param>
        /// <param name="server">DLMS server.</param>
        /// <param name="data">Received data.</param>
        public static void HandleReadRequest(GXDLMSSettings settings, GXDLMSServer server, GXByteBuffer data, GXByteBuffer replyData, GXDLMSTranslatorStructure xml)
        {
            GXByteBuffer          bb      = new GXByteBuffer();
            int                   cnt     = 0xFF;
            byte                  type    = 0;
            List <ValueEventArgs> list    = new List <ValueEventArgs>();
            List <ValueEventArgs> reads   = new List <ValueEventArgs>();
            List <ValueEventArgs> actions = new List <ValueEventArgs>();

            //If get next frame.
            if (xml == null && data.Size == 0)
            {
                if (server.transaction != null)
                {
                    return;
                }
                bb.Set(replyData);
                replyData.Clear();
                foreach (ValueEventArgs it in server.transaction.targets)
                {
                    list.Add(it);
                }
            }
            else
            {
                cnt = GXCommon.GetObjectCount(data);
                if (xml != null)
                {
                    xml.AppendStartTag(Command.ReadRequest, "Qty", xml.IntegerToHex(cnt, 2));
                }

                for (int pos = 0; pos != cnt; ++pos)
                {
                    type = data.GetUInt8();
                    if (type == (byte)VariableAccessSpecification.VariableName ||
                        type == (byte)VariableAccessSpecification.ParameterisedAccess)
                    {
                        HandleRead(settings, server, type, data, list, reads, actions, replyData, xml);
                    }
                    else if (type == (byte)VariableAccessSpecification.BlockNumberAccess)
                    {
                        HandleReadBlockNumberAccess(settings, server, data, replyData, xml);
                        if (xml != null)
                        {
                            xml.AppendEndTag(Command.ReadRequest);
                        }
                        return;
                    }
                    else if (type == (byte)VariableAccessSpecification.ReadDataBlockAccess)
                    {
                        HandleReadDataBlockAccess(settings, server, Command.ReadResponse, data, cnt, replyData, xml);
                        if (xml != null)
                        {
                            xml.AppendEndTag(Command.ReadRequest);
                        }
                        return;
                    }
                    else
                    {
                        ReturnSNError(settings, server, Command.ReadResponse, ErrorCode.ReadWriteDenied, replyData);
                        if (xml != null)
                        {
                            xml.AppendEndTag(Command.ReadRequest);
                        }
                        return;
                    }
                }
                if (reads.Count != 0)
                {
                    server.NotifyRead(reads.ToArray());
                }

                if (actions.Count != 0)
                {
                    server.NotifyAction(actions.ToArray());
                }
            }
            if (xml != null)
            {
                xml.AppendEndTag(Command.ReadRequest);
                return;
            }

            byte requestType = (byte)GetReadData(settings, list.ToArray(), bb);

            if (reads.Count != 0)
            {
                server.NotifyPostRead(reads.ToArray());
            }

            if (actions.Count != 0)
            {
                server.NotifyPostAction(actions.ToArray());
            }

            GXDLMSSNParameters p = new GXDLMSSNParameters(settings, Command.ReadResponse, list.Count, requestType, null, bb);

            GXDLMS.GetSNPdu(p, replyData);
            if (server.transaction == null && (bb.Size != bb.Position || settings.Count != settings.Index))
            {
                reads = new List <ValueEventArgs>();
                foreach (var it in list)
                {
                    reads.Add(it);
                }
                server.transaction = new GXDLMSLongTransaction(reads.ToArray(), Command.ReadRequest, bb);
            }
            else if (server.transaction != null)
            {
                replyData.Set(bb);
                return;
            }
        }