Skip to main content

rusty_copp/
api.rs

1use der_parser::Oid;
2use rusty_cosp::CospError;
3use thiserror::Error;
4
5pub use crate::messages::user_data::*;
6
7#[derive(Error, Debug)]
8pub enum CoppError {
9    #[error("COPP Protocol Error - {}", .0)]
10    ProtocolError(String),
11
12    #[error("COPP over COSP Protocol Stack Error - {}", .0)]
13    ProtocolStackError(#[from] CospError),
14
15    #[error("COPP IO Error: {:?}", .0)]
16    IoError(#[from] std::io::Error),
17
18    #[error("COPP Error: {}", .0)]
19    InternalError(String),
20}
21
22// TODO Support Default Context. This library is targeted towards ACSE/MMS which does not require the default context.
23#[derive(PartialEq, Clone, Debug)]
24pub enum PresentationContextType {
25    // DefaultContext,
26    ContextDefinitionList(Vec<PresentationContext>),
27}
28
29#[derive(PartialEq, Clone, Debug)]
30pub enum PresentationContextResultType {
31    // DefaultContextAccept,
32    // DefaultContextReject,
33    ContextDefinitionList(Vec<PresentationContextResult>),
34}
35
36#[derive(PartialEq, Clone, Debug)]
37pub struct PresentationContext {
38    pub indentifier: Vec<u8>, // ASN1 Integer
39    pub abstract_syntax_name: Oid<'static>,
40    pub transfer_syntax_name_list: Vec<Oid<'static>>,
41}
42
43#[derive(PartialEq, Clone, Debug)]
44pub enum PresentationContextResultCause {
45    Acceptance,
46    UserRejection,
47    ProviderRejection,
48    Unknown,
49}
50
51impl From<PresentationContextResultCause> for &[u8] {
52    fn from(value: PresentationContextResultCause) -> Self {
53        match value {
54            PresentationContextResultCause::Acceptance => &[0],
55            PresentationContextResultCause::UserRejection => &[1],
56            PresentationContextResultCause::ProviderRejection => &[2],
57            PresentationContextResultCause::Unknown => &[1], // Map Unknown to User Rejection
58        }
59    }
60}
61
62#[derive(PartialEq, Clone, Debug)]
63pub enum PresentationContextResultProviderReason {
64    ReasonNotSpecified,
65    AbstrctSyntaxNotSupported,
66    ProposedAbstrctSyntaxNotSupported,
67    LocalLimitOnDcsExceeded,
68}
69
70impl From<PresentationContextResultProviderReason> for &[u8] {
71    fn from(value: PresentationContextResultProviderReason) -> Self {
72        match value {
73            PresentationContextResultProviderReason::ReasonNotSpecified => &[0],
74            PresentationContextResultProviderReason::AbstrctSyntaxNotSupported => &[1],
75            PresentationContextResultProviderReason::ProposedAbstrctSyntaxNotSupported => &[2],
76            PresentationContextResultProviderReason::LocalLimitOnDcsExceeded => &[3],
77        }
78    }
79}
80
81#[derive(PartialEq, Clone, Debug)]
82pub struct PresentationContextResult {
83    pub result: PresentationContextResultCause,
84    pub transfer_syntax_name: Option<Oid<'static>>,
85    pub provider_reason: Option<PresentationContextResultProviderReason>,
86}
87
88#[derive(PartialEq, Clone, Debug)]
89pub struct CoppConnectionInformation {
90    pub calling_presentation_selector: Option<Vec<u8>>,
91    pub called_presentation_selector: Option<Vec<u8>>,
92}
93
94impl Default for CoppConnectionInformation {
95    fn default() -> Self {
96        Self {
97            calling_presentation_selector: None,
98            called_presentation_selector: None,
99        }
100    }
101}
102
103pub enum CoppRecvResult {
104    Closed,
105    Data(UserData),
106}
107
108pub trait CoppInitiator: Send {
109    fn initiate(self, presentation_contexts: PresentationContextType, user_data: Option<UserData>) -> impl std::future::Future<Output = Result<(impl CoppConnection, Option<UserData>), CoppError>> + Send;
110}
111
112pub trait CoppListener: Send {
113    fn responder(self) -> impl std::future::Future<Output = Result<(impl CoppResponder, Option<UserData>), CoppError>> + Send;
114}
115
116pub trait CoppResponder: Send {
117    fn accept(self, accept_data: Option<UserData>) -> impl std::future::Future<Output = Result<impl CoppConnection, CoppError>> + Send;
118}
119
120pub trait CoppConnection: Send {
121    fn split(self) -> impl std::future::Future<Output = Result<(impl CoppReader, impl CoppWriter), CoppError>> + Send;
122}
123
124pub trait CoppReader: Send {
125    fn recv(&mut self) -> impl std::future::Future<Output = Result<CoppRecvResult, CoppError>> + Send;
126}
127
128pub trait CoppWriter: Send {
129    fn send(&mut self, data: &UserData) -> impl std::future::Future<Output = Result<(), CoppError>> + Send;
130    fn continue_send(&mut self) -> impl std::future::Future<Output = Result<(), CoppError>> + Send;
131}