Skip to content

Commit bd6981c

Browse files
committed
Added Max NAK count to file downloads with XModem.
1 parent d82e235 commit bd6981c

File tree

6 files changed

+132
-91
lines changed

6 files changed

+132
-91
lines changed

app/build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ android {
66
applicationId "com.maxieds.chameleonminilivedebugger"
77
minSdkVersion 21
88
targetSdkVersion 25
9-
versionCode 13
10-
versionName "0.1.5"
9+
versionCode 14
10+
versionName "0.1.6"
1111
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
1212
}
1313
buildTypes {

app/release/app-release.apk

989 Bytes
Binary file not shown.

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

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import static com.maxieds.chameleonminilivedebugger.ChameleonIO.SerialRespCode.FALSE;
2020
import static com.maxieds.chameleonminilivedebugger.ChameleonIO.SerialRespCode.OK;
21+
import static com.maxieds.chameleonminilivedebugger.ChameleonIO.SerialRespCode.RESP_CODE_TEXT_MAP;
2122
import static java.lang.Math.round;
2223

2324
/**
@@ -63,6 +64,15 @@ public enum SerialRespCode {
6364
}
6465
}
6566

67+
public static final Map<String, SerialRespCode> RESP_CODE_TEXT_MAP = new HashMap<>();
68+
static {
69+
for (SerialRespCode respCode : values()) {
70+
String rcode = String.valueOf(respCode.toInteger());
71+
String rcodeText = respCode.name().replace("_", " ");
72+
RESP_CODE_TEXT_MAP.put(rcode + ":" + rcodeText, respCode);
73+
}
74+
}
75+
6676
public int toInteger() { return responseCode; }
6777

6878
public static SerialRespCode lookupByResponseCode(int rcode) {
@@ -71,6 +81,13 @@ public static SerialRespCode lookupByResponseCode(int rcode) {
7181

7282
}
7383

84+
public static boolean isCommandResponse(byte[] liveLogData) {
85+
String respText = new String(liveLogData).split("[\n\r]+")[0];
86+
if(SerialRespCode.RESP_CODE_TEXT_MAP.get(respText) != null)
87+
return true;
88+
return false;
89+
}
90+
7491
public static class DeviceStatusSettings {
7592

7693
public String CONFIG;

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

Lines changed: 98 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import android.os.Handler;
55
import android.os.Looper;
66
import android.util.Log;
7+
import android.view.View;
78
import android.widget.Button;
89

910
import com.felhr.usbserial.SerialInputStream;
@@ -19,6 +20,7 @@
1920
import java.io.FileInputStream;
2021
import java.io.FileOutputStream;
2122
import java.io.IOException;
23+
import java.nio.charset.StandardCharsets;
2224
import java.util.HashMap;
2325
import java.util.Map;
2426
import java.util.concurrent.TimeUnit;
@@ -39,6 +41,7 @@ public class ExportTools {
3941

4042
public static final long LOCK_TIMEOUT = 2000;
4143
public static boolean EOT = false;
44+
public static int MAX_NAK_COUNT = 6;
4245

4346
public static final byte BYTE_NAK = (byte) 0x15;
4447
public static final byte BYTE_SOH = (byte) 0x01;
@@ -74,12 +77,15 @@ public static enum State_t {
7477
public static byte[] frameBuffer = new byte[XMODEM_BLOCK_SIZE];
7578
public static byte CurrentFrameNumber;
7679
public static byte Checksum;
80+
public static int currentNAKCount;
81+
public static boolean transmissionErrorOccurred;
7782

7883
public static Runnable eotSleepRunnable = new Runnable() {
7984
public void run() {
8085
if (!ExportTools.EOT) {
8186
eotSleepHandler.postDelayed(this, 50);
82-
} else {
87+
}
88+
else {
8389
try {
8490
streamDest.close();
8591
} catch (Exception ioe) {
@@ -90,16 +96,22 @@ public void run() {
9096
ChameleonIO.executeChameleonMiniCommand(LiveLoggerActivity.serialPort, "LOGMODE=" + currentLogMode, ChameleonIO.TIMEOUT);
9197
LiveLoggerActivity.serialPortLock.release();
9298
}
93-
DownloadManager downloadManager = (DownloadManager) LiveLoggerActivity.defaultContext.getSystemService(DOWNLOAD_SERVICE);
94-
downloadManager.addCompletedDownload(outfile.getName(), outfile.getName(), true, "application/octet-stream",
95-
outfile.getAbsolutePath(), outfile.length(), true);
96-
String statusMsg = "Write internal log data to file " + outfile.getName() + "(+" + fileSize + " / " + outfile.length() + " bytes).\n";
97-
statusMsg += "If you are not seeing the expected output, try running the LOGSTORE command from the tools menu first.";
98-
LiveLoggerActivity.appendNewLog(new LogEntryMetadataRecord(LiveLoggerActivity.defaultInflater, "NEW EVENT", statusMsg));
99-
if (throwToLive) {
100-
throwDeviceLogDataToLive(outfile);
99+
if(!ExportTools.transmissionErrorOccurred) {
100+
DownloadManager downloadManager = (DownloadManager) LiveLoggerActivity.defaultContext.getSystemService(DOWNLOAD_SERVICE);
101+
downloadManager.addCompletedDownload(outfile.getName(), outfile.getName(), true, "application/octet-stream",
102+
outfile.getAbsolutePath(), outfile.length(), true);
103+
String statusMsg = "Write internal log data to file " + outfile.getName() + "(+" + fileSize + " / " + outfile.length() + " bytes).\n";
104+
statusMsg += "If you are not seeing the expected output, try running the LOGSTORE command from the tools menu first.";
105+
LiveLoggerActivity.appendNewLog(new LogEntryMetadataRecord(LiveLoggerActivity.defaultInflater, "NEW EVENT", statusMsg));
106+
if (throwToLive) {
107+
throwDeviceLogDataToLive(outfile);
108+
}
109+
}
110+
else {
111+
outfile.delete();
112+
LiveLoggerActivity.runningActivity.setStatusIcon(R.id.statusIconUlDl, R.drawable.statusxferfailed16);
113+
LiveLoggerActivity.appendNewLog(LogEntryMetadataRecord.createDefaultEventRecord("ERROR", "Maximum number of NAK errors exceeded. Download of data aborted."));
101114
}
102-
LiveLoggerActivity.runningActivity.clearStatusIcon(R.id.statusIconUlDl);
103115
}
104116
}
105117
};
@@ -122,13 +134,16 @@ public static void performXModemSerialDownload(byte[] liveLogData) {
122134
System.arraycopy(liveLogData, 3, ExportTools.frameBuffer, 0, ExportTools.XMODEM_BLOCK_SIZE);
123135
byte checksumByte = liveLogData[liveLogData.length - 1];
124136
ExportTools.Checksum = ExportTools.CalcChecksum(ExportTools.frameBuffer, ExportTools.XMODEM_BLOCK_SIZE);
125-
if (ExportTools.Checksum != checksumByte) {
126-
Log.w(TAG, "Sent another NAK (invalid checksum)");
127-
try {
128-
LiveLoggerActivity.serialPort.write(new byte[]{ExportTools.BYTE_NAK});
129-
} catch (Exception e) {
130-
e.printStackTrace();
131-
}
137+
if (ExportTools.Checksum != checksumByte && currentNAKCount < MAX_NAK_COUNT) {
138+
Log.w(TAG, "Sent another NAK (invalid checksum) : # = " + currentNAKCount);
139+
LiveLoggerActivity.serialPort.write(new byte[]{ExportTools.BYTE_NAK});
140+
currentNAKCount++;
141+
return;
142+
}
143+
else if(ExportTools.Checksum != checksumByte) {
144+
ExportTools.EOT = true;
145+
ExportTools.transmissionErrorOccurred = true;
146+
LiveLoggerActivity.serialPort.write(new byte[] {ExportTools.BYTE_CAN});
132147
return;
133148
}
134149
try {
@@ -143,12 +158,15 @@ public static void performXModemSerialDownload(byte[] liveLogData) {
143158
}
144159
}
145160
else {
146-
Log.w(TAG, "Sent another NAK");
147-
try {
148-
LiveLoggerActivity.serialPort.write(new byte[]{ExportTools.BYTE_NAK});
149-
} catch (Exception e) {
150-
e.printStackTrace();
161+
if(currentNAKCount >= MAX_NAK_COUNT) {
162+
ExportTools.EOT = true;
163+
ExportTools.transmissionErrorOccurred = true;
164+
LiveLoggerActivity.serialPort.write(new byte[] {ExportTools.BYTE_CAN});
165+
return;
151166
}
167+
Log.w(TAG, "Sent another NAK (invalid checksum) : # = " + currentNAKCount);
168+
LiveLoggerActivity.serialPort.write(new byte[]{ExportTools.BYTE_NAK});
169+
currentNAKCount++;
152170
}
153171
}
154172
else {
@@ -198,6 +216,8 @@ public static boolean downloadByXModem(String issueCmd, String outfilePrefix, bo
198216
LiveLoggerActivity.getSettingFromDevice(LiveLoggerActivity.serialPort, issueCmd);
199217
fileSize = 0;
200218
CurrentFrameNumber = FIRST_FRAME_NUMBER;
219+
currentNAKCount = 0;
220+
transmissionErrorOccurred = false;
201221
LiveLoggerActivity.serialPort.write(new byte[]{BYTE_NAK});
202222
//while (!EOT) {
203223
// Thread.sleep(500);
@@ -226,9 +246,64 @@ public static void throwDeviceLogDataToLive(File logDataFile) {
226246
}
227247
}
228248

249+
public static boolean writeFormattedLogFile(File fd) throws Exception {
250+
Log.i(TAG, String.valueOf("00".getBytes(StandardCharsets.US_ASCII)));
229251

252+
FileOutputStream fout = new FileOutputStream(fd);
253+
for (int vi = 0; vi < LiveLoggerActivity.logDataFeed.getChildCount(); vi++) {
254+
View logEntryView = LiveLoggerActivity.logDataFeed.getChildAt(vi);
255+
if (LiveLoggerActivity.logDataEntries.get(vi) instanceof LogEntryUI) {
256+
String dataLine = ((LogEntryUI) LiveLoggerActivity.logDataEntries.get(vi)).toString() + "\n";
257+
fout.write(dataLine.getBytes(StandardCharsets.US_ASCII));
258+
}
259+
else {
260+
String lineStr = "\n## " + ((LogEntryMetadataRecord) LiveLoggerActivity.logDataEntries.get(vi)).toString() + "\n";
261+
fout.write(lineStr.getBytes(StandardCharsets.US_ASCII));
262+
}
263+
}
264+
fout.close();
265+
return true;
266+
}
230267

268+
public static boolean writeHTMLLogFile(File fd) throws Exception {
269+
FileOutputStream fout = new FileOutputStream(fd);
270+
String htmlHeader = "<html><head><title>Chameleon Mini Live Debugger -- Logging Output</title></head><body>\n\n";
271+
fout.write(htmlHeader.getBytes(StandardCharsets.US_ASCII));
272+
String defaultBgColor = String.format("#%06X", (0xFFFFFF & R.color.colorPrimaryDarkLog));
273+
for (int vi = 0; vi < LiveLoggerActivity.logDataFeed.getChildCount(); vi++) {
274+
View logEntryView = LiveLoggerActivity.logDataFeed.getChildAt(vi);
275+
if (LiveLoggerActivity.logDataEntries.get(vi) instanceof LogEntryUI) {
276+
String bgColor = String.format("#%06X", (0xFFFFFF & logEntryView.getDrawingCacheBackgroundColor()));
277+
if(bgColor.equals(defaultBgColor))
278+
bgColor = "#ffffff";
279+
String lineData = "<code bgcolor='" + bgColor + "'>" + ((LogEntryUI) LiveLoggerActivity.logDataEntries.get(vi)).toString() + "</code><br/>\n";
280+
fout.write(lineData.getBytes(StandardCharsets.US_ASCII));
281+
}
282+
else {
283+
String lineData = "<b><code>" + ((LogEntryMetadataRecord) LiveLoggerActivity.logDataEntries.get(vi)).toString() + "</code></b><br/>\n";
284+
fout.write(lineData.getBytes(StandardCharsets.US_ASCII));
285+
}
286+
}
287+
String htmlFooter = "</body></html>";
288+
fout.write(htmlFooter.getBytes(StandardCharsets.US_ASCII));
289+
fout.close();
290+
return true;
291+
}
231292

232-
293+
public static boolean writeBinaryLogFile(File fd) throws Exception {
294+
FileOutputStream fout = new FileOutputStream(fd);
295+
short localTicks = 0;
296+
for (int vi = 0; vi < LiveLoggerActivity.logDataFeed.getChildCount(); vi++) {
297+
View logEntryView = LiveLoggerActivity.logDataFeed.getChildAt(vi);
298+
if (LiveLoggerActivity.logDataEntries.get(vi) instanceof LogEntryUI) {
299+
LogEntryUI logEntry = (LogEntryUI) LiveLoggerActivity.logDataEntries.get(vi);
300+
byte[] entryBytes = logEntry.packageBinaryLogData(localTicks);
301+
localTicks = logEntry.getNextOffsetTime(localTicks);
302+
fout.write(entryBytes);
303+
}
304+
}
305+
fout.close();
306+
return true;
307+
}
233308

234309
}

0 commit comments

Comments
 (0)