PACS System 0.1.0
PACS DICOM system library
Loading...
Searching...
No Matches
dicom_server_v2.h
Go to the documentation of this file.
1// BSD 3-Clause License
2// Copyright (c) 2021-2025, 🍀☀🌕🌥 🌊
3// See the LICENSE file in the project root for full license information.
4
21#ifndef PACS_NETWORK_V2_DICOM_SERVER_V2_HPP
22#define PACS_NETWORK_V2_DICOM_SERVER_V2_HPP
23
28
29#include <atomic>
30#include <chrono>
31#include <condition_variable>
32#include <functional>
33#include <map>
34#include <memory>
35#include <mutex>
36#include <string>
37#include <string_view>
38#include <unordered_map>
39#include <vector>
40
41// Forward declarations for public network_system interfaces
43class i_protocol_server;
44class i_session;
45} // namespace kcenon::network::interfaces
46
48
49// =============================================================================
50// DICOM Server V2 Class
51// =============================================================================
52
117public:
118 // =========================================================================
119 // Type Aliases
120 // =========================================================================
121
122 using clock = std::chrono::steady_clock;
123 using duration = std::chrono::milliseconds;
124 using time_point = clock::time_point;
125
128 std::function<void(const std::string& session_id,
129 const std::string& calling_ae,
130 const std::string& called_ae)>;
131
134 std::function<void(const std::string& session_id, bool graceful)>;
135
137 using error_callback = std::function<void(const std::string& error)>;
138
139 // =========================================================================
140 // Construction / Destruction
141 // =========================================================================
142
147 explicit dicom_server_v2(const server_config& config);
148
153
154 // Non-copyable, non-movable (owns network resources)
159
160 // =========================================================================
161 // Service Registration
162 // =========================================================================
163
174
179 [[nodiscard]] std::vector<std::string> supported_sop_classes() const;
180
181 // =========================================================================
182 // Lifecycle Management
183 // =========================================================================
184
193 [[nodiscard]] Result<std::monostate> start();
194
203 void stop(duration timeout = std::chrono::seconds{30});
204
211 void wait_for_shutdown();
212
213 // =========================================================================
214 // Status Queries
215 // =========================================================================
216
221 [[nodiscard]] bool is_running() const noexcept;
222
227 [[nodiscard]] size_t active_associations() const noexcept;
228
233 [[nodiscard]] server_statistics get_statistics() const;
234
239 [[nodiscard]] const server_config& config() const noexcept;
240
241 // =========================================================================
242 // Callbacks
243 // =========================================================================
244
250
256
261 void on_error(error_callback callback);
262
263 // =========================================================================
264 // Security / Access Control
265 // =========================================================================
266
276 void set_access_control(std::shared_ptr<security::access_control_manager> acm);
277
282 [[nodiscard]] std::shared_ptr<security::access_control_manager>
283 get_access_control() const noexcept;
284
289 void set_access_control_enabled(bool enabled);
290
295 [[nodiscard]] bool is_access_control_enabled() const noexcept;
296
297private:
298 // =========================================================================
299 // Network System Callbacks
300 // =========================================================================
301
303 void on_connection(std::shared_ptr<kcenon::network::interfaces::i_session> session);
304
306 void on_disconnection(std::string_view session_id);
307
309 void on_receive(std::string_view session_id,
310 const std::vector<uint8_t>& data);
311
313 void on_network_error(std::string_view session_id,
314 std::error_code ec);
315
316 // =========================================================================
317 // Handler Management
318 // =========================================================================
319
321 void create_handler(std::shared_ptr<kcenon::network::interfaces::i_session> session);
322
324 void remove_handler(const std::string& session_id);
325
327 [[nodiscard]] std::shared_ptr<dicom_association_handler>
328 find_handler(const std::string& session_id) const;
329
331 void check_idle_timeouts();
332
333 // =========================================================================
334 // Internal Helpers
335 // =========================================================================
336
338 [[nodiscard]] dicom_association_handler::service_map build_service_map() const;
339
341 void report_error(const std::string& error);
342
343 // =========================================================================
344 // Member Variables
345 // =========================================================================
346
349
351 std::shared_ptr<kcenon::network::interfaces::i_protocol_server> server_;
352
354 std::vector<services::scp_service_ptr> services_;
355
357 std::map<std::string, services::scp_service*> sop_class_to_service_;
358
360 std::unordered_map<std::string, std::shared_ptr<dicom_association_handler>> handlers_;
361
364
366 std::atomic<bool> running_{false};
367
369 mutable std::mutex handlers_mutex_;
370
372 mutable std::mutex services_mutex_;
373
375 mutable std::mutex stats_mutex_;
376
378 std::condition_variable shutdown_cv_;
379
381 std::mutex shutdown_mutex_;
382
385
388
391
393 mutable std::mutex callback_mutex_;
394
396 std::shared_ptr<security::access_control_manager> access_control_;
397
399 std::atomic<bool> access_control_enabled_{false};
400
402 mutable std::mutex acl_mutex_;
403};
404
405} // namespace kcenon::pacs::network::v2
406
407#endif // PACS_NETWORK_V2_DICOM_SERVER_V2_HPP
Core RBAC logic.
Bridges network_system sessions with DICOM protocol handling.
DICOM server using network_system's messaging_server for connection management.
void on_network_error(std::string_view session_id, std::error_code ec)
Handle network error.
server_config config_
Server configuration.
std::mutex acl_mutex_
Access control mutex.
void report_error(const std::string &error)
Report error through callback.
dicom_server_v2(const server_config &config)
Construct server with configuration.
std::atomic< bool > running_
Running flag.
server_statistics get_statistics() const
Get server statistics.
std::vector< services::scp_service_ptr > services_
Registered SCP services.
void on_error(error_callback callback)
Set callback for error events.
association_closed_callback on_closed_cb_
Association closed callback.
const server_config & config() const noexcept
Get server configuration.
std::shared_ptr< security::access_control_manager > access_control_
Access control manager for RBAC.
void create_handler(std::shared_ptr< kcenon::network::interfaces::i_session > session)
Create and register a new handler for a session.
std::unordered_map< std::string, std::shared_ptr< dicom_association_handler > > handlers_
Active association handlers (keyed by session ID)
void on_receive(std::string_view session_id, const std::vector< uint8_t > &data)
Handle receive data (forwarded to handler)
dicom_server_v2(dicom_server_v2 &&)=delete
std::shared_ptr< kcenon::network::interfaces::i_protocol_server > server_
network_system's protocol server (via tcp_facade)
bool is_running() const noexcept
Check if server is running.
void register_service(services::scp_service_ptr service)
Register an SCP service.
dicom_server_v2 & operator=(const dicom_server_v2 &)=delete
dicom_association_handler::service_map build_service_map() const
Build service map from registered services.
void on_association_established(association_established_callback callback)
Set callback for association established events.
std::function< void(const std::string &session_id, bool graceful)> association_closed_callback
Callback type for association closed events.
association_established_callback on_established_cb_
Association established callback.
void wait_for_shutdown()
Wait for server shutdown.
std::mutex services_mutex_
Service mutex (protects services_ and sop_class_to_service_)
void check_idle_timeouts()
Check for idle timeouts on handlers.
std::map< std::string, services::scp_service * > sop_class_to_service_
Map from SOP Class UID to service (non-owning pointers)
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.
~dicom_server_v2()
Destructor (stops server if running)
std::function< void(const std::string &error)> error_callback
Callback type for error events.
std::shared_ptr< dicom_association_handler > find_handler(const std::string &session_id) const
Find handler by session ID.
void remove_handler(const std::string &session_id)
Remove handler by session ID.
void on_association_closed(association_closed_callback callback)
Set callback for association closed events.
void set_access_control(std::shared_ptr< security::access_control_manager > acm)
Set the access control manager for RBAC.
dicom_server_v2(const dicom_server_v2 &)=delete
error_callback on_error_cb_
Error callback.
void stop(duration timeout=std::chrono::seconds{30})
Stop the server gracefully.
size_t active_associations() const noexcept
Get number of active associations.
std::mutex handlers_mutex_
Handler mutex (protects handlers_ map)
bool is_access_control_enabled() const noexcept
Check if access control is enabled.
void on_disconnection(std::string_view session_id)
Handle disconnection notification.
Result< std::monostate > start()
Start the server.
void set_access_control_enabled(bool enabled)
Enable or disable access control enforcement.
dicom_server_v2 & operator=(dicom_server_v2 &&)=delete
std::atomic< bool > access_control_enabled_
Whether access control is enabled.
std::vector< std::string > supported_sop_classes() const
Get list of supported SOP Class UIDs.
std::shared_ptr< security::access_control_manager > get_access_control() const noexcept
Get the access control manager.
void on_connection(std::shared_ptr< kcenon::network::interfaces::i_session > session)
Handle new connection from server.
server_statistics stats_
Server statistics.
std::condition_variable shutdown_cv_
Shutdown condition variable.
DICOM association handler for network_system integration.
std::function< void(const std::string &session_id, bool graceful)> association_closed_callback
Callback type for association closed 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.
std::shared_ptr< scp_service > scp_service_ptr
Shared pointer type for SCP services.
Base class for DICOM SCP (Service Class Provider) services.
DICOM Server configuration structures.
Statistics for server monitoring.