testing_networklayers.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. #include <unistd.h>
  2. #include <fcntl.h>
  3. #include <malloc.h>
  4. #include <assert.h>
  5. #include "testing_networklayers.h"
  6. typedef struct {
  7. UA_Connection connection;
  8. UA_UInt32 files;
  9. char **filenames;
  10. UA_UInt32 files_read;
  11. void (*writeCallback)(void *, UA_ByteStringArray 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, UA_ByteStringArray gather_buf) {
  17. handle->writeCallback(handle->callbackHandle, gather_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_BINARYNETWORKMESSAGE;
  47. work->work.binaryNetworkMessage.connection = &layer->connection;
  48. work->work.binaryNetworkMessage.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. UA_ServerNetworkLayer
  60. ServerNetworkLayerFileInput_new(UA_UInt32 files, char **filenames, void(*readCallback)(void),
  61. void(*writeCallback) (void*, UA_ByteStringArray buf),
  62. void *callbackHandle)
  63. {
  64. NetworkLayer_FileInput *layer = malloc(sizeof(NetworkLayer_FileInput));
  65. layer->connection.state = UA_CONNECTION_OPENING;
  66. layer->connection.localConf = UA_ConnectionConfig_standard;
  67. layer->connection.channel = (void*)0;
  68. layer->connection.close = (void (*)(UA_Connection*))closeCallback;
  69. layer->connection.write = (UA_StatusCode (*)(UA_Connection*, UA_ByteStringArray))writeCallback;
  70. layer->files = files;
  71. layer->filenames = filenames;
  72. layer->files_read = 0;
  73. layer->readCallback = readCallback;
  74. layer->writeCallback = writeCallback;
  75. layer->callbackHandle = callbackHandle;
  76. UA_ServerNetworkLayer nl;
  77. nl.nlHandle = layer;
  78. nl.start = (UA_StatusCode (*)(void*, UA_Logger *logger))NetworkLayer_FileInput_start;
  79. nl.getWork = (UA_Int32 (*)(void*, UA_WorkItem**, UA_UInt16)) NetworkLayer_FileInput_getWork;
  80. nl.stop = (UA_Int32 (*)(void*, UA_WorkItem**)) NetworkLayer_FileInput_stop;
  81. nl.free = (void (*)(void*))NetworkLayer_FileInput_delete;
  82. nl.discoveryUrl = UA_String_new();
  83. *nl.discoveryUrl = UA_STRING_ALLOC("");
  84. return nl;
  85. }