@@ -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 } ;
@@ -110,7 +113,7 @@ impl Radio for EspRadio<'_> {
110113 TX_SIGNAL . reset ( ) ;
111114
112115 trace ! (
113- "802.15.4 TX: {} bytes ch{}" ,
116+ "802.15.4: About to TX {} bytes ch{}" ,
114117 psdu. len( ) ,
115118 self . config. channel
116119 ) ;
@@ -122,48 +125,61 @@ impl Radio for EspRadio<'_> {
122125 let success = TX_SIGNAL . wait ( ) . await ;
123126
124127 if success {
125- trace ! ( "ESP Radio, transmission done" ) ;
128+ trace ! ( "802.15.4: TX done" ) ;
126129
127130 if let Some ( ack_psdu_buf) = ack_psdu_buf {
128131 // After tx_done signal received, get the ACK frame:
129132 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- } ) ) ;
133+ if ack_frame. data . len ( ) >= 1 {
134+ // Must have at least 1 byte for PSDU
135+ let ack_psdu_len =
136+ ( ack_frame. data . len ( ) - 1 ) . min ( ( ack_frame. data [ 0 ] & 0x7f ) as usize ) ;
137+
138+ if ack_psdu_len > ack_psdu_buf. len ( ) {
139+ ack_psdu_buf[ ..ack_psdu_len]
140+ . copy_from_slice ( & ack_frame. data [ 1 ..] [ ..ack_psdu_len] ) ;
141+
142+ trace ! (
143+ "802.15.4: ACK: {} on ch{}" ,
144+ Bytes ( & ack_psdu_buf[ ..ack_psdu_len] ) ,
145+ ack_frame. channel
146+ ) ;
147+
148+ // Only read RSSI if there is at least one byte after the PSDU.
149+ let rssi = if ack_frame. data . len ( ) > 1 + ack_psdu_len {
150+ Some ( ack_frame. data [ 1 ..] [ ack_psdu_len] as i8 )
151+ } else {
152+ None
153+ } ;
154+
155+ return Ok ( Some ( PsduMeta {
156+ len : ack_psdu_len,
157+ channel : ack_frame. channel ,
158+ rssi,
159+ } ) ) ;
160+ } else {
161+ trace ! (
162+ "802.15.4: ACK frame too large for provided buffer: {} bytes" ,
163+ ack_psdu_len
164+ ) ;
165+ }
166+ }
148167 }
149168 }
150169
151170 Ok ( None )
152171 } else {
153- trace ! ( "ESP Radio, transmission failed" ) ;
172+ trace ! ( "802.15.4: TX failed" ) ;
154173
155- // Report as NoAck error so OpenThread SubMac retries
174+ // Report as a failure so OpenThread SubMac retries
156175 Err ( RadioErrorKind :: TxFailed )
157176 }
158177 }
159178
160179 async fn receive ( & mut self , psdu_buf : & mut [ u8 ] ) -> Result < PsduMeta , Self :: Error > {
161180 RX_SIGNAL . reset ( ) ;
162181
163- trace ! (
164- "ESP Radio, about to receive on channel {}" ,
165- self . config. channel
166- ) ;
182+ trace ! ( "802.15.4: About to RX on ch{}" , self . config. channel) ;
167183
168184 self . driver . start_receive ( ) ;
169185
@@ -175,13 +191,32 @@ impl Radio for EspRadio<'_> {
175191 RX_SIGNAL . wait ( ) . await ;
176192 } ;
177193
194+ if raw. data . len ( ) < 1 {
195+ // Must have at least 1 byte for PSDU
196+ return Err ( RadioErrorKind :: Other ) ;
197+ }
198+
178199 let psdu_len = ( raw. data . len ( ) - 1 ) . min ( ( raw. data [ 0 ] & 0x7f ) as usize ) ;
200+ if psdu_len > psdu_buf. len ( ) {
201+ // PSDU length is larger than the provided buffer
202+ trace ! (
203+ "802.15.4: Received frame too large for provided buffer: {} bytes" ,
204+ psdu_len
205+ ) ;
206+ return Err ( RadioErrorKind :: Other ) ;
207+ }
208+
179209 psdu_buf[ ..psdu_len] . copy_from_slice ( & raw . data[ 1 ..] [ ..psdu_len] ) ;
180210
181- let rssi = raw. data [ 1 ..] [ psdu_len] as i8 ;
211+ // Only read RSSI if there is at least one byte after the PSDU.
212+ let rssi = if raw. data . len ( ) > 1 + psdu_len {
213+ Some ( raw. data [ 1 ..] [ psdu_len] as i8 )
214+ } else {
215+ None
216+ } ;
182217
183218 trace ! (
184- "802.15.4 RX: {} bytes ch{} rssi={}" ,
219+ "802.15.4: RX {} bytes ch{} rssi={:? }" ,
185220 psdu_len,
186221 raw. channel,
187222 rssi
@@ -190,7 +225,7 @@ impl Radio for EspRadio<'_> {
190225 Ok ( PsduMeta {
191226 len : psdu_len,
192227 channel : raw. channel ,
193- rssi : Some ( rssi ) ,
228+ rssi,
194229 } )
195230 }
196231}
0 commit comments