Minos.EnetStreams.Mod 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. MODULE EnetStreams;
  2. (**
  3. AUTHOR: Timothée Martiel, HighDim GmbH, 2015
  4. PURPOSE: Ethernet networking stack stream interface for MINOS
  5. *)
  6. IMPORT
  7. SYSTEM,
  8. StreamReaders, StreamWriters,
  9. EnetBase, EnetInterfaces;
  10. TYPE
  11. Reader * = POINTER TO ReaderDesc;
  12. ReaderDesc * = RECORD (StreamReaders.Reader)
  13. enetAccess *: ANY;
  14. enetPackets *: EnetBase.PacketFifo;
  15. enetPacket: EnetBase.Packet;
  16. enetPacketOffset: EnetBase.Int;
  17. enetEndOfStream *: BOOLEAN;
  18. END;
  19. Sender * = PROCEDURE (access: ANY; CONST buf: ARRAY OF CHAR; ofs, len: EnetBase.Int; flags: SET; VAR res: EnetBase.Int);
  20. Writer * = POINTER TO WriterDesc;
  21. WriterDesc * = RECORD (StreamWriters.Writer)
  22. enetAccess: ANY;
  23. enetFlags: SET;
  24. enetSend: Sender;
  25. END;
  26. PROCEDURE InitReader * (VAR reader: ReaderDesc; bufferSize: EnetBase.Int; access: ANY);
  27. BEGIN
  28. StreamReaders.Init(reader, Receive, bufferSize);
  29. reader.enetAccess := access;
  30. reader.enetPackets := EnetBase.NewPacketFifo(10);
  31. reader.enetPacketOffset := 0;
  32. reader.enetEndOfStream := FALSE
  33. END InitReader;
  34. PROCEDURE InitWriter * (VAR writer: WriterDesc; bufferSize: EnetBase.Int; access: ANY; flags: SET; sender: Sender);
  35. BEGIN
  36. StreamWriters.Init(writer, Send, bufferSize);
  37. writer.enetAccess := access;
  38. writer.enetFlags := flags;
  39. writer.enetSend := sender
  40. END InitWriter;
  41. PROCEDURE Receive * (VAR reader: StreamReaders.Reader; VAR buf: ARRAY OF CHAR; ofs, size, min: EnetBase.Int; VAR len, res: EnetBase.Int);
  42. VAR
  43. packet: EnetBase.Packet;
  44. pktOfs, cpLen: EnetBase.Int;
  45. BEGIN
  46. WITH reader: ReaderDesc DO
  47. packet := reader.enetPacket;
  48. len := 0;
  49. LOOP
  50. IF res > 0 THEN EXIT
  51. ELSIF size = 0 THEN EXIT
  52. ELSIF (packet = NIL) THEN
  53. REPEAT
  54. IF ~EnetInterfaces.UpdateAll(res) THEN EXIT END
  55. UNTIL EnetBase.PacketFifoGet(reader.enetPackets, packet) OR reader.enetEndOfStream OR (len >= min);
  56. IF res # 0 THEN EXIT
  57. ELSIF reader.enetEndOfStream & (packet = NIL) THEN
  58. reader.enetPacket := NIL;
  59. IF len = 0 THEN res := StreamReaders.EOF END;
  60. EXIT
  61. ELSIF (packet = NIL) & (len >= min) THEN
  62. reader.enetPacket := NIL;
  63. EXIT
  64. ELSE
  65. reader.enetPacketOffset := 0
  66. END;
  67. ASSERT(packet # NIL)
  68. ELSE
  69. pktOfs := packet.dataOffs + packet.payloadOffs + reader.enetPacketOffset;
  70. cpLen := MIN(size, packet.dataLen - packet.payloadOffs - reader.enetPacketOffset);
  71. SYSTEM.MOVE(ADDRESSOF(packet.data[pktOfs]), ADDRESSOF(buf[ofs]), cpLen);
  72. DEC(size, cpLen);
  73. INC(ofs, cpLen);
  74. INC(len, cpLen);
  75. IF cpLen = packet.dataLen - packet.payloadOffs - reader.enetPacketOffset THEN
  76. reader.enetPacketOffset := 0;
  77. packet.ownedByUser := FALSE;
  78. IF ~EnetBase.ReturnPacketToOwnerPool(packet) THEN res := -1; EXIT END;
  79. packet := NIL;
  80. ELSE
  81. reader.enetPacket := packet;
  82. reader.enetPacketOffset := cpLen + pktOfs - packet.dataOffs - packet.payloadOffs;
  83. EXIT
  84. END
  85. END
  86. END
  87. END
  88. END Receive;
  89. PROCEDURE Send (VAR writer: StreamWriters.Writer; CONST buf: ARRAY OF CHAR; ofs, len: EnetBase.Int; propagate: BOOLEAN; VAR res: EnetBase.Int);
  90. BEGIN
  91. WITH writer: WriterDesc DO
  92. writer.enetSend(writer.enetAccess, buf, ofs, len, writer.enetFlags, res)
  93. END;
  94. IF res = EnetBase.OpInProgress THEN res := StreamWriters.Ok END
  95. END Send;
  96. END EnetStreams.