From 02d29246cf4ecca96c979378d2ef4ae5e26612f7 Mon Sep 17 00:00:00 2001 From: maxieds Date: Sat, 12 May 2018 00:55:24 -0400 Subject: [PATCH] Integrated commands and button settings for the RevE boards into the app. --- app/build.gradle | 4 +- .../ChameleonIO.java | 117 +++++++++----- .../LiveLoggerActivity.java | 59 +++++-- .../TabFragment.java | 4 +- app/src/main/res/drawable/apdubullet16.png | Bin 0 -> 442 bytes app/src/main/res/drawable/buttonmy24.png | Bin 0 -> 728 bytes app/src/main/res/drawable/clearmy24.png | Bin 0 -> 684 bytes app/src/main/res/drawable/copysquare16.png | Bin 0 -> 430 bytes app/src/main/res/drawable/fingerprint.png | Bin 0 -> 917 bytes app/src/main/res/drawable/reset24v2.png | Bin 0 -> 745 bytes app/src/main/res/drawable/rssimy24.png | Bin 0 -> 637 bytes app/src/main/res/drawable/signalbars1.png | Bin 205 -> 164 bytes app/src/main/res/drawable/signalbars2.png | Bin 227 -> 193 bytes app/src/main/res/drawable/signalbars3.png | Bin 265 -> 238 bytes app/src/main/res/drawable/signalbars4.png | Bin 285 -> 278 bytes app/src/main/res/drawable/signalbars5.png | Bin 500 -> 299 bytes app/src/main/res/drawable/uididentifier16.png | Bin 0 -> 553 bytes app/src/main/res/drawable/versionmy24.png | Bin 0 -> 792 bytes app/src/main/res/layout/tools_menu_tab.xml | 149 +++++++++++++----- app/src/main/res/values/strings.xml | 13 +- app/src/main/res/xml/usb_device_filter.xml | 1 + 21 files changed, 249 insertions(+), 98 deletions(-) create mode 100644 app/src/main/res/drawable/apdubullet16.png create mode 100644 app/src/main/res/drawable/buttonmy24.png create mode 100644 app/src/main/res/drawable/clearmy24.png create mode 100644 app/src/main/res/drawable/copysquare16.png create mode 100644 app/src/main/res/drawable/fingerprint.png create mode 100644 app/src/main/res/drawable/reset24v2.png create mode 100644 app/src/main/res/drawable/rssimy24.png create mode 100644 app/src/main/res/drawable/uididentifier16.png create mode 100644 app/src/main/res/drawable/versionmy24.png diff --git a/app/build.gradle b/app/build.gradle index e517aac..36beece 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -26,8 +26,8 @@ android { applicationId "com.maxieds.chameleonminilivedebugger" minSdkVersion 21 targetSdkVersion 27 - versionCode 40 - versionName "0.4.0" + versionCode 41 + versionName "0.4.1" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" multiDexEnabled true } diff --git a/app/src/main/java/com/maxieds/chameleonminilivedebugger/ChameleonIO.java b/app/src/main/java/com/maxieds/chameleonminilivedebugger/ChameleonIO.java index 24a3dd0..0109349 100644 --- a/app/src/main/java/com/maxieds/chameleonminilivedebugger/ChameleonIO.java +++ b/app/src/main/java/com/maxieds/chameleonminilivedebugger/ChameleonIO.java @@ -24,8 +24,8 @@ * The ChameleonIO class provides subclasses storing status configurations of the * attached device and utilities for sending commands to the Chameleon Mini. * - * @author Maxie D. Schmidt - * @since 12/31/2017 + * @author Maxie D. Schmidt + * @since 12/31/2017 */ public class ChameleonIO { @@ -37,6 +37,9 @@ public class ChameleonIO { */ public static final int CMUSB_VENDORID = 0x16d0; public static final int CMUSB_PRODUCTID = 0x04b2; + public static final int CMUSB_REVE_VENDORID = 0x03eb; + public static final int CMUSB_REVE_PRODUCTID = 0x2044; + public static boolean REVE_BOARD = false; /** * Default timeout to use when communicating with the device. @@ -59,6 +62,7 @@ public class ChameleonIO { /** * Static storage for command return values. * Used to avoid overhead of passing messages for the command responses. + * * @ref LiveLoggerActivity.getSettingFromDevice * @ref LiveLoggerActivity.usbReaderCallback */ @@ -94,14 +98,18 @@ public enum SerialRespCode { /** * Constructor + * * @param rcode */ - private SerialRespCode(int rcode) { responseCode = rcode; } + private SerialRespCode(int rcode) { + responseCode = rcode; + } /** * Stores a map of integer-valued response codes to their corresponding enum value. */ private static final Map RESP_CODE_MAP = new HashMap<>(); + static { for (SerialRespCode respCode : values()) { int rcode = respCode.toInteger(); @@ -112,9 +120,11 @@ public enum SerialRespCode { /** * Lookup table of String response codes prefixing command return data sent by the device. + * * @ref ChameleonIO.isCommandResponse */ public static final Map RESP_CODE_TEXT_MAP = new HashMap<>(); + static { for (SerialRespCode respCode : values()) { String rcode = String.valueOf(respCode.toInteger()); @@ -125,12 +135,16 @@ public enum SerialRespCode { /** * Retrieve the integer-valued response code associated with the enum value. + * * @return int response code */ - public int toInteger() { return responseCode; } + public int toInteger() { + return responseCode; + } /** * Lookup the enum value by its associated integer response code value. + * * @param rcode * @return SerialRespCode enum value associated with the integer code */ @@ -143,6 +157,7 @@ public static SerialRespCode lookupByResponseCode(int rcode) { /** * Determines whether the received serial byte data is a command response sent by the device * (as opposed to a LIVE log sent by the device). + * * @param liveLogData * @return boolean whether the log data is a response to an issued command * @ref LiveLoggerActivity.usbReaderCallback @@ -150,9 +165,9 @@ public static SerialRespCode lookupByResponseCode(int rcode) { public static boolean isCommandResponse(byte[] liveLogData) { String respText = new String(liveLogData).split("[\n\r]+")[0]; String[] respText2 = new String(liveLogData).split("="); - if(SerialRespCode.RESP_CODE_TEXT_MAP.get(respText) != null) + if (SerialRespCode.RESP_CODE_TEXT_MAP.get(respText) != null) return true; - else if(respText2.length >= 2 && SerialRespCode.RESP_CODE_TEXT_MAP.get(LASTCMD.replace(respText2[1].substring(0, min(respText2[1].length(), LiveLoggerActivity.USB_DATA_BITS)), "")) != null) + else if (respText2.length >= 2 && SerialRespCode.RESP_CODE_TEXT_MAP.get(LASTCMD.replace(respText2[1].substring(0, min(respText2[1].length(), LiveLoggerActivity.USB_DATA_BITS)), "")) != null) return false; return false; } @@ -183,7 +198,7 @@ public static class DeviceStatusSettings { */ public final int STATS_UPDATE_INTERVAL = 8000; // 8 seconds public Handler statsUpdateHandler = new Handler(); - public Runnable statsUpdateRunnable = new Runnable(){ + public Runnable statsUpdateRunnable = new Runnable() { public void run() { updateAllStatusAndPost(true); } @@ -194,39 +209,53 @@ public void run() { */ private boolean updateAllStatus(boolean resetTimer) { try { - if(!LiveLoggerActivity.serialPortLock.tryAcquire(ChameleonIO.LOCK_TIMEOUT, TimeUnit.MILLISECONDS)) { - if(resetTimer) + if (!LiveLoggerActivity.serialPortLock.tryAcquire(ChameleonIO.LOCK_TIMEOUT, TimeUnit.MILLISECONDS)) { + if (resetTimer) statsUpdateHandler.postDelayed(statsUpdateRunnable, STATS_UPDATE_INTERVAL / 4); return false; } - } catch(InterruptedException ie) { - if(resetTimer) + } catch (InterruptedException ie) { + if (resetTimer) statsUpdateHandler.postDelayed(statsUpdateRunnable, STATS_UPDATE_INTERVAL / 4); return false; } - CONFIG = LiveLoggerActivity.getSettingFromDevice(LiveLoggerActivity.serialPort, "CONFIG?", CONFIG); - UID = LiveLoggerActivity.getSettingFromDevice(LiveLoggerActivity.serialPort, "UID?", UID); - UIDSIZE = Utils.parseInt(LiveLoggerActivity.getSettingFromDevice(LiveLoggerActivity.serialPort, "UIDSIZE?", String.format("%d",UIDSIZE))); - MEMSIZE = Utils.parseInt(LiveLoggerActivity.getSettingFromDevice(LiveLoggerActivity.serialPort, "MEMSIZE?", String.format("%d",MEMSIZE))); - LOGSIZE = Utils.parseInt(LiveLoggerActivity.getSettingFromDevice(LiveLoggerActivity.serialPort, "LOGMEM?", String.format("%d", LOGSIZE)).replaceAll(" \\(.*\\)", "")); - DIP_SETTING = Utils.parseInt(LiveLoggerActivity.getSettingFromDevice(LiveLoggerActivity.serialPort, "SETTING?", String.format("%d", DIP_SETTING))); - FIELD = LiveLoggerActivity.getSettingFromDevice(LiveLoggerActivity.serialPort, "FIELD?", String.format("%d", FIELD ? 1 : 0)).equals("1"); - READONLY = LiveLoggerActivity.getSettingFromDevice(LiveLoggerActivity.serialPort, "READONLY?", String.format("%d", READONLY ? 1 : 0)).equals("1"); - FIELD = LiveLoggerActivity.getSettingFromDevice(LiveLoggerActivity.serialPort, "FIELD?", String.format("%d", FIELD ? 1 : 0)).equals("1"); - CHARGING = LiveLoggerActivity.getSettingFromDevice(LiveLoggerActivity.serialPort, "CHARGING?", String.format("%d", CHARGING ? 1 : 0)).equals("TRUE"); - THRESHOLD = Utils.parseInt(LiveLoggerActivity.getSettingFromDevice(LiveLoggerActivity.serialPort, "THRESHOLD?", String.format("%d", THRESHOLD))); - TIMEOUT = LiveLoggerActivity.getSettingFromDevice(LiveLoggerActivity.serialPort, "TIMEOUT?", TIMEOUT); + if (!ChameleonIO.REVE_BOARD) { + CONFIG = LiveLoggerActivity.getSettingFromDevice(LiveLoggerActivity.serialPort, "CONFIG?", CONFIG); + UID = LiveLoggerActivity.getSettingFromDevice(LiveLoggerActivity.serialPort, "UID?", UID); + UIDSIZE = Utils.parseInt(LiveLoggerActivity.getSettingFromDevice(LiveLoggerActivity.serialPort, "UIDSIZE?", String.format("%d", UIDSIZE))); + MEMSIZE = Utils.parseInt(LiveLoggerActivity.getSettingFromDevice(LiveLoggerActivity.serialPort, "MEMSIZE?", String.format("%d", MEMSIZE))); + LOGSIZE = Utils.parseInt(LiveLoggerActivity.getSettingFromDevice(LiveLoggerActivity.serialPort, "LOGMEM?", String.format("%d", LOGSIZE)).replaceAll(" \\(.*\\)", "")); + DIP_SETTING = Utils.parseInt(LiveLoggerActivity.getSettingFromDevice(LiveLoggerActivity.serialPort, "SETTING?", String.format("%d", DIP_SETTING))); + READONLY = LiveLoggerActivity.getSettingFromDevice(LiveLoggerActivity.serialPort, "READONLY?", String.format("%d", READONLY ? 1 : 0)).equals("1"); + FIELD = LiveLoggerActivity.getSettingFromDevice(LiveLoggerActivity.serialPort, "FIELD?", String.format("%d", FIELD ? 1 : 0)).equals("1"); + CHARGING = LiveLoggerActivity.getSettingFromDevice(LiveLoggerActivity.serialPort, "CHARGING?", String.format("%d", CHARGING ? 1 : 0)).equals("TRUE"); + THRESHOLD = Utils.parseInt(LiveLoggerActivity.getSettingFromDevice(LiveLoggerActivity.serialPort, "THRESHOLD?", String.format("%d", THRESHOLD))); + TIMEOUT = LiveLoggerActivity.getSettingFromDevice(LiveLoggerActivity.serialPort, "TIMEOUT?", TIMEOUT); + } + else { + CONFIG = LiveLoggerActivity.getSettingFromDevice(LiveLoggerActivity.serialPort, "configmy?", CONFIG); + UID = LiveLoggerActivity.getSettingFromDevice(LiveLoggerActivity.serialPort, "uidmy?", UID); + UIDSIZE = Utils.parseInt(LiveLoggerActivity.getSettingFromDevice(LiveLoggerActivity.serialPort, "uidsizemy?", String.format("%d",UIDSIZE))); + MEMSIZE = Utils.parseInt(LiveLoggerActivity.getSettingFromDevice(LiveLoggerActivity.serialPort, "memsizemy?", String.format("%d",MEMSIZE))); + LOGSIZE = 0; + DIP_SETTING = Utils.parseInt(LiveLoggerActivity.getSettingFromDevice(LiveLoggerActivity.serialPort, "settingmy?", String.format("%d", DIP_SETTING))); + READONLY = LiveLoggerActivity.getSettingFromDevice(LiveLoggerActivity.serialPort, "readonlymy?", String.format("%d", READONLY ? 1 : 0)).equals("1"); + FIELD = false; + CHARGING = false; + THRESHOLD = 0; + TIMEOUT = "NA"; + } LiveLoggerActivity.serialPortLock.release(); // setup threshold signal bars: double signalStrength = THRESHOLD / 4500.0; - if(signalStrength >= 0.80) + if (signalStrength >= 0.80) LiveLoggerActivity.runningActivity.setStatusIcon(R.id.signalStrength, R.drawable.signalbars5); - else if(signalStrength >= 0.60) + else if (signalStrength >= 0.60) LiveLoggerActivity.runningActivity.setStatusIcon(R.id.signalStrength, R.drawable.signalbars4); - else if(signalStrength >= 0.40) + else if (signalStrength >= 0.40) LiveLoggerActivity.runningActivity.setStatusIcon(R.id.signalStrength, R.drawable.signalbars3); - else if(signalStrength >= 0.20) + else if (signalStrength >= 0.20) LiveLoggerActivity.runningActivity.setStatusIcon(R.id.signalStrength, R.drawable.signalbars2); else LiveLoggerActivity.runningActivity.setStatusIcon(R.id.signalStrength, R.drawable.signalbars1); @@ -236,44 +265,48 @@ else if(signalStrength >= 0.20) /** * Updates all status settings and posts the results to the live activity window. + * * @param resetTimer whether to have this execute again in STATS_UPDATE_INTERVAL milliseconds * @ref DeviceStatusSettings.STATS_UPDATE_INTERVAL * @ref DeviceStatusSettings.updateAllStatus */ public void updateAllStatusAndPost(boolean resetTimer) { - if(LiveLoggerActivity.serialPort == null) + if (LiveLoggerActivity.serialPort == null) return; boolean haveUpdates = updateAllStatus(resetTimer); - if(!haveUpdates) - return;ChameleonIO.WAITING_FOR_RESPONSE = true; + if (!haveUpdates) + return; + ChameleonIO.WAITING_FOR_RESPONSE = true; ((TextView) LiveLoggerActivity.runningActivity.findViewById(R.id.deviceConfigText)).setText(CONFIG); String formattedUID = UID; - if(!UID.equals("NO UID.")) + if (!UID.equals("NO UID.")) formattedUID = UID.replaceAll("..(?!$)", "$0:"); ((TextView) LiveLoggerActivity.runningActivity.findViewById(R.id.deviceConfigUID)).setText(Utils.trimString(formattedUID, "DEVICE CONFIGURATION".length())); - String subStats1 = String.format(Locale.ENGLISH,"MEM-%dK/LOG-%dK/DIP#%d", round(MEMSIZE / 1024), round(LOGSIZE / 1024), DIP_SETTING); + String subStats1 = String.format(Locale.ENGLISH, "MEM-%dK/LOG-%dK/DIP#%d", round(MEMSIZE / 1024), round(LOGSIZE / 1024), DIP_SETTING); ((TextView) LiveLoggerActivity.runningActivity.findViewById(R.id.deviceStats1)).setText(subStats1); - String subStats2 = String.format(Locale.ENGLISH,"%s/FLD-%d/%sCHRG", READONLY ? "RO" : "RW", FIELD ? 1 : 0, CHARGING ? "" : "NO-"); + String subStats2 = String.format(Locale.ENGLISH, "%s/FLD-%d/%sCHRG", READONLY ? "RO" : "RW", FIELD ? 1 : 0, CHARGING ? "" : "NO-"); ((TextView) LiveLoggerActivity.runningActivity.findViewById(R.id.deviceStats2)).setText(subStats2); - String subStats3 = String.format(Locale.ENGLISH,"THRS-%d mv/TMT-%s", THRESHOLD, TIMEOUT); + String subStats3 = String.format(Locale.ENGLISH, "THRS-%d mv/TMT-%s", THRESHOLD, TIMEOUT); ((TextView) LiveLoggerActivity.runningActivity.findViewById(R.id.deviceStats3)).setText(subStats3); SeekBar thresholdSeekbar = (SeekBar) LiveLoggerActivity.runningActivity.findViewById(R.id.thresholdSeekbar); - if(thresholdSeekbar != null) { + if (thresholdSeekbar != null) { thresholdSeekbar.setProgress(THRESHOLD); ((TextView) LiveLoggerActivity.runningActivity.findViewById(R.id.thresholdSeekbarValueText)).setText(String.format(Locale.ENGLISH, "% 5d mV", THRESHOLD)); } NumberPicker settingsNumberPicker = (NumberPicker) LiveLoggerActivity.runningActivity.findViewById(R.id.settingsNumberPicker); - if(settingsNumberPicker != null) { + if (settingsNumberPicker != null) { settingsNumberPicker.setValue(DIP_SETTING); } - if(resetTimer) + if (resetTimer) statsUpdateHandler.postDelayed(statsUpdateRunnable, STATS_UPDATE_INTERVAL); } } + public static DeviceStatusSettings deviceStatus = new ChameleonIO.DeviceStatusSettings(); /** * Put the device into sniffer / logger mode. + * * @param cmPort * @param timeout * @return SerialRespCode status code (OK) @@ -284,6 +317,7 @@ public static SerialRespCode setLoggerConfigMode(UsbSerialDevice cmPort, int tim /** * Put the device into reader mode. + * * @param cmPort * @param timeout * @return SerialRespCode status code (OK) @@ -294,6 +328,7 @@ public static SerialRespCode setReaderConfigMode(UsbSerialDevice cmPort, int tim /** * Enables LIVE logging on the device. + * * @param cmPort * @param timeout * @return SerialRespCode status code (OK) @@ -305,6 +340,7 @@ public static SerialRespCode enableLiveDebugging(UsbSerialDevice cmPort, int tim /** * Resets the timeout on the Chameleon device (avoids zero timeouts from AUTOCALIBRATE) that make * the app otherwise hang. + * * @param cmPort * @param timeout */ @@ -317,6 +353,7 @@ private static void setTimeout(UsbSerialDevice cmPort, int timeout) { /** * Executes the passed command by sending the command to the device. * The response returned by the device is handled separately elsewhere in the program. + * * @param cmPort * @param rawCmd * @param timeout @@ -324,13 +361,13 @@ private static void setTimeout(UsbSerialDevice cmPort, int timeout) { * @url http://rawgit.com/emsec/ChameleonMini/master/Doc/Doxygen/html/Page_CommandLine.html */ public static SerialRespCode executeChameleonMiniCommand(UsbSerialDevice cmPort, String rawCmd, int timeout) { - if(cmPort == null || PAUSED) + if (cmPort == null || PAUSED) return FALSE; - if(timeout < 0) { + if (timeout < 0) { timeout *= -1; SystemClock.sleep(timeout); } - if(timeout != Utils.parseInt(deviceStatus.TIMEOUT)) + if (timeout != Utils.parseInt(deviceStatus.TIMEOUT)) setTimeout(cmPort, timeout); String deviceConfigCmd = rawCmd + "\n\r"; byte[] sendBuf = deviceConfigCmd.getBytes(StandardCharsets.UTF_8); diff --git a/app/src/main/java/com/maxieds/chameleonminilivedebugger/LiveLoggerActivity.java b/app/src/main/java/com/maxieds/chameleonminilivedebugger/LiveLoggerActivity.java index 0f984da..35aad81 100644 --- a/app/src/main/java/com/maxieds/chameleonminilivedebugger/LiveLoggerActivity.java +++ b/app/src/main/java/com/maxieds/chameleonminilivedebugger/LiveLoggerActivity.java @@ -48,6 +48,7 @@ import android.widget.ScrollView; import android.widget.Spinner; import android.widget.SpinnerAdapter; +import android.widget.Switch; import android.widget.TextView; import android.widget.Toolbar; @@ -105,6 +106,7 @@ public class LiveLoggerActivity extends AppCompatActivity { public static SpinnerAdapter spinnerLButtonLongAdapter; public static SpinnerAdapter spinnerLEDRedAdapter; public static SpinnerAdapter spinnerLEDGreenAdapter; + public static SpinnerAdapter spinnerButtonMyAdapter; public static SpinnerAdapter spinnerLogModeAdapter; public static SpinnerAdapter spinnerCmdShellAdapter; public static MenuItem selectedThemeMenuItem; @@ -595,6 +597,12 @@ public UsbSerialDevice configureSerialPort(UsbSerialDevice serialPort, UsbSerial int deviceVID = device.getVendorId(); int devicePID = device.getProductId(); if(deviceVID == ChameleonIO.CMUSB_VENDORID && devicePID == ChameleonIO.CMUSB_PRODUCTID) { + ChameleonIO.REVE_BOARD = false; + connection = usbManager.openDevice(device); + break; + } + else if(deviceVID == ChameleonIO.CMUSB_REVE_VENDORID && devicePID == ChameleonIO.CMUSB_REVE_PRODUCTID) { + ChameleonIO.REVE_BOARD = true; connection = usbManager.openDevice(device); break; } @@ -740,7 +748,8 @@ public void actionButtonRestorePeripheralDefaults(View view) { R.id.LButtonSpinner, R.id.LButtonLongSpinner, R.id.LEDRedSpinner, - R.id.LEDGreenSpinner + R.id.LEDGreenSpinner, + R.id.ButtonMyRevEBoardSpinner }; String[] queryCmds = { "RBUTTON?", @@ -748,7 +757,8 @@ public void actionButtonRestorePeripheralDefaults(View view) { "LBUTTON?", "LBUTTON_LONG?", "LEDRED?", - "LEDGREEN?" + "LEDGREEN?", + "buttonmy?" }; for (int i = 0; i < spinnerIDs.length; i++) { Log.i(TAG, queryCmds[i]); @@ -756,6 +766,12 @@ public void actionButtonRestorePeripheralDefaults(View view) { String deviceSetting = getSettingFromDevice(LiveLoggerActivity.serialPort, queryCmds[i]); curSpinner.setSelection(((ArrayAdapter) curSpinner.getAdapter()).getPosition(deviceSetting)); } + // handle FIELD and READ-ONLY switches: + String fieldSetting = getSettingFromDevice(LiveLoggerActivity.serialPort, "FIELD?"); + ((Switch) findViewById(R.id.fieldOnOffSwitch)).setChecked(fieldSetting.equals("0") ? false : true); + String roQueryCmd = ChameleonIO.REVE_BOARD ? "readonlymy?" : "READONLY?"; + String roSetting = getSettingFromDevice(LiveLoggerActivity.serialPort, roQueryCmd); + ((Switch) findViewById(R.id.readonlyOnOffSwitch)).setChecked(roSetting.equals("0") ? false : true); } } @@ -847,17 +863,26 @@ else if(createCmd.equals("SNIFFER")) { return; } else if(createCmd.equals("ULTRALIGHT")) { - ChameleonIO.executeChameleonMiniCommand(serialPort, "CONFIG=MF_ULTRALIGHT", ChameleonIO.TIMEOUT); + if(!ChameleonIO.REVE_BOARD) + ChameleonIO.executeChameleonMiniCommand(serialPort, "CONFIG=MF_ULTRALIGHT", ChameleonIO.TIMEOUT); + else + ChameleonIO.executeChameleonMiniCommand(serialPort, "configmy=MF_ULTRALIGHT", ChameleonIO.TIMEOUT); ChameleonIO.deviceStatus.updateAllStatusAndPost(false); return; } else if(createCmd.equals("CLASSIC-1K")) { - ChameleonIO.executeChameleonMiniCommand(serialPort, "CONFIG=MF_CLASSIC_1K", ChameleonIO.TIMEOUT); + if(!ChameleonIO.REVE_BOARD) + ChameleonIO.executeChameleonMiniCommand(serialPort, "CONFIG=MF_CLASSIC_1K", ChameleonIO.TIMEOUT); + else + ChameleonIO.executeChameleonMiniCommand(serialPort, "configmy=MF_CLASSIC_1K", ChameleonIO.TIMEOUT); ChameleonIO.deviceStatus.updateAllStatusAndPost(false); return; } else if(createCmd.equals("CLASSIC-4K")) { - ChameleonIO.executeChameleonMiniCommand(serialPort, "CONFIG=MF_CLASSIC_4K", ChameleonIO.TIMEOUT); + if(!ChameleonIO.REVE_BOARD) + ChameleonIO.executeChameleonMiniCommand(serialPort, "CONFIG=MF_CLASSIC_4K", ChameleonIO.TIMEOUT); + else + ChameleonIO.executeChameleonMiniCommand(serialPort, "configmy=MF_CLASSIC_4K", ChameleonIO.TIMEOUT); ChameleonIO.deviceStatus.updateAllStatusAndPost(false); return; } @@ -887,12 +912,15 @@ else if(createCmd.equals("MFU-EV1-164B")) { return; } else if(createCmd.equals("CFGNONE")) { - ChameleonIO.executeChameleonMiniCommand(serialPort, "CONFIG=NONE", ChameleonIO.TIMEOUT); + if(!ChameleonIO.REVE_BOARD) + ChameleonIO.executeChameleonMiniCommand(serialPort, "CONFIG=NONE", ChameleonIO.TIMEOUT); + else + ChameleonIO.executeChameleonMiniCommand(serialPort, "configmy=NONE", ChameleonIO.TIMEOUT); ChameleonIO.deviceStatus.updateAllStatusAndPost(false); return; } - else if(createCmd.equals("RESET")) { // need to re-establish the usb connection: - ChameleonIO.executeChameleonMiniCommand(serialPort, "RESET", ChameleonIO.TIMEOUT); + else if(createCmd.equals("RESET") || createCmd.equals("resetmy")) { // need to re-establish the usb connection: + ChameleonIO.executeChameleonMiniCommand(serialPort, createCmd, ChameleonIO.TIMEOUT); ChameleonIO.deviceStatus.statsUpdateHandler.removeCallbacks(ChameleonIO.deviceStatus.statsUpdateRunnable); closeSerialPort(serialPort); configureSerialPort(null, usbReaderCallback); @@ -900,8 +928,9 @@ else if(createCmd.equals("RESET")) { // need to re-establish the usb connection: return; } else if(createCmd.equals("RANDOM UID")) { + String uidCmd = ChameleonIO.REVE_BOARD ? "uidmy=" : "UID="; byte[] randomBytes = Utils.getRandomBytes(ChameleonIO.deviceStatus.UIDSIZE); - String sendCmd = "UID=" + Utils.bytes2Hex(randomBytes).replace(" ", ""); + String sendCmd = uidCmd + Utils.bytes2Hex(randomBytes).replace(" ", ""); ChameleonIO.executeChameleonMiniCommand(serialPort, sendCmd, ChameleonIO.TIMEOUT); ChameleonIO.deviceStatus.updateAllStatusAndPost(false); } @@ -924,7 +953,8 @@ else if(createCmd.equals("ONCLICK")) { msgParam = "SYSTICK Millis := " + getSettingFromDevice(serialPort, "SYSTICK?"); } else if(createCmd.equals("GETUID")) { - String rParam = getSettingFromDevice(serialPort, "GETUID"); + String queryCmd = ChameleonIO.REVE_BOARD ? "uidmy?" : "GETUID"; + String rParam = getSettingFromDevice(serialPort, queryCmd); msgParam = "GETUID: " + rParam; } else if(createCmd.equals("SEND") || createCmd.equals("SEND_RAW")) { @@ -1071,7 +1101,8 @@ else if(uidAction.equals("SHIFT_LEFT")){ System.arraycopy(uid, 0, nextUID, 1, uid.length - 1); uid = nextUID; } - getSettingFromDevice(serialPort, String.format(Locale.ENGLISH, "UID=%s", Utils.bytes2Hex(uid).replace(" ", ""))); + String uidCmd = ChameleonIO.REVE_BOARD ? "uidmy" : "UID"; + getSettingFromDevice(serialPort, String.format(Locale.ENGLISH, "%s=%s", uidCmd, Utils.bytes2Hex(uid).replace(" ", ""))); ChameleonIO.deviceStatus.updateAllStatusAndPost(false); appendNewLog(LogEntryMetadataRecord.createDefaultEventRecord("UID", "Next device UID set to " + Utils.bytes2Hex(uid).replace(" ", ":"))); } @@ -1327,8 +1358,10 @@ public void actionButtonExportLogDownload(View view) { ExportTools.downloadByXModem("LOGDOWNLOAD", "devicelog", false); else if(action.equals("LOGDOWNLOAD2LIVE")) ExportTools.downloadByXModem("LOGDOWNLOAD", "devicelog", true); - else if(action.equals("DOWNLOAD")) - ExportTools.downloadByXModem("DOWNLOAD", "carddata-" + ChameleonIO.deviceStatus.CONFIG, false); + else if(action.equals("DOWNLOAD")) { + String dldCmd = ChameleonIO.REVE_BOARD ? "downloadmy" : "DOWNLOAD"; + ExportTools.downloadByXModem(dldCmd, "carddata-" + ChameleonIO.deviceStatus.CONFIG, false); + } } /** diff --git a/app/src/main/java/com/maxieds/chameleonminilivedebugger/TabFragment.java b/app/src/main/java/com/maxieds/chameleonminilivedebugger/TabFragment.java index 5a93f82..cfde925 100644 --- a/app/src/main/java/com/maxieds/chameleonminilivedebugger/TabFragment.java +++ b/app/src/main/java/com/maxieds/chameleonminilivedebugger/TabFragment.java @@ -227,6 +227,7 @@ else if(tabNumber == TAB_TOOLS && LiveLoggerActivity.spinnerRButtonLongAdapter = connectPeripheralSpinnerAdapter(view, R.id.LButtonLongSpinner, R.array.LButtonLongOptions, LiveLoggerActivity.spinnerLButtonLongAdapter, "LBUTTON_LONG?"); connectPeripheralSpinnerAdapter(view, R.id.LEDRedSpinner, R.array.LEDRedOptions, LiveLoggerActivity.spinnerLEDRedAdapter, "LEDRED?"); connectPeripheralSpinnerAdapter(view, R.id.LEDGreenSpinner, R.array.LEDGreenOptions, LiveLoggerActivity.spinnerLEDGreenAdapter, "LEDGREEN?"); + connectPeripheralSpinnerAdapter(view, R.id.ButtonMyRevEBoardSpinner, R.array.ButtonMyRevEBoards, LiveLoggerActivity.spinnerButtonMyAdapter, "buttonmy?"); connectPeripheralSpinnerAdapter(view, R.id.LogModeSpinner, R.array.LogModeOptions, LiveLoggerActivity.spinnerLogModeAdapter, "LOGMODE?"); connectCommandListSpinnerAdapter(view, R.id.FullCmdListSpinner, R.array.FullCommandList, LiveLoggerActivity.spinnerCmdShellAdapter, ""); @@ -283,7 +284,8 @@ public void onStopTrackingTouch(SeekBar seekBar) { @Override public void onScrollStateChange(NumberPicker numberPicker, int scrollState) { if (scrollState == NumberPicker.OnScrollListener.SCROLL_STATE_IDLE) { - LiveLoggerActivity.getSettingFromDevice(LiveLoggerActivity.serialPort, "SETTING=" + numberPicker.getValue()); + String settingCmd = ChameleonIO.REVE_BOARD ? "settingmy=" : "SETTING="; + LiveLoggerActivity.getSettingFromDevice(LiveLoggerActivity.serialPort, settingCmd + numberPicker.getValue()); ChameleonIO.deviceStatus.updateAllStatusAndPost(false); } } diff --git a/app/src/main/res/drawable/apdubullet16.png b/app/src/main/res/drawable/apdubullet16.png new file mode 100644 index 0000000000000000000000000000000000000000..740d336b61edbfa69abca0c7698e1f57230f4be3 GIT binary patch literal 442 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^xl_H+M9WCijSl0AZa z85pY67#JE_7#My5g&JNkFq9fFFuY1&V6d9Oz#v{QXIG#NP=YDR+uenMVO6iP5s=4O z;1O92wCOqsGdgL^t^f+Mmw5WRvOi*F;bN1SFIFZ96zcGFaSYKo-+RGO=wO0C+e7z9 z4F3fsx?aq6ekbM_yA%19*4A7SDmDJpAn9nO2EggD{`KJD>(hkPX54X(i=} nMX3zs<>h*rdD+Fui3O>8`9NS%G|oWRD45bDP46hOx7_4S6Fo+k-*%fF5lweBoc6VW5Sk5Uj7}P}D}aLRC7!;n?2lM^*i0nPEn-h$U|?M4>Eak-aeD3*`;6c~k>elz zXR&a4cr0aII4x?ex59$FrLrx2j!};nc?T}pY{Ai0RxG;Ed$~h9TS?%ARg<^4a!yhe zkQ15H)fF1BW=o2I%SyiYi9(-U9>>1>S$O_?(Z9R1CzKsjwXBcdt@X|*-SM0Jos&@p z(?7&`3cHIuU79Sjzw+hE@Do*YCS5)v`doMAk9!ZTUhcYW))V#Zz@lX`jLX(|l-;#i z^i6yF6477|r-Z8oJ{q6TZCRPPn&a1j1#2Z9OcBq`I<3%hV4e%lhl7n~Q#V{^dX<*c zU@Ct5N>5b=i^K(kd#oz9Cek+_OR)(oIk0V#>tC~a?bqVp?`%mt(KqR>!KMQrUsTNB zXm65t`TB{zRaXvsx&Bt{{?)FK#IZ0z|cb1z*N`JD8#_b z%GAip$W+_F$jZQA($mOgC>nC}Q!>*kacg+INS%G|oWRD45bDP46hOx7_4S6Fo+k-*%fF5lweBoc6VW5Sk5Uj7}P}D}aLRC7!;n?2lM^SWOKdcqz0oFfdkmx;TbdobJ73?=dw{=Ge#n z_olu71h#N=xdsGEE?u~k*DWB-+q;?f+{Ft5yiMJ{>)HfNOlAh;AD}ZhDx#~#^6m!qdT+LMT z^=5Gc%fap&UaYNrztv*#;kfCwE7{(Ev*^t)o>ChA zZbRttyBD4}sJY75emXPzZQFmIkczII-}U%_5u;k-8c~vxSdwa$T$Bo=7>o=IEp!b` zbq$R|3{0&|jjc>9wGE7{3=9q`*)B!Vkei>9nO2Eg!-o1+NuUNvkPX54X(i=}MX3zs j<>h*rdD+Fui3O>8`9WIkU{F)L$#RWg5MZ6@tOy`D#@1aObg68{%`eHKg)bm<`l2>*F+eXwT11A zyw$pK=JK`2-6Jif1^SF~uZRh#nSBy_n0AHZPUxgBe;)jAt=qm~TX`?vLxpnAGs4bS z{Q^|_^k(h64!{5l*E!$tK_0oAjM#0U}&LhV5)0i5@KjzWnf}u zWT5sBtbR==ckpFCl;kLl$V$5W#(lUCnpx9 X>g5-u&wghk1ybed>gTe~DWM4f6oQ9n literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable/fingerprint.png b/app/src/main/res/drawable/fingerprint.png new file mode 100644 index 0000000000000000000000000000000000000000..36896b4716c84b1c6bb7809ae6faf53d36d77cf2 GIT binary patch literal 917 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM0wlfaz7_*1mUKs7M+SzC{oH>NS%G|oWRD45bDP46hOx7_4S6Fo+k-*%fF5lweBoc6VW5Sk5Uj7}P}D}aLRC7!;n?2lNP_=I@+a@`bwnvy+T978Nlw_b_$5Gxa5`*8pF zGwZWn-Kl;XO|*+@Cy4ZFG^MPKJd?0{g>-Yrwr;&ScT2=;FMjuWnHdcAx_o`WMd_!Ji=!5^vFjK+ z9%<*}F6-E{O#i}CuA6?ZuRZOHy1Mr zq5q6(oi_KM`En)qr$lo5=T~n+wc3oEzA9WkBDZtqjunyXB#dlAUaw(qs%pJt^2$uw zd~VfRW!FBD(zNf9N1x9souL=r{aVTFrIFC27$f0o)iZ)0x5meAI4JP)(X1sAdOt$e zwOloD{jjv=V495RmMoz=Mm`f4`0RTiux@43(IFLHr?&8?%G{*cdOKg$*(OIiHiR7JS6kn@NDYAjKbWklo?uiZ095!)D@N)YhAA} zU8J`1xZ`evNM^T+24*ouZ|-BA>XP~kk4db2<@)!T{^8WjBOLXQW{5rAv^AmQc0hxz z)sva}8eu9w&N!S8@%l91>(4{?7khOttK=N!Tx<7Xt-|FP$4)0l&9EP<-dDaaxvn7p zdP}U&AWRQKn;>08-nxGO3D+9QW?t2%k?tzvWt@w3sUv+i_&Mm SvylQSV(@hJb6Mw<&;$Uc;d|x) literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable/reset24v2.png b/app/src/main/res/drawable/reset24v2.png new file mode 100644 index 0000000000000000000000000000000000000000..3ff066e4aa880a0bcb7ea76f2ab157a5f672f930 GIT binary patch literal 745 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM0wlfaz7_*1mUKs7M+SzC{oH>NS%G|oWRD45bDP46hOx7_4S6Fo+k-*%fF5lweBoc6VW5Sk5Uj7}P}D}aLRC7!;n?2lM^SoQe+OC3{WU|`(t>Eak-aeD5h^WIYeMUH(u z-;?Rw#UZE^xWnL7?<0OLbEUPtQx=8V3z$DW_y2%cZp=@1mPEE(r4q@T%ceFeKRu*W zqR1oRG~>Y`iT2A$_wH3*o%G_)S=;;1EvHwXx3zR%ydZjhosRael>3~937(NDVK*l= z+Rx@*7Ah2dvWa!6%IXm-p9bi?E0pM~)piFQ}bT2Ah<6Zz{ca`C%7YwiuNhX)O#dvg}* z=8MK^#@L5_u)JHEXu7`Rp2)dhl_&P)o8A2$w!Sp{#>oh`KOWX!?w;-0q9u_XP3>+VCVvx=^nKlF98TdH*D#DwjKwiR!!ZvSxQ z<&_OF*5@V9w-i|4?$!GBAZyZnK|Y%c&nD_SRTS>HUFkpR+@5mD(rd<_Lq0~_{kUHK zV<^XZ$L0NnC}Q!>*kackK3{+}gKgCxj? t;QX|b^2DN4hVt@qz0ADq;^f4FRK5J7^x5xhq=1STJYD@<);T3K0RSW>Cfxu4 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable/rssimy24.png b/app/src/main/res/drawable/rssimy24.png new file mode 100644 index 0000000000000000000000000000000000000000..20439ba0fbf055d1611f04c33dc57cfeffd8d035 GIT binary patch literal 637 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM0wlfaz7_*1mUKs7M+SzC{oH>NS%G|oWRD45bDP46hOx7_4S6Fo+k-*%fF5lweBoc6VW5Sk5Uj7}P}D}aLRC7!;n?2lM^Sk0|m*Uj!>U|{t2ba4!^IKB4rM(->bUER|Z}=s(5gR zMTOL_(s|40+An-=ZCi8i{P*8a4?jO#e`(6f)ej~ssjYrgdRuAR)zz%eT>bsegdd#E z=j!e*lNBcyA?kjt$5JR?|M2a)PSyPU6sVw|L2P6$9*!rmKTfP=OhH@d`*9Tl)>-rv>Osf(p`L}tV_&iXy+94|92~U zU-#C!pDzXYvL8j?WLtlvGc0mdVj`7-jIhhfA z+;{!WsoHb?&SFnny>8KupounD^BJYu>th%;)&fIXwZt`|BqgyV)hf9t6-Y4{85mmV z8kp)D8ig2`TA2cog|>l_m4U&shi)fOH00)|WTsW()^L5#zY?GZNstY}`DrEPiAAXl k<>lpinR(g8$%zH2dih1^v)|cB0TnTLy85}Sb4q9e0LpOo=>Px# literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable/signalbars1.png b/app/src/main/res/drawable/signalbars1.png index 633d21307b60f544f4feeb685c056516c2c384f3..0e8fed18f4e068d0c0a47c55e412001012447ad5 100644 GIT binary patch delta 127 zcmX@hxP(!$Gr-TCmrII^fq{Y7)59eQNDF{42Mdtg`pf*)L`A(&9u^JZ(=F+qKp|64 z7sn8d^T`PktY29F7oIZs_dWeV;*E1Z__p8s4+Q)Na?Q98`?AHg@&Cwq{^R`L`GVVR Z7+zHInV);dHw9<_gQu&X%Q~loCIH1?E{6aB delta 168 zcmZ3&c$QJIGr-TCmrII^fq{Y7)59eQNK1e)2Mdt&s{2|zQBkjsS%g#aaks`KpirEr zi(`nz>Er|jK?9-HAMB^3DP3(7T-n&V<3Nhczj^=q)fe*S+5b`3>fZ2Ydh&y$goGXE ze@wnH=gaT^Adqfs@TcABkB-`k#Sxv~O^&?$-|>BmF0(!}^I=W4C`JYw9mTod1ubfT PHZgd*`njxgN@xNAvxGpC diff --git a/app/src/main/res/drawable/signalbars2.png b/app/src/main/res/drawable/signalbars2.png index dd5332a0479810cd257ee5a832df3d0f8a2dfed0..563705d13208d8ce017254cf5455fcdb8854efb6 100644 GIT binary patch delta 156 zcmaFNc#u)CGr-TCmrII^fq{Y7)59eQNDF{42Mdtg`pf*)L`A(K9u^Jb53k%CfkHu^ zE{-7@=il~jU8OD?**F9;OXk;vd$@? F2>@6Er|jK?9-HAMB^3DP3(7T-n&V<3Nhczj^=q)fe*S`Tvjq{Qua0>HnWODt_&k zVHRg*K3scjK93d8D;^#mua=x0rwisjv~uS9=-0%eqy14zq46KT+@Jp(u5)ym^?`~t m+1T1N*b0H9HqRASQHFO<#df}7x#bCT0E4HipUXO@geCxJb3$MM diff --git a/app/src/main/res/drawable/signalbars3.png b/app/src/main/res/drawable/signalbars3.png index 8e12f2ddc9d3b53400b7236eae3f4077f2f3dc3c..dc449be68abc16f0fe1c72645a860db2cd541d97 100644 GIT binary patch delta 202 zcmeBVddH~P8Q|y6%O%Cdz`(%k>ERLtqy<2jg9S)#{bl}YqM}|s4~wRN_cZoRK%sh1 z7sn8d^KZ}Z<~+n8()v(eDw!)*v3Kzeu18{G>y~vaUb12sSO@+!H4oihC@br%9%BvVD+#&cbiNKHF&>%fD_!mn=}b-P;bo1FP5Aul!MH|vJu zPQBsVi++uYX9KXe+&dE zEffArqW}N^r%6OXR4C8Q&@pNPVGzaf-xojEEliizN=TJk*apN~SmbIEW9Jb(fQ3a0 z5$sch$gVgk*22Y2pMhb9$A2D=;a^s?X6i&3i=0Eb;1$OV?Mjokw4e_6};F ss2%Jb8z4og=UX;VIV*9J6{=LjFBvm0BO7aI7XSbN07*qoM6N<$f)SKtw*UYD delta 249 zcmV z3{|WlH@?%e+618 zQ=qbAENUT1D&nD&_v3y8t&N*w0m z{Hq)$0%A)? zL;(MXkIcW3Yao9N1S$rUZ{Z*S006v6L_t(2&xOuAN&{gSh2iJdaWZ(p#!9dftXza( zCxW;O3%6#FbS@zqkXTrR;PfhDE)zcsu^8u1Jl%npbKYcSBH6aI1~`kC7!_-XeTQuL zCmA4GEpw5?sS}TX$kxU~MD*h#A|mfF#Vm6XNk#fxEqPsJXcz|_$&h|p=@?~aA&Hyl z$E|r+r-&=N2F_jEa+d+z<5GjK-={Y4WY4SG*u=s!7AD4OZ))!;Dw{qOdgdAxrV6E* b#*XDT#~wbGI5_h800000NkvXXu0mjfD6MYt literal 500 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM0wlfaz7_*1mUKs7M+SzC{oH>NS%G|oWRD45bDP46hOx7_4S6Fo+k-*%fF5lweBoc6VW5Sk5Uj7}P}D}aLRC7!;n?2lNP#n`pCMK^o`3LWxvaSX9IeRaxOE~Y?%*8P!N zIK;YLS#+oAM(eO`wrj8a==;U-$SdmzokQy!#f~IxoS{?Aqx7%gO^2(x?2gZ8=N9Y5 z{Mc~j_6n)k2T$g$iI_BnJ@3)2%(@4izcm+xOz?G)zj5=9rGKzz5SNtqq%Zo*t}bLv z+4ganNg{)eL{&J~z4^7tQN~NXM8#)>P3D?#bLIrT3wpZ}y`2u7*ni1%`6hV*21}b2 ze_UU#^RZoZ;8I`L3g+zF_vQU~ogO5t?zeA@j%D!baJ~L2^{_M0H>xGB5hW>!C8<`) zMX5lF!N|bSLf61l*T6W$$jHjT+{(mQ+W^QgSYi9^3yOx^{FKbJO57T5Cir;(HAsSN t2+mI{DNig)WhgH%*UQYyE>2D?NY%?PN}v7CMhd8i!PC{xWt~$(698P%sg?i$ diff --git a/app/src/main/res/drawable/uididentifier16.png b/app/src/main/res/drawable/uididentifier16.png new file mode 100644 index 0000000000000000000000000000000000000000..9020f3497b1dc0276426ffaa5fd263b69e1490f8 GIT binary patch literal 553 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^xl_H+M9WCijSl0AZa z85pY67#JE_7#My5g&JNkFq9fFFuY1&V6d9Oz#v{QXIG#NP=YDR+uenMVO6iP5s=4O z;1O92wCOqsGdgL^t^f+Mmw5WRvOi+wVU?Bmzf{ZtDD>Ua#W6(VeCx&a-pz?3tPkAP zIgD3H$P`DVMEErExb%9rDJDg4lG+meMPFdcjWdfJSLZkyoZMt3nz%tJSwZT`^$q3s zFKntlZQEXK`JKI1iPflV&5rARIp@|rm6Hn*XDMwKwEusQ%jt}2a@tw-9TxGFj;Y?#HTV3Ra=ChW-|Q@@jWg!xr{7H#kICflyQBKo@k46#g%Ulh zr;ol??M!&~KKvi|GOI5RN;3@9_49)ccX!>ctMB{B{X46e<;@<~Hee8_mbgZgq$HN4 zS|t~y0x1R~149d415;f?qYwjADV wK@wy`aDG}zd16s2LwR|*US?i)adKios$PCk`s{Z$Qb0uvp00i_>zopr09+BlW&i*H literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable/versionmy24.png b/app/src/main/res/drawable/versionmy24.png new file mode 100644 index 0000000000000000000000000000000000000000..5c1360441fc0cd47d4a544e24f6bf25c65767909 GIT binary patch literal 792 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM0wlfaz7_*1mUKs7M+SzC{oH>NS%G|oWRD45bDP46hOx7_4S6Fo+k-*%fF5lweBoc6VW5Sk5Uj7}P}D}aLRC7!;n?2lM^SglwL6MtkeFfcyzba4!^INf{6+v7^01nY{7KU~=i8=1#Y!X|?bL+)2g{F*)N`aajE`f<# zm=3!x734IYkeH%5H8_O(zwzh!g<^BB{yk^=y!y_2x0K|$VrRc;e7l)_xvi&V{pU?j zzOqf#xb%3>+$6hKLD^Tnm+UimRa5M?cza!A<=$g|MXt`d9q^e$vlTeCkx#Q`k1@?a9gt6ui1$mSwYV$ zwfZ7AnC5C23*S1Dr!8l>>Q;;BQ^x;(zE<~FWCdj2TD0#fV{_!a-$@Shr1ey_b2gtA z$uM4We#!lXVUP5*LzhSBc+M-;x47EXeRHKXI=;&ZK`o!zUMc;~I{vdlThXMbj`p~-9U!b>7ncYH3XySVCVaeKbLy7&-#@wbJ? zT*|gRTwt)4j+a?HHoP9TU*HTsXyIgfS%U7?wH~TO9Dc6fn zld>8QpIptsSGjB1J2h{vzY`fM&7zJKUaU`?UwbL(+?Qv-M4(#Y8c~vxSdwa$T$Bo= z7>o=IEp!b`bq$R|3{0&|EvyVov<-}`3=HnXugpNvkei>9nO2Eg!&)Z6D?kmBARB`7 r(@M${i&7cN%ggmL^RkPR6AM!H@{7`Ezq647Dq`?-^>bP0l+XkKK{YqS literal 0 HcmV?d00001 diff --git a/app/src/main/res/layout/tools_menu_tab.xml b/app/src/main/res/layout/tools_menu_tab.xml index 8537607..c504507 100644 --- a/app/src/main/res/layout/tools_menu_tab.xml +++ b/app/src/main/res/layout/tools_menu_tab.xml @@ -110,12 +110,49 @@ android:onClick="actionButtonCreateNewEvent" android:text="CFGNONE" /> +