26 : logger_(logger ? std::move(logger) : di::null_logger()) {}
29 std::shared_ptr<di::ILogger> logger)
30 : logger_(logger ? std::move(logger) : di::null_logger()),
39 std::string_view sop_class_uid,
40 std::string_view sop_instance_uid,
41 const std::vector<core::dicom_tag>& attribute_tags) {
43 using namespace network::dimse;
45 auto start_time = std::chrono::steady_clock::now();
51 "Association not established");
55 if (sop_class_uid.empty()) {
58 "SOP Class UID is required for N-GET");
61 if (sop_instance_uid.empty()) {
64 "SOP Instance UID is required for N-GET");
72 "No accepted presentation context for SOP Class: " +
73 std::string(sop_class_uid));
77 auto request = make_n_get_rq(
80 logger_->debug(
"Sending N-GET request for instance: " +
81 std::string(sop_instance_uid) +
83 (attribute_tags.empty() ?
"all" :
84 std::to_string(attribute_tags.size())) +
")");
87 auto send_result = assoc.
send_dimse(*context_id, request);
88 if (send_result.is_err()) {
89 logger_->error(
"Failed to send N-GET: " + send_result.error().message);
90 return send_result.error();
95 if (recv_result.is_err()) {
96 logger_->error(
"Failed to receive N-GET response: " +
97 recv_result.error().message);
98 return recv_result.error();
101 const auto& [recv_context_id, response] = recv_result.value();
104 if (response.command() != command_field::n_get_rsp) {
107 "Expected N-GET-RSP but received " +
108 std::string(
to_string(response.command())));
111 auto end_time = std::chrono::steady_clock::now();
112 auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(
113 end_time - start_time);
117 result.
status =
static_cast<uint16_t
>(response.status());
121 if (response.command_set().contains(tag_error_comment)) {
127 if (response.has_dataset()) {
128 auto dataset_result = response.dataset();
129 if (dataset_result.is_ok()) {
138 logger_->info(
"N-GET successful for instance: " +
139 std::string(sop_instance_uid));
141 logger_->warn(
"N-GET returned status 0x" +
142 std::to_string(result.
status) +
143 " for instance: " + std::string(sop_instance_uid));
auto get(dicom_tag tag) noexcept -> dicom_element *
Get a pointer to the element with the given tag.
bool is_established() const noexcept
Check if association is established and ready for DIMSE.
Result< std::monostate > send_dimse(uint8_t context_id, const dimse::dimse_message &msg)
Send a DIMSE message.
Result< std::pair< uint8_t, dimse::dimse_message > > receive_dimse(duration timeout=default_timeout)
Receive a DIMSE message.
std::optional< uint8_t > accepted_context_id(std::string_view abstract_syntax) const
Get the presentation context ID for an abstract syntax.
std::atomic< uint16_t > message_id_counter_
void reset_statistics() noexcept
Reset statistics counters to zero.
uint16_t next_message_id() noexcept
Get the next message ID for DIMSE operations.
size_t gets_performed() const noexcept
Get the number of N-GET operations performed.
network::Result< n_get_result > get(network::association &assoc, std::string_view sop_class_uid, std::string_view sop_instance_uid, const std::vector< core::dicom_tag > &attribute_tags={})
Retrieve attributes from a managed SOP Instance.
n_get_scu(std::shared_ptr< di::ILogger > logger=nullptr)
Construct N-GET SCU with default configuration.
std::atomic< size_t > gets_performed_
std::shared_ptr< di::ILogger > logger_
DIMSE command field enumeration.
DICOM N-GET SCU service for attribute retrieval.
constexpr int n_get_missing_uid
constexpr int n_get_unexpected_command
constexpr int n_get_context_not_accepted
constexpr int association_not_established
auto to_string(mpps_status status) -> std::string_view
Convert mpps_status to DICOM string representation.
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.
Result of an N-GET operation.
std::chrono::milliseconds elapsed
Time taken for the operation.
std::string error_comment
Error comment from the SCP (if any)
core::dicom_dataset attributes
Retrieved attributes from the SOP Instance.
uint16_t status
DIMSE status code (0x0000 = success)
bool is_success() const noexcept
Check if the operation was successful.
Configuration for N-GET SCU service.
std::chrono::milliseconds timeout
Timeout for receiving DIMSE response.