Skip to content

Commit 9b807e3

Browse files
committed
Enhance CAN filter (Advanced filter structure, Timing requirements, Custom filter functions, Error frame detection, Multiple filters, VOltage thresholds, Dilter statistics, Dynamic filter addition.)
1 parent cf4c2e7 commit 9b807e3

File tree

1 file changed

+128
-1
lines changed

1 file changed

+128
-1
lines changed

src/can_filter.c

Lines changed: 128 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,132 @@
11
#include "can_filter.h"
2+
#include <stdio.h>
3+
#include <stdlib.h>
4+
#include <string.h>
5+
#include <time.h>
6+
7+
#define MAX_FILTERS 16
8+
#define SAMPLING_RATE 1000 // Hz
9+
#define VOLTAGE_THRESHOLD 2.5 // Volts
10+
#define CAN_ERROR_FRAME 0x20000000 // Error frame bit in CAN ID
11+
12+
// Advanced filter structure
13+
typedef struct {
14+
struct can_filter base;
15+
uint8_t priority;
16+
uint64_t timestamp;
17+
double signal_strength;
18+
int (*custom_filter_func)(const struct can_frame *);
19+
} advanced_can_filter;
20+
21+
// Global filter array
22+
static advanced_can_filter filter_array[MAX_FILTERS];
23+
static int filter_count = 0;
24+
25+
// Function prototypes
26+
static double calculate_signal_strength(const struct can_frame *frame);
27+
static int check_timing_requirements(const struct can_frame *frame, const advanced_can_filter *filter);
28+
static int apply_custom_filter(const struct can_frame *frame, const advanced_can_filter *filter);
29+
static int detect_error_frame(const struct can_frame *frame);
230

331
int apply_can_filter(const struct can_frame *frame, const struct can_filter *filter) {
4-
return (frame->can_id & filter->can_mask) == (filter->can_id & filter->can_mask);
32+
if (filter_count == 0) {
33+
printf("Warning: No filters configured\n");
34+
return 1; // Accept all frames if no filters are set
35+
}
36+
37+
for (int i = 0; i < filter_count; i++) {
38+
const advanced_can_filter *adv_filter = &filter_array[i];
39+
40+
// Basic ID and mask check
41+
if ((frame->can_id & adv_filter->base.can_mask) != (adv_filter->base.can_id & adv_filter->base.can_mask)) {
42+
continue;
43+
}
44+
45+
// Check signal strength
46+
double signal_strength = calculate_signal_strength(frame);
47+
if (signal_strength < adv_filter->signal_strength) {
48+
printf("Frame rejected due to weak signal strength: %.2f\n", signal_strength);
49+
continue;
50+
}
51+
52+
// Check timing requirements
53+
if (!check_timing_requirements(frame, adv_filter)) {
54+
continue;
55+
}
56+
57+
// Apply custom filter function if available
58+
if (!apply_custom_filter(frame, adv_filter)) {
59+
continue;
60+
}
61+
62+
// Check for error frames
63+
if (detect_error_frame(frame)) {
64+
printf("Error frame detected\n");
65+
return 0;
66+
}
67+
68+
// All checks passed, accept the frame
69+
return 1;
70+
}
71+
72+
return 0; // Frame doesn't match any filter
73+
}
74+
75+
int add_advanced_filter(struct can_filter *base_filter, uint8_t priority, double min_signal_strength,
76+
int (*custom_func)(const struct can_frame *)) {
77+
if (filter_count >= MAX_FILTERS) {
78+
printf("Error: Maximum number of filters reached\n");
79+
return 0;
80+
}
81+
82+
advanced_can_filter *new_filter = &filter_array[filter_count];
83+
memcpy(&new_filter->base, base_filter, sizeof(struct can_filter));
84+
new_filter->priority = priority;
85+
new_filter->timestamp = time(NULL);
86+
new_filter->signal_strength = min_signal_strength;
87+
new_filter->custom_filter_func = custom_func;
88+
89+
filter_count++;
90+
return 1;
91+
}
92+
93+
static double calculate_signal_strength(const struct can_frame *frame) {
94+
// Simulating signal strength calculation based on data bytes
95+
double strength = 0;
96+
for (int i = 0; i < frame->can_dlc; i++) {
97+
strength += (double)frame->data[i] / 255.0;
98+
}
99+
return strength / frame->can_dlc * 5.0; // Normalize to 0-5V range
100+
}
101+
102+
static int check_timing_requirements(const struct can_frame *frame, const advanced_can_filter *filter) {
103+
uint64_t current_time = time(NULL);
104+
double time_diff = difftime(current_time, filter->timestamp);
105+
106+
// Check if the frame arrives within the expected time window
107+
if (time_diff > 1.0 / SAMPLING_RATE) {
108+
printf("Frame rejected due to timing requirements\n");
109+
return 0;
110+
}
111+
return 1;
112+
}
113+
114+
static int apply_custom_filter(const struct can_frame *frame, const advanced_can_filter *filter) {
115+
if (filter->custom_filter_func != NULL) {
116+
return filter->custom_filter_func(frame);
117+
}
118+
return 1; // No custom filter function, so pass
119+
}
120+
121+
static int detect_error_frame(const struct can_frame *frame) {
122+
return (frame->can_id & CAN_ERROR_FRAME) != 0;
123+
}
124+
125+
void print_filter_stats() {
126+
printf("Current filter configuration:\n");
127+
for (int i = 0; i < filter_count; i++) {
128+
printf("Filter %d: ID=0x%X, Mask=0x%X, Priority=%d, Min Signal Strength=%.2fV\n",
129+
i, filter_array[i].base.can_id, filter_array[i].base.can_mask,
130+
filter_array[i].priority, filter_array[i].signal_strength);
131+
}
5132
}

0 commit comments

Comments
 (0)