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