4
4
5
5
use byte:: { check_len, BytesExt , TryRead , TryWrite } ;
6
6
use core:: convert:: From ;
7
- use core:: mem;
8
7
9
8
use crate :: mac:: { ExtendedAddress , ShortAddress } ;
10
9
@@ -40,11 +39,11 @@ impl From<BeaconOrder> for u8 {
40
39
}
41
40
}
42
41
43
- /// Superframe order, amount of time during wich this superframe is active
42
+ /// Superframe order, amount of time during which this superframe is active
44
43
#[ derive( Clone , Copy , Debug , Eq , Hash , PartialEq ) ]
45
44
#[ cfg_attr( feature = "defmt" , derive( defmt:: Format ) ) ]
46
45
pub enum SuperframeOrder {
47
- /// Ammount of time that the superframe is active
46
+ /// Amount of time that the superframe is active
48
47
///
49
48
/// superframe duration = base superframe duration × (2 ^ superframe order)
50
49
SuperframeOrder ( u8 ) ,
@@ -83,15 +82,15 @@ pub struct SuperframeSpecification {
83
82
///
84
83
/// Beacon interval = BaseSuperframeDuration × (2 ^ BeaconOrder)
85
84
pub beacon_order : BeaconOrder ,
86
- /// Superframe order, amount of time during wich this superframe is active
85
+ /// Superframe order, amount of time during which this superframe is active
87
86
pub superframe_order : SuperframeOrder ,
88
87
/// final contention access period slot used
89
88
pub final_cap_slot : u8 ,
90
89
/// Limit receiving of beacons for a period. Not used if beacon_order is OnDemand.
91
90
pub battery_life_extension : bool ,
92
91
/// Frame sent by a coordinator
93
92
pub pan_coordinator : bool ,
94
- /// The coordinator acceppts associations to the PAN
93
+ /// The coordinator accepts associations to the PAN
95
94
pub association_permit : bool ,
96
95
}
97
96
@@ -156,7 +155,7 @@ impl TryWrite for SuperframeSpecification {
156
155
/// Direction of data
157
156
#[ derive( Clone , Copy , Debug , Eq , Hash , PartialEq ) ]
158
157
#[ cfg_attr( feature = "defmt" , derive( defmt:: Format ) ) ]
159
- enum Direction {
158
+ pub enum Direction {
160
159
/// Receive data
161
160
Receive ,
162
161
/// Transmit data
@@ -168,13 +167,13 @@ enum Direction {
168
167
#[ cfg_attr( feature = "defmt" , derive( defmt:: Format ) ) ]
169
168
pub struct GuaranteedTimeSlotDescriptor {
170
169
/// Device short address used by this slot
171
- short_address : ShortAddress ,
170
+ pub short_address : ShortAddress ,
172
171
/// Slot start
173
- starting_slot : u8 ,
172
+ pub starting_slot : u8 ,
174
173
/// Slot length
175
- length : u8 ,
174
+ pub length : u8 ,
176
175
/// Direction of the slot, either transmit or receive
177
- direction : Direction ,
176
+ pub direction : Direction ,
178
177
}
179
178
180
179
impl GuaranteedTimeSlotDescriptor {
@@ -234,46 +233,44 @@ const COUNT_MASK: u8 = 0b0000_0111;
234
233
const PERMIT : u8 = 0b1000_0000 ;
235
234
236
235
/// Information of the guaranteed time slots (GTSs)
237
- #[ derive( Clone , Copy , Debug , Eq , Hash , PartialEq ) ]
236
+ #[ derive( Clone , Debug , Eq , Hash , PartialEq ) ]
238
237
#[ cfg_attr( feature = "defmt" , derive( defmt:: Format ) ) ]
239
238
pub struct GuaranteedTimeSlotInformation {
240
239
/// Permit GTS
241
240
pub permit : bool ,
242
- slot_count : usize ,
243
- slots : [ GuaranteedTimeSlotDescriptor ; 7 ] ,
241
+ /// Time slot information
242
+ pub slots : heapless :: Vec < GuaranteedTimeSlotDescriptor , 7 > ,
244
243
}
245
244
246
245
impl GuaranteedTimeSlotInformation {
247
246
/// Create a new empty GTS information
248
247
pub fn new ( ) -> Self {
249
248
GuaranteedTimeSlotInformation {
250
249
permit : false ,
251
- slot_count : 0 ,
252
- slots : [ GuaranteedTimeSlotDescriptor :: new ( ) ; 7 ] ,
250
+ slots : heapless:: Vec :: new ( ) ,
253
251
}
254
252
}
255
253
256
254
/// Get the slots as a slice
257
255
pub fn slots ( & self ) -> & [ GuaranteedTimeSlotDescriptor ] {
258
- & self . slots [ .. self . slot_count ]
256
+ self . slots . as_slice ( )
259
257
}
260
258
}
261
259
262
260
impl TryWrite for GuaranteedTimeSlotInformation {
263
261
fn try_write ( self , bytes : & mut [ u8 ] , _ctx : ( ) ) -> byte:: Result < usize > {
264
262
let offset = & mut 0 ;
265
- assert ! ( self . slot_count <= 7 ) ;
263
+ assert ! ( self . slots . capacity ( ) <= 7 ) ;
266
264
let permit = if self . permit { PERMIT } else { 0 } ;
267
265
268
- let header = ( ( self . slot_count as u8 ) & COUNT_MASK ) | permit;
266
+ let header = ( ( self . slots . len ( ) as u8 ) & COUNT_MASK ) | permit;
269
267
bytes. write ( offset, header) ?;
270
268
271
- if self . slot_count > 0 {
269
+ if ! self . slots . is_empty ( ) {
272
270
let direction_mask = {
273
271
let mut dir = 0x01 ;
274
272
let mut direction_mask = 0u8 ;
275
- for n in 0 ..self . slot_count {
276
- let slot = self . slots [ n] ;
273
+ for slot in & self . slots {
277
274
if slot. direction_transmit ( ) {
278
275
direction_mask = direction_mask | dir;
279
276
}
@@ -284,8 +281,8 @@ impl TryWrite for GuaranteedTimeSlotInformation {
284
281
285
282
bytes. write ( offset, direction_mask) ?;
286
283
287
- for n in 0 .. self . slot_count {
288
- bytes. write ( offset, self . slots [ n ] ) ?;
284
+ for slot in self . slots {
285
+ bytes. write ( offset, slot ) ?;
289
286
}
290
287
}
291
288
Ok ( * offset)
@@ -298,16 +295,12 @@ impl TryRead<'_> for GuaranteedTimeSlotInformation {
298
295
let byte: u8 = bytes. read ( offset) ?;
299
296
let slot_count = ( byte & COUNT_MASK ) as usize ;
300
297
let permit = ( byte & PERMIT ) == PERMIT ;
301
- let mut slots = [ GuaranteedTimeSlotDescriptor {
302
- short_address : ShortAddress :: broadcast ( ) ,
303
- starting_slot : 0 ,
304
- length : 0 ,
305
- direction : Direction :: Receive ,
306
- } ; 7 ] ;
298
+ let mut slots = heapless:: Vec :: new ( ) ;
299
+ assert ! ( slot_count <= slots. capacity( ) ) ;
307
300
if slot_count > 0 {
308
301
check_len ( & bytes[ * offset..] , 2 + ( 3 * slot_count) ) ?;
309
302
let mut direction_mask: u8 = bytes. read ( offset) ?;
310
- for n in 0 ..slot_count {
303
+ for _ in 0 ..slot_count {
311
304
let mut slot: GuaranteedTimeSlotDescriptor =
312
305
bytes. read ( offset) ?;
313
306
let direction = if direction_mask & 0b1 == 0b1 {
@@ -317,17 +310,12 @@ impl TryRead<'_> for GuaranteedTimeSlotInformation {
317
310
} ;
318
311
slot. set_direction ( direction) ;
319
312
direction_mask = direction_mask >> 1 ;
320
- slots[ n] = slot;
313
+ slots. push ( slot) . expect (
314
+ "slot_count can never be larger than Vec::capacity" ,
315
+ ) ;
321
316
}
322
317
}
323
- Ok ( (
324
- Self {
325
- permit,
326
- slot_count,
327
- slots,
328
- } ,
329
- * offset,
330
- ) )
318
+ Ok ( ( Self { permit, slots } , * offset) )
331
319
}
332
320
}
333
321
@@ -338,7 +326,7 @@ const EXTENDED_MASK: u8 = 0b0111_0000;
338
326
///
339
327
/// Addresses to devices that has pending messages with the coordinator
340
328
///
341
- /// ```notrust
329
+ /// ```txt
342
330
/// +--------+-----------------+--------------------+
343
331
/// | Header | Short Addresses | Extended Addresses |
344
332
/// +--------+-----------------+--------------------+
@@ -347,64 +335,66 @@ const EXTENDED_MASK: u8 = 0b0111_0000;
347
335
///
348
336
/// ## Header
349
337
///
350
- /// ```notrust
338
+ /// ```txt
351
339
/// +-------------+----------+----------------+----------+
352
340
/// | Short Count | Reserved | Extended Count | Reserved |
353
341
/// +-------------+----------+----------------+----------+
354
342
/// 0 - 2 3 4 - 6 7 bit
355
343
/// ```
356
- #[ derive( Clone , Copy , Debug , Eq , Hash , PartialEq ) ]
344
+ #[ derive( Clone , Default , Debug , Eq , Hash , PartialEq ) ]
357
345
#[ cfg_attr( feature = "defmt" , derive( defmt:: Format ) ) ]
358
346
pub struct PendingAddress {
359
- short_address_count : usize ,
360
- short_addresses : [ ShortAddress ; 7 ] ,
361
- extended_address_count : usize ,
362
- extended_addresses : [ ExtendedAddress ; 7 ] ,
347
+ /// List of pending [`ShortAddress`]es
348
+ pub short_addresses : heapless :: Vec < ShortAddress , 7 > ,
349
+ /// List of pending [`ExtendedAddress`]es
350
+ pub extended_addresses : heapless :: Vec < ExtendedAddress , 7 > ,
363
351
}
364
352
365
353
impl PendingAddress {
366
354
/// Create a new empty PendingAddress struct
367
- pub fn new ( ) -> Self {
368
- PendingAddress {
369
- short_address_count : 0 ,
370
- short_addresses : [ ShortAddress :: broadcast ( ) ; 7 ] ,
371
- extended_address_count : 0 ,
372
- extended_addresses : [ ExtendedAddress :: broadcast ( ) ; 7 ] ,
355
+ pub const fn new ( ) -> Self {
356
+ Self {
357
+ short_addresses : heapless:: Vec :: new ( ) ,
358
+ extended_addresses : heapless:: Vec :: new ( ) ,
373
359
}
374
360
}
375
361
376
362
/// Get the short addresses
377
363
pub fn short_addresses ( & self ) -> & [ ShortAddress ] {
378
- & self . short_addresses [ .. self . short_address_count ]
364
+ self . short_addresses . as_slice ( )
379
365
}
380
366
/// Get the extended address
381
367
pub fn extended_addresses ( & self ) -> & [ ExtendedAddress ] {
382
- & self . extended_addresses [ .. self . extended_address_count ]
368
+ self . extended_addresses . as_slice ( )
383
369
}
384
370
}
385
371
386
372
impl TryRead < ' _ > for PendingAddress {
387
373
fn try_read ( bytes : & [ u8 ] , _ctx : ( ) ) -> byte:: Result < ( Self , usize ) > {
388
374
let offset = & mut 0 ;
389
- let ss = mem :: size_of :: < ShortAddress > ( ) ;
390
- let es = mem :: size_of :: < ExtendedAddress > ( ) ;
375
+ let ss = size_of :: < ShortAddress > ( ) ;
376
+ let es = size_of :: < ExtendedAddress > ( ) ;
391
377
let byte: u8 = bytes. read ( offset) ?;
392
378
let sl = ( byte & SHORT_MASK ) as usize ;
393
379
let el = ( ( byte & EXTENDED_MASK ) >> 4 ) as usize ;
394
380
check_len ( & bytes[ * offset..] , ( sl * ss) + ( el * es) ) ?;
395
- let mut short_addresses = [ ShortAddress :: broadcast ( ) ; 7 ] ;
396
- for n in 0 ..sl {
397
- short_addresses[ n] = bytes. read ( offset) ?;
381
+ let mut short_addresses = heapless:: Vec :: new ( ) ;
382
+ assert ! ( sl <= short_addresses. capacity( ) ) ;
383
+ for _ in 0 ..sl {
384
+ short_addresses
385
+ . push ( bytes. read ( offset) ?)
386
+ . expect ( "sl can never be larger than 7" ) ;
398
387
}
399
- let mut extended_addresses = [ ExtendedAddress :: broadcast ( ) ; 7 ] ;
400
- for n in 0 ..el {
401
- extended_addresses[ n] = bytes. read ( offset) ?;
388
+ let mut extended_addresses = heapless:: Vec :: new ( ) ;
389
+ assert ! ( el <= extended_addresses. capacity( ) ) ;
390
+ for _ in 0 ..el {
391
+ extended_addresses
392
+ . push ( bytes. read ( offset) ?)
393
+ . expect ( "el can never be larger than 7" ) ;
402
394
}
403
395
Ok ( (
404
396
Self {
405
- short_address_count : sl,
406
397
short_addresses,
407
- extended_address_count : el,
408
398
extended_addresses,
409
399
} ,
410
400
* offset,
@@ -415,31 +405,30 @@ impl TryRead<'_> for PendingAddress {
415
405
impl TryWrite for PendingAddress {
416
406
fn try_write ( self , bytes : & mut [ u8 ] , _ctx : ( ) ) -> byte:: Result < usize > {
417
407
let offset = & mut 0 ;
418
- assert ! ( self . short_address_count <= 7 ) ;
419
- assert ! ( self . extended_address_count <= 7 ) ;
408
+ assert ! ( self . short_addresses . capacity ( ) <= 7 ) ;
409
+ assert ! ( self . extended_addresses . capacity ( ) <= 7 ) ;
420
410
421
- let sl = self . short_address_count ;
422
- let el = self . extended_address_count ;
411
+ let sl = self . short_addresses . len ( ) ;
412
+ let el = self . extended_addresses . len ( ) ;
423
413
424
- let it_s_magic =
425
- ( ( ( el as u8 ) << 4 ) & EXTENDED_MASK ) | ( ( sl as u8 ) & SHORT_MASK ) ; //FIXME give variable meaningful name
426
- bytes. write ( offset, it_s_magic) ?;
414
+ // Combine list lengths into one field, see Table 45 of IEEE 802.15.4-2011
415
+ let combined_lengths =
416
+ ( ( ( el as u8 ) << 4 ) & EXTENDED_MASK ) | ( ( sl as u8 ) & SHORT_MASK ) ;
417
+ bytes. write ( offset, combined_lengths) ?;
427
418
428
- for n in 0 ..self . short_address_count {
429
- let addr = self . short_addresses [ n] ;
419
+ for addr in self . short_addresses {
430
420
bytes. write ( offset, addr) ?;
431
421
}
432
422
433
- for n in 0 ..self . extended_address_count {
434
- let addr = self . extended_addresses [ n] ;
423
+ for addr in self . extended_addresses {
435
424
bytes. write ( offset, addr) ?;
436
425
}
437
426
Ok ( * offset)
438
427
}
439
428
}
440
429
441
430
/// Beacon frame
442
- #[ derive( Clone , Copy , Debug , Eq , Hash , PartialEq ) ]
431
+ #[ derive( Clone , Debug , Eq , Hash , PartialEq ) ]
443
432
#[ cfg_attr( feature = "defmt" , derive( defmt:: Format ) ) ]
444
433
pub struct Beacon {
445
434
/// Superframe specification
@@ -477,6 +466,7 @@ impl TryWrite for Beacon {
477
466
#[ cfg( test) ]
478
467
mod tests {
479
468
use super :: * ;
469
+ use heapless:: Vec ;
480
470
481
471
#[ test]
482
472
fn decode_superframe_specification ( ) {
@@ -632,29 +622,25 @@ mod tests {
632
622
association_permit : true ,
633
623
} ;
634
624
635
- let mut slots = [ GuaranteedTimeSlotDescriptor :: new ( ) ; 7 ] ;
636
- slots[ 0 ] = GuaranteedTimeSlotDescriptor {
625
+ let slots = Vec :: from_slice ( & [ GuaranteedTimeSlotDescriptor {
637
626
short_address : ShortAddress ( 0x1234 ) ,
638
627
starting_slot : 1 ,
639
628
length : 1 ,
640
629
direction : Direction :: Transmit ,
641
- } ;
630
+ } ] )
631
+ . unwrap ( ) ;
642
632
643
633
let guaranteed_time_slot_info = GuaranteedTimeSlotInformation {
644
634
permit : true ,
645
- slot_count : 1 ,
646
635
slots,
647
636
} ;
648
637
649
- let mut short_addresses = [ ShortAddress :: broadcast ( ) ; 7 ] ;
650
- short_addresses[ 0 ] = ShortAddress ( 0x7856 ) ;
651
- let mut extended_addresses = [ ExtendedAddress :: broadcast ( ) ; 7 ] ;
652
- extended_addresses[ 0 ] = ExtendedAddress ( 0xaec24a1c2116e260 ) ;
638
+ let short_addresses = Vec :: from_slice ( & [ ShortAddress ( 0x7856 ) ] ) . unwrap ( ) ;
639
+ let extended_addresses =
640
+ Vec :: from_slice ( & [ ExtendedAddress ( 0xaec24a1c2116e260 ) ] ) . unwrap ( ) ;
653
641
654
642
let pending_address = PendingAddress {
655
- short_address_count : 1 ,
656
643
short_addresses,
657
- extended_address_count : 1 ,
658
644
extended_addresses,
659
645
} ;
660
646
0 commit comments