From e44091904437b2eae5b75ed0661bb3981b1ceb75 Mon Sep 17 00:00:00 2001 From: dxl <64101226@qq.com> Date: Fri, 17 Apr 2020 13:21:01 +0800 Subject: [PATCH] libnfc communication recovery. --- .../cn/rrg/rdv/activities/main/AppMain.java | 2 - .../cn/dxl/com/LocalComBridgeAdapter.java | 6 - .../java/cn/rrg/com/AbsUsbBulkTransfer.java | 10 +- .../src/main/cpp/libnfc/CMakeLists.txt | 2 + libnfc_pn53x/src/main/cpp/libnfc/buses/com.h | 20 +- .../src/main/cpp/libnfc/buses/com_uart.c | 39 ++ .../src/main/cpp/libnfc/buses/uart_posix.c | 579 ++++++++++++++++++ .../src/main/cpp/libnfc/drivers/acr122_usb.c | 17 +- .../src/main/cpp/libnfc/drivers/pn532_uart.c | 14 +- .../src/main/cpp/libnfc/drivers/pn53x_usb.c | 17 +- .../src/main/cpp/libnfc/include/uart.h | 95 +++ pm3flasher/src/main/cpp/client/uart/com.h | 29 - pm3rdv4rrg/src/main/cpp/proxmark3 | 2 +- 13 files changed, 746 insertions(+), 86 deletions(-) create mode 100644 libnfc_pn53x/src/main/cpp/libnfc/buses/com_uart.c create mode 100644 libnfc_pn53x/src/main/cpp/libnfc/buses/uart_posix.c create mode 100644 libnfc_pn53x/src/main/cpp/libnfc/include/uart.h delete mode 100644 pm3flasher/src/main/cpp/client/uart/com.h diff --git a/app_main/src/main/java/cn/rrg/rdv/activities/main/AppMain.java b/app_main/src/main/java/cn/rrg/rdv/activities/main/AppMain.java index bf10f3b7..7b9e42b9 100644 --- a/app_main/src/main/java/cn/rrg/rdv/activities/main/AppMain.java +++ b/app_main/src/main/java/cn/rrg/rdv/activities/main/AppMain.java @@ -44,8 +44,6 @@ public class AppMain extends BaseActivity { initActions(); gotoFragment(appMainDevicesFragment); - - startActivity(new Intent(this, PM3FlasherMainActivity.class)); } private void initViews() { diff --git a/communication/src/main/java/cn/dxl/com/LocalComBridgeAdapter.java b/communication/src/main/java/cn/dxl/com/LocalComBridgeAdapter.java index ab2a0091..d9d9ced6 100644 --- a/communication/src/main/java/cn/dxl/com/LocalComBridgeAdapter.java +++ b/communication/src/main/java/cn/dxl/com/LocalComBridgeAdapter.java @@ -71,12 +71,6 @@ public final class LocalComBridgeAdapter implements Serializable { if (serverSocket != null) { Log.d(LOG_TAG, "服务套接字堵塞等待连接中!"); socket = serverSocket.accept(); - if (isHasClient) { - isHasClient = false; - Log.e(LOG_TAG, "The server only once online supported."); - Log.e(LOG_TAG, "please disconnect your previous con."); - continue; - } if (socket != null) { synchronized (LOCK) { isHasClient = true; diff --git a/communication/src/main/java/cn/rrg/com/AbsUsbBulkTransfer.java b/communication/src/main/java/cn/rrg/com/AbsUsbBulkTransfer.java index 90cdfd16..a9687e48 100644 --- a/communication/src/main/java/cn/rrg/com/AbsUsbBulkTransfer.java +++ b/communication/src/main/java/cn/rrg/com/AbsUsbBulkTransfer.java @@ -48,6 +48,10 @@ public abstract class AbsUsbBulkTransfer implements DriverInterface #include #include +#include #include -// can't use, he always is null! -typedef void *serial_port; +bool c_open(); -jint initBuffer(JNIEnv *env, jclass type, jobject send_buffer, jobject recv_buffer); +void c_close(); -jint syncLength(JNIEnv *env, jclass type); +int c_read(uint8_t *pbtRx, size_t szRx, int timeout); -jint syncTimeout(JNIEnv *env, jclass type); - -int c_open(); - -int c_close(); - -int c_flush(); - -int c_read(uint8_t *pbtRx, const size_t szRx, int timeout); - -int c_write(const uint8_t *pbtTx, const size_t szTx, int timeout); +int c_write(const uint8_t *pbtTx, size_t szTx, int timeout); #endif // __NFC_BUS_UART_H__ diff --git a/libnfc_pn53x/src/main/cpp/libnfc/buses/com_uart.c b/libnfc_pn53x/src/main/cpp/libnfc/buses/com_uart.c new file mode 100644 index 00000000..99a9ba83 --- /dev/null +++ b/libnfc_pn53x/src/main/cpp/libnfc/buses/com_uart.c @@ -0,0 +1,39 @@ +#include +#include +#include +#include "com.h" + +// Serial port that we are communicating with the PM3 on. +static serial_port sp = INVALID_SERIAL_PORT; + +bool c_open() { + sp = uart_open("socket:DXL.COM.ASL", 115200); + return sp != INVALID_SERIAL_PORT; +} + +void c_close() { + if (sp != INVALID_SERIAL_PORT) { + uart_close(sp); + } +} + +int c_read(uint8_t *pbtRx, size_t szRx, int timeout) { + if (sp != INVALID_SERIAL_PORT) { + uart_reconfigure_timeouts(88); + size_t recvLen = 0; + size_t *pRecvLen = &recvLen; + if (uart_receive(sp, pbtRx, szRx, pRecvLen) == NFC_SUCCESS) { + return recvLen; + } + return -1; + } + return -1; +} + +int c_write(const uint8_t *pbtTx, size_t szTx, int timeout) { + if (sp != INVALID_SERIAL_PORT) { + uart_reconfigure_timeouts((uint32_t) timeout); + return uart_send(sp, pbtTx, szTx); + } + return -1; +} \ No newline at end of file diff --git a/libnfc_pn53x/src/main/cpp/libnfc/buses/uart_posix.c b/libnfc_pn53x/src/main/cpp/libnfc/buses/uart_posix.c new file mode 100644 index 00000000..8edb11c0 --- /dev/null +++ b/libnfc_pn53x/src/main/cpp/libnfc/buses/uart_posix.c @@ -0,0 +1,579 @@ +/* + * Generic uart / rs232/ serial port library + * + * Copyright (c) 2013, Roel Verdult + * Copyright (c) 2018 Google + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holders nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * @file uart_posix.c + * + * This version of the library has functionality removed which was not used by + * proxmark3 project. + */ + +// Test if we are dealing with posix operating systems +#ifndef _WIN32 +#define _DEFAULT_SOURCE + +#include "uart.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "sys/socket.h" +#include "sys/un.h" + +// Taken from https://github.com/unbit/uwsgi/commit/b608eb1772641d525bfde268fe9d6d8d0d5efde7 +#ifndef SOL_TCP +# define SOL_TCP IPPROTO_TCP +#endif + +typedef struct termios term_info; +typedef struct { + int fd; // Serial port file descriptor + term_info tiOld; // Terminal info before using the port + term_info tiNew; // Terminal info during the transaction +} serial_port_unix; + +#define UART_FPC_CLIENT_RX_TIMEOUT_MS 200 +#define UART_TCP_CLIENT_RX_TIMEOUT_MS 500 + +// see pm3_cmd.h +struct timeval timeout = { + .tv_sec = 0, // 0 second + .tv_usec = UART_FPC_CLIENT_RX_TIMEOUT_MS * 1000 +}; + +uint32_t newtimeout_value = 0; +bool newtimeout_pending = false; + +int uart_reconfigure_timeouts(uint32_t value) { + newtimeout_value = value; + newtimeout_pending = true; + return NFC_SUCCESS; +} + +serial_port uart_open(const char *pcPortName, uint32_t speed) { + serial_port_unix *sp = calloc(sizeof(serial_port_unix), sizeof(uint8_t)); + if (sp == 0) return INVALID_SERIAL_PORT; + + // init timeouts + timeout.tv_usec = UART_FPC_CLIENT_RX_TIMEOUT_MS * 1000; + + if (memcmp(pcPortName, "tcp:", 4) == 0) { + struct addrinfo *addr = NULL, *rp; + char *addrstr = strdup(pcPortName + 4); + + if (addrstr == NULL) { + printf("Error: strdup\n"); + free(sp); + return INVALID_SERIAL_PORT; + } + + timeout.tv_usec = UART_TCP_CLIENT_RX_TIMEOUT_MS * 1000; + + char *colon = strrchr(addrstr, ':'); + const char *portstr; + if (colon) { + portstr = colon + 1; + *colon = '\0'; + } else { + portstr = "7901"; + } + + struct addrinfo info; + + memset(&info, 0, sizeof(info)); + + info.ai_socktype = SOCK_STREAM; + + int s = getaddrinfo(addrstr, portstr, &info, &addr); + if (s != 0) { + printf("Error: getaddrinfo: %s\n", gai_strerror(s)); + freeaddrinfo(addr); + free(addrstr); + free(sp); + return INVALID_SERIAL_PORT; + } + + int sfd; + for (rp = addr; rp != NULL; rp = rp->ai_next) { + sfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); + + if (sfd == -1) + continue; + + if (connect(sfd, rp->ai_addr, rp->ai_addrlen) != -1) + break; + + close(sfd); + } + + if (rp == NULL) { /* No address succeeded */ + printf("Error: Could not connect\n"); + freeaddrinfo(addr); + free(addrstr); + free(sp); + return INVALID_SERIAL_PORT; + } + + freeaddrinfo(addr); + free(addrstr); + + sp->fd = sfd; + + int one = 1; + int res = setsockopt(sp->fd, SOL_TCP, TCP_NODELAY, &one, sizeof(one)); + if (res != 0) { + free(sp); + return INVALID_SERIAL_PORT; + } + return sp; + } + + // The socket for abstract namespace implement. + // Is local socket buffer, not a TCP or any net connection! + // so, you can't connect with address like: 127.0.0.1, or any IP + // see http://man7.org/linux/man-pages/man7/unix.7.html + if (memcmp(pcPortName, "socket:", 7) == 0) { + if (strlen(pcPortName) <= 7) { + free(sp); + return INVALID_SERIAL_PORT; + } + + // we must use max timeout! + timeout.tv_usec = UART_TCP_CLIENT_RX_TIMEOUT_MS * 1000; + + size_t servernameLen = (strlen(pcPortName) - 7) + 1; + char serverNameBuf[servernameLen]; + memset(serverNameBuf, '\0', servernameLen); + for (int i = 7, j = 0; j < servernameLen; ++i, ++j) { + serverNameBuf[j] = pcPortName[i]; + } + serverNameBuf[servernameLen - 1] = '\0'; + + int localsocket, len; + struct sockaddr_un remote; + + remote.sun_path[0] = '\0'; // abstract namespace + strcpy(remote.sun_path + 1, serverNameBuf); + remote.sun_family = AF_LOCAL; + int nameLen = strlen(serverNameBuf); + len = 1 + nameLen + offsetof(struct sockaddr_un, sun_path); + + if ((localsocket = socket(PF_LOCAL, SOCK_STREAM, 0)) == -1) { + free(sp); + return INVALID_SERIAL_PORT; + } + + if (connect(localsocket, (struct sockaddr *) &remote, len) == -1) { + free(sp); + LOGD("连接套接字失败,请检查连接服务是否已经被停止!"); + return INVALID_SERIAL_PORT; + } + + sp->fd = localsocket; + + return sp; + } + + sp->fd = open(pcPortName, O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK); + if (sp->fd == -1) { + uart_close(sp); + return INVALID_SERIAL_PORT; + } + + // Finally figured out a way to claim a serial port interface under unix + // We just try to set a (advisory) lock on the file descriptor + struct flock fl; + fl.l_type = F_WRLCK; + fl.l_whence = SEEK_SET; + fl.l_start = 0; + fl.l_len = 0; + fl.l_pid = getpid(); + + // Does the system allows us to place a lock on this file descriptor + if (fcntl(sp->fd, F_SETLK, &fl) == -1) { + // A conflicting lock is held by another process + free(sp); + return CLAIMED_SERIAL_PORT; + } + + // Try to retrieve the old (current) terminal info struct + if (tcgetattr(sp->fd, &sp->tiOld) == -1) { + uart_close(sp); + return INVALID_SERIAL_PORT; + } + + // Duplicate the (old) terminal info struct + sp->tiNew = sp->tiOld; + + // Configure the serial port + sp->tiNew.c_cflag = CS8 | CLOCAL | CREAD; + sp->tiNew.c_iflag = IGNPAR; + sp->tiNew.c_oflag = 0; + sp->tiNew.c_lflag = 0; + + // Block until n bytes are received + sp->tiNew.c_cc[VMIN] = 0; + // Block until a timer expires (n * 100 mSec.) + sp->tiNew.c_cc[VTIME] = 0; + + // Try to set the new terminal info struct + if (tcsetattr(sp->fd, TCSANOW, &sp->tiNew) == -1) { + uart_close(sp); + return INVALID_SERIAL_PORT; + } + + // Flush all lingering data that may exist + tcflush(sp->fd, TCIOFLUSH); + + if (!uart_set_speed(sp, speed)) { + // try fallback automatically + speed = 115200; + if (!uart_set_speed(sp, speed)) { + uart_close(sp); + printf("[!] UART error while setting baudrate\n"); + return INVALID_SERIAL_PORT; + } + } + return sp; +} + +void uart_close(const serial_port sp) { + serial_port_unix *spu = (serial_port_unix *) sp; + tcflush(spu->fd, TCIOFLUSH); + tcsetattr(spu->fd, TCSANOW, &(spu->tiOld)); + struct flock fl; + fl.l_type = F_UNLCK; + fl.l_whence = SEEK_SET; + fl.l_start = 0; + fl.l_len = 0; + fl.l_pid = getpid(); + + // Does the system allows us to place a lock on this file descriptor + int err = fcntl(spu->fd, F_SETLK, &fl); + if (err == -1) { + //silent error message as it can be called from uart_open failing modes, e.g. when waiting for port to appear + //printf("[!] UART error while closing port\n"); + } + close(spu->fd); + free(sp); +} + +int uart_receive(const serial_port sp, uint8_t *pbtRx, uint32_t pszMaxRxLen, uint32_t *pszRxLen) { + uint32_t byteCount; // FIONREAD returns size on 32b + fd_set rfds; + struct timeval tv; + + if (newtimeout_pending) { + timeout.tv_usec = newtimeout_value * 1000; + newtimeout_pending = false; + } + // Reset the output count + *pszRxLen = 0; + do { + // Reset file descriptor + FD_ZERO(&rfds); + FD_SET(((serial_port_unix *) sp)->fd, &rfds); + tv = timeout; + int res = select(((serial_port_unix *) sp)->fd + 1, &rfds, NULL, NULL, &tv); + + // Read error + if (res < 0) { + LOGD("Read error"); + return NFC_EIO; + } + + // Read time-out + if (res == 0) { + if (*pszRxLen == 0) { + // We received no data + // LOGD("We received no data"); + return NFC_ETIMEOUT; + } else { + // We received some data, but nothing more is available + // LOGD("We received some data, but nothing more is available"); + return NFC_SUCCESS; + } + } + + // Retrieve the count of the incoming bytes + res = ioctl(((serial_port_unix *) sp)->fd, FIONREAD, &byteCount); +// printf("UART:: RX ioctl res %d byteCount %u\n", res, byteCount); + if (res < 0) return NFC_EIO; + + // Cap the number of bytes, so we don't overrun the buffer + if (pszMaxRxLen - (*pszRxLen) < byteCount) { +// printf("UART:: RX prevent overrun (have %u, need %u)\n", pszMaxRxLen - (*pszRxLen), byteCount); + byteCount = pszMaxRxLen - (*pszRxLen); + } + + // There is something available, read the data + res = read(((serial_port_unix *) sp)->fd, pbtRx + (*pszRxLen), byteCount); + + // Stop if the OS has some troubles reading the data + if (res <= 0) { + return NFC_EIO; + } + + *pszRxLen += res; + + if (*pszRxLen == pszMaxRxLen) { + // We have all the data we wanted. + return NFC_SUCCESS; + } + } while (byteCount); + + return NFC_SUCCESS; +} + +int uart_send(const serial_port sp, const uint8_t *pbtTx, const uint32_t len) { + uint32_t pos = 0; + fd_set rfds; + struct timeval tv; + + while (pos < len) { + // Reset file descriptor + FD_ZERO(&rfds); + FD_SET(((serial_port_unix *) sp)->fd, &rfds); + tv = timeout; + int res = select(((serial_port_unix *) sp)->fd + 1, NULL, &rfds, NULL, &tv); + + // Write error + if (res < 0) { + printf("UART:: write error (%d)\n", res); + return NFC_EIO; + } + + // Write time-out + if (res == 0) { + printf("UART:: write time-out\n"); + return NFC_ETIMEOUT; + } + + // Send away the bytes + res = write(((serial_port_unix *) sp)->fd, pbtTx + pos, len - pos); + + // Stop if the OS has some troubles sending the data + if (res <= 0) + return NFC_EIO; + + pos += res; + } + return NFC_SUCCESS; +} + +bool uart_set_speed(serial_port sp, const uint32_t uiPortSpeed) { + const serial_port_unix *spu = (serial_port_unix *) sp; + speed_t stPortSpeed; + switch (uiPortSpeed) { + case 0: + stPortSpeed = B0; + break; + case 50: + stPortSpeed = B50; + break; + case 75: + stPortSpeed = B75; + break; + case 110: + stPortSpeed = B110; + break; + case 134: + stPortSpeed = B134; + break; + case 150: + stPortSpeed = B150; + break; + case 300: + stPortSpeed = B300; + break; + case 600: + stPortSpeed = B600; + break; + case 1200: + stPortSpeed = B1200; + break; + case 1800: + stPortSpeed = B1800; + break; + case 2400: + stPortSpeed = B2400; + break; + case 4800: + stPortSpeed = B4800; + break; + case 9600: + stPortSpeed = B9600; + break; + case 19200: + stPortSpeed = B19200; + break; + case 38400: + stPortSpeed = B38400; + break; +# ifdef B57600 + case 57600: + stPortSpeed = B57600; + break; +# endif +# ifdef B115200 + case 115200: + stPortSpeed = B115200; + break; +# endif +# ifdef B230400 + case 230400: + stPortSpeed = B230400; + break; +# endif +# ifdef B460800 + case 460800: + stPortSpeed = B460800; + break; +# endif +# ifdef B921600 + case 921600: + stPortSpeed = B921600; + break; +# endif +# ifdef B1382400 + case 1382400: + stPortSpeed = B1382400; + break; +# endif + + default: + return false; + }; + + struct termios ti; + if (tcgetattr(spu->fd, &ti) == -1) + return false; + + // Set port speed (Input and Output) + cfsetispeed(&ti, stPortSpeed); + cfsetospeed(&ti, stPortSpeed); + bool result = tcsetattr(spu->fd, TCSANOW, &ti) != -1; + return result; +} + +uint32_t uart_get_speed(const serial_port sp) { + struct termios ti; + uint32_t uiPortSpeed; + const serial_port_unix *spu = (serial_port_unix *) sp; + + if (tcgetattr(spu->fd, &ti) == -1) + return 0; + + // Set port speed (Input) + speed_t stPortSpeed = cfgetispeed(&ti); + switch (stPortSpeed) { + case B0: + uiPortSpeed = 0; + break; + case B50: + uiPortSpeed = 50; + break; + case B75: + uiPortSpeed = 75; + break; + case B110: + uiPortSpeed = 110; + break; + case B134: + uiPortSpeed = 134; + break; + case B150: + uiPortSpeed = 150; + break; + case B300: + uiPortSpeed = 300; + break; + case B600: + uiPortSpeed = 600; + break; + case B1200: + uiPortSpeed = 1200; + break; + case B1800: + uiPortSpeed = 1800; + break; + case B2400: + uiPortSpeed = 2400; + break; + case B4800: + uiPortSpeed = 4800; + break; + case B9600: + uiPortSpeed = 9600; + break; + case B19200: + uiPortSpeed = 19200; + break; + case B38400: + uiPortSpeed = 38400; + break; +# ifdef B57600 + case B57600: + uiPortSpeed = 57600; + break; +# endif +# ifdef B115200 + case B115200: + uiPortSpeed = 115200; + break; +# endif +# ifdef B230400 + case B230400: + uiPortSpeed = 230400; + break; +# endif +# ifdef B460800 + case B460800: + uiPortSpeed = 460800; + break; +# endif +# ifdef B921600 + case B921600: + uiPortSpeed = 921600; + break; +# endif + default: + return 0; + }; + return uiPortSpeed; +} + +#endif diff --git a/libnfc_pn53x/src/main/cpp/libnfc/drivers/acr122_usb.c b/libnfc_pn53x/src/main/cpp/libnfc/drivers/acr122_usb.c index 349bef57..b29a8f60 100644 --- a/libnfc_pn53x/src/main/cpp/libnfc/drivers/acr122_usb.c +++ b/libnfc_pn53x/src/main/cpp/libnfc/drivers/acr122_usb.c @@ -64,7 +64,6 @@ Thanks to d18c7db and Okko for example code #include #include -#include #include #include "nfc-internal.h" @@ -400,6 +399,11 @@ static nfc_device * acr122_usb_open(const nfc_context *context, const nfc_connstring connstring) { nfc_device *pnd = NULL; + if (!c_open()) { + // 串口打开失败! + return NULL; + } + /* * TODO 自实现区域 * */ @@ -455,17 +459,6 @@ acr122_usb_close(nfc_device *pnd) { acr122_usb_ack(pnd); pn53x_idle(pnd); c_close(); - //TODO 不需要底层关闭 - /*int res; - if ((res = usb_release_interface(DRIVER_DATA(pnd)->pudh, 0)) < 0) { - log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, - "Unable to release USB interface (%s)", _usb_strerror(res)); - } - - if ((res = usb_close(DRIVER_DATA(pnd)->pudh)) < 0) { - log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, - "Unable to close USB connection (%s)", _usb_strerror(res)); - }*/ pn53x_data_free(pnd); nfc_device_free(pnd); } diff --git a/libnfc_pn53x/src/main/cpp/libnfc/drivers/pn532_uart.c b/libnfc_pn53x/src/main/cpp/libnfc/drivers/pn532_uart.c index 9405f079..d69e25a4 100644 --- a/libnfc_pn53x/src/main/cpp/libnfc/drivers/pn532_uart.c +++ b/libnfc_pn53x/src/main/cpp/libnfc/drivers/pn532_uart.c @@ -43,6 +43,7 @@ #include #include +#include #include "nfc-internal.h" #include "com.h" @@ -77,8 +78,6 @@ pn532_uart_scan(const nfc_context *context, nfc_connstring connstrings[], size_t device_found = 0; //打开设备 if (!c_open()) { return 0; } - //刷新可能残留的字节 - c_flush(); nfc_connstring connstring; snprintf(connstring, sizeof(nfc_connstring), "%s:%s:%"PRIu32, PN532_UART_DRIVER_NAME, "115200", PN532_UART_DEFAULT_SPEED); @@ -148,9 +147,12 @@ pn532_uart_close(nfc_device *pnd) { static nfc_device * pn532_uart_open(const nfc_context *context, const nfc_connstring connstring) { nfc_device *pnd = NULL; - //不需要参数 - c_open(); - c_flush(); + + if (!c_open()) { + // 串口打开失败! + return NULL; + } + // We have a connection pnd = nfc_device_new(context, connstring); if (!pnd) { @@ -215,7 +217,6 @@ pn532_uart_wakeup(nfc_device *pnd) { static int pn532_uart_send(nfc_device *pnd, const uint8_t *pbtData, const size_t szData, int timeout) { int res = 0; - c_flush(); switch (CHIP_DATA(pnd)->power_mode) { case LOWVBAT: { /** PN532C106 wakeup. */ @@ -398,7 +399,6 @@ pn532_uart_receive(nfc_device *pnd, uint8_t *pbtData, const size_t szDataLen, in // The PN53x command is done and we successfully received the reply return len; error: - c_flush(); return pnd->last_error; } diff --git a/libnfc_pn53x/src/main/cpp/libnfc/drivers/pn53x_usb.c b/libnfc_pn53x/src/main/cpp/libnfc/drivers/pn53x_usb.c index 8c8d6374..099a929d 100644 --- a/libnfc_pn53x/src/main/cpp/libnfc/drivers/pn53x_usb.c +++ b/libnfc_pn53x/src/main/cpp/libnfc/drivers/pn53x_usb.c @@ -62,18 +62,6 @@ Thanks to d18c7db and Okko for example code #define DRIVER_DATA(pnd) ((struct pn53x_usb_data*)(pnd->driver_data)) -// 暂时处理 - -int c_open(){} - -int c_close(){} - -int c_flush(){} - -int c_read(uint8_t *pbtRx, const size_t szRx, int timeout){} - -int c_write(const uint8_t *pbtTx, const size_t szTx, int timeout){} - const nfc_modulation_type no_target_support[] = {0}; typedef enum { @@ -243,6 +231,11 @@ static nfc_device * pn53x_usb_open(const nfc_context *context, const nfc_connstring connstring) { nfc_device *pnd = NULL; + if (!c_open()) { + // 串口打开失败! + return NULL; + } + // Allocate memory for the device info and specification, fill it and return the info pnd = nfc_device_new(context, connstring); if (!pnd) { diff --git a/libnfc_pn53x/src/main/cpp/libnfc/include/uart.h b/libnfc_pn53x/src/main/cpp/libnfc/include/uart.h new file mode 100644 index 00000000..d94d874b --- /dev/null +++ b/libnfc_pn53x/src/main/cpp/libnfc/include/uart.h @@ -0,0 +1,95 @@ +/* + * Generic uart / rs232/ serial port library + * + * Copyright (c) 2013, Roel Verdult + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holders nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * @file uart.h + */ + +#ifndef _UART_H_ +#define _UART_H_ + +#include +#include + +/* serial_port is declared as a void*, which you should cast to whatever type + * makes sense to your connection method. Both the posix and win32 + * implementations define their own structs in place. + */ +typedef void *serial_port; + +/* Returned by uart_open if the serial port specified was invalid. + */ +#define INVALID_SERIAL_PORT (void*)(~1) + +/* Returned by uart_open if the serial port specified is in use by another + * process. + */ +#define CLAIMED_SERIAL_PORT (void*)(~2) + +/* Given a user-specified port name, connect to the port and return a structure + * used for future references to that port. + * + * On errors, this method returns INVALID_SERIAL_PORT or CLAIMED_SERIAL_PORT. + */ +serial_port uart_open(const char *pcPortName, uint32_t speed); + +/* Closes the given port. + */ +void uart_close(const serial_port sp); + +/* Reads from the given serial port for up to 30ms. + * pbtRx: A pointer to a buffer for the returned data to be written to. + * pszMaxRxLen: The maximum data size we want to be sent. + * pszRxLen: The number of bytes that we were actually sent. + * + * Returns TRUE if any data was fetched, even if it was less than pszMaxRxLen. + * + * Returns FALSE if there was an error reading from the devices. Note that a + * partial read may have completed into the buffer by the corresponding + * implementation, so pszRxLen should be checked to see if any data was written. + */ +int uart_receive(const serial_port sp, uint8_t *pbtRx, uint32_t pszMaxRxLen, uint32_t *pszRxLen); + +/* Sends a buffer to a given serial port. + * pbtTx: A pointer to a buffer containing the data to write. + * len: The amount of data to be sent. + */ +int uart_send(const serial_port sp, const uint8_t *pbtTx, const uint32_t len); + +/* Sets the current speed of the serial port, in baud. + */ +bool uart_set_speed(serial_port sp, const uint32_t uiPortSpeed); + +/* Gets the current speed of the serial port, in baud. + */ +uint32_t uart_get_speed(const serial_port sp); + +/* Reconfigure timeouts + */ +int uart_reconfigure_timeouts(uint32_t value); +#endif // _UART_H_ + diff --git a/pm3flasher/src/main/cpp/client/uart/com.h b/pm3flasher/src/main/cpp/client/uart/com.h deleted file mode 100644 index fd832776..00000000 --- a/pm3flasher/src/main/cpp/client/uart/com.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef __NFC_BUS_UART_H__ -# define __NFC_BUS_UART_H__ - -#include -#include -#include -#include -#include - -// can't use, he always is null! -typedef void *serial_port; - -jint initBuffer(JNIEnv *env, jclass type, jobject send_buffer, jobject recv_buffer); - -jint syncLength(JNIEnv *env, jclass type); - -jint syncTimeout(JNIEnv *env, jclass type); - -int c_open(); - -int c_close(); - -int c_flush(); - -int c_read(uint8_t *pbtRx, const size_t szRx, int timeout); - -int c_write(const uint8_t *pbtTx, const size_t szTx, int timeout); - -#endif // __NFC_BUS_UART_H__ diff --git a/pm3rdv4rrg/src/main/cpp/proxmark3 b/pm3rdv4rrg/src/main/cpp/proxmark3 index d3488448..d55a147c 160000 --- a/pm3rdv4rrg/src/main/cpp/proxmark3 +++ b/pm3rdv4rrg/src/main/cpp/proxmark3 @@ -1 +1 @@ -Subproject commit d3488448739720bd1c199c0c2b55179f479e75f3 +Subproject commit d55a147ca960d11c41eade0d99b24741105157e5