예제 #1
0
    def test__primitive_to_event(self):
        """Test that parameter returns expected results"""
        dul = DummyDUL()
        p2e = dul._primitive_to_event

        primitive = A_ASSOCIATE()
        primitive.result = None
        self.assertEqual(p2e(primitive), 'Evt1')
        primitive.result = 0
        self.assertEqual(p2e(primitive), 'Evt7')
        primitive.result = 1
        self.assertEqual(p2e(primitive), 'Evt8')

        primitive = A_RELEASE()
        primitive.result = None
        self.assertEqual(p2e(primitive), 'Evt11')
        primitive.result = 'affirmative'
        self.assertEqual(p2e(primitive), 'Evt14')

        primitive = A_ABORT()
        self.assertEqual(p2e(primitive), 'Evt15')

        primitive = P_DATA()
        self.assertEqual(p2e(primitive), 'Evt9')

        with self.assertRaises(ValueError):
            p2e('TEST')
예제 #2
0
    def test_conversion(self):
        """ Check conversion to a PDU produces the correct output """
        assoc = A_ASSOCIATE()
        assoc.application_context_name = "1.2.840.10008.3.1.1.1"
        assoc.calling_ae_title = 'ECHOSCU'
        assoc.called_ae_title = 'ANY-SCP'
        assoc.maximum_length_received = 16382
        assoc.implementation_class_uid = '1.2.826.0.1.3680043.9.3811.0.9.0'

        imp_ver_name = ImplementationVersionNameNotification()
        imp_ver_name.implementation_version_name = 'PYNETDICOM_090'
        assoc.user_information.append(imp_ver_name)

        pc = PresentationContext()
        pc.context_id = 1
        pc.abstract_syntax = '1.2.840.10008.1.1'
        pc.transfer_syntax = ['1.2.840.10008.1.2']
        assoc.presentation_context_definition_list = [pc]

        pdu = A_ASSOCIATE_RQ()
        pdu.from_primitive(assoc)
        data = pdu.encode()

        ref = b"\x01\x00\x00\x00\x00\xd1\x00\x01\x00\x00\x41\x4e\x59\x2d\x53\x43" \
              b"\x50\x20\x20\x20\x20\x20\x20\x20\x20\x20\x45\x43\x48\x4f\x53\x43" \
              b"\x55\x20\x20\x20\x20\x20\x20\x20\x20\x20\x00\x00\x00\x00\x00\x00" \
              b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" \
              b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x15\x31\x2e" \
              b"\x32\x2e\x38\x34\x30\x2e\x31\x30\x30\x30\x38\x2e\x33\x2e\x31\x2e" \
              b"\x31\x2e\x31\x20\x00\x00\x2e\x01\x00\x00\x00\x30\x00\x00\x11\x31" \
              b"\x2e\x32\x2e\x38\x34\x30\x2e\x31\x30\x30\x30\x38\x2e\x31\x2e\x31" \
              b"\x40\x00\x00\x11\x31\x2e\x32\x2e\x38\x34\x30\x2e\x31\x30\x30\x30" \
              b"\x38\x2e\x31\x2e\x32\x50\x00\x00\x3e\x51\x00\x00\x04\x00\x00\x3f" \
              b"\xfe\x52\x00\x00\x20\x31\x2e\x32\x2e\x38\x32\x36\x2e\x30\x2e\x31" \
              b"\x2e\x33\x36\x38\x30\x30\x34\x33\x2e\x39\x2e\x33\x38\x31\x31\x2e" \
              b"\x30\x2e\x39\x2e\x30\x55\x00\x00\x0e\x50\x59\x4e\x45\x54\x44\x49" \
              b"\x43\x4f\x4d\x5f\x30\x39\x30"

        assert data == ref
예제 #3
0
파일: acse.py 프로젝트: vinjex/pynetdicom3
    def request_assoc(self,
                      local_ae,
                      peer_ae,
                      max_pdu_size,
                      pcdl,
                      userspdu=None):
        """Request an Association with a peer Application Entity SCP.

        Issues an A-ASSOCIATE request primitive to the DICOM UL service provider

        Requests an association with a remote AE and waits for association
        response (local AE is acting as an SCU)

        Parameters
        ----------
        local_ae : dict
            Contains information about the local AE, keys 'ae_title', 'port',
            'address', 'pdv_size', 'propsed_contexts'.
        peer_ae : dict
            Contains information about the peer AE, keys 'ae_title', 'port',
            'address'.
        max_pdu_size : int
            Maximum PDU size in bytes
        pcdl : list of pynetdicom3.presentation.PresentationContext
            A list of the proposed Presentation Contexts for the association
            If local_ae is ApplicationEntity then this is doubled up
            unnecessarily
        userpdu : List of UserInformation objects
            List of items to be added to the requests user information for use
            in extended negotiation. See PS3.7 Annex D.3.3

        Returns
        -------
        bool
            True if the Association was accepted, False if rejected or aborted
        """
        self.local_ae = local_ae
        self.local_ae['pdv_size'] = max_pdu_size
        self.remote_ae = peer_ae

        self.local_max_pdu = max_pdu_size

        ## Build an A-ASSOCIATE request primitive
        #
        # The following parameters must be set for a request primitive
        #   ApplicationContextName
        #   CallingAETitle
        #   CalledAETitle
        #   UserInformation
        #       Maximum PDV Length (required)
        #       Implementation Identification - Class UID (required)
        #   CallingPresentationAddress
        #   CalledPresentationAddress
        #   PresentationContextDefinitionList
        assoc_rq = A_ASSOCIATE()
        assoc_rq.application_context_name = self.application_context_name
        assoc_rq.calling_ae_title = self.local_ae['ae_title']
        assoc_rq.called_ae_title = self.remote_ae['ae_title']

        # Build User Information - PS3.7 Annex D.3.3
        #
        # Maximum Length Negotiation (required)
        max_length = MaximumLengthNegotiation()
        max_length.maximum_length_received = self.local_ae['pdv_size']
        assoc_rq.user_information = [max_length]

        # Implementation Identification Notification (required)
        # Class UID (required)
        implementation_class_uid = ImplementationClassUIDNotification()
        implementation_class_uid.implementation_class_uid = UID(
            pynetdicom_implementation_uid)
        assoc_rq.user_information.append(implementation_class_uid)

        # Version Name (optional)
        implementation_version_name = ImplementationVersionNameNotification()
        implementation_version_name.implementation_version_name = (
            pynetdicom_version)
        assoc_rq.user_information.append(implementation_version_name)

        # Add the extended negotiation information (optional)
        if userspdu is not None:
            assoc_rq.user_information += userspdu

        assoc_rq.calling_presentation_address = (self.local_ae['address'],
                                                 self.local_ae['port'])
        assoc_rq.called_presentation_address = (self.remote_ae['address'],
                                                self.remote_ae['port'])
        assoc_rq.presentation_context_definition_list = pcdl
        #
        ## A-ASSOCIATE request primitive is now complete

        # Send the A-ASSOCIATE request primitive to the peer via the
        #   DICOM UL service
        LOGGER.info("Requesting Association")
        self.dul.send_pdu(assoc_rq)

        ## Receive the response from the peer
        #   This may be an A-ASSOCIATE confirmation primitive or an
        #   A-ABORT or A-P-ABORT request primitive
        #
        assoc_rsp = self.dul.receive_pdu(wait=True, timeout=self.acse_timeout)

        # Association accepted or rejected
        if isinstance(assoc_rsp, A_ASSOCIATE):
            # Accepted
            if assoc_rsp.result == 0x00:
                # Get maximum pdu length from answer
                self.peer_max_pdu = assoc_rsp.maximum_length_received
                self.parent.peer_ae['pdv_size'] = (
                    assoc_rsp.maximum_length_received)
                # FIXME
                self.parent.peer_max_pdu = assoc_rsp.maximum_length_received

                # Get accepted presentation contexts using the manager
                self.context_manager.requestor_contexts = pcdl
                self.context_manager.acceptor_contexts = (
                    assoc_rsp.presentation_context_definition_results_list)

                # Once the context manager gets both sets of contexts it
                #   automatically determines which are accepted and refused
                self.accepted_contexts = self.context_manager.accepted
                self.rejected_contexts = self.context_manager.rejected

                return True, assoc_rsp

            # Rejected
            elif assoc_rsp.result in [0x01, 0x02]:
                # 0x01 is rejected (permanent)
                # 0x02 is rejected (transient)
                return False, assoc_rsp
            # Invalid Result value
            elif assoc_rsp.result is None:
                return False, assoc_rsp
            else:
                LOGGER.error(
                    "ACSE received an invalid result value from "
                    "the peer AE: '%s'", assoc_rsp.result)
                raise ValueError("ACSE received an invalid result value from "
                                 "the peer AE: '{}'".format(assoc_rsp.result))

        # Association aborted
        elif isinstance(assoc_rsp, (A_ABORT, A_P_ABORT)):
            return False, assoc_rsp

        elif assoc_rsp is None:
            return False, assoc_rsp

        else:
            raise ValueError("Unexpected response by the peer AE to the "
                             "ACSE association request")
예제 #4
0
    def test_exceptions(self):
        """ Check incorrect types/values for properties raise exceptions """
        assoc = A_ASSOCIATE()

        # application_context_name
        with pytest.raises(TypeError):
            assoc.application_context_name = 10

        with pytest.raises(TypeError):
            assoc.application_context_name = 45.2

        with pytest.raises(ValueError):
            assoc.application_context_name = 'abc'

        # calling_ae_title
        with pytest.raises(TypeError):
            assoc.calling_ae_title = 45.2

        with pytest.raises(TypeError):
            assoc.calling_ae_title = 100

        with pytest.raises(ValueError):
            assoc.calling_ae_title = ''

        with pytest.raises(ValueError):
            assoc.calling_ae_title = '    '

        # called_ae_title
        with pytest.raises(TypeError):
            assoc.called_ae_title = 45.2

        with pytest.raises(TypeError):
            assoc.called_ae_title = 100

        with pytest.raises(ValueError):
            assoc.called_ae_title = ''

        with pytest.raises(ValueError):
            assoc.called_ae_title = '    '

        # user_information
        with pytest.raises(TypeError):
            assoc.user_information = 45.2

        # result
        with pytest.raises(ValueError):
            assoc.result = -1

        with pytest.raises(ValueError):
            assoc.result = 3

        # result_source
        with pytest.raises(ValueError):
            assoc.result_source = 0

        # result_source
        with pytest.raises(ValueError):
            assoc.result_source = 4

        # diagnostic
        with pytest.raises(ValueError):
            assoc.diagnostic = 0

        with pytest.raises(ValueError):
            assoc.diagnostic = 4

        with pytest.raises(ValueError):
            assoc.diagnostic = 5

        with pytest.raises(ValueError):
            assoc.diagnostic = 6

        with pytest.raises(ValueError):
            assoc.diagnostic = 8

        # calling_presentation_addresss
        with pytest.raises(TypeError):
            assoc.calling_presentation_address = ['10.40.94.43', 105]

        with pytest.raises(TypeError):
            assoc.calling_presentation_address = (105, '10.40.94.43')

        # called_presentation_addresss
        with pytest.raises(TypeError):
            assoc.called_presentation_address = ['10.40.94.43', 105]

        with pytest.raises(TypeError):
            assoc.called_presentation_address = (105, '10.40.94.43')

        # presentation_context_definition_list
        with pytest.raises(TypeError):
            assoc.presentation_context_definition_list = 45.2

        # presentation_context_definition_results_list
        with pytest.raises(TypeError):
            assoc.presentation_context_definition_results_list = 45.2

        # implementation_class_uid
        with pytest.raises(ValueError):
            x = assoc.implementation_class_uid

        imp_uid = ImplementationClassUIDNotification()
        assoc.user_information.append(imp_uid)
        with pytest.raises(ValueError):
            x = assoc.implementation_class_uid
예제 #5
0
    def test_assignment(self):
        """ Check assignment works correctly """
        assoc = A_ASSOCIATE()

        def test_mode():
            assoc.mode = "test value"

        self.assertRaises(AttributeError, test_mode)

        def test_preq():
            assoc.presentation_requirements = "test value2"

        self.assertRaises(AttributeError, test_preq)

        def test_sreq():
            assoc.session_requirements = "test value3"

        self.assertRaises(AttributeError, test_sreq)

        assoc.application_context_name = "1.2.840.10008.3.1.1.1"
        self.assertTrue(
            assoc.application_context_name == UID('1.2.840.10008.3.1.1.1'))
        assoc.application_context_name = b"1.2.840.10008.3.1.1.1"
        self.assertTrue(
            assoc.application_context_name == UID('1.2.840.10008.3.1.1.1'))
        assoc.application_context_name = UID("1.2.840.10008.3.1.1.1")
        self.assertTrue(
            assoc.application_context_name == UID('1.2.840.10008.3.1.1.1'))

        assoc.calling_ae_title = 'ABCD1234ABCD12345'
        self.assertTrue(assoc.calling_ae_title == b'ABCD1234ABCD1234')

        assoc.called_ae_title = 'ABCD1234ABCD12345'
        self.assertTrue(assoc.called_ae_title == b'ABCD1234ABCD1234')
        self.assertTrue(assoc.responding_ae_title == b'ABCD1234ABCD1234')

        max_length = MaximumLengthNegotiation()
        max_length.maximum_length_received = 31222
        assoc.user_information.append(max_length)
        self.assertTrue(
            assoc.user_information[0].maximum_length_received == 31222)

        assoc.user_information = ['a', max_length]
        self.assertEqual(assoc.user_information, [max_length])

        assoc.result = 0
        self.assertTrue(assoc.result == 0)
        assoc.result = 1
        self.assertTrue(assoc.result == 1)
        assoc.result = 2
        self.assertTrue(assoc.result == 2)

        assoc.result_source = 1
        self.assertTrue(assoc.result_source == 1)
        assoc.result_source = 2
        self.assertTrue(assoc.result_source == 2)
        assoc.result_source = 3
        self.assertTrue(assoc.result_source == 3)

        assoc.diagnostic = 1
        self.assertTrue(assoc.diagnostic == 1)
        assoc.diagnostic = 2
        self.assertTrue(assoc.diagnostic == 2)
        assoc.diagnostic = 3
        self.assertTrue(assoc.diagnostic == 3)
        assoc.diagnostic = 7
        self.assertTrue(assoc.diagnostic == 7)

        assoc.calling_presentation_address = ('10.40.94.43', 105)
        self.assertTrue(assoc.calling_presentation_address == ('10.40.94.43',
                                                               105))

        assoc.called_presentation_address = ('10.40.94.44', 106)
        self.assertTrue(assoc.called_presentation_address == ('10.40.94.44',
                                                              106))

        pc = PresentationContext()
        pc.context_id = 1
        assoc.presentation_context_definition_list = [pc]
        self.assertTrue(assoc.presentation_context_definition_list == [pc])
        assoc.presentation_context_definition_list = ['a', pc]
        self.assertTrue(assoc.presentation_context_definition_list == [pc])

        assoc.presentation_context_definition_results_list = [pc]
        self.assertTrue(
            assoc.presentation_context_definition_results_list == [pc])
        assoc.presentation_context_definition_results_list = ['a', pc]
        self.assertTrue(
            assoc.presentation_context_definition_results_list == [pc])

        assoc = A_ASSOCIATE()
        # No maximum_length_received set
        self.assertEqual(assoc.maximum_length_received, None)

        # No MaximumLengthNegotiation present
        assoc.maximum_length_received = 31223
        self.assertTrue(
            assoc.user_information[0].maximum_length_received == 31223)
        self.assertTrue(assoc.maximum_length_received == 31223)

        # MaximumLengthNegotiation already present
        assoc.maximum_length_received = 31224
        self.assertTrue(assoc.maximum_length_received == 31224)

        # No ImplementationClassUIDNegotiation present
        assoc.implementation_class_uid = '1.1.2.3.4'
        self.assertTrue(assoc.user_information[1].implementation_class_uid ==
                        UID('1.1.2.3.4'))
        self.assertTrue(assoc.implementation_class_uid == UID('1.1.2.3.4'))

        # ImplementationClassUIDNegotiation already present
        assoc.implementation_class_uid = '1.1.2.3.4'
        self.assertTrue(assoc.implementation_class_uid == UID('1.1.2.3.4'))