Retrieve attributes from a managed SOP Instance.
Sends an N-GET-RQ and returns the retrieved attributes.
41 {
42
43 using namespace network::dimse;
44
45 auto start_time = std::chrono::steady_clock::now();
46
47
48 if (!assoc.is_established()) {
51 "Association not established");
52 }
53
54
58 "SOP Class UID is required for N-GET");
59 }
60
64 "SOP Instance UID is required for N-GET");
65 }
66
67
68 auto context_id = assoc.accepted_context_id(sop_class_uid);
69 if (!context_id) {
72 "No accepted presentation context for SOP Class: " +
73 std::string(sop_class_uid));
74 }
75
76
77 auto request = make_n_get_rq(
79
80 logger_->debug(
"Sending N-GET request for instance: " +
81 std::string(sop_instance_uid) +
82 " (attributes: " +
83 (attribute_tags.empty() ? "all" :
84 std::to_string(attribute_tags.size())) + ")");
85
86
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();
91 }
92
93
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();
99 }
100
101 const auto& [recv_context_id, response] = recv_result.value();
102
103
104 if (response.command() != command_field::n_get_rsp) {
107 "Expected N-GET-RSP but received " +
108 std::string(
to_string(response.command())));
109 }
110
111 auto end_time = std::chrono::steady_clock::now();
112 auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(
113 end_time - start_time);
114
115
116 n_get_result result;
117 result.status = static_cast<uint16_t>(response.status());
118 result.elapsed = elapsed;
119
120
121 if (response.command_set().contains(tag_error_comment)) {
122 result.error_comment = response.command_set().get_string(
123 tag_error_comment);
124 }
125
126
127 if (response.has_dataset()) {
128 auto dataset_result = response.dataset();
129 if (dataset_result.is_ok()) {
130 result.attributes = dataset_result.value().get();
131 }
132 }
133
134
136
137 if (result.is_success()) {
138 logger_->info(
"N-GET successful for instance: " +
139 std::string(sop_instance_uid));
140 } else {
141 logger_->warn(
"N-GET returned status 0x" +
142 std::to_string(result.status) +
143 " for instance: " + std::string(sop_instance_uid));
144 }
145
146 return result;
147}
uint16_t next_message_id() noexcept
Get the next message ID for DIMSE operations.
std::atomic< size_t > gets_performed_
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.
std::chrono::milliseconds timeout
Timeout for receiving DIMSE response.