USB Mass Storage emulator for Facedancer. Doesn't work yet.
[goodfet] / client / goodfet.maxusbmass
1 #!/usr/bin/env python
2
3 #USB Mass Storage Emulator
4 #by Travis Goodspeed
5 #with thanks to Brandon Wilson and his Linky project.
6
7 import sys;
8 import binascii;
9 import array;
10 import time;
11
12 from GoodFETMAXUSB import *;
13
14 class GoodFETMAXUSBMass(GoodFETMAXUSB):
15     """This emulates a USB Mass Storage device."""
16     def massinit(self):
17         """Initialize a USB Mass Storage device."""
18         self.usb_disconnect();
19         time.sleep(1);
20         self.usb_connect();
21         self.massrun();
22         
23     def massrun(self):
24         """Main loop of the USB Mass Storage emulator."""
25         print "Starting a Mass Storage device.  This doesn't work yet.";
26         while 1:
27             self.service_irqs();
28     def do_SETUP(self):
29         """Handle USB Enumeration"""
30         
31         #Grab the SETUP packet from the buffer.
32         SUD=self.readbytes(rSUDFIFO,8);
33         
34         #Parse the SETUP packet
35         print "Handling a setup packet of %s" % self.setup2str(SUD);
36         setuptype=(ord(SUD[bmRequestType])&0x60);
37         if setuptype==0x00:
38             self.std_request(SUD);
39         elif setuptype==0x20:
40             print "XXXXXXXXXX Got a class request."
41             self.class_request(SUD);
42         elif setuptype==0x40:
43             self.vendor_request(SUD);
44         else:
45             print "Unknown bmRequestType=0x%02x." % ord(SUD[bmRequestType])
46             self.STALL_EP0(SUD);
47     def class_request(self,SUD):
48         """Handle a class request."""
49         print "Stalling a class request.";
50         self.STALL_EP0(SUD);
51     def vendor_request(self,SUD):
52         """Handle a vendor request."""
53         request=ord(SUD[bRequest]);
54         print "Why the hell is there a vendor request?";
55         #self.wreg(rEP0FIFO,0);
56         self.wregAS(rEP0BC,0);
57     def std_request(self,SUD):
58         """Handles a standard setup request."""
59         setuptype=ord(SUD[bRequest]);
60         if setuptype==SR_GET_DESCRIPTOR: self.send_descriptor(SUD);
61         #elif setuptype==SR_SET_FEATURE: self.feature(1);
62         elif setuptype==SR_SET_CONFIGURATION: self.set_configuration(SUD);
63         elif setuptype==SR_GET_STATUS: self.get_status(SUD);
64         elif setuptype==SR_SET_ADDRESS: self.rregAS(rFNADDR);
65         elif setuptype==SR_GET_INTERFACE: self.get_interface(SUD);
66         else:
67             print "Stalling Unknown standard setup request type %02x" % setuptype;
68             self.STALL_EP0(SUD);
69     
70     def get_interface(self,SUD):
71         """Handles a setup request for SR_GET_INTERFACE."""
72         if ord(SUD[wIndexL]==0):
73             self.wreg(rEP0FIFO,0);
74             self.wregAS(rEP0BC,1);
75         else:
76             self.STALL_EP0(SUD);
77     
78
79 #0403:6001
80
81 #Device Descriptor
82     DD=[ 
83         
84     0x12, #length
85     0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
86     0x81, 0x07, #Sandisk 
87     0x50, 0x51, #SDCZ2 Cruzer Mini Flash Drive (thin)
88     0x00, 0x03, 0x00, 0x00, 0x00, 0x01
89     
90     ];
91
92 #Configuration Descriptor
93     CD=[
94
95   0x09, #Length
96   0x02, #Type
97   0x20, #Total Length
98   0x00, 0x01, 0x01, 0x00, 0xE0, 0x00, 0x09, 0x04, 0x00, 0x00,
99   0x02, #Num Endpoints
100   0x08, #Mass Storage Bulk Only
101   0x06, #SCSI
102   0x50, 0x00,
103   
104   #IN EP3
105   0x07, 0x05, 0x83, 0x02, 0x40, 0x00, 0x00,
106   #OUT EP1
107   0x07, 0x05, 0x01, 0x02, 0x40, 0x00, 0x00
108
109 ];
110     strDesc=[
111 # STRING descriptor 0--Language string
112 "\x04\x03\x09\x04",
113 # [
114 #         0x04,                 # bLength
115 #       0x03,                   # bDescriptorType = string
116 #       0x09,0x04               # wLANGID(L/H) = English-United Sates
117 # ],
118 # STRING descriptor 1--Manufacturer ID
119 "\x10\x03G\x00o\x00o\x00d\x00F\x00E\x00T\x00",
120 # STRING descriptor 2 - Product ID
121 "\x1C\x03M\x00A\x00S\x00S\x00 \x00E\x00m\x00u\x00l\x00a\x00t\x00o\x00r\x00",
122 # STRING descriptor 3 - Serial Number ID
123 "\x14\x03S\x00/\x00N\x00 \x003\x004\x002\x000\x00E\x00"
124 ];
125
126     def send_descriptor(self,SUD):
127         """Send the USB descriptors based upon the setup data."""
128         desclen=0;
129         reqlen=ord(SUD[wLengthL])+256*ord(SUD[wLengthH]); #16-bit length
130         desctype=ord(SUD[wValueH]);
131         
132         if desctype==GD_DEVICE:
133             desclen=self.DD[0];
134             ddata=self.DD;
135         elif desctype==GD_CONFIGURATION:
136             desclen=self.CD[2];
137             ddata=self.CD;
138         elif desctype==GD_STRING:
139             desclen=self.strDesc[ord(SUD[wValueL])][0];
140             ddata=self.strDesc[ord(SUD[wValueL])];
141         
142         #TODO Configuration, String, Hid, and Report
143         
144         if desclen>0:
145             sendlen=min(reqlen,desclen);
146             self.writebytes(rEP0FIFO,ddata);
147             self.wregAS(rEP0BC,sendlen);
148         else:
149             print "Stalling in send_descriptor() for lack of handler for %02x." % desctype;
150             self.STALL_EP0(SUD);
151     def set_configuration(self,SUD):
152         """Set the configuration."""
153         bmSUSPIE=0x10;
154         configval=ord(SUD[wValueL]);
155         if(configval>0):
156             self.SETBIT(rUSBIEN,bmSUSPIE);
157         self.rregAS(rFNADDR);
158     def get_status(self,SUD):
159         """Get the USB Setup Status."""
160         testbyte=ord(SUD[bmRequestType])
161         
162         #Toward Device
163         if testbyte==0x80:
164             self.wreg(rEP0FIFO,0x03); #Enable RWU and self-powered
165             self.wreg(rEP0FIFO,0x00); #Second byte is always zero.
166             self.wregAS(rEP0BC,2);    #Load byte count, arm transfer, and ack CTL.
167         #Toward Interface
168         elif testbyte==0x81:
169             self.wreg(rEP0FIFO,0x00);
170             self.wreg(rEP0FIFO,0x00); #Second byte is always zero.
171             self.wregAS(rEP0BC,2);
172         #Toward Endpoint
173         elif testbyte==0x82:
174             if(ord(SUD[wIndexL])==0x83):
175                 print "This code almost certainly doesn't work.";
176                 self.wreg(rEP0FIFO,0x01); #Stall EP3
177                 self.wreg(rEP0FIFO,0x00); #Second byte is always zero.
178                 self.wregAS(rEP0BC,2);
179             else:
180                 self.STALL_EP0(SUD);
181         else:
182             self.STALL_EP0(SUD);
183     def service_irqs(self):
184         """Handle USB interrupt events."""
185         
186         epirq=self.rreg(rEPIRQ);
187         usbirq=self.rreg(rUSBIRQ);
188         
189         #Are we being asked for setup data?
190         if(epirq&bmSUDAVIRQ): #Setup Data Requested
191             self.wreg(rEPIRQ,bmSUDAVIRQ); #Clear the bit
192             self.do_SETUP();
193         elif(epirq&bmIN3BAVIRQ): #EN3-IN packet
194             self.do_IN3();
195             #self.wreg(rEPIRQ,bmIN3BAVIRQ); #Clear the bit
196         elif(epirq&bmOUT1DAVIRQ): #OUT1-OUT packet
197             self.do_OUT1();
198             self.wregAS(rEPIRQ,bmOUT1DAVIRQ); #Clear the bit *AFTER* servicing.
199         #else:
200         #    self.do_IN3();
201     
202     typestring="GoodFET emulates Mass properly, if you can read this!\n";
203     typepos=0;
204     
205     def do_IN3(self):
206         """Handle IN3 input event."""
207         #Don't bother clearing interrupt flag, that's done by sending the reply.
208         #self.type_IN3();
209         print "Got an input event, no idea what to do about it.";
210         self.wreg(rEP3INFIFO,0x01);      #Modem Status
211         self.wreg(rEP3INFIFO,0x00);      #Line Status
212         self.wreg(rEP3INFIFO,0x00);
213         self.wregAS(rEP3INBC,3);
214     def do_OUT1(self):
215         """Handle an OUT1 output event."""
216         print "Got an output event, printing the result.";
217         l=self.rreg(rEP1OUTBC);
218         frame=self.readbytesAS(rEP1OUTFIFO,l);
219         print "Mass OUT: %s" % frame[1:len(frame)];
220         #self.type_IN3();
221
222 #Initialize FET and set baud rate
223 client=GoodFETMAXUSBMass();
224 client.serInit()
225
226
227 client.MAXUSBsetup();
228 client.massinit();
229