The MPPSSCP example demonstrates how to use DCF to implement a modality performed procedure step service class provider.
Classes
Class | Description | |
---|---|---|
Program |
Basic modality performed procedure step service class provider example should be run with MPPSSCU.
| |
ProgramModalityPerformedProcedureStepSCP |
An MMPS server that extends the AssociationListenerAdapter and implements the
IAssociationConfigPolicyManager.
|
Remarks
Supported OS Platforms:
- Windows - .Net Framework 4.7.2 64-bit and 32-bit
- Windows - .Net Core 2.1 64-bit and 32-bit
- Linux - .Net Core 2.1 64-bit
Examples
MPPSSCP Sample Code
public class Program { private static readonly ILogger Logger = LogManager.GetCurrentClassLogger(); /// <summary> /// Main entry point for MPPSSCP. /// </summary> [STAThread] public static void Main() { try { IList<AllowedPresentationContext> allowed = new List<AllowedPresentationContext>(); allowed.Add(new AllowedPresentationContext(Uids.ModalityPerformedProcedureStepSOPClass, new[] { Uids.TransferSyntax.ExplicitVRLittleEndian, Uids.TransferSyntax.ImplicitVRLittleEndian })); ModalityPerformedProcedureStepSCP scp = new ModalityPerformedProcedureStepSCP(allowed); AssociationManager mgr = new AssociationManager(); mgr.ServerTcpPort = 10104; mgr.AssociationConfigPolicyMgr = scp; mgr.AddAssociationListener(scp); // AssociationManager.run() blocks, so start him listening for connections on a separate thread Thread t = new Thread(mgr.Run); t.Start(); if (!mgr.WaitForRunning(2000)) { throw new TimeoutException("AssociationManager did not start in an acceptable amount of time"); } Console.WriteLine("listening on 10104..."); } catch (Exception e) { Console.WriteLine("Exception caught during execution: {0}", e); Environment.ExitCode = 1; } } /// <summary> /// An MMPS server that extends the <see cref="AssociationListenerAdapter"/> and implements the /// <see cref="IAssociationConfigPolicyManager"/>. /// </summary> /// <remarks> /// <para> /// The <see cref="IAssociationConfigPolicyManager"/> allows us to get a callback to set our /// session settings for the association. /// </para> /// <para> /// This class overrides the <see cref="AssociationListenerAdapter.BeginAssociation"/> method /// to install a service class provider which negotiates the association, and delegates service /// class specific messages back to us for processing. Other <see cref="AssociationListenerAdapter"/> /// methods may be overridden to implement additional functionality. /// </para> /// </remarks> public class ModalityPerformedProcedureStepSCP : AssociationListenerAdapter, IAssociationConfigPolicyManager { private readonly IList<AllowedPresentationContext> _presentationContexts; /// <summary> /// Constructs a Modality Performed Procedure Step SCP with the specified set of allowed presentation contexts. /// </summary> /// <param name="allowedPresentationContexts">The list of presentation contexts that will be allowed.</param> public ModalityPerformedProcedureStepSCP(IList<AllowedPresentationContext> allowedPresentationContexts) { _presentationContexts = allowedPresentationContexts; } #region IAssociationConfigPolicyManager Overrides /// <summary> /// Returns a DicomSessionSettings object to be used for the association. /// </summary> /// <param name="assoc">The AssociationAcceptor handling the association</param> /// <returns>The DicomSessionSettings for the given association.</returns> public DicomSessionSettings GetSessionSettings(AssociationAcceptor assoc) { return new DicomSessionSettings { SessionName = String.Format("MPPSSCP:{0}", assoc.DicomSocket.ConnectionID) }; } #endregion #region AssociationListenerAdapter Overrides /// <summary> /// Creates the ModalityPerformedProcedureStepSCP object to handle the association that caused this method to be called. /// </summary> /// <param name="assoc">The AssociationAcceptor for the given association</param> public override void BeginAssociation(AssociationAcceptor assoc) { assoc.RegisterServiceClassProvider(new DCF.Dicom.ProcedureStep.MPPSSCP(assoc, _presentationContexts, NCreate, NSet)); } #endregion #region Helper Delegates /// <summary> /// NCreate response handler to process the incoming NCreateRequest message. Once finished, /// the NCreate response DIMSE message is returned to be sent to the SCP. /// </summary> /// <param name="acceptor">The association acceptor for this association.</param> /// <param name="request">The incoming NCreate request.</param> /// <returns>The NCreate response DIMSE message.</returns> private NCreateResponse NCreate(AssociationAcceptor acceptor, NCreateRequest request) { Logger.InfoFormat("Incoming NCreate Request:{0}{1}", Environment.NewLine, request); NCreateResponse rsp = new NCreateResponse(request); // TODO: insert code to create/store the procedure. rsp.Status = DimseStatus.DIMSE_SUCCESS; Logger.InfoFormat("Outgoing NCreate Response:{0}{1}", Environment.NewLine, rsp); return rsp; } /// <summary> /// NSet response handler to process the incoming NSetRequest message. Once finished, /// the NSet response DIMSE message is returned to be sent to the SCP. /// </summary> /// <param name="acceptor">The association acceptor for this association.</param> /// <param name="request">The incoming NSet request.</param> /// <returns>The NSet response DIMSE message.</returns> private NSetResponse NSet(AssociationAcceptor acceptor, NSetRequest request) { Logger.InfoFormat("Incoming NSet Request:{0}{1}", Environment.NewLine, request); NSetResponse rsp = new NSetResponse(request); // TODO: insert code to update an already existing procedure. rsp.Status = DimseStatus.DIMSE_SUCCESS; Logger.InfoFormat("Outgoing NSet Response:{0}{1}", Environment.NewLine, rsp); return rsp; } #endregion } }