Mercurial > hg > orthanc
annotate OrthancServer/DicomProtocol/DicomUserConnection.cpp @ 928:882833632b1f mac
integration mainline -> mac
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Wed, 16 Apr 2014 17:02:07 +0200 |
parents | 55b945749bed |
children | 27d256e0b458 |
rev | line source |
---|---|
0 | 1 /** |
62 | 2 * Orthanc - A Lightweight, RESTful DICOM Store |
689 | 3 * Copyright (C) 2012-2014 Medical Physics Department, CHU of Liege, |
0 | 4 * Belgium |
5 * | |
6 * This program is free software: you can redistribute it and/or | |
7 * modify it under the terms of the GNU General Public License as | |
8 * published by the Free Software Foundation, either version 3 of the | |
9 * License, or (at your option) any later version. | |
136 | 10 * |
11 * In addition, as a special exception, the copyright holders of this | |
12 * program give permission to link the code of its release with the | |
13 * OpenSSL project's "OpenSSL" library (or with modified versions of it | |
14 * that use the same license as the "OpenSSL" library), and distribute | |
15 * the linked executables. You must obey the GNU General Public License | |
16 * in all respects for all of the code used other than "OpenSSL". If you | |
17 * modify file(s) with this exception, you may extend this exception to | |
18 * your version of the file(s), but you are not obligated to do so. If | |
19 * you do not wish to do so, delete this exception statement from your | |
20 * version. If you delete this exception statement from all source files | |
21 * in the program, then also delete it here. | |
0 | 22 * |
23 * This program is distributed in the hope that it will be useful, but | |
24 * WITHOUT ANY WARRANTY; without even the implied warranty of | |
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
26 * General Public License for more details. | |
27 * | |
28 * You should have received a copy of the GNU General Public License | |
29 * along with this program. If not, see <http://www.gnu.org/licenses/>. | |
30 **/ | |
31 | |
32 | |
33 #include "DicomUserConnection.h" | |
34 | |
62 | 35 #include "../../Core/OrthancException.h" |
0 | 36 #include "../ToDcmtkBridge.h" |
37 #include "../FromDcmtkBridge.h" | |
38 | |
39 #include <dcmtk/dcmdata/dcistrmb.h> | |
40 #include <dcmtk/dcmdata/dcistrmf.h> | |
41 #include <dcmtk/dcmdata/dcfilefo.h> | |
662
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
42 #include <dcmtk/dcmdata/dcmetinf.h> |
0 | 43 #include <dcmtk/dcmnet/diutil.h> |
44 | |
45 #include <set> | |
662
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
46 #include <glog/logging.h> |
0 | 47 |
48 | |
49 | |
50 #ifdef _WIN32 | |
51 /** | |
52 * "The maximum length, in bytes, of the string returned in the buffer | |
53 * pointed to by the name parameter is dependent on the namespace provider, | |
54 * but this string must be 256 bytes or less. | |
55 * http://msdn.microsoft.com/en-us/library/windows/desktop/ms738527(v=vs.85).aspx | |
56 **/ | |
57 #define HOST_NAME_MAX 256 | |
58 #endif | |
59 | |
60 | |
918 | 61 #if !defined(HOST_NAME_MAX) && defined(_POSIX_HOST_NAME_MAX) |
62 #define HOST_NAME_MAX _POSIX_HOST_NAME_MAX | |
63 #endif | |
64 | |
65 | |
662
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
66 static const char* DEFAULT_PREFERRED_TRANSFER_SYNTAX = UID_LittleEndianImplicitTransferSyntax; |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
67 |
62 | 68 namespace Orthanc |
0 | 69 { |
70 struct DicomUserConnection::PImpl | |
71 { | |
72 // Connection state | |
73 T_ASC_Network* net_; | |
74 T_ASC_Parameters* params_; | |
75 T_ASC_Association* assoc_; | |
76 | |
77 bool IsOpen() const | |
78 { | |
79 return assoc_ != NULL; | |
80 } | |
81 | |
82 void CheckIsOpen() const; | |
83 | |
662
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
84 void Store(DcmInputStream& is, DicomUserConnection& connection); |
0 | 85 }; |
86 | |
87 | |
88 static void Check(const OFCondition& cond) | |
89 { | |
90 if (cond.bad()) | |
91 { | |
62 | 92 throw OrthancException("DicomUserConnection: " + std::string(cond.text())); |
0 | 93 } |
94 } | |
95 | |
96 void DicomUserConnection::PImpl::CheckIsOpen() const | |
97 { | |
98 if (!IsOpen()) | |
99 { | |
62 | 100 throw OrthancException("DicomUserConnection: First open the connection"); |
0 | 101 } |
102 } | |
103 | |
104 | |
105 void DicomUserConnection::CheckIsOpen() const | |
106 { | |
107 pimpl_->CheckIsOpen(); | |
108 } | |
109 | |
110 | |
111 void DicomUserConnection::CopyParameters(const DicomUserConnection& other) | |
112 { | |
113 Close(); | |
114 localAet_ = other.localAet_; | |
115 distantAet_ = other.distantAet_; | |
116 distantHost_ = other.distantHost_; | |
117 distantPort_ = other.distantPort_; | |
662
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
118 manufacturer_ = other.manufacturer_; |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
119 preferredTransferSyntax_ = other.preferredTransferSyntax_; |
0 | 120 } |
121 | |
122 | |
662
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
123 void DicomUserConnection::SetupPresentationContexts(const std::string& preferredTransferSyntax) |
0 | 124 { |
662
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
125 // Fallback transfer syntaxes |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
126 std::set<std::string> fallbackSyntaxes; |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
127 fallbackSyntaxes.insert(UID_LittleEndianExplicitTransferSyntax); |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
128 fallbackSyntaxes.insert(UID_BigEndianExplicitTransferSyntax); |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
129 fallbackSyntaxes.insert(UID_LittleEndianImplicitTransferSyntax); |
0 | 130 |
131 // Transfer syntaxes for C-ECHO, C-FIND and C-MOVE | |
132 std::vector<std::string> transferSyntaxes; | |
133 transferSyntaxes.push_back(UID_VerificationSOPClass); | |
134 transferSyntaxes.push_back(UID_FINDPatientRootQueryRetrieveInformationModel); | |
135 transferSyntaxes.push_back(UID_FINDStudyRootQueryRetrieveInformationModel); | |
136 transferSyntaxes.push_back(UID_MOVEStudyRootQueryRetrieveInformationModel); | |
137 | |
138 // TODO: Allow the set below to be configured | |
139 std::set<std::string> uselessSyntaxes; | |
140 uselessSyntaxes.insert(UID_BlendingSoftcopyPresentationStateStorage); | |
141 uselessSyntaxes.insert(UID_GrayscaleSoftcopyPresentationStateStorage); | |
142 uselessSyntaxes.insert(UID_ColorSoftcopyPresentationStateStorage); | |
143 uselessSyntaxes.insert(UID_PseudoColorSoftcopyPresentationStateStorage); | |
144 | |
145 // Add the transfer syntaxes for C-STORE | |
146 for (int i = 0; i < numberOfDcmShortSCUStorageSOPClassUIDs - 1; i++) | |
147 { | |
148 // Test to make some room to allow the ECHO and FIND requests | |
149 if (uselessSyntaxes.find(dcmShortSCUStorageSOPClassUIDs[i]) == uselessSyntaxes.end()) | |
150 { | |
151 transferSyntaxes.push_back(dcmShortSCUStorageSOPClassUIDs[i]); | |
152 } | |
153 } | |
154 | |
662
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
155 // Flatten the fallback transfer syntaxes array |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
156 const char* asPreferred[1] = { preferredTransferSyntax.c_str() }; |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
157 |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
158 fallbackSyntaxes.erase(preferredTransferSyntax); |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
159 |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
160 std::vector<const char*> asFallback; |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
161 asFallback.reserve(fallbackSyntaxes.size()); |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
162 for (std::set<std::string>::const_iterator |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
163 it = fallbackSyntaxes.begin(); it != fallbackSyntaxes.end(); ++it) |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
164 { |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
165 asFallback.push_back(it->c_str()); |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
166 } |
0 | 167 |
168 unsigned int presentationContextId = 1; | |
169 for (size_t i = 0; i < transferSyntaxes.size(); i++) | |
170 { | |
171 Check(ASC_addPresentationContext(pimpl_->params_, presentationContextId, | |
172 transferSyntaxes[i].c_str(), asPreferred, 1)); | |
173 presentationContextId += 2; | |
174 | |
662
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
175 if (asFallback.size() > 0) |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
176 { |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
177 Check(ASC_addPresentationContext(pimpl_->params_, presentationContextId, |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
178 transferSyntaxes[i].c_str(), &asFallback[0], asFallback.size())); |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
179 presentationContextId += 2; |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
180 } |
0 | 181 } |
182 } | |
183 | |
184 | |
662
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
185 static bool IsGenericTransferSyntax(const std::string& syntax) |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
186 { |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
187 return (syntax == UID_LittleEndianExplicitTransferSyntax || |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
188 syntax == UID_BigEndianExplicitTransferSyntax || |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
189 syntax == UID_LittleEndianImplicitTransferSyntax); |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
190 } |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
191 |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
192 |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
193 void DicomUserConnection::PImpl::Store(DcmInputStream& is, DicomUserConnection& connection) |
0 | 194 { |
195 CheckIsOpen(); | |
196 | |
197 DcmFileFormat dcmff; | |
198 Check(dcmff.read(is, EXS_Unknown, EGL_noChange, DCM_MaxReadLength)); | |
199 | |
662
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
200 // Determine whether a new presentation context must be |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
201 // negociated, depending on the transfer syntax of this instance |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
202 DcmXfer xfer(dcmff.getDataset()->getOriginalXfer()); |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
203 const std::string syntax(xfer.getXferID()); |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
204 bool isGeneric = IsGenericTransferSyntax(syntax); |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
205 |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
206 if (isGeneric ^ IsGenericTransferSyntax(connection.GetPreferredTransferSyntax())) |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
207 { |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
208 // Making a generic-to-specific or specific-to-generic change of |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
209 // the transfer syntax. Renegociate the connection. |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
210 LOG(INFO) << "Renegociating a C-Store association due to a change in the transfer syntax"; |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
211 |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
212 if (isGeneric) |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
213 { |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
214 connection.ResetPreferredTransferSyntax(); |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
215 } |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
216 else |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
217 { |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
218 connection.SetPreferredTransferSyntax(syntax); |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
219 } |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
220 |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
221 connection.Open(); |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
222 } |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
223 |
0 | 224 // Figure out which SOP class and SOP instance is encapsulated in the file |
225 DIC_UI sopClass; | |
226 DIC_UI sopInstance; | |
227 if (!DU_findSOPClassAndInstanceInDataSet(dcmff.getDataset(), sopClass, sopInstance)) | |
228 { | |
62 | 229 throw OrthancException("DicomUserConnection: Unable to find the SOP class and instance"); |
0 | 230 } |
231 | |
232 // Figure out which of the accepted presentation contexts should be used | |
233 int presID = ASC_findAcceptedPresentationContextID(assoc_, sopClass); | |
234 if (presID == 0) | |
235 { | |
236 const char *modalityName = dcmSOPClassUIDToModality(sopClass); | |
237 if (!modalityName) modalityName = dcmFindNameOfUID(sopClass); | |
238 if (!modalityName) modalityName = "unknown SOP class"; | |
62 | 239 throw OrthancException("DicomUserConnection: No presentation context for modality " + |
0 | 240 std::string(modalityName)); |
241 } | |
242 | |
243 // Prepare the transmission of data | |
244 T_DIMSE_C_StoreRQ req; | |
245 memset(&req, 0, sizeof(req)); | |
246 req.MessageID = assoc_->nextMsgID++; | |
247 strcpy(req.AffectedSOPClassUID, sopClass); | |
248 strcpy(req.AffectedSOPInstanceUID, sopInstance); | |
249 req.DataSetType = DIMSE_DATASET_PRESENT; | |
250 req.Priority = DIMSE_PRIORITY_MEDIUM; | |
251 | |
252 // Finally conduct transmission of data | |
253 T_DIMSE_C_StoreRSP rsp; | |
254 DcmDataset* statusDetail = NULL; | |
255 Check(DIMSE_storeUser(assoc_, presID, &req, | |
256 NULL, dcmff.getDataset(), /*progressCallback*/ NULL, NULL, | |
257 /*opt_blockMode*/ DIMSE_BLOCKING, /*opt_dimse_timeout*/ 0, | |
258 &rsp, &statusDetail, NULL)); | |
259 | |
260 if (statusDetail != NULL) | |
261 { | |
262 delete statusDetail; | |
263 } | |
264 } | |
265 | |
266 | |
267 static void FindCallback( | |
268 /* in */ | |
269 void *callbackData, | |
270 T_DIMSE_C_FindRQ *request, /* original find request */ | |
271 int responseCount, | |
272 T_DIMSE_C_FindRSP *response, /* pending response received */ | |
273 DcmDataset *responseIdentifiers /* pending response identifiers */ | |
274 ) | |
275 { | |
657
5425bb6f1ea5
further cppcheck fixes
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
656
diff
changeset
|
276 DicomFindAnswers& answers = *reinterpret_cast<DicomFindAnswers*>(callbackData); |
0 | 277 |
278 if (responseIdentifiers != NULL) | |
279 { | |
280 DicomMap m; | |
281 FromDcmtkBridge::Convert(m, *responseIdentifiers); | |
282 answers.Add(m); | |
283 } | |
284 } | |
285 | |
286 void DicomUserConnection::Find(DicomFindAnswers& result, | |
287 FindRootModel model, | |
288 const DicomMap& fields) | |
289 { | |
290 CheckIsOpen(); | |
291 | |
292 const char* sopClass; | |
293 std::auto_ptr<DcmDataset> dataset(ToDcmtkBridge::Convert(fields)); | |
294 switch (model) | |
295 { | |
296 case FindRootModel_Patient: | |
297 DU_putStringDOElement(dataset.get(), DcmTagKey(0x0008, 0x0052), "PATIENT"); | |
298 sopClass = UID_FINDPatientRootQueryRetrieveInformationModel; | |
299 | |
300 // Accession number | |
301 if (!fields.HasTag(0x0008, 0x0050)) | |
302 DU_putStringDOElement(dataset.get(), DcmTagKey(0x0008, 0x0050), ""); | |
303 | |
304 // Patient ID | |
305 if (!fields.HasTag(0x0010, 0x0020)) | |
306 DU_putStringDOElement(dataset.get(), DcmTagKey(0x0010, 0x0020), ""); | |
307 | |
308 break; | |
309 | |
310 case FindRootModel_Study: | |
311 DU_putStringDOElement(dataset.get(), DcmTagKey(0x0008, 0x0052), "STUDY"); | |
312 sopClass = UID_FINDStudyRootQueryRetrieveInformationModel; | |
313 | |
314 // Accession number | |
315 if (!fields.HasTag(0x0008, 0x0050)) | |
316 DU_putStringDOElement(dataset.get(), DcmTagKey(0x0008, 0x0050), ""); | |
317 | |
318 // Study instance UID | |
319 if (!fields.HasTag(0x0020, 0x000d)) | |
320 DU_putStringDOElement(dataset.get(), DcmTagKey(0x0020, 0x000d), ""); | |
321 | |
322 break; | |
323 | |
324 case FindRootModel_Series: | |
325 DU_putStringDOElement(dataset.get(), DcmTagKey(0x0008, 0x0052), "SERIES"); | |
326 sopClass = UID_FINDStudyRootQueryRetrieveInformationModel; | |
327 | |
328 // Accession number | |
329 if (!fields.HasTag(0x0008, 0x0050)) | |
330 DU_putStringDOElement(dataset.get(), DcmTagKey(0x0008, 0x0050), ""); | |
331 | |
332 // Study instance UID | |
333 if (!fields.HasTag(0x0020, 0x000d)) | |
334 DU_putStringDOElement(dataset.get(), DcmTagKey(0x0020, 0x000d), ""); | |
335 | |
336 // Series instance UID | |
337 if (!fields.HasTag(0x0020, 0x000e)) | |
338 DU_putStringDOElement(dataset.get(), DcmTagKey(0x0020, 0x000e), ""); | |
339 | |
340 break; | |
341 | |
342 case FindRootModel_Instance: | |
732
b79eda29896d
dcm4chee manufacturer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
725
diff
changeset
|
343 if (manufacturer_ == ModalityManufacturer_ClearCanvas || |
b79eda29896d
dcm4chee manufacturer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
725
diff
changeset
|
344 manufacturer_ == ModalityManufacturer_Dcm4Chee) |
519
1b2cdc855bd3
Parameter for PACS manufacturer, support for ClearCanvas
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
399
diff
changeset
|
345 { |
1b2cdc855bd3
Parameter for PACS manufacturer, support for ClearCanvas
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
399
diff
changeset
|
346 // This is a particular case for ClearCanvas, thanks to Peter Somlo <peter.somlo@gmail.com>. |
1b2cdc855bd3
Parameter for PACS manufacturer, support for ClearCanvas
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
399
diff
changeset
|
347 // https://groups.google.com/d/msg/orthanc-users/j-6C3MAVwiw/iolB9hclom8J |
1b2cdc855bd3
Parameter for PACS manufacturer, support for ClearCanvas
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
399
diff
changeset
|
348 // http://www.clearcanvas.ca/Home/Community/OldForums/tabid/526/aff/11/aft/14670/afv/topic/Default.aspx |
1b2cdc855bd3
Parameter for PACS manufacturer, support for ClearCanvas
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
399
diff
changeset
|
349 DU_putStringDOElement(dataset.get(), DcmTagKey(0x0008, 0x0052), "IMAGE"); |
1b2cdc855bd3
Parameter for PACS manufacturer, support for ClearCanvas
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
399
diff
changeset
|
350 } |
1b2cdc855bd3
Parameter for PACS manufacturer, support for ClearCanvas
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
399
diff
changeset
|
351 else |
1b2cdc855bd3
Parameter for PACS manufacturer, support for ClearCanvas
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
399
diff
changeset
|
352 { |
1b2cdc855bd3
Parameter for PACS manufacturer, support for ClearCanvas
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
399
diff
changeset
|
353 DU_putStringDOElement(dataset.get(), DcmTagKey(0x0008, 0x0052), "INSTANCE"); |
1b2cdc855bd3
Parameter for PACS manufacturer, support for ClearCanvas
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
399
diff
changeset
|
354 } |
1b2cdc855bd3
Parameter for PACS manufacturer, support for ClearCanvas
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
399
diff
changeset
|
355 |
0 | 356 sopClass = UID_FINDStudyRootQueryRetrieveInformationModel; |
357 | |
358 // Accession number | |
359 if (!fields.HasTag(0x0008, 0x0050)) | |
360 DU_putStringDOElement(dataset.get(), DcmTagKey(0x0008, 0x0050), ""); | |
361 | |
362 // Study instance UID | |
363 if (!fields.HasTag(0x0020, 0x000d)) | |
364 DU_putStringDOElement(dataset.get(), DcmTagKey(0x0020, 0x000d), ""); | |
365 | |
366 // Series instance UID | |
367 if (!fields.HasTag(0x0020, 0x000e)) | |
368 DU_putStringDOElement(dataset.get(), DcmTagKey(0x0020, 0x000e), ""); | |
369 | |
370 // SOP Instance UID | |
371 if (!fields.HasTag(0x0008, 0x0018)) | |
372 DU_putStringDOElement(dataset.get(), DcmTagKey(0x0008, 0x0018), ""); | |
373 | |
374 break; | |
375 | |
376 default: | |
62 | 377 throw OrthancException(ErrorCode_ParameterOutOfRange); |
0 | 378 } |
379 | |
380 // Figure out which of the accepted presentation contexts should be used | |
381 int presID = ASC_findAcceptedPresentationContextID(pimpl_->assoc_, sopClass); | |
382 if (presID == 0) | |
383 { | |
62 | 384 throw OrthancException("DicomUserConnection: The C-FIND command is not supported by the distant AET"); |
0 | 385 } |
386 | |
387 T_DIMSE_C_FindRQ request; | |
388 memset(&request, 0, sizeof(request)); | |
389 request.MessageID = pimpl_->assoc_->nextMsgID++; | |
390 strcpy(request.AffectedSOPClassUID, sopClass); | |
391 request.DataSetType = DIMSE_DATASET_PRESENT; | |
392 request.Priority = DIMSE_PRIORITY_MEDIUM; | |
393 | |
394 T_DIMSE_C_FindRSP response; | |
395 DcmDataset* statusDetail = NULL; | |
396 OFCondition cond = DIMSE_findUser(pimpl_->assoc_, presID, &request, dataset.get(), | |
397 FindCallback, &result, | |
398 /*opt_blockMode*/ DIMSE_BLOCKING, /*opt_dimse_timeout*/ 0, | |
399 &response, &statusDetail); | |
400 | |
401 if (statusDetail) | |
402 { | |
403 delete statusDetail; | |
404 } | |
405 | |
406 Check(cond); | |
407 } | |
408 | |
409 | |
410 void DicomUserConnection::FindPatient(DicomFindAnswers& result, | |
411 const DicomMap& fields) | |
412 { | |
413 // Only keep the filters from "fields" that are related to the patient | |
414 DicomMap s; | |
415 fields.ExtractPatientInformation(s); | |
416 Find(result, FindRootModel_Patient, s); | |
417 } | |
418 | |
419 void DicomUserConnection::FindStudy(DicomFindAnswers& result, | |
420 const DicomMap& fields) | |
421 { | |
422 // Only keep the filters from "fields" that are related to the study | |
423 DicomMap s; | |
424 fields.ExtractStudyInformation(s); | |
425 | |
80 | 426 s.CopyTagIfExists(fields, DICOM_TAG_PATIENT_ID); |
427 s.CopyTagIfExists(fields, DICOM_TAG_ACCESSION_NUMBER); | |
725 | 428 s.CopyTagIfExists(fields, DICOM_TAG_MODALITIES_IN_STUDY); |
0 | 429 |
430 Find(result, FindRootModel_Study, s); | |
431 } | |
432 | |
433 void DicomUserConnection::FindSeries(DicomFindAnswers& result, | |
434 const DicomMap& fields) | |
435 { | |
436 // Only keep the filters from "fields" that are related to the series | |
437 DicomMap s; | |
438 fields.ExtractSeriesInformation(s); | |
439 | |
80 | 440 s.CopyTagIfExists(fields, DICOM_TAG_PATIENT_ID); |
441 s.CopyTagIfExists(fields, DICOM_TAG_ACCESSION_NUMBER); | |
442 s.CopyTagIfExists(fields, DICOM_TAG_STUDY_INSTANCE_UID); | |
0 | 443 |
444 Find(result, FindRootModel_Series, s); | |
445 } | |
446 | |
447 void DicomUserConnection::FindInstance(DicomFindAnswers& result, | |
448 const DicomMap& fields) | |
449 { | |
450 // Only keep the filters from "fields" that are related to the instance | |
451 DicomMap s; | |
452 fields.ExtractInstanceInformation(s); | |
453 | |
80 | 454 s.CopyTagIfExists(fields, DICOM_TAG_PATIENT_ID); |
455 s.CopyTagIfExists(fields, DICOM_TAG_ACCESSION_NUMBER); | |
456 s.CopyTagIfExists(fields, DICOM_TAG_STUDY_INSTANCE_UID); | |
457 s.CopyTagIfExists(fields, DICOM_TAG_SERIES_INSTANCE_UID); | |
0 | 458 |
459 Find(result, FindRootModel_Instance, s); | |
460 } | |
461 | |
462 | |
463 void DicomUserConnection::Move(const std::string& targetAet, | |
464 const DicomMap& fields) | |
465 { | |
466 CheckIsOpen(); | |
467 | |
468 const char* sopClass = UID_MOVEStudyRootQueryRetrieveInformationModel; | |
469 std::auto_ptr<DcmDataset> dataset(ToDcmtkBridge::Convert(fields)); | |
470 | |
471 // Figure out which of the accepted presentation contexts should be used | |
472 int presID = ASC_findAcceptedPresentationContextID(pimpl_->assoc_, sopClass); | |
473 if (presID == 0) | |
474 { | |
62 | 475 throw OrthancException("DicomUserConnection: The C-MOVE command is not supported by the distant AET"); |
0 | 476 } |
477 | |
478 T_DIMSE_C_MoveRQ request; | |
479 memset(&request, 0, sizeof(request)); | |
480 request.MessageID = pimpl_->assoc_->nextMsgID++; | |
481 strcpy(request.AffectedSOPClassUID, sopClass); | |
482 request.DataSetType = DIMSE_DATASET_PRESENT; | |
483 request.Priority = DIMSE_PRIORITY_MEDIUM; | |
484 strncpy(request.MoveDestination, targetAet.c_str(), sizeof(DIC_AE) / sizeof(char)); | |
485 | |
486 T_DIMSE_C_MoveRSP response; | |
487 DcmDataset* statusDetail = NULL; | |
488 DcmDataset* responseIdentifiers = NULL; | |
489 OFCondition cond = DIMSE_moveUser(pimpl_->assoc_, presID, &request, dataset.get(), | |
490 NULL, NULL, | |
491 /*opt_blockMode*/ DIMSE_BLOCKING, /*opt_dimse_timeout*/ 0, | |
492 pimpl_->net_, NULL, NULL, | |
493 &response, &statusDetail, &responseIdentifiers); | |
494 | |
495 if (statusDetail) | |
496 { | |
497 delete statusDetail; | |
498 } | |
499 | |
500 if (responseIdentifiers) | |
501 { | |
502 delete responseIdentifiers; | |
503 } | |
504 | |
505 Check(cond); | |
506 } | |
507 | |
508 | |
656 | 509 DicomUserConnection::DicomUserConnection() : |
510 pimpl_(new PImpl), | |
666
b8383ac0b227
fix cppcheck warning
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
662
diff
changeset
|
511 preferredTransferSyntax_(DEFAULT_PREFERRED_TRANSFER_SYNTAX), |
656 | 512 localAet_("STORESCU"), |
513 distantAet_("ANY-SCP"), | |
514 distantHost_("127.0.0.1") | |
0 | 515 { |
516 distantPort_ = 104; | |
519
1b2cdc855bd3
Parameter for PACS manufacturer, support for ClearCanvas
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
399
diff
changeset
|
517 manufacturer_ = ModalityManufacturer_Generic; |
0 | 518 |
519 pimpl_->net_ = NULL; | |
520 pimpl_->params_ = NULL; | |
521 pimpl_->assoc_ = NULL; | |
522 } | |
523 | |
524 DicomUserConnection::~DicomUserConnection() | |
525 { | |
526 Close(); | |
527 } | |
528 | |
529 void DicomUserConnection::SetLocalApplicationEntityTitle(const std::string& aet) | |
530 { | |
662
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
531 if (localAet_ != aet) |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
532 { |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
533 Close(); |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
534 localAet_ = aet; |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
535 } |
0 | 536 } |
537 | |
538 void DicomUserConnection::SetDistantApplicationEntityTitle(const std::string& aet) | |
539 { | |
662
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
540 if (distantAet_ != aet) |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
541 { |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
542 Close(); |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
543 distantAet_ = aet; |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
544 } |
0 | 545 } |
546 | |
519
1b2cdc855bd3
Parameter for PACS manufacturer, support for ClearCanvas
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
399
diff
changeset
|
547 void DicomUserConnection::SetDistantManufacturer(ModalityManufacturer manufacturer) |
1b2cdc855bd3
Parameter for PACS manufacturer, support for ClearCanvas
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
399
diff
changeset
|
548 { |
662
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
549 if (manufacturer_ != manufacturer) |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
550 { |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
551 Close(); |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
552 manufacturer_ = manufacturer; |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
553 } |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
554 } |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
555 |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
556 void DicomUserConnection::ResetPreferredTransferSyntax() |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
557 { |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
558 SetPreferredTransferSyntax(DEFAULT_PREFERRED_TRANSFER_SYNTAX); |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
559 } |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
560 |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
561 void DicomUserConnection::SetPreferredTransferSyntax(const std::string& preferredTransferSyntax) |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
562 { |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
563 if (preferredTransferSyntax_ != preferredTransferSyntax) |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
564 { |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
565 Close(); |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
566 preferredTransferSyntax_ = preferredTransferSyntax; |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
567 } |
519
1b2cdc855bd3
Parameter for PACS manufacturer, support for ClearCanvas
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
399
diff
changeset
|
568 } |
1b2cdc855bd3
Parameter for PACS manufacturer, support for ClearCanvas
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
399
diff
changeset
|
569 |
0 | 570 |
571 void DicomUserConnection::SetDistantHost(const std::string& host) | |
572 { | |
662
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
573 if (distantHost_ != host) |
0 | 574 { |
662
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
575 if (host.size() > HOST_NAME_MAX - 10) |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
576 { |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
577 throw OrthancException("Distant host name is too long"); |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
578 } |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
579 |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
580 Close(); |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
581 distantHost_ = host; |
0 | 582 } |
583 } | |
584 | |
585 void DicomUserConnection::SetDistantPort(uint16_t port) | |
586 { | |
662
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
587 if (distantPort_ != port) |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
588 { |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
589 Close(); |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
590 distantPort_ = port; |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
591 } |
0 | 592 } |
593 | |
594 void DicomUserConnection::Open() | |
595 { | |
662
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
596 if (IsOpen()) |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
597 { |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
598 // Don't reopen the connection |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
599 return; |
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
600 } |
0 | 601 |
602 Check(ASC_initializeNetwork(NET_REQUESTOR, 0, /*opt_acse_timeout*/ 30, &pimpl_->net_)); | |
603 Check(ASC_createAssociationParameters(&pimpl_->params_, /*opt_maxReceivePDULength*/ ASC_DEFAULTMAXPDU)); | |
604 | |
605 // Set this application's title and the called application's title in the params | |
606 Check(ASC_setAPTitles(pimpl_->params_, localAet_.c_str(), distantAet_.c_str(), NULL)); | |
607 | |
608 // Set the network addresses of the local and distant entities | |
609 char localHost[HOST_NAME_MAX]; | |
610 gethostname(localHost, HOST_NAME_MAX - 1); | |
611 | |
612 char distantHostAndPort[HOST_NAME_MAX]; | |
2 | 613 |
614 #ifdef _MSC_VER | |
615 _snprintf | |
616 #else | |
617 snprintf | |
618 #endif | |
619 (distantHostAndPort, HOST_NAME_MAX - 1, "%s:%d", distantHost_.c_str(), distantPort_); | |
0 | 620 |
621 Check(ASC_setPresentationAddresses(pimpl_->params_, localHost, distantHostAndPort)); | |
622 | |
623 // Set various options | |
624 Check(ASC_setTransportLayerType(pimpl_->params_, /*opt_secureConnection*/ false)); | |
625 | |
662
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
626 SetupPresentationContexts(preferredTransferSyntax_); |
0 | 627 |
628 // Do the association | |
629 Check(ASC_requestAssociation(pimpl_->net_, pimpl_->params_, &pimpl_->assoc_)); | |
630 | |
631 if (ASC_countAcceptedPresentationContexts(pimpl_->params_) == 0) | |
632 { | |
62 | 633 throw OrthancException("DicomUserConnection: No Acceptable Presentation Contexts"); |
0 | 634 } |
635 } | |
636 | |
637 void DicomUserConnection::Close() | |
638 { | |
639 if (pimpl_->assoc_ != NULL) | |
640 { | |
641 ASC_releaseAssociation(pimpl_->assoc_); | |
642 ASC_destroyAssociation(&pimpl_->assoc_); | |
643 pimpl_->assoc_ = NULL; | |
644 pimpl_->params_ = NULL; | |
645 } | |
646 else | |
647 { | |
648 if (pimpl_->params_ != NULL) | |
649 { | |
650 ASC_destroyAssociationParameters(&pimpl_->params_); | |
651 pimpl_->params_ = NULL; | |
652 } | |
653 } | |
654 | |
655 if (pimpl_->net_ != NULL) | |
656 { | |
657 ASC_dropNetwork(&pimpl_->net_); | |
658 pimpl_->net_ = NULL; | |
659 } | |
660 } | |
661 | |
662 bool DicomUserConnection::IsOpen() const | |
663 { | |
664 return pimpl_->IsOpen(); | |
665 } | |
666 | |
667 void DicomUserConnection::Store(const char* buffer, size_t size) | |
668 { | |
669 // Prepare an input stream for the memory buffer | |
670 DcmInputBufferStream is; | |
671 if (size > 0) | |
672 is.setBuffer(buffer, size); | |
673 is.setEos(); | |
674 | |
662
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
675 pimpl_->Store(is, *this); |
0 | 676 } |
677 | |
678 void DicomUserConnection::Store(const std::string& buffer) | |
679 { | |
680 if (buffer.size() > 0) | |
681 Store(reinterpret_cast<const char*>(&buffer[0]), buffer.size()); | |
682 else | |
683 Store(NULL, 0); | |
684 } | |
685 | |
686 void DicomUserConnection::StoreFile(const std::string& path) | |
687 { | |
688 // Prepare an input stream for the file | |
689 DcmInputFileStream is(path.c_str()); | |
662
70161eb45b5c
orthanc can act as a C-Store SCU for JPEG transfer syntax
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
657
diff
changeset
|
690 pimpl_->Store(is, *this); |
0 | 691 } |
692 | |
693 bool DicomUserConnection::Echo() | |
694 { | |
695 CheckIsOpen(); | |
696 DIC_US status; | |
697 Check(DIMSE_echoUser(pimpl_->assoc_, pimpl_->assoc_->nextMsgID++, | |
698 /*opt_blockMode*/ DIMSE_BLOCKING, /*opt_dimse_timeout*/ 0, | |
699 &status, NULL)); | |
700 return status == STATUS_Success; | |
701 } | |
702 | |
703 | |
704 void DicomUserConnection::MoveSeries(const std::string& targetAet, | |
705 const DicomMap& findResult) | |
706 { | |
707 DicomMap simplified; | |
80 | 708 simplified.SetValue(DICOM_TAG_STUDY_INSTANCE_UID, findResult.GetValue(DICOM_TAG_STUDY_INSTANCE_UID)); |
709 simplified.SetValue(DICOM_TAG_SERIES_INSTANCE_UID, findResult.GetValue(DICOM_TAG_SERIES_INSTANCE_UID)); | |
0 | 710 Move(targetAet, simplified); |
711 } | |
712 | |
713 void DicomUserConnection::MoveSeries(const std::string& targetAet, | |
714 const std::string& studyUid, | |
715 const std::string& seriesUid) | |
716 { | |
717 DicomMap map; | |
80 | 718 map.SetValue(DICOM_TAG_STUDY_INSTANCE_UID, studyUid); |
719 map.SetValue(DICOM_TAG_SERIES_INSTANCE_UID, seriesUid); | |
0 | 720 Move(targetAet, map); |
721 } | |
722 | |
723 void DicomUserConnection::MoveInstance(const std::string& targetAet, | |
724 const DicomMap& findResult) | |
725 { | |
726 DicomMap simplified; | |
80 | 727 simplified.SetValue(DICOM_TAG_STUDY_INSTANCE_UID, findResult.GetValue(DICOM_TAG_STUDY_INSTANCE_UID)); |
728 simplified.SetValue(DICOM_TAG_SERIES_INSTANCE_UID, findResult.GetValue(DICOM_TAG_SERIES_INSTANCE_UID)); | |
729 simplified.SetValue(DICOM_TAG_SOP_INSTANCE_UID, findResult.GetValue(DICOM_TAG_SOP_INSTANCE_UID)); | |
0 | 730 Move(targetAet, simplified); |
731 } | |
732 | |
733 void DicomUserConnection::MoveInstance(const std::string& targetAet, | |
734 const std::string& studyUid, | |
735 const std::string& seriesUid, | |
736 const std::string& instanceUid) | |
737 { | |
738 DicomMap map; | |
80 | 739 map.SetValue(DICOM_TAG_STUDY_INSTANCE_UID, studyUid); |
740 map.SetValue(DICOM_TAG_SERIES_INSTANCE_UID, seriesUid); | |
741 map.SetValue(DICOM_TAG_SOP_INSTANCE_UID, instanceUid); | |
0 | 742 Move(targetAet, map); |
743 } | |
744 | |
745 void DicomUserConnection::SetConnectionTimeout(uint32_t seconds) | |
746 { | |
747 dcmConnectionTimeout.set(seconds); | |
748 } | |
749 | |
750 } |