Set() public method

public Set ( GXByteBuffer value ) : void
value GXByteBuffer
return void
Esempio n. 1
0
        /// <summary>
        /// Generates discover report.
        /// </summary>
        /// <param name="systemTitle">System title</param>
        /// <param name="newMeter">Is this a new meter.</param>
        /// <returns>Generated bytes.</returns>
        public byte[] DiscoverReport(byte[] systemTitle, bool newMeter)
        {
            GXByteBuffer bb = new GXByteBuffer();

            if (settings.InterfaceType != Enums.InterfaceType.Plc &&
                settings.InterfaceType != Enums.InterfaceType.PlcHdlc)
            {
                throw new ArgumentOutOfRangeException("Invalid interface type.");
            }
            byte alarmDescription;

            if (settings.InterfaceType == Enums.InterfaceType.Plc)
            {
                alarmDescription = (byte)(newMeter ? 1 : 0x82);
            }
            else
            {
                alarmDescription = 0;
            }
            if (settings.InterfaceType == Enums.InterfaceType.PlcHdlc)
            {
                bb.Set(GXCommon.LLCReplyBytes);
            }
            bb.SetUInt8((byte)Command.DiscoverReport);
            bb.SetUInt8(1);
            bb.Set(systemTitle);
            if (alarmDescription != 0)
            {
                bb.SetUInt8(1);
            }
            bb.SetUInt8(alarmDescription);
            int    clientAddress    = settings.ClientAddress;
            int    serverAddress    = settings.ServerAddress;
            UInt16 macSourceAddress = settings.Plc.MacSourceAddress;
            UInt16 macTargetAddress = settings.Plc.MacDestinationAddress;

            try
            {
                //10.4.6.4 Source and destination APs and addresses of CI-PDUs
                //Client address is No-station in discoverReport.
                if (settings.InterfaceType == Enums.InterfaceType.PlcHdlc)
                {
                    settings.Plc.MacDestinationAddress = (UInt16)PlcHdlcSourceAddress.Initiator;
                }
                else
                {
                    settings.ClientAddress = 0;
                    settings.ServerAddress = 0xFD;
                }
                return(GXDLMS.GetMacFrame(settings, 0x13, 0, bb));
            }
            finally
            {
                settings.ClientAddress             = clientAddress;
                settings.ServerAddress             = serverAddress;
                settings.Plc.MacSourceAddress      = macSourceAddress;
                settings.Plc.MacDestinationAddress = macTargetAddress;
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Register PLC meters.
        /// </summary>
        /// <param name="initiatorSystemTitle">Active initiator systemtitle</param>
        /// <param name="systemTitle"></param>
        /// <returns>Generated bytes.</returns>
        public byte[] RegisterRequest(byte[] initiatorSystemTitle, byte[] systemTitle)
        {
            GXByteBuffer bb = new GXByteBuffer();

            //Control byte.
            bb.SetUInt8((byte)Command.RegisterRequest);
            bb.Set(initiatorSystemTitle);
            //LEN
            bb.SetUInt8(0x1);
            bb.Set(systemTitle);
            //MAC address.
            bb.SetUInt16(MacSourceAddress);
            int val = settings.Plc.InitialCredit << 5;

            val |= settings.Plc.CurrentCredit << 2;
            val |= settings.Plc.DeltaCredit & 0x3;

            int    clientAddress    = settings.ClientAddress;
            int    serverAddress    = settings.ServerAddress;
            UInt16 macSourceAddress = settings.Plc.MacSourceAddress;
            UInt16 macTargetAddress = settings.Plc.MacDestinationAddress;

            try
            {
                //10.4.6.4 Source and destination APs and addresses of CI-PDUs
                //Client address is No-station in discoverReport.
                if (settings.InterfaceType == Enums.InterfaceType.PlcHdlc)
                {
                    settings.Plc.InitialCredit         = 0;
                    settings.Plc.CurrentCredit         = 0;
                    settings.Plc.MacSourceAddress      = 0xC01;
                    settings.Plc.MacDestinationAddress = 0xFFF;
                    settings.ClientAddress             = 0x66;
                    // All-station
                    settings.ServerAddress = 0x33FF;
                }
                else
                {
                    settings.ClientAddress             = 1;
                    settings.ServerAddress             = 0;
                    settings.Plc.MacSourceAddress      = 0xC00;
                    settings.Plc.MacDestinationAddress = 0xFFF;
                }
                return(GXDLMS.GetMacFrame(settings, 0x13, (byte)val, bb));
            }
            finally
            {
                settings.ClientAddress             = clientAddress;
                settings.ServerAddress             = serverAddress;
                settings.Plc.MacSourceAddress      = macSourceAddress;
                settings.Plc.MacDestinationAddress = macTargetAddress;
            }
        }
Esempio n. 3
0
 private static void FillWithZeroes(GXByteBuffer bb, int size)
 {
     if (bb.Size < size)
     {
         bb.Set(0, new byte[size - bb.Size]);
     }
 }
Esempio n. 4
0
        /// <summary>
        /// Discover available PLC meters.
        /// </summary>
        /// <returns>Generated bytes.</returns>
        public byte[] DiscoverRequest()
        {
            GXByteBuffer bb = new GXByteBuffer();

            if (settings.InterfaceType != Enums.InterfaceType.Plc &&
                settings.InterfaceType != Enums.InterfaceType.PlcHdlc)
            {
                throw new ArgumentOutOfRangeException("Invalid interface type.");
            }
            if (settings.InterfaceType == Enums.InterfaceType.PlcHdlc)
            {
                bb.Set(GXCommon.LLCSendBytes);
            }
            bb.SetUInt8((byte)Command.DiscoverRequest);
            bb.SetUInt8(ResponseProbability);
            bb.SetUInt16(AllowedTimeSlots);
            //DiscoverReport initial credit
            bb.SetUInt8(0);
            // IC Equal credit
            bb.SetUInt8(0);
            int    val           = 0;
            int    clientAddress = settings.ClientAddress;
            int    serverAddress = settings.ServerAddress;
            UInt16 da            = settings.Plc.MacDestinationAddress;
            UInt16 sa            = settings.Plc.MacSourceAddress;

            try
            {
                //10.4.6.4 Source and destination APs and addresses of CI-PDUs
                //Client address is No-station in discoverReport.
                if (settings.InterfaceType == Enums.InterfaceType.PlcHdlc)
                {
                    settings.Plc.InitialCredit         = 0;
                    settings.Plc.CurrentCredit         = 0;
                    settings.Plc.MacSourceAddress      = 0xC01;
                    settings.Plc.MacDestinationAddress = 0xFFF;
                    settings.ClientAddress             = 0x66;
                    // All-station
                    settings.ServerAddress = 0x33FF;
                }
                else
                {
                    val  = settings.Plc.InitialCredit << 5;
                    val |= settings.Plc.CurrentCredit << 2;
                    val |= settings.Plc.DeltaCredit & 0x3;
                    settings.Plc.MacSourceAddress = 0xC00;
                    settings.ClientAddress        = 1;
                    settings.ServerAddress        = 0;
                }
                return(GXDLMS.GetMacFrame(settings, 0x13, (byte)val, bb));
            }
            finally
            {
                settings.ClientAddress             = clientAddress;
                settings.ServerAddress             = serverAddress;
                settings.Plc.MacDestinationAddress = da;
                settings.Plc.MacSourceAddress      = sa;
            }
        }
Esempio n. 5
0
        /// <summary>
        /// Ping PLC meter.
        /// </summary>
        /// <returns>Generated bytes.</returns>
        public byte[] PingRequest(byte[] systemTitle)
        {
            GXByteBuffer bb = new GXByteBuffer();

            //Control byte.
            bb.SetUInt8((byte)Command.PingRequest);
            bb.Set(systemTitle);
            return(GXDLMS.GetMacFrame(settings, 0x13, 0, bb));
        }
Esempio n. 6
0
        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 == ConnectionState.None && !settings.CanAccess())
            {
                replyData.Set(GXDLMSServer.GenerateConfirmedServiceError(ConfirmedServiceError.InitiateError,
                                                                         ServiceError.Service, (byte)Service.Unsupported));
                return;
            }
            byte           invokeID = 0;
            GetCommandType type     = GetCommandType.NextDataBlock;

            //If GBT is used data is empty.
            if (data.Size != 0)
            {
                type = (GetCommandType)data.GetUInt8();
                // Get invoke ID and priority.
                invokeID = data.GetUInt8();
                settings.UpdateInvokeId(invokeID);
                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, false);
            }
            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(null, settings, invokeID, Command.GetResponse, (byte)type, null, bb, (byte)ErrorCode.Ok), replyData);
            }
            if (xml != null)
            {
                xml.AppendEndTag(Command.GetRequest, type);
                xml.AppendEndTag(Command.GetRequest);
            }
        }
Esempio n. 7
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.
                    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;
            if (Settings.InterfaceType == Enums.InterfaceType.HDLC)
            {
                replyData.Set(GXCommon.LLCReplyBytes);
            }
            // Generate AARE packet.
            GXAPDU.GenerateAARE(Settings, replyData, result, diagnostic, Settings.Cipher, null);
        }
Esempio n. 8
0
        ///<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 == ConnectionState.None && !settings.CanAccess())
            {
                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();

            settings.UpdateInvokeId(invoke);
            // SetRequest normal or Set Request With First Data Block
            GXDLMSLNParameters p = new GXDLMSLNParameters(null, 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;

            case SetRequestType.WithList:
                HanleSetRequestWithList(settings, invoke, 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);
        }
        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);
            }
        }
Esempio n. 10
0
        /// <summary>
        /// Generates data notification message.
        /// </summary>
        /// <param name="date">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[][] GetDataNotificationMessage(DateTime date, byte[] data)
        {
            GXByteBuffer buff = new GXByteBuffer();

            if (date == DateTime.MinValue || date == DateTime.MaxValue)
            {
                buff.SetUInt8(DataType.None);
            }
            else
            {
                GXCommon.SetData(buff, DataType.DateTime, date);
            }
            buff.Set(data);
            return(GXDLMS.SplitPdu(Settings, Command.DataNotification, 0, buff, ErrorCode.Ok, DateTime.MinValue)[0]);
        }
Esempio n. 11
0
        /// <summary>
        /// Sends Event Notification or Information Report Request.
        /// </summary>
        /// <param name="time">Send time.</param>
        /// <param name="list">List of COSEM object and attribute index to report.</param>
        /// <returns>Report request as byte array.</returns>
        public byte[][] GenerateReport(DateTime time, List <KeyValuePair <GXDLMSObject, int> > list)
        {
            if (list == null || list.Count == 0)
            {
                throw new ArgumentNullException("list");
            }
            if (UseLogicalNameReferencing && list.Count != 1)
            {
                throw new ArgumentException("Only one object can send with Event Notification request.");
            }

            GXByteBuffer buff = new GXByteBuffer();

            byte[][] reply;
            if (UseLogicalNameReferencing)
            {
                foreach (KeyValuePair <GXDLMSObject, int> it in list)
                {
                    buff.SetUInt16((ushort)it.Key.ObjectType);
                    buff.Set(GXCommon.LogicalNameToBytes(it.Key.LogicalName));
                    buff.SetUInt8((byte)it.Value);
                    AddData(it.Key, it.Value, buff);
                }
                GXDLMSLNParameters p = new GXDLMSLNParameters(Settings, 0, Command.EventNotification, 0, null, buff, 0xff);
                p.time = time;
                reply  = GXDLMS.GetLnMessages(p);
            }
            else
            {
                GXDLMSSNParameters p = new GXDLMSSNParameters(Settings, Command.InformationReport, list.Count, 0xFF, null, buff);
                foreach (KeyValuePair <GXDLMSObject, int> it in list)
                {
                    // Add variable type.
                    buff.SetUInt8(VariableAccessSpecification.VariableName);
                    int sn = it.Key.ShortName;
                    sn += (it.Value - 1) * 8;
                    buff.SetUInt16((UInt16)sn);
                }
                GXCommon.SetObjectCount(list.Count, buff);
                foreach (KeyValuePair <GXDLMSObject, int> it in list)
                {
                    AddData(it.Key, it.Value, buff);
                }
                reply = GXDLMS.GetSnMessages(p);
            }
            return(reply);
        }
Esempio n. 12
0
        /// <summary>
        /// Sends Event Notification Request.
        /// </summary>
        /// <param name="time">Send time.</param>
        /// <param name="item">COSEM object and attribute index to report.</param>
        /// <returns>Report request as byte array.</returns>
        public byte[][] GenerateEventNotification(DateTime time, KeyValuePair <GXDLMSObject, int> item)
        {
            GXByteBuffer buff = new GXByteBuffer();

            byte[][] reply;
            if (UseLogicalNameReferencing)
            {
                buff.SetUInt16((ushort)item.Key.ObjectType);
                buff.Set(GXCommon.LogicalNameToBytes(item.Key.LogicalName));
                buff.SetUInt8((byte)item.Value);
                AddData(item.Key, item.Value, buff);
                GXDLMSLNParameters p = new GXDLMSLNParameters(null, Settings, 0, Command.EventNotification, 0, null, buff, 0xff, Command.None);
                p.time = time;
                reply  = GXDLMS.GetLnMessages(p);
            }
            else
            {
                throw new Exception("Use GenerateInformationReport when Short Name referencing is used.");
            }
            return(reply);
        }
Esempio n. 13
0
        ///<summary>
        /// Handles client request.
        /// </summary>
        ///<param name="buff">
        /// Received data from the client. </param>
        ///<returns>
        ///Response to the request. Response is null if request packet is not complete.
        ///</returns>
        public virtual byte[] HandleRequest(byte[] buff, GXDLMSConnectionEventArgs connectionInfo)
        {
            if (buff == null || buff.Length == 0)
            {
                return(null);
            }
            if (!Initialized)
            {
                throw new Exception("Server not Initialized.");
            }
            try
            {
                receivedData.Set(buff);
                bool first = Settings.ServerAddress == 0 && Settings.ClientAddress == 0;
                GXDLMS.GetData(Settings, receivedData, info);
                //If all data is not received yet.
                if (!info.IsComplete)
                {
                    return(null);
                }
                receivedData.Clear();
                if (first)
                {
                    // Check is data send to this server.
                    if (!IsTarget(Settings.ServerAddress,
                                  Settings.ClientAddress))
                    {
                        info.Clear();
                        return(null);
                    }
                }

                //If client want next frame.
                if ((info.MoreData & RequestTypes.Frame) == RequestTypes.Frame)
                {
                    return(GXDLMS.GetHdlcFrame(Settings, Settings.ReceiverReady(), replyData));
                }
                //Update command if transaction and next frame is asked.
                if (info.Command == Command.None)
                {
                    if (transaction != null)
                    {
                        info.Command = transaction.command;
                    }
                }
                //Check inactivity time out.
                if (hdlcSetup != null)
                {
                    if (info.Command == Command.Snrm)
                    {
                        dataReceived = DateTime.Now;
                    }
                    else
                    {
                        int elapsed = (int)(DateTime.Now - dataReceived).TotalSeconds;
                        //If inactivity time out is elapsed.
                        if (elapsed >= hdlcSetup.InactivityTimeout)
                        {
                            Reset();
                            dataReceived = DateTime.MinValue;
                            return(null);
                        }
                        dataReceived = DateTime.Now;
                    }
                }

                byte[] reply = HandleCommand(info.Command, info.Data, connectionInfo);
                info.Clear();
                return(reply);
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.ToString());
                if (info.Command != Command.None)
                {
                    return(ReportError(info.Command, ErrorCode.HardwareFault));
                }
                else
                {
                    Reset();
                    if (Settings.Connected)
                    {
                        Settings.Connected = false;
                        Disconnected(connectionInfo);
                    }
                    return(null);
                }
            }
        }
Esempio n. 14
0
        /// <summary>
        /// Handle AARE and AARQ XML tags.
        /// </summary>
        /// <param name="node">XML node.</param>
        /// <param name="s">XML Settings.</param>
        /// <param name="tag">XML tag.</param>
        private static void HandleAarqAare(XmlNode node, GXDLMSXmlSettings s, int tag)
        {
            byte[] tmp;
            byte[] conformanceBlock;
            int value;
            switch (tag)
            {
                case (int)TranslatorGeneralTags.ApplicationContextName:
                    if (s.OutputType == TranslatorOutputType.StandardXml)
                    {
                        value = int.Parse(node.InnerText);
                        switch (value)
                        {
                            case 1:
                                s.settings.UseLogicalNameReferencing = true;
                                break;
                            case 2:
                                s.settings.UseLogicalNameReferencing = false;
                                break;
                            case 3:
                                s.settings.UseLogicalNameReferencing = true;
                                break;
                            case 4:
                                s.settings.UseLogicalNameReferencing = false;
                                break;
                            default:
                                throw new ArgumentException("Invalid dedicated key.");
                        }
                    }
                    else
                    {
                        string str = node.Attributes[0].InnerText;
                        if (string.Compare(str, "SN") == 0 ||
                                string.Compare(str, "SN_WITH_CIPHERING") == 0)
                        {
                            s.settings.UseLogicalNameReferencing = false;
                        }
                        else if (string.Compare(str, "LN") == 0 ||
                                 string.Compare(str, "LN_WITH_CIPHERING") == 0)
                        {
                            s.settings.UseLogicalNameReferencing = true;
                        }
                        else
                        {
                            throw new ArgumentException("Invalid Reference type name.");
                        }
                    }
                    break;
                case (byte)Command.GloInitiateRequest:
                case (byte)Command.GloGetRequest:
                case (byte)Command.GloSetRequest:
                case (byte)Command.GloMethodRequest:
                case (byte)Command.GloReadRequest:
                case (byte)Command.GloWriteRequest:
                    s.settings.IsServer = false;
                    tmp = GXCommon.HexToBytes(GetValue(node, s));
                    s.settings.Cipher.Security = (Security)tmp[0];
                    s.data.Set(tmp);
                    break;
                case (byte)Command.GloInitiateResponse:
                case (byte)Command.GloGetResponse:
                case (byte)Command.GloSetResponse:
                case (byte)Command.GloMethodResponse:
                case (byte)Command.GloReadResponse:
                case (byte)Command.GloWriteResponse:
                    tmp = GXCommon.HexToBytes(GetValue(node, s));
                    s.settings.Cipher.Security = (Security)tmp[0];
                    s.data.Set(tmp);
                    break;
                case (byte)Command.InitiateRequest:
                case (byte)Command.InitiateResponse:
                    if (s.OutputType == TranslatorOutputType.StandardXml)
                    {
                        GXByteBuffer bb = new GXByteBuffer();
                        tmp = GXCommon.HexToBytes(GetValue(node, s));
                        GXCommon.SetObjectCount(tmp.Length, bb);
                        bb.Set(tmp);
                        GXAPDU.ParseUserInformation(s.settings,
                                                    s.settings.Cipher, bb, null);
                        if (s.command == Command.Aarq)
                        {
                            if (s.settings.UseLogicalNameReferencing)
                            {
                                s.settings.LnSettings.ConformanceBlock =
                                    s.settings.ConformanceBlock;
                            }
                            else
                            {
                                s.settings.SnSettings.ConformanceBlock =
                                    s.settings.ConformanceBlock;
                            }
                        }
                    }
                    break;
                case 0xBE00:
                    //NegotiatedQualityOfService
                    break;
                case 0xBE06:
                case 0xBE01:
                    //NegotiatedDlmsVersionNumber or ProposedDlmsVersionNumber is skipped.
                    break;
                case 0xBE04:
                    //VaaName is not needed.
                    break;
                case 0x8A:
                    //SenderACSERequirements is not needed.
                    break;
                case 0x8B:
                case 0x89:
                    //MechanismName.
                    s.settings.Authentication = (Authentication)Enum.Parse(typeof(Authentication), GetValue(node, s));
                    if (s.OutputType == TranslatorOutputType.SimpleXml)
                    {
                        s.settings.Authentication = (Authentication)Enum.Parse(typeof(Authentication), GetValue(node, s));
                    }
                    else
                    {
                        s.settings.Authentication = (Authentication)int.Parse(GetValue(node, s));
                    }
                    break;
                case 0xAC:
                    //CallingAuthentication.
                    if (s.settings.Authentication == Authentication.Low)
                    {
                        s.settings.Password = GXCommon.HexToBytes(GetValue(node, s));
                    }
                    else
                    {
                        s.settings.CtoSChallenge = GXCommon.HexToBytes(GetValue(node, s));
                    }
                    break;
                case (int)TranslatorGeneralTags.DedicatedKey:
                    tmp = GXCommon.HexToBytes(GetValue(node, s));
                    s.settings.DedicatedKey = tmp;
                    break;
                case (int)TranslatorGeneralTags.CallingAPTitle:
                    s.settings
                    .CtoSChallenge = GXCommon.HexToBytes(GetValue(node, s));
                    break;
                case 0xA4:
                    //RespondingAPTitle.
                    s.settings.StoCChallenge = GXCommon.HexToBytes(GetValue(node, s));
                    break;
                case 0xBE03:
                case 0xBE05:
                    //ProposedConformance or NegotiatedConformance
                    if (s.settings.UseLogicalNameReferencing)
                    {
                        s.settings.LnSettings.Clear();
                    }
                    else
                    {
                        s.settings.SnSettings.Clear();
                    }
                    if (s.OutputType == TranslatorOutputType.StandardXml)
                    {
                        String nodes = node.InnerText;

                        if (s.settings.UseLogicalNameReferencing)
                        {
                            conformanceBlock = s.settings.LnSettings.ConformanceBlock;
                        }
                        else
                        {
                            conformanceBlock = s.settings.SnSettings.ConformanceBlock;
                        }
                        foreach (String it in nodes.Split(' '))
                        {
                            if (it.Trim() != string.Empty)
                            {
                                value = (int)ValueOfConformance(it.Trim());
                                if (value < 0x100)
                                {
                                    conformanceBlock[2] |= (byte)value;
                                }
                                else if (value < 0x10000)
                                {
                                    conformanceBlock[1] |= (byte)(value >> 8);
                                }
                                else
                                {
                                    conformanceBlock[0] |= (byte)(value >> 16);
                                }
                            }
                        }
                    }
                    break;
                case 0xBE08:
                    //ConformanceBit.
                    value = (int)Enum.Parse(typeof(Conformance), node.Attributes["Name"].InnerText);
                    if (s.settings.UseLogicalNameReferencing)
                    {
                        conformanceBlock = s.settings.LnSettings.ConformanceBlock;
                    }
                    else
                    {
                        conformanceBlock = s.settings.SnSettings.ConformanceBlock;
                    }
                    if (value < 0x100)
                    {
                        conformanceBlock[2] |= (byte)value;
                    }
                    else if (value < 0x10000)
                    {
                        conformanceBlock[1] |= (byte)(value >> 8);
                    }
                    else
                    {
                        conformanceBlock[0] |= (byte)(value >> 16);
                    }
                    break;
                case 0xA2:
                    //AssociationResult
                    s.result = (AssociationResult)Enum.Parse(typeof(AssociationResult), GetValue(node, s));
                    break;
                case 0xBE02:
                case 0xBE07:
                    //NegotiatedMaxPduSize or ProposedMaxPduSize.
                    s.settings.MaxPduSize = (UInt16)s.ParseInt(GetValue(node, s));
                    break;
                case 0xA3:
                    //ResultSourceDiagnostic
                    s.diagnostic = SourceDiagnostic.None;
                    break;
                case 0xA301:
                    //ACSEServiceUser
                    s.diagnostic = (SourceDiagnostic)s.ParseInt(GetValue(node, s));
                    break;
                case 0xBE09:
                    // ProposedQualityOfService
                    break;
                case (int)TranslatorGeneralTags.CharString:
                    // Get PW
                    if (s.settings.Authentication == Authentication.Low)
                    {
                        s.settings
                        .Password = GXCommon.HexToBytes(GetValue(node, s));
                    }
                    else
                    {
                        if (s.command == Command.Aarq)
                        {
                            s.settings.CtoSChallenge =
                                GXCommon.HexToBytes(GetValue(node, s));
                        }
                        else
                        {
                            s.settings.StoCChallenge =
                                GXCommon.HexToBytes(GetValue(node, s));
                        }
                    }
                    break;
                case (int)TranslatorGeneralTags.ResponderACSERequirement:
                    break;
                case (int)TranslatorGeneralTags.RespondingAuthentication:
                    s.settings
                    .StoCChallenge = GXCommon.HexToBytes(GetValue(node, s));
                    break;
                case (int)TranslatorTags.Result:
                    s.result = (AssociationResult)
                               int.Parse(GetValue(node, s));
                    break;
                default:
                    throw new ArgumentException("Invalid AARQ node: " + node.Name);

            }
        }
 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();
     }
 }
Esempio n. 16
0
 internal static void AppendData(GXDLMSSettings settings, GXDLMSObject obj, int index, GXByteBuffer bb, Object value)
 {
     DataType tp = obj.GetDataType(index);
     if (tp == DataType.Array)
     {
         if (value is byte[])
         {
             bb.Set((byte[])value);
             return;
         }
         else if (value is GXByteBuffer)
         {
             bb.Set((GXByteBuffer)value);
             return;
         }
     }
     else
     {
         if (tp == DataType.None)
         {
             tp = GXCommon.GetValueType(value);
         }
     }
     GXCommon.SetData(settings, bb, tp, value);
 }
Esempio n. 17
0
        /// <summary>
        /// Handle get request next data block command.
        /// </summary>
        /// <param name="data">Received data.</param>
        internal static void GetRequestNextDataBlock(GXDLMSSettings settings, byte invokeID, GXDLMSServer server, GXByteBuffer data, GXByteBuffer replyData, GXDLMSTranslatorStructure xml, bool streaming)
        {
            GXByteBuffer bb = new GXByteBuffer();

            if (!streaming)
            {
                UInt32 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(null, settings, 0, Command.GetResponse, 2, null, bb, (byte)ErrorCode.DataBlockNumberInvalid), replyData);
                    return;
                }
            }
            settings.IncreaseBlockIndex();
            GXDLMSLNParameters p = new GXDLMSLNParameters(null, settings, invokeID, streaming ? Command.GeneralBlockTransfer : Command.GetResponse, 2, null, bb, (byte)ErrorCode.Ok);

            p.Streaming  = streaming;
            p.WindowSize = settings.WindowSize;
            //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();
                }
            }
        }
Esempio n. 18
0
        ///<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();

            settings.UpdateInvokeId(invokeId);
            // 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 == ConnectionState.None && !settings.CanAccess() && (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, GXDLMSConverter.GetDLMSDataType(actionReply), actionReply);
                    }
                    else
                    {
                        error = e.Error;
                        //Add return parameters
                        bb.SetUInt8(0);
                    }
                }
                invokeId = (byte)e.InvokeId;
            }

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

            GXDLMS.GetLNPdu(p, replyData);
            //If High level authentication fails.
            if (obj is GXDLMSAssociationLogicalName && id == 1)
            {
                if ((obj as GXDLMSAssociationLogicalName).AssociationStatus == Objects.Enums.AssociationStatus.Associated)
                {
                    server.NotifyConnected(connectionInfo);
                    settings.Connected |= ConnectionState.Dlms;
                }
                else
                {
                    server.NotifyInvalidConnection(connectionInfo);
                    settings.Connected &= ~ConnectionState.Dlms;
                }
            }
        }
Esempio n. 19
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="p"></param>
        /// <param name="reply"></param>
        internal static void GetSNPdu(GXDLMSSNParameters p, GXByteBuffer reply)
        {
            bool ciphering = p.settings.Cipher != null && p.settings.Cipher.Security != Gurux.DLMS.Enums.Security.None;
            if (!ciphering && p.settings.InterfaceType == InterfaceType.HDLC)
            {
                if (p.settings.IsServer)
                {
                    reply.Set(GXCommon.LLCReplyBytes);
                }
                else if (reply.Size == 0)
                {
                    reply.Set(GXCommon.LLCSendBytes);
                }
            }
            int cnt = 0, cipherSize = 0;
            if (ciphering)
            {
                cipherSize = CipheringHeaderSize;
                /*
                if (p.settings.Cipher.Security == Security.Encryption)
                {
                    cipherSize = 7;
                }
                else if (p.settings.Cipher.Security == Security.Authentication)
                {
                    cipherSize = 19;
                }
                else if (p.settings.Cipher.Security == Security.AuthenticationEncryption)
                {
                    cipherSize = 7;
                }
                 * */
            }
            if (p.data != null)
            {
                cnt = p.data.Size - p.data.Position;
            }
            // Add command.
            if (p.command != Command.Aarq && p.command != Command.Aare)
            {
                reply.SetUInt8((byte)p.command);
                if (p.count != 0xFF)
                {
                    GXCommon.SetObjectCount(p.count, reply);
                }
                if (p.requestType != 0xFF)
                {
                    reply.SetUInt8(p.requestType);
                }
                reply.Set(p.attributeDescriptor);

                if (!p.multipleBlocks)
                {
                    p.multipleBlocks = reply.Size + cipherSize + cnt > p.settings.MaxPduSize;
                    //If reply data is not fit to one PDU.
                    if (p.multipleBlocks)
                    {
                        //Remove command.
                        GXByteBuffer tmp = new GXByteBuffer();
                        int offset = 1;
                        if (!ciphering && p.settings.InterfaceType == InterfaceType.HDLC)
                        {
                            offset = 4;
                        }
                        tmp.Set(reply.Data, offset, reply.Size - offset);
                        reply.Size = 0;
                        if (!ciphering && p.settings.InterfaceType == InterfaceType.HDLC)
                        {
                            if (p.settings.IsServer)
                            {
                                reply.Set(GXCommon.LLCReplyBytes);
                            }
                            else if (reply.Size == 0)
                            {
                                reply.Set(GXCommon.LLCSendBytes);
                            }
                        }
                        if (p.command == Command.WriteRequest)
                        {
                            p.requestType = (byte)VariableAccessSpecification.WriteDataBlockAccess;
                        }
                        else if (p.command == Command.ReadRequest)
                        {
                            p.requestType = (byte)VariableAccessSpecification.ReadDataBlockAccess;
                        }
                        else if (p.command == Command.ReadResponse)
                        {
                            p.requestType = (byte)SingleReadResponse.DataBlockResult;
                        }
                        else
                        {
                            throw new ArgumentException("Invalid command.");
                        }
                        reply.SetUInt8((byte)p.command);
                        //Set object count.
                        reply.SetUInt8(1);
                        if (p.requestType != 0xFF)
                        {
                            reply.SetUInt8(p.requestType);
                        }
                        cnt = GXDLMS.AppendMultipleSNBlocks(p, tmp, reply);
                    }
                }
                else
                {
                    cnt = GXDLMS.AppendMultipleSNBlocks(p, null, reply);
                }
            }
            // Add data.
            reply.Set(p.data, cnt);
            //Af all data is transfered.
            if (p.data != null && p.data.Position == p.data.Size)
            {
                p.settings.Index = p.settings.Count = 0;
            }
            // If Ciphering is used.
            if (ciphering && p.command != Command.Aarq && p.command != Command.Aare)
            {
                byte[] tmp = p.settings.Cipher.Encrypt((byte)GetGloMessage(p.command), p.settings.Cipher.SystemTitle, reply.Array());
                System.Diagnostics.Debug.Assert(!(p.settings.MaxPduSize < tmp.Length));
                reply.Size = 0;
                if (p.settings.InterfaceType == InterfaceType.HDLC)
                {
                    if (p.settings.IsServer)
                    {
                        reply.Set(GXCommon.LLCReplyBytes);
                    }
                    else if (reply.Size == 0)
                    {
                        reply.Set(GXCommon.LLCSendBytes);
                    }
                }
                reply.Set(tmp);
            }
        }
Esempio n. 20
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;
            }
        }
Esempio n. 21
0
        /// <summary>
        /// Get next logical name PDU.
        /// </summary>
        /// <param name="p">LN parameters.</param>
        /// <param name="reply">Generated message.</param>
        internal static void GetLNPdu(GXDLMSLNParameters p, GXByteBuffer reply)
        {
            bool ciphering = p.settings.Cipher != null && p.settings.Cipher.Security != Gurux.DLMS.Enums.Security.None;
            int len = 0;
            if (!ciphering && p.settings.InterfaceType == InterfaceType.HDLC)
            {
                AddLLCBytes(p.settings, reply);
            }
            if (p.command == Command.Aarq)
            {
                reply.Set(p.attributeDescriptor);
            }
            else
            {
                if (p.settings.LnSettings.GeneralBlockTransfer)
                {
                    reply.SetUInt8((byte)Command.GeneralBlockTransfer);
                    MultipleBlocks(p, reply, ciphering);
                    // Is last block
                    if (!p.lastBlock)
                    {
                        reply.SetUInt8(0);
                    }
                    else
                    {
                        reply.SetUInt8(0x80);
                    }
                    // Set block number sent.
                    reply.SetUInt8(0);
                    // Set block number acknowledged
                    reply.SetUInt8((byte)p.blockIndex);
                    ++p.blockIndex;
                    // Add APU tag.
                    reply.SetUInt8(0);
                    // Add Addl fields
                    reply.SetUInt8(0);
                }
                // Add command.
                reply.SetUInt8((byte)p.command);

                if (p.command == Command.DataNotification ||
                        p.command == Command.AccessRequest ||
                        p.command == Command.AccessResponse)
                {
                    // Add Long-Invoke-Id-And-Priority
                    reply.SetUInt32(GetLongInvokeIDPriority(p.settings));
                    // Add date time.
                    if (p.time == null || p.time.Value.DateTime == DateTime.MinValue || p.time.Value.DateTime == DateTime.MaxValue ||
                            p.time.Value.LocalDateTime == DateTime.MinValue || p.time.Value.LocalDateTime == DateTime.MaxValue)
                    {
                        reply.SetUInt8(DataType.None);
                    }
                    else
                    {
                        // Data is send in octet string. Remove data type.
                        int pos = reply.Size;
                        GXCommon.SetData(p.settings, reply, DataType.OctetString, p.time);
                        reply.Move(pos + 1, pos, reply.Size - pos - 1);
                    }
                }
                else
                {
                    //Get request size can be bigger than PDU size.
                    if (p.command != Command.GetRequest &&
                            p.data != null && p.data.Size != 0)
                    {
                        MultipleBlocks(p, reply, ciphering);
                    }
                    //Change Request type if Set request and multiple blocks is needed.
                    if (p.command == Command.SetRequest)
                    {
                        if (p.multipleBlocks)
                        {
                            if (p.requestType == 1)
                            {
                                p.requestType = 2;
                            }
                            else if (p.requestType == 2)
                            {
                                p.requestType = 3;
                            }
                        }
                    }
                    //Change request type If get response and multiple blocks is needed.
                    if (p.command == Command.GetResponse)
                    {
                        if (p.multipleBlocks)
                        {
                            if (p.requestType == 1)
                            {
                                p.requestType = 2;
                            }
                        }
                    }
                    reply.SetUInt8(p.requestType);
                    // Add Invoke Id And Priority.
                    reply.SetUInt8(GetInvokeIDPriority(p.settings));
                }

                //Add attribute descriptor.
                reply.Set(p.attributeDescriptor);
                if (p.command != Command.DataNotification && !p.settings.LnSettings.GeneralBlockTransfer)
                {
                    //If multiple blocks.
                    if (p.multipleBlocks)
                    {
                        // Is last block.
                        if (p.lastBlock)
                        {
                            reply.SetUInt8(1);
                            p.settings.Count = p.settings.Index = 0;
                        }
                        else
                        {
                            reply.SetUInt8(0);
                        }
                        // Block index.
                        reply.SetUInt32(p.blockIndex);
                        ++p.blockIndex;
                        //Add status if reply.
                        if (p.status != 0xFF)
                        {
                            if (p.status != 0 && p.command == Command.GetResponse)
                            {
                                reply.SetUInt8(1);
                            }
                            reply.SetUInt8(p.status);
                        }
                        //Block size.
                        if (p.data != null)
                        {
                            len = p.data.Size - p.data.Position;
                        }
                        else
                        {
                            len = 0;
                        }
                        int totalLength = len + reply.Size;
                        if (ciphering)
                        {
                            totalLength += CipheringHeaderSize;
                        }

                        if (totalLength > p.settings.MaxPduSize)
                        {
                            len = p.settings.MaxPduSize - reply.Size - p.data.Position;
                            if (ciphering)
                            {
                                len -= CipheringHeaderSize;
                            }
                            len -= GXCommon.GetObjectCountSizeInBytes(len);
                        }
                        GXCommon.SetObjectCount(len, reply);
                        reply.Set(p.data, len);
                    }
                }
                //Add data that fits to one block.
                if (len == 0)
                {
                    //Add status if reply.
                    if (p.status != 0xFF)
                    {
                        if (p.status != 0 && p.command == Command.GetResponse)
                        {
                            reply.SetUInt8(1);
                        }
                        reply.SetUInt8(p.status);
                    }
                    if (p.data != null && p.data.Size != 0)
                    {
                        len = p.data.Size - p.data.Position;
                        //Get request size can be bigger than PDU size.
                        if (p.command != Command.GetRequest && len + reply.Size > p.settings.MaxPduSize)
                        {
                            len = p.settings.MaxPduSize - reply.Size;
                        }
                        reply.Set(p.data, len);
                    }
                }
                if (ciphering)
                {
                    byte[] tmp = p.settings.Cipher.Encrypt((byte)GetGloMessage(p.command),
                                                           p.settings.Cipher.SystemTitle, reply.Array());
                    reply.Size = 0;
                    if (p.settings.InterfaceType == InterfaceType.HDLC)
                    {
                        AddLLCBytes(p.settings, reply);
                    }
                    if (p.command == Command.DataNotification)
                    {
                        // Add command.
                        reply.SetUInt8(tmp[0]);
                        // Add system title.
                        GXCommon.SetObjectCount(
                            p.settings.Cipher.SystemTitle.Length,
                            reply);
                        reply.Set(p.settings.Cipher.SystemTitle);
                        // Add data.
                        reply.Set(tmp, 1, tmp.Length - 1);
                    }
                    else
                    {
                        reply.Set(tmp);
                    }
                }
            }
        }
 /// <summary>
 /// Handle get request next data block command.
 /// </summary>
 /// <param name="data">Received data.</param>
 private static void GetRequestNextDataBlock(GXDLMSSettings settings, GXDLMSServer server, GXByteBuffer data, GXByteBuffer replyData, GXDLMSTranslatorStructure xml)
 {
     GXByteBuffer bb = new GXByteBuffer();
     UInt32 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, Command.GetResponse, 2, null, bb, (byte)ErrorCode.DataBlockNumberInvalid), replyData);
     }
     else
     {
         settings.IncreaseBlockIndex();
         GXDLMSLNParameters p = new GXDLMSLNParameters(settings, 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;
                         if (arg.Handled)
                         {
                             server.NotifyRead(new ValueEventArgs[] { arg });
                             value = arg.Value;
                         }
                         else
                         {
                             value = (arg.Target as IGXDLMSBase).GetValue(settings, arg);
                         }
                         //Add data.
                         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;
             }
         }
     }
 }
        ///<summary>
        /// Handle action request.
        ///</summary>
        ///<param name="Reply">
        /// Received data from the client.
        ///</param>
        ///<returns>
        ///Reply.
        ///</returns>
        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, GXDLMSObject.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, GXDLMSObject.ToLogicalName(ln));
            }
            if (obj == null)
            {
                // Device reports a undefined object.
                error = ErrorCode.UndefinedObject;
            }
            else
            {
                if (obj.GetMethodAccess(id) == MethodAccessMode.NoAccess)
                {
                    error = ErrorCode.ReadWriteDenied;
                }
                else
                {
                    ValueEventArgs e = new ValueEventArgs(settings, obj, id, 0, parameters);
                    server.NotifyAction(new ValueEventArgs[] { e });
                    byte[] actionReply;
                    if (e.Handled)
                    {
                        actionReply = (byte[])e.Value;
                    }
                    else
                    {
                        actionReply = (obj as IGXDLMSBase).Invoke(settings, 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);
                    }
                }
            }

            GXDLMSLNParameters p = new GXDLMSLNParameters(settings, 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);
            }
        }
 ///<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, 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);
 }
Esempio n. 25
0
 /// <summary>
 /// Add LLC bytes to generated message.
 /// </summary>
 /// <param name="settings">DLMS settings.</param>
 /// <param name="data">Data where bytes are added.</param>
 private static void AddLLCBytes(GXDLMSSettings settings, GXByteBuffer data)
 {
     if (settings.IsServer)
     {
         data.Set(0, GXCommon.LLCReplyBytes);
     }
     else
     {
         data.Set(0, GXCommon.LLCSendBytes);
     }
 }
        ///<summary>
        /// Handle Access request.
        ///</summary>
        ///<param name="Reply">
        /// Received data from the client.
        /// </param>
        ///<returns>
        /// Reply.
        ///</returns>
        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.
            UInt32 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);
            }
        }
Esempio n. 27
0
 static int AppendMultipleSNBlocks(GXDLMSSNParameters p, GXByteBuffer header, GXByteBuffer reply)
 {
     bool ciphering = p.settings.Cipher != null && p.settings.Cipher.Security != Gurux.DLMS.Enums.Security.None;
     int hSize = reply.Size + 3;
     if (header != null)
     {
         hSize += header.Size;
     }
     //Add LLC bytes.
     if (p.command == Command.WriteRequest ||
             p.command == Command.ReadRequest)
     {
         hSize += 1 + GXCommon.GetObjectCountSizeInBytes(p.count);
     }
     int maxSize = p.settings.MaxPduSize - hSize;
     if (ciphering)
     {
         maxSize -= CipheringHeaderSize;
         if (p.settings.InterfaceType == InterfaceType.HDLC)
         {
             maxSize -= 3;
         }
     }
     maxSize -= GXCommon.GetObjectCountSizeInBytes(maxSize);
     if (p.data.Size - p.data.Position > maxSize)
     {
         //More blocks.
         reply.SetUInt8(0);
     }
     else
     {
         //Last block.
         reply.SetUInt8(1);
         maxSize = p.data.Size - p.data.Position;
     }
     //Add block index.
     reply.SetUInt16(p.blockIndex);
     if (p.command == Command.WriteRequest)
     {
         ++p.blockIndex;
         GXCommon.SetObjectCount(p.count, reply);
         reply.SetUInt8(DataType.OctetString);
     }
     if (p.command == Command.ReadRequest)
     {
         ++p.blockIndex;
     }
     if (header != null)
     {
         GXCommon.SetObjectCount(maxSize + header.Size, reply);
         reply.Set(header);
     }
     else
     {
         GXCommon.SetObjectCount(maxSize, reply);
     }
     return maxSize;
 }
Esempio n. 28
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();
            }
        }
Esempio n. 29
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());
        }
Esempio n. 30
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 != (byte)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 != (byte)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 (Settings.InterfaceType == Enums.InterfaceType.HDLC)
                    {
                        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());
        }
Esempio n. 31
0
        /// <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(null, settings, invokeID, Command.GetResponse, 3, null, bb, 0xFF);

            GXDLMS.GetLNPdu(p, replyData);
        }
Esempio n. 32
0
 /// <summary>
 /// Find next frame from the string.
 /// </summary>
 /// <remarks>
 /// Position of data is set to the begin of new frame. If Pdu is null it is not updated.
 /// </remarks>
 /// <param name="data">Data where frame is search.</param>
 /// <param name="pdu">Pdu of received frame is set here.</param>
 /// <returns>Is new frame found.</returns>
 public bool FindNextFrame(GXByteBuffer data, GXByteBuffer pdu)
 {
     GXDLMSSettings settings = new GXDLMSSettings(true);
     GXReplyData reply = new GXReplyData();
     reply.Xml = new GXDLMSTranslatorStructure(OutputType, Hex, ShowStringAsHex, null);
     int pos;
     while (data.Position != data.Size)
     {
         if (data.GetUInt8(data.Position) == 0x7e)
         {
             pos = data.Position;
             settings.InterfaceType = Enums.InterfaceType.HDLC;
             GXDLMS.GetData(settings, data, reply);
             data.Position = pos;
             break;
         }
         else if (data.Position + 2 < data.Size && data.GetUInt16(data.Position) == 0x1)
         {
             pos = data.Position;
             settings.InterfaceType = Enums.InterfaceType.WRAPPER;
             GXDLMS.GetData(settings, data, reply);
             data.Position = pos;
             break;
         }
         ++data.Position;
     }
     if (pdu != null)
     {
         pdu.Clear();
         pdu.Set(reply.Data.Data, 0, reply.Data.Size);
     }
     return data.Position != data.Size;
 }
Esempio n. 33
0
 /// <summary>
 /// Split DLMS PDU to wrapper frames.
 /// </summary>
 /// <param name="settings">DLMS settings.</param>
 /// <param name="data"> Wrapped data.</param>
 /// <returns>Wrapper frames</returns>
 internal static byte[] GetWrapperFrame(GXDLMSSettings settings, GXByteBuffer data)
 {
     GXByteBuffer bb = new GXByteBuffer();
     // Add version.
     bb.SetUInt16(1);
     if (settings.IsServer)
     {
         bb.SetUInt16((UInt16)settings.ServerAddress);
         bb.SetUInt16((UInt16)settings.ClientAddress);
     }
     else
     {
         bb.SetUInt16((UInt16)settings.ClientAddress);
         bb.SetUInt16((UInt16)settings.ServerAddress);
     }
     if (data == null)
     {
         // Data length.
         bb.SetUInt16(0);
     }
     else
     {
         // Data length.
         bb.SetUInt16((UInt16)data.Size);
         // Data
         bb.Set(data);
     }
     //Remove sent data in server side.
     if (settings.IsServer)
     {
         if (data.Size == data.Position)
         {
             data.Clear();
         }
         else
         {
             data.Move(data.Position, 0, data.Size - data.Position);
             data.Position = 0;
         }
     }
     return bb.Array();
 }
Esempio n. 34
0
        /// <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);
            e.InvokeId = invokeID;
            if (obj == null)
            {
                // "Access Error : Device reports a undefined object."
                status = ErrorCode.UndefinedObject;
            }
            else
            {
                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;
                }
            }
            GXDLMSLNParameters p = new GXDLMSLNParameters(null, settings, e.InvokeId, Command.GetResponse, 1, null, bb, (byte)status);

            GXDLMS.GetLNPdu(p, replyData);
            if (settings.Count != settings.Index || bb.Size != bb.Position)
            {
                server.transaction = new GXDLMSLongTransaction(new ValueEventArgs[] { e }, Command.GetRequest, bb);
            }
        }
        /// <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>();
            //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);
                List<ValueEventArgs> reads = new List<ValueEventArgs>();
                List<ValueEventArgs> actions = new List<ValueEventArgs>();
                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);
            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))
            {
                List<ValueEventArgs> 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;
            }
        }
Esempio n. 36
0
        ///<summary>
        /// Handle write request.
        ///</summary>
        public static void HandleWriteRequest(GXDLMSSettings settings, GXDLMSServer server, GXByteBuffer data,
                                              GXByteBuffer replyData, GXDLMSTranslatorStructure xml, Command cipheredCommand)
        {
            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);
                }
            }
            GXDataInfo   di;
            GXSNInfo     info;
            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
                                | type,
                                "Value", xml.IntegerToHex(sn, 4));
                    }
                    else
                    {
                        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)
                {
                    //Return error if connection is not established.
                    if (xml == null && (settings.Connected & ConnectionState.Dlms) == 0 && cipheredCommand == Command.None)
                    {
                        replyData.Add(GXDLMSServer.GenerateConfirmedServiceError(ConfirmedServiceError.InitiateError,
                                                                                 ServiceError.Service, (byte)Service.Unsupported));
                        return;
                    }
                    HandleReadDataBlockAccess(settings, server, Command.WriteResponse, data, cnt, replyData, xml, cipheredCommand);
                    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);
            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);
                    }
                }
                else if (results.GetUInt8(pos) == 0)
                {
                    bool access = true;
                    // If object has found.
                    GXSNInfo target = targets[pos];
                    value = GXCommon.GetData(settings, data, di);
                    ValueEventArgs e = new ValueEventArgs(server, target.Item, target.Index, 0, null);
                    if (target.IsAction)
                    {
                        MethodAccessMode am = server.NotifyGetMethodAccess(e);
                        // If action is denied.
                        if (am != MethodAccessMode.Access)
                        {
                            access = false;
                        }
                    }
                    else
                    {
                        if (value is byte[])
                        {
                            DataType dt = target.Item.GetDataType(target.Index);
                            if (dt != DataType.None && dt != DataType.OctetString)
                            {
                                value = GXDLMSClient.ChangeType((byte[])value, dt, settings.UseUtc2NormalTime);
                            }
                        }
                        AccessMode am = server.NotifyGetAttributeAccess(e);
                        // If write is denied.
                        if (am != AccessMode.Write && am != AccessMode.ReadWrite)
                        {
                            access = false;
                        }
                    }
                    if (access)
                    {
                        if (target.IsAction)
                        {
                            e.Parameters = value;
                            ValueEventArgs[] actions = new ValueEventArgs[] { e };
                            server.NotifyAction(actions);
                            if (!e.Handled)
                            {
                                byte[] reply = (target.Item as IGXDLMSBase).Invoke(settings, e);
                                server.NotifyPostAction(actions);
                                if (target.Item is GXDLMSAssociationShortName && target.Index == 8 && reply != null)
                                {
                                    GXByteBuffer bb = new GXByteBuffer();
                                    bb.SetUInt8((byte)DataType.OctetString);
                                    bb.SetUInt8((byte)reply.Length);
                                    bb.Set(reply);
                                    GXDLMSSNParameters p = new GXDLMSSNParameters(settings, Command.ReadResponse, 1, 0, null, bb);
                                    GXDLMS.GetSNPdu(p, replyData);
                                }
                            }
                        }
                        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 });
                            }
                        }
                    }
                    else
                    {
                        results.SetUInt8((byte)pos, (byte)ErrorCode.ReadWriteDenied);
                    }
                }
            }
            if (xml != null)
            {
                xml.AppendEndTag(TranslatorTags.ListOfData);
                xml.AppendEndTag(Command.WriteRequest);
                return;
            }
            GenerateWriteResponse(settings, results, replyData);
        }
Esempio n. 37
0
        /// <summary>
        /// Get HDLC frame for data.
        /// </summary>
        /// <param name="settings">DLMS settings.</param>
        /// <param name="frame">Frame ID. If zero new is generated.</param>
        /// <param name="data">Data to add.</param>
        /// <returns>HDLC frames.</returns>
        internal static byte[] GetHdlcFrame(GXDLMSSettings settings, byte frame, GXByteBuffer data)
        {
            GXByteBuffer bb = new GXByteBuffer();
            int frameSize, len = 0;
            byte[] primaryAddress, secondaryAddress;
            if (settings.IsServer)
            {
                primaryAddress = GetHdlcAddressBytes(settings.ClientAddress, 0);
                secondaryAddress = GetHdlcAddressBytes(settings.ServerAddress, settings.ServerAddressSize);
            }
            else
            {
                primaryAddress = GetHdlcAddressBytes(settings.ServerAddress, settings.ServerAddressSize);
                secondaryAddress = GetHdlcAddressBytes(settings.ClientAddress, 0);
            }
            // Add BOP
            bb.SetUInt8(GXCommon.HDLCFrameStartEnd);
            frameSize = Convert.ToInt32(settings.Limits.MaxInfoTX);
            // If no data
            if (data == null || data.Size == 0)
            {
                bb.SetUInt8(0xA0);
            }
            else if (data.Size - data.Position <= frameSize)
            {
                // Is last packet.
                bb.SetUInt8(0xA0);
                len = data.Size - data.Position;
            }
            else
            {
                // More data to left.
                bb.SetUInt8(0xA8);
                len = frameSize;
            }
            //Frame len.
            if (len == 0)
            {
                bb.SetUInt8((byte)(5 + primaryAddress.Length + secondaryAddress.Length + len));
            }
            else
            {
                bb.SetUInt8((byte)(7 + primaryAddress.Length + secondaryAddress.Length + len));
            }
            // Add primary address.
            bb.Set(primaryAddress);
            // Add secondary address.
            bb.Set(secondaryAddress);

            //Add frame ID.
            if (frame == 0)
            {
                frame = settings.NextSend();
            }
            bb.SetUInt8(frame);
            // Add header CRC.
            UInt16 crc = GXFCS16.CountFCS16(bb.Data, 1, bb.Size - 1);
            bb.SetUInt16(crc);
            if (len != 0)
            {
                //Add data.
                bb.Set(data, len);
                // Add data CRC.
                crc = GXFCS16.CountFCS16(bb.Data, 1, bb.Size - 1);
                bb.SetUInt16(crc);
            }
            // Add EOP
            bb.SetUInt8(GXCommon.HDLCFrameStartEnd);
            if (data != null)
            {
                //Remove sent data in server side.
                if (settings.IsServer)
                {
                    if (data.Size == data.Position)
                    {
                        data.Clear();
                    }
                    else
                    {
                        data.Move(data.Position, 0, data.Size - data.Position);
                        data.Position = 0;
                    }
                }
            }
            return bb.Array();
        }
Esempio n. 38
0
        ///<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 == ConnectionState.None && !settings.CanAccess())
            {
                reply.Set(GXDLMSServer.GenerateConfirmedServiceError(ConfirmedServiceError.InitiateError,
                                                                     ServiceError.Service, (byte)Service.Unsupported));
                return;
            }
            //Get long invoke id and priority.
            UInt32 invokeId = data.GetUInt32();

            settings.longInvokeID = invokeId;
            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);
            }
        }
Esempio n. 39
0
 /// <summary>
 /// Convert xml to byte array.
 /// </summary>
 /// <param name="xml">Converted xml.</param>
 /// <returns>Converted bytes.</returns>
 public byte[] XmlToPdu(string xml)
 {
     XmlDocument doc = new XmlDocument();
     doc.LoadXml(xml);
     GXDLMSXmlSettings s = new GXDLMSXmlSettings(OutputType, Hex, ShowStringAsHex, tagsByName);
     ReadAllNodes(doc, s);
     GXByteBuffer bb = new GXByteBuffer();
     GXDLMSLNParameters ln;
     GXDLMSSNParameters sn;
     switch (s.command)
     {
         case Command.InitiateRequest:
         case Command.InitiateResponse:
             break;
         case Command.ReadRequest:
         case Command.WriteRequest:
         case Command.ReadResponse:
         case Command.WriteResponse:
             sn = new GXDLMSSNParameters(s.settings, s.command, s.count,
                                         s.requestType, s.attributeDescriptor, s.data);
             GXDLMS.GetSNPdu(sn, bb);
             break;
         case Command.GetRequest:
         case Command.GetResponse:
         case Command.SetRequest:
         case Command.SetResponse:
         case Command.MethodRequest:
         case Command.MethodResponse:
             ln = new GXDLMSLNParameters(s.settings, s.command, s.requestType,
                                         s.attributeDescriptor, s.data, 0xff);
             GXDLMS.GetLNPdu(ln, bb);
             break;
         case Command.GloGetRequest:
         case Command.GloGetResponse:
         case Command.GloSetRequest:
         case Command.GloSetResponse:
         case Command.GloMethodRequest:
         case Command.GloMethodResponse:
         case Command.GloReadRequest:
         case Command.GloWriteRequest:
         case Command.GloReadResponse:
         case Command.GloWriteResponse:
             bb.SetUInt8((byte)s.command);
             GXCommon.SetObjectCount(s.data.Size, bb);
             bb.Set(s.data);
             break;
         case Command.Rejected:
             break;
         case Command.Snrm:
             s.settings.IsServer = false;
             bb.Set(GXDLMS.GetHdlcFrame(s.settings, (byte)Command.Snrm, null));
             break;
         case Command.Ua:
             break;
         case Command.Aarq:
         case Command.GloInitiateRequest:
             GXAPDU.GenerateAarq(s.settings, s.settings.Cipher, s.data, bb);
             break;
         case Command.Aare:
         case Command.GloInitiateResponse:
             GXAPDU.GenerateAARE(s.settings, bb, s.result, s.diagnostic, s.settings.Cipher, s.data);
             break;
         case Command.DisconnectRequest:
             break;
         case Command.ReleaseRequest:
             bb.SetUInt8((byte)s.command);
             bb.SetUInt8(0);
             break;
         case Command.ReleaseResponse:
             bb.SetUInt8((byte)s.command);
             //Len
             bb.SetUInt8(3);
             //BerType
             bb.SetUInt8(BerType.Context);
             //Len.
             bb.SetUInt8(1);
             bb.SetUInt8(s.reason);
             break;
         case Command.ConfirmedServiceError:
             break;
         case Command.ExceptionResponse:
             break;
         case Command.GeneralBlockTransfer:
             break;
         case Command.AccessRequest:
             ln = new GXDLMSLNParameters(s.settings, s.command, s.requestType,
                                         s.attributeDescriptor, s.data, 0xff);
             GXDLMS.GetLNPdu(ln, bb);
             break;
         case Command.AccessResponse:
             ln = new GXDLMSLNParameters(s.settings, s.command, s.requestType,
                                         s.attributeDescriptor, s.data, 0xff);
             GXDLMS.GetLNPdu(ln, bb);
             break;
         case Command.DataNotification:
             ln = new GXDLMSLNParameters(s.settings, s.command, s.requestType,
                                         s.attributeDescriptor, s.data, 0xff);
             ln.time = s.time;
             GXDLMS.GetLNPdu(ln, bb);
             break;
         case Command.GloGeneralCiphering:
             break;
         case Command.GloEventNotificationRequest:
             break;
         default:
         case Command.None:
             throw new ArgumentException("Invalid command.");
     }
     return bb.Array();
 }