123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248 |
- MODULE UsbNetwork; (** AUTHOR "staubesv"; PURPOSE "USB network device driver framework"; *)
- (**
- * History:
- *
- * 03.11.2006 First release (staubesv)
- *)
- IMPORT
- KernelLog, Usbdi, Commands, Network, Plugins;
- CONST
- Ok* = 0;
- Error* = 1;
- Unsupported* = 2;
- MinEthernetFrameSize* = 60;
- MaxEthernetFrameSize* = 1514;
- EthernetHeaderSize* = 14;
- Name = "UsbNet#";
- Description = "USB Link Device";
- ModuleName = "UsbNetwork";
- AddressSize = 6;
- RegisterAtNetwork = TRUE;
- TYPE
- UsbLinkDevice = OBJECT (Network.LinkDevice)
- VAR
- controller : UsbNetworkController;
- PROCEDURE Linked(): LONGINT;
- BEGIN
- RETURN controller.linkStatus;
- END Linked;
- PROCEDURE DoSend(dst: Network.LinkAdr; type: LONGINT; CONST l3hdr, l4hdr, data: ARRAY OF CHAR; h3len, h4len, dofs, dlen: LONGINT);
- BEGIN
- controller.SendFrame(dst, type, l3hdr, l4hdr, data, h3len, h4len, dofs, dlen);
- END DoSend;
- PROCEDURE Finalize(connected: BOOLEAN);
- BEGIN
- controller.Finalize;
- Finalize^(connected);
- END Finalize;
- PROCEDURE Diag;
- BEGIN
- Show(" Diagnostics:"); KernelLog.Ln;
- IF controller # NIL THEN controller.Diag;
- ELSE KernelLog.String("No controller available."); KernelLog.Ln;
- END;
- END Diag;
- PROCEDURE Show*(CONST string : ARRAY OF CHAR);
- BEGIN
- KernelLog.String(name); KernelLog.String(" ("); KernelLog.String(desc); KernelLog.String("): "); KernelLog.String(string);
- END Show;
- END UsbLinkDevice;
- TYPE
- UsbNetworkController* = OBJECT (Usbdi.Driver)
- VAR
- bulkInPipe-, bulkOutPipe-, interruptInPipe- : Usbdi.Pipe;
- rxBuffer-, interruptInBuffer- : Usbdi.BufferPtr;
- linkDevice- : UsbLinkDevice;
- linkStatus* : LONGINT;
- (** Interface to be implemented by actual network controller driver *)
- PROCEDURE SendFrame*(dst: Network.LinkAdr; type: LONGINT; CONST l3hdr, l4hdr, data: ARRAY OF CHAR; h3len, h4len, dofs, dlen: LONGINT); (* abstract *)
- BEGIN {EXCLUSIVE} HALT(301); END SendFrame;
- PROCEDURE GetLinkAddress*(VAR linkAddress : Network.LinkAdr; VAR res : WORD); (* abstract *)
- BEGIN HALT(301); END GetLinkAddress;
- PROCEDURE SetLinkAddress*(linkAddress : Network.LinkAdr; VAR res : WORD); (* abstract *)
- BEGIN HALT(301); END SetLinkAddress;
- PROCEDURE HandleInterrupt*(status : Usbdi.Status; actLen : LONGINT); (* abstract *)
- BEGIN HALT(301); END HandleInterrupt;
- PROCEDURE HandleBulkIn*(status : Usbdi.Status; actLen : LONGINT); (* abstract *)
- BEGIN HALT(301); END HandleBulkIn;
- PROCEDURE InitController*(VAR rxBuffer : Usbdi.BufferPtr) : BOOLEAN; (* abstract *)
- BEGIN HALT(301); END InitController;
- PROCEDURE Finalize*; (* abstract *)
- BEGIN HALT(301); END Finalize;
- PROCEDURE Diag*;
- BEGIN
- KernelLog.String("Diagnostics of "); KernelLog.String(name);
- KernelLog.String(" ("); KernelLog.String(desc); KernelLog.String(")"); KernelLog.Ln;
- END Diag;
- PROCEDURE InitLinkDevice() : BOOLEAN;
- VAR name : Plugins.Name; nofDevices, i : LONGINT; res : WORD;
- BEGIN
- NEW(linkDevice, Network.TypeEthernet, 1000, AddressSize);
- linkDevice.controller := SELF;
- nofDevices := GetNofDevices();
- name := Name;
- i := 0; WHILE name[i] # 0X DO INC(i) END;
- IF nofDevices > 9 THEN
- name[i] := CHR(ORD("A") + nofDevices - 10);
- ELSE
- name[i] := CHR(ORD("0") + nofDevices);
- END;
- name[i+1] := 0X;
- linkDevice.SetName(name);
- linkDevice.desc := Description;
- (* Set ethernet broadcast address: FF-FF-FF-FF-FF-FF *)
- FOR i := 0 TO 5 DO linkDevice.broadcast[i] := 0FFX; END;
- GetLinkAddress(linkDevice.local, res);
- IF res # Ok THEN
- Show("Could not get link address, res: "); KernelLog.Int(res, 0); KernelLog.Ln;
- RETURN FALSE;
- END;
- IF ~RegisterAtNetwork THEN RETURN TRUE; END;
- Network.registry.Add(linkDevice, res);
- ASSERT(res = Plugins.Ok);
- IncNofDevices;
- RETURN TRUE;
- END InitLinkDevice;
- PROCEDURE GetPipes(VAR bulkInPipe, bulkOutPipe, interruptInPipe : Usbdi.Pipe);
- VAR i : LONGINT; bulkInEndpoint, bulkOutEndpoint, interruptInEndpoint : LONGINT;
- BEGIN
- FOR i := 0 TO LEN(interface.endpoints)-1 DO
- IF interface.endpoints[i].type = Usbdi.BulkIn THEN
- bulkInEndpoint := interface.endpoints[i].bEndpointAddress;
- ELSIF interface.endpoints[i].type = Usbdi.BulkOut THEN
- bulkOutEndpoint := interface.endpoints[i].bEndpointAddress;
- ELSIF interface.endpoints[i].type = Usbdi.InterruptIn THEN
- interruptInEndpoint := interface.endpoints[i].bEndpointAddress;
- END;
- END;
- IF bulkInEndpoint # 0 THEN bulkInPipe := device.GetPipe(bulkInEndpoint); END;
- IF bulkOutEndpoint # 0 THEN bulkOutPipe := device.GetPipe(bulkOutEndpoint); END;
- IF interruptInEndpoint # 0 THEN interruptInPipe := device.GetPipe(interruptInEndpoint); END;
- END GetPipes;
- PROCEDURE Connect*() : BOOLEAN;
- VAR status : Usbdi.Status;
- BEGIN
- linkStatus := Network.LinkUnknown;
- GetPipes(bulkInPipe, bulkOutPipe, interruptInPipe);
- IF (bulkInPipe = NIL) OR (bulkOutPipe = NIL) OR (interruptInPipe = NIL) THEN
- Show("Device endpoints not found."); KernelLog.Ln;
- RETURN FALSE;
- END;
- IF ~InitController(rxBuffer) THEN
- Show("Controller initialization failed."); KernelLog.Ln;
- RETURN FALSE;
- END;
- bulkInPipe.SetTimeout(0);
- bulkInPipe.SetCompletionHandler(HandleBulkIn);
- status := bulkInPipe.Transfer(bulkInPipe.maxPacketSize, 0, rxBuffer^); (* ignore status *)
- (* setup status pipe *)
- NEW(interruptInBuffer, interruptInPipe.maxPacketSize);
- interruptInPipe.SetTimeout(0);
- interruptInPipe.SetCompletionHandler(HandleInterrupt);
- status := interruptInPipe.Transfer(interruptInPipe.maxPacketSize, 0, interruptInBuffer^); (* ignore status *)
- IF ~InitLinkDevice() THEN
- Show("Link device initialization failed."); KernelLog.Ln;
- RETURN FALSE;
- END;
- RETURN TRUE;
- END Connect;
- PROCEDURE Disconnect*;
- BEGIN
- IF ~RegisterAtNetwork THEN RETURN; END;
- Network.registry.Remove(linkDevice);
- END Disconnect;
- END UsbNetworkController;
- VAR
- nofDevices : LONGINT;
- (** Show diagnostics of the specified link device *)
- PROCEDURE Diag*(context : Commands.Context); (** linkdevice ~ *)
- VAR plugin : Plugins.Plugin; name : ARRAY 128 OF CHAR;
- BEGIN
- context.arg.SkipWhitespace; context.arg.String(name);
- plugin := Network.registry.Get(name);
- IF plugin # NIL THEN
- IF plugin IS UsbLinkDevice THEN
- plugin(UsbLinkDevice).Diag;
- ELSE
- context.out.String("Link device "); context.out.String(name); context.out.String(" is not a USB link device."); context.out.Ln;
- END;
- ELSE
- context.out.String("Link device "); context.out.String(name); context.out.String(" not found."); context.out.Ln;
- END;
- END Diag;
- PROCEDURE IncNofDevices;
- BEGIN {EXCLUSIVE}
- INC(nofDevices);
- END IncNofDevices;
- PROCEDURE GetNofDevices() : LONGINT;
- BEGIN {EXCLUSIVE}
- RETURN nofDevices;
- END GetNofDevices;
- PROCEDURE Show(CONST string : ARRAY OF CHAR);
- BEGIN
- KernelLog.String(ModuleName); KernelLog.String(": "); KernelLog.String(string);
- END Show;
- END UsbNetwork.
- UsbNetwork.Diag UsbNet#0 ~
- UsbNetwork.Diag UsbNet#1 ~
- UsbNetwork.Diag UsbNet#2 ~
- System.Free UsbNetwork ~
|