| package com.projectara.araepm; |
| |
| import android.hardware.I2cManager; |
| import android.hardware.I2cTransaction; |
| import android.util.Log; |
| import java.io.IOException; |
| |
| public class DME { |
| private static final int slaveAddress = 0x44; |
| private static final String TAG = "DME"; |
| private static String i2cBus; |
| private I2cManager i2c; |
| |
| public static enum AttributeId { |
| T_PEERDEVICEID (0x4021), |
| T_PEERCPORTID (0x4022), |
| T_CONNECTIONSTATE (0x4020), |
| T_TRAFFICCLASS (0x4023), |
| T_PROTOCOLID (0x4024), |
| T_CPORTFLAGS (0x4025), |
| T_TXTOKENVALUE (0x4026), |
| T_RXTOKENVALUE (0x4027), |
| T_LOCALBUFFERSPACE(0x4028), |
| T_PEERBUFFERSPACE (0x4029), |
| T_CREDITSTOSEND (0x402A), |
| T_CPORTMODE (0x402B), |
| DME_LINKSTARTUP (0xD020), |
| DME_FC0PROTECTIONTIMEOUTVAL (0xD041), |
| DME_MAILBOX (0x6100); |
| |
| private int id; |
| private AttributeId(int id) { |
| this.id = id; |
| } |
| } |
| |
| public static enum FunctionId { |
| C0_SETREQ (0x00), |
| C0_SETCNF (0x01), |
| C0_PEERSETREQ (0x02), |
| C0_PEERSETCNF (0x03), |
| C0_GETREQ (0x04), |
| C0_GETCNF (0x05), |
| C0_PEERGETREQ (0x06), |
| C0_PEERGETCNF (0x07), |
| C0_LUTSETREQ (0x08), |
| C0_LUTSETCNF (0x09), |
| C0_LUTGETREQ (0x0a), |
| C0_LUTGETCNF (0x0b), |
| C0_SWITCHATTRSETREQ (0x0c), |
| C0_SWITCHATTRSETCNF (0x0d), |
| C0_SWITCHATTRGETREQ (0x0e), |
| C0_SWITCHATTERGETCNF(0x0f); |
| |
| private int id; |
| private FunctionId(int id) { |
| this.id = id; |
| } |
| } |
| |
| private class SetRequest { |
| int portId; |
| FunctionId functionId; |
| AttributeId attrId; |
| int selectorIndex; |
| int attrVal; |
| |
| public byte[] getBytes() { |
| byte[] rawBytes = new byte[10]; |
| rawBytes[0] = (byte)(portId & 0xFF); |
| |
| rawBytes[1] = (byte)(functionId.id & 0xFF); |
| |
| rawBytes[2] = (byte)((attrId.id >> 8) & 0xFF); // msb |
| rawBytes[3] = (byte)(attrId.id & 0xFF); // lsb |
| |
| rawBytes[4] = (byte)((selectorIndex >> 8) & 0xFF); |
| rawBytes[5] = (byte)((selectorIndex) & 0xFF); |
| |
| rawBytes[6] = (byte)((attrVal >> 24) & 0xFF); |
| rawBytes[7] = (byte)((attrVal >> 16) & 0xFF); |
| rawBytes[8] = (byte)((attrVal >> 8) & 0xFF); |
| rawBytes[9] = (byte)((attrVal) & 0xFF); |
| return rawBytes; |
| } |
| } |
| |
| private class SetCnf { |
| public static final int MSG_SIZE = 4; |
| int portId; |
| FunctionId functionId; |
| int resultCode; |
| |
| public SetCnf(byte[] setCnfBytes) { |
| portId = setCnfBytes[0] & 0xFF; |
| functionId = FunctionId.values()[setCnfBytes[1] & 0xFF]; |
| resultCode = (((int)setCnfBytes[2] & 0xFF) << 8) | |
| (((int)setCnfBytes[3] & 0xFF)); |
| } |
| } |
| |
| |
| private class GetRequest { |
| int portId; |
| FunctionId functionId; |
| AttributeId attrId; |
| int selectorIndex; |
| |
| public byte[] getBytes() { |
| byte[] rawBytes = new byte[6]; |
| rawBytes[0] = (byte)(portId & 0xFF); |
| |
| rawBytes[1] = (byte)(functionId.id & 0xFF); |
| |
| rawBytes[2] = (byte)((attrId.id >> 8) & 0xFF); |
| rawBytes[3] = (byte)(attrId.id & 0xFF); |
| |
| rawBytes[4] = (byte)((selectorIndex >> 8) & 0xFF); |
| rawBytes[5] = (byte)((selectorIndex) & 0xFF); |
| return rawBytes; |
| } |
| } |
| |
| private class GetCnf { |
| public static final int MSG_SIZE = 8; |
| int portId; |
| FunctionId functionId; |
| int resultCode; |
| int attrVal; |
| |
| public GetCnf(byte[] getCnfBytes) { |
| portId = getCnfBytes[0] & 0xFF; |
| functionId = FunctionId.values()[getCnfBytes[1] & 0xFF]; |
| resultCode = (((int)getCnfBytes[2] & 0xFF) << 8) | |
| (((int)getCnfBytes[3] & 0xFF)); |
| |
| attrVal = (((int)getCnfBytes[4] & 0xFF) << 24) | |
| (((int)getCnfBytes[5] & 0xFF) << 16) | |
| (((int)getCnfBytes[6] & 0xFF) << 8) | |
| (((int)getCnfBytes[7] & 0xFF)); |
| } |
| } |
| |
| public DME(I2cManager i2c) { |
| this.i2c = i2c; |
| this.i2cBus = i2c.getI2cBuses()[0]; |
| } |
| |
| private void logByteArray(String prefix, byte[] arr) { |
| StringBuilder builder = new StringBuilder(prefix); |
| for (byte b: arr) { |
| builder.append(String.format(" %02x", b)); |
| } |
| Log.i(TAG, builder.toString()); |
| } |
| |
| // api_write_switch_config |
| public void writeDMEConfig(int port, boolean peer, AttributeId attrId, |
| int selectorIndex, int attrVal, |
| int expectedResultCode) throws IOException { |
| I2cTransaction txn = null; |
| SetRequest setReq = new SetRequest(); |
| |
| setReq.portId = port; |
| setReq.functionId = peer ? FunctionId.C0_PEERSETREQ : FunctionId.C0_SETREQ; |
| setReq.attrId = attrId; |
| setReq.selectorIndex = selectorIndex; |
| setReq.attrVal = attrVal; |
| |
| Log.d(TAG, "writeDMEConfig: setReq: portID: " + setReq.portId); |
| Log.d(TAG, "writeDMEConfig: setReq: functionId: " + setReq.functionId); |
| Log.d(TAG, "writeDMEConfig: setReq: attrId: " + setReq.attrId); |
| Log.d(TAG, "writeDMEConfig: setReq: selectorIndex: " + setReq.selectorIndex); |
| Log.d(TAG, "writeDMEConfig: setReq: attrVal: " + setReq.attrVal); |
| |
| byte[] raw = setReq.getBytes(); |
| logByteArray("writeDMEConfig: setReq, raw: ", raw); |
| txn = I2cTransaction.newWrite(raw); |
| I2cTransaction[] results; |
| results = i2c.performTransactions(i2cBus, slaveAddress, txn); |
| |
| txn = I2cTransaction.newRead(SetCnf.MSG_SIZE); |
| results = i2c.performTransactions(i2cBus, slaveAddress, txn); |
| logByteArray("writeDMEConfig: setCnf, raw: ", results[0].data); |
| SetCnf setCnf = new SetCnf(results[0].data); |
| |
| FunctionId expectedFunctionId = |
| (peer ? FunctionId.C0_PEERSETCNF : FunctionId.C0_SETCNF); |
| if (setCnf.resultCode != expectedResultCode) { |
| String err = "Unexpected resultCode: " + setCnf.resultCode + |
| " (expected " + expectedResultCode + ")"; |
| Log.e(TAG, err); |
| throw new IOException(err); |
| } else if (setCnf.functionId != expectedFunctionId) { |
| throw new IOException("Unexpected setCnf functionId: " + |
| setCnf.functionId); |
| } |
| |
| Log.d(TAG, "writeDMEConfig: setCnf portId: " + setCnf.portId); |
| Log.d(TAG, "writeDMEConfig: setCnf functionId: " + setCnf.functionId); |
| Log.d(TAG, "writeDMEConfig: setCnf resultCode: " + setCnf.resultCode); |
| return; |
| } |
| |
| public int readDMEConfig(int port, |
| boolean peer, |
| AttributeId attrId, |
| int selectorIndex, |
| int expectedResultCode) throws IOException { |
| I2cTransaction txn = null; |
| GetRequest getReq = new GetRequest(); |
| |
| getReq.portId = port; |
| getReq.functionId = peer ? FunctionId.C0_PEERGETREQ : FunctionId.C0_GETREQ; |
| getReq.attrId = attrId; |
| getReq.selectorIndex = selectorIndex; |
| |
| Log.d(TAG, "readDMEConfig: getReq: portID: " + getReq.portId); |
| Log.d(TAG, "readDMEConfig: getReq: functionId: " + getReq.functionId); |
| Log.d(TAG, "readDMEConfig: getReq: attrId: " + getReq.attrId); |
| Log.d(TAG, "readDMEConfig: getReq: selectorIndex: " + getReq.selectorIndex); |
| |
| byte[] raw = getReq.getBytes(); |
| logByteArray("readDMEConfig: getReq, raw: ", raw); |
| txn = I2cTransaction.newWrite(raw); |
| |
| I2cTransaction[] results; |
| results = i2c.performTransactions(i2cBus, slaveAddress, txn); |
| |
| txn = I2cTransaction.newRead(GetCnf.MSG_SIZE); |
| results = i2c.performTransactions(i2cBus, slaveAddress, txn); |
| logByteArray("readDMEConfig: getCnf, raw: ", results[0].data); |
| GetCnf getCnf = new GetCnf(results[0].data); |
| |
| FunctionId expectedFunctionId = |
| (peer ? FunctionId.C0_PEERGETCNF : FunctionId.C0_GETCNF); |
| if (getCnf.resultCode != expectedResultCode) { |
| String err = "Unexpected resultCode: " + getCnf.resultCode + |
| " (expected " + expectedResultCode + ")"; |
| Log.e(TAG, err); |
| throw new IOException(err); |
| } else if (getCnf.functionId != expectedFunctionId) { |
| throw new IOException("Unexpected getCnf functionId: " + |
| getCnf.functionId); |
| } |
| |
| Log.d(TAG, "readDMEConfig: getCnf portId: " + getCnf.portId); |
| Log.d(TAG, "readDMEConfig: getCnf functionId: " + getCnf.functionId); |
| Log.d(TAG, "readDMEConfig: getCnf resultCode: " + getCnf.resultCode); |
| Log.d(TAG, "readDMEConfig: getCnf attrVal: " + getCnf.attrVal); |
| |
| return getCnf.attrVal; |
| } |
| } |