pub enum MacCommand {
Show 33 variants
LinkCheckReq,
LinkCheckAns {
margin: u8,
gateways: u8,
},
LinkAdrReq {
data_rate: u8,
tx_power: u8,
channel_mask: u16,
mask_control: u8,
transmissions: u8,
},
LinkAdrAns {
power_ack: bool,
data_rate_ack: bool,
channel_mask_ack: bool,
},
DutyCycleReq {
max_duty_cycle: u8,
},
DutyCycleAns,
RxParamSetupReq {
rx1_offset: u8,
rx2_data_rate: u8,
frequency_hz: u32,
},
RxParamSetupAns {
rx1_offset_ack: bool,
rx2_data_rate_ack: bool,
channel_ack: bool,
},
DevStatusReq,
DevStatusAns {
battery: u8,
margin: i8,
},
NewChannelReq {
index: u8,
frequency_hz: u32,
max_data_rate: u8,
min_data_rate: u8,
},
NewChannelAns {
data_rate_range_ok: bool,
frequency_ok: bool,
},
RxTimingSetupReq {
delay: u8,
},
RxTimingSetupAns,
TxParamSetupReq {
max_eirp: u8,
uplink_dwell: bool,
downlink_dwell: bool,
},
TxParamSetupAns,
DlChannelReq {
index: u8,
frequency_hz: u32,
},
DlChannelAns {
uplink_frequency_exists: bool,
frequency_ok: bool,
},
DeviceTimeReq,
DeviceTimeAns {
seconds: u32,
fraction: u8,
},
RelayConfReq {
enabled: bool,
cad_periodicity: u8,
default_channel_index: u8,
second_channel_index: u8,
second_channel_data_rate: u8,
second_channel_ack_offset: u8,
second_channel_frequency_hz: u32,
},
RelayConfAns {
cad_periodicity_ack: bool,
default_channel_index_ack: bool,
second_channel_index_ack: bool,
second_channel_data_rate_ack: bool,
second_channel_ack_offset_ack: bool,
second_channel_frequency_ack: bool,
},
EndDeviceConfReq {
relay_mode: u8,
smart_enable_level: u8,
back_off: u8,
second_channel_index: u8,
second_channel_data_rate: u8,
second_channel_ack_offset: u8,
second_channel_frequency_hz: u32,
},
EndDeviceConfAns {
second_channel_ack_offset_ack: bool,
second_channel_index_ack: bool,
second_channel_data_rate_ack: bool,
second_channel_frequency_ack: bool,
},
FilterListReq {
index: u8,
action: u8,
eui_len: u8,
eui: [u8; 16],
},
FilterListAns {
combined_rules_ack: bool,
eui_len_ack: bool,
action_ack: bool,
},
UpdateUplinkListReq {
index: u8,
reload_rate: u8,
bucket_size: u8,
dev_addr: u32,
wfcnt: u32,
root_wor_s_key: [u8; 16],
},
UpdateUplinkListAns,
CtrlUplinkListReq {
index: u8,
action: u8,
},
CtrlUplinkListAns {
index_ack: bool,
wfcnt: u32,
},
ConfigureFwdLimitReq {
reset_limit_counters: u8,
join_request_reload_rate: u8,
notify_reload_rate: u8,
global_uplink_reload_rate: u8,
overall_reload_rate: u8,
join_request_bucket_size: u8,
notify_bucket_size: u8,
global_uplink_bucket_size: u8,
overall_bucket_size: u8,
},
ConfigureFwdLimitAns,
NotifyNewEndDeviceReq {
dev_addr: u32,
rssi_dbm: i16,
snr_db: i8,
},
}Expand description
One command, in either direction.
The name says which way it travels: a request goes to a device, an answer comes back.
Variants§
LinkCheckReq
A device asking whether the network can hear it.
LinkCheckAns
How well it was heard, and by how many gateways.
Fields
LinkAdrReq
Change rate, power, and which channels may be used.
Fields
LinkAdrAns
Which parts of the request a device took.
Fields
DutyCycleReq
Hold the device to a share of the air.
Fields
DutyCycleAns
The device took it.
RxParamSetupReq
Set where and how fast the second receive window listens.
Fields
RxParamSetupAns
Which parts of that the device took.
Fields
DevStatusReq
Ask a device how it is.
DevStatusAns
How it is.
Fields
NewChannelReq
Create a channel, or change one.
Fields
NewChannelAns
Whether the channel could be made.
Fields
RxTimingSetupReq
Set how long after sending the device starts listening.
Fields
delay: u8The delay in seconds as the command codes it, which
receive_delay_s reads.
RxTimingSetupAns
The device took it.
TxParamSetupReq
Set the power and dwell time a region asks for.
Fields
TxParamSetupAns
The device took it.
DlChannelReq
Move a channel’s downlink frequency away from its uplink one.
DlChannelAns
Whether that could be done.
Fields
DeviceTimeReq
A device asking the network what time it is.
DeviceTimeAns
The time, taken as the uplink that asked finished arriving.
Fields
RelayConfReq
Start or stop a relay, and set the channels it scans.
Fields
cad_periodicity: u8How often the relay scans its default channel, as TS011-1.0.1 table 18 codes it.
second_channel_index: u8Whether a second channel is set, as table 34 codes it: 0 for none, 1 for the one the next fields describe.
RelayConfAns
Which parts of the relay configuration were valid.
Fields
EndDeviceConfReq
Set how an end device uses a relay.
Fields
relay_mode: u8Whether relaying is off (0), on (1), turned on after uplinks go unanswered (2), or left to the device (3), TS011-1.0.1 table 40.
smart_enable_level: u8How many unanswered uplinks turn relaying on in mode 2, as table 41 codes it.
back_off: u8How many wake-on-radio frames without an acknowledgment before the uplink goes anyway, 0 meaning every time, table 43.
EndDeviceConfAns
Which parts of the end device configuration were valid, TS011-1.0.1 table 45.
Fields
FilterListReq
Set one rule of a relay’s join request filter.
Fields
eui_len: u8How many leading bytes of JoinEUI and DevEUI the rule matches. A length past
FILTER_EUI_MAX is kept, so a relay can refuse it, but not its bytes past the
sixteenth.
FilterListAns
Which parts of the filter rule were valid.
Fields
UpdateUplinkListReq
Trust an end device, so a relay verifies its wake-on-radio frames and forwards it.
Fields
UpdateUplinkListAns
The relay took it.
CtrlUplinkListReq
Read the counter of a trusted end device, or remove it.
Fields
CtrlUplinkListAns
The entry’s last valid counter.
Fields
ConfigureFwdLimitReq
Set a relay’s forwarding limits, TS011-1.0.1 section 10.6.
Fields
ConfigureFwdLimitAns
The relay took it.
NotifyNewEndDeviceReq
A relay heard a wake-on-radio frame it could not verify.
Implementations§
Source§impl MacCommand
impl MacCommand
Sourcepub const fn cid(&self) -> u8
pub const fn cid(&self) -> u8
The identifier this command goes out under.
§Returns
The byte, which is shared with the command answering it in the other direction.
§Examples
use pamoja_lorawan::mac::{MacCommand, CID_LINK_ADR};
let answer = MacCommand::LinkAdrAns {
power_ack: true,
data_rate_ack: true,
channel_mask_ack: true,
};
assert_eq!(answer.cid(), CID_LINK_ADR, "the same byte as the request");Sourcepub const fn direction(&self) -> Direction
pub const fn direction(&self) -> Direction
Which way this command travels.
§Returns
Direction::Downlink for what a network sends, Direction::Uplink for what a
device answers with.
§Examples
use pamoja_lorawan::{Direction, mac::MacCommand};
assert_eq!(MacCommand::DevStatusReq.direction(), Direction::Downlink);
assert_eq!(MacCommand::LinkCheckReq.direction(), Direction::Uplink);Sourcepub const fn len(&self) -> usize
pub const fn len(&self) -> usize
How many bytes this command takes, its identifier included.
§Returns
The length, which a reader has to know because the bytes do not carry it.
§Examples
use pamoja_lorawan::mac::MacCommand;
assert_eq!(MacCommand::LinkCheckReq.len(), 1, "the identifier and nothing else");
assert_eq!(MacCommand::DevStatusAns { battery: 200, margin: -3 }.len(), 3);Sourcepub fn encode(&self, out: &mut [u8]) -> Result<usize, LorawanError>
pub fn encode(&self, out: &mut [u8]) -> Result<usize, LorawanError>
Writes this command out.
§Arguments
out- where to write it.
§Returns
How many bytes were written.
§Errors
LorawanError::PayloadTooLong when out is shorter than the command, and
LorawanError::MalformedFrame for a frequency the field cannot hold, which is one
above 1.67 GHz or one that is not a whole number of hundreds of hertz, and for a join
filter longer than FILTER_EUI_MAX bytes.
§Examples
use pamoja_lorawan::mac::MacCommand;
use pamoja_lorawan::Direction;
// The network's answer to a link check: heard 20 dB above the floor by three gateways.
let mut out = [0u8; 8];
let command = MacCommand::LinkCheckAns { margin: 20, gateways: 3 };
let written = command.encode(&mut out).unwrap();
// The device reads it back from the downlink's frame options.
let (heard, taken) = MacCommand::parse(Direction::Downlink, &out[..written]).unwrap();
assert_eq!((heard, taken), (command, written));Sourcepub fn parse(
direction: Direction,
bytes: &[u8],
) -> Result<(MacCommand, usize), LorawanError>
pub fn parse( direction: Direction, bytes: &[u8], ) -> Result<(MacCommand, usize), LorawanError>
Reads one command.
§Arguments
direction- which way the frame carrying it travels. The same identifier is a different command each way, and nothing in the bytes says which, so this is not guessed.bytes- the command and whatever follows it.
§Returns
The command and how many bytes it took.
§Errors
LorawanError::FrameTooShort when the bytes stop inside the command, and
LorawanError::UnknownCommand carrying the identifier when it is one this
version does not know, which a caller cannot step over.
§Examples
use pamoja_lorawan::{Direction, mac::MacCommand};
// A request and its answer share an identifier, so the direction decides which one
// the same bytes are.
let mut bytes = [0u8; 2];
let request = MacCommand::DutyCycleReq { max_duty_cycle: 10 };
request.encode(&mut bytes).unwrap();
let (down, _) = MacCommand::parse(Direction::Downlink, &bytes).unwrap();
assert_eq!(down, request);
let (up, taken) = MacCommand::parse(Direction::Uplink, &bytes).unwrap();
assert_eq!(up, MacCommand::DutyCycleAns);
assert_eq!(taken, 1, "the answer has no payload, so the second byte is not its own");Trait Implementations§
Source§impl Clone for MacCommand
impl Clone for MacCommand
Source§fn clone(&self) -> MacCommand
fn clone(&self) -> MacCommand
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more