Mercurial > hg > orthanc
comparison Core/DicomNetworking/DicomStoreUserConnection.cpp @ 3862:594263db316a transcoding
DicomModalityStoreJob now uses DicomStoreUserConnection
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Mon, 27 Apr 2020 17:28:55 +0200 |
parents | 83ea6939293d |
children | d5be23fc0106 |
comparison
equal
deleted
inserted
replaced
3861:eb8280b30031 | 3862:594263db316a |
---|---|
114 } | 114 } |
115 } | 115 } |
116 | 116 |
117 return false; | 117 return false; |
118 } | 118 } |
119 | |
120 | |
121 void DicomStoreUserConnection::Setup() | |
122 { | |
123 association_.reset(new DicomAssociation); | |
124 proposeCommonClasses_ = true; | |
125 proposeUncompressedSyntaxes_ = true; | |
126 proposeRetiredBigEndian_ = false; | |
127 } | |
119 | 128 |
120 | 129 |
121 DicomStoreUserConnection::DicomStoreUserConnection( | 130 DicomStoreUserConnection::DicomStoreUserConnection( |
131 const std::string& localAet, | |
132 const RemoteModalityParameters& remote) : | |
133 parameters_(localAet, remote) | |
134 { | |
135 Setup(); | |
136 } | |
137 | |
138 | |
139 DicomStoreUserConnection::DicomStoreUserConnection( | |
122 const DicomAssociationParameters& params) : | 140 const DicomAssociationParameters& params) : |
123 parameters_(params), | 141 parameters_(params) |
124 association_(new DicomAssociation), | 142 { |
125 proposeCommonClasses_(true), | 143 Setup(); |
126 proposeUncompressedSyntaxes_(true), | |
127 proposeRetiredBigEndian_(false) | |
128 { | |
129 } | 144 } |
130 | 145 |
131 | 146 |
132 void DicomStoreUserConnection::PrepareStorageClass(const std::string& sopClassUid, | 147 void DicomStoreUserConnection::PrepareStorageClass(const std::string& sopClassUid, |
133 DicomTransferSyntax syntax) | 148 DicomTransferSyntax syntax) |
144 { | 159 { |
145 found->second.insert(syntax); | 160 found->second.insert(syntax); |
146 } | 161 } |
147 } | 162 } |
148 | 163 |
164 | |
165 void DicomStoreUserConnection::LookupParameters(std::string& sopClassUid, | |
166 std::string& sopInstanceUid, | |
167 DicomTransferSyntax& transferSyntax, | |
168 DcmDataset& dataset) | |
169 { | |
170 OFString a, b; | |
171 if (!dataset.findAndGetOFString(DCM_SOPClassUID, a).good() || | |
172 !dataset.findAndGetOFString(DCM_SOPInstanceUID, b).good()) | |
173 { | |
174 throw OrthancException(ErrorCode_NoSopClassOrInstance, | |
175 "Unable to determine the SOP class/instance for C-STORE with AET " + | |
176 parameters_.GetRemoteApplicationEntityTitle()); | |
177 } | |
178 | |
179 sopClassUid.assign(a.c_str()); | |
180 sopInstanceUid.assign(b.c_str()); | |
181 | |
182 if (!FromDcmtkBridge::LookupOrthancTransferSyntax( | |
183 transferSyntax, dataset.getOriginalXfer())) | |
184 { | |
185 throw OrthancException(ErrorCode_InternalError, | |
186 "Unknown transfer syntax from DCMTK"); | |
187 } | |
188 } | |
189 | |
149 | 190 |
150 bool DicomStoreUserConnection::NegotiatePresentationContext( | 191 bool DicomStoreUserConnection::NegotiatePresentationContext( |
151 uint8_t& presentationContextId, | 192 uint8_t& presentationContextId, |
152 const std::string& sopClassUid, | 193 const std::string& sopClassUid, |
153 DicomTransferSyntax transferSyntax) | 194 DicomTransferSyntax transferSyntax) |
161 { | 202 { |
162 return true; | 203 return true; |
163 } | 204 } |
164 | 205 |
165 // The association must be re-negotiated | 206 // The association must be re-negotiated |
166 LOG(INFO) << "Re-negociating DICOM association with " | 207 if (association_->IsOpen()) |
167 << parameters_.GetRemoteApplicationEntityTitle(); | 208 { |
209 LOG(INFO) << "Re-negociating DICOM association with " | |
210 << parameters_.GetRemoteApplicationEntityTitle(); | |
211 } | |
212 | |
168 association_->ClearPresentationContexts(); | 213 association_->ClearPresentationContexts(); |
169 PrepareStorageClass(sopClassUid, transferSyntax); | 214 PrepareStorageClass(sopClassUid, transferSyntax); |
170 | 215 |
171 | 216 |
172 /** | 217 /** |
247 std::string& sopInstanceUid, | 292 std::string& sopInstanceUid, |
248 DcmDataset& dataset, | 293 DcmDataset& dataset, |
249 const std::string& moveOriginatorAET, | 294 const std::string& moveOriginatorAET, |
250 uint16_t moveOriginatorID) | 295 uint16_t moveOriginatorID) |
251 { | 296 { |
252 OFString a, b; | |
253 if (!dataset.findAndGetOFString(DCM_SOPClassUID, a).good() || | |
254 !dataset.findAndGetOFString(DCM_SOPInstanceUID, b).good()) | |
255 { | |
256 throw OrthancException(ErrorCode_NoSopClassOrInstance, | |
257 "Unable to determine the SOP class/instance for C-STORE with AET " + | |
258 parameters_.GetRemoteApplicationEntityTitle()); | |
259 } | |
260 | |
261 sopClassUid.assign(a.c_str()); | |
262 sopInstanceUid.assign(b.c_str()); | |
263 | |
264 DicomTransferSyntax transferSyntax; | 297 DicomTransferSyntax transferSyntax; |
265 if (!FromDcmtkBridge::LookupOrthancTransferSyntax( | 298 LookupParameters(sopClassUid, sopInstanceUid, transferSyntax, dataset); |
266 transferSyntax, dataset.getOriginalXfer())) | 299 |
267 { | |
268 throw OrthancException(ErrorCode_InternalError, | |
269 "Unknown transfer syntax from DCMTK"); | |
270 } | |
271 | |
272 // Figure out which accepted presentation context should be used | |
273 uint8_t presID; | 300 uint8_t presID; |
274 if (!NegotiatePresentationContext(presID, sopClassUid.c_str(), transferSyntax)) | 301 if (!NegotiatePresentationContext(presID, sopClassUid, transferSyntax)) |
275 { | 302 { |
276 throw OrthancException(ErrorCode_InternalError, | 303 throw OrthancException(ErrorCode_NetworkProtocol, |
277 "No valid presentation context was negotiated upfront"); | 304 "No valid presentation context was negotiated for " |
305 "SOP class UID [" + sopClassUid + "] and transfer " | |
306 "syntax [" + GetTransferSyntaxUid(transferSyntax) + "] " | |
307 "while sending to modality [" + | |
308 parameters_.GetRemoteApplicationEntityTitle() + "]"); | |
278 } | 309 } |
279 | 310 |
280 // Prepare the transmission of data | 311 // Prepare the transmission of data |
281 T_DIMSE_C_StoreRQ request; | 312 T_DIMSE_C_StoreRQ request; |
282 memset(&request, 0, sizeof(request)); | 313 memset(&request, 0, sizeof(request)); |
336 std::string& sopInstanceUid, | 367 std::string& sopInstanceUid, |
337 ParsedDicomFile& parsed, | 368 ParsedDicomFile& parsed, |
338 const std::string& moveOriginatorAET, | 369 const std::string& moveOriginatorAET, |
339 uint16_t moveOriginatorID) | 370 uint16_t moveOriginatorID) |
340 { | 371 { |
372 if (parsed.GetDcmtkObject().getDataset() == NULL) | |
373 { | |
374 throw OrthancException(ErrorCode_InternalError); | |
375 } | |
376 | |
341 Store(sopClassUid, sopInstanceUid, *parsed.GetDcmtkObject().getDataset(), | 377 Store(sopClassUid, sopInstanceUid, *parsed.GetDcmtkObject().getDataset(), |
342 moveOriginatorAET, moveOriginatorID); | 378 moveOriginatorAET, moveOriginatorID); |
343 } | 379 } |
344 | 380 |
345 | 381 |
351 uint16_t moveOriginatorID) | 387 uint16_t moveOriginatorID) |
352 { | 388 { |
353 std::unique_ptr<DcmFileFormat> dicom( | 389 std::unique_ptr<DcmFileFormat> dicom( |
354 FromDcmtkBridge::LoadFromMemoryBuffer(buffer, size)); | 390 FromDcmtkBridge::LoadFromMemoryBuffer(buffer, size)); |
355 | 391 |
392 if (dicom.get() == NULL || | |
393 dicom->getDataset() == NULL) | |
394 { | |
395 throw OrthancException(ErrorCode_InternalError); | |
396 } | |
397 | |
356 Store(sopClassUid, sopInstanceUid, *dicom->getDataset(), | 398 Store(sopClassUid, sopInstanceUid, *dicom->getDataset(), |
357 moveOriginatorAET, moveOriginatorID); | 399 moveOriginatorAET, moveOriginatorID); |
358 } | 400 } |
359 } | 401 } |