+ self.handleCBW(frame);
+ lastCBW="";
+ def handleCBW(self,cbw):
+ """Handles an incoming Command Block Wrapper. See USB Mass
+ Storage Class for details."""
+
+ if len(cbw)!=31:
+ print "Invalid CBW length of %i bytes. Aborting." % len(cbw);
+ sig=cbw[0:4];
+ if sig!="USBC":
+ print "Invalid CBW signature: %s. Should be USBC; aborting." % sig;
+ return;
+ self.lastCBW=cbw;
+
+ dtlen=ord(cbw[8])+(ord(cbw[9])<<8)+(ord(cbw[10])<<16)+(ord(cbw[11])<<24);
+ flags=ord(cbw[12]);
+ dtdir=flags&0x80; # 0x80 for dev->host, 0x00 for host->dev
+ lun=ord(cbw[13])&0x0F; # Should be zero, as we only reported one LUN.
+ cblen=ord(cbw[14])&0x1F;
+ cb=cbw[15:31];
+ self.handleCB(cb,cblen,dtlen,dtdir);
+
+ def handleCB(self,cb,cblen,dtlen,dtdir):
+ """Handles a command block, then replies with a CSW."""
+ print "Got command block 0x%02x, length %i bytes" % (
+ ord(cb[0]), dtlen);
+ verb=ord(cb[0]);
+ status=00; #good, set to 1 for bad.
+ if verb==0x00: # Test Unit Ready
+ response=[0,0,0,0,0,0];
+ self.writebytes(rEP3INFIFO,
+ response);
+ self.wregAS(rEP3INBC,len(response));
+ while not(self.rreg(rEPIRQ)&bmIN3BAVIRQ):
+ #Wait for the packet to complete before sending the next.
+ print "Waiting to complete inquiry."
+ pass;
+ elif verb==0x03: # Request Sense
+ print "Responding to Request Sense. Needed for Macs.";
+ response=[0x70, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x0A,
+ 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00,
+ 0x00, 0x00,
+ 0,0,0,0,0];
+ status=1;
+ self.writebytes(rEP3INFIFO,
+ response);
+ self.wregAS(rEP3INBC,len(response));
+ while not(self.rreg(rEPIRQ)&bmIN3BAVIRQ):
+ #Wait for the packet to complete before sending the next.
+ print "Waiting to complete inquiry."
+ pass;
+ elif verb==0x12: #Inquiry
+ print "Responding to CB inquiry.";
+ response=[
+ 0x00,
+ 0x80, # make 0x80 for removable media
+ 0x05, # SPC2
+ 0x02, # SPC2
+ 0x1f, #Additional length.
+ 0x00, 0x00, 0x00,
+ #Manufacturer
+ ord('G'),ord('o'),ord('o'),ord('d'),ord('F'),ord('E'),ord('T'),0,
+ #Device name
+ ord('G'),ord('o'),ord('o'),ord('d'),ord('F'),ord('E'),ord('T'),0,
+ 0,0,0,0,0,0,0,0,
+ ord('0'),ord('.'),ord('0'),ord('1')]
+ self.writebytes(rEP3INFIFO,
+ response);
+ self.wregAS(rEP3INBC,len(response));
+ while not(self.rreg(rEPIRQ)&bmIN3BAVIRQ):
+ #Wait for the packet to complete before sending the next.
+ print "Waiting to complete inquiry."
+ pass;
+ else:
+ print "ERROR: Unknown command block verb %02x." % verb;
+ status=1; #Command Failed
+ if dtlen>0:
+ print "Exiting, as %i bytes are expected to be transfered toward %i." % (
+ dtlen,dtdir);
+
+ sys.exit();
+ cbw=self.lastCBW;
+
+ #Now we need to send the CSW.
+ csw=[
+ #Standard prefix.
+ ord('U'),ord('S'),ord('B'),ord('S'),
+ #CBW key; must be the same as the one we're replying to.
+ ord(cbw[4]),ord(cbw[5]),ord(cbw[6]),ord(cbw[7]),
+ #CSW Data Residue, probably oughtn't be zeroed.
+ 0,0,0,
+ #Status byte: 00 for good, 01 for bad.
+ status];
+ self.writebytes(rEP3INFIFO,
+ csw);
+ self.wregAS(rEP3INBC,len(csw));
+
+
+ self.wreg(rEPIRQ,bmIN3BAVIRQ); #Clear the IRQ bit.
+ return;