51 using namespace network::dimse;
55 case command_field::n_create_rq:
58 case command_field::n_set_rq:
64 "Unexpected command for MPPS SCP: " +
109 using namespace network::dimse;
115 "No N-CREATE handler configured for MPPS SCP");
123 "", status_refused_sop_class_not_supported);
128 if (sop_instance_uid.empty()) {
131 "", status_error_missing_attribute);
138 sop_instance_uid, status_error_cannot_understand);
141 const auto& dataset = request.
dataset().value().get();
147 instance.
data = dataset;
159 if (!parsed_status.has_value() ||
164 sop_instance_uid, status_error_cannot_understand);
170 if (result.is_err()) {
173 sop_instance_uid, status_error_unable_to_process);
182 sop_instance_uid, status_success);
194 using namespace network::dimse;
200 "No N-SET handler configured for MPPS SCP");
205 if (sop_class_uid.empty()) {
208 tag_requested_sop_class_uid);
214 "", status_refused_sop_class_not_supported);
218 auto sop_instance_uid = request.
command_set().get_string(
219 tag_requested_sop_instance_uid);
221 if (sop_instance_uid.empty()) {
226 if (sop_instance_uid.empty()) {
229 "", status_error_missing_attribute);
236 sop_instance_uid, status_error_cannot_understand);
239 const auto& dataset = request.
dataset().value().get();
245 sop_instance_uid, status_error_missing_attribute);
251 if (!new_status.has_value()) {
254 sop_instance_uid, status_error_cannot_understand);
262 sop_instance_uid, status_error_cannot_understand);
266 auto result =
set_handler_(sop_instance_uid, dataset, new_status.value());
267 if (result.is_err()) {
270 sop_instance_uid, status_error_unable_to_process);
284 sop_instance_uid, status_success);
295 const std::string& sop_instance_uid,
298 using namespace network::dimse;
301 dimse_message response{command_field::n_create_rsp, 0};
302 response.set_message_id_responded_to(message_id);
304 response.set_status(status);
306 if (!sop_instance_uid.empty()) {
307 response.set_affected_sop_instance_uid(sop_instance_uid);
311 return assoc.
send_dimse(context_id, response);
318 const std::string& sop_instance_uid,
321 using namespace network::dimse;
324 dimse_message response{command_field::n_set_rsp, 0};
325 response.set_message_id_responded_to(message_id);
327 response.set_status(status);
329 if (!sop_instance_uid.empty()) {
330 response.set_affected_sop_instance_uid(sop_instance_uid);
334 return assoc.
send_dimse(context_id, response);
Result< std::monostate > send_dimse(uint8_t context_id, const dimse::dimse_message &msg)
Send a DIMSE message.
auto message_id() const noexcept -> uint16_t
Get the message ID.
auto affected_sop_class_uid() const -> std::string
Get the Affected SOP Class UID.
auto command_set() noexcept -> core::dicom_dataset &
Get mutable reference to the command set.
auto has_dataset() const noexcept -> bool
Check if the message has an associated data set.
auto dataset() -> kcenon::pacs::Result< std::reference_wrapper< core::dicom_dataset > >
Get mutable reference to the data set.
auto affected_sop_instance_uid() const -> std::string
Get the Affected SOP Instance UID.
auto command() const noexcept -> command_field
Get the command field.
void set_set_handler(mpps_set_handler handler)
Set the N-SET handler function.
void reset_statistics() noexcept
Reset statistics counters.
void set_create_handler(mpps_create_handler handler)
Set the N-CREATE handler function.
mpps_set_handler set_handler_
network::Result< std::monostate > handle_n_create(network::association &assoc, uint8_t context_id, const network::dimse::dimse_message &request)
Handle N-CREATE request.
size_t creates_processed() const noexcept
Get total number of N-CREATE requests processed.
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.
std::atomic< size_t > creates_processed_
std::atomic< size_t > sets_processed_
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.
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)
size_t mpps_completed() const noexcept
Get number of MPPS completed successfully.
size_t mpps_discontinued() const noexcept
Get number of MPPS discontinued.
std::vector< std::string > supported_sop_classes() const override
Get supported SOP Class UIDs.
network::Result< std::monostate > handle_n_set(network::association &assoc, uint8_t context_id, const network::dimse::dimse_message &request)
Handle N-SET request.
mpps_create_handler create_handler_
mpps_scp(std::shared_ptr< di::ILogger > logger=nullptr)
Construct MPPS SCP with optional logger.
size_t sets_processed() const noexcept
Get total number of N-SET requests processed.
std::atomic< size_t > mpps_completed_
std::atomic< size_t > mpps_discontinued_
std::string_view service_name() const noexcept override
Get the service name.
DIMSE command field enumeration.
Compile-time constants for commonly used DICOM tags.
DICOM MPPS (Modality Performed Procedure Step) SCP service.
constexpr int mpps_handler_not_set
constexpr int mpps_unexpected_command
uint16_t status_code
DIMSE status code type alias.
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.
@ 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.
auto to_string(mpps_status status) -> std::string_view
Convert mpps_status to DICOM string representation.
constexpr std::string_view mpps_sop_class_uid
MPPS (Modality Performed Procedure Step) SOP Class UID.
auto parse_mpps_status(std::string_view str) -> std::optional< mpps_status >
Parse DICOM string to mpps_status enum.
VoidResult pacs_void_error(int code, const std::string &message, const std::string &details="")
Create a PACS void error result.
Result<T> type aliases and helpers for PACS system.
MPPS instance data structure.
mpps_status status
Current status (always IN PROGRESS for N-CREATE)
std::string sop_instance_uid
SOP Instance UID - unique identifier for this MPPS.
std::string station_ae
Performing station AE Title.
core::dicom_dataset data
Complete MPPS dataset from the request.