PACS System 0.1.0
PACS DICOM system library
Loading...
Searching...
No Matches
kcenon::pacs::network::pdu_encoder Class Reference

Encoder for DICOM PDU (Protocol Data Unit) messages. More...

#include <pdu_encoder.h>

Collaboration diagram for kcenon::pacs::network::pdu_encoder:
Collaboration graph

Static Public Member Functions

Association PDUs
static std::vector< uint8_t > encode_associate_rq (const associate_rq &rq)
 Encodes an A-ASSOCIATE-RQ PDU.
 
static std::vector< uint8_t > encode_associate_ac (const associate_ac &ac)
 Encodes an A-ASSOCIATE-AC PDU.
 
static std::vector< uint8_t > encode_associate_rj (const associate_rj &rj)
 Encodes an A-ASSOCIATE-RJ PDU.
 
Release PDUs
static std::vector< uint8_t > encode_release_rq ()
 Encodes an A-RELEASE-RQ PDU.
 
static std::vector< uint8_t > encode_release_rp ()
 Encodes an A-RELEASE-RP PDU.
 
Abort PDU
static std::vector< uint8_t > encode_abort (uint8_t source, uint8_t reason)
 Encodes an A-ABORT PDU.
 
static std::vector< uint8_t > encode_abort (abort_source source, abort_reason reason)
 Encodes an A-ABORT PDU using typed enums.
 
Data PDU
static std::vector< uint8_t > encode_p_data_tf (const std::vector< presentation_data_value > &pdvs)
 Encodes a P-DATA-TF PDU.
 
static std::vector< uint8_t > encode_p_data_tf (const presentation_data_value &pdv)
 Encodes a single PDV into a P-DATA-TF PDU.
 

Static Private Member Functions

Helper Functions
static void write_uint16_be (std::vector< uint8_t > &buffer, uint16_t value)
 Writes a 16-bit unsigned integer in big-endian format.
 
static void write_uint32_be (std::vector< uint8_t > &buffer, uint32_t value)
 Writes a 32-bit unsigned integer in big-endian format.
 
static void write_ae_title (std::vector< uint8_t > &buffer, const std::string &ae_title)
 Writes an AE Title (16 bytes, space-padded).
 
static void write_uid (std::vector< uint8_t > &buffer, const std::string &uid)
 Writes a UID string.
 
static void update_pdu_length (std::vector< uint8_t > &buffer)
 Updates the PDU length field at position 2-5.
 
static void encode_application_context (std::vector< uint8_t > &buffer, const std::string &context_name)
 Encodes an Application Context item.
 
static void encode_presentation_context_rq (std::vector< uint8_t > &buffer, const presentation_context_rq &pc)
 Encodes a Presentation Context item for A-ASSOCIATE-RQ.
 
static void encode_presentation_context_ac (std::vector< uint8_t > &buffer, const presentation_context_ac &pc)
 Encodes a Presentation Context item for A-ASSOCIATE-AC.
 
static void encode_user_information (std::vector< uint8_t > &buffer, const user_information &user_info)
 Encodes a User Information item.
 
static void encode_associate_header (std::vector< uint8_t > &buffer, pdu_type type, const std::string &called_ae, const std::string &calling_ae)
 Encodes the common header portion for ASSOCIATE-RQ/AC PDUs.
 

Detailed Description

Encoder for DICOM PDU (Protocol Data Unit) messages.

This class provides static methods to encode various PDU types according to DICOM PS3.8 Upper Layer Protocol.

PDU Structure:

┌─────────────────────────────────────┐
│ PDU Header │
├───────────┬───────────┬─────────────┤
│ Type │ Reserved │ Length │
│ (1 byte) │ (1 byte) │ (4 bytes) │
└───────────┴───────────┴─────────────┘
│ PDU Data (variable) │
└─────────────────────────────────────┘
See also
DICOM PS3.8 Section 9 - Upper Layer Protocol

Definition at line 41 of file pdu_encoder.h.

Member Function Documentation

◆ encode_abort() [1/2]

std::vector< uint8_t > kcenon::pacs::network::pdu_encoder::encode_abort ( abort_source source,
abort_reason reason )
staticnodiscard

Encodes an A-ABORT PDU using typed enums.

Parameters
sourceAbort source
reasonAbort reason
Returns
Encoded PDU bytes

Definition at line 430 of file pdu_encoder.cpp.

431 {
432 return encode_abort(static_cast<uint8_t>(source),
433 static_cast<uint8_t>(reason));
434}
static std::vector< uint8_t > encode_abort(uint8_t source, uint8_t reason)
Encodes an A-ABORT PDU.

References encode_abort().

Here is the call graph for this function:

◆ encode_abort() [2/2]

std::vector< uint8_t > kcenon::pacs::network::pdu_encoder::encode_abort ( uint8_t source,
uint8_t reason )
staticnodiscard

Encodes an A-ABORT PDU.

Parameters
sourceAbort source (0=UL service-user, 2=UL service-provider)
reasonAbort reason (only applicable when source=2)
Returns
Encoded PDU bytes (always 10 bytes)
See also
DICOM PS3.8 Section 9.3.8

Definition at line 406 of file pdu_encoder.cpp.

406 {
407 // A-ABORT PDU structure (10 bytes total):
408 // - PDU Type (1 byte) = 0x07
409 // - Reserved (1 byte)
410 // - PDU Length (4 bytes) = 0x00000004
411 // - Reserved (1 byte)
412 // - Reserved (1 byte)
413 // - Source (1 byte)
414 // - Reason/Diag (1 byte)
415
416 std::vector<uint8_t> buffer;
417 buffer.reserve(10);
418
419 buffer.push_back(static_cast<uint8_t>(pdu_type::abort));
420 buffer.push_back(0x00); // Reserved
421 write_uint32_be(buffer, 0x00000004); // PDU Length
422 buffer.push_back(0x00); // Reserved
423 buffer.push_back(0x00); // Reserved
424 buffer.push_back(source);
425 buffer.push_back(reason);
426
427 return buffer;
428}
static void write_uint32_be(std::vector< uint8_t > &buffer, uint32_t value)
Writes a 32-bit unsigned integer in big-endian format.

References kcenon::pacs::network::abort, and write_uint32_be().

Referenced by encode_abort(), and kcenon::pacs::network::v2::dicom_association_handler::send_abort().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ encode_application_context()

void kcenon::pacs::network::pdu_encoder::encode_application_context ( std::vector< uint8_t > & buffer,
const std::string & context_name )
staticprivate

Encodes an Application Context item.

Definition at line 64 of file pdu_encoder.cpp.

65 {
66 // Application Context Item structure:
67 // - Item type (1 byte) = 0x10
68 // - Reserved (1 byte)
69 // - Item length (2 bytes)
70 // - Application Context Name (variable)
71
72 buffer.push_back(static_cast<uint8_t>(item_type::application_context));
73 buffer.push_back(0x00); // Reserved
74
75 // Calculate padded length
76 size_t uid_length = context_name.size();
77 if (uid_length % 2 != 0) {
78 uid_length++;
79 }
80
81 write_uint16_be(buffer, static_cast<uint16_t>(uid_length));
82 write_uid(buffer, context_name);
83}
static void write_uint16_be(std::vector< uint8_t > &buffer, uint16_t value)
Writes a 16-bit unsigned integer in big-endian format.
static void write_uid(std::vector< uint8_t > &buffer, const std::string &uid)
Writes a UID string.
@ application_context
Application Context Item.

References kcenon::pacs::network::application_context, write_uid(), and write_uint16_be().

Referenced by encode_associate_ac(), and encode_associate_rq().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ encode_associate_ac()

std::vector< uint8_t > kcenon::pacs::network::pdu_encoder::encode_associate_ac ( const associate_ac & ac)
staticnodiscard

Encodes an A-ASSOCIATE-AC PDU.

Parameters
acThe association accept data
Returns
Encoded PDU bytes
See also
DICOM PS3.8 Section 9.3.3

Definition at line 323 of file pdu_encoder.cpp.

323 {
324 std::vector<uint8_t> buffer;
325 buffer.reserve(512);
326
328 ac.called_ae_title, ac.calling_ae_title);
329
330 // Variable Items
331 encode_application_context(buffer, ac.application_context.empty()
333 : ac.application_context);
334
335 for (const auto& pc : ac.presentation_contexts) {
337 }
338
339 encode_user_information(buffer, ac.user_info);
340
341 update_pdu_length(buffer);
342 return buffer;
343}
static void encode_associate_header(std::vector< uint8_t > &buffer, pdu_type type, const std::string &called_ae, const std::string &calling_ae)
Encodes the common header portion for ASSOCIATE-RQ/AC PDUs.
static void encode_user_information(std::vector< uint8_t > &buffer, const user_information &user_info)
Encodes a User Information item.
static void update_pdu_length(std::vector< uint8_t > &buffer)
Updates the PDU length field at position 2-5.
static void encode_presentation_context_ac(std::vector< uint8_t > &buffer, const presentation_context_ac &pc)
Encodes a Presentation Context item for A-ASSOCIATE-AC.
static void encode_application_context(std::vector< uint8_t > &buffer, const std::string &context_name)
Encodes an Application Context item.
@ associate_ac
A-ASSOCIATE-AC (Association Accept)
constexpr const char * DICOM_APPLICATION_CONTEXT
Default DICOM Application Context Name (PS3.7)
Definition pdu_types.h:267

References kcenon::pacs::network::associate_ac::application_context, kcenon::pacs::network::associate_ac, kcenon::pacs::network::associate_ac::called_ae_title, kcenon::pacs::network::associate_ac::calling_ae_title, kcenon::pacs::network::DICOM_APPLICATION_CONTEXT, encode_application_context(), encode_associate_header(), encode_presentation_context_ac(), encode_user_information(), kcenon::pacs::network::associate_ac::presentation_contexts, update_pdu_length(), and kcenon::pacs::network::associate_ac::user_info.

Referenced by kcenon::pacs::network::v2::dicom_association_handler::send_associate_ac().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ encode_associate_header()

void kcenon::pacs::network::pdu_encoder::encode_associate_header ( std::vector< uint8_t > & buffer,
pdu_type type,
const std::string & called_ae,
const std::string & calling_ae )
staticprivate

Encodes the common header portion for ASSOCIATE-RQ/AC PDUs.

Definition at line 270 of file pdu_encoder.cpp.

273 {
274 // PDU Header
275 buffer.push_back(static_cast<uint8_t>(type));
276 buffer.push_back(0x00); // Reserved
277
278 // PDU Length placeholder (4 bytes)
279 write_uint32_be(buffer, 0x00000000);
280
281 // Protocol Version (2 bytes)
283
284 // Reserved (2 bytes)
285 write_uint16_be(buffer, 0x0000);
286
287 // Called AE Title (16 bytes)
288 write_ae_title(buffer, called_ae);
289
290 // Calling AE Title (16 bytes)
291 write_ae_title(buffer, calling_ae);
292
293 // Reserved (32 bytes)
294 buffer.insert(buffer.end(), 32, 0x00);
295}
static void write_ae_title(std::vector< uint8_t > &buffer, const std::string &ae_title)
Writes an AE Title (16 bytes, space-padded).
constexpr uint16_t DICOM_PROTOCOL_VERSION
DICOM Protocol Version.
Definition pdu_types.h:270

References kcenon::pacs::network::DICOM_PROTOCOL_VERSION, write_ae_title(), write_uint16_be(), and write_uint32_be().

Referenced by encode_associate_ac(), and encode_associate_rq().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ encode_associate_rj()

std::vector< uint8_t > kcenon::pacs::network::pdu_encoder::encode_associate_rj ( const associate_rj & rj)
staticnodiscard

Encodes an A-ASSOCIATE-RJ PDU.

Parameters
rjThe association reject data
Returns
Encoded PDU bytes
See also
DICOM PS3.8 Section 9.3.4

Definition at line 345 of file pdu_encoder.cpp.

345 {
346 // A-ASSOCIATE-RJ PDU structure (10 bytes total):
347 // - PDU Type (1 byte) = 0x03
348 // - Reserved (1 byte)
349 // - PDU Length (4 bytes) = 0x00000004
350 // - Reserved (1 byte)
351 // - Result (1 byte)
352 // - Source (1 byte)
353 // - Reason/Diag (1 byte)
354
355 std::vector<uint8_t> buffer;
356 buffer.reserve(10);
357
358 buffer.push_back(static_cast<uint8_t>(pdu_type::associate_rj));
359 buffer.push_back(0x00); // Reserved
360 write_uint32_be(buffer, 0x00000004); // PDU Length
361
362 buffer.push_back(0x00); // Reserved
363 buffer.push_back(static_cast<uint8_t>(rj.result));
364 buffer.push_back(rj.source);
365 buffer.push_back(rj.reason);
366
367 return buffer;
368}
@ associate_rj
A-ASSOCIATE-RJ (Association Reject)

References kcenon::pacs::network::associate_rj, kcenon::pacs::network::associate_rj::reason, kcenon::pacs::network::associate_rj::result, kcenon::pacs::network::associate_rj::source, and write_uint32_be().

Referenced by kcenon::pacs::network::v2::dicom_association_handler::send_associate_rj().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ encode_associate_rq()

std::vector< uint8_t > kcenon::pacs::network::pdu_encoder::encode_associate_rq ( const associate_rq & rq)
staticnodiscard

Encodes an A-ASSOCIATE-RQ PDU.

Parameters
rqThe association request data
Returns
Encoded PDU bytes
See also
DICOM PS3.8 Section 9.3.2

Definition at line 301 of file pdu_encoder.cpp.

301 {
302 std::vector<uint8_t> buffer;
303 buffer.reserve(512); // Pre-allocate reasonable size
304
306 rq.called_ae_title, rq.calling_ae_title);
307
308 // Variable Items
309 encode_application_context(buffer, rq.application_context.empty()
311 : rq.application_context);
312
313 for (const auto& pc : rq.presentation_contexts) {
315 }
316
317 encode_user_information(buffer, rq.user_info);
318
319 update_pdu_length(buffer);
320 return buffer;
321}
static void encode_presentation_context_rq(std::vector< uint8_t > &buffer, const presentation_context_rq &pc)
Encodes a Presentation Context item for A-ASSOCIATE-RQ.
@ associate_rq
A-ASSOCIATE-RQ (Association Request)

References kcenon::pacs::network::associate_rq::application_context, kcenon::pacs::network::associate_rq, kcenon::pacs::network::associate_rq::called_ae_title, kcenon::pacs::network::associate_rq::calling_ae_title, kcenon::pacs::network::DICOM_APPLICATION_CONTEXT, encode_application_context(), encode_associate_header(), encode_presentation_context_rq(), encode_user_information(), kcenon::pacs::network::associate_rq::presentation_contexts, update_pdu_length(), and kcenon::pacs::network::associate_rq::user_info.

Here is the call graph for this function:

◆ encode_p_data_tf() [1/2]

std::vector< uint8_t > kcenon::pacs::network::pdu_encoder::encode_p_data_tf ( const presentation_data_value & pdv)
staticnodiscard

Encodes a single PDV into a P-DATA-TF PDU.

Parameters
pdvThe Presentation Data Value
Returns
Encoded PDU bytes

Definition at line 481 of file pdu_encoder.cpp.

482 {
483 return encode_p_data_tf(std::vector<presentation_data_value>{pdv});
484}
static std::vector< uint8_t > encode_p_data_tf(const std::vector< presentation_data_value > &pdvs)
Encodes a P-DATA-TF PDU.

References encode_p_data_tf().

Here is the call graph for this function:

◆ encode_p_data_tf() [2/2]

std::vector< uint8_t > kcenon::pacs::network::pdu_encoder::encode_p_data_tf ( const std::vector< presentation_data_value > & pdvs)
staticnodiscard

Encodes a P-DATA-TF PDU.

Parameters
pdvsList of Presentation Data Values to send
Returns
Encoded PDU bytes

P-DATA-TF can contain multiple PDV items. Each PDV has:

  • 4-byte length
  • 1-byte Presentation Context ID
  • 1-byte Message Control Header
  • Variable data
See also
DICOM PS3.8 Section 9.3.5

Definition at line 436 of file pdu_encoder.cpp.

437 {
438
439 std::vector<uint8_t> buffer;
440 buffer.reserve(256);
441
442 // PDU Header
443 buffer.push_back(static_cast<uint8_t>(pdu_type::p_data_tf));
444 buffer.push_back(0x00); // Reserved
445
446 // PDU Length placeholder
447 write_uint32_be(buffer, 0x00000000);
448
449 // PDV Items
450 for (const auto& pdv : pdvs) {
451 // PDV Item structure:
452 // - Item length (4 bytes) = context_id (1) + control (1) + data
453 // - Presentation Context ID (1 byte)
454 // - Message Control Header (1 byte)
455 // - Presentation Data Value (variable)
456
457 const uint32_t pdv_length = static_cast<uint32_t>(2 + pdv.data.size());
458 write_uint32_be(buffer, pdv_length);
459
460 buffer.push_back(pdv.context_id);
461
462 // Message Control Header:
463 // - Bit 0: 0 = Data, 1 = Command
464 // - Bit 1: 0 = Not last, 1 = Last
465 uint8_t control = 0;
466 if (pdv.is_command) {
467 control |= 0x01;
468 }
469 if (pdv.is_last) {
470 control |= 0x02;
471 }
472 buffer.push_back(control);
473
474 buffer.insert(buffer.end(), pdv.data.begin(), pdv.data.end());
475 }
476
477 update_pdu_length(buffer);
478 return buffer;
479}
@ control
Internal pipeline control messages.
@ p_data_tf
P-DATA-TF (Data Transfer)

References kcenon::pacs::network::p_data_tf, update_pdu_length(), and write_uint32_be().

Referenced by encode_p_data_tf().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ encode_presentation_context_ac()

void kcenon::pacs::network::pdu_encoder::encode_presentation_context_ac ( std::vector< uint8_t > & buffer,
const presentation_context_ac & pc )
staticprivate

Encodes a Presentation Context item for A-ASSOCIATE-AC.

Definition at line 143 of file pdu_encoder.cpp.

144 {
145 // Presentation Context Item (AC) structure:
146 // - Item type (1 byte) = 0x21
147 // - Reserved (1 byte)
148 // - Item length (2 bytes)
149 // - Presentation Context ID (1 byte)
150 // - Reserved (1 byte)
151 // - Result/Reason (1 byte)
152 // - Reserved (1 byte)
153 // - Transfer Syntax sub-item
154
155 const size_t start_pos = buffer.size();
156
157 buffer.push_back(static_cast<uint8_t>(item_type::presentation_context_ac));
158 buffer.push_back(0x00); // Reserved
159
160 // Placeholder for item length
161 const size_t length_pos = buffer.size();
162 write_uint16_be(buffer, 0x0000);
163
164 buffer.push_back(pc.id);
165 buffer.push_back(0x00); // Reserved
166 buffer.push_back(static_cast<uint8_t>(pc.result));
167 buffer.push_back(0x00); // Reserved
168
169 // Transfer Syntax sub-item (only if accepted)
171 !pc.transfer_syntax.empty()) {
172 buffer.push_back(static_cast<uint8_t>(item_type::transfer_syntax));
173 buffer.push_back(0x00); // Reserved
174
175 size_t ts_length = pc.transfer_syntax.size();
176 if (ts_length % 2 != 0) {
177 ts_length++;
178 }
179 write_uint16_be(buffer, static_cast<uint16_t>(ts_length));
180 write_uid(buffer, pc.transfer_syntax);
181 }
182
183 // Update item length
184 const uint16_t item_length = static_cast<uint16_t>(buffer.size() - start_pos - 4);
185 buffer[length_pos] = static_cast<uint8_t>((item_length >> 8) & 0xFF);
186 buffer[length_pos + 1] = static_cast<uint8_t>(item_length & 0xFF);
187}
@ transfer_syntax
Transfer Syntax Sub-item.
@ presentation_context_ac
Presentation Context Item (AC)

References kcenon::pacs::network::acceptance, kcenon::pacs::network::presentation_context_ac::id, kcenon::pacs::network::presentation_context_ac, kcenon::pacs::network::presentation_context_ac::result, kcenon::pacs::network::transfer_syntax, kcenon::pacs::network::presentation_context_ac::transfer_syntax, write_uid(), and write_uint16_be().

Referenced by encode_associate_ac().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ encode_presentation_context_rq()

void kcenon::pacs::network::pdu_encoder::encode_presentation_context_rq ( std::vector< uint8_t > & buffer,
const presentation_context_rq & pc )
staticprivate

Encodes a Presentation Context item for A-ASSOCIATE-RQ.

Definition at line 85 of file pdu_encoder.cpp.

86 {
87 // Presentation Context Item (RQ) structure:
88 // - Item type (1 byte) = 0x20
89 // - Reserved (1 byte)
90 // - Item length (2 bytes)
91 // - Presentation Context ID (1 byte)
92 // - Reserved (1 byte)
93 // - Reserved (1 byte)
94 // - Reserved (1 byte)
95 // - Abstract Syntax sub-item
96 // - Transfer Syntax sub-items
97
98 const size_t start_pos = buffer.size();
99
100 buffer.push_back(static_cast<uint8_t>(item_type::presentation_context_rq));
101 buffer.push_back(0x00); // Reserved
102
103 // Placeholder for item length
104 const size_t length_pos = buffer.size();
105 write_uint16_be(buffer, 0x0000);
106
107 // Presentation Context ID
108 buffer.push_back(pc.id);
109 buffer.push_back(0x00); // Reserved
110 buffer.push_back(0x00); // Reserved
111 buffer.push_back(0x00); // Reserved
112
113 // Abstract Syntax sub-item
114 buffer.push_back(static_cast<uint8_t>(item_type::abstract_syntax));
115 buffer.push_back(0x00); // Reserved
116
117 size_t abs_length = pc.abstract_syntax.size();
118 if (abs_length % 2 != 0) {
119 abs_length++;
120 }
121 write_uint16_be(buffer, static_cast<uint16_t>(abs_length));
122 write_uid(buffer, pc.abstract_syntax);
123
124 // Transfer Syntax sub-items
125 for (const auto& ts : pc.transfer_syntaxes) {
126 buffer.push_back(static_cast<uint8_t>(item_type::transfer_syntax));
127 buffer.push_back(0x00); // Reserved
128
129 size_t ts_length = ts.size();
130 if (ts_length % 2 != 0) {
131 ts_length++;
132 }
133 write_uint16_be(buffer, static_cast<uint16_t>(ts_length));
134 write_uid(buffer, ts);
135 }
136
137 // Update item length
138 const uint16_t item_length = static_cast<uint16_t>(buffer.size() - start_pos - 4);
139 buffer[length_pos] = static_cast<uint8_t>((item_length >> 8) & 0xFF);
140 buffer[length_pos + 1] = static_cast<uint8_t>(item_length & 0xFF);
141}
@ presentation_context_rq
Presentation Context Item (RQ)
@ abstract_syntax
Abstract Syntax Sub-item.
Transfer Syntax UIDs.
Definition main.cpp:78

References kcenon::pacs::network::abstract_syntax, kcenon::pacs::network::presentation_context_rq::abstract_syntax, kcenon::pacs::network::presentation_context_rq::id, kcenon::pacs::network::presentation_context_rq, kcenon::pacs::network::transfer_syntax, kcenon::pacs::network::presentation_context_rq::transfer_syntaxes, write_uid(), and write_uint16_be().

Referenced by encode_associate_rq().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ encode_release_rp()

std::vector< uint8_t > kcenon::pacs::network::pdu_encoder::encode_release_rp ( )
staticnodiscard

Encodes an A-RELEASE-RP PDU.

Returns
Encoded PDU bytes (always 10 bytes)
See also
DICOM PS3.8 Section 9.3.7

Definition at line 388 of file pdu_encoder.cpp.

388 {
389 // A-RELEASE-RP PDU structure (10 bytes total):
390 // - PDU Type (1 byte) = 0x06
391 // - Reserved (1 byte)
392 // - PDU Length (4 bytes) = 0x00000004
393 // - Reserved (4 bytes)
394
395 std::vector<uint8_t> buffer;
396 buffer.reserve(10);
397
398 buffer.push_back(static_cast<uint8_t>(pdu_type::release_rp));
399 buffer.push_back(0x00); // Reserved
400 write_uint32_be(buffer, 0x00000004); // PDU Length
401 write_uint32_be(buffer, 0x00000000); // Reserved
402
403 return buffer;
404}
@ release_rp
A-RELEASE-RP (Release Response)

References kcenon::pacs::network::release_rp, and write_uint32_be().

Referenced by kcenon::pacs::network::v2::dicom_association_handler::send_release_rp().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ encode_release_rq()

std::vector< uint8_t > kcenon::pacs::network::pdu_encoder::encode_release_rq ( )
staticnodiscard

Encodes an A-RELEASE-RQ PDU.

Returns
Encoded PDU bytes (always 10 bytes)
See also
DICOM PS3.8 Section 9.3.6

Definition at line 370 of file pdu_encoder.cpp.

370 {
371 // A-RELEASE-RQ PDU structure (10 bytes total):
372 // - PDU Type (1 byte) = 0x05
373 // - Reserved (1 byte)
374 // - PDU Length (4 bytes) = 0x00000004
375 // - Reserved (4 bytes)
376
377 std::vector<uint8_t> buffer;
378 buffer.reserve(10);
379
380 buffer.push_back(static_cast<uint8_t>(pdu_type::release_rq));
381 buffer.push_back(0x00); // Reserved
382 write_uint32_be(buffer, 0x00000004); // PDU Length
383 write_uint32_be(buffer, 0x00000000); // Reserved
384
385 return buffer;
386}
@ release_rq
A-RELEASE-RQ (Release Request)

References kcenon::pacs::network::release_rq, and write_uint32_be().

Here is the call graph for this function:

◆ encode_user_information()

void kcenon::pacs::network::pdu_encoder::encode_user_information ( std::vector< uint8_t > & buffer,
const user_information & user_info )
staticprivate

Encodes a User Information item.

Definition at line 189 of file pdu_encoder.cpp.

190 {
191 // User Information Item structure:
192 // - Item type (1 byte) = 0x50
193 // - Reserved (1 byte)
194 // - Item length (2 bytes)
195 // - User data sub-items
196
197 const size_t start_pos = buffer.size();
198
199 buffer.push_back(static_cast<uint8_t>(item_type::user_information));
200 buffer.push_back(0x00); // Reserved
201
202 // Placeholder for item length
203 const size_t length_pos = buffer.size();
204 write_uint16_be(buffer, 0x0000);
205
206 // Maximum Length sub-item (required)
207 buffer.push_back(static_cast<uint8_t>(item_type::maximum_length));
208 buffer.push_back(0x00); // Reserved
209 write_uint16_be(buffer, 0x0004); // Length is always 4
210 write_uint32_be(buffer, user_info.max_pdu_length);
211
212 // Implementation Class UID sub-item (required)
213 if (!user_info.implementation_class_uid.empty()) {
214 buffer.push_back(static_cast<uint8_t>(item_type::implementation_class_uid));
215 buffer.push_back(0x00); // Reserved
216
217 size_t uid_length = user_info.implementation_class_uid.size();
218 if (uid_length % 2 != 0) {
219 uid_length++;
220 }
221 write_uint16_be(buffer, static_cast<uint16_t>(uid_length));
222 write_uid(buffer, user_info.implementation_class_uid);
223 }
224
225 // Implementation Version Name sub-item (optional)
226 if (!user_info.implementation_version_name.empty()) {
227 buffer.push_back(static_cast<uint8_t>(item_type::implementation_version_name));
228 buffer.push_back(0x00); // Reserved
229
230 size_t name_length = user_info.implementation_version_name.size();
231 if (name_length % 2 != 0) {
232 name_length++;
233 }
234 write_uint16_be(buffer, static_cast<uint16_t>(name_length));
235
236 buffer.insert(buffer.end(),
237 user_info.implementation_version_name.begin(),
238 user_info.implementation_version_name.end());
239 if (user_info.implementation_version_name.size() % 2 != 0) {
240 buffer.push_back(' '); // Pad with space
241 }
242 }
243
244 // SCP/SCU Role Selection sub-items (optional)
245 for (const auto& role : user_info.role_selections) {
246 buffer.push_back(static_cast<uint8_t>(item_type::scp_scu_role_selection));
247 buffer.push_back(0x00); // Reserved
248
249 size_t uid_len = role.sop_class_uid.size();
250 if (uid_len % 2 != 0) {
251 uid_len++;
252 }
253 // Item length = UID length field (2) + UID + SCU role (1) + SCP role (1)
254 write_uint16_be(buffer, static_cast<uint16_t>(2 + uid_len + 2));
255
256 // UID length
257 write_uint16_be(buffer, static_cast<uint16_t>(role.sop_class_uid.size()));
258 write_uid(buffer, role.sop_class_uid);
259
260 buffer.push_back(role.scu_role ? 0x01 : 0x00);
261 buffer.push_back(role.scp_role ? 0x01 : 0x00);
262 }
263
264 // Update item length
265 const uint16_t item_length = static_cast<uint16_t>(buffer.size() - start_pos - 4);
266 buffer[length_pos] = static_cast<uint8_t>((item_length >> 8) & 0xFF);
267 buffer[length_pos + 1] = static_cast<uint8_t>(item_length & 0xFF);
268}
@ maximum_length
Maximum Length Sub-item.
@ scp_scu_role_selection
SCP/SCU Role Selection Sub-item.
@ implementation_class_uid
Implementation Class UID Sub-item.
@ implementation_version_name
Implementation Version Name Sub-item.
@ user_information
User Information Item.

References kcenon::pacs::network::implementation_class_uid, kcenon::pacs::network::user_information::implementation_class_uid, kcenon::pacs::network::implementation_version_name, kcenon::pacs::network::user_information::implementation_version_name, kcenon::pacs::network::user_information::max_pdu_length, kcenon::pacs::network::maximum_length, kcenon::pacs::network::user_information::role_selections, kcenon::pacs::network::scp_scu_role_selection, kcenon::pacs::network::user_information, write_uid(), write_uint16_be(), and write_uint32_be().

Referenced by encode_associate_ac(), and encode_associate_rq().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ update_pdu_length()

void kcenon::pacs::network::pdu_encoder::update_pdu_length ( std::vector< uint8_t > & buffer)
staticprivate

Updates the PDU length field at position 2-5.

Definition at line 48 of file pdu_encoder.cpp.

48 {
49 if (buffer.size() < 6) {
50 return;
51 }
52 // PDU length is bytes 2-5 (0-indexed), and covers data after the 6-byte header
53 const uint32_t length = static_cast<uint32_t>(buffer.size() - 6);
54 buffer[2] = static_cast<uint8_t>((length >> 24) & 0xFF);
55 buffer[3] = static_cast<uint8_t>((length >> 16) & 0xFF);
56 buffer[4] = static_cast<uint8_t>((length >> 8) & 0xFF);
57 buffer[5] = static_cast<uint8_t>(length & 0xFF);
58}
@ length
Linear distance measurement.

Referenced by encode_associate_ac(), encode_associate_rq(), and encode_p_data_tf().

Here is the caller graph for this function:

◆ write_ae_title()

void kcenon::pacs::network::pdu_encoder::write_ae_title ( std::vector< uint8_t > & buffer,
const std::string & ae_title )
staticprivate

Writes an AE Title (16 bytes, space-padded).

Definition at line 28 of file pdu_encoder.cpp.

29 {
30 // AE Title is exactly 16 bytes, space-padded
31 std::string padded = ae_title;
32 if (padded.size() > AE_TITLE_LENGTH) {
33 padded = padded.substr(0, AE_TITLE_LENGTH);
34 }
35 padded.resize(AE_TITLE_LENGTH, ' ');
36
37 buffer.insert(buffer.end(), padded.begin(), padded.end());
38}
constexpr size_t AE_TITLE_LENGTH
AE Title length (fixed 16 characters, space-padded)
Definition pdu_types.h:273

References kcenon::pacs::network::AE_TITLE_LENGTH.

Referenced by encode_associate_header().

Here is the caller graph for this function:

◆ write_uid()

void kcenon::pacs::network::pdu_encoder::write_uid ( std::vector< uint8_t > & buffer,
const std::string & uid )
staticprivate

Writes a UID string.

Definition at line 40 of file pdu_encoder.cpp.

40 {
41 buffer.insert(buffer.end(), uid.begin(), uid.end());
42 // Pad to even length if necessary
43 if (uid.size() % 2 != 0) {
44 buffer.push_back(0x00);
45 }
46}
std::string_view uid

References uid.

Referenced by encode_application_context(), encode_presentation_context_ac(), encode_presentation_context_rq(), and encode_user_information().

Here is the caller graph for this function:

◆ write_uint16_be()

void kcenon::pacs::network::pdu_encoder::write_uint16_be ( std::vector< uint8_t > & buffer,
uint16_t value )
staticprivate

Writes a 16-bit unsigned integer in big-endian format.

Definition at line 16 of file pdu_encoder.cpp.

16 {
17 buffer.push_back(static_cast<uint8_t>((value >> 8) & 0xFF));
18 buffer.push_back(static_cast<uint8_t>(value & 0xFF));
19}

Referenced by encode_application_context(), encode_associate_header(), encode_presentation_context_ac(), encode_presentation_context_rq(), and encode_user_information().

Here is the caller graph for this function:

◆ write_uint32_be()

void kcenon::pacs::network::pdu_encoder::write_uint32_be ( std::vector< uint8_t > & buffer,
uint32_t value )
staticprivate

Writes a 32-bit unsigned integer in big-endian format.

Definition at line 21 of file pdu_encoder.cpp.

21 {
22 buffer.push_back(static_cast<uint8_t>((value >> 24) & 0xFF));
23 buffer.push_back(static_cast<uint8_t>((value >> 16) & 0xFF));
24 buffer.push_back(static_cast<uint8_t>((value >> 8) & 0xFF));
25 buffer.push_back(static_cast<uint8_t>(value & 0xFF));
26}

Referenced by encode_abort(), encode_associate_header(), encode_associate_rj(), encode_p_data_tf(), encode_release_rp(), encode_release_rq(), and encode_user_information().

Here is the caller graph for this function:

The documentation for this class was generated from the following files: