PACS System 0.1.0
PACS DICOM system library
Loading...
Searching...
No Matches
print_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
18#ifndef PACS_SERVICES_PRINT_SCP_HPP
19#define PACS_SERVICES_PRINT_SCP_HPP
20
21#include "scp_service.h"
22
24
25#include <atomic>
26#include <cstdint>
27#include <functional>
28#include <mutex>
29#include <string>
30#include <unordered_map>
31#include <vector>
32
33namespace kcenon::pacs::services {
34
35// =============================================================================
36// Print Management SOP Class UIDs (PS3.4 Annex H)
37// =============================================================================
38
40inline constexpr std::string_view basic_film_session_sop_class_uid =
41 "1.2.840.10008.5.1.1.1";
42
44inline constexpr std::string_view basic_film_box_sop_class_uid =
45 "1.2.840.10008.5.1.1.2";
46
48inline constexpr std::string_view basic_grayscale_image_box_sop_class_uid =
49 "1.2.840.10008.5.1.1.4";
50
52inline constexpr std::string_view basic_color_image_box_sop_class_uid =
53 "1.2.840.10008.5.1.1.4.1";
54
56inline constexpr std::string_view printer_sop_class_uid =
57 "1.2.840.10008.5.1.1.16";
58
60inline constexpr std::string_view basic_grayscale_print_meta_sop_class_uid =
61 "1.2.840.10008.5.1.1.9";
62
64inline constexpr std::string_view basic_color_print_meta_sop_class_uid =
65 "1.2.840.10008.5.1.1.18";
66
67// =============================================================================
68// Print Management Types
69// =============================================================================
70
74enum class printer_status {
75 normal,
76 warning,
77 failure
78};
79
83[[nodiscard]] inline auto to_string(printer_status status) -> std::string_view {
84 switch (status) {
86 return "NORMAL";
88 return "WARNING";
90 return "FAILURE";
91 default:
92 return "NORMAL";
93 }
94}
95
99enum class print_job_status {
100 pending,
101 printing,
102 done,
103 failure
104};
105
111 std::string sop_instance_uid;
112
114 uint32_t number_of_copies{1};
115
117 std::string print_priority{"MED"};
118
120 std::string medium_type{"BLUE FILM"};
121
123 std::string film_destination{"MAGAZINE"};
124
126 std::vector<std::string> film_box_uids;
127
130};
131
135struct film_box {
137 std::string sop_instance_uid;
138
140 std::string film_session_uid;
141
143 std::string image_display_format{"STANDARD\\1,1"};
144
146 std::string film_orientation{"PORTRAIT"};
147
149 std::string film_size_id{"8INX10IN"};
150
152 std::vector<std::string> image_box_uids;
153
156};
157
161struct image_box {
163 std::string sop_instance_uid;
164
166 std::string film_box_uid;
167
169 uint16_t image_position{1};
170
172 bool has_pixel_data{false};
173
176};
177
178// =============================================================================
179// Handler Types
180// =============================================================================
181
188using print_session_handler = std::function<network::Result<std::monostate>(
189 const film_session& session)>;
190
197using print_action_handler = std::function<network::Result<std::monostate>(
198 const std::string& film_box_uid)>;
199
205using printer_status_handler = std::function<
207
208// =============================================================================
209// Print SCP Class
210// =============================================================================
211
239class print_scp final : public scp_service {
240public:
241 // =========================================================================
242 // Construction
243 // =========================================================================
244
250 explicit print_scp(std::shared_ptr<di::ILogger> logger = nullptr);
251
252 ~print_scp() override = default;
253
254 // =========================================================================
255 // Configuration
256 // =========================================================================
257
262
267
272
273 // =========================================================================
274 // scp_service Interface Implementation
275 // =========================================================================
276
282 [[nodiscard]] std::vector<std::string> supported_sop_classes() const override;
283
292 uint8_t context_id,
293 const network::dimse::dimse_message& request) override;
294
300 [[nodiscard]] std::string_view service_name() const noexcept override;
301
302 // =========================================================================
303 // Statistics
304 // =========================================================================
305
306 [[nodiscard]] size_t sessions_created() const noexcept;
307 [[nodiscard]] size_t film_boxes_created() const noexcept;
308 [[nodiscard]] size_t images_set() const noexcept;
309 [[nodiscard]] size_t prints_executed() const noexcept;
310 [[nodiscard]] size_t printer_queries() const noexcept;
311 void reset_statistics() noexcept;
312
313private:
314 // =========================================================================
315 // DIMSE-N Command Handlers
316 // =========================================================================
317
318 [[nodiscard]] network::Result<std::monostate> handle_n_create(
319 network::association& assoc,
320 uint8_t context_id,
321 const network::dimse::dimse_message& request);
322
323 [[nodiscard]] network::Result<std::monostate> handle_n_set(
324 network::association& assoc,
325 uint8_t context_id,
326 const network::dimse::dimse_message& request);
327
328 [[nodiscard]] network::Result<std::monostate> handle_n_get(
329 network::association& assoc,
330 uint8_t context_id,
331 const network::dimse::dimse_message& request);
332
333 [[nodiscard]] network::Result<std::monostate> handle_n_action(
334 network::association& assoc,
335 uint8_t context_id,
336 const network::dimse::dimse_message& request);
337
338 [[nodiscard]] network::Result<std::monostate> handle_n_delete(
339 network::association& assoc,
340 uint8_t context_id,
341 const network::dimse::dimse_message& request);
342
343 // =========================================================================
344 // SOP-specific Create Handlers
345 // =========================================================================
346
347 [[nodiscard]] network::Result<std::monostate> create_film_session(
348 network::association& assoc,
349 uint8_t context_id,
350 const network::dimse::dimse_message& request);
351
352 [[nodiscard]] network::Result<std::monostate> create_film_box(
353 network::association& assoc,
354 uint8_t context_id,
355 const network::dimse::dimse_message& request);
356
357 // =========================================================================
358 // Response Helpers
359 // =========================================================================
360
361 [[nodiscard]] network::Result<std::monostate> send_response(
362 network::association& assoc,
363 uint8_t context_id,
364 network::dimse::command_field response_type,
365 uint16_t message_id,
366 std::string_view sop_class_uid,
367 const std::string& sop_instance_uid,
368 network::dimse::status_code status);
369
370 // =========================================================================
371 // UID Generation
372 // =========================================================================
373
374 [[nodiscard]] auto generate_uid() -> std::string;
375
376 // =========================================================================
377 // Member Variables
378 // =========================================================================
379
383
385 std::unordered_map<std::string, film_session> sessions_;
386
388 std::unordered_map<std::string, film_box> film_boxes_;
389
391 std::unordered_map<std::string, image_box> image_boxes_;
392
394 mutable std::mutex mutex_;
395
397 std::atomic<uint32_t> uid_counter_{0};
398
400 std::atomic<size_t> sessions_created_{0};
401 std::atomic<size_t> film_boxes_created_{0};
402 std::atomic<size_t> images_set_{0};
403 std::atomic<size_t> prints_executed_{0};
404 std::atomic<size_t> printer_queries_{0};
405};
406
407// =============================================================================
408// Print-specific DICOM Tags (PS3.4 Annex H)
409// =============================================================================
410
411namespace print_tags {
412
414inline constexpr core::dicom_tag number_of_copies{0x2000, 0x0010};
415
417inline constexpr core::dicom_tag print_priority{0x2000, 0x0020};
418
420inline constexpr core::dicom_tag medium_type{0x2000, 0x0030};
421
423inline constexpr core::dicom_tag film_destination{0x2000, 0x0040};
424
426inline constexpr core::dicom_tag film_session_label{0x2000, 0x0050};
427
429inline constexpr core::dicom_tag image_display_format{0x2010, 0x0010};
430
432inline constexpr core::dicom_tag film_orientation{0x2010, 0x0040};
433
435inline constexpr core::dicom_tag film_size_id{0x2010, 0x0050};
436
438inline constexpr core::dicom_tag magnification_type{0x2010, 0x0060};
439
441inline constexpr core::dicom_tag referenced_film_session_sequence{0x2010, 0x0500};
442
444inline constexpr core::dicom_tag referenced_image_box_sequence{0x2010, 0x0510};
445
447inline constexpr core::dicom_tag image_position{0x2020, 0x0010};
448
450inline constexpr core::dicom_tag basic_grayscale_image_sequence{0x2020, 0x0110};
451
453inline constexpr core::dicom_tag basic_color_image_sequence{0x2020, 0x0111};
454
456inline constexpr core::dicom_tag printer_status_tag{0x2110, 0x0010};
457
459inline constexpr core::dicom_tag printer_status_info{0x2110, 0x0020};
460
462inline constexpr core::dicom_tag printer_name{0x2110, 0x0030};
463
464} // namespace print_tags
465
466} // namespace kcenon::pacs::services
467
468#endif // PACS_SERVICES_PRINT_SCP_HPP
Print Management SCP service.
Definition print_scp.h:239
std::atomic< size_t > images_set_
Definition print_scp.h:402
size_t printer_queries() const noexcept
print_session_handler session_handler_
Definition print_scp.h:380
std::vector< std::string > supported_sop_classes() const override
Get supported SOP Class UIDs.
Definition print_scp.cpp:50
size_t sessions_created() const noexcept
Definition print_scp.cpp:96
size_t film_boxes_created() const noexcept
network::Result< std::monostate > handle_n_set(network::association &assoc, uint8_t context_id, const network::dimse::dimse_message &request)
std::atomic< size_t > sessions_created_
Statistics.
Definition print_scp.h:400
print_action_handler print_handler_
Definition print_scp.h:381
network::Result< std::monostate > create_film_box(network::association &assoc, uint8_t context_id, const network::dimse::dimse_message &request)
network::Result< std::monostate > handle_n_delete(network::association &assoc, uint8_t context_id, const network::dimse::dimse_message &request)
network::Result< std::monostate > handle_n_action(network::association &assoc, uint8_t context_id, const network::dimse::dimse_message &request)
std::unordered_map< std::string, film_box > film_boxes_
Active film boxes indexed by SOP Instance UID.
Definition print_scp.h:388
std::unordered_map< std::string, film_session > sessions_
Active film sessions indexed by SOP Instance UID.
Definition print_scp.h:385
std::atomic< size_t > prints_executed_
Definition print_scp.h:403
size_t prints_executed() const noexcept
size_t images_set() const noexcept
std::string_view service_name() const noexcept override
Get the service name.
Definition print_scp.cpp:88
void set_session_handler(print_session_handler handler)
Set handler for film session creation.
Definition print_scp.cpp:34
network::Result< std::monostate > handle_n_create(network::association &assoc, uint8_t context_id, const network::dimse::dimse_message &request)
printer_status_handler printer_status_handler_
Definition print_scp.h:382
void set_print_handler(print_action_handler handler)
Set handler for print action (film box print)
Definition print_scp.cpp:38
std::atomic< size_t > printer_queries_
Definition print_scp.h:404
network::Result< std::monostate > send_response(network::association &assoc, uint8_t context_id, network::dimse::command_field response_type, uint16_t message_id, std::string_view sop_class_uid, const std::string &sop_instance_uid, network::dimse::status_code status)
auto generate_uid() -> std::string
network::Result< std::monostate > handle_n_get(network::association &assoc, uint8_t context_id, const network::dimse::dimse_message &request)
std::atomic< size_t > film_boxes_created_
Definition print_scp.h:401
network::Result< std::monostate > create_film_session(network::association &assoc, uint8_t context_id, const network::dimse::dimse_message &request)
network::Result< std::monostate > handle_message(network::association &assoc, uint8_t context_id, const network::dimse::dimse_message &request) override
Handle an incoming DIMSE-N message.
Definition print_scp.cpp:62
std::unordered_map< std::string, image_box > image_boxes_
Active image boxes indexed by SOP Instance UID.
Definition print_scp.h:391
std::mutex mutex_
Mutex for state management.
Definition print_scp.h:394
print_scp(std::shared_ptr< di::ILogger > logger=nullptr)
Construct Print SCP with optional logger.
Definition print_scp.cpp:27
std::atomic< uint32_t > uid_counter_
UID generation counter.
Definition print_scp.h:397
void set_printer_status_handler(printer_status_handler handler)
Set handler for printer status query.
Definition print_scp.cpp:42
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.
std::shared_mutex mutex
Mutex for thread-safe access.
constexpr core::dicom_tag printer_status_tag
Printer Status (2110,0010)
Definition print_scp.h:456
constexpr core::dicom_tag referenced_film_session_sequence
Referenced Film Session Sequence (2010,0500)
Definition print_scp.h:441
constexpr core::dicom_tag image_display_format
Image Display Format (2010,0010)
Definition print_scp.h:429
constexpr core::dicom_tag basic_grayscale_image_sequence
Basic Grayscale Image Sequence (2020,0110)
Definition print_scp.h:450
constexpr core::dicom_tag image_position
Image Position (2020,0010)
Definition print_scp.h:447
constexpr core::dicom_tag film_destination
Film Destination (2000,0040)
Definition print_scp.h:423
constexpr core::dicom_tag print_priority
Print Priority (2000,0020)
Definition print_scp.h:417
constexpr core::dicom_tag film_orientation
Film Orientation (2010,0040)
Definition print_scp.h:432
constexpr core::dicom_tag film_size_id
Film Size ID (2010,0050)
Definition print_scp.h:435
constexpr core::dicom_tag magnification_type
Magnification Type (2010,0060)
Definition print_scp.h:438
constexpr core::dicom_tag basic_color_image_sequence
Basic Color Image Sequence (2020,0111)
Definition print_scp.h:453
constexpr core::dicom_tag medium_type
Medium Type (2000,0030)
Definition print_scp.h:420
constexpr core::dicom_tag referenced_image_box_sequence
Referenced Image Box Sequence (2010,0510)
Definition print_scp.h:444
constexpr core::dicom_tag number_of_copies
Number of Copies (2000,0010)
Definition print_scp.h:414
constexpr core::dicom_tag film_session_label
Film Session Label (2000,0050)
Definition print_scp.h:426
constexpr core::dicom_tag printer_name
Printer Name (2110,0030)
Definition print_scp.h:462
constexpr core::dicom_tag printer_status_info
Printer Status Info (2110,0020)
Definition print_scp.h:459
constexpr std::string_view basic_grayscale_print_meta_sop_class_uid
Basic Grayscale Print Management Meta SOP Class UID.
Definition print_scp.h:60
printer_status
Printer status enumeration (PS3.4 H.4.17)
Definition print_scp.h:74
@ failure
Printer has a critical error.
@ warning
Printer has a non-critical issue.
@ normal
Printer is operating normally.
constexpr std::string_view basic_color_print_meta_sop_class_uid
Basic Color Print Management Meta SOP Class UID.
Definition print_scp.h:64
constexpr std::string_view basic_film_session_sop_class_uid
Basic Film Session SOP Class UID.
Definition print_scp.h:40
std::function< network::Result< std::monostate >( const film_session &session)> print_session_handler
Handler for film session creation.
Definition print_scp.h:188
constexpr std::string_view basic_color_image_box_sop_class_uid
Basic Color Image Box SOP Class UID.
Definition print_scp.h:52
print_job_status
Print job status.
Definition print_scp.h:99
@ done
Job completed successfully.
std::function< network::Result< std::monostate >( const std::string &film_box_uid)> print_action_handler
Handler for print action (film box print)
Definition print_scp.h:197
std::function< network::Result< std::pair< printer_status, core::dicom_dataset > >()> printer_status_handler
Handler for printer status query.
Definition print_scp.h:205
constexpr std::string_view basic_film_box_sop_class_uid
Basic Film Box SOP Class UID.
Definition print_scp.h:44
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 basic_grayscale_image_box_sop_class_uid
Basic Grayscale Image Box SOP Class UID.
Definition print_scp.h:48
constexpr std::string_view printer_sop_class_uid
Printer SOP Class UID.
Definition print_scp.h:56
Base class for DICOM SCP (Service Class Provider) services.
Film box data created by N-CREATE.
Definition print_scp.h:135
std::string film_orientation
Film orientation (PORTRAIT, LANDSCAPE)
Definition print_scp.h:146
std::vector< std::string > image_box_uids
Associated image box UIDs.
Definition print_scp.h:152
std::string sop_instance_uid
SOP Instance UID.
Definition print_scp.h:137
std::string film_size_id
Film size ID (8INX10IN, 14INX17IN, etc.)
Definition print_scp.h:149
std::string film_session_uid
Parent film session UID.
Definition print_scp.h:140
std::string image_display_format
Image display format (STANDARD\1,1 etc.)
Definition print_scp.h:143
core::dicom_dataset data
Complete dataset from request.
Definition print_scp.h:155
Film session data created by N-CREATE.
Definition print_scp.h:109
std::string sop_instance_uid
SOP Instance UID.
Definition print_scp.h:111
uint32_t number_of_copies
Number of copies.
Definition print_scp.h:114
std::string print_priority
Print priority (HIGH, MED, LOW)
Definition print_scp.h:117
std::vector< std::string > film_box_uids
Associated film box UIDs.
Definition print_scp.h:126
core::dicom_dataset data
Complete dataset from request.
Definition print_scp.h:129
std::string film_destination
Film destination (MAGAZINE, PROCESSOR)
Definition print_scp.h:123
std::string medium_type
Medium type (PAPER, CLEAR FILM, BLUE FILM)
Definition print_scp.h:120
Image box data set by N-SET.
Definition print_scp.h:161
std::string film_box_uid
Parent film box UID.
Definition print_scp.h:166
core::dicom_dataset data
Complete dataset from request.
Definition print_scp.h:175
std::string sop_instance_uid
SOP Instance UID.
Definition print_scp.h:163
uint16_t image_position
Image position (1-based)
Definition print_scp.h:169
bool has_pixel_data
Whether pixel data has been set.
Definition print_scp.h:172