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

DICOM session wrapper for network_system sessions. More...

#include <dicom_session.h>

Inheritance diagram for kcenon::pacs::integration::dicom_session:
Inheritance graph
Collaboration diagram for kcenon::pacs::integration::dicom_session:
Collaboration graph

Public Types

using clock = std::chrono::steady_clock
 
using duration = std::chrono::milliseconds
 
using time_point = clock::time_point
 

Public Member Functions

 dicom_session (std::shared_ptr< network_system::session::messaging_session > session)
 Construct a DICOM session wrapping a messaging_session.
 
 dicom_session (std::shared_ptr< network_system::session::secure_session > session)
 Construct a DICOM session wrapping a secure_session.
 
 dicom_session (std::shared_ptr< kcenon::network::interfaces::i_session > session)
 Construct a DICOM session wrapping an i_session interface.
 
 ~dicom_session ()
 Destructor (closes session if open)
 
 dicom_session (const dicom_session &)=delete
 
dicom_sessionoperator= (const dicom_session &)=delete
 
 dicom_session (dicom_session &&other) noexcept
 
dicom_sessionoperator= (dicom_session &&other) noexcept
 
Result< std::monostate > send_pdu (network::pdu_type type, const std::vector< uint8_t > &payload)
 Send a complete DICOM PDU.
 
Result< std::monostate > send_raw (const std::vector< uint8_t > &data)
 Send raw PDU data (with header already included)
 
Result< pdu_datareceive_pdu (duration timeout=default_timeout)
 Receive a complete DICOM PDU.
 
void set_pdu_callback (std::function< void(const pdu_data &)> callback)
 Set callback for asynchronous PDU reception.
 
void clear_pdu_callback ()
 Clear the PDU callback.
 
void feed_data (const std::vector< uint8_t > &data)
 Feed received data from external source.
 
void feed_error (std::error_code ec)
 Feed an error from external source.
 
void close ()
 Close the session.
 
bool is_open () const noexcept
 Check if the session is open.
 
std::string remote_address () const
 Get the remote peer address.
 
std::string session_id () const
 Get session identifier.
 
bool is_secure () const noexcept
 Check if this is a secure (TLS) session.
 
void set_error_callback (std::function< void(std::error_code)> callback)
 Set callback for error events.
 
std::error_code last_error () const noexcept
 Get the last error code.
 

Static Public Attributes

static constexpr duration default_timeout {30000}
 Default receive timeout.
 
static constexpr size_t pdu_header_size = 6
 PDU header size per DICOM PS3.8.
 
static constexpr size_t max_pdu_payload_size = 64 * 1024 * 1024
 Maximum PDU payload size (sanity check)
 

Private Types

using session_variant
 Variant for holding session types (legacy + public interface)
 

Private Member Functions

void on_data_received (const std::vector< uint8_t > &data)
 Handle incoming data from network.
 
void on_error (std::error_code ec)
 Handle connection errors.
 
void process_buffer ()
 Process buffered data for complete PDUs.
 
void send_data (std::vector< uint8_t > &&data)
 Send data through the underlying session.
 

Static Private Member Functions

static std::vector< uint8_t > encode_pdu_header (network::pdu_type type, uint32_t length)
 Encode PDU header.
 
static bool parse_pdu_header (const std::vector< uint8_t > &buffer, network::pdu_type &type, uint32_t &length)
 Parse PDU header from buffer.
 

Private Attributes

session_variant session_
 Underlying network session.
 
std::vector< uint8_t > receive_buffer_
 Receive buffer for PDU framing.
 
std::vector< pdu_datareceived_pdus_
 Queue of received complete PDUs.
 
std::function< void(const pdu_data &)> pdu_callback_
 PDU callback for async reception.
 
std::function< void(std::error_code)> error_callback_
 Error callback.
 
std::error_code last_error_
 Last error code.
 
bool closed_ = false
 Session closed flag.
 
std::mutex mutex_
 Mutex for thread safety.
 
std::condition_variable receive_cv_
 Condition variable for synchronous receive.
 

Detailed Description

DICOM session wrapper for network_system sessions.

This class wraps a network_system messaging_session (or secure_session) to provide DICOM PDU-level communication. Key features include:

  • PDU Framing: Handles DICOM PDU header parsing (6-byte header)
  • PDU Send/Receive: Send and receive complete PDUs
  • Timeout Support: Configurable timeouts for receive operations
  • Connection Management: Track connection state and remote address

PDU Header Format

The DICOM PDU header is 6 bytes:

  • Byte 0: PDU Type (1 byte)
  • Byte 1: Reserved (0x00)
  • Bytes 2-5: PDU Length (Big Endian, 4 bytes)

Thread Safety: All public methods are thread-safe. The underlying network operations are serialized through network_system's I/O context.

Definition at line 172 of file dicom_session.h.

Member Typedef Documentation

◆ clock

◆ duration

◆ session_variant

Initial value:
std::variant<
std::shared_ptr<network_system::session::messaging_session>,
std::shared_ptr<network_system::session::secure_session>,
std::shared_ptr<kcenon::network::interfaces::i_session>>

Variant for holding session types (legacy + public interface)

Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/integration/dicom_session.h.

Definition at line 376 of file dicom_session.h.

◆ time_point

Constructor & Destructor Documentation

◆ dicom_session() [1/5]

kcenon::pacs::integration::dicom_session::dicom_session ( std::shared_ptr< network_system::session::messaging_session > session)
explicit

Construct a DICOM session wrapping a messaging_session.

Parameters
sessionThe network_system session to wrap
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/integration/dicom_session.h.

Definition at line 26 of file dicom_session.cpp.

28 : session_(std::move(session)) {
29 if (auto* s = std::get_if<
30 std::shared_ptr<network_system::session::messaging_session>>(&session_)) {
31 // Set up callbacks for the underlying session
32 (*s)->set_receive_callback(
33 [this](const std::vector<uint8_t>& data) {
34 on_data_received(data);
35 });
36
37 (*s)->set_error_callback(
38 [this](std::error_code ec) {
39 on_error(ec);
40 });
41 }
42}
void on_data_received(const std::vector< uint8_t > &data)
Handle incoming data from network.
session_variant session_
Underlying network session.
void on_error(std::error_code ec)
Handle connection errors.

References on_data_received(), on_error(), and session_.

Here is the call graph for this function:

◆ dicom_session() [2/5]

kcenon::pacs::integration::dicom_session::dicom_session ( std::shared_ptr< network_system::session::secure_session > session)
explicit

Construct a DICOM session wrapping a secure_session.

Parameters
sessionThe secure network_system session to wrap

Definition at line 44 of file dicom_session.cpp.

46 : session_(std::move(session)) {
47 if (auto* s = std::get_if<
48 std::shared_ptr<network_system::session::secure_session>>(&session_)) {
49 // Set up callbacks for the underlying secure session
50 (*s)->set_receive_callback(
51 [this](const std::vector<uint8_t>& data) {
52 on_data_received(data);
53 });
54
55 (*s)->set_error_callback(
56 [this](std::error_code ec) {
57 on_error(ec);
58 });
59 }
60}

References on_data_received(), on_error(), and session_.

Here is the call graph for this function:

◆ dicom_session() [3/5]

kcenon::pacs::integration::dicom_session::dicom_session ( std::shared_ptr< kcenon::network::interfaces::i_session > session)
explicit

Construct a DICOM session wrapping an i_session interface.

When using i_session, data must be fed externally via feed_data() since i_session does not support session-level callbacks.

Parameters
sessionThe i_session interface to wrap

Definition at line 62 of file dicom_session.cpp.

64 : session_(std::move(session)) {
65 // i_session does not support session-level callbacks.
66 // Data must be fed externally via feed_data() / feed_error().
67}

◆ ~dicom_session()

kcenon::pacs::integration::dicom_session::~dicom_session ( )

Destructor (closes session if open)

Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/integration/dicom_session.h.

Definition at line 69 of file dicom_session.cpp.

69 {
70 close();
71}

References close().

Here is the call graph for this function:

◆ dicom_session() [4/5]

kcenon::pacs::integration::dicom_session::dicom_session ( const dicom_session & )
delete

◆ dicom_session() [5/5]

kcenon::pacs::integration::dicom_session::dicom_session ( dicom_session && other)
noexcept

Definition at line 73 of file dicom_session.cpp.

74 : session_(std::move(other.session_))
75 , receive_buffer_(std::move(other.receive_buffer_))
76 , received_pdus_(std::move(other.received_pdus_))
77 , pdu_callback_(std::move(other.pdu_callback_))
78 , error_callback_(std::move(other.error_callback_))
79 , last_error_(other.last_error_)
80 , closed_(other.closed_) {
81 other.closed_ = true;
82}
std::function< void(const pdu_data &)> pdu_callback_
PDU callback for async reception.
std::vector< uint8_t > receive_buffer_
Receive buffer for PDU framing.
std::error_code last_error_
Last error code.
std::function< void(std::error_code)> error_callback_
Error callback.
std::vector< pdu_data > received_pdus_
Queue of received complete PDUs.

Member Function Documentation

◆ clear_pdu_callback()

void kcenon::pacs::integration::dicom_session::clear_pdu_callback ( )

Clear the PDU callback.

Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/integration/dicom_session.h.

Definition at line 192 of file dicom_session.cpp.

192 {
193 std::lock_guard<std::mutex> lock(mutex_);
194 pdu_callback_ = nullptr;
195}
std::mutex mutex_
Mutex for thread safety.

References mutex_, and pdu_callback_.

◆ close()

void kcenon::pacs::integration::dicom_session::close ( )

Close the session.

Closes the underlying network connection. Any pending send or receive operations will be cancelled.

Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/integration/dicom_session.h.

Definition at line 201 of file dicom_session.cpp.

201 {
202 std::lock_guard<std::mutex> lock(mutex_);
203
204 if (closed_) {
205 return;
206 }
207
208 closed_ = true;
209
210 // Stop the underlying session
211 std::visit([](auto&& session) {
212 if (session) {
213 if constexpr (std::is_same_v<std::decay_t<decltype(session)>,
214 std::shared_ptr<kcenon::network::interfaces::i_session>>) {
215 session->close();
216 } else {
217 session->stop_session();
218 }
219 }
220 }, session_);
221
222 // Notify waiting receivers
223 receive_cv_.notify_all();
224}
std::condition_variable receive_cv_
Condition variable for synchronous receive.

References closed_, mutex_, receive_cv_, and session_.

Referenced by ~dicom_session().

Here is the caller graph for this function:

◆ encode_pdu_header()

std::vector< uint8_t > kcenon::pacs::integration::dicom_session::encode_pdu_header ( network::pdu_type type,
uint32_t length )
staticprivate

Encode PDU header.

Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/integration/dicom_session.h.

Definition at line 389 of file dicom_session.cpp.

389 {
390 std::vector<uint8_t> header(pdu_header_size);
391
392 // Byte 0: PDU Type
393 header[0] = static_cast<uint8_t>(type);
394
395 // Byte 1: Reserved
396 header[1] = 0x00;
397
398 // Bytes 2-5: Length (Big Endian)
399 header[2] = static_cast<uint8_t>((length >> 24) & 0xFF);
400 header[3] = static_cast<uint8_t>((length >> 16) & 0xFF);
401 header[4] = static_cast<uint8_t>((length >> 8) & 0xFF);
402 header[5] = static_cast<uint8_t>(length & 0xFF);
403
404 return header;
405}
static constexpr size_t pdu_header_size
PDU header size per DICOM PS3.8.
@ length
Linear distance measurement.

References pdu_header_size.

Referenced by send_pdu().

Here is the caller graph for this function:

◆ feed_data()

void kcenon::pacs::integration::dicom_session::feed_data ( const std::vector< uint8_t > & data)

Feed received data from external source.

Used when the session is backed by i_session, which does not support session-level callbacks. The server forwards data here.

Parameters
dataThe received data bytes
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/integration/dicom_session.h.

Definition at line 279 of file dicom_session.cpp.

279 {
280 on_data_received(data);
281}

References on_data_received().

Here is the call graph for this function:

◆ feed_error()

void kcenon::pacs::integration::dicom_session::feed_error ( std::error_code ec)

Feed an error from external source.

Used when the session is backed by i_session.

Parameters
ecThe error code
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/integration/dicom_session.h.

Definition at line 283 of file dicom_session.cpp.

283 {
284 on_error(ec);
285}

References on_error().

Here is the call graph for this function:

◆ is_open()

bool kcenon::pacs::integration::dicom_session::is_open ( ) const
nodiscardnoexcept

Check if the session is open.

Returns
true if the connection is active
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/integration/dicom_session.h.

Definition at line 226 of file dicom_session.cpp.

226 {
227 std::lock_guard<std::mutex> lock(mutex_);
228
229 if (closed_) {
230 return false;
231 }
232
233 return std::visit([](auto&& session) -> bool {
234 if (session) {
235 if constexpr (std::is_same_v<std::decay_t<decltype(session)>,
236 std::shared_ptr<kcenon::network::interfaces::i_session>>) {
237 return session->is_connected();
238 } else {
239 return !session->is_stopped();
240 }
241 }
242 return false;
243 }, session_);
244}

References closed_, mutex_, and session_.

◆ is_secure()

bool kcenon::pacs::integration::dicom_session::is_secure ( ) const
nodiscardnoexcept

Check if this is a secure (TLS) session.

Returns
true if using TLS
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/integration/dicom_session.h.

Definition at line 270 of file dicom_session.cpp.

270 {
271 return std::holds_alternative<
272 std::shared_ptr<network_system::session::secure_session>>(session_);
273}

References session_.

◆ last_error()

std::error_code kcenon::pacs::integration::dicom_session::last_error ( ) const
nodiscardnoexcept

Get the last error code.

Returns
Last error or success code
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/integration/dicom_session.h.

Definition at line 297 of file dicom_session.cpp.

297 {
298 std::lock_guard<std::mutex> lock(mutex_);
299 return last_error_;
300}

References last_error_, and mutex_.

◆ on_data_received()

void kcenon::pacs::integration::dicom_session::on_data_received ( const std::vector< uint8_t > & data)
private

Handle incoming data from network.

Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/integration/dicom_session.h.

Definition at line 306 of file dicom_session.cpp.

306 {
307 std::lock_guard<std::mutex> lock(mutex_);
308
309 if (closed_) {
310 return;
311 }
312
313 // Append to receive buffer
314 receive_buffer_.insert(receive_buffer_.end(), data.begin(), data.end());
315
316 // Process complete PDUs
318}
void process_buffer()
Process buffered data for complete PDUs.

References closed_, mutex_, process_buffer(), and receive_buffer_.

Referenced by dicom_session(), dicom_session(), and feed_data().

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

◆ on_error()

void kcenon::pacs::integration::dicom_session::on_error ( std::error_code ec)
private

Handle connection errors.

Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/integration/dicom_session.h.

Definition at line 320 of file dicom_session.cpp.

320 {
321 std::function<void(std::error_code)> callback;
322
323 {
324 std::lock_guard<std::mutex> lock(mutex_);
325 last_error_ = ec;
326 callback = error_callback_;
327 }
328
329 if (callback) {
330 callback(ec);
331 }
332
333 // Notify waiting receivers
334 receive_cv_.notify_all();
335}

References error_callback_, last_error_, mutex_, and receive_cv_.

Referenced by dicom_session(), dicom_session(), and feed_error().

Here is the caller graph for this function:

◆ operator=() [1/2]

dicom_session & kcenon::pacs::integration::dicom_session::operator= ( const dicom_session & )
delete

◆ operator=() [2/2]

dicom_session & kcenon::pacs::integration::dicom_session::operator= ( dicom_session && other)
noexcept

Definition at line 84 of file dicom_session.cpp.

84 {
85 if (this != &other) {
86 close();
87
88 std::lock_guard<std::mutex> lock(mutex_);
89 session_ = std::move(other.session_);
90 receive_buffer_ = std::move(other.receive_buffer_);
91 received_pdus_ = std::move(other.received_pdus_);
92 pdu_callback_ = std::move(other.pdu_callback_);
93 error_callback_ = std::move(other.error_callback_);
94 last_error_ = other.last_error_;
95 closed_ = other.closed_;
96
97 other.closed_ = true;
98 }
99 return *this;
100}

◆ parse_pdu_header()

bool kcenon::pacs::integration::dicom_session::parse_pdu_header ( const std::vector< uint8_t > & buffer,
network::pdu_type & type,
uint32_t & length )
staticprivate

Parse PDU header from buffer.

Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/integration/dicom_session.h.

Definition at line 407 of file dicom_session.cpp.

409 {
410 if (buffer.size() < pdu_header_size) {
411 return false;
412 }
413
414 // Byte 0: PDU Type
415 uint8_t type_byte = buffer[0];
416
417 // Validate PDU type
418 if (type_byte < 0x01 || type_byte > 0x07) {
419 return false;
420 }
421
422 type = static_cast<network::pdu_type>(type_byte);
423
424 // Byte 1: Reserved (should be 0, but we don't validate)
425
426 // Bytes 2-5: Length (Big Endian)
427 length = (static_cast<uint32_t>(buffer[2]) << 24) |
428 (static_cast<uint32_t>(buffer[3]) << 16) |
429 (static_cast<uint32_t>(buffer[4]) << 8) |
430 static_cast<uint32_t>(buffer[5]);
431
432 return true;
433}
pdu_type
PDU (Protocol Data Unit) types as defined in DICOM PS3.8.
Definition pdu_types.h:25

References pdu_header_size.

Referenced by process_buffer().

Here is the caller graph for this function:

◆ process_buffer()

void kcenon::pacs::integration::dicom_session::process_buffer ( )
private

Process buffered data for complete PDUs.

Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/integration/dicom_session.h.

Definition at line 337 of file dicom_session.cpp.

337 {
338 // Process all complete PDUs in the buffer
339 while (receive_buffer_.size() >= pdu_header_size) {
340 // Parse header
342 uint32_t length;
343
344 if (!parse_pdu_header(receive_buffer_, type, length)) {
345 // Invalid header - this is a protocol error
346 last_error_ = std::make_error_code(std::errc::protocol_error);
347 receive_cv_.notify_all();
348 return;
349 }
350
351 // Sanity check on length
352 if (length > max_pdu_payload_size) {
353 last_error_ = std::make_error_code(std::errc::message_size);
354 receive_cv_.notify_all();
355 return;
356 }
357
358 // Check if we have the complete PDU
359 size_t total_size = pdu_header_size + length;
360 if (receive_buffer_.size() < total_size) {
361 // Need more data
362 return;
363 }
364
365 // Extract payload (skip 6-byte header)
366 std::vector<uint8_t> payload(
368 receive_buffer_.begin() + total_size);
369
370 // Remove processed data from buffer
371 receive_buffer_.erase(
372 receive_buffer_.begin(),
373 receive_buffer_.begin() + total_size);
374
375 // Create PDU data
376 pdu_data pdu(type, std::move(payload));
377
378 // Deliver through callback or queue
379 if (pdu_callback_) {
380 pdu_callback_(pdu);
381 } else {
382 received_pdus_.push_back(std::move(pdu));
383 receive_cv_.notify_one();
384 }
385 }
386}
static bool parse_pdu_header(const std::vector< uint8_t > &buffer, network::pdu_type &type, uint32_t &length)
Parse PDU header from buffer.
static constexpr size_t max_pdu_payload_size
Maximum PDU payload size (sanity check)
std::variant< associate_rq, associate_ac, associate_rj, p_data_tf_pdu, release_rq_pdu, release_rp_pdu, abort_pdu > pdu
Variant type that can hold any PDU.
Definition pdu_decoder.h:62

References last_error_, max_pdu_payload_size, parse_pdu_header(), pdu_callback_, pdu_header_size, receive_buffer_, receive_cv_, and received_pdus_.

Referenced by on_data_received().

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

◆ receive_pdu()

Result< pdu_data > kcenon::pacs::integration::dicom_session::receive_pdu ( duration timeout = default_timeout)
nodiscard

Receive a complete DICOM PDU.

Waits for and receives a complete PDU, handling the PDU framing protocol (reading header, then payload based on length).

Parameters
timeoutMaximum time to wait for PDU
Returns
Result containing received PDU data or error
Note
This method blocks until a complete PDU is received or timeout
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/integration/dicom_session.h.

Definition at line 154 of file dicom_session.cpp.

154 {
155 std::unique_lock<std::mutex> lock(mutex_);
156
157 if (closed_) {
158 return Result<pdu_data>(error_info("Session is closed"));
159 }
160
161 // Wait for a complete PDU with timeout
162 auto deadline = clock::now() + timeout;
163
164 while (received_pdus_.empty()) {
165 if (closed_) {
166 return Result<pdu_data>(error_info("Session closed while waiting"));
167 }
168
169 auto status = receive_cv_.wait_until(lock, deadline);
170 if (status == std::cv_status::timeout) {
171 return Result<pdu_data>(error_info("Receive timeout"));
172 }
173
174 if (last_error_) {
175 return Result<pdu_data>(error_info("Receive error: " + last_error_.message()));
176 }
177 }
178
179 // Get the first PDU from the queue
180 pdu_data pdu = std::move(received_pdus_.front());
181 received_pdus_.erase(received_pdus_.begin());
182
183 return Result<pdu_data>(std::move(pdu));
184}
constexpr dicom_tag status
Status.
constexpr int timeout
Lock timeout exceeded.
kcenon::common::Result< T > Result
Result type alias for PACS operations.
Definition result.h:30
kcenon::common::error_info error_info
Error information type.
Definition result.h:40

References closed_, last_error_, mutex_, receive_cv_, and received_pdus_.

◆ remote_address()

std::string kcenon::pacs::integration::dicom_session::remote_address ( ) const
nodiscard

Get the remote peer address.

Returns
Remote address as "host:port" string
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/integration/dicom_session.h.

Definition at line 246 of file dicom_session.cpp.

246 {
247 std::lock_guard<std::mutex> lock(mutex_);
248
249 // For now, return a placeholder
250 // Real implementation would query the underlying socket
251 return "unknown";
252}

References mutex_.

◆ send_data()

void kcenon::pacs::integration::dicom_session::send_data ( std::vector< uint8_t > && data)
private

Send data through the underlying session.

Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/integration/dicom_session.h.

Definition at line 435 of file dicom_session.cpp.

435 {
436 std::visit([&data](auto&& session) {
437 if (session) {
438 if constexpr (std::is_same_v<std::decay_t<decltype(session)>,
439 std::shared_ptr<kcenon::network::interfaces::i_session>>) {
440 (void)session->send(std::move(data));
441 } else {
442 session->send_packet(std::move(data));
443 }
444 }
445 }, session_);
446}

References session_.

Referenced by send_pdu(), and send_raw().

Here is the caller graph for this function:

◆ send_pdu()

Result< std::monostate > kcenon::pacs::integration::dicom_session::send_pdu ( network::pdu_type type,
const std::vector< uint8_t > & payload )
nodiscard

Send a complete DICOM PDU.

Constructs a properly framed PDU with header and sends it over the network connection.

Parameters
typeThe PDU type
payloadThe PDU payload (without header)
Returns
Result indicating success or error
Note
The payload should not include the 6-byte PDU header; the header is constructed automatically.
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/integration/dicom_session.h.

Definition at line 107 of file dicom_session.cpp.

108 {
109 std::lock_guard<std::mutex> lock(mutex_);
110
111 if (closed_) {
112 return Result<std::monostate>(error_info("Session is closed"));
113 }
114
115 if (payload.size() > max_pdu_payload_size) {
116 return Result<std::monostate>(error_info("PDU payload exceeds maximum size"));
117 }
118
119 // Encode PDU header
120 auto header = encode_pdu_header(type, static_cast<uint32_t>(payload.size()));
121
122 // Combine header and payload
123 std::vector<uint8_t> pdu_data;
124 pdu_data.reserve(header.size() + payload.size());
125 pdu_data.insert(pdu_data.end(), header.begin(), header.end());
126 pdu_data.insert(pdu_data.end(), payload.begin(), payload.end());
127
128 // Send data
129 send_data(std::move(pdu_data));
130
131 return Result<std::monostate>(std::monostate{});
132}
static std::vector< uint8_t > encode_pdu_header(network::pdu_type type, uint32_t length)
Encode PDU header.
void send_data(std::vector< uint8_t > &&data)
Send data through the underlying session.

References closed_, encode_pdu_header(), max_pdu_payload_size, mutex_, and send_data().

Here is the call graph for this function:

◆ send_raw()

Result< std::monostate > kcenon::pacs::integration::dicom_session::send_raw ( const std::vector< uint8_t > & data)
nodiscard

Send raw PDU data (with header already included)

Sends pre-encoded PDU data directly without modification. Use this when the PDU has already been fully encoded.

Parameters
dataComplete PDU data including header
Returns
Result indicating success or error
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/integration/dicom_session.h.

Definition at line 135 of file dicom_session.cpp.

135 {
136 std::lock_guard<std::mutex> lock(mutex_);
137
138 if (closed_) {
139 return Result<std::monostate>(error_info("Session is closed"));
140 }
141
142 if (data.size() < pdu_header_size) {
143 return Result<std::monostate>(error_info("Raw PDU data too small"));
144 }
145
146 // Send data as-is
147 std::vector<uint8_t> copy = data;
148 send_data(std::move(copy));
149
150 return Result<std::monostate>(std::monostate{});
151}

References closed_, mutex_, pdu_header_size, and send_data().

Here is the call graph for this function:

◆ session_id()

std::string kcenon::pacs::integration::dicom_session::session_id ( ) const
nodiscard

Get session identifier.

Returns
Unique session identifier string
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/integration/dicom_session.h.

Definition at line 254 of file dicom_session.cpp.

254 {
255 std::lock_guard<std::mutex> lock(mutex_);
256
257 return std::visit([](auto&& session) -> std::string {
258 if (session) {
259 if constexpr (std::is_same_v<std::decay_t<decltype(session)>,
260 std::shared_ptr<kcenon::network::interfaces::i_session>>) {
261 return std::string(session->id());
262 } else {
263 return session->server_id();
264 }
265 }
266 return "invalid";
267 }, session_);
268}

References mutex_, and session_.

◆ set_error_callback()

void kcenon::pacs::integration::dicom_session::set_error_callback ( std::function< void(std::error_code)> callback)

Set callback for error events.

Parameters
callbackFunction called on errors
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/integration/dicom_session.h.

Definition at line 291 of file dicom_session.cpp.

292 {
293 std::lock_guard<std::mutex> lock(mutex_);
294 error_callback_ = std::move(callback);
295}

References error_callback_, and mutex_.

◆ set_pdu_callback()

void kcenon::pacs::integration::dicom_session::set_pdu_callback ( std::function< void(const pdu_data &)> callback)

Set callback for asynchronous PDU reception.

When set, incoming PDUs are delivered through this callback instead of requiring explicit receive_pdu() calls.

Parameters
callbackFunction called when PDU is received
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/integration/dicom_session.h.

Definition at line 186 of file dicom_session.cpp.

187 {
188 std::lock_guard<std::mutex> lock(mutex_);
189 pdu_callback_ = std::move(callback);
190}

References mutex_, and pdu_callback_.

Member Data Documentation

◆ closed_

bool kcenon::pacs::integration::dicom_session::closed_ = false
private

◆ default_timeout

duration kcenon::pacs::integration::dicom_session::default_timeout {30000}
staticconstexpr

Default receive timeout.

Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/integration/dicom_session.h.

Definition at line 183 of file dicom_session.h.

183{30000}; // 30 seconds

◆ error_callback_

std::function<void(std::error_code)> kcenon::pacs::integration::dicom_session::error_callback_
private

◆ last_error_

std::error_code kcenon::pacs::integration::dicom_session::last_error_
private

◆ max_pdu_payload_size

size_t kcenon::pacs::integration::dicom_session::max_pdu_payload_size = 64 * 1024 * 1024
staticconstexpr

Maximum PDU payload size (sanity check)

Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/integration/dicom_session.h.

Definition at line 189 of file dicom_session.h.

Referenced by process_buffer(), and send_pdu().

◆ mutex_

◆ pdu_callback_

std::function<void(const pdu_data&)> kcenon::pacs::integration::dicom_session::pdu_callback_
private

◆ pdu_header_size

size_t kcenon::pacs::integration::dicom_session::pdu_header_size = 6
staticconstexpr

◆ receive_buffer_

std::vector<uint8_t> kcenon::pacs::integration::dicom_session::receive_buffer_
private

Receive buffer for PDU framing.

Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/integration/dicom_session.h.

Definition at line 415 of file dicom_session.h.

Referenced by on_data_received(), and process_buffer().

◆ receive_cv_

std::condition_variable kcenon::pacs::integration::dicom_session::receive_cv_
private

Condition variable for synchronous receive.

Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/integration/dicom_session.h.

Definition at line 436 of file dicom_session.h.

Referenced by close(), on_error(), process_buffer(), and receive_pdu().

◆ received_pdus_

std::vector<pdu_data> kcenon::pacs::integration::dicom_session::received_pdus_
private

Queue of received complete PDUs.

Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/integration/dicom_session.h.

Definition at line 418 of file dicom_session.h.

Referenced by process_buffer(), and receive_pdu().

◆ session_

session_variant kcenon::pacs::integration::dicom_session::session_
private

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