1pub(crate) mod api;
2pub(crate) mod error;
3pub(crate) mod messages;
4pub(crate) mod service;
5use rusty_cosp::{RustyCospInitiatorIsoStack, RustyCospReaderIsoStack, RustyCospResponderIsoStack, RustyCospWriterIsoStack};
6
7pub use api::*;
8pub use service::*;
9
10pub type RustyCoppReaderIsoStack<R> = RustyCoppReader<RustyCospReaderIsoStack<R>>;
11pub type RustyCoppWriterIsoStack<W> = RustyCoppWriter<RustyCospWriterIsoStack<W>>;
12pub type RustyCoppInitiatorIsoStack<R, W> = RustyCoppInitiator<RustyCospInitiatorIsoStack<R, W>, RustyCospReaderIsoStack<R>, RustyCospWriterIsoStack<W>>;
13pub type RustyCoppListenerIsoStack<R, W> = RustyCoppListener<RustyCospResponderIsoStack<R, W>, RustyCospReaderIsoStack<R>, RustyCospWriterIsoStack<W>>;
14pub type RustyCoppResponderIsoStack<R, W> = RustyCoppResponder<RustyCospResponderIsoStack<R, W>, RustyCospReaderIsoStack<R>, RustyCospWriterIsoStack<W>>;
15pub type RustyCoppConnectionIsoStack<R, W> = RustyCoppConnection<RustyCospReaderIsoStack<R>, RustyCospWriterIsoStack<W>>;
16
17#[cfg(test)]
18mod tests {
19 use std::{time::Duration, vec};
20
21 use der_parser::Oid;
22 use rusty_cosp::{TcpCospInitiator, TcpCospListener, TcpCospReader, TcpCospResponder, TcpCospWriter};
23 use rusty_cotp::{CotpAcceptInformation, CotpConnectInformation, CotpResponder, TcpCotpAcceptor, TcpCotpConnection, TcpCotpReader, TcpCotpWriter};
24 use rusty_tpkt::{TcpTpktConnection, TcpTpktReader, TcpTpktServer, TcpTpktWriter};
25 use tokio::join;
26 use tracing_test::traced_test;
27
28 use super::*;
29
30 #[tokio::test]
31 #[traced_test]
32 async fn it_should_create_connection() -> Result<(), anyhow::Error> {
33 let options = CoppConnectionInformation {
34 calling_presentation_selector: Some(vec![0x00, 0x00, 0x00, 0x23]),
35 called_presentation_selector: Some(vec![0x65, 0x00, 0x00, 0x00]),
36 ..Default::default()
37 };
38 let presentation_contexts = vec![
39 PresentationContext {
41 indentifier: vec![1],
42 abstract_syntax_name: Oid::from(&[2, 2, 1, 0, 1]).map_err(|e| CoppError::InternalError(e.to_string()))?,
43 transfer_syntax_name_list: vec![Oid::from(&[2, 1, 1]).map_err(|e| CoppError::InternalError(e.to_string()))?],
44 },
45 PresentationContext {
47 indentifier: vec![3],
48 abstract_syntax_name: Oid::from(&[1, 0, 9506, 2, 1]).map_err(|e| CoppError::InternalError(e.to_string()))?,
49 transfer_syntax_name_list: vec![Oid::from(&[2, 1, 1]).map_err(|e| CoppError::InternalError(e.to_string()))?],
50 },
51 ];
52 let (client_connection, server_connection) = create_copp_connection_pair_with_options(
53 Some(UserData::FullyEncoded(vec![PresentationDataValueList {
54 presentation_context_identifier: vec![0x01],
55 presentation_data_values: PresentationDataValues::SingleAsn1Type(vec![0x60, 0x09, 0xa1, 0x07, 0x06, 0x05, 0x28, 0xca, 0x22, 0x02, 0x03]),
56 transfer_syntax_name: None,
57 }])),
58 options,
59 Some(UserData::FullyEncoded(vec![PresentationDataValueList {
60 presentation_context_identifier: vec![0x01],
61 presentation_data_values: PresentationDataValues::SingleAsn1Type(vec![0x61, 0x09, 0xa1, 0x07, 0x06, 0x05, 0x28, 0xca, 0x22, 0x02, 0x03]),
62 transfer_syntax_name: None,
63 }])),
64 presentation_contexts,
65 )
66 .await?;
67
68 let (mut client_reader, mut client_writer) = client_connection.split().await?;
69 let (mut server_reader, mut server_writer) = server_connection.split().await?;
70
71 client_writer
72 .send(&UserData::FullyEncoded(vec![PresentationDataValueList {
73 presentation_context_identifier: vec![0x03],
74 presentation_data_values: PresentationDataValues::SingleAsn1Type(vec![0x60, 0x09, 0xa1, 0x07, 0x06, 0x05, 0x28, 0xca, 0x22, 0x02, 0x03]),
75 transfer_syntax_name: None,
76 }]))
77 .await?;
78 server_reader.recv().await?;
79 server_writer
80 .send(&UserData::FullyEncoded(vec![PresentationDataValueList {
81 presentation_context_identifier: vec![0x03],
82 presentation_data_values: PresentationDataValues::SingleAsn1Type(vec![0x60, 0x09, 0xa1, 0x07, 0x06, 0x05, 0x28, 0xca, 0x22, 0x02, 0x03]),
83 transfer_syntax_name: None,
84 }]))
85 .await?;
86 client_reader.recv().await?;
87
88 Ok(())
89 }
90
91 async fn create_copp_connection_pair_with_options(
92 connect_data: Option<UserData>,
93 options: CoppConnectionInformation,
94 accept_data: Option<UserData>,
95 contexts: Vec<PresentationContext>,
96 ) -> Result<(impl CoppConnection, impl CoppConnection), anyhow::Error> {
97 let test_address = "127.0.0.1:10002".parse()?;
99
100 let connect_information = CotpConnectInformation::default();
101
102 let client_path = async {
103 tokio::time::sleep(Duration::from_millis(1)).await; let tpkt_client = TcpTpktConnection::connect(test_address).await?;
105 let cotp_client = TcpCotpConnection::<TcpTpktReader, TcpTpktWriter>::initiate(tpkt_client, connect_information.clone()).await?;
106 let cosp_client = TcpCospInitiator::<TcpCotpReader<TcpTpktReader>, TcpCotpWriter<TcpTpktWriter>>::new(cotp_client, Default::default()).await?;
107 let copp_client =
108 RustyCoppInitiator::<TcpCospInitiator<TcpCotpReader<TcpTpktReader>, TcpCotpWriter<TcpTpktWriter>>, TcpCospReader<TcpCotpReader<TcpTpktReader>>, TcpCospWriter<TcpCotpWriter<TcpTpktWriter>>>::new(cosp_client, options);
109 Ok(copp_client.initiate(PresentationContextType::ContextDefinitionList(contexts), connect_data.clone()).await?)
110 };
111 let server_path = async {
112 let tpkt_server = TcpTpktServer::listen(test_address).await?;
113 let (tpkt_connection, _) = tpkt_server.accept().await?;
114 let (cotp_server, _) = TcpCotpAcceptor::<TcpTpktReader, TcpTpktWriter>::new(tpkt_connection).await?;
115 let cotp_connection = cotp_server.accept(CotpAcceptInformation::default()).await?;
116 let (cosp_listener, _) = TcpCospListener::<TcpCotpReader<TcpTpktReader>, TcpCotpWriter<TcpTpktWriter>>::new(cotp_connection).await?;
117 let (copp_listener, _) =
118 RustyCoppListener::<TcpCospResponder<TcpCotpReader<TcpTpktReader>, TcpCotpWriter<TcpTpktWriter>>, TcpCospReader<TcpCotpReader<TcpTpktReader>>, TcpCospWriter<TcpCotpWriter<TcpTpktWriter>>>::new(cosp_listener).await?;
119 let (copp_responder, connect_user_data) = copp_listener.responder().await?;
120
121 Ok((copp_responder.accept(accept_data.clone()).await?, connect_user_data))
122 };
123
124 let (copp_client, copp_server): (Result<_, anyhow::Error>, Result<_, anyhow::Error>) = join!(client_path, server_path);
125 let (copp_client, accepted_data) = copp_client?;
126 let (copp_server, connected_data) = copp_server?;
127
128 assert_eq!(accept_data, accepted_data);
129 assert_eq!(connect_data, connected_data);
130
131 Ok((copp_client, copp_server))
132 }
133}