mqtt: fix ignoring args

This commit is contained in:
occheung 2020-09-15 13:03:54 +08:00
parent 4b52aa7099
commit 5438a81722
2 changed files with 33 additions and 10 deletions

View File

@ -272,7 +272,11 @@ fn main() -> ! {
.poll(|_client, topic, message, _properties| match topic { .poll(|_client, topic, message, _properties| match topic {
topic => { topic => {
info!("On '{:?}', received: {:?}", topic, message); info!("On '{:?}', received: {:?}", topic, message);
context.run_with_mqtt(topic.as_bytes(), &mut buf); // Why is topic a string while message is a slice?
context.run_with_mqtt(topic,
core::str::from_utf8(message).unwrap(),
&mut buf)
.unwrap();
}, },
}).is_ok(); }).is_ok();

View File

@ -2,27 +2,46 @@ use scpi::prelude::*;
use scpi::Context; use scpi::Context;
use scpi::error::Result; use scpi::error::Result;
use arrayvec::{ArrayVec}; use core::concat;
use arrayvec::{ArrayVec, ArrayString};
pub trait MqttScpiTranslator { pub trait MqttScpiTranslator {
fn run_with_mqtt<FMT: Formatter>(&mut self, s: &[u8], response: &mut FMT) -> Result<()>; // Convert an MQTT publish message into SCPI compatible command
// The argument part/ MQTT message must follow SCPI standard for parameter formatting
fn run_with_mqtt<FMT: Formatter>(&mut self, topic: &str, args: &str, response: &mut FMT) -> Result<()>;
} }
impl<'a, T: Device> MqttScpiTranslator for Context<'a, T> { impl<'a, T: Device> MqttScpiTranslator for Context<'a, T> {
fn run_with_mqtt<FMT>(&mut self, s: &[u8], response: &mut FMT) -> Result<()> fn run_with_mqtt<FMT>(&mut self, topic: &str, args: &str, response: &mut FMT) -> Result<()>
where where
FMT: Formatter, FMT: Formatter,
{ {
let mut array_vec = ArrayVec::<[u8; 1024]>::new(); // Create a fixed-size buffer to handle slice operation
for i in s.into_iter() { let mut buffer = ArrayVec::<[u8; 1024]>::new();
if *i == b'/' {
array_vec.try_push(b'/') // Copy MQTT topic, convert it into SCPI header format
for i in topic.chars() {
if i == '/' {
// The topic separator is colon(':') in SCPI, and slash('/') in MQTT
buffer.try_push(b':')
.map_err(|_| ErrorCode::OutOfMemory)?; .map_err(|_| ErrorCode::OutOfMemory)?;
} else { } else {
array_vec.try_push(*i) buffer.try_push(i as u8)
.map_err(|_| ErrorCode::OutOfMemory)?; .map_err(|_| ErrorCode::OutOfMemory)?;
} }
} }
self.run(array_vec.as_slice(), response)
// Place a space bar between header and parameter
buffer.try_push(b' ')
.map_err(|_| ErrorCode::OutOfMemory)?;
// Copy the arguments into the buffer
for i in args.chars() {
buffer.try_push(i as u8)
.map_err(|_| ErrorCode::OutOfMemory)?;
}
self.run(buffer.as_slice(), response)
} }
} }