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

[MRG] Handle Presentation Context AC with no Transfer Syntax Sub-item #362

Merged
merged 3 commits into from
Jul 7, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 0 additions & 1 deletion docs/changelog/v1.0.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ Changes
- Added ``AE.add_requested_context()``, ``AE.requested_contexts``,
``AE.remove_requested_context()`` for adding and removing the presentation
contexts requested as an SCU.

* Removed ``VerificationSOPClass``, ``StorageSOPClassList`` and
``QueryRetrieveSOPClassList``.
* Added ``VerificationPresentationContexts``, ``StoragePresentationContexts``,
Expand Down
16 changes: 14 additions & 2 deletions docs/changelog/v1.4.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,27 @@ Fixes
Enhancements
............

* Added support for Protocol Approval Query Retrieve service class
(:issue:`327`)
* Added ``Event.move_destination`` and ``Event.event`` properties
(:issue:`353`)
* Added ``meta_uid`` keyword parameters to the ``Association.send_n_*()``
methods to allow the use of Meta SOP Classes (such as those used in the
Print Management service class)
* Added *Basic Grayscale Print Management Meta SOP Class* and *Basic Color
Print Management Meta SOP Class* to ``sop_class``.
* Added full support for the following service classes:

* Protocol Approval Query Retrieve (:issue:`327`)
* Application Event Logging
* Instance Availability Notification
* Media Creation Management
* Added partial support for the following service classes:

* Print Management
* Unified Procedure Step
* RT Machine Verification
* Storage Commitment
* Added handling of non-conformant Presentation Context AC (reject) PDUs which
contain no Transfer Syntax Sub-item (:issue:`361`)


Changes
Expand Down
10 changes: 5 additions & 5 deletions pynetdicom/pdu_items.py
Original file line number Diff line number Diff line change
Expand Up @@ -856,11 +856,8 @@ def to_primitive(self):
primitive = PresentationContext()
primitive.context_id = self.presentation_context_id
primitive.result = self.result_reason
# May be `None` if context is rejected
if self.transfer_syntax_sub_item[0].transfer_syntax_name:
primitive.add_transfer_syntax(
self.transfer_syntax_sub_item[0].transfer_syntax_name
)
if self.transfer_syntax:
primitive.add_transfer_syntax(self.transfer_syntax)

return primitive

Expand Down Expand Up @@ -976,6 +973,9 @@ def transfer_syntax(self):
Returns
-------
pydicom.uid.UID or None
If no Transfer Syntax Sub-item or an empty Transfer Syntax Sub-item
has been sent by the Acceptor then returns None, otherwise returns
the Transfer Syntax Sub-item's transfer syntax UID.
"""
if self.transfer_syntax_sub_item:
return self.transfer_syntax_sub_item[0].transfer_syntax_name
Expand Down
4 changes: 3 additions & 1 deletion pynetdicom/presentation.py
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,9 @@ def add_transfer_syntax(self, syntax):
elif isinstance(syntax, bytes):
syntax = UID(syntax.decode('ascii'))
else:
LOGGER.error("Attempted to add an invalid transfer syntax")
if syntax is not None:
LOGGER.error("Attempted to add an invalid transfer syntax")

return

if syntax is not None and not validate_uid(syntax):
Expand Down
34 changes: 33 additions & 1 deletion pynetdicom/tests/encoded_pdu_items.py
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,6 @@
b'\x59\x00\x00\x0a\x00\x08\x41\x63\x63\x65' \
b'\x70\x74\x65\x64'


# Issue 342
# Called AET: ANY-SCP
# Calling AET: PYNETDICOM
Expand Down Expand Up @@ -321,6 +320,39 @@
b'\x65\x43\x4f\x4d\x33\x5f\x33\x39\x30\x49\x42\x32'
)

# Issue 361
# Called AET: ANY-SCP
# Calling AET: PYNETDICOM
# Application Context Name: 1.2.840.10008.3.1.1.1
# Presentation Context Items:
# Presentation Context ID: 1
# Abstract Syntax: Verification SOP Class
# SCP/SCU Role: Default
# Result: Reject
# Transfer Syntax: (no Transfer Syntax Sub-Item)
# User Information
# Max Length Received: 16382
# Implementation Class UID: 1.2.826.0.1.3680043.9.3811.1.4.0
# Implementation Version Name: PYNETDICOM_140
# Extended Negotiation
# SOP Extended: None
# Async Ops: None
# User ID: None
a_associate_ac_no_ts = (
b'\x02\x00\x00\x00\x00\xa7\x00\x01\x00\x00\x41\x4e\x59\x2d\x53\x43'
b'\x50\x20\x20\x20\x20\x20\x20\x20\x20\x20\x50\x59\x4e\x45\x54\x44'
b'\x49\x43\x4f\x4d\x20\x20\x20\x20\x20\x20\x00\x00\x00\x00\x00\x00'
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x15\x31\x2e'
b'\x32\x2e\x38\x34\x30\x2e\x31\x30\x30\x30\x38\x2e\x33\x2e\x31\x2e'
b'\x31\x2e\x31\x21\x00\x00\x04\x01\x00\x03\x00'
b'\x50\x00\x00\x3e\x51\x00\x00\x04\x00\x00\x3f\xfe\x52\x00\x00\x20'
b'\x31\x2e\x32\x2e\x38\x32\x36\x2e\x30\x2e\x31\x2e\x33\x36\x38\x30'
b'\x30\x34\x33\x2e\x39\x2e\x33\x38\x31\x31\x2e\x31\x2e\x34\x2e\x30'
b'\x55\x00\x00\x0e\x50\x59\x4e\x45\x54\x44\x49\x43\x4f\x4d\x5f\x31'
b'\x34\x30'
)


############################# A-ASSOCIATE-RJ PDU ###############################
# Result: Rejected (Permanent)
Expand Down
20 changes: 19 additions & 1 deletion pynetdicom/tests/test_pdu.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
from .encoded_pdu_items import (
a_associate_rq, a_associate_ac, a_associate_rj, a_release_rq, a_release_rq,
a_release_rp, a_abort, a_p_abort, p_data_tf,
a_associate_rq_user_id_ext_neg
a_associate_rq_user_id_ext_neg, a_associate_ac_no_ts
)
from pynetdicom.sop_class import VerificationSOPClass
from pynetdicom.utils import pretty_bytes
Expand Down Expand Up @@ -660,6 +660,24 @@ def test_from_primitive(self):

assert new == orig

def test_no_transfer_syntax(self):
"""Regression test for #361 - ASSOC-AC has no transfer syntax"""
pdu = A_ASSOCIATE_AC()
pdu.decode(a_associate_ac_no_ts)

assert pdu.pdu_type == 0x02
assert pdu.pdu_length == 167
assert pdu.protocol_version == 0x0001
assert isinstance(pdu.pdu_type, int)
assert isinstance(pdu.pdu_length, int)
assert isinstance(pdu.protocol_version, int)

item = pdu.variable_items[1]
cx = item.to_primitive()
assert cx.transfer_syntax == []
assert cx.result == 3
assert cx.context_id == 1


class TestASSOC_AC_ApplicationContext(object):
def test_decode(self):
Expand Down
6 changes: 6 additions & 0 deletions pynetdicom/tests/test_pdu_items.py
Original file line number Diff line number Diff line change
Expand Up @@ -627,6 +627,12 @@ def test_decode_empty(self):
assert len(item) == 12
assert item.transfer_syntax is None

# Confirm we can still convert the PDU into a PresentationContext
primitive = item.to_primitive()
assert primitive.context_id == 1
assert primitive.transfer_syntax == []
assert primitive.result == 1

assert "Item length: 8 bytes" in item.__str__()

item = item.transfer_syntax_sub_item[0]
Expand Down