/*========================================================================= Program: GDCM (Grassroots DICOM). A DICOM library Copyright (c) 2006-2011 Mathieu Malaterre All rights reserved. See Copyright.txt or http://gdcm.sourceforge.net/Copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notice for more information. =========================================================================*/ #include "gdcmServiceClassUser.h" #include "gdcmDataEvent.h" #include "gdcmSimpleSubjectWatcher.h" #include "gdcmPresentationContextGenerator.h" #include "gdcmAttribute.h" #include "gdcmCompositeNetworkFunctions.h" #include "gdcmTransferSyntax.h" #include "gdcmWriter.h" #include "gdcmReader.h" #include "gdcmUIDGenerator.h" #include "gdcmTesting.h" /* * This test actually fails on D. Clunie PACS, but succeed on DicomObject (www.dicomserver.co.uk)... * * $ findscu 184.73.255.26 11112 --call AWSPIXELMEDPUB -P -k 8,52=IMAGE -k 8,16="1.*" -k 20,d * $ gdcmscu --find 184.73.255.26 11112 --call AWSPIXELMEDPUB --patientroot --image -k 8,16="1.*" -k 20,d */ int TestServiceClassUser3(int argc, char *argv[]) { if( argc < 5 ) { std::cerr << argv[0] << " aetitle call portno moveReturnPort remote" << std::endl; return 1; } std::string aetitle = argv[1]; // the ae title of this computer std::string call = argv[2]; // the ae title of the server uint16_t portno = (uint16_t)atoi(argv[3]); // the port of the server uint16_t moveReturnPort = (uint16_t)atoi(argv[4]); // the port over which return cstore scps are done for cmove std::string remote = argv[5]; //the ip address of the remote server (void)moveReturnPort; gdcm::SmartPointer scup = new gdcm::ServiceClassUser; gdcm::ServiceClassUser &scu = *scup; gdcm::SimpleSubjectWatcher w( &scu, "TestServiceClassUser3" ); std::ostringstream error_log; gdcm::Trace::SetErrorStream( error_log ); scu.SetHostname( remote.c_str() ); scu.SetPort( portno ); scu.SetTimeout( 1000 ); scu.SetCalledAETitle( call.c_str() ); scu.SetAETitle( aetitle.c_str() ); if( !scu.InitializeConnection() ) { return 1; } gdcm::PresentationContextGenerator generator; if( !generator.GenerateFromUID( gdcm::UIDs::VerificationSOPClass ) ) { return 1; } // make sure to fail if no pres. contexts: if( scu.StartAssociation() ) { return 1; } scu.SetPresentationContexts( generator.GetPresentationContexts() ); if( !scu.StartAssociation() ) { return 1; } // C-ECHO if( !scu.SendEcho() ) { return 1; } if( !scu.StopAssociation() ) { return 1; } // customize the find query gdcm::DataSet findds; gdcm::Attribute<0x8,0x16> sop ={"1.*"}; findds.Insert( sop.GetAsDataElement() ); gdcm::Attribute<0x20,0xd> uid; findds.Insert( uid.GetAsDataElement() ); gdcm::SmartPointer findquery = gdcm::CompositeNetworkFunctions::ConstructQuery( gdcm::ePatientRootType, gdcm::eImage, findds); // make sure the query is valid findquery->Print( std::cout ); if (!findquery->ValidateQuery(false)) { return 1; } // Generate the PresentationContext array from the query UID: if( !generator.GenerateFromUID( findquery->GetAbstractSyntaxUID() ) ) { return 1; } scu.SetPresentationContexts( generator.GetPresentationContexts() ); if( !scu.StartAssociation() ) { return 1; } // C-FIND std::vector datasets; // This is an error if the previous query succeed: if( scu.SendFind(findquery, datasets) ) { std::cerr << "Could SendFind, this is not possible !" << std::endl; std::cerr << "Error log is:" << std::endl; std::cerr << error_log.str() << std::endl; return 1; } if( !scu.StopAssociation() ) { return 1; } // scu dstor will close the connection (!= association) return 0; }