diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..bf27d7a --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1 @@ +* @martinpaljak diff --git a/build.gradle b/build.gradle index 3c515e7..52423c2 100644 --- a/build.gradle +++ b/build.gradle @@ -2,12 +2,13 @@ plugins { id 'application' id 'org.openjfx.javafxplugin' version '0.0.14' id 'com.palantir.git-version' version '3.0.0' // for gitVersion() + id 'org.beryx.jlink' version '2.25.0' // id 'com.gluonhq.client-gradle-plugin' version '0.1.42' // id 'com.gluonhq.gluonfx-gradle-plugin' version '1.0.16' } group 'pro.javacard.nfc4pc' -version '230707' +version '230708-next' repositories { mavenLocal() @@ -27,19 +28,26 @@ javafx { modules = ['javafx.controls', 'javafx.graphics', 'javafx.swing'] //configuration = 'compileOnly' } + +jlink { + launcher { + name = 'nfc4pc' + } +} + //gluonClient { // reflectionList = ["pro.javacard.nfc4pc.MainWrapper"] //} application { - mainClass = "$moduleName/pro.javacard.nfc4pc.MainWrapper" mainModule = "pro.javacard.nfc4pc" + mainClass = "pro.javacard.nfc4pc.MainWrapper" } jar { manifest { - attributes 'Main-Class': 'pro.javacard.nfc4pc.MainWrapper' + attributes 'Main-Class': application.mainClass attributes 'Implementation-Version': gitVersion() } from { diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 249e583..ccebba7 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index da1db5f..a363877 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip +networkTimeout=10000 zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index a69d9cb..79a61d4 100755 --- a/gradlew +++ b/gradlew @@ -55,7 +55,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -80,10 +80,10 @@ do esac done -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit - -APP_NAME="Gradle" +# This is normally unused +# shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' @@ -143,12 +143,16 @@ fi if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then case $MAX_FD in #( max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 MAX_FD=$( ulimit -H -n ) || warn "Could not query maximum file descriptor limit" esac case $MAX_FD in #( '' | soft) :;; #( *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 ulimit -n "$MAX_FD" || warn "Could not set maximum file descriptor limit to $MAX_FD" esac diff --git a/gradlew.bat b/gradlew.bat index 53a6b23..6689b85 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -26,6 +26,7 @@ if "%OS%"=="Windows_NT" setlocal set DIRNAME=%~dp0 if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% diff --git a/src/main/java/pro/javacard/nfc4pc/CLIOptions.java b/src/main/java/pro/javacard/nfc4pc/CLIOptions.java index 39df3dd..e59a037 100644 --- a/src/main/java/pro/javacard/nfc4pc/CLIOptions.java +++ b/src/main/java/pro/javacard/nfc4pc/CLIOptions.java @@ -61,6 +61,15 @@ protected static OptionSet parseArguments(String[] argv) throws IOException { } if (args.has(OPT_VERSION)) { + if (args.has(OPT_DEBUG)) { + if (System.getProperty("os.name").equalsIgnoreCase("Mac OS X")) { + ProcessBuilder pb = new ProcessBuilder(List.of("/usr/sbin/sysctl", "-n", "machdep.cpu.brand_string")); + Process process = pb.start(); + String result = new String(process.getInputStream().readAllBytes()).trim(); + System.out.printf("# Running Java %s (%s) from %s on %s %s (%s)%n", System.getProperty("java.version"), System.getProperty("os.arch"), System.getProperty("java.vendor"), System.getProperty("os.name"), System.getProperty("os.version"), result); + } else + System.out.printf("# Running Java %s (%s) from %s on %s %s%n", System.getProperty("java.version"), System.getProperty("os.arch"), System.getProperty("java.vendor"), System.getProperty("os.name"), System.getProperty("os.version")); + } System.out.println("NFC4PC version " + CLIOptions.class.getPackage().getImplementationVersion()); System.exit(0); } diff --git a/src/main/java/pro/javacard/nfc4pc/NDEF.java b/src/main/java/pro/javacard/nfc4pc/NDEF.java index 1343b3d..55c78e4 100644 --- a/src/main/java/pro/javacard/nfc4pc/NDEF.java +++ b/src/main/java/pro/javacard/nfc4pc/NDEF.java @@ -35,33 +35,31 @@ static boolean isNull(byte[] b) { return true; } - // Returns the NDEF message + // Returns the NDEF message, if any static Optional getType2(APDUBIBO b) throws BIBOException { try { - // Read initial block - ResponseAPDU initial = b.transmit(new CommandAPDU(0xFF, 0xB0, 0x00, 3, 0x10)); - if (initial.getSW() == 0x9000 && initial.getData().length == 0x10) { + // Read capability container + ResponseAPDU initial = b.transmit(new CommandAPDU(0xFF, 0xB0, 0x00, 3, 0x04)); + if (initial.getSW() == 0x9000 && initial.getData().length == 4) { var init = initial.getData(); - log.debug("Initial read (blocks 3, 4, 5, 6): {}", HexUtils.bin2hex(init)); + log.debug("Capability container: {}", HexUtils.bin2hex(init)); if (init[0] == (byte) 0xE1 && init[1] == 0x10) { int total = (init[2] & 0xFF) * 8; log.info("NDEF payload of {} bytes", total); - int toRead = total - init.length - 4; // So that we don't read the OTP? ByteArrayOutputStream payload = new ByteArrayOutputStream(); - payload.write(Arrays.copyOfRange(init, 4, init.length)); - for (int i = 7; (i - 3) * 4 < total; i += 4) { - log.debug("Reading from block {} to {}, bytes {} to {}", i, i + 3, (i - 3) * 4, (i - 3) * 4 + 16); + for (int i = 4; i * 4 < total; i++) { + log.debug("Reading block {}", i); log.debug("Current payload: ({} bytes) {}", payload.toByteArray().length, HexUtils.bin2hex(payload.toByteArray())); - var block = b.transmit(new CommandAPDU(0xFF, 0xB0, 0x00, i, 0x10)); - var uid_bytes = block.getData(); + var block = b.transmit(new CommandAPDU(0xFF, 0xB0, 0x00, i, 4)); + var bytes = block.getData(); if (block.getSW() == 0x9000) { - log.debug("Block: {}", HexUtils.bin2hex(uid_bytes)); - if (isNull(uid_bytes)) { + log.debug("Block: {}", HexUtils.bin2hex(bytes)); + if (isNull(bytes)) { log.debug("Empty block, not reading more"); break; } - payload.write(uid_bytes); + payload.write(bytes); } else { log.warn("Read returned {}", HexUtils.bin2hex(block.getBytes())); return Optional.empty();