Why do you think the documentation has to be specific for FreeBSD?Unfortuately there is no documentation specific for it FreeBSD
This seems appropriate: https://www.open62541.org/doc/1.3/tutorial_server_firststeps.htmlCould someone provide me an example of how I can create a open62541 server using it.
In the link you sent me there is a section that describes how to build open62541 for OpenBSDWhy do you think the documentation has to be specific for FreeBSD?
This seems appropriate: https://www.open62541.org/doc/1.3/tutorial_server_firststeps.html
There is nothing you need to build,In the link you sent me there is a section that describes how to build open62541 for OpenBSD
pkg install open62541
will install everything already.There is nothing you need to build,pkg install open62541
will install everything already.
pkg install open62541
$ gcc -std=c99 open62541.c myServer.c -o myServer
but leaving out the [B]myServer.c [/B]file because I don't where to find it or generate it
[B] [aperri@freebsd ~/open62541Learning]$ gcc -std=c99 myServer.c -o myServer [/B]
In compiling it the compiler spews out the following information
[aperri@freebsd ~/open62541Learning]$ gcc -std=c99 myServer.c -o myServer
/usr/local/bin/ld: /tmp//cc5GU1QC.o: in function `UA_ServerConfig_setMinimal':
myServer.c:(.text+0x10b): undefined reference to `UA_ServerConfig_setMinimalCustomBuffer'
/usr/local/bin/ld: /tmp//cc5GU1QC.o: in function `stopHandler':
myServer.c:(.text+0x143): undefined reference to `UA_Log_Stdout'
/usr/local/bin/ld: /tmp//cc5GU1QC.o: in function `main':
myServer.c:(.text+0x18f): undefined reference to `UA_Server_new'
/usr/local/bin/ld: myServer.c:(.text+0x19f): undefined reference to `UA_Server_getConfig'
/usr/local/bin/ld: myServer.c:(.text+0x1b8): undefined reference to `UA_Server_run'
/usr/local/bin/ld: myServer.c:(.text+0x1c7): undefined reference to `UA_Server_delete'
collect2: error: ld returned 1 exit status
It is not the protocol itself.open62541 is an open source implementation of the OPC UA communication protocol
open62541Learning
directory.open62541.h
#ifdef __FreeBSD__
#define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP
#define IPV6_DROP_MEMBERSHIP IPV6_LEAVE_GROUP
#endif
myServer.c
source they suggest is slightly off. Try this
#include "open62541.h"
#include <signal.h>
#include <stdlib.h>
static volatile UA_Boolean running = true;
static void stopHandler(int sig) {
UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, "received ctrl-c");
running = false;
}
int main(void) {
signal(SIGINT, stopHandler);
signal(SIGTERM, stopHandler);
UA_Server *server = UA_Server_new();
UA_ServerConfig_setDefault(UA_Server_getConfig(server));
UA_StatusCode retval = UA_Server_run(server, &running);
UA_Server_delete(server);
return retval == UA_STATUSCODE_GOOD ? EXIT_SUCCESS : EXIT_FAILURE;
}
clang -D __BSD_VISIBLE myServer.c open62541.c -o myServer
$ ./myServer
[2024-04-18 18:08:24.454 (UTC-0700)] info/session SecureChannel 0 | Session "Administrator" | AddNode (i=15303): No TypeDefinition. Use the default TypeDefinition for the Variable/Object
[2024-04-18 18:08:24.458 (UTC-0700)] warn/server AccessControl: Unconfigured AccessControl. Users have all permissions.
[2024-04-18 18:08:24.458 (UTC-0700)] info/server AccessControl: Anonymous login is enabled
[2024-04-18 18:08:24.458 (UTC-0700)] info/server AccessControl: x509 certificate user authentication is enabled
[2024-04-18 18:08:24.458 (UTC-0700)] warn/server Username/Password Authentication configured, but no encrypting SecurityPolicy. This can leak credentials on the network.
[2024-04-18 18:08:24.458 (UTC-0700)] warn/userland AcceptAll Certificate Verification. Any remote certificate will be accepted.
[2024-04-18 18:08:24.458 (UTC-0700)] info/network TCP network layer listening on opc.tcp://squeeg:4840/
^C[2024-04-18 18:08:25.672 (UTC-0700)] info/userland received ctrl-c
[2024-04-18 18:08:25.672 (UTC-0700)] info/network Shutting down the TCP network layer
[2024-04-18 18:08:25.672 (UTC-0700)] info/server PubSub cleanup was called.
Hi Jose, in an earlier thread wb7odyfred (freebsd forum participant) said downloadingTheir instructions are a little jacked.
This should yield you a working binary in the current directory.
- Download the open62541.h and open62541.c files from the release page and put them in your
open62541Learning
directory.- You'll have to add these 4 lines to
open62541.h
Code:#ifdef __FreeBSD__ #define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP #define IPV6_DROP_MEMBERSHIP IPV6_LEAVE_GROUP #endif
- The
myServer.c
source they suggest is slightly off. Try thisCode:#include "open62541.h" #include <signal.h> #include <stdlib.h> static volatile UA_Boolean running = true; static void stopHandler(int sig) { UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, "received ctrl-c"); running = false; } int main(void) { signal(SIGINT, stopHandler); signal(SIGTERM, stopHandler); UA_Server *server = UA_Server_new(); UA_ServerConfig_setDefault(UA_Server_getConfig(server)); UA_StatusCode retval = UA_Server_run(server, &running); UA_Server_delete(server); return retval == UA_STATUSCODE_GOOD ? EXIT_SUCCESS : EXIT_FAILURE; }
- I don't have gcc installed, so I compiled it with clang like this
Code:clang -D __BSD_VISIBLE myServer.c open62541.c -o myServer
Code:$ ./myServer [2024-04-18 18:08:24.454 (UTC-0700)] info/session SecureChannel 0 | Session "Administrator" | AddNode (i=15303): No TypeDefinition. Use the default TypeDefinition for the Variable/Object [2024-04-18 18:08:24.458 (UTC-0700)] warn/server AccessControl: Unconfigured AccessControl. Users have all permissions. [2024-04-18 18:08:24.458 (UTC-0700)] info/server AccessControl: Anonymous login is enabled [2024-04-18 18:08:24.458 (UTC-0700)] info/server AccessControl: x509 certificate user authentication is enabled [2024-04-18 18:08:24.458 (UTC-0700)] warn/server Username/Password Authentication configured, but no encrypting SecurityPolicy. This can leak credentials on the network. [2024-04-18 18:08:24.458 (UTC-0700)] warn/userland AcceptAll Certificate Verification. Any remote certificate will be accepted. [2024-04-18 18:08:24.458 (UTC-0700)] info/network TCP network layer listening on opc.tcp://squeeg:4840/ ^C[2024-04-18 18:08:25.672 (UTC-0700)] info/userland received ctrl-c [2024-04-18 18:08:25.672 (UTC-0700)] info/network Shutting down the TCP network layer [2024-04-18 18:08:25.672 (UTC-0700)] info/server PubSub cleanup was called.
SirDice, thank you for trying to get me straight in how to start leaning about open62541, but I'm still groping in the dark. In the link you sent to compile the myServer.c example listed there assume that I have the open62541.c/.h files in the same folder I have myServer.c in. For not knowing any better I downloaded these files from the following link https://github.com/open62541/open62541/releases/tag/v1.3.6 to determine how to build my own "myServer.c" file based on the (/usr/local/include/ and /usr/local/lib/) on my computer after installing the open62541 pkg. I'm running in circles regarding this endeavor. Could you help me out with this please. I've attached the beginnings of myServer.c file showing my attempt so far.Why do you think the documentation has to be specific for FreeBSD?
This seems appropriate: https://www.open62541.org/doc/1.3/tutorial_server_firststeps.html
I suspect those open62541.c/.h files are not properly patched for FreeBSD...SirDice, thank you for trying to get me straight in how to start leaning about open62541, but I'm still groping in the dark. In the link you sent to compile the myServer.c example listed there assume that I have the open62541.c/.h files in the same folder I have myServer.c in. For not knowing any better I downloaded these files from the following link https://github.com/open62541/open62541/releases/tag/v1.3.6 to determine how to build my own "myServer.c" file based on the (/usr/local/include/ and /usr/local/lib/) on my computer after installing the open62541 pkg. I'm running in circles regarding this endeavor. Could you help me out with this please. I've attached the beginnings of myServer.c file showing my attempt so far.
% mkdir open62541
% cd open62541
% (fetch open62541.c/.h files in the same folder I have myServer.c in )
% gcc -std=c99 open62541.c myServer.c -o myServer
% (Got compilation errors, mostly related to networking)
You started this thread asking for help compiling something and that’s what has been provided.Since I installed the open62541 package for freebsd 14, shouldn't I be using these installed files, instead of installing files from some other website?
I suspect those open62541.c/.h files are not properly patched for FreeBSD...
I went through the same steps as OP (except that I compiled the port, which is at v. 1.3.7 on my system), fetched the files from the page OP linked to, created myServer.c according to instructions, but then got compilation errors, and no binary got produced...
Code:% mkdir open62541 % cd open62541 % (fetch open62541.c/.h files in the same folder I have myServer.c in ) % gcc -std=c99 open62541.c myServer.c -o myServer % (Got compilation errors, mostly related to networking)
The errors.txt file that I attached will show the compilation errors I got. There's not very many, and most are easy to fix, but some do require FreeBSD-specific knowledge of C programming...
Seems like the compiler line that you got from the instructions (linked to by SirDice ) wants those files to be in the same directory as myServer.c... When I installed the open62541 port, I ranHi astyle, if you compare the open62541.c/.h files to the (/usr/local/include/ and /usr/local/lib/) files made available through the open62541 pkg installation, you will find that there is a lot of overlap between them. So the mySever.c file should be made up from the installed files, and not the ones downloaded from https://github.com/open62541/open62541/releases/tag/v1.3.6. Could you provide a small road-map how one can go about doing this?
updatedb
as root. (On FreeBSD, it's a symlink to /usr/libexec/locate.updatedb that you have to make yourself). Doing it as root picks up ALL files on the system, so there are reasons to avoid running it as root. updatedb
as root, you should be able to use locate
to find the files in question. In my case, I discovered that the usual locations (/usr/local/include/ and /usr/local/lib/ ) actually don't have the open62541.c/.h files... Not only that, they were not present on the system at all, which is why I had to download them. make
look in the standard locations, or your can modify the include lines in myServer.c to look in the standard locations (provided the standard locations actually have the open62541.c/.h files that are needed). Or you can just go along with instructions and have those files in the same directory as myServer.c...The open62541.c/.h that you downloaded are a subset of the open62541 pkg files you install for FreeBSD.Seems like the compiler line that you got from the instructions (linked to by SirDice ) wants those files to be in the same directory as myServer.c... When I installed the open62541 port, I ranupdatedb
as root. (On FreeBSD, it's a symlink to /usr/libexec/locate.updatedb that you have to make yourself). Doing it as root picks up ALL files on the system, so there are reasons to avoid running it as root.
After thatupdatedb
as root, you should be able to uselocate
to find the files in question. In my case, I discovered that the usual locations (/usr/local/include/ and /usr/local/lib/ ) actually don't have the open62541.c/.h files... Not only that, they were not present on the system at all, which is why I had to download them.
Well, the very fact that for me, those open62541.c/.h files were NOT available in the locations where FreeBSD normally puts such files - that has me thinking that maybe the port is not that well-done. You can install the package, and FreeBSD will report it as installed, but with important files missing from the install package, compiling myServer.c is problematic, to the point that there's no output from the compiler.
But I agree, those files really should match the installed version of open62541, and be available in the package itself. Well, if you want, there's several ways to deal with it. You can write a Makefile that helpsmake
look in the standard locations, or your can modify the include lines in myServer.c to look in the standard locations (provided the standard locations actually have the open62541.c/.h files that are needed). Or you can just go along with instructions and have those files in the same directory as myServer.c...
Well, there's also the option of modifying the port itself, but then you'll need to read the FreeBSD Porter's Handbook...
If that were the case,The open62541.c/.h that you downloaded are a subset of the open62541 pkg files you install for FreeBSD.
locate
would find those files (provided you ran updatedb
beforehand). And yeah, presence of actual files is important to pay attention to when compiling, no matter the platform. Sometimes, though, an OS-specific package is not very well crafted, and trying to install it, one discovers that there are parts missing. Unfortunate, but to be expected when dealing with Open Source software.The file open62541.h or the open62541.c does NOT 'contain' header files. It will haveThe open62541.h file contains files such as /usr/local/include/open62541/config.h, /usr/local/include/open62541/types.h and so on.
# include
lines that refer to those files. Yes, there is a difference, and it is important to pay attention to it when compiling anything.$ locate config.h | grep 62541
/usr/home/user/open62541/open62541-1.3.7/include/open62541/config.h.in
/usr/home/user/open62541/open62541-1.3.7/src/pubsub/ua_pubsub_config.h
/usr/home/user/open62541/open62541-1.3.7/tests/pubsub/ethernet_config.h
/usr/local/include/open62541/config.h
/usr/ports/devel/open62541/work/.build/src_generated/open62541/config.h
/usr/ports/devel/open62541/work/open62541-1.3.7/include/open62541/config.h.in
/usr/ports/devel/open62541/work/open62541-1.3.7/src/pubsub/ua_pubsub_config.h
/usr/ports/devel/open62541/work/open62541-1.3.7/tests/pubsub/ethernet_config.h
/usr/ports/devel/open62541/work/stage/usr/local/include/open62541/config.h
Please don't start multiple threads on the same subject. (Thanks to SirDice for merging them.)Hi Jose, in an earlier thread wb7odyfred (freebsd forum participant) said downloading
I find what that tutorial asks you to do to be really confusing. On the one hand they instruct you to download the "amalgamated" release file (open62541.c), but also mention that you'll wind up with the open62541.h file in your work directory.So based on that information I was convinced I had all the include files to run the myServer.c as stated in the https://www.open62541.org/doc/1.3/tutorial_server_firststeps.html. However you pointed out that I need to download the open62541.h and open62541.c files from the release page and put them into my open62541Learning directory.
To get started, downdload the open62541 single-file release from http://open62541.org or generate it according to the build instructions with the “amalgamation” option enabled. From now on, we assume you have the open62541.c/.h files in the current folder.
#include <open62541/plugin/log_stdout.h>
#include <open62541/server.h>
#include <open62541/server_config_default.h>
__BSD_VISIBLE
on the command line.#ifdef __FreeBSD__
#define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP
#define IPV6_DROP_MEMBERSHIP IPV6_LEAVE_GROUP
#endif
gcc -std=c99 open62541.c myServer.c -o myServer
#include "open62541.h"
#include <signal.h>
#include <stdlib.h>
static volatile UA_Boolean running = true;
static void stopHandler(int sig) {
UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, "received ctrl-c");
running = false;
}
int main(void) {
signal(SIGINT, stopHandler);
signal(SIGTERM, stopHandler);
UA_Server *server = UA_Server_new();
UA_ServerConfig_setDefault(UA_Server_getConfig(server));
UA_StatusCode retval = UA_Server_run(server, &running);
UA_Server_delete(server);
return retval == UA_STATUSCODE_GOOD ? EXIT_SUCCESS : EXIT_FAILURE;
}
^ This one should be easy to correct.open62541.c: In function 'UA_PubSubChannelUDPMC_unregist': open62541.c:80750:2: error: #endif without #if 80750 | #endif
Hi astyle,^ This one should be easy to correct.
But the rest - study the OPC-UA architecture specs and the 62541 tutorials.
static UA_StatusCode
UA_PubSubChannelUDPMC_unregist(UA_PubSubChannel *channel, UA_ExtensionObject *transportSettings) {
if(!(channel->state == UA_PUBSUB_CHANNEL_PUB_SUB || channel->state == UA_PUBSUB_CHANNEL_SUB)){
UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "PubSub Connection unregist failed.");
return UA_STATUSCODE_BADINTERNALERROR;
}
UA_PubSubChannelDataUDPMC * connectionConfig = (UA_PubSubChannelDataUDPMC *) channel->handle;
if(connectionConfig->ai_family == PF_INET){//IPv4 handling
struct ip_mreq groupV4 = { 0 };
memcpy(&groupV4.imr_multiaddr,
&((const struct sockaddr_in *) &connectionConfig->ai_addr)->sin_addr,
sizeof(struct in_addr));
groupV4.imr_interface.s_addr = UA_htonl(INADDR_ANY);
if(UA_setsockopt(channel->sockfd, IPPROTO_IP, IP_DROP_MEMBERSHIP,
(char *) &groupV4, sizeof(groupV4)) != 0){
UA_LOG_SOCKET_ERRNO_WRAP(
UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_NETWORK,
"PubSub Connection unregist failed. IP membership setup failed: "
"Cannot set socket option IP_DROP_MEMBERSHIP. Error: %s",
errno_str));
return UA_STATUSCODE_BADINTERNALERROR;
}
#if UA_IPV6
} else if (connectionConfig->ai_family == PF_INET6) {//IPv6 handling
struct ipv6_mreq groupV6 = { 0 };
memcpy(&groupV6.ipv6mr_multiaddr,
&((const struct sockaddr_in6 *) &connectionConfig->ai_addr)->sin6_addr,
sizeof(struct in6_addr));
if(UA_setsockopt(channel->sockfd, IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP,
(char *) &groupV6, sizeof(groupV6)) != 0){
UA_LOG_SOCKET_ERRNO_WRAP(
UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_NETWORK,
"PubSub Connection unregist failed. IP membership setup failed: "
"Cannot set socket option IPV6_DROP_MEMBERSHIP. Error: %s",
errno_str));
return UA_STATUSCODE_BADINTERNALERROR;
}
#endif
} else {
UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "PubSub Connection unregist failed.");
return UA_STATUSCODE_BADINTERNALERROR;
}
return UA_STATUSCODE_GOOD;
}
static UA_StatusCode
UA_PubSubChannelUDPMC_unregist(UA_PubSubChannel *channel, UA_ExtensionObject *transportSettings) {
if(!(channel->state == UA_PUBSUB_CHANNEL_PUB_SUB || channel->state == UA_PUBSUB_CHANNEL_SUB)){
UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "PubSub Connection unregist failed.");
return UA_STATUSCODE_BADINTERNALERROR;
}
UA_PubSubChannelDataUDPMC * connectionConfig = (UA_PubSubChannelDataUDPMC *) channel->handle;
if(connectionConfig->ai_family == PF_INET){//IPv4 handling
struct ip_mreq groupV4 = { 0 };
memcpy(&groupV4.imr_multiaddr,
&((const struct sockaddr_in *) &connectionConfig->ai_addr)->sin_addr,
sizeof(struct in_addr));
groupV4.imr_interface.s_addr = UA_htonl(INADDR_ANY);
if(UA_setsockopt(channel->sockfd, IPPROTO_IP, IP_DROP_MEMBERSHIP,
(char *) &groupV4, sizeof(groupV4)) != 0){
UA_LOG_SOCKET_ERRNO_WRAP(
UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_NETWORK,
"PubSub Connection unregist failed. IP membership setup failed: "
"Cannot set socket option IP_DROP_MEMBERSHIP. Error: %s",
errno_str));
return UA_STATUSCODE_BADINTERNALERROR;
}
}
#if UA_IPV6
else if (connectionConfig->ai_family == PF_INET6) {//IPv6 handling
struct ipv6_mreq groupV6 = { 0 };
memcpy(&groupV6.ipv6mr_multiaddr,
&((const struct sockaddr_in6 *) &connectionConfig->ai_addr)->sin6_addr,
sizeof(struct in6_addr));
if(UA_setsockopt(channel->sockfd, IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP,
(char *) &groupV6, sizeof(groupV6)) != 0){
UA_LOG_SOCKET_ERRNO_WRAP(
UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_NETWORK,
"PubSub Connection unregist failed. IP membership setup failed: "
"Cannot set socket option IPV6_DROP_MEMBERSHIP. Error: %s",
errno_str));
return UA_STATUSCODE_BADINTERNALERROR;
}
}
#endif
else {
UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "PubSub Connection unregist failed.");
return UA_STATUSCODE_BADINTERNALERROR;
}
return UA_STATUSCODE_GOOD;
}