diff --git a/Dockerfile b/Dockerfile index 2187042..3d166a3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,15 +1,42 @@ -ARG ARCH=armv7hf -ARG ACAP_SDK_VERSION=3.5 -ARG SDK_IMAGE=axisecp/acap-sdk -ARG BUILD_DIR=/usr/local/src/server-acap +ARG ARCH=aarch64 +ARG ACAP_SDK_VERSION=1.15 +ARG SDK_IMAGE=axisecp/acap-native-sdk +ARG BUILD_DIR=/usr/local/src +ARG ACAP_BUILD_DIR="$BUILD_DIR"/server-acap +ARG OPEN62541_VERSION=1.4.4 FROM $SDK_IMAGE:$ACAP_SDK_VERSION-$ARCH AS builder ARG BUILD_DIR -RUN DEBIAN_FRONTEND=noninteractive \ - apt-get update && \ +ARG ACAP_BUILD_DIR +ARG OPEN62541_VERSION +ENV DEBIAN_FRONTEND=noninteractive + +# Install additional build dependencies +RUN apt-get update && \ apt-get install -y --no-install-recommends \ cmake -WORKDIR "$BUILD_DIR" + +# open62541 +ARG OPEN62541_DIR="$BUILD_DIR"/open62541 +ARG OPEN62541_SRC_DIR="$OPEN62541_DIR"/open62541-$OPEN62541_VERSION +ARG OPEN62541_BUILD_DIR="$OPEN62541_DIR"/build + +WORKDIR "$OPEN62541_DIR" +SHELL ["/bin/bash", "-o", "pipefail", "-c"] +RUN curl -L https://github.com/open62541/open62541/archive/refs/tags/v$OPEN62541_VERSION.tar.gz | tar xz +WORKDIR "$OPEN62541_BUILD_DIR" +RUN . /opt/axis/acapsdk/environment-setup* && \ + cmake \ + -DCMAKE_INSTALL_PREFIX="$SDKTARGETSYSROOT"/usr \ + -DCMAKE_BUILD_TYPE=Release \ + -DBUILD_BUILD_EXAMPLES=OFF \ + -DBUILD_SHARED_LIBS=OFF \ + -DUA_ENABLE_NODEMANAGEMENT=ON \ + "$OPEN62541_SRC_DIR" +RUN make -j "$(nproc)" install + +# ACAP application +WORKDIR "$ACAP_BUILD_DIR" COPY LICENSE \ Makefile \ *.c \ @@ -20,5 +47,5 @@ RUN . /opt/axis/acapsdk/environment-setup* && \ acap-build . FROM scratch -ARG BUILD_DIR -COPY --from=builder "$BUILD_DIR"/*eap "$BUILD_DIR"/*LICENSE.txt / +ARG ACAP_BUILD_DIR +COPY --from=builder "$ACAP_BUILD_DIR"/*eap "$ACAP_BUILD_DIR"/*LICENSE.txt / diff --git a/Makefile b/Makefile index 1090360..b42e894 100644 --- a/Makefile +++ b/Makefile @@ -5,44 +5,20 @@ SRCS = $(wildcard *.c) OBJS = $(SRCS:.c=.o) STRIP ?= strip -PKGS = gio-2.0 glib-2.0 axparameter +PKGS = gio-2.0 glib-2.0 axparameter open62541 CFLAGS += $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) pkg-config --cflags $(PKGS)) LDLIBS += $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) pkg-config --libs $(PKGS)) -# open62541 -OPEN62541_VERSION = 1.2.9 -OPEN62541 = open62541-$(OPEN62541_VERSION) -OPEN62541_BUILD = $(OPEN62541)/$(CROSS_COMPILE)build - -LIBOPEN62541 = $(OPEN62541_BUILD)/bin/libopen62541.a -CFLAGS += -I $(OPEN62541)/include -I $(OPEN62541_BUILD)/src_generated -I $(OPEN62541)/arch -I $(OPEN62541)/deps -I $(OPEN62541)/plugins/include -LDLIBS += $(OPEN62541_BUILD)/bin/libopen62541.a - CFLAGS += -Wformat=2 -Wpointer-arith -Wbad-function-cast -Wstrict-prototypes -Wdisabled-optimization -Wall -Werror +LDFLAGS += -flto=auto # main targets all: $(PROG) $(STRIP) $(PROG) -$(OBJS): $(LIBOPEN62541) - $(PROG): $(OBJS) $(CC) $(CFLAGS) $(LDFLAGS) $^ $(LIBS) $(LDLIBS) -o $@ -# open62541 targets -$(OPEN62541): - curl -L https://github.com/open62541/open62541/archive/refs/tags/v$(OPEN62541_VERSION).tar.gz | tar xz - -$(OPEN62541_BUILD): $(OPEN62541) - mkdir -p $(OPEN62541_BUILD) - -$(OPEN62541_BUILD)/Makefile: | $(OPEN62541_BUILD) - cd $(OPEN62541_BUILD) && \ - cmake -j -DBUILD_SHARED_LIBS=OFF -DUA_BUILD_EXAMPLES=OFF .. - -$(LIBOPEN62541): $(OPEN62541_BUILD)/Makefile - make -j -C $(OPEN62541_BUILD) - # docker build container targets %.eap: DOCKER_BUILDKIT=1 docker build --build-arg ARCH=$(basename $@) -o type=local,dest=. "$(CURDIR)" @@ -50,11 +26,8 @@ $(LIBOPEN62541): $(OPEN62541_BUILD)/Makefile dockerbuild: armv7hf.eap aarch64.eap # clean targets -3rd-party-clean: - rm -rf $(OPEN62541_BUILD) - clean: rm -f $(PROG) *.o *.eap *LICENSE.txt pa*conf* -very-clean: clean 3rd-party-clean - rm -rf *.eap *.eap.old $(OPEN62541) eap +very-clean: clean + rm -rf *.eap *.eap.old eap diff --git a/README.md b/README.md index ef526ec..5a1830c 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,13 @@ -*Copyright (C) 2022, Axis Communications AB, Lund, Sweden. All Rights Reserved.* +*Copyright (C) 2024, Axis Communications AB, Lund, Sweden. All Rights Reserved.* # OPC UA Server ACAP -[![Build ACAPs](https://github.com/AxisCommunications/opc-ua-server-acap/actions/workflows/build.yml/badge.svg)](https://github.com/AxisCommunications/opc-ua-server-acap/actions/workflows/build.yml) +[![Build ACAP packages](https://github.com/AxisCommunications/opc-ua-server-acap/actions/workflows/build.yml/badge.svg)](https://github.com/AxisCommunications/opc-ua-server-acap/actions/workflows/build.yml) [![GitHub Super-Linter](https://github.com/AxisCommunications/opc-ua-server-acap/actions/workflows/super-linter.yml/badge.svg)](https://github.com/AxisCommunications/opc-ua-server-acap/actions/workflows/super-linter.yml) This repository contains the source code to build a small example -[ACAP version 3](https://help.axis.com/acap-3-developer-guide) -application that uses D-Bus to get +[ACAP version 4](https://axiscommunications.github.io/acap-documentation/) +(native) application that uses D-Bus to get - temperature sensor data from `com.axis.TemperatureController` - IO port states from `com.axis.IOControl.State` @@ -25,17 +25,16 @@ it actually is to integrate any Axis device in an OPC UA system. ## Build -### On developer computer with ACAP SDK installed +The build step creates `eap` (embedded application package) packages that can +then be deployed on the target Axis device e.g. via the device's web UI. -```sh -# With the environment initialized, use: -acap-build . -``` - -### Using ACAP SDK build container and Docker +*For more information about the `eap` files, their content, and other ways to +deploy, please see the documentation on how to +[Develop ACAP applications](https://axiscommunications.github.io/acap-documentation/docs/develop/).* -The handling of this is integrated in the [Makefile](Makefile), so if you have -Docker and `make` on your computer all you need to do is: +The build uses [Docker](https://www.docker.com/) and the containerized ACAP SDK. +If you have `make` on your computer the Docker commands are nicely wrapped in +the [Makefile](Makefile). All you need to do then is: ```sh make dockerbuild @@ -118,8 +117,9 @@ curl -k --anyauth -u root: \ ## Usage -Attach an OPC UA client to the port set in the ACAP. The client will then be -able to read the values (and their timestamps) from the ACAP's OPC UA server. +Attach an OPC UA client to the port set in the ACAP application. The client +will then be able to read the values (and their timestamps) from the ACAP +application's OPC UA server. > [!NOTE] > The application will also log the values in the camera's syslog. diff --git a/manifest.json b/manifest.json index 201b480..6fc8aa5 100644 --- a/manifest.json +++ b/manifest.json @@ -1,22 +1,29 @@ { - "schemaVersion": "1.3", + "schemaVersion": "1.7.0", "acapPackageConf": { "setup": { "appName": "opcuaserver", "friendlyName": "OPC UA Server", "vendor": "Axis Communications AB", "embeddedSdkVersion": "3.0", - "user": { - "username": "sdk", - "group": "sdk" - }, + "vendorUrl": "https://www.axis.com/", "runMode": "respawn", - "version": "1.2.6" + "version": "2.0.0" }, "configuration": { "paramConfig": [ {"name": "port", "type": "int:min=1024,max=65535", "default": "4840"} ] } + }, + "resources": { + "dbus": { + "requiredMethods": [ + "com.axis.IOControl.State.GetNbrPorts", + "com.axis.IOControl.State.GetState", + "com.axis.TemperatureController.GetNbrOfTemperatureSensors", + "com.axis.TemperatureController.RegisterForTemperatureChangeSignal" + ] + } } } diff --git a/opcua_open62541.c b/opcua_open62541.c index 4b7eb91..a5b335c 100644 --- a/opcua_open62541.c +++ b/opcua_open62541.c @@ -14,6 +14,7 @@ * limitations under the License. */ +#include #include #include