├── .github ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── config.yml │ ├── 2.feature.md │ └── 1.bug.md ├── dependabot.yml └── workflows │ └── main.yml ├── chirpstack-concentratord-2g4 ├── config │ ├── region_ism2400.toml │ ├── channels_ism2400.toml │ └── concentratord.toml ├── src │ ├── config │ │ └── vendor │ │ │ ├── rak │ │ │ ├── mod.rs │ │ │ └── rak5148.rs │ │ │ ├── multitech │ │ │ ├── mod.rs │ │ │ └── mtac_lora_2g4.rs │ │ │ ├── semtech │ │ │ ├── mod.rs │ │ │ └── sx1280z3dsfgw1.rs │ │ │ └── mod.rs │ ├── cmd │ │ └── mod.rs │ ├── handler │ │ ├── mod.rs │ │ ├── gps.rs │ │ ├── stats.rs │ │ ├── jit.rs │ │ └── uplink.rs │ └── concentrator.rs ├── build.rs └── Cargo.toml ├── chirpstack-concentratord-sx1301 ├── config │ ├── region_in865.toml │ ├── region_ru864.toml │ ├── channels_ru864.toml │ ├── channels_eu433.toml │ ├── channels_in865.toml │ ├── channels_kr920.toml │ ├── channels_cn470_1.toml │ ├── channels_cn470_2.toml │ ├── channels_cn470_3.toml │ ├── channels_cn470_4.toml │ ├── channels_cn470_5.toml │ ├── channels_cn470_6.toml │ ├── channels_cn470_7.toml │ ├── channels_cn470_8.toml │ ├── channels_cn470_9.toml │ ├── channels_cn470_10.toml │ ├── channels_cn470_11.toml │ ├── channels_cn470_0.toml │ ├── region_as923.toml │ ├── region_as923_2.toml │ ├── region_as923_3.toml │ ├── region_as923_4.toml │ ├── region_eu433.toml │ ├── region_eu868.toml │ ├── region_kr920.toml │ ├── channels_as923.toml │ ├── channels_as923_2.toml │ ├── channels_as923_3.toml │ ├── channels_au915_0.toml │ ├── channels_au915_1.toml │ ├── channels_au915_2.toml │ ├── channels_au915_3.toml │ ├── channels_au915_4.toml │ ├── channels_au915_5.toml │ ├── channels_au915_6.toml │ ├── channels_au915_7.toml │ ├── channels_us915_0.toml │ ├── channels_us915_1.toml │ ├── channels_us915_2.toml │ ├── channels_us915_3.toml │ ├── channels_us915_4.toml │ ├── channels_us915_5.toml │ ├── channels_us915_6.toml │ ├── channels_us915_7.toml │ ├── channels_as923_4.toml │ ├── region_au915.toml │ ├── region_cn470.toml │ ├── region_us915.toml │ ├── channels_eu868.toml │ └── concentratord.toml ├── src │ ├── config │ │ └── vendor │ │ │ ├── imst │ │ │ └── mod.rs │ │ │ ├── kerlink │ │ │ └── mod.rs │ │ │ ├── risinghf │ │ │ └── mod.rs │ │ │ ├── wifx │ │ │ └── mod.rs │ │ │ ├── sandbox │ │ │ └── mod.rs │ │ │ ├── pi_supply │ │ │ ├── mod.rs │ │ │ └── lora_gateway_hat.rs │ │ │ ├── rak │ │ │ └── mod.rs │ │ │ ├── multitech │ │ │ └── mod.rs │ │ │ └── mod.rs │ ├── cmd │ │ └── mod.rs │ └── handler │ │ ├── mod.rs │ │ ├── stats.rs │ │ ├── jit.rs │ │ ├── uplink.rs │ │ └── timersync.rs ├── build.rs └── Cargo.toml ├── chirpstack-concentratord-sx1302 ├── config │ ├── region_in865.toml │ ├── region_ru864.toml │ ├── channels_ru864.toml │ ├── channels_eu433.toml │ ├── channels_in865.toml │ ├── channels_kr920.toml │ ├── region_as923.toml │ ├── region_as923_2.toml │ ├── region_as923_3.toml │ ├── region_as923_4.toml │ ├── region_eu433.toml │ ├── region_eu868.toml │ ├── region_kr920.toml │ ├── channels_as923.toml │ ├── channels_as923_2.toml │ ├── channels_as923_3.toml │ ├── channels_au915_0.toml │ ├── channels_au915_1.toml │ ├── channels_au915_2.toml │ ├── channels_au915_3.toml │ ├── channels_au915_4.toml │ ├── channels_au915_5.toml │ ├── channels_au915_6.toml │ ├── channels_au915_7.toml │ ├── channels_us915_0.toml │ ├── channels_us915_1.toml │ ├── channels_us915_2.toml │ ├── channels_us915_3.toml │ ├── channels_us915_4.toml │ ├── channels_us915_5.toml │ ├── channels_us915_6.toml │ ├── channels_us915_7.toml │ ├── channels_as923_4.toml │ ├── region_au915.toml │ ├── region_us915.toml │ ├── channels_eu868.toml │ └── concentratord.toml ├── src │ ├── config │ │ └── vendor │ │ │ ├── seeed │ │ │ └── mod.rs │ │ │ ├── dragino │ │ │ └── mod.rs │ │ │ ├── embit │ │ │ └── mod.rs │ │ │ ├── rak │ │ │ └── mod.rs │ │ │ ├── waveshare │ │ │ └── mod.rs │ │ │ ├── miromico │ │ │ └── mod.rs │ │ │ ├── multitech │ │ │ └── mod.rs │ │ │ ├── semtech │ │ │ └── mod.rs │ │ │ └── mod.rs │ ├── cmd │ │ └── mod.rs │ └── handler │ │ ├── mod.rs │ │ ├── jit.rs │ │ ├── stats.rs │ │ └── uplink.rs ├── build.rs └── Cargo.toml ├── packaging └── vendor │ ├── multitech │ ├── conduit │ │ ├── files │ │ │ ├── 2g4 │ │ │ │ ├── region.toml │ │ │ │ ├── chirpstack-concentratord-2g4-ap1.monit │ │ │ │ ├── chirpstack-concentratord-2g4-ap2.monit │ │ │ │ ├── channels.toml │ │ │ │ ├── concentratord.toml │ │ │ │ ├── chirpstack-concentratord-2g4-ap1.init │ │ │ │ └── chirpstack-concentratord-2g4-ap2.init │ │ │ ├── sx1301 │ │ │ │ ├── chirpstack-concentratord-sx1301-ap1.monit │ │ │ │ ├── chirpstack-concentratord-sx1301-ap2.monit │ │ │ │ ├── region_eu868.toml │ │ │ │ ├── channels_eu868_0.toml │ │ │ │ ├── region_us915.toml │ │ │ │ ├── channels_us915_0.toml │ │ │ │ ├── concentratord.toml │ │ │ │ ├── chirpstack-concentratord-sx1301-ap1.init │ │ │ │ └── chirpstack-concentratord-sx1301-ap2.init │ │ │ └── sx1302 │ │ │ │ ├── chirpstack-concentratord-sx1302-ap1.monit │ │ │ │ ├── chirpstack-concentratord-sx1302-ap2.monit │ │ │ │ ├── region_eu868.toml │ │ │ │ ├── channels_us915_0.toml │ │ │ │ ├── region_us915.toml │ │ │ │ ├── channels_eu868_0.toml │ │ │ │ ├── concentratord.toml │ │ │ │ ├── chirpstack-concentratord-sx1302-ap1.init │ │ │ │ └── chirpstack-concentratord-sx1302-ap2.init │ │ ├── package-2g4.sh │ │ ├── package-sx1301.sh │ │ └── package-sx1302.sh │ ├── conduit-ap │ │ ├── files │ │ │ ├── chirpstack-concentratord.monit │ │ │ ├── channels_eu868_0.toml │ │ │ ├── channels_us915_0.toml │ │ │ ├── concentratord.toml │ │ │ └── chirpstack-concentratord.init │ │ └── package.sh │ └── conduit-ap3 │ │ ├── files │ │ ├── chirpstack-concentratord.monit │ │ ├── channels_us915_0.toml │ │ ├── channels_eu868_0.toml │ │ ├── concentratord.toml │ │ └── chirpstack-concentratord.init │ │ └── package.sh │ └── kerlink │ └── ifemtocell │ ├── files │ ├── chirpstack-concentratord.monit │ ├── channels.toml │ ├── concentratord.toml │ └── chirpstack-concentratord.init │ └── package.sh ├── .vscode └── settings.json ├── libloragw-2g4 ├── wrapper.h ├── src │ ├── lib.rs │ ├── mutex.rs │ ├── gps.rs │ └── wrapper.rs ├── Cargo.toml └── build.rs ├── libconcentratord ├── src │ ├── regulation │ │ ├── mod.rs │ │ └── standard │ │ │ └── etsi_en_300_220.rs │ ├── region │ │ ├── as923.rs │ │ ├── au915.rs │ │ ├── cn470.rs │ │ ├── eu433.rs │ │ ├── eu868.rs │ │ ├── in865.rs │ │ ├── kr920.rs │ │ ├── ru864.rs │ │ ├── us915.rs │ │ ├── as923_2.rs │ │ ├── as923_3.rs │ │ ├── as923_4.rs │ │ ├── ism2400.rs │ │ └── mod.rs │ ├── socket.rs │ ├── helpers.rs │ ├── lib.rs │ ├── error.rs │ ├── signals.rs │ ├── events.rs │ ├── gnss.rs │ ├── commands.rs │ └── gpsd.rs └── Cargo.toml ├── rust-toolchain.toml ├── libloragw-sx1301 ├── src │ ├── mutex.rs │ ├── lib.rs │ ├── wrapper.rs │ ├── reg.rs │ ├── spi.rs │ └── timespec.rs ├── wrapper.h ├── Cargo.toml └── build.rs ├── libloragw-sx1302 ├── src │ ├── mutex.rs │ ├── lib.rs │ ├── wrapper.rs │ ├── com.rs │ └── timespec.rs ├── wrapper.h ├── Cargo.toml └── build.rs ├── .gitignore ├── gateway-id ├── Cargo.toml └── src │ └── main.rs ├── gateway-location ├── Cargo.toml └── src │ └── main.rs ├── Cross.toml ├── shell.nix ├── .cargo └── config.toml ├── LICENSE ├── Cargo.toml ├── cross ├── Dockerfile.aarch64-unknown-linux-musl ├── Dockerfile.armv5te-unknown-linux-musleabi ├── Dockerfile.armv7-unknown-linux-musleabihf ├── Dockerfile.x86_64-unknown-linux-musl └── Dockerfile.mipsel-unknown-linux-musl └── README.md /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: chirpstack 2 | -------------------------------------------------------------------------------- /chirpstack-concentratord-2g4/config/region_ism2400.toml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1301/config/region_in865.toml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1301/config/region_ru864.toml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1302/config/region_in865.toml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1302/config/region_ru864.toml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packaging/vendor/multitech/conduit/files/2g4/region.toml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /chirpstack-concentratord-2g4/src/config/vendor/rak/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod rak5148; 2 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1301/src/config/vendor/imst/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod ic880a; 2 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1302/src/config/vendor/seeed/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod wm1302; 2 | -------------------------------------------------------------------------------- /chirpstack-concentratord-2g4/src/cmd/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod configfile; 2 | pub mod root; 3 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1301/src/cmd/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod configfile; 2 | pub mod root; 3 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1301/src/config/vendor/kerlink/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod ifemtocell; 2 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1301/src/config/vendor/risinghf/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod rhf0m301; 2 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1301/src/config/vendor/wifx/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod lorix_one; 2 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1302/src/cmd/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod configfile; 2 | pub mod root; 3 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1302/src/config/vendor/dragino/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod pg1302; 2 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "nixEnvSelector.nixFile": "${workspaceFolder}/shell.nix" 3 | } -------------------------------------------------------------------------------- /chirpstack-concentratord-2g4/src/config/vendor/multitech/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod mtac_lora_2g4; 2 | -------------------------------------------------------------------------------- /chirpstack-concentratord-2g4/src/config/vendor/semtech/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod sx1280z3dsfgw1; 2 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1301/src/config/vendor/sandbox/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod lorago_port; 2 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1302/src/config/vendor/embit/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod emb_lr1302_mpcie; 2 | -------------------------------------------------------------------------------- /libloragw-2g4/wrapper.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1301/src/config/vendor/pi_supply/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod lora_gateway_hat; 2 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1302/src/config/vendor/rak/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod rak2287; 2 | pub mod rak5146; 3 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1302/src/config/vendor/waveshare/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod sx1302_lorawan_gateway_hat; 2 | -------------------------------------------------------------------------------- /libconcentratord/src/regulation/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod dutycycle; 2 | pub mod standard; 3 | pub mod tracker; 4 | -------------------------------------------------------------------------------- /libconcentratord/src/region/as923.rs: -------------------------------------------------------------------------------- 1 | pub const TX_MIN_MAX_FREQS: [(u32, u32); 1] = [(915000000, 928000000)]; 2 | -------------------------------------------------------------------------------- /libconcentratord/src/region/au915.rs: -------------------------------------------------------------------------------- 1 | pub const TX_MIN_MAX_FREQS: [(u32, u32); 1] = [(915000000, 928000000)]; 2 | -------------------------------------------------------------------------------- /libconcentratord/src/region/cn470.rs: -------------------------------------------------------------------------------- 1 | pub const TX_MIN_MAX_FREQS: [(u32, u32); 1] = [(470000000, 510000000)]; 2 | -------------------------------------------------------------------------------- /libconcentratord/src/region/eu433.rs: -------------------------------------------------------------------------------- 1 | pub const TX_MIN_MAX_FREQS: [(u32, u32); 1] = [(433050000, 434900000)]; 2 | -------------------------------------------------------------------------------- /libconcentratord/src/region/eu868.rs: -------------------------------------------------------------------------------- 1 | pub const TX_MIN_MAX_FREQS: [(u32, u32); 1] = [(863000000, 870000000)]; 2 | -------------------------------------------------------------------------------- /libconcentratord/src/region/in865.rs: -------------------------------------------------------------------------------- 1 | pub const TX_MIN_MAX_FREQS: [(u32, u32); 1] = [(865000000, 867000000)]; 2 | -------------------------------------------------------------------------------- /libconcentratord/src/region/kr920.rs: -------------------------------------------------------------------------------- 1 | pub const TX_MIN_MAX_FREQS: [(u32, u32); 1] = [(920900000, 923300000)]; 2 | -------------------------------------------------------------------------------- /libconcentratord/src/region/ru864.rs: -------------------------------------------------------------------------------- 1 | pub const TX_MIN_MAX_FREQS: [(u32, u32); 1] = [(864000000, 870000000)]; 2 | -------------------------------------------------------------------------------- /libconcentratord/src/region/us915.rs: -------------------------------------------------------------------------------- 1 | pub const TX_MIN_MAX_FREQS: [(u32, u32); 1] = [(902000000, 928000000)]; 2 | -------------------------------------------------------------------------------- /chirpstack-concentratord-2g4/build.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | println!("cargo:rustc-link-lib=static=stdc++"); 3 | } 4 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1301/build.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | println!("cargo:rustc-link-lib=static=stdc++"); 3 | } 4 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1302/build.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | println!("cargo:rustc-link-lib=static=stdc++"); 3 | } 4 | -------------------------------------------------------------------------------- /libconcentratord/src/region/as923_2.rs: -------------------------------------------------------------------------------- 1 | pub const TX_MIN_MAX_FREQS: [(u32, u32); 1] = [(915000000, 928000000)]; 2 | -------------------------------------------------------------------------------- /libconcentratord/src/region/as923_3.rs: -------------------------------------------------------------------------------- 1 | pub const TX_MIN_MAX_FREQS: [(u32, u32); 1] = [(915000000, 928000000)]; 2 | -------------------------------------------------------------------------------- /libconcentratord/src/region/as923_4.rs: -------------------------------------------------------------------------------- 1 | pub const TX_MIN_MAX_FREQS: [(u32, u32); 1] = [(915000000, 928000000)]; 2 | -------------------------------------------------------------------------------- /libconcentratord/src/region/ism2400.rs: -------------------------------------------------------------------------------- 1 | pub const TX_MIN_MAX_FREQS: [(u32, u32); 1] = [(2400000000, 2483500000)]; 2 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1301/src/config/vendor/rak/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod rak2245; 2 | pub mod rak2246; 3 | pub mod rak2247; 4 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1302/src/config/vendor/miromico/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod gwc_02_lw_868; 2 | pub mod gwc_02_lw_915; 3 | -------------------------------------------------------------------------------- /rust-toolchain.toml: -------------------------------------------------------------------------------- 1 | [toolchain] 2 | channel = "1.89.0" 3 | components = ["rustfmt", "clippy"] 4 | profile = "default" 5 | -------------------------------------------------------------------------------- /libloragw-2g4/src/lib.rs: -------------------------------------------------------------------------------- 1 | #[macro_use] 2 | extern crate anyhow; 3 | 4 | pub mod gps; 5 | pub mod hal; 6 | mod mutex; 7 | pub mod wrapper; 8 | -------------------------------------------------------------------------------- /libloragw-2g4/src/mutex.rs: -------------------------------------------------------------------------------- 1 | use std::sync::{LazyLock, Mutex}; 2 | 3 | pub static CONCENTATOR: LazyLock> = LazyLock::new(|| Mutex::new(())); 4 | -------------------------------------------------------------------------------- /libloragw-sx1301/src/mutex.rs: -------------------------------------------------------------------------------- 1 | use std::sync::{LazyLock, Mutex}; 2 | 3 | pub static CONCENTATOR: LazyLock> = LazyLock::new(|| Mutex::new(())); 4 | -------------------------------------------------------------------------------- /libloragw-sx1302/src/mutex.rs: -------------------------------------------------------------------------------- 1 | use std::sync::{LazyLock, Mutex}; 2 | 3 | pub static CONCENTATOR: LazyLock> = LazyLock::new(|| Mutex::new(())); 4 | -------------------------------------------------------------------------------- /chirpstack-concentratord-2g4/src/handler/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod command; 2 | pub mod config; 3 | pub mod gps; 4 | pub mod jit; 5 | pub mod stats; 6 | pub mod uplink; 7 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1302/src/config/vendor/multitech/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod mtac_003e00; 2 | pub mod mtac_003u00; 3 | pub mod mtcap3_003e00; 4 | pub mod mtcap3_003u00; 5 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1301/src/config/vendor/multitech/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod mtac_lora_h_868; 2 | pub mod mtac_lora_h_915; 3 | pub mod mtcap_lora_868; 4 | pub mod mtcap_lora_915; 5 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1302/src/handler/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod beacon; 2 | pub mod command; 3 | pub mod config; 4 | pub mod gps; 5 | pub mod jit; 6 | pub mod stats; 7 | pub mod uplink; 8 | -------------------------------------------------------------------------------- /libconcentratord/src/socket.rs: -------------------------------------------------------------------------------- 1 | use std::sync::{LazyLock, Mutex}; 2 | 3 | pub static ZMQ_CONTEXT: LazyLock> = 4 | LazyLock::new(|| Mutex::new(zmq::Context::new())); 5 | -------------------------------------------------------------------------------- /libloragw-sx1302/src/lib.rs: -------------------------------------------------------------------------------- 1 | #[macro_use] 2 | extern crate anyhow; 3 | 4 | pub mod com; 5 | pub mod gps; 6 | pub mod hal; 7 | mod mutex; 8 | mod timespec; 9 | pub mod wrapper; 10 | -------------------------------------------------------------------------------- /libloragw-sx1302/wrapper.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | #include 6 | -------------------------------------------------------------------------------- /libloragw-2g4/src/gps.rs: -------------------------------------------------------------------------------- 1 | /// GPS coordinates. 2 | #[derive(Clone, Copy, Debug)] 3 | pub struct Coordinates { 4 | pub latitude: f64, 5 | pub longitude: f64, 6 | pub altitude: i16, 7 | } 8 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1301/src/handler/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod beacon; 2 | pub mod command; 3 | pub mod config; 4 | pub mod gps; 5 | pub mod jit; 6 | pub mod stats; 7 | pub mod timersync; 8 | pub mod uplink; 9 | -------------------------------------------------------------------------------- /libloragw-sx1301/src/lib.rs: -------------------------------------------------------------------------------- 1 | #[macro_use] 2 | extern crate anyhow; 3 | 4 | pub mod gps; 5 | pub mod hal; 6 | mod mutex; 7 | pub mod reg; 8 | pub mod spi; 9 | mod timespec; 10 | pub mod wrapper; 11 | -------------------------------------------------------------------------------- /libloragw-2g4/src/wrapper.rs: -------------------------------------------------------------------------------- 1 | #![allow(non_upper_case_globals)] 2 | #![allow(non_camel_case_types)] 3 | #![allow(non_snake_case)] 4 | #![allow(dead_code)] 5 | 6 | include!(concat!(env!("OUT_DIR"), "/bindings.rs")); 7 | -------------------------------------------------------------------------------- /libloragw-sx1301/src/wrapper.rs: -------------------------------------------------------------------------------- 1 | #![allow(non_upper_case_globals)] 2 | #![allow(non_camel_case_types)] 3 | #![allow(non_snake_case)] 4 | #![allow(dead_code)] 5 | 6 | include!(concat!(env!("OUT_DIR"), "/bindings.rs")); 7 | -------------------------------------------------------------------------------- /libloragw-sx1302/src/wrapper.rs: -------------------------------------------------------------------------------- 1 | #![allow(non_upper_case_globals)] 2 | #![allow(non_camel_case_types)] 3 | #![allow(non_snake_case)] 4 | #![allow(dead_code)] 5 | 6 | include!(concat!(env!("OUT_DIR"), "/bindings.rs")); 7 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1302/src/config/vendor/semtech/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod sx1302c490gw1; 2 | pub mod sx1302c868gw1; 3 | pub mod sx1302c915gw1; 4 | pub mod sx1302css868gw1; 5 | pub mod sx1302css915gw1; 6 | pub mod sx1302css923gw1; 7 | -------------------------------------------------------------------------------- /libloragw-sx1301/wrapper.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false # force the usage of a template 2 | contact_links: 3 | - name: ChirpStack Community Forum 4 | url: https://forum.chirpstack.io/ 5 | about: I need support with ChirpStack. 6 | -------------------------------------------------------------------------------- /packaging/vendor/kerlink/ifemtocell/files/chirpstack-concentratord.monit: -------------------------------------------------------------------------------- 1 | check process chirpstack-concentratord pidfile /var/run/chirpstack-concentratord.pid 2 | start program = "/etc/init.d/chirpstack-concentratord start" 3 | stop program = "/etc/init.d/chirpstack-concentratord stop" 4 | -------------------------------------------------------------------------------- /packaging/vendor/multitech/conduit-ap/files/chirpstack-concentratord.monit: -------------------------------------------------------------------------------- 1 | check process chirpstack-concentratord pidfile /var/run/chirpstack-concentratord.pid 2 | start program = "/etc/init.d/chirpstack-concentratord start" 3 | stop program = "/etc/init.d/chirpstack-concentratord stop" 4 | -------------------------------------------------------------------------------- /packaging/vendor/multitech/conduit-ap3/files/chirpstack-concentratord.monit: -------------------------------------------------------------------------------- 1 | check process chirpstack-concentratord pidfile /var/run/chirpstack-concentratord.pid 2 | start program = "/etc/init.d/chirpstack-concentratord start" 3 | stop program = "/etc/init.d/chirpstack-concentratord stop" 4 | -------------------------------------------------------------------------------- /libconcentratord/src/region/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod as923; 2 | pub mod as923_2; 3 | pub mod as923_3; 4 | pub mod as923_4; 5 | pub mod au915; 6 | pub mod cn470; 7 | pub mod eu433; 8 | pub mod eu868; 9 | pub mod in865; 10 | pub mod ism2400; 11 | pub mod kr920; 12 | pub mod ru864; 13 | pub mod us915; 14 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1301/config/channels_ru864.toml: -------------------------------------------------------------------------------- 1 | # LoRa concentrator configuration. 2 | [gateway.concentrator] 3 | 4 | # Multi spreading-factor channels (LoRa). 5 | multi_sf_channels=[ 6 | 868900000, 7 | 869100000, 8 | 0, 9 | 0, 10 | 0, 11 | 0, 12 | 0, 13 | 0, 14 | ] 15 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1302/config/channels_ru864.toml: -------------------------------------------------------------------------------- 1 | # LoRa concentrator configuration. 2 | [gateway.concentrator] 3 | 4 | # Multi spreading-factor channels (LoRa). 5 | multi_sf_channels=[ 6 | 868900000, 7 | 869100000, 8 | 0, 9 | 0, 10 | 0, 11 | 0, 12 | 0, 13 | 0, 14 | ] 15 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1301/config/channels_eu433.toml: -------------------------------------------------------------------------------- 1 | # LoRa concentrator configuration. 2 | [gateway.concentrator] 3 | 4 | # Multi spreading-factor channels (LoRa). 5 | multi_sf_channels=[ 6 | 433175000, 7 | 433375000, 8 | 433575000, 9 | 0, 10 | 0, 11 | 0, 12 | 0, 13 | 0, 14 | ] 15 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1301/config/channels_in865.toml: -------------------------------------------------------------------------------- 1 | # LoRa concentrator configuration. 2 | [gateway.concentrator] 3 | 4 | # Multi spreading-factor channels (LoRa). 5 | multi_sf_channels=[ 6 | 865062500, 7 | 865402500, 8 | 865985000, 9 | 0, 10 | 0, 11 | 0, 12 | 0, 13 | 0, 14 | ] 15 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1301/config/channels_kr920.toml: -------------------------------------------------------------------------------- 1 | # LoRa concentrator configuration. 2 | [gateway.concentrator] 3 | 4 | # Multi spreading-factor channels (LoRa). 5 | multi_sf_channels=[ 6 | 922100000, 7 | 922300000, 8 | 922500000, 9 | 0, 10 | 0, 11 | 0, 12 | 0, 13 | 0, 14 | ] 15 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1302/config/channels_eu433.toml: -------------------------------------------------------------------------------- 1 | # LoRa concentrator configuration. 2 | [gateway.concentrator] 3 | 4 | # Multi spreading-factor channels (LoRa). 5 | multi_sf_channels=[ 6 | 433175000, 7 | 433375000, 8 | 433575000, 9 | 0, 10 | 0, 11 | 0, 12 | 0, 13 | 0, 14 | ] 15 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1302/config/channels_in865.toml: -------------------------------------------------------------------------------- 1 | # LoRa concentrator configuration. 2 | [gateway.concentrator] 3 | 4 | # Multi spreading-factor channels (LoRa). 5 | multi_sf_channels=[ 6 | 865062500, 7 | 865402500, 8 | 865985000, 9 | 0, 10 | 0, 11 | 0, 12 | 0, 13 | 0, 14 | ] 15 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1302/config/channels_kr920.toml: -------------------------------------------------------------------------------- 1 | # LoRa concentrator configuration. 2 | [gateway.concentrator] 3 | 4 | # Multi spreading-factor channels (LoRa). 5 | multi_sf_channels=[ 6 | 922100000, 7 | 922300000, 8 | 922500000, 9 | 0, 10 | 0, 11 | 0, 12 | 0, 13 | 0, 14 | ] 15 | -------------------------------------------------------------------------------- /libloragw-2g4/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "libloragw-2g4" 3 | version = "1.0.0" 4 | authors = ["Orne Brocaar "] 5 | edition = "2024" 6 | publish = false 7 | 8 | [dependencies] 9 | anyhow = { workspace = true } 10 | 11 | [build-dependencies] 12 | bindgen = { workspace = true } 13 | -------------------------------------------------------------------------------- /libconcentratord/src/helpers.rs: -------------------------------------------------------------------------------- 1 | use std::time::Duration; 2 | 3 | pub trait ToConcentratorCount { 4 | fn to_concentrator_count(self) -> u32; 5 | } 6 | 7 | impl ToConcentratorCount for Duration { 8 | fn to_concentrator_count(self) -> u32 { 9 | (self.as_micros() % (1 << 32)) as u32 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /libloragw-sx1301/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "libloragw-sx1301" 3 | version = "1.0.0" 4 | authors = ["Orne Brocaar "] 5 | edition = "2024" 6 | publish = false 7 | 8 | [dependencies] 9 | anyhow = { workspace = true } 10 | 11 | [build-dependencies] 12 | bindgen = { workspace = true } 13 | -------------------------------------------------------------------------------- /libloragw-sx1302/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "libloragw-sx1302" 3 | version = "1.0.0" 4 | authors = ["Orne Brocaar "] 5 | edition = "2024" 6 | publish = false 7 | 8 | [dependencies] 9 | anyhow = { workspace = true } 10 | 11 | [build-dependencies] 12 | bindgen = { workspace = true } 13 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # Please see the documentation for all configuration options: 2 | # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates 3 | 4 | version: 2 5 | updates: 6 | - package-ecosystem: "cargo" 7 | directory: "/" 8 | schedule: 9 | interval: "weekly" 10 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # hidden files 2 | .* 3 | !.cargo 4 | !.github 5 | !.vscode 6 | 7 | # rust builds / cache 8 | target 9 | 10 | # dist folder 11 | /dist 12 | 13 | # build folders 14 | /packaging/vendor/*/*/package 15 | /packaging/vendor/*/*/*.ipk 16 | 17 | # vendored files 18 | /vendor 19 | 20 | # Generated Bitbake recipes 21 | *.bb 22 | -------------------------------------------------------------------------------- /libconcentratord/src/lib.rs: -------------------------------------------------------------------------------- 1 | #[macro_use] 2 | extern crate anyhow; 3 | 4 | pub mod commands; 5 | pub mod error; 6 | pub mod events; 7 | pub mod gnss; 8 | pub mod gpsd; 9 | mod helpers; 10 | pub mod jitqueue; 11 | pub mod region; 12 | pub mod regulation; 13 | pub mod reset; 14 | pub mod signals; 15 | mod socket; 16 | pub mod stats; 17 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1301/config/channels_cn470_1.toml: -------------------------------------------------------------------------------- 1 | # LoRa concentrator configuration. 2 | [gateway.concentrator] 3 | 4 | # Multi spreading-factor channels (LoRa). 5 | multi_sf_channels=[ 6 | 471900000, 7 | 472100000, 8 | 472300000, 9 | 472500000, 10 | 472700000, 11 | 472900000, 12 | 473100000, 13 | 473300000, 14 | ] 15 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1301/config/channels_cn470_2.toml: -------------------------------------------------------------------------------- 1 | # LoRa concentrator configuration. 2 | [gateway.concentrator] 3 | 4 | # Multi spreading-factor channels (LoRa). 5 | multi_sf_channels=[ 6 | 473500000, 7 | 473700000, 8 | 473900000, 9 | 474100000, 10 | 474300000, 11 | 474500000, 12 | 474700000, 13 | 474900000, 14 | ] 15 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1301/config/channels_cn470_3.toml: -------------------------------------------------------------------------------- 1 | # LoRa concentrator configuration. 2 | [gateway.concentrator] 3 | 4 | # Multi spreading-factor channels (LoRa). 5 | multi_sf_channels=[ 6 | 475100000, 7 | 475300000, 8 | 475500000, 9 | 475700000, 10 | 475900000, 11 | 476100000, 12 | 476300000, 13 | 476500000, 14 | ] 15 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1301/config/channels_cn470_4.toml: -------------------------------------------------------------------------------- 1 | # LoRa concentrator configuration. 2 | [gateway.concentrator] 3 | 4 | # Multi spreading-factor channels (LoRa). 5 | multi_sf_channels=[ 6 | 476700000, 7 | 476900000, 8 | 477100000, 9 | 477300000, 10 | 477500000, 11 | 477700000, 12 | 477900000, 13 | 478100000, 14 | ] 15 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1301/config/channels_cn470_5.toml: -------------------------------------------------------------------------------- 1 | # LoRa concentrator configuration. 2 | [gateway.concentrator] 3 | 4 | # Multi spreading-factor channels (LoRa). 5 | multi_sf_channels=[ 6 | 478300000, 7 | 478500000, 8 | 478700000, 9 | 478900000, 10 | 479100000, 11 | 479300000, 12 | 479500000, 13 | 479700000, 14 | ] 15 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1301/config/channels_cn470_6.toml: -------------------------------------------------------------------------------- 1 | # LoRa concentrator configuration. 2 | [gateway.concentrator] 3 | 4 | # Multi spreading-factor channels (LoRa). 5 | multi_sf_channels=[ 6 | 479900000, 7 | 480100000, 8 | 480300000, 9 | 480500000, 10 | 480700000, 11 | 480900000, 12 | 481100000, 13 | 481300000, 14 | ] 15 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1301/config/channels_cn470_7.toml: -------------------------------------------------------------------------------- 1 | # LoRa concentrator configuration. 2 | [gateway.concentrator] 3 | 4 | # Multi spreading-factor channels (LoRa). 5 | multi_sf_channels=[ 6 | 481500000, 7 | 481700000, 8 | 481900000, 9 | 482100000, 10 | 482300000, 11 | 482500000, 12 | 482700000, 13 | 482900000, 14 | ] 15 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1301/config/channels_cn470_8.toml: -------------------------------------------------------------------------------- 1 | # LoRa concentrator configuration. 2 | [gateway.concentrator] 3 | 4 | # Multi spreading-factor channels (LoRa). 5 | multi_sf_channels=[ 6 | 483100000, 7 | 483300000, 8 | 483500000, 9 | 483700000, 10 | 483900000, 11 | 484100000, 12 | 484300000, 13 | 484500000, 14 | ] 15 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1301/config/channels_cn470_9.toml: -------------------------------------------------------------------------------- 1 | # LoRa concentrator configuration. 2 | [gateway.concentrator] 3 | 4 | # Multi spreading-factor channels (LoRa). 5 | multi_sf_channels=[ 6 | 484700000, 7 | 484900000, 8 | 485100000, 9 | 485300000, 10 | 485500000, 11 | 485700000, 12 | 485900000, 13 | 486100000, 14 | ] 15 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1301/config/channels_cn470_10.toml: -------------------------------------------------------------------------------- 1 | # LoRa concentrator configuration. 2 | [gateway.concentrator] 3 | 4 | # Multi spreading-factor channels (LoRa). 5 | multi_sf_channels=[ 6 | 486300000, 7 | 486500000, 8 | 486700000, 9 | 486900000, 10 | 487100000, 11 | 487300000, 12 | 487500000, 13 | 487700000, 14 | ] 15 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1301/config/channels_cn470_11.toml: -------------------------------------------------------------------------------- 1 | # LoRa concentrator configuration. 2 | [gateway.concentrator] 3 | 4 | # Multi spreading-factor channels (LoRa). 5 | multi_sf_channels=[ 6 | 487900000, 7 | 488100000, 8 | 488300000, 9 | 488500000, 10 | 488700000, 11 | 488900000, 12 | 489100000, 13 | 489300000, 14 | ] 15 | -------------------------------------------------------------------------------- /chirpstack-concentratord-2g4/src/config/vendor/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod multitech; 2 | pub mod rak; 3 | pub mod semtech; 4 | 5 | #[derive(Default, Clone)] 6 | pub struct Configuration { 7 | pub tty_path: String, 8 | pub tx_min_max_freqs: Vec<(u32, u32)>, 9 | pub reset_pin: Option<(String, u32)>, 10 | pub boot0_pin: Option<(String, u32)>, 11 | } 12 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1301/config/channels_cn470_0.toml: -------------------------------------------------------------------------------- 1 | # LoRa concentrator configuration. 2 | [gateway.concentrator] 3 | 4 | # Multi spreading-factor channels (LoRa). 5 | multi_sf_channels=[ 6 | 470300000, 7 | 470500000, 8 | 470700000, 9 | 470900000, 10 | 471100000, 11 | 471300000, 12 | 471500000, 13 | 471700000, 14 | ] 15 | 16 | -------------------------------------------------------------------------------- /packaging/vendor/multitech/conduit/files/2g4/chirpstack-concentratord-2g4-ap1.monit: -------------------------------------------------------------------------------- 1 | check process chirpstack-concentratord-2g4-ap1 pidfile /var/run/chirpstack-concentratord-2g4-ap1.pid 2 | start program = "/bin/bash -c '/etc/init.d/chirpstack-concentratord-2g4-ap1 start'" 3 | stop program = "/bin/bash -c '/etc/init.d/chirpstack-concentratord-2g4-ap1 stop'" 4 | -------------------------------------------------------------------------------- /packaging/vendor/multitech/conduit/files/2g4/chirpstack-concentratord-2g4-ap2.monit: -------------------------------------------------------------------------------- 1 | check process chirpstack-concentratord-2g4-ap2 pidfile /var/run/chirpstack-concentratord-2g4-ap2.pid 2 | start program = "/bin/bash -c '/etc/init.d/chirpstack-concentratord-2g4-ap2 start'" 3 | stop program = "/bin/bash -c '/etc/init.d/chirpstack-concentratord-2g4-ap2 stop'" 4 | -------------------------------------------------------------------------------- /packaging/vendor/multitech/conduit/files/sx1301/chirpstack-concentratord-sx1301-ap1.monit: -------------------------------------------------------------------------------- 1 | check process chirpstack-concentratord-sx1301-ap1 pidfile /var/run/chirpstack-concentratord-sx1301-ap1.pid 2 | start program = "/bin/bash -c '/etc/init.d/chirpstack-concentratord-sx1301-ap1 start'" 3 | stop program = "/bin/bash -c '/etc/init.d/chirpstack-concentratord-sx1301-ap1 stop'" 4 | -------------------------------------------------------------------------------- /packaging/vendor/multitech/conduit/files/sx1301/chirpstack-concentratord-sx1301-ap2.monit: -------------------------------------------------------------------------------- 1 | check process chirpstack-concentratord-sx1301-ap2 pidfile /var/run/chirpstack-concentratord-sx1301-ap2.pid 2 | start program = "/bin/bash -c '/etc/init.d/chirpstack-concentratord-sx1301-ap2 start'" 3 | stop program = "/bin/bash -c '/etc/init.d/chirpstack-concentratord-sx1301-ap2 stop'" 4 | -------------------------------------------------------------------------------- /packaging/vendor/multitech/conduit/files/sx1302/chirpstack-concentratord-sx1302-ap1.monit: -------------------------------------------------------------------------------- 1 | check process chirpstack-concentratord-sx1302-ap1 pidfile /var/run/chirpstack-concentratord-sx1302-ap1.pid 2 | start program = "/bin/bash -c '/etc/init.d/chirpstack-concentratord-sx1302-ap1 start'" 3 | stop program = "/bin/bash -c '/etc/init.d/chirpstack-concentratord-sx1302-ap1 stop'" 4 | -------------------------------------------------------------------------------- /packaging/vendor/multitech/conduit/files/sx1302/chirpstack-concentratord-sx1302-ap2.monit: -------------------------------------------------------------------------------- 1 | check process chirpstack-concentratord-sx1302-ap2 pidfile /var/run/chirpstack-concentratord-sx1302-ap2.pid 2 | start program = "/bin/bash -c '/etc/init.d/chirpstack-concentratord-sx1302-ap2 start'" 3 | stop program = "/bin/bash -c '/etc/init.d/chirpstack-concentratord-sx1302-ap2 stop'" 4 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1301/src/config/vendor/pi_supply/lora_gateway_hat.rs: -------------------------------------------------------------------------------- 1 | use anyhow::Result; 2 | 3 | use super::super::super::super::config; 4 | use super::super::Configuration; 5 | 6 | pub fn new(conf: &config::Configuration) -> Result { 7 | let mut c = super::super::rak::rak2247::new(conf)?; 8 | c.reset_pin = conf.gateway.get_sx1301_reset_pin("/dev/gpiochip0", 22); 9 | Ok(c) 10 | } 11 | -------------------------------------------------------------------------------- /libloragw-sx1301/src/reg.rs: -------------------------------------------------------------------------------- 1 | use anyhow::Result; 2 | 3 | use super::{mutex, wrapper}; 4 | 5 | /// LoRa concentrator register write. 6 | pub fn reg_w(reg_id: u32, reg_value: i32) -> Result<()> { 7 | let _guard = mutex::CONCENTATOR.lock().unwrap(); 8 | let ret = unsafe { wrapper::lgw_reg_w(reg_id as u16, reg_value) }; 9 | if ret != 0 { 10 | return Err(anyhow!("lgw_reg_w failed")); 11 | } 12 | 13 | Ok(()) 14 | } 15 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1301/config/region_as923.toml: -------------------------------------------------------------------------------- 1 | # Beacon configuration. 2 | # 3 | # This requires a gateway with GPS / GNSS. 4 | [gateway.beacon] 5 | 6 | # Compulsory RFU size. 7 | compulsory_rfu_size=2 8 | 9 | # Beacon frequency / frequencies (Hz). 10 | frequencies=[ 11 | 923400000, 12 | ] 13 | 14 | # Bandwidth (Hz). 15 | bandwidth=125000 16 | 17 | # Spreading factor. 18 | spreading_factor=9 19 | 20 | # TX power. 21 | tx_power=14 22 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1301/config/region_as923_2.toml: -------------------------------------------------------------------------------- 1 | # Beacon configuration. 2 | # 3 | # This requires a gateway with GPS / GNSS. 4 | [gateway.beacon] 5 | 6 | # Compulsory RFU size. 7 | compulsory_rfu_size=2 8 | 9 | # Beacon frequency / frequencies (Hz). 10 | frequencies=[ 11 | 921600000, 12 | ] 13 | 14 | # Bandwidth (Hz). 15 | bandwidth=125000 16 | 17 | # Spreading factor. 18 | spreading_factor=9 19 | 20 | # TX power. 21 | tx_power=14 22 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1301/config/region_as923_3.toml: -------------------------------------------------------------------------------- 1 | # Beacon configuration. 2 | # 3 | # This requires a gateway with GPS / GNSS. 4 | [gateway.beacon] 5 | 6 | # Compulsory RFU size. 7 | compulsory_rfu_size=2 8 | 9 | # Beacon frequency / frequencies (Hz). 10 | frequencies=[ 11 | 916800000, 12 | ] 13 | 14 | # Bandwidth (Hz). 15 | bandwidth=125000 16 | 17 | # Spreading factor. 18 | spreading_factor=9 19 | 20 | # TX power. 21 | tx_power=14 22 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1301/config/region_as923_4.toml: -------------------------------------------------------------------------------- 1 | # Beacon configuration. 2 | # 3 | # This requires a gateway with GPS / GNSS. 4 | [gateway.beacon] 5 | 6 | # Compulsory RFU size. 7 | compulsory_rfu_size=2 8 | 9 | # Beacon frequency / frequencies (Hz). 10 | frequencies=[ 11 | 917500000, 12 | ] 13 | 14 | # Bandwidth (Hz). 15 | bandwidth=125000 16 | 17 | # Spreading factor. 18 | spreading_factor=9 19 | 20 | # TX power. 21 | tx_power=14 22 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1301/config/region_eu433.toml: -------------------------------------------------------------------------------- 1 | # Beacon configuration. 2 | # 3 | # This requires a gateway with GPS / GNSS. 4 | [gateway.beacon] 5 | 6 | # Compulsory RFU size. 7 | compulsory_rfu_size=2 8 | 9 | # Beacon frequency / frequencies (Hz). 10 | frequencies=[ 11 | 434665000, 12 | ] 13 | 14 | # Bandwidth (Hz). 15 | bandwidth=125000 16 | 17 | # Spreading factor. 18 | spreading_factor=9 19 | 20 | # TX power. 21 | tx_power=12 22 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1301/config/region_eu868.toml: -------------------------------------------------------------------------------- 1 | # Beacon configuration. 2 | # 3 | # This requires a gateway with GPS / GNSS. 4 | [gateway.beacon] 5 | 6 | # Compulsory RFU size. 7 | compulsory_rfu_size=2 8 | 9 | # Beacon frequency / frequencies (Hz). 10 | frequencies=[ 11 | 869525000, 12 | ] 13 | 14 | # Bandwidth (Hz). 15 | bandwidth=125000 16 | 17 | # Spreading factor. 18 | spreading_factor=9 19 | 20 | # TX power. 21 | tx_power=14 22 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1301/config/region_kr920.toml: -------------------------------------------------------------------------------- 1 | # Beacon configuration. 2 | # 3 | # This requires a gateway with GPS / GNSS. 4 | [gateway.beacon] 5 | 6 | # Compulsory RFU size. 7 | compulsory_rfu_size=2 8 | 9 | # Beacon frequency / frequencies (Hz). 10 | frequencies=[ 11 | 923100000, 12 | ] 13 | 14 | # Bandwidth (Hz). 15 | bandwidth=125000 16 | 17 | # Spreading factor. 18 | spreading_factor=9 19 | 20 | # TX power. 21 | tx_power=14 22 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1302/config/region_as923.toml: -------------------------------------------------------------------------------- 1 | # Beacon configuration. 2 | # 3 | # This requires a gateway with GPS / GNSS. 4 | [gateway.beacon] 5 | 6 | # Compulsory RFU size. 7 | compulsory_rfu_size=2 8 | 9 | # Beacon frequency / frequencies (Hz). 10 | frequencies=[ 11 | 923400000, 12 | ] 13 | 14 | # Bandwidth (Hz). 15 | bandwidth=125000 16 | 17 | # Spreading factor. 18 | spreading_factor=9 19 | 20 | # TX power. 21 | tx_power=14 22 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1302/config/region_as923_2.toml: -------------------------------------------------------------------------------- 1 | # Beacon configuration. 2 | # 3 | # This requires a gateway with GPS / GNSS. 4 | [gateway.beacon] 5 | 6 | # Compulsory RFU size. 7 | compulsory_rfu_size=2 8 | 9 | # Beacon frequency / frequencies (Hz). 10 | frequencies=[ 11 | 921600000, 12 | ] 13 | 14 | # Bandwidth (Hz). 15 | bandwidth=125000 16 | 17 | # Spreading factor. 18 | spreading_factor=9 19 | 20 | # TX power. 21 | tx_power=14 22 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1302/config/region_as923_3.toml: -------------------------------------------------------------------------------- 1 | # Beacon configuration. 2 | # 3 | # This requires a gateway with GPS / GNSS. 4 | [gateway.beacon] 5 | 6 | # Compulsory RFU size. 7 | compulsory_rfu_size=2 8 | 9 | # Beacon frequency / frequencies (Hz). 10 | frequencies=[ 11 | 916800000, 12 | ] 13 | 14 | # Bandwidth (Hz). 15 | bandwidth=125000 16 | 17 | # Spreading factor. 18 | spreading_factor=9 19 | 20 | # TX power. 21 | tx_power=14 22 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1302/config/region_as923_4.toml: -------------------------------------------------------------------------------- 1 | # Beacon configuration. 2 | # 3 | # This requires a gateway with GPS / GNSS. 4 | [gateway.beacon] 5 | 6 | # Compulsory RFU size. 7 | compulsory_rfu_size=2 8 | 9 | # Beacon frequency / frequencies (Hz). 10 | frequencies=[ 11 | 917500000, 12 | ] 13 | 14 | # Bandwidth (Hz). 15 | bandwidth=125000 16 | 17 | # Spreading factor. 18 | spreading_factor=9 19 | 20 | # TX power. 21 | tx_power=14 22 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1302/config/region_eu433.toml: -------------------------------------------------------------------------------- 1 | # Beacon configuration. 2 | # 3 | # This requires a gateway with GPS / GNSS. 4 | [gateway.beacon] 5 | 6 | # Compulsory RFU size. 7 | compulsory_rfu_size=2 8 | 9 | # Beacon frequency / frequencies (Hz). 10 | frequencies=[ 11 | 434665000, 12 | ] 13 | 14 | # Bandwidth (Hz). 15 | bandwidth=125000 16 | 17 | # Spreading factor. 18 | spreading_factor=9 19 | 20 | # TX power. 21 | tx_power=12 22 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1302/config/region_eu868.toml: -------------------------------------------------------------------------------- 1 | # Beacon configuration. 2 | # 3 | # This requires a gateway with GPS / GNSS. 4 | [gateway.beacon] 5 | 6 | # Compulsory RFU size. 7 | compulsory_rfu_size=2 8 | 9 | # Beacon frequency / frequencies (Hz). 10 | frequencies=[ 11 | 869525000, 12 | ] 13 | 14 | # Bandwidth (Hz). 15 | bandwidth=125000 16 | 17 | # Spreading factor. 18 | spreading_factor=9 19 | 20 | # TX power. 21 | tx_power=14 22 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1302/config/region_kr920.toml: -------------------------------------------------------------------------------- 1 | # Beacon configuration. 2 | # 3 | # This requires a gateway with GPS / GNSS. 4 | [gateway.beacon] 5 | 6 | # Compulsory RFU size. 7 | compulsory_rfu_size=2 8 | 9 | # Beacon frequency / frequencies (Hz). 10 | frequencies=[ 11 | 923100000, 12 | ] 13 | 14 | # Bandwidth (Hz). 15 | bandwidth=125000 16 | 17 | # Spreading factor. 18 | spreading_factor=9 19 | 20 | # TX power. 21 | tx_power=14 22 | -------------------------------------------------------------------------------- /gateway-id/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "gateway-id" 3 | repository = "https://github.com/brocaar/chirpstack-concentratord/" 4 | description = "Print the Gateway ID" 5 | license = "MIT" 6 | version = "4.5.3" 7 | authors = ["Orne Brocaar "] 8 | edition = "2024" 9 | publish = false 10 | 11 | [dependencies] 12 | zmq = { workspace = true } 13 | clap = { workspace = true } 14 | chirpstack_api = { workspace = true } 15 | -------------------------------------------------------------------------------- /packaging/vendor/multitech/conduit/files/sx1302/region_eu868.toml: -------------------------------------------------------------------------------- 1 | # Beacon configuration. 2 | # 3 | # This requires a gateway with GPS / GNSS. 4 | [gateway.beacon] 5 | 6 | # Compulsory RFU size. 7 | compulsory_rfu_size=2 8 | 9 | # Beacon frequency / frequencies (Hz). 10 | frequencies=[ 11 | 869525000, 12 | ] 13 | 14 | # Bandwidth (Hz). 15 | bandwidth=125000 16 | 17 | # Spreading factor. 18 | spreading_factor=9 19 | 20 | # TX power. 21 | tx_power=14 22 | -------------------------------------------------------------------------------- /gateway-location/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "gateway-location" 3 | repository = "https://github.com/brocaar/chirpstack-concentratord/" 4 | description = "Print the Gateway location" 5 | license = "MIT" 6 | version = "4.5.3" 7 | authors = ["Orne Brocaar "] 8 | edition = "2024" 9 | publish = false 10 | 11 | [dependencies] 12 | zmq = { workspace = true } 13 | clap = { workspace = true } 14 | chirpstack_api = { workspace = true } 15 | -------------------------------------------------------------------------------- /chirpstack-concentratord-2g4/src/config/vendor/rak/rak5148.rs: -------------------------------------------------------------------------------- 1 | use super::super::super::super::config; 2 | use super::super::Configuration; 3 | use libconcentratord::region; 4 | 5 | pub fn new(conf: &config::Configuration) -> Configuration { 6 | Configuration { 7 | tty_path: conf.gateway.get_com_dev_path("/dev/ttyACM0"), 8 | tx_min_max_freqs: region::ism2400::TX_MIN_MAX_FREQS.to_vec(), 9 | reset_pin: None, 10 | boot0_pin: None, 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /libconcentratord/src/error.rs: -------------------------------------------------------------------------------- 1 | #[derive(thiserror::Error, Debug)] 2 | pub enum Error { 3 | #[error("Item exceeds duty-cycle")] 4 | DutyCycle, 5 | 6 | #[error("Item would exceed duty-cycle with future items")] 7 | DutyCycleFutureItems, 8 | 9 | #[error("No band for freq: {0}, tx_power_eirp: {1}")] 10 | BandNotFound(u32, i8), 11 | 12 | #[error("Timeout")] 13 | Timeout, 14 | 15 | #[error(transparent)] 16 | Anyhow(#[from] anyhow::Error), 17 | } 18 | -------------------------------------------------------------------------------- /chirpstack-concentratord-2g4/src/config/vendor/multitech/mtac_lora_2g4.rs: -------------------------------------------------------------------------------- 1 | use super::super::super::super::config; 2 | use super::super::Configuration; 3 | use libconcentratord::region; 4 | 5 | pub fn new(conf: &config::Configuration) -> Configuration { 6 | Configuration { 7 | tty_path: conf.gateway.get_com_dev_path("/dev/ttyACM0"), 8 | tx_min_max_freqs: region::ism2400::TX_MIN_MAX_FREQS.to_vec(), 9 | reset_pin: None, 10 | boot0_pin: None, 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /chirpstack-concentratord-2g4/config/channels_ism2400.toml: -------------------------------------------------------------------------------- 1 | # LoRa concentrator configuration. 2 | [gateway.concentrator] 3 | 4 | [[gateway.concentrator.channels]] 5 | frequency=2403000000 6 | bandwidth=812000 7 | spreading_factor=12 8 | 9 | [[gateway.concentrator.channels]] 10 | frequency=2479000000 11 | bandwidth=812000 12 | spreading_factor=12 13 | 14 | [[gateway.concentrator.channels]] 15 | frequency=2425000000 16 | bandwidth=812000 17 | spreading_factor=12 18 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1301/config/channels_as923.toml: -------------------------------------------------------------------------------- 1 | # LoRa concentrator configuration. 2 | [gateway.concentrator] 3 | 4 | # Multi spreading-factor channels (LoRa). 5 | multi_sf_channels=[ 6 | 923200000, 7 | 923400000, 8 | 923600000, 9 | 923800000, 10 | 924000000, 11 | 924200000, 12 | 924400000, 13 | 924600000, 14 | ] 15 | 16 | # LoRa std channel (single spreading-factor). 17 | [gateway.concentrator.lora_std] 18 | frequency=924500000 19 | bandwidth=250000 20 | spreading_factor=7 21 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1301/config/channels_as923_2.toml: -------------------------------------------------------------------------------- 1 | # LoRa concentrator configuration. 2 | [gateway.concentrator] 3 | 4 | # Multi spreading-factor channels (LoRa). 5 | multi_sf_channels=[ 6 | 921400000, 7 | 921600000, 8 | 921800000, 9 | 922000000, 10 | 922200000, 11 | 922400000, 12 | 922600000, 13 | 922800000, 14 | ] 15 | 16 | # LoRa std channel (single spreading-factor). 17 | [gateway.concentrator.lora_std] 18 | frequency=922700000 19 | bandwidth=250000 20 | spreading_factor=7 21 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1301/config/channels_as923_3.toml: -------------------------------------------------------------------------------- 1 | # LoRa concentrator configuration. 2 | [gateway.concentrator] 3 | 4 | # Multi spreading-factor channels (LoRa). 5 | multi_sf_channels=[ 6 | 916600000, 7 | 916800000, 8 | 917000000, 9 | 917200000, 10 | 917400000, 11 | 917600000, 12 | 917800000, 13 | 918000000, 14 | ] 15 | 16 | # LoRa std channel (single spreading-factor). 17 | [gateway.concentrator.lora_std] 18 | frequency=917900000 19 | bandwidth=250000 20 | spreading_factor=7 21 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1301/config/channels_au915_0.toml: -------------------------------------------------------------------------------- 1 | # LoRa concentrator configuration. 2 | [gateway.concentrator] 3 | 4 | # Multi spreading-factor channels (LoRa). 5 | multi_sf_channels=[ 6 | 915200000, 7 | 915400000, 8 | 915600000, 9 | 915800000, 10 | 916000000, 11 | 916200000, 12 | 916400000, 13 | 916600000, 14 | ] 15 | 16 | # LoRa std channel (single spreading-factor). 17 | [gateway.concentrator.lora_std] 18 | frequency=915900000 19 | bandwidth=500000 20 | spreading_factor=8 21 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1301/config/channels_au915_1.toml: -------------------------------------------------------------------------------- 1 | # LoRa concentrator configuration. 2 | [gateway.concentrator] 3 | 4 | # Multi spreading-factor channels (LoRa). 5 | multi_sf_channels=[ 6 | 916800000, 7 | 917000000, 8 | 917200000, 9 | 917400000, 10 | 917600000, 11 | 917800000, 12 | 918000000, 13 | 918200000, 14 | ] 15 | 16 | # LoRa std channel (single spreading-factor). 17 | [gateway.concentrator.lora_std] 18 | frequency=917500000 19 | bandwidth=500000 20 | spreading_factor=8 21 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1301/config/channels_au915_2.toml: -------------------------------------------------------------------------------- 1 | # LoRa concentrator configuration. 2 | [gateway.concentrator] 3 | 4 | # Multi spreading-factor channels (LoRa). 5 | multi_sf_channels=[ 6 | 918400000, 7 | 918600000, 8 | 918800000, 9 | 919000000, 10 | 919200000, 11 | 919400000, 12 | 919600000, 13 | 919800000, 14 | ] 15 | 16 | # LoRa std channel (single spreading-factor). 17 | [gateway.concentrator.lora_std] 18 | frequency=919100000 19 | bandwidth=500000 20 | spreading_factor=8 21 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1301/config/channels_au915_3.toml: -------------------------------------------------------------------------------- 1 | # LoRa concentrator configuration. 2 | [gateway.concentrator] 3 | 4 | # Multi spreading-factor channels (LoRa). 5 | multi_sf_channels=[ 6 | 920000000, 7 | 920200000, 8 | 920400000, 9 | 920600000, 10 | 920800000, 11 | 921000000, 12 | 921200000, 13 | 921400000, 14 | ] 15 | 16 | # LoRa std channel (single spreading-factor). 17 | [gateway.concentrator.lora_std] 18 | frequency=920700000 19 | bandwidth=500000 20 | spreading_factor=8 21 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1301/config/channels_au915_4.toml: -------------------------------------------------------------------------------- 1 | # LoRa concentrator configuration. 2 | [gateway.concentrator] 3 | 4 | # Multi spreading-factor channels (LoRa). 5 | multi_sf_channels=[ 6 | 921600000, 7 | 921800000, 8 | 922000000, 9 | 922200000, 10 | 922400000, 11 | 922600000, 12 | 922800000, 13 | 923000000, 14 | ] 15 | 16 | # LoRa std channel (single spreading-factor). 17 | [gateway.concentrator.lora_std] 18 | frequency=922300000 19 | bandwidth=500000 20 | spreading_factor=8 21 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1301/config/channels_au915_5.toml: -------------------------------------------------------------------------------- 1 | # LoRa concentrator configuration. 2 | [gateway.concentrator] 3 | 4 | # Multi spreading-factor channels (LoRa). 5 | multi_sf_channels=[ 6 | 923200000, 7 | 923400000, 8 | 923600000, 9 | 923800000, 10 | 924000000, 11 | 924200000, 12 | 924400000, 13 | 924600000, 14 | ] 15 | 16 | # LoRa std channel (single spreading-factor). 17 | [gateway.concentrator.lora_std] 18 | frequency=923900000 19 | bandwidth=500000 20 | spreading_factor=8 21 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1301/config/channels_au915_6.toml: -------------------------------------------------------------------------------- 1 | # LoRa concentrator configuration. 2 | [gateway.concentrator] 3 | 4 | # Multi spreading-factor channels (LoRa). 5 | multi_sf_channels=[ 6 | 924800000, 7 | 925000000, 8 | 925200000, 9 | 925400000, 10 | 925600000, 11 | 925800000, 12 | 926000000, 13 | 926200000, 14 | ] 15 | 16 | # LoRa std channel (single spreading-factor). 17 | [gateway.concentrator.lora_std] 18 | frequency=925500000 19 | bandwidth=500000 20 | spreading_factor=8 21 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1301/config/channels_au915_7.toml: -------------------------------------------------------------------------------- 1 | # LoRa concentrator configuration. 2 | [gateway.concentrator] 3 | 4 | # Multi spreading-factor channels (LoRa). 5 | multi_sf_channels=[ 6 | 926400000, 7 | 926600000, 8 | 926800000, 9 | 927000000, 10 | 927200000, 11 | 927400000, 12 | 927600000, 13 | 927800000, 14 | ] 15 | 16 | # LoRa std channel (single spreading-factor). 17 | [gateway.concentrator.lora_std] 18 | frequency=927100000 19 | bandwidth=500000 20 | spreading_factor=8 21 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1301/config/channels_us915_0.toml: -------------------------------------------------------------------------------- 1 | # LoRa concentrator configuration. 2 | [gateway.concentrator] 3 | 4 | # Multi spreading-factor channels (LoRa). 5 | multi_sf_channels=[ 6 | 902300000, 7 | 902500000, 8 | 902700000, 9 | 902900000, 10 | 903100000, 11 | 903300000, 12 | 903500000, 13 | 903700000, 14 | ] 15 | 16 | # LoRa std channel (single spreading-factor). 17 | [gateway.concentrator.lora_std] 18 | frequency=903000000 19 | bandwidth=500000 20 | spreading_factor=8 21 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1301/config/channels_us915_1.toml: -------------------------------------------------------------------------------- 1 | # LoRa concentrator configuration. 2 | [gateway.concentrator] 3 | 4 | # Multi spreading-factor channels (LoRa). 5 | multi_sf_channels=[ 6 | 903900000, 7 | 904100000, 8 | 904300000, 9 | 904500000, 10 | 904700000, 11 | 904900000, 12 | 905100000, 13 | 905300000, 14 | ] 15 | 16 | # LoRa std channel (single spreading-factor). 17 | [gateway.concentrator.lora_std] 18 | frequency=904600000 19 | bandwidth=500000 20 | spreading_factor=8 21 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1301/config/channels_us915_2.toml: -------------------------------------------------------------------------------- 1 | # LoRa concentrator configuration. 2 | [gateway.concentrator] 3 | 4 | # Multi spreading-factor channels (LoRa). 5 | multi_sf_channels=[ 6 | 905500000, 7 | 905700000, 8 | 905900000, 9 | 906100000, 10 | 906300000, 11 | 906500000, 12 | 906700000, 13 | 906900000, 14 | ] 15 | 16 | # LoRa std channel (single spreading-factor). 17 | [gateway.concentrator.lora_std] 18 | frequency=906200000 19 | bandwidth=500000 20 | spreading_factor=8 21 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1301/config/channels_us915_3.toml: -------------------------------------------------------------------------------- 1 | # LoRa concentrator configuration. 2 | [gateway.concentrator] 3 | 4 | # Multi spreading-factor channels (LoRa). 5 | multi_sf_channels=[ 6 | 907100000, 7 | 907300000, 8 | 907500000, 9 | 907700000, 10 | 907900000, 11 | 908100000, 12 | 908300000, 13 | 908500000, 14 | ] 15 | 16 | # LoRa std channel (single spreading-factor). 17 | [gateway.concentrator.lora_std] 18 | frequency=907800000 19 | bandwidth=500000 20 | spreading_factor=8 21 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1301/config/channels_us915_4.toml: -------------------------------------------------------------------------------- 1 | # LoRa concentrator configuration. 2 | [gateway.concentrator] 3 | 4 | # Multi spreading-factor channels (LoRa). 5 | multi_sf_channels=[ 6 | 908700000, 7 | 908900000, 8 | 909100000, 9 | 909300000, 10 | 909500000, 11 | 909700000, 12 | 909900000, 13 | 910100000, 14 | ] 15 | 16 | # LoRa std channel (single spreading-factor). 17 | [gateway.concentrator.lora_std] 18 | frequency=909400000 19 | bandwidth=500000 20 | spreading_factor=8 21 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1301/config/channels_us915_5.toml: -------------------------------------------------------------------------------- 1 | # LoRa concentrator configuration. 2 | [gateway.concentrator] 3 | 4 | # Multi spreading-factor channels (LoRa). 5 | multi_sf_channels=[ 6 | 910300000, 7 | 910500000, 8 | 910700000, 9 | 910900000, 10 | 911100000, 11 | 911300000, 12 | 911500000, 13 | 911700000, 14 | ] 15 | 16 | # LoRa std channel (single spreading-factor). 17 | [gateway.concentrator.lora_std] 18 | frequency=911000000 19 | bandwidth=500000 20 | spreading_factor=8 21 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1301/config/channels_us915_6.toml: -------------------------------------------------------------------------------- 1 | # LoRa concentrator configuration. 2 | [gateway.concentrator] 3 | 4 | # Multi spreading-factor channels (LoRa). 5 | multi_sf_channels=[ 6 | 911900000, 7 | 912100000, 8 | 912300000, 9 | 912500000, 10 | 912700000, 11 | 912900000, 12 | 913100000, 13 | 913300000, 14 | ] 15 | 16 | # LoRa std channel (single spreading-factor). 17 | [gateway.concentrator.lora_std] 18 | frequency=912600000 19 | bandwidth=500000 20 | spreading_factor=8 21 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1301/config/channels_us915_7.toml: -------------------------------------------------------------------------------- 1 | # LoRa concentrator configuration. 2 | [gateway.concentrator] 3 | 4 | # Multi spreading-factor channels (LoRa). 5 | multi_sf_channels=[ 6 | 913500000, 7 | 913700000, 8 | 913900000, 9 | 914100000, 10 | 914300000, 11 | 914500000, 12 | 914700000, 13 | 914900000, 14 | ] 15 | 16 | # LoRa std channel (single spreading-factor). 17 | [gateway.concentrator.lora_std] 18 | frequency=914200000 19 | bandwidth=500000 20 | spreading_factor=8 21 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1302/config/channels_as923.toml: -------------------------------------------------------------------------------- 1 | # LoRa concentrator configuration. 2 | [gateway.concentrator] 3 | 4 | # Multi spreading-factor channels (LoRa). 5 | multi_sf_channels=[ 6 | 923200000, 7 | 923400000, 8 | 923600000, 9 | 923800000, 10 | 924000000, 11 | 924200000, 12 | 924400000, 13 | 924600000, 14 | ] 15 | 16 | # LoRa std channel (single spreading-factor). 17 | [gateway.concentrator.lora_std] 18 | frequency=924500000 19 | bandwidth=250000 20 | spreading_factor=7 21 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1302/config/channels_as923_2.toml: -------------------------------------------------------------------------------- 1 | # LoRa concentrator configuration. 2 | [gateway.concentrator] 3 | 4 | # Multi spreading-factor channels (LoRa). 5 | multi_sf_channels=[ 6 | 921400000, 7 | 921600000, 8 | 921800000, 9 | 922000000, 10 | 922200000, 11 | 922400000, 12 | 922600000, 13 | 922800000, 14 | ] 15 | 16 | # LoRa std channel (single spreading-factor). 17 | [gateway.concentrator.lora_std] 18 | frequency=922700000 19 | bandwidth=250000 20 | spreading_factor=7 21 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1302/config/channels_as923_3.toml: -------------------------------------------------------------------------------- 1 | # LoRa concentrator configuration. 2 | [gateway.concentrator] 3 | 4 | # Multi spreading-factor channels (LoRa). 5 | multi_sf_channels=[ 6 | 916600000, 7 | 916800000, 8 | 917000000, 9 | 917200000, 10 | 917400000, 11 | 917600000, 12 | 917800000, 13 | 918000000, 14 | ] 15 | 16 | # LoRa std channel (single spreading-factor). 17 | [gateway.concentrator.lora_std] 18 | frequency=917900000 19 | bandwidth=250000 20 | spreading_factor=7 21 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1302/config/channels_au915_0.toml: -------------------------------------------------------------------------------- 1 | # LoRa concentrator configuration. 2 | [gateway.concentrator] 3 | 4 | # Multi spreading-factor channels (LoRa). 5 | multi_sf_channels=[ 6 | 915200000, 7 | 915400000, 8 | 915600000, 9 | 915800000, 10 | 916000000, 11 | 916200000, 12 | 916400000, 13 | 916600000, 14 | ] 15 | 16 | # LoRa std channel (single spreading-factor). 17 | [gateway.concentrator.lora_std] 18 | frequency=915900000 19 | bandwidth=500000 20 | spreading_factor=8 21 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1302/config/channels_au915_1.toml: -------------------------------------------------------------------------------- 1 | # LoRa concentrator configuration. 2 | [gateway.concentrator] 3 | 4 | # Multi spreading-factor channels (LoRa). 5 | multi_sf_channels=[ 6 | 916800000, 7 | 917000000, 8 | 917200000, 9 | 917400000, 10 | 917600000, 11 | 917800000, 12 | 918000000, 13 | 918200000, 14 | ] 15 | 16 | # LoRa std channel (single spreading-factor). 17 | [gateway.concentrator.lora_std] 18 | frequency=917500000 19 | bandwidth=500000 20 | spreading_factor=8 21 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1302/config/channels_au915_2.toml: -------------------------------------------------------------------------------- 1 | # LoRa concentrator configuration. 2 | [gateway.concentrator] 3 | 4 | # Multi spreading-factor channels (LoRa). 5 | multi_sf_channels=[ 6 | 918400000, 7 | 918600000, 8 | 918800000, 9 | 919000000, 10 | 919200000, 11 | 919400000, 12 | 919600000, 13 | 919800000, 14 | ] 15 | 16 | # LoRa std channel (single spreading-factor). 17 | [gateway.concentrator.lora_std] 18 | frequency=919100000 19 | bandwidth=500000 20 | spreading_factor=8 21 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1302/config/channels_au915_3.toml: -------------------------------------------------------------------------------- 1 | # LoRa concentrator configuration. 2 | [gateway.concentrator] 3 | 4 | # Multi spreading-factor channels (LoRa). 5 | multi_sf_channels=[ 6 | 920000000, 7 | 920200000, 8 | 920400000, 9 | 920600000, 10 | 920800000, 11 | 921000000, 12 | 921200000, 13 | 921400000, 14 | ] 15 | 16 | # LoRa std channel (single spreading-factor). 17 | [gateway.concentrator.lora_std] 18 | frequency=920700000 19 | bandwidth=500000 20 | spreading_factor=8 21 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1302/config/channels_au915_4.toml: -------------------------------------------------------------------------------- 1 | # LoRa concentrator configuration. 2 | [gateway.concentrator] 3 | 4 | # Multi spreading-factor channels (LoRa). 5 | multi_sf_channels=[ 6 | 921600000, 7 | 921800000, 8 | 922000000, 9 | 922200000, 10 | 922400000, 11 | 922600000, 12 | 922800000, 13 | 923000000, 14 | ] 15 | 16 | # LoRa std channel (single spreading-factor). 17 | [gateway.concentrator.lora_std] 18 | frequency=922300000 19 | bandwidth=500000 20 | spreading_factor=8 21 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1302/config/channels_au915_5.toml: -------------------------------------------------------------------------------- 1 | # LoRa concentrator configuration. 2 | [gateway.concentrator] 3 | 4 | # Multi spreading-factor channels (LoRa). 5 | multi_sf_channels=[ 6 | 923200000, 7 | 923400000, 8 | 923600000, 9 | 923800000, 10 | 924000000, 11 | 924200000, 12 | 924400000, 13 | 924600000, 14 | ] 15 | 16 | # LoRa std channel (single spreading-factor). 17 | [gateway.concentrator.lora_std] 18 | frequency=923900000 19 | bandwidth=500000 20 | spreading_factor=8 21 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1302/config/channels_au915_6.toml: -------------------------------------------------------------------------------- 1 | # LoRa concentrator configuration. 2 | [gateway.concentrator] 3 | 4 | # Multi spreading-factor channels (LoRa). 5 | multi_sf_channels=[ 6 | 924800000, 7 | 925000000, 8 | 925200000, 9 | 925400000, 10 | 925600000, 11 | 925800000, 12 | 926000000, 13 | 926200000, 14 | ] 15 | 16 | # LoRa std channel (single spreading-factor). 17 | [gateway.concentrator.lora_std] 18 | frequency=925500000 19 | bandwidth=500000 20 | spreading_factor=8 21 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1302/config/channels_au915_7.toml: -------------------------------------------------------------------------------- 1 | # LoRa concentrator configuration. 2 | [gateway.concentrator] 3 | 4 | # Multi spreading-factor channels (LoRa). 5 | multi_sf_channels=[ 6 | 926400000, 7 | 926600000, 8 | 926800000, 9 | 927000000, 10 | 927200000, 11 | 927400000, 12 | 927600000, 13 | 927800000, 14 | ] 15 | 16 | # LoRa std channel (single spreading-factor). 17 | [gateway.concentrator.lora_std] 18 | frequency=927100000 19 | bandwidth=500000 20 | spreading_factor=8 21 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1302/config/channels_us915_0.toml: -------------------------------------------------------------------------------- 1 | # LoRa concentrator configuration. 2 | [gateway.concentrator] 3 | 4 | # Multi spreading-factor channels (LoRa). 5 | multi_sf_channels=[ 6 | 902300000, 7 | 902500000, 8 | 902700000, 9 | 902900000, 10 | 903100000, 11 | 903300000, 12 | 903500000, 13 | 903700000, 14 | ] 15 | 16 | # LoRa std channel (single spreading-factor). 17 | [gateway.concentrator.lora_std] 18 | frequency=903000000 19 | bandwidth=500000 20 | spreading_factor=8 21 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1302/config/channels_us915_1.toml: -------------------------------------------------------------------------------- 1 | # LoRa concentrator configuration. 2 | [gateway.concentrator] 3 | 4 | # Multi spreading-factor channels (LoRa). 5 | multi_sf_channels=[ 6 | 903900000, 7 | 904100000, 8 | 904300000, 9 | 904500000, 10 | 904700000, 11 | 904900000, 12 | 905100000, 13 | 905300000, 14 | ] 15 | 16 | # LoRa std channel (single spreading-factor). 17 | [gateway.concentrator.lora_std] 18 | frequency=904600000 19 | bandwidth=500000 20 | spreading_factor=8 21 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1302/config/channels_us915_2.toml: -------------------------------------------------------------------------------- 1 | # LoRa concentrator configuration. 2 | [gateway.concentrator] 3 | 4 | # Multi spreading-factor channels (LoRa). 5 | multi_sf_channels=[ 6 | 905500000, 7 | 905700000, 8 | 905900000, 9 | 906100000, 10 | 906300000, 11 | 906500000, 12 | 906700000, 13 | 906900000, 14 | ] 15 | 16 | # LoRa std channel (single spreading-factor). 17 | [gateway.concentrator.lora_std] 18 | frequency=906200000 19 | bandwidth=500000 20 | spreading_factor=8 21 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1302/config/channels_us915_3.toml: -------------------------------------------------------------------------------- 1 | # LoRa concentrator configuration. 2 | [gateway.concentrator] 3 | 4 | # Multi spreading-factor channels (LoRa). 5 | multi_sf_channels=[ 6 | 907100000, 7 | 907300000, 8 | 907500000, 9 | 907700000, 10 | 907900000, 11 | 908100000, 12 | 908300000, 13 | 908500000, 14 | ] 15 | 16 | # LoRa std channel (single spreading-factor). 17 | [gateway.concentrator.lora_std] 18 | frequency=907800000 19 | bandwidth=500000 20 | spreading_factor=8 21 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1302/config/channels_us915_4.toml: -------------------------------------------------------------------------------- 1 | # LoRa concentrator configuration. 2 | [gateway.concentrator] 3 | 4 | # Multi spreading-factor channels (LoRa). 5 | multi_sf_channels=[ 6 | 908700000, 7 | 908900000, 8 | 909100000, 9 | 909300000, 10 | 909500000, 11 | 909700000, 12 | 909900000, 13 | 910100000, 14 | ] 15 | 16 | # LoRa std channel (single spreading-factor). 17 | [gateway.concentrator.lora_std] 18 | frequency=909400000 19 | bandwidth=500000 20 | spreading_factor=8 21 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1302/config/channels_us915_5.toml: -------------------------------------------------------------------------------- 1 | # LoRa concentrator configuration. 2 | [gateway.concentrator] 3 | 4 | # Multi spreading-factor channels (LoRa). 5 | multi_sf_channels=[ 6 | 910300000, 7 | 910500000, 8 | 910700000, 9 | 910900000, 10 | 911100000, 11 | 911300000, 12 | 911500000, 13 | 911700000, 14 | ] 15 | 16 | # LoRa std channel (single spreading-factor). 17 | [gateway.concentrator.lora_std] 18 | frequency=911000000 19 | bandwidth=500000 20 | spreading_factor=8 21 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1302/config/channels_us915_6.toml: -------------------------------------------------------------------------------- 1 | # LoRa concentrator configuration. 2 | [gateway.concentrator] 3 | 4 | # Multi spreading-factor channels (LoRa). 5 | multi_sf_channels=[ 6 | 911900000, 7 | 912100000, 8 | 912300000, 9 | 912500000, 10 | 912700000, 11 | 912900000, 12 | 913100000, 13 | 913300000, 14 | ] 15 | 16 | # LoRa std channel (single spreading-factor). 17 | [gateway.concentrator.lora_std] 18 | frequency=912600000 19 | bandwidth=500000 20 | spreading_factor=8 21 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1302/config/channels_us915_7.toml: -------------------------------------------------------------------------------- 1 | # LoRa concentrator configuration. 2 | [gateway.concentrator] 3 | 4 | # Multi spreading-factor channels (LoRa). 5 | multi_sf_channels=[ 6 | 913500000, 7 | 913700000, 8 | 913900000, 9 | 914100000, 10 | 914300000, 11 | 914500000, 12 | 914700000, 13 | 914900000, 14 | ] 15 | 16 | # LoRa std channel (single spreading-factor). 17 | [gateway.concentrator.lora_std] 18 | frequency=914200000 19 | bandwidth=500000 20 | spreading_factor=8 21 | -------------------------------------------------------------------------------- /packaging/vendor/multitech/conduit/files/2g4/channels.toml: -------------------------------------------------------------------------------- 1 | # LoRa concentrator configuration. 2 | [gateway.concentrator] 3 | 4 | [[gateway.concentrator.channels]] 5 | frequency=2403000000 6 | bandwidth=812000 7 | spreading_factor=12 8 | 9 | [[gateway.concentrator.channels]] 10 | frequency=2479000000 11 | bandwidth=812000 12 | spreading_factor=12 13 | 14 | [[gateway.concentrator.channels]] 15 | frequency=2425000000 16 | bandwidth=812000 17 | spreading_factor=12 18 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1301/config/channels_as923_4.toml: -------------------------------------------------------------------------------- 1 | # LoRa concentrator configuration. 2 | 3 | [gateway.concentrator] 4 | 5 | # Multi spreading-factor channels (LoRa). 6 | multi_sf_channels=[ 7 | 917300000, 8 | 917500000, 9 | 917700000, 10 | 917900000, 11 | 918100000, 12 | 918300000, 13 | 918500000, 14 | 918700000, 15 | ] 16 | 17 | # LoRa std channel (single spreading-factor). 18 | [gateway.concentrator.lora_std] 19 | frequency=918600000 20 | bandwidth=250000 21 | spreading_factor=7 22 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1302/config/channels_as923_4.toml: -------------------------------------------------------------------------------- 1 | # LoRa concentrator configuration. 2 | 3 | [gateway.concentrator] 4 | 5 | # Multi spreading-factor channels (LoRa). 6 | multi_sf_channels=[ 7 | 917300000, 8 | 917500000, 9 | 917700000, 10 | 917900000, 11 | 918100000, 12 | 918300000, 13 | 918500000, 14 | 918700000, 15 | ] 16 | 17 | # LoRa std channel (single spreading-factor). 18 | [gateway.concentrator.lora_std] 19 | frequency=918600000 20 | bandwidth=250000 21 | spreading_factor=7 22 | -------------------------------------------------------------------------------- /packaging/vendor/multitech/conduit-ap3/files/channels_us915_0.toml: -------------------------------------------------------------------------------- 1 | # LoRa concentrator configuration. 2 | [gateway.concentrator] 3 | 4 | # Multi spreading-factor channels (LoRa). 5 | multi_sf_channels=[ 6 | 902300000, 7 | 902500000, 8 | 902700000, 9 | 902900000, 10 | 903100000, 11 | 903300000, 12 | 903500000, 13 | 903700000, 14 | ] 15 | 16 | # LoRa std channel (single spreading-factor). 17 | [gateway.concentrator.lora_std] 18 | frequency=903000000 19 | bandwidth=500000 20 | spreading_factor=8 21 | -------------------------------------------------------------------------------- /packaging/vendor/multitech/conduit/files/sx1302/channels_us915_0.toml: -------------------------------------------------------------------------------- 1 | # LoRa concentrator configuration. 2 | [gateway.concentrator] 3 | 4 | # Multi spreading-factor channels (LoRa). 5 | multi_sf_channels=[ 6 | 902300000, 7 | 902500000, 8 | 902700000, 9 | 902900000, 10 | 903100000, 11 | 903300000, 12 | 903500000, 13 | 903700000, 14 | ] 15 | 16 | # LoRa std channel (single spreading-factor). 17 | [gateway.concentrator.lora_std] 18 | frequency=903000000 19 | bandwidth=500000 20 | spreading_factor=8 21 | -------------------------------------------------------------------------------- /libloragw-sx1301/src/spi.rs: -------------------------------------------------------------------------------- 1 | use std::ffi::CString; 2 | 3 | use anyhow::Result; 4 | 5 | use super::{mutex, wrapper}; 6 | 7 | /// Set SPI device. 8 | pub fn set_path(spidev_path: &str) -> Result<()> { 9 | let _guard = mutex::CONCENTATOR.lock().unwrap(); 10 | let spidev_path = CString::new(spidev_path).unwrap(); 11 | let ret = unsafe { wrapper::lgw_spi_set_path(spidev_path.as_ptr()) }; 12 | if ret != 0 { 13 | return Err(anyhow!("lgw_spi_set_path failed")); 14 | } 15 | 16 | Ok(()) 17 | } 18 | -------------------------------------------------------------------------------- /libconcentratord/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "libconcentratord" 3 | version = "4.5.3" 4 | authors = ["Orne Brocaar <@brocaar.com>"] 5 | edition = "2024" 6 | publish = false 7 | 8 | [dependencies] 9 | log = { workspace = true } 10 | zmq = { workspace = true } 11 | chirpstack_api = { workspace = true } 12 | hex = { workspace = true } 13 | gpiocdev = { workspace = true } 14 | anyhow = { workspace = true } 15 | thiserror = { workspace = true } 16 | serde = { workspace = true } 17 | serde_json = { workspace = true } 18 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1301/config/region_au915.toml: -------------------------------------------------------------------------------- 1 | # Beacon configuration. 2 | # 3 | # This requires a gateway with GPS / GNSS. 4 | [gateway.beacon] 5 | 6 | # Compulsory RFU size. 7 | compulsory_rfu_size=3 8 | 9 | # Beacon frequency / frequencies (Hz). 10 | frequencies=[ 11 | 923300000, 12 | 923900000, 13 | 924500000, 14 | 925100000, 15 | 925700000, 16 | 926300000, 17 | 926900000, 18 | 927500000, 19 | ] 20 | 21 | # Bandwidth (Hz). 22 | bandwidth=500000 23 | 24 | # Spreading factor. 25 | spreading_factor=12 26 | 27 | # TX power. 28 | tx_power=14 29 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1301/config/region_cn470.toml: -------------------------------------------------------------------------------- 1 | # Beacon configuration. 2 | # 3 | # This requires a gateway with GPS / GNSS. 4 | [gateway.beacon] 5 | 6 | # Compulsory RFU size. 7 | compulsory_rfu_size=3 8 | 9 | # Beacon frequency / frequencies (Hz). 10 | frequencies=[ 11 | 508300000, 12 | 508500000, 13 | 508700000, 14 | 508900000, 15 | 509100000, 16 | 509300000, 17 | 509500000, 18 | 509700000, 19 | ] 20 | 21 | # Bandwidth (Hz). 22 | bandwidth=125000 23 | 24 | # Spreading factor. 25 | spreading_factor=10 26 | 27 | # TX power. 28 | tx_power=14 29 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1301/config/region_us915.toml: -------------------------------------------------------------------------------- 1 | # Beacon configuration. 2 | # 3 | # This requires a gateway with GPS / GNSS. 4 | [gateway.beacon] 5 | 6 | # Compulsory RFU size. 7 | compulsory_rfu_size=5 8 | 9 | # Beacon frequency / frequencies (Hz). 10 | frequencies=[ 11 | 923300000, 12 | 923900000, 13 | 924500000, 14 | 925100000, 15 | 925700000, 16 | 926300000, 17 | 926900000, 18 | 927500000, 19 | ] 20 | 21 | # Bandwidth (Hz). 22 | bandwidth=500000 23 | 24 | # Spreading factor. 25 | spreading_factor=12 26 | 27 | # TX power. 28 | tx_power=14 29 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1302/config/region_au915.toml: -------------------------------------------------------------------------------- 1 | # beacon configuration. 2 | # 3 | # this requires a gateway with gps / gnss. 4 | [gateway.beacon] 5 | 6 | # compulsory rfu size. 7 | compulsory_rfu_size=3 8 | 9 | # beacon frequency / frequencies (hz). 10 | frequencies=[ 11 | 923300000, 12 | 923900000, 13 | 924500000, 14 | 925100000, 15 | 925700000, 16 | 926300000, 17 | 926900000, 18 | 927500000, 19 | ] 20 | 21 | # bandwidth (hz). 22 | bandwidth=500000 23 | 24 | # spreading factor. 25 | spreading_factor=12 26 | 27 | # tx power. 28 | tx_power=14 29 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1302/config/region_us915.toml: -------------------------------------------------------------------------------- 1 | # Beacon configuration. 2 | # 3 | # This requires a gateway with GPS / GNSS. 4 | [gateway.beacon] 5 | 6 | # Compulsory RFU size. 7 | compulsory_rfu_size=5 8 | 9 | # Beacon frequency / frequencies (Hz). 10 | frequencies=[ 11 | 923300000, 12 | 923900000, 13 | 924500000, 14 | 925100000, 15 | 925700000, 16 | 926300000, 17 | 926900000, 18 | 927500000, 19 | ] 20 | 21 | # Bandwidth (Hz). 22 | bandwidth=500000 23 | 24 | # Spreading factor. 25 | spreading_factor=12 26 | 27 | # TX power. 28 | tx_power=14 29 | -------------------------------------------------------------------------------- /packaging/vendor/multitech/conduit/files/sx1302/region_us915.toml: -------------------------------------------------------------------------------- 1 | # Beacon configuration. 2 | # 3 | # This requires a gateway with GPS / GNSS. 4 | [gateway.beacon] 5 | 6 | # Compulsory RFU size. 7 | compulsory_rfu_size=5 8 | 9 | # Beacon frequency / frequencies (Hz). 10 | frequencies=[ 11 | 923300000, 12 | 923900000, 13 | 924500000, 14 | 925100000, 15 | 925700000, 16 | 926300000, 17 | 926900000, 18 | 927500000, 19 | ] 20 | 21 | # Bandwidth (Hz). 22 | bandwidth=500000 23 | 24 | # Spreading factor. 25 | spreading_factor=12 26 | 27 | # TX power. 28 | tx_power=14 29 | -------------------------------------------------------------------------------- /packaging/vendor/multitech/conduit/files/sx1301/region_eu868.toml: -------------------------------------------------------------------------------- 1 | # Beacon configuration. 2 | # 3 | # This requires a gateway with GPS / GNSS. 4 | # 5 | # Please note that the beacon settings are region dependent. The correct 6 | # settings can be found in the LoRaWAN Regional Parameters specification. 7 | [gateway.beacon] 8 | 9 | # Compulsory RFU size. 10 | compulsory_rfu_size=2 11 | 12 | # Beacon frequency / frequencies (Hz). 13 | frequencies=[ 14 | 869525000, 15 | ] 16 | 17 | # Bandwidth (Hz). 18 | bandwidth=125000 19 | 20 | # Spreading factor. 21 | spreading_factor=9 22 | 23 | # TX power. 24 | tx_power=14 25 | -------------------------------------------------------------------------------- /packaging/vendor/kerlink/ifemtocell/files/channels.toml: -------------------------------------------------------------------------------- 1 | # LoRa concentrator configuration. 2 | [gateway.concentrator] 3 | 4 | # Multi spreading-factor channels (LoRa). 5 | multi_sf_channels=[ 6 | 868100000, 7 | 868300000, 8 | 868500000, 9 | 867100000, 10 | 867300000, 11 | 867500000, 12 | 867700000, 13 | 867900000, 14 | ] 15 | 16 | # LoRa std channel (single spreading-factor). 17 | [gateway.concentrator.lora_std] 18 | frequency=868300000 19 | bandwidth=250000 20 | spreading_factor=7 21 | 22 | # FSK channel. 23 | [gateway.concentrator.fsk] 24 | frequency=868800000 25 | bandwidth=125000 26 | datarate=50000 27 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1301/config/channels_eu868.toml: -------------------------------------------------------------------------------- 1 | # LoRa concentrator configuration. 2 | [gateway.concentrator] 3 | 4 | # Multi spreading-factor channels (LoRa). 5 | multi_sf_channels=[ 6 | 868100000, 7 | 868300000, 8 | 868500000, 9 | 867100000, 10 | 867300000, 11 | 867500000, 12 | 867700000, 13 | 867900000, 14 | ] 15 | 16 | # LoRa std channel (single spreading-factor). 17 | [gateway.concentrator.lora_std] 18 | frequency=868300000 19 | bandwidth=250000 20 | spreading_factor=7 21 | 22 | # FSK channel. 23 | [gateway.concentrator.fsk] 24 | frequency=868800000 25 | bandwidth=125000 26 | datarate=50000 27 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1302/config/channels_eu868.toml: -------------------------------------------------------------------------------- 1 | # LoRa concentrator configuration. 2 | [gateway.concentrator] 3 | 4 | # Multi spreading-factor channels (LoRa). 5 | multi_sf_channels=[ 6 | 868100000, 7 | 868300000, 8 | 868500000, 9 | 867100000, 10 | 867300000, 11 | 867500000, 12 | 867700000, 13 | 867900000, 14 | ] 15 | 16 | # LoRa std channel (single spreading-factor). 17 | [gateway.concentrator.lora_std] 18 | frequency=868300000 19 | bandwidth=250000 20 | spreading_factor=7 21 | 22 | # FSK channel. 23 | [gateway.concentrator.fsk] 24 | frequency=868800000 25 | bandwidth=125000 26 | datarate=50000 27 | -------------------------------------------------------------------------------- /packaging/vendor/multitech/conduit-ap/files/channels_eu868_0.toml: -------------------------------------------------------------------------------- 1 | # LoRa concentrator configuration. 2 | [gateway.concentrator] 3 | 4 | # Multi spreading-factor channels (LoRa). 5 | multi_sf_channels=[ 6 | 868100000, 7 | 868300000, 8 | 868500000, 9 | 867100000, 10 | 867300000, 11 | 867500000, 12 | 867700000, 13 | 867900000, 14 | ] 15 | 16 | # LoRa std channel (single spreading-factor). 17 | [gateway.concentrator.lora_std] 18 | frequency=868300000 19 | bandwidth=250000 20 | spreading_factor=7 21 | 22 | # FSK channel. 23 | [gateway.concentrator.fsk] 24 | frequency=868800000 25 | bandwidth=125000 26 | datarate=50000 27 | -------------------------------------------------------------------------------- /packaging/vendor/multitech/conduit-ap3/files/channels_eu868_0.toml: -------------------------------------------------------------------------------- 1 | # LoRa concentrator configuration. 2 | [gateway.concentrator] 3 | 4 | # Multi spreading-factor channels (LoRa). 5 | multi_sf_channels=[ 6 | 868100000, 7 | 868300000, 8 | 868500000, 9 | 867100000, 10 | 867300000, 11 | 867500000, 12 | 867700000, 13 | 867900000, 14 | ] 15 | 16 | # LoRa std channel (single spreading-factor). 17 | [gateway.concentrator.lora_std] 18 | frequency=868300000 19 | bandwidth=250000 20 | spreading_factor=7 21 | 22 | # FSK channel. 23 | [gateway.concentrator.fsk] 24 | frequency=868800000 25 | bandwidth=125000 26 | datarate=50000 27 | -------------------------------------------------------------------------------- /packaging/vendor/multitech/conduit/files/sx1301/channels_eu868_0.toml: -------------------------------------------------------------------------------- 1 | # LoRa concentrator configuration. 2 | [gateway.concentrator] 3 | 4 | # Multi spreading-factor channels (LoRa). 5 | multi_sf_channels=[ 6 | 868100000, 7 | 868300000, 8 | 868500000, 9 | 867100000, 10 | 867300000, 11 | 867500000, 12 | 867700000, 13 | 867900000, 14 | ] 15 | 16 | # LoRa std channel (single spreading-factor). 17 | [gateway.concentrator.lora_std] 18 | frequency=868300000 19 | bandwidth=250000 20 | spreading_factor=7 21 | 22 | # FSK channel. 23 | [gateway.concentrator.fsk] 24 | frequency=868800000 25 | bandwidth=125000 26 | datarate=50000 27 | -------------------------------------------------------------------------------- /packaging/vendor/multitech/conduit/files/sx1302/channels_eu868_0.toml: -------------------------------------------------------------------------------- 1 | # LoRa concentrator configuration. 2 | [gateway.concentrator] 3 | 4 | # Multi spreading-factor channels (LoRa). 5 | multi_sf_channels=[ 6 | 868100000, 7 | 868300000, 8 | 868500000, 9 | 867100000, 10 | 867300000, 11 | 867500000, 12 | 867700000, 13 | 867900000, 14 | ] 15 | 16 | # LoRa std channel (single spreading-factor). 17 | [gateway.concentrator.lora_std] 18 | frequency=868300000 19 | bandwidth=250000 20 | spreading_factor=7 21 | 22 | # FSK channel. 23 | [gateway.concentrator.fsk] 24 | frequency=868800000 25 | bandwidth=125000 26 | datarate=50000 27 | -------------------------------------------------------------------------------- /Cross.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | default-target = "x86_64-unknown-linux-musl" 3 | 4 | [target.x86_64-unknown-linux-musl] 5 | dockerfile = "cross/Dockerfile.x86_64-unknown-linux-musl" 6 | 7 | [target.aarch64-unknown-linux-musl] 8 | dockerfile = "cross/Dockerfile.aarch64-unknown-linux-musl" 9 | 10 | [target.armv7-unknown-linux-musleabihf] 11 | dockerfile = "cross/Dockerfile.armv7-unknown-linux-musleabihf" 12 | 13 | [target.armv5te-unknown-linux-musleabi] 14 | dockerfile = "cross/Dockerfile.armv5te-unknown-linux-musleabi" 15 | 16 | [target.mipsel-unknown-linux-musl] 17 | dockerfile = "cross/Dockerfile.mipsel-unknown-linux-musl" 18 | 19 | -------------------------------------------------------------------------------- /shell.nix: -------------------------------------------------------------------------------- 1 | { pkgs ? import (fetchTarball "https://github.com/NixOS/nixpkgs/archive/nixos-25.05.tar.gz") {} }: 2 | 3 | pkgs.mkShell { 4 | nativeBuildInputs = [ 5 | pkgs.pkg-config 6 | ]; 7 | buildInputs = [ 8 | pkgs.cacert 9 | pkgs.rustup 10 | # cargo-cross can be used once version > 0.2.5, as 0.2.5 does not work well 11 | # with nightly toolchain. It is for now installed through make dev-dependencies. 12 | # pkgs.cargo-cross 13 | pkgs.jq 14 | pkgs.opkg-utils 15 | ]; 16 | shellHook = '' 17 | export PATH=$PATH:~/.cargo/bin 18 | ''; 19 | DOCKER_BUILDKIT = "1"; 20 | NIX_STORE = "/nix/store"; 21 | } 22 | -------------------------------------------------------------------------------- /chirpstack-concentratord-2g4/src/config/vendor/semtech/sx1280z3dsfgw1.rs: -------------------------------------------------------------------------------- 1 | use super::super::super::super::config; 2 | use super::super::Configuration; 3 | use libconcentratord::region; 4 | 5 | pub fn new(conf: &config::Configuration) -> Configuration { 6 | Configuration { 7 | tty_path: conf.gateway.get_com_dev_path("/dev/ttyACM0"), 8 | tx_min_max_freqs: region::ism2400::TX_MIN_MAX_FREQS.to_vec(), 9 | // pin configuration taken from: 10 | // https://github.com/Lora-net/gateway_2g4_hal/blob/master/tools/rpi_configure_gpio.sh 11 | reset_pin: conf.gateway.get_mcu_reset_pin("/dev/gpiochip0", 32), 12 | boot0_pin: conf.gateway.get_mcu_boot_pin("/dev/gpiochip0", 18), 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /packaging/vendor/multitech/conduit-ap/files/channels_us915_0.toml: -------------------------------------------------------------------------------- 1 | # LoRa concentrator configuration. 2 | [gateway.concentrator] 3 | 4 | # Multi spreading-factor channels (LoRa). 5 | # 6 | # Note: this is for channels 0 - 7 + 64. For more US915 examples see: 7 | # https://github.com/brocaar/chirpstack-gateway-os/tree/master/layers/targets/meta-raspberrypi/recipes-chirpstack/chirpstack-concentratord/files/sx1301 8 | multi_sf_channels=[ 9 | 902300000, 10 | 902500000, 11 | 902700000, 12 | 902900000, 13 | 903100000, 14 | 903300000, 15 | 903500000, 16 | 903700000, 17 | ] 18 | 19 | # LoRa std channel (single spreading-factor). 20 | [gateway.concentrator.lora_std] 21 | frequency=903000000 22 | bandwidth=500000 23 | spreading_factor=8 24 | -------------------------------------------------------------------------------- /packaging/vendor/multitech/conduit/files/sx1301/region_us915.toml: -------------------------------------------------------------------------------- 1 | # Beacon configuration. 2 | # 3 | # This requires a gateway with GPS / GNSS. 4 | # 5 | # Please note that the beacon settings are region dependent. The correct 6 | # settings can be found in the LoRaWAN Regional Parameters specification. 7 | [gateway.beacon] 8 | 9 | # Compulsory RFU size. 10 | compulsory_rfu_size=5 11 | 12 | # Beacon frequency / frequencies (Hz). 13 | frequencies=[ 14 | 923300000, 15 | 923900000, 16 | 924500000, 17 | 925100000, 18 | 925700000, 19 | 926300000, 20 | 926900000, 21 | 927500000, 22 | ] 23 | 24 | # Bandwidth (Hz). 25 | bandwidth=500000 26 | 27 | # Spreading factor. 28 | spreading_factor=12 29 | 30 | # TX power. 31 | tx_power=14 32 | -------------------------------------------------------------------------------- /packaging/vendor/multitech/conduit/files/sx1301/channels_us915_0.toml: -------------------------------------------------------------------------------- 1 | # LoRa concentrator configuration. 2 | [gateway.concentrator] 3 | 4 | # Multi spreading-factor channels (LoRa). 5 | # 6 | # Note: this is for channels 0 - 7 + 64. For more US915 examples see: 7 | # https://github.com/brocaar/chirpstack-gateway-os/tree/master/layers/targets/meta-raspberrypi/recipes-chirpstack/chirpstack-concentratord/files/sx1301 8 | multi_sf_channels=[ 9 | 902300000, 10 | 902500000, 11 | 902700000, 12 | 902900000, 13 | 903100000, 14 | 903300000, 15 | 903500000, 16 | 903700000, 17 | ] 18 | 19 | # LoRa std channel (single spreading-factor). 20 | [gateway.concentrator.lora_std] 21 | frequency=903000000 22 | bandwidth=500000 23 | spreading_factor=8 24 | -------------------------------------------------------------------------------- /chirpstack-concentratord-2g4/src/handler/gps.rs: -------------------------------------------------------------------------------- 1 | use std::sync::{LazyLock, Mutex}; 2 | 3 | use libloragw_2g4::gps; 4 | 5 | static STATIC_GPS_COORDS: LazyLock>> = 6 | LazyLock::new(|| Mutex::new(None)); 7 | 8 | pub fn set_static_gps_coords(lat: f64, lon: f64, alt: i16) { 9 | let mut static_gps_coords = STATIC_GPS_COORDS.lock().unwrap(); 10 | 11 | if lat != 0.0 || lon != 0.0 || alt != 0 { 12 | *static_gps_coords = Some(gps::Coordinates { 13 | latitude: lat, 14 | longitude: lon, 15 | altitude: alt, 16 | }) 17 | } else { 18 | *static_gps_coords = None; 19 | } 20 | } 21 | 22 | pub fn get_coords() -> Option { 23 | let static_gps_coords = STATIC_GPS_COORDS.lock().unwrap(); 24 | *static_gps_coords 25 | } 26 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1301/src/config/vendor/mod.rs: -------------------------------------------------------------------------------- 1 | use libconcentratord::gnss; 2 | use libloragw_sx1301::hal; 3 | 4 | pub mod imst; 5 | pub mod kerlink; 6 | pub mod multitech; 7 | pub mod pi_supply; 8 | pub mod rak; 9 | pub mod risinghf; 10 | pub mod sandbox; 11 | pub mod wifx; 12 | 13 | #[derive(Default, Clone)] 14 | pub struct Configuration { 15 | pub radio_count: usize, 16 | pub clock_source: u8, 17 | pub radio_rssi_offset: Vec, 18 | pub radio_tx_enabled: Vec, 19 | pub radio_type: Vec, 20 | pub tx_min_max_freqs: Vec<(u32, u32)>, 21 | pub radio_tx_notch_freq: Vec, 22 | pub lora_multi_sf_bandwidth: u32, 23 | pub tx_gain_table: Vec, 24 | pub gps: gnss::Device, 25 | pub spidev_path: String, 26 | pub reset_pin: Option<(String, u32)>, 27 | pub enforce_duty_cycle: bool, 28 | } 29 | -------------------------------------------------------------------------------- /.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [target.x86_64-unknown-linux-musl] 2 | rustflags = ["-C", "target-feature=+crt-static", "-C", "link-arg=-s", "-C", "link-arg=-lc", "-C", "link-arg=-lgcc", "-L", "native=/usr/local/x86_64-linux-musl-target/lib", "-l", "static=stdc++"] 3 | 4 | [target.aarch64-unknown-linux-musl] 5 | rustflags = ["-C", "target-feature=+crt-static", "-C", "link-arg=-s", "-C", "link-arg=-lc", "-C", "link-arg=-lgcc", "-L", "native=/usr/local/aarch64-linux-musl-target/lib", "-l", "static=stdc++"] 6 | 7 | [target.armv7-unknown-linux-musleabihf] 8 | rustflags = ["-C", "target-feature=+crt-static", "-C", "link-arg=-s", "-C", "link-arg=-lc", "-C", "link-arg=-lgcc", "-L", "native=/usr/local/arm-linux-musleabihf-target/lib", "-l", "static=stdc++"] 9 | 10 | [target.armv5te-unknown-linux-musleabi] 11 | rustflags = ["-C", "target-feature=+crt-static", "-C", "link-arg=-s", "-C", "link-arg=-lc", "-C", "link-arg=-lgcc", "-L", "native=/usr/local/arm-linux-musleabi-target/lib", "-l", "static=stdc++"] 12 | -------------------------------------------------------------------------------- /libconcentratord/src/signals.rs: -------------------------------------------------------------------------------- 1 | use std::fmt; 2 | use std::sync::mpsc::{channel, Receiver, Sender}; 3 | 4 | #[derive(Clone)] 5 | pub enum Signal { 6 | Stop, 7 | Configuration(chirpstack_api::gw::GatewayConfiguration), 8 | } 9 | 10 | impl fmt::Display for Signal { 11 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 12 | match *self { 13 | Signal::Stop => write!(f, "Stop"), 14 | Signal::Configuration(_) => write!(f, "Configuration"), 15 | } 16 | } 17 | } 18 | 19 | #[derive(Default)] 20 | pub struct SignalPool { 21 | senders: Vec>, 22 | } 23 | 24 | impl SignalPool { 25 | pub fn new_receiver(&mut self) -> Receiver { 26 | let (sender, receiver) = channel(); 27 | self.senders.push(sender); 28 | receiver 29 | } 30 | 31 | pub fn send_signal(&self, signal: Signal) { 32 | for s in self.senders.iter() { 33 | s.send(signal.clone()).unwrap(); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /libloragw-sx1302/src/com.rs: -------------------------------------------------------------------------------- 1 | use std::ffi::CString; 2 | 3 | use anyhow::Result; 4 | 5 | use super::{mutex, wrapper}; 6 | 7 | /// Communication type. 8 | #[derive(Debug, PartialEq)] 9 | pub enum ComType { 10 | Spi, 11 | Usb, 12 | Unknown, 13 | } 14 | 15 | impl ComType { 16 | pub fn to_hal(&self) -> u32 { 17 | match self { 18 | ComType::Spi => wrapper::com_type_e_LGW_COM_SPI, 19 | ComType::Usb => wrapper::com_type_e_LGW_COM_USB, 20 | ComType::Unknown => wrapper::com_type_e_LGW_COM_UNKNOWN, 21 | } 22 | } 23 | } 24 | 25 | pub fn open(com_type: ComType, com_path: &str) -> Result<()> { 26 | let _guard = mutex::CONCENTATOR.lock().unwrap(); 27 | 28 | let com_type = com_type.to_hal(); 29 | let com_path = CString::new(com_path).unwrap(); 30 | 31 | let ret = unsafe { wrapper::lgw_com_open(com_type, com_path.into_raw()) }; 32 | if ret != 0 { 33 | return Err(anyhow!("lgw_com_open failed")); 34 | } 35 | 36 | Ok(()) 37 | } 38 | -------------------------------------------------------------------------------- /chirpstack-concentratord-2g4/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "chirpstack-concentratord-2g4" 3 | repository = "https://github.com/chirpstack/chirpstack-concentratord/" 4 | description = "LoRa concentrator HAL daemon (2.4GHz)" 5 | license = "MIT" 6 | version = "4.5.3" 7 | authors = ["Orne Brocaar "] 8 | edition = "2024" 9 | publish = false 10 | 11 | [dependencies] 12 | libloragw-2g4 = { path = "../libloragw-2g4" } 13 | libconcentratord = { path = "../libconcentratord" } 14 | chirpstack_api = { workspace = true } 15 | serde = { workspace = true } 16 | toml = { workspace = true } 17 | clap = { workspace = true } 18 | log = { workspace = true } 19 | simple_logger = { workspace = true } 20 | zmq = { workspace = true } 21 | hex = { workspace = true } 22 | chrono = { workspace = true } 23 | humantime-serde = { workspace = true } 24 | syslog = { workspace = true } 25 | signal-hook = { workspace = true } 26 | handlebars = { workspace = true } 27 | getrandom = { workspace = true } 28 | anyhow = { workspace = true } 29 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1301/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "chirpstack-concentratord-sx1301" 3 | description = "LoRa concentrator HAL daemon (sx1301)" 4 | repository = "https://github.com/chirpstack/chirpstack-concentratord/" 5 | license = "MIT" 6 | version = "4.5.3" 7 | authors = ["Orne Brocaar "] 8 | edition = "2024" 9 | publish = false 10 | 11 | [dependencies] 12 | libloragw-sx1301 = { path = "../libloragw-sx1301" } 13 | libconcentratord = { path = "../libconcentratord" } 14 | chirpstack_api = { workspace = true } 15 | serde = { workspace = true } 16 | toml = { workspace = true } 17 | clap = { workspace = true } 18 | log = { workspace = true } 19 | simple_logger = { workspace = true } 20 | zmq = { workspace = true } 21 | hex = { workspace = true } 22 | chrono = { workspace = true } 23 | humantime-serde = { workspace = true } 24 | syslog = { workspace = true } 25 | signal-hook = { workspace = true } 26 | handlebars = { workspace = true } 27 | getrandom = { workspace = true } 28 | anyhow = { workspace = true } 29 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1302/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "chirpstack-concentratord-sx1302" 3 | description = "LoRa concentrator HAL daemon for SX1302" 4 | repository = "https://github.com/chirpstack/chirpstack-concentratord/" 5 | license = "MIT" 6 | version = "4.5.3" 7 | authors = ["Orne Brocaar "] 8 | edition = "2024" 9 | publish = false 10 | 11 | [dependencies] 12 | libloragw-sx1302 = { path = "../libloragw-sx1302" } 13 | libconcentratord = { path = "../libconcentratord" } 14 | chirpstack_api = { workspace = true } 15 | serde = { workspace = true } 16 | toml = { workspace = true } 17 | clap = { workspace = true } 18 | log = { workspace = true } 19 | simple_logger = { workspace = true } 20 | zmq = { workspace = true } 21 | hex = { workspace = true } 22 | chrono = { workspace = true } 23 | humantime-serde = { workspace = true } 24 | syslog = { workspace = true } 25 | signal-hook = { workspace = true } 26 | handlebars = { workspace = true } 27 | getrandom = { workspace = true } 28 | anyhow = { workspace = true } 29 | -------------------------------------------------------------------------------- /libloragw-2g4/build.rs: -------------------------------------------------------------------------------- 1 | extern crate bindgen; 2 | 3 | use std::env; 4 | use std::path::PathBuf; 5 | 6 | fn main() { 7 | // Tell cargo to tell rustc to link the loragw 8 | // shared library. 9 | println!("cargo:rustc-link-lib=loragw-2g4"); 10 | 11 | // The bindgen::Builder is the main entry point 12 | // to bindgen, and lets you build up options for 13 | // the resulting bindings. 14 | let bindings = bindgen::Builder::default() 15 | // The input header we would like to generate 16 | // bindings for. 17 | .header("wrapper.h") 18 | // Derive Default. 19 | .derive_default(true) 20 | // Finish the builder and generate the bindings. 21 | .generate() 22 | // Unwrap the Result and panic on failure. 23 | .expect("Unable to generate bindings"); 24 | 25 | // Write the bindings to the $OUT_DIR/bindings.rs file. 26 | let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); 27 | bindings 28 | .write_to_file(out_path.join("bindings.rs")) 29 | .expect("Couldn't write bindings!"); 30 | } 31 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/2.feature.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest a new idea to ChirpStack Concentratord 4 | --- 5 | 6 | 10 | 11 | 12 | 13 | - [ ] I have searched the [issues](https://github.com/brocaar/chirpstack-concentratord) of this repository and believe that this is not a duplicate. 14 | 15 | ## Summary 16 | 17 | 18 | 19 | ## What is the use-case? 20 | 21 | 22 | 23 | ## Implementation description 24 | 25 | 28 | 29 | ## Can you implement this by yourself and make a pull request? 30 | -------------------------------------------------------------------------------- /chirpstack-concentratord-2g4/config/concentratord.toml: -------------------------------------------------------------------------------- 1 | # Concentratord configuration. 2 | [concentratord] 3 | 4 | # Log level. 5 | # 6 | # Valid options are: 7 | # * TRACE 8 | # * DEBUG 9 | # * INFO 10 | # * WARN 11 | # * ERROR 12 | # * OFF 13 | log_level="INFO" 14 | 15 | # Log to syslog. 16 | # 17 | # When set to true, log messages are being written to syslog instead of stdout. 18 | log_to_syslog=true 19 | 20 | # Statistics interval. 21 | stats_interval="30s" 22 | 23 | # Configuration for the (ZeroMQ based) API. 24 | [concentratord.api] 25 | 26 | # Event PUB socket bind. 27 | event_bind="ipc:///tmp/concentratord_event" 28 | 29 | # Command REP socket bind. 30 | command_bind="ipc:///tmp/concentratord_command" 31 | 32 | 33 | # LoRa gateway configuration. 34 | [gateway] 35 | 36 | # Antenna gain (dBi). 37 | antenna_gain=0 38 | 39 | # Public LoRaWAN network. 40 | lorawan_public=true 41 | 42 | # Gateway vendor / model. 43 | # 44 | # This configures various vendor and model specific settings like the min / max 45 | # frequency, TX gain table. 46 | model="semtech_sx1280z3dsfgw1" 47 | -------------------------------------------------------------------------------- /libloragw-sx1301/build.rs: -------------------------------------------------------------------------------- 1 | extern crate bindgen; 2 | 3 | use std::env; 4 | use std::path::PathBuf; 5 | 6 | fn main() { 7 | // Tell cargo to tell rustc to link the loragw 8 | // shared library. 9 | println!("cargo:rustc-link-lib=loragw-sx1301"); 10 | 11 | // The bindgen::Builder is the main entry point 12 | // to bindgen, and lets you build up options for 13 | // the resulting bindings. 14 | let bindings = bindgen::Builder::default() 15 | // The input header we would like to generate 16 | // bindings for. 17 | .header("wrapper.h") 18 | // Derive Default. 19 | .derive_default(true) 20 | // Finish the builder and generate the bindings. 21 | .generate() 22 | // Unwrap the Result and panic on failure. 23 | .expect("Unable to generate bindings"); 24 | 25 | // Write the bindings to the $OUT_DIR/bindings.rs file. 26 | let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); 27 | bindings 28 | .write_to_file(out_path.join("bindings.rs")) 29 | .expect("Couldn't write bindings!"); 30 | } 31 | -------------------------------------------------------------------------------- /packaging/vendor/multitech/conduit/files/sx1302/concentratord.toml: -------------------------------------------------------------------------------- 1 | # Concentratord configuration. 2 | [concentratord] 3 | 4 | # Log level. 5 | # 6 | # Valid options are: 7 | # * TRACE 8 | # * DEBUG 9 | # * INFO 10 | # * WARN 11 | # * ERROR 12 | # * OFF 13 | log_level="INFO" 14 | 15 | # Log to syslog. 16 | # 17 | # When set to true, log messages are being written to syslog instead of stdout. 18 | log_to_syslog=true 19 | 20 | # Statistics interval. 21 | stats_interval="30s" 22 | 23 | # Configuration for the (ZeroMQ based) API. 24 | [concentratord.api] 25 | 26 | # Event PUB socket bind. 27 | event_bind="ipc:///tmp/concentratord_event" 28 | 29 | # Command REP socket bind. 30 | command_bind="ipc:///tmp/concentratord_command" 31 | 32 | 33 | # LoRa gateway configuration. 34 | [gateway] 35 | 36 | # Antenna gain (dBi). 37 | antenna_gain=0 38 | 39 | # Public LoRaWAN network. 40 | lorawan_public=true 41 | 42 | # Region. 43 | region="" 44 | 45 | # Gateway vendor / model. 46 | model="" 47 | 48 | # Gateway vendor / model flags. 49 | model_flags=[] 50 | 51 | # Time fallback. 52 | time_fallback_enabled=true -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2022 Orne Brocaar 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /libloragw-sx1302/build.rs: -------------------------------------------------------------------------------- 1 | extern crate bindgen; 2 | 3 | use std::env; 4 | use std::path::PathBuf; 5 | 6 | fn main() { 7 | // Tell cargo to tell rustc to link the sx1302 HAL library + tinymt32 dependency. 8 | println!("cargo:rustc-link-lib=loragw-sx1302"); 9 | println!("cargo:rustc-link-lib=tinymt32"); 10 | 11 | // The bindgen::Builder is the main entry point 12 | // to bindgen, and lets you build up options for 13 | // the resulting bindings. 14 | let bindings = bindgen::Builder::default() 15 | // The input header we would like to generate 16 | // bindings for. 17 | .header("wrapper.h") 18 | // Derive Default. 19 | .derive_default(true) 20 | // Finish the builder and generate the bindings. 21 | .generate() 22 | // Unwrap the Result and panic on failure. 23 | .expect("Unable to generate bindings"); 24 | 25 | // Write the bindings to the $OUT_DIR/bindings.rs file. 26 | let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); 27 | bindings 28 | .write_to_file(out_path.join("bindings.rs")) 29 | .expect("Couldn't write bindings!"); 30 | } 31 | -------------------------------------------------------------------------------- /packaging/vendor/multitech/conduit-ap/files/concentratord.toml: -------------------------------------------------------------------------------- 1 | # Concentratord configuration. 2 | [concentratord] 3 | 4 | # Log level. 5 | # 6 | # Valid options are: 7 | # * TRACE 8 | # * DEBUG 9 | # * INFO 10 | # * WARN 11 | # * ERROR 12 | # * OFF 13 | log_level="INFO" 14 | 15 | # Log to syslog. 16 | # 17 | # When set to true, log messages are being written to syslog instead of stdout. 18 | log_to_syslog=true 19 | 20 | # Statistics interval. 21 | stats_interval="30s" 22 | 23 | # Configuration for the (ZeroMQ based) API. 24 | [concentratord.api] 25 | 26 | # Event PUB socket bind. 27 | event_bind="ipc:///tmp/concentratord_event" 28 | 29 | # Command REP socket bind. 30 | command_bind="ipc:///tmp/concentratord_command" 31 | 32 | 33 | # LoRa gateway configuration. 34 | [gateway] 35 | 36 | # Antenna gain (dBi). 37 | antenna_gain=0 38 | 39 | # Public LoRaWAN network. 40 | lorawan_public=true 41 | 42 | # Region. 43 | region="" 44 | 45 | # Gateway vendor / model. 46 | model="" 47 | 48 | # Gateway vendor / model flags. 49 | model_flags=[] 50 | 51 | # Gateway ID. 52 | gateway_id="" 53 | 54 | # Time fallback. 55 | time_fallback_enabled=true -------------------------------------------------------------------------------- /packaging/vendor/multitech/conduit/files/sx1301/concentratord.toml: -------------------------------------------------------------------------------- 1 | # Concentratord configuration. 2 | [concentratord] 3 | 4 | # Log level. 5 | # 6 | # Valid options are: 7 | # * TRACE 8 | # * DEBUG 9 | # * INFO 10 | # * WARN 11 | # * ERROR 12 | # * OFF 13 | log_level="INFO" 14 | 15 | # Log to syslog. 16 | # 17 | # When set to true, log messages are being written to syslog instead of stdout. 18 | log_to_syslog=true 19 | 20 | # Statistics interval. 21 | stats_interval="30s" 22 | 23 | # Configuration for the (ZeroMQ based) API. 24 | [concentratord.api] 25 | 26 | # Event PUB socket bind. 27 | event_bind="ipc:///tmp/concentratord_event" 28 | 29 | # Command REP socket bind. 30 | command_bind="ipc:///tmp/concentratord_command" 31 | 32 | 33 | # LoRa gateway configuration. 34 | [gateway] 35 | 36 | # Antenna gain (dBi). 37 | antenna_gain=0 38 | 39 | # Public LoRaWAN network. 40 | lorawan_public=true 41 | 42 | # Region. 43 | region="" 44 | 45 | # Gateway vendor / model. 46 | model="" 47 | 48 | # Gateway vendor / model flags. 49 | model_flags=[] 50 | 51 | # Gateway ID. 52 | gateway_id="" 53 | 54 | # Time fallback. 55 | time_fallback_enabled=true -------------------------------------------------------------------------------- /packaging/vendor/multitech/conduit/files/2g4/concentratord.toml: -------------------------------------------------------------------------------- 1 | # Concentratord configuration. 2 | [concentratord] 3 | 4 | # Log level. 5 | # 6 | # Valid options are: 7 | # * TRACE 8 | # * DEBUG 9 | # * INFO 10 | # * WARN 11 | # * ERROR 12 | # * OFF 13 | log_level="INFO" 14 | 15 | # Log to syslog. 16 | # 17 | # When set to true, log messages are being written to syslog instead of stdout. 18 | log_to_syslog=true 19 | 20 | # Statistics interval. 21 | stats_interval="30s" 22 | 23 | # Configuration for the (ZeroMQ based) API. 24 | [concentratord.api] 25 | 26 | # Event PUB socket bind. 27 | event_bind="ipc:///tmp/concentratord_event" 28 | 29 | # Command REP socket bind. 30 | command_bind="ipc:///tmp/concentratord_command" 31 | 32 | 33 | # LoRa gateway configuration. 34 | [gateway] 35 | 36 | # Antenna gain (dBi). 37 | antenna_gain=0 38 | 39 | # Public LoRaWAN network. 40 | lorawan_public=true 41 | 42 | # Gateway vendor / model. 43 | # 44 | # This configures various vendor and model specific settings like the min / max 45 | # frequency, TX gain table. 46 | model="multitech_mtac_lora_2g4" 47 | 48 | # Time fallback. 49 | time_fallback_enabled=true -------------------------------------------------------------------------------- /packaging/vendor/kerlink/ifemtocell/files/concentratord.toml: -------------------------------------------------------------------------------- 1 | # Concentratord configuration. 2 | [concentratord] 3 | 4 | # Log level. 5 | # 6 | # Valid options are: 7 | # * TRACE 8 | # * DEBUG 9 | # * INFO 10 | # * WARN 11 | # * ERROR 12 | # * OFF 13 | log_level="INFO" 14 | 15 | # Log to syslog. 16 | # 17 | # When set to true, log messages are being written to syslog instead of stdout. 18 | log_to_syslog=true 19 | 20 | # Statistics interval. 21 | stats_interval="30s" 22 | 23 | # Configuration for the (ZeroMQ based) API. 24 | [concentratord.api] 25 | 26 | # Event PUB socket bind. 27 | event_bind="ipc:///tmp/concentratord_event" 28 | 29 | # Command REP socket bind. 30 | command_bind="ipc:///tmp/concentratord_command" 31 | 32 | 33 | # LoRa gateway configuration. 34 | [gateway] 35 | 36 | # Antenna gain (dBi). 37 | antenna_gain=0 38 | 39 | # Public LoRaWAN network. 40 | lorawan_public=true 41 | 42 | # Region. 43 | region="EU868" 44 | 45 | # Gateway vendor / model. 46 | model="kerlink_ifemtocell" 47 | 48 | # Gateway vendor / model flags. 49 | model_flags=[] 50 | 51 | # Gateway ID. 52 | gateway_id="" 53 | 54 | # Time fallback. 55 | time_fallback_enabled=true -------------------------------------------------------------------------------- /libloragw-sx1302/src/timespec.rs: -------------------------------------------------------------------------------- 1 | use std::ops::Add; 2 | use std::time::{Duration, SystemTime}; 3 | 4 | use super::wrapper; 5 | 6 | pub fn timespec_to_system_time(ts: &wrapper::timespec) -> SystemTime { 7 | SystemTime::UNIX_EPOCH 8 | .add(Duration::from_secs(ts.tv_sec as u64) + Duration::from_nanos(ts.tv_nsec as u64)) 9 | } 10 | 11 | pub fn system_time_to_timespec(st: &SystemTime) -> wrapper::timespec { 12 | let utc_dur = st.duration_since(SystemTime::UNIX_EPOCH).unwrap(); 13 | 14 | #[allow(clippy::needless_update)] 15 | wrapper::timespec { 16 | tv_sec: utc_dur.as_secs() as wrapper::time_t, 17 | tv_nsec: (utc_dur.as_nanos() % 1000000000) as std::os::raw::c_long, 18 | ..Default::default() 19 | } 20 | } 21 | 22 | pub fn duration_to_timespec(d: &Duration) -> wrapper::timespec { 23 | #[allow(clippy::needless_update)] 24 | wrapper::timespec { 25 | tv_sec: d.as_secs() as wrapper::time_t, 26 | tv_nsec: (d.as_nanos() % 1000000000) as std::os::raw::c_long, 27 | ..Default::default() 28 | } 29 | } 30 | 31 | pub fn timespec_to_duration(ts: &wrapper::timespec) -> Duration { 32 | Duration::from_secs(ts.tv_sec as u64) + Duration::from_nanos(ts.tv_nsec as u64) 33 | } 34 | -------------------------------------------------------------------------------- /libloragw-sx1301/src/timespec.rs: -------------------------------------------------------------------------------- 1 | use std::ops::Add; 2 | use std::time::{Duration, SystemTime}; 3 | 4 | use super::wrapper; 5 | 6 | pub fn timespec_to_system_time(ts: &wrapper::timespec) -> SystemTime { 7 | SystemTime::UNIX_EPOCH 8 | .add(Duration::from_secs(ts.tv_sec as u64) + Duration::from_nanos(ts.tv_nsec as u64)) 9 | } 10 | 11 | pub fn system_time_to_timespec(st: &SystemTime) -> wrapper::timespec { 12 | let utc_dur = st.duration_since(SystemTime::UNIX_EPOCH).unwrap(); 13 | 14 | #[allow(clippy::needless_update)] 15 | wrapper::timespec { 16 | tv_sec: utc_dur.as_secs() as wrapper::time_t, 17 | tv_nsec: (utc_dur.as_nanos() % 1000000000) as std::os::raw::c_long, 18 | ..Default::default() 19 | } 20 | } 21 | 22 | 23 | pub fn duration_to_timespec(d: &Duration) -> wrapper::timespec { 24 | #[allow(clippy::needless_update)] 25 | wrapper::timespec { 26 | tv_sec: d.as_secs() as wrapper::time_t, 27 | tv_nsec: (d.as_nanos() % 1000000000) as std::os::raw::c_long, 28 | ..Default::default() 29 | } 30 | } 31 | 32 | pub fn timespec_to_duration(ts: &wrapper::timespec) -> Duration { 33 | Duration::from_secs(ts.tv_sec as u64) + Duration::from_nanos(ts.tv_nsec as u64) 34 | } 35 | -------------------------------------------------------------------------------- /packaging/vendor/multitech/conduit-ap3/files/concentratord.toml: -------------------------------------------------------------------------------- 1 | # Concentratord configuration. 2 | [concentratord] 3 | 4 | # Log level. 5 | # 6 | # Valid options are: 7 | # * TRACE 8 | # * DEBUG 9 | # * INFO 10 | # * WARN 11 | # * ERROR 12 | # * OFF 13 | log_level="INFO" 14 | 15 | # Log to syslog. 16 | # 17 | # When set to true, log messages are being written to syslog instead of stdout. 18 | log_to_syslog=true 19 | 20 | # Statistics interval. 21 | stats_interval="30s" 22 | 23 | # Configuration for the (ZeroMQ based) API. 24 | [concentratord.api] 25 | 26 | # Event PUB socket bind. 27 | event_bind="ipc:///tmp/concentratord_event" 28 | 29 | # Command REP socket bind. 30 | command_bind="ipc:///tmp/concentratord_command" 31 | 32 | 33 | # LoRa gateway configuration. 34 | [gateway] 35 | 36 | # Antenna gain (dBi). 37 | antenna_gain=0 38 | 39 | # Public LoRaWAN network. 40 | lorawan_public=true 41 | 42 | # Region. 43 | region="" 44 | 45 | # Gateway vendor / model. 46 | model="" 47 | 48 | # Gateway vendor / model flags. 49 | model_flags=[] 50 | 51 | # Gateway ID. 52 | # 53 | # Only set this if you would like to override the Gateway ID provided by the SX1302/3. 54 | gateway_id="" 55 | 56 | # Time fallback. 57 | time_fallback_enabled=true 58 | -------------------------------------------------------------------------------- /packaging/vendor/kerlink/ifemtocell/files/chirpstack-concentratord.init: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | NAME="chirpstack-concentratord" 4 | DESC="ChirpStack Concentratord" 5 | DAEMON_BIN=/usr/bin/$NAME 6 | DAEMON_CONF_DIR=/etc/$NAME 7 | DAEMON_PID=/var/run/$NAME.pid 8 | 9 | 10 | set_gateway_id() { 11 | gateway_id=`cat /tmp/board_info.json |grep EUI64 |cut -d'"' -f 4` 12 | sed -i "s/gateway_id=.*/gateway_id=\"${gateway_id}\"/" $DAEMON_CONF_DIR/concentratord.toml 13 | } 14 | 15 | function do_start { 16 | set_gateway_id 17 | 18 | echo "Starting $NAME" 19 | start-stop-daemon \ 20 | --start \ 21 | --background \ 22 | --make-pidfile \ 23 | --pidfile $DAEMON_PID \ 24 | --exec $DAEMON_BIN -- -c $DAEMON_CONF_DIR/concentratord.toml -c $DAEMON_CONF_DIR/channels.toml 25 | } 26 | 27 | function do_stop { 28 | echo "Stopping $NAME" 29 | start-stop-daemon \ 30 | --stop \ 31 | --oknodo \ 32 | --quiet \ 33 | --pidfile $DAEMON_PID 34 | } 35 | 36 | case "$1" in 37 | "start") 38 | do_start 39 | ;; 40 | "stop") 41 | do_stop 42 | ;; 43 | "restart") 44 | do_stop 45 | do_start 46 | ;; 47 | *) 48 | echo "Usage: $1 {start|stop|restart}" 49 | exit 1 50 | ;; 51 | esac 52 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | resolver = "3" 3 | members = [ 4 | "chirpstack-concentratord-2g4", 5 | "chirpstack-concentratord-sx1301", 6 | "chirpstack-concentratord-sx1302", 7 | "gateway-id", 8 | "gateway-location", 9 | "libloragw-sx1301", 10 | "libloragw-sx1302", 11 | "libloragw-2g4", 12 | "libconcentratord", 13 | ] 14 | 15 | [workspace.dependencies] 16 | chirpstack_api = { version = "4.15", default-features = false } 17 | serde = { version = "1.0", features = ["derive"] } 18 | serde_json = "1.0" 19 | toml = { version = "0.9", default-features = false, features = [ 20 | "std", 21 | "parse", 22 | "serde", 23 | ] } 24 | clap = { version = "4.5", default-features = false, features = [ 25 | "std", 26 | "help", 27 | "usage", 28 | "derive", 29 | ] } 30 | log = "0.4" 31 | simple_logger = { version = "5.0", default-features = false, features = [ 32 | "timestamps", 33 | ] } 34 | zmq = "0.10" 35 | hex = "0.4" 36 | chrono = { version = "0.4", default-features = false, features = ["now"] } 37 | humantime-serde = "1.1" 38 | syslog = "7.0" 39 | signal-hook = "0.3" 40 | handlebars = "6.3" 41 | getrandom = "0.3" 42 | anyhow = "1.0" 43 | thiserror = "2.0" 44 | bindgen = "0.72" 45 | gpiocdev = { version = "0.7", features = ["uapi_v1"] } 46 | -------------------------------------------------------------------------------- /gateway-location/src/main.rs: -------------------------------------------------------------------------------- 1 | use std::process::exit; 2 | 3 | use chirpstack_api::{gw, prost::Message}; 4 | use clap::Parser; 5 | 6 | #[derive(Parser)] 7 | #[command(author, version, about)] 8 | struct Cli { 9 | /// ZMQ command URL 10 | #[arg(short, long, default_value = "ipc:///tmp/concentratord_command")] 11 | command_url: String, 12 | } 13 | 14 | fn main() { 15 | let cli = Cli::parse(); 16 | 17 | // create new zmq REQ socket 18 | let zmq_ctx = zmq::Context::new(); 19 | let zmq_sock = zmq_ctx.socket(zmq::REQ).expect("new ZMQ socket error"); 20 | zmq_sock 21 | .connect(&cli.command_url) 22 | .expect("ZMQ connect error"); 23 | 24 | // Send command. 25 | let cmd = gw::Command { 26 | command: Some(gw::command::Command::GetLocation(gw::GetLocationRequest {})), 27 | }; 28 | zmq_sock.send(cmd.encode_to_vec(), 0).unwrap(); 29 | 30 | // set poller so that we can timeout after 100ms 31 | let mut items = [zmq_sock.as_poll_item(zmq::POLLIN)]; 32 | zmq::poll(&mut items, 100).unwrap(); 33 | if !items[0].is_readable() { 34 | println!("could not read gateway_id"); 35 | exit(1); 36 | } 37 | 38 | // Read response. 39 | let b = zmq_sock.recv_bytes(0).unwrap(); 40 | let resp = gw::GetLocationResponse::decode(b.as_slice()).unwrap(); 41 | println!("{:?}", resp); 42 | exit(0); 43 | } 44 | -------------------------------------------------------------------------------- /gateway-id/src/main.rs: -------------------------------------------------------------------------------- 1 | use std::process::exit; 2 | 3 | use chirpstack_api::{gw, prost::Message}; 4 | use clap::Parser; 5 | 6 | #[derive(Parser)] 7 | #[command(author, version, about)] 8 | struct Cli { 9 | /// ZMQ command URL 10 | #[arg(short, long, default_value = "ipc:///tmp/concentratord_command")] 11 | command_url: String, 12 | } 13 | 14 | fn main() { 15 | let cli = Cli::parse(); 16 | 17 | // create new zmq REQ socket 18 | let zmq_ctx = zmq::Context::new(); 19 | let zmq_sock = zmq_ctx.socket(zmq::REQ).expect("new ZMQ socket error"); 20 | zmq_sock 21 | .connect(&cli.command_url) 22 | .expect("ZMQ connect error"); 23 | 24 | // Send command. 25 | let cmd = gw::Command { 26 | command: Some(gw::command::Command::GetGatewayId( 27 | gw::GetGatewayIdRequest {}, 28 | )), 29 | }; 30 | zmq_sock.send(cmd.encode_to_vec(), 0).unwrap(); 31 | 32 | // set poller so that we can timeout after 100ms 33 | let mut items = [zmq_sock.as_poll_item(zmq::POLLIN)]; 34 | zmq::poll(&mut items, 100).unwrap(); 35 | if !items[0].is_readable() { 36 | println!("could not read gateway_id"); 37 | exit(1); 38 | } 39 | 40 | // Read response. 41 | let b = zmq_sock.recv_bytes(0).unwrap(); 42 | let resp = gw::GetGatewayIdResponse::decode(b.as_slice()).unwrap(); 43 | println!("{}", resp.gateway_id); 44 | exit(0); 45 | } 46 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1302/src/config/vendor/mod.rs: -------------------------------------------------------------------------------- 1 | use libconcentratord::gnss; 2 | use libloragw_sx1302::hal; 3 | 4 | pub mod dragino; 5 | pub mod embit; 6 | pub mod miromico; 7 | pub mod multitech; 8 | pub mod rak; 9 | pub mod seeed; 10 | pub mod semtech; 11 | pub mod waveshare; 12 | 13 | #[derive(Default, Clone, PartialEq, Debug)] 14 | pub enum ComType { 15 | #[default] 16 | Spi, 17 | Usb, 18 | } 19 | 20 | #[derive(Default, Clone)] 21 | pub struct Configuration { 22 | pub radio_count: usize, 23 | pub clock_source: u8, 24 | pub full_duplex: bool, 25 | pub lora_multi_sf_bandwidth: u32, 26 | pub radio_config: Vec, 27 | pub gps: gnss::Device, 28 | pub com_type: ComType, 29 | pub com_path: String, 30 | pub i2c_path: Option, 31 | pub i2c_temp_sensor_addr: Option, 32 | pub sx1302_reset_pin: Option<(String, u32)>, 33 | pub sx1302_power_en_pin: Option<(String, u32)>, 34 | pub sx1261_reset_pin: Option<(String, u32)>, 35 | pub ad5338r_reset_pin: Option<(String, u32)>, 36 | pub reset_commands: Option)>>, 37 | pub enforce_duty_cycle: bool, 38 | } 39 | 40 | #[derive(Clone)] 41 | pub struct RadioConfig { 42 | pub radio_type: hal::RadioType, 43 | pub single_input_mode: bool, 44 | pub rssi_offset: f32, 45 | pub rssi_temp_compensation: hal::RssiTempCompensationConfig, 46 | pub tx_enable: bool, 47 | pub tx_min_max_freqs: Vec<(u32, u32)>, 48 | pub tx_gain_table: Vec, 49 | } 50 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1302/config/concentratord.toml: -------------------------------------------------------------------------------- 1 | # Concentratord configuration. 2 | [concentratord] 3 | 4 | # Log level. 5 | # 6 | # Valid options are: 7 | # * TRACE 8 | # * DEBUG 9 | # * INFO 10 | # * WARN 11 | # * ERROR 12 | # * OFF 13 | log_level="INFO" 14 | 15 | # Log to syslog. 16 | # 17 | # When set to true, log messages are being written to syslog instead of stdout. 18 | log_to_syslog=true 19 | 20 | # Statistics interval. 21 | stats_interval="30s" 22 | 23 | # Configuration for the (ZeroMQ based) API. 24 | [concentratord.api] 25 | 26 | # Event PUB socket bind. 27 | event_bind="ipc:///tmp/concentratord_event" 28 | 29 | # Command REP socket bind. 30 | command_bind="ipc:///tmp/concentratord_command" 31 | 32 | 33 | # LoRa gateway configuration. 34 | [gateway] 35 | 36 | # Antenna gain (dBi). 37 | antenna_gain=0 38 | 39 | # Public LoRaWAN network. 40 | lorawan_public=true 41 | 42 | # Region. 43 | # 44 | # The region of the gateway. Options: 45 | # EU868, US915, CN779, EU433, AU915, CN470, AS923, AS923_2, AS923_3, AS923_4, 46 | # KR923, IN865, RU864 47 | # 48 | # Not not all the gateway models implement all regions. 49 | region="" 50 | 51 | # Gateway vendor / model. 52 | # 53 | # This configures various vendor and model specific settings like the min / max 54 | # frequency, TX gain table. 55 | model="" 56 | 57 | # Gateway vendor / model flags. 58 | model_flags=[] 59 | 60 | # Gateway ID. 61 | # 62 | # Only set this if you would like to override the Gateway ID provided by the SX1302/3. 63 | gateway_id="" 64 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1301/config/concentratord.toml: -------------------------------------------------------------------------------- 1 | # Concentratord configuration. 2 | [concentratord] 3 | 4 | # Log level. 5 | # 6 | # Valid options are: 7 | # * TRACE 8 | # * DEBUG 9 | # * INFO 10 | # * WARN 11 | # * ERROR 12 | # * OFF 13 | log_level="INFO" 14 | 15 | # Log to syslog. 16 | # 17 | # When set to true, log messages are being written to syslog instead of stdout. 18 | log_to_syslog=true 19 | 20 | # Statistics interval. 21 | stats_interval="30s" 22 | 23 | # Configuration for the (ZeroMQ based) API. 24 | [concentratord.api] 25 | 26 | # Event PUB socket bind. 27 | event_bind="ipc:///tmp/concentratord_event" 28 | 29 | # Command REP socket bind. 30 | command_bind="ipc:///tmp/concentratord_command" 31 | 32 | 33 | # LoRa gateway configuration. 34 | [gateway] 35 | 36 | # Antenna gain (dBi). 37 | antenna_gain=0 38 | 39 | # Public LoRaWAN network. 40 | lorawan_public=true 41 | 42 | # Region. 43 | # 44 | # The region of the gateway. Options: 45 | # EU868, US915, CN779, EU433, AU915, CN470, AS923, AS923_2, AS923_3, AS923_4, 46 | # KR923, IN865, RU864 47 | # 48 | # Not not all the gateway models implement all regions. 49 | region="" 50 | 51 | # Gateway vendor / model. 52 | # 53 | # This configures various vendor and model specific settings like the min / max 54 | # frequency, TX gain table. 55 | model="" 56 | 57 | # Gateway vendor / model flags. 58 | model_flags=[] 59 | 60 | # Gateway ID. 61 | gateway_id="0101010101010101" 62 | 63 | # Reset pin. 64 | # 65 | # Note: most model configurations come with a pre-defined reset_pin, in which 66 | # case the setting below will be ignored. 67 | reset_pin=0 68 | -------------------------------------------------------------------------------- /libconcentratord/src/events.rs: -------------------------------------------------------------------------------- 1 | use std::sync::{LazyLock, Mutex}; 2 | 3 | use anyhow::Result; 4 | use chirpstack_api::{gw, prost::Message}; 5 | use log::info; 6 | 7 | use super::socket::ZMQ_CONTEXT; 8 | 9 | static ZMQ_PUB: LazyLock>> = LazyLock::new(|| Mutex::new(None)); 10 | 11 | pub fn bind_socket(bind: &str) -> Result<()> { 12 | info!("Creating socket for publishing events, bind: {}", bind); 13 | 14 | let zmq_ctx = ZMQ_CONTEXT.lock().unwrap(); 15 | let mut zmq_pub = ZMQ_PUB.lock().unwrap(); 16 | 17 | let sock = zmq_ctx.socket(zmq::PUB)?; 18 | sock.bind(bind)?; 19 | 20 | *zmq_pub = Some(sock); 21 | 22 | Ok(()) 23 | } 24 | 25 | pub fn send_uplink(pl: chirpstack_api::gw::UplinkFrame) -> Result<()> { 26 | let pub_guard = ZMQ_PUB.lock().unwrap(); 27 | let publisher = pub_guard.as_ref().unwrap(); 28 | 29 | let event = gw::Event { 30 | event: Some(gw::event::Event::UplinkFrame(pl)), 31 | }; 32 | 33 | publisher.send(event.encode_to_vec(), 0).unwrap(); 34 | 35 | Ok(()) 36 | } 37 | 38 | pub fn send_stats(stats: chirpstack_api::gw::GatewayStats) -> Result<()> { 39 | let pub_guard = ZMQ_PUB.lock().unwrap(); 40 | let publisher = pub_guard.as_ref().unwrap(); 41 | 42 | info!( 43 | "Publishing stats event, rx_received: {}, rx_received_ok: {}, tx_received: {}, tx_emitted: {}", 44 | stats.rx_packets_received, 45 | stats.rx_packets_received_ok, 46 | stats.tx_packets_received, 47 | stats.tx_packets_emitted 48 | ); 49 | 50 | let event = gw::Event { 51 | event: Some(gw::event::Event::GatewayStats(stats)), 52 | }; 53 | 54 | publisher.send(event.encode_to_vec(), 0).unwrap(); 55 | 56 | Ok(()) 57 | } 58 | -------------------------------------------------------------------------------- /libconcentratord/src/gnss.rs: -------------------------------------------------------------------------------- 1 | use serde::{Deserialize, Deserializer, Serialize, Serializer}; 2 | 3 | #[derive(Debug, Default, Clone, PartialEq)] 4 | pub enum Device { 5 | #[default] 6 | None, 7 | TtyPath(String), 8 | Gpsd(String), 9 | } 10 | 11 | impl Device { 12 | pub fn new(path: &str) -> Device { 13 | if path.is_empty() { 14 | return Device::None; 15 | } 16 | 17 | if let Some(host) = path.strip_prefix("gpsd://") { 18 | return Device::Gpsd(host.to_string()); 19 | } 20 | 21 | Device::TtyPath(path.to_string()) 22 | } 23 | } 24 | 25 | impl<'de> Deserialize<'de> for Device { 26 | fn deserialize(deserializer: D) -> Result 27 | where 28 | D: Deserializer<'de>, 29 | { 30 | let s = String::deserialize(deserializer)?; 31 | Ok(Device::new(&s)) 32 | } 33 | } 34 | 35 | impl Serialize for Device { 36 | fn serialize(&self, serializer: S) -> Result 37 | where 38 | S: Serializer, 39 | { 40 | serializer.serialize_str(&match self { 41 | Device::None => "".to_string(), 42 | Device::TtyPath(v) => v.to_string(), 43 | Device::Gpsd(v) => format!("gpsd://{}", v), 44 | }) 45 | } 46 | } 47 | 48 | #[cfg(test)] 49 | mod test { 50 | use super::*; 51 | 52 | #[test] 53 | fn test_device_none() { 54 | assert_eq!(Device::None, Device::new("")); 55 | } 56 | 57 | #[test] 58 | fn test_device_tty_path() { 59 | assert_eq!( 60 | Device::TtyPath("/dev/ttyAMA0".to_string()), 61 | Device::new("/dev/ttyAMA0") 62 | ); 63 | } 64 | 65 | #[test] 66 | fn test_device_gpsd() { 67 | assert_eq!( 68 | Device::Gpsd("localhost:2947".to_string()), 69 | Device::new("gpsd://localhost:2947") 70 | ); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /libconcentratord/src/commands.rs: -------------------------------------------------------------------------------- 1 | use std::time::Duration; 2 | 3 | use anyhow::Result; 4 | use chirpstack_api::{gw, prost::Message}; 5 | use log::info; 6 | 7 | use crate::error::Error; 8 | use crate::socket::ZMQ_CONTEXT; 9 | 10 | pub fn get_socket(bind: &str) -> Result { 11 | info!("Creating socket for receiving commands, bind: {}", bind); 12 | 13 | let zmq_ctx = ZMQ_CONTEXT.lock().unwrap(); 14 | let sock = zmq_ctx.socket(zmq::REP)?; 15 | sock.bind(bind)?; 16 | Ok(sock) 17 | } 18 | 19 | pub enum Command { 20 | // Reading command timed out. 21 | Timeout, 22 | 23 | // Error reading command. 24 | Error(String), 25 | 26 | // Unknown command. 27 | Unknown(String, Vec), 28 | 29 | // Downlink enqueue. 30 | Downlink(chirpstack_api::gw::DownlinkFrame), 31 | 32 | // Gateway ID request. 33 | GatewayID, 34 | 35 | // Gateway configuration. 36 | Configuration(chirpstack_api::gw::GatewayConfiguration), 37 | } 38 | 39 | pub struct Reader<'a> { 40 | rep_sock: &'a zmq::Socket, 41 | timeout: Duration, 42 | } 43 | 44 | impl<'a> Reader<'a> { 45 | pub fn new(rep_sock: &'a zmq::Socket, timeout: Duration) -> Self { 46 | Reader { rep_sock, timeout } 47 | } 48 | } 49 | 50 | impl Iterator for Reader<'_> { 51 | type Item = Result; 52 | 53 | fn next(&mut self) -> Option> { 54 | // set poller so that we can timeout 55 | let mut items = [self.rep_sock.as_poll_item(zmq::POLLIN)]; 56 | zmq::poll(&mut items, self.timeout.as_millis() as i64).unwrap(); 57 | if !items[0].is_readable() { 58 | return Some(Err(Error::Timeout)); 59 | } 60 | 61 | let b = self.rep_sock.recv_bytes(0).unwrap(); 62 | match gw::Command::decode(b.as_slice()).map_err(|e| Error::Anyhow(anyhow::Error::new(e))) { 63 | Ok(v) => Some(Ok(v)), 64 | Err(e) => Some(Err(e)), 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/1.bug.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a bug report for ChirpStack Concentratord 4 | --- 5 | 6 | 10 | 11 | 12 | 13 | - [ ] The issue is present in the latest release. 14 | - [ ] I have searched the [issues](https://github.com/brocaar/chirpstack-concentratord) of this repository and believe that this is not a duplicate. 15 | 16 | ## What happened? 17 | 18 | ## What did you expect? 19 | 20 | ## Steps to reproduce this issue 21 | 22 | Steps: 23 | 24 | 1. 25 | 2. 26 | 3. 27 | 4. 28 | 29 | ## Could you share your log output? 30 | 31 | 37 | ```shell 38 | 39 | ``` 40 | 41 | ## Your Environment 42 | 43 | 60 | 61 | 62 | | Component | Version | 63 | | --------------------| ------- | 64 | | Application Server | v?.?.? | 65 | | Network Server | | 66 | | Gateway Bridge | | 67 | | Chirpstack API | | 68 | | Geolocation | | 69 | | Concentratord | | 70 | -------------------------------------------------------------------------------- /chirpstack-concentratord-2g4/src/handler/stats.rs: -------------------------------------------------------------------------------- 1 | use std::collections::HashMap; 2 | use std::sync::{mpsc::Receiver, Arc, Mutex}; 3 | use std::time::Duration; 4 | 5 | use anyhow::{Context, Result}; 6 | 7 | use chirpstack_api::gw::DutyCycleStats; 8 | use libconcentratord::signals::Signal; 9 | use libconcentratord::{jitqueue, stats}; 10 | use libloragw_2g4::hal; 11 | 12 | use super::gps; 13 | use crate::wrapper; 14 | 15 | pub fn stats_loop( 16 | gateway_id: &[u8], 17 | stats_interval: &Duration, 18 | stop_receive: Receiver, 19 | metadata: &HashMap, 20 | queue: Arc>>, 21 | ) -> Result<()> { 22 | debug!("Starting stats loop, stats_interval: {:?}", stats_interval); 23 | 24 | loop { 25 | // Instead of a 'stats interval' sleep, we receive from the stop channel with a 26 | // timeout equal to the 'stats interval'. 27 | if let Ok(v) = stop_receive.recv_timeout(*stats_interval) { 28 | debug!("Received stop signal, signal: {}", v); 29 | return Ok(()); 30 | } 31 | 32 | // fetch the current gps coordinates 33 | let loc = gps::get_coords().map(|v| chirpstack_api::common::Location { 34 | latitude: v.latitude, 35 | longitude: v.longitude, 36 | altitude: v.altitude as f64, 37 | source: chirpstack_api::common::LocationSource::Gps.into(), 38 | ..Default::default() 39 | }); 40 | 41 | let dc_stats = get_duty_cycle_stats(&queue)?; 42 | stats::send_and_reset(gateway_id, loc, dc_stats, metadata).context("Send stats")?; 43 | } 44 | } 45 | 46 | fn get_duty_cycle_stats( 47 | queue: &Arc>>, 48 | ) -> Result> { 49 | let mut queue = queue.lock().map_err(|_| anyhow!("Queue lock error"))?; 50 | let concentrator_count = hal::get_instcnt()?; 51 | Ok(queue.get_duty_cycle_stats(concentrator_count)) 52 | } 53 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1301/src/handler/stats.rs: -------------------------------------------------------------------------------- 1 | use std::collections::HashMap; 2 | use std::sync::{mpsc::Receiver, Arc, Mutex}; 3 | use std::time::Duration; 4 | 5 | use anyhow::Result; 6 | 7 | use chirpstack_api::gw::DutyCycleStats; 8 | use libconcentratord::signals::Signal; 9 | use libconcentratord::{jitqueue, stats}; 10 | 11 | use super::{gps, timersync}; 12 | use crate::wrapper; 13 | 14 | pub fn stats_loop( 15 | gateway_id: &[u8], 16 | stats_interval: &Duration, 17 | stop_receive: Receiver, 18 | metadata: &HashMap, 19 | queue: Arc>>, 20 | ) -> Result<()> { 21 | debug!("Starting stats loop, stats_interval: {:?}", stats_interval); 22 | 23 | loop { 24 | // Instead of a 'stats interval' sleep, we receive from the stop channel with a 25 | // timeout equal to the 'stats interval'. 26 | if let Ok(v) = stop_receive.recv_timeout(*stats_interval) { 27 | debug!("Received stop signal, signal: {}", v); 28 | return Ok(()); 29 | } 30 | 31 | // fetch the current gps coordinates 32 | let loc = gps::get_coords().map(|v| chirpstack_api::common::Location { 33 | latitude: v.latitude, 34 | longitude: v.longitude, 35 | altitude: v.altitude as f64, 36 | source: chirpstack_api::common::LocationSource::Gps.into(), 37 | ..Default::default() 38 | }); 39 | 40 | let dc_stats = get_duty_cycle_stats(&queue)?; 41 | stats::send_and_reset(gateway_id, loc, dc_stats, metadata).expect("sending stats failed"); 42 | } 43 | } 44 | 45 | fn get_duty_cycle_stats( 46 | queue: &Arc>>, 47 | ) -> Result> { 48 | let mut queue = queue.lock().map_err(|_| anyhow!("Lock queue error"))?; 49 | let concentrator_count = timersync::get_concentrator_count(); 50 | Ok(queue.get_duty_cycle_stats(concentrator_count)) 51 | } 52 | -------------------------------------------------------------------------------- /packaging/vendor/kerlink/ifemtocell/package.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | set -e 4 | 5 | REV="r1" 6 | 7 | PACKAGE_NAME="chirpstack-concentratord" 8 | PACKAGE_VERSION=`cargo metadata --no-deps --format-version 1 | jq -r '.packages[] | select(.name == "chirpstack-concentratord-sx1301").version'` 9 | PACKAGE_DESCRIPTION=`cargo metadata --no-deps --format-version 1 | jq -r '.packages[] | select(.name == "chirpstack-concentratord-sx1301").description'` 10 | BIN_PATH="../../../../target/armv7-unknown-linux-musleabihf/release/chirpstack-concentratord-sx1301" 11 | DIR=`dirname $0` 12 | PACKAGE_DIR="${DIR}/package" 13 | 14 | # Cleanup 15 | rm -rf $PACKAGE_DIR 16 | 17 | # CONTROL 18 | mkdir -p $PACKAGE_DIR/CONTROL 19 | cat > $PACKAGE_DIR/CONTROL/control << EOF 20 | Package: $PACKAGE_NAME 21 | Version: $PACKAGE_VERSION-$REV 22 | Architecture: klkgw 23 | Maintainer: Orne Brocaar 24 | Priority: optional 25 | Section: network 26 | Source: N/A 27 | Description: $PACKAGE_DESCRIPTION 28 | EOF 29 | 30 | cat > $PACKAGE_DIR/CONTROL/postinst << EOF 31 | #!/bin/sh 32 | /usr/bin/monit reload 33 | EOF 34 | chmod 755 $PACKAGE_DIR/CONTROL/postinst 35 | 36 | cat > $PACKAGE_DIR/CONTROL/conffiles << EOF 37 | /etc/$PACKAGE_NAME/concentratord.toml 38 | /etc/$PACKAGE_NAME/channels.toml 39 | EOF 40 | 41 | # Files 42 | mkdir -p $PACKAGE_DIR/usr/bin 43 | mkdir -p $PACKAGE_DIR/etc/$PACKAGE_NAME/examples 44 | mkdir -p $PACKAGE_DIR/etc/monit.d 45 | mkdir -p $PACKAGE_DIR/etc/init.d 46 | 47 | cp files/$PACKAGE_NAME.init $PACKAGE_DIR/etc/init.d/$PACKAGE_NAME 48 | cp files/$PACKAGE_NAME.monit $PACKAGE_DIR/etc/monit.d/$PACKAGE_NAME 49 | cp files/concentratord.toml $PACKAGE_DIR/etc/$PACKAGE_NAME 50 | cp files/channels.toml $PACKAGE_DIR/etc/$PACKAGE_NAME 51 | cp ../../../../chirpstack-concentratord-sx1301/config/channels_*.toml $PACKAGE_DIR/etc/$PACKAGE_NAME/examples 52 | 53 | cp $BIN_PATH $PACKAGE_DIR/usr/bin/$PACKAGE_NAME 54 | 55 | # Package 56 | opkg-build -o root -g root $PACKAGE_DIR 57 | 58 | # Cleanup 59 | rm -rf $PACKAGE_DIR 60 | -------------------------------------------------------------------------------- /packaging/vendor/multitech/conduit-ap3/package.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | REV="r1" 6 | 7 | PACKAGE_NAME="chirpstack-concentratord" 8 | PACKAGE_VERSION=`cargo metadata --no-deps --format-version 1 | jq -r '.packages[] | select(.name == "chirpstack-concentratord-sx1302").version'` 9 | PACKAGE_DESCRIPTION=`cargo metadata --no-deps --format-version 1 | jq -r '.packages[] | select(.name == "chirpstack-concentratord-sx1302").description'` 10 | BIN_PATH="../../../../target/armv7-unknown-linux-musleabihf/release/${PACKAGE_NAME}-sx1302" 11 | DIR=`dirname $0` 12 | PACKAGE_DIR="${DIR}/package" 13 | 14 | # Cleanup 15 | rm -rf $PACKAGE_DIR 16 | 17 | # CONTROL 18 | mkdir -p $PACKAGE_DIR/CONTROL 19 | cat > $PACKAGE_DIR/CONTROL/control << EOF 20 | Package: $PACKAGE_NAME 21 | Version: $PACKAGE_VERSION-$REV 22 | Architecture: mtcap3 23 | Maintainer: Orne Brocaar 24 | Priority: optional 25 | Section: network 26 | Source: N/A 27 | Description: $PACKAGE_DESCRIPTION 28 | EOF 29 | 30 | cat > $PACKAGE_DIR/CONTROL/postinst << EOF 31 | sed -i "s/ENABLED=.*/ENABLED=\"yes\"/" /etc/default/monit 32 | update-rc.d monit defaults 33 | /etc/init.d/monit start 34 | /usr/bin/monit reload 35 | EOF 36 | chmod 755 $PACKAGE_DIR/CONTROL/postinst 37 | 38 | cat > $PACKAGE_DIR/CONTROL/prerm << EOF 39 | /usr/bin/monit stop chirpstack-concentratord 40 | EOF 41 | chmod 755 $PACKAGE_DIR/CONTROL/prerm 42 | 43 | # This is empty, because the config files are copied on start. 44 | cat > $PACKAGE_DIR/CONTROL/conffiles << EOF 45 | EOF 46 | 47 | # Files 48 | mkdir -p $PACKAGE_DIR/opt/$PACKAGE_NAME 49 | mkdir -p $PACKAGE_DIR/var/config/$PACKAGE_NAME/examples 50 | mkdir -p $PACKAGE_DIR/etc/monit.d 51 | mkdir -p $PACKAGE_DIR/etc/init.d 52 | 53 | cp files/$PACKAGE_NAME.init $PACKAGE_DIR/etc/init.d/$PACKAGE_NAME 54 | cp files/$PACKAGE_NAME.monit $PACKAGE_DIR/etc/monit.d/$PACKAGE_NAME 55 | cp files/*.toml $PACKAGE_DIR/var/config/$PACKAGE_NAME/examples 56 | cp $BIN_PATH $PACKAGE_DIR/opt/$PACKAGE_NAME/$PACKAGE_NAME 57 | 58 | # Package 59 | opkg-build -o root -g root $PACKAGE_DIR 60 | 61 | # Cleanup 62 | rm -rf $PACKAGE_DIR 63 | -------------------------------------------------------------------------------- /packaging/vendor/multitech/conduit-ap/package.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | REV="r1" 6 | 7 | PACKAGE_NAME="chirpstack-concentratord" 8 | PACKAGE_VERSION=`cargo metadata --no-deps --format-version 1 | jq -r '.packages[] | select(.name == "chirpstack-concentratord-sx1301").version'` 9 | PACKAGE_DESCRIPTION=`cargo metadata --no-deps --format-version 1 | jq -r '.packages[] | select(.name == "chirpstack-concentratord-sx1301").description'` 10 | BIN_PATH="../../../../target/armv5te-unknown-linux-musleabi/release/${PACKAGE_NAME}-sx1301" 11 | DIR=`dirname $0` 12 | PACKAGE_DIR="${DIR}/package" 13 | 14 | # Cleanup 15 | rm -rf $PACKAGE_DIR 16 | 17 | # CONTROL 18 | mkdir -p $PACKAGE_DIR/CONTROL 19 | cat > $PACKAGE_DIR/CONTROL/control << EOF 20 | Package: $PACKAGE_NAME 21 | Version: $PACKAGE_VERSION-$REV 22 | Architecture: arm926ejste 23 | Maintainer: Orne Brocaar 24 | Priority: optional 25 | Section: network 26 | Source: N/A 27 | Description: $PACKAGE_DESCRIPTION 28 | EOF 29 | 30 | cat > $PACKAGE_DIR/CONTROL/postinst << EOF 31 | sed -i "s/ENABLED=.*/ENABLED=\"yes\"/" /etc/default/monit 32 | update-rc.d monit defaults 33 | /etc/init.d/monit start 34 | /usr/bin/monit reload 35 | EOF 36 | chmod 755 $PACKAGE_DIR/CONTROL/postinst 37 | 38 | cat > $PACKAGE_DIR/CONTROL/prerm << EOF 39 | /usr/bin/monit stop chirpstack-concentratord 40 | EOF 41 | chmod 755 $PACKAGE_DIR/CONTROL/prerm 42 | 43 | # This is empty, because the config files are copied on start. 44 | cat > $PACKAGE_DIR/CONTROL/conffiles << EOF 45 | EOF 46 | 47 | # Files 48 | mkdir -p $PACKAGE_DIR/opt/$PACKAGE_NAME 49 | mkdir -p $PACKAGE_DIR/var/config/$PACKAGE_NAME/examples 50 | mkdir -p $PACKAGE_DIR/etc/monit.d 51 | mkdir -p $PACKAGE_DIR/etc/init.d 52 | 53 | cp files/$PACKAGE_NAME.init $PACKAGE_DIR/etc/init.d/$PACKAGE_NAME 54 | cp files/$PACKAGE_NAME.monit $PACKAGE_DIR/etc/monit.d/$PACKAGE_NAME 55 | cp files/*.toml $PACKAGE_DIR/var/config/$PACKAGE_NAME/examples 56 | cp $BIN_PATH $PACKAGE_DIR/opt/$PACKAGE_NAME/$PACKAGE_NAME 57 | 58 | # Package 59 | opkg-build -o root -g root $PACKAGE_DIR 60 | 61 | # Cleanup 62 | rm -rf $PACKAGE_DIR 63 | -------------------------------------------------------------------------------- /libconcentratord/src/gpsd.rs: -------------------------------------------------------------------------------- 1 | use std::io::{BufRead, BufReader, BufWriter, Write}; 2 | use std::net::TcpStream; 3 | use std::time::Duration; 4 | 5 | use anyhow::Result; 6 | use log::{debug, info}; 7 | use serde::Deserialize; 8 | 9 | #[derive(Debug, Clone, Deserialize)] 10 | struct DevicesResponse { 11 | pub devices: Vec, 12 | } 13 | 14 | #[derive(Debug, Clone, Deserialize)] 15 | struct DevicesResponseDevice { 16 | pub path: String, 17 | pub driver: Option, 18 | } 19 | 20 | pub fn get_reader(server: &str) -> Result> { 21 | info!("Connecting to gpsd, server: {}", server); 22 | let stream = TcpStream::connect(server)?; 23 | stream.set_read_timeout(Some(Duration::from_secs(5)))?; 24 | 25 | let mut reader = BufReader::new(stream.try_clone()?); 26 | let mut writer = BufWriter::new(stream); 27 | 28 | // VERSION 29 | let mut b = Vec::new(); 30 | reader.read_until(b'\n', &mut b)?; 31 | debug!("Version response: {}", String::from_utf8(b.clone())?); 32 | 33 | // WATCH 34 | writer.write_all("?WATCH={\"enable\":true,\"nmea\":true,\"raw\":2};\r\n".as_bytes())?; 35 | writer.flush()?; 36 | 37 | // DEVICES 38 | let mut b = Vec::new(); 39 | reader.read_until(b'\n', &mut b)?; 40 | debug!("Devices response: {}", String::from_utf8(b.clone())?); 41 | let resp: DevicesResponse = serde_json::from_slice(&b)?; 42 | 43 | // WATCH 44 | let mut b = Vec::new(); 45 | reader.read_until(b'\n', &mut b)?; 46 | debug!("Watch response: {}", String::from_utf8(b.clone())?); 47 | 48 | for device in &resp.devices { 49 | if let Some(driver) = &device.driver 50 | && driver == "u-blox" { 51 | let config_str = format!("&{}=b5620601080001200001010000003294\r\n", device.path); 52 | debug!("Configuring uBlox device {} for NAV-TIMEGPS", device.path); 53 | writer.write_all(config_str.as_bytes())?; 54 | writer.flush()?; 55 | return Ok(reader); 56 | } 57 | } 58 | 59 | Err(anyhow!("No u-blox GNSS device found")) 60 | } 61 | -------------------------------------------------------------------------------- /libconcentratord/src/regulation/standard/etsi_en_300_220.rs: -------------------------------------------------------------------------------- 1 | use std::time::Duration; 2 | 3 | use super::{Band, Configuration}; 4 | 5 | pub fn new() -> Configuration { 6 | Configuration { 7 | regulation: chirpstack_api::common::Regulation::EtsiEn300220, 8 | bands: vec![ 9 | Band { 10 | label: "K".into(), 11 | frequency_min: 863000000, 12 | frequency_max: 865000000, 13 | duty_cycle_permille_max: 1, 14 | tx_power_max_eirp: 14 + 2, 15 | }, 16 | Band { 17 | label: "L".into(), 18 | frequency_min: 865000000, 19 | frequency_max: 868000000, 20 | duty_cycle_permille_max: 10, 21 | tx_power_max_eirp: 14 + 2, 22 | }, 23 | Band { 24 | label: "M".into(), 25 | frequency_min: 868000000, 26 | frequency_max: 868600000, 27 | duty_cycle_permille_max: 10, 28 | tx_power_max_eirp: 14 + 2, 29 | }, 30 | Band { 31 | label: "N".into(), 32 | frequency_min: 868700000, 33 | frequency_max: 869200000, 34 | duty_cycle_permille_max: 1, 35 | tx_power_max_eirp: 14 + 2, 36 | }, 37 | Band { 38 | label: "P".into(), 39 | frequency_min: 869400000, 40 | frequency_max: 869650000, 41 | duty_cycle_permille_max: 100, 42 | tx_power_max_eirp: 27 + 2, 43 | }, 44 | Band { 45 | label: "P".into(), 46 | frequency_min: 869700000, 47 | frequency_max: 870000000, 48 | duty_cycle_permille_max: 1000, 49 | tx_power_max_eirp: 7 + 2, 50 | }, 51 | Band { 52 | label: "Q".into(), 53 | frequency_min: 869700000, 54 | frequency_max: 870000000, 55 | duty_cycle_permille_max: 10, 56 | tx_power_max_eirp: 14 + 2, 57 | }, 58 | ], 59 | window_time: Duration::from_secs(60 * 60), 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /cross/Dockerfile.aarch64-unknown-linux-musl: -------------------------------------------------------------------------------- 1 | FROM ghcr.io/cross-rs/aarch64-unknown-linux-musl:main 2 | 3 | ENV SX1301_VERSION=v5.0.1r4 4 | ENV SX1302_VERSION=V2.1.0r9 5 | ENV SX2G4_VERSION=V1.1.0 6 | 7 | ENV HAL_ARCH=arm 8 | ENV MUSL_PREFIX=aarch64-linux-musl 9 | 10 | RUN apt-get update && \ 11 | apt-get --assume-yes install \ 12 | protobuf-compiler \ 13 | libprotobuf-dev \ 14 | git 15 | 16 | RUN mkdir /hal 17 | 18 | # Needed for RAK shields, works with other shields too 19 | # sed -i 's/define SPI_SPEED.*/define SPI_SPEED 2000000/g' /hal/lora_gateway/libloragw/src/loragw_spi.native.c 20 | 21 | RUN echo "Building sx1301 HAL" && \ 22 | cd /hal && \ 23 | git clone https://github.com/brocaar/lora_gateway.git -b $SX1301_VERSION && \ 24 | cd /hal/lora_gateway && \ 25 | ARCH=$ARCH CROSS_COMPILE=$MUSL_PREFIX- make && \ 26 | ln -s /hal/lora_gateway/libloragw/inc /usr/local/$MUSL_PREFIX/include/libloragw-sx1301 && \ 27 | ln -s /hal/lora_gateway/libloragw/libloragw.a /usr/local/$MUSL_PREFIX/lib/libloragw-sx1301.a 28 | 29 | RUN echo "Building sx1302 HAL" && \ 30 | cd /hal && \ 31 | git clone https://github.com/brocaar/sx1302_hal.git -b $SX1302_VERSION && \ 32 | cd /hal/sx1302_hal && \ 33 | ARCH=$ARCH CROSS_COMPILE=$MUSL_PREFIX- make libloragw && \ 34 | ln -s /hal/sx1302_hal/libloragw/inc /usr/local/$MUSL_PREFIX/include/libloragw-sx1302 && \ 35 | ln -s /hal/sx1302_hal/libloragw/libloragw.a /usr/local/$MUSL_PREFIX/lib/libloragw-sx1302.a && \ 36 | cp /hal/sx1302_hal/libtools/inc/* /usr/local/$MUSL_PREFIX/include && \ 37 | cp /hal/sx1302_hal/libtools/*.a /usr/local/$MUSL_PREFIX/lib 38 | 39 | RUN echo "Building 2g4 HAL" && \ 40 | cd /hal && \ 41 | git clone https://github.com/Lora-net/gateway_2g4_hal.git -b $SX2G4_VERSION && \ 42 | cd /hal/gateway_2g4_hal && \ 43 | ARCH=$ARCH CROSS_COMPILE=$MUSL_PREFIX- make libloragw && \ 44 | ln -s /hal/gateway_2g4_hal/libloragw/inc /usr/local/$MUSL_PREFIX/include/libloragw-2g4 && \ 45 | ln -s /hal/gateway_2g4_hal/libloragw/libloragw.a /usr/local/$MUSL_PREFIX/lib/libloragw-2g4.a 46 | 47 | RUN echo "Copy libstdc++" && \ 48 | mkdir -p /usr/local/$MUSL_PREFIX-target/lib && \ 49 | cp /usr/local/$MUSL_PREFIX/lib/libstdc++* /usr/local/$MUSL_PREFIX-target/lib 50 | -------------------------------------------------------------------------------- /cross/Dockerfile.armv5te-unknown-linux-musleabi: -------------------------------------------------------------------------------- 1 | FROM ghcr.io/cross-rs/armv5te-unknown-linux-musleabi:main 2 | 3 | ENV SX1301_VERSION=v5.0.1r4 4 | ENV SX1302_VERSION=V2.1.0r9 5 | ENV SX2G4_VERSION=V1.1.0 6 | 7 | ENV HAL_ARCH=arm 8 | ENV MUSL_PREFIX=arm-linux-musleabi 9 | 10 | RUN apt-get update && \ 11 | apt-get --assume-yes install \ 12 | protobuf-compiler \ 13 | libprotobuf-dev \ 14 | git 15 | 16 | RUN mkdir /hal 17 | 18 | # Needed for RAK shields, works with other shields too 19 | # sed -i 's/define SPI_SPEED.*/define SPI_SPEED 2000000/g' /hal/lora_gateway/libloragw/src/loragw_spi.native.c 20 | 21 | RUN echo "Building sx1301 HAL" && \ 22 | cd /hal && \ 23 | git clone https://github.com/brocaar/lora_gateway.git -b $SX1301_VERSION && \ 24 | cd /hal/lora_gateway && \ 25 | ARCH=$ARCH CROSS_COMPILE=$MUSL_PREFIX- make && \ 26 | ln -s /hal/lora_gateway/libloragw/inc /usr/local/$MUSL_PREFIX/include/libloragw-sx1301 && \ 27 | ln -s /hal/lora_gateway/libloragw/libloragw.a /usr/local/$MUSL_PREFIX/lib/libloragw-sx1301.a 28 | 29 | RUN echo "Building sx1302 HAL" && \ 30 | cd /hal && \ 31 | git clone https://github.com/brocaar/sx1302_hal.git -b $SX1302_VERSION && \ 32 | cd /hal/sx1302_hal && \ 33 | ARCH=$ARCH CROSS_COMPILE=$MUSL_PREFIX- make libloragw && \ 34 | ln -s /hal/sx1302_hal/libloragw/inc /usr/local/$MUSL_PREFIX/include/libloragw-sx1302 && \ 35 | ln -s /hal/sx1302_hal/libloragw/libloragw.a /usr/local/$MUSL_PREFIX/lib/libloragw-sx1302.a && \ 36 | cp /hal/sx1302_hal/libtools/inc/* /usr/local/$MUSL_PREFIX/include && \ 37 | cp /hal/sx1302_hal/libtools/*.a /usr/local/$MUSL_PREFIX/lib 38 | 39 | RUN echo "Building 2g4 HAL" && \ 40 | cd /hal && \ 41 | git clone https://github.com/Lora-net/gateway_2g4_hal.git -b $SX2G4_VERSION && \ 42 | cd /hal/gateway_2g4_hal && \ 43 | ARCH=$ARCH CROSS_COMPILE=$MUSL_PREFIX- make libloragw && \ 44 | ln -s /hal/gateway_2g4_hal/libloragw/inc /usr/local/$MUSL_PREFIX/include/libloragw-2g4 && \ 45 | ln -s /hal/gateway_2g4_hal/libloragw/libloragw.a /usr/local/$MUSL_PREFIX/lib/libloragw-2g4.a 46 | 47 | RUN echo "Copy libstdc++" && \ 48 | mkdir -p /usr/local/$MUSL_PREFIX-target/lib && \ 49 | cp /usr/local/$MUSL_PREFIX/lib/libstdc++* /usr/local/$MUSL_PREFIX-target/lib 50 | -------------------------------------------------------------------------------- /cross/Dockerfile.armv7-unknown-linux-musleabihf: -------------------------------------------------------------------------------- 1 | FROM ghcr.io/cross-rs/armv7-unknown-linux-musleabihf:main 2 | 3 | ENV SX1301_VERSION=v5.0.1r4 4 | ENV SX1302_VERSION=V2.1.0r9 5 | ENV SX2G4_VERSION=V1.1.0 6 | 7 | ENV HAL_ARCH=arm 8 | ENV MUSL_PREFIX=arm-linux-musleabihf 9 | 10 | RUN apt-get update && \ 11 | apt-get --assume-yes install \ 12 | protobuf-compiler \ 13 | libprotobuf-dev \ 14 | git 15 | 16 | RUN mkdir /hal 17 | 18 | # Needed for RAK shields, works with other shields too 19 | # sed -i 's/define SPI_SPEED.*/define SPI_SPEED 2000000/g' /hal/lora_gateway/libloragw/src/loragw_spi.native.c 20 | 21 | RUN echo "Building sx1301 HAL" && \ 22 | cd /hal && \ 23 | git clone https://github.com/brocaar/lora_gateway.git -b $SX1301_VERSION && \ 24 | cd /hal/lora_gateway && \ 25 | ARCH=$ARCH CROSS_COMPILE=$MUSL_PREFIX- make && \ 26 | ln -s /hal/lora_gateway/libloragw/inc /usr/local/$MUSL_PREFIX/include/libloragw-sx1301 && \ 27 | ln -s /hal/lora_gateway/libloragw/libloragw.a /usr/local/$MUSL_PREFIX/lib/libloragw-sx1301.a 28 | 29 | RUN echo "Building sx1302 HAL" && \ 30 | cd /hal && \ 31 | git clone https://github.com/brocaar/sx1302_hal.git -b $SX1302_VERSION && \ 32 | cd /hal/sx1302_hal && \ 33 | ARCH=$ARCH CROSS_COMPILE=$MUSL_PREFIX- make libloragw && \ 34 | ln -s /hal/sx1302_hal/libloragw/inc /usr/local/$MUSL_PREFIX/include/libloragw-sx1302 && \ 35 | ln -s /hal/sx1302_hal/libloragw/libloragw.a /usr/local/$MUSL_PREFIX/lib/libloragw-sx1302.a && \ 36 | cp /hal/sx1302_hal/libtools/inc/* /usr/local/$MUSL_PREFIX/include && \ 37 | cp /hal/sx1302_hal/libtools/*.a /usr/local/$MUSL_PREFIX/lib 38 | 39 | RUN echo "Building 2g4 HAL" && \ 40 | cd /hal && \ 41 | git clone https://github.com/Lora-net/gateway_2g4_hal.git -b $SX2G4_VERSION && \ 42 | cd /hal/gateway_2g4_hal && \ 43 | ARCH=$ARCH CROSS_COMPILE=$MUSL_PREFIX- make libloragw && \ 44 | ln -s /hal/gateway_2g4_hal/libloragw/inc /usr/local/$MUSL_PREFIX/include/libloragw-2g4 && \ 45 | ln -s /hal/gateway_2g4_hal/libloragw/libloragw.a /usr/local/$MUSL_PREFIX/lib/libloragw-2g4.a 46 | 47 | RUN echo "Copy libstdc++" && \ 48 | mkdir -p /usr/local/$MUSL_PREFIX-target/lib && \ 49 | cp /usr/local/$MUSL_PREFIX/lib/libstdc++* /usr/local/$MUSL_PREFIX-target/lib 50 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ChirpStack Concentratord 2 | 3 | ![Tests](https://github.com/brocaar/chirpstack-concentratord/actions/workflows/main.yml/badge.svg?branch=master) 4 | 5 | ChirpStack Concentratord is an open-source LoRa(WAN) concentrator daemon, part 6 | of the [ChirpStack](https://www.chirpstack.io/) project. It exposes a [ZeroMQ](https://zeromq.org/) 7 | based API that can be used by one or multiple applications to interact with 8 | gateway hardware. By implementing and abstracting the the hardware specifics 9 | in a separate daemon and exposing this over a ZeroMQ based API, the packet 10 | forwarding application can be completely decoupled from the gateway hardware. 11 | It also allows for running multiple packet forwarding applications simultaniously. 12 | 13 | ## Documentation and binaries 14 | 15 | Please refer to the [ChirpStack](https://www.chirpstack.io/) website for 16 | documentation and pre-compiled binaries. 17 | 18 | ## Building from source 19 | 20 | ### Requirements 21 | 22 | Building ChirpStack Concentratord requires: 23 | 24 | * [Nix](https://nixos.org/download.html) (recommended) and 25 | * [Docker](https://www.docker.com/) 26 | 27 | #### Nix 28 | 29 | Nix is used for setting up the development environment which is used for local 30 | development and for creating the binaries. 31 | 32 | If you do not have Nix installed and do not wish to install it, you could 33 | install the packages listed in `shell.nix` by hand, using your package-manager of 34 | choice. 35 | 36 | #### Docker 37 | 38 | Docker is used by [cross-rs](https://github.com/cross-rs/cross) for cross-compiling. 39 | 40 | ### Starting the development shell 41 | 42 | Run the following command to start the development shell: 43 | 44 | ```bash 45 | nix-shell 46 | ``` 47 | 48 | ### Running tests 49 | 50 | Execute the following command to run the tests: 51 | 52 | ```bash 53 | make test 54 | ``` 55 | 56 | ### Building binaries 57 | 58 | Execute the following commands to build the ChirpStack Concentratord binaries 59 | and packages: 60 | 61 | ```bash 62 | # Only build binaries 63 | make build 64 | 65 | # Build binaries + distributable packages. 66 | make dist 67 | ``` 68 | 69 | ## License 70 | 71 | ChirpStack Concentratord is distributed under the MIT license. See 72 | [LICENSE](https://github.com/brocaar/chirpstack-concentratord/blob/master/LICENSE). 73 | -------------------------------------------------------------------------------- /packaging/vendor/multitech/conduit/package-2g4.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | REV="r1" 6 | 7 | PACKAGE_NAME="chirpstack-concentratord-2g4" 8 | PACKAGE_VERSION=`cargo metadata --no-deps --format-version 1 | jq -r '.packages[] | select(.name == "chirpstack-concentratord-2g4").version'` 9 | PACKAGE_DESCRIPTION=`cargo metadata --no-deps --format-version 1 | jq -r '.packages[] | select(.name == "chirpstack-concentratord-2g4").description'` 10 | BIN_PATH="../../../../target/armv5te-unknown-linux-musleabi/release/${PACKAGE_NAME}" 11 | DIR=`dirname $0` 12 | PACKAGE_DIR="${DIR}/package-2g4" 13 | 14 | # Cleanup 15 | rm -rf $PACKAGE_DIR 16 | 17 | # CONTROL 18 | mkdir -p $PACKAGE_DIR/CONTROL 19 | cat > $PACKAGE_DIR/CONTROL/control << EOF 20 | Package: $PACKAGE_NAME 21 | Version: $PACKAGE_VERSION-$REV 22 | Architecture: arm926ejste 23 | Maintainer: Orne Brocaar 24 | Priority: optional 25 | Section: network 26 | Source: N/A 27 | Description: $PACKAGE_DESCRIPTION 28 | EOF 29 | 30 | cat > $PACKAGE_DIR/CONTROL/postinst << EOF 31 | sed -i "s/ENABLED=.*/ENABLED=\"yes\"/" /etc/default/monit 32 | update-rc.d monit defaults 33 | /etc/init.d/monit start 34 | /usr/bin/monit reload 35 | EOF 36 | chmod 755 $PACKAGE_DIR/CONTROL/postinst 37 | 38 | cat > $PACKAGE_DIR/CONTROL/prerm << EOF 39 | /etc/init.d/$PACKAGE_NAME-ap1 stop 40 | /etc/init.d/$PACKAGE_NAME-ap2 stop 41 | EOF 42 | chmod 755 $PACKAGE_DIR/CONTROL/prerm 43 | 44 | # This is empty, because the config files are copied on start. 45 | cat > $PACKAGE_DIR/CONTROL/conffiles << EOF 46 | EOF 47 | 48 | # Files 49 | mkdir -p $PACKAGE_DIR/opt/$PACKAGE_NAME 50 | mkdir -p $PACKAGE_DIR/var/config/$PACKAGE_NAME/examples 51 | mkdir -p $PACKAGE_DIR/etc/monit.d 52 | mkdir -p $PACKAGE_DIR/etc/init.d 53 | 54 | cp files/2g4/$PACKAGE_NAME-ap1.init $PACKAGE_DIR/etc/init.d/$PACKAGE_NAME-ap1 55 | cp files/2g4/$PACKAGE_NAME-ap2.init $PACKAGE_DIR/etc/init.d/$PACKAGE_NAME-ap2 56 | 57 | cp files/2g4/$PACKAGE_NAME-ap1.monit $PACKAGE_DIR/var/config/$PACKAGE_NAME/examples 58 | cp files/2g4/$PACKAGE_NAME-ap2.monit $PACKAGE_DIR/var/config/$PACKAGE_NAME/examples 59 | 60 | cp files/2g4/*.toml $PACKAGE_DIR/var/config/$PACKAGE_NAME/examples/ 61 | cp $BIN_PATH $PACKAGE_DIR/opt/$PACKAGE_NAME/$PACKAGE_NAME 62 | 63 | # Package 64 | opkg-build -o root -g root $PACKAGE_DIR 65 | 66 | # Cleanup 67 | rm -rf $PACKAGE_DIR 68 | -------------------------------------------------------------------------------- /chirpstack-concentratord-2g4/src/handler/jit.rs: -------------------------------------------------------------------------------- 1 | use std::sync::mpsc::Receiver; 2 | use std::sync::{Arc, Mutex}; 3 | use std::time::Duration; 4 | 5 | use anyhow::Result; 6 | 7 | use libconcentratord::jitqueue::TxPacket; 8 | use libconcentratord::signals::Signal; 9 | use libconcentratord::{jitqueue, stats}; 10 | use libloragw_2g4::hal; 11 | 12 | use super::super::wrapper; 13 | 14 | pub fn jit_loop( 15 | queue: Arc>>, 16 | antenna_gain_dbi: i8, 17 | stop_receive: Receiver, 18 | ) -> Result<()> { 19 | debug!("Start JIT queue loop"); 20 | 21 | loop { 22 | // Instead of a 10ms sleep, we receive from the stop channel with a 23 | // timeout of 10ms. 24 | if let Ok(v) = stop_receive.recv_timeout(Duration::from_millis(10)) { 25 | debug!("Received stop signal, signal: {}", v); 26 | return Ok(()); 27 | } 28 | 29 | let tx_packet = match get_tx_packet(&queue)? { 30 | Some(v) => v, 31 | None => continue, 32 | }; 33 | 34 | let downlink_id = tx_packet.get_id(); 35 | let mut tx_packet = tx_packet.tx_packet(); 36 | tx_packet.rf_power -= antenna_gain_dbi; 37 | 38 | match hal::send(&tx_packet) { 39 | Ok(_) => { 40 | info!("Scheduled packet for TX, downlink_id: {}, count_us: {}, freq: {}, bw: {}, mod: {:?}, dr: {:?}", 41 | downlink_id, 42 | tx_packet.count_us, 43 | tx_packet.freq_hz, 44 | tx_packet.bandwidth, 45 | hal::Modulation::LoRa, 46 | tx_packet.datarate 47 | ); 48 | 49 | if let Ok(tx_info) = wrapper::downlink_to_tx_info_proto(&tx_packet) { 50 | stats::inc_tx_counts(&tx_info); 51 | } 52 | } 53 | Err(err) => { 54 | error!("Schedule packet for tx error, error: {}", err); 55 | } 56 | } 57 | } 58 | } 59 | 60 | fn get_tx_packet( 61 | queue: &Arc>>, 62 | ) -> Result> { 63 | let mut queue = queue.lock().map_err(|_| anyhow!("Lock queue error"))?; 64 | let concentrator_count = hal::get_instcnt()?; 65 | Ok(queue.pop(concentrator_count)) 66 | } 67 | -------------------------------------------------------------------------------- /packaging/vendor/multitech/conduit/package-sx1301.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | REV="r1" 6 | 7 | PACKAGE_NAME="chirpstack-concentratord-sx1301" 8 | PACKAGE_VERSION=`cargo metadata --no-deps --format-version 1 | jq -r '.packages[] | select(.name == "chirpstack-concentratord-sx1301").version'` 9 | PACKAGE_DESCRIPTION=`cargo metadata --no-deps --format-version 1 | jq -r '.packages[] | select(.name == "chirpstack-concentratord-sx1301").description'` 10 | BIN_PATH="../../../../target/armv5te-unknown-linux-musleabi/release/${PACKAGE_NAME}" 11 | DIR=`dirname $0` 12 | PACKAGE_DIR="${DIR}/package-sx1301" 13 | 14 | # Cleanup 15 | rm -rf $PACKAGE_DIR 16 | 17 | # CONTROL 18 | mkdir -p $PACKAGE_DIR/CONTROL 19 | cat > $PACKAGE_DIR/CONTROL/control << EOF 20 | Package: $PACKAGE_NAME 21 | Version: $PACKAGE_VERSION-$REV 22 | Architecture: arm926ejste 23 | Maintainer: Orne Brocaar 24 | Priority: optional 25 | Section: network 26 | Source: N/A 27 | Description: $PACKAGE_DESCRIPTION 28 | EOF 29 | 30 | cat > $PACKAGE_DIR/CONTROL/postinst << EOF 31 | sed -i "s/ENABLED=.*/ENABLED=\"yes\"/" /etc/default/monit 32 | update-rc.d monit defaults 33 | /etc/init.d/monit start 34 | /usr/bin/monit reload 35 | EOF 36 | chmod 755 $PACKAGE_DIR/CONTROL/postinst 37 | 38 | cat > $PACKAGE_DIR/CONTROL/prerm << EOF 39 | /etc/init.d/$PACKAGE_NAME-ap1 stop 40 | /etc/init.d/$PACKAGE_NAME-ap2 stop 41 | EOF 42 | chmod 755 $PACKAGE_DIR/CONTROL/prerm 43 | 44 | # This is empty, because the config files are copied on start. 45 | cat > $PACKAGE_DIR/CONTROL/conffiles << EOF 46 | EOF 47 | 48 | # Files 49 | mkdir -p $PACKAGE_DIR/opt/$PACKAGE_NAME 50 | mkdir -p $PACKAGE_DIR/var/config/$PACKAGE_NAME/examples 51 | mkdir -p $PACKAGE_DIR/etc/monit.d 52 | mkdir -p $PACKAGE_DIR/etc/init.d 53 | 54 | cp files/sx1301/$PACKAGE_NAME-ap1.init $PACKAGE_DIR/etc/init.d/$PACKAGE_NAME-ap1 55 | cp files/sx1301/$PACKAGE_NAME-ap2.init $PACKAGE_DIR/etc/init.d/$PACKAGE_NAME-ap2 56 | 57 | cp files/sx1301/$PACKAGE_NAME-ap1.monit $PACKAGE_DIR/var/config/$PACKAGE_NAME/examples 58 | cp files/sx1301/$PACKAGE_NAME-ap2.monit $PACKAGE_DIR/var/config/$PACKAGE_NAME/examples 59 | 60 | cp files/sx1301/*.toml $PACKAGE_DIR/var/config/$PACKAGE_NAME/examples 61 | cp $BIN_PATH $PACKAGE_DIR/opt/$PACKAGE_NAME/$PACKAGE_NAME 62 | 63 | # Package 64 | opkg-build -o root -g root $PACKAGE_DIR 65 | 66 | # Cleanup 67 | rm -rf $PACKAGE_DIR 68 | -------------------------------------------------------------------------------- /packaging/vendor/multitech/conduit/package-sx1302.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | REV="r1" 6 | 7 | PACKAGE_NAME="chirpstack-concentratord-sx1302" 8 | PACKAGE_VERSION=`cargo metadata --no-deps --format-version 1 | jq -r '.packages[] | select(.name == "chirpstack-concentratord-sx1302").version'` 9 | PACKAGE_DESCRIPTION=`cargo metadata --no-deps --format-version 1 | jq -r '.packages[] | select(.name == "chirpstack-concentratord-sx1302").description'` 10 | BIN_PATH="../../../../target/armv5te-unknown-linux-musleabi/release/${PACKAGE_NAME}" 11 | DIR=`dirname $0` 12 | PACKAGE_DIR="${DIR}/package-sx1302" 13 | 14 | # Cleanup 15 | rm -rf $PACKAGE_DIR 16 | 17 | # CONTROL 18 | mkdir -p $PACKAGE_DIR/CONTROL 19 | cat > $PACKAGE_DIR/CONTROL/control << EOF 20 | Package: $PACKAGE_NAME 21 | Version: $PACKAGE_VERSION-$REV 22 | Architecture: arm926ejste 23 | Maintainer: Orne Brocaar 24 | Priority: optional 25 | Section: network 26 | Source: N/A 27 | Description: $PACKAGE_DESCRIPTION 28 | EOF 29 | 30 | cat > $PACKAGE_DIR/CONTROL/postinst << EOF 31 | sed -i "s/ENABLED=.*/ENABLED=\"yes\"/" /etc/default/monit 32 | update-rc.d monit defaults 33 | /etc/init.d/monit start 34 | /usr/bin/monit reload 35 | EOF 36 | chmod 755 $PACKAGE_DIR/CONTROL/postinst 37 | 38 | cat > $PACKAGE_DIR/CONTROL/prerm << EOF 39 | /etc/init.d/$PACKAGE_NAME-ap1 stop 40 | /etc/init.d/$PACKAGE_NAME-ap2 stop 41 | EOF 42 | chmod 755 $PACKAGE_DIR/CONTROL/prerm 43 | 44 | # This is empty, because the config files are copied on start. 45 | cat > $PACKAGE_DIR/CONTROL/conffiles << EOF 46 | EOF 47 | 48 | # Files 49 | mkdir -p $PACKAGE_DIR/opt/$PACKAGE_NAME 50 | mkdir -p $PACKAGE_DIR/var/config/$PACKAGE_NAME/examples 51 | mkdir -p $PACKAGE_DIR/etc/monit.d 52 | mkdir -p $PACKAGE_DIR/etc/init.d 53 | 54 | cp files/sx1302/$PACKAGE_NAME-ap1.init $PACKAGE_DIR/etc/init.d/$PACKAGE_NAME-ap1 55 | cp files/sx1302/$PACKAGE_NAME-ap2.init $PACKAGE_DIR/etc/init.d/$PACKAGE_NAME-ap2 56 | 57 | cp files/sx1302/$PACKAGE_NAME-ap1.monit $PACKAGE_DIR/var/config/$PACKAGE_NAME/examples 58 | cp files/sx1302/$PACKAGE_NAME-ap2.monit $PACKAGE_DIR/var/config/$PACKAGE_NAME/examples 59 | 60 | cp files/sx1302/*.toml $PACKAGE_DIR/var/config/$PACKAGE_NAME/examples 61 | cp $BIN_PATH $PACKAGE_DIR/opt/$PACKAGE_NAME/$PACKAGE_NAME 62 | 63 | # Package 64 | opkg-build -o root -g root $PACKAGE_DIR 65 | 66 | # Cleanup 67 | rm -rf $PACKAGE_DIR 68 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1302/src/handler/jit.rs: -------------------------------------------------------------------------------- 1 | use std::sync::mpsc::Receiver; 2 | use std::sync::{Arc, Mutex}; 3 | use std::time::Duration; 4 | 5 | use anyhow::Result; 6 | 7 | use libconcentratord::jitqueue::TxPacket; 8 | use libconcentratord::signals::Signal; 9 | use libconcentratord::{jitqueue, stats}; 10 | use libloragw_sx1302::hal; 11 | 12 | use super::super::wrapper; 13 | 14 | pub fn jit_loop( 15 | queue: Arc>>, 16 | antenna_gain_dbi: i8, 17 | stop_receive: Receiver, 18 | ) -> Result<()> { 19 | debug!("Starting JIT queue loop"); 20 | 21 | loop { 22 | // Instead of a 10ms sleep, we receive from the stop channel with a 23 | // timeout of 10ms. 24 | if let Ok(v) = stop_receive.recv_timeout(Duration::from_millis(10)) { 25 | debug!("Received stop signal, signal: {}", v); 26 | return Ok(()); 27 | } 28 | 29 | let tx_packet = match get_tx_packet(&queue)? { 30 | Some(v) => v, 31 | None => continue, 32 | }; 33 | 34 | let downlink_id = tx_packet.get_id(); 35 | let mut tx_packet = tx_packet.tx_packet(); 36 | tx_packet.rf_power -= antenna_gain_dbi; 37 | 38 | match hal::send(&tx_packet) { 39 | Ok(_) => { 40 | info!( 41 | "Scheduled packet for TX, downlink_id: {}, count_us: {}, freq: {}, bw: {}, mod: {:?}, dr: {:?}", 42 | downlink_id, 43 | tx_packet.count_us, 44 | tx_packet.freq_hz, 45 | tx_packet.bandwidth, 46 | tx_packet.modulation, 47 | tx_packet.datarate 48 | ); 49 | 50 | if let Ok(tx_info) = wrapper::downlink_to_tx_info_proto(&tx_packet) { 51 | stats::inc_tx_counts(&tx_info); 52 | } 53 | } 54 | Err(err) => { 55 | error!("Schedule packet for tx error, error: {}", err); 56 | } 57 | } 58 | } 59 | } 60 | 61 | fn get_tx_packet( 62 | queue: &Arc>>, 63 | ) -> Result> { 64 | let mut queue = queue.lock().map_err(|_| anyhow!("Lock queue error"))?; 65 | let concentrator_count = hal::get_instcnt()?; 66 | Ok(queue.pop(concentrator_count)) 67 | } 68 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1301/src/handler/jit.rs: -------------------------------------------------------------------------------- 1 | use std::sync::mpsc::Receiver; 2 | use std::sync::{Arc, Mutex}; 3 | use std::time::Duration; 4 | 5 | use anyhow::Result; 6 | 7 | use libconcentratord::jitqueue::TxPacket; 8 | use libconcentratord::signals::Signal; 9 | use libconcentratord::{jitqueue, stats}; 10 | use libloragw_sx1301::hal; 11 | 12 | use super::super::wrapper; 13 | use super::timersync; 14 | 15 | pub fn jit_loop( 16 | queue: Arc>>, 17 | antenna_gain_dbi: i8, 18 | stop_receive: Receiver, 19 | ) -> Result<()> { 20 | debug!("Starting JIT queue loop"); 21 | 22 | loop { 23 | // Instead of a 10ms sleep, we receive from the stop channel with a 24 | // timeout of 10ms. 25 | if let Ok(v) = stop_receive.recv_timeout(Duration::from_millis(10)) { 26 | debug!("Received stop signal, signal: {}", v); 27 | return Ok(()); 28 | } 29 | 30 | let tx_packet = match get_tx_packet(&queue)? { 31 | Some(v) => v, 32 | None => continue, 33 | }; 34 | 35 | let downlink_id = tx_packet.get_id(); 36 | let mut tx_packet = tx_packet.tx_packet(); 37 | tx_packet.rf_power -= antenna_gain_dbi; 38 | 39 | match hal::send(&tx_packet) { 40 | Ok(_) => { 41 | info!( 42 | "Scheduled packet for TX, downlink_id: {}, count_us: {}, freq: {}, bw: {}, mod: {:?}, dr: {:?}", 43 | downlink_id, 44 | tx_packet.count_us, 45 | tx_packet.freq_hz, 46 | tx_packet.bandwidth, 47 | tx_packet.modulation, 48 | tx_packet.datarate 49 | ); 50 | 51 | if let Ok(tx_info) = wrapper::downlink_to_tx_info_proto(&tx_packet) { 52 | stats::inc_tx_counts(&tx_info); 53 | } 54 | } 55 | Err(err) => { 56 | error!("Schedule packet for tx error, error: {}", err); 57 | } 58 | } 59 | } 60 | } 61 | 62 | fn get_tx_packet( 63 | queue: &Arc>>, 64 | ) -> Result> { 65 | let mut queue = queue.lock().map_err(|_| anyhow!("Lock queue error"))?; 66 | let concentrator_count = timersync::get_concentrator_count(); 67 | Ok(queue.pop(concentrator_count)) 68 | } 69 | -------------------------------------------------------------------------------- /cross/Dockerfile.x86_64-unknown-linux-musl: -------------------------------------------------------------------------------- 1 | FROM ghcr.io/cross-rs/x86_64-unknown-linux-musl:main 2 | 3 | ENV SX1301_VERSION=v5.0.1r4 4 | ENV SX1302_VERSION=V2.1.0r9 5 | ENV SX2G4_VERSION=V1.1.0 6 | 7 | ENV HAL_ARCH= 8 | ENV MUSL_PREFIX=x86_64-linux-musl 9 | 10 | RUN apt-get update && \ 11 | apt-get --assume-yes install \ 12 | protobuf-compiler \ 13 | libprotobuf-dev \ 14 | git 15 | 16 | RUN mkdir /hal 17 | 18 | # Needed for RAK shields, works with other shields too 19 | # sed -i 's/define SPI_SPEED.*/define SPI_SPEED 2000000/g' /hal/lora_gateway/libloragw/src/loragw_spi.native.c 20 | 21 | RUN echo "Building sx1301 HAL" && \ 22 | cd /hal && \ 23 | git clone https://github.com/brocaar/lora_gateway.git -b $SX1301_VERSION && \ 24 | cd /hal/lora_gateway && \ 25 | sed -i "s/CFLAGS\(.*\)/CFLAGS\1\ -fPIE/" libloragw/Makefile && \ 26 | ARCH=$ARCH CROSS_COMPILE=$MUSL_PREFIX- make && \ 27 | ln -s /hal/lora_gateway/libloragw/inc /usr/local/$MUSL_PREFIX/include/libloragw-sx1301 && \ 28 | ln -s /hal/lora_gateway/libloragw/libloragw.a /usr/local/$MUSL_PREFIX/lib/libloragw-sx1301.a 29 | 30 | RUN echo "Building sx1302 HAL" && \ 31 | cd /hal && \ 32 | git clone https://github.com/brocaar/sx1302_hal.git -b $SX1302_VERSION && \ 33 | cd /hal/sx1302_hal && \ 34 | sed -i "s/CFLAGS\(.*\)/CFLAGS\1\ -fPIE/" libloragw/Makefile && \ 35 | ARCH=$ARCH CROSS_COMPILE=$MUSL_PREFIX- make libloragw && \ 36 | ln -s /hal/sx1302_hal/libloragw/inc /usr/local/$MUSL_PREFIX/include/libloragw-sx1302 && \ 37 | ln -s /hal/sx1302_hal/libloragw/libloragw.a /usr/local/$MUSL_PREFIX/lib/libloragw-sx1302.a && \ 38 | cp /hal/sx1302_hal/libtools/inc/* /usr/local/$MUSL_PREFIX/include && \ 39 | cp /hal/sx1302_hal/libtools/*.a /usr/local/$MUSL_PREFIX/lib 40 | 41 | RUN echo "Building 2g4 HAL" && \ 42 | cd /hal && \ 43 | git clone https://github.com/Lora-net/gateway_2g4_hal.git -b $SX2G4_VERSION && \ 44 | cd /hal/gateway_2g4_hal && \ 45 | sed -i "s/CFLAGS\(.*\)/CFLAGS\1\ -fPIE/" libloragw/Makefile && \ 46 | ARCH=$ARCH CROSS_COMPILE=$MUSL_PREFIX- make libloragw && \ 47 | ln -s /hal/gateway_2g4_hal/libloragw/inc /usr/local/$MUSL_PREFIX/include/libloragw-2g4 && \ 48 | ln -s /hal/gateway_2g4_hal/libloragw/libloragw.a /usr/local/$MUSL_PREFIX/lib/libloragw-2g4.a 49 | 50 | RUN echo "Copy libstdc++" && \ 51 | mkdir -p /usr/local/$MUSL_PREFIX-target/lib && \ 52 | cp /usr/local/$MUSL_PREFIX/lib/libstdc++* /usr/local/$MUSL_PREFIX-target/lib 53 | -------------------------------------------------------------------------------- /chirpstack-concentratord-2g4/src/concentrator.rs: -------------------------------------------------------------------------------- 1 | use anyhow::Result; 2 | use libloragw_2g4::hal; 3 | 4 | use super::config::Configuration; 5 | 6 | pub fn board_setconf(config: &Configuration) -> Result<()> { 7 | let board_config = hal::BoardConfig { 8 | tty_path: config.gateway.model_config.tty_path.clone(), 9 | }; 10 | 11 | info!("Setting board configuration"); 12 | hal::board_setconf(&board_config)?; 13 | 14 | Ok(()) 15 | } 16 | 17 | pub fn rx_setconf(config: &Configuration) -> Result<()> { 18 | info!("Setting up concentrator channels"); 19 | 20 | for (i, channel) in config.gateway.concentrator.channels.iter().enumerate() { 21 | info!( 22 | "Configuring channel: {}, center_freq: {}", 23 | i, channel.frequency 24 | ); 25 | 26 | hal::channel_rx_setconf( 27 | i as u8, 28 | &hal::ChannelRxConfig { 29 | enable: channel.frequency > 0, 30 | freq_hz: channel.frequency, 31 | bandwidth: channel.bandwidth, 32 | datarate: match channel.spreading_factor { 33 | 5 => hal::DataRate::SF5, 34 | 6 => hal::DataRate::SF6, 35 | 7 => hal::DataRate::SF7, 36 | 8 => hal::DataRate::SF8, 37 | 9 => hal::DataRate::SF9, 38 | 10 => hal::DataRate::SF10, 39 | 11 => hal::DataRate::SF11, 40 | 12 => hal::DataRate::SF12, 41 | _ => return Err(anyhow!("invalid spreading_factor")), 42 | }, 43 | rssi_offset: channel.rssi_offset, 44 | sync_word: match config.gateway.lorawan_public { 45 | true => 0x21, 46 | false => 0x12, 47 | }, 48 | }, 49 | )?; 50 | } 51 | 52 | Ok(()) 53 | } 54 | 55 | pub fn tx_setconf(config: &Configuration) -> Result<()> { 56 | let enable = !config.gateway.model_config.tx_min_max_freqs.is_empty(); 57 | info!("Configuring tx path, enable: {}", enable); 58 | hal::channel_tx_setconf(&hal::ChannelTxConfig { enable }) 59 | } 60 | 61 | pub fn start() -> Result<()> { 62 | info!("Starting the concentrator"); 63 | hal::start() 64 | } 65 | 66 | pub fn stop() -> Result<()> { 67 | info!("Stopping the concentrator"); 68 | hal::stop() 69 | } 70 | 71 | pub fn get_eui() -> Result<[u8; 8]> { 72 | debug!("Getting the gateway EUI"); 73 | hal::get_eui() 74 | } 75 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1302/src/handler/stats.rs: -------------------------------------------------------------------------------- 1 | use std::collections::HashMap; 2 | use std::sync::mpsc::Receiver; 3 | use std::sync::{Arc, Mutex}; 4 | use std::time::Duration; 5 | 6 | use anyhow::{Context, Result}; 7 | 8 | use chirpstack_api::gw::DutyCycleStats; 9 | use libconcentratord::signals::Signal; 10 | use libconcentratord::{jitqueue, stats}; 11 | use libloragw_sx1302::hal; 12 | 13 | use super::gps; 14 | use crate::wrapper; 15 | 16 | pub fn stats_loop( 17 | gateway_id: &[u8], 18 | get_temperature: bool, 19 | stats_interval: &Duration, 20 | stop_receive: Receiver, 21 | mut metadata: HashMap, 22 | queue: Arc>>, 23 | ) -> Result<()> { 24 | debug!("Starting stats loop, stats_interval: {:?}", stats_interval); 25 | 26 | loop { 27 | // Instead of a 'stats interval' sleep, we receive from the stop channel with a 28 | // timeout equal to the 'stats interval'. 29 | if let Ok(v) = stop_receive.recv_timeout(*stats_interval) { 30 | debug!("Received stop signal, signal: {}", v); 31 | return Ok(()); 32 | } 33 | 34 | // fetch the current gps coordinates 35 | let loc = gps::get_coords().map(|v| chirpstack_api::common::Location { 36 | latitude: v.latitude, 37 | longitude: v.longitude, 38 | altitude: v.altitude as f64, 39 | source: chirpstack_api::common::LocationSource::Gps.into(), 40 | ..Default::default() 41 | }); 42 | 43 | // fetch the concentrator temperature. 44 | if get_temperature { 45 | match hal::get_temperature() { 46 | Ok(v) => { 47 | metadata.insert("concentrator_temp".to_string(), format!("{}", v)); 48 | } 49 | Err(err) => { 50 | metadata.remove("concentrator_temp"); 51 | error!("Get concentrator temperature error, error: {}", err); 52 | } 53 | } 54 | } 55 | 56 | let dc_stats = get_duty_cycle_stats(&queue)?; 57 | stats::send_and_reset(gateway_id, loc, dc_stats, &metadata).context("Send stats")?; 58 | } 59 | } 60 | 61 | fn get_duty_cycle_stats( 62 | queue: &Arc>>, 63 | ) -> Result> { 64 | let mut queue = queue.lock().map_err(|_| anyhow!("Lock queue error"))?; 65 | let concentrator_count = hal::get_instcnt()?; 66 | Ok(queue.get_duty_cycle_stats(concentrator_count)) 67 | } 68 | -------------------------------------------------------------------------------- /packaging/vendor/multitech/conduit-ap/files/chirpstack-concentratord.init: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | NAME="chirpstack-concentratord" 4 | DESC="ChirpStack Concentratord" 5 | DAEMON_BIN=/opt/$NAME/$NAME 6 | DAEMON_CONF_DIR=/var/config/$NAME 7 | DAEMON_PID=/var/run/$NAME.pid 8 | 9 | 10 | read_lora_hw_info() { 11 | lora_id=$(mts-io-sysfs show lora/product-id 2> /dev/null) 12 | lora_eui=$(mts-io-sysfs show lora/eui 2> /dev/null) 13 | # remove all colons 14 | lora_eui_raw=${lora_eui//:/} 15 | lora_hw=$(mts-io-sysfs show lora/hw-version 2> /dev/null) 16 | } 17 | 18 | hardware_found() { 19 | if [[ "$lora_id" =~ "MTCAP-LORA" ]]; then 20 | return 0 21 | fi 22 | 23 | return 1 24 | } 25 | 26 | copy_config() { 27 | if [ $lora_id == "MTCAP-LORA-868" ]; then 28 | model="${lora_id,,}" 29 | model="${model//-/_}" 30 | region="EU868" 31 | band_config="eu868" 32 | channel_config="channels_eu868_0" 33 | fi 34 | 35 | if [ $lora_id == "MTCAP-LORA-915" ]; then 36 | model="${lora_id,,}" 37 | model="${model//-/_}" 38 | region="US915" 39 | band_config="us915" 40 | channel_config="channels_us915_0" 41 | fi 42 | 43 | mkdir -p $DAEMON_CONF_DIR 44 | cp $DAEMON_CONF_DIR/examples/concentratord.toml $DAEMON_CONF_DIR/concentratord.toml 45 | cp $DAEMON_CONF_DIR/examples/$channel_config.toml $DAEMON_CONF_DIR/channels.toml 46 | 47 | sed -i "s/gateway_id=.*/gateway_id=\"${lora_eui_raw}\"/" $DAEMON_CONF_DIR/concentratord.toml 48 | sed -i "s/region=.*/region=\"${region}\"/" $DAEMON_CONF_DIR/concentratord.toml 49 | sed -i "s/model=.*/model=\"multitech_${model}\"/" $DAEMON_CONF_DIR/concentratord.toml 50 | } 51 | 52 | do_start() { 53 | read_lora_hw_info 54 | if hardware_found; then 55 | echo "Found $lora_id with $lora_hw hardware" 56 | else 57 | echo "$0: LORA card not detected" 58 | exit 1 59 | fi 60 | 61 | if ! [ -f "$DAEMON_CONF_DIR/concentratord.toml" ]; then 62 | copy_config 63 | fi 64 | 65 | echo "Starting $NAME" 66 | start-stop-daemon \ 67 | --start \ 68 | --background \ 69 | --make-pidfile \ 70 | --pidfile $DAEMON_PID \ 71 | --exec $DAEMON_BIN -- -c $DAEMON_CONF_DIR/concentratord.toml -c $DAEMON_CONF_DIR/channels.toml 72 | } 73 | 74 | function do_stop { 75 | echo "Stopping $NAME" 76 | start-stop-daemon \ 77 | --stop \ 78 | --oknodo \ 79 | --quiet \ 80 | --pidfile $DAEMON_PID 81 | } 82 | 83 | case "$1" in 84 | "start") 85 | do_start 86 | ;; 87 | "stop") 88 | do_stop 89 | ;; 90 | "restart") 91 | do_stop 92 | do_start 93 | ;; 94 | *) 95 | echo "Usage: $1 {start|stop|restart}" 96 | exit 1 97 | ;; 98 | esac 99 | -------------------------------------------------------------------------------- /packaging/vendor/multitech/conduit-ap3/files/chirpstack-concentratord.init: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | NAME="chirpstack-concentratord" 4 | DESC="ChirpStack Concentratord" 5 | DAEMON_BIN=/opt/$NAME/$NAME 6 | DAEMON_CONF_DIR=/var/config/$NAME 7 | DAEMON_PID=/var/run/$NAME.pid 8 | 9 | 10 | read_lora_hw_info() { 11 | lora_id=$(mts-io-sysfs show lora/product-id 2> /dev/null) 12 | lora_hw=$(mts-io-sysfs show lora/hw-version 2> /dev/null) 13 | lora_eui=$(mts-io-sysfs show lora/eui 2> /dev/null) 14 | # remove all colons 15 | lora_eui_raw=${lora_eui//:/} 16 | } 17 | 18 | hardware_found() { 19 | if [[ "$lora_id" =~ "MTCAP3" ]]; then 20 | return 0 21 | fi 22 | 23 | return 1 24 | } 25 | 26 | copy_config() { 27 | if [ $lora_id == "MTCAP3-003E00" ]; then 28 | model="${lora_id,,}" 29 | model="${model//-/_}" 30 | region="EU868" 31 | band_config="eu868" 32 | channel_config="channels_eu868_0" 33 | fi 34 | 35 | if [ $lora_id == "MTCAP3-003U00" ]; then 36 | model="${lora_id,,}" 37 | model="${model//-/_}" 38 | region="US915" 39 | band_config="us915" 40 | channel_config="channels_us915_0" 41 | fi 42 | 43 | mkdir -p $DAEMON_CONF_DIR 44 | cp $DAEMON_CONF_DIR/examples/concentratord.toml $DAEMON_CONF_DIR/concentratord.toml 45 | cp $DAEMON_CONF_DIR/examples/$channel_config.toml $DAEMON_CONF_DIR/channels.toml 46 | 47 | sed -i "s/region=.*/region=\"${region}\"/" $DAEMON_CONF_DIR/concentratord.toml 48 | sed -i "s/model=.*/model=\"multitech_${model}\"/" $DAEMON_CONF_DIR/concentratord.toml 49 | sed -i "s/gateway_id=.*/gateway_id=\"${lora_eui_raw}\"/" $DAEMON_CONF_DIR/concentratord.toml 50 | } 51 | 52 | do_start() { 53 | read_lora_hw_info 54 | if hardware_found; then 55 | echo "Found $lora_id with $lora_hw hardware" 56 | else 57 | echo "$0: LORA card not detected" 58 | exit 1 59 | fi 60 | 61 | if ! [ -f "$DAEMON_CONF_DIR/concentratord.toml" ]; then 62 | copy_config 63 | fi 64 | 65 | echo "Starting $NAME" 66 | start-stop-daemon \ 67 | --start \ 68 | --background \ 69 | --make-pidfile \ 70 | --pidfile $DAEMON_PID \ 71 | --exec $DAEMON_BIN -- -c $DAEMON_CONF_DIR/concentratord.toml -c $DAEMON_CONF_DIR/channels.toml 72 | } 73 | 74 | function do_stop { 75 | echo "Stopping $NAME" 76 | start-stop-daemon \ 77 | --stop \ 78 | --oknodo \ 79 | --quiet \ 80 | --pidfile $DAEMON_PID 81 | } 82 | 83 | case "$1" in 84 | "start") 85 | do_start 86 | ;; 87 | "stop") 88 | do_stop 89 | ;; 90 | "restart") 91 | do_stop 92 | do_start 93 | ;; 94 | *) 95 | echo "Usage: $1 {start|stop|restart}" 96 | exit 1 97 | ;; 98 | esac 99 | -------------------------------------------------------------------------------- /chirpstack-concentratord-2g4/src/handler/uplink.rs: -------------------------------------------------------------------------------- 1 | use std::sync::mpsc::Receiver; 2 | use std::thread; 3 | use std::time::Duration; 4 | 5 | use anyhow::{Context, Result}; 6 | 7 | use libconcentratord::signals::Signal; 8 | use libconcentratord::{events, stats}; 9 | use libloragw_2g4::hal; 10 | 11 | use crate::wrapper; 12 | 13 | pub fn handle_loop( 14 | gateway_id: &[u8], 15 | stop_receive: Receiver, 16 | disable_crc_filter: bool, 17 | time_fallback: bool, 18 | ) -> Result<()> { 19 | debug!("Starting uplink handle loop"); 20 | 21 | loop { 22 | if let Ok(v) = stop_receive.recv_timeout(Duration::from_millis(0)) { 23 | debug!("Received stop signal, signal: {}", v); 24 | return Ok(()); 25 | } 26 | 27 | match hal::receive() { 28 | Ok(frames) => { 29 | for frame in frames { 30 | stats::inc_rx_packets_received(); 31 | 32 | if !disable_crc_filter && frame.status != hal::CRC::CRCOk { 33 | debug!( 34 | "Frame received with invalid CRC, see disable_crc_filter configuration option if you want to receive these frames" 35 | ); 36 | continue; 37 | } 38 | 39 | let proto = match wrapper::uplink_to_proto(gateway_id, &frame, time_fallback) { 40 | Ok(v) => v, 41 | Err(err) => { 42 | error!("Convert uplink frame to protobuf error, error: {}", err); 43 | continue; 44 | } 45 | }; 46 | 47 | let rx_info = proto 48 | .rx_info 49 | .as_ref() 50 | .ok_or_else(|| anyhow!("rx_info is None"))?; 51 | 52 | info!( 53 | "Frame received, uplink_id: {}, count_us: {}, freq: {}, bw: {}, mod: {:?}, dr: {:?}", 54 | rx_info.uplink_id, 55 | frame.count_us, 56 | frame.freq_hz, 57 | frame.bandwidth, 58 | frame.modulation, 59 | frame.datarate, 60 | ); 61 | 62 | if frame.status == hal::CRC::CRCOk { 63 | stats::inc_rx_counts(&proto); 64 | } 65 | events::send_uplink(proto).context("Send uplink")?; 66 | } 67 | } 68 | Err(_) => error!("Receive error"), 69 | }; 70 | 71 | thread::sleep(Duration::from_millis(10)); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1301/src/handler/uplink.rs: -------------------------------------------------------------------------------- 1 | use std::sync::mpsc::Receiver; 2 | use std::thread; 3 | use std::time::Duration; 4 | 5 | use anyhow::{Context, Result}; 6 | 7 | use libconcentratord::signals::Signal; 8 | use libconcentratord::{events, stats}; 9 | use libloragw_sx1301::hal; 10 | 11 | use crate::wrapper; 12 | 13 | pub fn handle_loop( 14 | gateway_id: &[u8], 15 | stop_receive: Receiver, 16 | disable_crc_filter: bool, 17 | time_fallback: bool, 18 | ) -> Result<()> { 19 | debug!("Starting uplink handle loop"); 20 | 21 | loop { 22 | if let Ok(v) = stop_receive.recv_timeout(Duration::from_millis(0)) { 23 | debug!("Received stop signal, signal: {}", v); 24 | return Ok(()); 25 | } 26 | 27 | match hal::receive() { 28 | Ok(frames) => { 29 | for frame in frames { 30 | stats::inc_rx_packets_received(); 31 | 32 | if !disable_crc_filter && frame.status != hal::CRC::CRCOk { 33 | debug!( 34 | "Frame received with invalid CRC, see disable_crc_filter configuration option if you want to receive these frames" 35 | ); 36 | continue; 37 | } 38 | 39 | let proto = match wrapper::uplink_to_proto(gateway_id, &frame, time_fallback) { 40 | Ok(v) => v, 41 | Err(err) => { 42 | error!("Convert uplink frame to protobuf error, error: {}", err); 43 | continue; 44 | } 45 | }; 46 | 47 | let rx_info = proto 48 | .rx_info 49 | .as_ref() 50 | .ok_or_else(|| anyhow!("rx_info is None"))?; 51 | 52 | info!( 53 | "Frame received, uplink_id: {}, count_us: {}, freq: {}, bw: {}, mod: {:?}, dr: {:?}", 54 | rx_info.uplink_id, 55 | frame.count_us, 56 | frame.freq_hz, 57 | frame.bandwidth, 58 | frame.modulation, 59 | frame.datarate, 60 | ); 61 | 62 | if frame.status == hal::CRC::CRCOk { 63 | stats::inc_rx_counts(&proto); 64 | } 65 | events::send_uplink(proto).context("Send uplink")?; 66 | } 67 | } 68 | Err(_) => error!("Receive error"), 69 | }; 70 | 71 | thread::sleep(Duration::from_millis(10)); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /packaging/vendor/multitech/conduit/files/2g4/chirpstack-concentratord-2g4-ap1.init: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | AP=ap1 4 | 5 | NAME="chirpstack-concentratord-2g4" 6 | DESC="ChirpStack Concentratord 2g4" 7 | DAEMON_BIN=/opt/$NAME/$NAME 8 | DAEMON_PID=/var/run/$NAME-$AP.pid 9 | 10 | GPS_TTY_PATH=/dev/ttyXRUSB2 11 | CONF_DIR=/var/config/$NAME 12 | 13 | 14 | function read_lora_hw_info() { 15 | lora_id=$(mts-io-sysfs show $AP/product-id 2> /dev/null) 16 | lora_eui=$(mts-io-sysfs show $AP/eui 2> /dev/null) 17 | # remove all colons 18 | lora_eui_raw=${lora_eui//:/} 19 | lora_hw=$(mts-io-sysfs show $AP/hw-version 2> /dev/null) 20 | } 21 | 22 | function hardware_found() { 23 | if [[ "$lora_id" =~ "MTAC-LORA-2G4-3" ]]; then 24 | return 0 25 | fi 26 | 27 | return 1 28 | } 29 | 30 | copy_config() { 31 | if [ -e $GPS_TTY_PATH ]; then 32 | model_flags="\"${AP^^}\", \"GNSS\"" 33 | else 34 | model_flags="\"${AP^^}\"" 35 | fi 36 | 37 | mkdir -p $CONF_DIR/$AP 38 | cp $CONF_DIR/examples/concentratord.toml $CONF_DIR/$AP/concentratord.toml 39 | cp $CONF_DIR/examples/region.toml $CONF_DIR/$AP/region.toml 40 | cp $CONF_DIR/examples/channels.toml $CONF_DIR/$AP/channels.toml 41 | 42 | sed -i "s/gateway_id=.*/gateway_id=\"${lora_eui_raw}\"/" $CONF_DIR/$AP/concentratord.toml 43 | sed -i "s/model_flags=.*/model_flags=[${model_flags}]/" $CONF_DIR/$AP/concentratord.toml 44 | sed -i "s/event_bind=.*/event_bind=\"ipc:\/\/\/tmp\/concentratord_event_$AP\"/" $CONF_DIR/$AP/concentratord.toml 45 | sed -i "s/command_bind=.*/command_bind=\"ipc:\/\/\/tmp\/concentratord_command_$AP\"/" $CONF_DIR/$AP/concentratord.toml 46 | } 47 | 48 | function do_start { 49 | read_lora_hw_info 50 | if hardware_found; then 51 | echo "Found $lora_id with $lora_hw hardware at $AP" 52 | else 53 | echo "$0: LORA card not detected" 54 | exit 1 55 | fi 56 | 57 | if ! [ -f "$CONF_DIR/$AP/concentratord.toml" ]; then 58 | copy_config 59 | fi 60 | 61 | echo "Starting $NAME" 62 | start-stop-daemon \ 63 | --start \ 64 | --background \ 65 | --make-pidfile \ 66 | --pidfile $DAEMON_PID \ 67 | --exec $DAEMON_BIN -- -c $CONF_DIR/$AP/concentratord.toml -c $CONF_DIR/$AP/region.toml -c $CONF_DIR/$AP/channels.toml 68 | } 69 | 70 | function do_stop { 71 | echo "Stopping $NAME" 72 | start-stop-daemon \ 73 | --stop \ 74 | --oknodo \ 75 | --quiet \ 76 | --pidfile $DAEMON_PID 77 | } 78 | 79 | case "$1" in 80 | "start") 81 | do_start 82 | ;; 83 | "stop") 84 | do_stop 85 | ;; 86 | "restart") 87 | do_stop 88 | do_start 89 | ;; 90 | *) 91 | echo "Usage: $1 {start|stop|restart}" 92 | exit 1 93 | ;; 94 | esac 95 | -------------------------------------------------------------------------------- /packaging/vendor/multitech/conduit/files/2g4/chirpstack-concentratord-2g4-ap2.init: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | AP=ap2 4 | 5 | NAME="chirpstack-concentratord-2g4" 6 | DESC="ChirpStack Concentratord 2g4" 7 | DAEMON_BIN=/opt/$NAME/$NAME 8 | DAEMON_PID=/var/run/$NAME-$AP.pid 9 | 10 | GPS_TTY_PATH=/dev/ttyXRUSB2 11 | CONF_DIR=/var/config/$NAME 12 | 13 | 14 | function read_lora_hw_info() { 15 | lora_id=$(mts-io-sysfs show $AP/product-id 2> /dev/null) 16 | lora_eui=$(mts-io-sysfs show $AP/eui 2> /dev/null) 17 | # remove all colons 18 | lora_eui_raw=${lora_eui//:/} 19 | lora_hw=$(mts-io-sysfs show $AP/hw-version 2> /dev/null) 20 | } 21 | 22 | function hardware_found() { 23 | if [[ "$lora_id" =~ "MTAC-LORA-2G4-3" ]]; then 24 | return 0 25 | fi 26 | 27 | return 1 28 | } 29 | 30 | copy_config() { 31 | if [ -e $GPS_TTY_PATH ]; then 32 | model_flags="\"${AP^^}\", \"GNSS\"" 33 | else 34 | model_flags="\"${AP^^}\"" 35 | fi 36 | 37 | mkdir -p $CONF_DIR/$AP 38 | cp $CONF_DIR/examples/concentratord.toml $CONF_DIR/$AP/concentratord.toml 39 | cp $CONF_DIR/examples/region.toml $CONF_DIR/$AP/region.toml 40 | cp $CONF_DIR/examples/channels.toml $CONF_DIR/$AP/channels.toml 41 | 42 | sed -i "s/gateway_id=.*/gateway_id=\"${lora_eui_raw}\"/" $CONF_DIR/$AP/concentratord.toml 43 | sed -i "s/model_flags=.*/model_flags=[${model_flags}]/" $CONF_DIR/$AP/concentratord.toml 44 | sed -i "s/event_bind=.*/event_bind=\"ipc:\/\/\/tmp\/concentratord_event_$AP\"/" $CONF_DIR/$AP/concentratord.toml 45 | sed -i "s/command_bind=.*/command_bind=\"ipc:\/\/\/tmp\/concentratord_command_$AP\"/" $CONF_DIR/$AP/concentratord.toml 46 | } 47 | 48 | function do_start { 49 | read_lora_hw_info 50 | if hardware_found; then 51 | echo "Found $lora_id with $lora_hw hardware at $AP" 52 | else 53 | echo "$0: LORA card not detected" 54 | exit 1 55 | fi 56 | 57 | if ! [ -f "$CONF_DIR/$AP/concentratord.toml" ]; then 58 | copy_config 59 | fi 60 | 61 | echo "Starting $NAME" 62 | start-stop-daemon \ 63 | --start \ 64 | --background \ 65 | --make-pidfile \ 66 | --pidfile $DAEMON_PID \ 67 | --exec $DAEMON_BIN -- -c $CONF_DIR/$AP/concentratord.toml -c $CONF_DIR/$AP/region.toml -c $CONF_DIR/$AP/channels.toml 68 | } 69 | 70 | function do_stop { 71 | echo "Stopping $NAME" 72 | start-stop-daemon \ 73 | --stop \ 74 | --oknodo \ 75 | --quiet \ 76 | --pidfile $DAEMON_PID 77 | } 78 | 79 | case "$1" in 80 | "start") 81 | do_start 82 | ;; 83 | "stop") 84 | do_stop 85 | ;; 86 | "restart") 87 | do_stop 88 | do_start 89 | ;; 90 | *) 91 | echo "Usage: $1 {start|stop|restart}" 92 | exit 1 93 | ;; 94 | esac 95 | -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | on: 3 | push: 4 | branches: 5 | - '*' 6 | tags: 7 | - 'v*' 8 | pull_request: 9 | 10 | jobs: 11 | tests: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - 15 | name: Checkout 16 | uses: actions/checkout@v4 17 | - 18 | name: Install Nix 19 | uses: cachix/install-nix-action@v30 20 | with: 21 | nix_path: nixpkgs=channel:nixos-25.05 22 | - 23 | name: Cargo cache 24 | uses: actions/cache@v4 25 | with: 26 | path: | 27 | ~/.cargo/bin/ 28 | ~/.cargo/registry/index/ 29 | ~/.cargo/registry/cache/ 30 | ~/.cargo/git/db/ 31 | target/ 32 | key: ${{ runner.os }}-cargo-test-${{ hashFiles('**/Cargo.lock') }} 33 | - 34 | name: Install dev dependencies 35 | run: nix-shell --command "make dev-dependencies" 36 | - 37 | name: Run tests 38 | run: nix-shell --command "make test" 39 | 40 | dist: 41 | needs: tests 42 | runs-on: ubuntu-latest 43 | if: startsWith(github.ref, 'refs/tags/v') 44 | strategy: 45 | matrix: 46 | target: 47 | - aarch64-unknown-linux-musl 48 | - armv5te-unknown-linux-musleabi 49 | - armv7-unknown-linux-musleabihf 50 | - x86_64-unknown-linux-musl 51 | steps: 52 | - 53 | name: Checkout 54 | uses: actions/checkout@v4 55 | - 56 | name: Install Nix 57 | uses: cachix/install-nix-action@v30 58 | with: 59 | nix_path: nixpkgs=channel:nixos-25.04 60 | - 61 | name: Cargo cache 62 | uses: actions/cache@v4 63 | with: 64 | path: | 65 | ~/.cargo/bin/ 66 | ~/.cargo/registry/index/ 67 | ~/.cargo/registry/cache/ 68 | ~/.cargo/git/db/ 69 | target/ 70 | key: ${{ runner.os }}-cargo-dist-${{ matrix.target }}-${{ hashFiles('**/Cargo.lock') }} 71 | - 72 | name: Install dev dependencies 73 | run: nix-shell --command "make dev-dependencies" 74 | - 75 | name: Build distributables 76 | run: nix-shell --command "make dist-${{ matrix.target }}" 77 | - 78 | name: Configure AWS credentials 79 | uses: aws-actions/configure-aws-credentials@v4 80 | with: 81 | aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} 82 | aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} 83 | aws-region: eu-west-1 84 | - 85 | name: Upload binaries to S3 86 | run: | 87 | aws s3 sync dist s3://builds.loraserver.io/chirpstack-concentratord 88 | if: startsWith(github.ref, 'refs/tags/v') 89 | -------------------------------------------------------------------------------- /cross/Dockerfile.mipsel-unknown-linux-musl: -------------------------------------------------------------------------------- 1 | FROM ghcr.io/cross-rs/mipsel-unknown-linux-musl:main 2 | 3 | ENV SX1301_VERSION=v5.0.1r4 4 | ENV SX1302_VERSION=V2.1.0r9 5 | ENV SX2G4_VERSION=V1.1.0 6 | 7 | ENV HAL_ARCH=mips 8 | ENV MUSL_PREFIX=mipsel-linux-muslsf 9 | 10 | RUN apt-get update && \ 11 | apt-get --assume-yes install \ 12 | protobuf-compiler \ 13 | libprotobuf-dev \ 14 | git 15 | 16 | RUN mkdir /hal 17 | 18 | # Needed for RAK shields, works with other shields too 19 | # sed -i 's/define SPI_SPEED.*/define SPI_SPEED 2000000/g' /hal/lora_gateway/libloragw/src/loragw_spi.native.c 20 | 21 | RUN echo "Building sx1301 HAL" && \ 22 | cd /hal && \ 23 | git clone https://github.com/brocaar/lora_gateway.git -b $SX1301_VERSION && \ 24 | cd /hal/lora_gateway && \ 25 | sed -i "s/CFLAGS :=.*/CFLAGS := -O2 -Wall -Wextra -std=c99 -Iinc -I. -fPIC/g" libloragw/Makefile && \ 26 | ARCH=$ARCH CROSS_COMPILE=$MUSL_PREFIX- make && \ 27 | ln -s /hal/lora_gateway/libloragw/inc /usr/local/$MUSL_PREFIX/include/libloragw-sx1301 && \ 28 | ln -s /hal/lora_gateway/libloragw/libloragw.a /usr/local/$MUSL_PREFIX/lib/libloragw-sx1301.a 29 | 30 | RUN echo "Building sx1302 HAL" && \ 31 | cd /hal && \ 32 | git clone https://github.com/brocaar/sx1302_hal.git -b $SX1302_VERSION && \ 33 | cd /hal/sx1302_hal && \ 34 | sed -i "s/CFLAGS :=.*/CFLAGS := -O2 -Wall -Wextra -std=c99 -Iinc -I. -I..\/libtools\/inc -fPIC/g" libloragw/Makefile && \ 35 | sed -i "s/CFLAGS :=.*/CFLAGS := -O2 -Wall -Wextra -std=c99 -Iinc -I. -fPIC/g" libtools/Makefile && \ 36 | ARCH=$ARCH CROSS_COMPILE=$MUSL_PREFIX- make libloragw && \ 37 | ln -s /hal/sx1302_hal/libloragw/inc /usr/local/$MUSL_PREFIX/include/libloragw-sx1302 && \ 38 | ln -s /hal/sx1302_hal/libloragw/libloragw.a /usr/local/$MUSL_PREFIX/lib/libloragw-sx1302.a && \ 39 | cp /hal/sx1302_hal/libtools/inc/* /usr/local/$MUSL_PREFIX/include && \ 40 | cp /hal/sx1302_hal/libtools/*.a /usr/local/$MUSL_PREFIX/lib 41 | 42 | RUN echo "Building 2g4 HAL" && \ 43 | cd /hal && \ 44 | git clone https://github.com/Lora-net/gateway_2g4_hal.git -b $SX2G4_VERSION && \ 45 | cd /hal/gateway_2g4_hal && \ 46 | sed -i "s/CFLAGS :=.*/CFLAGS := -g -O0 -Wall -Wextra -std=c99 -Iinc -I. -fPIC/g" libloragw/Makefile && \ 47 | sed -i "s/CFLAGS :=.*/CFLAGS := -g -O0 -Wall -Wextra -std=c99 -Iinc -I. -fPIC/g" libtools/Makefile && \ 48 | ARCH=$ARCH CROSS_COMPILE=$MUSL_PREFIX- make libloragw && \ 49 | ln -s /hal/gateway_2g4_hal/libloragw/inc /usr/local/$MUSL_PREFIX/include/libloragw-2g4 && \ 50 | ln -s /hal/gateway_2g4_hal/libloragw/libloragw.a /usr/local/$MUSL_PREFIX/lib/libloragw-2g4.a 51 | 52 | RUN echo "Copy libstdc++" && \ 53 | mkdir -p /usr/local/$MUSL_PREFIX-target/lib && \ 54 | cp /usr/local/$MUSL_PREFIX/lib/libstdc++* /usr/local/$MUSL_PREFIX-target/lib 55 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1302/src/handler/uplink.rs: -------------------------------------------------------------------------------- 1 | use std::sync::mpsc::Receiver; 2 | use std::thread; 3 | use std::time::Duration; 4 | 5 | use anyhow::{Context, Result}; 6 | 7 | use libconcentratord::signals::Signal; 8 | use libconcentratord::{events, stats}; 9 | use libloragw_sx1302::hal; 10 | 11 | use super::super::wrapper; 12 | 13 | pub fn handle_loop( 14 | gateway_id: &[u8], 15 | stop_receive: Receiver, 16 | disable_crc_filter: bool, 17 | time_fallback: bool, 18 | ) -> Result<()> { 19 | debug!("Starting uplink handle loop"); 20 | 21 | loop { 22 | if let Ok(v) = stop_receive.recv_timeout(Duration::from_millis(0)) { 23 | debug!("Received stop signal, signal: {}", v); 24 | return Ok(()); 25 | } 26 | 27 | match hal::receive() { 28 | Ok(frames) => { 29 | for frame in frames { 30 | stats::inc_rx_packets_received(); 31 | 32 | if !disable_crc_filter && frame.status != hal::CRC::CRCOk { 33 | debug!( 34 | "Frame received with invalid CRC, see disable_crc_filter configuration option if you want to receive these frames" 35 | ); 36 | continue; 37 | } 38 | 39 | let proto = match wrapper::uplink_to_proto(gateway_id, &frame, time_fallback) { 40 | Ok(v) => v, 41 | Err(err) => { 42 | error!("Convert uplink frame to protobuf error, error: {}", err); 43 | continue; 44 | } 45 | }; 46 | 47 | let rx_info = proto 48 | .rx_info 49 | .as_ref() 50 | .ok_or_else(|| anyhow!("rx_info is None"))?; 51 | 52 | info!( 53 | "Frame received, uplink_id: {}, count_us: {}, freq: {}, bw: {}, mod: {:?}, dr: {:?}, ftime_received: {}, ftime_ns: {}", 54 | rx_info.uplink_id, 55 | frame.count_us, 56 | frame.freq_hz, 57 | frame.bandwidth, 58 | frame.modulation, 59 | frame.datarate, 60 | frame.ftime_received, 61 | frame.ftime, 62 | ); 63 | 64 | if frame.status == hal::CRC::CRCOk { 65 | stats::inc_rx_counts(&proto); 66 | } 67 | events::send_uplink(proto).context("Send uplink")?; 68 | } 69 | } 70 | Err(_) => error!("Receive error"), 71 | }; 72 | 73 | thread::sleep(Duration::from_millis(10)); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /chirpstack-concentratord-sx1301/src/handler/timersync.rs: -------------------------------------------------------------------------------- 1 | use std::sync::mpsc::Receiver; 2 | use std::sync::{LazyLock, Mutex}; 3 | use std::time::{Duration, SystemTime}; 4 | 5 | use anyhow::Result; 6 | 7 | use libconcentratord::signals::Signal; 8 | use libloragw_sx1301::{hal, reg, wrapper}; 9 | 10 | static PREV_CONCENTRATOR_COUNT: LazyLock> = 11 | LazyLock::new(|| Mutex::new(hal::get_trigcnt().unwrap())); 12 | static PREV_UNIX_TIME: LazyLock> = LazyLock::new(|| { 13 | Mutex::new( 14 | SystemTime::now() 15 | .duration_since(SystemTime::UNIX_EPOCH) 16 | .unwrap(), 17 | ) 18 | }); 19 | 20 | pub fn timesync_loop(stop_receive: Receiver) -> Result<()> { 21 | debug!("Starting timesync loop"); 22 | 23 | loop { 24 | // The timesync is in a separate function to make sure that the 25 | // mutex guard is dereferenced as soon as the function returns. 26 | timesync()?; 27 | 28 | // Instead of a 60s sleep, we receive from the stop channel with a 29 | // timeout of 60 seconds. 30 | if let Ok(v) = stop_receive.recv_timeout(Duration::from_secs(60)) { 31 | debug!("Received stop signal, signal: {}", v); 32 | return Ok(()); 33 | } 34 | } 35 | } 36 | 37 | pub fn get_concentrator_count() -> u32 { 38 | let prev_concentrator_count = PREV_CONCENTRATOR_COUNT.lock().unwrap(); 39 | let prev_unix_time = PREV_UNIX_TIME.lock().unwrap(); 40 | 41 | let unix_diff = SystemTime::now() 42 | .duration_since(SystemTime::UNIX_EPOCH) 43 | .unwrap() 44 | - *prev_unix_time; 45 | 46 | prev_concentrator_count.wrapping_add(unix_diff.as_micros() as u32) 47 | } 48 | 49 | fn timesync() -> Result<()> { 50 | debug!("Disabling GPS mode for concentrator counter"); 51 | reg::reg_w(wrapper::LGW_GPS_EN, 0)?; 52 | 53 | let mut prev_concentrator_count = PREV_CONCENTRATOR_COUNT.lock().unwrap(); 54 | let mut prev_unix_time = PREV_UNIX_TIME.lock().unwrap(); 55 | 56 | let concentrator_count = hal::get_trigcnt()?; 57 | let unix_time = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH)?; 58 | 59 | let unix_time_diff = unix_time - *prev_unix_time; 60 | let concentrator_diff: i64 = if concentrator_count > *prev_concentrator_count { 61 | (concentrator_count - *prev_concentrator_count) as i64 62 | } else { 63 | (concentrator_count as i64) + ((1 << 32) - 1) - (*prev_concentrator_count as i64) 64 | }; 65 | 66 | let drift = (unix_time_diff.as_micros() as i64) - concentrator_diff; 67 | 68 | *prev_unix_time = unix_time; 69 | *prev_concentrator_count = concentrator_count; 70 | 71 | debug!("Current concentrator count_us: {}", concentrator_count); 72 | debug!("Concentrator drift, drift_us: {}", drift); 73 | 74 | debug!("Enabling GPS mode for concentrator counter"); 75 | reg::reg_w(wrapper::LGW_GPS_EN, 1)?; 76 | 77 | Ok(()) 78 | } 79 | -------------------------------------------------------------------------------- /packaging/vendor/multitech/conduit/files/sx1302/chirpstack-concentratord-sx1302-ap1.init: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | AP=ap1 4 | 5 | NAME="chirpstack-concentratord-sx1302" 6 | DESC="ChirpStack Concentratord SX1302" 7 | DAEMON_BIN=/opt/$NAME/$NAME 8 | DAEMON_PID=/var/run/$NAME-$AP.pid 9 | 10 | GPS_TTY_PATH=/dev/ttyXRUSB2 11 | CONF_DIR=/var/config/$NAME 12 | 13 | 14 | function read_lora_hw_info() { 15 | lora_id=$(mts-io-sysfs show $AP/product-id 2> /dev/null) 16 | lora_eui=$(mts-io-sysfs show $AP/eui 2> /dev/null) 17 | # remove all colons 18 | lora_hw=$(mts-io-sysfs show $AP/hw-version 2> /dev/null) 19 | } 20 | 21 | function hardware_found() { 22 | if [[ "$lora_id" =~ "MTAC-003" ]]; then 23 | return 0 24 | fi 25 | 26 | return 1 27 | } 28 | 29 | copy_config() { 30 | if [ $lora_id == "MTAC-003E00" ]; then 31 | model="${lora_id,,}" 32 | model="${model//-/_}" 33 | region="EU868" 34 | band_config="eu868" 35 | channel_config="eu868_0" 36 | fi 37 | 38 | if [ $lora_id == "MTAC-003U00" ]; then 39 | model="${lora_id,,}" 40 | model="${model//-/_}" 41 | region="US915" 42 | band_config="us915" 43 | channel_config="us915_0" 44 | fi 45 | 46 | if [ -e $GPS_TTY_PATH ]; then 47 | model_flags="\"${AP^^}\", \"GNSS\"" 48 | else 49 | model_flags="\"${AP^^}\"" 50 | fi 51 | 52 | mkdir -p $CONF_DIR/$AP 53 | cp $CONF_DIR/examples/concentratord.toml $CONF_DIR/$AP/concentratord.toml 54 | cp $CONF_DIR/examples/region_$band_config.toml $CONF_DIR/$AP/region.toml 55 | cp $CONF_DIR/examples/channels_$channel_config.toml $CONF_DIR/$AP/channels.toml 56 | 57 | sed -i "s/region=.*/region=\"${region}\"/" $CONF_DIR/$AP/concentratord.toml 58 | sed -i "s/model=.*/model=\"multitech_${model}\"/" $CONF_DIR/$AP/concentratord.toml 59 | sed -i "s/model_flags=.*/model_flags=[${model_flags}]/" $CONF_DIR/$AP/concentratord.toml 60 | sed -i "s/event_bind=.*/event_bind=\"ipc:\/\/\/tmp\/concentratord_event_$AP\"/" $CONF_DIR/$AP/concentratord.toml 61 | sed -i "s/command_bind=.*/command_bind=\"ipc:\/\/\/tmp\/concentratord_command_$AP\"/" $CONF_DIR/$AP/concentratord.toml 62 | } 63 | 64 | function do_start { 65 | read_lora_hw_info 66 | if hardware_found; then 67 | echo "Found $lora_id with $lora_hw hardware at $AP" 68 | else 69 | echo "$0: LORA card not detected" 70 | exit 1 71 | fi 72 | 73 | if ! [ -f "$CONF_DIR/$AP/concentratord.toml" ]; then 74 | copy_config 75 | fi 76 | 77 | echo "Starting $NAME" 78 | start-stop-daemon \ 79 | --start \ 80 | --background \ 81 | --make-pidfile \ 82 | --pidfile $DAEMON_PID \ 83 | --exec $DAEMON_BIN -- -c $CONF_DIR/$AP/concentratord.toml -c $CONF_DIR/$AP/region.toml -c $CONF_DIR/$AP/channels.toml 84 | } 85 | 86 | function do_stop { 87 | echo "Stopping $NAME" 88 | start-stop-daemon \ 89 | --stop \ 90 | --oknodo \ 91 | --quiet \ 92 | --pidfile $DAEMON_PID 93 | } 94 | 95 | case "$1" in 96 | "start") 97 | do_start 98 | ;; 99 | "stop") 100 | do_stop 101 | ;; 102 | "restart") 103 | do_stop 104 | do_start 105 | ;; 106 | *) 107 | echo "Usage: $1 {start|stop|restart}" 108 | exit 1 109 | ;; 110 | esac 111 | -------------------------------------------------------------------------------- /packaging/vendor/multitech/conduit/files/sx1302/chirpstack-concentratord-sx1302-ap2.init: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | AP=ap2 4 | 5 | NAME="chirpstack-concentratord-sx1302" 6 | DESC="ChirpStack Concentratord SX1302" 7 | DAEMON_BIN=/opt/$NAME/$NAME 8 | DAEMON_PID=/var/run/$NAME-$AP.pid 9 | 10 | GPS_TTY_PATH=/dev/ttyXRUSB2 11 | CONF_DIR=/var/config/$NAME 12 | 13 | 14 | function read_lora_hw_info() { 15 | lora_id=$(mts-io-sysfs show $AP/product-id 2> /dev/null) 16 | lora_eui=$(mts-io-sysfs show $AP/eui 2> /dev/null) 17 | # remove all colons 18 | lora_hw=$(mts-io-sysfs show $AP/hw-version 2> /dev/null) 19 | } 20 | 21 | function hardware_found() { 22 | if [[ "$lora_id" =~ "MTAC-003" ]]; then 23 | return 0 24 | fi 25 | 26 | return 1 27 | } 28 | 29 | copy_config() { 30 | if [ $lora_id == "MTAC-003E00" ]; then 31 | model="${lora_id,,}" 32 | model="${model//-/_}" 33 | region="EU868" 34 | band_config="eu868" 35 | channel_config="eu868_0" 36 | fi 37 | 38 | if [ $lora_id == "MTAC-003U00" ]; then 39 | model="${lora_id,,}" 40 | model="${model//-/_}" 41 | region="US915" 42 | band_config="us915" 43 | channel_config="us915_0" 44 | fi 45 | 46 | if [ -e $GPS_TTY_PATH ]; then 47 | model_flags="\"${AP^^}\", \"GNSS\"" 48 | else 49 | model_flags="\"${AP^^}\"" 50 | fi 51 | 52 | mkdir -p $CONF_DIR/$AP 53 | cp $CONF_DIR/examples/concentratord.toml $CONF_DIR/$AP/concentratord.toml 54 | cp $CONF_DIR/examples/region_$band_config.toml $CONF_DIR/$AP/region.toml 55 | cp $CONF_DIR/examples/channels_$channel_config.toml $CONF_DIR/$AP/channels.toml 56 | 57 | sed -i "s/region=.*/region=\"${region}\"/" $CONF_DIR/$AP/concentratord.toml 58 | sed -i "s/model=.*/model=\"multitech_${model}\"/" $CONF_DIR/$AP/concentratord.toml 59 | sed -i "s/model_flags=.*/model_flags=[${model_flags}]/" $CONF_DIR/$AP/concentratord.toml 60 | sed -i "s/event_bind=.*/event_bind=\"ipc:\/\/\/tmp\/concentratord_event_$AP\"/" $CONF_DIR/$AP/concentratord.toml 61 | sed -i "s/command_bind=.*/command_bind=\"ipc:\/\/\/tmp\/concentratord_command_$AP\"/" $CONF_DIR/$AP/concentratord.toml 62 | } 63 | 64 | function do_start { 65 | read_lora_hw_info 66 | if hardware_found; then 67 | echo "Found $lora_id with $lora_hw hardware at $AP" 68 | else 69 | echo "$0: LORA card not detected" 70 | exit 1 71 | fi 72 | 73 | if ! [ -f "$CONF_DIR/$AP/concentratord.toml" ]; then 74 | copy_config 75 | fi 76 | 77 | echo "Starting $NAME" 78 | start-stop-daemon \ 79 | --start \ 80 | --background \ 81 | --make-pidfile \ 82 | --pidfile $DAEMON_PID \ 83 | --exec $DAEMON_BIN -- -c $CONF_DIR/$AP/concentratord.toml -c $CONF_DIR/$AP/region.toml -c $CONF_DIR/$AP/channels.toml 84 | } 85 | 86 | function do_stop { 87 | echo "Stopping $NAME" 88 | start-stop-daemon \ 89 | --stop \ 90 | --oknodo \ 91 | --quiet \ 92 | --pidfile $DAEMON_PID 93 | } 94 | 95 | case "$1" in 96 | "start") 97 | do_start 98 | ;; 99 | "stop") 100 | do_stop 101 | ;; 102 | "restart") 103 | do_stop 104 | do_start 105 | ;; 106 | *) 107 | echo "Usage: $1 {start|stop|restart}" 108 | exit 1 109 | ;; 110 | esac 111 | -------------------------------------------------------------------------------- /packaging/vendor/multitech/conduit/files/sx1301/chirpstack-concentratord-sx1301-ap1.init: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | AP=ap1 4 | 5 | NAME="chirpstack-concentratord-sx1301" 6 | DESC="ChirpStack Concentratord SX1301" 7 | DAEMON_BIN=/opt/$NAME/$NAME 8 | DAEMON_PID=/var/run/$NAME-$AP.pid 9 | 10 | GPS_TTY_PATH=/dev/ttyXRUSB2 11 | CONF_DIR=/var/config/$NAME 12 | 13 | 14 | function read_lora_hw_info() { 15 | lora_id=$(mts-io-sysfs show $AP/product-id 2> /dev/null) 16 | lora_eui=$(mts-io-sysfs show $AP/eui 2> /dev/null) 17 | # remove all colons 18 | lora_eui_raw=${lora_eui//:/} 19 | lora_hw=$(mts-io-sysfs show $AP/hw-version 2> /dev/null) 20 | } 21 | 22 | function hardware_found() { 23 | if [[ "$lora_id" =~ "MTAC-LORA" ]]; then 24 | return 0 25 | fi 26 | 27 | return 1 28 | } 29 | 30 | copy_config() { 31 | if [ $lora_id == "MTAC-LORA-H-868" ]; then 32 | model="${lora_id,,}" 33 | model="${model//-/_}" 34 | region="EU868" 35 | band_config="eu868" 36 | channel_config="eu868_0" 37 | fi 38 | 39 | if [ $lora_id == "MTAC-LORA-H-915" ]; then 40 | model="${lora_id,,}" 41 | model="${model//-/_}" 42 | region="US915" 43 | band_config="us915" 44 | channel_config="us915_0" 45 | fi 46 | 47 | if [ -e $GPS_TTY_PATH ]; then 48 | model_flags="\"${AP^^}\", \"GNSS\"" 49 | else 50 | model_flags="\"${AP^^}\"" 51 | fi 52 | 53 | mkdir -p $CONF_DIR/$AP 54 | cp $CONF_DIR/examples/concentratord.toml $CONF_DIR/$AP/concentratord.toml 55 | cp $CONF_DIR/examples/region_$band_config.toml $CONF_DIR/$AP/region.toml 56 | cp $CONF_DIR/examples/channels_$channel_config.toml $CONF_DIR/$AP/channels.toml 57 | 58 | sed -i "s/gateway_id=.*/gateway_id=\"${lora_eui_raw}\"/" $CONF_DIR/$AP/concentratord.toml 59 | sed -i "s/region=.*/region=\"${region}\"/" $CONF_DIR/$AP/concentratord.toml 60 | sed -i "s/model=.*/model=\"multitech_${model}\"/" $CONF_DIR/$AP/concentratord.toml 61 | sed -i "s/model_flags=.*/model_flags=[${model_flags}]/" $CONF_DIR/$AP/concentratord.toml 62 | sed -i "s/event_bind=.*/event_bind=\"ipc:\/\/\/tmp\/concentratord_event_$AP\"/" $CONF_DIR/$AP/concentratord.toml 63 | sed -i "s/command_bind=.*/command_bind=\"ipc:\/\/\/tmp\/concentratord_command_$AP\"/" $CONF_DIR/$AP/concentratord.toml 64 | } 65 | 66 | function do_start { 67 | read_lora_hw_info 68 | if hardware_found; then 69 | echo "Found $lora_id with $lora_hw hardware at $AP" 70 | else 71 | echo "$0: LORA card not detected" 72 | exit 1 73 | fi 74 | 75 | if ! [ -f "$CONF_DIR/$AP/concentratord.toml" ]; then 76 | copy_config 77 | fi 78 | 79 | echo "Starting $NAME" 80 | start-stop-daemon \ 81 | --start \ 82 | --background \ 83 | --make-pidfile \ 84 | --pidfile $DAEMON_PID \ 85 | --exec $DAEMON_BIN -- -c $CONF_DIR/$AP/concentratord.toml -c $CONF_DIR/$AP/region.toml -c $CONF_DIR/$AP/channels.toml 86 | } 87 | 88 | function do_stop { 89 | echo "Stopping $NAME" 90 | start-stop-daemon \ 91 | --stop \ 92 | --oknodo \ 93 | --quiet \ 94 | --pidfile $DAEMON_PID 95 | } 96 | 97 | case "$1" in 98 | "start") 99 | do_start 100 | ;; 101 | "stop") 102 | do_stop 103 | ;; 104 | "restart") 105 | do_stop 106 | do_start 107 | ;; 108 | *) 109 | echo "Usage: $1 {start|stop|restart}" 110 | exit 1 111 | ;; 112 | esac 113 | -------------------------------------------------------------------------------- /packaging/vendor/multitech/conduit/files/sx1301/chirpstack-concentratord-sx1301-ap2.init: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | AP=ap2 4 | 5 | NAME="chirpstack-concentratord-sx1301" 6 | DESC="ChirpStack Concentratord SX1301" 7 | DAEMON_BIN=/opt/$NAME/$NAME 8 | DAEMON_PID=/var/run/$NAME-$AP.pid 9 | 10 | GPS_TTY_PATH=/dev/ttyXRUSB2 11 | CONF_DIR=/var/config/$NAME 12 | 13 | 14 | function read_lora_hw_info() { 15 | lora_id=$(mts-io-sysfs show $AP/product-id 2> /dev/null) 16 | lora_eui=$(mts-io-sysfs show $AP/eui 2> /dev/null) 17 | # remove all colons 18 | lora_eui_raw=${lora_eui//:/} 19 | lora_hw=$(mts-io-sysfs show $AP/hw-version 2> /dev/null) 20 | } 21 | 22 | function hardware_found() { 23 | if [[ "$lora_id" =~ "MTAC-LORA" ]]; then 24 | return 0 25 | fi 26 | 27 | return 1 28 | } 29 | 30 | copy_config() { 31 | if [ $lora_id == "MTAC-LORA-H-868" ]; then 32 | model="${lora_id,,}" 33 | model="${model//-/_}" 34 | region="EU868" 35 | band_config="eu868" 36 | channel_config="eu868_0" 37 | fi 38 | 39 | if [ $lora_id == "MTAC-LORA-H-915" ]; then 40 | model="${lora_id,,}" 41 | model="${model//-/_}" 42 | region="US915" 43 | band_config="us915" 44 | channel_config="us915_0" 45 | fi 46 | 47 | if [ -e $GPS_TTY_PATH ]; then 48 | model_flags="\"${AP^^}\", \"GNSS\"" 49 | else 50 | model_flags="\"${AP^^}\"" 51 | fi 52 | 53 | mkdir -p $CONF_DIR/$AP 54 | cp $CONF_DIR/examples/concentratord.toml $CONF_DIR/$AP/concentratord.toml 55 | cp $CONF_DIR/examples/region_$band_config.toml $CONF_DIR/$AP/region.toml 56 | cp $CONF_DIR/examples/channels_$channel_config.toml $CONF_DIR/$AP/channels.toml 57 | 58 | sed -i "s/gateway_id=.*/gateway_id=\"${lora_eui_raw}\"/" $CONF_DIR/$AP/concentratord.toml 59 | sed -i "s/region=.*/region=\"${region}\"/" $CONF_DIR/$AP/concentratord.toml 60 | sed -i "s/model=.*/model=\"multitech_${model}\"/" $CONF_DIR/$AP/concentratord.toml 61 | sed -i "s/model_flags=.*/model_flags=[${model_flags}]/" $CONF_DIR/$AP/concentratord.toml 62 | sed -i "s/event_bind=.*/event_bind=\"ipc:\/\/\/tmp\/concentratord_event_$AP\"/" $CONF_DIR/$AP/concentratord.toml 63 | sed -i "s/command_bind=.*/command_bind=\"ipc:\/\/\/tmp\/concentratord_command_$AP\"/" $CONF_DIR/$AP/concentratord.toml 64 | } 65 | 66 | function do_start { 67 | read_lora_hw_info 68 | if hardware_found; then 69 | echo "Found $lora_id with $lora_hw hardware at $AP" 70 | else 71 | echo "$0: LORA card not detected" 72 | exit 1 73 | fi 74 | 75 | if ! [ -f "$CONF_DIR/$AP/concentratord.toml" ]; then 76 | copy_config 77 | fi 78 | 79 | echo "Starting $NAME" 80 | start-stop-daemon \ 81 | --start \ 82 | --background \ 83 | --make-pidfile \ 84 | --pidfile $DAEMON_PID \ 85 | --exec $DAEMON_BIN -- -c $CONF_DIR/$AP/concentratord.toml -c $CONF_DIR/$AP/region.toml -c $CONF_DIR/$AP/channels.toml 86 | } 87 | 88 | function do_stop { 89 | echo "Stopping $NAME" 90 | start-stop-daemon \ 91 | --stop \ 92 | --oknodo \ 93 | --quiet \ 94 | --pidfile $DAEMON_PID 95 | } 96 | 97 | case "$1" in 98 | "start") 99 | do_start 100 | ;; 101 | "stop") 102 | do_stop 103 | ;; 104 | "restart") 105 | do_stop 106 | do_start 107 | ;; 108 | *) 109 | echo "Usage: $1 {start|stop|restart}" 110 | exit 1 111 | ;; 112 | esac 113 | --------------------------------------------------------------------------------