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.Peripherals.Input;
10 using System.Collections.Generic;
11 using Antmicro.Renode.Logging;
12 using Antmicro.Renode.Core;
13 
14 namespace Antmicro.Renode.Peripherals.USBDeprecated
15 {
16     public class USBTablet :IUSBPeripheral, IAbsolutePositionPointerInput
17     {
USBTablet()18         public USBTablet()
19         {
20             Reset();
21         }
22 
23         public event Action<uint> SendInterrupt;
24         public event Action <uint> SendPacket
25         {
26             add {}
27             remove {}
28         }
29 
GetSpeed()30         public USBDeviceSpeed GetSpeed()
31         {
32             return USBDeviceSpeed.Low;
33         }
34 
ClearFeature(USBPacket packet, USBSetupPacket setupPacket)35         public void ClearFeature(USBPacket packet, USBSetupPacket setupPacket)
36         {
37             throw new NotImplementedException();
38         }
39 
GetConfiguration()40         public byte[] GetConfiguration()
41         {
42             throw new NotImplementedException();
43         }
44 
SetAddress(uint address)45         public void SetAddress(uint address)
46         {
47             deviceAddress = address;
48         }
49 
GetInterface(USBPacket packet, USBSetupPacket setupPacket)50         public byte[] GetInterface(USBPacket packet, USBSetupPacket setupPacket)
51         {
52             throw new NotImplementedException();
53         }
54 
GetStatus(USBPacket packet, USBSetupPacket setupPacket)55         public byte[] GetStatus(USBPacket packet, USBSetupPacket setupPacket)
56         {
57             var arr = new byte[2];
58             return arr;
59         }
60 
SetConfiguration(USBPacket packet, USBSetupPacket setupPacket)61         public void SetConfiguration(USBPacket packet, USBSetupPacket setupPacket)
62         {
63 
64         }
65 
SetDescriptor(USBPacket packet, USBSetupPacket setupPacket)66         public void SetDescriptor(USBPacket packet, USBSetupPacket setupPacket)
67         {
68             throw new NotImplementedException();
69         }
70 
SetFeature(USBPacket packet, USBSetupPacket setupPacket)71         public void SetFeature(USBPacket packet, USBSetupPacket setupPacket)
72         {
73             throw new NotImplementedException();
74         }
75 
SetInterface(USBPacket packet, USBSetupPacket setupPacket)76         public void SetInterface(USBPacket packet, USBSetupPacket setupPacket)
77         {
78             throw new NotImplementedException();
79         }
80 
ProcessVendorGet(USBPacket packet, USBSetupPacket setupPacket)81         public byte[] ProcessVendorGet(USBPacket packet, USBSetupPacket setupPacket)
82         {
83             throw new NotImplementedException();
84         }
85 
ProcessVendorSet(USBPacket packet, USBSetupPacket setupPacket)86         public void ProcessVendorSet(USBPacket packet, USBSetupPacket setupPacket)
87         {
88             throw new NotImplementedException();
89         }
90 
ProcessClassGet(USBPacket packet, USBSetupPacket setupPacket)91         public byte[] ProcessClassGet(USBPacket packet, USBSetupPacket setupPacket)
92         {
93             return controlPacket;
94         }
95 
ProcessClassSet(USBPacket packet, USBSetupPacket setupPacket)96         public void ProcessClassSet(USBPacket packet, USBSetupPacket setupPacket)
97         {
98 
99         }
100 
SetDataToggle(byte endpointNumber)101         public void SetDataToggle(byte endpointNumber)
102         {
103             throw new NotImplementedException();
104         }
105 
CleanDataToggle(byte endpointNumber)106         public void CleanDataToggle(byte endpointNumber)
107         {
108             throw new NotImplementedException();
109         }
110 
GetDataToggle(byte endpointNumber)111         public bool GetDataToggle(byte endpointNumber)
112         {
113             throw new NotImplementedException();
114         }
115 
ToggleDataToggle(byte endpointNumber)116         public void ToggleDataToggle(byte endpointNumber)
117         {
118             throw new NotImplementedException();
119         }
120 
GetAddress()121         public uint GetAddress()
122         {
123             return deviceAddress;
124         }
125 
WriteInterrupt(USBPacket packet)126         public byte[] WriteInterrupt(USBPacket packet)
127         {
128             lock(thisLock)
129             {
130                 if(changeState)
131                 {
132                     buffer[5] = 0;
133                     changeState = false;
134                     return this.buffer;
135                 }
136                 else
137                     return null;
138             }
139         }
140 
GetDataBulk(USBPacket packet)141         public byte[] GetDataBulk(USBPacket packet)
142         {
143             return null;
144         }
145 
GetDataControl(USBPacket packet)146         public byte[] GetDataControl(USBPacket packet)
147         {
148             return controlPacket;
149         }
150 
GetTransferStatus()151         public byte GetTransferStatus()
152         {
153             return 0;
154         }
155 
GetDescriptor(USBPacket packet, USBSetupPacket setupPacket)156         public byte[] GetDescriptor(USBPacket packet, USBSetupPacket setupPacket)
157         {
158             DescriptorType type;
159             type = (DescriptorType)((setupPacket.value & 0xff00) >> 8);
160             uint index = (uint)(setupPacket.value & 0xff);
161             switch(type)
162             {
163             case DescriptorType.Device:
164                 controlPacket = new byte[deviceDescriptor.ToArray().Length];
165                 deviceDescriptor.ToArray().CopyTo(controlPacket, 0);
166                 return deviceDescriptor.ToArray();
167             case DescriptorType.Configuration:
168                 controlPacket = new byte[configurationDescriptor.ToArray().Length];
169                 configurationDescriptor.ToArray().CopyTo(controlPacket, 0);
170                 controlPacket = tabletConfigDescriptor;
171                 return configurationDescriptor.ToArray();
172             case DescriptorType.DeviceQualifier:
173                 controlPacket = new byte[deviceQualifierDescriptor.ToArray().Length];
174                 deviceQualifierDescriptor.ToArray().CopyTo(controlPacket, 0);
175                 return deviceQualifierDescriptor.ToArray();
176             case DescriptorType.InterfacePower:
177                 throw new NotImplementedException("Interface Power Descriptor is not yet implemented. Please contact AntMicro for further support.");
178             case DescriptorType.OtherSpeedConfiguration:
179                 controlPacket = new byte[otherConfigurationDescriptor.ToArray().Length];
180                 otherConfigurationDescriptor.ToArray().CopyTo(controlPacket, 0);
181                 return otherConfigurationDescriptor.ToArray();
182             case DescriptorType.String:
183                 if(index == 0)
184                 {
185                     stringDescriptor = new StringUSBDescriptor(1);
186                     stringDescriptor.LangId[0] = EnglishLangId;
187                 }
188                 else
189                 {
190                     stringDescriptor = new StringUSBDescriptor(stringValues[setupPacket.index][index]);
191                 }
192                 controlPacket = new byte[stringDescriptor.ToArray().Length];
193                 stringDescriptor.ToArray().CopyTo(controlPacket, 0);
194                 return stringDescriptor.ToArray();
195             case (DescriptorType)0x22:
196                 controlPacket = tabletHIDReportDescriptor;
197                 break;
198             default:
199                 this.Log(LogLevel.Warning, "Unsupported mouse request!!!");
200                 return null;
201             }
202             return null;
203         }
204 
WriteDataBulk(USBPacket packet)205         public void WriteDataBulk(USBPacket packet)
206         {
207 
208         }
209 
WriteDataControl(USBPacket packet)210         public void WriteDataControl(USBPacket packet)
211         {
212 
213         }
214 
Reset()215         public void Reset()
216         {
217             x = y = 0;
218             otherConfigurationDescriptor = new ConfigurationUSBDescriptor();
219             deviceQualifierDescriptor = new DeviceQualifierUSBDescriptor();
220             endpointDescriptor = new EndpointUSBDescriptor[3];
221             for(int i = 0; i < NumberOfEndpoints; i++)
222             {
223                 endpointDescriptor[i] = new EndpointUSBDescriptor();
224             }
225             fillEndpointsDescriptors(endpointDescriptor);
226             interfaceDescriptor[0].EndpointDescriptor = endpointDescriptor;
227             configurationDescriptor.InterfaceDescriptor = interfaceDescriptor;
228 
229             mstate = 0;
230             changeState = false;
231             buffer = new byte[6];
232         }
233 
Press(MouseButton button)234         public void Press(MouseButton button)
235         {
236             lock(thisLock)
237             {
238                 mstate = (byte)button;
239                 buffer[0] = mstate;
240                 buffer[1] = (byte)(x & byte.MaxValue);
241                 // x small
242                 buffer[2] = (byte)((x >> 8) & 127);
243                 // x big
244                 buffer[3] = (byte)(y & byte.MaxValue);
245                 // y small
246                 buffer[4] = (byte)((y >> 8) & 127);
247                 // y big
248                 changeState = true;
249             }
250             Refresh();
251         }
252 
Release(MouseButton button)253         public void Release(MouseButton button)
254         {
255             lock(thisLock)
256             {
257                 buffer[0] = mstate = 0;
258                 buffer[1] = (byte)(x & byte.MaxValue);
259                 // x small
260                 buffer[2] = (byte)((x >> 8) & 127);
261                 // x big
262                 buffer[3] = (byte)(y & byte.MaxValue);
263                 // y small
264                 buffer[4] = (byte)((y >> 8) & 127);
265                 // y big
266                 changeState = true;
267             }
268             Refresh();
269         }
270 
MoveTo(int x, int y)271         public void MoveTo(int x, int y)
272         {
273             lock(thisLock)
274             {
275                 this.x = x;
276                 this.y = y;
277                 buffer[0] = mstate;
278                 buffer[1] = (byte)(x & byte.MaxValue);
279                 // x small
280                 buffer[2] = (byte)((x >> 8) & 127);
281                 // x big
282                 buffer[3] = (byte)(y & byte.MaxValue);
283                 // y small
284                 buffer[4] = (byte)((y >> 8) & 127);
285                 // y big
286                 changeState = true;
287             }
288             Refresh();
289         }
290 
291         public int MaxX
292         {
293             get
294             {
295                 return 32767;
296             }
297         }
298 
299         public int MaxY
300         {
301             get
302             {
303                 return 32767;
304             }
305         }
306 
307         public int MinX
308         {
309             get
310             {
311                 return 0;
312             }
313         }
314 
315         public int MinY
316         {
317             get
318             {
319                 return 0;
320             }
321         }
322 
fillEndpointsDescriptors(EndpointUSBDescriptor[] endpointDesc)323         private void fillEndpointsDescriptors(EndpointUSBDescriptor[] endpointDesc)
324         {
325             endpointDesc[0].EndpointNumber = 1;
326             endpointDesc[0].InEnpoint = true;
327             endpointDesc[0].TransferType = EndpointUSBDescriptor.TransferTypeEnum.Interrupt;
328             endpointDesc[0].MaxPacketSize = 0x0008;
329             endpointDesc[0].SynchronizationType = EndpointUSBDescriptor.SynchronizationTypeEnum.NoSynchronization;
330             endpointDesc[0].UsageType = EndpointUSBDescriptor.UsageTypeEnum.Data;
331             endpointDesc[0].Interval = 0x0a;
332         }
333 
Refresh()334         private void Refresh()
335         {
336             if(deviceAddress != 0)
337             {
338                 SendInterrupt(deviceAddress);
339             }
340         }
341 
342         private const byte NumX = 28;
343         private const byte NumY = 16;
344         private const ushort EnglishLangId = 0x09;
345         private const byte NumberOfEndpoints = 2;
346 
347         private uint deviceAddress;
348         private Object thisLock = new Object();
349         private DeviceQualifierUSBDescriptor deviceQualifierDescriptor;
350         private ConfigurationUSBDescriptor otherConfigurationDescriptor;
351         private StringUSBDescriptor stringDescriptor = null;
352         private EndpointUSBDescriptor[] endpointDescriptor;
353         private byte[] controlPacket;
354         private Byte[] buffer;
355         private int x;
356         private int y;
357         private byte mstate = 0;
358         private bool changeState = false;
359         private Dictionary<ushort, string[]> stringValues = new Dictionary<ushort, string[]>() { {EnglishLangId, new string[] {
360                     "",
361                     "1",
362                     "HID Tablet",
363                     "AntMicro",
364                     "",
365                     "",
366                     "HID Tablet",
367                     "Configuration"
368                 }
369             }
370         };
371         private InterfaceUSBDescriptor[] interfaceDescriptor = new[] {new InterfaceUSBDescriptor {
372                 AlternateSetting = 0,
373                 InterfaceNumber = 0x00,
374                 NumberOfEndpoints = 1,
375                 InterfaceClass = 0x03,
376                 InterfaceProtocol = 0x02,
377                 InterfaceSubClass = 0x01,
378                 InterfaceIndex = 0x07
379             }
380         };
381         private ConfigurationUSBDescriptor configurationDescriptor = new ConfigurationUSBDescriptor() {
382             ConfigurationIndex = 0,
383             SelfPowered = true,
384             NumberOfInterfaces = 1,
385             RemoteWakeup = true,
386             MaxPower = 50, //500mA
387             ConfigurationValue = 1
388         };
389 
390         private StandardUSBDescriptor deviceDescriptor = new StandardUSBDescriptor {
391             DeviceClass = 0x00,
392             DeviceSubClass = 0x00,
393             USB = 0x0100,
394             DeviceProtocol = 0x00,
395             MaxPacketSize = 8,
396             VendorId = 0x80ee,
397             ProductId = 0x0021,
398             Device = 0x0000,
399             ManufacturerIndex = 3,
400             ProductIndex = 2,
401             SerialNumberIndex = 1,
402             NumberOfConfigurations = 1
403         };
404 
405         private byte[] tabletConfigDescriptor = {
406             0x09,
407             0x02,
408             0x22, 0x00,
409             0x01,
410             0x01,
411             0x05,
412             0xa0,
413             50,
414             0x09,
415             0x04,
416             0x00,
417             0x00,
418             0x01,
419             0x03,
420             0x01,
421             0x02,
422             0x07,
423             0x09,
424             0x21,
425             0x01, 0x00,
426             0x00,
427             0x01,
428             0x22,
429             74, 0,
430             0x07,
431             0x05,
432             0x81,
433             0x03,
434             0x04, 0x00,
435             0x0a
436         };
437         private byte[] tabletHIDReportDescriptor = {
438             0x05, 0x01,
439             0x09, 0x01,
440             0xa1, 0x01,
441             0x09, 0x01,
442             0xa1, 0x00,
443             0x05, 0x09,
444             0x19, 0x01,
445             0x29, 0x03,
446             0x15, 0x00,
447             0x25, 0x01,
448             0x95, 0x03,
449             0x75, 0x01,
450             0x81, 0x02,
451             0x95, 0x01,
452             0x75, 0x05,
453             0x81, 0x01,
454             0x05, 0x01,
455             0x09, 0x30,
456             0x09, 0x31,
457             0x15, 0x00,
458             0x26, 0xff, 0x7f,
459             0x35, 0x00,
460             0x46, 0xff, 0x7f,
461             0x75, 0x10,
462             0x95, 0x02,
463             0x81, 0x02,
464             0x05, 0x01,
465             0x09, 0x38,
466             0x15, 0x81,
467             0x25, 0x7f,
468             0x35, 0x00,
469             0x45, 0x00,
470             0x75, 0x08,
471             0x95, 0x01,
472             0x81, 0x06,
473             0xc0,
474             0xc0,
475         };
476     }
477 }
478 
479