diff --git a/lib_standard_app/io.c b/lib_standard_app/io.c index b403be6fe..90b8f4105 100644 --- a/lib_standard_app/io.c +++ b/lib_standard_app/io.c @@ -153,25 +153,28 @@ WEAK int io_recv_command() return ret; } -WEAK int io_send_response_pointer(const uint8_t *ptr, size_t size, uint16_t sw) -{ - return io_send_response_buffer(&(const buffer_t){.ptr = ptr, .size = size, .offset = 0}, sw); -} - -WEAK int io_send_response_buffer(const buffer_t *rdata, uint16_t sw) +WEAK int io_send_response_buffers(const buffer_t *rdatalist, size_t count, uint16_t sw) { int ret = -1; - if (rdata != NULL) { - if (rdata->size - rdata->offset > IO_APDU_BUFFER_SIZE - 2 || // - !buffer_copy(rdata, G_io_apdu_buffer, sizeof(G_io_apdu_buffer))) { - return io_send_sw(SW_WRONG_RESPONSE_LENGTH); + G_output_len = 0; + if (rdatalist && count > 0) { + for (size_t i = 0; i < count; i++) { + const buffer_t *rdata = &rdatalist[i]; + + if (!buffer_copy(rdata, + G_io_apdu_buffer + G_output_len, + sizeof(G_io_apdu_buffer) - G_output_len - 2)) { + return io_send_sw(SW_WRONG_RESPONSE_LENGTH); + } + G_output_len += rdata->size - rdata->offset; + if (count > 1) { + PRINTF("<= FRAG (%u/%u) RData=%.*H\n", i + 1, count, rdata->size, rdata->ptr); + } } - G_output_len = rdata->size - rdata->offset; - PRINTF("<= SW=%04X | RData=%.*H\n", sw, rdata->size, rdata->ptr); + PRINTF("<= SW=%04X | RData=%.*H\n", sw, G_output_len, G_io_apdu_buffer); } else { - G_output_len = 0; PRINTF("<= SW=%04X | RData=\n", sw); } @@ -209,8 +212,3 @@ WEAK int io_send_response_buffer(const buffer_t *rdata, uint16_t sw) return ret; } - -WEAK int io_send_sw(uint16_t sw) -{ - return io_send_response_buffer(NULL, sw); -} diff --git a/lib_standard_app/io.h b/lib_standard_app/io.h index 19248a241..f3abff3e8 100644 --- a/lib_standard_app/io.h +++ b/lib_standard_app/io.h @@ -56,6 +56,22 @@ WEAK void io_init(void); */ WEAK int io_recv_command(void); +/** + * Send APDU response (response data + status word) by filling + * G_io_apdu_buffer. + * + * @param[in] rdatalist + * List of Buffers with APDU response data. + * @param[in] count + * Count of the buffers providded in rdatalist. + * @param[in] sw + * Status word of APDU response. + * + * @return zero or positive integer if success, -1 otherwise. + * + */ +WEAK int io_send_response_buffers(const buffer_t *rdatalist, size_t count, uint16_t sw); + /** * Send APDU response (response data + status word) by filling * G_io_apdu_buffer. @@ -70,7 +86,11 @@ WEAK int io_recv_command(void); * @return zero or positive integer if success, -1 otherwise. * */ -WEAK int io_send_response_pointer(const uint8_t *ptr, size_t size, uint16_t sw); +static inline int io_send_response_pointer(const uint8_t *ptr, size_t size, uint16_t sw) +{ + return io_send_response_buffers( + &(const buffer_t){.ptr = ptr, .size = size, .offset = 0}, 1, sw); +} /** * Send APDU response (response data + status word) by filling @@ -84,7 +104,10 @@ WEAK int io_send_response_pointer(const uint8_t *ptr, size_t size, uint16_t sw); * @return zero or positive integer if success, -1 otherwise. * */ -WEAK int io_send_response_buffer(const buffer_t *rdata, uint16_t sw); +static inline int io_send_response_buffer(const buffer_t *rdata, uint16_t sw) +{ + return io_send_response_buffers(rdata, 1, sw); +} /** * Send APDU response (only status word) by filling @@ -96,4 +119,7 @@ WEAK int io_send_response_buffer(const buffer_t *rdata, uint16_t sw); * @return zero or positive integer if success, -1 otherwise. * */ -WEAK int io_send_sw(uint16_t sw); +static inline int io_send_sw(uint16_t sw) +{ + return io_send_response_buffers(NULL, 0, sw); +}