Refactor device-profile relay fields.

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

View File

@ -24,11 +24,7 @@
# Database # Database
email_address = "0.2" email_address = "0.2"
diesel = { version = "2.2", features = [ diesel = { version = "2.2", features = ["chrono", "numeric"] }
"chrono",
"numeric",
"64-column-tables",
] }
diesel_migrations = { version = "2.2" } diesel_migrations = { version = "2.2" }
diesel-async = { version = "0.5", features = [ diesel-async = { version = "0.5", features = [
"deadpool", "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_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_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_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 update device_profile
set set
@ -26,7 +49,42 @@ update device_profile
where where
class_b_params is not null; 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 alter table device_profile
drop column abp_params, 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 alter table device_profile
add column abp_params jsonb null, add column abp_params jsonb null,
add column class_b_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 update device_profile
set abp_params = json_build_object( set abp_params = json_build_object(
@ -25,6 +26,33 @@ update device_profile
where where
supports_class_c = true; 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 alter table device_profile
drop column abp_rx1_delay, drop column abp_rx1_delay,
drop column abp_rx1_dr_offset, 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_nb_k,
drop column class_b_ping_slot_dr, drop column class_b_ping_slot_dr,
drop column class_b_ping_slot_freq, 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_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_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 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 update device_profile
set set
@ -32,7 +54,35 @@ update device_profile
where where
class_c_params is not null; 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 abp_params;
alter table device_profile drop column class_b_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 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 abp_params text null;
alter table device_profile add column class_b_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 class_c_params text null;
alter table device_profile add column relay_params text null;
update device_profile update device_profile
set abp_params = json_object( set abp_params = json_object(
@ -23,6 +24,32 @@ update device_profile
'timeout', class_c_timeout) 'timeout', class_c_timeout)
where supports_class_c = true; 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_delay;
alter table device_profile drop column abp_rx1_dr_offset; alter table device_profile drop column abp_rx1_dr_offset;
alter table device_profile drop column abp_rx2_dr; 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_b_ping_slot_freq;
alter table device_profile drop column class_c_timeout; 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, auto_detect_measurements: req_dp.auto_detect_measurements,
region_config_id: (!req_dp.region_config_id.is_empty()) region_config_id: (!req_dp.region_config_id.is_empty())
.then(|| req_dp.region_config_id.clone()), .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, allow_roaming: req_dp.allow_roaming,
rx1_delay: req_dp.rx1_delay as i16, rx1_delay: req_dp.rx1_delay as i16,
abp_params: if req_dp.supports_otaa { abp_params: if req_dp.supports_otaa {
@ -132,6 +108,38 @@ impl DeviceProfileService for DeviceProfile {
} else { } else {
None 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() ..Default::default()
}; };
@ -166,6 +174,7 @@ impl DeviceProfileService for DeviceProfile {
let abp_params = dp.abp_params.clone().unwrap_or_default(); let abp_params = dp.abp_params.clone().unwrap_or_default();
let class_b_params = dp.class_b_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 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 { let mut resp = Response::new(api::GetDeviceProfileResponse {
device_profile: Some(api::DeviceProfile { device_profile: Some(api::DeviceProfile {
@ -211,30 +220,36 @@ impl DeviceProfileService for DeviceProfile {
.collect(), .collect(),
auto_detect_measurements: dp.auto_detect_measurements, auto_detect_measurements: dp.auto_detect_measurements,
region_config_id: dp.region_config_id.clone().unwrap_or_default(), region_config_id: dp.region_config_id.clone().unwrap_or_default(),
is_relay: dp.is_relay, is_relay: relay_params.is_relay,
is_relay_ed: dp.is_relay_ed, is_relay_ed: relay_params.is_relay_ed,
relay_ed_relay_only: dp.relay_ed_relay_only, relay_ed_relay_only: relay_params.ed_relay_only,
relay_enabled: dp.relay_enabled, relay_enabled: relay_params.relay_enabled,
relay_cad_periodicity: dp.relay_cad_periodicity as i32, relay_cad_periodicity: relay_params.relay_cad_periodicity as i32,
relay_default_channel_index: dp.relay_default_channel_index as u32, relay_default_channel_index: relay_params.default_channel_index as u32,
relay_second_channel_freq: dp.relay_second_channel_freq as u32, relay_second_channel_freq: relay_params.second_channel_freq as u32,
relay_second_channel_dr: dp.relay_second_channel_dr as u32, relay_second_channel_dr: relay_params.second_channel_dr as u32,
relay_second_channel_ack_offset: dp.relay_second_channel_ack_offset as i32, relay_second_channel_ack_offset: relay_params.second_channel_ack_offset as i32,
relay_ed_activation_mode: dp.relay_ed_activation_mode.to_proto().into(), relay_ed_activation_mode: relay_params.ed_activation_mode.to_proto().into(),
relay_ed_smart_enable_level: dp.relay_ed_smart_enable_level as u32, relay_ed_smart_enable_level: relay_params.ed_smart_enable_level as u32,
relay_ed_back_off: dp.relay_ed_back_off as u32, relay_ed_back_off: relay_params.ed_back_off as u32,
relay_ed_uplink_limit_bucket_size: dp.relay_ed_uplink_limit_bucket_size as u32, relay_ed_uplink_limit_bucket_size: relay_params.ed_uplink_limit_bucket_size as u32,
relay_ed_uplink_limit_reload_rate: dp.relay_ed_uplink_limit_reload_rate as u32, relay_ed_uplink_limit_reload_rate: relay_params.ed_uplink_limit_reload_rate as u32,
relay_join_req_limit_reload_rate: dp.relay_join_req_limit_reload_rate as u32, relay_join_req_limit_reload_rate: relay_params.relay_join_req_limit_reload_rate
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
as u32, as u32,
relay_overall_limit_reload_rate: dp.relay_overall_limit_reload_rate as u32, relay_notify_limit_reload_rate: relay_params.relay_notify_limit_reload_rate as u32,
relay_join_req_limit_bucket_size: dp.relay_join_req_limit_bucket_size as u32, relay_global_uplink_limit_reload_rate: relay_params
relay_notify_limit_bucket_size: dp.relay_notify_limit_bucket_size as u32, .relay_global_uplink_limit_reload_rate
relay_global_uplink_limit_bucket_size: dp.relay_global_uplink_limit_bucket_size 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, as u32,
relay_overall_limit_bucket_size: dp.relay_overall_limit_bucket_size as u32,
allow_roaming: dp.allow_roaming, allow_roaming: dp.allow_roaming,
rx1_delay: dp.rx1_delay as u32, rx1_delay: dp.rx1_delay as u32,
}), }),
@ -302,30 +317,6 @@ impl DeviceProfileService for DeviceProfile {
auto_detect_measurements: req_dp.auto_detect_measurements, auto_detect_measurements: req_dp.auto_detect_measurements,
region_config_id: (!req_dp.region_config_id.is_empty()) region_config_id: (!req_dp.region_config_id.is_empty())
.then(|| req_dp.region_config_id.clone()), .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, allow_roaming: req_dp.allow_roaming,
rx1_delay: req_dp.rx1_delay as i16, rx1_delay: req_dp.rx1_delay as i16,
abp_params: if req_dp.supports_otaa { abp_params: if req_dp.supports_otaa {
@ -355,6 +346,38 @@ impl DeviceProfileService for DeviceProfile {
} else { } else {
None 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() ..Default::default()
}) })
.await .await

View File

@ -182,7 +182,7 @@ pub mod test {
use super::*; use super::*;
use crate::api::auth::validator::RequestValidator; use crate::api::auth::validator::RequestValidator;
use crate::api::auth::AuthID; 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; use crate::test;
#[tokio::test] #[tokio::test]
@ -229,8 +229,11 @@ pub mod test {
let dp_relay = device_profile::create(device_profile::DeviceProfile { let dp_relay = device_profile::create(device_profile::DeviceProfile {
name: "test-dp".into(), name: "test-dp".into(),
tenant_id: t.id, tenant_id: t.id,
relay_params: Some(fields::RelayParams {
is_relay: true, is_relay: true,
..Default::default() ..Default::default()
}),
..Default::default()
}) })
.await .await
.unwrap(); .unwrap();

View File

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

View File

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

View File

@ -41,33 +41,12 @@ pub struct DeviceProfile {
pub measurements: fields::Measurements, pub measurements: fields::Measurements,
pub auto_detect_measurements: bool, pub auto_detect_measurements: bool,
pub region_config_id: Option<String>, 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 allow_roaming: bool,
pub rx1_delay: i16, pub rx1_delay: i16,
pub abp_params: Option<fields::AbpParams>, pub abp_params: Option<fields::AbpParams>,
pub class_b_params: Option<fields::ClassBParams>, pub class_b_params: Option<fields::ClassBParams>,
pub class_c_params: Option<fields::ClassCParams>, pub class_c_params: Option<fields::ClassCParams>,
pub relay_params: Option<fields::RelayParams>,
} }
impl DeviceProfile { impl DeviceProfile {
@ -111,33 +90,12 @@ impl Default for DeviceProfile {
measurements: fields::Measurements::new(HashMap::new()), measurements: fields::Measurements::new(HashMap::new()),
auto_detect_measurements: false, auto_detect_measurements: false,
region_config_id: None, 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, allow_roaming: false,
rx1_delay: 0, rx1_delay: 0,
abp_params: None, abp_params: None,
class_b_params: None, class_b_params: None,
class_c_params: None, class_c_params: None,
relay_params: None,
} }
} }
} }
@ -153,12 +111,14 @@ impl DeviceProfile {
ds.class_b_ping_slot_nb = 1 << class_b_params.ping_slot_nb_k as u32; ds.class_b_ping_slot_nb = 1 << class_b_params.ping_slot_nb_k as u32;
} }
if self.is_relay_ed { if let Some(relay_params) = &self.relay_params {
if relay_params.is_relay_ed {
ds.relay = Some(internal::Relay { ds.relay = Some(internal::Relay {
ed_relay_only: self.relay_ed_relay_only, ed_relay_only: relay_params.ed_relay_only,
..Default::default() ..Default::default()
}); });
} }
}
if !self.supports_otaa { if !self.supports_otaa {
ds.tx_power_index = 0; ds.tx_power_index = 0;
@ -242,39 +202,12 @@ pub async fn update(dp: DeviceProfile) -> Result<DeviceProfile, Error> {
device_profile::measurements.eq(&dp.measurements), device_profile::measurements.eq(&dp.measurements),
device_profile::auto_detect_measurements.eq(&dp.auto_detect_measurements), device_profile::auto_detect_measurements.eq(&dp.auto_detect_measurements),
device_profile::region_config_id.eq(&dp.region_config_id), 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::allow_roaming.eq(&dp.allow_roaming),
device_profile::rx1_delay.eq(&dp.rx1_delay), device_profile::rx1_delay.eq(&dp.rx1_delay),
device_profile::abp_params.eq(&dp.abp_params), device_profile::abp_params.eq(&dp.abp_params),
device_profile::class_b_params.eq(&dp.class_b_params), device_profile::class_b_params.eq(&dp.class_b_params),
device_profile::class_c_params.eq(&dp.class_c_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?) .get_result(&mut get_async_db_conn().await?)
.await .await

View File

@ -146,3 +146,91 @@ impl serialize::ToSql<Text, Sqlite> for ClassCParams {
Ok(serialize::IsNull::No) 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 big_decimal::BigDecimal;
pub use dev_nonces::DevNonces; 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 device_session::DeviceSession;
pub use key_value::KeyValue; pub use key_value::KeyValue;
pub use measurements::*; pub use measurements::*;

View File

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

View File

@ -111,33 +111,12 @@ diesel::table! {
auto_detect_measurements -> Bool, auto_detect_measurements -> Bool,
#[max_length = 100] #[max_length = 100]
region_config_id -> Nullable<Varchar>, 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, allow_roaming -> Bool,
rx1_delay -> Int2, rx1_delay -> Int2,
abp_params -> Nullable<Jsonb>, abp_params -> Nullable<Jsonb>,
class_b_params -> Nullable<Jsonb>, class_b_params -> Nullable<Jsonb>,
class_c_params -> Nullable<Jsonb>, class_c_params -> Nullable<Jsonb>,
relay_params -> Nullable<Jsonb>,
} }
} }

View File

@ -99,33 +99,12 @@ diesel::table! {
measurements -> Text, measurements -> Text,
auto_detect_measurements -> Bool, auto_detect_measurements -> Bool,
region_config_id -> Nullable<Text>, 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, allow_roaming -> Bool,
rx1_delay -> SmallInt, rx1_delay -> SmallInt,
abp_params -> Nullable<Text>, abp_params -> Nullable<Text>,
class_b_params -> Nullable<Text>, class_b_params -> Nullable<Text>,
class_c_params -> Nullable<Text>, class_c_params -> Nullable<Text>,
relay_params -> Nullable<Text>,
} }
} }

View File

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

View File

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

View File

@ -1396,10 +1396,12 @@ impl Data {
let dp = self.device_profile.as_ref().unwrap(); let dp = self.device_profile.as_ref().unwrap();
if let lrwn::Payload::MACPayload(pl) = &self.phy_payload.payload { if let lrwn::Payload::MACPayload(pl) = &self.phy_payload.payload {
if dp.is_relay && pl.f_port.unwrap_or(0) == lrwn::LA_FPORT_RELAY { 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; return true;
} }
} }
}
false false
} }

View File

@ -381,11 +381,12 @@ impl JoinRequest {
fn abort_on_relay_only_comm(&self) -> Result<(), Error> { 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. // 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 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"); info!(dev_eui = %self.device.as_ref().unwrap().dev_eui, "Only communication through relay is allowed");
return Err(Error::Abort); return Err(Error::Abort);
} }
}
Ok(()) Ok(())
} }

View File

@ -4,12 +4,8 @@ use std::ops::{Deref, DerefMut};
use std::time::Duration; use std::time::Duration;
use anyhow::Result; 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")] #[cfg(feature = "serde")]
use serde::Serialize; use serde::{Deserialize, Serialize};
use crate::cflist::ChMask; use crate::cflist::ChMask;
use crate::dl_settings::DLSettings; use crate::dl_settings::DLSettings;
@ -1811,10 +1807,10 @@ impl PayloadCodec for RelayConfAnsPayload {
} }
} }
#[derive(Debug, PartialEq, Eq, Clone, Copy)] #[derive(Default, Debug, PartialEq, Eq, Clone, Copy)]
#[cfg_attr(feature = "serde", derive(Serialize))] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "diesel", derive(AsExpression, FromSqlRow), diesel(sql_type = diesel::sql_types::SmallInt))]
pub enum RelayModeActivation { pub enum RelayModeActivation {
#[default]
DisableRelayMode, DisableRelayMode,
EnableRelayMode, EnableRelayMode,
Dynamic, 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)] #[derive(Debug, PartialEq, Eq, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize))] #[cfg_attr(feature = "serde", derive(Serialize))]
pub struct ActivationRelayMode { pub struct ActivationRelayMode {