Only decode mac-commands for logging if in plaintext.

Please note that for LoRaWAN 1.1.x, mac-commands in the f_opts field are
encrypted. Within the context of the device we can decrypt these, but
within the context of a gateway we can only show these as raw bytes.
This commit is contained in:
Orne Brocaar 2022-08-09 15:29:22 +01:00
parent fd62076e02
commit 2b1bf3b96f
4 changed files with 80 additions and 56 deletions

View File

@ -415,6 +415,7 @@ impl TxAck {
"".to_string()
}
},
plaintext_mac_commands: false,
};
// Log for gateway (with potentially encrypted mac-commands).
@ -451,6 +452,7 @@ impl TxAck {
m_type: dfl.m_type,
dev_addr: dfl.dev_addr.clone(),
dev_eui: dfl.dev_eui.clone(),
plaintext_mac_commands: true,
};
// Log for device.

View File

@ -40,6 +40,7 @@ pub async fn log_uplink_for_gateways(ufl: &api::UplinkFrameLog) -> Result<()> {
dev_addr: ufl.dev_addr.clone(),
dev_eui: ufl.dev_eui.clone(),
time: ufl.time.clone(),
plaintext_mac_commands: ufl.plaintext_mac_commands,
};
let b = ufl_copy.encode_to_vec();
@ -268,13 +269,16 @@ pub async fn get_frame_logs(
for stream_id in &stream_key.ids {
last_id = stream_id.id.clone();
for (k, v) in &stream_id.map {
let res = || -> Result<()> {
match k.as_ref() {
"up" => {
trace!(key = %k, id = %last_id, "Frame-log received from stream");
if let redis::Value::Data(b) = v {
let pl = api::UplinkFrameLog::decode(&mut Cursor::new(b))?;
let mut phy = lrwn::PhyPayload::from_slice(&pl.phy_payload)?;
if pl.plaintext_mac_commands {
phy.decode_f_opts_to_mac_commands()?;
}
let pl = api::LogItem {
id: stream_id.id.clone(),
@ -294,8 +298,9 @@ pub async fn get_frame_logs(
.cloned()
.collect(),
};
if channel.blocking_send(pl).is_err() {
return Err(anyhow!("Channel send error"));
if let Err(e) = channel.blocking_send(pl) {
return Err(anyhow::Error::new(e));
}
}
}
@ -304,7 +309,9 @@ pub async fn get_frame_logs(
if let redis::Value::Data(b) = v {
let pl = api::DownlinkFrameLog::decode(&mut Cursor::new(b))?;
let mut phy = lrwn::PhyPayload::from_slice(&pl.phy_payload)?;
if pl.plaintext_mac_commands {
phy.decode_f_opts_to_mac_commands()?;
}
let pl = api::LogItem {
id: stream_id.id.clone(),
@ -325,8 +332,8 @@ pub async fn get_frame_logs(
.collect(),
};
if channel.blocking_send(pl).is_err() {
return Err(anyhow!("Channel send error"));
if let Err(e) = channel.blocking_send(pl) {
return Err(anyhow::Error::new(e));
}
}
}
@ -334,6 +341,19 @@ pub async fn get_frame_logs(
error!(key = %k, "Unexpected key in frame-log stream");
}
}
Ok(())
}();
if let Err(e) = res {
// Return in case of channel error, in any other case we just log
// the error.
if let Some(_) = e.downcast_ref::<mpsc::error::SendError<api::LogItem>>() {
return Err(e);
}
error!(key = %k, error = %e, "Parsing frame-log error");
}
}
}
}

View File

@ -442,6 +442,7 @@ impl Data {
trace!("Logging uplink frame-set");
let mut ufl: api::UplinkFrameLog = (&self.uplink_frame_set).try_into()?;
ufl.dev_eui = self.device.as_ref().unwrap().dev_eui.to_string();
ufl.plaintext_mac_commands = true;
framelog::log_uplink_for_device(&ufl).await?;
Ok(())
}

View File

@ -74,6 +74,7 @@ impl TryFrom<&UplinkFrameSet> for api::UplinkFrameLog {
_ => "".to_string(),
},
time: None, // is set below
plaintext_mac_commands: false,
};
for rx_info in &ufl.rx_info {