aboutsummaryrefslogtreecommitdiffstats
path: root/README.md
diff options
context:
space:
mode:
Diffstat (limited to 'README.md')
-rw-r--r--README.md175
1 files changed, 175 insertions, 0 deletions
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 <output_dir> <name> [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=<name>`). 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[]`).