changeset 1799:4f01c9d73f02 worklists

calledAet made available to all the handlers
author Sebastien Jodogne <s.jodogne@gmail.com>
date Fri, 20 Nov 2015 12:57:14 +0100
parents e92cd8841a5f
children 30e97a1f4093
files OrthancServer/DicomProtocol/IApplicationEntityFilter.h OrthancServer/DicomProtocol/IFindRequestHandler.h OrthancServer/DicomProtocol/IMoveRequestHandler.h OrthancServer/DicomProtocol/IWorklistRequestHandler.h OrthancServer/Internals/CommandDispatcher.cpp OrthancServer/Internals/CommandDispatcher.h OrthancServer/Internals/FindScp.cpp OrthancServer/Internals/FindScp.h OrthancServer/Internals/MoveScp.cpp OrthancServer/Internals/MoveScp.h OrthancServer/OrthancFindRequestHandler.cpp OrthancServer/OrthancFindRequestHandler.h OrthancServer/OrthancMoveRequestHandler.cpp OrthancServer/OrthancMoveRequestHandler.h OrthancServer/main.cpp Plugins/Include/orthanc/OrthancCPlugin.h
diffstat 16 files changed, 120 insertions(+), 55 deletions(-) [+]
line wrap: on
line diff
--- a/OrthancServer/DicomProtocol/IApplicationEntityFilter.h	Fri Nov 20 12:00:34 2015 +0100
+++ b/OrthancServer/DicomProtocol/IApplicationEntityFilter.h	Fri Nov 20 12:57:14 2015 +0100
@@ -45,15 +45,18 @@
     {
     }
 
-    virtual bool IsAllowedConnection(const std::string& callingIp,
-                                     const std::string& callingAet) = 0;
+    virtual bool IsAllowedConnection(const std::string& remoteIp,
+                                     const std::string& remoteAet,
+                                     const std::string& calledAet) = 0;
 
-    virtual bool IsAllowedRequest(const std::string& callingIp,
-                                  const std::string& callingAet,
+    virtual bool IsAllowedRequest(const std::string& remoteIp,
+                                  const std::string& remoteAet,
+                                  const std::string& calledAet,
                                   DicomRequestType type) = 0;
 
-    virtual bool IsAllowedTransferSyntax(const std::string& callingIp,
-                                         const std::string& callingAet,
+    virtual bool IsAllowedTransferSyntax(const std::string& remoteIp,
+                                         const std::string& remoteAet,
+                                         const std::string& calledAet,
                                          TransferSyntax syntax) = 0;
   };
 }
--- a/OrthancServer/DicomProtocol/IFindRequestHandler.h	Fri Nov 20 12:00:34 2015 +0100
+++ b/OrthancServer/DicomProtocol/IFindRequestHandler.h	Fri Nov 20 12:57:14 2015 +0100
@@ -52,6 +52,7 @@
     virtual bool Handle(DicomFindAnswers& answers,
                         const DicomMap& input,
                         const std::string& remoteIp,
-                        const std::string& remoteAet) = 0;
+                        const std::string& remoteAet,
+                        const std::string& calledAet) = 0;
   };
 }
--- a/OrthancServer/DicomProtocol/IMoveRequestHandler.h	Fri Nov 20 12:00:34 2015 +0100
+++ b/OrthancServer/DicomProtocol/IMoveRequestHandler.h	Fri Nov 20 12:57:14 2015 +0100
@@ -70,7 +70,8 @@
     virtual IMoveRequestIterator* Handle(const std::string& target,
                                          const DicomMap& input,
                                          const std::string& remoteIp,
-                                         const std::string& remoteAet) = 0;
+                                         const std::string& remoteAet,
+                                         const std::string& calledAet) = 0;
   };
 
 }
--- a/OrthancServer/DicomProtocol/IWorklistRequestHandler.h	Fri Nov 20 12:00:34 2015 +0100
+++ b/OrthancServer/DicomProtocol/IWorklistRequestHandler.h	Fri Nov 20 12:57:14 2015 +0100
@@ -52,6 +52,7 @@
     virtual bool Handle(DicomFindAnswers& answers,
                         ParsedDicomFile& query,
                         const std::string& remoteIp,
-                        const std::string& remoteAet) = 0;
+                        const std::string& remoteAet,
+                        const std::string& calledAet) = 0;
   };
 }
--- a/OrthancServer/Internals/CommandDispatcher.cpp	Fri Nov 20 12:00:34 2015 +0100
+++ b/OrthancServer/Internals/CommandDispatcher.cpp	Fri Nov 20 12:57:14 2015 +0100
@@ -465,17 +465,17 @@
       }
 
       // Retrieve the AET and the IP address of the remote modality
-      std::string callingAet;
-      std::string callingIp;
+      std::string remoteAet;
+      std::string remoteIp;
       std::string calledAet;
   
       {
-        DIC_AE callingAet_C;
+        DIC_AE remoteAet_C;
         DIC_AE calledAet_C;
-        DIC_AE callingIp_C;
+        DIC_AE remoteIp_C;
         DIC_AE calledIP_C;
-        if (ASC_getAPTitles(assoc->params, callingAet_C, calledAet_C, NULL).bad() ||
-            ASC_getPresentationAddresses(assoc->params, callingIp_C, calledIP_C).bad())
+        if (ASC_getAPTitles(assoc->params, remoteAet_C, calledAet_C, NULL).bad() ||
+            ASC_getPresentationAddresses(assoc->params, remoteIp_C, calledIP_C).bad())
         {
           T_ASC_RejectParameters rej =
             {
@@ -488,13 +488,13 @@
           return NULL;
         }
 
-        callingIp = std::string(/*OFSTRING_GUARD*/(callingIp_C));
-        callingAet = std::string(/*OFSTRING_GUARD*/(callingAet_C));
+        remoteIp = std::string(/*OFSTRING_GUARD*/(remoteIp_C));
+        remoteAet = std::string(/*OFSTRING_GUARD*/(remoteAet_C));
         calledAet = (/*OFSTRING_GUARD*/(calledAet_C));
       }
 
-      LOG(INFO) << "Association Received from AET " << callingAet 
-                << " on IP " << callingIp;
+      LOG(INFO) << "Association Received from AET " << remoteAet 
+                << " on IP " << remoteIp;
 
 
       std::vector<const char*> transferSyntaxes;
@@ -506,13 +506,13 @@
 
       // New transfer syntaxes supported since Orthanc 0.7.2
       if (!server.HasApplicationEntityFilter() ||
-          server.GetApplicationEntityFilter().IsAllowedTransferSyntax(callingIp, callingAet, TransferSyntax_Deflated))
+          server.GetApplicationEntityFilter().IsAllowedTransferSyntax(remoteIp, remoteAet, calledAet, TransferSyntax_Deflated))
       {
         transferSyntaxes.push_back(UID_DeflatedExplicitVRLittleEndianTransferSyntax); 
       }
 
       if (!server.HasApplicationEntityFilter() ||
-          server.GetApplicationEntityFilter().IsAllowedTransferSyntax(callingIp, callingAet, TransferSyntax_Jpeg))
+          server.GetApplicationEntityFilter().IsAllowedTransferSyntax(remoteIp, remoteAet, calledAet, TransferSyntax_Jpeg))
       {
         transferSyntaxes.push_back(UID_JPEGProcess1TransferSyntax);
         transferSyntaxes.push_back(UID_JPEGProcess2_4TransferSyntax);
@@ -537,14 +537,14 @@
       }
 
       if (!server.HasApplicationEntityFilter() ||
-          server.GetApplicationEntityFilter().IsAllowedTransferSyntax(callingIp, callingAet, TransferSyntax_Jpeg2000))
+          server.GetApplicationEntityFilter().IsAllowedTransferSyntax(remoteIp, remoteAet, calledAet, TransferSyntax_Jpeg2000))
       {
         transferSyntaxes.push_back(UID_JPEG2000LosslessOnlyTransferSyntax);
         transferSyntaxes.push_back(UID_JPEG2000TransferSyntax);
       }
 
       if (!server.HasApplicationEntityFilter() ||
-          server.GetApplicationEntityFilter().IsAllowedTransferSyntax(callingIp, callingAet, TransferSyntax_JpegLossless))
+          server.GetApplicationEntityFilter().IsAllowedTransferSyntax(remoteIp, remoteAet, calledAet, TransferSyntax_JpegLossless))
       {
         transferSyntaxes.push_back(UID_JPEG2000LosslessOnlyTransferSyntax);
         transferSyntaxes.push_back(UID_JPEG2000TransferSyntax);
@@ -553,21 +553,21 @@
       }
 
       if (!server.HasApplicationEntityFilter() ||
-          server.GetApplicationEntityFilter().IsAllowedTransferSyntax(callingIp, callingAet, TransferSyntax_Jpip))
+          server.GetApplicationEntityFilter().IsAllowedTransferSyntax(remoteIp, remoteAet, calledAet, TransferSyntax_Jpip))
       {
         transferSyntaxes.push_back(UID_JPIPReferencedTransferSyntax);
         transferSyntaxes.push_back(UID_JPIPReferencedDeflateTransferSyntax);
       }
 
       if (!server.HasApplicationEntityFilter() ||
-          server.GetApplicationEntityFilter().IsAllowedTransferSyntax(callingIp, callingAet, TransferSyntax_Mpeg2))
+          server.GetApplicationEntityFilter().IsAllowedTransferSyntax(remoteIp, remoteAet, calledAet, TransferSyntax_Mpeg2))
       {
         transferSyntaxes.push_back(UID_MPEG2MainProfileAtMainLevelTransferSyntax);
         transferSyntaxes.push_back(UID_MPEG2MainProfileAtHighLevelTransferSyntax);
       }
 
       if (!server.HasApplicationEntityFilter() ||
-          server.GetApplicationEntityFilter().IsAllowedTransferSyntax(callingIp, callingAet, TransferSyntax_Rle))
+          server.GetApplicationEntityFilter().IsAllowedTransferSyntax(remoteIp, remoteAet, calledAet, TransferSyntax_Rle))
       {
         transferSyntaxes.push_back(UID_RLELosslessTransferSyntax);
       }
@@ -643,9 +643,9 @@
       }
 
       if (server.HasApplicationEntityFilter() &&
-          !server.GetApplicationEntityFilter().IsAllowedConnection(callingIp, callingAet))
+          !server.GetApplicationEntityFilter().IsAllowedConnection(remoteIp, remoteAet, calledAet))
       {
-        LOG(WARNING) << "Rejected association for remote AET " << callingAet << " on IP " << callingIp;
+        LOG(WARNING) << "Rejected association for remote AET " << remoteAet << " on IP " << remoteIp;
         T_ASC_RejectParameters rej =
           {
             ASC_RESULT_REJECTEDPERMANENT,
@@ -692,7 +692,7 @@
       }
 
       IApplicationEntityFilter* filter = server.HasApplicationEntityFilter() ? &server.GetApplicationEntityFilter() : NULL;
-      return new CommandDispatcher(server, assoc, callingIp, callingAet, filter);
+      return new CommandDispatcher(server, assoc, remoteIp, remoteAet, calledAet, filter);
     }
 
     bool CommandDispatcher::Step()
@@ -776,7 +776,7 @@
         if (supported && 
             request != DicomRequestType_Echo &&  // Always allow incoming ECHO requests
             filter_ != NULL &&
-            !filter_->IsAllowedRequest(remoteIp_, remoteAet_, request))
+            !filter_->IsAllowedRequest(remoteIp_, remoteAet_, calledAet_, request))
         {
           LOG(ERROR) << EnumerationToString(request) 
                      << " requests are disallowed for the AET \"" 
@@ -812,7 +812,7 @@
               {
                 std::auto_ptr<IMoveRequestHandler> handler
                   (server_.GetMoveRequestHandlerFactory().ConstructMoveRequestHandler());
-                cond = Internals::moveScp(assoc_, &msg, presID, *handler, remoteIp_, remoteAet_);
+                cond = Internals::moveScp(assoc_, &msg, presID, *handler, remoteIp_, remoteAet_, calledAet_);
               }
               break;
 
@@ -833,7 +833,7 @@
                 }
 
                 cond = Internals::findScp(assoc_, &msg, presID, findHandler.get(), 
-                                          worklistHandler.get(), remoteIp_, remoteAet_);
+                                          worklistHandler.get(), remoteIp_, remoteAet_, calledAet_);
               }
               break;
 
--- a/OrthancServer/Internals/CommandDispatcher.h	Fri Nov 20 12:00:34 2015 +0100
+++ b/OrthancServer/Internals/CommandDispatcher.h	Fri Nov 20 12:57:14 2015 +0100
@@ -52,6 +52,7 @@
       T_ASC_Association* assoc_;
       std::string remoteIp_;
       std::string remoteAet_;
+      std::string calledAet_;
       IApplicationEntityFilter* filter_;
 
     public:
@@ -59,11 +60,13 @@
                         T_ASC_Association* assoc,
                         const std::string& remoteIp,
                         const std::string& remoteAet,
+                        const std::string& calledAet,
                         IApplicationEntityFilter* filter) :
         server_(server),
         assoc_(assoc),
         remoteIp_(remoteIp),
         remoteAet_(remoteAet),
+        calledAet_(calledAet),
         filter_(filter)
       {
         clientTimeout_ = server.GetClientTimeout();
--- a/OrthancServer/Internals/FindScp.cpp	Fri Nov 20 12:00:34 2015 +0100
+++ b/OrthancServer/Internals/FindScp.cpp	Fri Nov 20 12:57:14 2015 +0100
@@ -101,6 +101,7 @@
       DcmDataset* lastRequest_;
       const std::string* remoteIp_;
       const std::string* remoteAet_;
+      const std::string* calledAet_;
       bool noCroppingOfResults_;
     };
 
@@ -135,7 +136,8 @@
             {
               ParsedDicomFile query(*requestIdentifiers);
               data.noCroppingOfResults_ = data.worklistHandler_->Handle(data.answers_, query,
-                                                                        *data.remoteIp_, *data.remoteAet_);
+                                                                        *data.remoteIp_, *data.remoteAet_,
+                                                                        *data.calledAet_);
               ok = true;
             }
             else
@@ -150,7 +152,8 @@
               DicomMap input;
               FromDcmtkBridge::Convert(input, *requestIdentifiers);
               data.noCroppingOfResults_ = data.findHandler_->Handle(data.answers_, input,
-                                                                    *data.remoteIp_, *data.remoteAet_);
+                                                                    *data.remoteIp_, *data.remoteAet_,
+                                                                    *data.calledAet_);
               ok = true;
             }
             else
@@ -211,7 +214,8 @@
                                  IFindRequestHandler* findHandler,
                                  IWorklistRequestHandler* worklistHandler,
                                  const std::string& remoteIp,
-                                 const std::string& remoteAet)
+                                 const std::string& remoteAet,
+                                 const std::string& calledAet)
   {
     FindScpData data;
     data.lastRequest_ = NULL;
@@ -219,6 +223,7 @@
     data.worklistHandler_ = worklistHandler;
     data.remoteIp_ = &remoteIp;
     data.remoteAet_ = &remoteAet;
+    data.calledAet_ = &calledAet;
     data.noCroppingOfResults_ = true;
 
     OFCondition cond = DIMSE_findProvider(assoc, presID, &msg->msg.CFindRQ, 
--- a/OrthancServer/Internals/FindScp.h	Fri Nov 20 12:00:34 2015 +0100
+++ b/OrthancServer/Internals/FindScp.h	Fri Nov 20 12:57:14 2015 +0100
@@ -47,6 +47,7 @@
                         IFindRequestHandler* findHandler,   // can be NULL
                         IWorklistRequestHandler* worklistHandler,   // can be NULL
                         const std::string& remoteIp,
-                        const std::string& remoteAet);
+                        const std::string& remoteAet,
+                        const std::string& calledAet);
   }
 }
--- a/OrthancServer/Internals/MoveScp.cpp	Fri Nov 20 12:00:34 2015 +0100
+++ b/OrthancServer/Internals/MoveScp.cpp	Fri Nov 20 12:57:14 2015 +0100
@@ -105,6 +105,7 @@
       std::auto_ptr<IMoveRequestIterator> iterator_;
       const std::string* remoteIp_;
       const std::string* remoteAet_;
+      const std::string* calledAet_;
     };
 
 
@@ -133,7 +134,8 @@
         try
         {
           data.iterator_.reset(data.handler_->Handle(data.target_, input,
-                                                     *data.remoteIp_, *data.remoteAet_));
+                                                     *data.remoteIp_, *data.remoteAet_,
+                                                     *data.calledAet_));
 
           if (data.iterator_.get() == NULL)
           {
@@ -215,7 +217,8 @@
                                  T_ASC_PresentationContextID presID,
                                  IMoveRequestHandler& handler,
                                  const std::string& remoteIp,
-                                 const std::string& remoteAet)
+                                 const std::string& remoteAet,
+                                 const std::string& calledAet)
   {
     MoveScpData data;
     data.target_ = std::string(msg->msg.CMoveRQ.MoveDestination);
@@ -223,6 +226,7 @@
     data.handler_ = &handler;
     data.remoteIp_ = &remoteIp;
     data.remoteAet_ = &remoteAet;
+    data.calledAet_ = &calledAet;
 
     OFCondition cond = DIMSE_moveProvider(assoc, presID, &msg->msg.CMoveRQ, 
                                           MoveScpCallback, &data,
--- a/OrthancServer/Internals/MoveScp.h	Fri Nov 20 12:00:34 2015 +0100
+++ b/OrthancServer/Internals/MoveScp.h	Fri Nov 20 12:57:14 2015 +0100
@@ -45,6 +45,7 @@
                         T_ASC_PresentationContextID presID,
                         IMoveRequestHandler& handler,
                         const std::string& remoteIp,
-                        const std::string& remoteAet);
+                        const std::string& remoteAet,
+                        const std::string& calledAet);
   }
 }
--- a/OrthancServer/OrthancFindRequestHandler.cpp	Fri Nov 20 12:00:34 2015 +0100
+++ b/OrthancServer/OrthancFindRequestHandler.cpp	Fri Nov 20 12:57:14 2015 +0100
@@ -91,10 +91,11 @@
   bool OrthancFindRequestHandler::Handle(DicomFindAnswers& answers,
                                          const DicomMap& input,
                                          const std::string& remoteIp,
-                                         const std::string& remoteAet)
+                                         const std::string& remoteAet,
+                                         const std::string& calledAet)
   {
     /**
-     * Ensure that the calling modality is known to Orthanc.
+     * Ensure that the remote modality is known to Orthanc.
      **/
 
     RemoteModalityParameters modality;
--- a/OrthancServer/OrthancFindRequestHandler.h	Fri Nov 20 12:00:34 2015 +0100
+++ b/OrthancServer/OrthancFindRequestHandler.h	Fri Nov 20 12:57:14 2015 +0100
@@ -58,7 +58,8 @@
     virtual bool Handle(DicomFindAnswers& answers,
                         const DicomMap& input,
                         const std::string& remoteIp,
-                        const std::string& remoteAet);
+                        const std::string& remoteAet,
+                        const std::string& calledAet);
 
     unsigned int GetMaxResults() const
     {
--- a/OrthancServer/OrthancMoveRequestHandler.cpp	Fri Nov 20 12:00:34 2015 +0100
+++ b/OrthancServer/OrthancMoveRequestHandler.cpp	Fri Nov 20 12:57:14 2015 +0100
@@ -165,7 +165,8 @@
   IMoveRequestIterator* OrthancMoveRequestHandler::Handle(const std::string& targetAet,
                                                           const DicomMap& input,
                                                           const std::string& remoteIp,
-                                                          const std::string& remoteAet)
+                                                          const std::string& remoteAet,
+                                                          const std::string& calledAet)
   {
     LOG(WARNING) << "Move-SCU request received for AET \"" << targetAet << "\"";
 
--- a/OrthancServer/OrthancMoveRequestHandler.h	Fri Nov 20 12:00:34 2015 +0100
+++ b/OrthancServer/OrthancMoveRequestHandler.h	Fri Nov 20 12:57:14 2015 +0100
@@ -54,6 +54,7 @@
     virtual IMoveRequestIterator* Handle(const std::string& targetAet,
                                          const DicomMap& input,
                                          const std::string& remoteIp,
-                                         const std::string& remoteAet);
+                                         const std::string& remoteAet,
+                                         const std::string& calledAet);
   };
 }
--- a/OrthancServer/main.cpp	Fri Nov 20 12:00:34 2015 +0100
+++ b/OrthancServer/main.cpp	Fri Nov 20 12:57:14 2015 +0100
@@ -110,8 +110,11 @@
   virtual bool Handle(DicomFindAnswers& answers,
                       ParsedDicomFile& query,
                       const std::string& remoteIp,
-                      const std::string& remoteAet)
+                      const std::string& remoteAet,
+                      const std::string& calledAet)
   {
+    LOG(WARNING) << "Worklist Find query from " << remoteAet << " to " << calledAet;
+
     bool caseSensitivePN = Configuration::GetGlobalBoolParameter("CaseSensitivePN", false);
     HierarchicalMatcher matcher(query, caseSensitivePN);
 
@@ -227,14 +230,16 @@
   {
   }
 
-  virtual bool IsAllowedConnection(const std::string& /*callingIp*/,
-                                   const std::string& /*callingAet*/)
+  virtual bool IsAllowedConnection(const std::string& /*remoteIp*/,
+                                   const std::string& /*remoteAet*/,
+                                   const std::string& /*calledAet*/)
   {
     return true;
   }
 
-  virtual bool IsAllowedRequest(const std::string& /*callingIp*/,
-                                const std::string& callingAet,
+  virtual bool IsAllowedRequest(const std::string& /*remoteIp*/,
+                                const std::string& remoteAet,
+                                const std::string& /*calledAet*/,
                                 DicomRequestType type)
   {
     if (type == DicomRequestType_Store)
@@ -243,9 +248,9 @@
       return true;
     }
 
-    if (!Configuration::IsKnownAETitle(callingAet))
+    if (!Configuration::IsKnownAETitle(remoteAet))
     {
-      LOG(ERROR) << "Unknown remote DICOM modality AET: \"" << callingAet << "\"";
+      LOG(ERROR) << "Unknown remote DICOM modality AET: \"" << remoteAet << "\"";
       return false;
     }
     else
@@ -254,8 +259,9 @@
     }
   }
 
-  virtual bool IsAllowedTransferSyntax(const std::string& callingIp,
-                                       const std::string& callingAet,
+  virtual bool IsAllowedTransferSyntax(const std::string& remoteIp,
+                                       const std::string& remoteAet,
+                                       const std::string& /*calledAet*/,
                                        TransferSyntax syntax)
   {
     std::string configuration;
@@ -302,8 +308,8 @@
       if (locker.GetLua().IsExistingFunction(lua.c_str()))
       {
         LuaFunctionCall call(locker.GetLua(), lua.c_str());
-        call.PushString(callingAet);
-        call.PushString(callingIp);
+        call.PushString(remoteAet);
+        call.PushString(remoteIp);
         return call.ExecutePredicate();
       }
     }
--- a/Plugins/Include/orthanc/OrthancCPlugin.h	Fri Nov 20 12:00:34 2015 +0100
+++ b/Plugins/Include/orthanc/OrthancCPlugin.h	Fri Nov 20 12:57:14 2015 +0100
@@ -49,6 +49,9 @@
  * @defgroup Callbacks Callbacks
  * @brief Functions to register and manage callbacks by the plugins.
  *
+ * @defgroup Worklists Worklists
+ * @brief Functions to register and manage worklists.
+ *
  * @defgroup Orthanc Orthanc
  * @brief Functions to access the content of the Orthanc server.
  **/
@@ -755,6 +758,22 @@
 
 
   /**
+   * @brief Opaque structure to an object that represents a C-Find query.
+   * @ingroup Worklists
+   **/
+  typedef struct _OrthancPluginWorklistQuery_t OrthancPluginWorklistQuery;
+
+
+
+  /**
+   * @brief Opaque structure to an object that represents the answers to a C-Find query.
+   * @ingroup Worklists
+   **/
+  typedef struct _OrthancPluginWorklistAnswers_t OrthancPluginWorklistAnswers;
+
+
+
+  /**
    * @brief Signature of a callback function that answers to a REST request.
    * @ingroup Callbacks
    **/
@@ -850,6 +869,22 @@
 
 
   /**
+   * @brief Callback to handle the C-Find SCP requests received by Orthanc.
+   *
+   * Signature of a callback function that is triggered when Orthanc receives a C-Find SCP request.
+   *
+   * @return 0 if success, other value if error.
+   * @ingroup Worklists
+   **/
+  typedef OrthancPluginErrorCode (*OrthancPluginFindWorklist) (
+    OrthancPluginWorklistAnswers*     answers,
+    const OrthancPluginWorklistQuery* query,
+    const char*                       calledAet,
+    const char*                       remoteAet);
+
+
+
+  /**
    * @brief Data structure that contains information about the Orthanc core.
    **/
   typedef struct _OrthancPluginContext_t