Wait for first uplink for Class-C scheduling.

This commit is contained in:
Orne Brocaar 2023-07-19 11:27:55 +01:00
parent f66186bb7b
commit f930bd6b96
2 changed files with 39 additions and 3 deletions

View File

@ -291,6 +291,7 @@ impl Data {
ctx.select_downlink_gateway()?;
if ctx._is_class_c() {
ctx.check_for_first_uplink()?;
ctx.get_class_c_device_lock().await?;
ctx.set_immediately()?;
ctx.set_tx_info_for_rx2()?;
@ -705,7 +706,7 @@ impl Data {
// this is not an ACK, then DownlinkDataMIC will zero out ConfFCnt.
phy.set_downlink_data_mic(
self.device_session.mac_version().from_proto(),
self.device_session.f_cnt_up - 1,
self.device_session.f_cnt_up.overflowing_sub(1).0,
&lrwn::AES128Key::from_slice(&self.device_session.s_nwk_s_int_key)?,
)
.context("Set downlink data MIC")?;
@ -861,6 +862,16 @@ impl Data {
Ok(())
}
fn check_for_first_uplink(&self) -> Result<()> {
trace!("Checking if device has sent its first uplink already");
if self.device_session.f_cnt_up == 0 {
return Err(anyhow!("Device must send its first uplink first"));
}
Ok(())
}
async fn get_class_c_device_lock(&self) -> Result<()> {
trace!("Getting Class-C device lock");
let conf = config::get();

View File

@ -105,6 +105,31 @@ async fn test_downlink_scheduler() {
..Default::default()
};
let ds_no_uplink = internal::DeviceSession {
f_cnt_up: 0,
..ds.clone()
};
run_scheduler_test(&DownlinkTest {
name: "device has not yet sent an uplink".into(),
device_queue_items: vec![device_queue::DeviceQueueItem {
id: Uuid::nil(),
dev_eui: dev.dev_eui.clone(),
f_port: 10,
data: vec![1, 2, 3],
..Default::default()
}],
device_session: Some(ds_no_uplink.clone()),
device_gateway_rx_info: Some(device_gateway_rx_info.clone()),
assert: vec![assert::no_downlink_frame()],
})
.await;
// remove the schedule run after
device::set_scheduler_run_after(&dev.dev_eui.clone(), None)
.await
.unwrap();
run_scheduler_test(&DownlinkTest {
name: "unconfirmed data".into(),
device_queue_items: vec![device_queue::DeviceQueueItem {
@ -172,7 +197,7 @@ async fn test_downlink_scheduler() {
.unwrap();
run_scheduler_test(&DownlinkTest {
name: "cunconfirmed data".into(),
name: "unconfirmed data".into(),
device_queue_items: vec![device_queue::DeviceQueueItem {
id: Uuid::nil(),
dev_eui: dev.dev_eui.clone(),
@ -226,7 +251,7 @@ async fn test_downlink_scheduler() {
.unwrap();
run_scheduler_test(&DownlinkTest {
name: "cunconfirmed data".into(),
name: "unconfirmed data".into(),
device_queue_items: vec![device_queue::DeviceQueueItem {
id: Uuid::nil(),
dev_eui: dev.dev_eui.clone(),