comparison OrthancServer/Sources/OrthancGetRequestHandler.cpp @ 4257:c046d559edb3

Fix reporting of client-side store warnings/errors in C-GET SCP
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 20 Oct 2020 09:52:42 +0200
parents 318c16cfccab
children 6f5d4bfb2c90
comparison
equal deleted inserted replaced
4256:cbce4f43884a 4257:c046d559edb3
105 } 105 }
106 106
107 std::string sopClassUid(a.c_str()); 107 std::string sopClassUid(a.c_str());
108 std::string sopInstanceUid(b.c_str()); 108 std::string sopInstanceUid(b.c_str());
109 109
110 OFCondition cond = PerformGetSubOp(assoc, sopClassUid, sopInstanceUid, parsed.release()); 110 Status status = PerformGetSubOp(assoc, sopClassUid, sopInstanceUid, parsed.release());
111 111
112 if (getCancelled_) 112 if (getCancelled_)
113 { 113 {
114 LOG(INFO) << "C-GET SCP: Received C-Cancel RQ"; 114 LOG(INFO) << "C-GET SCP: Received C-Cancel RQ";
115 }
116
117 if (cond.bad() || getCancelled_)
118 {
119 return Status_Failure; 115 return Status_Failure;
120 } 116 }
121 117 else
122 return Status_Success; 118 {
119 return status;
120 }
123 } 121 }
124 122
125 123
126 void OrthancGetRequestHandler::AddFailedUIDInstance(const std::string& sopInstance) 124 void OrthancGetRequestHandler::AddFailedUIDInstance(const std::string& sopInstance)
127 { 125 {
231 // No preferred syntax was accepted 229 // No preferred syntax was accepted
232 return false; 230 return false;
233 } 231 }
234 232
235 233
236 OFCondition OrthancGetRequestHandler::PerformGetSubOp(T_ASC_Association* assoc, 234 OrthancGetRequestHandler::Status
237 const std::string& sopClassUid, 235 OrthancGetRequestHandler::PerformGetSubOp(T_ASC_Association* assoc,
238 const std::string& sopInstanceUid, 236 const std::string& sopClassUid,
239 DcmFileFormat* dicomRaw) 237 const std::string& sopInstanceUid,
238 DcmFileFormat* dicomRaw)
240 { 239 {
241 assert(dicomRaw != NULL); 240 assert(dicomRaw != NULL);
242 std::unique_ptr<DcmFileFormat> dicom(dicomRaw); 241 std::unique_ptr<DcmFileFormat> dicom(dicomRaw);
243 242
244 DicomTransferSyntax sourceSyntax; 243 DicomTransferSyntax sourceSyntax;
246 { 245 {
247 nFailed_++; 246 nFailed_++;
248 AddFailedUIDInstance(sopInstanceUid); 247 AddFailedUIDInstance(sopInstanceUid);
249 LOG(ERROR) << "C-GET SCP: Unknown transfer syntax: (" 248 LOG(ERROR) << "C-GET SCP: Unknown transfer syntax: ("
250 << dcmSOPClassUIDToModality(sopClassUid.c_str(), "OT") << ") " << sopClassUid; 249 << dcmSOPClassUIDToModality(sopClassUid.c_str(), "OT") << ") " << sopClassUid;
251 return DIMSE_NOVALIDPRESENTATIONCONTEXTID; 250 return Status_Failure;
252 } 251 }
253 252
254 bool allowTranscoding = (context_.IsTranscodeDicomProtocol() && 253 bool allowTranscoding = (context_.IsTranscodeDicomProtocol() &&
255 remote_.IsTranscodingAllowed()); 254 remote_.IsTranscodingAllowed());
256 255
262 { 261 {
263 nFailed_++; 262 nFailed_++;
264 AddFailedUIDInstance(sopInstanceUid); 263 AddFailedUIDInstance(sopInstanceUid);
265 LOG(ERROR) << "C-GET SCP: storeSCU: No presentation context for: (" 264 LOG(ERROR) << "C-GET SCP: storeSCU: No presentation context for: ("
266 << dcmSOPClassUIDToModality(sopClassUid.c_str(), "OT") << ") " << sopClassUid; 265 << dcmSOPClassUIDToModality(sopClassUid.c_str(), "OT") << ") " << sopClassUid;
267 return DIMSE_NOVALIDPRESENTATIONCONTEXTID; 266 return Status_Failure;
268 } 267 }
269 else 268 else
270 { 269 {
271 LOG(INFO) << "C-GET SCP selected transfer syntax " << GetTransferSyntaxUid(selectedSyntax) 270 LOG(INFO) << "C-GET SCP selected transfer syntax " << GetTransferSyntaxUid(selectedSyntax)
272 << ", for source instance with SOP class " << sopClassUid 271 << ", for source instance with SOP class " << sopClassUid
284 // the role is not appropriate 283 // the role is not appropriate
285 nFailed_++; 284 nFailed_++;
286 AddFailedUIDInstance(sopInstanceUid); 285 AddFailedUIDInstance(sopInstanceUid);
287 LOG(ERROR) << "C-GET SCP: storeSCU: [No presentation context with requestor SCP role for: (" 286 LOG(ERROR) << "C-GET SCP: storeSCU: [No presentation context with requestor SCP role for: ("
288 << dcmSOPClassUIDToModality(sopClassUid.c_str(), "OT") << ") " << sopClassUid; 287 << dcmSOPClassUIDToModality(sopClassUid.c_str(), "OT") << ") " << sopClassUid;
289 return DIMSE_NOVALIDPRESENTATIONCONTEXTID; 288 return Status_Failure;
290 } 289 }
291 } 290 }
292 291
293 const DIC_US msgId = assoc->nextMsgID++; 292 const DIC_US msgId = assoc->nextMsgID++;
294 293
352 nFailed_++; 351 nFailed_++;
353 AddFailedUIDInstance(sopInstanceUid); 352 AddFailedUIDInstance(sopInstanceUid);
354 LOG(ERROR) << "C-GET SCP: Cannot transcode " << sopClassUid 353 LOG(ERROR) << "C-GET SCP: Cannot transcode " << sopClassUid
355 << " from transfer syntax " << GetTransferSyntaxUid(sourceSyntax) 354 << " from transfer syntax " << GetTransferSyntaxUid(sourceSyntax)
356 << " to " << GetTransferSyntaxUid(selectedSyntax); 355 << " to " << GetTransferSyntaxUid(selectedSyntax);
357 return DIMSE_NOVALIDPRESENTATIONCONTEXTID; 356 return Status_Failure;
358 } 357 }
359 } 358 }
360 359
360 Status status;
361 if (cond.good()) 361 if (cond.good())
362 { 362 {
363 if (cancelParameters.cancelEncountered) 363 if (cancelParameters.cancelEncountered)
364 { 364 {
365 if (origPresId_ == cancelParameters.presId && 365 if (origPresId_ == cancelParameters.presId &&
366 origMsgId_ == cancelParameters.req.MessageIDBeingRespondedTo) 366 origMsgId_ == cancelParameters.req.MessageIDBeingRespondedTo)
367 { 367 {
368 getCancelled_ = OFTrue; 368 getCancelled_ = true;
369 } 369 }
370 else 370 else
371 { 371 {
372 LOG(ERROR) << "C-GET SCP: Unexpected C-Cancel-RQ encountered: pid=" << (int)cancelParameters.presId 372 LOG(ERROR) << "C-GET SCP: Unexpected C-Cancel-RQ encountered: pid=" << (int)cancelParameters.presId
373 << ", mid=" << (int)cancelParameters.req.MessageIDBeingRespondedTo; 373 << ", mid=" << (int)cancelParameters.req.MessageIDBeingRespondedTo;
376 376
377 if (rsp.DimseStatus == STATUS_Success) 377 if (rsp.DimseStatus == STATUS_Success)
378 { 378 {
379 // everything ok 379 // everything ok
380 nCompleted_++; 380 nCompleted_++;
381 status = Status_Success;
381 } 382 }
382 else if ((rsp.DimseStatus & 0xf000) == 0xb000) 383 else if ((rsp.DimseStatus & 0xf000) == 0xb000)
383 { 384 {
384 // a warning status message 385 // a warning status message
385 warningCount_++; 386 warningCount_++;
386 LOG(ERROR) << "C-GET SCP: Store Warning: Response Status: " 387 LOG(ERROR) << "C-GET SCP: Store Warning: Response Status: "
387 << DU_cstoreStatusString(rsp.DimseStatus); 388 << DU_cstoreStatusString(rsp.DimseStatus);
389 status = Status_Warning;
388 } 390 }
389 else 391 else
390 { 392 {
391 nFailed_++; 393 nFailed_++;
392 AddFailedUIDInstance(sopInstanceUid); 394 AddFailedUIDInstance(sopInstanceUid);
393 // print a status message 395 // print a status message
394 LOG(ERROR) << "C-GET SCP: Store Failed: Response Status: " 396 LOG(ERROR) << "C-GET SCP: Store Failed: Response Status: "
395 << DU_cstoreStatusString(rsp.DimseStatus); 397 << DU_cstoreStatusString(rsp.DimseStatus);
398 status = Status_Failure;
396 } 399 }
397 } 400 }
398 else 401 else
399 { 402 {
400 nFailed_++; 403 nFailed_++;
401 AddFailedUIDInstance(sopInstanceUid); 404 AddFailedUIDInstance(sopInstanceUid);
402 OFString temp_str; 405 OFString temp_str;
403 LOG(ERROR) << "C-GET SCP: storeSCU: Store Request Failed: " << DimseCondition::dump(temp_str, cond); 406 LOG(ERROR) << "C-GET SCP: storeSCU: Store Request Failed: " << DimseCondition::dump(temp_str, cond);
407 status = Status_Failure;
404 } 408 }
405 409
406 if (stDetail.get() != NULL) 410 if (stDetail.get() != NULL)
407 { 411 {
408 // It is impossible to directly use the "<<" stream construct 412 // It is impossible to directly use the "<<" stream construct
412 obj.dcmobj_.print(s); 416 obj.dcmobj_.print(s);
413 417
414 LOG(INFO) << " Status Detail: " << s.str(); 418 LOG(INFO) << " Status Detail: " << s.str();
415 } 419 }
416 420
417 return cond; 421 return status;
418 } 422 }
419 423
420 bool OrthancGetRequestHandler::LookupIdentifiers(std::list<std::string>& publicIds, 424 bool OrthancGetRequestHandler::LookupIdentifiers(std::list<std::string>& publicIds,
421 ResourceType level, 425 ResourceType level,
422 const DicomMap& input) const 426 const DicomMap& input) const
569 instances_.push_back(*it); 573 instances_.push_back(*it);
570 } 574 }
571 } 575 }
572 576
573 failedUIDs_.clear(); 577 failedUIDs_.clear();
574 getCancelled_ = OFFalse; 578 getCancelled_ = false;
575 579
576 nRemaining_ = GetSubOperationCount(); 580 nRemaining_ = GetSubOperationCount();
577 nCompleted_ = 0; 581 nCompleted_ = 0;
578 nFailed_ = 0; 582 nFailed_ = 0;
579 warningCount_ = 0; 583 warningCount_ = 0;