19#ifndef PACS_NETWORK_V2_DICOM_ASSOCIATION_HANDLER_HPP
20#define PACS_NETWORK_V2_DICOM_ASSOCIATION_HANDLER_HPP
79 default:
return "Unknown";
91 std::function<void(
const std::string& session_id,
92 const std::string& calling_ae,
93 const std::string& called_ae)>;
99 std::function<void(
const std::string& session_id,
bool graceful)>;
105 std::function<void(
const std::string& session_id,
const std::string& error)>;
149 :
public std::enable_shared_from_this<dicom_association_handler> {
155 using session_ptr = std::shared_ptr<kcenon::network::interfaces::i_session>;
156 using service_map = std::map<std::string, services::scp_service*>;
157 using clock = std::chrono::steady_clock;
214 void stop(
bool graceful =
false);
230 void feed_data(
const std::vector<uint8_t>& data);
268 [[nodiscard]]
bool is_closed() const noexcept;
286 [[nodiscard]] std::
string called_ae() const;
337 [[nodiscard]] uint64_t
pdus_sent() const noexcept;
426 const dimse::dimse_message& msg);
429 [[nodiscard]] services::scp_service*
find_service(const std::
string& sop_class_uid) const;
DICOM Association management per PS3.8.
Bridges network_system sessions with DICOM protocol handling.
uint64_t pdus_received() const noexcept
Get number of PDUs received.
Result< std::monostate > dispatch_to_service(uint8_t context_id, const dimse::dimse_message &msg)
Dispatch DIMSE message to appropriate service.
void start()
Start processing the session.
void handle_disconnect()
Handle session disconnection.
void transition_to(handler_state new_state)
Transition to new state.
void send_abort(abort_source source, abort_reason reason)
Send A-ABORT PDU.
void process_buffer()
Process accumulated buffer for complete PDUs.
session_ptr session_
Network session.
void feed_data(const std::vector< uint8_t > &data)
Feed received data to the handler.
std::atomic< uint64_t > pdus_sent_
void on_disconnected(const std::string &session_id)
Handle session disconnection.
dicom_association_handler(const dicom_association_handler &)=delete
void set_access_control_enabled(bool enabled)
Enable or disable access control enforcement.
handler_state state() const noexcept
Get current handler state.
void send_associate_rj(reject_result result, uint8_t source, uint8_t reason)
Send A-ASSOCIATE-RJ response.
void send_release_rp()
Send A-RELEASE-RP response.
void touch()
Update last activity timestamp.
uint64_t pdus_sent() const noexcept
Get number of PDUs sent.
services::scp_service * find_service(const std::string &sop_class_uid) const
Find service for SOP Class UID.
association_established_callback established_callback_
Callbacks.
void send_associate_ac()
Send A-ASSOCIATE-AC response.
association association_
DICOM association.
time_point last_activity_
Last activity timestamp.
dicom_association_handler & operator=(const dicom_association_handler &)=delete
bool is_established() const noexcept
Check if the association is established.
std::map< std::string, services::scp_service * > service_map
std::shared_ptr< security::access_control_manager > access_control_
Access control manager for RBAC.
void send_p_data_tf(const std::vector< uint8_t > &payload)
Send P-DATA-TF PDU.
service_map services_
Service registry (non-owning pointers)
bool access_control_enabled_
Whether access control is enabled.
std::chrono::steady_clock clock
std::string session_id() const
Get the session identifier.
void handle_associate_rq(const std::vector< uint8_t > &payload)
Handle A-ASSOCIATE-RQ PDU.
dicom_association_handler(session_ptr session, const server_config &config, const service_map &services)
Construct a handler for a network session.
uint32_t expected_pdu_length_
Expected PDU length (0 if waiting for header)
Result< std::reference_wrapper< association > > get_association()
Get the underlying association object.
pdu_type current_pdu_type_
Current PDU type being received.
void on_data_received(const std::vector< uint8_t > &data)
Handle data received from session.
static constexpr size_t pdu_header_size
PDU header size (type + reserved + length)
void close_handler(bool graceful)
Close and cleanup.
std::atomic< handler_state > state_
Current handler state.
std::atomic< uint64_t > pdus_received_
Statistics.
std::atomic< uint64_t > messages_processed_
void set_established_callback(association_established_callback callback)
Set callback for association established event.
void set_closed_callback(association_closed_callback callback)
Set callback for association closed event.
association_closed_callback closed_callback_
time_point last_activity() const noexcept
Get time of last activity.
bool is_closed() const noexcept
Check if the handler is closed.
std::mutex mutex_
Thread safety.
clock::time_point time_point
dicom_association_handler(dicom_association_handler &&)=delete
std::chrono::milliseconds duration
std::string calling_ae() const
Get the calling AE title.
~dicom_association_handler()
Destructor (stops handler if still running).
void handle_error(std::error_code ec)
Handle session error.
std::shared_ptr< kcenon::network::interfaces::i_session > session_ptr
void set_access_control(std::shared_ptr< security::access_control_manager > acm)
Set the access control manager for RBAC.
void stop(bool graceful=false)
Stop the handler and close the session.
void handle_release_rq()
Handle A-RELEASE-RQ PDU.
void send_pdu(pdu_type type, const std::vector< uint8_t > &payload)
Send raw PDU data.
std::mutex callback_mutex_
uint64_t messages_processed() const noexcept
Get number of DIMSE messages processed.
std::optional< security::user_context > user_context_
User context for this association (set after A-ASSOCIATE negotiation)
void report_error(const std::string &error)
Report error through callback.
void set_error_callback(handler_error_callback callback)
Set callback for error events.
void handle_p_data_tf(const std::vector< uint8_t > &payload)
Handle P-DATA-TF PDU.
static constexpr size_t max_pdu_size
Maximum PDU size for safety checks.
void on_error(std::error_code ec)
Handle session error.
dicom_association_handler & operator=(dicom_association_handler &&)=delete
std::vector< uint8_t > receive_buffer_
PDU receive buffer.
server_config config_
Server configuration.
std::string called_ae() const
Get the called AE title.
handler_error_callback error_callback_
void handle_abort(const std::vector< uint8_t > &payload)
Handle A-ABORT PDU.
void process_pdu(const integration::pdu_data &pdu)
Process a complete PDU.
DICOM session wrapper for network_system sessions.
constexpr const char * to_string(handler_state state) noexcept
Convert handler_state to string representation.
std::function< void(const std::string &session_id, bool graceful)> association_closed_callback
Callback type for association closed events.
handler_state
State machine states for the association handler.
@ awaiting_response
Sent response, awaiting next PDU.
@ closed
Association closed (released or aborted)
@ releasing
Graceful release in progress.
@ established
Association established, processing DIMSE.
@ idle
Initial state, waiting for A-ASSOCIATE-RQ.
std::function< void(const std::string &session_id, const std::string &error)> handler_error_callback
Callback type for error events.
std::function< void(const std::string &session_id, const std::string &calling_ae, const std::string &called_ae)> association_established_callback
Callback type for association established events.
reject_result
Reject result values.
pdu_type
PDU (Protocol Data Unit) types as defined in DICOM PS3.8.
abort_reason
Abort reason values when source is service-provider.
std::variant< associate_rq, associate_ac, associate_rj, p_data_tf_pdu, release_rq_pdu, release_rp_pdu, abort_pdu > pdu
Variant type that can hold any PDU.
abort_source
Abort source values.
Base class for DICOM SCP (Service Class Provider) services.
DICOM Server configuration structures.