ua_server.h 48 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104
  1. /* This Source Code Form is subject to the terms of the Mozilla Public
  2. * License, v. 2.0. If a copy of the MPL was not distributed with this
  3. * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  4. *
  5. * Copyright 2014-2017 (c) Julius Pfrommer, Fraunhofer IOSB
  6. * Copyright 2015-2016 (c) Sten Grüner
  7. * Copyright 2014-2015, 2017 (c) Florian Palm
  8. * Copyright 2015-2016 (c) Chris Iatrou
  9. * Copyright 2015-2016 (c) Oleksiy Vasylyev
  10. * Copyright 2016-2017 (c) Stefan Profanter, fortiss GmbH
  11. */
  12. #ifndef UA_SERVER_H_
  13. #define UA_SERVER_H_
  14. #ifdef __cplusplus
  15. extern "C" {
  16. #endif
  17. #include "ua_types.h"
  18. #include "ua_types_generated.h"
  19. #include "ua_types_generated_handling.h"
  20. struct UA_ServerConfig;
  21. typedef struct UA_ServerConfig UA_ServerConfig;
  22. struct UA_Server;
  23. typedef struct UA_Server UA_Server;
  24. /**
  25. * .. _server:
  26. *
  27. * Server
  28. * ======
  29. *
  30. * .. include:: server_config.rst
  31. *
  32. * .. _server-lifecycle:
  33. *
  34. * Server Lifecycle
  35. * ---------------- */
  36. UA_Server UA_EXPORT * UA_Server_new(const UA_ServerConfig *config);
  37. void UA_EXPORT UA_Server_delete(UA_Server *server);
  38. /* Runs the main loop of the server. In each iteration, this calls into the
  39. * networklayers to see if messages have arrived.
  40. *
  41. * @param server The server object.
  42. * @param running The loop is run as long as *running is true.
  43. * Otherwise, the server shuts down.
  44. * @return Returns the statuscode of the UA_Server_run_shutdown method */
  45. UA_StatusCode UA_EXPORT
  46. UA_Server_run(UA_Server *server, volatile UA_Boolean *running);
  47. /* The prologue part of UA_Server_run (no need to use if you call
  48. * UA_Server_run) */
  49. UA_StatusCode UA_EXPORT
  50. UA_Server_run_startup(UA_Server *server);
  51. /* Executes a single iteration of the server's main loop.
  52. *
  53. * @param server The server object.
  54. * @param waitInternal Should we wait for messages in the networklayer?
  55. * Otherwise, the timouts for the networklayers are set to zero.
  56. * The default max wait time is 50millisec.
  57. * @return Returns how long we can wait until the next scheduled
  58. * callback (in ms) */
  59. UA_UInt16 UA_EXPORT
  60. UA_Server_run_iterate(UA_Server *server, UA_Boolean waitInternal);
  61. /* The epilogue part of UA_Server_run (no need to use if you call
  62. * UA_Server_run) */
  63. UA_StatusCode UA_EXPORT
  64. UA_Server_run_shutdown(UA_Server *server);
  65. /**
  66. * Repeated Callbacks
  67. * ------------------ */
  68. typedef void (*UA_ServerCallback)(UA_Server *server, void *data);
  69. /* Add a callback for cyclic repetition to the server.
  70. *
  71. * @param server The server object.
  72. * @param callback The callback that shall be added.
  73. * @param interval The callback shall be repeatedly executed with the given interval
  74. * (in ms). The interval must be larger than 5ms. The first execution
  75. * occurs at now() + interval at the latest.
  76. * @param callbackId Set to the identifier of the repeated callback . This can be used to cancel
  77. * the callback later on. If the pointer is null, the identifier is not set.
  78. * @return Upon success, UA_STATUSCODE_GOOD is returned.
  79. * An error code otherwise. */
  80. UA_StatusCode UA_EXPORT
  81. UA_Server_addRepeatedCallback(UA_Server *server, UA_ServerCallback callback,
  82. void *data, UA_UInt32 interval, UA_UInt64 *callbackId);
  83. UA_StatusCode UA_EXPORT
  84. UA_Server_changeRepeatedCallbackInterval(UA_Server *server, UA_UInt64 callbackId,
  85. UA_UInt32 interval);
  86. /* Remove a repeated callback.
  87. *
  88. * @param server The server object.
  89. * @param callbackId The id of the callback that shall be removed.
  90. * @return Upon success, UA_STATUSCODE_GOOD is returned.
  91. * An error code otherwise. */
  92. UA_StatusCode UA_EXPORT
  93. UA_Server_removeRepeatedCallback(UA_Server *server, UA_UInt64 callbackId);
  94. /**
  95. * Reading and Writing Node Attributes
  96. * -----------------------------------
  97. * The functions for reading and writing node attributes call the regular read
  98. * and write service in the background that are also used over the network.
  99. *
  100. * The following attributes cannot be read, since the local "admin" user always
  101. * has full rights.
  102. *
  103. * - UserWriteMask
  104. * - UserAccessLevel
  105. * - UserExecutable */
  106. /* Read an attribute of a node. The specialized functions below provide a more
  107. * concise syntax.
  108. *
  109. * @param server The server object.
  110. * @param item ReadValueIds contain the NodeId of the target node, the id of the
  111. * attribute to read and (optionally) an index range to read parts
  112. * of an array only. See the section on NumericRange for the format
  113. * used for array ranges.
  114. * @param timestamps Which timestamps to return for the attribute.
  115. * @return Returns a DataValue that contains either an error code, or a variant
  116. * with the attribute value and the timestamps. */
  117. UA_DataValue UA_EXPORT
  118. UA_Server_read(UA_Server *server, const UA_ReadValueId *item,
  119. UA_TimestampsToReturn timestamps);
  120. /* Don't use this function. There are typed versions for every supported
  121. * attribute. */
  122. UA_StatusCode UA_EXPORT
  123. __UA_Server_read(UA_Server *server, const UA_NodeId *nodeId,
  124. UA_AttributeId attributeId, void *v);
  125. static UA_INLINE UA_StatusCode
  126. UA_Server_readNodeId(UA_Server *server, const UA_NodeId nodeId,
  127. UA_NodeId *outNodeId) {
  128. return __UA_Server_read(server, &nodeId, UA_ATTRIBUTEID_NODEID, outNodeId);
  129. }
  130. static UA_INLINE UA_StatusCode
  131. UA_Server_readNodeClass(UA_Server *server, const UA_NodeId nodeId,
  132. UA_NodeClass *outNodeClass) {
  133. return __UA_Server_read(server, &nodeId, UA_ATTRIBUTEID_NODECLASS,
  134. outNodeClass);
  135. }
  136. static UA_INLINE UA_StatusCode
  137. UA_Server_readBrowseName(UA_Server *server, const UA_NodeId nodeId,
  138. UA_QualifiedName *outBrowseName) {
  139. return __UA_Server_read(server, &nodeId, UA_ATTRIBUTEID_BROWSENAME,
  140. outBrowseName);
  141. }
  142. static UA_INLINE UA_StatusCode
  143. UA_Server_readDisplayName(UA_Server *server, const UA_NodeId nodeId,
  144. UA_LocalizedText *outDisplayName) {
  145. return __UA_Server_read(server, &nodeId, UA_ATTRIBUTEID_DISPLAYNAME,
  146. outDisplayName);
  147. }
  148. static UA_INLINE UA_StatusCode
  149. UA_Server_readDescription(UA_Server *server, const UA_NodeId nodeId,
  150. UA_LocalizedText *outDescription) {
  151. return __UA_Server_read(server, &nodeId, UA_ATTRIBUTEID_DESCRIPTION,
  152. outDescription);
  153. }
  154. static UA_INLINE UA_StatusCode
  155. UA_Server_readWriteMask(UA_Server *server, const UA_NodeId nodeId,
  156. UA_UInt32 *outWriteMask) {
  157. return __UA_Server_read(server, &nodeId, UA_ATTRIBUTEID_WRITEMASK,
  158. outWriteMask);
  159. }
  160. static UA_INLINE UA_StatusCode
  161. UA_Server_readIsAbstract(UA_Server *server, const UA_NodeId nodeId,
  162. UA_Boolean *outIsAbstract) {
  163. return __UA_Server_read(server, &nodeId, UA_ATTRIBUTEID_ISABSTRACT,
  164. outIsAbstract);
  165. }
  166. static UA_INLINE UA_StatusCode
  167. UA_Server_readSymmetric(UA_Server *server, const UA_NodeId nodeId,
  168. UA_Boolean *outSymmetric) {
  169. return __UA_Server_read(server, &nodeId, UA_ATTRIBUTEID_SYMMETRIC,
  170. outSymmetric);
  171. }
  172. static UA_INLINE UA_StatusCode
  173. UA_Server_readInverseName(UA_Server *server, const UA_NodeId nodeId,
  174. UA_LocalizedText *outInverseName) {
  175. return __UA_Server_read(server, &nodeId, UA_ATTRIBUTEID_INVERSENAME,
  176. outInverseName);
  177. }
  178. static UA_INLINE UA_StatusCode
  179. UA_Server_readContainsNoLoop(UA_Server *server, const UA_NodeId nodeId,
  180. UA_Boolean *outContainsNoLoops) {
  181. return __UA_Server_read(server, &nodeId, UA_ATTRIBUTEID_CONTAINSNOLOOPS,
  182. outContainsNoLoops);
  183. }
  184. static UA_INLINE UA_StatusCode
  185. UA_Server_readEventNotifier(UA_Server *server, const UA_NodeId nodeId,
  186. UA_Byte *outEventNotifier) {
  187. return __UA_Server_read(server, &nodeId, UA_ATTRIBUTEID_EVENTNOTIFIER,
  188. outEventNotifier);
  189. }
  190. static UA_INLINE UA_StatusCode
  191. UA_Server_readValue(UA_Server *server, const UA_NodeId nodeId,
  192. UA_Variant *outValue) {
  193. return __UA_Server_read(server, &nodeId, UA_ATTRIBUTEID_VALUE, outValue);
  194. }
  195. static UA_INLINE UA_StatusCode
  196. UA_Server_readDataType(UA_Server *server, const UA_NodeId nodeId,
  197. UA_NodeId *outDataType) {
  198. return __UA_Server_read(server, &nodeId, UA_ATTRIBUTEID_DATATYPE,
  199. outDataType);
  200. }
  201. static UA_INLINE UA_StatusCode
  202. UA_Server_readValueRank(UA_Server *server, const UA_NodeId nodeId,
  203. UA_Int32 *outValueRank) {
  204. return __UA_Server_read(server, &nodeId, UA_ATTRIBUTEID_VALUERANK,
  205. outValueRank);
  206. }
  207. /* Returns a variant with an int32 array */
  208. static UA_INLINE UA_StatusCode
  209. UA_Server_readArrayDimensions(UA_Server *server, const UA_NodeId nodeId,
  210. UA_Variant *outArrayDimensions) {
  211. return __UA_Server_read(server, &nodeId, UA_ATTRIBUTEID_ARRAYDIMENSIONS,
  212. outArrayDimensions);
  213. }
  214. static UA_INLINE UA_StatusCode
  215. UA_Server_readAccessLevel(UA_Server *server, const UA_NodeId nodeId,
  216. UA_Byte *outAccessLevel) {
  217. return __UA_Server_read(server, &nodeId, UA_ATTRIBUTEID_ACCESSLEVEL,
  218. outAccessLevel);
  219. }
  220. static UA_INLINE UA_StatusCode
  221. UA_Server_readMinimumSamplingInterval(UA_Server *server, const UA_NodeId nodeId,
  222. UA_Double *outMinimumSamplingInterval) {
  223. return __UA_Server_read(server, &nodeId,
  224. UA_ATTRIBUTEID_MINIMUMSAMPLINGINTERVAL,
  225. outMinimumSamplingInterval);
  226. }
  227. static UA_INLINE UA_StatusCode
  228. UA_Server_readHistorizing(UA_Server *server, const UA_NodeId nodeId,
  229. UA_Boolean *outHistorizing) {
  230. return __UA_Server_read(server, &nodeId, UA_ATTRIBUTEID_HISTORIZING,
  231. outHistorizing);
  232. }
  233. static UA_INLINE UA_StatusCode
  234. UA_Server_readExecutable(UA_Server *server, const UA_NodeId nodeId,
  235. UA_Boolean *outExecutable) {
  236. return __UA_Server_read(server, &nodeId, UA_ATTRIBUTEID_EXECUTABLE,
  237. outExecutable);
  238. }
  239. /**
  240. * The following node attributes cannot be changed once a node has been created:
  241. *
  242. * - NodeClass
  243. * - NodeId
  244. * - Symmetric
  245. * - ContainsNoLoop
  246. *
  247. * The following attributes cannot be written from the server, as they are
  248. * specific to the different users and set by the access control callback:
  249. *
  250. * - UserWriteMask
  251. * - UserAccessLevel
  252. * - UserExecutable
  253. *
  254. * Historizing is currently unsupported */
  255. /* Overwrite an attribute of a node. The specialized functions below provide a
  256. * more concise syntax.
  257. *
  258. * @param server The server object.
  259. * @param value WriteValues contain the NodeId of the target node, the id of the
  260. * attribute to overwritten, the actual value and (optionally) an
  261. * index range to replace parts of an array only. of an array only.
  262. * See the section on NumericRange for the format used for array
  263. * ranges.
  264. * @return Returns a status code. */
  265. UA_StatusCode UA_EXPORT
  266. UA_Server_write(UA_Server *server, const UA_WriteValue *value);
  267. /* Don't use this function. There are typed versions with no additional
  268. * overhead. */
  269. UA_StatusCode UA_EXPORT
  270. __UA_Server_write(UA_Server *server, const UA_NodeId *nodeId,
  271. const UA_AttributeId attributeId,
  272. const UA_DataType *attr_type, const void *attr);
  273. static UA_INLINE UA_StatusCode
  274. UA_Server_writeBrowseName(UA_Server *server, const UA_NodeId nodeId,
  275. const UA_QualifiedName browseName) {
  276. return __UA_Server_write(server, &nodeId, UA_ATTRIBUTEID_BROWSENAME,
  277. &UA_TYPES[UA_TYPES_QUALIFIEDNAME], &browseName);
  278. }
  279. static UA_INLINE UA_StatusCode
  280. UA_Server_writeDisplayName(UA_Server *server, const UA_NodeId nodeId,
  281. const UA_LocalizedText displayName) {
  282. return __UA_Server_write(server, &nodeId, UA_ATTRIBUTEID_DISPLAYNAME,
  283. &UA_TYPES[UA_TYPES_LOCALIZEDTEXT], &displayName);
  284. }
  285. static UA_INLINE UA_StatusCode
  286. UA_Server_writeDescription(UA_Server *server, const UA_NodeId nodeId,
  287. const UA_LocalizedText description) {
  288. return __UA_Server_write(server, &nodeId, UA_ATTRIBUTEID_DESCRIPTION,
  289. &UA_TYPES[UA_TYPES_LOCALIZEDTEXT], &description);
  290. }
  291. static UA_INLINE UA_StatusCode
  292. UA_Server_writeWriteMask(UA_Server *server, const UA_NodeId nodeId,
  293. const UA_UInt32 writeMask) {
  294. return __UA_Server_write(server, &nodeId, UA_ATTRIBUTEID_WRITEMASK,
  295. &UA_TYPES[UA_TYPES_UINT32], &writeMask);
  296. }
  297. static UA_INLINE UA_StatusCode
  298. UA_Server_writeIsAbstract(UA_Server *server, const UA_NodeId nodeId,
  299. const UA_Boolean isAbstract) {
  300. return __UA_Server_write(server, &nodeId, UA_ATTRIBUTEID_ISABSTRACT,
  301. &UA_TYPES[UA_TYPES_BOOLEAN], &isAbstract);
  302. }
  303. static UA_INLINE UA_StatusCode
  304. UA_Server_writeInverseName(UA_Server *server, const UA_NodeId nodeId,
  305. const UA_LocalizedText inverseName) {
  306. return __UA_Server_write(server, &nodeId, UA_ATTRIBUTEID_INVERSENAME,
  307. &UA_TYPES[UA_TYPES_LOCALIZEDTEXT], &inverseName);
  308. }
  309. static UA_INLINE UA_StatusCode
  310. UA_Server_writeEventNotifier(UA_Server *server, const UA_NodeId nodeId,
  311. const UA_Byte eventNotifier) {
  312. return __UA_Server_write(server, &nodeId, UA_ATTRIBUTEID_EVENTNOTIFIER,
  313. &UA_TYPES[UA_TYPES_BYTE], &eventNotifier);
  314. }
  315. static UA_INLINE UA_StatusCode
  316. UA_Server_writeValue(UA_Server *server, const UA_NodeId nodeId,
  317. const UA_Variant value) {
  318. return __UA_Server_write(server, &nodeId, UA_ATTRIBUTEID_VALUE,
  319. &UA_TYPES[UA_TYPES_VARIANT], &value);
  320. }
  321. static UA_INLINE UA_StatusCode
  322. UA_Server_writeDataType(UA_Server *server, const UA_NodeId nodeId,
  323. const UA_NodeId dataType) {
  324. return __UA_Server_write(server, &nodeId, UA_ATTRIBUTEID_DATATYPE,
  325. &UA_TYPES[UA_TYPES_NODEID], &dataType);
  326. }
  327. static UA_INLINE UA_StatusCode
  328. UA_Server_writeValueRank(UA_Server *server, const UA_NodeId nodeId,
  329. const UA_Int32 valueRank) {
  330. return __UA_Server_write(server, &nodeId, UA_ATTRIBUTEID_VALUERANK,
  331. &UA_TYPES[UA_TYPES_INT32], &valueRank);
  332. }
  333. static UA_INLINE UA_StatusCode
  334. UA_Server_writeArrayDimensions(UA_Server *server, const UA_NodeId nodeId,
  335. const UA_Variant arrayDimensions) {
  336. return __UA_Server_write(server, &nodeId, UA_ATTRIBUTEID_VALUE,
  337. &UA_TYPES[UA_TYPES_VARIANT], &arrayDimensions);
  338. }
  339. static UA_INLINE UA_StatusCode
  340. UA_Server_writeAccessLevel(UA_Server *server, const UA_NodeId nodeId,
  341. const UA_Byte accessLevel) {
  342. return __UA_Server_write(server, &nodeId, UA_ATTRIBUTEID_ACCESSLEVEL,
  343. &UA_TYPES[UA_TYPES_BYTE], &accessLevel);
  344. }
  345. static UA_INLINE UA_StatusCode
  346. UA_Server_writeMinimumSamplingInterval(UA_Server *server, const UA_NodeId nodeId,
  347. const UA_Double miniumSamplingInterval) {
  348. return __UA_Server_write(server, &nodeId,
  349. UA_ATTRIBUTEID_MINIMUMSAMPLINGINTERVAL,
  350. &UA_TYPES[UA_TYPES_DOUBLE],
  351. &miniumSamplingInterval);
  352. }
  353. static UA_INLINE UA_StatusCode
  354. UA_Server_writeExecutable(UA_Server *server, const UA_NodeId nodeId,
  355. const UA_Boolean executable) {
  356. return __UA_Server_write(server, &nodeId, UA_ATTRIBUTEID_EXECUTABLE,
  357. &UA_TYPES[UA_TYPES_BOOLEAN], &executable); }
  358. /**
  359. * Browsing
  360. * -------- */
  361. UA_BrowseResult UA_EXPORT
  362. UA_Server_browse(UA_Server *server, UA_UInt32 maxrefs,
  363. const UA_BrowseDescription *descr);
  364. UA_BrowseResult UA_EXPORT
  365. UA_Server_browseNext(UA_Server *server, UA_Boolean releaseContinuationPoint,
  366. const UA_ByteString *continuationPoint);
  367. UA_BrowsePathResult UA_EXPORT
  368. UA_Server_translateBrowsePathToNodeIds(UA_Server *server,
  369. const UA_BrowsePath *browsePath);
  370. #ifndef HAVE_NODEITER_CALLBACK
  371. #define HAVE_NODEITER_CALLBACK
  372. /* Iterate over all nodes referenced by parentNodeId by calling the callback
  373. * function for each child node (in ifdef because GCC/CLANG handle include order
  374. * differently) */
  375. typedef UA_StatusCode
  376. (*UA_NodeIteratorCallback)(UA_NodeId childId, UA_Boolean isInverse,
  377. UA_NodeId referenceTypeId, void *handle);
  378. #endif
  379. UA_StatusCode UA_EXPORT
  380. UA_Server_forEachChildNodeCall(UA_Server *server, UA_NodeId parentNodeId,
  381. UA_NodeIteratorCallback callback, void *handle);
  382. #ifdef UA_ENABLE_DISCOVERY
  383. /**
  384. * Discovery
  385. * --------- */
  386. /* Register the given server instance at the discovery server.
  387. * This should be called periodically.
  388. * The semaphoreFilePath is optional. If the given file is deleted,
  389. * the server will automatically be unregistered. This could be
  390. * for example a pid file which is deleted if the server crashes.
  391. *
  392. * When the server shuts down you need to call unregister.
  393. *
  394. * @param server
  395. * @param discoveryServerUrl if set to NULL, the default value
  396. * 'opc.tcp://localhost:4840' will be used
  397. * @param semaphoreFilePath optional parameter pointing to semaphore file. */
  398. UA_StatusCode UA_EXPORT
  399. UA_Server_register_discovery(UA_Server *server, const char* discoveryServerUrl,
  400. const char* semaphoreFilePath);
  401. /* Unregister the given server instance from the discovery server.
  402. * This should only be called when the server is shutting down.
  403. * @param server
  404. * @param discoveryServerUrl if set to NULL, the default value
  405. * 'opc.tcp://localhost:4840' will be used */
  406. UA_StatusCode UA_EXPORT
  407. UA_Server_unregister_discovery(UA_Server *server, const char* discoveryServerUrl);
  408. /* Adds a periodic callback to register the server with the LDS (local discovery server)
  409. * periodically. The interval between each register call is given as second parameter.
  410. * It should be 10 minutes by default (= 10*60*1000).
  411. *
  412. * The delayFirstRegisterMs parameter indicates the delay for the first register call.
  413. * If it is 0, the first register call will be after intervalMs milliseconds,
  414. * otherwise the server's first register will be after delayFirstRegisterMs.
  415. *
  416. * When you manually unregister the server, you also need to cancel the
  417. * periodic callback, otherwise it will be automatically be registered again.
  418. *
  419. * If you call this method multiple times for the same discoveryServerUrl, the older
  420. * periodic callback will be removed.
  421. *
  422. * @param server
  423. * @param discoveryServerUrl if set to NULL, the default value
  424. * 'opc.tcp://localhost:4840' will be used
  425. * @param intervalMs
  426. * @param delayFirstRegisterMs
  427. * @param periodicCallbackId */
  428. UA_StatusCode UA_EXPORT
  429. UA_Server_addPeriodicServerRegisterCallback(UA_Server *server, const char* discoveryServerUrl,
  430. UA_UInt32 intervalMs,
  431. UA_UInt32 delayFirstRegisterMs,
  432. UA_UInt64 *periodicCallbackId);
  433. /* Callback for RegisterServer. Data is passed from the register call */
  434. typedef void (*UA_Server_registerServerCallback)(const UA_RegisteredServer *registeredServer,
  435. void* data);
  436. /* Set the callback which is called if another server registeres or unregisters
  437. * with this instance. If called multiple times, previous data will be
  438. * overwritten.
  439. *
  440. * @param server
  441. * @param cb the callback
  442. * @param data data passed to the callback
  443. * @return UA_STATUSCODE_SUCCESS on success */
  444. void UA_EXPORT
  445. UA_Server_setRegisterServerCallback(UA_Server *server, UA_Server_registerServerCallback cb,
  446. void* data);
  447. #ifdef UA_ENABLE_DISCOVERY_MULTICAST
  448. /* Callback for server detected through mDNS. Data is passed from the register
  449. * call
  450. *
  451. * @param isServerAnnounce indicates if the server has just been detected. If
  452. * set to false, this means the server is shutting down.
  453. * @param isTxtReceived indicates if we already received the corresponding TXT
  454. * record with the path and caps data */
  455. typedef void (*UA_Server_serverOnNetworkCallback)(const UA_ServerOnNetwork *serverOnNetwork,
  456. UA_Boolean isServerAnnounce,
  457. UA_Boolean isTxtReceived, void* data);
  458. /* Set the callback which is called if another server is found through mDNS or
  459. * deleted. It will be called for any mDNS message from the remote server, thus
  460. * it may be called multiple times for the same instance. Also the SRV and TXT
  461. * records may arrive later, therefore for the first call the server
  462. * capabilities may not be set yet. If called multiple times, previous data will
  463. * be overwritten.
  464. *
  465. * @param server
  466. * @param cb the callback
  467. * @param data data passed to the callback
  468. * @return UA_STATUSCODE_SUCCESS on success */
  469. void UA_EXPORT
  470. UA_Server_setServerOnNetworkCallback(UA_Server *server,
  471. UA_Server_serverOnNetworkCallback cb,
  472. void* data);
  473. #endif /* UA_ENABLE_DISCOVERY_MULTICAST */
  474. #endif /* UA_ENABLE_DISCOVERY */
  475. /**
  476. * Information Model Callbacks
  477. * ---------------------------
  478. *
  479. * There are three places where a callback from an information model to
  480. * user-defined code can happen.
  481. *
  482. * - Custom node constructors and destructors
  483. * - Linking VariableNodes with an external data source
  484. * - MethodNode callbacks
  485. *
  486. * .. _node-lifecycle:
  487. *
  488. * Node Lifecycle: Constructors, Destructors and Node Contexts
  489. * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  490. *
  491. * To finalize the instantiation of a node, a (user-defined) constructor
  492. * callback is executed. There can be both a global constructor for all nodes
  493. * and node-type constructor specific to the TypeDefinition of the new node
  494. * (attached to an ObjectTypeNode or VariableTypeNode).
  495. *
  496. * In the hierarchy of ObjectTypes and VariableTypes, only the constructor of
  497. * the (lowest) type defined for the new node is executed. Note that every
  498. * Object and Variable can have only one ``isTypeOf`` reference. But type-nodes
  499. * can technically have several ``hasSubType`` references to implement multiple
  500. * inheritance. Issues of (multiple) inheritance in the constructor need to be
  501. * solved by the user.
  502. *
  503. * When a node is destroyed, the node-type destructor is called before the
  504. * global destructor. So the overall node lifecycle is as follows:
  505. *
  506. * 1. Global Constructor (set in the server config)
  507. * 2. Node-Type Constructor (for VariableType or ObjectTypes)
  508. * 3. (Usage-period of the Node)
  509. * 4. Node-Type Destructor
  510. * 5. Global Destructor
  511. *
  512. * The constructor and destructor callbacks can be set to ``NULL`` and are not
  513. * used in that case. If the node-type constructor fails, the global destructor
  514. * will be called before removing the node. The destructors are assumed to never
  515. * fail.
  516. *
  517. * Every node carries a user-context and a constructor-context pointer. The
  518. * user-context is used to attach custom data to a node. But the (user-defined)
  519. * constructors and destructors may replace the user-context pointer if they
  520. * wish to do so. The initial value for the constructor-context is ``NULL``.
  521. * When the ``AddNodes`` service is used over the network, the user-context
  522. * pointer of the new node is also initially set to ``NULL``. */
  523. /* To be set in the server config. */
  524. typedef struct {
  525. /* Can be NULL. May replace the nodeContext */
  526. UA_StatusCode (*constructor)(UA_Server *server,
  527. const UA_NodeId *sessionId, void *sessionContext,
  528. const UA_NodeId *nodeId, void **nodeContext);
  529. /* Can be NULL. The context cannot be replaced since the node is destroyed
  530. * immediately afterwards anyway. */
  531. void (*destructor)(UA_Server *server,
  532. const UA_NodeId *sessionId, void *sessionContext,
  533. const UA_NodeId *nodeId, void *nodeContext);
  534. } UA_GlobalNodeLifecycle;
  535. typedef struct {
  536. /* Can be NULL. May replace the nodeContext */
  537. UA_StatusCode (*constructor)(UA_Server *server,
  538. const UA_NodeId *sessionId, void *sessionContext,
  539. const UA_NodeId *typeNodeId, void *typeNodeContext,
  540. const UA_NodeId *nodeId, void **nodeContext);
  541. /* Can be NULL. May replace the nodeContext. */
  542. void (*destructor)(UA_Server *server,
  543. const UA_NodeId *sessionId, void *sessionContext,
  544. const UA_NodeId *typeNodeId, void *typeNodeContext,
  545. const UA_NodeId *nodeId, void **nodeContext);
  546. } UA_NodeTypeLifecycle;
  547. UA_StatusCode UA_EXPORT
  548. UA_Server_setNodeTypeLifecycle(UA_Server *server, UA_NodeId nodeId,
  549. UA_NodeTypeLifecycle lifecycle);
  550. UA_StatusCode UA_EXPORT
  551. UA_Server_getNodeContext(UA_Server *server, UA_NodeId nodeId,
  552. void **nodeContext);
  553. /* Careful! The user has to ensure that the destructor callbacks still work. */
  554. UA_StatusCode UA_EXPORT
  555. UA_Server_setNodeContext(UA_Server *server, UA_NodeId nodeId,
  556. void *nodeContext);
  557. /**
  558. * .. _datasource:
  559. *
  560. * Data Source Callback
  561. * ^^^^^^^^^^^^^^^^^^^^
  562. *
  563. * The server has a unique way of dealing with the content of variables. Instead
  564. * of storing a variant attached to the variable node, the node can point to a
  565. * function with a local data provider. Whenever the value attribute is read,
  566. * the function will be called and asked to provide a UA_DataValue return value
  567. * that contains the value content and additional timestamps.
  568. *
  569. * It is expected that the read callback is implemented. The write callback can
  570. * be set to a null-pointer. */
  571. typedef struct {
  572. /* Copies the data from the source into the provided value.
  573. *
  574. * !! ZERO-COPY OPERATIONS POSSIBLE !!
  575. * It is not required to return a copy of the actual content data. You can
  576. * return a pointer to memory owned by the user. Memory can be reused
  577. * between read callbacks of a DataSource, as the result is already encoded
  578. * on the network buffer between each read operation.
  579. *
  580. * To use zero-copy reads, set the value of the `value->value` Variant
  581. * without copying, e.g. with `UA_Variant_setScalar`. Then, also set
  582. * `value->value.storageType` to `UA_VARIANT_DATA_NODELETE` to prevent the
  583. * memory being cleaned up. Don't forget to also set `value->hasValue` to
  584. * true to indicate the presence of a value.
  585. *
  586. * @param handle An optional pointer to user-defined data for the
  587. * specific data source
  588. * @param nodeid Id of the read node
  589. * @param includeSourceTimeStamp If true, then the datasource is expected to
  590. * set the source timestamp in the returned value
  591. * @param range If not null, then the datasource shall return only a
  592. * selection of the (nonscalar) data. Set
  593. * UA_STATUSCODE_BADINDEXRANGEINVALID in the value if this does not
  594. * apply.
  595. * @param value The (non-null) DataValue that is returned to the client. The
  596. * data source sets the read data, the result status and optionally a
  597. * sourcetimestamp.
  598. * @return Returns a status code for logging. Error codes intended for the
  599. * original caller are set in the value. If an error is returned,
  600. * then no releasing of the value is done. */
  601. UA_StatusCode (*read)(UA_Server *server, const UA_NodeId *sessionId,
  602. void *sessionContext, const UA_NodeId *nodeId,
  603. void *nodeContext, UA_Boolean includeSourceTimeStamp,
  604. const UA_NumericRange *range, UA_DataValue *value);
  605. /* Write into a data source. This method pointer can be NULL if the
  606. * operation is unsupported.
  607. *
  608. * @param handle An optional pointer to user-defined data for the
  609. * specific data source
  610. * @param nodeid Id of the node being written to
  611. * @param data The data to be written into the data source
  612. * @param range An optional data range. If the data source is scalar or does
  613. * not support writing of ranges, then an error code is returned.
  614. * @return Returns a status code that is returned to the user */
  615. UA_StatusCode (*write)(UA_Server *server, const UA_NodeId *sessionId,
  616. void *sessionContext, const UA_NodeId *nodeId,
  617. void *nodeContext, const UA_NumericRange *range,
  618. const UA_DataValue *value);
  619. } UA_DataSource;
  620. UA_StatusCode UA_EXPORT
  621. UA_Server_setVariableNode_dataSource(UA_Server *server, const UA_NodeId nodeId,
  622. const UA_DataSource dataSource);
  623. /**
  624. * .. _value-callback:
  625. *
  626. * Value Callback
  627. * ^^^^^^^^^^^^^^
  628. * Value Callbacks can be attached to variable and variable type nodes. If
  629. * not ``NULL``, they are called before reading and after writing respectively. */
  630. typedef struct {
  631. /* Called before the value attribute is read. It is possible to write into the
  632. * value attribute during onRead (using the write service). The node is
  633. * re-opened afterwards so that changes are considered in the following read
  634. * operation.
  635. *
  636. * @param handle Points to user-provided data for the callback.
  637. * @param nodeid The identifier of the node.
  638. * @param data Points to the current node value.
  639. * @param range Points to the numeric range the client wants to read from
  640. * (or NULL). */
  641. void (*onRead)(UA_Server *server, const UA_NodeId *sessionId,
  642. void *sessionContext, const UA_NodeId *nodeid,
  643. void *nodeContext, const UA_NumericRange *range,
  644. const UA_DataValue *value);
  645. /* Called after writing the value attribute. The node is re-opened after
  646. * writing so that the new value is visible in the callback.
  647. *
  648. * @param server The server executing the callback
  649. * @sessionId The identifier of the session
  650. * @sessionContext Additional data attached to the session
  651. * in the access control layer
  652. * @param nodeid The identifier of the node.
  653. * @param nodeUserContext Additional data attached to the node by
  654. * the user.
  655. * @param nodeConstructorContext Additional data attached to the node
  656. * by the type constructor(s).
  657. * @param range Points to the numeric range the client wants to write to (or
  658. * NULL). */
  659. void (*onWrite)(UA_Server *server, const UA_NodeId *sessionId,
  660. void *sessionContext, const UA_NodeId *nodeId,
  661. void *nodeContext, const UA_NumericRange *range,
  662. const UA_DataValue *data);
  663. } UA_ValueCallback;
  664. UA_StatusCode UA_EXPORT
  665. UA_Server_setVariableNode_valueCallback(UA_Server *server,
  666. const UA_NodeId nodeId,
  667. const UA_ValueCallback callback);
  668. /**
  669. * Method Callbacks
  670. * ^^^^^^^^^^^^^^^^
  671. * Method callbacks are set to `NULL` (not executable) when a method node is added
  672. * over the network. In theory, it is possible to add a callback via
  673. * ``UA_Server_setMethodNode_callback`` within the global constructor when adding
  674. * methods over the network is really wanted. */
  675. typedef UA_StatusCode
  676. (*UA_MethodCallback)(UA_Server *server, const UA_NodeId *sessionId,
  677. void *sessionContext, const UA_NodeId *methodId,
  678. void *methodContext, const UA_NodeId *objectId,
  679. void *objectContext, size_t inputSize,
  680. const UA_Variant *input, size_t outputSize,
  681. UA_Variant *output);
  682. #ifdef UA_ENABLE_METHODCALLS
  683. UA_StatusCode UA_EXPORT
  684. UA_Server_setMethodNode_callback(UA_Server *server,
  685. const UA_NodeId methodNodeId,
  686. UA_MethodCallback methodCallback);
  687. UA_CallMethodResult UA_EXPORT
  688. UA_Server_call(UA_Server *server, const UA_CallMethodRequest *request);
  689. #endif
  690. /**
  691. * .. _addnodes:
  692. *
  693. * Node Addition and Deletion
  694. * --------------------------
  695. * When creating dynamic node instances at runtime, chances are that you will
  696. * not care about the specific NodeId of the new node, as long as you can
  697. * reference it later. When passing numeric NodeIds with a numeric identifier 0,
  698. * the stack evaluates this as "select a random unassigned numeric NodeId in
  699. * that namespace". To find out which NodeId was actually assigned to the new
  700. * node, you may pass a pointer `outNewNodeId`, which will (after a successful
  701. * node insertion) contain the nodeId of the new node. You may also pass a
  702. * ``NULL`` pointer if this result is not needed.
  703. *
  704. * See the Section :ref:`node-lifecycle` on constructors and on attaching
  705. * user-defined data to nodes.
  706. *
  707. * The methods for node addition and deletion take mostly const arguments that
  708. * are not modified. When creating a node, a deep copy of the node identifier,
  709. * node attributes, etc. is created. Therefore, it is possible to call for
  710. * example ``UA_Server_addVariablenode`` with a value attribute (a
  711. * :ref:`variant`) pointing to a memory location on the stack. If you need
  712. * changes to a variable value to manifest at a specific memory location, please
  713. * use a :ref:`datasource` or a :ref:`value-callback`. */
  714. /* Protect against redundant definitions for server/client */
  715. #ifndef UA_DEFAULT_ATTRIBUTES_DEFINED
  716. #define UA_DEFAULT_ATTRIBUTES_DEFINED
  717. /* The default for variables is "BaseDataType" for the datatype, -2 for the
  718. * valuerank and a read-accesslevel. */
  719. UA_EXPORT extern const UA_VariableAttributes UA_VariableAttributes_default;
  720. UA_EXPORT extern const UA_VariableTypeAttributes UA_VariableTypeAttributes_default;
  721. /* Methods are executable by default */
  722. UA_EXPORT extern const UA_MethodAttributes UA_MethodAttributes_default;
  723. /* The remaining attribute definitions are currently all zeroed out */
  724. UA_EXPORT extern const UA_ObjectAttributes UA_ObjectAttributes_default;
  725. UA_EXPORT extern const UA_ObjectTypeAttributes UA_ObjectTypeAttributes_default;
  726. UA_EXPORT extern const UA_ReferenceTypeAttributes UA_ReferenceTypeAttributes_default;
  727. UA_EXPORT extern const UA_DataTypeAttributes UA_DataTypeAttributes_default;
  728. UA_EXPORT extern const UA_ViewAttributes UA_ViewAttributes_default;
  729. #endif
  730. /* Don't use this function. There are typed versions as inline functions. */
  731. UA_StatusCode UA_EXPORT
  732. __UA_Server_addNode(UA_Server *server, const UA_NodeClass nodeClass,
  733. const UA_NodeId *requestedNewNodeId,
  734. const UA_NodeId *parentNodeId,
  735. const UA_NodeId *referenceTypeId,
  736. const UA_QualifiedName browseName,
  737. const UA_NodeId *typeDefinition,
  738. const UA_NodeAttributes *attr,
  739. const UA_DataType *attributeType,
  740. void *nodeContext, UA_NodeId *outNewNodeId);
  741. static UA_INLINE UA_StatusCode
  742. UA_Server_addVariableNode(UA_Server *server, const UA_NodeId requestedNewNodeId,
  743. const UA_NodeId parentNodeId,
  744. const UA_NodeId referenceTypeId,
  745. const UA_QualifiedName browseName,
  746. const UA_NodeId typeDefinition,
  747. const UA_VariableAttributes attr,
  748. void *nodeContext, UA_NodeId *outNewNodeId) {
  749. return __UA_Server_addNode(server, UA_NODECLASS_VARIABLE, &requestedNewNodeId,
  750. &parentNodeId, &referenceTypeId, browseName,
  751. &typeDefinition, (const UA_NodeAttributes*)&attr,
  752. &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],
  753. nodeContext, outNewNodeId);
  754. }
  755. static UA_INLINE UA_StatusCode
  756. UA_Server_addVariableTypeNode(UA_Server *server,
  757. const UA_NodeId requestedNewNodeId,
  758. const UA_NodeId parentNodeId,
  759. const UA_NodeId referenceTypeId,
  760. const UA_QualifiedName browseName,
  761. const UA_NodeId typeDefinition,
  762. const UA_VariableTypeAttributes attr,
  763. void *nodeContext, UA_NodeId *outNewNodeId) {
  764. return __UA_Server_addNode(server, UA_NODECLASS_VARIABLETYPE,
  765. &requestedNewNodeId, &parentNodeId, &referenceTypeId,
  766. browseName, &typeDefinition,
  767. (const UA_NodeAttributes*)&attr,
  768. &UA_TYPES[UA_TYPES_VARIABLETYPEATTRIBUTES],
  769. nodeContext, outNewNodeId);
  770. }
  771. static UA_INLINE UA_StatusCode
  772. UA_Server_addObjectNode(UA_Server *server, const UA_NodeId requestedNewNodeId,
  773. const UA_NodeId parentNodeId,
  774. const UA_NodeId referenceTypeId,
  775. const UA_QualifiedName browseName,
  776. const UA_NodeId typeDefinition,
  777. const UA_ObjectAttributes attr,
  778. void *nodeContext, UA_NodeId *outNewNodeId) {
  779. return __UA_Server_addNode(server, UA_NODECLASS_OBJECT, &requestedNewNodeId,
  780. &parentNodeId, &referenceTypeId, browseName,
  781. &typeDefinition, (const UA_NodeAttributes*)&attr,
  782. &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],
  783. nodeContext, outNewNodeId);
  784. }
  785. static UA_INLINE UA_StatusCode
  786. UA_Server_addObjectTypeNode(UA_Server *server, const UA_NodeId requestedNewNodeId,
  787. const UA_NodeId parentNodeId,
  788. const UA_NodeId referenceTypeId,
  789. const UA_QualifiedName browseName,
  790. const UA_ObjectTypeAttributes attr,
  791. void *nodeContext, UA_NodeId *outNewNodeId) {
  792. return __UA_Server_addNode(server, UA_NODECLASS_OBJECTTYPE, &requestedNewNodeId,
  793. &parentNodeId, &referenceTypeId, browseName,
  794. &UA_NODEID_NULL, (const UA_NodeAttributes*)&attr,
  795. &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES],
  796. nodeContext, outNewNodeId);
  797. }
  798. static UA_INLINE UA_StatusCode
  799. UA_Server_addViewNode(UA_Server *server, const UA_NodeId requestedNewNodeId,
  800. const UA_NodeId parentNodeId,
  801. const UA_NodeId referenceTypeId,
  802. const UA_QualifiedName browseName,
  803. const UA_ViewAttributes attr,
  804. void *nodeContext, UA_NodeId *outNewNodeId) {
  805. return __UA_Server_addNode(server, UA_NODECLASS_VIEW, &requestedNewNodeId,
  806. &parentNodeId, &referenceTypeId, browseName,
  807. &UA_NODEID_NULL, (const UA_NodeAttributes*)&attr,
  808. &UA_TYPES[UA_TYPES_VIEWATTRIBUTES],
  809. nodeContext, outNewNodeId);
  810. }
  811. static UA_INLINE UA_StatusCode
  812. UA_Server_addReferenceTypeNode(UA_Server *server,
  813. const UA_NodeId requestedNewNodeId,
  814. const UA_NodeId parentNodeId,
  815. const UA_NodeId referenceTypeId,
  816. const UA_QualifiedName browseName,
  817. const UA_ReferenceTypeAttributes attr,
  818. void *nodeContext, UA_NodeId *outNewNodeId) {
  819. return __UA_Server_addNode(server, UA_NODECLASS_REFERENCETYPE,
  820. &requestedNewNodeId, &parentNodeId, &referenceTypeId,
  821. browseName, &UA_NODEID_NULL,
  822. (const UA_NodeAttributes*)&attr,
  823. &UA_TYPES[UA_TYPES_REFERENCETYPEATTRIBUTES],
  824. nodeContext, outNewNodeId);
  825. }
  826. static UA_INLINE UA_StatusCode
  827. UA_Server_addDataTypeNode(UA_Server *server,
  828. const UA_NodeId requestedNewNodeId,
  829. const UA_NodeId parentNodeId,
  830. const UA_NodeId referenceTypeId,
  831. const UA_QualifiedName browseName,
  832. const UA_DataTypeAttributes attr,
  833. void *nodeContext, UA_NodeId *outNewNodeId) {
  834. return __UA_Server_addNode(server, UA_NODECLASS_DATATYPE, &requestedNewNodeId,
  835. &parentNodeId, &referenceTypeId, browseName,
  836. &UA_NODEID_NULL, (const UA_NodeAttributes*)&attr,
  837. &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],
  838. nodeContext, outNewNodeId);
  839. }
  840. UA_StatusCode UA_EXPORT
  841. UA_Server_addDataSourceVariableNode(UA_Server *server,
  842. const UA_NodeId requestedNewNodeId,
  843. const UA_NodeId parentNodeId,
  844. const UA_NodeId referenceTypeId,
  845. const UA_QualifiedName browseName,
  846. const UA_NodeId typeDefinition,
  847. const UA_VariableAttributes attr,
  848. const UA_DataSource dataSource,
  849. void *nodeContext, UA_NodeId *outNewNodeId);
  850. UA_StatusCode UA_EXPORT
  851. UA_Server_addMethodNodeEx(UA_Server *server, const UA_NodeId requestedNewNodeId,
  852. const UA_NodeId parentNodeId,
  853. const UA_NodeId referenceTypeId,
  854. const UA_QualifiedName browseName,
  855. const UA_MethodAttributes attr, UA_MethodCallback method,
  856. size_t inputArgumentsSize, const UA_Argument *inputArguments,
  857. const UA_NodeId inputArgumentsRequestedNewNodeId,
  858. UA_NodeId *inputArgumentsOutNewNodeId,
  859. size_t outputArgumentsSize, const UA_Argument *outputArguments,
  860. const UA_NodeId outputArgumentsRequestedNewNodeId,
  861. UA_NodeId *outputArgumentsOutNewNodeId,
  862. void *nodeContext, UA_NodeId *outNewNodeId);
  863. static UA_INLINE UA_StatusCode
  864. UA_Server_addMethodNode(UA_Server *server, const UA_NodeId requestedNewNodeId,
  865. const UA_NodeId parentNodeId, const UA_NodeId referenceTypeId,
  866. const UA_QualifiedName browseName, const UA_MethodAttributes attr,
  867. UA_MethodCallback method,
  868. size_t inputArgumentsSize, const UA_Argument *inputArguments,
  869. size_t outputArgumentsSize, const UA_Argument *outputArguments,
  870. void *nodeContext, UA_NodeId *outNewNodeId) {
  871. return UA_Server_addMethodNodeEx(server, requestedNewNodeId, parentNodeId,
  872. referenceTypeId, browseName, attr, method,
  873. inputArgumentsSize, inputArguments, UA_NODEID_NULL, NULL,
  874. outputArgumentsSize, outputArguments, UA_NODEID_NULL, NULL,
  875. nodeContext, outNewNodeId);
  876. }
  877. /**
  878. * The method pair UA_Server_addNode_begin and _finish splits the AddNodes
  879. * service in two parts. This is useful if the node shall be modified before
  880. * finish the instantiation. For example to add children with specific NodeIds.
  881. * Otherwise, mandatory children (e.g. of an ObjectType) are added with
  882. * pseudo-random unique NodeIds. Existing children are detected during the
  883. * _finish part via their matching BrowseName.
  884. *
  885. * The _begin method:
  886. * - prepares the node and adds it to the nodestore
  887. * - copies some unassigned attributes from the TypeDefinition node internally
  888. * - adds the references to the parent (and the TypeDefinition if applicable)
  889. * - performs type-checking of variables.
  890. *
  891. * You can add an object node without a parent if you set the parentNodeId and
  892. * referenceTypeId to UA_NODE_ID_NULL. Then you need to add the parent reference
  893. * and hasTypeDef reference yourself before calling the _finish method.
  894. * Not that this is only allowed for object nodes.
  895. *
  896. * The _finish method:
  897. * - copies mandatory children
  898. * - calls the node constructor(s) at the end
  899. * - may remove the node if it encounters an error.
  900. *
  901. * The special UA_Server_addMethodNode_finish method needs to be used for
  902. * method nodes, since there you need to explicitly specifiy the input
  903. * and output arguments which are added in the finish step (if not yet already there)
  904. **/
  905. /* The ``attr`` argument must have a type according to the NodeClass.
  906. * ``VariableAttributes`` for variables, ``ObjectAttributes`` for objects, and
  907. * so on. Missing attributes are taken from the TypeDefinition node if
  908. * applicable. */
  909. UA_StatusCode UA_EXPORT
  910. UA_Server_addNode_begin(UA_Server *server, const UA_NodeClass nodeClass,
  911. const UA_NodeId requestedNewNodeId,
  912. const UA_NodeId parentNodeId,
  913. const UA_NodeId referenceTypeId,
  914. const UA_QualifiedName browseName,
  915. const UA_NodeId typeDefinition,
  916. const void *attr, const UA_DataType *attributeType,
  917. void *nodeContext, UA_NodeId *outNewNodeId);
  918. UA_StatusCode UA_EXPORT
  919. UA_Server_addNode_finish(UA_Server *server, const UA_NodeId nodeId);
  920. UA_StatusCode UA_EXPORT
  921. UA_Server_addMethodNode_finish(UA_Server *server, const UA_NodeId nodeId,
  922. UA_MethodCallback method,
  923. size_t inputArgumentsSize, const UA_Argument* inputArguments,
  924. size_t outputArgumentsSize, const UA_Argument* outputArguments);
  925. /* Deletes a node and optionally all references leading to the node. */
  926. UA_StatusCode UA_EXPORT
  927. UA_Server_deleteNode(UA_Server *server, const UA_NodeId nodeId,
  928. UA_Boolean deleteReferences);
  929. /**
  930. * Reference Management
  931. * -------------------- */
  932. UA_StatusCode UA_EXPORT
  933. UA_Server_addReference(UA_Server *server, const UA_NodeId sourceId,
  934. const UA_NodeId refTypeId,
  935. const UA_ExpandedNodeId targetId, UA_Boolean isForward);
  936. UA_StatusCode UA_EXPORT
  937. UA_Server_deleteReference(UA_Server *server, const UA_NodeId sourceNodeId,
  938. const UA_NodeId referenceTypeId, UA_Boolean isForward,
  939. const UA_ExpandedNodeId targetNodeId,
  940. UA_Boolean deleteBidirectional);
  941. /**
  942. * Utility Functions
  943. * ----------------- */
  944. /* Add a new namespace to the server. Returns the index of the new namespace */
  945. UA_UInt16 UA_EXPORT UA_Server_addNamespace(UA_Server *server, const char* name);
  946. /**
  947. * Deprecated Server API
  948. * ---------------------
  949. * This file contains outdated API definitions that are kept for backwards
  950. * compatibility. Please switch to the new API, as the following definitions
  951. * will be removed eventually.
  952. *
  953. * UA_Job API
  954. * ^^^^^^^^^^
  955. * UA_Job was replaced since it unnecessarily exposed server internals to the
  956. * end-user. Please use plain UA_ServerCallbacks instead. The following UA_Job
  957. * definition contains just the fraction of the original struct that was useful
  958. * to end-users. */
  959. typedef enum {
  960. UA_JOBTYPE_METHODCALL
  961. } UA_JobType;
  962. typedef struct {
  963. UA_JobType type;
  964. union {
  965. struct {
  966. void *data;
  967. UA_ServerCallback method;
  968. } methodCall;
  969. } job;
  970. } UA_Job;
  971. UA_DEPRECATED static UA_INLINE UA_StatusCode
  972. UA_Server_addRepeatedJob(UA_Server *server, UA_Job job,
  973. UA_UInt32 interval, UA_Guid *jobId) {
  974. return UA_Server_addRepeatedCallback(server, job.job.methodCall.method,
  975. job.job.methodCall.data, interval,
  976. (UA_UInt64*)(uintptr_t)jobId);
  977. }
  978. UA_DEPRECATED static UA_INLINE UA_StatusCode
  979. UA_Server_removeRepeatedJob(UA_Server *server, UA_Guid jobId) {
  980. return UA_Server_removeRepeatedCallback(server,
  981. *(UA_UInt64*)(uintptr_t)&jobId);
  982. }
  983. #ifdef __cplusplus
  984. }
  985. #endif
  986. #endif /* UA_SERVER_H_ */