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: