PACS System 0.1.0
PACS DICOM system library
Loading...
Searching...
No Matches
storage_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
20#ifndef PACS_SERVICES_STORAGE_SCP_HPP
21#define PACS_SERVICES_STORAGE_SCP_HPP
22
23#include "scp_service.h"
24#include "storage_status.h"
26
27#include <atomic>
28#include <functional>
29#include <memory>
30#include <string>
31#include <vector>
32
33namespace kcenon::pacs::security { class atna_service_auditor; }
34
35namespace kcenon::pacs::services {
36
40enum class duplicate_policy {
41 reject,
42 replace,
43 ignore
44};
45
56
66using storage_handler = std::function<storage_status(
67 const core::dicom_dataset& dataset,
68 const std::string& calling_ae,
69 const std::string& sop_class_uid,
70 const std::string& sop_instance_uid)>;
71
81using pre_store_handler = std::function<bool(const core::dicom_dataset& dataset)>;
82
95using post_store_handler = std::function<void(
96 const core::dicom_dataset& dataset,
97 const std::string& patient_id,
98 const std::string& study_uid,
99 const std::string& series_uid,
100 const std::string& sop_instance_uid)>;
101
161class storage_scp final : public scp_service {
162public:
163 // =========================================================================
164 // Construction
165 // =========================================================================
166
172 explicit storage_scp(std::shared_ptr<di::ILogger> logger = nullptr);
173
180 explicit storage_scp(const storage_scp_config& config,
181 std::shared_ptr<di::ILogger> logger = nullptr);
182
183 ~storage_scp() override = default;
184
185 // =========================================================================
186 // Handler Registration
187 // =========================================================================
188
197 void set_handler(storage_handler handler);
198
208
237
247 std::shared_ptr<kcenon::pacs::security::atna_service_auditor> auditor);
248
249 // =========================================================================
250 // scp_service Interface Implementation
251 // =========================================================================
252
261 [[nodiscard]] std::vector<std::string> supported_sop_classes() const override;
262
280 uint8_t context_id,
281 const network::dimse::dimse_message& request) override;
282
287 [[nodiscard]] std::string_view service_name() const noexcept override;
288
289 // =========================================================================
290 // Statistics
291 // =========================================================================
292
297 [[nodiscard]] size_t images_received() const noexcept;
298
303 [[nodiscard]] size_t bytes_received() const noexcept;
304
308 void reset_statistics() noexcept;
309
310private:
311 // =========================================================================
312 // Private Members
313 // =========================================================================
314
317
320
323
326
328 std::shared_ptr<kcenon::pacs::security::atna_service_auditor> auditor_;
329
331 std::atomic<size_t> images_received_{0};
332
334 std::atomic<size_t> bytes_received_{0};
335};
336
337// =============================================================================
338// Standard Storage SOP Class UIDs
339// =============================================================================
340
343
345inline constexpr std::string_view ct_image_storage_uid =
346 "1.2.840.10008.5.1.4.1.1.2";
347
349inline constexpr std::string_view enhanced_ct_image_storage_uid =
350 "1.2.840.10008.5.1.4.1.1.2.1";
351
353inline constexpr std::string_view mr_image_storage_uid =
354 "1.2.840.10008.5.1.4.1.1.4";
355
357inline constexpr std::string_view enhanced_mr_image_storage_uid =
358 "1.2.840.10008.5.1.4.1.1.4.1";
359
361inline constexpr std::string_view cr_image_storage_uid =
362 "1.2.840.10008.5.1.4.1.1.1";
363
365inline constexpr std::string_view dx_image_storage_presentation_uid =
366 "1.2.840.10008.5.1.4.1.1.1.1";
367
369inline constexpr std::string_view dx_image_storage_processing_uid =
370 "1.2.840.10008.5.1.4.1.1.1.1.1";
371
373inline constexpr std::string_view us_image_storage_uid =
374 "1.2.840.10008.5.1.4.1.1.6.1";
375
377inline constexpr std::string_view secondary_capture_image_storage_uid =
378 "1.2.840.10008.5.1.4.1.1.7";
379
381inline constexpr std::string_view rt_image_storage_uid =
382 "1.2.840.10008.5.1.4.1.1.481.1";
383
385inline constexpr std::string_view rt_dose_storage_uid =
386 "1.2.840.10008.5.1.4.1.1.481.2";
387
389inline constexpr std::string_view rt_structure_set_storage_uid =
390 "1.2.840.10008.5.1.4.1.1.481.3";
391
393inline constexpr std::string_view rt_plan_storage_uid =
394 "1.2.840.10008.5.1.4.1.1.481.5";
395
397
406[[nodiscard]] std::vector<std::string> get_standard_storage_sop_classes();
407
408} // namespace kcenon::pacs::services
409
410#endif // PACS_SERVICES_STORAGE_SCP_HPP
const std::shared_ptr< di::ILogger > & logger() const noexcept
Get the current logger instance.
Definition scp_service.h:93
void set_audit_handler(std::shared_ptr< kcenon::pacs::security::atna_service_auditor > auditor)
Set the ATNA audit handler for C-STORE operations.
storage_scp(std::shared_ptr< di::ILogger > logger=nullptr)
Construct a Storage SCP with default configuration.
size_t bytes_received() const noexcept
Get the total bytes received since construction.
void reset_statistics() noexcept
Reset statistics counters to zero.
void set_handler(storage_handler handler)
Set the storage handler callback.
size_t images_received() const noexcept
Get the number of images received since construction.
std::vector< std::string > supported_sop_classes() const override
Get supported SOP Class UIDs.
std::shared_ptr< kcenon::pacs::security::atna_service_auditor > auditor_
ATNA audit handler.
storage_handler handler_
Main storage handler.
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-STORE-RQ)
storage_scp_config config_
Configuration.
std::atomic< size_t > images_received_
Statistics: number of images received.
void set_post_store_handler(post_store_handler handler)
std::string_view service_name() const noexcept override
Get the service name.
void set_pre_store_handler(pre_store_handler handler)
Set the pre-store validation handler.
pre_store_handler pre_store_handler_
Pre-store validation handler.
post_store_handler post_store_handler_
Post-store notification handler.
std::atomic< size_t > bytes_received_
Statistics: total bytes received.
DICOM Dataset - ordered collection of Data Elements.
std::vector< std::string > get_standard_storage_sop_classes()
Get a list of all standard Storage SOP Class UIDs.
constexpr std::string_view mr_image_storage_uid
MR Image Storage.
constexpr std::string_view cr_image_storage_uid
CR Image Storage.
constexpr std::string_view us_image_storage_uid
US Image Storage.
std::function< bool(const core::dicom_dataset &dataset)> pre_store_handler
Callback type for pre-store validation.
Definition storage_scp.h:81
storage_status
Storage operation status codes.
duplicate_policy
Policy for handling duplicate SOP instances.
Definition storage_scp.h:40
@ ignore
Silently accept duplicate (return success)
@ reject
Reject duplicates with error status.
@ replace
Replace existing instance with new one.
std::function< storage_status( const core::dicom_dataset &dataset, const std::string &calling_ae, const std::string &sop_class_uid, const std::string &sop_instance_uid)> storage_handler
Callback type for handling received DICOM images.
Definition storage_scp.h:66
constexpr std::string_view secondary_capture_image_storage_uid
Secondary Capture Image Storage.
constexpr std::string_view rt_image_storage_uid
RT Image Storage.
std::function< void( const core::dicom_dataset &dataset, const std::string &patient_id, const std::string &study_uid, const std::string &series_uid, const std::string &sop_instance_uid)> post_store_handler
Callback type for post-store notification.
Definition storage_scp.h:95
constexpr std::string_view dx_image_storage_presentation_uid
Digital X-Ray Image Storage - For Presentation.
constexpr std::string_view ct_image_storage_uid
CT Image Storage.
constexpr std::string_view rt_plan_storage_uid
RT Plan Storage.
constexpr std::string_view rt_dose_storage_uid
RT Dose Storage.
constexpr std::string_view enhanced_ct_image_storage_uid
Enhanced CT Image Storage.
constexpr std::string_view rt_structure_set_storage_uid
RT Structure Set Storage.
constexpr std::string_view enhanced_mr_image_storage_uid
Enhanced MR Image Storage.
constexpr std::string_view dx_image_storage_processing_uid
Digital X-Ray Image Storage - For Processing.
Base class for DICOM SCP (Service Class Provider) services.
Storage SCP status codes for C-STORE operations.
Configuration for Storage SCP service.
Definition storage_scp.h:49
duplicate_policy dup_policy
Policy for handling duplicate SOP instances.
Definition storage_scp.h:54
std::vector< std::string > accepted_sop_classes
List of accepted SOP Class UIDs (empty = accept all standard storage classes)
Definition storage_scp.h:51