| 20 | } |
| 21 | |
| 22 | pub fn get_ping_offset(beacon_ts: Duration, dev_addr: &DevAddr, ping_nb: usize) -> Result<usize> { |
| 23 | if ping_nb == 0 { |
| 24 | return Err(anyhow!("ping_nb must be > 0")); |
| 25 | } |
| 26 | |
| 27 | let ping_period = PING_PERIOD_BASE / ping_nb; |
| 28 | let beacon_time = (beacon_ts.num_seconds() % (1 << 32)) as u32; |
| 29 | |
| 30 | let key_bytes: [u8; 16] = [0x00; 16]; |
| 31 | let key = Array::from(key_bytes); |
| 32 | let cipher = Aes128::new(&key); |
| 33 | |
| 34 | let mut b: [u8; 16] = [0x00; 16]; |
| 35 | b[0..4].clone_from_slice(&beacon_time.to_le_bytes()); |
| 36 | b[4..8].clone_from_slice(&dev_addr.to_le_bytes()); |
| 37 | |
| 38 | let mut block = Block::from(b); |
| 39 | cipher.encrypt_block(&mut block); |
| 40 | let rand = block.as_slice(); |
| 41 | |
| 42 | Ok(((rand[0] as usize) + ((rand[1] as usize) * 256)) % ping_period) |
| 43 | } |
| 44 | |
| 45 | pub fn get_next_ping_slot_after( |
| 46 | after_gps_epoch_ts: Duration, |