Skip to content

Commit c3ce4d6

Browse files
committed
lrwn: Add get_new_channel_req_dr_range fn.
This function given the data-rates supported by the device, returns the min_dr / max_dr values to be used with the NewChannelReq mac-command. Note that in some cases (e.g. in EU868) the min_dr / max_dr have a special meaning (in which case the max_dr is 0, and the min_dr > 0).
1 parent d05b93a commit c3ce4d6

12 files changed

Lines changed: 200 additions & 1 deletion

File tree

lrwn/src/region/as923.rs

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
use std::collections::HashMap;
21
use std::time::Duration;
32

43
use anyhow::Result;
@@ -996,6 +995,31 @@ impl Region for Configuration {
996995
self.base.get_data_rate(uplink, dr_index)
997996
}
998997

998+
fn get_new_channel_req_dr_range(&self, data_rates: &[u8]) -> Result<(u8, u8)> {
999+
let dr_min = *data_rates
1000+
.first()
1001+
.ok_or_else(|| anyhow!("Can not get first data-rate"))?;
1002+
let dr_max = *data_rates
1003+
.last()
1004+
.ok_or_else(|| anyhow!("Can not get last data-rate"))?;
1005+
1006+
if dr_max - dr_min == (data_rates.len() - 1) as u8 {
1007+
// In case data_rates is a consecutive range.
1008+
Ok((dr_min, dr_max))
1009+
} else {
1010+
// Use special encoding as specified by RP002.
1011+
match data_rates {
1012+
[0, 1, 2, 3, 4, 5, 12, 13] => Ok((1, 0)),
1013+
[1, 2, 3, 4, 5, 12, 13] => Ok((2, 0)),
1014+
[2, 3, 4, 5, 12, 13] => Ok((3, 0)),
1015+
[3, 4, 5, 12, 13] => Ok((4, 0)),
1016+
[4, 5, 12, 13] => Ok((5, 0)),
1017+
[5, 12, 13] => Ok((6, 0)),
1018+
_ => Err(anyhow!("Unsupported data-rate range: {:?}", data_rates)),
1019+
}
1020+
}
1021+
}
1022+
9991023
fn get_max_dl_payload_size(
10001024
&self,
10011025
mac_version: MacVersion,

lrwn/src/region/au915.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -706,6 +706,10 @@ impl Region for Configuration {
706706
self.base.get_data_rate(uplink, dr_index)
707707
}
708708

709+
fn get_new_channel_req_dr_range(&self, data_rates: &[u8]) -> Result<(u8, u8)> {
710+
self.base.get_new_channel_req_dr_range(data_rates)
711+
}
712+
709713
fn get_max_dl_payload_size(
710714
&self,
711715
mac_version: MacVersion,

lrwn/src/region/cn470.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -508,6 +508,10 @@ impl Region for Configuration {
508508
self.base.add_channel(frequency, min_dr, max_dr)
509509
}
510510

511+
fn get_new_channel_req_dr_range(&self, data_rates: &[u8]) -> Result<(u8, u8)> {
512+
self.base.get_new_channel_req_dr_range(data_rates)
513+
}
514+
511515
fn get_uplink_channel(&self, channel: usize) -> Result<Channel> {
512516
self.base.get_uplink_channel(channel)
513517
}

lrwn/src/region/cn779.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -464,6 +464,10 @@ impl Region for Configuration {
464464
self.base.get_data_rate(uplink, dr_index)
465465
}
466466

467+
fn get_new_channel_req_dr_range(&self, data_rates: &[u8]) -> Result<(u8, u8)> {
468+
self.base.get_new_channel_req_dr_range(data_rates)
469+
}
470+
467471
fn get_max_dl_payload_size(
468472
&self,
469473
mac_version: MacVersion,

lrwn/src/region/eu433.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -702,6 +702,31 @@ impl Region for Configuration {
702702
self.base.get_data_rate(uplink, dr_index)
703703
}
704704

705+
fn get_new_channel_req_dr_range(&self, data_rates: &[u8]) -> Result<(u8, u8)> {
706+
let dr_min = *data_rates
707+
.first()
708+
.ok_or_else(|| anyhow!("Can not get first data-rate"))?;
709+
let dr_max = *data_rates
710+
.last()
711+
.ok_or_else(|| anyhow!("Can not get last data-rate"))?;
712+
713+
if dr_max - dr_min == (data_rates.len() - 1) as u8 {
714+
// In case data_rates is a consecutive range.
715+
Ok((dr_min, dr_max))
716+
} else {
717+
// Use special encoding as specified by RP002.
718+
match data_rates {
719+
[0, 1, 2, 3, 4, 5, 12, 13] => Ok((1, 0)),
720+
[1, 2, 3, 4, 5, 12, 13] => Ok((2, 0)),
721+
[2, 3, 4, 5, 12, 13] => Ok((3, 0)),
722+
[3, 4, 5, 12, 13] => Ok((4, 0)),
723+
[4, 5, 12, 13] => Ok((5, 0)),
724+
[5, 12, 13] => Ok((6, 0)),
725+
_ => Err(anyhow!("Unsupported data-rate range: {:?}", data_rates)),
726+
}
727+
}
728+
}
729+
705730
fn get_max_dl_payload_size(
706731
&self,
707732
mac_version: MacVersion,

lrwn/src/region/eu868.rs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -781,6 +781,31 @@ impl Region for Configuration {
781781
self.base.get_data_rate(uplink, dr_index)
782782
}
783783

784+
fn get_new_channel_req_dr_range(&self, data_rates: &[u8]) -> Result<(u8, u8)> {
785+
let dr_min = *data_rates
786+
.first()
787+
.ok_or_else(|| anyhow!("Can not get first data-rate"))?;
788+
let dr_max = *data_rates
789+
.last()
790+
.ok_or_else(|| anyhow!("Can not get last data-rate"))?;
791+
792+
if dr_max - dr_min == (data_rates.len() - 1) as u8 {
793+
// In case data_rates is a consecutive range.
794+
Ok((dr_min, dr_max))
795+
} else {
796+
// Use special encoding as specified by RP002.
797+
match data_rates {
798+
[0, 1, 2, 3, 4, 5, 12, 13] => Ok((1, 0)),
799+
[1, 2, 3, 4, 5, 12, 13] => Ok((2, 0)),
800+
[2, 3, 4, 5, 12, 13] => Ok((3, 0)),
801+
[3, 4, 5, 12, 13] => Ok((4, 0)),
802+
[4, 5, 12, 13] => Ok((5, 0)),
803+
[5, 12, 13] => Ok((6, 0)),
804+
_ => Err(anyhow!("Unsupported data-rate range: {:?}", data_rates)),
805+
}
806+
}
807+
}
808+
784809
fn get_max_dl_payload_size(
785810
&self,
786811
mac_version: MacVersion,
@@ -988,6 +1013,20 @@ mod tests {
9881013
}
9891014
}
9901015

1016+
#[test]
1017+
fn get_new_channel_req_dr_range() {
1018+
let c = Configuration::new(false);
1019+
let tests: Vec<(Vec<u8>, (u8, u8))> = vec![
1020+
(vec![0, 1, 2, 3, 4, 5], (0, 5)),
1021+
(vec![0, 1, 2, 3, 4, 5, 12, 13], (1, 0)),
1022+
(vec![5, 12, 13], (6, 0)),
1023+
];
1024+
1025+
for t in &tests {
1026+
assert_eq!(t.1, c.get_new_channel_req_dr_range(&t.0).unwrap());
1027+
}
1028+
}
1029+
9911030
#[test]
9921031
fn get_user_defined_uplink_channel_indices() {
9931032
assert_eq!(

lrwn/src/region/in865.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -610,6 +610,31 @@ impl Region for Configuration {
610610
self.base.get_data_rate(uplink, dr_index)
611611
}
612612

613+
fn get_new_channel_req_dr_range(&self, data_rates: &[u8]) -> Result<(u8, u8)> {
614+
let dr_min = *data_rates
615+
.first()
616+
.ok_or_else(|| anyhow!("Can not get first data-rate"))?;
617+
let dr_max = *data_rates
618+
.last()
619+
.ok_or_else(|| anyhow!("Can not get last data-rate"))?;
620+
621+
if dr_max - dr_min == (data_rates.len() - 1) as u8 {
622+
// In case data_rates is a consecutive range.
623+
Ok((dr_min, dr_max))
624+
} else {
625+
// Use special encoding as specified by RP002.
626+
match data_rates {
627+
[0, 1, 2, 3, 4, 5, 12, 13] => Ok((1, 0)),
628+
[1, 2, 3, 4, 5, 12, 13] => Ok((2, 0)),
629+
[2, 3, 4, 5, 12, 13] => Ok((3, 0)),
630+
[3, 4, 5, 12, 13] => Ok((4, 0)),
631+
[4, 5, 12, 13] => Ok((5, 0)),
632+
[5, 12, 13] => Ok((6, 0)),
633+
_ => Err(anyhow!("Unsupported data-rate range: {:?}", data_rates)),
634+
}
635+
}
636+
}
637+
613638
fn get_max_dl_payload_size(
614639
&self,
615640
mac_version: MacVersion,

lrwn/src/region/ism2400.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,10 @@ impl Region for Configuration {
290290
self.base.get_data_rate(uplink, dr_index)
291291
}
292292

293+
fn get_new_channel_req_dr_range(&self, data_rates: &[u8]) -> Result<(u8, u8)> {
294+
self.base.get_new_channel_req_dr_range(data_rates)
295+
}
296+
293297
fn get_max_dl_payload_size(
294298
&self,
295299
mac_version: MacVersion,

lrwn/src/region/kr920.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -558,6 +558,31 @@ impl Region for Configuration {
558558
self.base.get_data_rate(uplink, dr_index)
559559
}
560560

561+
fn get_new_channel_req_dr_range(&self, data_rates: &[u8]) -> Result<(u8, u8)> {
562+
let dr_min = *data_rates
563+
.first()
564+
.ok_or_else(|| anyhow!("Can not get first data-rate"))?;
565+
let dr_max = *data_rates
566+
.last()
567+
.ok_or_else(|| anyhow!("Can not get last data-rate"))?;
568+
569+
if dr_max - dr_min == (data_rates.len() - 1) as u8 {
570+
// In case data_rates is a consecutive range.
571+
Ok((dr_min, dr_max))
572+
} else {
573+
// Use special encoding as specified by RP002.
574+
match data_rates {
575+
[0, 1, 2, 3, 4, 5, 12, 13] => Ok((1, 0)),
576+
[1, 2, 3, 4, 5, 12, 13] => Ok((2, 0)),
577+
[2, 3, 4, 5, 12, 13] => Ok((3, 0)),
578+
[3, 4, 5, 12, 13] => Ok((4, 0)),
579+
[4, 5, 12, 13] => Ok((5, 0)),
580+
[5, 12, 13] => Ok((6, 0)),
581+
_ => Err(anyhow!("Unsupported data-rate range: {:?}", data_rates)),
582+
}
583+
}
584+
}
585+
561586
fn get_max_dl_payload_size(
562587
&self,
563588
mac_version: MacVersion,

lrwn/src/region/mod.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,14 @@ pub trait Region {
414414
/// Returns the modulation parameters given the data-rate.
415415
fn get_data_rate(&self, uplink: bool, dr_index: u8) -> Result<DataRateModulation>;
416416

417+
/// Returns the NewChannelReq data-rate range for the given data-rates.
418+
/// Notes:
419+
/// * It is expected that the provided range is sorted.
420+
/// * By default this returns the first item as min_dr and the last item
421+
/// as max_dr. For some regions, there can be gaps in the range and a
422+
/// special encoding is used (e.g. in case of EU868).
423+
fn get_new_channel_req_dr_range(&self, data_rates: &[u8]) -> Result<(u8, u8)>;
424+
417425
/// Returns the max downlink payload-size for the given data-rate index, protocol version
418426
/// and regional-parameters revision.
419427
/// When the version or revision is unknown, it will return the most recent
@@ -566,6 +574,14 @@ impl RegionBaseConfig {
566574
))
567575
}
568576

577+
fn get_new_channel_req_dr_range(&self, data_rates: &[u8]) -> Result<(u8, u8)> {
578+
if data_rates.is_empty() {
579+
return Err(anyhow!("data_rates can not be empty"));
580+
}
581+
582+
Ok((data_rates[0], data_rates[data_rates.len() - 1]))
583+
}
584+
569585
fn get_max_dl_payload_size(
570586
&self,
571587
mac_version: MacVersion,

0 commit comments

Comments
 (0)