From 85e991c62ad4c6bb8bcd53bcbaae16c958bf4144 Mon Sep 17 00:00:00 2001 From: Kevin Day Date: Wed, 13 Mar 2024 18:50:29 -0500 Subject: [PATCH] Progress: Further work in TacocaT. I've decided to shift focus on the controller program migration. This still needs a lot of work regarding packet parts. Checksum and encryption are also needed (via third-party libraries). --- sources/c/tacocat/main/common/define.h | 14 ++++++++ sources/c/tacocat/main/print/error.c | 10 ++++-- sources/c/tacocat/main/print/error.h | 5 ++- sources/c/tacocat/main/receive.c | 65 +++++++++++++++++++++------------- 4 files changed, 67 insertions(+), 27 deletions(-) diff --git a/sources/c/tacocat/main/common/define.h b/sources/c/tacocat/main/common/define.h index 140d946..d241466 100644 --- a/sources/c/tacocat/main/common/define.h +++ b/sources/c/tacocat/main/common/define.h @@ -120,6 +120,9 @@ extern "C" { * macro_kt_receive_process_begin_handle_error_exit_1: * Intended to be used for handling an error during the receive process while processing within step kt_tacocat_socket_step_receive_control_e. * + * macro_kt_receive_process_invalid_packet_exit_1: + * Similar to macro_kt_receive_process_handle_error_exit_1() but calls kt_tacocat_print_error_on_packet_invalid(). + * * @todo document all macros. */ #ifndef _di_kt_tacocat_macros_d_ @@ -184,6 +187,17 @@ extern "C" { return F_done_not; \ } + #define macro_kt_receive_process_invalid_packet_exit_1(main, network, name, step, id_data) \ + kt_tacocat_print_error_on_packet_invalid(&main->program.error, kt_tacocat_receive_s, network, name); \ + \ + if (id_data) { \ + f_file_close_id(&(id_data)); \ + } \ + \ + step = 0; \ + \ + return F_done_not; + #define macro_kt_receive_process_begin_handle_error_exit_1(main, method, network, status, name, step) \ if (F_status_is_error(status)) { \ kt_tacocat_print_error_on(&main->program.error, macro_kt_tacocat_f(method), kt_tacocat_receive_s, network, status, name); \ diff --git a/sources/c/tacocat/main/print/error.c b/sources/c/tacocat/main/print/error.c index 7e6ae5f..807543a 100644 --- a/sources/c/tacocat/main/print/error.c +++ b/sources/c/tacocat/main/print/error.c @@ -183,7 +183,7 @@ extern "C" { #endif // _di_kt_tacocat_print_error_on_packet_header_value_invalid_ #ifndef _di_kt_tacocat_print_error_on_packet_invalid_ - f_status_t kt_tacocat_print_error_on_packet_invalid(fl_print_t * const print, const f_string_static_t on, const f_string_static_t network) { + f_status_t kt_tacocat_print_error_on_packet_invalid(fl_print_t * const print, const f_string_static_t on, const f_string_static_t network, const f_string_static_t name) { if (!print) return F_status_set_error(F_output_not); if (print->verbosity < f_console_verbosity_error_e) return F_output_not; @@ -192,8 +192,14 @@ extern "C" { fl_print_format("%[%QNetwork packet is invalid for%] ", print->to, print->set->error, print->prefix, print->set->error); fl_print_format(f_string_format_Q_single_s.string, print->to, print->set->notable, on, print->set->notable); - fl_print_format(" %[buffer for '%]", print->to, print->set->error, print->set->error, f_string_eol_s); + fl_print_format(" %[for '%]", print->to, print->set->error, print->set->error, f_string_eol_s); fl_print_format(f_string_format_Q_single_s.string, print->to, print->set->notable, network, print->set->notable); + + if (name.used) { + fl_print_format("%[' with file '%]", print->to, print->set->error, print->set->error, f_string_eol_s); + fl_print_format(f_string_format_Q_single_s.string, print->to, print->set->notable, name, print->set->notable); + } + fl_print_format(f_string_format_sentence_end_quote_s.string, print->to, print->set->error, print->set->error, f_string_eol_s); f_file_stream_unlock(print->to); diff --git a/sources/c/tacocat/main/print/error.h b/sources/c/tacocat/main/print/error.h index 145d3b9..bad4f66 100644 --- a/sources/c/tacocat/main/print/error.h +++ b/sources/c/tacocat/main/print/error.h @@ -289,6 +289,9 @@ extern "C" { * The network connection direction, which should either be "receive" or "send". * @param network * The name of the network in which the error is related. + * @param name + * (optional) The name of the file. + * Set name.used to 0 to disable. * * @return * F_okay on success. @@ -299,7 +302,7 @@ extern "C" { * @see fll_error_file_print() */ #ifndef _di_kt_tacocat_print_error_on_packet_invalid_ - extern f_status_t kt_tacocat_print_error_on_packet_invalid(fl_print_t * const print, const f_string_static_t on, const f_string_static_t network); + extern f_status_t kt_tacocat_print_error_on_packet_invalid(fl_print_t * const print, const f_string_static_t on, const f_string_static_t network, const f_string_static_t name); #endif // _di_kt_tacocat_print_error_on_packet_invalid_ /** diff --git a/sources/c/tacocat/main/receive.c b/sources/c/tacocat/main/receive.c index b30600e..67b9c0a 100644 --- a/sources/c/tacocat/main/receive.c +++ b/sources/c/tacocat/main/receive.c @@ -13,11 +13,13 @@ extern "C" { kt_tacocat_main_t * const main = (kt_tacocat_main_t *) void_main; f_number_unsigned_t i = 0; + kt_tacocat_socket_set_t * set = 0; kt_tacocat_process_socket_set_receive(main); if (F_status_is_error_not(main->setting.status_receive) && main->setting.receive.used) { do { + // @todo this would probably be better when active_receive > 0 to add a nano timestamp check and if time elapsed is smaller than a given number then do not poll. main->setting.status_receive = f_file_poll(main->setting.receive_polls, main->setting.active_receive ? main->setting.interval_fast : main->setting.interval); @@ -34,46 +36,52 @@ extern "C" { if (main->setting.receive_polls.array[i].fd == -1) continue; if (main->setting.receive_polls.array[i].revents & (f_poll_read_e)) { - if (kt_tacocat_receive_process(main, &main->setting.receive.array[i]) == F_done) { - if (F_status_is_error(main->setting.receive.array[i].status)) { + set = &main->setting.receive.array[i]; + + if (kt_tacocat_receive_process(main, set) == F_done) { + if (F_status_is_error(set->status)) { + // @todo there probably should be a timeout as well as a retry, which should be checked if the poll read condition above is false. - if (++main->setting.receive.array[i].retry >= kt_tacocat_startup_retry_max_d) { - f_file_close(&main->setting.receive.array[i].file); + if (++set->retry >= kt_tacocat_startup_retry_max_d || (set->step == kt_tacocat_socket_step_receive_control_e && (F_status_set_fine(set->status) == F_packet_too_small || F_status_set_fine(set->status) == F_packet_too_large))) { + f_file_close(&set->file); // Keep error bit but set state to done to designate that nothing else is to be done. - main->setting.receive.array[i].status = F_status_set_error(F_done); + set->status = F_status_set_error(F_done); - if (main->setting.receive.array[i].step) { - main->setting.receive.array[i].step = 0; + if (set->step) { + set->step = 0; if (main->setting.active_receive) { --main->setting.active_receive; } } - kt_tacocat_print_error_on_max_retries_receive(&main->program.error, &main->setting.receive.array[i]); + if (set->retry >= kt_tacocat_startup_retry_max_d) { + kt_tacocat_print_error_on_max_retries_receive(&main->program.error, set); + } + else { + kt_tacocat_print_error_on_packet_invalid(&main->program.error, kt_tacocat_receive_s, set->network, set->name); + } } - - // @todo if step is kt_tacocat_socket_step_receive_control_e, check if error is either F_packet_too_small or F_packet_too_large. This is a non-retrying error. } } else { - if (F_status_is_error(main->setting.receive.array[i].status)) { - if (++main->setting.receive.array[i].retry >= kt_tacocat_startup_retry_max_d) { - f_file_close(&main->setting.receive.array[i].file); + if (F_status_is_error(set->status)) { + if (++set->retry >= kt_tacocat_startup_retry_max_d) { + f_file_close(&set->file); // Keep error bit but set state to done to designate that nothing else is to be done. @todo review and confirm if this assignment with error bit set is needed anymore or should be changed. - main->setting.receive.array[i].status = F_status_set_error(F_done); + set->status = F_status_set_error(F_done); - if (main->setting.receive.array[i].step) { - main->setting.receive.array[i].step = 0; + if (set->step) { + set->step = 0; if (main->setting.active_receive) { --main->setting.active_receive; } } - kt_tacocat_print_error_on_max_retries_receive(&main->program.error, &main->setting.receive.array[i]); + kt_tacocat_print_error_on_max_retries_receive(&main->program.error, set); } } } @@ -145,7 +153,7 @@ extern "C" { // Make sure the buffer is large enough for payload processing block reads. set->status = f_memory_array_increase_by(set->socket.size_read, sizeof(f_char_t), (void **) &set->buffer.string, &set->buffer.used, &set->buffer.size); - macro_kt_receive_process_handle_error_exit_1(main, f_memory_array_increase_by, set->network, set->status, set->name, set->flag, set->socket.id_data); + macro_kt_receive_process_handle_error_exit_1(main, f_memory_array_increase_by, set->network, set->status, set->name, set->step, set->socket.id_data); set->retry = 0; set->buffer.used = 0; @@ -156,7 +164,7 @@ extern "C" { size_t length_read = 0; set->status = f_socket_read_stream(&set->socket, 0, (void *) (set->buffer.string + set->buffer.used), &length_read); - macro_kt_receive_process_handle_error_exit_1(main, f_socket_read_stream, set->network, set->status, set->name, set->flag, set->socket.id_data); + macro_kt_receive_process_handle_error_exit_1(main, f_socket_read_stream, set->network, set->status, set->name, set->step, set->socket.id_data); if (length_read) { set->retry = 0; @@ -260,29 +268,38 @@ extern "C" { if (set->step == kt_tacocat_socket_step_receive_check_e) { if (set->parts.used) { + if (set->abstruses.array[1].value.type != f_abstruse_unsigned_e) { + macro_kt_receive_process_invalid_packet_exit_1(main, set->network, set->name, set->step, set->socket.id_data); + } + // @todo determine type of packet and process. } else { - // @todo the packet should only be a 'file' type for the first packet. + + // The packet should only be a 'file' type for the first packet. + if (set->abstruses.array[1].value.type != f_abstruse_unsigned_e || set->abstruses.array[1].value.is.a_unsigned != kt_tacocat_packet_type_file_e) { + macro_kt_receive_process_invalid_packet_exit_1(main, set->network, set->name, set->step, set->socket.id_data); + } + if (set->abstruses.array[4].value.type == f_abstruse_unsigned_e) { set->parts.used = 0; set->status = f_memory_array_increase_by(set->abstruses.array[4].value.is.a_unsigned, sizeof(f_number_unsigned_t), (void **) &set->parts.array, &set->parts.used, &set->parts.size); - macro_kt_receive_process_handle_error_exit_1(main, f_memory_array_increase_by, set->network, set->status, set->name, set->flag, set->socket.id_data); + macro_kt_receive_process_handle_error_exit_1(main, f_memory_array_increase_by, set->network, set->status, set->name, set->step, set->socket.id_data); memset(set->parts.array, 0, sizeof(f_number_unsigned_t)); set->parts.used = set->abstruses.array[4].value.is.a_unsigned; } else { - // @todo error. + macro_kt_receive_process_invalid_packet_exit_1(main, set->network, set->name, set->step, set->socket.id_data); } if (set->abstruses.array[3].value.type == f_abstruse_unsigned_e) { set->part = set->abstruses.array[3].value.is.a_unsigned; } else { - // @todo error + macro_kt_receive_process_invalid_packet_exit_1(main, set->network, set->name, set->step, set->socket.id_data); } } @@ -439,7 +456,7 @@ extern "C" { set->status = F_status_set_error(F_packet_too_large); } - kt_tacocat_print_error_on_packet_invalid(&main->program.error, kt_tacocat_receive_s, set->network); + kt_tacocat_print_error_on_packet_invalid(&main->program.error, kt_tacocat_receive_s, set->network, set->name); return; } -- 1.8.3.1