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)
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)
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
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
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
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
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
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
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
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
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
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
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
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)
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
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)
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))
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
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
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
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)
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
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
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""
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)
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
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
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
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
def test_encode_empty(self): """Test encoding an empty dataset.""" out = encode(Dataset(), True, True) assert out == b''
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