1 // 2 // Copyright (c) 2010-2020 Antmicro 3 // 4 // This file is licensed under the MIT License. 5 // Full license text is available in 'licenses/MIT.txt'. 6 // 7 using System; 8 using System.Collections.Generic; 9 using System.Linq; 10 using Antmicro.Renode.Exceptions; 11 using Antmicro.Renode.Utilities; 12 13 namespace Antmicro.Renode.Core.USB 14 { 15 public class USBInterface : DescriptorProvider 16 { USBInterface(IUSBDevice device, byte identifier, USBClassCode classCode = USBClassCode.NotSpecified, byte subClassCode = 0, byte protocol = 0, string description = null)17 public USBInterface(IUSBDevice device, 18 byte identifier, 19 USBClassCode classCode = USBClassCode.NotSpecified, 20 byte subClassCode = 0, 21 byte protocol = 0, 22 string description = null) : base(9, (byte)DescriptorType.Interface) 23 { 24 this.device = device; 25 endpoints = new List<USBEndpoint>(); 26 27 Identifier = identifier; 28 Class = classCode; 29 SubClass = subClassCode; 30 Protocol = protocol; 31 Description = description; 32 33 RegisterSubdescriptors(endpoints); 34 } 35 HandleRequest(SetupPacket packet)36 public virtual BitStream HandleRequest(SetupPacket packet) 37 { 38 return BitStream.Empty; 39 } 40 WithEndpoint(Direction direction, EndpointTransferType transferType, short maximumPacketSize, byte interval, out USBEndpoint createdEndpoint, byte? id = null)41 public USBInterface WithEndpoint(Direction direction, EndpointTransferType transferType, short maximumPacketSize, byte interval, out USBEndpoint createdEndpoint, byte? id = null) 42 { 43 if(!id.HasValue && endpoints.Count == byte.MaxValue) 44 { 45 throw new ConstructionException("The maximal number of endpoints reached"); 46 } 47 48 var localId = id ?? (byte)(endpoints.Count + 1); 49 if(endpoints.Any(x => x.Identifier == localId && x.Direction == direction)) 50 { 51 throw new ConstructionException($"Endpoint with id {localId} in direction {direction} already definied"); 52 } 53 54 createdEndpoint = new USBEndpoint(device, localId, direction, transferType, maximumPacketSize, interval); 55 endpoints.Add(createdEndpoint); 56 return this; 57 } 58 59 public USBClassCode Class { get; } 60 public byte SubClass { get; } 61 public byte Protocol { get; } 62 public string Description { get; } 63 public byte Identifier { get; } 64 public IReadOnlyCollection<USBEndpoint> Endpoints => endpoints; 65 FillDescriptor(BitStream buffer)66 protected override void FillDescriptor(BitStream buffer) 67 { 68 buffer 69 .Append(Identifier) 70 .Append(0) // TODO: implement alternate setting 71 .Append((byte)Endpoints.Count) 72 .Append((byte)Class) 73 .Append(SubClass) 74 .Append(Protocol) 75 .Append(USBString.FromString(Description).Index); 76 } 77 78 protected readonly IUSBDevice device; 79 80 private readonly List<USBEndpoint> endpoints; 81 } 82 } 83