Skip to content

Commit ef5b6dc

Browse files
committed
Add base64 encoding support to tedge mqtt
Signed-off-by: Didier Wenzek <[email protected]>
1 parent 9b67436 commit ef5b6dc

File tree

4 files changed

+54
-10
lines changed

4 files changed

+54
-10
lines changed

crates/core/tedge/src/cli/mqtt/cli.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ pub enum TEdgeMqttCli {
3030
/// Retain flag
3131
#[clap(short, long = "retain")]
3232
retain: bool,
33+
/// Decode the payload before publishing
34+
#[clap(long)]
35+
base64: bool,
3336
/// Repeat the message
3437
#[clap(long)]
3538
repeat: Option<u32>,
@@ -51,6 +54,9 @@ pub enum TEdgeMqttCli {
5154
/// Avoid printing the message topics on the console
5255
#[clap(long = "no-topic")]
5356
hide_topic: bool,
57+
/// Encode the received payloads
58+
#[clap(long)]
59+
base64: bool,
5460
/// Disconnect and exit after the specified timeout (e.g., 60s, 1h)
5561
#[clap(long, short = 'W')]
5662
duration: Option<SecondsOrHumanTime>,
@@ -75,6 +81,7 @@ impl BuildCommand for TEdgeMqttCli {
7581
message,
7682
qos,
7783
retain,
84+
base64,
7885
repeat,
7986
sleep,
8087
} => MqttPublishCommand {
@@ -85,6 +92,7 @@ impl BuildCommand for TEdgeMqttCli {
8592
qos,
8693
client_id: format!("{}-{}", PUB_CLIENT_PREFIX, std::process::id()),
8794
retain,
95+
base64,
8896
ca_file: auth_config.ca_file.clone(),
8997
ca_dir: auth_config.ca_dir,
9098
client_auth_config: auth_config.client,
@@ -96,6 +104,7 @@ impl BuildCommand for TEdgeMqttCli {
96104
topic,
97105
qos,
98106
hide_topic,
107+
base64,
99108
duration,
100109
count,
101110
retained_only,
@@ -105,6 +114,7 @@ impl BuildCommand for TEdgeMqttCli {
105114
topic,
106115
qos,
107116
hide_topic,
117+
base64,
108118
client_id: format!("{}-{}", SUB_CLIENT_PREFIX, std::process::id()),
109119
ca_file: auth_config.ca_file,
110120
ca_dir: auth_config.ca_dir,

crates/core/tedge/src/cli/mqtt/publish.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use crate::command::Command;
22
use crate::log::MaybeFancy;
3+
use base64::prelude::*;
34
use camino::Utf8PathBuf;
45
use mqtt_channel::MqttMessage;
56
use mqtt_channel::PubChannel;
@@ -19,6 +20,7 @@ pub struct MqttPublishCommand {
1920
pub qos: mqtt_channel::QoS,
2021
pub client_id: String,
2122
pub retain: bool,
23+
pub base64: bool,
2224
pub ca_file: Option<Utf8PathBuf>,
2325
pub ca_dir: Option<Utf8PathBuf>,
2426
pub client_auth_config: Option<MqttAuthClientConfig>,
@@ -72,7 +74,13 @@ async fn publish(cmd: &MqttPublishCommand) -> Result<(), anyhow::Error> {
7274
let mut mqtt = mqtt_channel::Connection::new(&config).await?;
7375
let mut signals = tedge_utils::signals::TermSignals::new(None);
7476

75-
let message = MqttMessage::new(&cmd.topic, cmd.message.clone())
77+
let payload = if cmd.base64 {
78+
BASE64_STANDARD.decode(cmd.message.as_bytes())?
79+
} else {
80+
cmd.message.clone().into_bytes()
81+
};
82+
83+
let message = MqttMessage::new(&cmd.topic, payload)
7684
.with_qos(cmd.qos)
7785
.with_retain_flag(cmd.retain);
7886

crates/core/tedge/src/cli/mqtt/subscribe.rs

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
use crate::command::Command;
22
use crate::log::MaybeFancy;
3+
use base64::prelude::*;
34
use camino::Utf8PathBuf;
5+
use mqtt_channel::MqttMessage;
46
use mqtt_channel::QoS;
57
use mqtt_channel::StreamExt;
68
use mqtt_channel::TopicFilter;
@@ -20,6 +22,7 @@ pub struct MqttSubscribeCommand {
2022
pub topic: SimpleTopicFilter,
2123
pub qos: QoS,
2224
pub hide_topic: bool,
25+
pub base64: bool,
2326
pub client_id: String,
2427
pub ca_file: Option<Utf8PathBuf>,
2528
pub ca_dir: Option<Utf8PathBuf>,
@@ -83,27 +86,38 @@ async fn subscribe(cmd: &MqttSubscribeCommand) -> Result<(), anyhow::Error> {
8386
}
8487
};
8588

89+
if cmd.retained_only && !message.retain {
90+
info!(target: "MQTT", "Received first non-retained message. topic={}", message.topic.name);
91+
break;
92+
}
93+
94+
let message = if cmd.base64 {
95+
MqttMessage::new(
96+
&message.topic,
97+
BASE64_STANDARD.encode(message.payload_bytes()),
98+
)
99+
} else {
100+
message
101+
};
102+
86103
match message.payload_str() {
87104
Ok(payload) => {
88-
if cmd.retained_only && !message.retain {
89-
info!(target: "MQTT", "Received first non-retained message. topic={}", message.topic.name);
90-
break;
91-
}
92105
let line = if cmd.hide_topic {
93106
format!("{payload}\n")
94107
} else {
95108
format!("[{}] {payload}\n", &message.topic)
96109
};
97110
let _ = stdout.write_all(line.as_bytes()).await;
98111
let _ = stdout.flush().await;
99-
n_messages += 1;
100-
if matches!(cmd.count, Some(count) if count > 0 && n_messages >= count) {
101-
info!(target: "MQTT", "Received {n_messages} message/s");
102-
break;
103-
}
104112
}
105113
Err(err) => error!(target: "MQTT", "{err}"),
106114
}
115+
116+
n_messages += 1;
117+
if matches!(cmd.count, Some(count) if count > 0 && n_messages >= count) {
118+
info!(target: "MQTT", "Received {n_messages} message/s");
119+
break;
120+
}
107121
}
108122

109123
mqtt.published.close_channel();

tests/RobotFramework/tests/tedge/tedge_mqtt.robot

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,18 @@ tedge mqtt sub breaks after receiving first non-retailed message
4545
Should Contain ${messages[0]} [foo/1] bar1
4646
Should Contain ${messages[1]} [foo/2] bar2
4747

48+
sending binary payload with tedge mqtt
49+
Execute Command
50+
... tedge mqtt pub -r --base64 te/device/main///m/ eyAidGVtcGVyYXR1cmUiOiAzMC4yLCAiaHVtaWRpdHkiOiAyMyB9
51+
${messages}= Execute Command tedge mqtt sub te/device/main///m/ --count 1
52+
Should Contain ${messages} { "temperature": 30.2, "humidity": 23 }
53+
54+
receiving binary payload with tedge mqtt
55+
Execute Command
56+
... tedge mqtt pub -r te/device/main///m/ '{ "temperature": 30.2, "humidity": 23 }'
57+
${messages}= Execute Command tedge mqtt sub --base64 te/device/main///m/ --count 1
58+
Should Contain ${messages} eyAidGVtcGVyYXR1cmUiOiAzMC4yLCAiaHVtaWRpdHkiOiAyMyB9
59+
4860

4961
*** Keywords ***
5062
Validate duration

0 commit comments

Comments
 (0)