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 }