OEBSerialInterfaces.Mod 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. MODULE OEBSerialInterfaces;
  2. (**
  3. AUTHOR Timothée Martiel, 05/2016
  4. PURPOSE OEB Server Interface for Serial devices
  5. *)
  6. IMPORT
  7. Modules, Strings, Serials, Streams,
  8. OEBInterfaces;
  9. CONST
  10. MaxLineSize = 128;
  11. TYPE
  12. Interface * = OBJECT (OEBInterfaces.Interface)
  13. VAR
  14. lines: ARRAY Serials.MaxPorts OF Line;
  15. readers: ARRAY Serials.MaxPorts OF Streams.Reader;
  16. writers: ARRAY Serials.MaxPorts OF Streams.Writer;
  17. PROCEDURE & Init *;
  18. BEGIN
  19. InitInterface("Serial", "SerialInterface")
  20. END Init;
  21. PROCEDURE Send * (session: OEBInterfaces.Session; CONST cmd: ARRAY OF CHAR): BOOLEAN;
  22. VAR
  23. writer: Streams.Writer;
  24. BEGIN
  25. writer := writers[session(Session).port];
  26. writer.String(cmd);
  27. writer.Char(OEBInterfaces.CR);
  28. writer.Char(OEBInterfaces.LF);
  29. writer.Update
  30. END Send;
  31. PROCEDURE Receive * (VAR session: OEBInterfaces.Session; VAR msg: ARRAY OF CHAR): BOOLEAN;
  32. VAR
  33. serialSession: Session;
  34. port: Serials.Port;
  35. p: LONGINT;
  36. c: CHAR;
  37. BEGIN
  38. LOOP
  39. FOR p := 0 TO Serials.MaxPorts - 1 DO
  40. IF port # NIL THEN
  41. LOOP
  42. IF port.Available() = 0 THEN EXIT END;
  43. c := readers[p].Get();
  44. lines[p].buffer[lines[p].tail] := c;
  45. lines[p].complete := (c = OEBInterfaces.CR) OR (c = OEBInterfaces.LF);
  46. IF lines[p].complete THEN
  47. (* Get message, without ending CR or LF *)
  48. lines[p].buffer[lines[p].tail] := 0X;
  49. COPY(lines[p].buffer, msg);
  50. lines[p].tail := 0;
  51. lines[p].buffer := "";
  52. lines[p].complete := FALSE;
  53. IF msg = "INFO: Enter" THEN
  54. NEW(serialSession, p);
  55. session := serialSession
  56. ELSE
  57. session := sessions;
  58. WHILE (session # NIL) & (session(Session).port # p) DO session := session.next END
  59. END
  60. END;
  61. INC(lines[p].tail);
  62. END;
  63. END
  64. END
  65. END
  66. END Receive;
  67. END Interface;
  68. Session * = OBJECT (OEBInterfaces.Session)
  69. VAR
  70. port: LONGINT;
  71. PROCEDURE & Init (port: LONGINT);
  72. VAR
  73. name: ARRAY 128 OF CHAR;
  74. BEGIN
  75. name := "PORT";
  76. Strings.AppendInt(name, port);
  77. InitSession(name);
  78. SELF.port := port;
  79. END Init;
  80. END Session;
  81. Factory = OBJECT (OEBInterfaces.Factory)
  82. PROCEDURE NewInterface (CONST param: ARRAY OF CHAR): OEBInterfaces.Interface;
  83. VAR
  84. itf: Interface;
  85. BEGIN
  86. NEW(itf);
  87. RETURN itf
  88. END NewInterface;
  89. END Factory;
  90. Line = RECORD
  91. buffer: ARRAY MaxLineSize OF CHAR;
  92. tail: LONGINT;
  93. complete: BOOLEAN;
  94. END;
  95. VAR
  96. factory: Factory;
  97. PROCEDURE Cleanup;
  98. BEGIN
  99. OEBInterfaces.Unregister(factory)
  100. END Cleanup;
  101. BEGIN
  102. NEW(factory);
  103. OEBInterfaces.Register("Serial", factory);
  104. Modules.InstallTermHandler(Cleanup)
  105. END OEBSerialInterfaces.