66c2e81b1a580205b65646e53abd5205e650778b
[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(GoodFETMAXUSBDevice):
15     """This emulates a USB Mass Storage device."""
16     
17     def getSectorData(self,lba):
18         """Overload this to return data from a given 512-byte sector."""
19         print "You forgot to overload getSectorData().  Returning something neighborly.";
20         sector=[
21             0xE9, 0x86, 0x00, 0x0A, 0x47, 0x6F, 0x6F, 0x64, 0x44, 0x69, 0x73, 0x6B, 0x20, 0x30, 0x2E, 0x30,
22             0x31, 0x0A, 0x0D, 0x62, 0x79, 0x20, 0x54, 0x72, 0x61, 0x76, 0x69, 0x73, 0x20, 0x47, 0x6F, 0x6F,
23             0x64, 0x73, 0x70, 0x65, 0x65, 0x64, 0x0A, 0x0A, 0x0D, 0x00, 0x59, 0x6F, 0x75, 0x20, 0x68, 0x61,
24             0x76, 0x65, 0x20, 0x62, 0x65, 0x65, 0x6E, 0x20, 0x65, 0x61, 0x74, 0x65, 0x6E, 0x20, 0x62, 0x79,
25             0x20, 0x61, 0x20, 0x67, 0x72, 0x75, 0x65, 0x2E, 0x20, 0x20, 0x53, 0x6F, 0x72, 0x72, 0x79, 0x2E,
26             0x0A, 0x0D, 0x00, 0x31, 0x29, 0x20, 0x52, 0x65, 0x61, 0x64, 0x69, 0x6E, 0x67, 0x20, 0x6B, 0x65,
27             0x72, 0x6E, 0x65, 0x6C, 0x20, 0x66, 0x72, 0x6F, 0x6D, 0x20, 0x64, 0x69, 0x73, 0x6B, 0x2E, 0x0A,
28             0x0D, 0x00, 0x32, 0x29, 0x20, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6E, 0x67, 0x20, 0x6B,
29             0x65, 0x72, 0x6E, 0x65, 0x6C, 0x2E, 0x0A, 0x0D, 0x00, 0xBE, 0x03, 0x7C, 0xE8, 0x41, 0x00, 0xE8,
30             0x7B, 0x00, 0x31, 0xC0, 0x30, 0xD2, 0xCD, 0x13, 0x0F, 0x82, 0xE8, 0x00, 0xBE, 0x53, 0x7C, 0xE8,
31             0x2E, 0x00, 0xB8, 0xE0, 0x07, 0x8E, 0xC0, 0x31, 0xDB, 0xB8, 0x10, 0x02, 0xB5, 0x00, 0xB1, 0x02,
32             0xB6, 0x00, 0xB2, 0x00, 0xCD, 0x13, 0x0F, 0x82, 0xCA, 0x00, 0xB8, 0x00, 0x7E, 0x89, 0xC6, 0xE8,
33             0x7C, 0x00, 0xBE, 0x72, 0x7C, 0xE8, 0x08, 0x00, 0xEA, 0x00, 0x00, 0xE0, 0x07, 0xE8, 0xB4, 0x00,
34             0xAC, 0x3C, 0x00, 0x74, 0x06, 0xB4, 0x0E, 0xCD, 0x10, 0xEB, 0xF5, 0xC3, 0x30, 0x78, 0x00, 0x20,
35             0x62, 0x79, 0x74, 0x65, 0x73, 0x20, 0x6F, 0x66, 0x20, 0x6D, 0x65, 0x6D, 0x6F, 0x72, 0x79, 0x20,
36             0x64, 0x65, 0x74, 0x65, 0x63, 0x74, 0x65, 0x64, 0x2E, 0x0A, 0x0D, 0x00, 0x53, 0x65, 0x67, 0x6D,
37             0x65, 0x6E, 0x74, 0x73, 0x3A, 0x20, 0x00, 0x2C, 0x20, 0x00, 0x0A, 0x0D, 0x00, 0xBE, 0xDC, 0x7C,
38             0xE8, 0xBD, 0xFF, 0xE8, 0x63, 0x00, 0xE8, 0x07, 0x00, 0xBE, 0xDF, 0x7C, 0xE8, 0xB1, 0xFF, 0xC3,
39             0x89, 0xC3, 0xC1, 0xE8, 0x0C, 0xE8, 0x39, 0x00, 0x89, 0xD8, 0xC1, 0xE8, 0x08, 0xE8, 0x31, 0x00,
40             0x89, 0xD8, 0xC1, 0xE8, 0x04, 0xE8, 0x29, 0x00, 0x89, 0xD8, 0xE8, 0x24, 0x00, 0xC3, 0x31, 0xC9,
41             0xAD, 0xE8, 0xDC, 0xFF, 0xE8, 0x2C, 0x00, 0x83, 0xC1, 0x02, 0x81, 0xF9, 0x00, 0x02, 0x75, 0xF0,
42             0xC3, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45,
43             0x46, 0x50, 0x56, 0x83, 0xE0, 0x0F, 0x05, 0x51, 0x7D, 0x89, 0xC6, 0xAC, 0xB4, 0x0E, 0xCD, 0x10,
44             0x5E, 0x58, 0xC3, 0xB8, 0x20, 0x0E, 0xCD, 0x10, 0xC3, 0x31, 0xC0, 0xCD, 0x12, 0x72, 0x05, 0x85,
45             0xC0, 0x74, 0x01, 0xC3, 0xBE, 0x2A, 0x7C, 0xE8, 0x46, 0xFF, 0xEB, 0xFE, 0xEA, 0x00, 0x00, 0xFF,
46             0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
47             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
48             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
49             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
50             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
51             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
52             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xAA
53             ];
54         return sector;
55     def putSectorData(self,lba,block):
56         """Overload this to write data to a given 512-byte sector."""
57         
58         return;
59     
60     def massinit(self):
61         """Initialize a USB Mass Storage device."""
62         self.usb_disconnect();
63         time.sleep(1);
64         self.usb_connect();
65         self.massrun();
66         
67     def massrun(self):
68         """Main loop of the USB Mass Storage emulator."""
69         print "Starting a Mass Storage device.  This doesn't work yet.";
70         while 1:
71             self.service_irqs();
72     def do_SETUP(self):
73         """Handle USB Enumeration"""
74         
75         #Grab the SETUP packet from the buffer.
76         SUD=self.readbytes(rSUDFIFO,8);
77         
78         #Parse the SETUP packet
79         print "Handling a setup packet of %s" % self.setup2str(SUD);
80         setuptype=(ord(SUD[bmRequestType])&0x60);
81         if setuptype==0x00:
82             self.std_request(SUD);
83         elif setuptype==0x20:
84             self.class_request(SUD);
85         elif setuptype==0x40:
86             self.vendor_request(SUD);
87         else:
88             print "Unknown bmRequestType=0x%02x." % ord(SUD[bmRequestType])
89             self.STALL_EP0(SUD);
90     def class_request(self,SUD):
91         """Handle a class request."""
92         requesttype=ord(SUD[bmRequestType]);
93         request=ord(SUD[bRequest]);
94         if requesttype==0xA1 and request==0xFE:
95             print "Reporting 0 as the maximum LUN.";
96             #This is a Get Max LUN request.
97             #Return 1-byte maximum Logical Unit Number
98             self.wreg(rEP0FIFO,0x00); # Just one LUN.
99             self.wregAS(rEP0BC,1); # ARM and fire!
100             return; #Don't stall.
101         if requesttype==0x21 and request==0xff:
102             print "Received BBB reset."
103             self.wregAS(rEP0BC,0); # ARM and fire!
104             return; #Don't stall.
105         print "Stalling an unknown class request: %s" % self.setup2str(SUD);
106         self.STALL_EP0(SUD);
107     def vendor_request(self,SUD):
108         """Handle a vendor request."""
109         request=ord(SUD[bRequest]);
110         print "Why the hell is there a vendor request?";
111         #self.wreg(rEP0FIFO,0);
112         self.wregAS(rEP0BC,0);
113     def std_request(self,SUD):
114         """Handles a standard setup request."""
115         setuptype=ord(SUD[bRequest]);
116         if setuptype==SR_GET_DESCRIPTOR: self.send_descriptor(SUD);
117         #elif setuptype==SR_SET_FEATURE: self.feature(1);
118         elif setuptype==SR_SET_CONFIGURATION: self.set_configuration(SUD);
119         elif setuptype==SR_GET_STATUS: self.get_status(SUD);
120         elif setuptype==SR_SET_ADDRESS: self.rregAS(rFNADDR);
121         elif setuptype==SR_GET_INTERFACE: self.get_interface(SUD);
122         else:
123             #print "Stalling Unknown standard setup request type %02x" % setuptype;
124             #self.STALL_EP0(SUD);
125             print "Accepting unknown standard setup request type %02x" % setuptype;
126             self.wregAS(rEP0BC,0);
127             
128     def get_interface(self,SUD):
129         """Handles a setup request for SR_GET_INTERFACE."""
130         if ord(SUD[wIndexL]==0):
131             self.wreg(rEP0FIFO,0);
132             self.wregAS(rEP0BC,1);
133         else:
134             self.STALL_EP0(SUD);
135     
136
137
138 #Device Descriptor
139     DD=[ 
140         
141     0x12, #length
142     0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
143     0x81, 0x07, #Sandisk 
144     0x50, 0x51, #SDCZ2 Cruzer Mini Flash Drive (thin)
145     0x00, 0x03,
146     0x01, 0x02, 0x03, #Strings
147     0x01
148     
149     ];
150
151 #Configuration Descriptor
152     CD=[
153
154   0x09, #Length
155   0x02, #Type
156   0x20, #Total Length
157   0x00, 0x01, 0x01, 0x00, 0xE0, 0x00, 0x09, 0x04, 0x00, 0x00,
158   0x02, #Num Endpoints
159   0x08, #Mass Storage Bulk Only
160   0x06, #SCSI
161   0x50, 0x00,
162   
163   #OUT EP1
164   0x07, 0x05, 0x01, 0x02, 0x40, 0x00, 0x00,
165   #IN EP3
166   0x07, 0x05, 0x83, 0x02, 0x40, 0x00, 0x00,
167
168 ];
169     strDesc=[
170 # STRING descriptor 0--Language string
171 "\x04\x03\x09\x04",
172 # [
173 #         0x04,                 # bLength
174 #       0x03,                   # bDescriptorType = string
175 #       0x09,0x04               # wLANGID(L/H) = English-United Sates
176 # ],
177 # STRING descriptor 1--Manufacturer ID
178 "\x10\x03G\x00o\x00o\x00d\x00F\x00E\x00T\x00",
179 # STRING descriptor 2 - Product ID
180 "\x1C\x03M\x00A\x00S\x00S\x00 \x00E\x00m\x00u\x00l\x00a\x00t\x00o\x00r\x00",
181 # STRING descriptor 3 - Serial Number ID
182 "\x14\x03S\x00/\x00N\x00 \x003\x004\x002\x000\x00E\x00"
183 ];
184
185     def get_status(self,SUD):
186         """Get the USB Setup Status."""
187         testbyte=ord(SUD[bmRequestType])
188         
189         #Toward Device
190         if testbyte==0x80:
191             self.wreg(rEP0FIFO,0x03); #Enable RWU and self-powered
192             self.wreg(rEP0FIFO,0x00); #Second byte is always zero.
193             self.wregAS(rEP0BC,2);    #Load byte count, arm transfer, and ack CTL.
194         #Toward Interface
195         elif testbyte==0x81:
196             self.wreg(rEP0FIFO,0x00);
197             self.wreg(rEP0FIFO,0x00); #Second byte is always zero.
198             self.wregAS(rEP0BC,2);
199         #Toward Endpoint
200         elif testbyte==0x82:
201             if(ord(SUD[wIndexL])==0x83):
202                 print "This code almost certainly doesn't work.";
203                 self.wreg(rEP0FIFO,0x01); #Stall EP3
204                 self.wreg(rEP0FIFO,0x00); #Second byte is always zero.
205                 self.wregAS(rEP0BC,2);
206             else:
207                 print "Stalling unknown status.";
208                 self.STALL_EP0(SUD);
209         else:
210             print "Stalling unknown status.";
211             self.STALL_EP0(SUD);
212     
213     def do_IN3(self):
214         """Handle IN3 input event."""
215         # Do nothing here, as it'll be taken care of elsewhere.  The
216         # interrupt just means that the buffer is empty, not that we
217         # are expected to fill it.
218         
219     def do_OUT1(self):
220         """Handle an OUT1 output event."""
221         print "Got an output event, printing the result.";
222         l=self.rreg(rEP1OUTBC);
223         frame=self.readbytes(rEP1OUTFIFO,l);
224         self.handleCBW(frame);
225         
226     lastCBW="";
227     def handleCBW(self,cbw):
228         """Handles an incoming Command Block Wrapper.  See USB Mass
229         Storage Class for details."""
230         
231         if len(cbw)!=31:
232             print "Invalid CBW length of %i bytes.  Aborting." % len(cbw);
233             return;
234         sig=cbw[0:4];
235         if sig!="USBC":
236             print "Invalid CBW signature: %s.  Should be USBC; aborting." % sig;
237             return;
238         self.lastCBW=cbw;
239         
240         dtlen=ord(cbw[8])+(ord(cbw[9])<<8)+(ord(cbw[10])<<16)+(ord(cbw[11])<<24);
241         flags=ord(cbw[12]);
242         dtdir=flags&0x80; # 0x80 for dev->host, 0x00 for host->dev
243         lun=ord(cbw[13])&0x0F; # Should be zero, as we only reported one LUN.
244         cblen=ord(cbw[14])&0x1F;
245         cb=cbw[15:31];
246         self.handleCB(cb,cblen,dtlen,dtdir);
247         
248     def handleCB(self,cb,cblen,dtlen,dtdir):
249         """Handles a command block, then replies with a CSW."""
250         print "\nGot command block 0x%02x, requesting 0x%02x bytes" % (
251             ord(cb[0]), dtlen);
252         verb=ord(cb[0]);
253         status=00; #good, set to 1 for bad.
254         if verb==0x00: # Test Unit Ready
255             # Send nothing, just the success code.
256             status=0;
257         elif verb==0x03: # Request Sense
258             print "Responding to Request Sense.  Needed for Macs.";
259             response=[0x70, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x0A,
260                       0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00,
261                       0x00, 0x00,
262                       0,0,0,0,0];
263             #status=1;
264             self.writebytes(rEP3INFIFO,
265                             response);
266             self.wreg(rEP3INBC,len(response));
267         elif verb==0x12: #Inquiry
268             #print "Responding to CB inquiry.";
269             response=[
270                 0x00, # 00 for Direct, 1F for "no floppy"
271                 0x80, # make 0x80 for removable media
272                 0x00, # Version
273                 0x01, # Response Data Format
274                 0x1f, #Additional length.
275                 0x00, 0x00, 0x00,
276                 #Manufacturer
277                 ord('G'),ord('o'),ord('o'),ord('d'),ord('F'),ord('E'),ord('T'),0x20,
278                 #Device name
279                 ord('G'),ord('o'),ord('o'),ord('d'),ord('F'),ord('E'),ord('T'),0x20,
280                 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
281                 ord('0'),ord('.'),ord('0'),ord('1')]
282             #print "Sending %i byte reply to %i byte query." % (
283             #        len(response),dtlen);
284             #while not(self.rreg(rEPIRQ)&bmIN3BAVIRQ):
285             #    #Wait for the packet to complete before sending the next.
286             #    print "Waiting to complete inquiry."
287             #    pass;
288             self.writebytes(rEP3INFIFO,
289                             response);
290             self.wregAS(rEP3INBC,
291                         dtlen);
292                         #len(response));
293             #self.wreg(rEPIRQ,bmIN3BAVIRQ); #Clear the bit
294             #while not(self.rreg(rEPIRQ)&bmIN3BAVIRQ):
295             #    #Wait for the packet to complete before sending the next.
296             #    print "Waiting to complete inquiry."
297             #    pass;
298         elif verb==0x1e: #Prevent/Allow Removal
299             # Give a good status to pretend we understand.
300             status=0x00;
301         elif verb==0x1A: #Mode Sense (6)
302             # I should probably send six bytes here.
303             response=[0x12,0,0,0, 0,0,0,0x1C];
304             self.writebytes(rEP3INFIFO,
305                             response);
306             self.wregAS(rEP3INBC,
307                         len(response));
308         elif verb==0x23: #Read Format Capacity
309             response=[
310                 0x00, 0,0x00,0x08, #Capacity list length.
311                 0,0x00,x10,0x00,   # Number of sectors, implying 10MB.
312                 0x01,0x00,            #reserved/desciptor code.
313                 0x02,0x00             # 512 bytes/sector.  Why is this twice?
314                 ];
315             self.writebytes(rEP3INFIFO,
316                             response);
317             self.wregAS(rEP3INBC,
318                         len(response));
319         elif verb==0x25: #Read Capacity
320             response=[
321                 0x00, 0,0x0f,0xFF, # Last LBA; might have endianness backward.
322                 0x00,0x00,0x02,0x00   # Block length of 512 bytes.
323                 ];
324             self.writebytes(rEP3INFIFO,
325                             response);
326             self.wregAS(rEP3INBC,
327                         len(response));
328         elif verb==0x28: #READ SECTOR
329             cbw=self.lastCBW;
330             baselba=(
331                 ord(cbw[20]) |
332                 (ord(cbw[19])<<8) |
333                 (ord(cbw[18])<<16) |
334                 (ord(cbw[17])<<24)
335                 );
336             count=dtlen/512;
337             print "Fetching %i blocks starting at  LBA %i." % (count,baselba);
338             for i in range(0,count):
339                 data=self.getSectorData(baselba+count);
340                 for j in range(0,8):
341                     print "Sending block fragment %i,%i" % (i,j);
342                     #Transmit each 64-byte block fragment, then wait for next.
343                     while not(self.rreg(rEPIRQ)&bmIN3BAVIRQ): pass;
344                     response=data[j*64:j*64+64];
345                     self.writebytes(rEP3INFIFO,
346                                     response);
347                     self.wregAS(rEP3INBC,
348                                 64);
349             #sys.exit();
350         elif verb==0x2A: #WRITE SECTOR
351             print "Haven't implemented WRITE SECTOR.";
352             sys.exit();
353         else:
354             print "ERROR: Unknown SCSI command block verb %02x." % verb;
355             status=1; #Command Failed
356             if dtlen>0:
357                 print "Perhaps I should send %i bytes of dummy data here." % dtlen;
358             sys.exit(1);
359         cbw=self.lastCBW;
360         
361         #Now we need to send the CSW.
362         csw=[
363             #Standard prefix.
364             ord('U'),ord('S'),ord('B'),ord('S'),
365             #CBW key; must be the same as the one we're replying to.
366             ord(cbw[4]),ord(cbw[5]),ord(cbw[6]),ord(cbw[7]),
367             #CSW Data Residue, probably oughtn't be zeroed.
368             0,0,0,0,
369             #Status byte: 00 for good, 01 for bad.
370             status];
371         self.writebytes(rEP3INFIFO,
372                         csw);
373         self.wregAS(rEP3INBC,len(csw));
374         
375         
376         return;
377 #Initialize FET and set baud rate
378 client=GoodFETMAXUSBMass();
379 client.serInit()
380
381 client.MAXUSBsetup();
382 client.massinit();
383