testing_networklayers.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. #include <unistd.h>
  2. #include <fcntl.h>
  3. #include <malloc.h>
  4. #include <assert.h>
  5. #include "testing_networklayers.h"
  6. typedef struct NetworkLayer_FileInput {
  7. UA_Connection connection;
  8. UA_UInt32 files;
  9. char **filenames;
  10. UA_UInt32 files_read;
  11. UA_StatusCode (*writeCallback)(struct NetworkLayer_FileInput *handle, const UA_ByteString *buf);
  12. void (*readCallback)(void);
  13. void *callbackHandle;
  14. } NetworkLayer_FileInput;
  15. /** Accesses only the sockfd in the handle. Can be run from parallel threads. */
  16. static UA_StatusCode writeCallback(NetworkLayer_FileInput *handle, const UA_ByteString *buf) {
  17. handle->writeCallback(handle->callbackHandle, buf);
  18. return UA_STATUSCODE_GOOD;
  19. }
  20. static void closeCallback(NetworkLayer_FileInput *handle) {
  21. }
  22. static UA_StatusCode NetworkLayer_FileInput_start(NetworkLayer_FileInput *layer, UA_Logger *logger) {
  23. return UA_STATUSCODE_GOOD;
  24. }
  25. static UA_Int32
  26. NetworkLayer_FileInput_getWork(NetworkLayer_FileInput *layer, UA_WorkItem **workItems, UA_UInt16 timeout)
  27. {
  28. layer->readCallback();
  29. // open a new connection
  30. // return a single buffer with the entire file
  31. if(layer->files >= layer->files_read)
  32. return 0;
  33. int filefd = open(layer->filenames[layer->files_read], O_RDONLY);
  34. layer->files_read++;
  35. if(filefd == -1)
  36. return 0;
  37. UA_Byte *buf = malloc(layer->connection.localConf.maxMessageSize);
  38. UA_Int32 bytes_read = read(filefd, buf, layer->connection.localConf.maxMessageSize);
  39. close(filefd);
  40. if(bytes_read <= 0) {
  41. free(buf);
  42. return 0;
  43. }
  44. *workItems = malloc(sizeof(UA_WorkItem));
  45. UA_WorkItem *work = *workItems;
  46. work->type = UA_WORKITEMTYPE_BINARYMESSAGE;
  47. work->work.binaryMessage.connection = &layer->connection;
  48. work->work.binaryMessage.message = (UA_ByteString){.length = bytes_read, .data = (UA_Byte*)buf};
  49. return 1;
  50. }
  51. static UA_Int32 NetworkLayer_FileInput_stop(NetworkLayer_FileInput * layer, UA_WorkItem **workItems) {
  52. // remove the connection in the server
  53. // return removeAllConnections(layer, workItems);
  54. return 0;
  55. }
  56. static void NetworkLayer_FileInput_delete(NetworkLayer_FileInput *layer) {
  57. free(layer);
  58. }
  59. static UA_StatusCode NetworkLayer_FileInput_getBuffer(UA_Connection *connection, UA_ByteString *buf, size_t minSize) {
  60. buf->data = malloc(minSize);
  61. if(!buf->data)
  62. return UA_STATUSCODE_BADOUTOFMEMORY;
  63. buf->length = minSize;
  64. return UA_STATUSCODE_GOOD;
  65. }
  66. static void NetworkLayer_FileInput_releaseBuffer(UA_Connection *connection, UA_ByteString *buf) {
  67. UA_ByteString_deleteMembers(buf);
  68. }
  69. UA_ServerNetworkLayer
  70. ServerNetworkLayerFileInput_new(UA_UInt32 files, char **filenames, void(*readCallback)(void),
  71. UA_StatusCode (*writeCallback) (void*, UA_ByteString *buf),
  72. void *callbackHandle)
  73. {
  74. NetworkLayer_FileInput *layer = malloc(sizeof(NetworkLayer_FileInput));
  75. layer->connection.state = UA_CONNECTION_OPENING;
  76. layer->connection.localConf = UA_ConnectionConfig_standard;
  77. layer->connection.channel = (void*)0;
  78. layer->connection.close = (void (*)(UA_Connection*))closeCallback;
  79. layer->connection.write = (UA_StatusCode (*)(UA_Connection*, const UA_ByteString*))writeCallback;
  80. layer->connection.releaseBuffer = NetworkLayer_FileInput_releaseBuffer;
  81. layer->connection.getBuffer = NetworkLayer_FileInput_getBuffer;
  82. layer->files = files;
  83. layer->filenames = filenames;
  84. layer->files_read = 0;
  85. layer->readCallback = readCallback;
  86. layer->writeCallback = (UA_StatusCode(*)(struct NetworkLayer_FileInput *handle, const UA_ByteString *buf)) writeCallback;
  87. layer->callbackHandle = callbackHandle;
  88. UA_ServerNetworkLayer nl;
  89. nl.nlHandle = layer;
  90. nl.start = (UA_StatusCode (*)(void*, UA_Logger *logger))NetworkLayer_FileInput_start;
  91. nl.getWork = (UA_Int32 (*)(void*, UA_WorkItem**, UA_UInt16)) NetworkLayer_FileInput_getWork;
  92. nl.stop = (UA_Int32 (*)(void*, UA_WorkItem**)) NetworkLayer_FileInput_stop;
  93. nl.free = (void (*)(void*))NetworkLayer_FileInput_delete;
  94. nl.discoveryUrl = UA_String_new();
  95. *nl.discoveryUrl = UA_STRING_ALLOC("");
  96. return nl;
  97. }