forked from Enet4/dicom-rs
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathassociation_echo.rs
86 lines (73 loc) · 2.77 KB
/
association_echo.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
use dicom_ul::{
association::client::ClientAssociationOptions,
pdu::{Pdu, PresentationContextResult, PresentationContextResultReason},
};
use std::net::TcpListener;
use std::{
net::SocketAddr,
thread::{spawn, JoinHandle},
};
use dicom_ul::association::server::ServerAssociationOptions;
type Result<T> = std::result::Result<T, Box<dyn std::error::Error + Send + Sync + 'static>>;
static SCU_AE_TITLE: &str = "ECHO-SCU";
static SCP_AE_TITLE: &str = "ECHO-SCP";
static IMPLICIT_VR_LE: &str = "1.2.840.10008.1.2";
static EXPLICIT_VR_LE: &str = "1.2.840.10008.1.2.1";
static JPEG_BASELINE: &str = "1.2.840.10008.1.2.4.50";
static VERIFICATION_SOP_CLASS: &str = "1.2.840.10008.1.1";
static DIGITAL_MG_STORAGE_SOP_CLASS: &str = "1.2.840.10008.5.1.4.1.1.1.2";
fn spawn_scp() -> Result<(JoinHandle<Result<()>>, SocketAddr)> {
let listener = TcpListener::bind("localhost:0")?;
let addr = listener.local_addr()?;
let scp = ServerAssociationOptions::new()
.accept_called_ae_title()
.ae_title(SCP_AE_TITLE)
.with_abstract_syntax(VERIFICATION_SOP_CLASS);
let h = spawn(move || -> Result<()> {
let (stream, _addr) = listener.accept()?;
let mut association = scp.establish(stream)?;
assert_eq!(
association.presentation_contexts(),
&[
PresentationContextResult {
id: 1,
reason: PresentationContextResultReason::Acceptance,
transfer_syntax: IMPLICIT_VR_LE.to_string(),
},
PresentationContextResult {
id: 3,
reason: PresentationContextResultReason::AbstractSyntaxNotSupported,
transfer_syntax: IMPLICIT_VR_LE.to_string(),
}
],
);
// handle one release request
let pdu = association.receive()?;
assert_eq!(pdu, Pdu::ReleaseRQ);
association.send(&Pdu::ReleaseRP)?;
Ok(())
});
Ok((h, addr))
}
/// Run an SCP and an SCU concurrently, negotiate an association and release it.
#[test]
fn scu_scp_association_test() {
let (scp_handle, scp_addr) = spawn_scp().unwrap();
let association = ClientAssociationOptions::new()
.calling_ae_title(SCU_AE_TITLE)
.called_ae_title(SCP_AE_TITLE)
.with_presentation_context(VERIFICATION_SOP_CLASS, vec![IMPLICIT_VR_LE, EXPLICIT_VR_LE])
.with_presentation_context(
DIGITAL_MG_STORAGE_SOP_CLASS,
vec![IMPLICIT_VR_LE, EXPLICIT_VR_LE, JPEG_BASELINE],
)
.establish(scp_addr)
.unwrap();
association
.release()
.expect("did not have a peaceful release");
scp_handle
.join()
.expect("SCP panicked")
.expect("Error at the SCP");
}