Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exception raised converting A-ASSOCIATE-AC PDU to A-ASSOCIATE primitive #361

Closed
ylmzkaan opened this issue Jul 5, 2019 · 6 comments
Closed

Comments

@ylmzkaan
Copy link

ylmzkaan commented Jul 5, 2019

Hi, I know an issue similar to this has been discussed but it did not help.

For test purposes, I want to make a C-MOVE request to ONIS Dicom Server to store ct and mammography images. I added my AE-Title, ip and port to ONIS so it recognizes me. I propose PatientRootQueryRetrieveInformationModelMove context and support CTImageStorage and DigitalMammographyXRayImagePresentationStorage within my AE. However I get the following debug logs that says PatientRootQueryRetrieveInformationModelMove is rejected. In its dicom conformance statement, it is written that ONIS supports PatientRootQueryRetrieveInformationModelMove.

If I don't request PatientRootQueryRetrieveInformationModelMove but VerificationPresentationContexts, association establishes successfully but I can't make a C-MOVE obviously.

Logs:

INFO:root:Server started.
INFO:pynetdicom.assoc:Requesting Association
DEBUG:pynetdicom.events:Request Parameters:
DEBUG:pynetdicom.events:========================= BEGIN A-ASSOCIATE-RQ PDU =========================
DEBUG:pynetdicom.events:Our Implementation Class UID: 1.2.826.0.1.3680043.9.3811.1.3.1
DEBUG:pynetdicom.events:Our Implementation Version Name: PYNETDICOM_131
DEBUG:pynetdicom.events:Application Context Name: 1.2.840.10008.3.1.1.1
DEBUG:pynetdicom.events:Calling Application Name: EGE-AI
DEBUG:pynetdicom.events:Called Application Name: ONIS25
DEBUG:pynetdicom.events:Our Max PDU Receive Size: 16382
DEBUG:pynetdicom.events:Presentation Context:
DEBUG:pynetdicom.events: Context ID: 1 (Proposed)
DEBUG:pynetdicom.events: Abstract Syntax: =Patient Root Query/Retrieve Information Model - MOVE
DEBUG:pynetdicom.events: Proposed SCP/SCU Role: Default
DEBUG:pynetdicom.events: Proposed Transfer Syntaxes:
DEBUG:pynetdicom.events: =Implicit VR Little Endian
DEBUG:pynetdicom.events: =Explicit VR Little Endian
DEBUG:pynetdicom.events: =Explicit VR Big Endian
DEBUG:pynetdicom.events:Requested Extended Negotiation: None
DEBUG:pynetdicom.events:Requested Common Extended Negotiation: None
DEBUG:pynetdicom.events:Requested Asynchronous Operations Window Negotiation: None
DEBUG:pynetdicom.events:Requested User Identity Negotiation: None
DEBUG:pynetdicom.events:========================== END A-ASSOCIATE-RQ PDU ==========================
DEBUG:pynetdicom.events:Accept Parameters:
DEBUG:pynetdicom.events:========================= BEGIN A-ASSOCIATE-AC PDU =========================
DEBUG:pynetdicom.events:Their Implementation Class UID: 1.2.392.200193
DEBUG:pynetdicom.events:Their Implementation Version Name: ONIS_Server 2.5
DEBUG:pynetdicom.events:Application Context Name: 1.2.840.10008.3.1.1.1
DEBUG:pynetdicom.events:Calling Application Name: EGE-AI
DEBUG:pynetdicom.events:Called Application Name: ONIS25
DEBUG:pynetdicom.events:Their Max PDU Receive Size: 16382
DEBUG:pynetdicom.events:Presentation Contexts:
DEBUG:pynetdicom.events: Context ID: 1 (Rejected - Abstract Syntax Not Supported)
DEBUG:pynetdicom.events: Abstract Syntax: =Patient Root Query/Retrieve Information Model - MOVE
DEBUG:pynetdicom.events:Accepted Extended Negotiation: None
DEBUG:pynetdicom.events:Accepted Asynchronous Operations Window Negotiation: None
DEBUG:pynetdicom.events:User Identity Negotiation Response: None
DEBUG:pynetdicom.events:========================== END A-ASSOCIATE-AC PDU ==========================
ERROR:pynetdicom.dul:Exception in DUL.run(), aborting association
ERROR:pynetdicom.dul:list index out of range
Traceback (most recent call last):
File "D:\Ege\DicomServer\venv\lib\site-packages\pynetdicom\dul.py", line 400, in run
elif self._is_transport_event():
File "D:\Ege\DicomServer\venv\lib\site-packages\pynetdicom\dul.py", line 188, in _is_transport_event
self._read_pdu_data()
File "D:\Ege\DicomServer\venv\lib\site-packages\pynetdicom\dul.py", line 324, in _read_pdu_data
self.primitive = self.pdu.to_primitive()
File "D:\Ege\DicomServer\venv\lib\site-packages\pynetdicom\pdu.py", line 892, in to_primitive
item.to_primitive()
File "D:\Ege\DicomServer\venv\lib\site-packages\pynetdicom\pdu_items.py", line 860, in to_primitive
self.transfer_syntax_sub_item[0].transfer_syntax_name
IndexError: list index out of range
ERROR:root:Association rejected, aborted or never connected

Code:

import logging

from pydicom.dataset import Dataset
from pynetdicom import AE, StoragePresentationContexts, evt
from pynetdicom.sop_class import (
    CTImageStorage, DigitalMammographyXRayImagePresentationStorage,
    PatientRootQueryRetrieveInformationModelMove)

from config import AE_TITLE, PEER_AE_TITLE, PEER_IP, PEER_PORT, PORT
from EventHandlers import handle_store

logging.basicConfig(level=logging.DEBUG)


def moveDataset(aeTitle, port, peerAeTitle, peerIP, peerPort, ds):

    ae = _initAE(aeTitle)
    # Start our Storage SCP in non-blocking mode, listening on port 11120
    handlers = [(evt.EVT_C_STORE, handle_store)]
    scp = ae.start_server(('', port), block=False, evt_handlers=handlers)
    logging.info("Server started.")

    try:
        # Associate with peer AE
        assoc = ae.associate(peerIP, peerPort, ae_title=peerAeTitle)
        if assoc.is_established:
            logging.info("Association established")
            _moveDatasetOverAssociation(assoc, ds)
            # Release the association
            assoc.release()
        else:
            logging.error('Association rejected, aborted or never connected')
    finally:
        # Stop Storage SCP
        scp.shutdown()

def _initAE(aeTitle):
    # Initialise the Application Entity
    ae = AE(ae_title=aeTitle)
    ae.add_requested_context(PatientRootQueryRetrieveInformationModelMove)
    # Add the Storage SCP's supported presentation contexts
    ae.add_supported_context(CTImageStorage)
    ae.add_supported_context(DigitalMammographyXRayImagePresentationStorage)
    return ae

def _moveDatasetOverAssociation(assoc, dataset):

    responses = assoc.send_c_move(dataset, assoc.ae.ae_title, query_model='P')

    for (status, identifier) in responses:
        if status:
            logging.debug('C-MOVE query status: 0x{0:04x}'.format(status.Status))

            # If the status is 'Pending' then `identifier` is the C-MOVE response
            if status.Status in (0xFF00, 0xFF01):
                logging.debug(identifier)
        else:
            logging.error('Connection timed out, was aborted or received invalid response')

if __name__ == "__main__":
    # Create out identifier (query) dataset
    ds = Dataset()
    ds.AccessionNumber = 'EU0000688977' # Balkan, Esma
    
    moveDataset(AE_TITLE, PORT, PEER_AE_TITLE, PEER_IP, PEER_PORT,ds)

config.py

AE_TITLE = b'EGE-AI'
PORT = 106

PEER_AE_TITLE = b'ONIS25'
PEER_IP = "127.0.0.1"
PEER_PORT = 104
@scaramallion
Copy link
Member

scaramallion commented Jul 7, 2019

I think this is because the Move SCP isn't sending any Transfer Syntax Sub-Item at all for the rejected presentation context in its A-ASSOCIATE-AC message (which is non-conformant), but I'd like to confirm that's the case. Could you add the following handler to evt.EVT_DATA_RECV on your Move SCU and post the output?

from pynetdicom.utils import pretty_bytes

def handle_data(event):
    slist = pretty_bytes(event.data, prefix='', max_size=None)

    # Only print out the A-ASSOCIATE-AC data
    if slist[0][0:2] == '02':
        for ss in slist:
            print(ss)

I should be able to add a workaround if so.

@scaramallion scaramallion changed the title Rejected - Abstract Syntax: Patient Root Query/Retrieve Information Model - MOVE Exception raised decoding rejected A-ASSOCIATE-AC PDU Jul 7, 2019
@scaramallion scaramallion changed the title Exception raised decoding rejected A-ASSOCIATE-AC PDU Exception raised decoding A-ASSOCIATE-AC PDU Jul 7, 2019
@scaramallion scaramallion changed the title Exception raised decoding A-ASSOCIATE-AC PDU Exception raised converting A-ASSOCIATE-AC PDU to A-ASSOCIATE primitive Jul 7, 2019
@scaramallion
Copy link
Member

I've added a workaround for what I think is the problem. I'd appreciate it if you could:

  • Post the evt.EVT_DATA_RECV output as suggested in my previous comment (since I'd like to confirm that's the cause)
  • After posting the output, update to the current master and see if it helps.

@ylmzkaan
Copy link
Author

ylmzkaan commented Jul 7, 2019

Unfortunately, nothing seems to be printed by handle_data(). In fact, the handler isn't triggered at all. I updated to the current master and the issue still present. Here is the output anyway:

INFO:root:Server started.
INFO:pynetdicom.assoc:Requesting Association
DEBUG:pynetdicom.events:Request Parameters:
DEBUG:pynetdicom.events:========================= BEGIN A-ASSOCIATE-RQ PDU =========================
DEBUG:pynetdicom.events:Our Implementation Class UID: 1.2.826.0.1.3680043.9.3811.1.3.1
DEBUG:pynetdicom.events:Our Implementation Version Name: PYNETDICOM_131
DEBUG:pynetdicom.events:Application Context Name: 1.2.840.10008.3.1.1.1
DEBUG:pynetdicom.events:Calling Application Name: EGE-AI
DEBUG:pynetdicom.events:Called Application Name: ONIS25
DEBUG:pynetdicom.events:Our Max PDU Receive Size: 16382
DEBUG:pynetdicom.events:Presentation Context:
DEBUG:pynetdicom.events: Context ID: 1 (Proposed)
DEBUG:pynetdicom.events: Abstract Syntax: =Patient Root Query/Retrieve Information Model - MOVE
DEBUG:pynetdicom.events: Proposed SCP/SCU Role: Default
DEBUG:pynetdicom.events: Proposed Transfer Syntaxes:
DEBUG:pynetdicom.events: =Implicit VR Little Endian
DEBUG:pynetdicom.events: =Explicit VR Little Endian
DEBUG:pynetdicom.events: =Explicit VR Big Endian
DEBUG:pynetdicom.events:Requested Extended Negotiation: None
DEBUG:pynetdicom.events:Requested Common Extended Negotiation: None
DEBUG:pynetdicom.events:Requested Asynchronous Operations Window Negotiation: None
DEBUG:pynetdicom.events:Requested User Identity Negotiation: None
DEBUG:pynetdicom.events:========================== END A-ASSOCIATE-RQ PDU ==========================
DEBUG:pynetdicom.events:Accept Parameters:
DEBUG:pynetdicom.events:========================= BEGIN A-ASSOCIATE-AC PDU =========================
DEBUG:pynetdicom.events:Their Implementation Class UID: 1.2.392.200193
DEBUG:pynetdicom.events:Their Implementation Version Name: ONIS_Server 2.5
DEBUG:pynetdicom.events:Application Context Name: 1.2.840.10008.3.1.1.1
DEBUG:pynetdicom.events:Calling Application Name: EGE-AI
DEBUG:pynetdicom.events:Called Application Name: ONIS25
DEBUG:pynetdicom.events:Their Max PDU Receive Size: 16382
DEBUG:pynetdicom.events:Presentation Contexts:
DEBUG:pynetdicom.events: Context ID: 1 (Rejected - Abstract Syntax Not Supported)
DEBUG:pynetdicom.events: Abstract Syntax: =Patient Root Query/Retrieve Information Model - MOVE
DEBUG:pynetdicom.events:Accepted Extended Negotiation: None
DEBUG:pynetdicom.events:Accepted Asynchronous Operations Window Negotiation: None
DEBUG:pynetdicom.events:User Identity Negotiation Response: None
DEBUG:pynetdicom.events:========================== END A-ASSOCIATE-AC PDU ==========================
ERROR:pynetdicom.dul:Exception in DUL.run(), aborting association
ERROR:pynetdicom.dul:list index out of range
Traceback (most recent call last):
File "D:\Ege\DicomServer\venv\lib\site-packages\pynetdicom\dul.py", line 400, in run
elif self._is_transport_event():
File "D:\Ege\DicomServer\venv\lib\site-packages\pynetdicom\dul.py", line 188, in _is_transport_event
self._read_pdu_data()
File "D:\Ege\DicomServer\venv\lib\site-packages\pynetdicom\dul.py", line 324, in _read_pdu_data
self.primitive = self.pdu.to_primitive()
File "D:\Ege\DicomServer\venv\lib\site-packages\pynetdicom\pdu.py", line 892, in to_primitive
item.to_primitive()
File "D:\Ege\DicomServer\venv\lib\site-packages\pynetdicom\pdu_items.py", line 860, in to_primitive
self.transfer_syntax_sub_item[0].transfer_syntax_name
IndexError: list index out of range
ERROR:root:Association rejected, aborted or never connected

@scaramallion
Copy link
Member

scaramallion commented Jul 7, 2019

Can you double check you're using the current master? If you're using pip you'll have to reinstall it. The Our Implementation Version Name: PYNETDICOM_131 line should have PYNETDICOM_140 and also the line that's triggering the exception is no longer the same. A quick way to check is from pynetdicom import __version__; print(__version__)

Its strange that handle_data() isn't being called, you bound it and included in the AE.associate() call?

handlers = [(evt.EVT_DATA_RECV, handle_data)]
assoc = ae.associate(peerIP, peerPort, ae_title=peerAeTitle, evt_handlers=handlers)

@ylmzkaan
Copy link
Author

ylmzkaan commented Jul 8, 2019

You were right that the my version wasn't 1.40.dev0 and I tied the event handlers to the ae.start_server function not ae.associate. I fixed both of them. The Patient Root QR Move abstract syntax is still being rejected but here is the logging output and latest version of the code if you would like to take a look at it.

QRMoveSCU.py
EventHandlers.py

INFO:root:Server started.
INFO:pynetdicom.assoc:Requesting Association
DEBUG:pynetdicom.events:Request Parameters:
DEBUG:pynetdicom.events:========================= BEGIN A-ASSOCIATE-RQ PDU =========================
DEBUG:pynetdicom.events:Our Implementation Class UID: 1.2.826.0.1.3680043.9.3811.1.4.0
DEBUG:pynetdicom.events:Our Implementation Version Name: PYNETDICOM_140
DEBUG:pynetdicom.events:Application Context Name: 1.2.840.10008.3.1.1.1
DEBUG:pynetdicom.events:Calling Application Name: EGE-AI
DEBUG:pynetdicom.events:Called Application Name: ONIS25
DEBUG:pynetdicom.events:Our Max PDU Receive Size: 16382
DEBUG:pynetdicom.events:Presentation Context:
DEBUG:pynetdicom.events: Context ID: 1 (Proposed)
DEBUG:pynetdicom.events: Abstract Syntax: =Patient Root Query/Retrieve Information Model - MOVE
DEBUG:pynetdicom.events: Proposed SCP/SCU Role: Default
DEBUG:pynetdicom.events: Proposed Transfer Syntaxes:
DEBUG:pynetdicom.events: =Implicit VR Little Endian
DEBUG:pynetdicom.events: =Explicit VR Little Endian
DEBUG:pynetdicom.events: =Explicit VR Big Endian
DEBUG:pynetdicom.events:Requested Extended Negotiation: None
DEBUG:pynetdicom.events:Requested Common Extended Negotiation: None
DEBUG:pynetdicom.events:Requested Asynchronous Operations Window Negotiation: None
DEBUG:pynetdicom.events:Requested User Identity Negotiation: None
DEBUG:pynetdicom.events:========================== END A-ASSOCIATE-RQ PDU ==========================
02 00 00 00 00 96 00 01 00 00 4f 4e 49 53 32 35
20 20 20 20 20 20 20 20 20 20 45 47 45 2d 41 49
20 20 20 20 20 20 20 20 20 20 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 10 00 00 15 31 2e
32 2e 38 34 30 2e 31 30 30 30 38 2e 33 2e 31 2e
31 2e 31 21 00 00 04 01 00 03 00 50 00 00 2d 51
00 00 04 00 00 3f fe 52 00 00 0e 31 2e 32 2e 33
39 32 2e 32 30 30 31 39 33 55 00 00 0f 4f 4e 49
53 5f 53 65 72 76 65 72 20 32 2e 35
DEBUG:pynetdicom.events:Accept Parameters:
DEBUG:pynetdicom.events:========================= BEGIN A-ASSOCIATE-AC PDU =========================
DEBUG:pynetdicom.events:Their Implementation Class UID: 1.2.392.200193
DEBUG:pynetdicom.events:Their Implementation Version Name: ONIS_Server 2.5
DEBUG:pynetdicom.events:Application Context Name: 1.2.840.10008.3.1.1.1
DEBUG:pynetdicom.events:Calling Application Name: EGE-AI
DEBUG:pynetdicom.events:Called Application Name: ONIS25
DEBUG:pynetdicom.events:Their Max PDU Receive Size: 16382
DEBUG:pynetdicom.events:Presentation Contexts:
DEBUG:pynetdicom.events: Context ID: 1 (Rejected - Abstract Syntax Not Supported)
DEBUG:pynetdicom.events: Abstract Syntax: =Patient Root Query/Retrieve Information Model - MOVE
DEBUG:pynetdicom.events:Accepted Extended Negotiation: None
DEBUG:pynetdicom.events:Accepted Asynchronous Operations Window Negotiation: None
DEBUG:pynetdicom.events:User Identity Negotiation Response: None
DEBUG:pynetdicom.events:========================== END A-ASSOCIATE-AC PDU ==========================
ERROR:pynetdicom.acse:No accepted presentation contexts
DEBUG:pynetdicom.events:Abort Parameters:
DEBUG:pynetdicom.events:============================ BEGIN A-ABORT PDU =============================
DEBUG:pynetdicom.events:Abort Source: DUL service-provider
DEBUG:pynetdicom.events:Abort Reason: No reason given
DEBUG:pynetdicom.events:============================= END A-ABORT PDU ==============================
ERROR:root:Association rejected, aborted or never connected

@scaramallion
Copy link
Member

scaramallion commented Jul 9, 2019

Thanks! As I thought, the Presentation Context (AC) Item is missing a Transfer Syntax Sub-item. In its entirety, the encoded item is 21 00 00 04 01 00 03 00.

The context itself has been rejected by the Move SCP due to an unsupported abstract syntax (the 03 in the encoded item). I suspect the problem lies with the configuration of the Onis server (this page seems to indicate that the remote must be added to the server config and have Move rights enabled). So while the conformance statement says that Onis supports your requested context, you'd need to configure the server properly before you can actually use it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants