@startuml
!theme mars
skinparam defaultFontSize 20
skinparam classFontSize 22
skinparam backgroundColor transparent
left to right direction
skinparam linetype ortho
!define AbstractClass class
hide empty members
hide circles

class E3Interface {
    -- Attributes --
    - _instance : E3Interface
    - _lock : threading.Lock
    - callbacks : list
    - stop_event : multiprocessing.Event
    - e3_connector : E3Connector
    -- Methods --
    __new__()
    __init__(link: str, transport: str)
    + add_callback(callback)
    + remove_callback(callback)
    + terminate_connections()
    - _handle_incoming_data(data)
    - schedule_control(payload: bytes)
    - schedule_report(payload: bytes)
}

AbstractClass SpectrumSharingDApp {
    -- Attributes --
    - counter : int
    - limit_per_file : int
    - FFT_SIZE : int
    - Noise_floor_threshold : int
    - First_carrier_offset : int
    - Average_over_frames : int
    - Num_car_prb : int
    - prb_thrs : int
    -- Methods --
    __init__(ota: bool, save_iqs: bool, control: bool, **kwargs)
    + get_iqs_from_ran(data)
    + stop()
}


AbstractClass DApp {
    -- Attributes --
    - e3_interface : E3Interface
    - control : bool
    -- Methods --
    __init__(ota: bool, save_iqs: bool, control: bool, **kwargs)
    + setup_connection()
    + control_loop()
    + stop()
}

class E3LinkLayer {
    -- Enumeration --
    + ZMQ = "zmq"
    + POSIX = "posix"
    -- Methods --
    + from_string(link_layer_str: str)
}

class E3TransportLayer {
    -- Enumeration --
    + SCTP = "sctp"
    + TCP = "tcp"
    + IPC = "ipc"
    -- Methods --
    + from_string(transport_layer_str: str)
}

AbstractClass E3Connector {
    -- Attributes --
    - VALID_CONFIGURATIONS : list
    - E3_IPC_SETUP_PATH : str
    - E3_IPC_SOCKET_PATH : str
    - DAPP_IPC_SOCKET_PATH : str
    -- Methods --
    + setup_connector(link_layer: str, transport_layer: str)
    + send_setup_request(payload: bytes)
    + setup_inbound_connection()
    + setup_outbound_connection()
    + send(payload: bytes)
    + receive() : bytes
    + dispose()
}

class ZMQConnector {
    -- Attributes --
    - setup_context : zmq.Context
    - inbound_context : zmq.Context
    - outbound_context : zmq.Context
    - transport_layer : E3TransportLayer
    -- Methods --
    + __init__(transport_layer: E3TransportLayer)
    + send_setup_request(payload: bytes)
    + setup_inbound_connection()
    + setup_outbound_connection()
    + send(payload: bytes)
    + receive() : bytes
    + dispose()
}

class POSIXConnector {
    -- Attributes --
    - transport_layer : E3TransportLayer
    - CHUNK_SIZE : int
    -- Methods --
    + __init__(transport_layer: E3TransportLayer)
    + send_setup_request(payload: bytes)
    + setup_inbound_connection()
    + setup_outbound_connection()
    + send(payload: bytes)
    + receive() : bytes
    + dispose()
}

DApp --> E3Interface
DApp <|-- SpectrumSharingDApp
E3Connector <|-- ZMQConnector
E3Connector <|-- POSIXConnector
E3Interface --* E3Connector
E3Connector --> E3LinkLayer 
E3Connector --> E3TransportLayer
@enduml
