1 //
2 // Copyright (c) 2010-2018 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.Collections.Generic;
8 using System.Linq;
9 using Antmicro.Renode.Utilities;
10 
11 namespace Antmicro.Renode.Core.USB.HID
12 {
13     public class ReportDescriptor : IProvidesDescriptor
14     {
ReportDescriptor(byte[] rawDescriptor)15         public ReportDescriptor(byte[] rawDescriptor)
16         {
17             this.rawDescriptor = rawDescriptor;
18         }
19 
ReportDescriptor()20         public ReportDescriptor()
21         {
22             items = new List<UsbHidItem>();
23         }
24 
GetDescriptor(bool recursive, BitStream buffer = null)25         public BitStream GetDescriptor(bool recursive, BitStream buffer = null)
26         {
27             if(buffer == null)
28             {
29                 buffer = new BitStream();
30             }
31 
32             if(rawDescriptor != null)
33             {
34                 foreach(var b in rawDescriptor)
35                 {
36                     buffer.Append(b);
37                 }
38             }
39             else
40             {
41                 foreach(var item in items)
42                 {
43                     item.FillDescriptor(buffer);
44                 }
45             }
46 
47             return buffer;
48         }
49 
50         public int RecursiveDescriptorLength => DescriptorLength;
51 
52         public int DescriptorLength => rawDescriptor != null
53             ? rawDescriptor.Length
54             : items.Sum(x => x.Data.Length + 1);
55 
56         private readonly List<UsbHidItem> items;
57         private readonly byte[] rawDescriptor;
58 
59         public class UsbHidItem
60         {
UsbHidItem()61             public UsbHidItem()
62             {
63             }
64 
FillDescriptor(BitStream buffer)65             public void FillDescriptor(BitStream buffer)
66             {
67                 buffer.Append((byte)((Tag << 4) | ((byte)Type << 2) | (byte)Size));
68                 for(var i = 0; i < Data.Length; i++)
69                 {
70                     buffer.Append(Data[i]);
71                 }
72             }
73 
74             public ItemSize Size { get; }
75             public ItemType Type { get; }
76             public byte Tag { get; }
77             public byte[] Data { get; }
78         }
79 
80         public enum ItemSize
81         {
82             Size0 = 0,
83             Size1 = 1,
84             Size2 = 2,
85             Size4 = 3
86         }
87 
88         public enum ItemType
89         {
90             Main = 0,
91             Global = 1,
92             Local = 2,
93             Reserved = 3
94         }
95     }
96 }