USB Mass Storage emulator for Facedancer. Doesn't work yet.
authortravisutk <travisutk@12e2690d-a6be-4b82-a7b7-67c4a43b65c8>
Tue, 17 Jul 2012 19:15:15 +0000 (19:15 +0000)
committertravisutk <travisutk@12e2690d-a6be-4b82-a7b7-67c4a43b65c8>
Tue, 17 Jul 2012 19:15:15 +0000 (19:15 +0000)
git-svn-id: https://svn.code.sf.net/p/goodfet/code/trunk@1200 12e2690d-a6be-4b82-a7b7-67c4a43b65c8

client/goodfet.maxusbmass [new file with mode: 0755]

diff --git a/client/goodfet.maxusbmass b/client/goodfet.maxusbmass
new file mode 100755 (executable)
index 0000000..950d67d
--- /dev/null
@@ -0,0 +1,229 @@
+#!/usr/bin/env python
+
+#USB Mass Storage Emulator
+#by Travis Goodspeed
+#with thanks to Brandon Wilson and his Linky project.
+
+import sys;
+import binascii;
+import array;
+import time;
+
+from GoodFETMAXUSB import *;
+
+class GoodFETMAXUSBMass(GoodFETMAXUSB):
+    """This emulates a USB Mass Storage device."""
+    def massinit(self):
+        """Initialize a USB Mass Storage device."""
+        self.usb_disconnect();
+        time.sleep(1);
+       self.usb_connect();
+        self.massrun();
+        
+    def massrun(self):
+        """Main loop of the USB Mass Storage emulator."""
+        print "Starting a Mass Storage device.  This doesn't work yet.";
+        while 1:
+            self.service_irqs();
+    def do_SETUP(self):
+        """Handle USB Enumeration"""
+        
+        #Grab the SETUP packet from the buffer.
+        SUD=self.readbytes(rSUDFIFO,8);
+        
+        #Parse the SETUP packet
+        print "Handling a setup packet of %s" % self.setup2str(SUD);
+        setuptype=(ord(SUD[bmRequestType])&0x60);
+        if setuptype==0x00:
+            self.std_request(SUD);
+        elif setuptype==0x20:
+            print "XXXXXXXXXX Got a class request."
+            self.class_request(SUD);
+        elif setuptype==0x40:
+            self.vendor_request(SUD);
+        else:
+            print "Unknown bmRequestType=0x%02x." % ord(SUD[bmRequestType])
+            self.STALL_EP0(SUD);
+    def class_request(self,SUD):
+        """Handle a class request."""
+        print "Stalling a class request.";
+        self.STALL_EP0(SUD);
+    def vendor_request(self,SUD):
+        """Handle a vendor request."""
+        request=ord(SUD[bRequest]);
+        print "Why the hell is there a vendor request?";
+        #self.wreg(rEP0FIFO,0);
+        self.wregAS(rEP0BC,0);
+    def std_request(self,SUD):
+        """Handles a standard setup request."""
+        setuptype=ord(SUD[bRequest]);
+        if setuptype==SR_GET_DESCRIPTOR: self.send_descriptor(SUD);
+        #elif setuptype==SR_SET_FEATURE: self.feature(1);
+        elif setuptype==SR_SET_CONFIGURATION: self.set_configuration(SUD);
+        elif setuptype==SR_GET_STATUS: self.get_status(SUD);
+        elif setuptype==SR_SET_ADDRESS: self.rregAS(rFNADDR);
+        elif setuptype==SR_GET_INTERFACE: self.get_interface(SUD);
+        else:
+            print "Stalling Unknown standard setup request type %02x" % setuptype;
+            self.STALL_EP0(SUD);
+    
+    def get_interface(self,SUD):
+        """Handles a setup request for SR_GET_INTERFACE."""
+        if ord(SUD[wIndexL]==0):
+            self.wreg(rEP0FIFO,0);
+            self.wregAS(rEP0BC,1);
+        else:
+            self.STALL_EP0(SUD);
+    
+
+#0403:6001
+
+#Device Descriptor
+    DD=[ 
+        
+    0x12, #length
+    0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
+    0x81, 0x07, #Sandisk 
+    0x50, 0x51, #SDCZ2 Cruzer Mini Flash Drive (thin)
+    0x00, 0x03, 0x00, 0x00, 0x00, 0x01
+    
+    ];
+
+#Configuration Descriptor
+    CD=[
+
+  0x09, #Length
+  0x02, #Type
+  0x20, #Total Length
+  0x00, 0x01, 0x01, 0x00, 0xE0, 0x00, 0x09, 0x04, 0x00, 0x00,
+  0x02, #Num Endpoints
+  0x08, #Mass Storage Bulk Only
+  0x06, #SCSI
+  0x50, 0x00,
+  
+  #IN EP3
+  0x07, 0x05, 0x83, 0x02, 0x40, 0x00, 0x00,
+  #OUT EP1
+  0x07, 0x05, 0x01, 0x02, 0x40, 0x00, 0x00
+
+];
+    strDesc=[
+# STRING descriptor 0--Language string
+"\x04\x03\x09\x04",
+# [
+#         0x04,                        # bLength
+#      0x03,                   # bDescriptorType = string
+#      0x09,0x04               # wLANGID(L/H) = English-United Sates
+# ],
+# STRING descriptor 1--Manufacturer ID
+"\x10\x03G\x00o\x00o\x00d\x00F\x00E\x00T\x00",
+# STRING descriptor 2 - Product ID
+"\x1C\x03M\x00A\x00S\x00S\x00 \x00E\x00m\x00u\x00l\x00a\x00t\x00o\x00r\x00",
+# STRING descriptor 3 - Serial Number ID
+"\x14\x03S\x00/\x00N\x00 \x003\x004\x002\x000\x00E\x00"
+];
+
+    def send_descriptor(self,SUD):
+        """Send the USB descriptors based upon the setup data."""
+        desclen=0;
+        reqlen=ord(SUD[wLengthL])+256*ord(SUD[wLengthH]); #16-bit length
+        desctype=ord(SUD[wValueH]);
+        
+        if desctype==GD_DEVICE:
+            desclen=self.DD[0];
+            ddata=self.DD;
+        elif desctype==GD_CONFIGURATION:
+            desclen=self.CD[2];
+            ddata=self.CD;
+        elif desctype==GD_STRING:
+            desclen=self.strDesc[ord(SUD[wValueL])][0];
+            ddata=self.strDesc[ord(SUD[wValueL])];
+        
+        #TODO Configuration, String, Hid, and Report
+        
+        if desclen>0:
+            sendlen=min(reqlen,desclen);
+            self.writebytes(rEP0FIFO,ddata);
+            self.wregAS(rEP0BC,sendlen);
+        else:
+            print "Stalling in send_descriptor() for lack of handler for %02x." % desctype;
+            self.STALL_EP0(SUD);
+    def set_configuration(self,SUD):
+        """Set the configuration."""
+        bmSUSPIE=0x10;
+        configval=ord(SUD[wValueL]);
+        if(configval>0):
+            self.SETBIT(rUSBIEN,bmSUSPIE);
+        self.rregAS(rFNADDR);
+    def get_status(self,SUD):
+        """Get the USB Setup Status."""
+        testbyte=ord(SUD[bmRequestType])
+        
+        #Toward Device
+        if testbyte==0x80:
+            self.wreg(rEP0FIFO,0x03); #Enable RWU and self-powered
+            self.wreg(rEP0FIFO,0x00); #Second byte is always zero.
+            self.wregAS(rEP0BC,2);    #Load byte count, arm transfer, and ack CTL.
+        #Toward Interface
+        elif testbyte==0x81:
+            self.wreg(rEP0FIFO,0x00);
+            self.wreg(rEP0FIFO,0x00); #Second byte is always zero.
+            self.wregAS(rEP0BC,2);
+        #Toward Endpoint
+        elif testbyte==0x82:
+            if(ord(SUD[wIndexL])==0x83):
+                print "This code almost certainly doesn't work.";
+                self.wreg(rEP0FIFO,0x01); #Stall EP3
+                self.wreg(rEP0FIFO,0x00); #Second byte is always zero.
+                self.wregAS(rEP0BC,2);
+            else:
+                self.STALL_EP0(SUD);
+        else:
+            self.STALL_EP0(SUD);
+    def service_irqs(self):
+        """Handle USB interrupt events."""
+        
+        epirq=self.rreg(rEPIRQ);
+        usbirq=self.rreg(rUSBIRQ);
+        
+        #Are we being asked for setup data?
+        if(epirq&bmSUDAVIRQ): #Setup Data Requested
+            self.wreg(rEPIRQ,bmSUDAVIRQ); #Clear the bit
+            self.do_SETUP();
+        elif(epirq&bmIN3BAVIRQ): #EN3-IN packet
+            self.do_IN3();
+            #self.wreg(rEPIRQ,bmIN3BAVIRQ); #Clear the bit
+        elif(epirq&bmOUT1DAVIRQ): #OUT1-OUT packet
+            self.do_OUT1();
+            self.wregAS(rEPIRQ,bmOUT1DAVIRQ); #Clear the bit *AFTER* servicing.
+        #else:
+        #    self.do_IN3();
+    
+    typestring="GoodFET emulates Mass properly, if you can read this!\n";
+    typepos=0;
+    
+    def do_IN3(self):
+        """Handle IN3 input event."""
+        #Don't bother clearing interrupt flag, that's done by sending the reply.
+        #self.type_IN3();
+        print "Got an input event, no idea what to do about it.";
+        self.wreg(rEP3INFIFO,0x01);      #Modem Status
+        self.wreg(rEP3INFIFO,0x00);      #Line Status
+        self.wreg(rEP3INFIFO,0x00);
+        self.wregAS(rEP3INBC,3);
+    def do_OUT1(self):
+        """Handle an OUT1 output event."""
+        print "Got an output event, printing the result.";
+        l=self.rreg(rEP1OUTBC);
+        frame=self.readbytesAS(rEP1OUTFIFO,l);
+        print "Mass OUT: %s" % frame[1:len(frame)];
+        #self.type_IN3();
+
+#Initialize FET and set baud rate
+client=GoodFETMAXUSBMass();
+client.serInit()
+
+
+client.MAXUSBsetup();
+client.massinit();
+