OEBUdpInterfaces.Mod 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. MODULE OEBUdpInterfaces; (** AUTHOR ""; PURPOSE ""; *)
  2. IMPORT
  3. Modules, KernelLog, IP, UDP, Strings, FoxBasic,
  4. OEBInterfaces;
  5. CONST
  6. Port = 5999;
  7. NopCmd = "nop";
  8. TYPE
  9. Interface * = OBJECT (OEBInterfaces.Interface)
  10. VAR
  11. socket: UDP.Socket;
  12. PROCEDURE & Init * (CONST param: ARRAY OF CHAR);
  13. VAR
  14. res: LONGINT;
  15. BEGIN
  16. InitInterface("UDP0", "UDP interface");
  17. NEW(socket, Port, res);
  18. IF res = UDP.Ok THEN
  19. BEGIN{EXCLUSIVE}
  20. sockets.Add(socket);
  21. END;
  22. ELSE
  23. socket := NIL;
  24. KernelLog.Enter;
  25. KernelLog.String("Error opening UDP socket: ");
  26. KernelLog.Int(res, 0);
  27. KernelLog.Exit
  28. END;
  29. END Init;
  30. PROCEDURE Send * (session: OEBInterfaces.Session; CONST cmd: ARRAY OF CHAR): BOOLEAN;
  31. VAR
  32. c: ARRAY 128 OF CHAR;
  33. res: LONGINT;
  34. BEGIN
  35. COPY(cmd, c);
  36. Strings.AppendChar(c, OEBInterfaces.CR);
  37. Strings.AppendChar(c, OEBInterfaces.LF);
  38. socket.Send(session(Session).address, Port, c, 0, Strings.Length(c), res);
  39. RETURN res = UDP.Ok
  40. END Send;
  41. PROCEDURE Receive * (VAR session: OEBInterfaces.Session; VAR msg: ARRAY OF CHAR): BOOLEAN;
  42. VAR
  43. ip: IP.Adr;
  44. i, len, port, res: LONGINT;
  45. new: Session;
  46. adr: ARRAY 128 OF CHAR;
  47. BEGIN
  48. socket.Receive(msg, 0, LEN(msg) - 1, -1, ip, port, len, res);
  49. IF port # Port THEN msg := ''; RETURN TRUE END;
  50. IF res = UDP.BufferOverflow THEN RETURN FALSE END;
  51. IF len = 0 THEN RETURN TRUE END;
  52. WHILE (i < len) & (msg[i] # OEBInterfaces.CR) & (msg[i] # OEBInterfaces.LF) DO INC(i) END;
  53. msg[i] := 0X;
  54. IP.AdrToStr(ip, adr);
  55. IF msg = "INFO: Enter" THEN
  56. NEW(new, adr);
  57. new.address := ip;
  58. session := new
  59. ELSE
  60. session := sessions;
  61. WHILE (session # NIL) & ~IP.AdrsEqual(session(Session).address, ip) DO session := session.next END;
  62. IF (session = NIL) & ~IsLocalhost(ip) THEN
  63. (* Create session *)
  64. NEW(new, adr);
  65. new.address := ip;
  66. session := new
  67. END;
  68. END;
  69. RETURN TRUE
  70. END Receive;
  71. PROCEDURE Start *;
  72. VAR
  73. cmd: ARRAY 32 OF CHAR;
  74. res: LONGINT;
  75. BEGIN
  76. Start^;
  77. cmd := NopCmd;
  78. Strings.AppendChar(cmd, OEBInterfaces.CR);
  79. Strings.AppendChar(cmd, OEBInterfaces.LF);
  80. socket.Send(IP.StrToAdr("10.3.34.255"), Port, cmd, 0, Strings.Length(cmd), res);
  81. IF res # UDP.Ok THEN
  82. KernelLog.Enter;
  83. KernelLog.String("Could not broadcast 'nop': ");
  84. KernelLog.Int(res, 0);
  85. KernelLog.Exit
  86. END;
  87. END Start;
  88. PROCEDURE Kill;
  89. BEGIN
  90. Kill^;
  91. IF socket # NIL THEN socket.Close; END;
  92. BEGIN{EXCLUSIVE}
  93. sockets.Remove(socket);
  94. END;
  95. socket := NIL;
  96. END Kill;
  97. END Interface;
  98. Session * = OBJECT (OEBInterfaces.Session)
  99. VAR
  100. address: IP.Adr;
  101. END Session;
  102. Factory = OBJECT (OEBInterfaces.Factory)
  103. PROCEDURE NewInterface (CONST param: ARRAY OF CHAR): OEBInterfaces.Interface;
  104. VAR
  105. itf: Interface;
  106. BEGIN
  107. NEW(itf, param);
  108. RETURN itf
  109. END NewInterface;
  110. END Factory;
  111. VAR
  112. factory: Factory;
  113. sockets: FoxBasic.List;
  114. PROCEDURE IsLocalhost (CONST adr: IP.Adr): BOOLEAN;
  115. VAR
  116. curr: IP.Interface;
  117. BEGIN
  118. curr := IP.interfaces;
  119. WHILE curr # NIL DO
  120. IF IP.AdrsEqual(adr, curr.localAdr) THEN RETURN TRUE END;
  121. curr := curr.next
  122. END;
  123. RETURN FALSE
  124. END IsLocalhost;
  125. PROCEDURE Cleanup;
  126. VAR socket: UDP.Socket;
  127. BEGIN
  128. OEBInterfaces.Unregister(factory);
  129. WHILE sockets.Length() > 0 DO
  130. socket := sockets.Get(0)(UDP.Socket);
  131. socket.Close;
  132. sockets.Remove(socket);
  133. END;
  134. END Cleanup;
  135. BEGIN
  136. NEW(factory);
  137. OEBInterfaces.Register("Udp", factory);
  138. Modules.InstallTermHandler(Cleanup);
  139. NEW(sockets,8);
  140. END OEBUdpInterfaces.