1 //
2 // Copyright (c) 2010-2018 Antmicro
3 // Copyright (c) 2011-2015 Realtime Embedded
4 //
5 // This file is licensed under the MIT License.
6 // Full license text is available in 'licenses/MIT.txt'.
7 //
8 using System;
9 using Antmicro.Renode.Core.Structure;
10 using Antmicro.Renode.Logging;
11 using Antmicro.Renode.Peripherals.Network;
12 using System.Collections.Generic;
13 using Antmicro.Renode.Network;
14 using Antmicro.Renode.Core;
15 using Antmicro.Renode.Utilities;
16 
17 namespace Antmicro.Renode.Peripherals.USBDeprecated
18 {
19     public class SMSC9500 : IUSBPeripheral, IMACInterface
20     {
21         public event Action <uint> SendInterrupt
22         {
23             add {}
24             remove {}
25         }
26         public event Action <uint> SendPacket
27         {
28             add {}
29             remove {}
30         }
31 
SMSC9500()32         public SMSC9500()
33         {
34             MAC = EmulationManager.Instance.CurrentEmulation.MACRepository.GenerateUniqueMAC();
35             for(int i=0; i<NumberOfEndpoints; i++)
36             {
37                 dataToggleBit[i] = false;
38             }
39             endpointDescriptor = new EndpointUSBDescriptor[NumberOfEndpoints];
40             for(int i=0; i<NumberOfEndpoints; i++)
41             {
42                 endpointDescriptor[i] = new EndpointUSBDescriptor();
43             }
44             fillEndpointsDescriptors(endpointDescriptor);
45             interfaceDescriptor[0].EndpointDescriptor = endpointDescriptor;
46             configurationDescriptor.InterfaceDescriptor = interfaceDescriptor;
47 
48             rxPacketQueue = new Queue<EthernetFrame>();
49         }
50 
GetData()51         public byte[] GetData()
52         {
53             return null;
54         }
55 
56         uint addr;
57 
GetAddress()58         public uint GetAddress()
59         {
60             return addr;
61         }
62 
GetSpeed()63         public USBDeviceSpeed GetSpeed()
64         {
65             return USBDeviceSpeed.High;
66         }
67         #region IUSBDevice implementation
ProcessClassGet(USBPacket packet, USBSetupPacket setupPacket)68         public byte[] ProcessClassGet(USBPacket packet, USBSetupPacket setupPacket)
69         {
70             throw new System.NotImplementedException();
71         }
72 
73         bool linkUp = false;
74 
WriteInterrupt(USBPacket packet)75         public byte[] WriteInterrupt(USBPacket packet)
76         {
77             if(linkUp == false)
78             {
79                 linkUp = true;
80                 packet.data = new byte[4];
81                 packet.data[0] = 0x00;
82                 packet.data[1] = 0x80;
83                 packet.data[2] = 0x00;
84                 packet.data[3] = 0x00;
85                 return packet.data;
86             }
87             else
88                 return null;
89         }
90 
GetTransferStatus()91         public     byte GetTransferStatus()
92         {
93             return 0;
94         }
95 
96         byte[] controlPacket;
97 
GetDataControl(USBPacket packet)98         public byte[] GetDataControl(USBPacket packet)
99         {
100             return controlPacket;
101         }
102 
GetDescriptor(USBPacket packet, USBSetupPacket setupPacket)103         public byte[] GetDescriptor(USBPacket packet, USBSetupPacket setupPacket)
104         {
105             DescriptorType type;
106             type = (DescriptorType)((setupPacket.value & 0xff00) >> 8);
107             uint index = (uint)(setupPacket.value & 0xff);
108             switch(type)
109             {
110             case DescriptorType.Device:
111                 controlPacket = new byte[deviceDescriptor.ToArray().Length];
112                 deviceDescriptor.ToArray().CopyTo(controlPacket, 0);
113                 return deviceDescriptor.ToArray();
114             case DescriptorType.Configuration:
115                 controlPacket = new byte[configurationDescriptor.ToArray().Length];
116                 configurationDescriptor.ToArray().CopyTo(controlPacket, 0);
117                 return configurationDescriptor.ToArray();
118             case DescriptorType.DeviceQualifier:
119                 controlPacket = new byte[deviceQualifierDescriptor.ToArray().Length];
120                 deviceQualifierDescriptor.ToArray().CopyTo(controlPacket, 0);
121                 return deviceQualifierDescriptor.ToArray();
122             case DescriptorType.InterfacePower:
123                 throw new NotImplementedException("Interface Power Descriptor is not yet implemented. Please contact AntMicro for further support.");
124             case DescriptorType.OtherSpeedConfiguration:
125                 controlPacket = new byte[otherConfigurationDescriptor.ToArray().Length];
126                 otherConfigurationDescriptor.ToArray().CopyTo(controlPacket, 0);
127                 return otherConfigurationDescriptor.ToArray();
128             case DescriptorType.String:
129                 if(index == 0)
130                 {
131                     stringDescriptor = new StringUSBDescriptor(1);
132                     stringDescriptor.LangId[0] = EnglishLangId;
133                 }
134                 else
135                 {
136                     if(index < stringValues.Count)
137                     {
138                         stringDescriptor = new StringUSBDescriptor(stringValues[setupPacket.index][index]);
139                     }
140                     else
141                     {
142                         stringDescriptor = new StringUSBDescriptor("");
143                     }
144 
145                 }
146                 controlPacket = new byte[stringDescriptor.ToArray().Length];
147                 stringDescriptor.ToArray().CopyTo(controlPacket, 0);
148                 return stringDescriptor.ToArray();
149             default:
150                 return null;
151             }
152         }
153 
WriteDataControl(USBPacket packet)154         public void WriteDataControl(USBPacket packet)
155         {
156         }
157 
ProcessClassSet(USBPacket packet, USBSetupPacket setupPacket)158         public void ProcessClassSet(USBPacket packet, USBSetupPacket setupPacket)
159         {
160             throw new System.NotImplementedException();
161         }
162 
SetDataToggle(byte endpointNumber)163         public void SetDataToggle(byte endpointNumber)
164         {
165             dataToggleBit[endpointNumber] = true;
166         }
167 
Reset()168         public void Reset()
169         {
170             linkUp = false;
171         }
172 
CleanDataToggle(byte endpointNumber)173         public void CleanDataToggle(byte endpointNumber)
174         {
175             dataToggleBit[endpointNumber] = false;
176         }
177 
ToggleDataToggle(byte endpointNumber)178         public void ToggleDataToggle(byte endpointNumber)
179         {
180             dataToggleBit[endpointNumber] = !dataToggleBit[endpointNumber];
181         }
182 
GetDataToggle(byte endpointNumber)183         public bool GetDataToggle(byte endpointNumber)
184         {
185             return dataToggleBit[endpointNumber];
186         }
187 
ClearFeature(USBPacket packet, USBSetupPacket setupPacket)188         public void ClearFeature(USBPacket packet, USBSetupPacket setupPacket)
189         {
190             throw new System.NotImplementedException();
191         }
192 
GetConfiguration()193         public byte[] GetConfiguration()
194         {
195             throw new System.NotImplementedException();
196         }
197 
GetInterface(USBPacket packet, USBSetupPacket setupPacket)198         public byte[] GetInterface(USBPacket packet, USBSetupPacket setupPacket)
199         {
200             throw new System.NotImplementedException();
201         }
202 
GetStatus(USBPacket packet, USBSetupPacket setupPacket)203         public byte[] GetStatus(USBPacket packet, USBSetupPacket setupPacket)
204         {
205             var arr = new byte[2];
206             MessageRecipient recipient = (MessageRecipient)(setupPacket.requestType & 0x3);
207             switch(recipient)
208             {
209             case MessageRecipient.Device:
210                 arr[0] = (byte)(((configurationDescriptor.RemoteWakeup ? 1 : 0) << 1) | (configurationDescriptor.SelfPowered ? 1 : 0));
211                 break;
212             case MessageRecipient.Endpoint:
213                 //TODO: endpoint halt status
214                 goto default;
215             default:
216                 arr[0] = 0;
217                 break;
218             }
219             controlPacket = new byte[arr.Length];
220             arr.CopyTo(controlPacket, 0);
221             return arr;
222         }
223 
SetAddress(uint address)224         public void SetAddress(uint address)
225         {
226             //this.address = address;
227             addr = address;
228             this.Log(LogLevel.Info, "Device addres set to 0x{0:X}", address);
229         }
230 
SetConfiguration(USBPacket packet, USBSetupPacket setupPacket)231         public void SetConfiguration(USBPacket packet, USBSetupPacket setupPacket)
232         {
233 
234         }
235 
SetDescriptor(USBPacket packet, USBSetupPacket setupPacket)236         public void SetDescriptor(USBPacket packet, USBSetupPacket setupPacket)
237         {
238             throw new System.NotImplementedException();
239         }
240 
SetFeature(USBPacket packet, USBSetupPacket setupPacket)241         public void SetFeature(USBPacket packet, USBSetupPacket setupPacket)
242         {
243 
244         }
245 
SetInterface(USBPacket packet, USBSetupPacket setupPacket)246         public void SetInterface(USBPacket packet, USBSetupPacket setupPacket)
247         {
248 
249         }
250 
SyncFrame(uint endpointId)251         public void SyncFrame(uint endpointId)
252         {
253             throw new System.NotImplementedException();
254         }
CalculateChecksumTX(byte[] data)255         private ushort CalculateChecksumTX(byte[] data)
256         {
257             ulong sum = 0;
258             int size = data.Length;
259             uint i = 0;
260             ushort addVal;
261             while(size > 1)
262             {
263                 addVal = (ushort)((data[i] << 8) | data[i + 1]);
264                 sum += addVal;
265                 i += 2;
266                 size -= 2;
267             }
268             if(size != 0) //if odd length
269                 sum += (ushort)((data[i] << 8) | 0x00);
270 
271 
272             while((sum >>16) != 0)
273             {
274                 sum = (sum >> 16) + (sum & 0xffff);
275             }
276             return (ushort)((~sum) + 1);
277         }
WriteDataBulk(USBPacket packet)278         public void WriteDataBulk(USBPacket packet)
279         {
280             if(packet.data == null)
281                 return;
282 
283             byte[] packetToSend;
284             if(packet.data[5] != 64)
285             {
286                 packetToSend = new byte[packet.data.Length - 8];
287                 Array.Copy(packet.data, 8, packetToSend, 0, packetToSend.Length);
288             }
289             else
290             {
291                 packetToSend = new byte[packet.data.Length - 12];
292                 Array.Copy(packet.data, 12, packetToSend, 0, packetToSend.Length);
293 
294                 if((packetToSend[14] & 0xF0) == 0x40) //IP packet
295                 {
296                     ushort cksum;
297                     IPHeaderLength = (ushort)((packetToSend[14] & 0x0F) * 4);
298                     if(packetToSend[23] == 0x06) // TCP packet
299                     {
300 
301                         IPpacket tcpPacket = new IPpacket(IPHeaderLength, IPpacket.PacketType.TCP);
302                         tcpPacket.ReadFromBuffer(packetToSend);
303                         cksum = tcpPacket.GetChecksum();
304                         cksum -= 1;
305                         packetToSend[MACHeaderLegth + IPHeaderLength + 16] = (byte)((cksum >> 8) & 0xFF);
306                         packetToSend[MACHeaderLegth + IPHeaderLength + 17] = (byte)((cksum) & 0xFF);
307                     }
308                     else if(packetToSend[23] == 0x11) // UDP packet
309                     {
310                         IPpacket udpPacket = new IPpacket(IPHeaderLength, IPpacket.PacketType.UDP);
311                         udpPacket.ReadFromBuffer(packetToSend);
312                         cksum = udpPacket.GetChecksum();
313                         cksum -= 1;
314                         packetToSend[MACHeaderLegth + IPHeaderLength + 6] = (byte)((cksum >> 8) & 0xFF);
315                         packetToSend[MACHeaderLegth + IPHeaderLength + 7] = (byte)((cksum) & 0xFF);
316                     }
317                 }
318 
319             }
320 
321             if(Misc.TryCreateFrameOrLogWarning(this, packetToSend, out var frame, addCrc: true))
322             {
323                 FrameReady?.Invoke(frame);
324             }
325         }
326 
CalculateChecksumRX(byte[] data)327         private ushort CalculateChecksumRX(byte[] data)
328         {
329             ulong sum = 0;
330             ulong part = 0;
331             int size = data.Length;
332             uint i = 0;
333             while(size > 1)
334             {
335                 part = (ulong)((data[i + 1] * 256) + data[i]);
336                 sum += ((part & 0xFFFFu) + (part >> 16));
337                 i += 2;
338                 size -= 2;
339             }
340             if(size != 0) //if odd length
341                 sum += (ushort)(data[size - 1]);
342 
343             return (ushort)sum;
344         }
345 
346         private readonly Queue<EthernetFrame> rxPacketQueue;
347 
GetDataBulk(USBPacket packet)348         public byte[] GetDataBulk(USBPacket packet)
349         {
350             lock(sync)
351             {
352                 if(packet.bytesToTransfer > 0)
353                 if(rxPacketQueue.Count > 0)
354                 {
355 
356                     EthernetFrame receivedFrame = rxPacketQueue.Dequeue();
357 
358                     //byte frameBytes []= rxFifo.Dequeue();
359                     var size = receivedFrame.Bytes.Length;
360                     uint packetSize;
361                     //  var packetSize = Math.Max(64, size & ~1); //64 is the minimal length
362                     packetSize = (uint)size;
363                     packetSize += 6;
364 
365 
366                     packetSize += 6;
367 
368                     if(packetSize > 1514 + 12)
369                     {
370                         //Maybe we should react to overruns. Now we just drop.
371                         return null;
372                     }
373 
374                     byte[] currentBuffer = new byte[(uint)packetSize];
375                     currentBuffer[2] = (byte)((packetSize - 6) & 0xff);
376                     currentBuffer[3] = (byte)((packetSize - 6) >> 8);
377                     var frameBytes = receivedFrame.Bytes;
378                     ushort cksum = 0;
379 
380                     byte[] tmp = new byte[(uint)frameBytes.Length - 14];
381                     Array.Copy(frameBytes, 14, tmp, 0, tmp.Length);
382                     cksum = CalculateChecksumRX(tmp);
383                     if((frameBytes[14] & 0xF0) == 0x40) //IP packet
384                     {
385 
386                         if(frameBytes[23] == 0x06) // TCP packet
387                         {
388 
389                             uint sa = (uint)((frameBytes[MACHeaderLegth + 12 + 3] << 24) | (frameBytes[MACHeaderLegth + 12 + 2] << 16) | (frameBytes[MACHeaderLegth + 12 + 1] << 8) | (frameBytes[MACHeaderLegth + 12 + 0] << 0));
390                             uint da = (uint)((frameBytes[MACHeaderLegth + 16 + 3] << 24) | (frameBytes[MACHeaderLegth + 16 + 2] << 16) | (frameBytes[MACHeaderLegth + 16 + 1] << 8) | (frameBytes[MACHeaderLegth + 16 + 0] << 0));
391                             ushort protocol = frameBytes[MACHeaderLegth + 9];
392                             ushort IPHeaderLength = (ushort)((frameBytes[14] & 0x0F) * 4);
393                             ushort packetLength = (ushort)(System.Net.IPAddress.HostToNetworkOrder((ushort)(frameBytes.Length - (MACHeaderLegth + IPHeaderLength))) >> 16);
394                             long s = sa + da + (protocol << 8) + packetLength;
395                             s += (s >> 32);
396                             s = (s & 0xffff) + (s >> 16);
397                             s = (s & 0xffff) + (s >> 16);
398                             cksum = (ushort)~s;
399                         }
400                     }
401 
402                     if((frameBytes[14] & 0xF0) == 0x40) //IP packet
403                     {
404                         if(frameBytes[23] == 0x01) // UDP packet
405                         {
406                             Array.Copy(frameBytes, 14, tmp, 0, tmp.Length);
407                             ushort cksumm = CalculateChecksumRX(tmp);
408                             frameBytes[36] = (byte)((cksumm >> 8) & 0xFF);
409                             frameBytes[37] = (byte)((cksumm) & 0xFF);
410                         }
411                     }
412 
413                     for(int i=0; i< size; i++)
414                     {
415                         currentBuffer[6 + i] = frameBytes[i];
416                     }
417 
418                     if((frameBytes[14] & 0xF0) == 0x40) //IP packet
419                     {
420                         if(frameBytes[23] == 0x06)
421                         {
422                             currentBuffer[packetSize - 1] = (byte)(((cksum) >> 8) & 0xFF);
423                             currentBuffer[packetSize - 2] = (byte)((cksum) & 0xFF);
424                         }
425                         else if(frameBytes[23] == 0x11)
426                         {
427                             currentBuffer[packetSize - 1] = (byte)(((cksum) >> 8) & 0xFF);
428                             currentBuffer[packetSize - 2] = (byte)((cksum) & 0xFF);
429                         }
430                     }
431                     return currentBuffer;
432                 }
433                 return null;
434             }
435 
436 
437         }
438         #endregion
439         #region ping hack variables
440         private readonly object sync = new object();
441         #endregion
442         #region INetworkInterface implementation
443         public event Action<EthernetFrame> FrameReady;
444 
ReceiveFrame(EthernetFrame frame)445         public void ReceiveFrame(EthernetFrame frame)//when data is send to us
446         {
447             lock(sync)
448             {
449                 if(!frame.DestinationMAC.IsBroadcast && frame.DestinationMAC != MAC)
450                 {
451                     return;
452                 }
453 
454                 if(!EthernetFrame.CheckCRC(frame.Bytes))
455                 {
456                     this.Log(LogLevel.Info, "Invalid CRC, packet discarded");
457                     return;
458                 }
459 
460                 rxPacketQueue.Enqueue(frame);
461             }
462         }
463         #endregion
464         #region device registers
465         //   private byte[] macAddress = new byte[] {0,0,0,0,0,0};
466         #endregion
467         #region USB descriptors
468 
469         private ConfigurationUSBDescriptor configurationDescriptor = new ConfigurationUSBDescriptor() {
470             ConfigurationIndex = 3,
471             SelfPowered = true,
472             NumberOfInterfaces = 1,
473             RemoteWakeup = true,
474             MaxPower = 0x01, //2mA
475             ConfigurationValue = 1
476         };
477         private ConfigurationUSBDescriptor otherConfigurationDescriptor = new ConfigurationUSBDescriptor();
478         private StringUSBDescriptor stringDescriptor = null;
479         private StandardUSBDescriptor deviceDescriptor = new StandardUSBDescriptor {
480             DeviceClass=0xff,//vendor specific
481             DeviceSubClass = 0xff,//vendor specific
482             USB = 0x0200,
483             DeviceProtocol = 0xff,//vendor specific
484             MaxPacketSize = 64,
485             VendorId = 0x0424,
486             ProductId = 0xec00,
487             Device = 0x0200,
488             ManufacturerIndex = 4,
489             ProductIndex = 1,
490             SerialNumberIndex = 2,
491             NumberOfConfigurations = 1
492         };
493         private DeviceQualifierUSBDescriptor deviceQualifierDescriptor = new DeviceQualifierUSBDescriptor();
494         private EndpointUSBDescriptor[] endpointDescriptor;
495         private InterfaceUSBDescriptor[] interfaceDescriptor = new[] {new InterfaceUSBDescriptor
496         {
497             AlternateSetting = 0,
498             InterfaceNumber = 0,
499             NumberOfEndpoints = NumberOfEndpoints,
500             InterfaceClass = 0xff, //vendor specific
501             InterfaceProtocol = 0xff,
502             InterfaceSubClass = 0xff,
503             InterfaceIndex = 0
504         }
505         };
506         //private uint address;
507         private Dictionary<ushort, string[]> stringValues = new Dictionary<ushort, string[]>() {
508             {EnglishLangId, new string[]{
509                     "",
510                     "SMSC914",
511                     "0xALLMAN",
512                     "Configuration",
513                     "AntMicro"
514                 }}
515         };
516 
fillEndpointsDescriptors(EndpointUSBDescriptor[] endpointDesc)517         private void fillEndpointsDescriptors(EndpointUSBDescriptor[] endpointDesc)
518         {
519             endpointDesc[0].EndpointNumber = 1;
520             endpointDesc[0].InEnpoint = true;
521             endpointDesc[0].TransferType = EndpointUSBDescriptor.TransferTypeEnum.Bulk;
522             endpointDesc[0].MaxPacketSize = 512;
523             endpointDesc[0].SynchronizationType = EndpointUSBDescriptor.SynchronizationTypeEnum.NoSynchronization;
524             endpointDesc[0].UsageType = EndpointUSBDescriptor.UsageTypeEnum.Data;
525             endpointDesc[0].Interval = 0;
526 
527             endpointDesc[1].EndpointNumber = 2;
528             endpointDesc[1].InEnpoint = false;
529             endpointDesc[1].TransferType = EndpointUSBDescriptor.TransferTypeEnum.Bulk;
530             endpointDesc[1].MaxPacketSize = 512;
531             endpointDesc[1].SynchronizationType = EndpointUSBDescriptor.SynchronizationTypeEnum.NoSynchronization;
532             endpointDesc[1].UsageType = EndpointUSBDescriptor.UsageTypeEnum.Data;
533             endpointDesc[1].Interval = 0;
534 
535             endpointDesc[2].EndpointNumber = 3;
536             endpointDesc[2].InEnpoint = true;
537             endpointDesc[2].TransferType = EndpointUSBDescriptor.TransferTypeEnum.Interrupt;
538             endpointDesc[2].MaxPacketSize = 16;
539             endpointDesc[2].SynchronizationType = EndpointUSBDescriptor.SynchronizationTypeEnum.NoSynchronization;
540             endpointDesc[2].UsageType = EndpointUSBDescriptor.UsageTypeEnum.Data;
541             endpointDesc[2].Interval = 2;
542 
543         }
544         #endregion
545         #region Device enums
546         private enum vendorRequest : byte
547         {
548             WriteRegister = 0xA0,
549             ReadRegister = 0xA1
550         }
551 
552         private enum txCommands
553         {
554             FirstSegment = 0x00002000,
555             LastSegment = 0x00001000
556         }
557 
558         private enum rxStatus
559         {
560             FrameLength = 0x3FFF0000,
561             ErrorSummary = 0x00008000
562         }
563 
564         private enum SCSR
565         {
566             IdRevision = 0x00,
567             InterruptStatus = 0x08,
568             TxConfig = 0x10,
569             HwConfig = 0x14,
570             PmControl = 0x20,
571             AfcConfig = 0x2C,
572             E2PCommand = 0x30,
573             E2PData = 0x34,
574             BurstCapabilities = 0x38,
575             InterruptEndpointControl = 0x68,
576             BulkInDly = 0x6C,
577             MACControl = 0x100,
578             MACAddressHi = 0x104,
579             MACAddressLo = 0x108,
580             MediaIndependentInterfaceAddress = 0x114,
581             MediaIndependentInterfaceData = 0x118,
582             Flow = 0x11C,
583             Vlan1 = 0x120,
584             ConnectionOrientedEthernetControl = 0x130
585         }
586         #endregion
587         #region Device constans
588         private const byte NumberOfEndpoints = 3;
589         private const ushort EnglishLangId = 0x09;
590         #endregion
591         #region Device variables
592         private uint macControlRegister = 0x00;
593         private uint e2pCommand = 0x00;
594         private uint hardwareConfigurationRegister = 0x00;
595         private uint powerMenagementConfigurationRegister = 0x00;
596         private uint miiData = 0x04;
597         private uint miiAddress = 0x04;
598         private bool[] dataToggleBit = new bool[NumberOfEndpoints + 1];
599         #endregion
600         #region IUSBDevice implementation
ProcessVendorGet(USBPacket packet, USBSetupPacket setupPacket)601         public byte[] ProcessVendorGet(USBPacket packet, USBSetupPacket setupPacket)
602         {
603             ushort index = setupPacket.index;
604             byte request = setupPacket.request;
605             ushort value = setupPacket.value;
606             if(request == (byte)vendorRequest.ReadRegister)
607             {
608                 switch((SCSR)index)
609                 {
610                 case SCSR.MACAddressLo:
611 
612                     break;
613                     case SCSR.MACAddressHi:
614 
615                     break;
616                     case SCSR.E2PData:
617                     if((e2pCommand & 0x000001FF) >= 0x1 && (e2pCommand & 0x000001FF) <= 0x6)
618                     {
619                         controlPacket = new byte[1];
620                         controlPacket[0] = MAC.Bytes[(e2pCommand & 0x000001FF) - 1];
621                         return controlPacket;
622                     }
623                     else
624                     {
625                         controlPacket = BitConverter.GetBytes((uint)0);
626                         return BitConverter.GetBytes((uint)0);
627                     }
628                     case SCSR.MACControl:
629                     controlPacket = BitConverter.GetBytes(macControlRegister);
630                     return BitConverter.GetBytes(macControlRegister);
631                     case SCSR.E2PCommand:
632                     controlPacket = BitConverter.GetBytes(e2pCommand);
633                     return BitConverter.GetBytes(e2pCommand);
634                     case SCSR.HwConfig:
635                     controlPacket = BitConverter.GetBytes(hardwareConfigurationRegister & (~0x00000008));
636                     return (BitConverter.GetBytes(hardwareConfigurationRegister & (~0x00000008)));
637                     case SCSR.PmControl:
638                     controlPacket = BitConverter.GetBytes(powerMenagementConfigurationRegister & (~0x00000010));
639                     return BitConverter.GetBytes(powerMenagementConfigurationRegister & (~0x00000010));
640                     case SCSR.MediaIndependentInterfaceData:
641                     controlPacket = BitConverter.GetBytes(miiData & (~0x8000) | 0x0004 | 0x0100);
642                     return BitConverter.GetBytes(miiData & (~0x8000) | 0x0004 | 0x0100);
643                     case SCSR.MediaIndependentInterfaceAddress:
644                     controlPacket = BitConverter.GetBytes(miiAddress);
645                     controlPacket[0] &= ((byte)(0xFEu));
646                     return controlPacket;
647                 default:
648                     this.Log(LogLevel.Warning, "Unknown register read request (request=0x{0:X}, value=0x{1:X}, index=0x{2:X})", request, value, index);
649                     break;
650                 }
651             }
652             var arr = new byte[] { 0 };
653             controlPacket = arr;
654             return arr;
655         }
656 
ProcessVendorSet(USBPacket packet, USBSetupPacket setupPacket)657         public void ProcessVendorSet(USBPacket packet, USBSetupPacket setupPacket)
658         {
659             ushort index = setupPacket.index;
660             byte request = setupPacket.request;
661             ushort value = setupPacket.value;
662             if(request == (byte)vendorRequest.WriteRegister)
663             {
664                 switch((SCSR)index)
665                 {
666                 case SCSR.HwConfig:
667                     if(packet.data != null)
668                         hardwareConfigurationRegister = BitConverter.ToUInt32(packet.data, 0);
669                     break;
670                     case SCSR.PmControl:
671                     if(packet.data != null)
672                         powerMenagementConfigurationRegister = BitConverter.ToUInt32(packet.data, 0);
673                     break;
674                     case SCSR.MACAddressLo:
675                     break;
676                     case SCSR.MACAddressHi:
677                     break;
678                     case SCSR.MACControl:
679                     if(packet.data != null)
680                         macControlRegister = BitConverter.ToUInt32(packet.data, 0);
681                     this.Log(LogLevel.Warning, "macControlRegister=0x{0:X}", macControlRegister);
682                     break;
683                     case SCSR.E2PData:
684                     break;
685                     case SCSR.E2PCommand:
686                     if(packet.data != null)
687                         e2pCommand = BitConverter.ToUInt32(packet.data, 0) & (~(0x80000000 | 0x00000400));
688                     break;
689                     case SCSR.MediaIndependentInterfaceAddress:
690                     if(packet.data != null)
691                         miiAddress = BitConverter.ToUInt32(packet.data, 0);
692                     break;
693                     case SCSR.MediaIndependentInterfaceData:
694                     if(packet.data != null)
695                         miiData = BitConverter.ToUInt32(packet.data, 0);
696                     break;
697                     default:
698                     this.Log(LogLevel.Warning, "Unknown register write request  (request=0x{0:X}, value=0x{1:X}, index=0x{2:X})", request, value, index);
699                     break;
700                 }
701             }
702         }
703         #endregion
704         #region IMACInterface implementation
705         public MACAddress MAC { get; set; }
706         #endregion
707 
708         private ushort IPHeaderLength = 20;
709         private const ushort MACHeaderLegth = 14;
710 
711 
712         private class IPpacket
713         {
IPpacket(ushort IPLength, PacketType type)714             public IPpacket(ushort IPLength, PacketType type)
715             {
716                 IPHeaderLength = IPLength;
717                 packetType = type;
718                 pseudoheader = new PseudoHeader();
719             }
720 
ReadFromBuffer(byte[] buffer)721             public void ReadFromBuffer(byte[] buffer)
722             {
723                 pseudoheader.FillFromBuffer( buffer );
724 
725                 packet = new byte[buffer.Length - (MACHeaderLegth + IPHeaderLength) ];
726                 Array.Copy(buffer, MACHeaderLegth + IPHeaderLength, packet, 0, ( buffer.Length - (MACHeaderLegth + IPHeaderLength) ) );
727                 if( packetType == PacketType.TCP )
728                 {
729                     packet[16] = 0;
730                     packet[17] = 0;
731                 }
732                 else if( packetType == PacketType.UDP )
733                 {
734                     packet[6] = 0;
735                     packet[7] = 0;
736                 }
737 
738             }
739 
CalculateChecksum(byte [] data)740             private ushort CalculateChecksum(byte [] data)
741             {
742                 ulong sum = 0;
743                 int size = data.Length;
744                 uint i = 0;
745                 ushort addVal;
746                 while( size > 1 )
747                 {
748                     addVal = (ushort)((data[i] << 8) | data[i+1]);
749                     sum += addVal;
750                     i+=2;
751                     size -= 2;
752                 }
753                 if( size != 0) //if odd length
754                     sum += (ushort)((data[i] << 8) | 0x00);
755 
756 
757                 while ( (sum >>16) != 0 )
758                 {
759                     sum = (sum >> 16) + (sum & 0xffff);
760                 }
761                 return (ushort)( (~sum) + 1 );
762             }
763 
GetChecksum()764             public ushort GetChecksum()
765             {
766                 ushort cksum;
767 
768                 checksumCalculationBase = new byte[packet.Length + pseudoheader.Length];
769 
770                 Array.Copy(pseudoheader.ToArray(),0,checksumCalculationBase,0,pseudoheader.Length);
771                 Array.Copy(packet,0,checksumCalculationBase,pseudoheader.Length,packet.Length);
772 
773                 cksum = CalculateChecksum(checksumCalculationBase);
774                 return (ushort)(cksum);
775 
776             }
777 
778             private class PseudoHeader
779             {
FillFromBuffer(byte[] buffer)780                 public void FillFromBuffer(byte[] buffer)
781                 {
782                     sourceAddress = new byte[4];
783                     destinationAddress = new byte[4];
784                     Array.Copy(buffer,MACHeaderLegth+12,sourceAddress,0,4);
785                     Array.Copy(buffer,MACHeaderLegth+16,destinationAddress,0,4);
786                     protocol = buffer[MACHeaderLegth + 9];
787                     packetLength = (ushort)(System.Net.IPAddress.HostToNetworkOrder((ushort)(buffer.Length - (MACHeaderLegth + IPHeaderLength)))>>16);
788                 }
789 
ToArray()790                 public byte[] ToArray()
791 
792                 {
793                     byte[] arr = new byte[Length];
794                     Array.Copy(sourceAddress,0,arr,0,4);
795                     Array.Copy(destinationAddress,0,arr,4,4);
796                     arr[8] = zeros;
797                     arr[9] = protocol;
798                     Array.Copy(BitConverter.GetBytes(packetLength),0,arr,10,2);
799                     return arr;
800                 }
801 
802                 private byte[] sourceAddress;
803                 private byte[] destinationAddress;
804                 private readonly byte zeros = 0x00;
805                 private byte protocol;
806                 private ushort packetLength;
807 
808                 public readonly ushort Length = 12;
809 
810             }
811 
812             public enum PacketType
813             {
814                 TCP = 1,
815                 UDP = 2
816             }
817 
818             private PacketType packetType;
819             private static ushort IPHeaderLength;
820             private const ushort MACHeaderLegth = 14;
821 
822             private PseudoHeader pseudoheader;
823             private byte[] packet;
824             private byte[] checksumCalculationBase;
825 
826         }
827     }
828 }
829 
830