24 std::shared_ptr<di::ILogger> logger)
25 : logger_(logger ? std::move(logger) : di::null_logger()) {}
42 const std::string& transaction_uid,
43 const std::vector<sop_reference>& references) {
45 using namespace network::dimse;
47 if (transaction_uid.empty() || references.empty()) {
50 "Transaction UID and references must not be empty");
54 auto action_rq = make_n_action_rq(
62 action_rq.set_dataset(std::move(action_dataset));
65 auto send_result = assoc.
send_dimse(context_id, action_rq);
66 if (send_result.is_err()) {
71 return kcenon::pacs::ok();
81 using namespace network::dimse;
84 if (event_rq.
command() != command_field::n_event_report_rq) {
87 "Expected N-EVENT-REPORT-RQ, got: " +
95 "N-EVENT-REPORT-RQ has no dataset");
98 const auto& dataset = event_rq.
dataset().value().get();
107 callback_(result.transaction_uid, result);
135 const std::string& transaction_uid,
136 const std::vector<sop_reference>& references) {
147 for (
const auto& ref : references) {
153 seq.push_back(std::move(item));
166 result.
timestamp = std::chrono::system_clock::now();
169 if (
const auto* success_seq =
171 for (
const auto& item : *success_seq) {
184 if (
const auto* failed_seq =
186 for (
const auto& item : *failed_seq) {
194 auto reason_val = item.get_numeric<uint16_t>(
196 if (reason_val.has_value()) {
auto get_sequence(dicom_tag tag) const noexcept -> const std::vector< dicom_dataset > *
void set_string(dicom_tag tag, encoding::vr_type vr, std::string_view value)
Set a string value for the given tag.
auto get_or_create_sequence(dicom_tag tag) -> std::vector< dicom_dataset > &
Insert or create a sequence element with the given tag.
auto get_string(dicom_tag tag, std::string_view default_value="") const -> std::string
Get the string value of an element.
Result< std::monostate > send_dimse(uint8_t context_id, const dimse::dimse_message &msg)
Send a DIMSE message.
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 command() const noexcept -> command_field
Get the command field.
size_t event_reports_received() const noexcept
std::atomic< size_t > event_reports_received_
std::function< void( const std::string &transaction_uid, const commitment_result &result)> commitment_callback
Callback type for commitment results.
void reset_statistics() noexcept
storage_commitment_scu(std::shared_ptr< di::ILogger > logger=nullptr)
std::atomic< size_t > requests_sent_
void set_commitment_callback(commitment_callback cb)
Set callback for commitment result notifications.
size_t requests_sent() const noexcept
network::Result< commitment_result > handle_event_report(const network::dimse::dimse_message &event_rq)
Handle an N-EVENT-REPORT-RQ received from the SCP.
commitment_callback callback_
static commitment_result parse_event_report_dataset(const core::dicom_dataset &dataset)
network::Result< std::monostate > request_commitment(network::association &assoc, uint8_t context_id, const std::string &transaction_uid, const std::vector< sop_reference > &references)
Send N-ACTION request to commit stored instances.
static core::dicom_dataset build_action_dataset(const std::string &transaction_uid, const std::vector< sop_reference > &references)
DIMSE command field enumeration.
Compile-time constants for commonly used DICOM tags.
@ UI
Unique Identifier (64 chars max)
constexpr int storage_commitment_unexpected_command
constexpr int storage_commitment_missing_transaction_uid
constexpr int storage_commitment_missing_sequence
constexpr std::string_view storage_commitment_push_model_sop_instance_uid
Storage Commitment Push Model SOP Instance UID (Well-Known)
constexpr std::string_view storage_commitment_push_model_sop_class_uid
Storage Commitment Push Model SOP Class UID (PS3.4 Table J.3-1)
commitment_failure_reason
Failure reason codes for Storage Commitment.
@ processing_failure
General processing failure.
constexpr uint16_t storage_commitment_action_type_request
N-ACTION: Request Storage Commitment (Action Type ID = 1)
auto to_string(mpps_status status) -> std::string_view
Convert mpps_status to DICOM string representation.
VoidResult pacs_void_error(int code, const std::string &message, const std::string &details="")
Create a PACS void error result.
Result< T > pacs_error(int code, const std::string &message, const std::string &details="")
Create a PACS error result with module context.
Result<T> type aliases and helpers for PACS system.
DICOM Storage Commitment Push Model SCU service.
Result of a Storage Commitment verification.
std::chrono::system_clock::time_point timestamp
Timestamp when verification was completed.
std::vector< std::pair< sop_reference, commitment_failure_reason > > failed_references
Failed SOP Instance references with failure reasons.
std::vector< sop_reference > success_references
Successfully committed SOP Instance references.
std::string transaction_uid
Transaction UID identifying this commitment request.
Reference to a SOP Instance in a commitment request.
std::string sop_class_uid
Referenced SOP Class UID (0008,1150)
std::string sop_instance_uid
Referenced SOP Instance UID (0008,1155)