Mercurial > hg > orthanc
comparison Core/DicomNetworking/Internals/CommandDispatcher.cpp @ 3818:4f78da5613a1 c-get
Add C-GET SCP support
author | Stacy Loesch <stacy.loesch@varian.com> |
---|---|
date | Fri, 27 Mar 2020 10:06:58 -0400 |
parents | eb044cc49d51 |
children | 82e88ff003d7 |
comparison
equal
deleted
inserted
replaced
3815:c81ac6ff232b | 3818:4f78da5613a1 |
---|---|
88 #endif | 88 #endif |
89 | 89 |
90 #include "FindScp.h" | 90 #include "FindScp.h" |
91 #include "StoreScp.h" | 91 #include "StoreScp.h" |
92 #include "MoveScp.h" | 92 #include "MoveScp.h" |
93 #include "GetScp.h" | |
93 #include "../../Compatibility.h" | 94 #include "../../Compatibility.h" |
94 #include "../../Toolbox.h" | 95 #include "../../Toolbox.h" |
95 #include "../../Logging.h" | 96 #include "../../Logging.h" |
96 #include "../../OrthancException.h" | 97 #include "../../OrthancException.h" |
97 | 98 |
273 T_ASC_Association *assoc; | 274 T_ASC_Association *assoc; |
274 OFCondition cond; | 275 OFCondition cond; |
275 OFString sprofile; | 276 OFString sprofile; |
276 OFString temp_str; | 277 OFString temp_str; |
277 | 278 |
279 | |
280 | |
278 cond = ASC_receiveAssociation(net, &assoc, | 281 cond = ASC_receiveAssociation(net, &assoc, |
279 /*opt_maxPDU*/ ASC_DEFAULTMAXPDU, | 282 /*opt_maxPDU*/ ASC_DEFAULTMAXPDU, |
280 NULL, NULL, | 283 NULL, NULL, |
281 /*opt_secureConnection*/ OFFalse, | 284 /*opt_secureConnection*/ OFFalse, |
282 DUL_NOBLOCK, 1); | 285 DUL_NOBLOCK, 1); |
369 if (server.HasMoveRequestHandlerFactory()) | 372 if (server.HasMoveRequestHandlerFactory()) |
370 { | 373 { |
371 knownAbstractSyntaxes.push_back(UID_MOVEStudyRootQueryRetrieveInformationModel); | 374 knownAbstractSyntaxes.push_back(UID_MOVEStudyRootQueryRetrieveInformationModel); |
372 knownAbstractSyntaxes.push_back(UID_MOVEPatientRootQueryRetrieveInformationModel); | 375 knownAbstractSyntaxes.push_back(UID_MOVEPatientRootQueryRetrieveInformationModel); |
373 } | 376 } |
377 | |
378 // For C-GET | |
379 if (server.HasGetRequestHandlerFactory()) | |
380 { | |
381 knownAbstractSyntaxes.push_back(UID_GETStudyRootQueryRetrieveInformationModel); | |
382 knownAbstractSyntaxes.push_back(UID_GETPatientRootQueryRetrieveInformationModel); | |
383 } | |
384 | |
374 | 385 |
375 cond = ASC_acceptContextsWithPreferredTransferSyntaxes( | 386 cond = ASC_acceptContextsWithPreferredTransferSyntaxes( |
376 assoc->params, | 387 assoc->params, |
377 &knownAbstractSyntaxes[0], knownAbstractSyntaxes.size(), | 388 &knownAbstractSyntaxes[0], knownAbstractSyntaxes.size(), |
378 &genericTransferSyntaxes[0], genericTransferSyntaxes.size()); | 389 &genericTransferSyntaxes[0], genericTransferSyntaxes.size()); |
509 // only published if DCMTK >= 3.6.2: | 520 // only published if DCMTK >= 3.6.2: |
510 // https://bitbucket.org/sjodogne/orthanc/issues/137 | 521 // https://bitbucket.org/sjodogne/orthanc/issues/137 |
511 assert(static_cast<int>(count) == numberOfDcmAllStorageSOPClassUIDs); | 522 assert(static_cast<int>(count) == numberOfDcmAllStorageSOPClassUIDs); |
512 #endif | 523 #endif |
513 | 524 |
525 if (!server.HasGetRequestHandlerFactory()) // dcmqrsrv.cc line 828 | |
526 { | |
514 cond = ASC_acceptContextsWithPreferredTransferSyntaxes( | 527 cond = ASC_acceptContextsWithPreferredTransferSyntaxes( |
515 assoc->params, | 528 assoc->params, |
516 dcmAllStorageSOPClassUIDs, count, | 529 dcmAllStorageSOPClassUIDs, count, |
517 &storageTransferSyntaxes[0], storageTransferSyntaxes.size()); | 530 &storageTransferSyntaxes[0], storageTransferSyntaxes.size()); |
518 if (cond.bad()) | 531 if (cond.bad()) |
519 { | 532 { |
520 LOG(INFO) << cond.text(); | 533 LOG(INFO) << cond.text(); |
521 AssociationCleanup(assoc); | 534 AssociationCleanup(assoc); |
522 return NULL; | 535 return NULL; |
523 } | 536 } |
537 } | |
538 else // see dcmqrsrv.cc lines 839 - 876 | |
539 { | |
540 /* accept storage syntaxes with proposed role */ | |
541 T_ASC_PresentationContext pc; | |
542 T_ASC_SC_ROLE role; | |
543 int npc = ASC_countPresentationContexts(assoc->params); | |
544 for (int i = 0; i < npc; i++) | |
545 { | |
546 ASC_getPresentationContext(assoc->params, i, &pc); | |
547 if (dcmIsaStorageSOPClassUID(pc.abstractSyntax)) | |
548 { | |
549 /* | |
550 ** We are prepared to accept whatever role the caller proposes. | |
551 ** Normally we can be the SCP of the Storage Service Class. | |
552 ** When processing the C-GET operation we can be the SCU of the Storage Service Class. | |
553 */ | |
554 role = pc.proposedRole; | |
555 | |
556 /* | |
557 ** Accept in the order "least wanted" to "most wanted" transfer | |
558 ** syntax. Accepting a transfer syntax will override previously | |
559 ** accepted transfer syntaxes. | |
560 */ | |
561 for (int k = (int) storageTransferSyntaxes.size() - 1; k >= 0; k--) | |
562 { | |
563 for (int j = 0; j < (int)pc.transferSyntaxCount; j++) | |
564 { | |
565 /* if the transfer syntax was proposed then we can accept it | |
566 * appears in our supported list of transfer syntaxes | |
567 */ | |
568 if (strcmp(pc.proposedTransferSyntaxes[j], storageTransferSyntaxes[k]) == 0) | |
569 { | |
570 cond = ASC_acceptPresentationContext( | |
571 assoc->params, pc.presentationContextID, storageTransferSyntaxes[k], role); | |
572 if (cond.bad()) | |
573 { | |
574 LOG(INFO) << cond.text(); | |
575 AssociationCleanup(assoc); | |
576 return NULL; | |
577 } | |
578 } | |
579 } | |
580 } | |
581 } | |
582 } /* for */ | |
583 | |
584 } | |
585 | |
524 | 586 |
525 if (!server.HasApplicationEntityFilter() || | 587 if (!server.HasApplicationEntityFilter() || |
526 server.GetApplicationEntityFilter().IsUnknownSopClassAccepted(remoteIp, remoteAet, calledAet)) | 588 server.GetApplicationEntityFilter().IsUnknownSopClassAccepted(remoteIp, remoteAet, calledAet)) |
527 { | 589 { |
528 /* | 590 /* |
731 | 793 |
732 case DIMSE_C_MOVE_RQ: | 794 case DIMSE_C_MOVE_RQ: |
733 request = DicomRequestType_Move; | 795 request = DicomRequestType_Move; |
734 supported = true; | 796 supported = true; |
735 break; | 797 break; |
798 | |
799 case DIMSE_C_GET_RQ: | |
800 request = DicomRequestType_Get; | |
801 supported = true; | |
802 break; | |
736 | 803 |
737 case DIMSE_C_FIND_RQ: | 804 case DIMSE_C_FIND_RQ: |
738 request = DicomRequestType_Find; | 805 request = DicomRequestType_Find; |
739 supported = true; | 806 supported = true; |
740 break; | 807 break; |
802 (server_.GetMoveRequestHandlerFactory().ConstructMoveRequestHandler()); | 869 (server_.GetMoveRequestHandlerFactory().ConstructMoveRequestHandler()); |
803 | 870 |
804 if (handler.get() != NULL) | 871 if (handler.get() != NULL) |
805 { | 872 { |
806 cond = Internals::moveScp(assoc_, &msg, presID, *handler, remoteIp_, remoteAet_, calledAet_, associationTimeout_); | 873 cond = Internals::moveScp(assoc_, &msg, presID, *handler, remoteIp_, remoteAet_, calledAet_, associationTimeout_); |
874 } | |
875 } | |
876 break; | |
877 | |
878 case DicomRequestType_Get: | |
879 if (server_.HasGetRequestHandlerFactory()) // Should always be true | |
880 { | |
881 std::auto_ptr<IGetRequestHandler> handler | |
882 (server_.GetGetRequestHandlerFactory().ConstructGetRequestHandler()); | |
883 | |
884 if (handler.get() != NULL) | |
885 { | |
886 cond = Internals::getScp(assoc_, &msg, presID, *handler, remoteIp_, remoteAet_, calledAet_); | |
807 } | 887 } |
808 } | 888 } |
809 break; | 889 break; |
810 | 890 |
811 case DicomRequestType_Find: | 891 case DicomRequestType_Find: |