Skip to content

Commit d16c453

Browse files
committed
Fixed more bugs with DUMP_MFU. When there is a new metadata log, the interface switches to the log tab and scrolls to it.
1 parent 259883b commit d16c453

File tree

7 files changed

+76
-20
lines changed

7 files changed

+76
-20
lines changed

app/build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ android {
2626
applicationId "com.maxieds.chameleonminilivedebugger"
2727
minSdkVersion 21
2828
targetSdkVersion 27
29-
versionCode 46
30-
versionName "0.4.6"
29+
versionCode 47
30+
versionName "0.4.7"
3131
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
3232
multiDexEnabled true
3333
}

app/src/main/java/com/maxieds/chameleonminilivedebugger/ExportTools.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -556,6 +556,12 @@ public static boolean saveBinaryDumpMFU(String filePathPrefix) {
556556
*/
557557
public static boolean cloneBinaryDumpMFU(byte[] dataBytes) {
558558

559+
if(dataBytes.length % 4 != 0) { // realign array:
560+
int dbPadding = (4 - (dataBytes.length % 4)) % 4;
561+
byte[] fullDataBytes = new byte[dataBytes.length + dbPadding];
562+
System.arraycopy(dataBytes, 0, fullDataBytes, 0, dataBytes.length);
563+
dataBytes = fullDataBytes;
564+
}
559565
ChameleonIO.executeChameleonMiniCommand(LiveLoggerActivity.serialPort, "CONFIG=MF_ULTRALIGHT", ChameleonIO.TIMEOUT);
560566
ChameleonIO.deviceStatus.updateAllStatusAndPost(true);
561567
for(int page = 0; page < dataBytes.length; page += 4) {
@@ -566,7 +572,7 @@ public static boolean cloneBinaryDumpMFU(byte[] dataBytes) {
566572
(byte) (page / 4), // P2
567573
};
568574
byte[] apduSendBytesData = new byte[4];
569-
System.arraycopy(dataBytes, 4 * page, apduSendBytesData, 4, 4);
575+
System.arraycopy(dataBytes, page, apduSendBytesData, 0, 4);
570576
int sendBytesHdr = Utils.bytes2Integer32(apduSendBytesHdr);
571577
int sendBytesData = Utils.bytes2Integer32(apduSendBytesData);
572578
String chameleonCmd = String.format("SEND %08x%08x", sendBytesHdr, sendBytesData);

app/src/main/java/com/maxieds/chameleonminilivedebugger/LiveLoggerActivity.java

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ public class LiveLoggerActivity extends AppCompatActivity {
100100
public static List<LogEntryBase> logDataEntries = new ArrayList<LogEntryBase>();
101101
public static int RECORDID = 0;
102102
public static boolean logDataFeedConfigured = false;
103+
public static ScrollView logScrollView;
103104
public static SpinnerAdapter spinnerRButtonAdapter;
104105
public static SpinnerAdapter spinnerRButtonLongAdapter;
105106
public static SpinnerAdapter spinnerLButtonAdapter;
@@ -137,6 +138,26 @@ public static void appendNewLog(LogEntryBase logEntry) {
137138
}
138139
logDataFeed.addView(logEntry.getLayoutContainer());
139140
logDataEntries.add(logEntry);
141+
if(logEntry instanceof LogEntryMetadataRecord) { // switch to the log tab to display the results:
142+
Log.i(TAG, String.format("LogEntryMetaData record height: %d", logEntry.getLayoutContainer().getHeight()));
143+
TabLayout tabLayout = (TabLayout) LiveLoggerActivity.runningActivity.findViewById(R.id.tab_layout);
144+
tabLayout.getTabAt(TAB_LOG).select();
145+
if(logScrollView != null) {
146+
logScrollView.postDelayed(new Runnable() {
147+
@Override
148+
public void run() {
149+
ScrollView logScroller = (ScrollView) LiveLoggerActivity.runningActivity.findViewById(R.id.log_scroll_view);
150+
//int bottomEltHeight = LiveLoggerActivity.logDataFeed.getChildAt(LiveLoggerActivity.logDataFeed.getChildCount() - 1).getHeight();
151+
LinearLayout lastLogElt = (LinearLayout) logDataFeed.getChildAt(logDataFeed.getChildCount() - 1);
152+
lastLogElt.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
153+
int bottomEltHeight = lastLogElt.getMeasuredHeight();
154+
Log.i(TAG, String.format("ScrollView bottom element height = %d + getBottom() = %d", bottomEltHeight, logScroller.getBottom()));
155+
logScroller.scrollTo(0, logScroller.getBottom() + bottomEltHeight);
156+
//logScroller.fullScroll(View.FOCUS_DOWN);
157+
}
158+
}, 250);
159+
}
160+
}
140161
}
141162

142163
/**
@@ -202,8 +223,8 @@ public void uncaughtException(Thread thread, Throwable ex) {
202223
protected void onCreate(Bundle savedInstanceState) {
203224

204225
// fix bug where the tabs are blank when the application is relaunched:
205-
super.onCreate(savedInstanceState); // should fix most of the crashes in the ANR report on Play Store
206226
if(runningActivity == null || !isTaskRoot()) {
227+
super.onCreate(savedInstanceState); // should fix most of the crashes in the ANR report on Play Store
207228
if(!BuildConfig.DEBUG) {
208229
Log.w(TAG, "Loading crashlytics");
209230
Fabric.with(this, new Crashlytics());
@@ -585,7 +606,11 @@ public static String getSettingFromDevice(UsbSerialDevice cmPort, String query,
585606
break;
586607
}
587608
}
588-
return ChameleonIO.DEVICE_RESPONSE[0];
609+
String retValue = ChameleonIO.DEVICE_RESPONSE[0];
610+
if(retValue.equals("201:INVALID COMMAND USAGE")) {
611+
retValue += " (Are you in READER mode?)";
612+
}
613+
return retValue;
589614
}
590615

591616
/**
@@ -981,7 +1006,7 @@ else if(createCmd.equals("SEND") || createCmd.equals("SEND_RAW")) {
9811006
appendNewLog(LogEntryMetadataRecord.createDefaultEventRecord("ERROR", "Input to send to card must be a _single hexadecimal_ byte!"));
9821007
return;
9831008
}
984-
msgParam = "Card Response (if any): " + getSettingFromDevice(serialPort, createCmd + " " + bytesToSend);
1009+
msgParam = "Card Response (if any): \n" + getSettingFromDevice(serialPort, createCmd + " " + bytesToSend);
9851010
}
9861011
else if(createCmd.equals("AUTOCAL")) {
9871012
msgParam = getSettingFromDevice(serialPort, "AUTOCALIBRATE");
@@ -1600,9 +1625,15 @@ else if(action.equals("RANDOM")) {
16001625

16011626
public void actionButtonSendAPDU(View view) {
16021627
String apduCmd = ApduUtils.apduTransceiveCmd.assembleAPDUString();
1603-
String chameleonCmd = "SEND " + apduCmd;
1604-
String respData = getSettingFromDevice(serialPort, chameleonCmd);
1605-
String logMsg = String.format("Sent %s as %s ... \nResponse: %s", ApduUtils.apduTransceiveCmd.apduCmdDesc, apduCmd, respData);
1628+
String logMsg = String.format("Sent %s as %s ... \n", ApduUtils.apduTransceiveCmd.apduCmdDesc, apduCmd);
1629+
for(int b = 0; b < apduCmd.length(); b += 2) {
1630+
String apduByte = apduCmd.substring(b, b + 2);
1631+
String chameleonCmd = "SEND_RAW " + apduByte;
1632+
String respData = getSettingFromDevice(serialPort, chameleonCmd);
1633+
logMsg += String.format(" %s => Response: %s", apduByte, respData);
1634+
if (b + 2 < apduCmd.length())
1635+
logMsg += "\n";
1636+
}
16061637
appendNewLog(LogEntryMetadataRecord.createDefaultEventRecord("APDU", logMsg));
16071638
}
16081639

app/src/main/java/com/maxieds/chameleonminilivedebugger/TabFragment.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,6 @@
2626

2727
import java.util.Locale;
2828

29-
import static android.content.ContentValues.TAG;
30-
3129
/**
3230
* <h1>Tab Fragment</h1>
3331
* Implements a Fragment for individual tab data in the application.
@@ -37,6 +35,8 @@
3735
*/
3836
public class TabFragment extends Fragment {
3937

38+
private static final String TAG = TabFragment.class.getSimpleName();
39+
4040
/**
4141
* Definitions of the in-order tab indices.
4242
*/
@@ -216,6 +216,8 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container,
216216
LinearLayout logDataFeed = LiveLoggerActivity.logDataFeed;
217217
logDataFeed.setOrientation(LinearLayout.VERTICAL);
218218
logScroller.addView(logDataFeed);
219+
logScroller.setFillViewport(true);
220+
LiveLoggerActivity.logScrollView = logScroller;
219221
LiveLoggerActivity.logDataFeed = logDataFeed;
220222
LiveLoggerActivity.logDataFeedConfigured = true;
221223
}

app/src/main/java/com/maxieds/chameleonminilivedebugger/Utils.java

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -261,11 +261,17 @@ public static int parseInt(String numberStr) {
261261
* @return Pretty String Format of the MFU tag
262262
*/
263263
public static String prettyPrintMFU(String mfuBytes) {
264-
String pp = "PG | B0 B1 B2 B3 | LOCK AND/OR SPECIAL REGISTERS";
265-
pp += "================================================";
264+
String pp = " PG | B0 B1 B2 B3 | LOCK AND/OR SPECIAL REGISTERS\n";
265+
pp += "=================================================\n";
266266
for(int page = 0; page < mfuBytes.length(); page += 8) {
267267
int pageNumber = page / 8;
268-
byte[] pageData = Utils.hexString2Bytes(mfuBytes.substring(page, page + 8));
268+
Log.i(TAG, String.format("prettyPrintMFU: page#% 2d, page=% 2d", pageNumber, page));
269+
byte[] pageData = Utils.hexString2Bytes(mfuBytes.substring(page, Math.min(page + 8, mfuBytes.length()) - 1));
270+
if(pageData.length < 4) {
271+
byte[] pageDataResized = new byte[4];
272+
System.arraycopy(pageData, 0, pageDataResized, 0, pageData.length);
273+
pageData = pageDataResized;
274+
}
269275
String specialRegs = "";
270276
int lockBits = 0;
271277
if(pageNumber == 0) {
@@ -300,7 +306,9 @@ else if(pageNumber == 19) {
300306
else {
301307
specialRegs = "ONE WAY CTRS";
302308
}
303-
String pageLine = String.format("% 2d | %02x %02x %02x %02x | [%s]\n", pageNumber, pageData[0], pageData[1], pageData[2], pageData[3]);
309+
String pageLine = String.format(" % 2d | %02x %02x %02x %02x | [%s]", pageNumber, pageData[0], pageData[1], pageData[2], pageData[3], specialRegs);
310+
if(page + 4 < mfuBytes.length())
311+
pageLine += "\n";
304312
pp += pageLine;
305313
}
306314
return pp;

app/src/main/res/layout/log_entry_ui.xml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@
55
style="@style/LogDataUITheme"
66
android:layout_width="match_parent"
77
android:layout_height="wrap_content"
8-
android:orientation="vertical">
8+
android:layout_marginLeft="0.5dp"
9+
android:layout_marginRight="0.5dp"
10+
android:orientation="vertical"
11+
>
912

1013
<LinearLayout
1114
android:layout_width="fill_parent"

app/src/main/res/layout/log_metadata_record.xml

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,18 @@
66
android:orientation="vertical"
77
android:padding="5px">
88

9+
<View
10+
android:layout_width="match_parent"
11+
android:layout_height="2dp"
12+
android:background="?colorPrimaryDark" />
13+
914
<TextView
1015
android:id="@+id/record_title_text"
1116
android:layout_width="fill_parent"
1217
android:layout_height="wrap_content"
13-
android:drawableLeft="@drawable/phonebubble24"
14-
android:drawablePadding="5dp"
1518
android:background="?colorAccentHighlight"
19+
android:drawableLeft="@drawable/phonebubble24"
20+
android:layout_marginLeft="3.5dp"
1621
android:textAllCaps="true"
1722
android:textStyle="bold" />
1823

@@ -26,8 +31,9 @@
2631
android:layout_width="fill_parent"
2732
android:layout_height="wrap_content"
2833
android:background="?colorAccentLog"
29-
android:textSize="12sp"
30-
android:textStyle="normal" />
34+
android:textSize="10sp"
35+
android:textStyle="normal"
36+
android:typeface="monospace" />
3137

3238
<View
3339
android:layout_width="match_parent"

0 commit comments

Comments
 (0)