changeset 1806:cd213ebcaefd

UnknownSopClassAccepted option
author Sebastien Jodogne <s.jodogne@gmail.com>
date Mon, 23 Nov 2015 15:24:39 +0100
parents bdef349f742c
children 91216c42c6e5 67466dcd23b1
files NEWS OrthancServer/DicomProtocol/IApplicationEntityFilter.h OrthancServer/Internals/CommandDispatcher.cpp OrthancServer/main.cpp Resources/Configuration.json Resources/Samples/Lua/TransferSyntaxDisable.lua Resources/Samples/Lua/TransferSyntaxEnable.lua
diffstat 7 files changed, 75 insertions(+), 21 deletions(-) [+]
line wrap: on
line diff
--- a/NEWS	Fri Nov 20 16:50:01 2015 +0100
+++ b/NEWS	Mon Nov 23 15:24:39 2015 +0100
@@ -1,15 +1,27 @@
 Pending changes in the mainline
 ===============================
 
-* Full indexation of the patient/study tags to speed up searches and C-Find
+Major
+-----
+
+* Experimental support of DICOM C-Find SCP for modality worklists through plugins
+* Support of DICOM C-Find SCU for modality worklists ("/modalities/{dicom}/find-worklist")
+
+Minor
+-----
+
+* New configuration options:
+  - "UnknownSopClassAccepted" to disable promiscuous mode (accept unknown SOP class UID)
+  - New configuration option: "Dictionary" to declare custom DICOM tags
 * Add ".dcm" suffix to files in ZIP archives (cf. URI ".../archive")
-* "/tools/create-dicom": Support of binary tags encoded using data URI scheme
-* "/tools/create-dicom": Support of hierarchical structures (creation of sequences)
+* "/tools/create-dicom":
+  - Support of binary tags encoded using data URI scheme
+  - Support of hierarchical structures (creation of sequences)
+  - Create tags with unknown VR
 * "/modify" can insert/modify sequences
 * "/series/.../ordered-slices" to order the slices of a 2D+t or 3D image
 * New URI "/tools/shutdown" to stop Orthanc from the REST API
 * New URIs for attachments: ".../compress", ".../uncompress" and ".../is-compressed"
-* New configuration option: "Dictionary" to declare custom DICOM tags
 * MIME content type can be associated to custom attachments (cf. "UserContentType")
 * New URIs "/tools/create-archive" and "/tools/create-media" to create ZIP/DICOMDIR
   from a set of resources
@@ -35,10 +47,10 @@
 Maintenance
 -----------
 
+* Full indexation of the patient/study tags to speed up searches and C-Find
 * Full refactoring of the searching features
 * C-Move SCP for studies using AccessionNumber tag
 * Fix issue 4 (C-Store Association not renegotiated on Specific-to-specific transfer syntax change)
-* "/tools/create-dicom" can create tags with unknown VR
 * "--logdir" flag creates a single log file instead of 3 separate files for errors/warnings/infos
 * "--errors" flag lists the error codes that could be returned by Orthanc
 * Under Windows, the exit status of Orthanc corresponds to the encountered error code
--- a/OrthancServer/DicomProtocol/IApplicationEntityFilter.h	Fri Nov 20 16:50:01 2015 +0100
+++ b/OrthancServer/DicomProtocol/IApplicationEntityFilter.h	Mon Nov 23 15:24:39 2015 +0100
@@ -58,5 +58,9 @@
                                          const std::string& remoteAet,
                                          const std::string& calledAet,
                                          TransferSyntax syntax) = 0;
+
+    virtual bool IsUnknownSopClassAccepted(const std::string& remoteIp,
+                                           const std::string& remoteAet,
+                                           const std::string& calledAet) = 0;
   };
 }
--- a/OrthancServer/Internals/CommandDispatcher.cpp	Fri Nov 20 16:50:01 2015 +0100
+++ b/OrthancServer/Internals/CommandDispatcher.cpp	Mon Nov 23 15:24:39 2015 +0100
@@ -91,15 +91,11 @@
 #include <dcmtk/dcmnet/dcasccfg.h>      /* for class DcmAssociationConfiguration */
 #include <boost/lexical_cast.hpp>
 
-#define ORTHANC_PROMISCUOUS 1
-
 static OFBool    opt_rejectWithoutImplementationUID = OFFalse;
 
 
 
-#if ORTHANC_PROMISCUOUS == 1
-static
-DUL_PRESENTATIONCONTEXT *
+static DUL_PRESENTATIONCONTEXT *
 findPresentationContextID(LST_HEAD * head,
                           T_ASC_PresentationContextID presentationContextID)
 {
@@ -231,7 +227,6 @@
   }
   return cond;
 }
-#endif
 
 
 
@@ -590,17 +585,22 @@
         return NULL;
       }
 
-#if ORTHANC_PROMISCUOUS == 1
-      /* accept everything not known not to be a storage SOP class */
-      cond = acceptUnknownContextsWithPreferredTransferSyntaxes(
-        assoc->params, &transferSyntaxes[0], transferSyntaxes.size());
-      if (cond.bad())
+      if (!server.HasApplicationEntityFilter() ||
+          server.GetApplicationEntityFilter().IsUnknownSopClassAccepted(remoteIp, remoteAet, calledAet))
       {
-        LOG(INFO) << cond.text();
-        AssociationCleanup(assoc);
-        return NULL;
+        /*
+         * Promiscous mode is enabled: Accept everything not known not
+         * to be a storage SOP class.
+         **/
+        cond = acceptUnknownContextsWithPreferredTransferSyntaxes(
+          assoc->params, &transferSyntaxes[0], transferSyntaxes.size());
+        if (cond.bad())
+        {
+          LOG(INFO) << cond.text();
+          AssociationCleanup(assoc);
+          return NULL;
+        }
       }
-#endif
 
       /* set our app title */
       ASC_setAPTitles(assoc->params, NULL, NULL, server.GetApplicationEntityTitle().c_str());
--- a/OrthancServer/main.cpp	Fri Nov 20 16:50:01 2015 +0100
+++ b/OrthancServer/main.cpp	Mon Nov 23 15:24:39 2015 +0100
@@ -190,7 +190,7 @@
 
   virtual bool IsAllowedTransferSyntax(const std::string& remoteIp,
                                        const std::string& remoteAet,
-                                       const std::string& /*calledAet*/,
+                                       const std::string& calledAet,
                                        TransferSyntax syntax)
   {
     std::string configuration;
@@ -239,6 +239,32 @@
         LuaFunctionCall call(locker.GetLua(), lua.c_str());
         call.PushString(remoteAet);
         call.PushString(remoteIp);
+        call.PushString(calledAet);
+        return call.ExecutePredicate();
+      }
+    }
+
+    return Configuration::GetGlobalBoolParameter(configuration, true);
+  }
+
+
+  virtual bool IsUnknownSopClassAccepted(const std::string& remoteIp,
+                                         const std::string& remoteAet,
+                                         const std::string& calledAet)
+  {
+    static const char* configuration = "UnknownSopClassAccepted";
+
+    {
+      std::string lua = "Is" + std::string(configuration);
+
+      LuaScripting::Locker locker(context_.GetLua());
+      
+      if (locker.GetLua().IsExistingFunction(lua.c_str()))
+      {
+        LuaFunctionCall call(locker.GetLua(), lua.c_str());
+        call.PushString(remoteAet);
+        call.PushString(remoteIp);
+        call.PushString(calledAet);
         return call.ExecutePredicate();
       }
     }
--- a/Resources/Configuration.json	Fri Nov 20 16:50:01 2015 +0100
+++ b/Resources/Configuration.json	Mon Nov 23 15:24:39 2015 +0100
@@ -102,6 +102,10 @@
   "Mpeg2TransferSyntaxAccepted"        : true,
   "RleTransferSyntaxAccepted"          : true,
 
+  // Whether Orthanc accepts to act as C-Store SCP for unknown storage
+  // SOP classes (aka. "promiscuous mode")
+  "UnknownSopClassAccepted"            : true,
+
 
 
   /**
--- a/Resources/Samples/Lua/TransferSyntaxDisable.lua	Fri Nov 20 16:50:01 2015 +0100
+++ b/Resources/Samples/Lua/TransferSyntaxDisable.lua	Mon Nov 23 15:24:39 2015 +0100
@@ -26,4 +26,8 @@
    return false
 end
 
+function IsUnknownSopClassAccepted(aet, ip)
+   return false
+end
+
 print('All special transfer syntaxes are now disallowed')
--- a/Resources/Samples/Lua/TransferSyntaxEnable.lua	Fri Nov 20 16:50:01 2015 +0100
+++ b/Resources/Samples/Lua/TransferSyntaxEnable.lua	Mon Nov 23 15:24:39 2015 +0100
@@ -26,4 +26,8 @@
    return true
 end
 
+function IsUnknownSopClassAccepted(aet, ip)
+   return true
+end
+
 print('All special transfer syntaxes are now accepted')