/// <summary>
        /// Read attribute value.
        /// </summary>
        /// <param name="it">COSEM object to read.</param>
        /// <param name="attributeIndex">Attribute index.</param>
        /// <returns>Read value.</returns>
        public object Read(GXDLMSObject it, int attributeIndex)
        {
            if ((it.GetAccess(attributeIndex) & AccessMode.Read) != 0)
            {
                GXReplyData reply = new GXReplyData();
                if (!ReadDataBlock(Client.Read(it, attributeIndex), reply))
                {
                    if (reply.Error != (short)ErrorCode.Rejected)
                    {
                        throw new GXDLMSException(reply.Error);
                    }
                    reply.Clear();
                    Thread.Sleep(1000);
                    if (!ReadDataBlock(Client.Read(it, attributeIndex), reply))
                    {
                        throw new GXDLMSException(reply.Error);
                    }
                }
                //Update data type.
                if (it.GetDataType(attributeIndex) == DataType.None)
                {
                    it.SetDataType(attributeIndex, reply.DataType);
                }
                return(Client.UpdateValue(it, attributeIndex, reply.Value));
            }

            return(null);
        }
 void OnProfileGenericDataReceived(object sender, GXReplyData reply)
 {
     if (reply.Value != null)
     {
         lock (reply)
         {
             client.UpdateValue(CurrentProfileGeneric, 2, reply.Value);
             reply.Value = new Object[0];
         }
         if (OnAfterRead != null)
         {
             OnAfterRead(CurrentProfileGeneric, 2);
         }
     }
 }
Example #3
0
        private async void DoWork(object ínfo)
        {
            //Give some time DB server to start up.
            Thread.Sleep(1000);
            GetNextTaskResponse ret = null;

            System.Net.Http.HttpResponseMessage response;
            //Don't wait reply. It might that DB server is not up yet.
            if (ínfo != null)
            {
                using (response = await client.PostAsJsonAsync(Startup.ServerAddress + "/api/reader/AddReader", new AddReader()
                {
                    Reader = ínfo as GXReaderInfo
                }))
                {
                    Helpers.CheckStatus(response);
                }
            }
            _logger.LogInformation("Reader Service is started.");
            while (!_cancellationToken.IsCancellationRequested)
            {
                try
                {
                    using (response = await client.PostAsJsonAsync(Startup.ServerAddress + "/api/task/GetNextTask", new GetNextTask()))
                    {
                        Helpers.CheckStatus(response);
                        ret = await response.Content.ReadAsAsync <GetNextTaskResponse>();
                    }
                    if (ret.Tasks != null)
                    {
                        int                pos = 0;
                        GXDevice           dev;
                        GXDLMSSecureClient cl;
                        using (response = await client.PostAsJsonAsync(Startup.ServerAddress + "/api/device/ListDevices", new ListDevices()
                        {
                            Ids = new[] { ret.Tasks[0].Object.DeviceId }
                        }))
                        {
                            Helpers.CheckStatus(response);
                            ListDevicesResponse r = await response.Content.ReadAsAsync <ListDevicesResponse>();

                            if (r.Devices == null || r.Devices.Length == 0)
                            {
                                continue;
                            }
                            dev = r.Devices[0];
                        }
                        IGXMedia media;
                        if (string.Compare(dev.MediaType, typeof(GXNet).FullName, true) == 0)
                        {
                            media = new GXNet();
                        }
                        else if (string.Compare(dev.MediaType, typeof(GXSerial).FullName, true) == 0)
                        {
                            media = new GXSerial();
                        }
                        else if (string.Compare(dev.MediaType, typeof(GXTerminal).FullName, true) == 0)
                        {
                            media = new GXTerminal();
                        }
                        else
                        {
                            Type type = Type.GetType(dev.MediaType);
                            if (type == null)
                            {
                                string ns = "";
                                pos = dev.MediaType.LastIndexOf('.');
                                if (pos != -1)
                                {
                                    ns = dev.MediaType.Substring(0, pos);
                                }
                                foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
                                {
                                    if (assembly.GetName().Name == ns)
                                    {
                                        if (assembly.GetType(dev.MediaType, false, true) != null)
                                        {
                                            type = assembly.GetType(dev.MediaType);
                                        }
                                    }
                                }
                            }
                            if (type == null)
                            {
                                throw new Exception("Invalid media type: " + dev.MediaType);
                            }
                            media = (IGXMedia)Activator.CreateInstance(type);
                        }
                        if (media == null)
                        {
                            throw new Exception("Unknown media type '" + dev.MediaType + "'.");
                        }
                        media.Settings = dev.MediaSettings;
                        GXDLMSReader reader;
                        //Read frame counter from the meter.
                        if (dev.Security != 0)
                        {
                            cl = new GXDLMSSecureClient(dev.UseLogicalNameReferencing, 16, dev.PhysicalAddress,
                                                        Authentication.None, null, (InterfaceType)dev.InterfaceType);
                            reader = new GXDLMSReader(cl, media, _logger);
                            media.Open();
                            reader.InitializeConnection();
                            //Read Innovation counter.
                            GXDLMSData d = new GXDLMSData(dev.FrameCounter);
                            reader.Read(d, 2);
                            dev.InvocationCounter = 1 + Convert.ToUInt32(d.Value);
                            reader.Disconnect();
                            media.Close();
                        }
                        cl = new GXDLMSSecureClient(dev.UseLogicalNameReferencing, dev.ClientAddress, dev.PhysicalAddress,
                                                    (Authentication)dev.Authentication, dev.Password, (InterfaceType)dev.InterfaceType);
                        if (dev.HexPassword != null && dev.HexPassword.Length != 0)
                        {
                            cl.Password = dev.HexPassword;
                        }
                        cl.UseUtc2NormalTime     = dev.UtcTimeZone;
                        cl.Standard              = dev.Standard;
                        cl.Ciphering.SystemTitle = GXCommon.HexToBytes(dev.ClientSystemTitle);
                        if (cl.Ciphering.SystemTitle != null && cl.Ciphering.SystemTitle.Length == 0)
                        {
                            cl.Ciphering.SystemTitle = null;
                        }
                        cl.Ciphering.BlockCipherKey = GXCommon.HexToBytes(dev.BlockCipherKey);
                        if (cl.Ciphering.BlockCipherKey != null && cl.Ciphering.BlockCipherKey.Length == 0)
                        {
                            cl.Ciphering.BlockCipherKey = null;
                        }
                        cl.Ciphering.AuthenticationKey = GXCommon.HexToBytes(dev.AuthenticationKey);
                        if (cl.Ciphering.AuthenticationKey != null && cl.Ciphering.AuthenticationKey.Length == 0)
                        {
                            cl.Ciphering.AuthenticationKey = null;
                        }
                        cl.ServerSystemTitle = GXCommon.HexToBytes(dev.DeviceSystemTitle);
                        if (cl.ServerSystemTitle != null && cl.ServerSystemTitle.Length == 0)
                        {
                            cl.ServerSystemTitle = null;
                        }
                        cl.Ciphering.InvocationCounter = dev.InvocationCounter;
                        cl.Ciphering.Security          = (Security)dev.Security;
                        reader = new GXDLMSReader(cl, media, _logger);
                        media.Open();
                        reader.InitializeConnection();
                        pos = 0;
                        int count = ret.Tasks.Length;
                        foreach (GXTask task in ret.Tasks)
                        {
                            ++pos;
                            try
                            {
                                GXDLMSObject obj = GXDLMSClient.CreateObject((ObjectType)task.Object.ObjectType);
                                obj.LogicalName = task.Object.LogicalName;
                                obj.ShortName   = task.Object.ShortName;
                                if (task.TaskType == TaskType.Write)
                                {
                                    if (obj.LogicalName == "0.0.1.1.0.255" && task.Index == 2)
                                    {
                                        cl.UpdateValue(obj, task.Index, GXDateTime.ToUnixTime(DateTime.UtcNow));
                                    }
                                    else
                                    {
                                        cl.UpdateValue(obj, task.Index, GXDLMSTranslator.XmlToValue(task.Data));
                                    }
                                    reader.Write(obj, task.Index);
                                }
                                else if (task.TaskType == TaskType.Action)
                                {
                                    reader.Method(obj, task.Index, GXDLMSTranslator.XmlToValue(task.Data), DataType.None);
                                }
                                else if (task.TaskType == TaskType.Read)
                                {
                                    //Reading the meter.
                                    if (task.Object.Attributes[0].DataType != 0)
                                    {
                                        obj.SetDataType(task.Index, (DataType)task.Object.Attributes[0].DataType);
                                    }
                                    if (task.Object.Attributes[0].UIDataType != 0)
                                    {
                                        obj.SetUIDataType(task.Index, (DataType)task.Object.Attributes[0].UIDataType);
                                    }
                                    Reader.Read(_logger, client, reader, task, media, obj);
                                    if (task.Object.Attributes[0].DataType == 0)
                                    {
                                        task.Object.Attributes[0].DataType = (int)obj.GetDataType(task.Index);
                                        if (task.Object.Attributes[0].UIDataType == 0)
                                        {
                                            task.Object.Attributes[0].UIDataType = (int)obj.GetUIDataType(task.Index);
                                        }
                                        UpdateDatatype u = new UpdateDatatype()
                                        {
                                            Items = new GXAttribute[] { task.Object.Attributes[0] }
                                        };
                                        response = client.PostAsJsonAsync(Startup.ServerAddress + "/api/Object/UpdateDatatype", u).Result;
                                        Helpers.CheckStatus(response);
                                    }
                                }
                            }
                            catch (Exception ex)
                            {
                                task.Result = ex.Message;
                                AddError error = new AddError();
                                error.Error = new GXError()
                                {
                                    DeviceId = dev.Id,
                                    Error    = "Failed to " + task.TaskType + " " + task.Object.LogicalName + ":" + task.Index + ". " + ex.Message
                                };
                                _logger.LogError(error.Error.Error);
                                using (response = await client.PostAsJsonAsync(Startup.ServerAddress + "/api/error/AddError", error))
                                {
                                    Helpers.CheckStatus(response);
                                    await response.Content.ReadAsAsync <AddErrorResponse>();
                                }
                            }
                            task.End = DateTime.Now;
                            //Close connection after last task is executed.
                            //This must done because there might be new task to execute.
                            if (count == pos)
                            {
                                try
                                {
                                    reader.Close();
                                }
                                catch (Exception ex)
                                {
                                    task.Result = ex.Message;
                                    AddError error = new AddError();
                                    error.Error = new GXError()
                                    {
                                        DeviceId = dev.Id,
                                        Error    = "Failed to close the connection. " + ex.Message
                                    };
                                    _logger.LogError(error.Error.Error);
                                    using (response = await client.PostAsJsonAsync(Startup.ServerAddress + "/api/error/AddError", error))
                                    {
                                        Helpers.CheckStatus(response);
                                        await response.Content.ReadAsAsync <AddErrorResponse>();
                                    }
                                }
                            }
                            //Update execution time.
                            response = client.PostAsJsonAsync(Startup.ServerAddress + "/api/task/TaskReady", new TaskReady()
                            {
                                Tasks = new GXTask[] { task }
                            }).Result;
                            Helpers.CheckStatus(response);
                        }
                    }
                    else
                    {
                        try
                        {
                            using (response = await client.PostAsJsonAsync(Startup.ServerAddress + "/api/task/WaitChange", new WaitChange()
                            {
                                Change = TargetType.Tasks, Time = lastUpdated, WaitTime = _waitTime
                            }))
                            {
                                Helpers.CheckStatus(response);
                                {
                                    WaitChangeResponse r = await response.Content.ReadAsAsync <WaitChangeResponse>();

                                    if (r.Time > lastUpdated)
                                    {
                                        lastUpdated = r.Time;
                                    }
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            if (!_cancellationToken.IsCancellationRequested)
                            {
                                break;
                            }
                            _cancellationToken.WaitHandle.WaitOne(TimeSpan.FromSeconds(10));
                        }
                    }
                }
                catch (Exception ex)
                {
                    //If app is closing.
                    if (_cancellationToken.IsCancellationRequested)
                    {
                        break;
                    }
                    if (ret == null)
                    {
                        _logger.LogError("Failed to connect to the DB server.");
                    }
                    else
                    {
                        AddError error = new AddError();
                        error.Error = new GXError()
                        {
                            DeviceId = ret.Tasks[0].Object.DeviceId,
                            Error    = "Failed to " + ret.Tasks[0].TaskType + " " + ret.Tasks[0].Object.LogicalName + ":" + ret.Tasks[0].Index + ". " + ex.Message
                        };
                        using (response = await client.PostAsJsonAsync(Startup.ServerAddress + "/api/error/AddError", error))
                        {
                            if (ret.Tasks != null)
                            {
                                DateTime now = DateTime.Now;
                                foreach (GXTask it in ret.Tasks)
                                {
                                    it.Result = ex.Message;
                                    it.End    = now;
                                }
                                response = await client.PostAsJsonAsync(Startup.ServerAddress + "/api/task/TaskReady", new TaskReady()
                                {
                                    Tasks = ret.Tasks
                                });
                            }
                        }
                    }
                    _logger.LogError(ex.Message);
                }
            }
        }
Example #4
0
        /// <summary>
        /// This method is used to update meter firmware.
        /// </summary>
        /// <param name="target"></param>
        public void ImageUpdate(GXDLMSImageTransfer target, byte[] identification, byte[] data)
        {
            //Check that image transfer ia enabled.
            GXReplyData reply = new GXReplyData();

            ReadDataBlock(Client.Read(target, 5), reply);
            Client.UpdateValue(target, 5, reply.Value);
            if (!target.ImageTransferEnabled)
            {
                throw new Exception("Image transfer is not enabled");
            }

            //Step 1: Read image block size.
            ReadDataBlock(Client.Read(target, 2), reply);
            Client.UpdateValue(target, 2, reply.Value);

            // Step 2: Initiate the Image transfer process.
            ReadDataBlock(target.ImageTransferInitiate(Client, identification, data.Length), reply);

            // Step 3: Transfers ImageBlocks.
            int imageBlockCount;

            ReadDataBlock(target.ImageBlockTransfer(Client, data, out imageBlockCount), reply);

            //Step 4: Check the completeness of the Image.
            ReadDataBlock(Client.Read(target, 3), reply);
            Client.UpdateValue(target, 3, reply.Value);

            // Step 5: The Image is verified;
            ReadDataBlock(target.ImageVerify(Client), reply);
            // Step 6: Before activation, the Image is checked;

            //Get list to images to activate.
            ReadDataBlock(Client.Read(target, 7), reply);
            Client.UpdateValue(target, 7, reply.Value);
            bool bFound = false;

            foreach (GXDLMSImageActivateInfo it in target.ImageActivateInfo)
            {
                if (it.Identification == identification)
                {
                    bFound = true;
                    break;
                }
            }

            //Read image transfer status.
            ReadDataBlock(Client.Read(target, 6), reply);
            Client.UpdateValue(target, 6, reply.Value);
            if (target.ImageTransferStatus != Gurux.DLMS.Objects.Enums.ImageTransferStatus.VerificationSuccessful)
            {
                throw new Exception("Image transfer status is " + target.ImageTransferStatus.ToString());
            }

            if (!bFound)
            {
                throw new Exception("Image not found.");
            }

            //Step 7: Activate image.
            ReadDataBlock(target.ImageActivate(Client), reply);
        }
        /// <summary>
        /// Client has send data.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void OnReceived(object sender, Gurux.Common.ReceiveEventArgs e)
        {
            try
            {
                lock (this)
                {
                    if (trace)
                    {
                        Console.WriteLine("<- " + Gurux.Common.GXCommon.ToHex((byte[])e.Data, true));
                    }
                    reply.Set((byte[])e.Data);
                    //Example handles only notify messages.
                    GXReplyData data = new GXReplyData();
                    client.GetData(reply, data, notify);
                    // If all data is received.
                    if (notify.IsComplete && !notify.IsMoreData)
                    {
                        try
                        {
                            //Show data as XML.
                            string           xml;
                            GXDLMSTranslator t = new GXDLMSTranslator(TranslatorOutputType.SimpleXml);
                            t.DataToXml(notify.Data, out xml);
                            Console.WriteLine(xml);

                            // Print received data.
                            PrintData(notify.Value, 0);

                            //Example is sending list of push messages in first parameter.
                            if (notify.Value is List <object> )
                            {
                                List <object> tmp = notify.Value as List <object>;
                                List <KeyValuePair <GXDLMSObject, int> > objects = client.ParsePushObjects((List <object>)tmp[0]);
                                //Remove first item because it's not needed anymore.
                                objects.RemoveAt(0);
                                //Update clock.
                                int Valueindex = 1;
                                foreach (KeyValuePair <GXDLMSObject, int> it in objects)
                                {
                                    client.UpdateValue(it.Key, it.Value, tmp[Valueindex]);
                                    ++Valueindex;
                                    //Print value
                                    Console.WriteLine(it.Key.ObjectType + " " + it.Key.LogicalName + " " + it.Value + ":" + it.Key.GetValues()[it.Value - 1]);
                                }
                            }
                            Console.WriteLine("Server address:" + notify.ServerAddress + " Client Address:" + notify.ClientAddress);
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine(ex.Message);
                        }
                        finally
                        {
                            notify.Clear();
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
Example #6
0
        public void InitializeConnection()
        {
            try
            {
                log("Connection");
                GXReplyData reply = new GXReplyData();
                byte[]      data;
                UpdateSettings();
                //Read frame counter if GeneralProtection is used.
                if (!string.IsNullOrEmpty(parent.FrameCounter) && client.Ciphering != null && client.Ciphering.Security != Security.None)
                {
                    reply.Clear();
                    int            add       = client.ClientAddress;
                    Authentication auth      = client.Authentication;
                    Security       security  = client.Ciphering.Security;
                    byte[]         challenge = client.CtoSChallenge;
                    try
                    {
                        client.ClientAddress      = 16;
                        client.Authentication     = Authentication.None;
                        client.Ciphering.Security = Security.None;

                        data = SNRMRequest();
                        if (data != null)
                        {
                            try
                            {
                                ReadDataBlock(data, "Send SNRM request.", reply);
                            }
                            catch (TimeoutException)
                            {
                                reply.Clear();
                                ReadDataBlock(DisconnectRequest(), "Send Disconnect request.", reply);
                                reply.Clear();
                                ReadDataBlock(data, "Send SNRM request.", reply);
                            }
                            catch (Exception e)
                            {
                                reply.Clear();
                                ReadDataBlock(DisconnectRequest(), "Send Disconnect request.", reply);
                                throw e;
                            }
                            //GXLogWriter.WriteLog("Parsing UA reply succeeded.");
                            //Has server accepted client.
                            ParseUAResponse(reply.Data);
                        }
                        ReadDataBlock(AARQRequest(), "Send AARQ request.", reply);
                        try
                        {
                            //Parse reply.
                            ParseAAREResponse(reply.Data);
                            //GXLogWriter.WriteLog("Parsing AARE reply succeeded.");
                            reply.Clear();
                            GXDLMSData d = new GXDLMSData(parent.FrameCounter);
                            ReadDLMSPacket(Read(d, 2), reply);
                            client.UpdateValue(d, 2, reply.Value);
                            client.Ciphering.InvocationCounter = parent.InvocationCounter = 1 + Convert.ToUInt32(d.Value);
                            reply.Clear();
                            ReadDataBlock(DisconnectRequest(), "Disconnect request", reply);
                        }
                        catch (Exception Ex)
                        {
                            reply.Clear();
                            ReadDataBlock(DisconnectRequest(), "Disconnect request", reply);
                            throw Ex;
                        }
                    }
                    finally
                    {
                        client.ClientAddress      = add;
                        client.Authentication     = auth;
                        client.Ciphering.Security = security;
                        client.CtoSChallenge      = challenge;
                    }
                }
                data = SNRMRequest();
                if (data != null)
                {
                    try
                    {
                        reply.Clear();
                        ReadDataBlock(data, "Send SNRM request.", reply);
                    }
                    catch (TimeoutException)
                    {
                        reply.Clear();
                        ReadDataBlock(DisconnectRequest(), "Send Disconnect request.", reply);
                        reply.Clear();
                        ReadDataBlock(data, "Send SNRM request.", reply);
                    }
                    catch (Exception e)
                    {
                        reply.Clear();
                        ReadDataBlock(DisconnectRequest(), "Send Disconnect request.", reply);
                        throw e;
                    }
                    //GXLogWriter.WriteLog("Parsing UA reply succeeded.");
                    //Has server accepted client.
                    ParseUAResponse(reply.Data);
                }
                if (!parent.PreEstablished)
                {
                    //Generate AARQ request.
                    //Split requests to multiple packets if needed.
                    //If password is used all data might not fit to one packet.
                    reply.Clear();
                    ReadDataBlock(AARQRequest(), "Send AARQ request.", reply);
                    try
                    {
                        //Parse reply.
                        ParseAAREResponse(reply.Data);
                        //GXLogWriter.WriteLog("Parsing AARE reply succeeded.");
                    }
                    catch (Exception Ex)
                    {
                        reply.Clear();
                        ReadDLMSPacket(DisconnectRequest(), reply);
                        throw Ex;
                    }
                    //If authentication is required.
                    if (client.Authentication > Authentication.Low)
                    {
                        reply.Clear();
                        ReadDataBlock(client.GetApplicationAssociationRequest(), "Authenticating.", reply);
                        client.ParseApplicationAssociationResponse(reply.Data);
                    }
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }