# HG changeset patch # User Sebastien Jodogne # Date 1614007931 -3600 # Node ID cb8fcecf1b02bff621d0a43f03efbbf89ec7cfd7 # Parent c494ee5d010134b715c1195f9aecf0bc105dfed9 new option "Timeout" in "DicomModalities" to set DICOM SCU timeout on a per-modality basis diff -r c494ee5d0101 -r cb8fcecf1b02 NEWS --- a/NEWS Mon Feb 22 15:27:25 2021 +0100 +++ b/NEWS Mon Feb 22 16:32:11 2021 +0100 @@ -8,6 +8,8 @@ * If the storage area doesn't support range reading, or if "StorageCompression" is enabled, a new type of attachment "dicom-until-pixel-data" is generated. * New metadata automatically computed at the instance level: "PixelDataOffset" +* New configuration option related to networking: + - "Timeout" in "DicomModalities" to set DICOM SCU timeout on a per-modality basis REST API -------- diff -r c494ee5d0101 -r cb8fcecf1b02 OrthancFramework/Sources/DicomNetworking/DicomAssociationParameters.cpp --- a/OrthancFramework/Sources/DicomNetworking/DicomAssociationParameters.cpp Mon Feb 22 15:27:25 2021 +0100 +++ b/OrthancFramework/Sources/DicomNetworking/DicomAssociationParameters.cpp Mon Feb 22 16:32:11 2021 +0100 @@ -78,8 +78,8 @@ timeout_(0), // Will be set by SetDefaultParameters() maximumPduLength_(0) // Will be set by SetDefaultParameters() { + SetDefaultParameters(); remote_.SetApplicationEntityTitle("ANY-SCP"); - SetDefaultParameters(); } @@ -89,8 +89,8 @@ timeout_(0), // Will be set by SetDefaultParameters() maximumPduLength_(0) // Will be set by SetDefaultParameters() { + SetDefaultParameters(); SetRemoteModality(remote); - SetDefaultParameters(); } const std::string &DicomAssociationParameters::GetLocalApplicationEntityTitle() const @@ -113,6 +113,12 @@ { CheckHost(remote.GetHost()); remote_ = remote; + + if (remote.HasTimeout()) + { + timeout_ = remote.GetTimeout(); + assert(timeout_ != 0); + } } void DicomAssociationParameters::SetRemoteApplicationEntityTitle(const std::string &aet) diff -r c494ee5d0101 -r cb8fcecf1b02 OrthancFramework/Sources/DicomNetworking/RemoteModalityParameters.cpp --- a/OrthancFramework/Sources/DicomNetworking/RemoteModalityParameters.cpp Mon Feb 22 15:27:25 2021 +0100 +++ b/OrthancFramework/Sources/DicomNetworking/RemoteModalityParameters.cpp Mon Feb 22 16:32:11 2021 +0100 @@ -46,6 +46,7 @@ static const char* KEY_PORT = "Port"; static const char* KEY_USE_DICOM_TLS = "UseDicomTls"; static const char* KEY_LOCAL_AET = "LocalAet"; +static const char* KEY_TIMEOUT = "Timeout"; namespace Orthanc @@ -66,6 +67,7 @@ allowTranscoding_ = true; useDicomTls_ = false; localAet_.clear(); + timeout_ = 0; } @@ -293,6 +295,11 @@ { localAet_ = SerializationToolbox::ReadString(serialized, KEY_LOCAL_AET); } + + if (serialized.isMember(KEY_TIMEOUT)) + { + timeout_ = SerializationToolbox::ReadUnsignedInteger(serialized, KEY_TIMEOUT); + } } @@ -402,6 +409,7 @@ target[KEY_ALLOW_TRANSCODING] = allowTranscoding_; target[KEY_USE_DICOM_TLS] = useDicomTls_; target[KEY_LOCAL_AET] = localAet_; + target[KEY_TIMEOUT] = timeout_; } else { @@ -481,4 +489,19 @@ localAet_ = aet; } } + + void RemoteModalityParameters::SetTimeout(uint32_t seconds) + { + timeout_ = seconds; + } + + uint32_t RemoteModalityParameters::GetTimeout() const + { + return timeout_; + } + + bool RemoteModalityParameters::HasTimeout() const + { + return timeout_ != 0; + } } diff -r c494ee5d0101 -r cb8fcecf1b02 OrthancFramework/Sources/DicomNetworking/RemoteModalityParameters.h --- a/OrthancFramework/Sources/DicomNetworking/RemoteModalityParameters.h Mon Feb 22 15:27:25 2021 +0100 +++ b/OrthancFramework/Sources/DicomNetworking/RemoteModalityParameters.h Mon Feb 22 16:32:11 2021 +0100 @@ -47,6 +47,7 @@ bool allowTranscoding_; bool useDicomTls_; std::string localAet_; + uint32_t timeout_; void Clear(); @@ -107,5 +108,12 @@ const std::string& GetLocalAet() const; void SetLocalAet(const std::string& aet); + + // Setting it to "0" will use "DicomAssociationParameters::GetDefaultTimeout()" + void SetTimeout(uint32_t seconds); + + uint32_t GetTimeout() const; + + bool HasTimeout() const; }; } diff -r c494ee5d0101 -r cb8fcecf1b02 OrthancFramework/UnitTestsSources/JobsTests.cpp --- a/OrthancFramework/UnitTestsSources/JobsTests.cpp Mon Feb 22 15:27:25 2021 +0100 +++ b/OrthancFramework/UnitTestsSources/JobsTests.cpp Mon Feb 22 16:32:11 2021 +0100 @@ -1271,6 +1271,8 @@ modality.Serialize(s, false); ASSERT_EQ(Json::arrayValue, s.type()); ASSERT_FALSE(modality.IsDicomTlsEnabled()); + ASSERT_FALSE(modality.HasTimeout()); + ASSERT_EQ(0u, modality.GetTimeout()); } { @@ -1291,6 +1293,8 @@ ASSERT_FALSE(modality.IsDicomTlsEnabled()); ASSERT_FALSE(modality.HasLocalAet()); ASSERT_THROW(modality.GetLocalAet(), OrthancException); + ASSERT_FALSE(modality.HasTimeout()); + ASSERT_EQ(0u, modality.GetTimeout()); } s = Json::nullValue; @@ -1307,6 +1311,8 @@ modality.Serialize(s, true); ASSERT_EQ(Json::objectValue, s.type()); ASSERT_FALSE(modality.HasLocalAet()); + ASSERT_FALSE(modality.HasTimeout()); + ASSERT_EQ(0u, modality.GetTimeout()); } { @@ -1325,6 +1331,8 @@ ASSERT_TRUE(modality.IsTranscodingAllowed()); ASSERT_FALSE(modality.IsDicomTlsEnabled()); ASSERT_FALSE(modality.HasLocalAet()); + ASSERT_FALSE(modality.HasTimeout()); + ASSERT_EQ(0u, modality.GetTimeout()); } s["Port"] = "46"; @@ -1382,16 +1390,21 @@ { RemoteModalityParameters modality; modality.SetLocalAet("hello"); + modality.SetTimeout(42); ASSERT_TRUE(modality.IsAdvancedFormatNeeded()); modality.Serialize(s, true); ASSERT_EQ(Json::objectValue, s.type()); ASSERT_TRUE(modality.HasLocalAet()); + ASSERT_TRUE(modality.HasTimeout()); + ASSERT_EQ(42u, modality.GetTimeout()); } { RemoteModalityParameters modality(s); ASSERT_TRUE(modality.HasLocalAet()); ASSERT_EQ("hello", modality.GetLocalAet()); + ASSERT_TRUE(modality.HasTimeout()); + ASSERT_EQ(42u, modality.GetTimeout()); } { @@ -1412,6 +1425,8 @@ ASSERT_FALSE(modality.IsDicomTlsEnabled()); ASSERT_FALSE(modality.HasLocalAet()); ASSERT_THROW(modality.GetLocalAet(), OrthancException); + ASSERT_FALSE(modality.HasTimeout()); + ASSERT_EQ(0u, modality.GetTimeout()); } { @@ -1424,6 +1439,7 @@ t["AllowTranscoding"] = false; t["UseDicomTls"] = true; t["LocalAet"] = "world"; + t["Timeout"] = 20; RemoteModalityParameters modality(t); ASSERT_TRUE(modality.IsAdvancedFormatNeeded()); @@ -1436,6 +1452,8 @@ ASSERT_TRUE(modality.IsDicomTlsEnabled()); ASSERT_TRUE(modality.HasLocalAet()); ASSERT_EQ("world", modality.GetLocalAet()); + ASSERT_TRUE(modality.HasTimeout()); + ASSERT_EQ(20u, modality.GetTimeout()); } { @@ -1487,6 +1505,8 @@ ASSERT_FALSE(b.GetRemoteModality().IsDicomTlsEnabled()); ASSERT_FALSE(b.GetRemoteModality().HasLocalAet()); ASSERT_THROW(b.GetRemoteModality().GetLocalAet(), OrthancException); + ASSERT_FALSE(b.GetRemoteModality().HasTimeout()); + ASSERT_EQ(0u, b.GetRemoteModality().GetTimeout()); } { @@ -1495,6 +1515,7 @@ p.SetPortNumber(4242); p.SetHost("hello.world.com"); p.SetDicomTlsEnabled(true); + p.SetTimeout(42); DicomAssociationParameters a("HELLO", p); a.SetOwnCertificatePath("key", "crt"); @@ -1521,5 +1542,7 @@ ASSERT_EQ("crt", b.GetOwnCertificatePath()); ASSERT_EQ("trusted", b.GetTrustedCertificatesPath()); ASSERT_EQ(131072u, b.GetMaximumPduLength()); + ASSERT_TRUE(b.GetRemoteModality().HasTimeout()); + ASSERT_EQ(42u, b.GetRemoteModality().GetTimeout()); } } diff -r c494ee5d0101 -r cb8fcecf1b02 OrthancServer/Resources/Configuration.json --- a/OrthancServer/Resources/Configuration.json Mon Feb 22 15:27:25 2021 +0100 +++ b/OrthancServer/Resources/Configuration.json Mon Feb 22 16:32:11 2021 +0100 @@ -355,9 +355,11 @@ * used when opening a SCU connection from Orthanc to this remote * modality. By default, DICOM TLS is not enabled. * - * The "LocalAet" allows to overwrite the global "DicomAet" - * configuration option in order to specify another AET for - * Orthanc when initiating an SCU to this very specific modality. + * The "LocalAet" option allows one to overwrite the global + * "DicomAet" configuration option in order to specify another AET + * for Orthanc when initiating an SCU to this very specific + * modality. Similarly, "Timeout" allows one to overwrite the + * global value "DicomScuTimeout" on a per-modality basis. **/ //"untrusted" : { // "AET" : "ORTHANC", @@ -373,6 +375,7 @@ // "AllowTranscoding" : true, // new in 1.7.0 // "UseDicomTls" : false // new in 1.9.0 // "LocalAet" : "HELLO" // new in 1.9.0 + // "Timeout" : 60 // new in 1.9.1 //} },