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

Skip to content

Commit acdaa34

Browse files
committed
Receive MAC data: DHCP works
1 parent ff0fa8e commit acdaa34

File tree

5 files changed

+123
-62
lines changed

5 files changed

+123
-62
lines changed

components/80211_mac_rust/80211_mac_interface.c

+59-14
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,11 @@
1111

1212
#define IEEE80211_MAX_FRAME_LEN (2352)
1313

14+
// TODO check this is correct
15+
#define IEEE80211_MAX_PAYLOAD_LEN (2304)
16+
1417
#define NUM_TX_SMART_FRAME_BUFFERS (5)
18+
#define NUM_RX_BUFFERS (5)
1519

1620
typedef struct {
1721
void* ptr;
@@ -24,8 +28,15 @@ typedef struct {
2428
bool in_use;
2529
} smart_frame_tracker_t;
2630

31+
typedef struct {
32+
uint8_t* buffer;
33+
bool in_use;
34+
size_t buffersize;
35+
} mac_rx_frame_t;
36+
2737
static QueueHandle_t rust_mac_event_queue = NULL;
2838
smart_frame_tracker_t smart_frame_tracker_list[NUM_TX_SMART_FRAME_BUFFERS] = {{0}};
39+
mac_rx_frame_t mac_rx_frame_list[NUM_RX_BUFFERS] = {{0}};
2940
bool init_done = false;
3041

3142
void interface_init() {
@@ -41,6 +52,12 @@ void interface_init() {
4152
smart_frame_tracker_list[i].frame = smart_frame;
4253
smart_frame_tracker_list[i].in_use = false;
4354
}
55+
for (int i = 0; i < NUM_RX_BUFFERS; i++) {
56+
// TODO also allocate smaller buffers?
57+
uint8_t* buffer = malloc(IEEE80211_MAX_PAYLOAD_LEN);
58+
mac_rx_frame_t rx_frame = {.buffer = buffer, .buffersize = IEEE80211_MAX_PAYLOAD_LEN, .in_use = false};
59+
mac_rx_frame_list[i] = rx_frame;
60+
}
4461
init_done = true;
4562
}
4663

@@ -61,6 +78,42 @@ int64_t rs_get_time_us() {
6178
return esp_timer_get_time();
6279
}
6380

81+
// declaration from IP
82+
// RX'ed 802.11 packets -> RX queue of MAC stack
83+
void openmac_netif_receive(void* buffer, size_t len);
84+
85+
/*Called from the Rust MAC stack, to obtain a frame to receive MAC data in and pass it to ESP-NETIF */
86+
uint8_t* rs_get_mac_rx_frame(size_t size_required) {
87+
for (int i = 0; i < NUM_RX_BUFFERS; i++) {
88+
if (!mac_rx_frame_list[i].in_use && mac_rx_frame_list[i].buffersize >= size_required) {
89+
mac_rx_frame_list[i].in_use = true;
90+
printf("handing out %d %p\n", i, mac_rx_frame_list[i].buffer);
91+
return mac_rx_frame_list[i].buffer;
92+
}
93+
}
94+
return NULL;
95+
}
96+
97+
/*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);
100+
}
101+
102+
/*
103+
Called from the ESP-NETIF stack to recycle a MAC RX frame after it was sent. Takes ownership of the buffer.
104+
*/
105+
void c_recycle_mac_rx_frame(uint8_t* buffer) {
106+
printf("recycling %p\n", buffer);
107+
for (int i = 0; i < NUM_RX_BUFFERS; i++) {
108+
if (mac_rx_frame_list[i].buffer == buffer) {
109+
mac_rx_frame_list[i].in_use = false;
110+
return;
111+
}
112+
}
113+
// if we reached this, we somehow recycled a frame that wasn't in the list
114+
abort();
115+
}
116+
64117
/*Called from the Rust MAC stack, to obtain a smart frame from the hardware, which can then be filled in*/
65118
rs_smart_frame_t* rs_get_smart_frame(size_t size_required) {
66119
for (int i = 0; i < NUM_TX_SMART_FRAME_BUFFERS; i++) {
@@ -77,11 +130,6 @@ rs_smart_frame_t* rs_get_smart_frame(size_t size_required) {
77130
bool transmit_80211_frame(rs_smart_frame_t* frame);
78131

79132

80-
// declaration from IP
81-
// RX'ed 802.11 packets -> RX queue of MAC stack
82-
void openmac_netif_receive(void* buffer, size_t len);
83-
84-
85133
/*
86134
Called from the hardware stack to recycle a smart frame after it was sent
87135
*/
@@ -125,18 +173,15 @@ void rs_mark_iface_down() {
125173
openmac_netif_down();
126174
}
127175

128-
/*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*/
129-
void rs_rx_mac_frame(uint8_t* frame, size_t len) {
130-
openmac_netif_receive(frame, len);
131-
}
132-
133-
void rs_recycle_data_frame(uint8_t* frame) {
134-
free(frame);
176+
void rs_recycle_mac_tx_data(uint8_t* data) {
177+
free(data);
135178
}
136179

137-
// Called from the C stack to request the Rust MAC stack to TX a frame
180+
// Called from the C ESP-NETIF stack to request the Rust MAC stack to TX a frame
138181
// This function does NOT take ownership of the frame, so you're allowed to reuse the buffer directly after this returns
139182
void c_transmit_data_frame(uint8_t* frame, size_t len) {
183+
// TODO make sure we don't flood the stack by sending too much frames
184+
// maybe use a counting semaphore?
140185
void* queued_buffer = malloc(len);
141186
memcpy(queued_buffer, frame, len);
142187

@@ -145,7 +190,7 @@ void c_transmit_data_frame(uint8_t* frame, size_t len) {
145190
to_queue.ptr = queued_buffer;
146191
to_queue.len = len;
147192
if (xQueueSendToBack(rust_mac_event_queue, &to_queue, 0) != pdTRUE) {
148-
rs_recycle_data_frame(queued_buffer);
193+
rs_recycle_mac_tx_data(queued_buffer);
149194
}
150195
}
151196

components/80211_mac_rust/include/80211_mac_interface.h

+4-1
Original file line numberDiff line numberDiff line change
@@ -129,4 +129,7 @@ void c_hand_rx_to_mac_stack();
129129
int64_t rs_get_time_us();
130130

131131
void c_transmit_data_frame(uint8_t* frame, size_t len);
132-
void rs_recycle_data_frame(uint8_t* frame);
132+
void rs_recycle_mac_tx_data(uint8_t* frame);
133+
134+
uint8_t* rs_get_mac_rx_frame(size_t size_required);
135+
void c_recycle_mac_rx_frame(uint8_t* buffer);

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

+52-37
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,18 @@
11
#![no_std]
22

3-
use core::default;
43
use core::ffi::c_void;
54
use core::marker::PhantomData;
65
use core::ptr::NonNull;
76

87
use ether_type::EtherType;
98
use ieee80211::common::{
10-
CapabilitiesInformation, FCFFlags, IEEE80211AuthenticationAlgorithmNumber, IEEE80211StatusCode, SequenceControl, IEEE_OUI,
9+
CapabilitiesInformation, FCFFlags, IEEE80211AuthenticationAlgorithmNumber, IEEE80211StatusCode, SequenceControl,
1110
};
1211
use ieee80211::data_frame::header::DataFrameHeader;
1312
use ieee80211::data_frame::{DataFrame, DataFrameReadPayload};
14-
use ieee80211::elements::element_chain::ElementChainEnd;
1513
use ieee80211::elements::rsn::RSNElement;
16-
use ieee80211::elements::{DSSSParameterSetElement, SSIDElement};
17-
use ieee80211::mac_parser::{MACAddress, BROADCAST};
18-
use ieee80211::mgmt_frame::body::{AssociationRequestBody, AuthenticationBody, BeaconBody};
14+
use ieee80211::mac_parser::MACAddress;
15+
use ieee80211::mgmt_frame::body::{AssociationRequestBody, AuthenticationBody};
1916
use ieee80211::mgmt_frame::{
2017
AssociationRequestFrame, AssociationResponseFrame, AuthenticationFrame, BeaconFrame,
2118
DeauthenticationFrame, ManagementFrameHeader,
@@ -24,7 +21,7 @@ use ieee80211::scroll::ctx::{MeasureWith, TryIntoCtx};
2421
use ieee80211::scroll::{Pread, Pwrite};
2522
use ieee80211::{element_chain, match_frames, ssid, supported_rates};
2623
use llc::SnapLlcFrame;
27-
use sys::{dma_list_item, rs_event_type_t, rs_get_smart_frame, rs_rx_frame_t, rs_tx_smart_frame, rs_get_time_us};
24+
use sys::{dma_list_item, rs_event_type_t, rs_get_smart_frame, rs_tx_smart_frame, rs_get_time_us};
2825

2926
use esp_println as _;
3027
use esp_println::println;
@@ -42,11 +39,11 @@ pub mod sys {
4239
include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
4340
}
4441

45-
pub struct RxFrameWrapper {
42+
pub struct HardwareRxDataWrapper {
4643
ptr: NonNull<dma_list_item>,
4744
}
4845

49-
impl RxFrameWrapper {
46+
impl HardwareRxDataWrapper {
5047
pub fn dma(&mut self) -> &mut dma_list_item {
5148
unsafe { self.ptr.as_mut() }
5249
}
@@ -63,28 +60,28 @@ impl RxFrameWrapper {
6360
}
6461
}
6562

66-
impl Drop for RxFrameWrapper {
63+
impl Drop for HardwareRxDataWrapper {
6764
fn drop(&mut self) {
6865
unsafe {
6966
sys::rs_recycle_dma_item(self.dma());
7067
}
7168
}
7269
}
7370

74-
pub struct TxDataFrameWrapper {
71+
pub struct MacTxDataWrapper {
7572
frame: *mut u8,
7673
len: usize
7774
}
7875

79-
impl Drop for TxDataFrameWrapper {
76+
impl Drop for MacTxDataWrapper {
8077
fn drop(&mut self) {
8178
unsafe {
82-
sys::rs_recycle_data_frame(self.frame)
79+
sys::rs_recycle_mac_tx_data(self.frame)
8380
}
8481
}
8582
}
8683

87-
impl TxDataFrameWrapper {
84+
impl MacTxDataWrapper {
8885

8986
pub fn destination_mac(&mut self) -> MACAddress {
9087
// TODO check that frame is big enough!
@@ -118,9 +115,8 @@ impl TxDataFrameWrapper {
118115

119116

120117
pub enum MacEvent {
121-
PhyRx(RxFrameWrapper),
122-
MacTx(TxDataFrameWrapper),
123-
MacRecycleRx(),
118+
HardwareRx(HardwareRxDataWrapper),
119+
MacTx(MacTxDataWrapper),
124120
}
125121

126122

@@ -142,13 +138,13 @@ pub fn get_next_mac_event(timeout_ms: u32) -> Option<MacEvent> {
142138
}
143139
match event_type {
144140
rs_event_type_t::EVENT_TYPE_PHY_RX_DATA => {
145-
let wrapper: RxFrameWrapper = RxFrameWrapper {
141+
let wrapper: HardwareRxDataWrapper = HardwareRxDataWrapper {
146142
ptr: NonNull::new(data_ptr as *mut dma_list_item).unwrap(),
147143
};
148-
return Some(MacEvent::PhyRx(wrapper));
144+
return Some(MacEvent::HardwareRx(wrapper));
149145
}
150146
rs_event_type_t::EVENT_TYPE_MAC_TX_DATA_FRAME => {
151-
let wrapper: TxDataFrameWrapper = TxDataFrameWrapper {
147+
let wrapper: MacTxDataWrapper = MacTxDataWrapper {
152148
frame: data_ptr as *mut u8,
153149
len,
154150
};
@@ -158,17 +154,17 @@ pub fn get_next_mac_event(timeout_ms: u32) -> Option<MacEvent> {
158154
}
159155
}
160156

161-
pub fn transmit_frame<
157+
pub fn transmit_hardware_frame<
162158
Frame: MeasureWith<bool> + TryIntoCtx<bool, Error = ieee80211::scroll::Error>,
163159
>(
164160
frame: Frame,
165161
rate: u32,
166-
) -> Result<(), Frame> {
162+
) -> Result<(), ()> {
167163
let length = frame.measure_with(&true);
168164
let smart_frame = unsafe { rs_get_smart_frame(length) };
169165

170166
if smart_frame.is_null() {
171-
return Err(frame);
167+
return Err(());
172168
}
173169

174170
unsafe {
@@ -188,6 +184,30 @@ pub fn transmit_frame<
188184
Ok(())
189185
}
190186

187+
fn receive_mac_frame(source: MACAddress, destination: MACAddress, ether_type: EtherType, payload: &[u8]) -> Result<(), ()> {
188+
let total_length: usize = 6 + 6 + 2 + payload.len();
189+
let buffer = unsafe {sys::rs_get_mac_rx_frame(total_length)};
190+
191+
if buffer.is_null() {
192+
return Err(());
193+
}
194+
195+
let buffer = unsafe {
196+
core::slice::from_raw_parts_mut(
197+
buffer,
198+
total_length,
199+
)
200+
};
201+
202+
buffer.pwrite(destination, 0).unwrap();
203+
buffer.pwrite(source,6).unwrap();
204+
buffer.pwrite(ether_type.into_bits(), 6+6).unwrap();
205+
buffer.pwrite(payload, 6+6+2).unwrap();
206+
207+
unsafe {sys::rs_rx_mac_frame(buffer.as_mut_ptr(), buffer.len())};
208+
Ok(())
209+
}
210+
191211
pub fn get_time_us() -> i64 {
192212
return unsafe {rs_get_time_us()};
193213
}
@@ -279,7 +299,6 @@ fn handle_assoc_resp(state: &mut STAState, assoc_resp_frame: AssociationResponse
279299
}
280300

281301
fn handle_data_frame(_state: &mut STAState, data_frame: DataFrame) -> Option<()> {
282-
// TODO validate MAC address?
283302
let payload = data_frame.payload?;
284303
match payload {
285304
DataFrameReadPayload::Single(llc) => {
@@ -292,11 +311,12 @@ fn handle_data_frame(_state: &mut STAState, data_frame: DataFrame) -> Option<()>
292311
(true, false) => {
293312
// Frame from DS
294313
let destination: MACAddress = data_frame.header.address_1;
295-
let sender: MACAddress = data_frame.header.address_3;
314+
let source: MACAddress = data_frame.header.address_3;
296315
let ethertype = inner_payload.ether_type;
297316
let packet = inner_payload.payload;
298-
// TODO actually send this back up the ESP-NETIF stack
299-
// ignore for now
317+
if let Err(_) = receive_mac_frame(source, destination, ethertype, packet) {
318+
println!("Receiving MAC frame failed");
319+
}
300320
}
301321
_ => {println!("unhandled data frame from={} to={}", data_frame.header.fcf_flags.from_ds(), data_frame.header.fcf_flags.to_ds())}
302322
}
@@ -333,7 +353,7 @@ fn send_authenticate(state: &mut STAState) {
333353
_phantom: PhantomData,
334354
},
335355
};
336-
transmit_frame(auth, 0x18).unwrap();
356+
transmit_hardware_frame(auth, 0x18).unwrap();
337357
// update last sent timer
338358
if let StaMachineState::Authenticate(s) = &mut state.state {
339359
s.last_sent = Some(get_time_us());
@@ -357,14 +377,14 @@ fn send_associate(state: &mut STAState) {
357377
_phantom: PhantomData,
358378
},
359379
};
360-
transmit_frame(assoc, 12).unwrap();
380+
transmit_hardware_frame(assoc, 12).unwrap();
361381
// update last sent timer
362382
if let StaMachineState::Associate(s) = &mut state.state {
363383
s.last_sent = Some(get_time_us());
364384
};
365385
}
366386

367-
fn send_data_frame(state: &mut STAState, wrapper: &mut TxDataFrameWrapper) {
387+
fn send_data_frame(state: &mut STAState, wrapper: &mut MacTxDataWrapper) {
368388
let fcf = FCFFlags::new().with_to_ds(true);
369389

370390
let dataframe = DataFrame {
@@ -387,7 +407,7 @@ fn send_data_frame(state: &mut STAState, wrapper: &mut TxDataFrameWrapper) {
387407
}),
388408
_phantom: PhantomData,
389409
};
390-
transmit_frame(dataframe, 12).unwrap();
410+
transmit_hardware_frame(dataframe, 12).unwrap();
391411
}
392412

393413
// handles whatever we need to do with the current state, then return the amount of ms to wait if no external events happen
@@ -440,7 +460,7 @@ pub extern "C" fn rust_mac_task() -> *const c_void {
440460
let a = get_next_mac_event(wait_for);
441461
match a {
442462
Some(event) => match event {
443-
MacEvent::PhyRx(mut wrapper) => {
463+
MacEvent::HardwareRx(mut wrapper) => {
444464
println!("RX frame");
445465
let payload = wrapper.payload();
446466
let res = match_frames! {
@@ -459,7 +479,6 @@ pub extern "C" fn rust_mac_task() -> *const c_void {
459479
}
460480
data_frame = DataFrame => {
461481
handle_data_frame(&mut state, data_frame);
462-
println!("TODO data frame")
463482
}
464483
_ = DeauthenticationFrame => {
465484
println!("TODO deauth")
@@ -471,7 +490,6 @@ pub extern "C" fn rust_mac_task() -> *const c_void {
471490
}
472491
}
473492
MacEvent::MacTx(mut wrapper) => {
474-
475493
match state.state {
476494
StaMachineState::Associated => {
477495
send_data_frame(&mut state, &mut wrapper);
@@ -481,9 +499,6 @@ pub extern "C" fn rust_mac_task() -> *const c_void {
481499
}
482500
}
483501
}
484-
_ => {
485-
println!("other event")
486-
}
487502
},
488503
None => {}
489504
}

0 commit comments

Comments
 (0)