ACSE classes

Introduction

This chapter describes the ACSE related classes and methods. ACSE stands for (Association Control Service Element).

The following classes are described in this chapter:

C++ class

Objective-C/Swift class

Description

imebra::PresentationContext

ImebraPresentationContext

Stores an abstract syntax and the list of allowed transfer syntaxes

imebra::PresentationContexts

ImebraPresentationContexts

Stores a list of Presentation contexts

imebra::AssociationMessage

ImebraAssociationMessage

Stores a message sent through an association

imebra::MutableAssociationMessage

ImebraMutableAssociationMessage

A mutable message (used to create a message)

imebra::AssociationBase

ImebraAssociationBase

Base class for the associations

imebra::AssociationSCU

ImebraAssociationSCU

An SCU association (Service user)

imebra::AssociationSCP

ImebraAssociationSCP

An SCP association (service provider)

ACSE related classes

Class diagram of the ACSE related classes

The ACSE classes (Association Control Service Element) take care of negotiating a DICOM association and transporting DICOM messages between DICOM entities connected through the association.

The client (Service User or SCU) must use AssociationSCU to connect, while the server (Service Provider or SCP) must use AssociationSCP to connect with a client.

The association usually transmits and receive data via a TCPStream, therefore the sequence of operations needed to connect an SCU to a remote SCP are as follow:

  • Create a TCPStream which connects to the remote SCP

  • Allocate a StreamReader and a StreamWriter connected to the TCPStream input and output streams (use imebra::DataSet::getStreamInput and imebra::DataSet::getStreamOutput)

  • Allocate a PresentationContexts and fill it with PresentationContext objects that represent the requested presentation contexts (abstract syntaxes and supported transfer syntaxes)

  • Allocate a AssociationSCU which in the constructor will perform the association negotiation through the StreamReader and StreamWriter

Sequence diagram that shows how to instantiate an SCU

Sequence diagram that shows how to instantiate an SCU

Once the association has been allocated, the client should use a DimseService in order to send and receive DICOM commands and responses.

Presentation context classes

PresentationContext

C++

class PresentationContext

A presentation context defines which transfer syntaxes are supported for a specific abstract syntax.

Add the PresentationContext to the PresentationContexts list to build a list of PresentationContext objects that can be managed by the client application.

Public Functions

PresentationContext(const std::string &abstractSyntax)

Constructor.

The SCU will act as SCU and the SCP will act as SCP when using this presentation context. To specify the roles of the SCU and the SCP use the other constructor which includes the roles parameters.

Parameters
  • abstractSyntax: the abstract syntax described by this presentation context

PresentationContext(const std::string &abstractSyntax, bool bSCURole, bool bSCPRole)

Constructor.

Parameters
  • abstractSyntax: the abstract syntax described by this presentation context

  • bSCURole: if true then the SCU will act as an SCU. The SCU and SCP can be both an SCU and an SCP for the same abstract syntax

  • bSCPRole: if true then the SCU will act as an SCP The SCU and SCP can be both an SCU and an SCP for the same abstract syntax

PresentationContext(const PresentationContext &source)

Copy constructor.

Parameters
  • source: source presentation context

void addTransferSyntax(const std::string &transferSyntax)

Add a supported transfer syntax to the presentation context.

Parameters
  • transferSyntax: the transfer syntax to add

Objective-C/Swift

class ImebraPresentationContext : public NSObject

A presentation context defines which transfer syntaxes are supported for a specific abstract syntax.

Public Functions

id ImebraPresentationContext::initWithAbstractSyntax:(NSString * abstractSyntax)

Initializer.

The SCU will act as SCU and the SCP will act as SCP when using this presentation context. To specify the roles of the SCU and the SCP use the initializer which includes the roles parameters.

Parameters
  • abstractSyntax: the abstract syntax described by this presentation context

id ImebraPresentationContext::initWithAbstractSyntax:scuRole:scpRole:(NSString * abstractSyntax, BOOL bSCURole, BOOL bSCPRole)

Initializer that specifies the SCU/SCP roles.

Parameters
  • abstractSyntax: the abstract syntax described by this presentation context

  • bSCURole: if true then the SCU will act as an SCU. The SCU and SCP can be both an SCU and an SCP for the same abstract syntax

  • bSCPRole: if true then the SCU will act as an SCP The SCU and SCP can be both an SCU and an SCP for the same abstract syntax

void ImebraPresentationContext::addTransferSyntax:(NSString * transferSyntax)

Add a supported transfer syntax to the presentation context.

Parameters
  • transferSyntax: the transfer syntax to add

PresentationContexts

C++

class PresentationContexts

A collection of PresentationContext objects.

Public Functions

PresentationContexts()

Default constructor.

PresentationContexts(const PresentationContexts &source)

Copy constructor.

Parameters
  • source: source presentation contexts

void addPresentationContext(const PresentationContext &presentationContext)

Add a presentation context to the collection.

Parameters
  • presentationContext: the presentation context to add to the collection

Objective-C/Swift

class ImebraPresentationContexts : public NSObject

A collection of presentation contexts.

Public Functions

id init()

Initializer.

void ImebraPresentationContexts::addPresentationContext:(ImebraPresentationContext * pPresentationContext)

Add a presentation context to the collection.

Parameters
  • pPresentationContext: the presentation context to add to the collection

Association classes

AssociationBase

C++

class AssociationBase

The AssociationBase class.

Subclassed by imebra::AssociationSCP, imebra::AssociationSCU

Public Functions

virtual ~AssociationBase()

Destructor.

const AssociationMessage getCommand()

Read a command dataset and its payload (if any).

Throws StreamClosedError if the association has been released or aborted.

Return

an AssociationDataSet containing a command and its payload.

const AssociationMessage getResponse(std::uint16_t messageId)

Read a response dataset and its payload (if any).

Throws StreamClosedError if the association has been released or aborted.

Return

an AssociationDataSet containing a response and its payload.

void sendMessage(const AssociationMessage &messageDataSet)

Send a DICOM message to the connected peer.

Parameters
  • messageDataSet: the DICOM message to send

void release()

Releases the association.

The method blocks until the other party acknowledges the release command or until the ACSE timout expires.

void abort()

Aborts the association.

The association will be aborted as soon as possible. The other party will not acknowledge the abort command.

std::string getThisAET() const

Returns our AET.

Return

our AET

std::string getOtherAET() const

Returns the other party’s AET.

Return

the connected peer’s AET

std::string getTransferSyntax(const std::string &abstractSyntax) const

Returns the transfer syntax negotiated for a specific abstract syntax.

This method has been deprecated: use getTransferSyntaxes() instead.

Throws:

Return

the negotiated transfer syntax for the specified abstract syntax

Parameters
  • abstractSyntax: the abstract syntax for which the transfer syntax is requested

std::vector<std::string> getTransferSyntaxes(const std::string &abstractSyntax) const

Returns the transfer syntaxes negotiated for a specific abstract syntax.

Throws:

Return

the negotiated transfer syntaxes for the specified abstract syntax

Parameters
  • abstractSyntax: the abstract syntax for which the transfer syntax is requested

Objective-C/Swift

class ImebraAssociationBase : public NSObject

The association base class.

Subclassed by ImebraAssociationSCP, ImebraAssociationSCU

Public Functions

ImebraAssociationMessage* ImebraAssociationBase::getCommand:(NSError ** pError)

Read a command dataset and its payload (if any).

Return

an ImebraAssociationMessage containing a command and its payload.

Parameters
  • pError: set to ImebraStreamClosedError if the association has been released or aborted.

ImebraAssociationMessage* ImebraAssociationBase::getResponse:error:(unsigned int messageId, NSError ** pError)

Read a response dataset and its payload (if any).

Return

an AssociationDataSet containing a response and its payload.

Parameters
  • messageId: the message ID for which the response is expected

  • pError: set to ImebraStreamClosedError if the association has been released or aborted.

void ImebraAssociationBase::sendMessage:error:(ImebraAssociationMessage * pMessage, (swift_error(nonnull_error)) __attribute__)

Send a DICOM message to the connected peer.

Parameters
  • pMessage: the DICOM message to send

  • pError: set to a subclass of NSError in case of error

void ImebraAssociationBase::release:((swift_error(nonnull_error)) __attribute__)

Releases the association.

The method blocks until the other party acknowledges the release command or until the ACSE timout expires.

Parameters
  • pError: set to a subclass of NSError in case of error

void ImebraAssociationBase::abort:((swift_error(nonnull_error)) __attribute__)

Aborts the association.

The association will be aborted as soon as possible. The other party will not acknowledge the abort command.

Parameters
  • pError: set to a subclass of NSError in case of error

NSString* ImebraAssociationBase::getTransferSyntax:error:(NSString * abstractSyntax, NSError ** pError)

Returns the transfer syntax negotiated for a specific abstract syntax.

Return

the negotiated transfer syntax for the specified abstract syntax

Parameters
  • abstractSyntax: the abstract syntax for which the transfer syntax is requested

  • pError: set to ImebraAcseNoTransferSyntaxError if no transfer syntax is available or ImebraAcsePresentationContextNotRequestedError if the abstract syntax was not negotiated at all

Property

property ImebraAssociationBase::thisAET

Returns our AET.

property ImebraAssociationBase::otherAET

Returns the other party’s AET.

AssociationSCU

C++

class AssociationSCU : public imebra::AssociationBase

Represents the SCU part of an association.

The constructor tries to create an association with an SCP via the StreamReader and the StreamWriter passed as parameter; when communicating through the TCPStream then the same object is used as reader and writer.

Public Functions

AssociationSCU(const std::string &thisAET, const std::string &otherAET, std::uint32_t invokedOperations, std::uint32_t performedOperations, const PresentationContexts &presentationContexts, StreamReader &pInput, StreamWriter &pOutput, std::uint32_t dimseTimeoutSeconds)

Initiates an association request.

Blocks until the association has been negotiated successfully or an error occurs (an exception is thrown).

The constructor blocks until an association has been successfully negotiated or until an error happens (an exception is thrown).

Parameters
  • thisAET: the AET of the SCU

  • otherAET: the AET of the SCP with wich the association is negotiated

  • invokedOperations: maximum number of parallel operations we intend to invoke when acting as a SCU

  • performedOperations: maximum number of parallel operations we can perform when acting as a SCP

  • presentationContexts: list of proposed presentation contexts

  • pInput: input stream from which the SCP receives data. When using a TCPStream the same object can act as both input and output

  • pOutput: output stream into which the SCP writes data. When using a TCPStream the same object can act as both input and output

  • dimseTimeoutSeconds: DIMSE timeout, in seconds. 0 means infinite

Throws:

AssociationSCU(const AssociationSCU &source)

Copy constructor.

Parameters
  • source: source SCU association

Objective-C/Swift

class ImebraAssociationSCU : public ImebraAssociationBase

Represents the SCU part of an association.

The initializer tries to create an association with an SCP via the ImebraStreamReader and the ImebraStreamWriter passed as parameter; when communicating through the ImebraTCPStream then the same object is used as reader and writer.

Public Functions

id ImebraAssociationSCU::initWithThisAET:otherAET:maxInvokedOperations:maxPerformedOperations:presentationContexts:reader:writer:dimseTimeoutSeconds:error:(NSString * thisAET, NSString * otherAET, unsigned int invokedOperations, unsigned int performedOperations, ImebraPresentationContexts * presentationContexts, ImebraStreamReader * pInput, ImebraStreamWriter * pOutput, unsigned int dimseTimeoutSeconds, NSError ** pError)

Initiates an association request.

Blocks until the association has been negotiated successfully or an error occurs (pError is set).

Parameters
  • thisAET: the AET of the SCU

  • otherAET: the AET of the SCP with wich the association is negotiated

  • invokedOperations: maximum number of parallel operations we intend to invoke when acting as a SCU

  • performedOperations: maximum number of parallel operations we can perform when acting as a SCP

  • presentationContexts: list of proposed presentation contexts

  • pInput: input stream from which the SCP receives data. When using a TCPStream the same object can act as both input and output

  • pOutput: output stream into which the SCP writes data. When using a TCPStream the same object can act as both input and output

  • dimseTimeoutSeconds: DIMSE timeout, in seconds. 0 means infinite

  • pError: may be set to one of the following errors:

    • ImebraCorruptedAcseMessageError

    • ImebraAcseSCUApplicationContextNameNotSupportedError

    • ImebraAcseSCUCalledAETNotRecognizedError

    • ImebraCodecWrongFormatError

    • ImebraDicomCodecDepthLimitReachedError

AssociationSCP

C++

class AssociationSCP : public imebra::AssociationBase

Represents the SCP part of an association.

The constructor waits for an incoming DICOM association request (a-request-rq) and then returns once the association has been established, or throws CorruptedAcseMessageError if the SCU sends a wrong message type.

AssociationSCP lifecycle

Only create an AssociationSCP object AFTER the StreamReader and StreamWriter parameters have been successfully connected to their peer, then keep it alive and poll the data via readCommand() and readPayload() until a StreamClosedError or a CorruptedAcseMessageError are thrown.

StreamClosedError means that the association has been released or aborted.

If you call the abort() method on the AssociationSCP you should still wait for the StreamClosedError exception to be thrown by readCommand() or readPayload().

Public Functions

AssociationSCP(const std::string &thisAET, std::uint32_t invokedOperations, std::uint32_t performedOperations, const PresentationContexts &presentationContexts, StreamReader &pInput, StreamWriter &pOutput, std::uint32_t dimseTimeoutSeconds, std::uint32_t artimTimeoutSeconds)

Listens for an association request.

Blocks until the association has been negotiated successfully or an error occurs (an exception is thrown).

The constructor blocks until an association has been successfully negotiated or until an error happens (an exception is thrown).

Parameters
  • thisAET: the AET of the SCP. If empty then the SCP will accept associations for any called AET, otherwise it will reject the association when the called AET does not match this one

  • invokedOperations: maximum number of parallel operations we intend to invoke when acting as a SCU

  • performedOperations: maximum number of parallel operations we can perform when acting as a SCP

  • presentationContexts: list of accepted presentation contexts. If several transfer syntaxes are associated to an abstract syntax in a single presentation context then the SCP will accept each transfer syntax even when the SCU spreads them on different presentation contexts (for the same abstract syntax)

  • pInput: input stream from which the SCP receives data. When using a TCPStream the same object can act as both input and output

  • pOutput: output stream into which the SCP writes data. When using a TCPStream the same object can act as both input and output

  • dimseTimeoutSeconds: DIMSE timeout, in seconds. 0 means infinite

  • artimTimeoutSeconds: ARTIM timeout, in seconds. Amount of time that is allowed to pass before an association request arrives

Throws:

AssociationSCP(const AssociationSCP &source)

Copy constructor.

Parameters
  • source: source SCP association

Objective-C/Swift

class ImebraAssociationSCP : public ImebraAssociationBase

Represents the SCP part of an association.

The initializer waits for an incoming DICOM association request (a-request-rq) and then returns once the association has been established, or set pError to ImebraCorruptedAcseMessageError if the SCU sends a wrong message type.

ImebraAssociationSCP lifecycle

Only create an ImebraAssociationSCP object AFTER the ImebraStreamReader and ImebraStreamWriter parameters have been successfully connected to their peer, then keep it alive and poll the data via readCommand() and readPayload() until pError is set to ImebraStreamClosedError or ImebraCorruptedAcseMessageError.

pError set to ImebraStreamClosedError means that the association has been released or aborted.

If you call the abort() method on the ImebraAssociationSCP you should still wait for pError set to ImebraStreamClosedError by getCommand().

Public Functions

id ImebraAssociationSCP::initWithThisAET:maxInvokedOperations:maxPerformedOperations:presentationContexts:reader:writer:dimseTimeoutSeconds:artimTimeoutSeconds:error:(NSString * thisAET, unsigned int invokedOperations, unsigned int performedOperations, ImebraPresentationContexts * presentationContexts, ImebraStreamReader * pInput, ImebraStreamWriter * pOutput, unsigned int dimseTimeoutSeconds, unsigned int artimTimeoutSeconds, NSError ** pError)

Listens for an association request.

Blocks until the association has been negotiated successfully or an error occurs (pError is set).

Parameters
  • thisAET: the AET of the SCP. If empty then the SCP will accept associations for any called AET, otherwise it will reject the association when the called AET does not match this one

  • invokedOperations: maximum number of parallel operations we intend to invoke when acting as a SCU

  • performedOperations: maximum number of parallel operations we can perform when acting as a SCP

  • presentationContexts: list of accepted presentation contexts

  • pInput: input stream from which the SCP receives data. When using a TCPStream the same object can act as both input and output

  • pOutput: output stream into which the SCP writes data. When using a TCPStream the same object can act as both input and output

  • dimseTimeoutSeconds: DIMSE timeout, in seconds. 0 means infinite

  • artimTimeoutSeconds: ARTIM timeout, in seconds. Amount of time that is allowed to pass before an association request arrives

  • pError: may be set to one of the following errors:

    • ImebraCorruptedAcseMessageError

    • ImebraAcseSCUApplicationContextNameNotSupportedError

    • ImebraAcseSCUCalledAETNotRecognizedError

    • ImebraCodecWrongFormatError

    • ImebraDicomCodecDepthLimitReachedError

Message payload class

AssociationMessage

C++

class AssociationMessage

An immutable ACSE message composed by one or two datasets.

Use getCommand() and getPayload() to retrieve the command and the payload DataSet objects.

If you need a mutable ACSE message then use MutableAssociationMessage.

Subclassed by imebra::MutableAssociationMessage

Public Functions

AssociationMessage(const AssociationMessage &source)

Copy constructor.

Parameters
  • source: source association message

std::string getAbstractSyntax() const

Retrieve the message’s abstract syntax.

Return

the message’s abstract syntax

const DataSet getCommand() const

Return the command stored in the message.

Return

the command DataSet

const DataSet getPayload() const

Return the payload stored in the message.

Return

the payload DataSet

bool hasPayload() const

Return true if the message has a payload.

Return

true if the message has a payload, false otherwise

Objective-C/Swift

class ImebraAssociationMessage : public NSObject

A message composed by one or two datasets.

When sending a message through an ImebraAssociationBase derived object then up to two dataset can be included into the message: the first dataset is the command dataset, while the optional second one is the command’s payload.

Subclassed by ImebraMutableAssociationMessage

Public Functions

ImebraDataSet* ImebraAssociationMessage::getCommand:(NSError ** pError)

Return the command stored in the message.

Return

the command ImebraDataSet

ImebraDataSet* ImebraAssociationMessage::getPayload:(NSError ** pError)

Return the payload stored in the message.

Return

the payload ImebraDataSet

BOOL hasPayload()

Return true if the message has a payload.

Return

true if the message has a payload, false otherwise

Property

property ImebraAssociationMessage::abstractSyntax

The message’s abstract syntax.

MutableAssociationMessage

C++

class MutableAssociationMessage : public imebra::AssociationMessage

A mutable ACSE message composed by one or two datasets.

When sending a message through an AssociationBase derived object then up to two dataset can be included into the message: the first dataset is be the command dataset, while the optional second one is the command’s payload.

If you need an immutable ACSE message then use AssociationMessage.

Public Functions

MutableAssociationMessage(const std::string &abstractSyntax)

Constructor.

Parameters
  • abstractSyntax: the abstract syntax of the message.

MutableAssociationMessage(const MutableAssociationMessage &source)

Copy constructor.

Parameters
  • source: source mutable association message

void addDataSet(const DataSet &dataSet)

Add a command DataSet to the message.

Two datasets can be transmitted at once: the first DataSet is the DICOM command, while the second optional one is the command payload.

Parameters
  • dataSet: a DataSet to add to the message

Objective-C/Swift

class ImebraMutableAssociationMessage : public ImebraAssociationMessage

A message composed by one or two datasets.

When sending a message through an ImebraAssociationBase derived object then up to two dataset can be included into the message: the first dataset is the command dataset, while the optional second one is the command’s payload.

Public Functions

id ImebraMutableAssociationMessage::initWithAbstractSyntax:(NSString * abstractSyntax)

Initializer.

Parameters
  • abstractSyntax: the abstract syntax of the message.

void ImebraMutableAssociationMessage::addDataSet:error:(ImebraDataSet * pDataSet, (swift_error(nonnull_error)) __attribute__)

Add a command ImebraDataSet to the message.

Two datasets can be transmitted at once: the first data set is the DICOM command, while the second optional one is the command payload.

Parameters
  • dataSet: a ImebraDataSet to add to the message

  • pError: set in case of error