Skip to content

Commit

Permalink
make the server struct opaque for userspace and
Browse files Browse the repository at this point in the history
auto-generate an array with the standard-nodeids (datatypes, referencetypes, objects) in ns0
  • Loading branch information
jpfr committed Nov 1, 2014
1 parent 88c182b commit 0d7e0e5
Show file tree
Hide file tree
Showing 31 changed files with 345 additions and 327 deletions.
42 changes: 24 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,33 +45,39 @@ void serverCallback(UA_Server *server) {
int main(int argc, char** argv) {
signal(SIGINT, stopHandler); /* catches ctrl-c */

#define PORT 16664
/* init the server */
UA_String endpointUrl;
UA_String_copyprintf("opc.tpc://127.0.0.1:%i", endpointUrl, PORT);

UA_Server server;
UA_Server_init(&server, &endpointUrl);
Logger_Stdout_init(&server.logger);
UA_String_copycstring("opc.tcp://192.168.56.101:16664",&endpointUrl);
UA_Server *server = UA_Server_new(&endpointUrl, NULL);

/* add a variable node */
UA_Int32 myInteger = 42;
UA_String myIntegerName;
UA_STRING_STATIC(myIntegerName, "The Answer");
// Adds the integer variable as a child (HasComponent) to the "Objects" node.
UA_Server_addScalarVariableNode(&server, &myIntegerName, (void*)&myInteger,
&UA_[UA_INT32], &server.objectsNodeId,
&server.hasComponentReferenceTypeId);
UA_Server_addScalarVariableNode(server,
/* The browse name, the value and the datatype's vtable*/
&myIntegerName, (void*)&myInteger, &UA_TYPES[UA_INT32],

/* The parent node to which the variable shall be attached */
&UA_NODEIDS[UA_OBJECTSFOLDER],
/* The (hierarchical) reference type from the "parent" node*/
&UA_NODEIDS[UA_HASCOMPONENT]);

NetworklayerTCP* nl;
NetworklayerTCP_new(&nl, UA_ConnectionConfig_standard, PORT);
/* attach a network layer */
#define PORT 16664
NetworklayerTCP* nl = NetworklayerTCP_new(UA_ConnectionConfig_standard, PORT);
printf("Server started, connect to to opc.tcp://127.0.0.1:%i\n", PORT);
struct timeval callback_interval = {5, 0}; // run serverCallback every 5 seconds
UA_Int32 retval = NetworkLayerTCP_run(nl, &server, callback_interval,
serverCallback, &running);
UA_Server_deleteMembers(&server);
struct timeval callback_interval = {1, 0}; // 1 second

/* run the server loop */
NetworkLayerTCP_run(nl, server, callback_interval, serverCallback, &running);

/* clean up */
NetworklayerTCP_delete(nl);
UA_Server_delete(server);
UA_String_deleteMembers(&endpointUrl);
return retval == UA_STATUSCODE_GOOD ? 0 : retval;
return 0;
}
```
Expand Down
19 changes: 9 additions & 10 deletions examples/networklayer_tcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,16 +51,15 @@ typedef struct TCPConnectionHandle {
NetworklayerTCP *layer;
} TCPConnectionHandle;

UA_StatusCode NetworklayerTCP_new(NetworklayerTCP **newlayer, UA_ConnectionConfig localConf,
UA_UInt32 port) {
*newlayer = malloc(sizeof(NetworklayerTCP));
if(*newlayer == NULL)
return UA_STATUSCODE_BADOUTOFMEMORY;
(*newlayer)->localConf = localConf;
(*newlayer)->port = port;
(*newlayer)->connectionsSize = 0;
(*newlayer)->connections = NULL;
return UA_STATUSCODE_GOOD;
NetworklayerTCP *NetworklayerTCP_new(UA_ConnectionConfig localConf, UA_UInt32 port) {
NetworklayerTCP *newlayer = malloc(sizeof(NetworklayerTCP));
if(newlayer == NULL)
return NULL;
newlayer->localConf = localConf;
newlayer->port = port;
newlayer->connectionsSize = 0;
newlayer->connections = NULL;
return newlayer;
}

// copy the array of connections, but _loose_ one. This does not close the
Expand Down
6 changes: 1 addition & 5 deletions examples/networklayer_tcp.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,7 @@
struct NetworklayerTCP;
typedef struct NetworklayerTCP NetworklayerTCP;

#define BINARYCONNECTION_PROTOCOL_VERSION 0
#define BINARYCONNECTION_MAX_CHUNK_COUNT 1
#define BINARYCONNECTION_MAX_MESSAGE_SIZE 8192

UA_StatusCode NetworklayerTCP_new(NetworklayerTCP **newlayer, UA_ConnectionConfig localConf, UA_UInt32 port);
NetworklayerTCP * NetworklayerTCP_new(UA_ConnectionConfig localConf, UA_UInt32 port);
void NetworklayerTCP_delete(NetworklayerTCP *layer);
UA_StatusCode NetworkLayerTCP_run(NetworklayerTCP *layer, UA_Server *server, struct timeval tv,
void(*worker)(UA_Server*), UA_Boolean *running);
Expand Down
10 changes: 5 additions & 5 deletions examples/opcuaClient.c
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ UA_Int64 sendReadRequest(UA_Int32 sock, UA_UInt32 channelId, UA_UInt32 tokenId,
UA_ReadRequest rq;
UA_ReadRequest_init(&rq);
rq.maxAge = 0;
UA_Array_new((void **)&rq.nodesToRead, nodeIds_size, &UA_[UA_READVALUEID]);
UA_Array_new((void **)&rq.nodesToRead, nodeIds_size, &UA_TYPES[UA_READVALUEID]);
rq.nodesToReadSize = nodeIds_size;
for(UA_Int32 i=0;i<nodeIds_size;i++) {
UA_ReadValueId_init(&(rq.nodesToRead[i]));
Expand Down Expand Up @@ -257,7 +257,7 @@ UA_Int64 sendReadRequest(UA_Int32 sock, UA_UInt32 channelId, UA_UInt32 tokenId,

UA_DateTime tic = UA_DateTime_now();
UA_Int32 sendret = send(sock, message->data, offset, 0);
UA_Array_delete(rq.nodesToRead,nodeIds_size,&UA_[UA_READVALUEID]);
UA_Array_delete(rq.nodesToRead,nodeIds_size,&UA_TYPES[UA_READVALUEID]);
UA_ByteString_delete(message);

if (sendret < 0) {
Expand Down Expand Up @@ -355,7 +355,7 @@ int main(int argc, char *argv[]) {
received = recv(sock, reply.data, reply.length, 0);

UA_NodeId *nodesToRead;
UA_Array_new((void**)&nodesToRead,nodesToReadSize,&UA_[UA_NODEID]);
UA_Array_new((void**)&nodesToRead,nodesToReadSize,&UA_TYPES[UA_NODEID]);

for(UA_UInt32 i = 0; i<nodesToReadSize; i++) {
if(alwaysSameNode)
Expand All @@ -369,7 +369,7 @@ int main(int argc, char *argv[]) {
UA_DateTime tic, toc;
UA_Double *timeDiffs;

UA_Array_new((void**)&timeDiffs,tries,&UA_[UA_DOUBLE]);
UA_Array_new((void**)&timeDiffs,tries,&UA_TYPES[UA_DOUBLE]);
UA_Double sum = 0;

for(UA_UInt32 i = 0; i < tries; i++) {
Expand Down Expand Up @@ -404,7 +404,7 @@ int main(int argc, char *argv[]) {
UA_OpenSecureChannelResponse_deleteMembers(&openSecChannelRsp);
UA_String_delete(endpointUrl);
UA_String_deleteMembers(&reply);
UA_Array_delete(nodesToRead,nodesToReadSize,&UA_[UA_NODEID]);
UA_Array_delete(nodesToRead,nodesToReadSize,&UA_TYPES[UA_NODEID]);
UA_free(timeDiffs);
UA_CreateSessionResponse_deleteMembers(&createSessionResponse);

Expand Down
22 changes: 9 additions & 13 deletions examples/opcuaServer.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,18 +52,17 @@ UA_ByteString loadCertificate() {
int main(int argc, char** argv) {
signal(SIGINT, stopHandler); /* catches ctrl-c */

UA_Server server;
UA_String endpointUrl;
UA_String_copycstring("opc.tcp://192.168.56.101:16664",&endpointUrl);
UA_ByteString certificate = loadCertificate();
UA_Server_init(&server, &endpointUrl, &certificate);
Logger_Stdout_init(&server.logger);
UA_Server *server = UA_Server_new(&endpointUrl, &certificate);
//Logger_Stdout_init(&server->logger);

UA_Int32 myInteger = 42;
UA_String myIntegerName;
UA_STRING_STATIC(myIntegerName, "The Answer");
UA_Server_addScalarVariableNode(&server, &myIntegerName, (void*)&myInteger, &UA_[UA_INT32],
&server.objectsNodeId, &server.hasComponentReferenceTypeId);
UA_Server_addScalarVariableNode(server, &myIntegerName, (void*)&myInteger, &UA_TYPES[UA_INT32],
&UA_NODEIDS[UA_OBJECTSFOLDER], &UA_NODEIDS[UA_HASCOMPONENT]);

#ifdef BENCHMARK
UA_UInt32 nodeCount = 500;
Expand All @@ -78,23 +77,20 @@ int main(int argc, char** argv) {
tmpNode->nodeId.identifier.numeric = 19000+i;
tmpNode->nodeClass = UA_NODECLASS_VARIABLE;
//tmpNode->valueRank = -1;
tmpNode->value.vt = &UA_[UA_INT32];
tmpNode->value.vt = &UA_TYPES[UA_INT32];
tmpNode->value.storage.data.dataPtr = &data;
tmpNode->value.storageType = UA_VARIANT_DATA_NODELETE;
tmpNode->value.storage.data.arrayLength = 1;
UA_Server_addNode(&server, (UA_Node**)&tmpNode, &server.objectsNodeId,
&server.hasComponentReferenceTypeId);
UA_Server_addNode(server, (UA_Node**)&tmpNode, &UA_NODEIDS[UA_OBJECTSFOLDER], &UA_NODEIDS[UA_HASCOMPONENT]);
}
#endif

#define PORT 16664
NetworklayerTCP* nl;
NetworklayerTCP_new(&nl, UA_ConnectionConfig_standard, PORT);
NetworklayerTCP* nl = NetworklayerTCP_new(UA_ConnectionConfig_standard, PORT);
printf("Server started, connect to to opc.tcp://127.0.0.1:%i\n", PORT);
struct timeval callback_interval = {1, 0}; // 1 second
UA_Int32 retval = NetworkLayerTCP_run(nl, &server, callback_interval,
serverCallback, &running);
UA_Server_deleteMembers(&server);
UA_Int32 retval = NetworkLayerTCP_run(nl, server, callback_interval, serverCallback, &running);
UA_Server_delete(server);
NetworklayerTCP_delete(nl);
UA_String_deleteMembers(&endpointUrl);
return retval == UA_STATUSCODE_GOOD ? 0 : retval;
Expand Down
41 changes: 8 additions & 33 deletions include/ua_server.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,47 +27,22 @@ extern "C" {

/** @defgroup server Server */

//identifier numbers are different for XML and binary, so we have to substract an offset for comparison
#define UA_ENCODINGOFFSET_XML 1
#define UA_ENCODINGOFFSET_BINARY 2

struct UA_SecureChannelManager;
typedef struct UA_SecureChannelManager UA_SecureChannelManager;

struct UA_SessionManager;
typedef struct UA_SessionManager UA_SessionManager;

struct UA_NodeStore;
typedef struct UA_NodeStore UA_NodeStore;

typedef struct UA_Server {
UA_ApplicationDescription description;
UA_Int32 endpointDescriptionsSize;
UA_EndpointDescription *endpointDescriptions;
UA_ByteString serverCertificate;

UA_SecureChannelManager *secureChannelManager;
UA_SessionManager *sessionManager;
UA_NodeStore *nodestore;
UA_Logger logger;

// todo: move these somewhere sane
UA_ExpandedNodeId objectsNodeId;
UA_NodeId hasComponentReferenceTypeId;
} UA_Server;
struct UA_Server;
typedef struct UA_Server UA_Server;

void UA_EXPORT UA_Server_init(UA_Server *server, UA_String *endpointUrl, UA_ByteString *serverCertificate);
UA_StatusCode UA_EXPORT UA_Server_deleteMembers(UA_Server *server);
UA_Server UA_EXPORT * UA_Server_new(UA_String *endpointUrl, UA_ByteString *serverCertificate);
void UA_EXPORT UA_Server_delete(UA_Server *server);
void UA_EXPORT UA_Server_processBinaryMessage(UA_Server *server, UA_Connection *connection, const UA_ByteString *msg);

/* Services for local use */
UA_AddNodesResult UA_EXPORT UA_Server_addNode(UA_Server *server, UA_Node **node, const UA_NodeId *parentNodeId, const UA_NodeId *referenceTypeId);
void UA_EXPORT UA_Server_addReference(UA_Server *server, const UA_AddReferencesRequest *request, UA_AddReferencesResponse *response);
UA_AddNodesResult UA_EXPORT UA_Server_addScalarVariableNode(UA_Server *server, UA_String *browseName, void *value,
const UA_VTable_Entry *vt, UA_ExpandedNodeId *parentNodeId,
UA_NodeId *referenceTypeId );
UA_AddNodesResult UA_EXPORT UA_Server_addNode(UA_Server *server, UA_Node **node, UA_ExpandedNodeId *parentNodeId,
UA_NodeId *referenceTypeId);
void UA_EXPORT UA_Server_addReferences(UA_Server *server, const UA_AddReferencesRequest *request,
UA_AddReferencesResponse *response);
const UA_VTable_Entry *vt, const UA_NodeId *parentNodeId,
const UA_NodeId *referenceTypeId );

#ifdef __cplusplus
} // extern "C"
Expand Down
2 changes: 1 addition & 1 deletion src/server/ua_nodestore.c
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,6 @@ void UA_NodeStore_iterate(const UA_NodeStore *ns, UA_NodeStore_nodeVisitor visit
}
}

void UA_NodeStore_releaseManagedNode(const UA_Node *managed) {
void UA_NodeStore_release(const UA_Node *managed) {
;
}
2 changes: 1 addition & 1 deletion src/server/ua_nodestore.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ UA_StatusCode UA_NodeStore_get(const UA_NodeStore *ns, const UA_NodeId *nodeid,

/** @brief Release a managed node. Do never insert a node that isn't stored in a
namespace. */
void UA_NodeStore_releaseManagedNode(const UA_Node *managed);
void UA_NodeStore_release(const UA_Node *managed);

/** @brief A function that can be evaluated on all entries in a namespace via
UA_NodeStore_iterate. Note that the visitor is read-only on the nodes. */
Expand Down
7 changes: 2 additions & 5 deletions src/server/ua_nodestore_concurrent.c
Original file line number Diff line number Diff line change
Expand Up @@ -164,10 +164,7 @@ static void markDead(struct rcu_head *head) {
}

/* Free the entry if it is dead and nobody uses it anymore */
void UA_NodeStore_releaseManagedNode(const UA_Node *managed) {
if(managed == UA_NULL)
return;

void UA_NodeStore_release(const UA_Node *managed) {
UA_NodeStore_Entry *entry = caa_container_of(managed, UA_NodeStore_Entry, node); // pointer to the first entry
if(uatomic_sub_return(&entry->readcount, 1) > 0)
return;
Expand Down Expand Up @@ -350,7 +347,7 @@ void UA_NodeStore_iterate(const UA_NodeStore *ns, UA_NodeStore_nodeVisitor visit
const UA_Node *node = &found_entry->node;
rcu_read_unlock();
visitor(node);
UA_NodeStore_releaseManagedNode((UA_Node *)node);
UA_NodeStore_release((UA_Node *)node);
rcu_read_lock();
cds_lfht_next(ht, &iter);
}
Expand Down
36 changes: 10 additions & 26 deletions src/server/ua_securechannel_manager.c
Original file line number Diff line number Diff line change
@@ -1,40 +1,25 @@
#include "ua_securechannel_manager.h"
#include "ua_session.h"
#include "ua_util.h"
#include "ua_statuscodes.h"

struct channel_list_entry {
UA_SecureChannel channel;
LIST_ENTRY(channel_list_entry) pointers;
};

struct UA_SecureChannelManager {
UA_Int32 maxChannelCount;
UA_DateTime maxChannelLifetime;
LIST_HEAD(channel_list, channel_list_entry) channels;
UA_MessageSecurityMode securityMode;
UA_String endpointUrl;
UA_DateTime channelLifeTime;
UA_Int32 lastChannelId;
UA_UInt32 lastTokenId;
};

UA_StatusCode UA_SecureChannelManager_new(UA_SecureChannelManager **cm, UA_UInt32 maxChannelCount,
UA_UInt32 tokenLifetime, UA_UInt32 startChannelId,
UA_UInt32 startTokenId, UA_String *endpointUrl) {
if(!(*cm = UA_alloc(sizeof(UA_SecureChannelManager))))
return UA_STATUSCODE_BADOUTOFMEMORY;
UA_SecureChannelManager *channelManager = *cm;
LIST_INIT(&channelManager->channels);
channelManager->lastChannelId = startChannelId;
channelManager->lastTokenId = startTokenId;
UA_String_copy(endpointUrl, &channelManager->endpointUrl);
channelManager->maxChannelLifetime = tokenLifetime;
channelManager->maxChannelCount = maxChannelCount;
UA_StatusCode UA_SecureChannelManager_init(UA_SecureChannelManager *cm, UA_UInt32 maxChannelCount,
UA_UInt32 tokenLifetime, UA_UInt32 startChannelId,
UA_UInt32 startTokenId, UA_String *endpointUrl) {
LIST_INIT(&cm->channels);
cm->lastChannelId = startChannelId;
cm->lastTokenId = startTokenId;
UA_String_copy(endpointUrl, &cm->endpointUrl);
cm->maxChannelLifetime = tokenLifetime;
cm->maxChannelCount = maxChannelCount;
return UA_STATUSCODE_GOOD;
}

void UA_SecureChannelManager_delete(UA_SecureChannelManager *cm) {
void UA_SecureChannelManager_deleteMembers(UA_SecureChannelManager *cm) {
struct channel_list_entry *entry = LIST_FIRST(&cm->channels);
while(entry) {
LIST_REMOVE(entry, pointers);
Expand All @@ -47,7 +32,6 @@ void UA_SecureChannelManager_delete(UA_SecureChannelManager *cm) {
entry = LIST_FIRST(&cm->channels);
}
UA_String_deleteMembers(&cm->endpointUrl);
UA_free(cm);
}

UA_StatusCode UA_SecureChannelManager_open(UA_SecureChannelManager *cm,
Expand Down
20 changes: 16 additions & 4 deletions src/server/ua_securechannel_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,23 @@

#include "ua_server.h"
#include "ua_securechannel.h"
#include "ua_util.h"

UA_StatusCode UA_SecureChannelManager_new(UA_SecureChannelManager **cm, UA_UInt32 maxChannelCount,
UA_UInt32 tokenLifetime, UA_UInt32 startChannelId,
UA_UInt32 startTokenId, UA_String *endpointUrl);
void UA_SecureChannelManager_delete(UA_SecureChannelManager *cm);
typedef struct UA_SecureChannelManager {
LIST_HEAD(channel_list, channel_list_entry) channels; // doubly-linked list of channels
UA_Int32 maxChannelCount;
UA_DateTime maxChannelLifetime;
UA_MessageSecurityMode securityMode;
UA_String endpointUrl;
UA_DateTime channelLifeTime;
UA_Int32 lastChannelId;
UA_UInt32 lastTokenId;
} UA_SecureChannelManager;

UA_StatusCode UA_SecureChannelManager_init(UA_SecureChannelManager *cm, UA_UInt32 maxChannelCount,
UA_UInt32 tokenLifetime, UA_UInt32 startChannelId,
UA_UInt32 startTokenId, UA_String *endpointUrl);
void UA_SecureChannelManager_deleteMembers(UA_SecureChannelManager *cm);
UA_StatusCode UA_SecureChannelManager_open(UA_SecureChannelManager *cm, UA_Connection *conn,
const UA_OpenSecureChannelRequest *request,
UA_OpenSecureChannelResponse *response);
Expand Down
Loading

0 comments on commit 0d7e0e5

Please sign in to comment.