# HG changeset patch # User Alain Mazy # Date 1700654227 -3600 # Node ID 7a20ee948676d620635acd8551f6569ffc631ccd # Parent 85da6dcd0e08eb9ef4bb700dde83a10c87f4eeb8 Added a new 'Telemis' manufacturer for DicomModalities diff -r 85da6dcd0e08 -r 7a20ee948676 NEWS --- a/NEWS Wed Nov 22 09:39:35 2023 +0100 +++ b/NEWS Wed Nov 22 12:57:07 2023 +0100 @@ -63,6 +63,8 @@ https://discourse.orthanc-server.org/t/c-find-fails-on-unknown-specific-character-set-iso-2022-ir-6-iso-2022-ir-100/3947 * When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision. +* Added a new 'Telemis' manufacturer for DicomModalities. This forces a new DICOM renegociation in case the + SopClassUid+TransferSyntax was rejected in the current association. * Upgraded dependencies for static builds: - boost 1.83.0 * Upgraded minizip library to stay away from CVE-2023-45853 although Orthanc is likely not affected since zip diff -r 85da6dcd0e08 -r 7a20ee948676 OrthancFramework/Sources/DicomNetworking/DicomStoreUserConnection.cpp --- a/OrthancFramework/Sources/DicomNetworking/DicomStoreUserConnection.cpp Wed Nov 22 09:39:35 2023 +0100 +++ b/OrthancFramework/Sources/DicomNetworking/DicomStoreUserConnection.cpp Wed Nov 22 12:57:07 2023 +0100 @@ -253,7 +253,8 @@ const std::string& sopClassUid, DicomTransferSyntax transferSyntax, bool hasPreferred, - DicomTransferSyntax preferred) + DicomTransferSyntax preferred, + bool alwaysRenegotiate) { /** * Step 1: Check whether this presentation context is already @@ -273,8 +274,8 @@ // Don't renegociate if we know that the remote modality was // already proposed this individual transfer syntax (**) - if (proposedOriginalClasses_.find(std::make_pair(sopClassUid, transferSyntax)) != - proposedOriginalClasses_.end()) + if (!alwaysRenegotiate && + proposedOriginalClasses_.find(std::make_pair(sopClassUid, transferSyntax)) != proposedOriginalClasses_.end()) { CLOG(INFO, DICOM) << "The remote modality has already rejected SOP class UID \"" << sopClassUid << "\" with transfer syntax \"" @@ -369,14 +370,15 @@ DcmFileFormat& dicom, bool hasMoveOriginator, const std::string& moveOriginatorAET, - uint16_t moveOriginatorID) + uint16_t moveOriginatorID, + bool alwaysRenegotiate) { DicomTransferSyntax transferSyntax; LookupParameters(sopClassUid, sopInstanceUid, transferSyntax, dicom); uint8_t presID; if (!NegotiatePresentationContext(presID, sopClassUid, transferSyntax, proposeUncompressedSyntaxes_, - DicomTransferSyntax_LittleEndianExplicit)) + DicomTransferSyntax_LittleEndianExplicit, alwaysRenegotiate)) { throw OrthancException(ErrorCode_NetworkProtocol, "No valid presentation context was negotiated for " @@ -458,7 +460,8 @@ size_t size, bool hasMoveOriginator, const std::string& moveOriginatorAET, - uint16_t moveOriginatorID) + uint16_t moveOriginatorID, + bool alwaysRenegotiate) { std::unique_ptr dicom( FromDcmtkBridge::LoadFromMemoryBuffer(buffer, size)); @@ -468,7 +471,7 @@ throw OrthancException(ErrorCode_InternalError); } - Store(sopClassUid, sopInstanceUid, *dicom, hasMoveOriginator, moveOriginatorAET, moveOriginatorID); + Store(sopClassUid, sopInstanceUid, *dicom, hasMoveOriginator, moveOriginatorAET, moveOriginatorID, alwaysRenegotiate); } @@ -477,7 +480,8 @@ const std::string& sopClassUid, DicomTransferSyntax sourceSyntax, bool hasPreferred, - DicomTransferSyntax preferred) + DicomTransferSyntax preferred, + bool alwaysRenegotiate) { acceptedSyntaxes.clear(); @@ -485,7 +489,7 @@ // syntax. We don't use the return code: Transcoding is possible // even if the "sourceSyntax" is not supported. uint8_t presID; - NegotiatePresentationContext(presID, sopClassUid, sourceSyntax, hasPreferred, preferred); + NegotiatePresentationContext(presID, sopClassUid, sourceSyntax, hasPreferred, preferred, alwaysRenegotiate); std::map contexts; if (association_->LookupAcceptedPresentationContext(contexts, sopClassUid)) @@ -509,7 +513,8 @@ DicomTransferSyntax preferredTransferSyntax, bool hasMoveOriginator, const std::string& moveOriginatorAET, - uint16_t moveOriginatorID) + uint16_t moveOriginatorID, + bool alwaysRenegotiate) { std::unique_ptr dicom(FromDcmtkBridge::LoadFromMemoryBuffer(buffer, size)); if (dicom.get() == NULL || @@ -522,13 +527,13 @@ LookupParameters(sopClassUid, sopInstanceUid, sourceSyntax, *dicom); std::set accepted; - LookupTranscoding(accepted, sopClassUid, sourceSyntax, true, preferredTransferSyntax); + LookupTranscoding(accepted, sopClassUid, sourceSyntax, true, preferredTransferSyntax, alwaysRenegotiate); if (accepted.find(sourceSyntax) != accepted.end()) { // No need for transcoding Store(sopClassUid, sopInstanceUid, *dicom, - hasMoveOriginator, moveOriginatorAET, moveOriginatorID); + hasMoveOriginator, moveOriginatorAET, moveOriginatorID, alwaysRenegotiate); } else { @@ -617,7 +622,7 @@ else { Store(sopClassUid, sopInstanceUid, transcoded.GetParsed(), - hasMoveOriginator, moveOriginatorAET, moveOriginatorID); + hasMoveOriginator, moveOriginatorAET, moveOriginatorID, alwaysRenegotiate); } } else @@ -646,10 +651,11 @@ size_t size, bool hasMoveOriginator, const std::string& moveOriginatorAET, - uint16_t moveOriginatorID) + uint16_t moveOriginatorID, + bool alwaysRenegotiate) { Transcode(sopClassUid, sopInstanceUid, transcoder, buffer, size, DicomTransferSyntax_LittleEndianExplicit, - hasMoveOriginator, moveOriginatorAET, moveOriginatorID); + hasMoveOriginator, moveOriginatorAET, moveOriginatorID, alwaysRenegotiate); } #endif } diff -r 85da6dcd0e08 -r 7a20ee948676 OrthancFramework/Sources/DicomNetworking/DicomStoreUserConnection.h --- a/OrthancFramework/Sources/DicomNetworking/DicomStoreUserConnection.h Wed Nov 22 09:39:35 2023 +0100 +++ b/OrthancFramework/Sources/DicomNetworking/DicomStoreUserConnection.h Wed Nov 22 12:57:07 2023 +0100 @@ -94,14 +94,16 @@ const std::string& sopClassUid, DicomTransferSyntax transferSyntax, bool hasPreferred, - DicomTransferSyntax preferred); + DicomTransferSyntax preferred, + bool alwaysRenegotiate); #if ORTHANC_ENABLE_DCMTK_TRANSCODING == 1 void LookupTranscoding(std::set& acceptedSyntaxes, const std::string& sopClassUid, DicomTransferSyntax sourceSyntax, bool hasPreferred, - DicomTransferSyntax preferred); + DicomTransferSyntax preferred, + bool alwaysRenegotiate); #endif public: @@ -129,7 +131,8 @@ DcmFileFormat& dicom, bool hasMoveOriginator, const std::string& moveOriginatorAET, - uint16_t moveOriginatorID); + uint16_t moveOriginatorID, + bool alwaysRenegotiate); void Store(std::string& sopClassUid, std::string& sopInstanceUid, @@ -137,7 +140,8 @@ size_t size, bool hasMoveOriginator, const std::string& moveOriginatorAET, - uint16_t moveOriginatorID); + uint16_t moveOriginatorID, + bool alwaysRenegotiate); void LookupParameters(std::string& sopClassUid, std::string& sopInstanceUid, @@ -153,7 +157,8 @@ DicomTransferSyntax preferredTransferSyntax, bool hasMoveOriginator, const std::string& moveOriginatorAET, - uint16_t moveOriginatorID); + uint16_t moveOriginatorID, + bool alwaysRenegotiate); #endif #if ORTHANC_ENABLE_DCMTK_TRANSCODING == 1 @@ -164,7 +169,8 @@ size_t size, bool hasMoveOriginator, const std::string& moveOriginatorAET, - uint16_t moveOriginatorID); + uint16_t moveOriginatorID, + bool alwaysRenegotiate); #endif }; } diff -r 85da6dcd0e08 -r 7a20ee948676 OrthancFramework/Sources/DicomNetworking/RemoteModalityParameters.cpp --- a/OrthancFramework/Sources/DicomNetworking/RemoteModalityParameters.cpp Wed Nov 22 09:39:35 2023 +0100 +++ b/OrthancFramework/Sources/DicomNetworking/RemoteModalityParameters.cpp Wed Nov 22 12:57:07 2023 +0100 @@ -186,6 +186,11 @@ manufacturer_ = StringToModalityManufacturer(manufacturer); } + bool RemoteModalityParameters::IsAlwaysRenegotiate() const + { + return manufacturer_ == ModalityManufacturer_Telemis; + } + void RemoteModalityParameters::UnserializeArray(const Json::Value& serialized) { diff -r 85da6dcd0e08 -r 7a20ee948676 OrthancFramework/Sources/DicomNetworking/RemoteModalityParameters.h --- a/OrthancFramework/Sources/DicomNetworking/RemoteModalityParameters.h Wed Nov 22 09:39:35 2023 +0100 +++ b/OrthancFramework/Sources/DicomNetworking/RemoteModalityParameters.h Wed Nov 22 12:57:07 2023 +0100 @@ -85,6 +85,8 @@ void SetManufacturer(const std::string& manufacturer); + bool IsAlwaysRenegotiate() const; + bool IsRequestAllowed(DicomRequestType type) const; void SetRequestAllowed(DicomRequestType type, diff -r 85da6dcd0e08 -r 7a20ee948676 OrthancFramework/Sources/Enumerations.cpp --- a/OrthancFramework/Sources/Enumerations.cpp Wed Nov 22 09:39:35 2023 +0100 +++ b/OrthancFramework/Sources/Enumerations.cpp Wed Nov 22 12:57:07 2023 +0100 @@ -807,6 +807,9 @@ case ModalityManufacturer_GE: return "GE"; + case ModalityManufacturer_Telemis: + return "Telemis"; + default: throw OrthancException(ErrorCode_ParameterOutOfRange); } @@ -1586,6 +1589,10 @@ { return ModalityManufacturer_GE; } + else if (manufacturer == "Telemis") + { + return ModalityManufacturer_Telemis; + } else if (manufacturer == "AgfaImpax" || manufacturer == "SyngoVia") { diff -r 85da6dcd0e08 -r 7a20ee948676 OrthancFramework/Sources/Enumerations.h --- a/OrthancFramework/Sources/Enumerations.h Wed Nov 22 09:39:35 2023 +0100 +++ b/OrthancFramework/Sources/Enumerations.h Wed Nov 22 12:57:07 2023 +0100 @@ -660,7 +660,8 @@ ModalityManufacturer_GenericNoWildcardInDates, ModalityManufacturer_GenericNoUniversalWildcard, ModalityManufacturer_Vitrea, - ModalityManufacturer_GE + ModalityManufacturer_GE, + ModalityManufacturer_Telemis }; enum DicomRequestType diff -r 85da6dcd0e08 -r 7a20ee948676 OrthancServer/Sources/OrthancRestApi/OrthancRestModalities.cpp --- a/OrthancServer/Sources/OrthancRestApi/OrthancRestModalities.cpp Wed Nov 22 09:39:35 2023 +0100 +++ b/OrthancServer/Sources/OrthancRestApi/OrthancRestModalities.cpp Wed Nov 22 12:57:07 2023 +0100 @@ -1520,7 +1520,10 @@ std::string sopClassUid, sopInstanceUid; connection.Store(sopClassUid, sopInstanceUid, call.GetBodyData(), - call.GetBodySize(), false /* Not a C-MOVE */, "", 0); + call.GetBodySize(), + false /* Not a C-MOVE */, + "", 0, + false /* AlwaysRenegotiate: no need to renegotiate since there is only a single file*/); Json::Value answer = Json::objectValue; answer[SOP_CLASS_UID] = sopClassUid; diff -r 85da6dcd0e08 -r 7a20ee948676 OrthancServer/Sources/ServerContext.cpp --- a/OrthancServer/Sources/ServerContext.cpp Wed Nov 22 09:39:35 2023 +0100 +++ b/OrthancServer/Sources/ServerContext.cpp Wed Nov 22 12:57:07 2023 +0100 @@ -1952,17 +1952,18 @@ uint16_t moveOriginatorId) { const void* data = dicom.empty() ? NULL : dicom.c_str(); - + const RemoteModalityParameters& modality = connection.GetParameters().GetRemoteModality(); + if (!transcodeDicomProtocol_ || - !connection.GetParameters().GetRemoteModality().IsTranscodingAllowed()) + !modality.IsTranscodingAllowed()) { connection.Store(sopClassUid, sopInstanceUid, data, dicom.size(), - hasMoveOriginator, moveOriginatorAet, moveOriginatorId); + hasMoveOriginator, moveOriginatorAet, moveOriginatorId, modality.IsAlwaysRenegotiate()); } else { connection.Transcode(sopClassUid, sopInstanceUid, *this, data, dicom.size(), preferredTransferSyntax_, - hasMoveOriginator, moveOriginatorAet, moveOriginatorId); + hasMoveOriginator, moveOriginatorAet, moveOriginatorId, modality.IsAlwaysRenegotiate()); } }