Esempio n. 1
0
def AE_7(dul):
    """Association establishment action AE-7.

    On receiving association request acceptance, issue A-ASSOCIATE-AC

    State-event triggers: Sta3 + Evt7

    References
    ----------
    1. DICOM Standard 2015b, PS3.8, Table 9-7, "Associate Establishment
       Related Actions"

    Parameters
    ----------
    dul : pynetdicom.dul.DULServiceProvider
        The DICOM Upper Layer Service instance for the local AE

    Returns
    -------
    str
        Sta6, the next state of the state machine
    """
    # Send A-ASSOCIATE-AC PDU
    dul.pdu = A_ASSOCIATE_AC()
    dul.pdu.from_primitive(dul.primitive)

    dul.socket.send(dul.pdu.encode())
    evt.trigger(dul.assoc, evt.EVT_PDU_SENT, {'pdu': dul.pdu})

    return 'Sta6'
Esempio n. 2
0
def AR_3(dul: "DULServiceProvider") -> str:
    """Association release AR-3.

    On receiving an association release response, send release confirmation,
    close connection and go back to Idle state

    State-event triggers: Sta7 + Evt13, Sta11 + Evt13

    Parameters
    ----------
    dul : dul.DULServiceProvider
        The DICOM Upper Layer Service instance for the local AE

    Returns
    -------
    str
        ``'Sta1'``, the next state of the state machine
    """
    # A-RELEASE-RP PDU received from peer
    pdu = dul._recv_pdu.get(False)

    # Issue A-RELEASE confirmation primitive and close transport connection
    dul.to_user_queue.put(pdu.to_primitive())
    sock = cast("AssociationSocket", dul.socket)
    sock.close()

    assoc = dul.assoc
    remote = assoc.acceptor if assoc.is_requestor else assoc.requestor

    address = (remote.address, remote.port)
    evt.trigger(dul.assoc, evt.EVT_CONN_CLOSE, {"address": address})

    dul.kill_dul()

    return "Sta1"
Esempio n. 3
0
def AA_4(dul: "DULServiceProvider") -> str:
    """Association abort AA-4.

    If connection closed, issue A-P-ABORT and return to Idle

    State-event triggers: Sta3/Sta4/Sta5/Sta6/Sta7/Sta8/Sta9/Sta10/Sta11/Sta12
    + Evt17

    Parameters
    ----------
    dul : dul.DULServiceProvider
        The DICOM Upper Layer Service instance for the local AE

    Returns
    -------
    str
        ``'Sta1'``, the next state of the state machine
    """
    assoc = dul.assoc
    assoc.dimse.msg_queue.put((None, None))

    remote = assoc.acceptor if assoc.is_requestor else assoc.requestor
    address = (remote.address, remote.port)
    evt.trigger(dul.assoc, evt.EVT_CONN_CLOSE, {"address": address})

    # Issue A-P-ABORT indication primitive.
    primitive = A_P_ABORT()
    primitive.provider_reason = 0x00
    dul.to_user_queue.put(primitive)
    dul.kill_dul()

    return "Sta1"
Esempio n. 4
0
def AA_7(dul):
    """Association abort AA-7.

    If receive a association request or invalid PDU while waiting for
    connection to close, send A-ABORT PDU

    State-event triggers: Sta13 + Evt6/Evt19

    Parameters
    ----------
    dul : dul.DULServiceProvider
        The DICOM Upper Layer Service instance for the local AE

    Returns
    -------
    str
        ``'Sta13'``, the next state of the state machine
    """
    primitive = A_P_ABORT()
    primitive.provider_reason = 0x02

    # Send A-ABORT PDU.
    pdu = A_ABORT_RQ()
    pdu.from_primitive(primitive)

    dul.socket.send(dul.pdu.encode())
    evt.trigger(dul.assoc, evt.EVT_PDU_SENT, {'pdu': dul.pdu})

    return 'Sta13'
Esempio n. 5
0
    def send_msg(self, primitive, context_id):
        """Send a DIMSE-C or DIMSE-N message to the peer AE.

        Parameters
        ----------
        primitive : dimse_primitives DIMSE Primitive class
            The DIMSE message primitive to send to the peer.
        context_id : int
            The ID of the presentation context that the message is to be
            sent under.
        """
        if primitive.MessageIDBeingRespondedTo is None:
            dimse_msg = _RQ_TO_MESSAGE[primitive.__class__]()
        else:
            dimse_msg = _RSP_TO_MESSAGE[primitive.__class__]()

        # Convert DIMSE primitive to DIMSE Message
        dimse_msg.primitive_to_message(primitive)
        dimse_msg.context_id = context_id

        # Trigger event
        evt.trigger(
            self.assoc, evt.EVT_DIMSE_SENT, {'message' : dimse_msg}
        )

        # Split the full messages into P-DATA chunks,
        #   each below the max_pdu size
        for pdata in dimse_msg.encode_msg(context_id, self.maximum_pdu_size):
            self.dul.send_pdu(pdata)
Esempio n. 6
0
def AR_5(dul):
    """Association release AR-5.

    On receiving transport connection closed, stop the ARTIM timer and go back
    to Idle state

    State-event triggers: Sta13 + Evt17

    Parameters
    ----------
    dul : dul.DULServiceProvider
        The DICOM Upper Layer Service instance for the local AE

    Returns
    -------
    str
        ``'Sta1'``, the next state of the state machine
    """
    assoc = dul.assoc
    remote = assoc.acceptor if assoc.is_requestor else assoc.requestor

    address = (remote.address, remote.port)
    evt.trigger(dul.assoc, evt.EVT_CONN_CLOSE, {'address': address})

    # Stop ARTIM timer
    dul.artim_timer.stop()
    dul.kill_dul()

    return 'Sta1'
Esempio n. 7
0
def AR_9(dul):
    """Association release AR-9.

    On receiving A-RELEASE primitive, send release response

    State-event triggers: Sta9 + Evt14

    Parameters
    ----------
    dul : dul.DULServiceProvider
        The DICOM Upper Layer Service instance for the local AE

    Returns
    -------
    str
        ``'Sta11'``, the next state of the state machine
    """
    # Send A-RELEASE-RP PDU
    dul.pdu = A_RELEASE_RP()
    dul.pdu.from_primitive(dul.primitive)

    dul.socket.send(dul.pdu.encode())
    evt.trigger(dul.assoc, evt.EVT_PDU_SENT, {'pdu': dul.pdu})

    return 'Sta11'
Esempio n. 8
0
    def _decode_pdu(self, bytestream):
        """Decode a received PDU.

        Parameters
        ----------
        bytestream : bytearray
            The received PDU.

        Returns
        -------
        pdu.PDU subclass, str
            The PDU subclass corresponding to the PDU and the event string
            corresponding to receiving that PDU type.
        """
        # Trigger before data is decoded in case of exception in decoding
        bytestream = bytes(bytestream)
        evt.trigger(self.assoc, evt.EVT_DATA_RECV, {'data': bytestream})

        pdu, event = _PDU_TYPES[bytestream[0:1]]
        pdu = pdu()
        pdu.decode(bytestream)

        evt.trigger(self.assoc, evt.EVT_PDU_RECV, {'pdu': pdu})

        return pdu, event
Esempio n. 9
0
    def send_pdu(self, primitive):
        """Place a primitive in the provider queue to be sent to the peer.

        Primitives are converted to the corresponding PDU and encoded before
        sending.

        Parameters
        ----------
        primitive : pdu_primitives.PDU sub-class
            A service primitive, one of:

            .. currentmodule:: pynetdicom.pdu_primitives

            * :class:`A_ASSOCIATE`
            * :class:`A_RELEASE`
            * :class:`A_ABORT`
            * :class:`A_P_ABORT`
            * :class:`P_DATA`
        """
        # Event handler - ACSE sent primitive to the DUL service
        acse_primitives = (A_ASSOCIATE, A_RELEASE, A_ABORT, A_P_ABORT)
        if isinstance(primitive, acse_primitives):
            evt.trigger(self.assoc, evt.EVT_ACSE_SENT,
                        {'primitive': primitive})

        self.to_provider_queue.put(primitive)
Esempio n. 10
0
def AA_5(dul):
    """Association abort AA-5.

    If connection closed during association request, stop ARTIM timer and return
    to Idle

    State-event triggers: Sta2 + Evt17

    References
    ----------
    1. DICOM Standard 2015b, PS3.8, Table 9-7, "Associate Establishment
       Related Actions"

    Parameters
    ----------
    dul : pynetdicom.dul.DULServiceProvider
        The DICOM Upper Layer Service instance for the local AE

    Returns
    -------
    str
        Sta1, the next state of the state machine
    """
    assoc = dul.assoc
    remote = assoc.acceptor if assoc.is_requestor else assoc.requestor

    address = (remote.address, remote.port)
    evt.trigger(dul.assoc, evt.EVT_CONN_CLOSE, {'address': address})

    # Stop ARTIM timer.
    dul.artim_timer.stop()
    dul.kill_dul()

    return 'Sta1'
Esempio n. 11
0
    def _decode_pdu(self, bytestream: bytearray) -> Tuple[_PDUType, str]:
        """Decode a received PDU.

        Parameters
        ----------
        bytestream : bytearray
            The received PDU.

        Returns
        -------
        pdu.PDU subclass, str
            The PDU subclass corresponding to the PDU and the event string
            corresponding to receiving that PDU type.
        """
        # Trigger before data is decoded in case of exception in decoding
        b = bytes(bytestream)
        evt.trigger(self.assoc, evt.EVT_DATA_RECV, {"data": b})

        pdu_cls, event = _PDU_TYPES[b[0:1]]
        pdu = pdu_cls()
        pdu.decode(b)

        evt.trigger(self.assoc, evt.EVT_PDU_RECV, {"pdu": pdu})

        return pdu, event
Esempio n. 12
0
def AR_9(dul):
    """Association release AR-9.

    On receiving A-RELEASE primitive, send release response

    State-event triggers: Sta9 + Evt14

    References
    ----------
    1. DICOM Standard 2015b, PS3.8, Table 9-7, "Associate Establishment
       Related Actions"

    Parameters
    ----------
    dul : pynetdicom.dul.DULServiceProvider
        The DICOM Upper Layer Service instance for the local AE

    Returns
    -------
    str
        Sta11, the next state of the state machine
    """
    # Send A-RELEASE-RP PDU
    dul.pdu = A_RELEASE_RP()
    dul.pdu.from_primitive(dul.primitive)

    dul.socket.send(dul.pdu.encode())
    evt.trigger(dul.assoc, evt.EVT_PDU_SENT, {'pdu': dul.pdu})

    return 'Sta11'
Esempio n. 13
0
def AR_7(dul):
    """Association release AR-7.

    On receiving P-DATA request during attempted association release request
    send P-DATA-TF

    State-event triggers: Sta8 + Evt9

    References
    ----------
    1. DICOM Standard 2015b, PS3.8, Table 9-7, "Associate Establishment
       Related Actions"

    Parameters
    ----------
    dul : pynetdicom.dul.DULServiceProvider
        The DICOM Upper Layer Service instance for the local AE

    Returns
    -------
    str
        Sta8, the next state of the state machine
    """
    # Issue P-DATA-TF PDU
    dul.pdu = P_DATA_TF()
    dul.pdu.from_primitive(dul.primitive)

    dul.socket.send(dul.pdu.encode())
    evt.trigger(dul.assoc, evt.EVT_PDU_SENT, {'pdu': dul.pdu})

    return 'Sta8'
Esempio n. 14
0
def DT_1(dul):
    """Data transfer DT-1.

    On receiving a P-DATA request, send P-DATA-TF

    State-event triggers: Sta6 + Evt9

    References
    ----------
    1. DICOM Standard 2015b, PS3.8, Table 9-7, "Associate Establishment
       Related Actions"

    Parameters
    ----------
    dul : pynetdicom.dul.DULServiceProvider
        The DICOM Upper Layer Service instance for the local AE

    Returns
    -------
    str
        Sta6, the next state of the state machine
    """
    # Send P-DATA-TF PDU
    dul.pdu = P_DATA_TF()
    dul.pdu.from_primitive(dul.primitive)
    dul.primitive = None  # Why this?

    dul.socket.send(dul.pdu.encode())
    evt.trigger(dul.assoc, evt.EVT_PDU_SENT, {'pdu': dul.pdu})

    return 'Sta6'
Esempio n. 15
0
def AR_3(dul):
    """Association release AR-3.

    On receiving an association release response, send release confirmation,
    close connection and go back to Idle state

    State-event triggers: Sta7 + Evt13, Sta11 + Evt13

    Parameters
    ----------
    dul : dul.DULServiceProvider
        The DICOM Upper Layer Service instance for the local AE

    Returns
    -------
    str
        ``'Sta1'``, the next state of the state machine
    """
    # Issue A-RELEASE confirmation primitive and close transport connection
    dul.to_user_queue.put(dul.primitive)
    dul.socket.close()

    assoc = dul.assoc
    remote = assoc.acceptor if assoc.is_requestor else assoc.requestor

    address = (remote.address, remote.port)
    evt.trigger(dul.assoc, evt.EVT_CONN_CLOSE, {'address': address})

    dul.kill_dul()

    return 'Sta1'
Esempio n. 16
0
    def _decode_pdu(self, bytestream):
        """Decode a received PDU.

        Parameters
        ----------
        bytestream : bytearray
            The received PDU.

        Returns
        -------
        pdu.PDU subclass, str
            The PDU subclass corresponding to the PDU and the event string
            corresponding to receiving that PDU type.
        """
        # Trigger before data is decoded in case of exception in decoding
        bytestream = bytes(bytestream)
        evt.trigger(self.assoc, evt.EVT_DATA_RECV, {'data': bytestream})

        pdu_types = {
            b'\x01': (A_ASSOCIATE_RQ, 'Evt6'),
            b'\x02': (A_ASSOCIATE_AC, 'Evt3'),
            b'\x03': (A_ASSOCIATE_RJ, 'Evt4'),
            b'\x04': (P_DATA_TF, 'Evt10'),
            b'\x05': (A_RELEASE_RQ, 'Evt12'),
            b'\x06': (A_RELEASE_RP, 'Evt13'),
            b'\x07': (A_ABORT_RQ, 'Evt16')
        }

        pdu, event = pdu_types[bytestream[0:1]]
        pdu = pdu()
        pdu.decode(bytestream)

        evt.trigger(self.assoc, evt.EVT_PDU_RECV, {'pdu': pdu})

        return pdu, event
Esempio n. 17
0
def AR_4(dul):
    """Association release AR-4.

    On receiving an association release response, send release response

    State-event triggers: Sta8 + Evt14, Sta12 + Evt14

    Parameters
    ----------
    dul : dul.DULServiceProvider
        The DICOM Upper Layer Service instance for the local AE

    Returns
    -------
    str
        ``'Sta13'``, the next state of the state machine
    """
    # Issue A-RELEASE-RP PDU and start ARTIM timer
    dul.pdu = A_RELEASE_RP()
    dul.pdu.from_primitive(dul.primitive)

    dul.socket.send(dul.pdu.encode())
    evt.trigger(dul.assoc, evt.EVT_PDU_SENT, {'pdu': dul.pdu})
    dul.artim_timer.start()

    return 'Sta13'
Esempio n. 18
0
def AE_2(dul):
    """Association establishment action AE-2.

    On receiving connection confirmation, send A-ASSOCIATE-RQ to the peer AE
    This send a byte stream with the format given by Table 9-11

    State-event triggers: Sta4 + Evt2

    Parameters
    ----------
    dul : dul.DULServiceProvider
        The DICOM Upper Layer Service instance for the local AE

    Returns
    -------
    str
        ``'Sta5'``, the next state of the state machine.
    """
    # Send A-ASSOCIATE-RQ PDU
    dul.pdu = A_ASSOCIATE_RQ()
    dul.pdu.from_primitive(dul.primitive)

    dul.socket.send(dul.pdu.encode())
    evt.trigger(dul.assoc, evt.EVT_PDU_SENT, {'pdu': dul.pdu})

    return 'Sta5'
Esempio n. 19
0
def AR_7(dul):
    """Association release AR-7.

    On receiving P-DATA request during attempted association release request
    send P-DATA-TF

    State-event triggers: Sta8 + Evt9

    Parameters
    ----------
    dul : dul.DULServiceProvider
        The DICOM Upper Layer Service instance for the local AE

    Returns
    -------
    str
        ``'Sta8'``, the next state of the state machine
    """
    # Issue P-DATA-TF PDU
    dul.pdu = P_DATA_TF()
    dul.pdu.from_primitive(dul.primitive)

    dul.socket.send(dul.pdu.encode())
    evt.trigger(dul.assoc, evt.EVT_PDU_SENT, {'pdu': dul.pdu})

    return 'Sta8'
Esempio n. 20
0
def AE_4(dul):
    """Association establishment action AE-4.

    On receiving A-ASSOCIATE-RJ, issue rejection confirmation and close
    connection

    State-event triggers: Sta5 + Evt4

    Parameters
    ----------
    dul : dul.DULServiceProvider
        The DICOM Upper Layer Service instance for the local AE

    Returns
    -------
    str
        ``'Sta1'``, the next state of the state machine
    """
    # Issue A-ASSOCIATE confirmation (reject) primitive and close transport
    # connection
    dul.to_user_queue.put(dul.primitive)
    dul.socket.close()

    assoc = dul.assoc
    remote = assoc.acceptor if assoc.is_requestor else assoc.requestor

    address = (remote.address, remote.port)
    evt.trigger(dul.assoc, evt.EVT_CONN_CLOSE, {'address': address})

    dul.kill_dul()

    return 'Sta1'
Esempio n. 21
0
def AA_1(dul):
    """Association abort AA-1.

    If on sending A-ASSOCIATE-RQ we receive an invalid reply, or an abort
    request then abort

    State-event triggers: Sta2 + Evt3/Evt4/Evt10/Evt12/Evt13/Evt19,
    Sta3/Sta5/Sta6/Sta7/Sta8/Sta9/Sta10/Sta11/Sta12 + Evt15

    Parameters
    ----------
    dul : dul.DULServiceProvider
        The DICOM Upper Layer Service instance for the local AE

    Returns
    -------
    str
        ``'Sta13'``, the next state of the state machine
    """
    # Send A-ABORT PDU (service-user source) and start (or restart
    # if already started) ARTIM timer.
    dul.pdu = A_ABORT_RQ()
    dul.pdu.source = 0x00
    # Reason not specified
    dul.pdu.reason_diagnostic = 0x00
    dul.pdu.from_primitive(dul.primitive)

    dul.socket.send(dul.pdu.encode())
    evt.trigger(dul.assoc, evt.EVT_PDU_SENT, {'pdu': dul.pdu})
    dul.artim_timer.restart()

    return 'Sta13'
Esempio n. 22
0
def AE_7(dul):
    """Association establishment action AE-7.

    On receiving association request acceptance, issue A-ASSOCIATE-AC

    State-event triggers: Sta3 + Evt7

    Parameters
    ----------
    dul : dul.DULServiceProvider
        The DICOM Upper Layer Service instance for the local AE

    Returns
    -------
    str
        ``'Sta6'``, the next state of the state machine
    """
    # Send A-ASSOCIATE-AC PDU
    dul.pdu = A_ASSOCIATE_AC()
    dul.pdu.from_primitive(dul.primitive)

    dul.socket.send(dul.pdu.encode())
    evt.trigger(dul.assoc, evt.EVT_PDU_SENT, {'pdu': dul.pdu})

    return 'Sta6'
Esempio n. 23
0
    def receive_primitive(self, primitive):
        """Process a P-DATA primitive received from the remote.

        .. versionadded:: 1.2

        A DIMSE message is split into one or more P-DATA primitives, which
        must be sent in sequential order. While waiting for all the P-DATA
        primitives associated with a message the encoded data is stored in
        :attr:`~DIMSEServiceProvider.message`, which is decoded only when
        complete and converted into a DIMSE Message primitive which is added
        to the :attr:`~DIMSEServiceProvider.msg_queue`.

        This makes it possible to process incoming P-DATA primitives into
        DIMSE messages while a service class implementation is running.

        Parameters
        ----------
        primitive : pdu_primitives.P_DATA
            A P-DATA primitive received from the peer to be processed.
        """
        if self.message is None:
            self.message = DIMSEMessage()

        if self.message.decode_msg(primitive):
            # Trigger event
            evt.trigger(
                self.assoc, evt.EVT_DIMSE_RECV, {'message' : self.message}
            )

            context_id = self.message.context_id
            try:
                primitive = self.message.message_to_primitive()
            except Exception as exc:
                LOGGER.error("Received an invalid DIMSE message")
                LOGGER.exception(exc)
                self.dul.event_queue.put('Evt19')
                return

            # Keep C-CANCEL requests separate from other messages
            # Only allow up to 10 C-CANCEL requests
            if isinstance(primitive, C_CANCEL) and len(self.cancel_req) < 10:
                msg_id = primitive.MessageIDBeingRespondedTo
                self.cancel_req[msg_id] = primitive
            elif (isinstance(primitive, N_EVENT_REPORT) and
                  primitive.is_valid_request):
                # N-EVENT-REPORT service requests are handled immediately
                # Ugly hack, but would block the DUL otherwise
                t = threading.Thread(
                    target=self.assoc._serve_request,
                    args=(primitive, context_id)
                )
                t.start()
            else:
                self.msg_queue.put((context_id, primitive))

            # Fix for memory leak, Issue #41
            #   Reset the DIMSE message, ready for the next one
            self.message.encoded_command_set = BytesIO()
            self.message.data_set = BytesIO()
            self.message = None
Esempio n. 24
0
def AE_8(dul):
    """Association establishment action AE-8.

    On receiving association request rejection, issue A-ASSOCIATE-RJ

    State-event triggers: Sta3 + Evt8

    Parameters
    ----------
    dul : dul.DULServiceProvider
        The DICOM Upper Layer Service instance for the local AE

    Returns
    -------
    str
        ``'Sta13'``, the next state of the state machine
    """
    # Send A-ASSOCIATE-RJ PDU and start ARTIM timer
    dul.pdu = A_ASSOCIATE_RJ()
    dul.pdu.from_primitive(dul.primitive)

    dul.socket.send(dul.pdu.encode())
    evt.trigger(dul.assoc, evt.EVT_PDU_SENT, {'pdu': dul.pdu})
    dul.artim_timer.start()

    return 'Sta13'
Esempio n. 25
0
    def send(self, bytestream: bytes) -> None:
        """Try and send the data in `bytestream` to the remote.

        *Events Emitted*

        - None
        - Evt17: Transport connected closed.

        Parameters
        ----------
        bytestream : bytes
            The data to send to the remote.
        """
        self.socket = cast(socket.socket, self.socket)
        total_sent = 0
        length_data = len(bytestream)
        try:
            while total_sent < length_data:
                # Returns the number of bytes sent
                nr_sent = self.socket.send(bytestream[total_sent:])
                total_sent += nr_sent

            evt.trigger(self.assoc, evt.EVT_DATA_SENT, {"data": bytestream})
        except (socket.error, socket.timeout):
            # Evt17: Transport connection closed
            self.event_queue.put("Evt17")
Esempio n. 26
0
def DT_1(dul):
    """Data transfer DT-1.

    On receiving a P-DATA request, send P-DATA-TF

    State-event triggers: Sta6 + Evt9

    Parameters
    ----------
    dul : dul.DULServiceProvider
        The DICOM Upper Layer Service instance for the local AE

    Returns
    -------
    str
        ``'Sta6'``, the next state of the state machine
    """
    # Send P-DATA-TF PDU
    dul.pdu = P_DATA_TF()
    dul.pdu.from_primitive(dul.primitive)
    dul.primitive = None  # Why this?

    dul.socket.send(dul.pdu.encode())
    evt.trigger(dul.assoc, evt.EVT_PDU_SENT, {'pdu': dul.pdu})

    return 'Sta6'
Esempio n. 27
0
def AA_2(dul: "DULServiceProvider") -> str:
    """Association abort AA-2.

    On receiving an A-ABORT or if the ARTIM timer expires, close connection and
    return to Idle

    State-event triggers: Sta2 + Evt16/Evt18, Sta4 + Evt15, Sta13 + Evt16/Evt18

    Parameters
    ----------
    dul : dul.DULServiceProvider
        The DICOM Upper Layer Service instance for the local AE

    Returns
    -------
    str
        ``'Sta1'``, the next state of the state machine
    """
    # Stop ARTIM timer if running. Close transport connection.
    dul.artim_timer.stop()
    sock = cast("AssociationSocket", dul.socket)
    sock.close()

    assoc = dul.assoc
    assoc.dimse.msg_queue.put((None, None))

    remote = assoc.acceptor if assoc.is_requestor else assoc.requestor
    address = (remote.address, remote.port)
    evt.trigger(dul.assoc, evt.EVT_CONN_CLOSE, {"address": address})

    dul.kill_dul()

    return "Sta1"
Esempio n. 28
0
def AR_1(dul):
    """Association release AR-1.

    Send Association release request

    State-event triggers: Sta6 + Evt11

    Parameters
    ----------
    dul : dul.DULServiceProvider
        The DICOM Upper Layer Service instance for the local AE

    Returns
    -------
    str
        ``'Sta7'``, the next state of the state machine
    """
    # Send A-RELEASE-RQ PDU
    dul.pdu = A_RELEASE_RQ()
    dul.pdu.from_primitive(dul.primitive)

    dul.socket.send(dul.pdu.encode())
    evt.trigger(dul.assoc, evt.EVT_PDU_SENT, {'pdu': dul.pdu})

    return 'Sta7'
Esempio n. 29
0
def AA_5(dul: "DULServiceProvider") -> str:
    """Association abort AA-5.

    If connection closed during association request, stop ARTIM timer and
    return to Idle

    State-event triggers: Sta2 + Evt17

    Parameters
    ----------
    dul : dul.DULServiceProvider
        The DICOM Upper Layer Service instance for the local AE

    Returns
    -------
    str
        ``'Sta1'``, the next state of the state machine
    """
    assoc = dul.assoc
    remote = assoc.acceptor if assoc.is_requestor else assoc.requestor

    address = (remote.address, remote.port)
    evt.trigger(dul.assoc, evt.EVT_CONN_CLOSE, {"address": address})

    # Stop ARTIM timer.
    dul.artim_timer.stop()
    dul.kill_dul()

    return "Sta1"
Esempio n. 30
0
    def test_send_assoc_ac_async(self, caplog):
        """Test ACSE.debug_send_associate_ac with async ops."""
        with caplog.at_level(logging.DEBUG, logger='pynetdicom'):
            self.ae = ae = AE()
            ae.add_supported_context(VerificationSOPClass)
            ae.add_requested_context(VerificationSOPClass)
            ae.add_requested_context(VerificationSOPClass)
            ae.add_requested_context(VerificationSOPClass)
            ae.add_requested_context(VerificationSOPClass)
            ae.add_requested_context(VerificationSOPClass)
            scp = ae.start_server(('', 11112), block=False)
            assoc = ae.associate('localhost', 11112)

            self.add_async_ops(self.associate_ac)
            pdu = A_ASSOCIATE_AC()
            pdu.from_primitive(self.associate_ac)
            evt.trigger(assoc, evt.EVT_PDU_SENT, {'pdu': pdu})

            messages = [
                "Accepted Extended Negotiation: None",
                "Accepted Asynchronous Operations Window Negotiation:",
                "Maximum Invoked Operations:     2",
                "Maximum Performed Operations:   3",
                "User Identity Negotiation Response: None",
            ]

            for msg in messages:
                assert msg in caplog.text

            assoc.release()
            scp.shutdown()