#ifndef _DCM_MOVE_H_ #define _DCM_MOVE_H_ #include "internal/dcm_global.h" #include "internal/dcm_type.h" #include "internal/dcmtk_headers.h" // C-Move is a little annoying, since C-Move scu is also a C-Store scp: // once upon the C-Move request is sent, C-Move scp will send data to // CMove scu through C-Store in which C_Move scp will act as a C-Store scu // and C-Move scu will act as a C-Store scp. // So, you need to provide two callback subclass to implement custom operation // related the progrss, status and all the like. // the subOpCallback is implemented internally, do not worry class _DCM_EXPORT dcm_cmove_callback { public: dcm_cmove_callback(); virtual ~dcm_cmove_callback(); virtual void callback(T_DIMSE_C_MoveRQ *request, int responseCount, T_DIMSE_C_MoveRSP *response) = 0; virtual void setAssoc(T_ASC_Association * assoc); virtual void setPresetnationContextID(const T_ASC_PresentationContextID& presId); virtual void setCancelAfterNReponse(int n = -1); protected: T_ASC_Association * assoc_; T_ASC_PresentationContextID presId_; int cancelAfterNResponse_; private: ////dcm_cmove_callback(const dcm_cmove_callback& other); ////dcm_cmove_callback& operator=(const dcm_cmove_callback& other); }; class _DCM_EXPORT dcm_cmove_callback_default : public dcm_cmove_callback { public: dcm_cmove_callback_default(); virtual ~dcm_cmove_callback_default(); virtual void callback(T_DIMSE_C_MoveRQ *request, int responseCount, T_DIMSE_C_MoveRSP *response); }; // callback funciton in dcmtk is not flexible if you want access to assoc and more underlayer stuff in callback implementation // so I will put as much as infos in this class, or you can inherit for more info to access // now the infos conatins: // char * imageFileName; // DcmFileFormat *dcmff; // T_ASC_Association *assoc; class _DCM_EXPORT dcm_cmove_storescp_callback { public: dcm_cmove_storescp_callback(); virtual ~dcm_cmove_storescp_callback(); virtual void callback(T_DIMSE_StoreProgress *progress, T_DIMSE_C_StoreRQ *request, char *imageFileName, DcmDataset **imageDataSet, T_DIMSE_C_StoreRSP *response, DcmDataset **statusDetail) = 0; virtual void setImageFileName(char * imageFileName); virtual void setDcmFileFormat(DcmFileFormat * dcmff); virtual void setAssoc(T_ASC_Association * assoc); protected: char * imageFile_; DcmFileFormat * dcmff_; T_ASC_Association * assoc_; private: ////dcm_cmove_storescp_callback(const dcm_cmove_storescp_callback& other); ////dcm_cmove_storescp_callback& operator=(const dcm_cmove_storescp_callback& other); }; // a default implemetation of dcm_cmove_storescp_callback // which save files in a specified directory, as a different // way to handle image, such as store in database, implement it yourself class _DCM_EXPORT dcm_cmove_storescp_callback_default : public dcm_cmove_storescp_callback { public: dcm_cmove_storescp_callback_default(std::string outputDirectory); virtual ~dcm_cmove_storescp_callback_default(); virtual void callback(T_DIMSE_StoreProgress *progress, T_DIMSE_C_StoreRQ *request, char *imageFileName, DcmDataset **imageDataSet, T_DIMSE_C_StoreRSP *response, DcmDataset **statusDetail); private: bool abortDuringStore_; bool abortAfterStore_; unsigned long sleepDuring_; bool bitPreserving_; bool ignore_; std::string outputDirectory_; E_TransferSyntax writeTransferSyntax_; E_EncodingType sequenceType_; E_GrpLenEncoding groupLength_; E_PaddingEncoding paddingType_; unsigned long filepad_; unsigned long itempad_; bool useMetaheader_; bool correctUIDPadding_; }; typedef enum { QMPatientRoot = 0, QMStudyRoot = 1, QMPatientStudyOnly = 2 } QueryModel; class _DCM_EXPORT dcm_cmove { public: dcm_cmove(const char *peerIp, unsigned long peerPort, const char *peerTitle, unsigned long ourPort, const char *ourTile); ~dcm_cmove(); void set_sleep_after(unsigned long); void set_sleep_during(unsigned long); void set_dimse_timeout(int timeout); void set_acse_timeout(int timeout); void set_cmove_callback(dcm_cmove_callback * callback); void set_cmove_scp_callback(dcm_cmove_storescp_callback * callback); int move_by_patient_id(std::string patient_id); int move_by_study_uid(std::string study_uid); int move_by_series_uid(std::string study_uid, std::string series_uid); int move_by_image_uid(std::string study_uid, std::string series_uid, std::string image_uid); OFCondition acceptSubAssoc(T_ASC_Network *aNet, T_ASC_Association **assoc); OFCondition subOpSCP(T_ASC_Association **subAssoc); private: void addOverrideKey(const char *s); OFCondition addPresentationContext(T_ASC_Parameters * params, T_ASC_PresentationContextID pid, const char * abstractSyntax); void substituteOverrideKeys(DcmDataset *dset); OFCondition echoSCP(T_ASC_Association *assoc, T_DIMSE_Message * msg, T_ASC_PresentationContextID presID); OFCondition storeSCP(T_ASC_Association *assoc, T_DIMSE_Message * msg, T_ASC_PresentationContextID presID); OFCondition moveSCU(T_ASC_Association * assoc, const char * fname); OFCondition cmove(T_ASC_Association *assoc, const char *fname); int docmove(); private: const char * peerIp_; unsigned long peerPort_; const char * peerTitle_; unsigned long ourPort_; char * ourTitle_; dcm_cmove_callback * cmove_callback; dcm_cmove_storescp_callback * storescp_callback; private: unsigned long sleepAfter; unsigned long sleepDuring; unsigned long maxPDU; bool useMetaheader; bool acceptAllXfer; E_TransferSyntax in_networkTransferSyntax; E_TransferSyntax out_networkTransferSyntax; bool bitPreserving; bool ignore; unsigned long repeatCount; bool abortAssociation; QueryModel queryModel; T_DIMSE_BlockingMode blockMode; int dimse_timeout; int acse_timeout; bool ignorePendingDatasets; T_ASC_Network * net; DcmDataset * overrideKeys; }; #endif // !_DCM_MOVE_H_