UsbNetwork.Mod 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. MODULE UsbNetwork; (** AUTHOR "staubesv"; PURPOSE "USB network device driver framework"; *)
  2. (**
  3. * History:
  4. *
  5. * 03.11.2006 First release (staubesv)
  6. *)
  7. IMPORT
  8. KernelLog, Usbdi, Commands, Network, Plugins;
  9. CONST
  10. Ok* = 0;
  11. Error* = 1;
  12. Unsupported* = 2;
  13. MinEthernetFrameSize* = 60;
  14. MaxEthernetFrameSize* = 1514;
  15. EthernetHeaderSize* = 14;
  16. Name = "UsbNet#";
  17. Description = "USB Link Device";
  18. ModuleName = "UsbNetwork";
  19. AddressSize = 6;
  20. RegisterAtNetwork = TRUE;
  21. TYPE
  22. UsbLinkDevice = OBJECT (Network.LinkDevice)
  23. VAR
  24. controller : UsbNetworkController;
  25. PROCEDURE Linked(): LONGINT;
  26. BEGIN
  27. RETURN controller.linkStatus;
  28. END Linked;
  29. PROCEDURE DoSend(dst: Network.LinkAdr; type: LONGINT; CONST l3hdr, l4hdr, data: ARRAY OF CHAR; h3len, h4len, dofs, dlen: LONGINT);
  30. BEGIN
  31. controller.SendFrame(dst, type, l3hdr, l4hdr, data, h3len, h4len, dofs, dlen);
  32. END DoSend;
  33. PROCEDURE Finalize(connected: BOOLEAN);
  34. BEGIN
  35. controller.Finalize;
  36. Finalize^(connected);
  37. END Finalize;
  38. PROCEDURE Diag;
  39. BEGIN
  40. Show(" Diagnostics:"); KernelLog.Ln;
  41. IF controller # NIL THEN controller.Diag;
  42. ELSE KernelLog.String("No controller available."); KernelLog.Ln;
  43. END;
  44. END Diag;
  45. PROCEDURE Show*(CONST string : ARRAY OF CHAR);
  46. BEGIN
  47. KernelLog.String(name); KernelLog.String(" ("); KernelLog.String(desc); KernelLog.String("): "); KernelLog.String(string);
  48. END Show;
  49. END UsbLinkDevice;
  50. TYPE
  51. UsbNetworkController* = OBJECT (Usbdi.Driver)
  52. VAR
  53. bulkInPipe-, bulkOutPipe-, interruptInPipe- : Usbdi.Pipe;
  54. rxBuffer-, interruptInBuffer- : Usbdi.BufferPtr;
  55. linkDevice- : UsbLinkDevice;
  56. linkStatus* : LONGINT;
  57. (** Interface to be implemented by actual network controller driver *)
  58. PROCEDURE SendFrame*(dst: Network.LinkAdr; type: LONGINT; CONST l3hdr, l4hdr, data: ARRAY OF CHAR; h3len, h4len, dofs, dlen: LONGINT); (* abstract *)
  59. BEGIN {EXCLUSIVE} HALT(301); END SendFrame;
  60. PROCEDURE GetLinkAddress*(VAR linkAddress : Network.LinkAdr; VAR res : WORD); (* abstract *)
  61. BEGIN HALT(301); END GetLinkAddress;
  62. PROCEDURE SetLinkAddress*(linkAddress : Network.LinkAdr; VAR res : WORD); (* abstract *)
  63. BEGIN HALT(301); END SetLinkAddress;
  64. PROCEDURE HandleInterrupt*(status : Usbdi.Status; actLen : LONGINT); (* abstract *)
  65. BEGIN HALT(301); END HandleInterrupt;
  66. PROCEDURE HandleBulkIn*(status : Usbdi.Status; actLen : LONGINT); (* abstract *)
  67. BEGIN HALT(301); END HandleBulkIn;
  68. PROCEDURE InitController*(VAR rxBuffer : Usbdi.BufferPtr) : BOOLEAN; (* abstract *)
  69. BEGIN HALT(301); END InitController;
  70. PROCEDURE Finalize*; (* abstract *)
  71. BEGIN HALT(301); END Finalize;
  72. PROCEDURE Diag*;
  73. BEGIN
  74. KernelLog.String("Diagnostics of "); KernelLog.String(name);
  75. KernelLog.String(" ("); KernelLog.String(desc); KernelLog.String(")"); KernelLog.Ln;
  76. END Diag;
  77. PROCEDURE InitLinkDevice() : BOOLEAN;
  78. VAR name : Plugins.Name; nofDevices, i : LONGINT; res : WORD;
  79. BEGIN
  80. NEW(linkDevice, Network.TypeEthernet, 1000, AddressSize);
  81. linkDevice.controller := SELF;
  82. nofDevices := GetNofDevices();
  83. name := Name;
  84. i := 0; WHILE name[i] # 0X DO INC(i) END;
  85. IF nofDevices > 9 THEN
  86. name[i] := CHR(ORD("A") + nofDevices - 10);
  87. ELSE
  88. name[i] := CHR(ORD("0") + nofDevices);
  89. END;
  90. name[i+1] := 0X;
  91. linkDevice.SetName(name);
  92. linkDevice.desc := Description;
  93. (* Set ethernet broadcast address: FF-FF-FF-FF-FF-FF *)
  94. FOR i := 0 TO 5 DO linkDevice.broadcast[i] := 0FFX; END;
  95. GetLinkAddress(linkDevice.local, res);
  96. IF res # Ok THEN
  97. Show("Could not get link address, res: "); KernelLog.Int(res, 0); KernelLog.Ln;
  98. RETURN FALSE;
  99. END;
  100. IF ~RegisterAtNetwork THEN RETURN TRUE; END;
  101. Network.registry.Add(linkDevice, res);
  102. ASSERT(res = Plugins.Ok);
  103. IncNofDevices;
  104. RETURN TRUE;
  105. END InitLinkDevice;
  106. PROCEDURE GetPipes(VAR bulkInPipe, bulkOutPipe, interruptInPipe : Usbdi.Pipe);
  107. VAR i : LONGINT; bulkInEndpoint, bulkOutEndpoint, interruptInEndpoint : LONGINT;
  108. BEGIN
  109. FOR i := 0 TO LEN(interface.endpoints)-1 DO
  110. IF interface.endpoints[i].type = Usbdi.BulkIn THEN
  111. bulkInEndpoint := interface.endpoints[i].bEndpointAddress;
  112. ELSIF interface.endpoints[i].type = Usbdi.BulkOut THEN
  113. bulkOutEndpoint := interface.endpoints[i].bEndpointAddress;
  114. ELSIF interface.endpoints[i].type = Usbdi.InterruptIn THEN
  115. interruptInEndpoint := interface.endpoints[i].bEndpointAddress;
  116. END;
  117. END;
  118. IF bulkInEndpoint # 0 THEN bulkInPipe := device.GetPipe(bulkInEndpoint); END;
  119. IF bulkOutEndpoint # 0 THEN bulkOutPipe := device.GetPipe(bulkOutEndpoint); END;
  120. IF interruptInEndpoint # 0 THEN interruptInPipe := device.GetPipe(interruptInEndpoint); END;
  121. END GetPipes;
  122. PROCEDURE Connect*() : BOOLEAN;
  123. VAR status : Usbdi.Status;
  124. BEGIN
  125. linkStatus := Network.LinkUnknown;
  126. GetPipes(bulkInPipe, bulkOutPipe, interruptInPipe);
  127. IF (bulkInPipe = NIL) OR (bulkOutPipe = NIL) OR (interruptInPipe = NIL) THEN
  128. Show("Device endpoints not found."); KernelLog.Ln;
  129. RETURN FALSE;
  130. END;
  131. IF ~InitController(rxBuffer) THEN
  132. Show("Controller initialization failed."); KernelLog.Ln;
  133. RETURN FALSE;
  134. END;
  135. bulkInPipe.SetTimeout(0);
  136. bulkInPipe.SetCompletionHandler(HandleBulkIn);
  137. status := bulkInPipe.Transfer(bulkInPipe.maxPacketSize, 0, rxBuffer^); (* ignore status *)
  138. (* setup status pipe *)
  139. NEW(interruptInBuffer, interruptInPipe.maxPacketSize);
  140. interruptInPipe.SetTimeout(0);
  141. interruptInPipe.SetCompletionHandler(HandleInterrupt);
  142. status := interruptInPipe.Transfer(interruptInPipe.maxPacketSize, 0, interruptInBuffer^); (* ignore status *)
  143. IF ~InitLinkDevice() THEN
  144. Show("Link device initialization failed."); KernelLog.Ln;
  145. RETURN FALSE;
  146. END;
  147. RETURN TRUE;
  148. END Connect;
  149. PROCEDURE Disconnect*;
  150. BEGIN
  151. IF ~RegisterAtNetwork THEN RETURN; END;
  152. Network.registry.Remove(linkDevice);
  153. END Disconnect;
  154. END UsbNetworkController;
  155. VAR
  156. nofDevices : LONGINT;
  157. (** Show diagnostics of the specified link device *)
  158. PROCEDURE Diag*(context : Commands.Context); (** linkdevice ~ *)
  159. VAR plugin : Plugins.Plugin; name : ARRAY 128 OF CHAR;
  160. BEGIN
  161. context.arg.SkipWhitespace; context.arg.String(name);
  162. plugin := Network.registry.Get(name);
  163. IF plugin # NIL THEN
  164. IF plugin IS UsbLinkDevice THEN
  165. plugin(UsbLinkDevice).Diag;
  166. ELSE
  167. context.out.String("Link device "); context.out.String(name); context.out.String(" is not a USB link device."); context.out.Ln;
  168. END;
  169. ELSE
  170. context.out.String("Link device "); context.out.String(name); context.out.String(" not found."); context.out.Ln;
  171. END;
  172. END Diag;
  173. PROCEDURE IncNofDevices;
  174. BEGIN {EXCLUSIVE}
  175. INC(nofDevices);
  176. END IncNofDevices;
  177. PROCEDURE GetNofDevices() : LONGINT;
  178. BEGIN {EXCLUSIVE}
  179. RETURN nofDevices;
  180. END GetNofDevices;
  181. PROCEDURE Show(CONST string : ARRAY OF CHAR);
  182. BEGIN
  183. KernelLog.String(ModuleName); KernelLog.String(": "); KernelLog.String(string);
  184. END Show;
  185. END UsbNetwork.
  186. UsbNetwork.Diag UsbNet#0 ~
  187. UsbNetwork.Diag UsbNet#1 ~
  188. UsbNetwork.Diag UsbNet#2 ~
  189. System.Free UsbNetwork ~