From 5d9ca1fcf0aaac78e9bb744328191f3d59b73037 Mon Sep 17 00:00:00 2001 From: edvard Date: Wed, 28 May 2025 15:09:14 +0200 Subject: [PATCH 1/5] vmem: return byte count even if not completed --- src/vmem/vmem_client.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/vmem/vmem_client.c b/src/vmem/vmem_client.c index f556b33d..4f5b2d58 100644 --- a/src/vmem/vmem_client.c +++ b/src/vmem/vmem_client.c @@ -180,7 +180,6 @@ int vmem_upload(int node, int timeout, uint64_t address, char * datain, uint32_t unsigned int window_size = 0; csp_rdp_get_opt(&window_size, NULL, NULL, NULL, NULL, NULL); printf("Upload didn't complete, suggested offset to resume: %"PRIu32"\n", count - ((window_size + 1) * VMEM_SERVER_MTU)); - return -1; } else { printf(" Uploaded %"PRIu32" bytes in %.03f s at %"PRIu32" Bps\n", count, time_total / 1000.0, (uint32_t)(count / ((float)time_total / 1000.0)) ); } @@ -395,4 +394,4 @@ int vmem_client_calc_crc32(int node, int timeout, uint64_t address, uint32_t len csp_close(conn); return res; -} \ No newline at end of file +} From 065035c4be4fcb51df40473dc14f9ae7029749ac Mon Sep 17 00:00:00 2001 From: edvard Date: Wed, 11 Jun 2025 14:43:59 +0200 Subject: [PATCH 2/5] vmem: upload verbosity flag added, length is now input length pointer and output length pointer --- include/vmem/vmem_client.h | 17 ++++++++++++- src/vmem/vmem_client.c | 52 +++++++++++++++++++++----------------- 2 files changed, 45 insertions(+), 24 deletions(-) diff --git a/include/vmem/vmem_client.h b/include/vmem/vmem_client.h index fc9c1fc6..f685e2f6 100644 --- a/include/vmem/vmem_client.h +++ b/include/vmem/vmem_client.h @@ -4,7 +4,22 @@ #include int vmem_download(int node, int timeout, uint64_t address, uint32_t length, char * dataout, int version, int use_rdp); -int vmem_upload(int node, int timeout, uint64_t address, char * datain, uint32_t length, int version); + +/** + * @brief Upload data to remote vmem server at vmem address + * + * Use this function for uploading data to remote node. + * + * @param node The remote node to upload to + * @param timeout Timeout for upload + * @param address VMEM address to upload to on remote + * @param datain Pointer to data to upload + * @param[in,out] lengthio On input, points to the desired upload size; on output, is updated with the actual size uploaded + * @param version Protocol version to use be used. Use 2 for 64-bit VMEM address otherwise 32-bit is assumed + * @param verbose Set verbosity level: 0 for silent, 1 for final summary, 2 = for detailed progress + * @return int 0=success, -1=error + */ +int vmem_upload(int node, int timeout, uint64_t address, char * datain, uint32_t *lengthio, int version, int verbose); void vmem_client_list(int node, int timeout, int version); int vmem_client_find(int node, int timeout, void * dataout, int version, char * name, int namelen); int vmem_client_backup(int node, int vmem_id, int timeout, int backup_or_restore); diff --git a/src/vmem/vmem_client.c b/src/vmem/vmem_client.c index 4f5b2d58..c474327e 100644 --- a/src/vmem/vmem_client.c +++ b/src/vmem/vmem_client.c @@ -107,7 +107,7 @@ int vmem_download(int node, int timeout, uint64_t address, uint32_t length, char } -int vmem_upload(int node, int timeout, uint64_t address, char * datain, uint32_t length, int version) { +int vmem_upload(int node, int timeout, uint64_t address, char * datain, uint32_t * lengthio, int version, int verbose) { uint32_t time_begin = csp_get_ms(); abort = 0; @@ -115,13 +115,18 @@ int vmem_upload(int node, int timeout, uint64_t address, char * datain, uint32_t /* Establish RDP connection */ csp_conn_t * conn = csp_connect(CSP_PRIO_HIGH, node, VMEM_PORT_SERVER, timeout, CSP_O_RDP | CSP_O_CRC32); if (conn == NULL) { - printf("Connection could not be established\n"); + if(verbose == 1) { + printf("Connection could not be established\n"); + } + *lengthio = 0; return -1; } - csp_packet_t * packet = csp_buffer_get(sizeof(vmem_request_t)); - if (packet == NULL) + csp_packet_t * packet = csp_buffer_get(0); + if (packet == NULL) { + *lengthio = 0; return -1; + } vmem_request_t * request = (void *) packet->data; request->version = version; @@ -129,10 +134,10 @@ int vmem_upload(int node, int timeout, uint64_t address, char * datain, uint32_t if (version == 2) { request->data2.address = htobe64(address); - request->data2.length = htobe32(length); + request->data2.length = htobe32(*lengthio); } else { request->data.address = htobe32((uint32_t)(address & 0x00000000FFFFFFFFULL)); - request->data.length = htobe32(length); + request->data.length = htobe32(*lengthio); } packet->length = sizeof(vmem_request_t); @@ -141,24 +146,26 @@ int vmem_upload(int node, int timeout, uint64_t address, char * datain, uint32_t uint32_t count = 0; int dotcount = 0; - while((count < length) && csp_conn_is_active(conn)) { + while((count < *lengthio) && csp_conn_is_active(conn)) { if (abort) { csp_buffer_free(packet); break; } - if (dotcount % 32 == 0) - printf(" "); - printf("."); - fflush(stdout); - dotcount++; - if (dotcount % 32 == 0) - printf(" - %.0f K\n", (count / 1024.0)); + if(verbose == 2) { + if (dotcount % 32 == 0) + printf(" "); + printf("."); + fflush(stdout); + dotcount++; + if (dotcount % 32 == 0) + printf(" - %.0f K\n", (count / 1024.0)); + } /* Prepare packet */ - csp_packet_t * packet = csp_buffer_get(VMEM_SERVER_MTU); - packet->length = VMEM_MIN(VMEM_SERVER_MTU, length - count); + csp_packet_t * packet = csp_buffer_get(0); + packet->length = VMEM_MIN(VMEM_SERVER_MTU, *lengthio - count); /* Copy data */ memcpy(packet->data, (void *) ((intptr_t) datain + count), packet->length); @@ -170,21 +177,20 @@ int vmem_upload(int node, int timeout, uint64_t address, char * datain, uint32_t } - printf(" - %.0f K\n", (count / 1024.0)); + if(verbose == 2) { + printf(" - %.0f K\n", (count / 1024.0)); + } csp_close(conn); uint32_t time_total = csp_get_ms() - time_begin; - if(count != length){ - unsigned int window_size = 0; - csp_rdp_get_opt(&window_size, NULL, NULL, NULL, NULL, NULL); - printf("Upload didn't complete, suggested offset to resume: %"PRIu32"\n", count - ((window_size + 1) * VMEM_SERVER_MTU)); - } else { + if(verbose == 1) { printf(" Uploaded %"PRIu32" bytes in %.03f s at %"PRIu32" Bps\n", count, time_total / 1000.0, (uint32_t)(count / ((float)time_total / 1000.0)) ); } - return count; + *lengthio = count; + return 0; } static csp_packet_t * vmem_client_list_get(int node, int timeout, int version) { From fd4dfab7e9fb03739aa2e2d75f25d653c122c536 Mon Sep 17 00:00:00 2001 From: edvard Date: Fri, 13 Jun 2025 10:14:04 +0200 Subject: [PATCH 3/5] return err on uncompleted upload --- src/vmem/vmem_client.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/vmem/vmem_client.c b/src/vmem/vmem_client.c index c474327e..1b1b5683 100644 --- a/src/vmem/vmem_client.c +++ b/src/vmem/vmem_client.c @@ -115,7 +115,7 @@ int vmem_upload(int node, int timeout, uint64_t address, char * datain, uint32_t /* Establish RDP connection */ csp_conn_t * conn = csp_connect(CSP_PRIO_HIGH, node, VMEM_PORT_SERVER, timeout, CSP_O_RDP | CSP_O_CRC32); if (conn == NULL) { - if(verbose == 1) { + if(verbose > 0) { printf("Connection could not be established\n"); } *lengthio = 0; @@ -125,7 +125,7 @@ int vmem_upload(int node, int timeout, uint64_t address, char * datain, uint32_t csp_packet_t * packet = csp_buffer_get(0); if (packet == NULL) { *lengthio = 0; - return -1; + return -2; } vmem_request_t * request = (void *) packet->data; @@ -153,7 +153,7 @@ int vmem_upload(int node, int timeout, uint64_t address, char * datain, uint32_t break; } - if(verbose == 2) { + if(verbose > 1) { if (dotcount % 32 == 0) printf(" "); printf("."); @@ -177,7 +177,7 @@ int vmem_upload(int node, int timeout, uint64_t address, char * datain, uint32_t } - if(verbose == 2) { + if(verbose > 1) { printf(" - %.0f K\n", (count / 1024.0)); } @@ -185,11 +185,15 @@ int vmem_upload(int node, int timeout, uint64_t address, char * datain, uint32_t uint32_t time_total = csp_get_ms() - time_begin; - if(verbose == 1) { + if(verbose > 0) { printf(" Uploaded %"PRIu32" bytes in %.03f s at %"PRIu32" Bps\n", count, time_total / 1000.0, (uint32_t)(count / ((float)time_total / 1000.0)) ); } - *lengthio = count; + if(*lengthio != count){ + *lengthio = count; + return -3; + } + return 0; } From 3be70c42ffcb085c54eeb9e6cbf04748916f33b7 Mon Sep 17 00:00:00 2001 From: edvard Date: Fri, 13 Jun 2025 12:43:15 +0200 Subject: [PATCH 4/5] err if addr is 64bit and version 1 --- src/vmem/vmem_client.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/vmem/vmem_client.c b/src/vmem/vmem_client.c index 1b1b5683..f34ddb4f 100644 --- a/src/vmem/vmem_client.c +++ b/src/vmem/vmem_client.c @@ -20,6 +20,12 @@ void vmem_client_abort(void) { int vmem_download(int node, int timeout, uint64_t address, uint32_t length, char * dataout, int version, int use_rdp) { + + if((address > UINT32_MAX) && version != 2){ + printf(" Error: Address out of range 64-bit addresses require version 2\n"); + return -1; + } + uint32_t time_begin = csp_get_ms(); abort = 0; @@ -109,6 +115,12 @@ int vmem_download(int node, int timeout, uint64_t address, uint32_t length, char int vmem_upload(int node, int timeout, uint64_t address, char * datain, uint32_t * lengthio, int version, int verbose) { + + if((address > UINT32_MAX) && version != 2){ + printf(" Error: Address out of range 64-bit addresses require version 2\n"); + return -1; + } + uint32_t time_begin = csp_get_ms(); abort = 0; @@ -359,6 +371,11 @@ int vmem_client_calc_crc32(int node, int timeout, uint64_t address, uint32_t len int res = -1; + if((address > UINT32_MAX) && version != 2){ + printf(" Error: 64 bit address only supported in version 2\n"); + return res; + } + uint32_t time_begin = csp_get_ms(); /* Establish connection */ From 1a7219c0d1b172bf632d8f84f7ad2898ce2aad0c Mon Sep 17 00:00:00 2001 From: edvard Date: Fri, 13 Jun 2025 18:25:47 +0200 Subject: [PATCH 5/5] Redefine upload download api, introducing param_errs --- include/param/param.h | 2 + include/param/param_error.h | 7 +++ include/vmem/vmem_client.h | 28 +++++++++-- src/vmem/vmem_client.c | 96 +++++++++++++++++++++---------------- 4 files changed, 87 insertions(+), 46 deletions(-) create mode 100644 include/param/param_error.h diff --git a/include/param/param.h b/include/param/param.h index fee97101..5e0d6e61 100644 --- a/include/param/param.h +++ b/include/param/param.h @@ -10,6 +10,8 @@ #include #include +#include + #include "libparam.h" diff --git a/include/param/param_error.h b/include/param/param_error.h new file mode 100644 index 00000000..428fb841 --- /dev/null +++ b/include/param/param_error.h @@ -0,0 +1,7 @@ +#pragma once + +#define PARAM_ERR_NONE 0 /**< No error */ +#define PARAM_ERR_NOMEM -400 /**< Not enough memory */ +#define PARAM_ERR_INVAL -401 /**< Invalid argument */ +#define PARAM_ERR_NOTSUP -402 /**< Operation not supported */ + diff --git a/include/vmem/vmem_client.h b/include/vmem/vmem_client.h index f685e2f6..698fd422 100644 --- a/include/vmem/vmem_client.h +++ b/include/vmem/vmem_client.h @@ -3,7 +3,23 @@ #include #include -int vmem_download(int node, int timeout, uint64_t address, uint32_t length, char * dataout, int version, int use_rdp); +/** + * @brief Download data from remote vmem server at vmem address + * + * Use this function for downloading data from remote node. + * + * @param node The remote node to upload to + * @param timeout Timeout for download + * @param address VMEM address to download from on remote + * @param dataout Pointer to data buffer + * @param length The length in bytes to download into dataout buffer + * @param use_rdp Set flag to use RDP connection + * @param version Protocol version to use be used. Use 2 for 64-bit VMEM address otherwise 32-bit is assumed + * @param verbosity Set verbosity level: 0 for silent, 1 for final summary, 2 = for detailed progress + * @return On success, the total number of bytes successfully uploaded + * @return On error, a negative value is returned to indicate the specific error + */ +ssize_t vmem_download(uint16_t node, uint32_t timeout, uint64_t address, char * dataout, uint32_t length, int use_rdp, int version, int verbosity); /** * @brief Upload data to remote vmem server at vmem address @@ -14,12 +30,14 @@ int vmem_download(int node, int timeout, uint64_t address, uint32_t length, char * @param timeout Timeout for upload * @param address VMEM address to upload to on remote * @param datain Pointer to data to upload - * @param[in,out] lengthio On input, points to the desired upload size; on output, is updated with the actual size uploaded + * @param length The length in bytes of the data passed in + * @param use_rdp Set flag to use RDP connection * @param version Protocol version to use be used. Use 2 for 64-bit VMEM address otherwise 32-bit is assumed - * @param verbose Set verbosity level: 0 for silent, 1 for final summary, 2 = for detailed progress - * @return int 0=success, -1=error + * @param verbosity Set verbosity level: 0 for silent, 1 for final summary, 2 = for detailed progress + * @return On success, the total number of bytes successfully downloaded + * @return On error, a negative value is returned to indicate the specific error */ -int vmem_upload(int node, int timeout, uint64_t address, char * datain, uint32_t *lengthio, int version, int verbose); +ssize_t vmem_upload(uint16_t node, uint32_t timeout, uint64_t address, const char * datain, uint32_t size, int use_rdp, int version, int verbosity); void vmem_client_list(int node, int timeout, int version); int vmem_client_find(int node, int timeout, void * dataout, int version, char * name, int namelen); int vmem_client_backup(int node, int vmem_id, int timeout, int backup_or_restore); diff --git a/src/vmem/vmem_client.c b/src/vmem/vmem_client.c index f34ddb4f..cc3d455d 100644 --- a/src/vmem/vmem_client.c +++ b/src/vmem/vmem_client.c @@ -5,12 +5,15 @@ * Author: johan */ +#include #include #include #include #include #include +#include +#include "csp/csp_error.h" static int abort = 0; @@ -18,12 +21,13 @@ void vmem_client_abort(void) { abort = 1; } -int vmem_download(int node, int timeout, uint64_t address, uint32_t length, char * dataout, int version, int use_rdp) -{ +ssize_t vmem_download(uint16_t node, uint32_t timeout, uint64_t address, char * dataout, uint32_t length, int use_rdp, int version, int verbosity) { if((address > UINT32_MAX) && version != 2){ - printf(" Error: Address out of range 64-bit addresses require version 2\n"); - return -1; + if(verbosity > 0){ + printf(" Error: Address out of range 64-bit addresses require version 2\n"); + } + return PARAM_ERR_INVAL; } uint32_t time_begin = csp_get_ms(); @@ -35,12 +39,16 @@ int vmem_download(int node, int timeout, uint64_t address, uint32_t length, char opts |= CSP_O_RDP; } csp_conn_t * conn = csp_connect(CSP_PRIO_HIGH, node, VMEM_PORT_SERVER, timeout, opts); - if (conn == NULL) - return -1; + if (conn == NULL){ + if(verbosity > 0) { + printf(" Connection could not be established\n"); + } + return CSP_ERR_TIMEDOUT; + } csp_packet_t * packet = csp_buffer_get(sizeof(vmem_request_t)); if (packet == NULL) - return -1; + return CSP_ERR_NOMEM; vmem_request_t * request = (void *) packet->data; request->version = version; @@ -84,13 +92,15 @@ int vmem_download(int node, int timeout, uint64_t address, uint32_t length, char break; } - if (dotcount % 32 == 0) - printf(" "); - printf("."); - fflush(stdout); - dotcount++; - if (dotcount % 32 == 0) - printf(" - %.0f K\n", (count / 1024.0)); + if(verbosity > 1) { + if (dotcount % 32 == 0) + printf(" "); + printf("."); + fflush(stdout); + dotcount++; + if (dotcount % 32 == 0) + printf(" - %.0f K\n", (count / 1024.0)); + } /* Put data */ memcpy((void *) ((intptr_t) dataout + count), packet->data, packet->length); @@ -101,43 +111,50 @@ int vmem_download(int node, int timeout, uint64_t address, uint32_t length, char csp_buffer_free(packet); } - printf(" - %.0f K\n", (count / 1024.0)); + if(verbosity > 1) { + printf(" - %.0f K\n", (count / 1024.0)); + } csp_close(conn); uint32_t time_total = csp_get_ms() - time_begin; - printf(" Downloaded %u bytes in %.03f s at %u Bps\n", (unsigned int) count, time_total / 1000.0, (unsigned int) (count / ((float)time_total / 1000.0)) ); + if(verbosity > 0) { + printf(" Downloaded %u bytes in %.03f s at %u Bps\n", (unsigned int) count, time_total / 1000.0, (unsigned int) (count / ((float)time_total / 1000.0)) ); + } return count; } -int vmem_upload(int node, int timeout, uint64_t address, char * datain, uint32_t * lengthio, int version, int verbose) { - +ssize_t vmem_upload(uint16_t node, uint32_t timeout, uint64_t address, const char * datain, uint32_t length, int use_rdp, int version, int verbosity) { if((address > UINT32_MAX) && version != 2){ - printf(" Error: Address out of range 64-bit addresses require version 2\n"); - return -1; + if(verbosity > 0){ + printf(" Error: Address out of range 64-bit addresses require version 2\n"); + } + return PARAM_ERR_INVAL; } uint32_t time_begin = csp_get_ms(); abort = 0; /* Establish RDP connection */ - csp_conn_t * conn = csp_connect(CSP_PRIO_HIGH, node, VMEM_PORT_SERVER, timeout, CSP_O_RDP | CSP_O_CRC32); + uint32_t opts = CSP_O_CRC32; + if (use_rdp) { + opts |= CSP_O_RDP; + } + csp_conn_t * conn = csp_connect(CSP_PRIO_HIGH, node, VMEM_PORT_SERVER, timeout, opts); if (conn == NULL) { - if(verbose > 0) { - printf("Connection could not be established\n"); + if(verbosity > 0) { + printf(" Connection could not be established\n"); } - *lengthio = 0; - return -1; + return CSP_ERR_TIMEDOUT; } csp_packet_t * packet = csp_buffer_get(0); if (packet == NULL) { - *lengthio = 0; - return -2; + return CSP_ERR_NOMEM; } vmem_request_t * request = (void *) packet->data; @@ -146,10 +163,10 @@ int vmem_upload(int node, int timeout, uint64_t address, char * datain, uint32_t if (version == 2) { request->data2.address = htobe64(address); - request->data2.length = htobe32(*lengthio); + request->data2.length = htobe32(length); } else { request->data.address = htobe32((uint32_t)(address & 0x00000000FFFFFFFFULL)); - request->data.length = htobe32(*lengthio); + request->data.length = htobe32(length); } packet->length = sizeof(vmem_request_t); @@ -158,14 +175,13 @@ int vmem_upload(int node, int timeout, uint64_t address, char * datain, uint32_t uint32_t count = 0; int dotcount = 0; - while((count < *lengthio) && csp_conn_is_active(conn)) { + while((count < length) && csp_conn_is_active(conn)) { if (abort) { - csp_buffer_free(packet); break; } - if(verbose > 1) { + if(verbosity > 1) { if (dotcount % 32 == 0) printf(" "); printf("."); @@ -177,7 +193,10 @@ int vmem_upload(int node, int timeout, uint64_t address, char * datain, uint32_t /* Prepare packet */ csp_packet_t * packet = csp_buffer_get(0); - packet->length = VMEM_MIN(VMEM_SERVER_MTU, *lengthio - count); + if(packet == NULL) { + break; + } + packet->length = VMEM_MIN(VMEM_SERVER_MTU, length - count); /* Copy data */ memcpy(packet->data, (void *) ((intptr_t) datain + count), packet->length); @@ -189,7 +208,7 @@ int vmem_upload(int node, int timeout, uint64_t address, char * datain, uint32_t } - if(verbose > 1) { + if(verbosity > 1) { printf(" - %.0f K\n", (count / 1024.0)); } @@ -197,16 +216,11 @@ int vmem_upload(int node, int timeout, uint64_t address, char * datain, uint32_t uint32_t time_total = csp_get_ms() - time_begin; - if(verbose > 0) { + if(verbosity > 0) { printf(" Uploaded %"PRIu32" bytes in %.03f s at %"PRIu32" Bps\n", count, time_total / 1000.0, (uint32_t)(count / ((float)time_total / 1000.0)) ); } - if(*lengthio != count){ - *lengthio = count; - return -3; - } - - return 0; + return count; } static csp_packet_t * vmem_client_list_get(int node, int timeout, int version) {