Coder Social home page Coder Social logo

opcfoundation / ua-.net-legacy Goto Github PK

View Code? Open in Web Editor NEW
329.0 82.0 297.0 44.42 MB

OPC Foundation Unified Architecture .NET Reference Implementations

C# 70.75% Smalltalk 1.15% Batchfile 0.01% C++ 4.20% C 5.50% HTML 15.90% CSS 0.26% JavaScript 2.18% Brightscript 0.01% Rich Text Format 0.03% ASP.NET 0.01%

ua-.net-legacy's Introduction

OPC Foundation UA .NET-Legacy

This repository is provided by OPC Foundation as legacy support for older .NET Framework versions and will not receive further features and updates.

The official Unified Architecture .NET Stack maintained by OPC Foundation will be based on .NET Standard and can be found here.

Only critical security updates will be provided for this repository.

The end of life for this codebase is 2022-12-32. All users should migrate to UA-.NETStandard before then.

ua-.net-legacy's People

Contributors

alinmoldovean avatar barnstee avatar benlaan avatar cmorty avatar esugoi avatar fhurta avatar maddin-619 avatar matkubicki avatar md-v avatar milankase avatar mrsuciu avatar nathanpocock avatar opcfoundation-org avatar randy-armstrong-alias avatar rf-brolli avatar thomasnehring avatar zryska avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ua-.net-legacy's Issues

Wrong revised MaxKeepAliveCount and LifeTimeCount calculation

The standard server sample does wrong calculations when the publishing interval is revised, because it still computes the time limits with the revised publishing interval instead of the requested one. This can lead in particular to actual subscription lifetime greater than the max subscription lifetime configured. The bug is both in SubscriptionManager.cs, CreateSubscription and ModifySubscription.

            revisedPublishingInterval = CalculatePublishingInterval(requestedPublishingInterval);
            // calculate the keep alive count.
            revisedMaxKeepAliveCount = CalculateKeepAliveCount(revisedPublishingInterval, requestedMaxKeepAliveCount);
            // calculate the lifetime count.
            revisedLifetimeCount = CalculateLifetimeCount(revisedPublishingInterval, revisedMaxKeepAliveCount, requestedLifetimeCount);

for example: revised publishing interval is 1000 instead of 100. CalculateKeepAliveCount receives revised publishing interval and keepAliveInterval is 10x too large. It may be capped.
Same for LifeTimeCount. Moreover, LifeTimeCount can be increased to 3*KeepAliveCount after check against MaxSubscriptionLifeTime, even if it should not have been caped in the first place and was correct from the client point of view.

Proposal: Calculate requested time interval and revise KeepAliveCount and LifeTimeCount if publishing interval is revised, before applying configuration checks and max.

Consider rename of 'Opc.Ua.NodeState.Description' to prevent member hiding?

In reference to:
https://github.com/OPCFoundation/UA-.NET/blob/master/Stack/Core/Stack/State/NodeState.cs#L334

I believe that 'Description' is a very common property name to have on an object type. Using that name on an OPC object type will however result in member hiding.

For example, if the following 'ObjectType'-declaration is fed through the modelcompiler...

<opc:ObjectType SymbolicName="MyObject" >
    <opc:Children>
        <opc:Property SymbolicName="Name" ModellingRule="Mandatory" DataType="ua:String" AccessLevel="ReadWrite"  />
        <opc:Property SymbolicName="Description" ModellingRule="Mandatory" DataType="ua:String" AccessLevel="ReadWrite"  />
    </opc:Children>
    <opc:References />
    <opc:ClassName />
    <opc:Fields />
</opc:ObjectType>

...it will generate a 'PropertyState Description'-property on the 'ObjectTypeState' generated for this declaration, which hides 'Opc.Ua.NodeState.Description' and causes a compiler warning. Wouldn't it make more sense to change 'Opc.Ua.NodeState.Description' into 'Opc.Ua.NodeState.LocalizedNodeDescription'? (Or something similiar?)

Obviously this would lead to breaking changes but at least I want to put my thoughts regarding this design out here.

.NET Sample UA client ExpandedNodeId Issue for nodes that have namespaceuri

Using the Java stack to develop the OPC UA Server. But .NET Sample client is not able convert ExpandedNodeId to nodeId for those node which have the namespaceuri "http://opcfoundation.org/UA/".

Error log :
6452 - 10:00:30.941 Could not fetch references for valid node with NodeId = i=85. Error = Cannot cast an absolute ExpandedNodeId to a NodeId. Use ExpandedNodeId.ToNodeId instead.
6452 - 10:00:30.955 Could not fetch references for valid node with NodeId = i=35. Error = Cannot cast an absolute ExpandedNodeId to a NodeId. Use ExpandedNodeId.ToNodeId instead.
6452 - 10:00:30.960 Could not fetch references for valid node with NodeId = nsu=http://opcfoundation.org/UA/;i=2004. Error = Cannot cast an absolute ExpandedNodeId to a NodeId. Use ExpandedNodeId.ToNodeId instead.
6452 - 10:00:30.967 Could not fetch references for valid node with NodeId = nsu=http://opcfoundation.org/UA/;i=61. Error = Cannot cast an absolute ExpandedNodeId to a NodeId. Use ExpandedNodeId.ToNodeId instead.

An examle of how to use OPC services

Can someone provide a simple example of how to use UA.NET services from the sample apps?
What I need is to read data from a tag on an Kepware OPC server. Thanks in advance.

ServerBase unregister from the UALDS even if never registered

StandardServer.cs, mthod OnServerStopping:
"if (m_maxRegistrationInterval > 0)"
should be added just before the call to RegisterWithDiscoveryServer();

Otherwise a server will try to contact UALDS even if LDS support is not allowed per configuration file (MaxRegistrationInterval set to 0).
Disabling is important since UALDS doesn't scale well.

Resolving DataType fails in UA Com Interoperability library

The problem occurs, when alias definitions are created in OPC Classic DA source server and OPC UA Wrapper connected to those measurement points. In this case the DataType attribute cannot be resolved correctly and Variant datatype is returned for alias nodes in every case. A workaround is to read correct datatype from Value attribute (if node is Readable) or from history data (if node is HistoryReadable), but in case the node has Write Only access, the datatype cannot be resolved at all.

The scenario can be verified e.g. by using Matrikon Simulation Server for OPC and making an alias definition to some of the write only nodes in OPC DA address space. Then connect the OPC UA wrapper into simulation server and start OPC Foundation’s OPC UA SampleClient and connect to the OPC UA wrapper. Using this combination it is impossible to write into test nodes. The problem reproduces using other OPC Classic source servers we have in production sites.

OPC UA .Net Stack Read service issues

I’m using .Net stack to implement OPC UA client. Everything works fine, but I’ve found very strange issue. I was investigating it, but cannot find any clue even in the source code.

My main issue is that when I’m calling a lot of Reads at the same time from .Net Thread Pool, I’m experiencing some problems at the beginning of the communication, the session is created, but first calls are very slow. It would be ok, but sometimes they are so slow, that the channel is timed out. After it is automatically recreated by the stack, everything works perfectly from now on. Very interesting thing is that when I increase the minimum number of working threads in Thread Pool it behaves much better (e.g. ThreadPool.SetMinThreads(16, completion)).

I haven’t experienced such issues when I execute exactly the same code from the same amount of concurrent jobs, but from within Threads that were created manually.

I’ve prepared sample application to reproduce this issue outside of my app. It is available here: source code and logs (https://onedrive.live.com/redir?resid=25D5CBE900D5F532!627&authkey=!AO8OtKIgqZ5XLTg&ithint=file%2c7z). There is only a project, but it could be used as part of the UA Sample Applications.sln solution of the opc-ua-1.02-.net-stackandsamples-336.0-20150707 release. To run this, please update the UA configuration in OPC.UA.config.xml file and the address of the endpoint of the Sample Server at the beginning.

Later on there are a few variations over how the Read calls are made.
• DoJobsInNewThreads – specified number of threads are created and read is executed for n times
• DoJobsInThreadPool – specified number of work items in Thread Pool are created and read is executed for n times

In my environment (Windows 7, i7 processor) DoJobsInNewThreads(10, 1000, …); is working correctly, while DoJobsInThreadPool(10, 1000, …); is not. I expect that with a big load it will work slower, but stable. The strangest thing is that it would start to work (sometimes after reconnection) and it works from the beginning if the code is run from the Thread.

Sample Configuration Library open configuration file not shared

The methods ApplicationConfiguration.LoadWithNoValidation and ApplicationConfiguration.Load open the configuration file with FileInfo.Open overload that uses only 2 parameters. This prevents sharing the file when multiple servers/clients try to open the same configuraiton file.
Please consider adding FileShare.Read to the Open call, as in:

        // BEGIN 24/02/2016
        XmlTextReader reader = new XmlTextReader(file.Open(FileMode.Open, FileAccess.Read, FileShare.Read));
        // END

Scalability problem within request queue with multiple request threads

The request queue code awakes all the threads of its thread pool each time a new request is inserted in the queue. With the default configuration, under load due to several clients connecting or even while their publishing work, 100 threads are awaken for each incoming request. This can use all the CPU resources even on a Core i7.
The reason is the "m_event" is a ManualResetEvent instead of an AutoResetEvent. With an AutoResetEvent we could ensure all threads are effectively used simply by resetting the event if necessary.
Change proposal:
In RequestQueue constructor:

                 // CODRA FFT 22624 - BEGIN 07/04/2016 - Issue GitHub#31
                m_event = new AutoResetEvent(false);
                // CODRA FFT 22624 - END

In OnProcessRequestQueue:

                             // CODRA FFT 22624 - BEGIN 07/04/2016 - Issue GitHub#31
                            // reset queue if queue is empty.
                            //if (m_queue.Count == 0)
                            //{
                            //    m_event.Reset();
                            //}
                            // restart a thread if queue is not empty.
                            if (m_queue.Count != 0)
                            {
                                m_event.Set();
                            }
                            // CODRA FFT 22624 - END

Add support for GDS

RegisterServer2 respective FindServersOnNetwork support to be added to stack and exemplified in the sample applications (both server and client).

Call OPC UA Method gives exception

I'm trying to call a method on a SINUMERIK 840d with the following code:

List<string> parameters = new List<string>() { "Q37.7" };
IList<object> val = session.Call("ns=2;s=Sinumerik/Methods", "ns=2;s=Sinumerik/Methods/ReadVar", parameters);

Console.WriteLine("Read value collection: " + val);
Console.WriteLine("Read value collection length: " + val.Count);

foreach (var t in val)
{
  Console.WriteLine("Iterated value: " + t);
}

This however gives me the exception error:

Unhandled Exception: Opc.Ua.ServiceResultException: BadUnknownResponse
   at Opc.Ua.Client.Session.Call(NodeId objectId, NodeId methodId, Object[] arg
)

Am I doing something wrong or is this an issue in the code?

Constructor 'NodeId(object, ushort)' does not throw an exception

The constructor for 'NodeId' featured below:

https://github.com/OPCFoundation/UA-.NET/blob/45681985986aaa01bd71884bfed94e33843c504c/Stack/Core/Types/BuiltIn/NodeId.cs#L251-L288

...does not throw an exception if an unsupported type is specified into the 'value'-parameter. I believe that either the documentation tag "Throws an exception if the identifier type is not supported." is false, or an actual exception should be thrown. Is my observation correct or am I mistaken? Thanks.

Client/Stack appends a forward slash to endpoint URLs

This was discovered here in Phoenix at the OPC interop.

It appears the sample client, perhaps due to some fault in the stack, since it's affecting users of the .NET stack as well, appends a forward slash to the end of endpoint URLs before it connects to a server.

For example, instructing the client to connect to opc.tcp://192.168.10.17:12685 will result in a Hello message containing the endpoint URL opc.tcp://192.168.10.17:12685/.

Certificate Issue BadCertificateHostNameInvalid

Hi,

We are using the Opc.Ua.Client library to connect to various OPC UA Servers (Ignition and KepServer to name two).

To take KepServer as an example we find that it creates a server certificate containing its fully qualified domain name and therefore if we attempt to connect via IP address we get a BadCertificateHostInvalid failure. This still happens if we setup KepServer with only IP address endpoints and regenerate the certificate.

Looking at the code for the Opc.Ua.Client I see that there is an option on the method Opc.Ua.Client.Session.Create called 'checkDomain', this disables the check for the domain in the certificate within the Create method, but is not passed on to Session.Open where another ceck is performed (in another call to 'CheckCertificateDomain').

Is this a bug? Looking at other OPC UA clients I see at least some (Unified Automation) have an option to disable the domain check, should we allow connections in this situation and change the Opc.Ua.Client library to allow it?

Thanks,

Matt

False warning messages from .NET OPC UA client session

The method ProcessPublishResponse of the client session (Opc.Ua.Client.Session) probably generates false warning messages Sequence number={0} was not received in the available sequence numbers. The code that checks for the sequence numbers does not take into account the subscription id. If there is more than one subscription in the session then this code mixes up the sequence numbers from different sessions and issues the above mentioned message.

The code responsible:

foreach (var acknowledgement in acknowledgementsToSend)
{
    if (!availableSequenceNumbers.Contains(acknowledgement.SequenceNumber))
    {
        Utils.Trace("Sequence number={0} was not received in the available sequence numbers.", acknowledgement.SequenceNumber);
    }
}

Suggested fix:

    ...
    if (acknowledgement.SubscriptionId == subscriptionId && !availableSequenceNumbers.Contains(acknowledgement.SequenceNumber))
    {
    ...

Can anybody confirm?

This is follow-up to the forum thread.

Add date information in trace messages

Minor update:

Add date information in trace messages. Currently only timestamp is logged.

In \Stack\Core\Types\Utils\Utils.cs file change line#482:

message.AppendFormat("{0:HH:mm:ss.fff} ", HiResClock.UtcNow.ToLocalTime());

to

message.AppendFormat("{0:d} {0:HH:mm:ss.fff} ", HiResClock.UtcNow.ToLocalTime());

Session Certificate private key is not loaded

When an OPC UA Client loads a certificate to use it as a session certificate, the method UserIdentity.Initialize() in Stack/Core/Stack/Client/UserIdentity.cs calls the CertificateIdentifier.Find() method without the optional boolean argument which indicates whether the certificate should be loaded together with it's private key. This causes the certificate to be loaded without it's private key, which is inadequate for the purpose (the certificate is needed to verify the identity of the client) in question and causes an error, e.g., in a later session.Create().

This can be fixed by calling 'Intialize()' with the value 'true'. I did not check for uninted side effects, though.

How to detect that status and timestamp is writable (CTT also)

Currently there is no way to detect if a server supports writing of status and or timestamp.

One option would be to have a server wide capability information about general support of this feature.

A more specific information would be to extend the access level with additional flags for StatusWrite and TimestampWrite.

Discussed at IOP Nuremberg 2013
Additional information / discussion through Christian Hock / Karl Deiretsbacher

Bug in ServerSystemContext.cs

Implementation of following are wrong:
public ServerSystemContext Copy(Session session)
public ServerSystemContext Copy(ServerSystemContext context)

should modify the cloned copy but not this self.

Correct implementation should be:
public ServerSystemContext Copy(Session session)
{
ServerSystemContext copy = (ServerSystemContext)MemberwiseClone();
copy.OperationContext = null;
if (session != null)
{
copy.SessionId = session.Id;
copy.UserIdentity = session.Identity;
copy.PreferredLocales = session.PreferredLocales;
}
else
{
copy.SessionId = null;
copy.UserIdentity = null;
copy.PreferredLocales = null;
}

        return copy;
    }

public ServerSystemContext Copy(ServerSystemContext context)
{
ServerSystemContext copy = (ServerSystemContext)MemberwiseClone();
if (context != null)
{
copy.OperationContext = context.OperationContext;
copy.SessionId = context.SessionId;
copy.UserIdentity = context.UserIdentity;
copy.PreferredLocales = context.PreferredLocales;
copy.NamespaceUris = context.NamespaceUris;
copy.ServerUris = context.ServerUris;
copy.TypeTable = context.TypeTable;
copy.EncodeableFactory = context.EncodeableFactory;
}

        return copy;
    }

IDictionary contract broken in implementation of NodeIdDictionary

When a diagnostics is not enabled, then the Server Subscription's m_diagnosticsId is initialized to null (in Opc.Ua.Server.Subscription constructor). Then during Subscription.Delete the null value is propagated to NodeIdDictionary.TryGetValue. This breaks the contract of the IDictionary, since the implementation of IDictionary.TryGetValue should throw ArgumentNullException for null keys. The NodeIdDictionary implementation returns false instead. When compiling library with Code Contracts enabled, the precondition violation is reported.

When OPC UA server Registers with LDS will always recieve a BadSecureChannelClosed exception

A UA server derived from StandardServer in the SDK using the .NET Framework Stack seems to always get a BadSecureChannelClosed exception when registering with the LDS. Note that the Registration itself succeeds, just that it seems to be abruptly terminating the SecureChannel which the .NET Framework Stack does not like. This may be by design, although seems kind of rough.

The actual issue is initiated in the TcpMessageSoccket.GetNextMessage method where the messageChunk.Array is null.

Because it appears that the Certificates between the LDS and the Server are mutually trusted, and the registration works properly I have to assume this is something everyone is just ignoring in the exception handling. Of course I may have something configured incorrectly...

Sample UA Server should exhibit the same behavior.

InvalidCastException in DataTypes.GetBrowseName

In the method DataTypes.GetBrowseName the return value from the FieldInfo.GetValue method is type-casted from object to int. This however throws the InvalidCastException since the constants in the DataTypes class are defined as uints and must be unboxed to the exact same type (i.e. int).

Improve description of the matrix dimensions array (CTT also)

It is not clear which values and combination of values are allowed for the elements in the dimensions array of matrices.

Suggestion for valid configurations:
[-1;-1;-1] for null matrix (according to array with length -1)
[0;0;0] for emtpy matrix (according to array with length 0)
[n>0;n>0;n>0] for all remaining configurations

Values < -1 should not be allowed.
0 or -1 in combination with values > 0 should not be allowed. (i.e. [-1;1;1])

Current stacks seem to preserve the input values which creates difficulties for the applications.

Stack should not try to "correct" invalid values but reject them.
The compliance test tool should provide tests with valid and invalid values.

Deadlock in ScheduleIncomingRequest. Regression from 335 build.

Hi,

We've been seeing a deadlock in the OPC UA stack with the code base from GitHub that had previously been fixed in the 335 builds prior to open sourcing the stack. I've done some digging with reflector and the current code on GitHub and have found what I think is the issue.

This was previously reported on Mantis:
https://opcfoundation-onlineapplications.org/mantis/view.php?id=2458
And reported as fixed in 335. It seemed to be fixed, and a look at the code and the comment from Cristian Gaudi on the Mantis issue suggests that the change was purely in ServerBase.RequestQueue.ScheduleIncomingRequest.

The deadlock appears to be that within RequestQueue.ScheduleIncomingRequest if we have too many requests we call OperationCompleted, this eventaully gets to TcpServerChannel.SendResponse who needs to get the DataLock lock, but if another thread is waiting on the RequestQueue lock whilst inside TcpServerChannel.HandleIncomingMessage there is a problem.

Here is the deadlocking code from Opc.Ua.Core v1.1.331.0 (excuse this code its reflectors best attempt!):

public void ScheduleIncomingRequest(IEndpointIncomingRequest request)
{
    lock (this.m_lock)
    {
        if (this.m_stopped || (this.m_queue.Count >= this.m_maxRequestCount))
        {
            request.OperationCompleted(null, -2146435072);
        }
        else
        {
            this.m_queue.Enqueue(request);
            this.m_event.Set();
            if ((this.m_totalThreadCount < this.m_maxThreadCount) && ((this.m_totalThreadCount < this.m_minThreadCount) || (this.m_totalThreadCount <= this.m_activeThreadCount)))
            {
                this.m_totalThreadCount++;
                new Thread(new ParameterizedThreadStart(this.OnProcessRequestQueue)) { IsBackground = true }.Start(null);
            }
        }
    }
}

Then the code from Opc.Ua.Core v1.1.335.0:

public void ScheduleIncomingRequest(IEndpointIncomingRequest request)
{
    bool flag = false;
    lock (this.m_lock)
    {
        if (this.m_stopped || (this.m_queue.Count >= this.m_maxRequestCount))
        {
            flag = true;
        }
        else
        {
            this.m_queue.Enqueue(request);
            this.m_event.Set();
            if (this.m_totalThreadCount >= this.m_maxThreadCount)
            {
                return;
            }
            if ((this.m_totalThreadCount < this.m_minThreadCount) || (this.m_totalThreadCount <= this.m_activeThreadCount))
            {
                this.m_totalThreadCount++;
                new Thread(new ParameterizedThreadStart(this.OnProcessRequestQueue)) { IsBackground = true }.Start(null);
            }
        }
    }
    if (flag)
    {
        request.OperationCompleted(null, -2146435072);
    }
}

Note that the call to report 'BadTooManyOperations', the number '-2146435072', is now outside of the lock, this removes the cause of the deadlock.

If we look at the code today on GitHub we see that it has changed again to improve the management of threads (it seems). The problem is that the call to OperationCompleted is back inside the lock:

public void ScheduleIncomingRequest(IEndpointIncomingRequest request)
 {
           // queue the request.
           lock (m_lock)   // i.e. Monitor.Enter(m_lock)
           {
                // check able to schedule requests.
                if (m_stopped || m_queue.Count >= m_maxRequestCount)
                {
                    request.OperationCompleted(null, StatusCodes.BadTooManyOperations);
                    return;
                }
               m_queue.Enqueue(request);
               // wake up an idle thread to handle the request if there is one
               if (m_activeThreadCount < m_totalThreadCount)
               {
                   Monitor.Pulse(m_lock);
               }
               // start a new thread to handle the request if none are idle and the pool is not full.
               else if (m_totalThreadCount < m_maxThreadCount)
               {
                   Thread thread = new Thread(OnProcessRequestQueue);
                   thread.IsBackground = true;
                   thread.Start(null);
                  m_totalThreadCount++;
                   m_activeThreadCount++;  // new threads start in an active state

                       Utils.Trace("Thread created: " + Thread.CurrentThread.ManagedThreadId + ". Current thread count: " + m_totalThreadCount + ". Active thread count" + m_activeThreadCount);
               }
           }
}

Wrong Min/MaxRequestThreadCount configuration parameters validation

The OPC UA Stack doesn't validate correctly configuration parameters for the request queue's thread pool:

  • it doesn't check the min and max are positive values ;
  • it doesn't check the min <= max ;
  • it forces the mawPoolThread at least to 100 threads, which is not justified and absurd.
    For the last point, this is annoying because in case of high load by many clients connecting and reading initial state, the thread count can grow up to the max, causing huge memory consumption on the server's process which may need the memory and CPU resources for other tasks. A more reasonable value should be for example the number of logical cores of the platform for instance.
    To fix this, I would propose modifying the following:
    In "InitializeRequestQueue.cs":
    // CODRA FFT 22622 - BEGIN 07/04/2016
    // set suitable defaults.
    int minRequestThreadCount = 2;
    int maxRequestThreadCount = 10;
    // CODRA FFT 22622 - END
    ...
    // CODRA FFT 22622 - BEGIN 07/04/2016
    // ensure configuration errors don't render the server inoperable.
    if (minRequestThreadCount < 1)
    {
    minRequestThreadCount = 1;
    }
    if (maxRequestThreadCount < minRequestThreadCount)
    {
    maxRequestThreadCount = minRequestThreadCount;
    }
    // CODRA FFT 22622 - BEGIN 07/04/2016

Faulty escape character handling

Hi,

I believe the escape character handling in UaComInterop/Common/Client/Da/DaParseNodeId.cs does not work correctly. The defected code is in function public static new DaParsedNodeId Parse(NodeId nodeId).

The OPC UA specification in Part 4. says following about escape characters: "_The & sign character is the escape character. It is used to specify reserved characters that appear within a BrowseName. A reserved character is escaped by inserting the „&‟ in front of it. Examples of BrowseNames with escaped characters are: Received browse path name Resolves to"
“&/Name_1” “/Name_1”
“&.Name_2” “.Name_2”
“&:Name_3” “:Name_3”
“&&Name_4” “&Name_4”
_

Now, if there is a '&' sign in the OPC classic server folder name that is connected to wrapper server using UaCominterop library, the folder name is resolved to "SomethingWithEscapeCharacter&&". In the defected line BOTH escape characters '&&' are then removed in DaParsedNodeId Parse(NodeId nodeId) function, which leads into BadNodeIdUnknown error, because the NodeId is not found anymore in OPC UA nodemanager.

Is SessionClient.Call thread-safe?

I can see async versions, but anyway I wonder if sync version (i.e. Call method) is thread-safe? I look for answer along the lines "yes, there is a guarantee", or "no, you have to use async versions".

The CertificateGenerator utility is not installed

I cloned and built the git repo. After building the repo I opened QuickStarts.DataAccessServer.exe just like the tutorial says but I received an exception since the certification could not be generated from the utility which doesn't seem to exist. How can I get the CertificateGenerator utility?
image

Thanks!

Nuget

Hello together,

what do you think about nuget? I think it could be useful to define nuget packages.
If you think it is usefull for this project, i would like to support you with this.

Best wishes

Handle leak in Tcp/TcpAsyncOperation.cs and Transport/AsyncResultBase.cs

TcpAsyncOperation implements IDisposable, but Dispose is never called.
The same for AsyncResultBase.
The TcpAsyncOperation.End method initializes an Event and uses it to wait the operation completion. However, this event cannot be freed determinstically since the opertion are never disposed.
A simple correction is to free the event just after the operation completion in the End method:

// wait for completion.
if (mustWait)
{
if (!m_event.WaitOne(timeout, false))
{
// Added :
m_event.Close();
m_event = null;
throw new ServiceResultException(StatusCodes.BadRequestInterrupted);
}
// Added :
m_event.Close();
m_event = null;
}

However the AsyncWaitHandle property should never be called, since we do not know if the event will be destroyed or not. Hopefully, this property is dead code and never called.

Same with AsyncResultBase.WaitForComplete and AsyncWaitHandle.

STEPS TO REPRODUCE:
36h certification test, with 5 clients, 1000 MonitoredItems/client, nodes changing at rate 1000 times/200ms
Small handle leak.

GPL, RCL and .NET licence questions

The UA samples are dual licensed GPLv2 (not LGPL) and RCL.
I wonder how will be licensed any modification (GPL only or both?), because fixes made in the GPL context cannot be used in proprietary softwares that use the RCL license.
Moreover, as .NET assemblies are not really system libraries (since MS has open sourced them), I think the GPL license is incompatible with any .NET solution.

Use after free in RequestQueue thread pool after Dispose

The RequestQueue Dispose code set the m_event and the Close it just afterwards, without waiting for all threads to complete.
The thread pool threads can therefore use the event after close, which can cause several problems (exceptions, bug check in underlying native code when accessing closed event, etc.).
This is not a good practice, either wait for all the threads to complete or transfer event.Close to the last thread:

 protected virtual void Dispose(bool disposing)
            {
                if (disposing)
                {
                    lock (m_lock)
                    {
                        m_stopped = true;
                        if (m_event != null)
                        {
                            m_event.Set();
                            m_event.Close();   // ARGGH
                            m_event = null;
                        }
                        m_queue.Clear();
                    }
                }
            }

Morever, with the proposed fix of issue 31, an alternative event for wakening all threads at dispose should be used.

Add Certificate Generator

The certificate generator is needed to run the samples. Therefore it should be added to this repository in binary format.

(current workaround - install the sample binaries first which implicitly also installs the certificate generator)

Unclear How To Get Started

It's not clear how to get started using this code. There's nothing in the ReadMe and the Getting Started guides on the project website require a paid membership.

Something as simple as "these files go here in this kind of project" would suffice.

GetItemResults causes an overflow exception in 64-bit environment

Exception happens in UA COM interop library, when items are added to DA group. The GetItemResults function in Client\Da\ComDaGroup.cs crashes due to overflow exception. Problem is caused by following line, which attempts to calculate IntPtr value:

pos = (IntPtr)(pos.ToInt32() + Marshal.SizeOf(typeof (OpcRcw.Da.OPCITEMRESULT)));

The exception message is: "Arithmetic operation resulted in an overflow."

Opc.Ua.ConfiguredEndpoint Constructor does not respect provided configuration

There is a mistake in the file:
UA-.NET/Stack/Core/Stack/Configuration/ConfiguredEndpoints.cs

Which means that when you create a ConfiguredEndpoint using an ApplicationDescription and an EndpointConfiguration the EndpointConfiguration is always ignored. A look through the samples suggests this is not intentional. It is a simple fix by the looks of things. Further down the constructor it checks for the member variable m_configuration being null, I suspect it should be checking the parameter configuration instead.

Recreating the session does not honor original client handles of monitored items

When the client session is recreated (the Session.Recreate method, used e.g. during reconnection) then monitored items in the new subscriptions of the newly created session does not honor original client handles, since during recreation the items are assigned autogenerated handles. Since the client handle is the only way to identify the item during session notification (or is it not?) this quite complicates things. One would legitimately expect that after reconnection (using the SessionReconnectHandler) the returned session is in the same state as the original one.

Is this a bug or a feature? How to identify items during session notification if not using client handles? What is the expected use case?

An exception occurs in NodeCache.FetchNode.

I found that An exception occurs in NodeCache.cs line 645.
When ExpandedNodeId.IsAbsolute is true and converts an ExpandedNodeId to a NodeId, an exception occurs.

I think that should set the node Id obtained by converting the namespace URI to the server dependent index in NodeCache.cs line 645.

For example, Add a constructor to the Node class;

public partial class Node : IFormattable, ILocalNode
{
    #region Constructors
------
    /// <summary>
    /// Creates a node from the local node id and a reference desciption.
    /// </summary>
    /// <param name="localId">The local node id.</param>
    /// <param name="reference">The reference.</param>
    public Node(NodeId localId, ReferenceDescription reference)
    {
        Initialize();

        m_nodeId = localId;
        m_nodeClass = reference.NodeClass;
        m_browseName = reference.BrowseName;
        m_displayName = reference.DisplayName;
    }
-----

Change the NodeCache.cs line 645;

Node target = new Node(reference);

Node target = new Node(localId, reference);

Thanks.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.