PACS System 0.1.0
PACS DICOM system library
Loading...
Searching...
No Matches
retrieve_scp.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
22#ifndef PACS_SERVICES_RETRIEVE_SCP_HPP
23#define PACS_SERVICES_RETRIEVE_SCP_HPP
24
25#include "scp_service.h"
28
29#include <atomic>
30#include <functional>
31#include <optional>
32#include <string>
33#include <utility>
34#include <vector>
35
36namespace kcenon::pacs::services {
37
38// =============================================================================
39// SOP Class UIDs
40// =============================================================================
41
43inline constexpr std::string_view patient_root_move_sop_class_uid =
44 "1.2.840.10008.5.1.4.1.2.1.2";
45
47inline constexpr std::string_view study_root_move_sop_class_uid =
48 "1.2.840.10008.5.1.4.1.2.2.2";
49
51inline constexpr std::string_view patient_root_get_sop_class_uid =
52 "1.2.840.10008.5.1.4.1.2.1.3";
53
55inline constexpr std::string_view study_root_get_sop_class_uid =
56 "1.2.840.10008.5.1.4.1.2.2.3";
57
58// =============================================================================
59// Sub-operation Statistics
60// =============================================================================
61
68 uint16_t remaining{0};
69 uint16_t completed{0};
70 uint16_t failed{0};
71 uint16_t warning{0};
72
77 [[nodiscard]] uint16_t total() const noexcept {
78 return remaining + completed + failed + warning;
79 }
80
85 [[nodiscard]] bool all_successful() const noexcept {
86 return failed == 0;
87 }
88};
89
90// =============================================================================
91// Handler Types
92// =============================================================================
93
102using retrieve_handler = std::function<std::vector<core::dicom_file>(
103 const core::dicom_dataset& query_keys)>;
104
114using destination_resolver = std::function<
115 std::optional<std::pair<std::string, uint16_t>>(
116 const std::string& ae_title)>;
117
134 uint8_t context_id,
135 const core::dicom_file& file,
136 const std::string& move_originator_ae,
137 uint16_t move_originator_msg_id)>;
138
147using retrieve_cancel_check = std::function<bool()>;
148
149// =============================================================================
150// Retrieve SCP Class
151// =============================================================================
152
230class retrieve_scp final : public scp_service {
231public:
232 // =========================================================================
233 // Construction
234 // =========================================================================
235
241 explicit retrieve_scp(std::shared_ptr<di::ILogger> logger = nullptr);
242
243 ~retrieve_scp() override = default;
244
245 // =========================================================================
246 // Configuration
247 // =========================================================================
248
258
267
278
288
289 // =========================================================================
290 // scp_service Interface Implementation
291 // =========================================================================
292
298 [[nodiscard]] std::vector<std::string> supported_sop_classes() const override;
299
319 uint8_t context_id,
320 const network::dimse::dimse_message& request) override;
321
326 [[nodiscard]] std::string_view service_name() const noexcept override;
327
328 // =========================================================================
329 // Statistics
330 // =========================================================================
331
336 [[nodiscard]] size_t move_operations() const noexcept;
337
342 [[nodiscard]] size_t get_operations() const noexcept;
343
348 [[nodiscard]] size_t images_transferred() const noexcept;
349
353 void reset_statistics() noexcept;
354
355private:
356 // =========================================================================
357 // Private Implementation
358 // =========================================================================
359
368 [[nodiscard]] network::Result<std::monostate> handle_c_move(
369 network::association& assoc,
370 uint8_t context_id,
371 const network::dimse::dimse_message& request);
372
381 [[nodiscard]] network::Result<std::monostate> handle_c_get(
382 network::association& assoc,
383 uint8_t context_id,
384 const network::dimse::dimse_message& request);
385
397 [[nodiscard]] network::Result<std::monostate> send_pending_response(
398 network::association& assoc,
399 uint8_t context_id,
400 uint16_t message_id,
401 std::string_view sop_class_uid,
402 bool is_move,
403 const sub_operation_stats& stats);
404
417 [[nodiscard]] network::Result<std::monostate> send_final_response(
418 network::association& assoc,
419 uint8_t context_id,
420 uint16_t message_id,
421 std::string_view sop_class_uid,
422 bool is_move,
423 const sub_operation_stats& stats,
424 bool was_cancelled);
425
432 [[nodiscard]] std::string get_move_destination(
433 const network::dimse::dimse_message& request) const;
434
435 // =========================================================================
436 // Member Variables
437 // =========================================================================
438
443
444 std::atomic<size_t> move_operations_{0};
445 std::atomic<size_t> get_operations_{0};
446 std::atomic<size_t> images_transferred_{0};
447};
448
449} // namespace kcenon::pacs::services
450
451#endif // PACS_SERVICES_RETRIEVE_SCP_HPP
std::string_view service_name() const noexcept override
Get the service name.
network::Result< std::monostate > handle_message(network::association &assoc, uint8_t context_id, const network::dimse::dimse_message &request) override
Handle an incoming DIMSE message (C-MOVE-RQ or C-GET-RQ)
std::string get_move_destination(const network::dimse::dimse_message &request) const
Get the Move Destination AE title from the request.
void set_destination_resolver(destination_resolver resolver)
Set the destination resolver function.
network::Result< std::monostate > send_pending_response(network::association &assoc, uint8_t context_id, uint16_t message_id, std::string_view sop_class_uid, bool is_move, const sub_operation_stats &stats)
Send a pending response with progress information.
std::atomic< size_t > get_operations_
size_t get_operations() const noexcept
Get total number of C-GET operations processed.
void reset_statistics() noexcept
Reset statistics counters.
size_t images_transferred() const noexcept
Get total number of images transferred.
void set_cancel_check(retrieve_cancel_check check)
Set the cancel check function.
retrieve_cancel_check cancel_check_
std::atomic< size_t > images_transferred_
std::vector< std::string > supported_sop_classes() const override
Get supported SOP Class UIDs.
network::Result< std::monostate > handle_c_get(network::association &assoc, uint8_t context_id, const network::dimse::dimse_message &request)
Handle a C-GET request.
network::Result< std::monostate > send_final_response(network::association &assoc, uint8_t context_id, uint16_t message_id, std::string_view sop_class_uid, bool is_move, const sub_operation_stats &stats, bool was_cancelled)
Send a final response with completion status.
network::Result< std::monostate > handle_c_move(network::association &assoc, uint8_t context_id, const network::dimse::dimse_message &request)
Handle a C-MOVE request.
destination_resolver destination_resolver_
void set_retrieve_handler(retrieve_handler handler)
Set the retrieve handler function.
std::atomic< size_t > move_operations_
size_t move_operations() const noexcept
Get total number of C-MOVE operations processed.
void set_store_sub_operation(store_sub_operation handler)
Set the store sub-operation handler.
retrieve_scp(std::shared_ptr< di::ILogger > logger=nullptr)
Construct a Retrieve SCP with optional logger.
const std::shared_ptr< di::ILogger > & logger() const noexcept
Get the current logger instance.
Definition scp_service.h:93
DICOM Dataset - ordered collection of Data Elements.
DICOM Part 10 file handling for reading/writing DICOM files.
uint16_t status_code
DIMSE status code type alias.
std::function< std::optional< std::pair< std::string, uint16_t > >( const std::string &ae_title)> destination_resolver
Destination resolver function type.
std::function< network::dimse::status_code( network::association &assoc, uint8_t context_id, const core::dicom_file &file, const std::string &move_originator_ae, uint16_t move_originator_msg_id)> store_sub_operation
Store sub-operation function type.
std::function< std::vector< core::dicom_file >( const core::dicom_dataset &query_keys)> retrieve_handler
Retrieve handler function type.
std::function< bool()> retrieve_cancel_check
Cancel check function type.
constexpr std::string_view study_root_move_sop_class_uid
Study Root Query/Retrieve Information Model - MOVE.
constexpr std::string_view study_root_get_sop_class_uid
Study Root Query/Retrieve Information Model - GET.
constexpr std::string_view patient_root_move_sop_class_uid
Patient Root Query/Retrieve Information Model - MOVE.
constexpr std::string_view patient_root_get_sop_class_uid
Patient Root Query/Retrieve Information Model - GET.
Base class for DICOM SCP (Service Class Provider) services.
Statistics for C-MOVE/C-GET sub-operations.
uint16_t total() const noexcept
Get total number of sub-operations.
uint16_t failed
Number of failed sub-operations.
bool all_successful() const noexcept
Check if all operations completed successfully.
uint16_t warning
Number of sub-operations with warnings.
uint16_t remaining
Number of remaining sub-operations.
uint16_t completed
Number of completed sub-operations.