Refactor device-profile relay fields.
Some checks are pending
CI / tests (postgres) (push) Waiting to run
CI / tests (sqlite) (push) Waiting to run
CI / dist (postgres) (push) Blocked by required conditions
CI / dist (sqlite) (push) Blocked by required conditions

This commit is contained in:
Orne Brocaar 2025-01-15 10:32:49 +00:00
parent d521bb4790
commit 73164a9747
20 changed files with 657 additions and 386 deletions

View File

@ -24,11 +24,7 @@
# Database
email_address = "0.2"
diesel = { version = "2.2", features = [
"chrono",
"numeric",
"64-column-tables",
] }
diesel = { version = "2.2", features = ["chrono", "numeric"] }
diesel_migrations = { version = "2.2" }
diesel-async = { version = "0.5", features = [
"deadpool",

View File

@ -6,7 +6,30 @@ alter table device_profile
add column class_b_timeout integer not null default 0,
add column class_b_ping_slot_nb_k integer not null default 0,
add column class_b_ping_slot_dr smallint not null default 0,
add column class_b_ping_slot_freq bigint not null default 0;
add column class_b_ping_slot_freq bigint not null default 0,
add column class_c_timeout integer not null default 0,
add column is_relay boolean not null default false,
add column is_relay_ed boolean not null default false,
add column relay_ed_relay_only boolean not null default false,
add column relay_enabled boolean not null default false,
add column relay_cad_periodicity smallint not null default 0,
add column relay_default_channel_index smallint not null default 0,
add column relay_second_channel_freq bigint not null default 0,
add column relay_second_channel_dr smallint not null default 0,
add column relay_second_channel_ack_offset smallint not null default 0,
add column relay_ed_activation_mode smallint not null default 0,
add column relay_ed_smart_enable_level smallint not null default 0,
add column relay_ed_back_off smallint not null default 0,
add column relay_ed_uplink_limit_bucket_size smallint not null default 0,
add column relay_ed_uplink_limit_reload_rate smallint not null default 0,
add column relay_join_req_limit_reload_rate smallint not null default 0,
add column relay_notify_limit_reload_rate smallint not null default 0,
add column relay_global_uplink_limit_reload_rate smallint not null default 0,
add column relay_overall_limit_reload_rate smallint not null default 0,
add column relay_join_req_limit_bucket_size smallint not null default 0,
add column relay_notify_limit_bucket_size smallint not null default 0,
add column relay_global_uplink_limit_bucket_size smallint not null default 0,
add column relay_overall_limit_bucket_size smallint not null default 0;
update device_profile
set
@ -26,7 +49,42 @@ update device_profile
where
class_b_params is not null;
update device_profile
set
class_c_timeout = (class_c_params->'timeout')::integer
where
class_c_params is not null;
update device_profile
set
is_relay = (relay_params->'is_relay')::boolean,
is_relay_ed = (relay_params->'is_relay_ed')::boolean,
relay_ed_relay_only = (relay_params->'ed_relay_only')::boolean,
relay_enabled = (relay_params->'relay_enabled')::boolean,
relay_cad_periodicity = (relay_params->'relay_cad_periodicity')::smallint,
relay_default_channel_index = (relay_params->'default_channel_index')::smallint,
relay_second_channel_freq = (relay_params->'second_channel_freq')::bigint,
relay_second_channel_dr = (relay_params->'second_channel_dr')::smallint,
relay_second_channel_ack_offset = (relay_params->'second_channel_ack_offset')::smallint,
relay_ed_activation_mode = (relay_params->'ed_activation_mode')::smallint,
relay_ed_smart_enable_level = (relay_params->'ed_smart_enable_level')::smallint,
relay_ed_back_off = (relay_params->'ed_back_off')::smallint,
relay_ed_uplink_limit_bucket_size = (relay_params->'ed_uplink_limit_bucket_size')::smallint,
relay_ed_uplink_limit_reload_rate = (relay_params->'ed_uplink_limit_reload_rate')::smallint,
relay_join_req_limit_reload_rate = (relay_params->'relay_join_req_limit_reload_rate')::smallint,
relay_notify_limit_reload_rate = (relay_params->'relay_notify_limit_reload_rate')::smallint,
relay_global_uplink_limit_reload_rate = (relay_params->'relay_global_uplink_limit_reload_rate')::smallint,
relay_overall_limit_reload_rate = (relay_params->'relay_overall_limit_reload_rate')::smallint,
relay_join_req_limit_bucket_size = (relay_params->'relay_join_req_limit_bucket_size')::smallint,
relay_notify_limit_bucket_size = (relay_params->'relay_notify_limit_bucket_size')::smallint,
relay_global_uplink_limit_bucket_size = (relay_params->'relay_global_uplink_limit_bucket_size')::smallint,
relay_overall_limit_bucket_size = (relay_params->'relay_overall_limit_bucket_size')::smallint
where
relay_params is not null;
alter table device_profile
drop column abp_params,
drop column class_b_params;
drop column class_b_params,
drop column class_c_params,
drop column relay_params;

View File

@ -1,7 +1,8 @@
alter table device_profile
add column abp_params jsonb null,
add column class_b_params jsonb null,
add column class_c_params jsonb null;
add column class_c_params jsonb null,
add column relay_params jsonb null;
update device_profile
set abp_params = json_build_object(
@ -25,6 +26,33 @@ update device_profile
where
supports_class_c = true;
update device_profile
set relay_params = json_build_object(
'is_relay', is_relay,
'is_relay_ed', is_relay_ed,
'ed_relay_only', relay_ed_relay_only,
'relay_enabled', relay_enabled,
'relay_cad_periodicity', relay_cad_periodicity,
'default_channel_index', relay_default_channel_index,
'second_channel_freq', relay_second_channel_freq,
'second_channel_dr', relay_second_channel_dr,
'second_channel_ack_offset', relay_second_channel_ack_offset,
'ed_activation_mode', relay_ed_activation_mode,
'ed_smart_enable_level', relay_ed_smart_enable_level,
'ed_back_off', relay_ed_back_off,
'ed_uplink_limit_bucket_size', relay_ed_uplink_limit_bucket_size,
'ed_uplink_limit_reload_rate', relay_ed_uplink_limit_reload_rate,
'relay_join_req_limit_reload_rate', relay_join_req_limit_reload_rate,
'relay_notify_limit_reload_rate', relay_notify_limit_reload_rate,
'relay_global_uplink_limit_reload_rate', relay_global_uplink_limit_reload_rate,
'relay_overall_limit_reload_rate', relay_overall_limit_reload_rate,
'relay_notify_limit_bucket_size', relay_join_req_limit_bucket_size,
'relay_notify_limit_bucket_size', relay_notify_limit_bucket_size,
'relay_global_uplink_limit_bucket_size', relay_global_uplink_limit_bucket_size,
'relay_overall_limit_bucket_size', relay_overall_limit_bucket_size)
where
is_relay = true or is_relay_ed = true;
alter table device_profile
drop column abp_rx1_delay,
drop column abp_rx1_dr_offset,
@ -34,5 +62,27 @@ alter table device_profile
drop column class_b_ping_slot_nb_k,
drop column class_b_ping_slot_dr,
drop column class_b_ping_slot_freq,
drop column class_c_timeout;
drop column class_c_timeout,
drop column is_relay,
drop column is_relay_ed,
drop column relay_ed_relay_only,
drop column relay_enabled,
drop column relay_cad_periodicity,
drop column relay_default_channel_index,
drop column relay_second_channel_freq,
drop column relay_second_channel_dr,
drop column relay_second_channel_ack_offset,
drop column relay_ed_activation_mode,
drop column relay_ed_smart_enable_level,
drop column relay_ed_back_off,
drop column relay_ed_uplink_limit_bucket_size,
drop column relay_ed_uplink_limit_reload_rate,
drop column relay_join_req_limit_reload_rate,
drop column relay_notify_limit_reload_rate,
drop column relay_global_uplink_limit_reload_rate,
drop column relay_overall_limit_reload_rate,
drop column relay_join_req_limit_bucket_size,
drop column relay_notify_limit_bucket_size,
drop column relay_global_uplink_limit_bucket_size,
drop column relay_overall_limit_bucket_size;

View File

@ -7,6 +7,28 @@ alter table device_profile add column class_b_ping_slot_nb_k integer not null de
alter table device_profile add column class_b_ping_slot_dr smallint not null default 0;
alter table device_profile add column class_b_ping_slot_freq bigint not null default 0;
alter table device_profile add column class_c_timeout integer not null default 0;
alter table device_profile add column is_relay boolean not null default false;
alter table device_profile add column is_relay_ed boolean not null default false;
alter table device_profile add column relay_ed_relay_only boolean not null default false;
alter table device_profile add column relay_enabled boolean not null default false;
alter table device_profile add column relay_cad_periodicity smallint not null default 0;
alter table device_profile add column relay_default_channel_index smallint not null default 0;
alter table device_profile add column relay_second_channel_freq bigint not null default 0;
alter table device_profile add column relay_second_channel_dr smallint not null default 0;
alter table device_profile add column relay_second_channel_ack_offset smallint not null default 0;
alter table device_profile add column relay_ed_activation_mode smallint not null default 0;
alter table device_profile add column relay_ed_smart_enable_level smallint not null default 0;
alter table device_profile add column relay_ed_back_off smallint not null default 0;
alter table device_profile add column relay_ed_uplink_limit_bucket_size smallint not null default 0;
alter table device_profile add column relay_ed_uplink_limit_reload_rate smallint not null default 0;
alter table device_profile add column relay_join_req_limit_reload_rate smallint not null default 0;
alter table device_profile add column relay_notify_limit_reload_rate smallint not null default 0;
alter table device_profile add column relay_global_uplink_limit_reload_rate smallint not null default 0;
alter table device_profile add column relay_overall_limit_reload_rate smallint not null default 0;
alter table device_profile add column relay_join_req_limit_bucket_size smallint not null default 0;
alter table device_profile add column relay_notify_limit_bucket_size smallint not null default 0;
alter table device_profile add column relay_global_uplink_limit_bucket_size smallint not null default 0;
alter table device_profile add column relay_overall_limit_bucket_size smallint not null default 0;
update device_profile
set
@ -32,7 +54,35 @@ update device_profile
where
class_c_params is not null;
update device_profile
set
is_relay = relay_params->'is_relay',
is_relay_ed = relay_params->'is_relay_ed',
relay_ed_relay_only = relay_params->'ed_relay_only',
relay_enabled = relay_params->'relay_enabled',
relay_cad_periodicity = relay_params->'relay_cad_periodicity',
relay_default_channel_index = relay_params->'default_channel_index',
relay_second_channel_freq = relay_params->'second_channel_freq',
relay_second_channel_dr = relay_params->'second_channel_dr',
relay_second_channel_ack_offset = relay_params->'second_channel_ack_offset',
relay_ed_activation_mode = relay_params->'ed_activation_mode',
relay_ed_smart_enable_level = relay_params->'ed_smart_enable_level',
relay_ed_back_off = relay_params->'ed_back_off',
relay_ed_uplink_limit_bucket_size = relay_params->'ed_uplink_limit_bucket_size',
relay_ed_uplink_limit_reload_rate = relay_params->'ed_uplink_limit_reload_rate',
relay_join_req_limit_reload_rate = relay_params->'relay_join_req_limit_reload_rate',
relay_notify_limit_reload_rate = relay_params->'relay_notify_limit_reload_rate',
relay_global_uplink_limit_reload_rate = relay_params->'relay_global_uplink_limit_reload_rate',
relay_overall_limit_reload_rate = relay_params->'relay_overall_limit_reload_rate',
relay_join_req_limit_bucket_size = relay_params->'relay_join_req_limit_bucket_size',
relay_notify_limit_bucket_size = relay_params->'relay_notify_limit_bucket_size',
relay_global_uplink_limit_bucket_size = relay_params->'relay_global_uplink_limit_bucket_size',
relay_overall_limit_bucket_size = relay_params->'relay_overall_limit_bucket_size'
where
relay_params is not null;
alter table device_profile drop column abp_params;
alter table device_profile drop column class_b_params;
alter table device_profile drop column class_c_params;
alter table device_profile drop column relay_params;

View File

@ -1,6 +1,7 @@
alter table device_profile add column abp_params text null;
alter table device_profile add column class_b_params text null;
alter table device_profile add column class_c_params text null;
alter table device_profile add column relay_params text null;
update device_profile
set abp_params = json_object(
@ -23,6 +24,32 @@ update device_profile
'timeout', class_c_timeout)
where supports_class_c = true;
update device_profile
set relay_params = json_object(
'is_relay', is_relay,
'is_relay_ed', is_relay_ed,
'ed_relay_only', relay_ed_relay_only,
'relay_enabled', relay_enabled,
'relay_cad_periodicity', relay_cad_periodicity,
'default_channel_index', relay_default_channel_index,
'second_channel_freq', relay_second_channel_freq,
'second_channel_dr', relay_second_channel_dr,
'second_channel_ack_offset', relay_second_channel_ack_offset,
'ed_activation_mode', relay_ed_activation_mode,
'ed_smart_enable_level', relay_ed_smart_enable_level,
'ed_back_off', relay_ed_back_off,
'ed_uplink_limit_bucket_size', relay_ed_uplink_limit_bucket_size,
'ed_uplink_limit_reload_rate', relay_ed_uplink_limit_reload_rate,
'relay_join_req_limit_reload_rate', relay_join_req_limit_reload_rate,
'relay_notify_limit_reload_rate', relay_notify_limit_reload_rate,
'relay_global_uplink_limit_reload_rate', relay_global_uplink_limit_reload_rate,
'relay_overall_limit_reload_rate', relay_overall_limit_reload_rate,
'relay_notify_limit_bucket_size', relay_join_req_limit_bucket_size,
'relay_notify_limit_bucket_size', relay_notify_limit_bucket_size,
'relay_global_uplink_limit_bucket_size', relay_global_uplink_limit_bucket_size,
'relay_overall_limit_bucket_size', relay_overall_limit_bucket_size)
where is_relay = true or is_relay_ed is true;
alter table device_profile drop column abp_rx1_delay;
alter table device_profile drop column abp_rx1_dr_offset;
alter table device_profile drop column abp_rx2_dr;
@ -34,3 +61,27 @@ alter table device_profile drop column class_b_ping_slot_dr;
alter table device_profile drop column class_b_ping_slot_freq;
alter table device_profile drop column class_c_timeout;
alter table device_profile drop column is_relay;
alter table device_profile drop column is_relay_ed;
alter table device_profile drop column relay_ed_relay_only;
alter table device_profile drop column relay_enabled;
alter table device_profile drop column relay_cad_periodicity;
alter table device_profile drop column relay_default_channel_index;
alter table device_profile drop column relay_second_channel_freq;
alter table device_profile drop column relay_second_channel_dr;
alter table device_profile drop column relay_second_channel_ack_offset;
alter table device_profile drop column relay_ed_activation_mode;
alter table device_profile drop column relay_ed_smart_enable_level;
alter table device_profile drop column relay_ed_back_off;
alter table device_profile drop column relay_ed_uplink_limit_bucket_size;
alter table device_profile drop column relay_ed_uplink_limit_reload_rate;
alter table device_profile drop column relay_join_req_limit_reload_rate;
alter table device_profile drop column relay_notify_limit_reload_rate;
alter table device_profile drop column relay_global_uplink_limit_reload_rate;
alter table device_profile drop column relay_overall_limit_reload_rate;
alter table device_profile drop column relay_join_req_limit_bucket_size;
alter table device_profile drop column relay_notify_limit_bucket_size;
alter table device_profile drop column relay_global_uplink_limit_bucket_size;
alter table device_profile drop column relay_overall_limit_bucket_size;

View File

@ -79,30 +79,6 @@ impl DeviceProfileService for DeviceProfile {
auto_detect_measurements: req_dp.auto_detect_measurements,
region_config_id: (!req_dp.region_config_id.is_empty())
.then(|| req_dp.region_config_id.clone()),
is_relay: req_dp.is_relay,
is_relay_ed: req_dp.is_relay_ed,
relay_ed_relay_only: req_dp.relay_ed_relay_only,
relay_enabled: req_dp.relay_enabled,
relay_cad_periodicity: req_dp.relay_cad_periodicity as i16,
relay_default_channel_index: req_dp.relay_default_channel_index as i16,
relay_second_channel_freq: req_dp.relay_second_channel_freq as i64,
relay_second_channel_dr: req_dp.relay_second_channel_dr as i16,
relay_second_channel_ack_offset: req_dp.relay_second_channel_ack_offset as i16,
relay_ed_activation_mode: req_dp.relay_ed_activation_mode().from_proto(),
relay_ed_smart_enable_level: req_dp.relay_ed_smart_enable_level as i16,
relay_ed_back_off: req_dp.relay_ed_back_off as i16,
relay_ed_uplink_limit_bucket_size: req_dp.relay_ed_uplink_limit_bucket_size as i16,
relay_ed_uplink_limit_reload_rate: req_dp.relay_ed_uplink_limit_reload_rate as i16,
relay_join_req_limit_reload_rate: req_dp.relay_join_req_limit_reload_rate as i16,
relay_notify_limit_reload_rate: req_dp.relay_notify_limit_reload_rate as i16,
relay_global_uplink_limit_reload_rate: req_dp.relay_global_uplink_limit_reload_rate
as i16,
relay_overall_limit_reload_rate: req_dp.relay_overall_limit_reload_rate as i16,
relay_join_req_limit_bucket_size: req_dp.relay_join_req_limit_bucket_size as i16,
relay_notify_limit_bucket_size: req_dp.relay_notify_limit_bucket_size as i16,
relay_global_uplink_limit_bucket_size: req_dp.relay_global_uplink_limit_bucket_size
as i16,
relay_overall_limit_bucket_size: req_dp.relay_overall_limit_bucket_size as i16,
allow_roaming: req_dp.allow_roaming,
rx1_delay: req_dp.rx1_delay as i16,
abp_params: if req_dp.supports_otaa {
@ -132,6 +108,38 @@ impl DeviceProfileService for DeviceProfile {
} else {
None
},
relay_params: if req_dp.is_relay || req_dp.is_relay_ed {
Some(fields::RelayParams {
is_relay: req_dp.is_relay,
is_relay_ed: req_dp.is_relay_ed,
ed_relay_only: req_dp.relay_ed_relay_only,
relay_enabled: req_dp.relay_enabled,
relay_cad_periodicity: req_dp.relay_cad_periodicity as u8,
default_channel_index: req_dp.relay_default_channel_index as u8,
second_channel_freq: req_dp.relay_second_channel_freq as u32,
second_channel_dr: req_dp.relay_second_channel_dr as u8,
second_channel_ack_offset: req_dp.relay_second_channel_ack_offset as u8,
ed_activation_mode: req_dp.relay_ed_activation_mode().from_proto(),
ed_smart_enable_level: req_dp.relay_ed_smart_enable_level as u8,
ed_back_off: req_dp.relay_ed_back_off as u8,
ed_uplink_limit_bucket_size: req_dp.relay_ed_uplink_limit_bucket_size as u8,
ed_uplink_limit_reload_rate: req_dp.relay_ed_uplink_limit_reload_rate as u8,
relay_join_req_limit_reload_rate: req_dp.relay_join_req_limit_reload_rate as u8,
relay_notify_limit_reload_rate: req_dp.relay_notify_limit_reload_rate as u8,
relay_global_uplink_limit_reload_rate: req_dp
.relay_global_uplink_limit_reload_rate
as u8,
relay_overall_limit_reload_rate: req_dp.relay_overall_limit_reload_rate as u8,
relay_join_req_limit_bucket_size: req_dp.relay_join_req_limit_bucket_size as u8,
relay_notify_limit_bucket_size: req_dp.relay_notify_limit_bucket_size as u8,
relay_global_uplink_limit_bucket_size: req_dp
.relay_global_uplink_limit_bucket_size
as u8,
relay_overall_limit_bucket_size: req_dp.relay_overall_limit_bucket_size as u8,
})
} else {
None
},
..Default::default()
};
@ -166,6 +174,7 @@ impl DeviceProfileService for DeviceProfile {
let abp_params = dp.abp_params.clone().unwrap_or_default();
let class_b_params = dp.class_b_params.clone().unwrap_or_default();
let class_c_params = dp.class_c_params.clone().unwrap_or_default();
let relay_params = dp.relay_params.clone().unwrap_or_default();
let mut resp = Response::new(api::GetDeviceProfileResponse {
device_profile: Some(api::DeviceProfile {
@ -211,30 +220,36 @@ impl DeviceProfileService for DeviceProfile {
.collect(),
auto_detect_measurements: dp.auto_detect_measurements,
region_config_id: dp.region_config_id.clone().unwrap_or_default(),
is_relay: dp.is_relay,
is_relay_ed: dp.is_relay_ed,
relay_ed_relay_only: dp.relay_ed_relay_only,
relay_enabled: dp.relay_enabled,
relay_cad_periodicity: dp.relay_cad_periodicity as i32,
relay_default_channel_index: dp.relay_default_channel_index as u32,
relay_second_channel_freq: dp.relay_second_channel_freq as u32,
relay_second_channel_dr: dp.relay_second_channel_dr as u32,
relay_second_channel_ack_offset: dp.relay_second_channel_ack_offset as i32,
relay_ed_activation_mode: dp.relay_ed_activation_mode.to_proto().into(),
relay_ed_smart_enable_level: dp.relay_ed_smart_enable_level as u32,
relay_ed_back_off: dp.relay_ed_back_off as u32,
relay_ed_uplink_limit_bucket_size: dp.relay_ed_uplink_limit_bucket_size as u32,
relay_ed_uplink_limit_reload_rate: dp.relay_ed_uplink_limit_reload_rate as u32,
relay_join_req_limit_reload_rate: dp.relay_join_req_limit_reload_rate as u32,
relay_notify_limit_reload_rate: dp.relay_notify_limit_reload_rate as u32,
relay_global_uplink_limit_reload_rate: dp.relay_global_uplink_limit_reload_rate
is_relay: relay_params.is_relay,
is_relay_ed: relay_params.is_relay_ed,
relay_ed_relay_only: relay_params.ed_relay_only,
relay_enabled: relay_params.relay_enabled,
relay_cad_periodicity: relay_params.relay_cad_periodicity as i32,
relay_default_channel_index: relay_params.default_channel_index as u32,
relay_second_channel_freq: relay_params.second_channel_freq as u32,
relay_second_channel_dr: relay_params.second_channel_dr as u32,
relay_second_channel_ack_offset: relay_params.second_channel_ack_offset as i32,
relay_ed_activation_mode: relay_params.ed_activation_mode.to_proto().into(),
relay_ed_smart_enable_level: relay_params.ed_smart_enable_level as u32,
relay_ed_back_off: relay_params.ed_back_off as u32,
relay_ed_uplink_limit_bucket_size: relay_params.ed_uplink_limit_bucket_size as u32,
relay_ed_uplink_limit_reload_rate: relay_params.ed_uplink_limit_reload_rate as u32,
relay_join_req_limit_reload_rate: relay_params.relay_join_req_limit_reload_rate
as u32,
relay_overall_limit_reload_rate: dp.relay_overall_limit_reload_rate as u32,
relay_join_req_limit_bucket_size: dp.relay_join_req_limit_bucket_size as u32,
relay_notify_limit_bucket_size: dp.relay_notify_limit_bucket_size as u32,
relay_global_uplink_limit_bucket_size: dp.relay_global_uplink_limit_bucket_size
relay_notify_limit_reload_rate: relay_params.relay_notify_limit_reload_rate as u32,
relay_global_uplink_limit_reload_rate: relay_params
.relay_global_uplink_limit_reload_rate
as u32,
relay_overall_limit_reload_rate: relay_params.relay_overall_limit_reload_rate
as u32,
relay_join_req_limit_bucket_size: relay_params.relay_join_req_limit_bucket_size
as u32,
relay_notify_limit_bucket_size: relay_params.relay_notify_limit_bucket_size as u32,
relay_global_uplink_limit_bucket_size: relay_params
.relay_global_uplink_limit_bucket_size
as u32,
relay_overall_limit_bucket_size: relay_params.relay_overall_limit_bucket_size
as u32,
relay_overall_limit_bucket_size: dp.relay_overall_limit_bucket_size as u32,
allow_roaming: dp.allow_roaming,
rx1_delay: dp.rx1_delay as u32,
}),
@ -302,30 +317,6 @@ impl DeviceProfileService for DeviceProfile {
auto_detect_measurements: req_dp.auto_detect_measurements,
region_config_id: (!req_dp.region_config_id.is_empty())
.then(|| req_dp.region_config_id.clone()),
is_relay: req_dp.is_relay,
is_relay_ed: req_dp.is_relay_ed,
relay_ed_relay_only: req_dp.relay_ed_relay_only,
relay_enabled: req_dp.relay_enabled,
relay_cad_periodicity: req_dp.relay_cad_periodicity as i16,
relay_default_channel_index: req_dp.relay_default_channel_index as i16,
relay_second_channel_freq: req_dp.relay_second_channel_freq as i64,
relay_second_channel_dr: req_dp.relay_second_channel_dr as i16,
relay_second_channel_ack_offset: req_dp.relay_second_channel_ack_offset as i16,
relay_ed_activation_mode: req_dp.relay_ed_activation_mode().from_proto(),
relay_ed_smart_enable_level: req_dp.relay_ed_smart_enable_level as i16,
relay_ed_back_off: req_dp.relay_ed_back_off as i16,
relay_ed_uplink_limit_bucket_size: req_dp.relay_ed_uplink_limit_bucket_size as i16,
relay_ed_uplink_limit_reload_rate: req_dp.relay_ed_uplink_limit_reload_rate as i16,
relay_join_req_limit_reload_rate: req_dp.relay_join_req_limit_reload_rate as i16,
relay_notify_limit_reload_rate: req_dp.relay_notify_limit_reload_rate as i16,
relay_global_uplink_limit_reload_rate: req_dp.relay_global_uplink_limit_reload_rate
as i16,
relay_overall_limit_reload_rate: req_dp.relay_overall_limit_reload_rate as i16,
relay_join_req_limit_bucket_size: req_dp.relay_join_req_limit_bucket_size as i16,
relay_notify_limit_bucket_size: req_dp.relay_notify_limit_bucket_size as i16,
relay_global_uplink_limit_bucket_size: req_dp.relay_global_uplink_limit_bucket_size
as i16,
relay_overall_limit_bucket_size: req_dp.relay_overall_limit_bucket_size as i16,
allow_roaming: req_dp.allow_roaming,
rx1_delay: req_dp.rx1_delay as i16,
abp_params: if req_dp.supports_otaa {
@ -355,6 +346,38 @@ impl DeviceProfileService for DeviceProfile {
} else {
None
},
relay_params: if req_dp.is_relay || req_dp.is_relay_ed {
Some(fields::RelayParams {
is_relay: req_dp.is_relay,
is_relay_ed: req_dp.is_relay_ed,
ed_relay_only: req_dp.relay_ed_relay_only,
relay_enabled: req_dp.relay_enabled,
relay_cad_periodicity: req_dp.relay_cad_periodicity as u8,
default_channel_index: req_dp.relay_default_channel_index as u8,
second_channel_freq: req_dp.relay_second_channel_freq as u32,
second_channel_dr: req_dp.relay_second_channel_dr as u8,
second_channel_ack_offset: req_dp.relay_second_channel_ack_offset as u8,
ed_activation_mode: req_dp.relay_ed_activation_mode().from_proto(),
ed_smart_enable_level: req_dp.relay_ed_smart_enable_level as u8,
ed_back_off: req_dp.relay_ed_back_off as u8,
ed_uplink_limit_bucket_size: req_dp.relay_ed_uplink_limit_bucket_size as u8,
ed_uplink_limit_reload_rate: req_dp.relay_ed_uplink_limit_reload_rate as u8,
relay_join_req_limit_reload_rate: req_dp.relay_join_req_limit_reload_rate as u8,
relay_notify_limit_reload_rate: req_dp.relay_notify_limit_reload_rate as u8,
relay_global_uplink_limit_reload_rate: req_dp
.relay_global_uplink_limit_reload_rate
as u8,
relay_overall_limit_reload_rate: req_dp.relay_overall_limit_reload_rate as u8,
relay_join_req_limit_bucket_size: req_dp.relay_join_req_limit_bucket_size as u8,
relay_notify_limit_bucket_size: req_dp.relay_notify_limit_bucket_size as u8,
relay_global_uplink_limit_bucket_size: req_dp
.relay_global_uplink_limit_bucket_size
as u8,
relay_overall_limit_bucket_size: req_dp.relay_overall_limit_bucket_size as u8,
})
} else {
None
},
..Default::default()
})
.await

View File

@ -182,7 +182,7 @@ pub mod test {
use super::*;
use crate::api::auth::validator::RequestValidator;
use crate::api::auth::AuthID;
use crate::storage::{application, device, device_profile, tenant, user};
use crate::storage::{application, device, device_profile, fields, tenant, user};
use crate::test;
#[tokio::test]
@ -229,7 +229,10 @@ pub mod test {
let dp_relay = device_profile::create(device_profile::DeviceProfile {
name: "test-dp".into(),
tenant_id: t.id,
is_relay: true,
relay_params: Some(fields::RelayParams {
is_relay: true,
..Default::default()
}),
..Default::default()
})
.await

View File

@ -643,16 +643,18 @@ impl Data {
self._set_rx_parameters().await?;
self._set_tx_parameters().await?;
if self.device_profile.is_relay {
self._update_relay_conf().await?;
self._update_filter_list().await?;
self._update_uplink_list().await?;
self._request_ctrl_uplink_list().await?;
self._configure_fwd_limit_req().await?;
}
if let Some(relay_params) = self.device_profile.relay_params.clone() {
if relay_params.is_relay {
self._update_relay_conf().await?;
self._update_filter_list().await?;
self._update_uplink_list().await?;
self._request_ctrl_uplink_list().await?;
self._configure_fwd_limit_req().await?;
}
if self.device_profile.is_relay_ed {
self._update_end_device_conf().await?;
if relay_params.is_relay_ed {
self._update_end_device_conf().await?;
}
}
let ds = self.device.get_device_session()?;
@ -1799,6 +1801,7 @@ impl Data {
let dev_eui = self.device.dev_eui;
let ds = self.device.get_device_session_mut()?;
let relay_params = self.device_profile.relay_params.clone().unwrap_or_default();
// Get the current relay state.
let relay = if let Some(r) = &ds.relay {
@ -1807,48 +1810,37 @@ impl Data {
internal::Relay::default()
};
if relay.join_req_limit_reload_rate
!= self.device_profile.relay_join_req_limit_reload_rate as u32
|| relay.notify_limit_reload_rate
!= self.device_profile.relay_notify_limit_reload_rate as u32
if relay.join_req_limit_reload_rate != relay_params.relay_join_req_limit_reload_rate as u32
|| relay.notify_limit_reload_rate != relay_params.relay_notify_limit_reload_rate as u32
|| relay.global_uplink_limit_reload_rate
!= self.device_profile.relay_global_uplink_limit_reload_rate as u32
!= relay_params.relay_global_uplink_limit_reload_rate as u32
|| relay.overall_limit_reload_rate
!= self.device_profile.relay_overall_limit_reload_rate as u32
!= relay_params.relay_overall_limit_reload_rate as u32
|| relay.join_req_limit_bucket_size
!= self.device_profile.relay_join_req_limit_bucket_size as u32
|| relay.notify_limit_bucket_size
!= self.device_profile.relay_notify_limit_bucket_size as u32
!= relay_params.relay_join_req_limit_bucket_size as u32
|| relay.notify_limit_bucket_size != relay_params.relay_notify_limit_bucket_size as u32
|| relay.global_uplink_limit_bucket_size
!= self.device_profile.relay_global_uplink_limit_bucket_size as u32
!= relay_params.relay_global_uplink_limit_bucket_size as u32
|| relay.overall_limit_bucket_size
!= self.device_profile.relay_overall_limit_bucket_size as u32
!= relay_params.relay_overall_limit_bucket_size as u32
{
let set = lrwn::MACCommandSet::new(vec![lrwn::MACCommand::ConfigureFwdLimitReq(
lrwn::ConfigureFwdLimitReqPayload {
reload_rate: lrwn::FwdLimitReloadRatePL {
overall_reload_rate: self.device_profile.relay_overall_limit_reload_rate
as u8,
global_uplink_reload_rate: self
.device_profile
overall_reload_rate: relay_params.relay_overall_limit_reload_rate as u8,
global_uplink_reload_rate: relay_params
.relay_global_uplink_limit_reload_rate
as u8,
notify_reload_rate: self.device_profile.relay_notify_limit_reload_rate
as u8,
join_req_reload_rate: self.device_profile.relay_join_req_limit_reload_rate
as u8,
notify_reload_rate: relay_params.relay_notify_limit_reload_rate as u8,
join_req_reload_rate: relay_params.relay_join_req_limit_reload_rate as u8,
reset_limit_counter: lrwn::ResetLimitCounter::NoChange,
},
load_capacity: lrwn::FwdLimitLoadCapacityPL {
overall_limit_size: self.device_profile.relay_overall_limit_bucket_size
as u8,
global_uplink_limit_size: self
.device_profile
.relay_global_uplink_limit_bucket_size
as u8,
notify_limit_size: self.device_profile.relay_notify_limit_bucket_size as u8,
join_req_limit_size: self.device_profile.relay_join_req_limit_bucket_size
overall_limit_size: relay_params.relay_overall_limit_bucket_size as u8,
global_uplink_limit_size: relay_params.relay_global_uplink_limit_bucket_size
as u8,
notify_limit_size: relay_params.relay_notify_limit_bucket_size as u8,
join_req_limit_size: relay_params.relay_join_req_limit_bucket_size as u8,
},
},
)]);
@ -2048,6 +2040,7 @@ impl Data {
let dev_eui = self.device.dev_eui;
let ds = self.device.get_device_session_mut()?;
let relay_params = self.device_profile.relay_params.clone().unwrap_or_default();
// Get the current relay state.
let relay = if let Some(r) = &ds.relay {
@ -2056,33 +2049,31 @@ impl Data {
internal::Relay::default()
};
if relay.enabled != self.device_profile.relay_enabled
|| relay.cad_periodicity != self.device_profile.relay_cad_periodicity as u32
|| relay.default_channel_index != self.device_profile.relay_default_channel_index as u32
|| relay.second_channel_freq != self.device_profile.relay_second_channel_freq as u32
|| relay.second_channel_dr != self.device_profile.relay_second_channel_dr as u32
|| relay.second_channel_ack_offset
!= self.device_profile.relay_second_channel_ack_offset as u32
if relay.enabled != relay_params.relay_enabled
|| relay.cad_periodicity != relay_params.relay_cad_periodicity as u32
|| relay.default_channel_index != relay_params.default_channel_index as u32
|| relay.second_channel_freq != relay_params.second_channel_freq as u32
|| relay.second_channel_dr != relay_params.second_channel_dr as u32
|| relay.second_channel_ack_offset != relay_params.second_channel_ack_offset as u32
{
let set = lrwn::MACCommandSet::new(vec![lrwn::MACCommand::RelayConfReq(
lrwn::RelayConfReqPayload {
channel_settings_relay: lrwn::ChannelSettingsRelay {
start_stop: match self.device_profile.relay_enabled {
start_stop: match relay_params.relay_enabled {
true => 1,
false => 0,
},
cad_periodicity: self.device_profile.relay_cad_periodicity as u8,
default_ch_idx: self.device_profile.relay_default_channel_index as u8,
second_ch_idx: if self.device_profile.relay_second_channel_freq > 0 {
cad_periodicity: relay_params.relay_cad_periodicity as u8,
default_ch_idx: relay_params.default_channel_index as u8,
second_ch_idx: if relay_params.second_channel_freq > 0 {
1
} else {
0
},
second_ch_dr: self.device_profile.relay_second_channel_dr as u8,
second_ch_ack_offset: self.device_profile.relay_second_channel_ack_offset
as u8,
second_ch_dr: relay_params.second_channel_dr as u8,
second_ch_ack_offset: relay_params.second_channel_ack_offset as u8,
},
second_ch_freq: self.device_profile.relay_second_channel_freq as u32,
second_ch_freq: relay_params.second_channel_freq as u32,
},
)]);
mac_command::set_pending(&dev_eui, lrwn::CID::RelayConfReq, &set).await?;
@ -2099,6 +2090,7 @@ impl Data {
let dev_eui = self.device.dev_eui;
let ds = self.device.get_device_session_mut()?;
let relay_params = self.device_profile.relay_params.clone().unwrap_or_default();
// Get the current relay state.
let relay = if let Some(r) = &ds.relay {
@ -2107,32 +2099,30 @@ impl Data {
internal::Relay::default()
};
if relay.ed_activation_mode != self.device_profile.relay_ed_activation_mode.to_u8() as u32
|| relay.ed_smart_enable_level != self.device_profile.relay_ed_smart_enable_level as u32
|| relay.ed_back_off != self.device_profile.relay_ed_back_off as u32
|| relay.second_channel_freq != self.device_profile.relay_second_channel_freq as u32
|| relay.second_channel_dr != self.device_profile.relay_second_channel_dr as u32
|| relay.second_channel_ack_offset
!= self.device_profile.relay_second_channel_ack_offset as u32
if relay.ed_activation_mode != relay_params.ed_activation_mode.to_u8() as u32
|| relay.ed_smart_enable_level != relay_params.ed_smart_enable_level as u32
|| relay.ed_back_off != relay_params.ed_back_off as u32
|| relay.second_channel_freq != relay_params.second_channel_freq as u32
|| relay.second_channel_dr != relay_params.second_channel_dr as u32
|| relay.second_channel_ack_offset != relay_params.second_channel_ack_offset as u32
{
let set = lrwn::MACCommandSet::new(vec![lrwn::MACCommand::EndDeviceConfReq(
lrwn::EndDeviceConfReqPayload {
activation_relay_mode: lrwn::ActivationRelayMode {
relay_mode_activation: self.device_profile.relay_ed_activation_mode,
smart_enable_level: self.device_profile.relay_ed_smart_enable_level as u8,
relay_mode_activation: relay_params.ed_activation_mode,
smart_enable_level: relay_params.ed_smart_enable_level as u8,
},
channel_settings_ed: lrwn::ChannelSettingsED {
second_ch_ack_offset: self.device_profile.relay_second_channel_ack_offset
as u8,
second_ch_dr: self.device_profile.relay_second_channel_dr as u8,
second_ch_idx: if self.device_profile.relay_second_channel_freq > 0 {
second_ch_ack_offset: relay_params.second_channel_ack_offset as u8,
second_ch_dr: relay_params.second_channel_dr as u8,
second_ch_idx: if relay_params.second_channel_freq > 0 {
1
} else {
0
},
backoff: self.device_profile.relay_ed_back_off as u8,
backoff: relay_params.ed_back_off as u8,
},
second_ch_freq: self.device_profile.relay_second_channel_freq as u32,
second_ch_freq: relay_params.second_channel_freq as u32,
},
)]);
mac_command::set_pending(&dev_eui, lrwn::CID::EndDeviceConfReq, &set).await?;
@ -2696,6 +2686,7 @@ fn filter_mac_commands(
#[cfg(test)]
mod test {
use super::*;
use crate::storage::fields;
use crate::test;
use lrwn::{DevAddr, EUI64};
use tokio::time::sleep;
@ -2715,7 +2706,10 @@ mod test {
let dp = device_profile::create(device_profile::DeviceProfile {
name: "dp".into(),
tenant_id: t.id,
is_relay: true,
relay_params: Some(fields::RelayParams {
is_relay: true,
..Default::default()
}),
..Default::default()
})
.await
@ -3440,7 +3434,10 @@ mod test {
let dp_relay = device_profile::create(device_profile::DeviceProfile {
name: "dp-relay".into(),
tenant_id: t.id,
is_relay: true,
relay_params: Some(fields::RelayParams {
is_relay: true,
..Default::default()
}),
..Default::default()
})
.await
@ -3449,9 +3446,12 @@ mod test {
let dp_ed = device_profile::create(device_profile::DeviceProfile {
name: "dp-ed".into(),
tenant_id: t.id,
is_relay_ed: true,
relay_ed_uplink_limit_bucket_size: 2,
relay_ed_uplink_limit_reload_rate: 1,
relay_params: Some(fields::RelayParams {
is_relay_ed: true,
ed_uplink_limit_bucket_size: 2,
ed_uplink_limit_reload_rate: 1,
..Default::default()
}),
..Default::default()
})
.await
@ -3900,7 +3900,10 @@ mod test {
let dp_relay = device_profile::create(device_profile::DeviceProfile {
name: "dp-relay".into(),
tenant_id: t.id,
is_relay: true,
relay_params: Some(fields::RelayParams {
is_relay: true,
..Default::default()
}),
..Default::default()
})
.await
@ -4023,13 +4026,16 @@ mod test {
..Default::default()
},
device_profile: device_profile::DeviceProfile {
is_relay: true,
relay_enabled: true,
relay_cad_periodicity: 1,
relay_default_channel_index: 0,
relay_second_channel_freq: 868300000,
relay_second_channel_dr: 3,
relay_second_channel_ack_offset: 2,
relay_params: Some(fields::RelayParams {
is_relay: true,
relay_enabled: true,
relay_cad_periodicity: 1,
default_channel_index: 0,
second_channel_freq: 868300000,
second_channel_dr: 3,
second_channel_ack_offset: 2,
..Default::default()
}),
..Default::default()
},
expected_mac_commands: vec![],
@ -4049,13 +4055,16 @@ mod test {
..Default::default()
},
device_profile: device_profile::DeviceProfile {
is_relay: true,
relay_enabled: true,
relay_cad_periodicity: 1,
relay_default_channel_index: 0,
relay_second_channel_freq: 868500000,
relay_second_channel_dr: 3,
relay_second_channel_ack_offset: 2,
relay_params: Some(fields::RelayParams {
is_relay: true,
relay_enabled: true,
relay_cad_periodicity: 1,
default_channel_index: 0,
second_channel_freq: 868500000,
second_channel_dr: 3,
second_channel_ack_offset: 2,
..Default::default()
}),
..Default::default()
},
expected_mac_commands: vec![lrwn::MACCommandSet::new(vec![
@ -4134,12 +4143,15 @@ mod test {
..Default::default()
},
device_profile: device_profile::DeviceProfile {
relay_ed_activation_mode: lrwn::RelayModeActivation::EnableRelayMode,
relay_ed_smart_enable_level: 1,
relay_ed_back_off: 16,
relay_second_channel_freq: 868100000,
relay_second_channel_dr: 3,
relay_second_channel_ack_offset: 4,
relay_params: Some(fields::RelayParams {
ed_activation_mode: lrwn::RelayModeActivation::EnableRelayMode,
ed_smart_enable_level: 1,
ed_back_off: 16,
second_channel_freq: 868100000,
second_channel_dr: 3,
second_channel_ack_offset: 4,
..Default::default()
}),
..Default::default()
},
expected_mac_commands: vec![],
@ -4159,12 +4171,15 @@ mod test {
..Default::default()
},
device_profile: device_profile::DeviceProfile {
relay_ed_activation_mode: lrwn::RelayModeActivation::EnableRelayMode,
relay_ed_smart_enable_level: 1,
relay_ed_back_off: 16,
relay_second_channel_freq: 868100000,
relay_second_channel_dr: 3,
relay_second_channel_ack_offset: 4,
relay_params: Some(fields::RelayParams {
ed_activation_mode: lrwn::RelayModeActivation::EnableRelayMode,
ed_smart_enable_level: 1,
ed_back_off: 16,
second_channel_freq: 868100000,
second_channel_dr: 3,
second_channel_ack_offset: 4,
..Default::default()
}),
..Default::default()
},
expected_mac_commands: vec![lrwn::MACCommandSet::new(vec![
@ -4247,14 +4262,17 @@ mod test {
..Default::default()
},
device_profile: device_profile::DeviceProfile {
relay_join_req_limit_reload_rate: 10,
relay_join_req_limit_bucket_size: 0,
relay_notify_limit_reload_rate: 15,
relay_notify_limit_bucket_size: 1,
relay_global_uplink_limit_reload_rate: 20,
relay_global_uplink_limit_bucket_size: 2,
relay_overall_limit_reload_rate: 25,
relay_overall_limit_bucket_size: 3,
relay_params: Some(fields::RelayParams {
relay_join_req_limit_reload_rate: 10,
relay_join_req_limit_bucket_size: 0,
relay_notify_limit_reload_rate: 15,
relay_notify_limit_bucket_size: 1,
relay_global_uplink_limit_reload_rate: 20,
relay_global_uplink_limit_bucket_size: 2,
relay_overall_limit_reload_rate: 25,
relay_overall_limit_bucket_size: 3,
..Default::default()
}),
..Default::default()
},
expected_mac_commands: vec![],
@ -4276,14 +4294,17 @@ mod test {
..Default::default()
},
device_profile: device_profile::DeviceProfile {
relay_join_req_limit_reload_rate: 10,
relay_join_req_limit_bucket_size: 0,
relay_notify_limit_reload_rate: 15,
relay_notify_limit_bucket_size: 1,
relay_global_uplink_limit_reload_rate: 20,
relay_global_uplink_limit_bucket_size: 2,
relay_overall_limit_reload_rate: 25,
relay_overall_limit_bucket_size: 3,
relay_params: Some(fields::RelayParams {
relay_join_req_limit_reload_rate: 10,
relay_join_req_limit_bucket_size: 0,
relay_notify_limit_reload_rate: 15,
relay_notify_limit_bucket_size: 1,
relay_global_uplink_limit_reload_rate: 20,
relay_global_uplink_limit_bucket_size: 2,
relay_overall_limit_reload_rate: 25,
relay_overall_limit_bucket_size: 3,
..Default::default()
}),
..Default::default()
},
expected_mac_commands: vec![lrwn::MACCommandSet::new(vec![
@ -4521,7 +4542,10 @@ mod test {
let dp_relay = device_profile::create(device_profile::DeviceProfile {
name: "dp-relay".into(),
tenant_id: t.id,
is_relay: true,
relay_params: Some(fields::RelayParams {
is_relay: true,
..Default::default()
}),
..Default::default()
})
.await

View File

@ -1,6 +1,3 @@
// Required by rust::table macro.
#![recursion_limit = "256"]
#[macro_use]
extern crate lazy_static;
extern crate diesel_migrations;

View File

@ -41,33 +41,12 @@ pub struct DeviceProfile {
pub measurements: fields::Measurements,
pub auto_detect_measurements: bool,
pub region_config_id: Option<String>,
pub is_relay: bool,
pub is_relay_ed: bool,
pub relay_ed_relay_only: bool,
pub relay_enabled: bool,
pub relay_cad_periodicity: i16,
pub relay_default_channel_index: i16,
pub relay_second_channel_freq: i64,
pub relay_second_channel_dr: i16,
pub relay_second_channel_ack_offset: i16,
pub relay_ed_activation_mode: lrwn::RelayModeActivation,
pub relay_ed_smart_enable_level: i16,
pub relay_ed_back_off: i16,
pub relay_ed_uplink_limit_bucket_size: i16,
pub relay_ed_uplink_limit_reload_rate: i16,
pub relay_join_req_limit_reload_rate: i16,
pub relay_notify_limit_reload_rate: i16,
pub relay_global_uplink_limit_reload_rate: i16,
pub relay_overall_limit_reload_rate: i16,
pub relay_join_req_limit_bucket_size: i16,
pub relay_notify_limit_bucket_size: i16,
pub relay_global_uplink_limit_bucket_size: i16,
pub relay_overall_limit_bucket_size: i16,
pub allow_roaming: bool,
pub rx1_delay: i16,
pub abp_params: Option<fields::AbpParams>,
pub class_b_params: Option<fields::ClassBParams>,
pub class_c_params: Option<fields::ClassCParams>,
pub relay_params: Option<fields::RelayParams>,
}
impl DeviceProfile {
@ -111,33 +90,12 @@ impl Default for DeviceProfile {
measurements: fields::Measurements::new(HashMap::new()),
auto_detect_measurements: false,
region_config_id: None,
is_relay: false,
is_relay_ed: false,
relay_ed_relay_only: false,
relay_enabled: false,
relay_cad_periodicity: 0,
relay_default_channel_index: 0,
relay_second_channel_freq: 0,
relay_second_channel_dr: 0,
relay_second_channel_ack_offset: 0,
relay_ed_activation_mode: lrwn::RelayModeActivation::DisableRelayMode,
relay_ed_smart_enable_level: 0,
relay_ed_back_off: 0,
relay_ed_uplink_limit_bucket_size: 0,
relay_ed_uplink_limit_reload_rate: 0,
relay_join_req_limit_reload_rate: 0,
relay_notify_limit_reload_rate: 0,
relay_global_uplink_limit_reload_rate: 0,
relay_overall_limit_reload_rate: 0,
relay_join_req_limit_bucket_size: 0,
relay_notify_limit_bucket_size: 0,
relay_global_uplink_limit_bucket_size: 0,
relay_overall_limit_bucket_size: 0,
allow_roaming: false,
rx1_delay: 0,
abp_params: None,
class_b_params: None,
class_c_params: None,
relay_params: None,
}
}
}
@ -153,11 +111,13 @@ impl DeviceProfile {
ds.class_b_ping_slot_nb = 1 << class_b_params.ping_slot_nb_k as u32;
}
if self.is_relay_ed {
ds.relay = Some(internal::Relay {
ed_relay_only: self.relay_ed_relay_only,
..Default::default()
});
if let Some(relay_params) = &self.relay_params {
if relay_params.is_relay_ed {
ds.relay = Some(internal::Relay {
ed_relay_only: relay_params.ed_relay_only,
..Default::default()
});
}
}
if !self.supports_otaa {
@ -242,39 +202,12 @@ pub async fn update(dp: DeviceProfile) -> Result<DeviceProfile, Error> {
device_profile::measurements.eq(&dp.measurements),
device_profile::auto_detect_measurements.eq(&dp.auto_detect_measurements),
device_profile::region_config_id.eq(&dp.region_config_id),
device_profile::is_relay.eq(&dp.is_relay),
device_profile::is_relay_ed.eq(&dp.is_relay_ed),
device_profile::relay_ed_relay_only.eq(&dp.relay_ed_relay_only),
device_profile::relay_enabled.eq(&dp.relay_enabled),
device_profile::relay_cad_periodicity.eq(&dp.relay_cad_periodicity),
device_profile::relay_default_channel_index.eq(&dp.relay_default_channel_index),
device_profile::relay_second_channel_freq.eq(&dp.relay_second_channel_freq),
device_profile::relay_second_channel_dr.eq(&dp.relay_second_channel_dr),
device_profile::relay_second_channel_ack_offset.eq(&dp.relay_second_channel_ack_offset),
device_profile::relay_ed_activation_mode.eq(&dp.relay_ed_activation_mode),
device_profile::relay_ed_smart_enable_level.eq(&dp.relay_ed_smart_enable_level),
device_profile::relay_ed_back_off.eq(&dp.relay_ed_back_off),
device_profile::relay_ed_uplink_limit_bucket_size
.eq(&dp.relay_ed_uplink_limit_bucket_size),
device_profile::relay_ed_uplink_limit_reload_rate
.eq(&dp.relay_ed_uplink_limit_reload_rate),
device_profile::relay_join_req_limit_reload_rate
.eq(&dp.relay_join_req_limit_reload_rate),
device_profile::relay_notify_limit_reload_rate.eq(&dp.relay_notify_limit_reload_rate),
device_profile::relay_global_uplink_limit_reload_rate
.eq(&dp.relay_global_uplink_limit_reload_rate),
device_profile::relay_overall_limit_reload_rate.eq(&dp.relay_overall_limit_reload_rate),
device_profile::relay_join_req_limit_bucket_size
.eq(&dp.relay_join_req_limit_bucket_size),
device_profile::relay_notify_limit_bucket_size.eq(&dp.relay_notify_limit_bucket_size),
device_profile::relay_global_uplink_limit_bucket_size
.eq(&dp.relay_global_uplink_limit_bucket_size),
device_profile::relay_overall_limit_bucket_size.eq(&dp.relay_overall_limit_bucket_size),
device_profile::allow_roaming.eq(&dp.allow_roaming),
device_profile::rx1_delay.eq(&dp.rx1_delay),
device_profile::abp_params.eq(&dp.abp_params),
device_profile::class_b_params.eq(&dp.class_b_params),
device_profile::class_c_params.eq(&dp.class_c_params),
device_profile::relay_params.eq(&dp.relay_params),
))
.get_result(&mut get_async_db_conn().await?)
.await

View File

@ -146,3 +146,91 @@ impl serialize::ToSql<Text, Sqlite> for ClassCParams {
Ok(serialize::IsNull::No)
}
}
#[derive(
Default, Debug, Clone, PartialEq, Eq, Deserialize, Serialize, AsExpression, FromSqlRow,
)]
#[cfg_attr(feature = "postgres", diesel(sql_type = Jsonb))]
#[cfg_attr(feature = "sqlite", diesel(sql_type = Text))]
pub struct RelayParams {
pub is_relay: bool,
pub is_relay_ed: bool,
pub ed_relay_only: bool,
pub relay_enabled: bool,
pub relay_cad_periodicity: u8,
pub default_channel_index: u8,
pub second_channel_freq: u32,
pub second_channel_dr: u8,
pub second_channel_ack_offset: u8,
#[serde(with = "ed_activation_mode")]
pub ed_activation_mode: lrwn::RelayModeActivation,
pub ed_smart_enable_level: u8,
pub ed_back_off: u8,
pub ed_uplink_limit_bucket_size: u8,
pub ed_uplink_limit_reload_rate: u8,
pub relay_join_req_limit_reload_rate: u8,
pub relay_notify_limit_reload_rate: u8,
pub relay_global_uplink_limit_reload_rate: u8,
pub relay_overall_limit_reload_rate: u8,
pub relay_join_req_limit_bucket_size: u8,
pub relay_notify_limit_bucket_size: u8,
pub relay_global_uplink_limit_bucket_size: u8,
pub relay_overall_limit_bucket_size: u8,
}
#[cfg(feature = "postgres")]
impl deserialize::FromSql<Jsonb, Pg> for RelayParams {
fn from_sql(value: <Pg as Backend>::RawValue<'_>) -> deserialize::Result<Self> {
let value = <serde_json::Value as deserialize::FromSql<Jsonb, Pg>>::from_sql(value)?;
Ok(serde_json::from_value(value)?)
}
}
#[cfg(feature = "postgres")]
impl serialize::ToSql<Jsonb, Pg> for RelayParams {
fn to_sql<'b>(&'b self, out: &mut serialize::Output<'b, '_, Pg>) -> serialize::Result {
let value = serde_json::to_value(&self)?;
<serde_json::Value as serialize::ToSql<Jsonb, Pg>>::to_sql(&value, &mut out.reborrow())
}
}
#[cfg(feature = "sqlite")]
impl deserialize::FromSql<Text, Sqlite> for RelayParams
where
*const str: deserialize::FromSql<Text, Sqlite>,
{
fn from_sql(value: <Sqlite as Backend>::RawValue<'_>) -> deserialize::Result<Self> {
let s =
<*const str as deserialize::FromSql<diesel::sql_types::Text, Sqlite>>::from_sql(value)?;
Ok(serde_json::from_str(unsafe { &*s })?)
}
}
#[cfg(feature = "sqlite")]
impl serialize::ToSql<Text, Sqlite> for RelayParams {
fn to_sql<'b>(&'b self, out: &mut serialize::Output<'b, '_, Sqlite>) -> serialize::Result {
out.set_value(serde_json::to_string(&self)?);
Ok(serialize::IsNull::No)
}
}
mod ed_activation_mode {
use serde::{self, Deserialize, Deserializer, Serializer};
pub fn serialize<S>(v: &lrwn::RelayModeActivation, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_u8(v.to_u8())
}
pub fn deserialize<'de, D>(deserializer: D) -> Result<lrwn::RelayModeActivation, D::Error>
where
D: Deserializer<'de>,
{
let v = u8::deserialize(deserializer)?;
let v = lrwn::RelayModeActivation::from_u8(v)
.map_err(|e| serde::de::Error::custom(e.to_string()))?;
Ok(v)
}
}

View File

@ -9,7 +9,7 @@ mod uuid;
pub use big_decimal::BigDecimal;
pub use dev_nonces::DevNonces;
pub use device_profile::{AbpParams, ClassBParams, ClassCParams};
pub use device_profile::{AbpParams, ClassBParams, ClassCParams, RelayParams};
pub use device_session::DeviceSession;
pub use key_value::KeyValue;
pub use measurements::*;

View File

@ -1,6 +1,6 @@
use anyhow::Result;
use chrono::{DateTime, Utc};
use diesel::{dsl, prelude::*};
use diesel::{dsl, prelude::*, sql_types};
use diesel_async::RunQueryDsl;
use tracing::info;
use uuid::Uuid;
@ -43,10 +43,24 @@ pub struct DeviceListItem {
}
pub async fn get_relay_count(filters: &RelayFilters) -> Result<i64, Error> {
let mut q = device::dsl::device
let q = device::dsl::device
.select(dsl::count_star())
.inner_join(device_profile::table)
.filter(device_profile::dsl::is_relay.eq(true))
.inner_join(device_profile::table);
#[cfg(feature = "postgres")]
let mut q = q
.filter(
dsl::sql::<sql_types::Bool>("(relay_params->'is_relay')::boolean =")
.bind::<sql_types::Bool, _>(true),
)
.into_boxed();
#[cfg(feature = "sqlite")]
let mut q = q
.filter(
dsl::sql::<sql_types::Bool>("relay_params->>'is_relay' =")
.bind::<sql_types::Bool, _>(true),
)
.into_boxed();
if let Some(application_id) = &filters.application_id {
@ -61,10 +75,24 @@ pub async fn list_relays(
offset: i64,
filters: &RelayFilters,
) -> Result<Vec<RelayListItem>, Error> {
let mut q = device::dsl::device
let q = device::dsl::device
.inner_join(device_profile::table)
.select((device::dev_eui, device::name))
.filter(device_profile::dsl::is_relay.eq(true))
.select((device::dev_eui, device::name));
#[cfg(feature = "postgres")]
let mut q = q
.filter(
dsl::sql::<sql_types::Bool>("(relay_params->'is_relay')::boolean =")
.bind::<sql_types::Bool, _>(true),
)
.into_boxed();
#[cfg(feature = "sqlite")]
let mut q = q
.filter(
dsl::sql::<sql_types::Bool>("relay_params->>'is_relay' =")
.bind::<sql_types::Bool, _>(true),
)
.into_boxed();
if let Some(application_id) = &filters.application_id {
@ -98,19 +126,43 @@ pub async fn list_devices(
offset: i64,
filters: &DeviceFilters,
) -> Result<Vec<DeviceListItem>, Error> {
let mut q = relay_device::dsl::relay_device
let q = relay_device::dsl::relay_device
.inner_join(device::table.on(relay_device::dsl::dev_eui.eq(device::dsl::dev_eui)))
.inner_join(
device_profile::table.on(device::dsl::device_profile_id.eq(device_profile::dsl::id)),
)
);
#[cfg(feature = "postgres")]
let mut q = q
.select((
relay_device::dev_eui,
device::join_eui,
device::dev_addr,
relay_device::created_at,
device::name,
device_profile::relay_ed_uplink_limit_bucket_size,
device_profile::relay_ed_uplink_limit_reload_rate,
dsl::sql::<sql_types::SmallInt>(
"coalesce((relay_params->'ed_uplink_limit_bucket_size')::smallint, 0::smallint)",
),
dsl::sql::<sql_types::SmallInt>(
"coalesce((relay_params->'ed_uplink_limit_reload_rate')::smallint, 0::smallint)",
),
))
.into_boxed();
#[cfg(feature = "sqlite")]
let mut q = q
.select((
relay_device::dev_eui,
device::join_eui,
device::dev_addr,
relay_device::created_at,
device::name,
dsl::sql::<sql_types::SmallInt>(
"coalesce(relay_params->>'ed_uplink_limit_bucket_size', 0)",
),
dsl::sql::<sql_types::SmallInt>(
"coalesce(relay_params->>'ed_uplink_limit_reload_rate', 0)",
),
))
.into_boxed();
@ -145,7 +197,13 @@ pub async fn add_device(relay_dev_eui: EUI64, device_dev_eui: EUI64) -> Result<(
.get_result(c)
.await
.map_err(|e| Error::from_diesel(e, rd.device_profile_id.to_string()))?;
if !rdp.is_relay {
if !rdp
.relay_params
.as_ref()
.map(|v| v.is_relay)
.unwrap_or_default()
{
return Err(Error::Validation("Device is not a relay".to_string()));
}
@ -175,8 +233,10 @@ pub async fn add_device(relay_dev_eui: EUI64, device_dev_eui: EUI64) -> Result<(
}
// Validate that the device is not a relay.
if dp.is_relay {
return Err(Error::Validation("Can not add relay to a relay".into()));
if let Some(relay_params) = &dp.relay_params {
if relay_params.is_relay {
return Err(Error::Validation("Can not add relay to a relay".into()));
}
}
// Validate max. number of devices.
@ -248,7 +308,10 @@ pub mod test {
let dp_relay = storage::device_profile::create(storage::device_profile::DeviceProfile {
tenant_id: dp.tenant_id,
name: "relay".into(),
is_relay: true,
relay_params: Some(fields::RelayParams {
is_relay: true,
..Default::default()
}),
..Default::default()
})
.await

View File

@ -111,33 +111,12 @@ diesel::table! {
auto_detect_measurements -> Bool,
#[max_length = 100]
region_config_id -> Nullable<Varchar>,
is_relay -> Bool,
is_relay_ed -> Bool,
relay_ed_relay_only -> Bool,
relay_enabled -> Bool,
relay_cad_periodicity -> Int2,
relay_default_channel_index -> Int2,
relay_second_channel_freq -> Int8,
relay_second_channel_dr -> Int2,
relay_second_channel_ack_offset -> Int2,
relay_ed_activation_mode -> Int2,
relay_ed_smart_enable_level -> Int2,
relay_ed_back_off -> Int2,
relay_ed_uplink_limit_bucket_size -> Int2,
relay_ed_uplink_limit_reload_rate -> Int2,
relay_join_req_limit_reload_rate -> Int2,
relay_notify_limit_reload_rate -> Int2,
relay_global_uplink_limit_reload_rate -> Int2,
relay_overall_limit_reload_rate -> Int2,
relay_join_req_limit_bucket_size -> Int2,
relay_notify_limit_bucket_size -> Int2,
relay_global_uplink_limit_bucket_size -> Int2,
relay_overall_limit_bucket_size -> Int2,
allow_roaming -> Bool,
rx1_delay -> Int2,
abp_params -> Nullable<Jsonb>,
class_b_params -> Nullable<Jsonb>,
class_c_params -> Nullable<Jsonb>,
relay_params -> Nullable<Jsonb>,
}
}

View File

@ -99,33 +99,12 @@ diesel::table! {
measurements -> Text,
auto_detect_measurements -> Bool,
region_config_id -> Nullable<Text>,
is_relay -> Bool,
is_relay_ed -> Bool,
relay_ed_relay_only -> Bool,
relay_enabled -> Bool,
relay_cad_periodicity -> SmallInt,
relay_default_channel_index -> SmallInt,
relay_second_channel_freq -> BigInt,
relay_second_channel_dr -> SmallInt,
relay_second_channel_ack_offset -> SmallInt,
relay_ed_activation_mode -> SmallInt,
relay_ed_smart_enable_level -> SmallInt,
relay_ed_back_off -> SmallInt,
relay_ed_uplink_limit_bucket_size -> SmallInt,
relay_ed_uplink_limit_reload_rate -> SmallInt,
relay_join_req_limit_reload_rate -> SmallInt,
relay_notify_limit_reload_rate -> SmallInt,
relay_global_uplink_limit_reload_rate -> SmallInt,
relay_overall_limit_reload_rate -> SmallInt,
relay_join_req_limit_bucket_size -> SmallInt,
relay_notify_limit_bucket_size -> SmallInt,
relay_global_uplink_limit_bucket_size -> SmallInt,
relay_overall_limit_bucket_size -> SmallInt,
allow_roaming -> Bool,
rx1_delay -> SmallInt,
abp_params -> Nullable<Text>,
class_b_params -> Nullable<Text>,
class_c_params -> Nullable<Text>,
relay_params -> Nullable<Text>,
}
}

View File

@ -62,8 +62,11 @@ async fn test_lorawan_10() {
mac_version: lrwn::region::MacVersion::LORAWAN_1_0_4,
reg_params_revision: lrwn::region::Revision::RP002_1_0_3,
supports_otaa: true,
is_relay: true,
relay_enabled: true,
relay_params: Some(fields::RelayParams {
is_relay: true,
relay_enabled: true,
..Default::default()
}),
..Default::default()
})
.await
@ -76,7 +79,10 @@ async fn test_lorawan_10() {
mac_version: lrwn::region::MacVersion::LORAWAN_1_0_4,
reg_params_revision: lrwn::region::Revision::RP002_1_0_3,
supports_otaa: true,
is_relay_ed: true,
relay_params: Some(fields::RelayParams {
is_relay_ed: true,
..Default::default()
}),
..Default::default()
})
.await

View File

@ -6,7 +6,7 @@ use super::assert;
use crate::storage::{
application,
device::{self, DeviceClass},
device_keys, device_profile, gateway, tenant,
device_keys, device_profile, fields, gateway, tenant,
};
use crate::{gateway::backend as gateway_backend, integration, test, uplink};
use chirpstack_api::{common, gw, internal};
@ -66,7 +66,10 @@ async fn test_lorawan_10() {
mac_version: lrwn::region::MacVersion::LORAWAN_1_0_2,
reg_params_revision: lrwn::region::Revision::A,
supports_otaa: true,
is_relay: true,
relay_params: Some(fields::RelayParams {
is_relay: true,
..Default::default()
}),
..Default::default()
})
.await

View File

@ -1396,8 +1396,10 @@ impl Data {
let dp = self.device_profile.as_ref().unwrap();
if let lrwn::Payload::MACPayload(pl) = &self.phy_payload.payload {
if dp.is_relay && pl.f_port.unwrap_or(0) == lrwn::LA_FPORT_RELAY {
return true;
if let Some(relay_params) = &dp.relay_params {
if relay_params.is_relay && pl.f_port.unwrap_or(0) == lrwn::LA_FPORT_RELAY {
return true;
}
}
}

View File

@ -381,10 +381,11 @@ impl JoinRequest {
fn abort_on_relay_only_comm(&self) -> Result<(), Error> {
// In case the relay context is not set and relay_ed_relay_only is set, abort.
if self.relay_context.is_none() && self.device_profile.as_ref().unwrap().relay_ed_relay_only
{
info!(dev_eui = %self.device.as_ref().unwrap().dev_eui, "Only communication through relay is allowed");
return Err(Error::Abort);
if let Some(relay_params) = &self.device_profile.as_ref().unwrap().relay_params {
if self.relay_context.is_none() && relay_params.ed_relay_only {
info!(dev_eui = %self.device.as_ref().unwrap().dev_eui, "Only communication through relay is allowed");
return Err(Error::Abort);
}
}
Ok(())
}

View File

@ -4,12 +4,8 @@ use std::ops::{Deref, DerefMut};
use std::time::Duration;
use anyhow::Result;
#[cfg(feature = "sqlite")]
use diesel::sqlite::Sqlite;
#[cfg(feature = "diesel")]
use diesel::{backend::Backend, deserialize, serialize, sql_types::SmallInt};
#[cfg(feature = "serde")]
use serde::Serialize;
use serde::{Deserialize, Serialize};
use crate::cflist::ChMask;
use crate::dl_settings::DLSettings;
@ -1811,10 +1807,10 @@ impl PayloadCodec for RelayConfAnsPayload {
}
}
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
#[cfg_attr(feature = "serde", derive(Serialize))]
#[cfg_attr(feature = "diesel", derive(AsExpression, FromSqlRow), diesel(sql_type = diesel::sql_types::SmallInt))]
#[derive(Default, Debug, PartialEq, Eq, Clone, Copy)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum RelayModeActivation {
#[default]
DisableRelayMode,
EnableRelayMode,
Dynamic,
@ -1876,37 +1872,6 @@ impl ResetLimitCounter {
}
}
#[cfg(feature = "diesel")]
impl<DB> deserialize::FromSql<SmallInt, DB> for RelayModeActivation
where
DB: Backend,
i16: deserialize::FromSql<SmallInt, DB>,
{
fn from_sql(value: <DB as Backend>::RawValue<'_>) -> deserialize::Result<Self> {
let i = i16::from_sql(value)?;
Ok(RelayModeActivation::from_u8(i as u8)?)
}
}
#[cfg(feature = "postgres")]
impl serialize::ToSql<SmallInt, diesel::pg::Pg> for RelayModeActivation
where
i16: serialize::ToSql<SmallInt, diesel::pg::Pg>,
{
fn to_sql(&self, out: &mut serialize::Output<'_, '_, diesel::pg::Pg>) -> serialize::Result {
let i = self.to_u8() as i16;
<i16 as serialize::ToSql<SmallInt, diesel::pg::Pg>>::to_sql(&i, &mut out.reborrow())
}
}
#[cfg(feature = "sqlite")]
impl serialize::ToSql<SmallInt, Sqlite> for RelayModeActivation {
fn to_sql<'b>(&'b self, out: &mut serialize::Output<'b, '_, Sqlite>) -> serialize::Result {
out.set_value(self.to_u8() as i32);
Ok(serialize::IsNull::No)
}
}
#[derive(Debug, PartialEq, Eq, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize))]
pub struct ActivationRelayMode {