def Accept(self, client_socket=None, AcceptablePresentationContexts=None, Wait=True): """Waits for an association request from a remote AE. Upon reception of the request sends association response based on AcceptablePresentationContexts""" if self.DUL is None: self.DUL = DULServiceProvider(Socket=client_socket) ass = self.DUL.Receive(Wait=True) if ass is None: return None # 写死 self.MaxPDULength = 16352 # analyse proposed presentation contexts rsp = [] self.AcceptedPresentationContexts = [] acceptable_sop = [x[0] for x in AcceptablePresentationContexts] ok = False for ii in ass.PresentationContextDefinitionList: pcid = ii[0] proposed_sop = ii[1] proposed_ts = ii[2] if proposed_sop in acceptable_sop: acceptable_ts = [ x[1] for x in AcceptablePresentationContexts if x[0] == proposed_sop ][0] for ts in proposed_ts: ok = False if ts in acceptable_ts: # accept sop class and ts rsp.append((ii[0], 0, ts)) self.AcceptedPresentationContexts.append( (ii[0], proposed_sop, UID(ts))) ok = True break if not ok: # Refuse sop class because of TS not supported rsp.append((ii[0], 1, '')) else: # Refuse sop class because of SOP class not supported rsp.append((ii[0], 1, '')) # Send response res = copy.copy(ass) res.CallingAETitle = ass.CalledAETitle res.CalledAETitle = ass.CallingAETitle res.PresentationContextDefinitionList = [] res.PresentationContextDefinitionResultList = rsp res.Result = 0 max_len = MaximumLengthParameters() max_len.MaximumLengthReceived = self.MaxPDULength async_oper_window = AsynchronousOperationsWindowSubItem() async_oper_window.MaximumNumberOperationsInvoked = 16 async_oper_window.MaximumNumberOperationsPerformed = 16 res.UserInformation = [max_len, async_oper_window] self.DUL.Send(res) return True
def testComparison(self): """UID: can compare by number or by name..................""" uid = UID('1.2.840.10008.1.2') self.assertEqual(uid, 'Implicit VR Little Endian', "UID equality failed on name") self.assertEqual(uid, '1.2.840.10008.1.2', "UID equality failed on number string")
def testKnownUID(self): """UID: Known UID properties accessed.....................""" uid = UID('1.2.840.10008.1.2') # Implicit VR Little Endian expected = 'Implicit VR Little Endian' got = uid.name self.assertEqual( got, expected, "UID: expected '%s', got '%s' for UID name" % (expected, got)) expected = 'Transfer Syntax' got = uid.type self.assertEqual( got, expected, "UID: expected '%s', got '%s' for UID type" % (expected, got)) expected = 'Default Transfer Syntax for DICOM' got = uid.info self.assertEqual( got, expected, "UID: expected '%s', got '%s' for UID info" % (expected, got)) expected = False got = uid.is_retired self.assertEqual( got, expected, "UID: expected '%s', got '%s' for UID is_retired" % (expected, got))
def Request(self, localAE, remoteAE, mp, pcdl, userspdu=None): """Requests an association with a remote AE and waits for association response.""" self.LocalAE = localAE self.RemoteAE = remoteAE self.MaxPDULength = mp # build association service parameters object assrq = A_ASSOCIATE_ServiceParameters() assrq.ApplicationContextName = self.ApplicationContextName assrq.CallingAETitle = self.LocalAE['AET'] assrq.CalledAETitle = self.RemoteAE['AET'] MaxPDULengthPar = MaximumLengthParameters() MaxPDULengthPar.MaximumLengthReceived = mp if userspdu <> None: assrq.UserInformation = [MaxPDULengthPar] + userspdu else: assrq.UserInformation = [MaxPDULengthPar] assrq.CallingPresentationAddress = (self.LocalAE['Address'], self.LocalAE['Port']) assrq.CalledPresentationAddress = (self.RemoteAE['Address'], self.RemoteAE['Port']) assrq.PresentationContextDefinitionList = pcdl if DEBUG: print pcdl # send A-Associate request if DEBUG: print "Sending Association Request ...", self.DUL.Send(assrq) if DEBUG: print " done" # get answer if DEBUG: print "Waiting for Association Response ...", assrsp = self.DUL.Receive(True) if DEBUG: print " done" if not assrsp: return False raise AssociationRefused if DEBUG: print assrsp if assrsp.Result <> 'Accepted': return False raise AssociationRefused # Get maximum pdu length from answer #print assrsp try: self.MaxPDULength = assrsp.UserInformation[0].MaximumLengthReceived except: self.MaxPDULength = 16000 print assrsp.UserInformation[0].MaximumLengthReceived # Get accepted presentation contexts self.AcceptedPresentationContexts = [] for cc in assrsp.PresentationContextDefinitionResultList: if cc[1] == 0: uid = [x[1] for x in pcdl if x[0] == cc[0]][0] self.AcceptedPresentationContexts.append( (cc[0], uid, UID(cc[2]))) return True
def Request(self, localAE, remoteAE, mp, pcdl, userspdu=None, timeout=30): """Requests an association with a remote AE and waits for association response.""" self.LocalAE = localAE self.RemoteAE = remoteAE self.MaxPDULength = mp # build association service parameters object assrq = A_ASSOCIATE_ServiceParameters() assrq.ApplicationContextName = self.ApplicationContextName assrq.CallingAETitle = self.LocalAE['AET'] assrq.CalledAETitle = self.RemoteAE['AET'] MaxPDULengthPar = MaximumLengthParameters() MaxPDULengthPar.MaximumLengthReceived = mp if userspdu is not None: assrq.UserInformation = [MaxPDULengthPar] + userspdu else: assrq.UserInformation = [MaxPDULengthPar] assrq.CallingPresentationAddress = ( self.LocalAE['Address'], self.LocalAE['Port']) assrq.CalledPresentationAddress = ( self.RemoteAE['Address'], self.RemoteAE['Port']) assrq.PresentationContextDefinitionList = pcdl logger.debug(pcdl) # send A-Associate request logger.debug("Sending Association Request") self.DUL.Send(assrq) # get answer logger.debug("Waiting for Association Response") assrsp = self.DUL.Receive(True, timeout) if not assrsp: return False logger.debug(assrsp) try: if assrsp.Result != 'Accepted': return False except AttributeError: return False # Get maximum pdu length from answer try: self.MaxPDULength = assrsp.UserInformation[0].MaximumLengthReceived except: self.MaxPDULength = 16000 # Get accepted presentation contexts self.AcceptedPresentationContexts = [] for cc in assrsp.PresentationContextDefinitionResultList: if cc[1] == 0: uid = [x[1] for x in pcdl if x[0] == cc[0]][0] self.AcceptedPresentationContexts.append( (cc[0], uid, UID(cc[2]))) return True
def Accept(self, client_socket=None, AcceptablePresentationContexts=None, Wait=True): """Waits for an association request from a remote AE. Upon reception of the request sends association response based on AcceptablePresentationContexts""" if self.DUL == None: self.DUL = DUL(Socket=client_socket) ass = self.DUL.Receive(Wait=True) if ass == None: return None self.MaxPDULength = ass.UserInformation[0].MaximumLengthReceived # analyse proposed presentation contexts rsp = [] self.AcceptedPresentationContexts = [] acceptable_sop = [x[0] for x in AcceptablePresentationContexts] for ii in ass.PresentationContextDefinitionList: pcid = ii[0] proposed_sop = ii[1] proposed_ts = ii[2] if proposed_sop in acceptable_sop: acceptable_ts = [ x[1] for x in AcceptablePresentationContexts if x[0] == proposed_sop ][0] for ts in proposed_ts: ok = False if ts in acceptable_ts: # accept sop class and ts rsp.append((ii[0], 0, ts)) self.AcceptedPresentationContexts.append( (ii[0], proposed_sop, UID(ts))) ok = True break if not ok: # Refuse sop class because of TS not supported rsp.append((ii[0], 1, '')) else: # Refuse sop class because of SOP class not supported rsp.append((ii[0], 1, '')) # Send response res = ass res.PresentationContextDefinitionList = [] res.PresentationContextDefinitionResultList = rsp res.Result = 0 res.UserInformation = [] #res.UserInformation = ass.UserInformation #print res self.DUL.Send(res) #print "response sent" return True
def _convert(self, val): """Take the value and convert to number, etc if possible""" if self.VR == 'IS': return IS(val) elif self.VR == 'DS': return DS(val) elif self.VR == "UI": return UID(val) # Later may need this for PersonName as for UI, # but needs more thought # elif self.VR == "PN": # return PersonName(val) else: # is either a string or a type 2 optionally blank string return val # this means a "numeric" value could be empty string ""
def testKnownUID(self): """UID: Known UID properties accessed.....................""" msg = "UID: expected '{1:s}', got '{2:s}' for UID {0:s}" uid = UID('1.2.840.10008.1.2') # Implicit VR Little Endian expected = 'Implicit VR Little Endian' got = uid.name self.assertEqual(got, expected, msg.format("name", expected, got)) expected = 'Transfer Syntax' got = uid.type self.assertEqual(got, expected, msg.format("type", expected, got)) expected = 'Default Transfer Syntax for DICOM' got = uid.info self.assertEqual(got, expected, msg.format("info", expected, got)) expected = False got = uid.is_retired self.assertEqual(got, expected, msg.format("is_retired", str(expected), str(got)))
def Accept(self, client_socket=None, AcceptablePresentationContexts=None, Wait=True, result=None, diag=None): """Waits for an association request from a remote AE. Upon reception of the request sends association response based on AcceptablePresentationContexts""" if self.DUL is None: self.DUL = DULServiceProvider(Socket=client_socket) assoc = self.DUL.Receive(Wait=True) if assoc is None: return None self.MaxPDULength = assoc.UserInformation[0].MaximumLengthReceived if result is not None and diag is not None: # Association is rejected res = assoc res.PresentationContextDefinitionList = [] res.PresentationContextDefinitionResultList = [] res.Result = result res.Diagnostic = diag res.UserInformation = [] #res.UserInformation = ass.UserInformation self.DUL.Send(res) return None # analyse proposed presentation contexts rsp = [] self.AcceptedPresentationContexts = [] acceptable_sop = [x[0] for x in AcceptablePresentationContexts] for ii in assoc.PresentationContextDefinitionList: pcid = ii[0] proposed_sop = ii[1] proposed_ts = ii[2] if proposed_sop in acceptable_sop: acceptable_ts = [x[1] for x in AcceptablePresentationContexts if x[0] == proposed_sop][0] for ts in proposed_ts: ok = False if ts in acceptable_ts: # accept sop class and ts rsp.append((ii[0], 0, ts)) self.AcceptedPresentationContexts.append( (ii[0], proposed_sop, UID(ts))) ok = True break if not ok: # Refuse sop class because of TS not supported rsp.append((ii[0], 1, '')) else: # Refuse sop class because of SOP class not supported rsp.append((ii[0], 1, '')) # Send response res = copy.copy(assoc) res.CallingAETitle = assoc.CalledAETitle res.CalledAETitle = assoc.CallingAETitle res.PresentationContextDefinitionList = [] res.PresentationContextDefinitionResultList = rsp res.Result = 0 #res.UserInformation = [] #res.UserInformation = [ass.UserInformation[0]] res.UserInformation = assoc.UserInformation self.DUL.Send(res) return assoc
def __init__(self, AET, port, SOPSCU, SOPSCP, SupportedTransferSyntax=[ ExplicitVRLittleEndian, ImplicitVRLittleEndian, ExplicitVRBigEndian ], MaxPDULength=16000): self.LocalAE = {'Address': platform.node(), 'Port': port, 'AET': AET} self.SupportedSOPClassesAsSCU = SOPSCU self.SupportedSOPClassesAsSCP = SOPSCP self.SupportedTransferSyntax = SupportedTransferSyntax self.MaxNumberOfAssociations = 2 # maximum amount of time this association can be idle before it gets # terminated self.MaxAssociationIdleSeconds = None self.ConnectTimeoutSeconds = None self.AssociateRequestTimeout = 30 threading.Thread.__init__(self, name=self.LocalAE['AET']) self.daemon = True self.SOPUID = [x for x in self.SupportedSOPClassesAsSCP] self.LocalServerSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.LocalServerSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) self.LocalServerSocket.bind(('', port)) self.LocalServerSocket.listen(1) self.MaxPDULength = MaxPDULength # build presentation context definition list to be sent to remote AE # when requesting association. count = 1 self.PresentationContextDefinitionList = [] for ii in self.SupportedSOPClassesAsSCU + \ self.SupportedSOPClassesAsSCP: if isinstance(ii, UID): self.PresentationContextDefinitionList.append([ count, ii, [x for x in self.SupportedTransferSyntax]]) count += 2 elif ii.__subclasses__(): for jj in ii.__subclasses__(): self.PresentationContextDefinitionList.append([ count, UID(jj.UID), [x for x in self.SupportedTransferSyntax] ]) count += 2 else: self.PresentationContextDefinitionList.append([ count, UID(ii.UID), [x for x in self.SupportedTransferSyntax]]) count += 2 # build acceptable context definition list used to decide # weither an association from a remote AE will be accepted or # not. This is based on the SupportedSOPClassesAsSCP and # SupportedTransferSyntax values set for this AE. self.AcceptablePresentationContexts = [] for ii in self.SupportedSOPClassesAsSCP: if ii.__subclasses__(): for jj in ii.__subclasses__(): self.AcceptablePresentationContexts.append( [jj.UID, [x for x in self.SupportedTransferSyntax]]) else: self.AcceptablePresentationContexts.append( [ii.UID, [x for x in self.SupportedTransferSyntax]]) # used to terminate AE self.__Quit = False # list of active association objects self.Associations = []
def testCompareNone(self): """UID: comparing against None give False.................""" # From issue 96 uid = UID('1.2.3') self.assertNotEqual(uid, None, "Comparison to a number returned True")
def testCompareNotEqualByName(self): """UID: comparing not equal by name.......................""" # from Issue 121 ct_image_storage = UID('1.2.840.10008.5.1.4.1.1.2') msg = "UID not equal comparison by name was not correct" self.assertFalse(ct_image_storage != 'CT Image Storage', msg)