diff --git a/app/src/main/c/glue.c b/app/src/main/c/glue.c index dcef42a..c13cacd 100644 --- a/app/src/main/c/glue.c +++ b/app/src/main/c/glue.c @@ -1,9 +1,13 @@ +#include "glue.h" + #include #include #include "../../../../clib/proxmark3/include/usb_cmd.h" #include "pm3dev.h" +void UsbCommandReceived(UsbCommand *UC); + void ShowGraphWindow(void) { printf("pm3jni: ShowGraphWindow called (stub)"); } void HideGraphWindow(void) { printf("pm3jni: HideGraphWindow called (stub)"); } void RepaintGraphWindow(void) { printf("pm3jni: RepaintGraphWindow called (stub)"); } @@ -63,3 +67,11 @@ const char *get_my_executable_directory(void) { printf("pm3jni: get_my_executable_directory called (stub)"); return "."; } + +size_t pm3glue_usbcmd_size(void) { + return sizeof(UsbCommand); +} + +void pm3glue_recv_cmd(void *cmd) { + UsbCommandReceived(cmd); +} diff --git a/app/src/main/c/glue.h b/app/src/main/c/glue.h new file mode 100644 index 0000000..2b09850 --- /dev/null +++ b/app/src/main/c/glue.h @@ -0,0 +1,7 @@ +#include + +#ifndef PROXMARK3_GLUE_H +#define PROXMARK3_GLUE_H +size_t pm3glue_usbcmd_size(void); +void pm3glue_recv_cmd(void *); +#endif // PROXMARK3_GLUE_H diff --git a/app/src/main/c/pm3dev.c b/app/src/main/c/pm3dev.c index 4fe7b55..a9a3489 100644 --- a/app/src/main/c/pm3dev.c +++ b/app/src/main/c/pm3dev.c @@ -1,74 +1,69 @@ +#include "pm3dev.h" + #include #include #include #include -#include "pm3dev.h" #include "pm3uart.h" #include "pm3util.h" #include "pm3relayd.h" +#include "glue.h" enum { DEVTYPE_INVALID, DEVTYPE_DIRECT, DEVTYPE_RELAYED, DEVTYPE_TEST } pm3dev_type = DEVTYPE_INVALID; int pm3dev_fd = -1; int pm3dev_relayd_outfd = -1; -int pm3dev_relayd_infd = -1; +int pm3dev_relayd_child_stdoutfd = -1; pid_t pm3dev_relayd_pid = -1; char *pm3dev_relayd_path = NULL; int *pm3dev_thread_quit = NULL; int pm3dev_relay_run(const char *devpath) { if (!pm3dev_relayd_path) { - fprintf(stderr, "pm3dev: relayd_path unset\n"); + fprintf(stderr, "pm3dev_relay_run: relayd_path unset\n"); return -1; } - int outp[2], inp[2]; - if (pipe(outp) == -1) { - perror("pm3dev: pipe(outp)"); + if (pm3dev_relayd_child_stdoutfd == -1) { + fprintf(stderr, "pm3dev_relay_run: relayd_child_stdoutfd unset\n"); return -1; } - if (pipe(inp) == -1) { - perror("pm3dev: pipe(inp)"); - close(outp[0]); - close(outp[1]); + + int outp[2]; + if (pipe(outp) == -1) { + perror("pm3dev_relay_run: pipe(outp)"); return -1; } char sharg[1024] = {0}; if (snprintf(sharg, sizeof(sharg), "exec %s %s", pm3dev_relayd_path, devpath) > sizeof(sharg)) { - fprintf(stderr, "pm3dev: pm3dev_relay_run: snprintf buffer too small\n"); + fprintf(stderr, "pm3dev_relay_run: pm3dev_relay_run: snprintf buffer too small\n"); close(outp[0]); close(outp[1]); - close(inp[0]); - close(inp[1]); return -1; } const char *const argv[] = {"su", "root", "sh", "-c", sharg, 0}; - fprintf(stderr, "pm3dev: pm3dev_relay_run: %s\n", sharg); + fprintf(stderr, "pm3dev_relay_run: pm3dev_relay_run: %s\n", sharg); pid_t pid = fork(); if (pid == 0) { if (dup2(outp[0], STDIN_FILENO) != STDIN_FILENO || - dup2(inp[1], STDOUT_FILENO) != STDOUT_FILENO) { - perror("pm3dev: pm3dev_relay_run: dup2"); + dup2(pm3dev_relayd_child_stdoutfd, STDOUT_FILENO) != STDOUT_FILENO) { + perror("pm3dev_relay_run: pm3dev_relay_run: dup2"); _exit(-1); } execvp("su", (char *const *) argv); _exit(-1); } else if (pid > 0) { close(outp[0]); - close(inp[1]); pm3dev_relayd_pid = pid; pm3dev_relayd_outfd = outp[1]; - pm3dev_relayd_infd = inp[0]; pm3dev_type = DEVTYPE_RELAYED; } else { - perror("pm3dev: vfork"); + perror("pm3dev_relay_run: vfork"); close(outp[0]); close(outp[1]); - close(inp[0]); - close(inp[1]); return -1; } @@ -78,27 +73,50 @@ int pm3dev_relay_run(const char *devpath) { void pm3dev_relay_shutdown(void) { enum pm3relayd_cmd cmd = RELAYDCMD_EXIT; if (pm3util_write(pm3dev_relayd_outfd, &cmd, sizeof(cmd)) == -1) { - perror("pm3dev: write(outfd) for RELAYDCMD_EXIT"); + perror("pm3dev_relay_shutdown: write(outfd) for RELAYDCMD_EXIT"); } } int pm3dev_relay_send(const uint8_t *bytes, const size_t size) { enum pm3relayd_cmd cmd = RELAYDCMD_SEND; if (pm3util_write(pm3dev_relayd_outfd, &cmd, sizeof(cmd)) == -1) { - perror("pm3dev: write(outfd) for RELAYDCMD_SEND"); + perror("pm3dev_relay_send: write(outfd) for RELAYDCMD_SEND"); return -1; } if (pm3util_write(pm3dev_relayd_outfd, &size, sizeof(size)) == -1) { - perror("pm3dev: write(outfd) for RELAYDCMD_SEND size"); + perror("pm3dev_relay_send: write(outfd) for RELAYDCMD_SEND size"); return -1; } if (pm3util_write(pm3dev_relayd_outfd, bytes, size) == -1) { - perror("pm3dev: write(outfd) for RELAYDCMD_SEND data"); + perror("pm3dev_relay_send: write(outfd) for RELAYDCMD_SEND data"); return -1; } return 0; } +int pm3dev_relay_thread(void) { + size_t cmdsize = pm3glue_usbcmd_size(); + void *buf = malloc(cmdsize); + if (!buf) { + perror("pm3dev_relay_thread: malloc"); + } + + int inp[2]; + if (pipe(inp) == -1) { + perror("pm3dev_relay_thread: pipe(inp)"); + return -1; + } + pm3dev_relayd_child_stdoutfd = inp[1]; + + while (1) { + if (pm3util_read(inp[0], buf, cmdsize) == -1) { + perror("pm3dev_relay_thread: read"); + return -1; + } + pm3glue_recv_cmd(buf); + } +} + int pm3dev_change(const char *newpath) { switch (pm3dev_type) { case DEVTYPE_DIRECT: @@ -116,14 +134,21 @@ int pm3dev_change(const char *newpath) { } if (*newpath) { + /* TODO: implement direct reading (need to spawn a thread to read from ttyACM + * TODO: and call UsbCommandReceived) + */ +#if 0 int newfd = pm3uart_open(newpath); if (newfd == -1) { - return pm3dev_relay_run(newpath); +#endif + return pm3dev_relay_run(newpath); +#if 0 } else { pm3dev_fd = newfd; pm3dev_type = DEVTYPE_DIRECT; return 0; } +#endif } else { pm3dev_type = DEVTYPE_TEST; return 0; diff --git a/app/src/main/c/pm3dev.h b/app/src/main/c/pm3dev.h index f9826c4..da036ac 100644 --- a/app/src/main/c/pm3dev.h +++ b/app/src/main/c/pm3dev.h @@ -4,7 +4,9 @@ #ifndef PROXMARK3_PM3DEV_H #define PROXMARK3_PM3DEV_H extern char *pm3dev_relayd_path; +extern int pm3dev_relayd_child_stdoutfd; int pm3dev_change(const char *); int pm3dev_write(const uint8_t *, size_t); +int pm3dev_relay_thread(void); #endif // PROXMARK3_PM3DEV_H diff --git a/app/src/main/c/pm3jni.c b/app/src/main/c/pm3jni.c index d9b9b3d..85ed857 100644 --- a/app/src/main/c/pm3jni.c +++ b/app/src/main/c/pm3jni.c @@ -86,3 +86,9 @@ JNIEXPORT void JNICALL Java_angelsl_androidapp_proxmark3_interop_Proxmark3_jniSe pm3dev_relayd_path = pathcopy; (*env)->ReleaseStringUTFChars(env, path_, path); } + +JNIEXPORT void JNICALL Java_angelsl_androidapp_proxmark3_interop_Proxmark3_jniUsbInWorker(JNIEnv *env, jclass type) { + if (pm3dev_relay_thread() == -1) { + jni_throw(env, "Relay thread quit"); + } +} diff --git a/app/src/main/java/angelsl/androidapp/proxmark3/interop/Proxmark3.java b/app/src/main/java/angelsl/androidapp/proxmark3/interop/Proxmark3.java index 6d0ba9f..ff62b2c 100644 --- a/app/src/main/java/angelsl/androidapp/proxmark3/interop/Proxmark3.java +++ b/app/src/main/java/angelsl/androidapp/proxmark3/interop/Proxmark3.java @@ -22,6 +22,12 @@ public void run() { jniStdoutWorker(); } }).start(); + new Thread(new Runnable() { + @Override + public void run() { + jniUsbInWorker(); + } + }).start(); } public static void init(Context c) { @@ -65,6 +71,7 @@ private static void dispatchOutput(String n) { } private static native void jniStdoutWorker(); + private static native void jniUsbInWorker(); private static native int jniExecCommand(String command); private static native void jniChangeDevice(String path); private static native void jniSetRelaydPath(String path);