testing_networklayers.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  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 void writeCallback(NetworkLayer_FileInput *handle, UA_ByteStringArray gather_buf) {
  17. handle->writeCallback(handle->callbackHandle, gather_buf);
  18. }
  19. static void closeCallback(NetworkLayer_FileInput *handle) {
  20. }
  21. static UA_StatusCode NetworkLayer_FileInput_start(NetworkLayer_FileInput *layer, UA_Logger *logger) {
  22. return UA_STATUSCODE_GOOD;
  23. }
  24. static UA_Int32
  25. NetworkLayer_FileInput_getWork(NetworkLayer_FileInput *layer, UA_WorkItem **workItems, UA_UInt16 timeout)
  26. {
  27. layer->readCallback();
  28. // open a new connection
  29. // return a single buffer with the entire file
  30. if(layer->files >= layer->files_read)
  31. return 0;
  32. int filefd = open(layer->filenames[layer->files_read], O_RDONLY);
  33. layer->files_read++;
  34. if(filefd == -1)
  35. return 0;
  36. UA_Byte *buf = malloc(layer->connection.localConf.maxMessageSize);
  37. UA_Int32 bytes_read = read(filefd, buf, layer->connection.localConf.maxMessageSize);
  38. close(filefd);
  39. if(bytes_read <= 0) {
  40. free(buf);
  41. return 0;
  42. }
  43. *workItems = malloc(sizeof(UA_WorkItem));
  44. UA_WorkItem *work = *workItems;
  45. work->type = UA_WORKITEMTYPE_BINARYNETWORKMESSAGE;
  46. work->work.binaryNetworkMessage.connection = &layer->connection;
  47. work->work.binaryNetworkMessage.message = (UA_ByteString){.length = bytes_read, .data = (UA_Byte*)buf};
  48. return 1;
  49. }
  50. static UA_Int32 NetworkLayer_FileInput_stop(NetworkLayer_FileInput * layer, UA_WorkItem **workItems) {
  51. // remove the connection in the server
  52. // return removeAllConnections(layer, workItems);
  53. return 0;
  54. }
  55. static void NetworkLayer_FileInput_delete(NetworkLayer_FileInput *layer) {
  56. free(layer);
  57. }
  58. UA_ServerNetworkLayer
  59. ServerNetworkLayerFileInput_new(UA_UInt32 files, char **filenames, void(*readCallback)(void),
  60. void(*writeCallback) (void*, UA_ByteStringArray buf),
  61. void *callbackHandle)
  62. {
  63. NetworkLayer_FileInput *layer = malloc(sizeof(NetworkLayer_FileInput));
  64. layer->connection.state = UA_CONNECTION_OPENING;
  65. layer->connection.localConf = UA_ConnectionConfig_standard;
  66. layer->connection.channel = (void*)0;
  67. layer->connection.close = (void (*)(void*))closeCallback;
  68. layer->connection.write = (void (*)(void*, UA_ByteStringArray))writeCallback;
  69. layer->files = files;
  70. layer->filenames = filenames;
  71. layer->files_read = 0;
  72. layer->readCallback = readCallback;
  73. layer->writeCallback = writeCallback;
  74. layer->callbackHandle = callbackHandle;
  75. UA_ServerNetworkLayer nl;
  76. nl.nlHandle = layer;
  77. nl.start = (UA_StatusCode (*)(void*, UA_Logger *logger))NetworkLayer_FileInput_start;
  78. nl.getWork = (UA_Int32 (*)(void*, UA_WorkItem**, UA_UInt16)) NetworkLayer_FileInput_getWork;
  79. nl.stop = (UA_Int32 (*)(void*, UA_WorkItem**)) NetworkLayer_FileInput_stop;
  80. nl.free = (void (*)(void*))NetworkLayer_FileInput_delete;
  81. nl.discoveryUrl = UA_String_new();
  82. *nl.discoveryUrl = UA_STRING_ALLOC("");
  83. return nl;
  84. }