ua_server.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507
  1. #ifdef UA_MULTITHREADING
  2. #define _LGPL_SOURCE
  3. #include <urcu.h>
  4. //#include <urcu-call-rcu.h>
  5. #endif
  6. #include "ua_server_internal.h"
  7. #include "ua_namespace_0.h"
  8. #include "ua_securechannel_manager.h"
  9. #include "ua_session_manager.h"
  10. #include "ua_util.h"
  11. #include "ua_services.h"
  12. /**********************/
  13. /* Namespace Handling */
  14. /**********************/
  15. static void UA_ExternalNamespace_init(UA_ExternalNamespace *ens) {
  16. ens->index = 0;
  17. UA_String_init(&ens->url);
  18. }
  19. static void UA_ExternalNamespace_deleteMembers(UA_ExternalNamespace *ens) {
  20. UA_String_deleteMembers(&ens->url);
  21. ens->externalNodeStore.delete(ens->externalNodeStore.ensHandle);
  22. }
  23. /*****************/
  24. /* Configuration */
  25. /*****************/
  26. void UA_Server_addNetworkLayer(UA_Server *server, UA_ServerNetworkLayer networkLayer) {
  27. server->nls = UA_realloc(server->nls, sizeof(UA_ServerNetworkLayer)*(server->nlsSize+1));
  28. server->nls[server->nlsSize] = networkLayer;
  29. server->nlsSize++;
  30. }
  31. void UA_Server_setServerCertificate(UA_Server *server, UA_ByteString certificate) {
  32. UA_ByteString_copy(&certificate, &server->serverCertificate);
  33. }
  34. /**********/
  35. /* Server */
  36. /**********/
  37. void UA_Server_delete(UA_Server *server) {
  38. // The server needs to be stopped before it can be deleted
  39. // Delete the network layers
  40. for(UA_Int32 i=0;i<server->nlsSize;i++) {
  41. server->nls[i].free(server->nls[i].nlHandle);
  42. }
  43. UA_free(server->nls);
  44. // Delete the timed work
  45. UA_Server_deleteTimedWork(server);
  46. // Delete all internal data
  47. UA_ApplicationDescription_deleteMembers(&server->description);
  48. UA_SecureChannelManager_deleteMembers(&server->secureChannelManager);
  49. UA_SessionManager_deleteMembers(&server->sessionManager);
  50. UA_NodeStore_delete(server->nodestore);
  51. UA_ByteString_deleteMembers(&server->serverCertificate);
  52. UA_Array_delete(server->endpointDescriptions, server->endpointDescriptionsSize, &UA_TYPES[UA_ENDPOINTDESCRIPTION]);
  53. UA_free(server);
  54. #ifdef UA_MULTITHREADING
  55. rcu_barrier(); // wait for all scheduled call_rcu work to complete
  56. #endif
  57. }
  58. UA_Server * UA_Server_new(void) {
  59. UA_Server *server = UA_malloc(sizeof(UA_Server));
  60. if(!server)
  61. return UA_NULL;
  62. LIST_INIT(&server->timedWork);
  63. #ifdef UA_MULTITHREADING
  64. rcu_init();
  65. cds_wfcq_init(&server->dispatchQueue_head, &server->dispatchQueue_tail);
  66. server->delayedWork = UA_NULL;
  67. #endif
  68. // random seed
  69. server->random_seed = (UA_UInt32) UA_DateTime_now();
  70. // networklayers
  71. server->nls = UA_NULL;
  72. server->nlsSize = 0;
  73. UA_ByteString_init(&server->serverCertificate);
  74. // mockup application description
  75. UA_ApplicationDescription_init(&server->description);
  76. UA_String_copycstring("urn:unconfigured:open62541:application", &server->description.productUri);
  77. UA_String_copycstring("http://unconfigured.open62541/applications/", &server->description.applicationUri);
  78. UA_LocalizedText_copycstring("Unconfigured open62541 application", &server->description.applicationName);
  79. server->description.applicationType = UA_APPLICATIONTYPE_SERVER;
  80. server->externalNamespacesSize = 0;
  81. server->externalNamespaces = UA_NULL;
  82. // mockup endpoint description
  83. server->endpointDescriptionsSize = 1;
  84. UA_EndpointDescription *endpoint = UA_EndpointDescription_new(); // todo: check return code
  85. endpoint->securityMode = UA_MESSAGESECURITYMODE_NONE;
  86. UA_String_copycstring("http://opcfoundation.org/UA/SecurityPolicy#None", &endpoint->securityPolicyUri);
  87. UA_String_copycstring("http://opcfoundation.org/UA-Profile/Transport/uatcp-uasc-uabinary", &endpoint->transportProfileUri);
  88. endpoint->userIdentityTokensSize = 1;
  89. endpoint->userIdentityTokens = UA_malloc(sizeof(UA_UserTokenPolicy));
  90. UA_UserTokenPolicy_init(endpoint->userIdentityTokens);
  91. UA_String_copycstring("my-anonymous-policy", &endpoint->userIdentityTokens->policyId); // defined per server
  92. endpoint->userIdentityTokens->tokenType = UA_USERTOKENTYPE_ANONYMOUS;
  93. /* UA_String_copy(endpointUrl, &endpoint->endpointUrl); */
  94. /* /\* The standard says "the HostName specified in the Server Certificate is the */
  95. /* same as the HostName contained in the endpointUrl provided in the */
  96. /* EndpointDescription *\/ */
  97. /* UA_String_copy(&server->serverCertificate, &endpoint->serverCertificate); */
  98. UA_ApplicationDescription_copy(&server->description, &endpoint->server);
  99. server->endpointDescriptions = endpoint;
  100. #define MAXCHANNELCOUNT 100
  101. #define STARTCHANNELID 1
  102. #define TOKENLIFETIME 10000
  103. #define STARTTOKENID 1
  104. UA_SecureChannelManager_init(&server->secureChannelManager, MAXCHANNELCOUNT,
  105. TOKENLIFETIME, STARTCHANNELID, STARTTOKENID);
  106. #define MAXSESSIONCOUNT 1000
  107. #define SESSIONLIFETIME 10000
  108. #define STARTSESSIONID 1
  109. UA_SessionManager_init(&server->sessionManager, MAXSESSIONCOUNT, SESSIONLIFETIME, STARTSESSIONID);
  110. server->nodestore = UA_NodeStore_new();
  111. #define ADDREFERENCE(NODEID, REFTYPE_NODEID, TARGET_EXPNODEID) do { \
  112. UA_AddReferencesItem item; \
  113. UA_AddReferencesItem_init(&item); \
  114. item.sourceNodeId = NODEID; \
  115. item.referenceTypeId = REFTYPE_NODEID; \
  116. item.isForward = UA_TRUE; \
  117. item.targetNodeId = TARGET_EXPNODEID; \
  118. UA_Server_addReference(server, &item); \
  119. } while(0)
  120. #define COPYNAMES(TARGET, NAME) do { \
  121. UA_QualifiedName_copycstring(NAME, &TARGET->browseName); \
  122. UA_LocalizedText_copycstring(NAME, &TARGET->displayName); \
  123. UA_LocalizedText_copycstring(NAME, &TARGET->description); \
  124. } while(0)
  125. /**************/
  126. /* References */
  127. /**************/
  128. /* bootstrap by manually inserting "references" and "hassubtype" */
  129. UA_ReferenceTypeNode *references = UA_ReferenceTypeNode_new();
  130. COPYNAMES(references, "References");
  131. references->nodeId = UA_NODEIDS[UA_REFERENCES];
  132. references->nodeClass = UA_NODECLASS_REFERENCETYPE;
  133. references->isAbstract = UA_TRUE;
  134. references->symmetric = UA_TRUE;
  135. // this node has no parent??
  136. UA_NodeStore_insert(server->nodestore, (const UA_Node**)&references, UA_FALSE);
  137. UA_ReferenceTypeNode *hassubtype = UA_ReferenceTypeNode_new();
  138. COPYNAMES(hassubtype, "HasSubtype");
  139. UA_LocalizedText_copycstring("SubtypeOf", &hassubtype->inverseName);
  140. hassubtype->nodeId = UA_NODEIDS[UA_HASSUBTYPE];
  141. hassubtype->nodeClass = UA_NODECLASS_REFERENCETYPE;
  142. hassubtype->isAbstract = UA_FALSE;
  143. hassubtype->symmetric = UA_FALSE;
  144. UA_NodeStore_insert(server->nodestore, (const UA_Node**)&hassubtype, UA_FALSE);
  145. /* continue adding reference types with normal "addnode" */
  146. UA_ReferenceTypeNode *hierarchicalreferences = UA_ReferenceTypeNode_new();
  147. COPYNAMES(hierarchicalreferences, "Hierarchicalreferences");
  148. hierarchicalreferences->nodeId = UA_NODEIDS[UA_HIERARCHICALREFERENCES];
  149. hierarchicalreferences->nodeClass = UA_NODECLASS_REFERENCETYPE;
  150. hierarchicalreferences->isAbstract = UA_TRUE;
  151. hierarchicalreferences->symmetric = UA_FALSE;
  152. UA_Server_addNode(server, (const UA_Node**)&hierarchicalreferences,
  153. &UA_EXPANDEDNODEIDS[UA_REFERENCES], &UA_NODEIDS[UA_HASSUBTYPE]);
  154. UA_ReferenceTypeNode *nonhierarchicalreferences = UA_ReferenceTypeNode_new();
  155. COPYNAMES(nonhierarchicalreferences, "NonHierarchicalReferences");
  156. nonhierarchicalreferences->nodeId = UA_NODEIDS[UA_NONHIERARCHICALREFERENCES];
  157. nonhierarchicalreferences->nodeClass = UA_NODECLASS_REFERENCETYPE;
  158. nonhierarchicalreferences->isAbstract = UA_TRUE;
  159. nonhierarchicalreferences->symmetric = UA_FALSE;
  160. UA_Server_addNode(server, (const UA_Node **)&nonhierarchicalreferences,
  161. &UA_EXPANDEDNODEIDS[UA_REFERENCES], &UA_NODEIDS[UA_HASSUBTYPE]);
  162. UA_ReferenceTypeNode *haschild = UA_ReferenceTypeNode_new();
  163. COPYNAMES(haschild, "HasChild");
  164. haschild->nodeId = UA_NODEIDS[UA_HASCHILD];
  165. haschild->nodeClass = UA_NODECLASS_REFERENCETYPE;
  166. haschild->isAbstract = UA_TRUE;
  167. haschild->symmetric = UA_FALSE;
  168. UA_Server_addNode(server, (const UA_Node **)&haschild,
  169. &UA_EXPANDEDNODEIDS[UA_HIERARCHICALREFERENCES], &UA_NODEIDS[UA_HASSUBTYPE]);
  170. UA_ReferenceTypeNode *organizes = UA_ReferenceTypeNode_new();
  171. COPYNAMES(organizes, "Organizes");
  172. UA_LocalizedText_copycstring("OrganizedBy", &organizes->inverseName);
  173. organizes->nodeId = UA_NODEIDS[UA_ORGANIZES];
  174. organizes->nodeClass = UA_NODECLASS_REFERENCETYPE;
  175. organizes->isAbstract = UA_FALSE;
  176. organizes->symmetric = UA_FALSE;
  177. UA_Server_addNode(server, (const UA_Node **)&organizes,
  178. &UA_EXPANDEDNODEIDS[UA_HIERARCHICALREFERENCES], &UA_NODEIDS[UA_HASSUBTYPE]);
  179. UA_ReferenceTypeNode *haseventsource = UA_ReferenceTypeNode_new();
  180. COPYNAMES(haseventsource, "HasEventSource");
  181. UA_LocalizedText_copycstring("EventSourceOf", &haseventsource->inverseName);
  182. haseventsource->nodeId = UA_NODEIDS[UA_HASEVENTSOURCE];
  183. haseventsource->nodeClass = UA_NODECLASS_REFERENCETYPE;
  184. haseventsource->isAbstract = UA_FALSE;
  185. haseventsource->symmetric = UA_FALSE;
  186. UA_Server_addNode(server, (const UA_Node **)&haseventsource,
  187. &UA_EXPANDEDNODEIDS[UA_HIERARCHICALREFERENCES], &UA_NODEIDS[UA_HASSUBTYPE]);
  188. UA_ReferenceTypeNode *hasmodellingrule = UA_ReferenceTypeNode_new();
  189. COPYNAMES(hasmodellingrule, "HasModellingRule");
  190. UA_LocalizedText_copycstring("ModellingRuleOf", &hasmodellingrule->inverseName);
  191. hasmodellingrule->nodeId = UA_NODEIDS[UA_HASMODELLINGRULE];
  192. hasmodellingrule->nodeClass = UA_NODECLASS_REFERENCETYPE;
  193. hasmodellingrule->isAbstract = UA_FALSE;
  194. hasmodellingrule->symmetric = UA_FALSE;
  195. UA_Server_addNode(server, (const UA_Node **)&hasmodellingrule,
  196. &UA_EXPANDEDNODEIDS[UA_NONHIERARCHICALREFERENCES], &UA_NODEIDS[UA_HASSUBTYPE]);
  197. UA_ReferenceTypeNode *hasencoding = UA_ReferenceTypeNode_new();
  198. COPYNAMES(hasencoding, "HasEncoding");
  199. UA_LocalizedText_copycstring("EncodingOf", &hasencoding->inverseName);
  200. hasencoding->nodeId = UA_NODEIDS[UA_HASENCODING];
  201. hasencoding->nodeClass = UA_NODECLASS_REFERENCETYPE;
  202. hasencoding->isAbstract = UA_FALSE;
  203. hasencoding->symmetric = UA_FALSE;
  204. UA_Server_addNode(server, (const UA_Node **)&hasencoding,
  205. &UA_EXPANDEDNODEIDS[UA_NONHIERARCHICALREFERENCES], &UA_NODEIDS[UA_HASSUBTYPE]);
  206. UA_ReferenceTypeNode *hasdescription = UA_ReferenceTypeNode_new();
  207. COPYNAMES(hasdescription, "HasDescription");
  208. UA_LocalizedText_copycstring("DescriptionOf", &hasdescription->inverseName);
  209. hasdescription->nodeId = UA_NODEIDS[UA_HASDESCRIPTION];
  210. hasdescription->nodeClass = UA_NODECLASS_REFERENCETYPE;
  211. hasdescription->isAbstract = UA_FALSE;
  212. hasdescription->symmetric = UA_FALSE;
  213. UA_Server_addNode(server, (const UA_Node **)&hasdescription,
  214. &UA_EXPANDEDNODEIDS[UA_NONHIERARCHICALREFERENCES], &UA_NODEIDS[UA_HASSUBTYPE]);
  215. UA_ReferenceTypeNode *hastypedefinition = UA_ReferenceTypeNode_new();
  216. COPYNAMES(hastypedefinition, "HasTypeDefinition");
  217. UA_LocalizedText_copycstring("TypeDefinitionOf", &hastypedefinition->inverseName);
  218. hastypedefinition->nodeId = UA_NODEIDS[UA_HASTYPEDEFINITION];
  219. hastypedefinition->nodeClass = UA_NODECLASS_REFERENCETYPE;
  220. hastypedefinition->isAbstract = UA_FALSE;
  221. hastypedefinition->symmetric = UA_FALSE;
  222. UA_Server_addNode(server, (const UA_Node **)&hastypedefinition,
  223. &UA_EXPANDEDNODEIDS[UA_NONHIERARCHICALREFERENCES], &UA_NODEIDS[UA_HASSUBTYPE]);
  224. UA_ReferenceTypeNode *generatesevent = UA_ReferenceTypeNode_new();
  225. COPYNAMES(generatesevent, "GeneratesEvent");
  226. UA_LocalizedText_copycstring("GeneratedBy", &generatesevent->inverseName);
  227. generatesevent->nodeId = UA_NODEIDS[UA_GENERATESEVENT];
  228. generatesevent->nodeClass = UA_NODECLASS_REFERENCETYPE;
  229. generatesevent->isAbstract = UA_FALSE;
  230. generatesevent->symmetric = UA_FALSE;
  231. UA_Server_addNode(server, (const UA_Node **)&generatesevent,
  232. &UA_EXPANDEDNODEIDS[UA_NONHIERARCHICALREFERENCES], &UA_NODEIDS[UA_HASSUBTYPE]);
  233. UA_ReferenceTypeNode *aggregates = UA_ReferenceTypeNode_new();
  234. COPYNAMES(aggregates, "Aggregates");
  235. // Todo: Is there an inverse name?
  236. aggregates->nodeId = UA_NODEIDS[UA_AGGREGATES];
  237. aggregates->nodeClass = UA_NODECLASS_REFERENCETYPE;
  238. aggregates->isAbstract = UA_TRUE;
  239. aggregates->symmetric = UA_FALSE;
  240. UA_Server_addNode(server, (const UA_Node **)&aggregates,
  241. &UA_EXPANDEDNODEIDS[UA_HASCHILD], &UA_NODEIDS[UA_HASSUBTYPE]);
  242. // complete bootstrap of hassubtype
  243. ADDREFERENCE(UA_NODEIDS[UA_HASCHILD], UA_NODEIDS[UA_HASSUBTYPE],
  244. UA_EXPANDEDNODEIDS[UA_HASSUBTYPE]);
  245. UA_ReferenceTypeNode *hasproperty = UA_ReferenceTypeNode_new();
  246. COPYNAMES(hasproperty, "HasProperty");
  247. UA_LocalizedText_copycstring("PropertyOf", &hasproperty->inverseName);
  248. hasproperty->nodeId = UA_NODEIDS[UA_HASPROPERTY];
  249. hasproperty->nodeClass = UA_NODECLASS_REFERENCETYPE;
  250. hasproperty->isAbstract = UA_FALSE;
  251. hasproperty->symmetric = UA_FALSE;
  252. UA_Server_addNode(server, (const UA_Node **)&hasproperty,
  253. &UA_EXPANDEDNODEIDS[UA_AGGREGATES], &UA_NODEIDS[UA_HASSUBTYPE]);
  254. UA_ReferenceTypeNode *hascomponent = UA_ReferenceTypeNode_new();
  255. COPYNAMES(hascomponent, "HasComponent");
  256. UA_LocalizedText_copycstring("ComponentOf", &hascomponent->inverseName);
  257. hascomponent->nodeId = UA_NODEIDS[UA_HASCOMPONENT];
  258. hascomponent->nodeClass = UA_NODECLASS_REFERENCETYPE;
  259. hascomponent->isAbstract = UA_FALSE;
  260. hascomponent->symmetric = UA_FALSE;
  261. UA_Server_addNode(server, (const UA_Node **)&hascomponent,
  262. &UA_EXPANDEDNODEIDS[UA_AGGREGATES], &UA_NODEIDS[UA_HASSUBTYPE]);
  263. UA_ReferenceTypeNode *hasnotifier = UA_ReferenceTypeNode_new();
  264. COPYNAMES(hasnotifier, "HasNotifier");
  265. UA_LocalizedText_copycstring("NotifierOf", &hasnotifier->inverseName);
  266. hasnotifier->nodeId = UA_NODEIDS[UA_HASNOTIFIER];
  267. hasnotifier->nodeClass = UA_NODECLASS_REFERENCETYPE;
  268. hasnotifier->isAbstract = UA_FALSE;
  269. hasnotifier->symmetric = UA_FALSE;
  270. UA_Server_addNode(server, (const UA_Node **)&hasnotifier,
  271. &UA_EXPANDEDNODEIDS[UA_HASEVENTSOURCE], &UA_NODEIDS[UA_HASSUBTYPE]);
  272. UA_ReferenceTypeNode *hasorderedcomponent = UA_ReferenceTypeNode_new();
  273. COPYNAMES(hasorderedcomponent, "HasOrderedComponent");
  274. UA_LocalizedText_copycstring("OrderedComponentOf", &hasorderedcomponent->inverseName);
  275. hasorderedcomponent->nodeId = UA_NODEIDS[UA_HASORDEREDCOMPONENT];
  276. hasorderedcomponent->nodeClass = UA_NODECLASS_REFERENCETYPE;
  277. hasorderedcomponent->isAbstract = UA_FALSE;
  278. hasorderedcomponent->symmetric = UA_FALSE;
  279. UA_Server_addNode(server, (const UA_Node **)&hasorderedcomponent,
  280. &UA_EXPANDEDNODEIDS[UA_HASCOMPONENT], &UA_NODEIDS[UA_HASSUBTYPE]);
  281. UA_ReferenceTypeNode *hasmodelparent = UA_ReferenceTypeNode_new();
  282. COPYNAMES(hasmodelparent, "HasModelParent");
  283. UA_LocalizedText_copycstring("ModelParentOf", &hasmodelparent->inverseName);
  284. hasmodelparent->nodeId = UA_NODEIDS[UA_HASMODELPARENT];
  285. hasmodelparent->nodeClass = UA_NODECLASS_REFERENCETYPE;
  286. hasmodelparent->isAbstract = UA_FALSE;
  287. hasmodelparent->symmetric = UA_FALSE;
  288. UA_Server_addNode(server, (const UA_Node **)&hasmodelparent,
  289. &UA_EXPANDEDNODEIDS[UA_NONHIERARCHICALREFERENCES], &UA_NODEIDS[UA_HASSUBTYPE]);
  290. UA_ReferenceTypeNode *fromstate = UA_ReferenceTypeNode_new();
  291. COPYNAMES(fromstate, "FromState");
  292. UA_LocalizedText_copycstring("ToTransition", &fromstate->inverseName);
  293. fromstate->nodeId = UA_NODEIDS[UA_FROMSTATE];
  294. fromstate->nodeClass = UA_NODECLASS_REFERENCETYPE;
  295. fromstate->isAbstract = UA_FALSE;
  296. fromstate->symmetric = UA_FALSE;
  297. UA_Server_addNode(server, (const UA_Node **)&fromstate,
  298. &UA_EXPANDEDNODEIDS[UA_NONHIERARCHICALREFERENCES], &UA_NODEIDS[UA_HASSUBTYPE]);
  299. UA_ReferenceTypeNode *tostate = UA_ReferenceTypeNode_new();
  300. COPYNAMES(tostate, "ToState");
  301. UA_LocalizedText_copycstring("FromTransition", &tostate->inverseName);
  302. tostate->nodeId = UA_NODEIDS[UA_TOSTATE];
  303. tostate->nodeClass = UA_NODECLASS_REFERENCETYPE;
  304. tostate->isAbstract = UA_FALSE;
  305. tostate->symmetric = UA_FALSE;
  306. UA_Server_addNode(server, (const UA_Node **)&tostate,
  307. &UA_EXPANDEDNODEIDS[UA_NONHIERARCHICALREFERENCES], &UA_NODEIDS[UA_HASSUBTYPE]);
  308. UA_ReferenceTypeNode *hascause = UA_ReferenceTypeNode_new();
  309. COPYNAMES(hascause, "HasCause");
  310. UA_LocalizedText_copycstring("MayBeCausedBy", &hascause->inverseName);
  311. hascause->nodeId = UA_NODEIDS[UA_HASCAUSE];
  312. hascause->nodeClass = UA_NODECLASS_REFERENCETYPE;
  313. hascause->isAbstract = UA_FALSE;
  314. hascause->symmetric = UA_FALSE;
  315. UA_Server_addNode(server, (const UA_Node **)&hascause,
  316. &UA_EXPANDEDNODEIDS[UA_NONHIERARCHICALREFERENCES], &UA_NODEIDS[UA_HASSUBTYPE]);
  317. UA_ReferenceTypeNode *haseffect = UA_ReferenceTypeNode_new();
  318. COPYNAMES(haseffect, "HasEffect");
  319. UA_LocalizedText_copycstring("MayBeEffectedBy", &haseffect->inverseName);
  320. haseffect->nodeId = UA_NODEIDS[UA_HASEFFECT];
  321. haseffect->nodeClass = UA_NODECLASS_REFERENCETYPE;
  322. haseffect->isAbstract = UA_FALSE;
  323. haseffect->symmetric = UA_FALSE;
  324. UA_Server_addNode(server, (const UA_Node **)&haseffect,
  325. &UA_EXPANDEDNODEIDS[UA_NONHIERARCHICALREFERENCES], &UA_NODEIDS[UA_HASSUBTYPE]);
  326. UA_ReferenceTypeNode *hashistoricalconfiguration = UA_ReferenceTypeNode_new();
  327. COPYNAMES(hashistoricalconfiguration, "HasHistoricalConfiguration");
  328. UA_LocalizedText_copycstring("HistoricalConfigurationOf", &hashistoricalconfiguration->inverseName);
  329. hashistoricalconfiguration->nodeId = UA_NODEIDS[UA_HASHISTORICALCONFIGURATION];
  330. hashistoricalconfiguration->nodeClass = UA_NODECLASS_REFERENCETYPE;
  331. hashistoricalconfiguration->isAbstract = UA_FALSE;
  332. hashistoricalconfiguration->symmetric = UA_FALSE;
  333. UA_Server_addNode(server, (const UA_Node **)&hashistoricalconfiguration,
  334. &UA_EXPANDEDNODEIDS[UA_AGGREGATES], &UA_NODEIDS[UA_HASSUBTYPE]);
  335. /***********/
  336. /* Objects */
  337. /***********/
  338. UA_ObjectNode *folderType = UA_ObjectNode_new();
  339. folderType->nodeId = UA_NODEIDS[UA_FOLDERTYPE];
  340. folderType->nodeClass = UA_NODECLASS_OBJECTTYPE;
  341. COPYNAMES(folderType, "FolderType");
  342. UA_NodeStore_insert(server->nodestore, (const UA_Node**)&folderType, UA_FALSE);
  343. UA_ObjectNode *root = UA_ObjectNode_new();
  344. COPYNAMES(root, "Root");
  345. root->nodeId = UA_NODEIDS[UA_ROOTFOLDER];
  346. root->nodeClass = UA_NODECLASS_OBJECT;
  347. UA_NodeStore_insert(server->nodestore, (const UA_Node**)&root, UA_FALSE);
  348. ADDREFERENCE(UA_NODEIDS[UA_ROOTFOLDER], UA_NODEIDS[UA_HASTYPEDEFINITION],
  349. UA_EXPANDEDNODEIDS[UA_FOLDERTYPE]);
  350. ADDREFERENCE(UA_NODEIDS[UA_ROOTFOLDER], UA_NODEIDS[UA_ORGANIZES],
  351. UA_EXPANDEDNODEIDS[UA_OBJECTSFOLDER]);
  352. ADDREFERENCE(UA_NODEIDS[UA_ROOTFOLDER], UA_NODEIDS[UA_ORGANIZES],
  353. UA_EXPANDEDNODEIDS[UA_TYPESFOLDER]);
  354. ADDREFERENCE(UA_NODEIDS[UA_ROOTFOLDER], UA_NODEIDS[UA_ORGANIZES],
  355. UA_EXPANDEDNODEIDS[UA_VIEWSFOLDER]);
  356. UA_ObjectNode *objects = UA_ObjectNode_new();
  357. COPYNAMES(objects, "Objects");
  358. objects->nodeId = UA_NODEIDS[UA_OBJECTSFOLDER];
  359. objects->nodeClass = UA_NODECLASS_OBJECT;
  360. UA_NodeStore_insert(server->nodestore, (const UA_Node**)&objects, UA_FALSE);
  361. ADDREFERENCE(UA_NODEIDS[UA_OBJECTSFOLDER], UA_NODEIDS[UA_HASTYPEDEFINITION],
  362. UA_EXPANDEDNODEIDS[UA_FOLDERTYPE]);
  363. ADDREFERENCE(UA_NODEIDS[UA_OBJECTSFOLDER], UA_NODEIDS[UA_ORGANIZES], UA_EXPANDEDNODEIDS[UA_SERVER]);
  364. UA_ObjectNode *types = UA_ObjectNode_new();
  365. COPYNAMES(types, "Types");
  366. types->nodeId = UA_NODEIDS[UA_TYPESFOLDER];
  367. types->nodeClass = UA_NODECLASS_OBJECT;
  368. UA_NodeStore_insert(server->nodestore, (const UA_Node**)&types, UA_FALSE);
  369. ADDREFERENCE(UA_NODEIDS[UA_TYPESFOLDER], UA_NODEIDS[UA_HASTYPEDEFINITION],
  370. UA_EXPANDEDNODEIDS[UA_FOLDERTYPE]);
  371. UA_ObjectNode *views = UA_ObjectNode_new();
  372. COPYNAMES(views, "Views");
  373. views->nodeId = UA_NODEIDS[UA_VIEWSFOLDER];
  374. views->nodeClass = UA_NODECLASS_OBJECT;
  375. UA_NodeStore_insert(server->nodestore, (const UA_Node**)&views, UA_FALSE);
  376. ADDREFERENCE(UA_NODEIDS[UA_VIEWSFOLDER], UA_NODEIDS[UA_HASTYPEDEFINITION],
  377. UA_EXPANDEDNODEIDS[UA_FOLDERTYPE]);
  378. UA_ObjectNode *servernode = UA_ObjectNode_new();
  379. COPYNAMES(servernode, "Server");
  380. servernode->nodeId = UA_NODEIDS[UA_SERVER];
  381. servernode->nodeClass = UA_NODECLASS_OBJECT;
  382. UA_NodeStore_insert(server->nodestore, (const UA_Node**)&servernode, UA_FALSE);
  383. ADDREFERENCE(UA_NODEIDS[UA_SERVER], UA_NODEIDS[UA_HASCOMPONENT],
  384. UA_EXPANDEDNODEIDS[UA_SERVER_SERVERCAPABILITIES]);
  385. ADDREFERENCE(UA_NODEIDS[UA_SERVER], UA_NODEIDS[UA_HASPROPERTY], UA_EXPANDEDNODEIDS[UA_SERVER_SERVERARRAY]);
  386. UA_VariableNode *namespaceArray = UA_VariableNode_new();
  387. COPYNAMES(namespaceArray, "NamespaceArray");
  388. namespaceArray->nodeId = UA_NODEIDS[UA_SERVER_NAMESPACEARRAY];
  389. namespaceArray->nodeClass = UA_NODECLASS_VARIABLE;
  390. UA_Array_new(&namespaceArray->value.storage.data.dataPtr, 2, &UA_TYPES[UA_STRING]);
  391. namespaceArray->value.vt = &UA_TYPES[UA_STRING];
  392. namespaceArray->value.storage.data.arrayLength = 2;
  393. // Fixme: Insert the external namespaces
  394. UA_String_copycstring("http://opcfoundation.org/UA/",
  395. &((UA_String *)(namespaceArray->value.storage.data.dataPtr))[0]);
  396. UA_String_copycstring("urn:myServer:myApplication",
  397. &((UA_String *)(namespaceArray->value.storage.data.dataPtr))[1]);
  398. UA_UInt32 *dimensions = UA_malloc(sizeof(UA_UInt32));
  399. if(dimensions) {
  400. *dimensions = 2;
  401. namespaceArray->arrayDimensions = dimensions;
  402. namespaceArray->arrayDimensionsSize = 1;
  403. }
  404. namespaceArray->dataType = UA_NODEIDS[UA_STRING];
  405. namespaceArray->valueRank = 1;
  406. namespaceArray->minimumSamplingInterval = 1.0;
  407. namespaceArray->historizing = UA_FALSE;
  408. UA_Server_addNode(server, (const UA_Node **)&namespaceArray,
  409. &UA_EXPANDEDNODEIDS[UA_SERVER], &UA_NODEIDS[UA_HASCOMPONENT]);
  410. UA_ServerStatusDataType *status = UA_ServerStatusDataType_new();
  411. status->startTime = UA_DateTime_now();
  412. status->currentTime = UA_DateTime_now();
  413. status->state = UA_SERVERSTATE_RUNNING;
  414. UA_String_copycstring("open62541.org", &status->buildInfo.productUri);
  415. UA_String_copycstring("open62541", &status->buildInfo.manufacturerName);
  416. UA_String_copycstring("open62541", &status->buildInfo.productName);
  417. UA_String_copycstring("0.0", &status->buildInfo.softwareVersion);
  418. UA_String_copycstring("0.0", &status->buildInfo.buildNumber);
  419. status->buildInfo.buildDate = UA_DateTime_now();
  420. status->secondsTillShutdown = 99999999;
  421. UA_LocalizedText_copycstring("because", &status->shutdownReason);
  422. UA_VariableNode *serverstatus = UA_VariableNode_new();
  423. COPYNAMES(serverstatus, "ServerStatus");
  424. serverstatus->nodeId = UA_NODEIDS[UA_SERVER_SERVERSTATUS];
  425. serverstatus->nodeClass = UA_NODECLASS_VARIABLE;
  426. serverstatus->value.vt = &UA_TYPES[UA_SERVERSTATUSDATATYPE]; // gets encoded as an extensionobject
  427. serverstatus->value.storage.data.arrayLength = 1;
  428. serverstatus->value.storage.data.dataPtr = status;
  429. UA_Server_addNode(server, (const UA_Node **)&serverstatus,
  430. &UA_EXPANDEDNODEIDS[UA_SERVER], &UA_NODEIDS[UA_HASPROPERTY]);
  431. // todo: make this variable point to a member of the serverstatus
  432. UA_VariableNode *state = UA_VariableNode_new();
  433. UA_ServerState *stateEnum = UA_ServerState_new();
  434. *stateEnum = UA_SERVERSTATE_RUNNING;
  435. COPYNAMES(state, "State");
  436. state->nodeId = UA_NODEIDS[UA_SERVER_SERVERSTATUS_STATE];
  437. state->nodeClass = UA_NODECLASS_VARIABLE;
  438. state->value.vt = &UA_TYPES[UA_SERVERSTATE];
  439. state->value.storage.data.arrayLength = 1;
  440. state->value.storage.data.dataPtr = stateEnum; // points into the other object.
  441. state->value.storageType = UA_VARIANT_DATA;
  442. UA_NodeStore_insert(server->nodestore, (const UA_Node**)&state, UA_FALSE);
  443. return server;
  444. }