use dicom_toolkit_core::error::{DcmError, DcmResult};
use dicom_toolkit_data::DataSet;
use dicom_toolkit_dict::tags;
use crate::association::Association;
pub async fn c_echo(assoc: &mut Association, context_id: u8) -> DcmResult<()> {
let mut cmd = DataSet::new();
cmd.set_uid(tags::AFFECTED_SOP_CLASS_UID, "1.2.840.10008.1.1");
cmd.set_u16(tags::COMMAND_FIELD, 0x0030); cmd.set_u16(tags::MESSAGE_ID, next_message_id());
cmd.set_u16(tags::COMMAND_DATA_SET_TYPE, 0x0101);
assoc.send_dimse_command(context_id, &cmd).await?;
let (_ctx, rsp) = assoc.recv_dimse_command().await?;
let status = rsp.get_u16(tags::STATUS).unwrap_or(0xFFFF);
if status != 0x0000 {
return Err(DcmError::DimseError {
status,
description: format!("C-ECHO failed with status 0x{:04X}", status),
});
}
Ok(())
}
fn next_message_id() -> u16 {
use std::sync::atomic::{AtomicU16, Ordering};
static ID: AtomicU16 = AtomicU16::new(1);
ID.fetch_add(1, Ordering::Relaxed)
}
#[cfg(test)]
mod tests {
use super::*;
use crate::dimse;
use dicom_toolkit_data::DataSet;
#[test]
fn echo_rq_command_fields() {
let mut cmd = DataSet::new();
cmd.set_uid(tags::AFFECTED_SOP_CLASS_UID, "1.2.840.10008.1.1");
cmd.set_u16(tags::COMMAND_FIELD, 0x0030);
cmd.set_u16(tags::MESSAGE_ID, 1);
cmd.set_u16(tags::COMMAND_DATA_SET_TYPE, 0x0101);
let bytes = dimse::encode_command_dataset(&cmd);
let decoded = dimse::decode_command_dataset(&bytes).unwrap();
assert_eq!(decoded.get_u16(tags::COMMAND_FIELD), Some(0x0030));
assert_eq!(
decoded.get_string(tags::AFFECTED_SOP_CLASS_UID),
Some("1.2.840.10008.1.1")
);
assert_eq!(decoded.get_u16(tags::COMMAND_DATA_SET_TYPE), Some(0x0101));
}
#[test]
fn echo_rsp_command_fields() {
let mut rsp = DataSet::new();
rsp.set_uid(tags::AFFECTED_SOP_CLASS_UID, "1.2.840.10008.1.1");
rsp.set_u16(tags::COMMAND_FIELD, 0x8030); rsp.set_u16(tags::MESSAGE_ID_BEING_RESPONDED_TO, 1);
rsp.set_u16(tags::COMMAND_DATA_SET_TYPE, 0x0101);
rsp.set_u16(tags::STATUS, 0x0000);
let bytes = dimse::encode_command_dataset(&rsp);
let decoded = dimse::decode_command_dataset(&bytes).unwrap();
assert_eq!(decoded.get_u16(tags::COMMAND_FIELD), Some(0x8030));
assert_eq!(decoded.get_u16(tags::STATUS), Some(0x0000));
}
}