Beispiel #1
0
    def send_c_echo(self):

        status = self.assoc.send_c_echo()
        qry_response = {
            'status': {
                'code': status.Status,
                'category': code_to_category(status.Status)
            }
        }

        return qry_response
Beispiel #2
0
    def send_c_find(self, qry_dict):

        qry_ds = self.make_qry_ds(qry_dict)
        qry_response = {'status': list(), 'data': list()}
        responses = self.assoc.send_c_find(qry_ds,
                                           query_model=self.query_model)

        for status, ds in responses:

            status_dict = {
                'code': status.Status,
                'category': code_to_category(status.Status)
            }
            qry_response['status'].append(status_dict)

            if ds:
                data_dict = self.dictify(ds)
                qry_response['data'].append(data_dict)

        return qry_response
Beispiel #3
0
    def send_c_move(self, qry_dict):

        qry_ds = self.make_qry_ds(qry_dict)
        qry_response = {'status': list(), 'data': list()}
        responses = self.assoc.send_c_move(qry_ds,
                                           self.client_name,
                                           query_model=self.query_model)

        cnt = 0

        for status, ds in responses:

            status_dict = self.dictify(status)
            status_dict['status_category'] = code_to_category(status.Status)
            qry_response['status'].append(status_dict)

            if ds:
                data_dict = self.dictify(ds)
                qry_response['data'].append(data_dict)

            if cnt == self.mv_brk_cnt - 1:
                if 'NumberOfCompletedSuboperations' in qry_response['status']:
                    if sum(
                            int(i['NumberOfCompletedSuboperations'])
                            for i in qry_response['status']) == 0:
                        qry_response['status'].append({
                            'Status':
                            'BREAK @ COUNT ={}'.format(self.mv_brk_cnt)
                        })
                        print(
                            'ABORTING MOVE: {} STATUSES RECEIVED WITHOUT FILE MOVEMENT'
                            .format(self.mv_brk_cnt))
                        break

            cnt += 1
        return qry_response
Beispiel #4
0
 def test_code_to_category_unknown(self):
     """Test converting an unknown status code to its category"""
     assert code_to_category(0xDF01) == 'Unknown'
Beispiel #5
0
# Add a requested presentation context
ae.add_requested_context(DisplaySystemSOPClass)

# Associate with peer AE at IP 127.0.0.1 and port 11112
assoc = ae.associate('127.0.0.1', 11112)

if assoc.is_established:
    # Use the N-GET service to send the request, returns the
    #  response status a pydicom Dataset and the AttributeList dataset
    status, attr_list = assoc.send_n_get([(0x0008, 0x0070)],
                                         DisplaySystemSOPClass,
                                         '1.2.840.10008.5.1.1.40.1')

    # Check the status of the display system request
    if 'Status' in status:
        print('N-GET request status: 0x{0:04x}'.format(status.Status))

        # If the display system request succeeded the status category may
        # be either success or warning
        category = code_to_category(status.Status)
        if category in ['Warning', 'Success']:
            # `attr_list` is a pydicom Dataset containing attribute values
            print(attr_list)
    else:
        print('Connection timed out or invalid response from peer')

    # Release the association
    assoc.release()
else:
    print('Association rejected or aborted')
Beispiel #6
0
    def SCP(self, req, context, info):
        """The implementation for the DIMSE N-GET service.

        Parameters
        ----------
        req : dimse_primitives.C_ECHO
            The N-GET request primitive sent by the peer.
        context : presentation.PresentationContext
            The presentation context that the service is operating under.
        info : dict
            A dict containing details about the association.

        See Also
        --------
        ae.ApplicationEntity.on_n_get
        association.Association.send_n_get

        Notes
        -----
        **N-GET Request**

        *Parameters*

        | (M) Message ID
        | (M) Requested SOP Class UID
        | (M) Requested SOP Instance UID
        | (U) Attribute Identifier List

        *Attribute Identifier List*

        An element with VR AT, VM 1-n, containing an attribute tag for each
        of the attributes applicable to the N-GET operation.

        **N-GET Response**

        *Parameters*

        | (M) Message ID Being Responded To
        | (U) Affected SOP Class UID
        | (U) Affected SOP Instance UID
        | (C) Attribute List
        | (M) Status

        *Attribute List*

        A dataset containing the values of the requested attributes.

        References
        ----------

        * DICOM Standard, Part 4, `Annex EE <http://dicom.nema.org/medical/dicom/current/output/html/part04.html#chapter_EE>`_
        * DICOM Standard, Part 7, Sections
          `10.1.2 <http://dicom.nema.org/medical/dicom/current/output/html/part07.html#sect_10.1.2>`_,
          `10.3.2 <http://dicom.nema.org/medical/dicom/current/output/html/part07.html#sect_10.3.2>`_
          and `Annex C <http://dicom.nema.org/medical/dicom/current/output/html/part07.html#chapter_C>`_
        """
        # Build N-GET response primitive
        rsp = N_GET()
        rsp.MessageIDBeingRespondedTo = req.MessageID
        rsp.AffectedSOPClassUID = req.RequestedSOPClassUID
        rsp.AffectedSOPInstanceUID = req.RequestedSOPInstanceUID

        default_handler = evt.get_default_handler(evt.EVT_N_GET)
        if self.assoc.get_handlers(evt.EVT_N_GET) != default_handler:
            try:
                (rsp_status, ds) = evt.trigger(self.assoc, evt.EVT_N_GET, {
                    'request': req,
                    'context': context.as_tuple,
                })
            except Exception as exc:
                LOGGER.error(
                    "Exception in the handler bound to 'evt.EVT_N_GET'")
                LOGGER.exception(exc)
                # Processing failure - Error in on_n_get callback
                rsp_status = 0x0110
        else:
            info['parameters'] = {
                'message_id': req.MessageID,
                'requested_sop_class_uid': req.RequestedSOPClassUID,
                'requested_sop_instance_uid': req.RequestedSOPInstanceUID,
            }

            # Attempt to run the ApplicationEntity's on_n_get callback
            # pylint: disable=broad-except
            try:
                # Send the value rather than the element
                (rsp_status,
                 ds) = self.ae.on_n_get(req.AttributeIdentifierList,
                                        context.as_tuple, info)
            except Exception as exc:
                LOGGER.error(
                    "Exception in the ApplicationEntity.on_n_get() callback")
                LOGGER.exception(exc)
                # Processing failure - Error in on_n_get callback
                rsp_status = 0x0110

        # Validate rsp_status and set rsp.Status accordingly
        rsp = self.validate_status(rsp_status, rsp)

        # Success or Warning, must return AttributeList dataset
        if code_to_category(rsp.Status) in [STATUS_SUCCESS, STATUS_WARNING]:
            # Encode the `dataset` using the agreed transfer syntax
            #   Will return None if failed to encode
            transfer_syntax = context.transfer_syntax[0]
            bytestream = encode(ds, transfer_syntax.is_implicit_VR,
                                transfer_syntax.is_little_endian)

            if bytestream is not None:
                rsp.AttributeList = BytesIO(bytestream)
            else:
                LOGGER.error("Failed to encode the supplied Dataset")
                # Processing failure - Failed to encode dataset
                rsp.Status = 0x0110

        self.dimse.send_msg(rsp, context.context_id)
    def _get_scp(self, req, context):
        """

        Parameters
        ----------
        req : dimse_primitives.N_GET
            The N-GET request primitive sent by the peer.
        context : presentation.PresentationContext
            The presentation context that the service is operating under.

        See Also
        --------
        association.Association.send_n_get

        Notes
        -----
        **N-GET Request**

        *Parameters*

        | (M) Message ID
        | (M) Requested SOP Class UID
        | (M) Requested SOP Instance UID
        | (U) Attribute Identifier List

        *Attribute Identifier List*

        An element with VR AT, VM 1-n, containing an attribute tag for each
        of the attributes applicable to the N-GET operation.

        **N-GET Response**

        *Parameters*

        | (M) Message ID Being Responded To
        | (U) Affected SOP Class UID
        | (U) Affected SOP Instance UID
        | (C) Attribute List
        | (M) Status

        *Attribute List*

        A dataset containing the values of the requested attributes.

        *Status*

        Success
          | ``0x0000`` - Success

        Failure
          | ``0x0107`` - SOP Class not supported
          | ``0x0110`` - Processing failure
          | ``0x0112`` - No such SOP Instance
          | ``0x0117`` - Invalid object instance
          | ``0x0118`` - No such SOP Class
          | ``0x0119`` - Class-Instance conflict
          | ``0x0122`` - SOP Class not supported
          | ``0x0124`` - Refused: not authorised
          | ``0x0210`` - Duplicate invocation
          | ``0x0211`` - Unrecognised operation
          | ``0x0212`` - Mistyped argument
          | ``0x0213`` - Resource limitation

        References
        ----------

        * DICOM Standard, Part 4, `Annex EE <http://dicom.nema.org/medical/dicom/current/output/html/part04.html#chapter_EE>`_
        * DICOM Standard, Part 7, Sections
          `10.1.2 <http://dicom.nema.org/medical/dicom/current/output/html/part07.html#sect_10.1.2>`_,
          `10.3.2 <http://dicom.nema.org/medical/dicom/current/output/html/part07.html#sect_10.3.2>`_
          and `Annex C <http://dicom.nema.org/medical/dicom/current/output/html/part07.html#chapter_C>`_
        """
        # Build N-GET response primitive
        rsp = N_GET()
        rsp.MessageIDBeingRespondedTo = req.MessageID
        rsp.AffectedSOPClassUID = req.RequestedSOPClassUID
        rsp.AffectedSOPInstanceUID = req.RequestedSOPInstanceUID

        try:
            status, ds = evt.trigger(
                self.assoc,
                evt.EVT_N_GET,
                {
                    'request' : req,
                    'context' : context.as_tuple,
                }
            )
        except Exception as exc:
            LOGGER.error(
                "Exception in the handler bound to 'evt.EVT_N_GET'"
            )
            LOGGER.exception(exc)
            # Processing failure - Error in handler
            rsp.Status = 0x0110
            self.dimse.send_msg(rsp, context.context_id)
            return

        # Validate rsp_status and set rsp.Status accordingly
        rsp = self.validate_status(status, rsp)

        # Success or Warning, must return AttributeList dataset
        if code_to_category(rsp.Status) in [STATUS_SUCCESS, STATUS_WARNING]:
            # Encode the `dataset` using the agreed transfer syntax
            #   Will return None if failed to encode
            transfer_syntax = context.transfer_syntax[0]
            bytestream = encode(ds,
                                transfer_syntax.is_implicit_VR,
                                transfer_syntax.is_little_endian)

            if bytestream is not None:
                rsp.AttributeList = BytesIO(bytestream)
            else:
                LOGGER.error("Failed to encode the supplied Dataset")
                # Processing failure - Failed to encode dataset
                rsp.Status = 0x0110

        self.dimse.send_msg(rsp, context.context_id)