Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 3da45b8

Browse files
committed
Start work on dual virtual interfaces
1 parent 214d8a0 commit 3da45b8

File tree

5 files changed

+80
-34
lines changed

5 files changed

+80
-34
lines changed

components/80211_mac_rust/80211_mac_interface.c

+10-10
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ int64_t rs_get_time_us() {
8080

8181
// declaration from IP
8282
// RX'ed 802.11 packets -> RX queue of MAC stack
83-
void openmac_netif_receive(void* buffer, size_t len);
83+
void openmac_netif_receive(rs_mac_interface_type_t interface, void* buffer, size_t len);
8484

8585
/*Called from the Rust MAC stack, to obtain a frame to receive MAC data in and pass it to ESP-NETIF */
8686
uint8_t* rs_get_mac_rx_frame(size_t size_required) {
@@ -95,8 +95,8 @@ uint8_t* rs_get_mac_rx_frame(size_t size_required) {
9595
}
9696

9797
/*Called from the Rust MAC stack, to pass a previously obtained data frame buffer to ESP-NETIF. Expects the frame to be in Ethernet format. Does not take ownership of the data*/
98-
void rs_rx_mac_frame(uint8_t* frame, size_t len) {
99-
openmac_netif_receive(frame, len);
98+
void rs_rx_mac_frame(rs_mac_interface_type_t interface, uint8_t* frame, size_t len) {
99+
openmac_netif_receive(interface, frame, len);
100100
}
101101

102102
/*
@@ -168,15 +168,15 @@ void c_hand_rx_to_mac_stack(dma_list_item* item) {
168168
}
169169
}
170170

171-
void openmac_netif_up();
172-
void openmac_netif_down();
171+
void openmac_netif_up(rs_mac_interface_type_t interface);
172+
void openmac_netif_down(rs_mac_interface_type_t interface);
173173

174-
void rs_mark_iface_up() {
175-
openmac_netif_up();
174+
void rs_mark_iface_up(rs_mac_interface_type_t interface) {
175+
openmac_netif_up(interface);
176176
}
177177

178-
void rs_mark_iface_down() {
179-
openmac_netif_down();
178+
void rs_mark_iface_down(rs_mac_interface_type_t interface) {
179+
openmac_netif_down(interface);
180180
}
181181

182182
void rs_recycle_mac_tx_data(uint8_t* data) {
@@ -202,7 +202,7 @@ void rs_filters_set_client_with_bssid(const uint8_t* addr) {
202202

203203
// Called from the C ESP-NETIF stack to request the Rust MAC stack to TX a frame
204204
// This function does NOT take ownership of the frame, so you're allowed to reuse the buffer directly after this returns
205-
void c_transmit_data_frame(uint8_t* frame, size_t len) {
205+
void c_transmit_data_frame(rs_mac_interface_type_t interface, uint8_t* frame, size_t len) {
206206
// TODO make sure we don't flood the stack by sending too much frames
207207
// maybe use a counting semaphore?
208208
void* queued_buffer = malloc(len);

components/80211_mac_rust/include/80211_mac_interface.h

+9-5
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44
#include <stdbool.h>
55
#include <stddef.h>
66

7+
// Number of virtual interfaces the hardware supports
8+
// See https://esp32-open-mac.be/posts/0008-rx-filter/
9+
#define NUM_VIRTUAL_INTERFACES (2)
10+
711
#define CONFIG_IDF_TARGET_ESP32 1
812

913
/** @brief Received packet radio metadata header, this is the common header at the beginning of all promiscuous mode RX callback buffers */
@@ -78,7 +82,7 @@ typedef enum {
7882
STA_2_MAC_INTERFACE_TYPE,
7983
AP_1_MAC_INTERFACE_TYPE,
8084
AP_2_MAC_INTERFACE_TYPE,
81-
} mac_interface_type_t;
85+
} rs_mac_interface_type_t;
8286

8387
typedef enum {
8488
EVENT_TYPE_MAC_TX_DATA_FRAME,
@@ -117,13 +121,13 @@ rs_smart_frame_t* rs_get_smart_frame(size_t size_hint);
117121
void rs_tx_smart_frame(rs_smart_frame_t* frame);
118122

119123
/*Called from the Rust MAC stack, to pass a data frame to the IP stack. Expects the frame to be in Ethernet format. Does not take ownership of the data*/
120-
void rs_rx_mac_frame(uint8_t* frame, size_t len);
124+
void rs_rx_mac_frame(rs_mac_interface_type_t interface, uint8_t* frame, size_t len);
121125

122126
void rs_recycle_dma_item(dma_list_item* item);
123127

124128

125-
void rs_mark_iface_up();
126-
void rs_mark_iface_down();
129+
void rs_mark_iface_up(rs_mac_interface_type_t interface);
130+
void rs_mark_iface_down(rs_mac_interface_type_t interface);
127131

128132
/*
129133
Called from the hardware stack to recycle a smart frame after it was sent
@@ -137,7 +141,7 @@ void c_hand_rx_to_mac_stack();
137141

138142
int64_t rs_get_time_us();
139143

140-
void c_transmit_data_frame(uint8_t* frame, size_t len);
144+
void c_transmit_data_frame(rs_mac_interface_type_t interface, uint8_t* frame, size_t len);
141145
void rs_recycle_mac_tx_data(uint8_t* frame);
142146

143147
uint8_t* rs_get_mac_rx_frame(size_t size_required);

components/80211_mac_rust/rust_crate/build.rs

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ fn run_bindgen(target: &str, out_dir: &Path) {
1717
.header(header)
1818
.allowlist_item(r#"(rs_.*)"#)
1919
.rustified_enum("rs_event_type_t")
20+
.rustified_enum("rs_mac_interface_type_t")
2021
.allowlist_item("dma_list_item");
2122
match target {
2223
"riscv32imc-esp-espidf" => {

components/80211_mac_rust/rust_crate/src/lib.rs

+13-6
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,7 @@ use ieee80211::scroll::{Pread, Pwrite};
2323
use ieee80211::{element_chain, match_frames, ssid, supported_rates, GenericFrame};
2424
use llc::SnapLlcFrame;
2525
use sys::{
26-
dma_list_item, rs_event_type_t, rs_get_smart_frame, rs_get_time_us,
27-
rs_tx_smart_frame,
26+
dma_list_item, rs_event_type_t, rs_get_smart_frame, rs_get_time_us, rs_mac_interface_type_t, rs_tx_smart_frame
2827
};
2928

3029
use esp_println as _;
@@ -215,6 +214,7 @@ pub fn transmit_hardware_frame<
215214
}
216215

217216
fn receive_mac_frame(
217+
interface: sys::rs_mac_interface_type_t,
218218
source: MACAddress,
219219
destination: MACAddress,
220220
ether_type: EtherType,
@@ -234,7 +234,7 @@ fn receive_mac_frame(
234234
buffer.pwrite(ether_type.into_bits(), 6 + 6).unwrap();
235235
buffer.pwrite(payload, 6 + 6 + 2).unwrap();
236236

237-
unsafe { sys::rs_rx_mac_frame(buffer.as_mut_ptr(), buffer.len()) };
237+
unsafe { sys::rs_rx_mac_frame(interface, buffer.as_mut_ptr(), buffer.len()) };
238238
Ok(())
239239
}
240240

@@ -289,7 +289,10 @@ struct STAState {
289289
const SEQNO_WINDOW_SIZE: i32 = 32;
290290

291291
fn transition_to_scanning(state: &mut STAState) {
292-
unsafe { sys::rs_mark_iface_down() }
292+
unsafe {
293+
// TODO don't hardcode this to STA 1
294+
sys::rs_mark_iface_down(rs_mac_interface_type_t::STA_1_MAC_INTERFACE_TYPE)
295+
}
293296
unsafe { sys::rs_filters_set_scanning() }
294297
state.state = StaMachineState::Scanning(ScanningS {
295298
last_channel_change: None,
@@ -357,7 +360,10 @@ fn handle_assoc_resp(state: &mut STAState, assoc_resp_frame: AssociationResponse
357360
// yay, they accepted our association
358361
match state.state {
359362
StaMachineState::Associated => {}
360-
_ => unsafe { sys::rs_mark_iface_up() },
363+
_ => unsafe {
364+
// TODO don't hardcode this to STA 1
365+
sys::rs_mark_iface_up(rs_mac_interface_type_t::STA_1_MAC_INTERFACE_TYPE)
366+
},
361367
}
362368
state.state = StaMachineState::Associated;
363369
}
@@ -396,7 +402,8 @@ fn handle_data_frame(_state: &mut STAState, data_frame: DataFrame) -> Option<()>
396402
let source: MACAddress = data_frame.header.address_3;
397403
let ethertype = inner_payload.ether_type;
398404
let packet = inner_payload.payload;
399-
if receive_mac_frame(source, destination, ethertype, packet).is_err() {
405+
// TODO make this dynamic instead of hardcofing STA_1
406+
if receive_mac_frame(sys::rs_mac_interface_type_t::STA_1_MAC_INTERFACE_TYPE, source, destination, ethertype, packet).is_err() {
400407
println!("Receiving MAC frame failed");
401408
}
402409
}

main/mac.c

+47-13
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,26 @@ static char* TAG = "mac.c";
1717

1818
typedef struct openmac_netif_driver {
1919
esp_netif_driver_base_t base;
20-
mac_interface_type_t interface_type;
20+
rs_mac_interface_type_t interface_type;
2121
} openmac_netif_driver_t;
2222

23-
static esp_netif_t *netif_openmac_sta = NULL;
23+
static openmac_netif_driver_t* active_interfaces[NUM_VIRTUAL_INTERFACES] = {0};
2424

2525
static esp_err_t openmac_netif_transmit(void *h, void *buffer, size_t len)
2626
{
27-
uint8_t* eth_data = (uint8_t*) buffer;
28-
ESP_LOGI("netif-tx", "Going to transmit a data packet: to "MACSTR" from "MACSTR" type=%02x%02x", MAC2STR(&eth_data[0]), MAC2STR(&eth_data[6]), eth_data[12], eth_data[13]);
29-
c_transmit_data_frame(buffer, len);
30-
return ESP_OK;
27+
openmac_netif_driver_t* driver = (openmac_netif_driver_t*)h;
28+
29+
for (int i = 0; i < NUM_VIRTUAL_INTERFACES; i++) {
30+
if (active_interfaces[i] != NULL && active_interfaces[i] == driver) {
31+
uint8_t* eth_data = (uint8_t*) buffer;
32+
ESP_LOGI("netif-tx", "Going to transmit a data packet: to "MACSTR" from "MACSTR" type=%02x%02x", MAC2STR(&eth_data[0]), MAC2STR(&eth_data[6]), eth_data[12], eth_data[13]);
33+
c_transmit_data_frame(active_interfaces[i]->interface_type, buffer, len);
34+
return ESP_OK;
35+
}
36+
}
37+
ESP_LOGE(TAG, "netif_tx: failed to find vif for handle %p", h);
38+
39+
return ESP_FAIL;
3140
}
3241

3342
static esp_err_t openmac_netif_transmit_wrap(void *h, void *buffer, size_t len, void *netstack_buf)
@@ -36,18 +45,38 @@ static esp_err_t openmac_netif_transmit_wrap(void *h, void *buffer, size_t len,
3645
}
3746

3847

39-
void openmac_netif_up() {
40-
esp_netif_action_connected(netif_openmac_sta, NULL, 0, NULL);
48+
void openmac_netif_up(rs_mac_interface_type_t interface) {
49+
for (int i = 0; i < NUM_VIRTUAL_INTERFACES; i++) {
50+
if (active_interfaces[i] != NULL && active_interfaces[i]->interface_type == interface) {
51+
esp_netif_action_connected(active_interfaces[i]->base.netif, NULL, 0, NULL);
52+
return;
53+
}
54+
}
55+
ESP_LOGE(TAG, "trying to up vif %d but not active", interface);
4156
}
4257

43-
void openmac_netif_down() {
44-
esp_netif_action_disconnected(netif_openmac_sta, NULL, 0, NULL);
58+
void openmac_netif_down(rs_mac_interface_type_t interface) {
59+
for (int i = 0; i < NUM_VIRTUAL_INTERFACES; i++) {
60+
if (active_interfaces[i] != NULL && active_interfaces[i]->interface_type == interface) {
61+
esp_netif_action_disconnected(active_interfaces[i]->base.netif, NULL, 0, NULL);
62+
return;
63+
}
64+
}
65+
ESP_LOGE(TAG, "trying to down vif %d but not active", interface);
4566
}
4667

4768
// Put Ethernet-formatted frame in MAC stack; does not take ownership of the buffer: after the function returns, you can delete/reuse it.
48-
void openmac_netif_receive(void* buffer, size_t len) {
69+
void openmac_netif_receive(rs_mac_interface_type_t interface, void* buffer, size_t len) {
4970
assert(buffer != NULL);
50-
esp_netif_receive(netif_openmac_sta, buffer, len, buffer);
71+
72+
for (int i = 0; i < NUM_VIRTUAL_INTERFACES; i++) {
73+
if (active_interfaces[i] != NULL && active_interfaces[i]->interface_type == interface) {
74+
esp_netif_receive(active_interfaces[i]->base.netif, buffer, len, buffer);
75+
return;
76+
}
77+
}
78+
// If we get here, the MAC stack passed us a frame that does not have a currently active interface
79+
ESP_LOGE(TAG, "received frame for vif %d but not active", interface);
5180
}
5281

5382
// Free RX buffer
@@ -92,14 +121,19 @@ esp_err_t openmac_netif_start()
92121
.base = &base_cfg_sta,
93122
.driver = NULL,
94123
.stack = ESP_NETIF_NETSTACK_DEFAULT_WIFI_STA };
95-
netif_openmac_sta = esp_netif_new(&cfg_sta);
124+
125+
esp_netif_t* netif_openmac_sta = esp_netif_new(&cfg_sta);
96126
assert(netif_openmac_sta);
97127

98128
openmac_netif_driver_t* driver = openmac_create_if_driver();
99129
if (driver == NULL) {
100130
ESP_LOGE(TAG, "Failed to create wifi interface handle");
101131
return ESP_FAIL;
102132
}
133+
134+
driver->interface_type = STA_1_MAC_INTERFACE_TYPE;
135+
active_interfaces[0] = driver;
136+
103137
esp_netif_attach(netif_openmac_sta, driver);
104138
esp_netif_set_hostname(netif_openmac_sta, "esp32-open-mac");
105139
esp_netif_set_mac(netif_openmac_sta, module_mac_addr);

0 commit comments

Comments
 (0)