/// <summary> /// Constructor. /// </summary> /// <remarks> /// The constructor creates a dictionary of each presentation context negotiated for the /// association, and the plugin that will handle it. This is used later when incoming request /// messages are processed. /// </remarks> /// <param name="server">The server.</param> /// <param name="parameters">Association parameters for the negotiated association.</param> /// <param name="userParms">User parameters to be passed to the plugins called by the class.</param> /// <param name="verifier">Delegate to call to verify an association before its accepted.</param> /// <param name="complete">Delegate to call when the association is closed/complete. Can be null.</param> public DicomScpHandler(DicomServer server, ServerAssociationParameters parameters, TContext userParms, DicomScp <TContext> .AssociationVerifyCallback verifier, DicomScp <TContext> .AssociationComplete complete) { _context = userParms; _verifier = verifier; _complete = complete; var ep = new DicomScpExtensionPoint <TContext>(); object[] scps = ep.CreateExtensions(); // First set the user parms for each of the extensions before we do anything with them. foreach (object obj in scps) { var scp = obj as IDicomScp <TContext>; if (scp != null) { scp.SetContext(_context); } } // Now, create a dictionary with the extension to be used for each presentation context. foreach (byte pcid in parameters.GetPresentationContextIDs()) { if (parameters.GetPresentationContextResult(pcid) == DicomPresContextResult.Accept) { SopClass acceptedSop = SopClass.GetSopClass(parameters.GetAbstractSyntax(pcid).UID); TransferSyntax acceptedSyntax = parameters.GetAcceptedTransferSyntax(pcid); foreach (object obj in scps) { var scp = obj as IDicomScp <TContext>; if (scp == null) { continue; } IList <SupportedSop> sops = scp.GetSupportedSopClasses(); foreach (SupportedSop sop in sops) { if (sop.SopClass.Equals(acceptedSop)) { if (sop.SyntaxList.Contains(acceptedSyntax)) { if (!_extensionList.ContainsKey(pcid)) { _extensionList.Add(pcid, scp); break; } Platform.Log(LogLevel.Error, "SOP Class {0} supported by more than one extension", sop.SopClass.Name); } } } } } } _statsRecorder = new AssociationStatisticsRecorder(server); }
/// <summary> /// Constructor. /// </summary> /// <remarks> /// The constructor creates a dictionary of each presentation context negotiated for the /// association, and the plugin that will handle it. This is used later when incoming request /// messages are processed. /// </remarks> /// <param name="server">The server.</param> /// <param name="parameters">Association parameters for the negotiated association.</param> /// <param name="userParms">User parameters to be passed to the plugins called by the class.</param> /// <param name="verifier">Delegate to call to verify an association before its accepted.</param> /// <param name="complete">Delegate to call when the association is closed/complete. Can be null.</param> public DicomScpHandler(DicomServer server, ServerAssociationParameters parameters, TContext userParms, DicomScp <TContext> .AssociationVerifyCallback verifier, DicomScp <TContext> .AssociationComplete complete) { _context = userParms; _verifier = verifier; _complete = complete; List <IDicomScp <TContext> > scps = Platform.Instance.CompositionContainer.GetExportedValues <IDicomScp <TContext> >().Select(scp => scp). ToList(); // First set the user parms for each of the extensions before we do anything with them. foreach (object obj in scps) { IDicomScp <TContext> scp = obj as IDicomScp <TContext>; scp.SetContext(_context); } // Now, create a dictionary with the extension to be used for each presentation context. foreach (byte pcid in parameters.GetPresentationContextIDs()) { if (parameters.GetPresentationContextResult(pcid) == DicomPresContextResult.Accept) { SopClass acceptedSop = SopClass.GetSopClass(parameters.GetAbstractSyntax(pcid).UID); TransferSyntax acceptedSyntax = parameters.GetAcceptedTransferSyntax(pcid); foreach (object obj in scps) { IDicomScp <TContext> scp = obj as IDicomScp <TContext>; IList <SupportedSop> sops = scp.GetSupportedSopClasses(); foreach (SupportedSop sop in sops) { if (sop.SopClass.Equals(acceptedSop)) { if (sop.SyntaxList.Contains(acceptedSyntax)) { if (!_extensionList.ContainsKey(pcid)) { _extensionList.Add(pcid, scp); break; } else { LogAdapter.Logger.ErrorWithFormat("SOP Class {0} supported by more than one extension", sop.SopClass.Name); } } } } } } } }
void IDicomServerHandler.OnReceiveAssociateRequest(DicomServer server, ServerAssociationParameters association) { if (_verifier != null) { DicomRejectResult result; DicomRejectReason reason; bool verified = _verifier(_context, association, out result, out reason); if (verified == false) { server.SendAssociateReject(result, DicomRejectSource.ServiceUser, reason); LogAdapter.Logger.Info("Association rejected from {0} to {1}", association.CallingAE, association.CalledAE); return; } } // Let the extensions have its say on whether a presentation context is really acceptable. // bool atLeastOneAccepted = false; foreach (byte pcid in association.GetPresentationContextIDs()) { if (association.GetPresentationContextResult(pcid) == DicomPresContextResult.Accept) { IDicomScp <TContext> scp = _extensionList[pcid]; DicomPresContextResult res = scp.VerifyAssociation(association, pcid); if (res != DicomPresContextResult.Accept) { association.GetPresentationContext(pcid).ClearTransfers(); association.SetPresentationContextResult(pcid, res); } else { atLeastOneAccepted = true; } } } if (!atLeastOneAccepted) { LogAdapter.Logger.Info("None of the proposed presentation context is accepted. Rejecting association from {0} to {1}", association.CallingAE, association.CalledAE); server.SendAssociateReject(DicomRejectResult.Permanent, DicomRejectSource.ServiceUser, DicomRejectReason.NoReasonGiven); return; } server.SendAssociateAccept(association); // Optimization to speed query performance Task.Factory.StartNew(() => LogAdapter.Logger.Info("Received association:\r\n{0}", association.ToString())); }