From 71bd06367ea830dd176019e0221dc516e7f07a36 Mon Sep 17 00:00:00 2001 From: Thomas Vanbesien Date: Tue, 31 Mar 2026 16:10:51 +0200 Subject: Update readme.md → README.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 175 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ readme.md | 194 -------------------------------------------------------------- 2 files changed, 175 insertions(+), 194 deletions(-) create mode 100644 README.md delete mode 100644 readme.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..bd8eb2d --- /dev/null +++ b/README.md @@ -0,0 +1,175 @@ +# BobinkCOpcUa + +A small C project that demonstrates OPC UA server discovery using the [open62541](https://www.open62541.org/) library. Three programs work together: + +- **bobink_opcua_discovery_server** — Local Discovery Server that other servers register with +- **bobink_opcua_server** — a server that periodically registers itself with the LDS +- **bobink_opcua_client** — queries the LDS for servers, lists endpoints, reads the current time, or downloads a server's certificate + +## Prerequisites + +- CMake 3.17+ +- A C11 compiler (GCC or Clang) +- OpenSSL development libraries (`libssl-dev` / `openssl-devel`) +- `openssl` CLI (for generating certificates) + +## Getting started + +Clone the repository with its submodule: + +```sh +git clone --recursive https://git.tvcloud.fr/BobinkCOpcUa +cd BobinkCOpcUa +``` + +### Certificates + +Test certificates are pre-generated and committed under each test directory (e.g. `tests/secure_anonymous/certs/`). Each secure test has per-identity subdirectories (`ServerLDS/`, `ServerRegister/`, `ServerRegisterClient/`, `Client/`) containing `cert.der` and `key.der`, plus a shared `trust/` directory with all certificates. + +Programs can also run without certificates (SecurityPolicy#None only) by omitting the `certificate`, `privateKey`, and `trustStore` keys from their config files. + +To generate new certificates, use `tools/generate_certificate.sh [uri]`. + +### Build + +```sh +cmake -B build +cmake --build build --parallel +``` + +open62541 is fetched from the submodule and built automatically — the first build takes a bit longer. + +## Running + +Start the programs in order, each in its own terminal, from the project root. Configuration files live in `tests/` (one directory per test scenario — see [Tests](#tests) below). The examples below use `tests/secure_user/`: + +```sh +# 1. Local Discovery Server +build/bobink_opcua_discovery_server tests/secure_user/server_lds.conf + +# 2. Register Server (connects to the LDS on port 14840) +build/bobink_opcua_server tests/secure_user/server_register.conf \ + tests/secure_user/server_register_client.conf opc.tcp://localhost:14840 \ + [nodes.conf] + +# 3. Find registered servers via the LDS +build/bobink_opcua_client tests/secure_user/client.conf find-servers opc.tcp://localhost:14840 + +# 4. List endpoints on the registered server +build/bobink_opcua_client tests/secure_user/client.conf get-endpoints opc.tcp://localhost:14841 + +# 5. Read the current time from the registered server +build/bobink_opcua_client tests/secure_user/client.conf read-time opc.tcp://localhost:14841 + +# 6. Download the server's certificate to a local file +build/bobink_opcua_client tests/secure_user/client.conf download-cert opc.tcp://localhost:14841 server.der +``` + +All three programs accept an optional log level as the last argument (`trace`, `debug`, `info`, `warning`, `error`, `fatal`). The default is `info`. + +## Tests + +Integration tests exercise four combinations of security and authentication: + +| Test | Security | Auth | +|----------------------|---------------------------------------|---------------------------| +| `unsecure_anonymous` | None / None | anonymous | +| `secure_anonymous` | SignAndEncrypt / Aes256_Sha256_RsaPss | anonymous | +| `secure_user` | SignAndEncrypt / Aes256_Sha256_RsaPss | user/password | +| `secure_cert` | SignAndEncrypt / Aes256_Sha256_RsaPss | X509 certificate | +| `download_cert` | SignAndEncrypt / Aes256_Sha256_RsaPss | anonymous (download-cert) | + +Run all tests: + +```sh +ctest --test-dir build --output-on-failure +``` + +### Memory leak check + +Rebuild with AddressSanitizer, run the tests, then switch back: + +```sh +# ASan build +cmake -B build \ + -DCMAKE_C_FLAGS="-fsanitize=address -fno-omit-frame-pointer" \ + -DCMAKE_EXE_LINKER_FLAGS="-fsanitize=address" +cmake --build build --parallel + +ASAN_OPTIONS="detect_leaks=1" ctest --test-dir build --output-on-failure + +# Restore normal build +cmake -B build -DCMAKE_C_FLAGS="" -DCMAKE_EXE_LINKER_FLAGS="" +cmake --build build --parallel +``` + +## Configuration + +Programs are configured through plain text files (`key = value`, one per line). See the `tests/` directories for working examples. + +Three authentication modes are supported via the `authMode` key: + +- **anonymous** — no user identity +- **user** — username and password (requires `username` and `password` keys) +- **cert** — X509 certificate identity token (reuses the application certificate; requires encryption to be configured) + +## Nodes Configuration + +`bobink_opcua_server` accepts an optional nodes config file that populates the server's address space with variable nodes. Pass it as the fourth positional argument (before the optional log level): + +```sh +build/bobink_opcua_server server.conf client.conf opc.tcp://localhost:14840 nodes.conf +``` + +The config file only declares the node structure (name, type, access level). Values are not specified in the config — the server assigns random values at startup and updates them every five seconds. This is intended for testing OPC UA monitoring and subscriptions. + +The file uses the same `key = value` format with dot-indexed keys: + +``` +node.0.name = Temperature +node.0.description = Current temperature reading +node.0.type = double +node.0.accessLevel = read + +node.1.name = DeviceName +node.1.type = string +node.1.accessLevel = readwrite + +node.2.name = Measurements +node.2.description = Recent measurements +node.2.type = double[] +node.2.accessLevel = read +``` + +Each node gets a string NodeId in namespace 1 (`ns=1;s=`). The `name` field is also used as the display name and browse name. Array nodes are created with 5 elements. + +### Fields + +| Field | Required | Description | +|---------------|----------|---------------------------------------------------------| +| `name` | yes | Display name, browse name, and string NodeId | +| `description` | no | Human-readable description | +| `type` | yes | Data type (see table below); append `[]` for a 1D array | +| `accessLevel` | yes | `read` or `readwrite` | + +### Supported Types + +| Type name | OPC UA type | +|--------------|-------------| +| `bool` | Boolean | +| `int16` | Int16 | +| `uint16` | UInt16 | +| `int32` | Int32 | +| `uint32` | UInt32 | +| `int64` | Int64 | +| `uint64` | UInt64 | +| `float` | Float | +| `double` | Double | +| `string` | String | +| `sbyte` | SByte | +| `byte` | Byte | +| `datetime` | DateTime | +| `guid` | Guid | +| `bytestring` | ByteString | + +Append `[]` to any type name for a 1D array (e.g. `double[]`, `string[]`). diff --git a/readme.md b/readme.md deleted file mode 100644 index a2c5496..0000000 --- a/readme.md +++ /dev/null @@ -1,194 +0,0 @@ -# BobinkCOpcUa - -A small C project that demonstrates OPC UA server discovery using the -[open62541](https://www.open62541.org/) library. Three programs work together: - -- **bobink_opcua_discovery_server** — Local Discovery Server that other servers register with -- **bobink_opcua_server** — a server that periodically registers itself with the LDS -- **bobink_opcua_client** — queries the LDS for servers, lists endpoints, reads the current time, or downloads a server's certificate - -## Prerequisites - -- CMake 3.17+ -- A C11 compiler (GCC or Clang) -- OpenSSL development libraries (`libssl-dev` / `openssl-devel`) -- `openssl` CLI (for generating certificates) - -## Getting started - -Clone the repository with its submodule: - -```sh -git clone --recursive https://git.tvcloud.fr/BobinkCOpcUa -cd BobinkCOpcUa -``` - -### Certificates - -Test certificates are pre-generated and committed under each test directory -(e.g. `tests/secure_anonymous/certs/`). Each secure test has per-identity -subdirectories (`ServerLDS/`, `ServerRegister/`, `ServerRegisterClient/`, -`Client/`) containing `cert.der` and `key.der`, plus a shared `trust/` -directory with all certificates. - -Programs can also run without certificates (SecurityPolicy#None only) by -omitting the `certificate`, `privateKey`, and `trustStore` keys from their -config files. - -To generate new certificates, use `tools/generate_certificate.sh [uri]`. - -### Build - -```sh -cmake -B build -cmake --build build --parallel -``` - -open62541 is fetched from the submodule and built automatically — the first -build takes a bit longer. - -## Running - -Start the programs in order, each in its own terminal, from the project root. -Configuration files live in `tests/` (one directory per test scenario — see -[Tests](#tests) below). The examples below use `tests/secure_user/`: - -```sh -# 1. Local Discovery Server -build/bobink_opcua_discovery_server tests/secure_user/server_lds.conf - -# 2. Register Server (connects to the LDS on port 14840) -build/bobink_opcua_server tests/secure_user/server_register.conf \ - tests/secure_user/server_register_client.conf opc.tcp://localhost:14840 \ - [nodes.conf] - -# 3. Find registered servers via the LDS -build/bobink_opcua_client tests/secure_user/client.conf find-servers opc.tcp://localhost:14840 - -# 4. List endpoints on the registered server -build/bobink_opcua_client tests/secure_user/client.conf get-endpoints opc.tcp://localhost:14841 - -# 5. Read the current time from the registered server -build/bobink_opcua_client tests/secure_user/client.conf read-time opc.tcp://localhost:14841 - -# 6. Download the server's certificate to a local file -build/bobink_opcua_client tests/secure_user/client.conf download-cert opc.tcp://localhost:14841 server.der -``` - -All three programs accept an optional log level as the last argument -(`trace`, `debug`, `info`, `warning`, `error`, `fatal`). The default is `info`. - -## Tests - -Integration tests exercise four combinations of security and authentication: - -| Test | Security | Auth | -|------|----------|------| -| `unsecure_anonymous` | None / None | anonymous | -| `secure_anonymous` | SignAndEncrypt / Aes256_Sha256_RsaPss | anonymous | -| `secure_user` | SignAndEncrypt / Aes256_Sha256_RsaPss | user/password | -| `secure_cert` | SignAndEncrypt / Aes256_Sha256_RsaPss | X509 certificate | -| `download_cert` | SignAndEncrypt / Aes256_Sha256_RsaPss | anonymous (download-cert) | - -Run all tests: - -```sh -ctest --test-dir build --output-on-failure -``` - -### Memory leak check - -Rebuild with AddressSanitizer, run the tests, then switch back: - -```sh -# ASan build -cmake -B build \ - -DCMAKE_C_FLAGS="-fsanitize=address -fno-omit-frame-pointer" \ - -DCMAKE_EXE_LINKER_FLAGS="-fsanitize=address" -cmake --build build --parallel - -ASAN_OPTIONS="detect_leaks=1" ctest --test-dir build --output-on-failure - -# Restore normal build -cmake -B build -DCMAKE_C_FLAGS="" -DCMAKE_EXE_LINKER_FLAGS="" -cmake --build build --parallel -``` - -## Configuration - -Programs are configured through plain text files (`key = value`, one per line). -See the `tests/` directories for working examples. - -Three authentication modes are supported via the `authMode` key: - -- **anonymous** — no user identity -- **user** — username and password (requires `username` and `password` keys) -- **cert** — X509 certificate identity token (reuses the application certificate; requires encryption to be configured) - -## Nodes Configuration - -`bobink_opcua_server` accepts an optional nodes config file that populates -the server's address space with variable nodes. Pass it as the fourth -positional argument (before the optional log level): - -```sh -build/bobink_opcua_server server.conf client.conf opc.tcp://localhost:14840 nodes.conf -``` - -The config file only declares the node structure (name, type, access level). -Values are not specified in the config — the server assigns random values at -startup and updates them every five seconds. This is intended for testing OPC UA -monitoring and subscriptions. - -The file uses the same `key = value` format with dot-indexed keys: - -``` -node.0.name = Temperature -node.0.description = Current temperature reading -node.0.type = double -node.0.accessLevel = read - -node.1.name = DeviceName -node.1.type = string -node.1.accessLevel = readwrite - -node.2.name = Measurements -node.2.description = Recent measurements -node.2.type = double[] -node.2.accessLevel = read -``` - -Each node gets a string NodeId in namespace 1 (`ns=1;s=`). The `name` -field is also used as the display name and browse name. Array nodes are -created with 5 elements. - -### Fields - -| Field | Required | Description | -|-------|----------|-------------| -| `name` | yes | Display name, browse name, and string NodeId | -| `description` | no | Human-readable description | -| `type` | yes | Data type (see table below); append `[]` for a 1D array | -| `accessLevel` | yes | `read` or `readwrite` | - -### Supported Types - -| Type name | OPC UA type | -|-----------|-------------| -| `bool` | Boolean | -| `int16` | Int16 | -| `uint16` | UInt16 | -| `int32` | Int32 | -| `uint32` | UInt32 | -| `int64` | Int64 | -| `uint64` | UInt64 | -| `float` | Float | -| `double` | Double | -| `string` | String | -| `sbyte` | SByte | -| `byte` | Byte | -| `datetime` | DateTime | -| `guid` | Guid | -| `bytestring` | ByteString | - -Append `[]` to any type name for a 1D array (e.g. `double[]`, `string[]`). -- cgit v1.2.3