mirror of
https://github.com/chirpstack/chirpstack.git
synced 2025-06-17 06:48:24 +00:00
Implement dev_addr_prefixes configuration.
This makes it possible to configure one or multiple DevAddr sub-ranges instead of using the whole DevAddr range provided by the configured NetID. Closes #49.
This commit is contained in:
@ -4,7 +4,6 @@ use std::time::SystemTime;
|
|||||||
|
|
||||||
use bigdecimal::ToPrimitive;
|
use bigdecimal::ToPrimitive;
|
||||||
use chrono::{DateTime, Local, Utc};
|
use chrono::{DateTime, Local, Utc};
|
||||||
use rand::RngCore;
|
|
||||||
use tonic::{Request, Response, Status};
|
use tonic::{Request, Response, Status};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
@ -19,7 +18,7 @@ use crate::storage::error::Error;
|
|||||||
use crate::storage::{
|
use crate::storage::{
|
||||||
device, device_keys, device_profile, device_queue, device_session, fields, metrics,
|
device, device_keys, device_profile, device_queue, device_session, fields, metrics,
|
||||||
};
|
};
|
||||||
use crate::{codec, config};
|
use crate::{codec, devaddr::get_random_dev_addr};
|
||||||
|
|
||||||
pub struct Device {
|
pub struct Device {
|
||||||
validator: validator::RequestValidator,
|
validator: validator::RequestValidator,
|
||||||
@ -547,20 +546,8 @@ impl DeviceService for Device {
|
|||||||
&self,
|
&self,
|
||||||
_request: Request<api::GetRandomDevAddrRequest>,
|
_request: Request<api::GetRandomDevAddrRequest>,
|
||||||
) -> Result<Response<api::GetRandomDevAddrResponse>, Status> {
|
) -> Result<Response<api::GetRandomDevAddrResponse>, Status> {
|
||||||
let conf = config::get();
|
|
||||||
let mut dev_addr: [u8; 4] = [0; 4];
|
|
||||||
|
|
||||||
rand::thread_rng().fill_bytes(&mut dev_addr);
|
|
||||||
#[cfg(test)]
|
|
||||||
{
|
|
||||||
dev_addr = [1, 2, 3, 4];
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut dev_addr = DevAddr::from_be_bytes(dev_addr);
|
|
||||||
dev_addr.set_addr_prefix(&conf.network.net_id);
|
|
||||||
|
|
||||||
Ok(Response::new(api::GetRandomDevAddrResponse {
|
Ok(Response::new(api::GetRandomDevAddrResponse {
|
||||||
dev_addr: dev_addr.to_string(),
|
dev_addr: get_random_dev_addr().to_string(),
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1347,7 +1334,7 @@ pub mod test {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
let dev_addr = DevAddr::from_str(&get_random_dev_addr_resp.get_ref().dev_addr).unwrap();
|
let dev_addr = DevAddr::from_str(&get_random_dev_addr_resp.get_ref().dev_addr).unwrap();
|
||||||
let mut dev_addr_copy = dev_addr.clone();
|
let mut dev_addr_copy = dev_addr.clone();
|
||||||
dev_addr_copy.set_addr_prefix(&NetID::from_str("000000").unwrap());
|
dev_addr_copy.set_dev_addr_prefix(NetID::from_str("000000").unwrap().dev_addr_prefix());
|
||||||
assert_eq!(dev_addr, dev_addr_copy);
|
assert_eq!(dev_addr, dev_addr_copy);
|
||||||
|
|
||||||
// enqueue
|
// enqueue
|
||||||
|
@ -117,6 +117,26 @@ pub fn run() {
|
|||||||
# Network identifier (NetID, 3 bytes) encoded as HEX (e.g. 010203).
|
# Network identifier (NetID, 3 bytes) encoded as HEX (e.g. 010203).
|
||||||
net_id="{{ network.net_id }}"
|
net_id="{{ network.net_id }}"
|
||||||
|
|
||||||
|
# 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.
|
||||||
|
#
|
||||||
|
# Example configuration:
|
||||||
|
# dev_addr_prefixes=["0000ff00/24"]
|
||||||
|
#
|
||||||
|
# This example configures the DevAddr range to 0000ff00 - 0000ffff.
|
||||||
|
# The /24 means that the 24MSB of the prefix will be used, meaning that the
|
||||||
|
# 8LSB will be used as address space.
|
||||||
|
dev_addr_prefixes=[
|
||||||
|
{{#each network.dev_addr_prefixes}}
|
||||||
|
"{{this}}",
|
||||||
|
{{/each}}
|
||||||
|
]
|
||||||
|
|
||||||
# Enabled regions.
|
# Enabled regions.
|
||||||
#
|
#
|
||||||
# Multiple regions can be enabled simultaneously. Each region must match
|
# Multiple regions can be enabled simultaneously. Each region must match
|
||||||
|
@ -7,7 +7,7 @@ use anyhow::{Context, Result};
|
|||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use lrwn::region::CommonName;
|
use lrwn::region::CommonName;
|
||||||
use lrwn::{AES128Key, NetID, EUI64};
|
use lrwn::{AES128Key, DevAddrPrefix, NetID, EUI64};
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
static ref CONFIG: Mutex<Arc<Configuration>> = Mutex::new(Arc::new(Default::default()));
|
static ref CONFIG: Mutex<Arc<Configuration>> = Mutex::new(Arc::new(Default::default()));
|
||||||
@ -150,6 +150,7 @@ impl Default for Gateway {
|
|||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub struct Network {
|
pub struct Network {
|
||||||
pub net_id: NetID,
|
pub net_id: NetID,
|
||||||
|
pub dev_addr_prefixes: Vec<DevAddrPrefix>,
|
||||||
pub enabled_regions: Vec<String>,
|
pub enabled_regions: Vec<String>,
|
||||||
#[serde(with = "humantime_serde")]
|
#[serde(with = "humantime_serde")]
|
||||||
pub device_session_ttl: Duration,
|
pub device_session_ttl: Duration,
|
||||||
@ -164,6 +165,7 @@ impl Default for Network {
|
|||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Network {
|
Network {
|
||||||
net_id: NetID::from_be_bytes([0x00, 0x00, 0x00]),
|
net_id: NetID::from_be_bytes([0x00, 0x00, 0x00]),
|
||||||
|
dev_addr_prefixes: vec![],
|
||||||
enabled_regions: vec!["eu868".into()],
|
enabled_regions: vec!["eu868".into()],
|
||||||
device_session_ttl: Duration::from_secs(60 * 60 * 24 * 31),
|
device_session_ttl: Duration::from_secs(60 * 60 * 24 * 31),
|
||||||
deduplication_delay: Duration::from_millis(200),
|
deduplication_delay: Duration::from_millis(200),
|
||||||
|
33
chirpstack/src/devaddr.rs
Normal file
33
chirpstack/src/devaddr.rs
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
use rand::seq::SliceRandom;
|
||||||
|
use rand::RngCore;
|
||||||
|
|
||||||
|
use crate::config;
|
||||||
|
use lrwn::DevAddr;
|
||||||
|
|
||||||
|
pub fn get_random_dev_addr() -> DevAddr {
|
||||||
|
let conf = config::get();
|
||||||
|
let mut rng = rand::thread_rng();
|
||||||
|
|
||||||
|
// Get configured DevAddr prefixes.
|
||||||
|
let prefixes = if conf.network.dev_addr_prefixes.is_empty() {
|
||||||
|
vec![conf.network.net_id.dev_addr_prefix()]
|
||||||
|
} else {
|
||||||
|
conf.network.dev_addr_prefixes.clone()
|
||||||
|
};
|
||||||
|
|
||||||
|
// Pick a random one (in case multiple prefixes are configured).
|
||||||
|
let prefix = *prefixes.choose(&mut rng).unwrap();
|
||||||
|
|
||||||
|
// Generate random DevAddr.
|
||||||
|
let mut dev_addr: [u8; 4] = [0; 4];
|
||||||
|
rng.fill_bytes(&mut dev_addr);
|
||||||
|
#[cfg(test)]
|
||||||
|
{
|
||||||
|
dev_addr = [1, 2, 3, 4];
|
||||||
|
}
|
||||||
|
let mut dev_addr = DevAddr::from_be_bytes(dev_addr);
|
||||||
|
|
||||||
|
// Set DevAddr prefix.
|
||||||
|
dev_addr.set_dev_addr_prefix(prefix);
|
||||||
|
dev_addr
|
||||||
|
}
|
@ -25,6 +25,7 @@ mod certificate;
|
|||||||
mod cmd;
|
mod cmd;
|
||||||
mod codec;
|
mod codec;
|
||||||
mod config;
|
mod config;
|
||||||
|
mod devaddr;
|
||||||
mod downlink;
|
mod downlink;
|
||||||
mod eventlog;
|
mod eventlog;
|
||||||
mod framelog;
|
mod framelog;
|
||||||
|
@ -86,7 +86,9 @@ async fn test_fns_uplink() {
|
|||||||
fhdr: lrwn::FHDR {
|
fhdr: lrwn::FHDR {
|
||||||
devaddr: {
|
devaddr: {
|
||||||
let mut d = lrwn::DevAddr::from_be_bytes([0, 0, 0, 0]);
|
let mut d = lrwn::DevAddr::from_be_bytes([0, 0, 0, 0]);
|
||||||
d.set_addr_prefix(&lrwn::NetID::from_str("000505").unwrap());
|
d.set_dev_addr_prefix(
|
||||||
|
lrwn::NetID::from_str("000505").unwrap().dev_addr_prefix(),
|
||||||
|
);
|
||||||
d
|
d
|
||||||
},
|
},
|
||||||
f_ctrl: Default::default(),
|
f_ctrl: Default::default(),
|
||||||
@ -232,7 +234,7 @@ async fn test_sns_uplink() {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let mut dev_addr = lrwn::DevAddr::from_be_bytes([0, 0, 0, 0]);
|
let mut dev_addr = lrwn::DevAddr::from_be_bytes([0, 0, 0, 0]);
|
||||||
dev_addr.set_addr_prefix(&lrwn::NetID::from_str("000505").unwrap());
|
dev_addr.set_dev_addr_prefix(lrwn::NetID::from_str("000505").unwrap().dev_addr_prefix());
|
||||||
|
|
||||||
let ds = internal::DeviceSession {
|
let ds = internal::DeviceSession {
|
||||||
dev_eui: vec![2, 2, 3, 4, 5, 6, 7, 8],
|
dev_eui: vec![2, 2, 3, 4, 5, 6, 7, 8],
|
||||||
@ -428,7 +430,7 @@ async fn test_sns_dev_not_found() {
|
|||||||
roaming::setup().unwrap();
|
roaming::setup().unwrap();
|
||||||
|
|
||||||
let mut dev_addr = lrwn::DevAddr::from_be_bytes([0, 0, 0, 0]);
|
let mut dev_addr = lrwn::DevAddr::from_be_bytes([0, 0, 0, 0]);
|
||||||
dev_addr.set_addr_prefix(&lrwn::NetID::from_str("000505").unwrap());
|
dev_addr.set_dev_addr_prefix(lrwn::NetID::from_str("000505").unwrap().dev_addr_prefix());
|
||||||
|
|
||||||
let data_phy = lrwn::PhyPayload {
|
let data_phy = lrwn::PhyPayload {
|
||||||
mhdr: lrwn::MHDR {
|
mhdr: lrwn::MHDR {
|
||||||
|
@ -3,7 +3,6 @@ use std::sync::Arc;
|
|||||||
|
|
||||||
use anyhow::{Context, Result};
|
use anyhow::{Context, Result};
|
||||||
use chrono::{DateTime, Local, Utc};
|
use chrono::{DateTime, Local, Utc};
|
||||||
use rand::RngCore;
|
|
||||||
use tracing::{error, info, span, trace, Instrument, Level};
|
use tracing::{error, info, span, trace, Instrument, Level};
|
||||||
|
|
||||||
use lrwn::{
|
use lrwn::{
|
||||||
@ -22,7 +21,9 @@ use crate::storage::{
|
|||||||
application, device, device_keys, device_profile, device_queue, error::Error as StorageError,
|
application, device, device_keys, device_profile, device_queue, error::Error as StorageError,
|
||||||
metrics, tenant,
|
metrics, tenant,
|
||||||
};
|
};
|
||||||
use crate::{config, downlink, framelog, integration, metalog, region};
|
use crate::{
|
||||||
|
config, devaddr::get_random_dev_addr, downlink, framelog, integration, metalog, region,
|
||||||
|
};
|
||||||
use chirpstack_api::{api, common, integration as integration_pb, internal, meta};
|
use chirpstack_api::{api, common, integration as integration_pb, internal, meta};
|
||||||
|
|
||||||
pub struct JoinRequest {
|
pub struct JoinRequest {
|
||||||
@ -349,21 +350,7 @@ impl JoinRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_random_dev_addr(&mut self) -> Result<()> {
|
fn get_random_dev_addr(&mut self) -> Result<()> {
|
||||||
let conf = config::get();
|
self.dev_addr = Some(get_random_dev_addr());
|
||||||
|
|
||||||
let mut dev_addr: [u8; 4] = [0; 4];
|
|
||||||
|
|
||||||
rand::thread_rng().fill_bytes(&mut dev_addr);
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
{
|
|
||||||
dev_addr = [1, 2, 3, 4];
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut dev_addr = DevAddr::from_be_bytes(dev_addr);
|
|
||||||
dev_addr.set_addr_prefix(&conf.network.net_id);
|
|
||||||
self.dev_addr = Some(dev_addr);
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,7 +2,6 @@ use std::sync::Arc;
|
|||||||
|
|
||||||
use anyhow::{Context, Result};
|
use anyhow::{Context, Result};
|
||||||
use chrono::{DateTime, Local, Utc};
|
use chrono::{DateTime, Local, Utc};
|
||||||
use rand::RngCore;
|
|
||||||
use tracing::{span, trace, Instrument, Level};
|
use tracing::{span, trace, Instrument, Level};
|
||||||
|
|
||||||
use super::{helpers, UplinkFrameSet};
|
use super::{helpers, UplinkFrameSet};
|
||||||
@ -12,7 +11,7 @@ use crate::storage::{
|
|||||||
application, device, device_keys, device_profile, device_queue, device_session,
|
application, device, device_keys, device_profile, device_queue, device_session,
|
||||||
error::Error as StorageError, metrics, tenant,
|
error::Error as StorageError, metrics, tenant,
|
||||||
};
|
};
|
||||||
use crate::{config, integration, metalog, region};
|
use crate::{config, devaddr::get_random_dev_addr, integration, metalog, region};
|
||||||
use backend::{PRStartAnsPayload, PRStartReqPayload};
|
use backend::{PRStartAnsPayload, PRStartReqPayload};
|
||||||
use chirpstack_api::{common, integration as integration_pb, internal, meta};
|
use chirpstack_api::{common, integration as integration_pb, internal, meta};
|
||||||
use lrwn::{keys, AES128Key, DevAddr, NetID};
|
use lrwn::{keys, AES128Key, DevAddr, NetID};
|
||||||
@ -203,21 +202,7 @@ impl JoinRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_random_dev_addr(&mut self) -> Result<()> {
|
fn get_random_dev_addr(&mut self) -> Result<()> {
|
||||||
let conf = config::get();
|
self.dev_addr = Some(get_random_dev_addr());
|
||||||
|
|
||||||
let mut dev_addr: [u8; 4] = [0; 4];
|
|
||||||
|
|
||||||
rand::thread_rng().fill_bytes(&mut dev_addr);
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
{
|
|
||||||
dev_addr = [1, 2, 3, 4];
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut dev_addr = DevAddr::from_be_bytes(dev_addr);
|
|
||||||
dev_addr.set_addr_prefix(&conf.network.net_id);
|
|
||||||
self.dev_addr = Some(dev_addr);
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user