# HG changeset patch # User Sebastien Jodogne # Date 1422972042 -3600 # Node ID 5730f374e4e65ae339f64d9776a9a7de24990175 # Parent 21ea32170764ed0495582043ad367cfa2b56f4a7 Access to called AET and remote AET from Lua scripts diff -r 21ea32170764 -r 5730f374e4e6 NEWS --- a/NEWS Tue Feb 03 14:07:07 2015 +0100 +++ b/NEWS Tue Feb 03 15:00:42 2015 +0100 @@ -15,6 +15,7 @@ * More flexible "/modify" and "/anonymize" for single instance * Code refactorings * Option "DicomAssociationCloseDelay" to set delay before closing DICOM association +* Access to called AET and remote AET from Lua scripts ("OnStoredInstance") Plugins ------- diff -r 21ea32170764 -r 5730f374e4e6 OrthancServer/DicomInstanceToStore.h --- a/OrthancServer/DicomInstanceToStore.h Tue Feb 03 14:07:07 2015 +0100 +++ b/OrthancServer/DicomInstanceToStore.h Tue Feb 03 15:00:42 2015 +0100 @@ -144,6 +144,7 @@ SmartContainer json_; std::string remoteAet_; + std::string calledAet_; ServerIndex::MetadataMap metadata_; void ComputeMissingInformation(); @@ -169,7 +170,7 @@ json_.SetConstReference(json); } - const std::string GetRemoteAet() const + const std::string& GetRemoteAet() const { return remoteAet_; } @@ -179,6 +180,16 @@ remoteAet_ = aet; } + const std::string& GetCalledAet() const + { + return calledAet_; + } + + void SetCalledAet(const std::string& aet) + { + calledAet_ = aet; + } + void AddMetadata(ResourceType level, MetadataType metadata, const std::string& value); diff -r 21ea32170764 -r 5730f374e4e6 OrthancServer/DicomProtocol/DicomUserConnection.cpp --- a/OrthancServer/DicomProtocol/DicomUserConnection.cpp Tue Feb 03 14:07:07 2015 +0100 +++ b/OrthancServer/DicomProtocol/DicomUserConnection.cpp Tue Feb 03 15:00:42 2015 +0100 @@ -454,7 +454,7 @@ int presID = ASC_findAcceptedPresentationContextID(pimpl_->assoc_, sopClass); if (presID == 0) { - throw OrthancException("DicomUserConnection: The C-FIND command is not supported by the distant AET"); + throw OrthancException("DicomUserConnection: The C-FIND command is not supported by the remote AET"); } T_DIMSE_C_FindRQ request; @@ -546,7 +546,7 @@ int presID = ASC_findAcceptedPresentationContextID(pimpl_->assoc_, sopClass); if (presID == 0) { - throw OrthancException("DicomUserConnection: The C-MOVE command is not supported by the distant AET"); + throw OrthancException("DicomUserConnection: The C-MOVE command is not supported by the remote AET"); } T_DIMSE_C_MoveRQ request; @@ -614,10 +614,10 @@ pimpl_(new PImpl), preferredTransferSyntax_(DEFAULT_PREFERRED_TRANSFER_SYNTAX), localAet_("STORESCU"), - distantAet_("ANY-SCP"), - distantHost_("127.0.0.1") + remoteAet_("ANY-SCP"), + remoteHost_("127.0.0.1") { - distantPort_ = 104; + remotePort_ = 104; manufacturer_ = ModalityManufacturer_Generic; SetTimeout(10); @@ -642,10 +642,10 @@ void DicomUserConnection::Connect(const RemoteModalityParameters& parameters) { - SetDistantApplicationEntityTitle(parameters.GetApplicationEntityTitle()); - SetDistantHost(parameters.GetHost()); - SetDistantPort(parameters.GetPort()); - SetDistantManufacturer(parameters.GetManufacturer()); + SetRemoteApplicationEntityTitle(parameters.GetApplicationEntityTitle()); + SetRemoteHost(parameters.GetHost()); + SetRemotePort(parameters.GetPort()); + SetRemoteManufacturer(parameters.GetManufacturer()); } @@ -658,16 +658,16 @@ } } - void DicomUserConnection::SetDistantApplicationEntityTitle(const std::string& aet) + void DicomUserConnection::SetRemoteApplicationEntityTitle(const std::string& aet) { - if (distantAet_ != aet) + if (remoteAet_ != aet) { Close(); - distantAet_ = aet; + remoteAet_ = aet; } } - void DicomUserConnection::SetDistantManufacturer(ModalityManufacturer manufacturer) + void DicomUserConnection::SetRemoteManufacturer(ModalityManufacturer manufacturer) { if (manufacturer_ != manufacturer) { @@ -691,26 +691,26 @@ } - void DicomUserConnection::SetDistantHost(const std::string& host) + void DicomUserConnection::SetRemoteHost(const std::string& host) { - if (distantHost_ != host) + if (remoteHost_ != host) { if (host.size() > HOST_NAME_MAX - 10) { - throw OrthancException("Distant host name is too long"); + throw OrthancException("Remote host name is too long"); } Close(); - distantHost_ = host; + remoteHost_ = host; } } - void DicomUserConnection::SetDistantPort(uint16_t port) + void DicomUserConnection::SetRemotePort(uint16_t port) { - if (distantPort_ != port) + if (remotePort_ != port) { Close(); - distantPort_ = port; + remotePort_ = port; } } @@ -723,30 +723,30 @@ } LOG(INFO) << "Opening a DICOM SCU connection from AET \"" << GetLocalApplicationEntityTitle() - << "\" to AET \"" << GetDistantApplicationEntityTitle() << "\" on host " - << GetDistantHost() << ":" << GetDistantPort() - << " (manufacturer: " << EnumerationToString(GetDistantManufacturer()) << ")"; + << "\" to AET \"" << GetRemoteApplicationEntityTitle() << "\" on host " + << GetRemoteHost() << ":" << GetRemotePort() + << " (manufacturer: " << EnumerationToString(GetRemoteManufacturer()) << ")"; Check(ASC_initializeNetwork(NET_REQUESTOR, 0, /*opt_acse_timeout*/ pimpl_->acseTimeout_, &pimpl_->net_)); Check(ASC_createAssociationParameters(&pimpl_->params_, /*opt_maxReceivePDULength*/ ASC_DEFAULTMAXPDU)); // Set this application's title and the called application's title in the params - Check(ASC_setAPTitles(pimpl_->params_, localAet_.c_str(), distantAet_.c_str(), NULL)); + Check(ASC_setAPTitles(pimpl_->params_, localAet_.c_str(), remoteAet_.c_str(), NULL)); - // Set the network addresses of the local and distant entities + // Set the network addresses of the local and remote entities char localHost[HOST_NAME_MAX]; gethostname(localHost, HOST_NAME_MAX - 1); - char distantHostAndPort[HOST_NAME_MAX]; + char remoteHostAndPort[HOST_NAME_MAX]; #ifdef _MSC_VER _snprintf #else snprintf #endif - (distantHostAndPort, HOST_NAME_MAX - 1, "%s:%d", distantHost_.c_str(), distantPort_); + (remoteHostAndPort, HOST_NAME_MAX - 1, "%s:%d", remoteHost_.c_str(), remotePort_); - Check(ASC_setPresentationAddresses(pimpl_->params_, localHost, distantHostAndPort)); + Check(ASC_setPresentationAddresses(pimpl_->params_, localHost, remoteHostAndPort)); // Set various options Check(ASC_setTransportLayerType(pimpl_->params_, /*opt_secureConnection*/ false)); diff -r 21ea32170764 -r 5730f374e4e6 OrthancServer/DicomProtocol/DicomUserConnection.h --- a/OrthancServer/DicomProtocol/DicomUserConnection.h Tue Feb 03 14:07:07 2015 +0100 +++ b/OrthancServer/DicomProtocol/DicomUserConnection.h Tue Feb 03 15:00:42 2015 +0100 @@ -60,9 +60,9 @@ // Connection parameters std::string preferredTransferSyntax_; std::string localAet_; - std::string distantAet_; - std::string distantHost_; - uint16_t distantPort_; + std::string remoteAet_; + std::string remoteHost_; + uint16_t remotePort_; ModalityManufacturer manufacturer_; std::set storageSOPClasses_; std::list reservedStorageSOPClasses_; @@ -97,30 +97,30 @@ return localAet_; } - void SetDistantApplicationEntityTitle(const std::string& aet); + void SetRemoteApplicationEntityTitle(const std::string& aet); - const std::string& GetDistantApplicationEntityTitle() const + const std::string& GetRemoteApplicationEntityTitle() const { - return distantAet_; + return remoteAet_; } - void SetDistantHost(const std::string& host); + void SetRemoteHost(const std::string& host); - const std::string& GetDistantHost() const + const std::string& GetRemoteHost() const { - return distantHost_; + return remoteHost_; } - void SetDistantPort(uint16_t port); + void SetRemotePort(uint16_t port); - uint16_t GetDistantPort() const + uint16_t GetRemotePort() const { - return distantPort_; + return remotePort_; } - void SetDistantManufacturer(ModalityManufacturer manufacturer); + void SetRemoteManufacturer(ModalityManufacturer manufacturer); - ModalityManufacturer GetDistantManufacturer() const + ModalityManufacturer GetRemoteManufacturer() const { return manufacturer_; } diff -r 21ea32170764 -r 5730f374e4e6 OrthancServer/DicomProtocol/IStoreRequestHandler.h --- a/OrthancServer/DicomProtocol/IStoreRequestHandler.h Tue Feb 03 14:07:07 2015 +0100 +++ b/OrthancServer/DicomProtocol/IStoreRequestHandler.h Tue Feb 03 15:00:42 2015 +0100 @@ -50,6 +50,7 @@ virtual void Handle(const std::string& dicomFile, const DicomMap& dicomSummary, const Json::Value& dicomJson, - const std::string& distantAet) = 0; + const std::string& remoteAet, + const std::string& calledAet) = 0; }; } diff -r 21ea32170764 -r 5730f374e4e6 OrthancServer/DicomProtocol/ReusableDicomUserConnection.cpp --- a/OrthancServer/DicomProtocol/ReusableDicomUserConnection.cpp Tue Feb 03 14:07:07 2015 +0100 +++ b/OrthancServer/DicomProtocol/ReusableDicomUserConnection.cpp Tue Feb 03 15:00:42 2015 +0100 @@ -50,10 +50,10 @@ ModalityManufacturer manufacturer) { if (connection_ != NULL && - connection_->GetDistantApplicationEntityTitle() == remoteAet && - connection_->GetDistantHost() == address && - connection_->GetDistantPort() == port && - connection_->GetDistantManufacturer() == manufacturer) + connection_->GetRemoteApplicationEntityTitle() == remoteAet && + connection_->GetRemoteHost() == address && + connection_->GetRemotePort() == port && + connection_->GetRemoteManufacturer() == manufacturer) { // The current connection can be reused LOG(INFO) << "Reusing the previous SCU connection"; @@ -64,10 +64,10 @@ connection_ = new DicomUserConnection(); connection_->SetLocalApplicationEntityTitle(localAet_); - connection_->SetDistantApplicationEntityTitle(remoteAet); - connection_->SetDistantHost(address); - connection_->SetDistantPort(port); - connection_->SetDistantManufacturer(manufacturer); + connection_->SetRemoteApplicationEntityTitle(remoteAet); + connection_->SetRemoteHost(address); + connection_->SetRemotePort(port); + connection_->SetRemoteManufacturer(manufacturer); connection_->Open(); } @@ -179,7 +179,7 @@ void ReusableDicomUserConnection::Unlock() { if (connection_ != NULL && - connection_->GetDistantManufacturer() == ModalityManufacturer_StoreScp) + connection_->GetRemoteManufacturer() == ModalityManufacturer_StoreScp) { // "storescp" from DCMTK has problems when reusing a // connection. Always close. diff -r 21ea32170764 -r 5730f374e4e6 OrthancServer/Internals/StoreScp.cpp --- a/OrthancServer/Internals/StoreScp.cpp Tue Feb 03 14:07:07 2015 +0100 +++ b/OrthancServer/Internals/StoreScp.cpp Tue Feb 03 15:00:42 2015 +0100 @@ -102,7 +102,8 @@ struct StoreCallbackData { IStoreRequestHandler* handler; - const char* distantAET; + const char* remoteAET; + const char* calledAET; const char* modality; const char* affectedSOPInstanceUID; uint32_t messageID; @@ -201,7 +202,7 @@ { try { - cbdata->handler->Handle(buffer, summary, dicomJson, cbdata->distantAET); + cbdata->handler->Handle(buffer, summary, dicomJson, cbdata->remoteAET, cbdata->calledAET); } catch (OrthancException& e) { @@ -255,11 +256,13 @@ callbackData.messageID = req->MessageID; if (assoc && assoc->params) { - callbackData.distantAET = assoc->params->DULparams.callingAPTitle; + callbackData.remoteAET = assoc->params->DULparams.callingAPTitle; + callbackData.calledAET = assoc->params->DULparams.calledAPTitle; } else { - callbackData.distantAET = ""; + callbackData.remoteAET = ""; + callbackData.calledAET = ""; } DcmFileFormat dcmff; diff -r 21ea32170764 -r 5730f374e4e6 OrthancServer/ServerContext.cpp --- a/OrthancServer/ServerContext.cpp Tue Feb 03 14:07:07 2015 +0100 +++ b/OrthancServer/ServerContext.cpp Tue Feb 03 15:00:42 2015 +0100 @@ -211,7 +211,9 @@ void ServerContext::ApplyLuaOnStoredInstance(const std::string& instanceId, const Json::Value& simplifiedDicom, - const Json::Value& metadata) + const Json::Value& metadata, + const std::string& remoteAet, + const std::string& calledAet) { LuaContextLocker locker(*this); @@ -223,6 +225,8 @@ call.PushString(instanceId); call.PushJson(simplifiedDicom); call.PushJson(metadata); + call.PushJson(remoteAet); + call.PushJson(calledAet); call.Execute(); Json::Value operations; @@ -360,11 +364,12 @@ try { - ApplyLuaOnStoredInstance(resultPublicId, simplified, metadata); + ApplyLuaOnStoredInstance(resultPublicId, simplified, metadata, + dicom.GetRemoteAet(), dicom.GetCalledAet()); } catch (OrthancException& e) { - LOG(ERROR) << "Error in OnStoredInstance callback (Lua): " << e.What(); + LOG(ERROR) << "Error in " << ON_STORED_INSTANCE << " callback (Lua): " << e.What(); } if (plugins_ != NULL) @@ -375,7 +380,7 @@ } catch (OrthancException& e) { - LOG(ERROR) << "Error in OnStoredInstance callback (plugins): " << e.What(); + LOG(ERROR) << "Error in " << ON_STORED_INSTANCE << " callback (plugins): " << e.What(); } } } diff -r 21ea32170764 -r 5730f374e4e6 OrthancServer/ServerContext.h --- a/OrthancServer/ServerContext.h Tue Feb 03 14:07:07 2015 +0100 +++ b/OrthancServer/ServerContext.h Tue Feb 03 15:00:42 2015 +0100 @@ -77,7 +77,9 @@ void ApplyLuaOnStoredInstance(const std::string& instanceId, const Json::Value& simplifiedDicom, - const Json::Value& metadata); + const Json::Value& metadata, + const std::string& remoteAet, + const std::string& calledAet); ServerIndex index_; CompressedFileStorageAccessor accessor_; diff -r 21ea32170764 -r 5730f374e4e6 OrthancServer/main.cpp --- a/OrthancServer/main.cpp Tue Feb 03 14:07:07 2015 +0100 +++ b/OrthancServer/main.cpp Tue Feb 03 15:00:42 2015 +0100 @@ -72,7 +72,8 @@ virtual void Handle(const std::string& dicomFile, const DicomMap& dicomSummary, const Json::Value& dicomJson, - const std::string& remoteAet) + const std::string& remoteAet, + const std::string& calledAet) { if (dicomFile.size() > 0) { @@ -81,6 +82,7 @@ toStore.SetSummary(dicomSummary); toStore.SetJson(dicomJson); toStore.SetRemoteAet(remoteAet); + toStore.SetCalledAet(calledAet); std::string id; server_.Store(id, toStore); diff -r 21ea32170764 -r 5730f374e4e6 Resources/Samples/Lua/AutoroutingConditional.lua --- a/Resources/Samples/Lua/AutoroutingConditional.lua Tue Feb 03 14:07:07 2015 +0100 +++ b/Resources/Samples/Lua/AutoroutingConditional.lua Tue Feb 03 15:00:42 2015 +0100 @@ -1,4 +1,10 @@ -function OnStoredInstance(instanceId, tags, metadata) +function OnStoredInstance(instanceId, tags, metadata, remoteAet, calledAet) + -- The "remoteAet" and "calledAet" arguments are only available + -- since Orthanc 0.8.6 + if remoteAet ~=nil and calledAet ~= nil then + print ("Source AET: " .. remoteAet .. " => Called AET: " .. calledAet) + end + -- Extract the value of the "PatientName" DICOM tag local patientName = string.lower(tags['PatientName'])