Add secondary_net_ids config option.

This can be useful when using multiple NetIDs (e.g. after a merge of two
networks, or when using multiple NetIDs). Previously, any other NetID
than the configured net_id would be considered roaming.
This commit is contained in:
Orne Brocaar 2023-10-09 14:24:23 +01:00
parent 99561f2e47
commit eccb09cb1b
3 changed files with 86 additions and 8 deletions

View File

@ -149,8 +149,8 @@ pub fn get_passive_roaming_kek_label(net_id: NetID) -> Result<String> {
}
pub fn is_enabled() -> bool {
let clients_r = CLIENTS.read().unwrap();
!clients_r.is_empty()
let conf = config::get();
conf.roaming.default.enabled || !conf.roaming.servers.is_empty()
}
pub fn is_roaming_dev_addr(dev_addr: DevAddr) -> bool {
@ -164,7 +164,7 @@ pub fn is_roaming_dev_addr(dev_addr: DevAddr) -> bool {
// Configured NetID.
conf.network.net_id,
// Test NetIDs. For roaming it is expected that non-testing NetIDs will be used. These are
// included as non-roaming NetIDs as one might start with a test-NetID and then aquires an
// included as non-roaming NetIDs as one might start with a test-NetID and then acquires an
// official NetID to setup roaming. Not including these would mean that all devices must
// re-join to obtain a new DevAddr.
NetID::from_be_bytes([0, 0, 0]),
@ -175,6 +175,12 @@ pub fn is_roaming_dev_addr(dev_addr: DevAddr) -> bool {
}
}
for net_id in &conf.network.secondary_net_ids {
if dev_addr.is_net_id(*net_id) {
return false;
}
}
true
}
@ -320,3 +326,61 @@ pub fn reset() {
let mut clients_w = CLIENTS.write().unwrap();
*clients_w = HashMap::new();
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_is_roaming_dev_addr() {
struct Test {
dev_addr: DevAddr,
net_id: NetID,
secondary_net_ids: Vec<NetID>,
is_roaming: bool,
}
let tests = vec![
Test {
dev_addr: {
let mut dev_addr = DevAddr::from_be_bytes([1, 2, 3, 4]);
dev_addr.set_dev_addr_prefix(NetID::from_be_bytes([1, 2, 3]).dev_addr_prefix());
dev_addr
},
net_id: NetID::from_be_bytes([1, 2, 3]),
secondary_net_ids: vec![],
is_roaming: false,
},
Test {
dev_addr: {
let mut dev_addr = DevAddr::from_be_bytes([1, 2, 3, 4]);
dev_addr.set_dev_addr_prefix(NetID::from_be_bytes([1, 2, 3]).dev_addr_prefix());
dev_addr
},
net_id: NetID::from_be_bytes([3, 2, 1]),
secondary_net_ids: vec![],
is_roaming: true,
},
Test {
dev_addr: {
let mut dev_addr = DevAddr::from_be_bytes([1, 2, 3, 4]);
dev_addr.set_dev_addr_prefix(NetID::from_be_bytes([1, 2, 3]).dev_addr_prefix());
dev_addr
},
net_id: NetID::from_be_bytes([3, 2, 1]),
secondary_net_ids: vec![NetID::from_be_bytes([1, 2, 3])],
is_roaming: false,
},
];
for tst in &tests {
let mut conf = config::Configuration::default();
conf.network.net_id = tst.net_id;
conf.network.secondary_net_ids = tst.secondary_net_ids.clone();
conf.roaming.default.enabled = true;
config::set(conf);
assert_eq!(tst.is_roaming, is_roaming_dev_addr(tst.dev_addr));
}
}
}

View File

@ -142,13 +142,25 @@ pub fn run() {
# Network identifier (NetID, 3 bytes) encoded as HEX (e.g. 010203).
net_id="{{ network.net_id }}"
# Secondary NetIDs.
#
# Additional NetIDs. At this moment, the additional NetIDs are only used to
# validate if an uplink belongs to the ChirpStack instance or if it is a
# roaming device (if roaming is enabled).
# If you would like to assign DevAddrs from multiple NetIDs, you must specify
# these in the dev_addr_prefixes configuration.
secondary_net_ids=[
{{#each network.secondary_net_ids}}
"{{this}}",
{{/each}}
]
# DevAddr prefix(es).
#
# This makes it possible to configure one or multiple sub-ranges within
# the configured NetID. If left blank, then the complete DevAddr space
# provided by the configured NetID will be used.
# If multiple prefixes are configured, a random prefix will be chosen when
# generating a DevAddr.
# This makes it possible to configure one or multiple DevAddr (sub)ranges
# If left blank, then the complete DevAddr space provided by the configured
# net_id value will be used. If multiple prefixes are configured, a random
# prefix will be chosen when generating a DevAddr.
#
# Example configuration:
# dev_addr_prefixes=["0000ff00/24"]

View File

@ -130,6 +130,7 @@ impl Default for Gateway {
#[serde(default)]
pub struct Network {
pub net_id: NetID,
pub secondary_net_ids: Vec<NetID>,
pub dev_addr_prefixes: Vec<DevAddrPrefix>,
pub enabled_regions: Vec<String>,
#[serde(with = "humantime_serde")]
@ -147,6 +148,7 @@ impl Default for Network {
fn default() -> Self {
Network {
net_id: NetID::from_be_bytes([0x00, 0x00, 0x00]),
secondary_net_ids: vec![],
dev_addr_prefixes: vec![],
enabled_regions: vec![],
device_session_ttl: Duration::from_secs(60 * 60 * 24 * 31),