mirror of
https://github.com/chirpstack/chirpstack.git
synced 2025-04-17 20:50:14 +00:00
Compare commits
7 Commits
v4.4.1
...
api/go/v4.
Author | SHA1 | Date | |
---|---|---|---|
7ff12f5ae7 | |||
a28d29deb9 | |||
f930bd6b96 | |||
f66186bb7b | |||
3f8f746dc5 | |||
57ab993a88 | |||
a975cf3223 |
495
Cargo.lock
generated
495
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
2
api/grpc-web/package.json
vendored
2
api/grpc-web/package.json
vendored
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@chirpstack/chirpstack-api-grpc-web",
|
||||
"version": "4.4.1",
|
||||
"version": "4.4.3",
|
||||
"description": "Chirpstack gRPC-web API",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
|
2
api/java/build.gradle.kts
vendored
2
api/java/build.gradle.kts
vendored
@ -8,7 +8,7 @@ plugins {
|
||||
}
|
||||
|
||||
group = "io.chirpstack"
|
||||
version = "4.4.1"
|
||||
version = "4.4.3"
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
|
2
api/js/package.json
vendored
2
api/js/package.json
vendored
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@chirpstack/chirpstack-api",
|
||||
"version": "4.4.1",
|
||||
"version": "4.4.3",
|
||||
"description": "Chirpstack JS and TS API",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
|
2
api/kotlin/build.gradle.kts
vendored
2
api/kotlin/build.gradle.kts
vendored
@ -9,7 +9,7 @@ plugins {
|
||||
}
|
||||
|
||||
group = "io.chirpstack"
|
||||
version = "4.4.1"
|
||||
version = "4.4.3"
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
|
2
api/python/src/setup.py
vendored
2
api/python/src/setup.py
vendored
@ -18,7 +18,7 @@ CLASSIFIERS = [
|
||||
|
||||
setup(
|
||||
name='chirpstack-api',
|
||||
version = "4.4.1",
|
||||
version = "4.4.3",
|
||||
url='https://github.com/brocaar/chirpstack-api',
|
||||
author='Orne Brocaar',
|
||||
author_email='info@brocaar.com',
|
||||
|
2
api/rust/Cargo.lock
generated
vendored
2
api/rust/Cargo.lock
generated
vendored
@ -108,7 +108,7 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "chirpstack_api"
|
||||
version = "4.4.1"
|
||||
version = "4.4.3"
|
||||
dependencies = [
|
||||
"hex",
|
||||
"pbjson",
|
||||
|
2
api/rust/Cargo.toml
vendored
2
api/rust/Cargo.toml
vendored
@ -1,7 +1,7 @@
|
||||
[package]
|
||||
name = "chirpstack_api"
|
||||
description = "ChirpStack Protobuf / gRPC API definitions."
|
||||
version = "4.4.1"
|
||||
version = "4.4.3"
|
||||
authors = ["Orne Brocaar <info@brocaar.com>"]
|
||||
license = "MIT"
|
||||
homepage = "https://www.chirpstack.io"
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "backend"
|
||||
version = "4.4.1"
|
||||
version = "4.4.3"
|
||||
authors = ["Orne Brocaar <info@brocaar.com>"]
|
||||
edition = "2018"
|
||||
publish = false
|
||||
|
@ -3,7 +3,7 @@ name = "chirpstack"
|
||||
description = "ChirpStack is an open-source LoRaWAN(TM) Network Server"
|
||||
repository = "https://github.com/chirpstack/chirpstack"
|
||||
homepage = "https://www.chirpstack.io/"
|
||||
version = "4.4.1"
|
||||
version = "4.4.3"
|
||||
authors = ["Orne Brocaar <info@brocaar.com>"]
|
||||
edition = "2021"
|
||||
publish = false
|
||||
@ -101,7 +101,7 @@ pbkdf2 = { version = "0.12", features = ["simple"] }
|
||||
rand_core = { version = "0.6", features = ["std"] }
|
||||
jsonwebtoken = "8.2"
|
||||
openssl = { version = "0.10" }
|
||||
openidconnect = { version = "3.1", features = ["accept-rfc3339-timestamps"] }
|
||||
openidconnect = { version = "3.3", features = ["accept-rfc3339-timestamps"] }
|
||||
|
||||
# MQTT
|
||||
paho-mqtt = { version = "0.12", features = ["ssl"] }
|
||||
@ -124,7 +124,7 @@ aes = "0.8"
|
||||
rand = "0.8"
|
||||
base64 = "0.21"
|
||||
async-recursion = "1.0"
|
||||
regex = "1.7"
|
||||
regex = "1.9"
|
||||
petgraph = "0.6"
|
||||
prometheus-client = "0.21"
|
||||
pin-project = "1.0"
|
||||
|
25
chirpstack/src/cmd/create_api_key.rs
Normal file
25
chirpstack/src/cmd/create_api_key.rs
Normal file
@ -0,0 +1,25 @@
|
||||
use anyhow::Result;
|
||||
|
||||
use crate::api::auth::claims;
|
||||
use crate::config;
|
||||
use crate::storage::api_key;
|
||||
|
||||
pub async fn run(name: &str) -> Result<()> {
|
||||
let conf = config::get();
|
||||
|
||||
crate::storage::setup().await?;
|
||||
|
||||
let key = api_key::create(api_key::ApiKey {
|
||||
name: name.to_string(),
|
||||
is_admin: true,
|
||||
..Default::default()
|
||||
})
|
||||
.await?;
|
||||
|
||||
let token = claims::AuthClaim::new_for_api_key(&key.id).encode(conf.api.secret.as_ref())?;
|
||||
|
||||
println!("id: {}", key.id);
|
||||
println!("token: {}", token);
|
||||
|
||||
Ok(())
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
pub mod configfile;
|
||||
pub mod create_api_key;
|
||||
pub mod import_legacy_lorawan_devices_repository;
|
||||
pub mod print_ds;
|
||||
pub mod root;
|
||||
|
@ -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();
|
||||
@ -1788,6 +1799,11 @@ impl Data {
|
||||
dev_eui: device.dev_eui.to_vec(),
|
||||
provisioned: false,
|
||||
});
|
||||
|
||||
// Return because we can't add multiple sets and if we would combine
|
||||
// multiple commands as a single set, it might not fit in a single
|
||||
// downlink.
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -14,7 +14,6 @@ extern crate diesel;
|
||||
extern crate anyhow;
|
||||
|
||||
use std::path::Path;
|
||||
use std::process;
|
||||
use std::str::FromStr;
|
||||
|
||||
use anyhow::Result;
|
||||
@ -78,6 +77,13 @@ enum Commands {
|
||||
#[arg(short, long, value_name = "DIR")]
|
||||
dir: String,
|
||||
},
|
||||
|
||||
/// Create global API key.
|
||||
CreateApiKey {
|
||||
/// Name.
|
||||
#[arg(short, long, value_name = "NAME")]
|
||||
name: String,
|
||||
},
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
@ -104,25 +110,20 @@ async fn main() -> Result<()> {
|
||||
.init();
|
||||
}
|
||||
|
||||
if let Some(Commands::Configfile {}) = &cli.command {
|
||||
cmd::configfile::run();
|
||||
process::exit(0);
|
||||
match &cli.command {
|
||||
Some(Commands::Configfile {}) => cmd::configfile::run(),
|
||||
Some(Commands::PrintDs { dev_eui }) => {
|
||||
let dev_eui = EUI64::from_str(dev_eui).unwrap();
|
||||
cmd::print_ds::run(&dev_eui).await.unwrap();
|
||||
}
|
||||
Some(Commands::ImportLegacyLorawanDevicesRepository { dir }) => {
|
||||
cmd::import_legacy_lorawan_devices_repository::run(Path::new(&dir))
|
||||
.await
|
||||
.unwrap()
|
||||
}
|
||||
Some(Commands::CreateApiKey { name }) => cmd::create_api_key::run(&name).await?,
|
||||
None => cmd::root::run().await?,
|
||||
}
|
||||
|
||||
if let Some(Commands::PrintDs { dev_eui }) = &cli.command {
|
||||
let dev_eui = EUI64::from_str(dev_eui).unwrap();
|
||||
cmd::print_ds::run(&dev_eui).await.unwrap();
|
||||
process::exit(0);
|
||||
}
|
||||
|
||||
if let Some(Commands::ImportLegacyLorawanDevicesRepository { dir }) = &cli.command {
|
||||
cmd::import_legacy_lorawan_devices_repository::run(Path::new(&dir))
|
||||
.await
|
||||
.unwrap();
|
||||
process::exit(0);
|
||||
}
|
||||
|
||||
cmd::root::run().await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -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(),
|
||||
|
@ -3,7 +3,7 @@ name = "lrwn_filters"
|
||||
description = "Library for filtering LoRaWAN payloads on DevAddr and JoinEUIs prefixes"
|
||||
homepage = "https://www.chirpstack.io/"
|
||||
license = "MIT"
|
||||
version = "4.4.1"
|
||||
version = "4.4.3"
|
||||
authors = ["Orne Brocaar <info@brocaar.com>"]
|
||||
edition = "2021"
|
||||
repository = "https://github.com/chirpstack/chirpstack"
|
||||
|
@ -3,7 +3,7 @@ name = "lrwn"
|
||||
description = "Library for encoding / decoding LoRaWAN frames."
|
||||
homepage = "https://www.chirpstack.io"
|
||||
license = "MIT"
|
||||
version = "4.4.1"
|
||||
version = "4.4.3"
|
||||
authors = ["Orne Brocaar <info@brocaar.com>"]
|
||||
edition = "2018"
|
||||
repository = "https://github.com/chirpstack/chirpstack"
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "chirpstack-ui",
|
||||
"version": "4.4.1",
|
||||
"version": "4.4.3",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@ant-design/colors": "^6.0.0",
|
||||
|
@ -59,7 +59,6 @@ class LW10DeviceActivationForm extends Component<FormProps> {
|
||||
value={this.props.initialValues.getDevAddr()}
|
||||
devEui={this.props.device.getDevEui()}
|
||||
formRef={this.formRef}
|
||||
disabled={this.props.disabled}
|
||||
required
|
||||
/>
|
||||
<AesKeyInput
|
||||
@ -67,7 +66,6 @@ class LW10DeviceActivationForm extends Component<FormProps> {
|
||||
name="nwkSEncKey"
|
||||
value={this.props.initialValues.getNwkSEncKey()}
|
||||
formRef={this.formRef}
|
||||
disabled={this.props.disabled}
|
||||
required
|
||||
/>
|
||||
<AesKeyInput
|
||||
@ -75,18 +73,17 @@ class LW10DeviceActivationForm extends Component<FormProps> {
|
||||
name="appSKey"
|
||||
value={this.props.initialValues.getAppSKey()}
|
||||
formRef={this.formRef}
|
||||
disabled={this.props.disabled}
|
||||
required
|
||||
/>
|
||||
<Row gutter={24}>
|
||||
<Col span={6}>
|
||||
<Form.Item label="Uplink frame-counter" name="fCntUp">
|
||||
<InputNumber min={0} disabled={this.props.disabled} />
|
||||
<InputNumber min={0} />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={6}>
|
||||
<Form.Item label="Downlink frame-counter" name="nFCntDown">
|
||||
<InputNumber min={0} disabled={this.props.disabled} />
|
||||
<InputNumber min={0} />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
</Row>
|
||||
@ -133,7 +130,6 @@ class LW11DeviceActivationForm extends Component<FormProps> {
|
||||
value={this.props.initialValues.getDevAddr()}
|
||||
devEui={this.props.device.getDevEui()}
|
||||
formRef={this.formRef}
|
||||
disabled={this.props.disabled}
|
||||
required
|
||||
/>
|
||||
<AesKeyInput
|
||||
@ -141,7 +137,6 @@ class LW11DeviceActivationForm extends Component<FormProps> {
|
||||
name="nwkSEncKey"
|
||||
value={this.props.initialValues.getNwkSEncKey()}
|
||||
formRef={this.formRef}
|
||||
disabled={this.props.disabled}
|
||||
required
|
||||
/>
|
||||
<AesKeyInput
|
||||
@ -149,7 +144,6 @@ class LW11DeviceActivationForm extends Component<FormProps> {
|
||||
name="sNwkSIntKey"
|
||||
value={this.props.initialValues.getSNwkSIntKey()}
|
||||
formRef={this.formRef}
|
||||
disabled={this.props.disabled}
|
||||
required
|
||||
/>
|
||||
<AesKeyInput
|
||||
@ -157,7 +151,6 @@ class LW11DeviceActivationForm extends Component<FormProps> {
|
||||
name="fNwkSIntKey"
|
||||
value={this.props.initialValues.getFNwkSIntKey()}
|
||||
formRef={this.formRef}
|
||||
disabled={this.props.disabled}
|
||||
required
|
||||
/>
|
||||
<AesKeyInput
|
||||
@ -165,23 +158,22 @@ class LW11DeviceActivationForm extends Component<FormProps> {
|
||||
name="appSKey"
|
||||
value={this.props.initialValues.getAppSKey()}
|
||||
formRef={this.formRef}
|
||||
disabled={this.props.disabled}
|
||||
required
|
||||
/>
|
||||
<Row gutter={24}>
|
||||
<Col span={6}>
|
||||
<Form.Item label="Uplink frame-counter" name="fCntUp">
|
||||
<InputNumber min={0} disabled={this.props.disabled} />
|
||||
<InputNumber min={0} />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={6}>
|
||||
<Form.Item label="Downlink frame-counter (network)" name="nFCntDown">
|
||||
<InputNumber min={0} disabled={this.props.disabled} />
|
||||
<InputNumber min={0} />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={6}>
|
||||
<Form.Item label="Downlink frame-counter (application)" name="aFCntDown">
|
||||
<InputNumber min={0} disabled={this.props.disabled} />
|
||||
<InputNumber min={0} />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
</Row>
|
||||
|
Reference in New Issue
Block a user