opcuaServerDataSource.c 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. /*
  2. * This work is licensed under a Creative Commons CCZero 1.0 Universal License.
  3. * See http://creativecommons.org/publicdomain/zero/1.0/ for more information.
  4. */
  5. #include <time.h>
  6. #include "ua_types.h"
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <signal.h>
  10. #include <errno.h> // errno, EINTR
  11. // provided by the open62541 lib
  12. #include "ua_server.h"
  13. // provided by the user, implementations available in the /examples folder
  14. #include "logger_stdout.h"
  15. #include "networklayer_tcp.h"
  16. // data source
  17. static UA_StatusCode readTimeData(const void *handle, UA_VariantData* data) {
  18. UA_DateTime *currentTime = UA_DateTime_new();
  19. if(!currentTime)
  20. return UA_STATUSCODE_BADOUTOFMEMORY;
  21. *currentTime = UA_DateTime_now();
  22. data->arrayLength = 1;
  23. data->dataPtr = currentTime;
  24. data->arrayDimensionsSize = -1;
  25. data->arrayDimensions = UA_NULL;
  26. return UA_STATUSCODE_GOOD;
  27. }
  28. static void releaseTimeData(const void *handle, UA_VariantData* data) {
  29. UA_DateTime_delete((UA_DateTime*)data->dataPtr);
  30. }
  31. static void destroyTimeDataSource(const void *handle) {
  32. return;
  33. }
  34. UA_Boolean running = 1;
  35. static void stopHandler(int sign) {
  36. printf("Received Ctrl-C\n");
  37. running = 0;
  38. }
  39. int main(int argc, char** argv) {
  40. signal(SIGINT, stopHandler); /* catches ctrl-c */
  41. UA_Server *server = UA_Server_new();
  42. UA_Server_addNetworkLayer(server, ServerNetworkLayerTCP_new(UA_ConnectionConfig_standard, 16664));
  43. // add node with a callback to the userspace
  44. UA_Variant *myDateTimeVariant = UA_Variant_new();
  45. myDateTimeVariant->storageType = UA_VARIANT_DATASOURCE;
  46. myDateTimeVariant->storage.datasource = (UA_VariantDataSource)
  47. {.handle = UA_NULL, .read = readTimeData, .release = releaseTimeData,
  48. .write = (UA_StatusCode (*)(const void*, const UA_VariantData*))UA_NULL,
  49. .destroy = destroyTimeDataSource};
  50. myDateTimeVariant->type = &UA_TYPES[UA_TYPES_DATETIME];
  51. myDateTimeVariant->typeId = UA_NODEID_STATIC(UA_TYPES_IDS[UA_TYPES_DATETIME],0);
  52. UA_QualifiedName myDateTimeName;
  53. UA_QUALIFIEDNAME_ASSIGN(myDateTimeName, "the time");
  54. UA_Server_addVariableNode(server, myDateTimeVariant, &UA_NODEID_NULL, &myDateTimeName,
  55. &UA_NODEID_STATIC(UA_NS0ID_OBJECTSFOLDER,0),
  56. &UA_NODEID_STATIC(UA_NS0ID_ORGANIZES,0));
  57. UA_StatusCode retval = UA_Server_run(server, 1, &running);
  58. UA_Server_delete(server);
  59. return retval;
  60. }