Align multicast class-b ping-slot config.

This aligns the multicast class-b ping-slot configuration with the way
how it is configured in the device-profile. This deprecates the
class_b_ping_slot_period field in favor of the class_b_ping_slot_nb_k
field, which should be a value between 0 - 7 (this is defined and
explained by the LoRaWAN specification).

Closes #255.
This commit is contained in:
Orne Brocaar 2024-03-26 16:45:24 +00:00
parent e96e828d3f
commit c71b856c78
10 changed files with 77 additions and 33 deletions

View File

@ -164,8 +164,15 @@ message MulticastGroup {
uint32 frequency = 11;
// Ping-slot period (only for Class-B).
// Deprecated: use class_b_ping_slot_nb_k.
uint32 class_b_ping_slot_period = 12;
// Class-B ping-slots per beacon period (only for Class-B).
// Valid options are: 0 - 7;
//
// The actual number of ping-slots per beacon period equals to 2^k.
uint32 class_b_ping_slot_nb_k = 14;
// Scheduling type (only for Class-C).
MulticastGroupSchedulingType class_c_scheduling_type = 13;
}

View File

@ -164,8 +164,15 @@ message MulticastGroup {
uint32 frequency = 11;
// Ping-slot period (only for Class-B).
// Deprecated: use class_b_ping_slot_nb_k.
uint32 class_b_ping_slot_period = 12;
// Class-B ping-slots per beacon period (only for Class-B).
// Valid options are: 0 - 7;
//
// The actual number of ping-slots per beacon period equals to 2^k.
uint32 class_b_ping_slot_nb_k = 14;
// Scheduling type (only for Class-C).
MulticastGroupSchedulingType class_c_scheduling_type = 13;
}

View File

@ -0,0 +1,8 @@
alter table multicast_group
alter column class_b_ping_slot_nb_k type integer;
update multicast_group set class_b_ping_slot_nb_k = pow(2, class_b_ping_slot_nb_k) * 32;
alter table multicast_group
rename column class_b_ping_slot_nb_k to class_b_ping_slot_period;

View File

@ -0,0 +1,8 @@
alter table multicast_group
rename column class_b_ping_slot_period to class_b_ping_slot_nb_k;
update multicast_group set class_b_ping_slot_nb_k = log(2, class_b_ping_slot_nb_k / 32);
alter table multicast_group
alter column class_b_ping_slot_nb_k type smallint;

View File

@ -61,7 +61,14 @@ impl MulticastGroupService for MulticastGroup {
.to_string(),
dr: req_mg.dr as i16,
frequency: req_mg.frequency as i64,
class_b_ping_slot_period: req_mg.class_b_ping_slot_period as i32,
class_b_ping_slot_nb_k: if req_mg.class_b_ping_slot_period != 0 {
// For backwards compatibility.
(req_mg.class_b_ping_slot_period / 32)
.checked_ilog2()
.unwrap_or_default()
} else {
req_mg.class_b_ping_slot_nb_k
} as i16,
class_c_scheduling_type: req_mg.class_c_scheduling_type().from_proto(),
..Default::default()
};
@ -114,7 +121,8 @@ impl MulticastGroupService for MulticastGroup {
.into(),
dr: mg.dr as u32,
frequency: mg.frequency as u32,
class_b_ping_slot_period: mg.class_b_ping_slot_period as u32,
class_b_ping_slot_period: (1 << (mg.class_b_ping_slot_nb_k as u32)) * 32,
class_b_ping_slot_nb_k: mg.class_b_ping_slot_nb_k as u32,
class_c_scheduling_type: mg.class_c_scheduling_type.to_proto().into(),
}),
created_at: Some(helpers::datetime_to_prost_timestamp(&mg.created_at)),
@ -160,7 +168,14 @@ impl MulticastGroupService for MulticastGroup {
.to_string(),
dr: req_mg.dr as i16,
frequency: req_mg.frequency as i64,
class_b_ping_slot_period: req_mg.class_b_ping_slot_period as i32,
class_b_ping_slot_nb_k: if req_mg.class_b_ping_slot_period != 0 {
// For backwards compatibility.
(req_mg.class_b_ping_slot_period / 32)
.checked_ilog2()
.unwrap_or_default()
} else {
req_mg.class_b_ping_slot_nb_k
} as i16,
class_c_scheduling_type: req_mg.class_c_scheduling_type().from_proto(),
..Default::default()
})
@ -579,7 +594,7 @@ pub mod test {
group_type: api::MulticastGroupType::ClassC.into(),
dr: 3,
frequency: 868300000,
class_b_ping_slot_period: 1,
class_b_ping_slot_nb_k: 1,
class_c_scheduling_type: api::MulticastGroupSchedulingType::GpsTime.into(),
..Default::default()
}),
@ -609,7 +624,8 @@ pub mod test {
group_type: api::MulticastGroupType::ClassC.into(),
dr: 3,
frequency: 868300000,
class_b_ping_slot_period: 1,
class_b_ping_slot_nb_k: 1,
class_b_ping_slot_period: 64,
class_c_scheduling_type: api::MulticastGroupSchedulingType::GpsTime.into(),
}),
get_resp.get_ref().multicast_group
@ -631,7 +647,8 @@ pub mod test {
group_type: api::MulticastGroupType::ClassB.into(),
dr: 2,
frequency: 868200000,
class_b_ping_slot_period: 2,
class_b_ping_slot_nb_k: 2,
class_b_ping_slot_period: 0,
class_c_scheduling_type: api::MulticastGroupSchedulingType::Delay.into(),
}),
},
@ -659,7 +676,8 @@ pub mod test {
group_type: api::MulticastGroupType::ClassB.into(),
dr: 2,
frequency: 868200000,
class_b_ping_slot_period: 2,
class_b_ping_slot_nb_k: 2,
class_b_ping_slot_period: 128,
class_c_scheduling_type: api::MulticastGroupSchedulingType::Delay.into(),
}),
get_resp.get_ref().multicast_group

View File

@ -376,7 +376,7 @@ pub mod test {
group_type: "C".into(),
dr: 1,
frequency: 868100000,
class_b_ping_slot_period: 1,
class_b_ping_slot_nb_k: 1,
..Default::default()
})
.await

View File

@ -33,7 +33,7 @@ pub struct MulticastGroup {
pub group_type: String,
pub dr: i16,
pub frequency: i64,
pub class_b_ping_slot_period: i32,
pub class_b_ping_slot_nb_k: i16,
pub class_c_scheduling_type: fields::MulticastGroupSchedulingType,
}
@ -64,7 +64,7 @@ impl Default for MulticastGroup {
group_type: "".into(),
dr: 0,
frequency: 0,
class_b_ping_slot_period: 0,
class_b_ping_slot_nb_k: 0,
class_c_scheduling_type: fields::MulticastGroupSchedulingType::DELAY,
}
}
@ -165,7 +165,7 @@ pub async fn update(mg: MulticastGroup) -> Result<MulticastGroup, Error> {
multicast_group::group_type.eq(&mg.group_type),
multicast_group::dr.eq(&mg.dr),
multicast_group::frequency.eq(&mg.frequency),
multicast_group::class_b_ping_slot_period.eq(&mg.class_b_ping_slot_period),
multicast_group::class_b_ping_slot_nb_k.eq(&mg.class_b_ping_slot_nb_k),
multicast_group::class_c_scheduling_type.eq(&mg.class_c_scheduling_type),
))
.get_result(&mut get_async_db_conn().await?)
@ -405,11 +405,7 @@ pub async fn enqueue(
match mg.group_type.as_ref() {
"B" => {
// get ping nb
let ping_nb = if mg.class_b_ping_slot_period != 0 {
(1 << 12) / mg.class_b_ping_slot_period
} else {
0
} as usize;
let ping_nb = 1 << mg.class_b_ping_slot_nb_k as usize;
// get max. gps epoch time.
let res: Option<i64> =
@ -684,7 +680,7 @@ pub mod test {
group_type: "C".into(),
dr: 1,
frequency: 868100000,
class_b_ping_slot_period: 1,
class_b_ping_slot_nb_k: 1,
..Default::default()
})
.await
@ -697,7 +693,7 @@ pub mod test {
// update
mg.name = "test-mg-updated".into();
mg.group_type = "B".into();
mg.class_b_ping_slot_period = 3;
mg.class_b_ping_slot_nb_k = 4;
mg = update(mg).await.unwrap();
let mg_get = get(&mg.id).await.unwrap();
assert_eq!(mg, mg_get);
@ -822,7 +818,7 @@ pub mod test {
group_type: "C".into(),
dr: 1,
frequency: 868100000,
class_b_ping_slot_period: 1,
class_b_ping_slot_nb_k: 1,
..Default::default()
})
.await
@ -880,7 +876,7 @@ pub mod test {
group_type: "C".into(),
dr: 1,
frequency: 868100000,
class_b_ping_slot_period: 1,
class_b_ping_slot_nb_k: 1,
..Default::default()
})
.await
@ -938,7 +934,7 @@ pub mod test {
group_type: "C".into(),
dr: 1,
frequency: 868100000,
class_b_ping_slot_period: 1,
class_b_ping_slot_nb_k: 1,
class_c_scheduling_type: fields::MulticastGroupSchedulingType::DELAY,
..Default::default()
})

View File

@ -243,7 +243,7 @@ diesel::table! {
group_type -> Bpchar,
dr -> Int2,
frequency -> Int8,
class_b_ping_slot_period -> Int4,
class_b_ping_slot_nb_k -> Int2,
#[max_length = 20]
class_c_scheduling_type -> Varchar,
}

View File

@ -82,7 +82,7 @@ async fn test_multicast() {
group_type: "C".into(),
dr: 3,
frequency: 868300000,
class_b_ping_slot_period: 32,
class_b_ping_slot_nb_k: 0,
..Default::default()
})
.await

View File

@ -47,7 +47,7 @@ function MulticastGroupForm(props: IProps) {
mg.setFrequency(v.frequency);
mg.setRegion(v.region);
mg.setGroupType(v.groupType);
mg.setClassBPingSlotPeriod(v.classBPingSlotPeriod);
mg.setClassBPingSlotNbK(v.classBPingSlotNbK);
mg.setClassCSchedulingType(v.classCSchedulingType);
props.onFinish(mg);
@ -146,16 +146,16 @@ function MulticastGroupForm(props: IProps) {
</Form.Item>
</Col>
<Col span={8}>
<Form.Item label="Class-B ping-slot periodicity" name="classBPingSlotPeriod">
<Form.Item label="Class-B ping-slot periodicity" name="classBPingSlotNbK">
<Select disabled={!selectPingSlotPeriod || props.disabled}>
<Select.Option value={32 * 1}>Every second</Select.Option>
<Select.Option value={32 * 2}>Every 2 seconds</Select.Option>
<Select.Option value={32 * 4}>Every 4 seconds</Select.Option>
<Select.Option value={32 * 8}>Every 8 seconds</Select.Option>
<Select.Option value={32 * 16}>Every 16 seconds</Select.Option>
<Select.Option value={32 * 32}>Every 32 seconds</Select.Option>
<Select.Option value={32 * 64}>Every 64 seconds</Select.Option>
<Select.Option value={32 * 128}>Every 128 seconds</Select.Option>
<Select.Option value={0}>Every second</Select.Option>
<Select.Option value={1}>Every 2 seconds</Select.Option>
<Select.Option value={2}>Every 4 seconds</Select.Option>
<Select.Option value={3}>Every 8 seconds</Select.Option>
<Select.Option value={4}>Every 16 seconds</Select.Option>
<Select.Option value={5}>Every 32 seconds</Select.Option>
<Select.Option value={6}>Every 64 seconds</Select.Option>
<Select.Option value={7}>Every 128 seconds</Select.Option>
</Select>
</Form.Item>
</Col>