diff --git a/client/src/uart/ringbuffer.c b/client/src/uart/ringbuffer.c index 4a3b01f74..13ff133e8 100644 --- a/client/src/uart/ringbuffer.c +++ b/client/src/uart/ringbuffer.c @@ -100,3 +100,19 @@ void RingBuf_destroy(RingBuffer* buffer) { free(buffer->data); free(buffer); } + +inline int RingBuf_getContinousAvailableSize(RingBuffer* buffer) { + const int availableSize = RingBuf_getAvailableSize(buffer); + const int continousSize = (buffer->capacity) - (buffer->rear); + return (availableSize < continousSize) ? availableSize : continousSize; +} + +inline void RingBuf_postEnqueueBatch(RingBuffer* buffer, int count) { + // no check there + buffer->rear = (buffer->rear + count) % buffer->capacity; + buffer->size += count; +} + +inline uint8_t* RingBuf_getRearPtr(RingBuffer* buffer) { + return buffer->data + buffer->rear; +} diff --git a/client/src/uart/ringbuffer.h b/client/src/uart/ringbuffer.h index e78e284b4..35321c8d6 100644 --- a/client/src/uart/ringbuffer.h +++ b/client/src/uart/ringbuffer.h @@ -23,4 +23,9 @@ int RingBuf_getUsedSize(RingBuffer* buffer); int RingBuf_getAvailableSize(RingBuffer* buffer); void RingBuf_destroy(RingBuffer* buffer); +// for direct write +int RingBuf_getContinousAvailableSize(RingBuffer* buffer); +void RingBuf_postEnqueueBatch(RingBuffer* buffer, int count); +uint8_t* RingBuf_getRearPtr(RingBuffer* buffer); + #endif diff --git a/client/src/uart/uart_posix.c b/client/src/uart/uart_posix.c index 05a728ada..ff2a6cde3 100644 --- a/client/src/uart/uart_posix.c +++ b/client/src/uart/uart_posix.c @@ -242,7 +242,7 @@ serial_port uart_open(const char *pcPortName, uint32_t speed) { } sp->fd = sfd; - sp->udpBuffer = RingBuf_create(MAX(sizeof(PacketResponseNGRaw), sizeof(PacketResponseOLD)) * 20); + sp->udpBuffer = RingBuf_create(MAX(sizeof(PacketResponseNGRaw), sizeof(PacketResponseOLD)) * 30); return sp; } @@ -497,9 +497,22 @@ int uart_receive(const serial_port sp, uint8_t *pbtRx, uint32_t pszMaxRxLen, uin // For UDP connection, put the incoming data into the buffer and handle them in the next round if (spu->udpBuffer != NULL) { - uint8_t recvBuf[MAX(sizeof(PacketResponseNGRaw), sizeof(PacketResponseOLD)) * 20]; - res = read(spu->fd, recvBuf, RingBuf_getAvailableSize(spu->udpBuffer)); - RingBuf_enqueueBatch(spu->udpBuffer, recvBuf, res); + if (RingBuf_getContinousAvailableSize(spu->udpBuffer) >= byteCount) { + // write to the buffer directly + res = read(spu->fd, RingBuf_getRearPtr(spu->udpBuffer), RingBuf_getAvailableSize(spu->udpBuffer)); + if (res >= 0) { + RingBuf_postEnqueueBatch(spu->udpBuffer, res); + } + } else { + // use transit buffer + uint8_t transitBuf[MAX(sizeof(PacketResponseNGRaw), sizeof(PacketResponseOLD)) * 30]; + res = read(spu->fd, transitBuf, RingBuf_getAvailableSize(spu->udpBuffer)); + RingBuf_enqueueBatch(spu->udpBuffer, transitBuf, res); + } + // Stop if the OS has some troubles reading the data + if (res < 0) { + return PM3_EIO; + } continue; }