diff --git a/components/C-Linked-List/list.c b/components/C-Linked-List/list.c index e83b30f..ed18b43 100644 --- a/components/C-Linked-List/list.c +++ b/components/C-Linked-List/list.c @@ -95,10 +95,3 @@ void list_remove(List** head, unsigned int index) { } } -void list_destroy(List** head) { - while (*head != NULL) { - List* tmp_cursor = *head; - *head = (*head)->next; - free(tmp_cursor); - } -} diff --git a/components/C-Linked-List/list.h b/components/C-Linked-List/list.h index 4108fba..f6be784 100644 --- a/components/C-Linked-List/list.h +++ b/components/C-Linked-List/list.h @@ -24,7 +24,4 @@ List* list_get(List* head, unsigned int index); // Delete the item in the list at the given ordinal location (1 is the first). void list_remove(List** head, unsigned int index); -// Remove all element of the list and set the given ptr to NULL -void list_destroy(List** head); - #endif diff --git a/main/can.h b/main/can.h index 5bb8d4d..8e3a323 100644 --- a/main/can.h +++ b/main/can.h @@ -31,6 +31,11 @@ typedef struct { bool sw_filtering; } adv_filt_t; +typedef struct { + uint32_t filt; + uint32_t mask; +} smart_filt_element_t; + typedef struct { can_state_e state; uint32_t msgs_to_tx; /**< Number of messages queued for transmission or awaiting transmission completion */ diff --git a/main/cmd_can.c b/main/cmd_can.c index 94c8106..ea35091 100644 --- a/main/cmd_can.c +++ b/main/cmd_can.c @@ -424,20 +424,73 @@ static struct { struct arg_end *end; } cansmart_args; + +void smartfilters_destroy(List** head) { + while (*head != NULL) { + List* tmp_cursor = *head; + *head = (*head)->next; + free((smart_filt_element_t *) tmp_cursor->data); + free(tmp_cursor); + } +} + static int cansmartfilter(int argc, char **argv) { + char *filter_str_buf = NULL; + smart_filt_element_t *filt_element = NULL; int nerrors = arg_parse(argc, argv, (void **) &cansmart_args); if (nerrors != 0) { arg_print_errors(stderr, cansmart_args.end, argv[0]); return 1; } - list_destroy(&adv_filters.filters); + smartfilters_destroy(&adv_filters.filters); + adv_filters.sw_filtering = false; + adv_filters.enabled = false; + bool tmp_sw = false; + uint32_t hwfilt_code = 0; + uint32_t hwfilt_mask = 0; for (int i = 0; i < cansmart_args.filters->count; i++) { - + filt_element = malloc(sizeof(smart_filt_element_t)); + const char *filter_str_ptr = cansmart_args.filters->sval[i]; + filter_str_buf = strdup(filter_str_ptr); + char *code_substr = strtok(filter_str_buf, "#"); + char *mask_substr = strtok(NULL, "#"); + if (code_substr == NULL || mask_substr == NULL || strtok(NULL, "#") != NULL) goto invalid_args; + int m_l = strlen(mask_substr); + int c_l = strlen(code_substr); + if (m_l > 8 || c_l > 8) goto invalid_args; + for (int i = 0; i < m_l; i++) if (!isxdigit((int) mask_substr[i])) goto invalid_args; + for (int i = 0; i < c_l; i++) if (!isxdigit((int) code_substr[i])) goto invalid_args; + if (sscanf(code_substr, "%" PRIX32, &filt_element->filt) < 1) goto invalid_args; + if (sscanf(mask_substr, "%" PRIX32, &filt_element->mask) < 1) goto invalid_args; + list_push(&adv_filters.filters, (void *) filt_element); + if (i == 0) { + hwfilt_mask = filt_element->mask; + hwfilt_code = filt_element->filt; + } else { + uint32_t common_bits = filt_element->mask & hwfilt_mask; + uint32_t new_bits = filt_element->mask - common_bits; + uint32_t missing_bits = hwfilt_mask - common_bits; + hwfilt_mask &= filt_element->mask; + uint32_t bit_to_delete = (hwfilt_code ^ filt_element->filt) & hwfilt_mask; + hwfilt_mask -= bit_to_delete; + if (new_bits || missing_bits || bit_to_delete) tmp_sw = true; + } + filt_element = NULL; } - - - + my_filters.single_filter = true; + my_filters.acceptance_mask = ~(hwfilt_mask << 3); + my_filters.acceptance_code = hwfilt_code << 3; + adv_filters.sw_filtering = tmp_sw; + adv_filters.enabled = true; + print_w_clr_time("Smart filters were set.", LOG_COLOR_GREEN, true); + printf("Num of smart filters: %d\n", list_sizeof(adv_filters.filters)); return 0; +invalid_args: + free(filter_str_buf); + free(filt_element); + print_w_clr_time("Invalid arguments!", LOG_COLOR_RED, true); + smartfilters_destroy(&adv_filters.filters); + return 1; } static void register_cansmartfilter(void) { @@ -445,7 +498,7 @@ static void register_cansmartfilter(void) { cansmart_args.filters = arg_strn(NULL, NULL, " ...", 1, CONFIG_CAN_MAX_SMARTFILTERS_NUM, "Filters, in hex format. Each one contains mask and code in format code#mask. Both mask and code are uint32_t numbers in hex format. Example: 0000FF00#0000FFFF"); const esp_console_cmd_t cmd = { .command = "cansmartfilter", - .help = "Setup smart mixed filters (hardware + software). Num of filters can be up to the value in config.", + .help = "Setup smart mixed filters (hardware + software). Num of filters can be up to the value in config. Supportd only ID filtering of extended frames, standart frames aren't supported for now.", .hint = NULL, .func = &cansmartfilter, .argtable = &cansmart_args,