### Basic Server Setup and Variable Creation Source: https://github.com/open62541/open62541-www/blob/main/static/doc/v1.5.3/_sources/tutorial_server_variabletype.rst.txt Initializes an OPC UA server, creates a simple integer variable, and starts the server. This is a foundational example for server-side variable management. ```c int main() { UA_Server *server = UA_Server_new(); UA_ServerConfig_setDefault(UA_Server_getConfig(server)); /* Add a variable */ UA_VariableAttributes attr = UA_VariableAttributes_default; UA_UInt32 value = 65535; attr.description = UA_LOCALIZEDTEXT("en-US", "the answer"); attr.displayName = UA_LOCALIZEDTEXT("en-US", "the answer"); attr.accessLevel = UA_ACCESSLEVELTYPE_τητα_READ | UA_ACCESSLEVELTYPE_τητα_WRITE; UA_Server_addVariableNode(server, UA_NODEID_NULL, UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER), UA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATAVARIABLETYPE), attr, UA_NODEID_NULL, UA_NODEID_NULL, &value); UA_StatusCode retval = UA_Server_run(server); UA_Server_delete(server); return retval == UA_STATUSCODE_GOOD ? 0 : -1; } ``` -------------------------------- ### Compile open62541 Example Server Source: https://github.com/open62541/open62541-www/blob/main/deps/open62541-www/static/doc/master/_sources/building.rst.txt Compiles a basic open62541 example server using GCC. Ensure the shared library is installed and the example source file is copied to the current directory. ```bash cp /path-to/examples/tutorial_server_firststeps.c . gcc -std=c99 -o server tutorial_server_firststeps.c -lopen62541 ``` -------------------------------- ### Creating Default Server Configuration in open62541 Source: https://github.com/open62541/open62541-www/blob/main/deps/open62541-www/static/doc/master/server.html Creates a server configuration with default settings as a starting point for further modifications. This is the initial step in server setup. ```c UA_ServerConfig config = UA_ServerConfig_default; ``` -------------------------------- ### Install open62541 Source: https://github.com/open62541/open62541-www/blob/main/deps/open62541-www/static/doc/master/building.html Installs the compiled open62541 library and headers to the default or specified installation directory. ```bash make install ``` -------------------------------- ### Run server with auto-generated P-256 certificate Source: https://github.com/open62541/open62541-www/blob/main/static/doc/master/_sources/ecc_security.rst.txt Starts the server_encryption example using an auto-generated NIST P-256 self-signed certificate. No external certificate files are needed for this mode. ```bash ./server_encryption --ecc ``` -------------------------------- ### Configure Nodeset Autoloading with CMake Source: https://github.com/open62541/open62541-www/blob/main/deps/open62541-www/static/doc/master/_sources/nodeset_compiler.rst.txt Example CMake call to enable building examples and automatically load specified information models. ```bash -DCMAKE_BUILD_TYPE=Debug -DUA_BUILD_EXAMPLES=ON -DUA_INFORMATION_MODEL_AUTOLOAD=DI;POWERLINK;PROFINET;MachineVision -DUA_NAMESPACE_ZERO=FULL ``` -------------------------------- ### Install build dependencies on OS X Source: https://github.com/open62541/open62541-www/blob/main/deps/open62541-www/static/doc/master/building.html Install necessary tools like CMake, Sphinx, Graphviz, and Check using Homebrew and pip for building and documentation. ```shell brew install cmake pip install sphinx pip install sphinx_rtd_theme brew install graphviz brew install check ``` -------------------------------- ### Install Build Tools on OpenBSD Source: https://github.com/open62541/open62541-www/blob/main/deps/open62541-www/static/doc/master/_sources/building.rst.txt Installs necessary build tools like gcc, python, and cmake on OpenBSD using pkg_add. ```bash pkg_add gcc python cmake ``` -------------------------------- ### Server Object Instantiation and Lifecycle Source: https://github.com/open62541/open62541-www/blob/main/deps/open62541-www/static/doc/master/tutorial_server_object.html This snippet shows the typical sequence for setting up objects, running the server, and cleaning up resources. ```c defineObjectTypes(server); addPumpObjectInstance(server, "pump2"); addPumpObjectInstance(server, "pump3"); addPumpTypeConstructor(server); addPumpObjectInstance(server, "pump4"); addPumpObjectInstance(server, "pump5"); UA_Server_runUntilInterrupt(server); UA_Server_delete(server); return 0; } ``` -------------------------------- ### Server Configuration Initialization Example Source: https://github.com/open62541/open62541-www/blob/main/static/doc/master/server.html Demonstrates the typical usage pattern for creating, modifying, and instantiating a server with a configuration. The configuration memory is cleaned up after server shutdown. ```c /* 1. Create a server configuration with default settings as a starting point UA_ServerConfig config = UA_ServerConfig_standard(); // 2. Modifiy the configuration, e.g. by adding a server certificate // ... // 3. Instantiate a server with it UA_Server *server; UA_StatusCode retval = UA_Server_new(&server, &config); if (retval != UA_STATUSCODE_GOOD) { // handle error } // ... server run ... // 4. After shutdown of the server, clean up the configuration (free memory) UA_Server_delete(server); UA_ServerConfig_clear(&config); */ ``` -------------------------------- ### Set Up Server Environment with Condition Callbacks Source: https://github.com/open62541/open62541-www/blob/main/deps/open62541-www/static/doc/master/tutorial_server_alarms_conditions.html Initializes the server environment and adds condition instances with user-specific callbacks for various state transitions. Ensure condition instances and sources are properly defined before use. ```c static UA_StatusCode setUpEnvironment(UA_Server *server) { UA_NodeId variable_1; UA_NodeId variable_2; UA_NodeId variable_3; UA_ValueCallback callback; callback.onRead = NULL; /* Exposed condition 1. We will add to it user specific callbacks when * entering enabled state, when acknowledging and when confirming. */ UA_StatusCode retval = addCondition_1(server); if(retval != UA_STATUSCODE_GOOD) { UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, "adding condition 1 failed. StatusCode %s", UA_StatusCode_name(retval)); return retval; } UA_TwoStateVariableChangeCallback userSpecificCallback = enteringEnabledStateCallback; retval = UA_Server_setConditionTwoStateVariableCallback(server, conditionInstance_1, conditionSource, false, userSpecificCallback, UA_ENTERING_ENABLEDSTATE); if(retval != UA_STATUSCODE_GOOD) { UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, "adding entering enabled state callback failed. StatusCode %s", UA_StatusCode_name(retval)); return retval; } userSpecificCallback = enteringAckedStateCallback; retval = UA_Server_setConditionTwoStateVariableCallback(server, conditionInstance_1, conditionSource, false, userSpecificCallback, UA_ENTERING_ACKEDSTATE); if(retval != UA_STATUSCODE_GOOD) { UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, "adding entering acked state callback failed. StatusCode %s", UA_StatusCode_name(retval)); return retval; } userSpecificCallback = enteringConfirmedStateCallback; retval = UA_Server_setConditionTwoStateVariableCallback(server, conditionInstance_1, conditionSource, false, userSpecificCallback, UA_ENTERING_CONFIRMEDSTATE); if(retval != UA_STATUSCODE_GOOD) { UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, "adding entering confirmed state callback failed. StatusCode %s", UA_StatusCode_name(retval)); return retval; } return retval; } ``` -------------------------------- ### Get Server Configuration Source: https://github.com/open62541/open62541-www/blob/main/static/doc/master/server.html Retrieves the current configuration of the UA server. No setup is required. ```c UA_Server_getConfig(UA_Server *server); ``` -------------------------------- ### Basic Server Setup with Custom Namespace Source: https://github.com/open62541/open62541-www/blob/main/static/doc/master/_sources/nodeset_compiler.rst.txt Includes the generated custom namespace header and calls the initialization function after creating the server instance. Requires compiling the stack with UA_NAMESPACE_ZERO=FULL. ```c /* This work is licensed under a Creative Commons CCZero 1.0 Universal License. * See http://creativecommons.org/publicdomain/zero/1.0/ for more information. */ #include #include #include "open62541.h" /* Files myNS.h and myNS.c are created from myNS.xml */ #include "myNS.h" UA_Boolean running = true; static void stopHandler(int sign) { UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "received ctrl-c"); ``` -------------------------------- ### Create a new KeyValueMap Source: https://github.com/open62541/open62541-www/blob/main/static/doc/v1.5.3/util.html Initializes a new, empty KeyValueMap. Use this to start storing key-value pairs. ```c UA_KeyValueMap_new(void); ``` -------------------------------- ### Create a New Server Instance Source: https://github.com/open62541/open62541-www/blob/main/deps/open62541-www/static/doc/master/server.html Creates a new server with a default configuration. This configuration includes essential plugins for networking, security, and logging. The default setup serves as a foundation for customization. ```c /* Create a new server with a default configuration that adds plugins for * networking, security, logging and so on. See the "server_config_default.h" * for more detailed options. * * The default configuration can be used as the starting point to adjust the * server configuration to individual needs. UA_Server_new is implemented in the * /plugins folder under the CC0 license. Furthermore the server confiugration * only uses the public server API. * * Returns the configured server or NULL if an error occurs. */ UA_Server * UA_Server_new(void); ``` -------------------------------- ### UA_Client_findServersOnNetwork Source: https://github.com/open62541/open62541-www/blob/main/static/doc/master/_sources/client.rst.txt Gets a list of all known servers in the network. This function is only supported by LDS (Local Discovery Server) servers and allows filtering by starting record ID, maximum records to return, and server capabilities. ```APIDOC ## UA_Client_findServersOnNetwork ### Description Gets a list of all known servers in the network. This function is only supported by LDS (Local Discovery Server) servers and allows filtering by starting record ID, maximum records to return, and server capabilities. ### Function Signature ```c UA_StatusCode UA_THREADSAFE UA_Client_findServersOnNetwork(UA_Client *client, const char *serverUrl, UA_UInt32 startingRecordId, UA_UInt32 maxRecordsToReturn, size_t serverCapabilityFilterSize, UA_String *serverCapabilityFilter, size_t *serverOnNetworkSize, UA_ServerOnNetwork **serverOnNetwork); ``` ### Parameters #### Path Parameters - **client** (UA_Client *) - A pointer to the client object. Must be connected to the same endpoint given in serverUrl or otherwise in a disconnected state. - **serverUrl** (const char *) - The URL of the LDS server to query (e.g., "opc.tcp://localhost:4840"). #### Query Parameters - **startingRecordId** (UA_UInt32) - Optional. Only return records with an ID higher than or equal to the given ID. Useful for pagination. - **maxRecordsToReturn** (UA_UInt32) - Optional. The maximum number of records to return. - **serverCapabilityFilter** (UA_String *) - Optional filter for server capabilities (e.g., "LDS"). `serverCapabilityFilterSize` indicates the number of capabilities in the array. #### Request Body None ### Response #### Success Response - **serverOnNetworkSize** (size_t*) - A pointer to a size_t variable that will be populated with the number of known/registered servers found. - **serverOnNetwork** (UA_ServerOnNetwork **) - A pointer to an array of UA_ServerOnNetwork structures containing the known servers. #### Response Example (No specific example provided in source, but would typically be an array of server on network descriptions) ### Error Handling - Returns UA_StatusCode indicating success or failure. ``` -------------------------------- ### Create and Manage Server Instance Source: https://github.com/open62541/open62541-www/blob/main/static/doc/master/_sources/server.rst.txt Provides functions for creating a new server with default or custom configuration, deleting it, retrieving its configuration, and checking its lifecycle state. Use UA_Server_new for a default setup or UA_Server_newWithConfig for custom configurations. ```c /* Create a new server with a default configuration that adds plugins for * networking, security, logging and so on. See the "server_config_default.h" * for more detailed options. * * The default configuration can be used as the starting point to adjust the * server configuration to individual needs. UA_Server_new is implemented in the * /plugins folder under the CC0 license. Furthermore the server confiugration * only uses the public server API. * * Returns the configured server or NULL if an error occurs. */ UA_Server * UA_Server_new(void); /* Creates a new server. Moves the config into the server with a shallow copy. * The config content is cleared together with the server. */ UA_Server * UA_Server_newWithConfig(UA_ServerConfig *config); /* Delete the server and its configuration */ UA_StatusCode UA_Server_delete(UA_Server *server); /* Get the configuration. Always succeeds as this simplfy resolves a pointer. * Attention! Do not adjust the configuration while the server is running! */ UA_ServerConfig * UA_Server_getConfig(UA_Server *server); /* Get the current server lifecycle state */ UA_LifecycleState UA_Server_getLifecycleState(UA_Server *server); ``` -------------------------------- ### Main Server Initialization and Run Source: https://github.com/open62541/open62541-www/blob/main/deps/open62541-www/static/doc/master/_sources/tutorial_server_datasource.rst.txt Initializes the open62541 server and registers the custom variables, including the data source variable. The server then runs until interrupted. ```c int main(void) { UA_Server *server = UA_Server_new(); addCurrentTimeVariable(server); addValueCallbackToCurrentTimeVariable(server); addCurrentTimeDataSourceVariable(server); UA_Server_runUntilInterrupt(server); UA_Server_delete(server); return 0; } ``` -------------------------------- ### Example Nodeset XML Snippet Source: https://github.com/open62541/open62541-www/blob/main/deps/open62541-www/static/doc/master/nodeset_compiler.html This XML snippet defines a custom reference type 'providesInputTo' and an abstract object type 'FieldDevice' with two variable components, 'ManufacturerName' and 'ModelName'. It serves as a starting point for demonstrating the nodeset compilation process. ```xml http://yourorganisation.org/example_nodeset/ i=1 i=7 i=12 i=37 i=40 i=45 i=46 i=47 i=296 providesInputTo i=33 inputProcidedBy FieldDevice i=58 ns=1;i=6001 ns=1;i=6002 ManufacturerName i=63 i=78 ns=1;i=1001 ModelName i=63 i=78 ns=1;i=1001 ``` -------------------------------- ### Define and Add Hello World Method Source: https://github.com/open62541/open62541-www/blob/main/deps/open62541-www/static/doc/master/tutorial_server_method.html Defines the arguments and attributes for a simple 'Hello World' method and adds it to the server. This method takes no input and returns a string. ```c static UA_StatusCode helloWorldMethodCallback(UA_Server *server, const UA_NodeId *sessionId, void *sessionContext, const UA_NodeId *methodId, void *methodContext, const UA_NodeId *objectId, void *objectContext, size_t inputSize, const UA_Variant *input, size_t outputSize, UA_Variant *output) { UA_String *out = UA_malloc(sizeof(UA_String)); out->data = (UA_Byte *)"Hello World"; out->length = (UA_Byte)strlen((char *)out->data); output[0].variantType = UA_TYPES[UA_TYPES_STRING].typeId; output[0].data = out; return UA_STATUSCODE_GOOD; } static void addHelloWorldMethod(UA_Server *server) { UA_Argument inputArgument; UA_Argument_init(&inputArgument); inputArgument.description = UA_LOCALIZEDTEXT("en-US", "no input"); inputArgument.name = UA_STRING("input"); inputArgument.dataType = UA_TYPES[UA_TYPES_STRING].typeId; inputArgument.valueRank = UA_VALUERANK_SCALAR; UA_Argument outputArgument; UA_Argument_init(&outputArgument); outputArgument.description = UA_LOCALIZEDTEXT("en-US", "A String"); outputArgument.name = UA_STRING("MyOutput"); outputArgument.dataType = UA_TYPES[UA_TYPES_STRING].typeId; outputArgument.valueRank = UA_VALUERANK_SCALAR; UA_MethodAttributes helloAttr = UA_MethodAttributes_default; helloAttr.description = UA_LOCALIZEDTEXT("en-US","Say `Hello World`"); helloAttr.displayName = UA_LOCALIZEDTEXT("en-US","Hello World"); helloAttr.executable = true; helloAttr.userExecutable = true; UA_Server_addMethodNode(server, UA_NODEID_NUMERIC(1,62541), UA_NS0ID(OBJECTSFOLDER), UA_NS0ID(HASCOMPONENT), UA_QUALIFIEDNAME(1, "hello world"), helloAttr, &helloWorldMethodCallback, 1, &inputArgument, 1, &outputArgument, NULL, NULL); } ``` -------------------------------- ### Format GUID String Source: https://github.com/open62541/open62541-www/blob/main/static/doc/v1.5.3/util.html Defines a printf format string for GUIDs and a macro to extract GUID data for printing. ```c #define UA_PRINTF_GUID_FORMAT \ "%08" PRIx32 "-%04" PRIx16 "-%04" PRIx16 "-%02" PRIx8 "%02" PRIx8 \ "-%02" PRIx8 "%02" PRIx8 "%02" PRIx8 "%02" PRIx8 "%02" PRIx8 "%02" PRIx8 #define UA_PRINTF_GUID_DATA(GUID) (GUID).data1, (GUID).data2, (GUID).data3, \ (GUID).data4[0], (GUID).data4[1], (GUID).data4[2], (GUID).data4[3], \ (GUID).data4[4], (GUID).data4[5], (GUID).data4[6], (GUID).data4[7] ``` -------------------------------- ### Create ExpandedNodeId from GUID Identifier Source: https://github.com/open62541/open62541-www/blob/main/static/doc/v1.5.3/_sources/types.rst.txt Creates an ExpandedNodeId using a namespace index and a GUID. This is suitable for nodes identified by a GUID. ```c UA_ExpandedNodeId UA_EXPANDEDNODEID_STRING_GUID(UA_UInt16 nsIndex, UA_Guid guid); ``` -------------------------------- ### GUID Structure Definition Source: https://github.com/open62541/open62541-www/blob/main/static/doc/master/_sources/types.rst.txt Defines the structure for a 16-byte GUID (Globally Unique Identifier) and declares a constant for a null GUID. ```c typedef struct { UA_UInt32 data1; UA_UInt16 data2; UA_UInt16 data3; UA_Byte data4[8]; } UA_Guid; extern const UA_Guid UA_GUID_NULL; /* Print a Guid in the human-readable format defined in Part 6, 5.1.3 * * Format: C496578A-0DFE-4B8F-870A-745238C6AEAE ``` -------------------------------- ### Register an EventSource Source: https://github.com/open62541/open62541-www/blob/main/deps/open62541-www/static/doc/master/_sources/plugin_eventloop.rst.txt Registers an EventSource with the EventLoop. If the EventLoop is already running, the EventSource is started immediately. Otherwise, it starts when the EventLoop starts. ```c UA_StatusCode (*registerEventSource)(UA_EventLoop *el, UA_EventSource *es); ``` -------------------------------- ### Setting Up Server Environment for Conditions Source: https://github.com/open62541/open62541-www/blob/main/deps/open62541-www/static/doc/master/_sources/tutorial_server_alarms_conditions.rst.txt Initializes the server environment by adding conditions and setting up callbacks for state transitions. This is crucial for managing alarm and condition lifecycles. ```c static UA_StatusCode setUpEnvironment(UA_Server *server) { UA_NodeId variable_1; UA_NodeId variable_2; UA_NodeId variable_3; UA_ValueCallback callback; callback.onRead = NULL; /* Exposed condition 1. We will add to it user specific callbacks when * entering enabled state, when acknowledging and when confirming. */ UA_StatusCode retval = addCondition_1(server); if(retval != UA_STATUSCODE_GOOD) { UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, "adding condition 1 failed. StatusCode %s", UA_StatusCode_name(retval)); return retval; } UA_TwoStateVariableChangeCallback userSpecificCallback = enteringEnabledStateCallback; retval = UA_Server_setConditionTwoStateVariableCallback(server, conditionInstance_1, conditionSource, false, userSpecificCallback, UA_ENTERING_ENABLEDSTATE); if(retval != UA_STATUSCODE_GOOD) { UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, "adding entering enabled state callback failed. StatusCode %s", UA_StatusCode_name(retval)); return retval; } userSpecificCallback = enteringAckedStateCallback; retval = UA_Server_setConditionTwoStateVariableCallback(server, conditionInstance_1, conditionSource, false, userSpecificCallback, UA_ENTERING_ACKEDSTATE); if(retval != UA_STATUSCODE_GOOD) { UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, "adding entering acked state callback failed. StatusCode %s", UA_StatusCode_name(retval)); return retval; } userSpecificCallback = enteringConfirmedStateCallback; retval = UA_Server_setConditionTwoStateVariableCallback(server, conditionInstance_1, conditionSource, false, userSpecificCallback, UA_ENTERING_CONFIRMEDSTATE); if(retval != UA_STATUSCODE_GOOD) { UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, "adding entering confirmed state callback failed. StatusCode %s", UA_StatusCode_name(retval)); return retval; } /* Unexposed condition 2. No user specific callbacks, so the server will * behave in a standard manner upon entering enabled state, acknowledging * and confirming. We will set Retain field to true and enable the condition * so we can receive event notifications (we cannot call enable method on * unexposed condition using a client like UaExpert or Softing). */ retval = addCondition_2(server); if(retval != UA_STATUSCODE_GOOD) { UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, "adding condition 2 failed. StatusCode %s", UA_StatusCode_name(retval)); return retval; } UA_Boolean retain = UA_TRUE; UA_Server_writeObjectProperty_scalar(server, conditionInstance_2, UA_QUALIFIEDNAME(0, "Retain"), &retain, &UA_TYPES[UA_TYPES_BOOLEAN]); UA_Variant value; UA_Boolean enabledStateId = true; UA_QualifiedName enabledStateField = UA_QUALIFIEDNAME(0,"EnabledState"); UA_QualifiedName enabledStateIdField = UA_QUALIFIEDNAME(0,"Id"); UA_Variant_setScalar(&value, &enabledStateId, &UA_TYPES[UA_TYPES_BOOLEAN]); retval = UA_Server_setConditionVariableFieldProperty(server, conditionInstance_2, &value, enabledStateField, ``` -------------------------------- ### Define and Add Hello World Method Source: https://github.com/open62541/open62541-www/blob/main/static/doc/master/tutorial_server_method.html Defines the arguments and attributes for a simple 'Hello World' method and adds it to the server. This method takes a scalar string input and returns a scalar string output. ```c static UA_StatusCode helloWorldMethodCallback(UA_Server *server, const UA_NodeId *sessionId, void *sessionContext, const UA_NodeId *methodId, void *methodContext, const UA_NodeId *objectId, void *objectContext, size_t inputSize, const UA_Variant *input, size_t outputSize, UA_Variant *output) { UA_String *inputString = (UA_String *)input[0].data; UA_String_copy(inputString, &output[0].data); return UA_STATUSCODE_GOOD; } static void addHelloWorldMethod(UA_Server *server) { UA_Argument inputArgument; UA_Argument_init(&inputArgument); inputArgument.description = UA_LOCALIZEDTEXT("en-US", "A String"); inputArgument.name = UA_STRING("MyInput"); inputArgument.dataType = UA_TYPES[UA_TYPES_STRING].typeId; inputArgument.valueRank = UA_VALUERANK_SCALAR; UA_Argument outputArgument; UA_Argument_init(&outputArgument); outputArgument.description = UA_LOCALIZEDTEXT("en-US", "A String"); outputArgument.name = UA_STRING("MyOutput"); outputArgument.dataType = UA_TYPES[UA_TYPES_STRING].typeId; outputArgument.valueRank = UA_VALUERANK_SCALAR; UA_MethodAttributes helloAttr = UA_MethodAttributes_default; helloAttr.description = UA_LOCALIZEDTEXT("en-US","Say `Hello World`"); helloAttr.displayName = UA_LOCALIZEDTEXT("en-US","Hello World"); helloAttr.executable = true; helloAttr.userExecutable = true; UA_Server_addMethodNode(server, UA_NODEID_NUMERIC(1,62541), UA_NS0ID(OBJECTSFOLDER), UA_NS0ID(HASCOMPONENT), UA_QUALIFIEDNAME(1, "hello world"), helloAttr, &helloWorldMethodCallback, 1, &inputArgument, 1, &outputArgument, NULL, NULL); } ``` -------------------------------- ### Register an EventSource with EventLoop Source: https://github.com/open62541/open62541-www/blob/main/static/doc/master/plugin_eventloop.html Registers an EventSource with the EventLoop. If the EventLoop is already running, the EventSource is started immediately. Otherwise, it starts when the EventLoop starts. ```c UA_StatusCode (*registerEventSource)(UA_EventLoop *el, UA_EventSource *es); ``` -------------------------------- ### Install open62541 OpenBSD Package Source: https://github.com/open62541/open62541-www/blob/main/deps/open62541-www/static/doc/master/_sources/building.rst.txt Installs the open62541 binary package on OpenBSD systems. ```bash pkg_add open62541 ``` -------------------------------- ### Create New Client with Custom Configuration Source: https://github.com/open62541/open62541-www/blob/main/deps/open62541-www/static/doc/master/client.html Creates a new client instance using a provided configuration. The configuration is moved into the client with a shallow copy, and its content is cleared when the client is deleted. ```c /* Creates a new client. Moves the config into the client with a shallow copy. * The config content is cleared together with the client. */ UA_Client * UA_Client_newWithConfig(const UA_ClientConfig *config); ``` -------------------------------- ### Format GUID for Printing Source: https://github.com/open62541/open62541-www/blob/main/static/doc/master/util.html Defines a format string for printing GUIDs in a standard hexadecimal representation. ```c #define UA_PRINTF_GUID_FORMAT \ "%08" PRIx32 "-%04" PRIx16 "-%04" PRIx16 "-%02" PRIx8 "%02" PRIx8 \ "-%02" PRIx8 "%02" PRIx8 "%02" PRIx8 "%02" PRIx8 "%02" PRIx8 "%02" PRIx8 ``` -------------------------------- ### Create New Client with Default Configuration Source: https://github.com/open62541/open62541-www/blob/main/deps/open62541-www/static/doc/master/client.html Creates a new client instance with a default configuration, including plugins for networking, security, and logging. This default configuration can be modified for specific needs. The function is implemented in the /plugins folder. ```c /* Create a new client with a default configuration that adds plugins for * networking, security, logging and so on. See `client_config_default.h` for * more detailed options. * * The default configuration can be used as the starting point to adjust the * client configuration to individual needs. UA_Client_new is implemented in the * /plugins folder under the CC0 license. Furthermore the client confiugration * only uses the public server API. * * @return Returns the configured client or NULL if an error occurs. */ UA_Client * UA_Client_new(void); ``` -------------------------------- ### UA_Server_addServerComponent Source: https://github.com/open62541/open62541-www/blob/main/static/doc/master/_sources/plugin_servercomponent.rst.txt Adds a ServerComponent to the server. If the server is already started, this function will also start the component. ```APIDOC ## UA_Server_addServerComponent ### Description Adds a ServerComponent to the server. Starts the component if the server is started. ### Method `UA_StatusCode UA_Server_addServerComponent(UA_Server *server, UA_ServerComponent *sc)` ### Parameters #### Path Parameters - **server** (`UA_Server *`) - The server to which the component will be added. - **sc** (`UA_ServerComponent *`) - The ServerComponent to add. ### Return Value - **UA_StatusCode** - Returns UA_SUCCESS on success, or an error code otherwise. ``` -------------------------------- ### Build Documentation Source: https://github.com/open62541/open62541-www/blob/main/deps/open62541-www/static/doc/master/building.html Compiles the project documentation into HTML or PDF formats. ```bash make doc # html documentation make doc_pdf # pdf documentation (requires LaTeX) ``` -------------------------------- ### Main Function and Argument Parsing Source: https://github.com/open62541/open62541-www/blob/main/static/doc/v1.5.3/_sources/tutorial_pubsub_publish.rst.txt Sets up the default transport profile and network address, then parses command-line arguments to configure the network address and transport profile before running the server. ```c int main(int argc, char **argv) { UA_String transportProfile = UA_STRING("http://opcfoundation.org/UA-Profile/Transport/pubsub-udp-uadp"); UA_NetworkAddressUrlDataType networkAddressUrl = {UA_STRING_NULL , UA_STRING("opc.udp://224.0.0.22:4840/")}; if (argc > 1) { if (strcmp(argv[1], "-h") == 0) { usage(argv[0]); return EXIT_SUCCESS; } else if (strncmp(argv[1], "opc.udp://", 10) == 0) { networkAddressUrl.url = UA_STRING(argv[1]); } else if (strncmp(argv[1], "opc.eth://", 10) == 0) { transportProfile = UA_STRING("http://opcfoundation.org/UA-Profile/Transport/pubsub-eth-uadp"); if (argc < 3) { printf("Error: UADP/ETH needs an interface name\n"); return EXIT_FAILURE; } networkAddressUrl.url = UA_STRING(argv[1]); } else { printf("Error: unknown URI\n"); return EXIT_FAILURE; } } if (argc > 2) { networkAddressUrl.networkInterface = UA_STRING(argv[2]); } return run(&transportProfile, &networkAddressUrl); } ``` -------------------------------- ### Install open62541 Debian PPA Source: https://github.com/open62541/open62541-www/blob/main/deps/open62541-www/static/doc/master/_sources/building.rst.txt Installs the open62541 development library from the official PPA on Debian-based systems. ```bash sudo add-apt-repository ppa:open62541-team/ppa sudo apt-get update sudo apt-get install libopen62541-1-dev ``` -------------------------------- ### Provide GUID Data for Printing Source: https://github.com/open62541/open62541-www/blob/main/static/doc/master/util.html Macro to extract and format the data components of a GUID for use with UA_PRINTF_GUID_FORMAT. ```c #define UA_PRINTF_GUID_DATA(GUID) (GUID).data1, (GUID).data2, (GUID).data3, \ (GUID).data4[0], (GUID).data4[1], (GUID).data4[2], (GUID).data4[3], \ (GUID).data4[4], (GUID).data4[5], (GUID).data4[6], (GUID).data4[7] ``` -------------------------------- ### Main Server Execution Source: https://github.com/open62541/open62541-www/blob/main/static/doc/v1.5.3/_sources/tutorial_server_alarms_conditions.rst.txt Initializes the server, sets up the environment for alarms and conditions, and runs the server until an interrupt signal is received. Finally, it cleans up server resources. ```c int main (void) { UA_Server *server = UA_Server_new(); setUpEnvironment(server); UA_Server_runUntilInterrupt(server); UA_Server_delete(server); return 0; } ``` -------------------------------- ### NodeId GUID Identifier Source: https://github.com/open62541/open62541-www/blob/main/deps/open62541-www/static/doc/master/_sources/types.rst.txt Creates a NodeId with a GUID identifier. Used for globally unique node identification. ```c UA_NodeId UA_NODEID_GUID(UA_UInt16 nsIndex, UA_Guid guid); ``` -------------------------------- ### Initialize Server with Namespaces Source: https://github.com/open62541/open62541-www/blob/main/deps/open62541-www/static/doc/master/_sources/nodeset_compiler.rst.txt C code to initialize an OPC UA server and add the DI and PLCopen namespaces. Includes error handling for namespace addition. ```c UA_Server *server = UA_Server_new(); UA_ServerConfig_setDefault(UA_Server_getConfig(server)); /* Create nodes from nodeset */ UA_StatusCode retval = ua_namespace_di(server); if(retval != UA_STATUSCODE_GOOD) { UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "Adding the DI namespace failed. Please check previous error output."); UA_Server_delete(server); return (int)UA_STATUSCODE_BADUNEXPECTEDERROR; } retval |= ua_namespace_plc(server); if(retval != UA_STATUSCODE_GOOD) { UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "Adding the PLCopen namespace failed. Please check previous error output."); UA_Server_delete(server); return (int)UA_STATUSCODE_BADUNEXPECTEDERROR; } retval = UA_Server_run(server, &running); ``` -------------------------------- ### Create Server with Custom Configuration Source: https://github.com/open62541/open62541-www/blob/main/deps/open62541-www/static/doc/master/server.html Creates a new server instance using a provided server configuration object. The configuration is moved into the server with a shallow copy, and its content will be cleared when the server is deleted. ```c /* Creates a new server. Moves the config into the server with a shallow copy. * The config content is cleared together with the server. */ UA_Server * UA_Server_newWithConfig(UA_ServerConfig *config); ``` -------------------------------- ### UA_Guid Source: https://github.com/open62541/open62541-www/blob/main/deps/open62541-www/static/doc/master/_sources/types.rst.txt Represents a Globally Unique Identifier (GUID). Provides functions for printing and parsing GUIDs in a human-readable format. ```APIDOC ## UA_Guid ### Description Represents a Globally Unique Identifier (GUID). Provides functions for printing and parsing GUIDs in a human-readable format. ### Functions * **UA_StatusCode UA_Guid_print(const UA_Guid *guid, UA_String *output);** Prints the GUID in a human-readable format. Allocates memory if the output string is empty. * **UA_StatusCode UA_Guid_parse(UA_Guid *guid, const UA_String str);** Parses a human-readable GUID string into a UA_Guid structure. * **UA_Guid UA_GUID(const char *chars);** Shorthand function to create a UA_Guid from a character string. Returns UA_GUID_NULL on failure. ``` -------------------------------- ### Build Documentation Source: https://github.com/open62541/open62541-www/blob/main/static/doc/master/building.html Compiles the project documentation into HTML or PDF formats. HTML generation requires Sphinx and a theme, while PDF requires LaTeX. ```bash # build documentation make doc # html documentation make doc_pdf # pdf documentation (requires LaTeX) ``` -------------------------------- ### Main Entry Point and Argument Parsing Source: https://github.com/open62541/open62541-www/blob/main/deps/open62541-www/static/doc/master/_sources/tutorial_pubsub_publish.rst.txt Sets up the main function for the PubSub publisher, parsing command-line arguments for transport profile and network address URL. It defaults to UDP/UADP. ```c static void usage(char *progname) { printf("usage: %s [device]\n", progname); } int main(int argc, char **argv) { UA_String transportProfile = UA_STRING("http://opcfoundation.org/UA-Profile/Transport/pubsub-udp-uadp"); UA_NetworkAddressUrlDataType networkAddressUrl = {UA_STRING_NULL , UA_STRING("opc.udp://224.0.0.22:4840/")}; if (argc > 1) { if (strcmp(argv[1], "-h") == 0) { usage(argv[0]); return EXIT_SUCCESS; } else if (strncmp(argv[1], "opc.udp://", 10) == 0) { networkAddressUrl.url = UA_STRING(argv[1]); } else if (strncmp(argv[1], "opc.eth://", 10) == 0) { transportProfile = UA_STRING("http://opcfoundation.org/UA-Profile/Transport/pubsub-eth-uadp"); if (argc < 3) { printf("Error: UADP/ETH needs an interface name\n"); return EXIT_FAILURE; } networkAddressUrl.url = UA_STRING(argv[1]); } else { printf("Error: unknown URI\n"); return EXIT_FAILURE; } } if (argc > 2) { networkAddressUrl.networkInterface = UA_STRING(argv[2]); } return run(&transportProfile, &networkAddressUrl); } ``` -------------------------------- ### Set and Get KeyValueMap Entries Source: https://github.com/open62541/open62541-www/blob/main/static/doc/master/util.html Functions for setting, getting, and removing entries in a UA_KeyValueMap. Supports deep and shallow copies of values. ```c /* Does the map contain an entry for the key? */ UA_Boolean UA_KeyValueMap_contains(const UA_KeyValueMap *map, const UA_QualifiedName key); /* Insert a copy of the value. Can reallocate the underlying array. This * invalidates pointers into the previous array. If the key exists already, the * value is overwritten (upsert semantics). */ UA_StatusCode UA_KeyValueMap_set(UA_KeyValueMap *map, const UA_QualifiedName key, const UA_Variant *value); /* The same as _set, but inserts a shallow copy of the value. Set * UA_VARIANT_DATA_NODELETE if the value should not be _cleared together with * the map. */ UA_StatusCode UA_KeyValueMap_setShallow(UA_KeyValueMap *map, const UA_QualifiedName key, UA_Variant *value); /* Helper function for scalar insertion that internally calls * `UA_KeyValueMap_set` */ UA_StatusCode UA_KeyValueMap_setScalar(UA_KeyValueMap *map, const UA_QualifiedName key, const void *p, const UA_DataType *type); UA_StatusCode UA_KeyValueMap_setScalarShallow(UA_KeyValueMap *map, const UA_QualifiedName key, void *p, const UA_DataType *type); /* Returns a pointer to the value or NULL if the key is not found */ const UA_Variant *UA_KeyValueMap_get(const UA_KeyValueMap *map, const UA_QualifiedName key); /* Returns NULL if the value for the key is not defined, not of the right * datatype or not a scalar */ const void *UA_KeyValueMap_getScalar(const UA_KeyValueMap *map, const UA_QualifiedName key, const UA_DataType *type); /* Remove a single entry. To delete the entire map, use `UA_KeyValueMap_clear`. */ UA_StatusCode UA_KeyValueMap_remove(UA_KeyValueMap *map, const UA_QualifiedName key); ``` -------------------------------- ### Server Main Function Source: https://github.com/open62541/open62541-www/blob/main/deps/open62541-www/static/doc/master/_sources/tutorial_server_alarms_conditions.rst.txt The main function initializes the server, sets up the environment for alarms and conditions, and runs the server until interrupted. This is the entry point for the server application. ```c int main (void) { UA_Server *server = UA_Server_new(); setUpEnvironment(server); UA_Server_runUntilInterrupt(server); UA_Server_delete(server); return 0; } ``` -------------------------------- ### GUID Printing Format Macros Source: https://github.com/open62541/open62541-www/blob/main/deps/open62541-www/static/doc/master/util.html Macros for formatting GUIDs for printing. UA_PRINTF_GUID_FORMAT defines the format string, and UA_PRINTF_GUID_DATA provides the arguments for the format. ```c #define UA_PRINTF_GUID_FORMAT \ "%08" PRIx32 "-%04" PRIx16 "-%04" PRIx16 "-%02" PRIx8 "%02" PRIx8 \ "-%02" PRIx8 "%02" PRIx8 "%02" PRIx8 "%02" PRIx8 "%02" PRIx8 "%02" PRIx8 #define UA_PRINTF_GUID_DATA(GUID) (GUID).data1, (GUID).data2, (GUID).data3, \ (GUID).data4[0], (GUID).data4[1], (GUID).data4[2], (GUID).data4[3], \ (GUID).data4[4], (GUID).data4[5], (GUID).data4[6], (GUID).data4[7] ``` -------------------------------- ### Add Hello World Method Source: https://github.com/open62541/open62541-www/blob/main/static/doc/v1.5.3/tutorial_server_method.html Adds a simple 'Hello World' method to the server. This method takes no arguments and returns a string. It's useful for basic method testing. ```c static UA_StatusCode helloWorldMethodCallback(UA_Server *server, const UA_NodeId *sessionId, void *sessionContext, const UA_NodeId *methodId, void *methodContext, const UA_NodeId *objectId, void *objectContext, size_t inputSize, const UA_Variant *input, size_t outputSize, UA_Variant *output) { UA_String *out = UA_malloc(sizeof(UA_String)); out->data = UA_malloc(sizeof(char) * 12); memcpy(out->data, "Hello World", 11); out->data[11] = '\0'; out->length = 11; output->data = out; output->type = &UA_TYPES[UA_TYPES_STRING]; output->isArray = UA_FALSE; return UA_STATUSCODE_GOOD; } static void addHelloWorldMethod(UA_Server *server) { UA_Argument inputArgument; UA_Argument_init(&inputArgument); inputArgument.description = UA_LOCALIZEDTEXT("en-US", "No input"); inputArgument.name = UA_STRING("InputArg"); inputArgument.dataType = UA_TYPES[UA_TYPES_STRING].typeId; inputArgument.valueRank = UA_VALUERANK_SCALAR; UA_Argument outputArgument; UA_Argument_init(&outputArgument); outputArgument.description = UA_LOCALIZEDTEXT("en-US", "A String"); outputArgument.name = UA_STRING("MyOutput"); outputArgument.dataType = UA_TYPES[UA_TYPES_STRING].typeId; outputArgument.valueRank = UA_VALUERANK_SCALAR; UA_MethodAttributes helloAttr = UA_MethodAttributes_default; helloAttr.description = UA_LOCALIZEDTEXT("en-US","Say `Hello World`"); helloAttr.displayName = UA_LOCALIZEDTEXT("en-US","Hello World"); helloAttr.executable = true; helloAttr.userExecutable = true; UA_Server_addMethodNode(server, UA_NODEID_NUMERIC(1,62541), UA_NS0ID(OBJECTSFOLDER), UA_NS0ID(HASCOMPONENT), UA_QUALIFIEDNAME(1, "hello world"), helloAttr, &helloWorldMethodCallback, 1, &inputArgument, 1, &outputArgument, NULL, NULL); } ``` -------------------------------- ### Getting Current Time with UA_DateTime Source: https://github.com/open62541/open62541-www/blob/main/static/doc/v1.5.3/types.html Provides functions to get the current time in UTC and a monotonic clock value, which is invariant to system time changes. ```c UA_DateTime UA_DateTime_now(void); UA_DateTime UA_DateTime_nowMonotonic(void); ``` -------------------------------- ### Add Node Begin and Finish Source: https://github.com/open62541/open62541-www/blob/main/static/doc/master/_sources/server.rst.txt Use UA_Server_addNode_begin to prepare a node and UA_Server_addNode_finish to complete its instantiation. Missing attributes are copied from the TypeDefinition node. ```c UA_StatusCode UA_THREADSAFE UA_Server_addNode_begin(UA_Server *server, const UA_NodeClass nodeClass, const UA_NodeId requestedNewNodeId, const UA_NodeId parentNodeId, const UA_NodeId referenceTypeId, const UA_QualifiedName browseName, const UA_NodeId typeDefinition, const void *attr, const UA_DataType *attributeType, void *nodeContext, UA_NodeId *outNewNodeId); UA_StatusCode UA_THREADSAFE UA_Server_addNode_finish(UA_Server *server, const UA_NodeId nodeId); ``` -------------------------------- ### UA_Guid Structure and Functions Source: https://github.com/open62541/open62541-www/blob/main/static/doc/master/types.html Defines the UA_Guid structure for 16-byte unique identifiers and provides functions for printing, parsing, and creating Guids. The UA_GUID_NULL constant represents an invalid Guid. ```c typedef struct { UA_UInt32 data1; UA_UInt16 data2; UA_UInt16 data3; UA_Byte data4[8]; } UA_Guid; extern const UA_Guid UA_GUID_NULL; UA_StatusCode UA_Guid_print(const UA_Guid *guid, UA_String *output); UA_StatusCode UA_Guid_parse(UA_Guid *guid, const UA_String str); UA_Guid UA_GUID(const char *chars); ``` -------------------------------- ### Main Server Execution with Monitored Item Source: https://github.com/open62541/open62541-www/blob/main/deps/open62541-www/static/doc/master/_sources/tutorial_server_monitoreditems.rst.txt Initializes the open62541 server, adds a monitored item for the current time, and then runs the server until interrupted. This demonstrates the integration of local monitoring into the server's lifecycle. ```c int main(void) { UA_Server *server = UA_Server_new(); addMonitoredItemToCurrentTimeVariable(server); UA_Server_runUntilInterrupt(server); UA_Server_delete(server); return 0; } ``` -------------------------------- ### Client Utility: Get and Set Namespace URI Source: https://github.com/open62541/open62541-www/blob/main/static/doc/master/_sources/client.rst.txt Functions to retrieve a namespace URI by its index or to get the index of a given namespace URI. The string is allocated and needs to be cleared. ```c UA_StatusCode UA_THREADSAFE UA_Client_getNamespaceUri(UA_Client *client, UA_UInt16 index, UA_String *nsUri); UA_StatusCode UA_THREADSAFE UA_Client_getNamespaceIndex(UA_Client *client, const UA_String nsUri, UA_UInt16 *outIndex); ```