Skip to content

Commit

Permalink
Merged in mode_sense (pull request #6)
Browse files Browse the repository at this point in the history
add mode sense scsi command.
  • Loading branch information
janseeger committed Sep 18, 2014
2 parents 821df0b + 39aa203 commit df7f298
Show file tree
Hide file tree
Showing 9 changed files with 144 additions and 30 deletions.
23 changes: 21 additions & 2 deletions lib/src/main/java/net/alphadev/usbstorage/bbb/BulkBlockDevice.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package net.alphadev.usbstorage.bbb;

import net.alphadev.usbstorage.api.BulkDevice;
import net.alphadev.usbstorage.scsi.answer.ModeSenseResponse;
import net.alphadev.usbstorage.scsi.answer.ReadCapacityResponse;
import net.alphadev.usbstorage.scsi.answer.ReadFormatCapacitiesEntry;
import net.alphadev.usbstorage.scsi.answer.ReadFormatCapacitiesHeader;
import net.alphadev.usbstorage.scsi.answer.StandardInquiryAnswer;
import net.alphadev.usbstorage.scsi.command.Inquiry;
import net.alphadev.usbstorage.scsi.command.ModeSense;
import net.alphadev.usbstorage.scsi.command.ReadCapacity;
import net.alphadev.usbstorage.scsi.command.ReadFormatCapacities;
import net.alphadev.usbstorage.scsi.command.ScsiCommand;
Expand All @@ -31,17 +33,32 @@ public BulkBlockDevice(BulkDevice usbBlockDevice) throws IOException {
mAbstractBulkDevice = usbBlockDevice;

setupInquiryPhase();
setupCapacityPhase();
testUnitReady();
acquireDriveCapacity();
senseMode();
testUnitReady();
}

private void senseMode() throws IOException {
ModeSense cmd = new ModeSense();
cmd.setDisableBlockDescriptor(false);
cmd.setPageControl(ModeSense.PageControlValues.Current);
cmd.setPageCode((byte) 0x3f);
cmd.setSubPageCode((byte) 0);
send_mass_storage_command(cmd);

byte[] data = mAbstractBulkDevice.retrieve_data_packet(cmd.getExpectedAnswerLength());
new ModeSenseResponse(data);
}

private void testUnitReady() throws IOException {
send_mass_storage_command(new TestUnitReady());

checkDeviceStatus();
}

private void setupCapacityPhase() throws IOException {
@SuppressWarnings("unused")
private void acquireCardCapacities() throws IOException {
try {
send_mass_storage_command(new ReadFormatCapacities());
byte[] answer = mAbstractBulkDevice.retrieve_data_packet(ReadFormatCapacitiesHeader.LENGTH);
Expand All @@ -64,7 +81,9 @@ private void setupCapacityPhase() throws IOException {
} catch (IllegalArgumentException ex) {
// do nothing as the read format capacities command is optional.
}
}

private void acquireDriveCapacity() throws IOException {
try {
send_mass_storage_command(new ReadCapacity());
byte[] answer = mAbstractBulkDevice.retrieve_data_packet(ReadCapacityResponse.LENGTH);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import static net.alphadev.usbstorage.util.BitStitching.convertToInt;

/**
*
* @author Jan Seeger <[email protected]>
*/
public class CommandStatusWrapper {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package net.alphadev.usbstorage.scsi.answer;

import java.util.BitSet;

/**
* @author Jan Seeger <[email protected]>
*/
public class ModeSenseResponse {
public static final int LENGTH = 8;

private byte mModeDataLength;
private MediumType mMediumType;
private byte mDeviceSpecificParameter;
private byte mBlockDescriptorLength;
private boolean mWriteProtection;
private boolean mDPOFUA;

public ModeSenseResponse(byte[] answer) {
mModeDataLength = answer[0];
mMediumType = determineMediumType(answer[1]);

BitSet bs = new BitSet(answer[2]);
mWriteProtection = bs.get(7);
mDPOFUA = bs.get(4);

mBlockDescriptorLength = answer[3];
}

private MediumType determineMediumType(byte typeField) {
switch (typeField) {
case 00:
return MediumType.SCB_DEVICE;
}
return null;
}

public static enum MediumType {
SCB_DEVICE
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package net.alphadev.usbstorage.scsi.command;

import net.alphadev.usbstorage.bbb.CommandBlockWrapper;
import net.alphadev.usbstorage.scsi.answer.StandardInquiryAnswer;

/**
Expand Down Expand Up @@ -36,11 +35,6 @@ public int getExpectedAnswerLength() {
return StandardInquiryAnswer.LENGTH;
}

@Override
public CommandBlockWrapper.Direction getDirection() {
return CommandBlockWrapper.Direction.DEVICE_TO_HOST;
}

public boolean isCmdDt() {
return mCmdDt;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package net.alphadev.usbstorage.scsi.command;

/**
* @author Jan Seeger <[email protected]>
*/
@SuppressWarnings("unused")
public class ModeSense extends ScsiCommand {
public static final byte MODE_SENSE = 0x1a;
/**
* DBD (disable block descriptors) bit
* Ifset to zero specifies that the device server may return zero or more block descriptors in the returned MODE SENSE data.
* A DBD bit set to one specifies that the device server shall not return any block descriptors in the returned MODE SENSE data,
*/
private boolean mDisableBlockDescriptor;
private byte mPageCode;
private byte mSubPageCode;
private PageControlValues mPageControl;

public ModeSense() {
super(MODE_SENSE);
}

@Override
public byte[] asBytes() {
byte[] retval = new byte[6];
retval[0] = MODE_SENSE; // opcode
retval[1] = (byte) (mDisableBlockDescriptor ? 1 : 0); // DBD bit
retval[2] = getPageField();
retval[3] = mSubPageCode;
retval[4] = (byte) 192;
// 5 == control bit
return retval;
}

private byte getPageField() {
byte retval = 0;

switch (mPageControl) {
case Changeable:
retval = 64;
break;
case Default:
retval = (byte) 128;
break;
case Saved:
retval = (byte) 192;
break;
}

return (byte) (retval + mPageCode);
}

@Override
public int getExpectedAnswerLength() {
return 0;
}

public void setDisableBlockDescriptor(boolean value) {
this.mDisableBlockDescriptor = value;
}

public void setPageCode(byte pageCode) {
this.mPageCode = pageCode;
}

public void setSubPageCode(byte subPageCode) {
this.mSubPageCode = subPageCode;
}

public void setPageControl(PageControlValues pageControl) {
this.mPageControl = pageControl;
}

public static enum PageControlValues {
Current,
Changeable,
Default,
Saved
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package net.alphadev.usbstorage.scsi.command;

import net.alphadev.usbstorage.bbb.CommandBlockWrapper;
import net.alphadev.usbstorage.scsi.answer.ReadCapacityResponse;

import static net.alphadev.usbstorage.util.BitStitching.setBytesFromInt;
Expand All @@ -19,11 +18,6 @@ public ReadCapacity() {
super(READ_CAPACITY);
}

@Override
public CommandBlockWrapper.Direction getDirection() {
return CommandBlockWrapper.Direction.DEVICE_TO_HOST;
}

@Override
public byte[] asBytes() {
byte[] retval = new byte[10];
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package net.alphadev.usbstorage.scsi.command;

import net.alphadev.usbstorage.bbb.CommandBlockWrapper;

import static net.alphadev.usbstorage.util.BitStitching.setBytesFromShort;

/**
Expand All @@ -14,11 +12,6 @@ public ReadFormatCapacities() {
super(READ_FORMAT_CAPACITIES);
}

@Override
public CommandBlockWrapper.Direction getDirection() {
return CommandBlockWrapper.Direction.DEVICE_TO_HOST;
}

@Override
public byte[] asBytes() {
byte[] retval = new byte[10];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,7 @@ public ScsiCommand(byte opCode) {
mOpCode = opCode;
}

public abstract CommandBlockWrapper.Direction getDirection();
public CommandBlockWrapper.Direction getDirection() {
return CommandBlockWrapper.Direction.DEVICE_TO_HOST;
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package net.alphadev.usbstorage.scsi.command;

import net.alphadev.usbstorage.bbb.CommandBlockWrapper;

/**
* @author Jan Seeger <[email protected]>
*/
Expand All @@ -12,11 +10,6 @@ public TestUnitReady() {
super(TEST_UNIT_READY);
}

@Override
public CommandBlockWrapper.Direction getDirection() {
return CommandBlockWrapper.Direction.DEVICE_TO_HOST;
}

@Override
public byte[] asBytes() {
// all zero since even opcode == 0x0
Expand Down

0 comments on commit df7f298

Please sign in to comment.