PACS System 0.1.0
PACS DICOM system library
Loading...
Searching...
No Matches
mpps_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
19#ifndef PACS_SERVICES_MPPS_SCP_HPP
20#define PACS_SERVICES_MPPS_SCP_HPP
21
22#include "scp_service.h"
23
24#include <atomic>
25#include <functional>
26#include <optional>
27#include <string>
28
29namespace kcenon::pacs::services {
30
31// =============================================================================
32// SOP Class UID
33// =============================================================================
34
36inline constexpr std::string_view mpps_sop_class_uid = "1.2.840.10008.3.1.2.3.3";
37
38// =============================================================================
39// MPPS Types
40// =============================================================================
41
48enum class mpps_status {
50 completed,
52};
53
60[[nodiscard]] inline auto to_string(mpps_status status) -> std::string_view {
61 switch (status) {
63 return "IN PROGRESS";
65 return "COMPLETED";
67 return "DISCONTINUED";
68 default:
69 return "IN PROGRESS";
70 }
71}
72
79[[nodiscard]] inline auto parse_mpps_status(std::string_view str)
80 -> std::optional<mpps_status> {
81 if (str == "IN PROGRESS") {
83 }
84 if (str == "COMPLETED") {
86 }
87 if (str == "DISCONTINUED") {
89 }
90 return std::nullopt;
91}
92
111
112// =============================================================================
113// Handler Types
114// =============================================================================
115
124using mpps_create_handler = std::function<network::Result<std::monostate>(
125 const mpps_instance& instance)>;
126
137using mpps_set_handler = std::function<network::Result<std::monostate>(
138 const std::string& sop_instance_uid,
139 const core::dicom_dataset& modifications,
140 mpps_status new_status)>;
141
142// =============================================================================
143// MPPS SCP Class
144// =============================================================================
145
231class mpps_scp final : public scp_service {
232public:
233 // =========================================================================
234 // Construction
235 // =========================================================================
236
242 explicit mpps_scp(std::shared_ptr<di::ILogger> logger = nullptr);
243
244 ~mpps_scp() override = default;
245
246 // =========================================================================
247 // Configuration
248 // =========================================================================
249
259
268 void set_set_handler(mpps_set_handler handler);
269
270 // =========================================================================
271 // scp_service Interface Implementation
272 // =========================================================================
273
279 [[nodiscard]] std::vector<std::string> supported_sop_classes() const override;
280
293 uint8_t context_id,
294 const network::dimse::dimse_message& request) override;
295
301 [[nodiscard]] std::string_view service_name() const noexcept override;
302
303 // =========================================================================
304 // Statistics
305 // =========================================================================
306
312 [[nodiscard]] size_t creates_processed() const noexcept;
313
319 [[nodiscard]] size_t sets_processed() const noexcept;
320
326 [[nodiscard]] size_t mpps_completed() const noexcept;
327
333 [[nodiscard]] size_t mpps_discontinued() const noexcept;
334
338 void reset_statistics() noexcept;
339
340private:
341 // =========================================================================
342 // Private Implementation
343 // =========================================================================
344
355 [[nodiscard]] network::Result<std::monostate> handle_n_create(
356 network::association& assoc,
357 uint8_t context_id,
358 const network::dimse::dimse_message& request);
359
370 [[nodiscard]] network::Result<std::monostate> handle_n_set(
371 network::association& assoc,
372 uint8_t context_id,
373 const network::dimse::dimse_message& request);
374
385 [[nodiscard]] network::Result<std::monostate> send_n_create_response(
386 network::association& assoc,
387 uint8_t context_id,
388 uint16_t message_id,
389 const std::string& sop_instance_uid,
390 network::dimse::status_code status);
391
402 [[nodiscard]] network::Result<std::monostate> send_n_set_response(
403 network::association& assoc,
404 uint8_t context_id,
405 uint16_t message_id,
406 const std::string& sop_instance_uid,
407 network::dimse::status_code status);
408
409 // =========================================================================
410 // Member Variables
411 // =========================================================================
412
415
416 std::atomic<size_t> creates_processed_{0};
417 std::atomic<size_t> sets_processed_{0};
418 std::atomic<size_t> mpps_completed_{0};
419 std::atomic<size_t> mpps_discontinued_{0};
420};
421
422// =============================================================================
423// MPPS DICOM Tags (Group 0x0040)
424// =============================================================================
425
426namespace mpps_tags {
427
429inline constexpr core::dicom_tag performed_station_ae_title{0x0040, 0x0241};
430
432inline constexpr core::dicom_tag performed_station_name{0x0040, 0x0242};
433
435inline constexpr core::dicom_tag performed_location{0x0040, 0x0243};
436
438inline constexpr core::dicom_tag performed_procedure_step_end_date{0x0040, 0x0250};
439
441inline constexpr core::dicom_tag performed_procedure_step_end_time{0x0040, 0x0251};
442
444inline constexpr core::dicom_tag performed_procedure_step_status{0x0040, 0x0252};
445
447inline constexpr core::dicom_tag performed_procedure_step_id{0x0040, 0x0253};
448
450inline constexpr core::dicom_tag performed_series_sequence{0x0040, 0x0340};
451
454
456inline constexpr core::dicom_tag referenced_study_sequence{0x0008, 0x1110};
457
458} // namespace mpps_tags
459
460} // namespace kcenon::pacs::services
461
462#endif // PACS_SERVICES_MPPS_SCP_HPP
void set_set_handler(mpps_set_handler handler)
Set the N-SET handler function.
Definition mpps_scp.cpp:34
void reset_statistics() noexcept
Reset statistics counters.
Definition mpps_scp.cpp:93
void set_create_handler(mpps_create_handler handler)
Set the N-CREATE handler function.
Definition mpps_scp.cpp:30
mpps_set_handler set_handler_
Definition mpps_scp.h:414
network::Result< std::monostate > handle_n_create(network::association &assoc, uint8_t context_id, const network::dimse::dimse_message &request)
Handle N-CREATE request.
Definition mpps_scp.cpp:104
size_t creates_processed() const noexcept
Get total number of N-CREATE requests processed.
Definition mpps_scp.cpp:77
network::Result< std::monostate > send_n_set_response(network::association &assoc, uint8_t context_id, uint16_t message_id, const std::string &sop_instance_uid, network::dimse::status_code status)
Send N-SET response.
Definition mpps_scp.cpp:314
std::atomic< size_t > creates_processed_
Definition mpps_scp.h:416
std::atomic< size_t > sets_processed_
Definition mpps_scp.h:417
network::Result< std::monostate > send_n_create_response(network::association &assoc, uint8_t context_id, uint16_t message_id, const std::string &sop_instance_uid, network::dimse::status_code status)
Send N-CREATE response.
Definition mpps_scp.cpp:291
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 (N-CREATE-RQ or N-SET-RQ)
Definition mpps_scp.cpp:46
size_t mpps_completed() const noexcept
Get number of MPPS completed successfully.
Definition mpps_scp.cpp:85
size_t mpps_discontinued() const noexcept
Get number of MPPS discontinued.
Definition mpps_scp.cpp:89
std::vector< std::string > supported_sop_classes() const override
Get supported SOP Class UIDs.
Definition mpps_scp.cpp:42
network::Result< std::monostate > handle_n_set(network::association &assoc, uint8_t context_id, const network::dimse::dimse_message &request)
Handle N-SET request.
Definition mpps_scp.cpp:189
mpps_create_handler create_handler_
Definition mpps_scp.h:413
mpps_scp(std::shared_ptr< di::ILogger > logger=nullptr)
Construct MPPS SCP with optional logger.
Definition mpps_scp.cpp:23
size_t sets_processed() const noexcept
Get total number of N-SET requests processed.
Definition mpps_scp.cpp:81
std::atomic< size_t > mpps_completed_
Definition mpps_scp.h:418
std::atomic< size_t > mpps_discontinued_
Definition mpps_scp.h:419
std::string_view service_name() const noexcept override
Get the service name.
Definition mpps_scp.cpp:69
const std::shared_ptr< di::ILogger > & logger() const noexcept
Get the current logger instance.
Definition scp_service.h:93
constexpr core::dicom_tag performed_series_sequence
Performed Series Sequence (0040,0340)
Definition mpps_scp.h:450
constexpr core::dicom_tag performed_procedure_step_end_date
Performed Procedure Step End Date (0040,0250)
Definition mpps_scp.h:438
constexpr core::dicom_tag performed_procedure_step_id
Performed Procedure Step ID (0040,0253)
Definition mpps_scp.h:447
constexpr core::dicom_tag performed_location
Performed Location (0040,0243)
Definition mpps_scp.h:435
constexpr core::dicom_tag performed_station_name
Performed Station Name (0040,0242)
Definition mpps_scp.h:432
constexpr core::dicom_tag performed_station_ae_title
Performed Station AE Title (0040,0241)
Definition mpps_scp.h:429
constexpr core::dicom_tag performed_procedure_step_status
Performed Procedure Step Status (0040,0252)
Definition mpps_scp.h:444
constexpr core::dicom_tag referenced_study_sequence
Referenced Study Sequence (0008,1110)
Definition mpps_scp.h:456
constexpr core::dicom_tag performed_procedure_step_end_time
Performed Procedure Step End Time (0040,0251)
Definition mpps_scp.h:441
constexpr core::dicom_tag scheduled_step_attributes_sequence
Scheduled Step Attributes Sequence (0040,0270)
Definition mpps_scp.h:453
std::function< network::Result< std::monostate >( const std::string &sop_instance_uid, const core::dicom_dataset &modifications, mpps_status new_status)> mpps_set_handler
N-SET handler function type.
Definition mpps_scp.h:137
mpps_status
MPPS status enumeration.
Definition mpps_scp.h:48
@ completed
Procedure completed successfully.
@ discontinued
Procedure was stopped/cancelled.
@ in_progress
Procedure is currently being performed.
std::function< network::Result< std::monostate >( const mpps_instance &instance)> mpps_create_handler
N-CREATE handler function type.
Definition mpps_scp.h:124
auto to_string(mpps_status status) -> std::string_view
Convert mpps_status to DICOM string representation.
Definition mpps_scp.h:60
constexpr std::string_view mpps_sop_class_uid
MPPS (Modality Performed Procedure Step) SOP Class UID.
Definition mpps_scp.h:36
auto parse_mpps_status(std::string_view str) -> std::optional< mpps_status >
Parse DICOM string to mpps_status enum.
Definition mpps_scp.h:79
Base class for DICOM SCP (Service Class Provider) services.
MPPS instance data structure.
Definition mpps_scp.h:98
mpps_status status
Current status (always IN PROGRESS for N-CREATE)
Definition mpps_scp.h:103
std::string sop_instance_uid
SOP Instance UID - unique identifier for this MPPS.
Definition mpps_scp.h:100
std::string station_ae
Performing station AE Title.
Definition mpps_scp.h:106
core::dicom_dataset data
Complete MPPS dataset from the request.
Definition mpps_scp.h:109