comparison Core/DicomNetworking/Internals/CommandDispatcher.cpp @ 3343:6e42d676401c

Fix issue #137 (C-STORE fails for unknown SOP Class although server is configured to accept any)
author Sebastien Jodogne <s.jodogne@gmail.com>
date Fri, 05 Apr 2019 16:01:42 +0200
parents bce0e4c9ca45
children 1bcc35e4615a
comparison
equal deleted inserted replaced
3342:63f59ad9381a 3343:6e42d676401c
92 #include "MoveScp.h" 92 #include "MoveScp.h"
93 #include "../../Toolbox.h" 93 #include "../../Toolbox.h"
94 #include "../../Logging.h" 94 #include "../../Logging.h"
95 95
96 #include <dcmtk/dcmnet/dcasccfg.h> /* for class DcmAssociationConfiguration */ 96 #include <dcmtk/dcmnet/dcasccfg.h> /* for class DcmAssociationConfiguration */
97 #include <dcmtk/dcmdata/dcuid.h> /* for variable dcmAllStorageSOPClassUIDs */
98
97 #include <boost/lexical_cast.hpp> 99 #include <boost/lexical_cast.hpp>
98 100
99 static OFBool opt_rejectWithoutImplementationUID = OFFalse; 101 static OFBool opt_rejectWithoutImplementationUID = OFFalse;
100 102
101 103
167 { 169 {
168 accepted = OFTrue; 170 accepted = OFTrue;
169 } 171 }
170 } 172 }
171 } 173 }
172 174
173 if (accepted) 175 if (accepted)
174 { 176 {
175 cond = ASC_acceptPresentationContext( 177 cond = ASC_acceptPresentationContext(
176 params, pc.presentationContextID, 178 params, pc.presentationContextID,
177 transferSyntax, acceptedRole); 179 transferSyntax, acceptedRole);
215 * @param acceptedRole SCU/SCP role to accept 217 * @param acceptedRole SCU/SCP role to accept
216 */ 218 */
217 static OFCondition acceptUnknownContextsWithPreferredTransferSyntaxes( 219 static OFCondition acceptUnknownContextsWithPreferredTransferSyntaxes(
218 T_ASC_Parameters * params, 220 T_ASC_Parameters * params,
219 const char* transferSyntaxes[], int transferSyntaxCount, 221 const char* transferSyntaxes[], int transferSyntaxCount,
220 T_ASC_SC_ROLE acceptedRole = ASC_SC_ROLE_DEFAULT) 222 T_ASC_SC_ROLE acceptedRole)
221 { 223 {
222 OFCondition cond = EC_Normal; 224 OFCondition cond = EC_Normal;
223 /* 225 /*
224 ** Accept in the order "least wanted" to "most wanted" transfer 226 ** Accept in the order "least wanted" to "most wanted" transfer
225 ** syntax. Accepting a transfer syntax will override previously 227 ** syntax. Accepting a transfer syntax will override previously
237 239
238 namespace Orthanc 240 namespace Orthanc
239 { 241 {
240 namespace Internals 242 namespace Internals
241 { 243 {
242 /**
243 * EXTRACT OF FILE "dcmdata/libsrc/dcuid.cc" FROM DCMTK 3.6.0
244 * (dcmAllStorageSOPClassUIDs).
245 *
246 * an array of const strings containing all known Storage SOP
247 * Classes that fit into the conventional
248 * PATIENT-STUDY-SERIES-INSTANCE information model,
249 * i.e. everything a Storage SCP might want to store in a PACS.
250 * Special cases such as hanging protocol storage or the Storage
251 * SOP Class are not included in this list.
252 *
253 * THIS LIST CONTAINS ALL STORAGE SOP CLASSES INCLUDING RETIRED
254 * ONES AND IS LARGER THAN 64 ENTRIES.
255 */
256
257 const char* orthancStorageSOPClassUIDs[] =
258 {
259 UID_AmbulatoryECGWaveformStorage,
260 UID_ArterialPulseWaveformStorage,
261 UID_AutorefractionMeasurementsStorage,
262 UID_BasicStructuredDisplayStorage,
263 UID_BasicTextSRStorage,
264 UID_BasicVoiceAudioWaveformStorage,
265 UID_BlendingSoftcopyPresentationStateStorage,
266 #if DCMTK_VERSION_NUMBER >= 361
267 UID_BreastProjectionXRayImageStorageForProcessing,
268 UID_BreastProjectionXRayImageStorageForPresentation,
269 #endif
270 UID_BreastTomosynthesisImageStorage,
271 UID_CardiacElectrophysiologyWaveformStorage,
272 UID_ChestCADSRStorage,
273 UID_ColonCADSRStorage,
274 UID_ColorSoftcopyPresentationStateStorage,
275 UID_ComprehensiveSRStorage,
276 UID_ComputedRadiographyImageStorage,
277 UID_CTImageStorage,
278 UID_DeformableSpatialRegistrationStorage,
279 UID_DigitalIntraOralXRayImageStorageForPresentation,
280 UID_DigitalIntraOralXRayImageStorageForProcessing,
281 UID_DigitalMammographyXRayImageStorageForPresentation,
282 UID_DigitalMammographyXRayImageStorageForProcessing,
283 UID_DigitalXRayImageStorageForPresentation,
284 UID_DigitalXRayImageStorageForProcessing,
285 UID_EncapsulatedCDAStorage,
286 UID_EncapsulatedPDFStorage,
287 UID_EnhancedCTImageStorage,
288 UID_EnhancedMRColorImageStorage,
289 UID_EnhancedMRImageStorage,
290 UID_EnhancedPETImageStorage,
291 UID_EnhancedSRStorage,
292 UID_EnhancedUSVolumeStorage,
293 UID_EnhancedXAImageStorage,
294 UID_EnhancedXRFImageStorage,
295 UID_GeneralAudioWaveformStorage,
296 UID_GeneralECGWaveformStorage,
297 UID_GenericImplantTemplateStorage,
298 UID_GrayscaleSoftcopyPresentationStateStorage,
299 UID_HemodynamicWaveformStorage,
300 UID_ImplantAssemblyTemplateStorage,
301 UID_ImplantationPlanSRDocumentStorage,
302 UID_ImplantTemplateGroupStorage,
303 UID_IntraocularLensCalculationsStorage,
304 UID_KeratometryMeasurementsStorage,
305 UID_KeyObjectSelectionDocumentStorage,
306 UID_LensometryMeasurementsStorage,
307 UID_MacularGridThicknessAndVolumeReportStorage,
308 UID_MammographyCADSRStorage,
309 UID_MRImageStorage,
310 UID_MRSpectroscopyStorage,
311 UID_MultiframeGrayscaleByteSecondaryCaptureImageStorage,
312 UID_MultiframeGrayscaleWordSecondaryCaptureImageStorage,
313 UID_MultiframeSingleBitSecondaryCaptureImageStorage,
314 UID_MultiframeTrueColorSecondaryCaptureImageStorage,
315 UID_NuclearMedicineImageStorage,
316 UID_OphthalmicAxialMeasurementsStorage,
317 UID_OphthalmicPhotography16BitImageStorage,
318 UID_OphthalmicPhotography8BitImageStorage,
319 UID_OphthalmicTomographyImageStorage,
320 UID_OphthalmicVisualFieldStaticPerimetryMeasurementsStorage,
321 UID_PositronEmissionTomographyImageStorage,
322 UID_ProcedureLogStorage,
323 UID_PseudoColorSoftcopyPresentationStateStorage,
324 UID_RawDataStorage,
325 UID_RealWorldValueMappingStorage,
326 UID_RespiratoryWaveformStorage,
327 UID_RTBeamsTreatmentRecordStorage,
328 UID_RTBrachyTreatmentRecordStorage,
329 UID_RTDoseStorage,
330 UID_RTImageStorage,
331 UID_RTIonBeamsTreatmentRecordStorage,
332 UID_RTIonPlanStorage,
333 UID_RTPlanStorage,
334 UID_RTStructureSetStorage,
335 UID_RTTreatmentSummaryRecordStorage,
336 UID_SecondaryCaptureImageStorage,
337 UID_SegmentationStorage,
338 UID_SpatialFiducialsStorage,
339 UID_SpatialRegistrationStorage,
340 UID_SpectaclePrescriptionReportStorage,
341 UID_StereometricRelationshipStorage,
342 UID_SubjectiveRefractionMeasurementsStorage,
343 UID_SurfaceSegmentationStorage,
344 UID_TwelveLeadECGWaveformStorage,
345 UID_UltrasoundImageStorage,
346 UID_UltrasoundMultiframeImageStorage,
347 UID_VideoEndoscopicImageStorage,
348 UID_VideoMicroscopicImageStorage,
349 UID_VideoPhotographicImageStorage,
350 UID_VisualAcuityMeasurementsStorage,
351 UID_VLEndoscopicImageStorage,
352 UID_VLMicroscopicImageStorage,
353 UID_VLPhotographicImageStorage,
354 UID_VLSlideCoordinatesMicroscopicImageStorage,
355 UID_VLWholeSlideMicroscopyImageStorage,
356 UID_XAXRFGrayscaleSoftcopyPresentationStateStorage,
357 UID_XRay3DAngiographicImageStorage,
358 UID_XRay3DCraniofacialImageStorage,
359 UID_XRayAngiographicImageStorage,
360 UID_XRayRadiationDoseSRStorage,
361 UID_XRayRadiofluoroscopicImageStorage,
362 // retired
363 UID_RETIRED_HardcopyColorImageStorage,
364 UID_RETIRED_HardcopyGrayscaleImageStorage,
365 UID_RETIRED_NuclearMedicineImageStorage,
366 UID_RETIRED_StandaloneCurveStorage,
367 UID_RETIRED_StandaloneModalityLUTStorage,
368 UID_RETIRED_StandaloneOverlayStorage,
369 UID_RETIRED_StandalonePETCurveStorage,
370 UID_RETIRED_StandaloneVOILUTStorage,
371 UID_RETIRED_StoredPrintStorage,
372 UID_RETIRED_UltrasoundImageStorage,
373 UID_RETIRED_UltrasoundMultiframeImageStorage,
374 UID_RETIRED_VLImageStorage,
375 #if DCMTK_VERSION_NUMBER >= 364
376 UID_RETIRED_VLMultiframeImageStorage,
377 #else
378 UID_RETIRED_VLMultiFrameImageStorage,
379 #endif
380 UID_RETIRED_XRayAngiographicBiPlaneImageStorage,
381 // draft
382 UID_DRAFT_SRAudioStorage,
383 UID_DRAFT_SRComprehensiveStorage,
384 UID_DRAFT_SRDetailStorage,
385 UID_DRAFT_SRTextStorage,
386 UID_DRAFT_WaveformStorage,
387 UID_DRAFT_RTBeamsDeliveryInstructionStorage,
388 NULL
389 };
390
391 const int orthancStorageSOPClassUIDsCount = (sizeof(orthancStorageSOPClassUIDs) / sizeof(const char*)) - 1;
392
393
394
395 OFCondition AssociationCleanup(T_ASC_Association *assoc) 244 OFCondition AssociationCleanup(T_ASC_Association *assoc)
396 { 245 {
397 OFCondition cond = ASC_dropSCPAssociation(assoc); 246 OFCondition cond = ASC_dropSCPAssociation(assoc);
398 if (cond.bad()) 247 if (cond.bad())
399 { 248 {
586 { 435 {
587 transferSyntaxes.push_back(UID_RLELosslessTransferSyntax); 436 transferSyntaxes.push_back(UID_RLELosslessTransferSyntax);
588 } 437 }
589 438
590 /* accept the Verification SOP Class if presented */ 439 /* accept the Verification SOP Class if presented */
591 cond = ASC_acceptContextsWithPreferredTransferSyntaxes(assoc->params, &knownAbstractSyntaxes[0], knownAbstractSyntaxes.size(), &transferSyntaxes[0], transferSyntaxes.size()); 440 cond = ASC_acceptContextsWithPreferredTransferSyntaxes(
441 assoc->params,
442 &knownAbstractSyntaxes[0], knownAbstractSyntaxes.size(),
443 &transferSyntaxes[0], transferSyntaxes.size());
592 if (cond.bad()) 444 if (cond.bad())
593 { 445 {
594 LOG(INFO) << cond.text(); 446 LOG(INFO) << cond.text();
595 AssociationCleanup(assoc); 447 AssociationCleanup(assoc);
596 return NULL; 448 return NULL;
597 } 449 }
598 450
599 /* the array of Storage SOP Class UIDs comes from dcuid.h */ 451 /* the array of Storage SOP Class UIDs that is defined within "dcmdata/libsrc/dcuid.cc" */
600 cond = ASC_acceptContextsWithPreferredTransferSyntaxes(assoc->params, orthancStorageSOPClassUIDs, orthancStorageSOPClassUIDsCount, &transferSyntaxes[0], transferSyntaxes.size()); 452 size_t count = 0;
453 while (dcmAllStorageSOPClassUIDs[count] != NULL)
454 {
455 count++;
456 }
457
458 #if DCMTK_VERSION_NUMBER >= 362
459 // The global variable "numberOfDcmAllStorageSOPClassUIDs" is
460 // only published if DCMTK >= 3.6.2:
461 // https://bitbucket.org/sjodogne/orthanc/issues/137
462 assert(count == numberOfDcmAllStorageSOPClassUIDs);
463 #endif
464
465 cond = ASC_acceptContextsWithPreferredTransferSyntaxes(
466 assoc->params,
467 dcmAllStorageSOPClassUIDs, count,
468 &transferSyntaxes[0], transferSyntaxes.size());
601 if (cond.bad()) 469 if (cond.bad())
602 { 470 {
603 LOG(INFO) << cond.text(); 471 LOG(INFO) << cond.text();
604 AssociationCleanup(assoc); 472 AssociationCleanup(assoc);
605 return NULL; 473 return NULL;
611 /* 479 /*
612 * Promiscous mode is enabled: Accept everything not known not 480 * Promiscous mode is enabled: Accept everything not known not
613 * to be a storage SOP class. 481 * to be a storage SOP class.
614 **/ 482 **/
615 cond = acceptUnknownContextsWithPreferredTransferSyntaxes( 483 cond = acceptUnknownContextsWithPreferredTransferSyntaxes(
616 assoc->params, &transferSyntaxes[0], transferSyntaxes.size()); 484 assoc->params, &transferSyntaxes[0], transferSyntaxes.size(), ASC_SC_ROLE_DEFAULT);
617 if (cond.bad()) 485 if (cond.bad())
618 { 486 {
619 LOG(INFO) << cond.text(); 487 LOG(INFO) << cond.text();
620 AssociationCleanup(assoc); 488 AssociationCleanup(assoc);
621 return NULL; 489 return NULL;