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