Skip to content

Commit

Permalink
Handle Presentation Context AC with no Transfer Syntax Sub-item (#362)
Browse files Browse the repository at this point in the history
  • Loading branch information
scaramallion committed Jul 7, 2019
1 parent 30ea1ed commit f8db5c0
Show file tree
Hide file tree
Showing 7 changed files with 80 additions and 11 deletions.
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

0 comments on commit f8db5c0

Please sign in to comment.