44import android .os .Handler ;
55import android .os .Looper ;
66import android .util .Log ;
7+ import android .view .View ;
78import android .widget .Button ;
89
910import com .felhr .usbserial .SerialInputStream ;
1920import java .io .FileInputStream ;
2021import java .io .FileOutputStream ;
2122import java .io .IOException ;
23+ import java .nio .charset .StandardCharsets ;
2224import java .util .HashMap ;
2325import java .util .Map ;
2426import 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