use crate::util::rtt::{RttDataHandler, client::RttClient};
use crate::{
cmd::dap_server::{
DebuggerError,
debug_adapter::{dap::adapter::*, protocol::ProtocolAdapter},
},
util::rtt::RttDecoder,
};
use anyhow::anyhow;
use probe_rs::{Core, rtt};
pub struct RttConnection {
pub(crate) client: RttClient,
pub(crate) debugger_rtt_channels: Vec<DebuggerRttChannel>,
}
impl RttConnection {
pub async fn process_rtt_data<P: ProtocolAdapter>(
&mut self,
debug_adapter: &mut DebugAdapter<P>,
target_core: &mut Core<'_>,
) -> bool {
let mut at_least_one_channel_had_data = false;
for debugger_rtt_channel in self.debugger_rtt_channels.iter_mut() {
at_least_one_channel_had_data |= debugger_rtt_channel
.poll_rtt_data(target_core, debug_adapter, &mut self.client)
.await
}
at_least_one_channel_had_data
}
pub fn clean_up(&mut self, target_core: &mut Core<'_>) -> Result<(), DebuggerError> {
self.client
.clean_up(target_core)
.map_err(|err| DebuggerError::Other(anyhow!(err)))?;
Ok(())
}
}
pub(crate) struct DebuggerRttChannel {
pub(crate) channel_number: u32,
pub(crate) has_client_window: bool,
pub(crate) channel_data_format: RttDecoder,
}
impl DebuggerRttChannel {
pub(crate) async fn poll_rtt_data<P: ProtocolAdapter>(
&mut self,
core: &mut Core<'_>,
debug_adapter: &mut DebugAdapter<P>,
client: &mut RttClient,
) -> bool {
if !self.has_client_window {
return false;
}
let mut out = StringCollector { data: None };
match client.poll_channel(core, self.channel_number) {
Ok(bytes) => self.channel_data_format.process(bytes, &mut out).await.ok(),
Err(e) => {
debug_adapter
.show_error_message(&DebuggerError::Other(anyhow!(e)))
.ok();
return false;
}
};
match out.data {
Some(data) => debug_adapter.rtt_output(self.channel_number, data),
None => false,
}
}
}
struct StringCollector {
data: Option<String>,
}
impl RttDataHandler for StringCollector {
async fn on_string_data(&mut self, data: String) -> Result<(), rtt::Error> {
self.data = Some(data);
Ok(())
}
}