00001 /* 00002 * 00003 * Copyright (C) 2009-2010, OFFIS e.V. 00004 * All rights reserved. See COPYRIGHT file for details. 00005 * 00006 * This software and supporting documentation were developed by 00007 * 00008 * OFFIS e.V. 00009 * R&D Division Health 00010 * Escherweg 2 00011 * D-26121 Oldenburg, Germany 00012 * 00013 * 00014 * Module: dcmnet 00015 * 00016 * Author: Michael Onken 00017 * 00018 * Purpose: General SCP class that can be used to implement derived SCP 00019 * applications. 00020 * 00021 * Last Update: $Author: joergr $ 00022 * Update Date: $Date: 2010-10-14 13:17:22 $ 00023 * CVS/RCS Revision: $Revision: 1.9 $ 00024 * Status: $State: Exp $ 00025 * 00026 * CVS/RCS Log at end of file 00027 * 00028 */ 00029 00030 #ifndef SCP_H 00031 #define SCP_H 00032 00033 #include "dcmtk/config/osconfig.h" /* make sure OS specific configuration is included first */ 00034 00035 #include "dcmtk/oflog/oflog.h" 00036 #include "dcmtk/dcmdata/dctk.h" /* Covers most common dcmdata classes */ 00037 #include "dcmtk/dcmnet/dimse.h" /* DIMSE network layer */ 00038 #include "dcmtk/dcmnet/dcasccff.h" /* For reading a association config file */ 00039 #include "dcmtk/dcmnet/dcasccfg.h" /* For holding association cfg file infos */ 00040 00041 #ifdef WITH_ZLIB 00042 #include <zlib.h> /* for zlibVersion() */ 00043 #endif 00044 00045 #ifdef WITH_OPENSSL 00046 #include "dcmtk/dcmtls/tlstrans.h" 00047 #include "dcmtk/dcmtls/tlslayer.h" 00048 #endif 00049 00050 00053 struct DcmProcessSlotType 00054 { 00056 DIC_NODENAME peerName; 00058 DIC_AE callingAETitle; 00060 DIC_AE calledAETitle; 00062 int processId; 00064 time_t startTime; 00066 OFBool hasStorageAbility; 00067 }; 00068 00072 enum DcmSCPActionType 00073 { 00075 DCMSCP_ACTION_UNDEFINED, 00077 DCMSCP_ACTION_REFUSE_ASSOCIATION 00078 }; 00079 00082 enum DcmRefuseReasonType 00083 { 00085 DCMSCP_TOO_MANY_ASSOCIATIONS, 00087 DCMSCP_CANNOT_FORK, 00089 DCMSCP_BAD_APPLICATION_CONTEXT_NAME, 00091 DCMSCP_BAD_APPLICATION_ENTITY_SERVICE, 00093 DCMSCP_FORCED, 00095 DCMSCP_NO_IMPLEMENTATION_CLASS_UID, 00097 DCMSCP_NO_PRESENTATION_CONTEXTS, 00099 DCMSCP_INTERNAL_ERROR 00100 }; 00101 00106 struct DcmPresentationContextInfo 00107 { 00109 Uint8 presentationContextID; 00111 OFString abstractSyntax; 00113 Uint8 proposedSCRole; 00115 Uint8 acceptedSCRole; 00117 OFString acceptedTransferSyntax; 00118 // Fields "reserved" and "result" not included from DUL_PRESENTATIONCONTEXT 00119 }; 00120 00121 00130 class DcmSCP 00131 { 00132 00133 public: 00134 00137 DcmSCP(); 00138 00141 virtual ~DcmSCP(); 00142 00143 #ifdef _WIN32 00144 00148 OFCondition markAsForkedChild(); 00149 #endif 00150 00155 virtual OFCondition listen(); 00156 00157 00158 /* ************************************************************* */ 00159 /* Set methods for configuring SCP behaviour */ 00160 /* ************************************************************* */ 00161 00172 virtual OFCondition addPresentationContext(const OFString &abstractSyntax, 00173 const OFList<OFString> xferSyntaxes, 00174 const T_ASC_SC_ROLE role = ASC_SC_ROLE_DEFAULT, 00175 const OFString &profile = "DEFAULT"); 00176 00181 void setPort(const Uint16 port); 00182 00188 void setAETitle(const OFString &aetitle); 00189 00196 void setRespondWithCalledAETitle(const OFBool useCalled); 00197 00203 virtual OFCondition loadAssociationCfgFile(const OFString &assocFile); 00204 00212 virtual OFCondition setAndCheckAssociationProfile(const OFString &profileName); 00213 00219 void forceAssociationRefuse(const OFBool doRefuse); 00220 00225 void setMaxReceivePDULength(const Uint32 maxRecPDU); 00226 00238 OFCondition enableMultiProcessMode(int argc = 0, 00239 char *argv[] = NULL); 00240 00245 void setMaxAssociations(const Uint16 maxAssocs); 00246 00256 void setDIMSEBlockingMode(const T_DIMSE_BlockingMode blockingMode); 00257 00262 void setDIMSETimeout(const Uint32 dimseTimeout); 00263 00267 void setACSETimeout(const Uint32 acseTimeout); 00268 00273 void setVerbosePCMode(const OFBool mode); 00274 00275 /* Get methods for SCP settings */ 00276 00280 Uint16 getPort() const; 00281 00286 const OFString &getAETitle() const; 00287 00292 OFBool getRespondWithCalledAETitle() const; 00293 00297 OFBool getRefuseAssociation() const; 00298 00302 Uint32 getMaxReceivePDULength() const; 00303 00307 OFBool getSingleProcess() const; 00308 00316 Uint16 getMaxAssociations() const; 00317 00321 T_DIMSE_BlockingMode getDIMSEBlockingMode() const; 00322 00326 Uint32 getDIMSETimeout() const; 00327 00331 Uint32 getACSETimeout() const; 00332 00338 OFBool getVerbosePCMode() const; 00339 00340 /* Get information about current association */ 00341 00347 OFBool isConnected() const; 00348 00353 Uint16 numAssociations() const; 00354 00359 OFString getCalledAETitle() const; 00360 00364 OFString getPeerAETitle() const; 00365 00369 OFString getPeerIP() const; 00370 00375 Uint32 getPeerMaxPDULength() const; 00376 00377 00378 protected: 00379 00380 /* *********************************************************************** 00381 * Functions particularly interesting for overwriting in derived classes 00382 * *********************************************************************** 00383 */ 00384 00392 virtual OFCondition handleIncomingCommand(T_DIMSE_Message *incomingMsg, 00393 const DcmPresentationContextInfo &presContextInfo); 00394 00399 virtual void notifyAssociationRequest(const T_ASC_Parameters ¶ms, 00400 DcmSCPActionType &desiredAction); 00401 00405 virtual void notifyAssociationAcknowledge(); 00406 00410 virtual void notifyReleaseRequest(); 00411 00415 virtual void notifyAbortRequest(); 00416 00420 virtual void notifyAssociationTermination(); 00421 00426 virtual void notifyDIMSEError(const OFCondition &cond); 00427 00433 virtual OFBool stopAfterCurrentAssociation(); 00434 00442 virtual OFCondition sendSTOREResponse(T_ASC_PresentationContextID presID, 00443 T_DIMSE_C_StoreRQ &reqMessage, 00444 T_DIMSE_C_StoreRSP &rspMessage, 00445 DcmDataset *statusDetail); 00446 00454 virtual OFCondition handleECHORequest(T_DIMSE_C_EchoRQ &reqMessage, 00455 T_ASC_PresentationContextID presID); 00456 00467 virtual OFCondition handleEVENTREPORTRequest(T_DIMSE_N_EventReportRQ &reqMessage, 00468 T_ASC_PresentationContextID presID, 00469 DcmDataset *&reqDataset, 00470 Uint16 &eventTypeID); 00471 00482 virtual Uint16 checkEVENTREPORTRequest(T_DIMSE_N_EventReportRQ &reqMessage, 00483 DcmDataset *reqDataset); 00484 00495 virtual OFBool calledAETitleAccepted(const OFString &callingAE, 00496 const OFString &calledAE); 00497 00498 00499 /* ********************************************************************* 00500 * Further functions and member variables 00501 * ********************************************************************* 00502 */ 00503 00512 virtual OFCondition waitForAssociation(T_ASC_Network *network); 00513 00519 virtual void cleanChildren(); 00520 00528 virtual OFCondition negotiateAssociation(); 00529 00534 virtual void addProcessToTable(int pid); 00535 00542 virtual void removeProcessFromTable(int pid); 00543 00548 virtual void refuseAssociation(DcmRefuseReasonType reason); 00549 00553 virtual void handleAssociation(); 00554 00570 OFCondition sendDIMSEMessage(const T_ASC_PresentationContextID presID, 00571 T_DIMSE_Message *msg, 00572 DcmDataset *dataObject, 00573 DIMSE_ProgressCallback callback, 00574 void *callbackContext, 00575 DcmDataset **commandSet = NULL); 00576 00598 OFCondition receiveDIMSECommand(T_ASC_PresentationContextID *presID, 00599 T_DIMSE_Message *msg, 00600 DcmDataset **statusDetail, 00601 DcmDataset **commandSet = NULL, 00602 const Uint32 timeout = 0); 00603 00617 OFCondition receiveDIMSEDataset(T_ASC_PresentationContextID *presID, 00618 DcmDataset **dataObject, 00619 DIMSE_ProgressCallback callback, 00620 void *callbackContext); 00621 00622 private: 00623 00627 DcmSCP(const DcmSCP &src); 00628 00633 DcmSCP &operator=(const DcmSCP &src); 00634 00636 T_ASC_Association *m_assoc; 00637 00640 DcmAssociationConfiguration *m_assocConfig; 00641 00644 OFString m_assocCfgProfileName; 00645 00647 Uint16 m_port; 00648 00653 OFString m_aetitle; 00654 00657 OFBool m_refuseAssociation; 00658 00661 Uint32 m_maxReceivePDULength; 00662 00671 OFBool m_singleProcess; 00672 00675 OFBool m_forkedChild; 00676 00677 #ifdef _WIN32 00679 int m_cmd_argc; 00680 00682 char **m_cmd_argv; 00683 #endif 00684 00688 Uint16 m_maxAssociations; 00689 00695 T_DIMSE_BlockingMode m_blockMode; 00696 00699 Uint32 m_dimseTimeout; 00700 00703 Uint32 m_acseTimeout; 00704 00707 OFBool m_verbosePCMode; 00708 00711 OFList<DcmProcessSlotType *> m_processTable; 00712 00715 OFBool m_respondWithCalledAETitle; 00716 00719 void dropAndDestroyAssociation(); 00720 00721 }; 00722 00723 #endif // SCP_H 00724 00725 00726 /* 00727 * CVS/RCS Log: 00728 * $Log: scp.h,v $ 00729 * Revision 1.9 2010-10-14 13:17:22 joergr 00730 * Updated copyright header. Added reference to COPYRIGHT file. 00731 * 00732 * Revision 1.8 2010-10-07 12:54:07 joergr 00733 * Fixed minor Doxygen API documentation issues (added backslash in order to 00734 * avoid that the short description ends at the first period). 00735 * 00736 * Revision 1.7 2010-06-22 15:44:55 joergr 00737 * Added support for handling N-EVENT-REPORT request. 00738 * Added support for stopping after the current association is finished. 00739 * Further code cleanup. Renamed some methods, variables, types and so on. 00740 * 00741 * Revision 1.6 2010-06-18 14:50:33 joergr 00742 * Added support for the SCP/SCU role selection negotiation. 00743 * 00744 * Revision 1.5 2010-06-17 17:06:30 joergr 00745 * Aligned SCP class with existing SCU class. Some further code cleanups. 00746 * Changed default profile from "Default" to "DEFAULT". Revised documentation. 00747 * 00748 * Revision 1.4 2010-04-29 16:14:59 onken 00749 * Added function for responding to storage requests to SCP class. 00750 * 00751 * Revision 1.3 2009-12-21 17:00:32 onken 00752 * Fixed API documentation to keep doxygen quiet. 00753 * 00754 * Revision 1.1 2009-12-17 09:02:43 onken 00755 * Added base classes for SCU and SCP implementations. 00756 * 00757 */