我正在尝试构建学习 open62541,我在这里使用示例示例。
我将示例保存为 publish.c 并使用 cmake 选项编译,cmake -DUA_ENABLE_SUBSCRIPTIONS=ON -DUA_ARCHITECTURE=freertosLWIP -DUA_ENABLE_AMALGAMATION=ON -DUA_ENABLE_PUBSUB=ON -DUA_ENABLE_PUBSUB_ETH_UADP=ON ../ 编译示例后出现以下错误:
[2021-02-10 21:15:41.328 (UTC+0100)] warn/server AccessControl: Unconfigured AccessControl. Users have all permissions.
[2021-02-10 21:15:41.328 (UTC+0100)] info/server AccessControl: Anonymous login is enabled
[2021-02-10 21:15:41.328 (UTC+0100)] warn/server Username/Password configured, but no encrypting SecurityPolicy. This can leak credentials on the network.
[2021-02-10 21:15:41.328 (UTC+0100)] warn/userland AcceptAll Certificate Verification. Any remote certificate will be accepted.
[2021-02-10 21:15:41.328 (UTC+0100)] info/userland PubSub channel requested
[2021-02-10 21:15:41.328 (UTC+0100)] info/network TCP network layer listening on opc.tcp://gaurav-VirtualBox:4840
[2021-02-10 21:15:41.431 (UTC+0100)] warn/server PubSub Connection sending failed.
[2021-02-10 21:15:41.431 (UTC+0100)] error/server PubSub Publish: Could not send a NetworkMessage
[2021-02-10 21:15:41.528 (UTC+0100)] warn/server PubSub Connection sending failed.
[2021-02-10 21:15:41.528 (UTC+0100)] error/server PubSub Publish: Could not send a NetworkMessage
[2021-02-10 21:15:41.631 (UTC+0100)] warn/server PubSub Connection sending failed.
[2021-02-10 21:15:41.631 (UTC+0100)] error/server PubSub Publish: Could not send a NetworkMessage
**[2021-02-10 21:15:41.729 (UTC+0100)] warn/server PubSub Connection sending failed.
[2021-02-10 21:15:41.729 (UTC+0100)] error/server PubSub Publish: Could not send a NetworkMessage**
我将发布间隔更改为 1 秒。因此,每 1 秒后,发布者会发出消息,但不知何故我收到了这个错误:
**PubSub Connection sending failed. & error/server PubSub Publish: Could not send a NetworkMessage**
连续直到按下 ctrl-c。
谁能帮我在我的电脑上运行这个
代码看起来像这样
#include "OPCUA/open62541.h"
#include "OPCUA/opcua.h"
UA_NodeId connectionIdent, publishedDataSetIdent, writerGroupIdent,
dataSetWriterIdent;
UA_NodeId connectionIdentifier;
UA_PublishedDataSetConfig publishedDataSetConfig;
UA_DataSetWriterConfig dataSetWriterConfig;
UA_Boolean running = true;
static void
addPubSubConnection(UA_Server *server, UA_String *transportProfile,
UA_NetworkAddressUrlDataType *networkAddressUrl){
/* Details about the connection configuration and handling are located
* in the pubsub connection tutorial */
UA_PubSubConnectionConfig connectionConfig;
memset(&connectionConfig, 0, sizeof(connectionConfig));
connectionConfig.name = UA_STRING("UADP Connection 1");
connectionConfig.transportProfileUri = *transportProfile;
connectionConfig.enabled = UA_TRUE;
UA_Variant_setScalar(&connectionConfig.address, networkAddressUrl,
&UA_TYPES[UA_TYPES_NETWORKADDRESSURLDATATYPE]);
/* Changed to static publisherId from random generation to identify
* the publisher on Subscriber side */
connectionConfig.publisherId.numeric = UA_UInt32_random();
UA_KeyValuePair connectionOptions[3];
connectionOptions[0].key = UA_QUALIFIEDNAME(0, "ttl");
UA_UInt32 ttl = 10;
UA_Variant_setScalar(&connectionOptions[0].value, &ttl,
&UA_TYPES[UA_TYPES_UINT32]);
connectionOptions[1].key = UA_QUALIFIEDNAME(0, "loopback");
UA_Boolean loopback = UA_FALSE;
UA_Variant_setScalar(&connectionOptions[1].value, &loopback,
&UA_TYPES[UA_TYPES_BOOLEAN]);
connectionOptions[2].key = UA_QUALIFIEDNAME(0, "reuse");
UA_Boolean reuse = UA_TRUE;
UA_Variant_setScalar(&connectionOptions[2].value, &reuse,
&UA_TYPES[UA_TYPES_BOOLEAN]);
connectionConfig.connectionProperties = connectionOptions;
connectionConfig.connectionPropertiesSize = 3;
UA_StatusCode retval = UA_Server_addPubSubConnection(server, &connectionConfig, &connectionIdent);
if (retval == UA_STATUSCODE_GOOD) {
UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_SERVER,
"1 --> The PubSub Connection was added successfully!");
}
printf("networkAddressUrl.url : %s \n", networkAddressUrl->url.data);
printf ("Done addPubSubConnection here...\r\n");
}
static void
addPublishedDataSet(UA_Server *server) {
/* The PublishedDataSetConfig contains all necessary public
* informations for the creation of a new PublishedDataSet */
UA_PublishedDataSetConfig publishedDataSetConfig;
memset(&publishedDataSetConfig, 0, sizeof(UA_PublishedDataSetConfig));
publishedDataSetConfig.publishedDataSetType = UA_PUBSUB_DATASET_PUBLISHEDITEMS;
publishedDataSetConfig.name = UA_STRING("Demo PDS");
/* Create new PublishedDataSet based on the PublishedDataSetConfig. */
UA_AddPublishedDataSetResult result = UA_Server_addPublishedDataSet(server, &publishedDataSetConfig, &publishedDataSetIdent);
if (result.addResult == UA_STATUSCODE_GOOD){
UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_SERVER,
"2 -->The addPublishedDataSet was created successfully!");
}
printf ("Done addPublishedDataSet here...\r\n");
}
static void
addDataSetField(UA_Server *server) {
/* Add a field to the previous created PublishedDataSet */
UA_NodeId dataSetFieldIdent;
UA_DataSetFieldConfig dataSetFieldConfig;
memset(&dataSetFieldConfig, 0, sizeof(UA_DataSetFieldConfig));
dataSetFieldConfig.dataSetFieldType = UA_PUBSUB_DATASETFIELD_VARIABLE;
dataSetFieldConfig.field.variable.fieldNameAlias = UA_STRING("Server localtime");
dataSetFieldConfig.field.variable.promotedField = UA_FALSE;
dataSetFieldConfig.field.variable.publishParameters.publishedVariable =
UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_SERVERSTATUS_CURRENTTIME);
dataSetFieldConfig.field.variable.publishParameters.attributeId = UA_ATTRIBUTEID_VALUE;
UA_DataSetFieldResult result = UA_Server_addDataSetField(server, publishedDataSetIdent,
&dataSetFieldConfig, &dataSetFieldIdent);
if (result.result == UA_STATUSCODE_GOOD)
{
UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_SERVER,
"3--> The PubSub UA_Server_addDataSetField successfully!");
}
printf ("Done addDataSetField here...\r\n");
}
static void
addWriterGroup(UA_Server *server) {
/* Now we create a new WriterGroupConfig and add the group to the existing
* PubSubConnection. */
UA_WriterGroupConfig writerGroupConfig;
memset(&writerGroupConfig, 0, sizeof(UA_WriterGroupConfig));
writerGroupConfig.name = UA_STRING("Demo WriterGroup");
writerGroupConfig.publishingInterval = 1000;
writerGroupConfig.enabled = UA_FALSE;
writerGroupConfig.writerGroupId = 2234;
writerGroupConfig.encodingMimeType = UA_PUBSUB_ENCODING_UADP;
writerGroupConfig.messageSettings.encoding = UA_EXTENSIONOBJECT_DECODED;
writerGroupConfig.messageSettings.content.decoded.type = &UA_TYPES[UA_TYPES_UADPWRITERGROUPMESSAGEDATATYPE];
/* The configuration flags for the messages are encapsulated inside the
* message- and transport settings extension objects. These extension
* objects are defined by the standard. e.g.
* UadpWriterGroupMessageDataType */
UA_UadpWriterGroupMessageDataType *writerGroupMessage = UA_UadpWriterGroupMessageDataType_new();
/* Change message settings of writerGroup to send PublisherId,
* WriterGroupId in GroupHeader and DataSetWriterId in PayloadHeader
* of NetworkMessage */
writerGroupMessage->networkMessageContentMask = (UA_UadpNetworkMessageContentMask)(UA_UADPNETWORKMESSAGECONTENTMASK_PUBLISHERID |
(UA_UadpNetworkMessageContentMask)UA_UADPNETWORKMESSAGECONTENTMASK_GROUPHEADER |
(UA_UadpNetworkMessageContentMask)UA_UADPNETWORKMESSAGECONTENTMASK_WRITERGROUPID |
(UA_UadpNetworkMessageContentMask)UA_UADPNETWORKMESSAGECONTENTMASK_PAYLOADHEADER);
writerGroupConfig.messageSettings.content.decoded.data = writerGroupMessage;
UA_StatusCode retval1 = UA_Server_addWriterGroup(server, connectionIdent, &writerGroupConfig, &writerGroupIdent);
if (retval1 == UA_STATUSCODE_GOOD )
{
UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_SERVER,
"4-->The PubSub Connection UA_Server_addWriterGroup successfully!");
}
UA_StatusCode retval2 = UA_Server_setWriterGroupOperational(server, writerGroupIdent);
if (retval2 == UA_STATUSCODE_GOOD )
{
UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_SERVER,
"4.1-->The PubSub UA_Server_setWriterGroupOperational executed successfully!");
}
UA_UadpWriterGroupMessageDataType_delete(writerGroupMessage);
printf("Done addWriterGroup here...\r\n");
}
static void
addDataSetWriter(UA_Server *server) {
/* We need now a DataSetWriter within the WriterGroup. This means we must
* create a new DataSetWriterConfig and add call the addWriterGroup function. */
UA_NodeId dataSetWriterIdent;
UA_DataSetWriterConfig dataSetWriterConfig;
memset(&dataSetWriterConfig, 0, sizeof(UA_DataSetWriterConfig));
dataSetWriterConfig.name = UA_STRING("Demo DataSetWriter");
dataSetWriterConfig.dataSetWriterId = 62541;
dataSetWriterConfig.keyFrameCount = 10;
UA_StatusCode retval = UA_Server_addDataSetWriter(server, writerGroupIdent, publishedDataSetIdent,
&dataSetWriterConfig, &dataSetWriterIdent);
if (retval == UA_STATUSCODE_GOOD)
{
UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_SERVER,
"5-->The PubSub addDataSetWriter executed successfully!");
}
printf("Done addDataSetWriter here...\r\n");
}
static int opcua_call (UA_String *transportProfile,
UA_NetworkAddressUrlDataType *networkAddressUrl)
{
UA_Boolean running = true;
/* Create the Server */
UA_Server *server = UA_Server_new();
if (server != 0)
printf("Server Created Successfully...\r\n");
else
printf("Failed to create Server...\r\n");
UA_ServerConfig *config = UA_Server_getConfig(server);
UA_ServerConfig_setDefault(config);
/* Server is created now */
/* Add the PubSubTransportLayer implementation to the server config.
* The PubSubTransportLayer is a factory to create new connections
* on runtime. The UA_PubSubTransportLayer is used for all kinds of
* concrete connections e.g. UDP, MQTT, AMQP...
*/
UA_String hostname;
hostname = UA_STRING("opc.udp://224.0.0.21");
UA_ServerConfig_setCustomHostname(UA_Server_getConfig(server), hostname);
wiced_hostname_t whn;
wiced_result_t wres;
memset(&whn, 0, sizeof(whn));
wiced_network_set_hostname("myServer");
wres = wiced_network_get_hostname( &whn );
printf ("wiced_network_get_hostname returned %d\n", wres);
printf ("wiced_network_get_hostname: %s\n",whn.value );
/* Change the host name */
// UA_String hostname;
// UA_String_init(&hostname);
// hostname.length = 8;
// hostname.data = "myServer";// "opc.udp://224.0.0.23:4841/"; //224.0.0.22:4840
// printf ("Hostname is set with %s...\r\n", hostname.data);
// UA_ServerConfig_setCustomHostname(UA_Server_getConfig(server), hostname);
config->pubsubTransportLayers = (UA_PubSubTransportLayer *) UA_calloc(
2, sizeof(UA_PubSubTransportLayer));
config->pubsubTransportLayers[0] = UA_PubSubTransportLayerUDPMP();
config->pubsubTransportLayersSize++;
UA_PubSubConnectionConfig connectionConfig;
memset(&connectionConfig, 0, sizeof(connectionConfig));
connectionConfig.name = UA_STRING("UDP-UADP Connection 1");
connectionConfig.transportProfileUri = UA_STRING("http://opcfoundation.org/UA-Profile/Transport/pubsub-udp-uadp");
connectionConfig.enabled = UA_TRUE;
addPubSubConnection(server, transportProfile, networkAddressUrl);
addPublishedDataSet(server);
addDataSetField(server);
addWriterGroup(server);
addDataSetWriter(server);
UA_Server_run_startup(server);
if (!config->pubsubTransportLayers) {
UA_Server_delete(server);
return -1;
printf("Error ! \r\n");
} else
printf("Success Adding the Transport Layer... \r\n");
// UA_StatusCode retval = UA_Server_run(server, &running);
UA_Server_delete(server);
}
int opcua_pub_thread (void *arg)
{
/* Configure the transport profile and Network Address*/
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/")};
networkAddressUrl.networkInterface = UA_STRING("udp");
networkAddressUrl.url = UA_STRING("opc.udp://224.0.0.22");
/* Start the pubsub procedure*/
return opcua_call(&transportProfile, &networkAddressUrl);
}
void opcua_pub_init(void)
{
printf("OPCUA Thread Created...\r\n");
/* Create the opcua sttarting point thread */
sys_thread_new("OPCUA Start", opcua_pub_thread, NULL, 20000, WICED_DEFAULT_LIBRARY_PRIORITY);
}