ctkDcmSCU.h 52 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048
  1. /*
  2. *
  3. * Copyright (C) 2008-2012, OFFIS e.V.
  4. * All rights reserved. See COPYRIGHT file for details.
  5. *
  6. * This software and supporting documentation were developed by
  7. *
  8. * OFFIS e.V.
  9. * R&D Division Health
  10. * Escherweg 2
  11. * D-26121 Oldenburg, Germany
  12. *
  13. *
  14. * Module: dcmnet
  15. *
  16. * Author: Michael Onken
  17. *
  18. * Purpose: Base class for Service Class Users (SCUs)
  19. *
  20. */
  21. #include "dcmtk/config/osconfig.h" /* make sure OS specific configuration is included first */
  22. #if ! ( PACKAGE_VERSION_NUMBER == 360 )
  23. #include "dcmtk/dcmnet/scu.h"
  24. #else
  25. #ifndef SCU_H
  26. #define SCU_H
  27. #include "dcmtk/dcmdata/dctk.h" /* Covers most common dcmdata classes */
  28. #include "dcmtk/dcmnet/dcompat.h"
  29. #include "dcmtk/dcmnet/dimse.h" /* DIMSE network layer */
  30. #include "dcmtk/dcmnet/dcasccff.h" /* For reading a association config file */
  31. #include "dcmtk/dcmnet/dcasccfg.h" /* For holding association config file infos */
  32. #include "dcmtk/ofstd/oflist.h"
  33. /* Remove below if changing to more current DCMTK */
  34. const unsigned short ECC_AlreadyConnected = 0x901;
  35. const unsigned short ECC_NoAcceptablePresentationContexts = 0x902;
  36. const unsigned short ECC_NoPresentationContextsDefined = 0x903;
  37. const unsigned short ECC_InvalidSOPInstanceUID = 0x904;
  38. const unsigned short ECC_InvalidSOPClassUID = 0x905;
  39. const unsigned short ECC_UnknownTransferSyntax = 0x906;
  40. const OFConditionConst ECE_NoAcceptablePresentationContexts( OFM_dcmnet, ECC_NoAcceptablePresentationContexts, OF_error, "No Acceptable Presentation Contexts");
  41. const OFConditionConst ECE_NoPresentationContextsDefined( OFM_dcmnet, ECC_NoPresentationContextsDefined, OF_error, "No Presentation Contexts defined");
  42. const OFConditionConst ECE_InvalidSOPClassUID( OFM_dcmnet, ECC_InvalidSOPClassUID, OF_error, "Invalid SOP Class UID");
  43. const OFConditionConst ECE_InvalidSOPInstanceUID( OFM_dcmnet, ECC_InvalidSOPInstanceUID, OF_error, "Invalid SOP Instance UID");
  44. const OFConditionConst ECE_UnknownTransferSyntax( OFM_dcmnet, ECC_UnknownTransferSyntax, OF_error, "Unknown Transfer Syntax");
  45. const OFConditionConst ECE_AlreadyConnected( OFM_dcmnet, ECC_AlreadyConnected, OF_error, "Already Connected");
  46. const OFCondition NET_EC_AlreadyConnected( ECE_AlreadyConnected);
  47. const OFCondition NET_EC_NoAcceptablePresentationContexts( ECE_NoAcceptablePresentationContexts);
  48. const OFCondition NET_EC_NoPresentationContextsDefined( ECE_NoPresentationContextsDefined);
  49. const OFCondition NET_EC_UnknownTransferSyntax( ECE_UnknownTransferSyntax);
  50. const OFCondition NET_EC_InvalidSOPClassUID( ECE_InvalidSOPClassUID);
  51. const OFCondition NET_EC_InvalidSOPInstanceUID( ECE_InvalidSOPInstanceUID);
  52. /* Remove above if changing to more current DCMTK */
  53. /** Different types of closing an association
  54. */
  55. enum DcmCloseAssociationType
  56. {
  57. /// Release the current association
  58. DCMSCU_RELEASE_ASSOCIATION,
  59. /// Abort the current association
  60. DCMSCU_ABORT_ASSOCIATION,
  61. /// Peer requested release (Aborting)
  62. DCMSCU_PEER_REQUESTED_RELEASE,
  63. /// Peer aborted the association
  64. DCMSCU_PEER_ABORTED_ASSOCIATION
  65. };
  66. /** Storage mode used for DICOM objects received via C-STORE
  67. */
  68. enum DcmStorageMode
  69. {
  70. /// Ignore any objects received via C-STORE
  71. DCMSCU_STORAGE_IGNORE,
  72. /// Try to store the objects to disk
  73. DCMSCU_STORAGE_DISK,
  74. /// Try to store to disk in bit-preserving mode. This is especially useful
  75. /// for huge files that cannot fully be received in memory since the
  76. /// data is directly streamed to disk. Originally, this was introduced for
  77. /// DICOM signatures which can be kept valid this way.
  78. DCMSCU_STORAGE_BIT_PRESERVING
  79. };
  80. /** Base class for C-FIND, C-MOVE and C-GET responses
  81. */
  82. class QRResponse
  83. {
  84. public:
  85. /** Standard constructor.
  86. */
  87. QRResponse() :
  88. m_messageIDRespondedTo(0),
  89. m_affectedSOPClassUID(),
  90. m_dataset(NULL),
  91. m_status(0),
  92. m_statusDetail(NULL) {}
  93. /** Destructor, cleans up internal memory (dataset if present).
  94. */
  95. virtual ~QRResponse() { delete m_dataset; delete m_statusDetail; }
  96. /// The message ID responded to (mandatory response field,
  97. /// equals message ID from request)
  98. Uint16 m_messageIDRespondedTo;
  99. /// Optional response field according to part 7 of the standard
  100. /// If present, equals SOP Class UID from request.
  101. OFString m_affectedSOPClassUID;
  102. /// Conditional response field (NULL if absent). From the standard (2009,
  103. /// part 4, C.4.2.1.4.2), for C-MOVE: In Q/R if no C-STORE sub-operation
  104. /// failed, Failed SOP Instance UID List (0008,0058) is absent and
  105. /// therefore no Data Set shall be sent in the C-MOVE response. Further
  106. /// rules: Statuses of Canceled, Failure, Refused, or Warning shall
  107. /// contain the Failed SOP Instance UID List Attribute; status of
  108. /// Pending shall not.
  109. DcmDataset *m_dataset;
  110. /// The returned DIMSE status (mandatory Response Field)
  111. Uint16 m_status;
  112. /// Status detail (NULL if absent). For some DIMSE return status codes,
  113. /// an additional dataset is sent which gives further information (i.e.
  114. /// in case of warnings or errors).
  115. DcmDataset *m_statusDetail;
  116. private:
  117. /** Private undefined copy constructor.
  118. * @param other The find response to copy from
  119. */
  120. QRResponse(const QRResponse &other);
  121. /** Private undefined assignment operator.
  122. * @param other The find response that should be assigned from
  123. */
  124. QRResponse &operator=(const QRResponse &other);
  125. };
  126. /// Base class representing for single C-GET or C-MOVE response
  127. class RetrieveResponse : public QRResponse
  128. {
  129. public:
  130. /** Standard constructor
  131. */
  132. RetrieveResponse() :
  133. m_numberOfRemainingSubops(0),
  134. m_numberOfCompletedSubops(0),
  135. m_numberOfFailedSubops(0),
  136. m_numberOfWarningSubops(0) {}
  137. /** Destructor, cleans up internal memory
  138. */
  139. virtual ~RetrieveResponse() {}
  140. /** Prints response to INFO log level.
  141. */
  142. void print();
  143. /// Number of remaining sub operations (in Q/R: C-STORE calls).
  144. /// For Q/R MOVE and GET, for status of pending this field shall be filled.
  145. /// For others, the field may be filled.
  146. Uint16 m_numberOfRemainingSubops;
  147. /// Number of successfully completed sub operations (in Q/R: C-STORE calls).
  148. /// For Q/R MOVE and GET, for status of pending this field shall be filled.
  149. /// For others, the field may be filled.
  150. Uint16 m_numberOfCompletedSubops;
  151. /// Number of failed sub operations (in Q/R: C-STORE calls).
  152. /// For Q/R MOVE and GET, for status of pending this field shall be filled.
  153. /// For others, the field may be filled.
  154. Uint16 m_numberOfFailedSubops;
  155. /// Number generated warnings generated by sub operations (in Q/R: C-STORE calls).
  156. /// For Q/R MOVE and GET, for status of pending this field shall be filled.
  157. /// For others, the field may be filled.
  158. Uint16 m_numberOfWarningSubops;
  159. private:
  160. /** Private undefined copy constructor
  161. * @param other Response to copy from
  162. */
  163. RetrieveResponse(const RetrieveResponse &other);
  164. /** Private undefined assignment operator
  165. * @param other Response that should be assigned from
  166. */
  167. RetrieveResponse &operator=(const RetrieveResponse &other);
  168. };
  169. /** Base class for implementing DICOM Service Class User functionality. The class offers
  170. * support for negotiating associations and sending and receiving arbitrary DIMSE messages
  171. * on that connection. DcmSCU has built-in C-ECHO support so derived classes do not have to
  172. * implement that capability on their own.
  173. * @warning This class is EXPERIMENTAL. Be careful to use it in production environment.
  174. */
  175. class DcmSCU
  176. {
  177. public:
  178. /** Constructor, just initializes internal class members
  179. */
  180. DcmSCU();
  181. /** Virtual destructor
  182. */
  183. virtual ~DcmSCU();
  184. /** Add presentation context to be used for association negotiation
  185. * @param abstractSyntax [in] Abstract syntax name in UID format
  186. * @param xferSyntaxes [in] List of transfer syntaxes to be added for the given abstract
  187. * syntax
  188. * @param role [in] The role to be negotiated
  189. * @return EC_Normal if adding was successful, otherwise error code
  190. */
  191. OFCondition addPresentationContext(const OFString &abstractSyntax,
  192. const OFList<OFString> &xferSyntaxes,
  193. const T_ASC_SC_ROLE role = ASC_SC_ROLE_DEFAULT);
  194. /** Initialize network, i.e.\ prepare for association negotiation. If the SCU is already
  195. * connected, the call will not be successful and the old connection keeps open.
  196. * @return EC_Normal if initialization was successful, otherwise error code.
  197. * NET_EC_AlreadyConnected if SCU is already connected.
  198. */
  199. virtual OFCondition initNetwork();
  200. /** Negotiate association by using presentation contexts and parameters as defined by
  201. * earlier function calls. If negotiation fails, there is no need to close the association
  202. * or to do anything else with this class.
  203. * @return EC_Normal if negotiation was successful, otherwise error code.
  204. * NET_EC_AlreadyConnected if SCU is already connected.
  205. */
  206. virtual OFCondition negotiateAssociation();
  207. /** After negotiation association, this call returns the first usable presentation context
  208. * given the desired abstract syntax and transfer syntax
  209. * @param abstractSyntax [in] The abstract syntax (UID) to look for
  210. * @param transferSyntax [in] The transfer syntax (UID) to look for. If empty, the transfer
  211. * syntax is not checked.
  212. * @return Adequate Presentation context ID that can be used. 0 if none found.
  213. */
  214. T_ASC_PresentationContextID findPresentationContextID(const OFString &abstractSyntax,
  215. const OFString &transferSyntax);
  216. /** After a successful association negotiation, this function is called to return the
  217. * presentation context ID that best matches the desired abstract syntax and transfer
  218. * syntax (TS). The function tries to do the following:
  219. * - If possible finds a presentation context with matching TS
  220. * - Else then tries to find an explicit VR uncompressed TS presentation context
  221. * - Else then tries to find an implicit VR uncompressed TS presentation context
  222. * - Else finally accepts each matching presentation ctx independent of TS.
  223. * @param abstractSyntax [in] The abstract syntax (UID) to look for
  224. * @param transferSyntax [in] The transfer syntax (UID) to look for. If empty, the transfer
  225. * syntax is not checked.
  226. * @return Adequate Presentation context ID that can be used. 0 if no appropriate
  227. * presentation context could be found at all.
  228. */
  229. T_ASC_PresentationContextID findAnyPresentationContextID(const OFString &abstractSyntax,
  230. const OFString &transferSyntax);
  231. /** This function sends a C-ECHO command via network to another DICOM application
  232. * @param presID [in] Presentation context ID to use. A value of 0 lets SCP class tries
  233. * to choose one on its own.
  234. * @return EC_Normal if echo was successful, an error code otherwise
  235. *
  236. */
  237. virtual OFCondition sendECHORequest(const T_ASC_PresentationContextID presID);
  238. /** This function sends a C-STORE request on the currently opened association and receives
  239. * the corresponding response then. If required and supported, the dataset of the SOP
  240. * instance can be converted automatically to the network transfer syntax that was
  241. * negotiated (and is specified by the parameter 'presID'). However, this feature is
  242. * disabled by default. See setDatasetConversionMode() on how to enable it.
  243. * @param presID [in] Contains in the end the ID of the presentation context which
  244. * was specified in the DIMSE command. If 0 is given, the
  245. * function tries to find an approriate presentation context
  246. * itself (based on SOP class and original transfer syntax of
  247. * the 'dicomFile' or 'dataset').
  248. * @param dicomFile [in] The filename of the DICOM file to be sent. Alternatively, a
  249. * dataset can be given in the next parameter. If both are given
  250. * the dataset from the file name is used.
  251. * @param dataset [in] The dataset to be sent. Alternatively, a filename can be
  252. * specified in the previous parameter. If both are given the
  253. * dataset from the filename is used.
  254. * @param rspStatusCode [out] The response status code received. 0 means success, others
  255. * can be found in the DICOM standard.
  256. * @return EC_Normal if request could be issued and response was received successfully,
  257. * error code otherwise. That means that if the receiver sends a response denoting
  258. * failure of the storage request, EC_Normal will be returned.
  259. */
  260. virtual OFCondition sendSTORERequest(const T_ASC_PresentationContextID presID,
  261. const OFString &dicomFile,
  262. DcmDataset *dataset,
  263. Uint16 &rspStatusCode);
  264. /** Sends a C-MOVE Request on given presentation context and receives list of responses.
  265. * The function receives the first response and then calls the function handleMOVEResponse()
  266. * which gets the relevant presentation context together with the response dataset and
  267. * status information. Then it waits again for the next response, if there are more to
  268. * come (i.e. response status is PENDING). In the end, after receiving all responses, the
  269. * full list of responses is returned to the caller. If he is not interested, he just sets
  270. * responses=NULL when calling the function.
  271. * This function can be overwritten by actual SCU implementations but just should work fine
  272. * for most people.
  273. * @param presID [in] The presentation context ID that should be used.
  274. * Must be an odd number.
  275. * @param moveDestinationAETitle [in] The move destination's AE title, i.e.\ the one that
  276. * is used for connection to the storage server.
  277. * @param dataset [in] The dataset containing the information about the
  278. * object(s) to be retrieved.
  279. * @param responses [out] The incoming C-MOVE responses for this request.
  280. * The caller is responsible for providing a non-NULL
  281. * pointer for this case. After receiving the results,
  282. * the caller is responsible for freeing the memory of
  283. * this variable. If NULL is specified, the responses
  284. * will not bereturned to the caller.
  285. * @return EC_Normal if everything went fine, i.e.\ if request could be send and responses
  286. * (with whatever status) could be received.
  287. */
  288. virtual OFCondition sendMOVERequest(const T_ASC_PresentationContextID presID,
  289. const OFString &moveDestinationAETitle,
  290. DcmDataset *dataset,
  291. OFList<RetrieveResponse*> *responses);
  292. /** This is the standard handler for C-MOVE message responses: It just adds up all responses
  293. * it receives and prints a DEBUG message. Therefore, it is called for each response
  294. * received in sendMOVERequest(). The idea is of course to overwrite this function in a
  295. * derived, actual SCU implementation if required. Thus, after each response, the caller of
  296. * sendMOVERequest() can decide on its own whether he wants to cancel the C-MOVE session,
  297. * terminate the association, do something useful or whatever. Thus this function is a more
  298. * object-oriented kind of callback.
  299. * @param presID [in] The presentation context ID where the response was
  300. * received on.
  301. * @param response [in] The C-MOVE response received.
  302. * @param waitForNextResponse [out] Denotes whether SCU should try to receive another
  303. * response. If set to OFTrue, then sendMOVERequest() will
  304. * continue waiting for responses. The current
  305. * implementation does that for all responses do not have
  306. * status Failed, Warning, Success or unknown. If set to
  307. * OFFalse, sendMOVERequest() will return control to the
  308. * caller.
  309. * @return EC_Normal, if response could be handled. Error code otherwise.
  310. * The current implementation always returns EC_Normal.
  311. */
  312. virtual OFCondition handleMOVEResponse(const T_ASC_PresentationContextID presID,
  313. RetrieveResponse *response,
  314. OFBool &waitForNextResponse);
  315. /** Sends a C-GET Request on given presentation context and receives list of responses. It
  316. * then switches control to the function handleCGETSession().
  317. * The full list of responses is returned to the caller. If he is not interested, he can
  318. * set responses=NULL when calling the function.
  319. * This function can be overwritten by actual SCU implementations but just should work fine
  320. * for most people.
  321. * @param presID [in] The presentation context ID that should be used. Must be an odd
  322. * number.
  323. * @param dataset [in] The dataset containing the information about the
  324. * object(s) to be retrieved
  325. * @param responses [out] The incoming C-GET responses for this request. If the caller
  326. * specifies NULL, no responses will be returned; otherwise there
  327. * should be at least one final C-GET response (mandatory). C-GET
  328. * responses after each DICOM object received are optional and may
  329. * have been ommitted by the server.
  330. * @return EC_Normal if everything went fine, i.e.\ if request could be sent and expected
  331. * responses (with whatever status) could be received.
  332. */
  333. virtual OFCondition sendCGETRequest(const T_ASC_PresentationContextID presID,
  334. DcmDataset *dataset,
  335. OFList<RetrieveResponse*> *responses);
  336. /** Does the logic for switching between C-GET Response and C-STORE Requests. Sends a C-GET
  337. * Request on given presentation context and receives list of responses. Ihe full list of
  338. * responses is returned to the caller. If he is not interested, he can set responses=NULL
  339. * when calling the function. After sending a C-GET Request, there might be two different
  340. * responses coming in: C-GET-RSP (optional after each received object and mandatory after
  341. * the last object) or a mandatory C-STORE for each incoming object that is received due to
  342. * the request. This function therefore either calls handleCGETResponse() or
  343. * handleSTORERequest() in order to deal with the incoming message. All other messages lead
  344. * to an error within this handler.
  345. * This function can be overwritten by actual SCU implementations but just should work fine
  346. * for most people.
  347. * @param presID [in] The presentation context ID that should be used. Must be an odd
  348. * number.
  349. * @param dataset [in] The dataset containing the information about the object(s) to be
  350. * retrieved
  351. * @param responses [out] The incoming C-GET responses for this request. If the caller
  352. * specifies NULL, no responses will be returned; otherwise there
  353. * should be at least one final C-GET response (mandatory). C-GET
  354. * responses after each DICOM object received are optional and may
  355. * have been ommitted by the server.
  356. * @return EC_Normal if everything went fine, i.e.\ if request could be send
  357. * and expected responses (with whatever status) could be received.
  358. */
  359. virtual OFCondition handleCGETSession(const T_ASC_PresentationContextID presID,
  360. DcmDataset *dataset,
  361. OFList<RetrieveResponse*> *responses);
  362. /** Function handling a single C-GET Response. This standard handler reads the status of the
  363. * response and decides whether to receive any further messages related to the original
  364. * C-GET Request or whether the last response was received or an error occured.
  365. * @param presID [in] The presentation context the C-GET Response was
  366. * received on.
  367. * @param response [in] The response received
  368. * @param continueCGETSession [out] Defines whether it is decided to wait for further C-GET
  369. * Responses/C-STORE Requests within this C-GET session
  370. * @return If no errors occur (dataset response NULL, SCU not connected), this method will
  371. * return EC_Normal, otherwise error code.
  372. */
  373. virtual OFCondition handleCGETResponse(const T_ASC_PresentationContextID presID,
  374. RetrieveResponse* response,
  375. OFBool &continueCGETSession);
  376. /** Function handling a single C-STORE Request. If storage mode is set to disk (default),
  377. * this function is called and the incoming object stored to disk.
  378. * @param presID [in] The presentation context the C-STORE Response was
  379. * received on.
  380. * @param incomingObject [in] The dataset (the object) received
  381. * @param continueCGETSession [out] Defines whether it is decided to wait for further
  382. * C-GET Responses/C-STORE requests within this C-GET
  383. * session.
  384. * @param cStoreReturnStatus [out] Denotes the desired C-STORE return status.
  385. * @return If errors occur (incomingObject NULL or SCU not connected or file could not be
  386. * stored), this method will return an error code otherwise EC_Normal.
  387. */
  388. virtual OFCondition handleSTORERequest(const T_ASC_PresentationContextID presID,
  389. DcmDataset *incomingObject,
  390. OFBool &continueCGETSession,
  391. Uint16 &cStoreReturnStatus);
  392. /** Function handling a single C-STORE Request. If storage mode is set to bit preserving,
  393. * this function is called and the incoming object stored directly to disk, i.e. not stored
  394. * fully in memory.
  395. * @param presID [in] The presentation context the C-STORE Response was received on.
  396. * @param filename [in] The filename to store to
  397. * @param request [in] The incoming C-STORE request command set
  398. * @return If errors occur (incomingObject NULL or SCU not connected filename not
  399. * specified), this method will return an error code otherwise EC_Normal.
  400. */
  401. virtual OFCondition handleSTORERequestFile(T_ASC_PresentationContextID *presID,
  402. const OFString &filename,
  403. T_DIMSE_C_StoreRQ *request);
  404. /** Sends a C-FIND Request on given presentation context and receives list of responses.
  405. * The function receives the first response and then calls the function handleFINDResponse
  406. * which gets the relevant presentation context together with the response dataset and
  407. * status information. Then it waits again for the next response, if there are more to
  408. * come (i.e. response status is PENDING). In the end, after receiving all responses, the
  409. * full list of responses is returned to the caller. If he is not interested, he just sets
  410. * responses=NULL when calling the function.
  411. * This function can be overwritten by actual SCU implementations but just should work fine
  412. * for most people.
  413. * @param presID [in] The presentation context ID that should be used. Must be an odd
  414. * number.
  415. * @param queryKeys [in] The dataset containing the query keys to be searched for on the
  416. * server (SCP).
  417. * @param responses [out] The incoming C-FIND responses for this request. The caller is
  418. * responsible for providing a non-NULL pointer for this case.
  419. * After receiving the results, the caller is responsible for
  420. * freeing the memory of this variable. If NULL is specified, the
  421. * responses will be not returned to the caller.
  422. * @return EC_Normal if everything went fine, i.e.\ if request could be send and responses
  423. * (with whatever status) could be received.
  424. */
  425. virtual OFCondition sendFINDRequest(const T_ASC_PresentationContextID presID,
  426. DcmDataset *queryKeys,
  427. OFList<QRResponse*> *responses);
  428. /** This is the standard handler for C-FIND message responses: It just adds up all responses
  429. * it receives and prints a DEBUG message. Therefore, it is called for each response
  430. * received in sendFINDRequest(). The idea is of course to overwrite this function in a
  431. * derived, actual SCU implementation if required. Thus, after each response, the caller of
  432. * sendFINDRequest() can decide on its own whether he wants to cancel the C-FIND session,
  433. * terminate the association, do something useful or whatever. That way this is a more
  434. * object-oriented kind of callback.
  435. * @param presID [in] The presentation context ID where the response was
  436. * received on.
  437. * @param response [in] The C-FIND response received.
  438. * @param waitForNextResponse [out] Denotes whether SCU should try to receive another
  439. * response. If set to OFTrue, then sendFINDRequest()
  440. * will continue waiting for responses. The current
  441. * implementation does that for all responses do not have
  442. * status SUCESSS. If set to OFFalse, sendFINDRequest()
  443. * will return control to the caller.
  444. * @return EC_Normal, if response could be handled. Error code otherwise.
  445. * The current implementation always returns EC_Normal.
  446. */
  447. virtual OFCondition handleFINDResponse(const T_ASC_PresentationContextID presID,
  448. QRResponse *response,
  449. OFBool &waitForNextResponse);
  450. /** Send C-CANCEL and, therefore, ends the C-FIND -GET or -MOVE session, i.e.\ no further
  451. * responses will be handled. A call to this function only makes sense if an association
  452. * is open, the given presentation context represents a valid C-FIND/GET/MOVE-enabled SOP
  453. * class and usually only, if the last command send on that presentation context was a
  454. * C-FIND message.
  455. * @param presID [in] The presentation context ID where the C-CANCEL should be sent on.
  456. * @return The current implementation always returns EC_Normal.
  457. */
  458. virtual OFCondition sendCANCELRequest(const T_ASC_PresentationContextID presID);
  459. /** This function sends a N-ACTION request on the currently opened association and receives
  460. * the corresponding response then
  461. * @param presID [in] The ID of the presentation context to be used for sending
  462. * the request message. Should not be 0.
  463. * @param sopInstanceUID [in] The requested SOP Instance UID
  464. * @param actionTypeID [in] The action type ID to be used
  465. * @param reqDataset [in] The dataset to be sent
  466. * @param rspStatusCode [out] The response status code received. 0 means success,
  467. * others can be found in the DICOM standard.
  468. * @return EC_Normal if request could be issued and response was received successfully,
  469. * an error code otherwise
  470. */
  471. virtual OFCondition sendACTIONRequest(const T_ASC_PresentationContextID presID,
  472. const OFString &sopInstanceUID,
  473. const Uint16 actionTypeID,
  474. DcmDataset *reqDataset,
  475. Uint16 &rspStatusCode);
  476. /** This function sends N-EVENT-REPORT request and receives the corresponding response
  477. * @param presID [in] The ID of the presentation context to be used for sending
  478. * the request message. Should not be 0.
  479. * @param sopInstanceUID [in] The requested SOP Instance UID
  480. * @param eventTypeID [in] The event type ID to be used
  481. * @param reqDataset [in] The request dataset to be sent
  482. * @param rspStatusCode [out] The response status code received. 0 means success,
  483. * others can be found in the DICOM standard.
  484. * @return EC_Normal if request could be issued and response was received successfully,
  485. * an error code otherwise
  486. */
  487. virtual OFCondition sendEVENTREPORTRequest(const T_ASC_PresentationContextID presID,
  488. const OFString &sopInstanceUID,
  489. const Uint16 eventTypeID,
  490. DcmDataset *reqDataset,
  491. Uint16 &rspStatusCode);
  492. /** Receives N-EVENT-REPORT request on the currently opened association and sends a
  493. * corresponding response. Calls checkEVENTREPORTRequest() in order to determine the
  494. * DIMSE status code to be used for the N-EVENT-REPORT response.
  495. * @param reqDataset [out] Pointer to the dataset received
  496. * @param eventTypeID [out] Event Type ID from the command set received
  497. * @param timeout [in] Optional timeout in seconds for receiving data. This value
  498. * (if not 0) overwrites the standard DIMSE timeout and also
  499. * enables the non-blocking mode for receiving the request.
  500. * @return status, EC_Normal if successful, an error code otherwise
  501. */
  502. virtual OFCondition handleEVENTREPORTRequest(DcmDataset *&reqDataset,
  503. Uint16 &eventTypeID,
  504. const int timeout = 0);
  505. /** Closes the association created by this SCU. Also resets the current association.
  506. * @param closeType [in] Define whether to release or abort the association
  507. */
  508. virtual void closeAssociation(const DcmCloseAssociationType closeType);
  509. /* Set methods */
  510. /** Set maximum PDU length (to be received by SCU)
  511. * @param maxRecPDU [in] The maximum PDU size to use in bytes
  512. */
  513. void setMaxReceivePDULength(const unsigned long maxRecPDU);
  514. /** Set whether to send in DIMSE blocking or non-blocking mode
  515. * @param blockingMode [in] Either blocking or non-blocking mode
  516. */
  517. void setDIMSEBlockingMode(const T_DIMSE_BlockingMode blockingMode);
  518. /** Set SCU's AETitle to be used in association negotiation
  519. * @param myAETtitle [in] The SCU's AETitle to be used
  520. */
  521. void setAETitle(const OFString &myAETtitle);
  522. /** Set SCP's host (hostname or IP address) to talk to in association negotiation
  523. * @param peerHostName [in] The SCP's hostname or IP address to be used
  524. */
  525. void setPeerHostName(const OFString &peerHostName);
  526. /** Set SCP's AETitle to talk to in association negotiation
  527. * @param peerAETitle [in] The SCP's AETitle to be used
  528. */
  529. void setPeerAETitle(const OFString &peerAETitle);
  530. /** Set SCP's port number to connect to for association negotiation
  531. * @param peerPort [in] The SCP's port number
  532. */
  533. void setPeerPort(const Uint16 peerPort);
  534. /** Set timeout for receiving DIMSE messages
  535. * @param dimseTimeout [in] DIMSE Timeout in seconds for receiving data. If the blocking
  536. * mode is DIMSE_NONBLOCKING and we are trying to read data from
  537. * the incoming socket stream and no data has been received.
  538. */
  539. void setDIMSETimeout(const Uint32 dimseTimeout);
  540. /** Set timeout for receiving ACSE messages
  541. * @param acseTimeout [in] ACSE Timeout in seconds used by timer for message timeouts
  542. * during association negotiation
  543. */
  544. void setACSETimeout(const Uint32 acseTimeout);
  545. /** Set an association configuration file and profile to be used
  546. * @param filename [in] File name of the association configuration file
  547. * @param profile [in] Profile inside the association negotiation file
  548. */
  549. void setAssocConfigFileAndProfile(const OFString &filename,
  550. const OFString &profile);
  551. /** Set the directory that should be used by the standard C-GET handler to store objects
  552. * that come in with the corresponding C-STORE rqeuests
  553. * @param storeDir [in] The directory to store to. It is checked in handleSTORERequest()
  554. * whether the directory is writeable and readable. Per default, the
  555. * received objects are stored in the current working directory.
  556. */
  557. void setStorageDir(const OFString &storeDir);
  558. /** Set the storage mode to be used. Default is DCMSCU_STORAGE_DISK.
  559. * @param storageMode The storage mode to be used.
  560. */
  561. void setStorageMode(const DcmStorageMode storageMode);
  562. /** Set whether to show presentation contexts in verbose or debug mode
  563. * @param mode [in] Show presentation contexts in verbose mode if OFTrue. By default, the
  564. * presentation contexts are shown in debug mode.
  565. */
  566. void setVerbosePCMode(const OFBool mode);
  567. /** Set the mode that specifies whether the transfer syntax of the dataset can be changed
  568. * for network transmission. This mainly covers the compression/decompression of datasets,
  569. * which is disabled by default.
  570. * @param mode [in] Allow dataset conversion if OFTrue
  571. */
  572. void setDatasetConversionMode(const OFBool mode);
  573. /** Set the mode that specifies whether the progress of sending and receiving DIMSE
  574. * messages is notified by calling notifySENDProgress() and notifyRECEIVEProgress(),
  575. * respectively. The progress notification is enabled by default.
  576. * @param mode [in] Disable progress notification if OFFalse
  577. */
  578. void setProgressNotificationMode(const OFBool mode);
  579. /* Get methods */
  580. /** Get current connection status
  581. * @return OFTrue if SCU is currently connected, OFFalse otherwise
  582. */
  583. OFBool isConnected() const;
  584. /** Returns maximum PDU length configured to be received by SCU
  585. * @return Maximum PDU length in bytes
  586. */
  587. Uint32 getMaxReceivePDULength() const;
  588. /** Returns whether DIMSE messaging is configured to be blocking or unblocking
  589. * @return The blocking mode configured
  590. */
  591. T_DIMSE_BlockingMode getDIMSEBlockingMode() const;
  592. /** Returns the SCU's own configured AETitle
  593. * @return The AETitle configured for this SCU
  594. */
  595. const OFString &getAETitle() const;
  596. /** Returns the SCP's (peer's) host name configured
  597. * @return The hostname (or IP) configured to be talked to
  598. */
  599. const OFString &getPeerHostName() const;
  600. /** Returns the SCP's (peer's) AETitle configured
  601. * @return The AETitle configured to be talked to
  602. */
  603. const OFString &getPeerAETitle() const;
  604. /** Returns the SCP's (peer's) TCP/IP port configured
  605. * @return The port configured to talked to
  606. */
  607. Uint16 getPeerPort() const;
  608. /** Returns the DIMSE timeout configured defining how long SCU will wait for DIMSE responses
  609. * @return The DIMSE timeout configured
  610. */
  611. Uint32 getDIMSETimeout() const;
  612. /** Returns the timeout configured defining how long SCU will wait for messages during ACSE
  613. * messaging (association negotiation)
  614. * @return The ACSE timeout configured
  615. */
  616. Uint32 getACSETimeout() const;
  617. /** Returns the storage directory used for storing objects received with C-STORE requests
  618. * in the context of C-GET sessions. Default is empty string which refers to the current
  619. * working directory.
  620. * @return The storage directory
  621. */
  622. OFString getStorageDir() const;
  623. /** Returns the storage mode enabled
  624. * @return The storage mode enabled
  625. */
  626. DcmStorageMode getStorageMode() const;
  627. /** Returns the verbose presentation context mode configured specifying whether details
  628. * on the presentation contexts (negotiated during association setup) should be shown in
  629. * verbose or debug mode. The latter is the default.
  630. * @return The current verbose presentation context mode. Show details on the
  631. * presentation contexts on INFO log level (verbose) if OFTrue and on DEBUG
  632. * level if OFFalse.
  633. */
  634. OFBool getVerbosePCMode() const;
  635. /** Returns the mode that specifies whether the transfer syntax of the dataset can be
  636. * changed for network transmission. This mainly covers the compression/decompression
  637. * of datasets, which is disabled by default.
  638. * @return The current dataset conversion mode, enabled if OFTrue
  639. */
  640. OFBool getDatasetConversionMode() const;
  641. /** Returns the mode that specifies whether the progress of sending and receiving DIMSE
  642. * messages is notified by calling notifySENDProgress() and notifyRECEIVEProgress(),
  643. * respectively. The progress notification is enabled by default.
  644. * @return The current progress notification mode, enabled if OFTrue
  645. */
  646. OFBool getProgressNotificationMode() const;
  647. /** Returns whether SCU is configured to create a TLS connection with the SCP
  648. * @return OFFalse for this class but may be overridden by derived classes
  649. */
  650. OFBool getTLSEnabled() const;
  651. /** Deletes internal networking structures from memory */
  652. void freeNetwork();
  653. protected:
  654. /** Sends a DIMSE command and possibly also a dataset from a data object via network to
  655. * another DICOM application
  656. * @param presID [in] Presentation context ID to be used for message
  657. * @param msg [in] Structure that represents a certain DIMSE command which
  658. * shall be sent
  659. * @param dataObject [in] The instance data which shall be sent to the other DICOM
  660. * application; NULL, if there is none
  661. * @param commandSet [out] If this parameter is not NULL it will return a copy of the
  662. * DIMSE command which is sent to the other DICOM application
  663. * @return EC_Normal if sending request was successful, an error code otherwise
  664. */
  665. OFCondition sendDIMSEMessage(const T_ASC_PresentationContextID presID,
  666. T_DIMSE_Message *msg,
  667. DcmDataset *dataObject,
  668. DcmDataset **commandSet = NULL);
  669. /** Returns SOP Class UID, SOP Instance UID and original transfer syntax for a given dataset.
  670. * If the dataset is NULL, all returned values will be undefined (i.e. empty or EXS_Unknown).
  671. * @param dataset [in] The dataset to read from
  672. * @param sopClassUID [out] The value of attribute SOP Class UID if present
  673. * @param sopInstanceUID [out] The value of attribute SOP Instance UID if present
  674. * @param transferSyntax [out] The value of transfer syntax that originally was read from
  675. * disk. Will be unknown if the dataset was created in memory.
  676. * @return EC_Normal if all information could be retrieved and is valid, an error code
  677. * otherwise
  678. */
  679. OFCondition getDatasetInfo(DcmDataset *dataset,
  680. OFString &sopClassUID,
  681. OFString &sopInstanceUID,
  682. E_TransferSyntax &transferSyntax);
  683. /** Tells DcmSCU to use a secure TLS connection described by the given TLS layer
  684. * @param tlayer [in] The TLS transport layer including all TLS parameters
  685. * @return EC_Normal if given transport layer is ok, an error code otherwise
  686. */
  687. OFCondition useSecureConnection(DcmTransportLayer *tlayer);
  688. /** Receive DIMSE command (excluding dataset!) over the currently open association
  689. * @param presID [out] Contains in the end the ID of the presentation context
  690. * which was specified in the DIMSE command received
  691. * @param msg [out] The message received
  692. * @param statusDetail [out] If a non-NULL value is passed this variable will in the end
  693. * contain detailed information with regard to the status
  694. * information which is captured in the status element
  695. * (0000,0900). Note that the value for element (0000,0900) is
  696. * not contained in this return value but in internal msg. For
  697. * details on the structure of this object, see DICOM standard
  698. * part 7, annex C).
  699. * @param commandSet [out] If this parameter is not NULL, it will return a copy of the
  700. * DIMSE command which was received from the other DICOM
  701. * application. The caller is responsible to de-allocate the
  702. * returned object!
  703. * @param timeout [in] If this parameter is not 0, it specifies the timeout (in
  704. * seconds) to be used for receiving the DIMSE command.
  705. * Otherwise, the default timeout value is used (see
  706. * setDIMSETimeout()).
  707. * @return EC_Normal if command could be received successfully, an error code otherwise
  708. */
  709. OFCondition receiveDIMSECommand(T_ASC_PresentationContextID *presID,
  710. T_DIMSE_Message *msg,
  711. DcmDataset **statusDetail,
  712. DcmDataset **commandSet = NULL,
  713. const Uint32 timeout = 0);
  714. /** Receives one dataset (of instance data) via network from another DICOM application
  715. * @param presID [out] Contains in the end the ID of the presentation context which
  716. * was used in the PDVs that were received on the network. If the
  717. * PDVs show different presentation context IDs, this function
  718. * will return an error.
  719. * @param dataObject [out] Contains in the end the information which was received over
  720. * the network
  721. * @return EC_Normal if dataset could be received successfully, an error code otherwise
  722. */
  723. OFCondition receiveDIMSEDataset(T_ASC_PresentationContextID *presID,
  724. DcmDataset **dataObject);
  725. /** clear list of presentation contexts. In addition, any currently selected association
  726. * configuration file is disabled.
  727. */
  728. void clearPresentationContexts();
  729. /** After negotiation association, this call returns the presentation context belonging
  730. * to the given presentation context ID
  731. * @param presID [in] The presentation context ID to look for
  732. * @param abstractSyntax [out] The abstract syntax (UID) for that ID.
  733. * Empty, if such a presentation context does not exist.
  734. * @param transferSyntax [out] The transfer syntax (UID) for that ID.
  735. * Empty, if such a presentation context does not exist.
  736. */
  737. void findPresentationContext(const T_ASC_PresentationContextID presID,
  738. OFString &abstractSyntax,
  739. OFString &transferSyntax);
  740. /* ***********************************************************************
  741. * Functions particularly interesting for overwriting in derived classes
  742. * *********************************************************************** */
  743. /** This function is called if an object was received due to a C-GET request and can be
  744. * overwritten by a user in order to be informed about such an event. The default
  745. * implementation just prints a DEBUG message. Note that this function is not called if
  746. * the SCU is in storage mode DCMSCU_STORAGE_IGNORE.
  747. * @param filename [in] The filename written
  748. * @param sopClassUID [in] The SOP Class UID of the object written
  749. * @param sopInstanceUID [in] The SOP Instance UID of the object written
  750. */
  751. virtual void notifyInstanceStored(const OFString &filename,
  752. const OFString &sopClassUID,
  753. const OFString &sopInstanceUID) const;
  754. /** This function is called while sending DIMSE messages, i.e.\ on each PDV of a dataset.
  755. * The default implementation just prints a TRACE message on the number of bytes sent so
  756. * far. By overwriting this method, the progress of the send process can be shown to the
  757. * user in a more appropriate way. The progress notification can also be disabled
  758. * completely by calling setProgressNotificationMode().
  759. * @param byteCount [in] Number of bytes sent so far
  760. */
  761. virtual void notifySENDProgress(const unsigned long byteCount);
  762. /** This function is called while receiving DIMSE messages, i.e.\ on each PDV of a dataset.
  763. * The default implementation just prints a TRACE message on the number of bytes received
  764. * so far. By overwriting this method, the progress of the receive process can be shown to
  765. * the user in a more appropriate way. The progress notification can also be disabled
  766. * completely by calling setProgressNotificationMode().
  767. * @param byteCount [in] Number of bytes received so far
  768. */
  769. virtual void notifyRECEIVEProgress(const unsigned long byteCount);
  770. /** Check given N-EVENT-REPORT request and dataset for validity. This method is called by
  771. * handleEVENTREPORTRequest() before sending the response in order to determine the
  772. * DIMSE status code to be used for the response message.
  773. * @param request [in] The N-EVENT-REPORT request message data structure
  774. * @param reqDataset [in] The N-EVENT-REPORT request dataset received. Might be NULL.
  775. * @return DIMSE status code to be used for the N-EVENT-REPORT response.
  776. * Always returns STATUS_Success (0). Derived classes should, therefore,
  777. * overwrite this method and return a more appropriate value based on the
  778. * result of the checks performed.
  779. */
  780. virtual Uint16 checkEVENTREPORTRequest(T_DIMSE_N_EventReportRQ &request,
  781. DcmDataset *reqDataset);
  782. /** Sends back a C-STORE response on the given presentation context, with the designated
  783. * status, fitting the corresponding C-STORE request.
  784. * @param presID [in] The presentation context ID to be used.
  785. * @param status [in] The storage DIMSE status to be used.
  786. * @param request [in] The C-STORE request that should be responded to.
  787. * @result EC_Normal if the response could be sent, error otherwise.
  788. */
  789. virtual OFCondition sendSTOREResponse(T_ASC_PresentationContextID presID,
  790. Uint16 status,
  791. const T_DIMSE_C_StoreRQ &request);
  792. /** Helper function that generates a storage filename by extracting SOP Class and SOP
  793. * Instance UID from a dataset and combining that with the configured storage directory.
  794. * The SOP class is used to create an initial two letter abbreviation for the
  795. * corresponding modality, e.g. CT. An example for a storage filename created by this
  796. * function is /storage_dir/CT.1.2.3.4.5 for a CT with SOP Instance UID 1.2.3.4.
  797. * This function might be overwritten to change the filename behaviour completely. This
  798. * function is only called if the SCU is in DCMSCU_STORAGE_DISK mode.
  799. * @param dataset [in] The dataset that should be stored to disk
  800. * @result Non-empty string if successful, otherwise empty string.
  801. */
  802. virtual OFString createStorageFilename(DcmDataset *dataset);
  803. /** Receives a DICOM dataset on a given presentation context ID but does not store it in
  804. * memory or disk, thus ignoring it.
  805. * @param presID [in] The presentation context to be used
  806. * @param request [in] The corresponding C-STORE request
  807. * @return EC_Normal if ignoring worked, error code otherwise.
  808. */
  809. virtual OFCondition ignoreSTORERequest(T_ASC_PresentationContextID presID,
  810. const T_DIMSE_C_StoreRQ &request);
  811. /* Callback functions (static) */
  812. /** Callback function used for sending DIMSE messages.
  813. * @param callbackContext [in] The desired user callback data
  814. * @param byteCount [in] Progress bytes count
  815. */
  816. static void callbackSENDProgress(void *callbackContext,
  817. unsigned long byteCount);
  818. /** Callback function used for receiving DIMSE messages.
  819. * @param callbackContext [in] The desired user callback data
  820. * @param byteCount [in] Progress bytes count
  821. */
  822. static void callbackRECEIVEProgress(void *callbackContext,
  823. unsigned long byteCount);
  824. private:
  825. /** Private undefined copy-constructor. Shall never be called.
  826. * @param src Source object
  827. */
  828. DcmSCU(const DcmSCU &src);
  829. /** Private undefined operator=. Shall never be called.
  830. * @param src Source object
  831. * @return Reference to this
  832. */
  833. DcmSCU &operator=(const DcmSCU &src);
  834. /// Associaton of this SCU. This class only handles 1 association at a time.
  835. T_ASC_Association *m_assoc;
  836. /// The DICOM network the association is based on
  837. T_ASC_Network *m_net;
  838. /// Association parameters
  839. T_ASC_Parameters *m_params;
  840. /// Configuration file for presentation contexts (optional)
  841. OFString m_assocConfigFilename;
  842. /// Profile in configuration file that should be used (optional)
  843. OFString m_assocConfigProfile;
  844. /// Defines presentation context, consisting of one abstract syntax name
  845. /// and a list of transfer syntaxes for this abstract syntax
  846. struct DcmSCUPresContext {
  847. /** Default constructor
  848. */
  849. DcmSCUPresContext()
  850. : abstractSyntaxName()
  851. , transferSyntaxes()
  852. , roleSelect(ASC_SC_ROLE_DEFAULT)
  853. {
  854. }
  855. /// Abstract Syntax Name of Presentation Context
  856. OFString abstractSyntaxName;
  857. /// List of Transfer Syntaxes for Presentation Context
  858. OFList<OFString> transferSyntaxes;
  859. /// Role Selection
  860. T_ASC_SC_ROLE roleSelect;
  861. };
  862. /// List of presentation contexts that should be negotiated
  863. OFList<DcmSCUPresContext> m_presContexts;
  864. /// Configuration file containing association parameters
  865. OFString m_assocConfigFile;
  866. /// The last DIMSE successfully sent, unresponded DIMSE request
  867. T_DIMSE_Message *m_openDIMSERequest;
  868. /// Maximum PDU size
  869. Uint32 m_maxReceivePDULength;
  870. /// DIMSE blocking mode
  871. T_DIMSE_BlockingMode m_blockMode;
  872. /// AEtitle of this application
  873. OFString m_ourAETitle;
  874. /// Peer hostname
  875. OFString m_peer;
  876. /// AEtitle of remote application
  877. OFString m_peerAETitle;
  878. /// Port of remote application entity
  879. Uint16 m_peerPort;
  880. /// DIMSE timeout
  881. Uint32 m_dimseTimeout;
  882. /// ACSE timeout
  883. Uint32 m_acseTimeout;
  884. /// Storage directory for objects received with C-STORE due to a
  885. /// running C-GET session. Per default, the received objects
  886. /// are stored in the current working directory.
  887. OFString m_storageDir;
  888. /// Set whether bit preserving storage should be enabled, i.e.\ any objects
  889. /// retrieved via C-STORE should be written directly to disk without
  890. /// any data correction/re-computation (e.g.\ group length calculations,
  891. /// padding, etc.). This is especially interesting for retaining valid
  892. /// signatures, and also to receive huge files which cannot be fully received
  893. /// in memory. Default is OFFalse (no bit preserving) storage.
  894. DcmStorageMode m_storageMode;
  895. /// Verbose PC mode
  896. OFBool m_verbosePCMode;
  897. /// Dataset conversion mode
  898. OFBool m_datasetConversionMode;
  899. /// Progress notification mode
  900. OFBool m_progressNotificationMode;
  901. /** Returns next available message ID free to be used by SCU
  902. * @return Next free message ID
  903. */
  904. Uint16 nextMessageID();
  905. };
  906. #endif // DCMTK 3.6.0
  907. #endif // SCU_H