Giter Site home page Giter Site logo

open62541 / open62541 Goto Github PK

View Code? Open in Web Editor NEW
2.4K 173.0 1.2K 53.45 MB

Open source implementation of OPC UA (OPC Unified Architecture) aka IEC 62541 licensed under Mozilla Public License v2.0

Home Page: http://open62541.org

License: Mozilla Public License 2.0

CMake 4.06% C++ 0.55% C 90.85% Shell 1.03% Python 3.23% PowerShell 0.17% Dockerfile 0.04% Makefile 0.01% Yacc 0.07%
opc-ua sdk server client iec-62541 opc c opcua industrial-automation pubsub

open62541's Introduction

open62541

open62541 (http://open62541.org) is an open source implementation of OPC UA (OPC Unified Architecture / IEC 62541) written in the C language. The library is usable with all major compilers and provides the necessary tools to implement dedicated OPC UA clients and servers, or to integrate OPC UA-based communication into existing applications. The open62541 library is platform independent: All platform-specific functionality is implemented via exchangeable plugins for easy porting to different (embedded) targets.

open62541 is licensed under the Mozilla Public License v2.0 (MPLv2). This allows the open62541 library to be combined and distributed with any proprietary software. Only changes to the open62541 library itself need to be licensed under the MPLv2 when copied and distributed. The plugins, as well as the server and client examples are in the public domain (CC0 license). They can be reused under any license and changes do not have to be published.

The library is available in standard source and binary form. In addition, the single-file source distribution merges the entire library into a single .c and .h file that can be easily added to existing projects. Example server and client implementations can be found in the /examples directory or further down on this page.

Open Hub Project Status Build Status Build Status Code Scanning Fuzzing Status codecov

Features

open62541 implements an OPC UA SDK with support for servers, clients and PubSub (publish-subscribe) communication. See the features overview for full details.

  • Core Stack
    • OPC UA binary and JSON encoding
    • TCP-based OPC UA SecureChannel
    • Custom data types (generated from XML definitions)
    • Portable C99 -- architecture-specific code is encapsulated behind standard interfaces
    • Highly configurable with default plugins for encryption (OpenSSL, mbedTLS), access control, historizing, logging, etc.
  • Server
    • Support for all OPC UA services (except the Query service -- not implemented by any SDK)
    • Support for generating information models from standard XML definitions (Nodeset Compiler)
    • Support for adding and removing nodes and references at runtime
    • Support for subscriptions (data-change and event notifications)
  • Client
    • Support for all OPC UA services
    • Support for asynchronous service requests
    • Background handling of subscriptions
  • PubSub
    • PubSub message encoding (binary and JSON)
    • Transport over UDP-multicast, Ethernet, MQTT
    • Runtime configuration via the information model
    • Configurable realtime fast-path

Commercial Use and Official Support

open62541 is licensed under the MPLv2. That is, changes to files under MPLv2 fall under the same open-source license. But the library can be combined with private development from separate files, also if a static binary is produced, without the license affecting the private files. See the full license document for details.

Fraunhofer IOSB maintains open62541 and provides official commercial support. Additional service providers are listed on open62541.org.

Official Certification

The sample server (server_ctt) built using open62541 v1.0 is in conformance with the 'Micro Embedded Device Server' Profile of OPC Foundation supporting OPC UA client/server communication, subscriptions, method calls and security (encryption) with the security policies 'Basic128Rsa15', 'Basic256' and 'Basic256Sha256' and the facets 'method server' and 'node management'. See https://open62541.org/certified-sdk for more details.

PubSub (UADP) is implemented in open62541. But the feature cannot be certified at this point in time (Sep-2019) due to the lack of official test cases and testing tools.

During development, the Conformance Testing Tools (CTT) of the OPC Foundation are regularly applied. The CTT configuration and results are tracked at https://github.com/open62541/open62541-ctt. The OPC UA profiles under regular test in the CTT are currently:

  • Micro Embedded Device Server
  • Method Server Facet
  • Node Management Facet
  • Security Policies
    • Basic128Rsa15
    • Basic256
    • Basic256Sha256
  • User Tokens
    • Anonymous Facet
    • User Name Password Server Facet

See the page on open62541 Features for an in-depth look at the support for the conformance units that make up the OPC UA profiles.

Documentation and Support

A general introduction to OPC UA and the open62541 documentation can be found at http://open62541.org. Past releases of the library can be downloaded at https://github.com/open62541/open62541/releases.

The overall open62541 community handles public support requests on Github and the mailing list. For individual discussion and support, use the following channels:

We want to foster an open and welcoming community. Please take our code of conduct into regard.

Development

As an open source project, new contributors are encouraged to help improve open62541. The file CONTRIBUTING.md aggregates good practices that we expect for code contributions. The following are good starting points for new contributors:

For custom development that shall eventually become part of the open62541 library, please keep one of the core maintainers in the loop.

Dependencies

On most systems, open62541 requires the C standard library only. For dependencies during the build process, see the following list and the build documentation for details.

  • Core Library: The core library has no dependencies besides the C99 standard headers.
  • Default Plugins: The default plugins use the POSIX interfaces for networking and accessing the system clock. Ports to different (embedded) architectures are achieved by customizing the plugins.
  • Building and Code Generation: The build environment is generated via CMake. Some code is auto-generated from XML definitions that are part of the OPC UA standard. The code generation scripts run with both Python 2 and 3.

Note: Some (optional) features are dependent on third-party libraries. These are all listed under the deps/ folder. Depending on the selected feature set, some of these libraries will be included in the resulting library. More information on the third-party libraries can be found in the corresponding deps/README.md

Code Quality

We emphasize code quality. The following quality metrics are continuously checked and are ensured to hold before an official release is made:

  • Zero errors indicated by the Compliance Testing Tool (CTT) of the OPC Foundation for the supported features
  • Zero compiler warnings from GCC/Clang/MSVC with very strict compilation flags
  • Zero issues indicated by unit tests (more than 80% coverage)
  • Zero issues indicated by clang-analyzer, clang-tidy, cpp-check and the Codacy static code analysis tools
  • Zero unresolved issues from fuzzing the library in Google's oss-fuzz infrastructure
  • Zero issues indicated by Valgrind (Linux), DrMemory (Windows) and Clang AddressSanitizer / MemorySanitizer for the CTT tests, unit tests and fuzzing

Installation and code usage

For every release, we provide some pre-packed release packages which you can directly use in your compile infrastructure.

Have a look at the release page and the corresponding attached assets.

A more detailed explanation on how to install the open62541 SDK is given in our documentation. In essence, clone the repository and initialize all the submodules using git submodule update --init --recursive. Then use CMake to configure your build.

Furthermore we provide "pack branches" that are up-to-date with the corresponding base branches, and in addition have the git submodules in-place for a zip download. Here are some direct download links for the current pack branches:

Examples

A complete list of examples can be found in the examples directory. To build the examples, we recommend to install open62541 as mentioned in the previous section. Using the GCC compiler, just run gcc -std=c99 <server.c> -lopen62541 -o server (under Windows you may need to add additionally link against the ws2_32 socket library).

Example Server Implementation

#include <open62541/server.h>

int main(int argc, char** argv)
{
    /* Create a server listening on port 4840 (default) */
    UA_Server *server = UA_Server_new();

    /* Add a variable node to the server */

    /* 1) Define the variable attributes */
    UA_VariableAttributes attr = UA_VariableAttributes_default;
    attr.displayName = UA_LOCALIZEDTEXT("en-US", "the answer");
    UA_Int32 myInteger = 42;
    UA_Variant_setScalar(&attr.value, &myInteger, &UA_TYPES[UA_TYPES_INT32]);

    /* 2) Define where the node shall be added with which browsename */
    UA_NodeId newNodeId = UA_NODEID_STRING(1, "the.answer");
    UA_NodeId parentNodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER);
    UA_NodeId parentReferenceNodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES);
    UA_NodeId variableType = UA_NODEID_NULL; /* take the default variable type */
    UA_QualifiedName browseName = UA_QUALIFIEDNAME(1, "the answer");

    /* 3) Add the node */
    UA_Server_addVariableNode(server, newNodeId, parentNodeId,
                              parentReferenceNodeId, browseName,
                              variableType, attr, NULL, NULL);

    /* Run the server (until ctrl-c interrupt) */
    UA_StatusCode status = UA_Server_runUntilInterrupt(server);

    /* Clean up */
    UA_Server_delete(server);
    return status == UA_STATUSCODE_GOOD ? EXIT_SUCCESS : EXIT_FAILURE;
}

Example Client Implementation

#include <stdio.h>
#include <open62541/client.h>
#include <open62541/client_highlevel.h>

int main(int argc, char *argv[])
{
    /* Create a client and connect */
    UA_Client *client = UA_Client_new();
    UA_ClientConfig_setDefault(UA_Client_getConfig(client));
    UA_StatusCode status = UA_Client_connect(client, "opc.tcp://localhost:4840");
    if(status != UA_STATUSCODE_GOOD) {
        UA_Client_delete(client);
        return status;
    }

    /* Read the value attribute of the node. UA_Client_readValueAttribute is a
     * wrapper for the raw read service available as UA_Client_Service_read. */
    UA_Variant value; /* Variants can hold scalar values and arrays of any type */
    UA_Variant_init(&value);
    status = UA_Client_readValueAttribute(client, UA_NODEID_STRING(1, "the.answer"), &value);
    if(status == UA_STATUSCODE_GOOD &&
       UA_Variant_hasScalarType(&value, &UA_TYPES[UA_TYPES_INT32])) {
        printf("the value is: %i\n", *(UA_Int32*)value.data);
    }

    /* Clean up */
    UA_Variant_clear(&value);
    UA_Client_delete(client); /* Disconnects the client internally */
    return status == UA_STATUSCODE_GOOD ? EXIT_SUCCESS : EXIT_FAILURE;
}

open62541's People

Contributors

andreasebner avatar basyskom-jvoe avatar basyskom-meerkoetter avatar bleeez avatar bluhm avatar ccvca avatar ckmk14 avatar dependabot[bot] avatar florianpalm avatar goetzgoerisch avatar holgerjeromin avatar ichrispa avatar janitza-thbe avatar jansurft avatar jonasgreen88 avatar jpfr avatar jrcoding avatar keba-estr avatar markusgraube avatar martinafelberfem avatar mlang-de avatar mlgiraud avatar muddasir-shakil avatar noelgraf avatar opcua-tsn-team-kalycito avatar peter-rustler-basyskom avatar pro avatar staldert avatar stasik0 avatar uleon 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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

open62541's Issues

namespace-vtable approach and dynamic memory

@jpfr suggested to add a delete-function to the namespace-vtable approach. I've done some thinking, modeling and experimenting and feel a need to discuss the results which you can find in /tools:

  1. We need a virtual function for allocation as well or at least a function for determining the size of the newly allocated memory. I decided for the later: Calling /calcSize/ with a null-pointer shall return the size of the internal memory, calling it with a pointer to an object shall return the binary encoding size.
  2. I suggest to have both a /delete/ and a /deleteMembers/-function. The delete-function calls deleteMembers and then UA_memfree on the object itself. I think this comes in handy, when we want to keep the parent or want to have a static parent. I've implemented this schema in UA_Variant_delete, please have a look at /tools/opcua_basictypes.c
  3. We shall not mix ptrs to dynamic memory and static memory. So, all ptrs in UA_XXX-datatypes shall point to heap-memory. In particular when it comes to UA_string this is not yet coding practice. I added a function UA_String_copy and two static strings (e.g. UA_String_empty) in /tools/opcua_basictypes.c
  4. Please give some feedback if you agree with my interpretation of our coding rules ;-)

Scope stack vs scope server

Hi,

another thought after a code-review: where does the stack end and where does the server begin? At the moment the servers are the real "high-level" implementations of the user-ready SDK (just hang in your services and go). Unfortunately we have then to deal with all the possible variants in the stack (single-threaded, MT, etc.). I bet, there will be more variants (e.g. memory management) and I fear the combinatoric explosion.

The second argument is the usability of the stack for a server and a client (it would be great to have an example client as well).

So, in my opinion the loops from UA_Stack, dispatcher and other stuff from #40 should be lifted up to the example layer, where we can have two different projects server and serverMT.

So from the operative perspective there will be no differences (file renames and bits of duplication), but the stack would be still really pthread-agnostic and its scope clear. Later server implementations can be lifted up to special projects without harming the stack itself.

Decode-functions not safe!!

The UA_xxx_decode functions don't consider the remaining length of the buffer.
That's bad.

If a "faulty" array is decoded with array-len > buf-len, then the decode-function will happily read over the boundary of the buffer.

Our current stack is very easy to crash remotely because of that.
If we fiddle with the compiler flags, we might not crash any more. But then, an attacker could easily use such an "overlength" array to see RAM that he is not supposed to see.

So an attacker could possibly access goodies like certificates, connection nonces for symmetric encryption, a.s.o.

TL_send is not threadsafe - mutual access to writer

TL_send may be called from different threads in parallel:

  1. application thread (events, monitors)
  2. reader thread (response)
    The shared resource is the writer - on a per connection basis. Therefore we might want to introduce a write_lock, i.e. a mutex or queue for each TL_connection. In pseudo code:
P(c->write_lock);
c->writer(msg);
V(c->write_lock);

Test strategy

Currently we have only one test suite.

Should we split this suite into multiple? Is the effort worth it?

Are more tests than unit-tests planned?

naming conventions

While mostly the naming conventions seem to be quite straight forward, I'm sometimes a little bit confused and I feel the need to discuss:

  1. We use prefixes like SL (security layer), TL (transport layer), UA (UA basic data types), UA_AD (advanced data type). While the distinction between TL/SL is quite clear I did not grasp when to choose AD - everything that's not defined as basic data type in Part ?4?

  2. prefix and name are concatenated with an underscore. Well mostly. Why not with UAByteString_calcSize a.s.o?

  3. we use CamelCase

  4. Data types start with capital letters (after prefix)

  5. instances and methods start with lowercase letters (after prefix)

  6. we do not tell that a variable or element of a structure is a pointer (eg. as in ptrAdditionalHeader or pDiagnosticInfo). Personally I like this style very much, but your mileage may vary.

  7. enums, constants and defines are all capital.

  8. we prefer symbolic names to coded values, don't we. Well, obviously not in all code, in particular not in testing. Is there a hidden reason?

  9. we prefer to reuse methods such as UAString_calcSize to writing down the formulas and exceptions over and over. Do we really?

Of course there are more conventions I just did not see or cannot remember. I'd be happy to end up with a coding style guide which I could simply apply to my own work and hand over to my students. What do you think?

feature freeze + refactoring

I would suggest to pause the "feature development" and

  • start with refactoring regarding coding conventions (encoding/decoding and size calculation auto generated-code from uleon can then easily be integrated)
  • rename/restructure the source files
  • rework the tests,
  • clear up source code: remove not needed functions

any further points?

memory check

UA_alloc keeps the last allocated address in a globally accessible variable. This provides limited checking-abilities while being dangerous as well.
We should replace this with a smarted solution, e.g. a ring buffer with a ro-accessfunction from outside the module.

SL_processMessage: OpenSecureChannelRequest - Response

Es gibt sicher schon Vorstellungen, wie und wo der Response an den Client zusammen gebaut und geschrieben werden soll, oder? Wer ist da gerade dran? Soll das in SL_receive passieren oder in SL_processMessage? Muss die Response-Funktion über die Layer verteilt werden?

ChannelSecurityToken, revisedLifetime

The definitions in the xml file differs from the one described in part 6 ( 6.6.4,Table 34), which is needed to encode the OpenSecureChannelResponse. One is signed the other not. We need the signed one. Any Suggestions?

UA_Variant_copy needed

To answer a readrequest we currently copy the node from addressspace to the respone

    UA_VariableNode * vn = (UA_VariableNode*) node;
    v->value = vn->value; 

Delete will be called later on on on all the members of v, so essentially
the nodes's data stored in vn->value->data will be deleted when we delete v.
We would need something like a deep copy function just as we have it for the strings

    UA_Variant_copy(UA_Variant* src, UA_Variant* dst);

check 9.12

Hallo,
ich habe gestern zu check 0.9.12 geupdatet (autoconfigure.ac ist angepasst). Der Update Grund: check 0.9.12 ermöglicht testen von unsigned integers.

ExtensionObject as BaseType

the stack currently assumes that ExtensionObjects strictly follow the structure given in 62541-6 Table 13:

/* ExtensionObjectBinaryEncoding - Part: 6, Chapter: 5.2.2.15, Page: 21 */
typedef struct T_UA_ExtensionObject {
    UA_NodeId typeId;
    UA_Byte encoding; 
    UA_ByteString body;
} UA_ExtensionObject;

Unfortunately the story it is a little bit more complicated, 62541-6 tells us that the "[...] length may be omitted for any DataTypeEncoding defined in this
document (See Annex A). The length shall be specified for all user defined types."

In fact all the response/request-headers are defined as ExtensionObjects. The binaryEncodings skip both encoding and body.length, that is for any request we will see a message structured like

    UA_NodeId typeId;
    UA_RequestHeader request; 
    ....

I assume this is true for any data type that has ExtensionObject as BaseType and resides in namespace zero, eg Node, Argument, EndPointDescription a.s.o.. Some more investigation needed.

opcua_namespace.c breaks build

opcua_namespace.c: In function 'delete':
opcua_namespace.c:242:1: warning: ISO C forbids nested functions [-Wpedantic]
 static hash_t hash_string (const UA_Byte * data, UA_Int32 len) {
 ^
opcua_namespace.c:242:15: error: invalid storage class for function 'hash_string'
 static hash_t hash_string (const UA_Byte * data, UA_Int32 len) {
               ^
opcua_namespace.c:288:1: warning: ISO C forbids nested functions [-Wpedantic]
 static hash_t hash(const UA_NodeId *n) {
 ^
opcua_namespace.c:288:15: error: invalid storage class for function 'hash'
 static hash_t hash(const UA_NodeId *n) {
               ^
opcua_namespace.c:307:1: warning: ISO C forbids nested functions [-Wpedantic]
 static unsigned int higher_prime_index (unsigned long n) {
 ^
opcua_namespace.c:307:21: error: invalid storage class for function 'higher_prime_index'
 static unsigned int higher_prime_index (unsigned long n) {
                     ^
opcua_namespace.c:327:1: warning: ISO C forbids nested functions [-Wpedantic]
 static inline hash_t mod_1 (hash_t x, hash_t y, hash_t inv, int shift) {
 ^
opcua_namespace.c:327:22: error: invalid storage class for function 'mod_1'
 static inline hash_t mod_1 (hash_t x, hash_t y, hash_t inv, int shift) {
                      ^
opcua_namespace.c:346:1: warning: ISO C forbids nested functions [-Wpedantic]
 static inline hash_t mod (hash_t h, const namespace *ns) {
 ^
opcua_namespace.c:346:22: error: invalid storage class for function 'mod'
 static inline hash_t mod (hash_t h, const namespace *ns) {
                      ^
opcua_namespace.c:351:1: warning: ISO C forbids nested functions [-Wpedantic]
 static inline hash_t mod_m2 (hash_t h, const namespace *ns) {
 ^
opcua_namespace.c:351:22: error: invalid storage class for function 'mod_m2'
 static inline hash_t mod_m2 (hash_t h, const namespace *ns) {
                      ^
opcua_namespace.c:356:1: warning: ISO C forbids nested functions [-Wpedantic]
 static UA_Int32 find_slot (const namespace *ns, UA_Node **slot, UA_NodeId *nodeid) {
 ^
opcua_namespace.c:356:17: error: invalid storage class for function 'find_slot'
 static UA_Int32 find_slot (const namespace *ns, UA_Node **slot, UA_NodeId *nodeid) {
                 ^
opcua_namespace.c:391:1: warning: ISO C forbids nested functions [-Wpedantic]
 static UA_Node ** find_empty_slot(const namespace *ns, hash_t h) {
 ^
opcua_namespace.c:391:19: error: invalid storage class for function 'find_empty_slot'
 static UA_Node ** find_empty_slot(const namespace *ns, hash_t h) {
                   ^
opcua_namespace.c:418:1: warning: ISO C forbids nested functions [-Wpedantic]
 static UA_Int32 expand (namespace *ns) {
 ^
opcua_namespace.c:418:17: error: invalid storage class for function 'expand'
 static UA_Int32 expand (namespace *ns) {
                 ^
opcua_namespace.c:456:1: error: expected declaration or statement at end of input
 }
 ^
In file included from opcua_namespace.c:1:0:
opcua_namespace.c: At top level:
opcua_namespace.h:27:15: warning: 'hash' used but never defined [enabled by default]
 static hash_t hash(const UA_NodeId *n);
               ^
opcua_namespace.h:29:21: warning: 'higher_prime_index' used but never defined [enabled by default]
 static unsigned int higher_prime_index (unsigned long n);
                     ^
opcua_namespace.h:33:17: warning: 'find_slot' used but never defined [enabled by default]
 static UA_Int32 find_slot(const namespace *ns, UA_Node **slot, UA_NodeId *nodeid);
                 ^
opcua_namespace.h:34:19: warning: 'find_empty_slot' used but never defined [enabled by default]
 static UA_Node ** find_empty_slot(const namespace *ns, hash_t hash);
                   ^
opcua_namespace.h:35:17: warning: 'expand' used but never defined [enabled by default]
 static UA_Int32 expand(namespace *ns);
                 ^
make[1]: *** [opcua_namespace.lo] Error 1

i have removed the file from Makefiles, so that the project can build

exampleServers broken

@jpfr 7c41554 was a great effort towards more readable and understandable code. Unfortunately none of the example servers seem to work any more:

  • exampleServerMT - bad communication error
  • exampleServer - infinite loop in reader does not fit with select-pattern. Perhaps we might want to seperate code to have a looping & waiting reader-thread and a one-shot reader-function that could be called by select and the reader-thread
  • exampleServerACPLT - bad disconnect

specification obj == decode(encode(obj))

the specification obj == decode(encode(obj)) is to restricitve due to the fact that compilers may decide to align internally. Therefore the specification should be reformulated:

encoding(obj) == encoding(decode(encode(obj)))

Unfortunately this is specification not met by the current state of the stack, mainly because of the improper initialization of UA_Variant. 62541 specifies that there is no such thing as a NULL-Variant, NULL is handled by the unioned types themselves.

The server does not support the configured security policy 'http://opcfoundation.org/UA/SecurityPolicy#None'.

Good Saturday evening!

I do not want to be the captain obvious, but unfortunately I am a bit out of the code changes ATM (feeling a bit like http://researchinprogress.tumblr.com/post/37970807869/when-your-co-authors-dont-quite-match-your-pace-in-the).

However, when I try to connect to our server with UaExpert client, I get the following problem. As far as I see the problem may be here:

SL_processMessage - client demands signed

so is it a bug, not jet implemented or does my client lie? (I configured it to have no security and no signature)

decoder_decodeBuiltInDatatype: not endian-save when dst-size neq src-size

The decoder_decodeBuiltInDatatype-functions are not endian-save whenever the size of the destination-variable is larger than the size of the src. This issue is in particular revelant to the NodeID-Decoding.

UA_NodeID.Namespace needs to be an Uint16. Depending on the EncodingByte we will however recieve a single Byte or an Uint16. While the decode logic ensures that the correct value will be decoded, the correct assignment to the dst-variable depends on the byte order.

The single solution I can imagine is to hand over the type of the destination as well. What do you think?

UA_SecureConversationMessageHeader erroneous?

the structure of the serialized UA_SecureConversationMessageHeader is something like:

UA_Byte[3] messageType, i.e. 'OPN'
UA_ Byte isFinal, i.e. 'F'
UA_?Int32 messageSize
UA_?Int32 secureChannelID

the ?generated? encoders/decoders are quite different. Before modifying I would like to learn the rationale behind the current definition.

Binaries und Configdateien im Repo

Hallo,

ich habe gesehen, dass @uleon binaries in /bin/ und /src/.libs/ eingecheckt hat.

Herr Urbas, ist es gewollt, weil wir noch kein Build System haben oder ein versehen?
Was ist mit den ganzen Hilfsdateien von dem autotools Stack?

Eigentlich sollten weder Binaries, noch Configdateien im repo liegen. @FlorianPalm was meinst du?

New compiler flags give warnings galore

I just committed a different set of compiler flags. With the intention to ensure good code practices from the beginning. (Inspired from this: http://blog.httrack.com/blog/2014/03/09/what-are-your-gcc-flags/)

But: Piping the compiler warnings only to a file currently gives over 16,000 lines (2 to 4 lines per warning).
We should decide which compiler warnings to fix and which flags to disable completely (e.g. -pedantic is very verbose).

The warnings should guide us to possible issues. If there are too many, nobody will actually care.

Edit: Without -pedantic, there are still ~14,000 lines. Do you see what portions are in the (easy to fix) auto-generated code?

A thread-free stack

I am reviewing the changes of the recent weekend and i am worried a bit about pthreads that have become a hard dependency. Ok, there is a pthread implementation for windows, but what about embedded systems, context switching pain, predictability etc.
For our chair, I bet, our boss wants to have a loop-style single-threaded version. On the other hand there might be other async implementations based one epoll or libuv like @jpfr suggested.

How do we make different server possible without breaking the stack too much?

My suggestion would be to have different examples under "servers", instead of bringing threads and locks into the stack itself, e.g. into UA_stack.

Am I too old-fashioned?

Mid-term plans

Today I got the program of AUTOMATION 14, together with @FlorianPalm we discussed that we should aim to make a half-way working server (one reference node with time) and present it there (our chair has a stand, we can probably get a poster as "community project between RWTH and TU Dresden") to get some PR and maybe more commitment from academia/industry.

It means that we will probably give up activities regarding session management etc. in order to get something running from top to bottom.

Is it okay for everybody? @uleon: surely your chair is also at the AUTOMATION. Are you interested in this small "PR-action"?

UA_list_find - request for method with additional argument

As standard C has no lambda expressions I'm asking for a find-fct that calls a matcher with two arguments, the payload of the current element of the iterated over list and an external argument. In pseudocode

UA_list_Elem UA_list_findFirstElem(UA_list_List* l, void* p),
int (*compare)(void* p1, void* p2));

Meeting / telephone conference

To enhance our development power, e.g. reduce the merge conflicts / "solo implementation", we need to discuss some things. Here are some points I am not sure about if we have a common understanding.

Organizational part

    1. clear work item distribution / responsibilities
    • what are the current specific work items?
    • how can we integrate new developers easily?
    1. synchronizing our implicit models of implementation
  • ...

Technical part:

  • 2.1 Threading
  • 2.2. Memory Management
    • do we need real-time behaviour
    • do we need an underlying OS for memory management.
  • 2.3. Session / Secure Channel Handling
    • create a clear data structure
  • 2.4. Endpoint Handling / redirection (discovery services)
  • 2.5. Client development (generic stack)
    • use the same datastructures as in the server application?
  • 2.6. Error handling concept / framework
    • at the moment there is no real error handling
  • ...

I am sure some of these points are clear and just need to be written down (e.g. in the wiki).
Using the "issue functionality" has worked great for many cases but I think the best and fastest solution to discuss those points and many more, would be to set up a meeting or telephone conference.

Wie sind die Tests organisiert?

Hallo,

ccheck sieht ja mehrere Dateien vor in denen Suits sein können.

Haben wir da schon eine Vorstellung der Organisation?

tests do not compile

since the commit f4d28e2 compilation of tests via make check gives warnings and fails.

Errors: https://travis-ci.org/acplt/open62541/builds/20306657#L1060

check_stack.c: In function ‘test_getPacketType_validParameter’:
check_stack.c:31:2: warning: passing argument 1 of ‘TL_getPacketType’ from incompatible pointer type [enabled by default]
../src/opcua_transportLayer.h:101:7: note: expected ‘struct UA_ByteString *’ but argument is of type ‘Int32 *’
check_stack.c:31:2: warning: passing argument 2 of ‘TL_getPacketType’ from incompatible pointer type [enabled by default]
../src/opcua_transportLayer.h:101:7: note: expected ‘Int32 *’ but argument is of type ‘struct AD_RawMessage *’
check_stack.c: In function ‘encodeUInt32_test’:
check_stack.c:203:23: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
check_stack.c: In function ‘encodeUInt64_test’:
check_stack.c:270:23: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
check_stack.c: In function ‘encodeInt64_test’:
check_stack.c:313:23: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
check_stack.c: In function ‘encodeFloat_test’:
check_stack.c:356:14: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
check_stack.c: In function ‘encodeDouble_test’:
check_stack.c:376:14: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
check_stack.c: In function ‘extensionObject_calcSize_test’:
check_stack.c:458:17: error: ‘UA_ExtensionObject’ has no member named ‘Length’
check_stack.c: In function ‘encodeDataValue_test’:
check_stack.c:520:14: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
make[2]: *** [check_stack-check_stack.o] Error 1

Who is feeling confident to fix this?

Windows compile fails

da socket.h nicht da

make[1]: Entering directory `/c/Users/Sten/Desktop/Open62541/OPCUAServer/src'
gcc -DPACKAGE_NAME=\"OPCUAServer\" -DPACKAGE_TARNAME=\"opcuaserver\" -DPACKAGE_V
ERSION=\"1.0\" -DPACKAGE_STRING=\"OPCUAServer\ 1.0\" -DPACKAGE_BUGREPORT=\"\" -D
PACKAGE_URL=\"\" -DPACKAGE=\"opcuaserver\" -DVERSION=\"1.0\" -DHAVE_LIBM=1 -DSTD
C_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_ST
RING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_
H=1 -DHAVE_UNISTD_H=1 -DLT_OBJDIR=\".libs/\" -I.     -g -O2 -MT opcuaServer.o -M
D -MP -MF .deps/opcuaServer.Tpo -c -o opcuaServer.o opcuaServer.c
opcuaServer.c:21:24: fatal error: sys/socket.h: No such file or directory
 #include <sys/socket.h>
                        ^

Internal "API" for service implementations

Hey guys,

I love the work on the UA-types (encoding, decoding, memory mgmt). This seems to have converged quite nicely in the last weeks.

Looking at the next "sprint", I see two main topics in order to make a first meaningful connection:

  1. Finish handling of communication (connection management, session management, chunking of large messages, Security#None profile)
  2. Implement the first services building on the server's information model (stored in the namespaces)

Are these two topics separate enough to be worked on independently?

If yes, what data does the communication layer forward into the service layer?
Can it be as trivial as in this example?

// UA_ReadRequest and UA_ReadResponse are defined in the standard.
// They are directly encoded into messages.
UA_ReadResponse* ReadService(const namespace ** namespaces,
                             const UserSession * session, UA_ReadRequest * request);

generate_builtin.py: manage derived types correctly

There are a lot of derived types, for instance UA_Node is a specialisation of UA_ExtensionObject and UA_InstanceNode is a specialisation of UA_Node. This not yet covered in the c-implementation of generate_builtin.py. I will come up with a proposal after having studied 62541...

/tools/opcua.h missing

https://travis-ci.org/acplt/open62541#L1045 says:

Making all in tool

make[1]: Entering directory `/home/travis/build/acplt/open62541/tool'

gcc -DPACKAGE_NAME="OPCUAServer" -DPACKAGE_TARNAME="opcuaserver" -DPACKAGE_VERSION="1.0" -DPACKAGE_STRING="OPCUAServer\ 1.0" -DPACKAGE_BUGREPORT="" -DPACKAGE_URL="" -DPACKAGE="opcuaserver" -DVERSION="1.0" -DHAVE_LIBM=1 -DLINUX=1 -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_DLFCN_H=1 -DLT_OBJDIR=".libs/" -I. -O2 -g -MT main.o -MD -MP -MF .deps/main.Tpo -c -o main.o main.c

main.c:9:19: fatal error: opcua.h: No such file or directory

compilation terminated.

@uleon: did you forget a file?

Added Doxygen Support...

...and can be enabled by
./configure --enable-doxygen
feel free to tune the doxygen.in configuration file! The purpose was to get a little more visualization of the control flow.

CDT Anleitung

@uleon, haben Sie CDT genutzt für die Entwicklung.
War die Einrichtung einfach genug oder sollten wir in der Wiki ein Tutorial einbauen?

regarding milstones

  1. working secureChannel communication (without security atm)
  2. implementation of service interface, means we can add any operation for each service set
  3. support for session services
    ...
    n. server development: implementation of various services (read, browse...)
    any other suggestions or improvements?

UA_DiagnosticInfo and UA_AD_DiagnosticInfo

We have UA_AD_DiagnosticInfo in opcua_types.h and UA_DiagnosticInfo in opcua_builtIndatatypes.h. Certainly we might want to remove one of them, don't we?

  1. I'd like to keep the structure of UA_DiagnosticInfo (all the coding was done with this one), UA_AD_DiagnosticInfo was not used and is faulty.
  2. I'm just currious - why do we have opcua_types.h and opcua_builtInDatatypes.h - just to differentiate between Part 4 and Part 6 Datatypes?
  3. If so, would I need to refactor UA_DiagnosticInfo to UA_AD_DiagnosticInfo (see issue #14 )

Heraustrennen der Lib und des Servers

Wie gerade in #2 festgestellt, exisiteren jetzt eine opcUAServer.c Datei, die den eigentlichen Server implementiert. Sollten wir diese nicht neben und somit ganz unabhängig von dem Stack verwalten?

Vorschlag 1: "OPCUAServer" umbenennen nach "libOpen62531" und den server daneben legen.
Vorschlag 2: intern den server unter "examples" aufbewahren, oder so.

Session /Connection/SecureChannel Handling

As we do not have any handling of these types, and @jpfr wants to decouple we should discuss how we want to deal with them. As a first approach I have added a little diagram to visualize my thoughts:
connectionsecuresessionhandling
I would like to know, what you think about this structure.

namespace not working

I observed some difficulties with get_node in Service_Read. Therefore I added the following test to my branch which fails with a segment violation

UA_Int32 createNode(UA_Node** p, UA_Int16 nsid, UA_Int32 id) {
    UA_Node_new(p);
    (*p)->nodeId.encodingByte = UA_NODEIDTYPE_FOURBYTE;
    (*p)->nodeId.namespace = nsid;
    (*p)->nodeId.identifier.numeric = id;
    return UA_SUCCESS;
}

START_TEST(findNodeInNamespaceWithSingleEntry) {
    // given
    namespace *ns;
    create_ns(&ns, 512);
    UA_Node* n1; createNode(&n1,0,2253); insert_node(ns,n1);
    UA_Node* nr = UA_NULL;
    ns_lock* nl = UA_NULL;
    UA_Int32 retval;
    // when
    retval = get_node(ns,&(n1->nodeId),&nr,&nl);
    // then
    ck_assert_int_eq(retval, UA_SUCCESS);
    ck_assert_ptr_eq(nr,n1);
    // finally
    delete_ns(ns);
}
END_TEST

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.