# HG changeset patch # User Sebastien Jodogne # Date 1582719755 -3600 # Node ID 736907ecb626df76e93012cbae742bfcb469db95 # Parent 89890302283659799bf8aa623babb8e32026593a# Parent 5cbbf14e516b2061616087ca233d54f30e707495 integration mainline->storage-commitment diff -r 898903022836 -r 736907ecb626 Core/DicomNetworking/DicomUserConnection.cpp --- a/Core/DicomNetworking/DicomUserConnection.cpp Wed Feb 26 10:39:55 2020 +0100 +++ b/Core/DicomNetworking/DicomUserConnection.cpp Wed Feb 26 13:22:35 2020 +0100 @@ -466,18 +466,36 @@ } // Finally conduct transmission of data - T_DIMSE_C_StoreRSP rsp; + T_DIMSE_C_StoreRSP response; DcmDataset* statusDetail = NULL; Check(DIMSE_storeUser(assoc_, presID, &request, NULL, dcmff.getDataset(), /*progressCallback*/ NULL, NULL, /*opt_blockMode*/ DIMSE_BLOCKING, /*opt_dimse_timeout*/ dimseTimeout_, - &rsp, &statusDetail, NULL), + &response, &statusDetail, NULL), connection.remoteAet_, "C-STORE"); if (statusDetail != NULL) { delete statusDetail; } + + + /** + * New in Orthanc 1.6.0: Deal with failures during C-STORE. + * http://dicom.nema.org/medical/dicom/current/output/chtml/part04/sect_B.2.3.html#table_B.2-1 + **/ + + if (response.DimseStatus != 0x0000 && // Success + response.DimseStatus != 0xB000 && // Warning - Coercion of Data Elements + response.DimseStatus != 0xB007 && // Warning - Data Set does not match SOP Class + response.DimseStatus != 0xB006) // Warning - Elements Discarded + { + char buf[16]; + sprintf(buf, "%04X", response.DimseStatus); + throw OrthancException(ErrorCode_NetworkProtocol, + "C-STORE SCU to AET \"" + connection.remoteAet_ + + "\" has failed with DIMSE status 0x" + buf); + } } @@ -696,6 +714,24 @@ } Check(cond, remoteAet, "C-FIND"); + + + /** + * New in Orthanc 1.6.0: Deal with failures during C-FIND. + * http://dicom.nema.org/medical/dicom/current/output/chtml/part04/sect_C.4.html#table_C.4-1 + **/ + + if (response.DimseStatus != 0x0000 && // Success + response.DimseStatus != 0xFF00 && // Pending - Matches are continuing + response.DimseStatus != 0xFF01) // Pending - Matches are continuing + { + char buf[16]; + sprintf(buf, "%04X", response.DimseStatus); + throw OrthancException(ErrorCode_NetworkProtocol, + "C-FIND SCU to AET \"" + remoteAet + + "\" has failed with DIMSE status 0x" + buf); + } + } @@ -882,6 +918,22 @@ } Check(cond, remoteAet_, "C-MOVE"); + + + /** + * New in Orthanc 1.6.0: Deal with failures during C-MOVE. + * http://dicom.nema.org/medical/dicom/current/output/chtml/part04/sect_C.4.2.html#table_C.4-2 + **/ + + if (response.DimseStatus != 0x0000 && // Success + response.DimseStatus != 0xFF00) // Pending - Sub-operations are continuing + { + char buf[16]; + sprintf(buf, "%04X", response.DimseStatus); + throw OrthancException(ErrorCode_NetworkProtocol, + "C-MOVE SCU to AET \"" + remoteAet_ + + "\" has failed with DIMSE status 0x" + buf); + } } diff -r 898903022836 -r 736907ecb626 Core/SQLite/StatementReference.cpp --- a/Core/SQLite/StatementReference.cpp Wed Feb 26 10:39:55 2020 +0100 +++ b/Core/SQLite/StatementReference.cpp Wed Feb 26 13:22:35 2020 +0100 @@ -82,8 +82,12 @@ if (error != SQLITE_OK) { #if ORTHANC_SQLITE_STANDALONE != 1 - LOG(ERROR) << "SQLite: " << sqlite3_errmsg(database) - << " (" << sqlite3_extended_errcode(database) << ")"; + int extended = sqlite3_extended_errcode(database); + LOG(ERROR) << "SQLite: " << sqlite3_errmsg(database) << " (" << extended << ")"; + if (extended == SQLITE_IOERR_SHMSIZE /* 4874 */) + { + LOG(ERROR) << " This probably indicates that your filesystem is full"; + } #endif throw OrthancSQLiteException(ErrorCode_SQLitePrepareStatement); diff -r 898903022836 -r 736907ecb626 Core/SharedLibrary.cpp --- a/Core/SharedLibrary.cpp Wed Feb 26 10:39:55 2020 +0100 +++ b/Core/SharedLibrary.cpp Wed Feb 26 13:22:35 2020 +0100 @@ -62,7 +62,19 @@ } #elif defined(__linux__) || (defined(__APPLE__) && defined(__MACH__)) || defined(__FreeBSD_kernel__) || defined(__FreeBSD__) || defined(__OpenBSD__) - handle_ = ::dlopen(path_.c_str(), RTLD_NOW); + + /** + * "RTLD_LOCAL" is the default, and is only present to be + * explicit. "RTLD_DEEPBIND" was added in Orthanc 1.6.0, in order + * to avoid crashes while loading plugins from the LSB binaries of + * the Orthanc core. + **/ +#if defined(RTLD_DEEPBIND) // This is a GNU extension + handle_ = ::dlopen(path_.c_str(), RTLD_NOW | RTLD_LOCAL | RTLD_DEEPBIND); +#else + handle_ = ::dlopen(path_.c_str(), RTLD_NOW | RTLD_LOCAL); +#endif + if (handle_ == NULL) { std::string explanation; diff -r 898903022836 -r 736907ecb626 NEWS --- a/NEWS Wed Feb 26 10:39:55 2020 +0100 +++ b/NEWS Wed Feb 26 13:22:35 2020 +0100 @@ -44,7 +44,9 @@ * More strict C-FIND SCP wrt. the DICOM standard: Forbid wildcard matching on some VRs, ignore main tags below the queried level * Fix issue #65 (Logging improvements) +* Fix issue #103 ("queries/.../retrieve" API returns HTTP code 200 even on server errors) * Fix issue #140 (Modifying private tags with REST API changes VR from LO to UN) +* Fix issue #154 (Matching against list of UID-s by C-MOVE) * Fix issue #156 (Chunked Dicom-web transfer uses 100% CPU) * Fix issue #165 (Boundary parameter in multipart Content-Type is too long) * Fix issue #166 (CMake find_boost version is now broken with newer boost/cmake) diff -r 898903022836 -r 736907ecb626 OrthancServer/OrthancMoveRequestHandler.cpp --- a/OrthancServer/OrthancMoveRequestHandler.cpp Wed Feb 26 10:39:55 2020 +0100 +++ b/OrthancServer/OrthancMoveRequestHandler.cpp Wed Feb 26 13:22:35 2020 +0100 @@ -142,7 +142,8 @@ position_(0) { job_->SetDescription("C-MOVE"); - job_->SetPermissive(true); + //job_->SetPermissive(true); // This was the behavior of Orthanc < 1.6.0 + job_->SetPermissive(false); job_->SetLocalAet(context.GetDefaultLocalApplicationEntityTitle()); { @@ -241,7 +242,24 @@ else { const std::string& content = value.GetContent(); - context_.GetIndex().LookupIdentifierExact(publicIds, level, tag, content); + + /** + * This tokenization fixes issue 154 ("Matching against list of + * UID-s by C-MOVE"). + * https://bitbucket.org/sjodogne/orthanc/issues/154/ + **/ + + std::vector tokens; + Toolbox::TokenizeString(tokens, content, '\\'); + for (size_t i = 0; i < tokens.size(); i++) + { + std::vector matches; + context_.GetIndex().LookupIdentifierExact(matches, level, tag, tokens[i]); + + // Concatenate "publicIds" with "matches" + publicIds.insert(publicIds.end(), matches.begin(), matches.end()); + } + return true; } } diff -r 898903022836 -r 736907ecb626 OrthancServer/ServerIndex.cpp --- a/OrthancServer/ServerIndex.cpp Wed Feb 26 10:39:55 2020 +0100 +++ b/OrthancServer/ServerIndex.cpp Wed Feb 26 13:22:35 2020 +0100 @@ -500,7 +500,16 @@ Logging::Flush(); boost::mutex::scoped_lock lock(that->mutex_); - that->db_.FlushToDisk(); + + try + { + that->db_.FlushToDisk(); + } + catch (OrthancException&) + { + LOG(ERROR) << "Cannot flush the SQLite database to the disk (is your filesystem full?)"; + } + count = 0; }