示例#1
0
    def test_callback_receive_c_find(self):
        """Check callback for receiving DIMSE C-FIND messages."""
        # C-FIND-RQ
        primitive = C_FIND()
        primitive.MessageID = 7
        primitive.AffectedSOPClassUID = '1.2.840.10008.5.1.4.1.1.2'
        primitive.AffectedSOPInstanceUID = '1.2.392.200036.9116.2.6.1.48.' \
                                           '1215709044.1459316254.522441'
        primitive.Priority = 0x02
        primitive.MoveOriginatorApplicationEntityTitle = 'UNITTEST_SCP'
        primitive.MoveOriginatorMessageID = 3
        primitive.Identifier = BytesIO()

        # No dataset
        msg = C_FIND_RQ()
        msg.primitive_to_message(primitive)
        self.dimse.debug_receive_c_find_rq(msg)

        # Dataset
        ref_ds = Dataset()
        ref_ds.PatientID = 'Test1101'
        ref_ds.PatientName = "Tube HeNe"

        primitive.Identifier = BytesIO(encode(ref_ds, True, True))

        msg = C_FIND_RQ()
        msg.primitive_to_message(primitive)
        # Dataset
        self.dimse.debug_receive_c_find_rq(msg)

        # C-FIND-RSP
        primitive = C_FIND()
        primitive.MessageIDBeingRespondedTo = 7
        primitive.AffectedSOPClassUID = '1.2.840.10008.5.1.4.1.1.2'
        primitive.AffectedSOPInstanceUID = '1.2.392.200036.9116.2.6.1.48.' \
                                           '1215709044.1459316254.522441'
        primitive.MoveOriginatorApplicationEntityTitle = 'UNITTEST_SCP'
        primitive.MoveOriginatorMessageID = 3
        primitive.Identifier = BytesIO()

        # No dataset
        primitive.Status = 0x0000  # Must be for pending

        msg = C_FIND_RSP()
        msg.primitive_to_message(primitive)
        self.dimse.debug_receive_c_find_rsp(msg)

        primitive.Identifier = BytesIO(encode(ref_ds, True, True))
        msg = C_FIND_RSP()
        msg.primitive_to_message(primitive)
        # Dataset
        msg.data_set = BytesIO(encode(ref_ds, True, True))
        self.dimse.debug_receive_c_find_rsp(msg)

        # Non-pending status
        msg.data_set.Status = 0x0001
        self.dimse.debug_receive_c_find_rsp(msg)

        # C-CANCEL-FIND-RQ
        self.dimse.debug_receive_c_cancel_rq(msg)
示例#2
0
    def test_callback_receive_c_store(self):
        """Check callback for sending DIMSE C-STORE messages."""
        # C-STORE-RQ
        primitive = C_STORE()
        primitive.MessageID = 7
        primitive.AffectedSOPClassUID = '1.2.840.10008.5.1.4.1.1.2'
        primitive.AffectedSOPInstanceUID = '1.2.392.200036.9116.2.6.1.48.' \
                                           '1215709044.1459316254.522441'
        primitive.Priority = 0x02
        primitive.MoveOriginatorApplicationEntityTitle = 'UNITTEST_SCP'
        primitive.MoveOriginatorMessageID = 3
        primitive.DataSet = BytesIO()

        # No dataset
        msg = C_STORE_RQ()
        msg.primitive_to_message(primitive)
        self.dimse.debug_receive_c_store_rq(msg)

        # Dataset
        ref_ds = Dataset()
        ref_ds.PatientID = 'Test1101'
        ref_ds.PatientName = "Tube HeNe"

        primitive.DataSet = BytesIO(encode(ref_ds, True, True))

        msg = C_STORE_RQ()
        msg.primitive_to_message(primitive)
        # Dataset
        self.dimse.debug_receive_c_store_rq(msg)

        # C-STORE-RSP
        primitive = C_STORE()
        primitive.MessageIDBeingRespondedTo = 7
        primitive.AffectedSOPClassUID = '1.2.840.10008.5.1.4.1.1.2'
        primitive.AffectedSOPInstanceUID = '1.2.392.200036.9116.2.6.1.48.' \
                                           '1215709044.1459316254.522441'
        primitive.MoveOriginatorApplicationEntityTitle = 'UNITTEST_SCP'
        primitive.MoveOriginatorMessageID = 3
        primitive.DataSet = BytesIO()

        # Check statuses + no dataset
        for status in [0x0000, 0xb000, 0xb007, 0xb006, 0xa700, 0xa900, 0xc000]:
            primitive.Status = status
            msg = C_STORE_RSP()
            msg.primitive_to_message(primitive)
            self.dimse.debug_receive_c_store_rsp(msg)

        # Dataset
        ref_ds = Dataset()
        ref_ds.PatientID = 'Test1101'
        ref_ds.PatientName = "Tube HeNe"

        msg = C_STORE_RSP()
        msg.primitive_to_message(primitive)
        # Dataset
        msg.data_set = BytesIO(encode(ref_ds, True, True))
        self.dimse.debug_receive_c_store_rsp(msg)
示例#3
0
    def test_assignment(self):
        """ Check assignment works correctly """
        primitive = N_EVENT_REPORT()

        # AffectedSOPClassUID
        primitive.AffectedSOPClassUID = '1.1.1'
        assert primitive.AffectedSOPClassUID == UID('1.1.1')
        assert isinstance(primitive.AffectedSOPClassUID, UID)
        primitive.AffectedSOPClassUID = UID('1.1.2')
        assert primitive.AffectedSOPClassUID == UID('1.1.2')
        assert isinstance(primitive.AffectedSOPClassUID, UID)
        primitive.AffectedSOPClassUID = b'1.1.3'
        assert primitive.AffectedSOPClassUID == UID('1.1.3')
        assert isinstance(primitive.AffectedSOPClassUID, UID)

        # AffectedSOPInstanceUID
        primitive.AffectedSOPInstanceUID = b'1.2.1'
        assert primitive.AffectedSOPInstanceUID == UID('1.2.1')
        assert isinstance(primitive.AffectedSOPClassUID, UID)
        primitive.AffectedSOPInstanceUID = UID('1.2.2')
        assert primitive.AffectedSOPInstanceUID == UID('1.2.2')
        assert isinstance(primitive.AffectedSOPClassUID, UID)
        primitive.AffectedSOPInstanceUID = '1.2.3'
        assert primitive.AffectedSOPInstanceUID == UID('1.2.3')
        assert isinstance(primitive.AffectedSOPClassUID, UID)

        # Event Information
        ds = Dataset()
        ds.PatientID = '1234567'
        primitive.EventInformation = BytesIO(encode(ds, True, True))
        ds = decode(primitive.EventInformation, True, True)
        assert ds.PatientID == '1234567'

        # Event Reply
        ds = Dataset()
        ds.PatientID = '123456'
        primitive.EventReply = BytesIO(encode(ds, True, True))
        ds = decode(primitive.EventReply, True, True)
        assert ds.PatientID == '123456'

        # Event Type ID
        primitive.EventTypeID = 0x0000
        assert primitive.EventTypeID == 0x0000

        # MessageID
        primitive.MessageID = 11
        assert 11 == primitive.MessageID

        # MessageIDBeingRespondedTo
        primitive.MessageIDBeingRespondedTo = 13
        assert 13 == primitive.MessageIDBeingRespondedTo

        # Status
        primitive.Status = 0x0000
        assert primitive.Status == 0x0000
示例#4
0
    def test_implicit_little(self):
        """Test encoding using implicit VR little endian."""
        ds = Dataset()
        ds.PatientName = 'CITIZEN^Snips'
        ds_enc = encode(ds, True, True)
        assert ds_enc == (b'\x10\x00\x10\x00\x0e\x00\x00\x00\x43\x49'
                          b'\x54\x49\x5a\x45\x4e\x5e\x53\x6e\x69\x70'
                          b'\x73\x20')

        ds.PerimeterValue = 10
        ds_enc = encode(ds, True, True)
        assert ds_enc is None
示例#5
0
    def test_explicit_big(self):
        """Test encoding using explicit VR big endian."""
        ds = Dataset()
        ds.PatientName = 'CITIZEN^Snips'
        ds_enc = encode(ds, False, False)
        assert ds_enc == (b'\x00\x10\x00\x10\x50\x4e\x00\x0e\x43\x49'
                          b'\x54\x49\x5a\x45\x4e\x5e\x53\x6e\x69\x70'
                          b'\x73\x20')

        ds.PerimeterValue = 10
        ds_enc = encode(ds, False, False)
        assert ds_enc is None
示例#6
0
    def test_explicit_little(self):
        """Test encoding using explicit VR little endian."""
        ds = Dataset()
        ds.PatientName = "CITIZEN^Snips"
        ds_enc = encode(ds, False, True)
        assert ds_enc == (
            b"\x10\x00\x10\x00\x50\x4e\x0e\x00\x43\x49"
            b"\x54\x49\x5a\x45\x4e\x5e\x53\x6e\x69\x70"
            b"\x73\x20"
        )

        ds.PerimeterValue = 10
        ds_enc = encode(ds, False, True)
        assert ds_enc is None
示例#7
0
    def test_conversion_rq(self):
        """ Check conversion to a -RQ PDU produces the correct output """
        primitive = C_MOVE()
        primitive.MessageID = 7
        primitive.AffectedSOPClassUID = '1.2.840.10008.5.1.4.1.1.2'
        primitive.Priority = 0x02
        primitive.MoveDestination = validate_ae_title("MOVE_SCP")

        ref_identifier = Dataset()
        ref_identifier.PatientID = '*'
        ref_identifier.QueryRetrieveLevel = "PATIENT"

        primitive.Identifier = BytesIO(encode(ref_identifier, True, True))

        dimse_msg = C_MOVE_RQ()
        dimse_msg.primitive_to_message(primitive)

        pdvs = []
        for fragment in dimse_msg.encode_msg(1, 16382):
            pdvs.append(fragment)

        cs_pdv = pdvs[0].presentation_data_value_list[0][1]
        ds_pdv = pdvs[1].presentation_data_value_list[0][1]
        assert cs_pdv == c_move_rq_cmd
        assert ds_pdv == c_move_rq_ds
示例#8
0
    def test_conversion_rsp(self):
        """Check conversion to a -RSP PDU produces the correct output"""
        primitive = C_FIND()
        primitive.MessageIDBeingRespondedTo = 5
        primitive.AffectedSOPClassUID = "1.2.840.10008.5.1.4.1.1.2"
        primitive.Status = 0xFF00

        ref_identifier = Dataset()
        ref_identifier.QueryRetrieveLevel = "PATIENT"
        ref_identifier.RetrieveAETitle = "FINDSCP"
        ref_identifier.PatientName = "ANON^A^B^C^D"

        primitive.Identifier = BytesIO(encode(ref_identifier, True, True))

        dimse_msg = C_FIND_RSP()
        dimse_msg.primitive_to_message(primitive)

        pdvs = []
        for fragment in dimse_msg.encode_msg(1, 16382):
            pdvs.append(fragment)
        cs_pdv = pdvs[0].presentation_data_value_list[0][1]
        ds_pdv = pdvs[1].presentation_data_value_list[0][1]
        assert cs_pdv == c_find_rsp_cmd
        # print(len(ds_pdv), len(c_find_rsp_ds))
        # print(' '.join([f"{b:02X}" for b in ds_pdv]))
        # print(' '.join([f"{b:02X}" for b in c_find_rsp_ds]))
        assert ds_pdv == c_find_rsp_ds
示例#9
0
    def test_conversion_rsp(self):
        """ Check conversion to a -RSP PDU produces the correct output """
        primitive = C_MOVE()
        primitive.MessageIDBeingRespondedTo = 5
        primitive.AffectedSOPClassUID = '1.2.840.10008.5.1.4.1.1.2'
        primitive.Status = 0xFF00
        primitive.NumberOfRemainingSuboperations = 3
        primitive.NumberOfCompletedSuboperations = 1
        primitive.NumberOfFailedSuboperations = 2
        primitive.NumberOfWarningSuboperations = 4

        ref_identifier = Dataset()
        ref_identifier.QueryRetrieveLevel = "PATIENT"
        ref_identifier.PatientID = "*"

        primitive.Identifier = BytesIO(encode(ref_identifier, True, True))

        dimse_msg = C_MOVE_RSP()
        dimse_msg.primitive_to_message(primitive)

        pdvs = []
        for fragment in dimse_msg.encode_msg(1, 16382):
            pdvs.append(fragment)
        cs_pdv = pdvs[0].presentation_data_value_list[0][1]
        ds_pdv = pdvs[1].presentation_data_value_list[0][1]
        assert cs_pdv == c_move_rsp_cmd
        assert ds_pdv == c_move_rsp_ds
示例#10
0
    def test_conversion_rsp(self):
        """ Check conversion to a -RSP PDU produces the correct output """
        primitive = N_ACTION()
        primitive.MessageIDBeingRespondedTo = 5
        primitive.AffectedSOPClassUID = '1.2.4.10'
        primitive.AffectedSOPInstanceUID = '1.2.4.5.7.8'
        primitive.Status = 0x0000
        primitive.ActionTypeID = 1

        ds = Dataset()
        ds.PatientID = 'Test1101'
        ds.PatientName = "Tube HeNe"

        primitive.ActionReply = BytesIO(encode(ds, True, True))

        dimse_msg = N_ACTION_RSP()
        dimse_msg.primitive_to_message(primitive)

        pdvs = []
        for fragment in dimse_msg.encode_msg(1, 16382):
            pdvs.append(fragment)

        assert len(pdvs) == 2
        cs_pdv = pdvs[0].presentation_data_value_list[0][1]
        ds_pdv = pdvs[1].presentation_data_value_list[0][1]

        assert cs_pdv == n_action_rsp_cmd
        assert ds_pdv == n_action_rsp_ds
示例#11
0
    def test_conversion_rq(self):
        """ Check conversion to a -RQ PDU produces the correct output """
        primitive = N_ACTION()
        primitive.MessageID = 7
        primitive.RequestedSOPClassUID = '1.2.840.10008.5.1.4.1.1.2'
        primitive.RequestedSOPInstanceUID = '1.2.392.200036.9116.2.6.1.48'
        primitive.ActionTypeID = 1

        ds = Dataset()
        ds.PatientID = 'Test1101'
        ds.PatientName = "Tube HeNe"

        primitive.ActionInformation = BytesIO(encode(ds, True, True))

        dimse_msg = N_ACTION_RQ()
        dimse_msg.primitive_to_message(primitive)

        pdvs = []
        for fragment in dimse_msg.encode_msg(1, 16382):
            pdvs.append(fragment)

        assert len(pdvs) == 2
        cs_pdv = pdvs[0].presentation_data_value_list[0][1]
        ds_pdv = pdvs[1].presentation_data_value_list[0][1]

        assert cs_pdv == n_action_rq_cmd
        assert ds_pdv == n_action_rq_ds
示例#12
0
    def test_conversion_rq(self):
        """ Check conversion to a -RQ PDU produces the correct output """
        primitive = C_STORE()
        primitive.MessageID = 7
        primitive.AffectedSOPClassUID = '1.2.840.10008.5.1.4.1.1.2'
        primitive.AffectedSOPInstanceUID = '1.2.392.200036.9116.2.6.1.48.' \
                                           '1215709044.1459316254.522441'
        primitive.Priority = 0x02
        primitive.MoveOriginatorApplicationEntityTitle = 'UNITTEST_SCP'
        primitive.MoveOriginatorMessageID = 3

        ref_ds = Dataset()
        ref_ds.PatientID = 'Test1101'
        ref_ds.PatientName = "Tube HeNe"

        primitive.DataSet = BytesIO(encode(ref_ds, True, True))

        dimse_msg = C_STORE_RQ()
        dimse_msg.primitive_to_message(primitive)

        pdvs = []
        for fragment in dimse_msg.encode_msg(1, 16382):
            pdvs.append(fragment)
        cs_pdv = pdvs[0].presentation_data_value_list[0][1]
        ds_pdv = pdvs[1].presentation_data_value_list[0][1]
        assert cs_pdv == c_store_rq_cmd_b
        assert ds_pdv == c_store_rq_ds_b
示例#13
0
    def test_assignment(self):
        """ Check assignment works correctly """
        primitive = C_STORE()

        primitive.MessageID = 11
        assert primitive.MessageID == 11

        primitive.MessageIDBeingRespondedTo = 13
        assert primitive.MessageIDBeingRespondedTo == 13

        # AffectedSOPClassUID
        primitive.AffectedSOPClassUID = '1.1.1'
        assert primitive.AffectedSOPClassUID == UID('1.1.1')
        assert isinstance(primitive.AffectedSOPClassUID, UID)
        primitive.AffectedSOPClassUID = UID('1.1.2')
        assert primitive.AffectedSOPClassUID == UID('1.1.2')
        assert isinstance(primitive.AffectedSOPClassUID, UID)
        primitive.AffectedSOPClassUID = b'1.1.3'
        assert primitive.AffectedSOPClassUID == UID('1.1.3')
        assert isinstance(primitive.AffectedSOPClassUID, UID)

        # AffectedSOPInstanceUID
        primitive.AffectedSOPInstanceUID = b'1.2.1'
        assert primitive.AffectedSOPInstanceUID == UID('1.2.1')
        assert isinstance(primitive.AffectedSOPClassUID, UID)
        primitive.AffectedSOPInstanceUID = UID('1.2.2')
        assert primitive.AffectedSOPInstanceUID == UID('1.2.2')
        assert isinstance(primitive.AffectedSOPClassUID, UID)
        primitive.AffectedSOPInstanceUID = '1.2.3'
        assert primitive.AffectedSOPInstanceUID == UID('1.2.3')
        assert isinstance(primitive.AffectedSOPClassUID, UID)

        primitive.Priority = 0x02
        assert primitive.Priority == 0x02

        primitive.MoveOriginatorApplicationEntityTitle = 'UNITTEST_SCP'
        assert primitive.MoveOriginatorApplicationEntityTitle == b'UNITTEST_SCP    '
        primitive.MoveOriginatorApplicationEntityTitle = b'UNITTEST_SCP'
        assert primitive.MoveOriginatorApplicationEntityTitle == b'UNITTEST_SCP    '

        primitive.MoveOriginatorMessageID = 15
        assert primitive.MoveOriginatorMessageID == 15

        ref_ds = Dataset()
        ref_ds.PatientID = 1234567

        primitive.DataSet = BytesIO(encode(ref_ds, True, True))
        #assert primitive.DataSet, ref_ds)

        primitive.Status = 0x0000
        assert primitive.Status == 0x0000

        primitive.Status = 0xC123
        assert primitive.Status == 0xC123

        primitive.Status = 0xEE01
        assert primitive.Status == 0xEE01
示例#14
0
 def setup(self):
     primitive = C_STORE()
     primitive.MessageID = 7
     primitive.AffectedSOPClassUID = '1.1.1'
     primitive.AffectedSOPInstanceUID = '1.2.1'
     primitive.Priority = 0x02
     primitive.MoveOriginatorApplicationEntityTitle = b'UNITTEST'
     primitive.MoveOriginatorMessageID = 3
     primitive.DataSet = BytesIO(encode(DATASET, True, True))
     self.msg = C_STORE_RQ()
     self.msg.primitive_to_message(primitive)
示例#15
0
    def handle(event):
        if write_ds == 1:
            with tempfile.TemporaryFile('w+b') as tfile:
                ds = event.dataset
                ds.file_meta = event.file_meta
                ds.save_as(tfile)
        elif write_ds in (2, 3):
            with tempfile.TemporaryFile('w+b') as tfile:
                tfile.write(encode(event.file_meta, False, True))
                tfile.write(event.request.DataSet.getvalue())

        return 0x0000
示例#16
0
 def setup(self):
     """Run prior to each test"""
     primitive = C_STORE()
     primitive.MessageID = 7
     primitive.AffectedSOPClassUID = '1.1.1'
     primitive.AffectedSOPInstanceUID = '1.2.1'
     primitive.Priority = 0x02
     primitive.MoveOriginatorApplicationEntityTitle = b'UNITTEST'
     primitive.MoveOriginatorMessageID = 3
     primitive.DataSet = BytesIO(encode(DATASET, True, True))
     msg = C_STORE_RQ()
     msg.primitive_to_message(primitive)
     self.fragments = msg.encode_msg(1, 16382)
示例#17
0
    def _set_command_group_length(self):
        """Reset the Command Group Length element value.

        Once the `command_set` Dataset has been built and filled with
        values, this should be called to set the (Command Group Length* element
        value correctly.
        """
        # Remove CommandGroupLength to stop it messing up the length calc
        del self.command_set.CommandGroupLength

        # The Command Set is always Implicit VR Little Endian
        self.command_set.CommandGroupLength = len(
            encode(self.command_set, True, True))
示例#18
0
    def test_encode(self):
        """Test encoding of a DIMSE message."""
        primitive = C_STORE()
        primitive.MessageID = 7
        primitive.AffectedSOPClassUID = "1.1.1"
        primitive.AffectedSOPInstanceUID = "1.2.1"
        primitive.Priority = 0x02
        primitive.MoveOriginatorApplicationEntityTitle = "UNITTEST"
        primitive.MoveOriginatorMessageID = 3

        # Test encode without dataset
        dimse_msg = C_STORE_RQ()
        dimse_msg.primitive_to_message(primitive)
        p_data_list = []
        for pdata in dimse_msg.encode_msg(12, 16):
            p_data_list.append(pdata)
        assert p_data_list[0].presentation_data_value_list[0][1][
            0:1] == b"\x01"
        assert p_data_list[-1].presentation_data_value_list[0][1][
            0:1] == b"\x03"
        assert dimse_msg.context_id == 12

        # Test encode with dataset
        ds = Dataset()
        ds.PatientID = "Test1101"
        ds.PatientName = "Tube^HeNe"
        primitive.DataSet = BytesIO(encode(ds, True, True))

        dimse_msg = C_STORE_RQ()
        dimse_msg.primitive_to_message(primitive)
        p_data_list = []
        for pdata in dimse_msg.encode_msg(13, 10):
            p_data_list.append(pdata)

        assert p_data_list[0].presentation_data_value_list[0][1][
            0:1] == b"\x01"
        assert p_data_list[-1].presentation_data_value_list[0][1][
            0:1] == b"\x02"
        assert p_data_list[-2].presentation_data_value_list[0][1][
            0:1] == b"\x00"
        assert p_data_list[-10].presentation_data_value_list[0][1][
            0:1] == b"\x03"
        assert dimse_msg.context_id == 13

        p_data_list = []
        for pdata in dimse_msg.encode_msg(1, 31682):
            p_data_list.append(pdata)
        assert p_data_list[0].presentation_data_value_list[0][
            1] == c_store_rq_cmd
        assert p_data_list[1].presentation_data_value_list[0][1] == c_store_ds
示例#19
0
    def test_assignment(self):
        """ Check assignment works correctly """
        primitive = C_GET()

        primitive.MessageID = 11
        assert primitive.MessageID == 11

        primitive.MessageIDBeingRespondedTo = 13
        assert primitive.MessageIDBeingRespondedTo == 13

        # AffectedSOPClassUID
        primitive.AffectedSOPClassUID = '1.1.1'
        assert primitive.AffectedSOPClassUID == UID('1.1.1')
        assert isinstance(primitive.AffectedSOPClassUID, UID)
        primitive.AffectedSOPClassUID = UID('1.1.2')
        assert primitive.AffectedSOPClassUID == UID('1.1.2')
        assert isinstance(primitive.AffectedSOPClassUID, UID)
        primitive.AffectedSOPClassUID = b'1.1.3'
        assert primitive.AffectedSOPClassUID == UID('1.1.3')
        assert isinstance(primitive.AffectedSOPClassUID, UID)

        primitive.Priority = 0x02
        assert primitive.Priority == 0x02

        ref_ds = Dataset()
        ref_ds.PatientID = 1234567

        primitive.Identifier = BytesIO(encode(ref_ds, True, True))
        #assert primitive.DataSet, ref_ds)

        primitive.Status = 0x0000
        assert primitive.Status == 0x0000

        primitive.Status = 0xC123
        assert primitive.Status == 0xC123

        primitive.Status = 0xEE01
        assert primitive.Status == 0xEE01

        primitive.NumberOfRemainingSuboperations = 1
        assert primitive.NumberOfRemainingSuboperations == 1

        primitive.NumberOfCompletedSuboperations = 2
        assert primitive.NumberOfCompletedSuboperations == 2

        primitive.NumberOfFailedSuboperations = 3
        assert primitive.NumberOfFailedSuboperations == 3

        primitive.NumberOfWarningSuboperations = 4
        assert primitive.NumberOfWarningSuboperations == 4
示例#20
0
    def test_is_valid_request(self):
        """Test N_SET.is_valid_request"""
        primitive = N_SET()
        assert not primitive.is_valid_request
        primitive.MessageID = 1
        assert not primitive.is_valid_request
        primitive.RequestedSOPClassUID = '1.2'
        assert not primitive.is_valid_request
        primitive.RequestedSOPInstanceUID = '1.2.1'
        assert not primitive.is_valid_request
        ds = Dataset()
        ds.PatientID = 'Test1101'
        ds.PatientName = "Tube HeNe"

        primitive.ModificationList = BytesIO(encode(ds, True, True))
        assert primitive.is_valid_request
示例#21
0
    def test_decode(self):
        """Test decoding of a DIMSE message."""
        primitive = C_STORE()
        primitive.MessageID = 7
        primitive.AffectedSOPClassUID = "1.1.1"
        primitive.AffectedSOPInstanceUID = "1.2.1"
        primitive.Priority = 0x02
        primitive.MoveOriginatorApplicationEntityTitle = "UNITTEST"
        primitive.MoveOriginatorMessageID = 3
        ds = Dataset()
        ds.PatientID = "Test1101"
        ds.PatientName = "Tube^HeNe"
        primitive.DataSet = BytesIO(encode(ds, True, True))
        dimse_msg = C_STORE_RQ()
        dimse_msg.primitive_to_message(primitive)

        # CMD: (1x4, 3x1), DS: (0x1, 2x1)
        p_data = dimse_msg.encode_msg(12, 24)

        # Command set decoding
        dimse_msg.decode_msg(next(p_data))  # MCHB 1
        dimse_msg.decode_msg(next(p_data))  # MCHB 1
        dimse_msg.decode_msg(next(p_data))  # MCHB 1
        dimse_msg.decode_msg(next(p_data))  # MCHB 1
        dimse_msg.decode_msg(next(p_data))  # MCHB 3 - end of command set
        assert dimse_msg.__class__ == C_STORE_RQ

        # Test decoded command set
        cs = dimse_msg.command_set
        assert cs.CommandGroupLength == 94
        assert cs.AffectedSOPClassUID == UID("1.1.1")
        assert cs.AffectedSOPInstanceUID == UID("1.2.1")
        assert cs.Priority == 2
        assert cs.CommandDataSetType == 1
        assert cs.CommandField == 1
        assert cs.MoveOriginatorApplicationEntityTitle == "UNITTEST"
        assert cs.MoveOriginatorMessageID == 3

        # Test decoded dataset
        dimse_msg.decode_msg(next(p_data))  # MCHB 1 # MCHB 0
        dimse_msg.decode_msg(next(p_data))  # MCHB 1 # MCHB 2
        assert dimse_msg.data_set.getvalue() == c_store_ds[1:]

        # Test returns false
        msg = C_STORE_RSP()
        assert not msg.decode_msg(c_store_rsp_cmd)
示例#22
0
    def test_assignment(self):
        """ Check assignment works correctly """
        primitive = N_CREATE()

        # AffectedSOPClassUID
        primitive.AffectedSOPClassUID = '1.1.1'
        assert primitive.AffectedSOPClassUID == UID('1.1.1')
        assert isinstance(primitive.AffectedSOPClassUID, UID)
        primitive.AffectedSOPClassUID = UID('1.1.2')
        assert primitive.AffectedSOPClassUID == UID('1.1.2')
        assert isinstance(primitive.AffectedSOPClassUID, UID)
        primitive.AffectedSOPClassUID = b'1.1.3'
        assert primitive.AffectedSOPClassUID == UID('1.1.3')
        assert isinstance(primitive.AffectedSOPClassUID, UID)

        # AffectedSOPInstanceUID
        primitive.AffectedSOPInstanceUID = b'1.2.1'
        assert primitive.AffectedSOPInstanceUID == UID('1.2.1')
        assert isinstance(primitive.AffectedSOPClassUID, UID)
        primitive.AffectedSOPInstanceUID = UID('1.2.2')
        assert primitive.AffectedSOPInstanceUID == UID('1.2.2')
        assert isinstance(primitive.AffectedSOPClassUID, UID)
        primitive.AffectedSOPInstanceUID = '1.2.3'
        assert primitive.AffectedSOPInstanceUID == UID('1.2.3')
        assert isinstance(primitive.AffectedSOPClassUID, UID)

        # AttributeList
        ref_ds = Dataset()
        ref_ds.PatientID = '1234567'
        primitive.AttributeList = BytesIO(encode(ref_ds, True, True))
        ds = decode(primitive.AttributeList, True, True)
        assert ds.PatientID == '1234567'

        # MessageID
        primitive.MessageID = 11
        assert 11 == primitive.MessageID

        # MessageIDBeingRespondedTo
        primitive.MessageIDBeingRespondedTo = 13
        assert 13 == primitive.MessageIDBeingRespondedTo

        # Status
        primitive.Status = 0x0000
        assert primitive.Status == 0x0000
示例#23
0
    def test_assignment(self):
        """ Check assignment works correctly """
        primitive = C_MOVE()

        primitive.MessageID = 11
        assert primitive.MessageID == 11

        primitive.MessageIDBeingRespondedTo = 13
        assert primitive.MessageIDBeingRespondedTo == 13

        # AffectedSOPClassUID
        primitive.AffectedSOPClassUID = '1.1.1'
        assert primitive.AffectedSOPClassUID == UID('1.1.1')
        assert isinstance(primitive.AffectedSOPClassUID, UID)
        primitive.AffectedSOPClassUID = UID('1.1.2')
        assert primitive.AffectedSOPClassUID == UID('1.1.2')
        assert isinstance(primitive.AffectedSOPClassUID, UID)
        primitive.AffectedSOPClassUID = b'1.1.3'
        assert primitive.AffectedSOPClassUID == UID('1.1.3')
        assert isinstance(primitive.AffectedSOPClassUID, UID)

        primitive.Priority = 0x02
        assert primitive.Priority == 0x02

        primitive.MoveDestination = 'UNITTEST_SCP'
        assert primitive.MoveDestination == b'UNITTEST_SCP    '

        ref_ds = Dataset()
        ref_ds.PatientID = 1234567

        primitive.Identifier = BytesIO(encode(ref_ds, True, True))
        #assert primitive.DataSet, ref_ds)

        primitive.Status = 0x0000
        assert primitive.Status == 0x0000

        primitive.Status = 0xC123
        assert primitive.Status == 0xC123

        primitive.Status = 0xEE01
        assert primitive.Status == 0xEE01
示例#24
0
    def test_cstore_rq(self):
        """Test creation of a DIMSE Message from a primitive works OK."""
        # Testing that primitive_to_message doesn't affect the original class
        #   definition
        req = C_STORE()
        req.MessageID = 12
        req.AffectedSOPClassUID = self.ds.SOPClassUID
        req.AffectedSOPInstanceUID = self.ds.SOPInstanceUID
        req.Priority = 0x02
        req.MoveOriginatorApplicationEntityTitle = None
        req.MoveOriginatorMessageID = None
        req.DataSet = BytesIO(encode(self.ds, True, True))

        msg = C_STORE_RQ()
        msg.primitive_to_message(req)
        cs = msg.command_set
        assert cs.CommandGroupLength == 88
        assert cs.AffectedSOPClassUID == "1.2.840.10008.5.1.4.1.1"
        assert cs.CommandField == 1
        assert cs.MessageID == 12
        assert cs.Priority == 2
        assert cs.CommandDataSetType == 1
        assert cs.AffectedSOPInstanceUID == "1.2.3.4"
        assert "MoveOriginatorApplicationEntityTitle" not in cs
        assert "MoveOriginatorMessageID" not in cs
        assert msg.data_set.getvalue() != b""

        # Test new class instance is OK
        msg = C_STORE_RQ()
        cs = msg.command_set
        ds = msg.data_set
        assert cs.CommandGroupLength is None
        assert cs.AffectedSOPClassUID in ["", None]  # pydicom upstream change
        assert cs.CommandField is None
        assert cs.MessageID is None
        assert cs.Priority is None
        assert cs.CommandDataSetType is None
        assert cs.AffectedSOPInstanceUID in ["", None]
        assert cs.MoveOriginatorApplicationEntityTitle is None
        assert cs.MoveOriginatorMessageID is None
        assert ds.getvalue() == b""
示例#25
0
    def test_callback_receive_c_move(self):
        """Check callback for receiving DIMSE C-MOVE messages."""
        # C-MOVE-RQ
        msg = C_MOVE_RQ()
        self.dimse.debug_receive_c_move_rq(msg)

        # C-MOVE-RSP
        primitive = C_MOVE()
        primitive.MessageIDBeingRespondedTo = 7
        primitive.AffectedSOPClassUID = '1.2.840.10008.5.1.4.1.1.2'
        primitive.AffectedSOPInstanceUID = '1.2.392.200036.9116.2.6.1.48.' \
                                           '1215709044.1459316254.522441'
        primitive.MoveOriginatorApplicationEntityTitle = 'UNITTEST_SCP'
        primitive.MoveOriginatorMessageID = 3
        primitive.Identifier = BytesIO()
        primitive.NumberOfCompletedSuboperations = 1
        primitive.NumberOfWarningSuboperations = 3
        primitive.NumberOfFailedSuboperations = 4

        # No dataset, remaining subops
        primitive.Status = 0x0000  # Must be for pending
        msg = C_MOVE_RSP()
        msg.primitive_to_message(primitive)
        self.dimse.debug_receive_c_move_rsp(msg)

        # Dataset
        ref_ds = Dataset()
        ref_ds.PatientID = 'Test1101'
        ref_ds.PatientName = "Tube HeNe"
        primitive.Identifier = BytesIO(encode(ref_ds, True, True))
        primitive.NumberOfRemainingSuboperations = 2

        msg = C_GET_RSP()

        msg.primitive_to_message(primitive)

        # Dataset
        self.dimse.debug_receive_c_move_rsp(msg)

        # C-CANCEL-MOVE-RQ
        self.dimse.debug_receive_c_cancel_rq(msg)
示例#26
0
    def test_encode_zero(self):
        """Test encoding with a 0 max pdu length."""
        primitive = C_STORE()
        primitive.MessageID = 7
        primitive.AffectedSOPClassUID = '1.1.1'
        primitive.AffectedSOPInstanceUID = '1.2.1'
        primitive.Priority = 0x02
        primitive.MoveOriginatorApplicationEntityTitle = 'UNITTEST'
        primitive.MoveOriginatorMessageID = 3

        # Test encode without dataset
        dimse_msg = C_STORE_RQ()
        dimse_msg.primitive_to_message(primitive)
        p_data_list = []
        for pdata in dimse_msg.encode_msg(12, 0):
            p_data_list.append(pdata)
        assert p_data_list[0].presentation_data_value_list[0][1][
            0:1] == b'\x03'
        assert dimse_msg.context_id == 12

        # Test encode with dataset
        ds = Dataset()
        ds.PatientID = 'Test1101'
        ds.PatientName = 'Tube^HeNe'
        primitive.DataSet = BytesIO(encode(ds, True, True))

        dimse_msg = C_STORE_RQ()
        dimse_msg.primitive_to_message(primitive)
        p_data_list = []
        for pdata in dimse_msg.encode_msg(13, 0):
            p_data_list.append(pdata)

        assert p_data_list[0].presentation_data_value_list[0][1][
            0:1] == b'\x03'
        assert p_data_list[0].presentation_data_value_list[0][
            1] == c_store_rq_cmd
        assert p_data_list[1].presentation_data_value_list[0][1][
            0:1] == b'\x02'
        assert p_data_list[1].presentation_data_value_list[0][1] == c_store_ds
        assert dimse_msg.context_id == 13
示例#27
0
    def test_assignment(self):
        """ Check assignment works correctly """
        primitive = C_FIND()

        primitive.MessageID = 11
        assert primitive.MessageID == 11

        primitive.MessageIDBeingRespondedTo = 13
        assert primitive.MessageIDBeingRespondedTo == 13

        # AffectedSOPClassUID
        primitive.AffectedSOPClassUID = '1.1.1'
        assert primitive.AffectedSOPClassUID == UID('1.1.1')
        assert isinstance(primitive.AffectedSOPClassUID, UID)
        primitive.AffectedSOPClassUID = UID('1.1.2')
        assert primitive.AffectedSOPClassUID == UID('1.1.2')
        assert isinstance(primitive.AffectedSOPClassUID, UID)
        primitive.AffectedSOPClassUID = b'1.1.3'
        assert primitive.AffectedSOPClassUID == UID('1.1.3')
        assert isinstance(primitive.AffectedSOPClassUID, UID)

        primitive.Priority = 0x02
        assert primitive.Priority == 0x02

        ref_ds = Dataset()
        ref_ds.PatientID = '*'
        ref_ds.QueryRetrieveLevel = "PATIENT"

        primitive.Identifier = BytesIO(encode(ref_ds, True, True))
        #assert primitive.DataSet, ref_ds)

        primitive.Status = 0x0000
        assert primitive.Status == 0x0000

        primitive.Status = 0xC123
        assert primitive.Status == 0xC123

        primitive.Status = 0xEE01
        assert primitive.Status == 0xEE01
示例#28
0
    def encode_msg(self, context_id, max_pdu_length):
        """Yield P-DATA primitive(s) for the current DIMSE Message.

        **Encoding**

        The encoding of the Command Set shall be Little Endian Implicit VR,
        while the Data Set will be encoded as per the agreed presentation
        context.

        A P-DATA request PDV List parameter shall contain one or more PDVs.
        Each PDV is wholly contained in a given P-DATA request and doesn't
        span across several P-DATA request primitives.

        The fragmentation of any message results in a series of PDVs that shall
        be sent, on a given association, by a corresponding series of P-DATA
        requests preserving the ordering of the fragments of any message.
        No fragments of any other messages shall be sent until all fragments
        of the current message have been sent.

        Parameters
        ----------
        context_id : int
            The ID of the agreed presentation context.
        max_pdu_length : int
            The maximum PDV length in bytes.

        Yields
        ------
        pdu_primitives.P_DATA
            The current DIMSE message as one or more P-DATA service
            primitives.

        References
        ----------

        * DICOM Standard, Part 7, Section 6.3.1
        * DICOM Standard, Part 8, Annex E
        """
        self.context_id = context_id

        # The Command Set is always Little Endian Implicit VR (PS3.7 6.3.1)
        #   encode(dataset, is_implicit_VR, is_little_endian)
        encoded_command_set = encode(self.command_set, True, True)

        # COMMAND SET (always)
        # Split the command set into fragments with maximum size max_pdu_length
        if max_pdu_length == 0:
            no_fragments = 1
        else:
            no_fragments = ceil(
                len(encoded_command_set) / (max_pdu_length - 6))

        cmd_fragments = self._generate_pdv_fragments(encoded_command_set,
                                                     max_pdu_length)

        # First to (n - 1)th command data fragment - bits xxxxxx01
        for ii in range(int(no_fragments - 1)):
            pdata = P_DATA()
            pdata.presentation_data_value_list.append(
                [context_id, b'\x01' + next(cmd_fragments)])
            yield pdata

        # Last command data fragment - bits xxxxxx11
        pdata = P_DATA()
        pdata.presentation_data_value_list.append(
            [context_id, b'\x03' + next(cmd_fragments)])
        yield pdata

        # DATASET (if available)
        #   Check that the Data Set is not empty
        if self.data_set is not None:
            encoded_data_set = self.data_set.getvalue()
            if encoded_data_set:
                # Split the data set into fragments with maximum
                #   size max_pdu_length
                if max_pdu_length == 0:
                    no_fragments = 1
                else:
                    no_fragments = ceil(
                        len(encoded_data_set) / (max_pdu_length - 6))
                ds_fragments = self._generate_pdv_fragments(
                    encoded_data_set, max_pdu_length)

                # First to (n - 1)th dataset fragment - bits xxxxxx00
                for ii in range(int(no_fragments - 1)):
                    pdata = P_DATA()
                    pdata.presentation_data_value_list.append(
                        [context_id, b'\x00' + next(ds_fragments)])
                    yield pdata

                # Last dataset fragment - bits xxxxxx10
                pdata = P_DATA()
                pdata.presentation_data_value_list.append(
                    [context_id, b'\x02' + next(ds_fragments)])
                yield pdata
示例#29
0
    def Encode(self, context_id, max_pdu):
        """
        Encode the DIMSE Message as one or more P-DATA service primitives
        
        PS3.7 6.3.1
        The encoding of the Command Set shall be Little Endian Implicit VR
        
        Parameters
        ----------
        context_id : int
            The ID of the presentation context agreed to under which we are
            sending the data
        max_pdu_length : int
            The maximum PDU length in bytes
            
        Returns
        -------
        p_data_list : list of pynetdicom.primitives.P_DATA
            A list of one or more P-DATA service primitives
        """
        self.ID = context_id
        p_data_list = []
        
        # The Command Set is always Little Endian Implicit VR (PS3.7 6.3.1)
        #   encode(dataset, is_implicit_VR, is_little_endian)
        encoded_command_set = encode(self.command_set, True, True)

        ## COMMAND SET
        # Split the command set into framents with maximum size max_pdu
        pdvs = fragment(max_pdu, encoded_command_set)
        
        # First to (n - 1)th command data fragment - b XXXXXX01
        for ii in pdvs[:-1]:
            pdata = P_DATA()
            pdata.presentation_data_value_list = [[self.ID, pack('b', 1) + ii]]
            
            p_data_list.append(pdata)
        
        # Nth command data fragment - b XXXXXX11
        pdata = P_DATA()
        pdata.presentation_data_value_list = [[self.ID, pack('b', 3) + pdvs[-1]]]
       
        p_data_list.append(pdata)

        ## DATASET (if available)
        # Split out dataset up into fragment with maximum size of max_pdu
        #   Check that the Data Set is not empty
        if self.data_set is None:
            pass
        elif self.data_set.getvalue() != b'':
            # Technically these are APDUs, not PDVs
            pdvs = fragment(max_pdu, self.data_set)

            # First to (n - 1)th dataset fragment - b XXXXXX00
            for ii in pdvs[:-1]:
                pdata = P_DATA()
                pdata.presentation_data_value_list = [[self.ID, pack('b', 0) + ii]]
                p_data_list.append(pdata)
            
            # Nth dataset fragment - b XXXXXX10
            pdata = P_DATA()
            pdata.presentation_data_value_list = \
                                        [[self.ID, pack('b', 2) + pdvs[-1]]]
            
            p_data_list.append(pdata)

        return p_data_list
示例#30
0
 def test_encode_empty(self):
     """Test encoding an empty dataset."""
     out = encode(Dataset(), True, True)
     assert out == b''
示例#31
0
    def encode_msg(self, context_id, max_pdu_length):
        """Yield P-DATA primitives for the current DIMSE Message.

        **Encoding**

        The encoding of the Command Set shall be *Little Endian Implicit VR*,
        while the *Data Set* will be encoded as per the agreed presentation
        context.

        A P-DATA request's PDV List parameter shall contain one or more PDVs.
        Each PDV is wholly contained in a given P-DATA request and doesn't
        span across several P-DATA request primitives.

        The fragmentation of any message results in a series of PDVs that shall
        be sent, on a given association, by a corresponding series of P-DATA
        requests preserving the ordering of the fragments of any message.
        No fragments of any other messages shall be sent until all fragments
        of the current message have been sent.

        Parameters
        ----------
        context_id : int
            The *ID* of the agreed presentation context.
        max_pdu_length : int
            The maximum PDV length (in bytes).

        Yields
        ------
        pdu_primitives.P_DATA
            The current DIMSE message as one or more P-DATA service
            primitives.

        References
        ----------

        * DICOM Standard, Part 7,
          :dcm:`Section 6.3.1<part07/sect_6.3.html#sect_6.3.1>`
        * DICOM Standard, Part 8, :dcm:`Annex E<part08/chapter_E.html>`
        """
        self.context_id = context_id

        # The Command Set is always Little Endian Implicit VR (PS3.7 6.3.1)
        #   encode(dataset, is_implicit_VR, is_little_endian)
        encoded_command_set = encode(self.command_set, True, True)

        # COMMAND SET (always)
        # Split the command set into fragments with maximum size max_pdu_length
        if max_pdu_length == 0:
            nr_fragments = 1
        else:
            nr_fragments = ceil(
                len(encoded_command_set) / (max_pdu_length - 6))

        cmd_fragments = self._generate_pdv_fragments(encoded_command_set,
                                                     max_pdu_length)

        # First to (n - 1)th command data fragment - bits xxxxxx01
        for ii in range(int(nr_fragments - 1)):
            pdata = P_DATA()
            pdata.presentation_data_value_list.append(
                [context_id, b'\x01' + next(cmd_fragments)])
            yield pdata

        # Last command data fragment - bits xxxxxx11
        pdata = P_DATA()
        pdata.presentation_data_value_list.append(
            [context_id, b'\x03' + next(cmd_fragments)])
        yield pdata

        # DATASET (if available)
        #   Check that the Data Set is not empty
        if self.data_set is not None:
            encoded_data_set = self.data_set.getvalue()
            if encoded_data_set:
                # Split the data set into fragments with maximum
                #   size max_pdu_length
                if max_pdu_length == 0:
                    nr_fragments = 1
                else:
                    nr_fragments = ceil(
                        len(encoded_data_set) / (max_pdu_length - 6))

                ds_fragments = self._generate_pdv_fragments(
                    encoded_data_set, max_pdu_length)

                # First to (n - 1)th dataset fragment - bits xxxxxx00
                for ii in range(int(nr_fragments - 1)):
                    pdata = P_DATA()
                    pdata.presentation_data_value_list.append(
                        [context_id, b'\x00' + next(ds_fragments)])
                    yield pdata

                # Last dataset fragment - bits xxxxxx10
                pdata = P_DATA()
                pdata.presentation_data_value_list.append(
                    [context_id, b'\x02' + next(ds_fragments)])
                yield pdata
        elif self._data_set_file is not None:
            # Read and send encoded dataset from file
            # Buffer size determined by io.DEFAULT_BUFFER_SIZE
            with open(self._data_set_file[0], 'rb') as f:
                end = f.seek(0, 2)
                length = end - f.seek(self._data_set_file[1])

                if max_pdu_length == 0:
                    nr_fragments = 1
                    max_pdu_length = length + 6
                else:
                    nr_fragments = ceil(length / (max_pdu_length - 6))

                # First to (n - 1)th dataset fragment - bits xxxxxx00
                for ii in range(int(nr_fragments - 1)):
                    pdata = P_DATA()
                    pdata.presentation_data_value_list.append(
                        [context_id, b'\x00' + f.read(max_pdu_length - 6)])
                    yield pdata

                # Last dataset fragment - bits xxxxxx10
                pdata = P_DATA()
                pdata.presentation_data_value_list.append(
                    [context_id, b'\x02' + f.read(max_pdu_length - 6)])
                yield pdata