| 9 | use crate::uplink::{UplinkFrameSet, helpers}; |
| 10 | |
| 11 | pub fn handle( |
| 12 | uplink_frame_set: &UplinkFrameSet, |
| 13 | dev: &device::Device, |
| 14 | block: &lrwn::MACCommandSet, |
| 15 | ) -> Result<Option<lrwn::MACCommandSet>> { |
| 16 | let _ = (**block) |
| 17 | .first() |
| 18 | .ok_or_else(|| anyhow!("Expected DeviceTimeReq"))?; |
| 19 | |
| 20 | let rx_time: DateTime<Utc> = helpers::get_rx_timestamp(&uplink_frame_set.rx_info_set).into(); |
| 21 | let gps_time = rx_time.to_gps_time(); |
| 22 | |
| 23 | info!(dev_eui = %dev.dev_eui, rx_time = %rx_time, gps_time = %gps_time.num_seconds(), "DeviceTimeReq received"); |
| 24 | |
| 25 | Ok(Some(lrwn::MACCommandSet::new(vec![ |
| 26 | lrwn::MACCommand::DeviceTimeAns(lrwn::DeviceTimeAnsPayload { |
| 27 | time_since_gps_epoch: match gps_time.to_std() { |
| 28 | Ok(v) => v, |
| 29 | Err(e) => { |
| 30 | warn!(error = %e, "To GPS time error"); |
| 31 | Duration::from_secs(0) |
| 32 | } |
| 33 | }, |
| 34 | }), |
| 35 | ]))) |
| 36 | } |
| 37 | |
| 38 | #[cfg(test)] |
| 39 | pub mod test { |