diff --git a/src/cha.c b/src/cha.c index aea2b03..bb33eda 100644 --- a/src/cha.c +++ b/src/cha.c @@ -21,6 +21,8 @@ #define ftdi_tcioflush(x) ftdi_usb_purge_buffers(x) #endif +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) + struct cha_loop_packet_callback_state { size_t count; ov_packet_decoder_callback user_callback; @@ -517,21 +519,27 @@ static void cha_loop_bus_frame_callback(void* data, uint16_t addr, uint8_t value static void LIBUSB_CALL cha_loop_transfer_callback(struct libusb_transfer* transfer) { struct cha_loop* loop = (struct cha_loop*)transfer->user_data; struct cha* cha = loop->cha; + struct ftdi_context* ftdi = &cha->ftdi; int ret = 0; + size_t offset = 0; switch (transfer->status) { case LIBUSB_TRANSFER_COMPLETED: { - if (loop->state == RUNNING && transfer->actual_length > 2) { - /* Skip FTDI header */ - if (frame_decoder_proc( - &loop->fd, - transfer->buffer + 2, - transfer->actual_length - 2) < 0) { - - loop->state = FATAL_ERROR; - cha->error_str = loop->fd.pd.error_str; - }; + while (loop->state == RUNNING && offset < transfer->actual_length) { + size_t packet_length = MIN(transfer->actual_length - offset, ftdi->max_packet_size); + if (packet_length > 2) { + /* Skip FTDI header */ + if (frame_decoder_proc( + &loop->fd, + transfer->buffer + offset + 2, + packet_length - 2) < 0) { + + loop->state = FATAL_ERROR; + cha->error_str = loop->fd.pd.error_str; + }; + } + offset += packet_length; } while (loop->state == RUNNING diff --git a/src/decoder.c b/src/decoder.c index c204eb2..bea9c2d 100644 --- a/src/decoder.c +++ b/src/decoder.c @@ -71,7 +71,7 @@ int packet_decoder_proc(struct packet_decoder* pd, uint8_t* buf, size_t size) { } } break; case NEED_PACKET_DATA: { - const size_t required_length = pd->packet->size - pd->buf_actual_length; + const size_t required_length = ov_packet_captured_size(pd->packet) - pd->buf_actual_length; const size_t copy = MIN(required_length, end - buf); memcpy(pd->packet->data + pd->buf_actual_length, buf, copy); diff --git a/test/decoder.c b/test/decoder.c index f2e1add..3385a48 100644 --- a/test/decoder.c +++ b/test/decoder.c @@ -5,7 +5,7 @@ union { struct ov_packet packet; - uint8_t data[1024]; + uint8_t data[sizeof(struct ov_packet) + OV_MAX_PACKET_SIZE]; } p; struct decoder_ops ops = { @@ -80,6 +80,19 @@ START_TEST (test_packet_decoder5) { } END_TEST +START_TEST (test_packet_decoder_truncated) { + char inp[5 + OV_MAX_PACKET_SIZE + 1] = { + 0xa0, OV_FLAGS_HF0_TRUNC, + (OV_MAX_PACKET_SIZE + 1) & 0xff, ((OV_MAX_PACKET_SIZE + 1) >> 8) & 0x1f, + }; + ck_assert_int_eq(packet_decoder_proc(&pd, inp, sizeof(inp)), sizeof(inp) - 1); + ck_assert_int_eq(pd.state, NEED_PACKET_MAGIC); + ck_assert_int_eq(p.packet.size, OV_MAX_PACKET_SIZE+1); + ck_assert_int_eq(ov_packet_captured_size(&p.packet), OV_MAX_PACKET_SIZE); + ck_assert_int_eq(memcmp(p.packet.data, inp+5, OV_MAX_PACKET_SIZE), 0); +} +END_TEST + START_TEST (test_frame_decoder1) { char inp[] = { 0xd0, 0x1f, 0xa0, 0x00, 0x00, 0x03, 0x00, 0xba, @@ -149,6 +162,7 @@ Suite* range_suite(void) { tcase_add_test(tc_packet, test_packet_decoder3); tcase_add_test(tc_packet, test_packet_decoder4); tcase_add_test(tc_packet, test_packet_decoder5); + tcase_add_test(tc_packet, test_packet_decoder_truncated); suite_add_tcase(s, tc_packet); tc_frame = tcase_create("Frame"); diff --git a/tools/sample/main.c b/tools/sample/main.c index 220a0d8..7e7f3c7 100644 --- a/tools/sample/main.c +++ b/tools/sample/main.c @@ -11,7 +11,7 @@ static void packet_handler(struct ov_packet* packet, void* data) { printf("[%02x] Received %d bytes at %" PRId64 ":", packet->flags, packet->size, packet->timestamp); - for (int i = 0; i < packet->size; ++i) + for (int i = 0; i < ov_packet_captured_size(packet); ++i) printf(" %02x", packet->data[i]); printf("\n"); }