Пример #1
0
 def time_ps_rq_basic(self):
     """Time a basic presentation service negotiation."""
     for ii in range(100):
         negotiate_as_requestor(self.requestor_contexts,
                                self.acceptor_contexts)
Пример #2
0
 def time_ps_ac_role(self):
     """Time a presentation service with SCP/SCU role negotiation."""
     for ii in range(100):
         negotiate_as_requestor(self.requestor_contexts,
                                self.acceptor_contexts, self.ac_roles)
Пример #3
0
    def _negotiate_as_requestor(self):
        """Perform an association negotiation as the association *requestor*."""
        if not self.requestor.requested_contexts:
            LOGGER.error(
                "One or more requested presentation contexts must be set "
                "prior to association negotiation")
            self.assoc.kill()
            return

        # Build and send an A-ASSOCIATE (request) PDU to the peer
        self.send_request()
        evt.trigger(self.assoc, evt.EVT_REQUESTED, {})

        # Wait for response
        rsp = self.dul.receive_pdu(wait=True, timeout=self.acse_timeout)

        # Association accepted or rejected
        if isinstance(rsp, A_ASSOCIATE):
            self.acceptor.primitive = rsp
            # Accepted
            if rsp.result == 0x00:
                ## Handle SCP/SCU Role Selection response
                # Apply requestor's proposed SCP/SCU role selection (if any)
                #   to the requested contexts
                rq_roles = {
                    uid: (ii.scu_role, ii.scp_role)
                    for uid, ii in self.requestor.role_selection.items()
                }
                if rq_roles:
                    for cx in self.requestor.requested_contexts:
                        try:
                            (cx.scu_role,
                             cx.scp_role) = rq_roles[cx.abstract_syntax]
                            # If no role was specified then use False
                            #   see SCP_SCU_RoleSelectionSubItem.from_primitive
                            cx.scu_role = cx.scu_role or False
                            cx.scp_role = cx.scp_role or False
                        except KeyError:
                            pass

                # Collate the acceptor's SCP/SCU role selection responses
                ac_roles = {
                    uid: (ii.scu_role, ii.scp_role)
                    for uid, ii in self.acceptor.role_selection.items()
                }

                # Check the negotiated presentation contexts results and
                #   determine their agreed upon SCP/SCU roles
                negotiated_contexts = negotiate_as_requestor(
                    self.requestor.requested_contexts,
                    rsp.presentation_context_definition_results_list, ac_roles)

                # pylint: disable=protected-access
                # Accepted contexts are stored as {context ID : context}
                self.assoc._accepted_cx = {
                    cx.context_id: cx
                    for cx in negotiated_contexts if cx.result == 0x00
                }
                self.assoc._rejected_cx = [
                    cx for cx in negotiated_contexts if cx.result != 0x00
                ]
                # pylint: enable=protected-access

                evt.trigger(self.assoc, evt.EVT_ACCEPTED, {})

                # No acceptable presentation contexts
                if not self.assoc.accepted_contexts:
                    LOGGER.error("No accepted presentation contexts")
                    self.send_abort(0x02)
                    self.assoc.is_aborted = True
                    self.assoc.is_established = False
                    evt.trigger(self.assoc, evt.EVT_ABORTED, {})
                    self.assoc.kill()
                else:
                    LOGGER.info('Association Accepted')
                    self.assoc.is_established = True
                    evt.trigger(self.assoc, evt.EVT_ESTABLISHED, {})

            elif hasattr(rsp, 'result') and rsp.result in [0x01, 0x02]:
                # 0x01 is rejected (permanent)
                # 0x02 is rejected (transient)
                LOGGER.error('Association Rejected')
                LOGGER.error(
                    f"Result: {rsp.result_str}, Source: {rsp.source_str}")
                LOGGER.error(f"Reason: {rsp.reason_str}")
                self.assoc.is_rejected = True
                self.assoc.is_established = False
                evt.trigger(self.assoc, evt.EVT_REJECTED, {})
                self.dul.kill_dul()
            else:
                LOGGER.error(
                    "Received an invalid A-ASSOCIATE response from the peer")
                LOGGER.error("Aborting Association")
                self.send_abort(0x02)
                self.assoc.is_aborted = True
                self.assoc.is_established = False
                # Event handler - association aborted
                evt.trigger(self.assoc, evt.EVT_ABORTED, {})
                self.assoc.kill()

        # Association aborted
        elif isinstance(rsp, (A_ABORT, A_P_ABORT)):
            LOGGER.error("Association Aborted")
            self.assoc.is_established = False
            self.assoc.is_aborted = True
            evt.trigger(self.assoc, evt.EVT_ABORTED, {})
            self.dul.kill_dul()
        elif rsp is None:
            # ACSE timeout
            LOGGER.error("ACSE timeout reached while waiting for response to "
                         "association request")
            self.assoc.abort()
        else:
            # Received A-RELEASE or some weird object
            self.assoc.is_established = False
            self.dul.kill_dul()