@@ -63,6 +63,9 @@ impl<'a> EspRadio<'a> {
6363 pan_id : config. pan_id ,
6464 short_addr : config. short_addr ,
6565 ext_addr : config. ext_addr ,
66+ // The default of 10 is too small for OpenThread,
67+ // which can have bursts of incoming frames, so we increase it to 50.
68+ // TODO: See if we can get by with a smaller number to save memory.
6669 rx_queue_size : 50 ,
6770 ..Default :: default ( )
6871 } ;
@@ -86,7 +89,10 @@ impl<'a> EspRadio<'a> {
8689impl Radio for EspRadio < ' _ > {
8790 type Error = RadioErrorKind ;
8891
89- const CAPS : Capabilities = Capabilities :: ACK_TIMEOUT . union ( Capabilities :: CSMA_BACKOFF ) /* TODO: Depends on coex being off .union(Capabilities::RX_WHEN_IDLE) */ ;
92+ const CAPS : Capabilities = Capabilities :: ACK_TIMEOUT
93+ . union ( Capabilities :: CSMA_BACKOFF )
94+ // .union(Capabilities::RX_ON_WHEN_IDLE) TODO: Depends on coex being off in ESP-IDF
95+ ;
9096
9197 const MAC_CAPS : MacCapabilities = MacCapabilities :: all ( ) ;
9298
@@ -110,7 +116,7 @@ impl Radio for EspRadio<'_> {
110116 TX_SIGNAL . reset ( ) ;
111117
112118 trace ! (
113- "802.15.4 TX: {} bytes ch{}" ,
119+ "802.15.4: About to TX {} bytes ch{}" ,
114120 psdu. len( ) ,
115121 self . config. channel
116122 ) ;
@@ -122,48 +128,61 @@ impl Radio for EspRadio<'_> {
122128 let success = TX_SIGNAL . wait ( ) . await ;
123129
124130 if success {
125- trace ! ( "ESP Radio, transmission done" ) ;
131+ trace ! ( "802.15.4: TX done" ) ;
126132
127133 if let Some ( ack_psdu_buf) = ack_psdu_buf {
128134 // After tx_done signal received, get the ACK frame:
129135 if let Some ( ack_frame) = self . driver . get_ack_frame ( ) {
130- let ack_psdu_len =
131- ( ack_frame. data . len ( ) - 1 ) . min ( ( ack_frame. data [ 0 ] & 0x7f ) as usize ) ;
132- ack_psdu_buf[ ..ack_psdu_len]
133- . copy_from_slice ( & ack_frame. data [ 1 ..] [ ..ack_psdu_len] ) ;
134-
135- trace ! (
136- "ESP Radio, received ACK: {} on channel {}" ,
137- Bytes ( & ack_psdu_buf[ ..ack_psdu_len] ) ,
138- ack_frame. channel
139- ) ;
140-
141- let rssi = ack_frame. data [ 1 ..] [ ack_psdu_len] as i8 ;
142-
143- return Ok ( Some ( PsduMeta {
144- len : ack_psdu_len,
145- channel : ack_frame. channel ,
146- rssi : Some ( rssi) ,
147- } ) ) ;
136+ if ack_frame. data . len ( ) >= 1 {
137+ // Must have at least 1 byte for PSDU
138+ let ack_psdu_len =
139+ ( ack_frame. data . len ( ) - 1 ) . min ( ( ack_frame. data [ 0 ] & 0x7f ) as usize ) ;
140+
141+ if ack_psdu_len <= ack_psdu_buf. len ( ) {
142+ ack_psdu_buf[ ..ack_psdu_len]
143+ . copy_from_slice ( & ack_frame. data [ 1 ..] [ ..ack_psdu_len] ) ;
144+
145+ trace ! (
146+ "802.15.4: ACK: {} on ch{}" ,
147+ Bytes ( & ack_psdu_buf[ ..ack_psdu_len] ) ,
148+ ack_frame. channel
149+ ) ;
150+
151+ // Only read RSSI if there is at least one byte after the PSDU.
152+ let rssi = if ack_frame. data . len ( ) > 1 + ack_psdu_len {
153+ Some ( ack_frame. data [ 1 ..] [ ack_psdu_len] as i8 )
154+ } else {
155+ None
156+ } ;
157+
158+ return Ok ( Some ( PsduMeta {
159+ len : ack_psdu_len,
160+ channel : ack_frame. channel ,
161+ rssi,
162+ } ) ) ;
163+ } else {
164+ trace ! (
165+ "802.15.4: ACK frame too large for provided buffer: {} bytes" ,
166+ ack_psdu_len
167+ ) ;
168+ }
169+ }
148170 }
149171 }
150172
151173 Ok ( None )
152174 } else {
153- trace ! ( "ESP Radio, transmission failed" ) ;
175+ trace ! ( "802.15.4: TX failed" ) ;
154176
155- // Report as NoAck error so OpenThread SubMac retries
177+ // Report as a failure so OpenThread SubMac retries
156178 Err ( RadioErrorKind :: TxFailed )
157179 }
158180 }
159181
160182 async fn receive ( & mut self , psdu_buf : & mut [ u8 ] ) -> Result < PsduMeta , Self :: Error > {
161183 RX_SIGNAL . reset ( ) ;
162184
163- trace ! (
164- "ESP Radio, about to receive on channel {}" ,
165- self . config. channel
166- ) ;
185+ trace ! ( "802.15.4: About to RX on ch{}" , self . config. channel) ;
167186
168187 self . driver . start_receive ( ) ;
169188
@@ -175,13 +194,32 @@ impl Radio for EspRadio<'_> {
175194 RX_SIGNAL . wait ( ) . await ;
176195 } ;
177196
197+ if raw. data . len ( ) < 1 {
198+ // Must have at least 1 byte for PSDU
199+ return Err ( RadioErrorKind :: Other ) ;
200+ }
201+
178202 let psdu_len = ( raw. data . len ( ) - 1 ) . min ( ( raw. data [ 0 ] & 0x7f ) as usize ) ;
203+ if psdu_len > psdu_buf. len ( ) {
204+ // PSDU length is larger than the provided buffer
205+ trace ! (
206+ "802.15.4: Received frame too large for provided buffer: {} bytes" ,
207+ psdu_len
208+ ) ;
209+ return Err ( RadioErrorKind :: Other ) ;
210+ }
211+
179212 psdu_buf[ ..psdu_len] . copy_from_slice ( & raw . data[ 1 ..] [ ..psdu_len] ) ;
180213
181- let rssi = raw. data [ 1 ..] [ psdu_len] as i8 ;
214+ // Only read RSSI if there is at least one byte after the PSDU.
215+ let rssi = if raw. data . len ( ) > 1 + psdu_len {
216+ Some ( raw. data [ 1 ..] [ psdu_len] as i8 )
217+ } else {
218+ None
219+ } ;
182220
183221 trace ! (
184- "802.15.4 RX: {} bytes ch{} rssi={}" ,
222+ "802.15.4: RX {} bytes ch{} rssi={:? }" ,
185223 psdu_len,
186224 raw. channel,
187225 rssi
@@ -190,7 +228,7 @@ impl Radio for EspRadio<'_> {
190228 Ok ( PsduMeta {
191229 len : psdu_len,
192230 channel : raw. channel ,
193- rssi : Some ( rssi ) ,
231+ rssi,
194232 } )
195233 }
196234}
0 commit comments